Commit 46132188bf72e22ef097f16ed5c969ee8cea1e8b

Authored by Alexander Duyck
Committed by David S. Miller
1 parent 2f90b8657e

DCB: Add interface to query for the DCB capabilities of an device.

Adds to the netlink interface for Data Center Bridging (DCB), allowing
the DCB capabilities supported by a device to be queried.

Signed-off-by: Alexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: Peter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

Showing 4 changed files with 161 additions and 1 deletions Side-by-side Diff

drivers/net/ixgbe/ixgbe_dcb_nl.c
... ... @@ -337,6 +337,45 @@
337 337 return ret;
338 338 }
339 339  
  340 +static u8 ixgbe_dcbnl_getcap(struct net_device *netdev, int capid, u8 *cap)
  341 +{
  342 + struct ixgbe_adapter *adapter = netdev_priv(netdev);
  343 + u8 rval = 0;
  344 +
  345 + if (adapter->flags & IXGBE_FLAG_DCB_ENABLED) {
  346 + switch (capid) {
  347 + case DCB_CAP_ATTR_PG:
  348 + *cap = true;
  349 + break;
  350 + case DCB_CAP_ATTR_PFC:
  351 + *cap = true;
  352 + break;
  353 + case DCB_CAP_ATTR_UP2TC:
  354 + *cap = false;
  355 + break;
  356 + case DCB_CAP_ATTR_PG_TCS:
  357 + *cap = 0x80;
  358 + break;
  359 + case DCB_CAP_ATTR_PFC_TCS:
  360 + *cap = 0x80;
  361 + break;
  362 + case DCB_CAP_ATTR_GSP:
  363 + *cap = true;
  364 + break;
  365 + case DCB_CAP_ATTR_BCN:
  366 + *cap = false;
  367 + break;
  368 + default:
  369 + rval = -EINVAL;
  370 + break;
  371 + }
  372 + } else {
  373 + rval = -EINVAL;
  374 + }
  375 +
  376 + return rval;
  377 +}
  378 +
340 379 struct dcbnl_rtnl_ops dcbnl_ops = {
341 380 .getstate = ixgbe_dcbnl_get_state,
342 381 .setstate = ixgbe_dcbnl_set_state,
... ... @@ -351,6 +390,7 @@
351 390 .getpgbwgcfgrx = ixgbe_dcbnl_get_pg_bwg_cfg_rx,
352 391 .setpfccfg = ixgbe_dcbnl_set_pfc_cfg,
353 392 .getpfccfg = ixgbe_dcbnl_get_pfc_cfg,
354   - .setall = ixgbe_dcbnl_set_all
  393 + .setall = ixgbe_dcbnl_set_all,
  394 + .getcap = ixgbe_dcbnl_getcap
355 395 };
include/linux/dcbnl.h
... ... @@ -43,6 +43,7 @@
43 43 * @DCB_CMD_SET_ALL: apply all changes to the underlying device
44 44 * @DCB_CMD_GPERM_HWADDR: get the permanent MAC address of the underlying
45 45 * device. Only useful when using bonding.
  46 + * @DCB_CMD_GCAP: request the DCB capabilities of the device
46 47 */
47 48 enum dcbnl_commands {
48 49 DCB_CMD_UNDEFINED,
... ... @@ -60,6 +61,7 @@
60 61  
61 62 DCB_CMD_SET_ALL,
62 63 DCB_CMD_GPERM_HWADDR,
  64 + DCB_CMD_GCAP,
63 65  
64 66 __DCB_CMD_ENUM_MAX,
65 67 DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1,
... ... @@ -78,6 +80,7 @@
78 80 * @DCB_ATTR_PG_CFG: priority group configuration (NLA_NESTED)
79 81 * @DCB_ATTR_SET_ALL: bool to commit changes to hardware or not (NLA_U8)
80 82 * @DCB_ATTR_PERM_HWADDR: MAC address of the physical device (NLA_NESTED)
  83 + * @DCB_ATTR_CAP: DCB capabilities of the device (NLA_NESTED)
81 84 */
82 85 enum dcbnl_attrs {
83 86 DCB_ATTR_UNDEFINED,
... ... @@ -90,6 +93,7 @@
90 93 DCB_ATTR_PG_CFG,
91 94 DCB_ATTR_SET_ALL,
92 95 DCB_ATTR_PERM_HWADDR,
  96 + DCB_ATTR_CAP,
93 97  
94 98 __DCB_ATTR_ENUM_MAX,
95 99 DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1,
... ... @@ -216,6 +220,39 @@
216 220 DCB_TC_ATTR_PARAM_MAX = __DCB_TC_ATTR_PARAM_ENUM_MAX - 1,
217 221 };
218 222  
  223 +/**
  224 + * enum dcbnl_cap_attrs - DCB Capability attributes
  225 + *
  226 + * @DCB_CAP_ATTR_UNDEFINED: unspecified attribute to catch errors
  227 + * @DCB_CAP_ATTR_ALL: (NLA_FLAG) all capability parameters
  228 + * @DCB_CAP_ATTR_PG: (NLA_U8) device supports Priority Groups
  229 + * @DCB_CAP_ATTR_PFC: (NLA_U8) device supports Priority Flow Control
  230 + * @DCB_CAP_ATTR_UP2TC: (NLA_U8) device supports user priority to
  231 + * traffic class mapping
  232 + * @DCB_CAP_ATTR_PG_TCS: (NLA_U8) bitmap where each bit represents a
  233 + * number of traffic classes the device
  234 + * can be configured to use for Priority Groups
  235 + * @DCB_CAP_ATTR_PFC_TCS: (NLA_U8) bitmap where each bit represents a
  236 + * number of traffic classes the device can be
  237 + * configured to use for Priority Flow Control
  238 + * @DCB_CAP_ATTR_GSP: (NLA_U8) device supports group strict priority
  239 + * @DCB_CAP_ATTR_BCN: (NLA_U8) device supports Backwards Congestion
  240 + * Notification
  241 + */
  242 +enum dcbnl_cap_attrs {
  243 + DCB_CAP_ATTR_UNDEFINED,
  244 + DCB_CAP_ATTR_ALL,
  245 + DCB_CAP_ATTR_PG,
  246 + DCB_CAP_ATTR_PFC,
  247 + DCB_CAP_ATTR_UP2TC,
  248 + DCB_CAP_ATTR_PG_TCS,
  249 + DCB_CAP_ATTR_PFC_TCS,
  250 + DCB_CAP_ATTR_GSP,
  251 + DCB_CAP_ATTR_BCN,
  252 +
  253 + __DCB_CAP_ATTR_ENUM_MAX,
  254 + DCB_CAP_ATTR_MAX = __DCB_CAP_ATTR_ENUM_MAX - 1,
  255 +};
219 256 /**
220 257 * enum dcb_general_attr_values - general DCB attribute values
221 258 *
... ... @@ -39,6 +39,7 @@
39 39 void (*setpfccfg)(struct net_device *, int, u8);
40 40 void (*getpfccfg)(struct net_device *, int, u8 *);
41 41 u8 (*setall)(struct net_device *);
  42 + u8 (*getcap)(struct net_device *, int, u8 *);
42 43 };
43 44  
44 45 #endif /* __NET_DCBNL_H__ */
... ... @@ -61,6 +61,7 @@
61 61 [DCB_ATTR_PG_CFG] = {.type = NLA_NESTED},
62 62 [DCB_ATTR_SET_ALL] = {.type = NLA_U8},
63 63 [DCB_ATTR_PERM_HWADDR] = {.type = NLA_FLAG},
  64 + [DCB_ATTR_CAP] = {.type = NLA_NESTED},
64 65 };
65 66  
66 67 /* DCB priority flow control to User Priority nested attributes */
... ... @@ -107,6 +108,17 @@
107 108 [DCB_TC_ATTR_PARAM_ALL] = {.type = NLA_FLAG},
108 109 };
109 110  
  111 +/* DCB capabilities nested attributes. */
  112 +static struct nla_policy dcbnl_cap_nest[DCB_CAP_ATTR_MAX + 1] = {
  113 + [DCB_CAP_ATTR_ALL] = {.type = NLA_FLAG},
  114 + [DCB_CAP_ATTR_PG] = {.type = NLA_U8},
  115 + [DCB_CAP_ATTR_PFC] = {.type = NLA_U8},
  116 + [DCB_CAP_ATTR_UP2TC] = {.type = NLA_U8},
  117 + [DCB_CAP_ATTR_PG_TCS] = {.type = NLA_U8},
  118 + [DCB_CAP_ATTR_PFC_TCS] = {.type = NLA_U8},
  119 + [DCB_CAP_ATTR_GSP] = {.type = NLA_U8},
  120 + [DCB_CAP_ATTR_BCN] = {.type = NLA_U8},
  121 +};
110 122  
111 123 /* standard netlink reply call */
112 124 static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
... ... @@ -269,6 +281,72 @@
269 281 return -EINVAL;
270 282 }
271 283  
  284 +static int dcbnl_getcap(struct net_device *netdev, struct nlattr **tb,
  285 + u32 pid, u32 seq, u16 flags)
  286 +{
  287 + struct sk_buff *dcbnl_skb;
  288 + struct nlmsghdr *nlh;
  289 + struct dcbmsg *dcb;
  290 + struct nlattr *data[DCB_CAP_ATTR_MAX + 1], *nest;
  291 + u8 value;
  292 + int ret = -EINVAL;
  293 + int i;
  294 + int getall = 0;
  295 +
  296 + if (!tb[DCB_ATTR_CAP] || !netdev->dcbnl_ops->getcap)
  297 + return ret;
  298 +
  299 + ret = nla_parse_nested(data, DCB_CAP_ATTR_MAX, tb[DCB_ATTR_CAP],
  300 + dcbnl_cap_nest);
  301 + if (ret)
  302 + goto err_out;
  303 +
  304 + dcbnl_skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
  305 + if (!dcbnl_skb)
  306 + goto err_out;
  307 +
  308 + nlh = NLMSG_NEW(dcbnl_skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
  309 +
  310 + dcb = NLMSG_DATA(nlh);
  311 + dcb->dcb_family = AF_UNSPEC;
  312 + dcb->cmd = DCB_CMD_GCAP;
  313 +
  314 + nest = nla_nest_start(dcbnl_skb, DCB_ATTR_CAP);
  315 + if (!nest)
  316 + goto err;
  317 +
  318 + if (data[DCB_CAP_ATTR_ALL])
  319 + getall = 1;
  320 +
  321 + for (i = DCB_CAP_ATTR_ALL+1; i <= DCB_CAP_ATTR_MAX; i++) {
  322 + if (!getall && !data[i])
  323 + continue;
  324 +
  325 + if (!netdev->dcbnl_ops->getcap(netdev, i, &value)) {
  326 + ret = nla_put_u8(dcbnl_skb, i, value);
  327 +
  328 + if (ret) {
  329 + nla_nest_cancel(dcbnl_skb, nest);
  330 + goto err;
  331 + }
  332 + }
  333 + }
  334 + nla_nest_end(dcbnl_skb, nest);
  335 +
  336 + nlmsg_end(dcbnl_skb, nlh);
  337 +
  338 + ret = rtnl_unicast(dcbnl_skb, &init_net, pid);
  339 + if (ret)
  340 + goto err;
  341 +
  342 + return 0;
  343 +nlmsg_failure:
  344 +err:
  345 + kfree(dcbnl_skb);
  346 +err_out:
  347 + return -EINVAL;
  348 +}
  349 +
272 350 static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb,
273 351 u32 pid, u32 seq, u16 flags, int dir)
274 352 {
... ... @@ -674,6 +752,10 @@
674 752 case DCB_CMD_PGRX_SCFG:
675 753 ret = dcbnl_pgrx_setcfg(netdev, tb, pid, nlh->nlmsg_seq,
676 754 nlh->nlmsg_flags);
  755 + goto out;
  756 + case DCB_CMD_GCAP:
  757 + ret = dcbnl_getcap(netdev, tb, pid, nlh->nlmsg_seq,
  758 + nlh->nlmsg_flags);
677 759 goto out;
678 760 default:
679 761 goto errout;