Commit c9368247 authored by Shani Michaeli's avatar Shani Michaeli Committed by David S. Miller

net/dcb: Add IEEE QCN attribute

As specified in 802.1Qau spec. Add this optional attribute to the
DCB netlink layer. To allow for application to use the new attribute,
NIC drivers should implement and register the  callbacks ieee_getqcn,
ieee_setqcn and ieee_getqcnstats.

The QCN attribute holds a set of parameters for management, and
a set of statistics to provide informative data on Congestion-Control
defined by this spec.
Signed-off-by: default avatarShani Michaeli <shanim@mellanox.com>
Signed-off-by: default avatarShachar Raindel <raindel@mellanox.com>
Signed-off-by: default avatarOr Gerlitz <ogerlitz@mellanox.com>
Acked-by: default avatarJohn Fastabend <john.r.fastabend@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 34de26d3
...@@ -49,6 +49,9 @@ struct dcbnl_rtnl_ops { ...@@ -49,6 +49,9 @@ struct dcbnl_rtnl_ops {
int (*ieee_setets) (struct net_device *, struct ieee_ets *); int (*ieee_setets) (struct net_device *, struct ieee_ets *);
int (*ieee_getmaxrate) (struct net_device *, struct ieee_maxrate *); int (*ieee_getmaxrate) (struct net_device *, struct ieee_maxrate *);
int (*ieee_setmaxrate) (struct net_device *, struct ieee_maxrate *); int (*ieee_setmaxrate) (struct net_device *, struct ieee_maxrate *);
int (*ieee_getqcn) (struct net_device *, struct ieee_qcn *);
int (*ieee_setqcn) (struct net_device *, struct ieee_qcn *);
int (*ieee_getqcnstats) (struct net_device *, struct ieee_qcn_stats *);
int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *); int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *);
int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *); int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *);
int (*ieee_getapp) (struct net_device *, struct dcb_app *); int (*ieee_getapp) (struct net_device *, struct dcb_app *);
......
...@@ -78,6 +78,70 @@ struct ieee_maxrate { ...@@ -78,6 +78,70 @@ struct ieee_maxrate {
__u64 tc_maxrate[IEEE_8021QAZ_MAX_TCS]; __u64 tc_maxrate[IEEE_8021QAZ_MAX_TCS];
}; };
enum dcbnl_cndd_states {
DCB_CNDD_RESET = 0,
DCB_CNDD_EDGE,
DCB_CNDD_INTERIOR,
DCB_CNDD_INTERIOR_READY,
};
/* This structure contains the IEEE 802.1Qau QCN managed object.
*
*@rpg_enable: enable QCN RP
*@rppp_max_rps: maximum number of RPs allowed for this CNPV on this port
*@rpg_time_reset: time between rate increases if no CNMs received.
* given in u-seconds
*@rpg_byte_reset: transmitted data between rate increases if no CNMs received.
* given in Bytes
*@rpg_threshold: The number of times rpByteStage or rpTimeStage can count
* before RP rate control state machine advances states
*@rpg_max_rate: the maxinun rate, in Mbits per second,
* at which an RP can transmit
*@rpg_ai_rate: The rate, in Mbits per second,
* used to increase rpTargetRate in the RPR_ACTIVE_INCREASE
*@rpg_hai_rate: The rate, in Mbits per second,
* used to increase rpTargetRate in the RPR_HYPER_INCREASE state
*@rpg_gd: Upon CNM receive, flow rate is limited to (Fb/Gd)*CurrentRate.
* rpgGd is given as log2(Gd), where Gd may only be powers of 2
*@rpg_min_dec_fac: The minimum factor by which the current transmit rate
* can be changed by reception of a CNM.
* value is given as percentage (1-100)
*@rpg_min_rate: The minimum value, in bits per second, for rate to limit
*@cndd_state_machine: The state of the congestion notification domain
* defense state machine, as defined by IEEE 802.3Qau
* section 32.1.1. In the interior ready state,
* the QCN capable hardware may add CN-TAG TLV to the
* outgoing traffic, to specifically identify outgoing
* flows.
*/
struct ieee_qcn {
__u8 rpg_enable[IEEE_8021QAZ_MAX_TCS];
__u32 rppp_max_rps[IEEE_8021QAZ_MAX_TCS];
__u32 rpg_time_reset[IEEE_8021QAZ_MAX_TCS];
__u32 rpg_byte_reset[IEEE_8021QAZ_MAX_TCS];
__u32 rpg_threshold[IEEE_8021QAZ_MAX_TCS];
__u32 rpg_max_rate[IEEE_8021QAZ_MAX_TCS];
__u32 rpg_ai_rate[IEEE_8021QAZ_MAX_TCS];
__u32 rpg_hai_rate[IEEE_8021QAZ_MAX_TCS];
__u32 rpg_gd[IEEE_8021QAZ_MAX_TCS];
__u32 rpg_min_dec_fac[IEEE_8021QAZ_MAX_TCS];
__u32 rpg_min_rate[IEEE_8021QAZ_MAX_TCS];
__u32 cndd_state_machine[IEEE_8021QAZ_MAX_TCS];
};
/* This structure contains the IEEE 802.1Qau QCN statistics.
*
*@rppp_rp_centiseconds: the number of RP-centiseconds accumulated
* by RPs at this priority level on this Port
*@rppp_created_rps: number of active RPs(flows) that react to CNMs
*/
struct ieee_qcn_stats {
__u64 rppp_rp_centiseconds[IEEE_8021QAZ_MAX_TCS];
__u32 rppp_created_rps[IEEE_8021QAZ_MAX_TCS];
};
/* This structure contains the IEEE 802.1Qaz PFC managed object /* This structure contains the IEEE 802.1Qaz PFC managed object
* *
* @pfc_cap: Indicates the number of traffic classes on the local device * @pfc_cap: Indicates the number of traffic classes on the local device
...@@ -334,6 +398,8 @@ enum ieee_attrs { ...@@ -334,6 +398,8 @@ enum ieee_attrs {
DCB_ATTR_IEEE_PEER_PFC, DCB_ATTR_IEEE_PEER_PFC,
DCB_ATTR_IEEE_PEER_APP, DCB_ATTR_IEEE_PEER_APP,
DCB_ATTR_IEEE_MAXRATE, DCB_ATTR_IEEE_MAXRATE,
DCB_ATTR_IEEE_QCN,
DCB_ATTR_IEEE_QCN_STATS,
__DCB_ATTR_IEEE_MAX __DCB_ATTR_IEEE_MAX
}; };
#define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1) #define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1)
......
...@@ -177,6 +177,8 @@ static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = { ...@@ -177,6 +177,8 @@ static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = {
[DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)}, [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)},
[DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED}, [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED},
[DCB_ATTR_IEEE_MAXRATE] = {.len = sizeof(struct ieee_maxrate)}, [DCB_ATTR_IEEE_MAXRATE] = {.len = sizeof(struct ieee_maxrate)},
[DCB_ATTR_IEEE_QCN] = {.len = sizeof(struct ieee_qcn)},
[DCB_ATTR_IEEE_QCN_STATS] = {.len = sizeof(struct ieee_qcn_stats)},
}; };
static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = { static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = {
...@@ -1030,7 +1032,7 @@ static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb, ...@@ -1030,7 +1032,7 @@ static int dcbnl_build_peer_app(struct net_device *netdev, struct sk_buff* skb,
return err; return err;
} }
/* Handle IEEE 802.1Qaz GET commands. */ /* Handle IEEE 802.1Qaz/802.1Qau/802.1Qbb GET commands. */
static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
{ {
struct nlattr *ieee, *app; struct nlattr *ieee, *app;
...@@ -1067,6 +1069,32 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev) ...@@ -1067,6 +1069,32 @@ static int dcbnl_ieee_fill(struct sk_buff *skb, struct net_device *netdev)
} }
} }
if (ops->ieee_getqcn) {
struct ieee_qcn qcn;
memset(&qcn, 0, sizeof(qcn));
err = ops->ieee_getqcn(netdev, &qcn);
if (!err) {
err = nla_put(skb, DCB_ATTR_IEEE_QCN,
sizeof(qcn), &qcn);
if (err)
return -EMSGSIZE;
}
}
if (ops->ieee_getqcnstats) {
struct ieee_qcn_stats qcn_stats;
memset(&qcn_stats, 0, sizeof(qcn_stats));
err = ops->ieee_getqcnstats(netdev, &qcn_stats);
if (!err) {
err = nla_put(skb, DCB_ATTR_IEEE_QCN_STATS,
sizeof(qcn_stats), &qcn_stats);
if (err)
return -EMSGSIZE;
}
}
if (ops->ieee_getpfc) { if (ops->ieee_getpfc) {
struct ieee_pfc pfc; struct ieee_pfc pfc;
memset(&pfc, 0, sizeof(pfc)); memset(&pfc, 0, sizeof(pfc));
...@@ -1379,8 +1407,9 @@ int dcbnl_cee_notify(struct net_device *dev, int event, int cmd, ...@@ -1379,8 +1407,9 @@ int dcbnl_cee_notify(struct net_device *dev, int event, int cmd,
} }
EXPORT_SYMBOL(dcbnl_cee_notify); EXPORT_SYMBOL(dcbnl_cee_notify);
/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not /* Handle IEEE 802.1Qaz/802.1Qau/802.1Qbb SET commands.
* be completed the entire msg is aborted and error value is returned. * If any requested operation can not be completed
* the entire msg is aborted and error value is returned.
* No attempt is made to reconcile the case where only part of the * No attempt is made to reconcile the case where only part of the
* cmd can be completed. * cmd can be completed.
*/ */
...@@ -1417,6 +1446,15 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh, ...@@ -1417,6 +1446,15 @@ static int dcbnl_ieee_set(struct net_device *netdev, struct nlmsghdr *nlh,
goto err; goto err;
} }
if (ieee[DCB_ATTR_IEEE_QCN] && ops->ieee_setqcn) {
struct ieee_qcn *qcn =
nla_data(ieee[DCB_ATTR_IEEE_QCN]);
err = ops->ieee_setqcn(netdev, qcn);
if (err)
goto err;
}
if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) { if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setpfc) {
struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]); struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]);
err = ops->ieee_setpfc(netdev, pfc); err = ops->ieee_setpfc(netdev, pfc);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment