net: aquantia: fix LRO with FCS error
Driver stops producing skbs on ring if a packet with FCS error
was coalesced into LRO session. Ring gets hang forever.
Thats a logical error in driver processing descriptors:
When rx_stat indicates MAC Error, next pointer and eop flags
are not filled. This confuses driver so it waits for descriptor 0
to be filled by HW.
Solution is fill next pointer and eop flag even for packets with FCS error.
Fixes: bab6de8fd1
("net: ethernet: aquantia: Atlantic A0 and B0 specific functions.")
Signed-off-by: Igor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: Dmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
f38f1ee8ae
commit
eaeb3b7494
|
@ -713,38 +713,41 @@ static int hw_atl_b0_hw_ring_rx_receive(struct aq_hw_s *self,
|
|||
if ((rx_stat & BIT(0)) || rxd_wb->type & 0x1000U) {
|
||||
/* MAC error or DMA error */
|
||||
buff->is_error = 1U;
|
||||
} else {
|
||||
if (self->aq_nic_cfg->is_rss) {
|
||||
/* last 4 byte */
|
||||
u16 rss_type = rxd_wb->type & 0xFU;
|
||||
}
|
||||
if (self->aq_nic_cfg->is_rss) {
|
||||
/* last 4 byte */
|
||||
u16 rss_type = rxd_wb->type & 0xFU;
|
||||
|
||||
if (rss_type && rss_type < 0x8U) {
|
||||
buff->is_hash_l4 = (rss_type == 0x4 ||
|
||||
rss_type == 0x5);
|
||||
buff->rss_hash = rxd_wb->rss_hash;
|
||||
}
|
||||
if (rss_type && rss_type < 0x8U) {
|
||||
buff->is_hash_l4 = (rss_type == 0x4 ||
|
||||
rss_type == 0x5);
|
||||
buff->rss_hash = rxd_wb->rss_hash;
|
||||
}
|
||||
}
|
||||
|
||||
if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
|
||||
buff->len = rxd_wb->pkt_len %
|
||||
AQ_CFG_RX_FRAME_MAX;
|
||||
buff->len = buff->len ?
|
||||
buff->len : AQ_CFG_RX_FRAME_MAX;
|
||||
buff->next = 0U;
|
||||
buff->is_eop = 1U;
|
||||
if (HW_ATL_B0_RXD_WB_STAT2_EOP & rxd_wb->status) {
|
||||
buff->len = rxd_wb->pkt_len %
|
||||
AQ_CFG_RX_FRAME_MAX;
|
||||
buff->len = buff->len ?
|
||||
buff->len : AQ_CFG_RX_FRAME_MAX;
|
||||
buff->next = 0U;
|
||||
buff->is_eop = 1U;
|
||||
} else {
|
||||
buff->len =
|
||||
rxd_wb->pkt_len > AQ_CFG_RX_FRAME_MAX ?
|
||||
AQ_CFG_RX_FRAME_MAX : rxd_wb->pkt_len;
|
||||
|
||||
if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
|
||||
rxd_wb->status) {
|
||||
/* LRO */
|
||||
buff->next = rxd_wb->next_desc_ptr;
|
||||
++ring->stats.rx.lro_packets;
|
||||
} else {
|
||||
if (HW_ATL_B0_RXD_WB_STAT2_RSCCNT &
|
||||
rxd_wb->status) {
|
||||
/* LRO */
|
||||
buff->next = rxd_wb->next_desc_ptr;
|
||||
++ring->stats.rx.lro_packets;
|
||||
} else {
|
||||
/* jumbo */
|
||||
buff->next =
|
||||
aq_ring_next_dx(ring,
|
||||
ring->hw_head);
|
||||
++ring->stats.rx.jumbo_packets;
|
||||
}
|
||||
/* jumbo */
|
||||
buff->next =
|
||||
aq_ring_next_dx(ring,
|
||||
ring->hw_head);
|
||||
++ring->stats.rx.jumbo_packets;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue