aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShmulik Ravid <shmulikr@broadcom.com>2011-02-27 00:04:31 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-03 00:58:54 -0500
commiteed84713bc47ce2f7d675914f297ad9b6227a587 (patch)
tree27da816e2d37163409639639c37171bb4c53945c
parent23b41168fc942a4a041325a04ecc1bd17d031a3e (diff)
dcbnl: add support for retrieving peer configuration - ieee
These 2 patches add the support for retrieving the remote or peer DCBX configuration via dcbnl for embedded DCBX stacks. The peer configuration is part of the DCBX MIB and is useful for debugging and diagnostics of the overall DCB configuration. The first patch add this support for IEEE 802.1Qaz standard the second patch add the same support for the older CEE standard. Diff for v2 - the peer-app-info is CEE specific. Signed-off-by: Shmulik Ravid <shmulikr@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/dcbnl.h28
-rw-r--r--include/net/dcbnl.h6
-rw-r--r--net/dcb/dcbnl.c69
3 files changed, 103 insertions, 0 deletions
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h
index 4c5b26e0cc48..2542685f8b3e 100644
--- a/include/linux/dcbnl.h
+++ b/include/linux/dcbnl.h
@@ -110,6 +110,20 @@ struct dcb_app {
110 __u16 protocol; 110 __u16 protocol;
111}; 111};
112 112
113/**
114 * struct dcb_peer_app_info - APP feature information sent by the peer
115 *
116 * @willing: willing bit in the peer APP tlv
117 * @error: error bit in the peer APP tlv
118 *
119 * In addition to this information the full peer APP tlv also contains
120 * a table of 'app_count' APP objects defined above.
121 */
122struct dcb_peer_app_info {
123 __u8 willing;
124 __u8 error;
125};
126
113struct dcbmsg { 127struct dcbmsg {
114 __u8 dcb_family; 128 __u8 dcb_family;
115 __u8 cmd; 129 __u8 cmd;
@@ -235,11 +249,25 @@ enum dcbnl_attrs {
235 DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, 249 DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1,
236}; 250};
237 251
252/**
253 * enum ieee_attrs - IEEE 802.1Qaz get/set attributes
254 *
255 * @DCB_ATTR_IEEE_UNSPEC: unspecified
256 * @DCB_ATTR_IEEE_ETS: negotiated ETS configuration
257 * @DCB_ATTR_IEEE_PFC: negotiated PFC configuration
258 * @DCB_ATTR_IEEE_APP_TABLE: negotiated APP configuration
259 * @DCB_ATTR_IEEE_PEER_ETS: peer ETS configuration - get only
260 * @DCB_ATTR_IEEE_PEER_PFC: peer PFC configuration - get only
261 * @DCB_ATTR_IEEE_PEER_APP: peer APP tlv - get only
262 */
238enum ieee_attrs { 263enum ieee_attrs {
239 DCB_ATTR_IEEE_UNSPEC, 264 DCB_ATTR_IEEE_UNSPEC,
240 DCB_ATTR_IEEE_ETS, 265 DCB_ATTR_IEEE_ETS,
241 DCB_ATTR_IEEE_PFC, 266 DCB_ATTR_IEEE_PFC,
242 DCB_ATTR_IEEE_APP_TABLE, 267 DCB_ATTR_IEEE_APP_TABLE,
268 DCB_ATTR_IEEE_PEER_ETS,
269 DCB_ATTR_IEEE_PEER_PFC,
270 DCB_ATTR_IEEE_PEER_APP,
243 __DCB_ATTR_IEEE_MAX 271 __DCB_ATTR_IEEE_MAX
244}; 272};
245#define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1) 273#define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1)
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h
index a8e7852b10ab..7b7180e692ef 100644
--- a/include/net/dcbnl.h
+++ b/include/net/dcbnl.h
@@ -43,6 +43,8 @@ struct dcbnl_rtnl_ops {
43 int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); 43 int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *);
44 int (*ieee_getapp) (struct net_device *, struct dcb_app *); 44 int (*ieee_getapp) (struct net_device *, struct dcb_app *);
45 int (*ieee_setapp) (struct net_device *, struct dcb_app *); 45 int (*ieee_setapp) (struct net_device *, struct dcb_app *);
46 int (*ieee_peer_getets) (struct net_device *, struct ieee_ets *);
47 int (*ieee_peer_getpfc) (struct net_device *, struct ieee_pfc *);
46 48
47 /* CEE std */ 49 /* CEE std */
48 u8 (*getstate)(struct net_device *); 50 u8 (*getstate)(struct net_device *);
@@ -77,6 +79,10 @@ struct dcbnl_rtnl_ops {
77 u8 (*getdcbx)(struct net_device *); 79 u8 (*getdcbx)(struct net_device *);
78 u8 (*setdcbx)(struct net_device *, u8); 80 u8 (*setdcbx)(struct net_device *, u8);
79 81
82 /* peer apps */
83 int (*peer_getappinfo)(struct net_device *, struct dcb_peer_app_info *,
84 u16 *);
85 int (*peer_getapptable)(struct net_device *, struct dcb_app *);
80 86
81}; 87};
82 88
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index d5074a567289..2e6dcf2967e2 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -1224,6 +1224,54 @@ err:
1224 return err; 1224 return err;
1225} 1225}
1226 1226
1227static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb)
1228{
1229 struct dcb_peer_app_info info;
1230 struct dcb_app *table = NULL;
1231 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1232 u16 app_count;
1233 int err;
1234
1235
1236 /**
1237 * retrieve the peer app configuration form the driver. If the driver
1238 * handlers fail exit without doing anything
1239 */
1240 err = ops->peer_getappinfo(netdev, &info, &app_count);
1241 if (!err && app_count) {
1242 table = kmalloc(sizeof(struct dcb_app) * app_count, GFP_KERNEL);
1243 if (!table)
1244 return -ENOMEM;
1245
1246 err = ops->peer_getapptable(netdev, table);
1247 }
1248
1249 if (!err) {
1250 u16 i;
1251 struct nlattr *app;
1252
1253 /**
1254 * build the message, from here on the only possible failure
1255 * is due to the skb size
1256 */
1257 err = -EMSGSIZE;
1258
1259 app = nla_nest_start(skb, DCB_ATTR_IEEE_PEER_APP);
1260 if (!app)
1261 goto nla_put_failure;
1262
1263 for (i = 0; i < app_count; i++)
1264 NLA_PUT(skb, DCB_ATTR_IEEE_APP, sizeof(struct dcb_app),
1265 &table[i]);
1266
1267 nla_nest_end(skb, app);
1268 }
1269 err = 0;
1270
1271nla_put_failure:
1272 kfree(table);
1273 return err;
1274}
1227 1275
1228/* Handle IEEE 802.1Qaz GET commands. */ 1276/* Handle IEEE 802.1Qaz GET commands. */
1229static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb, 1277static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
@@ -1288,6 +1336,27 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
1288 spin_unlock(&dcb_lock); 1336 spin_unlock(&dcb_lock);
1289 nla_nest_end(skb, app); 1337 nla_nest_end(skb, app);
1290 1338
1339 /* get peer info if available */
1340 if (ops->ieee_peer_getets) {
1341 struct ieee_ets ets;
1342 err = ops->ieee_peer_getets(netdev, &ets);
1343 if (!err)
1344 NLA_PUT(skb, DCB_ATTR_IEEE_PEER_ETS, sizeof(ets), &ets);
1345 }
1346
1347 if (ops->ieee_peer_getpfc) {
1348 struct ieee_pfc pfc;
1349 err = ops->ieee_peer_getpfc(netdev, &pfc);
1350 if (!err)
1351 NLA_PUT(skb, DCB_ATTR_IEEE_PEER_PFC, sizeof(pfc), &pfc);
1352 }
1353
1354 if (ops->peer_getappinfo && ops->peer_getapptable) {
1355 err = dcbnl_build_peer_app(netdev, skb);
1356 if (err)
1357 goto nla_put_failure;
1358 }
1359
1291 nla_nest_end(skb, ieee); 1360 nla_nest_end(skb, ieee);
1292 nlmsg_end(skb, nlh); 1361 nlmsg_end(skb, nlh);
1293 1362