From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2049AA04AD for ; Tue, 8 Feb 2022 11:05:16 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1718741154; Tue, 8 Feb 2022 11:05:14 +0100 (CET) Received: from smtpbgau1.qq.com (smtpbgau1.qq.com [54.206.16.166]) by mails.dpdk.org (Postfix) with ESMTP id E6DAA41154 for ; Tue, 8 Feb 2022 11:05:10 +0100 (CET) X-QQ-mid: bizesmtp46t1644314703ts763cbv Received: from wxdbg.localdomain.com (unknown [183.129.236.74]) by bizesmtp.qq.com (ESMTP) with id ; Tue, 08 Feb 2022 18:05:02 +0800 (CST) X-QQ-SSF: 01400000002000F0L000B00A0000000 X-QQ-FEAT: Lg5IqoGaTUjXFxakUhb4TI2M/tbcndf2cbswOaK0VLXFWvEe6pLU286jWlQoi FEp6YZu6kTAbE7rhVfcJHnMPE7OciKeaXHaa3w5ge15oG2HLYeYqqueVE22Q/+dcnF9c6X6 030SiJtCebSl8OROqkUCEBou7EfrTU1uA5bAhcaKBXva7sYJ9ruW5MjKinbwr/3JA7UaVK9 qgwe/I24/Zzei3BmqaOQgz7MemhdJ3aggSn/as0s7I/HIf3pnTeefVZmQRKhXb29UdLl/jJ xX4fhwvyX75Ek+/E7IveuA++R6Jgk3nSwGSxq8r+yWtR5k9f8bAyyGDIofStRc/wOtGpL6f cUXpyzGNL99jOSd0oD1AWf3GA0IxvzGNuiAACQ2 X-QQ-GoodBg: 2 From: Jiawen Wu To: dev@dpdk.org Cc: Jiawen Wu , stable@dpdk.org Subject: [PATCH 3/9] net/ngbe: fix Tx pending Date: Tue, 8 Feb 2022 18:11:23 +0800 Message-Id: <20220208101129.69173-4-jiawenwu@trustnetic.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220208101129.69173-1-jiawenwu@trustnetic.com> References: <20220208101129.69173-1-jiawenwu@trustnetic.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-QQ-SENDSIZE: 520 Feedback-ID: bizesmtp:trustnetic.com:qybgforeign:qybgforeign2 X-QQ-Bgrelay: 1 X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Add commands requesting firmware to enable or disable PCIe bus master. Disable PCIe master access to clear BME when stop hardware, and verify there are no pending requests. Fixes: 78710873c2f3 ("net/ngbe: add HW initialization") Cc: stable@dpdk.org Signed-off-by: Jiawen Wu --- drivers/net/ngbe/base/ngbe_hw.c | 76 +++++++++++++++++++++++++++---- drivers/net/ngbe/base/ngbe_hw.h | 1 + drivers/net/ngbe/base/ngbe_mng.c | 57 +++++++++++++++++++++++ drivers/net/ngbe/base/ngbe_mng.h | 21 +++++++++ drivers/net/ngbe/base/ngbe_regs.h | 3 ++ drivers/net/ngbe/base/ngbe_type.h | 3 ++ drivers/net/ngbe/ngbe_ethdev.c | 7 ++- 7 files changed, 158 insertions(+), 10 deletions(-) diff --git a/drivers/net/ngbe/base/ngbe_hw.c b/drivers/net/ngbe/base/ngbe_hw.c index 0b22ea0fb3..782fd71d29 100644 --- a/drivers/net/ngbe/base/ngbe_hw.c +++ b/drivers/net/ngbe/base/ngbe_hw.c @@ -350,8 +350,8 @@ void ngbe_set_lan_id_multi_port(struct ngbe_hw *hw) **/ s32 ngbe_stop_hw(struct ngbe_hw *hw) { - u32 reg_val; u16 i; + s32 status = 0; DEBUGFUNC("ngbe_stop_hw"); @@ -372,16 +372,27 @@ s32 ngbe_stop_hw(struct ngbe_hw *hw) wr32(hw, NGBE_ICRMISC, NGBE_ICRMISC_MASK); wr32(hw, NGBE_ICR(0), NGBE_ICR_MASK); - /* Disable the transmit unit. Each queue must be disabled. */ - for (i = 0; i < hw->mac.max_tx_queues; i++) - wr32(hw, NGBE_TXCFG(i), NGBE_TXCFG_FLUSH); + wr32(hw, NGBE_BMECTL, 0x3); /* Disable the receive unit by stopping each queue */ - for (i = 0; i < hw->mac.max_rx_queues; i++) { - reg_val = rd32(hw, NGBE_RXCFG(i)); - reg_val &= ~NGBE_RXCFG_ENA; - wr32(hw, NGBE_RXCFG(i), reg_val); - } + for (i = 0; i < hw->mac.max_rx_queues; i++) + wr32(hw, NGBE_RXCFG(i), 0); + + /* flush all queues disables */ + ngbe_flush(hw); + msec_delay(2); + + /* + * Prevent the PCI-E bus from hanging by disabling PCI-E master + * access and verify no pending requests + */ + status = ngbe_set_pcie_master(hw, false); + if (status) + return status; + + /* Disable the transmit unit. Each queue must be disabled. */ + for (i = 0; i < hw->mac.max_tx_queues; i++) + wr32(hw, NGBE_TXCFG(i), 0); /* flush all queues disables */ ngbe_flush(hw); @@ -1076,6 +1087,53 @@ void ngbe_fc_autoneg(struct ngbe_hw *hw) } } +/** + * ngbe_set_pcie_master - Disable or Enable PCI-express master access + * @hw: pointer to hardware structure + * + * Disables PCI-Express master access and verifies there are no pending + * requests. NGBE_ERR_MASTER_REQUESTS_PENDING is returned if master disable + * bit hasn't caused the master requests to be disabled, else 0 + * is returned signifying master requests disabled. + **/ +s32 ngbe_set_pcie_master(struct ngbe_hw *hw, bool enable) +{ + s32 status = 0; + u16 addr = 0x04; + u32 data, i; + + DEBUGFUNC("ngbe_set_pcie_master"); + + ngbe_hic_pcie_read(hw, addr, &data, 4); + if (enable) + data |= 0x04; + else + data &= ~0x04; + + ngbe_hic_pcie_write(hw, addr, &data, 4); + + if (enable) + goto out; + + /* Exit if master requests are blocked */ + if (!(rd32(hw, NGBE_BMEPEND)) || + NGBE_REMOVED(hw->hw_addr)) + goto out; + + /* Poll for master request bit to clear */ + for (i = 0; i < NGBE_PCI_MASTER_DISABLE_TIMEOUT; i++) { + usec_delay(100); + if (!(rd32(hw, NGBE_BMEPEND))) + goto out; + } + + DEBUGOUT("PCIe transaction pending bit also did not clear.\n"); + status = NGBE_ERR_MASTER_REQUESTS_PENDING; + +out: + return status; +} + /** * ngbe_acquire_swfw_sync - Acquire SWFW semaphore * @hw: pointer to hardware structure diff --git a/drivers/net/ngbe/base/ngbe_hw.h b/drivers/net/ngbe/base/ngbe_hw.h index b32cf87ff4..7e0e23b195 100644 --- a/drivers/net/ngbe/base/ngbe_hw.h +++ b/drivers/net/ngbe/base/ngbe_hw.h @@ -54,6 +54,7 @@ void ngbe_fc_autoneg(struct ngbe_hw *hw); s32 ngbe_validate_mac_addr(u8 *mac_addr); s32 ngbe_acquire_swfw_sync(struct ngbe_hw *hw, u32 mask); void ngbe_release_swfw_sync(struct ngbe_hw *hw, u32 mask); +s32 ngbe_set_pcie_master(struct ngbe_hw *hw, bool enable); s32 ngbe_set_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq); s32 ngbe_clear_vmdq(struct ngbe_hw *hw, u32 rar, u32 vmdq); diff --git a/drivers/net/ngbe/base/ngbe_mng.c b/drivers/net/ngbe/base/ngbe_mng.c index a3dd8093ce..68e06e2c24 100644 --- a/drivers/net/ngbe/base/ngbe_mng.c +++ b/drivers/net/ngbe/base/ngbe_mng.c @@ -243,6 +243,63 @@ s32 ngbe_hic_sr_write(struct ngbe_hw *hw, u32 addr, u8 *buf, int len) return err; } +s32 ngbe_hic_pcie_read(struct ngbe_hw *hw, u16 addr, u32 *buf, int len) +{ + struct ngbe_hic_read_pcie command; + u32 value = 0; + int err, i = 0; + + if (len > NGBE_PMMBX_DATA_SIZE) + return NGBE_ERR_HOST_INTERFACE_COMMAND; + + memset(&command, 0, sizeof(command)); + command.hdr.cmd = FW_PCIE_READ_CMD; + command.hdr.buf_len = sizeof(command) - sizeof(command.hdr); + command.hdr.checksum = FW_DEFAULT_CHECKSUM; + command.lan_id = hw->bus.lan_id; + command.addr = addr; + + err = ngbe_host_interface_command(hw, (u32 *)&command, + sizeof(command), NGBE_HI_COMMAND_TIMEOUT, false); + if (err) + return err; + + while (i < (len >> 2)) { + value = rd32a(hw, NGBE_MNGMBX, FW_PCIE_BUSMASTER_OFFSET + i); + ((u32 *)buf)[i] = value; + i++; + } + + return 0; +} + +s32 ngbe_hic_pcie_write(struct ngbe_hw *hw, u16 addr, u32 *buf, int len) +{ + struct ngbe_hic_write_pcie command; + u32 value = 0; + int err, i = 0; + + while (i < (len >> 2)) { + value = ((u32 *)buf)[i]; + i++; + } + + memset(&command, 0, sizeof(command)); + command.hdr.cmd = FW_PCIE_WRITE_CMD; + command.hdr.buf_len = sizeof(command) - sizeof(command.hdr); + command.hdr.checksum = FW_DEFAULT_CHECKSUM; + command.lan_id = hw->bus.lan_id; + command.addr = addr; + command.data = value; + + err = ngbe_host_interface_command(hw, (u32 *)&command, + sizeof(command), NGBE_HI_COMMAND_TIMEOUT, false); + if (err) + return err; + + return 0; +} + s32 ngbe_hic_check_cap(struct ngbe_hw *hw) { struct ngbe_hic_read_shadow_ram command; diff --git a/drivers/net/ngbe/base/ngbe_mng.h b/drivers/net/ngbe/base/ngbe_mng.h index e3d0309cbc..321338a051 100644 --- a/drivers/net/ngbe/base/ngbe_mng.h +++ b/drivers/net/ngbe/base/ngbe_mng.h @@ -20,6 +20,9 @@ #define FW_READ_SHADOW_RAM_LEN 0x6 #define FW_WRITE_SHADOW_RAM_CMD 0x33 #define FW_WRITE_SHADOW_RAM_LEN 0xA /* 8 plus 1 WORD to write */ +#define FW_PCIE_READ_CMD 0xEC +#define FW_PCIE_WRITE_CMD 0xED +#define FW_PCIE_BUSMASTER_OFFSET 2 #define FW_DEFAULT_CHECKSUM 0xFF /* checksum always 0xFF */ #define FW_NVM_DATA_OFFSET 3 #define FW_EEPROM_CHECK_STATUS 0xE9 @@ -76,8 +79,26 @@ struct ngbe_hic_write_shadow_ram { u16 pad3; }; +struct ngbe_hic_read_pcie { + struct ngbe_hic_hdr hdr; + u8 lan_id; + u8 rsvd; + u16 addr; + u32 data; +}; + +struct ngbe_hic_write_pcie { + struct ngbe_hic_hdr hdr; + u8 lan_id; + u8 rsvd; + u16 addr; + u32 data; +}; + s32 ngbe_hic_sr_read(struct ngbe_hw *hw, u32 addr, u8 *buf, int len); s32 ngbe_hic_sr_write(struct ngbe_hw *hw, u32 addr, u8 *buf, int len); +s32 ngbe_hic_pcie_read(struct ngbe_hw *hw, u16 addr, u32 *buf, int len); +s32 ngbe_hic_pcie_write(struct ngbe_hw *hw, u16 addr, u32 *buf, int len); s32 ngbe_hic_check_cap(struct ngbe_hw *hw); #endif /* _NGBE_MNG_H_ */ diff --git a/drivers/net/ngbe/base/ngbe_regs.h b/drivers/net/ngbe/base/ngbe_regs.h index 872b008c46..e84bfdf88a 100644 --- a/drivers/net/ngbe/base/ngbe_regs.h +++ b/drivers/net/ngbe/base/ngbe_regs.h @@ -866,6 +866,9 @@ enum ngbe_5tuple_protocol { * PF(Physical Function) Registers ******************************************************************************/ /* Interrupt */ +#define NGBE_BMECTL 0x012020 +#define NGBE_BMECTL_VFDRP MS(1, 0x1) +#define NGBE_BMECTL_PFDRP MS(0, 0x1) #define NGBE_ICRMISC 0x000100 #define NGBE_ICRMISC_MASK MS(8, 0xFFFFFF) #define NGBE_ICRMISC_RST MS(10, 0x1) /* device reset event */ diff --git a/drivers/net/ngbe/base/ngbe_type.h b/drivers/net/ngbe/base/ngbe_type.h index 269e087d50..4c995e7397 100644 --- a/drivers/net/ngbe/base/ngbe_type.h +++ b/drivers/net/ngbe/base/ngbe_type.h @@ -17,6 +17,9 @@ #define NGBE_MAX_QP (8) #define NGBE_MAX_UTA 128 +#define NGBE_PCI_MASTER_DISABLE_TIMEOUT 800 + + #define NGBE_ALIGN 128 /* as intel did */ #define NGBE_ISB_SIZE 16 diff --git a/drivers/net/ngbe/ngbe_ethdev.c b/drivers/net/ngbe/ngbe_ethdev.c index 8e31234442..30c9e68579 100644 --- a/drivers/net/ngbe/ngbe_ethdev.c +++ b/drivers/net/ngbe/ngbe_ethdev.c @@ -950,7 +950,6 @@ ngbe_dev_start(struct rte_eth_dev *dev) /* stop adapter */ hw->adapter_stopped = 0; - ngbe_stop_hw(hw); /* reinitialize adapter, this calls reset and start */ hw->nb_rx_queues = dev->data->nb_rx_queues; @@ -961,6 +960,8 @@ ngbe_dev_start(struct rte_eth_dev *dev) hw->mac.start_hw(hw); hw->mac.get_link_status = true; + ngbe_set_pcie_master(hw, true); + /* configure PF module if SRIOV enabled */ ngbe_pf_host_configure(dev); @@ -1174,6 +1175,8 @@ ngbe_dev_stop(struct rte_eth_dev *dev) rte_intr_efd_disable(intr_handle); rte_intr_vec_list_free(intr_handle); + ngbe_set_pcie_master(hw, true); + adapter->rss_reta_updated = 0; hw->adapter_stopped = true; @@ -1202,6 +1205,8 @@ ngbe_dev_close(struct rte_eth_dev *dev) ngbe_dev_free_queues(dev); + ngbe_set_pcie_master(hw, false); + /* reprogram the RAR[0] in case user changed it. */ ngbe_set_rar(hw, 0, hw->mac.addr, 0, true); -- 2.21.0.windows.1