diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 124 |
1 files changed, 92 insertions, 32 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f645921aff8b..6f97962dd06b 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -68,8 +68,8 @@ | |||
68 | 68 | ||
69 | #define DRV_MODULE_NAME "tg3" | 69 | #define DRV_MODULE_NAME "tg3" |
70 | #define PFX DRV_MODULE_NAME ": " | 70 | #define PFX DRV_MODULE_NAME ": " |
71 | #define DRV_MODULE_VERSION "3.62" | 71 | #define DRV_MODULE_VERSION "3.64" |
72 | #define DRV_MODULE_RELDATE "June 30, 2006" | 72 | #define DRV_MODULE_RELDATE "July 31, 2006" |
73 | 73 | ||
74 | #define TG3_DEF_MAC_MODE 0 | 74 | #define TG3_DEF_MAC_MODE 0 |
75 | #define TG3_DEF_RX_MODE 0 | 75 | #define TG3_DEF_RX_MODE 0 |
@@ -3097,7 +3097,7 @@ static int tg3_alloc_rx_skb(struct tg3 *tp, u32 opaque_key, | |||
3097 | * Callers depend upon this behavior and assume that | 3097 | * Callers depend upon this behavior and assume that |
3098 | * we leave everything unchanged if we fail. | 3098 | * we leave everything unchanged if we fail. |
3099 | */ | 3099 | */ |
3100 | skb = dev_alloc_skb(skb_size); | 3100 | skb = netdev_alloc_skb(tp->dev, skb_size); |
3101 | if (skb == NULL) | 3101 | if (skb == NULL) |
3102 | return -ENOMEM; | 3102 | return -ENOMEM; |
3103 | 3103 | ||
@@ -3270,7 +3270,7 @@ static int tg3_rx(struct tg3 *tp, int budget) | |||
3270 | tg3_recycle_rx(tp, opaque_key, | 3270 | tg3_recycle_rx(tp, opaque_key, |
3271 | desc_idx, *post_ptr); | 3271 | desc_idx, *post_ptr); |
3272 | 3272 | ||
3273 | copy_skb = dev_alloc_skb(len + 2); | 3273 | copy_skb = netdev_alloc_skb(tp->dev, len + 2); |
3274 | if (copy_skb == NULL) | 3274 | if (copy_skb == NULL) |
3275 | goto drop_it_no_recycle; | 3275 | goto drop_it_no_recycle; |
3276 | 3276 | ||
@@ -3590,6 +3590,28 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, | |||
3590 | static int tg3_init_hw(struct tg3 *, int); | 3590 | static int tg3_init_hw(struct tg3 *, int); |
3591 | static int tg3_halt(struct tg3 *, int, int); | 3591 | static int tg3_halt(struct tg3 *, int, int); |
3592 | 3592 | ||
3593 | /* Restart hardware after configuration changes, self-test, etc. | ||
3594 | * Invoked with tp->lock held. | ||
3595 | */ | ||
3596 | static int tg3_restart_hw(struct tg3 *tp, int reset_phy) | ||
3597 | { | ||
3598 | int err; | ||
3599 | |||
3600 | err = tg3_init_hw(tp, reset_phy); | ||
3601 | if (err) { | ||
3602 | printk(KERN_ERR PFX "%s: Failed to re-initialize device, " | ||
3603 | "aborting.\n", tp->dev->name); | ||
3604 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
3605 | tg3_full_unlock(tp); | ||
3606 | del_timer_sync(&tp->timer); | ||
3607 | tp->irq_sync = 0; | ||
3608 | netif_poll_enable(tp->dev); | ||
3609 | dev_close(tp->dev); | ||
3610 | tg3_full_lock(tp, 0); | ||
3611 | } | ||
3612 | return err; | ||
3613 | } | ||
3614 | |||
3593 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3615 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3594 | static void tg3_poll_controller(struct net_device *dev) | 3616 | static void tg3_poll_controller(struct net_device *dev) |
3595 | { | 3617 | { |
@@ -3630,13 +3652,15 @@ static void tg3_reset_task(void *_data) | |||
3630 | } | 3652 | } |
3631 | 3653 | ||
3632 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); | 3654 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); |
3633 | tg3_init_hw(tp, 1); | 3655 | if (tg3_init_hw(tp, 1)) |
3656 | goto out; | ||
3634 | 3657 | ||
3635 | tg3_netif_start(tp); | 3658 | tg3_netif_start(tp); |
3636 | 3659 | ||
3637 | if (restart_timer) | 3660 | if (restart_timer) |
3638 | mod_timer(&tp->timer, jiffies + 1); | 3661 | mod_timer(&tp->timer, jiffies + 1); |
3639 | 3662 | ||
3663 | out: | ||
3640 | tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; | 3664 | tp->tg3_flags &= ~TG3_FLAG_IN_RESET_TASK; |
3641 | 3665 | ||
3642 | tg3_full_unlock(tp); | 3666 | tg3_full_unlock(tp); |
@@ -4124,6 +4148,7 @@ static inline void tg3_set_mtu(struct net_device *dev, struct tg3 *tp, | |||
4124 | static int tg3_change_mtu(struct net_device *dev, int new_mtu) | 4148 | static int tg3_change_mtu(struct net_device *dev, int new_mtu) |
4125 | { | 4149 | { |
4126 | struct tg3 *tp = netdev_priv(dev); | 4150 | struct tg3 *tp = netdev_priv(dev); |
4151 | int err; | ||
4127 | 4152 | ||
4128 | if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) | 4153 | if (new_mtu < TG3_MIN_MTU || new_mtu > TG3_MAX_MTU(tp)) |
4129 | return -EINVAL; | 4154 | return -EINVAL; |
@@ -4144,13 +4169,14 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
4144 | 4169 | ||
4145 | tg3_set_mtu(dev, tp, new_mtu); | 4170 | tg3_set_mtu(dev, tp, new_mtu); |
4146 | 4171 | ||
4147 | tg3_init_hw(tp, 0); | 4172 | err = tg3_restart_hw(tp, 0); |
4148 | 4173 | ||
4149 | tg3_netif_start(tp); | 4174 | if (!err) |
4175 | tg3_netif_start(tp); | ||
4150 | 4176 | ||
4151 | tg3_full_unlock(tp); | 4177 | tg3_full_unlock(tp); |
4152 | 4178 | ||
4153 | return 0; | 4179 | return err; |
4154 | } | 4180 | } |
4155 | 4181 | ||
4156 | /* Free up pending packets in all rx/tx rings. | 4182 | /* Free up pending packets in all rx/tx rings. |
@@ -4232,7 +4258,7 @@ static void tg3_free_rings(struct tg3 *tp) | |||
4232 | * end up in the driver. tp->{tx,}lock are held and thus | 4258 | * end up in the driver. tp->{tx,}lock are held and thus |
4233 | * we may not sleep. | 4259 | * we may not sleep. |
4234 | */ | 4260 | */ |
4235 | static void tg3_init_rings(struct tg3 *tp) | 4261 | static int tg3_init_rings(struct tg3 *tp) |
4236 | { | 4262 | { |
4237 | u32 i; | 4263 | u32 i; |
4238 | 4264 | ||
@@ -4281,18 +4307,38 @@ static void tg3_init_rings(struct tg3 *tp) | |||
4281 | 4307 | ||
4282 | /* Now allocate fresh SKBs for each rx ring. */ | 4308 | /* Now allocate fresh SKBs for each rx ring. */ |
4283 | for (i = 0; i < tp->rx_pending; i++) { | 4309 | for (i = 0; i < tp->rx_pending; i++) { |
4284 | if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, | 4310 | if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_STD, -1, i) < 0) { |
4285 | -1, i) < 0) | 4311 | printk(KERN_WARNING PFX |
4312 | "%s: Using a smaller RX standard ring, " | ||
4313 | "only %d out of %d buffers were allocated " | ||
4314 | "successfully.\n", | ||
4315 | tp->dev->name, i, tp->rx_pending); | ||
4316 | if (i == 0) | ||
4317 | return -ENOMEM; | ||
4318 | tp->rx_pending = i; | ||
4286 | break; | 4319 | break; |
4320 | } | ||
4287 | } | 4321 | } |
4288 | 4322 | ||
4289 | if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) { | 4323 | if (tp->tg3_flags & TG3_FLAG_JUMBO_RING_ENABLE) { |
4290 | for (i = 0; i < tp->rx_jumbo_pending; i++) { | 4324 | for (i = 0; i < tp->rx_jumbo_pending; i++) { |
4291 | if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO, | 4325 | if (tg3_alloc_rx_skb(tp, RXD_OPAQUE_RING_JUMBO, |
4292 | -1, i) < 0) | 4326 | -1, i) < 0) { |
4327 | printk(KERN_WARNING PFX | ||
4328 | "%s: Using a smaller RX jumbo ring, " | ||
4329 | "only %d out of %d buffers were " | ||
4330 | "allocated successfully.\n", | ||
4331 | tp->dev->name, i, tp->rx_jumbo_pending); | ||
4332 | if (i == 0) { | ||
4333 | tg3_free_rings(tp); | ||
4334 | return -ENOMEM; | ||
4335 | } | ||
4336 | tp->rx_jumbo_pending = i; | ||
4293 | break; | 4337 | break; |
4338 | } | ||
4294 | } | 4339 | } |
4295 | } | 4340 | } |
4341 | return 0; | ||
4296 | } | 4342 | } |
4297 | 4343 | ||
4298 | /* | 4344 | /* |
@@ -5815,6 +5861,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) | |||
5815 | { | 5861 | { |
5816 | struct tg3 *tp = netdev_priv(dev); | 5862 | struct tg3 *tp = netdev_priv(dev); |
5817 | struct sockaddr *addr = p; | 5863 | struct sockaddr *addr = p; |
5864 | int err = 0; | ||
5818 | 5865 | ||
5819 | if (!is_valid_ether_addr(addr->sa_data)) | 5866 | if (!is_valid_ether_addr(addr->sa_data)) |
5820 | return -EINVAL; | 5867 | return -EINVAL; |
@@ -5832,9 +5879,9 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) | |||
5832 | tg3_full_lock(tp, 1); | 5879 | tg3_full_lock(tp, 1); |
5833 | 5880 | ||
5834 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 5881 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
5835 | tg3_init_hw(tp, 0); | 5882 | err = tg3_restart_hw(tp, 0); |
5836 | 5883 | if (!err) | |
5837 | tg3_netif_start(tp); | 5884 | tg3_netif_start(tp); |
5838 | tg3_full_unlock(tp); | 5885 | tg3_full_unlock(tp); |
5839 | } else { | 5886 | } else { |
5840 | spin_lock_bh(&tp->lock); | 5887 | spin_lock_bh(&tp->lock); |
@@ -5842,7 +5889,7 @@ static int tg3_set_mac_addr(struct net_device *dev, void *p) | |||
5842 | spin_unlock_bh(&tp->lock); | 5889 | spin_unlock_bh(&tp->lock); |
5843 | } | 5890 | } |
5844 | 5891 | ||
5845 | return 0; | 5892 | return err; |
5846 | } | 5893 | } |
5847 | 5894 | ||
5848 | /* tp->lock is held. */ | 5895 | /* tp->lock is held. */ |
@@ -5942,7 +5989,9 @@ static int tg3_reset_hw(struct tg3 *tp, int reset_phy) | |||
5942 | * can only do this after the hardware has been | 5989 | * can only do this after the hardware has been |
5943 | * successfully reset. | 5990 | * successfully reset. |
5944 | */ | 5991 | */ |
5945 | tg3_init_rings(tp); | 5992 | err = tg3_init_rings(tp); |
5993 | if (err) | ||
5994 | return err; | ||
5946 | 5995 | ||
5947 | /* This value is determined during the probe time DMA | 5996 | /* This value is determined during the probe time DMA |
5948 | * engine test, tg3_test_dma. | 5997 | * engine test, tg3_test_dma. |
@@ -7956,7 +8005,7 @@ static void tg3_get_ringparam(struct net_device *dev, struct ethtool_ringparam * | |||
7956 | static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) | 8005 | static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering) |
7957 | { | 8006 | { |
7958 | struct tg3 *tp = netdev_priv(dev); | 8007 | struct tg3 *tp = netdev_priv(dev); |
7959 | int irq_sync = 0; | 8008 | int irq_sync = 0, err = 0; |
7960 | 8009 | ||
7961 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || | 8010 | if ((ering->rx_pending > TG3_RX_RING_SIZE - 1) || |
7962 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || | 8011 | (ering->rx_jumbo_pending > TG3_RX_JUMBO_RING_SIZE - 1) || |
@@ -7980,13 +8029,14 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
7980 | 8029 | ||
7981 | if (netif_running(dev)) { | 8030 | if (netif_running(dev)) { |
7982 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 8031 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
7983 | tg3_init_hw(tp, 1); | 8032 | err = tg3_restart_hw(tp, 1); |
7984 | tg3_netif_start(tp); | 8033 | if (!err) |
8034 | tg3_netif_start(tp); | ||
7985 | } | 8035 | } |
7986 | 8036 | ||
7987 | tg3_full_unlock(tp); | 8037 | tg3_full_unlock(tp); |
7988 | 8038 | ||
7989 | return 0; | 8039 | return err; |
7990 | } | 8040 | } |
7991 | 8041 | ||
7992 | static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) | 8042 | static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) |
@@ -8001,7 +8051,7 @@ static void tg3_get_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
8001 | static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) | 8051 | static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam *epause) |
8002 | { | 8052 | { |
8003 | struct tg3 *tp = netdev_priv(dev); | 8053 | struct tg3 *tp = netdev_priv(dev); |
8004 | int irq_sync = 0; | 8054 | int irq_sync = 0, err = 0; |
8005 | 8055 | ||
8006 | if (netif_running(dev)) { | 8056 | if (netif_running(dev)) { |
8007 | tg3_netif_stop(tp); | 8057 | tg3_netif_stop(tp); |
@@ -8025,13 +8075,14 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
8025 | 8075 | ||
8026 | if (netif_running(dev)) { | 8076 | if (netif_running(dev)) { |
8027 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 8077 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
8028 | tg3_init_hw(tp, 1); | 8078 | err = tg3_restart_hw(tp, 1); |
8029 | tg3_netif_start(tp); | 8079 | if (!err) |
8080 | tg3_netif_start(tp); | ||
8030 | } | 8081 | } |
8031 | 8082 | ||
8032 | tg3_full_unlock(tp); | 8083 | tg3_full_unlock(tp); |
8033 | 8084 | ||
8034 | return 0; | 8085 | return err; |
8035 | } | 8086 | } |
8036 | 8087 | ||
8037 | static u32 tg3_get_rx_csum(struct net_device *dev) | 8088 | static u32 tg3_get_rx_csum(struct net_device *dev) |
@@ -8567,7 +8618,7 @@ static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | |||
8567 | err = -EIO; | 8618 | err = -EIO; |
8568 | 8619 | ||
8569 | tx_len = 1514; | 8620 | tx_len = 1514; |
8570 | skb = dev_alloc_skb(tx_len); | 8621 | skb = netdev_alloc_skb(tp->dev, tx_len); |
8571 | if (!skb) | 8622 | if (!skb) |
8572 | return -ENOMEM; | 8623 | return -ENOMEM; |
8573 | 8624 | ||
@@ -8666,7 +8717,9 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
8666 | if (!netif_running(tp->dev)) | 8717 | if (!netif_running(tp->dev)) |
8667 | return TG3_LOOPBACK_FAILED; | 8718 | return TG3_LOOPBACK_FAILED; |
8668 | 8719 | ||
8669 | tg3_reset_hw(tp, 1); | 8720 | err = tg3_reset_hw(tp, 1); |
8721 | if (err) | ||
8722 | return TG3_LOOPBACK_FAILED; | ||
8670 | 8723 | ||
8671 | if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) | 8724 | if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) |
8672 | err |= TG3_MAC_LOOPBACK_FAILED; | 8725 | err |= TG3_MAC_LOOPBACK_FAILED; |
@@ -8740,8 +8793,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
8740 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | 8793 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
8741 | if (netif_running(dev)) { | 8794 | if (netif_running(dev)) { |
8742 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 8795 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
8743 | tg3_init_hw(tp, 1); | 8796 | if (!tg3_restart_hw(tp, 1)) |
8744 | tg3_netif_start(tp); | 8797 | tg3_netif_start(tp); |
8745 | } | 8798 | } |
8746 | 8799 | ||
8747 | tg3_full_unlock(tp); | 8800 | tg3_full_unlock(tp); |
@@ -10078,6 +10131,8 @@ static int __devinit tg3_get_invariants(struct tg3 *tp) | |||
10078 | static struct pci_device_id write_reorder_chipsets[] = { | 10131 | static struct pci_device_id write_reorder_chipsets[] = { |
10079 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, | 10132 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, |
10080 | PCI_DEVICE_ID_AMD_FE_GATE_700C) }, | 10133 | PCI_DEVICE_ID_AMD_FE_GATE_700C) }, |
10134 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, | ||
10135 | PCI_DEVICE_ID_AMD_8131_BRIDGE) }, | ||
10081 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, | 10136 | { PCI_DEVICE(PCI_VENDOR_ID_VIA, |
10082 | PCI_DEVICE_ID_VIA_8385_0) }, | 10137 | PCI_DEVICE_ID_VIA_8385_0) }, |
10083 | { }, | 10138 | { }, |
@@ -11697,7 +11752,8 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
11697 | tg3_full_lock(tp, 0); | 11752 | tg3_full_lock(tp, 0); |
11698 | 11753 | ||
11699 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 11754 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
11700 | tg3_init_hw(tp, 1); | 11755 | if (tg3_restart_hw(tp, 1)) |
11756 | goto out; | ||
11701 | 11757 | ||
11702 | tp->timer.expires = jiffies + tp->timer_offset; | 11758 | tp->timer.expires = jiffies + tp->timer_offset; |
11703 | add_timer(&tp->timer); | 11759 | add_timer(&tp->timer); |
@@ -11705,6 +11761,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
11705 | netif_device_attach(dev); | 11761 | netif_device_attach(dev); |
11706 | tg3_netif_start(tp); | 11762 | tg3_netif_start(tp); |
11707 | 11763 | ||
11764 | out: | ||
11708 | tg3_full_unlock(tp); | 11765 | tg3_full_unlock(tp); |
11709 | } | 11766 | } |
11710 | 11767 | ||
@@ -11731,16 +11788,19 @@ static int tg3_resume(struct pci_dev *pdev) | |||
11731 | tg3_full_lock(tp, 0); | 11788 | tg3_full_lock(tp, 0); |
11732 | 11789 | ||
11733 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | 11790 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; |
11734 | tg3_init_hw(tp, 1); | 11791 | err = tg3_restart_hw(tp, 1); |
11792 | if (err) | ||
11793 | goto out; | ||
11735 | 11794 | ||
11736 | tp->timer.expires = jiffies + tp->timer_offset; | 11795 | tp->timer.expires = jiffies + tp->timer_offset; |
11737 | add_timer(&tp->timer); | 11796 | add_timer(&tp->timer); |
11738 | 11797 | ||
11739 | tg3_netif_start(tp); | 11798 | tg3_netif_start(tp); |
11740 | 11799 | ||
11800 | out: | ||
11741 | tg3_full_unlock(tp); | 11801 | tg3_full_unlock(tp); |
11742 | 11802 | ||
11743 | return 0; | 11803 | return err; |
11744 | } | 11804 | } |
11745 | 11805 | ||
11746 | static struct pci_driver tg3_driver = { | 11806 | static struct pci_driver tg3_driver = { |