LCOV - code coverage report
Current view: top level - drivers/net/i40e/base - i40e_dcb.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 457 0.0 %
Date: 2024-12-01 18:57:19 Functions: 0 25 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 240 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2001-2020 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "i40e_adminq.h"
       6                 :            : #include "i40e_prototype.h"
       7                 :            : #include "i40e_dcb.h"
       8                 :            : 
       9                 :            : /**
      10                 :            :  * i40e_get_dcbx_status
      11                 :            :  * @hw: pointer to the hw struct
      12                 :            :  * @status: Embedded DCBX Engine Status
      13                 :            :  *
      14                 :            :  * Get the DCBX status from the Firmware
      15                 :            :  **/
      16                 :          0 : enum i40e_status_code i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status)
      17                 :            : {
      18                 :            :         u32 reg;
      19                 :            : 
      20         [ #  # ]:          0 :         if (!status)
      21                 :            :                 return I40E_ERR_PARAM;
      22                 :            : 
      23                 :          0 :         reg = rd32(hw, I40E_PRTDCB_GENS);
      24                 :          0 :         *status = (u16)((reg & I40E_PRTDCB_GENS_DCBX_STATUS_MASK) >>
      25                 :            :                         I40E_PRTDCB_GENS_DCBX_STATUS_SHIFT);
      26                 :            : 
      27                 :          0 :         return I40E_SUCCESS;
      28                 :            : }
      29                 :            : 
      30                 :            : /**
      31                 :            :  * i40e_parse_ieee_etscfg_tlv
      32                 :            :  * @tlv: IEEE 802.1Qaz ETS CFG TLV
      33                 :            :  * @dcbcfg: Local store to update ETS CFG data
      34                 :            :  *
      35                 :            :  * Parses IEEE 802.1Qaz ETS CFG TLV
      36                 :            :  **/
      37                 :          0 : static void i40e_parse_ieee_etscfg_tlv(struct i40e_lldp_org_tlv *tlv,
      38                 :            :                                        struct i40e_dcbx_config *dcbcfg)
      39                 :            : {
      40                 :            :         struct i40e_dcb_ets_config *etscfg;
      41                 :          0 :         u8 *buf = tlv->tlvinfo;
      42                 :            :         u16 offset = 0;
      43                 :            :         u8 priority;
      44                 :            :         int i;
      45                 :            : 
      46                 :            :         /* First Octet post subtype
      47                 :            :          * --------------------------
      48                 :            :          * |will-|CBS  | Re-  | Max |
      49                 :            :          * |ing  |     |served| TCs |
      50                 :            :          * --------------------------
      51                 :            :          * |1bit | 1bit|3 bits|3bits|
      52                 :            :          */
      53                 :            :         etscfg = &dcbcfg->etscfg;
      54                 :          0 :         etscfg->willing = (u8)((buf[offset] & I40E_IEEE_ETS_WILLING_MASK) >>
      55                 :            :                                I40E_IEEE_ETS_WILLING_SHIFT);
      56                 :          0 :         etscfg->cbs = (u8)((buf[offset] & I40E_IEEE_ETS_CBS_MASK) >>
      57                 :            :                            I40E_IEEE_ETS_CBS_SHIFT);
      58                 :          0 :         etscfg->maxtcs = (u8)((buf[offset] & I40E_IEEE_ETS_MAXTC_MASK) >>
      59                 :            :                               I40E_IEEE_ETS_MAXTC_SHIFT);
      60                 :            : 
      61                 :            :         /* Move offset to Priority Assignment Table */
      62                 :            :         offset++;
      63                 :            : 
      64                 :            :         /* Priority Assignment Table (4 octets)
      65                 :            :          * Octets:|    1    |    2    |    3    |    4    |
      66                 :            :          *        -----------------------------------------
      67                 :            :          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
      68                 :            :          *        -----------------------------------------
      69                 :            :          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
      70                 :            :          *        -----------------------------------------
      71                 :            :          */
      72         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
      73                 :          0 :                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
      74                 :            :                                 I40E_IEEE_ETS_PRIO_1_SHIFT);
      75                 :          0 :                 etscfg->prioritytable[i * 2] =  priority;
      76                 :          0 :                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
      77                 :            :                                 I40E_IEEE_ETS_PRIO_0_SHIFT);
      78                 :          0 :                 etscfg->prioritytable[i * 2 + 1] = priority;
      79                 :          0 :                 offset++;
      80                 :            :         }
      81                 :            : 
      82                 :            :         /* TC Bandwidth Table (8 octets)
      83                 :            :          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
      84                 :            :          *        ---------------------------------
      85                 :            :          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
      86                 :            :          *        ---------------------------------
      87                 :            :          */
      88         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
      89                 :          0 :                 etscfg->tcbwtable[i] = buf[offset++];
      90                 :            : 
      91                 :            :         /* TSA Assignment Table (8 octets)
      92                 :            :          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
      93                 :            :          *        ---------------------------------
      94                 :            :          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
      95                 :            :          *        ---------------------------------
      96                 :            :          */
      97         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
      98                 :          0 :                 etscfg->tsatable[i] = buf[offset++];
      99                 :          0 : }
     100                 :            : 
     101                 :            : /**
     102                 :            :  * i40e_parse_ieee_etsrec_tlv
     103                 :            :  * @tlv: IEEE 802.1Qaz ETS REC TLV
     104                 :            :  * @dcbcfg: Local store to update ETS REC data
     105                 :            :  *
     106                 :            :  * Parses IEEE 802.1Qaz ETS REC TLV
     107                 :            :  **/
     108                 :          0 : static void i40e_parse_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
     109                 :            :                                        struct i40e_dcbx_config *dcbcfg)
     110                 :            : {
     111                 :          0 :         u8 *buf = tlv->tlvinfo;
     112                 :            :         u16 offset = 0;
     113                 :            :         u8 priority;
     114                 :            :         int i;
     115                 :            : 
     116                 :            :         /* Move offset to priority table */
     117                 :            :         offset++;
     118                 :            : 
     119                 :            :         /* Priority Assignment Table (4 octets)
     120                 :            :          * Octets:|    1    |    2    |    3    |    4    |
     121                 :            :          *        -----------------------------------------
     122                 :            :          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
     123                 :            :          *        -----------------------------------------
     124                 :            :          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
     125                 :            :          *        -----------------------------------------
     126                 :            :          */
     127         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
     128                 :          0 :                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_1_MASK) >>
     129                 :            :                                 I40E_IEEE_ETS_PRIO_1_SHIFT);
     130                 :          0 :                 dcbcfg->etsrec.prioritytable[i*2] =  priority;
     131                 :          0 :                 priority = (u8)((buf[offset] & I40E_IEEE_ETS_PRIO_0_MASK) >>
     132                 :            :                                 I40E_IEEE_ETS_PRIO_0_SHIFT);
     133                 :          0 :                 dcbcfg->etsrec.prioritytable[i*2 + 1] = priority;
     134                 :          0 :                 offset++;
     135                 :            :         }
     136                 :            : 
     137                 :            :         /* TC Bandwidth Table (8 octets)
     138                 :            :          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
     139                 :            :          *        ---------------------------------
     140                 :            :          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
     141                 :            :          *        ---------------------------------
     142                 :            :          */
     143         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
     144                 :          0 :                 dcbcfg->etsrec.tcbwtable[i] = buf[offset++];
     145                 :            : 
     146                 :            :         /* TSA Assignment Table (8 octets)
     147                 :            :          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
     148                 :            :          *        ---------------------------------
     149                 :            :          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
     150                 :            :          *        ---------------------------------
     151                 :            :          */
     152         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
     153                 :          0 :                 dcbcfg->etsrec.tsatable[i] = buf[offset++];
     154                 :          0 : }
     155                 :            : 
     156                 :            : /**
     157                 :            :  * i40e_parse_ieee_pfccfg_tlv
     158                 :            :  * @tlv: IEEE 802.1Qaz PFC CFG TLV
     159                 :            :  * @dcbcfg: Local store to update PFC CFG data
     160                 :            :  *
     161                 :            :  * Parses IEEE 802.1Qaz PFC CFG TLV
     162                 :            :  **/
     163                 :            : static void i40e_parse_ieee_pfccfg_tlv(struct i40e_lldp_org_tlv *tlv,
     164                 :            :                                        struct i40e_dcbx_config *dcbcfg)
     165                 :            : {
     166                 :            :         u8 *buf = tlv->tlvinfo;
     167                 :            : 
     168                 :            :         /* ----------------------------------------
     169                 :            :          * |will-|MBC  | Re-  | PFC |  PFC Enable  |
     170                 :            :          * |ing  |     |served| cap |              |
     171                 :            :          * -----------------------------------------
     172                 :            :          * |1bit | 1bit|2 bits|4bits| 1 octet      |
     173                 :            :          */
     174                 :          0 :         dcbcfg->pfc.willing = (u8)((buf[0] & I40E_IEEE_PFC_WILLING_MASK) >>
     175                 :            :                                    I40E_IEEE_PFC_WILLING_SHIFT);
     176                 :          0 :         dcbcfg->pfc.mbc = (u8)((buf[0] & I40E_IEEE_PFC_MBC_MASK) >>
     177                 :            :                                I40E_IEEE_PFC_MBC_SHIFT);
     178                 :          0 :         dcbcfg->pfc.pfccap = (u8)((buf[0] & I40E_IEEE_PFC_CAP_MASK) >>
     179                 :            :                                   I40E_IEEE_PFC_CAP_SHIFT);
     180                 :          0 :         dcbcfg->pfc.pfcenable = buf[1];
     181                 :          0 : }
     182                 :            : 
     183                 :            : /**
     184                 :            :  * i40e_parse_ieee_app_tlv
     185                 :            :  * @tlv: IEEE 802.1Qaz APP TLV
     186                 :            :  * @dcbcfg: Local store to update APP PRIO data
     187                 :            :  *
     188                 :            :  * Parses IEEE 802.1Qaz APP PRIO TLV
     189                 :            :  **/
     190                 :          0 : static void i40e_parse_ieee_app_tlv(struct i40e_lldp_org_tlv *tlv,
     191                 :            :                                     struct i40e_dcbx_config *dcbcfg)
     192                 :            : {
     193                 :            :         u16 typelength;
     194                 :            :         u16 offset = 0;
     195                 :            :         u16 length;
     196                 :            :         int i = 0;
     197                 :            :         u8 *buf;
     198                 :            : 
     199         [ #  # ]:          0 :         typelength = I40E_NTOHS(tlv->typelength);
     200                 :          0 :         length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
     201                 :            :                        I40E_LLDP_TLV_LEN_SHIFT);
     202                 :          0 :         buf = tlv->tlvinfo;
     203                 :            : 
     204                 :            :         /* The App priority table starts 5 octets after TLV header */
     205                 :          0 :         length -= (sizeof(tlv->ouisubtype) + 1);
     206                 :            : 
     207                 :            :         /* Move offset to App Priority Table */
     208                 :            :         offset++;
     209                 :            : 
     210                 :            :         /* Application Priority Table (3 octets)
     211                 :            :          * Octets:|         1          |    2    |    3    |
     212                 :            :          *        -----------------------------------------
     213                 :            :          *        |Priority|Rsrvd| Sel |    Protocol ID    |
     214                 :            :          *        -----------------------------------------
     215                 :            :          *   Bits:|23    21|20 19|18 16|15                0|
     216                 :            :          *        -----------------------------------------
     217                 :            :          */
     218         [ #  # ]:          0 :         while (offset < length) {
     219                 :          0 :                 dcbcfg->app[i].priority = (u8)((buf[offset] &
     220                 :          0 :                                                 I40E_IEEE_APP_PRIO_MASK) >>
     221                 :            :                                                I40E_IEEE_APP_PRIO_SHIFT);
     222                 :          0 :                 dcbcfg->app[i].selector = (u8)((buf[offset] &
     223                 :            :                                                 I40E_IEEE_APP_SEL_MASK) >>
     224                 :            :                                                I40E_IEEE_APP_SEL_SHIFT);
     225                 :          0 :                 dcbcfg->app[i].protocolid = (buf[offset + 1] << 0x8) |
     226                 :          0 :                                              buf[offset + 2];
     227                 :            :                 /* Move to next app */
     228                 :          0 :                 offset += 3;
     229                 :          0 :                 i++;
     230         [ #  # ]:          0 :                 if (i >= I40E_DCBX_MAX_APPS)
     231                 :            :                         break;
     232                 :            :         }
     233                 :            : 
     234                 :          0 :         dcbcfg->numapps = i;
     235                 :          0 : }
     236                 :            : 
     237                 :            : /**
     238                 :            :  * i40e_parse_ieee_tlv
     239                 :            :  * @tlv: IEEE 802.1Qaz TLV
     240                 :            :  * @dcbcfg: Local store to update ETS REC data
     241                 :            :  *
     242                 :            :  * Get the TLV subtype and send it to parsing function
     243                 :            :  * based on the subtype value
     244                 :            :  **/
     245                 :          0 : static void i40e_parse_ieee_tlv(struct i40e_lldp_org_tlv *tlv,
     246                 :            :                                 struct i40e_dcbx_config *dcbcfg)
     247                 :            : {
     248                 :            :         u32 ouisubtype;
     249                 :            :         u8 subtype;
     250                 :            : 
     251         [ #  # ]:          0 :         ouisubtype = I40E_NTOHL(tlv->ouisubtype);
     252                 :            :         subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
     253                 :            :                        I40E_LLDP_TLV_SUBTYPE_SHIFT);
     254   [ #  #  #  #  :          0 :         switch (subtype) {
                      # ]
     255                 :          0 :         case I40E_IEEE_SUBTYPE_ETS_CFG:
     256                 :          0 :                 i40e_parse_ieee_etscfg_tlv(tlv, dcbcfg);
     257                 :          0 :                 break;
     258                 :          0 :         case I40E_IEEE_SUBTYPE_ETS_REC:
     259                 :          0 :                 i40e_parse_ieee_etsrec_tlv(tlv, dcbcfg);
     260                 :          0 :                 break;
     261                 :            :         case I40E_IEEE_SUBTYPE_PFC_CFG:
     262                 :            :                 i40e_parse_ieee_pfccfg_tlv(tlv, dcbcfg);
     263                 :            :                 break;
     264                 :          0 :         case I40E_IEEE_SUBTYPE_APP_PRI:
     265                 :          0 :                 i40e_parse_ieee_app_tlv(tlv, dcbcfg);
     266                 :          0 :                 break;
     267                 :            :         default:
     268                 :            :                 break;
     269                 :            :         }
     270                 :          0 : }
     271                 :            : 
     272                 :            : /**
     273                 :            :  * i40e_parse_cee_pgcfg_tlv
     274                 :            :  * @tlv: CEE DCBX PG CFG TLV
     275                 :            :  * @dcbcfg: Local store to update ETS CFG data
     276                 :            :  *
     277                 :            :  * Parses CEE DCBX PG CFG TLV
     278                 :            :  **/
     279                 :          0 : static void i40e_parse_cee_pgcfg_tlv(struct i40e_cee_feat_tlv *tlv,
     280                 :            :                                      struct i40e_dcbx_config *dcbcfg)
     281                 :            : {
     282                 :            :         struct i40e_dcb_ets_config *etscfg;
     283                 :          0 :         u8 *buf = tlv->tlvinfo;
     284                 :            :         u16 offset = 0;
     285                 :            :         u8 priority;
     286                 :            :         int i;
     287                 :            : 
     288                 :            :         etscfg = &dcbcfg->etscfg;
     289                 :            : 
     290         [ #  # ]:          0 :         if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
     291                 :          0 :                 etscfg->willing = 1;
     292                 :            : 
     293                 :          0 :         etscfg->cbs = 0;
     294                 :            :         /* Priority Group Table (4 octets)
     295                 :            :          * Octets:|    1    |    2    |    3    |    4    |
     296                 :            :          *        -----------------------------------------
     297                 :            :          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
     298                 :            :          *        -----------------------------------------
     299                 :            :          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
     300                 :            :          *        -----------------------------------------
     301                 :            :          */
     302         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
     303                 :          0 :                 priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_1_MASK) >>
     304                 :            :                                  I40E_CEE_PGID_PRIO_1_SHIFT);
     305                 :          0 :                 etscfg->prioritytable[i * 2] =  priority;
     306                 :          0 :                 priority = (u8)((buf[offset] & I40E_CEE_PGID_PRIO_0_MASK) >>
     307                 :            :                                  I40E_CEE_PGID_PRIO_0_SHIFT);
     308                 :          0 :                 etscfg->prioritytable[i * 2 + 1] = priority;
     309                 :          0 :                 offset++;
     310                 :            :         }
     311                 :            : 
     312                 :            :         /* PG Percentage Table (8 octets)
     313                 :            :          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
     314                 :            :          *        ---------------------------------
     315                 :            :          *        |pg0|pg1|pg2|pg3|pg4|pg5|pg6|pg7|
     316                 :            :          *        ---------------------------------
     317                 :            :          */
     318         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
     319                 :          0 :                 etscfg->tcbwtable[i] = buf[offset++];
     320                 :            : 
     321         [ #  # ]:          0 :                 if (etscfg->prioritytable[i] == I40E_CEE_PGID_STRICT)
     322                 :          0 :                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
     323                 :            :                 else
     324                 :          0 :                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
     325                 :            :         }
     326                 :            : 
     327                 :            :         /* Number of TCs supported (1 octet) */
     328                 :          0 :         etscfg->maxtcs = buf[offset];
     329                 :          0 : }
     330                 :            : 
     331                 :            : /**
     332                 :            :  * i40e_parse_cee_pfccfg_tlv
     333                 :            :  * @tlv: CEE DCBX PFC CFG TLV
     334                 :            :  * @dcbcfg: Local store to update PFC CFG data
     335                 :            :  *
     336                 :            :  * Parses CEE DCBX PFC CFG TLV
     337                 :            :  **/
     338                 :            : static void i40e_parse_cee_pfccfg_tlv(struct i40e_cee_feat_tlv *tlv,
     339                 :            :                                       struct i40e_dcbx_config *dcbcfg)
     340                 :            : {
     341                 :            :         u8 *buf = tlv->tlvinfo;
     342                 :            : 
     343         [ #  # ]:          0 :         if (tlv->en_will_err & I40E_CEE_FEAT_TLV_WILLING_MASK)
     344                 :          0 :                 dcbcfg->pfc.willing = 1;
     345                 :            : 
     346                 :            :         /* ------------------------
     347                 :            :          * | PFC Enable | PFC TCs |
     348                 :            :          * ------------------------
     349                 :            :          * | 1 octet    | 1 octet |
     350                 :            :          */
     351                 :          0 :         dcbcfg->pfc.pfcenable = buf[0];
     352                 :          0 :         dcbcfg->pfc.pfccap = buf[1];
     353                 :          0 : }
     354                 :            : 
     355                 :            : /**
     356                 :            :  * i40e_parse_cee_app_tlv
     357                 :            :  * @tlv: CEE DCBX APP TLV
     358                 :            :  * @dcbcfg: Local store to update APP PRIO data
     359                 :            :  *
     360                 :            :  * Parses CEE DCBX APP PRIO TLV
     361                 :            :  **/
     362                 :          0 : static void i40e_parse_cee_app_tlv(struct i40e_cee_feat_tlv *tlv,
     363                 :            :                                    struct i40e_dcbx_config *dcbcfg)
     364                 :            : {
     365                 :            :         u16 length, typelength, offset = 0;
     366                 :            :         struct i40e_cee_app_prio *app;
     367                 :            :         u8 i;
     368                 :            : 
     369         [ #  # ]:          0 :         typelength = I40E_NTOHS(tlv->hdr.typelen);
     370                 :          0 :         length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
     371                 :            :                        I40E_LLDP_TLV_LEN_SHIFT);
     372                 :            : 
     373                 :          0 :         dcbcfg->numapps = length / sizeof(*app);
     374         [ #  # ]:          0 :         if (!dcbcfg->numapps)
     375                 :            :                 return;
     376         [ #  # ]:          0 :         if (dcbcfg->numapps > I40E_DCBX_MAX_APPS)
     377                 :          0 :                 dcbcfg->numapps = I40E_DCBX_MAX_APPS;
     378                 :            : 
     379         [ #  # ]:          0 :         for (i = 0; i < dcbcfg->numapps; i++) {
     380                 :            :                 u8 up, selector;
     381                 :            : 
     382                 :          0 :                 app = (struct i40e_cee_app_prio *)(tlv->tlvinfo + offset);
     383         [ #  # ]:          0 :                 for (up = 0; up < I40E_MAX_USER_PRIORITY; up++) {
     384         [ #  # ]:          0 :                         if (app->prio_map & BIT(up))
     385                 :            :                                 break;
     386                 :            :                 }
     387                 :          0 :                 dcbcfg->app[i].priority = up;
     388                 :            : 
     389                 :            :                 /* Get Selector from lower 2 bits, and convert to IEEE */
     390                 :          0 :                 selector = (app->upper_oui_sel & I40E_CEE_APP_SELECTOR_MASK);
     391      [ #  #  # ]:          0 :                 switch (selector) {
     392                 :          0 :                 case I40E_CEE_APP_SEL_ETHTYPE:
     393                 :          0 :                         dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
     394                 :          0 :                         break;
     395                 :          0 :                 case I40E_CEE_APP_SEL_TCPIP:
     396                 :          0 :                         dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
     397                 :          0 :                         break;
     398                 :          0 :                 default:
     399                 :            :                         /* Keep selector as it is for unknown types */
     400                 :          0 :                         dcbcfg->app[i].selector = selector;
     401                 :            :                 }
     402                 :            : 
     403         [ #  # ]:          0 :                 dcbcfg->app[i].protocolid = I40E_NTOHS(app->protocol);
     404                 :            :                 /* Move to next app */
     405                 :          0 :                 offset += sizeof(*app);
     406                 :            :         }
     407                 :            : }
     408                 :            : 
     409                 :            : /**
     410                 :            :  * i40e_parse_cee_tlv
     411                 :            :  * @tlv: CEE DCBX TLV
     412                 :            :  * @dcbcfg: Local store to update DCBX config data
     413                 :            :  *
     414                 :            :  * Get the TLV subtype and send it to parsing function
     415                 :            :  * based on the subtype value
     416                 :            :  **/
     417                 :          0 : static void i40e_parse_cee_tlv(struct i40e_lldp_org_tlv *tlv,
     418                 :            :                                struct i40e_dcbx_config *dcbcfg)
     419                 :            : {
     420                 :            :         u16 len, tlvlen, sublen, typelength;
     421                 :            :         struct i40e_cee_feat_tlv *sub_tlv;
     422                 :            :         u8 subtype, feat_tlv_count = 0;
     423                 :            :         u32 ouisubtype;
     424                 :            : 
     425         [ #  # ]:          0 :         ouisubtype = I40E_NTOHL(tlv->ouisubtype);
     426                 :          0 :         subtype = (u8)((ouisubtype & I40E_LLDP_TLV_SUBTYPE_MASK) >>
     427                 :            :                        I40E_LLDP_TLV_SUBTYPE_SHIFT);
     428                 :            :         /* Return if not CEE DCBX */
     429         [ #  # ]:          0 :         if (subtype != I40E_CEE_DCBX_TYPE)
     430                 :            :                 return;
     431                 :            : 
     432         [ #  # ]:          0 :         typelength = I40E_NTOHS(tlv->typelength);
     433                 :          0 :         tlvlen = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
     434                 :            :                         I40E_LLDP_TLV_LEN_SHIFT);
     435                 :            :         len = sizeof(tlv->typelength) + sizeof(ouisubtype) +
     436                 :            :               sizeof(struct i40e_cee_ctrl_tlv);
     437                 :            :         /* Return if no CEE DCBX Feature TLVs */
     438         [ #  # ]:          0 :         if (tlvlen <= len)
     439                 :            :                 return;
     440                 :            : 
     441                 :          0 :         sub_tlv = (struct i40e_cee_feat_tlv *)((char *)tlv + len);
     442         [ #  # ]:          0 :         while (feat_tlv_count < I40E_CEE_MAX_FEAT_TYPE) {
     443         [ #  # ]:          0 :                 typelength = I40E_NTOHS(sub_tlv->hdr.typelen);
     444                 :          0 :                 sublen = (u16)((typelength &
     445                 :            :                                 I40E_LLDP_TLV_LEN_MASK) >>
     446                 :            :                                 I40E_LLDP_TLV_LEN_SHIFT);
     447                 :          0 :                 subtype = (u8)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
     448                 :            :                                 I40E_LLDP_TLV_TYPE_SHIFT);
     449   [ #  #  #  # ]:          0 :                 switch (subtype) {
     450                 :          0 :                 case I40E_CEE_SUBTYPE_PG_CFG:
     451                 :          0 :                         i40e_parse_cee_pgcfg_tlv(sub_tlv, dcbcfg);
     452                 :          0 :                         break;
     453                 :            :                 case I40E_CEE_SUBTYPE_PFC_CFG:
     454                 :            :                         i40e_parse_cee_pfccfg_tlv(sub_tlv, dcbcfg);
     455                 :            :                         break;
     456                 :          0 :                 case I40E_CEE_SUBTYPE_APP_PRI:
     457                 :          0 :                         i40e_parse_cee_app_tlv(sub_tlv, dcbcfg);
     458                 :          0 :                         break;
     459                 :            :                 default:
     460                 :            :                         return; /* Invalid Sub-type return */
     461                 :            :                 }
     462                 :          0 :                 feat_tlv_count++;
     463                 :            :                 /* Move to next sub TLV */
     464                 :          0 :                 sub_tlv = (struct i40e_cee_feat_tlv *)((char *)sub_tlv +
     465                 :          0 :                                                 sizeof(sub_tlv->hdr.typelen) +
     466                 :            :                                                 sublen);
     467                 :            :         }
     468                 :            : }
     469                 :            : 
     470                 :            : /**
     471                 :            :  * i40e_parse_org_tlv
     472                 :            :  * @tlv: Organization specific TLV
     473                 :            :  * @dcbcfg: Local store to update ETS REC data
     474                 :            :  *
     475                 :            :  * Currently only IEEE 802.1Qaz TLV is supported, all others
     476                 :            :  * will be returned
     477                 :            :  **/
     478                 :          0 : static void i40e_parse_org_tlv(struct i40e_lldp_org_tlv *tlv,
     479                 :            :                                struct i40e_dcbx_config *dcbcfg)
     480                 :            : {
     481                 :            :         u32 ouisubtype;
     482                 :            :         u32 oui;
     483                 :            : 
     484         [ #  # ]:          0 :         ouisubtype = I40E_NTOHL(tlv->ouisubtype);
     485                 :          0 :         oui = (u32)((ouisubtype & I40E_LLDP_TLV_OUI_MASK) >>
     486                 :            :                     I40E_LLDP_TLV_OUI_SHIFT);
     487      [ #  #  # ]:          0 :         switch (oui) {
     488                 :          0 :         case I40E_IEEE_8021QAZ_OUI:
     489                 :          0 :                 i40e_parse_ieee_tlv(tlv, dcbcfg);
     490                 :          0 :                 break;
     491                 :          0 :         case I40E_CEE_DCBX_OUI:
     492                 :          0 :                 i40e_parse_cee_tlv(tlv, dcbcfg);
     493                 :          0 :                 break;
     494                 :            :         default:
     495                 :            :                 break;
     496                 :            :         }
     497                 :          0 : }
     498                 :            : 
     499                 :            : /**
     500                 :            :  * i40e_lldp_to_dcb_config
     501                 :            :  * @lldpmib: LLDPDU to be parsed
     502                 :            :  * @dcbcfg: store for LLDPDU data
     503                 :            :  *
     504                 :            :  * Parse DCB configuration from the LLDPDU
     505                 :            :  **/
     506                 :          0 : enum i40e_status_code i40e_lldp_to_dcb_config(u8 *lldpmib,
     507                 :            :                                     struct i40e_dcbx_config *dcbcfg)
     508                 :            : {
     509                 :            :         enum i40e_status_code ret = I40E_SUCCESS;
     510                 :            :         struct i40e_lldp_org_tlv *tlv;
     511                 :            :         u16 type;
     512                 :            :         u16 length;
     513                 :            :         u16 typelength;
     514                 :            :         u16 offset = 0;
     515                 :            : 
     516         [ #  # ]:          0 :         if (!lldpmib || !dcbcfg)
     517                 :            :                 return I40E_ERR_PARAM;
     518                 :            : 
     519                 :            :         /* set to the start of LLDPDU */
     520                 :          0 :         lldpmib += I40E_LLDP_MIB_HLEN;
     521                 :            :         tlv = (struct i40e_lldp_org_tlv *)lldpmib;
     522                 :            :         while (1) {
     523         [ #  # ]:          0 :                 typelength = I40E_NTOHS(tlv->typelength);
     524                 :          0 :                 type = (u16)((typelength & I40E_LLDP_TLV_TYPE_MASK) >>
     525                 :            :                              I40E_LLDP_TLV_TYPE_SHIFT);
     526                 :          0 :                 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
     527                 :            :                                I40E_LLDP_TLV_LEN_SHIFT);
     528                 :          0 :                 offset += sizeof(typelength) + length;
     529                 :            : 
     530                 :            :                 /* END TLV or beyond LLDPDU size */
     531         [ #  # ]:          0 :                 if ((type == I40E_TLV_TYPE_END) || (offset > I40E_LLDPDU_SIZE))
     532                 :            :                         break;
     533                 :            : 
     534         [ #  # ]:          0 :                 switch (type) {
     535                 :          0 :                 case I40E_TLV_TYPE_ORG:
     536                 :          0 :                         i40e_parse_org_tlv(tlv, dcbcfg);
     537                 :          0 :                         break;
     538                 :            :                 default:
     539                 :            :                         break;
     540                 :            :                 }
     541                 :            : 
     542                 :            :                 /* Move to next TLV */
     543                 :          0 :                 tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
     544                 :          0 :                                                     sizeof(tlv->typelength) +
     545                 :            :                                                     length);
     546                 :            :         }
     547                 :            : 
     548                 :            :         return ret;
     549                 :            : }
     550                 :            : 
     551                 :            : /**
     552                 :            :  * i40e_aq_get_dcb_config
     553                 :            :  * @hw: pointer to the hw struct
     554                 :            :  * @mib_type: mib type for the query
     555                 :            :  * @bridgetype: bridge type for the query (remote)
     556                 :            :  * @dcbcfg: store for LLDPDU data
     557                 :            :  *
     558                 :            :  * Query DCB configuration from the Firmware
     559                 :            :  **/
     560                 :          0 : enum i40e_status_code i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type,
     561                 :            :                                    u8 bridgetype,
     562                 :            :                                    struct i40e_dcbx_config *dcbcfg)
     563                 :            : {
     564                 :            :         enum i40e_status_code ret = I40E_SUCCESS;
     565                 :            :         struct i40e_virt_mem mem;
     566                 :            :         u8 *lldpmib;
     567                 :            : 
     568                 :            :         /* Allocate the LLDPDU */
     569                 :          0 :         ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
     570         [ #  # ]:          0 :         if (ret)
     571                 :            :                 return ret;
     572                 :            : 
     573                 :          0 :         lldpmib = (u8 *)mem.va;
     574                 :          0 :         ret = i40e_aq_get_lldp_mib(hw, bridgetype, mib_type,
     575                 :            :                                    (void *)lldpmib, I40E_LLDPDU_SIZE,
     576                 :            :                                    NULL, NULL, NULL);
     577         [ #  # ]:          0 :         if (ret)
     578                 :          0 :                 goto free_mem;
     579                 :            : 
     580                 :            :         /* Parse LLDP MIB to get dcb configuration */
     581                 :          0 :         ret = i40e_lldp_to_dcb_config(lldpmib, dcbcfg);
     582                 :            : 
     583                 :          0 : free_mem:
     584                 :          0 :         i40e_free_virt_mem(hw, &mem);
     585                 :          0 :         return ret;
     586                 :            : }
     587                 :            : 
     588                 :            : /**
     589                 :            :  * i40e_cee_to_dcb_v1_config
     590                 :            :  * @cee_cfg: pointer to CEE v1 response configuration struct
     591                 :            :  * @dcbcfg: DCB configuration struct
     592                 :            :  *
     593                 :            :  * Convert CEE v1 configuration from firmware to DCB configuration
     594                 :            :  **/
     595                 :          0 : static void i40e_cee_to_dcb_v1_config(
     596                 :            :                         struct i40e_aqc_get_cee_dcb_cfg_v1_resp *cee_cfg,
     597                 :            :                         struct i40e_dcbx_config *dcbcfg)
     598                 :            : {
     599                 :          0 :         u16 status, tlv_status = LE16_TO_CPU(cee_cfg->tlv_status);
     600                 :          0 :         u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
     601                 :            :         u8 i, tc, err;
     602                 :            : 
     603                 :            :         /* CEE PG data to ETS config */
     604                 :          0 :         dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
     605                 :            : 
     606                 :            :         /* Note that the FW creates the oper_prio_tc nibbles reversed
     607                 :            :          * from those in the CEE Priority Group sub-TLV.
     608                 :            :          */
     609         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
     610                 :          0 :                 tc = (u8)((cee_cfg->oper_prio_tc[i] &
     611                 :            :                          I40E_CEE_PGID_PRIO_0_MASK) >>
     612                 :            :                          I40E_CEE_PGID_PRIO_0_SHIFT);
     613                 :          0 :                 dcbcfg->etscfg.prioritytable[i*2] =  tc;
     614                 :          0 :                 tc = (u8)((cee_cfg->oper_prio_tc[i] &
     615                 :            :                          I40E_CEE_PGID_PRIO_1_MASK) >>
     616                 :            :                          I40E_CEE_PGID_PRIO_1_SHIFT);
     617                 :          0 :                 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
     618                 :            :         }
     619                 :            : 
     620         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
     621                 :          0 :                 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
     622                 :            : 
     623         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
     624         [ #  # ]:          0 :                 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
     625                 :            :                         /* Map it to next empty TC */
     626                 :          0 :                         dcbcfg->etscfg.prioritytable[i] =
     627                 :          0 :                                                 cee_cfg->oper_num_tc - 1;
     628                 :          0 :                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
     629                 :            :                 } else {
     630                 :          0 :                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
     631                 :            :                 }
     632                 :            :         }
     633                 :            : 
     634                 :            :         /* CEE PFC data to ETS config */
     635                 :          0 :         dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
     636                 :          0 :         dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
     637                 :            : 
     638                 :          0 :         status = (tlv_status & I40E_AQC_CEE_APP_STATUS_MASK) >>
     639                 :            :                   I40E_AQC_CEE_APP_STATUS_SHIFT;
     640                 :          0 :         err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
     641                 :            :         /* Add APPs if Error is False */
     642         [ #  # ]:          0 :         if (!err) {
     643                 :            :                 /* CEE operating configuration supports FCoE/iSCSI/FIP only */
     644                 :          0 :                 dcbcfg->numapps = I40E_CEE_OPER_MAX_APPS;
     645                 :            : 
     646                 :            :                 /* FCoE APP */
     647                 :          0 :                 dcbcfg->app[0].priority =
     648                 :          0 :                         (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
     649                 :            :                          I40E_AQC_CEE_APP_FCOE_SHIFT;
     650                 :          0 :                 dcbcfg->app[0].selector = I40E_APP_SEL_ETHTYPE;
     651                 :          0 :                 dcbcfg->app[0].protocolid = I40E_APP_PROTOID_FCOE;
     652                 :            : 
     653                 :            :                 /* iSCSI APP */
     654                 :          0 :                 dcbcfg->app[1].priority =
     655                 :          0 :                         (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
     656                 :            :                          I40E_AQC_CEE_APP_ISCSI_SHIFT;
     657                 :          0 :                 dcbcfg->app[1].selector = I40E_APP_SEL_TCPIP;
     658                 :          0 :                 dcbcfg->app[1].protocolid = I40E_APP_PROTOID_ISCSI;
     659                 :            : 
     660                 :            :                 /* FIP APP */
     661                 :          0 :                 dcbcfg->app[2].priority =
     662                 :          0 :                         (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
     663                 :            :                          I40E_AQC_CEE_APP_FIP_SHIFT;
     664                 :          0 :                 dcbcfg->app[2].selector = I40E_APP_SEL_ETHTYPE;
     665                 :          0 :                 dcbcfg->app[2].protocolid = I40E_APP_PROTOID_FIP;
     666                 :            :         }
     667                 :          0 : }
     668                 :            : 
     669                 :            : /**
     670                 :            :  * i40e_cee_to_dcb_config
     671                 :            :  * @cee_cfg: pointer to CEE configuration struct
     672                 :            :  * @dcbcfg: DCB configuration struct
     673                 :            :  *
     674                 :            :  * Convert CEE configuration from firmware to DCB configuration
     675                 :            :  **/
     676                 :          0 : static void i40e_cee_to_dcb_config(
     677                 :            :                                 struct i40e_aqc_get_cee_dcb_cfg_resp *cee_cfg,
     678                 :            :                                 struct i40e_dcbx_config *dcbcfg)
     679                 :            : {
     680                 :          0 :         u32 status, tlv_status = LE32_TO_CPU(cee_cfg->tlv_status);
     681                 :          0 :         u16 app_prio = LE16_TO_CPU(cee_cfg->oper_app_prio);
     682                 :            :         u8 i, tc, err, sync, oper;
     683                 :            : 
     684                 :            :         /* CEE PG data to ETS config */
     685                 :          0 :         dcbcfg->etscfg.maxtcs = cee_cfg->oper_num_tc;
     686                 :            : 
     687                 :            :         /* Note that the FW creates the oper_prio_tc nibbles reversed
     688                 :            :          * from those in the CEE Priority Group sub-TLV.
     689                 :            :          */
     690         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
     691                 :          0 :                 tc = (u8)((cee_cfg->oper_prio_tc[i] &
     692                 :            :                          I40E_CEE_PGID_PRIO_0_MASK) >>
     693                 :            :                          I40E_CEE_PGID_PRIO_0_SHIFT);
     694                 :          0 :                 dcbcfg->etscfg.prioritytable[i*2] =  tc;
     695                 :          0 :                 tc = (u8)((cee_cfg->oper_prio_tc[i] &
     696                 :            :                          I40E_CEE_PGID_PRIO_1_MASK) >>
     697                 :            :                          I40E_CEE_PGID_PRIO_1_SHIFT);
     698                 :          0 :                 dcbcfg->etscfg.prioritytable[i*2 + 1] = tc;
     699                 :            :         }
     700                 :            : 
     701         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
     702                 :          0 :                 dcbcfg->etscfg.tcbwtable[i] = cee_cfg->oper_tc_bw[i];
     703                 :            : 
     704         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
     705         [ #  # ]:          0 :                 if (dcbcfg->etscfg.prioritytable[i] == I40E_CEE_PGID_STRICT) {
     706                 :            :                         /* Map it to next empty TC */
     707                 :          0 :                         dcbcfg->etscfg.prioritytable[i] =
     708                 :          0 :                                                 cee_cfg->oper_num_tc - 1;
     709                 :          0 :                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT;
     710                 :            :                 } else {
     711                 :          0 :                         dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS;
     712                 :            :                 }
     713                 :            :         }
     714                 :            : 
     715                 :            :         /* CEE PFC data to ETS config */
     716                 :          0 :         dcbcfg->pfc.pfcenable = cee_cfg->oper_pfc_en;
     717                 :          0 :         dcbcfg->pfc.pfccap = I40E_MAX_TRAFFIC_CLASS;
     718                 :            : 
     719                 :            :         i = 0;
     720                 :          0 :         status = (tlv_status & I40E_AQC_CEE_FCOE_STATUS_MASK) >>
     721                 :            :                   I40E_AQC_CEE_FCOE_STATUS_SHIFT;
     722                 :          0 :         err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
     723                 :          0 :         sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
     724                 :          0 :         oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
     725                 :            :         /* Add FCoE APP if Error is False and Oper/Sync is True */
     726   [ #  #  #  # ]:          0 :         if (!err && sync && oper) {
     727                 :            :                 /* FCoE APP */
     728                 :          0 :                 dcbcfg->app[i].priority =
     729                 :          0 :                         (app_prio & I40E_AQC_CEE_APP_FCOE_MASK) >>
     730                 :            :                          I40E_AQC_CEE_APP_FCOE_SHIFT;
     731                 :          0 :                 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
     732                 :          0 :                 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FCOE;
     733                 :            :                 i++;
     734                 :            :         }
     735                 :            : 
     736                 :          0 :         status = (tlv_status & I40E_AQC_CEE_ISCSI_STATUS_MASK) >>
     737                 :            :                   I40E_AQC_CEE_ISCSI_STATUS_SHIFT;
     738                 :          0 :         err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
     739                 :          0 :         sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
     740                 :          0 :         oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
     741                 :            :         /* Add iSCSI APP if Error is False and Oper/Sync is True */
     742   [ #  #  #  # ]:          0 :         if (!err && sync && oper) {
     743                 :            :                 /* iSCSI APP */
     744                 :          0 :                 dcbcfg->app[i].priority =
     745                 :          0 :                         (app_prio & I40E_AQC_CEE_APP_ISCSI_MASK) >>
     746                 :            :                          I40E_AQC_CEE_APP_ISCSI_SHIFT;
     747                 :          0 :                 dcbcfg->app[i].selector = I40E_APP_SEL_TCPIP;
     748                 :          0 :                 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_ISCSI;
     749                 :          0 :                 i++;
     750                 :            :         }
     751                 :            : 
     752                 :          0 :         status = (tlv_status & I40E_AQC_CEE_FIP_STATUS_MASK) >>
     753                 :            :                   I40E_AQC_CEE_FIP_STATUS_SHIFT;
     754                 :          0 :         err = (status & I40E_TLV_STATUS_ERR) ? 1 : 0;
     755                 :          0 :         sync = (status & I40E_TLV_STATUS_SYNC) ? 1 : 0;
     756                 :          0 :         oper = (status & I40E_TLV_STATUS_OPER) ? 1 : 0;
     757                 :            :         /* Add FIP APP if Error is False and Oper/Sync is True */
     758   [ #  #  #  # ]:          0 :         if (!err && sync && oper) {
     759                 :            :                 /* FIP APP */
     760                 :          0 :                 dcbcfg->app[i].priority =
     761                 :          0 :                         (app_prio & I40E_AQC_CEE_APP_FIP_MASK) >>
     762                 :            :                          I40E_AQC_CEE_APP_FIP_SHIFT;
     763                 :          0 :                 dcbcfg->app[i].selector = I40E_APP_SEL_ETHTYPE;
     764                 :          0 :                 dcbcfg->app[i].protocolid = I40E_APP_PROTOID_FIP;
     765                 :          0 :                 i++;
     766                 :            :         }
     767                 :          0 :         dcbcfg->numapps = i;
     768                 :          0 : }
     769                 :            : 
     770                 :            : /**
     771                 :            :  * i40e_get_ieee_dcb_config
     772                 :            :  * @hw: pointer to the hw struct
     773                 :            :  *
     774                 :            :  * Get IEEE mode DCB configuration from the Firmware
     775                 :            :  **/
     776                 :          0 : STATIC enum i40e_status_code i40e_get_ieee_dcb_config(struct i40e_hw *hw)
     777                 :            : {
     778                 :            :         enum i40e_status_code ret = I40E_SUCCESS;
     779                 :            : 
     780                 :            :         /* IEEE mode */
     781                 :          0 :         hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_IEEE;
     782                 :            :         /* Get Local DCB Config */
     783                 :          0 :         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
     784                 :            :                                      &hw->local_dcbx_config);
     785         [ #  # ]:          0 :         if (ret)
     786                 :          0 :                 goto out;
     787                 :            : 
     788                 :            :         /* Get Remote DCB Config */
     789                 :          0 :         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
     790                 :            :                                      I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
     791                 :            :                                      &hw->remote_dcbx_config);
     792                 :            :         /* Don't treat ENOENT as an error for Remote MIBs */
     793         [ #  # ]:          0 :         if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
     794                 :            :                 ret = I40E_SUCCESS;
     795                 :            : 
     796                 :          0 : out:
     797                 :          0 :         return ret;
     798                 :            : }
     799                 :            : 
     800                 :            : /**
     801                 :            :  * i40e_get_dcb_config
     802                 :            :  * @hw: pointer to the hw struct
     803                 :            :  *
     804                 :            :  * Get DCB configuration from the Firmware
     805                 :            :  **/
     806                 :          0 : enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw)
     807                 :            : {
     808                 :            :         enum i40e_status_code ret = I40E_SUCCESS;
     809                 :            :         struct i40e_aqc_get_cee_dcb_cfg_resp cee_cfg;
     810                 :            :         struct i40e_aqc_get_cee_dcb_cfg_v1_resp cee_v1_cfg;
     811                 :            : 
     812                 :            :         /* If Firmware version < v4.33 on X710/XL710, IEEE only */
     813         [ #  # ]:          0 :         if ((hw->mac.type == I40E_MAC_XL710) &&
     814   [ #  #  #  #  :          0 :             (((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver < 33)) ||
                   #  # ]
     815                 :            :               (hw->aq.fw_maj_ver < 4)))
     816                 :          0 :                 return i40e_get_ieee_dcb_config(hw);
     817                 :            : 
     818                 :            :         /* If Firmware version == v4.33 on X710/XL710, use old CEE struct */
     819         [ #  # ]:          0 :         if ((hw->mac.type == I40E_MAC_XL710) &&
     820         [ #  # ]:          0 :             ((hw->aq.fw_maj_ver == 4) && (hw->aq.fw_min_ver == 33))) {
     821                 :          0 :                 ret = i40e_aq_get_cee_dcb_config(hw, &cee_v1_cfg,
     822                 :            :                                                  sizeof(cee_v1_cfg), NULL);
     823         [ #  # ]:          0 :                 if (ret == I40E_SUCCESS) {
     824                 :            :                         /* CEE mode */
     825                 :          0 :                         hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
     826                 :          0 :                         hw->local_dcbx_config.tlv_status =
     827                 :          0 :                                         LE16_TO_CPU(cee_v1_cfg.tlv_status);
     828                 :          0 :                         i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
     829                 :            :                                                   &hw->local_dcbx_config);
     830                 :            :                 }
     831                 :            :         } else {
     832                 :          0 :                 ret = i40e_aq_get_cee_dcb_config(hw, &cee_cfg,
     833                 :            :                                                  sizeof(cee_cfg), NULL);
     834         [ #  # ]:          0 :                 if (ret == I40E_SUCCESS) {
     835                 :            :                         /* CEE mode */
     836                 :          0 :                         hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
     837                 :          0 :                         hw->local_dcbx_config.tlv_status =
     838                 :          0 :                                         LE32_TO_CPU(cee_cfg.tlv_status);
     839                 :          0 :                         i40e_cee_to_dcb_config(&cee_cfg,
     840                 :            :                                                &hw->local_dcbx_config);
     841                 :            :                 }
     842                 :            :         }
     843                 :            : 
     844                 :            :         /* CEE mode not enabled try querying IEEE data */
     845         [ #  # ]:          0 :         if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
     846                 :          0 :                 return i40e_get_ieee_dcb_config(hw);
     847                 :            : 
     848         [ #  # ]:          0 :         if (ret != I40E_SUCCESS)
     849                 :          0 :                 goto out;
     850                 :            : 
     851                 :            :         /* Get CEE DCB Desired Config */
     852                 :          0 :         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_LOCAL, 0,
     853                 :            :                                      &hw->desired_dcbx_config);
     854         [ #  # ]:          0 :         if (ret)
     855                 :          0 :                 goto out;
     856                 :            : 
     857                 :            :         /* Get Remote DCB Config */
     858                 :          0 :         ret = i40e_aq_get_dcb_config(hw, I40E_AQ_LLDP_MIB_REMOTE,
     859                 :            :                              I40E_AQ_LLDP_BRIDGE_TYPE_NEAREST_BRIDGE,
     860                 :            :                              &hw->remote_dcbx_config);
     861                 :            :         /* Don't treat ENOENT as an error for Remote MIBs */
     862         [ #  # ]:          0 :         if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT)
     863                 :            :                 ret = I40E_SUCCESS;
     864                 :            : 
     865                 :          0 : out:
     866                 :            :         return ret;
     867                 :            : }
     868                 :            : 
     869                 :            : /**
     870                 :            :  * i40e_init_dcb
     871                 :            :  * @hw: pointer to the hw struct
     872                 :            :  * @enable_mib_change: enable mib change event
     873                 :            :  *
     874                 :            :  * Update DCB configuration from the Firmware
     875                 :            :  **/
     876                 :          0 : enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw, bool enable_mib_change)
     877                 :            : {
     878                 :            :         enum i40e_status_code ret = I40E_SUCCESS;
     879                 :            :         struct i40e_lldp_variables lldp_cfg;
     880                 :            :         u8 adminstatus = 0;
     881                 :            : 
     882         [ #  # ]:          0 :         if (!hw->func_caps.dcb)
     883                 :            :                 return I40E_NOT_SUPPORTED;
     884                 :            : 
     885                 :            :         /* Read LLDP NVM area */
     886         [ #  # ]:          0 :         if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT) {
     887                 :            :                 u8 offset = 0;
     888                 :            : 
     889         [ #  # ]:          0 :                 if (hw->mac.type == I40E_MAC_XL710)
     890                 :            :                         offset = I40E_LLDP_CURRENT_STATUS_XL710_OFFSET;
     891         [ #  # ]:          0 :                 else if (hw->mac.type == I40E_MAC_X722)
     892                 :            :                         offset = I40E_LLDP_CURRENT_STATUS_X722_OFFSET;
     893                 :            :                 else
     894                 :            :                         return I40E_NOT_SUPPORTED;
     895                 :            : 
     896                 :          0 :                 ret = i40e_read_nvm_module_data(hw,
     897                 :            :                                                 I40E_SR_EMP_SR_SETTINGS_PTR,
     898                 :            :                                                 offset,
     899                 :            :                                                 I40E_LLDP_CURRENT_STATUS_OFFSET,
     900                 :            :                                                 I40E_LLDP_CURRENT_STATUS_SIZE,
     901                 :            :                                                 &lldp_cfg.adminstatus);
     902                 :            :         } else {
     903                 :          0 :                 ret = i40e_read_lldp_cfg(hw, &lldp_cfg);
     904                 :            :         }
     905         [ #  # ]:          0 :         if (ret)
     906                 :            :                 return I40E_ERR_NOT_READY;
     907                 :            : 
     908                 :            :         /* Get the LLDP AdminStatus for the current port */
     909                 :          0 :         adminstatus = (u8)(lldp_cfg.adminstatus >> (hw->port * 4));
     910                 :          0 :         adminstatus &= 0xF;
     911                 :            : 
     912                 :            :         /* LLDP agent disabled */
     913         [ #  # ]:          0 :         if (!adminstatus) {
     914                 :          0 :                 hw->dcbx_status = I40E_DCBX_STATUS_DISABLED;
     915                 :          0 :                 return I40E_ERR_NOT_READY;
     916                 :            :         }
     917                 :            : 
     918                 :            :         /* Get DCBX status */
     919                 :          0 :         ret = i40e_get_dcbx_status(hw, &hw->dcbx_status);
     920         [ #  # ]:          0 :         if (ret)
     921                 :            :                 return ret;
     922                 :            : 
     923                 :            :         /* Check the DCBX Status */
     924         [ #  # ]:          0 :         if (hw->dcbx_status == I40E_DCBX_STATUS_DONE ||
     925                 :            :             hw->dcbx_status == I40E_DCBX_STATUS_IN_PROGRESS) {
     926                 :            :                 /* Get current DCBX configuration */
     927                 :          0 :                 ret = i40e_get_dcb_config(hw);
     928         [ #  # ]:          0 :                 if (ret)
     929                 :            :                         return ret;
     930         [ #  # ]:          0 :         } else if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) {
     931                 :            :                 return I40E_ERR_NOT_READY;
     932                 :            :         }
     933                 :            : 
     934                 :            :         /* Configure the LLDP MIB change event */
     935         [ #  # ]:          0 :         if (enable_mib_change)
     936                 :          0 :                 ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL);
     937                 :            : 
     938                 :            :         return ret;
     939                 :            : }
     940                 :            : 
     941                 :            : /**
     942                 :            :  * i40e_get_fw_lldp_status
     943                 :            :  * @hw: pointer to the hw struct
     944                 :            :  * @lldp_status: pointer to the status enum
     945                 :            :  *
     946                 :            :  * Get status of FW Link Layer Discovery Protocol (LLDP) Agent.
     947                 :            :  * Status of agent is reported via @lldp_status parameter.
     948                 :            :  **/
     949                 :            : enum i40e_status_code
     950                 :          0 : i40e_get_fw_lldp_status(struct i40e_hw *hw,
     951                 :            :                         enum i40e_get_fw_lldp_status_resp *lldp_status)
     952                 :            : {
     953                 :            :         enum i40e_status_code ret;
     954                 :            :         struct i40e_virt_mem mem;
     955                 :            :         u8 *lldpmib;
     956                 :            : 
     957         [ #  # ]:          0 :         if (!lldp_status)
     958                 :            :                 return I40E_ERR_PARAM;
     959                 :            : 
     960                 :            :         /* Allocate buffer for the LLDPDU */
     961                 :          0 :         ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
     962         [ #  # ]:          0 :         if (ret)
     963                 :            :                 return ret;
     964                 :            : 
     965                 :          0 :         lldpmib = (u8 *)mem.va;
     966                 :          0 :         ret = i40e_aq_get_lldp_mib(hw, 0, 0, (void *)lldpmib,
     967                 :            :                                    I40E_LLDPDU_SIZE, NULL, NULL, NULL);
     968                 :            : 
     969         [ #  # ]:          0 :         if (ret == I40E_SUCCESS) {
     970                 :          0 :                 *lldp_status = I40E_GET_FW_LLDP_STATUS_ENABLED;
     971         [ #  # ]:          0 :         } else if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT) {
     972                 :            :                 /* MIB is not available yet but the agent is running */
     973                 :          0 :                 *lldp_status = I40E_GET_FW_LLDP_STATUS_ENABLED;
     974                 :            :                 ret = I40E_SUCCESS;
     975         [ #  # ]:          0 :         } else if (hw->aq.asq_last_status == I40E_AQ_RC_EPERM) {
     976                 :          0 :                 *lldp_status = I40E_GET_FW_LLDP_STATUS_DISABLED;
     977                 :            :                 ret = I40E_SUCCESS;
     978                 :            :         }
     979                 :            : 
     980                 :          0 :         i40e_free_virt_mem(hw, &mem);
     981                 :          0 :         return ret;
     982                 :            : }
     983                 :            : 
     984                 :            : /**
     985                 :            :  * i40e_add_ieee_ets_tlv - Prepare ETS TLV in IEEE format
     986                 :            :  * @tlv: Fill the ETS config data in IEEE format
     987                 :            :  * @dcbcfg: Local store which holds the DCB Config
     988                 :            :  *
     989                 :            :  * Prepare IEEE 802.1Qaz ETS CFG TLV
     990                 :            :  **/
     991                 :          0 : static void i40e_add_ieee_ets_tlv(struct i40e_lldp_org_tlv *tlv,
     992                 :            :                                   struct i40e_dcbx_config *dcbcfg)
     993                 :            : {
     994                 :            :         u8 priority0, priority1, maxtcwilling = 0;
     995                 :            :         struct i40e_dcb_ets_config *etscfg;
     996                 :            :         u16 offset = 0, typelength, i;
     997                 :          0 :         u8 *buf = tlv->tlvinfo;
     998                 :            :         u32 ouisubtype;
     999                 :            : 
    1000                 :            :         typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
    1001                 :            :                         I40E_IEEE_ETS_TLV_LENGTH);
    1002                 :          0 :         tlv->typelength = I40E_HTONS(typelength);
    1003                 :            : 
    1004                 :            :         ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
    1005                 :            :                         I40E_IEEE_SUBTYPE_ETS_CFG);
    1006                 :          0 :         tlv->ouisubtype = I40E_HTONL(ouisubtype);
    1007                 :            : 
    1008                 :            :         /* First Octet post subtype
    1009                 :            :          * --------------------------
    1010                 :            :          * |will-|CBS  | Re-  | Max |
    1011                 :            :          * |ing  |     |served| TCs |
    1012                 :            :          * --------------------------
    1013                 :            :          * |1bit | 1bit|3 bits|3bits|
    1014                 :            :          */
    1015                 :            :         etscfg = &dcbcfg->etscfg;
    1016         [ #  # ]:          0 :         if (etscfg->willing)
    1017                 :            :                 maxtcwilling = BIT(I40E_IEEE_ETS_WILLING_SHIFT);
    1018                 :          0 :         maxtcwilling |= etscfg->maxtcs & I40E_IEEE_ETS_MAXTC_MASK;
    1019                 :          0 :         buf[offset] = maxtcwilling;
    1020                 :            : 
    1021                 :            :         /* Move offset to Priority Assignment Table */
    1022                 :            :         offset++;
    1023                 :            : 
    1024                 :            :         /* Priority Assignment Table (4 octets)
    1025                 :            :          * Octets:|    1    |    2    |    3    |    4    |
    1026                 :            :          *        -----------------------------------------
    1027                 :            :          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
    1028                 :            :          *        -----------------------------------------
    1029                 :            :          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
    1030                 :            :          *        -----------------------------------------
    1031                 :            :          */
    1032         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
    1033                 :          0 :                 priority0 = etscfg->prioritytable[i * 2] & 0xF;
    1034                 :          0 :                 priority1 = etscfg->prioritytable[i * 2 + 1] & 0xF;
    1035                 :          0 :                 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
    1036                 :            :                                 priority1;
    1037                 :          0 :                 offset++;
    1038                 :            :         }
    1039                 :            : 
    1040                 :            :         /* TC Bandwidth Table (8 octets)
    1041                 :            :          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
    1042                 :            :          *        ---------------------------------
    1043                 :            :          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
    1044                 :            :          *        ---------------------------------
    1045                 :            :          */
    1046         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
    1047                 :          0 :                 buf[offset++] = etscfg->tcbwtable[i];
    1048                 :            : 
    1049                 :            :         /* TSA Assignment Table (8 octets)
    1050                 :            :          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
    1051                 :            :          *        ---------------------------------
    1052                 :            :          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
    1053                 :            :          *        ---------------------------------
    1054                 :            :          */
    1055         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
    1056                 :          0 :                 buf[offset++] = etscfg->tsatable[i];
    1057                 :          0 : }
    1058                 :            : 
    1059                 :            : /**
    1060                 :            :  * i40e_add_ieee_etsrec_tlv - Prepare ETS Recommended TLV in IEEE format
    1061                 :            :  * @tlv: Fill ETS Recommended TLV in IEEE format
    1062                 :            :  * @dcbcfg: Local store which holds the DCB Config
    1063                 :            :  *
    1064                 :            :  * Prepare IEEE 802.1Qaz ETS REC TLV
    1065                 :            :  **/
    1066                 :          0 : static void i40e_add_ieee_etsrec_tlv(struct i40e_lldp_org_tlv *tlv,
    1067                 :            :                                      struct i40e_dcbx_config *dcbcfg)
    1068                 :            : {
    1069                 :            :         struct i40e_dcb_ets_config *etsrec;
    1070                 :            :         u16 offset = 0, typelength, i;
    1071                 :            :         u8 priority0, priority1;
    1072                 :          0 :         u8 *buf = tlv->tlvinfo;
    1073                 :            :         u32 ouisubtype;
    1074                 :            : 
    1075                 :            :         typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
    1076                 :            :                         I40E_IEEE_ETS_TLV_LENGTH);
    1077                 :          0 :         tlv->typelength = I40E_HTONS(typelength);
    1078                 :            : 
    1079                 :            :         ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
    1080                 :            :                         I40E_IEEE_SUBTYPE_ETS_REC);
    1081                 :          0 :         tlv->ouisubtype = I40E_HTONL(ouisubtype);
    1082                 :            : 
    1083                 :            :         etsrec = &dcbcfg->etsrec;
    1084                 :            :         /* First Octet is reserved */
    1085                 :            :         /* Move offset to Priority Assignment Table */
    1086                 :            :         offset++;
    1087                 :            : 
    1088                 :            :         /* Priority Assignment Table (4 octets)
    1089                 :            :          * Octets:|    1    |    2    |    3    |    4    |
    1090                 :            :          *        -----------------------------------------
    1091                 :            :          *        |pri0|pri1|pri2|pri3|pri4|pri5|pri6|pri7|
    1092                 :            :          *        -----------------------------------------
    1093                 :            :          *   Bits:|7  4|3  0|7  4|3  0|7  4|3  0|7  4|3  0|
    1094                 :            :          *        -----------------------------------------
    1095                 :            :          */
    1096         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
    1097                 :          0 :                 priority0 = etsrec->prioritytable[i * 2] & 0xF;
    1098                 :          0 :                 priority1 = etsrec->prioritytable[i * 2 + 1] & 0xF;
    1099                 :          0 :                 buf[offset] = (priority0 << I40E_IEEE_ETS_PRIO_1_SHIFT) |
    1100                 :            :                                 priority1;
    1101                 :          0 :                 offset++;
    1102                 :            :         }
    1103                 :            : 
    1104                 :            :         /* TC Bandwidth Table (8 octets)
    1105                 :            :          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
    1106                 :            :          *        ---------------------------------
    1107                 :            :          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
    1108                 :            :          *        ---------------------------------
    1109                 :            :          */
    1110         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
    1111                 :          0 :                 buf[offset++] = etsrec->tcbwtable[i];
    1112                 :            : 
    1113                 :            :         /* TSA Assignment Table (8 octets)
    1114                 :            :          * Octets:| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
    1115                 :            :          *        ---------------------------------
    1116                 :            :          *        |tc0|tc1|tc2|tc3|tc4|tc5|tc6|tc7|
    1117                 :            :          *        ---------------------------------
    1118                 :            :          */
    1119         [ #  # ]:          0 :         for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++)
    1120                 :          0 :                 buf[offset++] = etsrec->tsatable[i];
    1121                 :          0 : }
    1122                 :            : 
    1123                 :            :  /**
    1124                 :            :  * i40e_add_ieee_pfc_tlv - Prepare PFC TLV in IEEE format
    1125                 :            :  * @tlv: Fill PFC TLV in IEEE format
    1126                 :            :  * @dcbcfg: Local store to get PFC CFG data
    1127                 :            :  *
    1128                 :            :  * Prepare IEEE 802.1Qaz PFC CFG TLV
    1129                 :            :  **/
    1130                 :            : static void i40e_add_ieee_pfc_tlv(struct i40e_lldp_org_tlv *tlv,
    1131                 :            :                                   struct i40e_dcbx_config *dcbcfg)
    1132                 :            : {
    1133                 :            :         u8 *buf = tlv->tlvinfo;
    1134                 :            :         u32 ouisubtype;
    1135                 :            :         u16 typelength;
    1136                 :            : 
    1137                 :            :         typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
    1138                 :            :                         I40E_IEEE_PFC_TLV_LENGTH);
    1139                 :          0 :         tlv->typelength = I40E_HTONS(typelength);
    1140                 :            : 
    1141                 :            :         ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
    1142                 :            :                         I40E_IEEE_SUBTYPE_PFC_CFG);
    1143                 :          0 :         tlv->ouisubtype = I40E_HTONL(ouisubtype);
    1144                 :            : 
    1145                 :            :         /* ----------------------------------------
    1146                 :            :          * |will-|MBC  | Re-  | PFC |  PFC Enable  |
    1147                 :            :          * |ing  |     |served| cap |              |
    1148                 :            :          * -----------------------------------------
    1149                 :            :          * |1bit | 1bit|2 bits|4bits| 1 octet      |
    1150                 :            :          */
    1151         [ #  # ]:          0 :         if (dcbcfg->pfc.willing)
    1152                 :          0 :                 buf[0] = BIT(I40E_IEEE_PFC_WILLING_SHIFT);
    1153                 :            : 
    1154         [ #  # ]:          0 :         if (dcbcfg->pfc.mbc)
    1155                 :          0 :                 buf[0] |= BIT(I40E_IEEE_PFC_MBC_SHIFT);
    1156                 :            : 
    1157                 :          0 :         buf[0] |= dcbcfg->pfc.pfccap & 0xF;
    1158                 :          0 :         buf[1] = dcbcfg->pfc.pfcenable;
    1159                 :          0 : }
    1160                 :            : 
    1161                 :            : /**
    1162                 :            :  * i40e_add_ieee_app_pri_tlv -  Prepare APP TLV in IEEE format
    1163                 :            :  * @tlv: Fill APP TLV in IEEE format
    1164                 :            :  * @dcbcfg: Local store to get APP CFG data
    1165                 :            :  *
    1166                 :            :  * Prepare IEEE 802.1Qaz APP CFG TLV
    1167                 :            :  **/
    1168                 :          0 : static void i40e_add_ieee_app_pri_tlv(struct i40e_lldp_org_tlv *tlv,
    1169                 :            :                                       struct i40e_dcbx_config *dcbcfg)
    1170                 :            : {
    1171                 :            :         u16 typelength, length, offset = 0;
    1172                 :            :         u8 priority, selector, i = 0;
    1173                 :          0 :         u8 *buf = tlv->tlvinfo;
    1174                 :            :         u32 ouisubtype;
    1175                 :            : 
    1176                 :            :         /* No APP TLVs then just return */
    1177         [ #  # ]:          0 :         if (dcbcfg->numapps == 0)
    1178                 :            :                 return;
    1179                 :            :         ouisubtype = (u32)((I40E_IEEE_8021QAZ_OUI << I40E_LLDP_TLV_OUI_SHIFT) |
    1180                 :            :                         I40E_IEEE_SUBTYPE_APP_PRI);
    1181                 :          0 :         tlv->ouisubtype = I40E_HTONL(ouisubtype);
    1182                 :            : 
    1183                 :            :         /* Move offset to App Priority Table */
    1184                 :            :         offset++;
    1185                 :            :         /* Application Priority Table (3 octets)
    1186                 :            :          * Octets:|         1          |    2    |    3    |
    1187                 :            :          *        -----------------------------------------
    1188                 :            :          *        |Priority|Rsrvd| Sel |    Protocol ID    |
    1189                 :            :          *        -----------------------------------------
    1190                 :            :          *   Bits:|23    21|20 19|18 16|15                0|
    1191                 :            :          *        -----------------------------------------
    1192                 :            :          */
    1193         [ #  # ]:          0 :         while (i < dcbcfg->numapps) {
    1194                 :          0 :                 priority = dcbcfg->app[i].priority & 0x7;
    1195                 :          0 :                 selector = dcbcfg->app[i].selector & 0x7;
    1196                 :          0 :                 buf[offset] = (priority << I40E_IEEE_APP_PRIO_SHIFT) | selector;
    1197                 :          0 :                 buf[offset + 1] = (dcbcfg->app[i].protocolid >> 0x8) & 0xFF;
    1198                 :          0 :                 buf[offset + 2] =  dcbcfg->app[i].protocolid & 0xFF;
    1199                 :            :                 /* Move to next app */
    1200                 :          0 :                 offset += 3;
    1201                 :          0 :                 i++;
    1202         [ #  # ]:          0 :                 if (i >= I40E_DCBX_MAX_APPS)
    1203                 :            :                         break;
    1204                 :            :         }
    1205                 :            :         /* length includes size of ouisubtype + 1 reserved + 3*numapps */
    1206                 :          0 :         length = sizeof(tlv->ouisubtype) + 1 + (i*3);
    1207                 :          0 :         typelength = (u16)((I40E_TLV_TYPE_ORG << I40E_LLDP_TLV_TYPE_SHIFT) |
    1208                 :            :                 (length & 0x1FF));
    1209         [ #  # ]:          0 :         tlv->typelength = I40E_HTONS(typelength);
    1210                 :            : }
    1211                 :            : 
    1212                 :            :  /**
    1213                 :            :  * i40e_add_dcb_tlv - Add all IEEE TLVs
    1214                 :            :  * @tlv: pointer to org tlv
    1215                 :            :  *
    1216                 :            :  * add tlv information
    1217                 :            :  **/
    1218                 :          0 : static void i40e_add_dcb_tlv(struct i40e_lldp_org_tlv *tlv,
    1219                 :            :                              struct i40e_dcbx_config *dcbcfg,
    1220                 :            :                              u16 tlvid)
    1221                 :            : {
    1222   [ #  #  #  #  :          0 :         switch (tlvid) {
                      # ]
    1223                 :          0 :         case I40E_IEEE_TLV_ID_ETS_CFG:
    1224                 :          0 :                 i40e_add_ieee_ets_tlv(tlv, dcbcfg);
    1225                 :          0 :                 break;
    1226                 :          0 :         case I40E_IEEE_TLV_ID_ETS_REC:
    1227                 :          0 :                 i40e_add_ieee_etsrec_tlv(tlv, dcbcfg);
    1228                 :          0 :                 break;
    1229                 :            :         case I40E_IEEE_TLV_ID_PFC_CFG:
    1230                 :            :                 i40e_add_ieee_pfc_tlv(tlv, dcbcfg);
    1231                 :            :                 break;
    1232                 :          0 :         case I40E_IEEE_TLV_ID_APP_PRI:
    1233                 :          0 :                 i40e_add_ieee_app_pri_tlv(tlv, dcbcfg);
    1234                 :          0 :                 break;
    1235                 :            :         default:
    1236                 :            :                 break;
    1237                 :            :         }
    1238                 :          0 : }
    1239                 :            : 
    1240                 :            :  /**
    1241                 :            :  * i40e_set_dcb_config - Set the local LLDP MIB to FW
    1242                 :            :  * @hw: pointer to the hw struct
    1243                 :            :  *
    1244                 :            :  * Set DCB configuration to the Firmware
    1245                 :            :  **/
    1246                 :          0 : enum i40e_status_code i40e_set_dcb_config(struct i40e_hw *hw)
    1247                 :            : {
    1248                 :            :         enum i40e_status_code ret = I40E_SUCCESS;
    1249                 :            :         struct i40e_dcbx_config *dcbcfg;
    1250                 :            :         struct i40e_virt_mem mem;
    1251                 :            :         u8 mib_type, *lldpmib;
    1252                 :            :         u16 miblen;
    1253                 :            : 
    1254                 :            :         /* update the hw local config */
    1255                 :          0 :         dcbcfg = &hw->local_dcbx_config;
    1256                 :            :         /* Allocate the LLDPDU */
    1257                 :          0 :         ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE);
    1258         [ #  # ]:          0 :         if (ret)
    1259                 :            :                 return ret;
    1260                 :            : 
    1261                 :            :         mib_type = SET_LOCAL_MIB_AC_TYPE_LOCAL_MIB;
    1262         [ #  # ]:          0 :         if (dcbcfg->app_mode == I40E_DCBX_APPS_NON_WILLING) {
    1263                 :            :                 mib_type |= SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS <<
    1264                 :            :                             SET_LOCAL_MIB_AC_TYPE_NON_WILLING_APPS_SHIFT;
    1265                 :            :         }
    1266                 :          0 :         lldpmib = (u8 *)mem.va;
    1267                 :          0 :         ret = i40e_dcb_config_to_lldp(lldpmib, &miblen, dcbcfg);
    1268                 :          0 :         ret = i40e_aq_set_lldp_mib(hw, mib_type, (void *)lldpmib, miblen, NULL);
    1269                 :            : 
    1270                 :          0 :         i40e_free_virt_mem(hw, &mem);
    1271                 :          0 :         return ret;
    1272                 :            : }
    1273                 :            : 
    1274                 :            : /**
    1275                 :            :  * i40e_dcb_config_to_lldp - Convert Dcbconfig to MIB format
    1276                 :            :  * @lldpmib: pointer to mib to be output
    1277                 :            :  * @miblen: pointer to u16 for length of lldpmib
    1278                 :            :  * @dcbcfg: store for LLDPDU data
    1279                 :            :  *
    1280                 :            :  * send DCB configuration to FW
    1281                 :            :  **/
    1282                 :          0 : enum i40e_status_code i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen,
    1283                 :            :                                               struct i40e_dcbx_config *dcbcfg)
    1284                 :            : {
    1285                 :            :         u16 length, offset = 0, tlvid = I40E_TLV_ID_START;
    1286                 :            :         enum i40e_status_code ret = I40E_SUCCESS;
    1287                 :            :         struct i40e_lldp_org_tlv *tlv;
    1288                 :            :         u16 typelength;
    1289                 :            : 
    1290                 :            :         tlv = (struct i40e_lldp_org_tlv *)lldpmib;
    1291                 :            :         while (1) {
    1292                 :          0 :                 i40e_add_dcb_tlv(tlv, dcbcfg, tlvid++);
    1293         [ #  # ]:          0 :                 typelength = I40E_NTOHS(tlv->typelength);
    1294                 :          0 :                 length = (u16)((typelength & I40E_LLDP_TLV_LEN_MASK) >>
    1295                 :            :                                 I40E_LLDP_TLV_LEN_SHIFT);
    1296         [ #  # ]:          0 :                 if (length)
    1297                 :          0 :                         offset += length + 2;
    1298                 :            :                 /* END TLV or beyond LLDPDU size */
    1299                 :          0 :                 if ((tlvid >= I40E_TLV_ID_END_OF_LLDPPDU) ||
    1300         [ #  # ]:          0 :                     (offset > I40E_LLDPDU_SIZE))
    1301                 :            :                         break;
    1302                 :            :                 /* Move to next TLV */
    1303         [ #  # ]:          0 :                 if (length)
    1304                 :          0 :                         tlv = (struct i40e_lldp_org_tlv *)((char *)tlv +
    1305                 :          0 :                               sizeof(tlv->typelength) + length);
    1306                 :            :         }
    1307                 :          0 :         *miblen = offset;
    1308                 :          0 :         return ret;
    1309                 :            : }
    1310                 :            : 
    1311                 :            : /**
    1312                 :            :  * _i40e_read_lldp_cfg - generic read of LLDP Configuration data from NVM
    1313                 :            :  * @hw: pointer to the HW structure
    1314                 :            :  * @lldp_cfg: pointer to hold lldp configuration variables
    1315                 :            :  * @module: address of the module pointer
    1316                 :            :  * @word_offset: offset of LLDP configuration
    1317                 :            :  *
    1318                 :            :  * Reads the LLDP configuration data from NVM using passed addresses
    1319                 :            :  **/
    1320                 :          0 : static enum i40e_status_code _i40e_read_lldp_cfg(struct i40e_hw *hw,
    1321                 :            :                                           struct i40e_lldp_variables *lldp_cfg,
    1322                 :            :                                           u8 module, u32 word_offset)
    1323                 :            : {
    1324                 :          0 :         u32 address, offset = (2 * word_offset);
    1325                 :            :         enum i40e_status_code ret;
    1326                 :            :         __le16 raw_mem;
    1327                 :            :         u16 mem;
    1328                 :            : 
    1329                 :          0 :         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
    1330         [ #  # ]:          0 :         if (ret != I40E_SUCCESS)
    1331                 :            :                 return ret;
    1332                 :            : 
    1333                 :          0 :         ret = i40e_aq_read_nvm(hw, 0x0, module * 2, sizeof(raw_mem), &raw_mem,
    1334                 :            :                                true, NULL);
    1335                 :          0 :         i40e_release_nvm(hw);
    1336         [ #  # ]:          0 :         if (ret != I40E_SUCCESS)
    1337                 :            :                 return ret;
    1338                 :            : 
    1339                 :          0 :         mem = LE16_TO_CPU(raw_mem);
    1340                 :            :         /* Check if this pointer needs to be read in word size or 4K sector
    1341                 :            :          * units.
    1342                 :            :          */
    1343         [ #  # ]:          0 :         if (mem & I40E_PTR_TYPE)
    1344                 :          0 :                 address = (0x7FFF & mem) * 4096;
    1345                 :            :         else
    1346                 :          0 :                 address = (0x7FFF & mem) * 2;
    1347                 :            : 
    1348                 :          0 :         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
    1349         [ #  # ]:          0 :         if (ret != I40E_SUCCESS)
    1350                 :          0 :                 goto err_lldp_cfg;
    1351                 :            : 
    1352                 :          0 :         ret = i40e_aq_read_nvm(hw, module, offset, sizeof(raw_mem), &raw_mem,
    1353                 :            :                                true, NULL);
    1354                 :          0 :         i40e_release_nvm(hw);
    1355         [ #  # ]:          0 :         if (ret != I40E_SUCCESS)
    1356                 :            :                 return ret;
    1357                 :            : 
    1358                 :          0 :         mem = LE16_TO_CPU(raw_mem);
    1359                 :          0 :         offset = mem + word_offset;
    1360                 :          0 :         offset *= 2;
    1361                 :            : 
    1362                 :          0 :         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
    1363         [ #  # ]:          0 :         if (ret != I40E_SUCCESS)
    1364                 :          0 :                 goto err_lldp_cfg;
    1365                 :            : 
    1366                 :          0 :         ret = i40e_aq_read_nvm(hw, 0, address + offset,
    1367                 :            :                                sizeof(struct i40e_lldp_variables), lldp_cfg,
    1368                 :            :                                true, NULL);
    1369                 :          0 :         i40e_release_nvm(hw);
    1370                 :            : 
    1371                 :            : err_lldp_cfg:
    1372                 :            :         return ret;
    1373                 :            : }
    1374                 :            : 
    1375                 :            : /**
    1376                 :            :  * i40e_read_lldp_cfg - read LLDP Configuration data from NVM
    1377                 :            :  * @hw: pointer to the HW structure
    1378                 :            :  * @lldp_cfg: pointer to hold lldp configuration variables
    1379                 :            :  *
    1380                 :            :  * Reads the LLDP configuration data from NVM
    1381                 :            :  **/
    1382                 :          0 : enum i40e_status_code i40e_read_lldp_cfg(struct i40e_hw *hw,
    1383                 :            :                                          struct i40e_lldp_variables *lldp_cfg)
    1384                 :            : {
    1385                 :            :         enum i40e_status_code ret = I40E_SUCCESS;
    1386                 :            :         u32 mem;
    1387                 :            : 
    1388         [ #  # ]:          0 :         if (!lldp_cfg)
    1389                 :            :                 return I40E_ERR_PARAM;
    1390                 :            : 
    1391                 :          0 :         ret = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
    1392         [ #  # ]:          0 :         if (ret != I40E_SUCCESS)
    1393                 :            :                 return ret;
    1394                 :            : 
    1395                 :          0 :         ret = i40e_aq_read_nvm(hw, I40E_SR_NVM_CONTROL_WORD, 0, sizeof(mem),
    1396                 :            :                                &mem, true, NULL);
    1397                 :          0 :         i40e_release_nvm(hw);
    1398         [ #  # ]:          0 :         if (ret != I40E_SUCCESS)
    1399                 :            :                 return ret;
    1400                 :            : 
    1401                 :            :         /* Read a bit that holds information whether we are running flat or
    1402                 :            :          * structured NVM image. Flat image has LLDP configuration in shadow
    1403                 :            :          * ram, so there is a need to pass different addresses for both cases.
    1404                 :            :          */
    1405         [ #  # ]:          0 :         if (mem & I40E_SR_NVM_MAP_STRUCTURE_TYPE) {
    1406                 :            :                 /* Flat NVM case */
    1407                 :          0 :                 ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_SR_EMP_MODULE_PTR,
    1408                 :            :                                           I40E_SR_LLDP_CFG_PTR);
    1409                 :            :         } else {
    1410                 :            :                 /* Good old structured NVM image */
    1411                 :          0 :                 ret = _i40e_read_lldp_cfg(hw, lldp_cfg, I40E_EMP_MODULE_PTR,
    1412                 :            :                                           I40E_NVM_LLDP_CFG_PTR);
    1413                 :            :         }
    1414                 :            : 
    1415                 :            :         return ret;
    1416                 :            : }

Generated by: LCOV version 1.14