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_dcb_config
764 * @hw: pointer to the hw struct
766 * Get DCB configuration from the Firmware
768 enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw)
770 enum i40e_status_code ret = I40E_SUCCESS;
771 struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
772 struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
774 /* If Firmware version < v4.33 IEEE only */
775 if (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
776 (hw->aq.fw_maj_ver < 4))
779 /* If Firmware version == v4.33 use old CEE struct */
780 if ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33)) {
781 ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
782 sizeof(cee_v1_cfg), NULL);
783 if (ret == I40E_SUCCESS) {
785 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
786 i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
787 &hw->local_dcbx_config);
790 ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
791 sizeof(cee_cfg), NULL);
792 if (ret == I40E_SUCCESS) {
794 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
795 i40e_cee_to_dcb_config(&cee_cfg,
796 &hw->local_dcbx_config);
800 /* CEE mode not enabled try querying IEEE data */
801 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
808 hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
809 /* Get Local DCB Config */
810 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
811 &hw->local_dcbx_config);
815 /* Get Remote DCB Config */
816 ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
817 I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
818 &hw->remote_dcbx_config);
819 /* Don't treat ENOENT as an error for Remote MIBs */
820 if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
829 * @hw: pointer to the hw struct
831 * Update DCB configuration from the Firmware
833 enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw)
835 enum i40e_status_code ret = I40E_SUCCESS;
836 struct i40e_lldp_variables lldp_cfg;
839 if (!hw->func_caps.dcb)
842 /* Read LLDP NVM area */
843 ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
847 /* Get the LLDP AdminStatus for the current port */
848 adminstatus = lldp_cfg.adminstatus >> (hw->port * 4);
851 /* LLDP agent disabled */
853 hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
857 /* Get DCBX status */
858 ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
862 /* Check the DCBX Status */
863 switch (hw->dcbx_status) {
864 case I40E_DCBX_STATUS_DONE:
865 case I40E_DCBX_STATUS_IN_PROGRESS:
866 /* Get current DCBX configuration */
867 ret = i40e_get_dcb_config(hw);
871 case I40E_DCBX_STATUS_DISABLED:
873 case I40E_DCBX_STATUS_NOT_STARTED:
874 case I40E_DCBX_STATUS_MULTIPLE_PEERS:
879 /* Configure the LLDP MIB change event */
880 ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
890 * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
891 * @hw: pointer to the HW structure
892 * @lldp_cfg: pointer to hold lldp configuration variables
894 * Reads the LLDP configuration data from NVM
896 enum i40e_status_code i40e_read_lldp_cfg(struct i40e_hw *hw,
897 struct i40e_lldp_variables *lldp_cfg)
899 enum i40e_status_code ret = I40E_SUCCESS;
900 u32 offset = (2 * I40E_NVM_LLDP_CFG_PTR);
903 return I40E_ERR_PARAM;
905 ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
906 if (ret != I40E_SUCCESS)
909 ret = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, offset,
910 sizeof(struct i40e_lldp_variables),
913 i40e_release_nvm(hw);