diff options
| author | Shmulik Ravid <shmulikr@broadcom.com> | 2011-02-27 00:04:38 -0500 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2011-03-03 00:58:55 -0500 |
| commit | dc6ed1df5a5f84e45e77e2acb6fd99b995414956 (patch) | |
| tree | 3decaad599f29cb097fc370f1ed92a18fa3596ea | |
| parent | eed84713bc47ce2f7d675914f297ad9b6227a587 (diff) | |
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>
| -rw-r--r-- | include/linux/dcbnl.h | 71 | ||||
| -rw-r--r-- | include/net/dcbnl.h | 3 | ||||
| -rw-r--r-- | net/dcb/dcbnl.c | 85 |
3 files changed, 155 insertions, 4 deletions
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h index 2542685f8b3e..a3680a16718f 100644 --- a/include/linux/dcbnl.h +++ b/include/linux/dcbnl.h | |||
| @@ -87,6 +87,45 @@ struct ieee_pfc { | |||
| 87 | __u64 indications[IEEE_8021QAZ_MAX_TCS]; | 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 | /* This structure contains the IEEE 802.1Qaz APP managed object. This | 129 | /* This structure contains the IEEE 802.1Qaz APP managed object. This |
| 91 | * object is also used for the CEE std as well. There is no difference | 130 | * object is also used for the CEE std as well. There is no difference |
| 92 | * between the objects. | 131 | * between the objects. |
| @@ -158,6 +197,7 @@ struct dcbmsg { | |||
| 158 | * @DCB_CMD_SDCBX: set DCBX engine configuration | 197 | * @DCB_CMD_SDCBX: set DCBX engine configuration |
| 159 | * @DCB_CMD_GFEATCFG: get DCBX features flags | 198 | * @DCB_CMD_GFEATCFG: get DCBX features flags |
| 160 | * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags | 199 | * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags |
| 200 | * @DCB_CMD_CEE_GET: get CEE aggregated configuration | ||
| 161 | */ | 201 | */ |
| 162 | enum dcbnl_commands { | 202 | enum dcbnl_commands { |
| 163 | DCB_CMD_UNDEFINED, | 203 | DCB_CMD_UNDEFINED, |
| @@ -200,6 +240,8 @@ enum dcbnl_commands { | |||
| 200 | DCB_CMD_GFEATCFG, | 240 | DCB_CMD_GFEATCFG, |
| 201 | DCB_CMD_SFEATCFG, | 241 | DCB_CMD_SFEATCFG, |
| 202 | 242 | ||
| 243 | DCB_CMD_CEE_GET, | ||
| 244 | |||
| 203 | __DCB_CMD_ENUM_MAX, | 245 | __DCB_CMD_ENUM_MAX, |
| 204 | DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, | 246 | DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, |
| 205 | }; | 247 | }; |
| @@ -222,6 +264,7 @@ enum dcbnl_commands { | |||
| 222 | * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED) | 264 | * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED) |
| 223 | * @DCB_ATTR_DCBX: DCBX engine configuration in the device (NLA_U8) | 265 | * @DCB_ATTR_DCBX: DCBX engine configuration in the device (NLA_U8) |
| 224 | * @DCB_ATTR_FEATCFG: DCBX features flags (NLA_NESTED) | 266 | * @DCB_ATTR_FEATCFG: DCBX features flags (NLA_NESTED) |
| 267 | * @DCB_ATTR_CEE: CEE std supported attributes (NLA_NESTED) | ||
| 225 | */ | 268 | */ |
| 226 | enum dcbnl_attrs { | 269 | enum dcbnl_attrs { |
| 227 | DCB_ATTR_UNDEFINED, | 270 | DCB_ATTR_UNDEFINED, |
| @@ -245,6 +288,9 @@ enum dcbnl_attrs { | |||
| 245 | DCB_ATTR_DCBX, | 288 | DCB_ATTR_DCBX, |
| 246 | DCB_ATTR_FEATCFG, | 289 | DCB_ATTR_FEATCFG, |
| 247 | 290 | ||
| 291 | /* CEE nested attributes */ | ||
| 292 | DCB_ATTR_CEE, | ||
| 293 | |||
| 248 | __DCB_ATTR_ENUM_MAX, | 294 | __DCB_ATTR_ENUM_MAX, |
| 249 | DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, | 295 | DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, |
| 250 | }; | 296 | }; |
| @@ -280,6 +326,31 @@ enum ieee_attrs_app { | |||
| 280 | #define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1) | 326 | #define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1) |
| 281 | 327 | ||
| 282 | /** | 328 | /** |
| 329 | * enum cee_attrs - CEE DCBX get attributes | ||
| 330 | * | ||
| 331 | * @DCB_ATTR_CEE_UNSPEC: unspecified | ||
| 332 | * @DCB_ATTR_CEE_PEER_PG: peer PG configuration - get only | ||
| 333 | * @DCB_ATTR_CEE_PEER_PFC: peer PFC configuration - get only | ||
| 334 | * @DCB_ATTR_CEE_PEER_APP: peer APP tlv - get only | ||
| 335 | */ | ||
| 336 | enum cee_attrs { | ||
| 337 | DCB_ATTR_CEE_UNSPEC, | ||
| 338 | DCB_ATTR_CEE_PEER_PG, | ||
| 339 | DCB_ATTR_CEE_PEER_PFC, | ||
| 340 | DCB_ATTR_CEE_PEER_APP_TABLE, | ||
| 341 | __DCB_ATTR_CEE_MAX | ||
| 342 | }; | ||
| 343 | #define DCB_ATTR_CEE_MAX (__DCB_ATTR_CEE_MAX - 1) | ||
| 344 | |||
| 345 | enum peer_app_attr { | ||
| 346 | DCB_ATTR_CEE_PEER_APP_UNSPEC, | ||
| 347 | DCB_ATTR_CEE_PEER_APP_INFO, | ||
| 348 | DCB_ATTR_CEE_PEER_APP, | ||
| 349 | __DCB_ATTR_CEE_PEER_APP_MAX | ||
| 350 | }; | ||
| 351 | #define DCB_ATTR_CEE_PEER_APP_MAX (__DCB_ATTR_CEE_PEER_APP_MAX - 1) | ||
| 352 | |||
| 353 | /** | ||
| 283 | * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs | 354 | * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs |
| 284 | * | 355 | * |
| 285 | * @DCB_PFC_UP_ATTR_UNDEFINED: unspecified attribute to catch errors | 356 | * @DCB_PFC_UP_ATTR_UNDEFINED: unspecified attribute to catch errors |
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index 7b7180e692ef..e5983c9053dc 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h | |||
| @@ -84,6 +84,9 @@ struct dcbnl_rtnl_ops { | |||
| 84 | u16 *); | 84 | u16 *); |
| 85 | int (*peer_getapptable)(struct net_device *, struct dcb_app *); | 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 | #endif /* __NET_DCBNL_H__ */ | 92 | #endif /* __NET_DCBNL_H__ */ |
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 2e6dcf2967e2..d8b4f725b778 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
| @@ -1224,7 +1224,9 @@ err: | |||
| 1224 | return err; | 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 | struct dcb_peer_app_info info; | 1231 | struct dcb_peer_app_info info; |
| 1230 | struct dcb_app *table = NULL; | 1232 | struct dcb_app *table = NULL; |
| @@ -1256,12 +1258,15 @@ static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb) | |||
| 1256 | */ | 1258 | */ |
| 1257 | err = -EMSGSIZE; | 1259 | err = -EMSGSIZE; |
| 1258 | 1260 | ||
| 1259 | app = nla_nest_start(skb, DCB_ATTR_IEEE_PEER_APP); | 1261 | app = nla_nest_start(skb, app_nested_type); |
| 1260 | if (!app) | 1262 | if (!app) |
| 1261 | goto nla_put_failure; | 1263 | goto nla_put_failure; |
| 1262 | 1264 | ||
| 1265 | if (app_info_type) | ||
| 1266 | NLA_PUT(skb, app_info_type, sizeof(info), &info); | ||
| 1267 | |||
| 1263 | for (i = 0; i < app_count; i++) | 1268 | for (i = 0; i < app_count; i++) |
| 1264 | NLA_PUT(skb, DCB_ATTR_IEEE_APP, sizeof(struct dcb_app), | 1269 | NLA_PUT(skb, app_entry_type, sizeof(struct dcb_app), |
| 1265 | &table[i]); | 1270 | &table[i]); |
| 1266 | 1271 | ||
| 1267 | nla_nest_end(skb, app); | 1272 | nla_nest_end(skb, app); |
| @@ -1352,7 +1357,10 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, | |||
| 1352 | } | 1357 | } |
| 1353 | 1358 | ||
| 1354 | if (ops->peer_getappinfo && ops->peer_getapptable) { | 1359 | if (ops->peer_getappinfo && ops->peer_getapptable) { |
| 1355 | err = dcbnl_build_peer_app(netdev, skb); | 1360 | err = dcbnl_build_peer_app(netdev, skb, |
| 1361 | DCB_ATTR_IEEE_PEER_APP, | ||
| 1362 | DCB_ATTR_IEEE_APP_UNSPEC, | ||
| 1363 | DCB_ATTR_IEEE_APP); | ||
| 1356 | if (err) | 1364 | if (err) |
| 1357 | goto nla_put_failure; | 1365 | goto nla_put_failure; |
| 1358 | } | 1366 | } |
| @@ -1510,6 +1518,71 @@ err: | |||
| 1510 | return ret; | 1518 | return ret; |
| 1511 | } | 1519 | } |
| 1512 | 1520 | ||
| 1521 | /* Handle CEE DCBX GET commands. */ | ||
| 1522 | static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb, | ||
| 1523 | u32 pid, u32 seq, u16 flags) | ||
| 1524 | { | ||
| 1525 | struct sk_buff *skb; | ||
| 1526 | struct nlmsghdr *nlh; | ||
| 1527 | struct dcbmsg *dcb; | ||
| 1528 | struct nlattr *cee; | ||
| 1529 | const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops; | ||
| 1530 | int err; | ||
| 1531 | |||
| 1532 | if (!ops) | ||
| 1533 | return -EOPNOTSUPP; | ||
| 1534 | |||
| 1535 | skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL); | ||
| 1536 | if (!skb) | ||
| 1537 | return -ENOBUFS; | ||
| 1538 | |||
| 1539 | nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags); | ||
| 1540 | |||
| 1541 | dcb = NLMSG_DATA(nlh); | ||
| 1542 | dcb->dcb_family = AF_UNSPEC; | ||
| 1543 | dcb->cmd = DCB_CMD_CEE_GET; | ||
| 1544 | |||
| 1545 | NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name); | ||
| 1546 | |||
| 1547 | cee = nla_nest_start(skb, DCB_ATTR_CEE); | ||
| 1548 | if (!cee) | ||
| 1549 | goto nla_put_failure; | ||
| 1550 | |||
| 1551 | /* get peer info if available */ | ||
| 1552 | if (ops->cee_peer_getpg) { | ||
| 1553 | struct cee_pg pg; | ||
| 1554 | err = ops->cee_peer_getpg(netdev, &pg); | ||
| 1555 | if (!err) | ||
| 1556 | NLA_PUT(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg); | ||
| 1557 | } | ||
| 1558 | |||
| 1559 | if (ops->cee_peer_getpfc) { | ||
| 1560 | struct cee_pfc pfc; | ||
| 1561 | err = ops->cee_peer_getpfc(netdev, &pfc); | ||
| 1562 | if (!err) | ||
| 1563 | NLA_PUT(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc); | ||
| 1564 | } | ||
| 1565 | |||
| 1566 | if (ops->peer_getappinfo && ops->peer_getapptable) { | ||
| 1567 | err = dcbnl_build_peer_app(netdev, skb, | ||
| 1568 | DCB_ATTR_CEE_PEER_APP_TABLE, | ||
| 1569 | DCB_ATTR_CEE_PEER_APP_INFO, | ||
| 1570 | DCB_ATTR_CEE_PEER_APP); | ||
| 1571 | if (err) | ||
| 1572 | goto nla_put_failure; | ||
| 1573 | } | ||
| 1574 | |||
| 1575 | nla_nest_end(skb, cee); | ||
| 1576 | nlmsg_end(skb, nlh); | ||
| 1577 | |||
| 1578 | return rtnl_unicast(skb, &init_net, pid); | ||
| 1579 | nla_put_failure: | ||
| 1580 | nlmsg_cancel(skb, nlh); | ||
| 1581 | nlmsg_failure: | ||
| 1582 | kfree_skb(skb); | ||
| 1583 | return -1; | ||
| 1584 | } | ||
| 1585 | |||
| 1513 | static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 1586 | static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) |
| 1514 | { | 1587 | { |
| 1515 | struct net *net = sock_net(skb->sk); | 1588 | struct net *net = sock_net(skb->sk); |
| @@ -1639,6 +1712,10 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
| 1639 | ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, | 1712 | ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq, |
| 1640 | nlh->nlmsg_flags); | 1713 | nlh->nlmsg_flags); |
| 1641 | goto out; | 1714 | goto out; |
| 1715 | case DCB_CMD_CEE_GET: | ||
| 1716 | ret = dcbnl_cee_get(netdev, tb, pid, nlh->nlmsg_seq, | ||
| 1717 | nlh->nlmsg_flags); | ||
| 1718 | goto out; | ||
| 1642 | default: | 1719 | default: |
| 1643 | goto errout; | 1720 | goto errout; |
| 1644 | } | 1721 | } |
