]> git.itanic.dy.fi Git - linux-stable/commitdiff
net: hns3: fix error handling for desc filling
authorYunsheng Lin <linyunsheng@huawei.com>
Tue, 21 Jul 2020 11:03:53 +0000 (19:03 +0800)
committerDavid S. Miller <davem@davemloft.net>
Tue, 21 Jul 2020 22:49:17 +0000 (15:49 -0700)
The content of the TX desc is automatically cleared by the HW
when the HW has sent out the packet to the wire. When desc filling
fails in hns3_nic_net_xmit(), it will call hns3_clear_desc() to do
the error handling, which miss zeroing of the TX desc and the
checking if a unmapping is needed.

So add the zeroing and checking in hns3_clear_desc() to avoid the
above problem. Also add DESC_TYPE_UNKNOWN to indicate the info in
desc_cb is not valid, because hns3_nic_reclaim_desc() may treat
the desc_cb->type of zero as packet and add to the sent pkt
statistics accordingly.

Fixes: 76ad4f0ee747 ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/hisilicon/hns3/hnae3.h
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c

index d041cac9a487a842b59acd3c49034c5e7b2246c7..088550db2de78e056255c5eb820f835b788431a2 100644 (file)
@@ -77,6 +77,7 @@
        ((ring)->p = ((ring)->p - 1 + (ring)->desc_num) % (ring)->desc_num)
 
 enum hns_desc_type {
+       DESC_TYPE_UNKNOWN,
        DESC_TYPE_SKB,
        DESC_TYPE_FRAGLIST_SKB,
        DESC_TYPE_PAGE,
index a8a5112a578c74ac7cc7468b02a977ec15013c5e..33c481d11116a7793c3e4e9374cfcd9fd8999ce7 100644 (file)
@@ -1338,6 +1338,10 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
        unsigned int i;
 
        for (i = 0; i < ring->desc_num; i++) {
+               struct hns3_desc *desc = &ring->desc[ring->next_to_use];
+
+               memset(desc, 0, sizeof(*desc));
+
                /* check if this is where we started */
                if (ring->next_to_use == next_to_use_orig)
                        break;
@@ -1345,6 +1349,9 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
                /* rollback one */
                ring_ptr_move_bw(ring, next_to_use);
 
+               if (!ring->desc_cb[ring->next_to_use].dma)
+                       continue;
+
                /* unmap the descriptor dma address */
                if (ring->desc_cb[ring->next_to_use].type == DESC_TYPE_SKB ||
                    ring->desc_cb[ring->next_to_use].type ==
@@ -1361,6 +1368,7 @@ static void hns3_clear_desc(struct hns3_enet_ring *ring, int next_to_use_orig)
 
                ring->desc_cb[ring->next_to_use].length = 0;
                ring->desc_cb[ring->next_to_use].dma = 0;
+               ring->desc_cb[ring->next_to_use].type = DESC_TYPE_UNKNOWN;
        }
 }