aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-08-06 15:57:18 -0400
committerDavid S. Miller <davem@davemloft.net>2009-08-06 15:57:18 -0400
commitbfe34ebbaa125f00da309f59cc9d30febe1e3115 (patch)
tree505b43fc81be09ec5b42f82a3e64f300a5e838d5
parent3d7ddd540b4c2d24c6a3e7a52c083a0c31e6151c (diff)
parent6b4f645a491ac29c7dced415d034eea7736155a6 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--drivers/net/usb/rndis_host.c50
-rw-r--r--drivers/net/usb/usbnet.c32
-rw-r--r--drivers/net/wireless/Kconfig4
-rw-r--r--drivers/net/wireless/at76c50x-usb.c18
-rw-r--r--drivers/net/wireless/ath/Kconfig21
-rw-r--r--drivers/net/wireless/ath/ar9170/Kconfig4
-rw-r--r--drivers/net/wireless/ath/ar9170/led.c11
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c29
-rw-r--r--drivers/net/wireless/ath/ath5k/Kconfig3
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig1
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c106
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c175
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c368
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h11
-rw-r--r--drivers/net/wireless/ath/ath9k/initvals.h666
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c89
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.c53
-rw-r--r--drivers/net/wireless/ath/ath9k/phy.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h37
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c2
-rw-r--r--drivers/net/wireless/b43/b43.h11
-rw-r--r--drivers/net/wireless/b43/dma.c21
-rw-r--r--drivers/net/wireless/b43/main.c42
-rw-r--r--drivers/net/wireless/b43/phy_common.c9
-rw-r--r--drivers/net/wireless/b43/phy_common.h5
-rw-r--r--drivers/net/wireless/b43/phy_lp.c94
-rw-r--r--drivers/net/wireless/b43/phy_lp.h11
-rw-r--r--drivers/net/wireless/b43/phy_n.c3
-rw-r--r--drivers/net/wireless/b43/pio.c2
-rw-r--r--drivers/net/wireless/b43legacy/dma.c22
-rw-r--r--drivers/net/wireless/b43legacy/main.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c48
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c51
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h17
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c9
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c49
-rw-r--r--drivers/net/wireless/libertas/if_spi.c2
-rw-r--r--drivers/net/wireless/libertas/wext.c2
-rw-r--r--drivers/net/wireless/orinoco/cfg.c41
-rw-r--r--drivers/net/wireless/p54/led.c5
-rw-r--r--drivers/net/wireless/p54/main.c2
-rw-r--r--drivers/net/wireless/p54/p54spi.c4
-rw-r--r--drivers/net/wireless/p54/txrx.c2
-rw-r--r--drivers/net/wireless/rndis_wlan.c617
-rw-r--r--drivers/net/wireless/rt2x00/Kconfig8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c5
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_dev.c2
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187_leds.c10
-rw-r--r--drivers/net/wireless/strip.c9
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c2
-rw-r--r--include/linux/rfkill.h1
-rw-r--r--include/linux/usb/rndis_host.h13
-rw-r--r--include/linux/usb/usbnet.h6
-rw-r--r--include/net/cfg80211.h14
-rw-r--r--include/net/mac80211.h58
-rw-r--r--net/mac80211/driver-trace.c3
-rw-r--r--net/mac80211/ibss.c6
-rw-r--r--net/mac80211/ieee80211_i.h9
-rw-r--r--net/mac80211/iface.c36
-rw-r--r--net/mac80211/main.c40
-rw-r--r--net/mac80211/mesh.c10
-rw-r--r--net/mac80211/mesh_hwmp.c4
-rw-r--r--net/mac80211/mlme.c113
-rw-r--r--net/mac80211/pm.c8
-rw-r--r--net/mac80211/scan.c8
-rw-r--r--net/mac80211/tx.c2
-rw-r--r--net/mac80211/util.c41
-rw-r--r--net/rfkill/core.c4
-rw-r--r--net/wireless/core.c24
-rw-r--r--net/wireless/core.h8
-rw-r--r--net/wireless/mlme.c38
-rw-r--r--net/wireless/reg.c107
-rw-r--r--net/wireless/reg.h15
-rw-r--r--net/wireless/sme.c55
-rw-r--r--net/wireless/wext.c1
96 files changed, 2758 insertions, 797 deletions
diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c
index 2232232b7989..d032bba9bc4c 100644
--- a/drivers/net/usb/rndis_host.c
+++ b/drivers/net/usb/rndis_host.c
@@ -65,6 +65,32 @@ void rndis_status(struct usbnet *dev, struct urb *urb)
65EXPORT_SYMBOL_GPL(rndis_status); 65EXPORT_SYMBOL_GPL(rndis_status);
66 66
67/* 67/*
68 * RNDIS indicate messages.
69 */
70static void rndis_msg_indicate(struct usbnet *dev, struct rndis_indicate *msg,
71 int buflen)
72{
73 struct cdc_state *info = (void *)&dev->data;
74 struct device *udev = &info->control->dev;
75
76 if (dev->driver_info->indication) {
77 dev->driver_info->indication(dev, msg, buflen);
78 } else {
79 switch (msg->status) {
80 case RNDIS_STATUS_MEDIA_CONNECT:
81 dev_info(udev, "rndis media connect\n");
82 break;
83 case RNDIS_STATUS_MEDIA_DISCONNECT:
84 dev_info(udev, "rndis media disconnect\n");
85 break;
86 default:
87 dev_info(udev, "rndis indication: 0x%08x\n",
88 le32_to_cpu(msg->status));
89 }
90 }
91}
92
93/*
68 * RPC done RNDIS-style. Caller guarantees: 94 * RPC done RNDIS-style. Caller guarantees:
69 * - message is properly byteswapped 95 * - message is properly byteswapped
70 * - there's no other request pending 96 * - there's no other request pending
@@ -143,27 +169,9 @@ int rndis_command(struct usbnet *dev, struct rndis_msg_hdr *buf, int buflen)
143 request_id, xid); 169 request_id, xid);
144 /* then likely retry */ 170 /* then likely retry */
145 } else switch (buf->msg_type) { 171 } else switch (buf->msg_type) {
146 case RNDIS_MSG_INDICATE: { /* fault/event */ 172 case RNDIS_MSG_INDICATE: /* fault/event */
147 struct rndis_indicate *msg = (void *)buf; 173 rndis_msg_indicate(dev, (void *)buf, buflen);
148 int state = 0; 174
149
150 switch (msg->status) {
151 case RNDIS_STATUS_MEDIA_CONNECT:
152 state = 1;
153 case RNDIS_STATUS_MEDIA_DISCONNECT:
154 dev_info(&info->control->dev,
155 "rndis media %sconnect\n",
156 !state?"dis":"");
157 if (dev->driver_info->link_change)
158 dev->driver_info->link_change(
159 dev, state);
160 break;
161 default:
162 dev_info(&info->control->dev,
163 "rndis indication: 0x%08x\n",
164 le32_to_cpu(msg->status));
165 }
166 }
167 break; 175 break;
168 case RNDIS_MSG_KEEPALIVE: { /* ping */ 176 case RNDIS_MSG_KEEPALIVE: { /* ping */
169 struct rndis_keepalive_c *msg = (void *)buf; 177 struct rndis_keepalive_c *msg = (void *)buf;
diff --git a/drivers/net/usb/usbnet.c b/drivers/net/usb/usbnet.c
index 25e435c49040..af1fe4696509 100644
--- a/drivers/net/usb/usbnet.c
+++ b/drivers/net/usb/usbnet.c
@@ -601,21 +601,25 @@ int usbnet_stop (struct net_device *net)
601 info->description); 601 info->description);
602 } 602 }
603 603
604 // ensure there are no more active urbs 604 if (!(info->flags & FLAG_AVOID_UNLINK_URBS)) {
605 add_wait_queue (&unlink_wakeup, &wait); 605 /* ensure there are no more active urbs */
606 dev->wait = &unlink_wakeup; 606 add_wait_queue(&unlink_wakeup, &wait);
607 temp = unlink_urbs (dev, &dev->txq) + unlink_urbs (dev, &dev->rxq); 607 dev->wait = &unlink_wakeup;
608 608 temp = unlink_urbs(dev, &dev->txq) +
609 // maybe wait for deletions to finish. 609 unlink_urbs(dev, &dev->rxq);
610 while (!skb_queue_empty(&dev->rxq) 610
611 && !skb_queue_empty(&dev->txq) 611 /* maybe wait for deletions to finish. */
612 && !skb_queue_empty(&dev->done)) { 612 while (!skb_queue_empty(&dev->rxq)
613 msleep(UNLINK_TIMEOUT_MS); 613 && !skb_queue_empty(&dev->txq)
614 if (netif_msg_ifdown (dev)) 614 && !skb_queue_empty(&dev->done)) {
615 devdbg (dev, "waited for %d urb completions", temp); 615 msleep(UNLINK_TIMEOUT_MS);
616 if (netif_msg_ifdown(dev))
617 devdbg(dev, "waited for %d urb completions",
618 temp);
619 }
620 dev->wait = NULL;
621 remove_wait_queue(&unlink_wakeup, &wait);
616 } 622 }
617 dev->wait = NULL;
618 remove_wait_queue (&unlink_wakeup, &wait);
619 623
620 usb_kill_urb(dev->interrupt); 624 usb_kill_urb(dev->interrupt);
621 625
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index ca7a8a31d0b9..dda7cc2e1f57 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -5,7 +5,7 @@
5menu "Wireless LAN" 5menu "Wireless LAN"
6 depends on !S390 6 depends on !S390
7 7
8config WLAN_PRE80211 8menuconfig WLAN_PRE80211
9 bool "Wireless LAN (pre-802.11)" 9 bool "Wireless LAN (pre-802.11)"
10 depends on NETDEVICES 10 depends on NETDEVICES
11 ---help--- 11 ---help---
@@ -101,7 +101,7 @@ config PCMCIA_NETWAVE
101 called netwave_cs. If unsure, say N. 101 called netwave_cs. If unsure, say N.
102 102
103 103
104config WLAN_80211 104menuconfig WLAN_80211
105 bool "Wireless LAN (IEEE 802.11)" 105 bool "Wireless LAN (IEEE 802.11)"
106 depends on NETDEVICES 106 depends on NETDEVICES
107 ---help--- 107 ---help---
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c
index 13303fa34734..7218dbabad3e 100644
--- a/drivers/net/wireless/at76c50x-usb.c
+++ b/drivers/net/wireless/at76c50x-usb.c
@@ -1773,6 +1773,9 @@ static void at76_mac80211_stop(struct ieee80211_hw *hw)
1773 1773
1774 at76_dbg(DBG_MAC80211, "%s()", __func__); 1774 at76_dbg(DBG_MAC80211, "%s()", __func__);
1775 1775
1776 cancel_delayed_work(&priv->dwork_hw_scan);
1777 cancel_work_sync(&priv->work_set_promisc);
1778
1776 mutex_lock(&priv->mtx); 1779 mutex_lock(&priv->mtx);
1777 1780
1778 if (!priv->device_unplugged) { 1781 if (!priv->device_unplugged) {
@@ -1872,8 +1875,8 @@ static void at76_dwork_hw_scan(struct work_struct *work)
1872 /* FIXME: add maximum time for scan to complete */ 1875 /* FIXME: add maximum time for scan to complete */
1873 1876
1874 if (ret != CMD_STATUS_COMPLETE) { 1877 if (ret != CMD_STATUS_COMPLETE) {
1875 queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, 1878 ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan,
1876 SCAN_POLL_INTERVAL); 1879 SCAN_POLL_INTERVAL);
1877 mutex_unlock(&priv->mtx); 1880 mutex_unlock(&priv->mtx);
1878 return; 1881 return;
1879 } 1882 }
@@ -1934,8 +1937,8 @@ static int at76_hw_scan(struct ieee80211_hw *hw,
1934 goto exit; 1937 goto exit;
1935 } 1938 }
1936 1939
1937 queue_delayed_work(priv->hw->workqueue, &priv->dwork_hw_scan, 1940 ieee80211_queue_delayed_work(priv->hw, &priv->dwork_hw_scan,
1938 SCAN_POLL_INTERVAL); 1941 SCAN_POLL_INTERVAL);
1939 1942
1940exit: 1943exit:
1941 mutex_unlock(&priv->mtx); 1944 mutex_unlock(&priv->mtx);
@@ -2024,7 +2027,7 @@ static void at76_configure_filter(struct ieee80211_hw *hw,
2024 } else 2027 } else
2025 return; 2028 return;
2026 2029
2027 queue_work(hw->workqueue, &priv->work_set_promisc); 2030 ieee80211_queue_work(hw, &priv->work_set_promisc);
2028} 2031}
2029 2032
2030static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 2033static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
@@ -2295,11 +2298,8 @@ static void at76_delete_device(struct at76_priv *priv)
2295 2298
2296 tasklet_kill(&priv->rx_tasklet); 2299 tasklet_kill(&priv->rx_tasklet);
2297 2300
2298 if (priv->mac80211_registered) { 2301 if (priv->mac80211_registered)
2299 cancel_delayed_work(&priv->dwork_hw_scan);
2300 flush_workqueue(priv->hw->workqueue);
2301 ieee80211_unregister_hw(priv->hw); 2302 ieee80211_unregister_hw(priv->hw);
2302 }
2303 2303
2304 if (priv->tx_urb) { 2304 if (priv->tx_urb) {
2305 usb_kill_urb(priv->tx_urb); 2305 usb_kill_urb(priv->tx_urb);
diff --git a/drivers/net/wireless/ath/Kconfig b/drivers/net/wireless/ath/Kconfig
index eb0337c49546..253b95a264b1 100644
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -1,9 +1,24 @@
1config ATH_COMMON 1menuconfig ATH_COMMON
2 tristate "Atheros Wireless Cards" 2 tristate "Atheros Wireless Cards"
3 depends on WLAN_80211 3 depends on WLAN_80211
4 depends on ATH5K || ATH9K || AR9170_USB 4 depends on CFG80211
5 ---help---
6 This will enable the support for the Atheros wireless drivers.
7 ath5k, ath9k and ar9170 drivers share some common code, this option
8 enables the common ath.ko module which currently shares just common
9 regulatory EEPROM helpers but will likely be extended later to share
10 more between modules.
5 11
12 For more information and documentation on this module you can visit:
13
14 http://wireless.kernel.org/en/users/Drivers/ath
15
16 For information on all Atheros wireless drivers visit:
17
18 http://wireless.kernel.org/en/users/Drivers/Atheros
19
20if ATH_COMMON
6source "drivers/net/wireless/ath/ath5k/Kconfig" 21source "drivers/net/wireless/ath/ath5k/Kconfig"
7source "drivers/net/wireless/ath/ath9k/Kconfig" 22source "drivers/net/wireless/ath/ath9k/Kconfig"
8source "drivers/net/wireless/ath/ar9170/Kconfig" 23source "drivers/net/wireless/ath/ar9170/Kconfig"
9 24endif
diff --git a/drivers/net/wireless/ath/ar9170/Kconfig b/drivers/net/wireless/ath/ar9170/Kconfig
index b99e3263ee6d..05918f1e685a 100644
--- a/drivers/net/wireless/ath/ar9170/Kconfig
+++ b/drivers/net/wireless/ath/ar9170/Kconfig
@@ -1,13 +1,13 @@
1config AR9170_USB 1config AR9170_USB
2 tristate "Atheros AR9170 802.11n USB support" 2 tristate "Atheros AR9170 802.11n USB support"
3 depends on USB && MAC80211 && WLAN_80211 && EXPERIMENTAL 3 depends on USB && MAC80211 && WLAN_80211
4 select FW_LOADER 4 select FW_LOADER
5 select ATH_COMMON
6 help 5 help
7 This is a driver for the Atheros "otus" 802.11n USB devices. 6 This is a driver for the Atheros "otus" 802.11n USB devices.
8 7
9 These devices require additional firmware (2 files). 8 These devices require additional firmware (2 files).
10 For now, these files can be downloaded from here: 9 For now, these files can be downloaded from here:
10
11 http://wireless.kernel.org/en/users/Drivers/ar9170 11 http://wireless.kernel.org/en/users/Drivers/ar9170
12 12
13 If you choose to build a module, it'll be called ar9170usb. 13 If you choose to build a module, it'll be called ar9170usb.
diff --git a/drivers/net/wireless/ath/ar9170/led.c b/drivers/net/wireless/ath/ar9170/led.c
index 63fda6cd2101..86c4e79f6bc8 100644
--- a/drivers/net/wireless/ath/ar9170/led.c
+++ b/drivers/net/wireless/ath/ar9170/led.c
@@ -90,9 +90,12 @@ static void ar9170_update_leds(struct work_struct *work)
90 ar9170_set_leds_state(ar, led_val); 90 ar9170_set_leds_state(ar, led_val);
91 mutex_unlock(&ar->mutex); 91 mutex_unlock(&ar->mutex);
92 92
93 if (rerun) 93 if (!rerun)
94 queue_delayed_work(ar->hw->workqueue, &ar->led_work, 94 return;
95 msecs_to_jiffies(blink_delay)); 95
96 ieee80211_queue_delayed_work(ar->hw,
97 &ar->led_work,
98 msecs_to_jiffies(blink_delay));
96} 99}
97 100
98static void ar9170_led_brightness_set(struct led_classdev *led, 101static void ar9170_led_brightness_set(struct led_classdev *led,
@@ -110,7 +113,7 @@ static void ar9170_led_brightness_set(struct led_classdev *led,
110 } 113 }
111 114
112 if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled)) 115 if (likely(IS_ACCEPTING_CMD(ar) && arl->toggled))
113 queue_delayed_work(ar->hw->workqueue, &ar->led_work, HZ/10); 116 ieee80211_queue_delayed_work(ar->hw, &ar->led_work, HZ/10);
114} 117}
115 118
116static int ar9170_register_led(struct ar9170 *ar, int i, char *name, 119static int ar9170_register_led(struct ar9170 *ar, int i, char *name,
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 85a1452a7c3c..4fc389ae74b4 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -595,10 +595,12 @@ static void ar9170_tx_janitor(struct work_struct *work)
595 595
596 ar9170_tx_fake_ampdu_status(ar); 596 ar9170_tx_fake_ampdu_status(ar);
597 597
598 if (resched) 598 if (!resched)
599 queue_delayed_work(ar->hw->workqueue, 599 return;
600 &ar->tx_janitor, 600
601 msecs_to_jiffies(AR9170_JANITOR_DELAY)); 601 ieee80211_queue_delayed_work(ar->hw,
602 &ar->tx_janitor,
603 msecs_to_jiffies(AR9170_JANITOR_DELAY));
602} 604}
603 605
604void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) 606void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
@@ -648,7 +650,7 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
648 * pre-TBTT event 650 * pre-TBTT event
649 */ 651 */
650 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP) 652 if (ar->vif && ar->vif->type == NL80211_IFTYPE_AP)
651 queue_work(ar->hw->workqueue, &ar->beacon_work); 653 ieee80211_queue_work(ar->hw, &ar->beacon_work);
652 break; 654 break;
653 655
654 case 0xc2: 656 case 0xc2:
@@ -1290,14 +1292,13 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
1290 if (IS_STARTED(ar)) 1292 if (IS_STARTED(ar))
1291 ar->state = AR9170_IDLE; 1293 ar->state = AR9170_IDLE;
1292 1294
1293 flush_workqueue(ar->hw->workqueue);
1294
1295 cancel_delayed_work_sync(&ar->tx_janitor); 1295 cancel_delayed_work_sync(&ar->tx_janitor);
1296#ifdef CONFIG_AR9170_LEDS 1296#ifdef CONFIG_AR9170_LEDS
1297 cancel_delayed_work_sync(&ar->led_work); 1297 cancel_delayed_work_sync(&ar->led_work);
1298#endif 1298#endif
1299 cancel_work_sync(&ar->filter_config_work); 1299 cancel_work_sync(&ar->filter_config_work);
1300 cancel_work_sync(&ar->beacon_work); 1300 cancel_work_sync(&ar->beacon_work);
1301
1301 mutex_lock(&ar->mutex); 1302 mutex_lock(&ar->mutex);
1302 1303
1303 if (IS_ACCEPTING_CMD(ar)) { 1304 if (IS_ACCEPTING_CMD(ar)) {
@@ -1826,10 +1827,12 @@ static void ar9170_tx(struct ar9170 *ar)
1826 } 1827 }
1827 } 1828 }
1828 1829
1829 if (schedule_garbagecollector) 1830 if (!schedule_garbagecollector)
1830 queue_delayed_work(ar->hw->workqueue, 1831 return;
1831 &ar->tx_janitor, 1832
1832 msecs_to_jiffies(AR9170_JANITOR_DELAY)); 1833 ieee80211_queue_delayed_work(ar->hw,
1834 &ar->tx_janitor,
1835 msecs_to_jiffies(AR9170_JANITOR_DELAY));
1833} 1836}
1834 1837
1835static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb) 1838static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
@@ -2158,7 +2161,7 @@ static void ar9170_op_configure_filter(struct ieee80211_hw *hw,
2158 } 2161 }
2159 2162
2160 if (likely(IS_STARTED(ar))) 2163 if (likely(IS_STARTED(ar)))
2161 queue_work(ar->hw->workqueue, &ar->filter_config_work); 2164 ieee80211_queue_work(ar->hw, &ar->filter_config_work);
2162} 2165}
2163 2166
2164static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, 2167static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw,
@@ -2416,7 +2419,7 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw,
2416 } 2419 }
2417 2420
2418 if (IS_STARTED(ar) && ar->filter_changed) 2421 if (IS_STARTED(ar) && ar->filter_changed)
2419 queue_work(ar->hw->workqueue, &ar->filter_config_work); 2422 ieee80211_queue_work(ar->hw, &ar->filter_config_work);
2420} 2423}
2421 2424
2422static int ar9170_get_stats(struct ieee80211_hw *hw, 2425static int ar9170_get_stats(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath5k/Kconfig b/drivers/net/wireless/ath/ath5k/Kconfig
index daf0c83527d8..06d006675d7d 100644
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,7 +1,6 @@
1config ATH5K 1config ATH5K
2 tristate "Atheros 5xxx wireless cards support" 2 tristate "Atheros 5xxx wireless cards support"
3 depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL 3 depends on PCI && MAC80211 && WLAN_80211
4 select ATH_COMMON
5 select MAC80211_LEDS 4 select MAC80211_LEDS
6 select LEDS_CLASS 5 select LEDS_CLASS
7 select NEW_LEDS 6 select NEW_LEDS
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 7db32ce3dbd8..3a1c156d275f 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1117,6 +1117,8 @@ ath5k_mode_setup(struct ath5k_softc *sc)
1117 struct ath5k_hw *ah = sc->ah; 1117 struct ath5k_hw *ah = sc->ah;
1118 u32 rfilt; 1118 u32 rfilt;
1119 1119
1120 ah->ah_op_mode = sc->opmode;
1121
1120 /* configure rx filter */ 1122 /* configure rx filter */
1121 rfilt = sc->filter_flags; 1123 rfilt = sc->filter_flags;
1122 ath5k_hw_set_rx_filter(ah, rfilt); 1124 ath5k_hw_set_rx_filter(ah, rfilt);
@@ -1998,9 +2000,12 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1998static void 2000static void
1999ath5k_tasklet_tx(unsigned long data) 2001ath5k_tasklet_tx(unsigned long data)
2000{ 2002{
2003 int i;
2001 struct ath5k_softc *sc = (void *)data; 2004 struct ath5k_softc *sc = (void *)data;
2002 2005
2003 ath5k_tx_processq(sc, sc->txq); 2006 for (i=0; i < AR5K_NUM_TX_QUEUES; i++)
2007 if (sc->txqs[i].setup && (sc->ah->ah_txq_isr & BIT(i)))
2008 ath5k_tx_processq(sc, &sc->txqs[i]);
2004} 2009}
2005 2010
2006 2011
@@ -2768,6 +2773,7 @@ static int ath5k_add_interface(struct ieee80211_hw *hw,
2768 } 2773 }
2769 2774
2770 ath5k_hw_set_lladdr(sc->ah, conf->mac_addr); 2775 ath5k_hw_set_lladdr(sc->ah, conf->mac_addr);
2776 ath5k_mode_setup(sc);
2771 2777
2772 ret = 0; 2778 ret = 0;
2773end: 2779end:
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 0f4a6d862d3a..2cb72f8c32d7 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -1,7 +1,6 @@
1config ATH9K 1config ATH9K
2 tristate "Atheros 802.11n wireless cards support" 2 tristate "Atheros 802.11n wireless cards support"
3 depends on PCI && MAC80211 && WLAN_80211 3 depends on PCI && MAC80211 && WLAN_80211
4 select ATH_COMMON
5 select MAC80211_LEDS 4 select MAC80211_LEDS
6 select LEDS_CLASS 5 select LEDS_CLASS
7 select NEW_LEDS 6 select NEW_LEDS
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 0e65c51ba176..5618fc25d52f 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -119,7 +119,7 @@ static int ath_ahb_probe(struct platform_device *pdev)
119 sc->bus_ops = &ath_ahb_bus_ops; 119 sc->bus_ops = &ath_ahb_bus_ops;
120 sc->irq = irq; 120 sc->irq = irq;
121 121
122 ret = ath_attach(AR5416_AR9100_DEVID, sc); 122 ret = ath_init_device(AR5416_AR9100_DEVID, sc);
123 if (ret != 0) { 123 if (ret != 0) {
124 dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret); 124 dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
125 ret = -ENODEV; 125 ret = -ENODEV;
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index aad259b4c197..b7093126dbb8 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -777,7 +777,7 @@ void ath9k_hw_ani_setup(struct ath_hw *ah)
777 } 777 }
778} 778}
779 779
780void ath9k_hw_ani_attach(struct ath_hw *ah) 780void ath9k_hw_ani_init(struct ath_hw *ah)
781{ 781{
782 int i; 782 int i;
783 783
@@ -822,9 +822,9 @@ void ath9k_hw_ani_attach(struct ath_hw *ah)
822 ah->proc_phyerr |= HAL_PROCESS_ANI; 822 ah->proc_phyerr |= HAL_PROCESS_ANI;
823} 823}
824 824
825void ath9k_hw_ani_detach(struct ath_hw *ah) 825void ath9k_hw_ani_disable(struct ath_hw *ah)
826{ 826{
827 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detach ANI\n"); 827 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling ANI\n");
828 828
829 if (ah->has_hw_phycounters) { 829 if (ah->has_hw_phycounters) {
830 ath9k_hw_disable_mib_counters(ah); 830 ath9k_hw_disable_mib_counters(ah);
diff --git a/drivers/net/wireless/ath/ath9k/ani.h b/drivers/net/wireless/ath/ath9k/ani.h
index 08b4e7ed5ff0..a36b7bb7c42a 100644
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -132,7 +132,7 @@ u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hw *ah, u32 *rxc_pcnt,
132void ath9k_hw_procmibevent(struct ath_hw *ah, 132void ath9k_hw_procmibevent(struct ath_hw *ah,
133 const struct ath9k_node_stats *stats); 133 const struct ath9k_node_stats *stats);
134void ath9k_hw_ani_setup(struct ath_hw *ah); 134void ath9k_hw_ani_setup(struct ath_hw *ah);
135void ath9k_hw_ani_attach(struct ath_hw *ah); 135void ath9k_hw_ani_init(struct ath_hw *ah);
136void ath9k_hw_ani_detach(struct ath_hw *ah); 136void ath9k_hw_ani_disable(struct ath_hw *ah);
137 137
138#endif /* ANI_H */ 138#endif /* ANI_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index bda0f302340c..7a5a157e15c4 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -642,7 +642,7 @@ extern struct ieee80211_ops ath9k_ops;
642 642
643irqreturn_t ath_isr(int irq, void *dev); 643irqreturn_t ath_isr(int irq, void *dev);
644void ath_cleanup(struct ath_softc *sc); 644void ath_cleanup(struct ath_softc *sc);
645int ath_attach(u16 devid, struct ath_softc *sc); 645int ath_init_device(u16 devid, struct ath_softc *sc);
646void ath_detach(struct ath_softc *sc); 646void ath_detach(struct ath_softc *sc);
647const char *ath_mac_bb_name(u32 mac_bb_version); 647const char *ath_mac_bb_name(u32 mac_bb_version);
648const char *ath_rf_name(u16 rf_version); 648const char *ath_rf_name(u16 rf_version);
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index d1bbb02af8de..26d87527acbd 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -753,6 +753,98 @@ static void ath9k_olc_temp_compensation(struct ath_hw *ah)
753 } 753 }
754} 754}
755 755
756static void ath9k_hw_9271_pa_cal(struct ath_hw *ah)
757{
758 u32 regVal;
759 unsigned int i;
760 u32 regList [][2] = {
761 { 0x786c, 0 },
762 { 0x7854, 0 },
763 { 0x7820, 0 },
764 { 0x7824, 0 },
765 { 0x7868, 0 },
766 { 0x783c, 0 },
767 { 0x7838, 0 } ,
768 { 0x7828, 0 } ,
769 };
770
771 for (i = 0; i < ARRAY_SIZE(regList); i++)
772 regList[i][1] = REG_READ(ah, regList[i][0]);
773
774 regVal = REG_READ(ah, 0x7834);
775 regVal &= (~(0x1));
776 REG_WRITE(ah, 0x7834, regVal);
777 regVal = REG_READ(ah, 0x9808);
778 regVal |= (0x1 << 27);
779 REG_WRITE(ah, 0x9808, regVal);
780
781 /* 786c,b23,1, pwddac=1 */
782 REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1);
783 /* 7854, b5,1, pdrxtxbb=1 */
784 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1);
785 /* 7854, b7,1, pdv2i=1 */
786 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1);
787 /* 7854, b8,1, pddacinterface=1 */
788 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1);
789 /* 7824,b12,0, offcal=0 */
790 REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0);
791 /* 7838, b1,0, pwddb=0 */
792 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0);
793 /* 7820,b11,0, enpacal=0 */
794 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0);
795 /* 7820,b25,1, pdpadrv1=0 */
796 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0);
797 /* 7820,b24,0, pdpadrv2=0 */
798 REG_RMW_FIELD(ah, AR9285_AN_RF2G1,AR9285_AN_RF2G1_PDPADRV2,0);
799 /* 7820,b23,0, pdpaout=0 */
800 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0);
801 /* 783c,b14-16,7, padrvgn2tab_0=7 */
802 REG_RMW_FIELD(ah, AR9285_AN_RF2G8,AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
803 /*
804 * 7838,b29-31,0, padrvgn1tab_0=0
805 * does not matter since we turn it off
806 */
807 REG_RMW_FIELD(ah, AR9285_AN_RF2G7,AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
808
809 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
810
811 /* Set:
812 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
813 * txon=1,paon=1,oscon=1,synthon_force=1
814 */
815 REG_WRITE(ah, AR9285_AN_TOP2, 0xca0358a0);
816 udelay(30);
817 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0);
818
819 /* find off_6_1; */
820 for (i = 6; i >= 0; i--) {
821 regVal = REG_READ(ah, 0x7834);
822 regVal |= (1 << (20 + i));
823 REG_WRITE(ah, 0x7834, regVal);
824 udelay(1);
825 //regVal = REG_READ(ah, 0x7834);
826 regVal &= (~(0x1 << (20 + i)));
827 regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9)
828 << (20 + i));
829 REG_WRITE(ah, 0x7834, regVal);
830 }
831
832 /* Empirical offset correction */
833#if 0
834 REG_RMW_FIELD(ah, AR9285_AN_RF2G6, AR9271_AN_RF2G6_OFFS, 0x20);
835#endif
836
837 regVal = REG_READ(ah, 0x7834);
838 regVal |= 0x1;
839 REG_WRITE(ah, 0x7834, regVal);
840 regVal = REG_READ(ah, 0x9808);
841 regVal &= (~(0x1 << 27));
842 REG_WRITE(ah, 0x9808, regVal);
843
844 for (i = 0; i < ARRAY_SIZE(regList); i++)
845 REG_WRITE(ah, regList[i][0], regList[i][1]);
846}
847
756static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah) 848static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah)
757{ 849{
758 850
@@ -869,14 +961,26 @@ bool ath9k_hw_calibrate(struct ath_hw *ah, struct ath9k_channel *chan,
869 } 961 }
870 } 962 }
871 963
964 /* Do NF cal only at longer intervals */
872 if (longcal) { 965 if (longcal) {
873 if (AR_SREV_9285_11_OR_LATER(ah)) 966 /* Do periodic PAOffset Cal */
967 if (AR_SREV_9271(ah))
968 ath9k_hw_9271_pa_cal(ah);
969 else if (AR_SREV_9285_11_OR_LATER(ah))
874 ath9k_hw_9285_pa_cal(ah); 970 ath9k_hw_9285_pa_cal(ah);
875 971
876 if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER) 972 if (OLC_FOR_AR9280_20_LATER || OLC_FOR_AR9287_10_LATER)
877 ath9k_olc_temp_compensation(ah); 973 ath9k_olc_temp_compensation(ah);
974
975 /* Get the value from the previous NF cal and update history buffer */
878 ath9k_hw_getnf(ah, chan); 976 ath9k_hw_getnf(ah, chan);
977
978 /*
979 * Load the NF from history buffer of the current channel.
980 * NF is slow time-variant, so it is OK to use a historical value.
981 */
879 ath9k_hw_loadnf(ah, ah->curchan); 982 ath9k_hw_loadnf(ah, ah->curchan);
983
880 ath9k_hw_start_nfcal(ah); 984 ath9k_hw_start_nfcal(ah);
881 } 985 }
882 986
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 6fb1a8034b3c..4cb64a0900bb 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -1237,6 +1237,10 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
1237 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); 1237 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
1238} 1238}
1239 1239
1240/*
1241 * Read EEPROM header info and program the device for correct operation
1242 * given the channel value.
1243 */
1240static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, 1244static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1241 struct ath9k_channel *chan) 1245 struct ath9k_channel *chan)
1242{ 1246{
@@ -1313,38 +1317,110 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1313 } 1317 }
1314 } 1318 }
1315 1319
1316 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1320 if (AR_SREV_9271(ah)) {
1317 AR9285_AN_RF2G3_OB_0, AR9285_AN_RF2G3_OB_0_S, ob[0]); 1321 ath9k_hw_analog_shift_rmw(ah,
1318 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1322 AR9285_AN_RF2G3,
1319 AR9285_AN_RF2G3_OB_1, AR9285_AN_RF2G3_OB_1_S, ob[1]); 1323 AR9271_AN_RF2G3_OB_cck,
1320 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1324 AR9271_AN_RF2G3_OB_cck_S,
1321 AR9285_AN_RF2G3_OB_2, AR9285_AN_RF2G3_OB_2_S, ob[2]); 1325 ob[0]);
1322 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1326 ath9k_hw_analog_shift_rmw(ah,
1323 AR9285_AN_RF2G3_OB_3, AR9285_AN_RF2G3_OB_3_S, ob[3]); 1327 AR9285_AN_RF2G3,
1324 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1328 AR9271_AN_RF2G3_OB_psk,
1325 AR9285_AN_RF2G3_OB_4, AR9285_AN_RF2G3_OB_4_S, ob[4]); 1329 AR9271_AN_RF2G3_OB_psk_S,
1326 1330 ob[1]);
1327 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1331 ath9k_hw_analog_shift_rmw(ah,
1328 AR9285_AN_RF2G3_DB1_0, AR9285_AN_RF2G3_DB1_0_S, db1[0]); 1332 AR9285_AN_RF2G3,
1329 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1333 AR9271_AN_RF2G3_OB_qam,
1330 AR9285_AN_RF2G3_DB1_1, AR9285_AN_RF2G3_DB1_1_S, db1[1]); 1334 AR9271_AN_RF2G3_OB_qam_S,
1331 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G3, 1335 ob[2]);
1332 AR9285_AN_RF2G3_DB1_2, AR9285_AN_RF2G3_DB1_2_S, db1[2]); 1336 ath9k_hw_analog_shift_rmw(ah,
1333 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1337 AR9285_AN_RF2G3,
1334 AR9285_AN_RF2G4_DB1_3, AR9285_AN_RF2G4_DB1_3_S, db1[3]); 1338 AR9271_AN_RF2G3_DB_1,
1335 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1339 AR9271_AN_RF2G3_DB_1_S,
1336 AR9285_AN_RF2G4_DB1_4, AR9285_AN_RF2G4_DB1_4_S, db1[4]); 1340 db1[0]);
1337 1341 ath9k_hw_analog_shift_rmw(ah,
1338 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1342 AR9285_AN_RF2G4,
1339 AR9285_AN_RF2G4_DB2_0, AR9285_AN_RF2G4_DB2_0_S, db2[0]); 1343 AR9271_AN_RF2G4_DB_2,
1340 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1344 AR9271_AN_RF2G4_DB_2_S,
1341 AR9285_AN_RF2G4_DB2_1, AR9285_AN_RF2G4_DB2_1_S, db2[1]); 1345 db2[0]);
1342 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1346 } else {
1343 AR9285_AN_RF2G4_DB2_2, AR9285_AN_RF2G4_DB2_2_S, db2[2]); 1347 ath9k_hw_analog_shift_rmw(ah,
1344 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1348 AR9285_AN_RF2G3,
1345 AR9285_AN_RF2G4_DB2_3, AR9285_AN_RF2G4_DB2_3_S, db2[3]); 1349 AR9285_AN_RF2G3_OB_0,
1346 ath9k_hw_analog_shift_rmw(ah, AR9285_AN_RF2G4, 1350 AR9285_AN_RF2G3_OB_0_S,
1347 AR9285_AN_RF2G4_DB2_4, AR9285_AN_RF2G4_DB2_4_S, db2[4]); 1351 ob[0]);
1352 ath9k_hw_analog_shift_rmw(ah,
1353 AR9285_AN_RF2G3,
1354 AR9285_AN_RF2G3_OB_1,
1355 AR9285_AN_RF2G3_OB_1_S,
1356 ob[1]);
1357 ath9k_hw_analog_shift_rmw(ah,
1358 AR9285_AN_RF2G3,
1359 AR9285_AN_RF2G3_OB_2,
1360 AR9285_AN_RF2G3_OB_2_S,
1361 ob[2]);
1362 ath9k_hw_analog_shift_rmw(ah,
1363 AR9285_AN_RF2G3,
1364 AR9285_AN_RF2G3_OB_3,
1365 AR9285_AN_RF2G3_OB_3_S,
1366 ob[3]);
1367 ath9k_hw_analog_shift_rmw(ah,
1368 AR9285_AN_RF2G3,
1369 AR9285_AN_RF2G3_OB_4,
1370 AR9285_AN_RF2G3_OB_4_S,
1371 ob[4]);
1372
1373 ath9k_hw_analog_shift_rmw(ah,
1374 AR9285_AN_RF2G3,
1375 AR9285_AN_RF2G3_DB1_0,
1376 AR9285_AN_RF2G3_DB1_0_S,
1377 db1[0]);
1378 ath9k_hw_analog_shift_rmw(ah,
1379 AR9285_AN_RF2G3,
1380 AR9285_AN_RF2G3_DB1_1,
1381 AR9285_AN_RF2G3_DB1_1_S,
1382 db1[1]);
1383 ath9k_hw_analog_shift_rmw(ah,
1384 AR9285_AN_RF2G3,
1385 AR9285_AN_RF2G3_DB1_2,
1386 AR9285_AN_RF2G3_DB1_2_S,
1387 db1[2]);
1388 ath9k_hw_analog_shift_rmw(ah,
1389 AR9285_AN_RF2G4,
1390 AR9285_AN_RF2G4_DB1_3,
1391 AR9285_AN_RF2G4_DB1_3_S,
1392 db1[3]);
1393 ath9k_hw_analog_shift_rmw(ah,
1394 AR9285_AN_RF2G4,
1395 AR9285_AN_RF2G4_DB1_4,
1396 AR9285_AN_RF2G4_DB1_4_S, db1[4]);
1397
1398 ath9k_hw_analog_shift_rmw(ah,
1399 AR9285_AN_RF2G4,
1400 AR9285_AN_RF2G4_DB2_0,
1401 AR9285_AN_RF2G4_DB2_0_S,
1402 db2[0]);
1403 ath9k_hw_analog_shift_rmw(ah,
1404 AR9285_AN_RF2G4,
1405 AR9285_AN_RF2G4_DB2_1,
1406 AR9285_AN_RF2G4_DB2_1_S,
1407 db2[1]);
1408 ath9k_hw_analog_shift_rmw(ah,
1409 AR9285_AN_RF2G4,
1410 AR9285_AN_RF2G4_DB2_2,
1411 AR9285_AN_RF2G4_DB2_2_S,
1412 db2[2]);
1413 ath9k_hw_analog_shift_rmw(ah,
1414 AR9285_AN_RF2G4,
1415 AR9285_AN_RF2G4_DB2_3,
1416 AR9285_AN_RF2G4_DB2_3_S,
1417 db2[3]);
1418 ath9k_hw_analog_shift_rmw(ah,
1419 AR9285_AN_RF2G4,
1420 AR9285_AN_RF2G4_DB2_4,
1421 AR9285_AN_RF2G4_DB2_4_S,
1422 db2[4]);
1423 }
1348 1424
1349 1425
1350 if (AR_SREV_9285_11(ah)) 1426 if (AR_SREV_9285_11(ah))
@@ -2794,7 +2870,7 @@ static int ath9k_hw_AR9287_get_eeprom_rev(struct ath_hw *ah)
2794 2870
2795static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah) 2871static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
2796{ 2872{
2797 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287; 2873 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
2798 u16 *eep_data; 2874 u16 *eep_data;
2799 int addr, eep_start_loc = AR9287_EEP_START_LOC; 2875 int addr, eep_start_loc = AR9287_EEP_START_LOC;
2800 eep_data = (u16 *)eep; 2876 eep_data = (u16 *)eep;
@@ -2803,7 +2879,7 @@ static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
2803 "Reading from EEPROM, not flash\n"); 2879 "Reading from EEPROM, not flash\n");
2804 } 2880 }
2805 2881
2806 for (addr = 0; addr < sizeof(struct ar9287_eeprom_t) / sizeof(u16); 2882 for (addr = 0; addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
2807 addr++) { 2883 addr++) {
2808 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) { 2884 if (!ath9k_hw_nvram_read(ah, addr + eep_start_loc, eep_data)) {
2809 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, 2885 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
@@ -2816,12 +2892,11 @@ static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah)
2816} 2892}
2817static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) 2893static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
2818{ 2894{
2819#define SIZE_EEPROM_87 (sizeof(struct ar9287_eeprom_t) / sizeof(u16))
2820 u32 sum = 0, el, integer; 2895 u32 sum = 0, el, integer;
2821 u16 temp, word, magic, magic2, *eepdata; 2896 u16 temp, word, magic, magic2, *eepdata;
2822 int i, addr; 2897 int i, addr;
2823 bool need_swap = false; 2898 bool need_swap = false;
2824 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287; 2899 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
2825 2900
2826 if (!ath9k_hw_use_flash(ah)) { 2901 if (!ath9k_hw_use_flash(ah)) {
2827 if (!ath9k_hw_nvram_read 2902 if (!ath9k_hw_nvram_read
@@ -2842,7 +2917,9 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
2842 need_swap = true; 2917 need_swap = true;
2843 eepdata = (u16 *)(&ah->eeprom); 2918 eepdata = (u16 *)(&ah->eeprom);
2844 2919
2845 for (addr = 0; addr < SIZE_EEPROM_87; addr++) { 2920 for (addr = 0;
2921 addr < sizeof(struct ar9287_eeprom) / sizeof(u16);
2922 addr++) {
2846 temp = swab16(*eepdata); 2923 temp = swab16(*eepdata);
2847 *eepdata = temp; 2924 *eepdata = temp;
2848 eepdata++; 2925 eepdata++;
@@ -2862,8 +2939,13 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
2862 else 2939 else
2863 el = ah->eeprom.map9287.baseEepHeader.length; 2940 el = ah->eeprom.map9287.baseEepHeader.length;
2864 2941
2942 if (el > sizeof(struct ar9287_eeprom))
2943 el = sizeof(struct ar9287_eeprom) / sizeof(u16);
2944 else
2945 el = el / sizeof(u16);
2946
2865 eepdata = (u16 *)(&ah->eeprom); 2947 eepdata = (u16 *)(&ah->eeprom);
2866 for (i = 0; i < min(el, SIZE_EEPROM_87); i++) 2948 for (i = 0; i < el; i++)
2867 sum ^= *eepdata++; 2949 sum ^= *eepdata++;
2868 2950
2869 if (need_swap) { 2951 if (need_swap) {
@@ -2914,13 +2996,12 @@ static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah)
2914 } 2996 }
2915 2997
2916 return 0; 2998 return 0;
2917#undef SIZE_EEPROM_87
2918} 2999}
2919 3000
2920static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, 3001static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah,
2921 enum eeprom_param param) 3002 enum eeprom_param param)
2922{ 3003{
2923 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287; 3004 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
2924 struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 3005 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
2925 struct base_eep_ar9287_header *pBase = &eep->baseEepHeader; 3006 struct base_eep_ar9287_header *pBase = &eep->baseEepHeader;
2926 u16 ver_minor; 3007 u16 ver_minor;
@@ -3210,7 +3291,7 @@ static void ath9k_hw_set_AR9287_power_cal_table(struct ath_hw *ah,
3210 u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0}; 3291 u16 xpdGainValues[AR9287_NUM_PD_GAINS] = {0, 0, 0, 0};
3211 u32 reg32, regOffset, regChainOffset; 3292 u32 reg32, regOffset, regChainOffset;
3212 int16_t modalIdx, diff = 0; 3293 int16_t modalIdx, diff = 0;
3213 struct ar9287_eeprom_t *pEepData = &ah->eeprom.map9287; 3294 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
3214 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0; 3295 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3215 xpdMask = pEepData->modalHeader.xpdGain; 3296 xpdMask = pEepData->modalHeader.xpdGain;
3216 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >= 3297 if ((pEepData->baseEepHeader.version & AR9287_EEP_VER_MINOR_MASK) >=
@@ -3380,7 +3461,7 @@ static void ath9k_hw_set_AR9287_power_per_rate_table(struct ath_hw *ah,
3380 struct chan_centers centers; 3461 struct chan_centers centers;
3381 int tx_chainmask; 3462 int tx_chainmask;
3382 u16 twiceMinEdgePower; 3463 u16 twiceMinEdgePower;
3383 struct ar9287_eeprom_t *pEepData = &ah->eeprom.map9287; 3464 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
3384 tx_chainmask = ah->txchainmask; 3465 tx_chainmask = ah->txchainmask;
3385 3466
3386 ath9k_hw_get_channel_centers(ah, chan, &centers); 3467 ath9k_hw_get_channel_centers(ah, chan, &centers);
@@ -3613,7 +3694,7 @@ static void ath9k_hw_AR9287_set_txpower(struct ath_hw *ah,
3613{ 3694{
3614#define INCREASE_MAXPOW_BY_TWO_CHAIN 6 3695#define INCREASE_MAXPOW_BY_TWO_CHAIN 6
3615#define INCREASE_MAXPOW_BY_THREE_CHAIN 10 3696#define INCREASE_MAXPOW_BY_THREE_CHAIN 10
3616 struct ar9287_eeprom_t *pEepData = &ah->eeprom.map9287; 3697 struct ar9287_eeprom *pEepData = &ah->eeprom.map9287;
3617 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader; 3698 struct modal_eep_ar9287_header *pModal = &pEepData->modalHeader;
3618 int16_t ratesArray[Ar5416RateSize]; 3699 int16_t ratesArray[Ar5416RateSize];
3619 int16_t txPowerIndexOffset = 0; 3700 int16_t txPowerIndexOffset = 0;
@@ -3776,7 +3857,7 @@ static void ath9k_hw_AR9287_set_addac(struct ath_hw *ah,
3776static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, 3857static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah,
3777 struct ath9k_channel *chan) 3858 struct ath9k_channel *chan)
3778{ 3859{
3779 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287; 3860 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
3780 struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 3861 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
3781 3862
3782 u16 antWrites[AR9287_ANT_16S]; 3863 u16 antWrites[AR9287_ANT_16S];
@@ -3928,7 +4009,7 @@ static u8 ath9k_hw_AR9287_get_num_ant_config(struct ath_hw *ah,
3928static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah, 4009static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah,
3929 struct ath9k_channel *chan) 4010 struct ath9k_channel *chan)
3930{ 4011{
3931 struct ar9287_eeprom_t *eep = &ah->eeprom.map9287; 4012 struct ar9287_eeprom *eep = &ah->eeprom.map9287;
3932 struct modal_eep_ar9287_header *pModal = &eep->modalHeader; 4013 struct modal_eep_ar9287_header *pModal = &eep->modalHeader;
3933 return pModal->antCtrlCommon & 0xFFFF; 4014 return pModal->antCtrlCommon & 0xFFFF;
3934} 4015}
@@ -3978,13 +4059,13 @@ static struct eeprom_ops eep_AR9287_ops = {
3978}; 4059};
3979 4060
3980 4061
3981int ath9k_hw_eeprom_attach(struct ath_hw *ah) 4062int ath9k_hw_eeprom_init(struct ath_hw *ah)
3982{ 4063{
3983 int status; 4064 int status;
3984 if (AR_SREV_9287(ah)) { 4065 if (AR_SREV_9287(ah)) {
3985 ah->eep_map = EEP_MAP_AR9287; 4066 ah->eep_map = EEP_MAP_AR9287;
3986 ah->eep_ops = &eep_AR9287_ops; 4067 ah->eep_ops = &eep_AR9287_ops;
3987 } else if (AR_SREV_9285(ah)) { 4068 } else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
3988 ah->eep_map = EEP_MAP_4KBITS; 4069 ah->eep_map = EEP_MAP_4KBITS;
3989 ah->eep_ops = &eep_4k_ops; 4070 ah->eep_ops = &eep_4k_ops;
3990 } else { 4071 } else {
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.h b/drivers/net/wireless/ath/ath9k/eeprom.h
index 7ddd016a99ff..db77e90ed9ab 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.h
+++ b/drivers/net/wireless/ath/ath9k/eeprom.h
@@ -600,7 +600,7 @@ struct ar5416_eeprom_4k {
600 u8 padding; 600 u8 padding;
601} __packed; 601} __packed;
602 602
603struct ar9287_eeprom_t { 603struct ar9287_eeprom {
604 struct base_eep_ar9287_header baseEepHeader; 604 struct base_eep_ar9287_header baseEepHeader;
605 u8 custData[AR9287_DATA_SZ]; 605 u8 custData[AR9287_DATA_SZ];
606 struct modal_eep_ar9287_header modalHeader; 606 struct modal_eep_ar9287_header modalHeader;
@@ -665,6 +665,6 @@ struct eeprom_ops {
665 (((_txchainmask >> 2) & 1) + \ 665 (((_txchainmask >> 2) & 1) + \
666 ((_txchainmask >> 1) & 1) + (_txchainmask & 1)) 666 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
667 667
668int ath9k_hw_eeprom_attach(struct ath_hw *ah); 668int ath9k_hw_eeprom_init(struct ath_hw *ah);
669 669
670#endif /* EEPROM_H */ 670#endif /* EEPROM_H */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 431854ccb65b..71a3bcc450a2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -388,7 +388,7 @@ static const char *ath9k_hw_devname(u16 devid)
388 return NULL; 388 return NULL;
389} 389}
390 390
391static void ath9k_hw_set_defaults(struct ath_hw *ah) 391static void ath9k_hw_init_config(struct ath_hw *ah)
392{ 392{
393 int i; 393 int i;
394 394
@@ -437,27 +437,14 @@ static void ath9k_hw_set_defaults(struct ath_hw *ah)
437 ah->config.serialize_regmode = SER_REG_MODE_AUTO; 437 ah->config.serialize_regmode = SER_REG_MODE_AUTO;
438} 438}
439 439
440static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc, 440static void ath9k_hw_init_defaults(struct ath_hw *ah)
441 int *status)
442{ 441{
443 struct ath_hw *ah;
444
445 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
446 if (ah == NULL) {
447 DPRINTF(sc, ATH_DBG_FATAL,
448 "Cannot allocate memory for state block\n");
449 *status = -ENOMEM;
450 return NULL;
451 }
452
453 ah->ah_sc = sc;
454 ah->hw_version.magic = AR5416_MAGIC; 442 ah->hw_version.magic = AR5416_MAGIC;
455 ah->regulatory.country_code = CTRY_DEFAULT; 443 ah->regulatory.country_code = CTRY_DEFAULT;
456 ah->hw_version.devid = devid;
457 ah->hw_version.subvendorid = 0; 444 ah->hw_version.subvendorid = 0;
458 445
459 ah->ah_flags = 0; 446 ah->ah_flags = 0;
460 if ((devid == AR5416_AR9100_DEVID)) 447 if (ah->hw_version.devid == AR5416_AR9100_DEVID)
461 ah->hw_version.macVersion = AR_SREV_VERSION_9100; 448 ah->hw_version.macVersion = AR_SREV_VERSION_9100;
462 if (!AR_SREV_9100(ah)) 449 if (!AR_SREV_9100(ah))
463 ah->ah_flags = AH_USE_EEPROM; 450 ah->ah_flags = AH_USE_EEPROM;
@@ -479,8 +466,6 @@ static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc,
479 ah->gbeacon_rate = 0; 466 ah->gbeacon_rate = 0;
480 467
481 ah->power_mode = ATH9K_PM_UNDEFINED; 468 ah->power_mode = ATH9K_PM_UNDEFINED;
482
483 return ah;
484} 469}
485 470
486static int ath9k_hw_rfattach(struct ath_hw *ah) 471static int ath9k_hw_rfattach(struct ath_hw *ah)
@@ -593,7 +578,7 @@ static void ath9k_hw_init_txgain_ini(struct ath_hw *ah)
593 } 578 }
594} 579}
595 580
596static int ath9k_hw_post_attach(struct ath_hw *ah) 581static int ath9k_hw_post_init(struct ath_hw *ah)
597{ 582{
598 int ecode; 583 int ecode;
599 584
@@ -604,7 +589,7 @@ static int ath9k_hw_post_attach(struct ath_hw *ah)
604 if (ecode != 0) 589 if (ecode != 0)
605 return ecode; 590 return ecode;
606 591
607 ecode = ath9k_hw_eeprom_attach(ah); 592 ecode = ath9k_hw_eeprom_init(ah);
608 if (ecode != 0) 593 if (ecode != 0)
609 return ecode; 594 return ecode;
610 595
@@ -617,71 +602,52 @@ static int ath9k_hw_post_attach(struct ath_hw *ah)
617 602
618 if (!AR_SREV_9100(ah)) { 603 if (!AR_SREV_9100(ah)) {
619 ath9k_hw_ani_setup(ah); 604 ath9k_hw_ani_setup(ah);
620 ath9k_hw_ani_attach(ah); 605 ath9k_hw_ani_init(ah);
621 } 606 }
622 607
623 return 0; 608 return 0;
624} 609}
625 610
626static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, 611static bool ath9k_hw_devid_supported(u16 devid)
627 int *status)
628{ 612{
629 struct ath_hw *ah; 613 switch (devid) {
630 int ecode; 614 case AR5416_DEVID_PCI:
631 u32 i, j; 615 case AR5416_DEVID_PCIE:
632 616 case AR5416_AR9100_DEVID:
633 ah = ath9k_hw_newstate(devid, sc, status); 617 case AR9160_DEVID_PCI:
634 if (ah == NULL) 618 case AR9280_DEVID_PCI:
635 return NULL; 619 case AR9280_DEVID_PCIE:
636 620 case AR9285_DEVID_PCIE:
637 ath9k_hw_set_defaults(ah); 621 case AR5416_DEVID_AR9287_PCI:
638 622 case AR5416_DEVID_AR9287_PCIE:
639 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) { 623 return true;
640 DPRINTF(sc, ATH_DBG_FATAL, "Couldn't reset chip\n"); 624 default:
641 ecode = -EIO; 625 break;
642 goto bad;
643 }
644
645 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
646 DPRINTF(sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
647 ecode = -EIO;
648 goto bad;
649 }
650
651 if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
652 if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
653 (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
654 ah->config.serialize_regmode =
655 SER_REG_MODE_ON;
656 } else {
657 ah->config.serialize_regmode =
658 SER_REG_MODE_OFF;
659 }
660 }
661
662 DPRINTF(sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
663 ah->config.serialize_regmode);
664
665 if ((ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCI) &&
666 (ah->hw_version.macVersion != AR_SREV_VERSION_5416_PCIE) &&
667 (ah->hw_version.macVersion != AR_SREV_VERSION_9160) &&
668 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah)) &&
669 (!AR_SREV_9285(ah)) && (!AR_SREV_9287(ah))) {
670 DPRINTF(sc, ATH_DBG_FATAL,
671 "Mac Chip Rev 0x%02x.%x is not supported by "
672 "this driver\n", ah->hw_version.macVersion,
673 ah->hw_version.macRev);
674 ecode = -EOPNOTSUPP;
675 goto bad;
676 } 626 }
627 return false;
628}
677 629
678 if (AR_SREV_9100(ah)) { 630static bool ath9k_hw_macversion_supported(u32 macversion)
679 ah->iq_caldata.calData = &iq_cal_multi_sample; 631{
680 ah->supp_cals = IQ_MISMATCH_CAL; 632 switch (macversion) {
681 ah->is_pciexpress = false; 633 case AR_SREV_VERSION_5416_PCI:
634 case AR_SREV_VERSION_5416_PCIE:
635 case AR_SREV_VERSION_9160:
636 case AR_SREV_VERSION_9100:
637 case AR_SREV_VERSION_9280:
638 case AR_SREV_VERSION_9285:
639 case AR_SREV_VERSION_9287:
640 return true;
641 /* Not yet */
642 case AR_SREV_VERSION_9271:
643 default:
644 break;
682 } 645 }
683 ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID); 646 return false;
647}
684 648
649static void ath9k_hw_init_cal_settings(struct ath_hw *ah)
650{
685 if (AR_SREV_9160_10_OR_LATER(ah)) { 651 if (AR_SREV_9160_10_OR_LATER(ah)) {
686 if (AR_SREV_9280_10_OR_LATER(ah)) { 652 if (AR_SREV_9280_10_OR_LATER(ah)) {
687 ah->iq_caldata.calData = &iq_cal_single_sample; 653 ah->iq_caldata.calData = &iq_cal_single_sample;
@@ -702,10 +668,18 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
702 } 668 }
703 ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL; 669 ah->supp_cals = ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
704 } 670 }
671}
672
673static void ath9k_hw_init_mode_regs(struct ath_hw *ah)
674{
675 if (AR_SREV_9271(ah)) {
676 INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271_1_0,
677 ARRAY_SIZE(ar9271Modes_9271_1_0), 6);
678 INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271_1_0,
679 ARRAY_SIZE(ar9271Common_9271_1_0), 2);
680 return;
681 }
705 682
706 ah->ani_function = ATH9K_ANI_ALL;
707 if (AR_SREV_9280_10_OR_LATER(ah))
708 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
709 if (AR_SREV_9287_11_OR_LATER(ah)) { 683 if (AR_SREV_9287_11_OR_LATER(ah)) {
710 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1, 684 INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
711 ARRAY_SIZE(ar9287Modes_9287_1_1), 6); 685 ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
@@ -867,16 +841,10 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
867 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac, 841 INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
868 ARRAY_SIZE(ar5416Addac), 2); 842 ARRAY_SIZE(ar5416Addac), 2);
869 } 843 }
844}
870 845
871 if (ah->is_pciexpress) 846static void ath9k_hw_init_mode_gain_regs(struct ath_hw *ah)
872 ath9k_hw_configpcipowersave(ah, 0); 847{
873 else
874 ath9k_hw_disablepcie(ah);
875
876 ecode = ath9k_hw_post_attach(ah);
877 if (ecode != 0)
878 goto bad;
879
880 if (AR_SREV_9287_11(ah)) 848 if (AR_SREV_9287_11(ah))
881 INIT_INI_ARRAY(&ah->iniModesRxGain, 849 INIT_INI_ARRAY(&ah->iniModesRxGain,
882 ar9287Modes_rx_gain_9287_1_1, 850 ar9287Modes_rx_gain_9287_1_1,
@@ -913,8 +881,11 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
913 } 881 }
914 882
915 } 883 }
884}
916 885
917 ath9k_hw_fill_cap_info(ah); 886static void ath9k_hw_init_11a_eeprom_fix(struct ath_hw *ah)
887{
888 u32 i, j;
918 889
919 if ((ah->hw_version.devid == AR9280_DEVID_PCI) && 890 if ((ah->hw_version.devid == AR9280_DEVID_PCI) &&
920 test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) { 891 test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes)) {
@@ -933,29 +904,97 @@ static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc,
933 } 904 }
934 } 905 }
935 } 906 }
907}
908
909int ath9k_hw_init(struct ath_hw *ah)
910{
911 int r = 0;
912
913 if (!ath9k_hw_devid_supported(ah->hw_version.devid))
914 return -EOPNOTSUPP;
915
916 ath9k_hw_init_defaults(ah);
917 ath9k_hw_init_config(ah);
918
919 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
920 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Couldn't reset chip\n");
921 return -EIO;
922 }
923
924 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
925 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Couldn't wakeup chip\n");
926 return -EIO;
927 }
928
929 if (ah->config.serialize_regmode == SER_REG_MODE_AUTO) {
930 if (ah->hw_version.macVersion == AR_SREV_VERSION_5416_PCI ||
931 (AR_SREV_9280(ah) && !ah->is_pciexpress)) {
932 ah->config.serialize_regmode =
933 SER_REG_MODE_ON;
934 } else {
935 ah->config.serialize_regmode =
936 SER_REG_MODE_OFF;
937 }
938 }
939
940 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "serialize_regmode is %d\n",
941 ah->config.serialize_regmode);
942
943 if (!ath9k_hw_macversion_supported(ah->hw_version.macVersion)) {
944 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
945 "Mac Chip Rev 0x%02x.%x is not supported by "
946 "this driver\n", ah->hw_version.macVersion,
947 ah->hw_version.macRev);
948 return -EOPNOTSUPP;
949 }
950
951 if (AR_SREV_9100(ah)) {
952 ah->iq_caldata.calData = &iq_cal_multi_sample;
953 ah->supp_cals = IQ_MISMATCH_CAL;
954 ah->is_pciexpress = false;
955 }
956
957 if (AR_SREV_9271(ah))
958 ah->is_pciexpress = false;
959
960 ah->hw_version.phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
961
962 ath9k_hw_init_cal_settings(ah);
963
964 ah->ani_function = ATH9K_ANI_ALL;
965 if (AR_SREV_9280_10_OR_LATER(ah))
966 ah->ani_function &= ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
936 967
937 ecode = ath9k_hw_init_macaddr(ah); 968 ath9k_hw_init_mode_regs(ah);
938 if (ecode != 0) { 969
939 DPRINTF(sc, ATH_DBG_FATAL, 970 if (ah->is_pciexpress)
971 ath9k_hw_configpcipowersave(ah, 0);
972 else
973 ath9k_hw_disablepcie(ah);
974
975 r = ath9k_hw_post_init(ah);
976 if (r)
977 return r;
978
979 ath9k_hw_init_mode_gain_regs(ah);
980 ath9k_hw_fill_cap_info(ah);
981 ath9k_hw_init_11a_eeprom_fix(ah);
982
983 r = ath9k_hw_init_macaddr(ah);
984 if (r) {
985 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
940 "Failed to initialize MAC address\n"); 986 "Failed to initialize MAC address\n");
941 goto bad; 987 return r;
942 } 988 }
943 989
944 if (AR_SREV_9285(ah)) 990 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
945 ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S); 991 ah->tx_trig_level = (AR_FTRIG_256B >> AR_FTRIG_S);
946 else 992 else
947 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S); 993 ah->tx_trig_level = (AR_FTRIG_512B >> AR_FTRIG_S);
948 994
949 ath9k_init_nfcal_hist_buffer(ah); 995 ath9k_init_nfcal_hist_buffer(ah);
950 996
951 return ah; 997 return 0;
952bad:
953 if (ah)
954 ath9k_hw_detach(ah);
955 if (status)
956 *status = ecode;
957
958 return NULL;
959} 998}
960 999
961static void ath9k_hw_init_bb(struct ath_hw *ah, 1000static void ath9k_hw_init_bb(struct ath_hw *ah,
@@ -1194,35 +1233,12 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid)
1194void ath9k_hw_detach(struct ath_hw *ah) 1233void ath9k_hw_detach(struct ath_hw *ah)
1195{ 1234{
1196 if (!AR_SREV_9100(ah)) 1235 if (!AR_SREV_9100(ah))
1197 ath9k_hw_ani_detach(ah); 1236 ath9k_hw_ani_disable(ah);
1198 1237
1199 ath9k_hw_rfdetach(ah); 1238 ath9k_hw_rf_free(ah);
1200 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP); 1239 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
1201 kfree(ah); 1240 kfree(ah);
1202} 1241 ah = NULL;
1203
1204struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
1205{
1206 struct ath_hw *ah = NULL;
1207
1208 switch (devid) {
1209 case AR5416_DEVID_PCI:
1210 case AR5416_DEVID_PCIE:
1211 case AR5416_AR9100_DEVID:
1212 case AR9160_DEVID_PCI:
1213 case AR9280_DEVID_PCI:
1214 case AR9280_DEVID_PCIE:
1215 case AR9285_DEVID_PCIE:
1216 case AR5416_DEVID_AR9287_PCI:
1217 case AR5416_DEVID_AR9287_PCIE:
1218 ah = ath9k_hw_do_attach(devid, sc, error);
1219 break;
1220 default:
1221 *error = -ENXIO;
1222 break;
1223 }
1224
1225 return ah;
1226} 1242}
1227 1243
1228/*******/ 1244/*******/
@@ -1232,6 +1248,27 @@ struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error)
1232static void ath9k_hw_override_ini(struct ath_hw *ah, 1248static void ath9k_hw_override_ini(struct ath_hw *ah,
1233 struct ath9k_channel *chan) 1249 struct ath9k_channel *chan)
1234{ 1250{
1251 u32 val;
1252
1253 if (AR_SREV_9271(ah)) {
1254 /*
1255 * Enable spectral scan to solution for issues with stuck
1256 * beacons on AR9271 1.0. The beacon stuck issue is not seeon on
1257 * AR9271 1.1
1258 */
1259 if (AR_SREV_9271_10(ah)) {
1260 val = REG_READ(ah, AR_PHY_SPECTRAL_SCAN) | AR_PHY_SPECTRAL_SCAN_ENABLE;
1261 REG_WRITE(ah, AR_PHY_SPECTRAL_SCAN, val);
1262 }
1263 else if (AR_SREV_9271_11(ah))
1264 /*
1265 * change AR_PHY_RF_CTL3 setting to fix MAC issue
1266 * present on AR9271 1.1
1267 */
1268 REG_WRITE(ah, AR_PHY_RF_CTL3, 0x3a020001);
1269 return;
1270 }
1271
1235 /* 1272 /*
1236 * Set the RX_ABORT and RX_DIS and clear if off only after 1273 * Set the RX_ABORT and RX_DIS and clear if off only after
1237 * RXE is set for MAC. This prevents frames with corrupted 1274 * RXE is set for MAC. This prevents frames with corrupted
@@ -1243,7 +1280,10 @@ static void ath9k_hw_override_ini(struct ath_hw *ah,
1243 if (!AR_SREV_5416_20_OR_LATER(ah) || 1280 if (!AR_SREV_5416_20_OR_LATER(ah) ||
1244 AR_SREV_9280_10_OR_LATER(ah)) 1281 AR_SREV_9280_10_OR_LATER(ah))
1245 return; 1282 return;
1246 1283 /*
1284 * Disable BB clock gating
1285 * Necessary to avoid issues on AR5416 2.0
1286 */
1247 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11); 1287 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
1248} 1288}
1249 1289
@@ -1475,23 +1515,48 @@ static inline void ath9k_hw_set_dma(struct ath_hw *ah)
1475{ 1515{
1476 u32 regval; 1516 u32 regval;
1477 1517
1518 /*
1519 * set AHB_MODE not to do cacheline prefetches
1520 */
1478 regval = REG_READ(ah, AR_AHB_MODE); 1521 regval = REG_READ(ah, AR_AHB_MODE);
1479 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN); 1522 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
1480 1523
1524 /*
1525 * let mac dma reads be in 128 byte chunks
1526 */
1481 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK; 1527 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
1482 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B); 1528 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
1483 1529
1530 /*
1531 * Restore TX Trigger Level to its pre-reset value.
1532 * The initial value depends on whether aggregation is enabled, and is
1533 * adjusted whenever underruns are detected.
1534 */
1484 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level); 1535 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->tx_trig_level);
1485 1536
1537 /*
1538 * let mac dma writes be in 128 byte chunks
1539 */
1486 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK; 1540 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
1487 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B); 1541 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
1488 1542
1543 /*
1544 * Setup receive FIFO threshold to hold off TX activities
1545 */
1489 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200); 1546 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
1490 1547
1548 /*
1549 * reduce the number of usable entries in PCU TXBUF to avoid
1550 * wrap around issues.
1551 */
1491 if (AR_SREV_9285(ah)) { 1552 if (AR_SREV_9285(ah)) {
1553 /* For AR9285 the number of Fifos are reduced to half.
1554 * So set the usable tx buf size also to half to
1555 * avoid data/delimiter underruns
1556 */
1492 REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 1557 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
1493 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE); 1558 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
1494 } else { 1559 } else if (!AR_SREV_9271(ah)) {
1495 REG_WRITE(ah, AR_PCU_TXBUF_CTRL, 1560 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
1496 AR_PCU_TXBUF_CTRL_USABLE_SIZE); 1561 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
1497 } 1562 }
@@ -2297,11 +2362,26 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2297 2362
2298 ath9k_hw_mark_phy_inactive(ah); 2363 ath9k_hw_mark_phy_inactive(ah);
2299 2364
2365 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
2366 REG_WRITE(ah,
2367 AR9271_RESET_POWER_DOWN_CONTROL,
2368 AR9271_RADIO_RF_RST);
2369 udelay(50);
2370 }
2371
2300 if (!ath9k_hw_chip_reset(ah, chan)) { 2372 if (!ath9k_hw_chip_reset(ah, chan)) {
2301 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n"); 2373 DPRINTF(ah->ah_sc, ATH_DBG_FATAL, "Chip reset failed\n");
2302 return -EINVAL; 2374 return -EINVAL;
2303 } 2375 }
2304 2376
2377 if (AR_SREV_9271(ah) && ah->htc_reset_init) {
2378 ah->htc_reset_init = false;
2379 REG_WRITE(ah,
2380 AR9271_RESET_POWER_DOWN_CONTROL,
2381 AR9271_GATE_MAC_CTL);
2382 udelay(50);
2383 }
2384
2305 if (AR_SREV_9280_10_OR_LATER(ah)) 2385 if (AR_SREV_9280_10_OR_LATER(ah))
2306 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE); 2386 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
2307 2387
@@ -2437,6 +2517,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2437 2517
2438 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ); 2518 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
2439 2519
2520 /*
2521 * For big endian systems turn on swapping for descriptors
2522 */
2440 if (AR_SREV_9100(ah)) { 2523 if (AR_SREV_9100(ah)) {
2441 u32 mask; 2524 u32 mask;
2442 mask = REG_READ(ah, AR_CFG); 2525 mask = REG_READ(ah, AR_CFG);
@@ -2451,8 +2534,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2451 "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG)); 2534 "Setting CFG 0x%x\n", REG_READ(ah, AR_CFG));
2452 } 2535 }
2453 } else { 2536 } else {
2537 /* Configure AR9271 target WLAN */
2538 if (AR_SREV_9271(ah))
2539 REG_WRITE(ah, AR_CFG, AR_CFG_SWRB | AR_CFG_SWTB);
2454#ifdef __BIG_ENDIAN 2540#ifdef __BIG_ENDIAN
2455 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD); 2541 else
2542 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
2456#endif 2543#endif
2457 } 2544 }
2458 2545
@@ -2494,9 +2581,6 @@ bool ath9k_hw_keyreset(struct ath_hw *ah, u16 entry)
2494 2581
2495 } 2582 }
2496 2583
2497 if (ah->curchan == NULL)
2498 return true;
2499
2500 return true; 2584 return true;
2501} 2585}
2502 2586
@@ -2921,7 +3005,7 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
2921 /* 3005 /*
2922 * AR9280 2.0 or later chips use SerDes values from the 3006 * AR9280 2.0 or later chips use SerDes values from the
2923 * initvals.h initialized depending on chipset during 3007 * initvals.h initialized depending on chipset during
2924 * ath9k_hw_do_attach() 3008 * ath9k_hw_init()
2925 */ 3009 */
2926 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) { 3010 for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
2927 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0), 3011 REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
@@ -2982,7 +3066,7 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore)
2982 if (ah->config.pcie_waen) { 3066 if (ah->config.pcie_waen) {
2983 REG_WRITE(ah, AR_WA, ah->config.pcie_waen); 3067 REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
2984 } else { 3068 } else {
2985 if (AR_SREV_9285(ah)) 3069 if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
2986 REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT); 3070 REG_WRITE(ah, AR_WA, AR9285_WA_DEFAULT);
2987 /* 3071 /*
2988 * On AR9280 chips bit 22 of 0x4004 needs to be set to 3072 * On AR9280 chips bit 22 of 0x4004 needs to be set to
@@ -3152,11 +3236,6 @@ bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
3152 return true; 3236 return true;
3153} 3237}
3154 3238
3155enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah)
3156{
3157 return ah->mask_reg;
3158}
3159
3160enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) 3239enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
3161{ 3240{
3162 u32 omask = ah->mask_reg; 3241 u32 omask = ah->mask_reg;
@@ -3451,10 +3530,17 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3451 } 3530 }
3452 3531
3453 pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK); 3532 pCap->tx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_TX_MASK);
3533 /*
3534 * For AR9271 we will temporarilly uses the rx chainmax as read from
3535 * the EEPROM.
3536 */
3454 if ((ah->hw_version.devid == AR5416_DEVID_PCI) && 3537 if ((ah->hw_version.devid == AR5416_DEVID_PCI) &&
3455 !(eeval & AR5416_OPFLAGS_11A)) 3538 !(eeval & AR5416_OPFLAGS_11A) &&
3539 !(AR_SREV_9271(ah)))
3540 /* CB71: GPIO 0 is pulled down to indicate 3 rx chains */
3456 pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7; 3541 pCap->rx_chainmask = ath9k_hw_gpio_get(ah, 0) ? 0x5 : 0x7;
3457 else 3542 else
3543 /* Use rx_chainmask from EEPROM. */
3458 pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK); 3544 pCap->rx_chainmask = ah->eep_ops->get_eeprom(ah, EEP_RX_MASK);
3459 3545
3460 if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0))) 3546 if (!(AR_SREV_9280(ah) && (ah->hw_version.macRev == 0)))
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 2e196df10894..d4aaf4f8db29 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -403,7 +403,7 @@ struct ath_hw {
403 union { 403 union {
404 struct ar5416_eeprom_def def; 404 struct ar5416_eeprom_def def;
405 struct ar5416_eeprom_4k map4k; 405 struct ar5416_eeprom_4k map4k;
406 struct ar9287_eeprom_t map9287; 406 struct ar9287_eeprom map9287;
407 } eeprom; 407 } eeprom;
408 const struct eeprom_ops *eep_ops; 408 const struct eeprom_ops *eep_ops;
409 enum ath9k_eep_map eep_map; 409 enum ath9k_eep_map eep_map;
@@ -419,6 +419,8 @@ struct ath_hw {
419 u32 wlanactive_gpio; 419 u32 wlanactive_gpio;
420 u32 ah_flags; 420 u32 ah_flags;
421 421
422 bool htc_reset_init;
423
422 enum nl80211_iftype opmode; 424 enum nl80211_iftype opmode;
423 enum ath9k_power_mode power_mode; 425 enum ath9k_power_mode power_mode;
424 426
@@ -541,11 +543,11 @@ struct ath_hw {
541 struct ar5416IniArray iniModesTxGain; 543 struct ar5416IniArray iniModesTxGain;
542}; 544};
543 545
544/* Attach, Detach, Reset */ 546/* Initialization, Detach, Reset */
545const char *ath9k_hw_probe(u16 vendorid, u16 devid); 547const char *ath9k_hw_probe(u16 vendorid, u16 devid);
546void ath9k_hw_detach(struct ath_hw *ah); 548void ath9k_hw_detach(struct ath_hw *ah);
547struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error); 549int ath9k_hw_init(struct ath_hw *ah);
548void ath9k_hw_rfdetach(struct ath_hw *ah); 550void ath9k_hw_rf_free(struct ath_hw *ah);
549int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 551int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
550 bool bChannelChange); 552 bool bChannelChange);
551void ath9k_hw_fill_cap_info(struct ath_hw *ah); 553void ath9k_hw_fill_cap_info(struct ath_hw *ah);
@@ -612,7 +614,6 @@ void ath9k_hw_configpcipowersave(struct ath_hw *ah, int restore);
612/* Interrupt Handling */ 614/* Interrupt Handling */
613bool ath9k_hw_intrpend(struct ath_hw *ah); 615bool ath9k_hw_intrpend(struct ath_hw *ah);
614bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked); 616bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked);
615enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah);
616enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints); 617enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
617 618
618void ath9k_hw_btcoex_enable(struct ath_hw *ah); 619void ath9k_hw_btcoex_enable(struct ath_hw *ah);
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index af4a1bafa7e7..27a86bb7c4c8 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
@@ -6365,3 +6365,669 @@ static const u_int32_t ar9287PciePhy_clkreq_off_L1_9287_1_1[][2] = {
6365}; 6365};
6366 6366
6367 6367
6368/* AR9271 initialization values automaticaly created: 03/23/09 */
6369static const u_int32_t ar9271Modes_9271_1_0[][6] = {
6370 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
6371 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
6372 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
6373 { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
6374 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
6375 { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
6376 { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
6377 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
6378 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
6379 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
6380 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
6381 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
6382 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
6383 { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
6384 { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
6385 { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
6386 { 0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
6387 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
6388 { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
6389 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
6390 { 0x00009860, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18, 0x00058d18 },
6391 { 0x00009864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
6392 { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
6393 { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
6394 { 0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0 },
6395 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
6396 { 0x00009924, 0xd00a8007, 0xd00a8007, 0xd00a800d, 0xd00a800d, 0xd00a800d },
6397 { 0x00009944, 0xffbc1010, 0xffbc1010, 0xffbc1020, 0xffbc1020, 0xffbc1010 },
6398 { 0x00009960, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6399 { 0x00009964, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6400 { 0x000099b8, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c, 0x0000421c },
6401 { 0x000099bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
6402 { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
6403 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
6404 { 0x000099c8, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329, 0x6af65329 },
6405 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
6406 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
6407 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6408 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6409 { 0x00009a00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
6410 { 0x00009a04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
6411 { 0x00009a08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
6412 { 0x00009a0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
6413 { 0x00009a10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
6414 { 0x00009a14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
6415 { 0x00009a18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
6416 { 0x00009a1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
6417 { 0x00009a20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
6418 { 0x00009a24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
6419 { 0x00009a28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
6420 { 0x00009a2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
6421 { 0x00009a30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
6422 { 0x00009a34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
6423 { 0x00009a38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
6424 { 0x00009a3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
6425 { 0x00009a40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
6426 { 0x00009a44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6427 { 0x00009a48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6428 { 0x00009a4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6429 { 0x00009a50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
6430 { 0x00009a54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6431 { 0x00009a58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6432 { 0x00009a5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
6433 { 0x00009a60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
6434 { 0x00009a64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
6435 { 0x00009a68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
6436 { 0x00009a6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
6437 { 0x00009a70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
6438 { 0x00009a74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
6439 { 0x00009a78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
6440 { 0x00009a7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6441 { 0x00009a80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6442 { 0x00009a84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6443 { 0x00009a88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6444 { 0x00009a8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6445 { 0x00009a90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6446 { 0x00009a94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6447 { 0x00009a98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
6448 { 0x00009a9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
6449 { 0x00009aa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
6450 { 0x00009aa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
6451 { 0x00009aa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
6452 { 0x00009aac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
6453 { 0x00009ab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
6454 { 0x00009ab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
6455 { 0x00009ab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
6456 { 0x00009abc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
6457 { 0x00009ac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
6458 { 0x00009ac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
6459 { 0x00009ac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
6460 { 0x00009acc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
6461 { 0x00009ad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
6462 { 0x00009ad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
6463 { 0x00009ad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
6464 { 0x00009adc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
6465 { 0x00009ae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
6466 { 0x00009ae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
6467 { 0x00009ae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
6468 { 0x00009aec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
6469 { 0x00009af0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
6470 { 0x00009af4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
6471 { 0x00009af8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
6472 { 0x00009afc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
6473 { 0x00009b00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
6474 { 0x00009b04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
6475 { 0x00009b08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
6476 { 0x00009b0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
6477 { 0x00009b10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
6478 { 0x00009b14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
6479 { 0x00009b18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
6480 { 0x00009b1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
6481 { 0x00009b20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
6482 { 0x00009b24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
6483 { 0x00009b28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
6484 { 0x00009b2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
6485 { 0x00009b30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
6486 { 0x00009b34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
6487 { 0x00009b38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
6488 { 0x00009b3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
6489 { 0x00009b40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
6490 { 0x00009b44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
6491 { 0x00009b48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
6492 { 0x00009b4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
6493 { 0x00009b50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
6494 { 0x00009b54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
6495 { 0x00009b58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
6496 { 0x00009b5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
6497 { 0x00009b60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
6498 { 0x00009b64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6499 { 0x00009b68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6500 { 0x00009b6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6501 { 0x00009b70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6502 { 0x00009b74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6503 { 0x00009b78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6504 { 0x00009b7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6505 { 0x00009b80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6506 { 0x00009b84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6507 { 0x00009b88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6508 { 0x00009b8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6509 { 0x00009b90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6510 { 0x00009b94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6511 { 0x00009b98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6512 { 0x00009b9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6513 { 0x00009ba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6514 { 0x00009ba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6515 { 0x00009ba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6516 { 0x00009bac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6517 { 0x00009bb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6518 { 0x00009bb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6519 { 0x00009bb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6520 { 0x00009bbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6521 { 0x00009bc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6522 { 0x00009bc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6523 { 0x00009bc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6524 { 0x00009bcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6525 { 0x00009bd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6526 { 0x00009bd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6527 { 0x00009bd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6528 { 0x00009bdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6529 { 0x00009be0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6530 { 0x00009be4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6531 { 0x00009be8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6532 { 0x00009bec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6533 { 0x00009bf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6534 { 0x00009bf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6535 { 0x00009bf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6536 { 0x00009bfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6537 { 0x0000aa00, 0x00000000, 0x00000000, 0x00058084, 0x00058084, 0x00000000 },
6538 { 0x0000aa04, 0x00000000, 0x00000000, 0x00058088, 0x00058088, 0x00000000 },
6539 { 0x0000aa08, 0x00000000, 0x00000000, 0x0005808c, 0x0005808c, 0x00000000 },
6540 { 0x0000aa0c, 0x00000000, 0x00000000, 0x00058100, 0x00058100, 0x00000000 },
6541 { 0x0000aa10, 0x00000000, 0x00000000, 0x00058104, 0x00058104, 0x00000000 },
6542 { 0x0000aa14, 0x00000000, 0x00000000, 0x00058108, 0x00058108, 0x00000000 },
6543 { 0x0000aa18, 0x00000000, 0x00000000, 0x0005810c, 0x0005810c, 0x00000000 },
6544 { 0x0000aa1c, 0x00000000, 0x00000000, 0x00058110, 0x00058110, 0x00000000 },
6545 { 0x0000aa20, 0x00000000, 0x00000000, 0x00058114, 0x00058114, 0x00000000 },
6546 { 0x0000aa24, 0x00000000, 0x00000000, 0x00058180, 0x00058180, 0x00000000 },
6547 { 0x0000aa28, 0x00000000, 0x00000000, 0x00058184, 0x00058184, 0x00000000 },
6548 { 0x0000aa2c, 0x00000000, 0x00000000, 0x00058188, 0x00058188, 0x00000000 },
6549 { 0x0000aa30, 0x00000000, 0x00000000, 0x0005818c, 0x0005818c, 0x00000000 },
6550 { 0x0000aa34, 0x00000000, 0x00000000, 0x00058190, 0x00058190, 0x00000000 },
6551 { 0x0000aa38, 0x00000000, 0x00000000, 0x00058194, 0x00058194, 0x00000000 },
6552 { 0x0000aa3c, 0x00000000, 0x00000000, 0x000581a0, 0x000581a0, 0x00000000 },
6553 { 0x0000aa40, 0x00000000, 0x00000000, 0x0005820c, 0x0005820c, 0x00000000 },
6554 { 0x0000aa44, 0x00000000, 0x00000000, 0x000581a8, 0x000581a8, 0x00000000 },
6555 { 0x0000aa48, 0x00000000, 0x00000000, 0x00058284, 0x00058284, 0x00000000 },
6556 { 0x0000aa4c, 0x00000000, 0x00000000, 0x00058288, 0x00058288, 0x00000000 },
6557 { 0x0000aa50, 0x00000000, 0x00000000, 0x00058220, 0x00058220, 0x00000000 },
6558 { 0x0000aa54, 0x00000000, 0x00000000, 0x00058290, 0x00058290, 0x00000000 },
6559 { 0x0000aa58, 0x00000000, 0x00000000, 0x00058300, 0x00058300, 0x00000000 },
6560 { 0x0000aa5c, 0x00000000, 0x00000000, 0x00058304, 0x00058304, 0x00000000 },
6561 { 0x0000aa60, 0x00000000, 0x00000000, 0x00058308, 0x00058308, 0x00000000 },
6562 { 0x0000aa64, 0x00000000, 0x00000000, 0x0005830c, 0x0005830c, 0x00000000 },
6563 { 0x0000aa68, 0x00000000, 0x00000000, 0x00058380, 0x00058380, 0x00000000 },
6564 { 0x0000aa6c, 0x00000000, 0x00000000, 0x00058384, 0x00058384, 0x00000000 },
6565 { 0x0000aa70, 0x00000000, 0x00000000, 0x00068700, 0x00068700, 0x00000000 },
6566 { 0x0000aa74, 0x00000000, 0x00000000, 0x00068704, 0x00068704, 0x00000000 },
6567 { 0x0000aa78, 0x00000000, 0x00000000, 0x00068708, 0x00068708, 0x00000000 },
6568 { 0x0000aa7c, 0x00000000, 0x00000000, 0x0006870c, 0x0006870c, 0x00000000 },
6569 { 0x0000aa80, 0x00000000, 0x00000000, 0x00068780, 0x00068780, 0x00000000 },
6570 { 0x0000aa84, 0x00000000, 0x00000000, 0x00068784, 0x00068784, 0x00000000 },
6571 { 0x0000aa88, 0x00000000, 0x00000000, 0x00078b04, 0x00078b04, 0x00000000 },
6572 { 0x0000aa8c, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6573 { 0x0000aa90, 0x00000000, 0x00000000, 0x00078b08, 0x00078b08, 0x00000000 },
6574 { 0x0000aa94, 0x00000000, 0x00000000, 0x00078b0c, 0x00078b0c, 0x00000000 },
6575 { 0x0000aa98, 0x00000000, 0x00000000, 0x00078b80, 0x00078b80, 0x00000000 },
6576 { 0x0000aa9c, 0x00000000, 0x00000000, 0x00078b84, 0x00078b84, 0x00000000 },
6577 { 0x0000aaa0, 0x00000000, 0x00000000, 0x00078b88, 0x00078b88, 0x00000000 },
6578 { 0x0000aaa4, 0x00000000, 0x00000000, 0x00078b8c, 0x00078b8c, 0x00000000 },
6579 { 0x0000aaa8, 0x00000000, 0x00000000, 0x00078b90, 0x00078b90, 0x00000000 },
6580 { 0x0000aaac, 0x00000000, 0x00000000, 0x000caf80, 0x000caf80, 0x00000000 },
6581 { 0x0000aab0, 0x00000000, 0x00000000, 0x000caf84, 0x000caf84, 0x00000000 },
6582 { 0x0000aab4, 0x00000000, 0x00000000, 0x000caf88, 0x000caf88, 0x00000000 },
6583 { 0x0000aab8, 0x00000000, 0x00000000, 0x000caf8c, 0x000caf8c, 0x00000000 },
6584 { 0x0000aabc, 0x00000000, 0x00000000, 0x000caf90, 0x000caf90, 0x00000000 },
6585 { 0x0000aac0, 0x00000000, 0x00000000, 0x000db30c, 0x000db30c, 0x00000000 },
6586 { 0x0000aac4, 0x00000000, 0x00000000, 0x000db310, 0x000db310, 0x00000000 },
6587 { 0x0000aac8, 0x00000000, 0x00000000, 0x000db384, 0x000db384, 0x00000000 },
6588 { 0x0000aacc, 0x00000000, 0x00000000, 0x000db388, 0x000db388, 0x00000000 },
6589 { 0x0000aad0, 0x00000000, 0x00000000, 0x000db324, 0x000db324, 0x00000000 },
6590 { 0x0000aad4, 0x00000000, 0x00000000, 0x000eb704, 0x000eb704, 0x00000000 },
6591 { 0x0000aad8, 0x00000000, 0x00000000, 0x000eb6a4, 0x000eb6a4, 0x00000000 },
6592 { 0x0000aadc, 0x00000000, 0x00000000, 0x000eb6a8, 0x000eb6a8, 0x00000000 },
6593 { 0x0000aae0, 0x00000000, 0x00000000, 0x000eb710, 0x000eb710, 0x00000000 },
6594 { 0x0000aae4, 0x00000000, 0x00000000, 0x000eb714, 0x000eb714, 0x00000000 },
6595 { 0x0000aae8, 0x00000000, 0x00000000, 0x000eb720, 0x000eb720, 0x00000000 },
6596 { 0x0000aaec, 0x00000000, 0x00000000, 0x000eb724, 0x000eb724, 0x00000000 },
6597 { 0x0000aaf0, 0x00000000, 0x00000000, 0x000eb728, 0x000eb728, 0x00000000 },
6598 { 0x0000aaf4, 0x00000000, 0x00000000, 0x000eb72c, 0x000eb72c, 0x00000000 },
6599 { 0x0000aaf8, 0x00000000, 0x00000000, 0x000eb7a0, 0x000eb7a0, 0x00000000 },
6600 { 0x0000aafc, 0x00000000, 0x00000000, 0x000eb7a4, 0x000eb7a4, 0x00000000 },
6601 { 0x0000ab00, 0x00000000, 0x00000000, 0x000eb7a8, 0x000eb7a8, 0x00000000 },
6602 { 0x0000ab04, 0x00000000, 0x00000000, 0x000eb7b0, 0x000eb7b0, 0x00000000 },
6603 { 0x0000ab08, 0x00000000, 0x00000000, 0x000eb7b4, 0x000eb7b4, 0x00000000 },
6604 { 0x0000ab0c, 0x00000000, 0x00000000, 0x000eb7b8, 0x000eb7b8, 0x00000000 },
6605 { 0x0000ab10, 0x00000000, 0x00000000, 0x000eb7a5, 0x000eb7a5, 0x00000000 },
6606 { 0x0000ab14, 0x00000000, 0x00000000, 0x000eb7a9, 0x000eb7a9, 0x00000000 },
6607 { 0x0000ab18, 0x00000000, 0x00000000, 0x000eb7ad, 0x000eb7ad, 0x00000000 },
6608 { 0x0000ab1c, 0x00000000, 0x00000000, 0x000eb7b1, 0x000eb7b1, 0x00000000 },
6609 { 0x0000ab20, 0x00000000, 0x00000000, 0x000eb7b5, 0x000eb7b5, 0x00000000 },
6610 { 0x0000ab24, 0x00000000, 0x00000000, 0x000eb7b9, 0x000eb7b9, 0x00000000 },
6611 { 0x0000ab28, 0x00000000, 0x00000000, 0x000eb7c5, 0x000eb7c5, 0x00000000 },
6612 { 0x0000ab2c, 0x00000000, 0x00000000, 0x000eb7c9, 0x000eb7c9, 0x00000000 },
6613 { 0x0000ab30, 0x00000000, 0x00000000, 0x000eb7d1, 0x000eb7d1, 0x00000000 },
6614 { 0x0000ab34, 0x00000000, 0x00000000, 0x000eb7d5, 0x000eb7d5, 0x00000000 },
6615 { 0x0000ab38, 0x00000000, 0x00000000, 0x000eb7d9, 0x000eb7d9, 0x00000000 },
6616 { 0x0000ab3c, 0x00000000, 0x00000000, 0x000eb7c6, 0x000eb7c6, 0x00000000 },
6617 { 0x0000ab40, 0x00000000, 0x00000000, 0x000eb7ca, 0x000eb7ca, 0x00000000 },
6618 { 0x0000ab44, 0x00000000, 0x00000000, 0x000eb7ce, 0x000eb7ce, 0x00000000 },
6619 { 0x0000ab48, 0x00000000, 0x00000000, 0x000eb7d2, 0x000eb7d2, 0x00000000 },
6620 { 0x0000ab4c, 0x00000000, 0x00000000, 0x000eb7d6, 0x000eb7d6, 0x00000000 },
6621 { 0x0000ab50, 0x00000000, 0x00000000, 0x000eb7c3, 0x000eb7c3, 0x00000000 },
6622 { 0x0000ab54, 0x00000000, 0x00000000, 0x000eb7c7, 0x000eb7c7, 0x00000000 },
6623 { 0x0000ab58, 0x00000000, 0x00000000, 0x000eb7cb, 0x000eb7cb, 0x00000000 },
6624 { 0x0000ab5c, 0x00000000, 0x00000000, 0x000eb7cf, 0x000eb7cf, 0x00000000 },
6625 { 0x0000ab60, 0x00000000, 0x00000000, 0x000eb7d7, 0x000eb7d7, 0x00000000 },
6626 { 0x0000ab64, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6627 { 0x0000ab68, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6628 { 0x0000ab6c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6629 { 0x0000ab70, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6630 { 0x0000ab74, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6631 { 0x0000ab78, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6632 { 0x0000ab7c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6633 { 0x0000ab80, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6634 { 0x0000ab84, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6635 { 0x0000ab88, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6636 { 0x0000ab8c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6637 { 0x0000ab90, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6638 { 0x0000ab94, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6639 { 0x0000ab98, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6640 { 0x0000ab9c, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6641 { 0x0000aba0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6642 { 0x0000aba4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6643 { 0x0000aba8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6644 { 0x0000abac, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6645 { 0x0000abb0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6646 { 0x0000abb4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6647 { 0x0000abb8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6648 { 0x0000abbc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6649 { 0x0000abc0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6650 { 0x0000abc4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6651 { 0x0000abc8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6652 { 0x0000abcc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6653 { 0x0000abd0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6654 { 0x0000abd4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6655 { 0x0000abd8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6656 { 0x0000abdc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6657 { 0x0000abe0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6658 { 0x0000abe4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6659 { 0x0000abe8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6660 { 0x0000abec, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6661 { 0x0000abf0, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6662 { 0x0000abf4, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6663 { 0x0000abf8, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6664 { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
6665 { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
6666 { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
6667 { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
6668 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
6669 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
6670 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
6671 { 0x0000a274, 0x0a21c652, 0x0a21c652, 0x0a218652, 0x0a218652, 0x0a22a652 },
6672 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
6673 { 0x0000a304, 0x00000000, 0x00000000, 0x00009200, 0x00009200, 0x00000000 },
6674 { 0x0000a308, 0x00000000, 0x00000000, 0x00010208, 0x00010208, 0x00000000 },
6675 { 0x0000a30c, 0x00000000, 0x00000000, 0x00019608, 0x00019608, 0x00000000 },
6676 { 0x0000a310, 0x00000000, 0x00000000, 0x0001e610, 0x0001e610, 0x00000000 },
6677 { 0x0000a314, 0x00000000, 0x00000000, 0x0002d6d0, 0x0002d6d0, 0x00000000 },
6678 { 0x0000a318, 0x00000000, 0x00000000, 0x00039758, 0x00039758, 0x00000000 },
6679 { 0x0000a31c, 0x00000000, 0x00000000, 0x0003b759, 0x0003b759, 0x00000000 },
6680 { 0x0000a320, 0x00000000, 0x00000000, 0x0003d75a, 0x0003d75a, 0x00000000 },
6681 { 0x0000a324, 0x00000000, 0x00000000, 0x0004175c, 0x0004175c, 0x00000000 },
6682 { 0x0000a328, 0x00000000, 0x00000000, 0x0004575e, 0x0004575e, 0x00000000 },
6683 { 0x0000a32c, 0x00000000, 0x00000000, 0x0004979f, 0x0004979f, 0x00000000 },
6684 { 0x0000a330, 0x00000000, 0x00000000, 0x0004d7df, 0x0004d7df, 0x00000000 },
6685 { 0x0000a334, 0x000368de, 0x000368de, 0x000368de, 0x000368de, 0x00000000 },
6686 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
6687 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
6688 { 0x0000a340, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6689 { 0x0000a344, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x0003e9df, 0x00000000 },
6690 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
6691};
6692
6693static const u_int32_t ar9271Common_9271_1_0[][2] = {
6694 { 0x0000000c, 0x00000000 },
6695 { 0x00000030, 0x00020045 },
6696 { 0x00000034, 0x00000005 },
6697 { 0x00000040, 0x00000000 },
6698 { 0x00000044, 0x00000008 },
6699 { 0x00000048, 0x00000008 },
6700 { 0x0000004c, 0x00000010 },
6701 { 0x00000050, 0x00000000 },
6702 { 0x00000054, 0x0000001f },
6703 { 0x00000800, 0x00000000 },
6704 { 0x00000804, 0x00000000 },
6705 { 0x00000808, 0x00000000 },
6706 { 0x0000080c, 0x00000000 },
6707 { 0x00000810, 0x00000000 },
6708 { 0x00000814, 0x00000000 },
6709 { 0x00000818, 0x00000000 },
6710 { 0x0000081c, 0x00000000 },
6711 { 0x00000820, 0x00000000 },
6712 { 0x00000824, 0x00000000 },
6713 { 0x00001040, 0x002ffc0f },
6714 { 0x00001044, 0x002ffc0f },
6715 { 0x00001048, 0x002ffc0f },
6716 { 0x0000104c, 0x002ffc0f },
6717 { 0x00001050, 0x002ffc0f },
6718 { 0x00001054, 0x002ffc0f },
6719 { 0x00001058, 0x002ffc0f },
6720 { 0x0000105c, 0x002ffc0f },
6721 { 0x00001060, 0x002ffc0f },
6722 { 0x00001064, 0x002ffc0f },
6723 { 0x00001230, 0x00000000 },
6724 { 0x00001270, 0x00000000 },
6725 { 0x00001038, 0x00000000 },
6726 { 0x00001078, 0x00000000 },
6727 { 0x000010b8, 0x00000000 },
6728 { 0x000010f8, 0x00000000 },
6729 { 0x00001138, 0x00000000 },
6730 { 0x00001178, 0x00000000 },
6731 { 0x000011b8, 0x00000000 },
6732 { 0x000011f8, 0x00000000 },
6733 { 0x00001238, 0x00000000 },
6734 { 0x00001278, 0x00000000 },
6735 { 0x000012b8, 0x00000000 },
6736 { 0x000012f8, 0x00000000 },
6737 { 0x00001338, 0x00000000 },
6738 { 0x00001378, 0x00000000 },
6739 { 0x000013b8, 0x00000000 },
6740 { 0x000013f8, 0x00000000 },
6741 { 0x00001438, 0x00000000 },
6742 { 0x00001478, 0x00000000 },
6743 { 0x000014b8, 0x00000000 },
6744 { 0x000014f8, 0x00000000 },
6745 { 0x00001538, 0x00000000 },
6746 { 0x00001578, 0x00000000 },
6747 { 0x000015b8, 0x00000000 },
6748 { 0x000015f8, 0x00000000 },
6749 { 0x00001638, 0x00000000 },
6750 { 0x00001678, 0x00000000 },
6751 { 0x000016b8, 0x00000000 },
6752 { 0x000016f8, 0x00000000 },
6753 { 0x00001738, 0x00000000 },
6754 { 0x00001778, 0x00000000 },
6755 { 0x000017b8, 0x00000000 },
6756 { 0x000017f8, 0x00000000 },
6757 { 0x0000103c, 0x00000000 },
6758 { 0x0000107c, 0x00000000 },
6759 { 0x000010bc, 0x00000000 },
6760 { 0x000010fc, 0x00000000 },
6761 { 0x0000113c, 0x00000000 },
6762 { 0x0000117c, 0x00000000 },
6763 { 0x000011bc, 0x00000000 },
6764 { 0x000011fc, 0x00000000 },
6765 { 0x0000123c, 0x00000000 },
6766 { 0x0000127c, 0x00000000 },
6767 { 0x000012bc, 0x00000000 },
6768 { 0x000012fc, 0x00000000 },
6769 { 0x0000133c, 0x00000000 },
6770 { 0x0000137c, 0x00000000 },
6771 { 0x000013bc, 0x00000000 },
6772 { 0x000013fc, 0x00000000 },
6773 { 0x0000143c, 0x00000000 },
6774 { 0x0000147c, 0x00000000 },
6775 { 0x00004030, 0x00000002 },
6776 { 0x0000403c, 0x00000002 },
6777 { 0x00004024, 0x0000001f },
6778 { 0x00004060, 0x00000000 },
6779 { 0x00004064, 0x00000000 },
6780 { 0x00008004, 0x00000000 },
6781 { 0x00008008, 0x00000000 },
6782 { 0x0000800c, 0x00000000 },
6783 { 0x00008018, 0x00000700 },
6784 { 0x00008020, 0x00000000 },
6785 { 0x00008038, 0x00000000 },
6786 { 0x0000803c, 0x00000000 },
6787 { 0x00008048, 0x00000000 },
6788 { 0x00008054, 0x00000000 },
6789 { 0x00008058, 0x02000000 },
6790 { 0x0000805c, 0x000fc78f },
6791 { 0x00008060, 0x0000000f },
6792 { 0x00008064, 0x00000000 },
6793 { 0x00008070, 0x00000000 },
6794 { 0x000080b0, 0x00000000 },
6795 { 0x000080b4, 0x00000000 },
6796 { 0x000080b8, 0x00000000 },
6797 { 0x000080bc, 0x00000000 },
6798 { 0x000080c0, 0x2a80001a },
6799 { 0x000080c4, 0x05dc01e0 },
6800 { 0x000080c8, 0x1f402710 },
6801 { 0x000080cc, 0x01f40000 },
6802 { 0x000080d0, 0x00001e00 },
6803 { 0x000080d4, 0x00000000 },
6804 { 0x000080d8, 0x00400000 },
6805 { 0x000080e0, 0xffffffff },
6806 { 0x000080e4, 0x0000ffff },
6807 { 0x000080e8, 0x003f3f3f },
6808 { 0x000080ec, 0x00000000 },
6809 { 0x000080f0, 0x00000000 },
6810 { 0x000080f4, 0x00000000 },
6811 { 0x000080f8, 0x00000000 },
6812 { 0x000080fc, 0x00020000 },
6813 { 0x00008100, 0x00020000 },
6814 { 0x00008104, 0x00000001 },
6815 { 0x00008108, 0x00000052 },
6816 { 0x0000810c, 0x00000000 },
6817 { 0x00008110, 0x00000168 },
6818 { 0x00008118, 0x000100aa },
6819 { 0x0000811c, 0x00003210 },
6820 { 0x00008120, 0x08f04814 },
6821 { 0x00008124, 0x00000000 },
6822 { 0x00008128, 0x00000000 },
6823 { 0x0000812c, 0x00000000 },
6824 { 0x00008130, 0x00000000 },
6825 { 0x00008134, 0x00000000 },
6826 { 0x00008138, 0x00000000 },
6827 { 0x0000813c, 0x00000000 },
6828 { 0x00008144, 0xffffffff },
6829 { 0x00008168, 0x00000000 },
6830 { 0x0000816c, 0x00000000 },
6831 { 0x00008170, 0x32143320 },
6832 { 0x00008174, 0xfaa4fa50 },
6833 { 0x00008178, 0x00000100 },
6834 { 0x0000817c, 0x00000000 },
6835 { 0x000081c0, 0x00000000 },
6836 { 0x000081d0, 0x0000320a },
6837 { 0x000081ec, 0x00000000 },
6838 { 0x000081f0, 0x00000000 },
6839 { 0x000081f4, 0x00000000 },
6840 { 0x000081f8, 0x00000000 },
6841 { 0x000081fc, 0x00000000 },
6842 { 0x00008200, 0x00000000 },
6843 { 0x00008204, 0x00000000 },
6844 { 0x00008208, 0x00000000 },
6845 { 0x0000820c, 0x00000000 },
6846 { 0x00008210, 0x00000000 },
6847 { 0x00008214, 0x00000000 },
6848 { 0x00008218, 0x00000000 },
6849 { 0x0000821c, 0x00000000 },
6850 { 0x00008220, 0x00000000 },
6851 { 0x00008224, 0x00000000 },
6852 { 0x00008228, 0x00000000 },
6853 { 0x0000822c, 0x00000000 },
6854 { 0x00008230, 0x00000000 },
6855 { 0x00008234, 0x00000000 },
6856 { 0x00008238, 0x00000000 },
6857 { 0x0000823c, 0x00000000 },
6858 { 0x00008240, 0x00100000 },
6859 { 0x00008244, 0x0010f400 },
6860 { 0x00008248, 0x00000100 },
6861 { 0x0000824c, 0x0001e800 },
6862 { 0x00008250, 0x00000000 },
6863 { 0x00008254, 0x00000000 },
6864 { 0x00008258, 0x00000000 },
6865 { 0x0000825c, 0x400000ff },
6866 { 0x00008260, 0x00080922 },
6867 { 0x00008264, 0xa8a00010 },
6868 { 0x00008270, 0x00000000 },
6869 { 0x00008274, 0x40000000 },
6870 { 0x00008278, 0x003e4180 },
6871 { 0x0000827c, 0x00000000 },
6872 { 0x00008284, 0x0000002c },
6873 { 0x00008288, 0x0000002c },
6874 { 0x0000828c, 0x00000000 },
6875 { 0x00008294, 0x00000000 },
6876 { 0x00008298, 0x00000000 },
6877 { 0x0000829c, 0x00000000 },
6878 { 0x00008300, 0x00000040 },
6879 { 0x00008314, 0x00000000 },
6880 { 0x00008328, 0x00000000 },
6881 { 0x0000832c, 0x00000001 },
6882 { 0x00008330, 0x00000302 },
6883 { 0x00008334, 0x00000e00 },
6884 { 0x00008338, 0x00ff0000 },
6885 { 0x0000833c, 0x00000000 },
6886 { 0x00008340, 0x00010380 },
6887 { 0x00008344, 0x00581043 },
6888 { 0x00007010, 0x00000030 },
6889 { 0x00007034, 0x00000002 },
6890 { 0x00007038, 0x000004c2 },
6891 { 0x00007800, 0x00140000 },
6892 { 0x00007804, 0x0e4548d8 },
6893 { 0x00007808, 0x54214514 },
6894 { 0x0000780c, 0x02025820 },
6895 { 0x00007810, 0x71c0d388 },
6896 { 0x00007814, 0x924934a8 },
6897 { 0x0000781c, 0x00000000 },
6898 { 0x00007820, 0x00000c04 },
6899 { 0x00007824, 0x00d86bff },
6900 { 0x00007828, 0x66964300 },
6901 { 0x0000782c, 0x8db6d961 },
6902 { 0x00007830, 0x8db6d96c },
6903 { 0x00007834, 0x6140008b },
6904 { 0x00007838, 0x00000029 },
6905 { 0x0000783c, 0x72ee0a72 },
6906 { 0x00007840, 0xbbfffffc },
6907 { 0x00007844, 0x000c0db6 },
6908 { 0x00007848, 0x6db61b6f },
6909 { 0x0000784c, 0x6d9b66db },
6910 { 0x00007850, 0x6d8c6dba },
6911 { 0x00007854, 0x00040000 },
6912 { 0x00007858, 0xdb003012 },
6913 { 0x0000785c, 0x04924914 },
6914 { 0x00007860, 0x21084210 },
6915 { 0x00007864, 0xf7d7ffde },
6916 { 0x00007868, 0xc2034080 },
6917 { 0x0000786c, 0x48609eb4 },
6918 { 0x00007870, 0x10142c00 },
6919 { 0x00009808, 0x00000000 },
6920 { 0x0000980c, 0xafe68e30 },
6921 { 0x00009810, 0xfd14e000 },
6922 { 0x00009814, 0x9c0a9f6b },
6923 { 0x0000981c, 0x00000000 },
6924 { 0x0000982c, 0x0000a000 },
6925 { 0x00009830, 0x00000000 },
6926 { 0x0000983c, 0x00200400 },
6927 { 0x0000984c, 0x0040233c },
6928 { 0x00009854, 0x00000044 },
6929 { 0x00009900, 0x00000000 },
6930 { 0x00009904, 0x00000000 },
6931 { 0x00009908, 0x00000000 },
6932 { 0x0000990c, 0x00000000 },
6933 { 0x00009910, 0x30002310 },
6934 { 0x0000991c, 0x10000fff },
6935 { 0x00009920, 0x04900000 },
6936 { 0x00009928, 0x00000001 },
6937 { 0x0000992c, 0x00000004 },
6938 { 0x00009934, 0x1e1f2022 },
6939 { 0x00009938, 0x0a0b0c0d },
6940 { 0x0000993c, 0x00000000 },
6941 { 0x00009940, 0x14750604 },
6942 { 0x00009948, 0x9280c00a },
6943 { 0x0000994c, 0x00020028 },
6944 { 0x00009954, 0x5f3ca3de },
6945 { 0x00009958, 0x0108ecff },
6946 { 0x00009968, 0x000003ce },
6947 { 0x00009970, 0x192bb515 },
6948 { 0x00009974, 0x00000000 },
6949 { 0x00009978, 0x00000001 },
6950 { 0x0000997c, 0x00000000 },
6951 { 0x00009980, 0x00000000 },
6952 { 0x00009984, 0x00000000 },
6953 { 0x00009988, 0x00000000 },
6954 { 0x0000998c, 0x00000000 },
6955 { 0x00009990, 0x00000000 },
6956 { 0x00009994, 0x00000000 },
6957 { 0x00009998, 0x00000000 },
6958 { 0x0000999c, 0x00000000 },
6959 { 0x000099a0, 0x00000000 },
6960 { 0x000099a4, 0x00000001 },
6961 { 0x000099a8, 0x201fff00 },
6962 { 0x000099ac, 0x2def0400 },
6963 { 0x000099b0, 0x03051000 },
6964 { 0x000099b4, 0x00000820 },
6965 { 0x000099dc, 0x00000000 },
6966 { 0x000099e0, 0x00000000 },
6967 { 0x000099e4, 0xaaaaaaaa },
6968 { 0x000099e8, 0x3c466478 },
6969 { 0x000099ec, 0x0cc80caa },
6970 { 0x000099f0, 0x00000000 },
6971 { 0x0000a1f4, 0x00000000 },
6972 { 0x0000a1f8, 0x71733d01 },
6973 { 0x0000a1fc, 0xd0ad5c12 },
6974 { 0x0000a208, 0x803e68c8 },
6975 { 0x0000a210, 0x4080a333 },
6976 { 0x0000a214, 0x00206c10 },
6977 { 0x0000a218, 0x009c4060 },
6978 { 0x0000a220, 0x01834061 },
6979 { 0x0000a224, 0x00000400 },
6980 { 0x0000a228, 0x000003b5 },
6981 { 0x0000a22c, 0x00000000 },
6982 { 0x0000a234, 0x20202020 },
6983 { 0x0000a238, 0x20202020 },
6984 { 0x0000a244, 0x00000000 },
6985 { 0x0000a248, 0xfffffffc },
6986 { 0x0000a24c, 0x00000000 },
6987 { 0x0000a254, 0x00000000 },
6988 { 0x0000a258, 0x0ccb5380 },
6989 { 0x0000a25c, 0x15151501 },
6990 { 0x0000a260, 0xdfa90f01 },
6991 { 0x0000a268, 0x00000000 },
6992 { 0x0000a26c, 0x0ebae9e6 },
6993 { 0x0000a278, 0x3bdef7bd },
6994 { 0x0000a27c, 0x050e83bd },
6995 { 0x0000a388, 0x0c000000 },
6996 { 0x0000a38c, 0x20202020 },
6997 { 0x0000a390, 0x20202020 },
6998 { 0x0000a394, 0x3bdef7bd },
6999 { 0x0000a398, 0x000003bd },
7000 { 0x0000a39c, 0x00000001 },
7001 { 0x0000a3a0, 0x00000000 },
7002 { 0x0000a3a4, 0x00000000 },
7003 { 0x0000a3a8, 0x00000000 },
7004 { 0x0000a3ac, 0x00000000 },
7005 { 0x0000a3b0, 0x00000000 },
7006 { 0x0000a3b4, 0x00000000 },
7007 { 0x0000a3b8, 0x00000000 },
7008 { 0x0000a3bc, 0x00000000 },
7009 { 0x0000a3c0, 0x00000000 },
7010 { 0x0000a3c4, 0x00000000 },
7011 { 0x0000a3cc, 0x20202020 },
7012 { 0x0000a3d0, 0x20202020 },
7013 { 0x0000a3d4, 0x20202020 },
7014 { 0x0000a3dc, 0x3bdef7bd },
7015 { 0x0000a3e0, 0x000003bd },
7016 { 0x0000a3e4, 0x00000000 },
7017 { 0x0000a3e8, 0x18c43433 },
7018 { 0x0000a3ec, 0x00f70081 },
7019 { 0x0000a3f0, 0x01036a2f },
7020 { 0x0000a3f4, 0x00000000 },
7021 { 0x0000d270, 0x0d820820 },
7022 { 0x0000d35c, 0x07ffffef },
7023 { 0x0000d360, 0x0fffffe7 },
7024 { 0x0000d364, 0x17ffffe5 },
7025 { 0x0000d368, 0x1fffffe4 },
7026 { 0x0000d36c, 0x37ffffe3 },
7027 { 0x0000d370, 0x3fffffe3 },
7028 { 0x0000d374, 0x57ffffe3 },
7029 { 0x0000d378, 0x5fffffe2 },
7030 { 0x0000d37c, 0x7fffffe2 },
7031 { 0x0000d380, 0x7f3c7bba },
7032 { 0x0000d384, 0xf3307ff0 },
7033};
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 75ddb2acb644..a9e43f7a23f6 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -973,10 +973,11 @@ static void ath_led_blink_work(struct work_struct *work)
973 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 973 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN,
974 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0); 974 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
975 975
976 queue_delayed_work(sc->hw->workqueue, &sc->ath_led_blink_work, 976 ieee80211_queue_delayed_work(sc->hw,
977 (sc->sc_flags & SC_OP_LED_ON) ? 977 &sc->ath_led_blink_work,
978 msecs_to_jiffies(sc->led_off_duration) : 978 (sc->sc_flags & SC_OP_LED_ON) ?
979 msecs_to_jiffies(sc->led_on_duration)); 979 msecs_to_jiffies(sc->led_off_duration) :
980 msecs_to_jiffies(sc->led_on_duration));
980 981
981 sc->led_on_duration = sc->led_on_cnt ? 982 sc->led_on_duration = sc->led_on_cnt ?
982 max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) : 983 max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
@@ -1013,8 +1014,8 @@ static void ath_led_brightness(struct led_classdev *led_cdev,
1013 case LED_FULL: 1014 case LED_FULL:
1014 if (led->led_type == ATH_LED_ASSOC) { 1015 if (led->led_type == ATH_LED_ASSOC) {
1015 sc->sc_flags |= SC_OP_LED_ASSOCIATED; 1016 sc->sc_flags |= SC_OP_LED_ASSOCIATED;
1016 queue_delayed_work(sc->hw->workqueue, 1017 ieee80211_queue_delayed_work(sc->hw,
1017 &sc->ath_led_blink_work, 0); 1018 &sc->ath_led_blink_work, 0);
1018 } else if (led->led_type == ATH_LED_RADIO) { 1019 } else if (led->led_type == ATH_LED_RADIO) {
1019 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0); 1020 ath9k_hw_set_gpio(sc->sc_ah, ATH_LED_PIN, 0);
1020 sc->sc_flags |= SC_OP_LED_ON; 1021 sc->sc_flags |= SC_OP_LED_ON;
@@ -1056,7 +1057,6 @@ static void ath_unregister_led(struct ath_led *led)
1056 1057
1057static void ath_deinit_leds(struct ath_softc *sc) 1058static void ath_deinit_leds(struct ath_softc *sc)
1058{ 1059{
1059 cancel_delayed_work_sync(&sc->ath_led_blink_work);
1060 ath_unregister_led(&sc->assoc_led); 1060 ath_unregister_led(&sc->assoc_led);
1061 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED; 1061 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1062 ath_unregister_led(&sc->tx_led); 1062 ath_unregister_led(&sc->tx_led);
@@ -1113,6 +1113,7 @@ static void ath_init_leds(struct ath_softc *sc)
1113 return; 1113 return;
1114 1114
1115fail: 1115fail:
1116 cancel_delayed_work_sync(&sc->ath_led_blink_work);
1116 ath_deinit_leds(sc); 1117 ath_deinit_leds(sc);
1117} 1118}
1118 1119
@@ -1252,9 +1253,6 @@ void ath_detach(struct ath_softc *sc)
1252 DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n"); 1253 DPRINTF(sc, ATH_DBG_CONFIG, "Detach ATH hw\n");
1253 1254
1254 ath_deinit_leds(sc); 1255 ath_deinit_leds(sc);
1255 cancel_work_sync(&sc->chan_work);
1256 cancel_delayed_work_sync(&sc->wiphy_work);
1257 cancel_delayed_work_sync(&sc->tx_complete_work);
1258 1256
1259 for (i = 0; i < sc->num_sec_wiphy; i++) { 1257 for (i = 0; i < sc->num_sec_wiphy; i++) {
1260 struct ath_wiphy *aphy = sc->sec_wiphy[i]; 1258 struct ath_wiphy *aphy = sc->sec_wiphy[i];
@@ -1280,6 +1278,7 @@ void ath_detach(struct ath_softc *sc)
1280 ath_tx_cleanupq(sc, &sc->tx.txq[i]); 1278 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1281 1279
1282 ath9k_hw_detach(sc->sc_ah); 1280 ath9k_hw_detach(sc->sc_ah);
1281 sc->sc_ah = NULL;
1283 ath9k_exit_debug(sc); 1282 ath9k_exit_debug(sc);
1284} 1283}
1285 1284
@@ -1294,11 +1293,16 @@ static int ath9k_reg_notifier(struct wiphy *wiphy,
1294 return ath_reg_notifier_apply(wiphy, request, reg); 1293 return ath_reg_notifier_apply(wiphy, request, reg);
1295} 1294}
1296 1295
1297static int ath_init(u16 devid, struct ath_softc *sc) 1296/*
1297 * Initialize and fill ath_softc, ath_sofct is the
1298 * "Software Carrier" struct. Historically it has existed
1299 * to allow the separation between hardware specific
1300 * variables (now in ath_hw) and driver specific variables.
1301 */
1302static int ath_init_softc(u16 devid, struct ath_softc *sc)
1298{ 1303{
1299 struct ath_hw *ah = NULL; 1304 struct ath_hw *ah = NULL;
1300 int status; 1305 int r = 0, i;
1301 int error = 0, i;
1302 int csz = 0; 1306 int csz = 0;
1303 1307
1304 /* XXX: hardware will not be ready until ath_open() being called */ 1308 /* XXX: hardware will not be ready until ath_open() being called */
@@ -1325,14 +1329,23 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1325 /* XXX assert csz is non-zero */ 1329 /* XXX assert csz is non-zero */
1326 sc->cachelsz = csz << 2; /* convert to bytes */ 1330 sc->cachelsz = csz << 2; /* convert to bytes */
1327 1331
1328 ah = ath9k_hw_attach(devid, sc, &status); 1332 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
1329 if (ah == NULL) { 1333 if (!ah) {
1334 r = -ENOMEM;
1335 goto bad_no_ah;
1336 }
1337
1338 ah->ah_sc = sc;
1339 ah->hw_version.devid = devid;
1340 sc->sc_ah = ah;
1341
1342 r = ath9k_hw_init(ah);
1343 if (r) {
1330 DPRINTF(sc, ATH_DBG_FATAL, 1344 DPRINTF(sc, ATH_DBG_FATAL,
1331 "Unable to attach hardware; HAL status %d\n", status); 1345 "Unable to initialize hardware; "
1332 error = -ENXIO; 1346 "initialization status: %d\n", r);
1333 goto bad; 1347 goto bad;
1334 } 1348 }
1335 sc->sc_ah = ah;
1336 1349
1337 /* Get the hardware key cache size. */ 1350 /* Get the hardware key cache size. */
1338 sc->keymax = ah->caps.keycache_size; 1351 sc->keymax = ah->caps.keycache_size;
@@ -1350,9 +1363,6 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1350 for (i = 0; i < sc->keymax; i++) 1363 for (i = 0; i < sc->keymax; i++)
1351 ath9k_hw_keyreset(ah, (u16) i); 1364 ath9k_hw_keyreset(ah, (u16) i);
1352 1365
1353 if (error)
1354 goto bad;
1355
1356 /* default to MONITOR mode */ 1366 /* default to MONITOR mode */
1357 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR; 1367 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
1358 1368
@@ -1372,14 +1382,14 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1372 if (sc->beacon.beaconq == -1) { 1382 if (sc->beacon.beaconq == -1) {
1373 DPRINTF(sc, ATH_DBG_FATAL, 1383 DPRINTF(sc, ATH_DBG_FATAL,
1374 "Unable to setup a beacon xmit queue\n"); 1384 "Unable to setup a beacon xmit queue\n");
1375 error = -EIO; 1385 r = -EIO;
1376 goto bad2; 1386 goto bad2;
1377 } 1387 }
1378 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0); 1388 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
1379 if (sc->beacon.cabq == NULL) { 1389 if (sc->beacon.cabq == NULL) {
1380 DPRINTF(sc, ATH_DBG_FATAL, 1390 DPRINTF(sc, ATH_DBG_FATAL,
1381 "Unable to setup CAB xmit queue\n"); 1391 "Unable to setup CAB xmit queue\n");
1382 error = -EIO; 1392 r = -EIO;
1383 goto bad2; 1393 goto bad2;
1384 } 1394 }
1385 1395
@@ -1394,26 +1404,26 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1394 if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) { 1404 if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
1395 DPRINTF(sc, ATH_DBG_FATAL, 1405 DPRINTF(sc, ATH_DBG_FATAL,
1396 "Unable to setup xmit queue for BK traffic\n"); 1406 "Unable to setup xmit queue for BK traffic\n");
1397 error = -EIO; 1407 r = -EIO;
1398 goto bad2; 1408 goto bad2;
1399 } 1409 }
1400 1410
1401 if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) { 1411 if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
1402 DPRINTF(sc, ATH_DBG_FATAL, 1412 DPRINTF(sc, ATH_DBG_FATAL,
1403 "Unable to setup xmit queue for BE traffic\n"); 1413 "Unable to setup xmit queue for BE traffic\n");
1404 error = -EIO; 1414 r = -EIO;
1405 goto bad2; 1415 goto bad2;
1406 } 1416 }
1407 if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) { 1417 if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
1408 DPRINTF(sc, ATH_DBG_FATAL, 1418 DPRINTF(sc, ATH_DBG_FATAL,
1409 "Unable to setup xmit queue for VI traffic\n"); 1419 "Unable to setup xmit queue for VI traffic\n");
1410 error = -EIO; 1420 r = -EIO;
1411 goto bad2; 1421 goto bad2;
1412 } 1422 }
1413 if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) { 1423 if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
1414 DPRINTF(sc, ATH_DBG_FATAL, 1424 DPRINTF(sc, ATH_DBG_FATAL,
1415 "Unable to setup xmit queue for VO traffic\n"); 1425 "Unable to setup xmit queue for VO traffic\n");
1416 error = -EIO; 1426 r = -EIO;
1417 goto bad2; 1427 goto bad2;
1418 } 1428 }
1419 1429
@@ -1507,11 +1517,12 @@ bad2:
1507 if (ATH_TXQ_SETUP(sc, i)) 1517 if (ATH_TXQ_SETUP(sc, i))
1508 ath_tx_cleanupq(sc, &sc->tx.txq[i]); 1518 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1509bad: 1519bad:
1510 if (ah) 1520 ath9k_hw_detach(ah);
1511 ath9k_hw_detach(ah); 1521 sc->sc_ah = NULL;
1522bad_no_ah:
1512 ath9k_exit_debug(sc); 1523 ath9k_exit_debug(sc);
1513 1524
1514 return error; 1525 return r;
1515} 1526}
1516 1527
1517void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) 1528void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
@@ -1551,7 +1562,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
1551 &sc->sbands[IEEE80211_BAND_5GHZ]; 1562 &sc->sbands[IEEE80211_BAND_5GHZ];
1552} 1563}
1553 1564
1554int ath_attach(u16 devid, struct ath_softc *sc) 1565/* Device driver core initialization */
1566int ath_init_device(u16 devid, struct ath_softc *sc)
1555{ 1567{
1556 struct ieee80211_hw *hw = sc->hw; 1568 struct ieee80211_hw *hw = sc->hw;
1557 int error = 0, i; 1569 int error = 0, i;
@@ -1559,7 +1571,7 @@ int ath_attach(u16 devid, struct ath_softc *sc)
1559 1571
1560 DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n"); 1572 DPRINTF(sc, ATH_DBG_CONFIG, "Attach ATH hw\n");
1561 1573
1562 error = ath_init(devid, sc); 1574 error = ath_init_softc(devid, sc);
1563 if (error != 0) 1575 if (error != 0)
1564 return error; 1576 return error;
1565 1577
@@ -1617,6 +1629,7 @@ error_attach:
1617 ath_tx_cleanupq(sc, &sc->tx.txq[i]); 1629 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1618 1630
1619 ath9k_hw_detach(sc->sc_ah); 1631 ath9k_hw_detach(sc->sc_ah);
1632 sc->sc_ah = NULL;
1620 ath9k_exit_debug(sc); 1633 ath9k_exit_debug(sc);
1621 1634
1622 return error; 1635 return error;
@@ -1975,7 +1988,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
1975 1988
1976 ieee80211_wake_queues(hw); 1989 ieee80211_wake_queues(hw);
1977 1990
1978 queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work, 0); 1991 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work, 0);
1979 1992
1980mutex_unlock: 1993mutex_unlock:
1981 mutex_unlock(&sc->mutex); 1994 mutex_unlock(&sc->mutex);
@@ -2089,6 +2102,14 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2089 2102
2090 aphy->state = ATH_WIPHY_INACTIVE; 2103 aphy->state = ATH_WIPHY_INACTIVE;
2091 2104
2105 cancel_delayed_work_sync(&sc->ath_led_blink_work);
2106 cancel_delayed_work_sync(&sc->tx_complete_work);
2107
2108 if (!sc->num_sec_wiphy) {
2109 cancel_delayed_work_sync(&sc->wiphy_work);
2110 cancel_work_sync(&sc->chan_work);
2111 }
2112
2092 if (sc->sc_flags & SC_OP_INVALID) { 2113 if (sc->sc_flags & SC_OP_INVALID) {
2093 DPRINTF(sc, ATH_DBG_ANY, "Device not present\n"); 2114 DPRINTF(sc, ATH_DBG_ANY, "Device not present\n");
2094 return; 2115 return;
@@ -2096,6 +2117,8 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2096 2117
2097 mutex_lock(&sc->mutex); 2118 mutex_lock(&sc->mutex);
2098 2119
2120 cancel_delayed_work_sync(&sc->tx_complete_work);
2121
2099 if (ath9k_wiphy_started(sc)) { 2122 if (ath9k_wiphy_started(sc)) {
2100 mutex_unlock(&sc->mutex); 2123 mutex_unlock(&sc->mutex);
2101 return; /* another wiphy still in use */ 2124 return; /* another wiphy still in use */
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index cd4841be80af..3546504a83c4 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -178,7 +178,7 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
178 sc->mem = mem; 178 sc->mem = mem;
179 sc->bus_ops = &ath_pci_bus_ops; 179 sc->bus_ops = &ath_pci_bus_ops;
180 180
181 if (ath_attach(id->device, sc) != 0) { 181 if (ath_init_device(id->device, sc) != 0) {
182 ret = -ENODEV; 182 ret = -ENODEV;
183 goto bad3; 183 goto bad3;
184 } 184 }
diff --git a/drivers/net/wireless/ath/ath9k/phy.c b/drivers/net/wireless/ath/ath9k/phy.c
index aaa941561c36..59bb3ce1e646 100644
--- a/drivers/net/wireless/ath/ath9k/phy.c
+++ b/drivers/net/wireless/ath/ath9k/phy.c
@@ -264,44 +264,23 @@ ath9k_hw_set_rf_regs(struct ath_hw *ah, struct ath9k_channel *chan,
264} 264}
265 265
266void 266void
267ath9k_hw_rfdetach(struct ath_hw *ah) 267ath9k_hw_rf_free(struct ath_hw *ah)
268{ 268{
269 if (ah->analogBank0Data != NULL) { 269#define ATH_FREE_BANK(bank) do { \
270 kfree(ah->analogBank0Data); 270 kfree(bank); \
271 ah->analogBank0Data = NULL; 271 bank = NULL; \
272 } 272 } while (0);
273 if (ah->analogBank1Data != NULL) { 273
274 kfree(ah->analogBank1Data); 274 ATH_FREE_BANK(ah->analogBank0Data);
275 ah->analogBank1Data = NULL; 275 ATH_FREE_BANK(ah->analogBank1Data);
276 } 276 ATH_FREE_BANK(ah->analogBank2Data);
277 if (ah->analogBank2Data != NULL) { 277 ATH_FREE_BANK(ah->analogBank3Data);
278 kfree(ah->analogBank2Data); 278 ATH_FREE_BANK(ah->analogBank6Data);
279 ah->analogBank2Data = NULL; 279 ATH_FREE_BANK(ah->analogBank6TPCData);
280 } 280 ATH_FREE_BANK(ah->analogBank7Data);
281 if (ah->analogBank3Data != NULL) { 281 ATH_FREE_BANK(ah->addac5416_21);
282 kfree(ah->analogBank3Data); 282 ATH_FREE_BANK(ah->bank6Temp);
283 ah->analogBank3Data = NULL; 283#undef ATH_FREE_BANK
284 }
285 if (ah->analogBank6Data != NULL) {
286 kfree(ah->analogBank6Data);
287 ah->analogBank6Data = NULL;
288 }
289 if (ah->analogBank6TPCData != NULL) {
290 kfree(ah->analogBank6TPCData);
291 ah->analogBank6TPCData = NULL;
292 }
293 if (ah->analogBank7Data != NULL) {
294 kfree(ah->analogBank7Data);
295 ah->analogBank7Data = NULL;
296 }
297 if (ah->addac5416_21 != NULL) {
298 kfree(ah->addac5416_21);
299 ah->addac5416_21 = NULL;
300 }
301 if (ah->bank6Temp != NULL) {
302 kfree(ah->bank6Temp);
303 ah->bank6Temp = NULL;
304 }
305} 284}
306 285
307bool ath9k_hw_init_rf(struct ath_hw *ah, int *status) 286bool ath9k_hw_init_rf(struct ath_hw *ah, int *status)
diff --git a/drivers/net/wireless/ath/ath9k/phy.h b/drivers/net/wireless/ath/ath9k/phy.h
index de4fadadbce5..27bd93c6e74d 100644
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -185,6 +185,9 @@ bool ath9k_hw_init_rf(struct ath_hw *ah,
185#define AR_PHY_PLL_CTL_44_2133 0xeb 185#define AR_PHY_PLL_CTL_44_2133 0xeb
186#define AR_PHY_PLL_CTL_40_2133 0xea 186#define AR_PHY_PLL_CTL_40_2133 0xea
187 187
188#define AR_PHY_SPECTRAL_SCAN 0x9912
189#define AR_PHY_SPECTRAL_SCAN_ENABLE 0x1
190
188#define AR_PHY_RX_DELAY 0x9914 191#define AR_PHY_RX_DELAY 0x9914
189#define AR_PHY_SEARCH_START_DELAY 0x9918 192#define AR_PHY_SEARCH_START_DELAY 0x9918
190#define AR_PHY_RX_DELAY_DELAY 0x00003FFF 193#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index a07efa22551e..16a271787b85 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -44,7 +44,7 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
44 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 44 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
45 29300, 0x0c, 0x00, 108, 45 29300, 0x0c, 0x00, 108,
46 4, 7, 7, 7, 7, 0 }, 46 4, 7, 7, 7, 7, 0 },
47 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 47 { VALID_2040, VALID_2040, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
48 6400, 0x80, 0x00, 0, 48 6400, 0x80, 0x00, 0,
49 0, 8, 24, 8, 24, 3216 }, 49 0, 8, 24, 8, 24, 3216 },
50 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 50 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
@@ -463,8 +463,6 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
463 if (!ignore_cw && WLAN_RC_PHY_HT(phy)) 463 if (!ignore_cw && WLAN_RC_PHY_HT(phy))
464 if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG)) 464 if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
465 return 0; 465 return 0;
466 if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
467 return 0;
468 return 1; 466 return 1;
469} 467}
470 468
@@ -1043,9 +1041,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1043 /* Monotonicity is kept only for rates below the current rate. */ 1041 /* Monotonicity is kept only for rates below the current rate. */
1044 if (ath_rc_priv->per[tx_rate] < last_per) { 1042 if (ath_rc_priv->per[tx_rate] < last_per) {
1045 for (rate = tx_rate - 1; rate >= 0; rate--) { 1043 for (rate = tx_rate - 1; rate >= 0; rate--) {
1046 if (rate_table->info[rate].phy !=
1047 rate_table->info[tx_rate].phy)
1048 break;
1049 1044
1050 if (ath_rc_priv->per[rate] > 1045 if (ath_rc_priv->per[rate] >
1051 ath_rc_priv->per[rate+1]) { 1046 ath_rc_priv->per[rate+1]) {
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 8302aeb62e5d..13fd658b5d33 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -744,6 +744,9 @@
744#define AR_SREV_VERSION_9287 0x180 744#define AR_SREV_VERSION_9287 0x180
745#define AR_SREV_REVISION_9287_10 0 745#define AR_SREV_REVISION_9287_10 0
746#define AR_SREV_REVISION_9287_11 1 746#define AR_SREV_REVISION_9287_11 1
747#define AR_SREV_VERSION_9271 0x140
748#define AR_SREV_REVISION_9271_10 0
749#define AR_SREV_REVISION_9271_11 1
747 750
748#define AR_SREV_5416(_ah) \ 751#define AR_SREV_5416(_ah) \
749 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ 752 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -815,6 +818,15 @@
815 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \ 818 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
816 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_11))) 819 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_11)))
817 820
821#define AR_SREV_9271(_ah) \
822 (((_ah))->hw_version.macVersion == AR_SREV_VERSION_9271)
823#define AR_SREV_9271_10(_ah) \
824 (AR_SREV_9271(_ah) && \
825 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_10))
826#define AR_SREV_9271_11(_ah) \
827 (AR_SREV_9271(_ah) && \
828 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9271_11))
829
818#define AR_RADIO_SREV_MAJOR 0xf0 830#define AR_RADIO_SREV_MAJOR 0xf0
819#define AR_RAD5133_SREV_MAJOR 0xc0 831#define AR_RAD5133_SREV_MAJOR 0xc0
820#define AR_RAD2133_SREV_MAJOR 0xd0 832#define AR_RAD2133_SREV_MAJOR 0xd0
@@ -1142,12 +1154,32 @@ enum {
1142#define AR9285_AN_RF2G4_DB2_4 0x00003800 1154#define AR9285_AN_RF2G4_DB2_4 0x00003800
1143#define AR9285_AN_RF2G4_DB2_4_S 11 1155#define AR9285_AN_RF2G4_DB2_4_S 11
1144 1156
1157/* AR9271 : 0x7828, 0x782c different setting from AR9285 */
1158#define AR9271_AN_RF2G3_OB_cck 0x001C0000
1159#define AR9271_AN_RF2G3_OB_cck_S 18
1160#define AR9271_AN_RF2G3_OB_psk 0x00038000
1161#define AR9271_AN_RF2G3_OB_psk_S 15
1162#define AR9271_AN_RF2G3_OB_qam 0x00007000
1163#define AR9271_AN_RF2G3_OB_qam_S 12
1164
1165#define AR9271_AN_RF2G3_DB_1 0x00E00000
1166#define AR9271_AN_RF2G3_DB_1_S 21
1167
1168#define AR9271_AN_RF2G3_CCOMP 0xFFF
1169#define AR9271_AN_RF2G3_CCOMP_S 0
1170
1171#define AR9271_AN_RF2G4_DB_2 0xE0000000
1172#define AR9271_AN_RF2G4_DB_2_S 29
1173
1145#define AR9285_AN_RF2G6 0x7834 1174#define AR9285_AN_RF2G6 0x7834
1146#define AR9285_AN_RF2G6_CCOMP 0x00007800 1175#define AR9285_AN_RF2G6_CCOMP 0x00007800
1147#define AR9285_AN_RF2G6_CCOMP_S 11 1176#define AR9285_AN_RF2G6_CCOMP_S 11
1148#define AR9285_AN_RF2G6_OFFS 0x03f00000 1177#define AR9285_AN_RF2G6_OFFS 0x03f00000
1149#define AR9285_AN_RF2G6_OFFS_S 20 1178#define AR9285_AN_RF2G6_OFFS_S 20
1150 1179
1180#define AR9271_AN_RF2G6_OFFS 0x07f00000
1181#define AR9271_AN_RF2G6_OFFS_S 20
1182
1151#define AR9285_AN_RF2G7 0x7838 1183#define AR9285_AN_RF2G7 0x7838
1152#define AR9285_AN_RF2G7_PWDDB 0x00000002 1184#define AR9285_AN_RF2G7_PWDDB 0x00000002
1153#define AR9285_AN_RF2G7_PWDDB_S 1 1185#define AR9285_AN_RF2G7_PWDDB_S 1
@@ -1208,6 +1240,11 @@ enum {
1208#define AR9287_AN_TOP2_XPABIAS_LVL 0xC0000000 1240#define AR9287_AN_TOP2_XPABIAS_LVL 0xC0000000
1209#define AR9287_AN_TOP2_XPABIAS_LVL_S 30 1241#define AR9287_AN_TOP2_XPABIAS_LVL_S 30
1210 1242
1243/* AR9271 specific stuff */
1244#define AR9271_RESET_POWER_DOWN_CONTROL 0x50044
1245#define AR9271_RADIO_RF_RST 0x20
1246#define AR9271_GATE_MAC_CTL 0x4000
1247
1211#define AR_STA_ID0 0x8000 1248#define AR_STA_ID0 0x8000
1212#define AR_STA_ID1 0x8004 1249#define AR_STA_ID1 0x8004
1213#define AR_STA_ID1_SADH_MASK 0x0000FFFF 1250#define AR_STA_ID1_SADH_MASK 0x0000FFFF
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index e1d419e02b4a..19b88f8177fd 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -351,7 +351,7 @@ void ath9k_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
351 * Drop from tasklet to work to allow mutex for channel 351 * Drop from tasklet to work to allow mutex for channel
352 * change. 352 * change.
353 */ 353 */
354 queue_work(aphy->sc->hw->workqueue, 354 ieee80211_queue_work(aphy->sc->hw,
355 &aphy->sc->chan_work); 355 &aphy->sc->chan_work);
356 } 356 }
357 } 357 }
@@ -367,7 +367,7 @@ static void ath9k_mark_paused(struct ath_wiphy *aphy)
367 struct ath_softc *sc = aphy->sc; 367 struct ath_softc *sc = aphy->sc;
368 aphy->state = ATH_WIPHY_PAUSED; 368 aphy->state = ATH_WIPHY_PAUSED;
369 if (!__ath9k_wiphy_pausing(sc)) 369 if (!__ath9k_wiphy_pausing(sc))
370 queue_work(sc->hw->workqueue, &sc->chan_work); 370 ieee80211_queue_work(sc->hw, &sc->chan_work);
371} 371}
372 372
373static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) 373static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif)
@@ -521,7 +521,7 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
521 spin_unlock_bh(&sc->wiphy_lock); 521 spin_unlock_bh(&sc->wiphy_lock);
522 ath_radio_disable(sc); 522 ath_radio_disable(sc);
523 ath_radio_enable(sc); 523 ath_radio_enable(sc);
524 queue_work(aphy->sc->hw->workqueue, 524 ieee80211_queue_work(aphy->sc->hw,
525 &aphy->sc->chan_work); 525 &aphy->sc->chan_work);
526 return -EBUSY; /* previous select still in progress */ 526 return -EBUSY; /* previous select still in progress */
527 } 527 }
@@ -541,7 +541,7 @@ int ath9k_wiphy_select(struct ath_wiphy *aphy)
541 541
542 if (now) { 542 if (now) {
543 /* Ready to request channel change immediately */ 543 /* Ready to request channel change immediately */
544 queue_work(aphy->sc->hw->workqueue, &aphy->sc->chan_work); 544 ieee80211_queue_work(aphy->sc->hw, &aphy->sc->chan_work);
545 } 545 }
546 546
547 /* 547 /*
@@ -648,8 +648,9 @@ try_again:
648 "change\n"); 648 "change\n");
649 } 649 }
650 650
651 queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, 651 ieee80211_queue_delayed_work(sc->hw,
652 sc->wiphy_scheduler_int); 652 &sc->wiphy_work,
653 sc->wiphy_scheduler_int);
653} 654}
654 655
655void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) 656void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
@@ -657,8 +658,8 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
657 cancel_delayed_work_sync(&sc->wiphy_work); 658 cancel_delayed_work_sync(&sc->wiphy_work);
658 sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int); 659 sc->wiphy_scheduler_int = msecs_to_jiffies(msec_int);
659 if (sc->wiphy_scheduler_int) 660 if (sc->wiphy_scheduler_int)
660 queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, 661 ieee80211_queue_delayed_work(sc->hw, &sc->wiphy_work,
661 sc->wiphy_scheduler_int); 662 sc->wiphy_scheduler_int);
662} 663}
663 664
664/* caller must hold wiphy_lock */ 665/* caller must hold wiphy_lock */
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index b7806e2ca0e1..87762da0383b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -2063,7 +2063,7 @@ static void ath_tx_complete_poll_work(struct work_struct *work)
2063 ath_reset(sc, false); 2063 ath_reset(sc, false);
2064 } 2064 }
2065 2065
2066 queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work, 2066 ieee80211_queue_delayed_work(sc->hw, &sc->tx_complete_work,
2067 msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT)); 2067 msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT));
2068} 2068}
2069 2069
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 40448067e4cc..b6811cff18ba 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -142,6 +142,17 @@
142#define B43_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */ 142#define B43_BFL_BTCMOD 0x4000 /* BFL_BTCOEXIST is given in alternate GPIOs */
143#define B43_BFL_ALTIQ 0x8000 /* alternate I/Q settings */ 143#define B43_BFL_ALTIQ 0x8000 /* alternate I/Q settings */
144 144
145/* SPROM boardflags_hi values */
146#define B43_BFH_NOPA 0x0001 /* has no PA */
147#define B43_BFH_RSSIINV 0x0002 /* RSSI uses positive slope (not TSSI) */
148#define B43_BFH_PAREF 0x0004 /* uses the PARef LDO */
149#define B43_BFH_3TSWITCH 0x0008 /* uses a triple throw switch shared
150 * with bluetooth */
151#define B43_BFH_PHASESHIFT 0x0010 /* can support phase shifter */
152#define B43_BFH_BUCKBOOST 0x0020 /* has buck/booster */
153#define B43_BFH_FEM_BT 0x0040 /* has FEM and switch to share antenna
154 * with bluetooth */
155
145/* GPIO register offset, in both ChipCommon and PCI core. */ 156/* GPIO register offset, in both ChipCommon and PCI core. */
146#define B43_GPIO_CONTROL 0x6c 157#define B43_GPIO_CONTROL 0x6c
147 158
diff --git a/drivers/net/wireless/b43/dma.c b/drivers/net/wireless/b43/dma.c
index 7964cc32b258..41a0e9c2b339 100644
--- a/drivers/net/wireless/b43/dma.c
+++ b/drivers/net/wireless/b43/dma.c
@@ -1334,13 +1334,22 @@ int b43_dma_tx(struct b43_wldev *dev, struct sk_buff *skb)
1334 spin_lock_irqsave(&ring->lock, flags); 1334 spin_lock_irqsave(&ring->lock, flags);
1335 1335
1336 B43_WARN_ON(!ring->tx); 1336 B43_WARN_ON(!ring->tx);
1337 /* Check if the queue was stopped in mac80211,
1338 * but we got called nevertheless.
1339 * That would be a mac80211 bug. */
1340 B43_WARN_ON(ring->stopped);
1341 1337
1342 if (unlikely(free_slots(ring) < TX_SLOTS_PER_FRAME)) { 1338 if (unlikely(ring->stopped)) {
1343 b43warn(dev->wl, "DMA queue overflow\n"); 1339 /* We get here only because of a bug in mac80211.
1340 * Because of a race, one packet may be queued after
1341 * the queue is stopped, thus we got called when we shouldn't.
1342 * For now, just refuse the transmit. */
1343 if (b43_debug(dev, B43_DBG_DMAVERBOSE))
1344 b43err(dev->wl, "Packet after queue stopped\n");
1345 err = -ENOSPC;
1346 goto out_unlock;
1347 }
1348
1349 if (unlikely(WARN_ON(free_slots(ring) < TX_SLOTS_PER_FRAME))) {
1350 /* If we get here, we have a real error with the queue
1351 * full, but queues not stopped. */
1352 b43err(dev->wl, "DMA queue overflow\n");
1344 err = -ENOSPC; 1353 err = -ENOSPC;
1345 goto out_unlock; 1354 goto out_unlock;
1346 } 1355 }
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 3f4360ad0e4e..925f346ea361 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -395,9 +395,8 @@ u32 __b43_shm_read32(struct b43_wldev *dev, u16 routing, u16 offset)
395 /* Unaligned access */ 395 /* Unaligned access */
396 b43_shm_control_word(dev, routing, offset >> 2); 396 b43_shm_control_word(dev, routing, offset >> 2);
397 ret = b43_read16(dev, B43_MMIO_SHM_DATA_UNALIGNED); 397 ret = b43_read16(dev, B43_MMIO_SHM_DATA_UNALIGNED);
398 ret <<= 16;
399 b43_shm_control_word(dev, routing, (offset >> 2) + 1); 398 b43_shm_control_word(dev, routing, (offset >> 2) + 1);
400 ret |= b43_read16(dev, B43_MMIO_SHM_DATA); 399 ret |= ((u32)b43_read16(dev, B43_MMIO_SHM_DATA)) << 16;
401 400
402 goto out; 401 goto out;
403 } 402 }
@@ -464,9 +463,10 @@ void __b43_shm_write32(struct b43_wldev *dev, u16 routing, u16 offset, u32 value
464 /* Unaligned access */ 463 /* Unaligned access */
465 b43_shm_control_word(dev, routing, offset >> 2); 464 b43_shm_control_word(dev, routing, offset >> 2);
466 b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED, 465 b43_write16(dev, B43_MMIO_SHM_DATA_UNALIGNED,
467 (value >> 16) & 0xffff); 466 value & 0xFFFF);
468 b43_shm_control_word(dev, routing, (offset >> 2) + 1); 467 b43_shm_control_word(dev, routing, (offset >> 2) + 1);
469 b43_write16(dev, B43_MMIO_SHM_DATA, value & 0xffff); 468 b43_write16(dev, B43_MMIO_SHM_DATA,
469 (value >> 16) & 0xFFFF);
470 return; 470 return;
471 } 471 }
472 offset >>= 2; 472 offset >>= 2;
@@ -1524,10 +1524,13 @@ static void b43_write_probe_resp_template(struct b43_wldev *dev,
1524 /* Looks like PLCP headers plus packet timings are stored for 1524 /* Looks like PLCP headers plus packet timings are stored for
1525 * all possible basic rates 1525 * all possible basic rates
1526 */ 1526 */
1527 /* FIXME this is the wrong offset : it goes in tkip rx phase1 shm */
1528#if 0
1527 b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]); 1529 b43_write_probe_resp_plcp(dev, 0x31A, size, &b43_b_ratetable[0]);
1528 b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]); 1530 b43_write_probe_resp_plcp(dev, 0x32C, size, &b43_b_ratetable[1]);
1529 b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]); 1531 b43_write_probe_resp_plcp(dev, 0x33E, size, &b43_b_ratetable[2]);
1530 b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]); 1532 b43_write_probe_resp_plcp(dev, 0x350, size, &b43_b_ratetable[3]);
1533#endif
1531 1534
1532 size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6)); 1535 size = min((size_t) size, 0x200 - sizeof(struct b43_plcp_hdr6));
1533 b43_write_template_common(dev, probe_resp_data, 1536 b43_write_template_common(dev, probe_resp_data,
@@ -1654,7 +1657,7 @@ static void b43_update_templates(struct b43_wl *wl)
1654 wl->current_beacon = beacon; 1657 wl->current_beacon = beacon;
1655 wl->beacon0_uploaded = 0; 1658 wl->beacon0_uploaded = 0;
1656 wl->beacon1_uploaded = 0; 1659 wl->beacon1_uploaded = 0;
1657 queue_work(wl->hw->workqueue, &wl->beacon_update_trigger); 1660 ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
1658} 1661}
1659 1662
1660static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) 1663static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int)
@@ -2914,7 +2917,7 @@ out_requeue:
2914 delay = msecs_to_jiffies(50); 2917 delay = msecs_to_jiffies(50);
2915 else 2918 else
2916 delay = round_jiffies_relative(HZ * 15); 2919 delay = round_jiffies_relative(HZ * 15);
2917 queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay); 2920 ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay);
2918out: 2921out:
2919 mutex_unlock(&wl->mutex); 2922 mutex_unlock(&wl->mutex);
2920} 2923}
@@ -2925,15 +2928,16 @@ static void b43_periodic_tasks_setup(struct b43_wldev *dev)
2925 2928
2926 dev->periodic_state = 0; 2929 dev->periodic_state = 0;
2927 INIT_DELAYED_WORK(work, b43_periodic_work_handler); 2930 INIT_DELAYED_WORK(work, b43_periodic_work_handler);
2928 queue_delayed_work(dev->wl->hw->workqueue, work, 0); 2931 ieee80211_queue_delayed_work(dev->wl->hw, work, 0);
2929} 2932}
2930 2933
2931/* Check if communication with the device works correctly. */ 2934/* Check if communication with the device works correctly. */
2932static int b43_validate_chipaccess(struct b43_wldev *dev) 2935static int b43_validate_chipaccess(struct b43_wldev *dev)
2933{ 2936{
2934 u32 v, backup; 2937 u32 v, backup0, backup4;
2935 2938
2936 backup = b43_shm_read32(dev, B43_SHM_SHARED, 0); 2939 backup0 = b43_shm_read32(dev, B43_SHM_SHARED, 0);
2940 backup4 = b43_shm_read32(dev, B43_SHM_SHARED, 4);
2937 2941
2938 /* Check for read/write and endianness problems. */ 2942 /* Check for read/write and endianness problems. */
2939 b43_shm_write32(dev, B43_SHM_SHARED, 0, 0x55AAAA55); 2943 b43_shm_write32(dev, B43_SHM_SHARED, 0, 0x55AAAA55);
@@ -2943,7 +2947,23 @@ static int b43_validate_chipaccess(struct b43_wldev *dev)
2943 if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0xAA5555AA) 2947 if (b43_shm_read32(dev, B43_SHM_SHARED, 0) != 0xAA5555AA)
2944 goto error; 2948 goto error;
2945 2949
2946 b43_shm_write32(dev, B43_SHM_SHARED, 0, backup); 2950 /* Check if unaligned 32bit SHM_SHARED access works properly.
2951 * However, don't bail out on failure, because it's noncritical. */
2952 b43_shm_write16(dev, B43_SHM_SHARED, 0, 0x1122);
2953 b43_shm_write16(dev, B43_SHM_SHARED, 2, 0x3344);
2954 b43_shm_write16(dev, B43_SHM_SHARED, 4, 0x5566);
2955 b43_shm_write16(dev, B43_SHM_SHARED, 6, 0x7788);
2956 if (b43_shm_read32(dev, B43_SHM_SHARED, 2) != 0x55663344)
2957 b43warn(dev->wl, "Unaligned 32bit SHM read access is broken\n");
2958 b43_shm_write32(dev, B43_SHM_SHARED, 2, 0xAABBCCDD);
2959 if (b43_shm_read16(dev, B43_SHM_SHARED, 0) != 0x1122 ||
2960 b43_shm_read16(dev, B43_SHM_SHARED, 2) != 0xCCDD ||
2961 b43_shm_read16(dev, B43_SHM_SHARED, 4) != 0xAABB ||
2962 b43_shm_read16(dev, B43_SHM_SHARED, 6) != 0x7788)
2963 b43warn(dev->wl, "Unaligned 32bit SHM write access is broken\n");
2964
2965 b43_shm_write32(dev, B43_SHM_SHARED, 0, backup0);
2966 b43_shm_write32(dev, B43_SHM_SHARED, 4, backup4);
2947 2967
2948 if ((dev->dev->id.revision >= 3) && (dev->dev->id.revision <= 10)) { 2968 if ((dev->dev->id.revision >= 3) && (dev->dev->id.revision <= 10)) {
2949 /* The 32bit register shadows the two 16bit registers 2969 /* The 32bit register shadows the two 16bit registers
@@ -4871,7 +4891,7 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason)
4871 if (b43_status(dev) < B43_STAT_INITIALIZED) 4891 if (b43_status(dev) < B43_STAT_INITIALIZED)
4872 return; 4892 return;
4873 b43info(dev->wl, "Controller RESET (%s) ...\n", reason); 4893 b43info(dev->wl, "Controller RESET (%s) ...\n", reason);
4874 queue_work(dev->wl->hw->workqueue, &dev->restart_work); 4894 ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
4875} 4895}
4876 4896
4877#ifdef CONFIG_PM 4897#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index 6d241622210e..51686ec96984 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -240,6 +240,13 @@ void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value)
240 dev->phy.ops->phy_write(dev, reg, value); 240 dev->phy.ops->phy_write(dev, reg, value);
241} 241}
242 242
243void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
244{
245 assert_mac_suspended(dev);
246 dev->phy.ops->phy_write(dev, destreg,
247 dev->phy.ops->phy_read(dev, srcreg));
248}
249
243void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask) 250void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)
244{ 251{
245 b43_phy_write(dev, offset, 252 b43_phy_write(dev, offset,
@@ -352,7 +359,7 @@ void b43_phy_txpower_check(struct b43_wldev *dev, unsigned int flags)
352 359
353 /* We must adjust the transmission power in hardware. 360 /* We must adjust the transmission power in hardware.
354 * Schedule b43_phy_txpower_adjust_work(). */ 361 * Schedule b43_phy_txpower_adjust_work(). */
355 queue_work(dev->wl->hw->workqueue, &dev->wl->txpower_adjust_work); 362 ieee80211_queue_work(dev->wl->hw, &dev->wl->txpower_adjust_work);
356} 363}
357 364
358int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset) 365int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset)
diff --git a/drivers/net/wireless/b43/phy_common.h b/drivers/net/wireless/b43/phy_common.h
index 44cc918e4fc6..9f9f23cab72a 100644
--- a/drivers/net/wireless/b43/phy_common.h
+++ b/drivers/net/wireless/b43/phy_common.h
@@ -291,6 +291,11 @@ u16 b43_phy_read(struct b43_wldev *dev, u16 reg);
291void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value); 291void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value);
292 292
293/** 293/**
294 * b43_phy_copy - copy contents of 16bit PHY register to another
295 */
296void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg);
297
298/**
294 * b43_phy_mask - Mask a PHY register with a mask 299 * b43_phy_mask - Mask a PHY register with a mask
295 */ 300 */
296void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask); 301void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask);
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index ea0d3a3a6a64..aa1486a1354b 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -66,7 +66,99 @@ static void lpphy_table_init(struct b43_wldev *dev)
66 66
67static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) 67static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev)
68{ 68{
69 B43_WARN_ON(1);//TODO rev < 2 not supported, yet. 69 struct ssb_bus *bus = dev->dev->bus;
70 u16 tmp, tmp2;
71
72 if (dev->phy.rev == 1 &&
73 (bus->sprom.boardflags_hi & B43_BFH_FEM_BT)) {
74 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A);
75 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0x3F00, 0x0900);
76 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A);
77 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xC0FF, 0x0B00);
78 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xFFC0, 0x000A);
79 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xC0FF, 0x0400);
80 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x000A);
81 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0B00);
82 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_5, 0xFFC0, 0x000A);
83 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_5, 0xC0FF, 0x0900);
84 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_6, 0xFFC0, 0x000A);
85 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_6, 0xC0FF, 0x0B00);
86 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_7, 0xFFC0, 0x000A);
87 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_7, 0xC0FF, 0x0900);
88 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xFFC0, 0x000A);
89 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_8, 0xC0FF, 0x0B00);
90 } else if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ ||
91 (bus->boardinfo.type == 0x048A) || ((dev->phy.rev == 0) &&
92 (bus->sprom.boardflags_lo & B43_BFL_FEM))) {
93 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0001);
94 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0400);
95 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0001);
96 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xC0FF, 0x0500);
97 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xFFC0, 0x0002);
98 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xC0FF, 0x0800);
99 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002);
100 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0A00);
101 } else if (dev->phy.rev == 1 ||
102 (bus->sprom.boardflags_lo & B43_BFL_FEM)) {
103 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x0004);
104 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0800);
105 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x0004);
106 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xC0FF, 0x0C00);
107 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xFFC0, 0x0002);
108 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xC0FF, 0x0100);
109 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0002);
110 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0300);
111 } else {
112 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xFFC0, 0x000A);
113 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_1, 0xC0FF, 0x0900);
114 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xFFC0, 0x000A);
115 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_2, 0xC0FF, 0x0B00);
116 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xFFC0, 0x0006);
117 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_3, 0xC0FF, 0x0500);
118 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xFFC0, 0x0006);
119 b43_phy_maskset(dev, B43_LPPHY_TR_LOOKUP_4, 0xC0FF, 0x0700);
120 }
121 if (dev->phy.rev == 1) {
122 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_5, B43_LPPHY_TR_LOOKUP_1);
123 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_6, B43_LPPHY_TR_LOOKUP_2);
124 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_7, B43_LPPHY_TR_LOOKUP_3);
125 b43_phy_copy(dev, B43_LPPHY_TR_LOOKUP_8, B43_LPPHY_TR_LOOKUP_4);
126 }
127 if ((bus->sprom.boardflags_hi & B43_BFH_FEM_BT) &&
128 (bus->chip_id == 0x5354) &&
129 (bus->chip_package == SSB_CHIPPACK_BCM4712S)) {
130 b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0006);
131 b43_phy_write(dev, B43_LPPHY_GPIO_SELECT, 0x0005);
132 b43_phy_write(dev, B43_LPPHY_GPIO_OUTEN, 0xFFFF);
133 b43_hf_write(dev, b43_hf_read(dev) | 0x0800ULL << 32);
134 }
135 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
136 b43_phy_set(dev, B43_LPPHY_LP_PHY_CTL, 0x8000);
137 b43_phy_set(dev, B43_LPPHY_CRSGAIN_CTL, 0x0040);
138 b43_phy_maskset(dev, B43_LPPHY_MINPWR_LEVEL, 0x00FF, 0xA400);
139 b43_phy_maskset(dev, B43_LPPHY_CRSGAIN_CTL, 0xF0FF, 0x0B00);
140 b43_phy_maskset(dev, B43_LPPHY_SYNCPEAKCNT, 0xFFF8, 0x0007);
141 b43_phy_maskset(dev, B43_LPPHY_DSSS_CONFIRM_CNT, 0xFFF8, 0x0003);
142 b43_phy_maskset(dev, B43_LPPHY_DSSS_CONFIRM_CNT, 0xFFC7, 0x0020);
143 b43_phy_mask(dev, B43_LPPHY_IDLEAFTERPKTRXTO, 0x00FF);
144 } else { /* 5GHz */
145 b43_phy_mask(dev, B43_LPPHY_LP_PHY_CTL, 0x7FFF);
146 b43_phy_mask(dev, B43_LPPHY_CRSGAIN_CTL, 0xFFBF);
147 }
148 if (dev->phy.rev == 1) {
149 tmp = b43_phy_read(dev, B43_LPPHY_CLIPCTRTHRESH);
150 tmp2 = (tmp & 0x03E0) >> 5;
151 tmp2 |= tmp << 5;
152 b43_phy_write(dev, B43_LPPHY_4C3, tmp2);
153 tmp = b43_phy_read(dev, B43_LPPHY_OFDMSYNCTHRESH0);
154 tmp2 = (tmp & 0x1F00) >> 8;
155 tmp2 |= tmp << 5;
156 b43_phy_write(dev, B43_LPPHY_4C4, tmp2);
157 tmp = b43_phy_read(dev, B43_LPPHY_VERYLOWGAINDB);
158 tmp2 = tmp & 0x00FF;
159 tmp2 |= tmp << 8;
160 b43_phy_write(dev, B43_LPPHY_4C5, tmp2);
161 }
70} 162}
71 163
72static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) 164static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev)
diff --git a/drivers/net/wireless/b43/phy_lp.h b/drivers/net/wireless/b43/phy_lp.h
index 18370b4ac38e..829b2bba3ee1 100644
--- a/drivers/net/wireless/b43/phy_lp.h
+++ b/drivers/net/wireless/b43/phy_lp.h
@@ -273,12 +273,19 @@
273#define B43_LPPHY_AFE_DDFS_POINTER_INIT B43_PHY_OFDM(0xB8) /* AFE DDFS pointer init */ 273#define B43_LPPHY_AFE_DDFS_POINTER_INIT B43_PHY_OFDM(0xB8) /* AFE DDFS pointer init */
274#define B43_LPPHY_AFE_DDFS_INCR_INIT B43_PHY_OFDM(0xB9) /* AFE DDFS incr init */ 274#define B43_LPPHY_AFE_DDFS_INCR_INIT B43_PHY_OFDM(0xB9) /* AFE DDFS incr init */
275#define B43_LPPHY_MRCNOISEREDUCTION B43_PHY_OFDM(0xBA) /* mrcNoiseReduction */ 275#define B43_LPPHY_MRCNOISEREDUCTION B43_PHY_OFDM(0xBA) /* mrcNoiseReduction */
276#define B43_LPPHY_TRLOOKUP3 B43_PHY_OFDM(0xBB) /* TRLookup3 */ 276#define B43_LPPHY_TR_LOOKUP_3 B43_PHY_OFDM(0xBB) /* TR Lookup 3 */
277#define B43_LPPHY_TRLOOKUP4 B43_PHY_OFDM(0xBC) /* TRLookup4 */ 277#define B43_LPPHY_TR_LOOKUP_4 B43_PHY_OFDM(0xBC) /* TR Lookup 4 */
278#define B43_LPPHY_RADAR_FIFO_STAT B43_PHY_OFDM(0xBD) /* Radar FIFO Status */ 278#define B43_LPPHY_RADAR_FIFO_STAT B43_PHY_OFDM(0xBD) /* Radar FIFO Status */
279#define B43_LPPHY_GPIO_OUTEN B43_PHY_OFDM(0xBE) /* GPIO Out enable */ 279#define B43_LPPHY_GPIO_OUTEN B43_PHY_OFDM(0xBE) /* GPIO Out enable */
280#define B43_LPPHY_GPIO_SELECT B43_PHY_OFDM(0xBF) /* GPIO Select */ 280#define B43_LPPHY_GPIO_SELECT B43_PHY_OFDM(0xBF) /* GPIO Select */
281#define B43_LPPHY_GPIO_OUT B43_PHY_OFDM(0xC0) /* GPIO Out */ 281#define B43_LPPHY_GPIO_OUT B43_PHY_OFDM(0xC0) /* GPIO Out */
282#define B43_LPPHY_4C3 B43_PHY_OFDM(0xC3) /* unknown, used during BB init */
283#define B43_LPPHY_4C4 B43_PHY_OFDM(0xC4) /* unknown, used during BB init */
284#define B43_LPPHY_4C5 B43_PHY_OFDM(0xC5) /* unknown, used during BB init */
285#define B43_LPPHY_TR_LOOKUP_5 B43_PHY_OFDM(0xC7) /* TR Lookup 5 */
286#define B43_LPPHY_TR_LOOKUP_6 B43_PHY_OFDM(0xC8) /* TR Lookup 6 */
287#define B43_LPPHY_TR_LOOKUP_7 B43_PHY_OFDM(0xC9) /* TR Lookup 7 */
288#define B43_LPPHY_TR_LOOKUP_8 B43_PHY_OFDM(0xCA) /* TR Lookup 8 */
282 289
283 290
284 291
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index be7b5604947b..992318a78077 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -137,7 +137,8 @@ static void b43_radio_init2055_post(struct b43_wldev *dev)
137 137
138 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3); 138 b43_radio_mask(dev, B2055_MASTER1, 0xFFF3);
139 msleep(1); 139 msleep(1);
140 if ((sprom->revision != 4) || !(sprom->boardflags_hi & 0x0002)) { 140 if ((sprom->revision != 4) ||
141 !(sprom->boardflags_hi & B43_BFH_RSSIINV)) {
141 if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) || 142 if ((binfo->vendor != PCI_VENDOR_ID_BROADCOM) ||
142 (binfo->type != 0x46D) || 143 (binfo->type != 0x46D) ||
143 (binfo->rev < 0x41)) { 144 (binfo->rev < 0x41)) {
diff --git a/drivers/net/wireless/b43/pio.c b/drivers/net/wireless/b43/pio.c
index 69138e8c1db6..73c047d8de40 100644
--- a/drivers/net/wireless/b43/pio.c
+++ b/drivers/net/wireless/b43/pio.c
@@ -783,7 +783,7 @@ void b43_pio_rx(struct b43_pio_rxqueue *q)
783{ 783{
784 /* Due to latency issues we must run the RX path in 784 /* Due to latency issues we must run the RX path in
785 * a workqueue to be able to schedule between packets. */ 785 * a workqueue to be able to schedule between packets. */
786 queue_work(q->dev->wl->hw->workqueue, &q->rx_work); 786 ieee80211_queue_work(q->dev->wl->hw, &q->rx_work);
787} 787}
788 788
789static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q) 789static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q)
diff --git a/drivers/net/wireless/b43legacy/dma.c b/drivers/net/wireless/b43legacy/dma.c
index 2f90fb9f5367..866403415811 100644
--- a/drivers/net/wireless/b43legacy/dma.c
+++ b/drivers/net/wireless/b43legacy/dma.c
@@ -1366,15 +1366,25 @@ int b43legacy_dma_tx(struct b43legacy_wldev *dev,
1366 ring = priority_to_txring(dev, skb_get_queue_mapping(skb)); 1366 ring = priority_to_txring(dev, skb_get_queue_mapping(skb));
1367 spin_lock_irqsave(&ring->lock, flags); 1367 spin_lock_irqsave(&ring->lock, flags);
1368 B43legacy_WARN_ON(!ring->tx); 1368 B43legacy_WARN_ON(!ring->tx);
1369 if (unlikely(free_slots(ring) < SLOTS_PER_PACKET)) { 1369
1370 b43legacywarn(dev->wl, "DMA queue overflow\n"); 1370 if (unlikely(ring->stopped)) {
1371 /* We get here only because of a bug in mac80211.
1372 * Because of a race, one packet may be queued after
1373 * the queue is stopped, thus we got called when we shouldn't.
1374 * For now, just refuse the transmit. */
1375 if (b43legacy_debug(dev, B43legacy_DBG_DMAVERBOSE))
1376 b43legacyerr(dev->wl, "Packet after queue stopped\n");
1377 err = -ENOSPC;
1378 goto out_unlock;
1379 }
1380
1381 if (unlikely(WARN_ON(free_slots(ring) < SLOTS_PER_PACKET))) {
1382 /* If we get here, we have a real error with the queue
1383 * full, but queues not stopped. */
1384 b43legacyerr(dev->wl, "DMA queue overflow\n");
1371 err = -ENOSPC; 1385 err = -ENOSPC;
1372 goto out_unlock; 1386 goto out_unlock;
1373 } 1387 }
1374 /* Check if the queue was stopped in mac80211,
1375 * but we got called nevertheless.
1376 * That would be a mac80211 bug. */
1377 B43legacy_BUG_ON(ring->stopped);
1378 1388
1379 err = dma_tx_fragment(ring, skb); 1389 err = dma_tx_fragment(ring, skb);
1380 if (unlikely(err == -ENOKEY)) { 1390 if (unlikely(err == -ENOKEY)) {
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index c4973c1942bf..b1435594921a 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1252,7 +1252,7 @@ static void b43legacy_update_templates(struct b43legacy_wl *wl)
1252 wl->current_beacon = beacon; 1252 wl->current_beacon = beacon;
1253 wl->beacon0_uploaded = 0; 1253 wl->beacon0_uploaded = 0;
1254 wl->beacon1_uploaded = 0; 1254 wl->beacon1_uploaded = 0;
1255 queue_work(wl->hw->workqueue, &wl->beacon_update_trigger); 1255 ieee80211_queue_work(wl->hw, &wl->beacon_update_trigger);
1256} 1256}
1257 1257
1258static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, 1258static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev,
@@ -2300,7 +2300,7 @@ out_requeue:
2300 delay = msecs_to_jiffies(50); 2300 delay = msecs_to_jiffies(50);
2301 else 2301 else
2302 delay = round_jiffies_relative(HZ * 15); 2302 delay = round_jiffies_relative(HZ * 15);
2303 queue_delayed_work(wl->hw->workqueue, &dev->periodic_work, delay); 2303 ieee80211_queue_delayed_work(wl->hw, &dev->periodic_work, delay);
2304out: 2304out:
2305 mutex_unlock(&wl->mutex); 2305 mutex_unlock(&wl->mutex);
2306} 2306}
@@ -2311,7 +2311,7 @@ static void b43legacy_periodic_tasks_setup(struct b43legacy_wldev *dev)
2311 2311
2312 dev->periodic_state = 0; 2312 dev->periodic_state = 0;
2313 INIT_DELAYED_WORK(work, b43legacy_periodic_work_handler); 2313 INIT_DELAYED_WORK(work, b43legacy_periodic_work_handler);
2314 queue_delayed_work(dev->wl->hw->workqueue, work, 0); 2314 ieee80211_queue_delayed_work(dev->wl->hw, work, 0);
2315} 2315}
2316 2316
2317/* Validate access to the chip (SHM) */ 2317/* Validate access to the chip (SHM) */
@@ -3885,7 +3885,7 @@ void b43legacy_controller_restart(struct b43legacy_wldev *dev,
3885 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED) 3885 if (b43legacy_status(dev) < B43legacy_STAT_INITIALIZED)
3886 return; 3886 return;
3887 b43legacyinfo(dev->wl, "Controller RESET (%s) ...\n", reason); 3887 b43legacyinfo(dev->wl, "Controller RESET (%s) ...\n", reason);
3888 queue_work(dev->wl->hw->workqueue, &dev->restart_work); 3888 ieee80211_queue_work(dev->wl->hw, &dev->restart_work);
3889} 3889}
3890 3890
3891#ifdef CONFIG_PM 3891#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 5f7c52053c18..cf3fbc6b98ef 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -73,6 +73,18 @@ static void iwl1000_set_ct_threshold(struct iwl_priv *priv)
73 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; 73 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
74} 74}
75 75
76/* NIC configuration for 1000 series */
77static void iwl1000_nic_config(struct iwl_priv *priv)
78{
79 iwl5000_nic_config(priv);
80
81 /* Setting digital SVR for 1000 card to 1.32V */
82 /* locking is acquired in iwl_set_bits_mask_prph() function */
83 iwl_set_bits_mask_prph(priv, APMG_DIGITAL_SVR_REG,
84 APMG_SVR_DIGITAL_VOLTAGE_1_32,
85 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
86}
87
76static struct iwl_lib_ops iwl1000_lib = { 88static struct iwl_lib_ops iwl1000_lib = {
77 .set_hw_params = iwl5000_hw_set_hw_params, 89 .set_hw_params = iwl5000_hw_set_hw_params,
78 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 90 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
@@ -95,7 +107,7 @@ static struct iwl_lib_ops iwl1000_lib = {
95 .init = iwl5000_apm_init, 107 .init = iwl5000_apm_init,
96 .reset = iwl5000_apm_reset, 108 .reset = iwl5000_apm_reset,
97 .stop = iwl5000_apm_stop, 109 .stop = iwl5000_apm_stop,
98 .config = iwl5000_nic_config, 110 .config = iwl1000_nic_config,
99 .set_pwr_src = iwl_set_pwr_src, 111 .set_pwr_src = iwl_set_pwr_src,
100 }, 112 },
101 .eeprom_ops = { 113 .eeprom_ops = {
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index ddd64fef3039..87957c052839 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -198,6 +198,7 @@ out:
198} 198}
199 199
200 200
201/* NIC configuration for 5000 series and up */
201void iwl5000_nic_config(struct iwl_priv *priv) 202void iwl5000_nic_config(struct iwl_priv *priv)
202{ 203{
203 unsigned long flags; 204 unsigned long flags;
@@ -239,18 +240,11 @@ void iwl5000_nic_config(struct iwl_priv *priv)
239 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, 240 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS,
240 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS); 241 ~APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS);
241 242
242 if ((priv->hw_rev & CSR_HW_REV_TYPE_MSK) == CSR_HW_REV_TYPE_1000) {
243 /* Setting digital SVR for 1000 card to 1.32V */
244 iwl_set_bits_mask_prph(priv, APMG_DIGITAL_SVR_REG,
245 APMG_SVR_DIGITAL_VOLTAGE_1_32,
246 ~APMG_SVR_VOLTAGE_CONFIG_BIT_MSK);
247 }
248 243
249 spin_unlock_irqrestore(&priv->lock, flags); 244 spin_unlock_irqrestore(&priv->lock, flags);
250} 245}
251 246
252 247
253
254/* 248/*
255 * EEPROM 249 * EEPROM
256 */ 250 */
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index 59ff73536f3a..4450943d3dac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -68,6 +68,24 @@ static void iwl6000_set_ct_threshold(struct iwl_priv *priv)
68 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD; 68 priv->hw_params.ct_kill_exit_threshold = CT_KILL_EXIT_THRESHOLD;
69} 69}
70 70
71/* NIC configuration for 6000 series */
72static void iwl6000_nic_config(struct iwl_priv *priv)
73{
74 iwl5000_nic_config(priv);
75
76 /* no locking required for register write */
77 if (priv->cfg->pa_type == IWL_PA_HYBRID) {
78 /* 2x2 hybrid phy type */
79 iwl_write32(priv, CSR_GP_DRIVER_REG,
80 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB);
81 } else if (priv->cfg->pa_type == IWL_PA_INTERNAL) {
82 /* 2x2 IPA phy type */
83 iwl_write32(priv, CSR_GP_DRIVER_REG,
84 CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA);
85 }
86 /* else do nothing, uCode configured */
87}
88
71static struct iwl_lib_ops iwl6000_lib = { 89static struct iwl_lib_ops iwl6000_lib = {
72 .set_hw_params = iwl5000_hw_set_hw_params, 90 .set_hw_params = iwl5000_hw_set_hw_params,
73 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 91 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
@@ -90,7 +108,7 @@ static struct iwl_lib_ops iwl6000_lib = {
90 .init = iwl5000_apm_init, 108 .init = iwl5000_apm_init,
91 .reset = iwl5000_apm_reset, 109 .reset = iwl5000_apm_reset,
92 .stop = iwl5000_apm_stop, 110 .stop = iwl5000_apm_stop,
93 .config = iwl5000_nic_config, 111 .config = iwl6000_nic_config,
94 .set_pwr_src = iwl_set_pwr_src, 112 .set_pwr_src = iwl_set_pwr_src,
95 }, 113 },
96 .eeprom_ops = { 114 .eeprom_ops = {
@@ -132,23 +150,31 @@ static struct iwl_ops iwl6000_ops = {
132 .utils = &iwl6000_hcmd_utils, 150 .utils = &iwl6000_hcmd_utils,
133}; 151};
134 152
135struct iwl_cfg iwl6000_2ag_cfg = { 153
136 .name = "6000 Series 2x2 AG", 154/*
155 * "h": Hybrid configuration, use both internal and external Power Amplifier
156 */
157struct iwl_cfg iwl6000h_2agn_cfg = {
158 .name = "6000 Series 2x2 AGN",
137 .fw_name_pre = IWL6000_FW_PRE, 159 .fw_name_pre = IWL6000_FW_PRE,
138 .ucode_api_max = IWL6000_UCODE_API_MAX, 160 .ucode_api_max = IWL6000_UCODE_API_MAX,
139 .ucode_api_min = IWL6000_UCODE_API_MIN, 161 .ucode_api_min = IWL6000_UCODE_API_MIN,
140 .sku = IWL_SKU_A|IWL_SKU_G, 162 .sku = IWL_SKU_A|IWL_SKU_G|IWL_SKU_N,
141 .ops = &iwl6000_ops, 163 .ops = &iwl6000_ops,
142 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE, 164 .eeprom_size = IWL_5000_EEPROM_IMG_SIZE,
143 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 165 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
144 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 166 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
145 .mod_params = &iwl50_mod_params, 167 .mod_params = &iwl50_mod_params,
146 .valid_tx_ant = ANT_BC, 168 .valid_tx_ant = ANT_AB,
147 .valid_rx_ant = ANT_BC, 169 .valid_rx_ant = ANT_AB,
148 .need_pll_cfg = false, 170 .need_pll_cfg = false,
171 .pa_type = IWL_PA_HYBRID,
149}; 172};
150 173
151struct iwl_cfg iwl6000_2agn_cfg = { 174/*
175 * "i": Internal configuration, use internal Power Amplifier
176 */
177struct iwl_cfg iwl6000i_2agn_cfg = {
152 .name = "6000 Series 2x2 AGN", 178 .name = "6000 Series 2x2 AGN",
153 .fw_name_pre = IWL6000_FW_PRE, 179 .fw_name_pre = IWL6000_FW_PRE,
154 .ucode_api_max = IWL6000_UCODE_API_MAX, 180 .ucode_api_max = IWL6000_UCODE_API_MAX,
@@ -159,9 +185,10 @@ struct iwl_cfg iwl6000_2agn_cfg = {
159 .eeprom_ver = EEPROM_5000_EEPROM_VERSION, 185 .eeprom_ver = EEPROM_5000_EEPROM_VERSION,
160 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION, 186 .eeprom_calib_ver = EEPROM_5000_TX_POWER_VERSION,
161 .mod_params = &iwl50_mod_params, 187 .mod_params = &iwl50_mod_params,
162 .valid_tx_ant = ANT_AB, 188 .valid_tx_ant = ANT_BC,
163 .valid_rx_ant = ANT_AB, 189 .valid_rx_ant = ANT_BC,
164 .need_pll_cfg = false, 190 .need_pll_cfg = false,
191 .pa_type = IWL_PA_INTERNAL,
165}; 192};
166 193
167struct iwl_cfg iwl6050_2agn_cfg = { 194struct iwl_cfg iwl6050_2agn_cfg = {
@@ -178,6 +205,7 @@ struct iwl_cfg iwl6050_2agn_cfg = {
178 .valid_tx_ant = ANT_AB, 205 .valid_tx_ant = ANT_AB,
179 .valid_rx_ant = ANT_AB, 206 .valid_rx_ant = ANT_AB,
180 .need_pll_cfg = false, 207 .need_pll_cfg = false,
208 .pa_type = IWL_PA_SYSTEM,
181}; 209};
182 210
183struct iwl_cfg iwl6000_3agn_cfg = { 211struct iwl_cfg iwl6000_3agn_cfg = {
@@ -194,6 +222,7 @@ struct iwl_cfg iwl6000_3agn_cfg = {
194 .valid_tx_ant = ANT_ABC, 222 .valid_tx_ant = ANT_ABC,
195 .valid_rx_ant = ANT_ABC, 223 .valid_rx_ant = ANT_ABC,
196 .need_pll_cfg = false, 224 .need_pll_cfg = false,
225 .pa_type = IWL_PA_SYSTEM,
197}; 226};
198 227
199struct iwl_cfg iwl6050_3agn_cfg = { 228struct iwl_cfg iwl6050_3agn_cfg = {
@@ -210,6 +239,7 @@ struct iwl_cfg iwl6050_3agn_cfg = {
210 .valid_tx_ant = ANT_ABC, 239 .valid_tx_ant = ANT_ABC,
211 .valid_rx_ant = ANT_ABC, 240 .valid_rx_ant = ANT_ABC,
212 .need_pll_cfg = false, 241 .need_pll_cfg = false,
242 .pa_type = IWL_PA_SYSTEM,
213}; 243};
214 244
215MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); 245MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX));
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 4cb1a1b73483..db580cbf5982 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -1291,6 +1291,7 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1291 size_t len; 1291 size_t len;
1292 u32 api_ver, build; 1292 u32 api_ver, build;
1293 u32 inst_size, data_size, init_size, init_data_size, boot_size; 1293 u32 inst_size, data_size, init_size, init_data_size, boot_size;
1294 u16 eeprom_ver;
1294 1295
1295 /* Ask kernel firmware_class module to get the boot firmware off disk. 1296 /* Ask kernel firmware_class module to get the boot firmware off disk.
1296 * request_firmware() is synchronous, file is in memory on return. */ 1297 * request_firmware() is synchronous, file is in memory on return. */
@@ -1368,6 +1369,11 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1368 if (build) 1369 if (build)
1369 IWL_DEBUG_INFO(priv, "Build %u\n", build); 1370 IWL_DEBUG_INFO(priv, "Build %u\n", build);
1370 1371
1372 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
1373 IWL_DEBUG_INFO(priv, "NVM Type: %s, version: 0x%x\n",
1374 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
1375 ? "OTP" : "EEPROM", eeprom_ver);
1376
1371 IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", 1377 IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
1372 priv->ucode_ver); 1378 priv->ucode_ver);
1373 IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n", 1379 IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
@@ -2483,39 +2489,6 @@ static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
2483#endif /* CONFIG_IWLWIFI_DEBUG */ 2489#endif /* CONFIG_IWLWIFI_DEBUG */
2484 2490
2485 2491
2486static ssize_t show_version(struct device *d,
2487 struct device_attribute *attr, char *buf)
2488{
2489 struct iwl_priv *priv = dev_get_drvdata(d);
2490 struct iwl_alive_resp *palive = &priv->card_alive;
2491 ssize_t pos = 0;
2492 u16 eeprom_ver;
2493
2494 if (palive->is_valid)
2495 pos += sprintf(buf + pos,
2496 "fw version: 0x%01X.0x%01X.0x%01X.0x%01X\n"
2497 "fw type: 0x%01X 0x%01X\n",
2498 palive->ucode_major, palive->ucode_minor,
2499 palive->sw_rev[0], palive->sw_rev[1],
2500 palive->ver_type, palive->ver_subtype);
2501 else
2502 pos += sprintf(buf + pos, "fw not loaded\n");
2503
2504 if (priv->eeprom) {
2505 eeprom_ver = iwl_eeprom_query16(priv, EEPROM_VERSION);
2506 pos += sprintf(buf + pos, "NVM Type: %s, version: 0x%x\n",
2507 (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
2508 ? "OTP" : "EEPROM", eeprom_ver);
2509
2510 } else {
2511 pos += sprintf(buf + pos, "EEPROM not initialzed\n");
2512 }
2513
2514 return pos;
2515}
2516
2517static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL);
2518
2519static ssize_t show_temperature(struct device *d, 2492static ssize_t show_temperature(struct device *d,
2520 struct device_attribute *attr, char *buf) 2493 struct device_attribute *attr, char *buf)
2521{ 2494{
@@ -2779,7 +2752,6 @@ static struct attribute *iwl_sysfs_entries[] = {
2779#ifdef CONFIG_IWLWIFI_DEBUG 2752#ifdef CONFIG_IWLWIFI_DEBUG
2780 &dev_attr_debug_level.attr, 2753 &dev_attr_debug_level.attr,
2781#endif 2754#endif
2782 &dev_attr_version.attr,
2783 NULL 2755 NULL
2784}; 2756};
2785 2757
@@ -3139,15 +3111,12 @@ static struct pci_device_id iwl_hw_card_ids[] = {
3139 {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)}, 3111 {IWL_PCI_DEVICE(0x423C, PCI_ANY_ID, iwl5150_agn_cfg)},
3140 {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)}, 3112 {IWL_PCI_DEVICE(0x423D, PCI_ANY_ID, iwl5150_agn_cfg)},
3141/* 6000/6050 Series */ 3113/* 6000/6050 Series */
3142 {IWL_PCI_DEVICE(0x0082, 0x1102, iwl6000_2ag_cfg)}, 3114 {IWL_PCI_DEVICE(0x008D, PCI_ANY_ID, iwl6000h_2agn_cfg)},
3143 {IWL_PCI_DEVICE(0x0085, 0x1112, iwl6000_2ag_cfg)}, 3115 {IWL_PCI_DEVICE(0x008E, PCI_ANY_ID, iwl6000h_2agn_cfg)},
3144 {IWL_PCI_DEVICE(0x0082, 0x1122, iwl6000_2ag_cfg)},
3145 {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)}, 3116 {IWL_PCI_DEVICE(0x422B, PCI_ANY_ID, iwl6000_3agn_cfg)},
3146 {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000_2agn_cfg)}, 3117 {IWL_PCI_DEVICE(0x422C, PCI_ANY_ID, iwl6000i_2agn_cfg)},
3147 {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)}, 3118 {IWL_PCI_DEVICE(0x4238, PCI_ANY_ID, iwl6000_3agn_cfg)},
3148 {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000_2agn_cfg)}, 3119 {IWL_PCI_DEVICE(0x4239, PCI_ANY_ID, iwl6000i_2agn_cfg)},
3149 {IWL_PCI_DEVICE(0x0082, PCI_ANY_ID, iwl6000_2agn_cfg)},
3150 {IWL_PCI_DEVICE(0x0085, PCI_ANY_ID, iwl6000_3agn_cfg)},
3151 {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)}, 3120 {IWL_PCI_DEVICE(0x0086, PCI_ANY_ID, iwl6050_3agn_cfg)},
3152 {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)}, 3121 {IWL_PCI_DEVICE(0x0087, PCI_ANY_ID, iwl6050_2agn_cfg)},
3153 {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)}, 3122 {IWL_PCI_DEVICE(0x0088, PCI_ANY_ID, iwl6050_3agn_cfg)},
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 8570d56b3124..6797076bd45f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -548,9 +548,6 @@ int iwlcore_init_geos(struct iwl_priv *priv)
548 geo_ch->flags |= IEEE80211_CHAN_DISABLED; 548 geo_ch->flags |= IEEE80211_CHAN_DISABLED;
549 } 549 }
550 550
551 /* Save flags for reg domain usage */
552 geo_ch->orig_flags = geo_ch->flags;
553
554 IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n", 551 IWL_DEBUG_INFO(priv, "Channel %d Freq=%d[%sGHz] %s flag=0x%X\n",
555 ch->channel, geo_ch->center_freq, 552 ch->channel, geo_ch->center_freq,
556 is_channel_a_band(ch) ? "5.2" : "2.4", 553 is_channel_a_band(ch) ? "5.2" : "2.4",
@@ -1140,7 +1137,6 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
1140 priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK; 1137 priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK;
1141 } 1138 }
1142} 1139}
1143EXPORT_SYMBOL(iwl_set_flags_for_band);
1144 1140
1145/* 1141/*
1146 * initialize rxon structure with default values from eeprom 1142 * initialize rxon structure with default values from eeprom
@@ -2291,7 +2287,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags, u8 meta_flag)
2291 2287
2292 return iwl_send_cmd(priv, &cmd); 2288 return iwl_send_cmd(priv, &cmd);
2293} 2289}
2294EXPORT_SYMBOL(iwl_send_card_state);
2295 2290
2296void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, 2291void iwl_rx_pm_sleep_notif(struct iwl_priv *priv,
2297 struct iwl_rx_mem_buffer *rxb) 2292 struct iwl_rx_mem_buffer *rxb)
@@ -2335,7 +2330,6 @@ void iwl_clear_isr_stats(struct iwl_priv *priv)
2335{ 2330{
2336 memset(&priv->isr_stats, 0, sizeof(priv->isr_stats)); 2331 memset(&priv->isr_stats, 0, sizeof(priv->isr_stats));
2337} 2332}
2338EXPORT_SYMBOL(iwl_clear_isr_stats);
2339 2333
2340int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, 2334int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
2341 const struct ieee80211_tx_queue_params *params) 2335 const struct ieee80211_tx_queue_params *params)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index febcf76e1d41..10ddcdda1041 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -206,6 +206,7 @@ struct iwl_mod_params {
206 * filename is constructed as fw_name_pre<api>.ucode. 206 * filename is constructed as fw_name_pre<api>.ucode.
207 * @ucode_api_max: Highest version of uCode API supported by driver. 207 * @ucode_api_max: Highest version of uCode API supported by driver.
208 * @ucode_api_min: Lowest version of uCode API supported by driver. 208 * @ucode_api_min: Lowest version of uCode API supported by driver.
209 * @pa_type: used by 6000 series only to identify the type of Power Amplifier
209 * 210 *
210 * We enable the driver to be backward compatible wrt API version. The 211 * We enable the driver to be backward compatible wrt API version. The
211 * driver specifies which APIs it supports (with @ucode_api_max being the 212 * driver specifies which APIs it supports (with @ucode_api_max being the
@@ -226,6 +227,7 @@ struct iwl_mod_params {
226 * iwl_hcmd_utils_ops etc. we accommodate different command structures 227 * iwl_hcmd_utils_ops etc. we accommodate different command structures
227 * and flows between hardware versions (4965/5000) as well as their API 228 * and flows between hardware versions (4965/5000) as well as their API
228 * versions. 229 * versions.
230 *
229 */ 231 */
230struct iwl_cfg { 232struct iwl_cfg {
231 const char *name; 233 const char *name;
@@ -242,6 +244,7 @@ struct iwl_cfg {
242 u8 valid_rx_ant; 244 u8 valid_rx_ant;
243 bool need_pll_cfg; 245 bool need_pll_cfg;
244 bool use_isr_legacy; 246 bool use_isr_legacy;
247 enum iwl_pa_type pa_type;
245}; 248};
246 249
247/*************************** 250/***************************
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index f03dae1b2f36..06437d13e73e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -91,7 +91,8 @@
91#define CSR_EEPROM_GP (CSR_BASE+0x030) 91#define CSR_EEPROM_GP (CSR_BASE+0x030)
92#define CSR_OTP_GP_REG (CSR_BASE+0x034) 92#define CSR_OTP_GP_REG (CSR_BASE+0x034)
93#define CSR_GIO_REG (CSR_BASE+0x03C) 93#define CSR_GIO_REG (CSR_BASE+0x03C)
94#define CSR_GP_UCODE (CSR_BASE+0x044) 94#define CSR_GP_UCODE_REG (CSR_BASE+0x048)
95#define CSR_GP_DRIVER_REG (CSR_BASE+0x050)
95#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054) 96#define CSR_UCODE_DRV_GP1 (CSR_BASE+0x054)
96#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058) 97#define CSR_UCODE_DRV_GP1_SET (CSR_BASE+0x058)
97#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c) 98#define CSR_UCODE_DRV_GP1_CLR (CSR_BASE+0x05c)
@@ -245,6 +246,13 @@
245#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004) 246#define CSR_UCODE_DRV_GP1_BIT_CMD_BLOCKED (0x00000004)
246#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008) 247#define CSR_UCODE_DRV_GP1_REG_BIT_CT_KILL_EXIT (0x00000008)
247 248
249/* GP Driver */
250#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_MSK (0x00000003)
251#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_3x3_HYB (0x00000000)
252#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_HYB (0x00000001)
253#define CSR_GP_DRIVER_REG_BIT_RADIO_SKU_2x2_IPA (0x00000002)
254
255
248/* GI Chicken Bits */ 256/* GI Chicken Bits */
249#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000) 257#define CSR_GIO_CHICKEN_BITS_REG_BIT_L1A_NO_L0S_RX (0x00800000)
250#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000) 258#define CSR_GIO_CHICKEN_BITS_REG_BIT_DIS_L0S_EXIT_TIMER (0x20000000)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 0ee3ad245697..cab6255210d5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -56,8 +56,8 @@ extern struct iwl_cfg iwl5350_agn_cfg;
56extern struct iwl_cfg iwl5100_bg_cfg; 56extern struct iwl_cfg iwl5100_bg_cfg;
57extern struct iwl_cfg iwl5100_abg_cfg; 57extern struct iwl_cfg iwl5100_abg_cfg;
58extern struct iwl_cfg iwl5150_agn_cfg; 58extern struct iwl_cfg iwl5150_agn_cfg;
59extern struct iwl_cfg iwl6000_2ag_cfg; 59extern struct iwl_cfg iwl6000h_2agn_cfg;
60extern struct iwl_cfg iwl6000_2agn_cfg; 60extern struct iwl_cfg iwl6000i_2agn_cfg;
61extern struct iwl_cfg iwl6000_3agn_cfg; 61extern struct iwl_cfg iwl6000_3agn_cfg;
62extern struct iwl_cfg iwl6050_2agn_cfg; 62extern struct iwl_cfg iwl6050_2agn_cfg;
63extern struct iwl_cfg iwl6050_3agn_cfg; 63extern struct iwl_cfg iwl6050_3agn_cfg;
@@ -888,6 +888,19 @@ enum iwl_nvm_type {
888 NVM_DEVICE_TYPE_OTP, 888 NVM_DEVICE_TYPE_OTP,
889}; 889};
890 890
891
892/**
893 * enum iwl_pa_type - Power Amplifier type
894 * @IWL_PA_SYSTEM: based on uCode configuration
895 * @IWL_PA_HYBRID: use both Internal and external PA
896 * @IWL_PA_INTERNAL: use Internal only
897 */
898enum iwl_pa_type {
899 IWL_PA_SYSTEM = 0,
900 IWL_PA_HYBRID = 1,
901 IWL_PA_INTERNAL = 2,
902};
903
891/* interrupt statistics */ 904/* interrupt statistics */
892struct isr_statistics { 905struct isr_statistics {
893 u32 hw; 906 u32 hw;
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 7cce8f85bcc6..3d61cb43151c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -335,7 +335,6 @@ void iwl_leds_background(struct iwl_priv *priv)
335 priv->last_blink_time = jiffies; 335 priv->last_blink_time = jiffies;
336 priv->last_blink_rate = blink_idx; 336 priv->last_blink_rate = blink_idx;
337} 337}
338EXPORT_SYMBOL(iwl_leds_background);
339 338
340/* Register all led handler */ 339/* Register all led handler */
341int iwl_leds_register(struct iwl_priv *priv) 340int iwl_leds_register(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 5d5f2153f445..e002c8b56c49 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -406,7 +406,6 @@ void iwl_rx_queue_reset(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
406 rxq->free_count = 0; 406 rxq->free_count = 0;
407 spin_unlock_irqrestore(&rxq->lock, flags); 407 spin_unlock_irqrestore(&rxq->lock, flags);
408} 408}
409EXPORT_SYMBOL(iwl_rx_queue_reset);
410 409
411int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) 410int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq)
412{ 411{
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 79ea5cc2c89a..efcae0d5e193 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -464,7 +464,6 @@ out:
464 spin_unlock_irqrestore(&priv->sta_lock, flags); 464 spin_unlock_irqrestore(&priv->sta_lock, flags);
465 return ret; 465 return ret;
466} 466}
467EXPORT_SYMBOL(iwl_remove_station);
468 467
469/** 468/**
470 * iwl_clear_stations_table - Clear the driver's station table 469 * iwl_clear_stations_table - Clear the driver's station table
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 6bb9602f3477..288b871e974b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -970,6 +970,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
970 out_cmd = txq->cmd[idx]; 970 out_cmd = txq->cmd[idx];
971 out_meta = &txq->meta[idx]; 971 out_meta = &txq->meta[idx];
972 972
973 memset(out_meta, 0, sizeof(*out_meta)); /* re-initialize to NULL */
973 out_meta->flags = cmd->flags; 974 out_meta->flags = cmd->flags;
974 if (cmd->flags & CMD_WANT_SKB) 975 if (cmd->flags & CMD_WANT_SKB)
975 out_meta->source = cmd; 976 out_meta->source = cmd;
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 3f5a08fa401f..a6e852f4f92c 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -484,6 +484,8 @@ static int iwm_set_auth_type(struct iwm_priv *iwm,
484 484
485static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version) 485static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
486{ 486{
487 IWM_DBG_WEXT(iwm, DBG, "wpa_version: %d\n", wpa_version);
488
487 if (!wpa_version) { 489 if (!wpa_version) {
488 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE; 490 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
489 return 0; 491 return 0;
@@ -508,6 +510,9 @@ static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
508 return 0; 510 return 0;
509 } 511 }
510 512
513 IWM_DBG_WEXT(iwm, DBG, "%ccast cipher is 0x%x\n", ucast ? 'u' : 'm',
514 cipher);
515
511 switch (cipher) { 516 switch (cipher) {
512 case IW_AUTH_CIPHER_NONE: 517 case IW_AUTH_CIPHER_NONE:
513 *profile_cipher = UMAC_CIPHER_TYPE_NONE; 518 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
@@ -584,11 +589,11 @@ static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
584 iwm->umac_profile->bss_num = 0; 589 iwm->umac_profile->bss_num = 0;
585 } 590 }
586 591
587 ret = iwm_set_auth_type(iwm, sme->auth_type); 592 ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
588 if (ret < 0) 593 if (ret < 0)
589 return ret; 594 return ret;
590 595
591 ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions); 596 ret = iwm_set_auth_type(iwm, sme->auth_type);
592 if (ret < 0) 597 if (ret < 0)
593 return ret; 598 return ret;
594 599
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 0d6637005f42..f0c8acdb71a4 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -526,19 +526,6 @@ int iwm_read_mac(struct iwm_priv *iwm, u8 *mac)
526 return 0; 526 return 0;
527} 527}
528 528
529int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx)
530{
531 struct iwm_umac_tx_key_id tx_key_id;
532
533 tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID;
534 tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) -
535 sizeof(struct iwm_umac_wifi_if));
536
537 tx_key_id.key_idx = key_idx;
538
539 return iwm_send_wifi_if_cmd(iwm, &tx_key_id, sizeof(tx_key_id), 1);
540}
541
542static int iwm_check_profile(struct iwm_priv *iwm) 529static int iwm_check_profile(struct iwm_priv *iwm)
543{ 530{
544 if (!iwm->umac_profile_active) 531 if (!iwm->umac_profile_active)
@@ -572,6 +559,32 @@ static int iwm_check_profile(struct iwm_priv *iwm)
572 return 0; 559 return 0;
573} 560}
574 561
562int iwm_set_tx_key(struct iwm_priv *iwm, u8 key_idx)
563{
564 struct iwm_umac_tx_key_id tx_key_id;
565 int ret;
566
567 ret = iwm_check_profile(iwm);
568 if (ret < 0)
569 return ret;
570
571 /* UMAC only allows to set default key for WEP and auth type is
572 * NOT 802.1X or RSNA. */
573 if ((iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_40 &&
574 iwm->umac_profile->sec.ucast_cipher != UMAC_CIPHER_TYPE_WEP_104) ||
575 iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_8021X ||
576 iwm->umac_profile->sec.auth_type == UMAC_AUTH_TYPE_RSNA_PSK)
577 return 0;
578
579 tx_key_id.hdr.oid = UMAC_WIFI_IF_CMD_GLOBAL_TX_KEY_ID;
580 tx_key_id.hdr.buf_size = cpu_to_le16(sizeof(struct iwm_umac_tx_key_id) -
581 sizeof(struct iwm_umac_wifi_if));
582
583 tx_key_id.key_idx = key_idx;
584
585 return iwm_send_wifi_if_cmd(iwm, &tx_key_id, sizeof(tx_key_id), 1);
586}
587
575int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key) 588int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key)
576{ 589{
577 int ret = 0; 590 int ret = 0;
@@ -596,6 +609,8 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key)
596 key_idx = key->hdr.key_idx; 609 key_idx = key->hdr.key_idx;
597 610
598 if (!remove) { 611 if (!remove) {
612 u8 auth_type = iwm->umac_profile->sec.auth_type;
613
599 IWM_DBG_WEXT(iwm, DBG, "key_idx:%d\n", key_idx); 614 IWM_DBG_WEXT(iwm, DBG, "key_idx:%d\n", key_idx);
600 IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len); 615 IWM_DBG_WEXT(iwm, DBG, "key_len:%d\n", key_len);
601 IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n", 616 IWM_DBG_WEXT(iwm, DBG, "MAC:%pM, idx:%d, multicast:%d\n",
@@ -618,7 +633,9 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key)
618 memcpy(&wep40->key_hdr, key_hdr, 633 memcpy(&wep40->key_hdr, key_hdr,
619 sizeof(struct iwm_umac_key_hdr)); 634 sizeof(struct iwm_umac_key_hdr));
620 memcpy(wep40->key, key_data, key_len); 635 memcpy(wep40->key, key_data, key_len);
621 wep40->static_key = 1; 636 wep40->static_key =
637 !!((auth_type != UMAC_AUTH_TYPE_8021X) &&
638 (auth_type != UMAC_AUTH_TYPE_RSNA_PSK));
622 639
623 cmd_size = sizeof(struct iwm_umac_key_wep40); 640 cmd_size = sizeof(struct iwm_umac_key_wep40);
624 break; 641 break;
@@ -632,7 +649,9 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key)
632 memcpy(&wep104->key_hdr, key_hdr, 649 memcpy(&wep104->key_hdr, key_hdr,
633 sizeof(struct iwm_umac_key_hdr)); 650 sizeof(struct iwm_umac_key_hdr));
634 memcpy(wep104->key, key_data, key_len); 651 memcpy(wep104->key, key_data, key_len);
635 wep104->static_key = 1; 652 wep104->static_key =
653 !!((auth_type != UMAC_AUTH_TYPE_8021X) &&
654 (auth_type != UMAC_AUTH_TYPE_RSNA_PSK));
636 655
637 cmd_size = sizeof(struct iwm_umac_key_wep104); 656 cmd_size = sizeof(struct iwm_umac_key_wep104);
638 break; 657 break;
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c
index 963c20125fc9..446e327180f8 100644
--- a/drivers/net/wireless/libertas/if_spi.c
+++ b/drivers/net/wireless/libertas/if_spi.c
@@ -376,7 +376,7 @@ static int spu_set_bus_mode(struct if_spi_card *card, u16 mode)
376 err = spu_read_u16(card, IF_SPI_SPU_BUS_MODE_REG, &rval); 376 err = spu_read_u16(card, IF_SPI_SPU_BUS_MODE_REG, &rval);
377 if (err) 377 if (err)
378 return err; 378 return err;
379 if (rval != mode) { 379 if ((rval & 0xF) != mode) {
380 lbs_pr_err("Can't read bus mode register.\n"); 380 lbs_pr_err("Can't read bus mode register.\n");
381 return -EIO; 381 return -EIO;
382 } 382 }
diff --git a/drivers/net/wireless/libertas/wext.c b/drivers/net/wireless/libertas/wext.c
index e96451ce470b..be837a0d2517 100644
--- a/drivers/net/wireless/libertas/wext.c
+++ b/drivers/net/wireless/libertas/wext.c
@@ -1728,6 +1728,8 @@ static int lbs_set_auth(struct net_device *dev,
1728 } 1728 }
1729 1729
1730 switch (dwrq->flags & IW_AUTH_INDEX) { 1730 switch (dwrq->flags & IW_AUTH_INDEX) {
1731 case IW_AUTH_PRIVACY_INVOKED:
1732 case IW_AUTH_RX_UNENCRYPTED_EAPOL:
1731 case IW_AUTH_TKIP_COUNTERMEASURES: 1733 case IW_AUTH_TKIP_COUNTERMEASURES:
1732 case IW_AUTH_CIPHER_PAIRWISE: 1734 case IW_AUTH_CIPHER_PAIRWISE:
1733 case IW_AUTH_CIPHER_GROUP: 1735 case IW_AUTH_CIPHER_GROUP:
diff --git a/drivers/net/wireless/orinoco/cfg.c b/drivers/net/wireless/orinoco/cfg.c
index 1a87d3a0967c..27f2d3342645 100644
--- a/drivers/net/wireless/orinoco/cfg.c
+++ b/drivers/net/wireless/orinoco/cfg.c
@@ -156,7 +156,48 @@ static int orinoco_scan(struct wiphy *wiphy, struct net_device *dev,
156 return err; 156 return err;
157} 157}
158 158
159static int orinoco_set_channel(struct wiphy *wiphy,
160 struct ieee80211_channel *chan,
161 enum nl80211_channel_type channel_type)
162{
163 struct orinoco_private *priv = wiphy_priv(wiphy);
164 int err = 0;
165 unsigned long flags;
166 int channel;
167
168 if (!chan)
169 return -EINVAL;
170
171 if (channel_type != NL80211_CHAN_NO_HT)
172 return -EINVAL;
173
174 if (chan->band != IEEE80211_BAND_2GHZ)
175 return -EINVAL;
176
177 channel = ieee80211_freq_to_dsss_chan(chan->center_freq);
178
179 if ((channel < 1) || (channel > NUM_CHANNELS) ||
180 !(priv->channel_mask & (1 << (channel-1))))
181 return -EINVAL;
182
183 if (orinoco_lock(priv, &flags) != 0)
184 return -EBUSY;
185
186 priv->channel = channel;
187 if (priv->iw_mode == NL80211_IFTYPE_MONITOR) {
188 /* Fast channel change - no commit if successful */
189 hermes_t *hw = &priv->hw;
190 err = hermes_docmd_wait(hw, HERMES_CMD_TEST |
191 HERMES_TEST_SET_CHANNEL,
192 channel, NULL);
193 }
194 orinoco_unlock(priv, &flags);
195
196 return err;
197}
198
159const struct cfg80211_ops orinoco_cfg_ops = { 199const struct cfg80211_ops orinoco_cfg_ops = {
160 .change_virtual_intf = orinoco_change_vif, 200 .change_virtual_intf = orinoco_change_vif,
201 .set_channel = orinoco_set_channel,
161 .scan = orinoco_scan, 202 .scan = orinoco_scan,
162}; 203};
diff --git a/drivers/net/wireless/p54/led.c b/drivers/net/wireless/p54/led.c
index c00115b206d4..9575ac033630 100644
--- a/drivers/net/wireless/p54/led.c
+++ b/drivers/net/wireless/p54/led.c
@@ -61,7 +61,7 @@ static void p54_update_leds(struct work_struct *work)
61 wiphy_name(priv->hw->wiphy), err); 61 wiphy_name(priv->hw->wiphy), err);
62 62
63 if (rerun) 63 if (rerun)
64 queue_delayed_work(priv->hw->workqueue, &priv->led_work, 64 ieee80211_queue_delayed_work(priv->hw, &priv->led_work,
65 msecs_to_jiffies(blink_delay)); 65 msecs_to_jiffies(blink_delay));
66} 66}
67 67
@@ -78,8 +78,7 @@ static void p54_led_brightness_set(struct led_classdev *led_dev,
78 78
79 if ((brightness) && (led->registered)) { 79 if ((brightness) && (led->registered)) {
80 led->toggled++; 80 led->toggled++;
81 queue_delayed_work(priv->hw->workqueue, &priv->led_work, 81 ieee80211_queue_delayed_work(priv->hw, &priv->led_work, HZ/10);
82 HZ/10);
83 } 82 }
84} 83}
85 84
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 955f6d7ec16a..a0d0e726bc4e 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -180,7 +180,7 @@ static int p54_start(struct ieee80211_hw *dev)
180 goto out; 180 goto out;
181 } 181 }
182 182
183 queue_delayed_work(dev->workqueue, &priv->work, 0); 183 ieee80211_queue_delayed_work(dev, &priv->work, 0);
184 184
185 priv->softled_state = 0; 185 priv->softled_state = 0;
186 err = p54_set_leds(priv); 186 err = p54_set_leds(priv);
diff --git a/drivers/net/wireless/p54/p54spi.c b/drivers/net/wireless/p54/p54spi.c
index eef532987d05..05458d9249ce 100644
--- a/drivers/net/wireless/p54/p54spi.c
+++ b/drivers/net/wireless/p54/p54spi.c
@@ -391,7 +391,7 @@ static irqreturn_t p54spi_interrupt(int irq, void *config)
391 struct spi_device *spi = config; 391 struct spi_device *spi = config;
392 struct p54s_priv *priv = dev_get_drvdata(&spi->dev); 392 struct p54s_priv *priv = dev_get_drvdata(&spi->dev);
393 393
394 queue_work(priv->hw->workqueue, &priv->work); 394 ieee80211_queue_work(priv->hw, &priv->work);
395 395
396 return IRQ_HANDLED; 396 return IRQ_HANDLED;
397} 397}
@@ -479,7 +479,7 @@ static void p54spi_op_tx(struct ieee80211_hw *dev, struct sk_buff *skb)
479 list_add_tail(&di->tx_list, &priv->tx_pending); 479 list_add_tail(&di->tx_list, &priv->tx_pending);
480 spin_unlock_irqrestore(&priv->tx_lock, flags); 480 spin_unlock_irqrestore(&priv->tx_lock, flags);
481 481
482 queue_work(priv->hw->workqueue, &priv->work); 482 ieee80211_queue_work(priv->hw, &priv->work);
483} 483}
484 484
485static void p54spi_work(struct work_struct *work) 485static void p54spi_work(struct work_struct *work)
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index c32a0d2fa1f7..704685fab177 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -380,7 +380,7 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
380 380
381 ieee80211_rx_irqsafe(priv->hw, skb); 381 ieee80211_rx_irqsafe(priv->hw, skb);
382 382
383 queue_delayed_work(priv->hw->workqueue, &priv->work, 383 ieee80211_queue_delayed_work(priv->hw, &priv->work,
384 msecs_to_jiffies(P54_STATISTICS_UPDATE)); 384 msecs_to_jiffies(P54_STATISTICS_UPDATE));
385 385
386 return -1; 386 return -1;
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 09c0702ae645..828dc1825bba 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -100,7 +100,6 @@ MODULE_PARM_DESC(workaround_interval,
100#define OID_GEN_RCV_ERROR cpu_to_le32(0x00020104) 100#define OID_GEN_RCV_ERROR cpu_to_le32(0x00020104)
101#define OID_GEN_RCV_NO_BUFFER cpu_to_le32(0x00020105) 101#define OID_GEN_RCV_NO_BUFFER cpu_to_le32(0x00020105)
102 102
103#define OID_802_3_PERMANENT_ADDRESS cpu_to_le32(0x01010101)
104#define OID_802_3_CURRENT_ADDRESS cpu_to_le32(0x01010102) 103#define OID_802_3_CURRENT_ADDRESS cpu_to_le32(0x01010102)
105#define OID_802_3_MULTICAST_LIST cpu_to_le32(0x01010103) 104#define OID_802_3_MULTICAST_LIST cpu_to_le32(0x01010103)
106#define OID_802_3_MAXIMUM_LIST_SIZE cpu_to_le32(0x01010104) 105#define OID_802_3_MAXIMUM_LIST_SIZE cpu_to_le32(0x01010104)
@@ -202,6 +201,24 @@ enum ndis_80211_priv_filter {
202 NDIS_80211_PRIV_8021X_WEP 201 NDIS_80211_PRIV_8021X_WEP
203}; 202};
204 203
204enum ndis_80211_status_type {
205 NDIS_80211_STATUSTYPE_AUTHENTICATION,
206 NDIS_80211_STATUSTYPE_MEDIASTREAMMODE,
207 NDIS_80211_STATUSTYPE_PMKID_CANDIDATELIST,
208 NDIS_80211_STATUSTYPE_RADIOSTATE,
209};
210
211enum ndis_80211_media_stream_mode {
212 NDIS_80211_MEDIA_STREAM_OFF,
213 NDIS_80211_MEDIA_STREAM_ON
214};
215
216enum ndis_80211_radio_status {
217 NDIS_80211_RADIO_STATUS_ON,
218 NDIS_80211_RADIO_STATUS_HARDWARE_OFF,
219 NDIS_80211_RADIO_STATUS_SOFTWARE_OFF,
220};
221
205enum ndis_80211_addkey_bits { 222enum ndis_80211_addkey_bits {
206 NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28), 223 NDIS_80211_ADDKEY_8021X_AUTH = cpu_to_le32(1 << 28),
207 NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29), 224 NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ = cpu_to_le32(1 << 29),
@@ -214,6 +231,35 @@ enum ndis_80211_addwep_bits {
214 NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31) 231 NDIS_80211_ADDWEP_TRANSMIT_KEY = cpu_to_le32(1 << 31)
215}; 232};
216 233
234struct ndis_80211_auth_request {
235 __le32 length;
236 u8 bssid[6];
237 u8 padding[2];
238 __le32 flags;
239} __attribute__((packed));
240
241struct ndis_80211_pmkid_candidate {
242 u8 bssid[6];
243 u8 padding[2];
244 __le32 flags;
245} __attribute__((packed));
246
247struct ndis_80211_pmkid_cand_list {
248 __le32 version;
249 __le32 num_candidates;
250 struct ndis_80211_pmkid_candidate candidate_list[0];
251} __attribute__((packed));
252
253struct ndis_80211_status_indication {
254 __le32 status_type;
255 union {
256 enum ndis_80211_media_stream_mode media_stream_mode;
257 enum ndis_80211_radio_status radio_status;
258 struct ndis_80211_auth_request auth_request[0];
259 struct ndis_80211_pmkid_cand_list cand_list;
260 } u;
261} __attribute__((packed));
262
217struct ndis_80211_ssid { 263struct ndis_80211_ssid {
218 __le32 length; 264 __le32 length;
219 u8 essid[NDIS_802_11_LENGTH_SSID]; 265 u8 essid[NDIS_802_11_LENGTH_SSID];
@@ -281,6 +327,7 @@ struct ndis_80211_remove_key {
281 __le32 size; 327 __le32 size;
282 __le32 index; 328 __le32 index;
283 u8 bssid[6]; 329 u8 bssid[6];
330 u8 padding[2];
284} __attribute__((packed)); 331} __attribute__((packed));
285 332
286struct ndis_config_param { 333struct ndis_config_param {
@@ -366,6 +413,15 @@ static const struct ieee80211_rate rndis_rates[] = {
366 { .bitrate = 540 } 413 { .bitrate = 540 }
367}; 414};
368 415
416struct rndis_wlan_encr_key {
417 int len;
418 int cipher;
419 u8 material[32];
420 u8 bssid[ETH_ALEN];
421 bool pairwise;
422 bool tx_key;
423};
424
369/* RNDIS device private data */ 425/* RNDIS device private data */
370struct rndis_wlan_private { 426struct rndis_wlan_private {
371 struct usbnet *usbdev; 427 struct usbnet *usbdev;
@@ -409,9 +465,7 @@ struct rndis_wlan_private {
409 465
410 /* encryption stuff */ 466 /* encryption stuff */
411 int encr_tx_key_index; 467 int encr_tx_key_index;
412 char encr_keys[4][32]; 468 struct rndis_wlan_encr_key encr_keys[4];
413 int encr_key_len[4];
414 char encr_key_wpa[4];
415 int wpa_version; 469 int wpa_version;
416 int wpa_keymgmt; 470 int wpa_keymgmt;
417 int wpa_authalg; 471 int wpa_authalg;
@@ -478,6 +532,77 @@ static u32 get_bcm4320_power_dbm(struct rndis_wlan_private *priv)
478} 532}
479 533
480 534
535static bool is_wpa_key(struct rndis_wlan_private *priv, int idx)
536{
537 int cipher = priv->encr_keys[idx].cipher;
538
539 return (cipher == WLAN_CIPHER_SUITE_CCMP ||
540 cipher == WLAN_CIPHER_SUITE_TKIP);
541}
542
543
544#ifdef DEBUG
545static const char *oid_to_string(__le32 oid)
546{
547 switch (oid) {
548#define OID_STR(oid) case oid: return(#oid)
549 /* from rndis_host.h */
550 OID_STR(OID_802_3_PERMANENT_ADDRESS);
551 OID_STR(OID_GEN_MAXIMUM_FRAME_SIZE);
552 OID_STR(OID_GEN_CURRENT_PACKET_FILTER);
553 OID_STR(OID_GEN_PHYSICAL_MEDIUM);
554
555 /* from rndis_wlan.c */
556 OID_STR(OID_GEN_LINK_SPEED);
557 OID_STR(OID_GEN_RNDIS_CONFIG_PARAMETER);
558
559 OID_STR(OID_GEN_XMIT_OK);
560 OID_STR(OID_GEN_RCV_OK);
561 OID_STR(OID_GEN_XMIT_ERROR);
562 OID_STR(OID_GEN_RCV_ERROR);
563 OID_STR(OID_GEN_RCV_NO_BUFFER);
564
565 OID_STR(OID_802_3_CURRENT_ADDRESS);
566 OID_STR(OID_802_3_MULTICAST_LIST);
567 OID_STR(OID_802_3_MAXIMUM_LIST_SIZE);
568
569 OID_STR(OID_802_11_BSSID);
570 OID_STR(OID_802_11_SSID);
571 OID_STR(OID_802_11_INFRASTRUCTURE_MODE);
572 OID_STR(OID_802_11_ADD_WEP);
573 OID_STR(OID_802_11_REMOVE_WEP);
574 OID_STR(OID_802_11_DISASSOCIATE);
575 OID_STR(OID_802_11_AUTHENTICATION_MODE);
576 OID_STR(OID_802_11_PRIVACY_FILTER);
577 OID_STR(OID_802_11_BSSID_LIST_SCAN);
578 OID_STR(OID_802_11_ENCRYPTION_STATUS);
579 OID_STR(OID_802_11_ADD_KEY);
580 OID_STR(OID_802_11_REMOVE_KEY);
581 OID_STR(OID_802_11_ASSOCIATION_INFORMATION);
582 OID_STR(OID_802_11_PMKID);
583 OID_STR(OID_802_11_NETWORK_TYPES_SUPPORTED);
584 OID_STR(OID_802_11_NETWORK_TYPE_IN_USE);
585 OID_STR(OID_802_11_TX_POWER_LEVEL);
586 OID_STR(OID_802_11_RSSI);
587 OID_STR(OID_802_11_RSSI_TRIGGER);
588 OID_STR(OID_802_11_FRAGMENTATION_THRESHOLD);
589 OID_STR(OID_802_11_RTS_THRESHOLD);
590 OID_STR(OID_802_11_SUPPORTED_RATES);
591 OID_STR(OID_802_11_CONFIGURATION);
592 OID_STR(OID_802_11_BSSID_LIST);
593#undef OID_STR
594 }
595
596 return "?";
597}
598#else
599static const char *oid_to_string(__le32 oid)
600{
601 return "?";
602}
603#endif
604
605
481/* translate error code */ 606/* translate error code */
482static int rndis_error_status(__le32 rndis_status) 607static int rndis_error_status(__le32 rndis_status)
483{ 608{
@@ -533,11 +658,21 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len)
533 u.get->oid = oid; 658 u.get->oid = oid;
534 659
535 ret = rndis_command(dev, u.header, buflen); 660 ret = rndis_command(dev, u.header, buflen);
661 if (ret < 0)
662 devdbg(dev, "rndis_query_oid(%s): rndis_command() failed, %d "
663 "(%08x)", oid_to_string(oid), ret,
664 le32_to_cpu(u.get_c->status));
665
536 if (ret == 0) { 666 if (ret == 0) {
537 ret = le32_to_cpu(u.get_c->len); 667 ret = le32_to_cpu(u.get_c->len);
538 *len = (*len > ret) ? ret : *len; 668 *len = (*len > ret) ? ret : *len;
539 memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len); 669 memcpy(data, u.buf + le32_to_cpu(u.get_c->offset) + 8, *len);
540 ret = rndis_error_status(u.get_c->status); 670 ret = rndis_error_status(u.get_c->status);
671
672 if (ret < 0)
673 devdbg(dev, "rndis_query_oid(%s): device returned "
674 "error, 0x%08x (%d)", oid_to_string(oid),
675 le32_to_cpu(u.get_c->status), ret);
541 } 676 }
542 677
543 mutex_unlock(&priv->command_lock); 678 mutex_unlock(&priv->command_lock);
@@ -583,9 +718,20 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
583 memcpy(u.buf + sizeof(*u.set), data, len); 718 memcpy(u.buf + sizeof(*u.set), data, len);
584 719
585 ret = rndis_command(dev, u.header, buflen); 720 ret = rndis_command(dev, u.header, buflen);
586 if (ret == 0) 721 if (ret < 0)
722 devdbg(dev, "rndis_set_oid(%s): rndis_command() failed, %d "
723 "(%08x)", oid_to_string(oid), ret,
724 le32_to_cpu(u.set_c->status));
725
726 if (ret == 0) {
587 ret = rndis_error_status(u.set_c->status); 727 ret = rndis_error_status(u.set_c->status);
588 728
729 if (ret < 0)
730 devdbg(dev, "rndis_set_oid(%s): device returned error, "
731 "0x%08x (%d)", oid_to_string(oid),
732 le32_to_cpu(u.set_c->status), ret);
733 }
734
589 mutex_unlock(&priv->command_lock); 735 mutex_unlock(&priv->command_lock);
590 736
591 if (u.buf != priv->command_buffer) 737 if (u.buf != priv->command_buffer)
@@ -594,6 +740,28 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len)
594} 740}
595 741
596 742
743static int rndis_reset(struct usbnet *usbdev)
744{
745 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
746 struct rndis_reset *reset;
747 int ret;
748
749 mutex_lock(&priv->command_lock);
750
751 reset = (void *)priv->command_buffer;
752 memset(reset, 0, sizeof(*reset));
753 reset->msg_type = RNDIS_MSG_RESET;
754 reset->msg_len = cpu_to_le32(sizeof(*reset));
755 ret = rndis_command(usbdev, (void *)reset, CONTROL_BUFFER_SIZE);
756
757 mutex_unlock(&priv->command_lock);
758
759 if (ret < 0)
760 return ret;
761 return 0;
762}
763
764
597/* 765/*
598 * Specs say that we can only set config parameters only soon after device 766 * Specs say that we can only set config parameters only soon after device
599 * initialization. 767 * initialization.
@@ -743,8 +911,7 @@ static int freq_to_dsconfig(struct iw_freq *freq, unsigned int *dsconfig)
743/* 911/*
744 * common functions 912 * common functions
745 */ 913 */
746static int 914static void restore_keys(struct usbnet *usbdev);
747add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index);
748 915
749static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) 916static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid)
750{ 917{
@@ -963,7 +1130,7 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
963{ 1130{
964 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1131 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
965 __le32 tmp; 1132 __le32 tmp;
966 int ret, i; 1133 int ret;
967 1134
968 devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode); 1135 devdbg(usbdev, "set_infra_mode: infra_mode=0x%x", priv->infra_mode);
969 1136
@@ -978,14 +1145,7 @@ static int set_infra_mode(struct usbnet *usbdev, int mode)
978 /* NDIS drivers clear keys when infrastructure mode is 1145 /* NDIS drivers clear keys when infrastructure mode is
979 * changed. But Linux tools assume otherwise. So set the 1146 * changed. But Linux tools assume otherwise. So set the
980 * keys */ 1147 * keys */
981 if (priv->wpa_keymgmt == 0 || 1148 restore_keys(usbdev);
982 priv->wpa_keymgmt == IW_AUTH_KEY_MGMT_802_1X) {
983 for (i = 0; i < 4; i++) {
984 if (priv->encr_key_len[i] > 0 && !priv->encr_key_wpa[i])
985 add_wep_key(usbdev, priv->encr_keys[i],
986 priv->encr_key_len[i], i);
987 }
988 }
989 1149
990 priv->infra_mode = mode; 1150 priv->infra_mode = mode;
991 return 0; 1151 return 0;
@@ -1052,11 +1212,16 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
1052{ 1212{
1053 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1213 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1054 struct ndis_80211_wep_key ndis_key; 1214 struct ndis_80211_wep_key ndis_key;
1055 int ret; 1215 int cipher, ret;
1056 1216
1057 if (key_len <= 0 || key_len > 32 || index < 0 || index >= 4) 1217 if ((key_len != 5 || key_len != 13) || index < 0 || index > 3)
1058 return -EINVAL; 1218 return -EINVAL;
1059 1219
1220 if (key_len == 5)
1221 cipher = WLAN_CIPHER_SUITE_WEP40;
1222 else
1223 cipher = WLAN_CIPHER_SUITE_WEP104;
1224
1060 memset(&ndis_key, 0, sizeof(ndis_key)); 1225 memset(&ndis_key, 0, sizeof(ndis_key));
1061 1226
1062 ndis_key.size = cpu_to_le32(sizeof(ndis_key)); 1227 ndis_key.size = cpu_to_le32(sizeof(ndis_key));
@@ -1081,30 +1246,44 @@ static int add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index)
1081 return ret; 1246 return ret;
1082 } 1247 }
1083 1248
1084 priv->encr_key_len[index] = key_len; 1249 priv->encr_keys[index].len = key_len;
1085 priv->encr_key_wpa[index] = 0; 1250 priv->encr_keys[index].cipher = cipher;
1086 memcpy(&priv->encr_keys[index], key, key_len); 1251 memcpy(&priv->encr_keys[index].material, key, key_len);
1252 memset(&priv->encr_keys[index].bssid, 0xff, ETH_ALEN);
1087 1253
1088 return 0; 1254 return 0;
1089} 1255}
1090 1256
1091 1257
1092static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, 1258static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1093 int index, const struct sockaddr *addr, 1259 int index, const u8 *addr, const u8 *rx_seq, int cipher,
1094 const u8 *rx_seq, int alg, int flags) 1260 int flags)
1095{ 1261{
1096 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1262 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1097 struct ndis_80211_key ndis_key; 1263 struct ndis_80211_key ndis_key;
1264 bool is_addr_ok;
1098 int ret; 1265 int ret;
1099 1266
1100 if (index < 0 || index >= 4) 1267 if (index < 0 || index >= 4) {
1268 devdbg(usbdev, "add_wpa_key: index out of range (%i)", index);
1101 return -EINVAL; 1269 return -EINVAL;
1102 if (key_len > sizeof(ndis_key.material) || key_len < 0) 1270 }
1271 if (key_len > sizeof(ndis_key.material) || key_len < 0) {
1272 devdbg(usbdev, "add_wpa_key: key length out of range (%i)",
1273 key_len);
1103 return -EINVAL; 1274 return -EINVAL;
1104 if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq) 1275 }
1276 if ((flags & NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ) && !rx_seq) {
1277 devdbg(usbdev, "add_wpa_key: recv seq flag without buffer");
1105 return -EINVAL; 1278 return -EINVAL;
1106 if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !addr) 1279 }
1280 is_addr_ok = addr && memcmp(addr, zero_bssid, ETH_ALEN) != 0 &&
1281 memcmp(addr, ffff_bssid, ETH_ALEN) != 0;
1282 if ((flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) && !is_addr_ok) {
1283 devdbg(usbdev, "add_wpa_key: pairwise but bssid invalid (%pM)",
1284 addr);
1107 return -EINVAL; 1285 return -EINVAL;
1286 }
1108 1287
1109 devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index, 1288 devdbg(usbdev, "add_wpa_key(%i): flags:%i%i%i", index,
1110 !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY), 1289 !!(flags & NDIS_80211_ADDKEY_TRANSMIT_KEY),
@@ -1118,7 +1297,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1118 ndis_key.length = cpu_to_le32(key_len); 1297 ndis_key.length = cpu_to_le32(key_len);
1119 ndis_key.index = cpu_to_le32(index) | flags; 1298 ndis_key.index = cpu_to_le32(index) | flags;
1120 1299
1121 if (alg == IW_ENCODE_ALG_TKIP && key_len == 32) { 1300 if (cipher == WLAN_CIPHER_SUITE_TKIP && key_len == 32) {
1122 /* wpa_supplicant gives us the Michael MIC RX/TX keys in 1301 /* wpa_supplicant gives us the Michael MIC RX/TX keys in
1123 * different order than NDIS spec, so swap the order here. */ 1302 * different order than NDIS spec, so swap the order here. */
1124 memcpy(ndis_key.material, key, 16); 1303 memcpy(ndis_key.material, key, 16);
@@ -1132,7 +1311,7 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1132 1311
1133 if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) { 1312 if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY) {
1134 /* pairwise key */ 1313 /* pairwise key */
1135 memcpy(ndis_key.bssid, addr->sa_data, ETH_ALEN); 1314 memcpy(ndis_key.bssid, addr, ETH_ALEN);
1136 } else { 1315 } else {
1137 /* group key */ 1316 /* group key */
1138 if (priv->infra_mode == NDIS_80211_INFRA_ADHOC) 1317 if (priv->infra_mode == NDIS_80211_INFRA_ADHOC)
@@ -1147,8 +1326,14 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1147 if (ret != 0) 1326 if (ret != 0)
1148 return ret; 1327 return ret;
1149 1328
1150 priv->encr_key_len[index] = key_len; 1329 memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index]));
1151 priv->encr_key_wpa[index] = 1; 1330 priv->encr_keys[index].len = key_len;
1331 priv->encr_keys[index].cipher = cipher;
1332 memcpy(&priv->encr_keys[index].material, key, key_len);
1333 if (flags & NDIS_80211_ADDKEY_PAIRWISE_KEY)
1334 memcpy(&priv->encr_keys[index].bssid, ndis_key.bssid, ETH_ALEN);
1335 else
1336 memset(&priv->encr_keys[index].bssid, 0xff, ETH_ALEN);
1152 1337
1153 if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY) 1338 if (flags & NDIS_80211_ADDKEY_TRANSMIT_KEY)
1154 priv->encr_tx_key_index = index; 1339 priv->encr_tx_key_index = index;
@@ -1157,25 +1342,74 @@ static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len,
1157} 1342}
1158 1343
1159 1344
1345static int restore_key(struct usbnet *usbdev, int key_idx)
1346{
1347 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1348 struct rndis_wlan_encr_key key;
1349 int flags;
1350
1351 key = priv->encr_keys[key_idx];
1352
1353 devdbg(usbdev, "restore_key: %i:%s:%i", key_idx,
1354 is_wpa_key(priv, key_idx) ? "wpa" : "wep",
1355 key.len);
1356
1357 if (key.len == 0)
1358 return 0;
1359
1360 if (is_wpa_key(priv, key_idx)) {
1361 flags = 0;
1362
1363 /*if (priv->encr_tx_key_index == key_idx)
1364 flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY;*/
1365
1366 if (memcmp(key.bssid, zero_bssid, ETH_ALEN) != 0 &&
1367 memcmp(key.bssid, ffff_bssid, ETH_ALEN) != 0)
1368 flags |= NDIS_80211_ADDKEY_PAIRWISE_KEY;
1369
1370 return add_wpa_key(usbdev, key.material, key.len, key_idx,
1371 key.bssid, NULL, key.cipher, flags);
1372 }
1373
1374 return add_wep_key(usbdev, key.material, key.len, key_idx);
1375}
1376
1377
1378static void restore_keys(struct usbnet *usbdev)
1379{
1380 int i;
1381
1382 for (i = 0; i < 4; i++)
1383 restore_key(usbdev, i);
1384}
1385
1386
1387static void clear_key(struct rndis_wlan_private *priv, int idx)
1388{
1389 memset(&priv->encr_keys[idx], 0, sizeof(priv->encr_keys[idx]));
1390}
1391
1392
1160/* remove_key is for both wep and wpa */ 1393/* remove_key is for both wep and wpa */
1161static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) 1394static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN])
1162{ 1395{
1163 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1396 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1164 struct ndis_80211_remove_key remove_key; 1397 struct ndis_80211_remove_key remove_key;
1165 __le32 keyindex; 1398 __le32 keyindex;
1399 bool is_wpa;
1166 int ret; 1400 int ret;
1167 1401
1168 if (priv->encr_key_len[index] == 0) 1402 if (priv->encr_keys[index].len == 0)
1169 return 0; 1403 return 0;
1170 1404
1171 priv->encr_key_len[index] = 0; 1405 is_wpa = is_wpa_key(priv, index);
1172 priv->encr_key_wpa[index] = 0; 1406
1173 memset(&priv->encr_keys[index], 0, sizeof(priv->encr_keys[index])); 1407 devdbg(usbdev, "remove_key: %i:%s:%i", index, is_wpa ? "wpa" : "wep",
1408 priv->encr_keys[index].len);
1409
1410 clear_key(priv, index);
1174 1411
1175 if (priv->wpa_cipher_pair == IW_AUTH_CIPHER_TKIP || 1412 if (is_wpa) {
1176 priv->wpa_cipher_pair == IW_AUTH_CIPHER_CCMP ||
1177 priv->wpa_cipher_group == IW_AUTH_CIPHER_TKIP ||
1178 priv->wpa_cipher_group == IW_AUTH_CIPHER_CCMP) {
1179 remove_key.size = cpu_to_le32(sizeof(remove_key)); 1413 remove_key.size = cpu_to_le32(sizeof(remove_key));
1180 remove_key.index = cpu_to_le32(index); 1414 remove_key.index = cpu_to_le32(index);
1181 if (bssid) { 1415 if (bssid) {
@@ -1484,6 +1718,9 @@ static void rndis_get_scan_results(struct work_struct *work)
1484 1718
1485 devdbg(usbdev, "get_scan_results"); 1719 devdbg(usbdev, "get_scan_results");
1486 1720
1721 if (!priv->scan_request)
1722 return;
1723
1487 ret = rndis_check_bssid_list(usbdev); 1724 ret = rndis_check_bssid_list(usbdev);
1488 1725
1489 cfg80211_scan_done(priv->scan_request, ret < 0); 1726 cfg80211_scan_done(priv->scan_request, ret < 0);
@@ -1716,8 +1953,9 @@ static int rndis_iw_set_encode(struct net_device *dev,
1716{ 1953{
1717 struct usbnet *usbdev = netdev_priv(dev); 1954 struct usbnet *usbdev = netdev_priv(dev);
1718 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 1955 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1956 struct rndis_wlan_encr_key key;
1719 int ret, index, key_len; 1957 int ret, index, key_len;
1720 u8 *key; 1958 u8 *keybuf;
1721 1959
1722 index = (wrqu->encoding.flags & IW_ENCODE_INDEX); 1960 index = (wrqu->encoding.flags & IW_ENCODE_INDEX);
1723 1961
@@ -1752,17 +1990,18 @@ static int rndis_iw_set_encode(struct net_device *dev,
1752 1990
1753 if (wrqu->data.length > 0) { 1991 if (wrqu->data.length > 0) {
1754 key_len = wrqu->data.length; 1992 key_len = wrqu->data.length;
1755 key = extra; 1993 keybuf = extra;
1756 } else { 1994 } else {
1757 /* must be set as tx key */ 1995 /* must be set as tx key */
1758 if (priv->encr_key_len[index] == 0) 1996 if (priv->encr_keys[index].len == 0)
1759 return -EINVAL; 1997 return -EINVAL;
1760 key_len = priv->encr_key_len[index];
1761 key = priv->encr_keys[index]; 1998 key = priv->encr_keys[index];
1999 key_len = key.len;
2000 keybuf = key.material;
1762 priv->encr_tx_key_index = index; 2001 priv->encr_tx_key_index = index;
1763 } 2002 }
1764 2003
1765 if (add_wep_key(usbdev, key, key_len, index) != 0) 2004 if (add_wep_key(usbdev, keybuf, key_len, index) != 0)
1766 return -EINVAL; 2005 return -EINVAL;
1767 2006
1768 if (index == priv->encr_tx_key_index) 2007 if (index == priv->encr_tx_key_index)
@@ -1779,7 +2018,7 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
1779 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra; 2018 struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
1780 struct usbnet *usbdev = netdev_priv(dev); 2019 struct usbnet *usbdev = netdev_priv(dev);
1781 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2020 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
1782 int keyidx, flags; 2021 int keyidx, flags, cipher;
1783 2022
1784 keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX; 2023 keyidx = wrqu->encoding.flags & IW_ENCODE_INDEX;
1785 2024
@@ -1789,8 +2028,10 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
1789 else 2028 else
1790 keyidx = priv->encr_tx_key_index; 2029 keyidx = priv->encr_tx_key_index;
1791 2030
1792 if (keyidx < 0 || keyidx >= 4) 2031 if (keyidx < 0 || keyidx >= 4) {
2032 devwarn(usbdev, "encryption index out of range (%u)", keyidx);
1793 return -EINVAL; 2033 return -EINVAL;
2034 }
1794 2035
1795 if (ext->alg == WPA_ALG_WEP) { 2036 if (ext->alg == WPA_ALG_WEP) {
1796 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 2037 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
@@ -1798,10 +2039,19 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
1798 return add_wep_key(usbdev, ext->key, ext->key_len, keyidx); 2039 return add_wep_key(usbdev, ext->key, ext->key_len, keyidx);
1799 } 2040 }
1800 2041
2042 cipher = -1;
2043 if (ext->alg == IW_ENCODE_ALG_TKIP)
2044 cipher = WLAN_CIPHER_SUITE_TKIP;
2045 else if (ext->alg == IW_ENCODE_ALG_CCMP)
2046 cipher = WLAN_CIPHER_SUITE_CCMP;
2047
1801 if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) || 2048 if ((wrqu->encoding.flags & IW_ENCODE_DISABLED) ||
1802 ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0) 2049 ext->alg == IW_ENCODE_ALG_NONE || ext->key_len == 0)
1803 return remove_key(usbdev, keyidx, NULL); 2050 return remove_key(usbdev, keyidx, NULL);
1804 2051
2052 if (cipher == -1)
2053 return -EOPNOTSUPP;
2054
1805 flags = 0; 2055 flags = 0;
1806 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID) 2056 if (ext->ext_flags & IW_ENCODE_EXT_RX_SEQ_VALID)
1807 flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ; 2057 flags |= NDIS_80211_ADDKEY_SET_INIT_RECV_SEQ;
@@ -1810,8 +2060,9 @@ static int rndis_iw_set_encode_ext(struct net_device *dev,
1810 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) 2060 if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY)
1811 flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY; 2061 flags |= NDIS_80211_ADDKEY_TRANSMIT_KEY;
1812 2062
1813 return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx, &ext->addr, 2063 return add_wpa_key(usbdev, ext->key, ext->key_len, keyidx,
1814 ext->rx_seq, ext->alg, flags); 2064 (u8 *)&ext->addr.sa_data, ext->rx_seq, cipher,
2065 flags);
1815} 2066}
1816 2067
1817 2068
@@ -2104,13 +2355,216 @@ static void rndis_wlan_set_multicast_list(struct net_device *dev)
2104 queue_work(priv->workqueue, &priv->work); 2355 queue_work(priv->workqueue, &priv->work);
2105} 2356}
2106 2357
2107static void rndis_wlan_link_change(struct usbnet *usbdev, int state) 2358
2359static void rndis_wlan_auth_indication(struct usbnet *usbdev,
2360 struct ndis_80211_status_indication *indication,
2361 int len)
2362{
2363 u8 *buf;
2364 const char *type;
2365 int flags, buflen;
2366 bool pairwise_error, group_error;
2367 struct ndis_80211_auth_request *auth_req;
2368
2369 /* must have at least one array entry */
2370 if (len < offsetof(struct ndis_80211_status_indication, u) +
2371 sizeof(struct ndis_80211_auth_request)) {
2372 devinfo(usbdev, "authentication indication: "
2373 "too short message (%i)", len);
2374 return;
2375 }
2376
2377 buf = (void *)&indication->u.auth_request[0];
2378 buflen = len - offsetof(struct ndis_80211_status_indication, u);
2379
2380 while (buflen >= sizeof(*auth_req)) {
2381 auth_req = (void *)buf;
2382 type = "unknown";
2383 flags = le32_to_cpu(auth_req->flags);
2384 pairwise_error = false;
2385 group_error = false;
2386
2387 if (flags & 0x1)
2388 type = "reauth request";
2389 if (flags & 0x2)
2390 type = "key update request";
2391 if (flags & 0x6) {
2392 pairwise_error = true;
2393 type = "pairwise_error";
2394 }
2395 if (flags & 0xe) {
2396 group_error = true;
2397 type = "group_error";
2398 }
2399
2400 devinfo(usbdev, "authentication indication: %s (0x%08x)", type,
2401 le32_to_cpu(auth_req->flags));
2402
2403 if (pairwise_error || group_error) {
2404 union iwreq_data wrqu;
2405 struct iw_michaelmicfailure micfailure;
2406
2407 memset(&micfailure, 0, sizeof(micfailure));
2408 if (pairwise_error)
2409 micfailure.flags |= IW_MICFAILURE_PAIRWISE;
2410 if (group_error)
2411 micfailure.flags |= IW_MICFAILURE_GROUP;
2412
2413 memcpy(micfailure.src_addr.sa_data, auth_req->bssid,
2414 ETH_ALEN);
2415
2416 memset(&wrqu, 0, sizeof(wrqu));
2417 wrqu.data.length = sizeof(micfailure);
2418 wireless_send_event(usbdev->net, IWEVMICHAELMICFAILURE,
2419 &wrqu, (u8 *)&micfailure);
2420 }
2421
2422 buflen -= le32_to_cpu(auth_req->length);
2423 buf += le32_to_cpu(auth_req->length);
2424 }
2425}
2426
2427static void rndis_wlan_pmkid_cand_list_indication(struct usbnet *usbdev,
2428 struct ndis_80211_status_indication *indication,
2429 int len)
2430{
2431 struct ndis_80211_pmkid_cand_list *cand_list;
2432 int list_len, expected_len, i;
2433
2434 if (len < offsetof(struct ndis_80211_status_indication, u) +
2435 sizeof(struct ndis_80211_pmkid_cand_list)) {
2436 devinfo(usbdev, "pmkid candidate list indication: "
2437 "too short message (%i)", len);
2438 return;
2439 }
2440
2441 list_len = le32_to_cpu(indication->u.cand_list.num_candidates) *
2442 sizeof(struct ndis_80211_pmkid_candidate);
2443 expected_len = sizeof(struct ndis_80211_pmkid_cand_list) + list_len +
2444 offsetof(struct ndis_80211_status_indication, u);
2445
2446 if (len < expected_len) {
2447 devinfo(usbdev, "pmkid candidate list indication: "
2448 "list larger than buffer (%i < %i)",
2449 len, expected_len);
2450 return;
2451 }
2452
2453 cand_list = &indication->u.cand_list;
2454
2455 devinfo(usbdev, "pmkid candidate list indication: "
2456 "version %i, candidates %i",
2457 le32_to_cpu(cand_list->version),
2458 le32_to_cpu(cand_list->num_candidates));
2459
2460 if (le32_to_cpu(cand_list->version) != 1)
2461 return;
2462
2463 for (i = 0; i < le32_to_cpu(cand_list->num_candidates); i++) {
2464 struct iw_pmkid_cand pcand;
2465 union iwreq_data wrqu;
2466 struct ndis_80211_pmkid_candidate *cand =
2467 &cand_list->candidate_list[i];
2468
2469 devdbg(usbdev, "cand[%i]: flags: 0x%08x, bssid: %pM",
2470 i, le32_to_cpu(cand->flags), cand->bssid);
2471
2472 memset(&pcand, 0, sizeof(pcand));
2473 if (le32_to_cpu(cand->flags) & 0x01)
2474 pcand.flags |= IW_PMKID_CAND_PREAUTH;
2475 pcand.index = i;
2476 memcpy(pcand.bssid.sa_data, cand->bssid, ETH_ALEN);
2477
2478 memset(&wrqu, 0, sizeof(wrqu));
2479 wrqu.data.length = sizeof(pcand);
2480 wireless_send_event(usbdev->net, IWEVPMKIDCAND, &wrqu,
2481 (u8 *)&pcand);
2482 }
2483}
2484
2485static void rndis_wlan_media_specific_indication(struct usbnet *usbdev,
2486 struct rndis_indicate *msg, int buflen)
2487{
2488 struct ndis_80211_status_indication *indication;
2489 int len, offset;
2490
2491 offset = offsetof(struct rndis_indicate, status) +
2492 le32_to_cpu(msg->offset);
2493 len = le32_to_cpu(msg->length);
2494
2495 if (len < 8) {
2496 devinfo(usbdev, "media specific indication, "
2497 "ignore too short message (%i < 8)", len);
2498 return;
2499 }
2500
2501 if (offset + len > buflen) {
2502 devinfo(usbdev, "media specific indication, "
2503 "too large to fit to buffer (%i > %i)",
2504 offset + len, buflen);
2505 return;
2506 }
2507
2508 indication = (void *)((u8 *)msg + offset);
2509
2510 switch (le32_to_cpu(indication->status_type)) {
2511 case NDIS_80211_STATUSTYPE_RADIOSTATE:
2512 devinfo(usbdev, "radio state indication: %i",
2513 le32_to_cpu(indication->u.radio_status));
2514 return;
2515
2516 case NDIS_80211_STATUSTYPE_MEDIASTREAMMODE:
2517 devinfo(usbdev, "media stream mode indication: %i",
2518 le32_to_cpu(indication->u.media_stream_mode));
2519 return;
2520
2521 case NDIS_80211_STATUSTYPE_AUTHENTICATION:
2522 rndis_wlan_auth_indication(usbdev, indication, len);
2523 return;
2524
2525 case NDIS_80211_STATUSTYPE_PMKID_CANDIDATELIST:
2526 rndis_wlan_pmkid_cand_list_indication(usbdev, indication, len);
2527 return;
2528
2529 default:
2530 devinfo(usbdev, "media specific indication: "
2531 "unknown status type 0x%08x",
2532 le32_to_cpu(indication->status_type));
2533 }
2534}
2535
2536
2537static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
2108{ 2538{
2109 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev); 2539 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2540 struct rndis_indicate *msg = ind;
2110 2541
2111 /* queue work to avoid recursive calls into rndis_command */ 2542 switch (msg->status) {
2112 set_bit(state ? WORK_LINK_UP : WORK_LINK_DOWN, &priv->work_pending); 2543 case RNDIS_STATUS_MEDIA_CONNECT:
2113 queue_work(priv->workqueue, &priv->work); 2544 devinfo(usbdev, "media connect");
2545
2546 /* queue work to avoid recursive calls into rndis_command */
2547 set_bit(WORK_LINK_UP, &priv->work_pending);
2548 queue_work(priv->workqueue, &priv->work);
2549 break;
2550
2551 case RNDIS_STATUS_MEDIA_DISCONNECT:
2552 devinfo(usbdev, "media disconnect");
2553
2554 /* queue work to avoid recursive calls into rndis_command */
2555 set_bit(WORK_LINK_DOWN, &priv->work_pending);
2556 queue_work(priv->workqueue, &priv->work);
2557 break;
2558
2559 case RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION:
2560 rndis_wlan_media_specific_indication(usbdev, msg, buflen);
2561 break;
2562
2563 default:
2564 devinfo(usbdev, "indication: 0x%08x",
2565 le32_to_cpu(msg->status));
2566 break;
2567 }
2114} 2568}
2115 2569
2116 2570
@@ -2457,9 +2911,6 @@ static int rndis_wlan_bind(struct usbnet *usbdev, struct usb_interface *intf)
2457 disassociate(usbdev, 1); 2911 disassociate(usbdev, 1);
2458 netif_carrier_off(usbdev->net); 2912 netif_carrier_off(usbdev->net);
2459 2913
2460 queue_delayed_work(priv->workqueue, &priv->stats_work,
2461 round_jiffies_relative(STATS_UPDATE_JIFFIES));
2462
2463 return 0; 2914 return 0;
2464 2915
2465fail: 2916fail:
@@ -2499,21 +2950,61 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf)
2499 2950
2500static int rndis_wlan_reset(struct usbnet *usbdev) 2951static int rndis_wlan_reset(struct usbnet *usbdev)
2501{ 2952{
2953 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2954 int retval;
2955
2502 devdbg(usbdev, "rndis_wlan_reset"); 2956 devdbg(usbdev, "rndis_wlan_reset");
2957
2958 retval = rndis_reset(usbdev);
2959 if (retval)
2960 devwarn(usbdev, "rndis_reset() failed: %d", retval);
2961
2962 /* rndis_reset cleared multicast list, so restore here.
2963 (set_multicast_list() also turns on current packet filter) */
2964 set_multicast_list(usbdev);
2965
2966 queue_delayed_work(priv->workqueue, &priv->stats_work,
2967 round_jiffies_relative(STATS_UPDATE_JIFFIES));
2968
2503 return deauthenticate(usbdev); 2969 return deauthenticate(usbdev);
2504} 2970}
2505 2971
2506 2972
2507static int rndis_wlan_stop(struct usbnet *usbdev) 2973static int rndis_wlan_stop(struct usbnet *usbdev)
2508{ 2974{
2975 struct rndis_wlan_private *priv = get_rndis_wlan_priv(usbdev);
2976 int retval;
2977 __le32 filter;
2978
2509 devdbg(usbdev, "rndis_wlan_stop"); 2979 devdbg(usbdev, "rndis_wlan_stop");
2510 return disassociate(usbdev, 0); 2980
2981 retval = disassociate(usbdev, 0);
2982
2983 priv->work_pending = 0;
2984 cancel_delayed_work_sync(&priv->stats_work);
2985 cancel_delayed_work_sync(&priv->scan_work);
2986 cancel_work_sync(&priv->work);
2987 flush_workqueue(priv->workqueue);
2988
2989 if (priv->scan_request) {
2990 cfg80211_scan_done(priv->scan_request, true);
2991 priv->scan_request = NULL;
2992 }
2993
2994 /* Set current packet filter zero to block receiving data packets from
2995 device. */
2996 filter = 0;
2997 rndis_set_oid(usbdev, OID_GEN_CURRENT_PACKET_FILTER, &filter,
2998 sizeof(filter));
2999
3000 return retval;
2511} 3001}
2512 3002
2513 3003
2514static const struct driver_info bcm4320b_info = { 3004static const struct driver_info bcm4320b_info = {
2515 .description = "Wireless RNDIS device, BCM4320b based", 3005 .description = "Wireless RNDIS device, BCM4320b based",
2516 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, 3006 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
3007 FLAG_AVOID_UNLINK_URBS,
2517 .bind = rndis_wlan_bind, 3008 .bind = rndis_wlan_bind,
2518 .unbind = rndis_wlan_unbind, 3009 .unbind = rndis_wlan_unbind,
2519 .status = rndis_status, 3010 .status = rndis_status,
@@ -2522,12 +3013,13 @@ static const struct driver_info bcm4320b_info = {
2522 .reset = rndis_wlan_reset, 3013 .reset = rndis_wlan_reset,
2523 .stop = rndis_wlan_stop, 3014 .stop = rndis_wlan_stop,
2524 .early_init = bcm4320b_early_init, 3015 .early_init = bcm4320b_early_init,
2525 .link_change = rndis_wlan_link_change, 3016 .indication = rndis_wlan_indication,
2526}; 3017};
2527 3018
2528static const struct driver_info bcm4320a_info = { 3019static const struct driver_info bcm4320a_info = {
2529 .description = "Wireless RNDIS device, BCM4320a based", 3020 .description = "Wireless RNDIS device, BCM4320a based",
2530 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, 3021 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
3022 FLAG_AVOID_UNLINK_URBS,
2531 .bind = rndis_wlan_bind, 3023 .bind = rndis_wlan_bind,
2532 .unbind = rndis_wlan_unbind, 3024 .unbind = rndis_wlan_unbind,
2533 .status = rndis_status, 3025 .status = rndis_status,
@@ -2536,12 +3028,13 @@ static const struct driver_info bcm4320a_info = {
2536 .reset = rndis_wlan_reset, 3028 .reset = rndis_wlan_reset,
2537 .stop = rndis_wlan_stop, 3029 .stop = rndis_wlan_stop,
2538 .early_init = bcm4320a_early_init, 3030 .early_init = bcm4320a_early_init,
2539 .link_change = rndis_wlan_link_change, 3031 .indication = rndis_wlan_indication,
2540}; 3032};
2541 3033
2542static const struct driver_info rndis_wlan_info = { 3034static const struct driver_info rndis_wlan_info = {
2543 .description = "Wireless RNDIS device", 3035 .description = "Wireless RNDIS device",
2544 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT, 3036 .flags = FLAG_WLAN | FLAG_FRAMING_RN | FLAG_NO_SETINT |
3037 FLAG_AVOID_UNLINK_URBS,
2545 .bind = rndis_wlan_bind, 3038 .bind = rndis_wlan_bind,
2546 .unbind = rndis_wlan_unbind, 3039 .unbind = rndis_wlan_unbind,
2547 .status = rndis_status, 3040 .status = rndis_status,
@@ -2550,7 +3043,7 @@ static const struct driver_info rndis_wlan_info = {
2550 .reset = rndis_wlan_reset, 3043 .reset = rndis_wlan_reset,
2551 .stop = rndis_wlan_stop, 3044 .stop = rndis_wlan_stop,
2552 .early_init = bcm4320a_early_init, 3045 .early_init = bcm4320a_early_init,
2553 .link_change = rndis_wlan_link_change, 3046 .indication = rndis_wlan_indication,
2554}; 3047};
2555 3048
2556/*-------------------------------------------------------------------------*/ 3049/*-------------------------------------------------------------------------*/
diff --git a/drivers/net/wireless/rt2x00/Kconfig b/drivers/net/wireless/rt2x00/Kconfig
index f970aa25326a..ed1f997e3521 100644
--- a/drivers/net/wireless/rt2x00/Kconfig
+++ b/drivers/net/wireless/rt2x00/Kconfig
@@ -1,8 +1,8 @@
1menuconfig RT2X00 1menuconfig RT2X00
2 tristate "Ralink driver support" 2 tristate "Ralink driver support"
3 depends on MAC80211 && WLAN_80211 && EXPERIMENTAL 3 depends on MAC80211 && WLAN_80211
4 ---help--- 4 ---help---
5 This will enable the experimental support for the Ralink drivers, 5 This will enable the support for the Ralink drivers,
6 developed in the rt2x00 project <http://rt2x00.serialmonkey.com>. 6 developed in the rt2x00 project <http://rt2x00.serialmonkey.com>.
7 7
8 These drivers make use of the mac80211 stack. 8 These drivers make use of the mac80211 stack.
@@ -79,14 +79,14 @@ config RT73USB
79 79
80config RT2800USB 80config RT2800USB
81 tristate "Ralink rt2800 (USB) support" 81 tristate "Ralink rt2800 (USB) support"
82 depends on USB 82 depends on USB && EXPERIMENTAL
83 select RT2X00_LIB_USB 83 select RT2X00_LIB_USB
84 select RT2X00_LIB_HT 84 select RT2X00_LIB_HT
85 select RT2X00_LIB_FIRMWARE 85 select RT2X00_LIB_FIRMWARE
86 select RT2X00_LIB_CRYPTO 86 select RT2X00_LIB_CRYPTO
87 select CRC_CCITT 87 select CRC_CCITT
88 ---help--- 88 ---help---
89 This adds support for rt2800 wireless chipset family. 89 This adds experimental support for rt2800 wireless chipset family.
90 Supported chips: RT2770, RT2870 & RT3070. 90 Supported chips: RT2770, RT2870 & RT3070.
91 91
92 When compiled as a module, this driver will be called "rt2800usb.ko". 92 When compiled as a module, this driver will be called "rt2800usb.ko".
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 658a63bfb761..db54fcc94c8f 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -215,7 +215,7 @@ void rt2x00lib_beacondone(struct rt2x00_dev *rt2x00dev)
215 rt2x00lib_beacondone_iter, 215 rt2x00lib_beacondone_iter,
216 rt2x00dev); 216 rt2x00dev);
217 217
218 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->intf_work); 218 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->intf_work);
219} 219}
220EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); 220EXPORT_SYMBOL_GPL(rt2x00lib_beacondone);
221 221
@@ -893,6 +893,12 @@ void rt2x00lib_remove_dev(struct rt2x00_dev *rt2x00dev)
893 rt2x00lib_disable_radio(rt2x00dev); 893 rt2x00lib_disable_radio(rt2x00dev);
894 894
895 /* 895 /*
896 * Stop all work.
897 */
898 cancel_work_sync(&rt2x00dev->filter_work);
899 cancel_work_sync(&rt2x00dev->intf_work);
900
901 /*
896 * Uninitialize device. 902 * Uninitialize device.
897 */ 903 */
898 rt2x00lib_uninitialize(rt2x00dev); 904 rt2x00lib_uninitialize(rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index 79915687e744..917831689ccd 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -351,8 +351,8 @@ void rt2x00link_start_tuner(struct rt2x00_dev *rt2x00dev)
351 351
352 rt2x00link_reset_tuner(rt2x00dev, false); 352 rt2x00link_reset_tuner(rt2x00dev, false);
353 353
354 queue_delayed_work(rt2x00dev->hw->workqueue, 354 ieee80211_queue_delayed_work(rt2x00dev->hw,
355 &link->work, LINK_TUNE_INTERVAL); 355 &link->work, LINK_TUNE_INTERVAL);
356} 356}
357 357
358void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) 358void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev)
@@ -461,8 +461,8 @@ static void rt2x00link_tuner(struct work_struct *work)
461 * Increase tuner counter, and reschedule the next link tuner run. 461 * Increase tuner counter, and reschedule the next link tuner run.
462 */ 462 */
463 link->count++; 463 link->count++;
464 queue_delayed_work(rt2x00dev->hw->workqueue, 464 ieee80211_queue_delayed_work(rt2x00dev->hw,
465 &link->work, LINK_TUNE_INTERVAL); 465 &link->work, LINK_TUNE_INTERVAL);
466} 466}
467 467
468void rt2x00link_register(struct rt2x00_dev *rt2x00dev) 468void rt2x00link_register(struct rt2x00_dev *rt2x00dev)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index 7de1a2cdcf8c..81febdfd6639 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -431,10 +431,20 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
431 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags)) 431 if (!test_bit(DRIVER_REQUIRE_SCHEDULED, &rt2x00dev->flags))
432 rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags); 432 rt2x00dev->ops->lib->config_filter(rt2x00dev, *total_flags);
433 else 433 else
434 queue_work(rt2x00dev->hw->workqueue, &rt2x00dev->filter_work); 434 ieee80211_queue_work(rt2x00dev->hw, &rt2x00dev->filter_work);
435} 435}
436EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); 436EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter);
437 437
438int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
439 bool set)
440{
441 struct rt2x00_dev *rt2x00dev = hw->priv;
442
443 rt2x00lib_beacondone(rt2x00dev);
444 return 0;
445}
446EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);
447
438#ifdef CONFIG_RT2X00_LIB_CRYPTO 448#ifdef CONFIG_RT2X00_LIB_CRYPTO
439static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len) 449static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
440{ 450{
@@ -454,16 +464,6 @@ static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
454 sizeof(crypto->rx_mic)); 464 sizeof(crypto->rx_mic));
455} 465}
456 466
457int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
458 bool set)
459{
460 struct rt2x00_dev *rt2x00dev = hw->priv;
461
462 rt2x00lib_beacondone(rt2x00dev);
463 return 0;
464}
465EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);
466
467int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 467int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
468 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 468 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
469 struct ieee80211_key_conf *key) 469 struct ieee80211_key_conf *key)
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index fb95b8cc4fe9..e20dd7431f21 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2601,6 +2601,11 @@ static int rt61pci_probe_hw(struct rt2x00_dev *rt2x00dev)
2601 int retval; 2601 int retval;
2602 2602
2603 /* 2603 /*
2604 * Disable power saving.
2605 */
2606 rt2x00pci_register_write(rt2x00dev, SOFT_RESET_CSR, 0x00000007);
2607
2608 /*
2604 * Allocate eeprom data. 2609 * Allocate eeprom data.
2605 */ 2610 */
2606 retval = rt61pci_validate_eeprom(rt2x00dev); 2611 retval = rt61pci_validate_eeprom(rt2x00dev);
diff --git a/drivers/net/wireless/rtl818x/rtl8187_dev.c b/drivers/net/wireless/rtl818x/rtl8187_dev.c
index c9b9dbe584c6..53f57dc52226 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_dev.c
@@ -220,7 +220,7 @@ static void rtl8187_tx_cb(struct urb *urb)
220 * reading a register in the device. We are in interrupt mode 220 * reading a register in the device. We are in interrupt mode
221 * here, thus queue the skb and finish on a work queue. */ 221 * here, thus queue the skb and finish on a work queue. */
222 skb_queue_tail(&priv->b_tx_status.queue, skb); 222 skb_queue_tail(&priv->b_tx_status.queue, skb);
223 queue_delayed_work(hw->workqueue, &priv->work, 0); 223 ieee80211_queue_delayed_work(hw, &priv->work, 0);
224 } 224 }
225} 225}
226 226
diff --git a/drivers/net/wireless/rtl818x/rtl8187_leds.c b/drivers/net/wireless/rtl818x/rtl8187_leds.c
index cf9f899fe0e6..a6cfb7e77994 100644
--- a/drivers/net/wireless/rtl818x/rtl8187_leds.c
+++ b/drivers/net/wireless/rtl818x/rtl8187_leds.c
@@ -108,11 +108,11 @@ static void rtl8187_led_brightness_set(struct led_classdev *led_dev,
108 struct rtl8187_priv *priv = hw->priv; 108 struct rtl8187_priv *priv = hw->priv;
109 109
110 if (brightness == LED_OFF) { 110 if (brightness == LED_OFF) {
111 queue_delayed_work(hw->workqueue, &priv->led_off, 0); 111 ieee80211_queue_delayed_work(hw, &priv->led_off, 0);
112 /* The LED is off for 1/20 sec so that it just blinks. */ 112 /* The LED is off for 1/20 sec so that it just blinks. */
113 queue_delayed_work(hw->workqueue, &priv->led_on, HZ / 20); 113 ieee80211_queue_delayed_work(hw, &priv->led_on, HZ / 20);
114 } else 114 } else
115 queue_delayed_work(hw->workqueue, &priv->led_on, 0); 115 ieee80211_queue_delayed_work(hw, &priv->led_on, 0);
116} 116}
117 117
118static int rtl8187_register_led(struct ieee80211_hw *dev, 118static int rtl8187_register_led(struct ieee80211_hw *dev,
@@ -193,7 +193,7 @@ void rtl8187_leds_init(struct ieee80211_hw *dev, u16 custid)
193 err = rtl8187_register_led(dev, &priv->led_rx, name, 193 err = rtl8187_register_led(dev, &priv->led_rx, name,
194 ieee80211_get_rx_led_name(dev), ledpin); 194 ieee80211_get_rx_led_name(dev), ledpin);
195 if (!err) { 195 if (!err) {
196 queue_delayed_work(dev->workqueue, &priv->led_on, 0); 196 ieee80211_queue_delayed_work(dev, &priv->led_on, 0);
197 return; 197 return;
198 } 198 }
199 /* registration of RX LED failed - unregister TX */ 199 /* registration of RX LED failed - unregister TX */
@@ -209,7 +209,7 @@ void rtl8187_leds_exit(struct ieee80211_hw *dev)
209 struct rtl8187_priv *priv = dev->priv; 209 struct rtl8187_priv *priv = dev->priv;
210 210
211 /* turn the LED off before exiting */ 211 /* turn the LED off before exiting */
212 queue_delayed_work(dev->workqueue, &priv->led_off, 0); 212 ieee80211_queue_delayed_work(dev, &priv->led_off, 0);
213 cancel_delayed_work_sync(&priv->led_off); 213 cancel_delayed_work_sync(&priv->led_off);
214 cancel_delayed_work_sync(&priv->led_on); 214 cancel_delayed_work_sync(&priv->led_on);
215 rtl8187_unregister_led(&priv->led_rx); 215 rtl8187_unregister_led(&priv->led_rx);
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 73300c226f67..ef2cb20e96ad 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -1550,9 +1550,12 @@ static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
1550 1550
1551 if (time_after(jiffies, strip_info->pps_timer + HZ)) { 1551 if (time_after(jiffies, strip_info->pps_timer + HZ)) {
1552 unsigned long t = jiffies - strip_info->pps_timer; 1552 unsigned long t = jiffies - strip_info->pps_timer;
1553 unsigned long rx_pps_count = (strip_info->rx_pps_count * HZ * 8 + t / 2) / t; 1553 unsigned long rx_pps_count =
1554 unsigned long tx_pps_count = (strip_info->tx_pps_count * HZ * 8 + t / 2) / t; 1554 DIV_ROUND_CLOSEST(strip_info->rx_pps_count*HZ*8, t);
1555 unsigned long sx_pps_count = (strip_info->sx_pps_count * HZ * 8 + t / 2) / t; 1555 unsigned long tx_pps_count =
1556 DIV_ROUND_CLOSEST(strip_info->tx_pps_count*HZ*8, t);
1557 unsigned long sx_pps_count =
1558 DIV_ROUND_CLOSEST(strip_info->sx_pps_count*HZ*8, t);
1556 1559
1557 strip_info->pps_timer = jiffies; 1560 strip_info->pps_timer = jiffies;
1558 strip_info->rx_pps_count = 0; 1561 strip_info->rx_pps_count = 0;
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 9600b72495da..54abdd0c0045 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -698,7 +698,7 @@ int zd_mac_rx(struct ieee80211_hw *hw, const u8 *buffer, unsigned int length)
698 && !mac->pass_ctrl) 698 && !mac->pass_ctrl)
699 return 0; 699 return 0;
700 700
701 fc = *(__le16 *)buffer; 701 fc = get_unaligned((__le16*)buffer);
702 need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc); 702 need_padding = ieee80211_is_data_qos(fc) ^ ieee80211_has_a4(fc);
703 703
704 skb = dev_alloc_skb(length + (need_padding ? 2 : 0)); 704 skb = dev_alloc_skb(length + (need_padding ? 2 : 0));
diff --git a/include/linux/rfkill.h b/include/linux/rfkill.h
index 10202903141a..21ca51bf4dd2 100644
--- a/include/linux/rfkill.h
+++ b/include/linux/rfkill.h
@@ -47,6 +47,7 @@ enum rfkill_type {
47 RFKILL_TYPE_UWB, 47 RFKILL_TYPE_UWB,
48 RFKILL_TYPE_WIMAX, 48 RFKILL_TYPE_WIMAX,
49 RFKILL_TYPE_WWAN, 49 RFKILL_TYPE_WWAN,
50 RFKILL_TYPE_GPS,
50 NUM_RFKILL_TYPES, 51 NUM_RFKILL_TYPES,
51}; 52};
52 53
diff --git a/include/linux/usb/rndis_host.h b/include/linux/usb/rndis_host.h
index 37836b937d97..1ef1ebc2b04f 100644
--- a/include/linux/usb/rndis_host.h
+++ b/include/linux/usb/rndis_host.h
@@ -70,12 +70,13 @@ struct rndis_msg_hdr {
70#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION) 70#define RNDIS_MSG_KEEPALIVE_C (RNDIS_MSG_KEEPALIVE|RNDIS_MSG_COMPLETION)
71 71
72/* codes for "status" field of completion messages */ 72/* codes for "status" field of completion messages */
73#define RNDIS_STATUS_SUCCESS cpu_to_le32(0x00000000) 73#define RNDIS_STATUS_SUCCESS cpu_to_le32(0x00000000)
74#define RNDIS_STATUS_FAILURE cpu_to_le32(0xc0000001) 74#define RNDIS_STATUS_FAILURE cpu_to_le32(0xc0000001)
75#define RNDIS_STATUS_INVALID_DATA cpu_to_le32(0xc0010015) 75#define RNDIS_STATUS_INVALID_DATA cpu_to_le32(0xc0010015)
76#define RNDIS_STATUS_NOT_SUPPORTED cpu_to_le32(0xc00000bb) 76#define RNDIS_STATUS_NOT_SUPPORTED cpu_to_le32(0xc00000bb)
77#define RNDIS_STATUS_MEDIA_CONNECT cpu_to_le32(0x4001000b) 77#define RNDIS_STATUS_MEDIA_CONNECT cpu_to_le32(0x4001000b)
78#define RNDIS_STATUS_MEDIA_DISCONNECT cpu_to_le32(0x4001000c) 78#define RNDIS_STATUS_MEDIA_DISCONNECT cpu_to_le32(0x4001000c)
79#define RNDIS_STATUS_MEDIA_SPECIFIC_INDICATION cpu_to_le32(0x40010012)
79 80
80/* codes for OID_GEN_PHYSICAL_MEDIUM */ 81/* codes for OID_GEN_PHYSICAL_MEDIUM */
81#define RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED cpu_to_le32(0x00000000) 82#define RNDIS_PHYSICAL_MEDIUM_UNSPECIFIED cpu_to_le32(0x00000000)
diff --git a/include/linux/usb/usbnet.h b/include/linux/usb/usbnet.h
index 7c17b2efba86..de8b4b18961b 100644
--- a/include/linux/usb/usbnet.h
+++ b/include/linux/usb/usbnet.h
@@ -86,6 +86,7 @@ struct driver_info {
86 86
87#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */ 87#define FLAG_FRAMING_AX 0x0040 /* AX88772/178 packets */
88#define FLAG_WLAN 0x0080 /* use "wlan%d" names */ 88#define FLAG_WLAN 0x0080 /* use "wlan%d" names */
89#define FLAG_AVOID_UNLINK_URBS 0x0100 /* don't unlink urbs at usbnet_stop() */
89 90
90 91
91 /* init device ... can sleep, or cause probe() failure */ 92 /* init device ... can sleep, or cause probe() failure */
@@ -121,9 +122,8 @@ struct driver_info {
121 * right after minidriver have initialized hardware. */ 122 * right after minidriver have initialized hardware. */
122 int (*early_init)(struct usbnet *dev); 123 int (*early_init)(struct usbnet *dev);
123 124
124 /* called by minidriver when link state changes, state: 0=disconnect, 125 /* called by minidriver when receiving indication */
125 * 1=connect */ 126 void (*indication)(struct usbnet *dev, void *ind, int indlen);
126 void (*link_change)(struct usbnet *dev, int state);
127 127
128 /* for new devices, use the descriptor-reading code instead */ 128 /* for new devices, use the descriptor-reading code instead */
129 int in; /* rx endpoint */ 129 int in; /* rx endpoint */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index e1b92358242b..fa729979de88 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -1514,20 +1514,6 @@ unsigned int cfg80211_classify8021d(struct sk_buff *skb);
1514extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2); 1514extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2);
1515 1515
1516/** 1516/**
1517 * regulatory_hint_11d - hints a country IE as a regulatory domain
1518 * @wiphy: the wireless device giving the hint (used only for reporting
1519 * conflicts)
1520 * @country_ie: pointer to the country IE
1521 * @country_ie_len: length of the country IE
1522 *
1523 * We will intersect the rd with the what CRDA tells us should apply
1524 * for the alpha2 this country IE belongs to, this prevents APs from
1525 * sending us incorrect or outdated information against a country.
1526 */
1527extern void regulatory_hint_11d(struct wiphy *wiphy,
1528 u8 *country_ie,
1529 u8 country_ie_len);
1530/**
1531 * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain 1517 * wiphy_apply_custom_regulatory - apply a custom driver regulatory domain
1532 * @wiphy: the wireless device we want to process the regulatory domain on 1518 * @wiphy: the wireless device we want to process the regulatory domain on
1533 * @regd: the custom regulatory domain to use for this wiphy 1519 * @regd: the custom regulatory domain to use for this wiphy
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index d4e09a06b4a2..e2fb5767e1fa 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -73,6 +73,21 @@
73 */ 73 */
74 74
75/** 75/**
76 * DOC: mac80211 workqueue
77 *
78 * mac80211 provides its own workqueue for drivers and internal mac80211 use.
79 * The workqueue is a single threaded workqueue and can only be accessed by
80 * helpers for sanity checking. Drivers must ensure all work added onto the
81 * mac80211 workqueue should be cancelled on the driver stop() callback.
82 *
83 * mac80211 will flushed the workqueue upon interface removal and during
84 * suspend.
85 *
86 * All work performed on the mac80211 workqueue must not acquire the RTNL lock.
87 *
88 */
89
90/**
76 * enum ieee80211_max_queues - maximum number of queues 91 * enum ieee80211_max_queues - maximum number of queues
77 * 92 *
78 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues. 93 * @IEEE80211_MAX_QUEUES: Maximum number of regular device queues.
@@ -913,12 +928,6 @@ enum ieee80211_hw_flags {
913 * 928 *
914 * @conf: &struct ieee80211_conf, device configuration, don't use. 929 * @conf: &struct ieee80211_conf, device configuration, don't use.
915 * 930 *
916 * @workqueue: single threaded workqueue available for driver use,
917 * allocated by mac80211 on registration and flushed when an
918 * interface is removed.
919 * NOTICE: All work performed on this workqueue must not
920 * acquire the RTNL lock.
921 *
922 * @priv: pointer to private area that was allocated for driver use 931 * @priv: pointer to private area that was allocated for driver use
923 * along with this structure. 932 * along with this structure.
924 * 933 *
@@ -954,7 +963,6 @@ enum ieee80211_hw_flags {
954struct ieee80211_hw { 963struct ieee80211_hw {
955 struct ieee80211_conf conf; 964 struct ieee80211_conf conf;
956 struct wiphy *wiphy; 965 struct wiphy *wiphy;
957 struct workqueue_struct *workqueue;
958 const char *rate_control_algorithm; 966 const char *rate_control_algorithm;
959 void *priv; 967 void *priv;
960 u32 flags; 968 u32 flags;
@@ -1236,10 +1244,13 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
1236 * mac80211 needs to do and the amount of CPU wakeups, so you should 1244 * mac80211 needs to do and the amount of CPU wakeups, so you should
1237 * honour this flag if possible. 1245 * honour this flag if possible.
1238 * 1246 *
1239 * @FIF_CONTROL: pass control frames, if PROMISC_IN_BSS is not set then 1247 * @FIF_CONTROL: pass control frames (except for PS Poll), if PROMISC_IN_BSS
1240 * only those addressed to this station 1248 * is not set then only those addressed to this station.
1241 * 1249 *
1242 * @FIF_OTHER_BSS: pass frames destined to other BSSes 1250 * @FIF_OTHER_BSS: pass frames destined to other BSSes
1251 *
1252 * @FIF_PSPOLL: pass PS Poll frames, if PROMISC_IN_BSS is not set then only
1253 * those addressed to this station.
1243 */ 1254 */
1244enum ieee80211_filter_flags { 1255enum ieee80211_filter_flags {
1245 FIF_PROMISC_IN_BSS = 1<<0, 1256 FIF_PROMISC_IN_BSS = 1<<0,
@@ -1249,6 +1260,7 @@ enum ieee80211_filter_flags {
1249 FIF_BCN_PRBRESP_PROMISC = 1<<4, 1260 FIF_BCN_PRBRESP_PROMISC = 1<<4,
1250 FIF_CONTROL = 1<<5, 1261 FIF_CONTROL = 1<<5,
1251 FIF_OTHER_BSS = 1<<6, 1262 FIF_OTHER_BSS = 1<<6,
1263 FIF_PSPOLL = 1<<7,
1252}; 1264};
1253 1265
1254/** 1266/**
@@ -1301,7 +1313,8 @@ enum ieee80211_ampdu_mlme_action {
1301 * is disabled. This should turn off the hardware (at least 1313 * is disabled. This should turn off the hardware (at least
1302 * it must turn off frame reception.) 1314 * it must turn off frame reception.)
1303 * May be called right after add_interface if that rejects 1315 * May be called right after add_interface if that rejects
1304 * an interface. 1316 * an interface. If you added any work onto the mac80211 workqueue
1317 * you should ensure to cancel it on this callback.
1305 * Must be implemented. 1318 * Must be implemented.
1306 * 1319 *
1307 * @add_interface: Called when a netdevice attached to the hardware is 1320 * @add_interface: Called when a netdevice attached to the hardware is
@@ -1928,6 +1941,31 @@ void ieee80211_iterate_active_interfaces_atomic(struct ieee80211_hw *hw,
1928 void *data); 1941 void *data);
1929 1942
1930/** 1943/**
1944 * ieee80211_queue_work - add work onto the mac80211 workqueue
1945 *
1946 * Drivers and mac80211 use this to add work onto the mac80211 workqueue.
1947 * This helper ensures drivers are not queueing work when they should not be.
1948 *
1949 * @hw: the hardware struct for the interface we are adding work for
1950 * @work: the work we want to add onto the mac80211 workqueue
1951 */
1952void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work);
1953
1954/**
1955 * ieee80211_queue_delayed_work - add work onto the mac80211 workqueue
1956 *
1957 * Drivers and mac80211 use this to queue delayed work onto the mac80211
1958 * workqueue.
1959 *
1960 * @hw: the hardware struct for the interface we are adding work for
1961 * @dwork: delayable work to queue onto the mac80211 workqueue
1962 * @delay: number of jiffies to wait before queueing
1963 */
1964void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
1965 struct delayed_work *dwork,
1966 unsigned long delay);
1967
1968/**
1931 * ieee80211_start_tx_ba_session - Start a tx Block Ack session. 1969 * ieee80211_start_tx_ba_session - Start a tx Block Ack session.
1932 * @hw: pointer as obtained from ieee80211_alloc_hw(). 1970 * @hw: pointer as obtained from ieee80211_alloc_hw().
1933 * @ra: receiver address of the BA session recipient 1971 * @ra: receiver address of the BA session recipient
diff --git a/net/mac80211/driver-trace.c b/net/mac80211/driver-trace.c
index 6da6f79932fc..8ed8711b1a6d 100644
--- a/net/mac80211/driver-trace.c
+++ b/net/mac80211/driver-trace.c
@@ -1,6 +1,9 @@
1/* bug in tracepoint.h, it should include this */ 1/* bug in tracepoint.h, it should include this */
2#include <linux/module.h> 2#include <linux/module.h>
3 3
4/* sparse isn't too happy with all macros... */
5#ifndef __CHECKER__
4#include "driver-ops.h" 6#include "driver-ops.h"
5#define CREATE_TRACE_POINTS 7#define CREATE_TRACE_POINTS
6#include "driver-trace.h" 8#include "driver-trace.h"
9#endif
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 6e3cca65c460..920ec8792f4b 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -781,7 +781,7 @@ static void ieee80211_ibss_timer(unsigned long data)
781 } 781 }
782 782
783 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request); 783 set_bit(IEEE80211_IBSS_REQ_RUN, &ifibss->request);
784 queue_work(local->hw.workqueue, &ifibss->work); 784 ieee80211_queue_work(&local->hw, &ifibss->work);
785} 785}
786 786
787#ifdef CONFIG_PM 787#ifdef CONFIG_PM
@@ -853,7 +853,7 @@ ieee80211_ibss_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
853 case IEEE80211_STYPE_PROBE_REQ: 853 case IEEE80211_STYPE_PROBE_REQ:
854 case IEEE80211_STYPE_AUTH: 854 case IEEE80211_STYPE_AUTH:
855 skb_queue_tail(&sdata->u.ibss.skb_queue, skb); 855 skb_queue_tail(&sdata->u.ibss.skb_queue, skb);
856 queue_work(local->hw.workqueue, &sdata->u.ibss.work); 856 ieee80211_queue_work(&local->hw, &sdata->u.ibss.work);
857 return RX_QUEUED; 857 return RX_QUEUED;
858 } 858 }
859 859
@@ -912,7 +912,7 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
912 ieee80211_recalc_idle(sdata->local); 912 ieee80211_recalc_idle(sdata->local);
913 913
914 set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request); 914 set_bit(IEEE80211_IBSS_REQ_RUN, &sdata->u.ibss.request);
915 queue_work(sdata->local->hw.workqueue, &sdata->u.ibss.work); 915 ieee80211_queue_work(&sdata->local->hw, &sdata->u.ibss.work);
916 916
917 return 0; 917 return 0;
918} 918}
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index aec6853cb435..630a438180fd 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -280,6 +280,7 @@ struct ieee80211_if_managed {
280 struct work_struct beacon_loss_work; 280 struct work_struct beacon_loss_work;
281 281
282 unsigned long probe_timeout; 282 unsigned long probe_timeout;
283 int probe_send_count;
283 284
284 struct mutex mtx; 285 struct mutex mtx;
285 struct ieee80211_bss *associated; 286 struct ieee80211_bss *associated;
@@ -614,6 +615,12 @@ struct ieee80211_local {
614 615
615 const struct ieee80211_ops *ops; 616 const struct ieee80211_ops *ops;
616 617
618 /*
619 * private workqueue to mac80211. mac80211 makes this accessible
620 * via ieee80211_queue_work()
621 */
622 struct workqueue_struct *workqueue;
623
617 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES]; 624 unsigned long queue_stop_reasons[IEEE80211_MAX_QUEUES];
618 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ 625 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
619 spinlock_t queue_stop_reason_lock; 626 spinlock_t queue_stop_reason_lock;
@@ -621,7 +628,7 @@ struct ieee80211_local {
621 int open_count; 628 int open_count;
622 int monitors, cooked_mntrs; 629 int monitors, cooked_mntrs;
623 /* number of interfaces with corresponding FIF_ flags */ 630 /* number of interfaces with corresponding FIF_ flags */
624 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss; 631 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss, fif_pspoll;
625 unsigned int filter_flags; /* FIF_* */ 632 unsigned int filter_flags; /* FIF_* */
626 struct iw_statistics wstats; 633 struct iw_statistics wstats;
627 634
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 6c655b6547fb..e8fb03b91a44 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -220,8 +220,10 @@ static int ieee80211_open(struct net_device *dev)
220 local->fif_fcsfail++; 220 local->fif_fcsfail++;
221 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) 221 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
222 local->fif_plcpfail++; 222 local->fif_plcpfail++;
223 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) 223 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
224 local->fif_control++; 224 local->fif_control++;
225 local->fif_pspoll++;
226 }
225 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) 227 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
226 local->fif_other_bss++; 228 local->fif_other_bss++;
227 229
@@ -244,7 +246,14 @@ static int ieee80211_open(struct net_device *dev)
244 spin_unlock_bh(&local->filter_lock); 246 spin_unlock_bh(&local->filter_lock);
245 247
246 ieee80211_start_mesh(sdata); 248 ieee80211_start_mesh(sdata);
249 } else if (sdata->vif.type == NL80211_IFTYPE_AP) {
250 local->fif_pspoll++;
251
252 spin_lock_bh(&local->filter_lock);
253 ieee80211_configure_filter(local);
254 spin_unlock_bh(&local->filter_lock);
247 } 255 }
256
248 changed |= ieee80211_reset_erp_info(sdata); 257 changed |= ieee80211_reset_erp_info(sdata);
249 ieee80211_bss_info_change_notify(sdata, changed); 258 ieee80211_bss_info_change_notify(sdata, changed);
250 ieee80211_enable_keys(sdata); 259 ieee80211_enable_keys(sdata);
@@ -312,7 +321,7 @@ static int ieee80211_open(struct net_device *dev)
312 * to fix this. 321 * to fix this.
313 */ 322 */
314 if (sdata->vif.type == NL80211_IFTYPE_STATION) 323 if (sdata->vif.type == NL80211_IFTYPE_STATION)
315 queue_work(local->hw.workqueue, &sdata->u.mgd.work); 324 ieee80211_queue_work(&local->hw, &sdata->u.mgd.work);
316 325
317 netif_tx_start_all_queues(dev); 326 netif_tx_start_all_queues(dev);
318 327
@@ -388,6 +397,9 @@ static int ieee80211_stop(struct net_device *dev)
388 if (sdata->flags & IEEE80211_SDATA_PROMISC) 397 if (sdata->flags & IEEE80211_SDATA_PROMISC)
389 atomic_dec(&local->iff_promiscs); 398 atomic_dec(&local->iff_promiscs);
390 399
400 if (sdata->vif.type == NL80211_IFTYPE_AP)
401 local->fif_pspoll--;
402
391 netif_addr_lock_bh(dev); 403 netif_addr_lock_bh(dev);
392 spin_lock_bh(&local->filter_lock); 404 spin_lock_bh(&local->filter_lock);
393 __dev_addr_unsync(&local->mc_list, &local->mc_count, 405 __dev_addr_unsync(&local->mc_list, &local->mc_count,
@@ -401,7 +413,7 @@ static int ieee80211_stop(struct net_device *dev)
401 413
402 /* APs need special treatment */ 414 /* APs need special treatment */
403 if (sdata->vif.type == NL80211_IFTYPE_AP) { 415 if (sdata->vif.type == NL80211_IFTYPE_AP) {
404 struct ieee80211_sub_if_data *vlan, *tmp; 416 struct ieee80211_sub_if_data *vlan, *tmpsdata;
405 struct beacon_data *old_beacon = sdata->u.ap.beacon; 417 struct beacon_data *old_beacon = sdata->u.ap.beacon;
406 418
407 /* remove beacon */ 419 /* remove beacon */
@@ -410,7 +422,7 @@ static int ieee80211_stop(struct net_device *dev)
410 kfree(old_beacon); 422 kfree(old_beacon);
411 423
412 /* down all dependent devices, that is VLANs */ 424 /* down all dependent devices, that is VLANs */
413 list_for_each_entry_safe(vlan, tmp, &sdata->u.ap.vlans, 425 list_for_each_entry_safe(vlan, tmpsdata, &sdata->u.ap.vlans,
414 u.vlan.list) 426 u.vlan.list)
415 dev_close(vlan->dev); 427 dev_close(vlan->dev);
416 WARN_ON(!list_empty(&sdata->u.ap.vlans)); 428 WARN_ON(!list_empty(&sdata->u.ap.vlans));
@@ -439,8 +451,10 @@ static int ieee80211_stop(struct net_device *dev)
439 local->fif_fcsfail--; 451 local->fif_fcsfail--;
440 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL) 452 if (sdata->u.mntr_flags & MONITOR_FLAG_PLCPFAIL)
441 local->fif_plcpfail--; 453 local->fif_plcpfail--;
442 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) 454 if (sdata->u.mntr_flags & MONITOR_FLAG_CONTROL) {
455 local->fif_pspoll--;
443 local->fif_control--; 456 local->fif_control--;
457 }
444 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) 458 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
445 local->fif_other_bss--; 459 local->fif_other_bss--;
446 460
@@ -522,6 +536,16 @@ static int ieee80211_stop(struct net_device *dev)
522 ieee80211_scan_completed(&local->hw, true); 536 ieee80211_scan_completed(&local->hw, true);
523 } 537 }
524 538
539 /*
540 * Disable beaconing for AP and mesh, IBSS can't
541 * still be joined to a network at this point.
542 */
543 if (sdata->vif.type == NL80211_IFTYPE_AP ||
544 sdata->vif.type == NL80211_IFTYPE_MESH_POINT) {
545 ieee80211_bss_info_change_notify(sdata,
546 BSS_CHANGED_BEACON_ENABLED);
547 }
548
525 conf.vif = &sdata->vif; 549 conf.vif = &sdata->vif;
526 conf.type = sdata->vif.type; 550 conf.type = sdata->vif.type;
527 conf.mac_addr = dev->dev_addr; 551 conf.mac_addr = dev->dev_addr;
@@ -541,7 +565,7 @@ static int ieee80211_stop(struct net_device *dev)
541 565
542 ieee80211_led_radio(local, false); 566 ieee80211_led_radio(local, false);
543 567
544 flush_workqueue(local->hw.workqueue); 568 flush_workqueue(local->workqueue);
545 569
546 tasklet_disable(&local->tx_pending_tasklet); 570 tasklet_disable(&local->tx_pending_tasklet);
547 tasklet_disable(&local->tasklet); 571 tasklet_disable(&local->tasklet);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index c1a799194fff..0c4f8e122ed6 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -77,6 +77,9 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
77 if (local->fif_other_bss) 77 if (local->fif_other_bss)
78 new_flags |= FIF_OTHER_BSS; 78 new_flags |= FIF_OTHER_BSS;
79 79
80 if (local->fif_pspoll)
81 new_flags |= FIF_PSPOLL;
82
80 changed_flags = local->filter_flags ^ new_flags; 83 changed_flags = local->filter_flags ^ new_flags;
81 84
82 /* be a bit nasty */ 85 /* be a bit nasty */
@@ -198,7 +201,8 @@ void ieee80211_bss_info_change_notify(struct ieee80211_sub_if_data *sdata,
198 } 201 }
199 202
200 if (changed & BSS_CHANGED_BEACON_ENABLED) { 203 if (changed & BSS_CHANGED_BEACON_ENABLED) {
201 if (test_bit(SCAN_SW_SCANNING, &local->scanning)) { 204 if (local->quiescing || !netif_running(sdata->dev) ||
205 test_bit(SCAN_SW_SCANNING, &local->scanning)) {
202 sdata->vif.bss_conf.enable_beacon = false; 206 sdata->vif.bss_conf.enable_beacon = false;
203 } else { 207 } else {
204 /* 208 /*
@@ -310,6 +314,31 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
310{ 314{
311 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 315 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
312 316
317 /*
318 * XXX: This is temporary!
319 *
320 * The problem here is that when we get here, the driver will
321 * quite likely have pretty much overwritten info->control by
322 * using info->driver_data or info->rate_driver_data. Thus,
323 * when passing out the frame to the driver again, we would be
324 * passing completely bogus data since the driver would then
325 * expect a properly filled info->control. In mac80211 itself
326 * the same problem occurs, since we need info->control.vif
327 * internally.
328 *
329 * To fix this, we should send the frame through TX processing
330 * again. However, it's not that simple, since the frame will
331 * have been software-encrypted (if applicable) already, and
332 * encrypting it again doesn't do much good. So to properly do
333 * that, we not only have to skip the actual 'raw' encryption
334 * (key selection etc. still has to be done!) but also the
335 * sequence number assignment since that impacts the crypto
336 * encapsulation, of course.
337 *
338 * Hence, for now, fix the bug by just dropping the frame.
339 */
340 goto drop;
341
313 sta->tx_filtered_count++; 342 sta->tx_filtered_count++;
314 343
315 /* 344 /*
@@ -363,6 +392,7 @@ static void ieee80211_handle_filtered_frame(struct ieee80211_local *local,
363 return; 392 return;
364 } 393 }
365 394
395 drop:
366#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 396#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
367 if (net_ratelimit()) 397 if (net_ratelimit())
368 printk(KERN_DEBUG "%s: dropped TX filtered frame, " 398 printk(KERN_DEBUG "%s: dropped TX filtered frame, "
@@ -794,9 +824,9 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
794 if (hw->queues > IEEE80211_MAX_QUEUES) 824 if (hw->queues > IEEE80211_MAX_QUEUES)
795 hw->queues = IEEE80211_MAX_QUEUES; 825 hw->queues = IEEE80211_MAX_QUEUES;
796 826
797 local->hw.workqueue = 827 local->workqueue =
798 create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); 828 create_singlethread_workqueue(wiphy_name(local->hw.wiphy));
799 if (!local->hw.workqueue) { 829 if (!local->workqueue) {
800 result = -ENOMEM; 830 result = -ENOMEM;
801 goto fail_workqueue; 831 goto fail_workqueue;
802 } 832 }
@@ -886,7 +916,7 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
886 sta_info_stop(local); 916 sta_info_stop(local);
887 fail_sta_info: 917 fail_sta_info:
888 debugfs_hw_del(local); 918 debugfs_hw_del(local);
889 destroy_workqueue(local->hw.workqueue); 919 destroy_workqueue(local->workqueue);
890 fail_workqueue: 920 fail_workqueue:
891 wiphy_unregister(local->hw.wiphy); 921 wiphy_unregister(local->hw.wiphy);
892 fail_wiphy_register: 922 fail_wiphy_register:
@@ -928,7 +958,7 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
928 skb_queue_purge(&local->skb_queue); 958 skb_queue_purge(&local->skb_queue);
929 skb_queue_purge(&local->skb_queue_unreliable); 959 skb_queue_purge(&local->skb_queue_unreliable);
930 960
931 destroy_workqueue(local->hw.workqueue); 961 destroy_workqueue(local->workqueue);
932 wiphy_unregister(local->hw.wiphy); 962 wiphy_unregister(local->hw.wiphy);
933 ieee80211_wep_free(local); 963 ieee80211_wep_free(local);
934 ieee80211_led_exit(local); 964 ieee80211_led_exit(local);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 9a3826978b1c..2f4f518ab45c 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -54,7 +54,7 @@ static void ieee80211_mesh_housekeeping_timer(unsigned long data)
54 return; 54 return;
55 } 55 }
56 56
57 queue_work(local->hw.workqueue, &ifmsh->work); 57 ieee80211_queue_work(local->hw.workqueue, &ifmsh->work);
58} 58}
59 59
60/** 60/**
@@ -357,7 +357,7 @@ static void ieee80211_mesh_path_timer(unsigned long data)
357 return; 357 return;
358 } 358 }
359 359
360 queue_work(local->hw.workqueue, &ifmsh->work); 360 ieee80211_queue_work(local->hw.workqueue, &ifmsh->work);
361} 361}
362 362
363struct mesh_table *mesh_table_grow(struct mesh_table *tbl) 363struct mesh_table *mesh_table_grow(struct mesh_table *tbl)
@@ -471,7 +471,7 @@ void ieee80211_start_mesh(struct ieee80211_sub_if_data *sdata)
471 struct ieee80211_local *local = sdata->local; 471 struct ieee80211_local *local = sdata->local;
472 472
473 ifmsh->housekeeping = true; 473 ifmsh->housekeeping = true;
474 queue_work(local->hw.workqueue, &ifmsh->work); 474 ieee80211_queue_work(local->hw.workqueue, &ifmsh->work);
475 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON | 475 ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_BEACON |
476 BSS_CHANGED_BEACON_ENABLED); 476 BSS_CHANGED_BEACON_ENABLED);
477} 477}
@@ -619,7 +619,7 @@ void ieee80211_mesh_notify_scan_completed(struct ieee80211_local *local)
619 rcu_read_lock(); 619 rcu_read_lock();
620 list_for_each_entry_rcu(sdata, &local->interfaces, list) 620 list_for_each_entry_rcu(sdata, &local->interfaces, list)
621 if (ieee80211_vif_is_mesh(&sdata->vif)) 621 if (ieee80211_vif_is_mesh(&sdata->vif))
622 queue_work(local->hw.workqueue, &sdata->u.mesh.work); 622 ieee80211_queue_work(local->hw.workqueue, &sdata->u.mesh.work);
623 rcu_read_unlock(); 623 rcu_read_unlock();
624} 624}
625 625
@@ -692,7 +692,7 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
692 case IEEE80211_STYPE_PROBE_RESP: 692 case IEEE80211_STYPE_PROBE_RESP:
693 case IEEE80211_STYPE_BEACON: 693 case IEEE80211_STYPE_BEACON:
694 skb_queue_tail(&ifmsh->skb_queue, skb); 694 skb_queue_tail(&ifmsh->skb_queue, skb);
695 queue_work(local->hw.workqueue, &ifmsh->work); 695 ieee80211_queue_work(local->hw.workqueue, &ifmsh->work);
696 return RX_QUEUED; 696 return RX_QUEUED;
697 } 697 }
698 698
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index e93c37ef6a48..11ab71a68ff9 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -660,14 +660,14 @@ static void mesh_queue_preq(struct mesh_path *mpath, u8 flags)
660 spin_unlock(&ifmsh->mesh_preq_queue_lock); 660 spin_unlock(&ifmsh->mesh_preq_queue_lock);
661 661
662 if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata))) 662 if (time_after(jiffies, ifmsh->last_preq + min_preq_int_jiff(sdata)))
663 queue_work(sdata->local->hw.workqueue, &ifmsh->work); 663 ieee80211_queue_work(sdata->local->hw.workqueue, &ifmsh->work);
664 664
665 else if (time_before(jiffies, ifmsh->last_preq)) { 665 else if (time_before(jiffies, ifmsh->last_preq)) {
666 /* avoid long wait if did not send preqs for a long time 666 /* avoid long wait if did not send preqs for a long time
667 * and jiffies wrapped around 667 * and jiffies wrapped around
668 */ 668 */
669 ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1; 669 ifmsh->last_preq = jiffies - min_preq_int_jiff(sdata) - 1;
670 queue_work(sdata->local->hw.workqueue, &ifmsh->work); 670 ieee80211_queue_work(sdata->local->hw.workqueue, &ifmsh->work);
671 } else 671 } else
672 mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq + 672 mod_timer(&ifmsh->mesh_path_timer, ifmsh->last_preq +
673 min_preq_int_jiff(sdata)); 673 min_preq_int_jiff(sdata));
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ee83125ed179..6d5a1ee0445f 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -31,6 +31,7 @@
31#define IEEE80211_AUTH_MAX_TRIES 3 31#define IEEE80211_AUTH_MAX_TRIES 3
32#define IEEE80211_ASSOC_TIMEOUT (HZ / 5) 32#define IEEE80211_ASSOC_TIMEOUT (HZ / 5)
33#define IEEE80211_ASSOC_MAX_TRIES 3 33#define IEEE80211_ASSOC_MAX_TRIES 3
34#define IEEE80211_MAX_PROBE_TRIES 5
34 35
35/* 36/*
36 * beacon loss detection timeout 37 * beacon loss detection timeout
@@ -41,13 +42,13 @@
41 * Time the connection can be idle before we probe 42 * Time the connection can be idle before we probe
42 * it to see if we can still talk to the AP. 43 * it to see if we can still talk to the AP.
43 */ 44 */
44#define IEEE80211_CONNECTION_IDLE_TIME (2 * HZ) 45#define IEEE80211_CONNECTION_IDLE_TIME (30 * HZ)
45/* 46/*
46 * Time we wait for a probe response after sending 47 * Time we wait for a probe response after sending
47 * a probe request because of beacon loss or for 48 * a probe request because of beacon loss or for
48 * checking the connection still works. 49 * checking the connection still works.
49 */ 50 */
50#define IEEE80211_PROBE_WAIT (HZ / 5) 51#define IEEE80211_PROBE_WAIT (HZ / 2)
51 52
52#define TMR_RUNNING_TIMER 0 53#define TMR_RUNNING_TIMER 0
53#define TMR_RUNNING_CHANSW 1 54#define TMR_RUNNING_CHANSW 1
@@ -565,7 +566,7 @@ static void ieee80211_chswitch_timer(unsigned long data)
565 return; 566 return;
566 } 567 }
567 568
568 queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); 569 ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
569} 570}
570 571
571void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, 572void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
@@ -597,7 +598,7 @@ void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata,
597 sdata->local->csa_channel = new_ch; 598 sdata->local->csa_channel = new_ch;
598 599
599 if (sw_elem->count <= 1) { 600 if (sw_elem->count <= 1) {
600 queue_work(sdata->local->hw.workqueue, &ifmgd->chswitch_work); 601 ieee80211_queue_work(&sdata->local->hw, &ifmgd->chswitch_work);
601 } else { 602 } else {
602 ieee80211_stop_queues_by_reason(&sdata->local->hw, 603 ieee80211_stop_queues_by_reason(&sdata->local->hw,
603 IEEE80211_QUEUE_STOP_REASON_CSA); 604 IEEE80211_QUEUE_STOP_REASON_CSA);
@@ -763,7 +764,7 @@ void ieee80211_dynamic_ps_timer(unsigned long data)
763 if (local->quiescing || local->suspended) 764 if (local->quiescing || local->suspended)
764 return; 765 return;
765 766
766 queue_work(local->hw.workqueue, &local->dynamic_ps_enable_work); 767 ieee80211_queue_work(&local->hw, &local->dynamic_ps_enable_work);
767} 768}
768 769
769/* MLME */ 770/* MLME */
@@ -916,12 +917,9 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
916 917
917 ieee80211_bss_info_change_notify(sdata, bss_info_changed); 918 ieee80211_bss_info_change_notify(sdata, bss_info_changed);
918 919
919 /* will be same as sdata */ 920 mutex_lock(&local->iflist_mtx);
920 if (local->ps_sdata) { 921 ieee80211_recalc_ps(local, -1);
921 mutex_lock(&local->iflist_mtx); 922 mutex_unlock(&local->iflist_mtx);
922 ieee80211_recalc_ps(local, -1);
923 mutex_unlock(&local->iflist_mtx);
924 }
925 923
926 netif_tx_start_all_queues(sdata->dev); 924 netif_tx_start_all_queues(sdata->dev);
927 netif_carrier_on(sdata->dev); 925 netif_carrier_on(sdata->dev);
@@ -950,7 +948,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
950 * due to work needing to be done. Hence, queue the STAs work 948 * due to work needing to be done. Hence, queue the STAs work
951 * again for that. 949 * again for that.
952 */ 950 */
953 queue_work(local->hw.workqueue, &ifmgd->work); 951 ieee80211_queue_work(&local->hw, &ifmgd->work);
954 return RX_MGMT_CFG80211_AUTH_TO; 952 return RX_MGMT_CFG80211_AUTH_TO;
955 } 953 }
956 954
@@ -995,7 +993,7 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
995 * due to work needing to be done. Hence, queue the STAs work 993 * due to work needing to be done. Hence, queue the STAs work
996 * again for that. 994 * again for that.
997 */ 995 */
998 queue_work(local->hw.workqueue, &ifmgd->work); 996 ieee80211_queue_work(&local->hw, &ifmgd->work);
999 return RX_MGMT_CFG80211_AUTH_TO; 997 return RX_MGMT_CFG80211_AUTH_TO;
1000 } 998 }
1001 999
@@ -1124,7 +1122,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1124 * due to work needing to be done. Hence, queue the STAs work 1122 * due to work needing to be done. Hence, queue the STAs work
1125 * again for that. 1123 * again for that.
1126 */ 1124 */
1127 queue_work(local->hw.workqueue, &ifmgd->work); 1125 ieee80211_queue_work(&local->hw, &ifmgd->work);
1128 return RX_MGMT_CFG80211_ASSOC_TO; 1126 return RX_MGMT_CFG80211_ASSOC_TO;
1129 } 1127 }
1130 1128
@@ -1156,11 +1154,24 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1156 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME)); 1154 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
1157} 1155}
1158 1156
1157static void ieee80211_mgd_probe_ap_send(struct ieee80211_sub_if_data *sdata)
1158{
1159 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1160 const u8 *ssid;
1161
1162 ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID);
1163 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid,
1164 ssid + 2, ssid[1], NULL, 0);
1165
1166 ifmgd->probe_send_count++;
1167 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
1168 run_again(ifmgd, ifmgd->probe_timeout);
1169}
1170
1159static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, 1171static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1160 bool beacon) 1172 bool beacon)
1161{ 1173{
1162 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1174 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1163 const u8 *ssid;
1164 bool already = false; 1175 bool already = false;
1165 1176
1166 if (!netif_running(sdata->dev)) 1177 if (!netif_running(sdata->dev))
@@ -1203,18 +1214,12 @@ static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1203 if (already) 1214 if (already)
1204 goto out; 1215 goto out;
1205 1216
1206 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
1207
1208 mutex_lock(&sdata->local->iflist_mtx); 1217 mutex_lock(&sdata->local->iflist_mtx);
1209 ieee80211_recalc_ps(sdata->local, -1); 1218 ieee80211_recalc_ps(sdata->local, -1);
1210 mutex_unlock(&sdata->local->iflist_mtx); 1219 mutex_unlock(&sdata->local->iflist_mtx);
1211 1220
1212 ssid = ieee80211_bss_get_ie(&ifmgd->associated->cbss, WLAN_EID_SSID); 1221 ifmgd->probe_send_count = 0;
1213 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, 1222 ieee80211_mgd_probe_ap_send(sdata);
1214 ssid + 2, ssid[1], NULL, 0);
1215
1216 run_again(ifmgd, ifmgd->probe_timeout);
1217
1218 out: 1223 out:
1219 mutex_unlock(&ifmgd->mtx); 1224 mutex_unlock(&ifmgd->mtx);
1220} 1225}
@@ -1232,8 +1237,7 @@ void ieee80211_beacon_loss(struct ieee80211_vif *vif)
1232{ 1237{
1233 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1238 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
1234 1239
1235 queue_work(sdata->local->hw.workqueue, 1240 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work);
1236 &sdata->u.mgd.beacon_loss_work);
1237} 1241}
1238EXPORT_SYMBOL(ieee80211_beacon_loss); 1242EXPORT_SYMBOL(ieee80211_beacon_loss);
1239 1243
@@ -1570,6 +1574,9 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1570 wk->bss->cbss.bssid, 1574 wk->bss->cbss.bssid,
1571 ap_ht_cap_flags); 1575 ap_ht_cap_flags);
1572 1576
1577 /* delete work item -- must be before set_associated for PS */
1578 list_del(&wk->list);
1579
1573 /* set AID and assoc capability, 1580 /* set AID and assoc capability,
1574 * ieee80211_set_associated() will tell the driver */ 1581 * ieee80211_set_associated() will tell the driver */
1575 bss_conf->aid = aid; 1582 bss_conf->aid = aid;
@@ -1583,7 +1590,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1583 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt); 1590 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1584 mod_beacon_timer(sdata); 1591 mod_beacon_timer(sdata);
1585 1592
1586 list_del(&wk->list);
1587 kfree(wk); 1593 kfree(wk);
1588 return RX_MGMT_CFG80211_ASSOC; 1594 return RX_MGMT_CFG80211_ASSOC;
1589} 1595}
@@ -1847,12 +1853,8 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1847 bssid, ap_ht_cap_flags); 1853 bssid, ap_ht_cap_flags);
1848 } 1854 }
1849 1855
1856 /* Note: country IE parsing is done for us by cfg80211 */
1850 if (elems.country_elem) { 1857 if (elems.country_elem) {
1851 /* Note we are only reviewing this on beacons
1852 * for the BSSID we are associated to */
1853 regulatory_hint_11d(local->hw.wiphy,
1854 elems.country_elem, elems.country_elem_len);
1855
1856 /* TODO: IBSS also needs this */ 1858 /* TODO: IBSS also needs this */
1857 if (elems.pwr_constr_elem) 1859 if (elems.pwr_constr_elem)
1858 ieee80211_handle_pwr_constr(sdata, 1860 ieee80211_handle_pwr_constr(sdata,
@@ -1888,7 +1890,7 @@ ieee80211_rx_result ieee80211_sta_rx_mgmt(struct ieee80211_sub_if_data *sdata,
1888 case IEEE80211_STYPE_DISASSOC: 1890 case IEEE80211_STYPE_DISASSOC:
1889 case IEEE80211_STYPE_ACTION: 1891 case IEEE80211_STYPE_ACTION:
1890 skb_queue_tail(&sdata->u.mgd.skb_queue, skb); 1892 skb_queue_tail(&sdata->u.mgd.skb_queue, skb);
1891 queue_work(local->hw.workqueue, &sdata->u.mgd.work); 1893 ieee80211_queue_work(&local->hw, &sdata->u.mgd.work);
1892 return RX_QUEUED; 1894 return RX_QUEUED;
1893 } 1895 }
1894 1896
@@ -2026,7 +2028,7 @@ static void ieee80211_sta_timer(unsigned long data)
2026 return; 2028 return;
2027 } 2029 }
2028 2030
2029 queue_work(local->hw.workqueue, &ifmgd->work); 2031 ieee80211_queue_work(&local->hw, &ifmgd->work);
2030} 2032}
2031 2033
2032static void ieee80211_sta_work(struct work_struct *work) 2034static void ieee80211_sta_work(struct work_struct *work)
@@ -2051,13 +2053,11 @@ static void ieee80211_sta_work(struct work_struct *work)
2051 return; 2053 return;
2052 2054
2053 /* 2055 /*
2054 * Nothing should have been stuffed into the workqueue during 2056 * ieee80211_queue_work() should have picked up most cases,
2055 * the suspend->resume cycle. If this WARN is seen then there 2057 * here we'll pick the the rest.
2056 * is a bug with either the driver suspend or something in
2057 * mac80211 stuffing into the workqueue which we haven't yet
2058 * cleared during mac80211's suspend cycle.
2059 */ 2058 */
2060 if (WARN_ON(local->suspended)) 2059 if (WARN(local->suspended, "STA MLME work scheduled while "
2060 "going to suspend\n"))
2061 return; 2061 return;
2062 2062
2063 ifmgd = &sdata->u.mgd; 2063 ifmgd = &sdata->u.mgd;
@@ -2072,17 +2072,27 @@ static void ieee80211_sta_work(struct work_struct *work)
2072 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL | 2072 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
2073 IEEE80211_STA_CONNECTION_POLL) && 2073 IEEE80211_STA_CONNECTION_POLL) &&
2074 ifmgd->associated) { 2074 ifmgd->associated) {
2075 u8 bssid[ETH_ALEN];
2076
2077 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
2075 if (time_is_after_jiffies(ifmgd->probe_timeout)) 2078 if (time_is_after_jiffies(ifmgd->probe_timeout))
2076 run_again(ifmgd, ifmgd->probe_timeout); 2079 run_again(ifmgd, ifmgd->probe_timeout);
2077 else { 2080
2078 u8 bssid[ETH_ALEN]; 2081 else if (ifmgd->probe_send_count < IEEE80211_MAX_PROBE_TRIES) {
2082#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
2083 printk(KERN_DEBUG "No probe response from AP %pM"
2084 " after %dms, try %d\n", bssid,
2085 (1000 * IEEE80211_PROBE_WAIT)/HZ,
2086 ifmgd->probe_send_count);
2087#endif
2088 ieee80211_mgd_probe_ap_send(sdata);
2089 } else {
2079 /* 2090 /*
2080 * We actually lost the connection ... or did we? 2091 * We actually lost the connection ... or did we?
2081 * Let's make sure! 2092 * Let's make sure!
2082 */ 2093 */
2083 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL | 2094 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
2084 IEEE80211_STA_BEACON_POLL); 2095 IEEE80211_STA_BEACON_POLL);
2085 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
2086 printk(KERN_DEBUG "No probe response from AP %pM" 2096 printk(KERN_DEBUG "No probe response from AP %pM"
2087 " after %dms, disconnecting.\n", 2097 " after %dms, disconnecting.\n",
2088 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ); 2098 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
@@ -2113,9 +2123,9 @@ static void ieee80211_sta_work(struct work_struct *work)
2113 mutex_unlock(&ifmgd->mtx); 2123 mutex_unlock(&ifmgd->mtx);
2114 2124
2115 if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request)) 2125 if (test_and_clear_bit(IEEE80211_STA_REQ_SCAN, &ifmgd->request))
2116 queue_delayed_work(local->hw.workqueue, 2126 ieee80211_queue_delayed_work(&local->hw,
2117 &local->scan_work, 2127 &local->scan_work,
2118 round_jiffies_relative(0)); 2128 round_jiffies_relative(0));
2119 return; 2129 return;
2120 } 2130 }
2121 2131
@@ -2196,8 +2206,7 @@ static void ieee80211_sta_bcn_mon_timer(unsigned long data)
2196 if (local->quiescing) 2206 if (local->quiescing)
2197 return; 2207 return;
2198 2208
2199 queue_work(sdata->local->hw.workqueue, 2209 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.beacon_loss_work);
2200 &sdata->u.mgd.beacon_loss_work);
2201} 2210}
2202 2211
2203static void ieee80211_sta_conn_mon_timer(unsigned long data) 2212static void ieee80211_sta_conn_mon_timer(unsigned long data)
@@ -2210,7 +2219,7 @@ static void ieee80211_sta_conn_mon_timer(unsigned long data)
2210 if (local->quiescing) 2219 if (local->quiescing)
2211 return; 2220 return;
2212 2221
2213 queue_work(local->hw.workqueue, &ifmgd->monitor_work); 2222 ieee80211_queue_work(&local->hw, &ifmgd->monitor_work);
2214} 2223}
2215 2224
2216static void ieee80211_sta_monitor_work(struct work_struct *work) 2225static void ieee80211_sta_monitor_work(struct work_struct *work)
@@ -2229,10 +2238,10 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
2229 IEEE80211_STA_CONNECTION_POLL); 2238 IEEE80211_STA_CONNECTION_POLL);
2230 2239
2231 /* let's probe the connection once */ 2240 /* let's probe the connection once */
2232 queue_work(sdata->local->hw.workqueue, 2241 ieee80211_queue_work(&sdata->local->hw,
2233 &sdata->u.mgd.monitor_work); 2242 &sdata->u.mgd.monitor_work);
2234 /* and do all the other regular work too */ 2243 /* and do all the other regular work too */
2235 queue_work(sdata->local->hw.workqueue, 2244 ieee80211_queue_work(&sdata->local->hw,
2236 &sdata->u.mgd.work); 2245 &sdata->u.mgd.work);
2237 } 2246 }
2238} 2247}
@@ -2393,7 +2402,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2393 list_add(&wk->list, &sdata->u.mgd.work_list); 2402 list_add(&wk->list, &sdata->u.mgd.work_list);
2394 mutex_unlock(&ifmgd->mtx); 2403 mutex_unlock(&ifmgd->mtx);
2395 2404
2396 queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); 2405 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work);
2397 return 0; 2406 return 0;
2398} 2407}
2399 2408
@@ -2467,7 +2476,7 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
2467 else 2476 else
2468 ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT; 2477 ifmgd->flags &= ~IEEE80211_STA_CONTROL_PORT;
2469 2478
2470 queue_work(sdata->local->hw.workqueue, &sdata->u.mgd.work); 2479 ieee80211_queue_work(&sdata->local->hw, &sdata->u.mgd.work);
2471 2480
2472 err = 0; 2481 err = 0;
2473 2482
diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c
index 5e3d476972f9..a5d2f1fb4417 100644
--- a/net/mac80211/pm.c
+++ b/net/mac80211/pm.c
@@ -26,7 +26,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
26 /* make quiescing visible to timers everywhere */ 26 /* make quiescing visible to timers everywhere */
27 mb(); 27 mb();
28 28
29 flush_workqueue(local->hw.workqueue); 29 flush_workqueue(local->workqueue);
30 30
31 /* Don't try to run timers while suspended. */ 31 /* Don't try to run timers while suspended. */
32 del_timer_sync(&local->sta_cleanup); 32 del_timer_sync(&local->sta_cleanup);
@@ -96,6 +96,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
96 if (!netif_running(sdata->dev)) 96 if (!netif_running(sdata->dev))
97 continue; 97 continue;
98 98
99 /* disable beaconing */
100 ieee80211_bss_info_change_notify(sdata,
101 BSS_CHANGED_BEACON_ENABLED);
102
99 conf.vif = &sdata->vif; 103 conf.vif = &sdata->vif;
100 conf.type = sdata->vif.type; 104 conf.type = sdata->vif.type;
101 conf.mac_addr = sdata->dev->dev_addr; 105 conf.mac_addr = sdata->dev->dev_addr;
@@ -113,7 +117,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw)
113 * shouldn't be doing (or cancel everything in the 117 * shouldn't be doing (or cancel everything in the
114 * stop callback) that but better safe than sorry. 118 * stop callback) that but better safe than sorry.
115 */ 119 */
116 flush_workqueue(local->hw.workqueue); 120 flush_workqueue(local->workqueue);
117 121
118 local->suspended = true; 122 local->suspended = true;
119 /* need suspended to be visible before quiescing is false */ 123 /* need suspended to be visible before quiescing is false */
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 45731000eb8d..244f53f3c8b4 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -385,8 +385,9 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
385 spin_unlock_bh(&local->filter_lock); 385 spin_unlock_bh(&local->filter_lock);
386 386
387 /* TODO: start scan as soon as all nullfunc frames are ACKed */ 387 /* TODO: start scan as soon as all nullfunc frames are ACKed */
388 queue_delayed_work(local->hw.workqueue, &local->scan_work, 388 ieee80211_queue_delayed_work(&local->hw,
389 IEEE80211_CHANNEL_TIME); 389 &local->scan_work,
390 IEEE80211_CHANNEL_TIME);
390 391
391 return 0; 392 return 0;
392} 393}
@@ -715,8 +716,7 @@ void ieee80211_scan_work(struct work_struct *work)
715 } 716 }
716 } while (next_delay == 0); 717 } while (next_delay == 0);
717 718
718 queue_delayed_work(local->hw.workqueue, &local->scan_work, 719 ieee80211_queue_delayed_work(&local->hw, &local->scan_work, next_delay);
719 next_delay);
720} 720}
721 721
722int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, 722int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 4e1b2ba122cd..7cffaa046b33 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1400,7 +1400,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1400 if (local->hw.conf.flags & IEEE80211_CONF_PS) { 1400 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
1401 ieee80211_stop_queues_by_reason(&local->hw, 1401 ieee80211_stop_queues_by_reason(&local->hw,
1402 IEEE80211_QUEUE_STOP_REASON_PS); 1402 IEEE80211_QUEUE_STOP_REASON_PS);
1403 queue_work(local->hw.workqueue, 1403 ieee80211_queue_work(&local->hw,
1404 &local->dynamic_ps_disable_work); 1404 &local->dynamic_ps_disable_work);
1405 } 1405 }
1406 1406
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 8502936e5314..e55d57f559ec 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -511,6 +511,46 @@ void ieee80211_iterate_active_interfaces_atomic(
511} 511}
512EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); 512EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic);
513 513
514/*
515 * Nothing should have been stuffed into the workqueue during
516 * the suspend->resume cycle. If this WARN is seen then there
517 * is a bug with either the driver suspend or something in
518 * mac80211 stuffing into the workqueue which we haven't yet
519 * cleared during mac80211's suspend cycle.
520 */
521static bool ieee80211_can_queue_work(struct ieee80211_local *local)
522{
523 if (WARN(local->suspended, "queueing ieee80211 work while "
524 "going to suspend\n"))
525 return false;
526
527 return true;
528}
529
530void ieee80211_queue_work(struct ieee80211_hw *hw, struct work_struct *work)
531{
532 struct ieee80211_local *local = hw_to_local(hw);
533
534 if (!ieee80211_can_queue_work(local))
535 return;
536
537 queue_work(local->workqueue, work);
538}
539EXPORT_SYMBOL(ieee80211_queue_work);
540
541void ieee80211_queue_delayed_work(struct ieee80211_hw *hw,
542 struct delayed_work *dwork,
543 unsigned long delay)
544{
545 struct ieee80211_local *local = hw_to_local(hw);
546
547 if (!ieee80211_can_queue_work(local))
548 return;
549
550 queue_delayed_work(local->workqueue, dwork, delay);
551}
552EXPORT_SYMBOL(ieee80211_queue_delayed_work);
553
514void ieee802_11_parse_elems(u8 *start, size_t len, 554void ieee802_11_parse_elems(u8 *start, size_t len,
515 struct ieee802_11_elems *elems) 555 struct ieee802_11_elems *elems)
516{ 556{
@@ -1114,3 +1154,4 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1114#endif 1154#endif
1115 return 0; 1155 return 0;
1116} 1156}
1157
diff --git a/net/rfkill/core.c b/net/rfkill/core.c
index 044de1c6af3d..dbeaf2983822 100644
--- a/net/rfkill/core.c
+++ b/net/rfkill/core.c
@@ -589,11 +589,13 @@ static const char *rfkill_get_type_str(enum rfkill_type type)
589 return "wimax"; 589 return "wimax";
590 case RFKILL_TYPE_WWAN: 590 case RFKILL_TYPE_WWAN:
591 return "wwan"; 591 return "wwan";
592 case RFKILL_TYPE_GPS:
593 return "gps";
592 default: 594 default:
593 BUG(); 595 BUG();
594 } 596 }
595 597
596 BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_WWAN + 1); 598 BUILD_BUG_ON(NUM_RFKILL_TYPES != RFKILL_TYPE_GPS + 1);
597} 599}
598 600
599static ssize_t rfkill_type_show(struct device *dev, 601static ssize_t rfkill_type_show(struct device *dev,
diff --git a/net/wireless/core.c b/net/wireless/core.c
index f9fee65dc06a..1e189306560d 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -34,9 +34,7 @@ MODULE_DESCRIPTION("wireless configuration support");
34LIST_HEAD(cfg80211_rdev_list); 34LIST_HEAD(cfg80211_rdev_list);
35 35
36/* 36/*
37 * This is used to protect the cfg80211_rdev_list, cfg80211_regdomain, 37 * This is used to protect the cfg80211_rdev_list
38 * country_ie_regdomain, the reg_beacon_list and the the last regulatory
39 * request receipt (last_request).
40 */ 38 */
41DEFINE_MUTEX(cfg80211_mutex); 39DEFINE_MUTEX(cfg80211_mutex);
42 40
@@ -314,7 +312,8 @@ static void cfg80211_process_events(struct wireless_dev *wdev)
314 ev->cr.req_ie, ev->cr.req_ie_len, 312 ev->cr.req_ie, ev->cr.req_ie_len,
315 ev->cr.resp_ie, ev->cr.resp_ie_len, 313 ev->cr.resp_ie, ev->cr.resp_ie_len,
316 ev->cr.status, 314 ev->cr.status,
317 ev->cr.status == WLAN_STATUS_SUCCESS); 315 ev->cr.status == WLAN_STATUS_SUCCESS,
316 NULL);
318 break; 317 break;
319 case EVENT_ROAMED: 318 case EVENT_ROAMED:
320 __cfg80211_roamed(wdev, ev->rm.bssid, 319 __cfg80211_roamed(wdev, ev->rm.bssid,
@@ -672,7 +671,7 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
672 wdev->wext.default_mgmt_key = -1; 671 wdev->wext.default_mgmt_key = -1;
673 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC; 672 wdev->wext.connect.auth_type = NL80211_AUTHTYPE_AUTOMATIC;
674 wdev->wext.ps = CONFIG_CFG80211_DEFAULT_PS_VALUE; 673 wdev->wext.ps = CONFIG_CFG80211_DEFAULT_PS_VALUE;
675 wdev->wext.ps_timeout = 500; 674 wdev->wext.ps_timeout = 100;
676 if (rdev->ops->set_power_mgmt) 675 if (rdev->ops->set_power_mgmt)
677 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev, 676 if (rdev->ops->set_power_mgmt(wdev->wiphy, dev,
678 wdev->wext.ps, 677 wdev->wext.ps,
@@ -724,15 +723,22 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
724 break; 723 break;
725 case NETDEV_UNREGISTER: 724 case NETDEV_UNREGISTER:
726 mutex_lock(&rdev->devlist_mtx); 725 mutex_lock(&rdev->devlist_mtx);
726 /*
727 * It is possible to get NETDEV_UNREGISTER
728 * multiple times. To detect that, check
729 * that the interface is still on the list
730 * of registered interfaces, and only then
731 * remove and clean it up.
732 */
727 if (!list_empty(&wdev->list)) { 733 if (!list_empty(&wdev->list)) {
728 sysfs_remove_link(&dev->dev.kobj, "phy80211"); 734 sysfs_remove_link(&dev->dev.kobj, "phy80211");
729 list_del_init(&wdev->list); 735 list_del_init(&wdev->list);
730 } 736 mutex_destroy(&wdev->mtx);
731 mutex_unlock(&rdev->devlist_mtx);
732 mutex_destroy(&wdev->mtx);
733#ifdef CONFIG_WIRELESS_EXT 737#ifdef CONFIG_WIRELESS_EXT
734 kfree(wdev->wext.keys); 738 kfree(wdev->wext.keys);
735#endif 739#endif
740 }
741 mutex_unlock(&rdev->devlist_mtx);
736 break; 742 break;
737 case NETDEV_PRE_UP: 743 case NETDEV_PRE_UP:
738 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) 744 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 6d903c1d721d..325c17e6198c 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -127,6 +127,11 @@ static inline struct cfg80211_internal_bss *bss_from_pub(struct cfg80211_bss *pu
127 return container_of(pub, struct cfg80211_internal_bss, pub); 127 return container_of(pub, struct cfg80211_internal_bss, pub);
128} 128}
129 129
130static inline void cfg80211_ref_bss(struct cfg80211_internal_bss *bss)
131{
132 kref_get(&bss->ref);
133}
134
130static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss) 135static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss)
131{ 136{
132 atomic_inc(&bss->hold); 137 atomic_inc(&bss->hold);
@@ -323,7 +328,8 @@ void cfg80211_mlme_down(struct cfg80211_registered_device *rdev,
323void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 328void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
324 const u8 *req_ie, size_t req_ie_len, 329 const u8 *req_ie, size_t req_ie_len,
325 const u8 *resp_ie, size_t resp_ie_len, 330 const u8 *resp_ie, size_t resp_ie_len,
326 u16 status, bool wextev); 331 u16 status, bool wextev,
332 struct cfg80211_bss *bss);
327 333
328/* SME */ 334/* SME */
329int __cfg80211_connect(struct cfg80211_registered_device *rdev, 335int __cfg80211_connect(struct cfg80211_registered_device *rdev,
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 097a87d7bae1..525e8e247b30 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -61,7 +61,7 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
61 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf; 61 struct ieee80211_mgmt *mgmt = (struct ieee80211_mgmt *)buf;
62 u8 *ie = mgmt->u.assoc_resp.variable; 62 u8 *ie = mgmt->u.assoc_resp.variable;
63 int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable); 63 int i, ieoffs = offsetof(struct ieee80211_mgmt, u.assoc_resp.variable);
64 bool done; 64 struct cfg80211_internal_bss *bss = NULL;
65 65
66 wdev_lock(wdev); 66 wdev_lock(wdev);
67 67
@@ -69,22 +69,32 @@ void cfg80211_send_rx_assoc(struct net_device *dev, const u8 *buf, size_t len)
69 69
70 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL); 70 nl80211_send_rx_assoc(rdev, dev, buf, len, GFP_KERNEL);
71 71
72 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
73 status_code,
74 status_code == WLAN_STATUS_SUCCESS);
75
76 if (status_code == WLAN_STATUS_SUCCESS) { 72 if (status_code == WLAN_STATUS_SUCCESS) {
77 for (i = 0; wdev->current_bss && i < MAX_AUTH_BSSES; i++) { 73 for (i = 0; i < MAX_AUTH_BSSES; i++) {
78 if (wdev->auth_bsses[i] == wdev->current_bss) { 74 if (!wdev->auth_bsses[i])
79 cfg80211_unhold_bss(wdev->auth_bsses[i]); 75 continue;
80 cfg80211_put_bss(&wdev->auth_bsses[i]->pub); 76 if (memcmp(wdev->auth_bsses[i]->pub.bssid, mgmt->bssid,
77 ETH_ALEN) == 0) {
78 bss = wdev->auth_bsses[i];
81 wdev->auth_bsses[i] = NULL; 79 wdev->auth_bsses[i] = NULL;
82 done = true; 80 /* additional reference to drop hold */
81 cfg80211_ref_bss(bss);
83 break; 82 break;
84 } 83 }
85 } 84 }
86 85
87 WARN_ON(!done); 86 WARN_ON(!bss);
87 }
88
89 /* this consumes one bss reference (unless bss is NULL) */
90 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, ie, len - ieoffs,
91 status_code,
92 status_code == WLAN_STATUS_SUCCESS,
93 bss ? &bss->pub : NULL);
94 /* drop hold now, and also reference acquired above */
95 if (bss) {
96 cfg80211_unhold_bss(bss);
97 cfg80211_put_bss(&bss->pub);
88 } 98 }
89 99
90 wdev_unlock(wdev); 100 wdev_unlock(wdev);
@@ -144,7 +154,7 @@ static void __cfg80211_send_deauth(struct net_device *dev,
144 } else if (wdev->sme_state == CFG80211_SME_CONNECTING) { 154 } else if (wdev->sme_state == CFG80211_SME_CONNECTING) {
145 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 155 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
146 WLAN_STATUS_UNSPECIFIED_FAILURE, 156 WLAN_STATUS_UNSPECIFIED_FAILURE,
147 false); 157 false, NULL);
148 } 158 }
149} 159}
150 160
@@ -241,7 +251,7 @@ void cfg80211_send_auth_timeout(struct net_device *dev, const u8 *addr)
241 if (wdev->sme_state == CFG80211_SME_CONNECTING) 251 if (wdev->sme_state == CFG80211_SME_CONNECTING)
242 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 252 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
243 WLAN_STATUS_UNSPECIFIED_FAILURE, 253 WLAN_STATUS_UNSPECIFIED_FAILURE,
244 false); 254 false, NULL);
245 255
246 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { 256 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
247 if (wdev->authtry_bsses[i] && 257 if (wdev->authtry_bsses[i] &&
@@ -275,7 +285,7 @@ void cfg80211_send_assoc_timeout(struct net_device *dev, const u8 *addr)
275 if (wdev->sme_state == CFG80211_SME_CONNECTING) 285 if (wdev->sme_state == CFG80211_SME_CONNECTING)
276 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0, 286 __cfg80211_connect_result(dev, addr, NULL, 0, NULL, 0,
277 WLAN_STATUS_UNSPECIFIED_FAILURE, 287 WLAN_STATUS_UNSPECIFIED_FAILURE,
278 false); 288 false, NULL);
279 289
280 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) { 290 for (i = 0; addr && i < MAX_AUTH_BSSES; i++) {
281 if (wdev->auth_bsses[i] && 291 if (wdev->auth_bsses[i] &&
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index fb40428a5946..b3ac0aace0e5 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -62,6 +62,16 @@ const struct ieee80211_regdomain *cfg80211_regdomain;
62 */ 62 */
63static const struct ieee80211_regdomain *country_ie_regdomain; 63static const struct ieee80211_regdomain *country_ie_regdomain;
64 64
65/*
66 * Protects static reg.c components:
67 * - cfg80211_world_regdom
68 * - cfg80211_regdom
69 * - country_ie_regdomain
70 * - last_request
71 */
72DEFINE_MUTEX(reg_mutex);
73#define assert_reg_lock() WARN_ON(!mutex_is_locked(&reg_mutex))
74
65/* Used to queue up regulatory hints */ 75/* Used to queue up regulatory hints */
66static LIST_HEAD(reg_requests_list); 76static LIST_HEAD(reg_requests_list);
67static spinlock_t reg_requests_lock; 77static spinlock_t reg_requests_lock;
@@ -1293,7 +1303,7 @@ static void handle_channel_custom(struct wiphy *wiphy,
1293 struct ieee80211_supported_band *sband; 1303 struct ieee80211_supported_band *sband;
1294 struct ieee80211_channel *chan; 1304 struct ieee80211_channel *chan;
1295 1305
1296 assert_cfg80211_lock(); 1306 assert_reg_lock();
1297 1307
1298 sband = wiphy->bands[band]; 1308 sband = wiphy->bands[band];
1299 BUG_ON(chan_idx >= sband->n_channels); 1309 BUG_ON(chan_idx >= sband->n_channels);
@@ -1342,14 +1352,14 @@ void wiphy_apply_custom_regulatory(struct wiphy *wiphy,
1342 enum ieee80211_band band; 1352 enum ieee80211_band band;
1343 unsigned int bands_set = 0; 1353 unsigned int bands_set = 0;
1344 1354
1345 mutex_lock(&cfg80211_mutex); 1355 mutex_lock(&reg_mutex);
1346 for (band = 0; band < IEEE80211_NUM_BANDS; band++) { 1356 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1347 if (!wiphy->bands[band]) 1357 if (!wiphy->bands[band])
1348 continue; 1358 continue;
1349 handle_band_custom(wiphy, band, regd); 1359 handle_band_custom(wiphy, band, regd);
1350 bands_set++; 1360 bands_set++;
1351 } 1361 }
1352 mutex_unlock(&cfg80211_mutex); 1362 mutex_unlock(&reg_mutex);
1353 1363
1354 /* 1364 /*
1355 * no point in calling this if it won't have any effect 1365 * no point in calling this if it won't have any effect
@@ -1495,7 +1505,7 @@ static int ignore_request(struct wiphy *wiphy,
1495 * Returns zero if all went fine, %-EALREADY if a regulatory domain had 1505 * Returns zero if all went fine, %-EALREADY if a regulatory domain had
1496 * already been set or other standard error codes. 1506 * already been set or other standard error codes.
1497 * 1507 *
1498 * Caller must hold &cfg80211_mutex 1508 * Caller must hold &cfg80211_mutex and &reg_mutex
1499 */ 1509 */
1500static int __regulatory_hint(struct wiphy *wiphy, 1510static int __regulatory_hint(struct wiphy *wiphy,
1501 struct regulatory_request *pending_request) 1511 struct regulatory_request *pending_request)
@@ -1570,6 +1580,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1570 BUG_ON(!reg_request->alpha2); 1580 BUG_ON(!reg_request->alpha2);
1571 1581
1572 mutex_lock(&cfg80211_mutex); 1582 mutex_lock(&cfg80211_mutex);
1583 mutex_lock(&reg_mutex);
1573 1584
1574 if (wiphy_idx_valid(reg_request->wiphy_idx)) 1585 if (wiphy_idx_valid(reg_request->wiphy_idx))
1575 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx); 1586 wiphy = wiphy_idx_to_wiphy(reg_request->wiphy_idx);
@@ -1585,6 +1596,7 @@ static void reg_process_hint(struct regulatory_request *reg_request)
1585 if (r == -EALREADY && wiphy && wiphy->strict_regulatory) 1596 if (r == -EALREADY && wiphy && wiphy->strict_regulatory)
1586 wiphy_update_regulatory(wiphy, reg_request->initiator); 1597 wiphy_update_regulatory(wiphy, reg_request->initiator);
1587out: 1598out:
1599 mutex_unlock(&reg_mutex);
1588 mutex_unlock(&cfg80211_mutex); 1600 mutex_unlock(&cfg80211_mutex);
1589} 1601}
1590 1602
@@ -1613,6 +1625,10 @@ static void reg_process_pending_beacon_hints(void)
1613 struct cfg80211_registered_device *rdev; 1625 struct cfg80211_registered_device *rdev;
1614 struct reg_beacon *pending_beacon, *tmp; 1626 struct reg_beacon *pending_beacon, *tmp;
1615 1627
1628 /*
1629 * No need to hold the reg_mutex here as we just touch wiphys
1630 * and do not read or access regulatory variables.
1631 */
1616 mutex_lock(&cfg80211_mutex); 1632 mutex_lock(&cfg80211_mutex);
1617 1633
1618 /* This goes through the _pending_ beacon list */ 1634 /* This goes through the _pending_ beacon list */
@@ -1734,12 +1750,13 @@ int regulatory_hint(struct wiphy *wiphy, const char *alpha2)
1734} 1750}
1735EXPORT_SYMBOL(regulatory_hint); 1751EXPORT_SYMBOL(regulatory_hint);
1736 1752
1753/* Caller must hold reg_mutex */
1737static bool reg_same_country_ie_hint(struct wiphy *wiphy, 1754static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1738 u32 country_ie_checksum) 1755 u32 country_ie_checksum)
1739{ 1756{
1740 struct wiphy *request_wiphy; 1757 struct wiphy *request_wiphy;
1741 1758
1742 assert_cfg80211_lock(); 1759 assert_reg_lock();
1743 1760
1744 if (unlikely(last_request->initiator != 1761 if (unlikely(last_request->initiator !=
1745 NL80211_REGDOM_SET_BY_COUNTRY_IE)) 1762 NL80211_REGDOM_SET_BY_COUNTRY_IE))
@@ -1762,6 +1779,10 @@ static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1762 return false; 1779 return false;
1763} 1780}
1764 1781
1782/*
1783 * We hold wdev_lock() here so we cannot hold cfg80211_mutex() and
1784 * therefore cannot iterate over the rdev list here.
1785 */
1765void regulatory_hint_11d(struct wiphy *wiphy, 1786void regulatory_hint_11d(struct wiphy *wiphy,
1766 u8 *country_ie, 1787 u8 *country_ie,
1767 u8 country_ie_len) 1788 u8 country_ie_len)
@@ -1772,12 +1793,10 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1772 enum environment_cap env = ENVIRON_ANY; 1793 enum environment_cap env = ENVIRON_ANY;
1773 struct regulatory_request *request; 1794 struct regulatory_request *request;
1774 1795
1775 mutex_lock(&cfg80211_mutex); 1796 mutex_lock(&reg_mutex);
1776 1797
1777 if (unlikely(!last_request)) { 1798 if (unlikely(!last_request))
1778 mutex_unlock(&cfg80211_mutex); 1799 goto out;
1779 return;
1780 }
1781 1800
1782 /* IE len must be evenly divisible by 2 */ 1801 /* IE len must be evenly divisible by 2 */
1783 if (country_ie_len & 0x01) 1802 if (country_ie_len & 0x01)
@@ -1803,54 +1822,14 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1803 env = ENVIRON_OUTDOOR; 1822 env = ENVIRON_OUTDOOR;
1804 1823
1805 /* 1824 /*
1806 * We will run this for *every* beacon processed for the BSSID, so 1825 * We will run this only upon a successful connection on cfg80211.
1807 * we optimize an early check to exit out early if we don't have to 1826 * We leave conflict resolution to the workqueue, where can hold
1808 * do anything 1827 * cfg80211_mutex.
1809 */ 1828 */
1810 if (likely(last_request->initiator == 1829 if (likely(last_request->initiator ==
1811 NL80211_REGDOM_SET_BY_COUNTRY_IE && 1830 NL80211_REGDOM_SET_BY_COUNTRY_IE &&
1812 wiphy_idx_valid(last_request->wiphy_idx))) { 1831 wiphy_idx_valid(last_request->wiphy_idx)))
1813 struct cfg80211_registered_device *rdev_last_ie; 1832 goto out;
1814
1815 rdev_last_ie =
1816 cfg80211_rdev_by_wiphy_idx(last_request->wiphy_idx);
1817
1818 /*
1819 * Lets keep this simple -- we trust the first AP
1820 * after we intersect with CRDA
1821 */
1822 if (likely(&rdev_last_ie->wiphy == wiphy)) {
1823 /*
1824 * Ignore IEs coming in on this wiphy with
1825 * the same alpha2 and environment cap
1826 */
1827 if (likely(alpha2_equal(rdev_last_ie->country_ie_alpha2,
1828 alpha2) &&
1829 env == rdev_last_ie->env)) {
1830 goto out;
1831 }
1832 /*
1833 * the wiphy moved on to another BSSID or the AP
1834 * was reconfigured. XXX: We need to deal with the
1835 * case where the user suspends and goes to goes
1836 * to another country, and then gets IEs from an
1837 * AP with different settings
1838 */
1839 goto out;
1840 } else {
1841 /*
1842 * Ignore IEs coming in on two separate wiphys with
1843 * the same alpha2 and environment cap
1844 */
1845 if (likely(alpha2_equal(rdev_last_ie->country_ie_alpha2,
1846 alpha2) &&
1847 env == rdev_last_ie->env)) {
1848 goto out;
1849 }
1850 /* We could potentially intersect though */
1851 goto out;
1852 }
1853 }
1854 1833
1855 rd = country_ie_2_rd(country_ie, country_ie_len, &checksum); 1834 rd = country_ie_2_rd(country_ie, country_ie_len, &checksum);
1856 if (!rd) 1835 if (!rd)
@@ -1885,7 +1864,7 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1885 request->country_ie_checksum = checksum; 1864 request->country_ie_checksum = checksum;
1886 request->country_ie_env = env; 1865 request->country_ie_env = env;
1887 1866
1888 mutex_unlock(&cfg80211_mutex); 1867 mutex_unlock(&reg_mutex);
1889 1868
1890 queue_regulatory_request(request); 1869 queue_regulatory_request(request);
1891 1870
@@ -1894,9 +1873,8 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1894free_rd_out: 1873free_rd_out:
1895 kfree(rd); 1874 kfree(rd);
1896out: 1875out:
1897 mutex_unlock(&cfg80211_mutex); 1876 mutex_unlock(&reg_mutex);
1898} 1877}
1899EXPORT_SYMBOL(regulatory_hint_11d);
1900 1878
1901static bool freq_is_chan_12_13_14(u16 freq) 1879static bool freq_is_chan_12_13_14(u16 freq)
1902{ 1880{
@@ -2227,10 +2205,13 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2227 2205
2228 assert_cfg80211_lock(); 2206 assert_cfg80211_lock();
2229 2207
2208 mutex_lock(&reg_mutex);
2209
2230 /* Note that this doesn't update the wiphys, this is done below */ 2210 /* Note that this doesn't update the wiphys, this is done below */
2231 r = __set_regdom(rd); 2211 r = __set_regdom(rd);
2232 if (r) { 2212 if (r) {
2233 kfree(rd); 2213 kfree(rd);
2214 mutex_unlock(&reg_mutex);
2234 return r; 2215 return r;
2235 } 2216 }
2236 2217
@@ -2245,6 +2226,8 @@ int set_regdom(const struct ieee80211_regdomain *rd)
2245 2226
2246 nl80211_send_reg_change_event(last_request); 2227 nl80211_send_reg_change_event(last_request);
2247 2228
2229 mutex_unlock(&reg_mutex);
2230
2248 return r; 2231 return r;
2249} 2232}
2250 2233
@@ -2255,16 +2238,20 @@ void reg_device_remove(struct wiphy *wiphy)
2255 2238
2256 assert_cfg80211_lock(); 2239 assert_cfg80211_lock();
2257 2240
2241 mutex_lock(&reg_mutex);
2242
2258 kfree(wiphy->regd); 2243 kfree(wiphy->regd);
2259 2244
2260 if (last_request) 2245 if (last_request)
2261 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx); 2246 request_wiphy = wiphy_idx_to_wiphy(last_request->wiphy_idx);
2262 2247
2263 if (!request_wiphy || request_wiphy != wiphy) 2248 if (!request_wiphy || request_wiphy != wiphy)
2264 return; 2249 goto out;
2265 2250
2266 last_request->wiphy_idx = WIPHY_IDX_STALE; 2251 last_request->wiphy_idx = WIPHY_IDX_STALE;
2267 last_request->country_ie_env = ENVIRON_ANY; 2252 last_request->country_ie_env = ENVIRON_ANY;
2253out:
2254 mutex_unlock(&reg_mutex);
2268} 2255}
2269 2256
2270int regulatory_init(void) 2257int regulatory_init(void)
@@ -2325,6 +2312,7 @@ void regulatory_exit(void)
2325 cancel_work_sync(&reg_work); 2312 cancel_work_sync(&reg_work);
2326 2313
2327 mutex_lock(&cfg80211_mutex); 2314 mutex_lock(&cfg80211_mutex);
2315 mutex_lock(&reg_mutex);
2328 2316
2329 reset_regdomains(); 2317 reset_regdomains();
2330 2318
@@ -2363,5 +2351,6 @@ void regulatory_exit(void)
2363 } 2351 }
2364 spin_unlock(&reg_requests_lock); 2352 spin_unlock(&reg_requests_lock);
2365 2353
2354 mutex_unlock(&reg_mutex);
2366 mutex_unlock(&cfg80211_mutex); 2355 mutex_unlock(&cfg80211_mutex);
2367} 2356}
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index e37829a49dc4..662a9dad76d5 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -36,4 +36,19 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
36 struct ieee80211_channel *beacon_chan, 36 struct ieee80211_channel *beacon_chan,
37 gfp_t gfp); 37 gfp_t gfp);
38 38
39/**
40 * regulatory_hint_11d - hints a country IE as a regulatory domain
41 * @wiphy: the wireless device giving the hint (used only for reporting
42 * conflicts)
43 * @country_ie: pointer to the country IE
44 * @country_ie_len: length of the country IE
45 *
46 * We will intersect the rd with the what CRDA tells us should apply
47 * for the alpha2 this country IE belongs to, this prevents APs from
48 * sending us incorrect or outdated information against a country.
49 */
50void regulatory_hint_11d(struct wiphy *wiphy,
51 u8 *country_ie,
52 u8 country_ie_len);
53
39#endif /* __NET_WIRELESS_REG_H */ 54#endif /* __NET_WIRELESS_REG_H */
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index d2b5d4ce0a00..8a7dcbf90602 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -13,6 +13,7 @@
13#include <net/cfg80211.h> 13#include <net/cfg80211.h>
14#include <net/rtnetlink.h> 14#include <net/rtnetlink.h>
15#include "nl80211.h" 15#include "nl80211.h"
16#include "reg.h"
16 17
17struct cfg80211_conn { 18struct cfg80211_conn {
18 struct cfg80211_connect_params params; 19 struct cfg80211_connect_params params;
@@ -182,7 +183,7 @@ void cfg80211_conn_work(struct work_struct *work)
182 wdev->conn->params.bssid, 183 wdev->conn->params.bssid,
183 NULL, 0, NULL, 0, 184 NULL, 0, NULL, 0,
184 WLAN_STATUS_UNSPECIFIED_FAILURE, 185 WLAN_STATUS_UNSPECIFIED_FAILURE,
185 false); 186 false, NULL);
186 wdev_unlock(wdev); 187 wdev_unlock(wdev);
187 } 188 }
188 189
@@ -247,7 +248,7 @@ static void __cfg80211_sme_scan_done(struct net_device *dev)
247 wdev->conn->params.bssid, 248 wdev->conn->params.bssid,
248 NULL, 0, NULL, 0, 249 NULL, 0, NULL, 0,
249 WLAN_STATUS_UNSPECIFIED_FAILURE, 250 WLAN_STATUS_UNSPECIFIED_FAILURE,
250 false); 251 false, NULL);
251 } 252 }
252} 253}
253 254
@@ -305,7 +306,7 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
305 schedule_work(&rdev->conn_work); 306 schedule_work(&rdev->conn_work);
306 } else if (status_code != WLAN_STATUS_SUCCESS) { 307 } else if (status_code != WLAN_STATUS_SUCCESS) {
307 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0, 308 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
308 status_code, false); 309 status_code, false, NULL);
309 } else if (wdev->sme_state == CFG80211_SME_CONNECTING && 310 } else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
310 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) { 311 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
311 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 312 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
@@ -316,10 +317,11 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
316void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 317void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
317 const u8 *req_ie, size_t req_ie_len, 318 const u8 *req_ie, size_t req_ie_len,
318 const u8 *resp_ie, size_t resp_ie_len, 319 const u8 *resp_ie, size_t resp_ie_len,
319 u16 status, bool wextev) 320 u16 status, bool wextev,
321 struct cfg80211_bss *bss)
320{ 322{
321 struct wireless_dev *wdev = dev->ieee80211_ptr; 323 struct wireless_dev *wdev = dev->ieee80211_ptr;
322 struct cfg80211_bss *bss; 324 u8 *country_ie;
323#ifdef CONFIG_WIRELESS_EXT 325#ifdef CONFIG_WIRELESS_EXT
324 union iwreq_data wrqu; 326 union iwreq_data wrqu;
325#endif 327#endif
@@ -361,6 +363,12 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
361 } 363 }
362#endif 364#endif
363 365
366 if (wdev->current_bss) {
367 cfg80211_unhold_bss(wdev->current_bss);
368 cfg80211_put_bss(&wdev->current_bss->pub);
369 wdev->current_bss = NULL;
370 }
371
364 if (status == WLAN_STATUS_SUCCESS && 372 if (status == WLAN_STATUS_SUCCESS &&
365 wdev->sme_state == CFG80211_SME_IDLE) 373 wdev->sme_state == CFG80211_SME_IDLE)
366 goto success; 374 goto success;
@@ -368,12 +376,6 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
368 if (wdev->sme_state != CFG80211_SME_CONNECTING) 376 if (wdev->sme_state != CFG80211_SME_CONNECTING)
369 return; 377 return;
370 378
371 if (wdev->current_bss) {
372 cfg80211_unhold_bss(wdev->current_bss);
373 cfg80211_put_bss(&wdev->current_bss->pub);
374 wdev->current_bss = NULL;
375 }
376
377 if (wdev->conn) 379 if (wdev->conn)
378 wdev->conn->state = CFG80211_CONN_IDLE; 380 wdev->conn->state = CFG80211_CONN_IDLE;
379 381
@@ -383,13 +385,16 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
383 wdev->conn = NULL; 385 wdev->conn = NULL;
384 kfree(wdev->connect_keys); 386 kfree(wdev->connect_keys);
385 wdev->connect_keys = NULL; 387 wdev->connect_keys = NULL;
388 wdev->ssid_len = 0;
386 return; 389 return;
387 } 390 }
388 391
389 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid, 392 success:
390 wdev->ssid, wdev->ssid_len, 393 if (!bss)
391 WLAN_CAPABILITY_ESS, 394 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
392 WLAN_CAPABILITY_ESS); 395 wdev->ssid, wdev->ssid_len,
396 WLAN_CAPABILITY_ESS,
397 WLAN_CAPABILITY_ESS);
393 398
394 if (WARN_ON(!bss)) 399 if (WARN_ON(!bss))
395 return; 400 return;
@@ -397,9 +402,22 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
397 cfg80211_hold_bss(bss_from_pub(bss)); 402 cfg80211_hold_bss(bss_from_pub(bss));
398 wdev->current_bss = bss_from_pub(bss); 403 wdev->current_bss = bss_from_pub(bss);
399 404
400 success:
401 wdev->sme_state = CFG80211_SME_CONNECTED; 405 wdev->sme_state = CFG80211_SME_CONNECTED;
402 cfg80211_upload_connect_keys(wdev); 406 cfg80211_upload_connect_keys(wdev);
407
408 country_ie = (u8 *) ieee80211_bss_get_ie(bss, WLAN_EID_COUNTRY);
409
410 if (!country_ie)
411 return;
412
413 /*
414 * ieee80211_bss_get_ie() ensures we can access:
415 * - country_ie + 2, the start of the country ie data, and
416 * - and country_ie[1] which is the IE length
417 */
418 regulatory_hint_11d(wdev->wiphy,
419 country_ie + 2,
420 country_ie[1]);
403} 421}
404 422
405void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 423void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
@@ -549,6 +567,7 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
549 567
550 wdev->current_bss = NULL; 568 wdev->current_bss = NULL;
551 wdev->sme_state = CFG80211_SME_IDLE; 569 wdev->sme_state = CFG80211_SME_IDLE;
570 wdev->ssid_len = 0;
552 571
553 if (wdev->conn) { 572 if (wdev->conn) {
554 kfree(wdev->conn->ie); 573 kfree(wdev->conn->ie);
@@ -704,6 +723,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
704 wdev->conn = NULL; 723 wdev->conn = NULL;
705 wdev->sme_state = CFG80211_SME_IDLE; 724 wdev->sme_state = CFG80211_SME_IDLE;
706 wdev->connect_keys = NULL; 725 wdev->connect_keys = NULL;
726 wdev->ssid_len = 0;
707 } 727 }
708 728
709 return err; 729 return err;
@@ -768,6 +788,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
768 wdev->sme_state = CFG80211_SME_IDLE; 788 wdev->sme_state = CFG80211_SME_IDLE;
769 kfree(wdev->conn); 789 kfree(wdev->conn);
770 wdev->conn = NULL; 790 wdev->conn = NULL;
791 wdev->ssid_len = 0;
771 return 0; 792 return 0;
772 } 793 }
773 794
@@ -788,7 +809,7 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
788 else if (wdev->sme_state == CFG80211_SME_CONNECTING) 809 else if (wdev->sme_state == CFG80211_SME_CONNECTING)
789 __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0, 810 __cfg80211_connect_result(dev, NULL, NULL, 0, NULL, 0,
790 WLAN_STATUS_UNSPECIFIED_FAILURE, 811 WLAN_STATUS_UNSPECIFIED_FAILURE,
791 wextev); 812 wextev, NULL);
792 813
793 return 0; 814 return 0;
794} 815}
diff --git a/net/wireless/wext.c b/net/wireless/wext.c
index 3fe3c2c0ce11..5b4a0cee4418 100644
--- a/net/wireless/wext.c
+++ b/net/wireless/wext.c
@@ -1291,7 +1291,6 @@ static struct pernet_operations wext_pernet_ops = {
1291static int __init wireless_nlevent_init(void) 1291static int __init wireless_nlevent_init(void)
1292{ 1292{
1293 return register_pernet_subsys(&wext_pernet_ops); 1293 return register_pernet_subsys(&wext_pernet_ops);
1294 return 0;
1295} 1294}
1296 1295
1297subsys_initcall(wireless_nlevent_init); 1296subsys_initcall(wireless_nlevent_init);