diff options
author | David S. Miller <davem@davemloft.net> | 2009-08-06 15:57:18 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-08-06 15:57:18 -0400 |
commit | bfe34ebbaa125f00da309f59cc9d30febe1e3115 (patch) | |
tree | 505b43fc81be09ec5b42f82a3e64f300a5e838d5 | |
parent | 3d7ddd540b4c2d24c6a3e7a52c083a0c31e6151c (diff) | |
parent | 6b4f645a491ac29c7dced415d034eea7736155a6 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
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) | |||
65 | EXPORT_SYMBOL_GPL(rndis_status); | 65 | EXPORT_SYMBOL_GPL(rndis_status); |
66 | 66 | ||
67 | /* | 67 | /* |
68 | * RNDIS indicate messages. | ||
69 | */ | ||
70 | static 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 @@ | |||
5 | menu "Wireless LAN" | 5 | menu "Wireless LAN" |
6 | depends on !S390 | 6 | depends on !S390 |
7 | 7 | ||
8 | config WLAN_PRE80211 | 8 | menuconfig 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 | ||
104 | config WLAN_80211 | 104 | menuconfig 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 | ||
1940 | exit: | 1943 | exit: |
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 | ||
2030 | static int at76_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 2033 | static 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 @@ | |||
1 | config ATH_COMMON | 1 | menuconfig 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 | |||
20 | if ATH_COMMON | ||
6 | source "drivers/net/wireless/ath/ath5k/Kconfig" | 21 | source "drivers/net/wireless/ath/ath5k/Kconfig" |
7 | source "drivers/net/wireless/ath/ath9k/Kconfig" | 22 | source "drivers/net/wireless/ath/ath9k/Kconfig" |
8 | source "drivers/net/wireless/ath/ar9170/Kconfig" | 23 | source "drivers/net/wireless/ath/ar9170/Kconfig" |
9 | 24 | endif | |
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 @@ | |||
1 | config AR9170_USB | 1 | config 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 | ||
98 | static void ar9170_led_brightness_set(struct led_classdev *led, | 101 | static 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 | ||
116 | static int ar9170_register_led(struct ar9170 *ar, int i, char *name, | 119 | static 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 | ||
604 | void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len) | 606 | void 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 | ||
1835 | static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb) | 1838 | static 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 | ||
2164 | static void ar9170_op_bss_info_changed(struct ieee80211_hw *hw, | 2167 | static 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 | ||
2422 | static int ar9170_get_stats(struct ieee80211_hw *hw, | 2425 | static 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 @@ | |||
1 | config ATH5K | 1 | config 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) | |||
1998 | static void | 2000 | static void |
1999 | ath5k_tasklet_tx(unsigned long data) | 2001 | ath5k_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; |
2773 | end: | 2779 | end: |
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 @@ | |||
1 | config ATH9K | 1 | config 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 | ||
780 | void ath9k_hw_ani_attach(struct ath_hw *ah) | 780 | void 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 | ||
825 | void ath9k_hw_ani_detach(struct ath_hw *ah) | 825 | void 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, | |||
132 | void ath9k_hw_procmibevent(struct ath_hw *ah, | 132 | void ath9k_hw_procmibevent(struct ath_hw *ah, |
133 | const struct ath9k_node_stats *stats); | 133 | const struct ath9k_node_stats *stats); |
134 | void ath9k_hw_ani_setup(struct ath_hw *ah); | 134 | void ath9k_hw_ani_setup(struct ath_hw *ah); |
135 | void ath9k_hw_ani_attach(struct ath_hw *ah); | 135 | void ath9k_hw_ani_init(struct ath_hw *ah); |
136 | void ath9k_hw_ani_detach(struct ath_hw *ah); | 136 | void 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 | ||
643 | irqreturn_t ath_isr(int irq, void *dev); | 643 | irqreturn_t ath_isr(int irq, void *dev); |
644 | void ath_cleanup(struct ath_softc *sc); | 644 | void ath_cleanup(struct ath_softc *sc); |
645 | int ath_attach(u16 devid, struct ath_softc *sc); | 645 | int ath_init_device(u16 devid, struct ath_softc *sc); |
646 | void ath_detach(struct ath_softc *sc); | 646 | void ath_detach(struct ath_softc *sc); |
647 | const char *ath_mac_bb_name(u32 mac_bb_version); | 647 | const char *ath_mac_bb_name(u32 mac_bb_version); |
648 | const char *ath_rf_name(u16 rf_version); | 648 | const 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 | ||
756 | static 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 | |||
756 | static inline void ath9k_hw_9285_pa_cal(struct ath_hw *ah) | 848 | static 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 | */ | ||
1240 | static void ath9k_hw_4k_set_board_values(struct ath_hw *ah, | 1244 | static 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 | ||
2795 | static bool ath9k_hw_AR9287_fill_eeprom(struct ath_hw *ah) | 2871 | static 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 | } |
2817 | static int ath9k_hw_AR9287_check_eeprom(struct ath_hw *ah) | 2893 | static 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 | ||
2920 | static u32 ath9k_hw_AR9287_get_eeprom(struct ath_hw *ah, | 3001 | static 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, ¢ers); | 3467 | ath9k_hw_get_channel_centers(ah, chan, ¢ers); |
@@ -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, | |||
3776 | static void ath9k_hw_AR9287_set_board_values(struct ath_hw *ah, | 3857 | static 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, | |||
3928 | static u16 ath9k_hw_AR9287_get_eeprom_antenna_cfg(struct ath_hw *ah, | 4009 | static 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 | ||
3981 | int ath9k_hw_eeprom_attach(struct ath_hw *ah) | 4062 | int 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 | ||
603 | struct ar9287_eeprom_t { | 603 | struct 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 | ||
668 | int ath9k_hw_eeprom_attach(struct ath_hw *ah); | 668 | int 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 | ||
391 | static void ath9k_hw_set_defaults(struct ath_hw *ah) | 391 | static 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 | ||
440 | static struct ath_hw *ath9k_hw_newstate(u16 devid, struct ath_softc *sc, | 440 | static 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 | ||
486 | static int ath9k_hw_rfattach(struct ath_hw *ah) | 471 | static 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 | ||
596 | static int ath9k_hw_post_attach(struct ath_hw *ah) | 581 | static 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 | ||
626 | static struct ath_hw *ath9k_hw_do_attach(u16 devid, struct ath_softc *sc, | 611 | static 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)) { | 630 | static 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 | ||
649 | static 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 | |||
673 | static 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) | 846 | static 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); | 886 | static 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 | |||
909 | int 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; |
952 | bad: | ||
953 | if (ah) | ||
954 | ath9k_hw_detach(ah); | ||
955 | if (status) | ||
956 | *status = ecode; | ||
957 | |||
958 | return NULL; | ||
959 | } | 998 | } |
960 | 999 | ||
961 | static void ath9k_hw_init_bb(struct ath_hw *ah, | 1000 | static void ath9k_hw_init_bb(struct ath_hw *ah, |
@@ -1194,35 +1233,12 @@ const char *ath9k_hw_probe(u16 vendorid, u16 devid) | |||
1194 | void ath9k_hw_detach(struct ath_hw *ah) | 1233 | void 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 | |||
1204 | struct 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) | |||
1232 | static void ath9k_hw_override_ini(struct ath_hw *ah, | 1248 | static 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 | ||
3155 | enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah) | ||
3156 | { | ||
3157 | return ah->mask_reg; | ||
3158 | } | ||
3159 | |||
3160 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints) | 3239 | enum 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 */ |
545 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); | 547 | const char *ath9k_hw_probe(u16 vendorid, u16 devid); |
546 | void ath9k_hw_detach(struct ath_hw *ah); | 548 | void ath9k_hw_detach(struct ath_hw *ah); |
547 | struct ath_hw *ath9k_hw_attach(u16 devid, struct ath_softc *sc, int *error); | 549 | int ath9k_hw_init(struct ath_hw *ah); |
548 | void ath9k_hw_rfdetach(struct ath_hw *ah); | 550 | void ath9k_hw_rf_free(struct ath_hw *ah); |
549 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, | 551 | int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, |
550 | bool bChannelChange); | 552 | bool bChannelChange); |
551 | void ath9k_hw_fill_cap_info(struct ath_hw *ah); | 553 | void 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 */ |
613 | bool ath9k_hw_intrpend(struct ath_hw *ah); | 615 | bool ath9k_hw_intrpend(struct ath_hw *ah); |
614 | bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked); | 616 | bool ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked); |
615 | enum ath9k_int ath9k_hw_intrget(struct ath_hw *ah); | ||
616 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints); | 617 | enum ath9k_int ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints); |
617 | 618 | ||
618 | void ath9k_hw_btcoex_enable(struct ath_hw *ah); | 619 | void 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 */ | ||
6369 | static 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 | |||
6693 | static 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 | ||
1057 | static void ath_deinit_leds(struct ath_softc *sc) | 1058 | static 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 | ||
1115 | fail: | 1115 | fail: |
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 | ||
1297 | static 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 | */ | ||
1302 | static 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]); |
1509 | bad: | 1519 | bad: |
1510 | if (ah) | 1520 | ath9k_hw_detach(ah); |
1511 | ath9k_hw_detach(ah); | 1521 | sc->sc_ah = NULL; |
1522 | bad_no_ah: | ||
1512 | ath9k_exit_debug(sc); | 1523 | ath9k_exit_debug(sc); |
1513 | 1524 | ||
1514 | return error; | 1525 | return r; |
1515 | } | 1526 | } |
1516 | 1527 | ||
1517 | void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw) | 1528 | void 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 | ||
1554 | int ath_attach(u16 devid, struct ath_softc *sc) | 1565 | /* Device driver core initialization */ |
1566 | int 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 | ||
1980 | mutex_unlock: | 1993 | mutex_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 | ||
266 | void | 266 | void |
267 | ath9k_hw_rfdetach(struct ath_hw *ah) | 267 | ath9k_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 | ||
307 | bool ath9k_hw_init_rf(struct ath_hw *ah, int *status) | 286 | bool 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 | ||
373 | static void ath9k_pause_iter(void *data, u8 *mac, struct ieee80211_vif *vif) | 373 | static 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 | ||
655 | void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int) | 656 | void 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 | ||
1660 | static void b43_set_beacon_int(struct b43_wldev *dev, u16 beacon_int) | 1663 | static 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); |
2918 | out: | 2921 | out: |
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. */ |
2932 | static int b43_validate_chipaccess(struct b43_wldev *dev) | 2935 | static 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 | ||
243 | void 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 | |||
243 | void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask) | 250 | void 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 | ||
358 | int b43_phy_shm_tssi_read(struct b43_wldev *dev, u16 shm_offset) | 365 | int 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); | |||
291 | void b43_phy_write(struct b43_wldev *dev, u16 reg, u16 value); | 291 | void 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 | */ | ||
296 | void 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 | */ |
296 | void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask); | 301 | void 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 | ||
67 | static void lpphy_baseband_rev0_1_init(struct b43_wldev *dev) | 67 | static 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 | ||
72 | static void lpphy_baseband_rev2plus_init(struct b43_wldev *dev) | 164 | static 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 | ||
789 | static void b43_pio_tx_suspend_queue(struct b43_pio_txqueue *q) | 789 | static 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 | ||
1258 | static void b43legacy_set_beacon_int(struct b43legacy_wldev *dev, | 1258 | static 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); |
2304 | out: | 2304 | out: |
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 */ | ||
77 | static 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 | |||
76 | static struct iwl_lib_ops iwl1000_lib = { | 88 | static 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 */ | ||
201 | void iwl5000_nic_config(struct iwl_priv *priv) | 202 | void 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 */ | ||
72 | static 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 | |||
71 | static struct iwl_lib_ops iwl6000_lib = { | 89 | static 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 | ||
135 | struct 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 | */ | ||
157 | struct 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 | ||
151 | struct iwl_cfg iwl6000_2agn_cfg = { | 174 | /* |
175 | * "i": Internal configuration, use internal Power Amplifier | ||
176 | */ | ||
177 | struct 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 | ||
167 | struct iwl_cfg iwl6050_2agn_cfg = { | 194 | struct 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 | ||
183 | struct iwl_cfg iwl6000_3agn_cfg = { | 211 | struct 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 | ||
199 | struct iwl_cfg iwl6050_3agn_cfg = { | 228 | struct 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 | ||
215 | MODULE_FIRMWARE(IWL6000_MODULE_FIRMWARE(IWL6000_UCODE_API_MAX)); | 245 | MODULE_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 | ||
2486 | static 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 | |||
2517 | static DEVICE_ATTR(version, S_IWUSR | S_IRUGO, show_version, NULL); | ||
2518 | |||
2519 | static ssize_t show_temperature(struct device *d, | 2492 | static 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 | } |
1143 | EXPORT_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 | } |
2294 | EXPORT_SYMBOL(iwl_send_card_state); | ||
2295 | 2290 | ||
2296 | void iwl_rx_pm_sleep_notif(struct iwl_priv *priv, | 2291 | void 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 | } |
2338 | EXPORT_SYMBOL(iwl_clear_isr_stats); | ||
2339 | 2333 | ||
2340 | int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | 2334 | int 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 | */ |
230 | struct iwl_cfg { | 232 | struct 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; | |||
56 | extern struct iwl_cfg iwl5100_bg_cfg; | 56 | extern struct iwl_cfg iwl5100_bg_cfg; |
57 | extern struct iwl_cfg iwl5100_abg_cfg; | 57 | extern struct iwl_cfg iwl5100_abg_cfg; |
58 | extern struct iwl_cfg iwl5150_agn_cfg; | 58 | extern struct iwl_cfg iwl5150_agn_cfg; |
59 | extern struct iwl_cfg iwl6000_2ag_cfg; | 59 | extern struct iwl_cfg iwl6000h_2agn_cfg; |
60 | extern struct iwl_cfg iwl6000_2agn_cfg; | 60 | extern struct iwl_cfg iwl6000i_2agn_cfg; |
61 | extern struct iwl_cfg iwl6000_3agn_cfg; | 61 | extern struct iwl_cfg iwl6000_3agn_cfg; |
62 | extern struct iwl_cfg iwl6050_2agn_cfg; | 62 | extern struct iwl_cfg iwl6050_2agn_cfg; |
63 | extern struct iwl_cfg iwl6050_3agn_cfg; | 63 | extern 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 | */ | ||
898 | enum 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 */ |
892 | struct isr_statistics { | 905 | struct 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 | } |
338 | EXPORT_SYMBOL(iwl_leds_background); | ||
339 | 338 | ||
340 | /* Register all led handler */ | 339 | /* Register all led handler */ |
341 | int iwl_leds_register(struct iwl_priv *priv) | 340 | int 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 | } |
409 | EXPORT_SYMBOL(iwl_rx_queue_reset); | ||
410 | 409 | ||
411 | int iwl_rx_init(struct iwl_priv *priv, struct iwl_rx_queue *rxq) | 410 | int 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 | } |
467 | EXPORT_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 | ||
485 | static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version) | 485 | static 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 | ||
529 | int 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 | |||
542 | static int iwm_check_profile(struct iwm_priv *iwm) | 529 | static 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 | ||
562 | int 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 | |||
575 | int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key) | 588 | int 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 | ||
159 | static 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 | |||
159 | const struct cfg80211_ops orinoco_cfg_ops = { | 199 | const 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 | ||
485 | static void p54spi_work(struct work_struct *work) | 485 | static 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 | ||
204 | enum 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 | |||
211 | enum ndis_80211_media_stream_mode { | ||
212 | NDIS_80211_MEDIA_STREAM_OFF, | ||
213 | NDIS_80211_MEDIA_STREAM_ON | ||
214 | }; | ||
215 | |||
216 | enum 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 | |||
205 | enum ndis_80211_addkey_bits { | 222 | enum 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 | ||
234 | struct ndis_80211_auth_request { | ||
235 | __le32 length; | ||
236 | u8 bssid[6]; | ||
237 | u8 padding[2]; | ||
238 | __le32 flags; | ||
239 | } __attribute__((packed)); | ||
240 | |||
241 | struct ndis_80211_pmkid_candidate { | ||
242 | u8 bssid[6]; | ||
243 | u8 padding[2]; | ||
244 | __le32 flags; | ||
245 | } __attribute__((packed)); | ||
246 | |||
247 | struct 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 | |||
253 | struct 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 | |||
217 | struct ndis_80211_ssid { | 263 | struct 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 | ||
286 | struct ndis_config_param { | 333 | struct ndis_config_param { |
@@ -366,6 +413,15 @@ static const struct ieee80211_rate rndis_rates[] = { | |||
366 | { .bitrate = 540 } | 413 | { .bitrate = 540 } |
367 | }; | 414 | }; |
368 | 415 | ||
416 | struct 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 */ |
370 | struct rndis_wlan_private { | 426 | struct 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 | ||
535 | static 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 | ||
545 | static 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 | ||
599 | static const char *oid_to_string(__le32 oid) | ||
600 | { | ||
601 | return "?"; | ||
602 | } | ||
603 | #endif | ||
604 | |||
605 | |||
481 | /* translate error code */ | 606 | /* translate error code */ |
482 | static int rndis_error_status(__le32 rndis_status) | 607 | static 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 | ||
743 | static 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 | */ |
746 | static int | 914 | static void restore_keys(struct usbnet *usbdev); |
747 | add_wep_key(struct usbnet *usbdev, char *key, int key_len, int index); | ||
748 | 915 | ||
749 | static int get_essid(struct usbnet *usbdev, struct ndis_80211_ssid *ssid) | 916 | static 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 | ||
1092 | static int add_wpa_key(struct usbnet *usbdev, const u8 *key, int key_len, | 1258 | static 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 | ||
1345 | static 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 | |||
1378 | static 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 | |||
1387 | static 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 */ |
1161 | static int remove_key(struct usbnet *usbdev, int index, u8 bssid[ETH_ALEN]) | 1394 | static 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 | ||
2107 | static void rndis_wlan_link_change(struct usbnet *usbdev, int state) | 2358 | |
2359 | static 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 | |||
2427 | static 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 | |||
2485 | static 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 | |||
2537 | static 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 | ||
2465 | fail: | 2916 | fail: |
@@ -2499,21 +2950,61 @@ static void rndis_wlan_unbind(struct usbnet *usbdev, struct usb_interface *intf) | |||
2499 | 2950 | ||
2500 | static int rndis_wlan_reset(struct usbnet *usbdev) | 2951 | static 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 | ||
2507 | static int rndis_wlan_stop(struct usbnet *usbdev) | 2973 | static 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 | ||
2514 | static const struct driver_info bcm4320b_info = { | 3004 | static 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 | ||
2528 | static const struct driver_info bcm4320a_info = { | 3019 | static 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 | ||
2542 | static const struct driver_info rndis_wlan_info = { | 3034 | static 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 @@ | |||
1 | menuconfig RT2X00 | 1 | menuconfig 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 | ||
80 | config RT2800USB | 80 | config 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 | } |
220 | EXPORT_SYMBOL_GPL(rt2x00lib_beacondone); | 220 | EXPORT_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 | ||
358 | void rt2x00link_stop_tuner(struct rt2x00_dev *rt2x00dev) | 358 | void 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 | ||
468 | void rt2x00link_register(struct rt2x00_dev *rt2x00dev) | 468 | void 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 | } |
436 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); | 436 | EXPORT_SYMBOL_GPL(rt2x00mac_configure_filter); |
437 | 437 | ||
438 | int 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 | } | ||
446 | EXPORT_SYMBOL_GPL(rt2x00mac_set_tim); | ||
447 | |||
438 | #ifdef CONFIG_RT2X00_LIB_CRYPTO | 448 | #ifdef CONFIG_RT2X00_LIB_CRYPTO |
439 | static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len) | 449 | static 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 | ||
457 | int 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 | } | ||
465 | EXPORT_SYMBOL_GPL(rt2x00mac_set_tim); | ||
466 | |||
467 | int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, | 467 | int 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 | ||
118 | static int rtl8187_register_led(struct ieee80211_hw *dev, | 118 | static 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); | |||
1514 | extern int regulatory_hint(struct wiphy *wiphy, const char *alpha2); | 1514 | extern 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 | */ | ||
1527 | extern 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 { | |||
954 | struct ieee80211_hw { | 963 | struct 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 | */ |
1244 | enum ieee80211_filter_flags { | 1255 | enum 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 | */ | ||
1952 | void 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 | */ | ||
1964 | void 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 | ||
363 | struct mesh_table *mesh_table_grow(struct mesh_table *tbl) | 363 | struct 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 | ||
571 | void ieee80211_sta_process_chanswitch(struct ieee80211_sub_if_data *sdata, | 572 | void 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 | ||
1157 | static 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 | |||
1159 | static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata, | 1171 | static 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 | } |
1238 | EXPORT_SYMBOL(ieee80211_beacon_loss); | 1242 | EXPORT_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 | ||
2032 | static void ieee80211_sta_work(struct work_struct *work) | 2034 | static 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 | ||
2203 | static void ieee80211_sta_conn_mon_timer(unsigned long data) | 2212 | static 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 | ||
2216 | static void ieee80211_sta_monitor_work(struct work_struct *work) | 2225 | static 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 | ||
722 | int ieee80211_request_scan(struct ieee80211_sub_if_data *sdata, | 722 | int 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 | } |
512 | EXPORT_SYMBOL_GPL(ieee80211_iterate_active_interfaces_atomic); | 512 | EXPORT_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 | */ | ||
521 | static 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 | |||
530 | void 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 | } | ||
539 | EXPORT_SYMBOL(ieee80211_queue_work); | ||
540 | |||
541 | void 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 | } | ||
552 | EXPORT_SYMBOL(ieee80211_queue_delayed_work); | ||
553 | |||
514 | void ieee802_11_parse_elems(u8 *start, size_t len, | 554 | void 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 | ||
599 | static ssize_t rfkill_type_show(struct device *dev, | 601 | static 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"); | |||
34 | LIST_HEAD(cfg80211_rdev_list); | 34 | LIST_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 | */ |
41 | DEFINE_MUTEX(cfg80211_mutex); | 39 | DEFINE_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 | ||
130 | static inline void cfg80211_ref_bss(struct cfg80211_internal_bss *bss) | ||
131 | { | ||
132 | kref_get(&bss->ref); | ||
133 | } | ||
134 | |||
130 | static inline void cfg80211_hold_bss(struct cfg80211_internal_bss *bss) | 135 | static 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, | |||
323 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 328 | void __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 */ |
329 | int __cfg80211_connect(struct cfg80211_registered_device *rdev, | 335 | int __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 | */ |
63 | static const struct ieee80211_regdomain *country_ie_regdomain; | 63 | static 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 | */ | ||
72 | DEFINE_MUTEX(reg_mutex); | ||
73 | #define assert_reg_lock() WARN_ON(!mutex_is_locked(®_mutex)) | ||
74 | |||
65 | /* Used to queue up regulatory hints */ | 75 | /* Used to queue up regulatory hints */ |
66 | static LIST_HEAD(reg_requests_list); | 76 | static LIST_HEAD(reg_requests_list); |
67 | static spinlock_t reg_requests_lock; | 77 | static 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(®_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(®_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 ®_mutex |
1499 | */ | 1509 | */ |
1500 | static int __regulatory_hint(struct wiphy *wiphy, | 1510 | static 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(®_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); |
1587 | out: | 1598 | out: |
1599 | mutex_unlock(®_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 | } |
1735 | EXPORT_SYMBOL(regulatory_hint); | 1751 | EXPORT_SYMBOL(regulatory_hint); |
1736 | 1752 | ||
1753 | /* Caller must hold reg_mutex */ | ||
1737 | static bool reg_same_country_ie_hint(struct wiphy *wiphy, | 1754 | static 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 | */ | ||
1765 | void regulatory_hint_11d(struct wiphy *wiphy, | 1786 | void 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(®_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(®_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, | |||
1894 | free_rd_out: | 1873 | free_rd_out: |
1895 | kfree(rd); | 1874 | kfree(rd); |
1896 | out: | 1875 | out: |
1897 | mutex_unlock(&cfg80211_mutex); | 1876 | mutex_unlock(®_mutex); |
1898 | } | 1877 | } |
1899 | EXPORT_SYMBOL(regulatory_hint_11d); | ||
1900 | 1878 | ||
1901 | static bool freq_is_chan_12_13_14(u16 freq) | 1879 | static 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(®_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(®_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(®_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(®_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; |
2253 | out: | ||
2254 | mutex_unlock(®_mutex); | ||
2268 | } | 2255 | } |
2269 | 2256 | ||
2270 | int regulatory_init(void) | 2257 | int regulatory_init(void) |
@@ -2325,6 +2312,7 @@ void regulatory_exit(void) | |||
2325 | cancel_work_sync(®_work); | 2312 | cancel_work_sync(®_work); |
2326 | 2313 | ||
2327 | mutex_lock(&cfg80211_mutex); | 2314 | mutex_lock(&cfg80211_mutex); |
2315 | mutex_lock(®_mutex); | ||
2328 | 2316 | ||
2329 | reset_regdomains(); | 2317 | reset_regdomains(); |
2330 | 2318 | ||
@@ -2363,5 +2351,6 @@ void regulatory_exit(void) | |||
2363 | } | 2351 | } |
2364 | spin_unlock(®_requests_lock); | 2352 | spin_unlock(®_requests_lock); |
2365 | 2353 | ||
2354 | mutex_unlock(®_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 | */ | ||
50 | void 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 | ||
17 | struct cfg80211_conn { | 18 | struct 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, | |||
316 | void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 317 | void __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 | ||
405 | void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, | 423 | void 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 = { | |||
1291 | static int __init wireless_nlevent_init(void) | 1291 | static 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 | ||
1297 | subsys_initcall(wireless_nlevent_init); | 1296 | subsys_initcall(wireless_nlevent_init); |