Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0eb3aa9b authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller
Browse files

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: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarPeter P Waskiewicz Jr <peter.p.waskiewicz.jr@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 33dbabc4
Loading
Loading
Loading
Loading
+15 −1
Original line number Diff line number Diff line
@@ -405,6 +405,18 @@ static u8 ixgbe_dcbnl_setnumtcs(struct net_device *netdev, int tcid, u8 num)
	return -EINVAL;
}

static u8 ixgbe_dcbnl_getpfcstate(struct net_device *netdev)
{
	struct ixgbe_adapter *adapter = netdev_priv(netdev);

	return !!(adapter->flags & IXGBE_FLAG_DCB_ENABLED);
}

static void ixgbe_dcbnl_setpfcstate(struct net_device *netdev, u8 state)
{
	return;
}

struct dcbnl_rtnl_ops dcbnl_ops = {
	.getstate	= ixgbe_dcbnl_get_state,
	.setstate	= ixgbe_dcbnl_set_state,
@@ -422,6 +434,8 @@ struct dcbnl_rtnl_ops dcbnl_ops = {
	.setall		= ixgbe_dcbnl_set_all,
	.getcap		= ixgbe_dcbnl_getcap,
	.getnumtcs	= ixgbe_dcbnl_getnumtcs,
	.setnumtcs	= ixgbe_dcbnl_setnumtcs
	.setnumtcs	= ixgbe_dcbnl_setnumtcs,
	.getpfcstate	= ixgbe_dcbnl_getpfcstate,
	.setpfcstate	= ixgbe_dcbnl_setpfcstate
};
+2 −0
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ enum dcbnl_commands {
	DCB_CMD_GCAP,
	DCB_CMD_GNUMTCS,
	DCB_CMD_SNUMTCS,
	DCB_CMD_PFC_GSTATE,
	DCB_CMD_PFC_SSTATE,

	__DCB_CMD_ENUM_MAX,
	DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1,
+2 −0
Original line number Diff line number Diff line
@@ -42,6 +42,8 @@ struct dcbnl_rtnl_ops {
	u8   (*getcap)(struct net_device *, int, u8 *);
	u8   (*getnumtcs)(struct net_device *, int, u8 *);
	u8   (*setnumtcs)(struct net_device *, int, u8);
	u8   (*getpfcstate)(struct net_device *);
	void (*setpfcstate)(struct net_device *, u8);
};

#endif /* __NET_DCBNL_H__ */
+43 −0
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ static struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = {
	[DCB_ATTR_SET_ALL]   = {.type = NLA_U8},
	[DCB_ATTR_PERM_HWADDR] = {.type = NLA_FLAG},
	[DCB_ATTR_CAP]       = {.type = NLA_NESTED},
	[DCB_ATTR_PFC_STATE] = {.type = NLA_U8},
};

/* DCB priority flow control to User Priority nested attributes */
@@ -471,6 +472,40 @@ static int dcbnl_setnumtcs(struct net_device *netdev, struct nlattr **tb,
	return ret;
}

static int dcbnl_getpfcstate(struct net_device *netdev, struct nlattr **tb,
                             u32 pid, u32 seq, u16 flags)
{
	int ret = -EINVAL;

	if (!netdev->dcbnl_ops->getpfcstate)
		return ret;

	ret = dcbnl_reply(netdev->dcbnl_ops->getpfcstate(netdev), RTM_GETDCB,
	                  DCB_CMD_PFC_GSTATE, DCB_ATTR_PFC_STATE,
	                  pid, seq, flags);

	return ret;
}

static int dcbnl_setpfcstate(struct net_device *netdev, struct nlattr **tb,
                             u32 pid, u32 seq, u16 flags)
{
	int ret = -EINVAL;
	u8 value;

	if (!tb[DCB_ATTR_PFC_STATE] || !netdev->dcbnl_ops->setpfcstate)
		return ret;

	value = nla_get_u8(tb[DCB_ATTR_PFC_STATE]);

	netdev->dcbnl_ops->setpfcstate(netdev, value);

	ret = dcbnl_reply(0, RTM_SETDCB, DCB_CMD_PFC_SSTATE, DCB_ATTR_PFC_STATE,
	                  pid, seq, flags);

	return ret;
}

static int __dcbnl_pg_getcfg(struct net_device *netdev, struct nlattr **tb,
                             u32 pid, u32 seq, u16 flags, int dir)
{
@@ -889,6 +924,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
		ret = dcbnl_setnumtcs(netdev, tb, pid, nlh->nlmsg_seq,
		                      nlh->nlmsg_flags);
		goto out;
	case DCB_CMD_PFC_GSTATE:
		ret = dcbnl_getpfcstate(netdev, tb, pid, nlh->nlmsg_seq,
		                        nlh->nlmsg_flags);
		goto out;
	case DCB_CMD_PFC_SSTATE:
		ret = dcbnl_setpfcstate(netdev, tb, pid, nlh->nlmsg_seq,
		                        nlh->nlmsg_flags);
		goto out;
	default:
		goto errout;
	}