From patchwork Fri Aug 30 16:35:25 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58307 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 422231E99E; Fri, 30 Aug 2019 18:35:52 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 3F0D51E986 for ; Fri, 30 Aug 2019 18:35:47 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 1F0DC30C051; Fri, 30 Aug 2019 09:35:40 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 1F0DC30C051 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182940; bh=OrNhxr3sLTBNgNftDq50RfH2tB5WGvhSVKTmDRUJ1cU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=jlSozPqoqGeujikZYvsLjei8BsctghBY8g/Q/8TmjR7QrsnrXhmC4uPwULlzbQjKO 92Ev/HKB0rVk/R8/8VaqLx2vVR8ThaT27RygCJYdhHWoc93isdGvPRzlueVWJl6SfZ JPy1ad4NabdChRDsWC1KCGq+kgD60goyClngOwjQ= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id 4B395AC06AD; Fri, 30 Aug 2019 09:35:41 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:25 -0700 Message-Id: <20190830163537.32704-2-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 01/13] net/bnxt: add FW reset HWRM command X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP This patch adds new FW reset HWRM command. This command allows the host software to reset the underlying hardware if a device error is detected. Code using this command will be added in future patch. Signed-off-by: Kalesh AP Reviewed-by: Somnath Kotur Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/hsi_struct_def_dpdk.h | 137 +++++++++++++++++++++++++ 1 file changed, 137 insertions(+) diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h index 6c98c1d6d..009571725 100644 --- a/drivers/net/bnxt/hsi_struct_def_dpdk.h +++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h @@ -33621,4 +33621,141 @@ struct hwrm_nvm_validate_option_cmd_err { uint8_t unused_0[7]; } __attribute__((packed)); +/***************** + * hwrm_fw_reset * + ******************/ + + +/* hwrm_fw_reset_input (size:192b/24B) */ +struct hwrm_fw_reset_input { + /* The HWRM command request type. */ + uint16_t req_type; + /* + * The completion ring to send the completion event on. This should + * be the NQ ID returned from the `nq_alloc` HWRM command. + */ + uint16_t cmpl_ring; + /* + * The sequence ID is used by the driver for tracking multiple + * commands. This ID is treated as opaque data by the firmware and + * the value is returned in the `hwrm_resp_hdr` upon completion. + */ + uint16_t seq_id; + /* + * The target ID of the command: + * * 0x0-0xFFF8 - The function ID + * * 0xFFF8-0xFFFE - Reserved for internal processors + * * 0xFFFF - HWRM + */ + uint16_t target_id; + /* + * A physical address pointer pointing to a host buffer that the + * command's response data will be written. This can be either a host + * physical address (HPA) or a guest physical address (GPA) and must + * point to a physically contiguous block of memory. + */ + uint64_t resp_addr; + /* Type of embedded processor. */ + uint8_t embedded_proc_type; + /* Boot Processor */ + #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_BOOT \ + UINT32_C(0x0) + /* Management Processor */ + #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_MGMT \ + UINT32_C(0x1) + /* Network control processor */ + #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_NETCTRL \ + UINT32_C(0x2) + /* RoCE control processor */ + #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_ROCE \ + UINT32_C(0x3) + /* + * Host (in multi-host environment): This is only valid if requester is IPC. + * Reinit host hardware resources and PCIe. + */ + #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_HOST \ + UINT32_C(0x4) + /* AP processor complex (in multi-host environment). Use host_idx to control which core is reset */ + #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_AP \ + UINT32_C(0x5) + /* Reset all blocks of the chip (including all processors) */ + #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_CHIP \ + UINT32_C(0x6) + /* + * Host (in multi-host environment): This is only valid if requester is IPC. + * Reinit host hardware resources. + */ + #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_HOST_RESOURCE_REINIT \ + UINT32_C(0x7) + #define HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_LAST \ + HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_HOST_RESOURCE_REINIT + /* Type of self reset. */ + uint8_t selfrst_status; + /* No Self Reset */ + #define HWRM_FW_RESET_INPUT_SELFRST_STATUS_SELFRSTNONE \ + UINT32_C(0x0) + /* Self Reset as soon as possible to do so safely */ + #define HWRM_FW_RESET_INPUT_SELFRST_STATUS_SELFRSTASAP \ + UINT32_C(0x1) + /* Self Reset on PCIe Reset */ + #define HWRM_FW_RESET_INPUT_SELFRST_STATUS_SELFRSTPCIERST \ + UINT32_C(0x2) + /* Self Reset immediately after notification to all clients. */ + #define HWRM_FW_RESET_INPUT_SELFRST_STATUS_SELFRSTIMMEDIATE \ + UINT32_C(0x3) + #define HWRM_FW_RESET_INPUT_SELFRST_STATUS_LAST \ + HWRM_FW_RESET_INPUT_SELFRST_STATUS_SELFRSTIMMEDIATE + /* + * Indicate which host is being reset. 0 means first host. + * Only valid when embedded_proc_type is host in multihost + * environment + */ + uint8_t host_idx; + uint8_t flags; + /* + * When this bit is '1', then the core firmware initiates + * the reset only after graceful shut down of all registered instances. + * If not, the device will continue with the existing firmware. + */ + #define HWRM_FW_RESET_INPUT_FLAGS_RESET_GRACEFUL UINT32_C(0x1) + uint8_t unused_0[4]; +} __attribute__((packed)); + +/* hwrm_fw_reset_output (size:128b/16B) */ +struct hwrm_fw_reset_output { + /* The specific error status for the command. */ + uint16_t error_code; + /* The HWRM command request type. */ + uint16_t req_type; + /* The sequence ID from the original command. */ + uint16_t seq_id; + /* The length of the response data in number of bytes. */ + uint16_t resp_len; + /* Type of self reset. */ + uint8_t selfrst_status; + /* No Self Reset */ + #define HWRM_FW_RESET_OUTPUT_SELFRST_STATUS_SELFRSTNONE \ + UINT32_C(0x0) + /* Self Reset as soon as possible to do so safely */ + #define HWRM_FW_RESET_OUTPUT_SELFRST_STATUS_SELFRSTASAP \ + UINT32_C(0x1) + /* Self Reset on PCIe Reset */ + #define HWRM_FW_RESET_OUTPUT_SELFRST_STATUS_SELFRSTPCIERST \ + UINT32_C(0x2) + /* Self Reset immediately after notification to all clients. */ + #define HWRM_FW_RESET_OUTPUT_SELFRST_STATUS_SELFRSTIMMEDIATE \ + UINT32_C(0x3) + #define HWRM_FW_RESET_OUTPUT_SELFRST_STATUS_LAST \ + HWRM_FW_RESET_OUTPUT_SELFRST_STATUS_SELFRSTIMMEDIATE + uint8_t unused_0[6]; + /* + * This field is used in Output records to indicate that the output + * is completely written to RAM. This field should be read as '1' + * to indicate that the output has been completely written. + * When writing a command completion or response to an internal processor, + * the order of writes has to be such that this field is written last. + */ + uint8_t valid; +} __attribute__((packed)); + #endif /* _HSI_STRUCT_DEF_DPDK_H_ */ From patchwork Fri Aug 30 16:35:26 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58310 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 9F92D1E9B3; Fri, 30 Aug 2019 18:36:00 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 480981E998 for ; Fri, 30 Aug 2019 18:35:47 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 63E1030C054; Fri, 30 Aug 2019 09:35:40 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 63E1030C054 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182940; bh=SCoDg4dfmcQbhLTirlEWRaMTS0JaKULqcSu+hzHZc0Q=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IJhxtmzVP7sHa1N6Y4HQFS2dgqhb/oArElQb4adHeemu0ncCYEGL5ypBhqpHetznh 1QkblhiuZEjqNDeJ8M7i+EqC+JSwJs7WCCJo1tD6YTbW4gbHR1uOWQaREkyH08oGYQ J+WWspnWGcK/fmohN2zWPO6YDZByM3X21x/yGo1g= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id 8846CAC071D; Fri, 30 Aug 2019 09:35:41 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Santoshkumar Karanappa Rastapur , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:26 -0700 Message-Id: <20190830163537.32704-3-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 02/13] net/bnxt: prevent device access when device is in reset X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP Refactor init and uninit functions so that the driver can fail the eth_dev_ops callbacks and accessing Tx and Rx queues when device is in reset or in error state. Transmit and receive queues are freed during reset cleanup and reallocated during recovery. So we block all data path handling in this state. The eth_dev dev_started field is updated depending on the status of the device. Signed-off-by: Kalesh AP Reviewed-by: Ajit Khaparde Reviewed-by: Santoshkumar Karanappa Rastapur Reviewed-by: Somnath Kotur --- drivers/net/bnxt/bnxt.h | 3 + drivers/net/bnxt/bnxt_ethdev.c | 455 ++++++++++++++++++++++----------- drivers/net/bnxt/bnxt_hwrm.c | 2 - drivers/net/bnxt/bnxt_ring.c | 32 +++ drivers/net/bnxt/bnxt_ring.h | 1 + drivers/net/bnxt/bnxt_rxq.c | 25 ++ drivers/net/bnxt/bnxt_rxr.c | 17 ++ drivers/net/bnxt/bnxt_rxr.h | 2 + drivers/net/bnxt/bnxt_stats.c | 34 ++- drivers/net/bnxt/bnxt_txq.c | 7 + drivers/net/bnxt/bnxt_txr.c | 27 ++ drivers/net/bnxt/bnxt_txr.h | 2 + 12 files changed, 454 insertions(+), 153 deletions(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 0c9f994ea..37b4c717d 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -358,6 +358,8 @@ struct bnxt { #define BNXT_FLAG_DFLT_VNIC_SET (1 << 12) #define BNXT_FLAG_THOR_CHIP (1 << 13) #define BNXT_FLAG_STINGRAY (1 << 14) +#define BNXT_FLAG_FW_RESET (1 << 15) +#define BNXT_FLAG_FATAL_ERROR (1 << 16) #define BNXT_FLAG_EXT_STATS_SUPPORTED (1 << 29) #define BNXT_FLAG_NEW_RM (1 << 30) #define BNXT_FLAG_INIT_DONE (1U << 31) @@ -465,6 +467,7 @@ struct bnxt { int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete); int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg); +int is_bnxt_in_error(struct bnxt *bp); bool is_bnxt_supported(struct rte_eth_dev *dev); bool bnxt_stratus_device(struct bnxt *bp); diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 6685ee7d9..33ff4a5a7 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -167,6 +167,16 @@ static void bnxt_print_link_info(struct rte_eth_dev *eth_dev); static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu); static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev); +int is_bnxt_in_error(struct bnxt *bp) +{ + if (bp->flags & BNXT_FLAG_FATAL_ERROR) + return -EIO; + if (bp->flags & BNXT_FLAG_FW_RESET) + return -EBUSY; + + return 0; +} + /***********************/ /* @@ -207,6 +217,10 @@ static int bnxt_alloc_mem(struct bnxt *bp) { int rc; + rc = bnxt_alloc_ring_grps(bp); + if (rc) + goto alloc_mem_err; + rc = bnxt_alloc_async_ring_struct(bp); if (rc) goto alloc_mem_err; @@ -501,6 +515,9 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev, uint16_t max_vnics, i, j, vpool, vrxq; unsigned int max_rx_rings; + if (is_bnxt_in_error(bp)) + return; + /* MAC Specifics */ dev_info->max_mac_addrs = bp->max_l2_ctx; dev_info->max_hash_mac_addrs = 0; @@ -602,6 +619,10 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) bp->tx_nr_rings = eth_dev->data->nb_tx_queues; bp->rx_nr_rings = eth_dev->data->nb_rx_queues; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + if (BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM)) { rc = bnxt_hwrm_check_vf_rings(bp); if (rc) { @@ -791,8 +812,10 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) eth_dev->rx_pkt_burst = bnxt_receive_function(eth_dev); eth_dev->tx_pkt_burst = bnxt_transmit_function(eth_dev); + bnxt_enable_int(bp); bp->flags |= BNXT_FLAG_INIT_DONE; + eth_dev->data->dev_started = 1; bp->dev_stopped = 0; return 0; @@ -835,6 +858,11 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); struct rte_intr_handle *intr_handle = &pci_dev->intr_handle; + eth_dev->data->dev_started = 0; + /* Prevent crashes when queues are still in use */ + eth_dev->rx_pkt_burst = &bnxt_dummy_recv_pkts; + eth_dev->tx_pkt_burst = &bnxt_dummy_xmit_pkts; + bnxt_disable_int(bp); /* disable uio/vfio intr/eventfd mapping */ @@ -889,6 +917,9 @@ static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev, struct bnxt_filter_info *filter, *temp_filter; uint32_t i; + if (is_bnxt_in_error(bp)) + return; + /* * Loop through all VNICs from the specified filter flow pools to * remove the corresponding MAC addr filter @@ -924,6 +955,10 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev, struct bnxt_filter_info *filter; int rc = 0; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + if (BNXT_VF(bp) & !BNXT_VF_IS_TRUSTED(bp)) { PMD_DRV_LOG(ERR, "Cannot add MAC address to a VF interface\n"); return -ENOTSUP; @@ -969,6 +1004,10 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete) struct rte_eth_link new; unsigned int cnt = BNXT_LINK_WAIT_CNT; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + memset(&new, 0, sizeof(new)); do { /* Retrieve link info from hardware */ @@ -1009,6 +1048,9 @@ static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev) struct bnxt *bp = eth_dev->data->dev_private; struct bnxt_vnic_info *vnic; + if (is_bnxt_in_error(bp)) + return; + if (bp->vnic_info == NULL) return; @@ -1023,6 +1065,9 @@ static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev) struct bnxt *bp = eth_dev->data->dev_private; struct bnxt_vnic_info *vnic; + if (is_bnxt_in_error(bp)) + return; + if (bp->vnic_info == NULL) return; @@ -1037,6 +1082,9 @@ static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev) struct bnxt *bp = eth_dev->data->dev_private; struct bnxt_vnic_info *vnic; + if (is_bnxt_in_error(bp)) + return; + if (bp->vnic_info == NULL) return; @@ -1051,6 +1099,9 @@ static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev) struct bnxt *bp = eth_dev->data->dev_private; struct bnxt_vnic_info *vnic; + if (is_bnxt_in_error(bp)) + return; + if (bp->vnic_info == NULL) return; @@ -1100,7 +1151,11 @@ static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev, struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp); uint16_t idx, sft; - int i; + int i, rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; if (!vnic->rss_table) return -EINVAL; @@ -1156,6 +1211,11 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev, struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; uint16_t tbl_size = bnxt_rss_hash_tbl_size(bp); uint16_t idx, sft, i; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; /* Retrieve from the default VNIC */ if (!vnic) @@ -1202,6 +1262,11 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev, struct bnxt_vnic_info *vnic; uint16_t hash_type = 0; unsigned int i; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; /* * If RSS enablement were different than dev_configure, @@ -1255,9 +1320,13 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev, { struct bnxt *bp = eth_dev->data->dev_private; struct bnxt_vnic_info *vnic = &bp->vnic_info[0]; - int len; + int len, rc; uint32_t hash_types; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + /* RSS configuration is the same for all VNICs */ if (vnic && vnic->rss_hash_key) { if (rss_conf->rss_key) { @@ -1315,6 +1384,10 @@ static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev, struct rte_eth_link link_info; int rc; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + rc = bnxt_get_hwrm_link_config(bp, &link_info); if (rc) return rc; @@ -1344,6 +1417,11 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf) { struct bnxt *bp = dev->data->dev_private; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { PMD_DRV_LOG(ERR, "Flow Control Settings cannot be modified\n"); @@ -1403,6 +1481,10 @@ bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev, uint16_t tunnel_type = 0; int rc = 0; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + switch (udp_tunnel->prot_type) { case RTE_TUNNEL_TYPE_VXLAN: if (bp->vxlan_port_cnt) { @@ -1452,6 +1534,10 @@ bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev, uint16_t port = 0; int rc = 0; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + switch (udp_tunnel->prot_type) { case RTE_TUNNEL_TYPE_VXLAN: if (!bp->vxlan_port_cnt) { @@ -1605,6 +1691,11 @@ static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev, uint16_t vlan_id, int on) { struct bnxt *bp = eth_dev->data->dev_private; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; /* These operations apply to ALL existing MAC/VLAN filters */ if (on) @@ -1619,6 +1710,11 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask) struct bnxt *bp = dev->data->dev_private; uint64_t rx_offloads = dev->data->dev_conf.rxmode.offloads; unsigned int i; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; if (mask & ETH_VLAN_FILTER_MASK) { if (!(rx_offloads & DEV_RX_OFFLOAD_VLAN_FILTER)) { @@ -1660,6 +1756,10 @@ bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct bnxt_filter_info *filter; int rc; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + if (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)) return -EPERM; @@ -1699,6 +1799,11 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev, char *mc_addr_list = (char *)mc_addr_set; struct bnxt_vnic_info *vnic; uint32_t off = 0, i = 0; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; vnic = &bp->vnic_info[0]; @@ -1784,6 +1889,10 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu) uint32_t rc = 0; uint32_t i; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + new_pkt_size = new_mtu + RTE_ETHER_HDR_LEN + RTE_ETHER_CRC_LEN + VLAN_TAG_SIZE * BNXT_NUM_VLANS; @@ -1857,6 +1966,10 @@ bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on) uint16_t vlan = bp->vlan; int rc; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + if (!BNXT_SINGLE_PF(bp) || BNXT_VF(bp)) { PMD_DRV_LOG(ERR, "PVID cannot be modified for this function\n"); @@ -1874,6 +1987,11 @@ static int bnxt_dev_led_on_op(struct rte_eth_dev *dev) { struct bnxt *bp = dev->data->dev_private; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; return bnxt_hwrm_port_led_cfg(bp, true); } @@ -1882,6 +2000,11 @@ static int bnxt_dev_led_off_op(struct rte_eth_dev *dev) { struct bnxt *bp = dev->data->dev_private; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; return bnxt_hwrm_port_led_cfg(bp, false); } @@ -1889,6 +2012,7 @@ bnxt_dev_led_off_op(struct rte_eth_dev *dev) static uint32_t bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id) { + struct bnxt *bp = (struct bnxt *)dev->data->dev_private; uint32_t desc = 0, raw_cons = 0, cons; struct bnxt_cp_ring_info *cpr; struct bnxt_rx_queue *rxq; @@ -1896,6 +2020,11 @@ bnxt_rx_queue_count_op(struct rte_eth_dev *dev, uint16_t rx_queue_id) uint16_t cmp_type; uint8_t cmp = 1; bool valid; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; rxq = dev->data->rx_queues[rx_queue_id]; cpr = rxq->cp_ring; @@ -1940,10 +2069,15 @@ bnxt_rx_descriptor_status_op(void *rx_queue, uint16_t offset) struct bnxt_sw_rx_bd *rx_buf; struct rx_pkt_cmpl *rxcmp; uint32_t cons, cp_cons; + int rc; if (!rxq) return -EINVAL; + rc = is_bnxt_in_error(rxq->bp); + if (rc) + return rc; + cpr = rxq->cp_ring; rxr = rxq->rx_ring; @@ -1978,10 +2112,15 @@ bnxt_tx_descriptor_status_op(void *tx_queue, uint16_t offset) struct bnxt_sw_tx_bd *tx_buf; struct tx_pkt_cmpl *txcmp; uint32_t cons, cp_cons; + int rc; if (!txq) return -EINVAL; + rc = is_bnxt_in_error(txq->bp); + if (rc) + return rc; + cpr = txq->cp_ring; txr = txq->tx_ring; @@ -2811,6 +2950,10 @@ bnxt_filter_ctrl_op(struct rte_eth_dev *dev __rte_unused, { int ret = 0; + ret = is_bnxt_in_error(dev->data->dev_private); + if (ret) + return ret; + switch (filter_type) { case RTE_ETH_FILTER_TUNNEL: PMD_DRV_LOG(ERR, @@ -3126,6 +3269,10 @@ bnxt_get_eeprom_length_op(struct rte_eth_dev *dev) uint32_t dir_entries; uint32_t entry_length; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x\n", bp->pdev->addr.domain, bp->pdev->addr.bus, bp->pdev->addr.devid, bp->pdev->addr.function); @@ -3144,6 +3291,11 @@ bnxt_get_eeprom_op(struct rte_eth_dev *dev, struct bnxt *bp = dev->data->dev_private; uint32_t index; uint32_t offset; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x in_eeprom->offset = %d " "len = %d\n", bp->pdev->addr.domain, @@ -3215,6 +3367,11 @@ bnxt_set_eeprom_op(struct rte_eth_dev *dev, struct bnxt *bp = dev->data->dev_private; uint8_t index, dir_op; uint16_t type, ext, ordinal, attr; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; PMD_DRV_LOG(INFO, "%04x:%02x:%02x:%02x in_eeprom->offset = %d " "len = %d\n", bp->pdev->addr.domain, @@ -3768,19 +3925,139 @@ static int bnxt_setup_mac_addr(struct rte_eth_dev *eth_dev) return rc; } +static void bnxt_config_vf_req_fwd(struct bnxt *bp) +{ + if (!BNXT_PF(bp)) + return; + #define ALLOW_FUNC(x) \ { \ uint32_t arg = (x); \ bp->pf.vf_req_fwd[((arg) >> 5)] &= \ ~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \ } + + /* Forward all requests if firmware is new enough */ + if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) && + (bp->fw_ver < ((20 << 24) | (7 << 16)))) || + ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) { + memset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd)); + } else { + PMD_DRV_LOG(WARNING, + "Firmware too old for VF mailbox functionality\n"); + memset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd)); + } + + /* + * The following are used for driver cleanup. If we disallow these, + * VF drivers can't clean up cleanly. + */ + ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR); + ALLOW_FUNC(HWRM_VNIC_FREE); + ALLOW_FUNC(HWRM_RING_FREE); + ALLOW_FUNC(HWRM_RING_GRP_FREE); + ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE); + ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE); + ALLOW_FUNC(HWRM_STAT_CTX_FREE); + ALLOW_FUNC(HWRM_PORT_PHY_QCFG); + ALLOW_FUNC(HWRM_VNIC_TPA_CFG); +} + +static int bnxt_init_fw(struct bnxt *bp) +{ + uint16_t mtu; + int rc = 0; + + rc = bnxt_hwrm_ver_get(bp); + if (rc) + return rc; + + rc = bnxt_hwrm_func_reset(bp); + if (rc) + return -EIO; + + rc = bnxt_hwrm_queue_qportcfg(bp); + if (rc) + return rc; + + /* Get the MAX capabilities for this function */ + rc = bnxt_hwrm_func_qcaps(bp); + if (rc) + return rc; + + rc = bnxt_hwrm_func_qcfg(bp, &mtu); + if (rc) + return rc; + + if (mtu >= RTE_ETHER_MIN_MTU && mtu <= BNXT_MAX_MTU && + mtu != bp->eth_dev->data->mtu) + bp->eth_dev->data->mtu = mtu; + + bnxt_hwrm_port_led_qcaps(bp); + + return 0; +} + +static int bnxt_init_resources(struct bnxt *bp) +{ + int rc; + + rc = bnxt_init_fw(bp); + if (rc) + return rc; + + rc = bnxt_setup_mac_addr(bp->eth_dev); + if (rc) + return rc; + + bnxt_config_vf_req_fwd(bp); + + rc = bnxt_hwrm_func_driver_register(bp); + if (rc) { + PMD_DRV_LOG(ERR, "Failed to register driver"); + return -EBUSY; + } + + if (BNXT_PF(bp)) { + if (bp->pdev->max_vfs) { + rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs); + if (rc) { + PMD_DRV_LOG(ERR, "Failed to allocate VFs\n"); + return rc; + } + } else { + rc = bnxt_hwrm_allocate_pf_only(bp); + if (rc) { + PMD_DRV_LOG(ERR, + "Failed to allocate PF resources"); + return rc; + } + } + } + + rc = bnxt_alloc_mem(bp); + if (rc) + return rc; + + rc = bnxt_setup_int(bp); + if (rc) + return rc; + + bnxt_init_nic(bp); + + rc = bnxt_request_int(bp); + if (rc) + return rc; + + return 0; +} + static int bnxt_dev_init(struct rte_eth_dev *eth_dev) { struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev); static int version_printed; struct bnxt *bp; - uint16_t mtu; int rc; if (version_printed++ == 0) @@ -3822,166 +4099,50 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) rc = bnxt_init_board(eth_dev); if (rc) { PMD_DRV_LOG(ERR, - "Board initialization failed rc: %x\n", rc); - goto error; + "Failed to initialize board rc: %x\n", rc); + return rc; } rc = bnxt_alloc_hwrm_resources(bp); if (rc) { PMD_DRV_LOG(ERR, - "hwrm resource allocation failure rc: %x\n", rc); + "Failed to allocate hwrm resource rc: %x\n", rc); goto error_free; } - rc = bnxt_hwrm_ver_get(bp); + rc = bnxt_init_resources(bp); if (rc) goto error_free; - rc = bnxt_hwrm_func_reset(bp); - if (rc) { - PMD_DRV_LOG(ERR, "hwrm chip reset failure rc: %x\n", rc); - rc = -EIO; - goto error_free; - } - - rc = bnxt_hwrm_queue_qportcfg(bp); - if (rc) { - PMD_DRV_LOG(ERR, "hwrm queue qportcfg failed\n"); - goto error_free; - } - /* Get the MAX capabilities for this function */ - rc = bnxt_hwrm_func_qcaps(bp); - if (rc) { - PMD_DRV_LOG(ERR, "hwrm query capability failure rc: %x\n", rc); - goto error_free; - } - rc = bnxt_alloc_stats_mem(bp); if (rc) goto error_free; - if (bp->max_tx_rings == 0) { - PMD_DRV_LOG(ERR, "No TX rings available!\n"); - rc = -EBUSY; - goto error_free; - } - - rc = bnxt_setup_mac_addr(eth_dev); - if (rc) - goto error_free; - - /* THOR does not support ring groups. - * But we will use the array to save RSS context IDs. - */ - if (BNXT_CHIP_THOR(bp)) { - bp->max_ring_grps = BNXT_MAX_RSS_CTXTS_THOR; - } else if (bp->max_ring_grps < bp->rx_cp_nr_rings) { - /* 1 ring is for default completion ring */ - PMD_DRV_LOG(ERR, "Insufficient resource: Ring Group\n"); - rc = -ENOSPC; - goto error_free; - } - - if (BNXT_HAS_RING_GRPS(bp)) { - bp->grp_info = rte_zmalloc("bnxt_grp_info", - sizeof(*bp->grp_info) * - bp->max_ring_grps, 0); - if (!bp->grp_info) { - PMD_DRV_LOG(ERR, - "Failed to alloc %zu bytes for grp info tbl.\n", - sizeof(*bp->grp_info) * bp->max_ring_grps); - rc = -ENOMEM; - goto error_free; - } - } - - /* Forward all requests if firmware is new enough */ - if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) && - (bp->fw_ver < ((20 << 24) | (7 << 16)))) || - ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) { - memset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd)); - } else { - PMD_DRV_LOG(WARNING, - "Firmware too old for VF mailbox functionality\n"); - memset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd)); - } - - /* - * The following are used for driver cleanup. If we disallow these, - * VF drivers can't clean up cleanly. - */ - ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR); - ALLOW_FUNC(HWRM_VNIC_FREE); - ALLOW_FUNC(HWRM_RING_FREE); - ALLOW_FUNC(HWRM_RING_GRP_FREE); - ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE); - ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE); - ALLOW_FUNC(HWRM_STAT_CTX_FREE); - ALLOW_FUNC(HWRM_PORT_PHY_QCFG); - ALLOW_FUNC(HWRM_VNIC_TPA_CFG); - rc = bnxt_hwrm_func_driver_register(bp); - if (rc) { - PMD_DRV_LOG(ERR, - "Failed to register driver"); - rc = -EBUSY; - goto error_free; - } - PMD_DRV_LOG(INFO, - DRV_MODULE_NAME " found at mem %" PRIx64 ", node addr %pM\n", - pci_dev->mem_resource[0].phys_addr, - pci_dev->mem_resource[0].addr); - - rc = bnxt_hwrm_func_qcfg(bp, &mtu); - if (rc) { - PMD_DRV_LOG(ERR, "hwrm func qcfg failed\n"); - goto error_free; - } - - if (mtu >= RTE_ETHER_MIN_MTU && mtu <= BNXT_MAX_MTU && - mtu != eth_dev->data->mtu) - eth_dev->data->mtu = mtu; - - if (BNXT_PF(bp)) { - //if (bp->pf.active_vfs) { - // TODO: Deallocate VF resources? - //} - if (bp->pdev->max_vfs) { - rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs); - if (rc) { - PMD_DRV_LOG(ERR, "Failed to allocate VFs\n"); - goto error_free; - } - } else { - rc = bnxt_hwrm_allocate_pf_only(bp); - if (rc) { - PMD_DRV_LOG(ERR, - "Failed to allocate PF resources\n"); - goto error_free; - } - } - } - - bnxt_hwrm_port_led_qcaps(bp); - - rc = bnxt_setup_int(bp); - if (rc) - goto error_free; - - rc = bnxt_alloc_mem(bp); - if (rc) - goto error_free; - - bnxt_init_nic(bp); - - rc = bnxt_request_int(bp); - if (rc) - goto error_free; + DRV_MODULE_NAME "found at mem %" PRIX64 ", node addr %pM\n", + pci_dev->mem_resource[0].phys_addr, + pci_dev->mem_resource[0].addr); return 0; error_free: bnxt_dev_uninit(eth_dev); -error: + return rc; +} + +static int +bnxt_uninit_resources(struct bnxt *bp) +{ + int rc; + + bnxt_disable_int(bp); + bnxt_free_int(bp); + bnxt_free_mem(bp); + bnxt_hwrm_func_buf_unrgtr(bp); + rc = bnxt_hwrm_func_driver_unregister(bp, 0); + bp->flags &= ~BNXT_FLAG_REGISTERED; + bnxt_free_ctx_mem(bp); + bnxt_free_hwrm_resources(bp); + return rc; } @@ -3995,18 +4156,13 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) return -EPERM; PMD_DRV_LOG(DEBUG, "Calling Device uninit\n"); - bnxt_disable_int(bp); - bnxt_free_int(bp); - bnxt_free_mem(bp); - bnxt_hwrm_func_buf_unrgtr(bp); + rc = bnxt_uninit_resources(bp); if (bp->grp_info != NULL) { rte_free(bp->grp_info); bp->grp_info = NULL; } - rc = bnxt_hwrm_func_driver_unregister(bp, 0); - bnxt_free_hwrm_resources(bp); if (bp->tx_mem_zone) { rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone); @@ -4022,7 +4178,6 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) bnxt_dev_close_op(eth_dev); if (bp->pf.vf_info) rte_free(bp->pf.vf_info); - bnxt_free_ctx_mem(bp); eth_dev->dev_ops = NULL; eth_dev->rx_pkt_burst = NULL; eth_dev->tx_pkt_burst = NULL; diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index 9883fb506..24a5a0914 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -964,8 +964,6 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags) HWRM_CHECK_RESULT(); HWRM_UNLOCK(); - bp->flags &= ~BNXT_FLAG_REGISTERED; - return rc; } diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c index be15b4bd1..f19865c83 100644 --- a/drivers/net/bnxt/bnxt_ring.c +++ b/drivers/net/bnxt/bnxt_ring.c @@ -50,6 +50,38 @@ int bnxt_init_ring_grps(struct bnxt *bp) return 0; } +int bnxt_alloc_ring_grps(struct bnxt *bp) +{ + if (bp->max_tx_rings == 0) { + PMD_DRV_LOG(ERR, "No TX rings available!\n"); + return -EBUSY; + } + + /* THOR does not support ring groups. + * But we will use the array to save RSS context IDs. + */ + if (BNXT_CHIP_THOR(bp)) { + bp->max_ring_grps = BNXT_MAX_RSS_CTXTS_THOR; + } else if (bp->max_ring_grps < bp->rx_cp_nr_rings) { + /* 1 ring is for default completion ring */ + PMD_DRV_LOG(ERR, "Insufficient resource: Ring Group\n"); + return -ENOSPC; + } + + if (BNXT_HAS_RING_GRPS(bp)) { + bp->grp_info = rte_zmalloc("bnxt_grp_info", + sizeof(*bp->grp_info) * + bp->max_ring_grps, 0); + if (!bp->grp_info) { + PMD_DRV_LOG(ERR, + "Failed to alloc grp info tbl.\n"); + return -ENOMEM; + } + } + + return 0; +} + /* * Allocates a completion ring with vmem and stats optionally also allocating * a TX and/or RX ring. Passing NULL as tx_ring_info and/or rx_ring_info diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h index 04c7b04b8..a31d59ea3 100644 --- a/drivers/net/bnxt/bnxt_ring.h +++ b/drivers/net/bnxt/bnxt_ring.h @@ -67,6 +67,7 @@ struct bnxt_rx_ring_info; struct bnxt_cp_ring_info; void bnxt_free_ring(struct bnxt_ring *ring); int bnxt_init_ring_grps(struct bnxt *bp); +int bnxt_alloc_ring_grps(struct bnxt *bp); int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, struct bnxt_tx_queue *txq, struct bnxt_rx_queue *rxq, diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c index 1d95f1139..d5fc5268d 100644 --- a/drivers/net/bnxt/bnxt_rxq.c +++ b/drivers/net/bnxt/bnxt_rxq.c @@ -263,6 +263,9 @@ void bnxt_rx_queue_release_op(void *rx_queue) struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue; if (rxq) { + if (is_bnxt_in_error(rxq->bp)) + return; + bnxt_rx_queue_release_mbufs(rxq); /* Free RX ring hardware descriptors */ @@ -294,6 +297,10 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, int rc = 0; uint8_t queue_state; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + if (queue_idx >= bp->max_rx_rings) { PMD_DRV_LOG(ERR, "Cannot create Rx ring %d. Only %d rings available\n", @@ -363,10 +370,15 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev, int bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id) { + struct bnxt *bp = eth_dev->data->dev_private; struct bnxt_rx_queue *rxq; struct bnxt_cp_ring_info *cpr; int rc = 0; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + if (eth_dev->data->rx_queues) { rxq = eth_dev->data->rx_queues[queue_id]; if (!rxq) { @@ -382,10 +394,15 @@ bnxt_rx_queue_intr_enable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id) int bnxt_rx_queue_intr_disable_op(struct rte_eth_dev *eth_dev, uint16_t queue_id) { + struct bnxt *bp = eth_dev->data->dev_private; struct bnxt_rx_queue *rxq; struct bnxt_cp_ring_info *cpr; int rc = 0; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + if (eth_dev->data->rx_queues) { rxq = eth_dev->data->rx_queues[queue_id]; if (!rxq) { @@ -406,6 +423,10 @@ int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id) struct bnxt_vnic_info *vnic = NULL; int rc = 0; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + if (rxq == NULL) { PMD_DRV_LOG(ERR, "Invalid Rx queue %d\n", rx_queue_id); return -EINVAL; @@ -458,6 +479,10 @@ int bnxt_rx_queue_stop(struct rte_eth_dev *dev, uint16_t rx_queue_id) struct bnxt_rx_queue *rxq = NULL; int rc = 0; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + /* For the stingray platform and other platforms needing tighter * control of resource utilization, Rx CQ 0 also works as * Default CQ for async notifications diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c index 185a0e376..12313dd53 100644 --- a/drivers/net/bnxt/bnxt_rxr.c +++ b/drivers/net/bnxt/bnxt_rxr.c @@ -539,6 +539,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, int rc = 0; bool evt = false; + if (unlikely(is_bnxt_in_error(rxq->bp))) + return 0; + /* If Rx Q was stopped return. RxQ0 cannot be stopped. */ if (unlikely(((rxq->rx_deferred_start || !rte_spinlock_trylock(&rxq->lock)) && @@ -625,6 +628,20 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, return nb_rx_pkts; } +/* + * Dummy DPDK callback for RX. + * + * This function is used to temporarily replace the real callback during + * unsafe control operations on the queue, or in case of error. + */ +uint16_t +bnxt_dummy_recv_pkts(void *rx_queue __rte_unused, + struct rte_mbuf **rx_pkts __rte_unused, + uint16_t nb_pkts __rte_unused) +{ + return 0; +} + void bnxt_free_rx_rings(struct bnxt *bp) { int i; diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h index 6a80c37c8..493b75406 100644 --- a/drivers/net/bnxt/bnxt_rxr.h +++ b/drivers/net/bnxt/bnxt_rxr.h @@ -185,6 +185,8 @@ struct bnxt_rx_ring_info { uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts); +uint16_t bnxt_dummy_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, + uint16_t nb_pkts); void bnxt_free_rx_rings(struct bnxt *bp); int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id); int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq); diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c index 69ac2dd91..79f23746c 100644 --- a/drivers/net/bnxt/bnxt_stats.c +++ b/drivers/net/bnxt/bnxt_stats.c @@ -353,6 +353,10 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev, struct bnxt *bp = eth_dev->data->dev_private; unsigned int num_q_stats; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + memset(bnxt_stats, 0, sizeof(*bnxt_stats)); if (!(bp->flags & BNXT_FLAG_INIT_DONE)) { PMD_DRV_LOG(ERR, "Device Initialization not complete!\n"); @@ -397,6 +401,9 @@ void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev) struct bnxt *bp = eth_dev->data->dev_private; unsigned int i; + if (is_bnxt_in_error(bp)) + return; + if (!(bp->flags & BNXT_FLAG_INIT_DONE)) { PMD_DRV_LOG(ERR, "Device Initialization not complete!\n"); return; @@ -414,13 +421,17 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev, struct rte_eth_xstat *xstats, unsigned int n) { struct bnxt *bp = eth_dev->data->dev_private; - unsigned int count, i; uint64_t tx_drop_pkts; unsigned int rx_port_stats_ext_cnt; unsigned int tx_port_stats_ext_cnt; unsigned int stat_size = sizeof(uint64_t); unsigned int stat_count; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; memset(xstats, 0, sizeof(*xstats)); @@ -499,7 +510,13 @@ int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev, RTE_DIM(bnxt_tx_stats_strings) + 1 + RTE_DIM(bnxt_rx_ext_stats_strings) + RTE_DIM(bnxt_tx_ext_stats_strings); + struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; unsigned int i, count; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; if (xstats_names != NULL) { count = 0; @@ -547,6 +564,9 @@ void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev) { struct bnxt *bp = eth_dev->data->dev_private; + if (is_bnxt_in_error(bp)) + return; + if (bp->flags & BNXT_FLAG_PORT_STATS && BNXT_SINGLE_PF(bp)) bnxt_hwrm_port_clr_stats(bp); @@ -566,9 +586,15 @@ int bnxt_dev_xstats_get_by_id_op(struct rte_eth_dev *dev, const uint64_t *ids, RTE_DIM(bnxt_tx_stats_strings) + 1 + RTE_DIM(bnxt_rx_ext_stats_strings) + RTE_DIM(bnxt_tx_ext_stats_strings); + struct bnxt *bp = dev->data->dev_private; struct rte_eth_xstat xstats[stat_cnt]; uint64_t values_copy[stat_cnt]; uint16_t i; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; if (!ids) return bnxt_dev_xstats_get_op(dev, xstats, stat_cnt); @@ -594,7 +620,13 @@ int bnxt_dev_xstats_get_names_by_id_op(struct rte_eth_dev *dev, RTE_DIM(bnxt_rx_ext_stats_strings) + RTE_DIM(bnxt_tx_ext_stats_strings); struct rte_eth_xstat_name xstats_names_copy[stat_cnt]; + struct bnxt *bp = dev->data->dev_private; uint16_t i; + int rc; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; if (!ids) return bnxt_dev_xstats_get_names_op(dev, xstats_names, diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c index 43b3496c1..090132479 100644 --- a/drivers/net/bnxt/bnxt_txq.c +++ b/drivers/net/bnxt/bnxt_txq.c @@ -58,6 +58,9 @@ void bnxt_tx_queue_release_op(void *tx_queue) struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue; if (txq) { + if (is_bnxt_in_error(txq->bp)) + return; + /* Free TX ring hardware descriptors */ bnxt_tx_queue_release_mbufs(txq); bnxt_free_ring(txq->tx_ring->tx_ring_struct); @@ -84,6 +87,10 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev, struct bnxt_tx_queue *txq; int rc = 0; + rc = is_bnxt_in_error(bp); + if (rc) + return rc; + if (queue_idx >= bp->max_tx_rings) { PMD_DRV_LOG(ERR, "Cannot create Tx ring %d. Only %d rings available\n", diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c index c71e6f189..35e7166be 100644 --- a/drivers/net/bnxt/bnxt_txr.c +++ b/drivers/net/bnxt/bnxt_txr.c @@ -148,6 +148,9 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt, TX_BD_LONG_FLAGS_LHINT_LT2K }; + if (unlikely(is_bnxt_in_error(txq->bp))) + return -EIO; + if (tx_pkt->ol_flags & (PKT_TX_TCP_SEG | PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM | PKT_TX_VLAN_PKT | PKT_TX_OUTER_IP_CKSUM | @@ -485,10 +488,29 @@ uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, return nb_tx_pkts; } +/* + * Dummy DPDK callback for TX. + * + * This function is used to temporarily replace the real callback during + * unsafe control operations on the queue, or in case of error. + */ +uint16_t +bnxt_dummy_xmit_pkts(void *tx_queue __rte_unused, + struct rte_mbuf **tx_pkts __rte_unused, + uint16_t nb_pkts __rte_unused) +{ + return 0; +} + int bnxt_tx_queue_start(struct rte_eth_dev *dev, uint16_t tx_queue_id) { struct bnxt *bp = dev->data->dev_private; struct bnxt_tx_queue *txq = bp->tx_queues[tx_queue_id]; + int rc = 0; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; dev->data->tx_queue_state[tx_queue_id] = RTE_ETH_QUEUE_STATE_STARTED; txq->tx_deferred_start = false; @@ -501,6 +523,11 @@ int bnxt_tx_queue_stop(struct rte_eth_dev *dev, uint16_t tx_queue_id) { struct bnxt *bp = dev->data->dev_private; struct bnxt_tx_queue *txq = bp->tx_queues[tx_queue_id]; + int rc = 0; + + rc = is_bnxt_in_error(bp); + if (rc) + return rc; /* Handle TX completions */ bnxt_handle_tx_cp(txq); diff --git a/drivers/net/bnxt/bnxt_txr.h b/drivers/net/bnxt/bnxt_txr.h index 08fd2e014..e7f43f9d1 100644 --- a/drivers/net/bnxt/bnxt_txr.h +++ b/drivers/net/bnxt/bnxt_txr.h @@ -57,6 +57,8 @@ int bnxt_init_one_tx_ring(struct bnxt_tx_queue *txq); int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id); uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); +uint16_t bnxt_dummy_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts, + uint16_t nb_pkts); #ifdef RTE_ARCH_X86 uint16_t bnxt_xmit_pkts_vec(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts); From patchwork Fri Aug 30 16:35:27 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58309 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 88EAD1E9AA; Fri, 30 Aug 2019 18:35:58 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 4CF6E1E99A for ; Fri, 30 Aug 2019 18:35:47 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 9C8CC30C056; Fri, 30 Aug 2019 09:35:40 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 9C8CC30C056 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182940; bh=iLKePE7FgaGuqPyeJ/4RpfWLJusCLkmNshiFHC2b8tg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TPEqtbZtJIZQA8B9fbGUcPCr+fNFQ8dIRjNCIZu/fFPHefGK8u2MWImpnmFgBfo+r czRXAIGtZUeo3+YOMzlOEGo6aBmP2Idl1rW+g6Xqnv58y7Qfk3fw8aswyBaqtzI13h RMkktnhkXO1mbhMJQ9rbMYiQ7j76LRwJNSikpbYE= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id CD22FAC06AB; Fri, 30 Aug 2019 09:35:41 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:27 -0700 Message-Id: <20190830163537.32704-4-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 03/13] net/bnxt: handle reset notify async event from FW X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP When the FW upgrade is initiated the current instance of FW issues a HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY async notification to the driver. On receiving this notification, the PMD shall quiesce itself and poll on the HWRM_VER_GET FW command at regular intervals. Once the VER_GET command succeeds, the driver should go through the rediscovery process and re-initialize the device. Also register with FW for the reset notify async event. Signed-off-by: Kalesh AP Reviewed-by: Ajit Khaparde Reviewed-by: Somnath Kotur --- drivers/net/bnxt/bnxt.h | 13 ++++ drivers/net/bnxt/bnxt_cpr.c | 16 +++++ drivers/net/bnxt/bnxt_cpr.h | 1 + drivers/net/bnxt/bnxt_ethdev.c | 109 ++++++++++++++++++++++++++++----- drivers/net/bnxt/bnxt_hwrm.c | 39 +++++++++--- drivers/net/bnxt/bnxt_hwrm.h | 2 + 6 files changed, 157 insertions(+), 23 deletions(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 37b4c717d..8797b032e 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -333,6 +333,16 @@ struct bnxt_ctx_mem_info { struct bnxt_ctx_pg_info *tqm_mem[BNXT_MAX_TC_Q]; }; +/* Maximum Firmware Reset bail out value in milliseconds */ +#define BNXT_MAX_FW_RESET_TIMEOUT 6000 +/* Minimum time required for the firmware readiness in milliseconds */ +#define BNXT_MIN_FW_READY_TIMEOUT 2000 +/* Frequency for the firmware readiness check in milliseconds */ +#define BNXT_FW_READY_WAIT_INTERVAL 100 + +#define US_PER_MS 1000 +#define NS_PER_US 1000 + #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) struct bnxt { void *bar0; @@ -463,6 +473,9 @@ struct bnxt { struct bnxt_ptp_cfg *ptp_cfg; uint16_t vf_resv_strategy; struct bnxt_ctx_mem_info *ctx; + + uint16_t fw_reset_min_msecs; + uint16_t fw_reset_max_msecs; }; int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete); diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c index 655bcf1a8..62a16d2ed 100644 --- a/drivers/net/bnxt/bnxt_cpr.c +++ b/drivers/net/bnxt/bnxt_cpr.c @@ -4,6 +4,7 @@ */ #include +#include #include "bnxt.h" #include "bnxt_cpr.h" @@ -40,6 +41,21 @@ void bnxt_handle_async_event(struct bnxt *bp, case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED: PMD_DRV_LOG(INFO, "Port conn async event\n"); break; + case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY: + /* timestamp_lo/hi values are in units of 100ms */ + bp->fw_reset_max_msecs = async_cmp->timestamp_hi ? + rte_le_to_cpu_16(async_cmp->timestamp_hi) * 100 : + BNXT_MAX_FW_RESET_TIMEOUT; + bp->fw_reset_min_msecs = async_cmp->timestamp_lo ? + async_cmp->timestamp_lo * 100 : + BNXT_MIN_FW_READY_TIMEOUT; + PMD_DRV_LOG(INFO, + "Firmware non-fatal reset event received\n"); + + bp->flags |= BNXT_FLAG_FW_RESET; + rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume, + (void *)bp); + break; default: PMD_DRV_LOG(INFO, "handle_async_event id = 0x%x\n", event_id); break; diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h index 8c6a34b61..f48293b96 100644 --- a/drivers/net/bnxt/bnxt_cpr.h +++ b/drivers/net/bnxt/bnxt_cpr.h @@ -106,5 +106,6 @@ struct bnxt; void bnxt_handle_async_event(struct bnxt *bp, struct cmpl_base *cmp); void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmp); int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp); +void bnxt_dev_reset_and_resume(void *arg); #endif diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 33ff4a5a7..e545802ce 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "bnxt.h" #include "bnxt_cpr.h" @@ -166,6 +167,8 @@ static int bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask); static void bnxt_print_link_info(struct rte_eth_dev *eth_dev); static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu); static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev); +static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev); +static int bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev); int is_bnxt_in_error(struct bnxt *bp) { @@ -201,19 +204,25 @@ static uint16_t bnxt_rss_hash_tbl_size(const struct bnxt *bp) return bnxt_rss_ctxts(bp) * BNXT_RSS_ENTRIES_PER_CTX_THOR; } -static void bnxt_free_mem(struct bnxt *bp) +static void bnxt_free_mem(struct bnxt *bp, bool reconfig) { bnxt_free_filter_mem(bp); bnxt_free_vnic_attributes(bp); bnxt_free_vnic_mem(bp); - bnxt_free_stats(bp); - bnxt_free_tx_rings(bp); - bnxt_free_rx_rings(bp); + /* tx/rx rings are configured as part of *_queue_setup callbacks. + * If the number of rings change across fw update, + * we don't have much choice except to warn the user. + */ + if (!reconfig) { + bnxt_free_stats(bp); + bnxt_free_tx_rings(bp); + bnxt_free_rx_rings(bp); + } bnxt_free_async_cp_ring(bp); } -static int bnxt_alloc_mem(struct bnxt *bp) +static int bnxt_alloc_mem(struct bnxt *bp, bool reconfig) { int rc; @@ -244,7 +253,7 @@ static int bnxt_alloc_mem(struct bnxt *bp) return 0; alloc_mem_err: - bnxt_free_mem(bp); + bnxt_free_mem(bp, reconfig); return rc; } @@ -3483,6 +3492,71 @@ static const struct eth_dev_ops bnxt_dev_ops = { .timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp, }; +static void bnxt_dev_cleanup(struct bnxt *bp) +{ + bnxt_set_hwrm_link_config(bp, false); + bp->link_info.link_up = 0; + if (bp->dev_stopped == 0) + bnxt_dev_stop_op(bp->eth_dev); + + bnxt_uninit_resources(bp, true); +} + +static void bnxt_dev_recover(void *arg) +{ + struct bnxt *bp = arg; + int timeout = bp->fw_reset_max_msecs; + int rc = 0; + + do { + rc = bnxt_hwrm_ver_get(bp); + if (rc == 0) + break; + rte_delay_ms(BNXT_FW_READY_WAIT_INTERVAL); + timeout -= BNXT_FW_READY_WAIT_INTERVAL; + } while (rc && timeout); + + if (rc) { + PMD_DRV_LOG(ERR, "FW is not Ready after reset\n"); + goto err; + } + + rc = bnxt_init_resources(bp, true); + if (rc) { + PMD_DRV_LOG(ERR, + "Failed to initialize resources after reset\n"); + goto err; + } + /* clear reset flag as the device is initialized now */ + bp->flags &= ~BNXT_FLAG_FW_RESET; + + rc = bnxt_dev_start_op(bp->eth_dev); + if (rc) { + PMD_DRV_LOG(ERR, "Failed to start port after reset\n"); + goto err; + } + + PMD_DRV_LOG(INFO, "Recovered from FW reset\n"); + return; +err: + bp->flags |= BNXT_FLAG_FATAL_ERROR; + bnxt_uninit_resources(bp, false); + PMD_DRV_LOG(ERR, "Failed to recover from FW reset\n"); +} + +void bnxt_dev_reset_and_resume(void *arg) +{ + struct bnxt *bp = arg; + int rc; + + bnxt_dev_cleanup(bp); + + rc = rte_eal_alarm_set(US_PER_MS * bp->fw_reset_min_msecs, + bnxt_dev_recover, (void *)bp); + if (rc) + PMD_DRV_LOG(ERR, "Error setting recovery alarm"); +} + static bool bnxt_vf_pciid(uint16_t id) { if (id == BROADCOM_DEV_ID_57304_VF || @@ -3998,7 +4072,7 @@ static int bnxt_init_fw(struct bnxt *bp) return 0; } -static int bnxt_init_resources(struct bnxt *bp) +static int bnxt_init_resources(struct bnxt *bp, bool reconfig_dev) { int rc; @@ -4006,9 +4080,11 @@ static int bnxt_init_resources(struct bnxt *bp) if (rc) return rc; - rc = bnxt_setup_mac_addr(bp->eth_dev); - if (rc) - return rc; + if (!reconfig_dev) { + rc = bnxt_setup_mac_addr(bp->eth_dev); + if (rc) + return rc; + } bnxt_config_vf_req_fwd(bp); @@ -4035,7 +4111,7 @@ static int bnxt_init_resources(struct bnxt *bp) } } - rc = bnxt_alloc_mem(bp); + rc = bnxt_alloc_mem(bp, reconfig_dev); if (rc) return rc; @@ -4109,7 +4185,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) "Failed to allocate hwrm resource rc: %x\n", rc); goto error_free; } - rc = bnxt_init_resources(bp); + rc = bnxt_init_resources(bp, false); if (rc) goto error_free; @@ -4130,18 +4206,19 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) } static int -bnxt_uninit_resources(struct bnxt *bp) +bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) { int rc; bnxt_disable_int(bp); bnxt_free_int(bp); - bnxt_free_mem(bp); + bnxt_free_mem(bp, reconfig_dev); bnxt_hwrm_func_buf_unrgtr(bp); rc = bnxt_hwrm_func_driver_unregister(bp, 0); bp->flags &= ~BNXT_FLAG_REGISTERED; bnxt_free_ctx_mem(bp); - bnxt_free_hwrm_resources(bp); + if (!reconfig_dev) + bnxt_free_hwrm_resources(bp); return rc; } @@ -4157,7 +4234,7 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) PMD_DRV_LOG(DEBUG, "Calling Device uninit\n"); - rc = bnxt_uninit_resources(bp); + rc = bnxt_uninit_resources(bp, false); if (bp->grp_info != NULL) { rte_free(bp->grp_info); diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index 24a5a0914..b27dbe87e 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -26,7 +26,7 @@ #include -#define HWRM_CMD_TIMEOUT 6000000 +#define HWRM_SHORT_CMD_TIMEOUT 50000 #define HWRM_SPEC_CODE_1_8_3 0x10803 #define HWRM_VERSION_1_9_1 0x10901 #define HWRM_VERSION_1_9_2 0x10903 @@ -97,6 +97,14 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, GRCPF_REG_KONG_CHANNEL_OFFSET : GRCPF_REG_CHIMP_CHANNEL_OFFSET; uint16_t mb_trigger_offset = use_kong_mb ? GRCPF_REG_KONG_COMM_TRIGGER : GRCPF_REG_CHIMP_COMM_TRIGGER; + uint32_t timeout; + + /* Do not send HWRM commands to firmware in error state */ + if (bp->flags & BNXT_FLAG_FATAL_ERROR) + return 0; + + /* For VER_GET command, set timeout as 50ms */ + timeout = HWRM_SHORT_CMD_TIMEOUT; if (bp->flags & BNXT_FLAG_SHORT_CMD || msg_len > bp->max_req_len) { @@ -139,7 +147,7 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, rte_write32(1, bar); /* Poll for the valid bit */ - for (i = 0; i < HWRM_CMD_TIMEOUT; i++) { + for (i = 0; i < timeout; i++) { /* Sanity check on the resp->resp_len */ rte_rmb(); if (resp->resp_len && resp->resp_len <= bp->max_resp_len) { @@ -151,7 +159,12 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, rte_delay_us(1); } - if (i >= HWRM_CMD_TIMEOUT) { + if (i >= timeout) { + /* Suppress VER_GET timeout messages during reset recovery */ + if (bp->flags & BNXT_FLAG_FW_RESET && + rte_cpu_to_le_16(req->req_type) == HWRM_VER_GET) + return -ETIMEDOUT; + PMD_DRV_LOG(ERR, "Error(timeout) sending msg 0x%04x\n", req->req_type); return -ETIMEDOUT; @@ -657,12 +670,15 @@ int bnxt_hwrm_func_reset(struct bnxt *bp) int bnxt_hwrm_func_driver_register(struct bnxt *bp) { int rc; + uint32_t flags = 0; struct hwrm_func_drv_rgtr_input req = {.req_type = 0 }; struct hwrm_func_drv_rgtr_output *resp = bp->hwrm_cmd_resp_addr; if (bp->flags & BNXT_FLAG_REGISTERED) return 0; + flags = HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_HOT_RESET_SUPPORT; + HWRM_PREP(req, FUNC_DRV_RGTR, BNXT_USE_CHIMP_MB); req.enables = rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER | HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD); @@ -683,14 +699,16 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) * this HWRM sniffer list in FW because DPDK PF driver does * not support this. */ - req.flags = - rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_NONE_MODE); + flags |= HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_NONE_MODE; } + req.flags = rte_cpu_to_le_32(flags); + req.async_event_fwd[0] |= rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_LINK_STATUS_CHANGE | ASYNC_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED | - ASYNC_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE); + ASYNC_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE | + ASYNC_CMPL_EVENT_ID_RESET_NOTIFY); req.async_event_fwd[1] |= rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_PF_DRVR_UNLOAD | ASYNC_CMPL_EVENT_ID_VF_CFG_CHANGE); @@ -837,7 +855,10 @@ int bnxt_hwrm_ver_get(struct bnxt *bp) rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); - HWRM_CHECK_RESULT(); + if (bp->flags & BNXT_FLAG_FW_RESET) + HWRM_CHECK_RESULT_SILENT(); + else + HWRM_CHECK_RESULT(); PMD_DRV_LOG(INFO, "%d.%d.%d:%d.%d.%d\n", resp->hwrm_intf_maj_8b, resp->hwrm_intf_min_8b, @@ -2685,6 +2706,10 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp, uint16_t *mtu) if (BNXT_VF(bp) && (flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_TRUSTED_VF)) { bp->flags |= BNXT_FLAG_TRUSTED_VF_EN; PMD_DRV_LOG(INFO, "Trusted VF cap enabled\n"); + } else if (BNXT_VF(bp) && + !(flags & HWRM_FUNC_QCFG_OUTPUT_FLAGS_TRUSTED_VF)) { + bp->flags &= ~BNXT_FLAG_TRUSTED_VF_EN; + PMD_DRV_LOG(INFO, "Trusted VF cap disabled\n"); } if (mtu) diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index c882fc2a1..a03620532 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -21,6 +21,8 @@ struct bnxt_cp_ring_info; (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED) #define ASYNC_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE \ (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE) +#define ASYNC_CMPL_EVENT_ID_RESET_NOTIFY \ + (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY) #define ASYNC_CMPL_EVENT_ID_PF_DRVR_UNLOAD \ (1 << (HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD - 32)) #define ASYNC_CMPL_EVENT_ID_VF_CFG_CHANGE \ From patchwork Fri Aug 30 16:35:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58308 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E35841E9A5; Fri, 30 Aug 2019 18:35:54 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 4A82A1E999 for ; Fri, 30 Aug 2019 18:35:47 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 80BAC30C055; Fri, 30 Aug 2019 09:35:40 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 80BAC30C055 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182940; bh=u7wLrlcvOymMJvVI5idoxXPijE+bis7pSSVb1JmLGJQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=L0pS68HYhTwJzQnM6GbOYzAm2hD2mk4jVlPEo9rVLfbKhxGgNJwaLcBLmFI+zFErB e+Z0V/IDXEQ7yYuu5e4sl90UqRzpM4FfZgAM/y5wKTrcc4xmM2yr3hoo3I7X4wdjwQ qaB1uML/VfUJV6TY2/v9x8bit/Rv+JHR+hwBBGYs= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id 1175CAC06AD; Fri, 30 Aug 2019 09:35:42 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Santoshkumar Karanappa Rastapur , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:28 -0700 Message-Id: <20190830163537.32704-5-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 04/13] net/bnxt: inform firmware about IF state changes X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP Use latest firmware API to inform firmware about IF state changes. Firmware has the option to clean up resources during IF down and to require the driver to reserve resources again during IF up. Signed-off-by: Kalesh AP Reviewed-by: Santoshkumar Karanappa Rastapur Reviewed-by: Somnath Kotur Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/bnxt.h | 1 + drivers/net/bnxt/bnxt_ethdev.c | 4 ++++ drivers/net/bnxt/bnxt_hwrm.c | 35 ++++++++++++++++++++++++++++++++++ drivers/net/bnxt/bnxt_hwrm.h | 1 + 4 files changed, 41 insertions(+) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 8797b032e..394a2a941 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -370,6 +370,7 @@ struct bnxt { #define BNXT_FLAG_STINGRAY (1 << 14) #define BNXT_FLAG_FW_RESET (1 << 15) #define BNXT_FLAG_FATAL_ERROR (1 << 16) +#define BNXT_FLAG_FW_CAP_IF_CHANGE (1 << 17) #define BNXT_FLAG_EXT_STATS_SUPPORTED (1 << 29) #define BNXT_FLAG_NEW_RM (1 << 30) #define BNXT_FLAG_INIT_DONE (1U << 31) diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index e545802ce..385492db5 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -803,6 +803,8 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) bp->rx_cp_nr_rings, RTE_ETHDEV_QUEUE_STAT_CNTRS); } + bnxt_hwrm_if_change(bp, 1); + rc = bnxt_init_chip(bp); if (rc) goto error; @@ -829,6 +831,7 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev) return 0; error: + bnxt_hwrm_if_change(bp, 0); bnxt_shutdown_nic(bp); bnxt_free_tx_mbufs(bp); bnxt_free_rx_mbufs(bp); @@ -895,6 +898,7 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev) bnxt_free_tx_mbufs(bp); bnxt_free_rx_mbufs(bp); bnxt_shutdown_nic(bp); + bnxt_hwrm_if_change(bp, 0); bp->dev_stopped = 1; } diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index b27dbe87e..17c7b5e9e 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -716,6 +716,11 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); HWRM_CHECK_RESULT(); + + flags = rte_le_to_cpu_32(resp->flags); + if (flags & HWRM_FUNC_DRV_RGTR_OUTPUT_FLAGS_IF_CHANGE_SUPPORTED) + bp->flags |= BNXT_FLAG_FW_CAP_IF_CHANGE; + HWRM_UNLOCK(); bp->flags |= BNXT_FLAG_REGISTERED; @@ -4649,3 +4654,33 @@ int bnxt_hwrm_set_mac(struct bnxt *bp) return rc; } + +int bnxt_hwrm_if_change(struct bnxt *bp, bool state) +{ + struct hwrm_func_drv_if_change_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_func_drv_if_change_input req = {0}; + int rc; + + if (!(bp->flags & BNXT_FLAG_FW_CAP_IF_CHANGE)) + return 0; + + /* Do not issue FUNC_DRV_IF_CHANGE during reset recovery. + * If we issue FUNC_DRV_IF_CHANGE with flags down before + * FUNC_DRV_UNRGTR, FW resets before FUNC_DRV_UNRGTR + */ + if (!state && (bp->flags & BNXT_FLAG_FW_RESET)) + return 0; + + HWRM_PREP(req, FUNC_DRV_IF_CHANGE, BNXT_USE_CHIMP_MB); + + if (state) + req.flags = + rte_cpu_to_le_32(HWRM_FUNC_DRV_IF_CHANGE_INPUT_FLAGS_UP); + + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + + HWRM_CHECK_RESULT(); + HWRM_UNLOCK(); + + return rc; +} diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index a03620532..2f57e950b 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -201,4 +201,5 @@ int bnxt_hwrm_tunnel_redirect_query(struct bnxt *bp, uint32_t *type); int bnxt_hwrm_tunnel_redirect_info(struct bnxt *bp, uint8_t tun_type, uint16_t *dst_fid); int bnxt_hwrm_set_mac(struct bnxt *bp); +int bnxt_hwrm_if_change(struct bnxt *bp, bool state); #endif From patchwork Fri Aug 30 16:35:29 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58312 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 2FCD21E9C1; Fri, 30 Aug 2019 18:36:06 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 540541E986 for ; Fri, 30 Aug 2019 18:35:48 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id B1C1630C05D; Fri, 30 Aug 2019 09:35:40 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com B1C1630C05D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182940; bh=YCnrz4SZgpymJY4B0nKp1OdNMtgAsLhX02xxE1NSLEU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CWlnXBIdJDPatKRBVZGJ52s1RjtdW4QeNNNVvSUS8LXExCThr1ot45oMY5vaCVy2X Ef6ZZ/pMn66p9hGtzmJ+JY4cYkPGZb8gFrqZyZsPTE745g5Kx/hGEAc6dkK+9A/Uu/ +/C+Pz2E864Gz8UZI8qCkiCeIYKHvt7KGyrrr07o= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id 44596AC071D; Fri, 30 Aug 2019 09:35:42 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:29 -0700 Message-Id: <20190830163537.32704-6-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 05/13] net/bnxt: handle fatal event from FW under error conditions X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP When firmware hit some unrecoverable error conditions, firmware initiate the recovery by sending an async event EVENT_CMPL_EVENT_ID_RESET_NOTIFY with data1 set to RESET_NOTIFY_EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL to all host drivers and will reset the chip. The recovery procedure is same sequence as the one for hot FW upgrade. Signed-off-by: Kalesh AP Reviewed-by: Somnath Kotur Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/bnxt_cpr.c | 13 +++++++++++-- drivers/net/bnxt/bnxt_cpr.h | 5 +++++ drivers/net/bnxt/bnxt_ethdev.c | 3 +++ 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c index 62a16d2ed..0b2eeef8f 100644 --- a/drivers/net/bnxt/bnxt_cpr.c +++ b/drivers/net/bnxt/bnxt_cpr.c @@ -21,6 +21,7 @@ void bnxt_handle_async_event(struct bnxt *bp, struct hwrm_async_event_cmpl *async_cmp = (struct hwrm_async_event_cmpl *)cmp; uint16_t event_id = rte_le_to_cpu_16(async_cmp->event_id); + uint32_t event_data; /* TODO: HWRM async events are not defined yet */ /* Needs to handle: link events, error events, etc. */ @@ -42,6 +43,7 @@ void bnxt_handle_async_event(struct bnxt *bp, PMD_DRV_LOG(INFO, "Port conn async event\n"); break; case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY: + event_data = rte_le_to_cpu_32(async_cmp->event_data1); /* timestamp_lo/hi values are in units of 100ms */ bp->fw_reset_max_msecs = async_cmp->timestamp_hi ? rte_le_to_cpu_16(async_cmp->timestamp_hi) * 100 : @@ -49,8 +51,15 @@ void bnxt_handle_async_event(struct bnxt *bp, bp->fw_reset_min_msecs = async_cmp->timestamp_lo ? async_cmp->timestamp_lo * 100 : BNXT_MIN_FW_READY_TIMEOUT; - PMD_DRV_LOG(INFO, - "Firmware non-fatal reset event received\n"); + if ((event_data & EVENT_DATA1_REASON_CODE_MASK) == + EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL) { + PMD_DRV_LOG(INFO, + "Firmware fatal reset event received\n"); + bp->flags |= BNXT_FLAG_FATAL_ERROR; + } else { + PMD_DRV_LOG(INFO, + "Firmware non-fatal reset event received\n"); + } bp->flags |= BNXT_FLAG_FW_RESET; rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume, diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h index f48293b96..b61bafa0e 100644 --- a/drivers/net/bnxt/bnxt_cpr.h +++ b/drivers/net/bnxt/bnxt_cpr.h @@ -108,4 +108,9 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmp); int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp); void bnxt_dev_reset_and_resume(void *arg); +#define EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL \ + HWRM_ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_FW_EXCEPTION_FATAL +#define EVENT_DATA1_REASON_CODE_MASK \ + HWRM_ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_MASK + #endif diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 385492db5..a917e0440 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -3512,6 +3512,9 @@ static void bnxt_dev_recover(void *arg) int timeout = bp->fw_reset_max_msecs; int rc = 0; + /* Clear Error flag so that device re-init should happen */ + bp->flags &= ~BNXT_FLAG_FATAL_ERROR; + do { rc = bnxt_hwrm_ver_get(bp); if (rc == 0) From patchwork Fri Aug 30 16:35:30 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58311 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 0C0351E9BA; Fri, 30 Aug 2019 18:36:03 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 542C31E995 for ; Fri, 30 Aug 2019 18:35:48 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 3D81330C064; Fri, 30 Aug 2019 09:35:41 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 3D81330C064 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182941; bh=PMkSK8def224nc/iJTdIOl1wekweBvCdRrq5cRrgSJ8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B5Dv0dPmfi1wv4Jht+anCjM+HpFsP/YoBGyy0khF02xMTYK1ErZpb2USYVoWuzJaE vXae7aAGJjLgJcpEEZ8o4u34B0eYeUNWxf2m9Rgya+/JH12Tm7sqfx8+sH26d62vjz WQK3n9ogghBrMaOaRqFhGTq9/d62xZVJoByJl2hU= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id 74101AC06AB; Fri, 30 Aug 2019 09:35:42 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:30 -0700 Message-Id: <20190830163537.32704-7-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 06/13] net/bnxt: query firmware error recovery capabilities X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP In Driver initiated error recovery process, driver has to know about the registers offset and values to initiate FW reset. The HWRM command HWRM_ERROR_RECOVERY_QCFG is used to obtain all the registers and values required to initiate FW reset. This command response includes FW heart_beat register, health status register, Error counter register, register offsets and values to do chip reset if firmware crashes and becomes unresponsive. Signed-off-by: Kalesh AP Reviewed-by: Somnath Kotur Signed-off-by: Ajit Khaparde --- drivers/net/bnxt/bnxt.h | 27 +++++++++++ drivers/net/bnxt/bnxt_ethdev.c | 10 ++++ drivers/net/bnxt/bnxt_hwrm.c | 89 ++++++++++++++++++++++++++++++++++ drivers/net/bnxt/bnxt_hwrm.h | 1 + 4 files changed, 127 insertions(+) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 394a2a941..19bd13a7f 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -343,6 +343,29 @@ struct bnxt_ctx_mem_info { #define US_PER_MS 1000 #define NS_PER_US 1000 +struct bnxt_error_recovery_info { + /* All units in milliseconds */ + uint32_t driver_polling_freq; + uint32_t master_func_wait_period; + uint32_t normal_func_wait_period; + uint32_t master_func_wait_period_after_reset; + uint32_t max_bailout_time_after_reset; +#define BNXT_FW_STATUS_REG 0 +#define BNXT_FW_HEARTBEAT_CNT_REG 1 +#define BNXT_FW_RECOVERY_CNT_REG 2 +#define BNXT_FW_RESET_INPROG_REG 3 + uint32_t status_regs[4]; + uint32_t reset_inprogress_reg_mask; +#define BNXT_NUM_RESET_REG 16 + uint8_t reg_array_cnt; + uint32_t reset_reg[BNXT_NUM_RESET_REG]; + uint32_t reset_reg_val[BNXT_NUM_RESET_REG]; + uint8_t delay_after_reset[BNXT_NUM_RESET_REG]; +#define BNXT_FLAG_ERROR_RECOVERY_HOST (1 << 0) +#define BNXT_FLAG_ERROR_RECOVERY_CO_CPU (1 << 1) + uint32_t flags; +}; + #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) struct bnxt { void *bar0; @@ -371,6 +394,7 @@ struct bnxt { #define BNXT_FLAG_FW_RESET (1 << 15) #define BNXT_FLAG_FATAL_ERROR (1 << 16) #define BNXT_FLAG_FW_CAP_IF_CHANGE (1 << 17) +#define BNXT_FLAG_FW_CAP_ERROR_RECOVERY (1 << 18) #define BNXT_FLAG_EXT_STATS_SUPPORTED (1 << 29) #define BNXT_FLAG_NEW_RM (1 << 30) #define BNXT_FLAG_INIT_DONE (1U << 31) @@ -477,6 +501,9 @@ struct bnxt { uint16_t fw_reset_min_msecs; uint16_t fw_reset_max_msecs; + + /* Struct to hold adapter error recovery related info */ + struct bnxt_error_recovery_info *recovery_info; }; int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete); diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index a917e0440..7a1142947 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -4070,6 +4070,11 @@ static int bnxt_init_fw(struct bnxt *bp) if (rc) return rc; + /* Get the adapter error recovery support info */ + rc = bnxt_hwrm_error_recovery_qcfg(bp); + if (rc) + bp->flags &= ~BNXT_FLAG_FW_CAP_ERROR_RECOVERY; + if (mtu >= RTE_ETHER_MIN_MTU && mtu <= BNXT_MAX_MTU && mtu != bp->eth_dev->data->mtu) bp->eth_dev->data->mtu = mtu; @@ -4227,6 +4232,11 @@ bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) if (!reconfig_dev) bnxt_free_hwrm_resources(bp); + if (bp->recovery_info != NULL) { + rte_free(bp->recovery_info); + bp->recovery_info = NULL; + } + return rc; } diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index 17c7b5e9e..e2c993936 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -626,6 +626,13 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp) if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_STATS_SUPPORTED) bp->flags |= BNXT_FLAG_EXT_STATS_SUPPORTED; + if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ERROR_RECOVERY_CAPABLE) { + bp->flags |= BNXT_FLAG_FW_CAP_ERROR_RECOVERY; + PMD_DRV_LOG(DEBUG, "Adapter Error recovery SUPPORTED\n"); + } else { + bp->flags &= ~BNXT_FLAG_FW_CAP_ERROR_RECOVERY; + } + HWRM_UNLOCK(); return rc; @@ -4684,3 +4691,85 @@ int bnxt_hwrm_if_change(struct bnxt *bp, bool state) return rc; } + +int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp) +{ + struct hwrm_error_recovery_qcfg_output *resp = bp->hwrm_cmd_resp_addr; + struct bnxt_error_recovery_info *info; + struct hwrm_error_recovery_qcfg_input req = {0}; + uint32_t flags = 0; + unsigned int i; + int rc; + + /* Older FW does not have error recovery support */ + if (!(bp->flags & BNXT_FLAG_FW_CAP_ERROR_RECOVERY)) + return 0; + + info = rte_zmalloc("bnxt_hwrm_error_recovery_qcfg", + sizeof(*info), 0); + bp->recovery_info = info; + if (info == NULL) + return -ENOMEM; + + HWRM_PREP(req, ERROR_RECOVERY_QCFG, BNXT_USE_CHIMP_MB); + + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB); + + HWRM_CHECK_RESULT(); + + flags = rte_le_to_cpu_32(resp->flags); + if (flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_HOST) + info->flags |= BNXT_FLAG_ERROR_RECOVERY_HOST; + else if (flags & HWRM_ERROR_RECOVERY_QCFG_OUTPUT_FLAGS_CO_CPU) + info->flags |= BNXT_FLAG_ERROR_RECOVERY_CO_CPU; + + if ((info->flags & BNXT_FLAG_ERROR_RECOVERY_CO_CPU) && + !(bp->flags & BNXT_FLAG_KONG_MB_EN)) { + rc = -EINVAL; + goto err; + } + + /* FW returned values are in units of 100msec */ + info->driver_polling_freq = + rte_le_to_cpu_32(resp->driver_polling_freq) * 100; + info->master_func_wait_period = + rte_le_to_cpu_32(resp->master_func_wait_period) * 100; + info->normal_func_wait_period = + rte_le_to_cpu_32(resp->normal_func_wait_period) * 100; + info->master_func_wait_period_after_reset = + rte_le_to_cpu_32(resp->master_func_wait_period_after_reset) * 100; + info->max_bailout_time_after_reset = + rte_le_to_cpu_32(resp->max_bailout_time_after_reset) * 100; + info->status_regs[BNXT_FW_STATUS_REG] = + rte_le_to_cpu_32(resp->fw_health_status_reg); + info->status_regs[BNXT_FW_HEARTBEAT_CNT_REG] = + rte_le_to_cpu_32(resp->fw_heartbeat_reg); + info->status_regs[BNXT_FW_RECOVERY_CNT_REG] = + rte_le_to_cpu_32(resp->fw_reset_cnt_reg); + info->status_regs[BNXT_FW_RESET_INPROG_REG] = + rte_le_to_cpu_32(resp->reset_inprogress_reg); + info->reg_array_cnt = + rte_le_to_cpu_32(resp->reg_array_cnt); + + if (info->reg_array_cnt >= BNXT_NUM_RESET_REG) { + rc = -EINVAL; + goto err; + } + + for (i = 0; i < info->reg_array_cnt; i++) { + info->reset_reg[i] = + rte_le_to_cpu_32(resp->reset_reg[i]); + info->reset_reg_val[i] = + rte_le_to_cpu_32(resp->reset_reg_val[i]); + info->delay_after_reset[i] = + resp->delay_after_reset[i]; + } +err: + HWRM_UNLOCK(); + + if (rc) { + rte_free(bp->recovery_info); + bp->recovery_info = NULL; + } + return rc; +} diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index 2f57e950b..c332c129d 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -202,4 +202,5 @@ int bnxt_hwrm_tunnel_redirect_info(struct bnxt *bp, uint8_t tun_type, uint16_t *dst_fid); int bnxt_hwrm_set_mac(struct bnxt *bp); int bnxt_hwrm_if_change(struct bnxt *bp, bool state); +int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp); #endif From patchwork Fri Aug 30 16:35:31 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58314 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id AE7AB1E9D0; Fri, 30 Aug 2019 18:36:10 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 6CE521E998 for ; Fri, 30 Aug 2019 18:35:48 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 6F4DA30C069; Fri, 30 Aug 2019 09:35:41 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 6F4DA30C069 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182941; bh=aaoStP9WmsGqyhyF4A3L667/HstfWNw6FGRxPRLLRpk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=ZtMJdHSjmJ7QSw6xdR70yUd0TLmx5wrcgAugcS0+l2vf76bzOoaBXzCoEYadD6dqn QiSwv80ySvxvY2CXdU2auVCYuoObWE1X8MjlJMEH8DpomReF60frLQyGOUmVyFec8+ syPmvdPWei0wS0rB/wTjtOS4b2IUK6rjhIx9cueE= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id A65BDAC06AD; Fri, 30 Aug 2019 09:35:42 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:31 -0700 Message-Id: <20190830163537.32704-8-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 07/13] net/bnxt: map status registers for FW health monitoring X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP HWRM_ERROR_RECOVERY_QCFG command returns the FW status registers offset for periodic firmware health check monitoring. Map them to GRC window 2. Signed-off-by: Kalesh AP Reviewed-by: Somnath Kotur Signed-off-by: Ajit Khaparde --- drivers/net/bnxt/bnxt.h | 22 ++++++++++++++++- drivers/net/bnxt/bnxt_ethdev.c | 44 ++++++++++++++++++++++++++++++++++ drivers/net/bnxt/bnxt_hwrm.c | 4 ++++ 3 files changed, 69 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 19bd13a7f..1da09569d 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -354,7 +354,9 @@ struct bnxt_error_recovery_info { #define BNXT_FW_HEARTBEAT_CNT_REG 1 #define BNXT_FW_RECOVERY_CNT_REG 2 #define BNXT_FW_RESET_INPROG_REG 3 - uint32_t status_regs[4]; +#define BNXT_FW_STATUS_REG_CNT 4 + uint32_t status_regs[BNXT_FW_STATUS_REG_CNT]; + uint32_t mapped_status_regs[BNXT_FW_STATUS_REG_CNT]; uint32_t reset_inprogress_reg_mask; #define BNXT_NUM_RESET_REG 16 uint8_t reg_array_cnt; @@ -366,6 +368,22 @@ struct bnxt_error_recovery_info { uint32_t flags; }; +/* address space location of register */ +#define BNXT_FW_STATUS_REG_TYPE_MASK 3 +/* register is located in PCIe config space */ +#define BNXT_FW_STATUS_REG_TYPE_CFG 0 +/* register is located in GRC address space */ +#define BNXT_FW_STATUS_REG_TYPE_GRC 1 +/* register is located in BAR0 */ +#define BNXT_FW_STATUS_REG_TYPE_BAR0 2 +/* register is located in BAR1 */ +#define BNXT_FW_STATUS_REG_TYPE_BAR1 3 + +#define BNXT_FW_STATUS_REG_TYPE(reg) ((reg) & BNXT_FW_STATUS_REG_TYPE_MASK) +#define BNXT_FW_STATUS_REG_OFF(reg) ((reg) & ~BNXT_FW_STATUS_REG_TYPE_MASK) + +#define BNXT_GRCP_WINDOW_2_BASE 0x2000 + #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) struct bnxt { void *bar0; @@ -510,6 +528,8 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete); int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg); int is_bnxt_in_error(struct bnxt *bp); +int bnxt_map_fw_health_status_regs(struct bnxt *bp); + bool is_bnxt_supported(struct rte_eth_dev *dev); bool bnxt_stratus_device(struct bnxt *bp); extern const struct rte_flow_ops bnxt_flow_ops; diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 7a1142947..a0de259da 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -3496,6 +3496,49 @@ static const struct eth_dev_ops bnxt_dev_ops = { .timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp, }; +int bnxt_map_fw_health_status_regs(struct bnxt *bp) +{ + struct bnxt_error_recovery_info *info = bp->recovery_info; + uint32_t reg_base = 0xffffffff; + int i; + + /* Only pre-map the monitoring GRC registers using window 2 */ + for (i = 0; i < BNXT_FW_STATUS_REG_CNT; i++) { + uint32_t reg = info->status_regs[i]; + + if (BNXT_FW_STATUS_REG_TYPE(reg) != BNXT_FW_STATUS_REG_TYPE_GRC) + continue; + + if (reg_base == 0xffffffff) + reg_base = reg & 0xfffff000; + if ((reg & 0xfffff000) != reg_base) + return -ERANGE; + + /* Use mask 0xffc as the Lower 2 bits indicates + * address space location + */ + info->mapped_status_regs[i] = BNXT_GRCP_WINDOW_2_BASE + + (reg & 0xffc); + } + + if (reg_base == 0xffffffff) + return 0; + + rte_write32(reg_base, (uint8_t *)bp->bar0 + + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); + + return 0; +} + +static void bnxt_unmap_fw_health_status_regs(struct bnxt *bp) +{ + if (!(bp->flags & BNXT_FLAG_FW_CAP_ERROR_RECOVERY)) + return; + + rte_write32(0, (uint8_t *)bp->bar0 + + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); +} + static void bnxt_dev_cleanup(struct bnxt *bp) { bnxt_set_hwrm_link_config(bp, false); @@ -4226,6 +4269,7 @@ bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) bnxt_free_int(bp); bnxt_free_mem(bp, reconfig_dev); bnxt_hwrm_func_buf_unrgtr(bp); + bnxt_unmap_fw_health_status_regs(bp); rc = bnxt_hwrm_func_driver_unregister(bp, 0); bp->flags &= ~BNXT_FLAG_REGISTERED; bnxt_free_ctx_mem(bp); diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index e2c993936..2d9c43c98 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -4767,6 +4767,10 @@ int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp) err: HWRM_UNLOCK(); + /* Map the FW status registers */ + if (!rc) + rc = bnxt_map_fw_health_status_regs(bp); + if (rc) { rte_free(bp->recovery_info); bp->recovery_info = NULL; From patchwork Fri Aug 30 16:35:32 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58316 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id E95BC1E9EA; Fri, 30 Aug 2019 18:36:14 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 8101C1E99B for ; Fri, 30 Aug 2019 18:35:48 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id CC4F930C071; Fri, 30 Aug 2019 09:35:41 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com CC4F930C071 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182941; bh=sdNp3up0GTemiejp2SdJOyDSWR+95hdowdFaXdnq4BY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RDcbpwwBKGIsWds56iTj0IX0RqIpogjGD0wd8QfI8kYuC+dvVmF0WYZAcPyZ9gR3b ZOtJ/E7jO88v+RbpWkuMXjeDJ8RZrPUWtHDL6H3XVnjqOPpPeDa5znbxZPQk3VzGqt H3BZFzHxQBCEu3GP8R7zQU4hpUjZMRgc3VpWaNE8= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id D7C82AC071D; Fri, 30 Aug 2019 09:35:42 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:32 -0700 Message-Id: <20190830163537.32704-9-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 08/13] net/bnxt: advertise error recovery capability and handle async event X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP 1. Advertise HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_ERROR_RECOVERY_SUPPORT flag in the FUNC_DRV_RGTR command. 2. request for the async event ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY in the FUNC_DRV_RGTR command. 3. handle the async event EVENT_ID_ERROR_RECOVERY from FW. Error recovery support will be used by firmware only if all the driver instances support error recovery process. Signed-off-by: Kalesh AP Reviewed-by: Somnath Kotur Signed-off-by: Ajit Khaparde --- drivers/net/bnxt/bnxt.h | 2 ++ drivers/net/bnxt/bnxt_cpr.c | 45 ++++++++++++++++++++++++++++++++++++ drivers/net/bnxt/bnxt_cpr.h | 12 ++++++++++ drivers/net/bnxt/bnxt_hwrm.c | 5 ++++ drivers/net/bnxt/bnxt_hwrm.h | 2 ++ 5 files changed, 66 insertions(+) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 1da09569d..f9147a9a8 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -365,6 +365,8 @@ struct bnxt_error_recovery_info { uint8_t delay_after_reset[BNXT_NUM_RESET_REG]; #define BNXT_FLAG_ERROR_RECOVERY_HOST (1 << 0) #define BNXT_FLAG_ERROR_RECOVERY_CO_CPU (1 << 1) +#define BNXT_FLAG_MASTER_FUNC (1 << 2) +#define BNXT_FLAG_RECOVERY_ENABLED (1 << 3) uint32_t flags; }; diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c index 0b2eeef8f..a70301adc 100644 --- a/drivers/net/bnxt/bnxt_cpr.c +++ b/drivers/net/bnxt/bnxt_cpr.c @@ -21,6 +21,7 @@ void bnxt_handle_async_event(struct bnxt *bp, struct hwrm_async_event_cmpl *async_cmp = (struct hwrm_async_event_cmpl *)cmp; uint16_t event_id = rte_le_to_cpu_16(async_cmp->event_id); + struct bnxt_error_recovery_info *info; uint32_t event_data; /* TODO: HWRM async events are not defined yet */ @@ -65,6 +66,31 @@ void bnxt_handle_async_event(struct bnxt *bp, rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume, (void *)bp); break; + case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY: + info = bp->recovery_info; + + if (!info) + return; + + PMD_DRV_LOG(INFO, "Error recovery async event received\n"); + + event_data = rte_le_to_cpu_32(async_cmp->event_data1) & + EVENT_DATA1_FLAGS_MASK; + + if (event_data & EVENT_DATA1_FLAGS_MASTER_FUNC) + info->flags |= BNXT_FLAG_MASTER_FUNC; + else + info->flags &= ~BNXT_FLAG_MASTER_FUNC; + + if (event_data & EVENT_DATA1_FLAGS_RECOVERY_ENABLED) + info->flags |= BNXT_FLAG_RECOVERY_ENABLED; + else + info->flags &= ~BNXT_FLAG_RECOVERY_ENABLED; + + PMD_DRV_LOG(INFO, "recovery enabled(%d), master function(%d)\n", + bnxt_is_recovery_enabled(bp), + bnxt_is_master_func(bp)); + break; default: PMD_DRV_LOG(INFO, "handle_async_event id = 0x%x\n", event_id); break; @@ -186,3 +212,22 @@ int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp) return evt; } + +bool bnxt_is_master_func(struct bnxt *bp) +{ + if (bp->recovery_info->flags & BNXT_FLAG_MASTER_FUNC) + return true; + + return false; +} + +bool bnxt_is_recovery_enabled(struct bnxt *bp) +{ + struct bnxt_error_recovery_info *info; + + info = bp->recovery_info; + if (info && (info->flags & BNXT_FLAG_RECOVERY_ENABLED)) + return true; + + return false; +} diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h index b61bafa0e..f118bda36 100644 --- a/drivers/net/bnxt/bnxt_cpr.h +++ b/drivers/net/bnxt/bnxt_cpr.h @@ -113,4 +113,16 @@ void bnxt_dev_reset_and_resume(void *arg); #define EVENT_DATA1_REASON_CODE_MASK \ HWRM_ASYNC_EVENT_CMPL_RESET_NOTIFY_EVENT_DATA1_REASON_CODE_MASK +#define EVENT_DATA1_FLAGS_MASK \ + HWRM_ASYNC_EVENT_CMPL_ERROR_RECOVERY_EVENT_DATA1_FLAGS_MASK + +#define EVENT_DATA1_FLAGS_MASTER_FUNC \ + HWRM_ASYNC_EVENT_CMPL_ERROR_RECOVERY_EVENT_DATA1_FLAGS_MASTER_FUNC + +#define EVENT_DATA1_FLAGS_RECOVERY_ENABLED \ + HWRM_ASYNC_EVENT_CMPL_ERROR_RECOVERY_EVENT_DATA1_FLAGS_RECOVERY_ENABLED + +bool bnxt_is_recovery_enabled(struct bnxt *bp); +bool bnxt_is_master_func(struct bnxt *bp); + #endif diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index 2d9c43c98..350e867bf 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -685,6 +685,8 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) return 0; flags = HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_HOT_RESET_SUPPORT; + if (bp->flags & BNXT_FLAG_FW_CAP_ERROR_RECOVERY) + flags |= HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_ERROR_RECOVERY_SUPPORT; HWRM_PREP(req, FUNC_DRV_RGTR, BNXT_USE_CHIMP_MB); req.enables = rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER | @@ -716,6 +718,9 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) ASYNC_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED | ASYNC_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE | ASYNC_CMPL_EVENT_ID_RESET_NOTIFY); + if (bp->flags & BNXT_FLAG_FW_CAP_ERROR_RECOVERY) + req.async_event_fwd[0] |= + rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_ERROR_RECOVERY); req.async_event_fwd[1] |= rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_PF_DRVR_UNLOAD | ASYNC_CMPL_EVENT_ID_VF_CFG_CHANGE); diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index c332c129d..44e335507 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -23,6 +23,8 @@ struct bnxt_cp_ring_info; (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE) #define ASYNC_CMPL_EVENT_ID_RESET_NOTIFY \ (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_RESET_NOTIFY) +#define ASYNC_CMPL_EVENT_ID_ERROR_RECOVERY \ + (1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY) #define ASYNC_CMPL_EVENT_ID_PF_DRVR_UNLOAD \ (1 << (HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD - 32)) #define ASYNC_CMPL_EVENT_ID_VF_CFG_CHANGE \ From patchwork Fri Aug 30 16:35:33 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58313 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 6383F1E9C8; Fri, 30 Aug 2019 18:36:08 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 6D0AA1E999 for ; Fri, 30 Aug 2019 18:35:48 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 828EA30C06D; Fri, 30 Aug 2019 09:35:41 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 828EA30C06D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182941; bh=gK23BJ+WJntaXysMpwAZaVDXjl5eMgufuPucpY7Nr4U=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=cjxAsWF8LX6Wvf8dncElafxVRHKExclnzhwtlP1H5QqRpXAF20pNB8GVHHbmrO+ZS NTzSjwTJmkYEPQvnI+DP1Mu1SME8qCy93QeogpUzgMDU1LTfX4/asUx9ovQTlqmEul n3jt6Krc/MfsBW6DRPJPKYLQ0Q0wTKXijSHw/B3M= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id 159ECAC06AB; Fri, 30 Aug 2019 09:35:43 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:33 -0700 Message-Id: <20190830163537.32704-10-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 09/13] net/bnxt: add code for periodic FW health monitoring X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP Periodically poll the FW heartbeat register and FW recovery counter registers to check the FW health. Polling frequency will be advertised by the FW in HWRM_ERROR_RECOVERY_QCFG response. Schedule the task upon receiving the async event from FW. Signed-off-by: Kalesh AP Reviewed-by: Ajit Khaparde Reviewed-by: Somnath Kotur --- drivers/net/bnxt/bnxt.h | 6 +++ drivers/net/bnxt/bnxt_cpr.c | 10 ++++ drivers/net/bnxt/bnxt_ethdev.c | 89 ++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index f9147a9a8..5579e127c 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -368,6 +368,9 @@ struct bnxt_error_recovery_info { #define BNXT_FLAG_MASTER_FUNC (1 << 2) #define BNXT_FLAG_RECOVERY_ENABLED (1 << 3) uint32_t flags; + + uint32_t last_heart_beat; + uint32_t last_reset_counter; }; /* address space location of register */ @@ -415,6 +418,7 @@ struct bnxt { #define BNXT_FLAG_FATAL_ERROR (1 << 16) #define BNXT_FLAG_FW_CAP_IF_CHANGE (1 << 17) #define BNXT_FLAG_FW_CAP_ERROR_RECOVERY (1 << 18) +#define BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED (1 << 19) #define BNXT_FLAG_EXT_STATS_SUPPORTED (1 << 29) #define BNXT_FLAG_NEW_RM (1 << 30) #define BNXT_FLAG_INIT_DONE (1U << 31) @@ -531,6 +535,8 @@ int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg); int is_bnxt_in_error(struct bnxt *bp); int bnxt_map_fw_health_status_regs(struct bnxt *bp); +uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index); +void bnxt_schedule_fw_health_check(struct bnxt *bp); bool is_bnxt_supported(struct rte_eth_dev *dev); bool bnxt_stratus_device(struct bnxt *bp); diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c index a70301adc..3cedb891e 100644 --- a/drivers/net/bnxt/bnxt_cpr.c +++ b/drivers/net/bnxt/bnxt_cpr.c @@ -90,6 +90,16 @@ void bnxt_handle_async_event(struct bnxt *bp, PMD_DRV_LOG(INFO, "recovery enabled(%d), master function(%d)\n", bnxt_is_recovery_enabled(bp), bnxt_is_master_func(bp)); + + if (bp->flags & BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED) + return; + + info->last_heart_beat = + bnxt_read_fw_status_reg(bp, BNXT_FW_HEARTBEAT_CNT_REG); + info->last_reset_counter = + bnxt_read_fw_status_reg(bp, BNXT_FW_RECOVERY_CNT_REG); + + bnxt_schedule_fw_health_check(bp); break; default: PMD_DRV_LOG(INFO, "handle_async_event id = 0x%x\n", event_id); diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index a0de259da..62a4a65fb 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -3607,6 +3607,94 @@ void bnxt_dev_reset_and_resume(void *arg) PMD_DRV_LOG(ERR, "Error setting recovery alarm"); } +uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index) +{ + struct bnxt_error_recovery_info *info = bp->recovery_info; + uint32_t reg = info->status_regs[index]; + uint32_t type, offset, val = 0; + + type = BNXT_FW_STATUS_REG_TYPE(reg); + offset = BNXT_FW_STATUS_REG_OFF(reg); + + switch (type) { + case BNXT_FW_STATUS_REG_TYPE_CFG: + rte_pci_read_config(bp->pdev, &val, sizeof(val), offset); + break; + case BNXT_FW_STATUS_REG_TYPE_GRC: + offset = info->mapped_status_regs[index]; + /* FALLTHROUGH */ + case BNXT_FW_STATUS_REG_TYPE_BAR0: + val = rte_le_to_cpu_32(rte_read32((uint8_t *)bp->bar0 + + offset)); + break; + } + + return val; +} + +/* Driver should poll FW heartbeat, reset_counter with the frequency + * advertised by FW in HWRM_ERROR_RECOVERY_QCFG. + * When the driver detects heartbeat stop or change in reset_counter, + * it has to trigger a reset to recover from the error condition. + * A “master PF” is the function who will have the privilege to + * initiate the chimp reset. The master PF will be elected by the + * firmware and will be notified through async message. + */ +static void bnxt_check_fw_health(void *arg) +{ + struct bnxt *bp = arg; + struct bnxt_error_recovery_info *info = bp->recovery_info; + uint32_t val = 0; + + if (!info || !bnxt_is_recovery_enabled(bp) || + is_bnxt_in_error(bp)) + return; + + val = bnxt_read_fw_status_reg(bp, BNXT_FW_HEARTBEAT_CNT_REG); + if (val == info->last_heart_beat) + goto reset; + + info->last_heart_beat = val; + + val = bnxt_read_fw_status_reg(bp, BNXT_FW_RECOVERY_CNT_REG); + if (val != info->last_reset_counter) + goto reset; + + info->last_reset_counter = val; + + rte_eal_alarm_set(US_PER_MS * info->driver_polling_freq, + bnxt_check_fw_health, (void *)bp); + + return; +reset: + /* Stop DMA to/from device */ + bp->flags |= BNXT_FLAG_FATAL_ERROR; + bp->flags |= BNXT_FLAG_FW_RESET; + + PMD_DRV_LOG(ERR, "Detected FW dead condition\n"); +} + +void bnxt_schedule_fw_health_check(struct bnxt *bp) +{ + uint32_t polling_freq = bp->recovery_info->driver_polling_freq; + + if (!bnxt_is_recovery_enabled(bp)) + return; + + rte_eal_alarm_set(US_PER_MS * polling_freq, + bnxt_check_fw_health, (void *)bp); + bp->flags |= BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED; +} + +static void bnxt_cancel_fw_health_check(struct bnxt *bp) +{ + if (!bnxt_is_recovery_enabled(bp)) + return; + + rte_eal_alarm_cancel(bnxt_check_fw_health, (void *)bp); + bp->flags &= ~BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED; +} + static bool bnxt_vf_pciid(uint16_t id) { if (id == BROADCOM_DEV_ID_57304_VF || @@ -4269,6 +4357,7 @@ bnxt_uninit_resources(struct bnxt *bp, bool reconfig_dev) bnxt_free_int(bp); bnxt_free_mem(bp, reconfig_dev); bnxt_hwrm_func_buf_unrgtr(bp); + bnxt_cancel_fw_health_check(bp); bnxt_unmap_fw_health_status_regs(bp); rc = bnxt_hwrm_func_driver_unregister(bp, 0); bp->flags &= ~BNXT_FLAG_REGISTERED; From patchwork Fri Aug 30 16:35:34 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58315 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D6D621E9DD; Fri, 30 Aug 2019 18:36:12 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id 745B31E99A for ; Fri, 30 Aug 2019 18:35:48 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id CC51730C07C; Fri, 30 Aug 2019 09:35:41 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com CC51730C07C DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182941; bh=2LO8hz7yLtPiwv4MDOYHS94yyBKt6mFry2OZrnue3bo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=oOXULQn0lLAnuxnR8JtAomkwM/2xkIyfupEVTVPOguI6ddEB6olTpvHH/IadqPKm3 N5zHd8T8Y/W0V3zKajhoXxGbnxql8lYWtE90yzuy2WAtVB4XJ/5HcgFvWeoRWRn3uy XClLQBvs+mOR4PKo3OTDsQ9zYeQIuXZPDd2Ysj3k= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id 46491AC06AD; Fri, 30 Aug 2019 09:35:43 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:34 -0700 Message-Id: <20190830163537.32704-11-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 10/13] net/bnxt: add support for FW reset X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP Added code to perform FW_RESET. When the driver detects error in FW, it has to initiate the recovery by resetting the cores. FW advertise the method to do a core reset, reset register offsets and values to perform reset in response of HWRM_ERROR_RECOVERY_QCFG command. There are 2 ways to recover from the error. 1. Master function issues core resets to recover from error. 2. Master function detects chimp dead condition and notify the Kong processor about the chimp dead case through FW_RESET HWRM command. Kong Processor send an RESET_NOTIFY async event with REASON_CODE_FW_EXCEPTION_FATAL to all the PF’s/VF’s that chimp is dead and it is going to reset the chimp. Signed-off-by: Kalesh AP Reviewed-by: Somnath Kotur Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/bnxt.h | 1 + drivers/net/bnxt/bnxt_ethdev.c | 104 ++++++++++++++++++++++++++++++++- drivers/net/bnxt/bnxt_hwrm.c | 26 +++++++++ drivers/net/bnxt/bnxt_hwrm.h | 1 + 4 files changed, 131 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 5579e127c..a1a8cd534 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -388,6 +388,7 @@ struct bnxt_error_recovery_info { #define BNXT_FW_STATUS_REG_OFF(reg) ((reg) & ~BNXT_FW_STATUS_REG_TYPE_MASK) #define BNXT_GRCP_WINDOW_2_BASE 0x2000 +#define BNXT_GRCP_WINDOW_3_BASE 0x3000 #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) struct bnxt { diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 62a4a65fb..76f9e197f 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -3496,6 +3496,19 @@ static const struct eth_dev_ops bnxt_dev_ops = { .timesync_read_tx_timestamp = bnxt_timesync_read_tx_timestamp, }; +static uint32_t bnxt_map_reset_regs(struct bnxt *bp, uint32_t reg) +{ + uint32_t offset; + + /* Only pre-map the reset GRC registers using window 3 */ + rte_write32(reg & 0xfffff000, (uint8_t *)bp->bar0 + + BNXT_GRCPF_REG_WINDOW_BASE_OUT + 8); + + offset = BNXT_GRCP_WINDOW_3_BASE + (reg & 0xffc); + + return offset; +} + int bnxt_map_fw_health_status_regs(struct bnxt *bp) { struct bnxt_error_recovery_info *info = bp->recovery_info; @@ -3539,6 +3552,34 @@ static void bnxt_unmap_fw_health_status_regs(struct bnxt *bp) BNXT_GRCPF_REG_WINDOW_BASE_OUT + 4); } +static void bnxt_write_fw_reset_reg(struct bnxt *bp, uint32_t index) +{ + struct bnxt_error_recovery_info *info = bp->recovery_info; + uint32_t delay = info->delay_after_reset[index]; + uint32_t val = info->reset_reg_val[index]; + uint32_t reg = info->reset_reg[index]; + uint32_t type, offset; + + type = BNXT_FW_STATUS_REG_TYPE(reg); + offset = BNXT_FW_STATUS_REG_OFF(reg); + + switch (type) { + case BNXT_FW_STATUS_REG_TYPE_CFG: + rte_pci_write_config(bp->pdev, &val, sizeof(val), offset); + break; + case BNXT_FW_STATUS_REG_TYPE_GRC: + offset = bnxt_map_reset_regs(bp, offset); + rte_write32(val, (uint8_t *)bp->bar0 + offset); + break; + case BNXT_FW_STATUS_REG_TYPE_BAR0: + rte_write32(val, (uint8_t *)bp->bar0 + offset); + break; + } + /* wait on a specific interval of time until core reset is complete */ + if (delay) + rte_delay_ms(delay); +} + static void bnxt_dev_cleanup(struct bnxt *bp) { bnxt_set_hwrm_link_config(bp, false); @@ -3632,6 +3673,59 @@ uint32_t bnxt_read_fw_status_reg(struct bnxt *bp, uint32_t index) return val; } +static int bnxt_fw_reset_all(struct bnxt *bp) +{ + struct bnxt_error_recovery_info *info = bp->recovery_info; + uint32_t i; + int rc = 0; + + if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) { + /* Reset through master function driver */ + for (i = 0; i < info->reg_array_cnt; i++) + bnxt_write_fw_reset_reg(bp, i); + /* Wait for time specified by FW after triggering reset */ + rte_delay_ms(info->master_func_wait_period_after_reset); + } else if (info->flags & BNXT_FLAG_ERROR_RECOVERY_CO_CPU) { + /* Reset with the help of Kong processor */ + rc = bnxt_hwrm_fw_reset(bp); + if (rc) + PMD_DRV_LOG(ERR, "Failed to reset FW\n"); + } + + return rc; +} + +static void bnxt_fw_reset_cb(void *arg) +{ + struct bnxt *bp = arg; + struct bnxt_error_recovery_info *info = bp->recovery_info; + int rc = 0; + + /* Only Master function can do FW reset */ + if (bnxt_is_master_func(bp) && + bnxt_is_recovery_enabled(bp)) { + rc = bnxt_fw_reset_all(bp); + if (rc) { + PMD_DRV_LOG(ERR, "Adapter recovery failed\n"); + return; + } + } + + /* if recovery method is ERROR_RECOVERY_CO_CPU, KONG will send + * EXCEPTION_FATAL_ASYNC event to all the functions + * (including MASTER FUNC). After receiving this Async, all the active + * drivers should treat this case as FW initiated recovery + */ + if (info->flags & BNXT_FLAG_ERROR_RECOVERY_HOST) { + bp->fw_reset_min_msecs = BNXT_MIN_FW_READY_TIMEOUT; + bp->fw_reset_max_msecs = BNXT_MAX_FW_RESET_TIMEOUT; + + /* To recover from error */ + rte_eal_alarm_set(US_PER_MS, bnxt_dev_reset_and_resume, + (void *)bp); + } +} + /* Driver should poll FW heartbeat, reset_counter with the frequency * advertised by FW in HWRM_ERROR_RECOVERY_QCFG. * When the driver detects heartbeat stop or change in reset_counter, @@ -3644,7 +3738,7 @@ static void bnxt_check_fw_health(void *arg) { struct bnxt *bp = arg; struct bnxt_error_recovery_info *info = bp->recovery_info; - uint32_t val = 0; + uint32_t val = 0, wait_msec; if (!info || !bnxt_is_recovery_enabled(bp) || is_bnxt_in_error(bp)) @@ -3672,6 +3766,14 @@ static void bnxt_check_fw_health(void *arg) bp->flags |= BNXT_FLAG_FW_RESET; PMD_DRV_LOG(ERR, "Detected FW dead condition\n"); + + if (bnxt_is_master_func(bp)) + wait_msec = info->master_func_wait_period; + else + wait_msec = info->normal_func_wait_period; + + rte_eal_alarm_set(US_PER_MS * wait_msec, + bnxt_fw_reset_cb, (void *)bp); } void bnxt_schedule_fw_health_check(struct bnxt *bp) diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index 350e867bf..bd2cc01e1 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -4782,3 +4782,29 @@ int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp) } return rc; } + +int bnxt_hwrm_fw_reset(struct bnxt *bp) +{ + struct hwrm_fw_reset_output *resp = bp->hwrm_cmd_resp_addr; + struct hwrm_fw_reset_input req = {0}; + int rc; + + if (!BNXT_PF(bp)) + return -EOPNOTSUPP; + + HWRM_PREP(req, FW_RESET, BNXT_USE_KONG(bp)); + + req.embedded_proc_type = + HWRM_FW_RESET_INPUT_EMBEDDED_PROC_TYPE_CHIP; + req.selfrst_status = + HWRM_FW_RESET_INPUT_SELFRST_STATUS_SELFRSTASAP; + req.flags = HWRM_FW_RESET_INPUT_FLAGS_RESET_GRACEFUL; + + rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), + BNXT_USE_KONG(bp)); + + HWRM_CHECK_RESULT(); + HWRM_UNLOCK(); + + return rc; +} diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index 44e335507..db25ad591 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -205,4 +205,5 @@ int bnxt_hwrm_tunnel_redirect_info(struct bnxt *bp, uint8_t tun_type, int bnxt_hwrm_set_mac(struct bnxt *bp); int bnxt_hwrm_if_change(struct bnxt *bp, bool state); int bnxt_hwrm_error_recovery_qcfg(struct bnxt *bp); +int bnxt_hwrm_fw_reset(struct bnxt *bp); #endif From patchwork Fri Aug 30 16:35:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58319 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id DAAF81EA15; Fri, 30 Aug 2019 18:36:21 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id A8BFB1E99D for ; Fri, 30 Aug 2019 18:35:48 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 4655030C08D; Fri, 30 Aug 2019 09:35:42 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 4655030C08D DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182942; bh=XeB55kPMGNbniOHBymcFeZ7xdd+EaNI3P9+wRypKFDc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=mOz6/l72Tgb8IgjoIENcSLQkGtW+xXBgA4FfjWMVlR0kZ8S3g6uH1mbjcvaDNtckS zSoFKWWnPcNfERCBPjMSH+e4CS8K/g8ahNmDeJzdmNEnJonP0dp+OY40ojaRl1qFfl XkRLzuESQx/1lhvrMKAUh2vE91JhFICn/oHlD/eM= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id 78A86AC0768; Fri, 30 Aug 2019 09:35:43 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Lance Richardson , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:35 -0700 Message-Id: <20190830163537.32704-12-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 11/13] net/bnxt: reduce verbosity of logs X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP When IOMMU is available, EAL picks IOVA as VA as the default IOVA mode. This causes the bnxt driver to log warning messages saying "Memzone physical address same as virtual." and "Using rte_mem_virt2iova()" during load. Reduce the verbosity of logs to DEBUG. Signed-off-by: Kalesh AP Reviewed-by: Lance Richardson Reviewed-by: Somnath Kotur Reviewed-by: Ajit Khaparde --- drivers/net/bnxt/bnxt_ethdev.c | 21 +++++++++------------ drivers/net/bnxt/bnxt_ring.c | 7 +++---- drivers/net/bnxt/bnxt_vnic.c | 7 +++---- 3 files changed, 15 insertions(+), 20 deletions(-) diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index 76f9e197f..b94c9a122 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -3890,10 +3890,9 @@ static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp, memset(mz->addr, 0, mz->len); mz_phys_addr = mz->iova; if ((unsigned long)mz->addr == mz_phys_addr) { - PMD_DRV_LOG(WARNING, - "Memzone physical address same as virtual.\n"); - PMD_DRV_LOG(WARNING, - "Using rte_mem_virt2iova()\n"); + PMD_DRV_LOG(DEBUG, + "physical address same as virtual\n"); + PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n"); mz_phys_addr = rte_mem_virt2iova(mz->addr); if (mz_phys_addr == RTE_BAD_IOVA) { PMD_DRV_LOG(ERR, @@ -3926,10 +3925,9 @@ static int bnxt_alloc_ctx_mem_blk(__rte_unused struct bnxt *bp, memset(mz->addr, 0, mz->len); mz_phys_addr = mz->iova; if ((unsigned long)mz->addr == mz_phys_addr) { - PMD_DRV_LOG(WARNING, + PMD_DRV_LOG(DEBUG, "Memzone physical address same as virtual.\n"); - PMD_DRV_LOG(WARNING, - "Using rte_mem_virt2iova()\n"); + PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n"); for (sz = 0; sz < mem_size; sz += BNXT_PAGE_SIZE) rte_mem_lock_page(((char *)mz->addr) + sz); mz_phys_addr = rte_mem_virt2iova(mz->addr); @@ -4117,9 +4115,9 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp) memset(mz->addr, 0, mz->len); mz_phys_addr = mz->iova; if ((unsigned long)mz->addr == mz_phys_addr) { - PMD_DRV_LOG(WARNING, + PMD_DRV_LOG(DEBUG, "Memzone physical address same as virtual.\n"); - PMD_DRV_LOG(WARNING, + PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n"); mz_phys_addr = rte_mem_virt2iova(mz->addr); if (mz_phys_addr == RTE_BAD_IOVA) { @@ -4155,10 +4153,9 @@ static int bnxt_alloc_stats_mem(struct bnxt *bp) memset(mz->addr, 0, mz->len); mz_phys_addr = mz->iova; if ((unsigned long)mz->addr == mz_phys_addr) { - PMD_DRV_LOG(WARNING, + PMD_DRV_LOG(DEBUG, "Memzone physical address same as virtual\n"); - PMD_DRV_LOG(WARNING, - "Using rte_mem_virt2iova()\n"); + PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n"); mz_phys_addr = rte_mem_virt2iova(mz->addr); if (mz_phys_addr == RTE_BAD_IOVA) { PMD_DRV_LOG(ERR, diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c index f19865c83..2f57e038a 100644 --- a/drivers/net/bnxt/bnxt_ring.c +++ b/drivers/net/bnxt/bnxt_ring.c @@ -212,10 +212,9 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, mz_phys_addr_base = mz->iova; mz_phys_addr = mz->iova; if ((unsigned long)mz->addr == mz_phys_addr_base) { - PMD_DRV_LOG(WARNING, - "Memzone physical address same as virtual.\n"); - PMD_DRV_LOG(WARNING, - "Using rte_mem_virt2iova()\n"); + PMD_DRV_LOG(DEBUG, + "Memzone physical address same as virtual.\n"); + PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n"); for (sz = 0; sz < total_alloc_len; sz += getpagesize()) rte_mem_lock_page(((char *)mz->addr) + sz); mz_phys_addr_base = rte_mem_virt2iova(mz->addr); diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c index 98415633e..9ea99388b 100644 --- a/drivers/net/bnxt/bnxt_vnic.c +++ b/drivers/net/bnxt/bnxt_vnic.c @@ -150,10 +150,9 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp) } mz_phys_addr = mz->iova; if ((unsigned long)mz->addr == mz_phys_addr) { - PMD_DRV_LOG(WARNING, - "Memzone physical address same as virtual.\n"); - PMD_DRV_LOG(WARNING, - "Using rte_mem_virt2iova()\n"); + PMD_DRV_LOG(DEBUG, + "Memzone physical address same as virtual.\n"); + PMD_DRV_LOG(DEBUG, "Using rte_mem_virt2iova()\n"); mz_phys_addr = rte_mem_virt2iova(mz->addr); if (mz_phys_addr == RTE_BAD_IOVA) { PMD_DRV_LOG(ERR, From patchwork Fri Aug 30 16:35:36 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58318 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id D70E51EA0A; Fri, 30 Aug 2019 18:36:19 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id A8DBC1E99E for ; Fri, 30 Aug 2019 18:35:48 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id 43F9830C08A; Fri, 30 Aug 2019 09:35:42 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com 43F9830C08A DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182942; bh=owmwMEUl2ylPfgyIwn2VBhhnBu3Pxlk7HJBAPo8ig0I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KgtdxhHGZXXbyjQ6SJfPxBwuC1tsxn9VagtyzNBBt60bsN+qeYZTYGZZmGI+qpYn2 OEnMor+qctUSWE3QVYLaa8QuowibI2vd6MHf8LV4piDCtMIUiNLgm0xKw0DRCd8m5U wjJ+EMDXqtaAzvdJpRs+CwlLLzKOcH2V8ThdUzic= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id AF090AC07A7; Fri, 30 Aug 2019 09:35:43 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , Somnath Kotur Date: Fri, 30 Aug 2019 09:35:36 -0700 Message-Id: <20190830163537.32704-13-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 12/13] net/bnxt: use BIT macro instead of bit fields X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP use BIT macro instead of bit fields. Signed-off-by: Kalesh AP Reviewed-by: Somnath Kotur Signed-off-by: Ajit Khaparde --- drivers/net/bnxt/bnxt.h | 75 ++++++++++++++++++------------------ drivers/net/bnxt/bnxt_util.h | 4 ++ 2 files changed, 42 insertions(+), 37 deletions(-) diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index a1a8cd534..ac602fe52 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -19,6 +19,7 @@ #include #include "bnxt_cpr.h" +#include "bnxt_util.h" #define BNXT_MAX_MTU 9574 #define VLAN_TAG_SIZE 4 @@ -198,16 +199,16 @@ struct bnxt_ptp_cfg { struct bnxt *bp; #define BNXT_MAX_TX_TS 1 uint16_t rxctl; -#define BNXT_PTP_MSG_SYNC (1 << 0) -#define BNXT_PTP_MSG_DELAY_REQ (1 << 1) -#define BNXT_PTP_MSG_PDELAY_REQ (1 << 2) -#define BNXT_PTP_MSG_PDELAY_RESP (1 << 3) -#define BNXT_PTP_MSG_FOLLOW_UP (1 << 8) -#define BNXT_PTP_MSG_DELAY_RESP (1 << 9) -#define BNXT_PTP_MSG_PDELAY_RESP_FOLLOW_UP (1 << 10) -#define BNXT_PTP_MSG_ANNOUNCE (1 << 11) -#define BNXT_PTP_MSG_SIGNALING (1 << 12) -#define BNXT_PTP_MSG_MANAGEMENT (1 << 13) +#define BNXT_PTP_MSG_SYNC BIT(0) +#define BNXT_PTP_MSG_DELAY_REQ BIT(1) +#define BNXT_PTP_MSG_PDELAY_REQ BIT(2) +#define BNXT_PTP_MSG_PDELAY_RESP BIT(3) +#define BNXT_PTP_MSG_FOLLOW_UP BIT(8) +#define BNXT_PTP_MSG_DELAY_RESP BIT(9) +#define BNXT_PTP_MSG_PDELAY_RESP_FOLLOW_UP BIT(10) +#define BNXT_PTP_MSG_ANNOUNCE BIT(11) +#define BNXT_PTP_MSG_SIGNALING BIT(12) +#define BNXT_PTP_MSG_MANAGEMENT BIT(13) #define BNXT_PTP_MSG_EVENTS (BNXT_PTP_MSG_SYNC | \ BNXT_PTP_MSG_DELAY_REQ | \ BNXT_PTP_MSG_PDELAY_REQ | \ @@ -363,10 +364,10 @@ struct bnxt_error_recovery_info { uint32_t reset_reg[BNXT_NUM_RESET_REG]; uint32_t reset_reg_val[BNXT_NUM_RESET_REG]; uint8_t delay_after_reset[BNXT_NUM_RESET_REG]; -#define BNXT_FLAG_ERROR_RECOVERY_HOST (1 << 0) -#define BNXT_FLAG_ERROR_RECOVERY_CO_CPU (1 << 1) -#define BNXT_FLAG_MASTER_FUNC (1 << 2) -#define BNXT_FLAG_RECOVERY_ENABLED (1 << 3) +#define BNXT_FLAG_ERROR_RECOVERY_HOST BIT(0) +#define BNXT_FLAG_ERROR_RECOVERY_CO_CPU BIT(1) +#define BNXT_FLAG_MASTER_FUNC BIT(2) +#define BNXT_FLAG_RECOVERY_ENABLED BIT(3) uint32_t flags; uint32_t last_heart_beat; @@ -400,29 +401,29 @@ struct bnxt { void *doorbell_base; uint32_t flags; -#define BNXT_FLAG_REGISTERED (1 << 0) -#define BNXT_FLAG_VF (1 << 1) -#define BNXT_FLAG_PORT_STATS (1 << 2) -#define BNXT_FLAG_JUMBO (1 << 3) -#define BNXT_FLAG_SHORT_CMD (1 << 4) -#define BNXT_FLAG_UPDATE_HASH (1 << 5) -#define BNXT_FLAG_PTP_SUPPORTED (1 << 6) -#define BNXT_FLAG_MULTI_HOST (1 << 7) -#define BNXT_FLAG_EXT_RX_PORT_STATS (1 << 8) -#define BNXT_FLAG_EXT_TX_PORT_STATS (1 << 9) -#define BNXT_FLAG_KONG_MB_EN (1 << 10) -#define BNXT_FLAG_TRUSTED_VF_EN (1 << 11) -#define BNXT_FLAG_DFLT_VNIC_SET (1 << 12) -#define BNXT_FLAG_THOR_CHIP (1 << 13) -#define BNXT_FLAG_STINGRAY (1 << 14) -#define BNXT_FLAG_FW_RESET (1 << 15) -#define BNXT_FLAG_FATAL_ERROR (1 << 16) -#define BNXT_FLAG_FW_CAP_IF_CHANGE (1 << 17) -#define BNXT_FLAG_FW_CAP_ERROR_RECOVERY (1 << 18) -#define BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED (1 << 19) -#define BNXT_FLAG_EXT_STATS_SUPPORTED (1 << 29) -#define BNXT_FLAG_NEW_RM (1 << 30) -#define BNXT_FLAG_INIT_DONE (1U << 31) +#define BNXT_FLAG_REGISTERED BIT(0) +#define BNXT_FLAG_VF BIT(1) +#define BNXT_FLAG_PORT_STATS BIT(2) +#define BNXT_FLAG_JUMBO BIT(3) +#define BNXT_FLAG_SHORT_CMD BIT(4) +#define BNXT_FLAG_UPDATE_HASH BIT(5) +#define BNXT_FLAG_PTP_SUPPORTED BIT(6) +#define BNXT_FLAG_MULTI_HOST BIT(7) +#define BNXT_FLAG_EXT_RX_PORT_STATS BIT(8) +#define BNXT_FLAG_EXT_TX_PORT_STATS BIT(9) +#define BNXT_FLAG_KONG_MB_EN BIT(10) +#define BNXT_FLAG_TRUSTED_VF_EN BIT(11) +#define BNXT_FLAG_DFLT_VNIC_SET BIT(12) +#define BNXT_FLAG_THOR_CHIP BIT(13) +#define BNXT_FLAG_STINGRAY BIT(14) +#define BNXT_FLAG_FW_RESET BIT(15) +#define BNXT_FLAG_FATAL_ERROR BIT(16) +#define BNXT_FLAG_FW_CAP_IF_CHANGE BIT(17) +#define BNXT_FLAG_FW_CAP_ERROR_RECOVERY BIT(18) +#define BNXT_FLAG_FW_HEALTH_CHECK_SCHEDULED BIT(19) +#define BNXT_FLAG_EXT_STATS_SUPPORTED BIT(20) +#define BNXT_FLAG_NEW_RM BIT(21) +#define BNXT_FLAG_INIT_DONE BIT(22) #define BNXT_PF(bp) (!((bp)->flags & BNXT_FLAG_VF)) #define BNXT_VF(bp) ((bp)->flags & BNXT_FLAG_VF) #define BNXT_NPAR(bp) ((bp)->port_partition_type) diff --git a/drivers/net/bnxt/bnxt_util.h b/drivers/net/bnxt/bnxt_util.h index 9f1868a78..a15b3a1a9 100644 --- a/drivers/net/bnxt/bnxt_util.h +++ b/drivers/net/bnxt/bnxt_util.h @@ -6,6 +6,10 @@ #ifndef _BNXT_UTIL_H_ #define _BNXT_UTIL_H_ +#ifndef BIT +#define BIT(n) (1UL << (n)) +#endif /* BIT */ + int bnxt_check_zero_bytes(const uint8_t *bytes, int len); void bnxt_eth_hw_addr_random(uint8_t *mac_addr); From patchwork Fri Aug 30 16:35:37 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ajit Khaparde X-Patchwork-Id: 58317 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@dpdk.org Delivered-To: patchwork@dpdk.org Received: from [92.243.14.124] (localhost [127.0.0.1]) by dpdk.org (Postfix) with ESMTP id 795811E9F9; Fri, 30 Aug 2019 18:36:17 +0200 (CEST) Received: from rnd-relay.smtp.broadcom.com (rnd-relay.smtp.broadcom.com [192.19.229.170]) by dpdk.org (Postfix) with ESMTP id C0B861E99F; Fri, 30 Aug 2019 18:35:48 +0200 (CEST) Received: from nis-sj1-27.broadcom.com (nis-sj1-27.lvn.broadcom.net [10.75.144.136]) by rnd-relay.smtp.broadcom.com (Postfix) with ESMTP id B8EE230C092; Fri, 30 Aug 2019 09:35:42 -0700 (PDT) DKIM-Filter: OpenDKIM Filter v2.10.3 rnd-relay.smtp.broadcom.com B8EE230C092 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=broadcom.com; s=dkimrelay; t=1567182942; bh=fDYe0mzubezA/421dwAxazovmuaOcAQJ7uEXtHKqxmA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lNdHzUfvhwVhn7qW70McRzsXQnY+AvcEI9PAotv/fEvUOJW6mdPZNWD+8uD+4mVkB 6HLGPsknoOBCyJg81R8BlJUCIvgV89sMvUDoJxPjxxV5hmuGS6YxRfCbD9DOa8nriQ GG7Fp67NJLc75DEr5I+px2YB9qnHCJ8Gw7yMm5sg= Received: from localhost.localdomain (unknown [10.230.30.225]) by nis-sj1-27.broadcom.com (Postfix) with ESMTP id DE0B5AC06AB; Fri, 30 Aug 2019 09:35:43 -0700 (PDT) From: Ajit Khaparde To: dev@dpdk.org Cc: ferruh.yigit@intel.com, Kalesh AP , stable@dpdk.org, Ajit Kumar Khaparde , Rahul Gupta , Lance Richardson Date: Fri, 30 Aug 2019 09:35:37 -0700 Message-Id: <20190830163537.32704-14-ajit.khaparde@broadcom.com> X-Mailer: git-send-email 2.20.1 (Apple Git-117) In-Reply-To: <20190830163537.32704-1-ajit.khaparde@broadcom.com> References: <2a851a62-f5a1-7061-edb4-412db0d335ce@intel.com> <20190830163537.32704-1-ajit.khaparde@broadcom.com> MIME-Version: 1.0 Subject: [dpdk-dev] [PATCH v2 13/13] net/bnxt: avoid null pointer dereference X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Kalesh AP Commit "bd0a14c99f65" enables the creation of a dedicated completion ring for asynchronous event handling instead of handling these events on a receive completion ring on non Stingray Platforms. This causes a segfault due to NULL pointer defreference in bnxt_alloc_async_cp_ring() on stingray. Fix this by checking the pointer validity before accessing it. Fixes: bd0a14c99f65 ("net/bnxt: use dedicated CPR for async events") Cc: stable@dpdk.org Signed-off-by: Kalesh AP Signed-off-by: Ajit Kumar Khaparde Reviewed-by: Rahul Gupta Reviewed-by: Lance Richardson --- drivers/net/bnxt/bnxt_ring.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c index 2f57e038a..ec17783cf 100644 --- a/drivers/net/bnxt/bnxt_ring.c +++ b/drivers/net/bnxt/bnxt_ring.c @@ -694,13 +694,15 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp) int bnxt_alloc_async_cp_ring(struct bnxt *bp) { struct bnxt_cp_ring_info *cpr = bp->async_cp_ring; - struct bnxt_ring *cp_ring = cpr->cp_ring_struct; + struct bnxt_ring *cp_ring; uint8_t ring_type; int rc; - if (BNXT_NUM_ASYNC_CPR(bp) == 0) + if (BNXT_NUM_ASYNC_CPR(bp) == 0 || cpr == NULL) return 0; + cp_ring = cpr->cp_ring_struct; + if (BNXT_HAS_NQ(bp)) ring_type = HWRM_RING_ALLOC_INPUT_RING_TYPE_NQ; else