diff options
Diffstat (limited to 'drivers/net/ethernet/marvell/skge.c')
-rw-r--r-- | drivers/net/ethernet/marvell/skge.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/drivers/net/ethernet/marvell/skge.c b/drivers/net/ethernet/marvell/skge.c index 18a87a57fc0a..33947ac595c0 100644 --- a/drivers/net/ethernet/marvell/skge.c +++ b/drivers/net/ethernet/marvell/skge.c | |||
@@ -2576,6 +2576,7 @@ static int skge_up(struct net_device *dev) | |||
2576 | } | 2576 | } |
2577 | 2577 | ||
2578 | /* Initialize MAC */ | 2578 | /* Initialize MAC */ |
2579 | netif_carrier_off(dev); | ||
2579 | spin_lock_bh(&hw->phy_lock); | 2580 | spin_lock_bh(&hw->phy_lock); |
2580 | if (is_genesis(hw)) | 2581 | if (is_genesis(hw)) |
2581 | genesis_mac_init(hw, port); | 2582 | genesis_mac_init(hw, port); |
@@ -2797,6 +2798,8 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, | |||
2797 | td->control = BMU_OWN | BMU_SW | BMU_STF | control | len; | 2798 | td->control = BMU_OWN | BMU_SW | BMU_STF | control | len; |
2798 | wmb(); | 2799 | wmb(); |
2799 | 2800 | ||
2801 | netdev_sent_queue(dev, skb->len); | ||
2802 | |||
2800 | skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_START); | 2803 | skge_write8(hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_START); |
2801 | 2804 | ||
2802 | netif_printk(skge, tx_queued, KERN_DEBUG, skge->netdev, | 2805 | netif_printk(skge, tx_queued, KERN_DEBUG, skge->netdev, |
@@ -2816,11 +2819,9 @@ static netdev_tx_t skge_xmit_frame(struct sk_buff *skb, | |||
2816 | 2819 | ||
2817 | 2820 | ||
2818 | /* Free resources associated with this reing element */ | 2821 | /* Free resources associated with this reing element */ |
2819 | static void skge_tx_free(struct skge_port *skge, struct skge_element *e, | 2822 | static inline void skge_tx_unmap(struct pci_dev *pdev, struct skge_element *e, |
2820 | u32 control) | 2823 | u32 control) |
2821 | { | 2824 | { |
2822 | struct pci_dev *pdev = skge->hw->pdev; | ||
2823 | |||
2824 | /* skb header vs. fragment */ | 2825 | /* skb header vs. fragment */ |
2825 | if (control & BMU_STF) | 2826 | if (control & BMU_STF) |
2826 | pci_unmap_single(pdev, dma_unmap_addr(e, mapaddr), | 2827 | pci_unmap_single(pdev, dma_unmap_addr(e, mapaddr), |
@@ -2830,13 +2831,6 @@ static void skge_tx_free(struct skge_port *skge, struct skge_element *e, | |||
2830 | pci_unmap_page(pdev, dma_unmap_addr(e, mapaddr), | 2831 | pci_unmap_page(pdev, dma_unmap_addr(e, mapaddr), |
2831 | dma_unmap_len(e, maplen), | 2832 | dma_unmap_len(e, maplen), |
2832 | PCI_DMA_TODEVICE); | 2833 | PCI_DMA_TODEVICE); |
2833 | |||
2834 | if (control & BMU_EOF) { | ||
2835 | netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev, | ||
2836 | "tx done slot %td\n", e - skge->tx_ring.start); | ||
2837 | |||
2838 | dev_kfree_skb(e->skb); | ||
2839 | } | ||
2840 | } | 2834 | } |
2841 | 2835 | ||
2842 | /* Free all buffers in transmit ring */ | 2836 | /* Free all buffers in transmit ring */ |
@@ -2847,10 +2841,15 @@ static void skge_tx_clean(struct net_device *dev) | |||
2847 | 2841 | ||
2848 | for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) { | 2842 | for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) { |
2849 | struct skge_tx_desc *td = e->desc; | 2843 | struct skge_tx_desc *td = e->desc; |
2850 | skge_tx_free(skge, e, td->control); | 2844 | |
2845 | skge_tx_unmap(skge->hw->pdev, e, td->control); | ||
2846 | |||
2847 | if (td->control & BMU_EOF) | ||
2848 | dev_kfree_skb(e->skb); | ||
2851 | td->control = 0; | 2849 | td->control = 0; |
2852 | } | 2850 | } |
2853 | 2851 | ||
2852 | netdev_reset_queue(dev); | ||
2854 | skge->tx_ring.to_clean = e; | 2853 | skge->tx_ring.to_clean = e; |
2855 | } | 2854 | } |
2856 | 2855 | ||
@@ -3111,6 +3110,7 @@ static void skge_tx_done(struct net_device *dev) | |||
3111 | struct skge_port *skge = netdev_priv(dev); | 3110 | struct skge_port *skge = netdev_priv(dev); |
3112 | struct skge_ring *ring = &skge->tx_ring; | 3111 | struct skge_ring *ring = &skge->tx_ring; |
3113 | struct skge_element *e; | 3112 | struct skge_element *e; |
3113 | unsigned int bytes_compl = 0, pkts_compl = 0; | ||
3114 | 3114 | ||
3115 | skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F); | 3115 | skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F); |
3116 | 3116 | ||
@@ -3120,8 +3120,20 @@ static void skge_tx_done(struct net_device *dev) | |||
3120 | if (control & BMU_OWN) | 3120 | if (control & BMU_OWN) |
3121 | break; | 3121 | break; |
3122 | 3122 | ||
3123 | skge_tx_free(skge, e, control); | 3123 | skge_tx_unmap(skge->hw->pdev, e, control); |
3124 | |||
3125 | if (control & BMU_EOF) { | ||
3126 | netif_printk(skge, tx_done, KERN_DEBUG, skge->netdev, | ||
3127 | "tx done slot %td\n", | ||
3128 | e - skge->tx_ring.start); | ||
3129 | |||
3130 | pkts_compl++; | ||
3131 | bytes_compl += e->skb->len; | ||
3132 | |||
3133 | dev_kfree_skb(e->skb); | ||
3134 | } | ||
3124 | } | 3135 | } |
3136 | netdev_completed_queue(dev, pkts_compl, bytes_compl); | ||
3125 | skge->tx_ring.to_clean = e; | 3137 | skge->tx_ring.to_clean = e; |
3126 | 3138 | ||
3127 | /* Can run lockless until we need to synchronize to restart queue. */ | 3139 | /* Can run lockless until we need to synchronize to restart queue. */ |