1 /*******************************************************************************
3 Copyright (c) 2013 - 2015, Intel Corporation
6 Redistribution and use in source and binary forms, with or without
7 modification, are permitted provided that the following conditions are met:
9 1. Redistributions of source code must retain the above copyright notice,
10 this list of conditions and the following disclaimer.
12 2. Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in the
14 documentation and/or other materials provided with the distribution.
16 3. Neither the name of the Intel Corporation nor the names of its
17 contributors may be used to endorse or promote products derived from
18 this software without specific prior written permission.
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 POSSIBILITY OF SUCH DAMAGE.
32 ***************************************************************************/
34 #include "i40e_adminq.h"
35 #include "i40e_prototype.h"
39 * i40e_get_dcbx_status
40 * @hw: pointer to the hw struct
41 * @status: Embedded DCBX Engine Status
43 * Get the DCBX status from the Firmware
45 enum i40e_status_code i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status)
50 return I40E_ERR_PARAM;
52 reg = rd32(hw, I40E_PRTDCB_GENS);
53 *status = (u16)((reg & I40E_PRTDCB_GENS_DCBX_STATUS_MASK) >>
54 I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT);
60 * i40e_parse_ieee_etscfg_tlv
61 * @tlv: IEEE 802.1Qaz ETS CFG TLV
62 * @dcbcfg: Local store to update ETS CFG data
64 * Parses IEEE 802.1Qaz ETS CFG TLV
66 static void i40e_parse_ieee_etscfg_tlv(struct i40e_lldp_org_tlv *tlv,
67 struct i40e_dcbx_config *dcbcfg)
69 struct i40e_dcb_ets_config *etscfg;
70 u8 *buf = tlv->tlvinfo;
75 /* First Octet post subtype
76 * --------------------------
77 * |will-|CBS | Re- | Max |
78 * |ing | |served| TCs |
79 * --------------------------
80 * |1bit | 1bit|3 bits|3bits|
82 etscfg = &dcbcfg->etscfg;
83 etscfg->willing = (u8)((buf[offset] & I40E_IEEE_ETS_WILLING_MASK) >>
84 I40E_IEEE_ETS_WILLING_SHIFT);
85 etscfg->cbs = (u8)((buf[offset] & I40E_IEEE_ETS_CBS_MASK) >>
86 I40E_IEEE_ETS_CBS_SHIFT);
87 etscfg->maxtcs = (u8)((buf[offset] & I40E_IEEE_ETS_MAXTC_MASK) >>
88 I40E_IEEE_ETS_MAXTC_SHIFT);
90 /* Move offset to Priority Assignment Table */
93 /* Priority Assignment Table (4 octets)
94 * Octets:| 1 | 2 | 3 | 4 |
95 * -----------------------------------------
96 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
97 * -----------------------------------------
98 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
99 * -----------------------------------------
101 for (i = 0; i < 4; i++) {
102 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
103 I40E_IEEE_ETS_PRIO_1_SHIFT);
104 etscfg->prioritytable[i * 2] = priority;
105 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
106 I40E_IEEE_ETS_PRIO_0_SHIFT);
107 etscfg->prioritytable[i * 2 + 1] = priority;
111 /* TC Bandwidth Table (8 octets)
112 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
113 * ---------------------------------
114 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
115 * ---------------------------------
117 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
118 etscfg->tcbwtable[i] = buf[offset++];
120 /* TSA Assignment Table (8 octets)
121 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
122 * ---------------------------------
123 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
124 * ---------------------------------
126 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
127 etscfg->tsatable[i] = buf[offset++];
131 * i40e_parse_ieee_etsrec_tlv
132 * @tlv: IEEE 802.1Qaz ETS REC TLV
133 * @dcbcfg: Local store to update ETS REC data
135 * Parses IEEE 802.1Qaz ETS REC TLV
137 static void i40e_parse_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
138 struct i40e_dcbx_config *dcbcfg)
140 u8 *buf = tlv->tlvinfo;
145 /* Move offset to priority table */
148 /* Priority Assignment Table (4 octets)
149 * Octets:| 1 | 2 | 3 | 4 |
150 * -----------------------------------------
151 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
152 * -----------------------------------------
153 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
154 * -----------------------------------------
156 for (i = 0; i < 4; i++) {
157 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
158 I40E_IEEE_ETS_PRIO_1_SHIFT);
159 dcbcfg->etsrec.prioritytable[i*2] = priority;
160 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
161 I40E_IEEE_ETS_PRIO_0_SHIFT);
162 dcbcfg->etsrec.prioritytable[i*2 + 1] = priority;
166 /* TC Bandwidth Table (8 octets)
167 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
168 * ---------------------------------
169 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
170 * ---------------------------------
172 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
173 dcbcfg->etsrec.tcbwtable[i] = buf[offset++];
175 /* TSA Assignment Table (8 octets)
176 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
177 * ---------------------------------
178 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
179 * ---------------------------------
181 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
182 dcbcfg->etsrec.tsatable[i] = buf[offset++];
186 * i40e_parse_ieee_pfccfg_tlv
187 * @tlv: IEEE 802.1Qaz PFC CFG TLV
188 * @dcbcfg: Local store to update PFC CFG data
190 * Parses IEEE 802.1Qaz PFC CFG TLV
192 static void i40e_parse_ieee_pfccfg_tlv(struct i40e_lldp_org_tlv *tlv,
193 struct i40e_dcbx_config *dcbcfg)
195 u8 *buf = tlv->tlvinfo;
197 /* ----------------------------------------
198 * |will-|MBC | Re- | PFC | PFC Enable |
199 * |ing | |served| cap | |
200 * -----------------------------------------
201 * |1bit | 1bit|2 bits|4bits| 1 octet |
203 dcbcfg->pfc.willing = (u8)((buf[0] & I40E_IEEE_PFC_WILLING_MASK) >>
204 I40E_IEEE_PFC_WILLING_SHIFT);
205 dcbcfg->pfc.mbc = (u8)((buf[0] & I40E_IEEE_PFC_MBC_MASK) >>
206 I40E_IEEE_PFC_MBC_SHIFT);
207 dcbcfg->pfc.pfccap = (u8)((buf[0] & I40E_IEEE_PFC_CAP_MASK) >>
208 I40E_IEEE_PFC_CAP_SHIFT);
209 dcbcfg->pfc.pfcenable = buf[1];
213 * i40e_parse_ieee_app_tlv
214 * @tlv: IEEE 802.1Qaz APP TLV
215 * @dcbcfg: Local store to update APP PRIO data
217 * Parses IEEE 802.1Qaz APP PRIO TLV
219 static void i40e_parse_ieee_app_tlv(struct i40e_lldp_org_tlv *tlv,
220 struct i40e_dcbx_config *dcbcfg)
228 typelength = I40E_NTOHS(tlv->typelength);
229 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
230 I40E_LLDP_TLV_LEN_SHIFT);
233 /* The App priority table starts 5 octets after TLV header */
234 length -= (sizeof(tlv->ouisubtype) + 1);
236 /* Move offset to App Priority Table */
239 /* Application Priority Table (3 octets)
240 * Octets:| 1 | 2 | 3 |
241 * -----------------------------------------
242 * |Priority|Rsrvd| Sel | Protocol ID |
243 * -----------------------------------------
244 * Bits:|23 21|20 19|18 16|15 0|
245 * -----------------------------------------
247 while (offset < length) {
248 dcbcfg->app[i].priority = (u8)((buf[offset] &
249 I40E_IEEE_APP_PRIO_MASK) >>
250 I40E_IEEE_APP_PRIO_SHIFT);
251 dcbcfg->app[i].selector = (u8)((buf[offset] &
252 I40E_IEEE_APP_SEL_MASK) >>
253 I40E_IEEE_APP_SEL_SHIFT);
254 dcbcfg->app[i].protocolid = (buf[offset + 1] << 0x8) |
256 /* Move to next app */
259 if (i >= I40E_DCBX_MAX_APPS)
267 * i40e_parse_ieee_etsrec_tlv
268 * @tlv: IEEE 802.1Qaz TLV
269 * @dcbcfg: Local store to update ETS REC data
271 * Get the TLV subtype and send it to parsing function
272 * based on the subtype value
274 static void i40e_parse_ieee_tlv(struct i40e_lldp_org_tlv *tlv,
275 struct i40e_dcbx_config *dcbcfg)
280 ouisubtype = I40E_NTOHL(tlv->ouisubtype);
281 subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
282 I40E_LLDP_TLV_SUBTYPE_SHIFT);
284 case I40E_IEEE_SUBTYPE_ETS_CFG:
285 i40e_parse_ieee_etscfg_tlv(tlv, dcbcfg);
287 case I40E_IEEE_SUBTYPE_ETS_REC:
288 i40e_parse_ieee_etsrec_tlv(tlv, dcbcfg);
290 case I40E_IEEE_SUBTYPE_PFC_CFG:
291 i40e_parse_ieee_pfccfg_tlv(tlv, dcbcfg);
293 case I40E_IEEE_SUBTYPE_APP_PRI:
294 i40e_parse_ieee_app_tlv(tlv, dcbcfg);
303 * @tlv: Organization specific TLV
304 * @dcbcfg: Local store to update ETS REC data
306 * Currently only IEEE 802.1Qaz TLV is supported, all others
309 static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
310 struct i40e_dcbx_config *dcbcfg)
315 ouisubtype = I40E_NTOHL(tlv->ouisubtype);
316 oui = (u32)((ouisubtype & I40E_LLDP_TLV_OUI_MASK) >>
317 I40E_LLDP_TLV_OUI_SHIFT);
319 case I40E_IEEE_8021QAZ_OUI:
320 i40e_parse_ieee_tlv(tlv, dcbcfg);
328 * i40e_lldp_to_dcb_config
329 * @lldpmib: LLDPDU to be parsed
330 * @dcbcfg: store for LLDPDU data
332 * Parse DCB configuration from the LLDPDU
334 enum i40e_status_code i40e_lldp_to_dcb_config(u8 *lldpmib,
335 struct i40e_dcbx_config *dcbcfg)
337 enum i40e_status_code ret = I40E_SUCCESS;
338 struct i40e_lldp_org_tlv *tlv;
344 if (!lldpmib || !dcbcfg)
345 return I40E_ERR_PARAM;
347 /* set to the start of LLDPDU */
348 lldpmib += I40E_LLDP_MIB_HLEN;
349 tlv = (struct i40e_lldp_org_tlv *)lldpmib;
351 typelength = I40E_NTOHS(tlv->typelength);
352 type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
353 I40E_LLDP_TLV_TYPE_SHIFT);
354 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
355 I40E_LLDP_TLV_LEN_SHIFT);
356 offset += sizeof(typelength) + length;
358 /* END TLV or beyond LLDPDU size */
359 if ((type == I40E_TLV_TYPE_END) || (offset > I40E_LLDPDU_SIZE))
363 case I40E_TLV_TYPE_ORG:
364 i40e_parse_org_tlv(tlv, dcbcfg);
370 /* Move to next TLV */
371 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
372 sizeof(tlv->typelength) +
380 * i40e_aq_get_dcb_config
381 * @hw: pointer to the hw struct
382 * @mib_type: mib type for the query
383 * @bridgetype: bridge type for the query (remote)
384 * @dcbcfg: store for LLDPDU data
386 * Query DCB configuration from the Firmware
388 enum i40e_status_code i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
390 struct i40e_dcbx_config *dcbcfg)
392 enum i40e_status_code ret = I40E_SUCCESS;
393 struct i40e_virt_mem mem;
396 /* Allocate the LLDPDU */
397 ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
401 lldpmib = (u8 *)mem.va;
402 ret = i40e_aq_get_lldp_mib(hw, bridgetype, mib_type,
403 (void *)lldpmib, I40E_LLDPDU_SIZE,
408 /* Parse LLDP MIB to get dcb configuration */
409 ret = i40e_lldp_to_dcb_config(lldpmib, dcbcfg);
412 i40e_free_virt_mem(hw, &mem);
417 * i40e_cee_to_dcb_v1_config
418 * @cee_cfg: pointer to CEE v1 response configuration struct
419 * @dcbcfg: DCB configuration struct
421 * Convert CEE v1 configuration from firmware to DCB configuration
423 static void i40e_cee_to_dcb_v1_config(
424 struct i40e_aqc_get_cee_dcb_cfg_v1_resp *cee_cfg,
425 struct i40e_dcbx_config *dcbcfg)
427 u16 status, tlv_status = LE16_TO_CPU(cee_cfg->tlv_status);
428 u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
429 u8 i, tc, err, sync, oper;
431 /* CEE PG data to ETS config */
432 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
434 /* Note that the FW creates the oper_prio_tc nibbles reversed
435 * from those in the CEE Priority Group sub-TLV.
437 for (i = 0; i < 4; i++) {
438 tc = (u8)((cee_cfg->oper_prio_tc[i] &
439 I40E_CEE_PGID_PRIO_0_MASK) >>
440 I40E_CEE_PGID_PRIO_0_SHIFT);
441 dcbcfg->etscfg.prioritytable[i*2] = tc;
442 tc = (u8)((cee_cfg->oper_prio_tc[i] &
443 I40E_CEE_PGID_PRIO_1_MASK) >>
444 I40E_CEE_PGID_PRIO_1_SHIFT);
445 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
448 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
449 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
451 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
452 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
453 /* Map it to next empty TC */
454 dcbcfg->etscfg.prioritytable[i] =
455 cee_cfg->oper_num_tc - 1;
456 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
458 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
462 /* CEE PFC data to ETS config */
463 dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
464 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
466 status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
467 I40E_AQC_CEE_APP_STATUS_SHIFT;
468 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
469 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
470 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
471 /* Add APPs if Error is False and Oper/Sync is True */
473 /* CEE operating configuration supports FCoE/iSCSI/FIP only */
474 dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
477 dcbcfg->app[0].priority =
478 (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
479 I40E_AQC_CEE_APP_FCOE_SHIFT;
480 dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
481 dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
484 dcbcfg->app[1].priority =
485 (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
486 I40E_AQC_CEE_APP_ISCSI_SHIFT;
487 dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
488 dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
491 dcbcfg->app[2].priority =
492 (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
493 I40E_AQC_CEE_APP_FIP_SHIFT;
494 dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
495 dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
500 * i40e_cee_to_dcb_config
501 * @cee_cfg: pointer to CEE configuration struct
502 * @dcbcfg: DCB configuration struct
504 * Convert CEE configuration from firmware to DCB configuration
506 static void i40e_cee_to_dcb_config(
507 struct i40e_aqc_get_cee_dcb_cfg_resp *cee_cfg,
508 struct i40e_dcbx_config *dcbcfg)
510 u32 status, tlv_status = LE32_TO_CPU(cee_cfg->tlv_status);
511 u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
512 u8 i, tc, err, sync, oper;
514 /* CEE PG data to ETS config */
515 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
517 for (i = 0; i < 4; i++) {
518 tc = (u8)((cee_cfg->oper_prio_tc[i] &
519 I40E_CEE_PGID_PRIO_1_MASK) >>
520 I40E_CEE_PGID_PRIO_1_SHIFT);
521 dcbcfg->etscfg.prioritytable[i*2] = tc;
522 tc = (u8)((cee_cfg->oper_prio_tc[i] &
523 I40E_CEE_PGID_PRIO_0_MASK) >>
524 I40E_CEE_PGID_PRIO_0_SHIFT);
525 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
528 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
529 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
531 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
532 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
533 /* Map it to next empty TC */
534 dcbcfg->etscfg.prioritytable[i] =
535 cee_cfg->oper_num_tc - 1;
536 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
538 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
542 /* CEE PFC data to ETS config */
543 dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
544 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
546 status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
547 I40E_AQC_CEE_APP_STATUS_SHIFT;
548 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
549 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
550 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
551 /* Add APPs if Error is False and Oper/Sync is True */
552 if (!err && sync && oper) {
553 /* CEE operating configuration supports FCoE/iSCSI/FIP only */
554 dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
557 dcbcfg->app[0].priority =
558 (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
559 I40E_AQC_CEE_APP_FCOE_SHIFT;
560 dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
561 dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
564 dcbcfg->app[1].priority =
565 (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
566 I40E_AQC_CEE_APP_ISCSI_SHIFT;
567 dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
568 dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
571 dcbcfg->app[2].priority =
572 (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
573 I40E_AQC_CEE_APP_FIP_SHIFT;
574 dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
575 dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
580 * i40e_get_dcb_config
581 * @hw: pointer to the hw struct
583 * Get DCB configuration from the Firmware
585 enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw)
587 enum i40e_status_code ret = I40E_SUCCESS;
588 struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
589 struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
591 /* If Firmware version < v4.33 IEEE only */
592 if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
593 (hw->aq.fw_maj_ver < 4))
596 /* If Firmware version == v4.33 use old CEE struct */
597 if ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33)) {
598 ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
599 sizeof(cee_v1_cfg), NULL);
600 if (ret == I40E_SUCCESS) {
602 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
603 i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
604 &hw->local_dcbx_config);
607 ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
608 sizeof(cee_cfg), NULL);
609 if (ret == I40E_SUCCESS) {
611 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
612 i40e_cee_to_dcb_config(&cee_cfg,
613 &hw->local_dcbx_config);
617 /* CEE mode not enabled try querying IEEE data */
618 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
625 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
626 /* Get Local DCB Config */
627 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
628 &hw->local_dcbx_config);
632 /* Get Remote DCB Config */
633 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
634 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
635 &hw->remote_dcbx_config);
636 /* Don't treat ENOENT as an error for Remote MIBs */
637 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
646 * @hw: pointer to the hw struct
648 * Update DCB configuration from the Firmware
650 enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw)
652 enum i40e_status_code ret = I40E_SUCCESS;
653 struct i40e_lldp_variables lldp_cfg;
656 if (!hw->func_caps.dcb)
659 /* Read LLDP NVM area */
660 ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
664 /* Get the LLDP AdminStatus for the current port */
665 adminstatus = lldp_cfg.adminstatus >> (hw->port * 4);
668 /* LLDP agent disabled */
670 hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
674 /* Get DCBX status */
675 ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
679 /* Check the DCBX Status */
680 switch (hw->dcbx_status) {
681 case I40E_DCBX_STATUS_DONE:
682 case I40E_DCBX_STATUS_IN_PROGRESS:
683 /* Get current DCBX configuration */
684 ret = i40e_get_dcb_config(hw);
688 case I40E_DCBX_STATUS_DISABLED:
690 case I40E_DCBX_STATUS_NOT_STARTED:
691 case I40E_DCBX_STATUS_MULTIPLE_PEERS:
696 /* Configure the LLDP MIB change event */
697 ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
707 * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
708 * @hw: pointer to the HW structure
709 * @lldp_cfg: pointer to hold lldp configuration variables
711 * Reads the LLDP configuration data from NVM
713 enum i40e_status_code i40e_read_lldp_cfg(struct i40e_hw *hw,
714 struct i40e_lldp_variables *lldp_cfg)
716 enum i40e_status_code ret = I40E_SUCCESS;
717 u32 offset = (2 * I40E_NVM_LLDP_CFG_PTR);
720 return I40E_ERR_PARAM;
722 ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
723 if (ret != I40E_SUCCESS)
726 ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, offset,
727 sizeof(struct i40e_lldp_variables),
730 i40e_release_nvm(hw);