Commit 9f9f0f19 authored by Yunsheng Lin's avatar Yunsheng Lin Committed by David S. Miller

net: hns3: fix for miscalculation of rx unused desc

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: 76ad4f0e ("net: hns3: Add support of HNS3 Ethernet Driver for hip08 SoC")
Signed-off-by: default avatarYunsheng Lin <linyunsheng@huawei.com>
Signed-off-by: default avatarGuangbin Huang <huangguangbin2@huawei.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent adfb7b49
...@@ -3255,6 +3255,7 @@ static void hns3_buffer_detach(struct hns3_enet_ring *ring, int i) ...@@ -3255,6 +3255,7 @@ static void hns3_buffer_detach(struct hns3_enet_ring *ring, int i)
{ {
hns3_unmap_buffer(ring, &ring->desc_cb[i]); hns3_unmap_buffer(ring, &ring->desc_cb[i]);
ring->desc[i].addr = 0; ring->desc[i].addr = 0;
ring->desc_cb[i].refill = 0;
} }
static void hns3_free_buffer_detach(struct hns3_enet_ring *ring, int i, 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) ...@@ -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[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
ring->desc_cb[i].page_offset); ring->desc_cb[i].page_offset);
ring->desc_cb[i].refill = 1;
return 0; return 0;
} }
...@@ -3362,6 +3364,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i, ...@@ -3362,6 +3364,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i,
{ {
hns3_unmap_buffer(ring, &ring->desc_cb[i]); hns3_unmap_buffer(ring, &ring->desc_cb[i]);
ring->desc_cb[i] = *res_cb; 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[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
ring->desc_cb[i].page_offset); ring->desc_cb[i].page_offset);
ring->desc[i].rx.bd_base_info = 0; ring->desc[i].rx.bd_base_info = 0;
...@@ -3370,6 +3373,7 @@ static void hns3_replace_buffer(struct hns3_enet_ring *ring, int i, ...@@ -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) static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i)
{ {
ring->desc_cb[i].reuse_flag = 0; 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[i].addr = cpu_to_le64(ring->desc_cb[i].dma +
ring->desc_cb[i].page_offset); ring->desc_cb[i].page_offset);
ring->desc[i].rx.bd_base_info = 0; ring->desc[i].rx.bd_base_info = 0;
...@@ -3476,6 +3480,9 @@ static int hns3_desc_unused(struct hns3_enet_ring *ring) ...@@ -3476,6 +3480,9 @@ static int hns3_desc_unused(struct hns3_enet_ring *ring)
int ntc = ring->next_to_clean; int ntc = ring->next_to_clean;
int ntu = ring->next_to_use; 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; 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) ...@@ -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 &= ring->desc[ring->next_to_clean].rx.bd_base_info &=
cpu_to_le32(~BIT(HNS3_RXD_VLD_B)); cpu_to_le32(~BIT(HNS3_RXD_VLD_B));
ring->desc_cb[ring->next_to_clean].refill = 0;
ring->next_to_clean += 1; ring->next_to_clean += 1;
if (unlikely(ring->next_to_clean == ring->desc_num)) if (unlikely(ring->next_to_clean == ring->desc_num))
......
...@@ -330,6 +330,7 @@ struct hns3_desc_cb { ...@@ -330,6 +330,7 @@ struct hns3_desc_cb {
u32 length; /* length of the buffer */ u32 length; /* length of the buffer */
u16 reuse_flag; u16 reuse_flag;
u16 refill;
/* desc type, used by the ring user to mark the type of the priv data */ /* desc type, used by the ring user to mark the type of the priv data */
u16 type; u16 type;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment