diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c index e9c6f1fa0b1a7a108a08950169c29b7c18c99a37..673724efb05f83bebf2490312f5ffb7769dceb48 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.c @@ -286,8 +286,8 @@ bool aq_ring_tx_clean(struct aq_ring_s *self) if (!buff->is_eop && buff->eop_index != 0xffffU && (!aq_ring_dx_in_range(self->sw_head, - buff->eop_index, - self->hw_head))) + buff->eop_index, + self->hw_head))) break; dma_unmap_single(dev, buff->pa, buff->len, @@ -314,6 +314,33 @@ bool aq_ring_tx_clean(struct aq_ring_s *self) return !!budget; } +void aq_ring_tx_deinit(struct aq_ring_s *self) +{ + if (!self) + return; + + for (; self->sw_head != self->sw_tail; + self->sw_head = aq_ring_next_dx(self, self->sw_head)) { + struct aq_ring_buff_s *buff = &self->buff_ring[self->sw_head]; + struct device *ndev = aq_nic_get_dev(self->aq_nic); + + if (buff->is_mapped) { + if (buff->is_sop) { + dma_unmap_single(ndev, buff->pa, buff->len, + DMA_TO_DEVICE); + } else { + dma_unmap_page(ndev, buff->pa, buff->len, + DMA_TO_DEVICE); + } + } + + if (buff->is_eop) { + if (buff->skb) + dev_kfree_skb_any(buff->skb); + } + } +} + static void aq_rx_checksum(struct aq_ring_s *self, struct aq_ring_buff_s *buff, struct sk_buff *skb) @@ -381,7 +408,7 @@ int aq_ring_rx_clean(struct aq_ring_s *self, self->hw_head); if (unlikely(!is_rsc_completed) || - frag_cnt > MAX_SKB_FRAGS) { + frag_cnt > MAX_SKB_FRAGS) { err = 0; goto err_exit; } @@ -496,8 +523,8 @@ int aq_ring_rx_clean(struct aq_ring_s *self, /* Send all PTP traffic to 0 queue */ skb_record_rx_queue(skb, is_ptp_ring ? 0 - : AQ_NIC_RING2QMAP(self->aq_nic, - self->idx)); + : AQ_NIC_RING2QMAP(self->aq_nic, + self->idx)); u64_stats_update_begin(&self->stats.rx.syncp); ++self->stats.rx.packets; diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h index 93659e58f1ce11fc70b146e66837399266c9614d..3be56a4fc5bb0095959f3bc2c8929e0ac5806e9c 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_ring.h +++ b/drivers/net/ethernet/aquantia/atlantic/aq_ring.h @@ -182,6 +182,7 @@ void aq_ring_update_queue_state(struct aq_ring_s *ring); void aq_ring_queue_wake(struct aq_ring_s *ring); void aq_ring_queue_stop(struct aq_ring_s *ring); bool aq_ring_tx_clean(struct aq_ring_s *self); +void aq_ring_tx_deinit(struct aq_ring_s *self); int aq_ring_rx_clean(struct aq_ring_s *self, struct napi_struct *napi, int *work_done, diff --git a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c index 6ab1f3212d2463a53ac35fc41f1aa3706d376066..2d77554d1b8195291058bc434d38290b3c1bf9a8 100644 --- a/drivers/net/ethernet/aquantia/atlantic/aq_vec.c +++ b/drivers/net/ethernet/aquantia/atlantic/aq_vec.c @@ -270,7 +270,7 @@ void aq_vec_deinit(struct aq_vec_s *self) for (i = 0U; self->tx_rings > i; ++i) { ring = self->ring[i]; - aq_ring_tx_clean(&ring[AQ_VEC_TX_ID]); + aq_ring_tx_deinit(&ring[AQ_VEC_TX_ID]); aq_ring_rx_deinit(&ring[AQ_VEC_RX_ID]); }