X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fi40e%2Fbase%2Fi40e_common.c;h=0eb369ff6c7956b0a659d60c771b2dbd22497728;hb=92451d9039ddddeddf59208a988393a6d44b2b9b;hp=de0a81eb183824f8c6dc3f3f84aeec11e6e40721;hpb=8d653649a8643e869a1954cc1ee37c482444967c;p=dpdk.git diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c index de0a81eb18..0eb369ff6c 100644 --- a/drivers/net/i40e/base/i40e_common.c +++ b/drivers/net/i40e/base/i40e_common.c @@ -1,42 +1,12 @@ -/******************************************************************************* - -Copyright (c) 2013 - 2015, Intel Corporation -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of the Intel Corporation nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -POSSIBILITY OF SUCH DAMAGE. - -***************************************************************************/ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright(c) 2001-2018 + */ #include "i40e_type.h" #include "i40e_adminq.h" #include "i40e_prototype.h" #include "virtchnl.h" - /** * i40e_set_mac_type - Sets MAC type * @hw: pointer to the HW structure @@ -310,6 +280,8 @@ const char *i40e_stat_str(struct i40e_hw *hw, enum i40e_status_code stat_err) return "I40E_NOT_SUPPORTED"; case I40E_ERR_FIRMWARE_API_VERSION: return "I40E_ERR_FIRMWARE_API_VERSION"; + case I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR: + return "I40E_ERR_ADMIN_QUEUE_CRITICAL_ERROR"; } snprintf(hw->err_str, sizeof(hw->err_str), "%d", stat_err); @@ -1324,6 +1296,29 @@ STATIC enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw) return media; } +/** + * i40e_poll_globr - Poll for Global Reset completion + * @hw: pointer to the hardware structure + * @retry_limit: how many times to retry before failure + **/ +STATIC enum i40e_status_code i40e_poll_globr(struct i40e_hw *hw, + u32 retry_limit) +{ + u32 cnt, reg = 0; + + for (cnt = 0; cnt < retry_limit; cnt++) { + reg = rd32(hw, I40E_GLGEN_RSTAT); + if (!(reg & I40E_GLGEN_RSTAT_DEVSTATE_MASK)) + return I40E_SUCCESS; + i40e_msec_delay(100); + } + + DEBUGOUT("Global reset failed.\n"); + DEBUGOUT1("I40E_GLGEN_RSTAT = 0x%x\n", reg); + + return I40E_ERR_RESET_FAILED; +} + #define I40E_PF_RESET_WAIT_COUNT 200 /** * i40e_pf_reset - Reset the PF @@ -1347,7 +1342,7 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw) I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >> I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT; - grst_del = grst_del * 20; + grst_del = min(grst_del * 20, 160U); for (cnt = 0; cnt < grst_del; cnt++) { reg = rd32(hw, I40E_GLGEN_RSTAT); @@ -1393,14 +1388,14 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw) if (!(reg & I40E_PFGEN_CTRL_PFSWR_MASK)) break; reg2 = rd32(hw, I40E_GLGEN_RSTAT); - if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) { - DEBUGOUT("Core reset upcoming. Skipping PF reset request.\n"); - DEBUGOUT1("I40E_GLGEN_RSTAT = 0x%x\n", reg2); - return I40E_ERR_NOT_READY; - } + if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) + break; i40e_msec_delay(1); } - if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) { + if (reg2 & I40E_GLGEN_RSTAT_DEVSTATE_MASK) { + if (i40e_poll_globr(hw, grst_del) != I40E_SUCCESS) + return I40E_ERR_RESET_FAILED; + } else if (reg & I40E_PFGEN_CTRL_PFSWR_MASK) { DEBUGOUT("PF reset polling failed to complete.\n"); return I40E_ERR_RESET_FAILED; } @@ -2023,7 +2018,11 @@ enum i40e_status_code i40e_aq_get_link_info(struct i40e_hw *hw, if (hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR && hw->aq.api_min_ver >= 7) { - hw->phy.phy_types = LE32_TO_CPU(*(__le32 *)resp->link_type); + __le32 tmp; + + i40e_memcpy(&tmp, resp->link_type, sizeof(tmp), + I40E_NONDMA_TO_NONDMA); + hw->phy.phy_types = LE32_TO_CPU(tmp); hw->phy.phy_types |= ((u64)resp->link_type_ext << 32); } @@ -2166,9 +2165,9 @@ aq_get_partner_advt_exit: * * Sets loopback modes. **/ -enum i40e_status_code -i40e_aq_set_lb_modes(struct i40e_hw *hw, u8 lb_level, u8 lb_type, u8 speed, - struct i40e_asq_cmd_details *cmd_details) +enum i40e_status_code i40e_aq_set_lb_modes(struct i40e_hw *hw, + u16 lb_modes, + struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; struct i40e_aqc_set_lb_mode *cmd = @@ -2178,11 +2177,7 @@ i40e_aq_set_lb_modes(struct i40e_hw *hw, u8 lb_level, u8 lb_type, u8 speed, i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_set_lb_modes); - cmd->lb_level = lb_level; - cmd->lb_type = lb_type; - cmd->speed = speed; - if (speed) - cmd->force_speed = 1; + cmd->lb_mode = CPU_TO_LE16(lb_modes); status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); @@ -2709,13 +2704,14 @@ enum i40e_status_code i40e_aq_get_switch_config(struct i40e_hw *hw, * i40e_aq_set_switch_config * @hw: pointer to the hardware structure * @flags: bit flag values to set + * @mode: cloud filter mode * @valid_flags: which bit flags to set * @cmd_details: pointer to command details structure or NULL * * Set switch configuration bits **/ enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw, - u16 flags, u16 valid_flags, + u16 flags, u16 valid_flags, u8 mode, struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; @@ -2727,6 +2723,7 @@ enum i40e_status_code i40e_aq_set_switch_config(struct i40e_hw *hw, i40e_aqc_opc_set_switch_config); scfg->flags = CPU_TO_LE16(flags); scfg->valid_flags = CPU_TO_LE16(valid_flags); + scfg->mode = mode; if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) { scfg->switch_tag = CPU_TO_LE16(hw->switch_tag); scfg->first_tag = CPU_TO_LE16(hw->first_tag); @@ -3706,9 +3703,10 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, u32 valid_functions, num_functions; u32 number, logical_id, phys_id; struct i40e_hw_capabilities *p; + enum i40e_status_code status; + u16 id, ocp_cfg_word0; u8 major_rev; u32 i = 0; - u16 id; cap = (struct i40e_aqc_list_capabilities_element_resp *) buff; @@ -4000,6 +3998,26 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, hw->num_ports++; } + /* OCP cards case: if a mezz is removed the ethernet port is at + * disabled state in PRTGEN_CNF register. Additional NVM read is + * needed in order to check if we are dealing with OCP card. + * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting + * physical ports results in wrong partition id calculation and thus + * not supporting WoL. + */ + if (hw->mac.type == I40E_MAC_X722) { + if (i40e_acquire_nvm(hw, I40E_RESOURCE_READ) == I40E_SUCCESS) { + status = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR, + 2 * I40E_SR_OCP_CFG_WORD0, + sizeof(ocp_cfg_word0), + &ocp_cfg_word0, true, NULL); + if (status == I40E_SUCCESS && + (ocp_cfg_word0 & I40E_SR_OCP_ENABLED)) + hw->num_ports = 4; + i40e_release_nvm(hw); + } + } + valid_functions = p->valid_functions; num_functions = 0; while (valid_functions) { @@ -5691,10 +5709,10 @@ void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw, * to be shifted 1 byte over from the VxLAN VNI **/ STATIC void i40e_fix_up_geneve_vni( - struct i40e_aqc_add_remove_cloud_filters_element_data *filters, + struct i40e_aqc_cloud_filters_element_data *filters, u8 filter_count) { - struct i40e_aqc_add_remove_cloud_filters_element_data *f = filters; + struct i40e_aqc_cloud_filters_element_data *f = filters; int i; for (i = 0; i < filter_count; i++) { @@ -5719,13 +5737,13 @@ STATIC void i40e_fix_up_geneve_vni( * @filter_count: number of filters contained in the buffer * * Set the cloud filters for a given VSI. The contents of the - * i40e_aqc_add_remove_cloud_filters_element_data are filled + * i40e_aqc_cloud_filters_element_data are filled * in by the caller of the function. * **/ enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw, u16 seid, - struct i40e_aqc_add_remove_cloud_filters_element_data *filters, + struct i40e_aqc_cloud_filters_element_data *filters, u8 filter_count) { struct i40e_aq_desc desc; @@ -5751,21 +5769,21 @@ enum i40e_status_code i40e_aq_add_cloud_filters(struct i40e_hw *hw, } /** - * i40e_aq_add_cloud_filters_big_buffer + * i40e_aq_add_cloud_filters_bb * @hw: pointer to the hardware structure * @seid: VSI seid to add cloud filters from * @filters: Buffer which contains the filters in big buffer to be added * @filter_count: number of filters contained in the buffer * * Set the cloud filters for a given VSI. The contents of the - * i40e_aqc_add_rm_cloud_filt_elem_ext are filled in by the caller of + * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the * the function. * **/ -enum i40e_status_code i40e_aq_add_cloud_filters_big_buffer(struct i40e_hw *hw, - u16 seid, - struct i40e_aqc_add_rm_cloud_filt_elem_ext *filters, - u8 filter_count) +enum i40e_status_code +i40e_aq_add_cloud_filters_bb(struct i40e_hw *hw, u16 seid, + struct i40e_aqc_cloud_filters_element_bb *filters, + u8 filter_count) { struct i40e_aq_desc desc; struct i40e_aqc_add_remove_cloud_filters *cmd = @@ -5782,9 +5800,8 @@ enum i40e_status_code i40e_aq_add_cloud_filters_big_buffer(struct i40e_hw *hw, desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); cmd->num_filters = filter_count; cmd->seid = CPU_TO_LE16(seid); - cmd->big_buffer_flag = I40E_AQC_ADD_REM_CLOUD_CMD_BIG_BUFFER; + cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB; - /* adjust Geneve VNI for HW issue */ for (i = 0; i < filter_count; i++) { u16 tnl_type; u32 ti; @@ -5792,6 +5809,11 @@ enum i40e_status_code i40e_aq_add_cloud_filters_big_buffer(struct i40e_hw *hw, tnl_type = (LE16_TO_CPU(filters[i].element.flags) & I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >> I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT; + + /* Due to hardware eccentricities, the VNI for Geneve is shifted + * one more byte further than normally used for Tenant ID in + * other tunnel types. + */ if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) { ti = LE32_TO_CPU(filters[i].element.tenant_id); filters[i].element.tenant_id = CPU_TO_LE32(ti << 8); @@ -5804,21 +5826,21 @@ enum i40e_status_code i40e_aq_add_cloud_filters_big_buffer(struct i40e_hw *hw, } /** - * i40e_aq_remove_cloud_filters + * i40e_aq_rem_cloud_filters * @hw: pointer to the hardware structure * @seid: VSI seid to remove cloud filters from * @filters: Buffer which contains the filters to be removed * @filter_count: number of filters contained in the buffer * * Remove the cloud filters for a given VSI. The contents of the - * i40e_aqc_add_remove_cloud_filters_element_data are filled - * in by the caller of the function. + * i40e_aqc_cloud_filters_element_data are filled in by the caller + * of the function. * **/ -enum i40e_status_code i40e_aq_remove_cloud_filters(struct i40e_hw *hw, - u16 seid, - struct i40e_aqc_add_remove_cloud_filters_element_data *filters, - u8 filter_count) +enum i40e_status_code +i40e_aq_rem_cloud_filters(struct i40e_hw *hw, u16 seid, + struct i40e_aqc_cloud_filters_element_data *filters, + u8 filter_count) { struct i40e_aq_desc desc; struct i40e_aqc_add_remove_cloud_filters *cmd = @@ -5843,22 +5865,21 @@ enum i40e_status_code i40e_aq_remove_cloud_filters(struct i40e_hw *hw, } /** - * i40e_aq_remove_cloud_filters_big_buffer + * i40e_aq_rem_cloud_filters_bb * @hw: pointer to the hardware structure * @seid: VSI seid to remove cloud filters from * @filters: Buffer which contains the filters in big buffer to be removed * @filter_count: number of filters contained in the buffer * - * Remove the cloud filters for a given VSI. The contents of the - * i40e_aqc_add_rm_cloud_filt_elem_ext are filled in by the caller of - * the function. + * Remove the big buffer cloud filters for a given VSI. The contents of the + * i40e_aqc_cloud_filters_element_bb are filled in by the caller of the + * function. * **/ -enum i40e_status_code i40e_aq_remove_cloud_filters_big_buffer( - struct i40e_hw *hw, - u16 seid, - struct i40e_aqc_add_rm_cloud_filt_elem_ext *filters, - u8 filter_count) +enum i40e_status_code +i40e_aq_rem_cloud_filters_bb(struct i40e_hw *hw, u16 seid, + struct i40e_aqc_cloud_filters_element_bb *filters, + u8 filter_count) { struct i40e_aq_desc desc; struct i40e_aqc_add_remove_cloud_filters *cmd = @@ -5875,9 +5896,8 @@ enum i40e_status_code i40e_aq_remove_cloud_filters_big_buffer( desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); cmd->num_filters = filter_count; cmd->seid = CPU_TO_LE16(seid); - cmd->big_buffer_flag = I40E_AQC_ADD_REM_CLOUD_CMD_BIG_BUFFER; + cmd->big_buffer_flag = I40E_AQC_ADD_CLOUD_CMD_BB; - /* adjust Geneve VNI for HW issue */ for (i = 0; i < filter_count; i++) { u16 tnl_type; u32 ti; @@ -5885,6 +5905,11 @@ enum i40e_status_code i40e_aq_remove_cloud_filters_big_buffer( tnl_type = (LE16_TO_CPU(filters[i].element.flags) & I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK) >> I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT; + + /* Due to hardware eccentricities, the VNI for Geneve is shifted + * one more byte further than normally used for Tenant ID in + * other tunnel types. + */ if (tnl_type == I40E_AQC_ADD_CLOUD_TNL_TYPE_GENEVE) { ti = LE32_TO_CPU(filters[i].element.tenant_id); filters[i].element.tenant_id = CPU_TO_LE32(ti << 8); @@ -7169,9 +7194,9 @@ void i40e_vf_parse_hw_config(struct i40e_hw *hw, hw->dev_caps.num_rx_qp = msg->num_queue_pairs; hw->dev_caps.num_tx_qp = msg->num_queue_pairs; hw->dev_caps.num_msix_vectors_vf = msg->max_vectors; - hw->dev_caps.dcb = msg->vf_offload_flags & + hw->dev_caps.dcb = msg->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_L2; - hw->dev_caps.iwarp = (msg->vf_offload_flags & + hw->dev_caps.iwarp = (msg->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_IWARP) ? 1 : 0; for (i = 0; i < msg->num_vsis; i++) { if (vsi_res->vsi_type == VIRTCHNL_VSI_SRIOV) {