From: Jiawen Wu <jiawenwu@trustnetic.com>
To: dev@dpdk.org
Cc: Jiawen Wu <jiawenwu@trustnetic.com>, stable@dpdk.org
Subject: [PATCH 3/9] net/ngbe: fix Tx pending
Date: Tue, 8 Feb 2022 18:11:23 +0800 [thread overview]
Message-ID: <20220208101129.69173-4-jiawenwu@trustnetic.com> (raw)
In-Reply-To: <20220208101129.69173-1-jiawenwu@trustnetic.com>
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 <jiawenwu@trustnetic.com>
---
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
next prev parent reply other threads:[~2022-02-08 10:05 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20220208101129.69173-1-jiawenwu@trustnetic.com>
2022-02-08 10:11 ` [PATCH 1/9] net/ngbe: fix failed to receive packets Jiawen Wu
2022-02-08 10:11 ` [PATCH 2/9] net/ngbe: fix link interrupt sometimes lost Jiawen Wu
2022-02-08 10:11 ` Jiawen Wu [this message]
2022-02-08 17:38 ` [PATCH 3/9] net/ngbe: fix Tx pending Ferruh Yigit
2022-02-08 10:11 ` [PATCH 4/9] net/ngbe: fix RxTx packet statistics Jiawen Wu
2022-02-08 17:38 ` Ferruh Yigit
2022-02-08 10:11 ` [PATCH 8/9] net/txgbe: fix to set link up and down Jiawen Wu
2022-02-08 10:11 ` [PATCH 9/9] net/txgbe: fix KR auto-negotiation Jiawen Wu
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220208101129.69173-4-jiawenwu@trustnetic.com \
--to=jiawenwu@trustnetic.com \
--cc=dev@dpdk.org \
--cc=stable@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).