dcbnl: add support for retrieving peer configuration - cee
This patch adds the support for retrieving the remote or peer DCBX configuration via dcbnl for embedded DCBX stacks supporting the CEE DCBX standard. Signed-off-by: Shmulik Ravid <shmulikr@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
		
							parent
							
								
									eed84713bc
								
							
						
					
					
						commit
						dc6ed1df5a
					
				| @ -87,6 +87,45 @@ struct ieee_pfc { | ||||
| 	__u64	indications[IEEE_8021QAZ_MAX_TCS]; | ||||
| }; | ||||
| 
 | ||||
| /* CEE DCBX std supported values */ | ||||
| #define CEE_DCBX_MAX_PGS	8 | ||||
| #define CEE_DCBX_MAX_PRIO	8 | ||||
| 
 | ||||
| /**
 | ||||
|  * struct cee_pg - CEE Prioity-Group managed object | ||||
|  * | ||||
|  * @willing: willing bit in the PG tlv | ||||
|  * @error: error bit in the PG tlv | ||||
|  * @pg_en: enable bit of the PG feature | ||||
|  * @tcs_supported: number of traffic classes supported | ||||
|  * @pg_bw: bandwidth percentage for each priority group | ||||
|  * @prio_pg: priority to PG mapping indexed by priority | ||||
|  */ | ||||
| struct cee_pg { | ||||
| 	__u8    willing; | ||||
| 	__u8    error; | ||||
| 	__u8    pg_en; | ||||
| 	__u8    tcs_supported; | ||||
| 	__u8    pg_bw[CEE_DCBX_MAX_PGS]; | ||||
| 	__u8    prio_pg[CEE_DCBX_MAX_PGS]; | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct cee_pfc - CEE PFC managed object | ||||
|  * | ||||
|  * @willing: willing bit in the PFC tlv | ||||
|  * @error: error bit in the PFC tlv | ||||
|  * @pfc_en: bitmap indicating pfc enabled traffic classes | ||||
|  * @tcs_supported: number of traffic classes supported | ||||
|  */ | ||||
| struct cee_pfc { | ||||
| 	__u8    willing; | ||||
| 	__u8    error; | ||||
| 	__u8    pfc_en; | ||||
| 	__u8    tcs_supported; | ||||
| }; | ||||
| 
 | ||||
| 
 | ||||
| /* This structure contains the IEEE 802.1Qaz APP managed object. This
 | ||||
|  * object is also used for the CEE std as well. There is no difference | ||||
|  * between the objects. | ||||
| @ -158,6 +197,7 @@ struct dcbmsg { | ||||
|  * @DCB_CMD_SDCBX: set DCBX engine configuration | ||||
|  * @DCB_CMD_GFEATCFG: get DCBX features flags | ||||
|  * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags | ||||
|  * @DCB_CMD_CEE_GET: get CEE aggregated configuration | ||||
|  */ | ||||
| enum dcbnl_commands { | ||||
| 	DCB_CMD_UNDEFINED, | ||||
| @ -200,6 +240,8 @@ enum dcbnl_commands { | ||||
| 	DCB_CMD_GFEATCFG, | ||||
| 	DCB_CMD_SFEATCFG, | ||||
| 
 | ||||
| 	DCB_CMD_CEE_GET, | ||||
| 
 | ||||
| 	__DCB_CMD_ENUM_MAX, | ||||
| 	DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, | ||||
| }; | ||||
| @ -222,6 +264,7 @@ enum dcbnl_commands { | ||||
|  * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED) | ||||
|  * @DCB_ATTR_DCBX: DCBX engine configuration in the device (NLA_U8) | ||||
|  * @DCB_ATTR_FEATCFG: DCBX features flags (NLA_NESTED) | ||||
|  * @DCB_ATTR_CEE: CEE std supported attributes (NLA_NESTED) | ||||
|  */ | ||||
| enum dcbnl_attrs { | ||||
| 	DCB_ATTR_UNDEFINED, | ||||
| @ -245,6 +288,9 @@ enum dcbnl_attrs { | ||||
| 	DCB_ATTR_DCBX, | ||||
| 	DCB_ATTR_FEATCFG, | ||||
| 
 | ||||
| 	/* CEE nested attributes */ | ||||
| 	DCB_ATTR_CEE, | ||||
| 
 | ||||
| 	__DCB_ATTR_ENUM_MAX, | ||||
| 	DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, | ||||
| }; | ||||
| @ -279,6 +325,31 @@ enum ieee_attrs_app { | ||||
| }; | ||||
| #define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1) | ||||
| 
 | ||||
| /**
 | ||||
|  * enum cee_attrs - CEE DCBX get attributes | ||||
|  * | ||||
|  * @DCB_ATTR_CEE_UNSPEC: unspecified | ||||
|  * @DCB_ATTR_CEE_PEER_PG: peer PG configuration - get only | ||||
|  * @DCB_ATTR_CEE_PEER_PFC: peer PFC configuration - get only | ||||
|  * @DCB_ATTR_CEE_PEER_APP: peer APP tlv - get only | ||||
|  */ | ||||
| enum cee_attrs { | ||||
| 	DCB_ATTR_CEE_UNSPEC, | ||||
| 	DCB_ATTR_CEE_PEER_PG, | ||||
| 	DCB_ATTR_CEE_PEER_PFC, | ||||
| 	DCB_ATTR_CEE_PEER_APP_TABLE, | ||||
| 	__DCB_ATTR_CEE_MAX | ||||
| }; | ||||
| #define DCB_ATTR_CEE_MAX (__DCB_ATTR_CEE_MAX - 1) | ||||
| 
 | ||||
| enum peer_app_attr { | ||||
| 	DCB_ATTR_CEE_PEER_APP_UNSPEC, | ||||
| 	DCB_ATTR_CEE_PEER_APP_INFO, | ||||
| 	DCB_ATTR_CEE_PEER_APP, | ||||
| 	__DCB_ATTR_CEE_PEER_APP_MAX | ||||
| }; | ||||
| #define DCB_ATTR_CEE_PEER_APP_MAX (__DCB_ATTR_CEE_PEER_APP_MAX - 1) | ||||
| 
 | ||||
| /**
 | ||||
|  * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs | ||||
|  * | ||||
|  | ||||
| @ -84,6 +84,9 @@ struct dcbnl_rtnl_ops { | ||||
| 			       u16 *); | ||||
| 	int (*peer_getapptable)(struct net_device *, struct dcb_app *); | ||||
| 
 | ||||
| 	/* CEE peer */ | ||||
| 	int (*cee_peer_getpg) (struct net_device *, struct cee_pg *); | ||||
| 	int (*cee_peer_getpfc) (struct net_device *, struct cee_pfc *); | ||||
| }; | ||||
| 
 | ||||
| #endif /* __NET_DCBNL_H__ */ | ||||
|  | ||||
| @ -1224,7 +1224,9 @@ err: | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
| static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb) | ||||
| static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, | ||||
| 				int app_nested_type, int app_info_type, | ||||
| 				int app_entry_type) | ||||
| { | ||||
| 	struct dcb_peer_app_info info; | ||||
| 	struct dcb_app *table = NULL; | ||||
| @ -1256,12 +1258,15 @@ static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb) | ||||
| 		 */ | ||||
| 		err = -EMSGSIZE; | ||||
| 
 | ||||
| 		app = nla_nest_start(skb, DCB_ATTR_IEEE_PEER_APP); | ||||
| 		app = nla_nest_start(skb, app_nested_type); | ||||
| 		if (!app) | ||||
| 			goto nla_put_failure; | ||||
| 
 | ||||
| 		if (app_info_type) | ||||
| 			NLA_PUT(skb, app_info_type, sizeof(info), &info); | ||||
| 
 | ||||
| 		for (i = 0; i < app_count; i++) | ||||
| 			NLA_PUT(skb, DCB_ATTR_IEEE_APP, sizeof(struct dcb_app), | ||||
| 			NLA_PUT(skb, app_entry_type, sizeof(struct dcb_app), | ||||
| 				&table[i]); | ||||
| 
 | ||||
| 		nla_nest_end(skb, app); | ||||
| @ -1352,7 +1357,10 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, | ||||
| 	} | ||||
| 
 | ||||
| 	if (ops->peer_getappinfo && ops->peer_getapptable) { | ||||
| 		err = dcbnl_build_peer_app(netdev, skb); | ||||
| 		err = dcbnl_build_peer_app(netdev, skb, | ||||
| 					   DCB_ATTR_IEEE_PEER_APP, | ||||
| 					   DCB_ATTR_IEEE_APP_UNSPEC, | ||||
| 					   DCB_ATTR_IEEE_APP); | ||||
| 		if (err) | ||||
| 			goto nla_put_failure; | ||||
| 	} | ||||
| @ -1510,6 +1518,71 @@ err: | ||||
| 	return ret; | ||||
| } | ||||
| 
 | ||||
| /* Handle CEE DCBX GET commands. */ | ||||
| static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, | ||||
| 			 u32 pid, u32 seq, u16 flags) | ||||
| { | ||||
| 	struct sk_buff *skb; | ||||
| 	struct nlmsghdr *nlh; | ||||
| 	struct dcbmsg *dcb; | ||||
| 	struct nlattr *cee; | ||||
| 	const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; | ||||
| 	int err; | ||||
| 
 | ||||
| 	if (!ops) | ||||
| 		return -EOPNOTSUPP; | ||||
| 
 | ||||
| 	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||||
| 	if (!skb) | ||||
| 		return -ENOBUFS; | ||||
| 
 | ||||
| 	nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); | ||||
| 
 | ||||
| 	dcb = NLMSG_DATA(nlh); | ||||
| 	dcb->dcb_family = AF_UNSPEC; | ||||
| 	dcb->cmd = DCB_CMD_CEE_GET; | ||||
| 
 | ||||
| 	NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name); | ||||
| 
 | ||||
| 	cee = nla_nest_start(skb, DCB_ATTR_CEE); | ||||
| 	if (!cee) | ||||
| 		goto nla_put_failure; | ||||
| 
 | ||||
| 	/* get peer info if available */ | ||||
| 	if (ops->cee_peer_getpg) { | ||||
| 		struct cee_pg pg; | ||||
| 		err = ops->cee_peer_getpg(netdev, &pg); | ||||
| 		if (!err) | ||||
| 			NLA_PUT(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ops->cee_peer_getpfc) { | ||||
| 		struct cee_pfc pfc; | ||||
| 		err = ops->cee_peer_getpfc(netdev, &pfc); | ||||
| 		if (!err) | ||||
| 			NLA_PUT(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ops->peer_getappinfo && ops->peer_getapptable) { | ||||
| 		err = dcbnl_build_peer_app(netdev, skb, | ||||
| 					   DCB_ATTR_CEE_PEER_APP_TABLE, | ||||
| 					   DCB_ATTR_CEE_PEER_APP_INFO, | ||||
| 					   DCB_ATTR_CEE_PEER_APP); | ||||
| 		if (err) | ||||
| 			goto nla_put_failure; | ||||
| 	} | ||||
| 
 | ||||
| 	nla_nest_end(skb, cee); | ||||
| 	nlmsg_end(skb, nlh); | ||||
| 
 | ||||
| 	return rtnl_unicast(skb, &init_net, pid); | ||||
| nla_put_failure: | ||||
| 	nlmsg_cancel(skb, nlh); | ||||
| nlmsg_failure: | ||||
| 	kfree_skb(skb); | ||||
| 	return -1; | ||||
| } | ||||
| 
 | ||||
| static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | ||||
| { | ||||
| 	struct net *net = sock_net(skb->sk); | ||||
| @ -1639,6 +1712,10 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | ||||
| 		ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, | ||||
| 				       nlh->nlmsg_flags); | ||||
| 		goto out; | ||||
| 	case DCB_CMD_CEE_GET: | ||||
| 		ret = dcbnl_cee_get(netdev, tb, pid, nlh->nlmsg_seq, | ||||
| 				    nlh->nlmsg_flags); | ||||
| 		goto out; | ||||
| 	default: | ||||
| 		goto errout; | ||||
| 	} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user