diff options
-rw-r--r-- | drivers/net/skge.c | 82 | ||||
-rw-r--r-- | drivers/net/skge.h | 1 |
2 files changed, 28 insertions, 55 deletions
diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 8a321be24835..34a4b87819bd 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c | |||
@@ -91,7 +91,7 @@ MODULE_DEVICE_TABLE(pci, skge_id_table); | |||
91 | static int skge_up(struct net_device *dev); | 91 | static int skge_up(struct net_device *dev); |
92 | static int skge_down(struct net_device *dev); | 92 | static int skge_down(struct net_device *dev); |
93 | static void skge_phy_reset(struct skge_port *skge); | 93 | static void skge_phy_reset(struct skge_port *skge); |
94 | static void skge_tx_clean(struct skge_port *skge); | 94 | static void skge_tx_clean(struct net_device *dev); |
95 | static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); | 95 | static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); |
96 | static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); | 96 | static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val); |
97 | static void genesis_get_stats(struct skge_port *skge, u64 *data); | 97 | static void genesis_get_stats(struct skge_port *skge, u64 *data); |
@@ -105,6 +105,7 @@ static const int txqaddr[] = { Q_XA1, Q_XA2 }; | |||
105 | static const int rxqaddr[] = { Q_R1, Q_R2 }; | 105 | static const int rxqaddr[] = { Q_R1, Q_R2 }; |
106 | static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; | 106 | static const u32 rxirqmask[] = { IS_R1_F, IS_R2_F }; |
107 | static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; | 107 | static const u32 txirqmask[] = { IS_XA1_F, IS_XA2_F }; |
108 | static const u32 irqmask[] = { IS_R1_F|IS_XA1_F, IS_R2_F|IS_XA2_F }; | ||
108 | 109 | ||
109 | static int skge_get_regs_len(struct net_device *dev) | 110 | static int skge_get_regs_len(struct net_device *dev) |
110 | { | 111 | { |
@@ -2283,7 +2284,7 @@ static int skge_down(struct net_device *dev) | |||
2283 | skge_led(skge, LED_MODE_OFF); | 2284 | skge_led(skge, LED_MODE_OFF); |
2284 | 2285 | ||
2285 | netif_poll_disable(dev); | 2286 | netif_poll_disable(dev); |
2286 | skge_tx_clean(skge); | 2287 | skge_tx_clean(dev); |
2287 | skge_rx_clean(skge); | 2288 | skge_rx_clean(skge); |
2288 | 2289 | ||
2289 | kfree(skge->rx_ring.start); | 2290 | kfree(skge->rx_ring.start); |
@@ -2308,25 +2309,12 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
2308 | int i; | 2309 | int i; |
2309 | u32 control, len; | 2310 | u32 control, len; |
2310 | u64 map; | 2311 | u64 map; |
2311 | unsigned long flags; | ||
2312 | 2312 | ||
2313 | if (skb_padto(skb, ETH_ZLEN)) | 2313 | if (skb_padto(skb, ETH_ZLEN)) |
2314 | return NETDEV_TX_OK; | 2314 | return NETDEV_TX_OK; |
2315 | 2315 | ||
2316 | if (!spin_trylock_irqsave(&skge->tx_lock, flags)) | 2316 | if (unlikely(skge_avail(&skge->tx_ring) < skb_shinfo(skb)->nr_frags + 1)) |
2317 | /* Collision - tell upper layer to requeue */ | ||
2318 | return NETDEV_TX_LOCKED; | ||
2319 | |||
2320 | if (unlikely(skge_avail(&skge->tx_ring) < skb_shinfo(skb)->nr_frags + 1)) { | ||
2321 | if (!netif_queue_stopped(dev)) { | ||
2322 | netif_stop_queue(dev); | ||
2323 | |||
2324 | printk(KERN_WARNING PFX "%s: ring full when queue awake!\n", | ||
2325 | dev->name); | ||
2326 | } | ||
2327 | spin_unlock_irqrestore(&skge->tx_lock, flags); | ||
2328 | return NETDEV_TX_BUSY; | 2317 | return NETDEV_TX_BUSY; |
2329 | } | ||
2330 | 2318 | ||
2331 | e = skge->tx_ring.to_use; | 2319 | e = skge->tx_ring.to_use; |
2332 | td = e->desc; | 2320 | td = e->desc; |
@@ -2401,8 +2389,6 @@ static int skge_xmit_frame(struct sk_buff *skb, struct net_device *dev) | |||
2401 | netif_stop_queue(dev); | 2389 | netif_stop_queue(dev); |
2402 | } | 2390 | } |
2403 | 2391 | ||
2404 | spin_unlock_irqrestore(&skge->tx_lock, flags); | ||
2405 | |||
2406 | dev->trans_start = jiffies; | 2392 | dev->trans_start = jiffies; |
2407 | 2393 | ||
2408 | return NETDEV_TX_OK; | 2394 | return NETDEV_TX_OK; |
@@ -2432,18 +2418,18 @@ static void skge_tx_free(struct skge_port *skge, struct skge_element *e, | |||
2432 | printk(KERN_DEBUG PFX "%s: tx done slot %td\n", | 2418 | printk(KERN_DEBUG PFX "%s: tx done slot %td\n", |
2433 | skge->netdev->name, e - skge->tx_ring.start); | 2419 | skge->netdev->name, e - skge->tx_ring.start); |
2434 | 2420 | ||
2435 | dev_kfree_skb_any(e->skb); | 2421 | dev_kfree_skb(e->skb); |
2436 | } | 2422 | } |
2437 | e->skb = NULL; | 2423 | e->skb = NULL; |
2438 | } | 2424 | } |
2439 | 2425 | ||
2440 | /* Free all buffers in transmit ring */ | 2426 | /* Free all buffers in transmit ring */ |
2441 | static void skge_tx_clean(struct skge_port *skge) | 2427 | static void skge_tx_clean(struct net_device *dev) |
2442 | { | 2428 | { |
2429 | struct skge_port *skge = netdev_priv(dev); | ||
2443 | struct skge_element *e; | 2430 | struct skge_element *e; |
2444 | unsigned long flags; | ||
2445 | 2431 | ||
2446 | spin_lock_irqsave(&skge->tx_lock, flags); | 2432 | netif_tx_lock_bh(dev); |
2447 | for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) { | 2433 | for (e = skge->tx_ring.to_clean; e != skge->tx_ring.to_use; e = e->next) { |
2448 | struct skge_tx_desc *td = e->desc; | 2434 | struct skge_tx_desc *td = e->desc; |
2449 | skge_tx_free(skge, e, td->control); | 2435 | skge_tx_free(skge, e, td->control); |
@@ -2451,8 +2437,8 @@ static void skge_tx_clean(struct skge_port *skge) | |||
2451 | } | 2437 | } |
2452 | 2438 | ||
2453 | skge->tx_ring.to_clean = e; | 2439 | skge->tx_ring.to_clean = e; |
2454 | netif_wake_queue(skge->netdev); | 2440 | netif_wake_queue(dev); |
2455 | spin_unlock_irqrestore(&skge->tx_lock, flags); | 2441 | netif_tx_unlock_bh(dev); |
2456 | } | 2442 | } |
2457 | 2443 | ||
2458 | static void skge_tx_timeout(struct net_device *dev) | 2444 | static void skge_tx_timeout(struct net_device *dev) |
@@ -2463,7 +2449,7 @@ static void skge_tx_timeout(struct net_device *dev) | |||
2463 | printk(KERN_DEBUG PFX "%s: tx timeout\n", dev->name); | 2449 | printk(KERN_DEBUG PFX "%s: tx timeout\n", dev->name); |
2464 | 2450 | ||
2465 | skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP); | 2451 | skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_STOP); |
2466 | skge_tx_clean(skge); | 2452 | skge_tx_clean(dev); |
2467 | } | 2453 | } |
2468 | 2454 | ||
2469 | static int skge_change_mtu(struct net_device *dev, int new_mtu) | 2455 | static int skge_change_mtu(struct net_device *dev, int new_mtu) |
@@ -2679,15 +2665,15 @@ resubmit: | |||
2679 | } | 2665 | } |
2680 | 2666 | ||
2681 | /* Free all buffers in Tx ring which are no longer owned by device */ | 2667 | /* Free all buffers in Tx ring which are no longer owned by device */ |
2682 | static void skge_txirq(struct net_device *dev) | 2668 | static void skge_tx_done(struct net_device *dev) |
2683 | { | 2669 | { |
2684 | struct skge_port *skge = netdev_priv(dev); | 2670 | struct skge_port *skge = netdev_priv(dev); |
2685 | struct skge_ring *ring = &skge->tx_ring; | 2671 | struct skge_ring *ring = &skge->tx_ring; |
2686 | struct skge_element *e; | 2672 | struct skge_element *e; |
2687 | 2673 | ||
2688 | rmb(); | 2674 | skge_write8(skge->hw, Q_ADDR(txqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F); |
2689 | 2675 | ||
2690 | spin_lock(&skge->tx_lock); | 2676 | netif_tx_lock(dev); |
2691 | for (e = ring->to_clean; e != ring->to_use; e = e->next) { | 2677 | for (e = ring->to_clean; e != ring->to_use; e = e->next) { |
2692 | struct skge_tx_desc *td = e->desc; | 2678 | struct skge_tx_desc *td = e->desc; |
2693 | 2679 | ||
@@ -2698,11 +2684,10 @@ static void skge_txirq(struct net_device *dev) | |||
2698 | } | 2684 | } |
2699 | skge->tx_ring.to_clean = e; | 2685 | skge->tx_ring.to_clean = e; |
2700 | 2686 | ||
2701 | if (netif_queue_stopped(skge->netdev) | 2687 | if (skge_avail(&skge->tx_ring) > TX_LOW_WATER) |
2702 | && skge_avail(&skge->tx_ring) > TX_LOW_WATER) | 2688 | netif_wake_queue(dev); |
2703 | netif_wake_queue(skge->netdev); | ||
2704 | 2689 | ||
2705 | spin_unlock(&skge->tx_lock); | 2690 | netif_tx_unlock(dev); |
2706 | } | 2691 | } |
2707 | 2692 | ||
2708 | static int skge_poll(struct net_device *dev, int *budget) | 2693 | static int skge_poll(struct net_device *dev, int *budget) |
@@ -2714,6 +2699,10 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2714 | int to_do = min(dev->quota, *budget); | 2699 | int to_do = min(dev->quota, *budget); |
2715 | int work_done = 0; | 2700 | int work_done = 0; |
2716 | 2701 | ||
2702 | skge_tx_done(dev); | ||
2703 | |||
2704 | skge_write8(hw, Q_ADDR(rxqaddr[skge->port], Q_CSR), CSR_IRQ_CL_F); | ||
2705 | |||
2717 | for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) { | 2706 | for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) { |
2718 | struct skge_rx_desc *rd = e->desc; | 2707 | struct skge_rx_desc *rd = e->desc; |
2719 | struct sk_buff *skb; | 2708 | struct sk_buff *skb; |
@@ -2744,10 +2733,9 @@ static int skge_poll(struct net_device *dev, int *budget) | |||
2744 | if (work_done >= to_do) | 2733 | if (work_done >= to_do) |
2745 | return 1; /* not done */ | 2734 | return 1; /* not done */ |
2746 | 2735 | ||
2747 | netif_rx_complete(dev); | ||
2748 | |||
2749 | spin_lock_irq(&hw->hw_lock); | 2736 | spin_lock_irq(&hw->hw_lock); |
2750 | hw->intr_mask |= rxirqmask[skge->port]; | 2737 | __netif_rx_complete(dev); |
2738 | hw->intr_mask |= irqmask[skge->port]; | ||
2751 | skge_write32(hw, B0_IMSK, hw->intr_mask); | 2739 | skge_write32(hw, B0_IMSK, hw->intr_mask); |
2752 | skge_read32(hw, B0_IMSK); | 2740 | skge_read32(hw, B0_IMSK); |
2753 | spin_unlock_irq(&hw->hw_lock); | 2741 | spin_unlock_irq(&hw->hw_lock); |
@@ -2906,14 +2894,8 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2906 | schedule_work(&hw->phy_work); | 2894 | schedule_work(&hw->phy_work); |
2907 | } | 2895 | } |
2908 | 2896 | ||
2909 | if (status & IS_XA1_F) { | 2897 | if (status & (IS_XA1_F|IS_R1_F)) { |
2910 | skge_write8(hw, Q_ADDR(Q_XA1, Q_CSR), CSR_IRQ_CL_F); | 2898 | hw->intr_mask &= ~(IS_XA1_F|IS_R1_F); |
2911 | skge_txirq(hw->dev[0]); | ||
2912 | } | ||
2913 | |||
2914 | if (status & IS_R1_F) { | ||
2915 | skge_write8(hw, Q_ADDR(Q_R1, Q_CSR), CSR_IRQ_CL_F); | ||
2916 | hw->intr_mask &= ~IS_R1_F; | ||
2917 | netif_rx_schedule(hw->dev[0]); | 2899 | netif_rx_schedule(hw->dev[0]); |
2918 | } | 2900 | } |
2919 | 2901 | ||
@@ -2932,14 +2914,8 @@ static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs) | |||
2932 | skge_mac_intr(hw, 0); | 2914 | skge_mac_intr(hw, 0); |
2933 | 2915 | ||
2934 | if (hw->dev[1]) { | 2916 | if (hw->dev[1]) { |
2935 | if (status & IS_XA2_F) { | 2917 | if (status & (IS_XA2_F|IS_R2_F)) { |
2936 | skge_write8(hw, Q_ADDR(Q_XA2, Q_CSR), CSR_IRQ_CL_F); | 2918 | hw->intr_mask &= ~(IS_XA2_F|IS_R2_F); |
2937 | skge_txirq(hw->dev[1]); | ||
2938 | } | ||
2939 | |||
2940 | if (status & IS_R2_F) { | ||
2941 | skge_write8(hw, Q_ADDR(Q_R2, Q_CSR), CSR_IRQ_CL_F); | ||
2942 | hw->intr_mask &= ~IS_R2_F; | ||
2943 | netif_rx_schedule(hw->dev[1]); | 2919 | netif_rx_schedule(hw->dev[1]); |
2944 | } | 2920 | } |
2945 | 2921 | ||
@@ -3228,7 +3204,7 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3228 | dev->poll_controller = skge_netpoll; | 3204 | dev->poll_controller = skge_netpoll; |
3229 | #endif | 3205 | #endif |
3230 | dev->irq = hw->pdev->irq; | 3206 | dev->irq = hw->pdev->irq; |
3231 | dev->features = NETIF_F_LLTX; | 3207 | |
3232 | if (highmem) | 3208 | if (highmem) |
3233 | dev->features |= NETIF_F_HIGHDMA; | 3209 | dev->features |= NETIF_F_HIGHDMA; |
3234 | 3210 | ||
@@ -3250,8 +3226,6 @@ static struct net_device *skge_devinit(struct skge_hw *hw, int port, | |||
3250 | 3226 | ||
3251 | skge->port = port; | 3227 | skge->port = port; |
3252 | 3228 | ||
3253 | spin_lock_init(&skge->tx_lock); | ||
3254 | |||
3255 | if (hw->chip_id != CHIP_ID_GENESIS) { | 3229 | if (hw->chip_id != CHIP_ID_GENESIS) { |
3256 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; | 3230 | dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG; |
3257 | skge->rx_csum = 1; | 3231 | skge->rx_csum = 1; |
diff --git a/drivers/net/skge.h b/drivers/net/skge.h index 593387b3c0dd..79e09271bcf9 100644 --- a/drivers/net/skge.h +++ b/drivers/net/skge.h | |||
@@ -2417,7 +2417,6 @@ struct skge_port { | |||
2417 | struct net_device *netdev; | 2417 | struct net_device *netdev; |
2418 | int port; | 2418 | int port; |
2419 | 2419 | ||
2420 | spinlock_t tx_lock; | ||
2421 | struct skge_ring tx_ring; | 2420 | struct skge_ring tx_ring; |
2422 | struct skge_ring rx_ring; | 2421 | struct skge_ring rx_ring; |
2423 | 2422 | ||