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.c71
1 files changed, 60 insertions, 11 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 47731cb0d815..2c9088633ec6 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1262,6 +1262,23 @@ static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1262 flags |= B43_BCMA_IOCTL_GMODE; 1262 flags |= B43_BCMA_IOCTL_GMODE;
1263 b43_device_enable(dev, flags); 1263 b43_device_enable(dev, flags);
1264 1264
1265 if (dev->phy.type == B43_PHYTYPE_AC) {
1266 u16 tmp;
1267
1268 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
1269 tmp &= ~B43_BCMA_IOCTL_DAC;
1270 tmp |= 0x100;
1271 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
1272
1273 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
1274 tmp &= ~B43_BCMA_IOCTL_PHY_CLKEN;
1275 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
1276
1277 tmp = bcma_aread32(dev->dev->bdev, BCMA_IOCTL);
1278 tmp |= B43_BCMA_IOCTL_PHY_CLKEN;
1279 bcma_awrite32(dev->dev->bdev, BCMA_IOCTL, tmp);
1280 }
1281
1265 bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST); 1282 bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST);
1266 b43_bcma_phy_reset(dev); 1283 b43_bcma_phy_reset(dev);
1267 bcma_core_pll_ctl(dev->dev->bdev, req, status, true); 1284 bcma_core_pll_ctl(dev->dev->bdev, req, status, true);
@@ -1601,12 +1618,26 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
1601 unsigned int rate; 1618 unsigned int rate;
1602 u16 ctl; 1619 u16 ctl;
1603 int antenna; 1620 int antenna;
1604 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(dev->wl->current_beacon); 1621 struct ieee80211_tx_info *info;
1622 unsigned long flags;
1623 struct sk_buff *beacon_skb;
1605 1624
1606 bcn = (const struct ieee80211_mgmt *)(dev->wl->current_beacon->data); 1625 spin_lock_irqsave(&dev->wl->beacon_lock, flags);
1607 len = min_t(size_t, dev->wl->current_beacon->len, 1626 info = IEEE80211_SKB_CB(dev->wl->current_beacon);
1608 0x200 - sizeof(struct b43_plcp_hdr6));
1609 rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value; 1627 rate = ieee80211_get_tx_rate(dev->wl->hw, info)->hw_value;
1628 /* Clone the beacon, so it cannot go away, while we write it to hw. */
1629 beacon_skb = skb_clone(dev->wl->current_beacon, GFP_ATOMIC);
1630 spin_unlock_irqrestore(&dev->wl->beacon_lock, flags);
1631
1632 if (!beacon_skb) {
1633 b43dbg(dev->wl, "Could not upload beacon. "
1634 "Failed to clone beacon skb.");
1635 return;
1636 }
1637
1638 bcn = (const struct ieee80211_mgmt *)(beacon_skb->data);
1639 len = min_t(size_t, beacon_skb->len,
1640 0x200 - sizeof(struct b43_plcp_hdr6));
1610 1641
1611 b43_write_template_common(dev, (const u8 *)bcn, 1642 b43_write_template_common(dev, (const u8 *)bcn,
1612 len, ram_offset, shm_size_offset, rate); 1643 len, ram_offset, shm_size_offset, rate);
@@ -1674,6 +1705,8 @@ static void b43_write_beacon_template(struct b43_wldev *dev,
1674 B43_SHM_SH_DTIMPER, 0); 1705 B43_SHM_SH_DTIMPER, 0);
1675 } 1706 }
1676 b43dbg(dev->wl, "Updated beacon template at 0x%x\n", ram_offset); 1707 b43dbg(dev->wl, "Updated beacon template at 0x%x\n", ram_offset);
1708
1709 dev_kfree_skb_any(beacon_skb);
1677} 1710}
1678 1711
1679static void b43_upload_beacon0(struct b43_wldev *dev) 1712static void b43_upload_beacon0(struct b43_wldev *dev)
@@ -1790,13 +1823,13 @@ static void b43_beacon_update_trigger_work(struct work_struct *work)
1790 mutex_unlock(&wl->mutex); 1823 mutex_unlock(&wl->mutex);
1791} 1824}
1792 1825
1793/* Asynchronously update the packet templates in template RAM. 1826/* Asynchronously update the packet templates in template RAM. */
1794 * Locking: Requires wl->mutex to be locked. */
1795static void b43_update_templates(struct b43_wl *wl) 1827static void b43_update_templates(struct b43_wl *wl)
1796{ 1828{
1797 struct sk_buff *beacon; 1829 struct sk_buff *beacon, *old_beacon;
1830 unsigned long flags;
1798 1831
1799 /* This is the top half of the ansynchronous beacon update. 1832 /* This is the top half of the asynchronous beacon update.
1800 * The bottom half is the beacon IRQ. 1833 * The bottom half is the beacon IRQ.
1801 * Beacon update must be asynchronous to avoid sending an 1834 * Beacon update must be asynchronous to avoid sending an
1802 * invalid beacon. This can happen for example, if the firmware 1835 * invalid beacon. This can happen for example, if the firmware
@@ -1810,12 +1843,17 @@ static void b43_update_templates(struct b43_wl *wl)
1810 if (unlikely(!beacon)) 1843 if (unlikely(!beacon))
1811 return; 1844 return;
1812 1845
1813 if (wl->current_beacon) 1846 spin_lock_irqsave(&wl->beacon_lock, flags);
1814 dev_kfree_skb_any(wl->current_beacon); 1847 old_beacon = wl->current_beacon;
1815 wl->current_beacon = beacon; 1848 wl->current_beacon = beacon;
1816 wl->beacon0_uploaded = false; 1849 wl->beacon0_uploaded = false;
1817 wl->beacon1_uploaded = false; 1850 wl->beacon1_uploaded = false;
1851 spin_unlock_irqrestore(&wl->beacon_lock, flags);
1852
1818 ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger); 1853 ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
1854
1855 if (old_beacon)
1856 dev_kfree_skb_any(old_beacon);
1819} 1857}
1820 1858
1821static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) 1859static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
@@ -4318,6 +4356,7 @@ redo:
4318 mutex_unlock(&wl->mutex); 4356 mutex_unlock(&wl->mutex);
4319 cancel_delayed_work_sync(&dev->periodic_work); 4357 cancel_delayed_work_sync(&dev->periodic_work);
4320 cancel_work_sync(&wl->tx_work); 4358 cancel_work_sync(&wl->tx_work);
4359 b43_leds_stop(dev);
4321 mutex_lock(&wl->mutex); 4360 mutex_lock(&wl->mutex);
4322 dev = wl->current_dev; 4361 dev = wl->current_dev;
4323 if (!dev || b43_status(dev) < B43_STAT_STARTED) { 4362 if (!dev || b43_status(dev) < B43_STAT_STARTED) {
@@ -4505,6 +4544,12 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4505 unsupported = 1; 4544 unsupported = 1;
4506 break; 4545 break;
4507#endif 4546#endif
4547#ifdef CONFIG_B43_PHY_AC
4548 case B43_PHYTYPE_AC:
4549 if (phy_rev > 1)
4550 unsupported = 1;
4551 break;
4552#endif
4508 default: 4553 default:
4509 unsupported = 1; 4554 unsupported = 1;
4510 } 4555 }
@@ -4601,6 +4646,10 @@ static int b43_phy_versioning(struct b43_wldev *dev)
4601 if (radio_id != 0x2064) 4646 if (radio_id != 0x2064)
4602 unsupported = 1; 4647 unsupported = 1;
4603 break; 4648 break;
4649 case B43_PHYTYPE_AC:
4650 if (radio_id != 0x2069)
4651 unsupported = 1;
4652 break;
4604 default: 4653 default:
4605 B43_WARN_ON(1); 4654 B43_WARN_ON(1);
4606 } 4655 }
@@ -5094,7 +5143,6 @@ static int b43_op_beacon_set_tim(struct ieee80211_hw *hw,
5094{ 5143{
5095 struct b43_wl *wl = hw_to_b43_wl(hw); 5144 struct b43_wl *wl = hw_to_b43_wl(hw);
5096 5145
5097 /* FIXME: add locking */
5098 b43_update_templates(wl); 5146 b43_update_templates(wl);
5099 5147
5100 return 0; 5148 return 0;
@@ -5584,6 +5632,7 @@ static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
5584 wl->hw = hw; 5632 wl->hw = hw;
5585 mutex_init(&wl->mutex); 5633 mutex_init(&wl->mutex);
5586 spin_lock_init(&wl->hardirq_lock); 5634 spin_lock_init(&wl->hardirq_lock);
5635 spin_lock_init(&wl->beacon_lock);
5587 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work); 5636 INIT_WORK(&wl->beacon_update_trigger, b43_beacon_update_trigger_work);
5588 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work); 5637 INIT_WORK(&wl->txpower_adjust_work, b43_phy_txpower_adjust_work);
5589 INIT_WORK(&wl->tx_work, b43_tx_work); 5638 INIT_WORK(&wl->tx_work, b43_tx_work);