diff options
Diffstat (limited to 'drivers/net/tg3.c')
-rw-r--r-- | drivers/net/tg3.c | 610 |
1 files changed, 590 insertions, 20 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index f10dd74988c4..a0b8848049c9 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
@@ -7,7 +7,12 @@ | |||
7 | * Copyright (C) 2005 Broadcom Corporation. | 7 | * Copyright (C) 2005 Broadcom Corporation. |
8 | * | 8 | * |
9 | * Firmware is: | 9 | * Firmware is: |
10 | * Copyright (C) 2000-2003 Broadcom Corporation. | 10 | * Derived from proprietary unpublished source code, |
11 | * Copyright (C) 2000-2003 Broadcom Corporation. | ||
12 | * | ||
13 | * Permission is hereby granted for the distribution of this firmware | ||
14 | * data in hexadecimal or equivalent format, provided this copyright | ||
15 | * notice is accompanying it. | ||
11 | */ | 16 | */ |
12 | 17 | ||
13 | #include <linux/config.h> | 18 | #include <linux/config.h> |
@@ -61,8 +66,8 @@ | |||
61 | 66 | ||
62 | #define DRV_MODULE_NAME "tg3" | 67 | #define DRV_MODULE_NAME "tg3" |
63 | #define PFX DRV_MODULE_NAME ": " | 68 | #define PFX DRV_MODULE_NAME ": " |
64 | #define DRV_MODULE_VERSION "3.29" | 69 | #define DRV_MODULE_VERSION "3.31" |
65 | #define DRV_MODULE_RELDATE "May 23, 2005" | 70 | #define DRV_MODULE_RELDATE "June 8, 2005" |
66 | 71 | ||
67 | #define TG3_DEF_MAC_MODE 0 | 72 | #define TG3_DEF_MAC_MODE 0 |
68 | #define TG3_DEF_RX_MODE 0 | 73 | #define TG3_DEF_RX_MODE 0 |
@@ -133,6 +138,8 @@ | |||
133 | /* number of ETHTOOL_GSTATS u64's */ | 138 | /* number of ETHTOOL_GSTATS u64's */ |
134 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) | 139 | #define TG3_NUM_STATS (sizeof(struct tg3_ethtool_stats)/sizeof(u64)) |
135 | 140 | ||
141 | #define TG3_NUM_TEST 6 | ||
142 | |||
136 | static char version[] __devinitdata = | 143 | static char version[] __devinitdata = |
137 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; | 144 | DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; |
138 | 145 | ||
@@ -316,6 +323,17 @@ static struct { | |||
316 | { "nic_tx_threshold_hit" } | 323 | { "nic_tx_threshold_hit" } |
317 | }; | 324 | }; |
318 | 325 | ||
326 | static struct { | ||
327 | const char string[ETH_GSTRING_LEN]; | ||
328 | } ethtool_test_keys[TG3_NUM_TEST] = { | ||
329 | { "nvram test (online) " }, | ||
330 | { "link test (online) " }, | ||
331 | { "register test (offline)" }, | ||
332 | { "memory test (offline)" }, | ||
333 | { "loopback test (offline)" }, | ||
334 | { "interrupt test (offline)" }, | ||
335 | }; | ||
336 | |||
319 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) | 337 | static void tg3_write_indirect_reg32(struct tg3 *tp, u32 off, u32 val) |
320 | { | 338 | { |
321 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { | 339 | if ((tp->tg3_flags & TG3_FLAG_PCIX_TARGET_HWBUG) != 0) { |
@@ -3070,7 +3088,7 @@ static irqreturn_t tg3_test_isr(int irq, void *dev_id, | |||
3070 | } | 3088 | } |
3071 | 3089 | ||
3072 | static int tg3_init_hw(struct tg3 *); | 3090 | static int tg3_init_hw(struct tg3 *); |
3073 | static int tg3_halt(struct tg3 *, int); | 3091 | static int tg3_halt(struct tg3 *, int, int); |
3074 | 3092 | ||
3075 | #ifdef CONFIG_NET_POLL_CONTROLLER | 3093 | #ifdef CONFIG_NET_POLL_CONTROLLER |
3076 | static void tg3_poll_controller(struct net_device *dev) | 3094 | static void tg3_poll_controller(struct net_device *dev) |
@@ -3094,7 +3112,7 @@ static void tg3_reset_task(void *_data) | |||
3094 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; | 3112 | restart_timer = tp->tg3_flags2 & TG3_FLG2_RESTART_TIMER; |
3095 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; | 3113 | tp->tg3_flags2 &= ~TG3_FLG2_RESTART_TIMER; |
3096 | 3114 | ||
3097 | tg3_halt(tp, 0); | 3115 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 0); |
3098 | tg3_init_hw(tp); | 3116 | tg3_init_hw(tp); |
3099 | 3117 | ||
3100 | tg3_netif_start(tp); | 3118 | tg3_netif_start(tp); |
@@ -3440,7 +3458,7 @@ static int tg3_change_mtu(struct net_device *dev, int new_mtu) | |||
3440 | spin_lock_irq(&tp->lock); | 3458 | spin_lock_irq(&tp->lock); |
3441 | spin_lock(&tp->tx_lock); | 3459 | spin_lock(&tp->tx_lock); |
3442 | 3460 | ||
3443 | tg3_halt(tp, 1); | 3461 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
3444 | 3462 | ||
3445 | tg3_set_mtu(dev, tp, new_mtu); | 3463 | tg3_set_mtu(dev, tp, new_mtu); |
3446 | 3464 | ||
@@ -4131,19 +4149,19 @@ static void tg3_stop_fw(struct tg3 *tp) | |||
4131 | } | 4149 | } |
4132 | 4150 | ||
4133 | /* tp->lock is held. */ | 4151 | /* tp->lock is held. */ |
4134 | static int tg3_halt(struct tg3 *tp, int silent) | 4152 | static int tg3_halt(struct tg3 *tp, int kind, int silent) |
4135 | { | 4153 | { |
4136 | int err; | 4154 | int err; |
4137 | 4155 | ||
4138 | tg3_stop_fw(tp); | 4156 | tg3_stop_fw(tp); |
4139 | 4157 | ||
4140 | tg3_write_sig_pre_reset(tp, RESET_KIND_SHUTDOWN); | 4158 | tg3_write_sig_pre_reset(tp, kind); |
4141 | 4159 | ||
4142 | tg3_abort_hw(tp, silent); | 4160 | tg3_abort_hw(tp, silent); |
4143 | err = tg3_chip_reset(tp); | 4161 | err = tg3_chip_reset(tp); |
4144 | 4162 | ||
4145 | tg3_write_sig_legacy(tp, RESET_KIND_SHUTDOWN); | 4163 | tg3_write_sig_legacy(tp, kind); |
4146 | tg3_write_sig_post_reset(tp, RESET_KIND_SHUTDOWN); | 4164 | tg3_write_sig_post_reset(tp, kind); |
4147 | 4165 | ||
4148 | if (err) | 4166 | if (err) |
4149 | return err; | 4167 | return err; |
@@ -4357,7 +4375,12 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
4357 | */ | 4375 | */ |
4358 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; | 4376 | tp->tg3_flags |= TG3_FLAG_PCIX_TARGET_HWBUG; |
4359 | 4377 | ||
4378 | /* It is possible that bootcode is still loading at this point. | ||
4379 | * Get the nvram lock first before halting the cpu. | ||
4380 | */ | ||
4381 | tg3_nvram_lock(tp); | ||
4360 | err = tg3_halt_cpu(tp, cpu_base); | 4382 | err = tg3_halt_cpu(tp, cpu_base); |
4383 | tg3_nvram_unlock(tp); | ||
4361 | if (err) | 4384 | if (err) |
4362 | goto out; | 4385 | goto out; |
4363 | 4386 | ||
@@ -5881,6 +5904,9 @@ static int tg3_test_interrupt(struct tg3 *tp) | |||
5881 | int err, i; | 5904 | int err, i; |
5882 | u32 int_mbox = 0; | 5905 | u32 int_mbox = 0; |
5883 | 5906 | ||
5907 | if (!netif_running(dev)) | ||
5908 | return -ENODEV; | ||
5909 | |||
5884 | tg3_disable_ints(tp); | 5910 | tg3_disable_ints(tp); |
5885 | 5911 | ||
5886 | free_irq(tp->pdev->irq, dev); | 5912 | free_irq(tp->pdev->irq, dev); |
@@ -5984,7 +6010,7 @@ static int tg3_test_msi(struct tg3 *tp) | |||
5984 | spin_lock_irq(&tp->lock); | 6010 | spin_lock_irq(&tp->lock); |
5985 | spin_lock(&tp->tx_lock); | 6011 | spin_lock(&tp->tx_lock); |
5986 | 6012 | ||
5987 | tg3_halt(tp, 1); | 6013 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
5988 | err = tg3_init_hw(tp); | 6014 | err = tg3_init_hw(tp); |
5989 | 6015 | ||
5990 | spin_unlock(&tp->tx_lock); | 6016 | spin_unlock(&tp->tx_lock); |
@@ -6060,7 +6086,7 @@ static int tg3_open(struct net_device *dev) | |||
6060 | 6086 | ||
6061 | err = tg3_init_hw(tp); | 6087 | err = tg3_init_hw(tp); |
6062 | if (err) { | 6088 | if (err) { |
6063 | tg3_halt(tp, 1); | 6089 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6064 | tg3_free_rings(tp); | 6090 | tg3_free_rings(tp); |
6065 | } else { | 6091 | } else { |
6066 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) | 6092 | if (tp->tg3_flags & TG3_FLAG_TAGGED_STATUS) |
@@ -6104,7 +6130,7 @@ static int tg3_open(struct net_device *dev) | |||
6104 | pci_disable_msi(tp->pdev); | 6130 | pci_disable_msi(tp->pdev); |
6105 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; | 6131 | tp->tg3_flags2 &= ~TG3_FLG2_USING_MSI; |
6106 | } | 6132 | } |
6107 | tg3_halt(tp, 1); | 6133 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6108 | tg3_free_rings(tp); | 6134 | tg3_free_rings(tp); |
6109 | tg3_free_consistent(tp); | 6135 | tg3_free_consistent(tp); |
6110 | 6136 | ||
@@ -6377,7 +6403,7 @@ static int tg3_close(struct net_device *dev) | |||
6377 | 6403 | ||
6378 | tg3_disable_ints(tp); | 6404 | tg3_disable_ints(tp); |
6379 | 6405 | ||
6380 | tg3_halt(tp, 1); | 6406 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
6381 | tg3_free_rings(tp); | 6407 | tg3_free_rings(tp); |
6382 | tp->tg3_flags &= | 6408 | tp->tg3_flags &= |
6383 | ~(TG3_FLAG_INIT_COMPLETE | | 6409 | ~(TG3_FLAG_INIT_COMPLETE | |
@@ -7097,7 +7123,7 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e | |||
7097 | tp->tx_pending = ering->tx_pending; | 7123 | tp->tx_pending = ering->tx_pending; |
7098 | 7124 | ||
7099 | if (netif_running(dev)) { | 7125 | if (netif_running(dev)) { |
7100 | tg3_halt(tp, 1); | 7126 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
7101 | tg3_init_hw(tp); | 7127 | tg3_init_hw(tp); |
7102 | tg3_netif_start(tp); | 7128 | tg3_netif_start(tp); |
7103 | } | 7129 | } |
@@ -7140,7 +7166,7 @@ static int tg3_set_pauseparam(struct net_device *dev, struct ethtool_pauseparam | |||
7140 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; | 7166 | tp->tg3_flags &= ~TG3_FLAG_TX_PAUSE; |
7141 | 7167 | ||
7142 | if (netif_running(dev)) { | 7168 | if (netif_running(dev)) { |
7143 | tg3_halt(tp, 1); | 7169 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
7144 | tg3_init_hw(tp); | 7170 | tg3_init_hw(tp); |
7145 | tg3_netif_start(tp); | 7171 | tg3_netif_start(tp); |
7146 | } | 7172 | } |
@@ -7199,12 +7225,20 @@ static int tg3_get_stats_count (struct net_device *dev) | |||
7199 | return TG3_NUM_STATS; | 7225 | return TG3_NUM_STATS; |
7200 | } | 7226 | } |
7201 | 7227 | ||
7228 | static int tg3_get_test_count (struct net_device *dev) | ||
7229 | { | ||
7230 | return TG3_NUM_TEST; | ||
7231 | } | ||
7232 | |||
7202 | static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) | 7233 | static void tg3_get_strings (struct net_device *dev, u32 stringset, u8 *buf) |
7203 | { | 7234 | { |
7204 | switch (stringset) { | 7235 | switch (stringset) { |
7205 | case ETH_SS_STATS: | 7236 | case ETH_SS_STATS: |
7206 | memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); | 7237 | memcpy(buf, ðtool_stats_keys, sizeof(ethtool_stats_keys)); |
7207 | break; | 7238 | break; |
7239 | case ETH_SS_TEST: | ||
7240 | memcpy(buf, ðtool_test_keys, sizeof(ethtool_test_keys)); | ||
7241 | break; | ||
7208 | default: | 7242 | default: |
7209 | WARN_ON(1); /* we need a WARN() */ | 7243 | WARN_ON(1); /* we need a WARN() */ |
7210 | break; | 7244 | break; |
@@ -7218,6 +7252,516 @@ static void tg3_get_ethtool_stats (struct net_device *dev, | |||
7218 | memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); | 7252 | memcpy(tmp_stats, tg3_get_estats(tp), sizeof(tp->estats)); |
7219 | } | 7253 | } |
7220 | 7254 | ||
7255 | #define NVRAM_TEST_SIZE 0x100 | ||
7256 | |||
7257 | static int tg3_test_nvram(struct tg3 *tp) | ||
7258 | { | ||
7259 | u32 *buf, csum; | ||
7260 | int i, j, err = 0; | ||
7261 | |||
7262 | buf = kmalloc(NVRAM_TEST_SIZE, GFP_KERNEL); | ||
7263 | if (buf == NULL) | ||
7264 | return -ENOMEM; | ||
7265 | |||
7266 | for (i = 0, j = 0; i < NVRAM_TEST_SIZE; i += 4, j++) { | ||
7267 | u32 val; | ||
7268 | |||
7269 | if ((err = tg3_nvram_read(tp, i, &val)) != 0) | ||
7270 | break; | ||
7271 | buf[j] = cpu_to_le32(val); | ||
7272 | } | ||
7273 | if (i < NVRAM_TEST_SIZE) | ||
7274 | goto out; | ||
7275 | |||
7276 | err = -EIO; | ||
7277 | if (cpu_to_be32(buf[0]) != TG3_EEPROM_MAGIC) | ||
7278 | goto out; | ||
7279 | |||
7280 | /* Bootstrap checksum at offset 0x10 */ | ||
7281 | csum = calc_crc((unsigned char *) buf, 0x10); | ||
7282 | if(csum != cpu_to_le32(buf[0x10/4])) | ||
7283 | goto out; | ||
7284 | |||
7285 | /* Manufacturing block starts at offset 0x74, checksum at 0xfc */ | ||
7286 | csum = calc_crc((unsigned char *) &buf[0x74/4], 0x88); | ||
7287 | if (csum != cpu_to_le32(buf[0xfc/4])) | ||
7288 | goto out; | ||
7289 | |||
7290 | err = 0; | ||
7291 | |||
7292 | out: | ||
7293 | kfree(buf); | ||
7294 | return err; | ||
7295 | } | ||
7296 | |||
7297 | #define TG3_SERDES_TIMEOUT_SEC 2 | ||
7298 | #define TG3_COPPER_TIMEOUT_SEC 6 | ||
7299 | |||
7300 | static int tg3_test_link(struct tg3 *tp) | ||
7301 | { | ||
7302 | int i, max; | ||
7303 | |||
7304 | if (!netif_running(tp->dev)) | ||
7305 | return -ENODEV; | ||
7306 | |||
7307 | if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) | ||
7308 | max = TG3_SERDES_TIMEOUT_SEC; | ||
7309 | else | ||
7310 | max = TG3_COPPER_TIMEOUT_SEC; | ||
7311 | |||
7312 | for (i = 0; i < max; i++) { | ||
7313 | if (netif_carrier_ok(tp->dev)) | ||
7314 | return 0; | ||
7315 | |||
7316 | if (msleep_interruptible(1000)) | ||
7317 | break; | ||
7318 | } | ||
7319 | |||
7320 | return -EIO; | ||
7321 | } | ||
7322 | |||
7323 | /* Only test the commonly used registers */ | ||
7324 | static int tg3_test_registers(struct tg3 *tp) | ||
7325 | { | ||
7326 | int i, is_5705; | ||
7327 | u32 offset, read_mask, write_mask, val, save_val, read_val; | ||
7328 | static struct { | ||
7329 | u16 offset; | ||
7330 | u16 flags; | ||
7331 | #define TG3_FL_5705 0x1 | ||
7332 | #define TG3_FL_NOT_5705 0x2 | ||
7333 | #define TG3_FL_NOT_5788 0x4 | ||
7334 | u32 read_mask; | ||
7335 | u32 write_mask; | ||
7336 | } reg_tbl[] = { | ||
7337 | /* MAC Control Registers */ | ||
7338 | { MAC_MODE, TG3_FL_NOT_5705, | ||
7339 | 0x00000000, 0x00ef6f8c }, | ||
7340 | { MAC_MODE, TG3_FL_5705, | ||
7341 | 0x00000000, 0x01ef6b8c }, | ||
7342 | { MAC_STATUS, TG3_FL_NOT_5705, | ||
7343 | 0x03800107, 0x00000000 }, | ||
7344 | { MAC_STATUS, TG3_FL_5705, | ||
7345 | 0x03800100, 0x00000000 }, | ||
7346 | { MAC_ADDR_0_HIGH, 0x0000, | ||
7347 | 0x00000000, 0x0000ffff }, | ||
7348 | { MAC_ADDR_0_LOW, 0x0000, | ||
7349 | 0x00000000, 0xffffffff }, | ||
7350 | { MAC_RX_MTU_SIZE, 0x0000, | ||
7351 | 0x00000000, 0x0000ffff }, | ||
7352 | { MAC_TX_MODE, 0x0000, | ||
7353 | 0x00000000, 0x00000070 }, | ||
7354 | { MAC_TX_LENGTHS, 0x0000, | ||
7355 | 0x00000000, 0x00003fff }, | ||
7356 | { MAC_RX_MODE, TG3_FL_NOT_5705, | ||
7357 | 0x00000000, 0x000007fc }, | ||
7358 | { MAC_RX_MODE, TG3_FL_5705, | ||
7359 | 0x00000000, 0x000007dc }, | ||
7360 | { MAC_HASH_REG_0, 0x0000, | ||
7361 | 0x00000000, 0xffffffff }, | ||
7362 | { MAC_HASH_REG_1, 0x0000, | ||
7363 | 0x00000000, 0xffffffff }, | ||
7364 | { MAC_HASH_REG_2, 0x0000, | ||
7365 | 0x00000000, 0xffffffff }, | ||
7366 | { MAC_HASH_REG_3, 0x0000, | ||
7367 | 0x00000000, 0xffffffff }, | ||
7368 | |||
7369 | /* Receive Data and Receive BD Initiator Control Registers. */ | ||
7370 | { RCVDBDI_JUMBO_BD+0, TG3_FL_NOT_5705, | ||
7371 | 0x00000000, 0xffffffff }, | ||
7372 | { RCVDBDI_JUMBO_BD+4, TG3_FL_NOT_5705, | ||
7373 | 0x00000000, 0xffffffff }, | ||
7374 | { RCVDBDI_JUMBO_BD+8, TG3_FL_NOT_5705, | ||
7375 | 0x00000000, 0x00000003 }, | ||
7376 | { RCVDBDI_JUMBO_BD+0xc, TG3_FL_NOT_5705, | ||
7377 | 0x00000000, 0xffffffff }, | ||
7378 | { RCVDBDI_STD_BD+0, 0x0000, | ||
7379 | 0x00000000, 0xffffffff }, | ||
7380 | { RCVDBDI_STD_BD+4, 0x0000, | ||
7381 | 0x00000000, 0xffffffff }, | ||
7382 | { RCVDBDI_STD_BD+8, 0x0000, | ||
7383 | 0x00000000, 0xffff0002 }, | ||
7384 | { RCVDBDI_STD_BD+0xc, 0x0000, | ||
7385 | 0x00000000, 0xffffffff }, | ||
7386 | |||
7387 | /* Receive BD Initiator Control Registers. */ | ||
7388 | { RCVBDI_STD_THRESH, TG3_FL_NOT_5705, | ||
7389 | 0x00000000, 0xffffffff }, | ||
7390 | { RCVBDI_STD_THRESH, TG3_FL_5705, | ||
7391 | 0x00000000, 0x000003ff }, | ||
7392 | { RCVBDI_JUMBO_THRESH, TG3_FL_NOT_5705, | ||
7393 | 0x00000000, 0xffffffff }, | ||
7394 | |||
7395 | /* Host Coalescing Control Registers. */ | ||
7396 | { HOSTCC_MODE, TG3_FL_NOT_5705, | ||
7397 | 0x00000000, 0x00000004 }, | ||
7398 | { HOSTCC_MODE, TG3_FL_5705, | ||
7399 | 0x00000000, 0x000000f6 }, | ||
7400 | { HOSTCC_RXCOL_TICKS, TG3_FL_NOT_5705, | ||
7401 | 0x00000000, 0xffffffff }, | ||
7402 | { HOSTCC_RXCOL_TICKS, TG3_FL_5705, | ||
7403 | 0x00000000, 0x000003ff }, | ||
7404 | { HOSTCC_TXCOL_TICKS, TG3_FL_NOT_5705, | ||
7405 | 0x00000000, 0xffffffff }, | ||
7406 | { HOSTCC_TXCOL_TICKS, TG3_FL_5705, | ||
7407 | 0x00000000, 0x000003ff }, | ||
7408 | { HOSTCC_RXMAX_FRAMES, TG3_FL_NOT_5705, | ||
7409 | 0x00000000, 0xffffffff }, | ||
7410 | { HOSTCC_RXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7411 | 0x00000000, 0x000000ff }, | ||
7412 | { HOSTCC_TXMAX_FRAMES, TG3_FL_NOT_5705, | ||
7413 | 0x00000000, 0xffffffff }, | ||
7414 | { HOSTCC_TXMAX_FRAMES, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7415 | 0x00000000, 0x000000ff }, | ||
7416 | { HOSTCC_RXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
7417 | 0x00000000, 0xffffffff }, | ||
7418 | { HOSTCC_TXCOAL_TICK_INT, TG3_FL_NOT_5705, | ||
7419 | 0x00000000, 0xffffffff }, | ||
7420 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
7421 | 0x00000000, 0xffffffff }, | ||
7422 | { HOSTCC_RXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7423 | 0x00000000, 0x000000ff }, | ||
7424 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_NOT_5705, | ||
7425 | 0x00000000, 0xffffffff }, | ||
7426 | { HOSTCC_TXCOAL_MAXF_INT, TG3_FL_5705 | TG3_FL_NOT_5788, | ||
7427 | 0x00000000, 0x000000ff }, | ||
7428 | { HOSTCC_STAT_COAL_TICKS, TG3_FL_NOT_5705, | ||
7429 | 0x00000000, 0xffffffff }, | ||
7430 | { HOSTCC_STATS_BLK_HOST_ADDR, TG3_FL_NOT_5705, | ||
7431 | 0x00000000, 0xffffffff }, | ||
7432 | { HOSTCC_STATS_BLK_HOST_ADDR+4, TG3_FL_NOT_5705, | ||
7433 | 0x00000000, 0xffffffff }, | ||
7434 | { HOSTCC_STATUS_BLK_HOST_ADDR, 0x0000, | ||
7435 | 0x00000000, 0xffffffff }, | ||
7436 | { HOSTCC_STATUS_BLK_HOST_ADDR+4, 0x0000, | ||
7437 | 0x00000000, 0xffffffff }, | ||
7438 | { HOSTCC_STATS_BLK_NIC_ADDR, 0x0000, | ||
7439 | 0xffffffff, 0x00000000 }, | ||
7440 | { HOSTCC_STATUS_BLK_NIC_ADDR, 0x0000, | ||
7441 | 0xffffffff, 0x00000000 }, | ||
7442 | |||
7443 | /* Buffer Manager Control Registers. */ | ||
7444 | { BUFMGR_MB_POOL_ADDR, 0x0000, | ||
7445 | 0x00000000, 0x007fff80 }, | ||
7446 | { BUFMGR_MB_POOL_SIZE, 0x0000, | ||
7447 | 0x00000000, 0x007fffff }, | ||
7448 | { BUFMGR_MB_RDMA_LOW_WATER, 0x0000, | ||
7449 | 0x00000000, 0x0000003f }, | ||
7450 | { BUFMGR_MB_MACRX_LOW_WATER, 0x0000, | ||
7451 | 0x00000000, 0x000001ff }, | ||
7452 | { BUFMGR_MB_HIGH_WATER, 0x0000, | ||
7453 | 0x00000000, 0x000001ff }, | ||
7454 | { BUFMGR_DMA_DESC_POOL_ADDR, TG3_FL_NOT_5705, | ||
7455 | 0xffffffff, 0x00000000 }, | ||
7456 | { BUFMGR_DMA_DESC_POOL_SIZE, TG3_FL_NOT_5705, | ||
7457 | 0xffffffff, 0x00000000 }, | ||
7458 | |||
7459 | /* Mailbox Registers */ | ||
7460 | { GRCMBOX_RCVSTD_PROD_IDX+4, 0x0000, | ||
7461 | 0x00000000, 0x000001ff }, | ||
7462 | { GRCMBOX_RCVJUMBO_PROD_IDX+4, TG3_FL_NOT_5705, | ||
7463 | 0x00000000, 0x000001ff }, | ||
7464 | { GRCMBOX_RCVRET_CON_IDX_0+4, 0x0000, | ||
7465 | 0x00000000, 0x000007ff }, | ||
7466 | { GRCMBOX_SNDHOST_PROD_IDX_0+4, 0x0000, | ||
7467 | 0x00000000, 0x000001ff }, | ||
7468 | |||
7469 | { 0xffff, 0x0000, 0x00000000, 0x00000000 }, | ||
7470 | }; | ||
7471 | |||
7472 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
7473 | is_5705 = 1; | ||
7474 | else | ||
7475 | is_5705 = 0; | ||
7476 | |||
7477 | for (i = 0; reg_tbl[i].offset != 0xffff; i++) { | ||
7478 | if (is_5705 && (reg_tbl[i].flags & TG3_FL_NOT_5705)) | ||
7479 | continue; | ||
7480 | |||
7481 | if (!is_5705 && (reg_tbl[i].flags & TG3_FL_5705)) | ||
7482 | continue; | ||
7483 | |||
7484 | if ((tp->tg3_flags2 & TG3_FLG2_IS_5788) && | ||
7485 | (reg_tbl[i].flags & TG3_FL_NOT_5788)) | ||
7486 | continue; | ||
7487 | |||
7488 | offset = (u32) reg_tbl[i].offset; | ||
7489 | read_mask = reg_tbl[i].read_mask; | ||
7490 | write_mask = reg_tbl[i].write_mask; | ||
7491 | |||
7492 | /* Save the original register content */ | ||
7493 | save_val = tr32(offset); | ||
7494 | |||
7495 | /* Determine the read-only value. */ | ||
7496 | read_val = save_val & read_mask; | ||
7497 | |||
7498 | /* Write zero to the register, then make sure the read-only bits | ||
7499 | * are not changed and the read/write bits are all zeros. | ||
7500 | */ | ||
7501 | tw32(offset, 0); | ||
7502 | |||
7503 | val = tr32(offset); | ||
7504 | |||
7505 | /* Test the read-only and read/write bits. */ | ||
7506 | if (((val & read_mask) != read_val) || (val & write_mask)) | ||
7507 | goto out; | ||
7508 | |||
7509 | /* Write ones to all the bits defined by RdMask and WrMask, then | ||
7510 | * make sure the read-only bits are not changed and the | ||
7511 | * read/write bits are all ones. | ||
7512 | */ | ||
7513 | tw32(offset, read_mask | write_mask); | ||
7514 | |||
7515 | val = tr32(offset); | ||
7516 | |||
7517 | /* Test the read-only bits. */ | ||
7518 | if ((val & read_mask) != read_val) | ||
7519 | goto out; | ||
7520 | |||
7521 | /* Test the read/write bits. */ | ||
7522 | if ((val & write_mask) != write_mask) | ||
7523 | goto out; | ||
7524 | |||
7525 | tw32(offset, save_val); | ||
7526 | } | ||
7527 | |||
7528 | return 0; | ||
7529 | |||
7530 | out: | ||
7531 | printk(KERN_ERR PFX "Register test failed at offset %x\n", offset); | ||
7532 | tw32(offset, save_val); | ||
7533 | return -EIO; | ||
7534 | } | ||
7535 | |||
7536 | static int tg3_do_mem_test(struct tg3 *tp, u32 offset, u32 len) | ||
7537 | { | ||
7538 | static u32 test_pattern[] = { 0x00000000, 0xffffffff, 0xaa55a55a }; | ||
7539 | int i; | ||
7540 | u32 j; | ||
7541 | |||
7542 | for (i = 0; i < sizeof(test_pattern)/sizeof(u32); i++) { | ||
7543 | for (j = 0; j < len; j += 4) { | ||
7544 | u32 val; | ||
7545 | |||
7546 | tg3_write_mem(tp, offset + j, test_pattern[i]); | ||
7547 | tg3_read_mem(tp, offset + j, &val); | ||
7548 | if (val != test_pattern[i]) | ||
7549 | return -EIO; | ||
7550 | } | ||
7551 | } | ||
7552 | return 0; | ||
7553 | } | ||
7554 | |||
7555 | static int tg3_test_memory(struct tg3 *tp) | ||
7556 | { | ||
7557 | static struct mem_entry { | ||
7558 | u32 offset; | ||
7559 | u32 len; | ||
7560 | } mem_tbl_570x[] = { | ||
7561 | { 0x00000000, 0x01000}, | ||
7562 | { 0x00002000, 0x1c000}, | ||
7563 | { 0xffffffff, 0x00000} | ||
7564 | }, mem_tbl_5705[] = { | ||
7565 | { 0x00000100, 0x0000c}, | ||
7566 | { 0x00000200, 0x00008}, | ||
7567 | { 0x00000b50, 0x00400}, | ||
7568 | { 0x00004000, 0x00800}, | ||
7569 | { 0x00006000, 0x01000}, | ||
7570 | { 0x00008000, 0x02000}, | ||
7571 | { 0x00010000, 0x0e000}, | ||
7572 | { 0xffffffff, 0x00000} | ||
7573 | }; | ||
7574 | struct mem_entry *mem_tbl; | ||
7575 | int err = 0; | ||
7576 | int i; | ||
7577 | |||
7578 | if (tp->tg3_flags2 & TG3_FLG2_5705_PLUS) | ||
7579 | mem_tbl = mem_tbl_5705; | ||
7580 | else | ||
7581 | mem_tbl = mem_tbl_570x; | ||
7582 | |||
7583 | for (i = 0; mem_tbl[i].offset != 0xffffffff; i++) { | ||
7584 | if ((err = tg3_do_mem_test(tp, mem_tbl[i].offset, | ||
7585 | mem_tbl[i].len)) != 0) | ||
7586 | break; | ||
7587 | } | ||
7588 | |||
7589 | return err; | ||
7590 | } | ||
7591 | |||
7592 | static int tg3_test_loopback(struct tg3 *tp) | ||
7593 | { | ||
7594 | u32 mac_mode, send_idx, rx_start_idx, rx_idx, tx_idx, opaque_key; | ||
7595 | u32 desc_idx; | ||
7596 | struct sk_buff *skb, *rx_skb; | ||
7597 | u8 *tx_data; | ||
7598 | dma_addr_t map; | ||
7599 | int num_pkts, tx_len, rx_len, i, err; | ||
7600 | struct tg3_rx_buffer_desc *desc; | ||
7601 | |||
7602 | if (!netif_running(tp->dev)) | ||
7603 | return -ENODEV; | ||
7604 | |||
7605 | err = -EIO; | ||
7606 | |||
7607 | tg3_abort_hw(tp, 1); | ||
7608 | |||
7609 | /* Clearing this flag to keep interrupts disabled */ | ||
7610 | tp->tg3_flags &= ~TG3_FLAG_INIT_COMPLETE; | ||
7611 | tg3_reset_hw(tp); | ||
7612 | |||
7613 | mac_mode = (tp->mac_mode & ~MAC_MODE_PORT_MODE_MASK) | | ||
7614 | MAC_MODE_PORT_INT_LPBACK | MAC_MODE_LINK_POLARITY | | ||
7615 | MAC_MODE_PORT_MODE_GMII; | ||
7616 | tw32(MAC_MODE, mac_mode); | ||
7617 | |||
7618 | tx_len = 1514; | ||
7619 | skb = dev_alloc_skb(tx_len); | ||
7620 | tx_data = skb_put(skb, tx_len); | ||
7621 | memcpy(tx_data, tp->dev->dev_addr, 6); | ||
7622 | memset(tx_data + 6, 0x0, 8); | ||
7623 | |||
7624 | tw32(MAC_RX_MTU_SIZE, tx_len + 4); | ||
7625 | |||
7626 | for (i = 14; i < tx_len; i++) | ||
7627 | tx_data[i] = (u8) (i & 0xff); | ||
7628 | |||
7629 | map = pci_map_single(tp->pdev, skb->data, tx_len, PCI_DMA_TODEVICE); | ||
7630 | |||
7631 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | ||
7632 | HOSTCC_MODE_NOW); | ||
7633 | |||
7634 | udelay(10); | ||
7635 | |||
7636 | rx_start_idx = tp->hw_status->idx[0].rx_producer; | ||
7637 | |||
7638 | send_idx = 0; | ||
7639 | num_pkts = 0; | ||
7640 | |||
7641 | tg3_set_txd(tp, send_idx, map, tx_len, 0, 1); | ||
7642 | |||
7643 | send_idx++; | ||
7644 | num_pkts++; | ||
7645 | |||
7646 | tw32_tx_mbox(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW, send_idx); | ||
7647 | tr32(MAILBOX_SNDHOST_PROD_IDX_0 + TG3_64BIT_REG_LOW); | ||
7648 | |||
7649 | udelay(10); | ||
7650 | |||
7651 | for (i = 0; i < 10; i++) { | ||
7652 | tw32_f(HOSTCC_MODE, tp->coalesce_mode | HOSTCC_MODE_ENABLE | | ||
7653 | HOSTCC_MODE_NOW); | ||
7654 | |||
7655 | udelay(10); | ||
7656 | |||
7657 | tx_idx = tp->hw_status->idx[0].tx_consumer; | ||
7658 | rx_idx = tp->hw_status->idx[0].rx_producer; | ||
7659 | if ((tx_idx == send_idx) && | ||
7660 | (rx_idx == (rx_start_idx + num_pkts))) | ||
7661 | break; | ||
7662 | } | ||
7663 | |||
7664 | pci_unmap_single(tp->pdev, map, tx_len, PCI_DMA_TODEVICE); | ||
7665 | dev_kfree_skb(skb); | ||
7666 | |||
7667 | if (tx_idx != send_idx) | ||
7668 | goto out; | ||
7669 | |||
7670 | if (rx_idx != rx_start_idx + num_pkts) | ||
7671 | goto out; | ||
7672 | |||
7673 | desc = &tp->rx_rcb[rx_start_idx]; | ||
7674 | desc_idx = desc->opaque & RXD_OPAQUE_INDEX_MASK; | ||
7675 | opaque_key = desc->opaque & RXD_OPAQUE_RING_MASK; | ||
7676 | if (opaque_key != RXD_OPAQUE_RING_STD) | ||
7677 | goto out; | ||
7678 | |||
7679 | if ((desc->err_vlan & RXD_ERR_MASK) != 0 && | ||
7680 | (desc->err_vlan != RXD_ERR_ODD_NIBBLE_RCVD_MII)) | ||
7681 | goto out; | ||
7682 | |||
7683 | rx_len = ((desc->idx_len & RXD_LEN_MASK) >> RXD_LEN_SHIFT) - 4; | ||
7684 | if (rx_len != tx_len) | ||
7685 | goto out; | ||
7686 | |||
7687 | rx_skb = tp->rx_std_buffers[desc_idx].skb; | ||
7688 | |||
7689 | map = pci_unmap_addr(&tp->rx_std_buffers[desc_idx], mapping); | ||
7690 | pci_dma_sync_single_for_cpu(tp->pdev, map, rx_len, PCI_DMA_FROMDEVICE); | ||
7691 | |||
7692 | for (i = 14; i < tx_len; i++) { | ||
7693 | if (*(rx_skb->data + i) != (u8) (i & 0xff)) | ||
7694 | goto out; | ||
7695 | } | ||
7696 | err = 0; | ||
7697 | |||
7698 | /* tg3_free_rings will unmap and free the rx_skb */ | ||
7699 | out: | ||
7700 | return err; | ||
7701 | } | ||
7702 | |||
7703 | static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | ||
7704 | u64 *data) | ||
7705 | { | ||
7706 | struct tg3 *tp = netdev_priv(dev); | ||
7707 | |||
7708 | memset(data, 0, sizeof(u64) * TG3_NUM_TEST); | ||
7709 | |||
7710 | if (tg3_test_nvram(tp) != 0) { | ||
7711 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7712 | data[0] = 1; | ||
7713 | } | ||
7714 | if (tg3_test_link(tp) != 0) { | ||
7715 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7716 | data[1] = 1; | ||
7717 | } | ||
7718 | if (etest->flags & ETH_TEST_FL_OFFLINE) { | ||
7719 | if (netif_running(dev)) | ||
7720 | tg3_netif_stop(tp); | ||
7721 | |||
7722 | spin_lock_irq(&tp->lock); | ||
7723 | spin_lock(&tp->tx_lock); | ||
7724 | |||
7725 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); | ||
7726 | tg3_nvram_lock(tp); | ||
7727 | tg3_halt_cpu(tp, RX_CPU_BASE); | ||
7728 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) | ||
7729 | tg3_halt_cpu(tp, TX_CPU_BASE); | ||
7730 | tg3_nvram_unlock(tp); | ||
7731 | |||
7732 | if (tg3_test_registers(tp) != 0) { | ||
7733 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7734 | data[2] = 1; | ||
7735 | } | ||
7736 | if (tg3_test_memory(tp) != 0) { | ||
7737 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7738 | data[3] = 1; | ||
7739 | } | ||
7740 | if (tg3_test_loopback(tp) != 0) { | ||
7741 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7742 | data[4] = 1; | ||
7743 | } | ||
7744 | |||
7745 | spin_unlock(&tp->tx_lock); | ||
7746 | spin_unlock_irq(&tp->lock); | ||
7747 | if (tg3_test_interrupt(tp) != 0) { | ||
7748 | etest->flags |= ETH_TEST_FL_FAILED; | ||
7749 | data[5] = 1; | ||
7750 | } | ||
7751 | spin_lock_irq(&tp->lock); | ||
7752 | spin_lock(&tp->tx_lock); | ||
7753 | |||
7754 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); | ||
7755 | if (netif_running(dev)) { | ||
7756 | tp->tg3_flags |= TG3_FLAG_INIT_COMPLETE; | ||
7757 | tg3_init_hw(tp); | ||
7758 | tg3_netif_start(tp); | ||
7759 | } | ||
7760 | spin_unlock(&tp->tx_lock); | ||
7761 | spin_unlock_irq(&tp->lock); | ||
7762 | } | ||
7763 | } | ||
7764 | |||
7221 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 7765 | static int tg3_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
7222 | { | 7766 | { |
7223 | struct mii_ioctl_data *data = if_mii(ifr); | 7767 | struct mii_ioctl_data *data = if_mii(ifr); |
@@ -7331,6 +7875,8 @@ static struct ethtool_ops tg3_ethtool_ops = { | |||
7331 | .get_tso = ethtool_op_get_tso, | 7875 | .get_tso = ethtool_op_get_tso, |
7332 | .set_tso = tg3_set_tso, | 7876 | .set_tso = tg3_set_tso, |
7333 | #endif | 7877 | #endif |
7878 | .self_test_count = tg3_get_test_count, | ||
7879 | .self_test = tg3_self_test, | ||
7334 | .get_strings = tg3_get_strings, | 7880 | .get_strings = tg3_get_strings, |
7335 | .get_stats_count = tg3_get_stats_count, | 7881 | .get_stats_count = tg3_get_stats_count, |
7336 | .get_ethtool_stats = tg3_get_ethtool_stats, | 7882 | .get_ethtool_stats = tg3_get_ethtool_stats, |
@@ -8014,6 +8560,16 @@ static void __devinit tg3_get_eeprom_hw_cfg(struct tg3 *tp) | |||
8014 | 8560 | ||
8015 | case NIC_SRAM_DATA_CFG_LED_MODE_MAC: | 8561 | case NIC_SRAM_DATA_CFG_LED_MODE_MAC: |
8016 | tp->led_ctrl = LED_CTRL_MODE_MAC; | 8562 | tp->led_ctrl = LED_CTRL_MODE_MAC; |
8563 | |||
8564 | /* Default to PHY_1_MODE if 0 (MAC_MODE) is | ||
8565 | * read on some older 5700/5701 bootcode. | ||
8566 | */ | ||
8567 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == | ||
8568 | ASIC_REV_5700 || | ||
8569 | GET_ASIC_REV(tp->pci_chip_rev_id) == | ||
8570 | ASIC_REV_5701) | ||
8571 | tp->led_ctrl = LED_CTRL_MODE_PHY_1; | ||
8572 | |||
8017 | break; | 8573 | break; |
8018 | 8574 | ||
8019 | case SHASTA_EXT_LED_SHARED: | 8575 | case SHASTA_EXT_LED_SHARED: |
@@ -9139,10 +9695,24 @@ static int __devinit tg3_test_dma(struct tg3 *tp) | |||
9139 | } | 9695 | } |
9140 | if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != | 9696 | if ((tp->dma_rwctrl & DMA_RWCTRL_WRITE_BNDRY_MASK) != |
9141 | DMA_RWCTRL_WRITE_BNDRY_16) { | 9697 | DMA_RWCTRL_WRITE_BNDRY_16) { |
9698 | static struct pci_device_id dma_wait_state_chipsets[] = { | ||
9699 | { PCI_DEVICE(PCI_VENDOR_ID_APPLE, | ||
9700 | PCI_DEVICE_ID_APPLE_UNI_N_PCI15) }, | ||
9701 | { }, | ||
9702 | }; | ||
9703 | |||
9142 | /* DMA test passed without adjusting DMA boundary, | 9704 | /* DMA test passed without adjusting DMA boundary, |
9143 | * just restore the calculated DMA boundary | 9705 | * now look for chipsets that are known to expose the |
9706 | * DMA bug without failing the test. | ||
9144 | */ | 9707 | */ |
9145 | tp->dma_rwctrl = saved_dma_rwctrl; | 9708 | if (pci_dev_present(dma_wait_state_chipsets)) { |
9709 | tp->dma_rwctrl &= ~DMA_RWCTRL_WRITE_BNDRY_MASK; | ||
9710 | tp->dma_rwctrl |= DMA_RWCTRL_WRITE_BNDRY_16; | ||
9711 | } | ||
9712 | else | ||
9713 | /* Safe to use the calculated DMA boundary. */ | ||
9714 | tp->dma_rwctrl = saved_dma_rwctrl; | ||
9715 | |||
9146 | tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); | 9716 | tw32(TG3PCI_DMA_RW_CTRL, tp->dma_rwctrl); |
9147 | } | 9717 | } |
9148 | 9718 | ||
@@ -9478,7 +10048,7 @@ static int __devinit tg3_init_one(struct pci_dev *pdev, | |||
9478 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { | 10048 | (tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) { |
9479 | pci_save_state(tp->pdev); | 10049 | pci_save_state(tp->pdev); |
9480 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); | 10050 | tw32(MEMARB_MODE, MEMARB_MODE_ENABLE); |
9481 | tg3_halt(tp, 1); | 10051 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
9482 | } | 10052 | } |
9483 | 10053 | ||
9484 | err = tg3_test_dma(tp); | 10054 | err = tg3_test_dma(tp); |
@@ -9605,7 +10175,7 @@ static int tg3_suspend(struct pci_dev *pdev, pm_message_t state) | |||
9605 | 10175 | ||
9606 | spin_lock_irq(&tp->lock); | 10176 | spin_lock_irq(&tp->lock); |
9607 | spin_lock(&tp->tx_lock); | 10177 | spin_lock(&tp->tx_lock); |
9608 | tg3_halt(tp, 1); | 10178 | tg3_halt(tp, RESET_KIND_SHUTDOWN, 1); |
9609 | spin_unlock(&tp->tx_lock); | 10179 | spin_unlock(&tp->tx_lock); |
9610 | spin_unlock_irq(&tp->lock); | 10180 | spin_unlock_irq(&tp->lock); |
9611 | 10181 | ||