summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2007-12-22 21:56:30 +0100
committerDavid S. Miller <davem@davemloft.net>2008-01-28 15:09:15 -0800
commitf3dd3fcc2c79b950801641075b33b86acc372d9b (patch)
tree2b2416fd2a41629b9837255abcf12f8501f9a2f5 /drivers/net/wireless/b43/main.c
parent9db1f6d725921c413cc344beda5e7e7d011b02e7 (diff)
b43: Fix chip access validation for new devices
This fixes chip access validation for newer devices (4318 and up, I think) This patch fixes probing of a PCMCIA based 4318 device. Signed-off-by: Michael Buesch <mb@bu3sch.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c40
1 files changed, 25 insertions, 15 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index f4c14272332..6b3013c2d96 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2408,32 +2408,42 @@ static void b43_periodic_tasks_setup(struct b43_wldev *dev)
queue_delayed_work(dev->wl->hw->workqueue, work, 0);
}
-/* Validate access to the chip (SHM) */
+/* Check if communication with the device works correctly. */
static int b43_validate_chipaccess(struct b43_wldev *dev)
{
- u32 value;
- u32 shm_backup;
+ u32 v, backup;
- shm_backup = b43_shm_read32(dev, B43_SHM_SHARED, 0);
- b43_shm_write32(dev, B43_SHM_SHARED, 0, 0xAA5555AA);
- if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0xAA5555AA)
- goto error;
+ backup = b43_shm_read32(dev, B43_SHM_SHARED, 0);
+
+ /* Check for read/write and endianness problems. */
b43_shm_write32(dev, B43_SHM_SHARED, 0, 0x55AAAA55);
if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0x55AAAA55)
goto error;
- b43_shm_write32(dev, B43_SHM_SHARED, 0, shm_backup);
-
- value = b43_read32(dev, B43_MMIO_MACCTL);
- if ((value | B43_MACCTL_GMODE) !=
- (B43_MACCTL_GMODE | B43_MACCTL_IHR_ENABLED))
+ b43_shm_write32(dev, B43_SHM_SHARED, 0, 0xAA5555AA);
+ if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0xAA5555AA)
goto error;
- value = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
- if (value)
+ b43_shm_write32(dev, B43_SHM_SHARED, 0, backup);
+
+ if ((dev->dev->id.revision >= 3) && (dev->dev->id.revision <= 10)) {
+ /* The 32bit register shadows the two 16bit registers
+ * with update sideeffects. Validate this. */
+ b43_write16(dev, B43_MMIO_TSF_CFP_START, 0xAAAA);
+ b43_write32(dev, B43_MMIO_TSF_CFP_START, 0xCCCCBBBB);
+ if (b43_read16(dev, B43_MMIO_TSF_CFP_START_LOW) != 0xBBBB)
+ goto error;
+ if (b43_read16(dev, B43_MMIO_TSF_CFP_START_HIGH) != 0xCCCC)
+ goto error;
+ }
+ b43_write32(dev, B43_MMIO_TSF_CFP_START, 0);
+
+ v = b43_read32(dev, B43_MMIO_MACCTL);
+ v |= B43_MACCTL_GMODE;
+ if (v != (B43_MACCTL_GMODE | B43_MACCTL_IHR_ENABLED))
goto error;
return 0;
- error:
+error:
b43err(dev->wl, "Failed to validate the chipaccess\n");
return -ENODEV;
}