diff options
-rw-r--r-- | drivers/net/wireless/b43/main.c | 61 |
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 | ||
1859 | out: | 1876 | return 0; |
1877 | |||
1878 | error: | ||
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, | |||
3376 | static void b43_wireless_core_exit(struct b43_wldev *dev) | 3404 | static 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); |