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 for (i = 0; i < 4; i++) {
701 tc = (u8)((cee_cfg->oper_prio_tc[i] &
702 I40E_CEE_PGID_PRIO_1_MASK) >>
703 I40E_CEE_PGID_PRIO_1_SHIFT);
704 dcbcfg->etscfg.prioritytable[i*2] = tc;
705 tc = (u8)((cee_cfg->oper_prio_tc[i] &
706 I40E_CEE_PGID_PRIO_0_MASK) >>
707 I40E_CEE_PGID_PRIO_0_SHIFT);
708 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
711 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
712 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
714 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
715 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
716 /* Map it to next empty TC */
717 dcbcfg->etscfg.prioritytable[i] =
718 cee_cfg->oper_num_tc - 1;
719 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
721 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
725 /* CEE PFC data to ETS config */
726 dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
727 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
729 status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
730 I40E_AQC_CEE_APP_STATUS_SHIFT;
731 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
732 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
733 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
734 /* Add APPs if Error is False and Oper/Sync is True */
735 if (!err && sync && oper) {
736 /* CEE operating configuration supports FCoE/iSCSI/FIP only */
737 dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
740 dcbcfg->app[0].priority =
741 (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
742 I40E_AQC_CEE_APP_FCOE_SHIFT;
743 dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
744 dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
747 dcbcfg->app[1].priority =
748 (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
749 I40E_AQC_CEE_APP_ISCSI_SHIFT;
750 dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
751 dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
754 dcbcfg->app[2].priority =
755 (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
756 I40E_AQC_CEE_APP_FIP_SHIFT;
757 dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
758 dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
763 * i40e_get_ieee_dcb_config
764 * @hw: pointer to the hw struct
766 * Get IEEE mode DCB configuration from the Firmware
768 STATIC enum i40e_status_code i40e_get_ieee_dcb_config(struct i40e_hw *hw)
770 enum i40e_status_code ret = I40E_SUCCESS;
773 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
774 /* Get Local DCB Config */
775 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
776 &hw->local_dcbx_config);
780 /* Get Remote DCB Config */
781 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
782 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
783 &hw->remote_dcbx_config);
784 /* Don't treat ENOENT as an error for Remote MIBs */
785 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
793 * i40e_get_dcb_config
794 * @hw: pointer to the hw struct
796 * Get DCB configuration from the Firmware
798 enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw)
800 enum i40e_status_code ret = I40E_SUCCESS;
801 struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
802 struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
804 /* If Firmware version < v4.33 IEEE only */
805 if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
806 (hw->aq.fw_maj_ver < 4))
807 return i40e_get_ieee_dcb_config(hw);
809 /* If Firmware version == v4.33 use old CEE struct */
810 if ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33)) {
811 ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
812 sizeof(cee_v1_cfg), NULL);
813 if (ret == I40E_SUCCESS) {
815 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
816 hw->local_dcbx_config.tlv_status =
817 LE16_TO_CPU(cee_v1_cfg.tlv_status);
818 i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
819 &hw->local_dcbx_config);
822 ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
823 sizeof(cee_cfg), NULL);
824 if (ret == I40E_SUCCESS) {
826 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
827 hw->local_dcbx_config.tlv_status =
828 LE32_TO_CPU(cee_cfg.tlv_status);
829 i40e_cee_to_dcb_config(&cee_cfg,
830 &hw->local_dcbx_config);
834 /* CEE mode not enabled try querying IEEE data */
835 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
836 return i40e_get_ieee_dcb_config(hw);
838 if (ret != I40E_SUCCESS)
841 /* Get CEE DCB Desired Config */
842 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
843 &hw->desired_dcbx_config);
847 /* Get Remote DCB Config */
848 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
849 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
850 &hw->remote_dcbx_config);
851 /* Don't treat ENOENT as an error for Remote MIBs */
852 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
861 * @hw: pointer to the hw struct
863 * Update DCB configuration from the Firmware
865 enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw)
867 enum i40e_status_code ret = I40E_SUCCESS;
868 struct i40e_lldp_variables lldp_cfg;
871 if (!hw->func_caps.dcb)
874 /* Read LLDP NVM area */
875 ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
879 /* Get the LLDP AdminStatus for the current port */
880 adminstatus = lldp_cfg.adminstatus >> (hw->port * 4);
883 /* LLDP agent disabled */
885 hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
889 /* Get DCBX status */
890 ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
894 /* Check the DCBX Status */
895 switch (hw->dcbx_status) {
896 case I40E_DCBX_STATUS_DONE:
897 case I40E_DCBX_STATUS_IN_PROGRESS:
898 /* Get current DCBX configuration */
899 ret = i40e_get_dcb_config(hw);
903 case I40E_DCBX_STATUS_DISABLED:
905 case I40E_DCBX_STATUS_NOT_STARTED:
906 case I40E_DCBX_STATUS_MULTIPLE_PEERS:
911 /* Configure the LLDP MIB change event */
912 ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
920 * i40e_add_ieee_ets_tlv - Prepare ETS TLV in IEEE format
921 * @tlv: Fill the ETS config data in IEEE format
922 * @dcbcfg: Local store which holds the DCB Config
924 * Prepare IEEE 802.1Qaz ETS CFG TLV
926 static void i40e_add_ieee_ets_tlv(struct i40e_lldp_org_tlv *tlv,
927 struct i40e_dcbx_config *dcbcfg)
929 u8 priority0, priority1, maxtcwilling = 0;
930 struct i40e_dcb_ets_config *etscfg;
931 u16 offset = 0, typelength, i;
932 u8 *buf = tlv->tlvinfo;
935 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
936 I40E_IEEE_ETS_TLV_LENGTH);
937 tlv->typelength = I40E_HTONS(typelength);
939 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
940 I40E_IEEE_SUBTYPE_ETS_CFG);
941 tlv->ouisubtype = I40E_HTONL(ouisubtype);
943 /* First Octet post subtype
944 * --------------------------
945 * |will-|CBS | Re- | Max |
946 * |ing | |served| TCs |
947 * --------------------------
948 * |1bit | 1bit|3 bits|3bits|
950 etscfg = &dcbcfg->etscfg;
952 maxtcwilling = BIT(I40E_IEEE_ETS_WILLING_SHIFT);
953 maxtcwilling |= etscfg->maxtcs & I40E_IEEE_ETS_MAXTC_MASK;
954 buf[offset] = maxtcwilling;
956 /* Move offset to Priority Assignment Table */
959 /* Priority Assignment Table (4 octets)
960 * Octets:| 1 | 2 | 3 | 4 |
961 * -----------------------------------------
962 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
963 * -----------------------------------------
964 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
965 * -----------------------------------------
967 for (i = 0; i < 4; i++) {
968 priority0 = etscfg->prioritytable[i * 2] & 0xF;
969 priority1 = etscfg->prioritytable[i * 2 + 1] & 0xF;
970 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
975 /* TC Bandwidth Table (8 octets)
976 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
977 * ---------------------------------
978 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
979 * ---------------------------------
981 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
982 buf[offset++] = etscfg->tcbwtable[i];
984 /* TSA Assignment Table (8 octets)
985 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
986 * ---------------------------------
987 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
988 * ---------------------------------
990 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
991 buf[offset++] = etscfg->tsatable[i];
995 * i40e_add_ieee_etsrec_tlv - Prepare ETS Recommended TLV in IEEE format
996 * @tlv: Fill ETS Recommended TLV in IEEE format
997 * @dcbcfg: Local store which holds the DCB Config
999 * Prepare IEEE 802.1Qaz ETS REC TLV
1001 static void i40e_add_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
1002 struct i40e_dcbx_config *dcbcfg)
1004 struct i40e_dcb_ets_config *etsrec;
1005 u16 offset = 0, typelength, i;
1006 u8 priority0, priority1;
1007 u8 *buf = tlv->tlvinfo;
1010 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1011 I40E_IEEE_ETS_TLV_LENGTH);
1012 tlv->typelength = I40E_HTONS(typelength);
1014 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1015 I40E_IEEE_SUBTYPE_ETS_REC);
1016 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1018 etsrec = &dcbcfg->etsrec;
1019 /* First Octet is reserved */
1020 /* Move offset to Priority Assignment Table */
1023 /* Priority Assignment Table (4 octets)
1024 * Octets:| 1 | 2 | 3 | 4 |
1025 * -----------------------------------------
1026 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
1027 * -----------------------------------------
1028 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
1029 * -----------------------------------------
1031 for (i = 0; i < 4; i++) {
1032 priority0 = etsrec->prioritytable[i * 2] & 0xF;
1033 priority1 = etsrec->prioritytable[i * 2 + 1] & 0xF;
1034 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
1039 /* TC Bandwidth Table (8 octets)
1040 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1041 * ---------------------------------
1042 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1043 * ---------------------------------
1045 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1046 buf[offset++] = etsrec->tcbwtable[i];
1048 /* TSA Assignment Table (8 octets)
1049 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1050 * ---------------------------------
1051 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1052 * ---------------------------------
1054 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1055 buf[offset++] = etsrec->tsatable[i];
1059 * i40e_add_ieee_pfc_tlv - Prepare PFC TLV in IEEE format
1060 * @tlv: Fill PFC TLV in IEEE format
1061 * @dcbcfg: Local store to get PFC CFG data
1063 * Prepare IEEE 802.1Qaz PFC CFG TLV
1065 static void i40e_add_ieee_pfc_tlv(struct i40e_lldp_org_tlv *tlv,
1066 struct i40e_dcbx_config *dcbcfg)
1068 u8 *buf = tlv->tlvinfo;
1072 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1073 I40E_IEEE_PFC_TLV_LENGTH);
1074 tlv->typelength = I40E_HTONS(typelength);
1076 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1077 I40E_IEEE_SUBTYPE_PFC_CFG);
1078 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1080 /* ----------------------------------------
1081 * |will-|MBC | Re- | PFC | PFC Enable |
1082 * |ing | |served| cap | |
1083 * -----------------------------------------
1084 * |1bit | 1bit|2 bits|4bits| 1 octet |
1086 if (dcbcfg->pfc.willing)
1087 buf[0] = BIT(I40E_IEEE_PFC_WILLING_SHIFT);
1089 if (dcbcfg->pfc.mbc)
1090 buf[0] |= BIT(I40E_IEEE_PFC_MBC_SHIFT);
1092 buf[0] |= dcbcfg->pfc.pfccap & 0xF;
1093 buf[1] = dcbcfg->pfc.pfcenable;
1097 * i40e_add_ieee_app_pri_tlv - Prepare APP TLV in IEEE format
1098 * @tlv: Fill APP TLV in IEEE format
1099 * @dcbcfg: Local store to get APP CFG data
1101 * Prepare IEEE 802.1Qaz APP CFG TLV
1103 static void i40e_add_ieee_app_pri_tlv(struct i40e_lldp_org_tlv *tlv,
1104 struct i40e_dcbx_config *dcbcfg)
1106 u16 typelength, length, offset = 0;
1107 u8 priority, selector, i = 0;
1108 u8 *buf = tlv->tlvinfo;
1111 /* No APP TLVs then just return */
1112 if (dcbcfg->numapps == 0)
1114 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1115 I40E_IEEE_SUBTYPE_APP_PRI);
1116 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1118 /* Move offset to App Priority Table */
1120 /* Application Priority Table (3 octets)
1121 * Octets:| 1 | 2 | 3 |
1122 * -----------------------------------------
1123 * |Priority|Rsrvd| Sel | Protocol ID |
1124 * -----------------------------------------
1125 * Bits:|23 21|20 19|18 16|15 0|
1126 * -----------------------------------------
1128 while (i < dcbcfg->numapps) {
1129 priority = dcbcfg->app[i].priority & 0x7;
1130 selector = dcbcfg->app[i].selector & 0x7;
1131 buf[offset] = (priority << I40E_IEEE_APP_PRIO_SHIFT) | selector;
1132 buf[offset + 1] = (dcbcfg->app[i].protocolid >> 0x8) & 0xFF;
1133 buf[offset + 2] = dcbcfg->app[i].protocolid & 0xFF;
1134 /* Move to next app */
1137 if (i >= I40E_DCBX_MAX_APPS)
1140 /* length includes size of ouisubtype + 1 reserved + 3*numapps */
1141 length = sizeof(tlv->ouisubtype) + 1 + (i*3);
1142 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1144 tlv->typelength = I40E_HTONS(typelength);
1148 * i40e_add_dcb_tlv - Add all IEEE TLVs
1149 * @tlv: pointer to org tlv
1151 * add tlv information
1153 static void i40e_add_dcb_tlv(struct i40e_lldp_org_tlv *tlv,
1154 struct i40e_dcbx_config *dcbcfg,
1158 case I40E_IEEE_TLV_ID_ETS_CFG:
1159 i40e_add_ieee_ets_tlv(tlv, dcbcfg);
1161 case I40E_IEEE_TLV_ID_ETS_REC:
1162 i40e_add_ieee_etsrec_tlv(tlv, dcbcfg);
1164 case I40E_IEEE_TLV_ID_PFC_CFG:
1165 i40e_add_ieee_pfc_tlv(tlv, dcbcfg);
1167 case I40E_IEEE_TLV_ID_APP_PRI:
1168 i40e_add_ieee_app_pri_tlv(tlv, dcbcfg);
1176 * i40e_set_dcb_config - Set the local LLDP MIB to FW
1177 * @hw: pointer to the hw struct
1179 * Set DCB configuration to the Firmware
1181 enum i40e_status_code i40e_set_dcb_config(struct i40e_hw *hw)
1183 enum i40e_status_code ret = I40E_SUCCESS;
1184 struct i40e_dcbx_config *dcbcfg;
1185 struct i40e_virt_mem mem;
1186 u8 mib_type, *lldpmib;
1189 /* update the hw local config */
1190 dcbcfg = &hw->local_dcbx_config;
1191 /* Allocate the LLDPDU */
1192 ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
1196 mib_type = SET_LOCAL_MIB_AC_TYPE_LOCAL_MIB;
1197 if (dcbcfg->app_mode == I40E_DCBX_APPS_NON_WILLING) {
1198 mib_type |= SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS <<
1199 SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT;
1201 lldpmib = (u8 *)mem.va;
1202 ret = i40e_dcb_config_to_lldp(lldpmib, &miblen, dcbcfg);
1203 ret = i40e_aq_set_lldp_mib(hw, mib_type, (void *)lldpmib, miblen, NULL);
1205 i40e_free_virt_mem(hw, &mem);
1210 * i40e_dcb_config_to_lldp - Convert Dcbconfig to MIB format
1211 * @hw: pointer to the hw struct
1212 * @dcbcfg: store for LLDPDU data
1214 * send DCB configuration to FW
1216 enum i40e_status_code i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
1217 struct i40e_dcbx_config *dcbcfg)
1219 u16 length, offset = 0, tlvid = I40E_TLV_ID_START;
1220 enum i40e_status_code ret = I40E_SUCCESS;
1221 struct i40e_lldp_org_tlv *tlv;
1222 u16 type, typelength;
1224 tlv = (struct i40e_lldp_org_tlv *)lldpmib;
1226 i40e_add_dcb_tlv(tlv, dcbcfg, tlvid++);
1227 typelength = I40E_NTOHS(tlv->typelength);
1228 type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
1229 I40E_LLDP_TLV_TYPE_SHIFT);
1230 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
1231 I40E_LLDP_TLV_LEN_SHIFT);
1233 offset += length + 2;
1234 /* END TLV or beyond LLDPDU size */
1235 if ((tlvid >= I40E_TLV_ID_END_OF_LLDPPDU) ||
1236 (offset > I40E_LLDPDU_SIZE))
1238 /* Move to next TLV */
1240 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
1241 sizeof(tlv->typelength) + length);
1249 * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
1250 * @hw: pointer to the HW structure
1251 * @lldp_cfg: pointer to hold lldp configuration variables
1253 * Reads the LLDP configuration data from NVM
1255 enum i40e_status_code i40e_read_lldp_cfg(struct i40e_hw *hw,
1256 struct i40e_lldp_variables *lldp_cfg)
1258 enum i40e_status_code ret = I40E_SUCCESS;
1259 u32 offset = (2 * I40E_NVM_LLDP_CFG_PTR);
1262 return I40E_ERR_PARAM;
1264 ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1265 if (ret != I40E_SUCCESS)
1268 ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, offset,
1269 sizeof(struct i40e_lldp_variables),
1272 i40e_release_nvm(hw);