aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);