diff options
author | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:39:55 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-08 05:39:55 -0400 |
commit | c324b44c34050cf2a9b58830e11c974806bd85d8 (patch) | |
tree | 3ac45a783221283925cd698334a8f5e7dd4c1df8 /drivers/net/tg3.c | |
parent | 2fcf522509cceea524b6e7ece8fd6759b682175a (diff) | |
parent | caf39e87cc1182f7dae84eefc43ca14d54c78ef9 (diff) |
Merge /spare/repo/linux-2.6/
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 202 |
1 files changed, 132 insertions, 70 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index af8263a1580e..dc57352e5a97 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/ip.h> | 36 | #include <linux/ip.h> |
37 | #include <linux/tcp.h> | 37 | #include <linux/tcp.h> |
38 | #include <linux/workqueue.h> | 38 | #include <linux/workqueue.h> |
39 | #include <linux/prefetch.h> | ||
39 | 40 | ||
40 | #include <net/checksum.h> | 41 | #include <net/checksum.h> |
41 | 42 | ||
@@ -66,8 +67,8 @@ | |||
66 | 67 | ||
67 | #define DRV_MODULE_NAME "tg3" | 68 | #define DRV_MODULE_NAME "tg3" |
68 | #define PFX DRV_MODULE_NAME ": " | 69 | #define PFX DRV_MODULE_NAME ": " |
69 | #define DRV_MODULE_VERSION "3.37" | 70 | #define DRV_MODULE_VERSION "3.39" |
70 | #define DRV_MODULE_RELDATE "August 25, 2005" | 71 | #define DRV_MODULE_RELDATE "September 5, 2005" |
71 | 72 | ||
72 | #define TG3_DEF_MAC_MODE 0 | 73 | #define TG3_DEF_MAC_MODE 0 |
73 | #define TG3_DEF_RX_MODE 0 | 74 | #define TG3_DEF_RX_MODE 0 |
@@ -121,12 +122,9 @@ | |||
121 | TG3_RX_RCB_RING_SIZE(tp)) | 122 | TG3_RX_RCB_RING_SIZE(tp)) |
122 | #define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \ | 123 | #define TG3_TX_RING_BYTES (sizeof(struct tg3_tx_buffer_desc) * \ |
123 | TG3_TX_RING_SIZE) | 124 | TG3_TX_RING_SIZE) |
124 | #define TX_RING_GAP(TP) \ | ||
125 | (TG3_TX_RING_SIZE - (TP)->tx_pending) | ||
126 | #define TX_BUFFS_AVAIL(TP) \ | 125 | #define TX_BUFFS_AVAIL(TP) \ |
127 | (((TP)->tx_cons <= (TP)->tx_prod) ? \ | 126 | ((TP)->tx_pending - \ |
128 | (TP)->tx_cons + (TP)->tx_pending - (TP)->tx_prod : \ | 127 | (((TP)->tx_prod - (TP)->tx_cons) & (TG3_TX_RING_SIZE - 1))) |
129 | (TP)->tx_cons - (TP)->tx_prod - TX_RING_GAP(TP)) | ||
130 | #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) | 128 | #define NEXT_TX(N) (((N) + 1) & (TG3_TX_RING_SIZE - 1)) |
131 | 129 | ||
132 | #define RX_PKT_BUF_SZ (1536 + tp->rx_offset + 64) | 130 | #define RX_PKT_BUF_SZ (1536 + tp->rx_offset + 64) |
@@ -490,7 +488,8 @@ static void tg3_disable_ints(struct tg3 *tp) | |||
490 | 488 | ||
491 | static inline void tg3_cond_int(struct tg3 *tp) | 489 | static inline void tg3_cond_int(struct tg3 *tp) |
492 | { | 490 | { |
493 | if (tp->hw_status->status & SD_STATUS_UPDATED) | 491 | if (!(tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) && |
492 | (tp->hw_status->status & SD_STATUS_UPDATED)) | ||
494 | tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); | 493 | tw32(GRC_LOCAL_CTRL, tp->grc_local_ctrl | GRC_LCLCTRL_SETINT); |
495 | } | 494 | } |
496 | 495 | ||
@@ -2880,9 +2879,13 @@ static void tg3_tx(struct tg3 *tp) | |||
2880 | 2879 | ||
2881 | tp->tx_cons = sw_idx; | 2880 | tp->tx_cons = sw_idx; |
2882 | 2881 | ||
2883 | if (netif_queue_stopped(tp->dev) && | 2882 | if (unlikely(netif_queue_stopped(tp->dev))) { |
2884 | (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH)) | 2883 | spin_lock(&tp->tx_lock); |
2885 | netif_wake_queue(tp->dev); | 2884 | if (netif_queue_stopped(tp->dev) && |
2885 | (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH)) | ||
2886 | netif_wake_queue(tp->dev); | ||
2887 | spin_unlock(&tp->tx_lock); | ||
2888 | } | ||
2886 | } | 2889 | } |
2887 | 2890 | ||
2888 | /* Returns size of skb allocated or < 0 on error. | 2891 | /* Returns size of skb allocated or < 0 on error. |
@@ -3198,9 +3201,7 @@ static int tg3_poll(struct net_device *netdev, int *budget) | |||
3198 | 3201 | ||
3199 | /* run TX completion thread */ | 3202 | /* run TX completion thread */ |
3200 | if (sblk->idx[0].tx_consumer != tp->tx_cons) { | 3203 | if (sblk->idx[0].tx_consumer != tp->tx_cons) { |
3201 | spin_lock(&tp->tx_lock); | ||
3202 | tg3_tx(tp); | 3204 | tg3_tx(tp); |
3203 | spin_unlock(&tp->tx_lock); | ||
3204 | } | 3205 | } |
3205 | 3206 | ||
3206 | /* run RX thread, within the bounds set by NAPI. | 3207 | /* run RX thread, within the bounds set by NAPI. |
@@ -3220,18 +3221,17 @@ static int tg3_poll(struct net_device *netdev, int *budget) | |||
3220 | netdev->quota -= work_done; | 3221 | netdev->quota -= work_done; |
3221 | } | 3222 | } |
3222 | 3223 | ||
3223 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | 3224 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) { |
3224 | tp->last_tag = sblk->status_tag; | 3225 | tp->last_tag = sblk->status_tag; |
3225 | rmb(); | 3226 | rmb(); |
3226 | sblk->status &= ~SD_STATUS_UPDATED; | 3227 | } else |
3228 | sblk->status &= ~SD_STATUS_UPDATED; | ||
3227 | 3229 | ||
3228 | /* if no more work, tell net stack and NIC we're done */ | 3230 | /* if no more work, tell net stack and NIC we're done */ |
3229 | done = !tg3_has_work(tp); | 3231 | done = !tg3_has_work(tp); |
3230 | if (done) { | 3232 | if (done) { |
3231 | spin_lock(&tp->lock); | ||
3232 | netif_rx_complete(netdev); | 3233 | netif_rx_complete(netdev); |
3233 | tg3_restart_ints(tp); | 3234 | tg3_restart_ints(tp); |
3234 | spin_unlock(&tp->lock); | ||
3235 | } | 3235 | } |
3236 | 3236 | ||
3237 | return (done ? 0 : 1); | 3237 | return (done ? 0 : 1); |
@@ -3279,8 +3279,9 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) | |||
3279 | { | 3279 | { |
3280 | struct net_device *dev = dev_id; | 3280 | struct net_device *dev = dev_id; |
3281 | struct tg3 *tp = netdev_priv(dev); | 3281 | struct tg3 *tp = netdev_priv(dev); |
3282 | struct tg3_hw_status *sblk = tp->hw_status; | ||
3283 | 3282 | ||
3283 | prefetch(tp->hw_status); | ||
3284 | prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); | ||
3284 | /* | 3285 | /* |
3285 | * Writing any value to intr-mbox-0 clears PCI INTA# and | 3286 | * Writing any value to intr-mbox-0 clears PCI INTA# and |
3286 | * chip-internal interrupt pending events. | 3287 | * chip-internal interrupt pending events. |
@@ -3289,19 +3290,9 @@ static irqreturn_t tg3_msi(int irq, void *dev_id, struct pt_regs *regs) | |||
3289 | * event coalescing. | 3290 | * event coalescing. |
3290 | */ | 3291 | */ |
3291 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); | 3292 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, 0x00000001); |
3292 | tp->last_tag = sblk->status_tag; | 3293 | if (likely(!tg3_irq_sync(tp))) |
3293 | rmb(); | ||
3294 | if (tg3_irq_sync(tp)) | ||
3295 | goto out; | ||
3296 | sblk->status &= ~SD_STATUS_UPDATED; | ||
3297 | if (likely(tg3_has_work(tp))) | ||
3298 | netif_rx_schedule(dev); /* schedule NAPI poll */ | 3294 | netif_rx_schedule(dev); /* schedule NAPI poll */ |
3299 | else { | 3295 | |
3300 | /* No work, re-enable interrupts. */ | ||
3301 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | ||
3302 | tp->last_tag << 24); | ||
3303 | } | ||
3304 | out: | ||
3305 | return IRQ_RETVAL(1); | 3296 | return IRQ_RETVAL(1); |
3306 | } | 3297 | } |
3307 | 3298 | ||
@@ -3331,9 +3322,10 @@ static irqreturn_t tg3_interrupt(int irq, void *dev_id, struct pt_regs *regs) | |||
3331 | if (tg3_irq_sync(tp)) | 3322 | if (tg3_irq_sync(tp)) |
3332 | goto out; | 3323 | goto out; |
3333 | sblk->status &= ~SD_STATUS_UPDATED; | 3324 | sblk->status &= ~SD_STATUS_UPDATED; |
3334 | if (likely(tg3_has_work(tp))) | 3325 | if (likely(tg3_has_work(tp))) { |
3326 | prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); | ||
3335 | netif_rx_schedule(dev); /* schedule NAPI poll */ | 3327 | netif_rx_schedule(dev); /* schedule NAPI poll */ |
3336 | else { | 3328 | } else { |
3337 | /* No work, shared interrupt perhaps? re-enable | 3329 | /* No work, shared interrupt perhaps? re-enable |
3338 | * interrupts, and flush that PCI write | 3330 | * interrupts, and flush that PCI write |
3339 | */ | 3331 | */ |
@@ -3359,7 +3351,7 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r | |||
3359 | * Reading the PCI State register will confirm whether the | 3351 | * Reading the PCI State register will confirm whether the |
3360 | * interrupt is ours and will flush the status block. | 3352 | * interrupt is ours and will flush the status block. |
3361 | */ | 3353 | */ |
3362 | if ((sblk->status & SD_STATUS_UPDATED) || | 3354 | if ((sblk->status_tag != tp->last_tag) || |
3363 | !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { | 3355 | !(tr32(TG3PCI_PCISTATE) & PCISTATE_INT_NOT_ACTIVE)) { |
3364 | /* | 3356 | /* |
3365 | * writing any value to intr-mbox-0 clears PCI INTA# and | 3357 | * writing any value to intr-mbox-0 clears PCI INTA# and |
@@ -3370,19 +3362,17 @@ static irqreturn_t tg3_interrupt_tagged(int irq, void *dev_id, struct pt_regs *r | |||
3370 | */ | 3362 | */ |
3371 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3363 | tw32_mailbox(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, |
3372 | 0x00000001); | 3364 | 0x00000001); |
3373 | tp->last_tag = sblk->status_tag; | ||
3374 | rmb(); | ||
3375 | if (tg3_irq_sync(tp)) | 3365 | if (tg3_irq_sync(tp)) |
3376 | goto out; | 3366 | goto out; |
3377 | sblk->status &= ~SD_STATUS_UPDATED; | 3367 | if (netif_rx_schedule_prep(dev)) { |
3378 | if (likely(tg3_has_work(tp))) | 3368 | prefetch(&tp->rx_rcb[tp->rx_rcb_ptr]); |
3379 | netif_rx_schedule(dev); /* schedule NAPI poll */ | 3369 | /* Update last_tag to mark that this status has been |
3380 | else { | 3370 | * seen. Because interrupt may be shared, we may be |
3381 | /* no work, shared interrupt perhaps? re-enable | 3371 | * racing with tg3_poll(), so only update last_tag |
3382 | * interrupts, and flush that PCI write | 3372 | * if tg3_poll() is not scheduled. |
3383 | */ | 3373 | */ |
3384 | tw32_mailbox_f(MAILBOX_INTERRUPT_0 + TG3_64BIT_REG_LOW, | 3374 | tp->last_tag = sblk->status_tag; |
3385 | tp->last_tag << 24); | 3375 | __netif_rx_schedule(dev); |
3386 | } | 3376 | } |
3387 | } else { /* shared interrupt */ | 3377 | } else { /* shared interrupt */ |
3388 | handled = 0; | 3378 | handled = 0; |
@@ -3716,8 +3706,11 @@ static int tg3_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
3716 | tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); | 3706 | tw32_tx_mbox((MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW), entry); |
3717 | 3707 | ||
3718 | tp->tx_prod = entry; | 3708 | tp->tx_prod = entry; |
3719 | if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1)) | 3709 | if (TX_BUFFS_AVAIL(tp) <= (MAX_SKB_FRAGS + 1)) { |
3720 | netif_stop_queue(dev); | 3710 | netif_stop_queue(dev); |
3711 | if (TX_BUFFS_AVAIL(tp) > TG3_TX_WAKEUP_THRESH) | ||
3712 | netif_wake_queue(tp->dev); | ||
3713 | } | ||
3721 | 3714 | ||
3722 | out_unlock: | 3715 | out_unlock: |
3723 | mmiowb(); | 3716 | mmiowb(); |
@@ -5960,7 +5953,7 @@ static int tg3_reset_hw(struct tg3 *tp) | |||
5960 | tw32(MAC_LED_CTRL, tp->led_ctrl); | 5953 | tw32(MAC_LED_CTRL, tp->led_ctrl); |
5961 | 5954 | ||
5962 | tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); | 5955 | tw32(MAC_MI_STAT, MAC_MI_STAT_LNKSTAT_ATTN_ENAB); |
5963 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) { | 5956 | if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { |
5964 | tw32_f(MAC_RX_MODE, RX_MODE_RESET); | 5957 | tw32_f(MAC_RX_MODE, RX_MODE_RESET); |
5965 | udelay(10); | 5958 | udelay(10); |
5966 | } | 5959 | } |
@@ -6242,6 +6235,7 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
6242 | if (err) | 6235 | if (err) |
6243 | return err; | 6236 | return err; |
6244 | 6237 | ||
6238 | tp->hw_status->status &= ~SD_STATUS_UPDATED; | ||
6245 | tg3_enable_ints(tp); | 6239 | tg3_enable_ints(tp); |
6246 | 6240 | ||
6247 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | 6241 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | |
@@ -7557,6 +7551,38 @@ static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) | |||
7557 | } | 7551 | } |
7558 | } | 7552 | } |
7559 | 7553 | ||
7554 | static int tg3_phys_id(struct net_device *dev, u32 data) | ||
7555 | { | ||
7556 | struct tg3 *tp = netdev_priv(dev); | ||
7557 | int i; | ||
7558 | |||
7559 | if (!netif_running(tp->dev)) | ||
7560 | return -EAGAIN; | ||
7561 | |||
7562 | if (data == 0) | ||
7563 | data = 2; | ||
7564 | |||
7565 | for (i = 0; i < (data * 2); i++) { | ||
7566 | if ((i % 2) == 0) | ||
7567 | tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | | ||
7568 | LED_CTRL_1000MBPS_ON | | ||
7569 | LED_CTRL_100MBPS_ON | | ||
7570 | LED_CTRL_10MBPS_ON | | ||
7571 | LED_CTRL_TRAFFIC_OVERRIDE | | ||
7572 | LED_CTRL_TRAFFIC_BLINK | | ||
7573 | LED_CTRL_TRAFFIC_LED); | ||
7574 | |||
7575 | else | ||
7576 | tw32(MAC_LED_CTRL, LED_CTRL_LNKLED_OVERRIDE | | ||
7577 | LED_CTRL_TRAFFIC_OVERRIDE); | ||
7578 | |||
7579 | if (msleep_interruptible(500)) | ||
7580 | break; | ||
7581 | } | ||
7582 | tw32(MAC_LED_CTRL, tp->led_ctrl); | ||
7583 | return 0; | ||
7584 | } | ||
7585 | |||
7560 | static void tg3_get_ethtool_stats (struct net_device *dev, | 7586 | static void tg3_get_ethtool_stats (struct net_device *dev, |
7561 | struct ethtool_stats *estats, u64 *tmp_stats) | 7587 | struct ethtool_stats *estats, u64 *tmp_stats) |
7562 | { | 7588 | { |
@@ -7616,7 +7642,7 @@ static int tg3_test_link(struct tg3 *tp) | |||
7616 | if (!netif_running(tp->dev)) | 7642 | if (!netif_running(tp->dev)) |
7617 | return -ENODEV; | 7643 | return -ENODEV; |
7618 | 7644 | ||
7619 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) | 7645 | if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) |
7620 | max = TG3_SERDES_TIMEOUT_SEC; | 7646 | max = TG3_SERDES_TIMEOUT_SEC; |
7621 | else | 7647 | else |
7622 | max = TG3_COPPER_TIMEOUT_SEC; | 7648 | max = TG3_COPPER_TIMEOUT_SEC; |
@@ -7901,9 +7927,12 @@ static int tg3_test_memory(struct tg3 *tp) | |||
7901 | return err; | 7927 | return err; |
7902 | } | 7928 | } |
7903 | 7929 | ||
7904 | static int tg3_test_loopback(struct tg3 *tp) | 7930 | #define TG3_MAC_LOOPBACK 0 |
7931 | #define TG3_PHY_LOOPBACK 1 | ||
7932 | |||
7933 | static int tg3_run_loopback(struct tg3 *tp, int loopback_mode) | ||
7905 | { | 7934 | { |
7906 | u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key; | 7935 | u32 mac_mode, rx_start_idx, rx_idx, tx_idx, opaque_key; |
7907 | u32 desc_idx; | 7936 | u32 desc_idx; |
7908 | struct sk_buff *skb, *rx_skb; | 7937 | struct sk_buff *skb, *rx_skb; |
7909 | u8 *tx_data; | 7938 | u8 *tx_data; |
@@ -7911,18 +7940,26 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7911 | int num_pkts, tx_len, rx_len, i, err; | 7940 | int num_pkts, tx_len, rx_len, i, err; |
7912 | struct tg3_rx_buffer_desc *desc; | 7941 | struct tg3_rx_buffer_desc *desc; |
7913 | 7942 | ||
7914 | if (!netif_running(tp->dev)) | 7943 | if (loopback_mode == TG3_MAC_LOOPBACK) { |
7915 | return -ENODEV; | 7944 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | |
7945 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | | ||
7946 | MAC_MODE_PORT_MODE_GMII; | ||
7947 | tw32(MAC_MODE, mac_mode); | ||
7948 | } else if (loopback_mode == TG3_PHY_LOOPBACK) { | ||
7949 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | ||
7950 | MAC_MODE_LINK_POLARITY | MAC_MODE_PORT_MODE_GMII; | ||
7951 | if ((tp->phy_id & PHY_ID_MASK) == PHY_ID_BCM5401) | ||
7952 | mac_mode &= ~MAC_MODE_LINK_POLARITY; | ||
7953 | tw32(MAC_MODE, mac_mode); | ||
7954 | |||
7955 | tg3_writephy(tp, MII_BMCR, BMCR_LOOPBACK | BMCR_FULLDPLX | | ||
7956 | BMCR_SPEED1000); | ||
7957 | } | ||
7958 | else | ||
7959 | return -EINVAL; | ||
7916 | 7960 | ||
7917 | err = -EIO; | 7961 | err = -EIO; |
7918 | 7962 | ||
7919 | tg3_reset_hw(tp); | ||
7920 | |||
7921 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | ||
7922 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | | ||
7923 | MAC_MODE_PORT_MODE_GMII; | ||
7924 | tw32(MAC_MODE, mac_mode); | ||
7925 | |||
7926 | tx_len = 1514; | 7963 | tx_len = 1514; |
7927 | skb = dev_alloc_skb(tx_len); | 7964 | skb = dev_alloc_skb(tx_len); |
7928 | tx_data = skb_put(skb, tx_len); | 7965 | tx_data = skb_put(skb, tx_len); |
@@ -7943,15 +7980,15 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7943 | 7980 | ||
7944 | rx_start_idx = tp->hw_status->idx[0].rx_producer; | 7981 | rx_start_idx = tp->hw_status->idx[0].rx_producer; |
7945 | 7982 | ||
7946 | send_idx = 0; | ||
7947 | num_pkts = 0; | 7983 | num_pkts = 0; |
7948 | 7984 | ||
7949 | tg3_set_txd(tp, send_idx, map, tx_len, 0, 1); | 7985 | tg3_set_txd(tp, tp->tx_prod, map, tx_len, 0, 1); |
7950 | 7986 | ||
7951 | send_idx++; | 7987 | tp->tx_prod++; |
7952 | num_pkts++; | 7988 | num_pkts++; |
7953 | 7989 | ||
7954 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); | 7990 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, |
7991 | tp->tx_prod); | ||
7955 | tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); | 7992 | tr32_mailbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); |
7956 | 7993 | ||
7957 | udelay(10); | 7994 | udelay(10); |
@@ -7964,7 +8001,7 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7964 | 8001 | ||
7965 | tx_idx = tp->hw_status->idx[0].tx_consumer; | 8002 | tx_idx = tp->hw_status->idx[0].tx_consumer; |
7966 | rx_idx = tp->hw_status->idx[0].rx_producer; | 8003 | rx_idx = tp->hw_status->idx[0].rx_producer; |
7967 | if ((tx_idx == send_idx) && | 8004 | if ((tx_idx == tp->tx_prod) && |
7968 | (rx_idx == (rx_start_idx + num_pkts))) | 8005 | (rx_idx == (rx_start_idx + num_pkts))) |
7969 | break; | 8006 | break; |
7970 | } | 8007 | } |
@@ -7972,7 +8009,7 @@ static int tg3_test_loopback(struct tg3 *tp) | |||
7972 | pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); | 8009 | pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); |
7973 | dev_kfree_skb(skb); | 8010 | dev_kfree_skb(skb); |
7974 | 8011 | ||
7975 | if (tx_idx != send_idx) | 8012 | if (tx_idx != tp->tx_prod) |
7976 | goto out; | 8013 | goto out; |
7977 | 8014 | ||
7978 | if (rx_idx != rx_start_idx + num_pkts) | 8015 | if (rx_idx != rx_start_idx + num_pkts) |
@@ -8008,6 +8045,30 @@ out: | |||
8008 | return err; | 8045 | return err; |
8009 | } | 8046 | } |
8010 | 8047 | ||
8048 | #define TG3_MAC_LOOPBACK_FAILED 1 | ||
8049 | #define TG3_PHY_LOOPBACK_FAILED 2 | ||
8050 | #define TG3_LOOPBACK_FAILED (TG3_MAC_LOOPBACK_FAILED | \ | ||
8051 | TG3_PHY_LOOPBACK_FAILED) | ||
8052 | |||
8053 | static int tg3_test_loopback(struct tg3 *tp) | ||
8054 | { | ||
8055 | int err = 0; | ||
8056 | |||
8057 | if (!netif_running(tp->dev)) | ||
8058 | return TG3_LOOPBACK_FAILED; | ||
8059 | |||
8060 | tg3_reset_hw(tp); | ||
8061 | |||
8062 | if (tg3_run_loopback(tp, TG3_MAC_LOOPBACK)) | ||
8063 | err |= TG3_MAC_LOOPBACK_FAILED; | ||
8064 | if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES)) { | ||
8065 | if (tg3_run_loopback(tp, TG3_PHY_LOOPBACK)) | ||
8066 | err |= TG3_PHY_LOOPBACK_FAILED; | ||
8067 | } | ||
8068 | |||
8069 | return err; | ||
8070 | } | ||
8071 | |||
8011 | static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | 8072 | static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, |
8012 | u64 *data) | 8073 | u64 *data) |
8013 | { | 8074 | { |
@@ -8048,10 +8109,8 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
8048 | etest->flags |= ETH_TEST_FL_FAILED; | 8109 | etest->flags |= ETH_TEST_FL_FAILED; |
8049 | data[3] = 1; | 8110 | data[3] = 1; |
8050 | } | 8111 | } |
8051 | if (tg3_test_loopback(tp) != 0) { | 8112 | if ((data[4] = tg3_test_loopback(tp)) != 0) |
8052 | etest->flags |= ETH_TEST_FL_FAILED; | 8113 | etest->flags |= ETH_TEST_FL_FAILED; |
8053 | data[4] = 1; | ||
8054 | } | ||
8055 | 8114 | ||
8056 | tg3_full_unlock(tp); | 8115 | tg3_full_unlock(tp); |
8057 | 8116 | ||
@@ -8239,6 +8298,7 @@ static struct ethtool_ops tg3_ethtool_ops = { | |||
8239 | .self_test_count = tg3_get_test_count, | 8298 | .self_test_count = tg3_get_test_count, |
8240 | .self_test = tg3_self_test, | 8299 | .self_test = tg3_self_test, |
8241 | .get_strings = tg3_get_strings, | 8300 | .get_strings = tg3_get_strings, |
8301 | .phys_id = tg3_phys_id, | ||
8242 | .get_stats_count = tg3_get_stats_count, | 8302 | .get_stats_count = tg3_get_stats_count, |
8243 | .get_ethtool_stats = tg3_get_ethtool_stats, | 8303 | .get_ethtool_stats = tg3_get_ethtool_stats, |
8244 | .get_coalesce = tg3_get_coalesce, | 8304 | .get_coalesce = tg3_get_coalesce, |
@@ -8303,7 +8363,8 @@ static void __devinit tg3_get_nvram_info(struct tg3 *tp) | |||
8303 | tw32(NVRAM_CFG1, nvcfg1); | 8363 | tw32(NVRAM_CFG1, nvcfg1); |
8304 | } | 8364 | } |
8305 | 8365 | ||
8306 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) { | 8366 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) || |
8367 | (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)) { | ||
8307 | switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) { | 8368 | switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) { |
8308 | case FLASH_VENDOR_ATMEL_FLASH_BUFFERED: | 8369 | case FLASH_VENDOR_ATMEL_FLASH_BUFFERED: |
8309 | tp->nvram_jedecnum = JEDEC_ATMEL; | 8370 | tp->nvram_jedecnum = JEDEC_ATMEL; |
@@ -8717,8 +8778,9 @@ static int tg3_nvram_write_block_buffered(struct tg3 *tp, u32 offset, u32 len, | |||
8717 | if (i == (len - 4)) | 8778 | if (i == (len - 4)) |
8718 | nvram_cmd |= NVRAM_CMD_LAST; | 8779 | nvram_cmd |= NVRAM_CMD_LAST; |
8719 | 8780 | ||
8720 | if ((tp->nvram_jedecnum == JEDEC_ST) && | 8781 | if ((GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5752) && |
8721 | (nvram_cmd & NVRAM_CMD_FIRST)) { | 8782 | (tp->nvram_jedecnum == JEDEC_ST) && |
8783 | (nvram_cmd & NVRAM_CMD_FIRST)) { | ||
8722 | 8784 | ||
8723 | if ((ret = tg3_nvram_exec_cmd(tp, | 8785 | if ((ret = tg3_nvram_exec_cmd(tp, |
8724 | NVRAM_CMD_WREN | NVRAM_CMD_GO | | 8786 | NVRAM_CMD_WREN | NVRAM_CMD_GO | |