aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43
diff options
context:
space:
mode:
authorMichael Buesch <mb@bu3sch.de>2008-01-22 14:23:34 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:10:49 -0500
commit1f7d87b0ecacefe4541c75901cbcf29efba42ca6 (patch)
tree74fc6e174a171b10b564161dd4eab3261ace4dee /drivers/net/wireless/b43
parent4248d2f81159f62b7c7b83398fede653d449fd56 (diff)
b43: Fix MAC control and microcode init
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>
Diffstat (limited to 'drivers/net/wireless/b43')
-rw-r--r--drivers/net/wireless/b43/main.c61
1 files changed, 48 insertions, 13 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 2e563662c9a2..88d2c15d3fbe 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1778,9 +1778,20 @@ static int b43_upload_microcode(struct b43_wldev *dev)
1778 const __be32 *data; 1778 const __be32 *data;
1779 unsigned int i, len; 1779 unsigned int i, len;
1780 u16 fwrev, fwpatch, fwdate, fwtime; 1780 u16 fwrev, fwpatch, fwdate, fwtime;
1781 u32 tmp; 1781 u32 tmp, macctl;
1782 int err = 0; 1782 int err = 0;
1783 1783
1784 /* Jump the microcode PSM to offset 0 */
1785 macctl = b43_read32(dev, B43_MMIO_MACCTL);
1786 B43_WARN_ON(macctl & B43_MACCTL_PSM_RUN);
1787 macctl |= B43_MACCTL_PSM_JMP0;
1788 b43_write32(dev, B43_MMIO_MACCTL, macctl);
1789 /* Zero out all microcode PSM registers and shared memory. */
1790 for (i = 0; i < 64; i++)
1791 b43_shm_write16(dev, B43_SHM_SCRATCH, i, 0);
1792 for (i = 0; i < 4096; i += 2)
1793 b43_shm_write16(dev, B43_SHM_SHARED, i, 0);
1794
1784 /* Upload Microcode. */ 1795 /* Upload Microcode. */
1785 data = (__be32 *) (dev->fw.ucode.data->data + hdr_len); 1796 data = (__be32 *) (dev->fw.ucode.data->data + hdr_len);
1786 len = (dev->fw.ucode.data->size - hdr_len) / sizeof(__be32); 1797 len = (dev->fw.ucode.data->size - hdr_len) / sizeof(__be32);
@@ -1805,9 +1816,12 @@ static int b43_upload_microcode(struct b43_wldev *dev)
1805 } 1816 }
1806 1817
1807 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL); 1818 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, B43_IRQ_ALL);
1808 b43_write32(dev, B43_MMIO_MACCTL, 1819
1809 B43_MACCTL_PSM_RUN | 1820 /* Start the microcode PSM */
1810 B43_MACCTL_IHR_ENABLED | B43_MACCTL_INFRA); 1821 macctl = b43_read32(dev, B43_MMIO_MACCTL);
1822 macctl &= ~B43_MACCTL_PSM_JMP0;
1823 macctl |= B43_MACCTL_PSM_RUN;
1824 b43_write32(dev, B43_MMIO_MACCTL, macctl);
1811 1825
1812 /* Wait for the microcode to load and respond */ 1826 /* Wait for the microcode to load and respond */
1813 i = 0; 1827 i = 0;
@@ -1816,13 +1830,17 @@ static int b43_upload_microcode(struct b43_wldev *dev)
1816 if (tmp == B43_IRQ_MAC_SUSPENDED) 1830 if (tmp == B43_IRQ_MAC_SUSPENDED)
1817 break; 1831 break;
1818 i++; 1832 i++;
1819 if (i >= 50) { 1833 if (i >= 20) {
1820 b43err(dev->wl, "Microcode not responding\n"); 1834 b43err(dev->wl, "Microcode not responding\n");
1821 b43_print_fw_helptext(dev->wl, 1); 1835 b43_print_fw_helptext(dev->wl, 1);
1822 err = -ENODEV; 1836 err = -ENODEV;
1823 goto out; 1837 goto error;
1838 }
1839 msleep_interruptible(50);
1840 if (signal_pending(current)) {
1841 err = -EINTR;
1842 goto error;
1824 } 1843 }
1825 udelay(10);
1826 } 1844 }
1827 b43_read32(dev, B43_MMIO_GEN_IRQ_REASON); /* dummy read */ 1845 b43_read32(dev, B43_MMIO_GEN_IRQ_REASON); /* dummy read */
1828 1846
@@ -1837,9 +1855,8 @@ static int b43_upload_microcode(struct b43_wldev *dev)
1837 "binary drivers older than version 4.x is unsupported. " 1855 "binary drivers older than version 4.x is unsupported. "
1838 "You must upgrade your firmware files.\n"); 1856 "You must upgrade your firmware files.\n");
1839 b43_print_fw_helptext(dev->wl, 1); 1857 b43_print_fw_helptext(dev->wl, 1);
1840 b43_write32(dev, B43_MMIO_MACCTL, 0);
1841 err = -EOPNOTSUPP; 1858 err = -EOPNOTSUPP;
1842 goto out; 1859 goto error;
1843 } 1860 }
1844 b43dbg(dev->wl, "Loading firmware version %u.%u " 1861 b43dbg(dev->wl, "Loading firmware version %u.%u "
1845 "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n", 1862 "(20%.2i-%.2i-%.2i %.2i:%.2i:%.2i)\n",
@@ -1856,7 +1873,14 @@ static int b43_upload_microcode(struct b43_wldev *dev)
1856 b43_print_fw_helptext(dev->wl, 0); 1873 b43_print_fw_helptext(dev->wl, 0);
1857 } 1874 }
1858 1875
1859out: 1876 return 0;
1877
1878error:
1879 macctl = b43_read32(dev, B43_MMIO_MACCTL);
1880 macctl &= ~B43_MACCTL_PSM_RUN;
1881 macctl |= B43_MACCTL_PSM_JMP0;
1882 b43_write32(dev, B43_MMIO_MACCTL, macctl);
1883
1860 return err; 1884 return err;
1861} 1885}
1862 1886
@@ -2228,11 +2252,15 @@ static int b43_chip_init(struct b43_wldev *dev)
2228{ 2252{
2229 struct b43_phy *phy = &dev->phy; 2253 struct b43_phy *phy = &dev->phy;
2230 int err, tmp; 2254 int err, tmp;
2231 u32 value32; 2255 u32 value32, macctl;
2232 u16 value16; 2256 u16 value16;
2233 2257
2234 b43_write32(dev, B43_MMIO_MACCTL, 2258 /* Initialize the MAC control */
2235 B43_MACCTL_PSM_JMP0 | B43_MACCTL_IHR_ENABLED); 2259 macctl = B43_MACCTL_IHR_ENABLED | B43_MACCTL_SHM_ENABLED;
2260 if (dev->phy.gmode)
2261 macctl |= B43_MACCTL_GMODE;
2262 macctl |= B43_MACCTL_INFRA;
2263 b43_write32(dev, B43_MMIO_MACCTL, macctl);
2236 2264
2237 err = b43_request_firmware(dev); 2265 err = b43_request_firmware(dev);
2238 if (err) 2266 if (err)
@@ -3376,12 +3404,19 @@ static void b43_set_retry_limits(struct b43_wldev *dev,
3376static void b43_wireless_core_exit(struct b43_wldev *dev) 3404static void b43_wireless_core_exit(struct b43_wldev *dev)
3377{ 3405{
3378 struct b43_phy *phy = &dev->phy; 3406 struct b43_phy *phy = &dev->phy;
3407 u32 macctl;
3379 3408
3380 B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED); 3409 B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED);
3381 if (b43_status(dev) != B43_STAT_INITIALIZED) 3410 if (b43_status(dev) != B43_STAT_INITIALIZED)
3382 return; 3411 return;
3383 b43_set_status(dev, B43_STAT_UNINIT); 3412 b43_set_status(dev, B43_STAT_UNINIT);
3384 3413
3414 /* Stop the microcode PSM. */
3415 macctl = b43_read32(dev, B43_MMIO_MACCTL);
3416 macctl &= ~B43_MACCTL_PSM_RUN;
3417 macctl |= B43_MACCTL_PSM_JMP0;
3418 b43_write32(dev, B43_MMIO_MACCTL, macctl);
3419
3385 b43_leds_exit(dev); 3420 b43_leds_exit(dev);
3386 b43_rng_exit(dev->wl); 3421 b43_rng_exit(dev->wl);
3387 b43_dma_free(dev); 3422 b43_dma_free(dev);