diff options
Diffstat (limited to 'drivers/net/sky2.c')
-rw-r--r-- | drivers/net/sky2.c | 94 |
1 files changed, 41 insertions, 53 deletions
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index ea117fc3d5e3..a0d75b0f3798 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c | |||
@@ -1130,7 +1130,7 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp | |||
1130 | u16 port = sky2->port; | 1130 | u16 port = sky2->port; |
1131 | 1131 | ||
1132 | netif_tx_lock_bh(dev); | 1132 | netif_tx_lock_bh(dev); |
1133 | netif_poll_disable(sky2->hw->dev[0]); | 1133 | napi_disable(&hw->napi); |
1134 | 1134 | ||
1135 | sky2->vlgrp = grp; | 1135 | sky2->vlgrp = grp; |
1136 | if (grp) { | 1136 | if (grp) { |
@@ -1145,7 +1145,7 @@ static void sky2_vlan_rx_register(struct net_device *dev, struct vlan_group *grp | |||
1145 | TX_VLAN_TAG_OFF); | 1145 | TX_VLAN_TAG_OFF); |
1146 | } | 1146 | } |
1147 | 1147 | ||
1148 | netif_poll_enable(sky2->hw->dev[0]); | 1148 | napi_enable(&hw->napi); |
1149 | netif_tx_unlock_bh(dev); | 1149 | netif_tx_unlock_bh(dev); |
1150 | } | 1150 | } |
1151 | #endif | 1151 | #endif |
@@ -1385,9 +1385,13 @@ static int sky2_up(struct net_device *dev) | |||
1385 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, | 1385 | sky2_prefetch_init(hw, txqaddr[port], sky2->tx_le_map, |
1386 | TX_RING_SIZE - 1); | 1386 | TX_RING_SIZE - 1); |
1387 | 1387 | ||
1388 | napi_enable(&hw->napi); | ||
1389 | |||
1388 | err = sky2_rx_start(sky2); | 1390 | err = sky2_rx_start(sky2); |
1389 | if (err) | 1391 | if (err) { |
1392 | napi_disable(&hw->napi); | ||
1390 | goto err_out; | 1393 | goto err_out; |
1394 | } | ||
1391 | 1395 | ||
1392 | /* Enable interrupts from phy/mac for port */ | 1396 | /* Enable interrupts from phy/mac for port */ |
1393 | imask = sky2_read32(hw, B0_IMSK); | 1397 | imask = sky2_read32(hw, B0_IMSK); |
@@ -1676,6 +1680,8 @@ static int sky2_down(struct net_device *dev) | |||
1676 | /* Stop more packets from being queued */ | 1680 | /* Stop more packets from being queued */ |
1677 | netif_stop_queue(dev); | 1681 | netif_stop_queue(dev); |
1678 | 1682 | ||
1683 | napi_disable(&hw->napi); | ||
1684 | |||
1679 | /* Disable port IRQ */ | 1685 | /* Disable port IRQ */ |
1680 | imask = sky2_read32(hw, B0_IMSK); | 1686 | imask = sky2_read32(hw, B0_IMSK); |
1681 | imask &= ~portirq_msk[port]; | 1687 | imask &= ~portirq_msk[port]; |
@@ -2016,7 +2022,7 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
2016 | 2022 | ||
2017 | dev->trans_start = jiffies; /* prevent tx timeout */ | 2023 | dev->trans_start = jiffies; /* prevent tx timeout */ |
2018 | netif_stop_queue(dev); | 2024 | netif_stop_queue(dev); |
2019 | netif_poll_disable(hw->dev[0]); | 2025 | napi_disable(&hw->napi); |
2020 | 2026 | ||
2021 | synchronize_irq(hw->pdev->irq); | 2027 | synchronize_irq(hw->pdev->irq); |
2022 | 2028 | ||
@@ -2043,12 +2049,16 @@ static int sky2_change_mtu(struct net_device *dev, int new_mtu) | |||
2043 | err = sky2_rx_start(sky2); | 2049 | err = sky2_rx_start(sky2); |
2044 | sky2_write32(hw, B0_IMSK, imask); | 2050 | sky2_write32(hw, B0_IMSK, imask); |
2045 | 2051 | ||
2052 | /* Unconditionally re-enable NAPI because even if we | ||
2053 | * call dev_close() that will do a napi_disable(). | ||
2054 | */ | ||
2055 | napi_enable(&hw->napi); | ||
2056 | |||
2046 | if (err) | 2057 | if (err) |
2047 | dev_close(dev); | 2058 | dev_close(dev); |
2048 | else { | 2059 | else { |
2049 | gma_write16(hw, port, GM_GP_CTRL, ctl); | 2060 | gma_write16(hw, port, GM_GP_CTRL, ctl); |
2050 | 2061 | ||
2051 | netif_poll_enable(hw->dev[0]); | ||
2052 | netif_wake_queue(dev); | 2062 | netif_wake_queue(dev); |
2053 | } | 2063 | } |
2054 | 2064 | ||
@@ -2544,18 +2554,15 @@ static int sky2_rx_hung(struct net_device *dev) | |||
2544 | static void sky2_watchdog(unsigned long arg) | 2554 | static void sky2_watchdog(unsigned long arg) |
2545 | { | 2555 | { |
2546 | struct sky2_hw *hw = (struct sky2_hw *) arg; | 2556 | struct sky2_hw *hw = (struct sky2_hw *) arg; |
2547 | struct net_device *dev; | ||
2548 | 2557 | ||
2549 | /* Check for lost IRQ once a second */ | 2558 | /* Check for lost IRQ once a second */ |
2550 | if (sky2_read32(hw, B0_ISRC)) { | 2559 | if (sky2_read32(hw, B0_ISRC)) { |
2551 | dev = hw->dev[0]; | 2560 | napi_schedule(&hw->napi); |
2552 | if (__netif_rx_schedule_prep(dev)) | ||
2553 | __netif_rx_schedule(dev); | ||
2554 | } else { | 2561 | } else { |
2555 | int i, active = 0; | 2562 | int i, active = 0; |
2556 | 2563 | ||
2557 | for (i = 0; i < hw->ports; i++) { | 2564 | for (i = 0; i < hw->ports; i++) { |
2558 | dev = hw->dev[i]; | 2565 | struct net_device *dev = hw->dev[i]; |
2559 | if (!netif_running(dev)) | 2566 | if (!netif_running(dev)) |
2560 | continue; | 2567 | continue; |
2561 | ++active; | 2568 | ++active; |
@@ -2605,11 +2612,11 @@ static void sky2_err_intr(struct sky2_hw *hw, u32 status) | |||
2605 | sky2_le_error(hw, 1, Q_XA2, TX_RING_SIZE); | 2612 | sky2_le_error(hw, 1, Q_XA2, TX_RING_SIZE); |
2606 | } | 2613 | } |
2607 | 2614 | ||
2608 | static int sky2_poll(struct net_device *dev0, int *budget) | 2615 | static int sky2_poll(struct napi_struct *napi, int work_limit) |
2609 | { | 2616 | { |
2610 | struct sky2_hw *hw = ((struct sky2_port *) netdev_priv(dev0))->hw; | 2617 | struct sky2_hw *hw = container_of(napi, struct sky2_hw, napi); |
2611 | int work_done; | ||
2612 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); | 2618 | u32 status = sky2_read32(hw, B0_Y2_SP_EISR); |
2619 | int work_done; | ||
2613 | 2620 | ||
2614 | if (unlikely(status & Y2_IS_ERROR)) | 2621 | if (unlikely(status & Y2_IS_ERROR)) |
2615 | sky2_err_intr(hw, status); | 2622 | sky2_err_intr(hw, status); |
@@ -2620,31 +2627,27 @@ static int sky2_poll(struct net_device *dev0, int *budget) | |||
2620 | if (status & Y2_IS_IRQ_PHY2) | 2627 | if (status & Y2_IS_IRQ_PHY2) |
2621 | sky2_phy_intr(hw, 1); | 2628 | sky2_phy_intr(hw, 1); |
2622 | 2629 | ||
2623 | work_done = sky2_status_intr(hw, min(dev0->quota, *budget)); | 2630 | work_done = sky2_status_intr(hw, work_limit); |
2624 | *budget -= work_done; | ||
2625 | dev0->quota -= work_done; | ||
2626 | 2631 | ||
2627 | /* More work? */ | 2632 | /* More work? */ |
2628 | if (hw->st_idx != sky2_read16(hw, STAT_PUT_IDX)) | 2633 | if (hw->st_idx == sky2_read16(hw, STAT_PUT_IDX)) { |
2629 | return 1; | 2634 | /* Bug/Errata workaround? |
2635 | * Need to kick the TX irq moderation timer. | ||
2636 | */ | ||
2637 | if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { | ||
2638 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); | ||
2639 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); | ||
2640 | } | ||
2630 | 2641 | ||
2631 | /* Bug/Errata workaround? | 2642 | napi_complete(napi); |
2632 | * Need to kick the TX irq moderation timer. | 2643 | sky2_read32(hw, B0_Y2_SP_LISR); |
2633 | */ | ||
2634 | if (sky2_read8(hw, STAT_TX_TIMER_CTRL) == TIM_START) { | ||
2635 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_STOP); | ||
2636 | sky2_write8(hw, STAT_TX_TIMER_CTRL, TIM_START); | ||
2637 | } | 2644 | } |
2638 | netif_rx_complete(dev0); | 2645 | return work_done; |
2639 | |||
2640 | sky2_read32(hw, B0_Y2_SP_LISR); | ||
2641 | return 0; | ||
2642 | } | 2646 | } |
2643 | 2647 | ||
2644 | static irqreturn_t sky2_intr(int irq, void *dev_id) | 2648 | static irqreturn_t sky2_intr(int irq, void *dev_id) |
2645 | { | 2649 | { |
2646 | struct sky2_hw *hw = dev_id; | 2650 | struct sky2_hw *hw = dev_id; |
2647 | struct net_device *dev0 = hw->dev[0]; | ||
2648 | u32 status; | 2651 | u32 status; |
2649 | 2652 | ||
2650 | /* Reading this mask interrupts as side effect */ | 2653 | /* Reading this mask interrupts as side effect */ |
@@ -2653,8 +2656,8 @@ static irqreturn_t sky2_intr(int irq, void *dev_id) | |||
2653 | return IRQ_NONE; | 2656 | return IRQ_NONE; |
2654 | 2657 | ||
2655 | prefetch(&hw->st_le[hw->st_idx]); | 2658 | prefetch(&hw->st_le[hw->st_idx]); |
2656 | if (likely(__netif_rx_schedule_prep(dev0))) | 2659 | |
2657 | __netif_rx_schedule(dev0); | 2660 | napi_schedule(&hw->napi); |
2658 | 2661 | ||
2659 | return IRQ_HANDLED; | 2662 | return IRQ_HANDLED; |
2660 | } | 2663 | } |
@@ -2663,10 +2666,8 @@ static irqreturn_t sky2_intr(int irq, void *dev_id) | |||
2663 | static void sky2_netpoll(struct net_device *dev) | 2666 | static void sky2_netpoll(struct net_device *dev) |
2664 | { | 2667 | { |
2665 | struct sky2_port *sky2 = netdev_priv(dev); | 2668 | struct sky2_port *sky2 = netdev_priv(dev); |
2666 | struct net_device *dev0 = sky2->hw->dev[0]; | ||
2667 | 2669 | ||
2668 | if (netif_running(dev) && __netif_rx_schedule_prep(dev0)) | 2670 | napi_schedule(&sky2->hw->napi); |
2669 | __netif_rx_schedule(dev0); | ||
2670 | } | 2671 | } |
2671 | #endif | 2672 | #endif |
2672 | 2673 | ||
@@ -2914,8 +2915,6 @@ static void sky2_restart(struct work_struct *work) | |||
2914 | sky2_write32(hw, B0_IMSK, 0); | 2915 | sky2_write32(hw, B0_IMSK, 0); |
2915 | sky2_read32(hw, B0_IMSK); | 2916 | sky2_read32(hw, B0_IMSK); |
2916 | 2917 | ||
2917 | netif_poll_disable(hw->dev[0]); | ||
2918 | |||
2919 | for (i = 0; i < hw->ports; i++) { | 2918 | for (i = 0; i < hw->ports; i++) { |
2920 | dev = hw->dev[i]; | 2919 | dev = hw->dev[i]; |
2921 | if (netif_running(dev)) | 2920 | if (netif_running(dev)) |
@@ -2924,7 +2923,6 @@ static void sky2_restart(struct work_struct *work) | |||
2924 | 2923 | ||
2925 | sky2_reset(hw); | 2924 | sky2_reset(hw); |
2926 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); | 2925 | sky2_write32(hw, B0_IMSK, Y2_IS_BASE); |
2927 | netif_poll_enable(hw->dev[0]); | ||
2928 | 2926 | ||
2929 | for (i = 0; i < hw->ports; i++) { | 2927 | for (i = 0; i < hw->ports; i++) { |
2930 | dev = hw->dev[i]; | 2928 | dev = hw->dev[i]; |
@@ -3735,7 +3733,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v) | |||
3735 | { | 3733 | { |
3736 | struct net_device *dev = seq->private; | 3734 | struct net_device *dev = seq->private; |
3737 | const struct sky2_port *sky2 = netdev_priv(dev); | 3735 | const struct sky2_port *sky2 = netdev_priv(dev); |
3738 | const struct sky2_hw *hw = sky2->hw; | 3736 | struct sky2_hw *hw = sky2->hw; |
3739 | unsigned port = sky2->port; | 3737 | unsigned port = sky2->port; |
3740 | unsigned idx, last; | 3738 | unsigned idx, last; |
3741 | int sop; | 3739 | int sop; |
@@ -3748,7 +3746,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v) | |||
3748 | sky2_read32(hw, B0_IMSK), | 3746 | sky2_read32(hw, B0_IMSK), |
3749 | sky2_read32(hw, B0_Y2_SP_ICR)); | 3747 | sky2_read32(hw, B0_Y2_SP_ICR)); |
3750 | 3748 | ||
3751 | netif_poll_disable(hw->dev[0]); | 3749 | napi_disable(&hw->napi); |
3752 | last = sky2_read16(hw, STAT_PUT_IDX); | 3750 | last = sky2_read16(hw, STAT_PUT_IDX); |
3753 | 3751 | ||
3754 | if (hw->st_idx == last) | 3752 | if (hw->st_idx == last) |
@@ -3818,7 +3816,7 @@ static int sky2_debug_show(struct seq_file *seq, void *v) | |||
3818 | last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)), | 3816 | last = sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_PUT_IDX)), |
3819 | sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX))); | 3817 | sky2_read16(hw, Y2_QADDR(rxqaddr[port], PREF_UNIT_LAST_IDX))); |
3820 | 3818 | ||
3821 | netif_poll_enable(hw->dev[0]); | 3819 | napi_enable(&hw->napi); |
3822 | return 0; | 3820 | return 0; |
3823 | } | 3821 | } |
3824 | 3822 | ||
@@ -3943,15 +3941,8 @@ static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw, | |||
3943 | SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops); | 3941 | SET_ETHTOOL_OPS(dev, &sky2_ethtool_ops); |
3944 | dev->tx_timeout = sky2_tx_timeout; | 3942 | dev->tx_timeout = sky2_tx_timeout; |
3945 | dev->watchdog_timeo = TX_WATCHDOG; | 3943 | dev->watchdog_timeo = TX_WATCHDOG; |
3946 | if (port == 0) | ||
3947 | dev->poll = sky2_poll; | ||
3948 | dev->weight = NAPI_WEIGHT; | ||
3949 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3944 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3950 | /* Network console (only works on port 0) | 3945 | dev->poll_controller = sky2_netpoll; |
3951 | * because netpoll makes assumptions about NAPI | ||
3952 | */ | ||
3953 | if (port == 0) | ||
3954 | dev->poll_controller = sky2_netpoll; | ||
3955 | #endif | 3946 | #endif |
3956 | 3947 | ||
3957 | sky2 = netdev_priv(dev); | 3948 | sky2 = netdev_priv(dev); |
@@ -4166,6 +4157,7 @@ static int __devinit sky2_probe(struct pci_dev *pdev, | |||
4166 | err = -ENOMEM; | 4157 | err = -ENOMEM; |
4167 | goto err_out_free_pci; | 4158 | goto err_out_free_pci; |
4168 | } | 4159 | } |
4160 | netif_napi_add(dev, &hw->napi, sky2_poll, NAPI_WEIGHT); | ||
4169 | 4161 | ||
4170 | if (!disable_msi && pci_enable_msi(pdev) == 0) { | 4162 | if (!disable_msi && pci_enable_msi(pdev) == 0) { |
4171 | err = sky2_test_msi(hw); | 4163 | err = sky2_test_msi(hw); |
@@ -4288,8 +4280,6 @@ static int sky2_suspend(struct pci_dev *pdev, pm_message_t state) | |||
4288 | if (!hw) | 4280 | if (!hw) |
4289 | return 0; | 4281 | return 0; |
4290 | 4282 | ||
4291 | netif_poll_disable(hw->dev[0]); | ||
4292 | |||
4293 | for (i = 0; i < hw->ports; i++) { | 4283 | for (i = 0; i < hw->ports; i++) { |
4294 | struct net_device *dev = hw->dev[i]; | 4284 | struct net_device *dev = hw->dev[i]; |
4295 | struct sky2_port *sky2 = netdev_priv(dev); | 4285 | struct sky2_port *sky2 = netdev_priv(dev); |
@@ -4356,8 +4346,6 @@ static int sky2_resume(struct pci_dev *pdev) | |||
4356 | } | 4346 | } |
4357 | } | 4347 | } |
4358 | 4348 | ||
4359 | netif_poll_enable(hw->dev[0]); | ||
4360 | |||
4361 | return 0; | 4349 | return 0; |
4362 | out: | 4350 | out: |
4363 | dev_err(&pdev->dev, "resume failed (%d)\n", err); | 4351 | dev_err(&pdev->dev, "resume failed (%d)\n", err); |
@@ -4374,7 +4362,7 @@ static void sky2_shutdown(struct pci_dev *pdev) | |||
4374 | if (!hw) | 4362 | if (!hw) |
4375 | return; | 4363 | return; |
4376 | 4364 | ||
4377 | netif_poll_disable(hw->dev[0]); | 4365 | napi_disable(&hw->napi); |
4378 | 4366 | ||
4379 | for (i = 0; i < hw->ports; i++) { | 4367 | for (i = 0; i < hw->ports; i++) { |
4380 | struct net_device *dev = hw->dev[i]; | 4368 | struct net_device *dev = hw->dev[i]; |