aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/intel/ice
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/intel/ice')
-rw-r--r--drivers/net/ethernet/intel/ice/ice_adminq_cmd.h79
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb.c819
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb.h99
-rw-r--r--drivers/net/ethernet/intel/ice/ice_dcb_lib.c2
-rw-r--r--drivers/net/ethernet/intel/ice/ice_status.h1
-rw-r--r--drivers/net/ethernet/intel/ice/ice_type.h58
6 files changed, 1057 insertions, 1 deletions
diff --git a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
index 4809e5ac55f4..bbceaca11541 100644
--- a/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/ice/ice_adminq_cmd.h
@@ -1132,6 +1132,48 @@ struct ice_aqc_pf_vf_msg {
1132 __le32 addr_low; 1132 __le32 addr_low;
1133}; 1133};
1134 1134
1135/* Get LLDP MIB (indirect 0x0A00)
1136 * Note: This is also used by the LLDP MIB Change Event (0x0A01)
1137 * as the format is the same.
1138 */
1139struct ice_aqc_lldp_get_mib {
1140 u8 type;
1141#define ICE_AQ_LLDP_MIB_TYPE_S 0
1142#define ICE_AQ_LLDP_MIB_TYPE_M (0x3 << ICE_AQ_LLDP_MIB_TYPE_S)
1143#define ICE_AQ_LLDP_MIB_LOCAL 0
1144#define ICE_AQ_LLDP_MIB_REMOTE 1
1145#define ICE_AQ_LLDP_MIB_LOCAL_AND_REMOTE 2
1146#define ICE_AQ_LLDP_BRID_TYPE_S 2
1147#define ICE_AQ_LLDP_BRID_TYPE_M (0x3 << ICE_AQ_LLDP_BRID_TYPE_S)
1148#define ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID 0
1149#define ICE_AQ_LLDP_BRID_TYPE_NON_TPMR 1
1150/* Tx pause flags in the 0xA01 event use ICE_AQ_LLDP_TX_* */
1151#define ICE_AQ_LLDP_TX_S 0x4
1152#define ICE_AQ_LLDP_TX_M (0x03 << ICE_AQ_LLDP_TX_S)
1153#define ICE_AQ_LLDP_TX_ACTIVE 0
1154#define ICE_AQ_LLDP_TX_SUSPENDED 1
1155#define ICE_AQ_LLDP_TX_FLUSHED 3
1156/* The following bytes are reserved for the Get LLDP MIB command (0x0A00)
1157 * and in the LLDP MIB Change Event (0x0A01). They are valid for the
1158 * Get LLDP MIB (0x0A00) response only.
1159 */
1160 u8 reserved1;
1161 __le16 local_len;
1162 __le16 remote_len;
1163 u8 reserved2[2];
1164 __le32 addr_high;
1165 __le32 addr_low;
1166};
1167
1168/* Configure LLDP MIB Change Event (direct 0x0A01) */
1169/* For MIB Change Event use ice_aqc_lldp_get_mib structure above */
1170struct ice_aqc_lldp_set_mib_change {
1171 u8 command;
1172#define ICE_AQ_LLDP_MIB_UPDATE_ENABLE 0x0
1173#define ICE_AQ_LLDP_MIB_UPDATE_DIS 0x1
1174 u8 reserved[15];
1175};
1176
1135/* Start LLDP (direct 0x0A06) */ 1177/* Start LLDP (direct 0x0A06) */
1136struct ice_aqc_lldp_start { 1178struct ice_aqc_lldp_start {
1137 u8 command; 1179 u8 command;
@@ -1140,6 +1182,36 @@ struct ice_aqc_lldp_start {
1140 u8 reserved[15]; 1182 u8 reserved[15];
1141}; 1183};
1142 1184
1185/* Get CEE DCBX Oper Config (0x0A07)
1186 * The command uses the generic descriptor struct and
1187 * returns the struct below as an indirect response.
1188 */
1189struct ice_aqc_get_cee_dcb_cfg_resp {
1190 u8 oper_num_tc;
1191 u8 oper_prio_tc[4];
1192 u8 oper_tc_bw[8];
1193 u8 oper_pfc_en;
1194 __le16 oper_app_prio;
1195#define ICE_AQC_CEE_APP_FCOE_S 0
1196#define ICE_AQC_CEE_APP_FCOE_M (0x7 << ICE_AQC_CEE_APP_FCOE_S)
1197#define ICE_AQC_CEE_APP_ISCSI_S 3
1198#define ICE_AQC_CEE_APP_ISCSI_M (0x7 << ICE_AQC_CEE_APP_ISCSI_S)
1199#define ICE_AQC_CEE_APP_FIP_S 8
1200#define ICE_AQC_CEE_APP_FIP_M (0x7 << ICE_AQC_CEE_APP_FIP_S)
1201 __le32 tlv_status;
1202#define ICE_AQC_CEE_PG_STATUS_S 0
1203#define ICE_AQC_CEE_PG_STATUS_M (0x7 << ICE_AQC_CEE_PG_STATUS_S)
1204#define ICE_AQC_CEE_PFC_STATUS_S 3
1205#define ICE_AQC_CEE_PFC_STATUS_M (0x7 << ICE_AQC_CEE_PFC_STATUS_S)
1206#define ICE_AQC_CEE_FCOE_STATUS_S 8
1207#define ICE_AQC_CEE_FCOE_STATUS_M (0x7 << ICE_AQC_CEE_FCOE_STATUS_S)
1208#define ICE_AQC_CEE_ISCSI_STATUS_S 11
1209#define ICE_AQC_CEE_ISCSI_STATUS_M (0x7 << ICE_AQC_CEE_ISCSI_STATUS_S)
1210#define ICE_AQC_CEE_FIP_STATUS_S 16
1211#define ICE_AQC_CEE_FIP_STATUS_M (0x7 << ICE_AQC_CEE_FIP_STATUS_S)
1212 u8 reserved[12];
1213};
1214
1143/* Stop/Start LLDP Agent (direct 0x0A09) 1215/* Stop/Start LLDP Agent (direct 0x0A09)
1144 * Used for stopping/starting specific LLDP agent. e.g. DCBx. 1216 * Used for stopping/starting specific LLDP agent. e.g. DCBx.
1145 * The same structure is used for the response, with the command field 1217 * The same structure is used for the response, with the command field
@@ -1411,6 +1483,8 @@ struct ice_aq_desc {
1411 struct ice_aqc_query_txsched_res query_sched_res; 1483 struct ice_aqc_query_txsched_res query_sched_res;
1412 struct ice_aqc_nvm nvm; 1484 struct ice_aqc_nvm nvm;
1413 struct ice_aqc_pf_vf_msg virt; 1485 struct ice_aqc_pf_vf_msg virt;
1486 struct ice_aqc_lldp_get_mib lldp_get_mib;
1487 struct ice_aqc_lldp_set_mib_change lldp_set_event;
1414 struct ice_aqc_lldp_start lldp_start; 1488 struct ice_aqc_lldp_start lldp_start;
1415 struct ice_aqc_lldp_stop_start_specific_agent lldp_agent_ctrl; 1489 struct ice_aqc_lldp_stop_start_specific_agent lldp_agent_ctrl;
1416 struct ice_aqc_get_set_rss_lut get_set_rss_lut; 1490 struct ice_aqc_get_set_rss_lut get_set_rss_lut;
@@ -1445,6 +1519,8 @@ struct ice_aq_desc {
1445/* error codes */ 1519/* error codes */
1446enum ice_aq_err { 1520enum ice_aq_err {
1447 ICE_AQ_RC_OK = 0, /* Success */ 1521 ICE_AQ_RC_OK = 0, /* Success */
1522 ICE_AQ_RC_EPERM = 1, /* Operation not permitted */
1523 ICE_AQ_RC_ENOENT = 2, /* No such element */
1448 ICE_AQ_RC_ENOMEM = 9, /* Out of memory */ 1524 ICE_AQ_RC_ENOMEM = 9, /* Out of memory */
1449 ICE_AQ_RC_EBUSY = 12, /* Device or resource busy */ 1525 ICE_AQ_RC_EBUSY = 12, /* Device or resource busy */
1450 ICE_AQ_RC_EEXIST = 13, /* Object already exists */ 1526 ICE_AQ_RC_EEXIST = 13, /* Object already exists */
@@ -1515,7 +1591,10 @@ enum ice_adminq_opc {
1515 ice_mbx_opc_send_msg_to_pf = 0x0801, 1591 ice_mbx_opc_send_msg_to_pf = 0x0801,
1516 ice_mbx_opc_send_msg_to_vf = 0x0802, 1592 ice_mbx_opc_send_msg_to_vf = 0x0802,
1517 /* LLDP commands */ 1593 /* LLDP commands */
1594 ice_aqc_opc_lldp_get_mib = 0x0A00,
1595 ice_aqc_opc_lldp_set_mib_change = 0x0A01,
1518 ice_aqc_opc_lldp_start = 0x0A06, 1596 ice_aqc_opc_lldp_start = 0x0A06,
1597 ice_aqc_opc_get_cee_dcb_cfg = 0x0A07,
1519 ice_aqc_opc_lldp_stop_start_specific_agent = 0x0A09, 1598 ice_aqc_opc_lldp_stop_start_specific_agent = 0x0A09,
1520 1599
1521 /* RSS commands */ 1600 /* RSS commands */
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb.c b/drivers/net/ethernet/intel/ice/ice_dcb.c
index 39543e487ec1..6f0c6f323c60 100644
--- a/drivers/net/ethernet/intel/ice/ice_dcb.c
+++ b/drivers/net/ethernet/intel/ice/ice_dcb.c
@@ -6,6 +6,78 @@
6#include "ice_dcb.h" 6#include "ice_dcb.h"
7 7
8/** 8/**
9 * ice_aq_get_lldp_mib
10 * @hw: pointer to the HW struct
11 * @bridge_type: type of bridge requested
12 * @mib_type: Local, Remote or both Local and Remote MIBs
13 * @buf: pointer to the caller-supplied buffer to store the MIB block
14 * @buf_size: size of the buffer (in bytes)
15 * @local_len: length of the returned Local LLDP MIB
16 * @remote_len: length of the returned Remote LLDP MIB
17 * @cd: pointer to command details structure or NULL
18 *
19 * Requests the complete LLDP MIB (entire packet). (0x0A00)
20 */
21static enum ice_status
22ice_aq_get_lldp_mib(struct ice_hw *hw, u8 bridge_type, u8 mib_type, void *buf,
23 u16 buf_size, u16 *local_len, u16 *remote_len,
24 struct ice_sq_cd *cd)
25{
26 struct ice_aqc_lldp_get_mib *cmd;
27 struct ice_aq_desc desc;
28 enum ice_status status;
29
30 cmd = &desc.params.lldp_get_mib;
31
32 if (buf_size == 0 || !buf)
33 return ICE_ERR_PARAM;
34
35 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_get_mib);
36
37 cmd->type = mib_type & ICE_AQ_LLDP_MIB_TYPE_M;
38 cmd->type |= (bridge_type << ICE_AQ_LLDP_BRID_TYPE_S) &
39 ICE_AQ_LLDP_BRID_TYPE_M;
40
41 desc.datalen = cpu_to_le16(buf_size);
42
43 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
44 if (!status) {
45 if (local_len)
46 *local_len = le16_to_cpu(cmd->local_len);
47 if (remote_len)
48 *remote_len = le16_to_cpu(cmd->remote_len);
49 }
50
51 return status;
52}
53
54/**
55 * ice_aq_cfg_lldp_mib_change
56 * @hw: pointer to the HW struct
57 * @ena_update: Enable or Disable event posting
58 * @cd: pointer to command details structure or NULL
59 *
60 * Enable or Disable posting of an event on ARQ when LLDP MIB
61 * associated with the interface changes (0x0A01)
62 */
63static enum ice_status
64ice_aq_cfg_lldp_mib_change(struct ice_hw *hw, bool ena_update,
65 struct ice_sq_cd *cd)
66{
67 struct ice_aqc_lldp_set_mib_change *cmd;
68 struct ice_aq_desc desc;
69
70 cmd = &desc.params.lldp_set_event;
71
72 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_lldp_set_mib_change);
73
74 if (!ena_update)
75 cmd->command |= ICE_AQ_LLDP_MIB_UPDATE_DIS;
76
77 return ice_aq_send_cmd(hw, &desc, NULL, 0, cd);
78}
79
80/**
9 * ice_aq_start_lldp 81 * ice_aq_start_lldp
10 * @hw: pointer to the HW struct 82 * @hw: pointer to the HW struct
11 * @cd: pointer to command details structure or NULL 83 * @cd: pointer to command details structure or NULL
@@ -42,6 +114,523 @@ u8 ice_get_dcbx_status(struct ice_hw *hw)
42} 114}
43 115
44/** 116/**
117 * ice_parse_ieee_ets_common_tlv
118 * @buf: Data buffer to be parsed for ETS CFG/REC data
119 * @ets_cfg: Container to store parsed data
120 *
121 * Parses the common data of IEEE 802.1Qaz ETS CFG/REC TLV
122 */
123static void
124ice_parse_ieee_ets_common_tlv(u8 *buf, struct ice_dcb_ets_cfg *ets_cfg)
125{
126 u8 offset = 0;
127 int i;
128
129 /* Priority Assignment Table (4 octets)
130 * Octets:| 1 | 2 | 3 | 4 |
131 * -----------------------------------------
132 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
133 * -----------------------------------------
134 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
135 * -----------------------------------------
136 */
137 for (i = 0; i < 4; i++) {
138 ets_cfg->prio_table[i * 2] =
139 ((buf[offset] & ICE_IEEE_ETS_PRIO_1_M) >>
140 ICE_IEEE_ETS_PRIO_1_S);
141 ets_cfg->prio_table[i * 2 + 1] =
142 ((buf[offset] & ICE_IEEE_ETS_PRIO_0_M) >>
143 ICE_IEEE_ETS_PRIO_0_S);
144 offset++;
145 }
146
147 /* TC Bandwidth Table (8 octets)
148 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
149 * ---------------------------------
150 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
151 * ---------------------------------
152 *
153 * TSA Assignment Table (8 octets)
154 * Octets:| 9 | 10| 11| 12| 13| 14| 15| 16|
155 * ---------------------------------
156 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
157 * ---------------------------------
158 */
159 ice_for_each_traffic_class(i) {
160 ets_cfg->tcbwtable[i] = buf[offset];
161 ets_cfg->tsatable[i] = buf[ICE_MAX_TRAFFIC_CLASS + offset++];
162 }
163}
164
165/**
166 * ice_parse_ieee_etscfg_tlv
167 * @tlv: IEEE 802.1Qaz ETS CFG TLV
168 * @dcbcfg: Local store to update ETS CFG data
169 *
170 * Parses IEEE 802.1Qaz ETS CFG TLV
171 */
172static void
173ice_parse_ieee_etscfg_tlv(struct ice_lldp_org_tlv *tlv,
174 struct ice_dcbx_cfg *dcbcfg)
175{
176 struct ice_dcb_ets_cfg *etscfg;
177 u8 *buf = tlv->tlvinfo;
178
179 /* First Octet post subtype
180 * --------------------------
181 * |will-|CBS | Re- | Max |
182 * |ing | |served| TCs |
183 * --------------------------
184 * |1bit | 1bit|3 bits|3bits|
185 */
186 etscfg = &dcbcfg->etscfg;
187 etscfg->willing = ((buf[0] & ICE_IEEE_ETS_WILLING_M) >>
188 ICE_IEEE_ETS_WILLING_S);
189 etscfg->cbs = ((buf[0] & ICE_IEEE_ETS_CBS_M) >> ICE_IEEE_ETS_CBS_S);
190 etscfg->maxtcs = ((buf[0] & ICE_IEEE_ETS_MAXTC_M) >>
191 ICE_IEEE_ETS_MAXTC_S);
192
193 /* Begin parsing at Priority Assignment Table (offset 1 in buf) */
194 ice_parse_ieee_ets_common_tlv(&buf[1], etscfg);
195}
196
197/**
198 * ice_parse_ieee_etsrec_tlv
199 * @tlv: IEEE 802.1Qaz ETS REC TLV
200 * @dcbcfg: Local store to update ETS REC data
201 *
202 * Parses IEEE 802.1Qaz ETS REC TLV
203 */
204static void
205ice_parse_ieee_etsrec_tlv(struct ice_lldp_org_tlv *tlv,
206 struct ice_dcbx_cfg *dcbcfg)
207{
208 u8 *buf = tlv->tlvinfo;
209
210 /* Begin parsing at Priority Assignment Table (offset 1 in buf) */
211 ice_parse_ieee_ets_common_tlv(&buf[1], &dcbcfg->etsrec);
212}
213
214/**
215 * ice_parse_ieee_pfccfg_tlv
216 * @tlv: IEEE 802.1Qaz PFC CFG TLV
217 * @dcbcfg: Local store to update PFC CFG data
218 *
219 * Parses IEEE 802.1Qaz PFC CFG TLV
220 */
221static void
222ice_parse_ieee_pfccfg_tlv(struct ice_lldp_org_tlv *tlv,
223 struct ice_dcbx_cfg *dcbcfg)
224{
225 u8 *buf = tlv->tlvinfo;
226
227 /* ----------------------------------------
228 * |will-|MBC | Re- | PFC | PFC Enable |
229 * |ing | |served| cap | |
230 * -----------------------------------------
231 * |1bit | 1bit|2 bits|4bits| 1 octet |
232 */
233 dcbcfg->pfc.willing = ((buf[0] & ICE_IEEE_PFC_WILLING_M) >>
234 ICE_IEEE_PFC_WILLING_S);
235 dcbcfg->pfc.mbc = ((buf[0] & ICE_IEEE_PFC_MBC_M) >> ICE_IEEE_PFC_MBC_S);
236 dcbcfg->pfc.pfccap = ((buf[0] & ICE_IEEE_PFC_CAP_M) >>
237 ICE_IEEE_PFC_CAP_S);
238 dcbcfg->pfc.pfcena = buf[1];
239}
240
241/**
242 * ice_parse_ieee_app_tlv
243 * @tlv: IEEE 802.1Qaz APP TLV
244 * @dcbcfg: Local store to update APP PRIO data
245 *
246 * Parses IEEE 802.1Qaz APP PRIO TLV
247 */
248static void
249ice_parse_ieee_app_tlv(struct ice_lldp_org_tlv *tlv,
250 struct ice_dcbx_cfg *dcbcfg)
251{
252 u16 offset = 0;
253 u16 typelen;
254 int i = 0;
255 u16 len;
256 u8 *buf;
257
258 typelen = ntohs(tlv->typelen);
259 len = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
260 buf = tlv->tlvinfo;
261
262 /* Removing sizeof(ouisubtype) and reserved byte from len.
263 * Remaining len div 3 is number of APP TLVs.
264 */
265 len -= (sizeof(tlv->ouisubtype) + 1);
266
267 /* Move offset to App Priority Table */
268 offset++;
269
270 /* Application Priority Table (3 octets)
271 * Octets:| 1 | 2 | 3 |
272 * -----------------------------------------
273 * |Priority|Rsrvd| Sel | Protocol ID |
274 * -----------------------------------------
275 * Bits:|23 21|20 19|18 16|15 0|
276 * -----------------------------------------
277 */
278 while (offset < len) {
279 dcbcfg->app[i].priority = ((buf[offset] &
280 ICE_IEEE_APP_PRIO_M) >>
281 ICE_IEEE_APP_PRIO_S);
282 dcbcfg->app[i].selector = ((buf[offset] &
283 ICE_IEEE_APP_SEL_M) >>
284 ICE_IEEE_APP_SEL_S);
285 dcbcfg->app[i].prot_id = (buf[offset + 1] << 0x8) |
286 buf[offset + 2];
287 /* Move to next app */
288 offset += 3;
289 i++;
290 if (i >= ICE_DCBX_MAX_APPS)
291 break;
292 }
293
294 dcbcfg->numapps = i;
295}
296
297/**
298 * ice_parse_ieee_tlv
299 * @tlv: IEEE 802.1Qaz TLV
300 * @dcbcfg: Local store to update ETS REC data
301 *
302 * Get the TLV subtype and send it to parsing function
303 * based on the subtype value
304 */
305static void
306ice_parse_ieee_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
307{
308 u32 ouisubtype;
309 u8 subtype;
310
311 ouisubtype = ntohl(tlv->ouisubtype);
312 subtype = (u8)((ouisubtype & ICE_LLDP_TLV_SUBTYPE_M) >>
313 ICE_LLDP_TLV_SUBTYPE_S);
314 switch (subtype) {
315 case ICE_IEEE_SUBTYPE_ETS_CFG:
316 ice_parse_ieee_etscfg_tlv(tlv, dcbcfg);
317 break;
318 case ICE_IEEE_SUBTYPE_ETS_REC:
319 ice_parse_ieee_etsrec_tlv(tlv, dcbcfg);
320 break;
321 case ICE_IEEE_SUBTYPE_PFC_CFG:
322 ice_parse_ieee_pfccfg_tlv(tlv, dcbcfg);
323 break;
324 case ICE_IEEE_SUBTYPE_APP_PRI:
325 ice_parse_ieee_app_tlv(tlv, dcbcfg);
326 break;
327 default:
328 break;
329 }
330}
331
332/**
333 * ice_parse_cee_pgcfg_tlv
334 * @tlv: CEE DCBX PG CFG TLV
335 * @dcbcfg: Local store to update ETS CFG data
336 *
337 * Parses CEE DCBX PG CFG TLV
338 */
339static void
340ice_parse_cee_pgcfg_tlv(struct ice_cee_feat_tlv *tlv,
341 struct ice_dcbx_cfg *dcbcfg)
342{
343 struct ice_dcb_ets_cfg *etscfg;
344 u8 *buf = tlv->tlvinfo;
345 u16 offset = 0;
346 int i;
347
348 etscfg = &dcbcfg->etscfg;
349
350 if (tlv->en_will_err & ICE_CEE_FEAT_TLV_WILLING_M)
351 etscfg->willing = 1;
352
353 etscfg->cbs = 0;
354 /* Priority Group Table (4 octets)
355 * Octets:| 1 | 2 | 3 | 4 |
356 * -----------------------------------------
357 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
358 * -----------------------------------------
359 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
360 * -----------------------------------------
361 */
362 for (i = 0; i < 4; i++) {
363 etscfg->prio_table[i * 2] =
364 ((buf[offset] & ICE_CEE_PGID_PRIO_1_M) >>
365 ICE_CEE_PGID_PRIO_1_S);
366 etscfg->prio_table[i * 2 + 1] =
367 ((buf[offset] & ICE_CEE_PGID_PRIO_0_M) >>
368 ICE_CEE_PGID_PRIO_0_S);
369 offset++;
370 }
371
372 /* PG Percentage Table (8 octets)
373 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
374 * ---------------------------------
375 * |pg0|pg1|pg2|pg3|pg4|pg5|pg6|pg7|
376 * ---------------------------------
377 */
378 ice_for_each_traffic_class(i)
379 etscfg->tcbwtable[i] = buf[offset++];
380
381 /* Number of TCs supported (1 octet) */
382 etscfg->maxtcs = buf[offset];
383}
384
385/**
386 * ice_parse_cee_pfccfg_tlv
387 * @tlv: CEE DCBX PFC CFG TLV
388 * @dcbcfg: Local store to update PFC CFG data
389 *
390 * Parses CEE DCBX PFC CFG TLV
391 */
392static void
393ice_parse_cee_pfccfg_tlv(struct ice_cee_feat_tlv *tlv,
394 struct ice_dcbx_cfg *dcbcfg)
395{
396 u8 *buf = tlv->tlvinfo;
397
398 if (tlv->en_will_err & ICE_CEE_FEAT_TLV_WILLING_M)
399 dcbcfg->pfc.willing = 1;
400
401 /* ------------------------
402 * | PFC Enable | PFC TCs |
403 * ------------------------
404 * | 1 octet | 1 octet |
405 */
406 dcbcfg->pfc.pfcena = buf[0];
407 dcbcfg->pfc.pfccap = buf[1];
408}
409
410/**
411 * ice_parse_cee_app_tlv
412 * @tlv: CEE DCBX APP TLV
413 * @dcbcfg: Local store to update APP PRIO data
414 *
415 * Parses CEE DCBX APP PRIO TLV
416 */
417static void
418ice_parse_cee_app_tlv(struct ice_cee_feat_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
419{
420 u16 len, typelen, offset = 0;
421 struct ice_cee_app_prio *app;
422 u8 i;
423
424 typelen = ntohs(tlv->hdr.typelen);
425 len = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
426
427 dcbcfg->numapps = len / sizeof(*app);
428 if (!dcbcfg->numapps)
429 return;
430 if (dcbcfg->numapps > ICE_DCBX_MAX_APPS)
431 dcbcfg->numapps = ICE_DCBX_MAX_APPS;
432
433 for (i = 0; i < dcbcfg->numapps; i++) {
434 u8 up, selector;
435
436 app = (struct ice_cee_app_prio *)(tlv->tlvinfo + offset);
437 for (up = 0; up < ICE_MAX_USER_PRIORITY; up++)
438 if (app->prio_map & BIT(up))
439 break;
440
441 dcbcfg->app[i].priority = up;
442
443 /* Get Selector from lower 2 bits, and convert to IEEE */
444 selector = (app->upper_oui_sel & ICE_CEE_APP_SELECTOR_M);
445 switch (selector) {
446 case ICE_CEE_APP_SEL_ETHTYPE:
447 dcbcfg->app[i].selector = ICE_APP_SEL_ETHTYPE;
448 break;
449 case ICE_CEE_APP_SEL_TCPIP:
450 dcbcfg->app[i].selector = ICE_APP_SEL_TCPIP;
451 break;
452 default:
453 /* Keep selector as it is for unknown types */
454 dcbcfg->app[i].selector = selector;
455 }
456
457 dcbcfg->app[i].prot_id = ntohs(app->protocol);
458 /* Move to next app */
459 offset += sizeof(*app);
460 }
461}
462
463/**
464 * ice_parse_cee_tlv
465 * @tlv: CEE DCBX TLV
466 * @dcbcfg: Local store to update DCBX config data
467 *
468 * Get the TLV subtype and send it to parsing function
469 * based on the subtype value
470 */
471static void
472ice_parse_cee_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
473{
474 struct ice_cee_feat_tlv *sub_tlv;
475 u8 subtype, feat_tlv_count = 0;
476 u16 len, tlvlen, typelen;
477 u32 ouisubtype;
478
479 ouisubtype = ntohl(tlv->ouisubtype);
480 subtype = (u8)((ouisubtype & ICE_LLDP_TLV_SUBTYPE_M) >>
481 ICE_LLDP_TLV_SUBTYPE_S);
482 /* Return if not CEE DCBX */
483 if (subtype != ICE_CEE_DCBX_TYPE)
484 return;
485
486 typelen = ntohs(tlv->typelen);
487 tlvlen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
488 len = sizeof(tlv->typelen) + sizeof(ouisubtype) +
489 sizeof(struct ice_cee_ctrl_tlv);
490 /* Return if no CEE DCBX Feature TLVs */
491 if (tlvlen <= len)
492 return;
493
494 sub_tlv = (struct ice_cee_feat_tlv *)((char *)tlv + len);
495 while (feat_tlv_count < ICE_CEE_MAX_FEAT_TYPE) {
496 u16 sublen;
497
498 typelen = ntohs(sub_tlv->hdr.typelen);
499 sublen = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
500 subtype = (u8)((typelen & ICE_LLDP_TLV_TYPE_M) >>
501 ICE_LLDP_TLV_TYPE_S);
502 switch (subtype) {
503 case ICE_CEE_SUBTYPE_PG_CFG:
504 ice_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);
505 break;
506 case ICE_CEE_SUBTYPE_PFC_CFG:
507 ice_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);
508 break;
509 case ICE_CEE_SUBTYPE_APP_PRI:
510 ice_parse_cee_app_tlv(sub_tlv, dcbcfg);
511 break;
512 default:
513 return; /* Invalid Sub-type return */
514 }
515 feat_tlv_count++;
516 /* Move to next sub TLV */
517 sub_tlv = (struct ice_cee_feat_tlv *)
518 ((char *)sub_tlv + sizeof(sub_tlv->hdr.typelen) +
519 sublen);
520 }
521}
522
523/**
524 * ice_parse_org_tlv
525 * @tlv: Organization specific TLV
526 * @dcbcfg: Local store to update ETS REC data
527 *
528 * Currently only IEEE 802.1Qaz TLV is supported, all others
529 * will be returned
530 */
531static void
532ice_parse_org_tlv(struct ice_lldp_org_tlv *tlv, struct ice_dcbx_cfg *dcbcfg)
533{
534 u32 ouisubtype;
535 u32 oui;
536
537 ouisubtype = ntohl(tlv->ouisubtype);
538 oui = ((ouisubtype & ICE_LLDP_TLV_OUI_M) >> ICE_LLDP_TLV_OUI_S);
539 switch (oui) {
540 case ICE_IEEE_8021QAZ_OUI:
541 ice_parse_ieee_tlv(tlv, dcbcfg);
542 break;
543 case ICE_CEE_DCBX_OUI:
544 ice_parse_cee_tlv(tlv, dcbcfg);
545 break;
546 default:
547 break;
548 }
549}
550
551/**
552 * ice_lldp_to_dcb_cfg
553 * @lldpmib: LLDPDU to be parsed
554 * @dcbcfg: store for LLDPDU data
555 *
556 * Parse DCB configuration from the LLDPDU
557 */
558static enum ice_status
559ice_lldp_to_dcb_cfg(u8 *lldpmib, struct ice_dcbx_cfg *dcbcfg)
560{
561 struct ice_lldp_org_tlv *tlv;
562 enum ice_status ret = 0;
563 u16 offset = 0;
564 u16 typelen;
565 u16 type;
566 u16 len;
567
568 if (!lldpmib || !dcbcfg)
569 return ICE_ERR_PARAM;
570
571 /* set to the start of LLDPDU */
572 lldpmib += ETH_HLEN;
573 tlv = (struct ice_lldp_org_tlv *)lldpmib;
574 while (1) {
575 typelen = ntohs(tlv->typelen);
576 type = ((typelen & ICE_LLDP_TLV_TYPE_M) >> ICE_LLDP_TLV_TYPE_S);
577 len = ((typelen & ICE_LLDP_TLV_LEN_M) >> ICE_LLDP_TLV_LEN_S);
578 offset += sizeof(typelen) + len;
579
580 /* END TLV or beyond LLDPDU size */
581 if (type == ICE_TLV_TYPE_END || offset > ICE_LLDPDU_SIZE)
582 break;
583
584 switch (type) {
585 case ICE_TLV_TYPE_ORG:
586 ice_parse_org_tlv(tlv, dcbcfg);
587 break;
588 default:
589 break;
590 }
591
592 /* Move to next TLV */
593 tlv = (struct ice_lldp_org_tlv *)
594 ((char *)tlv + sizeof(tlv->typelen) + len);
595 }
596
597 return ret;
598}
599
600/**
601 * ice_aq_get_dcb_cfg
602 * @hw: pointer to the HW struct
603 * @mib_type: mib type for the query
604 * @bridgetype: bridge type for the query (remote)
605 * @dcbcfg: store for LLDPDU data
606 *
607 * Query DCB configuration from the firmware
608 */
609static enum ice_status
610ice_aq_get_dcb_cfg(struct ice_hw *hw, u8 mib_type, u8 bridgetype,
611 struct ice_dcbx_cfg *dcbcfg)
612{
613 enum ice_status ret;
614 u8 *lldpmib;
615
616 /* Allocate the LLDPDU */
617 lldpmib = devm_kzalloc(ice_hw_to_dev(hw), ICE_LLDPDU_SIZE, GFP_KERNEL);
618 if (!lldpmib)
619 return ICE_ERR_NO_MEMORY;
620
621 ret = ice_aq_get_lldp_mib(hw, bridgetype, mib_type, (void *)lldpmib,
622 ICE_LLDPDU_SIZE, NULL, NULL, NULL);
623
624 if (!ret)
625 /* Parse LLDP MIB to get DCB configuration */
626 ret = ice_lldp_to_dcb_cfg(lldpmib, dcbcfg);
627
628 devm_kfree(ice_hw_to_dev(hw), lldpmib);
629
630 return ret;
631}
632
633/**
45 * ice_aq_start_stop_dcbx - Start/Stop DCBx service in FW 634 * ice_aq_start_stop_dcbx - Start/Stop DCBx service in FW
46 * @hw: pointer to the HW struct 635 * @hw: pointer to the HW struct
47 * @start_dcbx_agent: True if DCBx Agent needs to be started 636 * @start_dcbx_agent: True if DCBx Agent needs to be started
@@ -83,3 +672,233 @@ ice_aq_start_stop_dcbx(struct ice_hw *hw, bool start_dcbx_agent,
83 672
84 return status; 673 return status;
85} 674}
675
676/**
677 * ice_aq_get_cee_dcb_cfg
678 * @hw: pointer to the HW struct
679 * @buff: response buffer that stores CEE operational configuration
680 * @cd: pointer to command details structure or NULL
681 *
682 * Get CEE DCBX mode operational configuration from firmware (0x0A07)
683 */
684static enum ice_status
685ice_aq_get_cee_dcb_cfg(struct ice_hw *hw,
686 struct ice_aqc_get_cee_dcb_cfg_resp *buff,
687 struct ice_sq_cd *cd)
688{
689 struct ice_aq_desc desc;
690
691 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_cee_dcb_cfg);
692
693 return ice_aq_send_cmd(hw, &desc, (void *)buff, sizeof(*buff), cd);
694}
695
696/**
697 * ice_cee_to_dcb_cfg
698 * @cee_cfg: pointer to CEE configuration struct
699 * @dcbcfg: DCB configuration struct
700 *
701 * Convert CEE configuration from firmware to DCB configuration
702 */
703static void
704ice_cee_to_dcb_cfg(struct ice_aqc_get_cee_dcb_cfg_resp *cee_cfg,
705 struct ice_dcbx_cfg *dcbcfg)
706{
707 u32 status, tlv_status = le32_to_cpu(cee_cfg->tlv_status);
708 u32 ice_aqc_cee_status_mask, ice_aqc_cee_status_shift;
709 u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio);
710 u8 i, err, sync, oper, app_index, ice_app_sel_type;
711 u16 ice_aqc_cee_app_mask, ice_aqc_cee_app_shift;
712 u16 ice_app_prot_id_type;
713
714 /* CEE PG data to ETS config */
715 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
716
717 /* Note that the FW creates the oper_prio_tc nibbles reversed
718 * from those in the CEE Priority Group sub-TLV.
719 */
720 for (i = 0; i < ICE_MAX_TRAFFIC_CLASS / 2; i++) {
721 dcbcfg->etscfg.prio_table[i * 2] =
722 ((cee_cfg->oper_prio_tc[i] & ICE_CEE_PGID_PRIO_0_M) >>
723 ICE_CEE_PGID_PRIO_0_S);
724 dcbcfg->etscfg.prio_table[i * 2 + 1] =
725 ((cee_cfg->oper_prio_tc[i] & ICE_CEE_PGID_PRIO_1_M) >>
726 ICE_CEE_PGID_PRIO_1_S);
727 }
728
729 ice_for_each_traffic_class(i) {
730 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
731
732 if (dcbcfg->etscfg.prio_table[i] == ICE_CEE_PGID_STRICT) {
733 /* Map it to next empty TC */
734 dcbcfg->etscfg.prio_table[i] = cee_cfg->oper_num_tc - 1;
735 dcbcfg->etscfg.tsatable[i] = ICE_IEEE_TSA_STRICT;
736 } else {
737 dcbcfg->etscfg.tsatable[i] = ICE_IEEE_TSA_ETS;
738 }
739 }
740
741 /* CEE PFC data to ETS config */
742 dcbcfg->pfc.pfcena = cee_cfg->oper_pfc_en;
743 dcbcfg->pfc.pfccap = ICE_MAX_TRAFFIC_CLASS;
744
745 app_index = 0;
746 for (i = 0; i < 3; i++) {
747 if (i == 0) {
748 /* FCoE APP */
749 ice_aqc_cee_status_mask = ICE_AQC_CEE_FCOE_STATUS_M;
750 ice_aqc_cee_status_shift = ICE_AQC_CEE_FCOE_STATUS_S;
751 ice_aqc_cee_app_mask = ICE_AQC_CEE_APP_FCOE_M;
752 ice_aqc_cee_app_shift = ICE_AQC_CEE_APP_FCOE_S;
753 ice_app_sel_type = ICE_APP_SEL_ETHTYPE;
754 ice_app_prot_id_type = ICE_APP_PROT_ID_FCOE;
755 } else if (i == 1) {
756 /* iSCSI APP */
757 ice_aqc_cee_status_mask = ICE_AQC_CEE_ISCSI_STATUS_M;
758 ice_aqc_cee_status_shift = ICE_AQC_CEE_ISCSI_STATUS_S;
759 ice_aqc_cee_app_mask = ICE_AQC_CEE_APP_ISCSI_M;
760 ice_aqc_cee_app_shift = ICE_AQC_CEE_APP_ISCSI_S;
761 ice_app_sel_type = ICE_APP_SEL_TCPIP;
762 ice_app_prot_id_type = ICE_APP_PROT_ID_ISCSI;
763 } else {
764 /* FIP APP */
765 ice_aqc_cee_status_mask = ICE_AQC_CEE_FIP_STATUS_M;
766 ice_aqc_cee_status_shift = ICE_AQC_CEE_FIP_STATUS_S;
767 ice_aqc_cee_app_mask = ICE_AQC_CEE_APP_FIP_M;
768 ice_aqc_cee_app_shift = ICE_AQC_CEE_APP_FIP_S;
769 ice_app_sel_type = ICE_APP_SEL_ETHTYPE;
770 ice_app_prot_id_type = ICE_APP_PROT_ID_FIP;
771 }
772
773 status = (tlv_status & ice_aqc_cee_status_mask) >>
774 ice_aqc_cee_status_shift;
775 err = (status & ICE_TLV_STATUS_ERR) ? 1 : 0;
776 sync = (status & ICE_TLV_STATUS_SYNC) ? 1 : 0;
777 oper = (status & ICE_TLV_STATUS_OPER) ? 1 : 0;
778 /* Add FCoE/iSCSI/FIP APP if Error is False and
779 * Oper/Sync is True
780 */
781 if (!err && sync && oper) {
782 dcbcfg->app[app_index].priority =
783 (app_prio & ice_aqc_cee_app_mask) >>
784 ice_aqc_cee_app_shift;
785 dcbcfg->app[app_index].selector = ice_app_sel_type;
786 dcbcfg->app[app_index].prot_id = ice_app_prot_id_type;
787 app_index++;
788 }
789 }
790
791 dcbcfg->numapps = app_index;
792}
793
794/**
795 * ice_get_ieee_dcb_cfg
796 * @pi: port information structure
797 * @dcbx_mode: mode of DCBX (IEEE or CEE)
798 *
799 * Get IEEE or CEE mode DCB configuration from the Firmware
800 */
801static enum ice_status
802ice_get_ieee_or_cee_dcb_cfg(struct ice_port_info *pi, u8 dcbx_mode)
803{
804 struct ice_dcbx_cfg *dcbx_cfg = NULL;
805 enum ice_status ret;
806
807 if (!pi)
808 return ICE_ERR_PARAM;
809
810 if (dcbx_mode == ICE_DCBX_MODE_IEEE)
811 dcbx_cfg = &pi->local_dcbx_cfg;
812 else if (dcbx_mode == ICE_DCBX_MODE_CEE)
813 dcbx_cfg = &pi->desired_dcbx_cfg;
814
815 /* Get Local DCB Config in case of ICE_DCBX_MODE_IEEE
816 * or get CEE DCB Desired Config in case of ICE_DCBX_MODE_CEE
817 */
818 ret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_LOCAL,
819 ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID, dcbx_cfg);
820 if (ret)
821 goto out;
822
823 /* Get Remote DCB Config */
824 dcbx_cfg = &pi->remote_dcbx_cfg;
825 ret = ice_aq_get_dcb_cfg(pi->hw, ICE_AQ_LLDP_MIB_REMOTE,
826 ICE_AQ_LLDP_BRID_TYPE_NEAREST_BRID, dcbx_cfg);
827 /* Don't treat ENOENT as an error for Remote MIBs */
828 if (pi->hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT)
829 ret = 0;
830
831out:
832 return ret;
833}
834
835/**
836 * ice_get_dcb_cfg
837 * @pi: port information structure
838 *
839 * Get DCB configuration from the Firmware
840 */
841static enum ice_status ice_get_dcb_cfg(struct ice_port_info *pi)
842{
843 struct ice_aqc_get_cee_dcb_cfg_resp cee_cfg;
844 struct ice_dcbx_cfg *dcbx_cfg;
845 enum ice_status ret;
846
847 if (!pi)
848 return ICE_ERR_PARAM;
849
850 ret = ice_aq_get_cee_dcb_cfg(pi->hw, &cee_cfg, NULL);
851 if (!ret) {
852 /* CEE mode */
853 dcbx_cfg = &pi->local_dcbx_cfg;
854 dcbx_cfg->dcbx_mode = ICE_DCBX_MODE_CEE;
855 dcbx_cfg->tlv_status = le32_to_cpu(cee_cfg.tlv_status);
856 ice_cee_to_dcb_cfg(&cee_cfg, dcbx_cfg);
857 ret = ice_get_ieee_or_cee_dcb_cfg(pi, ICE_DCBX_MODE_CEE);
858 } else if (pi->hw->adminq.sq_last_status == ICE_AQ_RC_ENOENT) {
859 /* CEE mode not enabled try querying IEEE data */
860 dcbx_cfg = &pi->local_dcbx_cfg;
861 dcbx_cfg->dcbx_mode = ICE_DCBX_MODE_IEEE;
862 ret = ice_get_ieee_or_cee_dcb_cfg(pi, ICE_DCBX_MODE_IEEE);
863 }
864
865 return ret;
866}
867
868/**
869 * ice_init_dcb
870 * @hw: pointer to the HW struct
871 *
872 * Update DCB configuration from the Firmware
873 */
874enum ice_status ice_init_dcb(struct ice_hw *hw)
875{
876 struct ice_port_info *pi = hw->port_info;
877 enum ice_status ret = 0;
878
879 if (!hw->func_caps.common_cap.dcb)
880 return ICE_ERR_NOT_SUPPORTED;
881
882 pi->is_sw_lldp = true;
883
884 /* Get DCBX status */
885 pi->dcbx_status = ice_get_dcbx_status(hw);
886
887 if (pi->dcbx_status == ICE_DCBX_STATUS_DONE ||
888 pi->dcbx_status == ICE_DCBX_STATUS_IN_PROGRESS) {
889 /* Get current DCBX configuration */
890 ret = ice_get_dcb_cfg(pi);
891 pi->is_sw_lldp = (hw->adminq.sq_last_status == ICE_AQ_RC_EPERM);
892 if (ret)
893 return ret;
894 } else if (pi->dcbx_status == ICE_DCBX_STATUS_DIS) {
895 return ICE_ERR_NOT_READY;
896 }
897
898 /* Configure the LLDP MIB change event */
899 ret = ice_aq_cfg_lldp_mib_change(hw, true, NULL);
900 if (!ret)
901 pi->is_sw_lldp = false;
902
903 return ret;
904}
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb.h b/drivers/net/ethernet/intel/ice/ice_dcb.h
index 071d205c983c..c2c2692990e8 100644
--- a/drivers/net/ethernet/intel/ice/ice_dcb.h
+++ b/drivers/net/ethernet/intel/ice/ice_dcb.h
@@ -8,8 +8,107 @@
8 8
9#define ICE_DCBX_STATUS_IN_PROGRESS 1 9#define ICE_DCBX_STATUS_IN_PROGRESS 1
10#define ICE_DCBX_STATUS_DONE 2 10#define ICE_DCBX_STATUS_DONE 2
11#define ICE_DCBX_STATUS_DIS 7
12
13#define ICE_TLV_TYPE_END 0
14#define ICE_TLV_TYPE_ORG 127
15
16#define ICE_IEEE_8021QAZ_OUI 0x0080C2
17#define ICE_IEEE_SUBTYPE_ETS_CFG 9
18#define ICE_IEEE_SUBTYPE_ETS_REC 10
19#define ICE_IEEE_SUBTYPE_PFC_CFG 11
20#define ICE_IEEE_SUBTYPE_APP_PRI 12
21
22#define ICE_CEE_DCBX_OUI 0x001B21
23#define ICE_CEE_DCBX_TYPE 2
24#define ICE_CEE_SUBTYPE_PG_CFG 2
25#define ICE_CEE_SUBTYPE_PFC_CFG 3
26#define ICE_CEE_SUBTYPE_APP_PRI 4
27#define ICE_CEE_MAX_FEAT_TYPE 3
28/* Defines for LLDP TLV header */
29#define ICE_LLDP_TLV_LEN_S 0
30#define ICE_LLDP_TLV_LEN_M (0x01FF << ICE_LLDP_TLV_LEN_S)
31#define ICE_LLDP_TLV_TYPE_S 9
32#define ICE_LLDP_TLV_TYPE_M (0x7F << ICE_LLDP_TLV_TYPE_S)
33#define ICE_LLDP_TLV_SUBTYPE_S 0
34#define ICE_LLDP_TLV_SUBTYPE_M (0xFF << ICE_LLDP_TLV_SUBTYPE_S)
35#define ICE_LLDP_TLV_OUI_S 8
36#define ICE_LLDP_TLV_OUI_M (0xFFFFFFUL << ICE_LLDP_TLV_OUI_S)
37
38/* Defines for IEEE ETS TLV */
39#define ICE_IEEE_ETS_MAXTC_S 0
40#define ICE_IEEE_ETS_MAXTC_M (0x7 << ICE_IEEE_ETS_MAXTC_S)
41#define ICE_IEEE_ETS_CBS_S 6
42#define ICE_IEEE_ETS_CBS_M BIT(ICE_IEEE_ETS_CBS_S)
43#define ICE_IEEE_ETS_WILLING_S 7
44#define ICE_IEEE_ETS_WILLING_M BIT(ICE_IEEE_ETS_WILLING_S)
45#define ICE_IEEE_ETS_PRIO_0_S 0
46#define ICE_IEEE_ETS_PRIO_0_M (0x7 << ICE_IEEE_ETS_PRIO_0_S)
47#define ICE_IEEE_ETS_PRIO_1_S 4
48#define ICE_IEEE_ETS_PRIO_1_M (0x7 << ICE_IEEE_ETS_PRIO_1_S)
49#define ICE_CEE_PGID_PRIO_0_S 0
50#define ICE_CEE_PGID_PRIO_0_M (0xF << ICE_CEE_PGID_PRIO_0_S)
51#define ICE_CEE_PGID_PRIO_1_S 4
52#define ICE_CEE_PGID_PRIO_1_M (0xF << ICE_CEE_PGID_PRIO_1_S)
53#define ICE_CEE_PGID_STRICT 15
54
55/* Defines for IEEE TSA types */
56#define ICE_IEEE_TSA_STRICT 0
57#define ICE_IEEE_TSA_ETS 2
58
59/* Defines for IEEE PFC TLV */
60#define ICE_IEEE_PFC_CAP_S 0
61#define ICE_IEEE_PFC_CAP_M (0xF << ICE_IEEE_PFC_CAP_S)
62#define ICE_IEEE_PFC_MBC_S 6
63#define ICE_IEEE_PFC_MBC_M BIT(ICE_IEEE_PFC_MBC_S)
64#define ICE_IEEE_PFC_WILLING_S 7
65#define ICE_IEEE_PFC_WILLING_M BIT(ICE_IEEE_PFC_WILLING_S)
66
67/* Defines for IEEE APP TLV */
68#define ICE_IEEE_APP_SEL_S 0
69#define ICE_IEEE_APP_SEL_M (0x7 << ICE_IEEE_APP_SEL_S)
70#define ICE_IEEE_APP_PRIO_S 5
71#define ICE_IEEE_APP_PRIO_M (0x7 << ICE_IEEE_APP_PRIO_S)
72
73/* IEEE 802.1AB LLDP Organization specific TLV */
74struct ice_lldp_org_tlv {
75 __be16 typelen;
76 __be32 ouisubtype;
77 u8 tlvinfo[1];
78} __packed;
79
80struct ice_cee_tlv_hdr {
81 __be16 typelen;
82 u8 operver;
83 u8 maxver;
84};
85
86struct ice_cee_ctrl_tlv {
87 struct ice_cee_tlv_hdr hdr;
88 __be32 seqno;
89 __be32 ackno;
90};
91
92struct ice_cee_feat_tlv {
93 struct ice_cee_tlv_hdr hdr;
94 u8 en_will_err; /* Bits: |En|Will|Err|Reserved(5)| */
95#define ICE_CEE_FEAT_TLV_ENA_M 0x80
96#define ICE_CEE_FEAT_TLV_WILLING_M 0x40
97#define ICE_CEE_FEAT_TLV_ERR_M 0x20
98 u8 subtype;
99 u8 tlvinfo[1];
100};
101
102struct ice_cee_app_prio {
103 __be16 protocol;
104 u8 upper_oui_sel; /* Bits: |Upper OUI(6)|Selector(2)| */
105#define ICE_CEE_APP_SELECTOR_M 0x03
106 __be16 lower_oui;
107 u8 prio_map;
108} __packed;
11 109
12u8 ice_get_dcbx_status(struct ice_hw *hw); 110u8 ice_get_dcbx_status(struct ice_hw *hw);
111enum ice_status ice_init_dcb(struct ice_hw *hw);
13#ifdef CONFIG_DCB 112#ifdef CONFIG_DCB
14enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd); 113enum ice_status ice_aq_start_lldp(struct ice_hw *hw, struct ice_sq_cd *cd);
15enum ice_status 114enum ice_status
diff --git a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
index 8ce358fbe9fb..f2dd41408652 100644
--- a/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
+++ b/drivers/net/ethernet/intel/ice/ice_dcb_lib.c
@@ -38,5 +38,5 @@ int ice_init_pf_dcb(struct ice_pf *pf)
38 ice_aq_start_stop_dcbx(hw, true, &dcbx_status, NULL); 38 ice_aq_start_stop_dcbx(hw, true, &dcbx_status, NULL);
39 } 39 }
40 40
41 return 0; 41 return ice_init_dcb(hw);
42} 42}
diff --git a/drivers/net/ethernet/intel/ice/ice_status.h b/drivers/net/ethernet/intel/ice/ice_status.h
index 683f48824a29..17afe6acb18a 100644
--- a/drivers/net/ethernet/intel/ice/ice_status.h
+++ b/drivers/net/ethernet/intel/ice/ice_status.h
@@ -12,6 +12,7 @@ enum ice_status {
12 ICE_ERR_PARAM = -1, 12 ICE_ERR_PARAM = -1,
13 ICE_ERR_NOT_IMPL = -2, 13 ICE_ERR_NOT_IMPL = -2,
14 ICE_ERR_NOT_READY = -3, 14 ICE_ERR_NOT_READY = -3,
15 ICE_ERR_NOT_SUPPORTED = -4,
15 ICE_ERR_BAD_PTR = -5, 16 ICE_ERR_BAD_PTR = -5,
16 ICE_ERR_INVAL_SIZE = -6, 17 ICE_ERR_INVAL_SIZE = -6,
17 ICE_ERR_DEVICE_NOT_SUPPORTED = -8, 18 ICE_ERR_DEVICE_NOT_SUPPORTED = -8,
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
index e21ea271b48e..d276e9a952db 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -262,6 +262,59 @@ struct ice_sched_tx_policy {
262 u8 rdma_ena; 262 u8 rdma_ena;
263}; 263};
264 264
265/* CEE or IEEE 802.1Qaz ETS Configuration data */
266struct ice_dcb_ets_cfg {
267 u8 willing;
268 u8 cbs;
269 u8 maxtcs;
270 u8 prio_table[ICE_MAX_TRAFFIC_CLASS];
271 u8 tcbwtable[ICE_MAX_TRAFFIC_CLASS];
272 u8 tsatable[ICE_MAX_TRAFFIC_CLASS];
273};
274
275/* CEE or IEEE 802.1Qaz PFC Configuration data */
276struct ice_dcb_pfc_cfg {
277 u8 willing;
278 u8 mbc;
279 u8 pfccap;
280 u8 pfcena;
281};
282
283/* CEE or IEEE 802.1Qaz Application Priority data */
284struct ice_dcb_app_priority_table {
285 u16 prot_id;
286 u8 priority;
287 u8 selector;
288};
289
290#define ICE_MAX_USER_PRIORITY 8
291#define ICE_DCBX_MAX_APPS 32
292#define ICE_LLDPDU_SIZE 1500
293#define ICE_TLV_STATUS_OPER 0x1
294#define ICE_TLV_STATUS_SYNC 0x2
295#define ICE_TLV_STATUS_ERR 0x4
296#define ICE_APP_PROT_ID_FCOE 0x8906
297#define ICE_APP_PROT_ID_ISCSI 0x0cbc
298#define ICE_APP_PROT_ID_FIP 0x8914
299#define ICE_APP_SEL_ETHTYPE 0x1
300#define ICE_APP_SEL_TCPIP 0x2
301#define ICE_CEE_APP_SEL_ETHTYPE 0x0
302#define ICE_CEE_APP_SEL_TCPIP 0x1
303
304struct ice_dcbx_cfg {
305 u32 numapps;
306 u32 tlv_status; /* CEE mode TLV status */
307 struct ice_dcb_ets_cfg etscfg;
308 struct ice_dcb_ets_cfg etsrec;
309 struct ice_dcb_pfc_cfg pfc;
310 struct ice_dcb_app_priority_table app[ICE_DCBX_MAX_APPS];
311 u8 dcbx_mode;
312#define ICE_DCBX_MODE_CEE 0x1
313#define ICE_DCBX_MODE_IEEE 0x2
314 u8 app_mode;
315#define ICE_DCBX_APPS_NON_WILLING 0x1
316};
317
265struct ice_port_info { 318struct ice_port_info {
266 struct ice_sched_node *root; /* Root Node per Port */ 319 struct ice_sched_node *root; /* Root Node per Port */
267 struct ice_hw *hw; /* back pointer to HW instance */ 320 struct ice_hw *hw; /* back pointer to HW instance */
@@ -279,8 +332,13 @@ struct ice_port_info {
279 struct ice_mac_info mac; 332 struct ice_mac_info mac;
280 struct ice_phy_info phy; 333 struct ice_phy_info phy;
281 struct mutex sched_lock; /* protect access to TXSched tree */ 334 struct mutex sched_lock; /* protect access to TXSched tree */
335 struct ice_dcbx_cfg local_dcbx_cfg; /* Oper/Local Cfg */
336 /* DCBX info */
337 struct ice_dcbx_cfg remote_dcbx_cfg; /* Peer Cfg */
338 struct ice_dcbx_cfg desired_dcbx_cfg; /* CEE Desired Cfg */
282 /* LLDP/DCBX Status */ 339 /* LLDP/DCBX Status */
283 u8 dcbx_status; 340 u8 dcbx_status;
341 u8 is_sw_lldp;
284 u8 lport; 342 u8 lport;
285#define ICE_LPORT_MASK 0xff 343#define ICE_LPORT_MASK 0xff
286 u8 is_vf; 344 u8 is_vf;