The test found that when the SMMU is disabled, the driver may receive the following error packet: note: The memory is initialized to 0xfe, and 0xbf is what we expect. 00000440: bf bf bf bf bf bf bf bf bf bf bf bf bf bf bf bf 00000450: bf bf bf bf bf bf bf bf bf bf bf bf bf bf bf bf 00000460: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe 00000470: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe 00000480: bf bf bf bf bf bf bf bf bf bf bf bf bf bf bf bf 00000490: bf bf bf bf bf bf bf bf bf bf bf bf bf bf bf bf It seems that the packet is not completely written when the descriptor indicates that the packet is valid. According to the chip document, the chip writes packets first and then writes the descriptor. However, the actual sequence in which the packets and descriptor are written to the memory is incorrect. Each packet and descriptor of the hibmcge are in the same page. Therefore, when the Relaxed Ordering is enabled, the transactions for writing packets and writing descriptors may not be strictly ordered. As a result, the driver receives incorrect packets. Therefore, this patch disables the Relaxed Ordering to ensure the strict order of packets and descriptors. Additionally, during the process of analyzing the issue, it was discovered that the position of dma_rmb() was incorrect. It should first execute dma_sync_single_for_cpu(), and then dma_rmb(). This patch has also made the corresponding modifications. Fixes: f72e25594061 ("net: hibmcge: Implement rx_poll function to receive packets") Signed-off-by: Jijie Shao --- drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c | 4 +++- drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c index 068da2fd1fea..5b91b596349c 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_main.c @@ -420,6 +420,8 @@ static int hbg_pci_init(struct pci_dev *pdev) return -ENOMEM; pci_set_master(pdev); + pcie_capability_clear_word(pdev, PCI_EXP_DEVCTL, + PCI_EXP_DEVCTL_RELAX_EN); return 0; } @@ -525,4 +527,4 @@ module_exit(hbg_module_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Huawei Tech. Co., Ltd."); MODULE_DESCRIPTION("hibmcge driver"); -MODULE_VERSION("1.0"); +MODULE_VERSION("2.0"); diff --git a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c index a4ea92c31c2f..0ae314994676 100644 --- a/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c +++ b/drivers/net/ethernet/hisilicon/hibmcge/hbg_txrx.c @@ -452,12 +452,12 @@ static bool hbg_sync_data_from_hw(struct hbg_priv *priv, { struct hbg_rx_desc *rx_desc; - /* make sure HW write desc complete */ - dma_rmb(); - dma_sync_single_for_cpu(&priv->pdev->dev, buffer->page_dma, buffer->page_size, DMA_FROM_DEVICE); + /* make sure HW write desc complete */ + dma_rmb(); + rx_desc = (struct hbg_rx_desc *)buffer->page_addr; return FIELD_GET(HBG_RX_DESC_W2_PKT_LEN_M, rx_desc->word2) != 0; } -- 2.33.0