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)
399 if (dcbcfg->numapps > I40E_DCBX_MAX_APPS)
400 dcbcfg->numapps = I40E_DCBX_MAX_APPS;
402 for (i = 0; i < dcbcfg->numapps; i++) {
405 app = (struct i40e_cee_app_prio *)(tlv->tlvinfo + offset);
406 for (up = 0; up < I40E_MAX_USER_PRIORITY; up++) {
407 if (app->prio_map & BIT(up))
410 dcbcfg->app[i].priority = up;
412 /* Get Selector from lower 2 bits, and convert to IEEE */
413 selector = (app->upper_oui_sel & I40E_CEE_APP_SELECTOR_MASK);
415 case I40E_CEE_APP_SEL_ETHTYPE:
416 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
418 case I40E_CEE_APP_SEL_TCPIP:
419 dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
422 /* Keep selector as it is for unknown types */
423 dcbcfg->app[i].selector = selector;
426 dcbcfg->app[i].protocolid = I40E_NTOHS(app->protocol);
427 /* Move to next app */
428 offset += sizeof(*app);
435 * @dcbcfg: Local store to update DCBX config data
437 * Get the TLV subtype and send it to parsing function
438 * based on the subtype value
440 static void i40e_parse_cee_tlv(struct i40e_lldp_org_tlv *tlv,
441 struct i40e_dcbx_config *dcbcfg)
443 u16 len, tlvlen, sublen, typelength;
444 struct i40e_cee_feat_tlv *sub_tlv;
445 u8 subtype, feat_tlv_count = 0;
448 ouisubtype = I40E_NTOHL(tlv->ouisubtype);
449 subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
450 I40E_LLDP_TLV_SUBTYPE_SHIFT);
451 /* Return if not CEE DCBX */
452 if (subtype != I40E_CEE_DCBX_TYPE)
455 typelength = I40E_NTOHS(tlv->typelength);
456 tlvlen = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
457 I40E_LLDP_TLV_LEN_SHIFT);
458 len = sizeof(tlv->typelength) + sizeof(ouisubtype) +
459 sizeof(struct i40e_cee_ctrl_tlv);
460 /* Return if no CEE DCBX Feature TLVs */
464 sub_tlv = (struct i40e_cee_feat_tlv *)((char *)tlv + len);
465 while (feat_tlv_count < I40E_CEE_MAX_FEAT_TYPE) {
466 typelength = I40E_NTOHS(sub_tlv->hdr.typelen);
467 sublen = (u16)((typelength &
468 I40E_LLDP_TLV_LEN_MASK) >>
469 I40E_LLDP_TLV_LEN_SHIFT);
470 subtype = (u8)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
471 I40E_LLDP_TLV_TYPE_SHIFT);
473 case I40E_CEE_SUBTYPE_PG_CFG:
474 i40e_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);
476 case I40E_CEE_SUBTYPE_PFC_CFG:
477 i40e_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);
479 case I40E_CEE_SUBTYPE_APP_PRI:
480 i40e_parse_cee_app_tlv(sub_tlv, dcbcfg);
483 return; /* Invalid Sub-type return */
486 /* Move to next sub TLV */
487 sub_tlv = (struct i40e_cee_feat_tlv *)((char *)sub_tlv +
488 sizeof(sub_tlv->hdr.typelen) +
495 * @tlv: Organization specific TLV
496 * @dcbcfg: Local store to update ETS REC data
498 * Currently only IEEE 802.1Qaz TLV is supported, all others
501 static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
502 struct i40e_dcbx_config *dcbcfg)
507 ouisubtype = I40E_NTOHL(tlv->ouisubtype);
508 oui = (u32)((ouisubtype & I40E_LLDP_TLV_OUI_MASK) >>
509 I40E_LLDP_TLV_OUI_SHIFT);
511 case I40E_IEEE_8021QAZ_OUI:
512 i40e_parse_ieee_tlv(tlv, dcbcfg);
514 case I40E_CEE_DCBX_OUI:
515 i40e_parse_cee_tlv(tlv, dcbcfg);
523 * i40e_lldp_to_dcb_config
524 * @lldpmib: LLDPDU to be parsed
525 * @dcbcfg: store for LLDPDU data
527 * Parse DCB configuration from the LLDPDU
529 enum i40e_status_code i40e_lldp_to_dcb_config(u8 *lldpmib,
530 struct i40e_dcbx_config *dcbcfg)
532 enum i40e_status_code ret = I40E_SUCCESS;
533 struct i40e_lldp_org_tlv *tlv;
539 if (!lldpmib || !dcbcfg)
540 return I40E_ERR_PARAM;
542 /* set to the start of LLDPDU */
543 lldpmib += I40E_LLDP_MIB_HLEN;
544 tlv = (struct i40e_lldp_org_tlv *)lldpmib;
546 typelength = I40E_NTOHS(tlv->typelength);
547 type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
548 I40E_LLDP_TLV_TYPE_SHIFT);
549 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
550 I40E_LLDP_TLV_LEN_SHIFT);
551 offset += sizeof(typelength) + length;
553 /* END TLV or beyond LLDPDU size */
554 if ((type == I40E_TLV_TYPE_END) || (offset > I40E_LLDPDU_SIZE))
558 case I40E_TLV_TYPE_ORG:
559 i40e_parse_org_tlv(tlv, dcbcfg);
565 /* Move to next TLV */
566 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
567 sizeof(tlv->typelength) +
575 * i40e_aq_get_dcb_config
576 * @hw: pointer to the hw struct
577 * @mib_type: mib type for the query
578 * @bridgetype: bridge type for the query (remote)
579 * @dcbcfg: store for LLDPDU data
581 * Query DCB configuration from the Firmware
583 enum i40e_status_code i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
585 struct i40e_dcbx_config *dcbcfg)
587 enum i40e_status_code ret = I40E_SUCCESS;
588 struct i40e_virt_mem mem;
591 /* Allocate the LLDPDU */
592 ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
596 lldpmib = (u8 *)mem.va;
597 ret = i40e_aq_get_lldp_mib(hw, bridgetype, mib_type,
598 (void *)lldpmib, I40E_LLDPDU_SIZE,
603 /* Parse LLDP MIB to get dcb configuration */
604 ret = i40e_lldp_to_dcb_config(lldpmib, dcbcfg);
607 i40e_free_virt_mem(hw, &mem);
612 * i40e_cee_to_dcb_v1_config
613 * @cee_cfg: pointer to CEE v1 response configuration struct
614 * @dcbcfg: DCB configuration struct
616 * Convert CEE v1 configuration from firmware to DCB configuration
618 static void i40e_cee_to_dcb_v1_config(
619 struct i40e_aqc_get_cee_dcb_cfg_v1_resp *cee_cfg,
620 struct i40e_dcbx_config *dcbcfg)
622 u16 status, tlv_status = LE16_TO_CPU(cee_cfg->tlv_status);
623 u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
626 /* CEE PG data to ETS config */
627 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
629 /* Note that the FW creates the oper_prio_tc nibbles reversed
630 * from those in the CEE Priority Group sub-TLV.
632 for (i = 0; i < 4; i++) {
633 tc = (u8)((cee_cfg->oper_prio_tc[i] &
634 I40E_CEE_PGID_PRIO_0_MASK) >>
635 I40E_CEE_PGID_PRIO_0_SHIFT);
636 dcbcfg->etscfg.prioritytable[i*2] = tc;
637 tc = (u8)((cee_cfg->oper_prio_tc[i] &
638 I40E_CEE_PGID_PRIO_1_MASK) >>
639 I40E_CEE_PGID_PRIO_1_SHIFT);
640 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
643 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
644 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
646 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
647 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
648 /* Map it to next empty TC */
649 dcbcfg->etscfg.prioritytable[i] =
650 cee_cfg->oper_num_tc - 1;
651 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
653 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
657 /* CEE PFC data to ETS config */
658 dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
659 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
661 status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
662 I40E_AQC_CEE_APP_STATUS_SHIFT;
663 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
664 /* Add APPs if Error is False */
666 /* CEE operating configuration supports FCoE/iSCSI/FIP only */
667 dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
670 dcbcfg->app[0].priority =
671 (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
672 I40E_AQC_CEE_APP_FCOE_SHIFT;
673 dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
674 dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
677 dcbcfg->app[1].priority =
678 (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
679 I40E_AQC_CEE_APP_ISCSI_SHIFT;
680 dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
681 dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
684 dcbcfg->app[2].priority =
685 (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
686 I40E_AQC_CEE_APP_FIP_SHIFT;
687 dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
688 dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
693 * i40e_cee_to_dcb_config
694 * @cee_cfg: pointer to CEE configuration struct
695 * @dcbcfg: DCB configuration struct
697 * Convert CEE configuration from firmware to DCB configuration
699 static void i40e_cee_to_dcb_config(
700 struct i40e_aqc_get_cee_dcb_cfg_resp *cee_cfg,
701 struct i40e_dcbx_config *dcbcfg)
703 u32 status, tlv_status = LE32_TO_CPU(cee_cfg->tlv_status);
704 u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
705 u8 i, tc, err, sync, oper;
707 /* CEE PG data to ETS config */
708 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
710 /* Note that the FW creates the oper_prio_tc nibbles reversed
711 * from those in the CEE Priority Group sub-TLV.
713 for (i = 0; i < 4; i++) {
714 tc = (u8)((cee_cfg->oper_prio_tc[i] &
715 I40E_CEE_PGID_PRIO_0_MASK) >>
716 I40E_CEE_PGID_PRIO_0_SHIFT);
717 dcbcfg->etscfg.prioritytable[i*2] = tc;
718 tc = (u8)((cee_cfg->oper_prio_tc[i] &
719 I40E_CEE_PGID_PRIO_1_MASK) >>
720 I40E_CEE_PGID_PRIO_1_SHIFT);
721 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
724 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
725 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
727 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
728 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
729 /* Map it to next empty TC */
730 dcbcfg->etscfg.prioritytable[i] =
731 cee_cfg->oper_num_tc - 1;
732 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
734 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
738 /* CEE PFC data to ETS config */
739 dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
740 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
743 status = (tlv_status & I40E_AQC_CEE_FCOE_STATUS_MASK) >>
744 I40E_AQC_CEE_FCOE_STATUS_SHIFT;
745 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
746 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
747 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
748 /* Add FCoE APP if Error is False and Oper/Sync is True */
749 if (!err && sync && oper) {
751 dcbcfg->app[i].priority =
752 (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
753 I40E_AQC_CEE_APP_FCOE_SHIFT;
754 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
755 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FCOE;
759 status = (tlv_status & I40E_AQC_CEE_ISCSI_STATUS_MASK) >>
760 I40E_AQC_CEE_ISCSI_STATUS_SHIFT;
761 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
762 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
763 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
764 /* Add iSCSI APP if Error is False and Oper/Sync is True */
765 if (!err && sync && oper) {
767 dcbcfg->app[i].priority =
768 (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
769 I40E_AQC_CEE_APP_ISCSI_SHIFT;
770 dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
771 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_ISCSI;
775 status = (tlv_status & I40E_AQC_CEE_FIP_STATUS_MASK) >>
776 I40E_AQC_CEE_FIP_STATUS_SHIFT;
777 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
778 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
779 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
780 /* Add FIP APP if Error is False and Oper/Sync is True */
781 if (!err && sync && oper) {
783 dcbcfg->app[i].priority =
784 (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
785 I40E_AQC_CEE_APP_FIP_SHIFT;
786 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
787 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FIP;
794 * i40e_get_ieee_dcb_config
795 * @hw: pointer to the hw struct
797 * Get IEEE mode DCB configuration from the Firmware
799 STATIC enum i40e_status_code i40e_get_ieee_dcb_config(struct i40e_hw *hw)
801 enum i40e_status_code ret = I40E_SUCCESS;
804 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
805 /* Get Local DCB Config */
806 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
807 &hw->local_dcbx_config);
811 /* Get Remote DCB Config */
812 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
813 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
814 &hw->remote_dcbx_config);
815 /* Don't treat ENOENT as an error for Remote MIBs */
816 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
824 * i40e_get_dcb_config
825 * @hw: pointer to the hw struct
827 * Get DCB configuration from the Firmware
829 enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw)
831 enum i40e_status_code ret = I40E_SUCCESS;
832 struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
833 struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
835 /* If Firmware version < v4.33 on X710/XL710, IEEE only */
836 if ((hw->mac.type == I40E_MAC_XL710) &&
837 (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
838 (hw->aq.fw_maj_ver < 4)))
839 return i40e_get_ieee_dcb_config(hw);
841 /* If Firmware version == v4.33 on X710/XL710, use old CEE struct */
842 if ((hw->mac.type == I40E_MAC_XL710) &&
843 ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33))) {
844 ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
845 sizeof(cee_v1_cfg), NULL);
846 if (ret == I40E_SUCCESS) {
848 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
849 hw->local_dcbx_config.tlv_status =
850 LE16_TO_CPU(cee_v1_cfg.tlv_status);
851 i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
852 &hw->local_dcbx_config);
855 ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
856 sizeof(cee_cfg), NULL);
857 if (ret == I40E_SUCCESS) {
859 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
860 hw->local_dcbx_config.tlv_status =
861 LE32_TO_CPU(cee_cfg.tlv_status);
862 i40e_cee_to_dcb_config(&cee_cfg,
863 &hw->local_dcbx_config);
867 /* CEE mode not enabled try querying IEEE data */
868 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
869 return i40e_get_ieee_dcb_config(hw);
871 if (ret != I40E_SUCCESS)
874 /* Get CEE DCB Desired Config */
875 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
876 &hw->desired_dcbx_config);
880 /* Get Remote DCB Config */
881 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
882 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
883 &hw->remote_dcbx_config);
884 /* Don't treat ENOENT as an error for Remote MIBs */
885 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
894 * @hw: pointer to the hw struct
896 * Update DCB configuration from the Firmware
898 enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw)
900 enum i40e_status_code ret = I40E_SUCCESS;
901 struct i40e_lldp_variables lldp_cfg;
904 if (!hw->func_caps.dcb)
907 /* Read LLDP NVM area */
908 ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
912 /* Get the LLDP AdminStatus for the current port */
913 adminstatus = lldp_cfg.adminstatus >> (hw->port * 4);
916 /* LLDP agent disabled */
918 hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
922 /* Get DCBX status */
923 ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
927 /* Check the DCBX Status */
928 switch (hw->dcbx_status) {
929 case I40E_DCBX_STATUS_DONE:
930 case I40E_DCBX_STATUS_IN_PROGRESS:
931 /* Get current DCBX configuration */
932 ret = i40e_get_dcb_config(hw);
936 case I40E_DCBX_STATUS_DISABLED:
938 case I40E_DCBX_STATUS_NOT_STARTED:
939 case I40E_DCBX_STATUS_MULTIPLE_PEERS:
944 /* Configure the LLDP MIB change event */
945 ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
953 * i40e_add_ieee_ets_tlv - Prepare ETS TLV in IEEE format
954 * @tlv: Fill the ETS config data in IEEE format
955 * @dcbcfg: Local store which holds the DCB Config
957 * Prepare IEEE 802.1Qaz ETS CFG TLV
959 static void i40e_add_ieee_ets_tlv(struct i40e_lldp_org_tlv *tlv,
960 struct i40e_dcbx_config *dcbcfg)
962 u8 priority0, priority1, maxtcwilling = 0;
963 struct i40e_dcb_ets_config *etscfg;
964 u16 offset = 0, typelength, i;
965 u8 *buf = tlv->tlvinfo;
968 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
969 I40E_IEEE_ETS_TLV_LENGTH);
970 tlv->typelength = I40E_HTONS(typelength);
972 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
973 I40E_IEEE_SUBTYPE_ETS_CFG);
974 tlv->ouisubtype = I40E_HTONL(ouisubtype);
976 /* First Octet post subtype
977 * --------------------------
978 * |will-|CBS | Re- | Max |
979 * |ing | |served| TCs |
980 * --------------------------
981 * |1bit | 1bit|3 bits|3bits|
983 etscfg = &dcbcfg->etscfg;
985 maxtcwilling = BIT(I40E_IEEE_ETS_WILLING_SHIFT);
986 maxtcwilling |= etscfg->maxtcs & I40E_IEEE_ETS_MAXTC_MASK;
987 buf[offset] = maxtcwilling;
989 /* Move offset to Priority Assignment Table */
992 /* Priority Assignment Table (4 octets)
993 * Octets:| 1 | 2 | 3 | 4 |
994 * -----------------------------------------
995 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
996 * -----------------------------------------
997 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
998 * -----------------------------------------
1000 for (i = 0; i < 4; i++) {
1001 priority0 = etscfg->prioritytable[i * 2] & 0xF;
1002 priority1 = etscfg->prioritytable[i * 2 + 1] & 0xF;
1003 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
1008 /* TC Bandwidth Table (8 octets)
1009 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1010 * ---------------------------------
1011 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1012 * ---------------------------------
1014 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1015 buf[offset++] = etscfg->tcbwtable[i];
1017 /* TSA Assignment Table (8 octets)
1018 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1019 * ---------------------------------
1020 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1021 * ---------------------------------
1023 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1024 buf[offset++] = etscfg->tsatable[i];
1028 * i40e_add_ieee_etsrec_tlv - Prepare ETS Recommended TLV in IEEE format
1029 * @tlv: Fill ETS Recommended TLV in IEEE format
1030 * @dcbcfg: Local store which holds the DCB Config
1032 * Prepare IEEE 802.1Qaz ETS REC TLV
1034 static void i40e_add_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
1035 struct i40e_dcbx_config *dcbcfg)
1037 struct i40e_dcb_ets_config *etsrec;
1038 u16 offset = 0, typelength, i;
1039 u8 priority0, priority1;
1040 u8 *buf = tlv->tlvinfo;
1043 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1044 I40E_IEEE_ETS_TLV_LENGTH);
1045 tlv->typelength = I40E_HTONS(typelength);
1047 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1048 I40E_IEEE_SUBTYPE_ETS_REC);
1049 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1051 etsrec = &dcbcfg->etsrec;
1052 /* First Octet is reserved */
1053 /* Move offset to Priority Assignment Table */
1056 /* Priority Assignment Table (4 octets)
1057 * Octets:| 1 | 2 | 3 | 4 |
1058 * -----------------------------------------
1059 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
1060 * -----------------------------------------
1061 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
1062 * -----------------------------------------
1064 for (i = 0; i < 4; i++) {
1065 priority0 = etsrec->prioritytable[i * 2] & 0xF;
1066 priority1 = etsrec->prioritytable[i * 2 + 1] & 0xF;
1067 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
1072 /* TC Bandwidth Table (8 octets)
1073 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1074 * ---------------------------------
1075 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1076 * ---------------------------------
1078 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1079 buf[offset++] = etsrec->tcbwtable[i];
1081 /* TSA Assignment Table (8 octets)
1082 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1083 * ---------------------------------
1084 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1085 * ---------------------------------
1087 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1088 buf[offset++] = etsrec->tsatable[i];
1092 * i40e_add_ieee_pfc_tlv - Prepare PFC TLV in IEEE format
1093 * @tlv: Fill PFC TLV in IEEE format
1094 * @dcbcfg: Local store to get PFC CFG data
1096 * Prepare IEEE 802.1Qaz PFC CFG TLV
1098 static void i40e_add_ieee_pfc_tlv(struct i40e_lldp_org_tlv *tlv,
1099 struct i40e_dcbx_config *dcbcfg)
1101 u8 *buf = tlv->tlvinfo;
1105 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1106 I40E_IEEE_PFC_TLV_LENGTH);
1107 tlv->typelength = I40E_HTONS(typelength);
1109 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1110 I40E_IEEE_SUBTYPE_PFC_CFG);
1111 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1113 /* ----------------------------------------
1114 * |will-|MBC | Re- | PFC | PFC Enable |
1115 * |ing | |served| cap | |
1116 * -----------------------------------------
1117 * |1bit | 1bit|2 bits|4bits| 1 octet |
1119 if (dcbcfg->pfc.willing)
1120 buf[0] = BIT(I40E_IEEE_PFC_WILLING_SHIFT);
1122 if (dcbcfg->pfc.mbc)
1123 buf[0] |= BIT(I40E_IEEE_PFC_MBC_SHIFT);
1125 buf[0] |= dcbcfg->pfc.pfccap & 0xF;
1126 buf[1] = dcbcfg->pfc.pfcenable;
1130 * i40e_add_ieee_app_pri_tlv - Prepare APP TLV in IEEE format
1131 * @tlv: Fill APP TLV in IEEE format
1132 * @dcbcfg: Local store to get APP CFG data
1134 * Prepare IEEE 802.1Qaz APP CFG TLV
1136 static void i40e_add_ieee_app_pri_tlv(struct i40e_lldp_org_tlv *tlv,
1137 struct i40e_dcbx_config *dcbcfg)
1139 u16 typelength, length, offset = 0;
1140 u8 priority, selector, i = 0;
1141 u8 *buf = tlv->tlvinfo;
1144 /* No APP TLVs then just return */
1145 if (dcbcfg->numapps == 0)
1147 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1148 I40E_IEEE_SUBTYPE_APP_PRI);
1149 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1151 /* Move offset to App Priority Table */
1153 /* Application Priority Table (3 octets)
1154 * Octets:| 1 | 2 | 3 |
1155 * -----------------------------------------
1156 * |Priority|Rsrvd| Sel | Protocol ID |
1157 * -----------------------------------------
1158 * Bits:|23 21|20 19|18 16|15 0|
1159 * -----------------------------------------
1161 while (i < dcbcfg->numapps) {
1162 priority = dcbcfg->app[i].priority & 0x7;
1163 selector = dcbcfg->app[i].selector & 0x7;
1164 buf[offset] = (priority << I40E_IEEE_APP_PRIO_SHIFT) | selector;
1165 buf[offset + 1] = (dcbcfg->app[i].protocolid >> 0x8) & 0xFF;
1166 buf[offset + 2] = dcbcfg->app[i].protocolid & 0xFF;
1167 /* Move to next app */
1170 if (i >= I40E_DCBX_MAX_APPS)
1173 /* length includes size of ouisubtype + 1 reserved + 3*numapps */
1174 length = sizeof(tlv->ouisubtype) + 1 + (i*3);
1175 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1177 tlv->typelength = I40E_HTONS(typelength);
1181 * i40e_add_dcb_tlv - Add all IEEE TLVs
1182 * @tlv: pointer to org tlv
1184 * add tlv information
1186 static void i40e_add_dcb_tlv(struct i40e_lldp_org_tlv *tlv,
1187 struct i40e_dcbx_config *dcbcfg,
1191 case I40E_IEEE_TLV_ID_ETS_CFG:
1192 i40e_add_ieee_ets_tlv(tlv, dcbcfg);
1194 case I40E_IEEE_TLV_ID_ETS_REC:
1195 i40e_add_ieee_etsrec_tlv(tlv, dcbcfg);
1197 case I40E_IEEE_TLV_ID_PFC_CFG:
1198 i40e_add_ieee_pfc_tlv(tlv, dcbcfg);
1200 case I40E_IEEE_TLV_ID_APP_PRI:
1201 i40e_add_ieee_app_pri_tlv(tlv, dcbcfg);
1209 * i40e_set_dcb_config - Set the local LLDP MIB to FW
1210 * @hw: pointer to the hw struct
1212 * Set DCB configuration to the Firmware
1214 enum i40e_status_code i40e_set_dcb_config(struct i40e_hw *hw)
1216 enum i40e_status_code ret = I40E_SUCCESS;
1217 struct i40e_dcbx_config *dcbcfg;
1218 struct i40e_virt_mem mem;
1219 u8 mib_type, *lldpmib;
1222 /* update the hw local config */
1223 dcbcfg = &hw->local_dcbx_config;
1224 /* Allocate the LLDPDU */
1225 ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
1229 mib_type = SET_LOCAL_MIB_AC_TYPE_LOCAL_MIB;
1230 if (dcbcfg->app_mode == I40E_DCBX_APPS_NON_WILLING) {
1231 mib_type |= SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS <<
1232 SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT;
1234 lldpmib = (u8 *)mem.va;
1235 ret = i40e_dcb_config_to_lldp(lldpmib, &miblen, dcbcfg);
1236 ret = i40e_aq_set_lldp_mib(hw, mib_type, (void *)lldpmib, miblen, NULL);
1238 i40e_free_virt_mem(hw, &mem);
1243 * i40e_dcb_config_to_lldp - Convert Dcbconfig to MIB format
1244 * @hw: pointer to the hw struct
1245 * @dcbcfg: store for LLDPDU data
1247 * send DCB configuration to FW
1249 enum i40e_status_code i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
1250 struct i40e_dcbx_config *dcbcfg)
1252 u16 length, offset = 0, tlvid = I40E_TLV_ID_START;
1253 enum i40e_status_code ret = I40E_SUCCESS;
1254 struct i40e_lldp_org_tlv *tlv;
1257 tlv = (struct i40e_lldp_org_tlv *)lldpmib;
1259 i40e_add_dcb_tlv(tlv, dcbcfg, tlvid++);
1260 typelength = I40E_NTOHS(tlv->typelength);
1261 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
1262 I40E_LLDP_TLV_LEN_SHIFT);
1264 offset += length + 2;
1265 /* END TLV or beyond LLDPDU size */
1266 if ((tlvid >= I40E_TLV_ID_END_OF_LLDPPDU) ||
1267 (offset > I40E_LLDPDU_SIZE))
1269 /* Move to next TLV */
1271 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
1272 sizeof(tlv->typelength) + length);
1280 * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
1281 * @hw: pointer to the HW structure
1282 * @lldp_cfg: pointer to hold lldp configuration variables
1284 * Reads the LLDP configuration data from NVM
1286 enum i40e_status_code i40e_read_lldp_cfg(struct i40e_hw *hw,
1287 struct i40e_lldp_variables *lldp_cfg)
1289 enum i40e_status_code ret = I40E_SUCCESS;
1290 u32 offset = (2 * I40E_NVM_LLDP_CFG_PTR);
1293 return I40E_ERR_PARAM;
1295 ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1296 if (ret != I40E_SUCCESS)
1299 ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, offset,
1300 sizeof(struct i40e_lldp_variables),
1303 i40e_release_nvm(hw);