root/drivers/net/ethernet/intel/i40e/i40e_dcb.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. i40e_get_dcbx_status
  2. i40e_parse_ieee_etscfg_tlv
  3. i40e_parse_ieee_etsrec_tlv
  4. i40e_parse_ieee_pfccfg_tlv
  5. i40e_parse_ieee_app_tlv
  6. i40e_parse_ieee_tlv
  7. i40e_parse_cee_pgcfg_tlv
  8. i40e_parse_cee_pfccfg_tlv
  9. i40e_parse_cee_app_tlv
  10. i40e_parse_cee_tlv
  11. i40e_parse_org_tlv
  12. i40e_lldp_to_dcb_config
  13. i40e_aq_get_dcb_config
  14. i40e_cee_to_dcb_v1_config
  15. i40e_cee_to_dcb_config
  16. i40e_get_ieee_dcb_config
  17. i40e_get_dcb_config
  18. i40e_init_dcb
  19. _i40e_read_lldp_cfg
  20. i40e_read_lldp_cfg

   1 // SPDX-License-Identifier: GPL-2.0
   2 /* Copyright(c) 2013 - 2018 Intel Corporation. */
   3 
   4 #include "i40e_adminq.h"
   5 #include "i40e_prototype.h"
   6 #include "i40e_dcb.h"
   7 
   8 /**
   9  * i40e_get_dcbx_status
  10  * @hw: pointer to the hw struct
  11  * @status: Embedded DCBX Engine Status
  12  *
  13  * Get the DCBX status from the Firmware
  14  **/
  15 i40e_status i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status)
  16 {
  17         u32 reg;
  18 
  19         if (!status)
  20                 return I40E_ERR_PARAM;
  21 
  22         reg = rd32(hw, I40E_PRTDCB_GENS);
  23         *status = (u16)((reg & I40E_PRTDCB_GENS_DCBX_STATUS_MASK) >>
  24                         I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT);
  25 
  26         return 0;
  27 }
  28 
  29 /**
  30  * i40e_parse_ieee_etscfg_tlv
  31  * @tlv: IEEE 802.1Qaz ETS CFG TLV
  32  * @dcbcfg: Local store to update ETS CFG data
  33  *
  34  * Parses IEEE 802.1Qaz ETS CFG TLV
  35  **/
  36 static void i40e_parse_ieee_etscfg_tlv(struct i40e_lldp_org_tlv *tlv,
  37                                        struct i40e_dcbx_config *dcbcfg)
  38 {
  39         struct i40e_dcb_ets_config *etscfg;
  40         u8 *buf = tlv->tlvinfo;
  41         u16 offset = 0;
  42         u8 priority;
  43         int i;
  44 
  45         /* First Octet post subtype
  46          * --------------------------
  47          * |will-|CBS  | Re-  | Max |
  48          * |ing  |     |served| TCs |
  49          * --------------------------
  50          * |1bit | 1bit|3 bits|3bits|
  51          */
  52         etscfg = &dcbcfg->etscfg;
  53         etscfg->willing = (u8)((buf[offset] & I40E_IEEE_ETS_WILLING_MASK) >>
  54                                I40E_IEEE_ETS_WILLING_SHIFT);
  55         etscfg->cbs = (u8)((buf[offset] & I40E_IEEE_ETS_CBS_MASK) >>
  56                            I40E_IEEE_ETS_CBS_SHIFT);
  57         etscfg->maxtcs = (u8)((buf[offset] & I40E_IEEE_ETS_MAXTC_MASK) >>
  58                               I40E_IEEE_ETS_MAXTC_SHIFT);
  59 
  60         /* Move offset to Priority Assignment Table */
  61         offset++;
  62 
  63         /* Priority Assignment Table (4 octets)
  64          * Octets:|    1    |    2    |    3    |    4    |
  65          *        -----------------------------------------
  66          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
  67          *        -----------------------------------------
  68          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
  69          *        -----------------------------------------
  70          */
  71         for (i = 0; i < 4; i++) {
  72                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
  73                                 I40E_IEEE_ETS_PRIO_1_SHIFT);
  74                 etscfg->prioritytable[i * 2] =  priority;
  75                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
  76                                 I40E_IEEE_ETS_PRIO_0_SHIFT);
  77                 etscfg->prioritytable[i * 2 + 1] = priority;
  78                 offset++;
  79         }
  80 
  81         /* TC Bandwidth Table (8 octets)
  82          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
  83          *        ---------------------------------
  84          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
  85          *        ---------------------------------
  86          */
  87         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
  88                 etscfg->tcbwtable[i] = buf[offset++];
  89 
  90         /* TSA Assignment Table (8 octets)
  91          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
  92          *        ---------------------------------
  93          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
  94          *        ---------------------------------
  95          */
  96         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
  97                 etscfg->tsatable[i] = buf[offset++];
  98 }
  99 
 100 /**
 101  * i40e_parse_ieee_etsrec_tlv
 102  * @tlv: IEEE 802.1Qaz ETS REC TLV
 103  * @dcbcfg: Local store to update ETS REC data
 104  *
 105  * Parses IEEE 802.1Qaz ETS REC TLV
 106  **/
 107 static void i40e_parse_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
 108                                        struct i40e_dcbx_config *dcbcfg)
 109 {
 110         u8 *buf = tlv->tlvinfo;
 111         u16 offset = 0;
 112         u8 priority;
 113         int i;
 114 
 115         /* Move offset to priority table */
 116         offset++;
 117 
 118         /* Priority Assignment Table (4 octets)
 119          * Octets:|    1    |    2    |    3    |    4    |
 120          *        -----------------------------------------
 121          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
 122          *        -----------------------------------------
 123          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
 124          *        -----------------------------------------
 125          */
 126         for (i = 0; i < 4; i++) {
 127                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
 128                                 I40E_IEEE_ETS_PRIO_1_SHIFT);
 129                 dcbcfg->etsrec.prioritytable[i*2] =  priority;
 130                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
 131                                 I40E_IEEE_ETS_PRIO_0_SHIFT);
 132                 dcbcfg->etsrec.prioritytable[i*2 + 1] = priority;
 133                 offset++;
 134         }
 135 
 136         /* TC Bandwidth Table (8 octets)
 137          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
 138          *        ---------------------------------
 139          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
 140          *        ---------------------------------
 141          */
 142         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
 143                 dcbcfg->etsrec.tcbwtable[i] = buf[offset++];
 144 
 145         /* TSA Assignment Table (8 octets)
 146          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
 147          *        ---------------------------------
 148          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
 149          *        ---------------------------------
 150          */
 151         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
 152                 dcbcfg->etsrec.tsatable[i] = buf[offset++];
 153 }
 154 
 155 /**
 156  * i40e_parse_ieee_pfccfg_tlv
 157  * @tlv: IEEE 802.1Qaz PFC CFG TLV
 158  * @dcbcfg: Local store to update PFC CFG data
 159  *
 160  * Parses IEEE 802.1Qaz PFC CFG TLV
 161  **/
 162 static void i40e_parse_ieee_pfccfg_tlv(struct i40e_lldp_org_tlv *tlv,
 163                                        struct i40e_dcbx_config *dcbcfg)
 164 {
 165         u8 *buf = tlv->tlvinfo;
 166 
 167         /* ----------------------------------------
 168          * |will-|MBC  | Re-  | PFC |  PFC Enable  |
 169          * |ing  |     |served| cap |              |
 170          * -----------------------------------------
 171          * |1bit | 1bit|2 bits|4bits| 1 octet      |
 172          */
 173         dcbcfg->pfc.willing = (u8)((buf[0] & I40E_IEEE_PFC_WILLING_MASK) >>
 174                                    I40E_IEEE_PFC_WILLING_SHIFT);
 175         dcbcfg->pfc.mbc = (u8)((buf[0] & I40E_IEEE_PFC_MBC_MASK) >>
 176                                I40E_IEEE_PFC_MBC_SHIFT);
 177         dcbcfg->pfc.pfccap = (u8)((buf[0] & I40E_IEEE_PFC_CAP_MASK) >>
 178                                   I40E_IEEE_PFC_CAP_SHIFT);
 179         dcbcfg->pfc.pfcenable = buf[1];
 180 }
 181 
 182 /**
 183  * i40e_parse_ieee_app_tlv
 184  * @tlv: IEEE 802.1Qaz APP TLV
 185  * @dcbcfg: Local store to update APP PRIO data
 186  *
 187  * Parses IEEE 802.1Qaz APP PRIO TLV
 188  **/
 189 static void i40e_parse_ieee_app_tlv(struct i40e_lldp_org_tlv *tlv,
 190                                     struct i40e_dcbx_config *dcbcfg)
 191 {
 192         u16 typelength;
 193         u16 offset = 0;
 194         u16 length;
 195         int i = 0;
 196         u8 *buf;
 197 
 198         typelength = ntohs(tlv->typelength);
 199         length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
 200                        I40E_LLDP_TLV_LEN_SHIFT);
 201         buf = tlv->tlvinfo;
 202 
 203         /* The App priority table starts 5 octets after TLV header */
 204         length -= (sizeof(tlv->ouisubtype) + 1);
 205 
 206         /* Move offset to App Priority Table */
 207         offset++;
 208 
 209         /* Application Priority Table (3 octets)
 210          * Octets:|         1          |    2    |    3    |
 211          *        -----------------------------------------
 212          *        |Priority|Rsrvd| Sel |    Protocol ID    |
 213          *        -----------------------------------------
 214          *   Bits:|23    21|20 19|18 16|15                0|
 215          *        -----------------------------------------
 216          */
 217         while (offset < length) {
 218                 dcbcfg->app[i].priority = (u8)((buf[offset] &
 219                                                 I40E_IEEE_APP_PRIO_MASK) >>
 220                                                I40E_IEEE_APP_PRIO_SHIFT);
 221                 dcbcfg->app[i].selector = (u8)((buf[offset] &
 222                                                 I40E_IEEE_APP_SEL_MASK) >>
 223                                                I40E_IEEE_APP_SEL_SHIFT);
 224                 dcbcfg->app[i].protocolid = (buf[offset + 1] << 0x8) |
 225                                              buf[offset + 2];
 226                 /* Move to next app */
 227                 offset += 3;
 228                 i++;
 229                 if (i >= I40E_DCBX_MAX_APPS)
 230                         break;
 231         }
 232 
 233         dcbcfg->numapps = i;
 234 }
 235 
 236 /**
 237  * i40e_parse_ieee_etsrec_tlv
 238  * @tlv: IEEE 802.1Qaz TLV
 239  * @dcbcfg: Local store to update ETS REC data
 240  *
 241  * Get the TLV subtype and send it to parsing function
 242  * based on the subtype value
 243  **/
 244 static void i40e_parse_ieee_tlv(struct i40e_lldp_org_tlv *tlv,
 245                                 struct i40e_dcbx_config *dcbcfg)
 246 {
 247         u32 ouisubtype;
 248         u8 subtype;
 249 
 250         ouisubtype = ntohl(tlv->ouisubtype);
 251         subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
 252                        I40E_LLDP_TLV_SUBTYPE_SHIFT);
 253         switch (subtype) {
 254         case I40E_IEEE_SUBTYPE_ETS_CFG:
 255                 i40e_parse_ieee_etscfg_tlv(tlv, dcbcfg);
 256                 break;
 257         case I40E_IEEE_SUBTYPE_ETS_REC:
 258                 i40e_parse_ieee_etsrec_tlv(tlv, dcbcfg);
 259                 break;
 260         case I40E_IEEE_SUBTYPE_PFC_CFG:
 261                 i40e_parse_ieee_pfccfg_tlv(tlv, dcbcfg);
 262                 break;
 263         case I40E_IEEE_SUBTYPE_APP_PRI:
 264                 i40e_parse_ieee_app_tlv(tlv, dcbcfg);
 265                 break;
 266         default:
 267                 break;
 268         }
 269 }
 270 
 271 /**
 272  * i40e_parse_cee_pgcfg_tlv
 273  * @tlv: CEE DCBX PG CFG TLV
 274  * @dcbcfg: Local store to update ETS CFG data
 275  *
 276  * Parses CEE DCBX PG CFG TLV
 277  **/
 278 static void i40e_parse_cee_pgcfg_tlv(struct i40e_cee_feat_tlv *tlv,
 279                                      struct i40e_dcbx_config *dcbcfg)
 280 {
 281         struct i40e_dcb_ets_config *etscfg;
 282         u8 *buf = tlv->tlvinfo;
 283         u16 offset = 0;
 284         u8 priority;
 285         int i;
 286 
 287         etscfg = &dcbcfg->etscfg;
 288 
 289         if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
 290                 etscfg->willing = 1;
 291 
 292         etscfg->cbs = 0;
 293         /* Priority Group Table (4 octets)
 294          * Octets:|    1    |    2    |    3    |    4    |
 295          *        -----------------------------------------
 296          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
 297          *        -----------------------------------------
 298          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
 299          *        -----------------------------------------
 300          */
 301         for (i = 0; i < 4; i++) {
 302                 priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_1_MASK) >>
 303                                  I40E_CEE_PGID_PRIO_1_SHIFT);
 304                 etscfg->prioritytable[i * 2] =  priority;
 305                 priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_0_MASK) >>
 306                                  I40E_CEE_PGID_PRIO_0_SHIFT);
 307                 etscfg->prioritytable[i * 2 + 1] = priority;
 308                 offset++;
 309         }
 310 
 311         /* PG Percentage Table (8 octets)
 312          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
 313          *        ---------------------------------
 314          *        |pg0|pg1|pg2|pg3|pg4|pg5|pg6|pg7|
 315          *        ---------------------------------
 316          */
 317         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
 318                 etscfg->tcbwtable[i] = buf[offset++];
 319 
 320         /* Number of TCs supported (1 octet) */
 321         etscfg->maxtcs = buf[offset];
 322 }
 323 
 324 /**
 325  * i40e_parse_cee_pfccfg_tlv
 326  * @tlv: CEE DCBX PFC CFG TLV
 327  * @dcbcfg: Local store to update PFC CFG data
 328  *
 329  * Parses CEE DCBX PFC CFG TLV
 330  **/
 331 static void i40e_parse_cee_pfccfg_tlv(struct i40e_cee_feat_tlv *tlv,
 332                                       struct i40e_dcbx_config *dcbcfg)
 333 {
 334         u8 *buf = tlv->tlvinfo;
 335 
 336         if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
 337                 dcbcfg->pfc.willing = 1;
 338 
 339         /* ------------------------
 340          * | PFC Enable | PFC TCs |
 341          * ------------------------
 342          * | 1 octet    | 1 octet |
 343          */
 344         dcbcfg->pfc.pfcenable = buf[0];
 345         dcbcfg->pfc.pfccap = buf[1];
 346 }
 347 
 348 /**
 349  * i40e_parse_cee_app_tlv
 350  * @tlv: CEE DCBX APP TLV
 351  * @dcbcfg: Local store to update APP PRIO data
 352  *
 353  * Parses CEE DCBX APP PRIO TLV
 354  **/
 355 static void i40e_parse_cee_app_tlv(struct i40e_cee_feat_tlv *tlv,
 356                                    struct i40e_dcbx_config *dcbcfg)
 357 {
 358         u16 length, typelength, offset = 0;
 359         struct i40e_cee_app_prio *app;
 360         u8 i;
 361 
 362         typelength = ntohs(tlv->hdr.typelen);
 363         length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
 364                        I40E_LLDP_TLV_LEN_SHIFT);
 365 
 366         dcbcfg->numapps = length / sizeof(*app);
 367 
 368         if (!dcbcfg->numapps)
 369                 return;
 370         if (dcbcfg->numapps > I40E_DCBX_MAX_APPS)
 371                 dcbcfg->numapps = I40E_DCBX_MAX_APPS;
 372 
 373         for (i = 0; i < dcbcfg->numapps; i++) {
 374                 u8 up, selector;
 375 
 376                 app = (struct i40e_cee_app_prio *)(tlv->tlvinfo + offset);
 377                 for (up = 0; up < I40E_MAX_USER_PRIORITY; up++) {
 378                         if (app->prio_map & BIT(up))
 379                                 break;
 380                 }
 381                 dcbcfg->app[i].priority = up;
 382 
 383                 /* Get Selector from lower 2 bits, and convert to IEEE */
 384                 selector = (app->upper_oui_sel & I40E_CEE_APP_SELECTOR_MASK);
 385                 switch (selector) {
 386                 case I40E_CEE_APP_SEL_ETHTYPE:
 387                         dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
 388                         break;
 389                 case I40E_CEE_APP_SEL_TCPIP:
 390                         dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
 391                         break;
 392                 default:
 393                         /* Keep selector as it is for unknown types */
 394                         dcbcfg->app[i].selector = selector;
 395                 }
 396 
 397                 dcbcfg->app[i].protocolid = ntohs(app->protocol);
 398                 /* Move to next app */
 399                 offset += sizeof(*app);
 400         }
 401 }
 402 
 403 /**
 404  * i40e_parse_cee_tlv
 405  * @tlv: CEE DCBX TLV
 406  * @dcbcfg: Local store to update DCBX config data
 407  *
 408  * Get the TLV subtype and send it to parsing function
 409  * based on the subtype value
 410  **/
 411 static void i40e_parse_cee_tlv(struct i40e_lldp_org_tlv *tlv,
 412                                struct i40e_dcbx_config *dcbcfg)
 413 {
 414         u16 len, tlvlen, sublen, typelength;
 415         struct i40e_cee_feat_tlv *sub_tlv;
 416         u8 subtype, feat_tlv_count = 0;
 417         u32 ouisubtype;
 418 
 419         ouisubtype = ntohl(tlv->ouisubtype);
 420         subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
 421                        I40E_LLDP_TLV_SUBTYPE_SHIFT);
 422         /* Return if not CEE DCBX */
 423         if (subtype != I40E_CEE_DCBX_TYPE)
 424                 return;
 425 
 426         typelength = ntohs(tlv->typelength);
 427         tlvlen = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
 428                         I40E_LLDP_TLV_LEN_SHIFT);
 429         len = sizeof(tlv->typelength) + sizeof(ouisubtype) +
 430               sizeof(struct i40e_cee_ctrl_tlv);
 431         /* Return if no CEE DCBX Feature TLVs */
 432         if (tlvlen <= len)
 433                 return;
 434 
 435         sub_tlv = (struct i40e_cee_feat_tlv *)((char *)tlv + len);
 436         while (feat_tlv_count < I40E_CEE_MAX_FEAT_TYPE) {
 437                 typelength = ntohs(sub_tlv->hdr.typelen);
 438                 sublen = (u16)((typelength &
 439                                 I40E_LLDP_TLV_LEN_MASK) >>
 440                                 I40E_LLDP_TLV_LEN_SHIFT);
 441                 subtype = (u8)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
 442                                 I40E_LLDP_TLV_TYPE_SHIFT);
 443                 switch (subtype) {
 444                 case I40E_CEE_SUBTYPE_PG_CFG:
 445                         i40e_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);
 446                         break;
 447                 case I40E_CEE_SUBTYPE_PFC_CFG:
 448                         i40e_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);
 449                         break;
 450                 case I40E_CEE_SUBTYPE_APP_PRI:
 451                         i40e_parse_cee_app_tlv(sub_tlv, dcbcfg);
 452                         break;
 453                 default:
 454                         return; /* Invalid Sub-type return */
 455                 }
 456                 feat_tlv_count++;
 457                 /* Move to next sub TLV */
 458                 sub_tlv = (struct i40e_cee_feat_tlv *)((char *)sub_tlv +
 459                                                 sizeof(sub_tlv->hdr.typelen) +
 460                                                 sublen);
 461         }
 462 }
 463 
 464 /**
 465  * i40e_parse_org_tlv
 466  * @tlv: Organization specific TLV
 467  * @dcbcfg: Local store to update ETS REC data
 468  *
 469  * Currently only IEEE 802.1Qaz TLV is supported, all others
 470  * will be returned
 471  **/
 472 static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
 473                                struct i40e_dcbx_config *dcbcfg)
 474 {
 475         u32 ouisubtype;
 476         u32 oui;
 477 
 478         ouisubtype = ntohl(tlv->ouisubtype);
 479         oui = (u32)((ouisubtype & I40E_LLDP_TLV_OUI_MASK) >>
 480                     I40E_LLDP_TLV_OUI_SHIFT);
 481         switch (oui) {
 482         case I40E_IEEE_8021QAZ_OUI:
 483                 i40e_parse_ieee_tlv(tlv, dcbcfg);
 484                 break;
 485         case I40E_CEE_DCBX_OUI:
 486                 i40e_parse_cee_tlv(tlv, dcbcfg);
 487                 break;
 488         default:
 489                 break;
 490         }
 491 }
 492 
 493 /**
 494  * i40e_lldp_to_dcb_config
 495  * @lldpmib: LLDPDU to be parsed
 496  * @dcbcfg: store for LLDPDU data
 497  *
 498  * Parse DCB configuration from the LLDPDU
 499  **/
 500 i40e_status i40e_lldp_to_dcb_config(u8 *lldpmib,
 501                                     struct i40e_dcbx_config *dcbcfg)
 502 {
 503         i40e_status ret = 0;
 504         struct i40e_lldp_org_tlv *tlv;
 505         u16 type;
 506         u16 length;
 507         u16 typelength;
 508         u16 offset = 0;
 509 
 510         if (!lldpmib || !dcbcfg)
 511                 return I40E_ERR_PARAM;
 512 
 513         /* set to the start of LLDPDU */
 514         lldpmib += ETH_HLEN;
 515         tlv = (struct i40e_lldp_org_tlv *)lldpmib;
 516         while (1) {
 517                 typelength = ntohs(tlv->typelength);
 518                 type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
 519                              I40E_LLDP_TLV_TYPE_SHIFT);
 520                 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
 521                                I40E_LLDP_TLV_LEN_SHIFT);
 522                 offset += sizeof(typelength) + length;
 523 
 524                 /* END TLV or beyond LLDPDU size */
 525                 if ((type == I40E_TLV_TYPE_END) || (offset > I40E_LLDPDU_SIZE))
 526                         break;
 527 
 528                 switch (type) {
 529                 case I40E_TLV_TYPE_ORG:
 530                         i40e_parse_org_tlv(tlv, dcbcfg);
 531                         break;
 532                 default:
 533                         break;
 534                 }
 535 
 536                 /* Move to next TLV */
 537                 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
 538                                                     sizeof(tlv->typelength) +
 539                                                     length);
 540         }
 541 
 542         return ret;
 543 }
 544 
 545 /**
 546  * i40e_aq_get_dcb_config
 547  * @hw: pointer to the hw struct
 548  * @mib_type: mib type for the query
 549  * @bridgetype: bridge type for the query (remote)
 550  * @dcbcfg: store for LLDPDU data
 551  *
 552  * Query DCB configuration from the Firmware
 553  **/
 554 i40e_status i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
 555                                    u8 bridgetype,
 556                                    struct i40e_dcbx_config *dcbcfg)
 557 {
 558         i40e_status ret = 0;
 559         struct i40e_virt_mem mem;
 560         u8 *lldpmib;
 561 
 562         /* Allocate the LLDPDU */
 563         ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
 564         if (ret)
 565                 return ret;
 566 
 567         lldpmib = (u8 *)mem.va;
 568         ret = i40e_aq_get_lldp_mib(hw, bridgetype, mib_type,
 569                                    (void *)lldpmib, I40E_LLDPDU_SIZE,
 570                                    NULL, NULL, NULL);
 571         if (ret)
 572                 goto free_mem;
 573 
 574         /* Parse LLDP MIB to get dcb configuration */
 575         ret = i40e_lldp_to_dcb_config(lldpmib, dcbcfg);
 576 
 577 free_mem:
 578         i40e_free_virt_mem(hw, &mem);
 579         return ret;
 580 }
 581 
 582 /**
 583  * i40e_cee_to_dcb_v1_config
 584  * @cee_cfg: pointer to CEE v1 response configuration struct
 585  * @dcbcfg: DCB configuration struct
 586  *
 587  * Convert CEE v1 configuration from firmware to DCB configuration
 588  **/
 589 static void i40e_cee_to_dcb_v1_config(
 590                         struct i40e_aqc_get_cee_dcb_cfg_v1_resp *cee_cfg,
 591                         struct i40e_dcbx_config *dcbcfg)
 592 {
 593         u16 status, tlv_status = le16_to_cpu(cee_cfg->tlv_status);
 594         u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio);
 595         u8 i, tc, err;
 596 
 597         /* CEE PG data to ETS config */
 598         dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
 599 
 600         /* Note that the FW creates the oper_prio_tc nibbles reversed
 601          * from those in the CEE Priority Group sub-TLV.
 602          */
 603         for (i = 0; i < 4; i++) {
 604                 tc = (u8)((cee_cfg->oper_prio_tc[i] &
 605                          I40E_CEE_PGID_PRIO_0_MASK) >>
 606                          I40E_CEE_PGID_PRIO_0_SHIFT);
 607                 dcbcfg->etscfg.prioritytable[i * 2] =  tc;
 608                 tc = (u8)((cee_cfg->oper_prio_tc[i] &
 609                          I40E_CEE_PGID_PRIO_1_MASK) >>
 610                          I40E_CEE_PGID_PRIO_1_SHIFT);
 611                 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
 612         }
 613 
 614         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
 615                 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
 616 
 617         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
 618                 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
 619                         /* Map it to next empty TC */
 620                         dcbcfg->etscfg.prioritytable[i] =
 621                                                 cee_cfg->oper_num_tc - 1;
 622                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
 623                 } else {
 624                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
 625                 }
 626         }
 627 
 628         /* CEE PFC data to ETS config */
 629         dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
 630         dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
 631 
 632         status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
 633                   I40E_AQC_CEE_APP_STATUS_SHIFT;
 634         err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
 635         /* Add APPs if Error is False */
 636         if (!err) {
 637                 /* CEE operating configuration supports FCoE/iSCSI/FIP only */
 638                 dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
 639 
 640                 /* FCoE APP */
 641                 dcbcfg->app[0].priority =
 642                         (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
 643                          I40E_AQC_CEE_APP_FCOE_SHIFT;
 644                 dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
 645                 dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
 646 
 647                 /* iSCSI APP */
 648                 dcbcfg->app[1].priority =
 649                         (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
 650                          I40E_AQC_CEE_APP_ISCSI_SHIFT;
 651                 dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
 652                 dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
 653 
 654                 /* FIP APP */
 655                 dcbcfg->app[2].priority =
 656                         (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
 657                          I40E_AQC_CEE_APP_FIP_SHIFT;
 658                 dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
 659                 dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
 660         }
 661 }
 662 
 663 /**
 664  * i40e_cee_to_dcb_config
 665  * @cee_cfg: pointer to CEE configuration struct
 666  * @dcbcfg: DCB configuration struct
 667  *
 668  * Convert CEE configuration from firmware to DCB configuration
 669  **/
 670 static void i40e_cee_to_dcb_config(
 671                                 struct i40e_aqc_get_cee_dcb_cfg_resp *cee_cfg,
 672                                 struct i40e_dcbx_config *dcbcfg)
 673 {
 674         u32 status, tlv_status = le32_to_cpu(cee_cfg->tlv_status);
 675         u16 app_prio = le16_to_cpu(cee_cfg->oper_app_prio);
 676         u8 i, tc, err, sync, oper;
 677 
 678         /* CEE PG data to ETS config */
 679         dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
 680 
 681         /* Note that the FW creates the oper_prio_tc nibbles reversed
 682          * from those in the CEE Priority Group sub-TLV.
 683          */
 684         for (i = 0; i < 4; i++) {
 685                 tc = (u8)((cee_cfg->oper_prio_tc[i] &
 686                          I40E_CEE_PGID_PRIO_0_MASK) >>
 687                          I40E_CEE_PGID_PRIO_0_SHIFT);
 688                 dcbcfg->etscfg.prioritytable[i * 2] =  tc;
 689                 tc = (u8)((cee_cfg->oper_prio_tc[i] &
 690                          I40E_CEE_PGID_PRIO_1_MASK) >>
 691                          I40E_CEE_PGID_PRIO_1_SHIFT);
 692                 dcbcfg->etscfg.prioritytable[i * 2 + 1] = tc;
 693         }
 694 
 695         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
 696                 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
 697 
 698         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
 699                 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
 700                         /* Map it to next empty TC */
 701                         dcbcfg->etscfg.prioritytable[i] =
 702                                                 cee_cfg->oper_num_tc - 1;
 703                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
 704                 } else {
 705                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
 706                 }
 707         }
 708 
 709         /* CEE PFC data to ETS config */
 710         dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
 711         dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
 712 
 713         i = 0;
 714         status = (tlv_status & I40E_AQC_CEE_FCOE_STATUS_MASK) >>
 715                   I40E_AQC_CEE_FCOE_STATUS_SHIFT;
 716         err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
 717         sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
 718         oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
 719         /* Add FCoE APP if Error is False and Oper/Sync is True */
 720         if (!err && sync && oper) {
 721                 /* FCoE APP */
 722                 dcbcfg->app[i].priority =
 723                         (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
 724                          I40E_AQC_CEE_APP_FCOE_SHIFT;
 725                 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
 726                 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FCOE;
 727                 i++;
 728         }
 729 
 730         status = (tlv_status & I40E_AQC_CEE_ISCSI_STATUS_MASK) >>
 731                   I40E_AQC_CEE_ISCSI_STATUS_SHIFT;
 732         err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
 733         sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
 734         oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
 735         /* Add iSCSI APP if Error is False and Oper/Sync is True */
 736         if (!err && sync && oper) {
 737                 /* iSCSI APP */
 738                 dcbcfg->app[i].priority =
 739                         (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
 740                          I40E_AQC_CEE_APP_ISCSI_SHIFT;
 741                 dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
 742                 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_ISCSI;
 743                 i++;
 744         }
 745 
 746         status = (tlv_status & I40E_AQC_CEE_FIP_STATUS_MASK) >>
 747                   I40E_AQC_CEE_FIP_STATUS_SHIFT;
 748         err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
 749         sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
 750         oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
 751         /* Add FIP APP if Error is False and Oper/Sync is True */
 752         if (!err && sync && oper) {
 753                 /* FIP APP */
 754                 dcbcfg->app[i].priority =
 755                         (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
 756                          I40E_AQC_CEE_APP_FIP_SHIFT;
 757                 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
 758                 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FIP;
 759                 i++;
 760         }
 761         dcbcfg->numapps = i;
 762 }
 763 
 764 /**
 765  * i40e_get_ieee_dcb_config
 766  * @hw: pointer to the hw struct
 767  *
 768  * Get IEEE mode DCB configuration from the Firmware
 769  **/
 770 static i40e_status i40e_get_ieee_dcb_config(struct i40e_hw *hw)
 771 {
 772         i40e_status ret = 0;
 773 
 774         /* IEEE mode */
 775         hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
 776         /* Get Local DCB Config */
 777         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
 778                                      &hw->local_dcbx_config);
 779         if (ret)
 780                 goto out;
 781 
 782         /* Get Remote DCB Config */
 783         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
 784                                      I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
 785                                      &hw->remote_dcbx_config);
 786         /* Don't treat ENOENT as an error for Remote MIBs */
 787         if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
 788                 ret = 0;
 789 
 790 out:
 791         return ret;
 792 }
 793 
 794 /**
 795  * i40e_get_dcb_config
 796  * @hw: pointer to the hw struct
 797  *
 798  * Get DCB configuration from the Firmware
 799  **/
 800 i40e_status i40e_get_dcb_config(struct i40e_hw *hw)
 801 {
 802         i40e_status ret = 0;
 803         struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
 804         struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
 805 
 806         /* If Firmware version < v4.33 on X710/XL710, IEEE only */
 807         if ((hw->mac.type == I40E_MAC_XL710) &&
 808             (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
 809               (hw->aq.fw_maj_ver < 4)))
 810                 return i40e_get_ieee_dcb_config(hw);
 811 
 812         /* If Firmware version == v4.33 on X710/XL710, use old CEE struct */
 813         if ((hw->mac.type == I40E_MAC_XL710) &&
 814             ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33))) {
 815                 ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
 816                                                  sizeof(cee_v1_cfg), NULL);
 817                 if (!ret) {
 818                         /* CEE mode */
 819                         hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
 820                         hw->local_dcbx_config.tlv_status =
 821                                         le16_to_cpu(cee_v1_cfg.tlv_status);
 822                         i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
 823                                                   &hw->local_dcbx_config);
 824                 }
 825         } else {
 826                 ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
 827                                                  sizeof(cee_cfg), NULL);
 828                 if (!ret) {
 829                         /* CEE mode */
 830                         hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
 831                         hw->local_dcbx_config.tlv_status =
 832                                         le32_to_cpu(cee_cfg.tlv_status);
 833                         i40e_cee_to_dcb_config(&cee_cfg,
 834                                                &hw->local_dcbx_config);
 835                 }
 836         }
 837 
 838         /* CEE mode not enabled try querying IEEE data */
 839         if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
 840                 return i40e_get_ieee_dcb_config(hw);
 841 
 842         if (ret)
 843                 goto out;
 844 
 845         /* Get CEE DCB Desired Config */
 846         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
 847                                      &hw->desired_dcbx_config);
 848         if (ret)
 849                 goto out;
 850 
 851         /* Get Remote DCB Config */
 852         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
 853                                      I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
 854                                      &hw->remote_dcbx_config);
 855         /* Don't treat ENOENT as an error for Remote MIBs */
 856         if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
 857                 ret = 0;
 858 
 859 out:
 860         return ret;
 861 }
 862 
 863 /**
 864  * i40e_init_dcb
 865  * @hw: pointer to the hw struct
 866  * @enable_mib_change: enable mib change event
 867  *
 868  * Update DCB configuration from the Firmware
 869  **/
 870 i40e_status i40e_init_dcb(struct i40e_hw *hw, bool enable_mib_change)
 871 {
 872         i40e_status ret = 0;
 873         struct i40e_lldp_variables lldp_cfg;
 874         u8 adminstatus = 0;
 875 
 876         if (!hw->func_caps.dcb)
 877                 return I40E_NOT_SUPPORTED;
 878 
 879         /* Read LLDP NVM area */
 880         if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT) {
 881                 u8 offset = 0;
 882 
 883                 if (hw->mac.type == I40E_MAC_XL710)
 884                         offset = I40E_LLDP_CURRENT_STATUS_XL710_OFFSET;
 885                 else if (hw->mac.type == I40E_MAC_X722)
 886                         offset = I40E_LLDP_CURRENT_STATUS_X722_OFFSET;
 887                 else
 888                         return I40E_NOT_SUPPORTED;
 889 
 890                 ret = i40e_read_nvm_module_data(hw,
 891                                                 I40E_SR_EMP_SR_SETTINGS_PTR,
 892                                                 offset, 1,
 893                                                 &lldp_cfg.adminstatus);
 894         } else {
 895                 ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
 896         }
 897         if (ret)
 898                 return I40E_ERR_NOT_READY;
 899 
 900         /* Get the LLDP AdminStatus for the current port */
 901         adminstatus = lldp_cfg.adminstatus >> (hw->port * 4);
 902         adminstatus &= 0xF;
 903 
 904         /* LLDP agent disabled */
 905         if (!adminstatus) {
 906                 hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
 907                 return I40E_ERR_NOT_READY;
 908         }
 909 
 910         /* Get DCBX status */
 911         ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
 912         if (ret)
 913                 return ret;
 914 
 915         /* Check the DCBX Status */
 916         if (hw->dcbx_status == I40E_DCBX_STATUS_DONE ||
 917             hw->dcbx_status == I40E_DCBX_STATUS_IN_PROGRESS) {
 918                 /* Get current DCBX configuration */
 919                 ret = i40e_get_dcb_config(hw);
 920                 if (ret)
 921                         return ret;
 922         } else if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) {
 923                 return I40E_ERR_NOT_READY;
 924         }
 925 
 926         /* Configure the LLDP MIB change event */
 927         if (enable_mib_change)
 928                 ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
 929 
 930         return ret;
 931 }
 932 
 933 /**
 934  * _i40e_read_lldp_cfg - generic read of LLDP Configuration data from NVM
 935  * @hw: pointer to the HW structure
 936  * @lldp_cfg: pointer to hold lldp configuration variables
 937  * @module: address of the module pointer
 938  * @word_offset: offset of LLDP configuration
 939  *
 940  * Reads the LLDP configuration data from NVM using passed addresses
 941  **/
 942 static i40e_status _i40e_read_lldp_cfg(struct i40e_hw *hw,
 943                                        struct i40e_lldp_variables *lldp_cfg,
 944                                        u8 module, u32 word_offset)
 945 {
 946         u32 address, offset = (2 * word_offset);
 947         i40e_status ret;
 948         __le16 raw_mem;
 949         u16 mem;
 950 
 951         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
 952         if (ret)
 953                 return ret;
 954 
 955         ret = i40e_aq_read_nvm(hw, 0x0, module * 2, sizeof(raw_mem), &raw_mem,
 956                                true, NULL);
 957         i40e_release_nvm(hw);
 958         if (ret)
 959                 return ret;
 960 
 961         mem = le16_to_cpu(raw_mem);
 962         /* Check if this pointer needs to be read in word size or 4K sector
 963          * units.
 964          */
 965         if (mem & I40E_PTR_TYPE)
 966                 address = (0x7FFF & mem) * 4096;
 967         else
 968                 address = (0x7FFF & mem) * 2;
 969 
 970         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
 971         if (ret)
 972                 goto err_lldp_cfg;
 973 
 974         ret = i40e_aq_read_nvm(hw, module, offset, sizeof(raw_mem), &raw_mem,
 975                                true, NULL);
 976         i40e_release_nvm(hw);
 977         if (ret)
 978                 return ret;
 979 
 980         mem = le16_to_cpu(raw_mem);
 981         offset = mem + word_offset;
 982         offset *= 2;
 983 
 984         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
 985         if (ret)
 986                 goto err_lldp_cfg;
 987 
 988         ret = i40e_aq_read_nvm(hw, 0, address + offset,
 989                                sizeof(struct i40e_lldp_variables), lldp_cfg,
 990                                true, NULL);
 991         i40e_release_nvm(hw);
 992 
 993 err_lldp_cfg:
 994         return ret;
 995 }
 996 
 997 /**
 998  * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
 999  * @hw: pointer to the HW structure
1000  * @lldp_cfg: pointer to hold lldp configuration variables
1001  *
1002  * Reads the LLDP configuration data from NVM
1003  **/
1004 i40e_status i40e_read_lldp_cfg(struct i40e_hw *hw,
1005                                struct i40e_lldp_variables *lldp_cfg)
1006 {
1007         i40e_status ret = 0;
1008         u32 mem;
1009 
1010         if (!lldp_cfg)
1011                 return I40E_ERR_PARAM;
1012 
1013         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
1014         if (ret)
1015                 return ret;
1016 
1017         ret = i40e_aq_read_nvm(hw, I40E_SR_NVM_CONTROL_WORD, 0, sizeof(mem),
1018                                &mem, true, NULL);
1019         i40e_release_nvm(hw);
1020         if (ret)
1021                 return ret;
1022 
1023         /* Read a bit that holds information whether we are running flat or
1024          * structured NVM image. Flat image has LLDP configuration in shadow
1025          * ram, so there is a need to pass different addresses for both cases.
1026          */
1027         if (mem & I40E_SR_NVM_MAP_STRUCTURE_TYPE) {
1028                 /* Flat NVM case */
1029                 ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_SR_EMP_MODULE_PTR,
1030                                           I40E_SR_LLDP_CFG_PTR);
1031         } else {
1032                 /* Good old structured NVM image */
1033                 ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_EMP_MODULE_PTR,
1034                                           I40E_NVM_LLDP_CFG_PTR);
1035         }
1036 
1037         return ret;
1038 }

/* [<][>][^][v][top][bottom][index][help] */