aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/b43/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
-rw-r--r--drivers/net/wireless/b43/main.c460
1 files changed, 229 insertions, 231 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index ae05f6671149..7a9a3fa55425 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -291,7 +291,7 @@ static struct ieee80211_supported_band b43_band_2GHz = {
291 291
292static void b43_wireless_core_exit(struct b43_wldev *dev); 292static void b43_wireless_core_exit(struct b43_wldev *dev);
293static int b43_wireless_core_init(struct b43_wldev *dev); 293static int b43_wireless_core_init(struct b43_wldev *dev);
294static void b43_wireless_core_stop(struct b43_wldev *dev); 294static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev);
295static int b43_wireless_core_start(struct b43_wldev *dev); 295static int b43_wireless_core_start(struct b43_wldev *dev);
296 296
297static int b43_ratelimit(struct b43_wl *wl) 297static int b43_ratelimit(struct b43_wl *wl)
@@ -390,7 +390,7 @@ static inline void b43_shm_control_word(struct b43_wldev *dev,
390 b43_write32(dev, B43_MMIO_SHM_CONTROL, control); 390 b43_write32(dev, B43_MMIO_SHM_CONTROL, control);
391} 391}
392 392
393u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) 393u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
394{ 394{
395 u32 ret; 395 u32 ret;
396 396
@@ -413,20 +413,7 @@ out:
413 return ret; 413 return ret;
414} 414}
415 415
416u32 b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset) 416u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
417{
418 struct b43_wl *wl = dev->wl;
419 unsigned long flags;
420 u32 ret;
421
422 spin_lock_irqsave(&wl->shm_lock, flags);
423 ret = __b43_shm_read32(dev, routing, offset);
424 spin_unlock_irqrestore(&wl->shm_lock, flags);
425
426 return ret;
427}
428
429u16 __b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset)
430{ 417{
431 u16 ret; 418 u16 ret;
432 419
@@ -447,20 +434,7 @@ out:
447 return ret; 434 return ret;
448} 435}
449 436
450u16 b43_shm_read16(struct b43_wldev *dev, u16 routing, u16 offset) 437void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
451{
452 struct b43_wl *wl = dev->wl;
453 unsigned long flags;
454 u16 ret;
455
456 spin_lock_irqsave(&wl->shm_lock, flags);
457 ret = __b43_shm_read16(dev, routing, offset);
458 spin_unlock_irqrestore(&wl->shm_lock, flags);
459
460 return ret;
461}
462
463void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value)
464{ 438{
465 if (routing == B43_SHM_SHARED) { 439 if (routing == B43_SHM_SHARED) {
466 B43_WARN_ON(offset & 0x0001); 440 B43_WARN_ON(offset & 0x0001);
@@ -480,17 +454,7 @@ void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value
480 b43_write32(dev, B43_MMIO_SHM_DATA, value); 454 b43_write32(dev, B43_MMIO_SHM_DATA, value);
481} 455}
482 456
483void b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value) 457void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
484{
485 struct b43_wl *wl = dev->wl;
486 unsigned long flags;
487
488 spin_lock_irqsave(&wl->shm_lock, flags);
489 __b43_shm_write32(dev, routing, offset, value);
490 spin_unlock_irqrestore(&wl->shm_lock, flags);
491}
492
493void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
494{ 458{
495 if (routing == B43_SHM_SHARED) { 459 if (routing == B43_SHM_SHARED) {
496 B43_WARN_ON(offset & 0x0001); 460 B43_WARN_ON(offset & 0x0001);
@@ -506,16 +470,6 @@ void __b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value
506 b43_write16(dev, B43_MMIO_SHM_DATA, value); 470 b43_write16(dev, B43_MMIO_SHM_DATA, value);
507} 471}
508 472
509void b43_shm_write16(struct b43_wldev *dev, u16 routing, u16 offset, u16 value)
510{
511 struct b43_wl *wl = dev->wl;
512 unsigned long flags;
513
514 spin_lock_irqsave(&wl->shm_lock, flags);
515 __b43_shm_write16(dev, routing, offset, value);
516 spin_unlock_irqrestore(&wl->shm_lock, flags);
517}
518
519/* Read HostFlags */ 473/* Read HostFlags */
520u64 b43_hf_read(struct b43_wldev *dev) 474u64 b43_hf_read(struct b43_wldev *dev)
521{ 475{
@@ -685,22 +639,11 @@ static void b43_short_slot_timing_disable(struct b43_wldev *dev)
685 b43_set_slot_time(dev, 20); 639 b43_set_slot_time(dev, 20);
686} 640}
687 641
688/* Synchronize IRQ top- and bottom-half.
689 * IRQs must be masked before calling this.
690 * This must not be called with the irq_lock held.
691 */
692static void b43_synchronize_irq(struct b43_wldev *dev)
693{
694 synchronize_irq(dev->dev->irq);
695 tasklet_kill(&dev->isr_tasklet);
696}
697
698/* DummyTransmission function, as documented on 642/* DummyTransmission function, as documented on
699 * http://bcm-v4.sipsolutions.net/802.11/DummyTransmission 643 * http://bcm-v4.sipsolutions.net/802.11/DummyTransmission
700 */ 644 */
701void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on) 645void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
702{ 646{
703 struct b43_wl *wl = dev->wl;
704 struct b43_phy *phy = &dev->phy; 647 struct b43_phy *phy = &dev->phy;
705 unsigned int i, max_loop; 648 unsigned int i, max_loop;
706 u16 value; 649 u16 value;
@@ -720,9 +663,6 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
720 buffer[0] = 0x000B846E; 663 buffer[0] = 0x000B846E;
721 } 664 }
722 665
723 spin_lock_irq(&wl->irq_lock);
724 write_lock(&wl->tx_lock);
725
726 for (i = 0; i < 5; i++) 666 for (i = 0; i < 5; i++)
727 b43_ram_write(dev, i * 4, buffer[i]); 667 b43_ram_write(dev, i * 4, buffer[i]);
728 668
@@ -778,9 +718,6 @@ void b43_dummy_transmission(struct b43_wldev *dev, bool ofdm, bool pa_on)
778 } 718 }
779 if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5) 719 if (phy->radio_ver == 0x2050 && phy->radio_rev <= 0x5)
780 b43_radio_write16(dev, 0x0051, 0x0037); 720 b43_radio_write16(dev, 0x0051, 0x0037);
781
782 write_unlock(&wl->tx_lock);
783 spin_unlock_irq(&wl->irq_lock);
784} 721}
785 722
786static void key_write(struct b43_wldev *dev, 723static void key_write(struct b43_wldev *dev,
@@ -1620,6 +1557,27 @@ static void handle_irq_beacon(struct b43_wldev *dev)
1620 } 1557 }
1621} 1558}
1622 1559
1560static void b43_do_beacon_update_trigger_work(struct b43_wldev *dev)
1561{
1562 u32 old_irq_mask = dev->irq_mask;
1563
1564 /* update beacon right away or defer to irq */
1565 handle_irq_beacon(dev);
1566 if (old_irq_mask != dev->irq_mask) {
1567 /* The handler updated the IRQ mask. */
1568 B43_WARN_ON(!dev->irq_mask);
1569 if (b43_read32(dev, B43_MMIO_GEN_IRQ_MASK)) {
1570 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
1571 } else {
1572 /* Device interrupts are currently disabled. That means
1573 * we just ran the hardirq handler and scheduled the
1574 * IRQ thread. The thread will write the IRQ mask when
1575 * it finished, so there's nothing to do here. Writing
1576 * the mask _here_ would incorrectly re-enable IRQs. */
1577 }
1578 }
1579}
1580
1623static void b43_beacon_update_trigger_work(struct work_struct *work) 1581static void b43_beacon_update_trigger_work(struct work_struct *work)
1624{ 1582{
1625 struct b43_wl *wl = container_of(work, struct b43_wl, 1583 struct b43_wl *wl = container_of(work, struct b43_wl,
@@ -1629,19 +1587,22 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
1629 mutex_lock(&wl->mutex); 1587 mutex_lock(&wl->mutex);
1630 dev = wl->current_dev; 1588 dev = wl->current_dev;
1631 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) { 1589 if (likely(dev && (b43_status(dev) >= B43_STAT_INITIALIZED))) {
1632 spin_lock_irq(&wl->irq_lock); 1590 if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
1633 /* update beacon right away or defer to irq */ 1591 /* wl->mutex is enough. */
1634 handle_irq_beacon(dev); 1592 b43_do_beacon_update_trigger_work(dev);
1635 /* The handler might have updated the IRQ mask. */ 1593 mmiowb();
1636 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask); 1594 } else {
1637 mmiowb(); 1595 spin_lock_irq(&wl->hardirq_lock);
1638 spin_unlock_irq(&wl->irq_lock); 1596 b43_do_beacon_update_trigger_work(dev);
1597 mmiowb();
1598 spin_unlock_irq(&wl->hardirq_lock);
1599 }
1639 } 1600 }
1640 mutex_unlock(&wl->mutex); 1601 mutex_unlock(&wl->mutex);
1641} 1602}
1642 1603
1643/* Asynchronously update the packet templates in template RAM. 1604/* Asynchronously update the packet templates in template RAM.
1644 * Locking: Requires wl->irq_lock to be locked. */ 1605 * Locking: Requires wl->mutex to be locked. */
1645static void b43_update_templates(struct b43_wl *wl) 1606static void b43_update_templates(struct b43_wl *wl)
1646{ 1607{
1647 struct sk_buff *beacon; 1608 struct sk_buff *beacon;
@@ -1778,18 +1739,15 @@ out:
1778 B43_DEBUGIRQ_REASON_REG, B43_DEBUGIRQ_ACK); 1739 B43_DEBUGIRQ_REASON_REG, B43_DEBUGIRQ_ACK);
1779} 1740}
1780 1741
1781/* Interrupt handler bottom-half */ 1742static void b43_do_interrupt_thread(struct b43_wldev *dev)
1782static void b43_interrupt_tasklet(struct b43_wldev *dev)
1783{ 1743{
1784 u32 reason; 1744 u32 reason;
1785 u32 dma_reason[ARRAY_SIZE(dev->dma_reason)]; 1745 u32 dma_reason[ARRAY_SIZE(dev->dma_reason)];
1786 u32 merged_dma_reason = 0; 1746 u32 merged_dma_reason = 0;
1787 int i; 1747 int i;
1788 unsigned long flags;
1789
1790 spin_lock_irqsave(&dev->wl->irq_lock, flags);
1791 1748
1792 B43_WARN_ON(b43_status(dev) != B43_STAT_STARTED); 1749 if (unlikely(b43_status(dev) != B43_STAT_STARTED))
1750 return;
1793 1751
1794 reason = dev->irq_reason; 1752 reason = dev->irq_reason;
1795 for (i = 0; i < ARRAY_SIZE(dma_reason); i++) { 1753 for (i = 0; i < ARRAY_SIZE(dma_reason); i++) {
@@ -1822,8 +1780,6 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
1822 dma_reason[2], dma_reason[3], 1780 dma_reason[2], dma_reason[3],
1823 dma_reason[4], dma_reason[5]); 1781 dma_reason[4], dma_reason[5]);
1824 b43_controller_restart(dev, "DMA error"); 1782 b43_controller_restart(dev, "DMA error");
1825 mmiowb();
1826 spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
1827 return; 1783 return;
1828 } 1784 }
1829 if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) { 1785 if (merged_dma_reason & B43_DMAIRQ_NONFATALMASK) {
@@ -1867,47 +1823,36 @@ static void b43_interrupt_tasklet(struct b43_wldev *dev)
1867 if (reason & B43_IRQ_TX_OK) 1823 if (reason & B43_IRQ_TX_OK)
1868 handle_irq_transmit_status(dev); 1824 handle_irq_transmit_status(dev);
1869 1825
1826 /* Re-enable interrupts on the device by restoring the current interrupt mask. */
1870 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask); 1827 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, dev->irq_mask);
1871 mmiowb();
1872 spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
1873} 1828}
1874 1829
1875static void b43_interrupt_ack(struct b43_wldev *dev, u32 reason) 1830/* Interrupt thread handler. Handles device interrupts in thread context. */
1831static irqreturn_t b43_interrupt_thread_handler(int irq, void *dev_id)
1876{ 1832{
1877 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, reason); 1833 struct b43_wldev *dev = dev_id;
1878 1834
1879 b43_write32(dev, B43_MMIO_DMA0_REASON, dev->dma_reason[0]); 1835 mutex_lock(&dev->wl->mutex);
1880 b43_write32(dev, B43_MMIO_DMA1_REASON, dev->dma_reason[1]); 1836 b43_do_interrupt_thread(dev);
1881 b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]); 1837 mmiowb();
1882 b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]); 1838 mutex_unlock(&dev->wl->mutex);
1883 b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]); 1839
1884/* Unused ring 1840 return IRQ_HANDLED;
1885 b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
1886*/
1887} 1841}
1888 1842
1889/* Interrupt handler top-half */ 1843static irqreturn_t b43_do_interrupt(struct b43_wldev *dev)
1890static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1891{ 1844{
1892 irqreturn_t ret = IRQ_NONE;
1893 struct b43_wldev *dev = dev_id;
1894 u32 reason; 1845 u32 reason;
1895 1846
1896 B43_WARN_ON(!dev); 1847 /* This code runs under wl->hardirq_lock, but _only_ on non-SDIO busses.
1848 * On SDIO, this runs under wl->mutex. */
1897 1849
1898 spin_lock(&dev->wl->irq_lock);
1899
1900 if (unlikely(b43_status(dev) < B43_STAT_STARTED)) {
1901 /* This can only happen on shared IRQ lines. */
1902 goto out;
1903 }
1904 reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON); 1850 reason = b43_read32(dev, B43_MMIO_GEN_IRQ_REASON);
1905 if (reason == 0xffffffff) /* shared IRQ */ 1851 if (reason == 0xffffffff) /* shared IRQ */
1906 goto out; 1852 return IRQ_NONE;
1907 ret = IRQ_HANDLED;
1908 reason &= dev->irq_mask; 1853 reason &= dev->irq_mask;
1909 if (!reason) 1854 if (!reason)
1910 goto out; 1855 return IRQ_HANDLED;
1911 1856
1912 dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON) 1857 dev->dma_reason[0] = b43_read32(dev, B43_MMIO_DMA0_REASON)
1913 & 0x0001DC00; 1858 & 0x0001DC00;
@@ -1924,15 +1869,38 @@ static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1924 & 0x0000DC00; 1869 & 0x0000DC00;
1925*/ 1870*/
1926 1871
1927 b43_interrupt_ack(dev, reason); 1872 /* ACK the interrupt. */
1928 /* disable all IRQs. They are enabled again in the bottom half. */ 1873 b43_write32(dev, B43_MMIO_GEN_IRQ_REASON, reason);
1874 b43_write32(dev, B43_MMIO_DMA0_REASON, dev->dma_reason[0]);
1875 b43_write32(dev, B43_MMIO_DMA1_REASON, dev->dma_reason[1]);
1876 b43_write32(dev, B43_MMIO_DMA2_REASON, dev->dma_reason[2]);
1877 b43_write32(dev, B43_MMIO_DMA3_REASON, dev->dma_reason[3]);
1878 b43_write32(dev, B43_MMIO_DMA4_REASON, dev->dma_reason[4]);
1879/* Unused ring
1880 b43_write32(dev, B43_MMIO_DMA5_REASON, dev->dma_reason[5]);
1881*/
1882
1883 /* Disable IRQs on the device. The IRQ thread handler will re-enable them. */
1929 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); 1884 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
1930 /* save the reason code and call our bottom half. */ 1885 /* Save the reason bitmasks for the IRQ thread handler. */
1931 dev->irq_reason = reason; 1886 dev->irq_reason = reason;
1932 tasklet_schedule(&dev->isr_tasklet); 1887
1933out: 1888 return IRQ_WAKE_THREAD;
1889}
1890
1891/* Interrupt handler top-half. This runs with interrupts disabled. */
1892static irqreturn_t b43_interrupt_handler(int irq, void *dev_id)
1893{
1894 struct b43_wldev *dev = dev_id;
1895 irqreturn_t ret;
1896
1897 if (unlikely(b43_status(dev) < B43_STAT_STARTED))
1898 return IRQ_NONE;
1899
1900 spin_lock(&dev->wl->hardirq_lock);
1901 ret = b43_do_interrupt(dev);
1934 mmiowb(); 1902 mmiowb();
1935 spin_unlock(&dev->wl->irq_lock); 1903 spin_unlock(&dev->wl->hardirq_lock);
1936 1904
1937 return ret; 1905 return ret;
1938} 1906}
@@ -3038,15 +3006,12 @@ static void b43_security_init(struct b43_wldev *dev)
3038static int b43_rng_read(struct hwrng *rng, u32 *data) 3006static int b43_rng_read(struct hwrng *rng, u32 *data)
3039{ 3007{
3040 struct b43_wl *wl = (struct b43_wl *)rng->priv; 3008 struct b43_wl *wl = (struct b43_wl *)rng->priv;
3041 unsigned long flags;
3042 3009
3043 /* Don't take wl->mutex here, as it could deadlock with 3010 /* FIXME: We need to take wl->mutex here to make sure the device
3044 * hwrng internal locking. It's not needed to take 3011 * is not going away from under our ass. However it could deadlock
3045 * wl->mutex here, anyway. */ 3012 * with hwrng internal locking. */
3046 3013
3047 spin_lock_irqsave(&wl->irq_lock, flags);
3048 *data = b43_read16(wl->current_dev, B43_MMIO_RNG); 3014 *data = b43_read16(wl->current_dev, B43_MMIO_RNG);
3049 spin_unlock_irqrestore(&wl->irq_lock, flags);
3050 3015
3051 return (sizeof(u16)); 3016 return (sizeof(u16));
3052} 3017}
@@ -3082,46 +3047,52 @@ static int b43_rng_init(struct b43_wl *wl)
3082 return err; 3047 return err;
3083} 3048}
3084 3049
3085static int b43_op_tx(struct ieee80211_hw *hw, 3050static void b43_tx_work(struct work_struct *work)
3086 struct sk_buff *skb)
3087{ 3051{
3088 struct b43_wl *wl = hw_to_b43_wl(hw); 3052 struct b43_wl *wl = container_of(work, struct b43_wl, tx_work);
3089 struct b43_wldev *dev = wl->current_dev; 3053 struct b43_wldev *dev;
3090 unsigned long flags; 3054 struct sk_buff *skb;
3091 int err; 3055 int err = 0;
3092 3056
3093 if (unlikely(skb->len < 2 + 2 + 6)) { 3057 mutex_lock(&wl->mutex);
3094 /* Too short, this can't be a valid frame. */ 3058 dev = wl->current_dev;
3095 goto drop_packet; 3059 if (unlikely(!dev || b43_status(dev) < B43_STAT_STARTED)) {
3060 mutex_unlock(&wl->mutex);
3061 return;
3096 } 3062 }
3097 B43_WARN_ON(skb_shinfo(skb)->nr_frags);
3098 if (unlikely(!dev))
3099 goto drop_packet;
3100 3063
3101 /* Transmissions on seperate queues can run concurrently. */ 3064 while (skb_queue_len(&wl->tx_queue)) {
3102 read_lock_irqsave(&wl->tx_lock, flags); 3065 skb = skb_dequeue(&wl->tx_queue);
3103 3066
3104 err = -ENODEV;
3105 if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
3106 if (b43_using_pio_transfers(dev)) 3067 if (b43_using_pio_transfers(dev))
3107 err = b43_pio_tx(dev, skb); 3068 err = b43_pio_tx(dev, skb);
3108 else 3069 else
3109 err = b43_dma_tx(dev, skb); 3070 err = b43_dma_tx(dev, skb);
3071 if (unlikely(err))
3072 dev_kfree_skb(skb); /* Drop it */
3110 } 3073 }
3111 3074
3112 read_unlock_irqrestore(&wl->tx_lock, flags); 3075 mutex_unlock(&wl->mutex);
3076}
3113 3077
3114 if (unlikely(err)) 3078static int b43_op_tx(struct ieee80211_hw *hw,
3115 goto drop_packet; 3079 struct sk_buff *skb)
3116 return NETDEV_TX_OK; 3080{
3081 struct b43_wl *wl = hw_to_b43_wl(hw);
3082
3083 if (unlikely(skb->len < 2 + 2 + 6)) {
3084 /* Too short, this can't be a valid frame. */
3085 dev_kfree_skb_any(skb);
3086 return NETDEV_TX_OK;
3087 }
3088 B43_WARN_ON(skb_shinfo(skb)->nr_frags);
3089
3090 skb_queue_tail(&wl->tx_queue, skb);
3091 ieee80211_queue_work(wl->hw, &wl->tx_work);
3117 3092
3118drop_packet:
3119 /* We can not transmit this packet. Drop it. */
3120 dev_kfree_skb_any(skb);
3121 return NETDEV_TX_OK; 3093 return NETDEV_TX_OK;
3122} 3094}
3123 3095
3124/* Locking: wl->irq_lock */
3125static void b43_qos_params_upload(struct b43_wldev *dev, 3096static void b43_qos_params_upload(struct b43_wldev *dev,
3126 const struct ieee80211_tx_queue_params *p, 3097 const struct ieee80211_tx_queue_params *p,
3127 u16 shm_offset) 3098 u16 shm_offset)
@@ -3130,6 +3101,9 @@ static void b43_qos_params_upload(struct b43_wldev *dev,
3130 int bslots, tmp; 3101 int bslots, tmp;
3131 unsigned int i; 3102 unsigned int i;
3132 3103
3104 if (!dev->qos_enabled)
3105 return;
3106
3133 bslots = b43_read16(dev, B43_MMIO_RNG) & p->cw_min; 3107 bslots = b43_read16(dev, B43_MMIO_RNG) & p->cw_min;
3134 3108
3135 memset(&params, 0, sizeof(params)); 3109 memset(&params, 0, sizeof(params));
@@ -3175,6 +3149,9 @@ static void b43_qos_upload_all(struct b43_wldev *dev)
3175 struct b43_qos_params *params; 3149 struct b43_qos_params *params;
3176 unsigned int i; 3150 unsigned int i;
3177 3151
3152 if (!dev->qos_enabled)
3153 return;
3154
3178 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) != 3155 BUILD_BUG_ON(ARRAY_SIZE(b43_qos_shm_offsets) !=
3179 ARRAY_SIZE(wl->qos_params)); 3156 ARRAY_SIZE(wl->qos_params));
3180 3157
@@ -3234,6 +3211,16 @@ static void b43_qos_clear(struct b43_wl *wl)
3234/* Initialize the core's QOS capabilities */ 3211/* Initialize the core's QOS capabilities */
3235static void b43_qos_init(struct b43_wldev *dev) 3212static void b43_qos_init(struct b43_wldev *dev)
3236{ 3213{
3214 if (!dev->qos_enabled) {
3215 /* Disable QOS support. */
3216 b43_hf_write(dev, b43_hf_read(dev) & ~B43_HF_EDCF);
3217 b43_write16(dev, B43_MMIO_IFSCTL,
3218 b43_read16(dev, B43_MMIO_IFSCTL)
3219 & ~B43_MMIO_IFSCTL_USE_EDCF);
3220 b43dbg(dev->wl, "QoS disabled\n");
3221 return;
3222 }
3223
3237 /* Upload the current QOS parameters. */ 3224 /* Upload the current QOS parameters. */
3238 b43_qos_upload_all(dev); 3225 b43_qos_upload_all(dev);
3239 3226
@@ -3242,6 +3229,7 @@ static void b43_qos_init(struct b43_wldev *dev)
3242 b43_write16(dev, B43_MMIO_IFSCTL, 3229 b43_write16(dev, B43_MMIO_IFSCTL,
3243 b43_read16(dev, B43_MMIO_IFSCTL) 3230 b43_read16(dev, B43_MMIO_IFSCTL)
3244 | B43_MMIO_IFSCTL_USE_EDCF); 3231 | B43_MMIO_IFSCTL_USE_EDCF);
3232 b43dbg(dev->wl, "QoS enabled\n");
3245} 3233}
3246 3234
3247static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue, 3235static int b43_op_conf_tx(struct ieee80211_hw *hw, u16 _queue,
@@ -3283,22 +3271,20 @@ static int b43_op_get_tx_stats(struct ieee80211_hw *hw,
3283 struct ieee80211_tx_queue_stats *stats) 3271 struct ieee80211_tx_queue_stats *stats)
3284{ 3272{
3285 struct b43_wl *wl = hw_to_b43_wl(hw); 3273 struct b43_wl *wl = hw_to_b43_wl(hw);
3286 struct b43_wldev *dev = wl->current_dev; 3274 struct b43_wldev *dev;
3287 unsigned long flags;
3288 int err = -ENODEV; 3275 int err = -ENODEV;
3289 3276
3290 if (!dev) 3277 mutex_lock(&wl->mutex);
3291 goto out; 3278 dev = wl->current_dev;
3292 spin_lock_irqsave(&wl->irq_lock, flags); 3279 if (dev && b43_status(dev) >= B43_STAT_STARTED) {
3293 if (likely(b43_status(dev) >= B43_STAT_STARTED)) {
3294 if (b43_using_pio_transfers(dev)) 3280 if (b43_using_pio_transfers(dev))
3295 b43_pio_get_tx_stats(dev, stats); 3281 b43_pio_get_tx_stats(dev, stats);
3296 else 3282 else
3297 b43_dma_get_tx_stats(dev, stats); 3283 b43_dma_get_tx_stats(dev, stats);
3298 err = 0; 3284 err = 0;
3299 } 3285 }
3300 spin_unlock_irqrestore(&wl->irq_lock, flags); 3286 mutex_unlock(&wl->mutex);
3301out: 3287
3302 return err; 3288 return err;
3303} 3289}
3304 3290
@@ -3306,11 +3292,10 @@ static int b43_op_get_stats(struct ieee80211_hw *hw,
3306 struct ieee80211_low_level_stats *stats) 3292 struct ieee80211_low_level_stats *stats)
3307{ 3293{
3308 struct b43_wl *wl = hw_to_b43_wl(hw); 3294 struct b43_wl *wl = hw_to_b43_wl(hw);
3309 unsigned long flags;
3310 3295
3311 spin_lock_irqsave(&wl->irq_lock, flags); 3296 mutex_lock(&wl->mutex);
3312 memcpy(stats, &wl->ieee_stats, sizeof(*stats)); 3297 memcpy(stats, &wl->ieee_stats, sizeof(*stats));
3313 spin_unlock_irqrestore(&wl->irq_lock, flags); 3298 mutex_unlock(&wl->mutex);
3314 3299
3315 return 0; 3300 return 0;
3316} 3301}
@@ -3322,7 +3307,6 @@ static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
3322 u64 tsf; 3307 u64 tsf;
3323 3308
3324 mutex_lock(&wl->mutex); 3309 mutex_lock(&wl->mutex);
3325 spin_lock_irq(&wl->irq_lock);
3326 dev = wl->current_dev; 3310 dev = wl->current_dev;
3327 3311
3328 if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) 3312 if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
@@ -3330,7 +3314,6 @@ static u64 b43_op_get_tsf(struct ieee80211_hw *hw)
3330 else 3314 else
3331 tsf = 0; 3315 tsf = 0;
3332 3316
3333 spin_unlock_irq(&wl->irq_lock);
3334 mutex_unlock(&wl->mutex); 3317 mutex_unlock(&wl->mutex);
3335 3318
3336 return tsf; 3319 return tsf;
@@ -3342,13 +3325,11 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw, u64 tsf)
3342 struct b43_wldev *dev; 3325 struct b43_wldev *dev;
3343 3326
3344 mutex_lock(&wl->mutex); 3327 mutex_lock(&wl->mutex);
3345 spin_lock_irq(&wl->irq_lock);
3346 dev = wl->current_dev; 3328 dev = wl->current_dev;
3347 3329
3348 if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED)) 3330 if (dev && (b43_status(dev) >= B43_STAT_INITIALIZED))
3349 b43_tsf_write(dev, tsf); 3331 b43_tsf_write(dev, tsf);
3350 3332
3351 spin_unlock_irq(&wl->irq_lock);
3352 mutex_unlock(&wl->mutex); 3333 mutex_unlock(&wl->mutex);
3353} 3334}
3354 3335
@@ -3434,7 +3415,7 @@ static int b43_switch_band(struct b43_wl *wl, struct ieee80211_channel *chan)
3434 prev_status = b43_status(down_dev); 3415 prev_status = b43_status(down_dev);
3435 /* Shutdown the currently running core. */ 3416 /* Shutdown the currently running core. */
3436 if (prev_status >= B43_STAT_STARTED) 3417 if (prev_status >= B43_STAT_STARTED)
3437 b43_wireless_core_stop(down_dev); 3418 down_dev = b43_wireless_core_stop(down_dev);
3438 if (prev_status >= B43_STAT_INITIALIZED) 3419 if (prev_status >= B43_STAT_INITIALIZED)
3439 b43_wireless_core_exit(down_dev); 3420 b43_wireless_core_exit(down_dev);
3440 3421
@@ -3498,7 +3479,6 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3498 struct b43_wldev *dev; 3479 struct b43_wldev *dev;
3499 struct b43_phy *phy; 3480 struct b43_phy *phy;
3500 struct ieee80211_conf *conf = &hw->conf; 3481 struct ieee80211_conf *conf = &hw->conf;
3501 unsigned long flags;
3502 int antenna; 3482 int antenna;
3503 int err = 0; 3483 int err = 0;
3504 3484
@@ -3529,13 +3509,11 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3529 3509
3530 /* Adjust the desired TX power level. */ 3510 /* Adjust the desired TX power level. */
3531 if (conf->power_level != 0) { 3511 if (conf->power_level != 0) {
3532 spin_lock_irqsave(&wl->irq_lock, flags);
3533 if (conf->power_level != phy->desired_txpower) { 3512 if (conf->power_level != phy->desired_txpower) {
3534 phy->desired_txpower = conf->power_level; 3513 phy->desired_txpower = conf->power_level;
3535 b43_phy_txpower_check(dev, B43_TXPWR_IGNORE_TIME | 3514 b43_phy_txpower_check(dev, B43_TXPWR_IGNORE_TIME |
3536 B43_TXPWR_IGNORE_TSSI); 3515 B43_TXPWR_IGNORE_TSSI);
3537 } 3516 }
3538 spin_unlock_irqrestore(&wl->irq_lock, flags);
3539 } 3517 }
3540 3518
3541 /* Antennas for RX and management frame TX. */ 3519 /* Antennas for RX and management frame TX. */
@@ -3620,7 +3598,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3620{ 3598{
3621 struct b43_wl *wl = hw_to_b43_wl(hw); 3599 struct b43_wl *wl = hw_to_b43_wl(hw);
3622 struct b43_wldev *dev; 3600 struct b43_wldev *dev;
3623 unsigned long flags;
3624 3601
3625 mutex_lock(&wl->mutex); 3602 mutex_lock(&wl->mutex);
3626 3603
@@ -3630,7 +3607,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3630 3607
3631 B43_WARN_ON(wl->vif != vif); 3608 B43_WARN_ON(wl->vif != vif);
3632 3609
3633 spin_lock_irqsave(&wl->irq_lock, flags);
3634 if (changed & BSS_CHANGED_BSSID) { 3610 if (changed & BSS_CHANGED_BSSID) {
3635 if (conf->bssid) 3611 if (conf->bssid)
3636 memcpy(wl->bssid, conf->bssid, ETH_ALEN); 3612 memcpy(wl->bssid, conf->bssid, ETH_ALEN);
@@ -3648,7 +3624,6 @@ static void b43_op_bss_info_changed(struct ieee80211_hw *hw,
3648 if (changed & BSS_CHANGED_BSSID) 3624 if (changed & BSS_CHANGED_BSSID)
3649 b43_write_mac_bssid_templates(dev); 3625 b43_write_mac_bssid_templates(dev);
3650 } 3626 }
3651 spin_unlock_irqrestore(&wl->irq_lock, flags);
3652 3627
3653 b43_mac_suspend(dev); 3628 b43_mac_suspend(dev);
3654 3629
@@ -3689,15 +3664,6 @@ static int b43_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3689 return -ENOSPC; /* User disabled HW-crypto */ 3664 return -ENOSPC; /* User disabled HW-crypto */
3690 3665
3691 mutex_lock(&wl->mutex); 3666 mutex_lock(&wl->mutex);
3692 spin_lock_irq(&wl->irq_lock);
3693 write_lock(&wl->tx_lock);
3694 /* Why do we need all this locking here?
3695 * mutex -> Every config operation must take it.
3696 * irq_lock -> We modify the dev->key array, which is accessed
3697 * in the IRQ handlers.
3698 * tx_lock -> We modify the dev->key array, which is accessed
3699 * in the TX handler.
3700 */
3701 3667
3702 dev = wl->current_dev; 3668 dev = wl->current_dev;
3703 err = -ENODEV; 3669 err = -ENODEV;
@@ -3789,8 +3755,6 @@ out_unlock:
3789 sta ? sta->addr : bcast_addr); 3755 sta ? sta->addr : bcast_addr);
3790 b43_dump_keymemory(dev); 3756 b43_dump_keymemory(dev);
3791 } 3757 }
3792 write_unlock(&wl->tx_lock);
3793 spin_unlock_irq(&wl->irq_lock);
3794 mutex_unlock(&wl->mutex); 3758 mutex_unlock(&wl->mutex);
3795 3759
3796 return err; 3760 return err;
@@ -3801,15 +3765,15 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
3801 u64 multicast) 3765 u64 multicast)
3802{ 3766{
3803 struct b43_wl *wl = hw_to_b43_wl(hw); 3767 struct b43_wl *wl = hw_to_b43_wl(hw);
3804 struct b43_wldev *dev = wl->current_dev; 3768 struct b43_wldev *dev;
3805 unsigned long flags;
3806 3769
3770 mutex_lock(&wl->mutex);
3771 dev = wl->current_dev;
3807 if (!dev) { 3772 if (!dev) {
3808 *fflags = 0; 3773 *fflags = 0;
3809 return; 3774 goto out_unlock;
3810 } 3775 }
3811 3776
3812 spin_lock_irqsave(&wl->irq_lock, flags);
3813 *fflags &= FIF_PROMISC_IN_BSS | 3777 *fflags &= FIF_PROMISC_IN_BSS |
3814 FIF_ALLMULTI | 3778 FIF_ALLMULTI |
3815 FIF_FCSFAIL | 3779 FIF_FCSFAIL |
@@ -3830,41 +3794,70 @@ static void b43_op_configure_filter(struct ieee80211_hw *hw,
3830 3794
3831 if (changed && b43_status(dev) >= B43_STAT_INITIALIZED) 3795 if (changed && b43_status(dev) >= B43_STAT_INITIALIZED)
3832 b43_adjust_opmode(dev); 3796 b43_adjust_opmode(dev);
3833 spin_unlock_irqrestore(&wl->irq_lock, flags); 3797
3798out_unlock:
3799 mutex_unlock(&wl->mutex);
3834} 3800}
3835 3801
3836/* Locking: wl->mutex */ 3802/* Locking: wl->mutex
3837static void b43_wireless_core_stop(struct b43_wldev *dev) 3803 * Returns the current dev. This might be different from the passed in dev,
3804 * because the core might be gone away while we unlocked the mutex. */
3805static struct b43_wldev * b43_wireless_core_stop(struct b43_wldev *dev)
3838{ 3806{
3839 struct b43_wl *wl = dev->wl; 3807 struct b43_wl *wl = dev->wl;
3840 unsigned long flags; 3808 struct b43_wldev *orig_dev;
3841 3809
3842 if (b43_status(dev) < B43_STAT_STARTED) 3810redo:
3843 return; 3811 if (!dev || b43_status(dev) < B43_STAT_STARTED)
3812 return dev;
3844 3813
3845 /* Disable and sync interrupts. We must do this before than 3814 /* Cancel work. Unlock to avoid deadlocks. */
3846 * setting the status to INITIALIZED, as the interrupt handler 3815 mutex_unlock(&wl->mutex);
3847 * won't care about IRQs then. */ 3816 cancel_delayed_work_sync(&dev->periodic_work);
3848 spin_lock_irqsave(&wl->irq_lock, flags); 3817 cancel_work_sync(&wl->tx_work);
3849 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0); 3818 mutex_lock(&wl->mutex);
3850 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* flush */ 3819 dev = wl->current_dev;
3851 spin_unlock_irqrestore(&wl->irq_lock, flags); 3820 if (!dev || b43_status(dev) < B43_STAT_STARTED) {
3852 b43_synchronize_irq(dev); 3821 /* Whoops, aliens ate up the device while we were unlocked. */
3822 return dev;
3823 }
3853 3824
3854 write_lock_irqsave(&wl->tx_lock, flags); 3825 /* Disable interrupts on the device. */
3855 b43_set_status(dev, B43_STAT_INITIALIZED); 3826 b43_set_status(dev, B43_STAT_INITIALIZED);
3856 write_unlock_irqrestore(&wl->tx_lock, flags); 3827 if (0 /*FIXME dev->dev->bus->bustype == SSB_BUSTYPE_SDIO*/) {
3857 3828 /* wl->mutex is locked. That is enough. */
3858 b43_pio_stop(dev); 3829 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
3830 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
3831 } else {
3832 spin_lock_irq(&wl->hardirq_lock);
3833 b43_write32(dev, B43_MMIO_GEN_IRQ_MASK, 0);
3834 b43_read32(dev, B43_MMIO_GEN_IRQ_MASK); /* Flush */
3835 spin_unlock_irq(&wl->hardirq_lock);
3836 }
3837 /* Synchronize the interrupt handlers. Unlock to avoid deadlocks. */
3838 orig_dev = dev;
3859 mutex_unlock(&wl->mutex); 3839 mutex_unlock(&wl->mutex);
3860 /* Must unlock as it would otherwise deadlock. No races here. 3840 synchronize_irq(dev->dev->irq);
3861 * Cancel the possibly running self-rearming periodic work. */
3862 cancel_delayed_work_sync(&dev->periodic_work);
3863 mutex_lock(&wl->mutex); 3841 mutex_lock(&wl->mutex);
3842 dev = wl->current_dev;
3843 if (!dev)
3844 return dev;
3845 if (dev != orig_dev) {
3846 if (b43_status(dev) >= B43_STAT_STARTED)
3847 goto redo;
3848 return dev;
3849 }
3850 B43_WARN_ON(b43_read32(dev, B43_MMIO_GEN_IRQ_MASK));
3851
3852 /* Drain the TX queue */
3853 while (skb_queue_len(&wl->tx_queue))
3854 dev_kfree_skb(skb_dequeue(&wl->tx_queue));
3864 3855
3865 b43_mac_suspend(dev); 3856 b43_mac_suspend(dev);
3866 free_irq(dev->dev->irq, dev); 3857 free_irq(dev->dev->irq, dev);
3867 b43dbg(wl, "Wireless interface stopped\n"); 3858 b43dbg(wl, "Wireless interface stopped\n");
3859
3860 return dev;
3868} 3861}
3869 3862
3870/* Locking: wl->mutex */ 3863/* Locking: wl->mutex */
@@ -3875,8 +3868,9 @@ static int b43_wireless_core_start(struct b43_wldev *dev)
3875 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED); 3868 B43_WARN_ON(b43_status(dev) != B43_STAT_INITIALIZED);
3876 3869
3877 drain_txstatus_queue(dev); 3870 drain_txstatus_queue(dev);
3878 err = request_irq(dev->dev->irq, b43_interrupt_handler, 3871 err = request_threaded_irq(dev->dev->irq, b43_interrupt_handler,
3879 IRQF_SHARED, KBUILD_MODNAME, dev); 3872 b43_interrupt_thread_handler,
3873 IRQF_SHARED, KBUILD_MODNAME, dev);
3880 if (err) { 3874 if (err) {
3881 b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq); 3875 b43err(dev->wl, "Cannot request IRQ-%d\n", dev->dev->irq);
3882 goto out; 3876 goto out;
@@ -4098,16 +4092,20 @@ static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
4098 bus->pcicore.dev->id.revision <= 5) { 4092 bus->pcicore.dev->id.revision <= 5) {
4099 /* IMCFGLO timeouts workaround. */ 4093 /* IMCFGLO timeouts workaround. */
4100 tmp = ssb_read32(dev->dev, SSB_IMCFGLO); 4094 tmp = ssb_read32(dev->dev, SSB_IMCFGLO);
4101 tmp &= ~SSB_IMCFGLO_REQTO;
4102 tmp &= ~SSB_IMCFGLO_SERTO;
4103 switch (bus->bustype) { 4095 switch (bus->bustype) {
4104 case SSB_BUSTYPE_PCI: 4096 case SSB_BUSTYPE_PCI:
4105 case SSB_BUSTYPE_PCMCIA: 4097 case SSB_BUSTYPE_PCMCIA:
4098 tmp &= ~SSB_IMCFGLO_REQTO;
4099 tmp &= ~SSB_IMCFGLO_SERTO;
4106 tmp |= 0x32; 4100 tmp |= 0x32;
4107 break; 4101 break;
4108 case SSB_BUSTYPE_SSB: 4102 case SSB_BUSTYPE_SSB:
4103 tmp &= ~SSB_IMCFGLO_REQTO;
4104 tmp &= ~SSB_IMCFGLO_SERTO;
4109 tmp |= 0x53; 4105 tmp |= 0x53;
4110 break; 4106 break;
4107 default:
4108 break;
4111 } 4109 }
4112 ssb_write32(dev->dev, SSB_IMCFGLO, tmp); 4110 ssb_write32(dev->dev, SSB_IMCFGLO, tmp);
4113 } 4111 }
@@ -4155,8 +4153,8 @@ static void b43_wireless_core_exit(struct b43_wldev *dev)
4155{ 4153{
4156 u32 macctl; 4154 u32 macctl;
4157 4155
4158 B43_WARN_ON(b43_status(dev) > B43_STAT_INITIALIZED); 4156 B43_WARN_ON(dev && b43_status(dev) > B43_STAT_INITIALIZED);
4159 if (b43_status(dev) != B43_STAT_INITIALIZED) 4157 if (!dev || b43_status(dev) != B43_STAT_INITIALIZED)
4160 return; 4158 return;
4161 b43_set_status(dev, B43_STAT_UNINIT); 4159 b43_set_status(dev, B43_STAT_UNINIT);
4162 4160
@@ -4309,7 +4307,6 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
4309{ 4307{
4310 struct b43_wl *wl = hw_to_b43_wl(hw); 4308 struct b43_wl *wl = hw_to_b43_wl(hw);
4311 struct b43_wldev *dev; 4309 struct b43_wldev *dev;
4312 unsigned long flags;
4313 int err = -EOPNOTSUPP; 4310 int err = -EOPNOTSUPP;
4314 4311
4315 /* TODO: allow WDS/AP devices to coexist */ 4312 /* TODO: allow WDS/AP devices to coexist */
@@ -4333,12 +4330,10 @@ static int b43_op_add_interface(struct ieee80211_hw *hw,
4333 wl->if_type = conf->type; 4330 wl->if_type = conf->type;
4334 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN); 4331 memcpy(wl->mac_addr, conf->mac_addr, ETH_ALEN);
4335 4332
4336 spin_lock_irqsave(&wl->irq_lock, flags);
4337 b43_adjust_opmode(dev); 4333 b43_adjust_opmode(dev);
4338 b43_set_pretbtt(dev); 4334 b43_set_pretbtt(dev);
4339 b43_set_synth_pu_delay(dev, 0); 4335 b43_set_synth_pu_delay(dev, 0);
4340 b43_upload_card_macaddress(dev); 4336 b43_upload_card_macaddress(dev);
4341 spin_unlock_irqrestore(&wl->irq_lock, flags);
4342 4337
4343 err = 0; 4338 err = 0;
4344 out_mutex_unlock: 4339 out_mutex_unlock:
@@ -4352,7 +4347,6 @@ static void b43_op_remove_interface(struct ieee80211_hw *hw,
4352{ 4347{
4353 struct b43_wl *wl = hw_to_b43_wl(hw); 4348 struct b43_wl *wl = hw_to_b43_wl(hw);
4354 struct b43_wldev *dev = wl->current_dev; 4349 struct b43_wldev *dev = wl->current_dev;
4355 unsigned long flags;
4356 4350
4357 b43dbg(wl, "Removing Interface type %d\n", conf->type); 4351 b43dbg(wl, "Removing Interface type %d\n", conf->type);
4358 4352
@@ -4364,11 +4358,9 @@ static void b43_op_remove_interface(struct ieee80211_hw *hw,
4364 4358
4365 wl->operating = 0; 4359 wl->operating = 0;
4366 4360
4367 spin_lock_irqsave(&wl->irq_lock, flags);
4368 b43_adjust_opmode(dev); 4361 b43_adjust_opmode(dev);
4369 memset(wl->mac_addr, 0, ETH_ALEN); 4362 memset(wl->mac_addr, 0, ETH_ALEN);
4370 b43_upload_card_macaddress(dev); 4363 b43_upload_card_macaddress(dev);
4371 spin_unlock_irqrestore(&wl->irq_lock, flags);
4372 4364
4373 mutex_unlock(&wl->mutex); 4365 mutex_unlock(&wl->mutex);
4374} 4366}
@@ -4428,10 +4420,15 @@ static void b43_op_stop(struct ieee80211_hw *hw)
4428 cancel_work_sync(&(wl->beacon_update_trigger)); 4420 cancel_work_sync(&(wl->beacon_update_trigger));
4429 4421
4430 mutex_lock(&wl->mutex); 4422 mutex_lock(&wl->mutex);
4431 if (b43_status(dev) >= B43_STAT_STARTED) 4423 if (b43_status(dev) >= B43_STAT_STARTED) {
4432 b43_wireless_core_stop(dev); 4424 dev = b43_wireless_core_stop(dev);
4425 if (!dev)
4426 goto out_unlock;
4427 }
4433 b43_wireless_core_exit(dev); 4428 b43_wireless_core_exit(dev);
4434 wl->radio_enabled = 0; 4429 wl->radio_enabled = 0;
4430
4431out_unlock:
4435 mutex_unlock(&wl->mutex); 4432 mutex_unlock(&wl->mutex);
4436 4433
4437 cancel_work_sync(&(wl->txpower_adjust_work)); 4434 cancel_work_sync(&(wl->txpower_adjust_work));
@@ -4441,11 +4438,10 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
4441 struct ieee80211_sta *sta, bool set) 4438 struct ieee80211_sta *sta, bool set)
4442{ 4439{
4443 struct b43_wl *wl = hw_to_b43_wl(hw); 4440 struct b43_wl *wl = hw_to_b43_wl(hw);
4444 unsigned long flags;
4445 4441
4446 spin_lock_irqsave(&wl->irq_lock, flags); 4442 mutex_lock(&wl->mutex);
4447 b43_update_templates(wl); 4443 b43_update_templates(wl);
4448 spin_unlock_irqrestore(&wl->irq_lock, flags); 4444 mutex_unlock(&wl->mutex);
4449 4445
4450 return 0; 4446 return 0;
4451} 4447}
@@ -4526,8 +4522,13 @@ static void b43_chip_reset(struct work_struct *work)
4526 4522
4527 prev_status = b43_status(dev); 4523 prev_status = b43_status(dev);
4528 /* Bring the device down... */ 4524 /* Bring the device down... */
4529 if (prev_status >= B43_STAT_STARTED) 4525 if (prev_status >= B43_STAT_STARTED) {
4530 b43_wireless_core_stop(dev); 4526 dev = b43_wireless_core_stop(dev);
4527 if (!dev) {
4528 err = -ENODEV;
4529 goto out;
4530 }
4531 }
4531 if (prev_status >= B43_STAT_INITIALIZED) 4532 if (prev_status >= B43_STAT_INITIALIZED)
4532 b43_wireless_core_exit(dev); 4533 b43_wireless_core_exit(dev);
4533 4534
@@ -4742,9 +4743,6 @@ static int b43_one_core_attach(struct ssb_device *dev, struct b43_wl *wl)
4742 wldev->wl = wl; 4743 wldev->wl = wl;
4743 b43_set_status(wldev, B43_STAT_UNINIT); 4744 b43_set_status(wldev, B43_STAT_UNINIT);
4744 wldev->bad_frames_preempt = modparam_bad_frames_preempt; 4745 wldev->bad_frames_preempt = modparam_bad_frames_preempt;
4745 tasklet_init(&wldev->isr_tasklet,
4746 (void (*)(unsigned long))b43_interrupt_tasklet,
4747 (unsigned long)wldev);
4748 INIT_LIST_HEAD(&wldev->list); 4746 INIT_LIST_HEAD(&wldev->list);
4749 4747
4750 err = b43_wireless_core_attach(wldev); 4748 err = b43_wireless_core_attach(wldev);
@@ -4841,14 +4839,14 @@ static int b43_wireless_init(struct ssb_device *dev)
4841 4839
4842 /* Initialize struct b43_wl */ 4840 /* Initialize struct b43_wl */
4843 wl->hw = hw; 4841 wl->hw = hw;
4844 spin_lock_init(&wl->irq_lock);
4845 rwlock_init(&wl->tx_lock);
4846 spin_lock_init(&wl->leds_lock); 4842 spin_lock_init(&wl->leds_lock);
4847 spin_lock_init(&wl->shm_lock);
4848 mutex_init(&wl->mutex); 4843 mutex_init(&wl->mutex);
4844 spin_lock_init(&wl->hardirq_lock);
4849 INIT_LIST_HEAD(&wl->devlist); 4845 INIT_LIST_HEAD(&wl->devlist);
4850 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); 4846 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
4851 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); 4847 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
4848 INIT_WORK(&wl->tx_work, b43_tx_work);
4849 skb_queue_head_init(&wl->tx_queue);
4852 4850
4853 ssb_set_devtypedata(dev, wl); 4851 ssb_set_devtypedata(dev, wl);
4854 b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n", 4852 b43info(wl, "Broadcom %04X WLAN found (core revision %u)\n",
@@ -4946,8 +4944,8 @@ static int b43_suspend(struct ssb_device *dev, pm_message_t state)
4946 wldev->suspend_in_progress = true; 4944 wldev->suspend_in_progress = true;
4947 wldev->suspend_init_status = b43_status(wldev); 4945 wldev->suspend_init_status = b43_status(wldev);
4948 if (wldev->suspend_init_status >= B43_STAT_STARTED) 4946 if (wldev->suspend_init_status >= B43_STAT_STARTED)
4949 b43_wireless_core_stop(wldev); 4947 wldev = b43_wireless_core_stop(wldev);
4950 if (wldev->suspend_init_status >= B43_STAT_INITIALIZED) 4948 if (wldev && wldev->suspend_init_status >= B43_STAT_INITIALIZED)
4951 b43_wireless_core_exit(wldev); 4949 b43_wireless_core_exit(wldev);
4952 mutex_unlock(&wl->mutex); 4950 mutex_unlock(&wl->mutex);
4953 4951