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

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: BSD-3-Clause
       2                 :            :  * Copyright(c) 2001-2023 Intel Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "ice_ddp.h"
       6                 :            : #include "ice_type.h"
       7                 :            : #include "ice_common.h"
       8                 :            : #include "ice_sched.h"
       9                 :            : 
      10                 :            : /**
      11                 :            :  * ice_aq_download_pkg
      12                 :            :  * @hw: pointer to the hardware structure
      13                 :            :  * @pkg_buf: the package buffer to transfer
      14                 :            :  * @buf_size: the size of the package buffer
      15                 :            :  * @last_buf: last buffer indicator
      16                 :            :  * @error_offset: returns error offset
      17                 :            :  * @error_info: returns error information
      18                 :            :  * @cd: pointer to command details structure or NULL
      19                 :            :  *
      20                 :            :  * Download Package (0x0C40)
      21                 :            :  */
      22                 :            : static int
      23                 :          0 : ice_aq_download_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,
      24                 :            :                     u16 buf_size, bool last_buf, u32 *error_offset,
      25                 :            :                     u32 *error_info, struct ice_sq_cd *cd)
      26                 :            : {
      27                 :            :         struct ice_aqc_download_pkg *cmd;
      28                 :            :         struct ice_aq_desc desc;
      29                 :            :         int status;
      30                 :            : 
      31         [ #  # ]:          0 :         if (error_offset)
      32                 :          0 :                 *error_offset = 0;
      33         [ #  # ]:          0 :         if (error_info)
      34                 :          0 :                 *error_info = 0;
      35                 :            : 
      36                 :            :         cmd = &desc.params.download_pkg;
      37                 :          0 :         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_download_pkg);
      38                 :          0 :         desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
      39                 :            : 
      40         [ #  # ]:          0 :         if (last_buf)
      41                 :          0 :                 cmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF;
      42                 :            : 
      43                 :          0 :         status = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);
      44         [ #  # ]:          0 :         if (status == ICE_ERR_AQ_ERROR) {
      45                 :            :                 /* Read error from buffer only when the FW returned an error */
      46                 :            :                 struct ice_aqc_download_pkg_resp *resp;
      47                 :            : 
      48                 :            :                 resp = (struct ice_aqc_download_pkg_resp *)pkg_buf;
      49         [ #  # ]:          0 :                 if (error_offset)
      50                 :          0 :                         *error_offset = LE32_TO_CPU(resp->error_offset);
      51         [ #  # ]:          0 :                 if (error_info)
      52                 :          0 :                         *error_info = LE32_TO_CPU(resp->error_info);
      53                 :            :         }
      54                 :            : 
      55                 :          0 :         return status;
      56                 :            : }
      57                 :            : 
      58                 :            : /**
      59                 :            :  * ice_aq_upload_section
      60                 :            :  * @hw: pointer to the hardware structure
      61                 :            :  * @pkg_buf: the package buffer which will receive the section
      62                 :            :  * @buf_size: the size of the package buffer
      63                 :            :  * @cd: pointer to command details structure or NULL
      64                 :            :  *
      65                 :            :  * Upload Section (0x0C41)
      66                 :            :  */
      67                 :            : int
      68                 :          0 : ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,
      69                 :            :                       u16 buf_size, struct ice_sq_cd *cd)
      70                 :            : {
      71                 :            :         struct ice_aq_desc desc;
      72                 :            : 
      73                 :          0 :         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_upload_section);
      74                 :          0 :         desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
      75                 :            : 
      76                 :          0 :         return ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);
      77                 :            : }
      78                 :            : 
      79                 :            : /**
      80                 :            :  * ice_aq_update_pkg
      81                 :            :  * @hw: pointer to the hardware structure
      82                 :            :  * @pkg_buf: the package cmd buffer
      83                 :            :  * @buf_size: the size of the package cmd buffer
      84                 :            :  * @last_buf: last buffer indicator
      85                 :            :  * @error_offset: returns error offset
      86                 :            :  * @error_info: returns error information
      87                 :            :  * @cd: pointer to command details structure or NULL
      88                 :            :  *
      89                 :            :  * Update Package (0x0C42)
      90                 :            :  */
      91                 :            : static int
      92                 :          0 : ice_aq_update_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf, u16 buf_size,
      93                 :            :                   bool last_buf, u32 *error_offset, u32 *error_info,
      94                 :            :                   struct ice_sq_cd *cd)
      95                 :            : {
      96                 :            :         struct ice_aqc_download_pkg *cmd;
      97                 :            :         struct ice_aq_desc desc;
      98                 :            :         int status;
      99                 :            : 
     100         [ #  # ]:          0 :         if (error_offset)
     101                 :          0 :                 *error_offset = 0;
     102         [ #  # ]:          0 :         if (error_info)
     103                 :          0 :                 *error_info = 0;
     104                 :            : 
     105                 :            :         cmd = &desc.params.download_pkg;
     106                 :          0 :         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_pkg);
     107                 :          0 :         desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
     108                 :            : 
     109         [ #  # ]:          0 :         if (last_buf)
     110                 :          0 :                 cmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF;
     111                 :            : 
     112                 :          0 :         status = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);
     113         [ #  # ]:          0 :         if (status == ICE_ERR_AQ_ERROR) {
     114                 :            :                 /* Read error from buffer only when the FW returned an error */
     115                 :            :                 struct ice_aqc_download_pkg_resp *resp;
     116                 :            : 
     117                 :            :                 resp = (struct ice_aqc_download_pkg_resp *)pkg_buf;
     118         [ #  # ]:          0 :                 if (error_offset)
     119                 :          0 :                         *error_offset = LE32_TO_CPU(resp->error_offset);
     120         [ #  # ]:          0 :                 if (error_info)
     121                 :          0 :                         *error_info = LE32_TO_CPU(resp->error_info);
     122                 :            :         }
     123                 :            : 
     124                 :          0 :         return status;
     125                 :            : }
     126                 :            : 
     127                 :            : /**
     128                 :            :  * ice_find_seg_in_pkg
     129                 :            :  * @hw: pointer to the hardware structure
     130                 :            :  * @seg_type: the segment type to search for (i.e., SEGMENT_TYPE_CPK)
     131                 :            :  * @pkg_hdr: pointer to the package header to be searched
     132                 :            :  *
     133                 :            :  * This function searches a package file for a particular segment type. On
     134                 :            :  * success it returns a pointer to the segment header, otherwise it will
     135                 :            :  * return NULL.
     136                 :            :  */
     137                 :            : struct ice_generic_seg_hdr *
     138                 :          0 : ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,
     139                 :            :                     struct ice_pkg_hdr *pkg_hdr)
     140                 :            : {
     141                 :            :         u32 i;
     142                 :            : 
     143         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_PKG, "Package format version: %d.%d.%d.%d\n",
     144                 :            :                   pkg_hdr->pkg_format_ver.major, pkg_hdr->pkg_format_ver.minor,
     145                 :            :                   pkg_hdr->pkg_format_ver.update,
     146                 :            :                   pkg_hdr->pkg_format_ver.draft);
     147                 :            : 
     148                 :            :         /* Search all package segments for the requested segment type */
     149         [ #  # ]:          0 :         for (i = 0; i < LE32_TO_CPU(pkg_hdr->seg_count); i++) {
     150                 :            :                 struct ice_generic_seg_hdr *seg;
     151                 :            : 
     152                 :          0 :                 seg = (struct ice_generic_seg_hdr *)
     153                 :          0 :                         ((u8 *)pkg_hdr + LE32_TO_CPU(pkg_hdr->seg_offset[i]));
     154                 :            : 
     155         [ #  # ]:          0 :                 if (LE32_TO_CPU(seg->seg_type) == seg_type)
     156                 :          0 :                         return seg;
     157                 :            :         }
     158                 :            : 
     159                 :            :         return NULL;
     160                 :            : }
     161                 :            : 
     162                 :            : /**
     163                 :            :  * ice_get_pkg_seg_by_idx
     164                 :            :  * @pkg_hdr: pointer to the package header to be searched
     165                 :            :  * @idx: index of segment
     166                 :            :  */
     167                 :            : static struct ice_generic_seg_hdr *
     168                 :            : ice_get_pkg_seg_by_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx)
     169                 :            : {
     170                 :            :         struct ice_generic_seg_hdr *seg = NULL;
     171                 :            : 
     172                 :          0 :         if (idx < LE32_TO_CPU(pkg_hdr->seg_count))
     173                 :          0 :                 seg = (struct ice_generic_seg_hdr *)
     174                 :            :                         ((u8 *)pkg_hdr +
     175                 :          0 :                          LE32_TO_CPU(pkg_hdr->seg_offset[idx]));
     176                 :            : 
     177                 :            :         return seg;
     178                 :            : }
     179                 :            : 
     180                 :            : /**
     181                 :            :  * ice_is_signing_seg_at_idx - determine if segment is a signing segment
     182                 :            :  * @pkg_hdr: pointer to package header
     183                 :            :  * @idx: segment index
     184                 :            :  */
     185                 :            : static bool ice_is_signing_seg_at_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx)
     186                 :            : {
     187                 :            :         struct ice_generic_seg_hdr *seg;
     188                 :            :         bool retval = false;
     189                 :            : 
     190                 :            :         seg = ice_get_pkg_seg_by_idx(pkg_hdr, idx);
     191                 :            :         if (seg)
     192                 :          0 :                 retval = LE32_TO_CPU(seg->seg_type) == SEGMENT_TYPE_SIGNING;
     193                 :            : 
     194                 :            :         return retval;
     195                 :            : }
     196                 :            : 
     197                 :            : /**
     198                 :            :  * ice_is_signing_seg_type_at_idx
     199                 :            :  * @pkg_hdr: pointer to package header
     200                 :            :  * @idx: segment index
     201                 :            :  * @seg_id: segment id that is expected
     202                 :            :  * @sign_type: signing type
     203                 :            :  *
     204                 :            :  * Determine if a segment is a signing segment of the correct type
     205                 :            :  */
     206                 :            : static bool
     207                 :            : ice_is_signing_seg_type_at_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx,
     208                 :            :                                u32 seg_id, u32 sign_type)
     209                 :            : {
     210                 :            :         bool result = false;
     211                 :            : 
     212         [ #  # ]:          0 :         if (ice_is_signing_seg_at_idx(pkg_hdr, idx)) {
     213                 :            :                 struct ice_sign_seg *seg;
     214                 :            : 
     215                 :            :                 seg = (struct ice_sign_seg *)ice_get_pkg_seg_by_idx(pkg_hdr,
     216                 :            :                                                                     idx);
     217   [ #  #  #  # ]:          0 :                 if (seg && LE32_TO_CPU(seg->seg_id) == seg_id &&
     218   [ #  #  #  # ]:          0 :                     LE32_TO_CPU(seg->sign_type) == sign_type)
     219                 :            :                         result = true;
     220                 :            :         }
     221                 :            : 
     222                 :            :         return result;
     223                 :            : }
     224                 :            : 
     225                 :            : /**
     226                 :            :  * ice_update_pkg_no_lock
     227                 :            :  * @hw: pointer to the hardware structure
     228                 :            :  * @bufs: pointer to an array of buffers
     229                 :            :  * @count: the number of buffers in the array
     230                 :            :  */
     231                 :            : int
     232                 :          0 : ice_update_pkg_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
     233                 :            : {
     234                 :            :         int status = 0;
     235                 :            :         u32 i;
     236                 :            : 
     237         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     238                 :          0 :                 struct ice_buf_hdr *bh = (struct ice_buf_hdr *)(bufs + i);
     239                 :          0 :                 bool last = ((i + 1) == count);
     240                 :            :                 u32 offset, info;
     241                 :            : 
     242                 :          0 :                 status = ice_aq_update_pkg(hw, bh, LE16_TO_CPU(bh->data_end),
     243                 :            :                                            last, &offset, &info, NULL);
     244                 :            : 
     245         [ #  # ]:          0 :                 if (status) {
     246         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_PKG, "Update pkg failed: err %d off %d inf %d\n",
     247                 :            :                                   status, offset, info);
     248                 :          0 :                         break;
     249                 :            :                 }
     250                 :            :         }
     251                 :            : 
     252                 :          0 :         return status;
     253                 :            : }
     254                 :            : 
     255                 :            : /**
     256                 :            :  * ice_update_pkg
     257                 :            :  * @hw: pointer to the hardware structure
     258                 :            :  * @bufs: pointer to an array of buffers
     259                 :            :  * @count: the number of buffers in the array
     260                 :            :  *
     261                 :            :  * Obtains change lock and updates package.
     262                 :            :  */
     263                 :            : int
     264                 :          0 : ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
     265                 :            : {
     266                 :            :         int status;
     267                 :            : 
     268                 :          0 :         status = ice_acquire_change_lock(hw, ICE_RES_WRITE);
     269         [ #  # ]:          0 :         if (status)
     270                 :            :                 return status;
     271                 :            : 
     272                 :          0 :         status = ice_update_pkg_no_lock(hw, bufs, count);
     273                 :            : 
     274                 :          0 :         ice_release_change_lock(hw);
     275                 :            : 
     276                 :          0 :         return status;
     277                 :            : }
     278                 :            : 
     279                 :            : static enum ice_ddp_state
     280                 :            : ice_map_aq_err_to_ddp_state(enum ice_aq_err aq_err)
     281                 :            : {
     282                 :            :         switch (aq_err) {
     283                 :            :         case ICE_AQ_RC_ENOSEC:
     284                 :            :                 return ICE_DDP_PKG_NO_SEC_MANIFEST;
     285                 :            :         case ICE_AQ_RC_EBADSIG:
     286                 :            :                 return ICE_DDP_PKG_FILE_SIGNATURE_INVALID;
     287                 :            :         case ICE_AQ_RC_ESVN:
     288                 :            :                 return ICE_DDP_PKG_SECURE_VERSION_NBR_TOO_LOW;
     289                 :            :         case ICE_AQ_RC_EBADMAN:
     290                 :            :                 return ICE_DDP_PKG_MANIFEST_INVALID;
     291                 :            :         case ICE_AQ_RC_EBADBUF:
     292                 :            :                 return ICE_DDP_PKG_BUFFER_INVALID;
     293                 :            :         default:
     294                 :            :                 return ICE_DDP_PKG_ERR;
     295                 :            :         }
     296                 :            : }
     297                 :            : 
     298                 :            : /**
     299                 :            :  * ice_is_buffer_metadata - determine if package buffer is a metadata buffer
     300                 :            :  * @buf: pointer to buffer header
     301                 :            :  */
     302                 :            : static bool ice_is_buffer_metadata(struct ice_buf_hdr *buf)
     303                 :            : {
     304                 :            :         bool metadata = false;
     305                 :            : 
     306         [ #  # ]:          0 :         if (LE32_TO_CPU(buf->section_entry[0].type) & ICE_METADATA_BUF)
     307                 :            :                 metadata = true;
     308                 :            : 
     309                 :            :         return metadata;
     310                 :            : }
     311                 :            : 
     312                 :            : /**
     313                 :            :  * ice_is_last_download_buffer
     314                 :            :  * @buf: pointer to current buffer header
     315                 :            :  * @idx: index of the buffer in the current sequence
     316                 :            :  * @count: the buffer count in the current sequence
     317                 :            :  *
     318                 :            :  * Note: this routine should only be called if the buffer is not the last buffer
     319                 :            :  */
     320                 :            : static bool
     321                 :            : ice_is_last_download_buffer(struct ice_buf_hdr *buf, u32 idx, u32 count)
     322                 :            : {
     323                 :          0 :         bool last = ((idx + 1) == count);
     324                 :            : 
     325                 :            :         /* A set metadata flag in the next buffer will signal that the current
     326                 :            :          * buffer will be the last buffer downloaded
     327                 :            :          */
     328         [ #  # ]:          0 :         if (!last) {
     329                 :            :                 struct ice_buf *next_buf = ((struct ice_buf *)buf) + 1;
     330                 :            : 
     331                 :            :                 last = ice_is_buffer_metadata((struct ice_buf_hdr *)next_buf);
     332                 :            :         }
     333                 :            : 
     334                 :            :         return last;
     335                 :            : }
     336                 :            : 
     337                 :            : /**
     338                 :            :  * ice_dwnld_cfg_bufs_no_lock
     339                 :            :  * @hw: pointer to the hardware structure
     340                 :            :  * @bufs: pointer to an array of buffers
     341                 :            :  * @start: buffer index of first buffer to download
     342                 :            :  * @count: the number of buffers to download
     343                 :            :  * @indicate_last: if true, then set last buffer flag on last buffer download
     344                 :            :  *
     345                 :            :  * Downloads package configuration buffers to the firmware. Metadata buffers
     346                 :            :  * are skipped, and the first metadata buffer found indicates that the rest
     347                 :            :  * of the buffers are all metadata buffers.
     348                 :            :  */
     349                 :            : static enum ice_ddp_state
     350                 :          0 : ice_dwnld_cfg_bufs_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 start,
     351                 :            :                            u32 count, bool indicate_last)
     352                 :            : {
     353                 :            :         enum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;
     354                 :            :         struct ice_buf_hdr *bh;
     355                 :            :         enum ice_aq_err err;
     356                 :            :         u32 offset, info, i;
     357                 :            : 
     358         [ #  # ]:          0 :         if (!bufs || !count)
     359                 :            :                 return ICE_DDP_PKG_ERR;
     360                 :            : 
     361                 :            :         /* If the first buffer's first section has its metadata bit set
     362                 :            :          * then there are no buffers to be downloaded, and the operation is
     363                 :            :          * considered a success.
     364                 :            :          */
     365                 :          0 :         bh = (struct ice_buf_hdr *)(bufs + start);
     366         [ #  # ]:          0 :         if (LE32_TO_CPU(bh->section_entry[0].type) & ICE_METADATA_BUF)
     367                 :            :                 return ICE_DDP_PKG_SUCCESS;
     368                 :            : 
     369         [ #  # ]:          0 :         for (i = 0; i < count; i++) {
     370                 :            :                 bool last = false;
     371                 :            :                 int status;
     372                 :            : 
     373                 :          0 :                 bh = (struct ice_buf_hdr *)(bufs + start + i);
     374                 :            : 
     375         [ #  # ]:          0 :                 if (indicate_last)
     376                 :            :                         last = ice_is_last_download_buffer(bh, i, count);
     377                 :            : 
     378                 :          0 :                 status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE, last,
     379                 :            :                                              &offset, &info, NULL);
     380                 :            : 
     381                 :            :                 /* Save AQ status from download package */
     382         [ #  # ]:          0 :                 if (status) {
     383         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_PKG, "Pkg download failed: err %d off %d inf %d\n",
     384                 :            :                                   status, offset, info);
     385         [ #  # ]:          0 :                         err = hw->adminq.sq_last_status;
     386                 :            :                         state = ice_map_aq_err_to_ddp_state(err);
     387                 :            :                         break;
     388                 :            :                 }
     389                 :            : 
     390         [ #  # ]:          0 :                 if (last)
     391                 :            :                         break;
     392                 :            :         }
     393                 :            : 
     394                 :            :         return state;
     395                 :            : }
     396                 :            : 
     397                 :            : /**
     398                 :            :  * ice_aq_get_pkg_info_list
     399                 :            :  * @hw: pointer to the hardware structure
     400                 :            :  * @pkg_info: the buffer which will receive the information list
     401                 :            :  * @buf_size: the size of the pkg_info information buffer
     402                 :            :  * @cd: pointer to command details structure or NULL
     403                 :            :  *
     404                 :            :  * Get Package Info List (0x0C43)
     405                 :            :  */
     406                 :            : static int
     407                 :            : ice_aq_get_pkg_info_list(struct ice_hw *hw,
     408                 :            :                          struct ice_aqc_get_pkg_info_resp *pkg_info,
     409                 :            :                          u16 buf_size, struct ice_sq_cd *cd)
     410                 :            : {
     411                 :            :         struct ice_aq_desc desc;
     412                 :            : 
     413                 :          0 :         ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_pkg_info_list);
     414                 :            : 
     415                 :          0 :         return ice_aq_send_cmd(hw, &desc, pkg_info, buf_size, cd);
     416                 :            : }
     417                 :            : 
     418                 :            : /**
     419                 :            :  * ice_get_pkg_segment_id - get correct package segment id, based on device
     420                 :            :  * @mac_type: MAC type of the device
     421                 :            :  */
     422                 :            : static u32 ice_get_pkg_segment_id(enum ice_mac_type mac_type)
     423                 :            : {
     424                 :            :         u32 seg_id;
     425                 :            : 
     426                 :          0 :         switch (mac_type) {
     427                 :            :         case ICE_MAC_E830:
     428                 :            :                 seg_id = SEGMENT_TYPE_ICE_E830;
     429                 :            :                 break;
     430                 :          0 :         case ICE_MAC_GENERIC:
     431                 :            :         case ICE_MAC_GENERIC_3K:
     432                 :            :         case ICE_MAC_GENERIC_3K_E825:
     433                 :            :         default:
     434                 :            :                 seg_id = SEGMENT_TYPE_ICE_E810;
     435                 :          0 :                 break;
     436                 :            :         }
     437                 :            : 
     438                 :            :         return seg_id;
     439                 :            : }
     440                 :            : 
     441                 :            : /**
     442                 :            :  * ice_get_pkg_sign_type - get package segment sign type, based on device
     443                 :            :  * @mac_type: MAC type of the device
     444                 :            :  */
     445                 :            : static u32 ice_get_pkg_sign_type(enum ice_mac_type mac_type)
     446                 :            : {
     447                 :            :         u32 sign_type;
     448                 :            : 
     449                 :            :         switch (mac_type) {
     450                 :            :         case ICE_MAC_E830:
     451                 :            :                 sign_type = SEGMENT_SIGN_TYPE_RSA3K_SBB;
     452                 :            :                 break;
     453                 :            :         case ICE_MAC_GENERIC_3K:
     454                 :            :                 sign_type = SEGMENT_SIGN_TYPE_RSA3K;
     455                 :            :                 break;
     456                 :            :         case ICE_MAC_GENERIC_3K_E825:
     457                 :            :                 sign_type = SEGMENT_SIGN_TYPE_RSA3K_E825;
     458                 :            :                 break;
     459                 :            :         case ICE_MAC_GENERIC:
     460                 :            :         default:
     461                 :            :                 sign_type = SEGMENT_SIGN_TYPE_RSA2K;
     462                 :            :                 break;
     463                 :            :         }
     464                 :            : 
     465                 :            :         return sign_type;
     466                 :            : }
     467                 :            : 
     468                 :            : /**
     469                 :            :  * ice_get_signing_req - get correct package requirements, based on device
     470                 :            :  * @hw: pointer to the hardware structure
     471                 :            :  */
     472                 :            : static void ice_get_signing_req(struct ice_hw *hw)
     473                 :            : {
     474   [ #  #  #  # ]:          0 :         hw->pkg_seg_id = ice_get_pkg_segment_id(hw->mac_type);
     475                 :          0 :         hw->pkg_sign_type = ice_get_pkg_sign_type(hw->mac_type);
     476                 :            : }
     477                 :            : 
     478                 :            : /**
     479                 :            :  * ice_download_pkg_sig_seg - download a signature segment
     480                 :            :  * @hw: pointer to the hardware structure
     481                 :            :  * @seg: pointer to signature segment
     482                 :            :  */
     483                 :            : static enum ice_ddp_state
     484                 :            : ice_download_pkg_sig_seg(struct ice_hw *hw, struct ice_sign_seg *seg)
     485                 :            : {
     486                 :            :         enum ice_ddp_state state;
     487                 :            : 
     488                 :          0 :         state = ice_dwnld_cfg_bufs_no_lock(hw, seg->buf_tbl.buf_array, 0,
     489                 :            :                                            LE32_TO_CPU(seg->buf_tbl.buf_count),
     490                 :            :                                            false);
     491                 :            : 
     492                 :            :         return state;
     493                 :            : }
     494                 :            : 
     495                 :            : /**
     496                 :            :  * ice_download_pkg_config_seg - download a config segment
     497                 :            :  * @hw: pointer to the hardware structure
     498                 :            :  * @pkg_hdr: pointer to package header
     499                 :            :  * @idx: segment index
     500                 :            :  * @start: starting buffer
     501                 :            :  * @count: buffer count
     502                 :            :  * @last_seg: last segment being downloaded
     503                 :            :  *
     504                 :            :  * Note: idx must reference a ICE segment
     505                 :            :  */
     506                 :            : static enum ice_ddp_state
     507         [ #  # ]:          0 : ice_download_pkg_config_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,
     508                 :            :                             u32 idx, u32 start, u32 count, bool last_seg)
     509                 :            : {
     510                 :            :         struct ice_buf_table *bufs;
     511                 :            :         enum ice_ddp_state state;
     512                 :            :         struct ice_seg *seg;
     513                 :            :         u32 buf_count;
     514                 :            : 
     515                 :            :         seg = (struct ice_seg *)ice_get_pkg_seg_by_idx(pkg_hdr, idx);
     516                 :            :         if (!seg)
     517                 :            :                 return ICE_DDP_PKG_ERR;
     518                 :            : 
     519                 :          0 :         bufs = ice_find_buf_table(seg);
     520                 :          0 :         buf_count = LE32_TO_CPU(bufs->buf_count);
     521                 :            : 
     522   [ #  #  #  # ]:          0 :         if (start >= buf_count || start + count > buf_count)
     523                 :            :                 return ICE_DDP_PKG_ERR;
     524                 :            : 
     525                 :          0 :         state = ice_dwnld_cfg_bufs_no_lock(hw, bufs->buf_array, start, count,
     526                 :            :                                            last_seg);
     527                 :            : 
     528                 :          0 :         return state;
     529                 :            : }
     530                 :            : 
     531                 :            : /**
     532                 :            :  * ice_dwnld_sign_and_cfg_segs - download a signing segment and config segment
     533                 :            :  * @hw: pointer to the hardware structure
     534                 :            :  * @pkg_hdr: pointer to package header
     535                 :            :  * @idx: segment index (must be a signature segment)
     536                 :            :  *
     537                 :            :  * Note: idx must reference a signature segment
     538                 :            :  */
     539                 :            : static enum ice_ddp_state
     540         [ #  # ]:          0 : ice_dwnld_sign_and_cfg_segs(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,
     541                 :            :                             u32 idx)
     542                 :            : {
     543                 :            :         enum ice_ddp_state state;
     544                 :            :         struct ice_sign_seg *seg;
     545                 :            :         bool last_seg = true;
     546                 :            :         u32 conf_idx;
     547                 :            :         u32 start;
     548                 :            :         u32 count;
     549                 :            :         u32 flags;
     550                 :            : 
     551                 :            :         seg = (struct ice_sign_seg *)ice_get_pkg_seg_by_idx(pkg_hdr, idx);
     552                 :            :         if (!seg) {
     553                 :            :                 state = ICE_DDP_PKG_ERR;
     554                 :          0 :                 goto exit;
     555                 :            :         }
     556                 :            : 
     557                 :          0 :         conf_idx = LE32_TO_CPU(seg->signed_seg_idx);
     558                 :          0 :         start = LE32_TO_CPU(seg->signed_buf_start);
     559                 :          0 :         count = LE32_TO_CPU(seg->signed_buf_count);
     560                 :          0 :         flags = LE32_TO_CPU(seg->flags);
     561                 :            : 
     562         [ #  # ]:          0 :         if (flags & ICE_SIGN_SEG_FLAGS_VALID)
     563                 :            :                 last_seg = !!(flags & ICE_SIGN_SEG_FLAGS_LAST);
     564                 :            : 
     565                 :            :         state = ice_download_pkg_sig_seg(hw, seg);
     566         [ #  # ]:          0 :         if (state)
     567                 :          0 :                 goto exit;
     568                 :            : 
     569         [ #  # ]:          0 :         if (count == 0) {
     570                 :            :                 /* this is a "Reference Signature Segment" and download should
     571                 :            :                  * be only for the buffers in the signature segment (and not
     572                 :            :                  * the hardware configuration segment)
     573                 :            :                  */
     574                 :          0 :                 goto exit;
     575                 :            :         }
     576                 :            : 
     577                 :          0 :         state = ice_download_pkg_config_seg(hw, pkg_hdr, conf_idx, start,
     578                 :            :                                             count, last_seg);
     579                 :            : 
     580                 :          0 : exit:
     581                 :          0 :         return state;
     582                 :            : }
     583                 :            : 
     584                 :            : /**
     585                 :            :  * ice_match_signing_seg - determine if a matching signing segment exists
     586                 :            :  * @pkg_hdr: pointer to package header
     587                 :            :  * @seg_id: segment id that is expected
     588                 :            :  * @sign_type: signing type
     589                 :            :  */
     590                 :            : static bool
     591                 :            : ice_match_signing_seg(struct ice_pkg_hdr *pkg_hdr, u32 seg_id, u32 sign_type)
     592                 :            : {
     593                 :            :         bool match = false;
     594                 :            :         u32 i;
     595                 :            : 
     596         [ #  # ]:          0 :         for (i = 0; i < LE32_TO_CPU(pkg_hdr->seg_count); i++) {
     597                 :            :                 if (ice_is_signing_seg_type_at_idx(pkg_hdr, i, seg_id,
     598                 :            :                                                    sign_type)) {
     599                 :            :                         match = true;
     600                 :            :                         break;
     601                 :            :                 }
     602                 :            :         }
     603                 :            : 
     604                 :            :         return match;
     605                 :            : }
     606                 :            : 
     607                 :            : /**
     608                 :            :  * ice_post_dwnld_pkg_actions - perform post download package actions
     609                 :            :  * @hw: pointer to the hardware structure
     610                 :            :  */
     611                 :            : static enum ice_ddp_state
     612                 :          0 : ice_post_dwnld_pkg_actions(struct ice_hw *hw)
     613                 :            : {
     614                 :            :         enum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;
     615                 :            :         int status;
     616                 :            : 
     617                 :          0 :         status = ice_set_vlan_mode(hw);
     618         [ #  # ]:          0 :         if (status) {
     619         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_PKG, "Failed to set VLAN mode: err %d\n",
     620                 :            :                           status);
     621                 :            :                 state = ICE_DDP_PKG_ERR;
     622                 :            :         }
     623                 :            : 
     624                 :          0 :         return state;
     625                 :            : }
     626                 :            : 
     627                 :            : /**
     628                 :            :  * ice_download_pkg_with_sig_seg - download package using signature segments
     629                 :            :  * @hw: pointer to the hardware structure
     630                 :            :  * @pkg_hdr: pointer to package header
     631                 :            :  */
     632                 :            : static enum ice_ddp_state
     633                 :          0 : ice_download_pkg_with_sig_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
     634                 :            : {
     635                 :          0 :         enum ice_aq_err aq_err = hw->adminq.sq_last_status;
     636                 :            :         enum ice_ddp_state state = ICE_DDP_PKG_ERR;
     637                 :            :         int status;
     638                 :            :         u32 i;
     639                 :            : 
     640         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_INIT, "Segment ID %d\n", hw->pkg_seg_id);
     641         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_INIT, "Signature type %d\n", hw->pkg_sign_type);
     642                 :            : 
     643                 :          0 :         status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);
     644         [ #  # ]:          0 :         if (status) {
     645         [ #  # ]:          0 :                 if (status == ICE_ERR_AQ_NO_WORK)
     646                 :            :                         state = ICE_DDP_PKG_ALREADY_LOADED;
     647                 :            :                 else
     648                 :            :                         state = ice_map_aq_err_to_ddp_state(aq_err);
     649                 :          0 :                 return state;
     650                 :            :         }
     651                 :            : 
     652         [ #  # ]:          0 :         for (i = 0; i < LE32_TO_CPU(pkg_hdr->seg_count); i++) {
     653         [ #  # ]:          0 :                 if (!ice_is_signing_seg_type_at_idx(pkg_hdr, i, hw->pkg_seg_id,
     654                 :            :                                                     hw->pkg_sign_type))
     655                 :          0 :                         continue;
     656                 :            : 
     657                 :          0 :                 state = ice_dwnld_sign_and_cfg_segs(hw, pkg_hdr, i);
     658         [ #  # ]:          0 :                 if (state)
     659                 :            :                         break;
     660                 :            :         }
     661                 :            : 
     662         [ #  # ]:          0 :         if (!state)
     663                 :          0 :                 state = ice_post_dwnld_pkg_actions(hw);
     664                 :            : 
     665                 :          0 :         ice_release_global_cfg_lock(hw);
     666                 :            : 
     667                 :          0 :         return state;
     668                 :            : }
     669                 :            : 
     670                 :            : /**
     671                 :            :  * ice_dwnld_cfg_bufs
     672                 :            :  * @hw: pointer to the hardware structure
     673                 :            :  * @bufs: pointer to an array of buffers
     674                 :            :  * @count: the number of buffers in the array
     675                 :            :  *
     676                 :            :  * Obtains global config lock and downloads the package configuration buffers
     677                 :            :  * to the firmware.
     678                 :            :  */
     679                 :            : static enum ice_ddp_state
     680                 :          0 : ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)
     681                 :            : {
     682                 :            :         enum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;
     683                 :            :         struct ice_buf_hdr *bh;
     684                 :            :         int status;
     685                 :            : 
     686         [ #  # ]:          0 :         if (!bufs || !count)
     687                 :            :                 return ICE_DDP_PKG_ERR;
     688                 :            : 
     689                 :            :         /* If the first buffer's first section has its metadata bit set
     690                 :            :          * then there are no buffers to be downloaded, and the operation is
     691                 :            :          * considered a success.
     692                 :            :          */
     693                 :            :         bh = (struct ice_buf_hdr *)bufs;
     694         [ #  # ]:          0 :         if (LE32_TO_CPU(bh->section_entry[0].type) & ICE_METADATA_BUF)
     695                 :            :                 return ICE_DDP_PKG_SUCCESS;
     696                 :            : 
     697                 :          0 :         status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);
     698         [ #  # ]:          0 :         if (status) {
     699         [ #  # ]:          0 :                 if (status == ICE_ERR_AQ_NO_WORK)
     700                 :            :                         return ICE_DDP_PKG_ALREADY_LOADED;
     701         [ #  # ]:          0 :                 return ice_map_aq_err_to_ddp_state(hw->adminq.sq_last_status);
     702                 :            :         }
     703                 :            : 
     704                 :          0 :         state = ice_dwnld_cfg_bufs_no_lock(hw, bufs, 0, count, true);
     705         [ #  # ]:          0 :         if (!state)
     706                 :          0 :                 state = ice_post_dwnld_pkg_actions(hw);
     707                 :            : 
     708                 :          0 :         ice_release_global_cfg_lock(hw);
     709                 :            : 
     710                 :          0 :         return state;
     711                 :            : }
     712                 :            : 
     713                 :            : /**
     714                 :            :  * ice_download_pkg_without_sig_seg
     715                 :            :  * @hw: pointer to the hardware structure
     716                 :            :  * @ice_seg: pointer to the segment of the package to be downloaded
     717                 :            :  *
     718                 :            :  * Handles the download of a complete package without signature segment.
     719                 :            :  */
     720                 :            : static enum ice_ddp_state
     721                 :          0 : ice_download_pkg_without_sig_seg(struct ice_hw *hw, struct ice_seg *ice_seg)
     722                 :            : {
     723                 :            :         struct ice_buf_table *ice_buf_tbl;
     724                 :            :         enum ice_ddp_state state;
     725                 :            : 
     726         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_PKG, "Segment format version: %d.%d.%d.%d\n",
     727                 :            :                   ice_seg->hdr.seg_format_ver.major,
     728                 :            :                   ice_seg->hdr.seg_format_ver.minor,
     729                 :            :                   ice_seg->hdr.seg_format_ver.update,
     730                 :            :                   ice_seg->hdr.seg_format_ver.draft);
     731                 :            : 
     732         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_PKG, "Seg: type 0x%X, size %d, name %s\n",
     733                 :            :                   LE32_TO_CPU(ice_seg->hdr.seg_type),
     734                 :            :                   LE32_TO_CPU(ice_seg->hdr.seg_size), ice_seg->hdr.seg_id);
     735                 :            : 
     736                 :          0 :         ice_buf_tbl = ice_find_buf_table(ice_seg);
     737                 :            : 
     738         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_PKG, "Seg buf count: %d\n",
     739                 :            :                   LE32_TO_CPU(ice_buf_tbl->buf_count));
     740                 :            : 
     741                 :          0 :         state = ice_dwnld_cfg_bufs(hw, ice_buf_tbl->buf_array,
     742                 :            :                                    LE32_TO_CPU(ice_buf_tbl->buf_count));
     743                 :            : 
     744                 :          0 :         return state;
     745                 :            : }
     746                 :            : 
     747                 :            : /**
     748                 :            :  * ice_download_pkg
     749                 :            :  * @hw: pointer to the hardware structure
     750                 :            :  * @pkg_hdr: pointer to package header
     751                 :            :  * @ice_seg: pointer to the segment of the package to be downloaded
     752                 :            :  *
     753                 :            :  * Handles the download of a complete package.
     754                 :            :  */
     755                 :            : static enum ice_ddp_state
     756                 :          0 : ice_download_pkg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,
     757                 :            :                  struct ice_seg *ice_seg)
     758                 :            : {
     759                 :            :         enum ice_ddp_state state;
     760                 :            : 
     761         [ #  # ]:          0 :         if (ice_match_signing_seg(pkg_hdr, hw->pkg_seg_id, hw->pkg_sign_type))
     762                 :          0 :                 state = ice_download_pkg_with_sig_seg(hw, pkg_hdr);
     763                 :            :         else
     764                 :          0 :                 state = ice_download_pkg_without_sig_seg(hw, ice_seg);
     765                 :            : 
     766                 :          0 :         ice_post_pkg_dwnld_vlan_mode_cfg(hw);
     767                 :            : 
     768                 :          0 :         return state;
     769                 :            : }
     770                 :            : 
     771                 :            : /**
     772                 :            :  * ice_init_pkg_info
     773                 :            :  * @hw: pointer to the hardware structure
     774                 :            :  * @pkg_hdr: pointer to the driver's package hdr
     775                 :            :  *
     776                 :            :  * Saves off the package details into the HW structure.
     777                 :            :  */
     778                 :            : static enum ice_ddp_state
     779                 :          0 : ice_init_pkg_info(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)
     780                 :            : {
     781                 :            :         struct ice_generic_seg_hdr *seg_hdr;
     782                 :            : 
     783         [ #  # ]:          0 :         if (!pkg_hdr)
     784                 :            :                 return ICE_DDP_PKG_ERR;
     785                 :            : 
     786                 :            :         ice_get_signing_req(hw);
     787                 :            : 
     788         [ #  # ]:          0 :         ice_debug(hw, ICE_DBG_INIT, "Pkg using segment id: 0x%08X\n",
     789                 :            :                   hw->pkg_seg_id);
     790                 :            : 
     791                 :          0 :         seg_hdr = (struct ice_generic_seg_hdr *)
     792                 :            :                 ice_find_seg_in_pkg(hw, hw->pkg_seg_id, pkg_hdr);
     793         [ #  # ]:          0 :         if (seg_hdr) {
     794                 :            :                 struct ice_meta_sect *meta;
     795                 :            :                 struct ice_pkg_enum state;
     796                 :            : 
     797                 :            :                 ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);
     798                 :            : 
     799                 :            :                 /* Get package information from the Metadata Section */
     800                 :            :                 meta = (struct ice_meta_sect *)
     801                 :          0 :                         ice_pkg_enum_section((struct ice_seg *)seg_hdr, &state,
     802                 :            :                                              ICE_SID_METADATA);
     803         [ #  # ]:          0 :                 if (!meta) {
     804         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_INIT, "Did not find ice metadata section in package\n");
     805                 :          0 :                         return ICE_DDP_PKG_INVALID_FILE;
     806                 :            :                 }
     807                 :            : 
     808                 :          0 :                 hw->pkg_ver = meta->ver;
     809         [ #  # ]:          0 :                 ice_memcpy(hw->pkg_name, meta->name, sizeof(meta->name),
     810                 :            :                            ICE_NONDMA_TO_NONDMA);
     811                 :            : 
     812         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_PKG, "Pkg: %d.%d.%d.%d, %s\n",
     813                 :            :                           meta->ver.major, meta->ver.minor, meta->ver.update,
     814                 :            :                           meta->ver.draft, meta->name);
     815                 :            : 
     816                 :          0 :                 hw->ice_seg_fmt_ver = seg_hdr->seg_format_ver;
     817         [ #  # ]:          0 :                 ice_memcpy(hw->ice_seg_id, seg_hdr->seg_id,
     818                 :            :                            sizeof(hw->ice_seg_id), ICE_NONDMA_TO_NONDMA);
     819                 :            : 
     820         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_PKG, "Ice Seg: %d.%d.%d.%d, %s\n",
     821                 :            :                           seg_hdr->seg_format_ver.major,
     822                 :            :                           seg_hdr->seg_format_ver.minor,
     823                 :            :                           seg_hdr->seg_format_ver.update,
     824                 :            :                           seg_hdr->seg_format_ver.draft,
     825                 :            :                           seg_hdr->seg_id);
     826                 :            :         } else {
     827         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Did not find ice segment in driver package\n");
     828                 :          0 :                 return ICE_DDP_PKG_INVALID_FILE;
     829                 :            :         }
     830                 :            : 
     831                 :          0 :         return ICE_DDP_PKG_SUCCESS;
     832                 :            : }
     833                 :            : 
     834                 :            : /**
     835                 :            :  * ice_get_pkg_info
     836                 :            :  * @hw: pointer to the hardware structure
     837                 :            :  *
     838                 :            :  * Store details of the package currently loaded in HW into the HW structure.
     839                 :            :  */
     840                 :          0 : enum ice_ddp_state ice_get_pkg_info(struct ice_hw *hw)
     841                 :            : {
     842                 :            :         enum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;
     843                 :            :         struct ice_aqc_get_pkg_info_resp *pkg_info;
     844                 :            :         u16 size;
     845                 :            :         u32 i;
     846                 :            : 
     847                 :            :         size = ice_struct_size(pkg_info, pkg_info, ICE_PKG_CNT);
     848                 :          0 :         pkg_info = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size);
     849         [ #  # ]:          0 :         if (!pkg_info)
     850                 :            :                 return ICE_DDP_PKG_ERR;
     851                 :            : 
     852         [ #  # ]:          0 :         if (ice_aq_get_pkg_info_list(hw, pkg_info, size, NULL)) {
     853                 :            :                 state = ICE_DDP_PKG_ERR;
     854                 :          0 :                 goto init_pkg_free_alloc;
     855                 :            :         }
     856                 :            : 
     857         [ #  # ]:          0 :         for (i = 0; i < LE32_TO_CPU(pkg_info->count); i++) {
     858                 :            : #define ICE_PKG_FLAG_COUNT      4
     859                 :          0 :                 char flags[ICE_PKG_FLAG_COUNT + 1] = { 0 };
     860                 :            :                 u8 place = 0;
     861                 :            : 
     862         [ #  # ]:          0 :                 if (pkg_info->pkg_info[i].is_active) {
     863                 :          0 :                         flags[place++] = 'A';
     864                 :          0 :                         hw->active_pkg_ver = pkg_info->pkg_info[i].ver;
     865                 :          0 :                         hw->active_track_id =
     866                 :          0 :                                 LE32_TO_CPU(pkg_info->pkg_info[i].track_id);
     867         [ #  # ]:          0 :                         ice_memcpy(hw->active_pkg_name,
     868                 :            :                                    pkg_info->pkg_info[i].name,
     869                 :            :                                    sizeof(pkg_info->pkg_info[i].name),
     870                 :            :                                    ICE_NONDMA_TO_NONDMA);
     871                 :          0 :                         hw->active_pkg_in_nvm = pkg_info->pkg_info[i].is_in_nvm;
     872                 :            :                 }
     873         [ #  # ]:          0 :                 if (pkg_info->pkg_info[i].is_active_at_boot)
     874                 :          0 :                         flags[place++] = 'B';
     875         [ #  # ]:          0 :                 if (pkg_info->pkg_info[i].is_modified)
     876                 :          0 :                         flags[place++] = 'M';
     877         [ #  # ]:          0 :                 if (pkg_info->pkg_info[i].is_in_nvm)
     878                 :          0 :                         flags[place++] = 'N';
     879                 :            : 
     880         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_PKG, "Pkg[%d]: %d.%d.%d.%d,%s,%s\n",
     881                 :            :                           i, pkg_info->pkg_info[i].ver.major,
     882                 :            :                           pkg_info->pkg_info[i].ver.minor,
     883                 :            :                           pkg_info->pkg_info[i].ver.update,
     884                 :            :                           pkg_info->pkg_info[i].ver.draft,
     885                 :            :                           pkg_info->pkg_info[i].name, flags);
     886                 :            :         }
     887                 :            : 
     888                 :          0 : init_pkg_free_alloc:
     889                 :          0 :         ice_free(hw, pkg_info);
     890                 :            : 
     891                 :          0 :         return state;
     892                 :            : }
     893                 :            : 
     894                 :            : /**
     895                 :            :  * ice_label_enum_handler
     896                 :            :  * @sect_type: section type
     897                 :            :  * @section: pointer to section
     898                 :            :  * @index: index of the label entry to be returned
     899                 :            :  * @offset: pointer to receive absolute offset, always zero for label sections
     900                 :            :  *
     901                 :            :  * This is a callback function that can be passed to ice_pkg_enum_entry.
     902                 :            :  * Handles enumeration of individual label entries.
     903                 :            :  */
     904                 :            : static void *
     905                 :          0 : ice_label_enum_handler(u32 __ALWAYS_UNUSED sect_type, void *section, u32 index,
     906                 :            :                        u32 *offset)
     907                 :            : {
     908                 :            :         struct ice_label_section *labels;
     909                 :            : 
     910         [ #  # ]:          0 :         if (!section)
     911                 :            :                 return NULL;
     912                 :            : 
     913         [ #  # ]:          0 :         if (index > ICE_MAX_LABELS_IN_BUF)
     914                 :            :                 return NULL;
     915                 :            : 
     916         [ #  # ]:          0 :         if (offset)
     917                 :          0 :                 *offset = 0;
     918                 :            : 
     919                 :            :         labels = (struct ice_label_section *)section;
     920         [ #  # ]:          0 :         if (index >= LE16_TO_CPU(labels->count))
     921                 :            :                 return NULL;
     922                 :            : 
     923                 :          0 :         return labels->label + index;
     924                 :            : }
     925                 :            : 
     926                 :            : /**
     927                 :            :  * ice_enum_labels
     928                 :            :  * @ice_seg: pointer to the ice segment (NULL on subsequent calls)
     929                 :            :  * @type: the section type that will contain the label (0 on subsequent calls)
     930                 :            :  * @state: ice_pkg_enum structure that will hold the state of the enumeration
     931                 :            :  * @value: pointer to a value that will return the label's value if found
     932                 :            :  *
     933                 :            :  * Enumerates a list of labels in the package. The caller will call
     934                 :            :  * ice_enum_labels(ice_seg, type, ...) to start the enumeration, then call
     935                 :            :  * ice_enum_labels(NULL, 0, ...) to continue. When the function returns a NULL
     936                 :            :  * the end of the list has been reached.
     937                 :            :  */
     938                 :            : static char *
     939                 :            : ice_enum_labels(struct ice_seg *ice_seg, u32 type, struct ice_pkg_enum *state,
     940                 :            :                 u16 *value)
     941                 :            : {
     942                 :            :         struct ice_label *label;
     943                 :            : 
     944                 :            :         /* Check for valid label section on first call */
     945                 :            :         if (type && !(type >= ICE_SID_LBL_FIRST && type <= ICE_SID_LBL_LAST))
     946                 :            :                 return NULL;
     947                 :            : 
     948                 :          0 :         label = (struct ice_label *)ice_pkg_enum_entry(ice_seg, state, type,
     949                 :            :                                                        NULL,
     950                 :            :                                                        ice_label_enum_handler);
     951   [ #  #  #  # ]:          0 :         if (!label)
     952                 :            :                 return NULL;
     953                 :            : 
     954                 :          0 :         *value = LE16_TO_CPU(label->value);
     955                 :          0 :         return label->name;
     956                 :            : }
     957                 :            : 
     958                 :            : /**
     959                 :            :  * ice_verify_pkg - verify package
     960                 :            :  * @pkg: pointer to the package buffer
     961                 :            :  * @len: size of the package buffer
     962                 :            :  *
     963                 :            :  * Verifies various attributes of the package file, including length, format
     964                 :            :  * version, and the requirement of at least one segment.
     965                 :            :  */
     966                 :          0 : enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len)
     967                 :            : {
     968                 :            :         u32 seg_count;
     969                 :            :         u32 i;
     970                 :            : 
     971         [ #  # ]:          0 :         if (len < ice_struct_size(pkg, seg_offset, 1))
     972                 :            :                 return ICE_DDP_PKG_INVALID_FILE;
     973                 :            : 
     974                 :          0 :         if (pkg->pkg_format_ver.major != ICE_PKG_FMT_VER_MAJ ||
     975         [ #  # ]:          0 :             pkg->pkg_format_ver.minor != ICE_PKG_FMT_VER_MNR ||
     976                 :          0 :             pkg->pkg_format_ver.update != ICE_PKG_FMT_VER_UPD ||
     977         [ #  # ]:          0 :             pkg->pkg_format_ver.draft != ICE_PKG_FMT_VER_DFT)
     978                 :            :                 return ICE_DDP_PKG_INVALID_FILE;
     979                 :            : 
     980                 :            :         /* pkg must have at least one segment */
     981                 :          0 :         seg_count = LE32_TO_CPU(pkg->seg_count);
     982         [ #  # ]:          0 :         if (seg_count < 1)
     983                 :            :                 return ICE_DDP_PKG_INVALID_FILE;
     984                 :            : 
     985                 :            :         /* make sure segment array fits in package length */
     986         [ #  # ]:          0 :         if (len < ice_struct_size(pkg, seg_offset, seg_count))
     987                 :            :                 return ICE_DDP_PKG_INVALID_FILE;
     988                 :            : 
     989                 :            :         /* all segments must fit within length */
     990         [ #  # ]:          0 :         for (i = 0; i < seg_count; i++) {
     991                 :          0 :                 u32 off = LE32_TO_CPU(pkg->seg_offset[i]);
     992                 :            :                 struct ice_generic_seg_hdr *seg;
     993                 :            : 
     994                 :            :                 /* segment header must fit */
     995         [ #  # ]:          0 :                 if (len < off + sizeof(*seg))
     996                 :            :                         return ICE_DDP_PKG_INVALID_FILE;
     997                 :            : 
     998                 :          0 :                 seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off);
     999                 :            : 
    1000                 :            :                 /* segment body must fit */
    1001         [ #  # ]:          0 :                 if (len < off + LE32_TO_CPU(seg->seg_size))
    1002                 :            :                         return ICE_DDP_PKG_INVALID_FILE;
    1003                 :            :         }
    1004                 :            : 
    1005                 :            :         return ICE_DDP_PKG_SUCCESS;
    1006                 :            : }
    1007                 :            : 
    1008                 :            : /**
    1009                 :            :  * ice_free_seg - free package segment pointer
    1010                 :            :  * @hw: pointer to the hardware structure
    1011                 :            :  *
    1012                 :            :  * Frees the package segment pointer in the proper manner, depending on if the
    1013                 :            :  * segment was allocated or just the passed in pointer was stored.
    1014                 :            :  */
    1015                 :          0 : void ice_free_seg(struct ice_hw *hw)
    1016                 :            : {
    1017         [ #  # ]:          0 :         if (hw->pkg_copy) {
    1018                 :          0 :                 ice_free(hw, hw->pkg_copy);
    1019                 :          0 :                 hw->pkg_copy = NULL;
    1020                 :          0 :                 hw->pkg_size = 0;
    1021                 :            :         }
    1022                 :          0 :         hw->seg = NULL;
    1023                 :          0 : }
    1024                 :            : 
    1025                 :            : /**
    1026                 :            :  * ice_chk_pkg_version - check package version for compatibility with driver
    1027                 :            :  * @pkg_ver: pointer to a version structure to check
    1028                 :            :  *
    1029                 :            :  * Check to make sure that the package about to be downloaded is compatible with
    1030                 :            :  * the driver. To be compatible, the major and minor components of the package
    1031                 :            :  * version must match our ICE_PKG_SUPP_VER_MAJ and ICE_PKG_SUPP_VER_MNR
    1032                 :            :  * definitions.
    1033                 :            :  */
    1034                 :            : static enum ice_ddp_state ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver)
    1035                 :            : {
    1036         [ #  # ]:          0 :         if (pkg_ver->major > ICE_PKG_SUPP_VER_MAJ ||
    1037                 :          0 :             (pkg_ver->major == ICE_PKG_SUPP_VER_MAJ &&
    1038         [ #  # ]:          0 :              pkg_ver->minor > ICE_PKG_SUPP_VER_MNR))
    1039                 :            :                 return ICE_DDP_PKG_FILE_VERSION_TOO_HIGH;
    1040         [ #  # ]:          0 :         else if (pkg_ver->major < ICE_PKG_SUPP_VER_MAJ ||
    1041                 :          0 :                  (pkg_ver->major == ICE_PKG_SUPP_VER_MAJ &&
    1042         [ #  # ]:          0 :                   pkg_ver->minor < ICE_PKG_SUPP_VER_MNR))
    1043                 :            :                 return ICE_DDP_PKG_FILE_VERSION_TOO_LOW;
    1044                 :            :         return ICE_DDP_PKG_SUCCESS;
    1045                 :            : }
    1046                 :            : 
    1047                 :            : /**
    1048                 :            :  * ice_chk_pkg_compat
    1049                 :            :  * @hw: pointer to the hardware structure
    1050                 :            :  * @ospkg: pointer to the package hdr
    1051                 :            :  * @seg: pointer to the package segment hdr
    1052                 :            :  *
    1053                 :            :  * This function checks the package version compatibility with driver and NVM
    1054                 :            :  */
    1055                 :            : static enum ice_ddp_state
    1056         [ #  # ]:          0 : ice_chk_pkg_compat(struct ice_hw *hw, struct ice_pkg_hdr *ospkg,
    1057                 :            :                    struct ice_seg **seg)
    1058                 :            : {
    1059                 :            :         struct ice_aqc_get_pkg_info_resp *pkg;
    1060                 :            :         enum ice_ddp_state state;
    1061                 :            :         u16 size;
    1062                 :            :         u32 i;
    1063                 :            : 
    1064                 :            :         /* Check package version compatibility */
    1065                 :            :         state = ice_chk_pkg_version(&hw->pkg_ver);
    1066                 :            :         if (state) {
    1067         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Package version check failed.\n");
    1068                 :          0 :                 return state;
    1069                 :            :         }
    1070                 :            : 
    1071                 :            :         /* find ICE segment in given package */
    1072                 :          0 :         *seg = (struct ice_seg *)ice_find_seg_in_pkg(hw, hw->pkg_seg_id,
    1073                 :            :                                                      ospkg);
    1074         [ #  # ]:          0 :         if (!*seg) {
    1075         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "no ice segment in package.\n");
    1076                 :          0 :                 return ICE_DDP_PKG_INVALID_FILE;
    1077                 :            :         }
    1078                 :            : 
    1079                 :            :         /* Check if FW is compatible with the OS package */
    1080                 :            :         size = ice_struct_size(pkg, pkg_info, ICE_PKG_CNT);
    1081                 :          0 :         pkg = (struct ice_aqc_get_pkg_info_resp *)ice_malloc(hw, size);
    1082         [ #  # ]:          0 :         if (!pkg)
    1083                 :            :                 return ICE_DDP_PKG_ERR;
    1084                 :            : 
    1085         [ #  # ]:          0 :         if (ice_aq_get_pkg_info_list(hw, pkg, size, NULL)) {
    1086                 :            :                 state = ICE_DDP_PKG_ERR;
    1087                 :          0 :                 goto fw_ddp_compat_free_alloc;
    1088                 :            :         }
    1089                 :            : 
    1090         [ #  # ]:          0 :         for (i = 0; i < LE32_TO_CPU(pkg->count); i++) {
    1091                 :            :                 /* loop till we find the NVM package */
    1092         [ #  # ]:          0 :                 if (!pkg->pkg_info[i].is_in_nvm)
    1093                 :            :                         continue;
    1094                 :          0 :                 if ((*seg)->hdr.seg_format_ver.major !=
    1095         [ #  # ]:          0 :                         pkg->pkg_info[i].ver.major ||
    1096                 :          0 :                     (*seg)->hdr.seg_format_ver.minor >
    1097         [ #  # ]:          0 :                         pkg->pkg_info[i].ver.minor) {
    1098                 :            :                         state = ICE_DDP_PKG_FW_MISMATCH;
    1099         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_INIT, "OS package is not compatible with NVM.\n");
    1100                 :            :                 }
    1101                 :            :                 /* done processing NVM package so break */
    1102                 :            :                 break;
    1103                 :            :         }
    1104                 :          0 : fw_ddp_compat_free_alloc:
    1105                 :          0 :         ice_free(hw, pkg);
    1106                 :          0 :         return state;
    1107                 :            : }
    1108                 :            : 
    1109                 :            : /**
    1110                 :            :  * ice_sw_fv_handler
    1111                 :            :  * @sect_type: section type
    1112                 :            :  * @section: pointer to section
    1113                 :            :  * @index: index of the field vector entry to be returned
    1114                 :            :  * @offset: ptr to variable that receives the offset in the field vector table
    1115                 :            :  *
    1116                 :            :  * This is a callback function that can be passed to ice_pkg_enum_entry.
    1117                 :            :  * This function treats the given section as of type ice_sw_fv_section and
    1118                 :            :  * enumerates offset field. "offset" is an index into the field vector table.
    1119                 :            :  */
    1120                 :            : static void *
    1121                 :          0 : ice_sw_fv_handler(u32 sect_type, void *section, u32 index, u32 *offset)
    1122                 :            : {
    1123                 :            :         struct ice_sw_fv_section *fv_section =
    1124                 :            :                 (struct ice_sw_fv_section *)section;
    1125                 :            : 
    1126         [ #  # ]:          0 :         if (!section || sect_type != ICE_SID_FLD_VEC_SW)
    1127                 :            :                 return NULL;
    1128         [ #  # ]:          0 :         if (index >= LE16_TO_CPU(fv_section->count))
    1129                 :            :                 return NULL;
    1130         [ #  # ]:          0 :         if (offset)
    1131                 :            :                 /* "index" passed in to this function is relative to a given
    1132                 :            :                  * 4k block. To get to the true index into the field vector
    1133                 :            :                  * table need to add the relative index to the base_offset
    1134                 :            :                  * field of this section
    1135                 :            :                  */
    1136                 :          0 :                 *offset = LE16_TO_CPU(fv_section->base_offset) + index;
    1137                 :          0 :         return fv_section->fv + index;
    1138                 :            : }
    1139                 :            : 
    1140                 :            : /**
    1141                 :            :  * ice_get_prof_index_max - get the max profile index for used profile
    1142                 :            :  * @hw: pointer to the HW struct
    1143                 :            :  *
    1144                 :            :  * Calling this function will get the max profile index for used profile
    1145                 :            :  * and store the index number in struct ice_switch_info *switch_info
    1146                 :            :  * in hw for following use.
    1147                 :            :  */
    1148         [ #  # ]:          0 : static int ice_get_prof_index_max(struct ice_hw *hw)
    1149                 :            : {
    1150                 :            :         u16 prof_index = 0, j, max_prof_index = 0;
    1151                 :            :         struct ice_pkg_enum state;
    1152                 :            :         struct ice_seg *ice_seg;
    1153                 :            :         bool flag = false;
    1154                 :            :         struct ice_fv *fv;
    1155                 :            :         u32 offset;
    1156                 :            : 
    1157                 :            :         ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);
    1158                 :            : 
    1159         [ #  # ]:          0 :         if (!hw->seg)
    1160                 :            :                 return ICE_ERR_PARAM;
    1161                 :            : 
    1162                 :            :         ice_seg = hw->seg;
    1163                 :            : 
    1164                 :            :         do {
    1165                 :            :                 fv = (struct ice_fv *)
    1166                 :          0 :                         ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
    1167                 :            :                                            &offset, ice_sw_fv_handler);
    1168         [ #  # ]:          0 :                 if (!fv)
    1169                 :            :                         break;
    1170                 :            :                 ice_seg = NULL;
    1171                 :            : 
    1172                 :            :                 /* in the profile that not be used, the prot_id is set to 0xff
    1173                 :            :                  * and the off is set to 0x1ff for all the field vectors.
    1174                 :            :                  */
    1175         [ #  # ]:          0 :                 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
    1176         [ #  # ]:          0 :                         if (fv->ew[j].prot_id != ICE_PROT_INVALID ||
    1177         [ #  # ]:          0 :                             fv->ew[j].off != ICE_FV_OFFSET_INVAL)
    1178                 :            :                                 flag = true;
    1179         [ #  # ]:          0 :                 if (flag && prof_index > max_prof_index)
    1180                 :            :                         max_prof_index = prof_index;
    1181                 :            : 
    1182                 :          0 :                 prof_index++;
    1183                 :            :                 flag = false;
    1184                 :            :         } while (fv);
    1185                 :            : 
    1186                 :          0 :         hw->switch_info->max_used_prof_index = max_prof_index;
    1187                 :            : 
    1188                 :          0 :         return 0;
    1189                 :            : }
    1190                 :            : 
    1191                 :            : /**
    1192                 :            :  * ice_get_ddp_pkg_state - get DDP pkg state after download
    1193                 :            :  * @hw: pointer to the HW struct
    1194                 :            :  * @already_loaded: indicates if pkg was already loaded onto the device
    1195                 :            :  *
    1196                 :            :  */
    1197                 :            : static enum ice_ddp_state
    1198                 :          0 : ice_get_ddp_pkg_state(struct ice_hw *hw, bool already_loaded)
    1199                 :            : {
    1200                 :          0 :         if (hw->pkg_ver.major == hw->active_pkg_ver.major &&
    1201         [ #  # ]:          0 :             hw->pkg_ver.minor == hw->active_pkg_ver.minor &&
    1202                 :          0 :             hw->pkg_ver.update == hw->active_pkg_ver.update &&
    1203         [ #  # ]:          0 :             hw->pkg_ver.draft == hw->active_pkg_ver.draft &&
    1204         [ #  # ]:          0 :             !memcmp(hw->pkg_name, hw->active_pkg_name, sizeof(hw->pkg_name))) {
    1205         [ #  # ]:          0 :                 if (already_loaded)
    1206                 :            :                         return ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED;
    1207                 :            :                 else
    1208                 :          0 :                         return ICE_DDP_PKG_SUCCESS;
    1209         [ #  # ]:          0 :         } else if (hw->active_pkg_ver.major != ICE_PKG_SUPP_VER_MAJ ||
    1210                 :            :                    hw->active_pkg_ver.minor != ICE_PKG_SUPP_VER_MNR) {
    1211                 :            :                 return ICE_DDP_PKG_ALREADY_LOADED_NOT_SUPPORTED;
    1212                 :            :         } else {
    1213                 :          0 :                 return ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED;
    1214                 :            :         }
    1215                 :            : }
    1216                 :            : 
    1217                 :            : /**
    1218                 :            :  * ice_init_pkg_regs - initialize additional package registers
    1219                 :            :  * @hw: pointer to the hardware structure
    1220                 :            :  */
    1221                 :            : static void ice_init_pkg_regs(struct ice_hw *hw)
    1222                 :            : {
    1223                 :            : #define ICE_SW_BLK_INP_MASK_L 0xFFFFFFFF
    1224                 :            : #define ICE_SW_BLK_INP_MASK_H 0x0000FFFF
    1225                 :            : #define ICE_SW_BLK_IDX  0
    1226                 :          0 :         if (hw->dcf_enabled)
    1227                 :            :                 return;
    1228                 :            : 
    1229                 :            :         /* setup Switch block input mask, which is 48-bits in two parts */
    1230                 :          0 :         wr32(hw, GL_PREEXT_L2_PMASK0(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_L);
    1231                 :          0 :         wr32(hw, GL_PREEXT_L2_PMASK1(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_H);
    1232                 :            : }
    1233                 :            : 
    1234                 :            : /**
    1235                 :            :  * ice_hw_ptype_ena - check if the PTYPE is enabled or not
    1236                 :            :  * @hw: pointer to the HW structure
    1237                 :            :  * @ptype: the hardware PTYPE
    1238                 :            :  */
    1239                 :          0 : bool ice_hw_ptype_ena(struct ice_hw *hw, u16 ptype)
    1240                 :            : {
    1241   [ #  #  #  # ]:          0 :         return ptype < ICE_FLOW_PTYPE_MAX &&
    1242         [ #  # ]:          0 :                ice_is_bit_set(hw->hw_ptype, ptype);
    1243                 :            : }
    1244                 :            : 
    1245                 :            : /**
    1246                 :            :  * ice_marker_ptype_tcam_handler
    1247                 :            :  * @sect_type: section type
    1248                 :            :  * @section: pointer to section
    1249                 :            :  * @index: index of the Marker PType TCAM entry to be returned
    1250                 :            :  * @offset: pointer to receive absolute offset, always 0 for ptype TCAM sections
    1251                 :            :  *
    1252                 :            :  * This is a callback function that can be passed to ice_pkg_enum_entry.
    1253                 :            :  * Handles enumeration of individual Marker PType TCAM entries.
    1254                 :            :  */
    1255                 :            : static void *
    1256                 :          0 : ice_marker_ptype_tcam_handler(u32 sect_type, void *section, u32 index,
    1257                 :            :                               u32 *offset)
    1258                 :            : {
    1259                 :            :         struct ice_marker_ptype_tcam_section *marker_ptype;
    1260                 :            : 
    1261         [ #  # ]:          0 :         if (!section)
    1262                 :            :                 return NULL;
    1263                 :            : 
    1264         [ #  # ]:          0 :         if (sect_type != ICE_SID_RXPARSER_MARKER_PTYPE)
    1265                 :            :                 return NULL;
    1266                 :            : 
    1267         [ #  # ]:          0 :         if (index > ICE_MAX_MARKER_PTYPE_TCAMS_IN_BUF)
    1268                 :            :                 return NULL;
    1269                 :            : 
    1270         [ #  # ]:          0 :         if (offset)
    1271                 :          0 :                 *offset = 0;
    1272                 :            : 
    1273                 :            :         marker_ptype = (struct ice_marker_ptype_tcam_section *)section;
    1274         [ #  # ]:          0 :         if (index >= LE16_TO_CPU(marker_ptype->count))
    1275                 :            :                 return NULL;
    1276                 :            : 
    1277                 :          0 :         return marker_ptype->tcam + index;
    1278                 :            : }
    1279                 :            : 
    1280                 :            : /**
    1281                 :            :  * ice_fill_hw_ptype - fill the enabled PTYPE bit information
    1282                 :            :  * @hw: pointer to the HW structure
    1283                 :            :  */
    1284                 :            : static void
    1285                 :          0 : ice_fill_hw_ptype(struct ice_hw *hw)
    1286                 :            : {
    1287                 :            :         struct ice_marker_ptype_tcam_entry *tcam;
    1288                 :          0 :         struct ice_seg *seg = hw->seg;
    1289                 :            :         struct ice_pkg_enum state;
    1290                 :            : 
    1291         [ #  # ]:          0 :         ice_zero_bitmap(hw->hw_ptype, ICE_FLOW_PTYPE_MAX);
    1292         [ #  # ]:          0 :         if (!seg)
    1293                 :          0 :                 return;
    1294                 :            : 
    1295                 :            :         ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);
    1296                 :            : 
    1297                 :            :         do {
    1298                 :            :                 tcam = (struct ice_marker_ptype_tcam_entry *)
    1299                 :          0 :                         ice_pkg_enum_entry(seg, &state,
    1300                 :            :                                            ICE_SID_RXPARSER_MARKER_PTYPE, NULL,
    1301                 :            :                                            ice_marker_ptype_tcam_handler);
    1302         [ #  # ]:          0 :                 if (tcam &&
    1303         [ #  # ]:          0 :                     LE16_TO_CPU(tcam->addr) < ICE_MARKER_PTYPE_TCAM_ADDR_MAX &&
    1304         [ #  # ]:          0 :                     LE16_TO_CPU(tcam->ptype) < ICE_FLOW_PTYPE_MAX)
    1305                 :            :                         ice_set_bit(LE16_TO_CPU(tcam->ptype), hw->hw_ptype);
    1306                 :            : 
    1307                 :            :                 seg = NULL;
    1308         [ #  # ]:          0 :         } while (tcam);
    1309                 :            : }
    1310                 :            : 
    1311                 :            : /**
    1312                 :            :  * ice_init_pkg - initialize/download package
    1313                 :            :  * @hw: pointer to the hardware structure
    1314                 :            :  * @buf: pointer to the package buffer
    1315                 :            :  * @len: size of the package buffer
    1316                 :            :  *
    1317                 :            :  * This function initializes a package. The package contains HW tables
    1318                 :            :  * required to do packet processing. First, the function extracts package
    1319                 :            :  * information such as version. Then it finds the ice configuration segment
    1320                 :            :  * within the package; this function then saves a copy of the segment pointer
    1321                 :            :  * within the supplied package buffer. Next, the function will cache any hints
    1322                 :            :  * from the package, followed by downloading the package itself. Note, that if
    1323                 :            :  * a previous PF driver has already downloaded the package successfully, then
    1324                 :            :  * the current driver will not have to download the package again.
    1325                 :            :  *
    1326                 :            :  * The local package contents will be used to query default behavior and to
    1327                 :            :  * update specific sections of the HW's version of the package (e.g. to update
    1328                 :            :  * the parse graph to understand new protocols).
    1329                 :            :  *
    1330                 :            :  * This function stores a pointer to the package buffer memory, and it is
    1331                 :            :  * expected that the supplied buffer will not be freed immediately. If the
    1332                 :            :  * package buffer needs to be freed, such as when read from a file, use
    1333                 :            :  * ice_copy_and_init_pkg() instead of directly calling ice_init_pkg() in this
    1334                 :            :  * case.
    1335                 :            :  */
    1336                 :          0 : enum ice_ddp_state ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len, bool load_sched)
    1337                 :            : {
    1338                 :            :         bool already_loaded = false;
    1339                 :            :         enum ice_ddp_state state;
    1340                 :            :         struct ice_pkg_hdr *pkg;
    1341                 :            :         struct ice_seg *seg;
    1342                 :            : 
    1343         [ #  # ]:          0 :         if (!buf || !len)
    1344                 :            :                 return ICE_DDP_PKG_ERR;
    1345                 :            : 
    1346                 :            :         pkg = (struct ice_pkg_hdr *)buf;
    1347                 :          0 :         state = ice_verify_pkg(pkg, len);
    1348         [ #  # ]:          0 :         if (state) {
    1349         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "failed to verify pkg (err: %d)\n",
    1350                 :            :                           state);
    1351                 :          0 :                 return state;
    1352                 :            :         }
    1353                 :            : 
    1354         [ #  # ]:          0 :         if (load_sched) {
    1355                 :          0 :                 enum ice_status res = ice_cfg_tx_topo(hw, buf, len);
    1356         [ #  # ]:          0 :                 if (res != ICE_SUCCESS) {
    1357         [ #  # ]:          0 :                         ice_debug(hw, ICE_DBG_INIT,
    1358                 :            :                                   "failed to apply sched topology  (err: %d)\n",
    1359                 :            :                                   res);
    1360                 :          0 :                         return ICE_DDP_PKG_ERR;
    1361                 :            :                 }
    1362         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT,
    1363                 :            :                           "Topology download successful, reinitializing device\n");
    1364                 :          0 :                 ice_deinit_hw(hw);
    1365                 :          0 :                 ice_init_hw(hw);
    1366                 :            :         }
    1367                 :            : 
    1368                 :            :         /* initialize package info */
    1369                 :          0 :         state = ice_init_pkg_info(hw, pkg);
    1370         [ #  # ]:          0 :         if (state)
    1371                 :            :                 return state;
    1372                 :            : 
    1373                 :            :         /* before downloading the package, check package version for
    1374                 :            :          * compatibility with driver
    1375                 :            :          */
    1376                 :          0 :         state = ice_chk_pkg_compat(hw, pkg, &seg);
    1377         [ #  # ]:          0 :         if (state)
    1378                 :            :                 return state;
    1379                 :            : 
    1380                 :            :         /* initialize package hints and then download package */
    1381                 :          0 :         ice_init_pkg_hints(hw, seg);
    1382                 :          0 :         state = ice_download_pkg(hw, pkg, seg);
    1383                 :            : 
    1384         [ #  # ]:          0 :         if (state == ICE_DDP_PKG_ALREADY_LOADED) {
    1385         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "package previously loaded - no work.\n");
    1386                 :            :                 already_loaded = true;
    1387                 :            :         }
    1388                 :            : 
    1389                 :            :         /* Get information on the package currently loaded in HW, then make sure
    1390                 :            :          * the driver is compatible with this version.
    1391                 :            :          */
    1392         [ #  # ]:          0 :         if (!state || state == ICE_DDP_PKG_ALREADY_LOADED) {
    1393                 :          0 :                 state = ice_get_pkg_info(hw);
    1394         [ #  # ]:          0 :                 if (!state)
    1395                 :          0 :                         state = ice_get_ddp_pkg_state(hw, already_loaded);
    1396                 :            :         }
    1397                 :            : 
    1398         [ #  # ]:          0 :         if (ice_is_init_pkg_successful(state)) {
    1399         [ #  # ]:          0 :                 hw->seg = seg;
    1400                 :            :                 /* on successful package download update other required
    1401                 :            :                  * registers to support the package and fill HW tables
    1402                 :            :                  * with package content.
    1403                 :            :                  */
    1404                 :            :                 ice_init_pkg_regs(hw);
    1405                 :          0 :                 ice_fill_blk_tbls(hw);
    1406                 :          0 :                 ice_fill_hw_ptype(hw);
    1407                 :          0 :                 ice_get_prof_index_max(hw);
    1408                 :            :         } else {
    1409         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "package load failed, %d\n",
    1410                 :            :                           state);
    1411                 :            :         }
    1412                 :            : 
    1413                 :            :         return state;
    1414                 :            : }
    1415                 :            : 
    1416                 :            : /**
    1417                 :            :  * ice_copy_and_init_pkg - initialize/download a copy of the package
    1418                 :            :  * @hw: pointer to the hardware structure
    1419                 :            :  * @buf: pointer to the package buffer
    1420                 :            :  * @len: size of the package buffer
    1421                 :            :  *
    1422                 :            :  * This function copies the package buffer, and then calls ice_init_pkg() to
    1423                 :            :  * initialize the copied package contents.
    1424                 :            :  *
    1425                 :            :  * The copying is necessary if the package buffer supplied is constant, or if
    1426                 :            :  * the memory may disappear shortly after calling this function.
    1427                 :            :  *
    1428                 :            :  * If the package buffer resides in the data segment and can be modified, the
    1429                 :            :  * caller is free to use ice_init_pkg() instead of ice_copy_and_init_pkg().
    1430                 :            :  *
    1431                 :            :  * However, if the package buffer needs to be copied first, such as when being
    1432                 :            :  * read from a file, the caller should use ice_copy_and_init_pkg().
    1433                 :            :  *
    1434                 :            :  * This function will first copy the package buffer, before calling
    1435                 :            :  * ice_init_pkg(). The caller is free to immediately destroy the original
    1436                 :            :  * package buffer, as the new copy will be managed by this function and
    1437                 :            :  * related routines.
    1438                 :            :  */
    1439                 :            : enum ice_ddp_state
    1440                 :          0 : ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf, u32 len, bool load_sched)
    1441                 :            : {
    1442                 :            :         enum ice_ddp_state state;
    1443                 :            :         u8 *buf_copy;
    1444                 :            : 
    1445         [ #  # ]:          0 :         if (!buf || !len)
    1446                 :            :                 return ICE_DDP_PKG_ERR;
    1447                 :            : 
    1448                 :          0 :         buf_copy = (u8 *)ice_memdup(hw, buf, len, ICE_NONDMA_TO_NONDMA);
    1449                 :            : 
    1450                 :          0 :         state = ice_init_pkg(hw, buf_copy, len, load_sched);
    1451         [ #  # ]:          0 :         if (!ice_is_init_pkg_successful(state)) {
    1452                 :            :                 /* Free the copy, since we failed to initialize the package */
    1453                 :          0 :                 ice_free(hw, buf_copy);
    1454                 :            :         } else {
    1455                 :            :                 /* Track the copied pkg so we can free it later */
    1456                 :          0 :                 hw->pkg_copy = buf_copy;
    1457                 :          0 :                 hw->pkg_size = len;
    1458                 :            :         }
    1459                 :            : 
    1460                 :            :         return state;
    1461                 :            : }
    1462                 :            : 
    1463                 :            : /**
    1464                 :            :  * ice_is_init_pkg_successful - check if DDP init was successful
    1465                 :            :  * @state: state of the DDP pkg after download
    1466                 :            :  */
    1467                 :          0 : bool ice_is_init_pkg_successful(enum ice_ddp_state state)
    1468                 :            : {
    1469         [ #  # ]:          0 :         switch (state) {
    1470                 :            :         case ICE_DDP_PKG_SUCCESS:
    1471                 :            :         case ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED:
    1472                 :            :         case ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED:
    1473                 :            :                 return true;
    1474                 :          0 :         default:
    1475                 :          0 :                 return false;
    1476                 :            :         }
    1477                 :            : }
    1478                 :            : 
    1479                 :            : /**
    1480                 :            :  * ice_pkg_buf_alloc
    1481                 :            :  * @hw: pointer to the HW structure
    1482                 :            :  *
    1483                 :            :  * Allocates a package buffer and returns a pointer to the buffer header.
    1484                 :            :  * Note: all package contents must be in Little Endian form.
    1485                 :            :  */
    1486                 :          0 : struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw)
    1487                 :            : {
    1488                 :            :         struct ice_buf_build *bld;
    1489                 :            :         struct ice_buf_hdr *buf;
    1490                 :            : 
    1491                 :          0 :         bld = (struct ice_buf_build *)ice_malloc(hw, sizeof(*bld));
    1492         [ #  # ]:          0 :         if (!bld)
    1493                 :            :                 return NULL;
    1494                 :            : 
    1495                 :            :         buf = (struct ice_buf_hdr *)bld;
    1496                 :          0 :         buf->data_end = CPU_TO_LE16(offsetof(struct ice_buf_hdr,
    1497                 :            :                                              section_entry));
    1498                 :          0 :         return bld;
    1499                 :            : }
    1500                 :            : 
    1501                 :            : /**
    1502                 :            :  * ice_get_sw_prof_type - determine switch profile type
    1503                 :            :  * @hw: pointer to the HW structure
    1504                 :            :  * @fv: pointer to the switch field vector
    1505                 :            :  */
    1506                 :            : static enum ice_prof_type
    1507                 :            : ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv)
    1508                 :            : {
    1509                 :            :         bool valid_prof = false;
    1510                 :            :         u16 i;
    1511                 :            : 
    1512         [ #  # ]:          0 :         for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) {
    1513         [ #  # ]:          0 :                 if (fv->ew[i].off != ICE_NAN_OFFSET)
    1514                 :            :                         valid_prof = true;
    1515                 :            : 
    1516                 :            :                 /* UDP tunnel will have UDP_OF protocol ID and VNI offset */
    1517   [ #  #  #  # ]:          0 :                 if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&
    1518                 :            :                     fv->ew[i].off == ICE_VNI_OFFSET)
    1519                 :            :                         return ICE_PROF_TUN_UDP;
    1520                 :            : 
    1521                 :            :                 /* GRE tunnel will have GRE protocol */
    1522         [ #  # ]:          0 :                 if (fv->ew[i].prot_id == (u8)ICE_PROT_GRE_OF)
    1523                 :            :                         return ICE_PROF_TUN_GRE;
    1524                 :            : 
    1525                 :            :                 /* PPPOE tunnel will have PPPOE protocol */
    1526         [ #  # ]:          0 :                 if (fv->ew[i].prot_id == (u8)ICE_PROT_PPPOE)
    1527                 :            :                         return ICE_PROF_TUN_PPPOE;
    1528                 :            :         }
    1529                 :            : 
    1530                 :          0 :         return valid_prof ? ICE_PROF_NON_TUN : ICE_PROF_INVALID;
    1531                 :            : }
    1532                 :            : 
    1533                 :            : /**
    1534                 :            :  * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type
    1535                 :            :  * @hw: pointer to hardware structure
    1536                 :            :  * @req_profs: type of profiles requested
    1537                 :            :  * @bm: pointer to memory for returning the bitmap of field vectors
    1538                 :            :  */
    1539                 :            : void
    1540                 :          0 : ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs,
    1541                 :            :                      ice_bitmap_t *bm)
    1542                 :            : {
    1543                 :            :         struct ice_pkg_enum state;
    1544                 :            :         struct ice_seg *ice_seg;
    1545                 :            :         struct ice_fv *fv;
    1546                 :            : 
    1547                 :            :         ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);
    1548                 :            :         ice_zero_bitmap(bm, ICE_MAX_NUM_PROFILES);
    1549                 :          0 :         ice_seg = hw->seg;
    1550                 :            :         do {
    1551                 :            :                 enum ice_prof_type prof_type;
    1552                 :            :                 u32 offset;
    1553                 :            : 
    1554                 :            :                 fv = (struct ice_fv *)
    1555                 :          0 :                         ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
    1556                 :            :                                            &offset, ice_sw_fv_handler);
    1557                 :            :                 ice_seg = NULL;
    1558                 :            : 
    1559         [ #  # ]:          0 :                 if (fv) {
    1560                 :            :                         /* Determine field vector type */
    1561                 :            :                         prof_type = ice_get_sw_prof_type(hw, fv);
    1562                 :            : 
    1563         [ #  # ]:          0 :                         if (req_profs & prof_type)
    1564                 :          0 :                                 ice_set_bit((u16)offset, bm);
    1565                 :            :                 }
    1566         [ #  # ]:          0 :         } while (fv);
    1567                 :          0 : }
    1568                 :            : 
    1569                 :            : /**
    1570                 :            :  * ice_get_sw_fv_list
    1571                 :            :  * @hw: pointer to the HW structure
    1572                 :            :  * @lkups: lookup elements or match criteria for the advanced recipe, one
    1573                 :            :  *         structure per protocol header
    1574                 :            :  * @bm: bitmap of field vectors to consider
    1575                 :            :  * @fv_list: Head of a list
    1576                 :            :  *
    1577                 :            :  * Finds all the field vector entries from switch block that contain
    1578                 :            :  * a given protocol ID and offset and returns a list of structures of type
    1579                 :            :  * "ice_sw_fv_list_entry". Every structure in the list has a field vector
    1580                 :            :  * definition and profile ID information
    1581                 :            :  * NOTE: The caller of the function is responsible for freeing the memory
    1582                 :            :  * allocated for every list entry.
    1583                 :            :  */
    1584                 :            : int
    1585                 :          0 : ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,
    1586                 :            :                    ice_bitmap_t *bm, struct LIST_HEAD_TYPE *fv_list)
    1587                 :            : {
    1588                 :            :         struct ice_sw_fv_list_entry *fvl;
    1589                 :            :         struct ice_sw_fv_list_entry *tmp;
    1590                 :            :         struct ice_pkg_enum state;
    1591                 :            :         struct ice_seg *ice_seg;
    1592                 :            :         struct ice_fv *fv;
    1593                 :            :         u32 offset;
    1594                 :            : 
    1595         [ #  # ]:          0 :         if (!lkups->n_val_words)
    1596                 :            :                 return 0;
    1597                 :            : 
    1598                 :            :         ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);
    1599                 :            : 
    1600         [ #  # ]:          0 :         if (!lkups->n_val_words || !hw->seg)
    1601                 :            :                 return ICE_ERR_PARAM;
    1602                 :            : 
    1603                 :            :         ice_seg = hw->seg;
    1604                 :            :         do {
    1605                 :            :                 u16 i;
    1606                 :            : 
    1607                 :            :                 fv = (struct ice_fv *)
    1608                 :          0 :                         ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
    1609                 :            :                                            &offset, ice_sw_fv_handler);
    1610         [ #  # ]:          0 :                 if (!fv)
    1611                 :            :                         break;
    1612                 :            :                 ice_seg = NULL;
    1613                 :            : 
    1614                 :            :                 /* If field vector is not in the bitmap list, then skip this
    1615                 :            :                  * profile.
    1616                 :            :                  */
    1617         [ #  # ]:          0 :                 if (!ice_is_bit_set(bm, (u16)offset))
    1618                 :          0 :                         continue;
    1619                 :            : 
    1620         [ #  # ]:          0 :                 for (i = 0; i < lkups->n_val_words; i++) {
    1621                 :            :                         int j;
    1622                 :            : 
    1623         [ #  # ]:          0 :                         for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)
    1624                 :          0 :                                 if (fv->ew[j].prot_id ==
    1625         [ #  # ]:          0 :                                     lkups->fv_words[i].prot_id &&
    1626         [ #  # ]:          0 :                                     fv->ew[j].off == lkups->fv_words[i].off)
    1627                 :            :                                         break;
    1628         [ #  # ]:          0 :                         if (j >= hw->blk[ICE_BLK_SW].es.fvw)
    1629                 :            :                                 break;
    1630         [ #  # ]:          0 :                         if (i + 1 == lkups->n_val_words) {
    1631                 :            :                                 fvl = (struct ice_sw_fv_list_entry *)
    1632                 :          0 :                                         ice_malloc(hw, sizeof(*fvl));
    1633         [ #  # ]:          0 :                                 if (!fvl)
    1634                 :          0 :                                         goto err;
    1635                 :          0 :                                 fvl->fv_ptr = fv;
    1636                 :          0 :                                 fvl->profile_id = offset;
    1637         [ #  # ]:          0 :                                 LIST_ADD(&fvl->list_entry, fv_list);
    1638                 :          0 :                                 break;
    1639                 :            :                         }
    1640                 :            :                 }
    1641                 :            :         } while (fv);
    1642         [ #  # ]:          0 :         if (LIST_EMPTY(fv_list)) {
    1643         [ #  # ]:          0 :                 ice_warn(hw, "Required profiles not found in currently loaded DDP package");
    1644                 :          0 :                 return ICE_ERR_CFG;
    1645                 :            :         }
    1646                 :            :         return 0;
    1647                 :            : 
    1648                 :            : err:
    1649   [ #  #  #  #  :          0 :         LIST_FOR_EACH_ENTRY_SAFE(fvl, tmp, fv_list, ice_sw_fv_list_entry,
          #  #  #  #  #  
                      # ]
    1650                 :            :                                  list_entry) {
    1651         [ #  # ]:          0 :                 LIST_DEL(&fvl->list_entry);
    1652                 :          0 :                 ice_free(hw, fvl);
    1653                 :            :         }
    1654                 :            : 
    1655                 :            :         return ICE_ERR_NO_MEMORY;
    1656                 :            : }
    1657                 :            : 
    1658                 :            : /**
    1659                 :            :  * ice_init_prof_result_bm - Initialize the profile result index bitmap
    1660                 :            :  * @hw: pointer to hardware structure
    1661                 :            :  */
    1662         [ #  # ]:          0 : void ice_init_prof_result_bm(struct ice_hw *hw)
    1663                 :            : {
    1664                 :            :         struct ice_pkg_enum state;
    1665                 :            :         struct ice_seg *ice_seg;
    1666                 :            :         struct ice_fv *fv;
    1667                 :            : 
    1668                 :            :         ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);
    1669                 :            : 
    1670         [ #  # ]:          0 :         if (!hw->seg)
    1671                 :          0 :                 return;
    1672                 :            : 
    1673                 :            :         ice_seg = hw->seg;
    1674                 :            :         do {
    1675                 :            :                 u32 off;
    1676                 :            :                 u16 i;
    1677                 :            : 
    1678                 :            :                 fv = (struct ice_fv *)
    1679                 :          0 :                         ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
    1680                 :            :                                            &off, ice_sw_fv_handler);
    1681                 :            :                 ice_seg = NULL;
    1682         [ #  # ]:          0 :                 if (!fv)
    1683                 :            :                         break;
    1684                 :            : 
    1685                 :          0 :                 ice_zero_bitmap(hw->switch_info->prof_res_bm[off],
    1686                 :            :                                 ICE_MAX_FV_WORDS);
    1687                 :            : 
    1688                 :            :                 /* Determine empty field vector indices, these can be
    1689                 :            :                  * used for recipe results. Skip index 0, since it is
    1690                 :            :                  * always used for Switch ID.
    1691                 :            :                  */
    1692         [ #  # ]:          0 :                 for (i = 1; i < ICE_MAX_FV_WORDS; i++)
    1693         [ #  # ]:          0 :                         if (fv->ew[i].prot_id == ICE_PROT_INVALID &&
    1694         [ #  # ]:          0 :                             fv->ew[i].off == ICE_FV_OFFSET_INVAL)
    1695                 :            :                                 ice_set_bit(i,
    1696                 :          0 :                                             hw->switch_info->prof_res_bm[off]);
    1697                 :            :         } while (fv);
    1698                 :            : }
    1699                 :            : 
    1700                 :            : /**
    1701                 :            :  * ice_pkg_buf_free
    1702                 :            :  * @hw: pointer to the HW structure
    1703                 :            :  * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())
    1704                 :            :  *
    1705                 :            :  * Frees a package buffer
    1706                 :            :  */
    1707                 :          0 : void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld)
    1708                 :            : {
    1709                 :          0 :         ice_free(hw, bld);
    1710                 :          0 : }
    1711                 :            : 
    1712                 :            : /**
    1713                 :            :  * ice_pkg_buf_reserve_section
    1714                 :            :  * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())
    1715                 :            :  * @count: the number of sections to reserve
    1716                 :            :  *
    1717                 :            :  * Reserves one or more section table entries in a package buffer. This routine
    1718                 :            :  * can be called multiple times as long as they are made before calling
    1719                 :            :  * ice_pkg_buf_alloc_section(). Once ice_pkg_buf_alloc_section()
    1720                 :            :  * is called once, the number of sections that can be allocated will not be able
    1721                 :            :  * to be increased; not using all reserved sections is fine, but this will
    1722                 :            :  * result in some wasted space in the buffer.
    1723                 :            :  * Note: all package contents must be in Little Endian form.
    1724                 :            :  */
    1725                 :            : int
    1726                 :          0 : ice_pkg_buf_reserve_section(struct ice_buf_build *bld, u16 count)
    1727                 :            : {
    1728                 :            :         struct ice_buf_hdr *buf;
    1729                 :            :         u16 section_count;
    1730                 :            :         u16 data_end;
    1731                 :            : 
    1732         [ #  # ]:          0 :         if (!bld)
    1733                 :            :                 return ICE_ERR_PARAM;
    1734                 :            : 
    1735                 :            :         buf = (struct ice_buf_hdr *)&bld->buf;
    1736                 :            : 
    1737                 :            :         /* already an active section, can't increase table size */
    1738                 :          0 :         section_count = LE16_TO_CPU(buf->section_count);
    1739         [ #  # ]:          0 :         if (section_count > 0)
    1740                 :            :                 return ICE_ERR_CFG;
    1741                 :            : 
    1742         [ #  # ]:          0 :         if (bld->reserved_section_table_entries + count > ICE_MAX_S_COUNT)
    1743                 :            :                 return ICE_ERR_CFG;
    1744                 :          0 :         bld->reserved_section_table_entries += count;
    1745                 :            : 
    1746                 :          0 :         data_end = LE16_TO_CPU(buf->data_end) +
    1747                 :          0 :                 FLEX_ARRAY_SIZE(buf, section_entry, count);
    1748                 :          0 :         buf->data_end = CPU_TO_LE16(data_end);
    1749                 :            : 
    1750                 :          0 :         return 0;
    1751                 :            : }
    1752                 :            : 
    1753                 :            : /**
    1754                 :            :  * ice_pkg_buf_alloc_section
    1755                 :            :  * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())
    1756                 :            :  * @type: the section type value
    1757                 :            :  * @size: the size of the section to reserve (in bytes)
    1758                 :            :  *
    1759                 :            :  * Reserves memory in the buffer for a section's content and updates the
    1760                 :            :  * buffers' status accordingly. This routine returns a pointer to the first
    1761                 :            :  * byte of the section start within the buffer, which is used to fill in the
    1762                 :            :  * section contents.
    1763                 :            :  * Note: all package contents must be in Little Endian form.
    1764                 :            :  */
    1765                 :            : void *
    1766                 :          0 : ice_pkg_buf_alloc_section(struct ice_buf_build *bld, u32 type, u16 size)
    1767                 :            : {
    1768                 :            :         struct ice_buf_hdr *buf;
    1769                 :            :         u16 sect_count;
    1770                 :            :         u16 data_end;
    1771                 :            : 
    1772   [ #  #  #  # ]:          0 :         if (!bld || !type || !size)
    1773                 :            :                 return NULL;
    1774                 :            : 
    1775                 :          0 :         buf = (struct ice_buf_hdr *)&bld->buf;
    1776                 :            : 
    1777                 :            :         /* check for enough space left in buffer */
    1778                 :          0 :         data_end = LE16_TO_CPU(buf->data_end);
    1779                 :            : 
    1780                 :            :         /* section start must align on 4 byte boundary */
    1781                 :          0 :         data_end = ICE_ALIGN(data_end, 4);
    1782                 :            : 
    1783         [ #  # ]:          0 :         if ((data_end + size) > ICE_MAX_S_DATA_END)
    1784                 :            :                 return NULL;
    1785                 :            : 
    1786                 :            :         /* check for more available section table entries */
    1787                 :          0 :         sect_count = LE16_TO_CPU(buf->section_count);
    1788         [ #  # ]:          0 :         if (sect_count < bld->reserved_section_table_entries) {
    1789                 :          0 :                 void *section_ptr = ((u8 *)buf) + data_end;
    1790                 :            : 
    1791                 :          0 :                 buf->section_entry[sect_count].offset = CPU_TO_LE16(data_end);
    1792                 :          0 :                 buf->section_entry[sect_count].size = CPU_TO_LE16(size);
    1793                 :          0 :                 buf->section_entry[sect_count].type = CPU_TO_LE32(type);
    1794                 :            : 
    1795                 :          0 :                 data_end += size;
    1796                 :          0 :                 buf->data_end = CPU_TO_LE16(data_end);
    1797                 :            : 
    1798                 :          0 :                 buf->section_count = CPU_TO_LE16(sect_count + 1);
    1799                 :          0 :                 return section_ptr;
    1800                 :            :         }
    1801                 :            : 
    1802                 :            :         /* no free section table entries */
    1803                 :            :         return NULL;
    1804                 :            : }
    1805                 :            : 
    1806                 :            : /**
    1807                 :            :  * ice_pkg_buf_alloc_single_section
    1808                 :            :  * @hw: pointer to the HW structure
    1809                 :            :  * @type: the section type value
    1810                 :            :  * @size: the size of the section to reserve (in bytes)
    1811                 :            :  * @section: returns pointer to the section
    1812                 :            :  *
    1813                 :            :  * Allocates a package buffer with a single section.
    1814                 :            :  * Note: all package contents must be in Little Endian form.
    1815                 :            :  */
    1816                 :            : struct ice_buf_build *
    1817                 :          0 : ice_pkg_buf_alloc_single_section(struct ice_hw *hw, u32 type, u16 size,
    1818                 :            :                                  void **section)
    1819                 :            : {
    1820                 :            :         struct ice_buf_build *buf;
    1821                 :            : 
    1822         [ #  # ]:          0 :         if (!section)
    1823                 :            :                 return NULL;
    1824                 :            : 
    1825                 :          0 :         buf = ice_pkg_buf_alloc(hw);
    1826         [ #  # ]:          0 :         if (!buf)
    1827                 :            :                 return NULL;
    1828                 :            : 
    1829         [ #  # ]:          0 :         if (ice_pkg_buf_reserve_section(buf, 1))
    1830                 :          0 :                 goto ice_pkg_buf_alloc_single_section_err;
    1831                 :            : 
    1832                 :          0 :         *section = ice_pkg_buf_alloc_section(buf, type, size);
    1833         [ #  # ]:          0 :         if (!*section)
    1834                 :          0 :                 goto ice_pkg_buf_alloc_single_section_err;
    1835                 :            : 
    1836                 :            :         return buf;
    1837                 :            : 
    1838                 :          0 : ice_pkg_buf_alloc_single_section_err:
    1839                 :          0 :         ice_pkg_buf_free(hw, buf);
    1840                 :          0 :         return NULL;
    1841                 :            : }
    1842                 :            : 
    1843                 :            : /**
    1844                 :            :  * ice_pkg_buf_get_active_sections
    1845                 :            :  * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())
    1846                 :            :  *
    1847                 :            :  * Returns the number of active sections. Before using the package buffer
    1848                 :            :  * in an update package command, the caller should make sure that there is at
    1849                 :            :  * least one active section - otherwise, the buffer is not legal and should
    1850                 :            :  * not be used.
    1851                 :            :  * Note: all package contents must be in Little Endian form.
    1852                 :            :  */
    1853                 :          0 : u16 ice_pkg_buf_get_active_sections(struct ice_buf_build *bld)
    1854                 :            : {
    1855                 :            :         struct ice_buf_hdr *buf;
    1856                 :            : 
    1857         [ #  # ]:          0 :         if (!bld)
    1858                 :            :                 return 0;
    1859                 :            : 
    1860                 :            :         buf = (struct ice_buf_hdr *)&bld->buf;
    1861                 :          0 :         return LE16_TO_CPU(buf->section_count);
    1862                 :            : }
    1863                 :            : 
    1864                 :            : /**
    1865                 :            :  * ice_pkg_buf
    1866                 :            :  * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())
    1867                 :            :  *
    1868                 :            :  * Return a pointer to the buffer's header
    1869                 :            :  */
    1870                 :          0 : struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld)
    1871                 :            : {
    1872         [ #  # ]:          0 :         if (bld)
    1873                 :          0 :                 return &bld->buf;
    1874                 :            : 
    1875                 :            :         return NULL;
    1876                 :            : }
    1877                 :            : 
    1878                 :            : /**
    1879                 :            :  * ice_find_buf_table
    1880                 :            :  * @ice_seg: pointer to the ice segment
    1881                 :            :  *
    1882                 :            :  * Returns the address of the buffer table within the ice segment.
    1883                 :            :  */
    1884                 :          0 : struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg)
    1885                 :            : {
    1886                 :            :         struct ice_nvm_table *nvms;
    1887                 :            : 
    1888                 :          0 :         nvms = (struct ice_nvm_table *)
    1889                 :          0 :                 (ice_seg->device_table +
    1890                 :          0 :                  LE32_TO_CPU(ice_seg->device_table_count));
    1891                 :            : 
    1892                 :          0 :         return (_FORCE_ struct ice_buf_table *)
    1893                 :          0 :                 (nvms->vers + LE32_TO_CPU(nvms->table_count));
    1894                 :            : }
    1895                 :            : 
    1896                 :            : /**
    1897                 :            :  * ice_pkg_val_buf
    1898                 :            :  * @buf: pointer to the ice buffer
    1899                 :            :  *
    1900                 :            :  * This helper function validates a buffer's header.
    1901                 :            :  */
    1902                 :            : static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf)
    1903                 :            : {
    1904                 :            :         struct ice_buf_hdr *hdr;
    1905                 :            :         u16 section_count;
    1906                 :            :         u16 data_end;
    1907                 :            : 
    1908                 :          0 :         hdr = (struct ice_buf_hdr *)buf->buf;
    1909                 :            :         /* verify data */
    1910                 :          0 :         section_count = LE16_TO_CPU(hdr->section_count);
    1911         [ #  # ]:          0 :         if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT)
    1912                 :            :                 return NULL;
    1913                 :            : 
    1914                 :          0 :         data_end = LE16_TO_CPU(hdr->data_end);
    1915   [ #  #  #  #  :          0 :         if (data_end < ICE_MIN_S_DATA_END || data_end > ICE_MAX_S_DATA_END)
                   #  # ]
    1916                 :          0 :                 return NULL;
    1917                 :            : 
    1918                 :            :         return hdr;
    1919                 :            : }
    1920                 :            : 
    1921                 :            : /**
    1922                 :            :  * ice_pkg_enum_buf
    1923                 :            :  * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)
    1924                 :            :  * @state: pointer to the enum state
    1925                 :            :  *
    1926                 :            :  * This function will enumerate all the buffers in the ice segment. The first
    1927                 :            :  * call is made with the ice_seg parameter non-NULL; on subsequent calls,
    1928                 :            :  * ice_seg is set to NULL which continues the enumeration. When the function
    1929                 :            :  * returns a NULL pointer, then the end of the buffers has been reached, or an
    1930                 :            :  * unexpected value has been detected (for example an invalid section count or
    1931                 :            :  * an invalid buffer end value).
    1932                 :            :  */
    1933                 :            : struct ice_buf_hdr *
    1934                 :          0 : ice_pkg_enum_buf(struct ice_seg *ice_seg, struct ice_pkg_enum *state)
    1935                 :            : {
    1936         [ #  # ]:          0 :         if (ice_seg) {
    1937                 :          0 :                 state->buf_table = ice_find_buf_table(ice_seg);
    1938         [ #  # ]:          0 :                 if (!state->buf_table)
    1939                 :            :                         return NULL;
    1940                 :            : 
    1941         [ #  # ]:          0 :                 state->buf_idx = 0;
    1942                 :          0 :                 return ice_pkg_val_buf(state->buf_table->buf_array);
    1943                 :            :         }
    1944                 :            : 
    1945         [ #  # ]:          0 :         if (++state->buf_idx < LE32_TO_CPU(state->buf_table->buf_count))
    1946                 :          0 :                 return ice_pkg_val_buf(state->buf_table->buf_array +
    1947         [ #  # ]:          0 :                                        state->buf_idx);
    1948                 :            :         else
    1949                 :            :                 return NULL;
    1950                 :            : }
    1951                 :            : 
    1952                 :            : /**
    1953                 :            :  * ice_pkg_advance_sect
    1954                 :            :  * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)
    1955                 :            :  * @state: pointer to the enum state
    1956                 :            :  *
    1957                 :            :  * This helper function will advance the section within the ice segment,
    1958                 :            :  * also advancing the buffer if needed.
    1959                 :            :  */
    1960                 :            : bool
    1961                 :          0 : ice_pkg_advance_sect(struct ice_seg *ice_seg, struct ice_pkg_enum *state)
    1962                 :            : {
    1963   [ #  #  #  # ]:          0 :         if (!ice_seg && !state->buf)
    1964                 :            :                 return false;
    1965                 :            : 
    1966   [ #  #  #  # ]:          0 :         if (!ice_seg && state->buf)
    1967         [ #  # ]:          0 :                 if (++state->sect_idx < LE16_TO_CPU(state->buf->section_count))
    1968                 :            :                         return true;
    1969                 :            : 
    1970                 :          0 :         state->buf = ice_pkg_enum_buf(ice_seg, state);
    1971         [ #  # ]:          0 :         if (!state->buf)
    1972                 :            :                 return false;
    1973                 :            : 
    1974                 :            :         /* start of new buffer, reset section index */
    1975                 :          0 :         state->sect_idx = 0;
    1976                 :          0 :         return true;
    1977                 :            : }
    1978                 :            : 
    1979                 :            : /**
    1980                 :            :  * ice_pkg_enum_section
    1981                 :            :  * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)
    1982                 :            :  * @state: pointer to the enum state
    1983                 :            :  * @sect_type: section type to enumerate
    1984                 :            :  *
    1985                 :            :  * This function will enumerate all the sections of a particular type in the
    1986                 :            :  * ice segment. The first call is made with the ice_seg parameter non-NULL;
    1987                 :            :  * on subsequent calls, ice_seg is set to NULL which continues the enumeration.
    1988                 :            :  * When the function returns a NULL pointer, then the end of the matching
    1989                 :            :  * sections has been reached.
    1990                 :            :  */
    1991                 :            : void *
    1992                 :          0 : ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state,
    1993                 :            :                      u32 sect_type)
    1994                 :            : {
    1995                 :            :         u16 offset, size;
    1996                 :            : 
    1997         [ #  # ]:          0 :         if (ice_seg)
    1998                 :          0 :                 state->type = sect_type;
    1999                 :            : 
    2000         [ #  # ]:          0 :         if (!ice_pkg_advance_sect(ice_seg, state))
    2001                 :            :                 return NULL;
    2002                 :            : 
    2003                 :            :         /* scan for next matching section */
    2004                 :          0 :         while (state->buf->section_entry[state->sect_idx].type !=
    2005         [ #  # ]:          0 :                CPU_TO_LE32(state->type))
    2006         [ #  # ]:          0 :                 if (!ice_pkg_advance_sect(NULL, state))
    2007                 :            :                         return NULL;
    2008                 :            : 
    2009                 :            :         /* validate section */
    2010                 :          0 :         offset = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset);
    2011         [ #  # ]:          0 :         if (offset < ICE_MIN_S_OFF || offset > ICE_MAX_S_OFF)
    2012                 :            :                 return NULL;
    2013                 :            : 
    2014                 :          0 :         size = LE16_TO_CPU(state->buf->section_entry[state->sect_idx].size);
    2015         [ #  # ]:          0 :         if (size < ICE_MIN_S_SZ || size > ICE_MAX_S_SZ)
    2016                 :            :                 return NULL;
    2017                 :            : 
    2018                 :            :         /* make sure the section fits in the buffer */
    2019         [ #  # ]:          0 :         if (offset + size > ICE_PKG_BUF_SIZE)
    2020                 :            :                 return NULL;
    2021                 :            : 
    2022                 :          0 :         state->sect_type =
    2023                 :            :                 LE32_TO_CPU(state->buf->section_entry[state->sect_idx].type);
    2024                 :            : 
    2025                 :            :         /* calc pointer to this section */
    2026                 :          0 :         state->sect = ((u8 *)state->buf) +
    2027                 :          0 :                 LE16_TO_CPU(state->buf->section_entry[state->sect_idx].offset);
    2028                 :            : 
    2029                 :          0 :         return state->sect;
    2030                 :            : }
    2031                 :            : 
    2032                 :            : /**
    2033                 :            :  * ice_pkg_enum_entry
    2034                 :            :  * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)
    2035                 :            :  * @state: pointer to the enum state
    2036                 :            :  * @sect_type: section type to enumerate
    2037                 :            :  * @offset: pointer to variable that receives the offset in the table (optional)
    2038                 :            :  * @handler: function that handles access to the entries into the section type
    2039                 :            :  *
    2040                 :            :  * This function will enumerate all the entries in particular section type in
    2041                 :            :  * the ice segment. The first call is made with the ice_seg parameter non-NULL;
    2042                 :            :  * on subsequent calls, ice_seg is set to NULL which continues the enumeration.
    2043                 :            :  * When the function returns a NULL pointer, then the end of the entries has
    2044                 :            :  * been reached.
    2045                 :            :  *
    2046                 :            :  * Since each section may have a different header and entry size, the handler
    2047                 :            :  * function is needed to determine the number and location entries in each
    2048                 :            :  * section.
    2049                 :            :  *
    2050                 :            :  * The offset parameter is optional, but should be used for sections that
    2051                 :            :  * contain an offset for each section table. For such cases, the section handler
    2052                 :            :  * function must return the appropriate offset + index to give the absolution
    2053                 :            :  * offset for each entry. For example, if the base for a section's header
    2054                 :            :  * indicates a base offset of 10, and the index for the entry is 2, then
    2055                 :            :  * section handler function should set the offset to 10 + 2 = 12.
    2056                 :            :  */
    2057                 :            : void *
    2058                 :          0 : ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state,
    2059                 :            :                    u32 sect_type, u32 *offset,
    2060                 :            :                    void *(*handler)(u32 sect_type, void *section,
    2061                 :            :                                     u32 index, u32 *offset))
    2062                 :            : {
    2063                 :            :         void *entry;
    2064                 :            : 
    2065         [ #  # ]:          0 :         if (ice_seg) {
    2066         [ #  # ]:          0 :                 if (!handler)
    2067                 :            :                         return NULL;
    2068                 :            : 
    2069         [ #  # ]:          0 :                 if (!ice_pkg_enum_section(ice_seg, state, sect_type))
    2070                 :            :                         return NULL;
    2071                 :            : 
    2072                 :          0 :                 state->entry_idx = 0;
    2073                 :          0 :                 state->handler = handler;
    2074                 :            :         } else {
    2075                 :          0 :                 state->entry_idx++;
    2076                 :            :         }
    2077                 :            : 
    2078         [ #  # ]:          0 :         if (!state->handler)
    2079                 :            :                 return NULL;
    2080                 :            : 
    2081                 :            :         /* get entry */
    2082                 :          0 :         entry = state->handler(state->sect_type, state->sect, state->entry_idx,
    2083                 :            :                                offset);
    2084         [ #  # ]:          0 :         if (!entry) {
    2085                 :            :                 /* end of a section, look for another section of this type */
    2086         [ #  # ]:          0 :                 if (!ice_pkg_enum_section(NULL, state, 0))
    2087                 :            :                         return NULL;
    2088                 :            : 
    2089                 :          0 :                 state->entry_idx = 0;
    2090                 :          0 :                 entry = state->handler(state->sect_type, state->sect,
    2091                 :            :                                        state->entry_idx, offset);
    2092                 :            :         }
    2093                 :            : 
    2094                 :            :         return entry;
    2095                 :            : }
    2096                 :            : 
    2097                 :            : /**
    2098                 :            :  * ice_boost_tcam_handler
    2099                 :            :  * @sect_type: section type
    2100                 :            :  * @section: pointer to section
    2101                 :            :  * @index: index of the boost TCAM entry to be returned
    2102                 :            :  * @offset: pointer to receive absolute offset, always 0 for boost TCAM sections
    2103                 :            :  *
    2104                 :            :  * This is a callback function that can be passed to ice_pkg_enum_entry.
    2105                 :            :  * Handles enumeration of individual boost TCAM entries.
    2106                 :            :  */
    2107                 :            : static void *
    2108                 :          0 : ice_boost_tcam_handler(u32 sect_type, void *section, u32 index, u32 *offset)
    2109                 :            : {
    2110                 :            :         struct ice_boost_tcam_section *boost;
    2111                 :            : 
    2112         [ #  # ]:          0 :         if (!section)
    2113                 :            :                 return NULL;
    2114                 :            : 
    2115         [ #  # ]:          0 :         if (sect_type != ICE_SID_RXPARSER_BOOST_TCAM)
    2116                 :            :                 return NULL;
    2117                 :            : 
    2118         [ #  # ]:          0 :         if (index > ICE_MAX_BST_TCAMS_IN_BUF)
    2119                 :            :                 return NULL;
    2120                 :            : 
    2121         [ #  # ]:          0 :         if (offset)
    2122                 :          0 :                 *offset = 0;
    2123                 :            : 
    2124                 :            :         boost = (struct ice_boost_tcam_section *)section;
    2125         [ #  # ]:          0 :         if (index >= LE16_TO_CPU(boost->count))
    2126                 :            :                 return NULL;
    2127                 :            : 
    2128                 :          0 :         return boost->tcam + index;
    2129                 :            : }
    2130                 :            : 
    2131                 :            : /**
    2132                 :            :  * ice_find_boost_entry
    2133                 :            :  * @ice_seg: pointer to the ice segment (non-NULL)
    2134                 :            :  * @addr: Boost TCAM address of entry to search for
    2135                 :            :  * @entry: returns pointer to the entry
    2136                 :            :  *
    2137                 :            :  * Finds a particular Boost TCAM entry and returns a pointer to that entry
    2138                 :            :  * if it is found. The ice_seg parameter must not be NULL since the first call
    2139                 :            :  * to ice_pkg_enum_entry requires a pointer to an actual ice_segment structure.
    2140                 :            :  */
    2141                 :            : static int
    2142         [ #  # ]:          0 : ice_find_boost_entry(struct ice_seg *ice_seg, u16 addr,
    2143                 :            :                      struct ice_boost_tcam_entry **entry)
    2144                 :            : {
    2145                 :            :         struct ice_boost_tcam_entry *tcam;
    2146                 :            :         struct ice_pkg_enum state;
    2147                 :            : 
    2148                 :            :         ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);
    2149                 :            : 
    2150         [ #  # ]:          0 :         if (!ice_seg)
    2151                 :            :                 return ICE_ERR_PARAM;
    2152                 :            : 
    2153                 :            :         do {
    2154                 :            :                 tcam = (struct ice_boost_tcam_entry *)
    2155                 :          0 :                        ice_pkg_enum_entry(ice_seg, &state,
    2156                 :            :                                           ICE_SID_RXPARSER_BOOST_TCAM, NULL,
    2157                 :            :                                           ice_boost_tcam_handler);
    2158   [ #  #  #  # ]:          0 :                 if (tcam && LE16_TO_CPU(tcam->addr) == addr) {
    2159                 :          0 :                         *entry = tcam;
    2160                 :          0 :                         return 0;
    2161                 :            :                 }
    2162                 :            : 
    2163                 :            :                 ice_seg = NULL;
    2164         [ #  # ]:          0 :         } while (tcam);
    2165                 :            : 
    2166                 :          0 :         *entry = NULL;
    2167                 :          0 :         return ICE_ERR_CFG;
    2168                 :            : }
    2169                 :            : 
    2170                 :            : /**
    2171                 :            :  * ice_init_pkg_hints
    2172                 :            :  * @hw: pointer to the HW structure
    2173                 :            :  * @ice_seg: pointer to the segment of the package scan (non-NULL)
    2174                 :            :  *
    2175                 :            :  * This function will scan the package and save off relevant information
    2176                 :            :  * (hints or metadata) for driver use. The ice_seg parameter must not be NULL
    2177                 :            :  * since the first call to ice_enum_labels requires a pointer to an actual
    2178                 :            :  * ice_seg structure.
    2179                 :            :  */
    2180                 :          0 : void ice_init_pkg_hints(struct ice_hw *hw, struct ice_seg *ice_seg)
    2181                 :            : {
    2182                 :            :         struct ice_pkg_enum state;
    2183                 :            :         char *label_name;
    2184                 :            :         u16 val;
    2185                 :            :         int i;
    2186                 :            : 
    2187         [ #  # ]:          0 :         ice_memset(&hw->tnl, 0, sizeof(hw->tnl), ICE_NONDMA_MEM);
    2188                 :            :         ice_memset(&state, 0, sizeof(state), ICE_NONDMA_MEM);
    2189                 :            : 
    2190         [ #  # ]:          0 :         if (!ice_seg)
    2191                 :          0 :                 return;
    2192                 :            : 
    2193                 :            :         label_name = ice_enum_labels(ice_seg, ICE_SID_LBL_RXPARSER_TMEM, &state,
    2194                 :            :                                      &val);
    2195                 :            : 
    2196         [ #  # ]:          0 :         while (label_name) {
    2197                 :            : /* TODO: Replace !strnsmp() with wrappers like match_some_pre() */
    2198         [ #  # ]:          0 :                 if (!strncmp(label_name, ICE_TNL_PRE, strlen(ICE_TNL_PRE)))
    2199                 :            :                         /* check for a tunnel entry */
    2200                 :          0 :                         ice_add_tunnel_hint(hw, label_name, val);
    2201                 :            : 
    2202                 :            :                 /* check for a dvm mode entry */
    2203         [ #  # ]:          0 :                 else if (!strncmp(label_name, ICE_DVM_PRE, strlen(ICE_DVM_PRE)))
    2204                 :          0 :                         ice_add_dvm_hint(hw, val, true);
    2205                 :            : 
    2206                 :            :                 /* check for a svm mode entry */
    2207         [ #  # ]:          0 :                 else if (!strncmp(label_name, ICE_SVM_PRE, strlen(ICE_SVM_PRE)))
    2208                 :          0 :                         ice_add_dvm_hint(hw, val, false);
    2209                 :            : 
    2210                 :            :                 label_name = ice_enum_labels(NULL, 0, &state, &val);
    2211                 :            :         }
    2212                 :            : 
    2213                 :            :         /* Cache the appropriate boost TCAM entry pointers for tunnels */
    2214         [ #  # ]:          0 :         for (i = 0; i < hw->tnl.count; i++) {
    2215                 :          0 :                 ice_find_boost_entry(ice_seg, hw->tnl.tbl[i].boost_addr,
    2216                 :            :                                      &hw->tnl.tbl[i].boost_entry);
    2217         [ #  # ]:          0 :                 if (hw->tnl.tbl[i].boost_entry)
    2218                 :          0 :                         hw->tnl.tbl[i].valid = true;
    2219                 :            :         }
    2220                 :            : 
    2221                 :            :         /* Cache the appropriate boost TCAM entry pointers for DVM and SVM */
    2222         [ #  # ]:          0 :         for (i = 0; i < hw->dvm_upd.count; i++)
    2223                 :          0 :                 ice_find_boost_entry(ice_seg, hw->dvm_upd.tbl[i].boost_addr,
    2224                 :            :                                      &hw->dvm_upd.tbl[i].boost_entry);
    2225                 :            : }
    2226                 :            : 
    2227                 :            : /**
    2228                 :            :  * ice_acquire_global_cfg_lock
    2229                 :            :  * @hw: pointer to the HW structure
    2230                 :            :  * @access: access type (read or write)
    2231                 :            :  *
    2232                 :            :  * This function will request ownership of the global config lock for reading
    2233                 :            :  * or writing of the package. When attempting to obtain write access, the
    2234                 :            :  * caller must check for the following two return values:
    2235                 :            :  *
    2236                 :            :  * 0                  - Means the caller has acquired the global config lock
    2237                 :            :  *                      and can perform writing of the package.
    2238                 :            :  * ICE_ERR_AQ_NO_WORK - Indicates another driver has already written the
    2239                 :            :  *                      package or has found that no update was necessary; in
    2240                 :            :  *                      this case, the caller can just skip performing any
    2241                 :            :  *                      update of the package.
    2242                 :            :  */
    2243                 :            : int
    2244                 :          0 : ice_acquire_global_cfg_lock(struct ice_hw *hw,
    2245                 :            :                             enum ice_aq_res_access_type access)
    2246                 :            : {
    2247                 :            :         int status;
    2248                 :            : 
    2249                 :          0 :         status = ice_acquire_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID, access,
    2250                 :            :                                  ICE_GLOBAL_CFG_LOCK_TIMEOUT);
    2251                 :            : 
    2252         [ #  # ]:          0 :         if (status == ICE_ERR_AQ_NO_WORK)
    2253         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_PKG, "Global config lock: No work to do\n");
    2254                 :            : 
    2255                 :          0 :         return status;
    2256                 :            : }
    2257                 :            : 
    2258                 :            : /**
    2259                 :            :  * ice_release_global_cfg_lock
    2260                 :            :  * @hw: pointer to the HW structure
    2261                 :            :  *
    2262                 :            :  * This function will release the global config lock.
    2263                 :            :  */
    2264                 :          0 : void ice_release_global_cfg_lock(struct ice_hw *hw)
    2265                 :            : {
    2266                 :          0 :         ice_release_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID);
    2267                 :          0 : }
    2268                 :            : 
    2269                 :            : /**
    2270                 :            :  * ice_acquire_change_lock
    2271                 :            :  * @hw: pointer to the HW structure
    2272                 :            :  * @access: access type (read or write)
    2273                 :            :  *
    2274                 :            :  * This function will request ownership of the change lock.
    2275                 :            :  */
    2276                 :            : int
    2277                 :          0 : ice_acquire_change_lock(struct ice_hw *hw, enum ice_aq_res_access_type access)
    2278                 :            : {
    2279                 :          0 :         return ice_acquire_res(hw, ICE_CHANGE_LOCK_RES_ID, access,
    2280                 :            :                                ICE_CHANGE_LOCK_TIMEOUT);
    2281                 :            : }
    2282                 :            : 
    2283                 :            : /**
    2284                 :            :  * ice_release_change_lock
    2285                 :            :  * @hw: pointer to the HW structure
    2286                 :            :  *
    2287                 :            :  * This function will release the change lock using the proper Admin Command.
    2288                 :            :  */
    2289                 :          0 : void ice_release_change_lock(struct ice_hw *hw)
    2290                 :            : {
    2291                 :          0 :         ice_release_res(hw, ICE_CHANGE_LOCK_RES_ID);
    2292                 :          0 : }
    2293                 :            : 
    2294                 :            : /**
    2295                 :            :  * ice_is_get_tx_sched_new_format
    2296                 :            :  * @hw: pointer to the HW struct
    2297                 :            :  *
    2298                 :            :  * Determines if the new format for the Tx scheduler get api is supported
    2299                 :            :  */
    2300                 :            : static bool
    2301                 :          0 : ice_is_get_tx_sched_new_format(struct ice_hw *hw)
    2302                 :            : {
    2303         [ #  # ]:          0 :         if (ice_is_e830(hw))
    2304                 :            :                 return true;
    2305         [ #  # ]:          0 :         if (ice_is_e825c(hw))
    2306                 :          0 :                 return true;
    2307                 :            :         return false;
    2308                 :            : }
    2309                 :            : 
    2310                 :            : /**
    2311                 :            :  * ice_get_set_tx_topo - get or set tx topology
    2312                 :            :  * @hw: pointer to the HW struct
    2313                 :            :  * @buf: pointer to tx topology buffer
    2314                 :            :  * @buf_size: buffer size
    2315                 :            :  * @cd: pointer to command details structure or NULL
    2316                 :            :  * @flags: pointer to descriptor flags
    2317                 :            :  * @set: 0-get, 1-set topology
    2318                 :            :  *
    2319                 :            :  * The function will get or set tx topology
    2320                 :            :  */
    2321                 :            : static int
    2322                 :          0 : ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,
    2323                 :            :                     struct ice_sq_cd *cd, u8 *flags, bool set)
    2324                 :            : {
    2325                 :            :         struct ice_aqc_get_set_tx_topo *cmd;
    2326                 :            :         struct ice_aq_desc desc;
    2327                 :            :         int status;
    2328                 :            : 
    2329                 :            :         cmd = &desc.params.get_set_tx_topo;
    2330         [ #  # ]:          0 :         if (set) {
    2331                 :          0 :                 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_tx_topo);
    2332                 :          0 :                 cmd->set_flags = ICE_AQC_TX_TOPO_FLAGS_ISSUED;
    2333                 :            :                 /* requested to update a new topology, not a default topolgy */
    2334         [ #  # ]:          0 :                 if (buf)
    2335                 :          0 :                         cmd->set_flags |= ICE_AQC_TX_TOPO_FLAGS_SRC_RAM |
    2336                 :            :                                           ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW;
    2337                 :            : 
    2338                 :          0 :                 desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
    2339                 :            :         } else {
    2340                 :          0 :                 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_tx_topo);
    2341                 :          0 :                 cmd->get_flags = ICE_AQC_TX_TOPO_GET_RAM;
    2342                 :            : 
    2343         [ #  # ]:          0 :                 if (!ice_is_get_tx_sched_new_format(hw))
    2344                 :          0 :                         desc.flags |= CPU_TO_LE16(ICE_AQ_FLAG_RD);
    2345                 :            :         }
    2346                 :            : 
    2347                 :          0 :         status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);
    2348         [ #  # ]:          0 :         if (status)
    2349                 :            :                 return status;
    2350                 :            :         /* read the return flag values (first byte) for get operation */
    2351         [ #  # ]:          0 :         if (!set && flags)
    2352                 :          0 :                 *flags = desc.params.get_set_tx_topo.set_flags;
    2353                 :            : 
    2354                 :            :         return 0;
    2355                 :            : }
    2356                 :            : 
    2357                 :            : /**
    2358                 :            :  * ice_cfg_tx_topo - Initialize new tx topology if available
    2359                 :            :  * @hw: pointer to the HW struct
    2360                 :            :  * @buf: pointer to Tx topology buffer
    2361                 :            :  * @len: buffer size
    2362                 :            :  *
    2363                 :            :  * The function will apply the new Tx topology from the package buffer
    2364                 :            :  * if available.
    2365                 :            :  */
    2366                 :          0 : int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len)
    2367                 :            : {
    2368                 :            :         u8 *current_topo, *new_topo = NULL;
    2369                 :            :         struct ice_run_time_cfg_seg *seg;
    2370                 :            :         struct ice_buf_hdr *section;
    2371                 :            :         struct ice_pkg_hdr *pkg_hdr;
    2372                 :            :         enum ice_ddp_state state;
    2373                 :            :         u16 i, size = 0, offset;
    2374                 :            :         u32 reg = 0;
    2375                 :            :         int status;
    2376                 :            :         u8 flags;
    2377                 :            : 
    2378         [ #  # ]:          0 :         if (!buf || !len)
    2379                 :            :                 return ICE_ERR_PARAM;
    2380                 :            : 
    2381                 :            :         /* Does FW support new Tx topology mode ? */
    2382         [ #  # ]:          0 :         if (!hw->func_caps.common_cap.tx_sched_topo_comp_mode_en) {
    2383         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "FW doesn't support compatibility mode\n");
    2384                 :          0 :                 return ICE_ERR_NOT_SUPPORTED;
    2385                 :            :         }
    2386                 :            : 
    2387                 :          0 :         current_topo = (u8 *)ice_malloc(hw, ICE_AQ_MAX_BUF_LEN);
    2388         [ #  # ]:          0 :         if (!current_topo)
    2389                 :            :                 return ICE_ERR_NO_MEMORY;
    2390                 :            : 
    2391                 :            :         /* get the current Tx topology */
    2392                 :          0 :         status = ice_get_set_tx_topo(hw, current_topo, ICE_AQ_MAX_BUF_LEN, NULL,
    2393                 :            :                                      &flags, false);
    2394                 :          0 :         ice_free(hw, current_topo);
    2395                 :            : 
    2396         [ #  # ]:          0 :         if (status) {
    2397         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");
    2398                 :          0 :                 return status;
    2399                 :            :         }
    2400                 :            : 
    2401                 :            :         pkg_hdr = (struct ice_pkg_hdr *)buf;
    2402                 :          0 :         state = ice_verify_pkg(pkg_hdr, len);
    2403         [ #  # ]:          0 :         if (state) {
    2404         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "failed to verify pkg (err: %d)\n",
    2405                 :            :                           state);
    2406                 :          0 :                 return ICE_ERR_CFG;
    2407                 :            :         }
    2408                 :            : 
    2409                 :            :         /* find run time configuration segment */
    2410                 :            :         seg = (struct ice_run_time_cfg_seg *)
    2411                 :          0 :                 ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr);
    2412         [ #  # ]:          0 :         if (!seg) {
    2413         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment is missing\n");
    2414                 :          0 :                 return ICE_ERR_CFG;
    2415                 :            :         }
    2416                 :            : 
    2417         [ #  # ]:          0 :         if (LE32_TO_CPU(seg->buf_table.buf_count) < ICE_MIN_S_COUNT) {
    2418         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment count(%d) is wrong\n",
    2419                 :            :                           seg->buf_table.buf_count);
    2420                 :          0 :                 return ICE_ERR_CFG;
    2421                 :            :         }
    2422                 :            : 
    2423                 :            :         section = ice_pkg_val_buf(seg->buf_table.buf_array);
    2424                 :            : 
    2425         [ #  # ]:          0 :         if (!section || LE32_TO_CPU(section->section_entry[0].type) !=
    2426                 :            :                 ICE_SID_TX_5_LAYER_TOPO) {
    2427         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "5 layer topology section type is wrong\n");
    2428                 :          0 :                 return ICE_ERR_CFG;
    2429                 :            :         }
    2430                 :            : 
    2431                 :          0 :         size = LE16_TO_CPU(section->section_entry[0].size);
    2432                 :          0 :         offset = LE16_TO_CPU(section->section_entry[0].offset);
    2433         [ #  # ]:          0 :         if (size < ICE_MIN_S_SZ || size > ICE_MAX_S_SZ) {
    2434         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "5 layer topology section size is wrong\n");
    2435                 :          0 :                 return ICE_ERR_CFG;
    2436                 :            :         }
    2437                 :            : 
    2438                 :            :         /* make sure the section fits in the buffer */
    2439         [ #  # ]:          0 :         if (offset + size > ICE_PKG_BUF_SIZE) {
    2440         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "5 layer topology buffer > 4K\n");
    2441                 :          0 :                 return ICE_ERR_CFG;
    2442                 :            :         }
    2443                 :            : 
    2444                 :            :         /* Get the new topology buffer */
    2445                 :          0 :         new_topo = ((u8 *)section) + offset;
    2446                 :            : 
    2447                 :            :         /* acquire global lock to make sure that set topology issued
    2448                 :            :          * by one PF
    2449                 :            :          */
    2450                 :          0 :         status = ice_acquire_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID, ICE_RES_WRITE,
    2451                 :            :                                  ICE_GLOBAL_CFG_LOCK_TIMEOUT);
    2452         [ #  # ]:          0 :         if (status) {
    2453         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n");
    2454                 :          0 :                 return status;
    2455                 :            :         }
    2456                 :            : 
    2457                 :            :         /* check reset was triggered already or not */
    2458                 :          0 :         reg = rd32(hw, GLGEN_RSTAT);
    2459         [ #  # ]:          0 :         if (reg & GLGEN_RSTAT_DEVSTATE_M) {
    2460                 :            :                 /* Reset is in progress, re-init the hw again */
    2461         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. layer topology might be applied already\n");
    2462                 :          0 :                 ice_check_reset(hw);
    2463                 :          0 :                 return 0;
    2464                 :            :         }
    2465                 :            : 
    2466                 :            :         /* set new topology */
    2467                 :          0 :         status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true);
    2468         [ #  # ]:          0 :         if (status) {
    2469         [ #  # ]:          0 :                 ice_debug(hw, ICE_DBG_INIT, "Set tx topology is failed\n");
    2470                 :          0 :                 return status;
    2471                 :            :         }
    2472                 :            : 
    2473                 :            :         /* new topology is updated, delay 1 second before issuing the CORRER */
    2474         [ #  # ]:          0 :         for (i = 0; i < 10; i++)
    2475                 :          0 :                 ice_msec_delay(100, true);
    2476                 :          0 :         ice_reset(hw, ICE_RESET_CORER);
    2477                 :            :         /* CORER will clear the global lock, so no explicit call
    2478                 :            :          * required for release
    2479                 :            :          */
    2480                 :          0 :         return 0;
    2481                 :            : }

Generated by: LCOV version 1.14