X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;ds=sidebyside;f=drivers%2Fnet%2Fice%2Fbase%2Fice_common.c;h=a617643b6035cd3b91b82be8625911ae81b329d7;hb=9c992978959e8d339e9d036b13665a5dfc48965f;hp=0d5a4e3e4dd8aea871721fdb03f559fd25d3a189;hpb=ed56a562aff5e3f59c4a65d035f5e0bd7d078142;p=dpdk.git diff --git a/drivers/net/ice/base/ice_common.c b/drivers/net/ice/base/ice_common.c index 0d5a4e3e4d..a617643b60 100644 --- a/drivers/net/ice/base/ice_common.c +++ b/drivers/net/ice/base/ice_common.c @@ -1,5 +1,5 @@ /* SPDX-License-Identifier: BSD-3-Clause - * Copyright(c) 2001-2020 + * Copyright(c) 2001-2020 Intel Corporation */ #include "ice_common.h" @@ -256,6 +256,15 @@ static enum ice_media_type ice_get_media_type(struct ice_port_info *pi) case ICE_PHY_TYPE_LOW_100GBASE_SR2: case ICE_PHY_TYPE_LOW_100GBASE_DR: return ICE_MEDIA_FIBER; + case ICE_PHY_TYPE_LOW_10G_SFI_AOC_ACC: + case ICE_PHY_TYPE_LOW_25G_AUI_AOC_ACC: + case ICE_PHY_TYPE_LOW_40G_XLAUI_AOC_ACC: + case ICE_PHY_TYPE_LOW_50G_LAUI2_AOC_ACC: + case ICE_PHY_TYPE_LOW_50G_AUI2_AOC_ACC: + case ICE_PHY_TYPE_LOW_50G_AUI1_AOC_ACC: + case ICE_PHY_TYPE_LOW_100G_CAUI4_AOC_ACC: + case ICE_PHY_TYPE_LOW_100G_AUI4_AOC_ACC: + return ICE_MEDIA_FIBER; case ICE_PHY_TYPE_LOW_100BASE_TX: case ICE_PHY_TYPE_LOW_1000BASE_T: case ICE_PHY_TYPE_LOW_2500BASE_T: @@ -282,7 +291,7 @@ static enum ice_media_type ice_get_media_type(struct ice_port_info *pi) case ICE_PHY_TYPE_LOW_100G_AUI4: case ICE_PHY_TYPE_LOW_100G_CAUI4: if (ice_is_media_cage_present(pi)) - return ICE_MEDIA_DA; + return ICE_MEDIA_AUI; /* fall-through */ case ICE_PHY_TYPE_LOW_1000BASE_KX: case ICE_PHY_TYPE_LOW_2500BASE_KX: @@ -302,11 +311,15 @@ static enum ice_media_type ice_get_media_type(struct ice_port_info *pi) } else { switch (hw_link_info->phy_type_high) { case ICE_PHY_TYPE_HIGH_100G_AUI2: + case ICE_PHY_TYPE_HIGH_100G_CAUI2: if (ice_is_media_cage_present(pi)) - return ICE_MEDIA_DA; + return ICE_MEDIA_AUI; /* fall-through */ case ICE_PHY_TYPE_HIGH_100GBASE_KR2_PAM4: return ICE_MEDIA_BACKPLANE; + case ICE_PHY_TYPE_HIGH_100G_CAUI2_AOC_ACC: + case ICE_PHY_TYPE_HIGH_100G_AUI2_AOC_ACC: + return ICE_MEDIA_FIBER; } } return ICE_MEDIA_UNKNOWN; @@ -409,6 +422,43 @@ ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse, return ICE_SUCCESS; } +/** + * ice_fill_tx_timer_and_fc_thresh + * @hw: pointer to the HW struct + * @cmd: pointer to MAC cfg structure + * + * Add Tx timer and FC refresh threshold info to Set MAC Config AQ command + * descriptor + */ +static void +ice_fill_tx_timer_and_fc_thresh(struct ice_hw *hw, + struct ice_aqc_set_mac_cfg *cmd) +{ + u16 fc_thres_val, tx_timer_val; + u32 val; + + /* We read back the transmit timer and fc threshold value of + * LFC. Thus, we will use index = + * PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX. + * + * Also, because we are opearating on transmit timer and fc + * threshold of LFC, we don't turn on any bit in tx_tmr_priority + */ +#define IDX_OF_LFC PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX + + /* Retrieve the transmit timer */ + val = rd32(hw, PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(IDX_OF_LFC)); + tx_timer_val = val & + PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_M; + cmd->tx_tmr_value = CPU_TO_LE16(tx_timer_val); + + /* Retrieve the fc threshold */ + val = rd32(hw, PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(IDX_OF_LFC)); + fc_thres_val = val & PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER_M; + + cmd->fc_refresh_threshold = CPU_TO_LE16(fc_thres_val); +} + /** * ice_aq_set_mac_cfg * @hw: pointer to the HW struct @@ -420,10 +470,8 @@ ice_aq_get_link_info(struct ice_port_info *pi, bool ena_lse, enum ice_status ice_aq_set_mac_cfg(struct ice_hw *hw, u16 max_frame_size, struct ice_sq_cd *cd) { - u16 fc_threshold_val, tx_timer_val; struct ice_aqc_set_mac_cfg *cmd; struct ice_aq_desc desc; - u32 reg_val; cmd = &desc.params.set_mac_cfg; @@ -434,27 +482,7 @@ ice_aq_set_mac_cfg(struct ice_hw *hw, u16 max_frame_size, struct ice_sq_cd *cd) cmd->max_frame_size = CPU_TO_LE16(max_frame_size); - /* We read back the transmit timer and fc threshold value of - * LFC. Thus, we will use index = - * PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX. - * - * Also, because we are opearating on transmit timer and fc - * threshold of LFC, we don't turn on any bit in tx_tmr_priority - */ -#define IDX_OF_LFC PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_MAX_INDEX - - /* Retrieve the transmit timer */ - reg_val = rd32(hw, - PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA(IDX_OF_LFC)); - tx_timer_val = reg_val & - PRTMAC_HSEC_CTL_TX_PAUSE_QUANTA_HSEC_CTL_TX_PAUSE_QUANTA_M; - cmd->tx_tmr_value = CPU_TO_LE16(tx_timer_val); - - /* Retrieve the fc threshold */ - reg_val = rd32(hw, - PRTMAC_HSEC_CTL_TX_PAUSE_REFRESH_TIMER(IDX_OF_LFC)); - fc_threshold_val = reg_val & MAKEMASK(0xFFFF, 0); - cmd->fc_refresh_threshold = CPU_TO_LE16(fc_threshold_val); + ice_fill_tx_timer_and_fc_thresh(hw, cmd); return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); } @@ -466,6 +494,7 @@ ice_aq_set_mac_cfg(struct ice_hw *hw, u16 max_frame_size, struct ice_sq_cd *cd) enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw) { struct ice_switch_info *sw; + enum ice_status status; hw->switch_info = (struct ice_switch_info *) ice_malloc(hw, sizeof(*hw->switch_info)); @@ -477,27 +506,36 @@ enum ice_status ice_init_fltr_mgmt_struct(struct ice_hw *hw) INIT_LIST_HEAD(&sw->vsi_list_map_head); - return ice_init_def_sw_recp(hw, &hw->switch_info->recp_list); + status = ice_init_def_sw_recp(hw, &hw->switch_info->recp_list); + if (status) { + ice_free(hw, hw->switch_info); + return status; + } + return ICE_SUCCESS; } /** - * ice_cleanup_fltr_mgmt_struct - cleanup filter management list and locks + * ice_cleanup_fltr_mgmt_single - clears single filter mngt struct * @hw: pointer to the HW struct + * @sw: pointer to switch info struct for which function clears filters */ -void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw) +static void +ice_cleanup_fltr_mgmt_single(struct ice_hw *hw, struct ice_switch_info *sw) { - struct ice_switch_info *sw = hw->switch_info; struct ice_vsi_list_map_info *v_pos_map; struct ice_vsi_list_map_info *v_tmp_map; struct ice_sw_recipe *recps; u8 i; + if (!sw) + return; + LIST_FOR_EACH_ENTRY_SAFE(v_pos_map, v_tmp_map, &sw->vsi_list_map_head, ice_vsi_list_map_info, list_entry) { LIST_DEL(&v_pos_map->list_entry); ice_free(hw, v_pos_map); } - recps = hw->switch_info->recp_list; + recps = sw->recp_list; for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) { struct ice_recp_grp_entry *rg_entry, *tmprg_entry; @@ -537,11 +575,20 @@ void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw) if (recps[i].root_buf) ice_free(hw, recps[i].root_buf); } - ice_rm_all_sw_replay_rule_info(hw); + ice_rm_sw_replay_rule_info(hw, sw); ice_free(hw, sw->recp_list); ice_free(hw, sw); } +/** + * ice_cleanup_all_fltr_mgmt - cleanup filter management list and locks + * @hw: pointer to the HW struct + */ +void ice_cleanup_fltr_mgmt_struct(struct ice_hw *hw) +{ + ice_cleanup_fltr_mgmt_single(hw, hw->switch_info); +} + /** * ice_get_itr_intrl_gran * @hw: pointer to the HW struct @@ -700,7 +747,6 @@ enum ice_status ice_init_hw(struct ice_hw *hw) /* Initialize max burst size */ if (!hw->max_burst_size) ice_cfg_rl_burst_size(hw, ICE_SCHED_DFLT_BURST_SIZE); - status = ice_init_fltr_mgmt_struct(hw); if (status) goto err_unroll_sched; @@ -719,6 +765,10 @@ enum ice_status ice_init_hw(struct ice_hw *hw) status = ice_aq_manage_mac_read(hw, mac_buf, mac_buf_len, NULL); ice_free(hw, mac_buf); + if (status) + goto err_unroll_fltr_mgmt_struct; + /* enable jumbo frame support at MAC level */ + status = ice_aq_set_mac_cfg(hw, ICE_AQ_SET_MAC_FRAME_SIZE_MAX, NULL); if (status) goto err_unroll_fltr_mgmt_struct; /* Obtain counter base index which would be used by flow director */ @@ -728,6 +778,7 @@ enum ice_status ice_init_hw(struct ice_hw *hw) status = ice_init_hw_tbls(hw); if (status) goto err_unroll_fltr_mgmt_struct; + ice_init_lock(&hw->tnl_lock); return ICE_SUCCESS; err_unroll_fltr_mgmt_struct: @@ -759,6 +810,7 @@ void ice_deinit_hw(struct ice_hw *hw) ice_sched_clear_agg(hw); ice_free_seg(hw); ice_free_hw_tbls(hw); + ice_destroy_lock(&hw->tnl_lock); if (hw->port_info) { ice_free(hw, hw->port_info); @@ -860,7 +912,12 @@ static enum ice_status ice_pf_reset(struct ice_hw *hw) wr32(hw, PFGEN_CTRL, (reg | PFGEN_CTRL_PFSWR_M)); - for (cnt = 0; cnt < ICE_PF_RESET_WAIT_COUNT; cnt++) { + /* Wait for the PFR to complete. The wait time is the global config lock + * timeout plus the PFR timeout which will account for a possible reset + * that is occurring during a download package operation. + */ + for (cnt = 0; cnt < ICE_GLOBAL_CFG_LOCK_TIMEOUT + + ICE_PF_RESET_WAIT_COUNT; cnt++) { reg = rd32(hw, PFGEN_CTRL); if (!(reg & PFGEN_CTRL_PFSWR_M)) break; @@ -916,72 +973,6 @@ enum ice_status ice_reset(struct ice_hw *hw, enum ice_reset_req req) return ice_check_reset(hw); } -/** - * ice_get_pfa_module_tlv - Reads sub module TLV from NVM PFA - * @hw: pointer to hardware structure - * @module_tlv: pointer to module TLV to return - * @module_tlv_len: pointer to module TLV length to return - * @module_type: module type requested - * - * Finds the requested sub module TLV type from the Preserved Field - * Area (PFA) and returns the TLV pointer and length. The caller can - * use these to read the variable length TLV value. - */ -enum ice_status -ice_get_pfa_module_tlv(struct ice_hw *hw, u16 *module_tlv, u16 *module_tlv_len, - u16 module_type) -{ - enum ice_status status; - u16 pfa_len, pfa_ptr; - u16 next_tlv; - - status = ice_read_sr_word(hw, ICE_SR_PFA_PTR, &pfa_ptr); - if (status != ICE_SUCCESS) { - ice_debug(hw, ICE_DBG_INIT, "Preserved Field Array pointer.\n"); - return status; - } - status = ice_read_sr_word(hw, pfa_ptr, &pfa_len); - if (status != ICE_SUCCESS) { - ice_debug(hw, ICE_DBG_INIT, "Failed to read PFA length.\n"); - return status; - } - /* Starting with first TLV after PFA length, iterate through the list - * of TLVs to find the requested one. - */ - next_tlv = pfa_ptr + 1; - while (next_tlv < pfa_ptr + pfa_len) { - u16 tlv_sub_module_type; - u16 tlv_len; - - /* Read TLV type */ - status = ice_read_sr_word(hw, next_tlv, &tlv_sub_module_type); - if (status != ICE_SUCCESS) { - ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV type.\n"); - break; - } - /* Read TLV length */ - status = ice_read_sr_word(hw, next_tlv + 1, &tlv_len); - if (status != ICE_SUCCESS) { - ice_debug(hw, ICE_DBG_INIT, "Failed to read TLV length.\n"); - break; - } - if (tlv_sub_module_type == module_type) { - if (tlv_len) { - *module_tlv = next_tlv; - *module_tlv_len = tlv_len; - return ICE_SUCCESS; - } - return ICE_ERR_INVAL_SIZE; - } - /* Check next TLV, i.e. current TLV pointer + length + 2 words - * (for current TLV's type and length) - */ - next_tlv = next_tlv + tlv_len + 2; - } - /* Module does not exist */ - return ICE_ERR_DOES_NOT_EXIST; -} - /** * ice_copy_rxq_ctx_to_hw * @hw: pointer to the hardware structure @@ -1060,7 +1051,7 @@ ice_write_rxq_ctx(struct ice_hw *hw, struct ice_rlan_ctx *rlan_ctx, rlan_ctx->prefena = 1; - ice_set_ctx((u8 *)rlan_ctx, ctx_buf, ice_rlan_ctx_info); + ice_set_ctx(hw, (u8 *)rlan_ctx, ctx_buf, ice_rlan_ctx_info); return ice_copy_rxq_ctx_to_hw(hw, ctx_buf, rxq_index); } @@ -1183,7 +1174,7 @@ ice_write_tx_cmpltnq_ctx(struct ice_hw *hw, { u8 ctx_buf[ICE_TX_CMPLTNQ_CTX_SIZE_DWORDS * sizeof(u32)] = { 0 }; - ice_set_ctx((u8 *)tx_cmpltnq_ctx, ctx_buf, ice_tx_cmpltnq_ctx_info); + ice_set_ctx(hw, (u8 *)tx_cmpltnq_ctx, ctx_buf, ice_tx_cmpltnq_ctx_info); return ice_copy_tx_cmpltnq_ctx_to_hw(hw, ctx_buf, tx_cmpltnq_index); } @@ -1274,7 +1265,8 @@ ice_write_tx_drbell_q_ctx(struct ice_hw *hw, { u8 ctx_buf[ICE_TX_DRBELL_Q_CTX_SIZE_DWORDS * sizeof(u32)] = { 0 }; - ice_set_ctx((u8 *)tx_drbell_q_ctx, ctx_buf, ice_tx_drbell_q_ctx_info); + ice_set_ctx(hw, (u8 *)tx_drbell_q_ctx, ctx_buf, + ice_tx_drbell_q_ctx_info); return ice_copy_tx_drbell_q_ctx_to_hw(hw, ctx_buf, tx_drbell_q_index); } @@ -1904,9 +1896,6 @@ ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count, caps->msix_vector_first_id); break; case ICE_AQC_CAPS_FD: - { - u32 reg_val, val; - if (dev_p) { dev_p->num_flow_director_fltr = number; ice_debug(hw, ICE_DBG_INIT, @@ -1915,6 +1904,8 @@ ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count, dev_p->num_flow_director_fltr); } if (func_p) { + u32 reg_val, val; + if (hw->dcf_enabled) break; reg_val = rd32(hw, GLQF_FD_SIZE); @@ -1933,7 +1924,6 @@ ice_parse_caps(struct ice_hw *hw, void *buf, u32 cap_count, prefix, func_p->fd_fltr_best_effort); } break; - } case ICE_AQC_CAPS_MAX_MTU: caps->max_mtu = number; ice_debug(hw, ICE_DBG_INIT, "%s: max_mtu = %d\n", @@ -2143,10 +2133,7 @@ ice_aq_manage_mac_write(struct ice_hw *hw, const u8 *mac_addr, u8 flags, ice_fill_dflt_direct_cmd_desc(&desc, ice_aqc_opc_manage_mac_write); cmd->flags = flags; - - /* Prep values for flags, sah, sal */ - cmd->sah = HTONS(*((const u16 *)mac_addr)); - cmd->sal = HTONL(*((const u32 *)(mac_addr + 2))); + ice_memcpy(cmd->mac_addr, mac_addr, ETH_ALEN, ICE_NONDMA_TO_DMA); return ice_aq_send_cmd(hw, &desc, NULL, 0, cd); } @@ -2404,6 +2391,9 @@ ice_aq_set_phy_cfg(struct ice_hw *hw, struct ice_port_info *pi, status = ice_aq_send_cmd(hw, &desc, cfg, sizeof(*cfg), cd); + if (hw->adminq.sq_last_status == ICE_AQ_RC_EMODE) + status = ICE_SUCCESS; + if (!status) pi->phy.curr_user_phy_cfg = *cfg; @@ -2530,50 +2520,36 @@ enum ice_fec_mode ice_caps_to_fec_mode(u8 caps, u8 fec_options) return ICE_FEC_NONE; } -/** - * ice_set_fc - * @pi: port information structure - * @aq_failures: pointer to status code, specific to ice_set_fc routine - * @ena_auto_link_update: enable automatic link update - * - * Set the requested flow control mode. - */ -enum ice_status -ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update) +static enum ice_status +ice_cfg_phy_fc(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, + enum ice_fc_mode req_mode) { - struct ice_aqc_set_phy_cfg_data cfg = { 0 }; + struct ice_aqc_get_phy_caps_data *pcaps = NULL; struct ice_phy_cache_mode_data cache_data; - struct ice_aqc_get_phy_caps_data *pcaps; - enum ice_status status; + enum ice_status status = ICE_SUCCESS; u8 pause_mask = 0x0; - struct ice_hw *hw; - if (!pi || !aq_failures) - return ICE_ERR_PARAM; - - hw = pi->hw; - *aq_failures = ICE_SET_FC_AQ_FAIL_NONE; - - /* Cache user FC request */ - cache_data.data.curr_user_fc_req = pi->fc.req_mode; - ice_cache_phy_user_req(pi, cache_data, ICE_FC_MODE); + if (!pi || !cfg) + return ICE_ERR_BAD_PTR; pcaps = (struct ice_aqc_get_phy_caps_data *) - ice_malloc(hw, sizeof(*pcaps)); + ice_malloc(pi->hw, sizeof(*pcaps)); if (!pcaps) return ICE_ERR_NO_MEMORY; - switch (pi->fc.req_mode) { + /* Cache user FC request */ + cache_data.data.curr_user_fc_req = req_mode; + ice_cache_phy_user_req(pi, cache_data, ICE_FC_MODE); + + switch (req_mode) { case ICE_FC_AUTO: /* Query the value of FC that both the NIC and attached media * can do. */ status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_TOPO_CAP, pcaps, NULL); - if (status) { - *aq_failures = ICE_SET_FC_AQ_FAIL_GET; + if (status) goto out; - } pause_mask |= pcaps->caps & ICE_AQC_PHY_EN_TX_LINK_PAUSE; pause_mask |= pcaps->caps & ICE_AQC_PHY_EN_RX_LINK_PAUSE; @@ -2592,8 +2568,45 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update) break; } + /* clear the old pause settings */ + cfg->caps &= ~(ICE_AQC_PHY_EN_TX_LINK_PAUSE | + ICE_AQC_PHY_EN_RX_LINK_PAUSE); + + /* set the new capabilities */ + cfg->caps |= pause_mask; + +out: + ice_free(pi->hw, pcaps); + return status; +} + +/** + * ice_set_fc + * @pi: port information structure + * @aq_failures: pointer to status code, specific to ice_set_fc routine + * @ena_auto_link_update: enable automatic link update + * + * Set the requested flow control mode. + */ +enum ice_status +ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update) +{ + struct ice_aqc_set_phy_cfg_data cfg = { 0 }; + struct ice_aqc_get_phy_caps_data *pcaps; + enum ice_status status; + struct ice_hw *hw; + + if (!pi || !aq_failures) + return ICE_ERR_BAD_PTR; + + hw = pi->hw; + + pcaps = (struct ice_aqc_get_phy_caps_data *) + ice_malloc(hw, sizeof(*pcaps)); + if (!pcaps) + return ICE_ERR_NO_MEMORY; + /* Get the current PHY config */ - ice_memset(pcaps, 0, sizeof(*pcaps), ICE_NONDMA_MEM); status = ice_aq_get_phy_caps(pi, false, ICE_AQC_REPORT_SW_CFG, pcaps, NULL); if (status) { @@ -2603,12 +2616,14 @@ ice_set_fc(struct ice_port_info *pi, u8 *aq_failures, bool ena_auto_link_update) ice_copy_phy_caps_to_cfg(pi, pcaps, &cfg); - /* clear the old pause settings */ - cfg.caps &= ~(ICE_AQC_PHY_EN_TX_LINK_PAUSE | - ICE_AQC_PHY_EN_RX_LINK_PAUSE); + /* Configure the set PHY data */ + status = ice_cfg_phy_fc(pi, &cfg, pi->fc.req_mode); + if (status) { + if (status != ICE_ERR_BAD_PTR) + *aq_failures = ICE_SET_FC_AQ_FAIL_GET; - /* set the new capabilities */ - cfg.caps |= pause_mask; + goto out; + } /* If the capabilities have changed, then set the new config */ if (cfg.caps != pcaps->caps) { @@ -2752,6 +2767,9 @@ ice_cfg_phy_fec(struct ice_port_info *pi, struct ice_aqc_set_phy_cfg_data *cfg, if (status) goto out; + cfg->caps |= (pcaps->caps & ICE_AQC_PHY_EN_AUTO_FEC); + cfg->link_fec_opt = pcaps->link_fec_options; + switch (fec) { case ICE_FEC_BASER: /* Clear RS bits, and AND BASE-R ability @@ -3607,12 +3625,14 @@ ice_write_qword(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) /** * ice_set_ctx - set context bits in packed structure + * @hw: pointer to the hardware structure * @src_ctx: pointer to a generic non-packed context structure * @dest_ctx: pointer to memory for the packed structure * @ce_info: a description of the structure to be transformed */ enum ice_status -ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) +ice_set_ctx(struct ice_hw *hw, u8 *src_ctx, u8 *dest_ctx, + const struct ice_ctx_ele *ce_info) { int f; @@ -3621,6 +3641,12 @@ ice_set_ctx(u8 *src_ctx, u8 *dest_ctx, const struct ice_ctx_ele *ce_info) * using the correct size so that we are correct regardless * of the endianness of the machine. */ + if (ce_info[f].width > (ce_info[f].size_of * BITS_PER_BYTE)) { + ice_debug(hw, ICE_DBG_QCTX, + "Field %d width of %d bits larger than size of %d byte(s) ... skipping write\n", + f, ce_info[f].width, ce_info[f].size_of); + continue; + } switch (ce_info[f].size_of) { case sizeof(u8): ice_write_byte(src_ctx, dest_ctx, &ce_info[f]); @@ -4105,19 +4131,33 @@ ice_cfg_vsi_lan(struct ice_port_info *pi, u16 vsi_handle, u16 tc_bitmap, ICE_SCHED_NODE_OWNER_LAN); } +/** + * ice_is_main_vsi - checks whether the VSI is main VSI + * @hw: pointer to the HW struct + * @vsi_handle: VSI handle + * + * Checks whether the VSI is the main VSI (the first PF VSI created on + * given PF). + */ +static bool ice_is_main_vsi(struct ice_hw *hw, u16 vsi_handle) +{ + return vsi_handle == ICE_MAIN_VSI_HANDLE && hw->vsi_ctx[vsi_handle]; +} + /** * ice_replay_pre_init - replay pre initialization * @hw: pointer to the HW struct + * @sw: pointer to switch info struct for which function initializes filters * * Initializes required config data for VSI, FD, ACL, and RSS before replay. */ -static enum ice_status ice_replay_pre_init(struct ice_hw *hw) +static enum ice_status +ice_replay_pre_init(struct ice_hw *hw, struct ice_switch_info *sw) { - struct ice_switch_info *sw = hw->switch_info; u8 i; /* Delete old entries from replay filter list head if there is any */ - ice_rm_all_sw_replay_rule_info(hw); + ice_rm_sw_replay_rule_info(hw, sw); /* In start of replay, move entries into replay_rules list, it * will allow adding rules entries back to filt_rules list, * which is operational list. @@ -4140,14 +4180,16 @@ static enum ice_status ice_replay_pre_init(struct ice_hw *hw) */ enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle) { + struct ice_switch_info *sw = hw->switch_info; + struct ice_port_info *pi = hw->port_info; enum ice_status status; if (!ice_is_vsi_valid(hw, vsi_handle)) return ICE_ERR_PARAM; /* Replay pre-initialization if there is any */ - if (vsi_handle == ICE_MAIN_VSI_HANDLE) { - status = ice_replay_pre_init(hw); + if (ice_is_main_vsi(hw, vsi_handle)) { + status = ice_replay_pre_init(hw, sw); if (status) return status; } @@ -4156,7 +4198,7 @@ enum ice_status ice_replay_vsi(struct ice_hw *hw, u16 vsi_handle) if (status) return status; /* Replay per VSI all filters */ - status = ice_replay_vsi_all_fltr(hw, vsi_handle); + status = ice_replay_vsi_all_fltr(hw, pi, vsi_handle); if (!status) status = ice_replay_vsi_agg(hw, vsi_handle); return status; @@ -4359,6 +4401,10 @@ enum ice_fw_modes ice_get_fw_mode(struct ice_hw *hw) */ bool ice_fw_supports_link_override(struct ice_hw *hw) { + /* Currently, only supported for E810 devices */ + if (hw->mac_type != ICE_MAC_E810) + return false; + if (hw->api_maj_ver == ICE_FW_API_LINK_OVERRIDE_MAJ) { if (hw->api_min_ver > ICE_FW_API_LINK_OVERRIDE_MIN) return true;