aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorMichael Chan <mchan@broadcom.com>2006-01-17 05:40:55 -0500
committerDavid S. Miller <davem@davemloft.net>2006-01-17 05:40:55 -0500
commitec41c7dfd525468decb9da9281dbc9ed82d98c98 (patch)
tree02ac7f0b1318c69d53a2405972f8a6880dc8b7c6 /drivers
parentf0daaa654af68c1651add9d21188d81c19672551 (diff)
[TG3]: Refine nvram locking
Add nvram lock count so that calls to tg3_nvram_lock()/unlock() can be nested. Add error checking to all callers of tg3_nvram_lock() where appropriate. To prevent nvram lock failures after halting the firmware, it is also necessary to release firmware's nvram lock in tg3_halt_cpu(). Update version to 3.48. Based on David Miller's initial patch. Signed-off-by: Michael Chan <mchan@broadcom.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/tg3.c82
-rw-r--r--drivers/net/tg3.h1
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. */
4209static void tg3_nvram_unlock(struct tg3 *tp) 4216static 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 {
4736static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base, 4756static 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;