diff options
| author | Amir Vadai <amirv@mellanox.com> | 2012-04-04 17:33:30 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2012-04-05 05:08:04 -0400 |
| commit | 08f10affe45051e18e0d8291c0a53aecef1b8a14 (patch) | |
| tree | 0f18aa6f7d3885f695dfe5ad876363afe03ce6a6 | |
| parent | 366cddb4028858079a9a8145bd713c13a9edb3dc (diff) | |
net/dcb: Add an optional max rate attribute
Although not specified in 8021Qaz spec, it could be useful to enable drivers
whose HW supports setting a rate limit for an ETS TC. This patch adds this
optional attribute to DCB netlink. To use it, drivers should implement and
register the callbacks ieee_setmaxrate and ieee_getmaxrate. The units are 64
bits long and specified in Kbps to enable usage over both slow and very fast
networks.
Signed-off-by: Amir Vadai <amirv@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | include/linux/dcbnl.h | 12 | ||||
| -rw-r--r-- | include/net/dcbnl.h | 2 | ||||
| -rw-r--r-- | net/dcb/dcbnl.c | 20 |
3 files changed, 34 insertions, 0 deletions
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h index 65a2562f66b4..6bb43382f3f3 100644 --- a/include/linux/dcbnl.h +++ b/include/linux/dcbnl.h | |||
| @@ -67,6 +67,17 @@ struct ieee_ets { | |||
| 67 | __u8 reco_prio_tc[IEEE_8021QAZ_MAX_TCS]; | 67 | __u8 reco_prio_tc[IEEE_8021QAZ_MAX_TCS]; |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | /* This structure contains rate limit extension to the IEEE 802.1Qaz ETS | ||
| 71 | * managed object. | ||
| 72 | * Values are 64 bits long and specified in Kbps to enable usage over both | ||
| 73 | * slow and very fast networks. | ||
| 74 | * | ||
| 75 | * @tc_maxrate: maximal tc tx bandwidth indexed by traffic class | ||
| 76 | */ | ||
| 77 | struct ieee_maxrate { | ||
| 78 | __u64 tc_maxrate[IEEE_8021QAZ_MAX_TCS]; | ||
| 79 | }; | ||
| 80 | |||
| 70 | /* This structure contains the IEEE 802.1Qaz PFC managed object | 81 | /* This structure contains the IEEE 802.1Qaz PFC managed object |
| 71 | * | 82 | * |
| 72 | * @pfc_cap: Indicates the number of traffic classes on the local device | 83 | * @pfc_cap: Indicates the number of traffic classes on the local device |
| @@ -321,6 +332,7 @@ enum ieee_attrs { | |||
| 321 | DCB_ATTR_IEEE_PEER_ETS, | 332 | DCB_ATTR_IEEE_PEER_ETS, |
| 322 | DCB_ATTR_IEEE_PEER_PFC, | 333 | DCB_ATTR_IEEE_PEER_PFC, |
| 323 | DCB_ATTR_IEEE_PEER_APP, | 334 | DCB_ATTR_IEEE_PEER_APP, |
| 335 | DCB_ATTR_IEEE_MAXRATE, | ||
| 324 | __DCB_ATTR_IEEE_MAX | 336 | __DCB_ATTR_IEEE_MAX |
| 325 | }; | 337 | }; |
| 326 | #define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1) | 338 | #define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1) |
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index f55c980d8e23..fc5d5dcebb00 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h | |||
| @@ -48,6 +48,8 @@ struct dcbnl_rtnl_ops { | |||
| 48 | /* IEEE 802.1Qaz std */ | 48 | /* IEEE 802.1Qaz std */ |
| 49 | int (*ieee_getets) (struct net_device *, struct ieee_ets *); | 49 | int (*ieee_getets) (struct net_device *, struct ieee_ets *); |
| 50 | int (*ieee_setets) (struct net_device *, struct ieee_ets *); | 50 | int (*ieee_setets) (struct net_device *, struct ieee_ets *); |
| 51 | int (*ieee_getmaxrate) (struct net_device *, struct ieee_maxrate *); | ||
| 52 | int (*ieee_setmaxrate) (struct net_device *, struct ieee_maxrate *); | ||
| 51 | int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *); | 53 | int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *); |
| 52 | int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); | 54 | int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); |
| 53 | int (*ieee_getapp) (struct net_device *, struct dcb_app *); | 55 | int (*ieee_getapp) (struct net_device *, struct dcb_app *); |
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 36f37af63bf2..8dfa1da7c40d 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
| @@ -178,6 +178,7 @@ static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = { | |||
| 178 | [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)}, | 178 | [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)}, |
| 179 | [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)}, | 179 | [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)}, |
| 180 | [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED}, | 180 | [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED}, |
| 181 | [DCB_ATTR_IEEE_MAXRATE] = {.len = sizeof(struct ieee_maxrate)}, | ||
| 181 | }; | 182 | }; |
| 182 | 183 | ||
| 183 | static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { | 184 | static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { |
| @@ -1246,6 +1247,17 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) | |||
| 1246 | goto nla_put_failure; | 1247 | goto nla_put_failure; |
| 1247 | } | 1248 | } |
| 1248 | 1249 | ||
| 1250 | if (ops->ieee_getmaxrate) { | ||
| 1251 | struct ieee_maxrate maxrate; | ||
| 1252 | err = ops->ieee_getmaxrate(netdev, &maxrate); | ||
| 1253 | if (!err) { | ||
| 1254 | err = nla_put(skb, DCB_ATTR_IEEE_MAXRATE, | ||
| 1255 | sizeof(maxrate), &maxrate); | ||
| 1256 | if (err) | ||
| 1257 | goto nla_put_failure; | ||
| 1258 | } | ||
| 1259 | } | ||
| 1260 | |||
| 1249 | if (ops->ieee_getpfc) { | 1261 | if (ops->ieee_getpfc) { |
| 1250 | struct ieee_pfc pfc; | 1262 | struct ieee_pfc pfc; |
| 1251 | err = ops->ieee_getpfc(netdev, &pfc); | 1263 | err = ops->ieee_getpfc(netdev, &pfc); |
| @@ -1601,6 +1613,14 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb, | |||
| 1601 | goto err; | 1613 | goto err; |
| 1602 | } | 1614 | } |
| 1603 | 1615 | ||
| 1616 | if (ieee[DCB_ATTR_IEEE_MAXRATE] && ops->ieee_setmaxrate) { | ||
| 1617 | struct ieee_maxrate *maxrate = | ||
| 1618 | nla_data(ieee[DCB_ATTR_IEEE_MAXRATE]); | ||
| 1619 | err = ops->ieee_setmaxrate(netdev, maxrate); | ||
| 1620 | if (err) | ||
| 1621 | goto err; | ||
| 1622 | } | ||
| 1623 | |||
| 1604 | if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { | 1624 | if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { |
| 1605 | struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); | 1625 | struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); |
| 1606 | err = ops->ieee_setpfc(netdev, pfc); | 1626 | err = ops->ieee_setpfc(netdev, pfc); |
