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

Commit dc6ed1df authored by Shmulik Ravid's avatar Shmulik Ravid Committed by David S. Miller
Browse files

dcbnl: add support for retrieving peer configuration - cee



This patch adds the support for retrieving the remote or peer DCBX
configuration via dcbnl for embedded DCBX stacks supporting the CEE DCBX
standard.

Signed-off-by: default avatarShmulik Ravid <shmulikr@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent eed84713
Loading
Loading
Loading
Loading
+71 −0
Original line number Diff line number Diff line
@@ -87,6 +87,45 @@ struct ieee_pfc {
	__u64	indications[IEEE_8021QAZ_MAX_TCS];
};

/* CEE DCBX std supported values */
#define CEE_DCBX_MAX_PGS	8
#define CEE_DCBX_MAX_PRIO	8

/**
 * struct cee_pg - CEE Prioity-Group managed object
 *
 * @willing: willing bit in the PG tlv
 * @error: error bit in the PG tlv
 * @pg_en: enable bit of the PG feature
 * @tcs_supported: number of traffic classes supported
 * @pg_bw: bandwidth percentage for each priority group
 * @prio_pg: priority to PG mapping indexed by priority
 */
struct cee_pg {
	__u8    willing;
	__u8    error;
	__u8    pg_en;
	__u8    tcs_supported;
	__u8    pg_bw[CEE_DCBX_MAX_PGS];
	__u8    prio_pg[CEE_DCBX_MAX_PGS];
};

/**
 * struct cee_pfc - CEE PFC managed object
 *
 * @willing: willing bit in the PFC tlv
 * @error: error bit in the PFC tlv
 * @pfc_en: bitmap indicating pfc enabled traffic classes
 * @tcs_supported: number of traffic classes supported
 */
struct cee_pfc {
	__u8    willing;
	__u8    error;
	__u8    pfc_en;
	__u8    tcs_supported;
};


/* This structure contains the IEEE 802.1Qaz APP managed object. This
 * object is also used for the CEE std as well. There is no difference
 * between the objects.
@@ -158,6 +197,7 @@ struct dcbmsg {
 * @DCB_CMD_SDCBX: set DCBX engine configuration
 * @DCB_CMD_GFEATCFG: get DCBX features flags
 * @DCB_CMD_SFEATCFG: set DCBX features negotiation flags
 * @DCB_CMD_CEE_GET: get CEE aggregated configuration
 */
enum dcbnl_commands {
	DCB_CMD_UNDEFINED,
@@ -200,6 +240,8 @@ enum dcbnl_commands {
	DCB_CMD_GFEATCFG,
	DCB_CMD_SFEATCFG,

	DCB_CMD_CEE_GET,

	__DCB_CMD_ENUM_MAX,
	DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1,
};
@@ -222,6 +264,7 @@ enum dcbnl_commands {
 * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED)
 * @DCB_ATTR_DCBX: DCBX engine configuration in the device (NLA_U8)
 * @DCB_ATTR_FEATCFG: DCBX features flags (NLA_NESTED)
 * @DCB_ATTR_CEE: CEE std supported attributes (NLA_NESTED)
 */
enum dcbnl_attrs {
	DCB_ATTR_UNDEFINED,
@@ -245,6 +288,9 @@ enum dcbnl_attrs {
	DCB_ATTR_DCBX,
	DCB_ATTR_FEATCFG,

	/* CEE nested attributes */
	DCB_ATTR_CEE,

	__DCB_ATTR_ENUM_MAX,
	DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1,
};
@@ -279,6 +325,31 @@ enum ieee_attrs_app {
};
#define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1)

/**
 * enum cee_attrs - CEE DCBX get attributes
 *
 * @DCB_ATTR_CEE_UNSPEC: unspecified
 * @DCB_ATTR_CEE_PEER_PG: peer PG configuration - get only
 * @DCB_ATTR_CEE_PEER_PFC: peer PFC configuration - get only
 * @DCB_ATTR_CEE_PEER_APP: peer APP tlv - get only
 */
enum cee_attrs {
	DCB_ATTR_CEE_UNSPEC,
	DCB_ATTR_CEE_PEER_PG,
	DCB_ATTR_CEE_PEER_PFC,
	DCB_ATTR_CEE_PEER_APP_TABLE,
	__DCB_ATTR_CEE_MAX
};
#define DCB_ATTR_CEE_MAX (__DCB_ATTR_CEE_MAX - 1)

enum peer_app_attr {
	DCB_ATTR_CEE_PEER_APP_UNSPEC,
	DCB_ATTR_CEE_PEER_APP_INFO,
	DCB_ATTR_CEE_PEER_APP,
	__DCB_ATTR_CEE_PEER_APP_MAX
};
#define DCB_ATTR_CEE_PEER_APP_MAX (__DCB_ATTR_CEE_PEER_APP_MAX - 1)

/**
 * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs
 *
+3 −0
Original line number Diff line number Diff line
@@ -84,6 +84,9 @@ struct dcbnl_rtnl_ops {
			       u16 *);
	int (*peer_getapptable)(struct net_device *, struct dcb_app *);

	/* CEE peer */
	int (*cee_peer_getpg) (struct net_device *, struct cee_pg *);
	int (*cee_peer_getpfc) (struct net_device *, struct cee_pfc *);
};

#endif /* __NET_DCBNL_H__ */
+81 −4
Original line number Diff line number Diff line
@@ -1224,7 +1224,9 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
	return err;
}

static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb)
static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb,
				int app_nested_type, int app_info_type,
				int app_entry_type)
{
	struct dcb_peer_app_info info;
	struct dcb_app *table = NULL;
@@ -1256,12 +1258,15 @@ static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb)
		 */
		err = -EMSGSIZE;

		app = nla_nest_start(skb, DCB_ATTR_IEEE_PEER_APP);
		app = nla_nest_start(skb, app_nested_type);
		if (!app)
			goto nla_put_failure;

		if (app_info_type)
			NLA_PUT(skb, app_info_type, sizeof(info), &info);

		for (i = 0; i < app_count; i++)
			NLA_PUT(skb, DCB_ATTR_IEEE_APP, sizeof(struct dcb_app),
			NLA_PUT(skb, app_entry_type, sizeof(struct dcb_app),
				&table[i]);

		nla_nest_end(skb, app);
@@ -1352,7 +1357,10 @@ static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
	}

	if (ops->peer_getappinfo && ops->peer_getapptable) {
		err = dcbnl_build_peer_app(netdev, skb);
		err = dcbnl_build_peer_app(netdev, skb,
					   DCB_ATTR_IEEE_PEER_APP,
					   DCB_ATTR_IEEE_APP_UNSPEC,
					   DCB_ATTR_IEEE_APP);
		if (err)
			goto nla_put_failure;
	}
@@ -1510,6 +1518,71 @@ static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb,
	return ret;
}

/* Handle CEE DCBX GET commands. */
static int dcbnl_cee_get(struct net_device *netdev, struct nlattr **tb,
			 u32 pid, u32 seq, u16 flags)
{
	struct sk_buff *skb;
	struct nlmsghdr *nlh;
	struct dcbmsg *dcb;
	struct nlattr *cee;
	const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
	int err;

	if (!ops)
		return -EOPNOTSUPP;

	skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
	if (!skb)
		return -ENOBUFS;

	nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);

	dcb = NLMSG_DATA(nlh);
	dcb->dcb_family = AF_UNSPEC;
	dcb->cmd = DCB_CMD_CEE_GET;

	NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name);

	cee = nla_nest_start(skb, DCB_ATTR_CEE);
	if (!cee)
		goto nla_put_failure;

	/* get peer info if available */
	if (ops->cee_peer_getpg) {
		struct cee_pg pg;
		err = ops->cee_peer_getpg(netdev, &pg);
		if (!err)
			NLA_PUT(skb, DCB_ATTR_CEE_PEER_PG, sizeof(pg), &pg);
	}

	if (ops->cee_peer_getpfc) {
		struct cee_pfc pfc;
		err = ops->cee_peer_getpfc(netdev, &pfc);
		if (!err)
			NLA_PUT(skb, DCB_ATTR_CEE_PEER_PFC, sizeof(pfc), &pfc);
	}

	if (ops->peer_getappinfo && ops->peer_getapptable) {
		err = dcbnl_build_peer_app(netdev, skb,
					   DCB_ATTR_CEE_PEER_APP_TABLE,
					   DCB_ATTR_CEE_PEER_APP_INFO,
					   DCB_ATTR_CEE_PEER_APP);
		if (err)
			goto nla_put_failure;
	}

	nla_nest_end(skb, cee);
	nlmsg_end(skb, nlh);

	return rtnl_unicast(skb, &init_net, pid);
nla_put_failure:
	nlmsg_cancel(skb, nlh);
nlmsg_failure:
	kfree_skb(skb);
	return -1;
}

static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
	struct net *net = sock_net(skb->sk);
@@ -1639,6 +1712,10 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
		ret = dcbnl_setfeatcfg(netdev, tb, pid, nlh->nlmsg_seq,
				       nlh->nlmsg_flags);
		goto out;
	case DCB_CMD_CEE_GET:
		ret = dcbnl_cee_get(netdev, tb, pid, nlh->nlmsg_seq,
				    nlh->nlmsg_flags);
		goto out;
	default:
		goto errout;
	}