]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: hns3: fix for miscalculation of rx unused desc
authorYunsheng Lin <linyunsheng@huawei.com>
Tue, 19 Oct 2021 14:16:32 +0000 (22:16 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 20 Oct 2021 10:38:11 +0000 (11:38 +0100)
rx unused desc is the desc that need attatching new buffer
before refilling to hw to receive new packet, the number of
desc need attatching new buffer is calculated using next_to_use
and next_to_clean. when next_to_use == next_to_clean, currently
hns3 driver assumes that all the desc has the buffer attatched,
but 'next_to_use == next_to_clean' also means all the desc need
attatching new buffer if hw has comsumed all the desc and the
driver has not attatched any buffer to the desc yet.

This patch adds 'refill' in desc_cb to indicate whether a new
buffer has been refilled to a desc.

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

index ea89772e8952e1ad6bcaaad0c5e571649d09ca3f..2ecc9abc02d6be7d1e87dcff2ae065f835b0d74e 100644 (file)
@@ -3255,6 +3255,7 @@ static void hns3_buffer_detach(struct hns3_enet_ring *ring, int i)
 {
        hns3_unmap_buffer(ring, &ring->desc_cb[i]);
        ring->desc[i].addr = 0;
+       ring->desc_cb[i].refill = 0;
 }
 
 static void hns3_free_buffer_detach(struct hns3_enet_ring *ring, int i,
@@ -3333,6 +3334,7 @@ static int hns3_alloc_and_attach_buffer(struct hns3_enet_ring *ring, int i)
 
        ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
                                         ring->desc_cb[i].page_offset);
+       ring->desc_cb[i].refill = 1;
 
        return 0;
 }
@@ -3362,6 +3364,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i,
 {
        hns3_unmap_buffer(ring, &ring->desc_cb[i]);
        ring->desc_cb[i] = *res_cb;
+       ring->desc_cb[i].refill = 1;
        ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
                                         ring->desc_cb[i].page_offset);
        ring->desc[i].rx.bd_base_info = 0;
@@ -3370,6 +3373,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i,
 static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i)
 {
        ring->desc_cb[i].reuse_flag = 0;
+       ring->desc_cb[i].refill = 1;
        ring->desc[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
                                         ring->desc_cb[i].page_offset);
        ring->desc[i].rx.bd_base_info = 0;
@@ -3476,6 +3480,9 @@ static int hns3_desc_unused(struct hns3_enet_ring *ring)
        int ntc = ring->next_to_clean;
        int ntu = ring->next_to_use;
 
+       if (unlikely(ntc == ntu && !ring->desc_cb[ntc].refill))
+               return ring->desc_num;
+
        return ((ntc >= ntu) ? 0 : ring->desc_num) + ntc - ntu;
 }
 
@@ -3821,6 +3828,7 @@ static void hns3_rx_ring_move_fw(struct hns3_enet_ring *ring)
 {
        ring->desc[ring->next_to_clean].rx.bd_base_info &=
                cpu_to_le32(~BIT(HNS3_RXD_VLD_B));
+       ring->desc_cb[ring->next_to_clean].refill = 0;
        ring->next_to_clean += 1;
 
        if (unlikely(ring->next_to_clean == ring->desc_num))
index 9d9be3665bb1f6de06516de114a2d47709758c90..f09a61d9c6264e75e2a33ba5f49602d59caefd09 100644 (file)
@@ -330,6 +330,7 @@ struct hns3_desc_cb {
        u32 length;     /* length of the buffer */
 
        u16 reuse_flag;
+       u16 refill;
 
        /* desc type, used by the ring user to mark the type of the priv data */
        u16 type;