diff options
author | Alexander Duyck <alexander.h.duyck@intel.com> | 2008-11-21 00:09:23 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-11-21 00:09:23 -0500 |
commit | 0eb3aa9bab20217fb42244ccdcb5bf8a002f504c (patch) | |
tree | b7d5a846b674a4f26ce4c1aa3b90f72fe9ce83d0 | |
parent | 33dbabc4a7f7bd72313c73a3c199f31f3900336f (diff) |
DCB: Add interface to query the state of PFC feature.
Adds a netlink interface for Data Center Bridging (DCB) to get and set
the enable state of the Priority Flow Control (PFC) feature.
Primarily, this is a way to turn off PFC in the driver while DCB
remains enabled.
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>
-rw-r--r-- | drivers/net/ixgbe/ixgbe_dcb_nl.c | 16 | ||||
-rw-r--r-- | include/linux/dcbnl.h | 2 | ||||
-rw-r--r-- | include/net/dcbnl.h | 2 | ||||
-rw-r--r-- | net/dcb/dcbnl.c | 43 |
4 files changed, 62 insertions, 1 deletions
diff --git a/drivers/net/ixgbe/ixgbe_dcb_nl.c b/drivers/net/ixgbe/ixgbe_dcb_nl.c index 5921795f8403..dd940a8f9357 100644 --- a/drivers/net/ixgbe/ixgbe_dcb_nl.c +++ b/drivers/net/ixgbe/ixgbe_dcb_nl.c | |||
@@ -405,6 +405,18 @@ static u8 ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num) | |||
405 | return -EINVAL; | 405 | return -EINVAL; |
406 | } | 406 | } |
407 | 407 | ||
408 | static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev) | ||
409 | { | ||
410 | struct ixgbe_adapter *adapter = netdev_priv(netdev); | ||
411 | |||
412 | return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED); | ||
413 | } | ||
414 | |||
415 | static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state) | ||
416 | { | ||
417 | return; | ||
418 | } | ||
419 | |||
408 | struct dcbnl_rtnl_ops dcbnl_ops = { | 420 | struct dcbnl_rtnl_ops dcbnl_ops = { |
409 | .getstate = ixgbe_dcbnl_get_state, | 421 | .getstate = ixgbe_dcbnl_get_state, |
410 | .setstate = ixgbe_dcbnl_set_state, | 422 | .setstate = ixgbe_dcbnl_set_state, |
@@ -422,6 +434,8 @@ struct dcbnl_rtnl_ops dcbnl_ops = { | |||
422 | .setall = ixgbe_dcbnl_set_all, | 434 | .setall = ixgbe_dcbnl_set_all, |
423 | .getcap = ixgbe_dcbnl_getcap, | 435 | .getcap = ixgbe_dcbnl_getcap, |
424 | .getnumtcs = ixgbe_dcbnl_getnumtcs, | 436 | .getnumtcs = ixgbe_dcbnl_getnumtcs, |
425 | .setnumtcs = ixgbe_dcbnl_setnumtcs | 437 | .setnumtcs = ixgbe_dcbnl_setnumtcs, |
438 | .getpfcstate = ixgbe_dcbnl_getpfcstate, | ||
439 | .setpfcstate = ixgbe_dcbnl_setpfcstate | ||
426 | }; | 440 | }; |
427 | 441 | ||
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h index 1077fba1dadc..6cc4560bc376 100644 --- a/include/linux/dcbnl.h +++ b/include/linux/dcbnl.h | |||
@@ -66,6 +66,8 @@ enum dcbnl_commands { | |||
66 | DCB_CMD_GCAP, | 66 | DCB_CMD_GCAP, |
67 | DCB_CMD_GNUMTCS, | 67 | DCB_CMD_GNUMTCS, |
68 | DCB_CMD_SNUMTCS, | 68 | DCB_CMD_SNUMTCS, |
69 | DCB_CMD_PFC_GSTATE, | ||
70 | DCB_CMD_PFC_SSTATE, | ||
69 | 71 | ||
70 | __DCB_CMD_ENUM_MAX, | 72 | __DCB_CMD_ENUM_MAX, |
71 | DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, | 73 | DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, |
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h index f0a65281ea73..c7d87caf3f99 100644 --- a/include/net/dcbnl.h +++ b/include/net/dcbnl.h | |||
@@ -42,6 +42,8 @@ struct dcbnl_rtnl_ops { | |||
42 | u8 (*getcap)(struct net_device *, int, u8 *); | 42 | u8 (*getcap)(struct net_device *, int, u8 *); |
43 | u8 (*getnumtcs)(struct net_device *, int, u8 *); | 43 | u8 (*getnumtcs)(struct net_device *, int, u8 *); |
44 | u8 (*setnumtcs)(struct net_device *, int, u8); | 44 | u8 (*setnumtcs)(struct net_device *, int, u8); |
45 | u8 (*getpfcstate)(struct net_device *); | ||
46 | void (*setpfcstate)(struct net_device *, u8); | ||
45 | }; | 47 | }; |
46 | 48 | ||
47 | #endif /* __NET_DCBNL_H__ */ | 49 | #endif /* __NET_DCBNL_H__ */ |
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 5ff7e3c0c172..758419c6f59b 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -62,6 +62,7 @@ static struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = { | |||
62 | [DCB_ATTR_SET_ALL] = {.type = NLA_U8}, | 62 | [DCB_ATTR_SET_ALL] = {.type = NLA_U8}, |
63 | [DCB_ATTR_PERM_HWADDR] = {.type = NLA_FLAG}, | 63 | [DCB_ATTR_PERM_HWADDR] = {.type = NLA_FLAG}, |
64 | [DCB_ATTR_CAP] = {.type = NLA_NESTED}, | 64 | [DCB_ATTR_CAP] = {.type = NLA_NESTED}, |
65 | [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | /* DCB priority flow control to User Priority nested attributes */ | 68 | /* DCB priority flow control to User Priority nested attributes */ |
@@ -471,6 +472,40 @@ err: | |||
471 | return ret; | 472 | return ret; |
472 | } | 473 | } |
473 | 474 | ||
475 | static int dcbnl_getpfcstate(struct net_device *netdev, struct nlattr **tb, | ||
476 | u32 pid, u32 seq, u16 flags) | ||
477 | { | ||
478 | int ret = -EINVAL; | ||
479 | |||
480 | if (!netdev->dcbnl_ops->getpfcstate) | ||
481 | return ret; | ||
482 | |||
483 | ret = dcbnl_reply(netdev->dcbnl_ops->getpfcstate(netdev), RTM_GETDCB, | ||
484 | DCB_CMD_PFC_GSTATE, DCB_ATTR_PFC_STATE, | ||
485 | pid, seq, flags); | ||
486 | |||
487 | return ret; | ||
488 | } | ||
489 | |||
490 | static int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb, | ||
491 | u32 pid, u32 seq, u16 flags) | ||
492 | { | ||
493 | int ret = -EINVAL; | ||
494 | u8 value; | ||
495 | |||
496 | if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate) | ||
497 | return ret; | ||
498 | |||
499 | value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]); | ||
500 | |||
501 | netdev->dcbnl_ops->setpfcstate(netdev, value); | ||
502 | |||
503 | ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SSTATE, DCB_ATTR_PFC_STATE, | ||
504 | pid, seq, flags); | ||
505 | |||
506 | return ret; | ||
507 | } | ||
508 | |||
474 | static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, | 509 | static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb, |
475 | u32 pid, u32 seq, u16 flags, int dir) | 510 | u32 pid, u32 seq, u16 flags, int dir) |
476 | { | 511 | { |
@@ -889,6 +924,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
889 | ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq, | 924 | ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq, |
890 | nlh->nlmsg_flags); | 925 | nlh->nlmsg_flags); |
891 | goto out; | 926 | goto out; |
927 | case DCB_CMD_PFC_GSTATE: | ||
928 | ret = dcbnl_getpfcstate(netdev, tb, pid, nlh->nlmsg_seq, | ||
929 | nlh->nlmsg_flags); | ||
930 | goto out; | ||
931 | case DCB_CMD_PFC_SSTATE: | ||
932 | ret = dcbnl_setpfcstate(netdev, tb, pid, nlh->nlmsg_seq, | ||
933 | nlh->nlmsg_flags); | ||
934 | goto out; | ||
892 | default: | 935 | default: |
893 | goto errout; | 936 | goto errout; |
894 | } | 937 | } |