LCOV - code coverage report
Current view: top level - drivers/net/i40e/base - i40e_lan_hmc.c (source / functions) Hit Total Coverage
Test: Code coverage Lines: 0 425 0.0 %
Date: 2024-01-22 15:55:54 Functions: 0 25 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 200 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_osdep.h"
       6                 :            : #include "i40e_register.h"
       7                 :            : #include "i40e_type.h"
       8                 :            : #include "i40e_hmc.h"
       9                 :            : #include "i40e_lan_hmc.h"
      10                 :            : #include "i40e_prototype.h"
      11                 :            : 
      12                 :            : /* lan specific interface functions */
      13                 :            : 
      14                 :            : /**
      15                 :            :  * i40e_align_l2obj_base - aligns base object pointer to 512 bytes
      16                 :            :  * @offset: base address offset needing alignment
      17                 :            :  *
      18                 :            :  * Aligns the layer 2 function private memory so it's 512-byte aligned.
      19                 :            :  **/
      20                 :            : STATIC u64 i40e_align_l2obj_base(u64 offset)
      21                 :            : {
      22                 :            :         u64 aligned_offset = offset;
      23                 :            : 
      24                 :          0 :         if ((offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT) > 0)
      25                 :          0 :                 aligned_offset += (I40E_HMC_L2OBJ_BASE_ALIGNMENT -
      26                 :            :                                    (offset % I40E_HMC_L2OBJ_BASE_ALIGNMENT));
      27                 :            : 
      28                 :            :         return aligned_offset;
      29                 :            : }
      30                 :            : 
      31                 :            : /**
      32                 :            :  * i40e_calculate_l2fpm_size - calculates layer 2 FPM memory size
      33                 :            :  * @txq_num: number of Tx queues needing backing context
      34                 :            :  * @rxq_num: number of Rx queues needing backing context
      35                 :            :  * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context
      36                 :            :  * @fcoe_filt_num: number of FCoE filters needing backing context
      37                 :            :  *
      38                 :            :  * Calculates the maximum amount of memory for the function required, based
      39                 :            :  * on the number of resources it must provide context for.
      40                 :            :  **/
      41                 :          0 : u64 i40e_calculate_l2fpm_size(u32 txq_num, u32 rxq_num,
      42                 :            :                               u32 fcoe_cntx_num, u32 fcoe_filt_num)
      43                 :            : {
      44                 :            :         u64 fpm_size = 0;
      45                 :            : 
      46         [ #  # ]:          0 :         fpm_size = txq_num * I40E_HMC_OBJ_SIZE_TXQ;
      47                 :            :         fpm_size = i40e_align_l2obj_base(fpm_size);
      48                 :            : 
      49         [ #  # ]:          0 :         fpm_size += (rxq_num * I40E_HMC_OBJ_SIZE_RXQ);
      50                 :            :         fpm_size = i40e_align_l2obj_base(fpm_size);
      51                 :            : 
      52         [ #  # ]:          0 :         fpm_size += (fcoe_cntx_num * I40E_HMC_OBJ_SIZE_FCOE_CNTX);
      53                 :            :         fpm_size = i40e_align_l2obj_base(fpm_size);
      54                 :            : 
      55         [ #  # ]:          0 :         fpm_size += (fcoe_filt_num * I40E_HMC_OBJ_SIZE_FCOE_FILT);
      56                 :            :         fpm_size = i40e_align_l2obj_base(fpm_size);
      57                 :            : 
      58                 :          0 :         return fpm_size;
      59                 :            : }
      60                 :            : 
      61                 :            : /**
      62                 :            :  * i40e_init_lan_hmc - initialize i40e_hmc_info struct
      63                 :            :  * @hw: pointer to the HW structure
      64                 :            :  * @txq_num: number of Tx queues needing backing context
      65                 :            :  * @rxq_num: number of Rx queues needing backing context
      66                 :            :  * @fcoe_cntx_num: amount of FCoE statefull contexts needing backing context
      67                 :            :  * @fcoe_filt_num: number of FCoE filters needing backing context
      68                 :            :  *
      69                 :            :  * This function will be called once per physical function initialization.
      70                 :            :  * It will fill out the i40e_hmc_obj_info structure for LAN objects based on
      71                 :            :  * the driver's provided input, as well as information from the HMC itself
      72                 :            :  * loaded from NVRAM.
      73                 :            :  *
      74                 :            :  * Assumptions:
      75                 :            :  *   - HMC Resource Profile has been selected before calling this function.
      76                 :            :  **/
      77                 :          0 : enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
      78                 :            :                                         u32 rxq_num, u32 fcoe_cntx_num,
      79                 :            :                                         u32 fcoe_filt_num)
      80                 :            : {
      81                 :            :         struct i40e_hmc_obj_info *obj, *full_obj;
      82                 :            :         enum i40e_status_code ret_code = I40E_SUCCESS;
      83                 :            :         u64 l2fpm_size;
      84                 :            :         u32 size_exp;
      85                 :            : 
      86                 :          0 :         hw->hmc.signature = I40E_HMC_INFO_SIGNATURE;
      87                 :          0 :         hw->hmc.hmc_fn_id = hw->pf_id;
      88                 :            : 
      89                 :            :         /* allocate memory for hmc_obj */
      90                 :          0 :         ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem,
      91                 :            :                         sizeof(struct i40e_hmc_obj_info) * I40E_HMC_LAN_MAX);
      92         [ #  # ]:          0 :         if (ret_code)
      93                 :          0 :                 goto init_lan_hmc_out;
      94                 :          0 :         hw->hmc.hmc_obj = (struct i40e_hmc_obj_info *)
      95                 :          0 :                           hw->hmc.hmc_obj_virt_mem.va;
      96                 :            : 
      97                 :            :         /* The full object will be used to create the LAN HMC SD */
      98                 :            :         full_obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_FULL];
      99                 :          0 :         full_obj->max_cnt = 0;
     100                 :          0 :         full_obj->cnt = 0;
     101                 :          0 :         full_obj->base = 0;
     102                 :          0 :         full_obj->size = 0;
     103                 :            : 
     104                 :            :         /* Tx queue context information */
     105                 :            :         obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX];
     106                 :          0 :         obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX);
     107                 :          0 :         obj->cnt = txq_num;
     108                 :          0 :         obj->base = 0;
     109                 :          0 :         size_exp = rd32(hw, I40E_GLHMC_LANTXOBJSZ);
     110                 :          0 :         obj->size = BIT_ULL(size_exp);
     111                 :            : 
     112                 :            :         /* validate values requested by driver don't exceed HMC capacity */
     113         [ #  # ]:          0 :         if (txq_num > obj->max_cnt) {
     114                 :            :                 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
     115                 :          0 :                 DEBUGOUT3("i40e_init_lan_hmc: Tx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
     116                 :            :                           txq_num, obj->max_cnt, ret_code);
     117                 :          0 :                 goto free_hmc_out;
     118                 :            :         }
     119                 :            : 
     120                 :            :         /* aggregate values into the full LAN object for later */
     121                 :          0 :         full_obj->max_cnt += obj->max_cnt;
     122                 :          0 :         full_obj->cnt += obj->cnt;
     123                 :            : 
     124                 :            :         /* Rx queue context information */
     125                 :          0 :         obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX];
     126                 :          0 :         obj->max_cnt = rd32(hw, I40E_GLHMC_LANQMAX);
     127                 :          0 :         obj->cnt = rxq_num;
     128                 :          0 :         obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_TX].base +
     129                 :          0 :                     (hw->hmc.hmc_obj[I40E_HMC_LAN_TX].cnt *
     130         [ #  # ]:          0 :                      hw->hmc.hmc_obj[I40E_HMC_LAN_TX].size);
     131                 :          0 :         obj->base = i40e_align_l2obj_base(obj->base);
     132                 :          0 :         size_exp = rd32(hw, I40E_GLHMC_LANRXOBJSZ);
     133                 :          0 :         obj->size = BIT_ULL(size_exp);
     134                 :            : 
     135                 :            :         /* validate values requested by driver don't exceed HMC capacity */
     136         [ #  # ]:          0 :         if (rxq_num > obj->max_cnt) {
     137                 :            :                 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
     138                 :          0 :                 DEBUGOUT3("i40e_init_lan_hmc: Rx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
     139                 :            :                           rxq_num, obj->max_cnt, ret_code);
     140                 :          0 :                 goto free_hmc_out;
     141                 :            :         }
     142                 :            : 
     143                 :            :         /* aggregate values into the full LAN object for later */
     144                 :          0 :         full_obj->max_cnt += obj->max_cnt;
     145                 :          0 :         full_obj->cnt += obj->cnt;
     146                 :            : 
     147                 :            :         /* FCoE context information */
     148                 :          0 :         obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX];
     149                 :          0 :         obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEMAX);
     150                 :          0 :         obj->cnt = fcoe_cntx_num;
     151                 :          0 :         obj->base = hw->hmc.hmc_obj[I40E_HMC_LAN_RX].base +
     152                 :          0 :                     (hw->hmc.hmc_obj[I40E_HMC_LAN_RX].cnt *
     153         [ #  # ]:          0 :                      hw->hmc.hmc_obj[I40E_HMC_LAN_RX].size);
     154                 :          0 :         obj->base = i40e_align_l2obj_base(obj->base);
     155                 :          0 :         size_exp = rd32(hw, I40E_GLHMC_FCOEDDPOBJSZ);
     156                 :          0 :         obj->size = BIT_ULL(size_exp);
     157                 :            : 
     158                 :            :         /* validate values requested by driver don't exceed HMC capacity */
     159         [ #  # ]:          0 :         if (fcoe_cntx_num > obj->max_cnt) {
     160                 :            :                 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
     161                 :          0 :                 DEBUGOUT3("i40e_init_lan_hmc: FCoE context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
     162                 :            :                           fcoe_cntx_num, obj->max_cnt, ret_code);
     163                 :          0 :                 goto free_hmc_out;
     164                 :            :         }
     165                 :            : 
     166                 :            :         /* aggregate values into the full LAN object for later */
     167                 :          0 :         full_obj->max_cnt += obj->max_cnt;
     168                 :          0 :         full_obj->cnt += obj->cnt;
     169                 :            : 
     170                 :            :         /* FCoE filter information */
     171                 :          0 :         obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT];
     172                 :          0 :         obj->max_cnt = rd32(hw, I40E_GLHMC_FCOEFMAX);
     173                 :          0 :         obj->cnt = fcoe_filt_num;
     174                 :          0 :         obj->base = hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].base +
     175                 :          0 :                     (hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].cnt *
     176         [ #  # ]:          0 :                      hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX].size);
     177                 :          0 :         obj->base = i40e_align_l2obj_base(obj->base);
     178                 :          0 :         size_exp = rd32(hw, I40E_GLHMC_FCOEFOBJSZ);
     179                 :          0 :         obj->size = BIT_ULL(size_exp);
     180                 :            : 
     181                 :            :         /* validate values requested by driver don't exceed HMC capacity */
     182         [ #  # ]:          0 :         if (fcoe_filt_num > obj->max_cnt) {
     183                 :            :                 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
     184                 :          0 :                 DEBUGOUT3("i40e_init_lan_hmc: FCoE filter: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
     185                 :            :                           fcoe_filt_num, obj->max_cnt, ret_code);
     186                 :          0 :                 goto free_hmc_out;
     187                 :            :         }
     188                 :            : 
     189                 :            :         /* aggregate values into the full LAN object for later */
     190                 :          0 :         full_obj->max_cnt += obj->max_cnt;
     191                 :          0 :         full_obj->cnt += obj->cnt;
     192                 :            : 
     193                 :          0 :         hw->hmc.first_sd_index = 0;
     194                 :          0 :         hw->hmc.sd_table.ref_cnt = 0;
     195                 :          0 :         l2fpm_size = i40e_calculate_l2fpm_size(txq_num, rxq_num, fcoe_cntx_num,
     196                 :            :                                                fcoe_filt_num);
     197         [ #  # ]:          0 :         if (NULL == hw->hmc.sd_table.sd_entry) {
     198                 :          0 :                 hw->hmc.sd_table.sd_cnt = (u32)
     199                 :          0 :                                    (l2fpm_size + I40E_HMC_DIRECT_BP_SIZE - 1) /
     200                 :            :                                    I40E_HMC_DIRECT_BP_SIZE;
     201                 :            : 
     202                 :            :                 /* allocate the sd_entry members in the sd_table */
     203                 :          0 :                 ret_code = i40e_allocate_virt_mem(hw, &hw->hmc.sd_table.addr,
     204                 :            :                                           (sizeof(struct i40e_hmc_sd_entry) *
     205                 :            :                                           hw->hmc.sd_table.sd_cnt));
     206         [ #  # ]:          0 :                 if (ret_code)
     207                 :          0 :                         goto free_hmc_out;
     208                 :          0 :                 hw->hmc.sd_table.sd_entry =
     209                 :          0 :                         (struct i40e_hmc_sd_entry *)hw->hmc.sd_table.addr.va;
     210                 :            :         }
     211                 :            :         /* store in the LAN full object for later */
     212                 :          0 :         full_obj->size = l2fpm_size;
     213                 :            : 
     214                 :            : init_lan_hmc_out:
     215                 :            :         return ret_code;
     216                 :          0 : free_hmc_out:
     217         [ #  # ]:          0 :         if (hw->hmc.hmc_obj_virt_mem.va)
     218                 :          0 :                 i40e_free_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem);
     219                 :            : 
     220                 :            :         return ret_code;
     221                 :            : }
     222                 :            : 
     223                 :            : /**
     224                 :            :  * i40e_remove_pd_page - Remove a page from the page descriptor table
     225                 :            :  * @hw: pointer to the HW structure
     226                 :            :  * @hmc_info: pointer to the HMC configuration information structure
     227                 :            :  * @idx: segment descriptor index to find the relevant page descriptor
     228                 :            :  *
     229                 :            :  * This function:
     230                 :            :  *      1. Marks the entry in pd table (for paged address mode) invalid
     231                 :            :  *      2. write to register PMPDINV to invalidate the backing page in FV cache
     232                 :            :  *      3. Decrement the ref count for  pd_entry
     233                 :            :  * assumptions:
     234                 :            :  *      1. caller can deallocate the memory used by pd after this function
     235                 :            :  *         returns.
     236                 :            :  **/
     237                 :          0 : STATIC enum i40e_status_code i40e_remove_pd_page(struct i40e_hw *hw,
     238                 :            :                                                  struct i40e_hmc_info *hmc_info,
     239                 :            :                                                  u32 idx)
     240                 :            : {
     241                 :            :         enum i40e_status_code ret_code = I40E_SUCCESS;
     242                 :            : 
     243         [ #  # ]:          0 :         if (i40e_prep_remove_pd_page(hmc_info, idx) == I40E_SUCCESS)
     244                 :          0 :                 ret_code = i40e_remove_pd_page_new(hw, hmc_info, idx, true);
     245                 :            : 
     246                 :          0 :         return ret_code;
     247                 :            : }
     248                 :            : 
     249                 :            : /**
     250                 :            :  * i40e_remove_sd_bp - remove a backing page from a segment descriptor
     251                 :            :  * @hw: pointer to our HW structure
     252                 :            :  * @hmc_info: pointer to the HMC configuration information structure
     253                 :            :  * @idx: the page index
     254                 :            :  *
     255                 :            :  * This function:
     256                 :            :  *      1. Marks the entry in sd table (for direct address mode) invalid
     257                 :            :  *      2. write to register PMSDCMD, PMSDDATALOW(PMSDDATALOW.PMSDVALID set
     258                 :            :  *         to 0) and PMSDDATAHIGH to invalidate the sd page
     259                 :            :  *      3. Decrement the ref count for the sd_entry
     260                 :            :  * assumptions:
     261                 :            :  *      1. caller can deallocate the memory used by backing storage after this
     262                 :            :  *         function returns.
     263                 :            :  **/
     264                 :          0 : STATIC enum i40e_status_code i40e_remove_sd_bp(struct i40e_hw *hw,
     265                 :            :                                                struct i40e_hmc_info *hmc_info,
     266                 :            :                                                u32 idx)
     267                 :            : {
     268                 :            :         enum i40e_status_code ret_code = I40E_SUCCESS;
     269                 :            : 
     270         [ #  # ]:          0 :         if (i40e_prep_remove_sd_bp(hmc_info, idx) == I40E_SUCCESS)
     271                 :          0 :                 ret_code = i40e_remove_sd_bp_new(hw, hmc_info, idx, true);
     272                 :            : 
     273                 :          0 :         return ret_code;
     274                 :            : }
     275                 :            : 
     276                 :            : /**
     277                 :            :  * i40e_create_lan_hmc_object - allocate backing store for hmc objects
     278                 :            :  * @hw: pointer to the HW structure
     279                 :            :  * @info: pointer to i40e_hmc_create_obj_info struct
     280                 :            :  *
     281                 :            :  * This will allocate memory for PDs and backing pages and populate
     282                 :            :  * the sd and pd entries.
     283                 :            :  **/
     284                 :          0 : enum i40e_status_code i40e_create_lan_hmc_object(struct i40e_hw *hw,
     285                 :            :                                 struct i40e_hmc_lan_create_obj_info *info)
     286                 :            : {
     287                 :            :         enum i40e_status_code ret_code = I40E_SUCCESS;
     288                 :            :         struct i40e_hmc_sd_entry *sd_entry;
     289                 :            :         u32 pd_idx1 = 0, pd_lmt1 = 0;
     290                 :            :         u32 pd_idx = 0, pd_lmt = 0;
     291                 :            :         bool pd_error = false;
     292                 :            :         u32 sd_idx, sd_lmt;
     293                 :            :         u64 sd_size;
     294                 :            :         u32 i, j;
     295                 :            : 
     296         [ #  # ]:          0 :         if (NULL == info) {
     297                 :            :                 ret_code = I40E_ERR_BAD_PTR;
     298                 :          0 :                 DEBUGOUT("i40e_create_lan_hmc_object: bad info ptr\n");
     299                 :          0 :                 goto exit;
     300                 :            :         }
     301         [ #  # ]:          0 :         if (NULL == info->hmc_info) {
     302                 :            :                 ret_code = I40E_ERR_BAD_PTR;
     303                 :          0 :                 DEBUGOUT("i40e_create_lan_hmc_object: bad hmc_info ptr\n");
     304                 :          0 :                 goto exit;
     305                 :            :         }
     306         [ #  # ]:          0 :         if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) {
     307                 :            :                 ret_code = I40E_ERR_BAD_PTR;
     308                 :          0 :                 DEBUGOUT("i40e_create_lan_hmc_object: bad signature\n");
     309                 :          0 :                 goto exit;
     310                 :            :         }
     311                 :            : 
     312         [ #  # ]:          0 :         if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
     313                 :            :                 ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
     314                 :          0 :                 DEBUGOUT1("i40e_create_lan_hmc_object: returns error %d\n",
     315                 :            :                           ret_code);
     316                 :          0 :                 goto exit;
     317                 :            :         }
     318         [ #  # ]:          0 :         if ((info->start_idx + info->count) >
     319                 :            :             info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
     320                 :            :                 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
     321                 :          0 :                 DEBUGOUT1("i40e_create_lan_hmc_object: returns error %d\n",
     322                 :            :                           ret_code);
     323                 :          0 :                 goto exit;
     324                 :            :         }
     325                 :            : 
     326                 :            :         /* find sd index and limit */
     327                 :          0 :         I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
     328                 :            :                                  info->start_idx, info->count,
     329                 :            :                                  &sd_idx, &sd_lmt);
     330   [ #  #  #  # ]:          0 :         if (sd_idx >= info->hmc_info->sd_table.sd_cnt ||
     331                 :            :             sd_lmt > info->hmc_info->sd_table.sd_cnt) {
     332                 :            :                         ret_code = I40E_ERR_INVALID_SD_INDEX;
     333                 :          0 :                         goto exit;
     334                 :            :         }
     335                 :            :         /* find pd index */
     336                 :          0 :         I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
     337                 :            :                                  info->start_idx, info->count, &pd_idx,
     338                 :            :                                  &pd_lmt);
     339                 :            : 
     340                 :            :         /* This is to cover for cases where you may not want to have an SD with
     341                 :            :          * the full 2M memory but something smaller. By not filling out any
     342                 :            :          * size, the function will default the SD size to be 2M.
     343                 :            :          */
     344         [ #  # ]:          0 :         if (info->direct_mode_sz == 0)
     345                 :            :                 sd_size = I40E_HMC_DIRECT_BP_SIZE;
     346                 :            :         else
     347                 :            :                 sd_size = info->direct_mode_sz;
     348                 :            : 
     349                 :            :         /* check if all the sds are valid. If not, allocate a page and
     350                 :            :          * initialize it.
     351                 :            :          */
     352         [ #  # ]:          0 :         for (j = sd_idx; j < sd_lmt; j++) {
     353                 :            :                 /* update the sd table entry */
     354                 :          0 :                 ret_code = i40e_add_sd_table_entry(hw, info->hmc_info, j,
     355                 :            :                                                    info->entry_type,
     356                 :            :                                                    sd_size);
     357         [ #  # ]:          0 :                 if (I40E_SUCCESS != ret_code)
     358                 :          0 :                         goto exit_sd_error;
     359                 :          0 :                 sd_entry = &info->hmc_info->sd_table.sd_entry[j];
     360         [ #  # ]:          0 :                 if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) {
     361                 :            :                         /* check if all the pds in this sd are valid. If not,
     362                 :            :                          * allocate a page and initialize it.
     363                 :            :                          */
     364                 :            : 
     365                 :            :                         /* find pd_idx and pd_lmt in this sd */
     366                 :          0 :                         pd_idx1 = max(pd_idx, (j * I40E_HMC_MAX_BP_COUNT));
     367                 :          0 :                         pd_lmt1 = min(pd_lmt,
     368                 :            :                                       ((j + 1) * I40E_HMC_MAX_BP_COUNT));
     369         [ #  # ]:          0 :                         for (i = pd_idx1; i < pd_lmt1; i++) {
     370                 :            :                                 /* update the pd table entry */
     371                 :          0 :                                 ret_code = i40e_add_pd_table_entry(hw,
     372                 :            :                                                                 info->hmc_info,
     373                 :            :                                                                 i, NULL);
     374         [ #  # ]:          0 :                                 if (I40E_SUCCESS != ret_code) {
     375                 :            :                                         pd_error = true;
     376                 :            :                                         break;
     377                 :            :                                 }
     378                 :            :                         }
     379         [ #  # ]:          0 :                         if (pd_error) {
     380                 :            :                                 /* remove the backing pages from pd_idx1 to i */
     381         [ #  # ]:          0 :                                 while (i && (i > pd_idx1)) {
     382                 :          0 :                                         i40e_remove_pd_bp(hw, info->hmc_info,
     383                 :            :                                                           (i - 1));
     384                 :            :                                         i--;
     385                 :            :                                 }
     386                 :            :                         }
     387                 :            :                 }
     388         [ #  # ]:          0 :                 if (!sd_entry->valid) {
     389                 :          0 :                         sd_entry->valid = true;
     390      [ #  #  # ]:          0 :                         switch (sd_entry->entry_type) {
     391                 :          0 :                         case I40E_SD_TYPE_PAGED:
     392                 :          0 :                                 I40E_SET_PF_SD_ENTRY(hw,
     393                 :            :                                         sd_entry->u.pd_table.pd_page_addr.pa,
     394                 :            :                                         j, sd_entry->entry_type);
     395                 :            :                                 break;
     396                 :          0 :                         case I40E_SD_TYPE_DIRECT:
     397                 :          0 :                                 I40E_SET_PF_SD_ENTRY(hw, sd_entry->u.bp.addr.pa,
     398                 :            :                                                      j, sd_entry->entry_type);
     399                 :            :                                 break;
     400                 :          0 :                         default:
     401                 :            :                                 ret_code = I40E_ERR_INVALID_SD_TYPE;
     402                 :          0 :                                 goto exit;
     403                 :            :                         }
     404                 :            :                 }
     405                 :            :         }
     406                 :          0 :         goto exit;
     407                 :            : 
     408                 :            : exit_sd_error:
     409                 :            :         /* cleanup for sd entries from j to sd_idx */
     410   [ #  #  #  # ]:          0 :         while (j && (j > sd_idx)) {
     411                 :          0 :                 sd_entry = &info->hmc_info->sd_table.sd_entry[j - 1];
     412      [ #  #  # ]:          0 :                 switch (sd_entry->entry_type) {
     413                 :          0 :                 case I40E_SD_TYPE_PAGED:
     414                 :          0 :                         pd_idx1 = max(pd_idx,
     415                 :            :                                       ((j - 1) * I40E_HMC_MAX_BP_COUNT));
     416                 :          0 :                         pd_lmt1 = min(pd_lmt, (j * I40E_HMC_MAX_BP_COUNT));
     417         [ #  # ]:          0 :                         for (i = pd_idx1; i < pd_lmt1; i++)
     418                 :          0 :                                 i40e_remove_pd_bp(hw, info->hmc_info, i);
     419                 :          0 :                         i40e_remove_pd_page(hw, info->hmc_info, (j - 1));
     420                 :          0 :                         break;
     421                 :          0 :                 case I40E_SD_TYPE_DIRECT:
     422                 :          0 :                         i40e_remove_sd_bp(hw, info->hmc_info, (j - 1));
     423                 :          0 :                         break;
     424                 :            :                 default:
     425                 :            :                         ret_code = I40E_ERR_INVALID_SD_TYPE;
     426                 :            :                         break;
     427                 :            :                 }
     428                 :            :                 j--;
     429                 :            :         }
     430                 :          0 : exit:
     431                 :          0 :         return ret_code;
     432                 :            : }
     433                 :            : 
     434                 :            : /**
     435                 :            :  * i40e_configure_lan_hmc - prepare the HMC backing store
     436                 :            :  * @hw: pointer to the hw structure
     437                 :            :  * @model: the model for the layout of the SD/PD tables
     438                 :            :  *
     439                 :            :  * - This function will be called once per physical function initialization.
     440                 :            :  * - This function will be called after i40e_init_lan_hmc() and before
     441                 :            :  *   any LAN/FCoE HMC objects can be created.
     442                 :            :  **/
     443                 :          0 : enum i40e_status_code i40e_configure_lan_hmc(struct i40e_hw *hw,
     444                 :            :                                              enum i40e_hmc_model model)
     445                 :            : {
     446                 :            :         struct i40e_hmc_lan_create_obj_info info;
     447                 :          0 :         u8 hmc_fn_id = hw->hmc.hmc_fn_id;
     448                 :            :         struct i40e_hmc_obj_info *obj;
     449                 :            :         enum i40e_status_code ret_code = I40E_SUCCESS;
     450                 :            : 
     451                 :            :         /* Initialize part of the create object info struct */
     452                 :          0 :         info.hmc_info = &hw->hmc;
     453                 :          0 :         info.rsrc_type = I40E_HMC_LAN_FULL;
     454                 :          0 :         info.start_idx = 0;
     455                 :          0 :         info.direct_mode_sz = hw->hmc.hmc_obj[I40E_HMC_LAN_FULL].size;
     456                 :            : 
     457                 :            :         /* Build the SD entry for the LAN objects */
     458      [ #  #  # ]:          0 :         switch (model) {
     459                 :          0 :         case I40E_HMC_MODEL_DIRECT_PREFERRED:
     460                 :            :         case I40E_HMC_MODEL_DIRECT_ONLY:
     461                 :          0 :                 info.entry_type = I40E_SD_TYPE_DIRECT;
     462                 :            :                 /* Make one big object, a single SD */
     463                 :          0 :                 info.count = 1;
     464                 :          0 :                 ret_code = i40e_create_lan_hmc_object(hw, &info);
     465         [ #  # ]:          0 :                 if ((ret_code != I40E_SUCCESS) && (model == I40E_HMC_MODEL_DIRECT_PREFERRED))
     466                 :          0 :                         goto try_type_paged;
     467         [ #  # ]:          0 :                 else if (ret_code != I40E_SUCCESS)
     468                 :          0 :                         goto configure_lan_hmc_out;
     469                 :            :                 /* else clause falls through the break */
     470                 :            :                 break;
     471                 :            :         case I40E_HMC_MODEL_PAGED_ONLY:
     472                 :          0 : try_type_paged:
     473                 :          0 :                 info.entry_type = I40E_SD_TYPE_PAGED;
     474                 :            :                 /* Make one big object in the PD table */
     475                 :          0 :                 info.count = 1;
     476                 :          0 :                 ret_code = i40e_create_lan_hmc_object(hw, &info);
     477         [ #  # ]:          0 :                 if (ret_code != I40E_SUCCESS)
     478                 :          0 :                         goto configure_lan_hmc_out;
     479                 :            :                 break;
     480                 :          0 :         default:
     481                 :            :                 /* unsupported type */
     482                 :            :                 ret_code = I40E_ERR_INVALID_SD_TYPE;
     483                 :          0 :                 DEBUGOUT1("i40e_configure_lan_hmc: Unknown SD type: %d\n",
     484                 :            :                           ret_code);
     485                 :          0 :                 goto configure_lan_hmc_out;
     486                 :            :         }
     487                 :            : 
     488                 :            :         /* Configure and program the FPM registers so objects can be created */
     489                 :            : 
     490                 :            :         /* Tx contexts */
     491                 :          0 :         obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_TX];
     492                 :          0 :         wr32(hw, I40E_GLHMC_LANTXBASE(hmc_fn_id),
     493                 :            :              (u32)((obj->base & I40E_GLHMC_LANTXBASE_FPMLANTXBASE_MASK) / 512));
     494                 :          0 :         wr32(hw, I40E_GLHMC_LANTXCNT(hmc_fn_id), obj->cnt);
     495                 :            : 
     496                 :            :         /* Rx contexts */
     497                 :          0 :         obj = &hw->hmc.hmc_obj[I40E_HMC_LAN_RX];
     498                 :          0 :         wr32(hw, I40E_GLHMC_LANRXBASE(hmc_fn_id),
     499                 :            :              (u32)((obj->base & I40E_GLHMC_LANRXBASE_FPMLANRXBASE_MASK) / 512));
     500                 :          0 :         wr32(hw, I40E_GLHMC_LANRXCNT(hmc_fn_id), obj->cnt);
     501                 :            : 
     502                 :            :         /* FCoE contexts */
     503                 :          0 :         obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_CTX];
     504                 :          0 :         wr32(hw, I40E_GLHMC_FCOEDDPBASE(hmc_fn_id),
     505                 :            :          (u32)((obj->base & I40E_GLHMC_FCOEDDPBASE_FPMFCOEDDPBASE_MASK) / 512));
     506                 :          0 :         wr32(hw, I40E_GLHMC_FCOEDDPCNT(hmc_fn_id), obj->cnt);
     507                 :            : 
     508                 :            :         /* FCoE filters */
     509                 :          0 :         obj = &hw->hmc.hmc_obj[I40E_HMC_FCOE_FILT];
     510                 :          0 :         wr32(hw, I40E_GLHMC_FCOEFBASE(hmc_fn_id),
     511                 :            :              (u32)((obj->base & I40E_GLHMC_FCOEFBASE_FPMFCOEFBASE_MASK) / 512));
     512                 :          0 :         wr32(hw, I40E_GLHMC_FCOEFCNT(hmc_fn_id), obj->cnt);
     513                 :            : 
     514                 :          0 : configure_lan_hmc_out:
     515                 :          0 :         return ret_code;
     516                 :            : }
     517                 :            : 
     518                 :            : /**
     519                 :            :  * i40e_delete_lan_hmc_object - remove hmc objects
     520                 :            :  * @hw: pointer to the HW structure
     521                 :            :  * @info: pointer to i40e_hmc_delete_obj_info struct
     522                 :            :  *
     523                 :            :  * This will de-populate the SDs and PDs.  It frees
     524                 :            :  * the memory for PDS and backing storage.  After this function is returned,
     525                 :            :  * caller should deallocate memory allocated previously for
     526                 :            :  * book-keeping information about PDs and backing storage.
     527                 :            :  **/
     528                 :          0 : enum i40e_status_code i40e_delete_lan_hmc_object(struct i40e_hw *hw,
     529                 :            :                                 struct i40e_hmc_lan_delete_obj_info *info)
     530                 :            : {
     531                 :            :         enum i40e_status_code ret_code = I40E_SUCCESS;
     532                 :            :         struct i40e_hmc_pd_table *pd_table;
     533                 :            :         u32 pd_idx, pd_lmt, rel_pd_idx;
     534                 :            :         u32 sd_idx, sd_lmt;
     535                 :            :         u32 i, j;
     536                 :            : 
     537         [ #  # ]:          0 :         if (NULL == info) {
     538                 :            :                 ret_code = I40E_ERR_BAD_PTR;
     539                 :          0 :                 DEBUGOUT("i40e_delete_hmc_object: bad info ptr\n");
     540                 :          0 :                 goto exit;
     541                 :            :         }
     542         [ #  # ]:          0 :         if (NULL == info->hmc_info) {
     543                 :            :                 ret_code = I40E_ERR_BAD_PTR;
     544                 :          0 :                 DEBUGOUT("i40e_delete_hmc_object: bad info->hmc_info ptr\n");
     545                 :          0 :                 goto exit;
     546                 :            :         }
     547         [ #  # ]:          0 :         if (I40E_HMC_INFO_SIGNATURE != info->hmc_info->signature) {
     548                 :            :                 ret_code = I40E_ERR_BAD_PTR;
     549                 :          0 :                 DEBUGOUT("i40e_delete_hmc_object: bad hmc_info->signature\n");
     550                 :          0 :                 goto exit;
     551                 :            :         }
     552                 :            : 
     553         [ #  # ]:          0 :         if (NULL == info->hmc_info->sd_table.sd_entry) {
     554                 :            :                 ret_code = I40E_ERR_BAD_PTR;
     555                 :          0 :                 DEBUGOUT("i40e_delete_hmc_object: bad sd_entry\n");
     556                 :          0 :                 goto exit;
     557                 :            :         }
     558                 :            : 
     559         [ #  # ]:          0 :         if (NULL == info->hmc_info->hmc_obj) {
     560                 :            :                 ret_code = I40E_ERR_BAD_PTR;
     561                 :          0 :                 DEBUGOUT("i40e_delete_hmc_object: bad hmc_info->hmc_obj\n");
     562                 :          0 :                 goto exit;
     563                 :            :         }
     564         [ #  # ]:          0 :         if (info->start_idx >= info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
     565                 :            :                 ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
     566                 :          0 :                 DEBUGOUT1("i40e_delete_hmc_object: returns error %d\n",
     567                 :            :                           ret_code);
     568                 :          0 :                 goto exit;
     569                 :            :         }
     570                 :            : 
     571         [ #  # ]:          0 :         if ((info->start_idx + info->count) >
     572                 :            :             info->hmc_info->hmc_obj[info->rsrc_type].cnt) {
     573                 :            :                 ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
     574                 :          0 :                 DEBUGOUT1("i40e_delete_hmc_object: returns error %d\n",
     575                 :            :                           ret_code);
     576                 :          0 :                 goto exit;
     577                 :            :         }
     578                 :            : 
     579                 :          0 :         I40E_FIND_PD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
     580                 :            :                                  info->start_idx, info->count, &pd_idx,
     581                 :            :                                  &pd_lmt);
     582                 :            : 
     583         [ #  # ]:          0 :         for (j = pd_idx; j < pd_lmt; j++) {
     584                 :          0 :                 sd_idx = j / I40E_HMC_PD_CNT_IN_SD;
     585                 :            : 
     586                 :          0 :                 if (I40E_SD_TYPE_PAGED !=
     587         [ #  # ]:          0 :                     info->hmc_info->sd_table.sd_entry[sd_idx].entry_type)
     588                 :          0 :                         continue;
     589                 :            : 
     590                 :          0 :                 rel_pd_idx = j % I40E_HMC_PD_CNT_IN_SD;
     591                 :            : 
     592                 :            :                 pd_table =
     593                 :            :                         &info->hmc_info->sd_table.sd_entry[sd_idx].u.pd_table;
     594         [ #  # ]:          0 :                 if (pd_table->pd_entry[rel_pd_idx].valid) {
     595                 :          0 :                         ret_code = i40e_remove_pd_bp(hw, info->hmc_info, j);
     596         [ #  # ]:          0 :                         if (I40E_SUCCESS != ret_code)
     597                 :          0 :                                 goto exit;
     598                 :            :                 }
     599                 :            :         }
     600                 :            : 
     601                 :            :         /* find sd index and limit */
     602                 :          0 :         I40E_FIND_SD_INDEX_LIMIT(info->hmc_info, info->rsrc_type,
     603                 :            :                                  info->start_idx, info->count,
     604                 :            :                                  &sd_idx, &sd_lmt);
     605   [ #  #  #  # ]:          0 :         if (sd_idx >= info->hmc_info->sd_table.sd_cnt ||
     606                 :            :             sd_lmt > info->hmc_info->sd_table.sd_cnt) {
     607                 :            :                 ret_code = I40E_ERR_INVALID_SD_INDEX;
     608                 :          0 :                 goto exit;
     609                 :            :         }
     610                 :            : 
     611         [ #  # ]:          0 :         for (i = sd_idx; i < sd_lmt; i++) {
     612         [ #  # ]:          0 :                 if (!info->hmc_info->sd_table.sd_entry[i].valid)
     613                 :          0 :                         continue;
     614      [ #  #  # ]:          0 :                 switch (info->hmc_info->sd_table.sd_entry[i].entry_type) {
     615                 :          0 :                 case I40E_SD_TYPE_DIRECT:
     616                 :          0 :                         ret_code = i40e_remove_sd_bp(hw, info->hmc_info, i);
     617         [ #  # ]:          0 :                         if (I40E_SUCCESS != ret_code)
     618                 :          0 :                                 goto exit;
     619                 :            :                         break;
     620                 :          0 :                 case I40E_SD_TYPE_PAGED:
     621                 :          0 :                         ret_code = i40e_remove_pd_page(hw, info->hmc_info, i);
     622         [ #  # ]:          0 :                         if (I40E_SUCCESS != ret_code)
     623                 :          0 :                                 goto exit;
     624                 :            :                         break;
     625                 :            :                 default:
     626                 :            :                         break;
     627                 :            :                 }
     628                 :            :         }
     629                 :          0 : exit:
     630                 :          0 :         return ret_code;
     631                 :            : }
     632                 :            : 
     633                 :            : /**
     634                 :            :  * i40e_shutdown_lan_hmc - Remove HMC backing store, free allocated memory
     635                 :            :  * @hw: pointer to the hw structure
     636                 :            :  *
     637                 :            :  * This must be called by drivers as they are shutting down and being
     638                 :            :  * removed from the OS.
     639                 :            :  **/
     640                 :          0 : enum i40e_status_code i40e_shutdown_lan_hmc(struct i40e_hw *hw)
     641                 :            : {
     642                 :            :         struct i40e_hmc_lan_delete_obj_info info;
     643                 :            :         enum i40e_status_code ret_code;
     644                 :            : 
     645                 :          0 :         info.hmc_info = &hw->hmc;
     646                 :          0 :         info.rsrc_type = I40E_HMC_LAN_FULL;
     647                 :          0 :         info.start_idx = 0;
     648                 :          0 :         info.count = 1;
     649                 :            : 
     650                 :            :         /* delete the object */
     651                 :          0 :         ret_code = i40e_delete_lan_hmc_object(hw, &info);
     652                 :            : 
     653                 :            :         /* free the SD table entry for LAN */
     654                 :          0 :         i40e_free_virt_mem(hw, &hw->hmc.sd_table.addr);
     655                 :          0 :         hw->hmc.sd_table.sd_cnt = 0;
     656                 :          0 :         hw->hmc.sd_table.sd_entry = NULL;
     657                 :            : 
     658                 :            :         /* free memory used for hmc_obj */
     659                 :          0 :         i40e_free_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem);
     660                 :          0 :         hw->hmc.hmc_obj = NULL;
     661                 :            : 
     662                 :          0 :         return ret_code;
     663                 :            : }
     664                 :            : 
     665                 :            : #define I40E_HMC_STORE(_struct, _ele)           \
     666                 :            :         offsetof(struct _struct, _ele),         \
     667                 :            :         FIELD_SIZEOF(struct _struct, _ele)
     668                 :            : 
     669                 :            : struct i40e_context_ele {
     670                 :            :         u16 offset;
     671                 :            :         u16 size_of;
     672                 :            :         u16 width;
     673                 :            :         u16 lsb;
     674                 :            : };
     675                 :            : 
     676                 :            : /* LAN Tx Queue Context */
     677                 :            : static struct i40e_context_ele i40e_hmc_txq_ce_info[] = {
     678                 :            :                                              /* Field      Width    LSB */
     679                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, head),           13,      0 },
     680                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, new_context),     1,     30 },
     681                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, base),           57,     32 },
     682                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, fc_ena),          1,     89 },
     683                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, timesync_ena),    1,     90 },
     684                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, fd_ena),          1,     91 },
     685                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, alt_vlan_ena),    1,     92 },
     686                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, cpuid),           8,     96 },
     687                 :            : /* line 1 */
     688                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, thead_wb),       13,  0 + 128 },
     689                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_ena),     1, 32 + 128 },
     690                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, qlen),           13, 33 + 128 },
     691                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, tphrdesc_ena),    1, 46 + 128 },
     692                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, tphrpacket_ena),  1, 47 + 128 },
     693                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, tphwdesc_ena),    1, 48 + 128 },
     694                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, head_wb_addr),   64, 64 + 128 },
     695                 :            : /* line 7 */
     696                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, crc),            32,  0 + (7 * 128) },
     697                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist),        10, 84 + (7 * 128) },
     698                 :            :         {I40E_HMC_STORE(i40e_hmc_obj_txq, rdylist_act),     1, 94 + (7 * 128) },
     699                 :            :         { 0 }
     700                 :            : };
     701                 :            : 
     702                 :            : /* LAN Rx Queue Context */
     703                 :            : static struct i40e_context_ele i40e_hmc_rxq_ce_info[] = {
     704                 :            :                                          /* Field      Width    LSB */
     705                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, head),        13,    0   },
     706                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, cpuid),        8,    13  },
     707                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, base),        57,    32  },
     708                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, qlen),        13,    89  },
     709                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, dbuff),        7,    102 },
     710                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, hbuff),        5,    109 },
     711                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, dtype),        2,    114 },
     712                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, dsize),        1,    116 },
     713                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, crcstrip),     1,    117 },
     714                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, fc_ena),       1,    118 },
     715                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, l2tsel),       1,    119 },
     716                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_0),     4,    120 },
     717                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, hsplit_1),     2,    124 },
     718                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, showiv),       1,    127 },
     719                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, rxmax),       14,    174 },
     720                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphrdesc_ena), 1,    193 },
     721                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphwdesc_ena), 1,    194 },
     722                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena),  1,    195 },
     723                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena),  1,    196 },
     724                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh),   3,    198 },
     725                 :            :         { I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena),      1,    201 },
     726                 :            :         { 0 }
     727                 :            : };
     728                 :            : 
     729                 :            : /**
     730                 :            :  * i40e_write_byte - replace HMC context byte
     731                 :            :  * @hmc_bits: pointer to the HMC memory
     732                 :            :  * @ce_info: a description of the struct to be read from
     733                 :            :  * @src: the struct to be read from
     734                 :            :  **/
     735                 :          0 : static void i40e_write_byte(u8 *hmc_bits,
     736                 :            :                             struct i40e_context_ele *ce_info,
     737                 :            :                             u8 *src)
     738                 :            : {
     739                 :            :         u8 src_byte, dest_byte, mask;
     740                 :            :         u8 *from, *dest;
     741                 :            :         u16 shift_width;
     742                 :            : 
     743                 :            :         /* copy from the next struct field */
     744                 :          0 :         from = src + ce_info->offset;
     745                 :            : 
     746                 :            :         /* prepare the bits and mask */
     747                 :          0 :         shift_width = ce_info->lsb % 8;
     748                 :          0 :         mask = (u8)(BIT(ce_info->width) - 1);
     749                 :            : 
     750                 :          0 :         src_byte = *from;
     751                 :          0 :         src_byte &= mask;
     752                 :            : 
     753                 :            :         /* shift to correct alignment */
     754                 :          0 :         mask <<= shift_width;
     755                 :          0 :         src_byte <<= shift_width;
     756                 :            : 
     757                 :            :         /* get the current bits from the target bit string */
     758         [ #  # ]:          0 :         dest = hmc_bits + (ce_info->lsb / 8);
     759                 :            : 
     760                 :            :         i40e_memcpy(&dest_byte, dest, sizeof(dest_byte), I40E_DMA_TO_NONDMA);
     761                 :            : 
     762                 :          0 :         dest_byte &= ~mask; /* get the bits not changing */
     763         [ #  # ]:          0 :         dest_byte |= src_byte;  /* add in the new bits */
     764                 :            : 
     765                 :            :         /* put it all back */
     766                 :            :         i40e_memcpy(dest, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA);
     767                 :          0 : }
     768                 :            : 
     769                 :            : /**
     770                 :            :  * i40e_write_word - replace HMC context word
     771                 :            :  * @hmc_bits: pointer to the HMC memory
     772                 :            :  * @ce_info: a description of the struct to be read from
     773                 :            :  * @src: the struct to be read from
     774                 :            :  **/
     775                 :          0 : static void i40e_write_word(u8 *hmc_bits,
     776                 :            :                             struct i40e_context_ele *ce_info,
     777                 :            :                             u8 *src)
     778                 :            : {
     779                 :            :         u16 src_word, mask;
     780                 :            :         u8 *from, *dest;
     781                 :            :         u16 shift_width;
     782                 :            :         __le16 dest_word;
     783                 :            : 
     784                 :            :         /* copy from the next struct field */
     785                 :          0 :         from = src + ce_info->offset;
     786                 :            : 
     787                 :            :         /* prepare the bits and mask */
     788                 :          0 :         shift_width = ce_info->lsb % 8;
     789                 :          0 :         mask = BIT(ce_info->width) - 1;
     790                 :            : 
     791                 :            :         /* don't swizzle the bits until after the mask because the mask bits
     792                 :            :          * will be in a different bit position on big endian machines
     793                 :            :          */
     794                 :          0 :         src_word = *(u16 *)from;
     795                 :          0 :         src_word &= mask;
     796                 :            : 
     797                 :            :         /* shift to correct alignment */
     798                 :          0 :         mask <<= shift_width;
     799                 :          0 :         src_word <<= shift_width;
     800                 :            : 
     801                 :            :         /* get the current bits from the target bit string */
     802         [ #  # ]:          0 :         dest = hmc_bits + (ce_info->lsb / 8);
     803                 :            : 
     804                 :            :         i40e_memcpy(&dest_word, dest, sizeof(dest_word), I40E_DMA_TO_NONDMA);
     805                 :            : 
     806                 :          0 :         dest_word &= ~(CPU_TO_LE16(mask));  /* get the bits not changing */
     807         [ #  # ]:          0 :         dest_word |= CPU_TO_LE16(src_word);     /* add in the new bits */
     808                 :            : 
     809                 :            :         /* put it all back */
     810                 :            :         i40e_memcpy(dest, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA);
     811                 :          0 : }
     812                 :            : 
     813                 :            : /**
     814                 :            :  * i40e_write_dword - replace HMC context dword
     815                 :            :  * @hmc_bits: pointer to the HMC memory
     816                 :            :  * @ce_info: a description of the struct to be read from
     817                 :            :  * @src: the struct to be read from
     818                 :            :  **/
     819                 :          0 : static void i40e_write_dword(u8 *hmc_bits,
     820                 :            :                              struct i40e_context_ele *ce_info,
     821                 :            :                              u8 *src)
     822                 :            : {
     823                 :            :         u32 src_dword, mask;
     824                 :            :         u8 *from, *dest;
     825                 :            :         u16 shift_width;
     826                 :            :         __le32 dest_dword;
     827                 :            : 
     828                 :            :         /* copy from the next struct field */
     829                 :          0 :         from = src + ce_info->offset;
     830                 :            : 
     831                 :            :         /* prepare the bits and mask */
     832                 :          0 :         shift_width = ce_info->lsb % 8;
     833                 :            : 
     834                 :            :         /* if the field width is exactly 32 on an x86 machine, then the shift
     835                 :            :          * operation will not work because the SHL instructions count is masked
     836                 :            :          * to 5 bits so the shift will do nothing
     837                 :            :          */
     838         [ #  # ]:          0 :         if (ce_info->width < 32)
     839                 :          0 :                 mask = BIT(ce_info->width) - 1;
     840                 :            :         else
     841                 :            :                 mask = ~(u32)0;
     842                 :            : 
     843                 :            :         /* don't swizzle the bits until after the mask because the mask bits
     844                 :            :          * will be in a different bit position on big endian machines
     845                 :            :          */
     846                 :          0 :         src_dword = *(u32 *)from;
     847                 :          0 :         src_dword &= mask;
     848                 :            : 
     849                 :            :         /* shift to correct alignment */
     850                 :          0 :         mask <<= shift_width;
     851                 :          0 :         src_dword <<= shift_width;
     852                 :            : 
     853                 :            :         /* get the current bits from the target bit string */
     854         [ #  # ]:          0 :         dest = hmc_bits + (ce_info->lsb / 8);
     855                 :            : 
     856                 :            :         i40e_memcpy(&dest_dword, dest, sizeof(dest_dword), I40E_DMA_TO_NONDMA);
     857                 :            : 
     858                 :          0 :         dest_dword &= ~(CPU_TO_LE32(mask)); /* get the bits not changing */
     859         [ #  # ]:          0 :         dest_dword |= CPU_TO_LE32(src_dword);   /* add in the new bits */
     860                 :            : 
     861                 :            :         /* put it all back */
     862                 :            :         i40e_memcpy(dest, &dest_dword, sizeof(dest_dword), I40E_NONDMA_TO_DMA);
     863                 :          0 : }
     864                 :            : 
     865                 :            : /**
     866                 :            :  * i40e_write_qword - replace HMC context qword
     867                 :            :  * @hmc_bits: pointer to the HMC memory
     868                 :            :  * @ce_info: a description of the struct to be read from
     869                 :            :  * @src: the struct to be read from
     870                 :            :  **/
     871                 :          0 : static void i40e_write_qword(u8 *hmc_bits,
     872                 :            :                              struct i40e_context_ele *ce_info,
     873                 :            :                              u8 *src)
     874                 :            : {
     875                 :            :         u64 src_qword, mask;
     876                 :            :         u8 *from, *dest;
     877                 :            :         u16 shift_width;
     878                 :            :         __le64 dest_qword;
     879                 :            : 
     880                 :            :         /* copy from the next struct field */
     881                 :          0 :         from = src + ce_info->offset;
     882                 :            : 
     883                 :            :         /* prepare the bits and mask */
     884                 :          0 :         shift_width = ce_info->lsb % 8;
     885                 :            : 
     886                 :            :         /* if the field width is exactly 64 on an x86 machine, then the shift
     887                 :            :          * operation will not work because the SHL instructions count is masked
     888                 :            :          * to 6 bits so the shift will do nothing
     889                 :            :          */
     890         [ #  # ]:          0 :         if (ce_info->width < 64)
     891                 :          0 :                 mask = BIT_ULL(ce_info->width) - 1;
     892                 :            :         else
     893                 :            :                 mask = ~(u64)0;
     894                 :            : 
     895                 :            :         /* don't swizzle the bits until after the mask because the mask bits
     896                 :            :          * will be in a different bit position on big endian machines
     897                 :            :          */
     898                 :          0 :         src_qword = *(u64 *)from;
     899                 :          0 :         src_qword &= mask;
     900                 :            : 
     901                 :            :         /* shift to correct alignment */
     902                 :          0 :         mask <<= shift_width;
     903                 :          0 :         src_qword <<= shift_width;
     904                 :            : 
     905                 :            :         /* get the current bits from the target bit string */
     906         [ #  # ]:          0 :         dest = hmc_bits + (ce_info->lsb / 8);
     907                 :            : 
     908                 :            :         i40e_memcpy(&dest_qword, dest, sizeof(dest_qword), I40E_DMA_TO_NONDMA);
     909                 :            : 
     910                 :          0 :         dest_qword &= ~(CPU_TO_LE64(mask)); /* get the bits not changing */
     911         [ #  # ]:          0 :         dest_qword |= CPU_TO_LE64(src_qword);   /* add in the new bits */
     912                 :            : 
     913                 :            :         /* put it all back */
     914                 :            :         i40e_memcpy(dest, &dest_qword, sizeof(dest_qword), I40E_NONDMA_TO_DMA);
     915                 :          0 : }
     916                 :            : 
     917                 :            : /**
     918                 :            :  * i40e_read_byte - read HMC context byte into struct
     919                 :            :  * @hmc_bits: pointer to the HMC memory
     920                 :            :  * @ce_info: a description of the struct to be filled
     921                 :            :  * @dest: the struct to be filled
     922                 :            :  **/
     923                 :          0 : static void i40e_read_byte(u8 *hmc_bits,
     924                 :            :                            struct i40e_context_ele *ce_info,
     925                 :            :                            u8 *dest)
     926                 :            : {
     927                 :            :         u8 dest_byte, mask;
     928                 :            :         u8 *src, *target;
     929                 :            :         u16 shift_width;
     930                 :            : 
     931                 :            :         /* prepare the bits and mask */
     932                 :          0 :         shift_width = ce_info->lsb % 8;
     933                 :          0 :         mask = (u8)(BIT(ce_info->width) - 1);
     934                 :            : 
     935                 :            :         /* shift to correct alignment */
     936                 :          0 :         mask <<= shift_width;
     937                 :            : 
     938                 :            :         /* get the current bits from the src bit string */
     939         [ #  # ]:          0 :         src = hmc_bits + (ce_info->lsb / 8);
     940                 :            : 
     941                 :            :         i40e_memcpy(&dest_byte, src, sizeof(dest_byte), I40E_DMA_TO_NONDMA);
     942                 :            : 
     943                 :          0 :         dest_byte &= ~(mask);
     944                 :            : 
     945                 :          0 :         dest_byte >>= shift_width;
     946                 :            : 
     947                 :            :         /* get the address from the struct field */
     948         [ #  # ]:          0 :         target = dest + ce_info->offset;
     949                 :            : 
     950                 :            :         /* put it back in the struct */
     951                 :            :         i40e_memcpy(target, &dest_byte, sizeof(dest_byte), I40E_NONDMA_TO_DMA);
     952                 :          0 : }
     953                 :            : 
     954                 :            : /**
     955                 :            :  * i40e_read_word - read HMC context word into struct
     956                 :            :  * @hmc_bits: pointer to the HMC memory
     957                 :            :  * @ce_info: a description of the struct to be filled
     958                 :            :  * @dest: the struct to be filled
     959                 :            :  **/
     960                 :          0 : static void i40e_read_word(u8 *hmc_bits,
     961                 :            :                            struct i40e_context_ele *ce_info,
     962                 :            :                            u8 *dest)
     963                 :            : {
     964                 :            :         u16 dest_word, mask;
     965                 :            :         u8 *src, *target;
     966                 :            :         u16 shift_width;
     967                 :            :         __le16 src_word;
     968                 :            : 
     969                 :            :         /* prepare the bits and mask */
     970                 :          0 :         shift_width = ce_info->lsb % 8;
     971                 :          0 :         mask = BIT(ce_info->width) - 1;
     972                 :            : 
     973                 :            :         /* shift to correct alignment */
     974                 :          0 :         mask <<= shift_width;
     975                 :            : 
     976                 :            :         /* get the current bits from the src bit string */
     977         [ #  # ]:          0 :         src = hmc_bits + (ce_info->lsb / 8);
     978                 :            : 
     979                 :            :         i40e_memcpy(&src_word, src, sizeof(src_word), I40E_DMA_TO_NONDMA);
     980                 :            : 
     981                 :            :         /* the data in the memory is stored as little endian so mask it
     982                 :            :          * correctly
     983                 :            :          */
     984                 :          0 :         src_word &= ~(CPU_TO_LE16(mask));
     985                 :            : 
     986                 :            :         /* get the data back into host order before shifting */
     987                 :            :         dest_word = LE16_TO_CPU(src_word);
     988                 :            : 
     989                 :          0 :         dest_word >>= shift_width;
     990                 :            : 
     991                 :            :         /* get the address from the struct field */
     992         [ #  # ]:          0 :         target = dest + ce_info->offset;
     993                 :            : 
     994                 :            :         /* put it back in the struct */
     995                 :            :         i40e_memcpy(target, &dest_word, sizeof(dest_word), I40E_NONDMA_TO_DMA);
     996                 :          0 : }
     997                 :            : 
     998                 :            : /**
     999                 :            :  * i40e_read_dword - read HMC context dword into struct
    1000                 :            :  * @hmc_bits: pointer to the HMC memory
    1001                 :            :  * @ce_info: a description of the struct to be filled
    1002                 :            :  * @dest: the struct to be filled
    1003                 :            :  **/
    1004                 :          0 : static void i40e_read_dword(u8 *hmc_bits,
    1005                 :            :                             struct i40e_context_ele *ce_info,
    1006                 :            :                             u8 *dest)
    1007                 :            : {
    1008                 :            :         u32 dest_dword, mask;
    1009                 :            :         u8 *src, *target;
    1010                 :            :         u16 shift_width;
    1011                 :            :         __le32 src_dword;
    1012                 :            : 
    1013                 :            :         /* prepare the bits and mask */
    1014                 :          0 :         shift_width = ce_info->lsb % 8;
    1015                 :            : 
    1016                 :            :         /* if the field width is exactly 32 on an x86 machine, then the shift
    1017                 :            :          * operation will not work because the SHL instructions count is masked
    1018                 :            :          * to 5 bits so the shift will do nothing
    1019                 :            :          */
    1020         [ #  # ]:          0 :         if (ce_info->width < 32)
    1021                 :          0 :                 mask = BIT(ce_info->width) - 1;
    1022                 :            :         else
    1023                 :            :                 mask = ~(u32)0;
    1024                 :            : 
    1025                 :            :         /* shift to correct alignment */
    1026                 :          0 :         mask <<= shift_width;
    1027                 :            : 
    1028                 :            :         /* get the current bits from the src bit string */
    1029         [ #  # ]:          0 :         src = hmc_bits + (ce_info->lsb / 8);
    1030                 :            : 
    1031                 :            :         i40e_memcpy(&src_dword, src, sizeof(src_dword), I40E_DMA_TO_NONDMA);
    1032                 :            : 
    1033                 :            :         /* the data in the memory is stored as little endian so mask it
    1034                 :            :          * correctly
    1035                 :            :          */
    1036                 :          0 :         src_dword &= ~(CPU_TO_LE32(mask));
    1037                 :            : 
    1038                 :            :         /* get the data back into host order before shifting */
    1039                 :            :         dest_dword = LE32_TO_CPU(src_dword);
    1040                 :            : 
    1041                 :          0 :         dest_dword >>= shift_width;
    1042                 :            : 
    1043                 :            :         /* get the address from the struct field */
    1044         [ #  # ]:          0 :         target = dest + ce_info->offset;
    1045                 :            : 
    1046                 :            :         /* put it back in the struct */
    1047                 :            :         i40e_memcpy(target, &dest_dword, sizeof(dest_dword),
    1048                 :            :                     I40E_NONDMA_TO_DMA);
    1049                 :          0 : }
    1050                 :            : 
    1051                 :            : /**
    1052                 :            :  * i40e_read_qword - read HMC context qword into struct
    1053                 :            :  * @hmc_bits: pointer to the HMC memory
    1054                 :            :  * @ce_info: a description of the struct to be filled
    1055                 :            :  * @dest: the struct to be filled
    1056                 :            :  **/
    1057                 :          0 : static void i40e_read_qword(u8 *hmc_bits,
    1058                 :            :                             struct i40e_context_ele *ce_info,
    1059                 :            :                             u8 *dest)
    1060                 :            : {
    1061                 :            :         u64 dest_qword, mask;
    1062                 :            :         u8 *src, *target;
    1063                 :            :         u16 shift_width;
    1064                 :            :         __le64 src_qword;
    1065                 :            : 
    1066                 :            :         /* prepare the bits and mask */
    1067                 :          0 :         shift_width = ce_info->lsb % 8;
    1068                 :            : 
    1069                 :            :         /* if the field width is exactly 64 on an x86 machine, then the shift
    1070                 :            :          * operation will not work because the SHL instructions count is masked
    1071                 :            :          * to 6 bits so the shift will do nothing
    1072                 :            :          */
    1073         [ #  # ]:          0 :         if (ce_info->width < 64)
    1074                 :          0 :                 mask = BIT_ULL(ce_info->width) - 1;
    1075                 :            :         else
    1076                 :            :                 mask = ~(u64)0;
    1077                 :            : 
    1078                 :            :         /* shift to correct alignment */
    1079                 :          0 :         mask <<= shift_width;
    1080                 :            : 
    1081                 :            :         /* get the current bits from the src bit string */
    1082         [ #  # ]:          0 :         src = hmc_bits + (ce_info->lsb / 8);
    1083                 :            : 
    1084                 :            :         i40e_memcpy(&src_qword, src, sizeof(src_qword), I40E_DMA_TO_NONDMA);
    1085                 :            : 
    1086                 :            :         /* the data in the memory is stored as little endian so mask it
    1087                 :            :          * correctly
    1088                 :            :          */
    1089                 :          0 :         src_qword &= ~(CPU_TO_LE64(mask));
    1090                 :            : 
    1091                 :            :         /* get the data back into host order before shifting */
    1092                 :            :         dest_qword = LE64_TO_CPU(src_qword);
    1093                 :            : 
    1094                 :          0 :         dest_qword >>= shift_width;
    1095                 :            : 
    1096                 :            :         /* get the address from the struct field */
    1097         [ #  # ]:          0 :         target = dest + ce_info->offset;
    1098                 :            : 
    1099                 :            :         /* put it back in the struct */
    1100                 :            :         i40e_memcpy(target, &dest_qword, sizeof(dest_qword),
    1101                 :            :                     I40E_NONDMA_TO_DMA);
    1102                 :          0 : }
    1103                 :            : 
    1104                 :            : /**
    1105                 :            :  * i40e_get_hmc_context - extract HMC context bits
    1106                 :            :  * @context_bytes: pointer to the context bit array
    1107                 :            :  * @ce_info: a description of the struct to be filled
    1108                 :            :  * @dest: the struct to be filled
    1109                 :            :  **/
    1110                 :          0 : static enum i40e_status_code i40e_get_hmc_context(u8 *context_bytes,
    1111                 :            :                                         struct i40e_context_ele *ce_info,
    1112                 :            :                                         u8 *dest)
    1113                 :            : {
    1114                 :            :         int f;
    1115                 :            : 
    1116         [ #  # ]:          0 :         for (f = 0; ce_info[f].width != 0; f++) {
    1117   [ #  #  #  #  :          0 :                 switch (ce_info[f].size_of) {
                      # ]
    1118                 :          0 :                 case 1:
    1119                 :          0 :                         i40e_read_byte(context_bytes, &ce_info[f], dest);
    1120                 :          0 :                         break;
    1121                 :          0 :                 case 2:
    1122                 :          0 :                         i40e_read_word(context_bytes, &ce_info[f], dest);
    1123                 :          0 :                         break;
    1124                 :          0 :                 case 4:
    1125                 :          0 :                         i40e_read_dword(context_bytes, &ce_info[f], dest);
    1126                 :          0 :                         break;
    1127                 :          0 :                 case 8:
    1128                 :          0 :                         i40e_read_qword(context_bytes, &ce_info[f], dest);
    1129                 :          0 :                         break;
    1130                 :            :                 default:
    1131                 :            :                         /* nothing to do, just keep going */
    1132                 :            :                         break;
    1133                 :            :                 }
    1134                 :            :         }
    1135                 :            : 
    1136                 :          0 :         return I40E_SUCCESS;
    1137                 :            : }
    1138                 :            : 
    1139                 :            : /**
    1140                 :            :  * i40e_clear_hmc_context - zero out the HMC context bits
    1141                 :            :  * @hw:       the hardware struct
    1142                 :            :  * @context_bytes: pointer to the context bit array (DMA memory)
    1143                 :            :  * @hmc_type: the type of HMC resource
    1144                 :            :  **/
    1145                 :            : static enum i40e_status_code i40e_clear_hmc_context(struct i40e_hw *hw,
    1146                 :            :                                         u8 *context_bytes,
    1147                 :            :                                         enum i40e_hmc_lan_rsrc_type hmc_type)
    1148                 :            : {
    1149                 :            :         /* clean the bit array */
    1150                 :          0 :         i40e_memset(context_bytes, 0, (u32)hw->hmc.hmc_obj[hmc_type].size,
    1151                 :            :                     I40E_DMA_MEM);
    1152                 :            : 
    1153                 :            :         return I40E_SUCCESS;
    1154                 :            : }
    1155                 :            : 
    1156                 :            : /**
    1157                 :            :  * i40e_set_hmc_context - replace HMC context bits
    1158                 :            :  * @context_bytes: pointer to the context bit array
    1159                 :            :  * @ce_info:  a description of the struct to be filled
    1160                 :            :  * @dest:     the struct to be filled
    1161                 :            :  **/
    1162                 :          0 : static enum i40e_status_code i40e_set_hmc_context(u8 *context_bytes,
    1163                 :            :                                         struct i40e_context_ele *ce_info,
    1164                 :            :                                         u8 *dest)
    1165                 :            : {
    1166                 :            :         int f;
    1167                 :            : 
    1168         [ #  # ]:          0 :         for (f = 0; ce_info[f].width != 0; f++) {
    1169                 :            : 
    1170                 :            :                 /* we have to deal with each element of the HMC using the
    1171                 :            :                  * correct size so that we are correct regardless of the
    1172                 :            :                  * endianness of the machine
    1173                 :            :                  */
    1174   [ #  #  #  #  :          0 :                 switch (ce_info[f].size_of) {
                      # ]
    1175                 :          0 :                 case 1:
    1176                 :          0 :                         i40e_write_byte(context_bytes, &ce_info[f], dest);
    1177                 :          0 :                         break;
    1178                 :          0 :                 case 2:
    1179                 :          0 :                         i40e_write_word(context_bytes, &ce_info[f], dest);
    1180                 :          0 :                         break;
    1181                 :          0 :                 case 4:
    1182                 :          0 :                         i40e_write_dword(context_bytes, &ce_info[f], dest);
    1183                 :          0 :                         break;
    1184                 :          0 :                 case 8:
    1185                 :          0 :                         i40e_write_qword(context_bytes, &ce_info[f], dest);
    1186                 :          0 :                         break;
    1187                 :            :                 }
    1188                 :            :         }
    1189                 :            : 
    1190                 :          0 :         return I40E_SUCCESS;
    1191                 :            : }
    1192                 :            : 
    1193                 :            : /**
    1194                 :            :  * i40e_hmc_get_object_va - retrieves an object's virtual address
    1195                 :            :  * @hw: pointer to the hw structure
    1196                 :            :  * @object_base: pointer to u64 to get the va
    1197                 :            :  * @rsrc_type: the hmc resource type
    1198                 :            :  * @obj_idx: hmc object index
    1199                 :            :  *
    1200                 :            :  * This function retrieves the object's virtual address from the object
    1201                 :            :  * base pointer.  This function is used for LAN Queue contexts.
    1202                 :            :  **/
    1203                 :            : STATIC
    1204                 :          0 : enum i40e_status_code i40e_hmc_get_object_va(struct i40e_hw *hw,
    1205                 :            :                                         u8 **object_base,
    1206                 :            :                                         enum i40e_hmc_lan_rsrc_type rsrc_type,
    1207                 :            :                                         u32 obj_idx)
    1208                 :            : {
    1209                 :            :         u32 obj_offset_in_sd, obj_offset_in_pd;
    1210                 :            :         struct i40e_hmc_info     *hmc_info = &hw->hmc;
    1211                 :            :         struct i40e_hmc_sd_entry *sd_entry;
    1212                 :            :         struct i40e_hmc_pd_entry *pd_entry;
    1213                 :            :         u32 pd_idx, pd_lmt, rel_pd_idx;
    1214                 :            :         enum i40e_status_code ret_code = I40E_SUCCESS;
    1215                 :            :         u64 obj_offset_in_fpm;
    1216                 :            :         u32 sd_idx, sd_lmt;
    1217                 :            : 
    1218         [ #  # ]:          0 :         if (NULL == hmc_info->hmc_obj) {
    1219                 :            :                 ret_code = I40E_ERR_BAD_PTR;
    1220                 :          0 :                 DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info->hmc_obj ptr\n");
    1221                 :          0 :                 goto exit;
    1222                 :            :         }
    1223         [ #  # ]:          0 :         if (NULL == object_base) {
    1224                 :            :                 ret_code = I40E_ERR_BAD_PTR;
    1225                 :          0 :                 DEBUGOUT("i40e_hmc_get_object_va: bad object_base ptr\n");
    1226                 :          0 :                 goto exit;
    1227                 :            :         }
    1228         [ #  # ]:          0 :         if (I40E_HMC_INFO_SIGNATURE != hmc_info->signature) {
    1229                 :            :                 ret_code = I40E_ERR_BAD_PTR;
    1230                 :          0 :                 DEBUGOUT("i40e_hmc_get_object_va: bad hmc_info->signature\n");
    1231                 :          0 :                 goto exit;
    1232                 :            :         }
    1233         [ #  # ]:          0 :         if (obj_idx >= hmc_info->hmc_obj[rsrc_type].cnt) {
    1234                 :          0 :                 DEBUGOUT1("i40e_hmc_get_object_va: returns error %d\n",
    1235                 :            :                           ret_code);
    1236                 :            :                 ret_code = I40E_ERR_INVALID_HMC_OBJ_INDEX;
    1237                 :          0 :                 goto exit;
    1238                 :            :         }
    1239                 :            :         /* find sd index and limit */
    1240                 :          0 :         I40E_FIND_SD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1,
    1241                 :            :                                  &sd_idx, &sd_lmt);
    1242                 :            : 
    1243                 :          0 :         sd_entry = &hmc_info->sd_table.sd_entry[sd_idx];
    1244                 :            :         obj_offset_in_fpm = hmc_info->hmc_obj[rsrc_type].base +
    1245                 :            :                             hmc_info->hmc_obj[rsrc_type].size * obj_idx;
    1246                 :            : 
    1247         [ #  # ]:          0 :         if (I40E_SD_TYPE_PAGED == sd_entry->entry_type) {
    1248                 :          0 :                 I40E_FIND_PD_INDEX_LIMIT(hmc_info, rsrc_type, obj_idx, 1,
    1249                 :            :                                          &pd_idx, &pd_lmt);
    1250                 :          0 :                 rel_pd_idx = pd_idx % I40E_HMC_PD_CNT_IN_SD;
    1251                 :          0 :                 pd_entry = &sd_entry->u.pd_table.pd_entry[rel_pd_idx];
    1252                 :          0 :                 obj_offset_in_pd = (u32)(obj_offset_in_fpm %
    1253                 :            :                                          I40E_HMC_PAGED_BP_SIZE);
    1254                 :          0 :                 *object_base = (u8 *)pd_entry->bp.addr.va + obj_offset_in_pd;
    1255                 :            :         } else {
    1256                 :          0 :                 obj_offset_in_sd = (u32)(obj_offset_in_fpm %
    1257                 :            :                                          I40E_HMC_DIRECT_BP_SIZE);
    1258                 :          0 :                 *object_base = (u8 *)sd_entry->u.bp.addr.va + obj_offset_in_sd;
    1259                 :            :         }
    1260                 :          0 : exit:
    1261                 :          0 :         return ret_code;
    1262                 :            : }
    1263                 :            : 
    1264                 :            : /**
    1265                 :            :  * i40e_get_lan_tx_queue_context - return the HMC context for the queue
    1266                 :            :  * @hw:    the hardware struct
    1267                 :            :  * @queue: the queue we care about
    1268                 :            :  * @s:     the struct to be filled
    1269                 :            :  **/
    1270                 :          0 : enum i40e_status_code i40e_get_lan_tx_queue_context(struct i40e_hw *hw,
    1271                 :            :                                                     u16 queue,
    1272                 :            :                                                     struct i40e_hmc_obj_txq *s)
    1273                 :            : {
    1274                 :            :         enum i40e_status_code err;
    1275                 :            :         u8 *context_bytes;
    1276                 :            : 
    1277                 :          0 :         err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue);
    1278         [ #  # ]:          0 :         if (err < 0)
    1279                 :            :                 return err;
    1280                 :            : 
    1281                 :          0 :         return i40e_get_hmc_context(context_bytes,
    1282                 :            :                                     i40e_hmc_txq_ce_info, (u8 *)s);
    1283                 :            : }
    1284                 :            : 
    1285                 :            : /**
    1286                 :            :  * i40e_clear_lan_tx_queue_context - clear the HMC context for the queue
    1287                 :            :  * @hw:    the hardware struct
    1288                 :            :  * @queue: the queue we care about
    1289                 :            :  **/
    1290                 :          0 : enum i40e_status_code i40e_clear_lan_tx_queue_context(struct i40e_hw *hw,
    1291                 :            :                                                       u16 queue)
    1292                 :            : {
    1293                 :            :         enum i40e_status_code err;
    1294                 :            :         u8 *context_bytes;
    1295                 :            : 
    1296                 :          0 :         err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue);
    1297         [ #  # ]:          0 :         if (err < 0)
    1298                 :            :                 return err;
    1299                 :            : 
    1300                 :          0 :         return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_TX);
    1301                 :            : }
    1302                 :            : 
    1303                 :            : /**
    1304                 :            :  * i40e_set_lan_tx_queue_context - set the HMC context for the queue
    1305                 :            :  * @hw:    the hardware struct
    1306                 :            :  * @queue: the queue we care about
    1307                 :            :  * @s:     the struct to be filled
    1308                 :            :  **/
    1309                 :          0 : enum i40e_status_code i40e_set_lan_tx_queue_context(struct i40e_hw *hw,
    1310                 :            :                                                     u16 queue,
    1311                 :            :                                                     struct i40e_hmc_obj_txq *s)
    1312                 :            : {
    1313                 :            :         enum i40e_status_code err;
    1314                 :            :         u8 *context_bytes;
    1315                 :            : 
    1316                 :          0 :         err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_TX, queue);
    1317         [ #  # ]:          0 :         if (err < 0)
    1318                 :            :                 return err;
    1319                 :            : 
    1320                 :          0 :         return i40e_set_hmc_context(context_bytes,
    1321                 :            :                                     i40e_hmc_txq_ce_info, (u8 *)s);
    1322                 :            : }
    1323                 :            : 
    1324                 :            : /**
    1325                 :            :  * i40e_get_lan_rx_queue_context - return the HMC context for the queue
    1326                 :            :  * @hw:    the hardware struct
    1327                 :            :  * @queue: the queue we care about
    1328                 :            :  * @s:     the struct to be filled
    1329                 :            :  **/
    1330                 :          0 : enum i40e_status_code i40e_get_lan_rx_queue_context(struct i40e_hw *hw,
    1331                 :            :                                                     u16 queue,
    1332                 :            :                                                     struct i40e_hmc_obj_rxq *s)
    1333                 :            : {
    1334                 :            :         enum i40e_status_code err;
    1335                 :            :         u8 *context_bytes;
    1336                 :            : 
    1337                 :          0 :         err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue);
    1338         [ #  # ]:          0 :         if (err < 0)
    1339                 :            :                 return err;
    1340                 :            : 
    1341                 :          0 :         return i40e_get_hmc_context(context_bytes,
    1342                 :            :                                     i40e_hmc_rxq_ce_info, (u8 *)s);
    1343                 :            : }
    1344                 :            : 
    1345                 :            : /**
    1346                 :            :  * i40e_clear_lan_rx_queue_context - clear the HMC context for the queue
    1347                 :            :  * @hw:    the hardware struct
    1348                 :            :  * @queue: the queue we care about
    1349                 :            :  **/
    1350                 :          0 : enum i40e_status_code i40e_clear_lan_rx_queue_context(struct i40e_hw *hw,
    1351                 :            :                                                       u16 queue)
    1352                 :            : {
    1353                 :            :         enum i40e_status_code err;
    1354                 :            :         u8 *context_bytes;
    1355                 :            : 
    1356                 :          0 :         err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue);
    1357         [ #  # ]:          0 :         if (err < 0)
    1358                 :            :                 return err;
    1359                 :            : 
    1360                 :          0 :         return i40e_clear_hmc_context(hw, context_bytes, I40E_HMC_LAN_RX);
    1361                 :            : }
    1362                 :            : 
    1363                 :            : /**
    1364                 :            :  * i40e_set_lan_rx_queue_context - set the HMC context for the queue
    1365                 :            :  * @hw:    the hardware struct
    1366                 :            :  * @queue: the queue we care about
    1367                 :            :  * @s:     the struct to be filled
    1368                 :            :  **/
    1369                 :          0 : enum i40e_status_code i40e_set_lan_rx_queue_context(struct i40e_hw *hw,
    1370                 :            :                                                     u16 queue,
    1371                 :            :                                                     struct i40e_hmc_obj_rxq *s)
    1372                 :            : {
    1373                 :            :         enum i40e_status_code err;
    1374                 :            :         u8 *context_bytes;
    1375                 :            : 
    1376                 :          0 :         err = i40e_hmc_get_object_va(hw, &context_bytes, I40E_HMC_LAN_RX, queue);
    1377         [ #  # ]:          0 :         if (err < 0)
    1378                 :            :                 return err;
    1379                 :            : 
    1380                 :          0 :         return i40e_set_hmc_context(context_bytes,
    1381                 :            :                                     i40e_hmc_rxq_ce_info, (u8 *)s);
    1382                 :            : }

Generated by: LCOV version 1.14