2501 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2022, Intel Corporation. */3 4#include "ice_common.h"5#include "ice.h"6#include "ice_ddp.h"7#include "ice_sched.h"8 9/* For supporting double VLAN mode, it is necessary to enable or disable certain10 * boost tcam entries. The metadata labels names that match the following11 * prefixes will be saved to allow enabling double VLAN mode.12 */13#define ICE_DVM_PRE "BOOST_MAC_VLAN_DVM" /* enable these entries */14#define ICE_SVM_PRE "BOOST_MAC_VLAN_SVM" /* disable these entries */15 16/* To support tunneling entries by PF, the package will append the PF number to17 * the label; for example TNL_VXLAN_PF0, TNL_VXLAN_PF1, TNL_VXLAN_PF2, etc.18 */19#define ICE_TNL_PRE "TNL_"20static const struct ice_tunnel_type_scan tnls[] = {21 { TNL_VXLAN, "TNL_VXLAN_PF" },22 { TNL_GENEVE, "TNL_GENEVE_PF" },23 { TNL_LAST, "" }24};25 26/**27 * ice_verify_pkg - verify package28 * @pkg: pointer to the package buffer29 * @len: size of the package buffer30 *31 * Verifies various attributes of the package file, including length, format32 * version, and the requirement of at least one segment.33 */34static enum ice_ddp_state ice_verify_pkg(const struct ice_pkg_hdr *pkg, u32 len)35{36 u32 seg_count;37 u32 i;38 39 if (len < struct_size(pkg, seg_offset, 1))40 return ICE_DDP_PKG_INVALID_FILE;41 42 if (pkg->pkg_format_ver.major != ICE_PKG_FMT_VER_MAJ ||43 pkg->pkg_format_ver.minor != ICE_PKG_FMT_VER_MNR ||44 pkg->pkg_format_ver.update != ICE_PKG_FMT_VER_UPD ||45 pkg->pkg_format_ver.draft != ICE_PKG_FMT_VER_DFT)46 return ICE_DDP_PKG_INVALID_FILE;47 48 /* pkg must have at least one segment */49 seg_count = le32_to_cpu(pkg->seg_count);50 if (seg_count < 1)51 return ICE_DDP_PKG_INVALID_FILE;52 53 /* make sure segment array fits in package length */54 if (len < struct_size(pkg, seg_offset, seg_count))55 return ICE_DDP_PKG_INVALID_FILE;56 57 /* all segments must fit within length */58 for (i = 0; i < seg_count; i++) {59 u32 off = le32_to_cpu(pkg->seg_offset[i]);60 const struct ice_generic_seg_hdr *seg;61 62 /* segment header must fit */63 if (len < off + sizeof(*seg))64 return ICE_DDP_PKG_INVALID_FILE;65 66 seg = (void *)pkg + off;67 68 /* segment body must fit */69 if (len < off + le32_to_cpu(seg->seg_size))70 return ICE_DDP_PKG_INVALID_FILE;71 }72 73 return ICE_DDP_PKG_SUCCESS;74}75 76/**77 * ice_free_seg - free package segment pointer78 * @hw: pointer to the hardware structure79 *80 * Frees the package segment pointer in the proper manner, depending on if the81 * segment was allocated or just the passed in pointer was stored.82 */83void ice_free_seg(struct ice_hw *hw)84{85 if (hw->pkg_copy) {86 devm_kfree(ice_hw_to_dev(hw), hw->pkg_copy);87 hw->pkg_copy = NULL;88 hw->pkg_size = 0;89 }90 hw->seg = NULL;91}92 93/**94 * ice_chk_pkg_version - check package version for compatibility with driver95 * @pkg_ver: pointer to a version structure to check96 *97 * Check to make sure that the package about to be downloaded is compatible with98 * the driver. To be compatible, the major and minor components of the package99 * version must match our ICE_PKG_SUPP_VER_MAJ and ICE_PKG_SUPP_VER_MNR100 * definitions.101 */102static enum ice_ddp_state ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver)103{104 if (pkg_ver->major > ICE_PKG_SUPP_VER_MAJ ||105 (pkg_ver->major == ICE_PKG_SUPP_VER_MAJ &&106 pkg_ver->minor > ICE_PKG_SUPP_VER_MNR))107 return ICE_DDP_PKG_FILE_VERSION_TOO_HIGH;108 else if (pkg_ver->major < ICE_PKG_SUPP_VER_MAJ ||109 (pkg_ver->major == ICE_PKG_SUPP_VER_MAJ &&110 pkg_ver->minor < ICE_PKG_SUPP_VER_MNR))111 return ICE_DDP_PKG_FILE_VERSION_TOO_LOW;112 113 return ICE_DDP_PKG_SUCCESS;114}115 116/**117 * ice_pkg_val_buf118 * @buf: pointer to the ice buffer119 *120 * This helper function validates a buffer's header.121 */122static const struct ice_buf_hdr *ice_pkg_val_buf(const struct ice_buf *buf)123{124 const struct ice_buf_hdr *hdr;125 u16 section_count;126 u16 data_end;127 128 hdr = (const struct ice_buf_hdr *)buf->buf;129 /* verify data */130 section_count = le16_to_cpu(hdr->section_count);131 if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT)132 return NULL;133 134 data_end = le16_to_cpu(hdr->data_end);135 if (data_end < ICE_MIN_S_DATA_END || data_end > ICE_MAX_S_DATA_END)136 return NULL;137 138 return hdr;139}140 141/**142 * ice_find_buf_table143 * @ice_seg: pointer to the ice segment144 *145 * Returns the address of the buffer table within the ice segment.146 */147static struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg)148{149 struct ice_nvm_table *nvms = (struct ice_nvm_table *)150 (ice_seg->device_table + le32_to_cpu(ice_seg->device_table_count));151 152 return (__force struct ice_buf_table *)(nvms->vers +153 le32_to_cpu(nvms->table_count));154}155 156/**157 * ice_pkg_enum_buf158 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)159 * @state: pointer to the enum state160 *161 * This function will enumerate all the buffers in the ice segment. The first162 * call is made with the ice_seg parameter non-NULL; on subsequent calls,163 * ice_seg is set to NULL which continues the enumeration. When the function164 * returns a NULL pointer, then the end of the buffers has been reached, or an165 * unexpected value has been detected (for example an invalid section count or166 * an invalid buffer end value).167 */168static const struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg,169 struct ice_pkg_enum *state)170{171 if (ice_seg) {172 state->buf_table = ice_find_buf_table(ice_seg);173 if (!state->buf_table)174 return NULL;175 176 state->buf_idx = 0;177 return ice_pkg_val_buf(state->buf_table->buf_array);178 }179 180 if (++state->buf_idx < le32_to_cpu(state->buf_table->buf_count))181 return ice_pkg_val_buf(state->buf_table->buf_array +182 state->buf_idx);183 else184 return NULL;185}186 187/**188 * ice_pkg_advance_sect189 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)190 * @state: pointer to the enum state191 *192 * This helper function will advance the section within the ice segment,193 * also advancing the buffer if needed.194 */195static bool ice_pkg_advance_sect(struct ice_seg *ice_seg,196 struct ice_pkg_enum *state)197{198 if (!ice_seg && !state->buf)199 return false;200 201 if (!ice_seg && state->buf)202 if (++state->sect_idx < le16_to_cpu(state->buf->section_count))203 return true;204 205 state->buf = ice_pkg_enum_buf(ice_seg, state);206 if (!state->buf)207 return false;208 209 /* start of new buffer, reset section index */210 state->sect_idx = 0;211 return true;212}213 214/**215 * ice_pkg_enum_section216 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)217 * @state: pointer to the enum state218 * @sect_type: section type to enumerate219 *220 * This function will enumerate all the sections of a particular type in the221 * ice segment. The first call is made with the ice_seg parameter non-NULL;222 * on subsequent calls, ice_seg is set to NULL which continues the enumeration.223 * When the function returns a NULL pointer, then the end of the matching224 * sections has been reached.225 */226void *ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state,227 u32 sect_type)228{229 u16 offset, size;230 231 if (ice_seg)232 state->type = sect_type;233 234 if (!ice_pkg_advance_sect(ice_seg, state))235 return NULL;236 237 /* scan for next matching section */238 while (state->buf->section_entry[state->sect_idx].type !=239 cpu_to_le32(state->type))240 if (!ice_pkg_advance_sect(NULL, state))241 return NULL;242 243 /* validate section */244 offset = le16_to_cpu(state->buf->section_entry[state->sect_idx].offset);245 if (offset < ICE_MIN_S_OFF || offset > ICE_MAX_S_OFF)246 return NULL;247 248 size = le16_to_cpu(state->buf->section_entry[state->sect_idx].size);249 if (size < ICE_MIN_S_SZ || size > ICE_MAX_S_SZ)250 return NULL;251 252 /* make sure the section fits in the buffer */253 if (offset + size > ICE_PKG_BUF_SIZE)254 return NULL;255 256 state->sect_type =257 le32_to_cpu(state->buf->section_entry[state->sect_idx].type);258 259 /* calc pointer to this section */260 state->sect =261 ((u8 *)state->buf) +262 le16_to_cpu(state->buf->section_entry[state->sect_idx].offset);263 264 return state->sect;265}266 267/**268 * ice_pkg_enum_entry269 * @ice_seg: pointer to the ice segment (or NULL on subsequent calls)270 * @state: pointer to the enum state271 * @sect_type: section type to enumerate272 * @offset: pointer to variable that receives the offset in the table (optional)273 * @handler: function that handles access to the entries into the section type274 *275 * This function will enumerate all the entries in particular section type in276 * the ice segment. The first call is made with the ice_seg parameter non-NULL;277 * on subsequent calls, ice_seg is set to NULL which continues the enumeration.278 * When the function returns a NULL pointer, then the end of the entries has279 * been reached.280 *281 * Since each section may have a different header and entry size, the handler282 * function is needed to determine the number and location entries in each283 * section.284 *285 * The offset parameter is optional, but should be used for sections that286 * contain an offset for each section table. For such cases, the section handler287 * function must return the appropriate offset + index to give the absolution288 * offset for each entry. For example, if the base for a section's header289 * indicates a base offset of 10, and the index for the entry is 2, then290 * section handler function should set the offset to 10 + 2 = 12.291 */292void *ice_pkg_enum_entry(struct ice_seg *ice_seg,293 struct ice_pkg_enum *state, u32 sect_type,294 u32 *offset,295 void *(*handler)(u32 sect_type, void *section,296 u32 index, u32 *offset))297{298 void *entry;299 300 if (ice_seg) {301 if (!handler)302 return NULL;303 304 if (!ice_pkg_enum_section(ice_seg, state, sect_type))305 return NULL;306 307 state->entry_idx = 0;308 state->handler = handler;309 } else {310 state->entry_idx++;311 }312 313 if (!state->handler)314 return NULL;315 316 /* get entry */317 entry = state->handler(state->sect_type, state->sect, state->entry_idx,318 offset);319 if (!entry) {320 /* end of a section, look for another section of this type */321 if (!ice_pkg_enum_section(NULL, state, 0))322 return NULL;323 324 state->entry_idx = 0;325 entry = state->handler(state->sect_type, state->sect,326 state->entry_idx, offset);327 }328 329 return entry;330}331 332/**333 * ice_sw_fv_handler334 * @sect_type: section type335 * @section: pointer to section336 * @index: index of the field vector entry to be returned337 * @offset: ptr to variable that receives the offset in the field vector table338 *339 * This is a callback function that can be passed to ice_pkg_enum_entry.340 * This function treats the given section as of type ice_sw_fv_section and341 * enumerates offset field. "offset" is an index into the field vector table.342 */343static void *ice_sw_fv_handler(u32 sect_type, void *section, u32 index,344 u32 *offset)345{346 struct ice_sw_fv_section *fv_section = section;347 348 if (!section || sect_type != ICE_SID_FLD_VEC_SW)349 return NULL;350 if (index >= le16_to_cpu(fv_section->count))351 return NULL;352 if (offset)353 /* "index" passed in to this function is relative to a given354 * 4k block. To get to the true index into the field vector355 * table need to add the relative index to the base_offset356 * field of this section357 */358 *offset = le16_to_cpu(fv_section->base_offset) + index;359 return fv_section->fv + index;360}361 362/**363 * ice_get_prof_index_max - get the max profile index for used profile364 * @hw: pointer to the HW struct365 *366 * Calling this function will get the max profile index for used profile367 * and store the index number in struct ice_switch_info *switch_info368 * in HW for following use.369 */370static int ice_get_prof_index_max(struct ice_hw *hw)371{372 u16 prof_index = 0, j, max_prof_index = 0;373 struct ice_pkg_enum state;374 struct ice_seg *ice_seg;375 bool flag = false;376 struct ice_fv *fv;377 u32 offset;378 379 memset(&state, 0, sizeof(state));380 381 if (!hw->seg)382 return -EINVAL;383 384 ice_seg = hw->seg;385 386 do {387 fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,388 &offset, ice_sw_fv_handler);389 if (!fv)390 break;391 ice_seg = NULL;392 393 /* in the profile that not be used, the prot_id is set to 0xff394 * and the off is set to 0x1ff for all the field vectors.395 */396 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)397 if (fv->ew[j].prot_id != ICE_PROT_INVALID ||398 fv->ew[j].off != ICE_FV_OFFSET_INVAL)399 flag = true;400 if (flag && prof_index > max_prof_index)401 max_prof_index = prof_index;402 403 prof_index++;404 flag = false;405 } while (fv);406 407 hw->switch_info->max_used_prof_index = max_prof_index;408 409 return 0;410}411 412/**413 * ice_get_ddp_pkg_state - get DDP pkg state after download414 * @hw: pointer to the HW struct415 * @already_loaded: indicates if pkg was already loaded onto the device416 */417static enum ice_ddp_state ice_get_ddp_pkg_state(struct ice_hw *hw,418 bool already_loaded)419{420 if (hw->pkg_ver.major == hw->active_pkg_ver.major &&421 hw->pkg_ver.minor == hw->active_pkg_ver.minor &&422 hw->pkg_ver.update == hw->active_pkg_ver.update &&423 hw->pkg_ver.draft == hw->active_pkg_ver.draft &&424 !memcmp(hw->pkg_name, hw->active_pkg_name, sizeof(hw->pkg_name))) {425 if (already_loaded)426 return ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED;427 else428 return ICE_DDP_PKG_SUCCESS;429 } else if (hw->active_pkg_ver.major != ICE_PKG_SUPP_VER_MAJ ||430 hw->active_pkg_ver.minor != ICE_PKG_SUPP_VER_MNR) {431 return ICE_DDP_PKG_ALREADY_LOADED_NOT_SUPPORTED;432 } else if (hw->active_pkg_ver.major == ICE_PKG_SUPP_VER_MAJ &&433 hw->active_pkg_ver.minor == ICE_PKG_SUPP_VER_MNR) {434 return ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED;435 } else {436 return ICE_DDP_PKG_ERR;437 }438}439 440/**441 * ice_init_pkg_regs - initialize additional package registers442 * @hw: pointer to the hardware structure443 */444static void ice_init_pkg_regs(struct ice_hw *hw)445{446#define ICE_SW_BLK_INP_MASK_L 0xFFFFFFFF447#define ICE_SW_BLK_INP_MASK_H 0x0000FFFF448#define ICE_SW_BLK_IDX 0449 450 /* setup Switch block input mask, which is 48-bits in two parts */451 wr32(hw, GL_PREEXT_L2_PMASK0(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_L);452 wr32(hw, GL_PREEXT_L2_PMASK1(ICE_SW_BLK_IDX), ICE_SW_BLK_INP_MASK_H);453}454 455/**456 * ice_marker_ptype_tcam_handler457 * @sect_type: section type458 * @section: pointer to section459 * @index: index of the Marker PType TCAM entry to be returned460 * @offset: pointer to receive absolute offset, always 0 for ptype TCAM sections461 *462 * This is a callback function that can be passed to ice_pkg_enum_entry.463 * Handles enumeration of individual Marker PType TCAM entries.464 */465static void *ice_marker_ptype_tcam_handler(u32 sect_type, void *section,466 u32 index, u32 *offset)467{468 struct ice_marker_ptype_tcam_section *marker_ptype;469 470 if (sect_type != ICE_SID_RXPARSER_MARKER_PTYPE)471 return NULL;472 473 if (index > ICE_MAX_MARKER_PTYPE_TCAMS_IN_BUF)474 return NULL;475 476 if (offset)477 *offset = 0;478 479 marker_ptype = section;480 if (index >= le16_to_cpu(marker_ptype->count))481 return NULL;482 483 return marker_ptype->tcam + index;484}485 486/**487 * ice_add_dvm_hint488 * @hw: pointer to the HW structure489 * @val: value of the boost entry490 * @enable: true if entry needs to be enabled, or false if needs to be disabled491 */492static void ice_add_dvm_hint(struct ice_hw *hw, u16 val, bool enable)493{494 if (hw->dvm_upd.count < ICE_DVM_MAX_ENTRIES) {495 hw->dvm_upd.tbl[hw->dvm_upd.count].boost_addr = val;496 hw->dvm_upd.tbl[hw->dvm_upd.count].enable = enable;497 hw->dvm_upd.count++;498 }499}500 501/**502 * ice_add_tunnel_hint503 * @hw: pointer to the HW structure504 * @label_name: label text505 * @val: value of the tunnel port boost entry506 */507static void ice_add_tunnel_hint(struct ice_hw *hw, char *label_name, u16 val)508{509 if (hw->tnl.count < ICE_TUNNEL_MAX_ENTRIES) {510 u16 i;511 512 for (i = 0; tnls[i].type != TNL_LAST; i++) {513 size_t len = strlen(tnls[i].label_prefix);514 515 /* Look for matching label start, before continuing */516 if (strncmp(label_name, tnls[i].label_prefix, len))517 continue;518 519 /* Make sure this label matches our PF. Note that the PF520 * character ('0' - '7') will be located where our521 * prefix string's null terminator is located.522 */523 if ((label_name[len] - '0') == hw->pf_id) {524 hw->tnl.tbl[hw->tnl.count].type = tnls[i].type;525 hw->tnl.tbl[hw->tnl.count].valid = false;526 hw->tnl.tbl[hw->tnl.count].boost_addr = val;527 hw->tnl.tbl[hw->tnl.count].port = 0;528 hw->tnl.count++;529 break;530 }531 }532 }533}534 535/**536 * ice_label_enum_handler537 * @sect_type: section type538 * @section: pointer to section539 * @index: index of the label entry to be returned540 * @offset: pointer to receive absolute offset, always zero for label sections541 *542 * This is a callback function that can be passed to ice_pkg_enum_entry.543 * Handles enumeration of individual label entries.544 */545static void *ice_label_enum_handler(u32 __always_unused sect_type,546 void *section, u32 index, u32 *offset)547{548 struct ice_label_section *labels;549 550 if (!section)551 return NULL;552 553 if (index > ICE_MAX_LABELS_IN_BUF)554 return NULL;555 556 if (offset)557 *offset = 0;558 559 labels = section;560 if (index >= le16_to_cpu(labels->count))561 return NULL;562 563 return labels->label + index;564}565 566/**567 * ice_enum_labels568 * @ice_seg: pointer to the ice segment (NULL on subsequent calls)569 * @type: the section type that will contain the label (0 on subsequent calls)570 * @state: ice_pkg_enum structure that will hold the state of the enumeration571 * @value: pointer to a value that will return the label's value if found572 *573 * Enumerates a list of labels in the package. The caller will call574 * ice_enum_labels(ice_seg, type, ...) to start the enumeration, then call575 * ice_enum_labels(NULL, 0, ...) to continue. When the function returns a NULL576 * the end of the list has been reached.577 */578static char *ice_enum_labels(struct ice_seg *ice_seg, u32 type,579 struct ice_pkg_enum *state, u16 *value)580{581 struct ice_label *label;582 583 /* Check for valid label section on first call */584 if (type && !(type >= ICE_SID_LBL_FIRST && type <= ICE_SID_LBL_LAST))585 return NULL;586 587 label = ice_pkg_enum_entry(ice_seg, state, type, NULL,588 ice_label_enum_handler);589 if (!label)590 return NULL;591 592 *value = le16_to_cpu(label->value);593 return label->name;594}595 596/**597 * ice_boost_tcam_handler598 * @sect_type: section type599 * @section: pointer to section600 * @index: index of the boost TCAM entry to be returned601 * @offset: pointer to receive absolute offset, always 0 for boost TCAM sections602 *603 * This is a callback function that can be passed to ice_pkg_enum_entry.604 * Handles enumeration of individual boost TCAM entries.605 */606static void *ice_boost_tcam_handler(u32 sect_type, void *section, u32 index,607 u32 *offset)608{609 struct ice_boost_tcam_section *boost;610 611 if (!section)612 return NULL;613 614 if (sect_type != ICE_SID_RXPARSER_BOOST_TCAM)615 return NULL;616 617 if (index > ICE_MAX_BST_TCAMS_IN_BUF)618 return NULL;619 620 if (offset)621 *offset = 0;622 623 boost = section;624 if (index >= le16_to_cpu(boost->count))625 return NULL;626 627 return boost->tcam + index;628}629 630/**631 * ice_find_boost_entry632 * @ice_seg: pointer to the ice segment (non-NULL)633 * @addr: Boost TCAM address of entry to search for634 * @entry: returns pointer to the entry635 *636 * Finds a particular Boost TCAM entry and returns a pointer to that entry637 * if it is found. The ice_seg parameter must not be NULL since the first call638 * to ice_pkg_enum_entry requires a pointer to an actual ice_segment structure.639 */640static int ice_find_boost_entry(struct ice_seg *ice_seg, u16 addr,641 struct ice_boost_tcam_entry **entry)642{643 struct ice_boost_tcam_entry *tcam;644 struct ice_pkg_enum state;645 646 memset(&state, 0, sizeof(state));647 648 if (!ice_seg)649 return -EINVAL;650 651 do {652 tcam = ice_pkg_enum_entry(ice_seg, &state,653 ICE_SID_RXPARSER_BOOST_TCAM, NULL,654 ice_boost_tcam_handler);655 if (tcam && le16_to_cpu(tcam->addr) == addr) {656 *entry = tcam;657 return 0;658 }659 660 ice_seg = NULL;661 } while (tcam);662 663 *entry = NULL;664 return -EIO;665}666 667/**668 * ice_is_init_pkg_successful - check if DDP init was successful669 * @state: state of the DDP pkg after download670 */671bool ice_is_init_pkg_successful(enum ice_ddp_state state)672{673 switch (state) {674 case ICE_DDP_PKG_SUCCESS:675 case ICE_DDP_PKG_SAME_VERSION_ALREADY_LOADED:676 case ICE_DDP_PKG_COMPATIBLE_ALREADY_LOADED:677 return true;678 default:679 return false;680 }681}682 683/**684 * ice_pkg_buf_alloc685 * @hw: pointer to the HW structure686 *687 * Allocates a package buffer and returns a pointer to the buffer header.688 * Note: all package contents must be in Little Endian form.689 */690struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw)691{692 struct ice_buf_build *bld;693 struct ice_buf_hdr *buf;694 695 bld = devm_kzalloc(ice_hw_to_dev(hw), sizeof(*bld), GFP_KERNEL);696 if (!bld)697 return NULL;698 699 buf = (struct ice_buf_hdr *)bld;700 buf->data_end =701 cpu_to_le16(offsetof(struct ice_buf_hdr, section_entry));702 return bld;703}704 705static bool ice_is_gtp_u_profile(u16 prof_idx)706{707 return (prof_idx >= ICE_PROFID_IPV6_GTPU_TEID &&708 prof_idx <= ICE_PROFID_IPV6_GTPU_IPV6_TCP_INNER) ||709 prof_idx == ICE_PROFID_IPV4_GTPU_TEID;710}711 712static bool ice_is_gtp_c_profile(u16 prof_idx)713{714 switch (prof_idx) {715 case ICE_PROFID_IPV4_GTPC_TEID:716 case ICE_PROFID_IPV4_GTPC_NO_TEID:717 case ICE_PROFID_IPV6_GTPC_TEID:718 case ICE_PROFID_IPV6_GTPC_NO_TEID:719 return true;720 default:721 return false;722 }723}724 725static bool ice_is_pfcp_profile(u16 prof_idx)726{727 return prof_idx >= ICE_PROFID_IPV4_PFCP_NODE &&728 prof_idx <= ICE_PROFID_IPV6_PFCP_SESSION;729}730 731/**732 * ice_get_sw_prof_type - determine switch profile type733 * @hw: pointer to the HW structure734 * @fv: pointer to the switch field vector735 * @prof_idx: profile index to check736 */737static enum ice_prof_type ice_get_sw_prof_type(struct ice_hw *hw,738 struct ice_fv *fv, u32 prof_idx)739{740 u16 i;741 742 if (ice_is_gtp_c_profile(prof_idx))743 return ICE_PROF_TUN_GTPC;744 745 if (ice_is_gtp_u_profile(prof_idx))746 return ICE_PROF_TUN_GTPU;747 748 if (ice_is_pfcp_profile(prof_idx))749 return ICE_PROF_TUN_PFCP;750 751 for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) {752 /* UDP tunnel will have UDP_OF protocol ID and VNI offset */753 if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&754 fv->ew[i].off == ICE_VNI_OFFSET)755 return ICE_PROF_TUN_UDP;756 757 /* GRE tunnel will have GRE protocol */758 if (fv->ew[i].prot_id == (u8)ICE_PROT_GRE_OF)759 return ICE_PROF_TUN_GRE;760 }761 762 return ICE_PROF_NON_TUN;763}764 765/**766 * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type767 * @hw: pointer to hardware structure768 * @req_profs: type of profiles requested769 * @bm: pointer to memory for returning the bitmap of field vectors770 */771void ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs,772 unsigned long *bm)773{774 struct ice_pkg_enum state;775 struct ice_seg *ice_seg;776 struct ice_fv *fv;777 778 if (req_profs == ICE_PROF_ALL) {779 bitmap_set(bm, 0, ICE_MAX_NUM_PROFILES);780 return;781 }782 783 memset(&state, 0, sizeof(state));784 bitmap_zero(bm, ICE_MAX_NUM_PROFILES);785 ice_seg = hw->seg;786 do {787 enum ice_prof_type prof_type;788 u32 offset;789 790 fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,791 &offset, ice_sw_fv_handler);792 ice_seg = NULL;793 794 if (fv) {795 /* Determine field vector type */796 prof_type = ice_get_sw_prof_type(hw, fv, offset);797 798 if (req_profs & prof_type)799 set_bit((u16)offset, bm);800 }801 } while (fv);802}803 804/**805 * ice_get_sw_fv_list806 * @hw: pointer to the HW structure807 * @lkups: list of protocol types808 * @bm: bitmap of field vectors to consider809 * @fv_list: Head of a list810 *811 * Finds all the field vector entries from switch block that contain812 * a given protocol ID and offset and returns a list of structures of type813 * "ice_sw_fv_list_entry". Every structure in the list has a field vector814 * definition and profile ID information815 * NOTE: The caller of the function is responsible for freeing the memory816 * allocated for every list entry.817 */818int ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,819 unsigned long *bm, struct list_head *fv_list)820{821 struct ice_sw_fv_list_entry *fvl;822 struct ice_sw_fv_list_entry *tmp;823 struct ice_pkg_enum state;824 struct ice_seg *ice_seg;825 struct ice_fv *fv;826 u32 offset;827 828 memset(&state, 0, sizeof(state));829 830 if (!lkups->n_val_words || !hw->seg)831 return -EINVAL;832 833 ice_seg = hw->seg;834 do {835 u16 i;836 837 fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,838 &offset, ice_sw_fv_handler);839 if (!fv)840 break;841 ice_seg = NULL;842 843 /* If field vector is not in the bitmap list, then skip this844 * profile.845 */846 if (!test_bit((u16)offset, bm))847 continue;848 849 for (i = 0; i < lkups->n_val_words; i++) {850 int j;851 852 for (j = 0; j < hw->blk[ICE_BLK_SW].es.fvw; j++)853 if (fv->ew[j].prot_id ==854 lkups->fv_words[i].prot_id &&855 fv->ew[j].off == lkups->fv_words[i].off)856 break;857 if (j >= hw->blk[ICE_BLK_SW].es.fvw)858 break;859 if (i + 1 == lkups->n_val_words) {860 fvl = devm_kzalloc(ice_hw_to_dev(hw),861 sizeof(*fvl), GFP_KERNEL);862 if (!fvl)863 goto err;864 fvl->fv_ptr = fv;865 fvl->profile_id = offset;866 list_add(&fvl->list_entry, fv_list);867 break;868 }869 }870 } while (fv);871 if (list_empty(fv_list)) {872 dev_warn(ice_hw_to_dev(hw),873 "Required profiles not found in currently loaded DDP package");874 return -EIO;875 }876 877 return 0;878 879err:880 list_for_each_entry_safe(fvl, tmp, fv_list, list_entry) {881 list_del(&fvl->list_entry);882 devm_kfree(ice_hw_to_dev(hw), fvl);883 }884 885 return -ENOMEM;886}887 888/**889 * ice_init_prof_result_bm - Initialize the profile result index bitmap890 * @hw: pointer to hardware structure891 */892void ice_init_prof_result_bm(struct ice_hw *hw)893{894 struct ice_pkg_enum state;895 struct ice_seg *ice_seg;896 struct ice_fv *fv;897 898 memset(&state, 0, sizeof(state));899 900 if (!hw->seg)901 return;902 903 ice_seg = hw->seg;904 do {905 u32 off;906 u16 i;907 908 fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,909 &off, ice_sw_fv_handler);910 ice_seg = NULL;911 if (!fv)912 break;913 914 bitmap_zero(hw->switch_info->prof_res_bm[off],915 ICE_MAX_FV_WORDS);916 917 /* Determine empty field vector indices, these can be918 * used for recipe results. Skip index 0, since it is919 * always used for Switch ID.920 */921 for (i = 1; i < ICE_MAX_FV_WORDS; i++)922 if (fv->ew[i].prot_id == ICE_PROT_INVALID &&923 fv->ew[i].off == ICE_FV_OFFSET_INVAL)924 set_bit(i, hw->switch_info->prof_res_bm[off]);925 } while (fv);926}927 928/**929 * ice_pkg_buf_free930 * @hw: pointer to the HW structure931 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())932 *933 * Frees a package buffer934 */935void ice_pkg_buf_free(struct ice_hw *hw, struct ice_buf_build *bld)936{937 devm_kfree(ice_hw_to_dev(hw), bld);938}939 940/**941 * ice_pkg_buf_reserve_section942 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())943 * @count: the number of sections to reserve944 *945 * Reserves one or more section table entries in a package buffer. This routine946 * can be called multiple times as long as they are made before calling947 * ice_pkg_buf_alloc_section(). Once ice_pkg_buf_alloc_section()948 * is called once, the number of sections that can be allocated will not be able949 * to be increased; not using all reserved sections is fine, but this will950 * result in some wasted space in the buffer.951 * Note: all package contents must be in Little Endian form.952 */953int ice_pkg_buf_reserve_section(struct ice_buf_build *bld, u16 count)954{955 struct ice_buf_hdr *buf;956 u16 section_count;957 u16 data_end;958 959 if (!bld)960 return -EINVAL;961 962 buf = (struct ice_buf_hdr *)&bld->buf;963 964 /* already an active section, can't increase table size */965 section_count = le16_to_cpu(buf->section_count);966 if (section_count > 0)967 return -EIO;968 969 if (bld->reserved_section_table_entries + count > ICE_MAX_S_COUNT)970 return -EIO;971 bld->reserved_section_table_entries += count;972 973 data_end = le16_to_cpu(buf->data_end) +974 flex_array_size(buf, section_entry, count);975 buf->data_end = cpu_to_le16(data_end);976 977 return 0;978}979 980/**981 * ice_pkg_buf_alloc_section982 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())983 * @type: the section type value984 * @size: the size of the section to reserve (in bytes)985 *986 * Reserves memory in the buffer for a section's content and updates the987 * buffers' status accordingly. This routine returns a pointer to the first988 * byte of the section start within the buffer, which is used to fill in the989 * section contents.990 * Note: all package contents must be in Little Endian form.991 */992void *ice_pkg_buf_alloc_section(struct ice_buf_build *bld, u32 type, u16 size)993{994 struct ice_buf_hdr *buf;995 u16 sect_count;996 u16 data_end;997 998 if (!bld || !type || !size)999 return NULL;1000 1001 buf = (struct ice_buf_hdr *)&bld->buf;1002 1003 /* check for enough space left in buffer */1004 data_end = le16_to_cpu(buf->data_end);1005 1006 /* section start must align on 4 byte boundary */1007 data_end = ALIGN(data_end, 4);1008 1009 if ((data_end + size) > ICE_MAX_S_DATA_END)1010 return NULL;1011 1012 /* check for more available section table entries */1013 sect_count = le16_to_cpu(buf->section_count);1014 if (sect_count < bld->reserved_section_table_entries) {1015 void *section_ptr = ((u8 *)buf) + data_end;1016 1017 buf->section_entry[sect_count].offset = cpu_to_le16(data_end);1018 buf->section_entry[sect_count].size = cpu_to_le16(size);1019 buf->section_entry[sect_count].type = cpu_to_le32(type);1020 1021 data_end += size;1022 buf->data_end = cpu_to_le16(data_end);1023 1024 buf->section_count = cpu_to_le16(sect_count + 1);1025 return section_ptr;1026 }1027 1028 /* no free section table entries */1029 return NULL;1030}1031 1032/**1033 * ice_pkg_buf_alloc_single_section1034 * @hw: pointer to the HW structure1035 * @type: the section type value1036 * @size: the size of the section to reserve (in bytes)1037 * @section: returns pointer to the section1038 *1039 * Allocates a package buffer with a single section.1040 * Note: all package contents must be in Little Endian form.1041 */1042struct ice_buf_build *ice_pkg_buf_alloc_single_section(struct ice_hw *hw,1043 u32 type, u16 size,1044 void **section)1045{1046 struct ice_buf_build *buf;1047 1048 if (!section)1049 return NULL;1050 1051 buf = ice_pkg_buf_alloc(hw);1052 if (!buf)1053 return NULL;1054 1055 if (ice_pkg_buf_reserve_section(buf, 1))1056 goto ice_pkg_buf_alloc_single_section_err;1057 1058 *section = ice_pkg_buf_alloc_section(buf, type, size);1059 if (!*section)1060 goto ice_pkg_buf_alloc_single_section_err;1061 1062 return buf;1063 1064ice_pkg_buf_alloc_single_section_err:1065 ice_pkg_buf_free(hw, buf);1066 return NULL;1067}1068 1069/**1070 * ice_pkg_buf_get_active_sections1071 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())1072 *1073 * Returns the number of active sections. Before using the package buffer1074 * in an update package command, the caller should make sure that there is at1075 * least one active section - otherwise, the buffer is not legal and should1076 * not be used.1077 * Note: all package contents must be in Little Endian form.1078 */1079u16 ice_pkg_buf_get_active_sections(struct ice_buf_build *bld)1080{1081 struct ice_buf_hdr *buf;1082 1083 if (!bld)1084 return 0;1085 1086 buf = (struct ice_buf_hdr *)&bld->buf;1087 return le16_to_cpu(buf->section_count);1088}1089 1090/**1091 * ice_pkg_buf1092 * @bld: pointer to pkg build (allocated by ice_pkg_buf_alloc())1093 *1094 * Return a pointer to the buffer's header1095 */1096struct ice_buf *ice_pkg_buf(struct ice_buf_build *bld)1097{1098 if (!bld)1099 return NULL;1100 1101 return &bld->buf;1102}1103 1104static enum ice_ddp_state ice_map_aq_err_to_ddp_state(enum ice_aq_err aq_err)1105{1106 switch (aq_err) {1107 case ICE_AQ_RC_ENOSEC:1108 case ICE_AQ_RC_EBADSIG:1109 return ICE_DDP_PKG_FILE_SIGNATURE_INVALID;1110 case ICE_AQ_RC_ESVN:1111 return ICE_DDP_PKG_FILE_REVISION_TOO_LOW;1112 case ICE_AQ_RC_EBADMAN:1113 case ICE_AQ_RC_EBADBUF:1114 return ICE_DDP_PKG_LOAD_ERROR;1115 default:1116 return ICE_DDP_PKG_ERR;1117 }1118}1119 1120/**1121 * ice_acquire_global_cfg_lock1122 * @hw: pointer to the HW structure1123 * @access: access type (read or write)1124 *1125 * This function will request ownership of the global config lock for reading1126 * or writing of the package. When attempting to obtain write access, the1127 * caller must check for the following two return values:1128 *1129 * 0 - Means the caller has acquired the global config lock1130 * and can perform writing of the package.1131 * -EALREADY - Indicates another driver has already written the1132 * package or has found that no update was necessary; in1133 * this case, the caller can just skip performing any1134 * update of the package.1135 */1136static int ice_acquire_global_cfg_lock(struct ice_hw *hw,1137 enum ice_aq_res_access_type access)1138{1139 int status;1140 1141 status = ice_acquire_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID, access,1142 ICE_GLOBAL_CFG_LOCK_TIMEOUT);1143 1144 if (!status)1145 mutex_lock(&ice_global_cfg_lock_sw);1146 else if (status == -EALREADY)1147 ice_debug(hw, ICE_DBG_PKG,1148 "Global config lock: No work to do\n");1149 1150 return status;1151}1152 1153/**1154 * ice_release_global_cfg_lock1155 * @hw: pointer to the HW structure1156 *1157 * This function will release the global config lock.1158 */1159static void ice_release_global_cfg_lock(struct ice_hw *hw)1160{1161 mutex_unlock(&ice_global_cfg_lock_sw);1162 ice_release_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID);1163}1164 1165/**1166 * ice_aq_download_pkg1167 * @hw: pointer to the hardware structure1168 * @pkg_buf: the package buffer to transfer1169 * @buf_size: the size of the package buffer1170 * @last_buf: last buffer indicator1171 * @error_offset: returns error offset1172 * @error_info: returns error information1173 * @cd: pointer to command details structure or NULL1174 *1175 * Download Package (0x0C40)1176 */1177static int1178ice_aq_download_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,1179 u16 buf_size, bool last_buf, u32 *error_offset,1180 u32 *error_info, struct ice_sq_cd *cd)1181{1182 struct ice_aqc_download_pkg *cmd;1183 struct ice_aq_desc desc;1184 int status;1185 1186 if (error_offset)1187 *error_offset = 0;1188 if (error_info)1189 *error_info = 0;1190 1191 cmd = &desc.params.download_pkg;1192 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_download_pkg);1193 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);1194 1195 if (last_buf)1196 cmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF;1197 1198 status = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);1199 if (status == -EIO) {1200 /* Read error from buffer only when the FW returned an error */1201 struct ice_aqc_download_pkg_resp *resp;1202 1203 resp = (struct ice_aqc_download_pkg_resp *)pkg_buf;1204 if (error_offset)1205 *error_offset = le32_to_cpu(resp->error_offset);1206 if (error_info)1207 *error_info = le32_to_cpu(resp->error_info);1208 }1209 1210 return status;1211}1212 1213/**1214 * ice_get_pkg_seg_by_idx1215 * @pkg_hdr: pointer to the package header to be searched1216 * @idx: index of segment1217 */1218static struct ice_generic_seg_hdr *1219ice_get_pkg_seg_by_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx)1220{1221 if (idx < le32_to_cpu(pkg_hdr->seg_count))1222 return (struct ice_generic_seg_hdr *)1223 ((u8 *)pkg_hdr +1224 le32_to_cpu(pkg_hdr->seg_offset[idx]));1225 1226 return NULL;1227}1228 1229/**1230 * ice_is_signing_seg_at_idx - determine if segment is a signing segment1231 * @pkg_hdr: pointer to package header1232 * @idx: segment index1233 */1234static bool ice_is_signing_seg_at_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx)1235{1236 struct ice_generic_seg_hdr *seg;1237 1238 seg = ice_get_pkg_seg_by_idx(pkg_hdr, idx);1239 if (!seg)1240 return false;1241 1242 return le32_to_cpu(seg->seg_type) == SEGMENT_TYPE_SIGNING;1243}1244 1245/**1246 * ice_is_signing_seg_type_at_idx1247 * @pkg_hdr: pointer to package header1248 * @idx: segment index1249 * @seg_id: segment id that is expected1250 * @sign_type: signing type1251 *1252 * Determine if a segment is a signing segment of the correct type1253 */1254static bool1255ice_is_signing_seg_type_at_idx(struct ice_pkg_hdr *pkg_hdr, u32 idx,1256 u32 seg_id, u32 sign_type)1257{1258 struct ice_sign_seg *seg;1259 1260 if (!ice_is_signing_seg_at_idx(pkg_hdr, idx))1261 return false;1262 1263 seg = (struct ice_sign_seg *)ice_get_pkg_seg_by_idx(pkg_hdr, idx);1264 1265 if (seg && le32_to_cpu(seg->seg_id) == seg_id &&1266 le32_to_cpu(seg->sign_type) == sign_type)1267 return true;1268 1269 return false;1270}1271 1272/**1273 * ice_is_buffer_metadata - determine if package buffer is a metadata buffer1274 * @buf: pointer to buffer header1275 */1276static bool ice_is_buffer_metadata(struct ice_buf_hdr *buf)1277{1278 if (le32_to_cpu(buf->section_entry[0].type) & ICE_METADATA_BUF)1279 return true;1280 1281 return false;1282}1283 1284/**1285 * ice_is_last_download_buffer1286 * @buf: pointer to current buffer header1287 * @idx: index of the buffer in the current sequence1288 * @count: the buffer count in the current sequence1289 *1290 * Note: this routine should only be called if the buffer is not the last buffer1291 */1292static bool1293ice_is_last_download_buffer(struct ice_buf_hdr *buf, u32 idx, u32 count)1294{1295 struct ice_buf *next_buf;1296 1297 if ((idx + 1) == count)1298 return true;1299 1300 /* A set metadata flag in the next buffer will signal that the current1301 * buffer will be the last buffer downloaded1302 */1303 next_buf = ((struct ice_buf *)buf) + 1;1304 1305 return ice_is_buffer_metadata((struct ice_buf_hdr *)next_buf);1306}1307 1308/**1309 * ice_dwnld_cfg_bufs_no_lock1310 * @hw: pointer to the hardware structure1311 * @bufs: pointer to an array of buffers1312 * @start: buffer index of first buffer to download1313 * @count: the number of buffers to download1314 * @indicate_last: if true, then set last buffer flag on last buffer download1315 *1316 * Downloads package configuration buffers to the firmware. Metadata buffers1317 * are skipped, and the first metadata buffer found indicates that the rest1318 * of the buffers are all metadata buffers.1319 */1320static enum ice_ddp_state1321ice_dwnld_cfg_bufs_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 start,1322 u32 count, bool indicate_last)1323{1324 enum ice_ddp_state state = ICE_DDP_PKG_SUCCESS;1325 struct ice_buf_hdr *bh;1326 enum ice_aq_err err;1327 u32 offset, info, i;1328 1329 if (!bufs || !count)1330 return ICE_DDP_PKG_ERR;1331 1332 /* If the first buffer's first section has its metadata bit set1333 * then there are no buffers to be downloaded, and the operation is1334 * considered a success.1335 */1336 bh = (struct ice_buf_hdr *)(bufs + start);1337 if (le32_to_cpu(bh->section_entry[0].type) & ICE_METADATA_BUF)1338 return ICE_DDP_PKG_SUCCESS;1339 1340 for (i = 0; i < count; i++) {1341 bool last = false;1342 int try_cnt = 0;1343 int status;1344 1345 bh = (struct ice_buf_hdr *)(bufs + start + i);1346 1347 if (indicate_last)1348 last = ice_is_last_download_buffer(bh, i, count);1349 1350 while (1) {1351 status = ice_aq_download_pkg(hw, bh, ICE_PKG_BUF_SIZE,1352 last, &offset, &info,1353 NULL);1354 if (hw->adminq.sq_last_status != ICE_AQ_RC_ENOSEC &&1355 hw->adminq.sq_last_status != ICE_AQ_RC_EBADSIG)1356 break;1357 1358 try_cnt++;1359 1360 if (try_cnt == 5)1361 break;1362 1363 msleep(20);1364 }1365 1366 if (try_cnt)1367 dev_dbg(ice_hw_to_dev(hw),1368 "ice_aq_download_pkg number of retries: %d\n",1369 try_cnt);1370 1371 /* Save AQ status from download package */1372 if (status) {1373 ice_debug(hw, ICE_DBG_PKG, "Pkg download failed: err %d off %d inf %d\n",1374 status, offset, info);1375 err = hw->adminq.sq_last_status;1376 state = ice_map_aq_err_to_ddp_state(err);1377 break;1378 }1379 1380 if (last)1381 break;1382 }1383 1384 return state;1385}1386 1387/**1388 * ice_download_pkg_sig_seg - download a signature segment1389 * @hw: pointer to the hardware structure1390 * @seg: pointer to signature segment1391 */1392static enum ice_ddp_state1393ice_download_pkg_sig_seg(struct ice_hw *hw, struct ice_sign_seg *seg)1394{1395 return ice_dwnld_cfg_bufs_no_lock(hw, seg->buf_tbl.buf_array, 0,1396 le32_to_cpu(seg->buf_tbl.buf_count),1397 false);1398}1399 1400/**1401 * ice_download_pkg_config_seg - download a config segment1402 * @hw: pointer to the hardware structure1403 * @pkg_hdr: pointer to package header1404 * @idx: segment index1405 * @start: starting buffer1406 * @count: buffer count1407 *1408 * Note: idx must reference a ICE segment1409 */1410static enum ice_ddp_state1411ice_download_pkg_config_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,1412 u32 idx, u32 start, u32 count)1413{1414 struct ice_buf_table *bufs;1415 struct ice_seg *seg;1416 u32 buf_count;1417 1418 seg = (struct ice_seg *)ice_get_pkg_seg_by_idx(pkg_hdr, idx);1419 if (!seg)1420 return ICE_DDP_PKG_ERR;1421 1422 bufs = ice_find_buf_table(seg);1423 buf_count = le32_to_cpu(bufs->buf_count);1424 1425 if (start >= buf_count || start + count > buf_count)1426 return ICE_DDP_PKG_ERR;1427 1428 return ice_dwnld_cfg_bufs_no_lock(hw, bufs->buf_array, start, count,1429 true);1430}1431 1432/**1433 * ice_dwnld_sign_and_cfg_segs - download a signing segment and config segment1434 * @hw: pointer to the hardware structure1435 * @pkg_hdr: pointer to package header1436 * @idx: segment index (must be a signature segment)1437 *1438 * Note: idx must reference a signature segment1439 */1440static enum ice_ddp_state1441ice_dwnld_sign_and_cfg_segs(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,1442 u32 idx)1443{1444 enum ice_ddp_state state;1445 struct ice_sign_seg *seg;1446 u32 conf_idx;1447 u32 start;1448 u32 count;1449 1450 seg = (struct ice_sign_seg *)ice_get_pkg_seg_by_idx(pkg_hdr, idx);1451 if (!seg) {1452 state = ICE_DDP_PKG_ERR;1453 goto exit;1454 }1455 1456 count = le32_to_cpu(seg->signed_buf_count);1457 state = ice_download_pkg_sig_seg(hw, seg);1458 if (state || !count)1459 goto exit;1460 1461 conf_idx = le32_to_cpu(seg->signed_seg_idx);1462 start = le32_to_cpu(seg->signed_buf_start);1463 1464 state = ice_download_pkg_config_seg(hw, pkg_hdr, conf_idx, start,1465 count);1466 1467exit:1468 return state;1469}1470 1471/**1472 * ice_match_signing_seg - determine if a matching signing segment exists1473 * @pkg_hdr: pointer to package header1474 * @seg_id: segment id that is expected1475 * @sign_type: signing type1476 */1477static bool1478ice_match_signing_seg(struct ice_pkg_hdr *pkg_hdr, u32 seg_id, u32 sign_type)1479{1480 u32 i;1481 1482 for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) {1483 if (ice_is_signing_seg_type_at_idx(pkg_hdr, i, seg_id,1484 sign_type))1485 return true;1486 }1487 1488 return false;1489}1490 1491/**1492 * ice_post_dwnld_pkg_actions - perform post download package actions1493 * @hw: pointer to the hardware structure1494 */1495static enum ice_ddp_state1496ice_post_dwnld_pkg_actions(struct ice_hw *hw)1497{1498 int status;1499 1500 status = ice_set_vlan_mode(hw);1501 if (status) {1502 ice_debug(hw, ICE_DBG_PKG, "Failed to set VLAN mode: err %d\n",1503 status);1504 return ICE_DDP_PKG_ERR;1505 }1506 1507 return ICE_DDP_PKG_SUCCESS;1508}1509 1510/**1511 * ice_download_pkg_with_sig_seg1512 * @hw: pointer to the hardware structure1513 * @pkg_hdr: pointer to package header1514 *1515 * Handles the download of a complete package.1516 */1517static enum ice_ddp_state1518ice_download_pkg_with_sig_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)1519{1520 enum ice_aq_err aq_err = hw->adminq.sq_last_status;1521 enum ice_ddp_state state = ICE_DDP_PKG_ERR;1522 int status;1523 u32 i;1524 1525 ice_debug(hw, ICE_DBG_INIT, "Segment ID %d\n", hw->pkg_seg_id);1526 ice_debug(hw, ICE_DBG_INIT, "Signature type %d\n", hw->pkg_sign_type);1527 1528 status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);1529 if (status) {1530 if (status == -EALREADY)1531 state = ICE_DDP_PKG_ALREADY_LOADED;1532 else1533 state = ice_map_aq_err_to_ddp_state(aq_err);1534 return state;1535 }1536 1537 for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) {1538 if (!ice_is_signing_seg_type_at_idx(pkg_hdr, i, hw->pkg_seg_id,1539 hw->pkg_sign_type))1540 continue;1541 1542 state = ice_dwnld_sign_and_cfg_segs(hw, pkg_hdr, i);1543 if (state)1544 break;1545 }1546 1547 if (!state)1548 state = ice_post_dwnld_pkg_actions(hw);1549 1550 ice_release_global_cfg_lock(hw);1551 1552 return state;1553}1554 1555/**1556 * ice_dwnld_cfg_bufs1557 * @hw: pointer to the hardware structure1558 * @bufs: pointer to an array of buffers1559 * @count: the number of buffers in the array1560 *1561 * Obtains global config lock and downloads the package configuration buffers1562 * to the firmware.1563 */1564static enum ice_ddp_state1565ice_dwnld_cfg_bufs(struct ice_hw *hw, struct ice_buf *bufs, u32 count)1566{1567 enum ice_ddp_state state;1568 struct ice_buf_hdr *bh;1569 int status;1570 1571 if (!bufs || !count)1572 return ICE_DDP_PKG_ERR;1573 1574 /* If the first buffer's first section has its metadata bit set1575 * then there are no buffers to be downloaded, and the operation is1576 * considered a success.1577 */1578 bh = (struct ice_buf_hdr *)bufs;1579 if (le32_to_cpu(bh->section_entry[0].type) & ICE_METADATA_BUF)1580 return ICE_DDP_PKG_SUCCESS;1581 1582 status = ice_acquire_global_cfg_lock(hw, ICE_RES_WRITE);1583 if (status) {1584 if (status == -EALREADY)1585 return ICE_DDP_PKG_ALREADY_LOADED;1586 return ice_map_aq_err_to_ddp_state(hw->adminq.sq_last_status);1587 }1588 1589 state = ice_dwnld_cfg_bufs_no_lock(hw, bufs, 0, count, true);1590 if (!state)1591 state = ice_post_dwnld_pkg_actions(hw);1592 1593 ice_release_global_cfg_lock(hw);1594 1595 return state;1596}1597 1598/**1599 * ice_download_pkg_without_sig_seg1600 * @hw: pointer to the hardware structure1601 * @ice_seg: pointer to the segment of the package to be downloaded1602 *1603 * Handles the download of a complete package without signature segment.1604 */1605static enum ice_ddp_state1606ice_download_pkg_without_sig_seg(struct ice_hw *hw, struct ice_seg *ice_seg)1607{1608 struct ice_buf_table *ice_buf_tbl;1609 1610 ice_debug(hw, ICE_DBG_PKG, "Segment format version: %d.%d.%d.%d\n",1611 ice_seg->hdr.seg_format_ver.major,1612 ice_seg->hdr.seg_format_ver.minor,1613 ice_seg->hdr.seg_format_ver.update,1614 ice_seg->hdr.seg_format_ver.draft);1615 1616 ice_debug(hw, ICE_DBG_PKG, "Seg: type 0x%X, size %d, name %s\n",1617 le32_to_cpu(ice_seg->hdr.seg_type),1618 le32_to_cpu(ice_seg->hdr.seg_size), ice_seg->hdr.seg_id);1619 1620 ice_buf_tbl = ice_find_buf_table(ice_seg);1621 1622 ice_debug(hw, ICE_DBG_PKG, "Seg buf count: %d\n",1623 le32_to_cpu(ice_buf_tbl->buf_count));1624 1625 return ice_dwnld_cfg_bufs(hw, ice_buf_tbl->buf_array,1626 le32_to_cpu(ice_buf_tbl->buf_count));1627}1628 1629/**1630 * ice_download_pkg1631 * @hw: pointer to the hardware structure1632 * @pkg_hdr: pointer to package header1633 * @ice_seg: pointer to the segment of the package to be downloaded1634 *1635 * Handles the download of a complete package.1636 */1637static enum ice_ddp_state1638ice_download_pkg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr,1639 struct ice_seg *ice_seg)1640{1641 enum ice_ddp_state state;1642 1643 if (hw->pkg_has_signing_seg)1644 state = ice_download_pkg_with_sig_seg(hw, pkg_hdr);1645 else1646 state = ice_download_pkg_without_sig_seg(hw, ice_seg);1647 1648 ice_post_pkg_dwnld_vlan_mode_cfg(hw);1649 1650 return state;1651}1652 1653/**1654 * ice_aq_get_pkg_info_list1655 * @hw: pointer to the hardware structure1656 * @pkg_info: the buffer which will receive the information list1657 * @buf_size: the size of the pkg_info information buffer1658 * @cd: pointer to command details structure or NULL1659 *1660 * Get Package Info List (0x0C43)1661 */1662static int ice_aq_get_pkg_info_list(struct ice_hw *hw,1663 struct ice_aqc_get_pkg_info_resp *pkg_info,1664 u16 buf_size, struct ice_sq_cd *cd)1665{1666 struct ice_aq_desc desc;1667 1668 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_pkg_info_list);1669 1670 return ice_aq_send_cmd(hw, &desc, pkg_info, buf_size, cd);1671}1672 1673/**1674 * ice_aq_update_pkg1675 * @hw: pointer to the hardware structure1676 * @pkg_buf: the package cmd buffer1677 * @buf_size: the size of the package cmd buffer1678 * @last_buf: last buffer indicator1679 * @error_offset: returns error offset1680 * @error_info: returns error information1681 * @cd: pointer to command details structure or NULL1682 *1683 * Update Package (0x0C42)1684 */1685static int ice_aq_update_pkg(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,1686 u16 buf_size, bool last_buf, u32 *error_offset,1687 u32 *error_info, struct ice_sq_cd *cd)1688{1689 struct ice_aqc_download_pkg *cmd;1690 struct ice_aq_desc desc;1691 int status;1692 1693 if (error_offset)1694 *error_offset = 0;1695 if (error_info)1696 *error_info = 0;1697 1698 cmd = &desc.params.download_pkg;1699 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_update_pkg);1700 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);1701 1702 if (last_buf)1703 cmd->flags |= ICE_AQC_DOWNLOAD_PKG_LAST_BUF;1704 1705 status = ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);1706 if (status == -EIO) {1707 /* Read error from buffer only when the FW returned an error */1708 struct ice_aqc_download_pkg_resp *resp;1709 1710 resp = (struct ice_aqc_download_pkg_resp *)pkg_buf;1711 if (error_offset)1712 *error_offset = le32_to_cpu(resp->error_offset);1713 if (error_info)1714 *error_info = le32_to_cpu(resp->error_info);1715 }1716 1717 return status;1718}1719 1720/**1721 * ice_aq_upload_section1722 * @hw: pointer to the hardware structure1723 * @pkg_buf: the package buffer which will receive the section1724 * @buf_size: the size of the package buffer1725 * @cd: pointer to command details structure or NULL1726 *1727 * Upload Section (0x0C41)1728 */1729int ice_aq_upload_section(struct ice_hw *hw, struct ice_buf_hdr *pkg_buf,1730 u16 buf_size, struct ice_sq_cd *cd)1731{1732 struct ice_aq_desc desc;1733 1734 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_upload_section);1735 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);1736 1737 return ice_aq_send_cmd(hw, &desc, pkg_buf, buf_size, cd);1738}1739 1740/**1741 * ice_update_pkg_no_lock1742 * @hw: pointer to the hardware structure1743 * @bufs: pointer to an array of buffers1744 * @count: the number of buffers in the array1745 */1746int ice_update_pkg_no_lock(struct ice_hw *hw, struct ice_buf *bufs, u32 count)1747{1748 int status = 0;1749 u32 i;1750 1751 for (i = 0; i < count; i++) {1752 struct ice_buf_hdr *bh = (struct ice_buf_hdr *)(bufs + i);1753 bool last = ((i + 1) == count);1754 u32 offset, info;1755 1756 status = ice_aq_update_pkg(hw, bh, le16_to_cpu(bh->data_end),1757 last, &offset, &info, NULL);1758 1759 if (status) {1760 ice_debug(hw, ICE_DBG_PKG,1761 "Update pkg failed: err %d off %d inf %d\n",1762 status, offset, info);1763 break;1764 }1765 }1766 1767 return status;1768}1769 1770/**1771 * ice_update_pkg1772 * @hw: pointer to the hardware structure1773 * @bufs: pointer to an array of buffers1774 * @count: the number of buffers in the array1775 *1776 * Obtains change lock and updates package.1777 */1778int ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count)1779{1780 int status;1781 1782 status = ice_acquire_change_lock(hw, ICE_RES_WRITE);1783 if (status)1784 return status;1785 1786 status = ice_update_pkg_no_lock(hw, bufs, count);1787 1788 ice_release_change_lock(hw);1789 1790 return status;1791}1792 1793/**1794 * ice_find_seg_in_pkg1795 * @hw: pointer to the hardware structure1796 * @seg_type: the segment type to search for (i.e., SEGMENT_TYPE_CPK)1797 * @pkg_hdr: pointer to the package header to be searched1798 *1799 * This function searches a package file for a particular segment type. On1800 * success it returns a pointer to the segment header, otherwise it will1801 * return NULL.1802 */1803static const struct ice_generic_seg_hdr *1804ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type,1805 const struct ice_pkg_hdr *pkg_hdr)1806{1807 u32 i;1808 1809 ice_debug(hw, ICE_DBG_PKG, "Package format version: %d.%d.%d.%d\n",1810 pkg_hdr->pkg_format_ver.major, pkg_hdr->pkg_format_ver.minor,1811 pkg_hdr->pkg_format_ver.update,1812 pkg_hdr->pkg_format_ver.draft);1813 1814 /* Search all package segments for the requested segment type */1815 for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) {1816 const struct ice_generic_seg_hdr *seg;1817 1818 seg = (void *)pkg_hdr + le32_to_cpu(pkg_hdr->seg_offset[i]);1819 1820 if (le32_to_cpu(seg->seg_type) == seg_type)1821 return seg;1822 }1823 1824 return NULL;1825}1826 1827/**1828 * ice_has_signing_seg - determine if package has a signing segment1829 * @hw: pointer to the hardware structure1830 * @pkg_hdr: pointer to the driver's package hdr1831 */1832static bool ice_has_signing_seg(struct ice_hw *hw, struct ice_pkg_hdr *pkg_hdr)1833{1834 struct ice_generic_seg_hdr *seg_hdr;1835 1836 seg_hdr = (struct ice_generic_seg_hdr *)1837 ice_find_seg_in_pkg(hw, SEGMENT_TYPE_SIGNING, pkg_hdr);1838 1839 return seg_hdr ? true : false;1840}1841 1842/**1843 * ice_get_pkg_segment_id - get correct package segment id, based on device1844 * @mac_type: MAC type of the device1845 */1846static u32 ice_get_pkg_segment_id(enum ice_mac_type mac_type)1847{1848 u32 seg_id;1849 1850 switch (mac_type) {1851 case ICE_MAC_E830:1852 seg_id = SEGMENT_TYPE_ICE_E830;1853 break;1854 case ICE_MAC_GENERIC:1855 case ICE_MAC_GENERIC_3K_E825:1856 default:1857 seg_id = SEGMENT_TYPE_ICE_E810;1858 break;1859 }1860 1861 return seg_id;1862}1863 1864/**1865 * ice_get_pkg_sign_type - get package segment sign type, based on device1866 * @mac_type: MAC type of the device1867 */1868static u32 ice_get_pkg_sign_type(enum ice_mac_type mac_type)1869{1870 u32 sign_type;1871 1872 switch (mac_type) {1873 case ICE_MAC_E830:1874 sign_type = SEGMENT_SIGN_TYPE_RSA3K_SBB;1875 break;1876 case ICE_MAC_GENERIC_3K_E825:1877 sign_type = SEGMENT_SIGN_TYPE_RSA3K_E825;1878 break;1879 case ICE_MAC_GENERIC:1880 default:1881 sign_type = SEGMENT_SIGN_TYPE_RSA2K;1882 break;1883 }1884 1885 return sign_type;1886}1887 1888/**1889 * ice_get_signing_req - get correct package requirements, based on device1890 * @hw: pointer to the hardware structure1891 */1892static void ice_get_signing_req(struct ice_hw *hw)1893{1894 hw->pkg_seg_id = ice_get_pkg_segment_id(hw->mac_type);1895 hw->pkg_sign_type = ice_get_pkg_sign_type(hw->mac_type);1896}1897 1898/**1899 * ice_init_pkg_info1900 * @hw: pointer to the hardware structure1901 * @pkg_hdr: pointer to the driver's package hdr1902 *1903 * Saves off the package details into the HW structure.1904 */1905static enum ice_ddp_state ice_init_pkg_info(struct ice_hw *hw,1906 struct ice_pkg_hdr *pkg_hdr)1907{1908 struct ice_generic_seg_hdr *seg_hdr;1909 1910 if (!pkg_hdr)1911 return ICE_DDP_PKG_ERR;1912 1913 hw->pkg_has_signing_seg = ice_has_signing_seg(hw, pkg_hdr);1914 ice_get_signing_req(hw);1915 1916 ice_debug(hw, ICE_DBG_INIT, "Pkg using segment id: 0x%08X\n",1917 hw->pkg_seg_id);1918 1919 seg_hdr = (struct ice_generic_seg_hdr *)1920 ice_find_seg_in_pkg(hw, hw->pkg_seg_id, pkg_hdr);1921 if (seg_hdr) {1922 struct ice_meta_sect *meta;1923 struct ice_pkg_enum state;1924 1925 memset(&state, 0, sizeof(state));1926 1927 /* Get package information from the Metadata Section */1928 meta = ice_pkg_enum_section((struct ice_seg *)seg_hdr, &state,1929 ICE_SID_METADATA);1930 if (!meta) {1931 ice_debug(hw, ICE_DBG_INIT,1932 "Did not find ice metadata section in package\n");1933 return ICE_DDP_PKG_INVALID_FILE;1934 }1935 1936 hw->pkg_ver = meta->ver;1937 memcpy(hw->pkg_name, meta->name, sizeof(meta->name));1938 1939 ice_debug(hw, ICE_DBG_PKG, "Pkg: %d.%d.%d.%d, %s\n",1940 meta->ver.major, meta->ver.minor, meta->ver.update,1941 meta->ver.draft, meta->name);1942 1943 hw->ice_seg_fmt_ver = seg_hdr->seg_format_ver;1944 memcpy(hw->ice_seg_id, seg_hdr->seg_id, sizeof(hw->ice_seg_id));1945 1946 ice_debug(hw, ICE_DBG_PKG, "Ice Seg: %d.%d.%d.%d, %s\n",1947 seg_hdr->seg_format_ver.major,1948 seg_hdr->seg_format_ver.minor,1949 seg_hdr->seg_format_ver.update,1950 seg_hdr->seg_format_ver.draft, seg_hdr->seg_id);1951 } else {1952 ice_debug(hw, ICE_DBG_INIT,1953 "Did not find ice segment in driver package\n");1954 return ICE_DDP_PKG_INVALID_FILE;1955 }1956 1957 return ICE_DDP_PKG_SUCCESS;1958}1959 1960/**1961 * ice_get_pkg_info1962 * @hw: pointer to the hardware structure1963 *1964 * Store details of the package currently loaded in HW into the HW structure.1965 */1966static enum ice_ddp_state ice_get_pkg_info(struct ice_hw *hw)1967{1968 DEFINE_RAW_FLEX(struct ice_aqc_get_pkg_info_resp, pkg_info, pkg_info,1969 ICE_PKG_CNT);1970 u16 size = __struct_size(pkg_info);1971 u32 i;1972 1973 if (ice_aq_get_pkg_info_list(hw, pkg_info, size, NULL))1974 return ICE_DDP_PKG_ERR;1975 1976 for (i = 0; i < le32_to_cpu(pkg_info->count); i++) {1977#define ICE_PKG_FLAG_COUNT 41978 char flags[ICE_PKG_FLAG_COUNT + 1] = { 0 };1979 u8 place = 0;1980 1981 if (pkg_info->pkg_info[i].is_active) {1982 flags[place++] = 'A';1983 hw->active_pkg_ver = pkg_info->pkg_info[i].ver;1984 hw->active_track_id =1985 le32_to_cpu(pkg_info->pkg_info[i].track_id);1986 memcpy(hw->active_pkg_name, pkg_info->pkg_info[i].name,1987 sizeof(pkg_info->pkg_info[i].name));1988 hw->active_pkg_in_nvm = pkg_info->pkg_info[i].is_in_nvm;1989 }1990 if (pkg_info->pkg_info[i].is_active_at_boot)1991 flags[place++] = 'B';1992 if (pkg_info->pkg_info[i].is_modified)1993 flags[place++] = 'M';1994 if (pkg_info->pkg_info[i].is_in_nvm)1995 flags[place++] = 'N';1996 1997 ice_debug(hw, ICE_DBG_PKG, "Pkg[%d]: %d.%d.%d.%d,%s,%s\n", i,1998 pkg_info->pkg_info[i].ver.major,1999 pkg_info->pkg_info[i].ver.minor,2000 pkg_info->pkg_info[i].ver.update,2001 pkg_info->pkg_info[i].ver.draft,2002 pkg_info->pkg_info[i].name, flags);2003 }2004 2005 return ICE_DDP_PKG_SUCCESS;2006}2007 2008/**2009 * ice_chk_pkg_compat2010 * @hw: pointer to the hardware structure2011 * @ospkg: pointer to the package hdr2012 * @seg: pointer to the package segment hdr2013 *2014 * This function checks the package version compatibility with driver and NVM2015 */2016static enum ice_ddp_state ice_chk_pkg_compat(struct ice_hw *hw,2017 struct ice_pkg_hdr *ospkg,2018 struct ice_seg **seg)2019{2020 DEFINE_RAW_FLEX(struct ice_aqc_get_pkg_info_resp, pkg, pkg_info,2021 ICE_PKG_CNT);2022 u16 size = __struct_size(pkg);2023 enum ice_ddp_state state;2024 u32 i;2025 2026 /* Check package version compatibility */2027 state = ice_chk_pkg_version(&hw->pkg_ver);2028 if (state) {2029 ice_debug(hw, ICE_DBG_INIT, "Package version check failed.\n");2030 return state;2031 }2032 2033 /* find ICE segment in given package */2034 *seg = (struct ice_seg *)ice_find_seg_in_pkg(hw, hw->pkg_seg_id,2035 ospkg);2036 if (!*seg) {2037 ice_debug(hw, ICE_DBG_INIT, "no ice segment in package.\n");2038 return ICE_DDP_PKG_INVALID_FILE;2039 }2040 2041 /* Check if FW is compatible with the OS package */2042 if (ice_aq_get_pkg_info_list(hw, pkg, size, NULL))2043 return ICE_DDP_PKG_LOAD_ERROR;2044 2045 for (i = 0; i < le32_to_cpu(pkg->count); i++) {2046 /* loop till we find the NVM package */2047 if (!pkg->pkg_info[i].is_in_nvm)2048 continue;2049 if ((*seg)->hdr.seg_format_ver.major !=2050 pkg->pkg_info[i].ver.major ||2051 (*seg)->hdr.seg_format_ver.minor >2052 pkg->pkg_info[i].ver.minor) {2053 state = ICE_DDP_PKG_FW_MISMATCH;2054 ice_debug(hw, ICE_DBG_INIT,2055 "OS package is not compatible with NVM.\n");2056 }2057 /* done processing NVM package so break */2058 break;2059 }2060 2061 return state;2062}2063 2064/**2065 * ice_init_pkg_hints2066 * @hw: pointer to the HW structure2067 * @ice_seg: pointer to the segment of the package scan (non-NULL)2068 *2069 * This function will scan the package and save off relevant information2070 * (hints or metadata) for driver use. The ice_seg parameter must not be NULL2071 * since the first call to ice_enum_labels requires a pointer to an actual2072 * ice_seg structure.2073 */2074static void ice_init_pkg_hints(struct ice_hw *hw, struct ice_seg *ice_seg)2075{2076 struct ice_pkg_enum state;2077 char *label_name;2078 u16 val;2079 int i;2080 2081 memset(&hw->tnl, 0, sizeof(hw->tnl));2082 memset(&state, 0, sizeof(state));2083 2084 if (!ice_seg)2085 return;2086 2087 label_name = ice_enum_labels(ice_seg, ICE_SID_LBL_RXPARSER_TMEM, &state,2088 &val);2089 2090 while (label_name) {2091 if (!strncmp(label_name, ICE_TNL_PRE, strlen(ICE_TNL_PRE)))2092 /* check for a tunnel entry */2093 ice_add_tunnel_hint(hw, label_name, val);2094 2095 /* check for a dvm mode entry */2096 else if (!strncmp(label_name, ICE_DVM_PRE, strlen(ICE_DVM_PRE)))2097 ice_add_dvm_hint(hw, val, true);2098 2099 /* check for a svm mode entry */2100 else if (!strncmp(label_name, ICE_SVM_PRE, strlen(ICE_SVM_PRE)))2101 ice_add_dvm_hint(hw, val, false);2102 2103 label_name = ice_enum_labels(NULL, 0, &state, &val);2104 }2105 2106 /* Cache the appropriate boost TCAM entry pointers for tunnels */2107 for (i = 0; i < hw->tnl.count; i++) {2108 ice_find_boost_entry(ice_seg, hw->tnl.tbl[i].boost_addr,2109 &hw->tnl.tbl[i].boost_entry);2110 if (hw->tnl.tbl[i].boost_entry) {2111 hw->tnl.tbl[i].valid = true;2112 if (hw->tnl.tbl[i].type < __TNL_TYPE_CNT)2113 hw->tnl.valid_count[hw->tnl.tbl[i].type]++;2114 }2115 }2116 2117 /* Cache the appropriate boost TCAM entry pointers for DVM and SVM */2118 for (i = 0; i < hw->dvm_upd.count; i++)2119 ice_find_boost_entry(ice_seg, hw->dvm_upd.tbl[i].boost_addr,2120 &hw->dvm_upd.tbl[i].boost_entry);2121}2122 2123/**2124 * ice_fill_hw_ptype - fill the enabled PTYPE bit information2125 * @hw: pointer to the HW structure2126 */2127static void ice_fill_hw_ptype(struct ice_hw *hw)2128{2129 struct ice_marker_ptype_tcam_entry *tcam;2130 struct ice_seg *seg = hw->seg;2131 struct ice_pkg_enum state;2132 2133 bitmap_zero(hw->hw_ptype, ICE_FLOW_PTYPE_MAX);2134 if (!seg)2135 return;2136 2137 memset(&state, 0, sizeof(state));2138 2139 do {2140 tcam = ice_pkg_enum_entry(seg, &state,2141 ICE_SID_RXPARSER_MARKER_PTYPE, NULL,2142 ice_marker_ptype_tcam_handler);2143 if (tcam &&2144 le16_to_cpu(tcam->addr) < ICE_MARKER_PTYPE_TCAM_ADDR_MAX &&2145 le16_to_cpu(tcam->ptype) < ICE_FLOW_PTYPE_MAX)2146 set_bit(le16_to_cpu(tcam->ptype), hw->hw_ptype);2147 2148 seg = NULL;2149 } while (tcam);2150}2151 2152/**2153 * ice_init_pkg - initialize/download package2154 * @hw: pointer to the hardware structure2155 * @buf: pointer to the package buffer2156 * @len: size of the package buffer2157 *2158 * This function initializes a package. The package contains HW tables2159 * required to do packet processing. First, the function extracts package2160 * information such as version. Then it finds the ice configuration segment2161 * within the package; this function then saves a copy of the segment pointer2162 * within the supplied package buffer. Next, the function will cache any hints2163 * from the package, followed by downloading the package itself. Note, that if2164 * a previous PF driver has already downloaded the package successfully, then2165 * the current driver will not have to download the package again.2166 *2167 * The local package contents will be used to query default behavior and to2168 * update specific sections of the HW's version of the package (e.g. to update2169 * the parse graph to understand new protocols).2170 *2171 * This function stores a pointer to the package buffer memory, and it is2172 * expected that the supplied buffer will not be freed immediately. If the2173 * package buffer needs to be freed, such as when read from a file, use2174 * ice_copy_and_init_pkg() instead of directly calling ice_init_pkg() in this2175 * case.2176 */2177enum ice_ddp_state ice_init_pkg(struct ice_hw *hw, u8 *buf, u32 len)2178{2179 bool already_loaded = false;2180 enum ice_ddp_state state;2181 struct ice_pkg_hdr *pkg;2182 struct ice_seg *seg;2183 2184 if (!buf || !len)2185 return ICE_DDP_PKG_ERR;2186 2187 pkg = (struct ice_pkg_hdr *)buf;2188 state = ice_verify_pkg(pkg, len);2189 if (state) {2190 ice_debug(hw, ICE_DBG_INIT, "failed to verify pkg (err: %d)\n",2191 state);2192 return state;2193 }2194 2195 /* initialize package info */2196 state = ice_init_pkg_info(hw, pkg);2197 if (state)2198 return state;2199 2200 /* must be a matching segment */2201 if (hw->pkg_has_signing_seg &&2202 !ice_match_signing_seg(pkg, hw->pkg_seg_id, hw->pkg_sign_type))2203 return ICE_DDP_PKG_ERR;2204 2205 /* before downloading the package, check package version for2206 * compatibility with driver2207 */2208 state = ice_chk_pkg_compat(hw, pkg, &seg);2209 if (state)2210 return state;2211 2212 /* initialize package hints and then download package */2213 ice_init_pkg_hints(hw, seg);2214 state = ice_download_pkg(hw, pkg, seg);2215 if (state == ICE_DDP_PKG_ALREADY_LOADED) {2216 ice_debug(hw, ICE_DBG_INIT,2217 "package previously loaded - no work.\n");2218 already_loaded = true;2219 }2220 2221 /* Get information on the package currently loaded in HW, then make sure2222 * the driver is compatible with this version.2223 */2224 if (!state || state == ICE_DDP_PKG_ALREADY_LOADED) {2225 state = ice_get_pkg_info(hw);2226 if (!state)2227 state = ice_get_ddp_pkg_state(hw, already_loaded);2228 }2229 2230 if (ice_is_init_pkg_successful(state)) {2231 hw->seg = seg;2232 /* on successful package download update other required2233 * registers to support the package and fill HW tables2234 * with package content.2235 */2236 ice_init_pkg_regs(hw);2237 ice_fill_blk_tbls(hw);2238 ice_fill_hw_ptype(hw);2239 ice_get_prof_index_max(hw);2240 } else {2241 ice_debug(hw, ICE_DBG_INIT, "package load failed, %d\n", state);2242 }2243 2244 return state;2245}2246 2247/**2248 * ice_copy_and_init_pkg - initialize/download a copy of the package2249 * @hw: pointer to the hardware structure2250 * @buf: pointer to the package buffer2251 * @len: size of the package buffer2252 *2253 * This function copies the package buffer, and then calls ice_init_pkg() to2254 * initialize the copied package contents.2255 *2256 * The copying is necessary if the package buffer supplied is constant, or if2257 * the memory may disappear shortly after calling this function.2258 *2259 * If the package buffer resides in the data segment and can be modified, the2260 * caller is free to use ice_init_pkg() instead of ice_copy_and_init_pkg().2261 *2262 * However, if the package buffer needs to be copied first, such as when being2263 * read from a file, the caller should use ice_copy_and_init_pkg().2264 *2265 * This function will first copy the package buffer, before calling2266 * ice_init_pkg(). The caller is free to immediately destroy the original2267 * package buffer, as the new copy will be managed by this function and2268 * related routines.2269 */2270enum ice_ddp_state ice_copy_and_init_pkg(struct ice_hw *hw, const u8 *buf,2271 u32 len)2272{2273 enum ice_ddp_state state;2274 u8 *buf_copy;2275 2276 if (!buf || !len)2277 return ICE_DDP_PKG_ERR;2278 2279 buf_copy = devm_kmemdup(ice_hw_to_dev(hw), buf, len, GFP_KERNEL);2280 2281 state = ice_init_pkg(hw, buf_copy, len);2282 if (!ice_is_init_pkg_successful(state)) {2283 /* Free the copy, since we failed to initialize the package */2284 devm_kfree(ice_hw_to_dev(hw), buf_copy);2285 } else {2286 /* Track the copied pkg so we can free it later */2287 hw->pkg_copy = buf_copy;2288 hw->pkg_size = len;2289 }2290 2291 return state;2292}2293 2294/**2295 * ice_get_set_tx_topo - get or set Tx topology2296 * @hw: pointer to the HW struct2297 * @buf: pointer to Tx topology buffer2298 * @buf_size: buffer size2299 * @cd: pointer to command details structure or NULL2300 * @flags: pointer to descriptor flags2301 * @set: 0-get, 1-set topology2302 *2303 * The function will get or set Tx topology2304 *2305 * Return: zero when set was successful, negative values otherwise.2306 */2307static int2308ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size,2309 struct ice_sq_cd *cd, u8 *flags, bool set)2310{2311 struct ice_aqc_get_set_tx_topo *cmd;2312 struct ice_aq_desc desc;2313 int status;2314 2315 cmd = &desc.params.get_set_tx_topo;2316 if (set) {2317 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_set_tx_topo);2318 cmd->set_flags = ICE_AQC_TX_TOPO_FLAGS_ISSUED;2319 /* requested to update a new topology, not a default topology */2320 if (buf)2321 cmd->set_flags |= ICE_AQC_TX_TOPO_FLAGS_SRC_RAM |2322 ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW;2323 2324 if (ice_is_e825c(hw))2325 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);2326 } else {2327 ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_get_tx_topo);2328 cmd->get_flags = ICE_AQC_TX_TOPO_GET_RAM;2329 }2330 2331 if (!ice_is_e825c(hw))2332 desc.flags |= cpu_to_le16(ICE_AQ_FLAG_RD);2333 2334 status = ice_aq_send_cmd(hw, &desc, buf, buf_size, cd);2335 if (status)2336 return status;2337 /* read the return flag values (first byte) for get operation */2338 if (!set && flags)2339 *flags = desc.params.get_set_tx_topo.set_flags;2340 2341 return 0;2342}2343 2344/**2345 * ice_cfg_tx_topo - Initialize new Tx topology if available2346 * @hw: pointer to the HW struct2347 * @buf: pointer to Tx topology buffer2348 * @len: buffer size2349 *2350 * The function will apply the new Tx topology from the package buffer2351 * if available.2352 *2353 * Return: zero when update was successful, negative values otherwise.2354 */2355int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len)2356{2357 u8 *new_topo = NULL, *topo __free(kfree) = NULL;2358 const struct ice_run_time_cfg_seg *seg;2359 const struct ice_buf_hdr *section;2360 const struct ice_pkg_hdr *pkg_hdr;2361 enum ice_ddp_state state;2362 u16 offset, size = 0;2363 u32 reg = 0;2364 int status;2365 u8 flags;2366 2367 if (!buf || !len)2368 return -EINVAL;2369 2370 /* Does FW support new Tx topology mode ? */2371 if (!hw->func_caps.common_cap.tx_sched_topo_comp_mode_en) {2372 ice_debug(hw, ICE_DBG_INIT, "FW doesn't support compatibility mode\n");2373 return -EOPNOTSUPP;2374 }2375 2376 topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL);2377 if (!topo)2378 return -ENOMEM;2379 2380 /* Get the current Tx topology flags */2381 status = ice_get_set_tx_topo(hw, topo, ICE_AQ_MAX_BUF_LEN, NULL, &flags,2382 false);2383 2384 if (status) {2385 ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n");2386 return status;2387 }2388 2389 /* Is default topology already applied ? */2390 if (!(flags & ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW) &&2391 hw->num_tx_sched_layers == ICE_SCHED_9_LAYERS) {2392 ice_debug(hw, ICE_DBG_INIT, "Default topology already applied\n");2393 return -EEXIST;2394 }2395 2396 /* Is new topology already applied ? */2397 if ((flags & ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW) &&2398 hw->num_tx_sched_layers == ICE_SCHED_5_LAYERS) {2399 ice_debug(hw, ICE_DBG_INIT, "New topology already applied\n");2400 return -EEXIST;2401 }2402 2403 /* Setting topology already issued? */2404 if (flags & ICE_AQC_TX_TOPO_FLAGS_ISSUED) {2405 ice_debug(hw, ICE_DBG_INIT, "Update Tx topology was done by another PF\n");2406 /* Add a small delay before exiting */2407 msleep(2000);2408 return -EEXIST;2409 }2410 2411 /* Change the topology from new to default (5 to 9) */2412 if (!(flags & ICE_AQC_TX_TOPO_FLAGS_LOAD_NEW) &&2413 hw->num_tx_sched_layers == ICE_SCHED_5_LAYERS) {2414 ice_debug(hw, ICE_DBG_INIT, "Change topology from 5 to 9 layers\n");2415 goto update_topo;2416 }2417 2418 pkg_hdr = (const struct ice_pkg_hdr *)buf;2419 state = ice_verify_pkg(pkg_hdr, len);2420 if (state) {2421 ice_debug(hw, ICE_DBG_INIT, "Failed to verify pkg (err: %d)\n",2422 state);2423 return -EIO;2424 }2425 2426 /* Find runtime configuration segment */2427 seg = (const struct ice_run_time_cfg_seg *)2428 ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr);2429 if (!seg) {2430 ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment is missing\n");2431 return -EIO;2432 }2433 2434 if (le32_to_cpu(seg->buf_table.buf_count) < ICE_MIN_S_COUNT) {2435 ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment count(%d) is wrong\n",2436 seg->buf_table.buf_count);2437 return -EIO;2438 }2439 2440 section = ice_pkg_val_buf(seg->buf_table.buf_array);2441 if (!section || le32_to_cpu(section->section_entry[0].type) !=2442 ICE_SID_TX_5_LAYER_TOPO) {2443 ice_debug(hw, ICE_DBG_INIT, "5 layer topology section type is wrong\n");2444 return -EIO;2445 }2446 2447 size = le16_to_cpu(section->section_entry[0].size);2448 offset = le16_to_cpu(section->section_entry[0].offset);2449 if (size < ICE_MIN_S_SZ || size > ICE_MAX_S_SZ) {2450 ice_debug(hw, ICE_DBG_INIT, "5 layer topology section size is wrong\n");2451 return -EIO;2452 }2453 2454 /* Make sure the section fits in the buffer */2455 if (offset + size > ICE_PKG_BUF_SIZE) {2456 ice_debug(hw, ICE_DBG_INIT, "5 layer topology buffer > 4K\n");2457 return -EIO;2458 }2459 2460 /* Get the new topology buffer, reuse current topo copy mem */2461 static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN);2462 new_topo = topo;2463 memcpy(new_topo, (u8 *)section + offset, size);2464 2465update_topo:2466 /* Acquire global lock to make sure that set topology issued2467 * by one PF.2468 */2469 status = ice_acquire_res(hw, ICE_GLOBAL_CFG_LOCK_RES_ID, ICE_RES_WRITE,2470 ICE_GLOBAL_CFG_LOCK_TIMEOUT);2471 if (status) {2472 ice_debug(hw, ICE_DBG_INIT, "Failed to acquire global lock\n");2473 return status;2474 }2475 2476 /* Check if reset was triggered already. */2477 reg = rd32(hw, GLGEN_RSTAT);2478 if (reg & GLGEN_RSTAT_DEVSTATE_M) {2479 /* Reset is in progress, re-init the HW again */2480 ice_debug(hw, ICE_DBG_INIT, "Reset is in progress. Layer topology might be applied already\n");2481 ice_check_reset(hw);2482 return 0;2483 }2484 2485 /* Set new topology */2486 status = ice_get_set_tx_topo(hw, new_topo, size, NULL, NULL, true);2487 if (status) {2488 ice_debug(hw, ICE_DBG_INIT, "Failed setting Tx topology\n");2489 return status;2490 }2491 2492 /* New topology is updated, delay 1 second before issuing the CORER */2493 msleep(1000);2494 ice_reset(hw, ICE_RESET_CORER);2495 /* CORER will clear the global lock, so no explicit call2496 * required for release.2497 */2498 2499 return 0;2500}2501