aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Fastabend <john.r.fastabend@intel.com>2010-12-30 04:25:46 -0500
committerDavid S. Miller <davem@davemloft.net>2010-12-31 13:47:45 -0500
commit3e29027af43728c2a91fe3f735ab2822edaf54a8 (patch)
treefb453671722596b9dcb1af4171bdcfa17cd48d61
parenta7dd6027e55992dd7c409a71a4a2b576fda2f7c2 (diff)
dcbnl: add support for ieee8021Qaz attributes
The IEEE8021Qaz is the IEEE standard version of CEE. The standard has had enough significant changes from the CEE version that many of the CEE attributes have no meaning in the new spec or do not easily map to IEEE standards. Rather then attempt to create a complicated mapping between CEE and IEEE standards this patch adds a nested IEEE attribute to the list of DCB attributes. The policy is, [DCB_ATTR_IFNAME] [DCB_ATTR_STATE] ... [DCB_ATTR_IEEE] [DCB_ATTR_IEEE_ETS] [DCB_ATTR_IEEE_PFC] [DCB_ATTR_IEEE_APP_TABLE] [DCB_ATTR_IEEE_APP] ... The following dcbnl_rtnl_ops routines were added to handle the IEEE standard, int (*ieee_getets) (struct net_device *, struct ieee_ets *); int (*ieee_setets) (struct net_device *, struct ieee_ets *); int (*ieee_getpfc) (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_setapp) (struct net_device *, struct dcb_app *); Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--include/linux/dcbnl.h106
-rw-r--r--include/net/dcbnl.h11
-rw-r--r--net/dcb/dcbnl.c131
3 files changed, 248 insertions, 0 deletions
diff --git a/include/linux/dcbnl.h b/include/linux/dcbnl.h
index 8723491f7dfd..287b5618e296 100644
--- a/include/linux/dcbnl.h
+++ b/include/linux/dcbnl.h
@@ -22,6 +22,87 @@
22 22
23#include <linux/types.h> 23#include <linux/types.h>
24 24
25/* IEEE 802.1Qaz std supported values */
26#define IEEE_8021QAZ_MAX_TCS 8
27
28/* This structure contains the IEEE 802.1Qaz ETS managed object
29 *
30 * @willing: willing bit in ETS configuratin TLV
31 * @ets_cap: indicates supported capacity of ets feature
32 * @cbs: credit based shaper ets algorithm supported
33 * @tc_tx_bw: tc tx bandwidth indexed by traffic class
34 * @tc_rx_bw: tc rx bandwidth indexed by traffic class
35 * @tc_tsa: TSA Assignment table, indexed by traffic class
36 * @prio_tc: priority assignment table mapping 8021Qp to traffic class
37 * @tc_reco_bw: recommended tc bandwidth indexed by traffic class for TLV
38 * @tc_reco_tsa: recommended tc bandwidth indexed by traffic class for TLV
39 * @reco_prio_tc: recommended tc tx bandwidth indexed by traffic class for TLV
40 *
41 * Recommended values are used to set fields in the ETS recommendation TLV
42 * with hardware offloaded LLDP.
43 *
44 * ----
45 * TSA Assignment 8 bit identifiers
46 * 0 strict priority
47 * 1 credit-based shaper
48 * 2 enhanced transmission selection
49 * 3-254 reserved
50 * 255 vendor specific
51 */
52struct ieee_ets {
53 __u8 willing;
54 __u8 ets_cap;
55 __u8 cbs;
56 __u8 tc_tx_bw[IEEE_8021QAZ_MAX_TCS];
57 __u8 tc_rx_bw[IEEE_8021QAZ_MAX_TCS];
58 __u8 tc_tsa[IEEE_8021QAZ_MAX_TCS];
59 __u8 prio_tc[IEEE_8021QAZ_MAX_TCS];
60 __u8 tc_reco_bw[IEEE_8021QAZ_MAX_TCS];
61 __u8 tc_reco_tsa[IEEE_8021QAZ_MAX_TCS];
62 __u8 reco_prio_tc[IEEE_8021QAZ_MAX_TCS];
63};
64
65/* This structure contains the IEEE 802.1Qaz PFC managed object
66 *
67 * @pfc_cap: Indicates the number of traffic classes on the local device
68 * that may simultaneously have PFC enabled.
69 * @pfc_en: bitmap indicating pfc enabled traffic classes
70 * @mbc: enable macsec bypass capability
71 * @delay: the allowance made for a round-trip propagation delay of the
72 * link in bits.
73 * @requests: count of the sent pfc frames
74 * @indications: count of the received pfc frames
75 */
76struct ieee_pfc {
77 __u8 pfc_cap;
78 __u8 pfc_en;
79 __u8 mbc;
80 __u16 delay;
81 __u64 requests[IEEE_8021QAZ_MAX_TCS];
82 __u64 indications[IEEE_8021QAZ_MAX_TCS];
83};
84
85/* This structure contains the IEEE 802.1Qaz APP managed object
86 *
87 * @selector: protocol identifier type
88 * @protocol: protocol of type indicated
89 * @priority: 3-bit unsigned integer indicating priority
90 *
91 * ----
92 * Selector field values
93 * 0 Reserved
94 * 1 Ethertype
95 * 2 Well known port number over TCP or SCTP
96 * 3 Well known port number over UDP or DCCP
97 * 4 Well known port number over TCP, SCTP, UDP, or DCCP
98 * 5-7 Reserved
99 */
100struct dcb_app {
101 __u8 selector;
102 __u32 protocol;
103 __u8 priority;
104};
105
25struct dcbmsg { 106struct dcbmsg {
26 __u8 dcb_family; 107 __u8 dcb_family;
27 __u8 cmd; 108 __u8 cmd;
@@ -50,6 +131,8 @@ struct dcbmsg {
50 * @DCB_CMD_SBCN: get backward congestion notification configration. 131 * @DCB_CMD_SBCN: get backward congestion notification configration.
51 * @DCB_CMD_GAPP: get application protocol configuration 132 * @DCB_CMD_GAPP: get application protocol configuration
52 * @DCB_CMD_SAPP: set application protocol configuration 133 * @DCB_CMD_SAPP: set application protocol configuration
134 * @DCB_CMD_IEEE_SET: set IEEE 802.1Qaz configuration
135 * @DCB_CMD_IEEE_GET: get IEEE 802.1Qaz configuration
53 */ 136 */
54enum dcbnl_commands { 137enum dcbnl_commands {
55 DCB_CMD_UNDEFINED, 138 DCB_CMD_UNDEFINED,
@@ -83,6 +166,9 @@ enum dcbnl_commands {
83 DCB_CMD_GAPP, 166 DCB_CMD_GAPP,
84 DCB_CMD_SAPP, 167 DCB_CMD_SAPP,
85 168
169 DCB_CMD_IEEE_SET,
170 DCB_CMD_IEEE_GET,
171
86 __DCB_CMD_ENUM_MAX, 172 __DCB_CMD_ENUM_MAX,
87 DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1, 173 DCB_CMD_MAX = __DCB_CMD_ENUM_MAX - 1,
88}; 174};
@@ -102,6 +188,7 @@ enum dcbnl_commands {
102 * @DCB_ATTR_CAP: DCB capabilities of the device (NLA_NESTED) 188 * @DCB_ATTR_CAP: DCB capabilities of the device (NLA_NESTED)
103 * @DCB_ATTR_NUMTCS: number of traffic classes supported (NLA_NESTED) 189 * @DCB_ATTR_NUMTCS: number of traffic classes supported (NLA_NESTED)
104 * @DCB_ATTR_BCN: backward congestion notification configuration (NLA_NESTED) 190 * @DCB_ATTR_BCN: backward congestion notification configuration (NLA_NESTED)
191 * @DCB_ATTR_IEEE: IEEE 802.1Qaz supported attributes (NLA_NESTED)
105 */ 192 */
106enum dcbnl_attrs { 193enum dcbnl_attrs {
107 DCB_ATTR_UNDEFINED, 194 DCB_ATTR_UNDEFINED,
@@ -119,10 +206,29 @@ enum dcbnl_attrs {
119 DCB_ATTR_BCN, 206 DCB_ATTR_BCN,
120 DCB_ATTR_APP, 207 DCB_ATTR_APP,
121 208
209 /* IEEE std attributes */
210 DCB_ATTR_IEEE,
211
122 __DCB_ATTR_ENUM_MAX, 212 __DCB_ATTR_ENUM_MAX,
123 DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1, 213 DCB_ATTR_MAX = __DCB_ATTR_ENUM_MAX - 1,
124}; 214};
125 215
216enum ieee_attrs {
217 DCB_ATTR_IEEE_UNSPEC,
218 DCB_ATTR_IEEE_ETS,
219 DCB_ATTR_IEEE_PFC,
220 DCB_ATTR_IEEE_APP_TABLE,
221 __DCB_ATTR_IEEE_MAX
222};
223#define DCB_ATTR_IEEE_MAX (__DCB_ATTR_IEEE_MAX - 1)
224
225enum ieee_attrs_app {
226 DCB_ATTR_IEEE_APP_UNSPEC,
227 DCB_ATTR_IEEE_APP,
228 __DCB_ATTR_IEEE_APP_MAX
229};
230#define DCB_ATTR_IEEE_APP_MAX (__DCB_ATTR_IEEE_APP_MAX - 1)
231
126/** 232/**
127 * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs 233 * enum dcbnl_pfc_attrs - DCB Priority Flow Control user priority nested attrs
128 * 234 *
diff --git a/include/net/dcbnl.h b/include/net/dcbnl.h
index b36ac7e0914d..e2d841e963b3 100644
--- a/include/net/dcbnl.h
+++ b/include/net/dcbnl.h
@@ -20,11 +20,22 @@
20#ifndef __NET_DCBNL_H__ 20#ifndef __NET_DCBNL_H__
21#define __NET_DCBNL_H__ 21#define __NET_DCBNL_H__
22 22
23#include <linux/dcbnl.h>
24
23/* 25/*
24 * Ops struct for the netlink callbacks. Used by DCB-enabled drivers through 26 * Ops struct for the netlink callbacks. Used by DCB-enabled drivers through
25 * the netdevice struct. 27 * the netdevice struct.
26 */ 28 */
27struct dcbnl_rtnl_ops { 29struct dcbnl_rtnl_ops {
30 /* IEEE 802.1Qaz std */
31 int (*ieee_getets) (struct net_device *, struct ieee_ets *);
32 int (*ieee_setets) (struct net_device *, struct ieee_ets *);
33 int (*ieee_getpfc) (struct net_device *, struct ieee_pfc *);
34 int (*ieee_setpfc) (struct net_device *, struct ieee_pfc *);
35 int (*ieee_getapp) (struct net_device *, struct dcb_app *);
36 int (*ieee_setapp) (struct net_device *, struct dcb_app *);
37
38 /* CEE std */
28 u8 (*getstate)(struct net_device *); 39 u8 (*getstate)(struct net_device *);
29 u8 (*setstate)(struct net_device *, u8); 40 u8 (*setstate)(struct net_device *, u8);
30 void (*getpermhwaddr)(struct net_device *, u8 *); 41 void (*getpermhwaddr)(struct net_device *, u8 *);
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c
index 19ac2b985485..2ff908498924 100644
--- a/net/dcb/dcbnl.c
+++ b/net/dcb/dcbnl.c
@@ -66,6 +66,7 @@ static const struct nla_policy dcbnl_rtnl_policy[DCB_ATTR_MAX + 1] = {
66 [DCB_ATTR_PFC_STATE] = {.type = NLA_U8}, 66 [DCB_ATTR_PFC_STATE] = {.type = NLA_U8},
67 [DCB_ATTR_BCN] = {.type = NLA_NESTED}, 67 [DCB_ATTR_BCN] = {.type = NLA_NESTED},
68 [DCB_ATTR_APP] = {.type = NLA_NESTED}, 68 [DCB_ATTR_APP] = {.type = NLA_NESTED},
69 [DCB_ATTR_IEEE] = {.type = NLA_NESTED},
69}; 70};
70 71
71/* DCB priority flow control to User Priority nested attributes */ 72/* DCB priority flow control to User Priority nested attributes */
@@ -167,6 +168,17 @@ static const struct nla_policy dcbnl_app_nest[DCB_APP_ATTR_MAX + 1] = {
167 [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8}, 168 [DCB_APP_ATTR_PRIORITY] = {.type = NLA_U8},
168}; 169};
169 170
171/* IEEE 802.1Qaz nested attributes. */
172static const struct nla_policy dcbnl_ieee_policy[DCB_ATTR_IEEE_MAX + 1] = {
173 [DCB_ATTR_IEEE_ETS] = {.len = sizeof(struct ieee_ets)},
174 [DCB_ATTR_IEEE_PFC] = {.len = sizeof(struct ieee_pfc)},
175 [DCB_ATTR_IEEE_APP_TABLE] = {.type = NLA_NESTED},
176};
177
178static const struct nla_policy dcbnl_ieee_app[DCB_ATTR_IEEE_APP_MAX + 1] = {
179 [DCB_ATTR_IEEE_APP] = {.len = sizeof(struct dcb_app)},
180};
181
170/* standard netlink reply call */ 182/* standard netlink reply call */
171static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid, 183static int dcbnl_reply(u8 value, u8 event, u8 cmd, u8 attr, u32 pid,
172 u32 seq, u16 flags) 184 u32 seq, u16 flags)
@@ -1118,6 +1130,117 @@ err:
1118 return ret; 1130 return ret;
1119} 1131}
1120 1132
1133/* Handle IEEE 802.1Qaz SET commands. If any requested operation can not
1134 * be completed the entire msg is aborted and error value is returned.
1135 * No attempt is made to reconcile the case where only part of the
1136 * cmd can be completed.
1137 */
1138static int dcbnl_ieee_set(struct net_device *netdev, struct nlattr **tb,
1139 u32 pid, u32 seq, u16 flags)
1140{
1141 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1142 struct nlattr *ieee[DCB_ATTR_IEEE_MAX + 1];
1143 int err = -EOPNOTSUPP;
1144
1145 if (!ops)
1146 goto err;
1147
1148 err = nla_parse_nested(ieee, DCB_ATTR_IEEE_MAX,
1149 tb[DCB_ATTR_IEEE], dcbnl_ieee_policy);
1150 if (err)
1151 goto err;
1152
1153 if (ieee[DCB_ATTR_IEEE_ETS] && ops->ieee_setets) {
1154 struct ieee_ets *ets = nla_data(ieee[DCB_ATTR_IEEE_ETS]);
1155 err = ops->ieee_setets(netdev, ets);
1156 if (err)
1157 goto err;
1158 }
1159
1160 if (ieee[DCB_ATTR_IEEE_PFC] && ops->ieee_setets) {
1161 struct ieee_pfc *pfc = nla_data(ieee[DCB_ATTR_IEEE_PFC]);
1162 err = ops->ieee_setpfc(netdev, pfc);
1163 if (err)
1164 goto err;
1165 }
1166
1167 if (ieee[DCB_ATTR_IEEE_APP_TABLE] && ops->ieee_setapp) {
1168 struct nlattr *attr;
1169 int rem;
1170
1171 nla_for_each_nested(attr, ieee[DCB_ATTR_IEEE_APP_TABLE], rem) {
1172 struct dcb_app *app_data;
1173 if (nla_type(attr) != DCB_ATTR_IEEE_APP)
1174 continue;
1175 app_data = nla_data(attr);
1176 err = ops->ieee_setapp(netdev, app_data);
1177 if (err)
1178 goto err;
1179 }
1180 }
1181
1182err:
1183 dcbnl_reply(err, RTM_SETDCB, DCB_CMD_IEEE_SET, DCB_ATTR_IEEE,
1184 pid, seq, flags);
1185 return err;
1186}
1187
1188
1189/* Handle IEEE 802.1Qaz GET commands. */
1190static int dcbnl_ieee_get(struct net_device *netdev, struct nlattr **tb,
1191 u32 pid, u32 seq, u16 flags)
1192{
1193 struct sk_buff *skb;
1194 struct nlmsghdr *nlh;
1195 struct dcbmsg *dcb;
1196 struct nlattr *ieee;
1197 const struct dcbnl_rtnl_ops *ops = netdev->dcbnl_ops;
1198 int err;
1199
1200 if (!ops)
1201 return -EOPNOTSUPP;
1202
1203 skb = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1204 if (!skb)
1205 return -ENOBUFS;
1206
1207 nlh = NLMSG_NEW(skb, pid, seq, RTM_GETDCB, sizeof(*dcb), flags);
1208
1209 dcb = NLMSG_DATA(nlh);
1210 dcb->dcb_family = AF_UNSPEC;
1211 dcb->cmd = DCB_CMD_IEEE_GET;
1212
1213 NLA_PUT_STRING(skb, DCB_ATTR_IFNAME, netdev->name);
1214
1215 ieee = nla_nest_start(skb, DCB_ATTR_IEEE);
1216 if (!ieee)
1217 goto nla_put_failure;
1218
1219 if (ops->ieee_getets) {
1220 struct ieee_ets ets;
1221 err = ops->ieee_getets(netdev, &ets);
1222 if (!err)
1223 NLA_PUT(skb, DCB_ATTR_IEEE_ETS, sizeof(ets), &ets);
1224 }
1225
1226 if (ops->ieee_getpfc) {
1227 struct ieee_pfc pfc;
1228 err = ops->ieee_getpfc(netdev, &pfc);
1229 if (!err)
1230 NLA_PUT(skb, DCB_ATTR_IEEE_PFC, sizeof(pfc), &pfc);
1231 }
1232
1233 nla_nest_end(skb, ieee);
1234 nlmsg_end(skb, nlh);
1235
1236 return rtnl_unicast(skb, &init_net, pid);
1237nla_put_failure:
1238 nlmsg_cancel(skb, nlh);
1239nlmsg_failure:
1240 kfree_skb(skb);
1241 return -1;
1242}
1243
1121static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 1244static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1122{ 1245{
1123 struct net *net = sock_net(skb->sk); 1246 struct net *net = sock_net(skb->sk);
@@ -1223,6 +1346,14 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1223 ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq, 1346 ret = dcbnl_setapp(netdev, tb, pid, nlh->nlmsg_seq,
1224 nlh->nlmsg_flags); 1347 nlh->nlmsg_flags);
1225 goto out; 1348 goto out;
1349 case DCB_CMD_IEEE_SET:
1350 ret = dcbnl_ieee_set(netdev, tb, pid, nlh->nlmsg_seq,
1351 nlh->nlmsg_flags);
1352 goto out;
1353 case DCB_CMD_IEEE_GET:
1354 ret = dcbnl_ieee_get(netdev, tb, pid, nlh->nlmsg_seq,
1355 nlh->nlmsg_flags);
1356 goto out;
1226 default: 1357 default:
1227 goto errout; 1358 goto errout;
1228 } 1359 }