Skip to content

Commit

Permalink
b43: Fix MAC control and microcode init
Browse files Browse the repository at this point in the history
This zeros out all microcode related memory before loading
the microcode.

This also fixes initialization of the MAC control register.
The _only_ place where we overwrite the contents of the MAC control
register is at the beginning of b43_chip_init().
All other places must do read() -> mask/set -> write() to not
overwrite existing bits.

This also adds a longer delay for waiting for the microcode
to initialize itself. It seems that the current timeout is sufficient
on all available devices, but there's no real reason why we shouldn't
wait for up to one second. Slow embedded devices might exist.
Better safe than sorry.

Signed-off-by: Michael Buesch <mb@bu3sch.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
  • Loading branch information
Michael Buesch authored and David S. Miller committed Jan 28, 2008
1 parent 4248d2f commit 1f7d87b
Showing 1 changed file with 48 additions and 13 deletions.
61 changes: 48 additions & 13 deletions drivers/net/wireless/b43/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1778,9 +1778,20 @@ static int b43_upload_microcode(struct b43_wldev *dev)
const __be32 *data;
unsigned int i, len;
u16 fwrev, fwpatch, fwdate, fwtime;
u32 tmp;
u32 tmp, macctl;
int err = 0;

/* Jump the microcode PSM to offset 0 */
macctl = b43_read32(dev, B43_MMIO_MACCTL);
B43_WARN_ON(macctl & B43_MACCTL_PSM_RUN);
macctl |= B43_MACCTL_PSM_JMP0;
b43_write32(dev, B43_MMIO_MACCTL, macctl);
/* Zero out all microcode PSM registers and shared memory. */
for (i = 0; i < 64; i++)
b43_shm_write16(dev, B43_SHM_SCRATCH, i, 0);
for (i = 0; i < 4096; i += 2)
b43_shm_write16(dev, B43_SHM_SHARED, i, 0);

/* Upload Microcode. */
data = (__be32 *) (dev->fw.ucode.data->data + hdr_len);
len = (dev->fw.ucode.data->size - hdr_len) / sizeof(__be32);
Expand All @@ -1805,9 +1816,12 @@ static int b43_upload_microcode(struct b43_wldev *dev)
}

b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL);
b43_write32(dev, B43_MMIO_MACCTL,
B43_MACCTL_PSM_RUN |
B43_MACCTL_IHR_ENABLED | B43_MACCTL_INFRA);

/* Start the microcode PSM */
macctl = b43_read32(dev, B43_MMIO_MACCTL);
macctl &= ~B43_MACCTL_PSM_JMP0;
macctl |= B43_MACCTL_PSM_RUN;
b43_write32(dev, B43_MMIO_MACCTL, macctl);

/* Wait for the microcode to load and respond */
i = 0;
Expand All @@ -1816,13 +1830,17 @@ static int b43_upload_microcode(struct b43_wldev *dev)
if (tmp == B43_IRQ_MAC_SUSPENDED)
break;
i++;
if (i >= 50) {
if (i >= 20) {
b43err(dev->wl, "Microcode not responding\n");
b43_print_fw_helptext(dev->wl, 1);
err = -ENODEV;
goto out;
goto error;
}
msleep_interruptible(50);
if (signal_pending(current)) {
err = -EINTR;
goto error;
}
udelay(10);
}
b43_read32(dev, B43_MMIO_GEN_IRQ_REASON); /* dummy read */

Expand All @@ -1837,9 +1855,8 @@ static int b43_upload_microcode(struct b43_wldev *dev)
"binary drivers older than version 4.x is unsupported. "
"You must upgrade your firmware files.\n");
b43_print_fw_helptext(dev->wl, 1);
b43_write32(dev, B43_MMIO_MACCTL, 0);
err = -EOPNOTSUPP;
goto out;
goto error;
}
b43dbg(dev->wl, "Loading firmware version %u.%u "
"(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
Expand All @@ -1856,7 +1873,14 @@ static int b43_upload_microcode(struct b43_wldev *dev)
b43_print_fw_helptext(dev->wl, 0);
}

out:
return 0;

error:
macctl = b43_read32(dev, B43_MMIO_MACCTL);
macctl &= ~B43_MACCTL_PSM_RUN;
macctl |= B43_MACCTL_PSM_JMP0;
b43_write32(dev, B43_MMIO_MACCTL, macctl);

return err;
}

Expand Down Expand Up @@ -2228,11 +2252,15 @@ static int b43_chip_init(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
int err, tmp;
u32 value32;
u32 value32, macctl;
u16 value16;

b43_write32(dev, B43_MMIO_MACCTL,
B43_MACCTL_PSM_JMP0 | B43_MACCTL_IHR_ENABLED);
/* Initialize the MAC control */
macctl = B43_MACCTL_IHR_ENABLED | B43_MACCTL_SHM_ENABLED;
if (dev->phy.gmode)
macctl |= B43_MACCTL_GMODE;
macctl |= B43_MACCTL_INFRA;
b43_write32(dev, B43_MMIO_MACCTL, macctl);

err = b43_request_firmware(dev);
if (err)
Expand Down Expand Up @@ -3376,12 +3404,19 @@ static void b43_set_retry_limits(struct b43_wldev *dev,
static void b43_wireless_core_exit(struct b43_wldev *dev)
{
struct b43_phy *phy = &dev->phy;
u32 macctl;

B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED);
if (b43_status(dev) != B43_STAT_INITIALIZED)
return;
b43_set_status(dev, B43_STAT_UNINIT);

/* Stop the microcode PSM. */
macctl = b43_read32(dev, B43_MMIO_MACCTL);
macctl &= ~B43_MACCTL_PSM_RUN;
macctl |= B43_MACCTL_PSM_JMP0;
b43_write32(dev, B43_MMIO_MACCTL, macctl);

b43_leds_exit(dev);
b43_rng_exit(dev->wl);
b43_dma_free(dev);
Expand Down

0 comments on commit 1f7d87b

Please sign in to comment.