diff options
| -rw-r--r-- | drivers/net/tg3.c | 82 | ||||
| -rw-r--r-- | drivers/net/tg3.h | 1 |
2 files changed, 55 insertions, 28 deletions
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index eb86b059809b..f2d1dafde087 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c | |||
| @@ -69,8 +69,8 @@ | |||
| 69 | 69 | ||
| 70 | #define DRV_MODULE_NAME "tg3" | 70 | #define DRV_MODULE_NAME "tg3" |
| 71 | #define PFX DRV_MODULE_NAME ": " | 71 | #define PFX DRV_MODULE_NAME ": " |
| 72 | #define DRV_MODULE_VERSION "3.47" | 72 | #define DRV_MODULE_VERSION "3.48" |
| 73 | #define DRV_MODULE_RELDATE "Dec 28, 2005" | 73 | #define DRV_MODULE_RELDATE "Jan 16, 2006" |
| 74 | 74 | ||
| 75 | #define TG3_DEF_MAC_MODE 0 | 75 | #define TG3_DEF_MAC_MODE 0 |
| 76 | #define TG3_DEF_RX_MODE 0 | 76 | #define TG3_DEF_RX_MODE 0 |
| @@ -1325,10 +1325,12 @@ static int tg3_set_power_state(struct tg3 *tp, int state) | |||
| 1325 | val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1); | 1325 | val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1); |
| 1326 | tw32(0x7d00, val); | 1326 | tw32(0x7d00, val); |
| 1327 | if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { | 1327 | if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) { |
| 1328 | tg3_nvram_lock(tp); | 1328 | int err; |
| 1329 | |||
| 1330 | err = tg3_nvram_lock(tp); | ||
| 1329 | tg3_halt_cpu(tp, RX_CPU_BASE); | 1331 | tg3_halt_cpu(tp, RX_CPU_BASE); |
| 1330 | tw32_f(NVRAM_SWARB, SWARB_REQ_CLR0); | 1332 | if (!err) |
| 1331 | tg3_nvram_unlock(tp); | 1333 | tg3_nvram_unlock(tp); |
| 1332 | } | 1334 | } |
| 1333 | } | 1335 | } |
| 1334 | 1336 | ||
| @@ -4193,14 +4195,19 @@ static int tg3_nvram_lock(struct tg3 *tp) | |||
| 4193 | if (tp->tg3_flags & TG3_FLAG_NVRAM) { | 4195 | if (tp->tg3_flags & TG3_FLAG_NVRAM) { |
| 4194 | int i; | 4196 | int i; |
| 4195 | 4197 | ||
| 4196 | tw32(NVRAM_SWARB, SWARB_REQ_SET1); | 4198 | if (tp->nvram_lock_cnt == 0) { |
| 4197 | for (i = 0; i < 8000; i++) { | 4199 | tw32(NVRAM_SWARB, SWARB_REQ_SET1); |
| 4198 | if (tr32(NVRAM_SWARB) & SWARB_GNT1) | 4200 | for (i = 0; i < 8000; i++) { |
| 4199 | break; | 4201 | if (tr32(NVRAM_SWARB) & SWARB_GNT1) |
| 4200 | udelay(20); | 4202 | break; |
| 4203 | udelay(20); | ||
| 4204 | } | ||
| 4205 | if (i == 8000) { | ||
| 4206 | tw32(NVRAM_SWARB, SWARB_REQ_CLR1); | ||
| 4207 | return -ENODEV; | ||
| 4208 | } | ||
| 4201 | } | 4209 | } |
| 4202 | if (i == 8000) | 4210 | tp->nvram_lock_cnt++; |
| 4203 | return -ENODEV; | ||
| 4204 | } | 4211 | } |
| 4205 | return 0; | 4212 | return 0; |
| 4206 | } | 4213 | } |
| @@ -4208,8 +4215,12 @@ static int tg3_nvram_lock(struct tg3 *tp) | |||
| 4208 | /* tp->lock is held. */ | 4215 | /* tp->lock is held. */ |
| 4209 | static void tg3_nvram_unlock(struct tg3 *tp) | 4216 | static void tg3_nvram_unlock(struct tg3 *tp) |
| 4210 | { | 4217 | { |
| 4211 | if (tp->tg3_flags & TG3_FLAG_NVRAM) | 4218 | if (tp->tg3_flags & TG3_FLAG_NVRAM) { |
| 4212 | tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1); | 4219 | if (tp->nvram_lock_cnt > 0) |
| 4220 | tp->nvram_lock_cnt--; | ||
| 4221 | if (tp->nvram_lock_cnt == 0) | ||
| 4222 | tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1); | ||
| 4223 | } | ||
| 4213 | } | 4224 | } |
| 4214 | 4225 | ||
| 4215 | /* tp->lock is held. */ | 4226 | /* tp->lock is held. */ |
| @@ -4320,8 +4331,13 @@ static int tg3_chip_reset(struct tg3 *tp) | |||
| 4320 | void (*write_op)(struct tg3 *, u32, u32); | 4331 | void (*write_op)(struct tg3 *, u32, u32); |
| 4321 | int i; | 4332 | int i; |
| 4322 | 4333 | ||
| 4323 | if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) | 4334 | if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) { |
| 4324 | tg3_nvram_lock(tp); | 4335 | tg3_nvram_lock(tp); |
| 4336 | /* No matching tg3_nvram_unlock() after this because | ||
| 4337 | * chip reset below will undo the nvram lock. | ||
| 4338 | */ | ||
| 4339 | tp->nvram_lock_cnt = 0; | ||
| 4340 | } | ||
| 4325 | 4341 | ||
| 4326 | /* | 4342 | /* |
| 4327 | * We must avoid the readl() that normally takes place. | 4343 | * We must avoid the readl() that normally takes place. |
| @@ -4717,6 +4733,10 @@ static int tg3_halt_cpu(struct tg3 *tp, u32 offset) | |||
| 4717 | (offset == RX_CPU_BASE ? "RX" : "TX")); | 4733 | (offset == RX_CPU_BASE ? "RX" : "TX")); |
| 4718 | return -ENODEV; | 4734 | return -ENODEV; |
| 4719 | } | 4735 | } |
| 4736 | |||
| 4737 | /* Clear firmware's nvram arbitration. */ | ||
| 4738 | if (tp->tg3_flags & TG3_FLAG_NVRAM) | ||
| 4739 | tw32(NVRAM_SWARB, SWARB_REQ_CLR0); | ||
| 4720 | return 0; | 4740 | return 0; |
| 4721 | } | 4741 | } |
| 4722 | 4742 | ||
| @@ -4736,7 +4756,7 @@ struct fw_info { | |||
| 4736 | static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base, | 4756 | static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base, |
| 4737 | int cpu_scratch_size, struct fw_info *info) | 4757 | int cpu_scratch_size, struct fw_info *info) |
| 4738 | { | 4758 | { |
| 4739 | int err, i; | 4759 | int err, lock_err, i; |
| 4740 | void (*write_op)(struct tg3 *, u32, u32); | 4760 | void (*write_op)(struct tg3 *, u32, u32); |
| 4741 | 4761 | ||
| 4742 | if (cpu_base == TX_CPU_BASE && | 4762 | if (cpu_base == TX_CPU_BASE && |
| @@ -4755,9 +4775,10 @@ static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_b | |||
| 4755 | /* It is possible that bootcode is still loading at this point. | 4775 | /* It is possible that bootcode is still loading at this point. |
| 4756 | * Get the nvram lock first before halting the cpu. | 4776 | * Get the nvram lock first before halting the cpu. |
| 4757 | */ | 4777 | */ |
| 4758 | tg3_nvram_lock(tp); | 4778 | lock_err = tg3_nvram_lock(tp); |
| 4759 | err = tg3_halt_cpu(tp, cpu_base); | 4779 | err = tg3_halt_cpu(tp, cpu_base); |
| 4760 | tg3_nvram_unlock(tp); | 4780 | if (!lock_err) |
| 4781 | tg3_nvram_unlock(tp); | ||
| 4761 | if (err) | 4782 | if (err) |
| 4762 | goto out; | 4783 | goto out; |
| 4763 | 4784 | ||
| @@ -8182,7 +8203,7 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
| 8182 | data[1] = 1; | 8203 | data[1] = 1; |
| 8183 | } | 8204 | } |
| 8184 | if (etest->flags & ETH_TEST_FL_OFFLINE) { | 8205 | if (etest->flags & ETH_TEST_FL_OFFLINE) { |
| 8185 | int irq_sync = 0; | 8206 | int err, irq_sync = 0; |
| 8186 | 8207 | ||
| 8187 | if (netif_running(dev)) { | 8208 | if (netif_running(dev)) { |
| 8188 | tg3_netif_stop(tp); | 8209 | tg3_netif_stop(tp); |
| @@ -8192,11 +8213,12 @@ static void tg3_self_test(struct net_device *dev, struct ethtool_test *etest, | |||
| 8192 | tg3_full_lock(tp, irq_sync); | 8213 | tg3_full_lock(tp, irq_sync); |
| 8193 | 8214 | ||
| 8194 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); | 8215 | tg3_halt(tp, RESET_KIND_SUSPEND, 1); |
| 8195 | tg3_nvram_lock(tp); | 8216 | err = tg3_nvram_lock(tp); |
| 8196 | tg3_halt_cpu(tp, RX_CPU_BASE); | 8217 | tg3_halt_cpu(tp, RX_CPU_BASE); |
| 8197 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) | 8218 | if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS)) |
| 8198 | tg3_halt_cpu(tp, TX_CPU_BASE); | 8219 | tg3_halt_cpu(tp, TX_CPU_BASE); |
| 8199 | tg3_nvram_unlock(tp); | 8220 | if (!err) |
| 8221 | tg3_nvram_unlock(tp); | ||
| 8200 | 8222 | ||
| 8201 | if (tg3_test_registers(tp) != 0) { | 8223 | if (tg3_test_registers(tp) != 0) { |
| 8202 | etest->flags |= ETH_TEST_FL_FAILED; | 8224 | etest->flags |= ETH_TEST_FL_FAILED; |
| @@ -8588,7 +8610,11 @@ static void __devinit tg3_nvram_init(struct tg3 *tp) | |||
| 8588 | GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { | 8610 | GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) { |
| 8589 | tp->tg3_flags |= TG3_FLAG_NVRAM; | 8611 | tp->tg3_flags |= TG3_FLAG_NVRAM; |
| 8590 | 8612 | ||
| 8591 | tg3_nvram_lock(tp); | 8613 | if (tg3_nvram_lock(tp)) { |
| 8614 | printk(KERN_WARNING PFX "%s: Cannot get nvarm lock, " | ||
| 8615 | "tg3_nvram_init failed.\n", tp->dev->name); | ||
| 8616 | return; | ||
| 8617 | } | ||
| 8592 | tg3_enable_nvram_access(tp); | 8618 | tg3_enable_nvram_access(tp); |
| 8593 | 8619 | ||
| 8594 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) | 8620 | if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752) |
| @@ -8686,7 +8712,9 @@ static int tg3_nvram_read(struct tg3 *tp, u32 offset, u32 *val) | |||
| 8686 | if (offset > NVRAM_ADDR_MSK) | 8712 | if (offset > NVRAM_ADDR_MSK) |
| 8687 | return -EINVAL; | 8713 | return -EINVAL; |
| 8688 | 8714 | ||
| 8689 | tg3_nvram_lock(tp); | 8715 | ret = tg3_nvram_lock(tp); |
| 8716 | if (ret) | ||
| 8717 | return ret; | ||
| 8690 | 8718 | ||
| 8691 | tg3_enable_nvram_access(tp); | 8719 | tg3_enable_nvram_access(tp); |
| 8692 | 8720 | ||
| @@ -8785,10 +8813,6 @@ static int tg3_nvram_write_block_unbuffered(struct tg3 *tp, u32 offset, u32 len, | |||
| 8785 | 8813 | ||
| 8786 | offset = offset + (pagesize - page_off); | 8814 | offset = offset + (pagesize - page_off); |
| 8787 | 8815 | ||
| 8788 | /* Nvram lock released by tg3_nvram_read() above, | ||
| 8789 | * so need to get it again. | ||
| 8790 | */ | ||
| 8791 | tg3_nvram_lock(tp); | ||
| 8792 | tg3_enable_nvram_access(tp); | 8816 | tg3_enable_nvram_access(tp); |
| 8793 | 8817 | ||
| 8794 | /* | 8818 | /* |
| @@ -8925,7 +8949,9 @@ static int tg3_nvram_write_block(struct tg3 *tp, u32 offset, u32 len, u8 *buf) | |||
| 8925 | else { | 8949 | else { |
| 8926 | u32 grc_mode; | 8950 | u32 grc_mode; |
| 8927 | 8951 | ||
| 8928 | tg3_nvram_lock(tp); | 8952 | ret = tg3_nvram_lock(tp); |
| 8953 | if (ret) | ||
| 8954 | return ret; | ||
| 8929 | 8955 | ||
| 8930 | tg3_enable_nvram_access(tp); | 8956 | tg3_enable_nvram_access(tp); |
| 8931 | if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && | 8957 | if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) && |
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h index 890e1635996b..e8243305f0e8 100644 --- a/drivers/net/tg3.h +++ b/drivers/net/tg3.h | |||
| @@ -2275,6 +2275,7 @@ struct tg3 { | |||
| 2275 | dma_addr_t stats_mapping; | 2275 | dma_addr_t stats_mapping; |
| 2276 | struct work_struct reset_task; | 2276 | struct work_struct reset_task; |
| 2277 | 2277 | ||
| 2278 | int nvram_lock_cnt; | ||
| 2278 | u32 nvram_size; | 2279 | u32 nvram_size; |
| 2279 | u32 nvram_pagesize; | 2280 | u32 nvram_pagesize; |
| 2280 | u32 nvram_jedecnum; | 2281 | u32 nvram_jedecnum; |
