Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Shmulik Ravid and committed by
David S. Miller
dc6ed1df eed84713

+155 -4
+71
include/linux/dcbnl.h
··· 87 87 __u64 indications[IEEE_8021QAZ_MAX_TCS]; 88 88 }; 89 89 90 + /* CEE DCBX std supported values */ 91 + #define CEE_DCBX_MAX_PGS 8 92 + #define CEE_DCBX_MAX_PRIO 8 93 + 94 + /** 95 + * struct cee_pg - CEE Prioity-Group managed object 96 + * 97 + * @willing: willing bit in the PG tlv 98 + * @error: error bit in the PG tlv 99 + * @pg_en: enable bit of the PG feature 100 + * @tcs_supported: number of traffic classes supported 101 + * @pg_bw: bandwidth percentage for each priority group 102 + * @prio_pg: priority to PG mapping indexed by priority 103 + */ 104 + struct cee_pg { 105 + __u8 willing; 106 + __u8 error; 107 + __u8 pg_en; 108 + __u8 tcs_supported; 109 + __u8 pg_bw[CEE_DCBX_MAX_PGS]; 110 + __u8 prio_pg[CEE_DCBX_MAX_PGS]; 111 + }; 112 + 113 + /** 114 + * struct cee_pfc - CEE PFC managed object 115 + * 116 + * @willing: willing bit in the PFC tlv 117 + * @error: error bit in the PFC tlv 118 + * @pfc_en: bitmap indicating pfc enabled traffic classes 119 + * @tcs_supported: number of traffic classes supported 120 + */ 121 + struct cee_pfc { 122 + __u8 willing; 123 + __u8 error; 124 + __u8 pfc_en; 125 + __u8 tcs_supported; 126 + }; 127 + 128 + 90 129 /* This structure contains the IEEE 802.1Qaz APP managed object. This 91 130 * object is also used for the CEE std as well. There is no difference 92 131 * between the objects. ··· 197 158 * @DCB_CMD_SDCBX: set DCBX engine configuration 198 159 * @DCB_CMD_GFEATCFG: get DCBX features flags 199 160 * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags 161 + * @DCB_CMD_CEE_GET: get CEE aggregated configuration 200 162 */ 201 163 enum dcbnl_commands { 202 164 DCB_CMD_UNDEFINED, ··· 240 200 DCB_CMD_GFEATCFG, 241 201 DCB_CMD_SFEATCFG, 242 202 203 + DCB_CMD_CEE_GET, 204 + 243 205 __DCB_CMD_ENUM_MAX, 244 206 DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, 245 207 }; ··· 264 222 * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED) 265 223 * @DCB_ATTR_DCBX: DCBX engine configuration in the device (NLA_U8) 266 224 * @DCB_ATTR_FEATCFG: DCBX features flags (NLA_NESTED) 225 + * @DCB_ATTR_CEE: CEE std supported attributes (NLA_NESTED) 267 226 */ 268 227 enum dcbnl_attrs { 269 228 DCB_ATTR_UNDEFINED, ··· 287 244 288 245 DCB_ATTR_DCBX, 289 246 DCB_ATTR_FEATCFG, 247 + 248 + /* CEE nested attributes */ 249 + DCB_ATTR_CEE, 290 250 291 251 __DCB_ATTR_ENUM_MAX, 292 252 DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, ··· 324 278 __DCB_ATTR_IEEE_APP_MAX 325 279 }; 326 280 #define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1) 281 + 282 + /** 283 + * enum cee_attrs - CEE DCBX get attributes 284 + * 285 + * @DCB_ATTR_CEE_UNSPEC: unspecified 286 + * @DCB_ATTR_CEE_PEER_PG: peer PG configuration - get only 287 + * @DCB_ATTR_CEE_PEER_PFC: peer PFC configuration - get only 288 + * @DCB_ATTR_CEE_PEER_APP: peer APP tlv - get only 289 + */ 290 + enum cee_attrs { 291 + DCB_ATTR_CEE_UNSPEC, 292 + DCB_ATTR_CEE_PEER_PG, 293 + DCB_ATTR_CEE_PEER_PFC, 294 + DCB_ATTR_CEE_PEER_APP_TABLE, 295 + __DCB_ATTR_CEE_MAX 296 + }; 297 + #define DCB_ATTR_CEE_MAX (__DCB_ATTR_CEE_MAX - 1) 298 + 299 + enum peer_app_attr { 300 + DCB_ATTR_CEE_PEER_APP_UNSPEC, 301 + DCB_ATTR_CEE_PEER_APP_INFO, 302 + DCB_ATTR_CEE_PEER_APP, 303 + __DCB_ATTR_CEE_PEER_APP_MAX 304 + }; 305 + #define DCB_ATTR_CEE_PEER_APP_MAX (__DCB_ATTR_CEE_PEER_APP_MAX - 1) 327 306 328 307 /** 329 308 * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs
+3
include/net/dcbnl.h
··· 84 84 u16 *); 85 85 int (*peer_getapptable)(struct net_device *, struct dcb_app *); 86 86 87 + /* CEE peer */ 88 + int (*cee_peer_getpg) (struct net_device *, struct cee_pg *); 89 + int (*cee_peer_getpfc) (struct net_device *, struct cee_pfc *); 87 90 }; 88 91 89 92 #endif /* __NET_DCBNL_H__ */
+81 -4
net/dcb/dcbnl.c
··· 1224 1224 return err; 1225 1225 } 1226 1226 1227 - static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb) 1227 + static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, 1228 + int app_nested_type, int app_info_type, 1229 + int app_entry_type) 1228 1230 { 1229 1231 struct dcb_peer_app_info info; 1230 1232 struct dcb_app *table = NULL; ··· 1258 1256 */ 1259 1257 err = -EMSGSIZE; 1260 1258 1261 - app = nla_nest_start(skb, DCB_ATTR_IEEE_PEER_APP); 1259 + app = nla_nest_start(skb, app_nested_type); 1262 1260 if (!app) 1263 1261 goto nla_put_failure; 1264 1262 1263 + if (app_info_type) 1264 + NLA_PUT(skb, app_info_type, sizeof(info), &info); 1265 + 1265 1266 for (i = 0; i < app_count; i++) 1266 - NLA_PUT(skb, DCB_ATTR_IEEE_APP, sizeof(struct dcb_app), 1267 + NLA_PUT(skb, app_entry_type, sizeof(struct dcb_app), 1267 1268 &table[i]); 1268 1269 1269 1270 nla_nest_end(skb, app); ··· 1357 1352 } 1358 1353 1359 1354 if (ops->peer_getappinfo && ops->peer_getapptable) { 1360 - err = dcbnl_build_peer_app(netdev, skb); 1355 + err = dcbnl_build_peer_app(netdev, skb, 1356 + DCB_ATTR_IEEE_PEER_APP, 1357 + DCB_ATTR_IEEE_APP_UNSPEC, 1358 + DCB_ATTR_IEEE_APP); 1361 1359 if (err) 1362 1360 goto nla_put_failure; 1363 1361 } ··· 1518 1510 return ret; 1519 1511 } 1520 1512 1513 + /* Handle CEE DCBX GET commands. */ 1514 + static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, 1515 + u32 pid, u32 seq, u16 flags) 1516 + { 1517 + struct sk_buff *skb; 1518 + struct nlmsghdr *nlh; 1519 + struct dcbmsg *dcb; 1520 + struct nlattr *cee; 1521 + const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; 1522 + int err; 1523 + 1524 + if (!ops) 1525 + return -EOPNOTSUPP; 1526 + 1527 + skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); 1528 + if (!skb) 1529 + return -ENOBUFS; 1530 + 1531 + nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); 1532 + 1533 + dcb = NLMSG_DATA(nlh); 1534 + dcb->dcb_family = AF_UNSPEC; 1535 + dcb->cmd = DCB_CMD_CEE_GET; 1536 + 1537 + NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name); 1538 + 1539 + cee = nla_nest_start(skb, DCB_ATTR_CEE); 1540 + if (!cee) 1541 + goto nla_put_failure; 1542 + 1543 + /* get peer info if available */ 1544 + if (ops->cee_peer_getpg) { 1545 + struct cee_pg pg; 1546 + err = ops->cee_peer_getpg(netdev, &pg); 1547 + if (!err) 1548 + NLA_PUT(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg); 1549 + } 1550 + 1551 + if (ops->cee_peer_getpfc) { 1552 + struct cee_pfc pfc; 1553 + err = ops->cee_peer_getpfc(netdev, &pfc); 1554 + if (!err) 1555 + NLA_PUT(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc); 1556 + } 1557 + 1558 + if (ops->peer_getappinfo && ops->peer_getapptable) { 1559 + err = dcbnl_build_peer_app(netdev, skb, 1560 + DCB_ATTR_CEE_PEER_APP_TABLE, 1561 + DCB_ATTR_CEE_PEER_APP_INFO, 1562 + DCB_ATTR_CEE_PEER_APP); 1563 + if (err) 1564 + goto nla_put_failure; 1565 + } 1566 + 1567 + nla_nest_end(skb, cee); 1568 + nlmsg_end(skb, nlh); 1569 + 1570 + return rtnl_unicast(skb, &init_net, pid); 1571 + nla_put_failure: 1572 + nlmsg_cancel(skb, nlh); 1573 + nlmsg_failure: 1574 + kfree_skb(skb); 1575 + return -1; 1576 + } 1577 + 1521 1578 static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 1522 1579 { 1523 1580 struct net *net = sock_net(skb->sk); ··· 1711 1638 case DCB_CMD_SFEATCFG: 1712 1639 ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, 1713 1640 nlh->nlmsg_flags); 1641 + goto out; 1642 + case DCB_CMD_CEE_GET: 1643 + ret = dcbnl_cee_get(netdev, tb, pid, nlh->nlmsg_seq, 1644 + nlh->nlmsg_flags); 1714 1645 goto out; 1715 1646 default: 1716 1647 goto errout;