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);
302 * i40e_parse_cee_pgcfg_tlv
303 * @tlv: CEE DCBX PG CFG TLV
304 * @dcbcfg: Local store to update ETS CFG data
306 * Parses CEE DCBX PG CFG TLV
308 static void i40e_parse_cee_pgcfg_tlv(struct i40e_cee_feat_tlv *tlv,
309 struct i40e_dcbx_config *dcbcfg)
311 struct i40e_dcb_ets_config *etscfg;
312 u8 *buf = tlv->tlvinfo;
317 etscfg = &dcbcfg->etscfg;
319 if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
323 /* Priority Group Table (4 octets)
324 * Octets:| 1 | 2 | 3 | 4 |
325 * -----------------------------------------
326 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
327 * -----------------------------------------
328 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
329 * -----------------------------------------
331 for (i = 0; i < 4; i++) {
332 priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_1_MASK) >>
333 I40E_CEE_PGID_PRIO_1_SHIFT);
334 etscfg->prioritytable[i * 2] = priority;
335 priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_0_MASK) >>
336 I40E_CEE_PGID_PRIO_0_SHIFT);
337 etscfg->prioritytable[i * 2 + 1] = priority;
341 /* PG Percentage Table (8 octets)
342 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
343 * ---------------------------------
344 * |pg0|pg1|pg2|pg3|pg4|pg5|pg6|pg7|
345 * ---------------------------------
347 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
348 etscfg->tcbwtable[i] = buf[offset++];
350 /* Number of TCs supported (1 octet) */
351 etscfg->maxtcs = buf[offset];
355 * i40e_parse_cee_pfccfg_tlv
356 * @tlv: CEE DCBX PFC CFG TLV
357 * @dcbcfg: Local store to update PFC CFG data
359 * Parses CEE DCBX PFC CFG TLV
361 static void i40e_parse_cee_pfccfg_tlv(struct i40e_cee_feat_tlv *tlv,
362 struct i40e_dcbx_config *dcbcfg)
364 u8 *buf = tlv->tlvinfo;
366 if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
367 dcbcfg->pfc.willing = 1;
369 /* ------------------------
370 * | PFC Enable | PFC TCs |
371 * ------------------------
372 * | 1 octet | 1 octet |
374 dcbcfg->pfc.pfcenable = buf[0];
375 dcbcfg->pfc.pfccap = buf[1];
379 * i40e_parse_cee_app_tlv
380 * @tlv: CEE DCBX APP TLV
381 * @dcbcfg: Local store to update APP PRIO data
383 * Parses CEE DCBX APP PRIO TLV
385 static void i40e_parse_cee_app_tlv(struct i40e_cee_feat_tlv *tlv,
386 struct i40e_dcbx_config *dcbcfg)
388 u16 length, typelength, offset = 0;
389 struct i40e_cee_app_prio *app;
392 typelength = I40E_NTOHS(tlv->hdr.typelen);
393 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
394 I40E_LLDP_TLV_LEN_SHIFT);
396 dcbcfg->numapps = length/sizeof(*app);
397 if (!dcbcfg->numapps)
400 for (i = 0; i < dcbcfg->numapps; i++) {
401 app = (struct i40e_cee_app_prio *)(tlv->tlvinfo + offset);
402 for (up = 0; up < I40E_MAX_USER_PRIORITY; up++) {
403 if (app->prio_map & BIT(up))
406 dcbcfg->app[i].priority = up;
407 /* Get Selector from lower 2 bits, and convert to IEEE */
408 selector = (app->upper_oui_sel & I40E_CEE_APP_SELECTOR_MASK);
409 if (selector == I40E_CEE_APP_SEL_ETHTYPE)
410 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
411 else if (selector == I40E_CEE_APP_SEL_TCPIP)
412 dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
414 /* Keep selector as it is for unknown types */
415 dcbcfg->app[i].selector = selector;
416 dcbcfg->app[i].protocolid = I40E_NTOHS(app->protocol);
417 /* Move to next app */
418 offset += sizeof(*app);
425 * @dcbcfg: Local store to update DCBX config data
427 * Get the TLV subtype and send it to parsing function
428 * based on the subtype value
430 static void i40e_parse_cee_tlv(struct i40e_lldp_org_tlv *tlv,
431 struct i40e_dcbx_config *dcbcfg)
433 u16 len, tlvlen, sublen, typelength;
434 struct i40e_cee_feat_tlv *sub_tlv;
435 u8 subtype, feat_tlv_count = 0;
438 ouisubtype = I40E_NTOHL(tlv->ouisubtype);
439 subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
440 I40E_LLDP_TLV_SUBTYPE_SHIFT);
441 /* Return if not CEE DCBX */
442 if (subtype != I40E_CEE_DCBX_TYPE)
445 typelength = I40E_NTOHS(tlv->typelength);
446 tlvlen = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
447 I40E_LLDP_TLV_LEN_SHIFT);
448 len = sizeof(tlv->typelength) + sizeof(ouisubtype) +
449 sizeof(struct i40e_cee_ctrl_tlv);
450 /* Return if no CEE DCBX Feature TLVs */
454 sub_tlv = (struct i40e_cee_feat_tlv *)((char *)tlv + len);
455 while (feat_tlv_count < I40E_CEE_MAX_FEAT_TYPE) {
456 typelength = I40E_NTOHS(sub_tlv->hdr.typelen);
457 sublen = (u16)((typelength &
458 I40E_LLDP_TLV_LEN_MASK) >>
459 I40E_LLDP_TLV_LEN_SHIFT);
460 subtype = (u8)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
461 I40E_LLDP_TLV_TYPE_SHIFT);
463 case I40E_CEE_SUBTYPE_PG_CFG:
464 i40e_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);
466 case I40E_CEE_SUBTYPE_PFC_CFG:
467 i40e_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);
469 case I40E_CEE_SUBTYPE_APP_PRI:
470 i40e_parse_cee_app_tlv(sub_tlv, dcbcfg);
473 return; /* Invalid Sub-type return */
476 /* Move to next sub TLV */
477 sub_tlv = (struct i40e_cee_feat_tlv *)((char *)sub_tlv +
478 sizeof(sub_tlv->hdr.typelen) +
485 * @tlv: Organization specific TLV
486 * @dcbcfg: Local store to update ETS REC data
488 * Currently only IEEE 802.1Qaz TLV is supported, all others
491 static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
492 struct i40e_dcbx_config *dcbcfg)
497 ouisubtype = I40E_NTOHL(tlv->ouisubtype);
498 oui = (u32)((ouisubtype & I40E_LLDP_TLV_OUI_MASK) >>
499 I40E_LLDP_TLV_OUI_SHIFT);
501 case I40E_IEEE_8021QAZ_OUI:
502 i40e_parse_ieee_tlv(tlv, dcbcfg);
504 case I40E_CEE_DCBX_OUI:
505 i40e_parse_cee_tlv(tlv, dcbcfg);
513 * i40e_lldp_to_dcb_config
514 * @lldpmib: LLDPDU to be parsed
515 * @dcbcfg: store for LLDPDU data
517 * Parse DCB configuration from the LLDPDU
519 enum i40e_status_code i40e_lldp_to_dcb_config(u8 *lldpmib,
520 struct i40e_dcbx_config *dcbcfg)
522 enum i40e_status_code ret = I40E_SUCCESS;
523 struct i40e_lldp_org_tlv *tlv;
529 if (!lldpmib || !dcbcfg)
530 return I40E_ERR_PARAM;
532 /* set to the start of LLDPDU */
533 lldpmib += I40E_LLDP_MIB_HLEN;
534 tlv = (struct i40e_lldp_org_tlv *)lldpmib;
536 typelength = I40E_NTOHS(tlv->typelength);
537 type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
538 I40E_LLDP_TLV_TYPE_SHIFT);
539 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
540 I40E_LLDP_TLV_LEN_SHIFT);
541 offset += sizeof(typelength) + length;
543 /* END TLV or beyond LLDPDU size */
544 if ((type == I40E_TLV_TYPE_END) || (offset > I40E_LLDPDU_SIZE))
548 case I40E_TLV_TYPE_ORG:
549 i40e_parse_org_tlv(tlv, dcbcfg);
555 /* Move to next TLV */
556 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
557 sizeof(tlv->typelength) +
565 * i40e_aq_get_dcb_config
566 * @hw: pointer to the hw struct
567 * @mib_type: mib type for the query
568 * @bridgetype: bridge type for the query (remote)
569 * @dcbcfg: store for LLDPDU data
571 * Query DCB configuration from the Firmware
573 enum i40e_status_code i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
575 struct i40e_dcbx_config *dcbcfg)
577 enum i40e_status_code ret = I40E_SUCCESS;
578 struct i40e_virt_mem mem;
581 /* Allocate the LLDPDU */
582 ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
586 lldpmib = (u8 *)mem.va;
587 ret = i40e_aq_get_lldp_mib(hw, bridgetype, mib_type,
588 (void *)lldpmib, I40E_LLDPDU_SIZE,
593 /* Parse LLDP MIB to get dcb configuration */
594 ret = i40e_lldp_to_dcb_config(lldpmib, dcbcfg);
597 i40e_free_virt_mem(hw, &mem);
602 * i40e_cee_to_dcb_v1_config
603 * @cee_cfg: pointer to CEE v1 response configuration struct
604 * @dcbcfg: DCB configuration struct
606 * Convert CEE v1 configuration from firmware to DCB configuration
608 static void i40e_cee_to_dcb_v1_config(
609 struct i40e_aqc_get_cee_dcb_cfg_v1_resp *cee_cfg,
610 struct i40e_dcbx_config *dcbcfg)
612 u16 status, tlv_status = LE16_TO_CPU(cee_cfg->tlv_status);
613 u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
616 /* CEE PG data to ETS config */
617 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
619 /* Note that the FW creates the oper_prio_tc nibbles reversed
620 * from those in the CEE Priority Group sub-TLV.
622 for (i = 0; i < 4; i++) {
623 tc = (u8)((cee_cfg->oper_prio_tc[i] &
624 I40E_CEE_PGID_PRIO_0_MASK) >>
625 I40E_CEE_PGID_PRIO_0_SHIFT);
626 dcbcfg->etscfg.prioritytable[i*2] = tc;
627 tc = (u8)((cee_cfg->oper_prio_tc[i] &
628 I40E_CEE_PGID_PRIO_1_MASK) >>
629 I40E_CEE_PGID_PRIO_1_SHIFT);
630 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
633 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
634 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
636 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
637 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
638 /* Map it to next empty TC */
639 dcbcfg->etscfg.prioritytable[i] =
640 cee_cfg->oper_num_tc - 1;
641 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
643 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
647 /* CEE PFC data to ETS config */
648 dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
649 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
651 status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
652 I40E_AQC_CEE_APP_STATUS_SHIFT;
653 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
654 /* Add APPs if Error is False */
656 /* CEE operating configuration supports FCoE/iSCSI/FIP only */
657 dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
660 dcbcfg->app[0].priority =
661 (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
662 I40E_AQC_CEE_APP_FCOE_SHIFT;
663 dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
664 dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
667 dcbcfg->app[1].priority =
668 (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
669 I40E_AQC_CEE_APP_ISCSI_SHIFT;
670 dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
671 dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
674 dcbcfg->app[2].priority =
675 (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
676 I40E_AQC_CEE_APP_FIP_SHIFT;
677 dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
678 dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
683 * i40e_cee_to_dcb_config
684 * @cee_cfg: pointer to CEE configuration struct
685 * @dcbcfg: DCB configuration struct
687 * Convert CEE configuration from firmware to DCB configuration
689 static void i40e_cee_to_dcb_config(
690 struct i40e_aqc_get_cee_dcb_cfg_resp *cee_cfg,
691 struct i40e_dcbx_config *dcbcfg)
693 u32 status, tlv_status = LE32_TO_CPU(cee_cfg->tlv_status);
694 u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
695 u8 i, tc, err, sync, oper;
697 /* CEE PG data to ETS config */
698 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
700 /* Note that the FW creates the oper_prio_tc nibbles reversed
701 * from those in the CEE Priority Group sub-TLV.
703 for (i = 0; i < 4; i++) {
704 tc = (u8)((cee_cfg->oper_prio_tc[i] &
705 I40E_CEE_PGID_PRIO_0_MASK) >>
706 I40E_CEE_PGID_PRIO_0_SHIFT);
707 dcbcfg->etscfg.prioritytable[i*2] = tc;
708 tc = (u8)((cee_cfg->oper_prio_tc[i] &
709 I40E_CEE_PGID_PRIO_1_MASK) >>
710 I40E_CEE_PGID_PRIO_1_SHIFT);
711 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
714 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
715 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
717 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
718 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
719 /* Map it to next empty TC */
720 dcbcfg->etscfg.prioritytable[i] =
721 cee_cfg->oper_num_tc - 1;
722 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
724 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
728 /* CEE PFC data to ETS config */
729 dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
730 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
733 status = (tlv_status & I40E_AQC_CEE_FCOE_STATUS_MASK) >>
734 I40E_AQC_CEE_FCOE_STATUS_SHIFT;
735 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
736 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
737 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
738 /* Add FCoE APP if Error is False and Oper/Sync is True */
739 if (!err && sync && oper) {
741 dcbcfg->app[i].priority =
742 (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
743 I40E_AQC_CEE_APP_FCOE_SHIFT;
744 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
745 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FCOE;
749 status = (tlv_status & I40E_AQC_CEE_ISCSI_STATUS_MASK) >>
750 I40E_AQC_CEE_ISCSI_STATUS_SHIFT;
751 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
752 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
753 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
754 /* Add iSCSI APP if Error is False and Oper/Sync is True */
755 if (!err && sync && oper) {
757 dcbcfg->app[i].priority =
758 (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
759 I40E_AQC_CEE_APP_ISCSI_SHIFT;
760 dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
761 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_ISCSI;
765 status = (tlv_status & I40E_AQC_CEE_FIP_STATUS_MASK) >>
766 I40E_AQC_CEE_FIP_STATUS_SHIFT;
767 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
768 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
769 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
770 /* Add FIP APP if Error is False and Oper/Sync is True */
771 if (!err && sync && oper) {
773 dcbcfg->app[i].priority =
774 (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
775 I40E_AQC_CEE_APP_FIP_SHIFT;
776 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
777 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FIP;
784 * i40e_get_ieee_dcb_config
785 * @hw: pointer to the hw struct
787 * Get IEEE mode DCB configuration from the Firmware
789 STATIC enum i40e_status_code i40e_get_ieee_dcb_config(struct i40e_hw *hw)
791 enum i40e_status_code ret = I40E_SUCCESS;
794 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
795 /* Get Local DCB Config */
796 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
797 &hw->local_dcbx_config);
801 /* Get Remote DCB Config */
802 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
803 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
804 &hw->remote_dcbx_config);
805 /* Don't treat ENOENT as an error for Remote MIBs */
806 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
814 * i40e_get_dcb_config
815 * @hw: pointer to the hw struct
817 * Get DCB configuration from the Firmware
819 enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw)
821 enum i40e_status_code ret = I40E_SUCCESS;
822 struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
823 struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
825 /* If Firmware version < v4.33 IEEE only */
826 if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
827 (hw->aq.fw_maj_ver < 4))
828 return i40e_get_ieee_dcb_config(hw);
830 /* If Firmware version == v4.33 use old CEE struct */
831 if ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33)) {
832 ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
833 sizeof(cee_v1_cfg), NULL);
834 if (ret == I40E_SUCCESS) {
836 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
837 hw->local_dcbx_config.tlv_status =
838 LE16_TO_CPU(cee_v1_cfg.tlv_status);
839 i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
840 &hw->local_dcbx_config);
843 ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
844 sizeof(cee_cfg), NULL);
845 if (ret == I40E_SUCCESS) {
847 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
848 hw->local_dcbx_config.tlv_status =
849 LE32_TO_CPU(cee_cfg.tlv_status);
850 i40e_cee_to_dcb_config(&cee_cfg,
851 &hw->local_dcbx_config);
855 /* CEE mode not enabled try querying IEEE data */
856 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
857 return i40e_get_ieee_dcb_config(hw);
859 if (ret != I40E_SUCCESS)
862 /* Get CEE DCB Desired Config */
863 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
864 &hw->desired_dcbx_config);
868 /* Get Remote DCB Config */
869 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
870 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
871 &hw->remote_dcbx_config);
872 /* Don't treat ENOENT as an error for Remote MIBs */
873 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
882 * @hw: pointer to the hw struct
884 * Update DCB configuration from the Firmware
886 enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw)
888 enum i40e_status_code ret = I40E_SUCCESS;
889 struct i40e_lldp_variables lldp_cfg;
892 if (!hw->func_caps.dcb)
895 /* Read LLDP NVM area */
896 ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
900 /* Get the LLDP AdminStatus for the current port */
901 adminstatus = lldp_cfg.adminstatus >> (hw->port * 4);
904 /* LLDP agent disabled */
906 hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
910 /* Get DCBX status */
911 ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
915 /* Check the DCBX Status */
916 switch (hw->dcbx_status) {
917 case I40E_DCBX_STATUS_DONE:
918 case I40E_DCBX_STATUS_IN_PROGRESS:
919 /* Get current DCBX configuration */
920 ret = i40e_get_dcb_config(hw);
924 case I40E_DCBX_STATUS_DISABLED:
926 case I40E_DCBX_STATUS_NOT_STARTED:
927 case I40E_DCBX_STATUS_MULTIPLE_PEERS:
932 /* Configure the LLDP MIB change event */
933 ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
941 * i40e_add_ieee_ets_tlv - Prepare ETS TLV in IEEE format
942 * @tlv: Fill the ETS config data in IEEE format
943 * @dcbcfg: Local store which holds the DCB Config
945 * Prepare IEEE 802.1Qaz ETS CFG TLV
947 static void i40e_add_ieee_ets_tlv(struct i40e_lldp_org_tlv *tlv,
948 struct i40e_dcbx_config *dcbcfg)
950 u8 priority0, priority1, maxtcwilling = 0;
951 struct i40e_dcb_ets_config *etscfg;
952 u16 offset = 0, typelength, i;
953 u8 *buf = tlv->tlvinfo;
956 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
957 I40E_IEEE_ETS_TLV_LENGTH);
958 tlv->typelength = I40E_HTONS(typelength);
960 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
961 I40E_IEEE_SUBTYPE_ETS_CFG);
962 tlv->ouisubtype = I40E_HTONL(ouisubtype);
964 /* First Octet post subtype
965 * --------------------------
966 * |will-|CBS | Re- | Max |
967 * |ing | |served| TCs |
968 * --------------------------
969 * |1bit | 1bit|3 bits|3bits|
971 etscfg = &dcbcfg->etscfg;
973 maxtcwilling = BIT(I40E_IEEE_ETS_WILLING_SHIFT);
974 maxtcwilling |= etscfg->maxtcs & I40E_IEEE_ETS_MAXTC_MASK;
975 buf[offset] = maxtcwilling;
977 /* Move offset to Priority Assignment Table */
980 /* Priority Assignment Table (4 octets)
981 * Octets:| 1 | 2 | 3 | 4 |
982 * -----------------------------------------
983 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
984 * -----------------------------------------
985 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
986 * -----------------------------------------
988 for (i = 0; i < 4; i++) {
989 priority0 = etscfg->prioritytable[i * 2] & 0xF;
990 priority1 = etscfg->prioritytable[i * 2 + 1] & 0xF;
991 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
996 /* TC Bandwidth Table (8 octets)
997 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
998 * ---------------------------------
999 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1000 * ---------------------------------
1002 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1003 buf[offset++] = etscfg->tcbwtable[i];
1005 /* TSA Assignment Table (8 octets)
1006 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1007 * ---------------------------------
1008 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1009 * ---------------------------------
1011 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1012 buf[offset++] = etscfg->tsatable[i];
1016 * i40e_add_ieee_etsrec_tlv - Prepare ETS Recommended TLV in IEEE format
1017 * @tlv: Fill ETS Recommended TLV in IEEE format
1018 * @dcbcfg: Local store which holds the DCB Config
1020 * Prepare IEEE 802.1Qaz ETS REC TLV
1022 static void i40e_add_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
1023 struct i40e_dcbx_config *dcbcfg)
1025 struct i40e_dcb_ets_config *etsrec;
1026 u16 offset = 0, typelength, i;
1027 u8 priority0, priority1;
1028 u8 *buf = tlv->tlvinfo;
1031 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1032 I40E_IEEE_ETS_TLV_LENGTH);
1033 tlv->typelength = I40E_HTONS(typelength);
1035 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1036 I40E_IEEE_SUBTYPE_ETS_REC);
1037 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1039 etsrec = &dcbcfg->etsrec;
1040 /* First Octet is reserved */
1041 /* Move offset to Priority Assignment Table */
1044 /* Priority Assignment Table (4 octets)
1045 * Octets:| 1 | 2 | 3 | 4 |
1046 * -----------------------------------------
1047 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
1048 * -----------------------------------------
1049 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
1050 * -----------------------------------------
1052 for (i = 0; i < 4; i++) {
1053 priority0 = etsrec->prioritytable[i * 2] & 0xF;
1054 priority1 = etsrec->prioritytable[i * 2 + 1] & 0xF;
1055 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
1060 /* TC Bandwidth Table (8 octets)
1061 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1062 * ---------------------------------
1063 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1064 * ---------------------------------
1066 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1067 buf[offset++] = etsrec->tcbwtable[i];
1069 /* TSA Assignment Table (8 octets)
1070 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1071 * ---------------------------------
1072 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1073 * ---------------------------------
1075 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1076 buf[offset++] = etsrec->tsatable[i];
1080 * i40e_add_ieee_pfc_tlv - Prepare PFC TLV in IEEE format
1081 * @tlv: Fill PFC TLV in IEEE format
1082 * @dcbcfg: Local store to get PFC CFG data
1084 * Prepare IEEE 802.1Qaz PFC CFG TLV
1086 static void i40e_add_ieee_pfc_tlv(struct i40e_lldp_org_tlv *tlv,
1087 struct i40e_dcbx_config *dcbcfg)
1089 u8 *buf = tlv->tlvinfo;
1093 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1094 I40E_IEEE_PFC_TLV_LENGTH);
1095 tlv->typelength = I40E_HTONS(typelength);
1097 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1098 I40E_IEEE_SUBTYPE_PFC_CFG);
1099 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1101 /* ----------------------------------------
1102 * |will-|MBC | Re- | PFC | PFC Enable |
1103 * |ing | |served| cap | |
1104 * -----------------------------------------
1105 * |1bit | 1bit|2 bits|4bits| 1 octet |
1107 if (dcbcfg->pfc.willing)
1108 buf[0] = BIT(I40E_IEEE_PFC_WILLING_SHIFT);
1110 if (dcbcfg->pfc.mbc)
1111 buf[0] |= BIT(I40E_IEEE_PFC_MBC_SHIFT);
1113 buf[0] |= dcbcfg->pfc.pfccap & 0xF;
1114 buf[1] = dcbcfg->pfc.pfcenable;
1118 * i40e_add_ieee_app_pri_tlv - Prepare APP TLV in IEEE format
1119 * @tlv: Fill APP TLV in IEEE format
1120 * @dcbcfg: Local store to get APP CFG data
1122 * Prepare IEEE 802.1Qaz APP CFG TLV
1124 static void i40e_add_ieee_app_pri_tlv(struct i40e_lldp_org_tlv *tlv,
1125 struct i40e_dcbx_config *dcbcfg)
1127 u16 typelength, length, offset = 0;
1128 u8 priority, selector, i = 0;
1129 u8 *buf = tlv->tlvinfo;
1132 /* No APP TLVs then just return */
1133 if (dcbcfg->numapps == 0)
1135 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1136 I40E_IEEE_SUBTYPE_APP_PRI);
1137 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1139 /* Move offset to App Priority Table */
1141 /* Application Priority Table (3 octets)
1142 * Octets:| 1 | 2 | 3 |
1143 * -----------------------------------------
1144 * |Priority|Rsrvd| Sel | Protocol ID |
1145 * -----------------------------------------
1146 * Bits:|23 21|20 19|18 16|15 0|
1147 * -----------------------------------------
1149 while (i < dcbcfg->numapps) {
1150 priority = dcbcfg->app[i].priority & 0x7;
1151 selector = dcbcfg->app[i].selector & 0x7;
1152 buf[offset] = (priority << I40E_IEEE_APP_PRIO_SHIFT) | selector;
1153 buf[offset + 1] = (dcbcfg->app[i].protocolid >> 0x8) & 0xFF;
1154 buf[offset + 2] = dcbcfg->app[i].protocolid & 0xFF;
1155 /* Move to next app */
1158 if (i >= I40E_DCBX_MAX_APPS)
1161 /* length includes size of ouisubtype + 1 reserved + 3*numapps */
1162 length = sizeof(tlv->ouisubtype) + 1 + (i*3);
1163 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1165 tlv->typelength = I40E_HTONS(typelength);
1169 * i40e_add_dcb_tlv - Add all IEEE TLVs
1170 * @tlv: pointer to org tlv
1172 * add tlv information
1174 static void i40e_add_dcb_tlv(struct i40e_lldp_org_tlv *tlv,
1175 struct i40e_dcbx_config *dcbcfg,
1179 case I40E_IEEE_TLV_ID_ETS_CFG:
1180 i40e_add_ieee_ets_tlv(tlv, dcbcfg);
1182 case I40E_IEEE_TLV_ID_ETS_REC:
1183 i40e_add_ieee_etsrec_tlv(tlv, dcbcfg);
1185 case I40E_IEEE_TLV_ID_PFC_CFG:
1186 i40e_add_ieee_pfc_tlv(tlv, dcbcfg);
1188 case I40E_IEEE_TLV_ID_APP_PRI:
1189 i40e_add_ieee_app_pri_tlv(tlv, dcbcfg);
1197 * i40e_set_dcb_config - Set the local LLDP MIB to FW
1198 * @hw: pointer to the hw struct
1200 * Set DCB configuration to the Firmware
1202 enum i40e_status_code i40e_set_dcb_config(struct i40e_hw *hw)
1204 enum i40e_status_code ret = I40E_SUCCESS;
1205 struct i40e_dcbx_config *dcbcfg;
1206 struct i40e_virt_mem mem;
1207 u8 mib_type, *lldpmib;
1210 /* update the hw local config */
1211 dcbcfg = &hw->local_dcbx_config;
1212 /* Allocate the LLDPDU */
1213 ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
1217 mib_type = SET_LOCAL_MIB_AC_TYPE_LOCAL_MIB;
1218 if (dcbcfg->app_mode == I40E_DCBX_APPS_NON_WILLING) {
1219 mib_type |= SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS <<
1220 SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT;
1222 lldpmib = (u8 *)mem.va;
1223 ret = i40e_dcb_config_to_lldp(lldpmib, &miblen, dcbcfg);
1224 ret = i40e_aq_set_lldp_mib(hw, mib_type, (void *)lldpmib, miblen, NULL);
1226 i40e_free_virt_mem(hw, &mem);
1231 * i40e_dcb_config_to_lldp - Convert Dcbconfig to MIB format
1232 * @hw: pointer to the hw struct
1233 * @dcbcfg: store for LLDPDU data
1235 * send DCB configuration to FW
1237 enum i40e_status_code i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
1238 struct i40e_dcbx_config *dcbcfg)
1240 u16 length, offset = 0, tlvid = I40E_TLV_ID_START;
1241 enum i40e_status_code ret = I40E_SUCCESS;
1242 struct i40e_lldp_org_tlv *tlv;
1243 u16 type, typelength;
1245 tlv = (struct i40e_lldp_org_tlv *)lldpmib;
1247 i40e_add_dcb_tlv(tlv, dcbcfg, tlvid++);
1248 typelength = I40E_NTOHS(tlv->typelength);
1249 type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
1250 I40E_LLDP_TLV_TYPE_SHIFT);
1251 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
1252 I40E_LLDP_TLV_LEN_SHIFT);
1254 offset += length + 2;
1255 /* END TLV or beyond LLDPDU size */
1256 if ((tlvid >= I40E_TLV_ID_END_OF_LLDPPDU) ||
1257 (offset > I40E_LLDPDU_SIZE))
1259 /* Move to next TLV */
1261 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
1262 sizeof(tlv->typelength) + length);
1270 * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
1271 * @hw: pointer to the HW structure
1272 * @lldp_cfg: pointer to hold lldp configuration variables
1274 * Reads the LLDP configuration data from NVM
1276 enum i40e_status_code i40e_read_lldp_cfg(struct i40e_hw *hw,
1277 struct i40e_lldp_variables *lldp_cfg)
1279 enum i40e_status_code ret = I40E_SUCCESS;
1280 u32 offset = (2 * I40E_NVM_LLDP_CFG_PTR);
1283 return I40E_ERR_PARAM;
1285 ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1286 if (ret != I40E_SUCCESS)
1289 ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, offset,
1290 sizeof(struct i40e_lldp_variables),
1293 i40e_release_nvm(hw);