#define DRV_MODULE_NAME "tg3"
#define PFX DRV_MODULE_NAME ": "
-#define DRV_MODULE_VERSION "3.47"
-#define DRV_MODULE_RELDATE "Dec 28, 2005"
+#define DRV_MODULE_VERSION "3.48"
+#define DRV_MODULE_RELDATE "Jan 16, 2006"
#define TG3_DEF_MAC_MODE 0
#define TG3_DEF_RX_MODE 0
val &= ~((1 << 16) | (1 << 4) | (1 << 2) | (1 << 1) | 1);
tw32(0x7d00, val);
if (!(tp->tg3_flags & TG3_FLAG_ENABLE_ASF)) {
- tg3_nvram_lock(tp);
+ int err;
+
+ err = tg3_nvram_lock(tp);
tg3_halt_cpu(tp, RX_CPU_BASE);
- tw32_f(NVRAM_SWARB, SWARB_REQ_CLR0);
- tg3_nvram_unlock(tp);
+ if (!err)
+ tg3_nvram_unlock(tp);
}
}
if (tp->tg3_flags & TG3_FLAG_NVRAM) {
int i;
- tw32(NVRAM_SWARB, SWARB_REQ_SET1);
- for (i = 0; i < 8000; i++) {
- if (tr32(NVRAM_SWARB) & SWARB_GNT1)
- break;
- udelay(20);
+ if (tp->nvram_lock_cnt == 0) {
+ tw32(NVRAM_SWARB, SWARB_REQ_SET1);
+ for (i = 0; i < 8000; i++) {
+ if (tr32(NVRAM_SWARB) & SWARB_GNT1)
+ break;
+ udelay(20);
+ }
+ if (i == 8000) {
+ tw32(NVRAM_SWARB, SWARB_REQ_CLR1);
+ return -ENODEV;
+ }
}
- if (i == 8000)
- return -ENODEV;
+ tp->nvram_lock_cnt++;
}
return 0;
}
/* tp->lock is held. */
static void tg3_nvram_unlock(struct tg3 *tp)
{
- if (tp->tg3_flags & TG3_FLAG_NVRAM)
- tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
+ if (tp->tg3_flags & TG3_FLAG_NVRAM) {
+ if (tp->nvram_lock_cnt > 0)
+ tp->nvram_lock_cnt--;
+ if (tp->nvram_lock_cnt == 0)
+ tw32_f(NVRAM_SWARB, SWARB_REQ_CLR1);
+ }
}
/* tp->lock is held. */
void (*write_op)(struct tg3 *, u32, u32);
int i;
- if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X))
+ if (!(tp->tg3_flags2 & TG3_FLG2_SUN_570X)) {
tg3_nvram_lock(tp);
+ /* No matching tg3_nvram_unlock() after this because
+ * chip reset below will undo the nvram lock.
+ */
+ tp->nvram_lock_cnt = 0;
+ }
/*
* We must avoid the readl() that normally takes place.
(offset == RX_CPU_BASE ? "RX" : "TX"));
return -ENODEV;
}
+
+ /* Clear firmware's nvram arbitration. */
+ if (tp->tg3_flags & TG3_FLAG_NVRAM)
+ tw32(NVRAM_SWARB, SWARB_REQ_CLR0);
return 0;
}
static int tg3_load_firmware_cpu(struct tg3 *tp, u32 cpu_base, u32 cpu_scratch_base,
int cpu_scratch_size, struct fw_info *info)
{
- int err, i;
+ int err, lock_err, i;
void (*write_op)(struct tg3 *, u32, u32);
if (cpu_base == TX_CPU_BASE &&
/* It is possible that bootcode is still loading at this point.
* Get the nvram lock first before halting the cpu.
*/
- tg3_nvram_lock(tp);
+ lock_err = tg3_nvram_lock(tp);
err = tg3_halt_cpu(tp, cpu_base);
- tg3_nvram_unlock(tp);
+ if (!lock_err)
+ tg3_nvram_unlock(tp);
if (err)
goto out;
data[1] = 1;
}
if (etest->flags & ETH_TEST_FL_OFFLINE) {
- int irq_sync = 0;
+ int err, irq_sync = 0;
if (netif_running(dev)) {
tg3_netif_stop(tp);
tg3_full_lock(tp, irq_sync);
tg3_halt(tp, RESET_KIND_SUSPEND, 1);
- tg3_nvram_lock(tp);
+ err = tg3_nvram_lock(tp);
tg3_halt_cpu(tp, RX_CPU_BASE);
if (!(tp->tg3_flags2 & TG3_FLG2_5705_PLUS))
tg3_halt_cpu(tp, TX_CPU_BASE);
- tg3_nvram_unlock(tp);
+ if (!err)
+ tg3_nvram_unlock(tp);
if (tg3_test_registers(tp) != 0) {
etest->flags |= ETH_TEST_FL_FAILED;
GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5701) {
tp->tg3_flags |= TG3_FLAG_NVRAM;
- tg3_nvram_lock(tp);
+ if (tg3_nvram_lock(tp)) {
+ printk(KERN_WARNING PFX "%s: Cannot get nvarm lock, "
+ "tg3_nvram_init failed.\n", tp->dev->name);
+ return;
+ }
tg3_enable_nvram_access(tp);
if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752)
if (offset > NVRAM_ADDR_MSK)
return -EINVAL;
- tg3_nvram_lock(tp);
+ ret = tg3_nvram_lock(tp);
+ if (ret)
+ return ret;
tg3_enable_nvram_access(tp);
offset = offset + (pagesize - page_off);
- /* Nvram lock released by tg3_nvram_read() above,
- * so need to get it again.
- */
- tg3_nvram_lock(tp);
tg3_enable_nvram_access(tp);
/*
else {
u32 grc_mode;
- tg3_nvram_lock(tp);
+ ret = tg3_nvram_lock(tp);
+ if (ret)
+ return ret;
tg3_enable_nvram_access(tp);
if ((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&