From patchwork Mon Mar 28 08:03:23 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Steve Yang X-Patchwork-Id: 108924 X-Patchwork-Delegate: qi.z.zhang@intel.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 6490AA034C; Mon, 28 Mar 2022 10:11:30 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 0C99242871; Mon, 28 Mar 2022 10:11:30 +0200 (CEST) Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) by mails.dpdk.org (Postfix) with ESMTP id CA7494285A for ; Mon, 28 Mar 2022 10:11:27 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1648455088; x=1679991088; h=from:to:cc:subject:date:message-id:mime-version: content-transfer-encoding; bh=ZPhb7OxVNcdKGwCcQFzUPyUSs5GS9RaWcnFQhABG758=; b=nQ9nMhYkPjjZqQZA5SvMK8dQ9cuKrXBKUWEdrkYQNp8XFWsPJ+ngfpFj bhh54aj87vcRdNw2wqcP4vONi0j3Jm4ihDsJuVKvobilTQ1nqVydDzQt+ 67+SHTEeTOAYBm855Sug1115pMnk+QaJfrXYU1CEg/m0zjaNoJ5QRzSLb VZAIKLbO9lo9oDGPktj4QtdLK0Fklu3FzWzxMdVf0P6Pfp8yi+r8JzyTz hiVZSgNxKN+HOZbk0rVZuo4PPjzG2tYHhbSfkztuFF/UMo4aJpYKLuoKk uG0Xi2SP3IKxl8DPRZmFvYg05bQr/4U0p0PuyN88cZVPX3HLK0vsqJ/xs Q==; X-IronPort-AV: E=McAfee;i="6200,9189,10299"; a="258657853" X-IronPort-AV: E=Sophos;i="5.90,216,1643702400"; d="scan'208";a="258657853" Received: from orsmga006.jf.intel.com ([10.7.209.51]) by orsmga102.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Mar 2022 01:11:26 -0700 X-IronPort-AV: E=Sophos;i="5.90,216,1643702400"; d="scan'208";a="520921914" Received: from intel-cd-odc-steve.cd.intel.com ([10.240.178.135]) by orsmga006-auth.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 28 Mar 2022 01:11:20 -0700 From: Steve Yang To: dev@dpdk.org Cc: qiming.yang@intel.com, Steve Yang Subject: [RFC] net/i40e: backport i40e fixes and share code to 19.11.11 Date: Mon, 28 Mar 2022 08:03:23 +0000 Message-Id: <20220328080323.84632-1-stevex.yang@intel.com> X-Mailer: git-send-email 2.27.0 MIME-Version: 1.0 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Backport all the i40e share code to 19.11.11 based on cid-i40e.2022.03.08. Backport all DPDK bug fixes of i40e & i40evf to 19.11.11 from 22.03. Signed-off-by: Steve Yang --- drivers/net/i40e/base/README | 2 +- drivers/net/i40e/base/i40e_adminq.c | 217 ++++-- drivers/net/i40e/base/i40e_adminq_cmd.h | 165 ++++- drivers/net/i40e/base/i40e_common.c | 903 ++++++++++++++++++------ drivers/net/i40e/base/i40e_dcb.c | 95 ++- drivers/net/i40e/base/i40e_dcb.h | 18 +- drivers/net/i40e/base/i40e_devids.h | 10 +- drivers/net/i40e/base/i40e_nvm.c | 112 ++- drivers/net/i40e/base/i40e_osdep.h | 2 +- drivers/net/i40e/base/i40e_prototype.h | 100 ++- drivers/net/i40e/base/i40e_register.h | 154 +++- drivers/net/i40e/base/i40e_status.h | 2 +- drivers/net/i40e/base/i40e_type.h | 65 +- drivers/net/i40e/base/virtchnl.h | 28 +- drivers/net/i40e/i40e_ethdev.c | 113 +-- drivers/net/i40e/i40e_ethdev_vf.c | 68 +- drivers/net/i40e/i40e_regs.h | 11 +- drivers/net/i40e/rte_pmd_i40e.c | 4 +- 18 files changed, 1594 insertions(+), 475 deletions(-) diff --git a/drivers/net/i40e/base/README b/drivers/net/i40e/base/README index b46593566b..b1da53db2b 100644 --- a/drivers/net/i40e/base/README +++ b/drivers/net/i40e/base/README @@ -6,7 +6,7 @@ IntelĀ® I40E driver ================== This directory contains source code of FreeBSD i40e driver of version -cid-i40e.2018.09.13.tar.gz released by the team which develops +cid-i40e.2022.03.08.tar.gz released by the team which develops basic drivers for any i40e NIC. The directory of base/ contains the original source package. This driver is valid for the product(s) listed below diff --git a/drivers/net/i40e/base/i40e_adminq.c b/drivers/net/i40e/base/i40e_adminq.c index 48f9d8071a..27c82d9b44 100644 --- a/drivers/net/i40e/base/i40e_adminq.c +++ b/drivers/net/i40e/base/i40e_adminq.c @@ -573,6 +573,70 @@ STATIC void i40e_resume_aq(struct i40e_hw *hw) } #endif /* PF_DRIVER */ +/** + * i40e_set_hw_flags - set HW flags + * @hw: pointer to the hardware structure + **/ +STATIC void i40e_set_hw_flags(struct i40e_hw *hw) +{ + struct i40e_adminq_info *aq = &hw->aq; + + hw->flags = 0; + + switch (hw->mac.type) { + case I40E_MAC_XL710: + if (aq->api_maj_ver > 1 || + (aq->api_maj_ver == 1 && + aq->api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710)) { + hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE; + hw->flags |= I40E_HW_FLAG_FW_LLDP_STOPPABLE; + /* The ability to RX (not drop) 802.1ad frames */ + hw->flags |= I40E_HW_FLAG_802_1AD_CAPABLE; + } + break; + case I40E_MAC_X722: + hw->flags |= I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE | + I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK; + + if (aq->api_maj_ver > 1 || + (aq->api_maj_ver == 1 && + aq->api_min_ver >= I40E_MINOR_VER_FW_LLDP_STOPPABLE_X722)) + hw->flags |= I40E_HW_FLAG_FW_LLDP_STOPPABLE; + + if (aq->api_maj_ver > 1 || + (aq->api_maj_ver == 1 && + aq->api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_X722)) + hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE; + + if (aq->api_maj_ver > 1 || + (aq->api_maj_ver == 1 && + aq->api_min_ver >= I40E_MINOR_VER_FW_REQUEST_FEC_X722)) + hw->flags |= I40E_HW_FLAG_X722_FEC_REQUEST_CAPABLE; + + /* fall through */ + default: + break; + } + + /* Newer versions of firmware require lock when reading the NVM */ + if (aq->api_maj_ver > 1 || + (aq->api_maj_ver == 1 && + aq->api_min_ver >= 5)) + hw->flags |= I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK; + + if (aq->api_maj_ver > 1 || + (aq->api_maj_ver == 1 && + aq->api_min_ver >= 8)) { + hw->flags |= I40E_HW_FLAG_FW_LLDP_PERSISTENT; + hw->flags |= I40E_HW_FLAG_DROP_MODE; + } + + if (aq->api_maj_ver > 1 || + (aq->api_maj_ver == 1 && + aq->api_min_ver >= 9)) + hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED; +} + /** * i40e_init_adminq - main initialization routine for Admin Queue * @hw: pointer to the hardware structure @@ -586,27 +650,24 @@ STATIC void i40e_resume_aq(struct i40e_hw *hw) **/ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw) { -#ifdef PF_DRIVER + struct i40e_adminq_info *aq = &hw->aq; + enum i40e_status_code ret_code; u16 oem_hi = 0, oem_lo = 0; u16 eetrack_hi = 0; u16 eetrack_lo = 0; u16 cfg_ptr = 0; -#endif - enum i40e_status_code ret_code; -#ifdef PF_DRIVER int retry = 0; -#endif /* verify input for valid configuration */ - if ((hw->aq.num_arq_entries == 0) || - (hw->aq.num_asq_entries == 0) || - (hw->aq.arq_buf_size == 0) || - (hw->aq.asq_buf_size == 0)) { + if (aq->num_arq_entries == 0 || + aq->num_asq_entries == 0 || + aq->arq_buf_size == 0 || + aq->asq_buf_size == 0) { ret_code = I40E_ERR_CONFIG; goto init_adminq_exit; } - i40e_init_spinlock(&hw->aq.asq_spinlock); - i40e_init_spinlock(&hw->aq.arq_spinlock); + i40e_init_spinlock(&aq->asq_spinlock); + i40e_init_spinlock(&aq->arq_spinlock); /* Set up register offsets */ i40e_adminq_init_regs(hw); @@ -624,23 +685,21 @@ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw) if (ret_code != I40E_SUCCESS) goto init_adminq_free_asq; -#ifdef PF_DRIVER -#ifdef INTEGRATED_VF /* VF has no need of firmware */ if (i40e_is_vf(hw)) goto init_adminq_exit; -#endif + /* There are some cases where the firmware may not be quite ready * for AdminQ operations, so we retry the AdminQ setup a few times * if we see timeouts in this first AQ call. */ do { ret_code = i40e_aq_get_firmware_version(hw, - &hw->aq.fw_maj_ver, - &hw->aq.fw_min_ver, - &hw->aq.fw_build, - &hw->aq.api_maj_ver, - &hw->aq.api_min_ver, + &aq->fw_maj_ver, + &aq->fw_min_ver, + &aq->fw_build, + &aq->api_maj_ver, + &aq->api_min_ver, NULL); if (ret_code != I40E_ERR_ADMIN_QUEUE_TIMEOUT) break; @@ -651,6 +710,12 @@ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw) if (ret_code != I40E_SUCCESS) goto init_adminq_free_arq; + /* + * Some features were introduced in different FW API version + * for different MAC type. + */ + i40e_set_hw_flags(hw); + /* get the NVM version info */ i40e_read_nvm_word(hw, I40E_SR_NVM_DEV_STARTER_VERSION, &hw->nvm.version); @@ -664,31 +729,7 @@ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw) &oem_lo); hw->nvm.oem_ver = ((u32)oem_hi << 16) | oem_lo; - /* The ability to RX (not drop) 802.1ad frames was added in API 1.7 */ - if ((hw->aq.api_maj_ver > 1) || - ((hw->aq.api_maj_ver == 1) && - (hw->aq.api_min_ver >= 7))) - hw->flags |= I40E_HW_FLAG_802_1AD_CAPABLE; - - if (hw->mac.type == I40E_MAC_XL710 && - hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR && - hw->aq.api_min_ver >= I40E_MINOR_VER_GET_LINK_INFO_XL710) { - hw->flags |= I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE; - hw->flags |= I40E_HW_FLAG_FW_LLDP_STOPPABLE; - } - if (hw->mac.type == I40E_MAC_X722 && - hw->aq.api_maj_ver == I40E_FW_API_VERSION_MAJOR && - hw->aq.api_min_ver >= I40E_MINOR_VER_FW_LLDP_STOPPABLE_X722) { - hw->flags |= I40E_HW_FLAG_FW_LLDP_STOPPABLE; - } - - /* Newer versions of firmware require lock when reading the NVM */ - if ((hw->aq.api_maj_ver > 1) || - ((hw->aq.api_maj_ver == 1) && - (hw->aq.api_min_ver >= 5))) - hw->flags |= I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK; - - if (hw->aq.api_maj_ver > I40E_FW_API_VERSION_MAJOR) { + if (aq->api_maj_ver > I40E_FW_API_VERSION_MAJOR) { ret_code = I40E_ERR_FIRMWARE_API_VERSION; goto init_adminq_free_arq; } @@ -698,21 +739,18 @@ enum i40e_status_code i40e_init_adminq(struct i40e_hw *hw) hw->nvm_release_on_done = false; hw->nvmupd_state = I40E_NVMUPD_STATE_INIT; -#endif /* PF_DRIVER */ ret_code = I40E_SUCCESS; /* success! */ goto init_adminq_exit; -#ifdef PF_DRIVER init_adminq_free_arq: i40e_shutdown_arq(hw); -#endif init_adminq_free_asq: i40e_shutdown_asq(hw); init_adminq_destroy_spinlocks: - i40e_destroy_spinlock(&hw->aq.asq_spinlock); - i40e_destroy_spinlock(&hw->aq.arq_spinlock); + i40e_destroy_spinlock(&aq->asq_spinlock); + i40e_destroy_spinlock(&aq->arq_spinlock); init_adminq_exit: return ret_code; @@ -757,7 +795,7 @@ u16 i40e_clean_asq(struct i40e_hw *hw) desc = I40E_ADMINQ_DESC(*asq, ntc); details = I40E_ADMINQ_DETAILS(*asq, ntc); while (rd32(hw, hw->aq.asq.head) != ntc) { - i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, + i40e_debug(hw, I40E_DEBUG_AQ_COMMAND, "ntc %d head %d.\n", ntc, rd32(hw, hw->aq.asq.head)); if (details->callback) { @@ -802,7 +840,7 @@ STATIC bool i40e_asq_done(struct i40e_hw *hw) } /** - * i40e_asq_send_command - send command to Admin Queue + * i40e_asq_send_command_exec - send command to Admin Queue * @hw: pointer to the hw struct * @desc: prefilled descriptor describing the command (non DMA mem) * @buff: buffer to use for indirect commands @@ -812,11 +850,12 @@ STATIC bool i40e_asq_done(struct i40e_hw *hw) * This is the main send command driver routine for the Admin Queue send * queue. It runs the queue, cleans the queue, etc **/ -enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, - struct i40e_aq_desc *desc, - void *buff, /* can be NULL */ - u16 buff_size, - struct i40e_asq_cmd_details *cmd_details) +STATIC enum i40e_status_code +i40e_asq_send_command_exec(struct i40e_hw *hw, + struct i40e_aq_desc *desc, + void *buff, /* can be NULL */ + u16 buff_size, + struct i40e_asq_cmd_details *cmd_details) { enum i40e_status_code status = I40E_SUCCESS; struct i40e_dma_mem *dma_buff = NULL; @@ -826,8 +865,6 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, u16 retval = 0; u32 val = 0; - i40e_acquire_spinlock(&hw->aq.asq_spinlock); - hw->aq.asq_last_status = I40E_AQ_RC_OK; if (hw->aq.asq.count == 0) { @@ -929,7 +966,7 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, } /* bump the tail */ - i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: desc and buffer:\n"); + i40e_debug(hw, I40E_DEBUG_AQ_COMMAND, "AQTX: desc and buffer:\n"); i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc_on_ring, buff, buff_size); (hw->aq.asq.next_to_use)++; @@ -982,7 +1019,7 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval; } - i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, + i40e_debug(hw, I40E_DEBUG_AQ_COMMAND, "AQTX: desc and buffer writeback:\n"); i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, buff_size); @@ -1010,6 +1047,64 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, } asq_send_command_error: + return status; +} + +/** + * i40e_asq_send_command - send command to Admin Queue + * @hw: pointer to the hw struct + * @desc: prefilled descriptor describing the command (non DMA mem) + * @buff: buffer to use for indirect commands + * @buff_size: size of buffer for indirect commands + * @cmd_details: pointer to command details structure + * + * Acquires the lock and calls the main send command execution + * routine. + **/ +enum i40e_status_code +i40e_asq_send_command(struct i40e_hw *hw, + struct i40e_aq_desc *desc, + void *buff, /* can be NULL */ + u16 buff_size, + struct i40e_asq_cmd_details *cmd_details) +{ + enum i40e_status_code status = I40E_SUCCESS; + + i40e_acquire_spinlock(&hw->aq.asq_spinlock); + status = i40e_asq_send_command_exec(hw, desc, buff, buff_size, + cmd_details); + i40e_release_spinlock(&hw->aq.asq_spinlock); + return status; +} + +/** + * i40e_asq_send_command_v2 - send command to Admin Queue + * @hw: pointer to the hw struct + * @desc: prefilled descriptor describing the command (non DMA mem) + * @buff: buffer to use for indirect commands + * @buff_size: size of buffer for indirect commands + * @cmd_details: pointer to command details structure + * @aq_status: pointer to Admin Queue status return value + * + * Acquires the lock and calls the main send command execution + * routine. Returns the last Admin Queue status in aq_status + * to avoid race conditions in access to hw->aq.asq_last_status. + **/ +enum i40e_status_code +i40e_asq_send_command_v2(struct i40e_hw *hw, + struct i40e_aq_desc *desc, + void *buff, /* can be NULL */ + u16 buff_size, + struct i40e_asq_cmd_details *cmd_details, + enum i40e_admin_queue_err *aq_status) +{ + enum i40e_status_code status = I40E_SUCCESS; + + i40e_acquire_spinlock(&hw->aq.asq_spinlock); + status = i40e_asq_send_command_exec(hw, desc, buff, buff_size, + cmd_details); + if (aq_status) + *aq_status = hw->aq.asq_last_status; i40e_release_spinlock(&hw->aq.asq_spinlock); return status; } @@ -1111,7 +1206,7 @@ enum i40e_status_code i40e_clean_arq_element(struct i40e_hw *hw, hw->aq.arq.r.arq_bi[desc_idx].va, e->msg_len, I40E_DMA_TO_NONDMA); - i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n"); + i40e_debug(hw, I40E_DEBUG_AQ_COMMAND, "AQRX: desc and buffer:\n"); i40e_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf, hw->aq.arq_buf_size); diff --git a/drivers/net/i40e/base/i40e_adminq_cmd.h b/drivers/net/i40e/base/i40e_adminq_cmd.h index 3d56d12fe8..def307b59d 100644 --- a/drivers/net/i40e/base/i40e_adminq_cmd.h +++ b/drivers/net/i40e/base/i40e_adminq_cmd.h @@ -12,8 +12,8 @@ */ #define I40E_FW_API_VERSION_MAJOR 0x0001 -#define I40E_FW_API_VERSION_MINOR_X722 0x0006 -#define I40E_FW_API_VERSION_MINOR_X710 0x0007 +#define I40E_FW_API_VERSION_MINOR_X722 0x000C +#define I40E_FW_API_VERSION_MINOR_X710 0x000F #define I40E_FW_MINOR_VERSION(_h) ((_h)->mac.type == I40E_MAC_XL710 ? \ I40E_FW_API_VERSION_MINOR_X710 : \ @@ -21,8 +21,12 @@ /* API version 1.7 implements additional link and PHY-specific APIs */ #define I40E_MINOR_VER_GET_LINK_INFO_XL710 0x0007 +/* API version 1.9 for X722 implements additional link and PHY-specific APIs */ +#define I40E_MINOR_VER_GET_LINK_INFO_X722 0x0009 /* API version 1.6 for X722 devices adds ability to stop FW LLDP agent */ #define I40E_MINOR_VER_FW_LLDP_STOPPABLE_X722 0x0006 +/* API version 1.10 for X722 devices adds ability to request FEC encoding */ +#define I40E_MINOR_VER_FW_REQUEST_FEC_X722 0x000A struct i40e_aq_desc { __le16 flags; @@ -236,7 +240,8 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_nvm_update = 0x0703, i40e_aqc_opc_nvm_config_read = 0x0704, i40e_aqc_opc_nvm_config_write = 0x0705, - i40e_aqc_opc_nvm_progress = 0x0706, + i40e_aqc_opc_nvm_update_in_process = 0x0706, + i40e_aqc_opc_rollback_revision_update = 0x0707, i40e_aqc_opc_oem_post_update = 0x0720, i40e_aqc_opc_thermal_sensor = 0x0721, @@ -265,6 +270,7 @@ enum i40e_admin_queue_opc { i40e_aqc_opc_get_cee_dcb_cfg = 0x0A07, i40e_aqc_opc_lldp_set_local_mib = 0x0A08, i40e_aqc_opc_lldp_stop_start_spec_agent = 0x0A09, + i40e_aqc_opc_lldp_restore = 0x0A0A, /* Tunnel commands */ i40e_aqc_opc_add_udp_tunnel = 0x0B00, @@ -435,6 +441,7 @@ struct i40e_aqc_list_capabilities_element_resp { #define I40E_AQ_CAP_ID_SDP 0x0062 #define I40E_AQ_CAP_ID_MDIO 0x0063 #define I40E_AQ_CAP_ID_WSR_PROT 0x0064 +#define I40E_AQ_CAP_ID_DIS_UNUSED_PORTS 0x0067 #define I40E_AQ_CAP_ID_NVM_MGMT 0x0080 #define I40E_AQ_CAP_ID_FLEX10 0x00F1 #define I40E_AQ_CAP_ID_CEM 0x00F2 @@ -761,6 +768,7 @@ struct i40e_aqc_set_switch_config { #define I40E_AQ_SET_SWITCH_CFG_PROMISC 0x0001 #define I40E_AQ_SET_SWITCH_CFG_L2_FILTER 0x0002 #define I40E_AQ_SET_SWITCH_CFG_HW_ATR_EVICT 0x0004 +#define I40E_AQ_SET_SWITCH_CFG_OUTER_VLAN 0x0008 __le16 valid_flags; /* The ethertype in switch_tag is dropped on ingress and used * internally by the switch. Set this to zero for the default @@ -897,7 +905,7 @@ struct i40e_aqc_vsi_properties_data { u8 sec_reserved; /* VLAN section */ __le16 pvid; /* VLANS include priority bits */ - __le16 fcoe_pvid; + __le16 outer_vlan; u8 port_vlan_flags; #define I40E_AQ_VSI_PVLAN_MODE_SHIFT 0x00 #define I40E_AQ_VSI_PVLAN_MODE_MASK (0x03 << \ @@ -913,7 +921,24 @@ struct i40e_aqc_vsi_properties_data { #define I40E_AQ_VSI_PVLAN_EMOD_STR_UP 0x08 #define I40E_AQ_VSI_PVLAN_EMOD_STR 0x10 #define I40E_AQ_VSI_PVLAN_EMOD_NOTHING 0x18 - u8 pvlan_reserved[3]; + u8 outer_vlan_flags; +#define I40E_AQ_VSI_OVLAN_MODE_SHIFT 0x00 +#define I40E_AQ_VSI_OVLAN_MODE_MASK (0x03 << \ + I40E_AQ_VSI_OVLAN_MODE_SHIFT) +#define I40E_AQ_VSI_OVLAN_MODE_UNTAGGED 0x01 +#define I40E_AQ_VSI_OVLAN_MODE_TAGGED 0x02 +#define I40E_AQ_VSI_OVLAN_MODE_ALL 0x03 +#define I40E_AQ_VSI_OVLAN_INSERT_PVID 0x04 +#define I40E_AQ_VSI_OVLAN_EMOD_SHIFT 0x03 +#define I40E_AQ_VSI_OVLAN_EMOD_MASK (0x03 <<\ + I40E_AQ_VSI_OVLAN_EMOD_SHIFT) +#define I40E_AQ_VSI_OVLAN_EMOD_SHOW_ALL 0x00 +#define I40E_AQ_VSI_OVLAN_EMOD_SHOW_UP 0x01 +#define I40E_AQ_VSI_OVLAN_EMOD_HIDE_ALL 0x02 +#define I40E_AQ_VSI_OVLAN_EMOD_NOTHING 0x03 +#define I40E_AQ_VSI_OVLAN_CTRL_ENA 0x04 + + u8 pvlan_reserved[2]; /* ingress egress up sections */ __le32 ingress_table; /* bitmap, 3 bits per up */ #define I40E_AQ_VSI_UP_TABLE_UP0_SHIFT 0 @@ -1401,6 +1426,11 @@ struct i40e_aqc_cloud_filters_element_data { #define I40E_AQC_ADD_CLOUD_FILTER_IMAC 0x000A #define I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC 0x000B #define I40E_AQC_ADD_CLOUD_FILTER_IIP 0x000C +#define I40E_AQC_ADD_CLOUD_FILTER_OIP1 0x0010 +#define I40E_AQC_ADD_CLOUD_FILTER_OIP2 0x0012 +/* 0x000D reserved */ +/* 0x000E reserved */ +/* 0x000F reserved */ /* 0x0010 to 0x0017 is for custom filters */ #define I40E_AQC_ADD_CLOUD_FILTER_IP_PORT 0x0010 /* Dest IP + L4 Port */ #define I40E_AQC_ADD_CLOUD_FILTER_MAC_PORT 0x0011 /* Dest MAC + L4 Port */ @@ -2005,6 +2035,15 @@ enum i40e_aq_link_speed { I40E_LINK_SPEED_25GB = (1 << I40E_LINK_SPEED_25GB_SHIFT), }; +enum i40e_prt_mac_pcs_link_speed { + I40E_PRT_MAC_PCS_LINK_SPEED_UNKNOWN = 0, + I40E_PRT_MAC_PCS_LINK_SPEED_100MB, + I40E_PRT_MAC_PCS_LINK_SPEED_1GB, + I40E_PRT_MAC_PCS_LINK_SPEED_10GB, + I40E_PRT_MAC_PCS_LINK_SPEED_40GB, + I40E_PRT_MAC_PCS_LINK_SPEED_20GB +}; + struct i40e_aqc_module_desc { u8 oui[3]; u8 reserved1; @@ -2028,12 +2067,15 @@ struct i40e_aq_get_phy_abilities_resp { #define I40E_AQ_PHY_FEC_ABILITY_KR 0x40 #define I40E_AQ_PHY_FEC_ABILITY_RS 0x80 __le16 eee_capability; +#define I40E_AQ_EEE_AUTO 0x0001 #define I40E_AQ_EEE_100BASE_TX 0x0002 #define I40E_AQ_EEE_1000BASE_T 0x0004 #define I40E_AQ_EEE_10GBASE_T 0x0008 #define I40E_AQ_EEE_1000BASE_KX 0x0010 #define I40E_AQ_EEE_10GBASE_KX4 0x0020 #define I40E_AQ_EEE_10GBASE_KR 0x0040 +#define I40E_AQ_EEE_2_5GBASE_T 0x0100 +#define I40E_AQ_EEE_5GBASE_T 0x0200 __le32 eeer_val; u8 d3_lpan; #define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01 @@ -2096,20 +2138,21 @@ I40E_CHECK_CMD_LENGTH(i40e_aq_set_phy_config); struct i40e_aq_set_mac_config { __le16 max_frame_size; u8 params; -#define I40E_AQ_SET_MAC_CONFIG_CRC_EN 0x04 -#define I40E_AQ_SET_MAC_CONFIG_PACING_MASK 0x78 -#define I40E_AQ_SET_MAC_CONFIG_PACING_SHIFT 3 -#define I40E_AQ_SET_MAC_CONFIG_PACING_NONE 0x0 -#define I40E_AQ_SET_MAC_CONFIG_PACING_1B_13TX 0xF -#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_9TX 0x9 -#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_4TX 0x8 -#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_7TX 0x7 -#define I40E_AQ_SET_MAC_CONFIG_PACING_2DW_3TX 0x6 -#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_1TX 0x5 -#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_2TX 0x4 -#define I40E_AQ_SET_MAC_CONFIG_PACING_7DW_3TX 0x3 -#define I40E_AQ_SET_MAC_CONFIG_PACING_4DW_1TX 0x2 -#define I40E_AQ_SET_MAC_CONFIG_PACING_9DW_1TX 0x1 +#define I40E_AQ_SET_MAC_CONFIG_CRC_EN 0x04 +#define I40E_AQ_SET_MAC_CONFIG_PACING_MASK 0x78 +#define I40E_AQ_SET_MAC_CONFIG_PACING_SHIFT 3 +#define I40E_AQ_SET_MAC_CONFIG_PACING_NONE 0x0 +#define I40E_AQ_SET_MAC_CONFIG_PACING_1B_13TX 0xF +#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_9TX 0x9 +#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_4TX 0x8 +#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_7TX 0x7 +#define I40E_AQ_SET_MAC_CONFIG_PACING_2DW_3TX 0x6 +#define I40E_AQ_SET_MAC_CONFIG_PACING_1DW_1TX 0x5 +#define I40E_AQ_SET_MAC_CONFIG_PACING_3DW_2TX 0x4 +#define I40E_AQ_SET_MAC_CONFIG_PACING_7DW_3TX 0x3 +#define I40E_AQ_SET_MAC_CONFIG_PACING_4DW_1TX 0x2 +#define I40E_AQ_SET_MAC_CONFIG_PACING_9DW_1TX 0x1 +#define I40E_AQ_SET_MAC_CONFIG_DROP_BLOCKING_PACKET_EN 0x80 u8 tx_timer_priority; /* bitmap */ __le16 tx_timer_value; __le16 fc_refresh_threshold; @@ -2270,15 +2313,32 @@ enum i40e_aq_phy_reg_type { I40E_AQC_PHY_REG_EXERNAL_MODULE = 0x3 }; +#pragma pack(1) /* Run PHY Activity (0x0626) */ struct i40e_aqc_run_phy_activity { - __le16 activity_id; - u8 flags; - u8 reserved1; - __le32 control; - __le32 data; - u8 reserved2[4]; + u8 cmd_flags; + __le16 activity_id; +#define I40E_AQ_RUN_PHY_ACT_ID_USR_DFND 0x10 + u8 reserved; + union { + struct { + __le32 dnl_opcode; +#define I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR 0x801a +#define I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT 0x801b +#define I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR 0x1801b + __le32 data; + u8 reserved2[4]; + } cmd; + struct { + __le32 cmd_status; +#define I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC 0x4 +#define I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK 0xFFFF + __le32 data0; + __le32 data1; + } resp; + } params; }; +#pragma pack() I40E_CHECK_CMD_LENGTH(i40e_aqc_run_phy_activity); @@ -2291,7 +2351,11 @@ struct i40e_aqc_phy_register_access { #define I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE 2 u8 dev_addres; u8 cmd_flags; -#define I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE 1 +#define I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE 0x01 +#define I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER 0x02 +#define I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT 2 +#define I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK (0x3 << \ + I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT) u8 reserved1; __le32 reg_address; __le32 reg_value; @@ -2366,6 +2430,16 @@ struct i40e_aqc_nvm_config_data_feature { I40E_CHECK_STRUCT_LEN(0x6, i40e_aqc_nvm_config_data_feature); +/* NVM Update in Process (direct 0x0706) */ +struct i40e_aqc_nvm_update_in_process { + u8 command; +#define I40E_AQ_UPDATE_FLOW_END 0x0 +#define I40E_AQ_UPDATE_FLOW_START 0x1 + u8 reserved[15]; +}; + +I40E_CHECK_CMD_LENGTH(i40e_aqc_nvm_update_in_process); + struct i40e_aqc_nvm_config_data_immediate_field { __le32 field_id; __le32 field_value; @@ -2375,6 +2449,27 @@ struct i40e_aqc_nvm_config_data_immediate_field { I40E_CHECK_STRUCT_LEN(0xc, i40e_aqc_nvm_config_data_immediate_field); +/* Minimal Rollback Revision Update (direct 0x0707) */ +struct i40e_aqc_rollback_revision_update { + u8 optin_mode; /* bool */ +#define I40E_AQ_RREV_OPTION_MODE 0x01 + u8 module_selected; +#define I40E_AQ_RREV_MODULE_PCIE_ANALOG 0 +#define I40E_AQ_RREV_MODULE_PHY_ANALOG 1 +#define I40E_AQ_RREV_MODULE_OPTION_ROM 2 +#define I40E_AQ_RREV_MODULE_EMP_IMAGE 3 +#define I40E_AQ_RREV_MODULE_PE_IMAGE 4 +#define I40E_AQ_RREV_MODULE_PHY_PLL_O_CONFIGURATION 5 +#define I40E_AQ_RREV_MODULE_PHY_0_CONFIGURATION 6 +#define I40E_AQ_RREV_MODULE_PHY_PLL_1_CONFIGURATION 7 +#define I40E_AQ_RREV_MODULE_PHY_1_CONFIGURATION 8 + u8 reserved1[2]; + u32 min_rrev; + u8 reserved2[8]; +}; + +I40E_CHECK_CMD_LENGTH(i40e_aqc_rollback_revision_update); + /* OEM Post Update (indirect 0x0720) * no command data struct used */ @@ -2556,8 +2651,9 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_update_tlv); /* Stop LLDP (direct 0x0A05) */ struct i40e_aqc_lldp_stop { u8 command; -#define I40E_AQ_LLDP_AGENT_STOP 0x0 -#define I40E_AQ_LLDP_AGENT_SHUTDOWN 0x1 +#define I40E_AQ_LLDP_AGENT_STOP 0x0 +#define I40E_AQ_LLDP_AGENT_SHUTDOWN 0x1 +#define I40E_AQ_LLDP_AGENT_STOP_PERSIST 0x2 u8 reserved[15]; }; @@ -2567,7 +2663,8 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop); struct i40e_aqc_lldp_start { u8 command; -#define I40E_AQ_LLDP_AGENT_START 0x1 +#define I40E_AQ_LLDP_AGENT_START 0x1 +#define I40E_AQ_LLDP_AGENT_START_PERSIST 0x2 u8 reserved[15]; }; @@ -2687,6 +2784,16 @@ struct i40e_aqc_lldp_stop_start_specific_agent { I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_stop_start_specific_agent); +/* Restore LLDP Agent factory settings (direct 0x0A0A) */ +struct i40e_aqc_lldp_restore { + u8 command; +#define I40E_AQ_LLDP_AGENT_RESTORE_NOT 0x0 +#define I40E_AQ_LLDP_AGENT_RESTORE 0x1 + u8 reserved[15]; +}; + +I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_restore); + /* Add Udp Tunnel command and completion (direct 0x0B00) */ struct i40e_aqc_add_udp_tunnel { __le16 udp_port; diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c index 6099ebe571..06608b324e 100644 --- a/drivers/net/i40e/base/i40e_common.c +++ b/drivers/net/i40e/base/i40e_common.c @@ -16,11 +16,7 @@ * This function sets the mac type of the adapter based on the * vendor ID and device ID stored in the hw structure. **/ -#if defined(INTEGRATED_VF) || defined(VF_DRIVER) enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw) -#else -STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw) -#endif { enum i40e_status_code status = I40E_SUCCESS; @@ -38,6 +34,10 @@ STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw) case I40E_DEV_ID_10G_BASE_T: case I40E_DEV_ID_10G_BASE_T4: case I40E_DEV_ID_10G_BASE_T_BC: + case I40E_DEV_ID_10G_B: + case I40E_DEV_ID_10G_SFP: + case I40E_DEV_ID_5G_BASE_T_BC: + case I40E_DEV_ID_1G_BASE_T_BC: case I40E_DEV_ID_20G_KR2: case I40E_DEV_ID_20G_KR2_A: case I40E_DEV_ID_25G_B: @@ -55,6 +55,7 @@ STATIC enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw) case I40E_DEV_ID_1G_BASE_T_X722: case I40E_DEV_ID_10G_BASE_T_X722: case I40E_DEV_ID_SFP_I_X722: + case I40E_DEV_ID_SFP_X722_A: hw->mac.type = I40E_MAC_X722; break; #if defined(INTEGRATED_VF) || defined(VF_DRIVER) @@ -177,8 +178,8 @@ const char *i40e_stat_str(struct i40e_hw *hw, enum i40e_status_code stat_err) return "I40E_ERR_INVALID_MAC_ADDR"; case I40E_ERR_DEVICE_NOT_SUPPORTED: return "I40E_ERR_DEVICE_NOT_SUPPORTED"; - case I40E_ERR_MASTER_REQUESTS_PENDING: - return "I40E_ERR_MASTER_REQUESTS_PENDING"; + case I40E_ERR_PRIMARY_REQUESTS_PENDING: + return "I40E_ERR_PRIMARY_REQUESTS_PENDING"; case I40E_ERR_INVALID_LINK_SETTINGS: return "I40E_ERR_INVALID_LINK_SETTINGS"; case I40E_ERR_AUTONEG_NOT_COMPLETE: @@ -307,32 +308,37 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc, void *buffer, u16 buf_len) { struct i40e_aq_desc *aq_desc = (struct i40e_aq_desc *)desc; + u32 effective_mask = hw->debug_mask & mask; u8 *buf = (u8 *)buffer; u16 len; - u16 i = 0; + u16 i; - if ((!(mask & hw->debug_mask)) || (desc == NULL)) + if (!effective_mask || !desc) return; len = LE16_TO_CPU(aq_desc->datalen); - i40e_debug(hw, mask, + i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR, "AQ CMD: opcode 0x%04X, flags 0x%04X, datalen 0x%04X, retval 0x%04X\n", LE16_TO_CPU(aq_desc->opcode), LE16_TO_CPU(aq_desc->flags), LE16_TO_CPU(aq_desc->datalen), LE16_TO_CPU(aq_desc->retval)); - i40e_debug(hw, mask, "\tcookie (h,l) 0x%08X 0x%08X\n", + i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR, + "\tcookie (h,l) 0x%08X 0x%08X\n", LE32_TO_CPU(aq_desc->cookie_high), LE32_TO_CPU(aq_desc->cookie_low)); - i40e_debug(hw, mask, "\tparam (0,1) 0x%08X 0x%08X\n", + i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR, + "\tparam (0,1) 0x%08X 0x%08X\n", LE32_TO_CPU(aq_desc->params.internal.param0), LE32_TO_CPU(aq_desc->params.internal.param1)); - i40e_debug(hw, mask, "\taddr (h,l) 0x%08X 0x%08X\n", + i40e_debug(hw, mask & I40E_DEBUG_AQ_DESCRIPTOR, + "\taddr (h,l) 0x%08X 0x%08X\n", LE32_TO_CPU(aq_desc->params.external.addr_high), LE32_TO_CPU(aq_desc->params.external.addr_low)); - if ((buffer != NULL) && (aq_desc->datalen != 0)) { + if (buffer && buf_len != 0 && len != 0 && + (effective_mask & I40E_DEBUG_AQ_DESC_BUFFER)) { i40e_debug(hw, mask, "AQ CMD Buffer:\n"); if (buf_len < len) len = buf_len; @@ -1016,6 +1022,17 @@ enum i40e_status_code i40e_init_shared_code(struct i40e_hw *hw) if (hw->mac.type == I40E_MAC_X722) hw->flags |= I40E_HW_FLAG_AQ_SRCTL_ACCESS_ENABLE | I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK; + /* NVMUpdate features structure initialization */ + hw->nvmupd_features.major = I40E_NVMUPD_FEATURES_API_VER_MAJOR; + hw->nvmupd_features.minor = I40E_NVMUPD_FEATURES_API_VER_MINOR; + hw->nvmupd_features.size = sizeof(hw->nvmupd_features); + i40e_memset(hw->nvmupd_features.features, 0x0, + I40E_NVMUPD_FEATURES_API_FEATURES_ARRAY_LEN * + sizeof(*hw->nvmupd_features.features), + I40E_NONDMA_MEM); + + /* No features supported at the moment */ + hw->nvmupd_features.features[0] = 0; status = i40e_init_nvm(hw); return status; @@ -1532,9 +1549,9 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx) u32 gpio_val = 0; u32 port; - if (!hw->func_caps.led[idx]) + if (!I40E_IS_X710TL_DEVICE(hw->device_id) && + !hw->func_caps.led[idx]) return 0; - gpio_val = rd32(hw, I40E_GLGEN_GPIO_CTL(idx)); port = (gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK) >> I40E_GLGEN_GPIO_CTL_PRT_NUM_SHIFT; @@ -1553,8 +1570,15 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx) #define I40E_FILTER_ACTIVITY 0xE #define I40E_LINK_ACTIVITY 0xC #define I40E_MAC_ACTIVITY 0xD +#define I40E_FW_LED BIT(4) +#define I40E_LED_MODE_VALID (I40E_GLGEN_GPIO_CTL_LED_MODE_MASK >> \ + I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) + #define I40E_LED0 22 +#define I40E_PIN_FUNC_SDP 0x0 +#define I40E_PIN_FUNC_LED 0x1 + /** * i40e_led_get - return current on/off mode * @hw: pointer to the hw struct @@ -1602,6 +1626,35 @@ u32 i40e_led_get(struct i40e_hw *hw) return mode; } +/** + * i40e_led_get_blink - return current LED blink setting + * @hw: pointer to the hw struct + * + * The value returned is the LED_BLINK bit as defined in the + * GPIO register definitions (0 = no blink, 1 = do blink). + **/ +bool i40e_led_get_blink(struct i40e_hw *hw) +{ + bool blink = 0; + int i; + + /* as per the documentation GPIO 22-29 are the LED + * GPIO pins named LED0..LED7 + */ + for (i = I40E_LED0; i <= I40E_GLGEN_GPIO_CTL_MAX_INDEX; i++) { + u32 gpio_val = i40e_led_is_mine(hw, i); + + if (!gpio_val) + continue; + + blink = (gpio_val & I40E_GLGEN_GPIO_CTL_LED_BLINK_MASK) >> + I40E_GLGEN_GPIO_CTL_LED_BLINK_SHIFT; + break; + } + + return blink; +} + /** * i40e_led_set - set new on/off mode * @hw: pointer to the hw struct @@ -1616,8 +1669,10 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink) u32 current_mode = 0; int i; - if (mode & 0xfffffff0) + if (mode & ~I40E_LED_MODE_VALID) { DEBUGOUT1("invalid mode passed in %X\n", mode); + return; + } /* as per the documentation GPIO 22-29 are the LED * GPIO pins named LED0..LED7 @@ -1643,6 +1698,19 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink) break; } + if (I40E_IS_X710TL_DEVICE(hw->device_id)) { + u32 pin_func = 0; + + if (mode & I40E_FW_LED) + pin_func = I40E_PIN_FUNC_SDP; + else + pin_func = I40E_PIN_FUNC_LED; + + gpio_val &= ~I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK; + gpio_val |= ((pin_func << + I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT) & + I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK); + } gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK; /* this & is a bit of paranoia, but serves as a range check */ gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) & @@ -1860,6 +1928,7 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures, * @max_frame_size: Maximum Frame Size to be supported by the port * @crc_en: Tell HW to append a CRC to outgoing frames * @pacing: Pacing configurations + * @auto_drop_blocking_packets: Tell HW to drop packets if TC queue is blocked * @cmd_details: pointer to command details structure or NULL * * Configure MAC settings for frame size, jumbo frame support and the @@ -1868,6 +1937,7 @@ enum i40e_status_code i40e_set_fc(struct i40e_hw *hw, u8 *aq_failures, enum i40e_status_code i40e_aq_set_mac_config(struct i40e_hw *hw, u16 max_frame_size, bool crc_en, u16 pacing, + bool auto_drop_blocking_packets, struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; @@ -1886,6 +1956,15 @@ enum i40e_status_code i40e_aq_set_mac_config(struct i40e_hw *hw, if (crc_en) cmd->params |= I40E_AQ_SET_MAC_CONFIG_CRC_EN; + if (auto_drop_blocking_packets) { + if (hw->flags & I40E_HW_FLAG_DROP_MODE) + cmd->params |= + I40E_AQ_SET_MAC_CONFIG_DROP_BLOCKING_PACKET_EN; + else + i40e_debug(hw, I40E_DEBUG_ALL, + "This FW api version does not support drop mode.\n"); + } + #define I40E_AQ_SET_MAC_CONFIG_FC_DEFAULT_THRESHOLD 0x7FFF cmd->fc_refresh_threshold = CPU_TO_LE16(I40E_AQ_SET_MAC_CONFIG_FC_DEFAULT_THRESHOLD); @@ -3072,6 +3151,46 @@ enum i40e_status_code i40e_aq_get_veb_parameters(struct i40e_hw *hw, return status; } +/** + * i40e_prepare_add_macvlan + * @mv_list: list of macvlans to be added + * @desc: pointer to AQ descriptor structure + * @count: length of the list + * @seid: VSI for the mac address + * + * Internal helper function that prepares the add macvlan request + * and returns the buffer size. + **/ +static u16 +i40e_prepare_add_macvlan(struct i40e_aqc_add_macvlan_element_data *mv_list, + struct i40e_aq_desc *desc, u16 count, u16 seid) +{ + struct i40e_aqc_macvlan *cmd = + (struct i40e_aqc_macvlan *)&desc->params.raw; + u16 buf_size; + int i; + + buf_size = count * sizeof(*mv_list); + + /* prep the rest of the request */ + i40e_fill_default_direct_cmd_desc(desc, i40e_aqc_opc_add_macvlan); + cmd->num_addresses = CPU_TO_LE16(count); + cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid); + cmd->seid[1] = 0; + cmd->seid[2] = 0; + + for (i = 0; i < count; i++) + if (I40E_IS_MULTICAST(mv_list[i].mac_addr)) + mv_list[i].flags |= + CPU_TO_LE16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC); + + desc->flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); + if (buf_size > I40E_AQ_LARGE_BUF) + desc->flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB); + + return buf_size; +} + /** * i40e_aq_add_macvlan * @hw: pointer to the hw struct @@ -3082,8 +3201,74 @@ enum i40e_status_code i40e_aq_get_veb_parameters(struct i40e_hw *hw, * * Add MAC/VLAN addresses to the HW filtering **/ -enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid, - struct i40e_aqc_add_macvlan_element_data *mv_list, +enum i40e_status_code +i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid, + struct i40e_aqc_add_macvlan_element_data *mv_list, + u16 count, struct i40e_asq_cmd_details *cmd_details) +{ + struct i40e_aq_desc desc; + enum i40e_status_code status; + u16 buf_size; + + if (count == 0 || !mv_list || !hw) + return I40E_ERR_PARAM; + + buf_size = i40e_prepare_add_macvlan(mv_list, &desc, count, seid); + + status = i40e_asq_send_command(hw, &desc, mv_list, buf_size, + cmd_details); + + return status; +} + +/** + * i40e_aq_add_macvlan_v2 + * @hw: pointer to the hw struct + * @seid: VSI for the mac address + * @mv_list: list of macvlans to be added + * @count: length of the list + * @cmd_details: pointer to command details structure or NULL + * @aq_status: pointer to Admin Queue status return value + * + * Add MAC/VLAN addresses to the HW filtering. + * The _v2 version returns the last Admin Queue status in aq_status + * to avoid race conditions in access to hw->aq.asq_last_status. + * It also calls _v2 versions of asq_send_command functions to + * get the aq_status on the stack. + **/ +enum i40e_status_code +i40e_aq_add_macvlan_v2(struct i40e_hw *hw, u16 seid, + struct i40e_aqc_add_macvlan_element_data *mv_list, + u16 count, struct i40e_asq_cmd_details *cmd_details, + enum i40e_admin_queue_err *aq_status) +{ + struct i40e_aq_desc desc; + enum i40e_status_code status; + u16 buf_size; + + if (count == 0 || !mv_list || !hw) + return I40E_ERR_PARAM; + + buf_size = i40e_prepare_add_macvlan(mv_list, &desc, count, seid); + + status = i40e_asq_send_command_v2(hw, &desc, mv_list, buf_size, + cmd_details, aq_status); + + return status; +} + +/** + * i40e_aq_remove_macvlan + * @hw: pointer to the hw struct + * @seid: VSI for the mac address + * @mv_list: list of macvlans to be removed + * @count: length of the list + * @cmd_details: pointer to command details structure or NULL + * + * Remove MAC/VLAN addresses from the HW filtering + **/ +enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid, + struct i40e_aqc_remove_macvlan_element_data *mv_list, u16 count, struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; @@ -3091,7 +3276,6 @@ enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid, (struct i40e_aqc_macvlan *)&desc.params.raw; enum i40e_status_code status; u16 buf_size; - int i; if (count == 0 || !mv_list || !hw) return I40E_ERR_PARAM; @@ -3099,17 +3283,12 @@ enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid, buf_size = count * sizeof(*mv_list); /* prep the rest of the request */ - i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_add_macvlan); + i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_remove_macvlan); cmd->num_addresses = CPU_TO_LE16(count); cmd->seid[0] = CPU_TO_LE16(I40E_AQC_MACVLAN_CMD_SEID_VALID | seid); cmd->seid[1] = 0; cmd->seid[2] = 0; - for (i = 0; i < count; i++) - if (I40E_IS_MULTICAST(mv_list[i].mac_addr)) - mv_list[i].flags |= - CPU_TO_LE16(I40E_AQC_MACVLAN_ADD_USE_SHARED_MAC); - desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); if (buf_size > I40E_AQ_LARGE_BUF) desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB); @@ -3121,18 +3300,25 @@ enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 seid, } /** - * i40e_aq_remove_macvlan + * i40e_aq_remove_macvlan_v2 * @hw: pointer to the hw struct * @seid: VSI for the mac address * @mv_list: list of macvlans to be removed * @count: length of the list * @cmd_details: pointer to command details structure or NULL + * @aq_status: pointer to Admin Queue status return value * - * Remove MAC/VLAN addresses from the HW filtering + * Remove MAC/VLAN addresses from the HW filtering. + * The _v2 version returns the last Admin Queue status in aq_status + * to avoid race conditions in access to hw->aq.asq_last_status. + * It also calls _v2 versions of asq_send_command functions to + * get the aq_status on the stack. **/ -enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid, - struct i40e_aqc_remove_macvlan_element_data *mv_list, - u16 count, struct i40e_asq_cmd_details *cmd_details) +enum i40e_status_code +i40e_aq_remove_macvlan_v2(struct i40e_hw *hw, u16 seid, + struct i40e_aqc_remove_macvlan_element_data *mv_list, + u16 count, struct i40e_asq_cmd_details *cmd_details, + enum i40e_admin_queue_err *aq_status) { struct i40e_aq_desc desc; struct i40e_aqc_macvlan *cmd = @@ -3156,8 +3342,8 @@ enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 seid, if (buf_size > I40E_AQ_LARGE_BUF) desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB); - status = i40e_asq_send_command(hw, &desc, mv_list, buf_size, - cmd_details); + status = i40e_asq_send_command_v2(hw, &desc, mv_list, buf_size, + cmd_details, aq_status); return status; } @@ -3666,6 +3852,66 @@ enum i40e_status_code i40e_aq_write_nvm_config(struct i40e_hw *hw, return status; } +/** + * i40e_aq_nvm_update_in_process + * @hw: pointer to the hw struct + * @update_flow_state: True indicates that update flow starts, false that ends + * @cmd_details: pointer to command details structure or NULL + * + * Indicate NVM update in process. + **/ +enum i40e_status_code +i40e_aq_nvm_update_in_process(struct i40e_hw *hw, + bool update_flow_state, + struct i40e_asq_cmd_details *cmd_details) +{ + struct i40e_aq_desc desc; + struct i40e_aqc_nvm_update_in_process *cmd = + (struct i40e_aqc_nvm_update_in_process *)&desc.params.raw; + enum i40e_status_code status; + + i40e_fill_default_direct_cmd_desc(&desc, + i40e_aqc_opc_nvm_update_in_process); + + cmd->command = I40E_AQ_UPDATE_FLOW_END; + + if (update_flow_state) + cmd->command |= I40E_AQ_UPDATE_FLOW_START; + + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); + + return status; +} + +/** + * i40e_aq_min_rollback_rev_update - triggers an ow after update + * @hw: pointer to the hw struct + * @mode: opt-in mode, 1b for single module update, 0b for bulk update + * @module: module to be updated. Ignored if mode is 0b + * @min_rrev: value of the new minimal version. Ignored if mode is 0b + * @cmd_details: pointer to command details structure or NULL + **/ +enum i40e_status_code +i40e_aq_min_rollback_rev_update(struct i40e_hw *hw, u8 mode, u8 module, + u32 min_rrev, + struct i40e_asq_cmd_details *cmd_details) +{ + struct i40e_aq_desc desc; + struct i40e_aqc_rollback_revision_update *cmd = + (struct i40e_aqc_rollback_revision_update *)&desc.params.raw; + enum i40e_status_code status; + + i40e_fill_default_direct_cmd_desc(&desc, + i40e_aqc_opc_rollback_revision_update); + cmd->optin_mode = mode; + cmd->module_selected = module; + cmd->min_rrev = min_rrev; + + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); + + return status; +} + /** * i40e_aq_oem_post_update - triggers an OEM specific flow after update * @hw: pointer to the hw struct @@ -4001,6 +4247,12 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff, "HW Capability: wr_csr_prot = 0x%" PRIX64 "\n\n", (p->wr_csr_prot & 0xffff)); break; + case I40E_AQ_CAP_ID_DIS_UNUSED_PORTS: + p->dis_unused_ports = (bool)number; + i40e_debug(hw, I40E_DEBUG_INIT, + "HW Capability: dis_unused_ports = %d\n\n", + p->dis_unused_ports); + break; case I40E_AQ_CAP_ID_NVM_MGMT: if (number & I40E_NVM_MGMT_SEC_REV_DISABLED) p->sec_rev_disabled = true; @@ -4231,28 +4483,6 @@ enum i40e_status_code i40e_aq_rearrange_nvm(struct i40e_hw *hw, return status; } -/** - * i40e_aq_nvm_progress - * @hw: pointer to the hw struct - * @progress: pointer to progress returned from AQ - * @cmd_details: pointer to command details structure or NULL - * - * Gets progress of flash rearrangement process - **/ -enum i40e_status_code i40e_aq_nvm_progress(struct i40e_hw *hw, u8 *progress, - struct i40e_asq_cmd_details *cmd_details) -{ - enum i40e_status_code status; - struct i40e_aq_desc desc; - - DEBUGFUNC("i40e_aq_nvm_progress"); - - i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_nvm_progress); - status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); - *progress = desc.params.raw[0]; - return status; -} - /** * i40e_aq_get_lldp_mib * @hw: pointer to the hw struct @@ -4374,151 +4604,39 @@ enum i40e_status_code i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw, } /** - * i40e_aq_add_lldp_tlv + * i40e_aq_restore_lldp * @hw: pointer to the hw struct - * @bridge_type: type of bridge - * @buff: buffer with TLV to add - * @buff_size: length of the buffer - * @tlv_len: length of the TLV to be added - * @mib_len: length of the LLDP MIB returned in response + * @setting: pointer to factory setting variable or NULL + * @restore: True if factory settings should be restored * @cmd_details: pointer to command details structure or NULL * - * Add the specified TLV to LLDP Local MIB for the given bridge type, - * it is responsibility of the caller to make sure that the TLV is not - * already present in the LLDPDU. - * In return firmware will write the complete LLDP MIB with the newly - * added TLV in the response buffer. + * Restore LLDP Agent factory settings if @restore set to True. In other case + * only returns factory setting in AQ response. **/ -enum i40e_status_code i40e_aq_add_lldp_tlv(struct i40e_hw *hw, u8 bridge_type, - void *buff, u16 buff_size, u16 tlv_len, - u16 *mib_len, - struct i40e_asq_cmd_details *cmd_details) -{ - struct i40e_aq_desc desc; - struct i40e_aqc_lldp_add_tlv *cmd = - (struct i40e_aqc_lldp_add_tlv *)&desc.params.raw; - enum i40e_status_code status; - - if (buff_size == 0 || !buff || tlv_len == 0) - return I40E_ERR_PARAM; - - i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_add_tlv); - - /* Indirect Command */ - desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); - if (buff_size > I40E_AQ_LARGE_BUF) - desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB); - desc.datalen = CPU_TO_LE16(buff_size); - - cmd->type = ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) & - I40E_AQ_LLDP_BRIDGE_TYPE_MASK); - cmd->len = CPU_TO_LE16(tlv_len); - - status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details); - if (!status) { - if (mib_len != NULL) - *mib_len = LE16_TO_CPU(desc.datalen); - } - - return status; -} - -/** - * i40e_aq_update_lldp_tlv - * @hw: pointer to the hw struct - * @bridge_type: type of bridge - * @buff: buffer with TLV to update - * @buff_size: size of the buffer holding original and updated TLVs - * @old_len: Length of the Original TLV - * @new_len: Length of the Updated TLV - * @offset: offset of the updated TLV in the buff - * @mib_len: length of the returned LLDP MIB - * @cmd_details: pointer to command details structure or NULL - * - * Update the specified TLV to the LLDP Local MIB for the given bridge type. - * Firmware will place the complete LLDP MIB in response buffer with the - * updated TLV. - **/ -enum i40e_status_code i40e_aq_update_lldp_tlv(struct i40e_hw *hw, - u8 bridge_type, void *buff, u16 buff_size, - u16 old_len, u16 new_len, u16 offset, - u16 *mib_len, - struct i40e_asq_cmd_details *cmd_details) +enum i40e_status_code +i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore, + struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; - struct i40e_aqc_lldp_update_tlv *cmd = - (struct i40e_aqc_lldp_update_tlv *)&desc.params.raw; + struct i40e_aqc_lldp_restore *cmd = + (struct i40e_aqc_lldp_restore *)&desc.params.raw; enum i40e_status_code status; - if (buff_size == 0 || !buff || offset == 0 || - old_len == 0 || new_len == 0) - return I40E_ERR_PARAM; - - i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_update_tlv); - - /* Indirect Command */ - desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); - if (buff_size > I40E_AQ_LARGE_BUF) - desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB); - desc.datalen = CPU_TO_LE16(buff_size); - - cmd->type = ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) & - I40E_AQ_LLDP_BRIDGE_TYPE_MASK); - cmd->old_len = CPU_TO_LE16(old_len); - cmd->new_offset = CPU_TO_LE16(offset); - cmd->new_len = CPU_TO_LE16(new_len); - - status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details); - if (!status) { - if (mib_len != NULL) - *mib_len = LE16_TO_CPU(desc.datalen); + if (!(hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT)) { + i40e_debug(hw, I40E_DEBUG_ALL, + "Restore LLDP not supported by current FW version.\n"); + return I40E_ERR_DEVICE_NOT_SUPPORTED; } - return status; -} - -/** - * i40e_aq_delete_lldp_tlv - * @hw: pointer to the hw struct - * @bridge_type: type of bridge - * @buff: pointer to a user supplied buffer that has the TLV - * @buff_size: length of the buffer - * @tlv_len: length of the TLV to be deleted - * @mib_len: length of the returned LLDP MIB - * @cmd_details: pointer to command details structure or NULL - * - * Delete the specified TLV from LLDP Local MIB for the given bridge type. - * The firmware places the entire LLDP MIB in the response buffer. - **/ -enum i40e_status_code i40e_aq_delete_lldp_tlv(struct i40e_hw *hw, - u8 bridge_type, void *buff, u16 buff_size, - u16 tlv_len, u16 *mib_len, - struct i40e_asq_cmd_details *cmd_details) -{ - struct i40e_aq_desc desc; - struct i40e_aqc_lldp_add_tlv *cmd = - (struct i40e_aqc_lldp_add_tlv *)&desc.params.raw; - enum i40e_status_code status; - - if (buff_size == 0 || !buff) - return I40E_ERR_PARAM; + i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_restore); - i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_delete_tlv); + if (restore) + cmd->command |= I40E_AQ_LLDP_AGENT_RESTORE; - /* Indirect Command */ - desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); - if (buff_size > I40E_AQ_LARGE_BUF) - desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB); - desc.datalen = CPU_TO_LE16(buff_size); - cmd->len = CPU_TO_LE16(tlv_len); - cmd->type = ((bridge_type << I40E_AQ_LLDP_BRIDGE_TYPE_SHIFT) & - I40E_AQ_LLDP_BRIDGE_TYPE_MASK); + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); - status = i40e_asq_send_command(hw, &desc, buff, buff_size, cmd_details); - if (!status) { - if (mib_len != NULL) - *mib_len = LE16_TO_CPU(desc.datalen); - } + if (setting) + *setting = cmd->command & 1; return status; } @@ -4527,11 +4645,13 @@ enum i40e_status_code i40e_aq_delete_lldp_tlv(struct i40e_hw *hw, * i40e_aq_stop_lldp * @hw: pointer to the hw struct * @shutdown_agent: True if LLDP Agent needs to be Shutdown + * @persist: True if stop of LLDP should be persistent across power cycles * @cmd_details: pointer to command details structure or NULL * * Stop or Shutdown the embedded LLDP Agent **/ enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent, + bool persist, struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; @@ -4544,6 +4664,14 @@ enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent, if (shutdown_agent) cmd->command |= I40E_AQ_LLDP_AGENT_SHUTDOWN; + if (persist) { + if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT) + cmd->command |= I40E_AQ_LLDP_AGENT_STOP_PERSIST; + else + i40e_debug(hw, I40E_DEBUG_ALL, + "Persistent Stop LLDP not supported by current FW version.\n"); + } + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); return status; @@ -4552,11 +4680,13 @@ enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent, /** * i40e_aq_start_lldp * @hw: pointer to the hw struct + * @persist: True if start of LLDP should be persistent across power cycles * @cmd_details: pointer to command details structure or NULL * * Start the embedded LLDP Agent on all ports. **/ enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw, + bool persist, struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; @@ -4567,6 +4697,15 @@ enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw, i40e_fill_default_direct_cmd_desc(&desc, i40e_aqc_opc_lldp_start); cmd->command = I40E_AQ_LLDP_AGENT_START; + + if (persist) { + if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT) + cmd->command |= I40E_AQ_LLDP_AGENT_START_PERSIST; + else + i40e_debug(hw, I40E_DEBUG_ALL, + "Persistent Start LLDP not supported by current FW version.\n"); + } + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); return status; @@ -4963,8 +5102,6 @@ enum i40e_status_code i40e_aq_add_mcast_etag(struct i40e_hw *hw, u16 pv_seid, cmd->num_unicast_etags = num_tags_in_buf; desc.flags |= CPU_TO_LE16((u16)(I40E_AQ_FLAG_BUF | I40E_AQ_FLAG_RD)); - if (length > I40E_AQ_LARGE_BUF) - desc.flags |= CPU_TO_LE16((u16)I40E_AQ_FLAG_LB); status = i40e_asq_send_command(hw, &desc, buf, length, cmd_details); @@ -5555,7 +5692,6 @@ STATIC enum i40e_status_code i40e_validate_filter_settings(struct i40e_hw *hw, struct i40e_filter_control_settings *settings) { u32 fcoe_cntx_size, fcoe_filt_size; - u32 pe_cntx_size, pe_filt_size; u32 fcoe_fmax; u32 val; @@ -5600,8 +5736,6 @@ STATIC enum i40e_status_code i40e_validate_filter_settings(struct i40e_hw *hw, case I40E_HASH_FILTER_SIZE_256K: case I40E_HASH_FILTER_SIZE_512K: case I40E_HASH_FILTER_SIZE_1M: - pe_filt_size = I40E_HASH_FILTER_BASE_SIZE; - pe_filt_size <<= (u32)settings->pe_filt_num; break; default: return I40E_ERR_PARAM; @@ -5618,8 +5752,6 @@ STATIC enum i40e_status_code i40e_validate_filter_settings(struct i40e_hw *hw, case I40E_DMA_CNTX_SIZE_64K: case I40E_DMA_CNTX_SIZE_128K: case I40E_DMA_CNTX_SIZE_256K: - pe_cntx_size = I40E_DMA_CNTX_BASE_SIZE; - pe_cntx_size <<= (u32)settings->pe_cntx_num; break; default: return I40E_ERR_PARAM; @@ -6417,6 +6549,71 @@ enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id, return status; } + +/** + * i40e_enable_eee + * @hw: pointer to the hardware structure + * @enable: state of Energy Efficient Ethernet mode to be set + * + * Enables or disables Energy Efficient Ethernet (EEE) mode + * accordingly to @enable parameter. + **/ +enum i40e_status_code i40e_enable_eee(struct i40e_hw *hw, bool enable) +{ + struct i40e_aq_get_phy_abilities_resp abilities; + struct i40e_aq_set_phy_config config; + enum i40e_status_code status; + __le16 eee_capability; + + /* Get initial PHY capabilities */ + status = i40e_aq_get_phy_capabilities(hw, false, true, &abilities, + NULL); + if (status) + goto err; + + /* Check whether NIC configuration is compatible with Energy Efficient + * Ethernet (EEE) mode. + */ + if (abilities.eee_capability == 0) { + status = I40E_ERR_CONFIG; + goto err; + } + + /* Cache initial EEE capability */ + eee_capability = abilities.eee_capability; + + /* Get current configuration */ + status = i40e_aq_get_phy_capabilities(hw, false, false, &abilities, + NULL); + if (status) + goto err; + + /* Cache current configuration */ + config.phy_type = abilities.phy_type; + config.phy_type_ext = abilities.phy_type_ext; + config.link_speed = abilities.link_speed; + config.abilities = abilities.abilities | + I40E_AQ_PHY_ENABLE_ATOMIC_LINK; + config.eeer = abilities.eeer_val; + config.low_power_ctrl = abilities.d3_lpan; + config.fec_config = abilities.fec_cfg_curr_mod_ext_info & + I40E_AQ_PHY_FEC_CONFIG_MASK; + + /* Set desired EEE state */ + if (enable) { + config.eee_capability = eee_capability; + config.eeer |= I40E_PRTPM_EEER_TX_LPI_EN_MASK; + } else { + config.eee_capability = 0; + config.eeer &= ~I40E_PRTPM_EEER_TX_LPI_EN_MASK; + } + + /* Save modified config */ + status = i40e_aq_set_phy_config(hw, &config, NULL); +err: + return status; +} + /** * i40e_read_bw_from_alt_ram * @hw: pointer to the hardware structure @@ -6738,6 +6935,8 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw, case I40E_DEV_ID_10G_BASE_T: case I40E_DEV_ID_10G_BASE_T4: case I40E_DEV_ID_10G_BASE_T_BC: + case I40E_DEV_ID_5G_BASE_T_BC: + case I40E_DEV_ID_1G_BASE_T_BC: case I40E_DEV_ID_10G_BASE_T_X722: case I40E_DEV_ID_25G_B: case I40E_DEV_ID_25G_SFP28: @@ -6774,6 +6973,9 @@ enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw, break; case I40E_DEV_ID_10G_BASE_T: case I40E_DEV_ID_10G_BASE_T4: + case I40E_DEV_ID_10G_BASE_T_BC: + case I40E_DEV_ID_5G_BASE_T_BC: + case I40E_DEV_ID_1G_BASE_T_BC: case I40E_DEV_ID_10G_BASE_T_X722: case I40E_DEV_ID_25G_B: case I40E_DEV_ID_25G_SFP28: @@ -6883,8 +7085,8 @@ enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw, * @led_addr: LED register address * @reg_val: read register value **/ -static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr, - u32 *reg_val) +enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr, + u32 *reg_val) { enum i40e_status_code status; u8 phy_addr = 0; @@ -6912,8 +7114,8 @@ static enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr, * @led_addr: LED register address * @reg_val: register value to write **/ -static enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr, - u32 reg_val) +enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr, + u32 reg_val) { enum i40e_status_code status; u8 phy_addr = 0; @@ -7029,6 +7231,203 @@ enum i40e_status_code i40e_led_set_phy(struct i40e_hw *hw, bool on, return status; } #endif /* PF_DRIVER */ +/** + * i40e_get_phy_lpi_status - read LPI status from PHY or MAC register + * @hw: pointer to the hw struct + * @stat: pointer to structure with status of rx and tx lpi + * + * Read LPI state directly from external PHY register or from MAC + * register, depending on device ID and current link speed. + */ +enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw, + struct i40e_hw_port_stats *stat) +{ + enum i40e_status_code ret = I40E_SUCCESS; + bool eee_mrvl_phy; + bool eee_bcm_phy; + u32 val; + + stat->rx_lpi_status = 0; + stat->tx_lpi_status = 0; + + eee_bcm_phy = + (hw->device_id == I40E_DEV_ID_10G_BASE_T_BC || + hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) && + (hw->phy.link_info.link_speed == I40E_LINK_SPEED_2_5GB || + hw->phy.link_info.link_speed == I40E_LINK_SPEED_5GB); + eee_mrvl_phy = + hw->device_id == I40E_DEV_ID_1G_BASE_T_X722; + + if (eee_bcm_phy || eee_mrvl_phy) { + /* read Clause 45 PCS Status 1 register */ + ret = i40e_aq_get_phy_register(hw, + I40E_AQ_PHY_REG_ACCESS_EXTERNAL, + I40E_BCM_PHY_PCS_STATUS1_PAGE, + true, + I40E_BCM_PHY_PCS_STATUS1_REG, + &val, NULL); + + if (ret != I40E_SUCCESS) + return ret; + + stat->rx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_RX_LPI); + stat->tx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_TX_LPI); + + return ret; + } + + val = rd32(hw, I40E_PRTPM_EEE_STAT); + stat->rx_lpi_status = (val & I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK) >> + I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT; + stat->tx_lpi_status = (val & I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK) >> + I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT; + + return ret; +} + +/** + * i40e_get_lpi_counters - read LPI counters from EEE statistics + * @hw: pointer to the hw struct + * @tx_counter: pointer to memory for TX LPI counter + * @rx_counter: pointer to memory for RX LPI counter + * @is_clear: returns true if counters are clear after read + * + * Read Low Power Idle (LPI) mode counters from Energy Efficient + * Ethernet (EEE) statistics. + **/ +enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw, + u32 *tx_counter, u32 *rx_counter, + bool *is_clear) +{ + /* only X710-T*L requires special handling of counters + * for other devices we just read the MAC registers + */ + if ((hw->device_id == I40E_DEV_ID_10G_BASE_T_BC || + hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) && + hw->phy.link_info.link_speed != I40E_LINK_SPEED_1GB) { + enum i40e_status_code retval; + u32 cmd_status = 0; + + *is_clear = false; + retval = i40e_aq_run_phy_activity(hw, + I40E_AQ_RUN_PHY_ACT_ID_USR_DFND, + I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT, + &cmd_status, tx_counter, rx_counter, NULL); + + if (!retval && cmd_status != I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC) + retval = I40E_ERR_ADMIN_QUEUE_ERROR; + + return retval; + } + + *is_clear = true; + *tx_counter = rd32(hw, I40E_PRTPM_TLPIC); + *rx_counter = rd32(hw, I40E_PRTPM_RLPIC); + + return I40E_SUCCESS; +} + +/** + * i40e_get_lpi_duration - read LPI time duration from EEE statistics + * @hw: pointer to the hw struct + * @stat: pointer to structure with status of rx and tx lpi + * @tx_duration: pointer to memory for TX LPI time duration + * @rx_duration: pointer to memory for RX LPI time duration + * + * Read Low Power Idle (LPI) mode time duration from Energy Efficient + * Ethernet (EEE) statistics. + */ +enum i40e_status_code i40e_get_lpi_duration(struct i40e_hw *hw, + struct i40e_hw_port_stats *stat, + u64 *tx_duration, u64 *rx_duration) +{ + u32 tx_time_dur, rx_time_dur; + enum i40e_status_code retval; + u32 cmd_status; + + if (hw->device_id != I40E_DEV_ID_10G_BASE_T_BC && + hw->device_id != I40E_DEV_ID_5G_BASE_T_BC) + return I40E_ERR_NOT_IMPLEMENTED; + + retval = i40e_aq_run_phy_activity + (hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND, + I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR, + &cmd_status, &tx_time_dur, &rx_time_dur, NULL); + + if (retval) + return retval; + if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) != + I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC) + return I40E_ERR_ADMIN_QUEUE_ERROR; + + if (hw->phy.link_info.link_speed == I40E_LINK_SPEED_1GB && + !tx_time_dur && !rx_time_dur && + stat->tx_lpi_status && stat->rx_lpi_status) { + retval = i40e_aq_run_phy_activity + (hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND, + I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR, + &cmd_status, + &tx_time_dur, &rx_time_dur, NULL); + + if (retval) + return retval; + if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) != + I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC) + return I40E_ERR_ADMIN_QUEUE_ERROR; + tx_time_dur = 0; + rx_time_dur = 0; + } + + *tx_duration = tx_time_dur; + *rx_duration = rx_time_dur; + + return retval; +} + +/** + * i40e_lpi_stat_update - update LPI counters with values relative to offset + * @hw: pointer to the hw struct + * @offset_loaded: flag indicating need of writing current value to offset + * @tx_offset: pointer to offset of TX LPI counter + * @tx_stat: pointer to value of TX LPI counter + * @rx_offset: pointer to offset of RX LPI counter + * @rx_stat: pointer to value of RX LPI counter + * + * Update Low Power Idle (LPI) mode counters while having regard to passed + * offsets. + **/ +enum i40e_status_code i40e_lpi_stat_update(struct i40e_hw *hw, + bool offset_loaded, u64 *tx_offset, + u64 *tx_stat, u64 *rx_offset, + u64 *rx_stat) +{ + enum i40e_status_code retval; + u32 tx_counter, rx_counter; + bool is_clear; + + retval = i40e_get_lpi_counters(hw, &tx_counter, &rx_counter, &is_clear); + if (retval) + goto err; + + if (is_clear) { + *tx_stat += tx_counter; + *rx_stat += rx_counter; + } else { + if (!offset_loaded) { + *tx_offset = tx_counter; + *rx_offset = rx_counter; + } + + *tx_stat = (tx_counter >= *tx_offset) ? + (u32)(tx_counter - *tx_offset) : + (u32)((tx_counter + BIT_ULL(32)) - *tx_offset); + *rx_stat = (rx_counter >= *rx_offset) ? + (u32)(rx_counter - *rx_offset) : + (u32)((rx_counter + BIT_ULL(32)) - *rx_offset); + } +err: + return retval; +} /** * i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register @@ -7156,23 +7555,52 @@ void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val) wr32(hw, reg_addr, reg_val); } -#ifdef PF_DRIVER /** - * i40e_aq_set_phy_register + * i40e_mdio_if_number_selection - MDIO I/F number selection + * @hw: pointer to the hw struct + * @set_mdio: use MDIO I/F number specified by mdio_num + * @mdio_num: MDIO I/F number + * @cmd: pointer to PHY Register command structure + **/ +static void +i40e_mdio_if_number_selection(struct i40e_hw *hw, bool set_mdio, u8 mdio_num, + struct i40e_aqc_phy_register_access *cmd) +{ + if (set_mdio && cmd->phy_interface == I40E_AQ_PHY_REG_ACCESS_EXTERNAL) { + if (hw->flags & I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED) + cmd->cmd_flags |= + I40E_AQ_PHY_REG_ACCESS_SET_MDIO_IF_NUMBER | + ((mdio_num << + I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_SHIFT) & + I40E_AQ_PHY_REG_ACCESS_MDIO_IF_NUMBER_MASK); + else + i40e_debug(hw, I40E_DEBUG_PHY, + "MDIO I/F number selection not supported by current FW version.\n"); + } +} + +/** + * i40e_aq_set_phy_register_ext * @hw: pointer to the hw struct * @phy_select: select which phy should be accessed * @dev_addr: PHY device address * @page_change: enable auto page change + * @set_mdio: use MDIO I/F number specified by mdio_num + * @mdio_num: MDIO I/F number * @reg_addr: PHY register address * @reg_val: new register value * @cmd_details: pointer to command details structure or NULL * * Write the external PHY register. + * NOTE: In common cases MDIO I/F number should not be changed, thats why you + * may use simple wrapper i40e_aq_set_phy_register. **/ -enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw, - u8 phy_select, u8 dev_addr, bool page_change, - u32 reg_addr, u32 reg_val, - struct i40e_asq_cmd_details *cmd_details) +enum i40e_status_code +i40e_aq_set_phy_register_ext(struct i40e_hw *hw, + u8 phy_select, u8 dev_addr, bool page_change, + bool set_mdio, u8 mdio_num, + u32 reg_addr, u32 reg_val, + struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; struct i40e_aqc_phy_register_access *cmd = @@ -7190,27 +7618,35 @@ enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw, if (!page_change) cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE; + i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd); + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); return status; } /** - * i40e_aq_get_phy_register + * i40e_aq_get_phy_register_ext * @hw: pointer to the hw struct * @phy_select: select which phy should be accessed * @dev_addr: PHY device address * @page_change: enable auto page change + * @set_mdio: use MDIO I/F number specified by mdio_num + * @mdio_num: MDIO I/F number * @reg_addr: PHY register address * @reg_val: read register value * @cmd_details: pointer to command details structure or NULL * * Read the external PHY register. + * NOTE: In common cases MDIO I/F number should not be changed, thats why you + * may use simple wrapper i40e_aq_get_phy_register. **/ -enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw, - u8 phy_select, u8 dev_addr, bool page_change, - u32 reg_addr, u32 *reg_val, - struct i40e_asq_cmd_details *cmd_details) +enum i40e_status_code +i40e_aq_get_phy_register_ext(struct i40e_hw *hw, + u8 phy_select, u8 dev_addr, bool page_change, + bool set_mdio, u8 mdio_num, + u32 reg_addr, u32 *reg_val, + struct i40e_asq_cmd_details *cmd_details) { struct i40e_aq_desc desc; struct i40e_aqc_phy_register_access *cmd = @@ -7227,6 +7663,8 @@ enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw, if (!page_change) cmd->cmd_flags = I40E_AQ_PHY_REG_ACCESS_DONT_CHANGE_QSFP_PAGE; + i40e_mdio_if_number_selection(hw, set_mdio, mdio_num, cmd); + status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); if (!status) *reg_val = LE32_TO_CPU(cmd->reg_value); @@ -7234,7 +7672,51 @@ enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw, return status; } -#endif /* PF_DRIVER */ +/** + * i40e_aq_run_phy_activity + * @hw: pointer to the hw struct + * @activity_id: ID of DNL activity to run + * @dnl_opcode: opcode passed to DNL script + * @cmd_status: pointer to memory to write return value of DNL script + * @data0: pointer to memory for first 4 bytes of data returned by DNL script + * @data1: pointer to memory for last 4 bytes of data returned by DNL script + * @cmd_details: pointer to command details structure or NULL + * + * Run DNL admin command. + **/ +enum i40e_status_code +i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 dnl_opcode, + u32 *cmd_status, u32 *data0, u32 *data1, + struct i40e_asq_cmd_details *cmd_details) +{ + struct i40e_aqc_run_phy_activity *cmd; + enum i40e_status_code retval; + struct i40e_aq_desc desc; + + cmd = (struct i40e_aqc_run_phy_activity *)&desc.params.raw; + + if (!cmd_status || !data0 || !data1) { + retval = I40E_ERR_PARAM; + goto err; + } + + i40e_fill_default_direct_cmd_desc(&desc, + i40e_aqc_opc_run_phy_activity); + + cmd->activity_id = CPU_TO_LE16(activity_id); + cmd->params.cmd.dnl_opcode = CPU_TO_LE32(dnl_opcode); + + retval = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details); + if (retval) + goto err; + + *cmd_status = LE32_TO_CPU(cmd->params.resp.cmd_status); + *data0 = LE32_TO_CPU(cmd->params.resp.data0); + *data1 = LE32_TO_CPU(cmd->params.resp.data1); +err: + return retval; +} + #ifdef VF_DRIVER /** @@ -7745,7 +8227,8 @@ i40e_validate_profile(struct i40e_hw *hw, struct i40e_profile_segment *profile, u32 sec_off; u32 i; - if (track_id == I40E_DDP_TRACKID_INVALID) { + if (track_id == I40E_DDP_TRACKID_INVALID || + track_id == I40E_DDP_TRACKID_RDONLY) { i40e_debug(hw, I40E_DEBUG_PACKAGE, "Invalid track_id\n"); return I40E_NOT_SUPPORTED; } diff --git a/drivers/net/i40e/base/i40e_dcb.c b/drivers/net/i40e/base/i40e_dcb.c index a1c9470057..8f9b7e823f 100644 --- a/drivers/net/i40e/base/i40e_dcb.c +++ b/drivers/net/i40e/base/i40e_dcb.c @@ -315,9 +315,15 @@ static void i40e_parse_cee_pgcfg_tlv(struct i40e_cee_feat_tlv *tlv, * |pg0|pg1|pg2|pg3|pg4|pg5|pg6|pg7| * --------------------------------- */ - for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) + for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) { etscfg->tcbwtable[i] = buf[offset++]; + if (etscfg->prioritytable[i] == I40E_CEE_PGID_STRICT) + dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_STRICT; + else + dcbcfg->etscfg.tsatable[i] = I40E_IEEE_TSA_ETS; + } + /* Number of TCs supported (1 octet) */ etscfg->maxtcs = buf[offset]; } @@ -863,22 +869,41 @@ enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw) /** * i40e_init_dcb * @hw: pointer to the hw struct + * @enable_mib_change: enable mib change event * * Update DCB configuration from the Firmware **/ -enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw) +enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw, bool enable_mib_change) { enum i40e_status_code ret = I40E_SUCCESS; struct i40e_lldp_variables lldp_cfg; u8 adminstatus = 0; if (!hw->func_caps.dcb) - return ret; + return I40E_NOT_SUPPORTED; /* Read LLDP NVM area */ - ret = i40e_read_lldp_cfg(hw, &lldp_cfg); + if (hw->flags & I40E_HW_FLAG_FW_LLDP_PERSISTENT) { + u8 offset = 0; + + if (hw->mac.type == I40E_MAC_XL710) + offset = I40E_LLDP_CURRENT_STATUS_XL710_OFFSET; + else if (hw->mac.type == I40E_MAC_X722) + offset = I40E_LLDP_CURRENT_STATUS_X722_OFFSET; + else + return I40E_NOT_SUPPORTED; + + ret = i40e_read_nvm_module_data(hw, + I40E_SR_EMP_SR_SETTINGS_PTR, + offset, + I40E_LLDP_CURRENT_STATUS_OFFSET, + I40E_LLDP_CURRENT_STATUS_SIZE, + &lldp_cfg.adminstatus); + } else { + ret = i40e_read_lldp_cfg(hw, &lldp_cfg); + } if (ret) - return ret; + return I40E_ERR_NOT_READY; /* Get the LLDP AdminStatus for the current port */ adminstatus = lldp_cfg.adminstatus >> (hw->port * 4); @@ -887,7 +912,7 @@ enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw) /* LLDP agent disabled */ if (!adminstatus) { hw->dcbx_status = I40E_DCBX_STATUS_DISABLED; - return ret; + return I40E_ERR_NOT_READY; } /* Get DCBX status */ @@ -896,27 +921,63 @@ enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw) return ret; /* Check the DCBX Status */ - switch (hw->dcbx_status) { - case I40E_DCBX_STATUS_DONE: - case I40E_DCBX_STATUS_IN_PROGRESS: + if (hw->dcbx_status == I40E_DCBX_STATUS_DONE || + hw->dcbx_status == I40E_DCBX_STATUS_IN_PROGRESS) { /* Get current DCBX configuration */ ret = i40e_get_dcb_config(hw); if (ret) return ret; - break; - case I40E_DCBX_STATUS_DISABLED: - return ret; - case I40E_DCBX_STATUS_NOT_STARTED: - case I40E_DCBX_STATUS_MULTIPLE_PEERS: - default: - break; + } else if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) { + return I40E_ERR_NOT_READY; } /* Configure the LLDP MIB change event */ - ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL); + if (enable_mib_change) + ret = i40e_aq_cfg_lldp_mib_change_event(hw, true, NULL); + + return ret; +} + +/** + * i40e_get_fw_lldp_status + * @hw: pointer to the hw struct + * @lldp_status: pointer to the status enum + * + * Get status of FW Link Layer Discovery Protocol (LLDP) Agent. + * Status of agent is reported via @lldp_status parameter. + **/ +enum i40e_status_code +i40e_get_fw_lldp_status(struct i40e_hw *hw, + enum i40e_get_fw_lldp_status_resp *lldp_status) +{ + enum i40e_status_code ret; + struct i40e_virt_mem mem; + u8 *lldpmib; + + if (!lldp_status) + return I40E_ERR_PARAM; + + /* Allocate buffer for the LLDPDU */ + ret = i40e_allocate_virt_mem(hw, &mem, I40E_LLDPDU_SIZE); if (ret) return ret; + lldpmib = (u8 *)mem.va; + ret = i40e_aq_get_lldp_mib(hw, 0, 0, (void *)lldpmib, + I40E_LLDPDU_SIZE, NULL, NULL, NULL); + + if (ret == I40E_SUCCESS) { + *lldp_status = I40E_GET_FW_LLDP_STATUS_ENABLED; + } else if (hw->aq.asq_last_status == I40E_AQ_RC_ENOENT) { + /* MIB is not available yet but the agent is running */ + *lldp_status = I40E_GET_FW_LLDP_STATUS_ENABLED; + ret = I40E_SUCCESS; + } else if (hw->aq.asq_last_status == I40E_AQ_RC_EPERM) { + *lldp_status = I40E_GET_FW_LLDP_STATUS_DISABLED; + ret = I40E_SUCCESS; + } + + i40e_free_virt_mem(hw, &mem); return ret; } diff --git a/drivers/net/i40e/base/i40e_dcb.h b/drivers/net/i40e/base/i40e_dcb.h index 8d36fce430..0409fd3e1a 100644 --- a/drivers/net/i40e/base/i40e_dcb.h +++ b/drivers/net/i40e/base/i40e_dcb.h @@ -39,6 +39,11 @@ #define I40E_LLDP_ADMINSTATUS_ENABLED_TX 2 #define I40E_LLDP_ADMINSTATUS_ENABLED_RXTX 3 +#define I40E_LLDP_CURRENT_STATUS_XL710_OFFSET 0x2B +#define I40E_LLDP_CURRENT_STATUS_X722_OFFSET 0x31 +#define I40E_LLDP_CURRENT_STATUS_OFFSET 1 +#define I40E_LLDP_CURRENT_STATUS_SIZE 1 + /* Defines for LLDP TLV header */ #define I40E_LLDP_MIB_HLEN 14 #define I40E_LLDP_TLV_LEN_SHIFT 0 @@ -178,6 +183,12 @@ struct i40e_dcbx_variables { u32 deftsaassignment; }; + +enum i40e_get_fw_lldp_status_resp { + I40E_GET_FW_LLDP_STATUS_DISABLED = 0, + I40E_GET_FW_LLDP_STATUS_ENABLED = 1 +}; + enum i40e_status_code i40e_get_dcbx_status(struct i40e_hw *hw, u16 *status); enum i40e_status_code i40e_lldp_to_dcb_config(u8 *lldpmib, @@ -186,9 +197,12 @@ enum i40e_status_code i40e_aq_get_dcb_config(struct i40e_hw *hw, u8 mib_type, u8 bridgetype, struct i40e_dcbx_config *dcbcfg); enum i40e_status_code i40e_get_dcb_config(struct i40e_hw *hw); -enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw); +enum i40e_status_code i40e_init_dcb(struct i40e_hw *hw, + bool enable_mib_change); +enum i40e_status_code +i40e_get_fw_lldp_status(struct i40e_hw *hw, + enum i40e_get_fw_lldp_status_resp *lldp_status); enum i40e_status_code i40e_set_dcb_config(struct i40e_hw *hw); enum i40e_status_code i40e_dcb_config_to_lldp(u8 *lldpmib, u16 *miblen, struct i40e_dcbx_config *dcbcfg); - #endif /* _I40E_DCB_H_ */ diff --git a/drivers/net/i40e/base/i40e_devids.h b/drivers/net/i40e/base/i40e_devids.h index 64cfe2bb26..60f8e1cd21 100644 --- a/drivers/net/i40e/base/i40e_devids.h +++ b/drivers/net/i40e/base/i40e_devids.h @@ -22,9 +22,11 @@ #define I40E_DEV_ID_10G_BASE_T4 0x1589 #define I40E_DEV_ID_25G_B 0x158A #define I40E_DEV_ID_25G_SFP28 0x158B -#define I40E_DEV_ID_X710_N3000 0x0CF8 +#define I40E_DEV_ID_X710_N3000 0x0CF8 #define I40E_DEV_ID_XXV710_N3000 0x0D58 #define I40E_DEV_ID_10G_BASE_T_BC 0x15FF +#define I40E_DEV_ID_5G_BASE_T_BC 0x101F +#define I40E_DEV_ID_1G_BASE_T_BC 0x0DD2 #if defined(INTEGRATED_VF) || defined(VF_DRIVER) || defined(I40E_NDIS_SUPPORT) #define I40E_DEV_ID_VF 0x154C #define I40E_DEV_ID_VF_HV 0x1571 @@ -36,12 +38,18 @@ #define I40E_DEV_ID_X722_A0_VF 0x374D #endif #endif +#define I40E_DEV_ID_10G_B 0x104F +#define I40E_DEV_ID_10G_SFP 0x104E +#define I40E_IS_X710TL_DEVICE(d) \ + (((d) == I40E_DEV_ID_10G_BASE_T_BC) || \ + ((d) == I40E_DEV_ID_5G_BASE_T_BC)) #define I40E_DEV_ID_KX_X722 0x37CE #define I40E_DEV_ID_QSFP_X722 0x37CF #define I40E_DEV_ID_SFP_X722 0x37D0 #define I40E_DEV_ID_1G_BASE_T_X722 0x37D1 #define I40E_DEV_ID_10G_BASE_T_X722 0x37D2 #define I40E_DEV_ID_SFP_I_X722 0x37D3 +#define I40E_DEV_ID_SFP_X722_A 0x0DDA #if defined(INTEGRATED_VF) || defined(VF_DRIVER) || defined(I40E_NDIS_SUPPORT) #define I40E_DEV_ID_X722_VF 0x37CD #endif /* VF_DRIVER */ diff --git a/drivers/net/i40e/base/i40e_nvm.c b/drivers/net/i40e/base/i40e_nvm.c index 338972a2f9..7a41a8495c 100644 --- a/drivers/net/i40e/base/i40e_nvm.c +++ b/drivers/net/i40e/base/i40e_nvm.c @@ -339,6 +339,76 @@ enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, return ret_code; } +/** + * i40e_read_nvm_module_data - Reads NVM Buffer to specified memory location + * @hw: Pointer to the HW structure + * @module_ptr: Pointer to module in words with respect to NVM beginning + * @module_offset: Offset in words from module start + * @data_offset: Offset in words from reading data area start + * @words_data_size: Words to read from NVM + * @data_ptr: Pointer to memory location where resulting buffer will be stored + **/ +enum i40e_status_code +i40e_read_nvm_module_data(struct i40e_hw *hw, u8 module_ptr, u16 module_offset, + u16 data_offset, u16 words_data_size, u16 *data_ptr) +{ + enum i40e_status_code status; + u16 specific_ptr = 0; + u16 ptr_value = 0; + u16 offset = 0; + + if (module_ptr != 0) { + status = i40e_read_nvm_word(hw, module_ptr, &ptr_value); + if (status != I40E_SUCCESS) { + i40e_debug(hw, I40E_DEBUG_ALL, + "Reading nvm word failed.Error code: %d.\n", + status); + return I40E_ERR_NVM; + } + } +#define I40E_NVM_INVALID_PTR_VAL 0x7FFF +#define I40E_NVM_INVALID_VAL 0xFFFF + + /* Pointer not initialized */ + if (ptr_value == I40E_NVM_INVALID_PTR_VAL || + ptr_value == I40E_NVM_INVALID_VAL) { + i40e_debug(hw, I40E_DEBUG_ALL, "Pointer not initialized.\n"); + return I40E_ERR_BAD_PTR; + } + + /* Check whether the module is in SR mapped area or outside */ + if (ptr_value & I40E_PTR_TYPE) { + /* Pointer points outside of the Shared RAM mapped area */ + i40e_debug(hw, I40E_DEBUG_ALL, + "Reading nvm data failed. Pointer points outside of the Shared RAM mapped area.\n"); + + return I40E_ERR_PARAM; + } + + /* Read from the Shadow RAM */ + status = i40e_read_nvm_word(hw, ptr_value + module_offset, + &specific_ptr); + if (status != I40E_SUCCESS) { + i40e_debug(hw, I40E_DEBUG_ALL, + "Reading nvm word failed.Error code: %d.\n", + status); + return I40E_ERR_NVM; + } + + offset = ptr_value + module_offset + specific_ptr + + data_offset; + + status = i40e_read_nvm_buffer(hw, offset, &words_data_size, + data_ptr); + if (status != I40E_SUCCESS) { + i40e_debug(hw, I40E_DEBUG_ALL, + "Reading nvm buffer failed.Error code: %d.\n", + status); + } + + return status; +} + /** * i40e_read_nvm_buffer_srctl - Reads Shadow RAM buffer via SRCTL register * @hw: pointer to the HW structure @@ -800,6 +870,7 @@ STATIC const char *i40e_nvm_update_state_str[] = { "I40E_NVMUPD_EXEC_AQ", "I40E_NVMUPD_GET_AQ_RESULT", "I40E_NVMUPD_GET_AQ_EVENT", + "I40E_NVMUPD_GET_FEATURES", }; /** @@ -862,6 +933,31 @@ enum i40e_status_code i40e_nvmupd_command(struct i40e_hw *hw, return I40E_SUCCESS; } + /* + * A supported features request returns immediately + * rather than going into state machine + */ + if (upd_cmd == I40E_NVMUPD_FEATURES) { + if (cmd->data_size < hw->nvmupd_features.size) { + *perrno = -EFAULT; + return I40E_ERR_BUF_TOO_SHORT; + } + + /* + * If buffer is bigger than i40e_nvmupd_features structure, + * make sure the trailing bytes are set to 0x0. + */ + if (cmd->data_size > hw->nvmupd_features.size) + i40e_memset(bytes + hw->nvmupd_features.size, 0x0, + cmd->data_size - hw->nvmupd_features.size, + I40E_NONDMA_MEM); + + i40e_memcpy(bytes, &hw->nvmupd_features, + hw->nvmupd_features.size, I40E_NONDMA_MEM); + + return I40E_SUCCESS; + } + /* Clear status even it is not read and log */ if (hw->nvmupd_state == I40E_NVMUPD_STATE_ERROR) { i40e_debug(hw, I40E_DEBUG_NVM, @@ -1328,10 +1424,20 @@ STATIC enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw, upd_cmd = I40E_NVMUPD_READ_SA; break; case I40E_NVM_EXEC: - if (module == 0xf) - upd_cmd = I40E_NVMUPD_STATUS; - else if (module == 0) + switch (module) { + case I40E_NVM_EXEC_GET_AQ_RESULT: upd_cmd = I40E_NVMUPD_GET_AQ_RESULT; + break; + case I40E_NVM_EXEC_FEATURES: + upd_cmd = I40E_NVMUPD_FEATURES; + break; + case I40E_NVM_EXEC_STATUS: + upd_cmd = I40E_NVMUPD_STATUS; + break; + default: + *perrno = -EFAULT; + return I40E_NVMUPD_INVALID; + } break; case I40E_NVM_AQE: upd_cmd = I40E_NVMUPD_GET_AQ_EVENT; diff --git a/drivers/net/i40e/base/i40e_osdep.h b/drivers/net/i40e/base/i40e_osdep.h index ebd6872400..29653e145e 100644 --- a/drivers/net/i40e/base/i40e_osdep.h +++ b/drivers/net/i40e/base/i40e_osdep.h @@ -160,7 +160,7 @@ static inline uint64_t i40e_read64_addr(volatile void *addr) I40E_PCI_REG_WRITE(I40E_PCI_REG_ADDR((a), (reg)), (value)) #define flush(a) i40e_read_addr(I40E_PCI_REG_ADDR((a), (I40E_GLGEN_STAT))) -#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) +#define ARRAY_SIZE(arr) RTE_DIM(arr) /* memory allocation tracking */ struct i40e_dma_mem { diff --git a/drivers/net/i40e/base/i40e_prototype.h b/drivers/net/i40e/base/i40e_prototype.h index f356834206..8c21ac71ab 100644 --- a/drivers/net/i40e/base/i40e_prototype.h +++ b/drivers/net/i40e/base/i40e_prototype.h @@ -38,6 +38,13 @@ enum i40e_status_code i40e_asq_send_command(struct i40e_hw *hw, void *buff, /* can be NULL */ u16 buff_size, struct i40e_asq_cmd_details *cmd_details); +enum i40e_status_code +i40e_asq_send_command_v2(struct i40e_hw *hw, + struct i40e_aq_desc *desc, + void *buff, /* can be NULL */ + u16 buff_size, + struct i40e_asq_cmd_details *cmd_details, + enum i40e_admin_queue_err *aq_status); #ifdef VF_DRIVER bool i40e_asq_done(struct i40e_hw *hw); #endif @@ -66,6 +73,7 @@ const char *i40e_stat_str(struct i40e_hw *hw, enum i40e_status_code stat_err); #ifdef PF_DRIVER u32 i40e_led_get(struct i40e_hw *hw); +bool i40e_led_get_blink(struct i40e_hw *hw); void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink); enum i40e_status_code i40e_led_set_phy(struct i40e_hw *hw, bool on, u16 led_addr, u32 mode); @@ -73,7 +81,21 @@ enum i40e_status_code i40e_led_get_phy(struct i40e_hw *hw, u16 *led_addr, u16 *val); enum i40e_status_code i40e_blink_phy_link_led(struct i40e_hw *hw, u32 time, u32 interval); - +enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr, + u32 *reg_val); +enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr, + u32 reg_val); +enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw, + struct i40e_hw_port_stats *stats); +enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw, u32 *tx_counter, + u32 *rx_counter, bool *is_clear); +enum i40e_status_code i40e_lpi_stat_update(struct i40e_hw *hw, + bool offset_loaded, u64 *tx_offset, + u64 *tx_stat, u64 *rx_offset, + u64 *rx_stat); +enum i40e_status_code i40e_get_lpi_duration(struct i40e_hw *hw, + struct i40e_hw_port_stats *stat, + u64 *tx_duration, u64 *rx_duration); /* admin send queue commands */ enum i40e_status_code i40e_aq_get_firmware_version(struct i40e_hw *hw, @@ -106,6 +128,7 @@ enum i40e_status_code i40e_aq_set_phy_int_mask(struct i40e_hw *hw, u16 mask, struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_aq_set_mac_config(struct i40e_hw *hw, u16 max_frame_size, bool crc_en, u16 pacing, + bool auto_drop_blocking_packets, struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_aq_get_local_advt_reg(struct i40e_hw *hw, u64 *advt_reg, @@ -173,9 +196,19 @@ enum i40e_status_code i40e_aq_get_veb_parameters(struct i40e_hw *hw, enum i40e_status_code i40e_aq_add_macvlan(struct i40e_hw *hw, u16 vsi_id, struct i40e_aqc_add_macvlan_element_data *mv_list, u16 count, struct i40e_asq_cmd_details *cmd_details); +enum i40e_status_code +i40e_aq_add_macvlan_v2(struct i40e_hw *hw, u16 seid, + struct i40e_aqc_add_macvlan_element_data *mv_list, + u16 count, struct i40e_asq_cmd_details *cmd_details, + enum i40e_admin_queue_err *aq_status); enum i40e_status_code i40e_aq_remove_macvlan(struct i40e_hw *hw, u16 vsi_id, struct i40e_aqc_remove_macvlan_element_data *mv_list, u16 count, struct i40e_asq_cmd_details *cmd_details); +enum i40e_status_code +i40e_aq_remove_macvlan_v2(struct i40e_hw *hw, u16 seid, + struct i40e_aqc_remove_macvlan_element_data *mv_list, + u16 count, struct i40e_asq_cmd_details *cmd_details, + enum i40e_admin_queue_err *aq_status); enum i40e_status_code i40e_aq_add_mirrorrule(struct i40e_hw *hw, u16 sw_seid, u16 rule_type, u16 dest_vsi, u16 count, __le16 *mr_list, struct i40e_asq_cmd_details *cmd_details, @@ -225,6 +258,10 @@ enum i40e_status_code i40e_aq_write_nvm_config(struct i40e_hw *hw, u8 cmd_flags, void *data, u16 buf_size, u16 element_count, struct i40e_asq_cmd_details *cmd_details); +enum i40e_status_code +i40e_aq_min_rollback_rev_update(struct i40e_hw *hw, u8 mode, u8 module, + u32 min_rrev, + struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_aq_oem_post_update(struct i40e_hw *hw, void *buff, u16 buff_size, struct i40e_asq_cmd_details *cmd_details); @@ -239,8 +276,10 @@ enum i40e_status_code i40e_aq_update_nvm(struct i40e_hw *hw, u8 module_pointer, enum i40e_status_code i40e_aq_rearrange_nvm(struct i40e_hw *hw, u8 rearrange_nvm, struct i40e_asq_cmd_details *cmd_details); -enum i40e_status_code i40e_aq_nvm_progress(struct i40e_hw *hw, u8 *progress, - struct i40e_asq_cmd_details *cmd_details); +enum i40e_status_code +i40e_aq_nvm_update_in_process(struct i40e_hw *hw, + bool update_flow_state, + struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_aq_get_lldp_mib(struct i40e_hw *hw, u8 bridge_type, u8 mib_type, void *buff, u16 buff_size, u16 *local_len, u16 *remote_len, @@ -251,26 +290,18 @@ enum i40e_status_code i40e_aq_set_lldp_mib(struct i40e_hw *hw, enum i40e_status_code i40e_aq_cfg_lldp_mib_change_event(struct i40e_hw *hw, bool enable_update, struct i40e_asq_cmd_details *cmd_details); -enum i40e_status_code i40e_aq_add_lldp_tlv(struct i40e_hw *hw, u8 bridge_type, - void *buff, u16 buff_size, u16 tlv_len, - u16 *mib_len, - struct i40e_asq_cmd_details *cmd_details); -enum i40e_status_code i40e_aq_update_lldp_tlv(struct i40e_hw *hw, - u8 bridge_type, void *buff, u16 buff_size, - u16 old_len, u16 new_len, u16 offset, - u16 *mib_len, - struct i40e_asq_cmd_details *cmd_details); -enum i40e_status_code i40e_aq_delete_lldp_tlv(struct i40e_hw *hw, - u8 bridge_type, void *buff, u16 buff_size, - u16 tlv_len, u16 *mib_len, - struct i40e_asq_cmd_details *cmd_details); +enum i40e_status_code +i40e_aq_restore_lldp(struct i40e_hw *hw, u8 *setting, bool restore, + struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent, + bool persist, struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_aq_set_dcb_parameters(struct i40e_hw *hw, bool dcb_enable, struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_aq_start_lldp(struct i40e_hw *hw, + bool persist, struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_aq_get_cee_dcb_config(struct i40e_hw *hw, void *buff, u16 buff_size, @@ -441,6 +472,9 @@ enum i40e_status_code i40e_acquire_nvm(struct i40e_hw *hw, void i40e_release_nvm(struct i40e_hw *hw); enum i40e_status_code i40e_read_nvm_word(struct i40e_hw *hw, u16 offset, u16 *data); +enum i40e_status_code +i40e_read_nvm_module_data(struct i40e_hw *hw, u8 module_ptr, u16 module_offset, + u16 data_offset, u16 words_data_size, u16 *data_ptr); enum i40e_status_code i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset, u16 *words, u16 *data); enum i40e_status_code i40e_write_nvm_aq(struct i40e_hw *hw, u8 module, @@ -466,11 +500,10 @@ void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode, void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw); void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status); #endif /* PF_DRIVER */ +enum i40e_status_code i40e_enable_eee(struct i40e_hw *hw, bool enable); -#if defined(I40E_QV) || defined(VF_DRIVER) enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw); -#endif extern struct i40e_rx_ptype_decoded i40e_ptype_lookup[]; STATIC INLINE struct i40e_rx_ptype_decoded decode_rx_desc_ptype(u8 ptype) @@ -551,14 +584,29 @@ enum i40e_status_code i40e_aq_rx_ctl_write_register(struct i40e_hw *hw, u32 reg_addr, u32 reg_val, struct i40e_asq_cmd_details *cmd_details); void i40e_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val); -enum i40e_status_code i40e_aq_set_phy_register(struct i40e_hw *hw, - u8 phy_select, u8 dev_addr, bool page_change, - u32 reg_addr, u32 reg_val, - struct i40e_asq_cmd_details *cmd_details); -enum i40e_status_code i40e_aq_get_phy_register(struct i40e_hw *hw, - u8 phy_select, u8 dev_addr, bool page_change, - u32 reg_addr, u32 *reg_val, - struct i40e_asq_cmd_details *cmd_details); +enum i40e_status_code +i40e_aq_set_phy_register_ext(struct i40e_hw *hw, + u8 phy_select, u8 dev_addr, bool page_change, + bool set_mdio, u8 mdio_num, + u32 reg_addr, u32 reg_val, + struct i40e_asq_cmd_details *cmd_details); +enum i40e_status_code +i40e_aq_get_phy_register_ext(struct i40e_hw *hw, + u8 phy_select, u8 dev_addr, bool page_change, + bool set_mdio, u8 mdio_num, + u32 reg_addr, u32 *reg_val, + struct i40e_asq_cmd_details *cmd_details); + +/* Convenience wrappers for most common use case */ +#define i40e_aq_set_phy_register(hw, ps, da, pc, ra, rv, cd) \ + i40e_aq_set_phy_register_ext(hw, ps, da, pc, false, 0, ra, rv, cd) +#define i40e_aq_get_phy_register(hw, ps, da, pc, ra, rv, cd) \ + i40e_aq_get_phy_register_ext(hw, ps, da, pc, false, 0, ra, rv, cd) + +enum i40e_status_code +i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 opcode, + u32 *cmd_status, u32 *data0, u32 *data1, + struct i40e_asq_cmd_details *cmd_details); enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw, struct i40e_aqc_arp_proxy_data *proxy_config, diff --git a/drivers/net/i40e/base/i40e_register.h b/drivers/net/i40e/base/i40e_register.h index 2408dcb117..651b0230f7 100644 --- a/drivers/net/i40e/base/i40e_register.h +++ b/drivers/net/i40e/base/i40e_register.h @@ -366,6 +366,20 @@ #define I40E_GL_FWSTS_FWRI_MASK I40E_MASK(0x1, I40E_GL_FWSTS_FWRI_SHIFT) #define I40E_GL_FWSTS_FWS1B_SHIFT 16 #define I40E_GL_FWSTS_FWS1B_MASK I40E_MASK(0xFF, I40E_GL_FWSTS_FWS1B_SHIFT) +#define I40E_GL_FWSTS_FWS1B_EMPR_0 I40E_MASK(0x20, I40E_GL_FWSTS_FWS1B_SHIFT) +#define I40E_GL_FWSTS_FWS1B_EMPR_10 I40E_MASK(0x2A, I40E_GL_FWSTS_FWS1B_SHIFT) +#define I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_CORER_MASK \ + I40E_MASK(0x30, I40E_GL_FWSTS_FWS1B_SHIFT) +#define I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_GLOBR_MASK \ + I40E_MASK(0x31, I40E_GL_FWSTS_FWS1B_SHIFT) +#define I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_TRANSITION_MASK \ + I40E_MASK(0x32, I40E_GL_FWSTS_FWS1B_SHIFT) +#define I40E_XL710_GL_FWSTS_FWS1B_REC_MOD_NVM_MASK \ + I40E_MASK(0x33, I40E_GL_FWSTS_FWS1B_SHIFT) +#define I40E_X722_GL_FWSTS_FWS1B_REC_MOD_CORER_MASK \ + I40E_MASK(0xB, I40E_GL_FWSTS_FWS1B_SHIFT) +#define I40E_X722_GL_FWSTS_FWS1B_REC_MOD_GLOBR_MASK \ + I40E_MASK(0xC, I40E_GL_FWSTS_FWS1B_SHIFT) #define I40E_GLGEN_CLKSTAT 0x000B8184 /* Reset: POR */ #define I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT 0 #define I40E_GLGEN_CLKSTAT_CLKMODE_MASK I40E_MASK(0x1, I40E_GLGEN_CLKSTAT_CLKMODE_SHIFT) @@ -1397,6 +1411,11 @@ #define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE1_SHIFT) #define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT 14 #define I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_MASK I40E_MASK(0x3, I40E_PRTMAC_PCS_XAUI_SWAP_B_SWAP_RX_LANE0_SHIFT) +/* _i=0...3 */ /* Reset: GLOBR */ +#define I40E_PRTMAC_PCS_LINK_STATUS1(_i) (0x0008C200 + ((_i) * 4)) +#define I40E_PRTMAC_PCS_LINK_STATUS1_LINK_SPEED_SHIFT 24 +#define I40E_PRTMAC_PCS_LINK_STATUS1_LINK_SPEED_MASK \ + I40E_MASK(0x7, I40E_PRTMAC_PCS_LINK_STATUS1_LINK_SPEED_SHIFT) #define I40E_GL_FWRESETCNT 0x00083100 /* Reset: POR */ #define I40E_GL_FWRESETCNT_FWRESETCNT_SHIFT 0 #define I40E_GL_FWRESETCNT_FWRESETCNT_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FWRESETCNT_FWRESETCNT_SHIFT) @@ -2376,10 +2395,14 @@ #define I40E_GL_FCOERPDC_MAX_INDEX 143 #define I40E_GL_FCOERPDC_FCOERPDC_SHIFT 0 #define I40E_GL_FCOERPDC_FCOERPDC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_FCOERPDC_FCOERPDC_SHIFT) -#define I40E_GL_RXERR1_L(_i) (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */ -#define I40E_GL_RXERR1_L_MAX_INDEX 143 -#define I40E_GL_RXERR1_L_FCOEDIFRC_SHIFT 0 -#define I40E_GL_RXERR1_L_FCOEDIFRC_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1_L_FCOEDIFRC_SHIFT) +#define I40E_GL_RXERR1H(_i) (0x00318004 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */ +#define I40E_GL_RXERR1H_MAX_INDEX 143 +#define I40E_GL_RXERR1H_RXERR1H_SHIFT 0 +#define I40E_GL_RXERR1H_RXERR1H_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1H_RXERR1H_SHIFT) +#define I40E_GL_RXERR1L(_i) (0x00318000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */ +#define I40E_GL_RXERR1L_MAX_INDEX 143 +#define I40E_GL_RXERR1L_RXERR1L_SHIFT 0 +#define I40E_GL_RXERR1L_RXERR1L_MASK I40E_MASK(0xFFFFFFFF, I40E_GL_RXERR1L_RXERR1L_SHIFT) #define I40E_GL_RXERR2_L(_i) (0x0031c000 + ((_i) * 8)) /* _i=0...143 */ /* Reset: CORER */ #define I40E_GL_RXERR2_L_MAX_INDEX 143 #define I40E_GL_RXERR2_L_FCOEDIXAC_SHIFT 0 @@ -2896,6 +2919,10 @@ #define I40E_PRTTSYN_AUX_0_PULSEW_MASK I40E_MASK(0xF, I40E_PRTTSYN_AUX_0_PULSEW_SHIFT) #define I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT 16 #define I40E_PRTTSYN_AUX_0_EVNTLVL_MASK I40E_MASK(0x3, I40E_PRTTSYN_AUX_0_EVNTLVL_SHIFT) +#define I40E_PRTTSYN_AUX_0_PTPFLAG_SHIFT 17 +#define I40E_PRTTSYN_AUX_0_PTPFLAG_MASK \ + I40E_MASK(0x1, I40E_PRTTSYN_AUX_0_PTPFLAG_SHIFT) +#define I40E_PRTTSYN_AUX_0_PTP_OUT_SYNC_CLK_IO 0xF #define I40E_PRTTSYN_AUX_1(_i) (0x001E42E0 + ((_i) * 32)) /* _i=0...1 */ /* Reset: GLOBR */ #define I40E_PRTTSYN_AUX_1_MAX_INDEX 1 #define I40E_PRTTSYN_AUX_1_INSTNT_SHIFT 0 @@ -3602,27 +3629,6 @@ #define I40E_GLHMC_PETIMEROBJSZ 0x000C2080 /* Reset: CORER */ #define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT 0 #define I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PETIMEROBJSZ_PMPETIMEROBJSZ_SHIFT) -#define I40E_GLHMC_PEXFBASE(_i) (0x000C4e00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */ -#define I40E_GLHMC_PEXFBASE_MAX_INDEX 15 -#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT 0 -#define I40E_GLHMC_PEXFBASE_FPMPEXFBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEXFBASE_FPMPEXFBASE_SHIFT) -#define I40E_GLHMC_PEXFCNT(_i) (0x000C4f00 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */ -#define I40E_GLHMC_PEXFCNT_MAX_INDEX 15 -#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT 0 -#define I40E_GLHMC_PEXFCNT_FPMPEXFCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_PEXFCNT_FPMPEXFCNT_SHIFT) -#define I40E_GLHMC_PEXFFLBASE(_i) (0x000C5000 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */ -#define I40E_GLHMC_PEXFFLBASE_MAX_INDEX 15 -#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT 0 -#define I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_PEXFFLBASE_FPMPEXFFLBASE_SHIFT) -#define I40E_GLHMC_PEXFFLMAX 0x000C204c /* Reset: CORER */ -#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT 0 -#define I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_MASK I40E_MASK(0x1FFFFFF, I40E_GLHMC_PEXFFLMAX_PMPEXFFLMAX_SHIFT) -#define I40E_GLHMC_PEXFMAX 0x000C2048 /* Reset: CORER */ -#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT 0 -#define I40E_GLHMC_PEXFMAX_PMPEXFMAX_MASK I40E_MASK(0x3FFFFFF, I40E_GLHMC_PEXFMAX_PMPEXFMAX_SHIFT) -#define I40E_GLHMC_PEXFOBJSZ 0x000C2044 /* Reset: CORER */ -#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT 0 -#define I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_MASK I40E_MASK(0xF, I40E_GLHMC_PEXFOBJSZ_PMPEXFOBJSZ_SHIFT) #define I40E_GLHMC_PFPESDPART(_i) (0x000C0880 + ((_i) * 4)) /* _i=0...15 */ /* Reset: CORER */ #define I40E_GLHMC_PFPESDPART_MAX_INDEX 15 #define I40E_GLHMC_PFPESDPART_PMSDBASE_SHIFT 0 @@ -3743,18 +3749,6 @@ #define I40E_GLHMC_VFPETIMERCNT_MAX_INDEX 31 #define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT 0 #define I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPETIMERCNT_FPMPETIMERCNT_SHIFT) -#define I40E_GLHMC_VFPEXFBASE(_i) (0x000Cce00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */ -#define I40E_GLHMC_VFPEXFBASE_MAX_INDEX 31 -#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT 0 -#define I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEXFBASE_FPMPEXFBASE_SHIFT) -#define I40E_GLHMC_VFPEXFCNT(_i) (0x000Ccf00 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */ -#define I40E_GLHMC_VFPEXFCNT_MAX_INDEX 31 -#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT 0 -#define I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_MASK I40E_MASK(0x1FFFFFFF, I40E_GLHMC_VFPEXFCNT_FPMPEXFCNT_SHIFT) -#define I40E_GLHMC_VFPEXFFLBASE(_i) (0x000Cd000 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */ -#define I40E_GLHMC_VFPEXFFLBASE_MAX_INDEX 31 -#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT 0 -#define I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_MASK I40E_MASK(0xFFFFFF, I40E_GLHMC_VFPEXFFLBASE_FPMPEXFFLBASE_SHIFT) #define I40E_GLHMC_VFSDPART(_i) (0x000C8800 + ((_i) * 4)) /* _i=0...31 */ /* Reset: CORER */ #define I40E_GLHMC_VFSDPART_MAX_INDEX 31 #define I40E_GLHMC_VFSDPART_PMSDBASE_SHIFT 0 @@ -3855,6 +3849,11 @@ #define I40E_PRTMAC_LINK_DOWN_COUNTER 0x001E2440 /* Reset: GLOBR */ #define I40E_PRTMAC_LINK_DOWN_COUNTER_LINK_DOWN_COUNTER_SHIFT 0 #define I40E_PRTMAC_LINK_DOWN_COUNTER_LINK_DOWN_COUNTER_MASK I40E_MASK(0xFFFF, I40E_PRTMAC_LINK_DOWN_COUNTER_LINK_DOWN_COUNTER_SHIFT) +/* _i=0...3 */ /* Reset: GLOBR */ +#define I40E_PRTMAC_LINKSTA(_i) (0x001E2420 + ((_i) * 4)) +#define I40E_PRTMAC_LINKSTA_MAC_LINK_SPEED_SHIFT 27 +#define I40E_PRTMAC_LINKSTA_MAC_LINK_SPEED_MASK \ + I40E_MASK(0x7, I40E_PRTMAC_LINKSTA_MAC_LINK_SPEED_SHIFT) #define I40E_GLNVM_AL_REQ 0x000B6164 /* Reset: POR */ #define I40E_GLNVM_AL_REQ_POR_SHIFT 0 #define I40E_GLNVM_AL_REQ_POR_MASK I40E_MASK(0x1, I40E_GLNVM_AL_REQ_POR_SHIFT) @@ -5275,6 +5274,87 @@ #define I40E_GLGEN_STAT_HALT_HALT_CELLS_SHIFT 0 #define I40E_GLGEN_STAT_HALT_HALT_CELLS_MASK I40E_MASK(0x3FFFFFFF, I40E_GLGEN_STAT_HALT_HALT_CELLS_SHIFT) #endif /* PF_DRIVER */ +/* Flow Director */ +#define I40E_REG_INSET_L2_DMAC_SHIFT 60 +#define I40E_REG_INSET_L2_DMAC_MASK I40E_MASK(0xEULL, I40E_REG_INSET_L2_DMAC_SHIFT) +#define I40E_REG_INSET_L2_SMAC_SHIFT 56 +#define I40E_REG_INSET_L2_SMAC_MASK I40E_MASK(0x1CULL, I40E_REG_INSET_L2_SMAC_SHIFT) +#define I40E_REG_INSET_L2_OUTER_VLAN_SHIFT 26 +#define I40E_REG_INSET_L2_OUTER_VLAN_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L2_OUTER_VLAN_SHIFT) +#define I40E_REG_INSET_L2_INNER_VLAN_SHIFT 55 +#define I40E_REG_INSET_L2_INNER_VLAN_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L2_INNER_VLAN_SHIFT) +#define I40E_REG_INSET_TUNNEL_VLAN_SHIFT 56 +#define I40E_REG_INSET_TUNNEL_VLAN_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_TUNNEL_VLAN_SHIFT) +#define I40E_REG_INSET_L3_SRC_IP4_SHIFT 47 +#define I40E_REG_INSET_L3_SRC_IP4_MASK I40E_MASK(0x3ULL, I40E_REG_INSET_L3_SRC_IP4_SHIFT) +#define I40E_REG_INSET_L3_DST_IP4_SHIFT 35 +#define I40E_REG_INSET_L3_DST_IP4_MASK I40E_MASK(0x3ULL, I40E_REG_INSET_L3_DST_IP4_SHIFT) +#define I40E_X722_REG_INSET_L3_SRC_IP4_SHIFT 49 +#define I40E_X722_REG_INSET_L3_SRC_IP4_MASK I40E_MASK(0x3ULL, I40E_X722_REG_INSET_L3_SRC_IP4_SHIFT) +#define I40E_X722_REG_INSET_L3_DST_IP4_SHIFT 41 +#define I40E_X722_REG_INSET_L3_DST_IP4_MASK I40E_MASK(0x3ULL, I40E_X722_REG_INSET_L3_DST_IP4_SHIFT) +#define I40E_X722_REG_INSET_L3_IP4_PROTO_SHIFT 52 +#define I40E_X722_REG_INSET_L3_IP4_PROTO_MASK I40E_MASK(0x1ULL, I40E_X722_REG_INSET_L3_IP4_PROTO_SHIFT) +#define I40E_X722_REG_INSET_L3_IP4_TTL_SHIFT 52 +#define I40E_X722_REG_INSET_L3_IP4_TTL_MASK I40E_MASK(0x1ULL, I40E_X722_REG_INSET_L3_IP4_TTL_SHIFT) +#define I40E_REG_INSET_L3_IP4_TOS_SHIFT 54 +#define I40E_REG_INSET_L3_IP4_TOS_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L3_IP4_TOS_SHIFT) +#define I40E_REG_INSET_L3_IP4_PROTO_SHIFT 50 +#define I40E_REG_INSET_L3_IP4_PROTO_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L3_IP4_PROTO_SHIFT) +#define I40E_REG_INSET_L3_IP4_TTL_SHIFT 50 +#define I40E_REG_INSET_L3_IP4_TTL_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L3_IP4_TTL_SHIFT) +#define I40E_REG_INSET_L3_SRC_IP6_SHIFT 43 +#define I40E_REG_INSET_L3_SRC_IP6_MASK I40E_MASK(0xFFULL, I40E_REG_INSET_L3_SRC_IP6_SHIFT) +#define I40E_REG_INSET_L3_DST_IP6_SHIFT 35 +#define I40E_REG_INSET_L3_DST_IP6_MASK I40E_MASK(0xFFULL, I40E_REG_INSET_L3_DST_IP6_SHIFT) +#define I40E_REG_INSET_L3_IP6_TC_SHIFT 54 +#define I40E_REG_INSET_L3_IP6_TC_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L3_IP6_TC_SHIFT) +#define I40E_REG_INSET_L3_IP6_NEXT_HDR_SHIFT 51 +#define I40E_REG_INSET_L3_IP6_NEXT_HDR_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L3_IP6_NEXT_HDR_SHIFT) +#define I40E_REG_INSET_L3_IP6_HOP_LIMIT_SHIFT 51 +#define I40E_REG_INSET_L3_IP6_HOP_LIMIT_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L3_IP6_HOP_LIMIT_SHIFT) +#define I40E_REG_INSET_L4_SRC_PORT_SHIFT 34 +#define I40E_REG_INSET_L4_SRC_PORT_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L4_SRC_PORT_SHIFT) +#define I40E_REG_INSET_L4_DST_PORT_SHIFT 33 +#define I40E_REG_INSET_L4_DST_PORT_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_L4_DST_PORT_SHIFT) +#define I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG_SHIFT 31 +#define I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG_MASK I40E_MASK(0x3ULL, I40E_REG_INSET_L4_SCTP_VERIFICATION_TAG_SHIFT) +#define I40E_REG_INSET_TUNNEL_L2_INNER_DST_MAC_SHIFT 22 +#define I40E_REG_INSET_TUNNEL_L2_INNER_DST_MAC_MASK I40E_MASK(0x7ULL, I40E_REG_INSET_TUNNEL_L2_INNER_DST_MAC_SHIFT) +#define I40E_REG_INSET_TUNNEL_L2_INNER_SRC_MAC_SHIFT 11 +#define I40E_REG_INSET_TUNNEL_L2_INNER_SRC_MAC_MASK I40E_MASK(0x7ULL, I40E_REG_INSET_TUNNEL_L2_INNER_SRC_MAC_SHIFT) +#define I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT_SHIFT 21 +#define I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_TUNNEL_L4_UDP_DST_PORT_SHIFT) +#define I40E_REG_INSET_TUNNEL_ID_SHIFT 18 +#define I40E_REG_INSET_TUNNEL_ID_MASK I40E_MASK(0x3ULL, I40E_REG_INSET_TUNNEL_ID_SHIFT) +#define I40E_REG_INSET_LAST_ETHER_TYPE_SHIFT 14 +#define I40E_REG_INSET_LAST_ETHER_TYPE_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_LAST_ETHER_TYPE_SHIFT) +#define I40E_REG_INSET_TUNNEL_L3_SRC_IP4_SHIFT 8 +#define I40E_REG_INSET_TUNNEL_L3_SRC_IP4_MASK I40E_MASK(0x3ULL, I40E_REG_INSET_TUNNEL_L3_SRC_IP4_SHIFT) +#define I40E_REG_INSET_TUNNEL_L3_DST_IP4_SHIFT 6 +#define I40E_REG_INSET_TUNNEL_L3_DST_IP4_MASK I40E_MASK(0x3ULL, I40E_REG_INSET_TUNNEL_L3_DST_IP4_SHIFT) +#define I40E_REG_INSET_TUNNEL_L3_DST_IP6_SHIFT 6 +#define I40E_REG_INSET_TUNNEL_L3_DST_IP6_MASK I40E_MASK(0xFFULL, I40E_REG_INSET_TUNNEL_L3_DST_IP6_SHIFT) +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD1_SHIFT 13 +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD1_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_FLEX_PAYLOAD_WORD1_SHIFT) +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD2_SHIFT 12 +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD2_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_FLEX_PAYLOAD_WORD2_SHIFT) +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD3_SHIFT 11 +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD3_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_FLEX_PAYLOAD_WORD3_SHIFT) +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD4_SHIFT 10 +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD4_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_FLEX_PAYLOAD_WORD4_SHIFT) +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD5_SHIFT 9 +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD5_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_FLEX_PAYLOAD_WORD5_SHIFT) +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD6_SHIFT 8 +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD6_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_FLEX_PAYLOAD_WORD6_SHIFT) +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD7_SHIFT 7 +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD7_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_FLEX_PAYLOAD_WORD7_SHIFT) +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD8_SHIFT 6 +#define I40E_REG_INSET_FLEX_PAYLOAD_WORD8_MASK I40E_MASK(0x1ULL, I40E_REG_INSET_FLEX_PAYLOAD_WORD8_SHIFT) +#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS_SHIFT 6 +#define I40E_REG_INSET_FLEX_PAYLOAD_WORDS_MASK I40E_MASK(0xFFULL, I40E_REG_INSET_FLEX_PAYLOAD_WORDS_SHIFT) +#define I40E_REG_INSET_MASK_DEFAULT 0x0000000000000000ULL + #define I40E_VFINT_DYN_CTL01_WB_ON_ITR_SHIFT 30 #define I40E_VFINT_DYN_CTL01_WB_ON_ITR_MASK I40E_MASK(0x1, I40E_VFINT_DYN_CTL01_WB_ON_ITR_SHIFT) #define I40E_VFINT_DYN_CTLN1_WB_ON_ITR_SHIFT 30 diff --git a/drivers/net/i40e/base/i40e_status.h b/drivers/net/i40e/base/i40e_status.h index cd72169f14..89b05ede3e 100644 --- a/drivers/net/i40e/base/i40e_status.h +++ b/drivers/net/i40e/base/i40e_status.h @@ -19,7 +19,7 @@ enum i40e_status_code { I40E_ERR_ADAPTER_STOPPED = -9, I40E_ERR_INVALID_MAC_ADDR = -10, I40E_ERR_DEVICE_NOT_SUPPORTED = -11, - I40E_ERR_MASTER_REQUESTS_PENDING = -12, + I40E_ERR_PRIMARY_REQUESTS_PENDING = -12, I40E_ERR_INVALID_LINK_SETTINGS = -13, I40E_ERR_AUTONEG_NOT_COMPLETE = -14, I40E_ERR_RESET_FAILED = -15, diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h index 98952d9cfc..3cfb0ca430 100644 --- a/drivers/net/i40e/base/i40e_type.h +++ b/drivers/net/i40e/base/i40e_type.h @@ -38,7 +38,7 @@ #define I40E_MAX_PF_VSI 64 #define I40E_MAX_PF_QP 128 #define I40E_MAX_VSI_QP 16 -#define I40E_MAX_VF_VSI 3 +#define I40E_MAX_VF_VSI 4 #define I40E_MAX_CHAINED_RX_BUFFERS 5 #define I40E_MAX_PF_UDP_OFFLOAD_PORTS 16 @@ -236,6 +236,14 @@ enum i40e_queue_type { I40E_QUEUE_TYPE_UNKNOWN }; +enum i40e_prt_mac_link_speed { + I40E_PRT_MAC_LINK_SPEED_100MB = 0, + I40E_PRT_MAC_LINK_SPEED_1GB, + I40E_PRT_MAC_LINK_SPEED_10GB, + I40E_PRT_MAC_LINK_SPEED_40GB, + I40E_PRT_MAC_LINK_SPEED_20GB +}; + struct i40e_link_status { enum i40e_aq_phy_type phy_type; enum i40e_aq_link_speed link_speed; @@ -421,6 +429,7 @@ struct i40e_hw_capabilities { u32 enabled_tcmap; u32 maxtc; u64 wr_csr_prot; + bool dis_unused_ports; bool apm_wol_support; enum i40e_acpi_programming_method acpi_prog_method; bool proxy_support; @@ -474,6 +483,7 @@ enum i40e_nvmupd_cmd { I40E_NVMUPD_EXEC_AQ, I40E_NVMUPD_GET_AQ_RESULT, I40E_NVMUPD_GET_AQ_EVENT, + I40E_NVMUPD_FEATURES, }; enum i40e_nvmupd_state { @@ -509,6 +519,10 @@ enum i40e_nvmupd_state { #define I40E_NVM_AQE 0xe #define I40E_NVM_EXEC 0xf +#define I40E_NVM_EXEC_GET_AQ_RESULT 0x0 +#define I40E_NVM_EXEC_FEATURES 0xe +#define I40E_NVM_EXEC_STATUS 0xf + #define I40E_NVM_ADAPT_SHIFT 16 #define I40E_NVM_ADAPT_MASK (0xffffULL << I40E_NVM_ADAPT_SHIFT) @@ -523,6 +537,20 @@ struct i40e_nvm_access { u8 data[1]; }; +/* NVMUpdate features API */ +#define I40E_NVMUPD_FEATURES_API_VER_MAJOR 0 +#define I40E_NVMUPD_FEATURES_API_VER_MINOR 14 +#define I40E_NVMUPD_FEATURES_API_FEATURES_ARRAY_LEN 12 + +#define I40E_NVMUPD_FEATURE_FLAT_NVM_SUPPORT BIT(0) + +struct i40e_nvmupd_features { + u8 major; + u8 minor; + u16 size; + u8 features[I40E_NVMUPD_FEATURES_API_FEATURES_ARRAY_LEN]; +}; + /* (Q)SFP module access definitions */ #define I40E_I2C_EEPROM_DEV_ADDR 0xA0 #define I40E_I2C_EEPROM_DEV_ADDR2 0xA2 @@ -719,6 +747,10 @@ struct i40e_hw { #define I40E_HW_FLAG_AQ_PHY_ACCESS_CAPABLE BIT_ULL(2) #define I40E_HW_FLAG_NVM_READ_REQUIRES_LOCK BIT_ULL(3) #define I40E_HW_FLAG_FW_LLDP_STOPPABLE BIT_ULL(4) +#define I40E_HW_FLAG_FW_LLDP_PERSISTENT BIT_ULL(5) +#define I40E_HW_FLAG_AQ_PHY_ACCESS_EXTENDED BIT_ULL(6) +#define I40E_HW_FLAG_DROP_MODE BIT_ULL(7) +#define I40E_HW_FLAG_X722_FEC_REQUEST_CAPABLE BIT_ULL(8) u64 flags; /* Used in set switch config AQ command */ @@ -726,6 +758,9 @@ struct i40e_hw { u16 first_tag; u16 second_tag; + /* NVMUpdate features */ + struct i40e_nvmupd_features nvmupd_features; + /* debug mask */ u32 debug_mask; char err_str[16]; @@ -782,7 +817,7 @@ union i40e_32byte_rx_desc { __le64 rsvd2; } read; struct { - struct { + struct i40e_32b_rx_wb_qw0 { struct { union { __le16 mirroring_status; @@ -820,6 +855,9 @@ union i40e_32byte_rx_desc { } hi_dword; } qword3; } wb; /* writeback */ + struct { + u64 qword[4]; + } raw; }; #define I40E_RXD_QW0_MIRROR_STATUS_SHIFT 8 @@ -931,7 +969,8 @@ enum i40e_rx_l2_ptype { I40E_RX_PTYPE_GRENAT4_MAC_PAY3 = 58, I40E_RX_PTYPE_GRENAT4_MACVLAN_IPV6_ICMP_PAY4 = 87, I40E_RX_PTYPE_GRENAT6_MAC_PAY3 = 124, - I40E_RX_PTYPE_GRENAT6_MACVLAN_IPV6_ICMP_PAY4 = 153 + I40E_RX_PTYPE_GRENAT6_MACVLAN_IPV6_ICMP_PAY4 = 153, + I40E_RX_PTYPE_PARSER_ABORTED = 255 }; struct i40e_rx_ptype_decoded { @@ -1389,6 +1428,7 @@ struct i40e_eth_stats { u64 tx_broadcast; /* bptc */ u64 tx_discards; /* tdpc */ u64 tx_errors; /* tepc */ + u64 rx_discards_other; /* rxerr1 */ }; /* Statistics collected per VEB per TC */ @@ -1469,6 +1509,8 @@ struct i40e_hw_port_stats { u32 rx_lpi_status; u64 tx_lpi_count; /* etlpic */ u64 rx_lpi_count; /* erlpic */ + u64 tx_lpi_duration; + u64 rx_lpi_duration; }; /* Checksum and Shadow RAM pointers */ @@ -1521,6 +1563,9 @@ struct i40e_hw_port_stats { #define I40E_SR_FEATURE_CONFIGURATION_PTR 0x49 #define I40E_SR_CONFIGURATION_METADATA_PTR 0x4D #define I40E_SR_IMMEDIATE_VALUES_PTR 0x4E +#define I40E_SR_PRESERVATION_RULES_PTR 0x70 +#define I40E_X722_SR_5TH_FREE_PROVISION_AREA_PTR 0x71 +#define I40E_SR_6TH_FREE_PROVISION_AREA_PTR 0x71 /* Auxiliary field, mask and shift definition for Shadow RAM and NVM Flash */ #define I40E_SR_VPD_MODULE_MAX_SIZE 1024 @@ -1878,6 +1923,10 @@ struct i40e_lldp_variables { #define I40E_PFQF_CTL_0_HASHLUTSIZE_512 0x00010000 /* INPUT SET MASK for RSS, flow director, and flexible payload */ +#define I40E_X722_L3_SRC_SHIFT 49 +#define I40E_X722_L3_SRC_MASK (0x3ULL << I40E_X722_L3_SRC_SHIFT) +#define I40E_X722_L3_DST_SHIFT 41 +#define I40E_X722_L3_DST_MASK (0x3ULL << I40E_X722_L3_DST_SHIFT) #define I40E_L3_SRC_SHIFT 47 #define I40E_L3_SRC_MASK (0x3ULL << I40E_L3_SRC_SHIFT) #define I40E_L3_V6_SRC_SHIFT 43 @@ -1944,6 +1993,10 @@ struct i40e_metadata_segment { struct i40e_ddp_version version; #define I40E_DDP_TRACKID_RDONLY 0 #define I40E_DDP_TRACKID_INVALID 0xFFFFFFFF +#define I40E_DDP_TRACKID_GRP_MSK 0x00FF0000 +#define I40E_DDP_TRACKID_GRP_COMP_ALL 0xFF +#define I40E_DDP_TRACKID_PKGTYPE_MSK 0xFF000000 +#define I40E_DDP_TRACKID_PKGTYPE_RDONLY 0 u32 track_id; char name[I40E_DDP_NAME_SIZE]; }; @@ -2011,4 +2064,10 @@ struct i40e_profile_info { u8 reserved[7]; u8 name[I40E_DDP_NAME_SIZE]; }; + +#define I40E_BCM_PHY_PCS_STATUS1_PAGE 0x3 +#define I40E_BCM_PHY_PCS_STATUS1_REG 0x0001 +#define I40E_BCM_PHY_PCS_STATUS1_RX_LPI BIT(8) +#define I40E_BCM_PHY_PCS_STATUS1_TX_LPI BIT(9) + #endif /* _I40E_TYPE_H_ */ diff --git a/drivers/net/i40e/base/virtchnl.h b/drivers/net/i40e/base/virtchnl.h index 1b4e76f60b..97b3a28041 100644 --- a/drivers/net/i40e/base/virtchnl.h +++ b/drivers/net/i40e/base/virtchnl.h @@ -40,13 +40,19 @@ /* Error Codes */ enum virtchnl_status_code { VIRTCHNL_STATUS_SUCCESS = 0, - VIRTCHNL_ERR_PARAM = -5, + VIRTCHNL_STATUS_ERR_PARAM = -5, + VIRTCHNL_STATUS_ERR_NO_MEMORY = -18, VIRTCHNL_STATUS_ERR_OPCODE_MISMATCH = -38, VIRTCHNL_STATUS_ERR_CQP_COMPL_ERROR = -39, VIRTCHNL_STATUS_ERR_INVALID_VF_ID = -40, - VIRTCHNL_STATUS_NOT_SUPPORTED = -64, + VIRTCHNL_STATUS_ERR_ADMIN_QUEUE_ERROR = -53, + VIRTCHNL_STATUS_ERR_NOT_SUPPORTED = -64, }; +/* Backward compatibility */ +#define VIRTCHNL_ERR_PARAM VIRTCHNL_STATUS_ERR_PARAM +#define VIRTCHNL_STATUS_NOT_SUPPORTED VIRTCHNL_STATUS_ERR_NOT_SUPPORTED + #define VIRTCHNL_LINK_SPEED_2_5GB_SHIFT 0x0 #define VIRTCHNL_LINK_SPEED_100MB_SHIFT 0x1 #define VIRTCHNL_LINK_SPEED_1000MB_SHIFT 0x2 @@ -127,13 +133,13 @@ enum virtchnl_ops { }; -/* This macro is used to generate a compilation error if a structure +/* These macros are used to generate compilation errors if a structure/union * is not exactly the correct length. It gives a divide by zero error if the * structure is not of the correct size, otherwise it creates an enum that is * never used. */ #define VIRTCHNL_CHECK_STRUCT_LEN(n, X) enum virtchnl_static_assert_enum_##X \ - {virtchnl_static_assert_##X = (n) / ((sizeof(struct X) == (n)) ? 1 : 0)} + { virtchnl_static_assert_##X = (n) / ((sizeof(struct X) == (n)) ? 1 : 0) } /* Virtual channel message descriptor. This overlays the admin queue * descriptor. All other data is passed in external buffers. @@ -226,6 +232,7 @@ VIRTCHNL_CHECK_STRUCT_LEN(16, virtchnl_vsi_resource); #define VIRTCHNL_VF_OFFLOAD_RSS_REG 0x00000010 #define VIRTCHNL_VF_OFFLOAD_WB_ON_ITR 0x00000020 #define VIRTCHNL_VF_OFFLOAD_REQ_QUEUES 0x00000040 +#define VIRTCHNL_VF_OFFLOAD_CRC 0x00000080 #define VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000 #define VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000 #define VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 0x00040000 @@ -275,7 +282,13 @@ VIRTCHNL_CHECK_STRUCT_LEN(24, virtchnl_txq_info); /* VIRTCHNL_OP_CONFIG_RX_QUEUE * VF sends this message to set up parameters for one RX queue. * External data buffer contains one instance of virtchnl_rxq_info. - * PF configures requested queue and returns a status code. + * PF configures requested queue and returns a status code. The + * crc_disable flag disables CRC stripping on the VF. Setting + * the crc_disable flag to 1 will disable CRC stripping for each + * queue in the VF where the flag is set. The VIRTCHNL_VF_OFFLOAD_CRC + * offload must have been set prior to sending this info or the PF + * will ignore the request. This flag should be set the same for + * all of the queues for a VF. */ /* Rx queue config info */ @@ -287,7 +300,8 @@ struct virtchnl_rxq_info { u16 splithdr_enabled; /* deprecated with AVF 1.0 */ u32 databuffer_size; u32 max_pkt_size; - u32 pad1; + u8 crc_disable; + u8 pad1[3]; u64 dma_ring_addr; enum virtchnl_rx_hsplit rx_split_pos; /* deprecated with AVF 1.0 */ u32 pad2; @@ -777,7 +791,7 @@ virtchnl_vc_validate_vf_msg(struct virtchnl_version_info *ver, u32 v_opcode, case VIRTCHNL_OP_EVENT: case VIRTCHNL_OP_UNKNOWN: default: - return VIRTCHNL_ERR_PARAM; + return VIRTCHNL_STATUS_ERR_PARAM; } /* few more checks */ if (err_msg_format || valid_len != msglen) diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c index 62ef536464..bf2226be04 100644 --- a/drivers/net/i40e/i40e_ethdev.c +++ b/drivers/net/i40e/i40e_ethdev.c @@ -322,7 +322,6 @@ static int i40e_dev_init_vlan(struct rte_eth_dev *dev); static int i40e_veb_release(struct i40e_veb *veb); static struct i40e_veb *i40e_veb_setup(struct i40e_pf *pf, struct i40e_vsi *vsi); -static int i40e_pf_config_mq_rx(struct i40e_pf *pf); static int i40e_vsi_config_double_vlan(struct i40e_vsi *vsi, int on); static inline int i40e_find_all_mac_for_vlan(struct i40e_vsi *vsi, struct i40e_macvlan_filter *mv_f, @@ -400,6 +399,7 @@ static int i40e_set_default_mac_addr(struct rte_eth_dev *dev, struct rte_ether_addr *mac_addr); static int i40e_dev_mtu_set(struct rte_eth_dev *dev, uint16_t mtu); +static void i40e_set_mac_max_frame(struct rte_eth_dev *dev, uint16_t size); static int i40e_ethertype_filter_convert( const struct rte_eth_ethertype_filter *input, @@ -418,6 +418,7 @@ static void i40e_ethertype_filter_restore(struct i40e_pf *pf); static void i40e_tunnel_filter_restore(struct i40e_pf *pf); static void i40e_filter_restore(struct i40e_pf *pf); static void i40e_notify_all_vfs_link_status(struct rte_eth_dev *dev); +static int i40e_pf_config_rss(struct i40e_pf *pf); int i40e_logtype_init; int i40e_logtype_driver; @@ -464,6 +465,9 @@ static const struct rte_pci_id pci_id_i40e_map[] = { { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_X710_N3000) }, { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_XXV710_N3000) }, { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_BC) }, + { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_5G_BASE_T_BC) }, + { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_B) }, + { RTE_PCI_DEVICE(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_SFP) }, { .vendor_id = 0, /* sentinel */ }, }; @@ -1686,11 +1690,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev, void *init_params __rte_unused) */ i40e_add_tx_flow_control_drop_filter(pf); - /* Set the max frame size to 0x2600 by default, - * in case other drivers changed the default value. - */ - i40e_aq_set_mac_config(hw, I40E_FRAME_SIZE_MAX, TRUE, 0, NULL); - /* initialize mirror rule list */ TAILQ_INIT(&pf->mirror_list); @@ -1886,8 +1885,6 @@ i40e_dev_configure(struct rte_eth_dev *dev) goto err; /* VMDQ setup. - * Needs to move VMDQ setting out of i40e_pf_config_mq_rx() as VMDQ and - * RSS setting have different requirements. * General PMD call sequence are NIC init, configure, * rx/tx_queue_setup and dev_start. In rx/tx_queue_setup() function, it * will try to lookup the VSI that specific queue belongs to if VMDQ @@ -2327,6 +2324,7 @@ i40e_dev_start(struct rte_eth_dev *dev) uint32_t intr_vector = 0; struct i40e_vsi *vsi; uint16_t nb_rxq, nb_txq; + uint16_t max_frame_size; hw->adapter_stopped = 0; @@ -2468,6 +2466,9 @@ i40e_dev_start(struct rte_eth_dev *dev) "please call hierarchy_commit() " "before starting the port"); + max_frame_size = dev->data->mtu + I40E_ETH_OVERHEAD; + i40e_set_mac_max_frame(dev, max_frame_size); + return I40E_SUCCESS; tx_err: @@ -2830,11 +2831,13 @@ i40e_dev_set_link_down(struct rte_eth_dev *dev) return i40e_phy_conf_link(hw, abilities, speed, false); } +#define CHECK_INTERVAL 100 /* 100ms */ +#define MAX_REPEAT_TIME 10 /* 1s (10 * 100ms) in total */ + static __rte_always_inline void update_link_reg(struct i40e_hw *hw, struct rte_eth_link *link) { /* Link status registers and values*/ -#define I40E_PRTMAC_LINKSTA 0x001E2420 #define I40E_REG_LINK_UP 0x40000080 #define I40E_PRTMAC_MACC 0x001E24E0 #define I40E_REG_MACC_25GB 0x00020000 @@ -2847,7 +2850,7 @@ update_link_reg(struct i40e_hw *hw, struct rte_eth_link *link) uint32_t link_speed; uint32_t reg_val; - reg_val = I40E_READ_REG(hw, I40E_PRTMAC_LINKSTA); + reg_val = I40E_READ_REG(hw, I40E_PRTMAC_LINKSTA(0)); link_speed = reg_val & I40E_REG_SPEED_MASK; reg_val &= I40E_REG_LINK_UP; link->link_status = (reg_val == I40E_REG_LINK_UP) ? 1 : 0; @@ -2897,8 +2900,6 @@ static __rte_always_inline void update_link_aq(struct i40e_hw *hw, struct rte_eth_link *link, bool enable_lse, int wait_to_complete) { -#define CHECK_INTERVAL 100 /* 100ms */ -#define MAX_REPEAT_TIME 10 /* 1s (10 * 100ms) in total */ uint32_t rep_cnt = MAX_REPEAT_TIME; struct i40e_link_status link_status; int status; @@ -3182,7 +3183,7 @@ i40e_read_stats_registers(struct i40e_pf *pf, struct i40e_hw *hw) &os->eth.rx_unknown_protocol, &ns->eth.rx_unknown_protocol); i40e_stat_update_48(hw, I40E_GL_RXERR1_H(hw->pf_id + I40E_MAX_VF), - I40E_GL_RXERR1_L(hw->pf_id + I40E_MAX_VF), + I40E_GL_RXERR1L(hw->pf_id + I40E_MAX_VF), pf->offset_loaded, &pf->rx_err1_offset, &pf->rx_err1); i40e_stat_update_48_in_64(hw, I40E_GLPRT_GOTCH(hw->port), @@ -6498,7 +6499,7 @@ i40e_dev_rx_init(struct i40e_pf *pf) uint16_t i; struct i40e_rx_queue *rxq; - i40e_pf_config_mq_rx(pf); + i40e_pf_config_rss(pf); for (i = 0; i < data->nb_rx_queues; i++) { rxq = data->rx_queues[i]; if (!rxq || !rxq->q_set) @@ -7010,6 +7011,7 @@ i40e_remove_macvlan_filters(struct i40e_vsi *vsi, int ret = I40E_SUCCESS; struct i40e_hw *hw = I40E_VSI_TO_HW(vsi); struct i40e_aqc_remove_macvlan_element_data *req_list; + enum i40e_admin_queue_err aq_status; if (filter == NULL || total == 0) return I40E_ERR_PARAM; @@ -7057,11 +7059,17 @@ i40e_remove_macvlan_filters(struct i40e_vsi *vsi, req_list[i].flags = rte_cpu_to_le_16(flags); } - ret = i40e_aq_remove_macvlan(hw, vsi->seid, req_list, - actual_num, NULL); + ret = i40e_aq_remove_macvlan_v2(hw, vsi->seid, req_list, + actual_num, NULL, &aq_status); + if (ret != I40E_SUCCESS) { - PMD_DRV_LOG(ERR, "Failed to remove macvlan filter"); - goto DONE; + /* Do not report as an error when firmware returns ENOENT */ + if (aq_status == I40E_AQ_RC_ENOENT) { + ret = I40E_SUCCESS; + } else { + PMD_DRV_LOG(ERR, "Failed to remove macvlan filter"); + goto DONE; + } } num += actual_num; } while (num < total); @@ -8723,6 +8731,7 @@ i40e_pf_calc_configured_queues_num(struct i40e_pf *pf) static int i40e_pf_config_rss(struct i40e_pf *pf) { + enum rte_eth_rx_mq_mode mq_mode = pf->dev_data->dev_conf.rxmode.mq_mode; struct i40e_hw *hw = I40E_PF_TO_HW(pf); struct rte_eth_rss_conf rss_conf; uint32_t i, lut = 0; @@ -8759,7 +8768,8 @@ i40e_pf_config_rss(struct i40e_pf *pf) } rss_conf = pf->dev_data->dev_conf.rx_adv_conf.rss_conf; - if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0) { + if ((rss_conf.rss_hf & pf->adapter->flow_types_mask) == 0 || + !(mq_mode & ETH_MQ_RX_RSS_FLAG)) { i40e_pf_disable_rss(pf); return 0; } @@ -8932,21 +8942,6 @@ i40e_tunnel_filter_handle(struct rte_eth_dev *dev, return ret; } -static int -i40e_pf_config_mq_rx(struct i40e_pf *pf) -{ - int ret = 0; - enum rte_eth_rx_mq_mode mq_mode = pf->dev_data->dev_conf.rxmode.mq_mode; - - /* RSS setup */ - if (mq_mode & ETH_MQ_RX_RSS_FLAG) - ret = i40e_pf_config_rss(pf); - else - i40e_pf_disable_rss(pf); - - return ret; -} - /* Get the symmetric hash enable configurations per port */ static void i40e_get_symmetric_hash_enable_per_port(struct i40e_hw *hw, uint8_t *enable) @@ -11707,13 +11702,17 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb) * LLDP MIB change event. */ if (sw_dcb == TRUE) { - if (i40e_need_stop_lldp(dev)) { - ret = i40e_aq_stop_lldp(hw, TRUE, NULL); - if (ret != I40E_SUCCESS) - PMD_INIT_LOG(DEBUG, "Failed to stop lldp"); - } + /* Stopping lldp is necessary for DPDK, but it will cause + * DCB init failed. For i40e_init_dcb(), the prerequisite + * for successful initialization of DCB is that LLDP is + * enabled. So it is needed to start lldp before DCB init + * and stop it after initialization. + */ + ret = i40e_aq_start_lldp(hw, true, NULL); + if (ret != I40E_SUCCESS) + PMD_INIT_LOG(DEBUG, "Failed to start lldp"); - ret = i40e_init_dcb(hw); + ret = i40e_init_dcb(hw, true); /* If lldp agent is stopped, the return value from * i40e_init_dcb we expect is failure with I40E_AQ_RC_EPERM * adminq status. Otherwise, it should return success. @@ -11756,12 +11755,17 @@ i40e_dcb_init_configure(struct rte_eth_dev *dev, bool sw_dcb) ret, hw->aq.asq_last_status); return -ENOTSUP; } + if (i40e_need_stop_lldp(dev)) { + ret = i40e_aq_stop_lldp(hw, TRUE, TRUE, NULL); + if (ret != I40E_SUCCESS) + PMD_INIT_LOG(DEBUG, "Failed to stop lldp"); + } } else { - ret = i40e_aq_start_lldp(hw, NULL); + ret = i40e_aq_start_lldp(hw, true, NULL); if (ret != I40E_SUCCESS) PMD_INIT_LOG(DEBUG, "Failed to start lldp"); - ret = i40e_init_dcb(hw); + ret = i40e_init_dcb(hw, true); if (!ret) { if (hw->dcbx_status == I40E_DCBX_STATUS_DISABLED) { PMD_INIT_LOG(ERR, @@ -12893,6 +12897,31 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf) return ret; } +static void +i40e_set_mac_max_frame(struct rte_eth_dev *dev, uint16_t size) +{ + struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private); + uint32_t rep_cnt = MAX_REPEAT_TIME; + struct rte_eth_link link; + enum i40e_status_code status; + + do { + update_link_reg(hw, &link); + if (link.link_status) + break; + + rte_delay_ms(CHECK_INTERVAL); + } while (--rep_cnt); + + if (link.link_status) { + status = i40e_aq_set_mac_config(hw, size, TRUE, 0, false, NULL); + if (status != I40E_SUCCESS) + PMD_DRV_LOG(ERR, "Failed to set max frame size at port level"); + } else { + PMD_DRV_LOG(ERR, "Set max frame size at port level not applicable on link down"); + } +} + int i40e_rss_conf_init(struct i40e_rte_flow_rss_conf *out, const struct rte_flow_action_rss *in) diff --git a/drivers/net/i40e/i40e_ethdev_vf.c b/drivers/net/i40e/i40e_ethdev_vf.c index 9f1c0f4ac4..33aec61e6a 100644 --- a/drivers/net/i40e/i40e_ethdev_vf.c +++ b/drivers/net/i40e/i40e_ethdev_vf.c @@ -677,44 +677,68 @@ i40evf_config_irq_map(struct rte_eth_dev *dev) { struct i40e_vf *vf = I40EVF_DEV_PRIVATE_TO_VF(dev->data->dev_private); struct vf_cmd_info args; - uint8_t cmd_buffer[sizeof(struct virtchnl_irq_map_info) + \ - sizeof(struct virtchnl_vector_map)]; + uint8_t *cmd_buffer = NULL; struct virtchnl_irq_map_info *map_info; struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(dev); struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; - uint32_t vector_id; - int i, err; + uint32_t vec, cmd_buffer_size, max_vectors, nb_msix, msix_base, i; + uint16_t rxq_map[vf->vf_res->max_vectors]; + int err; + memset(rxq_map, 0, sizeof(rxq_map)); if (dev->data->dev_conf.intr_conf.rxq != 0 && - rte_intr_allow_others(intr_handle)) - vector_id = I40E_RX_VEC_START; - else - vector_id = I40E_MISC_VEC_ID; + rte_intr_allow_others(intr_handle)) { + msix_base = I40E_RX_VEC_START; + /* For interrupt mode, available vector id is from 1. */ + max_vectors = vf->vf_res->max_vectors - 1; + nb_msix = RTE_MIN(max_vectors, intr_handle->nb_efd); + + vec = msix_base; + for (i = 0; i < dev->data->nb_rx_queues; i++) { + rxq_map[vec] |= 1 << i; + intr_handle->intr_vec[i] = vec++; + if (vec >= vf->vf_res->max_vectors) + vec = msix_base; + } + } else { + msix_base = I40E_MISC_VEC_ID; + nb_msix = 1; + + for (i = 0; i < dev->data->nb_rx_queues; i++) { + rxq_map[msix_base] |= 1 << i; + if (rte_intr_dp_is_en(intr_handle)) + intr_handle->intr_vec[i] = msix_base; + } + } + + cmd_buffer_size = sizeof(struct virtchnl_irq_map_info) + + sizeof(struct virtchnl_vector_map) * nb_msix; + cmd_buffer = rte_zmalloc("i40e", cmd_buffer_size, 0); + if (!cmd_buffer) { + PMD_DRV_LOG(ERR, "Failed to allocate memory"); + return I40E_ERR_NO_MEMORY; + } map_info = (struct virtchnl_irq_map_info *)cmd_buffer; - map_info->num_vectors = 1; - map_info->vecmap[0].rxitr_idx = I40E_ITR_INDEX_DEFAULT; - map_info->vecmap[0].vsi_id = vf->vsi_res->vsi_id; - /* Alway use default dynamic MSIX interrupt */ - map_info->vecmap[0].vector_id = vector_id; - /* Don't map any tx queue */ - map_info->vecmap[0].txq_map = 0; - map_info->vecmap[0].rxq_map = 0; - for (i = 0; i < dev->data->nb_rx_queues; i++) { - map_info->vecmap[0].rxq_map |= 1 << i; - if (rte_intr_dp_is_en(intr_handle)) - intr_handle->intr_vec[i] = vector_id; + map_info->num_vectors = nb_msix; + for (i = 0; i < nb_msix; i++) { + map_info->vecmap[i].rxitr_idx = I40E_ITR_INDEX_DEFAULT; + map_info->vecmap[i].vsi_id = vf->vsi_res->vsi_id; + map_info->vecmap[i].vector_id = msix_base + i; + map_info->vecmap[i].txq_map = 0; + map_info->vecmap[i].rxq_map = rxq_map[msix_base + i]; } args.ops = VIRTCHNL_OP_CONFIG_IRQ_MAP; args.in_args = (u8 *)cmd_buffer; - args.in_args_size = sizeof(cmd_buffer); + args.in_args_size = cmd_buffer_size; args.out_buffer = vf->aq_resp; args.out_size = I40E_AQ_BUF_SZ; err = i40evf_execute_vf_cmd(dev, &args); if (err) PMD_DRV_LOG(ERR, "fail to execute command OP_ENABLE_QUEUES"); + rte_free(cmd_buffer); return err; } @@ -1214,7 +1238,7 @@ i40evf_reset_vf(struct rte_eth_dev *dev) * it to ACTIVE. In this duration, vf may not catch the moment that * COMPLETE is set. So, for vf, we'll try to wait a long time. */ - rte_delay_ms(200); + rte_delay_ms(500); ret = i40evf_check_vf_reset_done(dev); if (ret) { diff --git a/drivers/net/i40e/i40e_regs.h b/drivers/net/i40e/i40e_regs.h index b19bb1d5a5..cf62c9dfb7 100644 --- a/drivers/net/i40e/i40e_regs.h +++ b/drivers/net/i40e/i40e_regs.h @@ -586,9 +586,6 @@ static const struct i40e_reg_info i40e_regs_others[] = { {I40E_GLHMC_PEARPMAX, 0, 0, 0, 0, "GLHMC_PEARPMAX"}, {I40E_GLHMC_PEMROBJSZ, 0, 0, 0, 0, "GLHMC_PEMROBJSZ"}, {I40E_GLHMC_PEMRMAX, 0, 0, 0, 0, "GLHMC_PEMRMAX"}, - {I40E_GLHMC_PEXFOBJSZ, 0, 0, 0, 0, "GLHMC_PEXFOBJSZ"}, - {I40E_GLHMC_PEXFMAX, 0, 0, 0, 0, "GLHMC_PEXFMAX"}, - {I40E_GLHMC_PEXFFLMAX, 0, 0, 0, 0, "GLHMC_PEXFFLMAX"}, {I40E_GLHMC_PEQ1OBJSZ, 0, 0, 0, 0, "GLHMC_PEQ1OBJSZ"}, {I40E_GLHMC_PEQ1MAX, 0, 0, 0, 0, "GLHMC_PEQ1MAX"}, {I40E_GLHMC_PEQ1FLMAX, 0, 0, 0, 0, "GLHMC_PEQ1FLMAX"}, @@ -616,9 +613,6 @@ static const struct i40e_reg_info i40e_regs_others[] = { {I40E_GLHMC_APBVTINUSEBASE(0), 15, 4, 0, 0, "GLHMC_APBVTINUSEBASE"}, {I40E_GLHMC_PEMRBASE(0), 15, 4, 0, 0, "GLHMC_PEMRBASE"}, {I40E_GLHMC_PEMRCNT(0), 15, 4, 0, 0, "GLHMC_PEMRCNT"}, - {I40E_GLHMC_PEXFBASE(0), 15, 4, 0, 0, "GLHMC_PEXFBASE"}, - {I40E_GLHMC_PEXFCNT(0), 15, 4, 0, 0, "GLHMC_PEXFCNT"}, - {I40E_GLHMC_PEXFFLBASE(0), 15, 4, 0, 0, "GLHMC_PEXFFLBASE"}, {I40E_GLHMC_PEQ1BASE(0), 15, 4, 0, 0, "GLHMC_PEQ1BASE"}, {I40E_GLHMC_PEQ1CNT(0), 15, 4, 0, 0, "GLHMC_PEQ1CNT"}, {I40E_GLHMC_PEQ1FLBASE(0), 15, 4, 0, 0, "GLHMC_PEQ1FLBASE"}, @@ -653,9 +647,6 @@ static const struct i40e_reg_info i40e_regs_others[] = { {I40E_GLHMC_VFAPBVTINUSEBASE(0), 31, 4, 0, 0, "GLHMC_VFAPBVTINUSEBASE"}, {I40E_GLHMC_VFPEMRBASE(0), 31, 4, 0, 0, "GLHMC_VFPEMRBASE"}, {I40E_GLHMC_VFPEMRCNT(0), 31, 4, 0, 0, "GLHMC_VFPEMRCNT"}, - {I40E_GLHMC_VFPEXFBASE(0), 31, 4, 0, 0, "GLHMC_VFPEXFBASE"}, - {I40E_GLHMC_VFPEXFCNT(0), 31, 4, 0, 0, "GLHMC_VFPEXFCNT"}, - {I40E_GLHMC_VFPEXFFLBASE(0), 31, 4, 0, 0, "GLHMC_VFPEXFFLBASE"}, {I40E_GLHMC_VFPEQ1BASE(0), 31, 4, 0, 0, "GLHMC_VFPEQ1BASE"}, {I40E_GLHMC_VFPEQ1CNT(0), 31, 4, 0, 0, "GLHMC_VFPEQ1CNT"}, {I40E_GLHMC_VFPEQ1FLBASE(0), 31, 4, 0, 0, "GLHMC_VFPEQ1FLBASE"}, @@ -896,7 +887,7 @@ static const struct i40e_reg_info i40e_regs_others[] = { {I40E_GL_FCOEDDPC(0), 143, 8, 0, 0, "GL_FCOEDDPC"}, {I40E_GL_FCOECRC(0), 143, 8, 0, 0, "GL_FCOECRC"}, {I40E_GL_FCOEPRC(0), 143, 8, 0, 0, "GL_FCOEPRC"}, - {I40E_GL_RXERR1_L(0), 143, 8, 0, 0, "GL_RXERR1_L"}, + {I40E_GL_RXERR1L(0), 143, 8, 0, 0, "GL_RXERR1_L"}, {I40E_GL_FCOEDIFEC(0), 143, 8, 0, 0, "GL_FCOEDIFEC"}, {I40E_GL_RXERR2_L(0), 143, 8, 0, 0, "GL_RXERR2_L"}, {I40E_GL_FCOEDWRCL(0), 143, 8, 0, 0, "GL_FCOEDWRCL"}, diff --git a/drivers/net/i40e/rte_pmd_i40e.c b/drivers/net/i40e/rte_pmd_i40e.c index cd2ec58df7..1d4ec81529 100644 --- a/drivers/net/i40e/rte_pmd_i40e.c +++ b/drivers/net/i40e/rte_pmd_i40e.c @@ -1409,7 +1409,7 @@ rte_pmd_i40e_set_tc_strict_prio(uint16_t port, uint8_t tc_map) /* Disable DCBx if it's the first time to set strict priority. */ if (!veb->strict_prio_tc) { - ret = i40e_aq_stop_lldp(hw, true, NULL); + ret = i40e_aq_stop_lldp(hw, true, true, NULL); if (ret) PMD_DRV_LOG(INFO, "Failed to disable DCBx as it's already" @@ -1464,7 +1464,7 @@ rte_pmd_i40e_set_tc_strict_prio(uint16_t port, uint8_t tc_map) /* Enable DCBx again, if all the TCs' strict priority disabled. */ if (!tc_map) { - ret = i40e_aq_start_lldp(hw, NULL); + ret = i40e_aq_start_lldp(hw, true, NULL); if (ret) { PMD_DRV_LOG(ERR, "Failed to enable DCBx, err(%d).", ret);