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++) {
403 app = (struct i40e_cee_app_prio *)(tlv->tlvinfo + offset);
404 for (up = 0; up < I40E_MAX_USER_PRIORITY; up++) {
405 if (app->prio_map & BIT(up))
408 dcbcfg->app[i].priority = up;
410 /* Get Selector from lower 2 bits, and convert to IEEE */
411 selector = (app->upper_oui_sel & I40E_CEE_APP_SELECTOR_MASK);
413 case I40E_CEE_APP_SEL_ETHTYPE:
414 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
416 case I40E_CEE_APP_SEL_TCPIP:
417 dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
420 /* Keep selector as it is for unknown types */
421 dcbcfg->app[i].selector = selector;
424 dcbcfg->app[i].protocolid = I40E_NTOHS(app->protocol);
425 /* Move to next app */
426 offset += sizeof(*app);
433 * @dcbcfg: Local store to update DCBX config data
435 * Get the TLV subtype and send it to parsing function
436 * based on the subtype value
438 static void i40e_parse_cee_tlv(struct i40e_lldp_org_tlv *tlv,
439 struct i40e_dcbx_config *dcbcfg)
441 u16 len, tlvlen, sublen, typelength;
442 struct i40e_cee_feat_tlv *sub_tlv;
443 u8 subtype, feat_tlv_count = 0;
446 ouisubtype = I40E_NTOHL(tlv->ouisubtype);
447 subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
448 I40E_LLDP_TLV_SUBTYPE_SHIFT);
449 /* Return if not CEE DCBX */
450 if (subtype != I40E_CEE_DCBX_TYPE)
453 typelength = I40E_NTOHS(tlv->typelength);
454 tlvlen = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
455 I40E_LLDP_TLV_LEN_SHIFT);
456 len = sizeof(tlv->typelength) + sizeof(ouisubtype) +
457 sizeof(struct i40e_cee_ctrl_tlv);
458 /* Return if no CEE DCBX Feature TLVs */
462 sub_tlv = (struct i40e_cee_feat_tlv *)((char *)tlv + len);
463 while (feat_tlv_count < I40E_CEE_MAX_FEAT_TYPE) {
464 typelength = I40E_NTOHS(sub_tlv->hdr.typelen);
465 sublen = (u16)((typelength &
466 I40E_LLDP_TLV_LEN_MASK) >>
467 I40E_LLDP_TLV_LEN_SHIFT);
468 subtype = (u8)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
469 I40E_LLDP_TLV_TYPE_SHIFT);
471 case I40E_CEE_SUBTYPE_PG_CFG:
472 i40e_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);
474 case I40E_CEE_SUBTYPE_PFC_CFG:
475 i40e_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);
477 case I40E_CEE_SUBTYPE_APP_PRI:
478 i40e_parse_cee_app_tlv(sub_tlv, dcbcfg);
481 return; /* Invalid Sub-type return */
484 /* Move to next sub TLV */
485 sub_tlv = (struct i40e_cee_feat_tlv *)((char *)sub_tlv +
486 sizeof(sub_tlv->hdr.typelen) +
493 * @tlv: Organization specific TLV
494 * @dcbcfg: Local store to update ETS REC data
496 * Currently only IEEE 802.1Qaz TLV is supported, all others
499 static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
500 struct i40e_dcbx_config *dcbcfg)
505 ouisubtype = I40E_NTOHL(tlv->ouisubtype);
506 oui = (u32)((ouisubtype & I40E_LLDP_TLV_OUI_MASK) >>
507 I40E_LLDP_TLV_OUI_SHIFT);
509 case I40E_IEEE_8021QAZ_OUI:
510 i40e_parse_ieee_tlv(tlv, dcbcfg);
512 case I40E_CEE_DCBX_OUI:
513 i40e_parse_cee_tlv(tlv, dcbcfg);
521 * i40e_lldp_to_dcb_config
522 * @lldpmib: LLDPDU to be parsed
523 * @dcbcfg: store for LLDPDU data
525 * Parse DCB configuration from the LLDPDU
527 enum i40e_status_code i40e_lldp_to_dcb_config(u8 *lldpmib,
528 struct i40e_dcbx_config *dcbcfg)
530 enum i40e_status_code ret = I40E_SUCCESS;
531 struct i40e_lldp_org_tlv *tlv;
537 if (!lldpmib || !dcbcfg)
538 return I40E_ERR_PARAM;
540 /* set to the start of LLDPDU */
541 lldpmib += I40E_LLDP_MIB_HLEN;
542 tlv = (struct i40e_lldp_org_tlv *)lldpmib;
544 typelength = I40E_NTOHS(tlv->typelength);
545 type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
546 I40E_LLDP_TLV_TYPE_SHIFT);
547 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
548 I40E_LLDP_TLV_LEN_SHIFT);
549 offset += sizeof(typelength) + length;
551 /* END TLV or beyond LLDPDU size */
552 if ((type == I40E_TLV_TYPE_END) || (offset > I40E_LLDPDU_SIZE))
556 case I40E_TLV_TYPE_ORG:
557 i40e_parse_org_tlv(tlv, dcbcfg);
563 /* Move to next TLV */
564 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
565 sizeof(tlv->typelength) +
573 * i40e_aq_get_dcb_config
574 * @hw: pointer to the hw struct
575 * @mib_type: mib type for the query
576 * @bridgetype: bridge type for the query (remote)
577 * @dcbcfg: store for LLDPDU data
579 * Query DCB configuration from the Firmware
581 enum i40e_status_code i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
583 struct i40e_dcbx_config *dcbcfg)
585 enum i40e_status_code ret = I40E_SUCCESS;
586 struct i40e_virt_mem mem;
589 /* Allocate the LLDPDU */
590 ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
594 lldpmib = (u8 *)mem.va;
595 ret = i40e_aq_get_lldp_mib(hw, bridgetype, mib_type,
596 (void *)lldpmib, I40E_LLDPDU_SIZE,
601 /* Parse LLDP MIB to get dcb configuration */
602 ret = i40e_lldp_to_dcb_config(lldpmib, dcbcfg);
605 i40e_free_virt_mem(hw, &mem);
610 * i40e_cee_to_dcb_v1_config
611 * @cee_cfg: pointer to CEE v1 response configuration struct
612 * @dcbcfg: DCB configuration struct
614 * Convert CEE v1 configuration from firmware to DCB configuration
616 static void i40e_cee_to_dcb_v1_config(
617 struct i40e_aqc_get_cee_dcb_cfg_v1_resp *cee_cfg,
618 struct i40e_dcbx_config *dcbcfg)
620 u16 status, tlv_status = LE16_TO_CPU(cee_cfg->tlv_status);
621 u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
624 /* CEE PG data to ETS config */
625 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
627 /* Note that the FW creates the oper_prio_tc nibbles reversed
628 * from those in the CEE Priority Group sub-TLV.
630 for (i = 0; i < 4; i++) {
631 tc = (u8)((cee_cfg->oper_prio_tc[i] &
632 I40E_CEE_PGID_PRIO_0_MASK) >>
633 I40E_CEE_PGID_PRIO_0_SHIFT);
634 dcbcfg->etscfg.prioritytable[i*2] = tc;
635 tc = (u8)((cee_cfg->oper_prio_tc[i] &
636 I40E_CEE_PGID_PRIO_1_MASK) >>
637 I40E_CEE_PGID_PRIO_1_SHIFT);
638 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
641 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
642 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
644 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
645 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
646 /* Map it to next empty TC */
647 dcbcfg->etscfg.prioritytable[i] =
648 cee_cfg->oper_num_tc - 1;
649 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
651 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
655 /* CEE PFC data to ETS config */
656 dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
657 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
659 status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
660 I40E_AQC_CEE_APP_STATUS_SHIFT;
661 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
662 /* Add APPs if Error is False */
664 /* CEE operating configuration supports FCoE/iSCSI/FIP only */
665 dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
668 dcbcfg->app[0].priority =
669 (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
670 I40E_AQC_CEE_APP_FCOE_SHIFT;
671 dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
672 dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
675 dcbcfg->app[1].priority =
676 (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
677 I40E_AQC_CEE_APP_ISCSI_SHIFT;
678 dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
679 dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
682 dcbcfg->app[2].priority =
683 (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
684 I40E_AQC_CEE_APP_FIP_SHIFT;
685 dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
686 dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
691 * i40e_cee_to_dcb_config
692 * @cee_cfg: pointer to CEE configuration struct
693 * @dcbcfg: DCB configuration struct
695 * Convert CEE configuration from firmware to DCB configuration
697 static void i40e_cee_to_dcb_config(
698 struct i40e_aqc_get_cee_dcb_cfg_resp *cee_cfg,
699 struct i40e_dcbx_config *dcbcfg)
701 u32 status, tlv_status = LE32_TO_CPU(cee_cfg->tlv_status);
702 u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
703 u8 i, tc, err, sync, oper;
705 /* CEE PG data to ETS config */
706 dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
708 /* Note that the FW creates the oper_prio_tc nibbles reversed
709 * from those in the CEE Priority Group sub-TLV.
711 for (i = 0; i < 4; i++) {
712 tc = (u8)((cee_cfg->oper_prio_tc[i] &
713 I40E_CEE_PGID_PRIO_0_MASK) >>
714 I40E_CEE_PGID_PRIO_0_SHIFT);
715 dcbcfg->etscfg.prioritytable[i*2] = tc;
716 tc = (u8)((cee_cfg->oper_prio_tc[i] &
717 I40E_CEE_PGID_PRIO_1_MASK) >>
718 I40E_CEE_PGID_PRIO_1_SHIFT);
719 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
722 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
723 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
725 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
726 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
727 /* Map it to next empty TC */
728 dcbcfg->etscfg.prioritytable[i] =
729 cee_cfg->oper_num_tc - 1;
730 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
732 dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
736 /* CEE PFC data to ETS config */
737 dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
738 dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
741 status = (tlv_status & I40E_AQC_CEE_FCOE_STATUS_MASK) >>
742 I40E_AQC_CEE_FCOE_STATUS_SHIFT;
743 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
744 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
745 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
746 /* Add FCoE APP if Error is False and Oper/Sync is True */
747 if (!err && sync && oper) {
749 dcbcfg->app[i].priority =
750 (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
751 I40E_AQC_CEE_APP_FCOE_SHIFT;
752 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
753 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FCOE;
757 status = (tlv_status & I40E_AQC_CEE_ISCSI_STATUS_MASK) >>
758 I40E_AQC_CEE_ISCSI_STATUS_SHIFT;
759 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
760 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
761 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
762 /* Add iSCSI APP if Error is False and Oper/Sync is True */
763 if (!err && sync && oper) {
765 dcbcfg->app[i].priority =
766 (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
767 I40E_AQC_CEE_APP_ISCSI_SHIFT;
768 dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
769 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_ISCSI;
773 status = (tlv_status & I40E_AQC_CEE_FIP_STATUS_MASK) >>
774 I40E_AQC_CEE_FIP_STATUS_SHIFT;
775 err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
776 sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
777 oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
778 /* Add FIP APP if Error is False and Oper/Sync is True */
779 if (!err && sync && oper) {
781 dcbcfg->app[i].priority =
782 (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
783 I40E_AQC_CEE_APP_FIP_SHIFT;
784 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
785 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FIP;
792 * i40e_get_ieee_dcb_config
793 * @hw: pointer to the hw struct
795 * Get IEEE mode DCB configuration from the Firmware
797 STATIC enum i40e_status_code i40e_get_ieee_dcb_config(struct i40e_hw *hw)
799 enum i40e_status_code ret = I40E_SUCCESS;
802 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
803 /* Get Local DCB Config */
804 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
805 &hw->local_dcbx_config);
809 /* Get Remote DCB Config */
810 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
811 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
812 &hw->remote_dcbx_config);
813 /* Don't treat ENOENT as an error for Remote MIBs */
814 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
822 * i40e_get_dcb_config
823 * @hw: pointer to the hw struct
825 * Get DCB configuration from the Firmware
827 enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw)
829 enum i40e_status_code ret = I40E_SUCCESS;
830 struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
831 struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
833 /* If Firmware version < v4.33 on X710/XL710, IEEE only */
834 if ((hw->mac.type == I40E_MAC_XL710) &&
835 (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
836 (hw->aq.fw_maj_ver < 4)))
837 return i40e_get_ieee_dcb_config(hw);
839 /* If Firmware version == v4.33 on X710/XL710, use old CEE struct */
840 if ((hw->mac.type == I40E_MAC_XL710) &&
841 ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33))) {
842 ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
843 sizeof(cee_v1_cfg), NULL);
844 if (ret == I40E_SUCCESS) {
846 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
847 hw->local_dcbx_config.tlv_status =
848 LE16_TO_CPU(cee_v1_cfg.tlv_status);
849 i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
850 &hw->local_dcbx_config);
853 ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
854 sizeof(cee_cfg), NULL);
855 if (ret == I40E_SUCCESS) {
857 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
858 hw->local_dcbx_config.tlv_status =
859 LE32_TO_CPU(cee_cfg.tlv_status);
860 i40e_cee_to_dcb_config(&cee_cfg,
861 &hw->local_dcbx_config);
865 /* CEE mode not enabled try querying IEEE data */
866 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
867 return i40e_get_ieee_dcb_config(hw);
869 if (ret != I40E_SUCCESS)
872 /* Get CEE DCB Desired Config */
873 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
874 &hw->desired_dcbx_config);
878 /* Get Remote DCB Config */
879 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
880 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
881 &hw->remote_dcbx_config);
882 /* Don't treat ENOENT as an error for Remote MIBs */
883 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
892 * @hw: pointer to the hw struct
894 * Update DCB configuration from the Firmware
896 enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw)
898 enum i40e_status_code ret = I40E_SUCCESS;
899 struct i40e_lldp_variables lldp_cfg;
902 if (!hw->func_caps.dcb)
905 /* Read LLDP NVM area */
906 ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
910 /* Get the LLDP AdminStatus for the current port */
911 adminstatus = lldp_cfg.adminstatus >> (hw->port * 4);
914 /* LLDP agent disabled */
916 hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
920 /* Get DCBX status */
921 ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
925 /* Check the DCBX Status */
926 switch (hw->dcbx_status) {
927 case I40E_DCBX_STATUS_DONE:
928 case I40E_DCBX_STATUS_IN_PROGRESS:
929 /* Get current DCBX configuration */
930 ret = i40e_get_dcb_config(hw);
934 case I40E_DCBX_STATUS_DISABLED:
936 case I40E_DCBX_STATUS_NOT_STARTED:
937 case I40E_DCBX_STATUS_MULTIPLE_PEERS:
942 /* Configure the LLDP MIB change event */
943 ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
951 * i40e_add_ieee_ets_tlv - Prepare ETS TLV in IEEE format
952 * @tlv: Fill the ETS config data in IEEE format
953 * @dcbcfg: Local store which holds the DCB Config
955 * Prepare IEEE 802.1Qaz ETS CFG TLV
957 static void i40e_add_ieee_ets_tlv(struct i40e_lldp_org_tlv *tlv,
958 struct i40e_dcbx_config *dcbcfg)
960 u8 priority0, priority1, maxtcwilling = 0;
961 struct i40e_dcb_ets_config *etscfg;
962 u16 offset = 0, typelength, i;
963 u8 *buf = tlv->tlvinfo;
966 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
967 I40E_IEEE_ETS_TLV_LENGTH);
968 tlv->typelength = I40E_HTONS(typelength);
970 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
971 I40E_IEEE_SUBTYPE_ETS_CFG);
972 tlv->ouisubtype = I40E_HTONL(ouisubtype);
974 /* First Octet post subtype
975 * --------------------------
976 * |will-|CBS | Re- | Max |
977 * |ing | |served| TCs |
978 * --------------------------
979 * |1bit | 1bit|3 bits|3bits|
981 etscfg = &dcbcfg->etscfg;
983 maxtcwilling = BIT(I40E_IEEE_ETS_WILLING_SHIFT);
984 maxtcwilling |= etscfg->maxtcs & I40E_IEEE_ETS_MAXTC_MASK;
985 buf[offset] = maxtcwilling;
987 /* Move offset to Priority Assignment Table */
990 /* Priority Assignment Table (4 octets)
991 * Octets:| 1 | 2 | 3 | 4 |
992 * -----------------------------------------
993 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
994 * -----------------------------------------
995 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
996 * -----------------------------------------
998 for (i = 0; i < 4; i++) {
999 priority0 = etscfg->prioritytable[i * 2] & 0xF;
1000 priority1 = etscfg->prioritytable[i * 2 + 1] & 0xF;
1001 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
1006 /* TC Bandwidth Table (8 octets)
1007 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1008 * ---------------------------------
1009 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1010 * ---------------------------------
1012 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1013 buf[offset++] = etscfg->tcbwtable[i];
1015 /* TSA Assignment Table (8 octets)
1016 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1017 * ---------------------------------
1018 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1019 * ---------------------------------
1021 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1022 buf[offset++] = etscfg->tsatable[i];
1026 * i40e_add_ieee_etsrec_tlv - Prepare ETS Recommended TLV in IEEE format
1027 * @tlv: Fill ETS Recommended TLV in IEEE format
1028 * @dcbcfg: Local store which holds the DCB Config
1030 * Prepare IEEE 802.1Qaz ETS REC TLV
1032 static void i40e_add_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
1033 struct i40e_dcbx_config *dcbcfg)
1035 struct i40e_dcb_ets_config *etsrec;
1036 u16 offset = 0, typelength, i;
1037 u8 priority0, priority1;
1038 u8 *buf = tlv->tlvinfo;
1041 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1042 I40E_IEEE_ETS_TLV_LENGTH);
1043 tlv->typelength = I40E_HTONS(typelength);
1045 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1046 I40E_IEEE_SUBTYPE_ETS_REC);
1047 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1049 etsrec = &dcbcfg->etsrec;
1050 /* First Octet is reserved */
1051 /* Move offset to Priority Assignment Table */
1054 /* Priority Assignment Table (4 octets)
1055 * Octets:| 1 | 2 | 3 | 4 |
1056 * -----------------------------------------
1057 * |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
1058 * -----------------------------------------
1059 * Bits:|7 4|3 0|7 4|3 0|7 4|3 0|7 4|3 0|
1060 * -----------------------------------------
1062 for (i = 0; i < 4; i++) {
1063 priority0 = etsrec->prioritytable[i * 2] & 0xF;
1064 priority1 = etsrec->prioritytable[i * 2 + 1] & 0xF;
1065 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
1070 /* TC Bandwidth Table (8 octets)
1071 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1072 * ---------------------------------
1073 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1074 * ---------------------------------
1076 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1077 buf[offset++] = etsrec->tcbwtable[i];
1079 /* TSA Assignment Table (8 octets)
1080 * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
1081 * ---------------------------------
1082 * |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
1083 * ---------------------------------
1085 for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
1086 buf[offset++] = etsrec->tsatable[i];
1090 * i40e_add_ieee_pfc_tlv - Prepare PFC TLV in IEEE format
1091 * @tlv: Fill PFC TLV in IEEE format
1092 * @dcbcfg: Local store to get PFC CFG data
1094 * Prepare IEEE 802.1Qaz PFC CFG TLV
1096 static void i40e_add_ieee_pfc_tlv(struct i40e_lldp_org_tlv *tlv,
1097 struct i40e_dcbx_config *dcbcfg)
1099 u8 *buf = tlv->tlvinfo;
1103 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1104 I40E_IEEE_PFC_TLV_LENGTH);
1105 tlv->typelength = I40E_HTONS(typelength);
1107 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1108 I40E_IEEE_SUBTYPE_PFC_CFG);
1109 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1111 /* ----------------------------------------
1112 * |will-|MBC | Re- | PFC | PFC Enable |
1113 * |ing | |served| cap | |
1114 * -----------------------------------------
1115 * |1bit | 1bit|2 bits|4bits| 1 octet |
1117 if (dcbcfg->pfc.willing)
1118 buf[0] = BIT(I40E_IEEE_PFC_WILLING_SHIFT);
1120 if (dcbcfg->pfc.mbc)
1121 buf[0] |= BIT(I40E_IEEE_PFC_MBC_SHIFT);
1123 buf[0] |= dcbcfg->pfc.pfccap & 0xF;
1124 buf[1] = dcbcfg->pfc.pfcenable;
1128 * i40e_add_ieee_app_pri_tlv - Prepare APP TLV in IEEE format
1129 * @tlv: Fill APP TLV in IEEE format
1130 * @dcbcfg: Local store to get APP CFG data
1132 * Prepare IEEE 802.1Qaz APP CFG TLV
1134 static void i40e_add_ieee_app_pri_tlv(struct i40e_lldp_org_tlv *tlv,
1135 struct i40e_dcbx_config *dcbcfg)
1137 u16 typelength, length, offset = 0;
1138 u8 priority, selector, i = 0;
1139 u8 *buf = tlv->tlvinfo;
1142 /* No APP TLVs then just return */
1143 if (dcbcfg->numapps == 0)
1145 ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
1146 I40E_IEEE_SUBTYPE_APP_PRI);
1147 tlv->ouisubtype = I40E_HTONL(ouisubtype);
1149 /* Move offset to App Priority Table */
1151 /* Application Priority Table (3 octets)
1152 * Octets:| 1 | 2 | 3 |
1153 * -----------------------------------------
1154 * |Priority|Rsrvd| Sel | Protocol ID |
1155 * -----------------------------------------
1156 * Bits:|23 21|20 19|18 16|15 0|
1157 * -----------------------------------------
1159 while (i < dcbcfg->numapps) {
1160 priority = dcbcfg->app[i].priority & 0x7;
1161 selector = dcbcfg->app[i].selector & 0x7;
1162 buf[offset] = (priority << I40E_IEEE_APP_PRIO_SHIFT) | selector;
1163 buf[offset + 1] = (dcbcfg->app[i].protocolid >> 0x8) & 0xFF;
1164 buf[offset + 2] = dcbcfg->app[i].protocolid & 0xFF;
1165 /* Move to next app */
1168 if (i >= I40E_DCBX_MAX_APPS)
1171 /* length includes size of ouisubtype + 1 reserved + 3*numapps */
1172 length = sizeof(tlv->ouisubtype) + 1 + (i*3);
1173 typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
1175 tlv->typelength = I40E_HTONS(typelength);
1179 * i40e_add_dcb_tlv - Add all IEEE TLVs
1180 * @tlv: pointer to org tlv
1182 * add tlv information
1184 static void i40e_add_dcb_tlv(struct i40e_lldp_org_tlv *tlv,
1185 struct i40e_dcbx_config *dcbcfg,
1189 case I40E_IEEE_TLV_ID_ETS_CFG:
1190 i40e_add_ieee_ets_tlv(tlv, dcbcfg);
1192 case I40E_IEEE_TLV_ID_ETS_REC:
1193 i40e_add_ieee_etsrec_tlv(tlv, dcbcfg);
1195 case I40E_IEEE_TLV_ID_PFC_CFG:
1196 i40e_add_ieee_pfc_tlv(tlv, dcbcfg);
1198 case I40E_IEEE_TLV_ID_APP_PRI:
1199 i40e_add_ieee_app_pri_tlv(tlv, dcbcfg);
1207 * i40e_set_dcb_config - Set the local LLDP MIB to FW
1208 * @hw: pointer to the hw struct
1210 * Set DCB configuration to the Firmware
1212 enum i40e_status_code i40e_set_dcb_config(struct i40e_hw *hw)
1214 enum i40e_status_code ret = I40E_SUCCESS;
1215 struct i40e_dcbx_config *dcbcfg;
1216 struct i40e_virt_mem mem;
1217 u8 mib_type, *lldpmib;
1220 /* update the hw local config */
1221 dcbcfg = &hw->local_dcbx_config;
1222 /* Allocate the LLDPDU */
1223 ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
1227 mib_type = SET_LOCAL_MIB_AC_TYPE_LOCAL_MIB;
1228 if (dcbcfg->app_mode == I40E_DCBX_APPS_NON_WILLING) {
1229 mib_type |= SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS <<
1230 SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT;
1232 lldpmib = (u8 *)mem.va;
1233 ret = i40e_dcb_config_to_lldp(lldpmib, &miblen, dcbcfg);
1234 ret = i40e_aq_set_lldp_mib(hw, mib_type, (void *)lldpmib, miblen, NULL);
1236 i40e_free_virt_mem(hw, &mem);
1241 * i40e_dcb_config_to_lldp - Convert Dcbconfig to MIB format
1242 * @hw: pointer to the hw struct
1243 * @dcbcfg: store for LLDPDU data
1245 * send DCB configuration to FW
1247 enum i40e_status_code i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
1248 struct i40e_dcbx_config *dcbcfg)
1250 u16 length, offset = 0, tlvid = I40E_TLV_ID_START;
1251 enum i40e_status_code ret = I40E_SUCCESS;
1252 struct i40e_lldp_org_tlv *tlv;
1255 tlv = (struct i40e_lldp_org_tlv *)lldpmib;
1257 i40e_add_dcb_tlv(tlv, dcbcfg, tlvid++);
1258 typelength = I40E_NTOHS(tlv->typelength);
1259 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
1260 I40E_LLDP_TLV_LEN_SHIFT);
1262 offset += length + 2;
1263 /* END TLV or beyond LLDPDU size */
1264 if ((tlvid >= I40E_TLV_ID_END_OF_LLDPPDU) ||
1265 (offset > I40E_LLDPDU_SIZE))
1267 /* Move to next TLV */
1269 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
1270 sizeof(tlv->typelength) + length);
1278 * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
1279 * @hw: pointer to the HW structure
1280 * @lldp_cfg: pointer to hold lldp configuration variables
1282 * Reads the LLDP configuration data from NVM
1284 enum i40e_status_code i40e_read_lldp_cfg(struct i40e_hw *hw,
1285 struct i40e_lldp_variables *lldp_cfg)
1287 enum i40e_status_code ret = I40E_SUCCESS;
1288 u32 offset = (2 * I40E_NVM_LLDP_CFG_PTR);
1291 return I40E_ERR_PARAM;
1293 ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1294 if (ret != I40E_SUCCESS)
1297 ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, offset,
1298 sizeof(struct i40e_lldp_variables),
1301 i40e_release_nvm(hw);