diff options
Diffstat (limited to 'drivers/net/ethernet/broadcom/tg3.c')
-rw-r--r-- | drivers/net/ethernet/broadcom/tg3.c | 41 |
1 files changed, 20 insertions, 21 deletions
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c index fe712f955110..161cbbb4814a 100644 --- a/drivers/net/ethernet/broadcom/tg3.c +++ b/drivers/net/ethernet/broadcom/tg3.c @@ -5356,7 +5356,7 @@ static void tg3_tx(struct tg3_napi *tnapi) pci_unmap_page(tp->pdev, dma_unmap_addr(ri, mapping), - skb_shinfo(skb)->frags[i].size, + skb_frag_size(&skb_shinfo(skb)->frags[i]), PCI_DMA_TODEVICE); while (ri->fragmented) { @@ -6510,14 +6510,14 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last) } for (i = 0; i < last; i++) { - skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; entry = NEXT_TX(entry); txb = &tnapi->tx_buffers[entry]; pci_unmap_page(tnapi->tp->pdev, dma_unmap_addr(txb, mapping), - frag->size, PCI_DMA_TODEVICE); + skb_frag_size(frag), PCI_DMA_TODEVICE); while (txb->fragmented) { txb->fragmented = false; @@ -6529,12 +6529,12 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last) /* Workaround 4GB and 40-bit hardware DMA bugs. */ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, - struct sk_buff *skb, + struct sk_buff **pskb, u32 *entry, u32 *budget, u32 base_flags, u32 mss, u32 vlan) { struct tg3 *tp = tnapi->tp; - struct sk_buff *new_skb; + struct sk_buff *new_skb, *skb = *pskb; dma_addr_t new_addr = 0; int ret = 0; @@ -6576,7 +6576,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi, } dev_kfree_skb(skb); - + *pskb = new_skb; return ret; } @@ -6671,10 +6671,8 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) u32 tcp_opt_len, hdr_len; if (skb_header_cloned(skb) && - pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) { - dev_kfree_skb(skb); - goto out_unlock; - } + pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) + goto drop; iph = ip_hdr(skb); tcp_opt_len = tcp_optlen(skb); @@ -6746,10 +6744,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) len = skb_headlen(skb); mapping = pci_map_single(tp->pdev, skb->data, len, PCI_DMA_TODEVICE); - if (pci_dma_mapping_error(tp->pdev, mapping)) { - dev_kfree_skb(skb); - goto out_unlock; - } + if (pci_dma_mapping_error(tp->pdev, mapping)) + goto drop; + tnapi->tx_buffers[entry].skb = skb; dma_unmap_addr_set(&tnapi->tx_buffers[entry], mapping, mapping); @@ -6777,7 +6774,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) for (i = 0; i <= last; i++) { skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; - len = frag->size; + len = skb_frag_size(frag); mapping = skb_frag_dma_map(&tp->pdev->dev, frag, 0, len, DMA_TO_DEVICE); @@ -6803,9 +6800,9 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) */ entry = tnapi->tx_prod; budget = tg3_tx_avail(tnapi); - if (tigon3_dma_hwbug_workaround(tnapi, skb, &entry, &budget, + if (tigon3_dma_hwbug_workaround(tnapi, &skb, &entry, &budget, base_flags, mss, vlan)) - goto out_unlock; + goto drop_nofree; } skb_tx_timestamp(skb); @@ -6827,15 +6824,16 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) netif_tx_wake_queue(txq); } -out_unlock: mmiowb(); - return NETDEV_TX_OK; dma_error: tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i); - dev_kfree_skb(skb); tnapi->tx_buffers[tnapi->tx_prod].skb = NULL; +drop: + dev_kfree_skb(skb); +drop_nofree: + tp->tx_dropped++; return NETDEV_TX_OK; } @@ -10009,6 +10007,7 @@ static struct rtnl_link_stats64 *tg3_get_stats64(struct net_device *dev, get_stat64(&hw_stats->rx_discards); stats->rx_dropped = tp->rx_dropped; + stats->tx_dropped = tp->tx_dropped; return stats; } @@ -15668,7 +15667,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev) cancel_work_sync(&tp->reset_task); - if (!tg3_flag(tp, USE_PHYLIB)) { + if (tg3_flag(tp, USE_PHYLIB)) { tg3_phy_fini(tp); tg3_mdio_fini(tp); } |