diff options
Diffstat (limited to 'drivers/net/ethernet/realtek/r8169_main.c')
-rw-r--r-- | drivers/net/ethernet/realtek/r8169_main.c | 99 |
1 files changed, 48 insertions, 51 deletions
diff --git a/drivers/net/ethernet/realtek/r8169_main.c b/drivers/net/ethernet/realtek/r8169_main.c index e35820c72264..e887ee1e308f 100644 --- a/drivers/net/ethernet/realtek/r8169_main.c +++ b/drivers/net/ethernet/realtek/r8169_main.c @@ -4413,15 +4413,17 @@ static inline void rtl8169_rx_csum(struct sk_buff *skb, u32 opts1) static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget) { - unsigned int cur_rx, rx_left; - unsigned int count; + unsigned int cur_rx, rx_left, count; + struct device *d = tp_to_dev(tp); cur_rx = tp->cur_rx; for (rx_left = min(budget, NUM_RX_DESC); rx_left > 0; rx_left--, cur_rx++) { - unsigned int entry = cur_rx % NUM_RX_DESC; - const void *rx_buf = page_address(tp->Rx_databuff[entry]); + unsigned int pkt_size, entry = cur_rx % NUM_RX_DESC; struct RxDesc *desc = tp->RxDescArray + entry; + struct sk_buff *skb; + const void *rx_buf; + dma_addr_t addr; u32 status; status = le32_to_cpu(desc->opts1); @@ -4443,62 +4445,57 @@ static int rtl_rx(struct net_device *dev, struct rtl8169_private *tp, u32 budget dev->stats.rx_length_errors++; if (status & RxCRC) dev->stats.rx_crc_errors++; - if (status & (RxRUNT | RxCRC) && !(status & RxRWT) && - dev->features & NETIF_F_RXALL) { - goto process_pkt; - } - } else { - unsigned int pkt_size; - struct sk_buff *skb; - -process_pkt: - pkt_size = status & GENMASK(13, 0); - if (likely(!(dev->features & NETIF_F_RXFCS))) - pkt_size -= ETH_FCS_LEN; - /* - * The driver does not support incoming fragmented - * frames. They are seen as a symptom of over-mtu - * sized frames. - */ - if (unlikely(rtl8169_fragmented_frame(status))) { - dev->stats.rx_dropped++; - dev->stats.rx_length_errors++; - goto release_descriptor; - } - skb = napi_alloc_skb(&tp->napi, pkt_size); - if (unlikely(!skb)) { - dev->stats.rx_dropped++; + if (!(dev->features & NETIF_F_RXALL)) goto release_descriptor; - } + else if (status & RxRWT || !(status & (RxRUNT | RxCRC))) + goto release_descriptor; + } - dma_sync_single_for_cpu(tp_to_dev(tp), - le64_to_cpu(desc->addr), - pkt_size, DMA_FROM_DEVICE); - prefetch(rx_buf); - skb_copy_to_linear_data(skb, rx_buf, pkt_size); - skb->tail += pkt_size; - skb->len = pkt_size; + pkt_size = status & GENMASK(13, 0); + if (likely(!(dev->features & NETIF_F_RXFCS))) + pkt_size -= ETH_FCS_LEN; - dma_sync_single_for_device(tp_to_dev(tp), - le64_to_cpu(desc->addr), - pkt_size, DMA_FROM_DEVICE); + /* The driver does not support incoming fragmented frames. + * They are seen as a symptom of over-mtu sized frames. + */ + if (unlikely(rtl8169_fragmented_frame(status))) { + dev->stats.rx_dropped++; + dev->stats.rx_length_errors++; + goto release_descriptor; + } - rtl8169_rx_csum(skb, status); - skb->protocol = eth_type_trans(skb, dev); + skb = napi_alloc_skb(&tp->napi, pkt_size); + if (unlikely(!skb)) { + dev->stats.rx_dropped++; + goto release_descriptor; + } - rtl8169_rx_vlan_tag(desc, skb); + addr = le64_to_cpu(desc->addr); + rx_buf = page_address(tp->Rx_databuff[entry]); - if (skb->pkt_type == PACKET_MULTICAST) - dev->stats.multicast++; + dma_sync_single_for_cpu(d, addr, pkt_size, DMA_FROM_DEVICE); + prefetch(rx_buf); + skb_copy_to_linear_data(skb, rx_buf, pkt_size); + skb->tail += pkt_size; + skb->len = pkt_size; + dma_sync_single_for_device(d, addr, pkt_size, DMA_FROM_DEVICE); - napi_gro_receive(&tp->napi, skb); + rtl8169_rx_csum(skb, status); + skb->protocol = eth_type_trans(skb, dev); + + rtl8169_rx_vlan_tag(desc, skb); + + if (skb->pkt_type == PACKET_MULTICAST) + dev->stats.multicast++; + + napi_gro_receive(&tp->napi, skb); + + u64_stats_update_begin(&tp->rx_stats.syncp); + tp->rx_stats.packets++; + tp->rx_stats.bytes += pkt_size; + u64_stats_update_end(&tp->rx_stats.syncp); - u64_stats_update_begin(&tp->rx_stats.syncp); - tp->rx_stats.packets++; - tp->rx_stats.bytes += pkt_size; - u64_stats_update_end(&tp->rx_stats.syncp); - } release_descriptor: rtl8169_mark_to_asic(desc); } |