Commit f38f1ee8 authored by Dmitry Bogdanov's avatar Dmitry Bogdanov Committed by David S. Miller

net: aquantia: check rx csum for all packets in LRO session

Atlantic hardware does not aggregate nor breaks LRO sessions
with bad csum packets. This means driver should take care of that.

If in LRO session there is a non-first descriptor with invalid
checksum (L2/L3/L4), the driver must account this information
in csum application logic.

Fixes: 018423e9 ("net: ethernet: aquantia: Add ring support code")
Signed-off-by: default avatarIgor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: default avatarDmitry Bogdanov <dmitry.bogdanov@aquantia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 31bafc49
...@@ -299,35 +299,47 @@ int aq_ring_rx_clean(struct aq_ring_s *self, ...@@ -299,35 +299,47 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
unsigned int i = 0U; unsigned int i = 0U;
u16 hdr_len; u16 hdr_len;
if (buff->is_error)
continue;
if (buff->is_cleaned) if (buff->is_cleaned)
continue; continue;
if (!buff->is_eop) { if (!buff->is_eop) {
for (next_ = buff->next, buff_ = buff;
buff_ = &self->buff_ring[next_]; true; do {
next_ = buff_->next, next_ = buff_->next,
buff_ = &self->buff_ring[next_]) { buff_ = &self->buff_ring[next_];
is_rsc_completed = is_rsc_completed =
aq_ring_dx_in_range(self->sw_head, aq_ring_dx_in_range(self->sw_head,
next_, next_,
self->hw_head); self->hw_head);
if (unlikely(!is_rsc_completed)) { if (unlikely(!is_rsc_completed))
is_rsc_completed = false;
break; break;
}
if (buff_->is_eop) buff->is_error |= buff_->is_error;
break;
} } while (!buff_->is_eop);
if (!is_rsc_completed) { if (!is_rsc_completed) {
err = 0; err = 0;
goto err_exit; goto err_exit;
} }
if (buff->is_error) {
buff_ = buff;
do {
next_ = buff_->next,
buff_ = &self->buff_ring[next_];
buff_->is_cleaned = true;
} while (!buff_->is_eop);
++self->stats.rx.errors;
continue;
}
}
if (buff->is_error) {
++self->stats.rx.errors;
continue;
} }
dma_sync_single_range_for_cpu(aq_nic_get_dev(self->aq_nic), dma_sync_single_range_for_cpu(aq_nic_get_dev(self->aq_nic),
...@@ -390,6 +402,12 @@ int aq_ring_rx_clean(struct aq_ring_s *self, ...@@ -390,6 +402,12 @@ int aq_ring_rx_clean(struct aq_ring_s *self,
AQ_CFG_RX_FRAME_MAX); AQ_CFG_RX_FRAME_MAX);
page_ref_inc(buff_->rxdata.page); page_ref_inc(buff_->rxdata.page);
buff_->is_cleaned = 1; buff_->is_cleaned = 1;
buff->is_ip_cso &= buff_->is_ip_cso;
buff->is_udp_cso &= buff_->is_udp_cso;
buff->is_tcp_cso &= buff_->is_tcp_cso;
buff->is_cso_err |= buff_->is_cso_err;
} while (!buff_->is_eop); } while (!buff_->is_eop);
} }
} }
......
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