From: Yunsheng Lin <linyunsh...@huawei.com>

[ Upstream commit 2e9361efa707e186d91b938e44f9e326725259f7 ]

If SMMU is on, there is more likely that skb_shinfo(skb)->frags[i]
can not send by a single BD. when this happen, the
hns_nic_net_xmit_hw function map the whole data in a frags using
skb_frag_dma_map, but unmap each BD' data individually when tx is
done, which causes problem when SMMU is on.

This patch fixes this problem by ummapping the whole data in a
frags when tx is done.

Signed-off-by: Yunsheng Lin <linyunsh...@huawei.com>
Signed-off-by: Peng Li <lipeng...@huawei.com>
Reviewed-by: Yisen Zhuang <yisen.zhu...@huawei.com>
Signed-off-by: Salil Mehta <salil.me...@huawei.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/net/ethernet/hisilicon/hns/hnae.c     |  2 +-
 drivers/net/ethernet/hisilicon/hns/hns_enet.c | 30 ++++++++++++-------
 2 files changed, 20 insertions(+), 12 deletions(-)

diff --git a/drivers/net/ethernet/hisilicon/hns/hnae.c 
b/drivers/net/ethernet/hisilicon/hns/hnae.c
index a051e582d541..79d03f8ee7b1 100644
--- a/drivers/net/ethernet/hisilicon/hns/hnae.c
+++ b/drivers/net/ethernet/hisilicon/hns/hnae.c
@@ -84,7 +84,7 @@ static void hnae_unmap_buffer(struct hnae_ring *ring, struct 
hnae_desc_cb *cb)
        if (cb->type == DESC_TYPE_SKB)
                dma_unmap_single(ring_to_dev(ring), cb->dma, cb->length,
                                 ring_to_dma_dir(ring));
-       else
+       else if (cb->length)
                dma_unmap_page(ring_to_dev(ring), cb->dma, cb->length,
                               ring_to_dma_dir(ring));
 }
diff --git a/drivers/net/ethernet/hisilicon/hns/hns_enet.c 
b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
index b4518f45f048..1336ec73230d 100644
--- a/drivers/net/ethernet/hisilicon/hns/hns_enet.c
+++ b/drivers/net/ethernet/hisilicon/hns/hns_enet.c
@@ -40,9 +40,9 @@
 #define SKB_TMP_LEN(SKB) \
        (((SKB)->transport_header - (SKB)->mac_header) + tcp_hdrlen(SKB))
 
-static void fill_v2_desc(struct hnae_ring *ring, void *priv,
-                        int size, dma_addr_t dma, int frag_end,
-                        int buf_num, enum hns_desc_type type, int mtu)
+static void fill_v2_desc_hw(struct hnae_ring *ring, void *priv, int size,
+                           int send_sz, dma_addr_t dma, int frag_end,
+                           int buf_num, enum hns_desc_type type, int mtu)
 {
        struct hnae_desc *desc = &ring->desc[ring->next_to_use];
        struct hnae_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use];
@@ -64,7 +64,7 @@ static void fill_v2_desc(struct hnae_ring *ring, void *priv,
        desc_cb->type = type;
 
        desc->addr = cpu_to_le64(dma);
-       desc->tx.send_size = cpu_to_le16((u16)size);
+       desc->tx.send_size = cpu_to_le16((u16)send_sz);
 
        /* config bd buffer end */
        hnae_set_bit(rrcfv, HNSV2_TXD_VLD_B, 1);
@@ -133,6 +133,14 @@ static void fill_v2_desc(struct hnae_ring *ring, void 
*priv,
        ring_ptr_move_fw(ring, next_to_use);
 }
 
+static void fill_v2_desc(struct hnae_ring *ring, void *priv,
+                        int size, dma_addr_t dma, int frag_end,
+                        int buf_num, enum hns_desc_type type, int mtu)
+{
+       fill_v2_desc_hw(ring, priv, size, size, dma, frag_end,
+                       buf_num, type, mtu);
+}
+
 static const struct acpi_device_id hns_enet_acpi_match[] = {
        { "HISI00C1", 0 },
        { "HISI00C2", 0 },
@@ -289,15 +297,15 @@ static void fill_tso_desc(struct hnae_ring *ring, void 
*priv,
 
        /* when the frag size is bigger than hardware, split this frag */
        for (k = 0; k < frag_buf_num; k++)
-               fill_v2_desc(ring, priv,
-                            (k == frag_buf_num - 1) ?
+               fill_v2_desc_hw(ring, priv, k == 0 ? size : 0,
+                               (k == frag_buf_num - 1) ?
                                        sizeoflast : BD_MAX_SEND_SIZE,
-                            dma + BD_MAX_SEND_SIZE * k,
-                            frag_end && (k == frag_buf_num - 1) ? 1 : 0,
-                            buf_num,
-                            (type == DESC_TYPE_SKB && !k) ?
+                               dma + BD_MAX_SEND_SIZE * k,
+                               frag_end && (k == frag_buf_num - 1) ? 1 : 0,
+                               buf_num,
+                               (type == DESC_TYPE_SKB && !k) ?
                                        DESC_TYPE_SKB : DESC_TYPE_PAGE,
-                            mtu);
+                               mtu);
 }
 
 netdev_tx_t hns_nic_net_xmit_hw(struct net_device *ndev,
-- 
2.17.1

Reply via email to