aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2009-07-26 13:01:25 -0400
committerDavid S. Miller <davem@davemloft.net>2009-07-26 13:01:25 -0400
commitc8b201ff867e64b6233d069563081775269f4499 (patch)
tree35d363e6cb565fd7285480dc877a2da79eafb9a7
parent436b355b96042ab6564f43a7dabd5c61d9634ff7 (diff)
parent249b405cf8145da8a74b70544ae1079d244bdb00 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
-rw-r--r--MAINTAINERS11
-rw-r--r--drivers/net/wireless/Kconfig6
-rw-r--r--drivers/net/wireless/adm8211.c17
-rw-r--r--drivers/net/wireless/arlan-main.c2
-rw-r--r--drivers/net/wireless/ath/ar9170/ar9170.h52
-rw-r--r--drivers/net/wireless/ath/ar9170/main.c609
-rw-r--r--drivers/net/wireless/ath/ath5k/reg.h12
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h48
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c70
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h18
-rw-r--r--drivers/net/wireless/ath/ath9k/initvals.h47
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c35
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c609
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.h29
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c25
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h93
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c17
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c76
-rw-r--r--drivers/net/wireless/b43/main.c4
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c3
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-hw.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c24
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c67
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c60
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c165
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c424
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c69
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h40
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-helpers.h21
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-led.c34
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-tx.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c89
-rw-r--r--drivers/net/wireless/iwmc3200wifi/cfg80211.c270
-rw-r--r--drivers/net/wireless/iwmc3200wifi/commands.c52
-rw-r--r--drivers/net/wireless/iwmc3200wifi/hal.c16
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h5
-rw-r--r--drivers/net/wireless/iwmc3200wifi/main.c7
-rw-r--r--drivers/net/wireless/iwmc3200wifi/rx.c96
-rw-r--r--drivers/net/wireless/iwmc3200wifi/umac.h6
-rw-r--r--drivers/net/wireless/iwmc3200wifi/wext.c320
-rw-r--r--drivers/net/wireless/libertas/assoc.c10
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c8
-rw-r--r--drivers/net/wireless/mwl8k.c6
-rw-r--r--drivers/net/wireless/p54/eeprom.c327
-rw-r--r--drivers/net/wireless/p54/fwio.c23
-rw-r--r--drivers/net/wireless/p54/lmac.h7
-rw-r--r--drivers/net/wireless/p54/main.c112
-rw-r--r--drivers/net/wireless/p54/p54.h3
-rw-r--r--drivers/net/wireless/p54/txrx.c80
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2400pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt2500usb.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c9
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h7
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00config.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00crypto.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00link.c2
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c14
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.h10
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00reg.h4
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c1
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.h4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_acx.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c61
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_netlink.c679
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_ops.c4
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_rx.h2
-rw-r--r--drivers/net/wireless/zd1211rw/zd_usb.c1
-rw-r--r--include/linux/nl80211.h52
-rw-r--r--include/linux/skbuff.h6
-rw-r--r--include/net/cfg80211.h20
-rw-r--r--include/net/mac80211.h37
-rw-r--r--net/core/dev.c2
-rw-r--r--net/core/skbuff.c3
-rw-r--r--net/mac80211/Kconfig12
-rw-r--r--net/mac80211/Makefile3
-rw-r--r--net/mac80211/agg-tx.c3
-rw-r--r--net/mac80211/cfg.c2
-rw-r--r--net/mac80211/debugfs.c2
-rw-r--r--net/mac80211/driver-ops.h85
-rw-r--r--net/mac80211/driver-trace.c6
-rw-r--r--net/mac80211/driver-trace.h648
-rw-r--r--net/mac80211/ibss.c9
-rw-r--r--net/mac80211/ieee80211_i.h47
-rw-r--r--net/mac80211/iface.c51
-rw-r--r--net/mac80211/main.c120
-rw-r--r--net/mac80211/mesh.c5
-rw-r--r--net/mac80211/mesh_hwmp.c9
-rw-r--r--net/mac80211/mesh_pathtbl.c26
-rw-r--r--net/mac80211/mlme.c308
-rw-r--r--net/mac80211/rate.c31
-rw-r--r--net/mac80211/rc80211_minstrel.c23
-rw-r--r--net/mac80211/rc80211_pid_algo.c12
-rw-r--r--net/mac80211/rx.c55
-rw-r--r--net/mac80211/scan.c19
-rw-r--r--net/mac80211/tx.c323
-rw-r--r--net/mac80211/util.c68
-rw-r--r--net/mac80211/wep.c6
-rw-r--r--net/mac80211/wep.h3
-rw-r--r--net/mac80211/wme.c6
-rw-r--r--net/mac80211/wme.h3
-rw-r--r--net/wireless/core.c21
-rw-r--r--net/wireless/core.h32
-rw-r--r--net/wireless/ibss.c84
-rw-r--r--net/wireless/mlme.c24
-rw-r--r--net/wireless/nl80211.c428
-rw-r--r--net/wireless/reg.c25
-rw-r--r--net/wireless/sme.c112
-rw-r--r--net/wireless/util.c45
-rw-r--r--net/wireless/wext-compat.c202
-rw-r--r--net/wireless/wext-sme.c76
134 files changed, 4999 insertions, 3237 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index d119ba9e724d..df55d24a2f69 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4984,7 +4984,7 @@ L: linux-wireless@vger.kernel.org
4984W: http://linuxwireless.org/ 4984W: http://linuxwireless.org/
4985T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git 4985T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
4986S: Maintained 4986S: Maintained
4987F: drivers/net/wireless/rtl818* 4987F: drivers/net/wireless/rtl818x/rtl8180*
4988 4988
4989RTL8187 WIRELESS DRIVER 4989RTL8187 WIRELESS DRIVER
4990P: Herton Ronaldo Krzesinski 4990P: Herton Ronaldo Krzesinski
@@ -6466,6 +6466,15 @@ M: mitr@volny.cz
6466S: Maintained 6466S: Maintained
6467F: drivers/input/misc/wistron_btns.c 6467F: drivers/input/misc/wistron_btns.c
6468 6468
6469WL1251 WIRELESS DRIVER
6470P: Kalle Valo
6471M: kalle.valo@nokia.com
6472L: linux-wireless@vger.kernel.org
6473W: http://wireless.kernel.org
6474T: git git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-testing.git
6475S: Maintained
6476F: drivers/net/wireless/wl12xx/wl1251*
6477
6469WL3501 WIRELESS PCMCIA CARD DRIVER 6478WL3501 WIRELESS PCMCIA CARD DRIVER
6470P: Arnaldo Carvalho de Melo 6479P: Arnaldo Carvalho de Melo
6471M: acme@ghostprotocols.net 6480M: acme@ghostprotocols.net
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 5bc00db21b24..ca7a8a31d0b9 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -428,10 +428,12 @@ config RTL8187
428 Micronet SP907GK V5 428 Micronet SP907GK V5
429 Encore ENUWI-G2 429 Encore ENUWI-G2
430 Trendnet TEW-424UB 430 Trendnet TEW-424UB
431 ASUS P5B Deluxe 431 ASUS P5B Deluxe/P5K Premium motherboards
432 Toshiba Satellite Pro series of laptops 432 Toshiba Satellite Pro series of laptops
433 Asus Wireless Link 433 Asus Wireless Link
434 Linksys WUSB54GC-EU 434 Linksys WUSB54GC-EU v2
435 (v1 = rt73usb; v3 is rt2070-based,
436 use staging/rt3070 or try rt2800usb)
435 437
436 Thanks to Realtek for their support! 438 Thanks to Realtek for their support!
437 439
diff --git a/drivers/net/wireless/adm8211.c b/drivers/net/wireless/adm8211.c
index ecc93834533f..5695911bc602 100644
--- a/drivers/net/wireless/adm8211.c
+++ b/drivers/net/wireless/adm8211.c
@@ -1964,14 +1964,6 @@ static void __devexit adm8211_remove(struct pci_dev *pdev)
1964#ifdef CONFIG_PM 1964#ifdef CONFIG_PM
1965static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state) 1965static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state)
1966{ 1966{
1967 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1968 struct adm8211_priv *priv = dev->priv;
1969
1970 if (priv->mode != NL80211_IFTYPE_UNSPECIFIED) {
1971 ieee80211_stop_queues(dev);
1972 adm8211_stop(dev);
1973 }
1974
1975 pci_save_state(pdev); 1967 pci_save_state(pdev);
1976 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 1968 pci_set_power_state(pdev, pci_choose_state(pdev, state));
1977 return 0; 1969 return 0;
@@ -1979,17 +1971,8 @@ static int adm8211_suspend(struct pci_dev *pdev, pm_message_t state)
1979 1971
1980static int adm8211_resume(struct pci_dev *pdev) 1972static int adm8211_resume(struct pci_dev *pdev)
1981{ 1973{
1982 struct ieee80211_hw *dev = pci_get_drvdata(pdev);
1983 struct adm8211_priv *priv = dev->priv;
1984
1985 pci_set_power_state(pdev, PCI_D0); 1974 pci_set_power_state(pdev, PCI_D0);
1986 pci_restore_state(pdev); 1975 pci_restore_state(pdev);
1987
1988 if (priv->mode != NL80211_IFTYPE_UNSPECIFIED) {
1989 adm8211_start(dev);
1990 ieee80211_wake_queues(dev);
1991 }
1992
1993 return 0; 1976 return 0;
1994} 1977}
1995#endif /* CONFIG_PM */ 1978#endif /* CONFIG_PM */
diff --git a/drivers/net/wireless/arlan-main.c b/drivers/net/wireless/arlan-main.c
index d479f4735aaa..f96c634e2d35 100644
--- a/drivers/net/wireless/arlan-main.c
+++ b/drivers/net/wireless/arlan-main.c
@@ -1022,7 +1022,7 @@ static int arlan_mac_addr(struct net_device *dev, void *p)
1022 ARLAN_DEBUG_ENTRY("arlan_mac_addr"); 1022 ARLAN_DEBUG_ENTRY("arlan_mac_addr");
1023 return -EINVAL; 1023 return -EINVAL;
1024 1024
1025 if (!netif_running(dev)) 1025 if (netif_running(dev))
1026 return -EBUSY; 1026 return -EBUSY;
1027 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len); 1027 memcpy(dev->dev_addr, addr->sa_data, dev->addr_len);
1028 1028
diff --git a/drivers/net/wireless/ath/ar9170/ar9170.h b/drivers/net/wireless/ath/ar9170/ar9170.h
index bb97981fb248..e6c3ee3e0581 100644
--- a/drivers/net/wireless/ath/ar9170/ar9170.h
+++ b/drivers/net/wireless/ath/ar9170/ar9170.h
@@ -109,11 +109,52 @@ struct ar9170_rxstream_mpdu_merge {
109 bool has_plcp; 109 bool has_plcp;
110}; 110};
111 111
112#define AR9170_NUM_MAX_BA_RETRY 5
113#define AR9170_NUM_TID 16
114#define WME_BA_BMP_SIZE 64
115#define AR9170_NUM_MAX_AGG_LEN (2 * WME_BA_BMP_SIZE)
116
117#define WME_AC_BE 2
118#define WME_AC_BK 3
119#define WME_AC_VI 1
120#define WME_AC_VO 0
121
122#define TID_TO_WME_AC(_tid) \
123 ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
124 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
125 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
126 WME_AC_VO)
127
128#define BAW_WITHIN(_start, _bawsz, _seqno) \
129 ((((_seqno) - (_start)) & 0xfff) < (_bawsz))
130
131enum ar9170_tid_state {
132 AR9170_TID_STATE_INVALID,
133 AR9170_TID_STATE_SHUTDOWN,
134 AR9170_TID_STATE_PROGRESS,
135 AR9170_TID_STATE_COMPLETE,
136};
137
138struct ar9170_sta_tid {
139 struct list_head list;
140 struct sk_buff_head queue;
141 u8 addr[ETH_ALEN];
142 u16 ssn;
143 u16 tid;
144 enum ar9170_tid_state state;
145 bool active;
146 u8 retry;
147};
148
112#define AR9170_QUEUE_TIMEOUT 64 149#define AR9170_QUEUE_TIMEOUT 64
113#define AR9170_TX_TIMEOUT 8 150#define AR9170_TX_TIMEOUT 8
151#define AR9170_BA_TIMEOUT 4
114#define AR9170_JANITOR_DELAY 128 152#define AR9170_JANITOR_DELAY 128
115#define AR9170_TX_INVALID_RATE 0xffffffff 153#define AR9170_TX_INVALID_RATE 0xffffffff
116 154
155#define AR9170_NUM_TX_STATUS 128
156#define AR9170_NUM_TX_AGG_MAX 30
157
117struct ar9170 { 158struct ar9170 {
118 struct ieee80211_hw *hw; 159 struct ieee80211_hw *hw;
119 struct mutex mutex; 160 struct mutex mutex;
@@ -187,14 +228,25 @@ struct ar9170 {
187 struct sk_buff_head tx_pending[__AR9170_NUM_TXQ]; 228 struct sk_buff_head tx_pending[__AR9170_NUM_TXQ];
188 struct sk_buff_head tx_status[__AR9170_NUM_TXQ]; 229 struct sk_buff_head tx_status[__AR9170_NUM_TXQ];
189 struct delayed_work tx_janitor; 230 struct delayed_work tx_janitor;
231 /* tx ampdu */
232 struct sk_buff_head tx_status_ampdu;
233 spinlock_t tx_ampdu_list_lock;
234 struct list_head tx_ampdu_list;
235 unsigned int tx_ampdu_pending;
190 236
191 /* rxstream mpdu merge */ 237 /* rxstream mpdu merge */
192 struct ar9170_rxstream_mpdu_merge rx_mpdu; 238 struct ar9170_rxstream_mpdu_merge rx_mpdu;
193 struct sk_buff *rx_failover; 239 struct sk_buff *rx_failover;
194 int rx_failover_missing; 240 int rx_failover_missing;
241
242 /* (cached) HW A-MPDU settings */
243 u8 global_ampdu_density;
244 u8 global_ampdu_factor;
195}; 245};
196 246
197struct ar9170_sta_info { 247struct ar9170_sta_info {
248 struct ar9170_sta_tid agg[AR9170_NUM_TID];
249 unsigned int ampdu_max_len;
198}; 250};
199 251
200#define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0) 252#define AR9170_TX_FLAG_WAIT_FOR_ACK BIT(0)
diff --git a/drivers/net/wireless/ath/ar9170/main.c b/drivers/net/wireless/ath/ar9170/main.c
index 51753ed1b8ba..c7287a883a48 100644
--- a/drivers/net/wireless/ath/ar9170/main.c
+++ b/drivers/net/wireless/ath/ar9170/main.c
@@ -49,6 +49,10 @@ static int modparam_nohwcrypt;
49module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO); 49module_param_named(nohwcrypt, modparam_nohwcrypt, bool, S_IRUGO);
50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption."); 50MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption.");
51 51
52static int modparam_ht;
53module_param_named(ht, modparam_ht, bool, S_IRUGO);
54MODULE_PARM_DESC(ht, "enable MPDU aggregation.");
55
52#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \ 56#define RATE(_bitrate, _hw_rate, _txpidx, _flags) { \
53 .bitrate = (_bitrate), \ 57 .bitrate = (_bitrate), \
54 .flags = (_flags), \ 58 .flags = (_flags), \
@@ -148,12 +152,15 @@ static struct ieee80211_channel ar9170_5ghz_chantable[] = {
148 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \ 152 .cap = IEEE80211_HT_CAP_MAX_AMSDU | \
149 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \ 153 IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
150 IEEE80211_HT_CAP_SGI_40 | \ 154 IEEE80211_HT_CAP_SGI_40 | \
155 IEEE80211_HT_CAP_GRN_FLD | \
151 IEEE80211_HT_CAP_DSSSCCK40 | \ 156 IEEE80211_HT_CAP_DSSSCCK40 | \
152 IEEE80211_HT_CAP_SM_PS, \ 157 IEEE80211_HT_CAP_SM_PS, \
153 .ampdu_factor = 3, \ 158 .ampdu_factor = 3, \
154 .ampdu_density = 6, \ 159 .ampdu_density = 6, \
155 .mcs = { \ 160 .mcs = { \
156 .rx_mask = { 0xFF, 0xFF, 0, 0, 0, 0, 0, 0, 0, 0, }, \ 161 .rx_mask = { 0xff, 0xff, 0, 0, 0x1, 0, 0, 0, 0, 0, }, \
162 .rx_highest = cpu_to_le16(300), \
163 .tx_params = IEEE80211_HT_MCS_TX_DEFINED, \
157 }, \ 164 }, \
158} 165}
159 166
@@ -174,8 +181,31 @@ static struct ieee80211_supported_band ar9170_band_5GHz = {
174}; 181};
175 182
176static void ar9170_tx(struct ar9170 *ar); 183static void ar9170_tx(struct ar9170 *ar);
184static bool ar9170_tx_ampdu(struct ar9170 *ar);
177 185
178#ifdef AR9170_QUEUE_DEBUG 186static inline u16 ar9170_get_seq_h(struct ieee80211_hdr *hdr)
187{
188 return le16_to_cpu(hdr->seq_ctrl) >> 4;
189}
190
191static inline u16 ar9170_get_seq(struct sk_buff *skb)
192{
193 struct ar9170_tx_control *txc = (void *) skb->data;
194 return ar9170_get_seq_h((void *) txc->frame_data);
195}
196
197static inline u16 ar9170_get_tid(struct sk_buff *skb)
198{
199 struct ar9170_tx_control *txc = (void *) skb->data;
200 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
201
202 return (ieee80211_get_qos_ctl(hdr))[0] & IEEE80211_QOS_CTL_TID_MASK;
203}
204
205#define GET_NEXT_SEQ(seq) ((seq + 1) & 0x0fff)
206#define GET_NEXT_SEQ_FROM_SKB(skb) (GET_NEXT_SEQ(ar9170_get_seq(skb)))
207
208#if (defined AR9170_QUEUE_DEBUG) || (defined AR9170_TXAGG_DEBUG)
179static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb) 209static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
180{ 210{
181 struct ar9170_tx_control *txc = (void *) skb->data; 211 struct ar9170_tx_control *txc = (void *) skb->data;
@@ -183,10 +213,10 @@ static void ar9170_print_txheader(struct ar9170 *ar, struct sk_buff *skb)
183 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data; 213 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
184 struct ieee80211_hdr *hdr = (void *) txc->frame_data; 214 struct ieee80211_hdr *hdr = (void *) txc->frame_data;
185 215
186 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x " 216 printk(KERN_DEBUG "%s: => FRAME [skb:%p, q:%d, DA:[%pM] flags:%x s:%d "
187 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n", 217 "mac_ctrl:%04x, phy_ctrl:%08x, timeout:[%d ms]]\n",
188 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb), 218 wiphy_name(ar->hw->wiphy), skb, skb_get_queue_mapping(skb),
189 ieee80211_get_DA(hdr), arinfo->flags, 219 ieee80211_get_DA(hdr), arinfo->flags, ar9170_get_seq_h(hdr),
190 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control), 220 le16_to_cpu(txc->mac_control), le32_to_cpu(txc->phy_control),
191 jiffies_to_msecs(arinfo->timeout - jiffies)); 221 jiffies_to_msecs(arinfo->timeout - jiffies));
192} 222}
@@ -210,7 +240,9 @@ static void __ar9170_dump_txqueue(struct ar9170 *ar,
210 "mismatch %d != %d\n", skb_queue_len(queue), i); 240 "mismatch %d != %d\n", skb_queue_len(queue), i);
211 printk(KERN_DEBUG "---[ end ]---\n"); 241 printk(KERN_DEBUG "---[ end ]---\n");
212} 242}
243#endif /* AR9170_QUEUE_DEBUG || AR9170_TXAGG_DEBUG */
213 244
245#ifdef AR9170_QUEUE_DEBUG
214static void ar9170_dump_txqueue(struct ar9170 *ar, 246static void ar9170_dump_txqueue(struct ar9170 *ar,
215 struct sk_buff_head *queue) 247 struct sk_buff_head *queue)
216{ 248{
@@ -220,7 +252,9 @@ static void ar9170_dump_txqueue(struct ar9170 *ar,
220 __ar9170_dump_txqueue(ar, queue); 252 __ar9170_dump_txqueue(ar, queue);
221 spin_unlock_irqrestore(&queue->lock, flags); 253 spin_unlock_irqrestore(&queue->lock, flags);
222} 254}
255#endif /* AR9170_QUEUE_DEBUG */
223 256
257#ifdef AR9170_QUEUE_STOP_DEBUG
224static void __ar9170_dump_txstats(struct ar9170 *ar) 258static void __ar9170_dump_txstats(struct ar9170 *ar)
225{ 259{
226 int i; 260 int i;
@@ -229,20 +263,27 @@ static void __ar9170_dump_txstats(struct ar9170 *ar)
229 wiphy_name(ar->hw->wiphy)); 263 wiphy_name(ar->hw->wiphy));
230 264
231 for (i = 0; i < __AR9170_NUM_TXQ; i++) 265 for (i = 0; i < __AR9170_NUM_TXQ; i++)
232 printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d\n", 266 printk(KERN_DEBUG "%s: queue:%d limit:%d len:%d waitack:%d "
233 wiphy_name(ar->hw->wiphy), i, ar->tx_stats[i].limit, 267 " stopped:%d\n", wiphy_name(ar->hw->wiphy), i,
234 ar->tx_stats[i].len, skb_queue_len(&ar->tx_status[i])); 268 ar->tx_stats[i].limit, ar->tx_stats[i].len,
269 skb_queue_len(&ar->tx_status[i]),
270 ieee80211_queue_stopped(ar->hw, i));
235} 271}
272#endif /* AR9170_QUEUE_STOP_DEBUG */
236 273
237static void ar9170_dump_txstats(struct ar9170 *ar) 274#ifdef AR9170_TXAGG_DEBUG
275static void ar9170_dump_tx_status_ampdu(struct ar9170 *ar)
238{ 276{
239 unsigned long flags; 277 unsigned long flags;
240 278
241 spin_lock_irqsave(&ar->tx_stats_lock, flags); 279 spin_lock_irqsave(&ar->tx_status_ampdu.lock, flags);
242 __ar9170_dump_txstats(ar); 280 printk(KERN_DEBUG "%s: A-MPDU tx_status queue => \n",
243 spin_unlock_irqrestore(&ar->tx_stats_lock, flags); 281 wiphy_name(ar->hw->wiphy));
282 __ar9170_dump_txqueue(ar, &ar->tx_status_ampdu);
283 spin_unlock_irqrestore(&ar->tx_status_ampdu.lock, flags);
244} 284}
245#endif /* AR9170_QUEUE_DEBUG */ 285
286#endif /* AR9170_TXAGG_DEBUG */
246 287
247/* caller must guarantee exclusive access for _bin_ queue. */ 288/* caller must guarantee exclusive access for _bin_ queue. */
248static void ar9170_recycle_expired(struct ar9170 *ar, 289static void ar9170_recycle_expired(struct ar9170 *ar,
@@ -315,6 +356,70 @@ static void ar9170_tx_status(struct ar9170 *ar, struct sk_buff *skb,
315 ieee80211_tx_status_irqsafe(ar->hw, skb); 356 ieee80211_tx_status_irqsafe(ar->hw, skb);
316} 357}
317 358
359static void ar9170_tx_fake_ampdu_status(struct ar9170 *ar)
360{
361 struct sk_buff_head success;
362 struct sk_buff *skb;
363 unsigned int i;
364 unsigned long queue_bitmap = 0;
365
366 skb_queue_head_init(&success);
367
368 while (skb_queue_len(&ar->tx_status_ampdu) > AR9170_NUM_TX_STATUS)
369 __skb_queue_tail(&success, skb_dequeue(&ar->tx_status_ampdu));
370
371 ar9170_recycle_expired(ar, &ar->tx_status_ampdu, &success);
372
373#ifdef AR9170_TXAGG_DEBUG
374 printk(KERN_DEBUG "%s: collected %d A-MPDU frames.\n",
375 wiphy_name(ar->hw->wiphy), skb_queue_len(&success));
376 __ar9170_dump_txqueue(ar, &success);
377#endif /* AR9170_TXAGG_DEBUG */
378
379 while ((skb = __skb_dequeue(&success))) {
380 struct ieee80211_tx_info *txinfo;
381
382 queue_bitmap |= BIT(skb_get_queue_mapping(skb));
383
384 txinfo = IEEE80211_SKB_CB(skb);
385 ieee80211_tx_info_clear_status(txinfo);
386
387 txinfo->flags |= IEEE80211_TX_STAT_ACK;
388 txinfo->status.rates[0].count = 1;
389
390 skb_pull(skb, sizeof(struct ar9170_tx_control));
391 ieee80211_tx_status_irqsafe(ar->hw, skb);
392 }
393
394 for_each_bit(i, &queue_bitmap, BITS_PER_BYTE) {
395#ifdef AR9170_QUEUE_STOP_DEBUG
396 printk(KERN_DEBUG "%s: wake queue %d\n",
397 wiphy_name(ar->hw->wiphy), i);
398 __ar9170_dump_txstats(ar);
399#endif /* AR9170_QUEUE_STOP_DEBUG */
400 ieee80211_wake_queue(ar->hw, i);
401 }
402
403 if (queue_bitmap)
404 ar9170_tx(ar);
405}
406
407static void ar9170_tx_ampdu_callback(struct ar9170 *ar, struct sk_buff *skb)
408{
409 struct ieee80211_tx_info *txinfo = IEEE80211_SKB_CB(skb);
410 struct ar9170_tx_info *arinfo = (void *) txinfo->rate_driver_data;
411
412 arinfo->timeout = jiffies +
413 msecs_to_jiffies(AR9170_BA_TIMEOUT);
414
415 skb_queue_tail(&ar->tx_status_ampdu, skb);
416 ar9170_tx_fake_ampdu_status(ar);
417 ar->tx_ampdu_pending--;
418
419 if (!list_empty(&ar->tx_ampdu_list) && !ar->tx_ampdu_pending)
420 ar9170_tx_ampdu(ar);
421}
422
318void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb) 423void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
319{ 424{
320 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 425 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -336,7 +441,7 @@ void ar9170_tx_callback(struct ar9170 *ar, struct sk_buff *skb)
336 spin_unlock_irqrestore(&ar->tx_stats_lock, flags); 441 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
337 442
338 if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) { 443 if (arinfo->flags & AR9170_TX_FLAG_BLOCK_ACK) {
339 dev_kfree_skb_any(skb); 444 ar9170_tx_ampdu_callback(ar, skb);
340 } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) { 445 } else if (arinfo->flags & AR9170_TX_FLAG_WAIT_FOR_ACK) {
341 arinfo->timeout = jiffies + 446 arinfo->timeout = jiffies +
342 msecs_to_jiffies(AR9170_TX_TIMEOUT); 447 msecs_to_jiffies(AR9170_TX_TIMEOUT);
@@ -420,6 +525,38 @@ static struct sk_buff *ar9170_get_queued_skb(struct ar9170 *ar,
420 return NULL; 525 return NULL;
421} 526}
422 527
528static void ar9170_handle_block_ack(struct ar9170 *ar, u16 count, u16 r)
529{
530 struct sk_buff *skb;
531 struct ieee80211_tx_info *txinfo;
532
533 while (count) {
534 skb = ar9170_get_queued_skb(ar, NULL, &ar->tx_status_ampdu, r);
535 if (!skb)
536 break;
537
538 txinfo = IEEE80211_SKB_CB(skb);
539 ieee80211_tx_info_clear_status(txinfo);
540
541 /* FIXME: maybe more ? */
542 txinfo->status.rates[0].count = 1;
543
544 skb_pull(skb, sizeof(struct ar9170_tx_control));
545 ieee80211_tx_status_irqsafe(ar->hw, skb);
546 count--;
547 }
548
549#ifdef AR9170_TXAGG_DEBUG
550 if (count) {
551 printk(KERN_DEBUG "%s: got %d more failed mpdus, but no more "
552 "suitable frames left in tx_status queue.\n",
553 wiphy_name(ar->hw->wiphy), count);
554
555 ar9170_dump_tx_status_ampdu(ar);
556 }
557#endif /* AR9170_TXAGG_DEBUG */
558}
559
423/* 560/*
424 * This worker tries to keeps an maintain tx_status queues. 561 * This worker tries to keeps an maintain tx_status queues.
425 * So we can guarantee that incoming tx_status reports are 562 * So we can guarantee that incoming tx_status reports are
@@ -456,6 +593,8 @@ static void ar9170_tx_janitor(struct work_struct *work)
456 resched = true; 593 resched = true;
457 } 594 }
458 595
596 ar9170_tx_fake_ampdu_status(ar);
597
459 if (resched) 598 if (resched)
460 queue_delayed_work(ar->hw->workqueue, 599 queue_delayed_work(ar->hw->workqueue,
461 &ar->tx_janitor, 600 &ar->tx_janitor,
@@ -528,8 +667,15 @@ void ar9170_handle_command_response(struct ar9170 *ar, void *buf, u32 len)
528 break; 667 break;
529 668
530 case 0xc4: 669 case 0xc4:
670 /* BlockACK bitmap */
671 break;
672
531 case 0xc5: 673 case 0xc5:
532 /* BlockACK events */ 674 /* BlockACK events */
675 ar9170_handle_block_ack(ar,
676 le16_to_cpu(cmd->ba_fail_cnt.failed),
677 le16_to_cpu(cmd->ba_fail_cnt.rate));
678 ar9170_tx_fake_ampdu_status(ar);
533 break; 679 break;
534 680
535 case 0xc6: 681 case 0xc6:
@@ -1098,6 +1244,10 @@ static int ar9170_op_start(struct ieee80211_hw *hw)
1098 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */ 1244 AR9170_FILL_QUEUE(ar->edcf[3], 2, 3, 7, 47); /* VOICE */
1099 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */ 1245 AR9170_FILL_QUEUE(ar->edcf[4], 2, 3, 7, 0); /* SPECIAL */
1100 1246
1247 /* set sane AMPDU defaults */
1248 ar->global_ampdu_density = 6;
1249 ar->global_ampdu_factor = 3;
1250
1101 ar->bad_hw_nagger = jiffies; 1251 ar->bad_hw_nagger = jiffies;
1102 1252
1103 err = ar->open(ar); 1253 err = ar->open(ar);
@@ -1143,6 +1293,7 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
1143 flush_workqueue(ar->hw->workqueue); 1293 flush_workqueue(ar->hw->workqueue);
1144 1294
1145 cancel_delayed_work_sync(&ar->tx_janitor); 1295 cancel_delayed_work_sync(&ar->tx_janitor);
1296 cancel_delayed_work_sync(&ar->led_work);
1146 cancel_work_sync(&ar->filter_config_work); 1297 cancel_work_sync(&ar->filter_config_work);
1147 cancel_work_sync(&ar->beacon_work); 1298 cancel_work_sync(&ar->beacon_work);
1148 mutex_lock(&ar->mutex); 1299 mutex_lock(&ar->mutex);
@@ -1159,9 +1310,40 @@ static void ar9170_op_stop(struct ieee80211_hw *hw)
1159 skb_queue_purge(&ar->tx_pending[i]); 1310 skb_queue_purge(&ar->tx_pending[i]);
1160 skb_queue_purge(&ar->tx_status[i]); 1311 skb_queue_purge(&ar->tx_status[i]);
1161 } 1312 }
1313 skb_queue_purge(&ar->tx_status_ampdu);
1314
1162 mutex_unlock(&ar->mutex); 1315 mutex_unlock(&ar->mutex);
1163} 1316}
1164 1317
1318static void ar9170_tx_indicate_immba(struct ar9170 *ar, struct sk_buff *skb)
1319{
1320 struct ar9170_tx_control *txc = (void *) skb->data;
1321
1322 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_IMM_AMPDU);
1323}
1324
1325static void ar9170_tx_copy_phy(struct ar9170 *ar, struct sk_buff *dst,
1326 struct sk_buff *src)
1327{
1328 struct ar9170_tx_control *dst_txc, *src_txc;
1329 struct ieee80211_tx_info *dst_info, *src_info;
1330 struct ar9170_tx_info *dst_arinfo, *src_arinfo;
1331
1332 src_txc = (void *) src->data;
1333 src_info = IEEE80211_SKB_CB(src);
1334 src_arinfo = (void *) src_info->rate_driver_data;
1335
1336 dst_txc = (void *) dst->data;
1337 dst_info = IEEE80211_SKB_CB(dst);
1338 dst_arinfo = (void *) dst_info->rate_driver_data;
1339
1340 dst_txc->phy_control = src_txc->phy_control;
1341
1342 /* same MCS for the whole aggregate */
1343 memcpy(dst_info->driver_rates, src_info->driver_rates,
1344 sizeof(dst_info->driver_rates));
1345}
1346
1165static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb) 1347static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
1166{ 1348{
1167 struct ieee80211_hdr *hdr; 1349 struct ieee80211_hdr *hdr;
@@ -1230,6 +1412,7 @@ static int ar9170_tx_prepare(struct ar9170 *ar, struct sk_buff *skb)
1230 1412
1231 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR); 1413 txc->mac_control |= cpu_to_le16(AR9170_TX_MAC_AGGR);
1232 arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK; 1414 arinfo->flags = AR9170_TX_FLAG_BLOCK_ACK;
1415
1233 goto out; 1416 goto out;
1234 } 1417 }
1235 1418
@@ -1360,6 +1543,159 @@ static void ar9170_tx_prepare_phy(struct ar9170 *ar, struct sk_buff *skb)
1360 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT); 1543 txc->phy_control |= cpu_to_le32(chains << AR9170_TX_PHY_TXCHAIN_SHIFT);
1361} 1544}
1362 1545
1546static bool ar9170_tx_ampdu(struct ar9170 *ar)
1547{
1548 struct sk_buff_head agg;
1549 struct ar9170_sta_tid *tid_info = NULL, *tmp;
1550 struct sk_buff *skb, *first = NULL;
1551 unsigned long flags, f2;
1552 unsigned int i = 0;
1553 u16 seq, queue, tmpssn;
1554 bool run = false;
1555
1556 skb_queue_head_init(&agg);
1557
1558 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1559 if (list_empty(&ar->tx_ampdu_list)) {
1560#ifdef AR9170_TXAGG_DEBUG
1561 printk(KERN_DEBUG "%s: aggregation list is empty.\n",
1562 wiphy_name(ar->hw->wiphy));
1563#endif /* AR9170_TXAGG_DEBUG */
1564 goto out_unlock;
1565 }
1566
1567 list_for_each_entry_safe(tid_info, tmp, &ar->tx_ampdu_list, list) {
1568 if (tid_info->state != AR9170_TID_STATE_COMPLETE) {
1569#ifdef AR9170_TXAGG_DEBUG
1570 printk(KERN_DEBUG "%s: dangling aggregation entry!\n",
1571 wiphy_name(ar->hw->wiphy));
1572#endif /* AR9170_TXAGG_DEBUG */
1573 continue;
1574 }
1575
1576 if (++i > 64) {
1577#ifdef AR9170_TXAGG_DEBUG
1578 printk(KERN_DEBUG "%s: enough frames aggregated.\n",
1579 wiphy_name(ar->hw->wiphy));
1580#endif /* AR9170_TXAGG_DEBUG */
1581 break;
1582 }
1583
1584 queue = TID_TO_WME_AC(tid_info->tid);
1585
1586 if (skb_queue_len(&ar->tx_pending[queue]) >=
1587 AR9170_NUM_TX_AGG_MAX) {
1588#ifdef AR9170_TXAGG_DEBUG
1589 printk(KERN_DEBUG "%s: queue %d full.\n",
1590 wiphy_name(ar->hw->wiphy), queue);
1591#endif /* AR9170_TXAGG_DEBUG */
1592 continue;
1593 }
1594
1595 list_del_init(&tid_info->list);
1596
1597 spin_lock_irqsave(&tid_info->queue.lock, f2);
1598 tmpssn = seq = tid_info->ssn;
1599 first = skb_peek(&tid_info->queue);
1600
1601 if (likely(first))
1602 tmpssn = ar9170_get_seq(first);
1603
1604 if (unlikely(tmpssn != seq)) {
1605#ifdef AR9170_TXAGG_DEBUG
1606 printk(KERN_DEBUG "%s: ssn mismatch [%d != %d]\n.",
1607 wiphy_name(ar->hw->wiphy), seq, tmpssn);
1608#endif /* AR9170_TXAGG_DEBUG */
1609 tid_info->ssn = tmpssn;
1610 }
1611
1612#ifdef AR9170_TXAGG_DEBUG
1613 printk(KERN_DEBUG "%s: generate A-MPDU for tid:%d ssn:%d with "
1614 "%d queued frames.\n", wiphy_name(ar->hw->wiphy),
1615 tid_info->tid, tid_info->ssn,
1616 skb_queue_len(&tid_info->queue));
1617 __ar9170_dump_txqueue(ar, &tid_info->queue);
1618#endif /* AR9170_TXAGG_DEBUG */
1619
1620 while ((skb = skb_peek(&tid_info->queue))) {
1621 if (unlikely(ar9170_get_seq(skb) != seq))
1622 break;
1623
1624 __skb_unlink(skb, &tid_info->queue);
1625 tid_info->ssn = seq = GET_NEXT_SEQ(seq);
1626
1627 if (unlikely(skb_get_queue_mapping(skb) != queue)) {
1628#ifdef AR9170_TXAGG_DEBUG
1629 printk(KERN_DEBUG "%s: tid:%d(q:%d) queue:%d "
1630 "!match.\n", wiphy_name(ar->hw->wiphy),
1631 tid_info->tid,
1632 TID_TO_WME_AC(tid_info->tid),
1633 skb_get_queue_mapping(skb));
1634#endif /* AR9170_TXAGG_DEBUG */
1635 dev_kfree_skb_any(skb);
1636 continue;
1637 }
1638
1639 if (unlikely(first == skb)) {
1640 ar9170_tx_prepare_phy(ar, skb);
1641 __skb_queue_tail(&agg, skb);
1642 first = skb;
1643 } else {
1644 ar9170_tx_copy_phy(ar, skb, first);
1645 __skb_queue_tail(&agg, skb);
1646 }
1647
1648 if (unlikely(skb_queue_len(&agg) ==
1649 AR9170_NUM_TX_AGG_MAX))
1650 break;
1651 }
1652
1653 if (skb_queue_empty(&tid_info->queue))
1654 tid_info->active = false;
1655 else
1656 list_add_tail(&tid_info->list,
1657 &ar->tx_ampdu_list);
1658
1659 spin_unlock_irqrestore(&tid_info->queue.lock, f2);
1660
1661 if (unlikely(skb_queue_empty(&agg))) {
1662#ifdef AR9170_TXAGG_DEBUG
1663 printk(KERN_DEBUG "%s: queued empty list!\n",
1664 wiphy_name(ar->hw->wiphy));
1665#endif /* AR9170_TXAGG_DEBUG */
1666 continue;
1667 }
1668
1669 /*
1670 * tell the FW/HW that this is the last frame,
1671 * that way it will wait for the immediate block ack.
1672 */
1673 if (likely(skb_peek_tail(&agg)))
1674 ar9170_tx_indicate_immba(ar, skb_peek_tail(&agg));
1675
1676#ifdef AR9170_TXAGG_DEBUG
1677 printk(KERN_DEBUG "%s: generated A-MPDU looks like this:\n",
1678 wiphy_name(ar->hw->wiphy));
1679 __ar9170_dump_txqueue(ar, &agg);
1680#endif /* AR9170_TXAGG_DEBUG */
1681
1682 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1683
1684 spin_lock_irqsave(&ar->tx_pending[queue].lock, flags);
1685 skb_queue_splice_tail_init(&agg, &ar->tx_pending[queue]);
1686 spin_unlock_irqrestore(&ar->tx_pending[queue].lock, flags);
1687 run = true;
1688
1689 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1690 }
1691
1692out_unlock:
1693 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1694 __skb_queue_purge(&agg);
1695
1696 return run;
1697}
1698
1363static void ar9170_tx(struct ar9170 *ar) 1699static void ar9170_tx(struct ar9170 *ar)
1364{ 1700{
1365 struct sk_buff *skb; 1701 struct sk_buff *skb;
@@ -1384,11 +1720,17 @@ static void ar9170_tx(struct ar9170 *ar)
1384 printk(KERN_DEBUG "%s: queue %d full\n", 1720 printk(KERN_DEBUG "%s: queue %d full\n",
1385 wiphy_name(ar->hw->wiphy), i); 1721 wiphy_name(ar->hw->wiphy), i);
1386 1722
1387 __ar9170_dump_txstats(ar); 1723 printk(KERN_DEBUG "%s: stuck frames: ===> \n",
1388 printk(KERN_DEBUG "stuck frames: ===> \n"); 1724 wiphy_name(ar->hw->wiphy));
1389 ar9170_dump_txqueue(ar, &ar->tx_pending[i]); 1725 ar9170_dump_txqueue(ar, &ar->tx_pending[i]);
1390 ar9170_dump_txqueue(ar, &ar->tx_status[i]); 1726 ar9170_dump_txqueue(ar, &ar->tx_status[i]);
1391#endif /* AR9170_QUEUE_DEBUG */ 1727#endif /* AR9170_QUEUE_DEBUG */
1728
1729#ifdef AR9170_QUEUE_STOP_DEBUG
1730 printk(KERN_DEBUG "%s: stop queue %d\n",
1731 wiphy_name(ar->hw->wiphy), i);
1732 __ar9170_dump_txstats(ar);
1733#endif /* AR9170_QUEUE_STOP_DEBUG */
1392 ieee80211_stop_queue(ar->hw, i); 1734 ieee80211_stop_queue(ar->hw, i);
1393 spin_unlock_irqrestore(&ar->tx_stats_lock, flags); 1735 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1394 continue; 1736 continue;
@@ -1403,8 +1745,6 @@ static void ar9170_tx(struct ar9170 *ar)
1403 "remaining slots:%d, needed:%d\n", 1745 "remaining slots:%d, needed:%d\n",
1404 wiphy_name(ar->hw->wiphy), i, remaining_space, 1746 wiphy_name(ar->hw->wiphy), i, remaining_space,
1405 frames); 1747 frames);
1406
1407 ar9170_dump_txstats(ar);
1408#endif /* AR9170_QUEUE_DEBUG */ 1748#endif /* AR9170_QUEUE_DEBUG */
1409 frames = remaining_space; 1749 frames = remaining_space;
1410 } 1750 }
@@ -1432,6 +1772,9 @@ static void ar9170_tx(struct ar9170 *ar)
1432 arinfo->timeout = jiffies + 1772 arinfo->timeout = jiffies +
1433 msecs_to_jiffies(AR9170_TX_TIMEOUT); 1773 msecs_to_jiffies(AR9170_TX_TIMEOUT);
1434 1774
1775 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
1776 ar->tx_ampdu_pending++;
1777
1435#ifdef AR9170_QUEUE_DEBUG 1778#ifdef AR9170_QUEUE_DEBUG
1436 printk(KERN_DEBUG "%s: send frame q:%d =>\n", 1779 printk(KERN_DEBUG "%s: send frame q:%d =>\n",
1437 wiphy_name(ar->hw->wiphy), i); 1780 wiphy_name(ar->hw->wiphy), i);
@@ -1440,6 +1783,9 @@ static void ar9170_tx(struct ar9170 *ar)
1440 1783
1441 err = ar->tx(ar, skb); 1784 err = ar->tx(ar, skb);
1442 if (unlikely(err)) { 1785 if (unlikely(err)) {
1786 if (arinfo->flags == AR9170_TX_FLAG_BLOCK_ACK)
1787 ar->tx_ampdu_pending--;
1788
1443 frames_failed++; 1789 frames_failed++;
1444 dev_kfree_skb_any(skb); 1790 dev_kfree_skb_any(skb);
1445 } else { 1791 } else {
@@ -1461,13 +1807,18 @@ static void ar9170_tx(struct ar9170 *ar)
1461 1807
1462 if (unlikely(frames_failed)) { 1808 if (unlikely(frames_failed)) {
1463#ifdef AR9170_QUEUE_DEBUG 1809#ifdef AR9170_QUEUE_DEBUG
1464 printk(KERN_DEBUG "%s: frames failed =>\n", 1810 printk(KERN_DEBUG "%s: frames failed %d =>\n",
1465 wiphy_name(ar->hw->wiphy), frames_failed); 1811 wiphy_name(ar->hw->wiphy), frames_failed);
1466#endif /* AR9170_QUEUE_DEBUG */ 1812#endif /* AR9170_QUEUE_DEBUG */
1467 1813
1468 spin_lock_irqsave(&ar->tx_stats_lock, flags); 1814 spin_lock_irqsave(&ar->tx_stats_lock, flags);
1469 ar->tx_stats[i].len -= frames_failed; 1815 ar->tx_stats[i].len -= frames_failed;
1470 ar->tx_stats[i].count -= frames_failed; 1816 ar->tx_stats[i].count -= frames_failed;
1817#ifdef AR9170_QUEUE_STOP_DEBUG
1818 printk(KERN_DEBUG "%s: wake queue %d\n",
1819 wiphy_name(ar->hw->wiphy), i);
1820 __ar9170_dump_txstats(ar);
1821#endif /* AR9170_QUEUE_STOP_DEBUG */
1471 ieee80211_wake_queue(ar->hw, i); 1822 ieee80211_wake_queue(ar->hw, i);
1472 spin_unlock_irqrestore(&ar->tx_stats_lock, flags); 1823 spin_unlock_irqrestore(&ar->tx_stats_lock, flags);
1473 } 1824 }
@@ -1479,6 +1830,90 @@ static void ar9170_tx(struct ar9170 *ar)
1479 msecs_to_jiffies(AR9170_JANITOR_DELAY)); 1830 msecs_to_jiffies(AR9170_JANITOR_DELAY));
1480} 1831}
1481 1832
1833static bool ar9170_tx_ampdu_queue(struct ar9170 *ar, struct sk_buff *skb)
1834{
1835 struct ieee80211_tx_info *txinfo;
1836 struct ar9170_sta_info *sta_info;
1837 struct ar9170_sta_tid *agg;
1838 struct sk_buff *iter;
1839 unsigned long flags, f2;
1840 unsigned int max;
1841 u16 tid, seq, qseq;
1842 bool run = false, queue = false;
1843
1844 tid = ar9170_get_tid(skb);
1845 seq = ar9170_get_seq(skb);
1846 txinfo = IEEE80211_SKB_CB(skb);
1847 sta_info = (void *) txinfo->control.sta->drv_priv;
1848 agg = &sta_info->agg[tid];
1849 max = sta_info->ampdu_max_len;
1850
1851 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
1852
1853 if (unlikely(agg->state != AR9170_TID_STATE_COMPLETE)) {
1854#ifdef AR9170_TXAGG_DEBUG
1855 printk(KERN_DEBUG "%s: BlockACK session not fully initialized "
1856 "for ESS:%pM tid:%d state:%d.\n",
1857 wiphy_name(ar->hw->wiphy), agg->addr, agg->tid,
1858 agg->state);
1859#endif /* AR9170_TXAGG_DEBUG */
1860 goto err_unlock;
1861 }
1862
1863 if (!agg->active) {
1864 agg->active = true;
1865 agg->ssn = seq;
1866 queue = true;
1867 }
1868
1869 /* check if seq is within the BA window */
1870 if (unlikely(!BAW_WITHIN(agg->ssn, max, seq))) {
1871#ifdef AR9170_TXAGG_DEBUG
1872 printk(KERN_DEBUG "%s: frame with tid:%d seq:%d does not "
1873 "fit into BA window (%d - %d)\n",
1874 wiphy_name(ar->hw->wiphy), tid, seq, agg->ssn,
1875 (agg->ssn + max) & 0xfff);
1876#endif /* AR9170_TXAGG_DEBUG */
1877 goto err_unlock;
1878 }
1879
1880 spin_lock_irqsave(&agg->queue.lock, f2);
1881
1882 skb_queue_reverse_walk(&agg->queue, iter) {
1883 qseq = ar9170_get_seq(iter);
1884
1885 if (GET_NEXT_SEQ(qseq) == seq) {
1886 __skb_queue_after(&agg->queue, iter, skb);
1887 goto queued;
1888 }
1889 }
1890
1891 __skb_queue_head(&agg->queue, skb);
1892
1893queued:
1894 spin_unlock_irqrestore(&agg->queue.lock, f2);
1895
1896#ifdef AR9170_TXAGG_DEBUG
1897 printk(KERN_DEBUG "%s: new aggregate %p queued.\n",
1898 wiphy_name(ar->hw->wiphy), skb);
1899 __ar9170_dump_txqueue(ar, &agg->queue);
1900#endif /* AR9170_TXAGG_DEBUG */
1901
1902 if (skb_queue_len(&agg->queue) >= AR9170_NUM_TX_AGG_MAX)
1903 run = true;
1904
1905 if (queue)
1906 list_add_tail(&agg->list, &ar->tx_ampdu_list);
1907
1908 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1909 return run;
1910
1911err_unlock:
1912 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
1913 dev_kfree_skb_irq(skb);
1914 return false;
1915}
1916
1482int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 1917int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1483{ 1918{
1484 struct ar9170 *ar = hw->priv; 1919 struct ar9170 *ar = hw->priv;
@@ -1492,8 +1927,10 @@ int ar9170_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
1492 1927
1493 info = IEEE80211_SKB_CB(skb); 1928 info = IEEE80211_SKB_CB(skb);
1494 if (info->flags & IEEE80211_TX_CTL_AMPDU) { 1929 if (info->flags & IEEE80211_TX_CTL_AMPDU) {
1495 /* drop frame, we do not allow TX A-MPDU aggregation yet. */ 1930 bool run = ar9170_tx_ampdu_queue(ar, skb);
1496 goto err_free; 1931
1932 if (run || !ar->tx_ampdu_pending)
1933 ar9170_tx_ampdu(ar);
1497 } else { 1934 } else {
1498 unsigned int queue = skb_get_queue_mapping(skb); 1935 unsigned int queue = skb_get_queue_mapping(skb);
1499 1936
@@ -1931,6 +2368,53 @@ static void ar9170_sta_notify(struct ieee80211_hw *hw,
1931 enum sta_notify_cmd cmd, 2368 enum sta_notify_cmd cmd,
1932 struct ieee80211_sta *sta) 2369 struct ieee80211_sta *sta)
1933{ 2370{
2371 struct ar9170 *ar = hw->priv;
2372 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2373 unsigned int i;
2374
2375 switch (cmd) {
2376 case STA_NOTIFY_ADD:
2377 memset(sta_info, 0, sizeof(*sta_info));
2378
2379 if (!sta->ht_cap.ht_supported)
2380 break;
2381
2382 if (sta->ht_cap.ampdu_density > ar->global_ampdu_density)
2383 ar->global_ampdu_density = sta->ht_cap.ampdu_density;
2384
2385 if (sta->ht_cap.ampdu_factor < ar->global_ampdu_factor)
2386 ar->global_ampdu_factor = sta->ht_cap.ampdu_factor;
2387
2388 for (i = 0; i < AR9170_NUM_TID; i++) {
2389 sta_info->agg[i].state = AR9170_TID_STATE_SHUTDOWN;
2390 sta_info->agg[i].active = false;
2391 sta_info->agg[i].ssn = 0;
2392 sta_info->agg[i].retry = 0;
2393 sta_info->agg[i].tid = i;
2394 INIT_LIST_HEAD(&sta_info->agg[i].list);
2395 skb_queue_head_init(&sta_info->agg[i].queue);
2396 }
2397
2398 sta_info->ampdu_max_len = 1 << (3 + sta->ht_cap.ampdu_factor);
2399 break;
2400
2401 case STA_NOTIFY_REMOVE:
2402 if (!sta->ht_cap.ht_supported)
2403 break;
2404
2405 for (i = 0; i < AR9170_NUM_TID; i++) {
2406 sta_info->agg[i].state = AR9170_TID_STATE_INVALID;
2407 skb_queue_purge(&sta_info->agg[i].queue);
2408 }
2409
2410 break;
2411
2412 default:
2413 break;
2414 }
2415
2416 if (IS_STARTED(ar) && ar->filter_changed)
2417 queue_work(ar->hw->workqueue, &ar->filter_config_work);
1934} 2418}
1935 2419
1936static int ar9170_get_stats(struct ieee80211_hw *hw, 2420static int ar9170_get_stats(struct ieee80211_hw *hw,
@@ -1985,18 +2469,65 @@ static int ar9170_ampdu_action(struct ieee80211_hw *hw,
1985 enum ieee80211_ampdu_mlme_action action, 2469 enum ieee80211_ampdu_mlme_action action,
1986 struct ieee80211_sta *sta, u16 tid, u16 *ssn) 2470 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
1987{ 2471{
2472 struct ar9170 *ar = hw->priv;
2473 struct ar9170_sta_info *sta_info = (void *) sta->drv_priv;
2474 struct ar9170_sta_tid *tid_info = &sta_info->agg[tid];
2475 unsigned long flags;
2476
2477 if (!modparam_ht)
2478 return -EOPNOTSUPP;
2479
1988 switch (action) { 2480 switch (action) {
2481 case IEEE80211_AMPDU_TX_START:
2482 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2483 if (tid_info->state != AR9170_TID_STATE_SHUTDOWN ||
2484 !list_empty(&tid_info->list)) {
2485 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2486#ifdef AR9170_TXAGG_DEBUG
2487 printk(KERN_INFO "%s: A-MPDU [ESS:[%pM] tid:[%d]] "
2488 "is in a very bad state!\n",
2489 wiphy_name(hw->wiphy), sta->addr, tid);
2490#endif /* AR9170_TXAGG_DEBUG */
2491 return -EBUSY;
2492 }
2493
2494 *ssn = tid_info->ssn;
2495 tid_info->state = AR9170_TID_STATE_PROGRESS;
2496 tid_info->active = false;
2497 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2498 ieee80211_start_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2499 break;
2500
2501 case IEEE80211_AMPDU_TX_STOP:
2502 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2503 tid_info->state = AR9170_TID_STATE_SHUTDOWN;
2504 list_del_init(&tid_info->list);
2505 tid_info->active = false;
2506 skb_queue_purge(&tid_info->queue);
2507 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2508 ieee80211_stop_tx_ba_cb_irqsafe(hw, sta->addr, tid);
2509 break;
2510
2511 case IEEE80211_AMPDU_TX_OPERATIONAL:
2512#ifdef AR9170_TXAGG_DEBUG
2513 printk(KERN_INFO "%s: A-MPDU for %pM [tid:%d] Operational.\n",
2514 wiphy_name(hw->wiphy), sta->addr, tid);
2515#endif /* AR9170_TXAGG_DEBUG */
2516 spin_lock_irqsave(&ar->tx_ampdu_list_lock, flags);
2517 sta_info->agg[tid].state = AR9170_TID_STATE_COMPLETE;
2518 spin_unlock_irqrestore(&ar->tx_ampdu_list_lock, flags);
2519 break;
2520
1989 case IEEE80211_AMPDU_RX_START: 2521 case IEEE80211_AMPDU_RX_START:
1990 case IEEE80211_AMPDU_RX_STOP: 2522 case IEEE80211_AMPDU_RX_STOP:
1991 /* 2523 /* Handled by firmware */
1992 * Something goes wrong -- RX locks up 2524 break;
1993 * after a while of receiving aggregated 2525
1994 * frames -- not enabling for now.
1995 */
1996 return -EOPNOTSUPP;
1997 default: 2526 default:
1998 return -EOPNOTSUPP; 2527 return -EOPNOTSUPP;
1999 } 2528 }
2529
2530 return 0;
2000} 2531}
2001 2532
2002static const struct ieee80211_ops ar9170_ops = { 2533static const struct ieee80211_ops ar9170_ops = {
@@ -2045,6 +2576,8 @@ void *ar9170_alloc(size_t priv_size)
2045 mutex_init(&ar->mutex); 2576 mutex_init(&ar->mutex);
2046 spin_lock_init(&ar->cmdlock); 2577 spin_lock_init(&ar->cmdlock);
2047 spin_lock_init(&ar->tx_stats_lock); 2578 spin_lock_init(&ar->tx_stats_lock);
2579 spin_lock_init(&ar->tx_ampdu_list_lock);
2580 skb_queue_head_init(&ar->tx_status_ampdu);
2048 for (i = 0; i < __AR9170_NUM_TXQ; i++) { 2581 for (i = 0; i < __AR9170_NUM_TXQ; i++) {
2049 skb_queue_head_init(&ar->tx_status[i]); 2582 skb_queue_head_init(&ar->tx_status[i]);
2050 skb_queue_head_init(&ar->tx_pending[i]); 2583 skb_queue_head_init(&ar->tx_pending[i]);
@@ -2053,6 +2586,7 @@ void *ar9170_alloc(size_t priv_size)
2053 INIT_WORK(&ar->filter_config_work, ar9170_set_filters); 2586 INIT_WORK(&ar->filter_config_work, ar9170_set_filters);
2054 INIT_WORK(&ar->beacon_work, ar9170_new_beacon); 2587 INIT_WORK(&ar->beacon_work, ar9170_new_beacon);
2055 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor); 2588 INIT_DELAYED_WORK(&ar->tx_janitor, ar9170_tx_janitor);
2589 INIT_LIST_HEAD(&ar->tx_ampdu_list);
2056 2590
2057 /* all hw supports 2.4 GHz, so set channel to 1 by default */ 2591 /* all hw supports 2.4 GHz, so set channel to 1 by default */
2058 ar->channel = &ar9170_2ghz_chantable[0]; 2592 ar->channel = &ar9170_2ghz_chantable[0];
@@ -2066,6 +2600,13 @@ void *ar9170_alloc(size_t priv_size)
2066 IEEE80211_HW_SIGNAL_DBM | 2600 IEEE80211_HW_SIGNAL_DBM |
2067 IEEE80211_HW_NOISE_DBM; 2601 IEEE80211_HW_NOISE_DBM;
2068 2602
2603 if (modparam_ht) {
2604 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
2605 } else {
2606 ar9170_band_2GHz.ht_cap.ht_supported = false;
2607 ar9170_band_5GHz.ht_cap.ht_supported = false;
2608 }
2609
2069 ar->hw->queues = __AR9170_NUM_TXQ; 2610 ar->hw->queues = __AR9170_NUM_TXQ;
2070 ar->hw->extra_tx_headroom = 8; 2611 ar->hw->extra_tx_headroom = 8;
2071 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info); 2612 ar->hw->sta_data_size = sizeof(struct ar9170_sta_info);
@@ -2087,10 +2628,10 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
2087{ 2628{
2088#define RW 8 /* number of words to read at once */ 2629#define RW 8 /* number of words to read at once */
2089#define RB (sizeof(u32) * RW) 2630#define RB (sizeof(u32) * RW)
2090 DECLARE_MAC_BUF(mbuf);
2091 u8 *eeprom = (void *)&ar->eeprom; 2631 u8 *eeprom = (void *)&ar->eeprom;
2092 u8 *addr = ar->eeprom.mac_address; 2632 u8 *addr = ar->eeprom.mac_address;
2093 __le32 offsets[RW]; 2633 __le32 offsets[RW];
2634 unsigned int rx_streams, tx_streams, tx_params = 0;
2094 int i, j, err, bands = 0; 2635 int i, j, err, bands = 0;
2095 2636
2096 BUILD_BUG_ON(sizeof(ar->eeprom) & 3); 2637 BUILD_BUG_ON(sizeof(ar->eeprom) & 3);
@@ -2127,6 +2668,20 @@ static int ar9170_read_eeprom(struct ar9170 *ar)
2127 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz; 2668 ar->hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar9170_band_5GHz;
2128 bands++; 2669 bands++;
2129 } 2670 }
2671
2672 rx_streams = hweight8(ar->eeprom.rx_mask);
2673 tx_streams = hweight8(ar->eeprom.tx_mask);
2674
2675 if (rx_streams != tx_streams)
2676 tx_params = IEEE80211_HT_MCS_TX_RX_DIFF;
2677
2678 if (tx_streams >= 1 && tx_streams <= IEEE80211_HT_MCS_TX_MAX_STREAMS)
2679 tx_params = (tx_streams - 1) <<
2680 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
2681
2682 ar9170_band_2GHz.ht_cap.mcs.tx_params |= tx_params;
2683 ar9170_band_5GHz.ht_cap.mcs.tx_params |= tx_params;
2684
2130 /* 2685 /*
2131 * I measured this, a bandswitch takes roughly 2686 * I measured this, a bandswitch takes roughly
2132 * 135 ms and a frequency switch about 80. 2687 * 135 ms and a frequency switch about 80.
diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h
index 6809b54a2ad7..debad07d9900 100644
--- a/drivers/net/wireless/ath/ath5k/reg.h
+++ b/drivers/net/wireless/ath/ath5k/reg.h
@@ -339,9 +339,9 @@
339#define AR5K_SISR2 0x008c /* Register Address [5211+] */ 339#define AR5K_SISR2 0x008c /* Register Address [5211+] */
340#define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ 340#define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */
341#define AR5K_SISR2_QCU_TXURN_S 0 341#define AR5K_SISR2_QCU_TXURN_S 0
342#define AR5K_SISR2_MCABT 0x00100000 /* Master Cycle Abort */ 342#define AR5K_SISR2_MCABT 0x00010000 /* Master Cycle Abort */
343#define AR5K_SISR2_SSERR 0x00200000 /* Signaled System Error */ 343#define AR5K_SISR2_SSERR 0x00020000 /* Signaled System Error */
344#define AR5K_SISR2_DPERR 0x00400000 /* Bus parity error */ 344#define AR5K_SISR2_DPERR 0x00040000 /* Bus parity error */
345#define AR5K_SISR2_TIM 0x01000000 /* [5212+] */ 345#define AR5K_SISR2_TIM 0x01000000 /* [5212+] */
346#define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */ 346#define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */
347#define AR5K_SISR2_DTIM_SYNC 0x04000000 /* DTIM sync lost [5212+] */ 347#define AR5K_SISR2_DTIM_SYNC 0x04000000 /* DTIM sync lost [5212+] */
@@ -430,9 +430,9 @@
430#define AR5K_SIMR2 0x00ac /* Register Address [5211+] */ 430#define AR5K_SIMR2 0x00ac /* Register Address [5211+] */
431#define AR5K_SIMR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ 431#define AR5K_SIMR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */
432#define AR5K_SIMR2_QCU_TXURN_S 0 432#define AR5K_SIMR2_QCU_TXURN_S 0
433#define AR5K_SIMR2_MCABT 0x00100000 /* Master Cycle Abort */ 433#define AR5K_SIMR2_MCABT 0x00010000 /* Master Cycle Abort */
434#define AR5K_SIMR2_SSERR 0x00200000 /* Signaled System Error */ 434#define AR5K_SIMR2_SSERR 0x00020000 /* Signaled System Error */
435#define AR5K_SIMR2_DPERR 0x00400000 /* Bus parity error */ 435#define AR5K_SIMR2_DPERR 0x00040000 /* Bus parity error */
436#define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */ 436#define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */
437#define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */ 437#define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */
438#define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* DTIM Sync lost [5212+] */ 438#define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* DTIM Sync lost [5212+] */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index eb9d5228cb6c..751885a5df47 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -164,7 +164,6 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
164#define WME_NUM_TID 16 164#define WME_NUM_TID 16
165#define ATH_TXBUF 512 165#define ATH_TXBUF 512
166#define ATH_TXMAXTRY 13 166#define ATH_TXMAXTRY 13
167#define ATH_11N_TXMAXTRY 10
168#define ATH_MGT_TXMAXTRY 4 167#define ATH_MGT_TXMAXTRY 4
169#define WME_BA_BMP_SIZE 64 168#define WME_BA_BMP_SIZE 64
170#define WME_MAX_BA WME_BA_BMP_SIZE 169#define WME_MAX_BA WME_BA_BMP_SIZE
@@ -226,6 +225,8 @@ void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
226#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA) 225#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
227#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)]) 226#define ATH_AN_2_TID(_an, _tidno) (&(_an)->tid[(_tidno)])
228 227
228#define ATH_TX_COMPLETE_POLL_INT 1000
229
229enum ATH_AGGR_STATUS { 230enum ATH_AGGR_STATUS {
230 ATH_AGGR_DONE, 231 ATH_AGGR_DONE,
231 ATH_AGGR_BAW_CLOSED, 232 ATH_AGGR_BAW_CLOSED,
@@ -241,6 +242,7 @@ struct ath_txq {
241 u8 axq_aggr_depth; 242 u8 axq_aggr_depth;
242 u32 axq_totalqueued; 243 u32 axq_totalqueued;
243 bool stopped; 244 bool stopped;
245 bool axq_tx_inprogress;
244 struct ath_buf *axq_linkbuf; 246 struct ath_buf *axq_linkbuf;
245 247
246 /* first desc of the last descriptor that contains CTS */ 248 /* first desc of the last descriptor that contains CTS */
@@ -291,12 +293,28 @@ struct ath_tx_control {
291#define ATH_TX_XRETRY 0x02 293#define ATH_TX_XRETRY 0x02
292#define ATH_TX_BAR 0x04 294#define ATH_TX_BAR 0x04
293 295
296#define ATH_RSSI_LPF_LEN 10
297#define RSSI_LPF_THRESHOLD -20
298#define ATH9K_RSSI_BAD 0x80
299#define ATH_RSSI_EP_MULTIPLIER (1<<7)
300#define ATH_EP_MUL(x, mul) ((x) * (mul))
301#define ATH_RSSI_IN(x) (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER))
302#define ATH_LPF_RSSI(x, y, len) \
303 ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
304#define ATH_RSSI_LPF(x, y) do { \
305 if ((y) >= RSSI_LPF_THRESHOLD) \
306 x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \
307} while (0)
308#define ATH_EP_RND(x, mul) \
309 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
310
294struct ath_node { 311struct ath_node {
295 struct ath_softc *an_sc; 312 struct ath_softc *an_sc;
296 struct ath_atx_tid tid[WME_NUM_TID]; 313 struct ath_atx_tid tid[WME_NUM_TID];
297 struct ath_atx_ac ac[WME_NUM_AC]; 314 struct ath_atx_ac ac[WME_NUM_AC];
298 u16 maxampdu; 315 u16 maxampdu;
299 u8 mpdudensity; 316 u8 mpdudensity;
317 int last_rssi;
300}; 318};
301 319
302struct ath_tx { 320struct ath_tx {
@@ -541,6 +559,7 @@ struct ath_softc {
541 spinlock_t sc_resetlock; 559 spinlock_t sc_resetlock;
542 spinlock_t sc_serial_rw; 560 spinlock_t sc_serial_rw;
543 spinlock_t ani_lock; 561 spinlock_t ani_lock;
562 spinlock_t sc_pm_lock;
544 struct mutex mutex; 563 struct mutex mutex;
545 564
546 u8 curbssid[ETH_ALEN]; 565 u8 curbssid[ETH_ALEN];
@@ -557,7 +576,7 @@ struct ath_softc {
557 u32 keymax; 576 u32 keymax;
558 DECLARE_BITMAP(keymap, ATH_KEYMAX); 577 DECLARE_BITMAP(keymap, ATH_KEYMAX);
559 u8 splitmic; 578 u8 splitmic;
560 atomic_t ps_usecount; 579 unsigned long ps_usecount;
561 enum ath9k_int imask; 580 enum ath9k_int imask;
562 enum ath9k_ht_extprotspacing ht_extprotspacing; 581 enum ath9k_ht_extprotspacing ht_extprotspacing;
563 enum ath9k_ht_macmode tx_chan_width; 582 enum ath9k_ht_macmode tx_chan_width;
@@ -590,6 +609,7 @@ struct ath_softc {
590#endif 609#endif
591 struct ath_bus_ops *bus_ops; 610 struct ath_bus_ops *bus_ops;
592 struct ath_beacon_config cur_beacon_conf; 611 struct ath_beacon_config cur_beacon_conf;
612 struct delayed_work tx_complete_work;
593}; 613};
594 614
595struct ath_wiphy { 615struct ath_wiphy {
@@ -654,27 +674,8 @@ static inline int ath_ahb_init(void) { return 0; };
654static inline void ath_ahb_exit(void) {}; 674static inline void ath_ahb_exit(void) {};
655#endif 675#endif
656 676
657static inline void ath9k_ps_wakeup(struct ath_softc *sc) 677void ath9k_ps_wakeup(struct ath_softc *sc);
658{ 678void ath9k_ps_restore(struct ath_softc *sc);
659 if (atomic_inc_return(&sc->ps_usecount) == 1)
660 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) {
661 sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
662 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
663 }
664}
665
666static inline void ath9k_ps_restore(struct ath_softc *sc)
667{
668 if (atomic_dec_and_test(&sc->ps_usecount))
669 if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
670 !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
671 SC_OP_WAIT_FOR_CAB |
672 SC_OP_WAIT_FOR_PSPOLL_DATA |
673 SC_OP_WAIT_FOR_TX_ACK)))
674 ath9k_hw_setpower(sc->sc_ah,
675 sc->sc_ah->restore_mode);
676}
677
678 679
679void ath9k_set_bssid_mask(struct ieee80211_hw *hw); 680void ath9k_set_bssid_mask(struct ieee80211_hw *hw);
680int ath9k_wiphy_add(struct ath_softc *sc); 681int ath9k_wiphy_add(struct ath_softc *sc);
@@ -690,6 +691,7 @@ void ath9k_wiphy_pause_all_forced(struct ath_softc *sc,
690 struct ath_wiphy *selected); 691 struct ath_wiphy *selected);
691bool ath9k_wiphy_scanning(struct ath_softc *sc); 692bool ath9k_wiphy_scanning(struct ath_softc *sc);
692void ath9k_wiphy_work(struct work_struct *work); 693void ath9k_wiphy_work(struct work_struct *work);
694bool ath9k_all_wiphys_idle(struct ath_softc *sc);
693 695
694void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val); 696void ath9k_iowrite32(struct ath_hw *ah, u32 reg_offset, u32 val);
695unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset); 697unsigned int ath9k_ioread32(struct ath_hw *ah, u32 reg_offset);
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index a32d7e7fecbe..1f0c5fe4a68b 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -691,15 +691,22 @@ int16_t ath9k_hw_getnf(struct ath_hw *ah,
691void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah) 691void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah)
692{ 692{
693 int i, j; 693 int i, j;
694 s16 noise_floor;
695
696 if (AR_SREV_9280(ah))
697 noise_floor = AR_PHY_CCA_MAX_AR9280_GOOD_VALUE;
698 else if (AR_SREV_9285(ah))
699 noise_floor = AR_PHY_CCA_MAX_AR9285_GOOD_VALUE;
700 else
701 noise_floor = AR_PHY_CCA_MAX_AR5416_GOOD_VALUE;
694 702
695 for (i = 0; i < NUM_NF_READINGS; i++) { 703 for (i = 0; i < NUM_NF_READINGS; i++) {
696 ah->nfCalHist[i].currIndex = 0; 704 ah->nfCalHist[i].currIndex = 0;
697 ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE; 705 ah->nfCalHist[i].privNF = noise_floor;
698 ah->nfCalHist[i].invalidNFcount = 706 ah->nfCalHist[i].invalidNFcount =
699 AR_PHY_CCA_FILTERWINDOW_LENGTH; 707 AR_PHY_CCA_FILTERWINDOW_LENGTH;
700 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) { 708 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
701 ah->nfCalHist[i].nfCalBuffer[j] = 709 ah->nfCalHist[i].nfCalBuffer[j] = noise_floor;
702 AR_PHY_CCA_MAX_GOOD_VALUE;
703 } 710 }
704 } 711 }
705} 712}
diff --git a/drivers/net/wireless/ath/ath9k/calib.h b/drivers/net/wireless/ath/ath9k/calib.h
index fe5367f14148..547e697b9055 100644
--- a/drivers/net/wireless/ath/ath9k/calib.h
+++ b/drivers/net/wireless/ath/ath9k/calib.h
@@ -25,7 +25,9 @@ extern const struct ath9k_percal_data adc_dc_cal_multi_sample;
25extern const struct ath9k_percal_data adc_dc_cal_single_sample; 25extern const struct ath9k_percal_data adc_dc_cal_single_sample;
26extern const struct ath9k_percal_data adc_init_dc_cal; 26extern const struct ath9k_percal_data adc_init_dc_cal;
27 27
28#define AR_PHY_CCA_MAX_GOOD_VALUE -85 28#define AR_PHY_CCA_MAX_AR5416_GOOD_VALUE -85
29#define AR_PHY_CCA_MAX_AR9280_GOOD_VALUE -112
30#define AR_PHY_CCA_MAX_AR9285_GOOD_VALUE -118
29#define AR_PHY_CCA_MAX_HIGH_VALUE -62 31#define AR_PHY_CCA_MAX_HIGH_VALUE -62
30#define AR_PHY_CCA_MIN_BAD_VALUE -140 32#define AR_PHY_CCA_MIN_BAD_VALUE -140
31#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3 33#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index d82a0f97e6f5..df41ed5fd7c4 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -1208,6 +1208,19 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
1208 pModal->xatten2Margin[0]); 1208 pModal->xatten2Margin[0]);
1209 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 1209 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
1210 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]); 1210 AR_PHY_GAIN_2GHZ_XATTEN2_DB, pModal->xatten2Db[0]);
1211
1212 /* Set the block 1 value to block 0 value */
1213 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
1214 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
1215 pModal->bswMargin[0]);
1216 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
1217 AR_PHY_GAIN_2GHZ_XATTEN1_DB, pModal->bswAtten[0]);
1218 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
1219 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
1220 pModal->xatten2Margin[0]);
1221 REG_RMW_FIELD(ah, AR_PHY_GAIN_2GHZ + 0x1000,
1222 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
1223 pModal->xatten2Db[0]);
1211 } 1224 }
1212 1225
1213 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1226 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
@@ -1215,6 +1228,11 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
1215 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset, 1228 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + regChainOffset,
1216 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 1229 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
1217 1230
1231 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
1232 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
1233 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
1234 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
1235
1218 if (AR_SREV_9285_11(ah)) 1236 if (AR_SREV_9285_11(ah))
1219 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14)); 1237 REG_WRITE(ah, AR9285_AN_TOP4, (AR9285_AN_TOP4_DEFAULT | 0x14));
1220} 1238}
@@ -1239,7 +1257,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1239 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0); 1257 ath9k_hw_4k_set_gain(ah, pModal, eep, txRxAttenLocal, 0);
1240 1258
1241 /* Initialize Ant Diversity settings from EEPROM */ 1259 /* Initialize Ant Diversity settings from EEPROM */
1242 if (pModal->version == 3) { 1260 if (pModal->version >= 3) {
1243 ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf); 1261 ant_div_control1 = ((pModal->ob_234 >> 12) & 0xf);
1244 ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf); 1262 ant_div_control2 = ((pModal->db1_234 >> 12) & 0xf);
1245 regVal = REG_READ(ah, 0x99ac); 1263 regVal = REG_READ(ah, 0x99ac);
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index cffb0789f669..605803ae9ed8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2728,7 +2728,8 @@ static bool ath9k_hw_set_power_awake(struct ath_hw *ah, int setChip)
2728 return true; 2728 return true;
2729} 2729}
2730 2730
2731bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode) 2731static bool ath9k_hw_setpower_nolock(struct ath_hw *ah,
2732 enum ath9k_power_mode mode)
2732{ 2733{
2733 int status = true, setChip = true; 2734 int status = true, setChip = true;
2734 static const char *modes[] = { 2735 static const char *modes[] = {
@@ -2762,6 +2763,55 @@ bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
2762 return status; 2763 return status;
2763} 2764}
2764 2765
2766bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode)
2767{
2768 unsigned long flags;
2769 bool ret;
2770
2771 spin_lock_irqsave(&ah->ah_sc->sc_pm_lock, flags);
2772 ret = ath9k_hw_setpower_nolock(ah, mode);
2773 spin_unlock_irqrestore(&ah->ah_sc->sc_pm_lock, flags);
2774
2775 return ret;
2776}
2777
2778void ath9k_ps_wakeup(struct ath_softc *sc)
2779{
2780 unsigned long flags;
2781
2782 spin_lock_irqsave(&sc->sc_pm_lock, flags);
2783 if (++sc->ps_usecount != 1)
2784 goto unlock;
2785
2786 if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE) {
2787 sc->sc_ah->restore_mode = sc->sc_ah->power_mode;
2788 ath9k_hw_setpower_nolock(sc->sc_ah, ATH9K_PM_AWAKE);
2789 }
2790
2791 unlock:
2792 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
2793}
2794
2795void ath9k_ps_restore(struct ath_softc *sc)
2796{
2797 unsigned long flags;
2798
2799 spin_lock_irqsave(&sc->sc_pm_lock, flags);
2800 if (--sc->ps_usecount != 0)
2801 goto unlock;
2802
2803 if ((sc->hw->conf.flags & IEEE80211_CONF_PS) &&
2804 !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON |
2805 SC_OP_WAIT_FOR_CAB |
2806 SC_OP_WAIT_FOR_PSPOLL_DATA |
2807 SC_OP_WAIT_FOR_TX_ACK)))
2808 ath9k_hw_setpower_nolock(sc->sc_ah,
2809 sc->sc_ah->restore_mode);
2810
2811 unlock:
2812 spin_unlock_irqrestore(&sc->sc_pm_lock, flags);
2813}
2814
2765/* 2815/*
2766 * Helper for ASPM support. 2816 * Helper for ASPM support.
2767 * 2817 *
@@ -3305,7 +3355,6 @@ void ath9k_hw_fill_cap_info(struct ath_hw *ah)
3305 } 3355 }
3306 3356
3307 if (eeval & AR5416_OPFLAGS_11G) { 3357 if (eeval & AR5416_OPFLAGS_11G) {
3308 set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
3309 set_bit(ATH9K_MODE_11G, pCap->wireless_modes); 3358 set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
3310 if (ah->config.ht_enable) { 3359 if (ah->config.ht_enable) {
3311 if (!(eeval & AR5416_OPFLAGS_N_2G_HT20)) 3360 if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
@@ -3791,19 +3840,14 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64)
3791 3840
3792void ath9k_hw_reset_tsf(struct ath_hw *ah) 3841void ath9k_hw_reset_tsf(struct ath_hw *ah)
3793{ 3842{
3794 int count; 3843 ath9k_ps_wakeup(ah->ah_sc);
3844 if (!ath9k_hw_wait(ah, AR_SLP32_MODE, AR_SLP32_TSF_WRITE_STATUS, 0,
3845 AH_TSF_WRITE_TIMEOUT))
3846 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3847 "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
3795 3848
3796 count = 0;
3797 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
3798 count++;
3799 if (count > 10) {
3800 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3801 "AR_SLP32_TSF_WRITE_STATUS limit exceeded\n");
3802 break;
3803 }
3804 udelay(10);
3805 }
3806 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE); 3849 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
3850 ath9k_ps_restore(ah->ah_sc);
3807} 3851}
3808 3852
3809bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting) 3853bool ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting)
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 9d0b31ad4603..28bffdb365a2 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -95,6 +95,7 @@
95 95
96#define MAX_RATE_POWER 63 96#define MAX_RATE_POWER 63
97#define AH_WAIT_TIMEOUT 100000 /* (us) */ 97#define AH_WAIT_TIMEOUT 100000 /* (us) */
98#define AH_TSF_WRITE_TIMEOUT 100 /* (us) */
98#define AH_TIME_QUANTUM 10 99#define AH_TIME_QUANTUM 10
99#define AR_KEYTABLE_SIZE 128 100#define AR_KEYTABLE_SIZE 128
100#define POWER_UP_TIME 200000 101#define POWER_UP_TIME 200000
@@ -113,15 +114,14 @@
113 114
114enum wireless_mode { 115enum wireless_mode {
115 ATH9K_MODE_11A = 0, 116 ATH9K_MODE_11A = 0,
116 ATH9K_MODE_11B = 2, 117 ATH9K_MODE_11G,
117 ATH9K_MODE_11G = 3, 118 ATH9K_MODE_11NA_HT20,
118 ATH9K_MODE_11NA_HT20 = 6, 119 ATH9K_MODE_11NG_HT20,
119 ATH9K_MODE_11NG_HT20 = 7, 120 ATH9K_MODE_11NA_HT40PLUS,
120 ATH9K_MODE_11NA_HT40PLUS = 8, 121 ATH9K_MODE_11NA_HT40MINUS,
121 ATH9K_MODE_11NA_HT40MINUS = 9, 122 ATH9K_MODE_11NG_HT40PLUS,
122 ATH9K_MODE_11NG_HT40PLUS = 10, 123 ATH9K_MODE_11NG_HT40MINUS,
123 ATH9K_MODE_11NG_HT40MINUS = 11, 124 ATH9K_MODE_MAX,
124 ATH9K_MODE_MAX
125}; 125};
126 126
127enum ath9k_hw_caps { 127enum ath9k_hw_caps {
diff --git a/drivers/net/wireless/ath/ath9k/initvals.h b/drivers/net/wireless/ath/ath9k/initvals.h
index e2f0a34b79a1..f67a2a96cc5c 100644
--- a/drivers/net/wireless/ath/ath9k/initvals.h
+++ b/drivers/net/wireless/ath/ath9k/initvals.h
@@ -2782,7 +2782,7 @@ static const u32 ar9280Common_9280_2[][2] = {
2782 { 0x00008338, 0x00ff0000 }, 2782 { 0x00008338, 0x00ff0000 },
2783 { 0x0000833c, 0x00000000 }, 2783 { 0x0000833c, 0x00000000 },
2784 { 0x00008340, 0x000107ff }, 2784 { 0x00008340, 0x000107ff },
2785 { 0x00008344, 0x00581043 }, 2785 { 0x00008344, 0x00481043 },
2786 { 0x00009808, 0x00000000 }, 2786 { 0x00009808, 0x00000000 },
2787 { 0x0000980c, 0xafa68e30 }, 2787 { 0x0000980c, 0xafa68e30 },
2788 { 0x00009810, 0xfd14e000 }, 2788 { 0x00009810, 0xfd14e000 },
@@ -3439,7 +3439,7 @@ static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
3439 {0x00004044, 0x00000000 }, 3439 {0x00004044, 0x00000000 },
3440}; 3440};
3441 3441
3442/* AR9285 */ 3442/* AR9285 Revsion 10*/
3443static const u_int32_t ar9285Modes_9285[][6] = { 3443static const u_int32_t ar9285Modes_9285[][6] = {
3444 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, 3444 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
3445 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, 3445 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
@@ -3955,7 +3955,7 @@ static const u_int32_t ar9285Common_9285[][2] = {
3955 { 0x00008338, 0x00000000 }, 3955 { 0x00008338, 0x00000000 },
3956 { 0x0000833c, 0x00000000 }, 3956 { 0x0000833c, 0x00000000 },
3957 { 0x00008340, 0x00010380 }, 3957 { 0x00008340, 0x00010380 },
3958 { 0x00008344, 0x00581043 }, 3958 { 0x00008344, 0x00481043 },
3959 { 0x00009808, 0x00000000 }, 3959 { 0x00009808, 0x00000000 },
3960 { 0x0000980c, 0xafe68e30 }, 3960 { 0x0000980c, 0xafe68e30 },
3961 { 0x00009810, 0xfd14e000 }, 3961 { 0x00009810, 0xfd14e000 },
@@ -4121,8 +4121,9 @@ static const u_int32_t ar9285PciePhy_clkreq_off_L1_9285[][2] = {
4121 {0x00004044, 0x00000000 }, 4121 {0x00004044, 0x00000000 },
4122}; 4122};
4123 4123
4124/* AR9285 v1_2 PCI Register Writes. Created: 03/04/09 */ 4124/* AR9285 v1_2 PCI Register Writes. Created: 04/13/09 */
4125static const u_int32_t ar9285Modes_9285_1_2[][6] = { 4125static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4126 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
4126 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 }, 4127 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
4127 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 }, 4128 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
4128 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 }, 4129 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
@@ -4139,6 +4140,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4139 { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e }, 4140 { 0x00009840, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e, 0x206a012e },
4140 { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 }, 4141 { 0x00009844, 0x0372161e, 0x0372161e, 0x03721620, 0x03721620, 0x037216a0 },
4141 { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 }, 4142 { 0x00009848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
4143 { 0x0000a848, 0x00001066, 0x00001066, 0x00001053, 0x00001053, 0x00001059 },
4142 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 }, 4144 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
4143 { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e }, 4145 { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e, 0x7ec84d2e },
4144 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e }, 4146 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3137605e, 0x3137605e, 0x3139605e },
@@ -4419,6 +4421,7 @@ static const u_int32_t ar9285Modes_9285_1_2[][6] = {
4419 { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 }, 4421 { 0x0000abfc, 0x00000000, 0x00000000, 0x000eb7db, 0x000eb7db, 0x00000000 },
4420 { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 }, 4422 { 0x0000a204, 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 },
4421 { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 }, 4423 { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
4424 { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f000, 0x0001f000, 0x0001f000 },
4422 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a }, 4425 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
4423 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 }, 4426 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
4424 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 }, 4427 { 0x0000a250, 0x0004f000, 0x0004f000, 0x0004a000, 0x0004a000, 0x0004a000 },
@@ -4618,7 +4621,7 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
4618 { 0x00008338, 0x00ff0000 }, 4621 { 0x00008338, 0x00ff0000 },
4619 { 0x0000833c, 0x00000000 }, 4622 { 0x0000833c, 0x00000000 },
4620 { 0x00008340, 0x00010380 }, 4623 { 0x00008340, 0x00010380 },
4621 { 0x00008344, 0x00581043 }, 4624 { 0x00008344, 0x00481043 },
4622 { 0x00009808, 0x00000000 }, 4625 { 0x00009808, 0x00000000 },
4623 { 0x0000980c, 0xafe68e30 }, 4626 { 0x0000980c, 0xafe68e30 },
4624 { 0x00009810, 0xfd14e000 }, 4627 { 0x00009810, 0xfd14e000 },
@@ -4752,18 +4755,18 @@ static const u_int32_t ar9285Common_9285_1_2[][2] = {
4752static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = { 4755static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
4753 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */ 4756 /* Address 5G-HT20 5G-HT40 2G-HT40 2G-HT20 Turbo */
4754 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, 4757 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
4755 { 0x0000a304, 0x00000000, 0x00000000, 0x00005200, 0x00005200, 0x00000000 }, 4758 { 0x0000a304, 0x00000000, 0x00000000, 0x00006200, 0x00006200, 0x00000000 },
4756 { 0x0000a308, 0x00000000, 0x00000000, 0x00007201, 0x00007201, 0x00000000 }, 4759 { 0x0000a308, 0x00000000, 0x00000000, 0x00008201, 0x00008201, 0x00000000 },
4757 { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 }, 4760 { 0x0000a30c, 0x00000000, 0x00000000, 0x0000b240, 0x0000b240, 0x00000000 },
4758 { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 }, 4761 { 0x0000a310, 0x00000000, 0x00000000, 0x0000d241, 0x0000d241, 0x00000000 },
4759 { 0x0000a314, 0x00000000, 0x00000000, 0x0000f440, 0x0000f440, 0x00000000 }, 4762 { 0x0000a314, 0x00000000, 0x00000000, 0x0000f600, 0x0000f600, 0x00000000 },
4760 { 0x0000a318, 0x00000000, 0x00000000, 0x00014640, 0x00014640, 0x00000000 }, 4763 { 0x0000a318, 0x00000000, 0x00000000, 0x00012800, 0x00012800, 0x00000000 },
4761 { 0x0000a31c, 0x00000000, 0x00000000, 0x00018680, 0x00018680, 0x00000000 }, 4764 { 0x0000a31c, 0x00000000, 0x00000000, 0x00016802, 0x00016802, 0x00000000 },
4762 { 0x0000a320, 0x00000000, 0x00000000, 0x00019841, 0x00019841, 0x00000000 }, 4765 { 0x0000a320, 0x00000000, 0x00000000, 0x0001b805, 0x0001b805, 0x00000000 },
4763 { 0x0000a324, 0x00000000, 0x00000000, 0x0001ca40, 0x0001ca40, 0x00000000 }, 4766 { 0x0000a324, 0x00000000, 0x00000000, 0x00021a80, 0x00021a80, 0x00000000 },
4764 { 0x0000a328, 0x00000000, 0x00000000, 0x0001fa80, 0x0001fa80, 0x00000000 }, 4767 { 0x0000a328, 0x00000000, 0x00000000, 0x00028b00, 0x00028b00, 0x00000000 },
4765 { 0x0000a32c, 0x00000000, 0x00000000, 0x00023ac0, 0x00023ac0, 0x00000000 }, 4768 { 0x0000a32c, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 },
4766 { 0x0000a330, 0x00000000, 0x00000000, 0x0002ab40, 0x0002ab40, 0x00000000 }, 4769 { 0x0000a330, 0x00000000, 0x00000000, 0x0002cd80, 0x0002cd80, 0x00000000 },
4767 { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 }, 4770 { 0x0000a334, 0x00000000, 0x00000000, 0x00033d82, 0x00033d82, 0x00000000 },
4768 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 }, 4771 { 0x0000a338, 0x0003891e, 0x0003891e, 0x0003891e, 0x0003891e, 0x00000000 },
4769 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 }, 4772 { 0x0000a33c, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x0003a95e, 0x00000000 },
@@ -4776,13 +4779,13 @@ static const u_int32_t ar9285Modes_high_power_tx_gain_9285_1_2[][6] = {
4776 { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 }, 4779 { 0x00007838, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803, 0xfac68803 },
4777 { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe }, 4780 { 0x0000786c, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe, 0x08609ebe },
4778 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 }, 4781 { 0x00007820, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00, 0x00000c00 },
4779 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a21a652, 0x0a21a652, 0x0a22a652 }, 4782 { 0x0000a274, 0x0a22a652, 0x0a22a652, 0x0a216652, 0x0a216652, 0x0a22a652 },
4780 { 0x0000a278, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce }, 4783 { 0x0000a278, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
4781 { 0x0000a27c, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce, 0x050701ce }, 4784 { 0x0000a27c, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7, 0x050380e7 },
4782 { 0x0000a394, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce }, 4785 { 0x0000a394, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
4783 { 0x0000a398, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce }, 4786 { 0x0000a398, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
4784 { 0x0000a3dc, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce }, 4787 { 0x0000a3dc, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7, 0x0e739ce7 },
4785 { 0x0000a3e0, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce }, 4788 { 0x0000a3e0, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7, 0x000000e7 },
4786}; 4789};
4787 4790
4788static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = { 4791static const u_int32_t ar9285Modes_original_tx_gain_9285_1_2[][6] = {
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c
index 8ae4ec21667b..6f923e318727 100644
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -825,13 +825,29 @@ int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
825 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen; 825 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
826 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp; 826 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
827 827
828 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined); 828 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
829 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00); 829 ds->ds_rxstat.rs_rssi = ATH9K_RSSI_BAD;
830 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01); 830 ds->ds_rxstat.rs_rssi_ctl0 = ATH9K_RSSI_BAD;
831 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02); 831 ds->ds_rxstat.rs_rssi_ctl1 = ATH9K_RSSI_BAD;
832 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10); 832 ds->ds_rxstat.rs_rssi_ctl2 = ATH9K_RSSI_BAD;
833 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11); 833 ds->ds_rxstat.rs_rssi_ext0 = ATH9K_RSSI_BAD;
834 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12); 834 ds->ds_rxstat.rs_rssi_ext1 = ATH9K_RSSI_BAD;
835 ds->ds_rxstat.rs_rssi_ext2 = ATH9K_RSSI_BAD;
836 } else {
837 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
838 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
839 AR_RxRSSIAnt00);
840 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
841 AR_RxRSSIAnt01);
842 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
843 AR_RxRSSIAnt02);
844 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4,
845 AR_RxRSSIAnt10);
846 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4,
847 AR_RxRSSIAnt11);
848 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4,
849 AR_RxRSSIAnt12);
850 }
835 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid) 851 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
836 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx); 852 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
837 else 853 else
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 961b0ce6ef3e..3436295e0509 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -465,6 +465,7 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta)
465 an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR + 465 an->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
466 sta->ht_cap.ampdu_factor); 466 sta->ht_cap.ampdu_factor);
467 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density); 467 an->mpdudensity = parse_mpdudensity(sta->ht_cap.ampdu_density);
468 an->last_rssi = ATH_RSSI_DUMMY_MARKER;
468 } 469 }
469} 470}
470 471
@@ -1258,6 +1259,7 @@ void ath_detach(struct ath_softc *sc)
1258 ath_deinit_leds(sc); 1259 ath_deinit_leds(sc);
1259 cancel_work_sync(&sc->chan_work); 1260 cancel_work_sync(&sc->chan_work);
1260 cancel_delayed_work_sync(&sc->wiphy_work); 1261 cancel_delayed_work_sync(&sc->wiphy_work);
1262 cancel_delayed_work_sync(&sc->tx_complete_work);
1261 1263
1262 for (i = 0; i < sc->num_sec_wiphy; i++) { 1264 for (i = 0; i < sc->num_sec_wiphy; i++) {
1263 struct ath_wiphy *aphy = sc->sec_wiphy[i]; 1265 struct ath_wiphy *aphy = sc->sec_wiphy[i];
@@ -1284,7 +1286,6 @@ void ath_detach(struct ath_softc *sc)
1284 1286
1285 ath9k_hw_detach(sc->sc_ah); 1287 ath9k_hw_detach(sc->sc_ah);
1286 ath9k_exit_debug(sc); 1288 ath9k_exit_debug(sc);
1287 ath9k_ps_restore(sc);
1288} 1289}
1289 1290
1290static int ath9k_reg_notifier(struct wiphy *wiphy, 1291static int ath9k_reg_notifier(struct wiphy *wiphy,
@@ -1315,6 +1316,7 @@ static int ath_init(u16 devid, struct ath_softc *sc)
1315 spin_lock_init(&sc->sc_resetlock); 1316 spin_lock_init(&sc->sc_resetlock);
1316 spin_lock_init(&sc->sc_serial_rw); 1317 spin_lock_init(&sc->sc_serial_rw);
1317 spin_lock_init(&sc->ani_lock); 1318 spin_lock_init(&sc->ani_lock);
1319 spin_lock_init(&sc->sc_pm_lock);
1318 mutex_init(&sc->mutex); 1320 mutex_init(&sc->mutex);
1319 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc); 1321 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
1320 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet, 1322 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
@@ -1540,7 +1542,8 @@ void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
1540 hw->max_rates = 4; 1542 hw->max_rates = 4;
1541 hw->channel_change_time = 5000; 1543 hw->channel_change_time = 5000;
1542 hw->max_listen_interval = 10; 1544 hw->max_listen_interval = 10;
1543 hw->max_rate_tries = ATH_11N_TXMAXTRY; 1545 /* Hardware supports 10 but we use 4 */
1546 hw->max_rate_tries = 4;
1544 hw->sta_data_size = sizeof(struct ath_node); 1547 hw->sta_data_size = sizeof(struct ath_node);
1545 hw->vif_data_size = sizeof(struct ath_vif); 1548 hw->vif_data_size = sizeof(struct ath_vif);
1546 1549
@@ -1977,6 +1980,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
1977 1980
1978 ieee80211_wake_queues(hw); 1981 ieee80211_wake_queues(hw);
1979 1982
1983 queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work, 0);
1984
1980mutex_unlock: 1985mutex_unlock:
1981 mutex_unlock(&sc->mutex); 1986 mutex_unlock(&sc->mutex);
1982 1987
@@ -2096,8 +2101,6 @@ static void ath9k_stop(struct ieee80211_hw *hw)
2096 2101
2097 mutex_lock(&sc->mutex); 2102 mutex_lock(&sc->mutex);
2098 2103
2099 ieee80211_stop_queues(hw);
2100
2101 if (ath9k_wiphy_started(sc)) { 2104 if (ath9k_wiphy_started(sc)) {
2102 mutex_unlock(&sc->mutex); 2105 mutex_unlock(&sc->mutex);
2103 return; /* another wiphy still in use */ 2106 return; /* another wiphy still in use */
@@ -2255,9 +2258,28 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2255 struct ath_softc *sc = aphy->sc; 2258 struct ath_softc *sc = aphy->sc;
2256 struct ieee80211_conf *conf = &hw->conf; 2259 struct ieee80211_conf *conf = &hw->conf;
2257 struct ath_hw *ah = sc->sc_ah; 2260 struct ath_hw *ah = sc->sc_ah;
2261 bool all_wiphys_idle = false, disable_radio = false;
2258 2262
2259 mutex_lock(&sc->mutex); 2263 mutex_lock(&sc->mutex);
2260 2264
2265 /* Leave this as the first check */
2266 if (changed & IEEE80211_CONF_CHANGE_IDLE) {
2267
2268 spin_lock_bh(&sc->wiphy_lock);
2269 all_wiphys_idle = ath9k_all_wiphys_idle(sc);
2270 spin_unlock_bh(&sc->wiphy_lock);
2271
2272 if (conf->flags & IEEE80211_CONF_IDLE){
2273 if (all_wiphys_idle)
2274 disable_radio = true;
2275 }
2276 else if (all_wiphys_idle) {
2277 ath_radio_enable(sc);
2278 DPRINTF(sc, ATH_DBG_CONFIG,
2279 "not-idle: enabling radio\n");
2280 }
2281 }
2282
2261 if (changed & IEEE80211_CONF_CHANGE_PS) { 2283 if (changed & IEEE80211_CONF_CHANGE_PS) {
2262 if (conf->flags & IEEE80211_CONF_PS) { 2284 if (conf->flags & IEEE80211_CONF_PS) {
2263 if (!(ah->caps.hw_caps & 2285 if (!(ah->caps.hw_caps &
@@ -2325,6 +2347,11 @@ skip_chan_change:
2325 if (changed & IEEE80211_CONF_CHANGE_POWER) 2347 if (changed & IEEE80211_CONF_CHANGE_POWER)
2326 sc->config.txpowlimit = 2 * conf->power_level; 2348 sc->config.txpowlimit = 2 * conf->power_level;
2327 2349
2350 if (disable_radio) {
2351 DPRINTF(sc, ATH_DBG_CONFIG, "idle: disabling radio\n");
2352 ath_radio_disable(sc);
2353 }
2354
2328 mutex_unlock(&sc->mutex); 2355 mutex_unlock(&sc->mutex);
2329 2356
2330 return 0; 2357 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index ba06e78b2f50..a07efa22551e 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -22,133 +22,132 @@ static const struct ath_rate_table ar5416_11na_ratetable = {
22 { 22 {
23 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 23 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
24 5400, 0x0b, 0x00, 12, 24 5400, 0x0b, 0x00, 12,
25 0, 2, 1, 0, 0, 0, 0, 0 }, 25 0, 0, 0, 0, 0, 0 },
26 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 26 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
27 7800, 0x0f, 0x00, 18, 27 7800, 0x0f, 0x00, 18,
28 0, 3, 1, 1, 1, 1, 1, 0 }, 28 0, 1, 1, 1, 1, 0 },
29 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 29 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
30 10000, 0x0a, 0x00, 24, 30 10000, 0x0a, 0x00, 24,
31 2, 4, 2, 2, 2, 2, 2, 0 }, 31 2, 2, 2, 2, 2, 0 },
32 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 32 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
33 13900, 0x0e, 0x00, 36, 33 13900, 0x0e, 0x00, 36,
34 2, 6, 2, 3, 3, 3, 3, 0 }, 34 2, 3, 3, 3, 3, 0 },
35 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 35 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
36 17300, 0x09, 0x00, 48, 36 17300, 0x09, 0x00, 48,
37 4, 10, 3, 4, 4, 4, 4, 0 }, 37 4, 4, 4, 4, 4, 0 },
38 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 38 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
39 23000, 0x0d, 0x00, 72, 39 23000, 0x0d, 0x00, 72,
40 4, 14, 3, 5, 5, 5, 5, 0 }, 40 4, 5, 5, 5, 5, 0 },
41 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 41 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
42 27400, 0x08, 0x00, 96, 42 27400, 0x08, 0x00, 96,
43 4, 20, 3, 6, 6, 6, 6, 0 }, 43 4, 6, 6, 6, 6, 0 },
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, 23, 3, 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_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
48 6400, 0x80, 0x00, 0, 48 6400, 0x80, 0x00, 0,
49 0, 2, 3, 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 */
51 12700, 0x81, 0x00, 1, 51 12700, 0x81, 0x00, 1,
52 2, 4, 3, 9, 25, 9, 25, 6434 }, 52 2, 9, 25, 9, 25, 6434 },
53 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 53 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
54 18800, 0x82, 0x00, 2, 54 18800, 0x82, 0x00, 2,
55 2, 6, 3, 10, 26, 10, 26, 9650 }, 55 2, 10, 26, 10, 26, 9650 },
56 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 56 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
57 25000, 0x83, 0x00, 3, 57 25000, 0x83, 0x00, 3,
58 4, 10, 3, 11, 27, 11, 27, 12868 }, 58 4, 11, 27, 11, 27, 12868 },
59 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 59 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
60 36700, 0x84, 0x00, 4, 60 36700, 0x84, 0x00, 4,
61 4, 14, 3, 12, 28, 12, 28, 19304 }, 61 4, 12, 28, 12, 28, 19304 },
62 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 62 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
63 48100, 0x85, 0x00, 5, 63 48100, 0x85, 0x00, 5,
64 4, 20, 3, 13, 29, 13, 29, 25740 }, 64 4, 13, 29, 13, 29, 25740 },
65 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 65 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
66 53500, 0x86, 0x00, 6, 66 53500, 0x86, 0x00, 6,
67 4, 23, 3, 14, 30, 14, 30, 28956 }, 67 4, 14, 30, 14, 30, 28956 },
68 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 68 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
69 59000, 0x87, 0x00, 7, 69 59000, 0x87, 0x00, 7,
70 4, 25, 3, 15, 31, 15, 32, 32180 }, 70 4, 15, 31, 15, 32, 32180 },
71 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 71 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
72 12700, 0x88, 0x00, 72 12700, 0x88, 0x00,
73 8, 0, 2, 3, 16, 33, 16, 33, 6430 }, 73 8, 3, 16, 33, 16, 33, 6430 },
74 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 74 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
75 24800, 0x89, 0x00, 9, 75 24800, 0x89, 0x00, 9,
76 2, 4, 3, 17, 34, 17, 34, 12860 }, 76 2, 17, 34, 17, 34, 12860 },
77 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 77 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
78 36600, 0x8a, 0x00, 10, 78 36600, 0x8a, 0x00, 10,
79 2, 6, 3, 18, 35, 18, 35, 19300 }, 79 2, 18, 35, 18, 35, 19300 },
80 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 80 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
81 48100, 0x8b, 0x00, 11, 81 48100, 0x8b, 0x00, 11,
82 4, 10, 3, 19, 36, 19, 36, 25736 }, 82 4, 19, 36, 19, 36, 25736 },
83 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 83 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
84 69500, 0x8c, 0x00, 12, 84 69500, 0x8c, 0x00, 12,
85 4, 14, 3, 20, 37, 20, 37, 38600 }, 85 4, 20, 37, 20, 37, 38600 },
86 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 86 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
87 89500, 0x8d, 0x00, 13, 87 89500, 0x8d, 0x00, 13,
88 4, 20, 3, 21, 38, 21, 38, 51472 }, 88 4, 21, 38, 21, 38, 51472 },
89 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 89 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
90 98900, 0x8e, 0x00, 14, 90 98900, 0x8e, 0x00, 14,
91 4, 23, 3, 22, 39, 22, 39, 57890 }, 91 4, 22, 39, 22, 39, 57890 },
92 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 92 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
93 108300, 0x8f, 0x00, 15, 93 108300, 0x8f, 0x00, 15,
94 4, 25, 3, 23, 40, 23, 41, 64320 }, 94 4, 23, 40, 23, 41, 64320 },
95 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 95 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
96 13200, 0x80, 0x00, 0, 96 13200, 0x80, 0x00, 0,
97 0, 2, 3, 8, 24, 24, 24, 6684 }, 97 0, 8, 24, 24, 24, 6684 },
98 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 98 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
99 25900, 0x81, 0x00, 1, 99 25900, 0x81, 0x00, 1,
100 2, 4, 3, 9, 25, 25, 25, 13368 }, 100 2, 9, 25, 25, 25, 13368 },
101 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 101 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
102 38600, 0x82, 0x00, 2, 102 38600, 0x82, 0x00, 2,
103 2, 6, 3, 10, 26, 26, 26, 20052 }, 103 2, 10, 26, 26, 26, 20052 },
104 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 104 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
105 49800, 0x83, 0x00, 3, 105 49800, 0x83, 0x00, 3,
106 4, 10, 3, 11, 27, 27, 27, 26738 }, 106 4, 11, 27, 27, 27, 26738 },
107 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 107 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
108 72200, 0x84, 0x00, 4, 108 72200, 0x84, 0x00, 4,
109 4, 14, 3, 12, 28, 28, 28, 40104 }, 109 4, 12, 28, 28, 28, 40104 },
110 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 110 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
111 92900, 0x85, 0x00, 5, 111 92900, 0x85, 0x00, 5,
112 4, 20, 3, 13, 29, 29, 29, 53476 }, 112 4, 13, 29, 29, 29, 53476 },
113 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 113 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
114 102700, 0x86, 0x00, 6, 114 102700, 0x86, 0x00, 6,
115 4, 23, 3, 14, 30, 30, 30, 60156 }, 115 4, 14, 30, 30, 30, 60156 },
116 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 116 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
117 112000, 0x87, 0x00, 7, 117 112000, 0x87, 0x00, 7,
118 4, 25, 3, 15, 31, 32, 32, 66840 }, 118 4, 15, 31, 32, 32, 66840 },
119 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 119 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
120 122000, 0x87, 0x00, 7, 120 122000, 0x87, 0x00, 7,
121 4, 25, 3, 15, 31, 32, 32, 74200 }, 121 4, 15, 31, 32, 32, 74200 },
122 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 122 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
123 25800, 0x88, 0x00, 8, 123 25800, 0x88, 0x00, 8,
124 0, 2, 3, 16, 33, 33, 33, 13360 }, 124 0, 16, 33, 33, 33, 13360 },
125 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 125 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
126 49800, 0x89, 0x00, 9, 126 49800, 0x89, 0x00, 9,
127 2, 4, 3, 17, 34, 34, 34, 26720 }, 127 2, 17, 34, 34, 34, 26720 },
128 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 128 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
129 71900, 0x8a, 0x00, 10, 129 71900, 0x8a, 0x00, 10,
130 2, 6, 3, 18, 35, 35, 35, 40080 }, 130 2, 18, 35, 35, 35, 40080 },
131 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 131 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
132 92500, 0x8b, 0x00, 11, 132 92500, 0x8b, 0x00, 11,
133 4, 10, 3, 19, 36, 36, 36, 53440 }, 133 4, 19, 36, 36, 36, 53440 },
134 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 134 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
135 130300, 0x8c, 0x00, 12, 135 130300, 0x8c, 0x00, 12,
136 4, 14, 3, 20, 37, 37, 37, 80160 }, 136 4, 20, 37, 37, 37, 80160 },
137 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 137 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
138 162800, 0x8d, 0x00, 13, 138 162800, 0x8d, 0x00, 13,
139 4, 20, 3, 21, 38, 38, 38, 106880 }, 139 4, 21, 38, 38, 38, 106880 },
140 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 140 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
141 178200, 0x8e, 0x00, 14, 141 178200, 0x8e, 0x00, 14,
142 4, 23, 3, 22, 39, 39, 39, 120240 }, 142 4, 22, 39, 39, 39, 120240 },
143 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 143 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
144 192100, 0x8f, 0x00, 15, 144 192100, 0x8f, 0x00, 15,
145 4, 25, 3, 23, 40, 41, 41, 133600 }, 145 4, 23, 40, 41, 41, 133600 },
146 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 146 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
147 207000, 0x8f, 0x00, 15, 147 207000, 0x8f, 0x00, 15,
148 4, 25, 3, 23, 40, 41, 41, 148400 }, 148 4, 23, 40, 41, 41, 148400 },
149 }, 149 },
150 50, /* probe interval */ 150 50, /* probe interval */
151 50, /* rssi reduce interval */
152 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 151 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
153}; 152};
154 153
@@ -160,145 +159,144 @@ static const struct ath_rate_table ar5416_11ng_ratetable = {
160 { 159 {
161 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 160 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
162 900, 0x1b, 0x00, 2, 161 900, 0x1b, 0x00, 2,
163 0, 0, 1, 0, 0, 0, 0, 0 }, 162 0, 0, 0, 0, 0, 0 },
164 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 163 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
165 1900, 0x1a, 0x04, 4, 164 1900, 0x1a, 0x04, 4,
166 1, 1, 1, 1, 1, 1, 1, 0 }, 165 1, 1, 1, 1, 1, 0 },
167 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 166 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
168 4900, 0x19, 0x04, 11, 167 4900, 0x19, 0x04, 11,
169 2, 2, 2, 2, 2, 2, 2, 0 }, 168 2, 2, 2, 2, 2, 0 },
170 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 169 { VALID_ALL, VALID_ALL, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
171 8100, 0x18, 0x04, 22, 170 8100, 0x18, 0x04, 22,
172 3, 3, 2, 3, 3, 3, 3, 0 }, 171 3, 3, 3, 3, 3, 0 },
173 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 172 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
174 5400, 0x0b, 0x00, 12, 173 5400, 0x0b, 0x00, 12,
175 4, 2, 1, 4, 4, 4, 4, 0 }, 174 4, 4, 4, 4, 4, 0 },
176 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 175 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
177 7800, 0x0f, 0x00, 18, 176 7800, 0x0f, 0x00, 18,
178 4, 3, 1, 5, 5, 5, 5, 0 }, 177 4, 5, 5, 5, 5, 0 },
179 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 178 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
180 10100, 0x0a, 0x00, 24, 179 10100, 0x0a, 0x00, 24,
181 6, 4, 1, 6, 6, 6, 6, 0 }, 180 6, 6, 6, 6, 6, 0 },
182 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 181 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
183 14100, 0x0e, 0x00, 36, 182 14100, 0x0e, 0x00, 36,
184 6, 6, 2, 7, 7, 7, 7, 0 }, 183 6, 7, 7, 7, 7, 0 },
185 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 184 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
186 17700, 0x09, 0x00, 48, 185 17700, 0x09, 0x00, 48,
187 8, 10, 3, 8, 8, 8, 8, 0 }, 186 8, 8, 8, 8, 8, 0 },
188 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 187 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
189 23700, 0x0d, 0x00, 72, 188 23700, 0x0d, 0x00, 72,
190 8, 14, 3, 9, 9, 9, 9, 0 }, 189 8, 9, 9, 9, 9, 0 },
191 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 190 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
192 27400, 0x08, 0x00, 96, 191 27400, 0x08, 0x00, 96,
193 8, 20, 3, 10, 10, 10, 10, 0 }, 192 8, 10, 10, 10, 10, 0 },
194 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 193 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
195 30900, 0x0c, 0x00, 108, 194 30900, 0x0c, 0x00, 108,
196 8, 23, 3, 11, 11, 11, 11, 0 }, 195 8, 11, 11, 11, 11, 0 },
197 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */ 196 { INVALID, INVALID, WLAN_RC_PHY_HT_20_SS, 6500, /* 6.5 Mb */
198 6400, 0x80, 0x00, 0, 197 6400, 0x80, 0x00, 0,
199 4, 2, 3, 12, 28, 12, 28, 3216 }, 198 4, 12, 28, 12, 28, 3216 },
200 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */ 199 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 13000, /* 13 Mb */
201 12700, 0x81, 0x00, 1, 200 12700, 0x81, 0x00, 1,
202 6, 4, 3, 13, 29, 13, 29, 6434 }, 201 6, 13, 29, 13, 29, 6434 },
203 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */ 202 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 19500, /* 19.5 Mb */
204 18800, 0x82, 0x00, 2, 203 18800, 0x82, 0x00, 2,
205 6, 6, 3, 14, 30, 14, 30, 9650 }, 204 6, 14, 30, 14, 30, 9650 },
206 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */ 205 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 26000, /* 26 Mb */
207 25000, 0x83, 0x00, 3, 206 25000, 0x83, 0x00, 3,
208 8, 10, 3, 15, 31, 15, 31, 12868 }, 207 8, 15, 31, 15, 31, 12868 },
209 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */ 208 { VALID_20, VALID_20, WLAN_RC_PHY_HT_20_SS, 39000, /* 39 Mb */
210 36700, 0x84, 0x00, 4, 209 36700, 0x84, 0x00, 4,
211 8, 14, 3, 16, 32, 16, 32, 19304 }, 210 8, 16, 32, 16, 32, 19304 },
212 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */ 211 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 52000, /* 52 Mb */
213 48100, 0x85, 0x00, 5, 212 48100, 0x85, 0x00, 5,
214 8, 20, 3, 17, 33, 17, 33, 25740 }, 213 8, 17, 33, 17, 33, 25740 },
215 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */ 214 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 58500, /* 58.5 Mb */
216 53500, 0x86, 0x00, 6, 215 53500, 0x86, 0x00, 6,
217 8, 23, 3, 18, 34, 18, 34, 28956 }, 216 8, 18, 34, 18, 34, 28956 },
218 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */ 217 { INVALID, VALID_20, WLAN_RC_PHY_HT_20_SS, 65000, /* 65 Mb */
219 59000, 0x87, 0x00, 7, 218 59000, 0x87, 0x00, 7,
220 8, 25, 3, 19, 35, 19, 36, 32180 }, 219 8, 19, 35, 19, 36, 32180 },
221 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */ 220 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 13000, /* 13 Mb */
222 12700, 0x88, 0x00, 8, 221 12700, 0x88, 0x00, 8,
223 4, 2, 3, 20, 37, 20, 37, 6430 }, 222 4, 20, 37, 20, 37, 6430 },
224 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */ 223 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 26000, /* 26 Mb */
225 24800, 0x89, 0x00, 9, 224 24800, 0x89, 0x00, 9,
226 6, 4, 3, 21, 38, 21, 38, 12860 }, 225 6, 21, 38, 21, 38, 12860 },
227 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */ 226 { INVALID, INVALID, WLAN_RC_PHY_HT_20_DS, 39000, /* 39 Mb */
228 36600, 0x8a, 0x00, 10, 227 36600, 0x8a, 0x00, 10,
229 6, 6, 3, 22, 39, 22, 39, 19300 }, 228 6, 22, 39, 22, 39, 19300 },
230 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */ 229 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 52000, /* 52 Mb */
231 48100, 0x8b, 0x00, 11, 230 48100, 0x8b, 0x00, 11,
232 8, 10, 3, 23, 40, 23, 40, 25736 }, 231 8, 23, 40, 23, 40, 25736 },
233 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */ 232 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 78000, /* 78 Mb */
234 69500, 0x8c, 0x00, 12, 233 69500, 0x8c, 0x00, 12,
235 8, 14, 3, 24, 41, 24, 41, 38600 }, 234 8, 24, 41, 24, 41, 38600 },
236 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */ 235 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 104000, /* 104 Mb */
237 89500, 0x8d, 0x00, 13, 236 89500, 0x8d, 0x00, 13,
238 8, 20, 3, 25, 42, 25, 42, 51472 }, 237 8, 25, 42, 25, 42, 51472 },
239 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */ 238 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 117000, /* 117 Mb */
240 98900, 0x8e, 0x00, 14, 239 98900, 0x8e, 0x00, 14,
241 8, 23, 3, 26, 43, 26, 44, 57890 }, 240 8, 26, 43, 26, 44, 57890 },
242 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */ 241 { VALID_20, INVALID, WLAN_RC_PHY_HT_20_DS, 130000, /* 130 Mb */
243 108300, 0x8f, 0x00, 15, 242 108300, 0x8f, 0x00, 15,
244 8, 25, 3, 27, 44, 27, 45, 64320 }, 243 8, 27, 44, 27, 45, 64320 },
245 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */ 244 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 13500, /* 13.5 Mb */
246 13200, 0x80, 0x00, 0, 245 13200, 0x80, 0x00, 0,
247 8, 2, 3, 12, 28, 28, 28, 6684 }, 246 8, 12, 28, 28, 28, 6684 },
248 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */ 247 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 27500, /* 27.0 Mb */
249 25900, 0x81, 0x00, 1, 248 25900, 0x81, 0x00, 1,
250 8, 4, 3, 13, 29, 29, 29, 13368 }, 249 8, 13, 29, 29, 29, 13368 },
251 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */ 250 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 40500, /* 40.5 Mb */
252 38600, 0x82, 0x00, 2, 251 38600, 0x82, 0x00, 2,
253 8, 6, 3, 14, 30, 30, 30, 20052 }, 252 8, 14, 30, 30, 30, 20052 },
254 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */ 253 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 54000, /* 54 Mb */
255 49800, 0x83, 0x00, 3, 254 49800, 0x83, 0x00, 3,
256 8, 10, 3, 15, 31, 31, 31, 26738 }, 255 8, 15, 31, 31, 31, 26738 },
257 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */ 256 { VALID_40, VALID_40, WLAN_RC_PHY_HT_40_SS, 81500, /* 81 Mb */
258 72200, 0x84, 0x00, 4, 257 72200, 0x84, 0x00, 4,
259 8, 14, 3, 16, 32, 32, 32, 40104 }, 258 8, 16, 32, 32, 32, 40104 },
260 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */ 259 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 108000, /* 108 Mb */
261 92900, 0x85, 0x00, 5, 260 92900, 0x85, 0x00, 5,
262 8, 20, 3, 17, 33, 33, 33, 53476 }, 261 8, 17, 33, 33, 33, 53476 },
263 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */ 262 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 121500, /* 121.5 Mb */
264 102700, 0x86, 0x00, 6, 263 102700, 0x86, 0x00, 6,
265 8, 23, 3, 18, 34, 34, 34, 60156 }, 264 8, 18, 34, 34, 34, 60156 },
266 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */ 265 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS, 135000, /* 135 Mb */
267 112000, 0x87, 0x00, 7, 266 112000, 0x87, 0x00, 7,
268 8, 23, 3, 19, 35, 36, 36, 66840 }, 267 8, 19, 35, 36, 36, 66840 },
269 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */ 268 { INVALID, VALID_40, WLAN_RC_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
270 122000, 0x87, 0x00, 7, 269 122000, 0x87, 0x00, 7,
271 8, 25, 3, 19, 35, 36, 36, 74200 }, 270 8, 19, 35, 36, 36, 74200 },
272 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */ 271 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 27000, /* 27 Mb */
273 25800, 0x88, 0x00, 8, 272 25800, 0x88, 0x00, 8,
274 8, 2, 3, 20, 37, 37, 37, 13360 }, 273 8, 20, 37, 37, 37, 13360 },
275 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */ 274 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 54000, /* 54 Mb */
276 49800, 0x89, 0x00, 9, 275 49800, 0x89, 0x00, 9,
277 8, 4, 3, 21, 38, 38, 38, 26720 }, 276 8, 21, 38, 38, 38, 26720 },
278 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */ 277 { INVALID, INVALID, WLAN_RC_PHY_HT_40_DS, 81000, /* 81 Mb */
279 71900, 0x8a, 0x00, 10, 278 71900, 0x8a, 0x00, 10,
280 8, 6, 3, 22, 39, 39, 39, 40080 }, 279 8, 22, 39, 39, 39, 40080 },
281 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */ 280 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 108000, /* 108 Mb */
282 92500, 0x8b, 0x00, 11, 281 92500, 0x8b, 0x00, 11,
283 8, 10, 3, 23, 40, 40, 40, 53440 }, 282 8, 23, 40, 40, 40, 53440 },
284 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */ 283 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 162000, /* 162 Mb */
285 130300, 0x8c, 0x00, 12, 284 130300, 0x8c, 0x00, 12,
286 8, 14, 3, 24, 41, 41, 41, 80160 }, 285 8, 24, 41, 41, 41, 80160 },
287 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */ 286 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 216000, /* 216 Mb */
288 162800, 0x8d, 0x00, 13, 287 162800, 0x8d, 0x00, 13,
289 8, 20, 3, 25, 42, 42, 42, 106880 }, 288 8, 25, 42, 42, 42, 106880 },
290 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */ 289 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 243000, /* 243 Mb */
291 178200, 0x8e, 0x00, 14, 290 178200, 0x8e, 0x00, 14,
292 8, 23, 3, 26, 43, 43, 43, 120240 }, 291 8, 26, 43, 43, 43, 120240 },
293 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */ 292 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS, 270000, /* 270 Mb */
294 192100, 0x8f, 0x00, 15, 293 192100, 0x8f, 0x00, 15,
295 8, 23, 3, 27, 44, 45, 45, 133600 }, 294 8, 27, 44, 45, 45, 133600 },
296 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */ 295 { VALID_40, INVALID, WLAN_RC_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
297 207000, 0x8f, 0x00, 15, 296 207000, 0x8f, 0x00, 15,
298 8, 25, 3, 27, 44, 45, 45, 148400 }, 297 8, 27, 44, 45, 45, 148400 },
299 }, 298 },
300 50, /* probe interval */ 299 50, /* probe interval */
301 50, /* rssi reduce interval */
302 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ 300 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
303}; 301};
304 302
@@ -307,31 +305,30 @@ static const struct ath_rate_table ar5416_11a_ratetable = {
307 { 305 {
308 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 306 { VALID, VALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
309 5400, 0x0b, 0x00, (0x80|12), 307 5400, 0x0b, 0x00, (0x80|12),
310 0, 2, 1, 0, 0 }, 308 0, 0, 0 },
311 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 309 { VALID, VALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
312 7800, 0x0f, 0x00, 18, 310 7800, 0x0f, 0x00, 18,
313 0, 3, 1, 1, 0 }, 311 0, 1, 0 },
314 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 312 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
315 10000, 0x0a, 0x00, (0x80|24), 313 10000, 0x0a, 0x00, (0x80|24),
316 2, 4, 2, 2, 0 }, 314 2, 2, 0 },
317 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 315 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
318 13900, 0x0e, 0x00, 36, 316 13900, 0x0e, 0x00, 36,
319 2, 6, 2, 3, 0 }, 317 2, 3, 0 },
320 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 318 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
321 17300, 0x09, 0x00, (0x80|48), 319 17300, 0x09, 0x00, (0x80|48),
322 4, 10, 3, 4, 0 }, 320 4, 4, 0 },
323 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 321 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
324 23000, 0x0d, 0x00, 72, 322 23000, 0x0d, 0x00, 72,
325 4, 14, 3, 5, 0 }, 323 4, 5, 0 },
326 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 324 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
327 27400, 0x08, 0x00, 96, 325 27400, 0x08, 0x00, 96,
328 4, 19, 3, 6, 0 }, 326 4, 6, 0 },
329 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 327 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
330 29300, 0x0c, 0x00, 108, 328 29300, 0x0c, 0x00, 108,
331 4, 23, 3, 7, 0 }, 329 4, 7, 0 },
332 }, 330 },
333 50, /* probe interval */ 331 50, /* probe interval */
334 50, /* rssi reduce interval */
335 0, /* Phy rates allowed initially */ 332 0, /* Phy rates allowed initially */
336}; 333};
337 334
@@ -340,64 +337,42 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
340 { 337 {
341 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */ 338 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
342 900, 0x1b, 0x00, 2, 339 900, 0x1b, 0x00, 2,
343 0, 0, 1, 0, 0 }, 340 0, 0, 0 },
344 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */ 341 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
345 1900, 0x1a, 0x04, 4, 342 1900, 0x1a, 0x04, 4,
346 1, 1, 1, 1, 0 }, 343 1, 1, 0 },
347 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */ 344 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
348 4900, 0x19, 0x04, 11, 345 4900, 0x19, 0x04, 11,
349 2, 2, 2, 2, 0 }, 346 2, 2, 0 },
350 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */ 347 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
351 8100, 0x18, 0x04, 22, 348 8100, 0x18, 0x04, 22,
352 3, 3, 2, 3, 0 }, 349 3, 3, 0 },
353 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */ 350 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 6000, /* 6 Mb */
354 5400, 0x0b, 0x00, 12, 351 5400, 0x0b, 0x00, 12,
355 4, 2, 1, 4, 0 }, 352 4, 4, 0 },
356 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */ 353 { INVALID, INVALID, WLAN_RC_PHY_OFDM, 9000, /* 9 Mb */
357 7800, 0x0f, 0x00, 18, 354 7800, 0x0f, 0x00, 18,
358 4, 3, 1, 5, 0 }, 355 4, 5, 0 },
359 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */ 356 { VALID, VALID, WLAN_RC_PHY_OFDM, 12000, /* 12 Mb */
360 10000, 0x0a, 0x00, 24, 357 10000, 0x0a, 0x00, 24,
361 6, 4, 1, 6, 0 }, 358 6, 6, 0 },
362 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */ 359 { VALID, VALID, WLAN_RC_PHY_OFDM, 18000, /* 18 Mb */
363 13900, 0x0e, 0x00, 36, 360 13900, 0x0e, 0x00, 36,
364 6, 6, 2, 7, 0 }, 361 6, 7, 0 },
365 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */ 362 { VALID, VALID, WLAN_RC_PHY_OFDM, 24000, /* 24 Mb */
366 17300, 0x09, 0x00, 48, 363 17300, 0x09, 0x00, 48,
367 8, 10, 3, 8, 0 }, 364 8, 8, 0 },
368 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */ 365 { VALID, VALID, WLAN_RC_PHY_OFDM, 36000, /* 36 Mb */
369 23000, 0x0d, 0x00, 72, 366 23000, 0x0d, 0x00, 72,
370 8, 14, 3, 9, 0 }, 367 8, 9, 0 },
371 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */ 368 { VALID, VALID, WLAN_RC_PHY_OFDM, 48000, /* 48 Mb */
372 27400, 0x08, 0x00, 96, 369 27400, 0x08, 0x00, 96,
373 8, 19, 3, 10, 0 }, 370 8, 10, 0 },
374 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */ 371 { VALID, VALID, WLAN_RC_PHY_OFDM, 54000, /* 54 Mb */
375 29300, 0x0c, 0x00, 108, 372 29300, 0x0c, 0x00, 108,
376 8, 23, 3, 11, 0 }, 373 8, 11, 0 },
377 }, 374 },
378 50, /* probe interval */ 375 50, /* probe interval */
379 50, /* rssi reduce interval */
380 0, /* Phy rates allowed initially */
381};
382
383static const struct ath_rate_table ar5416_11b_ratetable = {
384 4,
385 {
386 { VALID, VALID, WLAN_RC_PHY_CCK, 1000, /* 1 Mb */
387 900, 0x1b, 0x00, (0x80|2),
388 0, 0, 1, 0, 0 },
389 { VALID, VALID, WLAN_RC_PHY_CCK, 2000, /* 2 Mb */
390 1800, 0x1a, 0x04, (0x80|4),
391 1, 1, 1, 1, 0 },
392 { VALID, VALID, WLAN_RC_PHY_CCK, 5500, /* 5.5 Mb */
393 4300, 0x19, 0x04, (0x80|11),
394 1, 2, 2, 2, 0 },
395 { VALID, VALID, WLAN_RC_PHY_CCK, 11000, /* 11 Mb */
396 7100, 0x18, 0x04, (0x80|22),
397 1, 4, 100, 3, 0 },
398 },
399 100, /* probe interval */
400 100, /* rssi reduce interval */
401 0, /* Phy rates allowed initially */ 376 0, /* Phy rates allowed initially */
402}; 377};
403 378
@@ -454,13 +429,6 @@ static inline void ath_rc_set_valid_txmask(struct ath_rate_priv *ath_rc_priv,
454 ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0; 429 ath_rc_priv->valid_rate_index[index] = valid_tx_rate ? 1 : 0;
455} 430}
456 431
457static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
458 u8 index)
459{
460 ASSERT(index <= ath_rc_priv->rate_table_size);
461 return ath_rc_priv->valid_rate_index[index];
462}
463
464static inline 432static inline
465int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table, 433int ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
466 struct ath_rate_priv *ath_rc_priv, 434 struct ath_rate_priv *ath_rc_priv,
@@ -501,9 +469,9 @@ static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
501} 469}
502 470
503static inline int 471static inline int
504ath_rc_get_nextlowervalid_txrate(const struct ath_rate_table *rate_table, 472ath_rc_get_lower_rix(const struct ath_rate_table *rate_table,
505 struct ath_rate_priv *ath_rc_priv, 473 struct ath_rate_priv *ath_rc_priv,
506 u8 cur_valid_txrate, u8 *next_idx) 474 u8 cur_valid_txrate, u8 *next_idx)
507{ 475{
508 int8_t i; 476 int8_t i;
509 477
@@ -629,52 +597,20 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
629 return hi; 597 return hi;
630} 598}
631 599
632static u8 ath_rc_ratefind_ht(struct ath_softc *sc, 600/* Finds the highest rate index we can use */
633 struct ath_rate_priv *ath_rc_priv, 601static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
634 const struct ath_rate_table *rate_table, 602 struct ath_rate_priv *ath_rc_priv,
635 int *is_probing) 603 const struct ath_rate_table *rate_table,
604 int *is_probing)
636{ 605{
637 u32 dt, best_thruput, this_thruput, now_msec; 606 u32 best_thruput, this_thruput, now_msec;
638 u8 rate, next_rate, best_rate, maxindex, minindex; 607 u8 rate, next_rate, best_rate, maxindex, minindex;
639 int8_t rssi_last, rssi_reduce = 0, index = 0; 608 int8_t index = 0;
640
641 *is_probing = 0;
642
643 rssi_last = median(ath_rc_priv->rssi_last,
644 ath_rc_priv->rssi_last_prev,
645 ath_rc_priv->rssi_last_prev2);
646
647 /*
648 * Age (reduce) last ack rssi based on how old it is.
649 * The bizarre numbers are so the delta is 160msec,
650 * meaning we divide by 16.
651 * 0msec <= dt <= 25msec: don't derate
652 * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB
653 * 185msec <= dt: derate by 10dB
654 */
655 609
656 now_msec = jiffies_to_msecs(jiffies); 610 now_msec = jiffies_to_msecs(jiffies);
657 dt = now_msec - ath_rc_priv->rssi_time; 611 *is_probing = 0;
658
659 if (dt >= 185)
660 rssi_reduce = 10;
661 else if (dt >= 25)
662 rssi_reduce = (u8)((dt - 25) >> 4);
663
664 /* Now reduce rssi_last by rssi_reduce */
665 if (rssi_last < rssi_reduce)
666 rssi_last = 0;
667 else
668 rssi_last -= rssi_reduce;
669
670 /*
671 * Now look up the rate in the rssi table and return it.
672 * If no rates match then we return 0 (lowest rate)
673 */
674
675 best_thruput = 0; 612 best_thruput = 0;
676 maxindex = ath_rc_priv->max_valid_rate-1; 613 maxindex = ath_rc_priv->max_valid_rate-1;
677
678 minindex = 0; 614 minindex = 0;
679 best_rate = minindex; 615 best_rate = minindex;
680 616
@@ -700,7 +636,7 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
700 * 10-15 and we would be worse off then staying 636 * 10-15 and we would be worse off then staying
701 * at the current rate. 637 * at the current rate.
702 */ 638 */
703 per_thres = ath_rc_priv->state[rate].per; 639 per_thres = ath_rc_priv->per[rate];
704 if (per_thres < 12) 640 if (per_thres < 12)
705 per_thres = 12; 641 per_thres = 12;
706 642
@@ -714,7 +650,6 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
714 } 650 }
715 651
716 rate = best_rate; 652 rate = best_rate;
717 ath_rc_priv->rssi_last_lookup = rssi_last;
718 653
719 /* 654 /*
720 * Must check the actual rate (ratekbps) to account for 655 * Must check the actual rate (ratekbps) to account for
@@ -741,10 +676,18 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
741 if (rate > (ath_rc_priv->rate_table_size - 1)) 676 if (rate > (ath_rc_priv->rate_table_size - 1))
742 rate = ath_rc_priv->rate_table_size - 1; 677 rate = ath_rc_priv->rate_table_size - 1;
743 678
744 ASSERT((rate_table->info[rate].valid && 679 if (rate_table->info[rate].valid &&
745 (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG)) || 680 (ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))
746 (rate_table->info[rate].valid_single_stream && 681 return rate;
747 !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG))); 682
683 if (rate_table->info[rate].valid_single_stream &&
684 !(ath_rc_priv->ht_cap & WLAN_RC_DS_FLAG));
685 return rate;
686
687 /* This should not happen */
688 WARN_ON(1);
689
690 rate = ath_rc_priv->valid_rate_index[0];
748 691
749 return rate; 692 return rate;
750} 693}
@@ -796,7 +739,6 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
796 * just CTS. Note that this is only done for OFDM/HT unicast frames. 739 * just CTS. Note that this is only done for OFDM/HT unicast frames.
797 */ 740 */
798 if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) && 741 if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
799 !(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) &&
800 (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM || 742 (rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
801 WLAN_RC_PHY_HT(rate_table->info[rix].phy))) { 743 WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
802 rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT; 744 rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
@@ -806,50 +748,37 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
806 tx_info->control.rts_cts_rate_idx = cix; 748 tx_info->control.rts_cts_rate_idx = cix;
807} 749}
808 750
809static u8 ath_rc_rate_getidx(struct ath_softc *sc, 751static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
810 struct ath_rate_priv *ath_rc_priv, 752 struct ieee80211_tx_rate_control *txrc)
811 const struct ath_rate_table *rate_table,
812 u8 rix, u16 stepdown,
813 u16 min_rate)
814{
815 u32 j;
816 u8 nextindex = 0;
817
818 if (min_rate) {
819 for (j = RATE_TABLE_SIZE; j > 0; j--) {
820 if (ath_rc_get_nextlowervalid_txrate(rate_table,
821 ath_rc_priv, rix, &nextindex))
822 rix = nextindex;
823 else
824 break;
825 }
826 } else {
827 for (j = stepdown; j > 0; j--) {
828 if (ath_rc_get_nextlowervalid_txrate(rate_table,
829 ath_rc_priv, rix, &nextindex))
830 rix = nextindex;
831 else
832 break;
833 }
834 }
835 return rix;
836}
837
838static void ath_rc_ratefind(struct ath_softc *sc,
839 struct ath_rate_priv *ath_rc_priv,
840 struct ieee80211_tx_rate_control *txrc)
841{ 753{
754 struct ath_softc *sc = priv;
755 struct ath_rate_priv *ath_rc_priv = priv_sta;
842 const struct ath_rate_table *rate_table; 756 const struct ath_rate_table *rate_table;
843 struct sk_buff *skb = txrc->skb; 757 struct sk_buff *skb = txrc->skb;
844 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb); 758 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
845 struct ieee80211_tx_rate *rates = tx_info->control.rates; 759 struct ieee80211_tx_rate *rates = tx_info->control.rates;
846 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 760 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
847 __le16 fc = hdr->frame_control; 761 __le16 fc = hdr->frame_control;
848 u8 try_per_rate = 0, i = 0, rix, nrix; 762 u8 try_per_rate, i = 0, rix, nrix;
849 int is_probe = 0; 763 int is_probe = 0;
850 764
765 if (rate_control_send_low(sta, priv_sta, txrc))
766 return;
767
768 /*
769 * For Multi Rate Retry we use a different number of
770 * retry attempt counts. This ends up looking like this:
771 *
772 * MRR[0] = 2
773 * MRR[1] = 2
774 * MRR[2] = 2
775 * MRR[3] = 4
776 *
777 */
778 try_per_rate = sc->hw->max_rate_tries;
779
851 rate_table = sc->cur_rate_table; 780 rate_table = sc->cur_rate_table;
852 rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table, &is_probe); 781 rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
853 nrix = rix; 782 nrix = rix;
854 783
855 if (is_probe) { 784 if (is_probe) {
@@ -858,18 +787,15 @@ static void ath_rc_ratefind(struct ath_softc *sc,
858 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 787 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
859 1, nrix, 0); 788 1, nrix, 0);
860 789
861 try_per_rate = (ATH_11N_TXMAXTRY/4);
862 /* Get the next tried/allowed rate. No RTS for the next series 790 /* Get the next tried/allowed rate. No RTS for the next series
863 * after the probe rate 791 * after the probe rate
864 */ 792 */
865 nrix = ath_rc_rate_getidx(sc, ath_rc_priv, 793 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
866 rate_table, nrix, 1, 0);
867 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 794 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
868 try_per_rate, nrix, 0); 795 try_per_rate, nrix, 0);
869 796
870 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; 797 tx_info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE;
871 } else { 798 } else {
872 try_per_rate = (ATH_11N_TXMAXTRY/4);
873 /* Set the choosen rate. No RTS for first series entry. */ 799 /* Set the choosen rate. No RTS for first series entry. */
874 ath_rc_rate_set_series(rate_table, &rates[i++], txrc, 800 ath_rc_rate_set_series(rate_table, &rates[i++], txrc,
875 try_per_rate, nrix, 0); 801 try_per_rate, nrix, 0);
@@ -877,18 +803,14 @@ static void ath_rc_ratefind(struct ath_softc *sc,
877 803
878 /* Fill in the other rates for multirate retry */ 804 /* Fill in the other rates for multirate retry */
879 for ( ; i < 4; i++) { 805 for ( ; i < 4; i++) {
880 u8 try_num; 806 /* Use twice the number of tries for the last MRR segment. */
881 u8 min_rate; 807 if (i + 1 == 4)
882 808 try_per_rate = 4;
883 try_num = ((i + 1) == 4) ?
884 ATH_11N_TXMAXTRY - (try_per_rate * i) : try_per_rate ;
885 min_rate = (((i + 1) == 4) && 0);
886 809
887 nrix = ath_rc_rate_getidx(sc, ath_rc_priv, 810 ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &nrix);
888 rate_table, nrix, 1, min_rate);
889 /* All other rates in the series have RTS enabled */ 811 /* All other rates in the series have RTS enabled */
890 ath_rc_rate_set_series(rate_table, &rates[i], txrc, 812 ath_rc_rate_set_series(rate_table, &rates[i], txrc,
891 try_num, nrix, 1); 813 try_per_rate, nrix, 1);
892 } 814 }
893 815
894 /* 816 /*
@@ -925,9 +847,8 @@ static void ath_rc_ratefind(struct ath_softc *sc,
925 * 847 *
926 * FIXME: Fix duration 848 * FIXME: Fix duration
927 */ 849 */
928 if (!(tx_info->flags & IEEE80211_TX_CTL_NO_ACK) && 850 if (ieee80211_has_morefrags(fc) ||
929 (ieee80211_has_morefrags(fc) || 851 (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
930 (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG))) {
931 rates[1].count = rates[2].count = rates[3].count = 0; 852 rates[1].count = rates[2].count = rates[3].count = 0;
932 rates[1].idx = rates[2].idx = rates[3].idx = 0; 853 rates[1].idx = rates[2].idx = rates[3].idx = 0;
933 rates[0].count = ATH_TXMAXTRY; 854 rates[0].count = ATH_TXMAXTRY;
@@ -960,13 +881,13 @@ static bool ath_rc_update_per(struct ath_softc *sc,
960 100 * 9 / 10 881 100 * 9 / 10
961 }; 882 };
962 883
963 last_per = ath_rc_priv->state[tx_rate].per; 884 last_per = ath_rc_priv->per[tx_rate];
964 885
965 if (xretries) { 886 if (xretries) {
966 if (xretries == 1) { 887 if (xretries == 1) {
967 ath_rc_priv->state[tx_rate].per += 30; 888 ath_rc_priv->per[tx_rate] += 30;
968 if (ath_rc_priv->state[tx_rate].per > 100) 889 if (ath_rc_priv->per[tx_rate] > 100)
969 ath_rc_priv->state[tx_rate].per = 100; 890 ath_rc_priv->per[tx_rate] = 100;
970 } else { 891 } else {
971 /* xretries == 2 */ 892 /* xretries == 2 */
972 count = ARRAY_SIZE(nretry_to_per_lookup); 893 count = ARRAY_SIZE(nretry_to_per_lookup);
@@ -974,7 +895,7 @@ static bool ath_rc_update_per(struct ath_softc *sc,
974 retries = count - 1; 895 retries = count - 1;
975 896
976 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */ 897 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
977 ath_rc_priv->state[tx_rate].per = 898 ath_rc_priv->per[tx_rate] =
978 (u8)(last_per - (last_per >> 3) + (100 >> 3)); 899 (u8)(last_per - (last_per >> 3) + (100 >> 3));
979 } 900 }
980 901
@@ -1010,18 +931,14 @@ static bool ath_rc_update_per(struct ath_softc *sc,
1010 n_frames = tx_info_priv->n_frames * (retries + 1); 931 n_frames = tx_info_priv->n_frames * (retries + 1);
1011 cur_per = (100 * n_bad_frames / n_frames) >> 3; 932 cur_per = (100 * n_bad_frames / n_frames) >> 3;
1012 new_per = (u8)(last_per - (last_per >> 3) + cur_per); 933 new_per = (u8)(last_per - (last_per >> 3) + cur_per);
1013 ath_rc_priv->state[tx_rate].per = new_per; 934 ath_rc_priv->per[tx_rate] = new_per;
1014 } 935 }
1015 } else { 936 } else {
1016 ath_rc_priv->state[tx_rate].per = 937 ath_rc_priv->per[tx_rate] =
1017 (u8)(last_per - (last_per >> 3) + 938 (u8)(last_per - (last_per >> 3) +
1018 (nretry_to_per_lookup[retries] >> 3)); 939 (nretry_to_per_lookup[retries] >> 3));
1019 } 940 }
1020 941
1021 ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
1022 ath_rc_priv->rssi_last_prev = ath_rc_priv->rssi_last;
1023 ath_rc_priv->rssi_last = tx_info_priv->tx.ts_rssi;
1024 ath_rc_priv->rssi_time = now_msec;
1025 942
1026 /* 943 /*
1027 * If we got at most one retry then increase the max rate if 944 * If we got at most one retry then increase the max rate if
@@ -1045,8 +962,8 @@ static bool ath_rc_update_per(struct ath_softc *sc,
1045 ath_rc_priv->probe_rate; 962 ath_rc_priv->probe_rate;
1046 probe_rate = ath_rc_priv->probe_rate; 963 probe_rate = ath_rc_priv->probe_rate;
1047 964
1048 if (ath_rc_priv->state[probe_rate].per > 30) 965 if (ath_rc_priv->per[probe_rate] > 30)
1049 ath_rc_priv->state[probe_rate].per = 20; 966 ath_rc_priv->per[probe_rate] = 20;
1050 967
1051 ath_rc_priv->probe_rate = 0; 968 ath_rc_priv->probe_rate = 0;
1052 969
@@ -1065,18 +982,9 @@ static bool ath_rc_update_per(struct ath_softc *sc,
1065 /* 982 /*
1066 * Don't update anything. We don't know if 983 * Don't update anything. We don't know if
1067 * this was because of collisions or poor signal. 984 * this was because of collisions or poor signal.
1068 *
1069 * Later: if rssi_ack is close to
1070 * ath_rc_priv->state[txRate].rssi_thres and we see lots
1071 * of retries, then we could increase
1072 * ath_rc_priv->state[txRate].rssi_thres.
1073 */ 985 */
1074 ath_rc_priv->hw_maxretry_pktcnt = 0; 986 ath_rc_priv->hw_maxretry_pktcnt = 0;
1075 } else { 987 } else {
1076 int32_t rssi_ackAvg;
1077 int8_t rssi_thres;
1078 int8_t rssi_ack_vmin;
1079
1080 /* 988 /*
1081 * It worked with no retries. First ignore bogus (small) 989 * It worked with no retries. First ignore bogus (small)
1082 * rssi_ack values. 990 * rssi_ack values.
@@ -1086,43 +994,9 @@ static bool ath_rc_update_per(struct ath_softc *sc,
1086 ath_rc_priv->hw_maxretry_pktcnt++; 994 ath_rc_priv->hw_maxretry_pktcnt++;
1087 } 995 }
1088 996
1089 if (tx_info_priv->tx.ts_rssi <
1090 rate_table->info[tx_rate].rssi_ack_validmin)
1091 goto exit;
1092
1093 /* Average the rssi */
1094 if (tx_rate != ath_rc_priv->rssi_sum_rate) {
1095 ath_rc_priv->rssi_sum_rate = tx_rate;
1096 ath_rc_priv->rssi_sum =
1097 ath_rc_priv->rssi_sum_cnt = 0;
1098 }
1099
1100 ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
1101 ath_rc_priv->rssi_sum_cnt++;
1102
1103 if (ath_rc_priv->rssi_sum_cnt < 4)
1104 goto exit;
1105
1106 rssi_ackAvg =
1107 (ath_rc_priv->rssi_sum + 2) / 4;
1108 rssi_thres =
1109 ath_rc_priv->state[tx_rate].rssi_thres;
1110 rssi_ack_vmin =
1111 rate_table->info[tx_rate].rssi_ack_validmin;
1112
1113 ath_rc_priv->rssi_sum =
1114 ath_rc_priv->rssi_sum_cnt = 0;
1115
1116 /* Now reduce the current rssi threshold */
1117 if ((rssi_ackAvg < rssi_thres + 2) &&
1118 (rssi_thres > rssi_ack_vmin)) {
1119 ath_rc_priv->state[tx_rate].rssi_thres--;
1120 }
1121
1122 state_change = true;
1123 } 997 }
1124 } 998 }
1125exit: 999
1126 return state_change; 1000 return state_change;
1127} 1001}
1128 1002
@@ -1134,11 +1008,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1134 struct ath_tx_info_priv *tx_info_priv, 1008 struct ath_tx_info_priv *tx_info_priv,
1135 int tx_rate, int xretries, int retries) 1009 int tx_rate, int xretries, int retries)
1136{ 1010{
1137#define CHK_RSSI(rate) \
1138 ((ath_rc_priv->state[(rate)].rssi_thres + \
1139 rate_table->info[(rate)].rssi_ack_deltamin) > \
1140 ath_rc_priv->state[(rate)+1].rssi_thres)
1141
1142 u32 now_msec = jiffies_to_msecs(jiffies); 1011 u32 now_msec = jiffies_to_msecs(jiffies);
1143 int rate; 1012 int rate;
1144 u8 last_per; 1013 u8 last_per;
@@ -1149,14 +1018,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1149 if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt)) 1018 if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
1150 return; 1019 return;
1151 1020
1152 /* To compensate for some imbalance between ctrl and ext. channel */ 1021 last_per = ath_rc_priv->per[tx_rate];
1153
1154 if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
1155 tx_info_priv->tx.ts_rssi =
1156 tx_info_priv->tx.ts_rssi < 3 ? 0 :
1157 tx_info_priv->tx.ts_rssi - 3;
1158
1159 last_per = ath_rc_priv->state[tx_rate].per;
1160 1022
1161 /* Update PER first */ 1023 /* Update PER first */
1162 state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv, 1024 state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
@@ -1167,114 +1029,55 @@ static void ath_rc_update_ht(struct ath_softc *sc,
1167 * If this rate looks bad (high PER) then stop using it for 1029 * If this rate looks bad (high PER) then stop using it for
1168 * a while (except if we are probing). 1030 * a while (except if we are probing).
1169 */ 1031 */
1170 if (ath_rc_priv->state[tx_rate].per >= 55 && tx_rate > 0 && 1032 if (ath_rc_priv->per[tx_rate] >= 55 && tx_rate > 0 &&
1171 rate_table->info[tx_rate].ratekbps <= 1033 rate_table->info[tx_rate].ratekbps <=
1172 rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) { 1034 rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
1173 ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv, 1035 ath_rc_get_lower_rix(rate_table, ath_rc_priv,
1174 (u8)tx_rate, &ath_rc_priv->rate_max_phy); 1036 (u8)tx_rate, &ath_rc_priv->rate_max_phy);
1175 1037
1176 /* Don't probe for a little while. */ 1038 /* Don't probe for a little while. */
1177 ath_rc_priv->probe_time = now_msec; 1039 ath_rc_priv->probe_time = now_msec;
1178 } 1040 }
1179 1041
1180 if (state_change) {
1181 /*
1182 * Make sure the rates above this have higher rssi thresholds.
1183 * (Note: Monotonicity is kept within the OFDM rates and
1184 * within the CCK rates. However, no adjustment is
1185 * made to keep the rssi thresholds monotonically
1186 * increasing between the CCK and OFDM rates.)
1187 */
1188 for (rate = tx_rate; rate < size - 1; rate++) {
1189 if (rate_table->info[rate+1].phy !=
1190 rate_table->info[tx_rate].phy)
1191 break;
1192
1193 if (CHK_RSSI(rate)) {
1194 ath_rc_priv->state[rate+1].rssi_thres =
1195 ath_rc_priv->state[rate].rssi_thres +
1196 rate_table->info[rate].rssi_ack_deltamin;
1197 }
1198 }
1199
1200 /* Make sure the rates below this have lower rssi thresholds. */
1201 for (rate = tx_rate - 1; rate >= 0; rate--) {
1202 if (rate_table->info[rate].phy !=
1203 rate_table->info[tx_rate].phy)
1204 break;
1205
1206 if (CHK_RSSI(rate)) {
1207 if (ath_rc_priv->state[rate+1].rssi_thres <
1208 rate_table->info[rate].rssi_ack_deltamin)
1209 ath_rc_priv->state[rate].rssi_thres = 0;
1210 else {
1211 ath_rc_priv->state[rate].rssi_thres =
1212 ath_rc_priv->state[rate+1].rssi_thres -
1213 rate_table->info[rate].rssi_ack_deltamin;
1214 }
1215
1216 if (ath_rc_priv->state[rate].rssi_thres <
1217 rate_table->info[rate].rssi_ack_validmin) {
1218 ath_rc_priv->state[rate].rssi_thres =
1219 rate_table->info[rate].rssi_ack_validmin;
1220 }
1221 }
1222 }
1223 }
1224
1225 /* Make sure the rates below this have lower PER */ 1042 /* Make sure the rates below this have lower PER */
1226 /* Monotonicity is kept only for rates below the current rate. */ 1043 /* Monotonicity is kept only for rates below the current rate. */
1227 if (ath_rc_priv->state[tx_rate].per < last_per) { 1044 if (ath_rc_priv->per[tx_rate] < last_per) {
1228 for (rate = tx_rate - 1; rate >= 0; rate--) { 1045 for (rate = tx_rate - 1; rate >= 0; rate--) {
1229 if (rate_table->info[rate].phy != 1046 if (rate_table->info[rate].phy !=
1230 rate_table->info[tx_rate].phy) 1047 rate_table->info[tx_rate].phy)
1231 break; 1048 break;
1232 1049
1233 if (ath_rc_priv->state[rate].per > 1050 if (ath_rc_priv->per[rate] >
1234 ath_rc_priv->state[rate+1].per) { 1051 ath_rc_priv->per[rate+1]) {
1235 ath_rc_priv->state[rate].per = 1052 ath_rc_priv->per[rate] =
1236 ath_rc_priv->state[rate+1].per; 1053 ath_rc_priv->per[rate+1];
1237 } 1054 }
1238 } 1055 }
1239 } 1056 }
1240 1057
1241 /* Maintain monotonicity for rates above the current rate */ 1058 /* Maintain monotonicity for rates above the current rate */
1242 for (rate = tx_rate; rate < size - 1; rate++) { 1059 for (rate = tx_rate; rate < size - 1; rate++) {
1243 if (ath_rc_priv->state[rate+1].per < 1060 if (ath_rc_priv->per[rate+1] <
1244 ath_rc_priv->state[rate].per) 1061 ath_rc_priv->per[rate])
1245 ath_rc_priv->state[rate+1].per = 1062 ath_rc_priv->per[rate+1] =
1246 ath_rc_priv->state[rate].per; 1063 ath_rc_priv->per[rate];
1247 }
1248
1249 /* Every so often, we reduce the thresholds and
1250 * PER (different for CCK and OFDM). */
1251 if (now_msec - ath_rc_priv->rssi_down_time >=
1252 rate_table->rssi_reduce_interval) {
1253
1254 for (rate = 0; rate < size; rate++) {
1255 if (ath_rc_priv->state[rate].rssi_thres >
1256 rate_table->info[rate].rssi_ack_validmin)
1257 ath_rc_priv->state[rate].rssi_thres -= 1;
1258 }
1259 ath_rc_priv->rssi_down_time = now_msec;
1260 } 1064 }
1261 1065
1262 /* Every so often, we reduce the thresholds 1066 /* Every so often, we reduce the thresholds
1263 * and PER (different for CCK and OFDM). */ 1067 * and PER (different for CCK and OFDM). */
1264 if (now_msec - ath_rc_priv->per_down_time >= 1068 if (now_msec - ath_rc_priv->per_down_time >=
1265 rate_table->rssi_reduce_interval) { 1069 rate_table->probe_interval) {
1266 for (rate = 0; rate < size; rate++) { 1070 for (rate = 0; rate < size; rate++) {
1267 ath_rc_priv->state[rate].per = 1071 ath_rc_priv->per[rate] =
1268 7 * ath_rc_priv->state[rate].per / 8; 1072 7 * ath_rc_priv->per[rate] / 8;
1269 } 1073 }
1270 1074
1271 ath_rc_priv->per_down_time = now_msec; 1075 ath_rc_priv->per_down_time = now_msec;
1272 } 1076 }
1273 1077
1274 ath_debug_stat_retries(sc, tx_rate, xretries, retries, 1078 ath_debug_stat_retries(sc, tx_rate, xretries, retries,
1275 ath_rc_priv->state[tx_rate].per); 1079 ath_rc_priv->per[tx_rate]);
1276 1080
1277#undef CHK_RSSI
1278} 1081}
1279 1082
1280static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table, 1083static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
@@ -1410,9 +1213,7 @@ static void ath_rc_init(struct ath_softc *sc,
1410 1213
1411 /* Initialize thresholds according to the global rate table */ 1214 /* Initialize thresholds according to the global rate table */
1412 for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) { 1215 for (i = 0 ; i < ath_rc_priv->rate_table_size; i++) {
1413 ath_rc_priv->state[i].rssi_thres = 1216 ath_rc_priv->per[i] = 0;
1414 rate_table->info[i].rssi_ack_validmin;
1415 ath_rc_priv->state[i].per = 0;
1416 } 1217 }
1417 1218
1418 /* Determine the valid rates */ 1219 /* Determine the valid rates */
@@ -1521,7 +1322,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1521 /* 1322 /*
1522 * If underrun error is seen assume it as an excessive retry only 1323 * If underrun error is seen assume it as an excessive retry only
1523 * if prefetch trigger level have reached the max (0x3f for 5416) 1324 * if prefetch trigger level have reached the max (0x3f for 5416)
1524 * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY 1325 * Adjust the long retry as if the frame was tried hw->max_rate_tries
1525 * times. This affects how ratectrl updates PER for the failed rate. 1326 * times. This affects how ratectrl updates PER for the failed rate.
1526 */ 1327 */
1527 if (tx_info_priv->tx.ts_flags & 1328 if (tx_info_priv->tx.ts_flags &
@@ -1536,7 +1337,7 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
1536 tx_status = 1; 1337 tx_status = 1;
1537 1338
1538 ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status, 1339 ath_rc_tx_status(sc, ath_rc_priv, tx_info, final_ts_idx, tx_status,
1539 (is_underrun) ? ATH_11N_TXMAXTRY : 1340 (is_underrun) ? sc->hw->max_rate_tries :
1540 tx_info_priv->tx.ts_longretry); 1341 tx_info_priv->tx.ts_longretry);
1541 1342
1542 /* Check if aggregation has to be enabled for this tid */ 1343 /* Check if aggregation has to be enabled for this tid */
@@ -1560,31 +1361,6 @@ exit:
1560 kfree(tx_info_priv); 1361 kfree(tx_info_priv);
1561} 1362}
1562 1363
1563static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
1564 struct ieee80211_tx_rate_control *txrc)
1565{
1566 struct ieee80211_supported_band *sband = txrc->sband;
1567 struct sk_buff *skb = txrc->skb;
1568 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1569 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1570 struct ath_softc *sc = priv;
1571 struct ath_rate_priv *ath_rc_priv = priv_sta;
1572 __le16 fc = hdr->frame_control;
1573
1574 /* lowest rate for management and NO_ACK frames */
1575 if (!ieee80211_is_data(fc) ||
1576 tx_info->flags & IEEE80211_TX_CTL_NO_ACK || !sta) {
1577 tx_info->control.rates[0].idx = rate_lowest_index(sband, sta);
1578 tx_info->control.rates[0].count =
1579 (tx_info->flags & IEEE80211_TX_CTL_NO_ACK) ?
1580 1 : ATH_MGT_TXMAXTRY;
1581 return;
1582 }
1583
1584 /* Find tx rate for unicast frames */
1585 ath_rc_ratefind(sc, ath_rc_priv, txrc);
1586}
1587
1588static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband, 1364static void ath_rate_init(void *priv, struct ieee80211_supported_band *sband,
1589 struct ieee80211_sta *sta, void *priv_sta) 1365 struct ieee80211_sta *sta, void *priv_sta)
1590{ 1366{
@@ -1697,7 +1473,6 @@ static void *ath_rate_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp
1697 return NULL; 1473 return NULL;
1698 } 1474 }
1699 1475
1700 rate_priv->rssi_down_time = jiffies_to_msecs(jiffies);
1701 rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max; 1476 rate_priv->tx_triglevel_max = sc->sc_ah->caps.tx_triglevel_max;
1702 1477
1703 return rate_priv; 1478 return rate_priv;
@@ -1725,8 +1500,6 @@ static struct rate_control_ops ath_rate_ops = {
1725 1500
1726void ath_rate_attach(struct ath_softc *sc) 1501void ath_rate_attach(struct ath_softc *sc)
1727{ 1502{
1728 sc->hw_rate_table[ATH9K_MODE_11B] =
1729 &ar5416_11b_ratetable;
1730 sc->hw_rate_table[ATH9K_MODE_11A] = 1503 sc->hw_rate_table[ATH9K_MODE_11A] =
1731 &ar5416_11a_ratetable; 1504 &ar5416_11a_ratetable;
1732 sc->hw_rate_table[ATH9K_MODE_11G] = 1505 sc->hw_rate_table[ATH9K_MODE_11G] =
diff --git a/drivers/net/wireless/ath/ath9k/rc.h b/drivers/net/wireless/ath/ath9k/rc.h
index e3abd76103fd..fa21a628ddd0 100644
--- a/drivers/net/wireless/ath/ath9k/rc.h
+++ b/drivers/net/wireless/ath/ath9k/rc.h
@@ -112,8 +112,6 @@ struct ath_rate_table {
112 u8 short_preamble; 112 u8 short_preamble;
113 u8 dot11rate; 113 u8 dot11rate;
114 u8 ctrl_rate; 114 u8 ctrl_rate;
115 int8_t rssi_ack_validmin;
116 int8_t rssi_ack_deltamin;
117 u8 base_index; 115 u8 base_index;
118 u8 cw40index; 116 u8 cw40index;
119 u8 sgi_index; 117 u8 sgi_index;
@@ -121,15 +119,9 @@ struct ath_rate_table {
121 u32 max_4ms_framelen; 119 u32 max_4ms_framelen;
122 } info[RATE_TABLE_SIZE]; 120 } info[RATE_TABLE_SIZE];
123 u32 probe_interval; 121 u32 probe_interval;
124 u32 rssi_reduce_interval;
125 u8 initial_ratemax; 122 u8 initial_ratemax;
126}; 123};
127 124
128struct ath_tx_ratectrl_state {
129 int8_t rssi_thres; /* required rssi for this rate (dB) */
130 u8 per; /* recent estimate of packet error rate (%) */
131};
132
133struct ath_rateset { 125struct ath_rateset {
134 u8 rs_nrates; 126 u8 rs_nrates;
135 u8 rs_rates[ATH_RATE_MAX]; 127 u8 rs_rates[ATH_RATE_MAX];
@@ -138,22 +130,14 @@ struct ath_rateset {
138/** 130/**
139 * struct ath_rate_priv - Rate Control priv data 131 * struct ath_rate_priv - Rate Control priv data
140 * @state: RC state 132 * @state: RC state
141 * @rssi_last: last ACK rssi
142 * @rssi_last_lookup: last ACK rssi used for lookup
143 * @rssi_last_prev: previous last ACK rssi
144 * @rssi_last_prev2: 2nd previous last ACK rssi
145 * @rssi_sum_cnt: count of rssi_sum for averaging
146 * @rssi_sum_rate: rate that we are averaging
147 * @rssi_sum: running sum of rssi for averaging
148 * @probe_rate: rate we are probing at 133 * @probe_rate: rate we are probing at
149 * @rssi_time: msec timestamp for last ack rssi
150 * @rssi_down_time: msec timestamp for last down step
151 * @probe_time: msec timestamp for last probe 134 * @probe_time: msec timestamp for last probe
152 * @hw_maxretry_pktcnt: num of packets since we got HW max retry error 135 * @hw_maxretry_pktcnt: num of packets since we got HW max retry error
153 * @max_valid_rate: maximum number of valid rate 136 * @max_valid_rate: maximum number of valid rate
154 * @per_down_time: msec timestamp for last PER down step 137 * @per_down_time: msec timestamp for last PER down step
155 * @valid_phy_ratecnt: valid rate count 138 * @valid_phy_ratecnt: valid rate count
156 * @rate_max_phy: phy index for the max rate 139 * @rate_max_phy: phy index for the max rate
140 * @per: PER for every valid rate in %
157 * @probe_interval: interval for ratectrl to probe for other rates 141 * @probe_interval: interval for ratectrl to probe for other rates
158 * @prev_data_rix: rate idx of last data frame 142 * @prev_data_rix: rate idx of last data frame
159 * @ht_cap: HT capabilities 143 * @ht_cap: HT capabilities
@@ -161,13 +145,6 @@ struct ath_rateset {
161 * @neg_ht_rates: Negotiated HT rates 145 * @neg_ht_rates: Negotiated HT rates
162 */ 146 */
163struct ath_rate_priv { 147struct ath_rate_priv {
164 int8_t rssi_last;
165 int8_t rssi_last_lookup;
166 int8_t rssi_last_prev;
167 int8_t rssi_last_prev2;
168 int32_t rssi_sum_cnt;
169 int32_t rssi_sum_rate;
170 int32_t rssi_sum;
171 u8 rate_table_size; 148 u8 rate_table_size;
172 u8 probe_rate; 149 u8 probe_rate;
173 u8 hw_maxretry_pktcnt; 150 u8 hw_maxretry_pktcnt;
@@ -177,14 +154,12 @@ struct ath_rate_priv {
177 u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; 154 u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX];
178 u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE]; 155 u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][RATE_TABLE_SIZE];
179 u8 rate_max_phy; 156 u8 rate_max_phy;
180 u32 rssi_time; 157 u8 per[RATE_TABLE_SIZE];
181 u32 rssi_down_time;
182 u32 probe_time; 158 u32 probe_time;
183 u32 per_down_time; 159 u32 per_down_time;
184 u32 probe_interval; 160 u32 probe_interval;
185 u32 prev_data_rix; 161 u32 prev_data_rix;
186 u32 tx_triglevel_max; 162 u32 tx_triglevel_max;
187 struct ath_tx_ratectrl_state state[RATE_TABLE_SIZE];
188 struct ath_rateset neg_rates; 163 struct ath_rateset neg_rates;
189 struct ath_rateset neg_ht_rates; 164 struct ath_rateset neg_ht_rates;
190 struct ath_rate_softc *asc; 165 struct ath_rate_softc *asc;
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index b3da81db453b..61edfab20ffc 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -145,6 +145,10 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
145 u8 ratecode; 145 u8 ratecode;
146 __le16 fc; 146 __le16 fc;
147 struct ieee80211_hw *hw; 147 struct ieee80211_hw *hw;
148 struct ieee80211_sta *sta;
149 struct ath_node *an;
150 int last_rssi = ATH_RSSI_DUMMY_MARKER;
151
148 152
149 hdr = (struct ieee80211_hdr *)skb->data; 153 hdr = (struct ieee80211_hdr *)skb->data;
150 fc = hdr->frame_control; 154 fc = hdr->frame_control;
@@ -229,11 +233,30 @@ static int ath_rx_prepare(struct sk_buff *skb, struct ath_desc *ds,
229 } 233 }
230 } 234 }
231 235
236 rcu_read_lock();
237 sta = ieee80211_find_sta(sc->hw, hdr->addr2);
238 if (sta) {
239 an = (struct ath_node *) sta->drv_priv;
240 if (ds->ds_rxstat.rs_rssi != ATH9K_RSSI_BAD &&
241 !ds->ds_rxstat.rs_moreaggr)
242 ATH_RSSI_LPF(an->last_rssi, ds->ds_rxstat.rs_rssi);
243 last_rssi = an->last_rssi;
244 }
245 rcu_read_unlock();
246
247 if (likely(last_rssi != ATH_RSSI_DUMMY_MARKER))
248 ds->ds_rxstat.rs_rssi = ATH_EP_RND(last_rssi,
249 ATH_RSSI_EP_MULTIPLIER);
250 if (ds->ds_rxstat.rs_rssi < 0)
251 ds->ds_rxstat.rs_rssi = 0;
252 else if (ds->ds_rxstat.rs_rssi > 127)
253 ds->ds_rxstat.rs_rssi = 127;
254
232 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp); 255 rx_status->mactime = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
233 rx_status->band = hw->conf.channel->band; 256 rx_status->band = hw->conf.channel->band;
234 rx_status->freq = hw->conf.channel->center_freq; 257 rx_status->freq = hw->conf.channel->center_freq;
235 rx_status->noise = sc->ani.noise_floor; 258 rx_status->noise = sc->ani.noise_floor;
236 rx_status->signal = rx_status->noise + ds->ds_rxstat.rs_rssi; 259 rx_status->signal = ATH_DEFAULT_NOISE_FLOOR + ds->ds_rxstat.rs_rssi;
237 rx_status->antenna = ds->ds_rxstat.rs_antenna; 260 rx_status->antenna = ds->ds_rxstat.rs_antenna;
238 261
239 /* 262 /*
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index 52605246679f..8302aeb62e5d 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -574,6 +574,7 @@
574 574
575#define AR_D_GBL_IFS_SIFS 0x1030 575#define AR_D_GBL_IFS_SIFS 0x1030
576#define AR_D_GBL_IFS_SIFS_M 0x0000FFFF 576#define AR_D_GBL_IFS_SIFS_M 0x0000FFFF
577#define AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR 0x000003AB
577#define AR_D_GBL_IFS_SIFS_RESV0 0xFFFFFFFF 578#define AR_D_GBL_IFS_SIFS_RESV0 0xFFFFFFFF
578 579
579#define AR_D_TXBLK_BASE 0x1038 580#define AR_D_TXBLK_BASE 0x1038
@@ -589,10 +590,12 @@
589#define AR_D_GBL_IFS_SLOT 0x1070 590#define AR_D_GBL_IFS_SLOT 0x1070
590#define AR_D_GBL_IFS_SLOT_M 0x0000FFFF 591#define AR_D_GBL_IFS_SLOT_M 0x0000FFFF
591#define AR_D_GBL_IFS_SLOT_RESV0 0xFFFF0000 592#define AR_D_GBL_IFS_SLOT_RESV0 0xFFFF0000
593#define AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR 0x00000420
592 594
593#define AR_D_GBL_IFS_EIFS 0x10b0 595#define AR_D_GBL_IFS_EIFS 0x10b0
594#define AR_D_GBL_IFS_EIFS_M 0x0000FFFF 596#define AR_D_GBL_IFS_EIFS_M 0x0000FFFF
595#define AR_D_GBL_IFS_EIFS_RESV0 0xFFFF0000 597#define AR_D_GBL_IFS_EIFS_RESV0 0xFFFF0000
598#define AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR 0x0000A5EB
596 599
597#define AR_D_GBL_IFS_MISC 0x10f0 600#define AR_D_GBL_IFS_MISC 0x10f0
598#define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL 0x00000007 601#define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL 0x00000007
@@ -738,6 +741,9 @@
738#define AR_SREV_REVISION_9285_10 0 741#define AR_SREV_REVISION_9285_10 0
739#define AR_SREV_REVISION_9285_11 1 742#define AR_SREV_REVISION_9285_11 1
740#define AR_SREV_REVISION_9285_12 2 743#define AR_SREV_REVISION_9285_12 2
744#define AR_SREV_VERSION_9287 0x180
745#define AR_SREV_REVISION_9287_10 0
746#define AR_SREV_REVISION_9287_11 1
741 747
742#define AR_SREV_5416(_ah) \ 748#define AR_SREV_5416(_ah) \
743 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \ 749 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_5416_PCI) || \
@@ -794,6 +800,21 @@
794 (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \ 800 (AR_SREV_9285(ah) && ((_ah)->hw_version.macRev >= \
795 AR_SREV_REVISION_9285_12))) 801 AR_SREV_REVISION_9285_12)))
796 802
803#define AR_SREV_9287(_ah) \
804 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287))
805#define AR_SREV_9287_10_OR_LATER(_ah) \
806 (((_ah)->hw_version.macVersion >= AR_SREV_VERSION_9287))
807#define AR_SREV_9287_10(_ah) \
808 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
809 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_10))
810#define AR_SREV_9287_11(_ah) \
811 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
812 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9287_11))
813#define AR_SREV_9287_11_OR_LATER(_ah) \
814 (((_ah)->hw_version.macVersion > AR_SREV_VERSION_9287) || \
815 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9287) && \
816 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9287_11)))
817
797#define AR_RADIO_SREV_MAJOR 0xf0 818#define AR_RADIO_SREV_MAJOR 0xf0
798#define AR_RAD5133_SREV_MAJOR 0xc0 819#define AR_RAD5133_SREV_MAJOR 0xc0
799#define AR_RAD2133_SREV_MAJOR 0xd0 820#define AR_RAD2133_SREV_MAJOR 0xd0
@@ -809,6 +830,9 @@
809#define AR_AHB_PAGE_SIZE_1K 0x00000000 830#define AR_AHB_PAGE_SIZE_1K 0x00000000
810#define AR_AHB_PAGE_SIZE_2K 0x00000008 831#define AR_AHB_PAGE_SIZE_2K 0x00000008
811#define AR_AHB_PAGE_SIZE_4K 0x00000010 832#define AR_AHB_PAGE_SIZE_4K 0x00000010
833#define AR_AHB_CUSTOM_BURST_EN 0x000000C0
834#define AR_AHB_CUSTOM_BURST_EN_S 6
835#define AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL 3
812 836
813#define AR_INTR_RTC_IRQ 0x00000001 837#define AR_INTR_RTC_IRQ 0x00000001
814#define AR_INTR_MAC_IRQ 0x00000002 838#define AR_INTR_MAC_IRQ 0x00000002
@@ -885,6 +909,7 @@ enum {
885#define AR_NUM_GPIO 14 909#define AR_NUM_GPIO 14
886#define AR928X_NUM_GPIO 10 910#define AR928X_NUM_GPIO 10
887#define AR9285_NUM_GPIO 12 911#define AR9285_NUM_GPIO 12
912#define AR9287_NUM_GPIO 11
888 913
889#define AR_GPIO_IN_OUT 0x4048 914#define AR_GPIO_IN_OUT 0x4048
890#define AR_GPIO_IN_VAL 0x0FFFC000 915#define AR_GPIO_IN_VAL 0x0FFFC000
@@ -893,6 +918,8 @@ enum {
893#define AR928X_GPIO_IN_VAL_S 10 918#define AR928X_GPIO_IN_VAL_S 10
894#define AR9285_GPIO_IN_VAL 0x00FFF000 919#define AR9285_GPIO_IN_VAL 0x00FFF000
895#define AR9285_GPIO_IN_VAL_S 12 920#define AR9285_GPIO_IN_VAL_S 12
921#define AR9287_GPIO_IN_VAL 0x003FF800
922#define AR9287_GPIO_IN_VAL_S 11
896 923
897#define AR_GPIO_OE_OUT 0x404c 924#define AR_GPIO_OE_OUT 0x404c
898#define AR_GPIO_OE_OUT_DRV 0x3 925#define AR_GPIO_OE_OUT_DRV 0x3
@@ -1154,6 +1181,33 @@ enum {
1154#define AR9285_AN_TOP4 0x7870 1181#define AR9285_AN_TOP4 0x7870
1155#define AR9285_AN_TOP4_DEFAULT 0x10142c00 1182#define AR9285_AN_TOP4_DEFAULT 0x10142c00
1156 1183
1184#define AR9287_AN_RF2G3_CH0 0x7808
1185#define AR9287_AN_RF2G3_CH1 0x785c
1186#define AR9287_AN_RF2G3_DB1 0xE0000000
1187#define AR9287_AN_RF2G3_DB1_S 29
1188#define AR9287_AN_RF2G3_DB2 0x1C000000
1189#define AR9287_AN_RF2G3_DB2_S 26
1190#define AR9287_AN_RF2G3_OB_CCK 0x03800000
1191#define AR9287_AN_RF2G3_OB_CCK_S 23
1192#define AR9287_AN_RF2G3_OB_PSK 0x00700000
1193#define AR9287_AN_RF2G3_OB_PSK_S 20
1194#define AR9287_AN_RF2G3_OB_QAM 0x000E0000
1195#define AR9287_AN_RF2G3_OB_QAM_S 17
1196#define AR9287_AN_RF2G3_OB_PAL_OFF 0x0001C000
1197#define AR9287_AN_RF2G3_OB_PAL_OFF_S 14
1198
1199#define AR9287_AN_TXPC0 0x7898
1200#define AR9287_AN_TXPC0_TXPCMODE 0x0000C000
1201#define AR9287_AN_TXPC0_TXPCMODE_S 14
1202#define AR9287_AN_TXPC0_TXPCMODE_NORMAL 0
1203#define AR9287_AN_TXPC0_TXPCMODE_TEST 1
1204#define AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE 2
1205#define AR9287_AN_TXPC0_TXPCMODE_ATBTEST 3
1206
1207#define AR9287_AN_TOP2 0x78b4
1208#define AR9287_AN_TOP2_XPABIAS_LVL 0xC0000000
1209#define AR9287_AN_TOP2_XPABIAS_LVL_S 30
1210
1157#define AR_STA_ID0 0x8000 1211#define AR_STA_ID0 0x8000
1158#define AR_STA_ID1 0x8004 1212#define AR_STA_ID1 0x8004
1159#define AR_STA_ID1_SADH_MASK 0x0000FFFF 1213#define AR_STA_ID1_SADH_MASK 0x0000FFFF
@@ -1188,6 +1242,7 @@ enum {
1188#define AR_TIME_OUT_ACK_S 0 1242#define AR_TIME_OUT_ACK_S 0
1189#define AR_TIME_OUT_CTS 0x3FFF0000 1243#define AR_TIME_OUT_CTS 0x3FFF0000
1190#define AR_TIME_OUT_CTS_S 16 1244#define AR_TIME_OUT_CTS_S 16
1245#define AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR 0x16001D56
1191 1246
1192#define AR_RSSI_THR 0x8018 1247#define AR_RSSI_THR 0x8018
1193#define AR_RSSI_THR_MASK 0x000000FF 1248#define AR_RSSI_THR_MASK 0x000000FF
@@ -1203,6 +1258,7 @@ enum {
1203#define AR_USEC_TX_LAT_S 14 1258#define AR_USEC_TX_LAT_S 14
1204#define AR_USEC_RX_LAT 0x1F800000 1259#define AR_USEC_RX_LAT 0x1F800000
1205#define AR_USEC_RX_LAT_S 23 1260#define AR_USEC_RX_LAT_S 23
1261#define AR_USEC_ASYNC_FIFO_DUR 0x12e00074
1206 1262
1207#define AR_RESET_TSF 0x8020 1263#define AR_RESET_TSF 0x8020
1208#define AR_RESET_TSF_ONCE 0x01000000 1264#define AR_RESET_TSF_ONCE 0x01000000
@@ -1468,6 +1524,10 @@ enum {
1468#define AR_SLP_MIB_CLEAR 0x00000001 1524#define AR_SLP_MIB_CLEAR 0x00000001
1469#define AR_SLP_MIB_PENDING 0x00000002 1525#define AR_SLP_MIB_PENDING 0x00000002
1470 1526
1527#define AR_MAC_PCU_LOGIC_ANALYZER 0x8264
1528#define AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768 0x20000000
1529
1530
1471#define AR_2040_MODE 0x8318 1531#define AR_2040_MODE 0x8318
1472#define AR_2040_JOINED_RX_CLEAR 0x00000001 1532#define AR_2040_JOINED_RX_CLEAR 0x00000001
1473 1533
@@ -1485,6 +1545,39 @@ enum {
1485#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002 1545#define AR_PCU_MISC_MODE2_MGMT_CRYPTO_ENABLE 0x00000002
1486#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT 0x00000004 1546#define AR_PCU_MISC_MODE2_NO_CRYPTO_FOR_NON_DATA_PKT 0x00000004
1487 1547
1548#define AR_PCU_MISC_MODE2_RESERVED 0x00000038
1549#define AR_PCU_MISC_MODE2_ADHOC_MCAST_KEYID_ENABLE 0x00000040
1550#define AR_PCU_MISC_MODE2_CFP_IGNORE 0x00000080
1551#define AR_PCU_MISC_MODE2_MGMT_QOS 0x0000FF00
1552#define AR_PCU_MISC_MODE2_MGMT_QOS_S 8
1553#define AR_PCU_MISC_MODE2_ENABLE_LOAD_NAV_BEACON_DURATION 0x00010000
1554#define AR_PCU_MISC_MODE2_ENABLE_AGGWEP 0x00020000
1555#define AR_PCU_MISC_MODE2_HWWAR1 0x00100000
1556#define AR_PCU_MISC_MODE2_HWWAR2 0x02000000
1557#define AR_PCU_MISC_MODE2_RESERVED2 0xFFFE0000
1558
1559#define AR_MAC_PCU_ASYNC_FIFO_REG3 0x8358
1560#define AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL 0x00000400
1561#define AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET 0x80000000
1562
1563
1564#define AR_AES_MUTE_MASK0 0x805c
1565#define AR_AES_MUTE_MASK0_FC 0x0000FFFF
1566#define AR_AES_MUTE_MASK0_QOS 0xFFFF0000
1567#define AR_AES_MUTE_MASK0_QOS_S 16
1568
1569#define AR_AES_MUTE_MASK1 0x8060
1570#define AR_AES_MUTE_MASK1_SEQ 0x0000FFFF
1571#define AR_AES_MUTE_MASK1_SEQ_S 0
1572#define AR_AES_MUTE_MASK1_FC_MGMT 0xFFFF0000
1573#define AR_AES_MUTE_MASK1_FC_MGMT_S 16
1574
1575#define AR_RATE_DURATION_0 0x8700
1576#define AR_RATE_DURATION_31 0x87CC
1577#define AR_RATE_DURATION_32 0x8780
1578#define AR_RATE_DURATION(_n) (AR_RATE_DURATION_0 + ((_n)<<2))
1579
1580
1488#define AR_KEYTABLE_0 0x8800 1581#define AR_KEYTABLE_0 0x8800
1489#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32)) 1582#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32))
1490#define AR_KEY_CACHE_SIZE 128 1583#define AR_KEY_CACHE_SIZE 128
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index 1ff429b027d7..e1d419e02b4a 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -660,3 +660,20 @@ void ath9k_wiphy_set_scheduler(struct ath_softc *sc, unsigned int msec_int)
660 queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work, 660 queue_delayed_work(sc->hw->workqueue, &sc->wiphy_work,
661 sc->wiphy_scheduler_int); 661 sc->wiphy_scheduler_int);
662} 662}
663
664/* caller must hold wiphy_lock */
665bool ath9k_all_wiphys_idle(struct ath_softc *sc)
666{
667 unsigned int i;
668 if (sc->pri_wiphy->state != ATH_WIPHY_INACTIVE) {
669 return false;
670 }
671 for (i = 0; i < sc->num_sec_wiphy; i++) {
672 struct ath_wiphy *aphy = sc->sec_wiphy[i];
673 if (!aphy)
674 continue;
675 if (aphy->state != ATH_WIPHY_INACTIVE)
676 return false;
677 }
678 return true;
679}
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 5de9878d2c12..4ff155e8ee59 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -242,7 +242,6 @@ static struct ath_buf* ath_clone_txbuf(struct ath_softc *sc, struct ath_buf *bf)
242 spin_unlock_bh(&sc->tx.txbuflock); 242 spin_unlock_bh(&sc->tx.txbuflock);
243 return NULL; 243 return NULL;
244 } 244 }
245 ASSERT(!list_empty((&sc->tx.txbuf)));
246 tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list); 245 tbf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
247 list_del(&tbf->list); 246 list_del(&tbf->list);
248 spin_unlock_bh(&sc->tx.txbuflock); 247 spin_unlock_bh(&sc->tx.txbuflock);
@@ -383,8 +382,24 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
383 struct ath_buf *tbf; 382 struct ath_buf *tbf;
384 383
385 tbf = ath_clone_txbuf(sc, bf_last); 384 tbf = ath_clone_txbuf(sc, bf_last);
386 if (!tbf) 385 /*
386 * Update tx baw and complete the frame with
387 * failed status if we run out of tx buf
388 */
389 if (!tbf) {
390 spin_lock_bh(&txq->axq_lock);
391 ath_tx_update_baw(sc, tid,
392 bf->bf_seqno);
393 spin_unlock_bh(&txq->axq_lock);
394
395 bf->bf_state.bf_type |= BUF_XRETRY;
396 ath_tx_rc_status(bf, ds, nbad,
397 0, false);
398 ath_tx_complete_buf(sc, bf, &bf_head,
399 0, 0);
387 break; 400 break;
401 }
402
388 ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc); 403 ath9k_hw_cleartxdesc(sc->sc_ah, tbf->bf_desc);
389 list_add_tail(&tbf->list, &bf_head); 404 list_add_tail(&tbf->list, &bf_head);
390 } else { 405 } else {
@@ -857,6 +872,7 @@ struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
857 txq->axq_aggr_depth = 0; 872 txq->axq_aggr_depth = 0;
858 txq->axq_totalqueued = 0; 873 txq->axq_totalqueued = 0;
859 txq->axq_linkbuf = NULL; 874 txq->axq_linkbuf = NULL;
875 txq->axq_tx_inprogress = false;
860 sc->tx.txqsetup |= 1<<qnum; 876 sc->tx.txqsetup |= 1<<qnum;
861 } 877 }
862 return &sc->tx.txq[qnum]; 878 return &sc->tx.txq[qnum];
@@ -1023,6 +1039,10 @@ void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, bool retry_tx)
1023 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0); 1039 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
1024 } 1040 }
1025 1041
1042 spin_lock_bh(&txq->axq_lock);
1043 txq->axq_tx_inprogress = false;
1044 spin_unlock_bh(&txq->axq_lock);
1045
1026 /* flush any pending frames if aggregation is enabled */ 1046 /* flush any pending frames if aggregation is enabled */
1027 if (sc->sc_flags & SC_OP_TXAGGR) { 1047 if (sc->sc_flags & SC_OP_TXAGGR) {
1028 if (!retry_tx) { 1048 if (!retry_tx) {
@@ -1103,8 +1123,7 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1103 if (tid->paused) 1123 if (tid->paused)
1104 continue; 1124 continue;
1105 1125
1106 if ((txq->axq_depth % 2) == 0) 1126 ath_tx_sched_aggr(sc, txq, tid);
1107 ath_tx_sched_aggr(sc, txq, tid);
1108 1127
1109 /* 1128 /*
1110 * add tid to round-robin queue if more frames 1129 * add tid to round-robin queue if more frames
@@ -1947,19 +1966,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1947 if (bf->bf_stale) { 1966 if (bf->bf_stale) {
1948 bf_held = bf; 1967 bf_held = bf;
1949 if (list_is_last(&bf_held->list, &txq->axq_q)) { 1968 if (list_is_last(&bf_held->list, &txq->axq_q)) {
1950 txq->axq_link = NULL;
1951 txq->axq_linkbuf = NULL;
1952 spin_unlock_bh(&txq->axq_lock); 1969 spin_unlock_bh(&txq->axq_lock);
1953
1954 /*
1955 * The holding descriptor is the last
1956 * descriptor in queue. It's safe to remove
1957 * the last holding descriptor in BH context.
1958 */
1959 spin_lock_bh(&sc->tx.txbuflock);
1960 list_move_tail(&bf_held->list, &sc->tx.txbuf);
1961 spin_unlock_bh(&sc->tx.txbuflock);
1962
1963 break; 1970 break;
1964 } else { 1971 } else {
1965 bf = list_entry(bf_held->list.next, 1972 bf = list_entry(bf_held->list.next,
@@ -1996,6 +2003,7 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1996 txq->axq_aggr_depth--; 2003 txq->axq_aggr_depth--;
1997 2004
1998 txok = (ds->ds_txstat.ts_status == 0); 2005 txok = (ds->ds_txstat.ts_status == 0);
2006 txq->axq_tx_inprogress = false;
1999 spin_unlock_bh(&txq->axq_lock); 2007 spin_unlock_bh(&txq->axq_lock);
2000 2008
2001 if (bf_held) { 2009 if (bf_held) {
@@ -2029,6 +2037,40 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2029 } 2037 }
2030} 2038}
2031 2039
2040void ath_tx_complete_poll_work(struct work_struct *work)
2041{
2042 struct ath_softc *sc = container_of(work, struct ath_softc,
2043 tx_complete_work.work);
2044 struct ath_txq *txq;
2045 int i;
2046 bool needreset = false;
2047
2048 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
2049 if (ATH_TXQ_SETUP(sc, i)) {
2050 txq = &sc->tx.txq[i];
2051 spin_lock_bh(&txq->axq_lock);
2052 if (txq->axq_depth) {
2053 if (txq->axq_tx_inprogress) {
2054 needreset = true;
2055 spin_unlock_bh(&txq->axq_lock);
2056 break;
2057 } else {
2058 txq->axq_tx_inprogress = true;
2059 }
2060 }
2061 spin_unlock_bh(&txq->axq_lock);
2062 }
2063
2064 if (needreset) {
2065 DPRINTF(sc, ATH_DBG_RESET, "tx hung, resetting the chip\n");
2066 ath_reset(sc, false);
2067 }
2068
2069 queue_delayed_work(sc->hw->workqueue, &sc->tx_complete_work,
2070 msecs_to_jiffies(ATH_TX_COMPLETE_POLL_INT));
2071}
2072
2073
2032 2074
2033void ath_tx_tasklet(struct ath_softc *sc) 2075void ath_tx_tasklet(struct ath_softc *sc)
2034{ 2076{
@@ -2069,6 +2111,8 @@ int ath_tx_init(struct ath_softc *sc, int nbufs)
2069 goto err; 2111 goto err;
2070 } 2112 }
2071 2113
2114 INIT_DELAYED_WORK(&sc->tx_complete_work, ath_tx_complete_poll_work);
2115
2072err: 2116err:
2073 if (error != 0) 2117 if (error != 0)
2074 ath_tx_cleanup(sc); 2118 ath_tx_cleanup(sc);
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index e71c8d9cd706..3f4360ad0e4e 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -938,7 +938,6 @@ static void b43_clear_keys(struct b43_wldev *dev)
938static void b43_dump_keymemory(struct b43_wldev *dev) 938static void b43_dump_keymemory(struct b43_wldev *dev)
939{ 939{
940 unsigned int i, index, offset; 940 unsigned int i, index, offset;
941 DECLARE_MAC_BUF(macbuf);
942 u8 mac[ETH_ALEN]; 941 u8 mac[ETH_ALEN];
943 u16 algo; 942 u16 algo;
944 u32 rcmta0; 943 u32 rcmta0;
@@ -973,8 +972,7 @@ static void b43_dump_keymemory(struct b43_wldev *dev)
973 ((index - 4) * 2) + 1); 972 ((index - 4) * 2) + 1);
974 *((__le32 *)(&mac[0])) = cpu_to_le32(rcmta0); 973 *((__le32 *)(&mac[0])) = cpu_to_le32(rcmta0);
975 *((__le16 *)(&mac[4])) = cpu_to_le16(rcmta1); 974 *((__le16 *)(&mac[4])) = cpu_to_le16(rcmta1);
976 printk(" MAC: %s", 975 printk(" MAC: %pM", mac);
977 print_mac(macbuf, mac));
978 } else 976 } else
979 printk(" DEFAULT KEY"); 977 printk(" DEFAULT KEY");
980 printk("\n"); 978 printk("\n");
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 633740277352..ad8eab4a639b 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -666,7 +666,8 @@ static int prism2_config(struct pcmcia_device *link)
666 * irq structure is initialized. 666 * irq structure is initialized.
667 */ 667 */
668 if (link->conf.Attributes & CONF_ENABLE_IRQ) { 668 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
669 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT; 669 link->irq.Attributes = IRQ_TYPE_DYNAMIC_SHARING |
670 IRQ_HANDLE_PRESENT;
670 link->irq.IRQInfo1 = IRQ_LEVEL_ID; 671 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
671 link->irq.Handler = prism2_interrupt; 672 link->irq.Handler = prism2_interrupt;
672 link->irq.Instance = dev; 673 link->irq.Instance = dev;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index d726b3c6077a..2dc1cdbb4939 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -7250,9 +7250,6 @@ static void ipw_bg_qos_activate(struct work_struct *work)
7250 struct ipw_priv *priv = 7250 struct ipw_priv *priv =
7251 container_of(work, struct ipw_priv, qos_activate); 7251 container_of(work, struct ipw_priv, qos_activate);
7252 7252
7253 if (priv == NULL)
7254 return;
7255
7256 mutex_lock(&priv->mutex); 7253 mutex_lock(&priv->mutex);
7257 7254
7258 if (priv->status & STATUS_ASSOCIATED) 7255 if (priv->status & STATUS_ASSOCIATED)
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 7da52f1cc1d6..a899be914ebf 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -46,7 +46,7 @@
46#include "iwl-5000-hw.h" 46#include "iwl-5000-hw.h"
47 47
48/* Highest firmware API version supported */ 48/* Highest firmware API version supported */
49#define IWL1000_UCODE_API_MAX 2 49#define IWL1000_UCODE_API_MAX 3
50 50
51/* Lowest firmware API version supported */ 51/* Lowest firmware API version supported */
52#define IWL1000_UCODE_API_MIN 1 52#define IWL1000_UCODE_API_MIN 1
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
index 73f93a0ff2df..b569c6f38e5c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-hw.h
@@ -232,9 +232,8 @@ struct iwl3945_eeprom {
232#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */ 232#define PCI_CFG_REV_ID_BIT_BASIC_SKU (0x40) /* bit 6 */
233#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */ 233#define PCI_CFG_REV_ID_BIT_RTP (0x80) /* bit 7 */
234 234
235#define TFD_QUEUE_MIN 0 235/* 4 DATA + 1 CMD. There are 2 HCCA queues that are not used. */
236#define TFD_QUEUE_MAX 5 /* 4 DATA + 1 CMD */ 236#define IWL39_NUM_QUEUES 5
237
238#define IWL_NUM_SCAN_RATES (2) 237#define IWL_NUM_SCAN_RATES (2)
239 238
240#define IWL_DEFAULT_TX_RETRY 15 239#define IWL_DEFAULT_TX_RETRY 15
@@ -280,8 +279,6 @@ struct iwl3945_eeprom {
280/* Size of uCode instruction memory in bootstrap state machine */ 279/* Size of uCode instruction memory in bootstrap state machine */
281#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE 280#define IWL39_MAX_BSM_SIZE IWL39_RTC_INST_SIZE
282 281
283#define IWL39_MAX_NUM_QUEUES 8
284
285static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr) 282static inline int iwl3945_hw_valid_rtc_data_addr(u32 addr)
286{ 283{
287 return (addr >= IWL39_RTC_DATA_LOWER_BOUND) && 284 return (addr >= IWL39_RTC_DATA_LOWER_BOUND) &&
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 5eb538d18a80..a16bd4147eac 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -673,33 +673,17 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta,
673 s8 scale_action = 0; 673 s8 scale_action = 0;
674 unsigned long flags; 674 unsigned long flags;
675 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; 675 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
676 u16 fc; 676 u16 rate_mask = sta ? sta->supp_rates[sband->band] : 0;
677 u16 rate_mask = 0;
678 s8 max_rate_idx = -1; 677 s8 max_rate_idx = -1;
679 struct iwl_priv *priv = (struct iwl_priv *)priv_r; 678 struct iwl_priv *priv = (struct iwl_priv *)priv_r;
680 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 679 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
681 680
682 IWL_DEBUG_RATE(priv, "enter\n"); 681 IWL_DEBUG_RATE(priv, "enter\n");
683 682
684 if (sta) 683 if (rate_control_send_low(sta, priv_sta, txrc))
685 rate_mask = sta->supp_rates[sband->band];
686
687 /* Send management frames and NO_ACK data using lowest rate. */
688 fc = le16_to_cpu(hdr->frame_control);
689 if ((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
690 info->flags & IEEE80211_TX_CTL_NO_ACK ||
691 !sta || !priv_sta) {
692 IWL_DEBUG_RATE(priv, "leave: No STA priv data to update!\n");
693 if (!rate_mask)
694 info->control.rates[0].idx =
695 rate_lowest_index(sband, NULL);
696 else
697 info->control.rates[0].idx =
698 rate_lowest_index(sband, sta);
699 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
700 info->control.rates[0].count = 1;
701 return; 684 return;
702 } 685
686 rate_mask = sta->supp_rates[sband->band];
703 687
704 /* get user max rate if set */ 688 /* get user max rate if set */
705 max_rate_idx = txrc->max_rate_idx; 689 max_rate_idx = txrc->max_rate_idx;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index b0246dbda99a..8ee403cd9b99 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -502,14 +502,14 @@ static void _iwl3945_dbg_report_frame(struct iwl_priv *priv,
502 } 502 }
503 } 503 }
504 if (print_dump) 504 if (print_dump)
505 iwl_print_hex_dump(priv, IWL_DL_RX, data, length); 505 iwl_print_hex_dump(IWL_DL_RX, data, length);
506} 506}
507 507
508static void iwl3945_dbg_report_frame(struct iwl_priv *priv, 508static void iwl3945_dbg_report_frame(struct iwl_priv *priv,
509 struct iwl_rx_packet *pkt, 509 struct iwl_rx_packet *pkt,
510 struct ieee80211_hdr *header, int group100) 510 struct ieee80211_hdr *header, int group100)
511{ 511{
512 if (priv->debug_level & IWL_DL_RX) 512 if (iwl_debug_level & IWL_DL_RX)
513 _iwl3945_dbg_report_frame(priv, pkt, header, group100); 513 _iwl3945_dbg_report_frame(priv, pkt, header, group100);
514} 514}
515 515
@@ -963,7 +963,7 @@ static int iwl3945_txq_ctx_reset(struct iwl_priv *priv)
963 goto error; 963 goto error;
964 964
965 /* Tx queue(s) */ 965 /* Tx queue(s) */
966 for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) { 966 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
967 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? 967 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ?
968 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; 968 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
969 rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, 969 rc = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
@@ -1140,7 +1140,7 @@ void iwl3945_hw_txq_ctx_free(struct iwl_priv *priv)
1140 int txq_id; 1140 int txq_id;
1141 1141
1142 /* Tx queues */ 1142 /* Tx queues */
1143 for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) 1143 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
1144 if (txq_id == IWL_CMD_QUEUE_NUM) 1144 if (txq_id == IWL_CMD_QUEUE_NUM)
1145 iwl_cmd_queue_free(priv); 1145 iwl_cmd_queue_free(priv);
1146 else 1146 else
@@ -1156,7 +1156,7 @@ void iwl3945_hw_txq_ctx_stop(struct iwl_priv *priv)
1156 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0); 1156 iwl_write_prph(priv, ALM_SCD_MODE_REG, 0);
1157 1157
1158 /* reset TFD queues */ 1158 /* reset TFD queues */
1159 for (txq_id = 0; txq_id <= priv->hw_params.max_txq_num; txq_id++) { 1159 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
1160 iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0); 1160 iwl_write_direct32(priv, FH39_TCSR_CONFIG(txq_id), 0x0);
1161 iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS, 1161 iwl_poll_direct_bit(priv, FH39_TSSR_TX_STATUS,
1162 FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id), 1162 FH39_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(txq_id),
@@ -2552,7 +2552,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2552 } 2552 }
2553 2553
2554 /* Assign number of Usable TX queues */ 2554 /* Assign number of Usable TX queues */
2555 priv->hw_params.max_txq_num = TFD_QUEUE_MAX; 2555 priv->hw_params.max_txq_num = IWL39_NUM_QUEUES;
2556 2556
2557 priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd); 2557 priv->hw_params.tfd_size = sizeof(struct iwl3945_tfd);
2558 priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K; 2558 priv->hw_params.rx_buf_size = IWL_RX_BUF_SIZE_3K;
@@ -2786,11 +2786,50 @@ static int iwl3945_load_bsm(struct iwl_priv *priv)
2786 return 0; 2786 return 0;
2787} 2787}
2788 2788
2789#define IWL3945_UCODE_GET(item) \
2790static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode,\
2791 u32 api_ver) \
2792{ \
2793 return le32_to_cpu(ucode->u.v1.item); \
2794}
2795
2796static u32 iwl3945_ucode_get_header_size(u32 api_ver)
2797{
2798 return UCODE_HEADER_SIZE(1);
2799}
2800static u32 iwl3945_ucode_get_build(const struct iwl_ucode_header *ucode,
2801 u32 api_ver)
2802{
2803 return 0;
2804}
2805static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode,
2806 u32 api_ver)
2807{
2808 return (u8 *) ucode->u.v1.data;
2809}
2810
2811IWL3945_UCODE_GET(inst_size);
2812IWL3945_UCODE_GET(data_size);
2813IWL3945_UCODE_GET(init_size);
2814IWL3945_UCODE_GET(init_data_size);
2815IWL3945_UCODE_GET(boot_size);
2816
2789static struct iwl_hcmd_ops iwl3945_hcmd = { 2817static struct iwl_hcmd_ops iwl3945_hcmd = {
2790 .rxon_assoc = iwl3945_send_rxon_assoc, 2818 .rxon_assoc = iwl3945_send_rxon_assoc,
2791 .commit_rxon = iwl3945_commit_rxon, 2819 .commit_rxon = iwl3945_commit_rxon,
2792}; 2820};
2793 2821
2822static struct iwl_ucode_ops iwl3945_ucode = {
2823 .get_header_size = iwl3945_ucode_get_header_size,
2824 .get_build = iwl3945_ucode_get_build,
2825 .get_inst_size = iwl3945_ucode_get_inst_size,
2826 .get_data_size = iwl3945_ucode_get_data_size,
2827 .get_init_size = iwl3945_ucode_get_init_size,
2828 .get_init_data_size = iwl3945_ucode_get_init_data_size,
2829 .get_boot_size = iwl3945_ucode_get_boot_size,
2830 .get_data = iwl3945_ucode_get_data,
2831};
2832
2794static struct iwl_lib_ops iwl3945_lib = { 2833static struct iwl_lib_ops iwl3945_lib = {
2795 .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd, 2834 .txq_attach_buf_to_tfd = iwl3945_hw_txq_attach_buf_to_tfd,
2796 .txq_free_tfd = iwl3945_hw_txq_free_tfd, 2835 .txq_free_tfd = iwl3945_hw_txq_free_tfd,
@@ -2831,6 +2870,7 @@ static struct iwl_hcmd_utils_ops iwl3945_hcmd_utils = {
2831}; 2870};
2832 2871
2833static struct iwl_ops iwl3945_ops = { 2872static struct iwl_ops iwl3945_ops = {
2873 .ucode = &iwl3945_ucode,
2834 .lib = &iwl3945_lib, 2874 .lib = &iwl3945_lib,
2835 .hcmd = &iwl3945_hcmd, 2875 .hcmd = &iwl3945_hcmd,
2836 .utils = &iwl3945_hcmd_utils, 2876 .utils = &iwl3945_hcmd_utils,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index fbb3a573463e..f2ffc48cbaf8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -111,9 +111,6 @@ enum iwl3945_antenna {
111#define IWL_TX_FIFO_HCCA_2 6 111#define IWL_TX_FIFO_HCCA_2 6
112#define IWL_TX_FIFO_NONE 7 112#define IWL_TX_FIFO_NONE 7
113 113
114/* Minimum number of queues. MAX_NUM is defined in hw specific files */
115#define IWL_MIN_NUM_QUEUES 4
116
117#define IEEE80211_DATA_LEN 2304 114#define IEEE80211_DATA_LEN 2304
118#define IEEE80211_4ADDR_LEN 30 115#define IEEE80211_4ADDR_LEN 30
119#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN) 116#define IEEE80211_HLEN (IEEE80211_4ADDR_LEN)
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index edbb0bfd8cb7..c30a1b960576 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -146,7 +146,7 @@ static int iwl4965_load_bsm(struct iwl_priv *priv)
146 146
147 IWL_DEBUG_INFO(priv, "Begin load bsm\n"); 147 IWL_DEBUG_INFO(priv, "Begin load bsm\n");
148 148
149 priv->ucode_type = UCODE_RT; 149 priv->ucode_type = UCODE_INIT;
150 150
151 /* make sure bootstrap program is no larger than BSM's SRAM size */ 151 /* make sure bootstrap program is no larger than BSM's SRAM size */
152 if (len > IWL49_MAX_BSM_SIZE) 152 if (len > IWL49_MAX_BSM_SIZE)
@@ -256,6 +256,8 @@ static int iwl4965_set_ucode_ptrs(struct iwl_priv *priv)
256*/ 256*/
257static void iwl4965_init_alive_start(struct iwl_priv *priv) 257static void iwl4965_init_alive_start(struct iwl_priv *priv)
258{ 258{
259 int ret;
260
259 /* Check alive response for "valid" sign from uCode */ 261 /* Check alive response for "valid" sign from uCode */
260 if (priv->card_alive_init.is_valid != UCODE_VALID_OK) { 262 if (priv->card_alive_init.is_valid != UCODE_VALID_OK) {
261 /* We had an error bringing up the hardware, so take it 263 /* We had an error bringing up the hardware, so take it
@@ -287,6 +289,28 @@ static void iwl4965_init_alive_start(struct iwl_priv *priv)
287 IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n"); 289 IWL_DEBUG_INFO(priv, "Couldn't set up uCode pointers.\n");
288 goto restart; 290 goto restart;
289 } 291 }
292 priv->ucode_type = UCODE_RT;
293 if (test_bit(STATUS_RT_UCODE_ALIVE, &priv->status)) {
294 IWL_WARN(priv, "Runtime uCode already alive? "
295 "Waiting for alive anyway\n");
296 clear_bit(STATUS_RT_UCODE_ALIVE, &priv->status);
297 }
298 ret = wait_event_interruptible_timeout(
299 priv->wait_command_queue,
300 test_bit(STATUS_RT_UCODE_ALIVE, &priv->status),
301 UCODE_ALIVE_TIMEOUT);
302 if (!ret) {
303 /* FIXME: if STATUS_RT_UCODE_ALIVE timeout
304 * go back to restart the download Init uCode again
305 * this might cause to trap in the restart loop
306 */
307 priv->ucode_type = UCODE_NONE;
308 if (!test_bit(STATUS_RT_UCODE_ALIVE, &priv->status)) {
309 IWL_ERR(priv, "Runtime timeout after %dms\n",
310 jiffies_to_msecs(UCODE_ALIVE_TIMEOUT));
311 goto restart;
312 }
313 }
290 return; 314 return;
291 315
292restart: 316restart:
@@ -2221,12 +2245,50 @@ static void iwl4965_cancel_deferred_work(struct iwl_priv *priv)
2221 cancel_work_sync(&priv->txpower_work); 2245 cancel_work_sync(&priv->txpower_work);
2222} 2246}
2223 2247
2248#define IWL4965_UCODE_GET(item) \
2249static u32 iwl4965_ucode_get_##item(const struct iwl_ucode_header *ucode,\
2250 u32 api_ver) \
2251{ \
2252 return le32_to_cpu(ucode->u.v1.item); \
2253}
2254
2255static u32 iwl4965_ucode_get_header_size(u32 api_ver)
2256{
2257 return UCODE_HEADER_SIZE(1);
2258}
2259static u32 iwl4965_ucode_get_build(const struct iwl_ucode_header *ucode,
2260 u32 api_ver)
2261{
2262 return 0;
2263}
2264static u8 *iwl4965_ucode_get_data(const struct iwl_ucode_header *ucode,
2265 u32 api_ver)
2266{
2267 return (u8 *) ucode->u.v1.data;
2268}
2269
2270IWL4965_UCODE_GET(inst_size);
2271IWL4965_UCODE_GET(data_size);
2272IWL4965_UCODE_GET(init_size);
2273IWL4965_UCODE_GET(init_data_size);
2274IWL4965_UCODE_GET(boot_size);
2275
2224static struct iwl_hcmd_ops iwl4965_hcmd = { 2276static struct iwl_hcmd_ops iwl4965_hcmd = {
2225 .rxon_assoc = iwl4965_send_rxon_assoc, 2277 .rxon_assoc = iwl4965_send_rxon_assoc,
2226 .commit_rxon = iwl_commit_rxon, 2278 .commit_rxon = iwl_commit_rxon,
2227 .set_rxon_chain = iwl_set_rxon_chain, 2279 .set_rxon_chain = iwl_set_rxon_chain,
2228}; 2280};
2229 2281
2282static struct iwl_ucode_ops iwl4965_ucode = {
2283 .get_header_size = iwl4965_ucode_get_header_size,
2284 .get_build = iwl4965_ucode_get_build,
2285 .get_inst_size = iwl4965_ucode_get_inst_size,
2286 .get_data_size = iwl4965_ucode_get_data_size,
2287 .get_init_size = iwl4965_ucode_get_init_size,
2288 .get_init_data_size = iwl4965_ucode_get_init_data_size,
2289 .get_boot_size = iwl4965_ucode_get_boot_size,
2290 .get_data = iwl4965_ucode_get_data,
2291};
2230static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = { 2292static struct iwl_hcmd_utils_ops iwl4965_hcmd_utils = {
2231 .get_hcmd_size = iwl4965_get_hcmd_size, 2293 .get_hcmd_size = iwl4965_get_hcmd_size,
2232 .build_addsta_hcmd = iwl4965_build_addsta_hcmd, 2294 .build_addsta_hcmd = iwl4965_build_addsta_hcmd,
@@ -2287,6 +2349,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2287}; 2349};
2288 2350
2289static struct iwl_ops iwl4965_ops = { 2351static struct iwl_ops iwl4965_ops = {
2352 .ucode = &iwl4965_ucode,
2290 .lib = &iwl4965_lib, 2353 .lib = &iwl4965_lib,
2291 .hcmd = &iwl4965_hcmd, 2354 .hcmd = &iwl4965_hcmd,
2292 .utils = &iwl4965_hcmd_utils, 2355 .utils = &iwl4965_hcmd_utils,
@@ -2313,8 +2376,6 @@ module_param_named(antenna, iwl4965_mod_params.antenna, int, 0444);
2313MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])"); 2376MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
2314module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444); 2377module_param_named(swcrypto, iwl4965_mod_params.sw_crypto, int, 0444);
2315MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])"); 2378MODULE_PARM_DESC(swcrypto, "using crypto in software (default 0 [hardware])");
2316module_param_named(debug, iwl4965_mod_params.debug, uint, 0444);
2317MODULE_PARM_DESC(debug, "debug output mask");
2318module_param_named( 2379module_param_named(
2319 disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, 0444); 2380 disable_hw_scan, iwl4965_mod_params.disable_hw_scan, int, 0444);
2320MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); 2381MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 85e8bac499a7..702db07fa382 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -239,6 +239,13 @@ static void iwl5000_nic_config(struct iwl_priv *priv)
239 APMG_PS_CTRL_EARLY_PWR_OFF_RESET_DIS, 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 241
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
242 spin_unlock_irqrestore(&priv->lock, flags); 249 spin_unlock_irqrestore(&priv->lock, flags);
243} 250}
244 251
@@ -1449,6 +1456,44 @@ int iwl5000_calc_rssi(struct iwl_priv *priv,
1449 return max_rssi - agc - IWL49_RSSI_OFFSET; 1456 return max_rssi - agc - IWL49_RSSI_OFFSET;
1450} 1457}
1451 1458
1459#define IWL5000_UCODE_GET(item) \
1460static u32 iwl5000_ucode_get_##item(const struct iwl_ucode_header *ucode,\
1461 u32 api_ver) \
1462{ \
1463 if (api_ver <= 2) \
1464 return le32_to_cpu(ucode->u.v1.item); \
1465 return le32_to_cpu(ucode->u.v2.item); \
1466}
1467
1468static u32 iwl5000_ucode_get_header_size(u32 api_ver)
1469{
1470 if (api_ver <= 2)
1471 return UCODE_HEADER_SIZE(1);
1472 return UCODE_HEADER_SIZE(2);
1473}
1474
1475static u32 iwl5000_ucode_get_build(const struct iwl_ucode_header *ucode,
1476 u32 api_ver)
1477{
1478 if (api_ver <= 2)
1479 return 0;
1480 return le32_to_cpu(ucode->u.v2.build);
1481}
1482
1483static u8 *iwl5000_ucode_get_data(const struct iwl_ucode_header *ucode,
1484 u32 api_ver)
1485{
1486 if (api_ver <= 2)
1487 return (u8 *) ucode->u.v1.data;
1488 return (u8 *) ucode->u.v2.data;
1489}
1490
1491IWL5000_UCODE_GET(inst_size);
1492IWL5000_UCODE_GET(data_size);
1493IWL5000_UCODE_GET(init_size);
1494IWL5000_UCODE_GET(init_data_size);
1495IWL5000_UCODE_GET(boot_size);
1496
1452struct iwl_hcmd_ops iwl5000_hcmd = { 1497struct iwl_hcmd_ops iwl5000_hcmd = {
1453 .rxon_assoc = iwl5000_send_rxon_assoc, 1498 .rxon_assoc = iwl5000_send_rxon_assoc,
1454 .commit_rxon = iwl_commit_rxon, 1499 .commit_rxon = iwl_commit_rxon,
@@ -1464,6 +1509,17 @@ struct iwl_hcmd_utils_ops iwl5000_hcmd_utils = {
1464 .calc_rssi = iwl5000_calc_rssi, 1509 .calc_rssi = iwl5000_calc_rssi,
1465}; 1510};
1466 1511
1512struct iwl_ucode_ops iwl5000_ucode = {
1513 .get_header_size = iwl5000_ucode_get_header_size,
1514 .get_build = iwl5000_ucode_get_build,
1515 .get_inst_size = iwl5000_ucode_get_inst_size,
1516 .get_data_size = iwl5000_ucode_get_data_size,
1517 .get_init_size = iwl5000_ucode_get_init_size,
1518 .get_init_data_size = iwl5000_ucode_get_init_data_size,
1519 .get_boot_size = iwl5000_ucode_get_boot_size,
1520 .get_data = iwl5000_ucode_get_data,
1521};
1522
1467struct iwl_lib_ops iwl5000_lib = { 1523struct iwl_lib_ops iwl5000_lib = {
1468 .set_hw_params = iwl5000_hw_set_hw_params, 1524 .set_hw_params = iwl5000_hw_set_hw_params,
1469 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl, 1525 .txq_update_byte_cnt_tbl = iwl5000_txq_update_byte_cnt_tbl,
@@ -1565,12 +1621,14 @@ static struct iwl_lib_ops iwl5150_lib = {
1565}; 1621};
1566 1622
1567struct iwl_ops iwl5000_ops = { 1623struct iwl_ops iwl5000_ops = {
1624 .ucode = &iwl5000_ucode,
1568 .lib = &iwl5000_lib, 1625 .lib = &iwl5000_lib,
1569 .hcmd = &iwl5000_hcmd, 1626 .hcmd = &iwl5000_hcmd,
1570 .utils = &iwl5000_hcmd_utils, 1627 .utils = &iwl5000_hcmd_utils,
1571}; 1628};
1572 1629
1573static struct iwl_ops iwl5150_ops = { 1630static struct iwl_ops iwl5150_ops = {
1631 .ucode = &iwl5000_ucode,
1574 .lib = &iwl5150_lib, 1632 .lib = &iwl5150_lib,
1575 .hcmd = &iwl5000_hcmd, 1633 .hcmd = &iwl5000_hcmd,
1576 .utils = &iwl5000_hcmd_utils, 1634 .utils = &iwl5000_hcmd_utils,
@@ -1687,8 +1745,6 @@ MODULE_FIRMWARE(IWL5150_MODULE_FIRMWARE(IWL5150_UCODE_API_MAX));
1687module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444); 1745module_param_named(swcrypto50, iwl50_mod_params.sw_crypto, bool, 0444);
1688MODULE_PARM_DESC(swcrypto50, 1746MODULE_PARM_DESC(swcrypto50,
1689 "using software crypto engine (default 0 [hardware])\n"); 1747 "using software crypto engine (default 0 [hardware])\n");
1690module_param_named(debug50, iwl50_mod_params.debug, uint, 0444);
1691MODULE_PARM_DESC(debug50, "50XX debug output mask");
1692module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444); 1748module_param_named(queues_num50, iwl50_mod_params.num_of_queues, int, 0444);
1693MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series"); 1749MODULE_PARM_DESC(queues_num50, "number of hw queues in 50xx series");
1694module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444); 1750module_param_named(11n_disable50, iwl50_mod_params.disable_11n, int, 0444);
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index bd438d8acf55..26c5d4a60d17 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -46,8 +46,8 @@
46#include "iwl-5000-hw.h" 46#include "iwl-5000-hw.h"
47 47
48/* Highest firmware API version supported */ 48/* Highest firmware API version supported */
49#define IWL6000_UCODE_API_MAX 2 49#define IWL6000_UCODE_API_MAX 3
50#define IWL6050_UCODE_API_MAX 2 50#define IWL6050_UCODE_API_MAX 3
51 51
52/* Lowest firmware API version supported */ 52/* Lowest firmware API version supported */
53#define IWL6000_UCODE_API_MIN 1 53#define IWL6000_UCODE_API_MIN 1
@@ -69,6 +69,7 @@ static struct iwl_hcmd_utils_ops iwl6000_hcmd_utils = {
69}; 69};
70 70
71static struct iwl_ops iwl6000_ops = { 71static struct iwl_ops iwl6000_ops = {
72 .ucode = &iwl5000_ucode,
72 .lib = &iwl5000_lib, 73 .lib = &iwl5000_lib,
73 .hcmd = &iwl5000_hcmd, 74 .hcmd = &iwl5000_hcmd,
74 .utils = &iwl6000_hcmd_utils, 75 .utils = &iwl6000_hcmd_utils,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index ff20e5048a55..63280411fd58 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -2466,7 +2466,6 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2466 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2466 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2467 struct iwl_lq_sta *lq_sta = priv_sta; 2467 struct iwl_lq_sta *lq_sta = priv_sta;
2468 int rate_idx; 2468 int rate_idx;
2469 u64 mask_bit = 0;
2470 2469
2471 IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n"); 2470 IWL_DEBUG_RATE_LIMIT(priv, "rate scale calculate new rate for skb\n");
2472 2471
@@ -2481,22 +2480,9 @@ static void rs_get_rate(void *priv_r, struct ieee80211_sta *sta, void *priv_sta,
2481 lq_sta->max_rate_idx = -1; 2480 lq_sta->max_rate_idx = -1;
2482 } 2481 }
2483 2482
2484 if (sta)
2485 mask_bit = sta->supp_rates[sband->band];
2486
2487 /* Send management frames and NO_ACK data using lowest rate. */ 2483 /* Send management frames and NO_ACK data using lowest rate. */
2488 if (!ieee80211_is_data(hdr->frame_control) || 2484 if (rate_control_send_low(sta, priv_sta, txrc))
2489 info->flags & IEEE80211_TX_CTL_NO_ACK || !sta || !lq_sta) {
2490 if (!mask_bit)
2491 info->control.rates[0].idx =
2492 rate_lowest_index(sband, NULL);
2493 else
2494 info->control.rates[0].idx =
2495 rate_lowest_index(sband, sta);
2496 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
2497 info->control.rates[0].count = 1;
2498 return; 2485 return;
2499 }
2500 2486
2501 rate_idx = lq_sta->last_txrate_idx; 2487 rate_idx = lq_sta->last_txrate_idx;
2502 2488
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index e2cc5994d108..44c7f236a7a3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -533,12 +533,16 @@ static void iwl_rx_reply_alive(struct iwl_priv *priv,
533 533
534 if (palive->ver_subtype == INITIALIZE_SUBTYPE) { 534 if (palive->ver_subtype == INITIALIZE_SUBTYPE) {
535 IWL_DEBUG_INFO(priv, "Initialization Alive received.\n"); 535 IWL_DEBUG_INFO(priv, "Initialization Alive received.\n");
536 set_bit(STATUS_INIT_UCODE_ALIVE, &priv->status);
537 wake_up_interruptible(&priv->wait_command_queue);
536 memcpy(&priv->card_alive_init, 538 memcpy(&priv->card_alive_init,
537 &pkt->u.alive_frame, 539 &pkt->u.alive_frame,
538 sizeof(struct iwl_init_alive_resp)); 540 sizeof(struct iwl_init_alive_resp));
539 pwork = &priv->init_alive_start; 541 pwork = &priv->init_alive_start;
540 } else { 542 } else {
541 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); 543 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
544 set_bit(STATUS_RT_UCODE_ALIVE, &priv->status);
545 wake_up_interruptible(&priv->wait_command_queue);
542 memcpy(&priv->card_alive, &pkt->u.alive_frame, 546 memcpy(&priv->card_alive, &pkt->u.alive_frame,
543 sizeof(struct iwl_alive_resp)); 547 sizeof(struct iwl_alive_resp));
544 pwork = &priv->alive_start; 548 pwork = &priv->alive_start;
@@ -900,7 +904,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
900 iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); 904 iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
901 905
902#ifdef CONFIG_IWLWIFI_DEBUG 906#ifdef CONFIG_IWLWIFI_DEBUG
903 if (priv->debug_level & IWL_DL_ISR) { 907 if (iwl_debug_level & IWL_DL_ISR) {
904 /* just for debug */ 908 /* just for debug */
905 inta_mask = iwl_read32(priv, CSR_INT_MASK); 909 inta_mask = iwl_read32(priv, CSR_INT_MASK);
906 IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", 910 IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
@@ -919,7 +923,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
919 923
920 /* Now service all interrupt bits discovered above. */ 924 /* Now service all interrupt bits discovered above. */
921 if (inta & CSR_INT_BIT_HW_ERR) { 925 if (inta & CSR_INT_BIT_HW_ERR) {
922 IWL_ERR(priv, "Microcode HW error detected. Restarting.\n"); 926 IWL_ERR(priv, "Hardware error detected. Restarting.\n");
923 927
924 /* Tell the device to stop sending interrupts */ 928 /* Tell the device to stop sending interrupts */
925 iwl_disable_interrupts(priv); 929 iwl_disable_interrupts(priv);
@@ -935,7 +939,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
935 } 939 }
936 940
937#ifdef CONFIG_IWLWIFI_DEBUG 941#ifdef CONFIG_IWLWIFI_DEBUG
938 if (priv->debug_level & (IWL_DL_ISR)) { 942 if (iwl_debug_level & (IWL_DL_ISR)) {
939 /* NIC fires this, but we don't use it, redundant with WAKEUP */ 943 /* NIC fires this, but we don't use it, redundant with WAKEUP */
940 if (inta & CSR_INT_BIT_SCD) { 944 if (inta & CSR_INT_BIT_SCD) {
941 IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " 945 IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
@@ -960,7 +964,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
960 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) 964 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
961 hw_rf_kill = 1; 965 hw_rf_kill = 1;
962 966
963 IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", 967 IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
964 hw_rf_kill ? "disable radio" : "enable radio"); 968 hw_rf_kill ? "disable radio" : "enable radio");
965 969
966 priv->isr_stats.rfkill++; 970 priv->isr_stats.rfkill++;
@@ -1049,7 +1053,7 @@ static void iwl_irq_tasklet_legacy(struct iwl_priv *priv)
1049 iwl_enable_interrupts(priv); 1053 iwl_enable_interrupts(priv);
1050 1054
1051#ifdef CONFIG_IWLWIFI_DEBUG 1055#ifdef CONFIG_IWLWIFI_DEBUG
1052 if (priv->debug_level & (IWL_DL_ISR)) { 1056 if (iwl_debug_level & (IWL_DL_ISR)) {
1053 inta = iwl_read32(priv, CSR_INT); 1057 inta = iwl_read32(priv, CSR_INT);
1054 inta_mask = iwl_read32(priv, CSR_INT_MASK); 1058 inta_mask = iwl_read32(priv, CSR_INT_MASK);
1055 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); 1059 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
@@ -1080,7 +1084,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1080 inta = priv->inta; 1084 inta = priv->inta;
1081 1085
1082#ifdef CONFIG_IWLWIFI_DEBUG 1086#ifdef CONFIG_IWLWIFI_DEBUG
1083 if (priv->debug_level & IWL_DL_ISR) { 1087 if (iwl_debug_level & IWL_DL_ISR) {
1084 /* just for debug */ 1088 /* just for debug */
1085 inta_mask = iwl_read32(priv, CSR_INT_MASK); 1089 inta_mask = iwl_read32(priv, CSR_INT_MASK);
1086 IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ", 1090 IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x\n ",
@@ -1092,7 +1096,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1092 1096
1093 /* Now service all interrupt bits discovered above. */ 1097 /* Now service all interrupt bits discovered above. */
1094 if (inta & CSR_INT_BIT_HW_ERR) { 1098 if (inta & CSR_INT_BIT_HW_ERR) {
1095 IWL_ERR(priv, "Microcode HW error detected. Restarting.\n"); 1099 IWL_ERR(priv, "Hardware error detected. Restarting.\n");
1096 1100
1097 /* Tell the device to stop sending interrupts */ 1101 /* Tell the device to stop sending interrupts */
1098 iwl_disable_interrupts(priv); 1102 iwl_disable_interrupts(priv);
@@ -1108,7 +1112,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1108 } 1112 }
1109 1113
1110#ifdef CONFIG_IWLWIFI_DEBUG 1114#ifdef CONFIG_IWLWIFI_DEBUG
1111 if (priv->debug_level & (IWL_DL_ISR)) { 1115 if (iwl_debug_level & (IWL_DL_ISR)) {
1112 /* NIC fires this, but we don't use it, redundant with WAKEUP */ 1116 /* NIC fires this, but we don't use it, redundant with WAKEUP */
1113 if (inta & CSR_INT_BIT_SCD) { 1117 if (inta & CSR_INT_BIT_SCD) {
1114 IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " 1118 IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
@@ -1133,7 +1137,7 @@ static void iwl_irq_tasklet(struct iwl_priv *priv)
1133 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) 1137 CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW))
1134 hw_rf_kill = 1; 1138 hw_rf_kill = 1;
1135 1139
1136 IWL_DEBUG_RF_KILL(priv, "RF_KILL bit toggled to %s.\n", 1140 IWL_WARN(priv, "RF_KILL bit toggled to %s.\n",
1137 hw_rf_kill ? "disable radio" : "enable radio"); 1141 hw_rf_kill ? "disable radio" : "enable radio");
1138 1142
1139 priv->isr_stats.rfkill++; 1143 priv->isr_stats.rfkill++;
@@ -1284,7 +1288,7 @@ static void iwl_nic_start(struct iwl_priv *priv)
1284 */ 1288 */
1285static int iwl_read_ucode(struct iwl_priv *priv) 1289static int iwl_read_ucode(struct iwl_priv *priv)
1286{ 1290{
1287 struct iwl_ucode *ucode; 1291 struct iwl_ucode_header *ucode;
1288 int ret = -EINVAL, index; 1292 int ret = -EINVAL, index;
1289 const struct firmware *ucode_raw; 1293 const struct firmware *ucode_raw;
1290 const char *name_pre = priv->cfg->fw_name_pre; 1294 const char *name_pre = priv->cfg->fw_name_pre;
@@ -1293,7 +1297,8 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1293 char buf[25]; 1297 char buf[25];
1294 u8 *src; 1298 u8 *src;
1295 size_t len; 1299 size_t len;
1296 u32 api_ver, inst_size, data_size, init_size, init_data_size, boot_size; 1300 u32 api_ver, build;
1301 u32 inst_size, data_size, init_size, init_data_size, boot_size;
1297 1302
1298 /* Ask kernel firmware_class module to get the boot firmware off disk. 1303 /* Ask kernel firmware_class module to get the boot firmware off disk.
1299 * request_firmware() is synchronous, file is in memory on return. */ 1304 * request_firmware() is synchronous, file is in memory on return. */
@@ -1323,23 +1328,26 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1323 if (ret < 0) 1328 if (ret < 0)
1324 goto error; 1329 goto error;
1325 1330
1326 /* Make sure that we got at least our header! */ 1331 /* Make sure that we got at least the v1 header! */
1327 if (ucode_raw->size < sizeof(*ucode)) { 1332 if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
1328 IWL_ERR(priv, "File size way too small!\n"); 1333 IWL_ERR(priv, "File size way too small!\n");
1329 ret = -EINVAL; 1334 ret = -EINVAL;
1330 goto err_release; 1335 goto err_release;
1331 } 1336 }
1332 1337
1333 /* Data from ucode file: header followed by uCode images */ 1338 /* Data from ucode file: header followed by uCode images */
1334 ucode = (void *)ucode_raw->data; 1339 ucode = (struct iwl_ucode_header *)ucode_raw->data;
1335 1340
1336 priv->ucode_ver = le32_to_cpu(ucode->ver); 1341 priv->ucode_ver = le32_to_cpu(ucode->ver);
1337 api_ver = IWL_UCODE_API(priv->ucode_ver); 1342 api_ver = IWL_UCODE_API(priv->ucode_ver);
1338 inst_size = le32_to_cpu(ucode->inst_size); 1343 build = priv->cfg->ops->ucode->get_build(ucode, api_ver);
1339 data_size = le32_to_cpu(ucode->data_size); 1344 inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
1340 init_size = le32_to_cpu(ucode->init_size); 1345 data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
1341 init_data_size = le32_to_cpu(ucode->init_data_size); 1346 init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
1342 boot_size = le32_to_cpu(ucode->boot_size); 1347 init_data_size =
1348 priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
1349 boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
1350 src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
1343 1351
1344 /* api_ver should match the api version forming part of the 1352 /* api_ver should match the api version forming part of the
1345 * firmware filename ... but we don't check for that and only rely 1353 * firmware filename ... but we don't check for that and only rely
@@ -1365,6 +1373,9 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1365 IWL_UCODE_API(priv->ucode_ver), 1373 IWL_UCODE_API(priv->ucode_ver),
1366 IWL_UCODE_SERIAL(priv->ucode_ver)); 1374 IWL_UCODE_SERIAL(priv->ucode_ver));
1367 1375
1376 if (build)
1377 IWL_DEBUG_INFO(priv, "Build %u\n", build);
1378
1368 IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n", 1379 IWL_DEBUG_INFO(priv, "f/w package hdr ucode version raw = 0x%x\n",
1369 priv->ucode_ver); 1380 priv->ucode_ver);
1370 IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n", 1381 IWL_DEBUG_INFO(priv, "f/w package hdr runtime inst size = %u\n",
@@ -1379,12 +1390,14 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1379 boot_size); 1390 boot_size);
1380 1391
1381 /* Verify size of file vs. image size info in file's header */ 1392 /* Verify size of file vs. image size info in file's header */
1382 if (ucode_raw->size < sizeof(*ucode) + 1393 if (ucode_raw->size !=
1394 priv->cfg->ops->ucode->get_header_size(api_ver) +
1383 inst_size + data_size + init_size + 1395 inst_size + data_size + init_size +
1384 init_data_size + boot_size) { 1396 init_data_size + boot_size) {
1385 1397
1386 IWL_DEBUG_INFO(priv, "uCode file size %d too small\n", 1398 IWL_DEBUG_INFO(priv,
1387 (int)ucode_raw->size); 1399 "uCode file size %d does not match expected size\n",
1400 (int)ucode_raw->size);
1388 ret = -EINVAL; 1401 ret = -EINVAL;
1389 goto err_release; 1402 goto err_release;
1390 } 1403 }
@@ -1464,42 +1477,42 @@ static int iwl_read_ucode(struct iwl_priv *priv)
1464 /* Copy images into buffers for card's bus-master reads ... */ 1477 /* Copy images into buffers for card's bus-master reads ... */
1465 1478
1466 /* Runtime instructions (first block of data in file) */ 1479 /* Runtime instructions (first block of data in file) */
1467 src = &ucode->data[0]; 1480 len = inst_size;
1468 len = priv->ucode_code.len;
1469 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len); 1481 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode instr len %Zd\n", len);
1470 memcpy(priv->ucode_code.v_addr, src, len); 1482 memcpy(priv->ucode_code.v_addr, src, len);
1483 src += len;
1484
1471 IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", 1485 IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
1472 priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); 1486 priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
1473 1487
1474 /* Runtime data (2nd block) 1488 /* Runtime data (2nd block)
1475 * NOTE: Copy into backup buffer will be done in iwl_up() */ 1489 * NOTE: Copy into backup buffer will be done in iwl_up() */
1476 src = &ucode->data[inst_size]; 1490 len = data_size;
1477 len = priv->ucode_data.len;
1478 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len); 1491 IWL_DEBUG_INFO(priv, "Copying (but not loading) uCode data len %Zd\n", len);
1479 memcpy(priv->ucode_data.v_addr, src, len); 1492 memcpy(priv->ucode_data.v_addr, src, len);
1480 memcpy(priv->ucode_data_backup.v_addr, src, len); 1493 memcpy(priv->ucode_data_backup.v_addr, src, len);
1494 src += len;
1481 1495
1482 /* Initialization instructions (3rd block) */ 1496 /* Initialization instructions (3rd block) */
1483 if (init_size) { 1497 if (init_size) {
1484 src = &ucode->data[inst_size + data_size]; 1498 len = init_size;
1485 len = priv->ucode_init.len;
1486 IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n", 1499 IWL_DEBUG_INFO(priv, "Copying (but not loading) init instr len %Zd\n",
1487 len); 1500 len);
1488 memcpy(priv->ucode_init.v_addr, src, len); 1501 memcpy(priv->ucode_init.v_addr, src, len);
1502 src += len;
1489 } 1503 }
1490 1504
1491 /* Initialization data (4th block) */ 1505 /* Initialization data (4th block) */
1492 if (init_data_size) { 1506 if (init_data_size) {
1493 src = &ucode->data[inst_size + data_size + init_size]; 1507 len = init_data_size;
1494 len = priv->ucode_init_data.len;
1495 IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n", 1508 IWL_DEBUG_INFO(priv, "Copying (but not loading) init data len %Zd\n",
1496 len); 1509 len);
1497 memcpy(priv->ucode_init_data.v_addr, src, len); 1510 memcpy(priv->ucode_init_data.v_addr, src, len);
1511 src += len;
1498 } 1512 }
1499 1513
1500 /* Bootstrap instructions (5th block) */ 1514 /* Bootstrap instructions (5th block) */
1501 src = &ucode->data[inst_size + data_size + init_size + init_data_size]; 1515 len = boot_size;
1502 len = priv->ucode_boot.len;
1503 IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len); 1516 IWL_DEBUG_INFO(priv, "Copying (but not loading) boot instr len %Zd\n", len);
1504 memcpy(priv->ucode_boot.v_addr, src, len); 1517 memcpy(priv->ucode_boot.v_addr, src, len);
1505 1518
@@ -1773,6 +1786,7 @@ static int __iwl_up(struct iwl_priv *priv)
1773{ 1786{
1774 int i; 1787 int i;
1775 int ret; 1788 int ret;
1789 unsigned long status;
1776 1790
1777 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { 1791 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
1778 IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); 1792 IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
@@ -1850,6 +1864,51 @@ static int __iwl_up(struct iwl_priv *priv)
1850 /* start card; "initialize" will load runtime ucode */ 1864 /* start card; "initialize" will load runtime ucode */
1851 iwl_nic_start(priv); 1865 iwl_nic_start(priv);
1852 1866
1867 /* Just finish download Init or Runtime uCode image to device
1868 * now we wait here for uCode send REPLY_ALIVE notification
1869 * to indicate uCode is ready.
1870 * 1) For Init uCode image, all iwlagn devices should wait here
1871 * on STATUS_INIT_UCODE_ALIVE status bit; if timeout before
1872 * receive the REPLY_ALIVE notification, go back and try to
1873 * download the Init uCode image again.
1874 * 2) For Runtime uCode image, all iwlagn devices except 4965
1875 * wait here on STATUS_RT_UCODE_ALIVE status bit; if
1876 * timeout before receive the REPLY_ALIVE notification, go back
1877 * and download the Runtime uCode image again.
1878 * 3) For 4965 Runtime uCode, it will not go through this path,
1879 * need to wait for STATUS_RT_UCODE_ALIVE status bit in
1880 * iwl4965_init_alive_start() function; if timeout, need to
1881 * restart and download Init uCode image.
1882 */
1883 if (priv->ucode_type == UCODE_INIT)
1884 status = STATUS_INIT_UCODE_ALIVE;
1885 else
1886 status = STATUS_RT_UCODE_ALIVE;
1887 if (test_bit(status, &priv->status)) {
1888 IWL_WARN(priv,
1889 "%s uCode already alive? "
1890 "Waiting for alive anyway\n",
1891 (status == STATUS_INIT_UCODE_ALIVE)
1892 ? "INIT" : "Runtime");
1893 clear_bit(status, &priv->status);
1894 }
1895 ret = wait_event_interruptible_timeout(
1896 priv->wait_command_queue,
1897 test_bit(status, &priv->status),
1898 UCODE_ALIVE_TIMEOUT);
1899 if (!ret) {
1900 if (!test_bit(status, &priv->status)) {
1901 priv->ucode_type =
1902 (status == STATUS_INIT_UCODE_ALIVE)
1903 ? UCODE_NONE : UCODE_INIT;
1904 IWL_ERR(priv,
1905 "%s timeout after %dms\n",
1906 (status == STATUS_INIT_UCODE_ALIVE)
1907 ? "INIT" : "Runtime",
1908 jiffies_to_msecs(UCODE_ALIVE_TIMEOUT));
1909 continue;
1910 }
1911 }
1853 IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n"); 1912 IWL_DEBUG_INFO(priv, DRV_NAME " is coming up\n");
1854 1913
1855 return 0; 1914 return 0;
@@ -2397,14 +2456,16 @@ static int iwl_mac_get_stats(struct ieee80211_hw *hw,
2397 * used for controlling the debug level. 2456 * used for controlling the debug level.
2398 * 2457 *
2399 * See the level definitions in iwl for details. 2458 * See the level definitions in iwl for details.
2459 *
2460 * FIXME This file can be deprecated as the module parameter is
2461 * writable and users can thus also change the debug level
2462 * using the /sys/module/iwl3945/parameters/debug file.
2400 */ 2463 */
2401 2464
2402static ssize_t show_debug_level(struct device *d, 2465static ssize_t show_debug_level(struct device *d,
2403 struct device_attribute *attr, char *buf) 2466 struct device_attribute *attr, char *buf)
2404{ 2467{
2405 struct iwl_priv *priv = dev_get_drvdata(d); 2468 return sprintf(buf, "0x%08X\n", iwl_debug_level);
2406
2407 return sprintf(buf, "0x%08X\n", priv->debug_level);
2408} 2469}
2409static ssize_t store_debug_level(struct device *d, 2470static ssize_t store_debug_level(struct device *d,
2410 struct device_attribute *attr, 2471 struct device_attribute *attr,
@@ -2418,7 +2479,7 @@ static ssize_t store_debug_level(struct device *d,
2418 if (ret) 2479 if (ret)
2419 IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf); 2480 IWL_ERR(priv, "%s is not in hex or decimal form.\n", buf);
2420 else 2481 else
2421 priv->debug_level = val; 2482 iwl_debug_level = val;
2422 2483
2423 return strnlen(buf, count); 2484 return strnlen(buf, count);
2424} 2485}
@@ -2627,26 +2688,6 @@ static ssize_t show_power_level(struct device *d,
2627static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level, 2688static DEVICE_ATTR(power_level, S_IWUSR | S_IRUSR, show_power_level,
2628 store_power_level); 2689 store_power_level);
2629 2690
2630static ssize_t show_qos(struct device *d,
2631 struct device_attribute *attr, char *buf)
2632{
2633 struct iwl_priv *priv = dev_get_drvdata(d);
2634 char *p = buf;
2635 int q;
2636
2637 for (q = 0; q < AC_NUM; q++) {
2638 p += sprintf(p, "\tcw_min\tcw_max\taifsn\ttxop\n");
2639 p += sprintf(p, "AC[%d]\t%u\t%u\t%u\t%u\n", q,
2640 priv->qos_data.def_qos_parm.ac[q].cw_min,
2641 priv->qos_data.def_qos_parm.ac[q].cw_max,
2642 priv->qos_data.def_qos_parm.ac[q].aifsn,
2643 priv->qos_data.def_qos_parm.ac[q].edca_txop);
2644 }
2645
2646 return p - buf + 1;
2647}
2648
2649static DEVICE_ATTR(qos, S_IRUGO, show_qos, NULL);
2650 2691
2651static ssize_t show_statistics(struct device *d, 2692static ssize_t show_statistics(struct device *d,
2652 struct device_attribute *attr, char *buf) 2693 struct device_attribute *attr, char *buf)
@@ -2747,7 +2788,6 @@ static struct attribute *iwl_sysfs_entries[] = {
2747 &dev_attr_debug_level.attr, 2788 &dev_attr_debug_level.attr,
2748#endif 2789#endif
2749 &dev_attr_version.attr, 2790 &dev_attr_version.attr,
2750 &dev_attr_qos.attr,
2751 NULL 2791 NULL
2752}; 2792};
2753 2793
@@ -2791,7 +2831,7 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2791 /* Disabling hardware scan means that mac80211 will perform scans 2831 /* Disabling hardware scan means that mac80211 will perform scans
2792 * "the hard way", rather than using device's scan. */ 2832 * "the hard way", rather than using device's scan. */
2793 if (cfg->mod_params->disable_hw_scan) { 2833 if (cfg->mod_params->disable_hw_scan) {
2794 if (cfg->mod_params->debug & IWL_DL_INFO) 2834 if (iwl_debug_level & IWL_DL_INFO)
2795 dev_printk(KERN_DEBUG, &(pdev->dev), 2835 dev_printk(KERN_DEBUG, &(pdev->dev),
2796 "Disabling hw_scan\n"); 2836 "Disabling hw_scan\n");
2797 iwl_hw_ops.hw_scan = NULL; 2837 iwl_hw_ops.hw_scan = NULL;
@@ -2813,7 +2853,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
2813 priv->inta_mask = CSR_INI_SET_MASK; 2853 priv->inta_mask = CSR_INI_SET_MASK;
2814 2854
2815#ifdef CONFIG_IWLWIFI_DEBUG 2855#ifdef CONFIG_IWLWIFI_DEBUG
2816 priv->debug_level = priv->cfg->mod_params->debug;
2817 atomic_set(&priv->restrict_refcnt, 0); 2856 atomic_set(&priv->restrict_refcnt, 0);
2818#endif 2857#endif
2819 2858
@@ -3173,3 +3212,11 @@ static void __exit iwl_exit(void)
3173 3212
3174module_exit(iwl_exit); 3213module_exit(iwl_exit);
3175module_init(iwl_init); 3214module_init(iwl_init);
3215
3216#ifdef CONFIG_IWLWIFI_DEBUG
3217module_param_named(debug50, iwl_debug_level, uint, 0444);
3218MODULE_PARM_DESC(debug50, "50XX debug output mask (deprecated)");
3219module_param_named(debug, iwl_debug_level, uint, 0644);
3220MODULE_PARM_DESC(debug, "debug output mask");
3221#endif
3222
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index d5cd9a20edca..6aea02644809 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -59,6 +59,9 @@ MODULE_LICENSE("GPL");
59 IWL_RATE_##pp##M_INDEX, \ 59 IWL_RATE_##pp##M_INDEX, \
60 IWL_RATE_##np##M_INDEX } 60 IWL_RATE_##np##M_INDEX }
61 61
62u32 iwl_debug_level;
63EXPORT_SYMBOL(iwl_debug_level);
64
62static irqreturn_t iwl_isr(int irq, void *data); 65static irqreturn_t iwl_isr(int irq, void *data);
63 66
64/* 67/*
@@ -1275,7 +1278,7 @@ static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
1275 struct iwl_rxon_cmd *rxon = &priv->staging_rxon; 1278 struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
1276 1279
1277 IWL_DEBUG_RADIO(priv, "RX CONFIG:\n"); 1280 IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
1278 iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); 1281 iwl_print_hex_dump(IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
1279 IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", le16_to_cpu(rxon->channel)); 1282 IWL_DEBUG_RADIO(priv, "u16 channel: 0x%x\n", le16_to_cpu(rxon->channel));
1280 IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags)); 1283 IWL_DEBUG_RADIO(priv, "u32 flags: 0x%08X\n", le32_to_cpu(rxon->flags));
1281 IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n", 1284 IWL_DEBUG_RADIO(priv, "u32 filter_flags: 0x%08x\n",
@@ -1290,6 +1293,209 @@ static void iwl_print_rx_config_cmd(struct iwl_priv *priv)
1290} 1293}
1291#endif 1294#endif
1292 1295
1296static const char *desc_lookup_text[] = {
1297 "OK",
1298 "FAIL",
1299 "BAD_PARAM",
1300 "BAD_CHECKSUM",
1301 "NMI_INTERRUPT_WDG",
1302 "SYSASSERT",
1303 "FATAL_ERROR",
1304 "BAD_COMMAND",
1305 "HW_ERROR_TUNE_LOCK",
1306 "HW_ERROR_TEMPERATURE",
1307 "ILLEGAL_CHAN_FREQ",
1308 "VCC_NOT_STABLE",
1309 "FH_ERROR",
1310 "NMI_INTERRUPT_HOST",
1311 "NMI_INTERRUPT_ACTION_PT",
1312 "NMI_INTERRUPT_UNKNOWN",
1313 "UCODE_VERSION_MISMATCH",
1314 "HW_ERROR_ABS_LOCK",
1315 "HW_ERROR_CAL_LOCK_FAIL",
1316 "NMI_INTERRUPT_INST_ACTION_PT",
1317 "NMI_INTERRUPT_DATA_ACTION_PT",
1318 "NMI_TRM_HW_ER",
1319 "NMI_INTERRUPT_TRM",
1320 "NMI_INTERRUPT_BREAK_POINT"
1321 "DEBUG_0",
1322 "DEBUG_1",
1323 "DEBUG_2",
1324 "DEBUG_3",
1325 "UNKNOWN"
1326};
1327
1328static const char *desc_lookup(int i)
1329{
1330 int max = ARRAY_SIZE(desc_lookup_text) - 1;
1331
1332 if (i < 0 || i > max)
1333 i = max;
1334
1335 return desc_lookup_text[i];
1336}
1337
1338#define ERROR_START_OFFSET (1 * sizeof(u32))
1339#define ERROR_ELEM_SIZE (7 * sizeof(u32))
1340
1341static void iwl_dump_nic_error_log(struct iwl_priv *priv)
1342{
1343 u32 data2, line;
1344 u32 desc, time, count, base, data1;
1345 u32 blink1, blink2, ilink1, ilink2;
1346
1347 switch (priv->ucode_type) {
1348 case UCODE_RT:
1349 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
1350 break;
1351 case UCODE_INIT:
1352 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
1353 break;
1354 default:
1355 IWL_ERR(priv, "uCode image not available\n");
1356 return;
1357 }
1358
1359 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
1360 IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
1361 return;
1362 }
1363
1364 count = iwl_read_targ_mem(priv, base);
1365
1366 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
1367 IWL_ERR(priv, "Start IWL Error Log Dump:\n");
1368 IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
1369 priv->status, count);
1370 }
1371
1372 desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
1373 blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
1374 blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
1375 ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
1376 ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
1377 data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
1378 data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
1379 line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
1380 time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
1381
1382 IWL_ERR(priv, "Desc Time "
1383 "data1 data2 line\n");
1384 IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
1385 desc_lookup(desc), desc, time, data1, data2, line);
1386 IWL_ERR(priv, "blink1 blink2 ilink1 ilink2\n");
1387 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
1388 ilink1, ilink2);
1389
1390}
1391
1392#define EVENT_START_OFFSET (4 * sizeof(u32))
1393
1394/**
1395 * iwl_print_event_log - Dump error event log to syslog
1396 *
1397 */
1398static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
1399 u32 num_events, u32 mode)
1400{
1401 u32 i;
1402 u32 base; /* SRAM byte address of event log header */
1403 u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
1404 u32 ptr; /* SRAM byte address of log data */
1405 u32 ev, time, data; /* event log data */
1406
1407 if (num_events == 0)
1408 return;
1409 switch (priv->ucode_type) {
1410 case UCODE_RT:
1411 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1412 break;
1413 case UCODE_INIT:
1414 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1415 break;
1416 default:
1417 IWL_ERR(priv, "uCode image not available\n");
1418 return;
1419 }
1420
1421 if (mode == 0)
1422 event_size = 2 * sizeof(u32);
1423 else
1424 event_size = 3 * sizeof(u32);
1425
1426 ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
1427
1428 /* "time" is actually "data" for mode 0 (no timestamp).
1429 * place event id # at far right for easier visual parsing. */
1430 for (i = 0; i < num_events; i++) {
1431 ev = iwl_read_targ_mem(priv, ptr);
1432 ptr += sizeof(u32);
1433 time = iwl_read_targ_mem(priv, ptr);
1434 ptr += sizeof(u32);
1435 if (mode == 0) {
1436 /* data, ev */
1437 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
1438 } else {
1439 data = iwl_read_targ_mem(priv, ptr);
1440 ptr += sizeof(u32);
1441 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
1442 time, data, ev);
1443 }
1444 }
1445}
1446
1447void iwl_dump_nic_event_log(struct iwl_priv *priv)
1448{
1449 u32 base; /* SRAM byte address of event log header */
1450 u32 capacity; /* event log capacity in # entries */
1451 u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
1452 u32 num_wraps; /* # times uCode wrapped to top of log */
1453 u32 next_entry; /* index of next entry to be written by uCode */
1454 u32 size; /* # entries that we'll print */
1455
1456 switch (priv->ucode_type) {
1457 case UCODE_RT:
1458 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
1459 break;
1460 case UCODE_INIT:
1461 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
1462 break;
1463 default:
1464 IWL_ERR(priv, "uCode image not available\n");
1465 return;
1466 }
1467
1468 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
1469 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
1470 return;
1471 }
1472
1473 /* event log header */
1474 capacity = iwl_read_targ_mem(priv, base);
1475 mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
1476 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
1477 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
1478
1479 size = num_wraps ? capacity : next_entry;
1480
1481 /* bail out if nothing in log */
1482 if (size == 0) {
1483 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
1484 return;
1485 }
1486
1487 IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
1488 size, num_wraps);
1489
1490 /* if uCode has wrapped back to top of log, start at the oldest entry,
1491 * i.e the next one that uCode would fill. */
1492 if (num_wraps)
1493 iwl_print_event_log(priv, next_entry,
1494 capacity - next_entry, mode);
1495 /* (then/else) start at top of log */
1496 iwl_print_event_log(priv, 0, next_entry, mode);
1497
1498}
1293/** 1499/**
1294 * iwl_irq_handle_error - called for HW or SW error interrupt from card 1500 * iwl_irq_handle_error - called for HW or SW error interrupt from card
1295 */ 1501 */
@@ -1302,7 +1508,7 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1302 clear_bit(STATUS_HCMD_ACTIVE, &priv->status); 1508 clear_bit(STATUS_HCMD_ACTIVE, &priv->status);
1303 1509
1304#ifdef CONFIG_IWLWIFI_DEBUG 1510#ifdef CONFIG_IWLWIFI_DEBUG
1305 if (priv->debug_level & IWL_DL_FW_ERRORS) { 1511 if (iwl_debug_level & IWL_DL_FW_ERRORS) {
1306 iwl_dump_nic_error_log(priv); 1512 iwl_dump_nic_error_log(priv);
1307 iwl_dump_nic_event_log(priv); 1513 iwl_dump_nic_event_log(priv);
1308 iwl_print_rx_config_cmd(priv); 1514 iwl_print_rx_config_cmd(priv);
@@ -1543,31 +1749,6 @@ void iwl_uninit_drv(struct iwl_priv *priv)
1543} 1749}
1544EXPORT_SYMBOL(iwl_uninit_drv); 1750EXPORT_SYMBOL(iwl_uninit_drv);
1545 1751
1546
1547void iwl_disable_interrupts(struct iwl_priv *priv)
1548{
1549 clear_bit(STATUS_INT_ENABLED, &priv->status);
1550
1551 /* disable interrupts from uCode/NIC to host */
1552 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
1553
1554 /* acknowledge/clear/reset any interrupts still pending
1555 * from uCode or flow handler (Rx/Tx DMA) */
1556 iwl_write32(priv, CSR_INT, 0xffffffff);
1557 iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
1558 IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
1559}
1560EXPORT_SYMBOL(iwl_disable_interrupts);
1561
1562void iwl_enable_interrupts(struct iwl_priv *priv)
1563{
1564 IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
1565 set_bit(STATUS_INT_ENABLED, &priv->status);
1566 iwl_write32(priv, CSR_INT_MASK, priv->inta_mask);
1567}
1568EXPORT_SYMBOL(iwl_enable_interrupts);
1569
1570
1571#define ICT_COUNT (PAGE_SIZE/sizeof(u32)) 1752#define ICT_COUNT (PAGE_SIZE/sizeof(u32))
1572 1753
1573/* Free dram table */ 1754/* Free dram table */
@@ -1801,7 +1982,7 @@ static irqreturn_t iwl_isr(int irq, void *data)
1801 } 1982 }
1802 1983
1803#ifdef CONFIG_IWLWIFI_DEBUG 1984#ifdef CONFIG_IWLWIFI_DEBUG
1804 if (priv->debug_level & (IWL_DL_ISR)) { 1985 if (iwl_debug_level & (IWL_DL_ISR)) {
1805 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); 1986 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
1806 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, " 1987 IWL_DEBUG_ISR(priv, "ISR inta 0x%08x, enabled 0x%08x, "
1807 "fh 0x%08x\n", inta, inta_mask, inta_fh); 1988 "fh 0x%08x\n", inta, inta_mask, inta_fh);
@@ -2040,191 +2221,6 @@ int iwl_verify_ucode(struct iwl_priv *priv)
2040EXPORT_SYMBOL(iwl_verify_ucode); 2221EXPORT_SYMBOL(iwl_verify_ucode);
2041 2222
2042 2223
2043static const char *desc_lookup_text[] = {
2044 "OK",
2045 "FAIL",
2046 "BAD_PARAM",
2047 "BAD_CHECKSUM",
2048 "NMI_INTERRUPT_WDG",
2049 "SYSASSERT",
2050 "FATAL_ERROR",
2051 "BAD_COMMAND",
2052 "HW_ERROR_TUNE_LOCK",
2053 "HW_ERROR_TEMPERATURE",
2054 "ILLEGAL_CHAN_FREQ",
2055 "VCC_NOT_STABLE",
2056 "FH_ERROR",
2057 "NMI_INTERRUPT_HOST",
2058 "NMI_INTERRUPT_ACTION_PT",
2059 "NMI_INTERRUPT_UNKNOWN",
2060 "UCODE_VERSION_MISMATCH",
2061 "HW_ERROR_ABS_LOCK",
2062 "HW_ERROR_CAL_LOCK_FAIL",
2063 "NMI_INTERRUPT_INST_ACTION_PT",
2064 "NMI_INTERRUPT_DATA_ACTION_PT",
2065 "NMI_TRM_HW_ER",
2066 "NMI_INTERRUPT_TRM",
2067 "NMI_INTERRUPT_BREAK_POINT"
2068 "DEBUG_0",
2069 "DEBUG_1",
2070 "DEBUG_2",
2071 "DEBUG_3",
2072 "UNKNOWN"
2073};
2074
2075static const char *desc_lookup(int i)
2076{
2077 int max = ARRAY_SIZE(desc_lookup_text) - 1;
2078
2079 if (i < 0 || i > max)
2080 i = max;
2081
2082 return desc_lookup_text[i];
2083}
2084
2085#define ERROR_START_OFFSET (1 * sizeof(u32))
2086#define ERROR_ELEM_SIZE (7 * sizeof(u32))
2087
2088void iwl_dump_nic_error_log(struct iwl_priv *priv)
2089{
2090 u32 data2, line;
2091 u32 desc, time, count, base, data1;
2092 u32 blink1, blink2, ilink1, ilink2;
2093
2094 if (priv->ucode_type == UCODE_INIT)
2095 base = le32_to_cpu(priv->card_alive_init.error_event_table_ptr);
2096 else
2097 base = le32_to_cpu(priv->card_alive.error_event_table_ptr);
2098
2099 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
2100 IWL_ERR(priv, "Not valid error log pointer 0x%08X\n", base);
2101 return;
2102 }
2103
2104 count = iwl_read_targ_mem(priv, base);
2105
2106 if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
2107 IWL_ERR(priv, "Start IWL Error Log Dump:\n");
2108 IWL_ERR(priv, "Status: 0x%08lX, count: %d\n",
2109 priv->status, count);
2110 }
2111
2112 desc = iwl_read_targ_mem(priv, base + 1 * sizeof(u32));
2113 blink1 = iwl_read_targ_mem(priv, base + 3 * sizeof(u32));
2114 blink2 = iwl_read_targ_mem(priv, base + 4 * sizeof(u32));
2115 ilink1 = iwl_read_targ_mem(priv, base + 5 * sizeof(u32));
2116 ilink2 = iwl_read_targ_mem(priv, base + 6 * sizeof(u32));
2117 data1 = iwl_read_targ_mem(priv, base + 7 * sizeof(u32));
2118 data2 = iwl_read_targ_mem(priv, base + 8 * sizeof(u32));
2119 line = iwl_read_targ_mem(priv, base + 9 * sizeof(u32));
2120 time = iwl_read_targ_mem(priv, base + 11 * sizeof(u32));
2121
2122 IWL_ERR(priv, "Desc Time "
2123 "data1 data2 line\n");
2124 IWL_ERR(priv, "%-28s (#%02d) %010u 0x%08X 0x%08X %u\n",
2125 desc_lookup(desc), desc, time, data1, data2, line);
2126 IWL_ERR(priv, "blink1 blink2 ilink1 ilink2\n");
2127 IWL_ERR(priv, "0x%05X 0x%05X 0x%05X 0x%05X\n", blink1, blink2,
2128 ilink1, ilink2);
2129
2130}
2131EXPORT_SYMBOL(iwl_dump_nic_error_log);
2132
2133#define EVENT_START_OFFSET (4 * sizeof(u32))
2134
2135/**
2136 * iwl_print_event_log - Dump error event log to syslog
2137 *
2138 */
2139static void iwl_print_event_log(struct iwl_priv *priv, u32 start_idx,
2140 u32 num_events, u32 mode)
2141{
2142 u32 i;
2143 u32 base; /* SRAM byte address of event log header */
2144 u32 event_size; /* 2 u32s, or 3 u32s if timestamp recorded */
2145 u32 ptr; /* SRAM byte address of log data */
2146 u32 ev, time, data; /* event log data */
2147
2148 if (num_events == 0)
2149 return;
2150 if (priv->ucode_type == UCODE_INIT)
2151 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2152 else
2153 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2154
2155 if (mode == 0)
2156 event_size = 2 * sizeof(u32);
2157 else
2158 event_size = 3 * sizeof(u32);
2159
2160 ptr = base + EVENT_START_OFFSET + (start_idx * event_size);
2161
2162 /* "time" is actually "data" for mode 0 (no timestamp).
2163 * place event id # at far right for easier visual parsing. */
2164 for (i = 0; i < num_events; i++) {
2165 ev = iwl_read_targ_mem(priv, ptr);
2166 ptr += sizeof(u32);
2167 time = iwl_read_targ_mem(priv, ptr);
2168 ptr += sizeof(u32);
2169 if (mode == 0) {
2170 /* data, ev */
2171 IWL_ERR(priv, "EVT_LOG:0x%08x:%04u\n", time, ev);
2172 } else {
2173 data = iwl_read_targ_mem(priv, ptr);
2174 ptr += sizeof(u32);
2175 IWL_ERR(priv, "EVT_LOGT:%010u:0x%08x:%04u\n",
2176 time, data, ev);
2177 }
2178 }
2179}
2180
2181void iwl_dump_nic_event_log(struct iwl_priv *priv)
2182{
2183 u32 base; /* SRAM byte address of event log header */
2184 u32 capacity; /* event log capacity in # entries */
2185 u32 mode; /* 0 - no timestamp, 1 - timestamp recorded */
2186 u32 num_wraps; /* # times uCode wrapped to top of log */
2187 u32 next_entry; /* index of next entry to be written by uCode */
2188 u32 size; /* # entries that we'll print */
2189
2190 if (priv->ucode_type == UCODE_INIT)
2191 base = le32_to_cpu(priv->card_alive_init.log_event_table_ptr);
2192 else
2193 base = le32_to_cpu(priv->card_alive.log_event_table_ptr);
2194
2195 if (!priv->cfg->ops->lib->is_valid_rtc_data_addr(base)) {
2196 IWL_ERR(priv, "Invalid event log pointer 0x%08X\n", base);
2197 return;
2198 }
2199
2200 /* event log header */
2201 capacity = iwl_read_targ_mem(priv, base);
2202 mode = iwl_read_targ_mem(priv, base + (1 * sizeof(u32)));
2203 num_wraps = iwl_read_targ_mem(priv, base + (2 * sizeof(u32)));
2204 next_entry = iwl_read_targ_mem(priv, base + (3 * sizeof(u32)));
2205
2206 size = num_wraps ? capacity : next_entry;
2207
2208 /* bail out if nothing in log */
2209 if (size == 0) {
2210 IWL_ERR(priv, "Start IWL Event Log Dump: nothing in log\n");
2211 return;
2212 }
2213
2214 IWL_ERR(priv, "Start IWL Event Log Dump: display count %d, wraps %d\n",
2215 size, num_wraps);
2216
2217 /* if uCode has wrapped back to top of log, start at the oldest entry,
2218 * i.e the next one that uCode would fill. */
2219 if (num_wraps)
2220 iwl_print_event_log(priv, next_entry,
2221 capacity - next_entry, mode);
2222 /* (then/else) start at top of log */
2223 iwl_print_event_log(priv, 0, next_entry, mode);
2224
2225}
2226EXPORT_SYMBOL(iwl_dump_nic_event_log);
2227
2228void iwl_rf_kill_ct_config(struct iwl_priv *priv) 2224void iwl_rf_kill_ct_config(struct iwl_priv *priv)
2229{ 2225{
2230 struct iwl_ct_kill_config cmd; 2226 struct iwl_ct_kill_config cmd;
@@ -2293,7 +2289,7 @@ void iwl_rx_pm_debug_statistics_notif(struct iwl_priv *priv,
2293 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled " 2289 IWL_DEBUG_RADIO(priv, "Dumping %d bytes of unhandled "
2294 "notification for %s:\n", 2290 "notification for %s:\n",
2295 le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd)); 2291 le32_to_cpu(pkt->len), get_cmd_string(pkt->hdr.cmd));
2296 iwl_print_hex_dump(priv, IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len)); 2292 iwl_print_hex_dump(IWL_DL_RADIO, pkt->u.raw, le32_to_cpu(pkt->len));
2297} 2293}
2298EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif); 2294EXPORT_SYMBOL(iwl_rx_pm_debug_statistics_notif);
2299 2295
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index a658410e66a4..614ec7cc5b31 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -116,6 +116,17 @@ struct iwl_temp_ops {
116 void (*set_ct_kill)(struct iwl_priv *priv); 116 void (*set_ct_kill)(struct iwl_priv *priv);
117}; 117};
118 118
119struct iwl_ucode_ops {
120 u32 (*get_header_size)(u32);
121 u32 (*get_build)(const struct iwl_ucode_header *, u32);
122 u32 (*get_inst_size)(const struct iwl_ucode_header *, u32);
123 u32 (*get_data_size)(const struct iwl_ucode_header *, u32);
124 u32 (*get_init_size)(const struct iwl_ucode_header *, u32);
125 u32 (*get_init_data_size)(const struct iwl_ucode_header *, u32);
126 u32 (*get_boot_size)(const struct iwl_ucode_header *, u32);
127 u8 * (*get_data)(const struct iwl_ucode_header *, u32);
128};
129
119struct iwl_lib_ops { 130struct iwl_lib_ops {
120 /* set hw dependent parameters */ 131 /* set hw dependent parameters */
121 int (*set_hw_params)(struct iwl_priv *priv); 132 int (*set_hw_params)(struct iwl_priv *priv);
@@ -171,6 +182,7 @@ struct iwl_lib_ops {
171}; 182};
172 183
173struct iwl_ops { 184struct iwl_ops {
185 const struct iwl_ucode_ops *ucode;
174 const struct iwl_lib_ops *lib; 186 const struct iwl_lib_ops *lib;
175 const struct iwl_hcmd_ops *hcmd; 187 const struct iwl_hcmd_ops *hcmd;
176 const struct iwl_hcmd_utils_ops *utils; 188 const struct iwl_hcmd_utils_ops *utils;
@@ -178,7 +190,6 @@ struct iwl_ops {
178 190
179struct iwl_mod_params { 191struct iwl_mod_params {
180 int sw_crypto; /* def: 0 = using hardware encryption */ 192 int sw_crypto; /* def: 0 = using hardware encryption */
181 u32 debug; /* def: 0 = minimal debug log messages */
182 int disable_hw_scan; /* def: 0 = use h/w scan */ 193 int disable_hw_scan; /* def: 0 = use h/w scan */
183 int num_of_queues; /* def: HW dependent */ 194 int num_of_queues; /* def: HW dependent */
184 int num_of_ampdu_queues;/* def: HW dependent */ 195 int num_of_ampdu_queues;/* def: HW dependent */
@@ -447,8 +458,6 @@ int iwl_send_card_state(struct iwl_priv *priv, u32 flags,
447/***************************************************** 458/*****************************************************
448 * PCI * 459 * PCI *
449 *****************************************************/ 460 *****************************************************/
450void iwl_disable_interrupts(struct iwl_priv *priv);
451void iwl_enable_interrupts(struct iwl_priv *priv);
452irqreturn_t iwl_isr_legacy(int irq, void *data); 461irqreturn_t iwl_isr_legacy(int irq, void *data);
453int iwl_reset_ict(struct iwl_priv *priv); 462int iwl_reset_ict(struct iwl_priv *priv);
454void iwl_disable_ict(struct iwl_priv *priv); 463void iwl_disable_ict(struct iwl_priv *priv);
@@ -472,7 +481,6 @@ int iwl_pci_resume(struct pci_dev *pdev);
472/***************************************************** 481/*****************************************************
473* Error Handling Debugging 482* Error Handling Debugging
474******************************************************/ 483******************************************************/
475void iwl_dump_nic_error_log(struct iwl_priv *priv);
476void iwl_dump_nic_event_log(struct iwl_priv *priv); 484void iwl_dump_nic_event_log(struct iwl_priv *priv);
477void iwl_clear_isr_stats(struct iwl_priv *priv); 485void iwl_clear_isr_stats(struct iwl_priv *priv);
478 486
@@ -501,6 +509,8 @@ void iwlcore_free_geos(struct iwl_priv *priv);
501#define STATUS_POWER_PMI 16 509#define STATUS_POWER_PMI 16
502#define STATUS_FW_ERROR 17 510#define STATUS_FW_ERROR 17
503#define STATUS_MODE_PENDING 18 511#define STATUS_MODE_PENDING 18
512#define STATUS_INIT_UCODE_ALIVE 19
513#define STATUS_RT_UCODE_ALIVE 20
504 514
505 515
506static inline int iwl_is_ready(struct iwl_priv *priv) 516static inline int iwl_is_ready(struct iwl_priv *priv)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 65bbce0f1717..9faf0c2ff608 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -30,6 +30,7 @@
30#define __iwl_debug_h__ 30#define __iwl_debug_h__
31 31
32struct iwl_priv; 32struct iwl_priv;
33extern u32 iwl_debug_level;
33 34
34#define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a) 35#define IWL_ERR(p, f, a...) dev_err(&((p)->pci_dev->dev), f, ## a)
35#define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a) 36#define IWL_WARN(p, f, a...) dev_warn(&((p)->pci_dev->dev), f, ## a)
@@ -45,7 +46,7 @@ do { \
45#ifdef CONFIG_IWLWIFI_DEBUG 46#ifdef CONFIG_IWLWIFI_DEBUG
46#define IWL_DEBUG(__priv, level, fmt, args...) \ 47#define IWL_DEBUG(__priv, level, fmt, args...) \
47do { \ 48do { \
48 if (__priv->debug_level & (level)) \ 49 if (iwl_debug_level & (level)) \
49 dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \ 50 dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \
50 "%c %s " fmt, in_interrupt() ? 'I' : 'U', \ 51 "%c %s " fmt, in_interrupt() ? 'I' : 'U', \
51 __func__ , ## args); \ 52 __func__ , ## args); \
@@ -53,15 +54,15 @@ do { \
53 54
54#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) \ 55#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) \
55do { \ 56do { \
56 if ((__priv->debug_level & (level)) && net_ratelimit()) \ 57 if ((iwl_debug_level & (level)) && net_ratelimit()) \
57 dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \ 58 dev_printk(KERN_ERR, &(__priv->hw->wiphy->dev), \
58 "%c %s " fmt, in_interrupt() ? 'I' : 'U', \ 59 "%c %s " fmt, in_interrupt() ? 'I' : 'U', \
59 __func__ , ## args); \ 60 __func__ , ## args); \
60} while (0) 61} while (0)
61 62
62#define iwl_print_hex_dump(priv, level, p, len) \ 63#define iwl_print_hex_dump(level, p, len) \
63do { \ 64do { \
64 if (priv->debug_level & level) \ 65 if (iwl_debug_level & level) \
65 print_hex_dump(KERN_DEBUG, "iwl data: ", \ 66 print_hex_dump(KERN_DEBUG, "iwl data: ", \
66 DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \ 67 DUMP_PREFIX_OFFSET, 16, 1, p, len, 1); \
67} while (0) 68} while (0)
@@ -82,6 +83,10 @@ struct iwl_debugfs {
82 struct dentry *file_channels; 83 struct dentry *file_channels;
83 struct dentry *file_status; 84 struct dentry *file_status;
84 struct dentry *file_interrupt; 85 struct dentry *file_interrupt;
86 struct dentry *file_qos;
87#ifdef CONFIG_IWLWIFI_LEDS
88 struct dentry *file_led;
89#endif
85 } dbgfs_data_files; 90 } dbgfs_data_files;
86 struct dir_rf_files { 91 struct dir_rf_files {
87 struct dentry *file_disable_sensitivity; 92 struct dentry *file_disable_sensitivity;
@@ -99,8 +104,7 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv);
99#else 104#else
100#define IWL_DEBUG(__priv, level, fmt, args...) 105#define IWL_DEBUG(__priv, level, fmt, args...)
101#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...) 106#define IWL_DEBUG_LIMIT(__priv, level, fmt, args...)
102static inline void iwl_print_hex_dump(struct iwl_priv *priv, int level, 107static inline void iwl_print_hex_dump(int level, void *p, u32 len)
103 void *p, u32 len)
104{} 108{}
105#endif /* CONFIG_IWLWIFI_DEBUG */ 109#endif /* CONFIG_IWLWIFI_DEBUG */
106 110
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index f32ac74b69ac..0ab3463aa07e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -49,7 +49,8 @@
49 49
50#define DEBUGFS_ADD_FILE(name, parent) do { \ 50#define DEBUGFS_ADD_FILE(name, parent) do { \
51 dbgfs->dbgfs_##parent##_files.file_##name = \ 51 dbgfs->dbgfs_##parent##_files.file_##name = \
52 debugfs_create_file(#name, 0644, dbgfs->dir_##parent, priv, \ 52 debugfs_create_file(#name, S_IWUSR | S_IRUSR, \
53 dbgfs->dir_##parent, priv, \
53 &iwl_dbgfs_##name##_ops); \ 54 &iwl_dbgfs_##name##_ops); \
54 if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \ 55 if (!(dbgfs->dbgfs_##parent##_files.file_##name)) \
55 goto err; \ 56 goto err; \
@@ -57,7 +58,8 @@
57 58
58#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \ 59#define DEBUGFS_ADD_BOOL(name, parent, ptr) do { \
59 dbgfs->dbgfs_##parent##_files.file_##name = \ 60 dbgfs->dbgfs_##parent##_files.file_##name = \
60 debugfs_create_bool(#name, 0644, dbgfs->dir_##parent, ptr); \ 61 debugfs_create_bool(#name, S_IWUSR | S_IRUSR, \
62 dbgfs->dir_##parent, ptr); \
61 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 63 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
62 || !dbgfs->dbgfs_##parent##_files.file_##name) \ 64 || !dbgfs->dbgfs_##parent##_files.file_##name) \
63 goto err; \ 65 goto err; \
@@ -65,7 +67,7 @@
65 67
66#define DEBUGFS_ADD_X32(name, parent, ptr) do { \ 68#define DEBUGFS_ADD_X32(name, parent, ptr) do { \
67 dbgfs->dbgfs_##parent##_files.file_##name = \ 69 dbgfs->dbgfs_##parent##_files.file_##name = \
68 debugfs_create_x32(#name, 0444, dbgfs->dir_##parent, ptr); \ 70 debugfs_create_x32(#name, S_IRUSR, dbgfs->dir_##parent, ptr); \
69 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \ 71 if (IS_ERR(dbgfs->dbgfs_##parent##_files.file_##name) \
70 || !dbgfs->dbgfs_##parent##_files.file_##name) \ 72 || !dbgfs->dbgfs_##parent##_files.file_##name) \
71 goto err; \ 73 goto err; \
@@ -566,6 +568,55 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
566 return count; 568 return count;
567} 569}
568 570
571static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
572 size_t count, loff_t *ppos)
573{
574 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
575 int pos = 0, i;
576 char buf[256];
577 const size_t bufsz = sizeof(buf);
578 ssize_t ret;
579
580 for (i = 0; i < AC_NUM; i++) {
581 pos += scnprintf(buf + pos, bufsz - pos,
582 "\tcw_min\tcw_max\taifsn\ttxop\n");
583 pos += scnprintf(buf + pos, bufsz - pos,
584 "AC[%d]\t%u\t%u\t%u\t%u\n", i,
585 priv->qos_data.def_qos_parm.ac[i].cw_min,
586 priv->qos_data.def_qos_parm.ac[i].cw_max,
587 priv->qos_data.def_qos_parm.ac[i].aifsn,
588 priv->qos_data.def_qos_parm.ac[i].edca_txop);
589 }
590 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
591 return ret;
592}
593
594#ifdef CONFIG_IWLWIFI_LEDS
595static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
596 size_t count, loff_t *ppos)
597{
598 struct iwl_priv *priv = (struct iwl_priv *)file->private_data;
599 int pos = 0;
600 char buf[256];
601 const size_t bufsz = sizeof(buf);
602 ssize_t ret;
603
604 pos += scnprintf(buf + pos, bufsz - pos,
605 "allow blinking: %s\n",
606 (priv->allow_blinking) ? "True" : "False");
607 if (priv->allow_blinking) {
608 pos += scnprintf(buf + pos, bufsz - pos,
609 "Led blinking rate: %u\n",
610 priv->last_blink_rate);
611 pos += scnprintf(buf + pos, bufsz - pos,
612 "Last blink time: %lu\n",
613 priv->last_blink_time);
614 }
615
616 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
617 return ret;
618}
619#endif
569 620
570DEBUGFS_READ_WRITE_FILE_OPS(sram); 621DEBUGFS_READ_WRITE_FILE_OPS(sram);
571DEBUGFS_WRITE_FILE_OPS(log_event); 622DEBUGFS_WRITE_FILE_OPS(log_event);
@@ -576,6 +627,10 @@ DEBUGFS_READ_FILE_OPS(tx_statistics);
576DEBUGFS_READ_FILE_OPS(channels); 627DEBUGFS_READ_FILE_OPS(channels);
577DEBUGFS_READ_FILE_OPS(status); 628DEBUGFS_READ_FILE_OPS(status);
578DEBUGFS_READ_WRITE_FILE_OPS(interrupt); 629DEBUGFS_READ_WRITE_FILE_OPS(interrupt);
630DEBUGFS_READ_FILE_OPS(qos);
631#ifdef CONFIG_IWLWIFI_LEDS
632DEBUGFS_READ_FILE_OPS(led);
633#endif
579 634
580/* 635/*
581 * Create the debugfs files and directories 636 * Create the debugfs files and directories
@@ -612,6 +667,10 @@ int iwl_dbgfs_register(struct iwl_priv *priv, const char *name)
612 DEBUGFS_ADD_FILE(channels, data); 667 DEBUGFS_ADD_FILE(channels, data);
613 DEBUGFS_ADD_FILE(status, data); 668 DEBUGFS_ADD_FILE(status, data);
614 DEBUGFS_ADD_FILE(interrupt, data); 669 DEBUGFS_ADD_FILE(interrupt, data);
670 DEBUGFS_ADD_FILE(qos, data);
671#ifdef CONFIG_IWLWIFI_LEDS
672 DEBUGFS_ADD_FILE(led, data);
673#endif
615 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal); 674 DEBUGFS_ADD_BOOL(disable_sensitivity, rf, &priv->disable_sens_cal);
616 DEBUGFS_ADD_BOOL(disable_chain_noise, rf, 675 DEBUGFS_ADD_BOOL(disable_chain_noise, rf,
617 &priv->disable_chain_noise_cal); 676 &priv->disable_chain_noise_cal);
@@ -646,6 +705,10 @@ void iwl_dbgfs_unregister(struct iwl_priv *priv)
646 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels); 705 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_channels);
647 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status); 706 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_status);
648 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt); 707 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_interrupt);
708 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_qos);
709#ifdef CONFIG_IWLWIFI_LEDS
710 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_data_files.file_led);
711#endif
649 DEBUGFS_REMOVE(priv->dbgfs->dir_data); 712 DEBUGFS_REMOVE(priv->dbgfs->dir_data);
650 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity); 713 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_sensitivity);
651 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise); 714 DEBUGFS_REMOVE(priv->dbgfs->dbgfs_rf_files.file_disable_chain_noise);
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 1a2fe37d4735..0751891f4ab7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -66,6 +66,7 @@ extern struct iwl_cfg iwl1000_bgn_cfg;
66/* shared structures from iwl-5000.c */ 66/* shared structures from iwl-5000.c */
67extern struct iwl_mod_params iwl50_mod_params; 67extern struct iwl_mod_params iwl50_mod_params;
68extern struct iwl_ops iwl5000_ops; 68extern struct iwl_ops iwl5000_ops;
69extern struct iwl_ucode_ops iwl5000_ucode;
69extern struct iwl_lib_ops iwl5000_lib; 70extern struct iwl_lib_ops iwl5000_lib;
70extern struct iwl_hcmd_ops iwl5000_hcmd; 71extern struct iwl_hcmd_ops iwl5000_hcmd;
71extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils; 72extern struct iwl_hcmd_utils_ops iwl5000_hcmd_utils;
@@ -258,8 +259,10 @@ struct iwl_channel_info {
258#define IWL_TX_FIFO_HCCA_2 6 259#define IWL_TX_FIFO_HCCA_2 6
259#define IWL_TX_FIFO_NONE 7 260#define IWL_TX_FIFO_NONE 7
260 261
261/* Minimum number of queues. MAX_NUM is defined in hw specific files */ 262/* Minimum number of queues. MAX_NUM is defined in hw specific files.
262#define IWL_MIN_NUM_QUEUES 4 263 * Set the minimum to accommodate the 4 standard TX queues, 1 command
264 * queue, 2 (unused) HCCA queues, and 4 HT queues (one for each AC) */
265#define IWL_MIN_NUM_QUEUES 10
263 266
264/* Power management (not Tx power) structures */ 267/* Power management (not Tx power) structures */
265 268
@@ -523,15 +526,29 @@ struct fw_desc {
523}; 526};
524 527
525/* uCode file layout */ 528/* uCode file layout */
526struct iwl_ucode { 529struct iwl_ucode_header {
527 __le32 ver; /* major/minor/API/serial */ 530 __le32 ver; /* major/minor/API/serial */
528 __le32 inst_size; /* bytes of runtime instructions */ 531 union {
529 __le32 data_size; /* bytes of runtime data */ 532 struct {
530 __le32 init_size; /* bytes of initialization instructions */ 533 __le32 inst_size; /* bytes of runtime code */
531 __le32 init_data_size; /* bytes of initialization data */ 534 __le32 data_size; /* bytes of runtime data */
532 __le32 boot_size; /* bytes of bootstrap instructions */ 535 __le32 init_size; /* bytes of init code */
533 u8 data[0]; /* data in same order as "size" elements */ 536 __le32 init_data_size; /* bytes of init data */
537 __le32 boot_size; /* bytes of bootstrap code */
538 u8 data[0]; /* in same order as sizes */
539 } v1;
540 struct {
541 __le32 build; /* build number */
542 __le32 inst_size; /* bytes of runtime code */
543 __le32 data_size; /* bytes of runtime data */
544 __le32 init_size; /* bytes of init code */
545 __le32 init_data_size; /* bytes of init data */
546 __le32 boot_size; /* bytes of bootstrap code */
547 u8 data[0]; /* in same order as sizes */
548 } v2;
549 } u;
534}; 550};
551#define UCODE_HEADER_SIZE(ver) ((ver) == 1 ? 24 : 28)
535 552
536struct iwl4965_ibss_seq { 553struct iwl4965_ibss_seq {
537 u8 mac[ETH_ALEN]; 554 u8 mac[ETH_ALEN];
@@ -755,6 +772,8 @@ struct iwl_calib_result {
755 size_t buf_len; 772 size_t buf_len;
756}; 773};
757 774
775#define UCODE_ALIVE_TIMEOUT (5 * HZ)
776
758enum ucode_type { 777enum ucode_type {
759 UCODE_NONE = 0, 778 UCODE_NONE = 0,
760 UCODE_INIT, 779 UCODE_INIT,
@@ -1092,7 +1111,6 @@ struct iwl_priv {
1092 1111
1093#ifdef CONFIG_IWLWIFI_DEBUG 1112#ifdef CONFIG_IWLWIFI_DEBUG
1094 /* debugging info */ 1113 /* debugging info */
1095 u32 debug_level;
1096 u32 framecnt_to_us; 1114 u32 framecnt_to_us;
1097 atomic_t restrict_refcnt; 1115 atomic_t restrict_refcnt;
1098#ifdef CONFIG_IWLWIFI_DEBUGFS 1116#ifdef CONFIG_IWLWIFI_DEBUGFS
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 7d7554a2f341..51eed7226669 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -159,6 +159,9 @@ static int iwlcore_get_nvm_type(struct iwl_priv *priv)
159 159
160 /* OTP only valid for CP/PP and after */ 160 /* OTP only valid for CP/PP and after */
161 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) { 161 switch (priv->hw_rev & CSR_HW_REV_TYPE_MSK) {
162 case CSR_HW_REV_TYPE_NONE:
163 IWL_ERR(priv, "Unknown hardware type\n");
164 return -ENOENT;
162 case CSR_HW_REV_TYPE_3945: 165 case CSR_HW_REV_TYPE_3945:
163 case CSR_HW_REV_TYPE_4965: 166 case CSR_HW_REV_TYPE_4965:
164 case CSR_HW_REV_TYPE_5300: 167 case CSR_HW_REV_TYPE_5300:
@@ -266,7 +269,8 @@ int iwl_eeprom_init(struct iwl_priv *priv)
266 u32 otpgp; 269 u32 otpgp;
267 270
268 priv->nvm_device_type = iwlcore_get_nvm_type(priv); 271 priv->nvm_device_type = iwlcore_get_nvm_type(priv);
269 272 if (priv->nvm_device_type == -ENOENT)
273 return -ENOENT;
270 /* allocate eeprom */ 274 /* allocate eeprom */
271 if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP) 275 if (priv->nvm_device_type == NVM_DEVICE_TYPE_OTP)
272 priv->cfg->eeprom_size = 276 priv->cfg->eeprom_size =
diff --git a/drivers/net/wireless/iwlwifi/iwl-helpers.h b/drivers/net/wireless/iwlwifi/iwl-helpers.h
index a1328c3c81ae..bd0b12efb5c7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-helpers.h
+++ b/drivers/net/wireless/iwlwifi/iwl-helpers.h
@@ -145,4 +145,25 @@ static inline void iwl_stop_queue(struct iwl_priv *priv, u8 queue)
145#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue 145#define ieee80211_stop_queue DO_NOT_USE_ieee80211_stop_queue
146#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue 146#define ieee80211_wake_queue DO_NOT_USE_ieee80211_wake_queue
147 147
148static inline void iwl_disable_interrupts(struct iwl_priv *priv)
149{
150 clear_bit(STATUS_INT_ENABLED, &priv->status);
151
152 /* disable interrupts from uCode/NIC to host */
153 iwl_write32(priv, CSR_INT_MASK, 0x00000000);
154
155 /* acknowledge/clear/reset any interrupts still pending
156 * from uCode or flow handler (Rx/Tx DMA) */
157 iwl_write32(priv, CSR_INT, 0xffffffff);
158 iwl_write32(priv, CSR_FH_INT_STATUS, 0xffffffff);
159 IWL_DEBUG_ISR(priv, "Disabled interrupts\n");
160}
161
162static inline void iwl_enable_interrupts(struct iwl_priv *priv)
163{
164 IWL_DEBUG_ISR(priv, "Enabling interrupts\n");
165 set_bit(STATUS_INT_ENABLED, &priv->status);
166 iwl_write32(priv, CSR_INT_MASK, priv->inta_mask);
167}
168
148#endif /* __iwl_helpers_h__ */ 169#endif /* __iwl_helpers_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-led.c b/drivers/net/wireless/iwlwifi/iwl-led.c
index 5e64252f80f6..8c8115293b3c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-led.c
+++ b/drivers/net/wireless/iwlwifi/iwl-led.c
@@ -54,7 +54,7 @@ static const char *led_type_str[] = {
54 54
55 55
56static const struct { 56static const struct {
57 u16 tpt; 57 u16 tpt; /* Mb/s */
58 u8 on_time; 58 u8 on_time;
59 u8 off_time; 59 u8 off_time;
60} blink_tbl[] = 60} blink_tbl[] =
@@ -104,7 +104,7 @@ static int iwl_send_led_cmd(struct iwl_priv *priv, struct iwl_led_cmd *led_cmd)
104} 104}
105 105
106/* Set led pattern command */ 106/* Set led pattern command */
107static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id, 107static int iwl_led_pattern(struct iwl_priv *priv, int led_id,
108 unsigned int idx) 108 unsigned int idx)
109{ 109{
110 struct iwl_led_cmd led_cmd = { 110 struct iwl_led_cmd led_cmd = {
@@ -121,7 +121,7 @@ static int iwl4965_led_pattern(struct iwl_priv *priv, int led_id,
121} 121}
122 122
123/* Set led register off */ 123/* Set led register off */
124static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id) 124static int iwl_led_on_reg(struct iwl_priv *priv, int led_id)
125{ 125{
126 IWL_DEBUG_LED(priv, "led on %d\n", led_id); 126 IWL_DEBUG_LED(priv, "led on %d\n", led_id);
127 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON); 127 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_ON);
@@ -130,7 +130,7 @@ static int iwl4965_led_on_reg(struct iwl_priv *priv, int led_id)
130 130
131#if 0 131#if 0
132/* Set led on command */ 132/* Set led on command */
133static int iwl4965_led_on(struct iwl_priv *priv, int led_id) 133static int iwl_led_on(struct iwl_priv *priv, int led_id)
134{ 134{
135 struct iwl_led_cmd led_cmd = { 135 struct iwl_led_cmd led_cmd = {
136 .id = led_id, 136 .id = led_id,
@@ -142,7 +142,7 @@ static int iwl4965_led_on(struct iwl_priv *priv, int led_id)
142} 142}
143 143
144/* Set led off command */ 144/* Set led off command */
145int iwl4965_led_off(struct iwl_priv *priv, int led_id) 145int iwl_led_off(struct iwl_priv *priv, int led_id)
146{ 146{
147 struct iwl_led_cmd led_cmd = { 147 struct iwl_led_cmd led_cmd = {
148 .id = led_id, 148 .id = led_id,
@@ -157,7 +157,7 @@ int iwl4965_led_off(struct iwl_priv *priv, int led_id)
157 157
158 158
159/* Set led register off */ 159/* Set led register off */
160static int iwl4965_led_off_reg(struct iwl_priv *priv, int led_id) 160static int iwl_led_off_reg(struct iwl_priv *priv, int led_id)
161{ 161{
162 IWL_DEBUG_LED(priv, "LED Reg off\n"); 162 IWL_DEBUG_LED(priv, "LED Reg off\n");
163 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF); 163 iwl_write32(priv, CSR_LED_REG, CSR_LED_REG_TRUN_OFF);
@@ -171,7 +171,7 @@ static int iwl_led_associate(struct iwl_priv *priv, int led_id)
171{ 171{
172 IWL_DEBUG_LED(priv, "Associated\n"); 172 IWL_DEBUG_LED(priv, "Associated\n");
173 priv->allow_blinking = 1; 173 priv->allow_blinking = 1;
174 return iwl4965_led_on_reg(priv, led_id); 174 return iwl_led_on_reg(priv, led_id);
175} 175}
176static int iwl_led_disassociate(struct iwl_priv *priv, int led_id) 176static int iwl_led_disassociate(struct iwl_priv *priv, int led_id)
177{ 177{
@@ -264,13 +264,15 @@ static int iwl_leds_register_led(struct iwl_priv *priv, struct iwl_led *led,
264 264
265 265
266/* 266/*
267 * calculate blink rate according to last 2 sec Tx/Rx activities 267 * calculate blink rate according to last second Tx/Rx activities
268 */ 268 */
269static int iwl_get_blink_rate(struct iwl_priv *priv) 269static int iwl_get_blink_rate(struct iwl_priv *priv)
270{ 270{
271 int i; 271 int i;
272 u64 current_tpt = priv->tx_stats[2].bytes; 272 /* count both tx and rx traffic to be able to
273 /* FIXME: + priv->rx_stats[2].bytes; */ 273 * handle traffic in either direction
274 */
275 u64 current_tpt = priv->tx_stats[2].bytes + priv->rx_stats[2].bytes;
274 s64 tpt = current_tpt - priv->led_tpt; 276 s64 tpt = current_tpt - priv->led_tpt;
275 277
276 if (tpt < 0) /* wraparound */ 278 if (tpt < 0) /* wraparound */
@@ -314,7 +316,7 @@ void iwl_leds_background(struct iwl_priv *priv)
314 priv->last_blink_time = 0; 316 priv->last_blink_time = 0;
315 if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) { 317 if (priv->last_blink_rate != IWL_SOLID_BLINK_IDX) {
316 priv->last_blink_rate = IWL_SOLID_BLINK_IDX; 318 priv->last_blink_rate = IWL_SOLID_BLINK_IDX;
317 iwl4965_led_pattern(priv, IWL_LED_LINK, 319 iwl_led_pattern(priv, IWL_LED_LINK,
318 IWL_SOLID_BLINK_IDX); 320 IWL_SOLID_BLINK_IDX);
319 } 321 }
320 return; 322 return;
@@ -328,7 +330,7 @@ void iwl_leds_background(struct iwl_priv *priv)
328 330
329 /* call only if blink rate change */ 331 /* call only if blink rate change */
330 if (blink_idx != priv->last_blink_rate) 332 if (blink_idx != priv->last_blink_rate)
331 iwl4965_led_pattern(priv, IWL_LED_LINK, blink_idx); 333 iwl_led_pattern(priv, IWL_LED_LINK, blink_idx);
332 334
333 priv->last_blink_time = jiffies; 335 priv->last_blink_time = jiffies;
334 priv->last_blink_rate = blink_idx; 336 priv->last_blink_rate = blink_idx;
@@ -351,8 +353,8 @@ int iwl_leds_register(struct iwl_priv *priv)
351 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio", 353 sizeof(priv->led[IWL_LED_TRG_RADIO].name), "iwl-%s::radio",
352 wiphy_name(priv->hw->wiphy)); 354 wiphy_name(priv->hw->wiphy));
353 355
354 priv->led[IWL_LED_TRG_RADIO].led_on = iwl4965_led_on_reg; 356 priv->led[IWL_LED_TRG_RADIO].led_on = iwl_led_on_reg;
355 priv->led[IWL_LED_TRG_RADIO].led_off = iwl4965_led_off_reg; 357 priv->led[IWL_LED_TRG_RADIO].led_off = iwl_led_off_reg;
356 priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL; 358 priv->led[IWL_LED_TRG_RADIO].led_pattern = NULL;
357 359
358 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO], 360 ret = iwl_leds_register_led(priv, &priv->led[IWL_LED_TRG_RADIO],
@@ -386,7 +388,7 @@ int iwl_leds_register(struct iwl_priv *priv)
386 388
387 priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated; 389 priv->led[IWL_LED_TRG_RX].led_on = iwl_led_associated;
388 priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated; 390 priv->led[IWL_LED_TRG_RX].led_off = iwl_led_associated;
389 priv->led[IWL_LED_TRG_RX].led_pattern = iwl4965_led_pattern; 391 priv->led[IWL_LED_TRG_RX].led_pattern = iwl_led_pattern;
390 392
391 if (ret) 393 if (ret)
392 goto exit_fail; 394 goto exit_fail;
@@ -401,7 +403,7 @@ int iwl_leds_register(struct iwl_priv *priv)
401 403
402 priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated; 404 priv->led[IWL_LED_TRG_TX].led_on = iwl_led_associated;
403 priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated; 405 priv->led[IWL_LED_TRG_TX].led_off = iwl_led_associated;
404 priv->led[IWL_LED_TRG_TX].led_pattern = iwl4965_led_pattern; 406 priv->led[IWL_LED_TRG_TX].led_pattern = iwl_led_pattern;
405 407
406 if (ret) 408 if (ret)
407 goto exit_fail; 409 goto exit_fail;
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 3b9cac3fd216..d393e8f02102 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -80,6 +80,8 @@
80#define APMG_RFKILL_REG (APMG_BASE + 0x0014) 80#define APMG_RFKILL_REG (APMG_BASE + 0x0014)
81#define APMG_RTC_INT_STT_REG (APMG_BASE + 0x001c) 81#define APMG_RTC_INT_STT_REG (APMG_BASE + 0x001c)
82#define APMG_RTC_INT_MSK_REG (APMG_BASE + 0x0020) 82#define APMG_RTC_INT_MSK_REG (APMG_BASE + 0x0020)
83#define APMG_DIGITAL_SVR_REG (APMG_BASE + 0x0058)
84#define APMG_ANALOG_SVR_REG (APMG_BASE + 0x006C)
83 85
84#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200) 86#define APMG_CLK_VAL_DMA_CLK_RQT (0x00000200)
85#define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800) 87#define APMG_CLK_VAL_BSM_CLK_RQT (0x00000800)
@@ -91,7 +93,8 @@
91#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000) 93#define APMG_PS_CTRL_VAL_PWR_SRC_VMAIN (0x00000000)
92#define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */ 94#define APMG_PS_CTRL_VAL_PWR_SRC_MAX (0x01000000) /* 3945 only */
93#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000) 95#define APMG_PS_CTRL_VAL_PWR_SRC_VAUX (0x02000000)
94 96#define APMG_SVR_VOLTAGE_CONFIG_BIT_MSK (0x000001E0) /* bit 8:5 */
97#define APMG_SVR_DIGITAL_VOLTAGE_1_32 (0x00000060)
95 98
96#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800) 99#define APMG_PCIDEV_STT_VAL_L1_ACT_DIS (0x00000800)
97 100
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 66fe365dd08a..5d5f2153f445 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -646,7 +646,7 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
646 u32 tsf_low; 646 u32 tsf_low;
647 int rssi; 647 int rssi;
648 648
649 if (likely(!(priv->debug_level & IWL_DL_RX))) 649 if (likely(!(iwl_debug_level & IWL_DL_RX)))
650 return; 650 return;
651 651
652 /* MAC header */ 652 /* MAC header */
@@ -742,7 +742,7 @@ static void iwl_dbg_report_frame(struct iwl_priv *priv,
742 } 742 }
743 } 743 }
744 if (print_dump) 744 if (print_dump)
745 iwl_print_hex_dump(priv, IWL_DL_RX, header, length); 745 iwl_print_hex_dump(IWL_DL_RX, header, length);
746} 746}
747#endif 747#endif
748 748
@@ -1061,11 +1061,11 @@ void iwl_rx_reply_rx(struct iwl_priv *priv,
1061 1061
1062 /* Set "1" to report good data frames in groups of 100 */ 1062 /* Set "1" to report good data frames in groups of 100 */
1063#ifdef CONFIG_IWLWIFI_DEBUG 1063#ifdef CONFIG_IWLWIFI_DEBUG
1064 if (unlikely(priv->debug_level & IWL_DL_RX)) 1064 if (unlikely(iwl_debug_level & IWL_DL_RX))
1065 iwl_dbg_report_frame(priv, rx_start, len, header, 1); 1065 iwl_dbg_report_frame(priv, rx_start, len, header, 1);
1066#endif 1066#endif
1067 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n", 1067 IWL_DEBUG_STATS_LIMIT(priv, "Rssi %d, noise %d, qual %d, TSF %llu\n",
1068 rx_status.signal, rx_status.noise, rx_status.signal, 1068 rx_status.signal, rx_status.noise, rx_status.qual,
1069 (unsigned long long)rx_status.mactime); 1069 (unsigned long long)rx_status.mactime);
1070 1070
1071 /* 1071 /*
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 2addf735b193..cbe4e26d053f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -566,6 +566,8 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
566 unsigned long flags; 566 unsigned long flags;
567 567
568 spin_lock_irqsave(&priv->sta_lock, flags); 568 spin_lock_irqsave(&priv->sta_lock, flags);
569 IWL_DEBUG_WEP(priv, "Removing default WEP key: idx=%d\n",
570 keyconf->keyidx);
569 571
570 if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table)) 572 if (!test_and_clear_bit(keyconf->keyidx, &priv->ucode_key_table))
571 IWL_ERR(priv, "index %d not used in uCode key table.\n", 573 IWL_ERR(priv, "index %d not used in uCode key table.\n",
@@ -573,6 +575,11 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
573 575
574 priv->default_wep_key--; 576 priv->default_wep_key--;
575 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0])); 577 memset(&priv->wep_keys[keyconf->keyidx], 0, sizeof(priv->wep_keys[0]));
578 if (iwl_is_rfkill(priv)) {
579 IWL_DEBUG_WEP(priv, "Not sending REPLY_WEPKEY command due to RFKILL.\n");
580 spin_unlock_irqrestore(&priv->sta_lock, flags);
581 return 0;
582 }
576 ret = iwl_send_static_wepkey_cmd(priv, 1); 583 ret = iwl_send_static_wepkey_cmd(priv, 1);
577 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n", 584 IWL_DEBUG_WEP(priv, "Remove default WEP key: idx=%d ret=%d\n",
578 keyconf->keyidx, ret); 585 keyconf->keyidx, ret);
@@ -853,6 +860,11 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
853 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 860 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
854 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 861 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
855 862
863 if (iwl_is_rfkill(priv)) {
864 IWL_DEBUG_WEP(priv, "Not sending REPLY_ADD_STA command because RFKILL enabled. \n");
865 spin_unlock_irqrestore(&priv->sta_lock, flags);
866 return 0;
867 }
856 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 868 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
857 spin_unlock_irqrestore(&priv->sta_lock, flags); 869 spin_unlock_irqrestore(&priv->sta_lock, flags);
858 return ret; 870 return ret;
@@ -1044,11 +1056,10 @@ EXPORT_SYMBOL(iwl_rxon_add_station);
1044int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr) 1056int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1045{ 1057{
1046 int sta_id; 1058 int sta_id;
1047 u16 fc = le16_to_cpu(hdr->frame_control); 1059 __le16 fc = hdr->frame_control;
1048 1060
1049 /* If this frame is broadcast or management, use broadcast station id */ 1061 /* If this frame is broadcast or management, use broadcast station id */
1050 if (((fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA) || 1062 if (!ieee80211_is_data(fc) || is_multicast_ether_addr(hdr->addr1))
1051 is_multicast_ether_addr(hdr->addr1))
1052 return priv->hw_params.bcast_sta_id; 1063 return priv->hw_params.bcast_sta_id;
1053 1064
1054 switch (priv->iw_mode) { 1065 switch (priv->iw_mode) {
@@ -1082,7 +1093,7 @@ int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr)
1082 IWL_DEBUG_DROP(priv, "Station %pM not in station map. " 1093 IWL_DEBUG_DROP(priv, "Station %pM not in station map. "
1083 "Defaulting to broadcast...\n", 1094 "Defaulting to broadcast...\n",
1084 hdr->addr1); 1095 hdr->addr1);
1085 iwl_print_hex_dump(priv, IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr)); 1096 iwl_print_hex_dump(IWL_DL_DROP, (u8 *) hdr, sizeof(*hdr));
1086 return priv->hw_params.bcast_sta_id; 1097 return priv->hw_params.bcast_sta_id;
1087 1098
1088 default: 1099 default:
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c
index 7073069a61a9..0912987af603 100644
--- a/drivers/net/wireless/iwlwifi/iwl-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-tx.c
@@ -869,8 +869,8 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
869 IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n", 869 IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
870 le16_to_cpu(out_cmd->hdr.sequence)); 870 le16_to_cpu(out_cmd->hdr.sequence));
871 IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags)); 871 IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx_cmd->tx_flags));
872 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd)); 872 iwl_print_hex_dump(IWL_DL_TX, (u8 *)tx_cmd, sizeof(*tx_cmd));
873 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len); 873 iwl_print_hex_dump(IWL_DL_TX, (u8 *)tx_cmd->hdr, hdr_len);
874 874
875 /* Set up entry for this TFD in Tx byte-count array */ 875 /* Set up entry for this TFD in Tx byte-count array */
876 if (info->flags & IEEE80211_TX_CTL_AMPDU) 876 if (info->flags & IEEE80211_TX_CTL_AMPDU)
@@ -940,7 +940,7 @@ int iwl_enqueue_hcmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
940 !(cmd->meta.flags & CMD_SIZE_HUGE)); 940 !(cmd->meta.flags & CMD_SIZE_HUGE));
941 941
942 if (iwl_is_rfkill(priv)) { 942 if (iwl_is_rfkill(priv)) {
943 IWL_DEBUG_INFO(priv, "Not sending command - RF KILL"); 943 IWL_DEBUG_INFO(priv, "Not sending command - RF KILL\n");
944 return -EIO; 944 return -EIO;
945 } 945 }
946 946
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 7ff95f80b817..2cc7e30d7743 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -89,7 +89,7 @@ MODULE_LICENSE("GPL");
89 89
90 /* module parameters */ 90 /* module parameters */
91struct iwl_mod_params iwl3945_mod_params = { 91struct iwl_mod_params iwl3945_mod_params = {
92 .num_of_queues = IWL39_MAX_NUM_QUEUES, 92 .num_of_queues = IWL39_NUM_QUEUES, /* Not used */
93 .sw_crypto = 1, 93 .sw_crypto = 1,
94 .restart_fw = 1, 94 .restart_fw = 1,
95 /* the rest are 0 by default */ 95 /* the rest are 0 by default */
@@ -612,8 +612,8 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
612 IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n", 612 IWL_DEBUG_TX(priv, "sequence nr = 0X%x \n",
613 le16_to_cpu(out_cmd->hdr.sequence)); 613 le16_to_cpu(out_cmd->hdr.sequence));
614 IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx->tx_flags)); 614 IWL_DEBUG_TX(priv, "tx_flags = 0X%x \n", le32_to_cpu(tx->tx_flags));
615 iwl_print_hex_dump(priv, IWL_DL_TX, tx, sizeof(*tx)); 615 iwl_print_hex_dump(IWL_DL_TX, tx, sizeof(*tx));
616 iwl_print_hex_dump(priv, IWL_DL_TX, (u8 *)tx->hdr, 616 iwl_print_hex_dump(IWL_DL_TX, (u8 *)tx->hdr,
617 ieee80211_hdrlen(fc)); 617 ieee80211_hdrlen(fc));
618 618
619 /* 619 /*
@@ -926,7 +926,7 @@ static void iwl3945_rx_card_state_notif(struct iwl_priv *priv,
926 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags); 926 u32 flags = le32_to_cpu(pkt->u.card_state_notif.flags);
927 unsigned long status = priv->status; 927 unsigned long status = priv->status;
928 928
929 IWL_DEBUG_RF_KILL(priv, "Card state received: HW:%s SW:%s\n", 929 IWL_WARN(priv, "Card state received: HW:%s SW:%s\n",
930 (flags & HW_CARD_DISABLED) ? "Kill" : "On", 930 (flags & HW_CARD_DISABLED) ? "Kill" : "On",
931 (flags & SW_CARD_DISABLED) ? "Kill" : "On"); 931 (flags & SW_CARD_DISABLED) ? "Kill" : "On");
932 932
@@ -1644,7 +1644,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1644 iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh); 1644 iwl_write32(priv, CSR_FH_INT_STATUS, inta_fh);
1645 1645
1646#ifdef CONFIG_IWLWIFI_DEBUG 1646#ifdef CONFIG_IWLWIFI_DEBUG
1647 if (priv->debug_level & IWL_DL_ISR) { 1647 if (iwl_debug_level & IWL_DL_ISR) {
1648 /* just for debug */ 1648 /* just for debug */
1649 inta_mask = iwl_read32(priv, CSR_INT_MASK); 1649 inta_mask = iwl_read32(priv, CSR_INT_MASK);
1650 IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n", 1650 IWL_DEBUG_ISR(priv, "inta 0x%08x, enabled 0x%08x, fh 0x%08x\n",
@@ -1663,7 +1663,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1663 1663
1664 /* Now service all interrupt bits discovered above. */ 1664 /* Now service all interrupt bits discovered above. */
1665 if (inta & CSR_INT_BIT_HW_ERR) { 1665 if (inta & CSR_INT_BIT_HW_ERR) {
1666 IWL_ERR(priv, "Microcode HW error detected. Restarting.\n"); 1666 IWL_ERR(priv, "Hardware error detected. Restarting.\n");
1667 1667
1668 /* Tell the device to stop sending interrupts */ 1668 /* Tell the device to stop sending interrupts */
1669 iwl_disable_interrupts(priv); 1669 iwl_disable_interrupts(priv);
@@ -1679,7 +1679,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1679 } 1679 }
1680 1680
1681#ifdef CONFIG_IWLWIFI_DEBUG 1681#ifdef CONFIG_IWLWIFI_DEBUG
1682 if (priv->debug_level & (IWL_DL_ISR)) { 1682 if (iwl_debug_level & (IWL_DL_ISR)) {
1683 /* NIC fires this, but we don't use it, redundant with WAKEUP */ 1683 /* NIC fires this, but we don't use it, redundant with WAKEUP */
1684 if (inta & CSR_INT_BIT_SCD) { 1684 if (inta & CSR_INT_BIT_SCD) {
1685 IWL_DEBUG_ISR(priv, "Scheduler finished to transmit " 1685 IWL_DEBUG_ISR(priv, "Scheduler finished to transmit "
@@ -1758,7 +1758,7 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1758 iwl_enable_interrupts(priv); 1758 iwl_enable_interrupts(priv);
1759 1759
1760#ifdef CONFIG_IWLWIFI_DEBUG 1760#ifdef CONFIG_IWLWIFI_DEBUG
1761 if (priv->debug_level & (IWL_DL_ISR)) { 1761 if (iwl_debug_level & (IWL_DL_ISR)) {
1762 inta = iwl_read32(priv, CSR_INT); 1762 inta = iwl_read32(priv, CSR_INT);
1763 inta_mask = iwl_read32(priv, CSR_INT_MASK); 1763 inta_mask = iwl_read32(priv, CSR_INT_MASK);
1764 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS); 1764 inta_fh = iwl_read32(priv, CSR_FH_INT_STATUS);
@@ -2041,7 +2041,7 @@ static void iwl3945_nic_start(struct iwl_priv *priv)
2041 */ 2041 */
2042static int iwl3945_read_ucode(struct iwl_priv *priv) 2042static int iwl3945_read_ucode(struct iwl_priv *priv)
2043{ 2043{
2044 struct iwl_ucode *ucode; 2044 const struct iwl_ucode_header *ucode;
2045 int ret = -EINVAL, index; 2045 int ret = -EINVAL, index;
2046 const struct firmware *ucode_raw; 2046 const struct firmware *ucode_raw;
2047 /* firmware file name contains uCode/driver compatibility version */ 2047 /* firmware file name contains uCode/driver compatibility version */
@@ -2082,22 +2082,24 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
2082 goto error; 2082 goto error;
2083 2083
2084 /* Make sure that we got at least our header! */ 2084 /* Make sure that we got at least our header! */
2085 if (ucode_raw->size < sizeof(*ucode)) { 2085 if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) {
2086 IWL_ERR(priv, "File size way too small!\n"); 2086 IWL_ERR(priv, "File size way too small!\n");
2087 ret = -EINVAL; 2087 ret = -EINVAL;
2088 goto err_release; 2088 goto err_release;
2089 } 2089 }
2090 2090
2091 /* Data from ucode file: header followed by uCode images */ 2091 /* Data from ucode file: header followed by uCode images */
2092 ucode = (void *)ucode_raw->data; 2092 ucode = (struct iwl_ucode_header *)ucode_raw->data;
2093 2093
2094 priv->ucode_ver = le32_to_cpu(ucode->ver); 2094 priv->ucode_ver = le32_to_cpu(ucode->ver);
2095 api_ver = IWL_UCODE_API(priv->ucode_ver); 2095 api_ver = IWL_UCODE_API(priv->ucode_ver);
2096 inst_size = le32_to_cpu(ucode->inst_size); 2096 inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver);
2097 data_size = le32_to_cpu(ucode->data_size); 2097 data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver);
2098 init_size = le32_to_cpu(ucode->init_size); 2098 init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver);
2099 init_data_size = le32_to_cpu(ucode->init_data_size); 2099 init_data_size =
2100 boot_size = le32_to_cpu(ucode->boot_size); 2100 priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver);
2101 boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver);
2102 src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
2101 2103
2102 /* api_ver should match the api version forming part of the 2104 /* api_ver should match the api version forming part of the
2103 * firmware filename ... but we don't check for that and only rely 2105 * firmware filename ... but we don't check for that and only rely
@@ -2138,12 +2140,13 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
2138 2140
2139 2141
2140 /* Verify size of file vs. image size info in file's header */ 2142 /* Verify size of file vs. image size info in file's header */
2141 if (ucode_raw->size < sizeof(*ucode) + 2143 if (ucode_raw->size != priv->cfg->ops->ucode->get_header_size(api_ver) +
2142 inst_size + data_size + init_size + 2144 inst_size + data_size + init_size +
2143 init_data_size + boot_size) { 2145 init_data_size + boot_size) {
2144 2146
2145 IWL_DEBUG_INFO(priv, "uCode file size %zd too small\n", 2147 IWL_DEBUG_INFO(priv,
2146 ucode_raw->size); 2148 "uCode file size %zd does not match expected size\n",
2149 ucode_raw->size);
2147 ret = -EINVAL; 2150 ret = -EINVAL;
2148 goto err_release; 2151 goto err_release;
2149 } 2152 }
@@ -2226,44 +2229,44 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
2226 /* Copy images into buffers for card's bus-master reads ... */ 2229 /* Copy images into buffers for card's bus-master reads ... */
2227 2230
2228 /* Runtime instructions (first block of data in file) */ 2231 /* Runtime instructions (first block of data in file) */
2229 src = &ucode->data[0]; 2232 len = inst_size;
2230 len = priv->ucode_code.len;
2231 IWL_DEBUG_INFO(priv, 2233 IWL_DEBUG_INFO(priv,
2232 "Copying (but not loading) uCode instr len %zd\n", len); 2234 "Copying (but not loading) uCode instr len %zd\n", len);
2233 memcpy(priv->ucode_code.v_addr, src, len); 2235 memcpy(priv->ucode_code.v_addr, src, len);
2236 src += len;
2237
2234 IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n", 2238 IWL_DEBUG_INFO(priv, "uCode instr buf vaddr = 0x%p, paddr = 0x%08x\n",
2235 priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr); 2239 priv->ucode_code.v_addr, (u32)priv->ucode_code.p_addr);
2236 2240
2237 /* Runtime data (2nd block) 2241 /* Runtime data (2nd block)
2238 * NOTE: Copy into backup buffer will be done in iwl3945_up() */ 2242 * NOTE: Copy into backup buffer will be done in iwl3945_up() */
2239 src = &ucode->data[inst_size]; 2243 len = data_size;
2240 len = priv->ucode_data.len;
2241 IWL_DEBUG_INFO(priv, 2244 IWL_DEBUG_INFO(priv,
2242 "Copying (but not loading) uCode data len %zd\n", len); 2245 "Copying (but not loading) uCode data len %zd\n", len);
2243 memcpy(priv->ucode_data.v_addr, src, len); 2246 memcpy(priv->ucode_data.v_addr, src, len);
2244 memcpy(priv->ucode_data_backup.v_addr, src, len); 2247 memcpy(priv->ucode_data_backup.v_addr, src, len);
2248 src += len;
2245 2249
2246 /* Initialization instructions (3rd block) */ 2250 /* Initialization instructions (3rd block) */
2247 if (init_size) { 2251 if (init_size) {
2248 src = &ucode->data[inst_size + data_size]; 2252 len = init_size;
2249 len = priv->ucode_init.len;
2250 IWL_DEBUG_INFO(priv, 2253 IWL_DEBUG_INFO(priv,
2251 "Copying (but not loading) init instr len %zd\n", len); 2254 "Copying (but not loading) init instr len %zd\n", len);
2252 memcpy(priv->ucode_init.v_addr, src, len); 2255 memcpy(priv->ucode_init.v_addr, src, len);
2256 src += len;
2253 } 2257 }
2254 2258
2255 /* Initialization data (4th block) */ 2259 /* Initialization data (4th block) */
2256 if (init_data_size) { 2260 if (init_data_size) {
2257 src = &ucode->data[inst_size + data_size + init_size]; 2261 len = init_data_size;
2258 len = priv->ucode_init_data.len;
2259 IWL_DEBUG_INFO(priv, 2262 IWL_DEBUG_INFO(priv,
2260 "Copying (but not loading) init data len %zd\n", len); 2263 "Copying (but not loading) init data len %zd\n", len);
2261 memcpy(priv->ucode_init_data.v_addr, src, len); 2264 memcpy(priv->ucode_init_data.v_addr, src, len);
2265 src += len;
2262 } 2266 }
2263 2267
2264 /* Bootstrap instructions (5th block) */ 2268 /* Bootstrap instructions (5th block) */
2265 src = &ucode->data[inst_size + data_size + init_size + init_data_size]; 2269 len = boot_size;
2266 len = priv->ucode_boot.len;
2267 IWL_DEBUG_INFO(priv, 2270 IWL_DEBUG_INFO(priv,
2268 "Copying (but not loading) boot instr len %zd\n", len); 2271 "Copying (but not loading) boot instr len %zd\n", len);
2269 memcpy(priv->ucode_boot.v_addr, src, len); 2272 memcpy(priv->ucode_boot.v_addr, src, len);
@@ -3305,13 +3308,15 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3305 * used for controlling the debug level. 3308 * used for controlling the debug level.
3306 * 3309 *
3307 * See the level definitions in iwl for details. 3310 * See the level definitions in iwl for details.
3311 *
3312 * FIXME This file can be deprecated as the module parameter is
3313 * writable and users can thus also change the debug level
3314 * using the /sys/module/iwl3945/parameters/debug file.
3308 */ 3315 */
3309static ssize_t show_debug_level(struct device *d, 3316static ssize_t show_debug_level(struct device *d,
3310 struct device_attribute *attr, char *buf) 3317 struct device_attribute *attr, char *buf)
3311{ 3318{
3312 struct iwl_priv *priv = dev_get_drvdata(d); 3319 return sprintf(buf, "0x%08X\n", iwl_debug_level);
3313
3314 return sprintf(buf, "0x%08X\n", priv->debug_level);
3315} 3320}
3316static ssize_t store_debug_level(struct device *d, 3321static ssize_t store_debug_level(struct device *d,
3317 struct device_attribute *attr, 3322 struct device_attribute *attr,
@@ -3325,7 +3330,7 @@ static ssize_t store_debug_level(struct device *d,
3325 if (ret) 3330 if (ret)
3326 IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf); 3331 IWL_INFO(priv, "%s is not in hex or decimal form.\n", buf);
3327 else 3332 else
3328 priv->debug_level = val; 3333 iwl_debug_level = val;
3329 3334
3330 return strnlen(buf, count); 3335 return strnlen(buf, count);
3331} 3336}
@@ -3947,15 +3952,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
3947 priv = hw->priv; 3952 priv = hw->priv;
3948 SET_IEEE80211_DEV(hw, &pdev->dev); 3953 SET_IEEE80211_DEV(hw, &pdev->dev);
3949 3954
3950 if ((iwl3945_mod_params.num_of_queues > IWL39_MAX_NUM_QUEUES) ||
3951 (iwl3945_mod_params.num_of_queues < IWL_MIN_NUM_QUEUES)) {
3952 IWL_ERR(priv,
3953 "invalid queues_num, should be between %d and %d\n",
3954 IWL_MIN_NUM_QUEUES, IWL39_MAX_NUM_QUEUES);
3955 err = -EINVAL;
3956 goto out_ieee80211_free_hw;
3957 }
3958
3959 /* 3955 /*
3960 * Disabling hardware scan means that mac80211 will perform scans 3956 * Disabling hardware scan means that mac80211 will perform scans
3961 * "the hard way", rather than using device's scan. 3957 * "the hard way", rather than using device's scan.
@@ -3972,7 +3968,6 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
3972 priv->inta_mask = CSR_INI_SET_MASK; 3968 priv->inta_mask = CSR_INI_SET_MASK;
3973 3969
3974#ifdef CONFIG_IWLWIFI_DEBUG 3970#ifdef CONFIG_IWLWIFI_DEBUG
3975 priv->debug_level = iwl3945_mod_params.debug;
3976 atomic_set(&priv->restrict_refcnt, 0); 3971 atomic_set(&priv->restrict_refcnt, 0);
3977#endif 3972#endif
3978 3973
@@ -4268,14 +4263,12 @@ MODULE_PARM_DESC(antenna, "select antenna (1=Main, 2=Aux, default 0 [both])");
4268module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444); 4263module_param_named(swcrypto, iwl3945_mod_params.sw_crypto, int, 0444);
4269MODULE_PARM_DESC(swcrypto, 4264MODULE_PARM_DESC(swcrypto,
4270 "using software crypto (default 1 [software])\n"); 4265 "using software crypto (default 1 [software])\n");
4271module_param_named(debug, iwl3945_mod_params.debug, uint, 0444); 4266#ifdef CONFIG_IWLWIFI_DEBUG
4267module_param_named(debug, iwl_debug_level, uint, 0644);
4272MODULE_PARM_DESC(debug, "debug output mask"); 4268MODULE_PARM_DESC(debug, "debug output mask");
4269#endif
4273module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444); 4270module_param_named(disable_hw_scan, iwl3945_mod_params.disable_hw_scan, int, 0444);
4274MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)"); 4271MODULE_PARM_DESC(disable_hw_scan, "disable hardware scanning (default 0)");
4275
4276module_param_named(queues_num, iwl3945_mod_params.num_of_queues, int, 0444);
4277MODULE_PARM_DESC(queues_num, "number of hw queues.");
4278
4279module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444); 4272module_param_named(fw_restart3945, iwl3945_mod_params.restart_fw, int, 0444);
4280MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error"); 4273MODULE_PARM_DESC(fw_restart3945, "restart firmware in case of error");
4281 4274
diff --git a/drivers/net/wireless/iwmc3200wifi/cfg80211.c b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
index 54bebba8e27e..3f5a08fa401f 100644
--- a/drivers/net/wireless/iwmc3200wifi/cfg80211.c
+++ b/drivers/net/wireless/iwmc3200wifi/cfg80211.c
@@ -158,34 +158,6 @@ static int iwm_key_init(struct iwm_key *key, u8 key_index,
158 return 0; 158 return 0;
159} 159}
160 160
161static int iwm_reset_profile(struct iwm_priv *iwm)
162{
163 int ret;
164
165 if (!iwm->umac_profile_active)
166 return 0;
167
168 /*
169 * If there is a current active profile, but no
170 * default key, it's not worth trying to associate again.
171 */
172 if (iwm->default_key < 0)
173 return 0;
174
175 /*
176 * Here we have an active profile, but a key setting changed.
177 * We thus have to invalidate the current profile, and push the
178 * new one. Keys will be pushed when association takes place.
179 */
180 ret = iwm_invalidate_mlme_profile(iwm);
181 if (ret < 0) {
182 IWM_ERR(iwm, "Couldn't invalidate profile\n");
183 return ret;
184 }
185
186 return iwm_send_mlme_profile(iwm);
187}
188
189static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev, 161static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
190 u8 key_index, const u8 *mac_addr, 162 u8 key_index, const u8 *mac_addr,
191 struct key_params *params) 163 struct key_params *params)
@@ -203,32 +175,6 @@ static int iwm_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
203 return ret; 175 return ret;
204 } 176 }
205 177
206 /*
207 * The WEP keys can be set before or after setting the essid.
208 * We need to handle both cases by simply pushing the keys after
209 * we send the profile.
210 * If the profile is not set yet (i.e. we're pushing keys before
211 * the essid), we set the cipher appropriately.
212 * If the profile is set, we havent associated yet because our
213 * cipher was incorrectly set. So we invalidate and send the
214 * profile again.
215 */
216 if (key->cipher == WLAN_CIPHER_SUITE_WEP40 ||
217 key->cipher == WLAN_CIPHER_SUITE_WEP104) {
218 u8 *ucast_cipher = &iwm->umac_profile->sec.ucast_cipher;
219 u8 *mcast_cipher = &iwm->umac_profile->sec.mcast_cipher;
220
221 IWM_DBG_WEXT(iwm, DBG, "WEP key\n");
222
223 if (key->cipher == WLAN_CIPHER_SUITE_WEP40)
224 *ucast_cipher = *mcast_cipher = UMAC_CIPHER_TYPE_WEP_40;
225 if (key->cipher == WLAN_CIPHER_SUITE_WEP104)
226 *ucast_cipher = *mcast_cipher =
227 UMAC_CIPHER_TYPE_WEP_104;
228
229 return iwm_reset_profile(iwm);
230 }
231
232 return iwm_set_key(iwm, 0, key); 178 return iwm_set_key(iwm, 0, key);
233} 179}
234 180
@@ -271,10 +217,6 @@ static int iwm_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
271 if (key_index == iwm->default_key) 217 if (key_index == iwm->default_key)
272 iwm->default_key = -1; 218 iwm->default_key = -1;
273 219
274 /* If the interface is down, we just cache this */
275 if (!test_bit(IWM_STATUS_READY, &iwm->status))
276 return 0;
277
278 return iwm_set_key(iwm, 1, key); 220 return iwm_set_key(iwm, 1, key);
279} 221}
280 222
@@ -283,7 +225,6 @@ static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
283 u8 key_index) 225 u8 key_index)
284{ 226{
285 struct iwm_priv *iwm = ndev_to_iwm(ndev); 227 struct iwm_priv *iwm = ndev_to_iwm(ndev);
286 int ret;
287 228
288 IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index); 229 IWM_DBG_WEXT(iwm, DBG, "Default key index is: %d\n", key_index);
289 230
@@ -294,15 +235,26 @@ static int iwm_cfg80211_set_default_key(struct wiphy *wiphy,
294 235
295 iwm->default_key = key_index; 236 iwm->default_key = key_index;
296 237
297 /* If the interface is down, we just cache this */ 238 return iwm_set_tx_key(iwm, key_index);
298 if (!test_bit(IWM_STATUS_READY, &iwm->status)) 239}
299 return 0;
300 240
301 ret = iwm_set_tx_key(iwm, key_index); 241int iwm_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
302 if (ret < 0) 242 u8 *mac, struct station_info *sinfo)
303 return ret; 243{
244 struct iwm_priv *iwm = ndev_to_iwm(ndev);
245
246 if (memcmp(mac, iwm->bssid, ETH_ALEN))
247 return -ENOENT;
304 248
305 return iwm_reset_profile(iwm); 249 sinfo->filled |= STATION_INFO_TX_BITRATE;
250 sinfo->txrate.legacy = iwm->rate * 10;
251
252 if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
253 sinfo->filled |= STATION_INFO_SIGNAL;
254 sinfo->signal = iwm->wstats.qual.level;
255 }
256
257 return 0;
306} 258}
307 259
308 260
@@ -500,6 +452,179 @@ static int iwm_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
500 return 0; 452 return 0;
501} 453}
502 454
455static int iwm_set_auth_type(struct iwm_priv *iwm,
456 enum nl80211_auth_type sme_auth_type)
457{
458 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
459
460 switch (sme_auth_type) {
461 case NL80211_AUTHTYPE_AUTOMATIC:
462 case NL80211_AUTHTYPE_OPEN_SYSTEM:
463 IWM_DBG_WEXT(iwm, DBG, "OPEN auth\n");
464 *auth_type = UMAC_AUTH_TYPE_OPEN;
465 break;
466 case NL80211_AUTHTYPE_SHARED_KEY:
467 if (iwm->umac_profile->sec.flags &
468 (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
469 IWM_DBG_WEXT(iwm, DBG, "WPA auth alg\n");
470 *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
471 } else {
472 IWM_DBG_WEXT(iwm, DBG, "WEP shared key auth alg\n");
473 *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
474 }
475
476 break;
477 default:
478 IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", sme_auth_type);
479 return -ENOTSUPP;
480 }
481
482 return 0;
483}
484
485static int iwm_set_wpa_version(struct iwm_priv *iwm, u32 wpa_version)
486{
487 if (!wpa_version) {
488 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
489 return 0;
490 }
491
492 if (wpa_version & NL80211_WPA_VERSION_2)
493 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
494
495 if (wpa_version & NL80211_WPA_VERSION_1)
496 iwm->umac_profile->sec.flags |= UMAC_SEC_FLG_WPA_ON_MSK;
497
498 return 0;
499}
500
501static int iwm_set_cipher(struct iwm_priv *iwm, u32 cipher, bool ucast)
502{
503 u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
504 &iwm->umac_profile->sec.mcast_cipher;
505
506 if (!cipher) {
507 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
508 return 0;
509 }
510
511 switch (cipher) {
512 case IW_AUTH_CIPHER_NONE:
513 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
514 break;
515 case WLAN_CIPHER_SUITE_WEP40:
516 *profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
517 break;
518 case WLAN_CIPHER_SUITE_WEP104:
519 *profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
520 break;
521 case WLAN_CIPHER_SUITE_TKIP:
522 *profile_cipher = UMAC_CIPHER_TYPE_TKIP;
523 break;
524 case WLAN_CIPHER_SUITE_CCMP:
525 *profile_cipher = UMAC_CIPHER_TYPE_CCMP;
526 break;
527 default:
528 IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
529 return -ENOTSUPP;
530 }
531
532 return 0;
533}
534
535static int iwm_set_key_mgt(struct iwm_priv *iwm, u32 key_mgt)
536{
537 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
538
539 IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
540
541 if (key_mgt == WLAN_AKM_SUITE_8021X)
542 *auth_type = UMAC_AUTH_TYPE_8021X;
543 else if (key_mgt == WLAN_AKM_SUITE_PSK) {
544 if (iwm->umac_profile->sec.flags &
545 (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
546 *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
547 else
548 *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
549 } else {
550 IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
551 return -EINVAL;
552 }
553
554 return 0;
555}
556
557
558static int iwm_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
559 struct cfg80211_connect_params *sme)
560{
561 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
562 struct ieee80211_channel *chan = sme->channel;
563 int ret;
564
565 if (!test_bit(IWM_STATUS_READY, &iwm->status))
566 return -EIO;
567
568 if (!sme->ssid)
569 return -EINVAL;
570
571 if (chan)
572 iwm->channel =
573 ieee80211_frequency_to_channel(chan->center_freq);
574
575 iwm->umac_profile->ssid.ssid_len = sme->ssid_len;
576 memcpy(iwm->umac_profile->ssid.ssid, sme->ssid, sme->ssid_len);
577
578 if (sme->bssid) {
579 IWM_DBG_WEXT(iwm, DBG, "BSSID: %pM\n", sme->bssid);
580 memcpy(&iwm->umac_profile->bssid[0], sme->bssid, ETH_ALEN);
581 iwm->umac_profile->bss_num = 1;
582 } else {
583 memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
584 iwm->umac_profile->bss_num = 0;
585 }
586
587 ret = iwm_set_auth_type(iwm, sme->auth_type);
588 if (ret < 0)
589 return ret;
590
591 ret = iwm_set_wpa_version(iwm, sme->crypto.wpa_versions);
592 if (ret < 0)
593 return ret;
594
595 if (sme->crypto.n_ciphers_pairwise) {
596 ret = iwm_set_cipher(iwm, sme->crypto.ciphers_pairwise[0],
597 true);
598 if (ret < 0)
599 return ret;
600 }
601
602 ret = iwm_set_cipher(iwm, sme->crypto.cipher_group, false);
603 if (ret < 0)
604 return ret;
605
606 if (sme->crypto.n_akm_suites) {
607 ret = iwm_set_key_mgt(iwm, sme->crypto.akm_suites[0]);
608 if (ret < 0)
609 return ret;
610 }
611
612 return iwm_send_mlme_profile(iwm);
613}
614
615static int iwm_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
616 u16 reason_code)
617{
618 struct iwm_priv *iwm = wiphy_to_iwm(wiphy);
619
620 IWM_DBG_WEXT(iwm, DBG, "Active: %d\n", iwm->umac_profile_active);
621
622 if (iwm->umac_profile_active)
623 return iwm_invalidate_mlme_profile(iwm);
624
625 return 0;
626}
627
503static int iwm_cfg80211_set_txpower(struct wiphy *wiphy, 628static int iwm_cfg80211_set_txpower(struct wiphy *wiphy,
504 enum tx_power_setting type, int dbm) 629 enum tx_power_setting type, int dbm)
505{ 630{
@@ -549,8 +674,11 @@ static struct cfg80211_ops iwm_cfg80211_ops = {
549 .get_key = iwm_cfg80211_get_key, 674 .get_key = iwm_cfg80211_get_key,
550 .del_key = iwm_cfg80211_del_key, 675 .del_key = iwm_cfg80211_del_key,
551 .set_default_key = iwm_cfg80211_set_default_key, 676 .set_default_key = iwm_cfg80211_set_default_key,
677 .get_station = iwm_cfg80211_get_station,
552 .scan = iwm_cfg80211_scan, 678 .scan = iwm_cfg80211_scan,
553 .set_wiphy_params = iwm_cfg80211_set_wiphy_params, 679 .set_wiphy_params = iwm_cfg80211_set_wiphy_params,
680 .connect = iwm_cfg80211_connect,
681 .disconnect = iwm_cfg80211_disconnect,
554 .join_ibss = iwm_cfg80211_join_ibss, 682 .join_ibss = iwm_cfg80211_join_ibss,
555 .leave_ibss = iwm_cfg80211_leave_ibss, 683 .leave_ibss = iwm_cfg80211_leave_ibss,
556 .set_tx_power = iwm_cfg80211_set_txpower, 684 .set_tx_power = iwm_cfg80211_set_txpower,
@@ -558,6 +686,13 @@ static struct cfg80211_ops iwm_cfg80211_ops = {
558 .set_power_mgmt = iwm_cfg80211_set_power_mgmt, 686 .set_power_mgmt = iwm_cfg80211_set_power_mgmt,
559}; 687};
560 688
689static const u32 cipher_suites[] = {
690 WLAN_CIPHER_SUITE_WEP40,
691 WLAN_CIPHER_SUITE_WEP104,
692 WLAN_CIPHER_SUITE_TKIP,
693 WLAN_CIPHER_SUITE_CCMP,
694};
695
561struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev) 696struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
562{ 697{
563 int ret = 0; 698 int ret = 0;
@@ -600,6 +735,9 @@ struct wireless_dev *iwm_wdev_alloc(int sizeof_bus, struct device *dev)
600 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz; 735 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &iwm_band_5ghz;
601 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM; 736 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
602 737
738 wdev->wiphy->cipher_suites = cipher_suites;
739 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
740
603 ret = wiphy_register(wdev->wiphy); 741 ret = wiphy_register(wdev->wiphy);
604 if (ret < 0) { 742 if (ret < 0) {
605 dev_err(dev, "Couldn't register wiphy device\n"); 743 dev_err(dev, "Couldn't register wiphy device\n");
diff --git a/drivers/net/wireless/iwmc3200wifi/commands.c b/drivers/net/wireless/iwmc3200wifi/commands.c
index 0d35afefb61c..0d6637005f42 100644
--- a/drivers/net/wireless/iwmc3200wifi/commands.c
+++ b/drivers/net/wireless/iwmc3200wifi/commands.c
@@ -87,8 +87,7 @@ int iwm_send_wifi_if_cmd(struct iwm_priv *iwm, void *payload, u16 payload_size,
87 test_and_clear_bit(oid, &iwm->wifi_ntfy[0]), 87 test_and_clear_bit(oid, &iwm->wifi_ntfy[0]),
88 3 * HZ); 88 3 * HZ);
89 89
90 if (!ret) 90 return ret ? 0 : -EBUSY;
91 ret = -EBUSY;
92 } 91 }
93 92
94 return ret; 93 return ret;
@@ -480,8 +479,10 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address,
480 target_cmd.eop = 1; 479 target_cmd.eop = 1;
481 480
482 ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL); 481 ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
483 if (ret < 0) 482 if (ret < 0) {
484 IWM_ERR(iwm, "Couldn't send READ command\n"); 483 IWM_ERR(iwm, "Couldn't send READ command\n");
484 return ret;
485 }
485 486
486 /* When succeding, the send_target routine returns the seq number */ 487 /* When succeding, the send_target routine returns the seq number */
487 seq_num = ret; 488 seq_num = ret;
@@ -501,7 +502,7 @@ static int iwm_target_read(struct iwm_priv *iwm, __le32 address,
501 502
502 kfree(cmd); 503 kfree(cmd);
503 504
504 return ret; 505 return 0;
505} 506}
506 507
507int iwm_read_mac(struct iwm_priv *iwm, u8 *mac) 508int iwm_read_mac(struct iwm_priv *iwm, u8 *mac)
@@ -511,7 +512,7 @@ int iwm_read_mac(struct iwm_priv *iwm, u8 *mac)
511 512
512 ret = iwm_target_read(iwm, cpu_to_le32(WICO_MAC_ADDRESS_ADDR), 513 ret = iwm_target_read(iwm, cpu_to_le32(WICO_MAC_ADDRESS_ADDR),
513 mac_align, sizeof(mac_align)); 514 mac_align, sizeof(mac_align));
514 if (ret < 0) 515 if (ret)
515 return ret; 516 return ret;
516 517
517 if (is_valid_ether_addr(mac_align)) 518 if (is_valid_ether_addr(mac_align))
@@ -583,12 +584,6 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key)
583 struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd; 584 struct iwm_umac_key_tkip *tkip = (struct iwm_umac_key_tkip *)cmd;
584 struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd; 585 struct iwm_umac_key_ccmp *ccmp = (struct iwm_umac_key_ccmp *)cmd;
585 586
586 /*
587 * We check if our current profile is valid.
588 * If not, we dont push the key, we just cache them,
589 * so that with the next siwsessid call, the keys
590 * will be actually pushed.
591 */
592 if (!remove) { 587 if (!remove) {
593 ret = iwm_check_profile(iwm); 588 ret = iwm_check_profile(iwm);
594 if (ret < 0) 589 if (ret < 0)
@@ -714,7 +709,7 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key)
714 ret = iwm_send_wifi_if_cmd(iwm, &key_remove, 709 ret = iwm_send_wifi_if_cmd(iwm, &key_remove,
715 sizeof(struct iwm_umac_key_remove), 710 sizeof(struct iwm_umac_key_remove),
716 1); 711 1);
717 if (ret < 0) 712 if (ret)
718 return ret; 713 return ret;
719 714
720 iwm->keys[key_idx].key_len = 0; 715 iwm->keys[key_idx].key_len = 0;
@@ -726,7 +721,7 @@ int iwm_set_key(struct iwm_priv *iwm, bool remove, struct iwm_key *key)
726 721
727int iwm_send_mlme_profile(struct iwm_priv *iwm) 722int iwm_send_mlme_profile(struct iwm_priv *iwm)
728{ 723{
729 int ret, i; 724 int ret;
730 struct iwm_umac_profile profile; 725 struct iwm_umac_profile profile;
731 726
732 memcpy(&profile, iwm->umac_profile, sizeof(profile)); 727 memcpy(&profile, iwm->umac_profile, sizeof(profile));
@@ -736,32 +731,11 @@ int iwm_send_mlme_profile(struct iwm_priv *iwm)
736 sizeof(struct iwm_umac_wifi_if)); 731 sizeof(struct iwm_umac_wifi_if));
737 732
738 ret = iwm_send_wifi_if_cmd(iwm, &profile, sizeof(profile), 1); 733 ret = iwm_send_wifi_if_cmd(iwm, &profile, sizeof(profile), 1);
739 if (ret < 0) { 734 if (ret) {
740 IWM_ERR(iwm, "Send profile command failed\n"); 735 IWM_ERR(iwm, "Send profile command failed\n");
741 return ret; 736 return ret;
742 } 737 }
743 738
744 for (i = 0; i < IWM_NUM_KEYS; i++)
745 if (iwm->keys[i].key_len) {
746 struct iwm_key *key = &iwm->keys[i];
747
748 /* Wait for the profile before sending the keys */
749 wait_event_interruptible_timeout(iwm->mlme_queue,
750 (test_bit(IWM_STATUS_ASSOCIATING, &iwm->status) ||
751 test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)),
752 3 * HZ);
753
754 ret = iwm_set_key(iwm, 0, key);
755 if (ret < 0)
756 return ret;
757
758 if (iwm->default_key == i) {
759 ret = iwm_set_tx_key(iwm, i);
760 if (ret < 0)
761 return ret;
762 }
763 }
764
765 return 0; 739 return 0;
766} 740}
767 741
@@ -778,15 +752,13 @@ int iwm_invalidate_mlme_profile(struct iwm_priv *iwm)
778 invalid.reason = WLAN_REASON_UNSPECIFIED; 752 invalid.reason = WLAN_REASON_UNSPECIFIED;
779 753
780 ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1); 754 ret = iwm_send_wifi_if_cmd(iwm, &invalid, sizeof(invalid), 1);
781 if (ret < 0) 755 if (ret)
782 return ret; 756 return ret;
783 757
784 ret = wait_event_interruptible_timeout(iwm->mlme_queue, 758 ret = wait_event_interruptible_timeout(iwm->mlme_queue,
785 (iwm->umac_profile_active == 0), 2 * HZ); 759 (iwm->umac_profile_active == 0), 2 * HZ);
786 if (!ret)
787 return -EBUSY;
788 760
789 return 0; 761 return ret ? 0 : -EBUSY;
790} 762}
791 763
792int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags) 764int iwm_send_umac_stats_req(struct iwm_priv *iwm, u32 flags)
@@ -869,7 +841,7 @@ int iwm_scan_ssids(struct iwm_priv *iwm, struct cfg80211_ssid *ssids,
869 } 841 }
870 842
871 ret = iwm_send_wifi_if_cmd(iwm, &req, sizeof(req), 0); 843 ret = iwm_send_wifi_if_cmd(iwm, &req, sizeof(req), 0);
872 if (ret < 0) { 844 if (ret) {
873 IWM_ERR(iwm, "Couldn't send scan request\n"); 845 IWM_ERR(iwm, "Couldn't send scan request\n");
874 return ret; 846 return ret;
875 } 847 }
diff --git a/drivers/net/wireless/iwmc3200wifi/hal.c b/drivers/net/wireless/iwmc3200wifi/hal.c
index ee127fe4f43f..c430418248b4 100644
--- a/drivers/net/wireless/iwmc3200wifi/hal.c
+++ b/drivers/net/wireless/iwmc3200wifi/hal.c
@@ -105,9 +105,9 @@
105#include "umac.h" 105#include "umac.h"
106#include "debug.h" 106#include "debug.h"
107 107
108static void iwm_nonwifi_cmd_init(struct iwm_priv *iwm, 108static int iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
109 struct iwm_nonwifi_cmd *cmd, 109 struct iwm_nonwifi_cmd *cmd,
110 struct iwm_udma_nonwifi_cmd *udma_cmd) 110 struct iwm_udma_nonwifi_cmd *udma_cmd)
111{ 111{
112 INIT_LIST_HEAD(&cmd->pending); 112 INIT_LIST_HEAD(&cmd->pending);
113 113
@@ -118,7 +118,7 @@ static void iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
118 cmd->seq_num = iwm->nonwifi_seq_num; 118 cmd->seq_num = iwm->nonwifi_seq_num;
119 udma_cmd->seq_num = cpu_to_le16(cmd->seq_num); 119 udma_cmd->seq_num = cpu_to_le16(cmd->seq_num);
120 120
121 cmd->seq_num = iwm->nonwifi_seq_num++; 121 iwm->nonwifi_seq_num++;
122 iwm->nonwifi_seq_num %= UMAC_NONWIFI_SEQ_NUM_MAX; 122 iwm->nonwifi_seq_num %= UMAC_NONWIFI_SEQ_NUM_MAX;
123 123
124 if (udma_cmd->resp) 124 if (udma_cmd->resp)
@@ -130,6 +130,8 @@ static void iwm_nonwifi_cmd_init(struct iwm_priv *iwm,
130 cmd->buf.len = 0; 130 cmd->buf.len = 0;
131 131
132 memcpy(&cmd->udma_cmd, udma_cmd, sizeof(*udma_cmd)); 132 memcpy(&cmd->udma_cmd, udma_cmd, sizeof(*udma_cmd));
133
134 return cmd->seq_num;
133} 135}
134 136
135u16 iwm_alloc_wifi_cmd_seq(struct iwm_priv *iwm) 137u16 iwm_alloc_wifi_cmd_seq(struct iwm_priv *iwm)
@@ -369,7 +371,7 @@ int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
369 const void *payload) 371 const void *payload)
370{ 372{
371 struct iwm_nonwifi_cmd *cmd; 373 struct iwm_nonwifi_cmd *cmd;
372 int ret; 374 int ret, seq_num;
373 375
374 cmd = kzalloc(sizeof(struct iwm_nonwifi_cmd), GFP_KERNEL); 376 cmd = kzalloc(sizeof(struct iwm_nonwifi_cmd), GFP_KERNEL);
375 if (!cmd) { 377 if (!cmd) {
@@ -377,7 +379,7 @@ int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
377 return -ENOMEM; 379 return -ENOMEM;
378 } 380 }
379 381
380 iwm_nonwifi_cmd_init(iwm, cmd, udma_cmd); 382 seq_num = iwm_nonwifi_cmd_init(iwm, cmd, udma_cmd);
381 383
382 if (cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE || 384 if (cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE ||
383 cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE_PERSISTENT) { 385 cmd->udma_cmd.opcode == UMAC_HDI_OUT_OPCODE_WRITE_PERSISTENT) {
@@ -393,7 +395,7 @@ int iwm_hal_send_target_cmd(struct iwm_priv *iwm,
393 if (ret < 0) 395 if (ret < 0)
394 return ret; 396 return ret;
395 397
396 return cmd->seq_num; 398 return seq_num;
397} 399}
398 400
399static void iwm_build_lmac_hdr(struct iwm_priv *iwm, struct iwm_lmac_hdr *hdr, 401static void iwm_build_lmac_hdr(struct iwm_priv *iwm, struct iwm_lmac_hdr *hdr,
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 79d9d89d47ae..2175a481d2f4 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -281,6 +281,11 @@ struct iwm_priv {
281 struct work_struct reset_worker; 281 struct work_struct reset_worker;
282 struct mutex mutex; 282 struct mutex mutex;
283 283
284 u8 *req_ie;
285 int req_ie_len;
286 u8 *resp_ie;
287 int resp_ie_len;
288
284 char private[0] __attribute__((__aligned__(NETDEV_ALIGN))); 289 char private[0] __attribute__((__aligned__(NETDEV_ALIGN)));
285}; 290};
286 291
diff --git a/drivers/net/wireless/iwmc3200wifi/main.c b/drivers/net/wireless/iwmc3200wifi/main.c
index 484f110151b7..cf2574442b57 100644
--- a/drivers/net/wireless/iwmc3200wifi/main.c
+++ b/drivers/net/wireless/iwmc3200wifi/main.c
@@ -497,6 +497,13 @@ void iwm_link_off(struct iwm_priv *iwm)
497 memset(wstats, 0, sizeof(struct iw_statistics)); 497 memset(wstats, 0, sizeof(struct iw_statistics));
498 wstats->qual.updated = IW_QUAL_ALL_INVALID; 498 wstats->qual.updated = IW_QUAL_ALL_INVALID;
499 499
500 kfree(iwm->req_ie);
501 iwm->req_ie = NULL;
502 iwm->req_ie_len = 0;
503 kfree(iwm->resp_ie);
504 iwm->resp_ie = NULL;
505 iwm->resp_ie_len = 0;
506
500 del_timer_sync(&iwm->watchdog); 507 del_timer_sync(&iwm->watchdog);
501} 508}
502 509
diff --git a/drivers/net/wireless/iwmc3200wifi/rx.c b/drivers/net/wireless/iwmc3200wifi/rx.c
index 3909477fb3bf..86079a187eef 100644
--- a/drivers/net/wireless/iwmc3200wifi/rx.c
+++ b/drivers/net/wireless/iwmc3200wifi/rx.c
@@ -102,7 +102,6 @@ static int iwm_ntf_error(struct iwm_priv *iwm, u8 *buf,
102 error = (struct iwm_umac_notif_error *)buf; 102 error = (struct iwm_umac_notif_error *)buf;
103 fw_err = &error->err; 103 fw_err = &error->err;
104 104
105
106 IWM_ERR(iwm, "%cMAC FW ERROR:\n", 105 IWM_ERR(iwm, "%cMAC FW ERROR:\n",
107 (le32_to_cpu(fw_err->category) == UMAC_SYS_ERR_CAT_LMAC) ? 'L' : 'U'); 106 (le32_to_cpu(fw_err->category) == UMAC_SYS_ERR_CAT_LMAC) ? 'L' : 'U');
108 IWM_ERR(iwm, "\tCategory: %d\n", le32_to_cpu(fw_err->category)); 107 IWM_ERR(iwm, "\tCategory: %d\n", le32_to_cpu(fw_err->category));
@@ -219,17 +218,17 @@ static int iwm_ntf_tx(struct iwm_priv *iwm, u8 *buf,
219 (buf + sizeof(struct iwm_umac_wifi_in_hdr)); 218 (buf + sizeof(struct iwm_umac_wifi_in_hdr));
220 hdr = (struct iwm_umac_wifi_in_hdr *)buf; 219 hdr = (struct iwm_umac_wifi_in_hdr *)buf;
221 220
222 IWM_DBG_NTF(iwm, DBG, "REPLY_TX, buf size: %lu\n", buf_size); 221 IWM_DBG_TX(iwm, DBG, "REPLY_TX, buf size: %lu\n", buf_size);
223 222
224 IWM_DBG_NTF(iwm, DBG, "Seqnum: %d\n", 223 IWM_DBG_TX(iwm, DBG, "Seqnum: %d\n",
225 le16_to_cpu(hdr->sw_hdr.cmd.seq_num)); 224 le16_to_cpu(hdr->sw_hdr.cmd.seq_num));
226 IWM_DBG_NTF(iwm, DBG, "\tFrame cnt: %d\n", tx_resp->frame_cnt); 225 IWM_DBG_TX(iwm, DBG, "\tFrame cnt: %d\n", tx_resp->frame_cnt);
227 IWM_DBG_NTF(iwm, DBG, "\tRetry cnt: %d\n", 226 IWM_DBG_TX(iwm, DBG, "\tRetry cnt: %d\n",
228 le16_to_cpu(tx_resp->retry_cnt)); 227 le16_to_cpu(tx_resp->retry_cnt));
229 IWM_DBG_NTF(iwm, DBG, "\tSeq ctl: %d\n", le16_to_cpu(tx_resp->seq_ctl)); 228 IWM_DBG_TX(iwm, DBG, "\tSeq ctl: %d\n", le16_to_cpu(tx_resp->seq_ctl));
230 IWM_DBG_NTF(iwm, DBG, "\tByte cnt: %d\n", 229 IWM_DBG_TX(iwm, DBG, "\tByte cnt: %d\n",
231 le16_to_cpu(tx_resp->byte_cnt)); 230 le16_to_cpu(tx_resp->byte_cnt));
232 IWM_DBG_NTF(iwm, DBG, "\tStatus: 0x%x\n", le32_to_cpu(tx_resp->status)); 231 IWM_DBG_TX(iwm, DBG, "\tStatus: 0x%x\n", le32_to_cpu(tx_resp->status));
233 232
234 return 0; 233 return 0;
235} 234}
@@ -419,8 +418,8 @@ static int iwm_ntf_rx_ticket(struct iwm_priv *iwm, u8 *buf,
419 if (IS_ERR(ticket_node)) 418 if (IS_ERR(ticket_node))
420 return PTR_ERR(ticket_node); 419 return PTR_ERR(ticket_node);
421 420
422 IWM_DBG_NTF(iwm, DBG, "TICKET RELEASE(%d)\n", 421 IWM_DBG_RX(iwm, DBG, "TICKET RELEASE(%d)\n",
423 ticket->id); 422 ticket->id);
424 list_add_tail(&ticket_node->node, &iwm->rx_tickets); 423 list_add_tail(&ticket_node->node, &iwm->rx_tickets);
425 424
426 /* 425 /*
@@ -455,15 +454,15 @@ static int iwm_ntf_rx_packet(struct iwm_priv *iwm, u8 *buf,
455 u16 id, buf_offset; 454 u16 id, buf_offset;
456 u32 packet_size; 455 u32 packet_size;
457 456
458 IWM_DBG_NTF(iwm, DBG, "\n"); 457 IWM_DBG_RX(iwm, DBG, "\n");
459 458
460 wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf; 459 wifi_hdr = (struct iwm_umac_wifi_in_hdr *)buf;
461 id = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num); 460 id = le16_to_cpu(wifi_hdr->sw_hdr.cmd.seq_num);
462 buf_offset = sizeof(struct iwm_umac_wifi_in_hdr); 461 buf_offset = sizeof(struct iwm_umac_wifi_in_hdr);
463 packet_size = buf_size - sizeof(struct iwm_umac_wifi_in_hdr); 462 packet_size = buf_size - sizeof(struct iwm_umac_wifi_in_hdr);
464 463
465 IWM_DBG_NTF(iwm, DBG, "CMD:0x%x, seqnum: %d, packet size: %d\n", 464 IWM_DBG_RX(iwm, DBG, "CMD:0x%x, seqnum: %d, packet size: %d\n",
466 wifi_hdr->sw_hdr.cmd.cmd, id, packet_size); 465 wifi_hdr->sw_hdr.cmd.cmd, id, packet_size);
467 IWM_DBG_RX(iwm, DBG, "Packet id: %d\n", id); 466 IWM_DBG_RX(iwm, DBG, "Packet id: %d\n", id);
468 IWM_HEXDUMP(iwm, DBG, RX, "PACKET: ", buf + buf_offset, packet_size); 467 IWM_HEXDUMP(iwm, DBG, RX, "PACKET: ", buf + buf_offset, packet_size);
469 468
@@ -504,13 +503,10 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
504{ 503{
505 struct iwm_umac_notif_assoc_complete *complete = 504 struct iwm_umac_notif_assoc_complete *complete =
506 (struct iwm_umac_notif_assoc_complete *)buf; 505 (struct iwm_umac_notif_assoc_complete *)buf;
507 union iwreq_data wrqu;
508 506
509 IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n", 507 IWM_DBG_MLME(iwm, INFO, "Association with %pM completed, status: %d\n",
510 complete->bssid, complete->status); 508 complete->bssid, complete->status);
511 509
512 memset(&wrqu, 0, sizeof(wrqu));
513
514 clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status); 510 clear_bit(IWM_STATUS_ASSOCIATING, &iwm->status);
515 511
516 switch (le32_to_cpu(complete->status)) { 512 switch (le32_to_cpu(complete->status)) {
@@ -521,7 +517,14 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
521 517
522 iwm_link_on(iwm); 518 iwm_link_on(iwm);
523 519
524 memcpy(wrqu.ap_addr.sa_data, complete->bssid, ETH_ALEN); 520 if (iwm->conf.mode == UMAC_MODE_IBSS)
521 goto ibss;
522
523 cfg80211_connect_result(iwm_to_ndev(iwm),
524 complete->bssid,
525 iwm->req_ie, iwm->req_ie_len,
526 iwm->resp_ie, iwm->resp_ie_len,
527 WLAN_STATUS_SUCCESS, GFP_KERNEL);
525 break; 528 break;
526 case UMAC_ASSOC_COMPLETE_FAILURE: 529 case UMAC_ASSOC_COMPLETE_FAILURE:
527 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status); 530 clear_bit(IWM_STATUS_ASSOCIATED, &iwm->status);
@@ -529,18 +532,22 @@ static int iwm_mlme_assoc_complete(struct iwm_priv *iwm, u8 *buf,
529 iwm->channel = 0; 532 iwm->channel = 0;
530 533
531 iwm_link_off(iwm); 534 iwm_link_off(iwm);
535
536 if (iwm->conf.mode == UMAC_MODE_IBSS)
537 goto ibss;
538
539 cfg80211_connect_result(iwm_to_ndev(iwm), complete->bssid,
540 NULL, 0, NULL, 0,
541 WLAN_STATUS_UNSPECIFIED_FAILURE,
542 GFP_KERNEL);
532 default: 543 default:
533 break; 544 break;
534 } 545 }
535 546
536 if (iwm->conf.mode == UMAC_MODE_IBSS) { 547 return 0;
537 cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL);
538 return 0;
539 }
540
541 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
542 wireless_send_event(iwm_to_ndev(iwm), SIOCGIWAP, &wrqu, NULL);
543 548
549 ibss:
550 cfg80211_ibss_joined(iwm_to_ndev(iwm), iwm->bssid, GFP_KERNEL);
544 return 0; 551 return 0;
545} 552}
546 553
@@ -770,37 +777,46 @@ static int iwm_mlme_mgt_frame(struct iwm_priv *iwm, u8 *buf,
770 unsigned long buf_size, struct iwm_wifi_cmd *cmd) 777 unsigned long buf_size, struct iwm_wifi_cmd *cmd)
771{ 778{
772 struct iwm_umac_notif_mgt_frame *mgt_frame = 779 struct iwm_umac_notif_mgt_frame *mgt_frame =
773 (struct iwm_umac_notif_mgt_frame *)buf; 780 (struct iwm_umac_notif_mgt_frame *)buf;
774 struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame; 781 struct ieee80211_mgmt *mgt = (struct ieee80211_mgmt *)mgt_frame->frame;
775 u8 *ie; 782 u8 *ie;
776 unsigned int event;
777 union iwreq_data wrqu;
778 783
779 IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame, 784 IWM_HEXDUMP(iwm, DBG, MLME, "MGT: ", mgt_frame->frame,
780 le16_to_cpu(mgt_frame->len)); 785 le16_to_cpu(mgt_frame->len));
781 786
782 if (ieee80211_is_assoc_req(mgt->frame_control)) { 787 if (ieee80211_is_assoc_req(mgt->frame_control)) {
783 ie = mgt->u.assoc_req.variable;; 788 ie = mgt->u.assoc_req.variable;;
784 event = IWEVASSOCREQIE; 789 iwm->req_ie_len =
790 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
791 kfree(iwm->req_ie);
792 iwm->req_ie = kmemdup(mgt->u.assoc_req.variable,
793 iwm->req_ie_len, GFP_KERNEL);
785 } else if (ieee80211_is_reassoc_req(mgt->frame_control)) { 794 } else if (ieee80211_is_reassoc_req(mgt->frame_control)) {
786 ie = mgt->u.reassoc_req.variable;; 795 ie = mgt->u.reassoc_req.variable;;
787 event = IWEVASSOCREQIE; 796 iwm->req_ie_len =
797 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
798 kfree(iwm->req_ie);
799 iwm->req_ie = kmemdup(mgt->u.reassoc_req.variable,
800 iwm->req_ie_len, GFP_KERNEL);
788 } else if (ieee80211_is_assoc_resp(mgt->frame_control)) { 801 } else if (ieee80211_is_assoc_resp(mgt->frame_control)) {
789 ie = mgt->u.assoc_resp.variable;; 802 ie = mgt->u.assoc_resp.variable;;
790 event = IWEVASSOCRESPIE; 803 iwm->resp_ie_len =
804 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
805 kfree(iwm->resp_ie);
806 iwm->resp_ie = kmemdup(mgt->u.assoc_resp.variable,
807 iwm->resp_ie_len, GFP_KERNEL);
791 } else if (ieee80211_is_reassoc_resp(mgt->frame_control)) { 808 } else if (ieee80211_is_reassoc_resp(mgt->frame_control)) {
792 ie = mgt->u.reassoc_resp.variable;; 809 ie = mgt->u.reassoc_resp.variable;;
793 event = IWEVASSOCRESPIE; 810 iwm->resp_ie_len =
811 le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
812 kfree(iwm->resp_ie);
813 iwm->resp_ie = kmemdup(mgt->u.reassoc_resp.variable,
814 iwm->resp_ie_len, GFP_KERNEL);
794 } else { 815 } else {
795 IWM_ERR(iwm, "Unsupported management frame"); 816 IWM_ERR(iwm, "Unsupported management frame");
796 return 0; 817 return 0;
797 } 818 }
798 819
799 wrqu.data.length = le16_to_cpu(mgt_frame->len) - (ie - (u8 *)mgt);
800
801 IWM_HEXDUMP(iwm, DBG, MLME, "EVT: ", ie, wrqu.data.length);
802 wireless_send_event(iwm_to_ndev(iwm), event, &wrqu, ie);
803
804 return 0; 820 return 0;
805} 821}
806 822
@@ -1360,7 +1376,7 @@ static void iwm_rx_process_packet(struct iwm_priv *iwm,
1360 1376
1361 skb->dev = iwm_to_ndev(iwm); 1377 skb->dev = iwm_to_ndev(iwm);
1362 skb->protocol = eth_type_trans(skb, ndev); 1378 skb->protocol = eth_type_trans(skb, ndev);
1363 skb->ip_summed = CHECKSUM_UNNECESSARY; 1379 skb->ip_summed = CHECKSUM_NONE;
1364 memset(skb->cb, 0, sizeof(skb->cb)); 1380 memset(skb->cb, 0, sizeof(skb->cb));
1365 1381
1366 ndev->stats.rx_packets++; 1382 ndev->stats.rx_packets++;
diff --git a/drivers/net/wireless/iwmc3200wifi/umac.h b/drivers/net/wireless/iwmc3200wifi/umac.h
index 0af2a3c76281..c5a14ae3160a 100644
--- a/drivers/net/wireless/iwmc3200wifi/umac.h
+++ b/drivers/net/wireless/iwmc3200wifi/umac.h
@@ -615,6 +615,7 @@ struct iwm_umac_notif_alive {
615} __attribute__ ((packed)); 615} __attribute__ ((packed));
616 616
617struct iwm_umac_notif_init_complete { 617struct iwm_umac_notif_init_complete {
618 struct iwm_umac_wifi_in_hdr hdr;
618 __le16 status; 619 __le16 status;
619 __le16 reserved; 620 __le16 reserved;
620} __attribute__ ((packed)); 621} __attribute__ ((packed));
@@ -643,6 +644,11 @@ struct iwm_fw_error_hdr {
643 __le32 umac_status; 644 __le32 umac_status;
644 __le32 lmac_status; 645 __le32 lmac_status;
645 __le32 sdio_status; 646 __le32 sdio_status;
647 __le32 dbm_sample_ctrl;
648 __le32 dbm_buf_base;
649 __le32 dbm_buf_end;
650 __le32 dbm_buf_write_ptr;
651 __le32 dbm_buf_cycle_cnt;
646} __attribute__ ((packed)); 652} __attribute__ ((packed));
647 653
648struct iwm_umac_notif_error { 654struct iwm_umac_notif_error {
diff --git a/drivers/net/wireless/iwmc3200wifi/wext.c b/drivers/net/wireless/iwmc3200wifi/wext.c
index 2e7eaf96cf93..c3c90d5963bf 100644
--- a/drivers/net/wireless/iwmc3200wifi/wext.c
+++ b/drivers/net/wireless/iwmc3200wifi/wext.c
@@ -21,31 +21,11 @@
21 * 21 *
22 */ 22 */
23 23
24#include <linux/kernel.h>
25#include <linux/netdevice.h>
26#include <linux/wireless.h> 24#include <linux/wireless.h>
27#include <linux/if_arp.h>
28#include <linux/etherdevice.h>
29#include <net/cfg80211.h> 25#include <net/cfg80211.h>
30#include <net/iw_handler.h>
31 26
32#include "iwm.h" 27#include "iwm.h"
33#include "umac.h"
34#include "commands.h" 28#include "commands.h"
35#include "debug.h"
36
37static struct iw_statistics *iwm_get_wireless_stats(struct net_device *dev)
38{
39 struct iwm_priv *iwm = ndev_to_iwm(dev);
40 struct iw_statistics *wstats = &iwm->wstats;
41
42 if (!test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) {
43 memset(wstats, 0, sizeof(struct iw_statistics));
44 wstats->qual.updated = IW_QUAL_ALL_INVALID;
45 }
46
47 return wstats;
48}
49 29
50static int iwm_wext_siwfreq(struct net_device *dev, 30static int iwm_wext_siwfreq(struct net_device *dev,
51 struct iw_request_info *info, 31 struct iw_request_info *info,
@@ -53,14 +33,12 @@ static int iwm_wext_siwfreq(struct net_device *dev,
53{ 33{
54 struct iwm_priv *iwm = ndev_to_iwm(dev); 34 struct iwm_priv *iwm = ndev_to_iwm(dev);
55 35
56 if (freq->flags == IW_FREQ_AUTO) 36 switch (iwm->conf.mode) {
57 return 0; 37 case UMAC_MODE_IBSS:
58 38 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
59 /* frequency/channel can only be set in IBSS mode */ 39 default:
60 if (iwm->conf.mode != UMAC_MODE_IBSS)
61 return -EOPNOTSUPP; 40 return -EOPNOTSUPP;
62 41 }
63 return cfg80211_ibss_wext_siwfreq(dev, info, freq, extra);
64} 42}
65 43
66static int iwm_wext_giwfreq(struct net_device *dev, 44static int iwm_wext_giwfreq(struct net_device *dev,
@@ -69,69 +47,29 @@ static int iwm_wext_giwfreq(struct net_device *dev,
69{ 47{
70 struct iwm_priv *iwm = ndev_to_iwm(dev); 48 struct iwm_priv *iwm = ndev_to_iwm(dev);
71 49
72 if (iwm->conf.mode == UMAC_MODE_IBSS) 50 switch (iwm->conf.mode) {
51 case UMAC_MODE_IBSS:
73 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra); 52 return cfg80211_ibss_wext_giwfreq(dev, info, freq, extra);
74 53 case UMAC_MODE_BSS:
75 freq->e = 0; 54 return cfg80211_mgd_wext_giwfreq(dev, info, freq, extra);
76 freq->m = iwm->channel; 55 default:
77 56 return -EOPNOTSUPP;
78 return 0; 57 }
79} 58}
80 59
81static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info, 60static int iwm_wext_siwap(struct net_device *dev, struct iw_request_info *info,
82 struct sockaddr *ap_addr, char *extra) 61 struct sockaddr *ap_addr, char *extra)
83{ 62{
84 struct iwm_priv *iwm = ndev_to_iwm(dev); 63 struct iwm_priv *iwm = ndev_to_iwm(dev);
85 int ret;
86
87 IWM_DBG_WEXT(iwm, DBG, "Set BSSID: %pM\n", ap_addr->sa_data);
88 64
89 if (iwm->conf.mode == UMAC_MODE_IBSS) 65 switch (iwm->conf.mode) {
66 case UMAC_MODE_IBSS:
90 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra); 67 return cfg80211_ibss_wext_siwap(dev, info, ap_addr, extra);
91 68 case UMAC_MODE_BSS:
92 if (!test_bit(IWM_STATUS_READY, &iwm->status)) 69 return cfg80211_mgd_wext_siwap(dev, info, ap_addr, extra);
93 return -EIO; 70 default:
94 71 return -EOPNOTSUPP;
95 if (is_zero_ether_addr(ap_addr->sa_data) ||
96 is_broadcast_ether_addr(ap_addr->sa_data)) {
97 IWM_DBG_WEXT(iwm, DBG, "clear mandatory bssid %pM\n",
98 iwm->umac_profile->bssid[0]);
99 memset(&iwm->umac_profile->bssid[0], 0, ETH_ALEN);
100 iwm->umac_profile->bss_num = 0;
101 } else {
102 IWM_DBG_WEXT(iwm, DBG, "add mandatory bssid %pM\n",
103 ap_addr->sa_data);
104 memcpy(&iwm->umac_profile->bssid[0], ap_addr->sa_data,
105 ETH_ALEN);
106 iwm->umac_profile->bss_num = 1;
107 }
108
109 if (iwm->umac_profile_active) {
110 int i;
111
112 if (!memcmp(&iwm->umac_profile->bssid[0], iwm->bssid, ETH_ALEN))
113 return 0;
114
115 /*
116 * If we're clearing the BSSID, and we're associated,
117 * we have to clear the keys as they're no longer valid.
118 */
119 if (is_zero_ether_addr(ap_addr->sa_data)) {
120 for (i = 0; i < IWM_NUM_KEYS; i++)
121 iwm->keys[i].key_len = 0;
122 }
123
124 ret = iwm_invalidate_mlme_profile(iwm);
125 if (ret < 0) {
126 IWM_ERR(iwm, "Couldn't invalidate profile\n");
127 return ret;
128 }
129 } 72 }
130
131 if (iwm->umac_profile->ssid.ssid_len)
132 return iwm_send_mlme_profile(iwm);
133
134 return 0;
135} 73}
136 74
137static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info, 75static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info,
@@ -143,17 +81,10 @@ static int iwm_wext_giwap(struct net_device *dev, struct iw_request_info *info,
143 case UMAC_MODE_IBSS: 81 case UMAC_MODE_IBSS:
144 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra); 82 return cfg80211_ibss_wext_giwap(dev, info, ap_addr, extra);
145 case UMAC_MODE_BSS: 83 case UMAC_MODE_BSS:
146 if (test_bit(IWM_STATUS_ASSOCIATED, &iwm->status)) { 84 return cfg80211_mgd_wext_giwap(dev, info, ap_addr, extra);
147 ap_addr->sa_family = ARPHRD_ETHER;
148 memcpy(&ap_addr->sa_data, iwm->bssid, ETH_ALEN);
149 } else
150 memset(&ap_addr->sa_data, 0, ETH_ALEN);
151 break;
152 default: 85 default:
153 return -EOPNOTSUPP; 86 return -EOPNOTSUPP;
154 } 87 }
155
156 return 0;
157} 88}
158 89
159static int iwm_wext_siwessid(struct net_device *dev, 90static int iwm_wext_siwessid(struct net_device *dev,
@@ -161,36 +92,15 @@ static int iwm_wext_siwessid(struct net_device *dev,
161 struct iw_point *data, char *ssid) 92 struct iw_point *data, char *ssid)
162{ 93{
163 struct iwm_priv *iwm = ndev_to_iwm(dev); 94 struct iwm_priv *iwm = ndev_to_iwm(dev);
164 size_t len = data->length;
165 int ret;
166
167 IWM_DBG_WEXT(iwm, DBG, "Set ESSID: >%s<\n", ssid);
168 95
169 if (iwm->conf.mode == UMAC_MODE_IBSS) 96 switch (iwm->conf.mode) {
97 case UMAC_MODE_IBSS:
170 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid); 98 return cfg80211_ibss_wext_siwessid(dev, info, data, ssid);
171 99 case UMAC_MODE_BSS:
172 if (!test_bit(IWM_STATUS_READY, &iwm->status)) 100 return cfg80211_mgd_wext_siwessid(dev, info, data, ssid);
173 return -EIO; 101 default:
174 102 return -EOPNOTSUPP;
175 if (len > 0 && ssid[len - 1] == '\0')
176 len--;
177
178 if (iwm->umac_profile_active) {
179 if (iwm->umac_profile->ssid.ssid_len == len &&
180 !memcmp(iwm->umac_profile->ssid.ssid, ssid, len))
181 return 0;
182
183 ret = iwm_invalidate_mlme_profile(iwm);
184 if (ret < 0) {
185 IWM_ERR(iwm, "Couldn't invalidate profile\n");
186 return ret;
187 }
188 } 103 }
189
190 iwm->umac_profile->ssid.ssid_len = len;
191 memcpy(iwm->umac_profile->ssid.ssid, ssid, len);
192
193 return iwm_send_mlme_profile(iwm);
194} 104}
195 105
196static int iwm_wext_giwessid(struct net_device *dev, 106static int iwm_wext_giwessid(struct net_device *dev,
@@ -199,174 +109,14 @@ static int iwm_wext_giwessid(struct net_device *dev,
199{ 109{
200 struct iwm_priv *iwm = ndev_to_iwm(dev); 110 struct iwm_priv *iwm = ndev_to_iwm(dev);
201 111
202 if (iwm->conf.mode == UMAC_MODE_IBSS) 112 switch (iwm->conf.mode) {
113 case UMAC_MODE_IBSS:
203 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid); 114 return cfg80211_ibss_wext_giwessid(dev, info, data, ssid);
204 115 case UMAC_MODE_BSS:
205 if (!test_bit(IWM_STATUS_READY, &iwm->status)) 116 return cfg80211_mgd_wext_giwessid(dev, info, data, ssid);
206 return -EIO;
207
208 data->length = iwm->umac_profile->ssid.ssid_len;
209 if (data->length) {
210 memcpy(ssid, iwm->umac_profile->ssid.ssid, data->length);
211 data->flags = 1;
212 } else
213 data->flags = 0;
214
215 return 0;
216}
217
218static int iwm_wext_giwrate(struct net_device *dev,
219 struct iw_request_info *info,
220 struct iw_param *rate, char *extra)
221{
222 struct iwm_priv *iwm = ndev_to_iwm(dev);
223
224 rate->value = iwm->rate * 1000000;
225
226 return 0;
227}
228
229static int iwm_set_wpa_version(struct iwm_priv *iwm, u8 wpa_version)
230{
231 if (wpa_version & IW_AUTH_WPA_VERSION_WPA2)
232 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_RSNA_ON_MSK;
233 else if (wpa_version & IW_AUTH_WPA_VERSION_WPA)
234 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_WPA_ON_MSK;
235 else
236 iwm->umac_profile->sec.flags = UMAC_SEC_FLG_LEGACY_PROFILE;
237
238 return 0;
239}
240
241static int iwm_set_key_mgt(struct iwm_priv *iwm, u8 key_mgt)
242{
243 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
244
245 IWM_DBG_WEXT(iwm, DBG, "key_mgt: 0x%x\n", key_mgt);
246
247 if (key_mgt == IW_AUTH_KEY_MGMT_802_1X)
248 *auth_type = UMAC_AUTH_TYPE_8021X;
249 else if (key_mgt == IW_AUTH_KEY_MGMT_PSK) {
250 if (iwm->umac_profile->sec.flags &
251 (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK))
252 *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
253 else
254 *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
255 } else {
256 IWM_ERR(iwm, "Invalid key mgt: 0x%x\n", key_mgt);
257 return -EINVAL;
258 }
259
260 return 0;
261}
262
263static int iwm_set_cipher(struct iwm_priv *iwm, u8 cipher, u8 ucast)
264{
265 u8 *profile_cipher = ucast ? &iwm->umac_profile->sec.ucast_cipher :
266 &iwm->umac_profile->sec.mcast_cipher;
267
268 switch (cipher) {
269 case IW_AUTH_CIPHER_NONE:
270 *profile_cipher = UMAC_CIPHER_TYPE_NONE;
271 break;
272 case IW_AUTH_CIPHER_WEP40:
273 *profile_cipher = UMAC_CIPHER_TYPE_WEP_40;
274 break;
275 case IW_AUTH_CIPHER_TKIP:
276 *profile_cipher = UMAC_CIPHER_TYPE_TKIP;
277 break;
278 case IW_AUTH_CIPHER_CCMP:
279 *profile_cipher = UMAC_CIPHER_TYPE_CCMP;
280 break;
281 case IW_AUTH_CIPHER_WEP104:
282 *profile_cipher = UMAC_CIPHER_TYPE_WEP_104;
283 break;
284 default:
285 IWM_ERR(iwm, "Unsupported cipher: 0x%x\n", cipher);
286 return -ENOTSUPP;
287 }
288
289 return 0;
290}
291
292static int iwm_set_auth_alg(struct iwm_priv *iwm, u8 auth_alg)
293{
294 u8 *auth_type = &iwm->umac_profile->sec.auth_type;
295
296 IWM_DBG_WEXT(iwm, DBG, "auth_alg: 0x%x\n", auth_alg);
297
298 switch (auth_alg) {
299 case IW_AUTH_ALG_OPEN_SYSTEM:
300 *auth_type = UMAC_AUTH_TYPE_OPEN;
301 break;
302 case IW_AUTH_ALG_SHARED_KEY:
303 if (iwm->umac_profile->sec.flags &
304 (UMAC_SEC_FLG_WPA_ON_MSK | UMAC_SEC_FLG_RSNA_ON_MSK)) {
305 if (*auth_type == UMAC_AUTH_TYPE_8021X)
306 return -EINVAL;
307 *auth_type = UMAC_AUTH_TYPE_RSNA_PSK;
308 } else {
309 IWM_DBG_WEXT(iwm, DBG, "WEP shared key\n");
310 *auth_type = UMAC_AUTH_TYPE_LEGACY_PSK;
311 }
312 break;
313 case IW_AUTH_ALG_LEAP:
314 default:
315 IWM_ERR(iwm, "Unsupported auth alg: 0x%x\n", auth_alg);
316 return -ENOTSUPP;
317 }
318
319 return 0;
320}
321
322static int iwm_wext_siwauth(struct net_device *dev,
323 struct iw_request_info *info,
324 struct iw_param *data, char *extra)
325{
326 struct iwm_priv *iwm = ndev_to_iwm(dev);
327 int ret;
328
329 if ((data->flags) &
330 (IW_AUTH_WPA_VERSION | IW_AUTH_KEY_MGMT |
331 IW_AUTH_WPA_ENABLED | IW_AUTH_80211_AUTH_ALG)) {
332 /* We need to invalidate the current profile */
333 if (iwm->umac_profile_active) {
334 ret = iwm_invalidate_mlme_profile(iwm);
335 if (ret < 0) {
336 IWM_ERR(iwm, "Couldn't invalidate profile\n");
337 return ret;
338 }
339 }
340 }
341
342 switch (data->flags & IW_AUTH_INDEX) {
343 case IW_AUTH_WPA_VERSION:
344 return iwm_set_wpa_version(iwm, data->value);
345 break;
346 case IW_AUTH_CIPHER_PAIRWISE:
347 return iwm_set_cipher(iwm, data->value, 1);
348 break;
349 case IW_AUTH_CIPHER_GROUP:
350 return iwm_set_cipher(iwm, data->value, 0);
351 break;
352 case IW_AUTH_KEY_MGMT:
353 return iwm_set_key_mgt(iwm, data->value);
354 break;
355 case IW_AUTH_80211_AUTH_ALG:
356 return iwm_set_auth_alg(iwm, data->value);
357 break;
358 default: 117 default:
359 return -ENOTSUPP; 118 return -EOPNOTSUPP;
360 } 119 }
361
362 return 0;
363}
364
365static int iwm_wext_giwauth(struct net_device *dev,
366 struct iw_request_info *info,
367 struct iw_param *data, char *extra)
368{
369 return 0;
370} 120}
371 121
372static const iw_handler iwm_handlers[] = 122static const iw_handler iwm_handlers[] =
@@ -404,7 +154,7 @@ static const iw_handler iwm_handlers[] =
404 (iw_handler) NULL, /* -- hole -- */ 154 (iw_handler) NULL, /* -- hole -- */
405 (iw_handler) NULL, /* -- hole -- */ 155 (iw_handler) NULL, /* -- hole -- */
406 (iw_handler) NULL, /* SIOCSIWRATE */ 156 (iw_handler) NULL, /* SIOCSIWRATE */
407 (iw_handler) iwm_wext_giwrate, /* SIOCGIWRATE */ 157 (iw_handler) cfg80211_wext_giwrate, /* SIOCGIWRATE */
408 (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */ 158 (iw_handler) cfg80211_wext_siwrts, /* SIOCSIWRTS */
409 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */ 159 (iw_handler) cfg80211_wext_giwrts, /* SIOCGIWRTS */
410 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */ 160 (iw_handler) cfg80211_wext_siwfrag, /* SIOCSIWFRAG */
@@ -419,10 +169,10 @@ static const iw_handler iwm_handlers[] =
419 (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */ 169 (iw_handler) cfg80211_wext_giwpower, /* SIOCGIWPOWER */
420 (iw_handler) NULL, /* -- hole -- */ 170 (iw_handler) NULL, /* -- hole -- */
421 (iw_handler) NULL, /* -- hole -- */ 171 (iw_handler) NULL, /* -- hole -- */
422 (iw_handler) NULL, /* SIOCSIWGENIE */ 172 (iw_handler) cfg80211_wext_siwgenie, /* SIOCSIWGENIE */
423 (iw_handler) NULL, /* SIOCGIWGENIE */ 173 (iw_handler) NULL, /* SIOCGIWGENIE */
424 (iw_handler) iwm_wext_siwauth, /* SIOCSIWAUTH */ 174 (iw_handler) cfg80211_wext_siwauth, /* SIOCSIWAUTH */
425 (iw_handler) iwm_wext_giwauth, /* SIOCGIWAUTH */ 175 (iw_handler) cfg80211_wext_giwauth, /* SIOCGIWAUTH */
426 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */ 176 (iw_handler) cfg80211_wext_siwencodeext, /* SIOCSIWENCODEEXT */
427 (iw_handler) NULL, /* SIOCGIWENCODEEXT */ 177 (iw_handler) NULL, /* SIOCGIWENCODEEXT */
428 (iw_handler) NULL, /* SIOCSIWPMKSA */ 178 (iw_handler) NULL, /* SIOCSIWPMKSA */
@@ -432,6 +182,6 @@ static const iw_handler iwm_handlers[] =
432const struct iw_handler_def iwm_iw_handler_def = { 182const struct iw_handler_def iwm_iw_handler_def = {
433 .num_standard = ARRAY_SIZE(iwm_handlers), 183 .num_standard = ARRAY_SIZE(iwm_handlers),
434 .standard = (iw_handler *) iwm_handlers, 184 .standard = (iw_handler *) iwm_handlers,
435 .get_wireless_stats = iwm_get_wireless_stats, 185 .get_wireless_stats = cfg80211_wireless_stats,
436}; 186};
437 187
diff --git a/drivers/net/wireless/libertas/assoc.c b/drivers/net/wireless/libertas/assoc.c
index fbf26499c9a9..385b50f4b105 100644
--- a/drivers/net/wireless/libertas/assoc.c
+++ b/drivers/net/wireless/libertas/assoc.c
@@ -129,7 +129,6 @@ static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth
129{ 129{
130 struct cmd_ds_802_11_authenticate cmd; 130 struct cmd_ds_802_11_authenticate cmd;
131 int ret = -1; 131 int ret = -1;
132 DECLARE_MAC_BUF(mac);
133 132
134 lbs_deb_enter(LBS_DEB_JOIN); 133 lbs_deb_enter(LBS_DEB_JOIN);
135 134
@@ -138,8 +137,7 @@ static int lbs_set_authentication(struct lbs_private *priv, u8 bssid[6], u8 auth
138 137
139 cmd.authtype = iw_auth_to_ieee_auth(auth); 138 cmd.authtype = iw_auth_to_ieee_auth(auth);
140 139
141 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n", 140 lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n", bssid, cmd.authtype);
142 print_mac(mac, bssid), cmd.authtype);
143 141
144 ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd); 142 ret = lbs_cmd_with_response(priv, CMD_802_11_AUTHENTICATE, &cmd);
145 143
@@ -342,8 +340,6 @@ static int lbs_associate(struct lbs_private *priv,
342 340
343 /* Firmware v9+ indicate authentication suites as a TLV */ 341 /* Firmware v9+ indicate authentication suites as a TLV */
344 if (priv->fwrelease >= 0x09000000) { 342 if (priv->fwrelease >= 0x09000000) {
345 DECLARE_MAC_BUF(mac);
346
347 auth = (struct mrvl_ie_auth_type *) pos; 343 auth = (struct mrvl_ie_auth_type *) pos;
348 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE); 344 auth->header.type = cpu_to_le16(TLV_TYPE_AUTH_TYPE);
349 auth->header.len = cpu_to_le16(2); 345 auth->header.len = cpu_to_le16(2);
@@ -351,8 +347,8 @@ static int lbs_associate(struct lbs_private *priv,
351 auth->auth = cpu_to_le16(tmpauth); 347 auth->auth = cpu_to_le16(tmpauth);
352 pos += sizeof(auth->header) + 2; 348 pos += sizeof(auth->header) + 2;
353 349
354 lbs_deb_join("AUTH_CMD: BSSID %s, auth 0x%x\n", 350 lbs_deb_join("AUTH_CMD: BSSID %pM, auth 0x%x\n",
355 print_mac(mac, bss->bssid), priv->secinfo.auth_mode); 351 bss->bssid, priv->secinfo.auth_mode);
356 } 352 }
357 353
358 /* WPA/WPA2 IEs */ 354 /* WPA/WPA2 IEs */
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index e9b5442f1dda..930f5c7da4a6 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -406,7 +406,8 @@ static bool mac80211_hwsim_tx_frame(struct ieee80211_hw *hw,
406 rx_status.freq = data->channel->center_freq; 406 rx_status.freq = data->channel->center_freq;
407 rx_status.band = data->channel->band; 407 rx_status.band = data->channel->band;
408 rx_status.rate_idx = info->control.rates[0].idx; 408 rx_status.rate_idx = info->control.rates[0].idx;
409 /* TODO: simulate signal strength (and optional packet drop) */ 409 /* TODO: simulate real signal strength (and optional packet loss) */
410 rx_status.signal = -50;
410 411
411 if (data->ps != PS_DISABLED) 412 if (data->ps != PS_DISABLED)
412 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM); 413 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
@@ -836,7 +837,6 @@ static void hwsim_send_ps_poll(void *dat, u8 *mac, struct ieee80211_vif *vif)
836{ 837{
837 struct mac80211_hwsim_data *data = dat; 838 struct mac80211_hwsim_data *data = dat;
838 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 839 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
839 DECLARE_MAC_BUF(buf);
840 struct sk_buff *skb; 840 struct sk_buff *skb;
841 struct ieee80211_pspoll *pspoll; 841 struct ieee80211_pspoll *pspoll;
842 842
@@ -866,7 +866,6 @@ static void hwsim_send_nullfunc(struct mac80211_hwsim_data *data, u8 *mac,
866 struct ieee80211_vif *vif, int ps) 866 struct ieee80211_vif *vif, int ps)
867{ 867{
868 struct hwsim_vif_priv *vp = (void *)vif->drv_priv; 868 struct hwsim_vif_priv *vp = (void *)vif->drv_priv;
869 DECLARE_MAC_BUF(buf);
870 struct sk_buff *skb; 869 struct sk_buff *skb;
871 struct ieee80211_hdr *hdr; 870 struct ieee80211_hdr *hdr;
872 871
@@ -1024,7 +1023,8 @@ static int __init init_mac80211_hwsim(void)
1024 BIT(NL80211_IFTYPE_AP) | 1023 BIT(NL80211_IFTYPE_AP) |
1025 BIT(NL80211_IFTYPE_MESH_POINT); 1024 BIT(NL80211_IFTYPE_MESH_POINT);
1026 1025
1027 hw->flags = IEEE80211_HW_MFP_CAPABLE; 1026 hw->flags = IEEE80211_HW_MFP_CAPABLE |
1027 IEEE80211_HW_SIGNAL_DBM;
1028 1028
1029 /* ask mac80211 to reserve space for magic */ 1029 /* ask mac80211 to reserve space for magic */
1030 hw->vif_data_size = sizeof(struct hwsim_vif_priv); 1030 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index b9eded88c322..4f725473fb73 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2271,7 +2271,6 @@ static int mwl8k_cmd_update_sta_db(struct ieee80211_hw *hw,
2271 struct mwl8k_cmd_update_sta_db *cmd; 2271 struct mwl8k_cmd_update_sta_db *cmd;
2272 struct peer_capability_info *peer_info; 2272 struct peer_capability_info *peer_info;
2273 struct ieee80211_rate *bitrates = mv_vif->legacy_rates; 2273 struct ieee80211_rate *bitrates = mv_vif->legacy_rates;
2274 DECLARE_MAC_BUF(mac);
2275 int rc; 2274 int rc;
2276 __u8 count, *rates; 2275 __u8 count, *rates;
2277 2276
@@ -3480,7 +3479,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3480{ 3479{
3481 struct ieee80211_hw *hw; 3480 struct ieee80211_hw *hw;
3482 struct mwl8k_priv *priv; 3481 struct mwl8k_priv *priv;
3483 DECLARE_MAC_BUF(mac);
3484 int rc; 3482 int rc;
3485 int i; 3483 int i;
3486 u8 *fw; 3484 u8 *fw;
@@ -3669,8 +3667,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3669 MWL8K_DESC); 3667 MWL8K_DESC);
3670 printk(KERN_INFO "%s: Driver Ver:%s Firmware Ver:%u.%u.%u.%u\n", 3668 printk(KERN_INFO "%s: Driver Ver:%s Firmware Ver:%u.%u.%u.%u\n",
3671 priv->name, MWL8K_VERSION, fw[3], fw[2], fw[1], fw[0]); 3669 priv->name, MWL8K_VERSION, fw[3], fw[2], fw[1], fw[0]);
3672 printk(KERN_INFO "%s: MAC Address: %s\n", priv->name, 3670 printk(KERN_INFO "%s: MAC Address: %pM\n", priv->name,
3673 print_mac(mac, hw->wiphy->perm_addr)); 3671 hw->wiphy->perm_addr);
3674 3672
3675 return 0; 3673 return 0;
3676 3674
diff --git a/drivers/net/wireless/p54/eeprom.c b/drivers/net/wireless/p54/eeprom.c
index a2a044ef1012..0efe67deedee 100644
--- a/drivers/net/wireless/p54/eeprom.c
+++ b/drivers/net/wireless/p54/eeprom.c
@@ -19,6 +19,7 @@
19#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/firmware.h> 20#include <linux/firmware.h>
21#include <linux/etherdevice.h> 21#include <linux/etherdevice.h>
22#include <linux/sort.h>
22 23
23#include <net/mac80211.h> 24#include <net/mac80211.h>
24 25
@@ -41,30 +42,6 @@ static struct ieee80211_rate p54_bgrates[] = {
41 { .bitrate = 540, .hw_value = 11, }, 42 { .bitrate = 540, .hw_value = 11, },
42}; 43};
43 44
44static struct ieee80211_channel p54_bgchannels[] = {
45 { .center_freq = 2412, .hw_value = 1, },
46 { .center_freq = 2417, .hw_value = 2, },
47 { .center_freq = 2422, .hw_value = 3, },
48 { .center_freq = 2427, .hw_value = 4, },
49 { .center_freq = 2432, .hw_value = 5, },
50 { .center_freq = 2437, .hw_value = 6, },
51 { .center_freq = 2442, .hw_value = 7, },
52 { .center_freq = 2447, .hw_value = 8, },
53 { .center_freq = 2452, .hw_value = 9, },
54 { .center_freq = 2457, .hw_value = 10, },
55 { .center_freq = 2462, .hw_value = 11, },
56 { .center_freq = 2467, .hw_value = 12, },
57 { .center_freq = 2472, .hw_value = 13, },
58 { .center_freq = 2484, .hw_value = 14, },
59};
60
61static struct ieee80211_supported_band band_2GHz = {
62 .channels = p54_bgchannels,
63 .n_channels = ARRAY_SIZE(p54_bgchannels),
64 .bitrates = p54_bgrates,
65 .n_bitrates = ARRAY_SIZE(p54_bgrates),
66};
67
68static struct ieee80211_rate p54_arates[] = { 45static struct ieee80211_rate p54_arates[] = {
69 { .bitrate = 60, .hw_value = 4, }, 46 { .bitrate = 60, .hw_value = 4, },
70 { .bitrate = 90, .hw_value = 5, }, 47 { .bitrate = 90, .hw_value = 5, },
@@ -76,51 +53,257 @@ static struct ieee80211_rate p54_arates[] = {
76 { .bitrate = 540, .hw_value = 11, }, 53 { .bitrate = 540, .hw_value = 11, },
77}; 54};
78 55
79static struct ieee80211_channel p54_achannels[] = { 56#define CHAN_HAS_CAL BIT(0)
80 { .center_freq = 4920 }, 57#define CHAN_HAS_LIMIT BIT(1)
81 { .center_freq = 4940 }, 58#define CHAN_HAS_CURVE BIT(2)
82 { .center_freq = 4960 }, 59#define CHAN_HAS_ALL (CHAN_HAS_CAL | CHAN_HAS_LIMIT | CHAN_HAS_CURVE)
83 { .center_freq = 4980 }, 60
84 { .center_freq = 5040 }, 61struct p54_channel_entry {
85 { .center_freq = 5060 }, 62 u16 freq;
86 { .center_freq = 5080 }, 63 u16 data;
87 { .center_freq = 5170 }, 64 int index;
88 { .center_freq = 5180 }, 65 enum ieee80211_band band;
89 { .center_freq = 5190 },
90 { .center_freq = 5200 },
91 { .center_freq = 5210 },
92 { .center_freq = 5220 },
93 { .center_freq = 5230 },
94 { .center_freq = 5240 },
95 { .center_freq = 5260 },
96 { .center_freq = 5280 },
97 { .center_freq = 5300 },
98 { .center_freq = 5320 },
99 { .center_freq = 5500 },
100 { .center_freq = 5520 },
101 { .center_freq = 5540 },
102 { .center_freq = 5560 },
103 { .center_freq = 5580 },
104 { .center_freq = 5600 },
105 { .center_freq = 5620 },
106 { .center_freq = 5640 },
107 { .center_freq = 5660 },
108 { .center_freq = 5680 },
109 { .center_freq = 5700 },
110 { .center_freq = 5745 },
111 { .center_freq = 5765 },
112 { .center_freq = 5785 },
113 { .center_freq = 5805 },
114 { .center_freq = 5825 },
115}; 66};
116 67
117static struct ieee80211_supported_band band_5GHz = { 68struct p54_channel_list {
118 .channels = p54_achannels, 69 struct p54_channel_entry *channels;
119 .n_channels = ARRAY_SIZE(p54_achannels), 70 size_t entries;
120 .bitrates = p54_arates, 71 size_t max_entries;
121 .n_bitrates = ARRAY_SIZE(p54_arates), 72 size_t band_channel_num[IEEE80211_NUM_BANDS];
122}; 73};
123 74
75static int p54_get_band_from_freq(u16 freq)
76{
77 /* FIXME: sync these values with the 802.11 spec */
78
79 if ((freq >= 2412) && (freq <= 2484))
80 return IEEE80211_BAND_2GHZ;
81
82 if ((freq >= 4920) && (freq <= 5825))
83 return IEEE80211_BAND_5GHZ;
84
85 return -1;
86}
87
88static int p54_compare_channels(const void *_a,
89 const void *_b)
90{
91 const struct p54_channel_entry *a = _a;
92 const struct p54_channel_entry *b = _b;
93
94 return a->index - b->index;
95}
96
97static int p54_fill_band_bitrates(struct ieee80211_hw *dev,
98 struct ieee80211_supported_band *band_entry,
99 enum ieee80211_band band)
100{
101 /* TODO: generate rate array dynamically */
102
103 switch (band) {
104 case IEEE80211_BAND_2GHZ:
105 band_entry->bitrates = p54_bgrates;
106 band_entry->n_bitrates = ARRAY_SIZE(p54_bgrates);
107 break;
108 case IEEE80211_BAND_5GHZ:
109 band_entry->bitrates = p54_arates;
110 band_entry->n_bitrates = ARRAY_SIZE(p54_arates);
111 break;
112 default:
113 return -EINVAL;
114 }
115
116 return 0;
117}
118
119static int p54_generate_band(struct ieee80211_hw *dev,
120 struct p54_channel_list *list,
121 enum ieee80211_band band)
122{
123 struct p54_common *priv = dev->priv;
124 struct ieee80211_supported_band *tmp, *old;
125 unsigned int i, j;
126 int ret = -ENOMEM;
127
128 if ((!list->entries) || (!list->band_channel_num[band]))
129 return 0;
130
131 tmp = kzalloc(sizeof(*tmp), GFP_KERNEL);
132 if (!tmp)
133 goto err_out;
134
135 tmp->channels = kzalloc(sizeof(struct ieee80211_channel) *
136 list->band_channel_num[band], GFP_KERNEL);
137 if (!tmp->channels)
138 goto err_out;
139
140 ret = p54_fill_band_bitrates(dev, tmp, band);
141 if (ret)
142 goto err_out;
143
144 for (i = 0, j = 0; (j < list->band_channel_num[band]) &&
145 (i < list->entries); i++) {
146
147 if (list->channels[i].band != band)
148 continue;
149
150 if (list->channels[i].data != CHAN_HAS_ALL) {
151 printk(KERN_ERR "%s:%s%s%s is/are missing for "
152 "channel:%d [%d MHz].\n",
153 wiphy_name(dev->wiphy),
154 (list->channels[i].data & CHAN_HAS_CAL ? "" :
155 " [iqauto calibration data]"),
156 (list->channels[i].data & CHAN_HAS_LIMIT ? "" :
157 " [output power limits]"),
158 (list->channels[i].data & CHAN_HAS_CURVE ? "" :
159 " [curve data]"),
160 list->channels[i].index, list->channels[i].freq);
161 }
162
163 tmp->channels[j].band = list->channels[i].band;
164 tmp->channels[j].center_freq = list->channels[i].freq;
165 j++;
166 }
167
168 tmp->n_channels = list->band_channel_num[band];
169 old = priv->band_table[band];
170 priv->band_table[band] = tmp;
171 if (old) {
172 kfree(old->channels);
173 kfree(old);
174 }
175
176 return 0;
177
178err_out:
179 if (tmp) {
180 kfree(tmp->channels);
181 kfree(tmp);
182 }
183
184 return ret;
185}
186
187static void p54_update_channel_param(struct p54_channel_list *list,
188 u16 freq, u16 data)
189{
190 int band, i;
191
192 /*
193 * usually all lists in the eeprom are mostly sorted.
194 * so it's very likely that the entry we are looking for
195 * is right at the end of the list
196 */
197 for (i = list->entries; i >= 0; i--) {
198 if (freq == list->channels[i].freq) {
199 list->channels[i].data |= data;
200 break;
201 }
202 }
203
204 if ((i < 0) && (list->entries < list->max_entries)) {
205 /* entry does not exist yet. Initialize a new one. */
206 band = p54_get_band_from_freq(freq);
207
208 /*
209 * filter out frequencies which don't belong into
210 * any supported band.
211 */
212 if (band < 0)
213 return ;
214
215 i = list->entries++;
216 list->band_channel_num[band]++;
217
218 list->channels[i].freq = freq;
219 list->channels[i].data = data;
220 list->channels[i].band = band;
221 list->channels[i].index = ieee80211_frequency_to_channel(freq);
222 /* TODO: parse output_limit and fill max_power */
223 }
224}
225
226static int p54_generate_channel_lists(struct ieee80211_hw *dev)
227{
228 struct p54_common *priv = dev->priv;
229 struct p54_channel_list *list;
230 unsigned int i, j, max_channel_num;
231 int ret = -ENOMEM;
232 u16 freq;
233
234 if ((priv->iq_autocal_len != priv->curve_data->entries) ||
235 (priv->iq_autocal_len != priv->output_limit->entries))
236 printk(KERN_ERR "%s: EEPROM is damaged... you may not be able"
237 "to use all channels with this device.\n",
238 wiphy_name(dev->wiphy));
239
240 max_channel_num = max_t(unsigned int, priv->output_limit->entries,
241 priv->iq_autocal_len);
242 max_channel_num = max_t(unsigned int, max_channel_num,
243 priv->curve_data->entries);
244
245 list = kzalloc(sizeof(*list), GFP_KERNEL);
246 if (!list)
247 goto free;
248
249 list->max_entries = max_channel_num;
250 list->channels = kzalloc(sizeof(struct p54_channel_entry) *
251 max_channel_num, GFP_KERNEL);
252 if (!list->channels)
253 goto free;
254
255 for (i = 0; i < max_channel_num; i++) {
256 if (i < priv->iq_autocal_len) {
257 freq = le16_to_cpu(priv->iq_autocal[i].freq);
258 p54_update_channel_param(list, freq, CHAN_HAS_CAL);
259 }
260
261 if (i < priv->output_limit->entries) {
262 freq = le16_to_cpup((__le16 *) (i *
263 priv->output_limit->entry_size +
264 priv->output_limit->offset +
265 priv->output_limit->data));
266
267 p54_update_channel_param(list, freq, CHAN_HAS_LIMIT);
268 }
269
270 if (i < priv->curve_data->entries) {
271 freq = le16_to_cpup((__le16 *) (i *
272 priv->curve_data->entry_size +
273 priv->curve_data->offset +
274 priv->curve_data->data));
275
276 p54_update_channel_param(list, freq, CHAN_HAS_CURVE);
277 }
278 }
279
280 /* sort the list by the channel index */
281 sort(list->channels, list->entries, sizeof(struct p54_channel_entry),
282 p54_compare_channels, NULL);
283
284 for (i = 0, j = 0; i < IEEE80211_NUM_BANDS; i++) {
285 if (list->band_channel_num[i]) {
286 ret = p54_generate_band(dev, list, i);
287 if (ret)
288 goto free;
289
290 j++;
291 }
292 }
293 if (j == 0) {
294 /* no useable band available. */
295 ret = -EINVAL;
296 }
297
298free:
299 if (list) {
300 kfree(list->channels);
301 kfree(list);
302 }
303
304 return ret;
305}
306
124static int p54_convert_rev0(struct ieee80211_hw *dev, 307static int p54_convert_rev0(struct ieee80211_hw *dev,
125 struct pda_pa_curve_data *curve_data) 308 struct pda_pa_curve_data *curve_data)
126{ 309{
@@ -346,7 +529,7 @@ static struct p54_cal_database *p54_convert_db(struct pda_custom_wrapper *src,
346int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len) 529int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
347{ 530{
348 struct p54_common *priv = dev->priv; 531 struct p54_common *priv = dev->priv;
349 struct eeprom_pda_wrap *wrap = NULL; 532 struct eeprom_pda_wrap *wrap;
350 struct pda_entry *entry; 533 struct pda_entry *entry;
351 unsigned int data_len, entry_len; 534 unsigned int data_len, entry_len;
352 void *tmp; 535 void *tmp;
@@ -487,13 +670,19 @@ int p54_parse_eeprom(struct ieee80211_hw *dev, void *eeprom, int len)
487 goto err; 670 goto err;
488 } 671 }
489 672
673 err = p54_generate_channel_lists(dev);
674 if (err)
675 goto err;
676
490 priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK; 677 priv->rxhw = synth & PDR_SYNTH_FRONTEND_MASK;
491 if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW) 678 if (priv->rxhw == PDR_SYNTH_FRONTEND_XBOW)
492 p54_init_xbow_synth(priv); 679 p54_init_xbow_synth(priv);
493 if (!(synth & PDR_SYNTH_24_GHZ_DISABLED)) 680 if (!(synth & PDR_SYNTH_24_GHZ_DISABLED))
494 dev->wiphy->bands[IEEE80211_BAND_2GHZ] = &band_2GHz; 681 dev->wiphy->bands[IEEE80211_BAND_2GHZ] =
682 priv->band_table[IEEE80211_BAND_2GHZ];
495 if (!(synth & PDR_SYNTH_5_GHZ_DISABLED)) 683 if (!(synth & PDR_SYNTH_5_GHZ_DISABLED))
496 dev->wiphy->bands[IEEE80211_BAND_5GHZ] = &band_5GHz; 684 dev->wiphy->bands[IEEE80211_BAND_5GHZ] =
685 priv->band_table[IEEE80211_BAND_5GHZ];
497 if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED) 686 if ((synth & PDR_SYNTH_RX_DIV_MASK) == PDR_SYNTH_RX_DIV_SUPPORTED)
498 priv->rx_diversity_mask = 3; 687 priv->rx_diversity_mask = 3;
499 if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED) 688 if ((synth & PDR_SYNTH_TX_DIV_MASK) == PDR_SYNTH_TX_DIV_SUPPORTED)
@@ -533,7 +722,7 @@ int p54_read_eeprom(struct ieee80211_hw *dev)
533 struct p54_common *priv = dev->priv; 722 struct p54_common *priv = dev->priv;
534 size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize; 723 size_t eeprom_size = 0x2020, offset = 0, blocksize, maxblocksize;
535 int ret = -ENOMEM; 724 int ret = -ENOMEM;
536 void *eeprom = NULL; 725 void *eeprom;
537 726
538 maxblocksize = EEPROM_READBACK_LEN; 727 maxblocksize = EEPROM_READBACK_LEN;
539 if (priv->fw_var >= 0x509) 728 if (priv->fw_var >= 0x509)
diff --git a/drivers/net/wireless/p54/fwio.c b/drivers/net/wireless/p54/fwio.c
index dc4f3f5ee0c8..21f19018fab5 100644
--- a/drivers/net/wireless/p54/fwio.c
+++ b/drivers/net/wireless/p54/fwio.c
@@ -585,7 +585,8 @@ int p54_set_ps(struct p54_common *priv)
585 unsigned int i; 585 unsigned int i;
586 u16 mode; 586 u16 mode;
587 587
588 if (priv->hw->conf.flags & IEEE80211_CONF_PS) 588 if (priv->hw->conf.flags & IEEE80211_CONF_PS &&
589 !priv->powersave_override)
589 mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM | 590 mode = P54_PSM | P54_PSM_BEACON_TIMEOUT | P54_PSM_DTIM |
590 P54_PSM_CHECKSUM | P54_PSM_MCBC; 591 P54_PSM_CHECKSUM | P54_PSM_MCBC;
591 else 592 else
@@ -607,8 +608,8 @@ int p54_set_ps(struct p54_common *priv)
607 608
608 psm->beacon_rssi_skip_max = 200; 609 psm->beacon_rssi_skip_max = 200;
609 psm->rssi_delta_threshold = 0; 610 psm->rssi_delta_threshold = 0;
610 psm->nr = 10; 611 psm->nr = 1;
611 psm->exclude[0] = 0; 612 psm->exclude[0] = WLAN_EID_TIM;
612 613
613 p54_tx(priv, skb); 614 p54_tx(priv, skb);
614 return 0; 615 return 0;
@@ -685,6 +686,8 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot, u8 idx, u8 len,
685 686
686int p54_fetch_statistics(struct p54_common *priv) 687int p54_fetch_statistics(struct p54_common *priv)
687{ 688{
689 struct ieee80211_tx_info *txinfo;
690 struct p54_tx_info *p54info;
688 struct sk_buff *skb; 691 struct sk_buff *skb;
689 692
690 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL, 693 skb = p54_alloc_skb(priv, P54_HDR_FLAG_CONTROL,
@@ -693,6 +696,20 @@ int p54_fetch_statistics(struct p54_common *priv)
693 if (!skb) 696 if (!skb)
694 return -ENOMEM; 697 return -ENOMEM;
695 698
699 /*
700 * The statistic feedback causes some extra headaches here, if it
701 * is not to crash/corrupt the firmware data structures.
702 *
703 * Unlike all other Control Get OIDs we can not use helpers like
704 * skb_put to reserve the space for the data we're requesting.
705 * Instead the extra frame length -which will hold the results later-
706 * will only be told to the p54_assign_address, so that following
707 * frames won't be placed into the allegedly empty area.
708 */
709 txinfo = IEEE80211_SKB_CB(skb);
710 p54info = (void *) txinfo->rate_driver_data;
711 p54info->extra_len = sizeof(struct p54_statistics);
712
696 p54_tx(priv, skb); 713 p54_tx(priv, skb);
697 return 0; 714 return 0;
698} 715}
diff --git a/drivers/net/wireless/p54/lmac.h b/drivers/net/wireless/p54/lmac.h
index 0496cff26b35..04b63ec80fa4 100644
--- a/drivers/net/wireless/p54/lmac.h
+++ b/drivers/net/wireless/p54/lmac.h
@@ -98,6 +98,10 @@ struct p54_hdr {
98 (!((((struct p54_hdr *) ((struct sk_buff *) skb)->data)-> \ 98 (!((((struct p54_hdr *) ((struct sk_buff *) skb)->data)-> \
99 flags) & cpu_to_le16(P54_HDR_FLAG_CONTROL))) 99 flags) & cpu_to_le16(P54_HDR_FLAG_CONTROL)))
100 100
101#define GET_HW_QUEUE(skb) \
102 (((struct p54_tx_data *)((struct p54_hdr *) \
103 skb->data)->data)->hw_queue)
104
101/* 105/*
102 * shared interface ID definitions 106 * shared interface ID definitions
103 * The interface ID is a unique identification of a specific interface. 107 * The interface ID is a unique identification of a specific interface.
@@ -548,4 +552,7 @@ int p54_upload_key(struct p54_common *priv, u8 algo, int slot,
548int p54_download_eeprom(struct p54_common *priv, void *buf, 552int p54_download_eeprom(struct p54_common *priv, void *buf,
549 u16 offset, u16 len); 553 u16 offset, u16 len);
550 554
555/* utility */
556u8 *p54_find_ie(struct sk_buff *skb, u8 ie);
557
551#endif /* LMAC_H */ 558#endif /* LMAC_H */
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index f9b4f6a238ea..955f6d7ec16a 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -65,51 +65,64 @@ static int p54_set_tim(struct ieee80211_hw *dev, struct ieee80211_sta *sta,
65 return p54_update_beacon_tim(priv, sta->aid, set); 65 return p54_update_beacon_tim(priv, sta->aid, set);
66} 66}
67 67
68static int p54_beacon_format_ie_tim(struct sk_buff *skb) 68u8 *p54_find_ie(struct sk_buff *skb, u8 ie)
69{ 69{
70 /*
71 * the good excuse for this mess is ... the firmware.
72 * The dummy TIM MUST be at the end of the beacon frame,
73 * because it'll be overwritten!
74 */
75
76 struct ieee80211_mgmt *mgmt = (void *)skb->data; 70 struct ieee80211_mgmt *mgmt = (void *)skb->data;
77 u8 *pos, *end; 71 u8 *pos, *end;
78 72
79 if (skb->len <= sizeof(mgmt)) 73 if (skb->len <= sizeof(mgmt))
80 return -EINVAL; 74 return NULL;
81 75
82 pos = (u8 *)mgmt->u.beacon.variable; 76 pos = (u8 *)mgmt->u.beacon.variable;
83 end = skb->data + skb->len; 77 end = skb->data + skb->len;
84 while (pos < end) { 78 while (pos < end) {
85 if (pos + 2 + pos[1] > end) 79 if (pos + 2 + pos[1] > end)
86 return -EINVAL; 80 return NULL;
81
82 if (pos[0] == ie)
83 return pos;
84
85 pos += 2 + pos[1];
86 }
87 return NULL;
88}
89
90static int p54_beacon_format_ie_tim(struct sk_buff *skb)
91{
92 /*
93 * the good excuse for this mess is ... the firmware.
94 * The dummy TIM MUST be at the end of the beacon frame,
95 * because it'll be overwritten!
96 */
97 u8 *tim;
98 u8 dtim_len;
99 u8 dtim_period;
100 u8 *next;
87 101
88 if (pos[0] == WLAN_EID_TIM) { 102 tim = p54_find_ie(skb, WLAN_EID_TIM);
89 u8 dtim_len = pos[1]; 103 if (!tim)
90 u8 dtim_period = pos[3]; 104 return 0;
91 u8 *next = pos + 2 + dtim_len;
92 105
93 if (dtim_len < 3) 106 dtim_len = tim[1];
94 return -EINVAL; 107 dtim_period = tim[3];
108 next = tim + 2 + dtim_len;
95 109
96 memmove(pos, next, end - next); 110 if (dtim_len < 3)
111 return -EINVAL;
97 112
98 if (dtim_len > 3) 113 memmove(tim, next, skb_tail_pointer(skb) - next);
99 skb_trim(skb, skb->len - (dtim_len - 3)); 114 tim = skb_tail_pointer(skb) - (dtim_len + 2);
100 115
101 pos = end - (dtim_len + 2); 116 /* add the dummy at the end */
117 tim[0] = WLAN_EID_TIM;
118 tim[1] = 3;
119 tim[2] = 0;
120 tim[3] = dtim_period;
121 tim[4] = 0;
122
123 if (dtim_len > 3)
124 skb_trim(skb, skb->len - (dtim_len - 3));
102 125
103 /* add the dummy at the end */
104 pos[0] = WLAN_EID_TIM;
105 pos[1] = 3;
106 pos[2] = 0;
107 pos[3] = dtim_period;
108 pos[4] = 0;
109 return 0;
110 }
111 pos += 2 + pos[1];
112 }
113 return 0; 126 return 0;
114} 127}
115 128
@@ -117,7 +130,6 @@ static int p54_beacon_update(struct p54_common *priv,
117 struct ieee80211_vif *vif) 130 struct ieee80211_vif *vif)
118{ 131{
119 struct sk_buff *beacon; 132 struct sk_buff *beacon;
120 __le32 old_beacon_req_id;
121 int ret; 133 int ret;
122 134
123 beacon = ieee80211_beacon_get(priv->hw, vif); 135 beacon = ieee80211_beacon_get(priv->hw, vif);
@@ -127,15 +139,16 @@ static int p54_beacon_update(struct p54_common *priv,
127 if (ret) 139 if (ret)
128 return ret; 140 return ret;
129 141
130 old_beacon_req_id = priv->beacon_req_id; 142 /*
131 priv->beacon_req_id = GET_REQ_ID(beacon); 143 * During operation, the firmware takes care of beaconing.
132 144 * The driver only needs to upload a new beacon template, once
133 ret = p54_tx_80211(priv->hw, beacon); 145 * the template was changed by the stack or userspace.
134 if (ret) { 146 *
135 priv->beacon_req_id = old_beacon_req_id; 147 * LMAC API 3.2.2 also specifies that the driver does not need
136 return -ENOSPC; 148 * to cancel the old beacon template by hand, instead the firmware
137 } 149 * will release the previous one through the feedback mechanism.
138 150 */
151 WARN_ON(p54_tx_80211(priv->hw, beacon));
139 priv->tsf_high32 = 0; 152 priv->tsf_high32 = 0;
140 priv->tsf_low32 = 0; 153 priv->tsf_low32 = 0;
141 154
@@ -240,9 +253,14 @@ static void p54_remove_interface(struct ieee80211_hw *dev,
240 253
241 mutex_lock(&priv->conf_mutex); 254 mutex_lock(&priv->conf_mutex);
242 priv->vif = NULL; 255 priv->vif = NULL;
243 if (priv->beacon_req_id) { 256
257 /*
258 * LMAC API 3.2.2 states that any active beacon template must be
259 * canceled by the driver before attempting a mode transition.
260 */
261 if (le32_to_cpu(priv->beacon_req_id) != 0) {
244 p54_tx_cancel(priv, priv->beacon_req_id); 262 p54_tx_cancel(priv, priv->beacon_req_id);
245 priv->beacon_req_id = cpu_to_le32(0); 263 wait_for_completion_interruptible_timeout(&priv->beacon_comp, HZ);
246 } 264 }
247 priv->mode = NL80211_IFTYPE_MONITOR; 265 priv->mode = NL80211_IFTYPE_MONITOR;
248 memset(priv->mac_addr, 0, ETH_ALEN); 266 memset(priv->mac_addr, 0, ETH_ALEN);
@@ -384,6 +402,9 @@ static void p54_bss_info_changed(struct ieee80211_hw *dev,
384 priv->wakeup_timer = info->beacon_int * 402 priv->wakeup_timer = info->beacon_int *
385 info->dtim_period * 5; 403 info->dtim_period * 5;
386 p54_setup_mac(priv); 404 p54_setup_mac(priv);
405 } else {
406 priv->wakeup_timer = 500;
407 priv->aid = 0;
387 } 408 }
388 } 409 }
389 410
@@ -517,6 +538,9 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
517 skb_queue_head_init(&priv->tx_pending); 538 skb_queue_head_init(&priv->tx_pending);
518 dev->flags = IEEE80211_HW_RX_INCLUDES_FCS | 539 dev->flags = IEEE80211_HW_RX_INCLUDES_FCS |
519 IEEE80211_HW_SIGNAL_DBM | 540 IEEE80211_HW_SIGNAL_DBM |
541 IEEE80211_HW_SUPPORTS_PS |
542 IEEE80211_HW_PS_NULLFUNC_STACK |
543 IEEE80211_HW_BEACON_FILTER |
520 IEEE80211_HW_NOISE_DBM; 544 IEEE80211_HW_NOISE_DBM;
521 545
522 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 546 dev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
@@ -525,6 +549,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
525 BIT(NL80211_IFTYPE_MESH_POINT); 549 BIT(NL80211_IFTYPE_MESH_POINT);
526 550
527 dev->channel_change_time = 1000; /* TODO: find actual value */ 551 dev->channel_change_time = 1000; /* TODO: find actual value */
552 priv->beacon_req_id = cpu_to_le32(0);
528 priv->tx_stats[P54_QUEUE_BEACON].limit = 1; 553 priv->tx_stats[P54_QUEUE_BEACON].limit = 1;
529 priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1; 554 priv->tx_stats[P54_QUEUE_FWSCAN].limit = 1;
530 priv->tx_stats[P54_QUEUE_MGMT].limit = 3; 555 priv->tx_stats[P54_QUEUE_MGMT].limit = 3;
@@ -548,6 +573,7 @@ struct ieee80211_hw *p54_init_common(size_t priv_data_len)
548 mutex_init(&priv->conf_mutex); 573 mutex_init(&priv->conf_mutex);
549 mutex_init(&priv->eeprom_mutex); 574 mutex_init(&priv->eeprom_mutex);
550 init_completion(&priv->eeprom_comp); 575 init_completion(&priv->eeprom_comp);
576 init_completion(&priv->beacon_comp);
551 INIT_DELAYED_WORK(&priv->work, p54_work); 577 INIT_DELAYED_WORK(&priv->work, p54_work);
552 578
553 return dev; 579 return dev;
@@ -579,6 +605,10 @@ EXPORT_SYMBOL_GPL(p54_register_common);
579void p54_free_common(struct ieee80211_hw *dev) 605void p54_free_common(struct ieee80211_hw *dev)
580{ 606{
581 struct p54_common *priv = dev->priv; 607 struct p54_common *priv = dev->priv;
608 unsigned int i;
609
610 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
611 kfree(priv->band_table[i]);
582 612
583 kfree(priv->iq_autocal); 613 kfree(priv->iq_autocal);
584 kfree(priv->output_limit); 614 kfree(priv->output_limit);
diff --git a/drivers/net/wireless/p54/p54.h b/drivers/net/wireless/p54/p54.h
index 19d085c73d7d..1afc39410e85 100644
--- a/drivers/net/wireless/p54/p54.h
+++ b/drivers/net/wireless/p54/p54.h
@@ -198,6 +198,7 @@ struct p54_common {
198 struct p54_cal_database *curve_data; 198 struct p54_cal_database *curve_data;
199 struct p54_cal_database *output_limit; 199 struct p54_cal_database *output_limit;
200 struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS]; 200 struct p54_rssi_linear_approximation rssical_db[IEEE80211_NUM_BANDS];
201 struct ieee80211_supported_band *band_table[IEEE80211_NUM_BANDS];
201 202
202 /* BBP/MAC state */ 203 /* BBP/MAC state */
203 u8 mac_addr[ETH_ALEN]; 204 u8 mac_addr[ETH_ALEN];
@@ -208,7 +209,9 @@ struct p54_common {
208 u32 tsf_low32, tsf_high32; 209 u32 tsf_low32, tsf_high32;
209 u32 basic_rate_mask; 210 u32 basic_rate_mask;
210 u16 aid; 211 u16 aid;
212 bool powersave_override;
211 __le32 beacon_req_id; 213 __le32 beacon_req_id;
214 struct completion beacon_comp;
212 215
213 /* cryptographic engine information */ 216 /* cryptographic engine information */
214 u8 privacy_caps; 217 u8 privacy_caps;
diff --git a/drivers/net/wireless/p54/txrx.c b/drivers/net/wireless/p54/txrx.c
index 6426d2cae6de..0d589d68e547 100644
--- a/drivers/net/wireless/p54/txrx.c
+++ b/drivers/net/wireless/p54/txrx.c
@@ -87,9 +87,6 @@ static int p54_assign_address(struct p54_common *priv, struct sk_buff *skb)
87 u32 target_addr = priv->rx_start; 87 u32 target_addr = priv->rx_start;
88 u16 len = priv->headroom + skb->len + priv->tailroom + 3; 88 u16 len = priv->headroom + skb->len + priv->tailroom + 3;
89 89
90 if (unlikely(WARN_ON(!skb || !priv)))
91 return -EINVAL;
92
93 info = IEEE80211_SKB_CB(skb); 90 info = IEEE80211_SKB_CB(skb);
94 range = (void *) info->rate_driver_data; 91 range = (void *) info->rate_driver_data;
95 len = (range->extra_len + len) & ~0x3; 92 len = (range->extra_len + len) & ~0x3;
@@ -111,11 +108,6 @@ static int p54_assign_address(struct p54_common *priv, struct sk_buff *skb)
111 range = (void *) info->rate_driver_data; 108 range = (void *) info->rate_driver_data;
112 hole_size = range->start_addr - last_addr; 109 hole_size = range->start_addr - last_addr;
113 110
114 if (!entry->next) {
115 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
116 return -ENOSPC;
117 }
118
119 if (!target_skb && hole_size >= len) { 111 if (!target_skb && hole_size >= len) {
120 target_skb = entry->prev; 112 target_skb = entry->prev;
121 hole_size -= len; 113 hole_size -= len;
@@ -142,9 +134,13 @@ static int p54_assign_address(struct p54_common *priv, struct sk_buff *skb)
142 range = (void *) info->rate_driver_data; 134 range = (void *) info->rate_driver_data;
143 range->start_addr = target_addr; 135 range->start_addr = target_addr;
144 range->end_addr = target_addr + len; 136 range->end_addr = target_addr + len;
137 data->req_id = cpu_to_le32(target_addr + priv->headroom);
138 if (IS_DATA_FRAME(skb) &&
139 unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON))
140 priv->beacon_req_id = data->req_id;
141
145 __skb_queue_after(&priv->tx_queue, target_skb, skb); 142 __skb_queue_after(&priv->tx_queue, target_skb, skb);
146 spin_unlock_irqrestore(&priv->tx_queue.lock, flags); 143 spin_unlock_irqrestore(&priv->tx_queue.lock, flags);
147 data->req_id = cpu_to_le32(target_addr + priv->headroom);
148 return 0; 144 return 0;
149} 145}
150 146
@@ -153,9 +149,6 @@ static void p54_tx_pending(struct p54_common *priv)
153 struct sk_buff *skb; 149 struct sk_buff *skb;
154 int ret; 150 int ret;
155 151
156 if (unlikely(WARN_ON(!priv)))
157 return ;
158
159 skb = skb_dequeue(&priv->tx_pending); 152 skb = skb_dequeue(&priv->tx_pending);
160 if (unlikely(!skb)) 153 if (unlikely(!skb))
161 return ; 154 return ;
@@ -219,14 +212,20 @@ static int p54_tx_qos_accounting_alloc(struct p54_common *priv,
219static void p54_tx_qos_accounting_free(struct p54_common *priv, 212static void p54_tx_qos_accounting_free(struct p54_common *priv,
220 struct sk_buff *skb) 213 struct sk_buff *skb)
221{ 214{
222 if (skb && IS_DATA_FRAME(skb)) { 215 if (IS_DATA_FRAME(skb)) {
223 struct p54_hdr *hdr = (void *) skb->data;
224 struct p54_tx_data *data = (void *) hdr->data;
225 unsigned long flags; 216 unsigned long flags;
226 217
227 spin_lock_irqsave(&priv->tx_stats_lock, flags); 218 spin_lock_irqsave(&priv->tx_stats_lock, flags);
228 priv->tx_stats[data->hw_queue].len--; 219 priv->tx_stats[GET_HW_QUEUE(skb)].len--;
229 spin_unlock_irqrestore(&priv->tx_stats_lock, flags); 220 spin_unlock_irqrestore(&priv->tx_stats_lock, flags);
221
222 if (unlikely(GET_HW_QUEUE(skb) == P54_QUEUE_BEACON)) {
223 if (priv->beacon_req_id == GET_REQ_ID(skb)) {
224 /* this is the active beacon set anymore */
225 priv->beacon_req_id = 0;
226 }
227 complete(&priv->beacon_comp);
228 }
230 } 229 }
231 p54_wake_queues(priv); 230 p54_wake_queues(priv);
232} 231}
@@ -266,9 +265,6 @@ static struct sk_buff *p54_find_and_unlink_skb(struct p54_common *priv,
266 265
267void p54_tx(struct p54_common *priv, struct sk_buff *skb) 266void p54_tx(struct p54_common *priv, struct sk_buff *skb)
268{ 267{
269 if (unlikely(WARN_ON(!priv)))
270 return ;
271
272 skb_queue_tail(&priv->tx_pending, skb); 268 skb_queue_tail(&priv->tx_pending, skb);
273 p54_tx_pending(priv); 269 p54_tx_pending(priv);
274} 270}
@@ -288,6 +284,45 @@ static int p54_rssi_to_dbm(struct p54_common *priv, int rssi)
288 priv->rssical_db[band].add) / 4; 284 priv->rssical_db[band].add) / 4;
289} 285}
290 286
287/*
288 * Even if the firmware is capable of dealing with incoming traffic,
289 * while dozing, we have to prepared in case mac80211 uses PS-POLL
290 * to retrieve outstanding frames from our AP.
291 * (see comment in net/mac80211/mlme.c @ line 1993)
292 */
293static void p54_pspoll_workaround(struct p54_common *priv, struct sk_buff *skb)
294{
295 struct ieee80211_hdr *hdr = (void *) skb->data;
296 struct ieee80211_tim_ie *tim_ie;
297 u8 *tim;
298 u8 tim_len;
299 bool new_psm;
300
301 /* only beacons have a TIM IE */
302 if (!ieee80211_is_beacon(hdr->frame_control))
303 return;
304
305 if (!priv->aid)
306 return;
307
308 /* only consider beacons from the associated BSSID */
309 if (compare_ether_addr(hdr->addr3, priv->bssid))
310 return;
311
312 tim = p54_find_ie(skb, WLAN_EID_TIM);
313 if (!tim)
314 return;
315
316 tim_len = tim[1];
317 tim_ie = (struct ieee80211_tim_ie *) &tim[2];
318
319 new_psm = ieee80211_check_tim(tim_ie, tim_len, priv->aid);
320 if (new_psm != priv->powersave_override) {
321 priv->powersave_override = new_psm;
322 p54_set_ps(priv);
323 }
324}
325
291static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb) 326static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
292{ 327{
293 struct p54_rx_data *hdr = (struct p54_rx_data *) skb->data; 328 struct p54_rx_data *hdr = (struct p54_rx_data *) skb->data;
@@ -340,6 +375,9 @@ static int p54_rx_data(struct p54_common *priv, struct sk_buff *skb)
340 375
341 skb_pull(skb, header_len); 376 skb_pull(skb, header_len);
342 skb_trim(skb, le16_to_cpu(hdr->len)); 377 skb_trim(skb, le16_to_cpu(hdr->len));
378 if (unlikely(priv->hw->conf.flags & IEEE80211_CONF_PS))
379 p54_pspoll_workaround(priv, skb);
380
343 ieee80211_rx_irqsafe(priv->hw, skb); 381 ieee80211_rx_irqsafe(priv->hw, skb);
344 382
345 queue_delayed_work(priv->hw->workqueue, &priv->work, 383 queue_delayed_work(priv->hw->workqueue, &priv->work,
@@ -375,10 +413,6 @@ static void p54_rx_frame_sent(struct p54_common *priv, struct sk_buff *skb)
375 * and we don't want to confuse the mac80211 stack. 413 * and we don't want to confuse the mac80211 stack.
376 */ 414 */
377 if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) { 415 if (unlikely(entry_data->hw_queue < P54_QUEUE_FWSCAN)) {
378 if (entry_data->hw_queue == P54_QUEUE_BEACON &&
379 hdr->req_id == priv->beacon_req_id)
380 priv->beacon_req_id = cpu_to_le32(0);
381
382 dev_kfree_skb_any(entry); 416 dev_kfree_skb_any(entry);
383 return ; 417 return ;
384 } 418 }
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.c b/drivers/net/wireless/rt2x00/rt2400pci.c
index d8035e3575e8..30185ad28d93 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.c
+++ b/drivers/net/wireless/rt2x00/rt2400pci.c
@@ -1561,6 +1561,7 @@ static const struct ieee80211_ops rt2400pci_mac80211_ops = {
1561 .remove_interface = rt2x00mac_remove_interface, 1561 .remove_interface = rt2x00mac_remove_interface,
1562 .config = rt2x00mac_config, 1562 .config = rt2x00mac_config,
1563 .configure_filter = rt2x00mac_configure_filter, 1563 .configure_filter = rt2x00mac_configure_filter,
1564 .set_tim = rt2x00mac_set_tim,
1564 .get_stats = rt2x00mac_get_stats, 1565 .get_stats = rt2x00mac_get_stats,
1565 .bss_info_changed = rt2x00mac_bss_info_changed, 1566 .bss_info_changed = rt2x00mac_bss_info_changed,
1566 .conf_tx = rt2400pci_conf_tx, 1567 .conf_tx = rt2400pci_conf_tx,
diff --git a/drivers/net/wireless/rt2x00/rt2400pci.h b/drivers/net/wireless/rt2x00/rt2400pci.h
index ec3b004ddc3c..ccd644104ad1 100644
--- a/drivers/net/wireless/rt2x00/rt2400pci.h
+++ b/drivers/net/wireless/rt2x00/rt2400pci.h
@@ -928,7 +928,7 @@
928#define RXD_W7_RESERVED FIELD32(0xffffffff) 928#define RXD_W7_RESERVED FIELD32(0xffffffff)
929 929
930/* 930/*
931 * Macro's for converting txpower from EEPROM to mac80211 value 931 * Macros for converting txpower from EEPROM to mac80211 value
932 * and from mac80211 value to register value. 932 * and from mac80211 value to register value.
933 * NOTE: Logics in rt2400pci for txpower are reversed 933 * NOTE: Logics in rt2400pci for txpower are reversed
934 * compared to the other rt2x00 drivers. A higher txpower 934 * compared to the other rt2x00 drivers. A higher txpower
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.c b/drivers/net/wireless/rt2x00/rt2500pci.c
index c123e28396d0..3b3171578b14 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.c
+++ b/drivers/net/wireless/rt2x00/rt2500pci.c
@@ -1860,6 +1860,7 @@ static const struct ieee80211_ops rt2500pci_mac80211_ops = {
1860 .remove_interface = rt2x00mac_remove_interface, 1860 .remove_interface = rt2x00mac_remove_interface,
1861 .config = rt2x00mac_config, 1861 .config = rt2x00mac_config,
1862 .configure_filter = rt2x00mac_configure_filter, 1862 .configure_filter = rt2x00mac_configure_filter,
1863 .set_tim = rt2x00mac_set_tim,
1863 .get_stats = rt2x00mac_get_stats, 1864 .get_stats = rt2x00mac_get_stats,
1864 .bss_info_changed = rt2x00mac_bss_info_changed, 1865 .bss_info_changed = rt2x00mac_bss_info_changed,
1865 .conf_tx = rt2x00mac_conf_tx, 1866 .conf_tx = rt2x00mac_conf_tx,
diff --git a/drivers/net/wireless/rt2x00/rt2500pci.h b/drivers/net/wireless/rt2x00/rt2500pci.h
index ce2f065c7486..54d37957883c 100644
--- a/drivers/net/wireless/rt2x00/rt2500pci.h
+++ b/drivers/net/wireless/rt2x00/rt2500pci.h
@@ -1218,7 +1218,7 @@
1218#define RXD_W10_DROP FIELD32(0x00000001) 1218#define RXD_W10_DROP FIELD32(0x00000001)
1219 1219
1220/* 1220/*
1221 * Macro's for converting txpower from EEPROM to mac80211 value 1221 * Macros for converting txpower from EEPROM to mac80211 value
1222 * and from mac80211 value to register value. 1222 * and from mac80211 value to register value.
1223 */ 1223 */
1224#define MIN_TXPOWER 0 1224#define MIN_TXPOWER 0
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.c b/drivers/net/wireless/rt2x00/rt2500usb.c
index 00611b32d08b..de48c5c68eff 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.c
+++ b/drivers/net/wireless/rt2x00/rt2500usb.c
@@ -1896,6 +1896,7 @@ static const struct ieee80211_ops rt2500usb_mac80211_ops = {
1896 .remove_interface = rt2x00mac_remove_interface, 1896 .remove_interface = rt2x00mac_remove_interface,
1897 .config = rt2x00mac_config, 1897 .config = rt2x00mac_config,
1898 .configure_filter = rt2x00mac_configure_filter, 1898 .configure_filter = rt2x00mac_configure_filter,
1899 .set_tim = rt2x00mac_set_tim,
1899 .set_key = rt2x00mac_set_key, 1900 .set_key = rt2x00mac_set_key,
1900 .get_stats = rt2x00mac_get_stats, 1901 .get_stats = rt2x00mac_get_stats,
1901 .bss_info_changed = rt2x00mac_bss_info_changed, 1902 .bss_info_changed = rt2x00mac_bss_info_changed,
diff --git a/drivers/net/wireless/rt2x00/rt2500usb.h b/drivers/net/wireless/rt2x00/rt2500usb.h
index 5bc46fe72179..b01edca42583 100644
--- a/drivers/net/wireless/rt2x00/rt2500usb.h
+++ b/drivers/net/wireless/rt2x00/rt2500usb.h
@@ -831,7 +831,7 @@
831#define RXD_W3_EIV FIELD32(0xffffffff) 831#define RXD_W3_EIV FIELD32(0xffffffff)
832 832
833/* 833/*
834 * Macro's for converting txpower from EEPROM to mac80211 value 834 * Macros for converting txpower from EEPROM to mac80211 value
835 * and from mac80211 value to register value. 835 * and from mac80211 value to register value.
836 */ 836 */
837#define MIN_TXPOWER 0 837#define MIN_TXPOWER 0
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index a204e66753c2..9efb41710508 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -1910,7 +1910,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
1910 /* 1910 /*
1911 * Before the radio can be enabled, the device first has 1911 * Before the radio can be enabled, the device first has
1912 * to be woken up. After that it needs a bit of time 1912 * to be woken up. After that it needs a bit of time
1913 * to be fully awake and the radio can be enabled. 1913 * to be fully awake and then the radio can be enabled.
1914 */ 1914 */
1915 rt2800usb_set_state(rt2x00dev, STATE_AWAKE); 1915 rt2800usb_set_state(rt2x00dev, STATE_AWAKE);
1916 msleep(1); 1916 msleep(1);
@@ -1918,7 +1918,7 @@ static int rt2800usb_set_device_state(struct rt2x00_dev *rt2x00dev,
1918 break; 1918 break;
1919 case STATE_RADIO_OFF: 1919 case STATE_RADIO_OFF:
1920 /* 1920 /*
1921 * After the radio has been disablee, the device should 1921 * After the radio has been disabled, the device should
1922 * be put to sleep for powersaving. 1922 * be put to sleep for powersaving.
1923 */ 1923 */
1924 rt2800usb_disable_radio(rt2x00dev); 1924 rt2800usb_disable_radio(rt2x00dev);
@@ -2220,10 +2220,8 @@ static int rt2800usb_validate_eeprom(struct rt2x00_dev *rt2x00dev)
2220 */ 2220 */
2221 mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0); 2221 mac = rt2x00_eeprom_addr(rt2x00dev, EEPROM_MAC_ADDR_0);
2222 if (!is_valid_ether_addr(mac)) { 2222 if (!is_valid_ether_addr(mac)) {
2223 DECLARE_MAC_BUF(macbuf);
2224
2225 random_ether_addr(mac); 2223 random_ether_addr(mac);
2226 EEPROM(rt2x00dev, "MAC: %s\n", print_mac(macbuf, mac)); 2224 EEPROM(rt2x00dev, "MAC: %pM\n", mac);
2227 } 2225 }
2228 2226
2229 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word); 2227 rt2x00_eeprom_read(rt2x00dev, EEPROM_ANTENNA, &word);
@@ -2786,6 +2784,7 @@ static const struct ieee80211_ops rt2800usb_mac80211_ops = {
2786 .remove_interface = rt2x00mac_remove_interface, 2784 .remove_interface = rt2x00mac_remove_interface,
2787 .config = rt2x00mac_config, 2785 .config = rt2x00mac_config,
2788 .configure_filter = rt2x00mac_configure_filter, 2786 .configure_filter = rt2x00mac_configure_filter,
2787 .set_tim = rt2x00mac_set_tim,
2789 .set_key = rt2x00mac_set_key, 2788 .set_key = rt2x00mac_set_key,
2790 .get_stats = rt2x00mac_get_stats, 2789 .get_stats = rt2x00mac_get_stats,
2791 .get_tkip_seq = rt2800usb_get_tkip_seq, 2790 .get_tkip_seq = rt2800usb_get_tkip_seq,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.h b/drivers/net/wireless/rt2x00/rt2800usb.h
index 61a8be61d3f5..2d9dc3783361 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.h
+++ b/drivers/net/wireless/rt2x00/rt2800usb.h
@@ -1921,7 +1921,7 @@ struct mac_iveiv_entry {
1921#define RXWI_W3_SNR1 FIELD32(0x0000ff00) 1921#define RXWI_W3_SNR1 FIELD32(0x0000ff00)
1922 1922
1923/* 1923/*
1924 * Macro's for converting txpower from EEPROM to mac80211 value 1924 * Macros for converting txpower from EEPROM to mac80211 value
1925 * and from mac80211 value to register value. 1925 * and from mac80211 value to register value.
1926 */ 1926 */
1927#define MIN_G_TXPOWER 0 1927#define MIN_G_TXPOWER 0
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index 71f37cb476b0..cbec91ef6f76 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -245,7 +245,7 @@ struct link_ant {
245 struct antenna_setup active; 245 struct antenna_setup active;
246 246
247 /* 247 /*
248 * RSSI information for the different antenna's. 248 * RSSI information for the different antennas.
249 * These statistics are used to determine when 249 * These statistics are used to determine when
250 * to switch antenna when using software diversity. 250 * to switch antenna when using software diversity.
251 * 251 *
@@ -594,7 +594,6 @@ enum rt2x00_flags {
594 DEVICE_STATE_INITIALIZED, 594 DEVICE_STATE_INITIALIZED,
595 DEVICE_STATE_STARTED, 595 DEVICE_STATE_STARTED,
596 DEVICE_STATE_ENABLED_RADIO, 596 DEVICE_STATE_ENABLED_RADIO,
597 DEVICE_STATE_DISABLED_RADIO_HW,
598 597
599 /* 598 /*
600 * Driver requirements 599 * Driver requirements
@@ -634,7 +633,7 @@ struct rt2x00_dev {
634 * The structure stored in here depends on the 633 * The structure stored in here depends on the
635 * system bus (PCI or USB). 634 * system bus (PCI or USB).
636 * When accessing this variable, the rt2x00dev_{pci,usb} 635 * When accessing this variable, the rt2x00dev_{pci,usb}
637 * macro's should be used for correct typecasting. 636 * macros should be used for correct typecasting.
638 */ 637 */
639 struct device *dev; 638 struct device *dev;
640 639
@@ -963,6 +962,8 @@ void rt2x00mac_configure_filter(struct ieee80211_hw *hw,
963 unsigned int changed_flags, 962 unsigned int changed_flags,
964 unsigned int *total_flags, 963 unsigned int *total_flags,
965 int mc_count, struct dev_addr_list *mc_list); 964 int mc_count, struct dev_addr_list *mc_list);
965int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
966 bool set);
966#ifdef CONFIG_RT2X00_LIB_CRYPTO 967#ifdef CONFIG_RT2X00_LIB_CRYPTO
967int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 968int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
968 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 969 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
diff --git a/drivers/net/wireless/rt2x00/rt2x00config.c b/drivers/net/wireless/rt2x00/rt2x00config.c
index 3e019a12df2e..c6e0bcf78e9e 100644
--- a/drivers/net/wireless/rt2x00/rt2x00config.c
+++ b/drivers/net/wireless/rt2x00/rt2x00config.c
@@ -132,7 +132,7 @@ void rt2x00lib_config_antenna(struct rt2x00_dev *rt2x00dev,
132 /* 132 /*
133 * Failsafe: Make sure we are not sending the 133 * Failsafe: Make sure we are not sending the
134 * ANTENNA_SW_DIVERSITY state to the driver. 134 * ANTENNA_SW_DIVERSITY state to the driver.
135 * If that happes fallback to hardware default, 135 * If that happens, fallback to hardware defaults,
136 * or our own default. 136 * or our own default.
137 * The calls to rt2x00lib_config_antenna_check() 137 * The calls to rt2x00lib_config_antenna_check()
138 * might have caused that we restore back to the already 138 * might have caused that we restore back to the already
diff --git a/drivers/net/wireless/rt2x00/rt2x00crypto.c b/drivers/net/wireless/rt2x00/rt2x00crypto.c
index c54eda3c2db0..30fbd3bbe08b 100644
--- a/drivers/net/wireless/rt2x00/rt2x00crypto.c
+++ b/drivers/net/wireless/rt2x00/rt2x00crypto.c
@@ -129,7 +129,7 @@ void rt2x00crypto_tx_remove_iv(struct sk_buff *skb, struct txentry_desc *txdesc)
129 /* Pull buffer to correct size */ 129 /* Pull buffer to correct size */
130 skb_pull(skb, txdesc->iv_len); 130 skb_pull(skb, txdesc->iv_len);
131 131
132 /* IV/EIV data has officially be stripped */ 132 /* IV/EIV data has officially been stripped */
133 skbdesc->flags |= SKBDESC_IV_STRIPPED; 133 skbdesc->flags |= SKBDESC_IV_STRIPPED;
134} 134}
135 135
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index 4fff3a83f7df..658a63bfb761 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -40,8 +40,7 @@ int rt2x00lib_enable_radio(struct rt2x00_dev *rt2x00dev)
40 * Don't enable the radio twice. 40 * Don't enable the radio twice.
41 * And check if the hardware button has been disabled. 41 * And check if the hardware button has been disabled.
42 */ 42 */
43 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags) || 43 if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags))
44 test_bit(DEVICE_STATE_DISABLED_RADIO_HW, &rt2x00dev->flags))
45 return 0; 44 return 0;
46 45
47 /* 46 /*
diff --git a/drivers/net/wireless/rt2x00/rt2x00link.c b/drivers/net/wireless/rt2x00/rt2x00link.c
index eb9b981b9139..32570758e67c 100644
--- a/drivers/net/wireless/rt2x00/rt2x00link.c
+++ b/drivers/net/wireless/rt2x00/rt2x00link.c
@@ -158,7 +158,7 @@ static void rt2x00lib_antenna_diversity_sample(struct rt2x00_dev *rt2x00dev)
158 158
159 /* 159 /*
160 * During the last period we have sampled the RSSI 160 * During the last period we have sampled the RSSI
161 * from both antenna's. It now is time to determine 161 * from both antennas. It now is time to determine
162 * which antenna demonstrated the best performance. 162 * which antenna demonstrated the best performance.
163 * When we are already on the antenna with the best 163 * When we are already on the antenna with the best
164 * performance, then there really is nothing for us 164 * performance, then there really is nothing for us
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index b7e0ddda38f5..9d31c23b92fa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -341,7 +341,7 @@ int rt2x00mac_config(struct ieee80211_hw *hw, u32 changed)
341 int status; 341 int status;
342 342
343 /* 343 /*
344 * Mac80211 might be calling this function while we are trying 344 * mac80211 might be calling this function while we are trying
345 * to remove the device or perhaps suspending it. 345 * to remove the device or perhaps suspending it.
346 */ 346 */
347 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) 347 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
@@ -454,6 +454,16 @@ static void memcpy_tkip(struct rt2x00lib_crypto *crypto, u8 *key, u8 key_len)
454 sizeof(crypto->rx_mic)); 454 sizeof(crypto->rx_mic));
455} 455}
456 456
457int rt2x00mac_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta,
458 bool set)
459{
460 struct rt2x00_dev *rt2x00dev = hw->priv;
461
462 rt2x00lib_beacondone(rt2x00dev);
463 return 0;
464}
465EXPORT_SYMBOL_GPL(rt2x00mac_set_tim);
466
457int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, 467int rt2x00mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
458 struct ieee80211_vif *vif, struct ieee80211_sta *sta, 468 struct ieee80211_vif *vif, struct ieee80211_sta *sta,
459 struct ieee80211_key_conf *key) 469 struct ieee80211_key_conf *key)
@@ -577,7 +587,7 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
577 int update_bssid = 0; 587 int update_bssid = 0;
578 588
579 /* 589 /*
580 * Mac80211 might be calling this function while we are trying 590 * mac80211 might be calling this function while we are trying
581 * to remove the device or perhaps suspending it. 591 * to remove the device or perhaps suspending it.
582 */ 592 */
583 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) 593 if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags))
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.h b/drivers/net/wireless/rt2x00/rt2x00queue.h
index b5e06347c8a7..47d175a13790 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.h
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.h
@@ -29,7 +29,7 @@
29#include <linux/prefetch.h> 29#include <linux/prefetch.h>
30 30
31/** 31/**
32 * DOC: Entrie frame size 32 * DOC: Entry frame size
33 * 33 *
34 * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes, 34 * Ralink PCI devices demand the Frame size to be a multiple of 128 bytes,
35 * for USB devices this restriction does not apply, but the value of 35 * for USB devices this restriction does not apply, but the value of
@@ -45,13 +45,13 @@
45/** 45/**
46 * DOC: Number of entries per queue 46 * DOC: Number of entries per queue
47 * 47 *
48 * Under normal load without fragmentation 12 entries are sufficient 48 * Under normal load without fragmentation, 12 entries are sufficient
49 * without the queue being filled up to the maximum. When using fragmentation 49 * without the queue being filled up to the maximum. When using fragmentation
50 * and the queue threshold code we need to add some additional margins to 50 * and the queue threshold code, we need to add some additional margins to
51 * make sure the queue will never (or only under extreme load) fill up 51 * make sure the queue will never (or only under extreme load) fill up
52 * completely. 52 * completely.
53 * Since we don't use preallocated DMA having a large number of queue entries 53 * Since we don't use preallocated DMA, having a large number of queue entries
54 * will have only minimal impact on the memory requirements for the queue. 54 * will have minimal impact on the memory requirements for the queue.
55 */ 55 */
56#define RX_ENTRIES 24 56#define RX_ENTRIES 24
57#define TX_ENTRIES 24 57#define TX_ENTRIES 24
diff --git a/drivers/net/wireless/rt2x00/rt2x00reg.h b/drivers/net/wireless/rt2x00/rt2x00reg.h
index 861322d97fce..983e52e127a7 100644
--- a/drivers/net/wireless/rt2x00/rt2x00reg.h
+++ b/drivers/net/wireless/rt2x00/rt2x00reg.h
@@ -176,8 +176,8 @@ struct rt2x00_field32 {
176#define is_valid_mask(x) is_power_of_two(1LU + (x) + low_bit_mask(x)) 176#define is_valid_mask(x) is_power_of_two(1LU + (x) + low_bit_mask(x))
177 177
178/* 178/*
179 * Macro's to find first set bit in a variable. 179 * Macros to find first set bit in a variable.
180 * These macro's behaves the same as the __ffs() function with 180 * These macros behave the same as the __ffs() functions but
181 * the most important difference that this is done during 181 * the most important difference that this is done during
182 * compile-time rather then run-time. 182 * compile-time rather then run-time.
183 */ 183 */
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 8a49d99df682..fb95b8cc4fe9 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2312,7 +2312,7 @@ static int rt61pci_init_eeprom(struct rt2x00_dev *rt2x00dev)
2312 } 2312 }
2313 2313
2314 /* 2314 /*
2315 * Determine number of antenna's. 2315 * Determine number of antennas.
2316 */ 2316 */
2317 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2) 2317 if (rt2x00_get_field16(eeprom, EEPROM_ANTENNA_NUM) == 2)
2318 __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags); 2318 __set_bit(CONFIG_DOUBLE_ANTENNA, &rt2x00dev->flags);
@@ -2716,6 +2716,7 @@ static const struct ieee80211_ops rt61pci_mac80211_ops = {
2716 .remove_interface = rt2x00mac_remove_interface, 2716 .remove_interface = rt2x00mac_remove_interface,
2717 .config = rt2x00mac_config, 2717 .config = rt2x00mac_config,
2718 .configure_filter = rt2x00mac_configure_filter, 2718 .configure_filter = rt2x00mac_configure_filter,
2719 .set_tim = rt2x00mac_set_tim,
2719 .set_key = rt2x00mac_set_key, 2720 .set_key = rt2x00mac_set_key,
2720 .get_stats = rt2x00mac_get_stats, 2721 .get_stats = rt2x00mac_get_stats,
2721 .bss_info_changed = rt2x00mac_bss_info_changed, 2722 .bss_info_changed = rt2x00mac_bss_info_changed,
diff --git a/drivers/net/wireless/rt2x00/rt61pci.h b/drivers/net/wireless/rt2x00/rt61pci.h
index 6c71f77c8165..93eb699165cc 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.h
+++ b/drivers/net/wireless/rt2x00/rt61pci.h
@@ -1476,7 +1476,7 @@ struct hw_pairwise_ta_entry {
1476#define RXD_W15_RESERVED FIELD32(0xffffffff) 1476#define RXD_W15_RESERVED FIELD32(0xffffffff)
1477 1477
1478/* 1478/*
1479 * Macro's for converting txpower from EEPROM to mac80211 value 1479 * Macros for converting txpower from EEPROM to mac80211 value
1480 * and from mac80211 value to register value. 1480 * and from mac80211 value to register value.
1481 */ 1481 */
1482#define MIN_TXPOWER 0 1482#define MIN_TXPOWER 0
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index ad2898ca8677..4f9b1772e1a1 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2241,6 +2241,7 @@ static const struct ieee80211_ops rt73usb_mac80211_ops = {
2241 .remove_interface = rt2x00mac_remove_interface, 2241 .remove_interface = rt2x00mac_remove_interface,
2242 .config = rt2x00mac_config, 2242 .config = rt2x00mac_config,
2243 .configure_filter = rt2x00mac_configure_filter, 2243 .configure_filter = rt2x00mac_configure_filter,
2244 .set_tim = rt2x00mac_set_tim,
2244 .set_key = rt2x00mac_set_key, 2245 .set_key = rt2x00mac_set_key,
2245 .get_stats = rt2x00mac_get_stats, 2246 .get_stats = rt2x00mac_get_stats,
2246 .bss_info_changed = rt2x00mac_bss_info_changed, 2247 .bss_info_changed = rt2x00mac_bss_info_changed,
diff --git a/drivers/net/wireless/rt2x00/rt73usb.h b/drivers/net/wireless/rt2x00/rt73usb.h
index c8016f65b4bd..81fe0be51c42 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.h
+++ b/drivers/net/wireless/rt2x00/rt73usb.h
@@ -809,7 +809,7 @@ struct hw_pairwise_ta_entry {
809 809
810/* 810/*
811 * EEPROM antenna. 811 * EEPROM antenna.
812 * ANTENNA_NUM: Number of antenna's. 812 * ANTENNA_NUM: Number of antennas.
813 * TX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. 813 * TX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B.
814 * RX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B. 814 * RX_DEFAULT: Default antenna 0: diversity, 1: A, 2: B.
815 * FRAME_TYPE: 0: DPDT , 1: SPDT , noted this bit is valid for g only. 815 * FRAME_TYPE: 0: DPDT , 1: SPDT , noted this bit is valid for g only.
@@ -1058,7 +1058,7 @@ struct hw_pairwise_ta_entry {
1058#define RXD_W5_RESERVED FIELD32(0xffffffff) 1058#define RXD_W5_RESERVED FIELD32(0xffffffff)
1059 1059
1060/* 1060/*
1061 * Macro's for converting txpower from EEPROM to mac80211 value 1061 * Macros for converting txpower from EEPROM to mac80211 value
1062 * and from mac80211 value to register value. 1062 * and from mac80211 value to register value.
1063 */ 1063 */
1064#define MIN_TXPOWER 0 1064#define MIN_TXPOWER 0
diff --git a/drivers/net/wireless/wl12xx/wl1251_acx.c b/drivers/net/wireless/wl12xx/wl1251_acx.c
index 5a8d21c3192d..a46c92a29526 100644
--- a/drivers/net/wireless/wl12xx/wl1251_acx.c
+++ b/drivers/net/wireless/wl12xx/wl1251_acx.c
@@ -84,7 +84,7 @@ int wl1251_acx_default_key(struct wl1251 *wl, u8 key_id)
84 ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY, 84 ret = wl1251_cmd_configure(wl, DOT11_DEFAULT_KEY,
85 default_key, sizeof(*default_key)); 85 default_key, sizeof(*default_key));
86 if (ret < 0) { 86 if (ret < 0) {
87 wl1251_error("Couldnt set default key"); 87 wl1251_error("Couldn't set default key");
88 goto out; 88 goto out;
89 } 89 }
90 90
@@ -231,7 +231,7 @@ int wl1251_acx_feature_cfg(struct wl1251 *wl)
231 ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG, 231 ret = wl1251_cmd_configure(wl, ACX_FEATURE_CFG,
232 feature, sizeof(*feature)); 232 feature, sizeof(*feature));
233 if (ret < 0) { 233 if (ret < 0) {
234 wl1251_error("Couldnt set HW encryption"); 234 wl1251_error("Couldn't set HW encryption");
235 goto out; 235 goto out;
236 } 236 }
237 237
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index cf5e0549fa14..da4c688c46af 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -246,60 +246,6 @@ out:
246 mutex_unlock(&wl->mutex); 246 mutex_unlock(&wl->mutex);
247} 247}
248 248
249int wl1251_plt_start(struct wl1251 *wl)
250{
251 int ret;
252
253 mutex_lock(&wl->mutex);
254
255 wl1251_notice("power up");
256
257 if (wl->state != WL1251_STATE_OFF) {
258 wl1251_error("cannot go into PLT state because not "
259 "in off state: %d", wl->state);
260 return -EBUSY;
261 }
262
263 wl->state = WL1251_STATE_PLT;
264
265 ret = wl1251_chip_wakeup(wl);
266 if (ret < 0)
267 return ret;
268
269 ret = wl->chip.op_boot(wl);
270 if (ret < 0)
271 return ret;
272
273 wl1251_notice("firmware booted in PLT mode (%s)", wl->chip.fw_ver);
274
275 ret = wl->chip.op_plt_init(wl);
276 if (ret < 0)
277 return ret;
278
279 return 0;
280}
281
282int wl1251_plt_stop(struct wl1251 *wl)
283{
284 mutex_lock(&wl->mutex);
285
286 wl1251_notice("power down");
287
288 if (wl->state != WL1251_STATE_PLT) {
289 wl1251_error("cannot power down because not in PLT "
290 "state: %d", wl->state);
291 return -EBUSY;
292 }
293
294 wl1251_disable_interrupts(wl);
295 wl1251_power_off(wl);
296
297 wl->state = WL1251_STATE_OFF;
298
299 return 0;
300}
301
302
303static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb) 249static int wl1251_op_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
304{ 250{
305 struct wl1251 *wl = hw->priv; 251 struct wl1251 *wl = hw->priv;
@@ -349,7 +295,7 @@ static int wl1251_op_start(struct ieee80211_hw *hw)
349 295
350 ret = wl1251_chip_wakeup(wl); 296 ret = wl1251_chip_wakeup(wl);
351 if (ret < 0) 297 if (ret < 0)
352 return ret; 298 goto out;
353 299
354 ret = wl->chip.op_boot(wl); 300 ret = wl->chip.op_boot(wl);
355 if (ret < 0) 301 if (ret < 0)
@@ -435,11 +381,10 @@ static int wl1251_op_add_interface(struct ieee80211_hw *hw,
435 struct ieee80211_if_init_conf *conf) 381 struct ieee80211_if_init_conf *conf)
436{ 382{
437 struct wl1251 *wl = hw->priv; 383 struct wl1251 *wl = hw->priv;
438 DECLARE_MAC_BUF(mac);
439 int ret = 0; 384 int ret = 0;
440 385
441 wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %s", 386 wl1251_debug(DEBUG_MAC80211, "mac80211 add interface type %d mac %pM",
442 conf->type, print_mac(mac, conf->mac_addr)); 387 conf->type, conf->mac_addr);
443 388
444 mutex_lock(&wl->mutex); 389 mutex_lock(&wl->mutex);
445 390
diff --git a/drivers/net/wireless/wl12xx/wl1251_netlink.c b/drivers/net/wireless/wl12xx/wl1251_netlink.c
deleted file mode 100644
index 67d3d5a3b519..000000000000
--- a/drivers/net/wireless/wl12xx/wl1251_netlink.c
+++ /dev/null
@@ -1,679 +0,0 @@
1/*
2 * This file is part of wl1251
3 *
4 * Copyright (C) 2008 Nokia Corporation
5 *
6 * Contact: Kalle Valo <kalle.valo@nokia.com>
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA
21 *
22 */
23#include "wl1251_netlink.h"
24
25#include <linux/mutex.h>
26#include <linux/socket.h>
27#include <net/net_namespace.h>
28#include <net/sock.h>
29#include <net/genetlink.h>
30#include <net/wireless.h>
31#include <net/mac80211.h>
32
33#include "wl1251.h"
34#include "wl1251_spi.h"
35#include "wl1251_acx.h"
36
37/* FIXME: this should be changed as soon as user space catches up */
38#define WL1251_NL_NAME "wl1251"
39#define WL1251_NL_VERSION 1
40
41#define WL1251_MAX_TEST_LENGTH 1024
42#define WL1251_MAX_NVS_LENGTH 1024
43
44enum wl1251_nl_commands {
45 WL1251_NL_CMD_UNSPEC,
46 WL1251_NL_CMD_TEST,
47 WL1251_NL_CMD_INTERROGATE,
48 WL1251_NL_CMD_CONFIGURE,
49 WL1251_NL_CMD_PHY_REG_READ,
50 WL1251_NL_CMD_NVS_PUSH,
51 WL1251_NL_CMD_REG_WRITE,
52 WL1251_NL_CMD_REG_READ,
53 WL1251_NL_CMD_SET_PLT_MODE,
54
55 __WL1251_NL_CMD_AFTER_LAST
56};
57#define WL1251_NL_CMD_MAX (__WL1251_NL_CMD_AFTER_LAST - 1)
58
59enum wl1251_nl_attrs {
60 WL1251_NL_ATTR_UNSPEC,
61 WL1251_NL_ATTR_IFNAME,
62 WL1251_NL_ATTR_CMD_TEST_PARAM,
63 WL1251_NL_ATTR_CMD_TEST_ANSWER,
64 WL1251_NL_ATTR_CMD_IE,
65 WL1251_NL_ATTR_CMD_IE_LEN,
66 WL1251_NL_ATTR_CMD_IE_BUFFER,
67 WL1251_NL_ATTR_CMD_IE_ANSWER,
68 WL1251_NL_ATTR_REG_ADDR,
69 WL1251_NL_ATTR_REG_VAL,
70 WL1251_NL_ATTR_NVS_BUFFER,
71 WL1251_NL_ATTR_NVS_LEN,
72 WL1251_NL_ATTR_PLT_MODE,
73
74 __WL1251_NL_ATTR_AFTER_LAST
75};
76#define WL1251_NL_ATTR_MAX (__WL1251_NL_ATTR_AFTER_LAST - 1)
77
78static struct genl_family wl1251_nl_family = {
79 .id = GENL_ID_GENERATE,
80 .name = WL1251_NL_NAME,
81 .hdrsize = 0,
82 .version = WL1251_NL_VERSION,
83 .maxattr = WL1251_NL_ATTR_MAX,
84};
85
86static struct net_device *ifname_to_netdev(struct net *net,
87 struct genl_info *info)
88{
89 char *ifname;
90
91 if (!info->attrs[WL1251_NL_ATTR_IFNAME])
92 return NULL;
93
94 ifname = nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]);
95
96 wl1251_debug(DEBUG_NETLINK, "Looking for %s", ifname);
97
98 return dev_get_by_name(net, ifname);
99}
100
101static struct wl1251 *ifname_to_wl1251(struct net *net, struct genl_info *info)
102{
103 struct net_device *netdev;
104 struct wireless_dev *wdev;
105 struct wiphy *wiphy;
106 struct ieee80211_hw *hw;
107
108 netdev = ifname_to_netdev(net, info);
109 if (netdev == NULL) {
110 wl1251_error("Wrong interface");
111 return NULL;
112 }
113
114 wdev = netdev->ieee80211_ptr;
115 if (wdev == NULL) {
116 wl1251_error("ieee80211_ptr is NULL");
117 return NULL;
118 }
119
120 wiphy = wdev->wiphy;
121 if (wiphy == NULL) {
122 wl1251_error("wiphy is NULL");
123 return NULL;
124 }
125
126 hw = wiphy_priv(wiphy);
127 if (hw == NULL) {
128 wl1251_error("hw is NULL");
129 return NULL;
130 }
131
132 dev_put(netdev);
133
134 return hw->priv;
135}
136
137static int wl1251_nl_test_cmd(struct sk_buff *skb, struct genl_info *info)
138{
139 struct wl1251 *wl;
140 struct wl1251_command *cmd;
141 char *buf;
142 int buf_len, ret, cmd_len;
143 u8 answer;
144
145 if (!info->attrs[WL1251_NL_ATTR_CMD_TEST_PARAM])
146 return -EINVAL;
147
148 wl = ifname_to_wl1251(&init_net, info);
149 if (wl == NULL) {
150 wl1251_error("wl1251 not found");
151 return -EINVAL;
152 }
153
154 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
155 if (!cmd)
156 return -ENOMEM;
157
158 buf = nla_data(info->attrs[WL1251_NL_ATTR_CMD_TEST_PARAM]);
159 buf_len = nla_len(info->attrs[WL1251_NL_ATTR_CMD_TEST_PARAM]);
160 answer = nla_get_u8(info->attrs[WL1251_NL_ATTR_CMD_TEST_ANSWER]);
161
162 cmd->header.id = CMD_TEST;
163 memcpy(cmd->parameters, buf, buf_len);
164 cmd_len = sizeof(struct wl1251_cmd_header) + buf_len;
165
166 mutex_lock(&wl->mutex);
167 ret = wl1251_cmd_test(wl, cmd, cmd_len, answer);
168 mutex_unlock(&wl->mutex);
169
170 if (ret < 0) {
171 wl1251_error("%s() failed", __func__);
172 goto out;
173 }
174
175 if (answer) {
176 struct sk_buff *msg;
177 void *hdr;
178
179 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
180 if (!msg) {
181 ret = -ENOMEM;
182 goto out;
183 }
184
185 hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
186 &wl1251_nl_family, 0, WL1251_NL_CMD_TEST);
187 if (IS_ERR(hdr)) {
188 ret = PTR_ERR(hdr);
189 goto nla_put_failure;
190 }
191
192 NLA_PUT_STRING(msg, WL1251_NL_ATTR_IFNAME,
193 nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]));
194 NLA_PUT(msg, WL1251_NL_ATTR_CMD_TEST_ANSWER,
195 sizeof(*cmd), cmd);
196
197 ret = genlmsg_end(msg, hdr);
198 if (ret < 0) {
199 wl1251_error("%s() failed", __func__);
200 goto nla_put_failure;
201 }
202
203 wl1251_debug(DEBUG_NETLINK, "TEST cmd sent, answer");
204 ret = genlmsg_reply(msg, info);
205 goto out;
206
207 nla_put_failure:
208 nlmsg_free(msg);
209 } else
210 wl1251_debug(DEBUG_NETLINK, "TEST cmd sent");
211
212out:
213 kfree(cmd);
214 return ret;
215}
216
217static int wl1251_nl_interrogate(struct sk_buff *skb, struct genl_info *info)
218{
219 struct wl1251 *wl;
220 struct sk_buff *msg;
221 int ret = -ENOBUFS, cmd_ie, cmd_ie_len;
222 struct wl1251_command *cmd;
223 void *hdr;
224
225 if (!info->attrs[WL1251_NL_ATTR_CMD_IE])
226 return -EINVAL;
227
228 if (!info->attrs[WL1251_NL_ATTR_CMD_IE_LEN])
229 return -EINVAL;
230
231 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
232 if (!cmd)
233 return -ENOMEM;
234
235 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
236 if (!msg)
237 return -ENOMEM;
238
239 wl = ifname_to_wl1251(&init_net, info);
240 if (wl == NULL) {
241 wl1251_error("wl1251 not found");
242 ret = -EINVAL;
243 goto nla_put_failure;
244 }
245
246 /* acx id */
247 cmd_ie = nla_get_u32(info->attrs[WL1251_NL_ATTR_CMD_IE]);
248
249 /* maximum length of acx, including all headers */
250 cmd_ie_len = nla_get_u32(info->attrs[WL1251_NL_ATTR_CMD_IE_LEN]);
251
252 wl1251_debug(DEBUG_NETLINK, "Getting IE 0x%x (len %d)",
253 cmd_ie, cmd_ie_len);
254
255 mutex_lock(&wl->mutex);
256 ret = wl1251_cmd_interrogate(wl, cmd_ie, cmd, cmd_ie_len);
257 mutex_unlock(&wl->mutex);
258
259 if (ret < 0) {
260 wl1251_error("%s() failed", __func__);
261 goto nla_put_failure;
262 }
263
264 hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
265 &wl1251_nl_family, 0, WL1251_NL_CMD_INTERROGATE);
266 if (IS_ERR(hdr)) {
267 ret = PTR_ERR(hdr);
268 goto nla_put_failure;
269 }
270
271 NLA_PUT_STRING(msg, WL1251_NL_ATTR_IFNAME,
272 nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]));
273 NLA_PUT(msg, WL1251_NL_ATTR_CMD_IE_ANSWER, cmd_ie_len, cmd);
274
275 ret = genlmsg_end(msg, hdr);
276 if (ret < 0) {
277 wl1251_error("%s() failed", __func__);
278 goto nla_put_failure;
279 }
280
281 kfree(cmd);
282 return genlmsg_reply(msg, info);
283
284 nla_put_failure:
285 kfree(cmd);
286 nlmsg_free(msg);
287
288 return ret;
289}
290
291static int wl1251_nl_configure(struct sk_buff *skb, struct genl_info *info)
292{
293 int ret = 0, cmd_ie_len, acx_len;
294 struct acx_header *acx = NULL;
295 struct sk_buff *msg;
296 struct wl1251 *wl;
297 void *cmd_ie;
298 u16 *id;
299
300 if (!info->attrs[WL1251_NL_ATTR_CMD_IE_BUFFER])
301 return -EINVAL;
302
303 if (!info->attrs[WL1251_NL_ATTR_CMD_IE_LEN])
304 return -EINVAL;
305
306 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
307 if (!msg)
308 return -ENOMEM;
309
310 wl = ifname_to_wl1251(&init_net, info);
311 if (wl == NULL) {
312 wl1251_error("wl1251 not found");
313 ret = -EINVAL;
314 goto nla_put_failure;
315 }
316
317 /* contains the acx header but not the cmd header */
318 cmd_ie = nla_data(info->attrs[WL1251_NL_ATTR_CMD_IE_BUFFER]);
319
320 cmd_ie_len = nla_get_u32(info->attrs[WL1251_NL_ATTR_CMD_IE_LEN]);
321
322 /* acx id is in the first two bytes */
323 id = cmd_ie;
324
325 /* need to add acx_header before cmd_ie, so create a new command */
326 acx_len = sizeof(struct acx_header) + cmd_ie_len;
327 acx = kzalloc(acx_len, GFP_KERNEL);
328 if (!acx) {
329 ret = -ENOMEM;
330 goto nla_put_failure;
331 }
332
333 /* copy the acx header and the payload */
334 memcpy(&acx->id, cmd_ie, cmd_ie_len);
335
336 mutex_lock(&wl->mutex);
337 ret = wl1251_cmd_configure(wl, *id, acx, acx_len);
338 mutex_unlock(&wl->mutex);
339
340 if (ret < 0) {
341 wl1251_error("%s() failed", __func__);
342 goto nla_put_failure;
343 }
344
345 wl1251_debug(DEBUG_NETLINK, "CONFIGURE cmd sent");
346
347 nla_put_failure:
348 kfree(acx);
349 nlmsg_free(msg);
350
351 return ret;
352}
353
354static int wl1251_nl_phy_reg_read(struct sk_buff *skb, struct genl_info *info)
355{
356 struct wl1251 *wl;
357 struct sk_buff *msg;
358 u32 reg_addr, *reg_value = NULL;
359 int ret = 0;
360 void *hdr;
361
362 if (!info->attrs[WL1251_NL_ATTR_REG_ADDR])
363 return -EINVAL;
364
365 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
366 if (!msg)
367 return -ENOMEM;
368
369 wl = ifname_to_wl1251(&init_net, info);
370 if (wl == NULL) {
371 wl1251_error("wl1251 not found");
372 ret = -EINVAL;
373 goto nla_put_failure;
374 }
375
376 reg_value = kmalloc(sizeof(*reg_value), GFP_KERNEL);
377 if (!reg_value) {
378 ret = -ENOMEM;
379 goto nla_put_failure;
380 }
381
382 reg_addr = nla_get_u32(info->attrs[WL1251_NL_ATTR_REG_ADDR]);
383
384 wl1251_debug(DEBUG_NETLINK, "Reading PHY reg 0x%x", reg_addr);
385
386 mutex_lock(&wl->mutex);
387 ret = wl1251_cmd_read_memory(wl, reg_addr, reg_value,
388 sizeof(*reg_value));
389 mutex_unlock(&wl->mutex);
390
391 if (ret < 0) {
392 wl1251_error("%s() failed", __func__);
393 goto nla_put_failure;
394 }
395
396
397 hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
398 &wl1251_nl_family, 0, WL1251_NL_CMD_PHY_REG_READ);
399 if (IS_ERR(hdr)) {
400 ret = PTR_ERR(hdr);
401 goto nla_put_failure;
402 }
403
404 NLA_PUT_STRING(msg, WL1251_NL_ATTR_IFNAME,
405 nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]));
406
407 NLA_PUT_U32(msg, WL1251_NL_ATTR_REG_VAL, *reg_value);
408
409 ret = genlmsg_end(msg, hdr);
410 if (ret < 0) {
411 wl1251_error("%s() failed", __func__);
412 goto nla_put_failure;
413 }
414
415 kfree(reg_value);
416
417 return genlmsg_reply(msg, info);
418
419 nla_put_failure:
420 nlmsg_free(msg);
421 kfree(reg_value);
422
423 return ret;
424}
425
426static int wl1251_nl_nvs_push(struct sk_buff *skb, struct genl_info *info)
427{
428 struct wl1251 *wl;
429 int ret = 0;
430
431 if (!info->attrs[WL1251_NL_ATTR_NVS_BUFFER])
432 return -EINVAL;
433
434 if (!info->attrs[WL1251_NL_ATTR_NVS_LEN])
435 return -EINVAL;
436
437 wl = ifname_to_wl1251(&init_net, info);
438 if (wl == NULL) {
439 wl1251_error("wl1251 not found");
440 return -EINVAL;
441 }
442
443 mutex_lock(&wl->mutex);
444 wl->nvs_len = nla_get_u32(info->attrs[WL1251_NL_ATTR_NVS_LEN]);
445 if (wl->nvs_len % 4) {
446 wl1251_error("NVS size is not multiple of 32: %d", wl->nvs_len);
447 ret = -EILSEQ;
448 goto out;
449 }
450
451 /* If we already have an NVS, we should free it */
452 kfree(wl->nvs);
453
454 wl->nvs = kzalloc(wl->nvs_len, GFP_KERNEL);
455 if (wl->nvs == NULL) {
456 wl1251_error("Can't allocate NVS");
457 ret = -ENOMEM;
458 goto out;
459 }
460
461 memcpy(wl->nvs,
462 nla_data(info->attrs[WL1251_NL_ATTR_NVS_BUFFER]),
463 wl->nvs_len);
464
465 wl1251_debug(DEBUG_NETLINK, "got NVS from userspace, %d bytes",
466 wl->nvs_len);
467
468out:
469 mutex_unlock(&wl->mutex);
470
471 return ret;
472}
473
474static int wl1251_nl_reg_read(struct sk_buff *skb, struct genl_info *info)
475{
476 struct wl1251 *wl;
477 u32 addr, val;
478 int ret = 0;
479 struct sk_buff *msg;
480 void *hdr;
481
482 if (!info->attrs[WL1251_NL_ATTR_REG_ADDR])
483 return -EINVAL;
484
485 msg = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
486 if (!msg)
487 return -ENOMEM;
488
489 wl = ifname_to_wl1251(&init_net, info);
490 if (wl == NULL) {
491 wl1251_error("wl1251 not found");
492 return -EINVAL;
493 }
494
495 addr = nla_get_u32(info->attrs[WL1251_NL_ATTR_REG_ADDR]);
496
497 mutex_lock(&wl->mutex);
498 val = wl1251_reg_read32(wl, addr);
499 mutex_unlock(&wl->mutex);
500
501 hdr = genlmsg_put(msg, info->snd_pid, info->snd_seq,
502 &wl1251_nl_family, 0, WL1251_NL_CMD_PHY_REG_READ);
503 if (IS_ERR(hdr)) {
504 ret = PTR_ERR(hdr);
505 goto nla_put_failure;
506 }
507
508 NLA_PUT_STRING(msg, WL1251_NL_ATTR_IFNAME,
509 nla_data(info->attrs[WL1251_NL_ATTR_IFNAME]));
510
511 NLA_PUT_U32(msg, WL1251_NL_ATTR_REG_VAL, val);
512
513 ret = genlmsg_end(msg, hdr);
514 if (ret < 0) {
515 wl1251_error("%s() failed", __func__);
516 goto nla_put_failure;
517 }
518
519 return genlmsg_reply(msg, info);
520
521 nla_put_failure:
522 nlmsg_free(msg);
523
524 return ret;
525}
526
527static int wl1251_nl_reg_write(struct sk_buff *skb, struct genl_info *info)
528{
529 struct wl1251 *wl;
530 u32 addr, val;
531
532 if (!info->attrs[WL1251_NL_ATTR_REG_ADDR])
533 return -EINVAL;
534
535 if (!info->attrs[WL1251_NL_ATTR_REG_VAL])
536 return -EINVAL;
537
538 wl = ifname_to_wl1251(&init_net, info);
539 if (wl == NULL) {
540 wl1251_error("wl1251 not found");
541 return -EINVAL;
542 }
543
544 addr = nla_get_u32(info->attrs[WL1251_NL_ATTR_REG_ADDR]);
545 val = nla_get_u32(info->attrs[WL1251_NL_ATTR_REG_VAL]);
546
547 mutex_lock(&wl->mutex);
548 wl1251_reg_write32(wl, addr, val);
549 mutex_unlock(&wl->mutex);
550
551 return 0;
552}
553
554static int wl1251_nl_set_plt_mode(struct sk_buff *skb, struct genl_info *info)
555{
556 struct wl1251 *wl;
557 u32 val;
558 int ret;
559
560 if (!info->attrs[WL1251_NL_ATTR_PLT_MODE])
561 return -EINVAL;
562
563 wl = ifname_to_wl1251(&init_net, info);
564 if (wl == NULL) {
565 wl1251_error("wl1251 not found");
566 return -EINVAL;
567 }
568
569 val = nla_get_u32(info->attrs[WL1251_NL_ATTR_PLT_MODE]);
570
571 switch (val) {
572 case 0:
573 ret = wl1251_plt_stop(wl);
574 break;
575 case 1:
576 ret = wl1251_plt_start(wl);
577 break;
578 default:
579 ret = -EINVAL;
580 break;
581 }
582
583 return ret;
584}
585
586static struct nla_policy wl1251_nl_policy[WL1251_NL_ATTR_MAX + 1] = {
587 [WL1251_NL_ATTR_IFNAME] = { .type = NLA_NUL_STRING,
588 .len = IFNAMSIZ-1 },
589 [WL1251_NL_ATTR_CMD_TEST_PARAM] = { .type = NLA_BINARY,
590 .len = WL1251_MAX_TEST_LENGTH },
591 [WL1251_NL_ATTR_CMD_TEST_ANSWER] = { .type = NLA_U8 },
592 [WL1251_NL_ATTR_CMD_IE] = { .type = NLA_U32 },
593 [WL1251_NL_ATTR_CMD_IE_LEN] = { .type = NLA_U32 },
594 [WL1251_NL_ATTR_CMD_IE_BUFFER] = { .type = NLA_BINARY,
595 .len = WL1251_MAX_TEST_LENGTH },
596 [WL1251_NL_ATTR_CMD_IE_ANSWER] = { .type = NLA_BINARY,
597 .len = WL1251_MAX_TEST_LENGTH },
598 [WL1251_NL_ATTR_REG_ADDR] = { .type = NLA_U32 },
599 [WL1251_NL_ATTR_REG_VAL] = { .type = NLA_U32 },
600 [WL1251_NL_ATTR_NVS_BUFFER] = { .type = NLA_BINARY,
601 .len = WL1251_MAX_NVS_LENGTH },
602 [WL1251_NL_ATTR_NVS_LEN] = { .type = NLA_U32 },
603 [WL1251_NL_ATTR_PLT_MODE] = { .type = NLA_U32 },
604};
605
606static struct genl_ops wl1251_nl_ops[] = {
607 {
608 .cmd = WL1251_NL_CMD_TEST,
609 .doit = wl1251_nl_test_cmd,
610 .policy = wl1251_nl_policy,
611 .flags = GENL_ADMIN_PERM,
612 },
613 {
614 .cmd = WL1251_NL_CMD_INTERROGATE,
615 .doit = wl1251_nl_interrogate,
616 .policy = wl1251_nl_policy,
617 .flags = GENL_ADMIN_PERM,
618 },
619 {
620 .cmd = WL1251_NL_CMD_CONFIGURE,
621 .doit = wl1251_nl_configure,
622 .policy = wl1251_nl_policy,
623 .flags = GENL_ADMIN_PERM,
624 },
625 {
626 .cmd = WL1251_NL_CMD_PHY_REG_READ,
627 .doit = wl1251_nl_phy_reg_read,
628 .policy = wl1251_nl_policy,
629 .flags = GENL_ADMIN_PERM,
630 },
631 {
632 .cmd = WL1251_NL_CMD_NVS_PUSH,
633 .doit = wl1251_nl_nvs_push,
634 .policy = wl1251_nl_policy,
635 .flags = GENL_ADMIN_PERM,
636 },
637 {
638 .cmd = WL1251_NL_CMD_REG_WRITE,
639 .doit = wl1251_nl_reg_write,
640 .policy = wl1251_nl_policy,
641 .flags = GENL_ADMIN_PERM,
642 },
643 {
644 .cmd = WL1251_NL_CMD_REG_READ,
645 .doit = wl1251_nl_reg_read,
646 .policy = wl1251_nl_policy,
647 .flags = GENL_ADMIN_PERM,
648 },
649 {
650 .cmd = WL1251_NL_CMD_SET_PLT_MODE,
651 .doit = wl1251_nl_set_plt_mode,
652 .policy = wl1251_nl_policy,
653 .flags = GENL_ADMIN_PERM,
654 },
655};
656
657int wl1251_nl_register(void)
658{
659 int err, i;
660
661 err = genl_register_family(&wl1251_nl_family);
662 if (err)
663 return err;
664
665 for (i = 0; i < ARRAY_SIZE(wl1251_nl_ops); i++) {
666 err = genl_register_ops(&wl1251_nl_family, &wl1251_nl_ops[i]);
667 if (err)
668 goto err_out;
669 }
670 return 0;
671 err_out:
672 genl_unregister_family(&wl1251_nl_family);
673 return err;
674}
675
676void wl1251_nl_unregister(void)
677{
678 genl_unregister_family(&wl1251_nl_family);
679}
diff --git a/drivers/net/wireless/wl12xx/wl1251_ops.c b/drivers/net/wireless/wl12xx/wl1251_ops.c
index 96a45f595297..e7b9aab3682f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_ops.c
+++ b/drivers/net/wireless/wl12xx/wl1251_ops.c
@@ -423,7 +423,7 @@ static void wl1251_irq_work(struct work_struct *work)
423 wl->rx_counter = 423 wl->rx_counter =
424 wl1251_mem_read32(wl, wl->data_path->rx_control_addr); 424 wl1251_mem_read32(wl, wl->data_path->rx_control_addr);
425 425
426 /* We handle a frmware bug here */ 426 /* We handle a firmware bug here */
427 switch ((wl->rx_counter - wl->rx_handled) & 0xf) { 427 switch ((wl->rx_counter - wl->rx_handled) & 0xf) {
428 case 0: 428 case 0:
429 wl1251_debug(DEBUG_IRQ, "RX: FW and host in sync"); 429 wl1251_debug(DEBUG_IRQ, "RX: FW and host in sync");
@@ -575,7 +575,7 @@ static int wl1251_hw_init_data_path_config(struct wl1251 *wl)
575 wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp), 575 wl->data_path = kzalloc(sizeof(struct acx_data_path_params_resp),
576 GFP_KERNEL); 576 GFP_KERNEL);
577 if (!wl->data_path) { 577 if (!wl->data_path) {
578 wl1251_error("Couldnt allocate data path parameters"); 578 wl1251_error("Couldn't allocate data path parameters");
579 return -ENOMEM; 579 return -ENOMEM;
580 } 580 }
581 581
diff --git a/drivers/net/wireless/wl12xx/wl1251_rx.h b/drivers/net/wireless/wl12xx/wl1251_rx.h
index 81156b9c4758..563a3fde40fb 100644
--- a/drivers/net/wireless/wl12xx/wl1251_rx.h
+++ b/drivers/net/wireless/wl12xx/wl1251_rx.h
@@ -88,7 +88,7 @@ struct wl1251_rx_descriptor {
88 u8 type; 88 u8 type;
89 89
90 /* 90 /*
91 * Recevied Rate: 91 * Received Rate:
92 * 0x0A - 1MBPS 92 * 0x0A - 1MBPS
93 * 0x14 - 2MBPS 93 * 0x14 - 2MBPS
94 * 0x37 - 5_5MBPS 94 * 0x37 - 5_5MBPS
diff --git a/drivers/net/wireless/zd1211rw/zd_usb.c b/drivers/net/wireless/zd1211rw/zd_usb.c
index 07d7ab674a0f..38688847d568 100644
--- a/drivers/net/wireless/zd1211rw/zd_usb.c
+++ b/drivers/net/wireless/zd1211rw/zd_usb.c
@@ -76,6 +76,7 @@ static struct usb_device_id usb_ids[] = {
76 { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B }, 76 { USB_DEVICE(0x07b8, 0x6001), .driver_info = DEVICE_ZD1211B },
77 { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B }, 77 { USB_DEVICE(0x07fa, 0x1196), .driver_info = DEVICE_ZD1211B },
78 { USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B }, 78 { USB_DEVICE(0x083a, 0x4505), .driver_info = DEVICE_ZD1211B },
79 { USB_DEVICE(0x083a, 0xe501), .driver_info = DEVICE_ZD1211B },
79 { USB_DEVICE(0x083a, 0xe503), .driver_info = DEVICE_ZD1211B }, 80 { USB_DEVICE(0x083a, 0xe503), .driver_info = DEVICE_ZD1211B },
80 { USB_DEVICE(0x083a, 0xe506), .driver_info = DEVICE_ZD1211B }, 81 { USB_DEVICE(0x083a, 0xe506), .driver_info = DEVICE_ZD1211B },
81 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B }, 82 { USB_DEVICE(0x0ace, 0x1215), .driver_info = DEVICE_ZD1211B },
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index e496a2daf7ef..962e2232a074 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -567,6 +567,12 @@ enum nl80211_commands {
567 * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE 567 * @NL80211_ATTR_PREV_BSSID: previous BSSID, to be used by in ASSOCIATE
568 * commands to specify using a reassociate frame 568 * commands to specify using a reassociate frame
569 * 569 *
570 * @NL80211_ATTR_KEY: key information in a nested attribute with
571 * %NL80211_KEY_* sub-attributes
572 * @NL80211_ATTR_KEYS: array of keys for static WEP keys for connect()
573 * and join_ibss(), key information is in a nested attribute each
574 * with %NL80211_KEY_* sub-attributes
575 *
570 * @NL80211_ATTR_MAX: highest attribute number currently defined 576 * @NL80211_ATTR_MAX: highest attribute number currently defined
571 * @__NL80211_ATTR_AFTER_LAST: internal use 577 * @__NL80211_ATTR_AFTER_LAST: internal use
572 */ 578 */
@@ -692,6 +698,9 @@ enum nl80211_attrs {
692 698
693 NL80211_ATTR_PREV_BSSID, 699 NL80211_ATTR_PREV_BSSID,
694 700
701 NL80211_ATTR_KEY,
702 NL80211_ATTR_KEYS,
703
695 /* add attributes here, update the policy in nl80211.c */ 704 /* add attributes here, update the policy in nl80211.c */
696 705
697 __NL80211_ATTR_AFTER_LAST, 706 __NL80211_ATTR_AFTER_LAST,
@@ -720,6 +729,8 @@ enum nl80211_attrs {
720#define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP 729#define NL80211_ATTR_CIPHER_SUITE_GROUP NL80211_ATTR_CIPHER_SUITE_GROUP
721#define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS 730#define NL80211_ATTR_WPA_VERSIONS NL80211_ATTR_WPA_VERSIONS
722#define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES 731#define NL80211_ATTR_AKM_SUITES NL80211_ATTR_AKM_SUITES
732#define NL80211_ATTR_KEY NL80211_ATTR_KEY
733#define NL80211_ATTR_KEYS NL80211_ATTR_KEYS
723 734
724#define NL80211_MAX_SUPP_RATES 32 735#define NL80211_MAX_SUPP_RATES 32
725#define NL80211_MAX_SUPP_REG_RULES 32 736#define NL80211_MAX_SUPP_REG_RULES 32
@@ -1249,6 +1260,7 @@ enum nl80211_channel_type {
1249 * in mBm (100 * dBm) (s32) 1260 * in mBm (100 * dBm) (s32)
1250 * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon 1261 * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
1251 * in unspecified units, scaled to 0..100 (u8) 1262 * in unspecified units, scaled to 0..100 (u8)
1263 * @NL80211_BSS_STATUS: status, if this BSS is "used"
1252 * @__NL80211_BSS_AFTER_LAST: internal 1264 * @__NL80211_BSS_AFTER_LAST: internal
1253 * @NL80211_BSS_MAX: highest BSS attribute 1265 * @NL80211_BSS_MAX: highest BSS attribute
1254 */ 1266 */
@@ -1262,6 +1274,7 @@ enum nl80211_bss {
1262 NL80211_BSS_INFORMATION_ELEMENTS, 1274 NL80211_BSS_INFORMATION_ELEMENTS,
1263 NL80211_BSS_SIGNAL_MBM, 1275 NL80211_BSS_SIGNAL_MBM,
1264 NL80211_BSS_SIGNAL_UNSPEC, 1276 NL80211_BSS_SIGNAL_UNSPEC,
1277 NL80211_BSS_STATUS,
1265 1278
1266 /* keep last */ 1279 /* keep last */
1267 __NL80211_BSS_AFTER_LAST, 1280 __NL80211_BSS_AFTER_LAST,
@@ -1269,6 +1282,15 @@ enum nl80211_bss {
1269}; 1282};
1270 1283
1271/** 1284/**
1285 * enum nl80211_bss_status - BSS "status"
1286 */
1287enum nl80211_bss_status {
1288 NL80211_BSS_STATUS_AUTHENTICATED,
1289 NL80211_BSS_STATUS_ASSOCIATED,
1290 NL80211_BSS_STATUS_IBSS_JOINED,
1291};
1292
1293/**
1272 * enum nl80211_auth_type - AuthenticationType 1294 * enum nl80211_auth_type - AuthenticationType
1273 * 1295 *
1274 * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication 1296 * @NL80211_AUTHTYPE_OPEN_SYSTEM: Open System authentication
@@ -1320,4 +1342,34 @@ enum nl80211_wpa_versions {
1320 NL80211_WPA_VERSION_2 = 1 << 1, 1342 NL80211_WPA_VERSION_2 = 1 << 1,
1321}; 1343};
1322 1344
1345/**
1346 * enum nl80211_key_attributes - key attributes
1347 * @__NL80211_KEY_INVALID: invalid
1348 * @NL80211_KEY_DATA: (temporal) key data; for TKIP this consists of
1349 * 16 bytes encryption key followed by 8 bytes each for TX and RX MIC
1350 * keys
1351 * @NL80211_KEY_IDX: key ID (u8, 0-3)
1352 * @NL80211_KEY_CIPHER: key cipher suite (u32, as defined by IEEE 802.11
1353 * section 7.3.2.25.1, e.g. 0x000FAC04)
1354 * @NL80211_KEY_SEQ: transmit key sequence number (IV/PN) for TKIP and
1355 * CCMP keys, each six bytes in little endian
1356 * @NL80211_KEY_DEFAULT: flag indicating default key
1357 * @NL80211_KEY_DEFAULT_MGMT: flag indicating default management key
1358 * @__NL80211_KEY_AFTER_LAST: internal
1359 * @NL80211_KEY_MAX: highest key attribute
1360 */
1361enum nl80211_key_attributes {
1362 __NL80211_KEY_INVALID,
1363 NL80211_KEY_DATA,
1364 NL80211_KEY_IDX,
1365 NL80211_KEY_CIPHER,
1366 NL80211_KEY_SEQ,
1367 NL80211_KEY_DEFAULT,
1368 NL80211_KEY_DEFAULT_MGMT,
1369
1370 /* keep last */
1371 __NL80211_KEY_AFTER_LAST,
1372 NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
1373};
1374
1323#endif /* __LINUX_NL80211_H */ 1375#endif /* __LINUX_NL80211_H */
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index f2c69a2cca17..df7b23ac66e6 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -304,7 +304,6 @@ typedef unsigned char *sk_buff_data_t;
304 * @tc_index: Traffic control index 304 * @tc_index: Traffic control index
305 * @tc_verd: traffic control verdict 305 * @tc_verd: traffic control verdict
306 * @ndisc_nodetype: router type (from link layer) 306 * @ndisc_nodetype: router type (from link layer)
307 * @do_not_encrypt: set to prevent encryption of this frame
308 * @dma_cookie: a cookie to one of several possible DMA operations 307 * @dma_cookie: a cookie to one of several possible DMA operations
309 * done by skb DMA functions 308 * done by skb DMA functions
310 * @secmark: security marking 309 * @secmark: security marking
@@ -380,12 +379,9 @@ struct sk_buff {
380#ifdef CONFIG_IPV6_NDISC_NODETYPE 379#ifdef CONFIG_IPV6_NDISC_NODETYPE
381 __u8 ndisc_nodetype:2; 380 __u8 ndisc_nodetype:2;
382#endif 381#endif
383#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
384 __u8 do_not_encrypt:1;
385#endif
386 kmemcheck_bitfield_end(flags2); 382 kmemcheck_bitfield_end(flags2);
387 383
388 /* 0/13/14 bit hole */ 384 /* 0/14 bit hole */
389 385
390#ifdef CONFIG_NET_DMA 386#ifdef CONFIG_NET_DMA
391 dma_cookie_t dma_cookie; 387 dma_cookie_t dma_cookie;
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 83c2c727d71e..a981ca8a5701 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -538,7 +538,7 @@ struct cfg80211_ssid {
538 * @ssids: SSIDs to scan for (active scan only) 538 * @ssids: SSIDs to scan for (active scan only)
539 * @n_ssids: number of SSIDs 539 * @n_ssids: number of SSIDs
540 * @channels: channels to scan on. 540 * @channels: channels to scan on.
541 * @n_channels: number of channels for each band 541 * @n_channels: total number of channels to scan
542 * @ie: optional information element(s) to add into Probe Request or %NULL 542 * @ie: optional information element(s) to add into Probe Request or %NULL
543 * @ie_len: length of ie in octets 543 * @ie_len: length of ie in octets
544 * @wiphy: the wiphy this was for 544 * @wiphy: the wiphy this was for
@@ -647,12 +647,17 @@ struct cfg80211_crypto_settings {
647 * @auth_type: Authentication type (algorithm) 647 * @auth_type: Authentication type (algorithm)
648 * @ie: Extra IEs to add to Authentication frame or %NULL 648 * @ie: Extra IEs to add to Authentication frame or %NULL
649 * @ie_len: Length of ie buffer in octets 649 * @ie_len: Length of ie buffer in octets
650 * @key_len: length of WEP key for shared key authentication
651 * @key_idx: index of WEP key for shared key authentication
652 * @key: WEP key for shared key authentication
650 */ 653 */
651struct cfg80211_auth_request { 654struct cfg80211_auth_request {
652 struct cfg80211_bss *bss; 655 struct cfg80211_bss *bss;
653 const u8 *ie; 656 const u8 *ie;
654 size_t ie_len; 657 size_t ie_len;
655 enum nl80211_auth_type auth_type; 658 enum nl80211_auth_type auth_type;
659 const u8 *key;
660 u8 key_len, key_idx;
656}; 661};
657 662
658/** 663/**
@@ -727,6 +732,8 @@ struct cfg80211_disassoc_request {
727 * @ie: information element(s) to include in the beacon 732 * @ie: information element(s) to include in the beacon
728 * @ie_len: length of that 733 * @ie_len: length of that
729 * @beacon_interval: beacon interval to use 734 * @beacon_interval: beacon interval to use
735 * @privacy: this is a protected network, keys will be configured
736 * after joining
730 */ 737 */
731struct cfg80211_ibss_params { 738struct cfg80211_ibss_params {
732 u8 *ssid; 739 u8 *ssid;
@@ -736,6 +743,7 @@ struct cfg80211_ibss_params {
736 u8 ssid_len, ie_len; 743 u8 ssid_len, ie_len;
737 u16 beacon_interval; 744 u16 beacon_interval;
738 bool channel_fixed; 745 bool channel_fixed;
746 bool privacy;
739}; 747};
740 748
741/** 749/**
@@ -755,6 +763,9 @@ struct cfg80211_ibss_params {
755 * @assoc_ie_len: Length of assoc_ie in octets 763 * @assoc_ie_len: Length of assoc_ie in octets
756 * @privacy: indicates whether privacy-enabled APs should be used 764 * @privacy: indicates whether privacy-enabled APs should be used
757 * @crypto: crypto settings 765 * @crypto: crypto settings
766 * @key_len: length of WEP key for shared key authentication
767 * @key_idx: index of WEP key for shared key authentication
768 * @key: WEP key for shared key authentication
758 */ 769 */
759struct cfg80211_connect_params { 770struct cfg80211_connect_params {
760 struct ieee80211_channel *channel; 771 struct ieee80211_channel *channel;
@@ -766,6 +777,8 @@ struct cfg80211_connect_params {
766 size_t ie_len; 777 size_t ie_len;
767 bool privacy; 778 bool privacy;
768 struct cfg80211_crypto_settings crypto; 779 struct cfg80211_crypto_settings crypto;
780 const u8 *key;
781 u8 key_len, key_idx;
769}; 782};
770 783
771/** 784/**
@@ -1223,9 +1236,10 @@ extern void wiphy_unregister(struct wiphy *wiphy);
1223 */ 1236 */
1224extern void wiphy_free(struct wiphy *wiphy); 1237extern void wiphy_free(struct wiphy *wiphy);
1225 1238
1226/* internal struct */ 1239/* internal structs */
1227struct cfg80211_conn; 1240struct cfg80211_conn;
1228struct cfg80211_internal_bss; 1241struct cfg80211_internal_bss;
1242struct cfg80211_cached_keys;
1229 1243
1230#define MAX_AUTH_BSSES 4 1244#define MAX_AUTH_BSSES 4
1231 1245
@@ -1267,6 +1281,7 @@ struct wireless_dev {
1267 CFG80211_SME_CONNECTED, 1281 CFG80211_SME_CONNECTED,
1268 } sme_state; 1282 } sme_state;
1269 struct cfg80211_conn *conn; 1283 struct cfg80211_conn *conn;
1284 struct cfg80211_cached_keys *connect_keys;
1270 1285
1271 struct list_head event_list; 1286 struct list_head event_list;
1272 spinlock_t event_lock; 1287 spinlock_t event_lock;
@@ -1280,6 +1295,7 @@ struct wireless_dev {
1280 struct { 1295 struct {
1281 struct cfg80211_ibss_params ibss; 1296 struct cfg80211_ibss_params ibss;
1282 struct cfg80211_connect_params connect; 1297 struct cfg80211_connect_params connect;
1298 struct cfg80211_cached_keys *keys;
1283 u8 *ie; 1299 u8 *ie;
1284 size_t ie_len; 1300 size_t ie_len;
1285 u8 bssid[ETH_ALEN]; 1301 u8 bssid[ETH_ALEN];
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index ce7cb1b5d453..7dd67a1ff4d5 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -241,6 +241,8 @@ struct ieee80211_bss_conf {
241 * it can be sent out. 241 * it can be sent out.
242 * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211, 242 * @IEEE80211_TX_INTFL_RETRIED: completely internal to mac80211,
243 * used to indicate that a frame was already retried due to PS 243 * used to indicate that a frame was already retried due to PS
244 * @IEEE80211_TX_INTFL_DONT_ENCRYPT: completely internal to mac80211,
245 * used to indicate frame should not be encrypted
244 */ 246 */
245enum mac80211_tx_control_flags { 247enum mac80211_tx_control_flags {
246 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0), 248 IEEE80211_TX_CTL_REQ_TX_STATUS = BIT(0),
@@ -259,6 +261,7 @@ enum mac80211_tx_control_flags {
259 IEEE80211_TX_INTFL_RCALGO = BIT(13), 261 IEEE80211_TX_INTFL_RCALGO = BIT(13),
260 IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), 262 IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14),
261 IEEE80211_TX_INTFL_RETRIED = BIT(15), 263 IEEE80211_TX_INTFL_RETRIED = BIT(15),
264 IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16),
262}; 265};
263 266
264/** 267/**
@@ -2094,6 +2097,29 @@ static inline int rate_supported(struct ieee80211_sta *sta,
2094 return (sta == NULL || sta->supp_rates[band] & BIT(index)); 2097 return (sta == NULL || sta->supp_rates[band] & BIT(index));
2095} 2098}
2096 2099
2100/**
2101 * rate_control_send_low - helper for drivers for management/no-ack frames
2102 *
2103 * Rate control algorithms that agree to use the lowest rate to
2104 * send management frames and NO_ACK data with the respective hw
2105 * retries should use this in the beginning of their mac80211 get_rate
2106 * callback. If true is returned the rate control can simply return.
2107 * If false is returned we guarantee that sta and sta and priv_sta is
2108 * not null.
2109 *
2110 * Rate control algorithms wishing to do more intelligent selection of
2111 * rate for multicast/broadcast frames may choose to not use this.
2112 *
2113 * @sta: &struct ieee80211_sta pointer to the target destination. Note
2114 * that this may be null.
2115 * @priv_sta: private rate control structure. This may be null.
2116 * @txrc: rate control information we sholud populate for mac80211.
2117 */
2118bool rate_control_send_low(struct ieee80211_sta *sta,
2119 void *priv_sta,
2120 struct ieee80211_tx_rate_control *txrc);
2121
2122
2097static inline s8 2123static inline s8
2098rate_lowest_index(struct ieee80211_supported_band *sband, 2124rate_lowest_index(struct ieee80211_supported_band *sband,
2099 struct ieee80211_sta *sta) 2125 struct ieee80211_sta *sta)
@@ -2110,6 +2136,17 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
2110 return 0; 2136 return 0;
2111} 2137}
2112 2138
2139static inline
2140bool rate_usable_index_exists(struct ieee80211_supported_band *sband,
2141 struct ieee80211_sta *sta)
2142{
2143 unsigned int i;
2144
2145 for (i = 0; i < sband->n_bitrates; i++)
2146 if (rate_supported(sta, sband->band, i))
2147 return true;
2148 return false;
2149}
2113 2150
2114int ieee80211_rate_control_register(struct rate_control_ops *ops); 2151int ieee80211_rate_control_register(struct rate_control_ops *ops);
2115void ieee80211_rate_control_unregister(struct rate_control_ops *ops); 2152void ieee80211_rate_control_unregister(struct rate_control_ops *ops);
diff --git a/net/core/dev.c b/net/core/dev.c
index dca8b5000d3b..d6c657ee413d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3923,6 +3923,7 @@ int __dev_addr_sync(struct dev_addr_list **to, int *to_count,
3923 } 3923 }
3924 return err; 3924 return err;
3925} 3925}
3926EXPORT_SYMBOL_GPL(__dev_addr_sync);
3926 3927
3927void __dev_addr_unsync(struct dev_addr_list **to, int *to_count, 3928void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
3928 struct dev_addr_list **from, int *from_count) 3929 struct dev_addr_list **from, int *from_count)
@@ -3942,6 +3943,7 @@ void __dev_addr_unsync(struct dev_addr_list **to, int *to_count,
3942 da = next; 3943 da = next;
3943 } 3944 }
3944} 3945}
3946EXPORT_SYMBOL_GPL(__dev_addr_unsync);
3945 3947
3946/** 3948/**
3947 * dev_unicast_sync - Synchronize device's unicast list to another device 3949 * dev_unicast_sync - Synchronize device's unicast list to another device
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 9e0597d189b0..80a96166df39 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -559,9 +559,6 @@ static void __copy_skb_header(struct sk_buff *new, const struct sk_buff *old)
559#endif 559#endif
560#endif 560#endif
561 new->vlan_tci = old->vlan_tci; 561 new->vlan_tci = old->vlan_tci;
562#if defined(CONFIG_MAC80211) || defined(CONFIG_MAC80211_MODULE)
563 new->do_not_encrypt = old->do_not_encrypt;
564#endif
565 562
566 skb_copy_secmark(new, old); 563 skb_copy_secmark(new, old);
567} 564}
diff --git a/net/mac80211/Kconfig b/net/mac80211/Kconfig
index 182c9c5c6818..19a4c66e143e 100644
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -206,3 +206,15 @@ config MAC80211_DEBUG_COUNTERS
206 and show them in debugfs. 206 and show them in debugfs.
207 207
208 If unsure, say N. 208 If unsure, say N.
209
210config MAC80211_DRIVER_API_TRACER
211 bool "Driver API tracer"
212 depends on MAC80211_DEBUG_MENU
213 depends on EVENT_TRACING
214 help
215 Say Y here to make mac80211 register with the ftrace
216 framework for the driver API -- you can see which
217 driver methods it is calling then by looking at the
218 trace.
219
220 If unsure, say N.
diff --git a/net/mac80211/Makefile b/net/mac80211/Makefile
index 0e3ab88bb706..91284a74ff91 100644
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -41,6 +41,9 @@ mac80211-$(CONFIG_MAC80211_MESH) += \
41 41
42mac80211-$(CONFIG_PM) += pm.o 42mac80211-$(CONFIG_PM) += pm.o
43 43
44mac80211-$(CONFIG_MAC80211_DRIVER_API_TRACER) += driver-trace.o
45CFLAGS_driver-trace.o := -I$(src)
46
44# objects for PID algorithm 47# objects for PID algorithm
45rc80211_pid-y := rc80211_pid_algo.o 48rc80211_pid-y := rc80211_pid_algo.o
46rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o 49rc80211_pid-$(CONFIG_MAC80211_DEBUGFS) += rc80211_pid_debugfs.o
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index 9e5762ad307d..1958c7c42cd9 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -383,9 +383,6 @@ static void ieee80211_agg_splice_packets(struct ieee80211_local *local,
383 383
384 if (!skb_queue_empty(&sta->ampdu_mlme.tid_tx[tid]->pending)) { 384 if (!skb_queue_empty(&sta->ampdu_mlme.tid_tx[tid]->pending)) {
385 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 385 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
386 /* mark queue as pending, it is stopped already */
387 __set_bit(IEEE80211_QUEUE_STOP_REASON_PENDING,
388 &local->queue_stop_reasons[queue]);
389 /* copy over remaining packets */ 386 /* copy over remaining packets */
390 skb_queue_splice_tail_init( 387 skb_queue_splice_tail_init(
391 &sta->ampdu_mlme.tid_tx[tid]->pending, 388 &sta->ampdu_mlme.tid_tx[tid]->pending,
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 36f8f245fa4c..52928ad90570 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -1293,7 +1293,7 @@ static void ieee80211_rfkill_poll(struct wiphy *wiphy)
1293} 1293}
1294 1294
1295#ifdef CONFIG_NL80211_TESTMODE 1295#ifdef CONFIG_NL80211_TESTMODE
1296int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len) 1296static int ieee80211_testmode_cmd(struct wiphy *wiphy, void *data, int len)
1297{ 1297{
1298 struct ieee80211_local *local = wiphy_priv(wiphy); 1298 struct ieee80211_local *local = wiphy_priv(wiphy);
1299 1299
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index 6c439cd5ccea..96991b68f048 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -175,7 +175,7 @@ static ssize_t queues_read(struct file *file, char __user *user_buf,
175 for (q = 0; q < local->hw.queues; q++) 175 for (q = 0; q < local->hw.queues; q++)
176 res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q, 176 res += sprintf(buf + res, "%02d: %#.8lx/%d\n", q,
177 local->queue_stop_reasons[q], 177 local->queue_stop_reasons[q],
178 __netif_subqueue_stopped(local->mdev, q)); 178 skb_queue_len(&local->pending[q]));
179 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 179 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
180 180
181 return simple_read_from_buffer(user_buf, count, ppos, buf, res); 181 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index b13446afd48f..4100c361a99d 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -3,6 +3,7 @@
3 3
4#include <net/mac80211.h> 4#include <net/mac80211.h>
5#include "ieee80211_i.h" 5#include "ieee80211_i.h"
6#include "driver-trace.h"
6 7
7static inline int drv_tx(struct ieee80211_local *local, struct sk_buff *skb) 8static inline int drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
8{ 9{
@@ -11,29 +12,37 @@ static inline int drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
11 12
12static inline int drv_start(struct ieee80211_local *local) 13static inline int drv_start(struct ieee80211_local *local)
13{ 14{
14 return local->ops->start(&local->hw); 15 int ret = local->ops->start(&local->hw);
16 trace_drv_start(local, ret);
17 return ret;
15} 18}
16 19
17static inline void drv_stop(struct ieee80211_local *local) 20static inline void drv_stop(struct ieee80211_local *local)
18{ 21{
19 local->ops->stop(&local->hw); 22 local->ops->stop(&local->hw);
23 trace_drv_stop(local);
20} 24}
21 25
22static inline int drv_add_interface(struct ieee80211_local *local, 26static inline int drv_add_interface(struct ieee80211_local *local,
23 struct ieee80211_if_init_conf *conf) 27 struct ieee80211_if_init_conf *conf)
24{ 28{
25 return local->ops->add_interface(&local->hw, conf); 29 int ret = local->ops->add_interface(&local->hw, conf);
30 trace_drv_add_interface(local, conf->mac_addr, conf->vif, ret);
31 return ret;
26} 32}
27 33
28static inline void drv_remove_interface(struct ieee80211_local *local, 34static inline void drv_remove_interface(struct ieee80211_local *local,
29 struct ieee80211_if_init_conf *conf) 35 struct ieee80211_if_init_conf *conf)
30{ 36{
31 local->ops->remove_interface(&local->hw, conf); 37 local->ops->remove_interface(&local->hw, conf);
38 trace_drv_remove_interface(local, conf->mac_addr, conf->vif);
32} 39}
33 40
34static inline int drv_config(struct ieee80211_local *local, u32 changed) 41static inline int drv_config(struct ieee80211_local *local, u32 changed)
35{ 42{
36 return local->ops->config(&local->hw, changed); 43 int ret = local->ops->config(&local->hw, changed);
44 trace_drv_config(local, changed, ret);
45 return ret;
37} 46}
38 47
39static inline void drv_bss_info_changed(struct ieee80211_local *local, 48static inline void drv_bss_info_changed(struct ieee80211_local *local,
@@ -43,6 +52,7 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
43{ 52{
44 if (local->ops->bss_info_changed) 53 if (local->ops->bss_info_changed)
45 local->ops->bss_info_changed(&local->hw, vif, info, changed); 54 local->ops->bss_info_changed(&local->hw, vif, info, changed);
55 trace_drv_bss_info_changed(local, vif, info, changed);
46} 56}
47 57
48static inline void drv_configure_filter(struct ieee80211_local *local, 58static inline void drv_configure_filter(struct ieee80211_local *local,
@@ -53,14 +63,18 @@ static inline void drv_configure_filter(struct ieee80211_local *local,
53{ 63{
54 local->ops->configure_filter(&local->hw, changed_flags, total_flags, 64 local->ops->configure_filter(&local->hw, changed_flags, total_flags,
55 mc_count, mc_list); 65 mc_count, mc_list);
66 trace_drv_configure_filter(local, changed_flags, total_flags,
67 mc_count);
56} 68}
57 69
58static inline int drv_set_tim(struct ieee80211_local *local, 70static inline int drv_set_tim(struct ieee80211_local *local,
59 struct ieee80211_sta *sta, bool set) 71 struct ieee80211_sta *sta, bool set)
60{ 72{
73 int ret = 0;
61 if (local->ops->set_tim) 74 if (local->ops->set_tim)
62 return local->ops->set_tim(&local->hw, sta, set); 75 ret = local->ops->set_tim(&local->hw, sta, set);
63 return 0; 76 trace_drv_set_tim(local, sta, set, ret);
77 return ret;
64} 78}
65 79
66static inline int drv_set_key(struct ieee80211_local *local, 80static inline int drv_set_key(struct ieee80211_local *local,
@@ -68,7 +82,9 @@ static inline int drv_set_key(struct ieee80211_local *local,
68 struct ieee80211_sta *sta, 82 struct ieee80211_sta *sta,
69 struct ieee80211_key_conf *key) 83 struct ieee80211_key_conf *key)
70{ 84{
71 return local->ops->set_key(&local->hw, cmd, vif, sta, key); 85 int ret = local->ops->set_key(&local->hw, cmd, vif, sta, key);
86 trace_drv_set_key(local, cmd, vif, sta, key, ret);
87 return ret;
72} 88}
73 89
74static inline void drv_update_tkip_key(struct ieee80211_local *local, 90static inline void drv_update_tkip_key(struct ieee80211_local *local,
@@ -79,32 +95,41 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local,
79 if (local->ops->update_tkip_key) 95 if (local->ops->update_tkip_key)
80 local->ops->update_tkip_key(&local->hw, conf, address, 96 local->ops->update_tkip_key(&local->hw, conf, address,
81 iv32, phase1key); 97 iv32, phase1key);
98 trace_drv_update_tkip_key(local, conf, address, iv32);
82} 99}
83 100
84static inline int drv_hw_scan(struct ieee80211_local *local, 101static inline int drv_hw_scan(struct ieee80211_local *local,
85 struct cfg80211_scan_request *req) 102 struct cfg80211_scan_request *req)
86{ 103{
87 return local->ops->hw_scan(&local->hw, req); 104 int ret = local->ops->hw_scan(&local->hw, req);
105 trace_drv_hw_scan(local, req, ret);
106 return ret;
88} 107}
89 108
90static inline void drv_sw_scan_start(struct ieee80211_local *local) 109static inline void drv_sw_scan_start(struct ieee80211_local *local)
91{ 110{
92 if (local->ops->sw_scan_start) 111 if (local->ops->sw_scan_start)
93 local->ops->sw_scan_start(&local->hw); 112 local->ops->sw_scan_start(&local->hw);
113 trace_drv_sw_scan_start(local);
94} 114}
95 115
96static inline void drv_sw_scan_complete(struct ieee80211_local *local) 116static inline void drv_sw_scan_complete(struct ieee80211_local *local)
97{ 117{
98 if (local->ops->sw_scan_complete) 118 if (local->ops->sw_scan_complete)
99 local->ops->sw_scan_complete(&local->hw); 119 local->ops->sw_scan_complete(&local->hw);
120 trace_drv_sw_scan_complete(local);
100} 121}
101 122
102static inline int drv_get_stats(struct ieee80211_local *local, 123static inline int drv_get_stats(struct ieee80211_local *local,
103 struct ieee80211_low_level_stats *stats) 124 struct ieee80211_low_level_stats *stats)
104{ 125{
105 if (!local->ops->get_stats) 126 int ret = -EOPNOTSUPP;
106 return -EOPNOTSUPP; 127
107 return local->ops->get_stats(&local->hw, stats); 128 if (local->ops->get_stats)
129 ret = local->ops->get_stats(&local->hw, stats);
130 trace_drv_get_stats(local, stats, ret);
131
132 return ret;
108} 133}
109 134
110static inline void drv_get_tkip_seq(struct ieee80211_local *local, 135static inline void drv_get_tkip_seq(struct ieee80211_local *local,
@@ -112,14 +137,17 @@ static inline void drv_get_tkip_seq(struct ieee80211_local *local,
112{ 137{
113 if (local->ops->get_tkip_seq) 138 if (local->ops->get_tkip_seq)
114 local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16); 139 local->ops->get_tkip_seq(&local->hw, hw_key_idx, iv32, iv16);
140 trace_drv_get_tkip_seq(local, hw_key_idx, iv32, iv16);
115} 141}
116 142
117static inline int drv_set_rts_threshold(struct ieee80211_local *local, 143static inline int drv_set_rts_threshold(struct ieee80211_local *local,
118 u32 value) 144 u32 value)
119{ 145{
146 int ret = 0;
120 if (local->ops->set_rts_threshold) 147 if (local->ops->set_rts_threshold)
121 return local->ops->set_rts_threshold(&local->hw, value); 148 ret = local->ops->set_rts_threshold(&local->hw, value);
122 return 0; 149 trace_drv_set_rts_threshold(local, value, ret);
150 return ret;
123} 151}
124 152
125static inline void drv_sta_notify(struct ieee80211_local *local, 153static inline void drv_sta_notify(struct ieee80211_local *local,
@@ -129,46 +157,57 @@ static inline void drv_sta_notify(struct ieee80211_local *local,
129{ 157{
130 if (local->ops->sta_notify) 158 if (local->ops->sta_notify)
131 local->ops->sta_notify(&local->hw, vif, cmd, sta); 159 local->ops->sta_notify(&local->hw, vif, cmd, sta);
160 trace_drv_sta_notify(local, vif, cmd, sta);
132} 161}
133 162
134static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue, 163static inline int drv_conf_tx(struct ieee80211_local *local, u16 queue,
135 const struct ieee80211_tx_queue_params *params) 164 const struct ieee80211_tx_queue_params *params)
136{ 165{
166 int ret = -EOPNOTSUPP;
137 if (local->ops->conf_tx) 167 if (local->ops->conf_tx)
138 return local->ops->conf_tx(&local->hw, queue, params); 168 ret = local->ops->conf_tx(&local->hw, queue, params);
139 return -EOPNOTSUPP; 169 trace_drv_conf_tx(local, queue, params, ret);
170 return ret;
140} 171}
141 172
142static inline int drv_get_tx_stats(struct ieee80211_local *local, 173static inline int drv_get_tx_stats(struct ieee80211_local *local,
143 struct ieee80211_tx_queue_stats *stats) 174 struct ieee80211_tx_queue_stats *stats)
144{ 175{
145 return local->ops->get_tx_stats(&local->hw, stats); 176 int ret = local->ops->get_tx_stats(&local->hw, stats);
177 trace_drv_get_tx_stats(local, stats, ret);
178 return ret;
146} 179}
147 180
148static inline u64 drv_get_tsf(struct ieee80211_local *local) 181static inline u64 drv_get_tsf(struct ieee80211_local *local)
149{ 182{
183 u64 ret = -1ULL;
150 if (local->ops->get_tsf) 184 if (local->ops->get_tsf)
151 return local->ops->get_tsf(&local->hw); 185 ret = local->ops->get_tsf(&local->hw);
152 return -1ULL; 186 trace_drv_get_tsf(local, ret);
187 return ret;
153} 188}
154 189
155static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf) 190static inline void drv_set_tsf(struct ieee80211_local *local, u64 tsf)
156{ 191{
157 if (local->ops->set_tsf) 192 if (local->ops->set_tsf)
158 local->ops->set_tsf(&local->hw, tsf); 193 local->ops->set_tsf(&local->hw, tsf);
194 trace_drv_set_tsf(local, tsf);
159} 195}
160 196
161static inline void drv_reset_tsf(struct ieee80211_local *local) 197static inline void drv_reset_tsf(struct ieee80211_local *local)
162{ 198{
163 if (local->ops->reset_tsf) 199 if (local->ops->reset_tsf)
164 local->ops->reset_tsf(&local->hw); 200 local->ops->reset_tsf(&local->hw);
201 trace_drv_reset_tsf(local);
165} 202}
166 203
167static inline int drv_tx_last_beacon(struct ieee80211_local *local) 204static inline int drv_tx_last_beacon(struct ieee80211_local *local)
168{ 205{
206 int ret = 1;
169 if (local->ops->tx_last_beacon) 207 if (local->ops->tx_last_beacon)
170 return local->ops->tx_last_beacon(&local->hw); 208 ret = local->ops->tx_last_beacon(&local->hw);
171 return 1; 209 trace_drv_tx_last_beacon(local, ret);
210 return ret;
172} 211}
173 212
174static inline int drv_ampdu_action(struct ieee80211_local *local, 213static inline int drv_ampdu_action(struct ieee80211_local *local,
@@ -176,10 +215,12 @@ static inline int drv_ampdu_action(struct ieee80211_local *local,
176 struct ieee80211_sta *sta, u16 tid, 215 struct ieee80211_sta *sta, u16 tid,
177 u16 *ssn) 216 u16 *ssn)
178{ 217{
218 int ret = -EOPNOTSUPP;
179 if (local->ops->ampdu_action) 219 if (local->ops->ampdu_action)
180 return local->ops->ampdu_action(&local->hw, action, 220 ret = local->ops->ampdu_action(&local->hw, action,
181 sta, tid, ssn); 221 sta, tid, ssn);
182 return -EOPNOTSUPP; 222 trace_drv_ampdu_action(local, action, sta, tid, ssn, ret);
223 return ret;
183} 224}
184 225
185 226
diff --git a/net/mac80211/driver-trace.c b/net/mac80211/driver-trace.c
new file mode 100644
index 000000000000..6da6f79932fc
--- /dev/null
+++ b/net/mac80211/driver-trace.c
@@ -0,0 +1,6 @@
1/* bug in tracepoint.h, it should include this */
2#include <linux/module.h>
3
4#include "driver-ops.h"
5#define CREATE_TRACE_POINTS
6#include "driver-trace.h"
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
new file mode 100644
index 000000000000..5a10da2d70fd
--- /dev/null
+++ b/net/mac80211/driver-trace.h
@@ -0,0 +1,648 @@
1#if !defined(__MAC80211_DRIVER_TRACE) || defined(TRACE_HEADER_MULTI_READ)
2#define __MAC80211_DRIVER_TRACE
3
4#include <linux/tracepoint.h>
5#include <net/mac80211.h>
6#include "ieee80211_i.h"
7
8#if !defined(CONFIG_MAC80211_DRIVER_API_TRACER) || defined(__CHECKER__)
9#undef TRACE_EVENT
10#define TRACE_EVENT(name, proto, ...) \
11static inline void trace_ ## name(proto) {}
12#endif
13
14#undef TRACE_SYSTEM
15#define TRACE_SYSTEM mac80211
16
17#define MAXNAME 32
18#define LOCAL_ENTRY __array(char, wiphy_name, 32)
19#define LOCAL_ASSIGN strlcpy(__entry->wiphy_name, wiphy_name(local->hw.wiphy), MAXNAME)
20#define LOCAL_PR_FMT "%s"
21#define LOCAL_PR_ARG __entry->wiphy_name
22
23#define STA_ENTRY __array(char, sta_addr, ETH_ALEN)
24#define STA_ASSIGN (sta ? memcpy(__entry->sta_addr, sta->addr, ETH_ALEN) : memset(__entry->sta_addr, 0, ETH_ALEN))
25#define STA_PR_FMT " sta:%pM"
26#define STA_PR_ARG __entry->sta_addr
27
28#define VIF_ENTRY __field(enum nl80211_iftype, vif_type) __field(void *, vif)
29#define VIF_ASSIGN __entry->vif_type = vif ? vif->type : 0; __entry->vif = vif
30#define VIF_PR_FMT " vif:%p(%d)"
31#define VIF_PR_ARG __entry->vif, __entry->vif_type
32
33TRACE_EVENT(drv_start,
34 TP_PROTO(struct ieee80211_local *local, int ret),
35
36 TP_ARGS(local, ret),
37
38 TP_STRUCT__entry(
39 LOCAL_ENTRY
40 __field(int, ret)
41 ),
42
43 TP_fast_assign(
44 LOCAL_ASSIGN;
45 __entry->ret = ret;
46 ),
47
48 TP_printk(
49 LOCAL_PR_FMT, LOCAL_PR_ARG
50 )
51);
52
53TRACE_EVENT(drv_stop,
54 TP_PROTO(struct ieee80211_local *local),
55
56 TP_ARGS(local),
57
58 TP_STRUCT__entry(
59 LOCAL_ENTRY
60 ),
61
62 TP_fast_assign(
63 LOCAL_ASSIGN;
64 ),
65
66 TP_printk(
67 LOCAL_PR_FMT, LOCAL_PR_ARG
68 )
69);
70
71TRACE_EVENT(drv_add_interface,
72 TP_PROTO(struct ieee80211_local *local,
73 const u8 *addr,
74 struct ieee80211_vif *vif,
75 int ret),
76
77 TP_ARGS(local, addr, vif, ret),
78
79 TP_STRUCT__entry(
80 LOCAL_ENTRY
81 VIF_ENTRY
82 __array(char, addr, 6)
83 __field(int, ret)
84 ),
85
86 TP_fast_assign(
87 LOCAL_ASSIGN;
88 VIF_ASSIGN;
89 memcpy(__entry->addr, addr, 6);
90 __entry->ret = ret;
91 ),
92
93 TP_printk(
94 LOCAL_PR_FMT VIF_PR_FMT " addr:%pM ret:%d",
95 LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr, __entry->ret
96 )
97);
98
99TRACE_EVENT(drv_remove_interface,
100 TP_PROTO(struct ieee80211_local *local,
101 const u8 *addr, struct ieee80211_vif *vif),
102
103 TP_ARGS(local, addr, vif),
104
105 TP_STRUCT__entry(
106 LOCAL_ENTRY
107 VIF_ENTRY
108 __array(char, addr, 6)
109 ),
110
111 TP_fast_assign(
112 LOCAL_ASSIGN;
113 VIF_ASSIGN;
114 memcpy(__entry->addr, addr, 6);
115 ),
116
117 TP_printk(
118 LOCAL_PR_FMT VIF_PR_FMT " addr:%pM",
119 LOCAL_PR_ARG, VIF_PR_ARG, __entry->addr
120 )
121);
122
123TRACE_EVENT(drv_config,
124 TP_PROTO(struct ieee80211_local *local,
125 u32 changed,
126 int ret),
127
128 TP_ARGS(local, changed, ret),
129
130 TP_STRUCT__entry(
131 LOCAL_ENTRY
132 __field(u32, changed)
133 __field(int, ret)
134 ),
135
136 TP_fast_assign(
137 LOCAL_ASSIGN;
138 __entry->changed = changed;
139 __entry->ret = ret;
140 ),
141
142 TP_printk(
143 LOCAL_PR_FMT " ch:%#x ret:%d",
144 LOCAL_PR_ARG, __entry->changed, __entry->ret
145 )
146);
147
148TRACE_EVENT(drv_bss_info_changed,
149 TP_PROTO(struct ieee80211_local *local,
150 struct ieee80211_vif *vif,
151 struct ieee80211_bss_conf *info,
152 u32 changed),
153
154 TP_ARGS(local, vif, info, changed),
155
156 TP_STRUCT__entry(
157 LOCAL_ENTRY
158 VIF_ENTRY
159 __field(bool, assoc)
160 __field(u16, aid)
161 __field(bool, cts)
162 __field(bool, shortpre)
163 __field(bool, shortslot)
164 __field(u8, dtimper)
165 __field(u16, bcnint)
166 __field(u16, assoc_cap)
167 __field(u64, timestamp)
168 __field(u32, basic_rates)
169 __field(u32, changed)
170 ),
171
172 TP_fast_assign(
173 LOCAL_ASSIGN;
174 VIF_ASSIGN;
175 __entry->changed = changed;
176 __entry->aid = info->aid;
177 __entry->assoc = info->assoc;
178 __entry->shortpre = info->use_short_preamble;
179 __entry->cts = info->use_cts_prot;
180 __entry->shortslot = info->use_short_slot;
181 __entry->dtimper = info->dtim_period;
182 __entry->bcnint = info->beacon_int;
183 __entry->assoc_cap = info->assoc_capability;
184 __entry->timestamp = info->timestamp;
185 __entry->basic_rates = info->basic_rates;
186 ),
187
188 TP_printk(
189 LOCAL_PR_FMT VIF_PR_FMT " changed:%#x",
190 LOCAL_PR_ARG, VIF_PR_ARG, __entry->changed
191 )
192);
193
194TRACE_EVENT(drv_configure_filter,
195 TP_PROTO(struct ieee80211_local *local,
196 unsigned int changed_flags,
197 unsigned int *total_flags,
198 int mc_count),
199
200 TP_ARGS(local, changed_flags, total_flags, mc_count),
201
202 TP_STRUCT__entry(
203 LOCAL_ENTRY
204 __field(unsigned int, changed)
205 __field(unsigned int, total)
206 __field(int, mc)
207 ),
208
209 TP_fast_assign(
210 LOCAL_ASSIGN;
211 __entry->changed = changed_flags;
212 __entry->total = *total_flags;
213 __entry->mc = mc_count;
214 ),
215
216 TP_printk(
217 LOCAL_PR_FMT " changed:%#x total:%#x mc:%d",
218 LOCAL_PR_ARG, __entry->changed, __entry->total, __entry->mc
219 )
220);
221
222TRACE_EVENT(drv_set_tim,
223 TP_PROTO(struct ieee80211_local *local,
224 struct ieee80211_sta *sta, bool set, int ret),
225
226 TP_ARGS(local, sta, set, ret),
227
228 TP_STRUCT__entry(
229 LOCAL_ENTRY
230 STA_ENTRY
231 __field(bool, set)
232 __field(int, ret)
233 ),
234
235 TP_fast_assign(
236 LOCAL_ASSIGN;
237 STA_ASSIGN;
238 __entry->set = set;
239 __entry->ret = ret;
240 ),
241
242 TP_printk(
243 LOCAL_PR_FMT STA_PR_FMT " set:%d ret:%d",
244 LOCAL_PR_ARG, STA_PR_FMT, __entry->set, __entry->ret
245 )
246);
247
248TRACE_EVENT(drv_set_key,
249 TP_PROTO(struct ieee80211_local *local,
250 enum set_key_cmd cmd, struct ieee80211_vif *vif,
251 struct ieee80211_sta *sta,
252 struct ieee80211_key_conf *key, int ret),
253
254 TP_ARGS(local, cmd, vif, sta, key, ret),
255
256 TP_STRUCT__entry(
257 LOCAL_ENTRY
258 VIF_ENTRY
259 STA_ENTRY
260 __field(enum ieee80211_key_alg, alg)
261 __field(u8, hw_key_idx)
262 __field(u8, flags)
263 __field(s8, keyidx)
264 __field(int, ret)
265 ),
266
267 TP_fast_assign(
268 LOCAL_ASSIGN;
269 VIF_ASSIGN;
270 STA_ASSIGN;
271 __entry->alg = key->alg;
272 __entry->flags = key->flags;
273 __entry->keyidx = key->keyidx;
274 __entry->hw_key_idx = key->hw_key_idx;
275 __entry->ret = ret;
276 ),
277
278 TP_printk(
279 LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " ret:%d",
280 LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->ret
281 )
282);
283
284TRACE_EVENT(drv_update_tkip_key,
285 TP_PROTO(struct ieee80211_local *local,
286 struct ieee80211_key_conf *conf,
287 const u8 *address, u32 iv32),
288
289 TP_ARGS(local, conf, address, iv32),
290
291 TP_STRUCT__entry(
292 LOCAL_ENTRY
293 __array(u8, addr, 6)
294 __field(u32, iv32)
295 ),
296
297 TP_fast_assign(
298 LOCAL_ASSIGN;
299 memcpy(__entry->addr, address, 6);
300 __entry->iv32 = iv32;
301 ),
302
303 TP_printk(
304 LOCAL_PR_FMT " addr:%pM iv32:%#x",
305 LOCAL_PR_ARG, __entry->addr, __entry->iv32
306 )
307);
308
309TRACE_EVENT(drv_hw_scan,
310 TP_PROTO(struct ieee80211_local *local,
311 struct cfg80211_scan_request *req, int ret),
312
313 TP_ARGS(local, req, ret),
314
315 TP_STRUCT__entry(
316 LOCAL_ENTRY
317 __field(int, ret)
318 ),
319
320 TP_fast_assign(
321 LOCAL_ASSIGN;
322 __entry->ret = ret;
323 ),
324
325 TP_printk(
326 LOCAL_PR_FMT " ret:%d",
327 LOCAL_PR_ARG, __entry->ret
328 )
329);
330
331TRACE_EVENT(drv_sw_scan_start,
332 TP_PROTO(struct ieee80211_local *local),
333
334 TP_ARGS(local),
335
336 TP_STRUCT__entry(
337 LOCAL_ENTRY
338 ),
339
340 TP_fast_assign(
341 LOCAL_ASSIGN;
342 ),
343
344 TP_printk(
345 LOCAL_PR_FMT, LOCAL_PR_ARG
346 )
347);
348
349TRACE_EVENT(drv_sw_scan_complete,
350 TP_PROTO(struct ieee80211_local *local),
351
352 TP_ARGS(local),
353
354 TP_STRUCT__entry(
355 LOCAL_ENTRY
356 ),
357
358 TP_fast_assign(
359 LOCAL_ASSIGN;
360 ),
361
362 TP_printk(
363 LOCAL_PR_FMT, LOCAL_PR_ARG
364 )
365);
366
367TRACE_EVENT(drv_get_stats,
368 TP_PROTO(struct ieee80211_local *local,
369 struct ieee80211_low_level_stats *stats,
370 int ret),
371
372 TP_ARGS(local, stats, ret),
373
374 TP_STRUCT__entry(
375 LOCAL_ENTRY
376 __field(int, ret)
377 __field(unsigned int, ackfail)
378 __field(unsigned int, rtsfail)
379 __field(unsigned int, fcserr)
380 __field(unsigned int, rtssucc)
381 ),
382
383 TP_fast_assign(
384 LOCAL_ASSIGN;
385 __entry->ret = ret;
386 __entry->ackfail = stats->dot11ACKFailureCount;
387 __entry->rtsfail = stats->dot11RTSFailureCount;
388 __entry->fcserr = stats->dot11FCSErrorCount;
389 __entry->rtssucc = stats->dot11RTSSuccessCount;
390 ),
391
392 TP_printk(
393 LOCAL_PR_FMT " ret:%d",
394 LOCAL_PR_ARG, __entry->ret
395 )
396);
397
398TRACE_EVENT(drv_get_tkip_seq,
399 TP_PROTO(struct ieee80211_local *local,
400 u8 hw_key_idx, u32 *iv32, u16 *iv16),
401
402 TP_ARGS(local, hw_key_idx, iv32, iv16),
403
404 TP_STRUCT__entry(
405 LOCAL_ENTRY
406 __field(u8, hw_key_idx)
407 __field(u32, iv32)
408 __field(u16, iv16)
409 ),
410
411 TP_fast_assign(
412 LOCAL_ASSIGN;
413 __entry->hw_key_idx = hw_key_idx;
414 __entry->iv32 = *iv32;
415 __entry->iv16 = *iv16;
416 ),
417
418 TP_printk(
419 LOCAL_PR_FMT, LOCAL_PR_ARG
420 )
421);
422
423TRACE_EVENT(drv_set_rts_threshold,
424 TP_PROTO(struct ieee80211_local *local, u32 value, int ret),
425
426 TP_ARGS(local, value, ret),
427
428 TP_STRUCT__entry(
429 LOCAL_ENTRY
430 __field(u32, value)
431 __field(int, ret)
432 ),
433
434 TP_fast_assign(
435 LOCAL_ASSIGN;
436 __entry->ret = ret;
437 __entry->value = value;
438 ),
439
440 TP_printk(
441 LOCAL_PR_FMT " value:%d ret:%d",
442 LOCAL_PR_ARG, __entry->value, __entry->ret
443 )
444);
445
446TRACE_EVENT(drv_sta_notify,
447 TP_PROTO(struct ieee80211_local *local,
448 struct ieee80211_vif *vif,
449 enum sta_notify_cmd cmd,
450 struct ieee80211_sta *sta),
451
452 TP_ARGS(local, vif, cmd, sta),
453
454 TP_STRUCT__entry(
455 LOCAL_ENTRY
456 VIF_ENTRY
457 STA_ENTRY
458 __field(u32, cmd)
459 ),
460
461 TP_fast_assign(
462 LOCAL_ASSIGN;
463 VIF_ASSIGN;
464 STA_ASSIGN;
465 __entry->cmd = cmd;
466 ),
467
468 TP_printk(
469 LOCAL_PR_FMT VIF_PR_FMT STA_PR_FMT " cmd:%d",
470 LOCAL_PR_ARG, VIF_PR_ARG, STA_PR_ARG, __entry->cmd
471 )
472);
473
474TRACE_EVENT(drv_conf_tx,
475 TP_PROTO(struct ieee80211_local *local, u16 queue,
476 const struct ieee80211_tx_queue_params *params,
477 int ret),
478
479 TP_ARGS(local, queue, params, ret),
480
481 TP_STRUCT__entry(
482 LOCAL_ENTRY
483 __field(u16, queue)
484 __field(u16, txop)
485 __field(u16, cw_min)
486 __field(u16, cw_max)
487 __field(u8, aifs)
488 __field(int, ret)
489 ),
490
491 TP_fast_assign(
492 LOCAL_ASSIGN;
493 __entry->queue = queue;
494 __entry->ret = ret;
495 __entry->txop = params->txop;
496 __entry->cw_max = params->cw_max;
497 __entry->cw_min = params->cw_min;
498 __entry->aifs = params->aifs;
499 ),
500
501 TP_printk(
502 LOCAL_PR_FMT " queue:%d ret:%d",
503 LOCAL_PR_ARG, __entry->queue, __entry->ret
504 )
505);
506
507TRACE_EVENT(drv_get_tx_stats,
508 TP_PROTO(struct ieee80211_local *local,
509 struct ieee80211_tx_queue_stats *stats,
510 int ret),
511
512 TP_ARGS(local, stats, ret),
513
514 TP_STRUCT__entry(
515 LOCAL_ENTRY
516 __field(int, ret)
517 ),
518
519 TP_fast_assign(
520 LOCAL_ASSIGN;
521 __entry->ret = ret;
522 ),
523
524 TP_printk(
525 LOCAL_PR_FMT " ret:%d",
526 LOCAL_PR_ARG, __entry->ret
527 )
528);
529
530TRACE_EVENT(drv_get_tsf,
531 TP_PROTO(struct ieee80211_local *local, u64 ret),
532
533 TP_ARGS(local, ret),
534
535 TP_STRUCT__entry(
536 LOCAL_ENTRY
537 __field(u64, ret)
538 ),
539
540 TP_fast_assign(
541 LOCAL_ASSIGN;
542 __entry->ret = ret;
543 ),
544
545 TP_printk(
546 LOCAL_PR_FMT " ret:%llu",
547 LOCAL_PR_ARG, (unsigned long long)__entry->ret
548 )
549);
550
551TRACE_EVENT(drv_set_tsf,
552 TP_PROTO(struct ieee80211_local *local, u64 tsf),
553
554 TP_ARGS(local, tsf),
555
556 TP_STRUCT__entry(
557 LOCAL_ENTRY
558 __field(u64, tsf)
559 ),
560
561 TP_fast_assign(
562 LOCAL_ASSIGN;
563 __entry->tsf = tsf;
564 ),
565
566 TP_printk(
567 LOCAL_PR_FMT " tsf:%llu",
568 LOCAL_PR_ARG, (unsigned long long)__entry->tsf
569 )
570);
571
572TRACE_EVENT(drv_reset_tsf,
573 TP_PROTO(struct ieee80211_local *local),
574
575 TP_ARGS(local),
576
577 TP_STRUCT__entry(
578 LOCAL_ENTRY
579 ),
580
581 TP_fast_assign(
582 LOCAL_ASSIGN;
583 ),
584
585 TP_printk(
586 LOCAL_PR_FMT, LOCAL_PR_ARG
587 )
588);
589
590TRACE_EVENT(drv_tx_last_beacon,
591 TP_PROTO(struct ieee80211_local *local, int ret),
592
593 TP_ARGS(local, ret),
594
595 TP_STRUCT__entry(
596 LOCAL_ENTRY
597 __field(int, ret)
598 ),
599
600 TP_fast_assign(
601 LOCAL_ASSIGN;
602 __entry->ret = ret;
603 ),
604
605 TP_printk(
606 LOCAL_PR_FMT " ret:%d",
607 LOCAL_PR_ARG, __entry->ret
608 )
609);
610
611TRACE_EVENT(drv_ampdu_action,
612 TP_PROTO(struct ieee80211_local *local,
613 enum ieee80211_ampdu_mlme_action action,
614 struct ieee80211_sta *sta, u16 tid,
615 u16 *ssn, int ret),
616
617 TP_ARGS(local, action, sta, tid, ssn, ret),
618
619 TP_STRUCT__entry(
620 LOCAL_ENTRY
621 STA_ENTRY
622 __field(u32, action)
623 __field(u16, tid)
624 __field(u16, ssn)
625 __field(int, ret)
626 ),
627
628 TP_fast_assign(
629 LOCAL_ASSIGN;
630 STA_ASSIGN;
631 __entry->ret = ret;
632 __entry->action = action;
633 __entry->tid = tid;
634 __entry->ssn = *ssn;
635 ),
636
637 TP_printk(
638 LOCAL_PR_FMT STA_PR_FMT " action:%d tid:%d ret:%d",
639 LOCAL_PR_ARG, STA_PR_ARG, __entry->action, __entry->tid, __entry->ret
640 )
641);
642#endif /* !__MAC80211_DRIVER_TRACE || TRACE_HEADER_MULTI_READ */
643
644#undef TRACE_INCLUDE_PATH
645#define TRACE_INCLUDE_PATH .
646#undef TRACE_INCLUDE_FILE
647#define TRACE_INCLUDE_FILE driver-trace
648#include <trace/define_trace.h>
diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index 15d5a53b59a8..8e2220000e5c 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -57,7 +57,7 @@ static void ieee80211_rx_mgmt_auth_ibss(struct ieee80211_sub_if_data *sdata,
57 */ 57 */
58 if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1) 58 if (auth_alg == WLAN_AUTH_OPEN && auth_transaction == 1)
59 ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0, 59 ieee80211_send_auth(sdata, 2, WLAN_AUTH_OPEN, NULL, 0,
60 sdata->u.ibss.bssid, 0); 60 sdata->u.ibss.bssid, NULL, 0, 0);
61} 61}
62 62
63static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata, 63static void __ieee80211_sta_join_ibss(struct ieee80211_sub_if_data *sdata,
@@ -494,7 +494,7 @@ static void ieee80211_sta_create_ibss(struct ieee80211_sub_if_data *sdata)
494 494
495 capability = WLAN_CAPABILITY_IBSS; 495 capability = WLAN_CAPABILITY_IBSS;
496 496
497 if (sdata->default_key) 497 if (ifibss->privacy)
498 capability |= WLAN_CAPABILITY_PRIVACY; 498 capability |= WLAN_CAPABILITY_PRIVACY;
499 else 499 else
500 sdata->drop_unencrypted = 0; 500 sdata->drop_unencrypted = 0;
@@ -524,9 +524,8 @@ static void ieee80211_sta_find_ibss(struct ieee80211_sub_if_data *sdata)
524 return; 524 return;
525 525
526 capability = WLAN_CAPABILITY_IBSS; 526 capability = WLAN_CAPABILITY_IBSS;
527 if (sdata->default_key) 527 if (ifibss->privacy)
528 capability |= WLAN_CAPABILITY_PRIVACY; 528 capability |= WLAN_CAPABILITY_PRIVACY;
529
530 if (ifibss->fixed_bssid) 529 if (ifibss->fixed_bssid)
531 bssid = ifibss->bssid; 530 bssid = ifibss->bssid;
532 if (ifibss->fixed_channel) 531 if (ifibss->fixed_channel)
@@ -872,6 +871,8 @@ int ieee80211_ibss_join(struct ieee80211_sub_if_data *sdata,
872 } else 871 } else
873 sdata->u.ibss.fixed_bssid = false; 872 sdata->u.ibss.fixed_bssid = false;
874 873
874 sdata->u.ibss.privacy = params->privacy;
875
875 sdata->vif.bss_conf.beacon_int = params->beacon_interval; 876 sdata->vif.bss_conf.beacon_int = params->beacon_interval;
876 877
877 sdata->u.ibss.channel = params->channel; 878 sdata->u.ibss.channel = params->channel;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 327aabc07abe..6a0177137dd5 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -247,18 +247,22 @@ struct ieee80211_mgd_work {
247 247
248 int tries; 248 int tries;
249 249
250 u8 key[WLAN_KEY_LEN_WEP104];
251 u8 key_len, key_idx;
252
250 /* must be last */ 253 /* must be last */
251 u8 ie[0]; /* for auth or assoc frame, not probe */ 254 u8 ie[0]; /* for auth or assoc frame, not probe */
252}; 255};
253 256
254/* flags used in struct ieee80211_if_managed.flags */ 257/* flags used in struct ieee80211_if_managed.flags */
255enum ieee80211_sta_flags { 258enum ieee80211_sta_flags {
256 IEEE80211_STA_PROBEREQ_POLL = BIT(3), 259 IEEE80211_STA_BEACON_POLL = BIT(0),
257 IEEE80211_STA_CONTROL_PORT = BIT(4), 260 IEEE80211_STA_CONNECTION_POLL = BIT(1),
258 IEEE80211_STA_WMM_ENABLED = BIT(5), 261 IEEE80211_STA_CONTROL_PORT = BIT(2),
259 IEEE80211_STA_DISABLE_11N = BIT(6), 262 IEEE80211_STA_WMM_ENABLED = BIT(3),
260 IEEE80211_STA_CSA_RECEIVED = BIT(7), 263 IEEE80211_STA_DISABLE_11N = BIT(4),
261 IEEE80211_STA_MFP_ENABLED = BIT(8), 264 IEEE80211_STA_CSA_RECEIVED = BIT(5),
265 IEEE80211_STA_MFP_ENABLED = BIT(6),
262}; 266};
263 267
264/* flags for MLME request */ 268/* flags for MLME request */
@@ -268,11 +272,16 @@ enum ieee80211_sta_request {
268 272
269struct ieee80211_if_managed { 273struct ieee80211_if_managed {
270 struct timer_list timer; 274 struct timer_list timer;
275 struct timer_list conn_mon_timer;
276 struct timer_list bcn_mon_timer;
271 struct timer_list chswitch_timer; 277 struct timer_list chswitch_timer;
272 struct work_struct work; 278 struct work_struct work;
279 struct work_struct monitor_work;
273 struct work_struct chswitch_work; 280 struct work_struct chswitch_work;
274 struct work_struct beacon_loss_work; 281 struct work_struct beacon_loss_work;
275 282
283 unsigned long probe_timeout;
284
276 struct mutex mtx; 285 struct mutex mtx;
277 struct ieee80211_bss *associated; 286 struct ieee80211_bss *associated;
278 struct list_head work_list; 287 struct list_head work_list;
@@ -289,8 +298,6 @@ struct ieee80211_if_managed {
289 298
290 unsigned long request; 299 unsigned long request;
291 300
292 unsigned long last_beacon;
293
294 unsigned int flags; 301 unsigned int flags;
295 302
296 u32 beacon_crc; 303 u32 beacon_crc;
@@ -321,6 +328,7 @@ struct ieee80211_if_ibss {
321 328
322 bool fixed_bssid; 329 bool fixed_bssid;
323 bool fixed_channel; 330 bool fixed_channel;
331 bool privacy;
324 332
325 u8 bssid[ETH_ALEN]; 333 u8 bssid[ETH_ALEN];
326 u8 ssid[IEEE80211_MAX_SSID_LEN]; 334 u8 ssid[IEEE80211_MAX_SSID_LEN];
@@ -559,14 +567,9 @@ enum queue_stop_reason {
559 IEEE80211_QUEUE_STOP_REASON_CSA, 567 IEEE80211_QUEUE_STOP_REASON_CSA,
560 IEEE80211_QUEUE_STOP_REASON_AGGREGATION, 568 IEEE80211_QUEUE_STOP_REASON_AGGREGATION,
561 IEEE80211_QUEUE_STOP_REASON_SUSPEND, 569 IEEE80211_QUEUE_STOP_REASON_SUSPEND,
562 IEEE80211_QUEUE_STOP_REASON_PENDING,
563 IEEE80211_QUEUE_STOP_REASON_SKB_ADD, 570 IEEE80211_QUEUE_STOP_REASON_SKB_ADD,
564}; 571};
565 572
566struct ieee80211_master_priv {
567 struct ieee80211_local *local;
568};
569
570struct ieee80211_local { 573struct ieee80211_local {
571 /* embed the driver visible part. 574 /* embed the driver visible part.
572 * don't cast (use the static inlines below), but we keep 575 * don't cast (use the static inlines below), but we keep
@@ -579,13 +582,20 @@ struct ieee80211_local {
579 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */ 582 /* also used to protect ampdu_ac_queue and amdpu_ac_stop_refcnt */
580 spinlock_t queue_stop_reason_lock; 583 spinlock_t queue_stop_reason_lock;
581 584
582 struct net_device *mdev; /* wmaster# - "master" 802.11 device */
583 int open_count; 585 int open_count;
584 int monitors, cooked_mntrs; 586 int monitors, cooked_mntrs;
585 /* number of interfaces with corresponding FIF_ flags */ 587 /* number of interfaces with corresponding FIF_ flags */
586 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss; 588 int fif_fcsfail, fif_plcpfail, fif_control, fif_other_bss;
587 unsigned int filter_flags; /* FIF_* */ 589 unsigned int filter_flags; /* FIF_* */
588 struct iw_statistics wstats; 590 struct iw_statistics wstats;
591
592 /* protects the aggregated multicast list and filter calls */
593 spinlock_t filter_lock;
594
595 /* aggregated multicast list */
596 struct dev_addr_list *mc_list;
597 int mc_count;
598
589 bool tim_in_locked_section; /* see ieee80211_beacon_get() */ 599 bool tim_in_locked_section; /* see ieee80211_beacon_get() */
590 600
591 /* 601 /*
@@ -805,10 +815,6 @@ struct ieee80211_local {
805static inline struct ieee80211_sub_if_data * 815static inline struct ieee80211_sub_if_data *
806IEEE80211_DEV_TO_SUB_IF(struct net_device *dev) 816IEEE80211_DEV_TO_SUB_IF(struct net_device *dev)
807{ 817{
808 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
809
810 BUG_ON(!local || local->mdev == dev);
811
812 return netdev_priv(dev); 818 return netdev_priv(dev);
813} 819}
814 820
@@ -988,7 +994,6 @@ void ieee80211_recalc_idle(struct ieee80211_local *local);
988/* tx handling */ 994/* tx handling */
989void ieee80211_clear_tx_pending(struct ieee80211_local *local); 995void ieee80211_clear_tx_pending(struct ieee80211_local *local);
990void ieee80211_tx_pending(unsigned long data); 996void ieee80211_tx_pending(unsigned long data);
991int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev);
992int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev); 997int ieee80211_monitor_start_xmit(struct sk_buff *skb, struct net_device *dev);
993int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev); 998int ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev);
994 999
@@ -1093,8 +1098,8 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
1093 1098
1094void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 1099void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
1095 u16 transaction, u16 auth_alg, 1100 u16 transaction, u16 auth_alg,
1096 u8 *extra, size_t extra_len, 1101 u8 *extra, size_t extra_len, const u8 *bssid,
1097 const u8 *bssid, int encrypt); 1102 const u8 *key, u8 key_len, u8 key_idx);
1098int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 1103int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
1099 const u8 *ie, size_t ie_len); 1104 const u8 *ie, size_t ie_len);
1100void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst, 1105void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 4839a2d97a3b..2f797a86ced5 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -190,10 +190,6 @@ static int ieee80211_open(struct net_device *dev)
190 ETH_ALEN); 190 ETH_ALEN);
191 } 191 }
192 192
193 if (compare_ether_addr(null_addr, local->mdev->dev_addr) == 0)
194 memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr,
195 ETH_ALEN);
196
197 /* 193 /*
198 * Validate the MAC address for this device. 194 * Validate the MAC address for this device.
199 */ 195 */
@@ -229,9 +225,9 @@ static int ieee80211_open(struct net_device *dev)
229 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) 225 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
230 local->fif_other_bss++; 226 local->fif_other_bss++;
231 227
232 netif_addr_lock_bh(local->mdev); 228 spin_lock_bh(&local->filter_lock);
233 ieee80211_configure_filter(local); 229 ieee80211_configure_filter(local);
234 netif_addr_unlock_bh(local->mdev); 230 spin_unlock_bh(&local->filter_lock);
235 break; 231 break;
236 default: 232 default:
237 conf.vif = &sdata->vif; 233 conf.vif = &sdata->vif;
@@ -243,9 +239,9 @@ static int ieee80211_open(struct net_device *dev)
243 239
244 if (ieee80211_vif_is_mesh(&sdata->vif)) { 240 if (ieee80211_vif_is_mesh(&sdata->vif)) {
245 local->fif_other_bss++; 241 local->fif_other_bss++;
246 netif_addr_lock_bh(local->mdev); 242 spin_lock_bh(&local->filter_lock);
247 ieee80211_configure_filter(local); 243 ieee80211_configure_filter(local);
248 netif_addr_unlock_bh(local->mdev); 244 spin_unlock_bh(&local->filter_lock);
249 245
250 ieee80211_start_mesh(sdata); 246 ieee80211_start_mesh(sdata);
251 } 247 }
@@ -279,10 +275,6 @@ static int ieee80211_open(struct net_device *dev)
279 } 275 }
280 276
281 if (local->open_count == 0) { 277 if (local->open_count == 0) {
282 res = dev_open(local->mdev);
283 WARN_ON(res);
284 if (res)
285 goto err_del_interface;
286 tasklet_enable(&local->tx_pending_tasklet); 278 tasklet_enable(&local->tx_pending_tasklet);
287 tasklet_enable(&local->tasklet); 279 tasklet_enable(&local->tasklet);
288 } 280 }
@@ -393,7 +385,14 @@ static int ieee80211_stop(struct net_device *dev)
393 if (sdata->flags & IEEE80211_SDATA_PROMISC) 385 if (sdata->flags & IEEE80211_SDATA_PROMISC)
394 atomic_dec(&local->iff_promiscs); 386 atomic_dec(&local->iff_promiscs);
395 387
396 dev_mc_unsync(local->mdev, dev); 388 netif_addr_lock_bh(dev);
389 spin_lock_bh(&local->filter_lock);
390 __dev_addr_unsync(&local->mc_list, &local->mc_count,
391 &dev->mc_list, &dev->mc_count);
392 ieee80211_configure_filter(local);
393 spin_unlock_bh(&local->filter_lock);
394 netif_addr_unlock_bh(dev);
395
397 del_timer_sync(&local->dynamic_ps_timer); 396 del_timer_sync(&local->dynamic_ps_timer);
398 cancel_work_sync(&local->dynamic_ps_enable_work); 397 cancel_work_sync(&local->dynamic_ps_enable_work);
399 398
@@ -442,23 +441,25 @@ static int ieee80211_stop(struct net_device *dev)
442 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS) 441 if (sdata->u.mntr_flags & MONITOR_FLAG_OTHER_BSS)
443 local->fif_other_bss--; 442 local->fif_other_bss--;
444 443
445 netif_addr_lock_bh(local->mdev); 444 spin_lock_bh(&local->filter_lock);
446 ieee80211_configure_filter(local); 445 ieee80211_configure_filter(local);
447 netif_addr_unlock_bh(local->mdev); 446 spin_unlock_bh(&local->filter_lock);
448 break; 447 break;
449 case NL80211_IFTYPE_STATION: 448 case NL80211_IFTYPE_STATION:
450 del_timer_sync(&sdata->u.mgd.chswitch_timer); 449 del_timer_sync(&sdata->u.mgd.chswitch_timer);
451 del_timer_sync(&sdata->u.mgd.timer); 450 del_timer_sync(&sdata->u.mgd.timer);
451 del_timer_sync(&sdata->u.mgd.conn_mon_timer);
452 del_timer_sync(&sdata->u.mgd.bcn_mon_timer);
452 /* 453 /*
453 * If the timer fired while we waited for it, it will have 454 * If any of the timers fired while we waited for it, it will
454 * requeued the work. Now the work will be running again 455 * have queued its work. Now the work will be running again
455 * but will not rearm the timer again because it checks 456 * but will not rearm the timer again because it checks
456 * whether the interface is running, which, at this point, 457 * whether the interface is running, which, at this point,
457 * it no longer is. 458 * it no longer is.
458 */ 459 */
459 cancel_work_sync(&sdata->u.mgd.work); 460 cancel_work_sync(&sdata->u.mgd.work);
460 cancel_work_sync(&sdata->u.mgd.chswitch_work); 461 cancel_work_sync(&sdata->u.mgd.chswitch_work);
461 462 cancel_work_sync(&sdata->u.mgd.monitor_work);
462 cancel_work_sync(&sdata->u.mgd.beacon_loss_work); 463 cancel_work_sync(&sdata->u.mgd.beacon_loss_work);
463 464
464 /* 465 /*
@@ -485,9 +486,9 @@ static int ieee80211_stop(struct net_device *dev)
485 local->fif_other_bss--; 486 local->fif_other_bss--;
486 atomic_dec(&local->iff_allmultis); 487 atomic_dec(&local->iff_allmultis);
487 488
488 netif_addr_lock_bh(local->mdev); 489 spin_lock_bh(&local->filter_lock);
489 ieee80211_configure_filter(local); 490 ieee80211_configure_filter(local);
490 netif_addr_unlock_bh(local->mdev); 491 spin_unlock_bh(&local->filter_lock);
491 492
492 ieee80211_stop_mesh(sdata); 493 ieee80211_stop_mesh(sdata);
493 } 494 }
@@ -533,9 +534,6 @@ static int ieee80211_stop(struct net_device *dev)
533 ieee80211_recalc_ps(local, -1); 534 ieee80211_recalc_ps(local, -1);
534 535
535 if (local->open_count == 0) { 536 if (local->open_count == 0) {
536 if (netif_running(local->mdev))
537 dev_close(local->mdev);
538
539 drv_stop(local); 537 drv_stop(local);
540 538
541 ieee80211_led_radio(local, false); 539 ieee80211_led_radio(local, false);
@@ -582,8 +580,11 @@ static void ieee80211_set_multicast_list(struct net_device *dev)
582 atomic_dec(&local->iff_promiscs); 580 atomic_dec(&local->iff_promiscs);
583 sdata->flags ^= IEEE80211_SDATA_PROMISC; 581 sdata->flags ^= IEEE80211_SDATA_PROMISC;
584 } 582 }
585 583 spin_lock_bh(&local->filter_lock);
586 dev_mc_sync(local->mdev, dev); 584 __dev_addr_sync(&local->mc_list, &local->mc_count,
585 &dev->mc_list, &dev->mc_count);
586 ieee80211_configure_filter(local);
587 spin_unlock_bh(&local->filter_lock);
587} 588}
588 589
589/* 590/*
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 5b69f5f07299..3234f3751d22 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -83,75 +83,14 @@ void ieee80211_configure_filter(struct ieee80211_local *local)
83 new_flags |= (1<<31); 83 new_flags |= (1<<31);
84 84
85 drv_configure_filter(local, changed_flags, &new_flags, 85 drv_configure_filter(local, changed_flags, &new_flags,
86 local->mdev->mc_count, 86 local->mc_count,
87 local->mdev->mc_list); 87 local->mc_list);
88 88
89 WARN_ON(new_flags & (1<<31)); 89 WARN_ON(new_flags & (1<<31));
90 90
91 local->filter_flags = new_flags & ~(1<<31); 91 local->filter_flags = new_flags & ~(1<<31);
92} 92}
93 93
94/* master interface */
95
96static int header_parse_80211(const struct sk_buff *skb, unsigned char *haddr)
97{
98 memcpy(haddr, skb_mac_header(skb) + 10, ETH_ALEN); /* addr2 */
99 return ETH_ALEN;
100}
101
102static const struct header_ops ieee80211_header_ops = {
103 .create = eth_header,
104 .parse = header_parse_80211,
105 .rebuild = eth_rebuild_header,
106 .cache = eth_header_cache,
107 .cache_update = eth_header_cache_update,
108};
109
110static int ieee80211_master_open(struct net_device *dev)
111{
112 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
113 struct ieee80211_local *local = mpriv->local;
114 struct ieee80211_sub_if_data *sdata;
115 int res = -EOPNOTSUPP;
116
117 /* we hold the RTNL here so can safely walk the list */
118 list_for_each_entry(sdata, &local->interfaces, list) {
119 if (netif_running(sdata->dev)) {
120 res = 0;
121 break;
122 }
123 }
124
125 if (res)
126 return res;
127
128 netif_tx_start_all_queues(local->mdev);
129
130 return 0;
131}
132
133static int ieee80211_master_stop(struct net_device *dev)
134{
135 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
136 struct ieee80211_local *local = mpriv->local;
137 struct ieee80211_sub_if_data *sdata;
138
139 /* we hold the RTNL here so can safely walk the list */
140 list_for_each_entry(sdata, &local->interfaces, list)
141 if (netif_running(sdata->dev))
142 dev_close(sdata->dev);
143
144 return 0;
145}
146
147static void ieee80211_master_set_multicast_list(struct net_device *dev)
148{
149 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
150 struct ieee80211_local *local = mpriv->local;
151
152 ieee80211_configure_filter(local);
153}
154
155int ieee80211_hw_config(struct ieee80211_local *local, u32 changed) 94int ieee80211_hw_config(struct ieee80211_local *local, u32 changed)
156{ 95{
157 struct ieee80211_channel *chan, *scan_chan; 96 struct ieee80211_channel *chan, *scan_chan;
@@ -310,7 +249,6 @@ void ieee80211_tx_status_irqsafe(struct ieee80211_hw *hw,
310 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 249 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
311 int tmp; 250 int tmp;
312 251
313 skb->dev = local->mdev;
314 skb->pkt_type = IEEE80211_TX_STATUS_MSG; 252 skb->pkt_type = IEEE80211_TX_STATUS_MSG;
315 skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ? 253 skb_queue_tail(info->flags & IEEE80211_TX_CTL_REQ_TX_STATUS ?
316 &local->skb_queue : &local->skb_queue_unreliable, skb); 254 &local->skb_queue : &local->skb_queue_unreliable, skb);
@@ -716,7 +654,7 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
716 mutex_init(&local->scan_mtx); 654 mutex_init(&local->scan_mtx);
717 655
718 spin_lock_init(&local->key_lock); 656 spin_lock_init(&local->key_lock);
719 657 spin_lock_init(&local->filter_lock);
720 spin_lock_init(&local->queue_stop_reason_lock); 658 spin_lock_init(&local->queue_stop_reason_lock);
721 659
722 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work); 660 INIT_DELAYED_WORK(&local->scan_work, ieee80211_scan_work);
@@ -752,30 +690,11 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
752} 690}
753EXPORT_SYMBOL(ieee80211_alloc_hw); 691EXPORT_SYMBOL(ieee80211_alloc_hw);
754 692
755static const struct net_device_ops ieee80211_master_ops = {
756 .ndo_start_xmit = ieee80211_master_start_xmit,
757 .ndo_open = ieee80211_master_open,
758 .ndo_stop = ieee80211_master_stop,
759 .ndo_set_multicast_list = ieee80211_master_set_multicast_list,
760 .ndo_select_queue = ieee80211_select_queue,
761};
762
763static void ieee80211_master_setup(struct net_device *mdev)
764{
765 mdev->type = ARPHRD_IEEE80211;
766 mdev->netdev_ops = &ieee80211_master_ops;
767 mdev->header_ops = &ieee80211_header_ops;
768 mdev->tx_queue_len = 1000;
769 mdev->addr_len = ETH_ALEN;
770}
771
772int ieee80211_register_hw(struct ieee80211_hw *hw) 693int ieee80211_register_hw(struct ieee80211_hw *hw)
773{ 694{
774 struct ieee80211_local *local = hw_to_local(hw); 695 struct ieee80211_local *local = hw_to_local(hw);
775 int result; 696 int result;
776 enum ieee80211_band band; 697 enum ieee80211_band band;
777 struct net_device *mdev;
778 struct ieee80211_master_priv *mpriv;
779 int channels, i, j, max_bitrates; 698 int channels, i, j, max_bitrates;
780 bool supp_ht; 699 bool supp_ht;
781 static const u32 cipher_suites[] = { 700 static const u32 cipher_suites[] = {
@@ -874,16 +793,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
874 if (hw->queues > IEEE80211_MAX_QUEUES) 793 if (hw->queues > IEEE80211_MAX_QUEUES)
875 hw->queues = IEEE80211_MAX_QUEUES; 794 hw->queues = IEEE80211_MAX_QUEUES;
876 795
877 mdev = alloc_netdev_mq(sizeof(struct ieee80211_master_priv),
878 "wmaster%d", ieee80211_master_setup,
879 hw->queues);
880 if (!mdev)
881 goto fail_mdev_alloc;
882
883 mpriv = netdev_priv(mdev);
884 mpriv->local = local;
885 local->mdev = mdev;
886
887 local->hw.workqueue = 796 local->hw.workqueue =
888 create_singlethread_workqueue(wiphy_name(local->hw.wiphy)); 797 create_singlethread_workqueue(wiphy_name(local->hw.wiphy));
889 if (!local->hw.workqueue) { 798 if (!local->hw.workqueue) {
@@ -918,17 +827,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
918 } 827 }
919 828
920 rtnl_lock(); 829 rtnl_lock();
921 result = dev_alloc_name(local->mdev, local->mdev->name);
922 if (result < 0)
923 goto fail_dev;
924
925 memcpy(local->mdev->dev_addr, local->hw.wiphy->perm_addr, ETH_ALEN);
926 SET_NETDEV_DEV(local->mdev, wiphy_dev(local->hw.wiphy));
927 local->mdev->features |= NETIF_F_NETNS_LOCAL;
928
929 result = register_netdevice(local->mdev);
930 if (result < 0)
931 goto fail_dev;
932 830
933 result = ieee80211_init_rate_ctrl_alg(local, 831 result = ieee80211_init_rate_ctrl_alg(local,
934 hw->rate_control_algorithm); 832 hw->rate_control_algorithm);
@@ -981,9 +879,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
981 ieee80211_led_exit(local); 879 ieee80211_led_exit(local);
982 ieee80211_remove_interfaces(local); 880 ieee80211_remove_interfaces(local);
983 fail_rate: 881 fail_rate:
984 unregister_netdevice(local->mdev);
985 local->mdev = NULL;
986 fail_dev:
987 rtnl_unlock(); 882 rtnl_unlock();
988 ieee80211_wep_free(local); 883 ieee80211_wep_free(local);
989 fail_wep: 884 fail_wep:
@@ -992,9 +887,6 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
992 debugfs_hw_del(local); 887 debugfs_hw_del(local);
993 destroy_workqueue(local->hw.workqueue); 888 destroy_workqueue(local->hw.workqueue);
994 fail_workqueue: 889 fail_workqueue:
995 if (local->mdev)
996 free_netdev(local->mdev);
997 fail_mdev_alloc:
998 wiphy_unregister(local->hw.wiphy); 890 wiphy_unregister(local->hw.wiphy);
999 fail_wiphy_register: 891 fail_wiphy_register:
1000 kfree(local->int_scan_req.channels); 892 kfree(local->int_scan_req.channels);
@@ -1019,13 +911,8 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1019 * because the driver cannot be handing us frames any 911 * because the driver cannot be handing us frames any
1020 * more and the tasklet is killed. 912 * more and the tasklet is killed.
1021 */ 913 */
1022
1023 /* First, we remove all virtual interfaces. */
1024 ieee80211_remove_interfaces(local); 914 ieee80211_remove_interfaces(local);
1025 915
1026 /* then, finally, remove the master interface */
1027 unregister_netdevice(local->mdev);
1028
1029 rtnl_unlock(); 916 rtnl_unlock();
1030 917
1031 ieee80211_clear_tx_pending(local); 918 ieee80211_clear_tx_pending(local);
@@ -1044,7 +931,6 @@ void ieee80211_unregister_hw(struct ieee80211_hw *hw)
1044 wiphy_unregister(local->hw.wiphy); 931 wiphy_unregister(local->hw.wiphy);
1045 ieee80211_wep_free(local); 932 ieee80211_wep_free(local);
1046 ieee80211_led_exit(local); 933 ieee80211_led_exit(local);
1047 free_netdev(local->mdev);
1048 kfree(local->int_scan_req.channels); 934 kfree(local->int_scan_req.channels);
1049} 935}
1050EXPORT_SYMBOL(ieee80211_unregister_hw); 936EXPORT_SYMBOL(ieee80211_unregister_hw);
diff --git a/net/mac80211/mesh.c b/net/mac80211/mesh.c
index 542ea025494e..8a97b1423088 100644
--- a/net/mac80211/mesh.c
+++ b/net/mac80211/mesh.c
@@ -685,9 +685,12 @@ ieee80211_mesh_rx_mgmt(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
685 fc = le16_to_cpu(mgmt->frame_control); 685 fc = le16_to_cpu(mgmt->frame_control);
686 686
687 switch (fc & IEEE80211_FCTL_STYPE) { 687 switch (fc & IEEE80211_FCTL_STYPE) {
688 case IEEE80211_STYPE_ACTION:
689 if (skb->len < IEEE80211_MIN_ACTION_SIZE)
690 return RX_DROP_MONITOR;
691 /* fall through */
688 case IEEE80211_STYPE_PROBE_RESP: 692 case IEEE80211_STYPE_PROBE_RESP:
689 case IEEE80211_STYPE_BEACON: 693 case IEEE80211_STYPE_BEACON:
690 case IEEE80211_STYPE_ACTION:
691 skb_queue_tail(&ifmsh->skb_queue, skb); 694 skb_queue_tail(&ifmsh->skb_queue, skb);
692 queue_work(local->hw.workqueue, &ifmsh->work); 695 queue_work(local->hw.workqueue, &ifmsh->work);
693 return RX_QUEUED; 696 return RX_QUEUED;
diff --git a/net/mac80211/mesh_hwmp.c b/net/mac80211/mesh_hwmp.c
index f49ef288e2e2..e93c37ef6a48 100644
--- a/net/mac80211/mesh_hwmp.c
+++ b/net/mac80211/mesh_hwmp.c
@@ -686,11 +686,11 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
686 u8 ttl, dst_flags; 686 u8 ttl, dst_flags;
687 u32 lifetime; 687 u32 lifetime;
688 688
689 spin_lock(&ifmsh->mesh_preq_queue_lock); 689 spin_lock_bh(&ifmsh->mesh_preq_queue_lock);
690 if (!ifmsh->preq_queue_len || 690 if (!ifmsh->preq_queue_len ||
691 time_before(jiffies, ifmsh->last_preq + 691 time_before(jiffies, ifmsh->last_preq +
692 min_preq_int_jiff(sdata))) { 692 min_preq_int_jiff(sdata))) {
693 spin_unlock(&ifmsh->mesh_preq_queue_lock); 693 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
694 return; 694 return;
695 } 695 }
696 696
@@ -698,7 +698,7 @@ void mesh_path_start_discovery(struct ieee80211_sub_if_data *sdata)
698 struct mesh_preq_queue, list); 698 struct mesh_preq_queue, list);
699 list_del(&preq_node->list); 699 list_del(&preq_node->list);
700 --ifmsh->preq_queue_len; 700 --ifmsh->preq_queue_len;
701 spin_unlock(&ifmsh->mesh_preq_queue_lock); 701 spin_unlock_bh(&ifmsh->mesh_preq_queue_lock);
702 702
703 rcu_read_lock(); 703 rcu_read_lock();
704 mpath = mesh_path_lookup(preq_node->dst, sdata); 704 mpath = mesh_path_lookup(preq_node->dst, sdata);
@@ -784,7 +784,6 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
784 mesh_path_add(dst_addr, sdata); 784 mesh_path_add(dst_addr, sdata);
785 mpath = mesh_path_lookup(dst_addr, sdata); 785 mpath = mesh_path_lookup(dst_addr, sdata);
786 if (!mpath) { 786 if (!mpath) {
787 dev_kfree_skb(skb);
788 sdata->u.mesh.mshstats.dropped_frames_no_route++; 787 sdata->u.mesh.mshstats.dropped_frames_no_route++;
789 err = -ENOSPC; 788 err = -ENOSPC;
790 goto endlookup; 789 goto endlookup;
@@ -804,6 +803,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
804 memcpy(hdr->addr1, mpath->next_hop->sta.addr, 803 memcpy(hdr->addr1, mpath->next_hop->sta.addr,
805 ETH_ALEN); 804 ETH_ALEN);
806 } else { 805 } else {
806 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
807 if (!(mpath->flags & MESH_PATH_RESOLVING)) { 807 if (!(mpath->flags & MESH_PATH_RESOLVING)) {
808 /* Start discovery only if it is not running yet */ 808 /* Start discovery only if it is not running yet */
809 mesh_queue_preq(mpath, PREQ_Q_F_START); 809 mesh_queue_preq(mpath, PREQ_Q_F_START);
@@ -815,6 +815,7 @@ int mesh_nexthop_lookup(struct sk_buff *skb,
815 skb_unlink(skb_to_free, &mpath->frame_queue); 815 skb_unlink(skb_to_free, &mpath->frame_queue);
816 } 816 }
817 817
818 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
818 skb_queue_tail(&mpath->frame_queue, skb); 819 skb_queue_tail(&mpath->frame_queue, skb);
819 if (skb_to_free) 820 if (skb_to_free)
820 mesh_path_discard_frame(skb_to_free, sdata); 821 mesh_path_discard_frame(skb_to_free, sdata);
diff --git a/net/mac80211/mesh_pathtbl.c b/net/mac80211/mesh_pathtbl.c
index 479597e88583..04b9e4d61b8e 100644
--- a/net/mac80211/mesh_pathtbl.c
+++ b/net/mac80211/mesh_pathtbl.c
@@ -55,7 +55,25 @@ static DEFINE_RWLOCK(pathtbl_resize_lock);
55 */ 55 */
56void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta) 56void mesh_path_assign_nexthop(struct mesh_path *mpath, struct sta_info *sta)
57{ 57{
58 struct sk_buff *skb;
59 struct ieee80211_hdr *hdr;
60 struct sk_buff_head tmpq;
61 unsigned long flags;
62
58 rcu_assign_pointer(mpath->next_hop, sta); 63 rcu_assign_pointer(mpath->next_hop, sta);
64
65 __skb_queue_head_init(&tmpq);
66
67 spin_lock_irqsave(&mpath->frame_queue.lock, flags);
68
69 while ((skb = __skb_dequeue(&mpath->frame_queue)) != NULL) {
70 hdr = (struct ieee80211_hdr *) skb->data;
71 memcpy(hdr->addr1, sta->sta.addr, ETH_ALEN);
72 __skb_queue_tail(&tmpq, skb);
73 }
74
75 skb_queue_splice(&tmpq, &mpath->frame_queue);
76 spin_unlock_irqrestore(&mpath->frame_queue.lock, flags);
59} 77}
60 78
61 79
@@ -481,11 +499,9 @@ enddel:
481 */ 499 */
482void mesh_path_tx_pending(struct mesh_path *mpath) 500void mesh_path_tx_pending(struct mesh_path *mpath)
483{ 501{
484 struct sk_buff *skb; 502 if (mpath->flags & MESH_PATH_ACTIVE)
485 503 ieee80211_add_pending_skbs(mpath->sdata->local,
486 while ((skb = skb_dequeue(&mpath->frame_queue)) && 504 &mpath->frame_queue);
487 (mpath->flags & MESH_PATH_ACTIVE))
488 dev_queue_xmit(skb);
489} 505}
490 506
491/** 507/**
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index c9db9646025b..523c0d994d15 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -31,8 +31,23 @@
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_MONITORING_INTERVAL (2 * HZ) 34
35#define IEEE80211_PROBE_WAIT (HZ / 5) 35/*
36 * beacon loss detection timeout
37 * XXX: should depend on beacon interval
38 */
39#define IEEE80211_BEACON_LOSS_TIME (2 * HZ)
40/*
41 * Time the connection can be idle before we probe
42 * it to see if we can still talk to the AP.
43 */
44#define IEEE80211_CONNECTION_IDLE_TIME (2 * HZ)
45/*
46 * Time we wait for a probe response after sending
47 * a probe request because of beacon loss or for
48 * checking the connection still works.
49 */
50#define IEEE80211_PROBE_WAIT (HZ / 5)
36 51
37#define TMR_RUNNING_TIMER 0 52#define TMR_RUNNING_TIMER 0
38#define TMR_RUNNING_CHANSW 1 53#define TMR_RUNNING_CHANSW 1
@@ -72,6 +87,35 @@ static inline void ASSERT_MGD_MTX(struct ieee80211_if_managed *ifmgd)
72 WARN_ON(!mutex_is_locked(&ifmgd->mtx)); 87 WARN_ON(!mutex_is_locked(&ifmgd->mtx));
73} 88}
74 89
90/*
91 * We can have multiple work items (and connection probing)
92 * scheduling this timer, but we need to take care to only
93 * reschedule it when it should fire _earlier_ than it was
94 * asked for before, or if it's not pending right now. This
95 * function ensures that. Note that it then is required to
96 * run this function for all timeouts after the first one
97 * has happened -- the work that runs from this timer will
98 * do that.
99 */
100static void run_again(struct ieee80211_if_managed *ifmgd,
101 unsigned long timeout)
102{
103 ASSERT_MGD_MTX(ifmgd);
104
105 if (!timer_pending(&ifmgd->timer) ||
106 time_before(timeout, ifmgd->timer.expires))
107 mod_timer(&ifmgd->timer, timeout);
108}
109
110static void mod_beacon_timer(struct ieee80211_sub_if_data *sdata)
111{
112 if (sdata->local->hw.flags & IEEE80211_HW_BEACON_FILTER)
113 return;
114
115 mod_timer(&sdata->u.mgd.bcn_mon_timer,
116 round_jiffies_up(jiffies + IEEE80211_BEACON_LOSS_TIME));
117}
118
75static int ecw2cw(int ecw) 119static int ecw2cw(int ecw)
76{ 120{
77 return (1 << ecw) - 1; 121 return (1 << ecw) - 1;
@@ -646,7 +690,8 @@ void ieee80211_recalc_ps(struct ieee80211_local *local, s32 latency)
646 690
647 if (count == 1 && found->u.mgd.powersave && 691 if (count == 1 && found->u.mgd.powersave &&
648 found->u.mgd.associated && list_empty(&found->u.mgd.work_list) && 692 found->u.mgd.associated && list_empty(&found->u.mgd.work_list) &&
649 !(found->u.mgd.flags & IEEE80211_STA_PROBEREQ_POLL)) { 693 !(found->u.mgd.flags & (IEEE80211_STA_BEACON_POLL |
694 IEEE80211_STA_CONNECTION_POLL))) {
650 s32 beaconint_us; 695 s32 beaconint_us;
651 696
652 if (latency < 0) 697 if (latency < 0)
@@ -852,6 +897,10 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
852 sdata->u.mgd.associated = bss; 897 sdata->u.mgd.associated = bss;
853 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN); 898 memcpy(sdata->u.mgd.bssid, bss->cbss.bssid, ETH_ALEN);
854 899
900 /* just to be sure */
901 sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
902 IEEE80211_STA_BEACON_POLL);
903
855 ieee80211_led_assoc(local, 1); 904 ieee80211_led_assoc(local, 1);
856 905
857 sdata->vif.bss_conf.assoc = 1; 906 sdata->vif.bss_conf.assoc = 1;
@@ -916,7 +965,7 @@ ieee80211_direct_probe(struct ieee80211_sub_if_data *sdata,
916 ieee80211_send_probe_req(sdata, NULL, wk->ssid, wk->ssid_len, NULL, 0); 965 ieee80211_send_probe_req(sdata, NULL, wk->ssid, wk->ssid_len, NULL, 0);
917 966
918 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 967 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
919 mod_timer(&ifmgd->timer, wk->timeout); 968 run_again(ifmgd, wk->timeout);
920 969
921 return RX_MGMT_NONE; 970 return RX_MGMT_NONE;
922} 971}
@@ -954,25 +1003,30 @@ ieee80211_authenticate(struct ieee80211_sub_if_data *sdata,
954 sdata->dev->name, wk->bss->cbss.bssid, wk->tries); 1003 sdata->dev->name, wk->bss->cbss.bssid, wk->tries);
955 1004
956 ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len, 1005 ieee80211_send_auth(sdata, 1, wk->auth_alg, wk->ie, wk->ie_len,
957 wk->bss->cbss.bssid, 0); 1006 wk->bss->cbss.bssid, NULL, 0, 0);
958 wk->auth_transaction = 2; 1007 wk->auth_transaction = 2;
959 1008
960 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT; 1009 wk->timeout = jiffies + IEEE80211_AUTH_TIMEOUT;
961 mod_timer(&ifmgd->timer, wk->timeout); 1010 run_again(ifmgd, wk->timeout);
962 1011
963 return RX_MGMT_NONE; 1012 return RX_MGMT_NONE;
964} 1013}
965 1014
966static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata, 1015static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
967 const u8 *bssid, bool deauth)
968{ 1016{
969 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1017 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
970 struct ieee80211_local *local = sdata->local; 1018 struct ieee80211_local *local = sdata->local;
971 struct sta_info *sta; 1019 struct sta_info *sta;
972 u32 changed = 0, config_changed = 0; 1020 u32 changed = 0, config_changed = 0;
1021 u8 bssid[ETH_ALEN];
973 1022
974 ASSERT_MGD_MTX(ifmgd); 1023 ASSERT_MGD_MTX(ifmgd);
975 1024
1025 if (WARN_ON(!ifmgd->associated))
1026 return;
1027
1028 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
1029
976 ifmgd->associated = NULL; 1030 ifmgd->associated = NULL;
977 memset(ifmgd->bssid, 0, ETH_ALEN); 1031 memset(ifmgd->bssid, 0, ETH_ALEN);
978 1032
@@ -1079,7 +1133,7 @@ ieee80211_associate(struct ieee80211_sub_if_data *sdata,
1079 ieee80211_send_assoc(sdata, wk); 1133 ieee80211_send_assoc(sdata, wk);
1080 1134
1081 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT; 1135 wk->timeout = jiffies + IEEE80211_ASSOC_TIMEOUT;
1082 mod_timer(&ifmgd->timer, wk->timeout); 1136 run_again(ifmgd, wk->timeout);
1083 1137
1084 return RX_MGMT_NONE; 1138 return RX_MGMT_NONE;
1085} 1139}
@@ -1092,31 +1146,24 @@ void ieee80211_sta_rx_notify(struct ieee80211_sub_if_data *sdata,
1092 * from AP because we know that the connection is working both ways 1146 * from AP because we know that the connection is working both ways
1093 * at that time. But multicast frames (and hence also beacons) must 1147 * at that time. But multicast frames (and hence also beacons) must
1094 * be ignored here, because we need to trigger the timer during 1148 * be ignored here, because we need to trigger the timer during
1095 * data idle periods for sending the periodical probe request to 1149 * data idle periods for sending the periodic probe request to the
1096 * the AP. 1150 * AP we're connected to.
1097 */ 1151 */
1098 if (!is_multicast_ether_addr(hdr->addr1)) 1152 if (is_multicast_ether_addr(hdr->addr1))
1099 mod_timer(&sdata->u.mgd.timer, 1153 return;
1100 jiffies + IEEE80211_MONITORING_INTERVAL); 1154
1155 mod_timer(&sdata->u.mgd.conn_mon_timer,
1156 round_jiffies_up(jiffies + IEEE80211_CONNECTION_IDLE_TIME));
1101} 1157}
1102 1158
1103void ieee80211_beacon_loss_work(struct work_struct *work) 1159static void ieee80211_mgd_probe_ap(struct ieee80211_sub_if_data *sdata,
1160 bool beacon)
1104{ 1161{
1105 struct ieee80211_sub_if_data *sdata =
1106 container_of(work, struct ieee80211_sub_if_data,
1107 u.mgd.beacon_loss_work);
1108 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd; 1162 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
1109 const u8 *ssid; 1163 const u8 *ssid;
1164 bool already = false;
1110 1165
1111 /* 1166 if (!netif_running(sdata->dev))
1112 * The driver has already reported this event and we have
1113 * already sent a probe request. Maybe the AP died and the
1114 * driver keeps reporting until we disassociate... We have
1115 * to ignore that because otherwise we would continually
1116 * reset the timer and never check whether we received a
1117 * probe response!
1118 */
1119 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL)
1120 return; 1167 return;
1121 1168
1122 mutex_lock(&ifmgd->mtx); 1169 mutex_lock(&ifmgd->mtx);
@@ -1125,12 +1172,35 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1125 goto out; 1172 goto out;
1126 1173
1127#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1174#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1128 if (net_ratelimit()) 1175 if (beacon && net_ratelimit())
1129 printk(KERN_DEBUG "%s: driver reports beacon loss from AP " 1176 printk(KERN_DEBUG "%s: detected beacon loss from AP "
1130 "- sending probe request\n", sdata->dev->name); 1177 "- sending probe request\n", sdata->dev->name);
1131#endif 1178#endif
1132 1179
1133 ifmgd->flags |= IEEE80211_STA_PROBEREQ_POLL; 1180 /*
1181 * The driver/our work has already reported this event or the
1182 * connection monitoring has kicked in and we have already sent
1183 * a probe request. Or maybe the AP died and the driver keeps
1184 * reporting until we disassociate...
1185 *
1186 * In either case we have to ignore the current call to this
1187 * function (except for setting the correct probe reason bit)
1188 * because otherwise we would reset the timer every time and
1189 * never check whether we received a probe response!
1190 */
1191 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
1192 IEEE80211_STA_CONNECTION_POLL))
1193 already = true;
1194
1195 if (beacon)
1196 ifmgd->flags |= IEEE80211_STA_BEACON_POLL;
1197 else
1198 ifmgd->flags |= IEEE80211_STA_CONNECTION_POLL;
1199
1200 if (already)
1201 goto out;
1202
1203 ifmgd->probe_timeout = jiffies + IEEE80211_PROBE_WAIT;
1134 1204
1135 mutex_lock(&sdata->local->iflist_mtx); 1205 mutex_lock(&sdata->local->iflist_mtx);
1136 ieee80211_recalc_ps(sdata->local, -1); 1206 ieee80211_recalc_ps(sdata->local, -1);
@@ -1140,11 +1210,21 @@ void ieee80211_beacon_loss_work(struct work_struct *work)
1140 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid, 1210 ieee80211_send_probe_req(sdata, ifmgd->associated->cbss.bssid,
1141 ssid + 2, ssid[1], NULL, 0); 1211 ssid + 2, ssid[1], NULL, 0);
1142 1212
1143 mod_timer(&ifmgd->timer, jiffies + IEEE80211_PROBE_WAIT); 1213 run_again(ifmgd, ifmgd->probe_timeout);
1214
1144 out: 1215 out:
1145 mutex_unlock(&ifmgd->mtx); 1216 mutex_unlock(&ifmgd->mtx);
1146} 1217}
1147 1218
1219void ieee80211_beacon_loss_work(struct work_struct *work)
1220{
1221 struct ieee80211_sub_if_data *sdata =
1222 container_of(work, struct ieee80211_sub_if_data,
1223 u.mgd.beacon_loss_work);
1224
1225 ieee80211_mgd_probe_ap(sdata, true);
1226}
1227
1148void ieee80211_beacon_loss(struct ieee80211_vif *vif) 1228void ieee80211_beacon_loss(struct ieee80211_vif *vif)
1149{ 1229{
1150 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif); 1230 struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
@@ -1176,7 +1256,8 @@ static void ieee80211_auth_challenge(struct ieee80211_sub_if_data *sdata,
1176 return; 1256 return;
1177 ieee80211_send_auth(sdata, 3, wk->auth_alg, 1257 ieee80211_send_auth(sdata, 3, wk->auth_alg,
1178 elems.challenge - 2, elems.challenge_len + 2, 1258 elems.challenge - 2, elems.challenge_len + 2,
1179 wk->bss->cbss.bssid, 1); 1259 wk->bss->cbss.bssid,
1260 wk->key, wk->key_len, wk->key_idx);
1180 wk->auth_transaction = 4; 1261 wk->auth_transaction = 4;
1181} 1262}
1182 1263
@@ -1257,7 +1338,7 @@ ieee80211_rx_mgmt_deauth(struct ieee80211_sub_if_data *sdata,
1257 sdata->dev->name, bssid, reason_code); 1338 sdata->dev->name, bssid, reason_code);
1258 1339
1259 if (!wk) { 1340 if (!wk) {
1260 ieee80211_set_disassoc(sdata, bssid, true); 1341 ieee80211_set_disassoc(sdata);
1261 } else { 1342 } else {
1262 list_del(&wk->list); 1343 list_del(&wk->list);
1263 kfree(wk); 1344 kfree(wk);
@@ -1290,7 +1371,7 @@ ieee80211_rx_mgmt_disassoc(struct ieee80211_sub_if_data *sdata,
1290 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n", 1371 printk(KERN_DEBUG "%s: disassociated (Reason: %u)\n",
1291 sdata->dev->name, reason_code); 1372 sdata->dev->name, reason_code);
1292 1373
1293 ieee80211_set_disassoc(sdata, ifmgd->associated->cbss.bssid, false); 1374 ieee80211_set_disassoc(sdata);
1294 return RX_MGMT_CFG80211_DISASSOC; 1375 return RX_MGMT_CFG80211_DISASSOC;
1295} 1376}
1296 1377
@@ -1349,8 +1430,7 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1349 sdata->dev->name, tu, ms); 1430 sdata->dev->name, tu, ms);
1350 wk->timeout = jiffies + msecs_to_jiffies(ms); 1431 wk->timeout = jiffies + msecs_to_jiffies(ms);
1351 if (ms > IEEE80211_ASSOC_TIMEOUT) 1432 if (ms > IEEE80211_ASSOC_TIMEOUT)
1352 mod_timer(&ifmgd->timer, 1433 run_again(ifmgd, jiffies + msecs_to_jiffies(ms));
1353 jiffies + msecs_to_jiffies(ms));
1354 return RX_MGMT_NONE; 1434 return RX_MGMT_NONE;
1355 } 1435 }
1356 1436
@@ -1392,9 +1472,6 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1392 return RX_MGMT_NONE; 1472 return RX_MGMT_NONE;
1393 } 1473 }
1394 1474
1395 /* update new sta with its last rx activity */
1396 sta->last_rx = jiffies;
1397
1398 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC | 1475 set_sta_flags(sta, WLAN_STA_AUTH | WLAN_STA_ASSOC |
1399 WLAN_STA_ASSOC_AP); 1476 WLAN_STA_ASSOC_AP);
1400 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT)) 1477 if (!(ifmgd->flags & IEEE80211_STA_CONTROL_PORT))
@@ -1497,10 +1574,11 @@ ieee80211_rx_mgmt_assoc_resp(struct ieee80211_sub_if_data *sdata,
1497 ieee80211_set_associated(sdata, wk->bss, changed); 1574 ieee80211_set_associated(sdata, wk->bss, changed);
1498 1575
1499 /* 1576 /*
1500 * initialise the time of last beacon to be the association time, 1577 * Start timer to probe the connection to the AP now.
1501 * otherwise beacon loss check will trigger immediately 1578 * Also start the timer that will detect beacon loss.
1502 */ 1579 */
1503 ifmgd->last_beacon = jiffies; 1580 ieee80211_sta_rx_notify(sdata, (struct ieee80211_hdr *)mgmt);
1581 mod_beacon_timer(sdata);
1504 1582
1505 list_del(&wk->list); 1583 list_del(&wk->list);
1506 kfree(wk); 1584 kfree(wk);
@@ -1584,11 +1662,22 @@ static void ieee80211_rx_mgmt_probe_resp(struct ieee80211_sub_if_data *sdata,
1584 1662
1585 if (ifmgd->associated && 1663 if (ifmgd->associated &&
1586 memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 && 1664 memcmp(mgmt->bssid, ifmgd->associated->cbss.bssid, ETH_ALEN) == 0 &&
1587 ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { 1665 ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
1588 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1666 IEEE80211_STA_CONNECTION_POLL)) {
1667 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
1668 IEEE80211_STA_BEACON_POLL);
1589 mutex_lock(&sdata->local->iflist_mtx); 1669 mutex_lock(&sdata->local->iflist_mtx);
1590 ieee80211_recalc_ps(sdata->local, -1); 1670 ieee80211_recalc_ps(sdata->local, -1);
1591 mutex_unlock(&sdata->local->iflist_mtx); 1671 mutex_unlock(&sdata->local->iflist_mtx);
1672 /*
1673 * We've received a probe response, but are not sure whether
1674 * we have or will be receiving any beacons or data, so let's
1675 * schedule the timers again, just in case.
1676 */
1677 mod_beacon_timer(sdata);
1678 mod_timer(&ifmgd->conn_mon_timer,
1679 round_jiffies_up(jiffies +
1680 IEEE80211_CONNECTION_IDLE_TIME));
1592 } 1681 }
1593} 1682}
1594 1683
@@ -1638,27 +1727,41 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
1638 if (rx_status->freq != local->hw.conf.channel->center_freq) 1727 if (rx_status->freq != local->hw.conf.channel->center_freq)
1639 return; 1728 return;
1640 1729
1641 if (WARN_ON(!ifmgd->associated)) 1730 /*
1731 * We might have received a number of frames, among them a
1732 * disassoc frame and a beacon...
1733 */
1734 if (!ifmgd->associated)
1642 return; 1735 return;
1643 1736
1644 bssid = ifmgd->associated->cbss.bssid; 1737 bssid = ifmgd->associated->cbss.bssid;
1645 1738
1646 if (WARN_ON(memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)) 1739 /*
1740 * And in theory even frames from a different AP we were just
1741 * associated to a split-second ago!
1742 */
1743 if (memcmp(bssid, mgmt->bssid, ETH_ALEN) != 0)
1647 return; 1744 return;
1648 1745
1649 if (ifmgd->flags & IEEE80211_STA_PROBEREQ_POLL) { 1746 if (ifmgd->flags & IEEE80211_STA_BEACON_POLL) {
1650#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 1747#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1651 if (net_ratelimit()) { 1748 if (net_ratelimit()) {
1652 printk(KERN_DEBUG "%s: cancelling probereq poll due " 1749 printk(KERN_DEBUG "%s: cancelling probereq poll due "
1653 "to a received beacon\n", sdata->dev->name); 1750 "to a received beacon\n", sdata->dev->name);
1654 } 1751 }
1655#endif 1752#endif
1656 ifmgd->flags &= ~IEEE80211_STA_PROBEREQ_POLL; 1753 ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
1657 mutex_lock(&local->iflist_mtx); 1754 mutex_lock(&local->iflist_mtx);
1658 ieee80211_recalc_ps(local, -1); 1755 ieee80211_recalc_ps(local, -1);
1659 mutex_unlock(&local->iflist_mtx); 1756 mutex_unlock(&local->iflist_mtx);
1660 } 1757 }
1661 1758
1759 /*
1760 * Push the beacon loss detection into the future since
1761 * we are processing a beacon from the AP just now.
1762 */
1763 mod_beacon_timer(sdata);
1764
1662 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4); 1765 ncrc = crc32_be(0, (void *)&mgmt->u.beacon.beacon_int, 4);
1663 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable, 1766 ncrc = ieee802_11_parse_elems_crc(mgmt->u.beacon.variable,
1664 len - baselen, &elems, 1767 len - baselen, &elems,
@@ -1960,6 +2063,37 @@ static void ieee80211_sta_work(struct work_struct *work)
1960 /* then process the rest of the work */ 2063 /* then process the rest of the work */
1961 mutex_lock(&ifmgd->mtx); 2064 mutex_lock(&ifmgd->mtx);
1962 2065
2066 if (ifmgd->flags & (IEEE80211_STA_BEACON_POLL |
2067 IEEE80211_STA_CONNECTION_POLL) &&
2068 ifmgd->associated) {
2069 if (time_is_after_jiffies(ifmgd->probe_timeout))
2070 run_again(ifmgd, ifmgd->probe_timeout);
2071 else {
2072 u8 bssid[ETH_ALEN];
2073 /*
2074 * We actually lost the connection ... or did we?
2075 * Let's make sure!
2076 */
2077 ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
2078 IEEE80211_STA_BEACON_POLL);
2079 memcpy(bssid, ifmgd->associated->cbss.bssid, ETH_ALEN);
2080 printk(KERN_DEBUG "No probe response from AP %pM"
2081 " after %dms, disconnecting.\n",
2082 bssid, (1000 * IEEE80211_PROBE_WAIT)/HZ);
2083 ieee80211_set_disassoc(sdata);
2084 mutex_unlock(&ifmgd->mtx);
2085 /*
2086 * must be outside lock due to cfg80211,
2087 * but that's not a problem.
2088 */
2089 ieee80211_send_deauth_disassoc(sdata, bssid,
2090 IEEE80211_STYPE_DEAUTH,
2091 WLAN_REASON_DISASSOC_DUE_TO_INACTIVITY,
2092 NULL);
2093 mutex_lock(&ifmgd->mtx);
2094 }
2095 }
2096
1963 list_for_each_entry(wk, &ifmgd->work_list, list) { 2097 list_for_each_entry(wk, &ifmgd->work_list, list) {
1964 if (wk->state != IEEE80211_MGD_STATE_IDLE) { 2098 if (wk->state != IEEE80211_MGD_STATE_IDLE) {
1965 anybusy = true; 2099 anybusy = true;
@@ -1980,8 +2114,15 @@ static void ieee80211_sta_work(struct work_struct *work)
1980 } 2114 }
1981 2115
1982 list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) { 2116 list_for_each_entry_safe(wk, tmp, &ifmgd->work_list, list) {
1983 if (time_before(jiffies, wk->timeout)) 2117 if (time_is_after_jiffies(wk->timeout)) {
2118 /*
2119 * This work item isn't supposed to be worked on
2120 * right now, but take care to adjust the timer
2121 * properly.
2122 */
2123 run_again(ifmgd, wk->timeout);
1984 continue; 2124 continue;
2125 }
1985 2126
1986 switch (wk->state) { 2127 switch (wk->state) {
1987 default: 2128 default:
@@ -2040,15 +2181,54 @@ static void ieee80211_sta_work(struct work_struct *work)
2040 ieee80211_recalc_idle(local); 2181 ieee80211_recalc_idle(local);
2041} 2182}
2042 2183
2184static void ieee80211_sta_bcn_mon_timer(unsigned long data)
2185{
2186 struct ieee80211_sub_if_data *sdata =
2187 (struct ieee80211_sub_if_data *) data;
2188 struct ieee80211_local *local = sdata->local;
2189
2190 if (local->quiescing)
2191 return;
2192
2193 queue_work(sdata->local->hw.workqueue,
2194 &sdata->u.mgd.beacon_loss_work);
2195}
2196
2197static void ieee80211_sta_conn_mon_timer(unsigned long data)
2198{
2199 struct ieee80211_sub_if_data *sdata =
2200 (struct ieee80211_sub_if_data *) data;
2201 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
2202 struct ieee80211_local *local = sdata->local;
2203
2204 if (local->quiescing)
2205 return;
2206
2207 queue_work(local->hw.workqueue, &ifmgd->monitor_work);
2208}
2209
2210static void ieee80211_sta_monitor_work(struct work_struct *work)
2211{
2212 struct ieee80211_sub_if_data *sdata =
2213 container_of(work, struct ieee80211_sub_if_data,
2214 u.mgd.monitor_work);
2215
2216 if (sdata->local->sw_scanning || sdata->local->hw_scanning)
2217 return;
2218
2219 ieee80211_mgd_probe_ap(sdata, false);
2220}
2221
2043static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata) 2222static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
2044{ 2223{
2045 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 2224 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
2046 /* 2225 sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL |
2047 * Need to update last_beacon to avoid beacon loss 2226 IEEE80211_STA_CONNECTION_POLL);
2048 * test to trigger.
2049 */
2050 sdata->u.mgd.last_beacon = jiffies;
2051 2227
2228 /* let's probe the connection once */
2229 queue_work(sdata->local->hw.workqueue,
2230 &sdata->u.mgd.monitor_work);
2231 /* and do all the other regular work too */
2052 queue_work(sdata->local->hw.workqueue, 2232 queue_work(sdata->local->hw.workqueue,
2053 &sdata->u.mgd.work); 2233 &sdata->u.mgd.work);
2054 } 2234 }
@@ -2073,6 +2253,11 @@ void ieee80211_sta_quiesce(struct ieee80211_sub_if_data *sdata)
2073 cancel_work_sync(&ifmgd->chswitch_work); 2253 cancel_work_sync(&ifmgd->chswitch_work);
2074 if (del_timer_sync(&ifmgd->chswitch_timer)) 2254 if (del_timer_sync(&ifmgd->chswitch_timer))
2075 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running); 2255 set_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running);
2256
2257 cancel_work_sync(&ifmgd->monitor_work);
2258 /* these will just be re-established on connection */
2259 del_timer_sync(&ifmgd->conn_mon_timer);
2260 del_timer_sync(&ifmgd->bcn_mon_timer);
2076} 2261}
2077 2262
2078void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata) 2263void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
@@ -2093,10 +2278,15 @@ void ieee80211_sta_setup_sdata(struct ieee80211_sub_if_data *sdata)
2093 2278
2094 ifmgd = &sdata->u.mgd; 2279 ifmgd = &sdata->u.mgd;
2095 INIT_WORK(&ifmgd->work, ieee80211_sta_work); 2280 INIT_WORK(&ifmgd->work, ieee80211_sta_work);
2281 INIT_WORK(&ifmgd->monitor_work, ieee80211_sta_monitor_work);
2096 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work); 2282 INIT_WORK(&ifmgd->chswitch_work, ieee80211_chswitch_work);
2097 INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work); 2283 INIT_WORK(&ifmgd->beacon_loss_work, ieee80211_beacon_loss_work);
2098 setup_timer(&ifmgd->timer, ieee80211_sta_timer, 2284 setup_timer(&ifmgd->timer, ieee80211_sta_timer,
2099 (unsigned long) sdata); 2285 (unsigned long) sdata);
2286 setup_timer(&ifmgd->bcn_mon_timer, ieee80211_sta_bcn_mon_timer,
2287 (unsigned long) sdata);
2288 setup_timer(&ifmgd->conn_mon_timer, ieee80211_sta_conn_mon_timer,
2289 (unsigned long) sdata);
2100 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer, 2290 setup_timer(&ifmgd->chswitch_timer, ieee80211_chswitch_timer,
2101 (unsigned long) sdata); 2291 (unsigned long) sdata);
2102 skb_queue_head_init(&ifmgd->skb_queue); 2292 skb_queue_head_init(&ifmgd->skb_queue);
@@ -2175,6 +2365,12 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
2175 wk->ie_len = req->ie_len; 2365 wk->ie_len = req->ie_len;
2176 } 2366 }
2177 2367
2368 if (req->key && req->key_len) {
2369 wk->key_len = req->key_len;
2370 wk->key_idx = req->key_idx;
2371 memcpy(wk->key, req->key, req->key_len);
2372 }
2373
2178 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); 2374 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
2179 memcpy(wk->ssid, ssid + 2, ssid[1]); 2375 memcpy(wk->ssid, ssid + 2, ssid[1]);
2180 wk->ssid_len = ssid[1]; 2376 wk->ssid_len = ssid[1];
@@ -2290,7 +2486,7 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,
2290 2486
2291 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) { 2487 if (ifmgd->associated && &ifmgd->associated->cbss == req->bss) {
2292 bssid = req->bss->bssid; 2488 bssid = req->bss->bssid;
2293 ieee80211_set_disassoc(sdata, bssid, true); 2489 ieee80211_set_disassoc(sdata);
2294 } else list_for_each_entry(wk, &ifmgd->work_list, list) { 2490 } else list_for_each_entry(wk, &ifmgd->work_list, list) {
2295 if (&wk->bss->cbss == req->bss) { 2491 if (&wk->bss->cbss == req->bss) {
2296 bssid = req->bss->bssid; 2492 bssid = req->bss->bssid;
@@ -2332,7 +2528,7 @@ int ieee80211_mgd_disassoc(struct ieee80211_sub_if_data *sdata,
2332 return -ENOLINK; 2528 return -ENOLINK;
2333 } 2529 }
2334 2530
2335 ieee80211_set_disassoc(sdata, req->bss->bssid, false); 2531 ieee80211_set_disassoc(sdata);
2336 2532
2337 mutex_unlock(&ifmgd->mtx); 2533 mutex_unlock(&ifmgd->mtx);
2338 2534
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index 4641f00a1e5c..b33efc4fc267 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -198,6 +198,35 @@ static void rate_control_release(struct kref *kref)
198 kfree(ctrl_ref); 198 kfree(ctrl_ref);
199} 199}
200 200
201static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc)
202{
203 struct sk_buff *skb = txrc->skb;
204 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
205 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
206 __le16 fc;
207
208 fc = hdr->frame_control;
209
210 return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc));
211}
212
213bool rate_control_send_low(struct ieee80211_sta *sta,
214 void *priv_sta,
215 struct ieee80211_tx_rate_control *txrc)
216{
217 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
218
219 if (!sta || !priv_sta || rc_no_data_or_no_ack(txrc)) {
220 info->control.rates[0].idx = rate_lowest_index(txrc->sband, sta);
221 info->control.rates[0].count =
222 (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
223 1 : txrc->hw->max_rate_tries;
224 return true;
225 }
226 return false;
227}
228EXPORT_SYMBOL(rate_control_send_low);
229
201void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, 230void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
202 struct sta_info *sta, 231 struct sta_info *sta,
203 struct ieee80211_tx_rate_control *txrc) 232 struct ieee80211_tx_rate_control *txrc)
@@ -258,7 +287,7 @@ int ieee80211_init_rate_ctrl_alg(struct ieee80211_local *local,
258 struct rate_control_ref *ref, *old; 287 struct rate_control_ref *ref, *old;
259 288
260 ASSERT_RTNL(); 289 ASSERT_RTNL();
261 if (local->open_count || netif_running(local->mdev)) 290 if (local->open_count)
262 return -EBUSY; 291 return -EBUSY;
263 292
264 ref = rate_control_alloc(name, local); 293 ref = rate_control_alloc(name, local);
diff --git a/net/mac80211/rc80211_minstrel.c b/net/mac80211/rc80211_minstrel.c
index 37771abd8f5a..7c5142988bbb 100644
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -70,20 +70,6 @@ rix_to_ndx(struct minstrel_sta_info *mi, int rix)
70 return i; 70 return i;
71} 71}
72 72
73static inline bool
74use_low_rate(struct sk_buff *skb)
75{
76 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
77 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
78 u16 fc;
79
80 fc = le16_to_cpu(hdr->frame_control);
81
82 return ((info->flags & IEEE80211_TX_CTL_NO_ACK) ||
83 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA);
84}
85
86
87static void 73static void
88minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi) 74minstrel_update_stats(struct minstrel_priv *mp, struct minstrel_sta_info *mi)
89{ 75{
@@ -232,7 +218,6 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
232 void *priv_sta, struct ieee80211_tx_rate_control *txrc) 218 void *priv_sta, struct ieee80211_tx_rate_control *txrc)
233{ 219{
234 struct sk_buff *skb = txrc->skb; 220 struct sk_buff *skb = txrc->skb;
235 struct ieee80211_supported_band *sband = txrc->sband;
236 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 221 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
237 struct minstrel_sta_info *mi = priv_sta; 222 struct minstrel_sta_info *mi = priv_sta;
238 struct minstrel_priv *mp = priv; 223 struct minstrel_priv *mp = priv;
@@ -245,14 +230,8 @@ minstrel_get_rate(void *priv, struct ieee80211_sta *sta,
245 int mrr_ndx[3]; 230 int mrr_ndx[3];
246 int sample_rate; 231 int sample_rate;
247 232
248 if (!sta || !mi || use_low_rate(skb)) { 233 if (rate_control_send_low(sta, priv_sta, txrc))
249 ar[0].idx = rate_lowest_index(sband, sta);
250 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
251 ar[0].count = 1;
252 else
253 ar[0].count = mp->max_retry;
254 return; 234 return;
255 }
256 235
257 mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot; 236 mrr = mp->has_mrr && !txrc->rts && !txrc->bss_conf->use_cts_prot;
258 237
diff --git a/net/mac80211/rc80211_pid_algo.c b/net/mac80211/rc80211_pid_algo.c
index a0bef767ceb5..8c053be9dc24 100644
--- a/net/mac80211/rc80211_pid_algo.c
+++ b/net/mac80211/rc80211_pid_algo.c
@@ -276,11 +276,9 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
276{ 276{
277 struct sk_buff *skb = txrc->skb; 277 struct sk_buff *skb = txrc->skb;
278 struct ieee80211_supported_band *sband = txrc->sband; 278 struct ieee80211_supported_band *sband = txrc->sband;
279 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
280 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 279 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
281 struct rc_pid_sta_info *spinfo = priv_sta; 280 struct rc_pid_sta_info *spinfo = priv_sta;
282 int rateidx; 281 int rateidx;
283 u16 fc;
284 282
285 if (txrc->rts) 283 if (txrc->rts)
286 info->control.rates[0].count = 284 info->control.rates[0].count =
@@ -290,16 +288,8 @@ rate_control_pid_get_rate(void *priv, struct ieee80211_sta *sta,
290 txrc->hw->conf.short_frame_max_tx_count; 288 txrc->hw->conf.short_frame_max_tx_count;
291 289
292 /* Send management frames and NO_ACK data using lowest rate. */ 290 /* Send management frames and NO_ACK data using lowest rate. */
293 fc = le16_to_cpu(hdr->frame_control); 291 if (rate_control_send_low(sta, priv_sta, txrc))
294 if (!sta || !spinfo ||
295 (fc & IEEE80211_FCTL_FTYPE) != IEEE80211_FTYPE_DATA ||
296 info->flags & IEEE80211_TX_CTL_NO_ACK) {
297 info->control.rates[0].idx = rate_lowest_index(sband, sta);
298 if (info->flags & IEEE80211_TX_CTL_NO_ACK)
299 info->control.rates[0].count = 1;
300
301 return; 292 return;
302 }
303 293
304 rateidx = spinfo->txrate_idx; 294 rateidx = spinfo->txrate_idx;
305 295
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index fe6b99059531..66c797cc85ce 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -833,28 +833,22 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
833 if (!sta) 833 if (!sta)
834 return RX_CONTINUE; 834 return RX_CONTINUE;
835 835
836 /* Update last_rx only for IBSS packets which are for the current 836 /*
837 * BSSID to avoid keeping the current IBSS network alive in cases where 837 * Update last_rx only for IBSS packets which are for the current
838 * other STAs are using different BSSID. */ 838 * BSSID to avoid keeping the current IBSS network alive in cases
839 * where other STAs start using different BSSID.
840 */
839 if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) { 841 if (rx->sdata->vif.type == NL80211_IFTYPE_ADHOC) {
840 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len, 842 u8 *bssid = ieee80211_get_bssid(hdr, rx->skb->len,
841 NL80211_IFTYPE_ADHOC); 843 NL80211_IFTYPE_ADHOC);
842 if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0) 844 if (compare_ether_addr(bssid, rx->sdata->u.ibss.bssid) == 0)
843 sta->last_rx = jiffies; 845 sta->last_rx = jiffies;
844 } else 846 } else if (!is_multicast_ether_addr(hdr->addr1)) {
845 if (!is_multicast_ether_addr(hdr->addr1) || 847 /*
846 rx->sdata->vif.type == NL80211_IFTYPE_STATION) {
847 /* Update last_rx only for unicast frames in order to prevent
848 * the Probe Request frames (the only broadcast frames from a
849 * STA in infrastructure mode) from keeping a connection alive.
850 * Mesh beacons will update last_rx when if they are found to 848 * Mesh beacons will update last_rx when if they are found to
851 * match the current local configuration when processed. 849 * match the current local configuration when processed.
852 */ 850 */
853 if (rx->sdata->vif.type == NL80211_IFTYPE_STATION && 851 sta->last_rx = jiffies;
854 ieee80211_is_beacon(hdr->frame_control)) {
855 rx->sdata->u.mgd.last_beacon = jiffies;
856 } else
857 sta->last_rx = jiffies;
858 } 852 }
859 853
860 if (!(rx->flags & IEEE80211_RX_RA_MATCH)) 854 if (!(rx->flags & IEEE80211_RX_RA_MATCH))
@@ -1484,10 +1478,13 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1484 struct ieee80211s_hdr *mesh_hdr; 1478 struct ieee80211s_hdr *mesh_hdr;
1485 unsigned int hdrlen; 1479 unsigned int hdrlen;
1486 struct sk_buff *skb = rx->skb, *fwd_skb; 1480 struct sk_buff *skb = rx->skb, *fwd_skb;
1481 struct ieee80211_local *local = rx->local;
1482 struct ieee80211_sub_if_data *sdata;
1487 1483
1488 hdr = (struct ieee80211_hdr *) skb->data; 1484 hdr = (struct ieee80211_hdr *) skb->data;
1489 hdrlen = ieee80211_hdrlen(hdr->frame_control); 1485 hdrlen = ieee80211_hdrlen(hdr->frame_control);
1490 mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); 1486 mesh_hdr = (struct ieee80211s_hdr *) (skb->data + hdrlen);
1487 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1491 1488
1492 if (!ieee80211_is_data(hdr->frame_control)) 1489 if (!ieee80211_is_data(hdr->frame_control))
1493 return RX_CONTINUE; 1490 return RX_CONTINUE;
@@ -1497,10 +1494,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1497 return RX_DROP_MONITOR; 1494 return RX_DROP_MONITOR;
1498 1495
1499 if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){ 1496 if (mesh_hdr->flags & MESH_FLAGS_AE_A5_A6){
1500 struct ieee80211_sub_if_data *sdata;
1501 struct mesh_path *mppath; 1497 struct mesh_path *mppath;
1502 1498
1503 sdata = IEEE80211_DEV_TO_SUB_IF(rx->dev);
1504 rcu_read_lock(); 1499 rcu_read_lock();
1505 mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata); 1500 mppath = mpp_path_lookup(mesh_hdr->eaddr2, sdata);
1506 if (!mppath) { 1501 if (!mppath) {
@@ -1526,6 +1521,8 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1526 dropped_frames_ttl); 1521 dropped_frames_ttl);
1527 else { 1522 else {
1528 struct ieee80211_hdr *fwd_hdr; 1523 struct ieee80211_hdr *fwd_hdr;
1524 struct ieee80211_tx_info *info;
1525
1529 fwd_skb = skb_copy(skb, GFP_ATOMIC); 1526 fwd_skb = skb_copy(skb, GFP_ATOMIC);
1530 1527
1531 if (!fwd_skb && net_ratelimit()) 1528 if (!fwd_skb && net_ratelimit())
@@ -1539,9 +1536,25 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1539 */ 1536 */
1540 memcpy(fwd_hdr->addr1, fwd_hdr->addr2, ETH_ALEN); 1537 memcpy(fwd_hdr->addr1, fwd_hdr->addr2, ETH_ALEN);
1541 memcpy(fwd_hdr->addr2, rx->dev->dev_addr, ETH_ALEN); 1538 memcpy(fwd_hdr->addr2, rx->dev->dev_addr, ETH_ALEN);
1542 fwd_skb->dev = rx->local->mdev; 1539 info = IEEE80211_SKB_CB(fwd_skb);
1540 memset(info, 0, sizeof(*info));
1541 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1543 fwd_skb->iif = rx->dev->ifindex; 1542 fwd_skb->iif = rx->dev->ifindex;
1544 dev_queue_xmit(fwd_skb); 1543 ieee80211_select_queue(local, fwd_skb);
1544 if (is_multicast_ether_addr(fwd_hdr->addr3))
1545 memcpy(fwd_hdr->addr1, fwd_hdr->addr3,
1546 ETH_ALEN);
1547 else {
1548 int err = mesh_nexthop_lookup(fwd_skb, sdata);
1549 /* Failed to immediately resolve next hop:
1550 * fwded frame was dropped or will be added
1551 * later to the pending skb queue. */
1552 if (err)
1553 return RX_DROP_MONITOR;
1554 }
1555 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
1556 fwded_frames);
1557 ieee80211_add_pending_skb(local, fwd_skb);
1545 } 1558 }
1546 } 1559 }
1547 1560
@@ -1809,8 +1822,7 @@ ieee80211_rx_h_mgmt(struct ieee80211_rx_data *rx)
1809 return RX_DROP_MONITOR; 1822 return RX_DROP_MONITOR;
1810} 1823}
1811 1824
1812static void ieee80211_rx_michael_mic_report(struct net_device *dev, 1825static void ieee80211_rx_michael_mic_report(struct ieee80211_hdr *hdr,
1813 struct ieee80211_hdr *hdr,
1814 struct ieee80211_rx_data *rx) 1826 struct ieee80211_rx_data *rx)
1815{ 1827{
1816 int keyidx; 1828 int keyidx;
@@ -2120,7 +2132,7 @@ static void __ieee80211_rx_handle_packet(struct ieee80211_hw *hw,
2120 } 2132 }
2121 2133
2122 if ((status->flag & RX_FLAG_MMIC_ERROR)) { 2134 if ((status->flag & RX_FLAG_MMIC_ERROR)) {
2123 ieee80211_rx_michael_mic_report(local->mdev, hdr, &rx); 2135 ieee80211_rx_michael_mic_report(hdr, &rx);
2124 return; 2136 return;
2125 } 2137 }
2126 2138
@@ -2489,7 +2501,6 @@ void ieee80211_rx_irqsafe(struct ieee80211_hw *hw, struct sk_buff *skb)
2489 2501
2490 BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb)); 2502 BUILD_BUG_ON(sizeof(struct ieee80211_rx_status) > sizeof(skb->cb));
2491 2503
2492 skb->dev = local->mdev;
2493 skb->pkt_type = IEEE80211_RX_MSG; 2504 skb->pkt_type = IEEE80211_RX_MSG;
2494 skb_queue_tail(&local->skb_queue, skb); 2505 skb_queue_tail(&local->skb_queue, skb);
2495 tasklet_schedule(&local->tasklet); 2506 tasklet_schedule(&local->tasklet);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 5f4f7869d050..74820656dc89 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -294,16 +294,13 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
294 if (was_hw_scan) 294 if (was_hw_scan)
295 goto done; 295 goto done;
296 296
297 netif_tx_lock_bh(local->mdev); 297 spin_lock_bh(&local->filter_lock);
298 netif_addr_lock(local->mdev);
299 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC; 298 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
300 drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC, 299 drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
301 &local->filter_flags, 300 &local->filter_flags,
302 local->mdev->mc_count, 301 local->mc_count,
303 local->mdev->mc_list); 302 local->mc_list);
304 303 spin_unlock_bh(&local->filter_lock);
305 netif_addr_unlock(local->mdev);
306 netif_tx_unlock_bh(local->mdev);
307 304
308 drv_sw_scan_complete(local); 305 drv_sw_scan_complete(local);
309 306
@@ -382,13 +379,13 @@ static int ieee80211_start_sw_scan(struct ieee80211_local *local)
382 local->scan_state = SCAN_SET_CHANNEL; 379 local->scan_state = SCAN_SET_CHANNEL;
383 local->scan_channel_idx = 0; 380 local->scan_channel_idx = 0;
384 381
385 netif_addr_lock_bh(local->mdev); 382 spin_lock_bh(&local->filter_lock);
386 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC; 383 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
387 drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC, 384 drv_configure_filter(local, FIF_BCN_PRBRESP_PROMISC,
388 &local->filter_flags, 385 &local->filter_flags,
389 local->mdev->mc_count, 386 local->mc_count,
390 local->mdev->mc_list); 387 local->mc_list);
391 netif_addr_unlock_bh(local->mdev); 388 spin_unlock_bh(&local->filter_lock);
392 389
393 /* TODO: start scan as soon as all nullfunc frames are ACKed */ 390 /* TODO: start scan as soon as all nullfunc frames are ACKed */
394 queue_delayed_work(local->hw.workqueue, &local->scan_work, 391 queue_delayed_work(local->hw.workqueue, &local->scan_work,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 60ae086995b1..2572509d5568 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -451,7 +451,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
451 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb); 451 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(tx->skb);
452 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data; 452 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)tx->skb->data;
453 453
454 if (unlikely(tx->skb->do_not_encrypt)) 454 if (unlikely(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT))
455 tx->key = NULL; 455 tx->key = NULL;
456 else if (tx->sta && (key = rcu_dereference(tx->sta->key))) 456 else if (tx->sta && (key = rcu_dereference(tx->sta->key)))
457 tx->key = key; 457 tx->key = key;
@@ -497,7 +497,7 @@ ieee80211_tx_h_select_key(struct ieee80211_tx_data *tx)
497 } 497 }
498 498
499 if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE)) 499 if (!tx->key || !(tx->key->flags & KEY_FLAG_UPLOADED_TO_HARDWARE))
500 tx->skb->do_not_encrypt = 1; 500 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
501 501
502 return TX_CONTINUE; 502 return TX_CONTINUE;
503} 503}
@@ -512,6 +512,7 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
512 int i, len; 512 int i, len;
513 bool inval = false, rts = false, short_preamble = false; 513 bool inval = false, rts = false, short_preamble = false;
514 struct ieee80211_tx_rate_control txrc; 514 struct ieee80211_tx_rate_control txrc;
515 u32 sta_flags;
515 516
516 memset(&txrc, 0, sizeof(txrc)); 517 memset(&txrc, 0, sizeof(txrc));
517 518
@@ -544,7 +545,26 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
544 (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE)))) 545 (tx->sta && test_sta_flags(tx->sta, WLAN_STA_SHORT_PREAMBLE))))
545 txrc.short_preamble = short_preamble = true; 546 txrc.short_preamble = short_preamble = true;
546 547
548 sta_flags = tx->sta ? get_sta_flags(tx->sta) : 0;
549
550 /*
551 * Lets not bother rate control if we're associated and cannot
552 * talk to the sta. This should not happen.
553 */
554 if (WARN((tx->local->sw_scanning) &&
555 (sta_flags & WLAN_STA_ASSOC) &&
556 !rate_usable_index_exists(sband, &tx->sta->sta),
557 "%s: Dropped data frame as no usable bitrate found while "
558 "scanning and associated. Target station: "
559 "%pM on %d GHz band\n",
560 tx->dev->name, hdr->addr1,
561 tx->channel->band ? 5 : 2))
562 return TX_DROP;
547 563
564 /*
565 * If we're associated with the sta at this point we know we can at
566 * least send the frame at the lowest bit rate.
567 */
548 rate_control_get_rate(tx->sdata, tx->sta, &txrc); 568 rate_control_get_rate(tx->sdata, tx->sta, &txrc);
549 569
550 if (unlikely(info->control.rates[0].idx < 0)) 570 if (unlikely(info->control.rates[0].idx < 0))
@@ -754,9 +774,7 @@ static int ieee80211_fragment(struct ieee80211_local *local,
754 memcpy(tmp->cb, skb->cb, sizeof(tmp->cb)); 774 memcpy(tmp->cb, skb->cb, sizeof(tmp->cb));
755 skb_copy_queue_mapping(tmp, skb); 775 skb_copy_queue_mapping(tmp, skb);
756 tmp->priority = skb->priority; 776 tmp->priority = skb->priority;
757 tmp->do_not_encrypt = skb->do_not_encrypt;
758 tmp->dev = skb->dev; 777 tmp->dev = skb->dev;
759 tmp->iif = skb->iif;
760 778
761 /* copy header and data */ 779 /* copy header and data */
762 memcpy(skb_put(tmp, hdrlen), skb->data, hdrlen); 780 memcpy(skb_put(tmp, hdrlen), skb->data, hdrlen);
@@ -784,7 +802,7 @@ ieee80211_tx_h_fragment(struct ieee80211_tx_data *tx)
784 802
785 /* 803 /*
786 * Warn when submitting a fragmented A-MPDU frame and drop it. 804 * Warn when submitting a fragmented A-MPDU frame and drop it.
787 * This scenario is handled in __ieee80211_tx_prepare but extra 805 * This scenario is handled in ieee80211_tx_prepare but extra
788 * caution taken here as fragmented ampdu may cause Tx stop. 806 * caution taken here as fragmented ampdu may cause Tx stop.
789 */ 807 */
790 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) 808 if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU))
@@ -923,11 +941,12 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
923 struct ieee80211_radiotap_header *rthdr = 941 struct ieee80211_radiotap_header *rthdr =
924 (struct ieee80211_radiotap_header *) skb->data; 942 (struct ieee80211_radiotap_header *) skb->data;
925 struct ieee80211_supported_band *sband; 943 struct ieee80211_supported_band *sband;
944 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
926 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len); 945 int ret = ieee80211_radiotap_iterator_init(&iterator, rthdr, skb->len);
927 946
928 sband = tx->local->hw.wiphy->bands[tx->channel->band]; 947 sband = tx->local->hw.wiphy->bands[tx->channel->band];
929 948
930 skb->do_not_encrypt = 1; 949 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
931 tx->flags &= ~IEEE80211_TX_FRAGMENTED; 950 tx->flags &= ~IEEE80211_TX_FRAGMENTED;
932 951
933 /* 952 /*
@@ -965,7 +984,7 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
965 skb_trim(skb, skb->len - FCS_LEN); 984 skb_trim(skb, skb->len - FCS_LEN);
966 } 985 }
967 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP) 986 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_WEP)
968 tx->skb->do_not_encrypt = 0; 987 info->flags &= ~IEEE80211_TX_INTFL_DONT_ENCRYPT;
969 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG) 988 if (*iterator.this_arg & IEEE80211_RADIOTAP_F_FRAG)
970 tx->flags |= IEEE80211_TX_FRAGMENTED; 989 tx->flags |= IEEE80211_TX_FRAGMENTED;
971 break; 990 break;
@@ -998,13 +1017,12 @@ static bool __ieee80211_parse_tx_radiotap(struct ieee80211_tx_data *tx,
998 * initialises @tx 1017 * initialises @tx
999 */ 1018 */
1000static ieee80211_tx_result 1019static ieee80211_tx_result
1001__ieee80211_tx_prepare(struct ieee80211_tx_data *tx, 1020ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1002 struct sk_buff *skb, 1021 struct ieee80211_tx_data *tx,
1003 struct net_device *dev) 1022 struct sk_buff *skb)
1004{ 1023{
1005 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1024 struct ieee80211_local *local = sdata->local;
1006 struct ieee80211_hdr *hdr; 1025 struct ieee80211_hdr *hdr;
1007 struct ieee80211_sub_if_data *sdata;
1008 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1026 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1009 int hdrlen, tid; 1027 int hdrlen, tid;
1010 u8 *qc, *state; 1028 u8 *qc, *state;
@@ -1012,9 +1030,9 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1012 1030
1013 memset(tx, 0, sizeof(*tx)); 1031 memset(tx, 0, sizeof(*tx));
1014 tx->skb = skb; 1032 tx->skb = skb;
1015 tx->dev = dev; /* use original interface */ 1033 tx->dev = sdata->dev; /* use original interface */
1016 tx->local = local; 1034 tx->local = local;
1017 tx->sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1035 tx->sdata = sdata;
1018 tx->channel = local->hw.conf.channel; 1036 tx->channel = local->hw.conf.channel;
1019 /* 1037 /*
1020 * Set this flag (used below to indicate "automatic fragmentation"), 1038 * Set this flag (used below to indicate "automatic fragmentation"),
@@ -1023,7 +1041,6 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1023 tx->flags |= IEEE80211_TX_FRAGMENTED; 1041 tx->flags |= IEEE80211_TX_FRAGMENTED;
1024 1042
1025 /* process and remove the injection radiotap header */ 1043 /* process and remove the injection radiotap header */
1026 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1027 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) { 1044 if (unlikely(info->flags & IEEE80211_TX_CTL_INJECTED)) {
1028 if (!__ieee80211_parse_tx_radiotap(tx, skb)) 1045 if (!__ieee80211_parse_tx_radiotap(tx, skb))
1029 return TX_DROP; 1046 return TX_DROP;
@@ -1119,50 +1136,28 @@ __ieee80211_tx_prepare(struct ieee80211_tx_data *tx,
1119 return TX_CONTINUE; 1136 return TX_CONTINUE;
1120} 1137}
1121 1138
1122/*
1123 * NB: @tx is uninitialised when passed in here
1124 */
1125static int ieee80211_tx_prepare(struct ieee80211_local *local,
1126 struct ieee80211_tx_data *tx,
1127 struct sk_buff *skb)
1128{
1129 struct net_device *dev;
1130
1131 dev = dev_get_by_index(&init_net, skb->iif);
1132 if (unlikely(dev && !is_ieee80211_device(local, dev))) {
1133 dev_put(dev);
1134 dev = NULL;
1135 }
1136 if (unlikely(!dev))
1137 return -ENODEV;
1138 /*
1139 * initialises tx with control
1140 *
1141 * return value is safe to ignore here because this function
1142 * can only be invoked for multicast frames
1143 *
1144 * XXX: clean up
1145 */
1146 __ieee80211_tx_prepare(tx, skb, dev);
1147 dev_put(dev);
1148 return 0;
1149}
1150
1151static int __ieee80211_tx(struct ieee80211_local *local, 1139static int __ieee80211_tx(struct ieee80211_local *local,
1152 struct sk_buff **skbp, 1140 struct sk_buff **skbp,
1153 struct sta_info *sta) 1141 struct sta_info *sta,
1142 bool txpending)
1154{ 1143{
1155 struct sk_buff *skb = *skbp, *next; 1144 struct sk_buff *skb = *skbp, *next;
1156 struct ieee80211_tx_info *info; 1145 struct ieee80211_tx_info *info;
1146 unsigned long flags;
1157 int ret, len; 1147 int ret, len;
1158 bool fragm = false; 1148 bool fragm = false;
1159 1149
1160 local->mdev->trans_start = jiffies;
1161
1162 while (skb) { 1150 while (skb) {
1163 if (ieee80211_queue_stopped(&local->hw, 1151 int q = skb_get_queue_mapping(skb);
1164 skb_get_queue_mapping(skb))) 1152
1165 return IEEE80211_TX_PENDING; 1153 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
1154 ret = IEEE80211_TX_OK;
1155 if (local->queue_stop_reasons[q] ||
1156 (!txpending && !skb_queue_empty(&local->pending[q])))
1157 ret = IEEE80211_TX_PENDING;
1158 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
1159 if (ret != IEEE80211_TX_OK)
1160 return ret;
1166 1161
1167 info = IEEE80211_SKB_CB(skb); 1162 info = IEEE80211_SKB_CB(skb);
1168 1163
@@ -1234,10 +1229,10 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1234 return 0; 1229 return 0;
1235} 1230}
1236 1231
1237static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb, 1232static void ieee80211_tx(struct ieee80211_sub_if_data *sdata,
1238 bool txpending) 1233 struct sk_buff *skb, bool txpending)
1239{ 1234{
1240 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1235 struct ieee80211_local *local = sdata->local;
1241 struct ieee80211_tx_data tx; 1236 struct ieee80211_tx_data tx;
1242 ieee80211_tx_result res_prepare; 1237 ieee80211_tx_result res_prepare;
1243 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1238 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
@@ -1248,8 +1243,6 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1248 1243
1249 queue = skb_get_queue_mapping(skb); 1244 queue = skb_get_queue_mapping(skb);
1250 1245
1251 WARN_ON(!txpending && !skb_queue_empty(&local->pending[queue]));
1252
1253 if (unlikely(skb->len < 10)) { 1246 if (unlikely(skb->len < 10)) {
1254 dev_kfree_skb(skb); 1247 dev_kfree_skb(skb);
1255 return; 1248 return;
@@ -1258,7 +1251,7 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1258 rcu_read_lock(); 1251 rcu_read_lock();
1259 1252
1260 /* initialises tx */ 1253 /* initialises tx */
1261 res_prepare = __ieee80211_tx_prepare(&tx, skb, dev); 1254 res_prepare = ieee80211_tx_prepare(sdata, &tx, skb);
1262 1255
1263 if (unlikely(res_prepare == TX_DROP)) { 1256 if (unlikely(res_prepare == TX_DROP)) {
1264 dev_kfree_skb(skb); 1257 dev_kfree_skb(skb);
@@ -1277,7 +1270,7 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1277 1270
1278 retries = 0; 1271 retries = 0;
1279 retry: 1272 retry:
1280 ret = __ieee80211_tx(local, &tx.skb, tx.sta); 1273 ret = __ieee80211_tx(local, &tx.skb, tx.sta, txpending);
1281 switch (ret) { 1274 switch (ret) {
1282 case IEEE80211_TX_OK: 1275 case IEEE80211_TX_OK:
1283 break; 1276 break;
@@ -1295,34 +1288,35 @@ static void ieee80211_tx(struct net_device *dev, struct sk_buff *skb,
1295 1288
1296 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 1289 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
1297 1290
1298 if (__netif_subqueue_stopped(local->mdev, queue)) { 1291 if (local->queue_stop_reasons[queue] ||
1292 !skb_queue_empty(&local->pending[queue])) {
1293 /*
1294 * if queue is stopped, queue up frames for later
1295 * transmission from the tasklet
1296 */
1299 do { 1297 do {
1300 next = skb->next; 1298 next = skb->next;
1301 skb->next = NULL; 1299 skb->next = NULL;
1302 if (unlikely(txpending)) 1300 if (unlikely(txpending))
1303 skb_queue_head(&local->pending[queue], 1301 __skb_queue_head(&local->pending[queue],
1304 skb); 1302 skb);
1305 else 1303 else
1306 skb_queue_tail(&local->pending[queue], 1304 __skb_queue_tail(&local->pending[queue],
1307 skb); 1305 skb);
1308 } while ((skb = next)); 1306 } while ((skb = next));
1309 1307
1310 /*
1311 * Make sure nobody will enable the queue on us
1312 * (without going through the tasklet) nor disable the
1313 * netdev queue underneath the pending handling code.
1314 */
1315 __set_bit(IEEE80211_QUEUE_STOP_REASON_PENDING,
1316 &local->queue_stop_reasons[queue]);
1317
1318 spin_unlock_irqrestore(&local->queue_stop_reason_lock, 1308 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
1319 flags); 1309 flags);
1320 } else { 1310 } else {
1311 /*
1312 * otherwise retry, but this is a race condition or
1313 * a driver bug (which we warn about if it persists)
1314 */
1321 spin_unlock_irqrestore(&local->queue_stop_reason_lock, 1315 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
1322 flags); 1316 flags);
1323 1317
1324 retries++; 1318 retries++;
1325 if (WARN(retries > 10, "tx refused but queue active")) 1319 if (WARN(retries > 10, "tx refused but queue active\n"))
1326 goto drop; 1320 goto drop;
1327 goto retry; 1321 goto retry;
1328 } 1322 }
@@ -1383,14 +1377,13 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
1383 return 0; 1377 return 0;
1384} 1378}
1385 1379
1386int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev) 1380static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1381 struct sk_buff *skb)
1387{ 1382{
1388 struct ieee80211_master_priv *mpriv = netdev_priv(dev); 1383 struct ieee80211_local *local = sdata->local;
1389 struct ieee80211_local *local = mpriv->local;
1390 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 1384 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1391 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1385 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1392 struct net_device *odev = NULL; 1386 struct ieee80211_sub_if_data *tmp_sdata;
1393 struct ieee80211_sub_if_data *osdata;
1394 int headroom; 1387 int headroom;
1395 bool may_encrypt; 1388 bool may_encrypt;
1396 enum { 1389 enum {
@@ -1399,20 +1392,7 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1399 UNKNOWN_ADDRESS, 1392 UNKNOWN_ADDRESS,
1400 } monitor_iface = NOT_MONITOR; 1393 } monitor_iface = NOT_MONITOR;
1401 1394
1402 if (skb->iif) 1395 dev_hold(sdata->dev);
1403 odev = dev_get_by_index(&init_net, skb->iif);
1404 if (unlikely(odev && !is_ieee80211_device(local, odev))) {
1405 dev_put(odev);
1406 odev = NULL;
1407 }
1408 if (unlikely(!odev)) {
1409#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
1410 printk(KERN_DEBUG "%s: Discarded packet with nonexistent "
1411 "originating device\n", dev->name);
1412#endif
1413 dev_kfree_skb(skb);
1414 return NETDEV_TX_OK;
1415 }
1416 1396
1417 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) && 1397 if ((local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK) &&
1418 local->hw.conf.dynamic_ps_timeout > 0 && 1398 local->hw.conf.dynamic_ps_timeout > 0 &&
@@ -1428,26 +1408,18 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1428 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout)); 1408 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
1429 } 1409 }
1430 1410
1431 memset(info, 0, sizeof(*info));
1432
1433 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS; 1411 info->flags |= IEEE80211_TX_CTL_REQ_TX_STATUS;
1434 1412
1435 osdata = IEEE80211_DEV_TO_SUB_IF(odev); 1413 if (ieee80211_vif_is_mesh(&sdata->vif) &&
1436
1437 if (ieee80211_vif_is_mesh(&osdata->vif) &&
1438 ieee80211_is_data(hdr->frame_control)) { 1414 ieee80211_is_data(hdr->frame_control)) {
1439 if (is_multicast_ether_addr(hdr->addr3)) 1415 if (is_multicast_ether_addr(hdr->addr3))
1440 memcpy(hdr->addr1, hdr->addr3, ETH_ALEN); 1416 memcpy(hdr->addr1, hdr->addr3, ETH_ALEN);
1441 else 1417 else
1442 if (mesh_nexthop_lookup(skb, osdata)) { 1418 if (mesh_nexthop_lookup(skb, sdata)) {
1443 dev_put(odev); 1419 dev_put(sdata->dev);
1444 return NETDEV_TX_OK; 1420 return;
1445 } 1421 }
1446 if (memcmp(odev->dev_addr, hdr->addr4, ETH_ALEN) != 0) 1422 } else if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {
1447 IEEE80211_IFSTA_MESH_CTR_INC(&osdata->u.mesh,
1448 fwded_frames);
1449 } else if (unlikely(osdata->vif.type == NL80211_IFTYPE_MONITOR)) {
1450 struct ieee80211_sub_if_data *sdata;
1451 int hdrlen; 1423 int hdrlen;
1452 u16 len_rthdr; 1424 u16 len_rthdr;
1453 1425
@@ -1471,19 +1443,17 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1471 */ 1443 */
1472 1444
1473 rcu_read_lock(); 1445 rcu_read_lock();
1474 list_for_each_entry_rcu(sdata, &local->interfaces, 1446 list_for_each_entry_rcu(tmp_sdata, &local->interfaces,
1475 list) { 1447 list) {
1476 if (!netif_running(sdata->dev)) 1448 if (!netif_running(tmp_sdata->dev))
1477 continue; 1449 continue;
1478 if (sdata->vif.type != NL80211_IFTYPE_AP) 1450 if (tmp_sdata->vif.type != NL80211_IFTYPE_AP)
1479 continue; 1451 continue;
1480 if (compare_ether_addr(sdata->dev->dev_addr, 1452 if (compare_ether_addr(tmp_sdata->dev->dev_addr,
1481 hdr->addr2)) { 1453 hdr->addr2)) {
1482 dev_hold(sdata->dev); 1454 dev_hold(tmp_sdata->dev);
1483 dev_put(odev); 1455 dev_put(sdata->dev);
1484 osdata = sdata; 1456 sdata = tmp_sdata;
1485 odev = osdata->dev;
1486 skb->iif = sdata->dev->ifindex;
1487 monitor_iface = FOUND_SDATA; 1457 monitor_iface = FOUND_SDATA;
1488 break; 1458 break;
1489 } 1459 }
@@ -1492,31 +1462,31 @@ int ieee80211_master_start_xmit(struct sk_buff *skb, struct net_device *dev)
1492 } 1462 }
1493 } 1463 }
1494 1464
1495 may_encrypt = !skb->do_not_encrypt; 1465 may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT);
1496 1466
1497 headroom = osdata->local->tx_headroom; 1467 headroom = local->tx_headroom;
1498 if (may_encrypt) 1468 if (may_encrypt)
1499 headroom += IEEE80211_ENCRYPT_HEADROOM; 1469 headroom += IEEE80211_ENCRYPT_HEADROOM;
1500 headroom -= skb_headroom(skb); 1470 headroom -= skb_headroom(skb);
1501 headroom = max_t(int, 0, headroom); 1471 headroom = max_t(int, 0, headroom);
1502 1472
1503 if (ieee80211_skb_resize(osdata->local, skb, headroom, may_encrypt)) { 1473 if (ieee80211_skb_resize(local, skb, headroom, may_encrypt)) {
1504 dev_kfree_skb(skb); 1474 dev_kfree_skb(skb);
1505 dev_put(odev); 1475 dev_put(sdata->dev);
1506 return NETDEV_TX_OK; 1476 return;
1507 } 1477 }
1508 1478
1509 if (osdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1479 tmp_sdata = sdata;
1510 osdata = container_of(osdata->bss, 1480 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1511 struct ieee80211_sub_if_data, 1481 tmp_sdata = container_of(sdata->bss,
1512 u.ap); 1482 struct ieee80211_sub_if_data,
1483 u.ap);
1513 if (likely(monitor_iface != UNKNOWN_ADDRESS)) 1484 if (likely(monitor_iface != UNKNOWN_ADDRESS))
1514 info->control.vif = &osdata->vif; 1485 info->control.vif = &tmp_sdata->vif;
1515
1516 ieee80211_tx(odev, skb, false);
1517 dev_put(odev);
1518 1486
1519 return NETDEV_TX_OK; 1487 ieee80211_select_queue(local, skb);
1488 ieee80211_tx(sdata, skb, false);
1489 dev_put(sdata->dev);
1520} 1490}
1521 1491
1522int ieee80211_monitor_start_xmit(struct sk_buff *skb, 1492int ieee80211_monitor_start_xmit(struct sk_buff *skb,
@@ -1526,6 +1496,7 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
1526 struct ieee80211_channel *chan = local->hw.conf.channel; 1496 struct ieee80211_channel *chan = local->hw.conf.channel;
1527 struct ieee80211_radiotap_header *prthdr = 1497 struct ieee80211_radiotap_header *prthdr =
1528 (struct ieee80211_radiotap_header *)skb->data; 1498 (struct ieee80211_radiotap_header *)skb->data;
1499 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1529 u16 len_rthdr; 1500 u16 len_rthdr;
1530 1501
1531 /* 1502 /*
@@ -1563,15 +1534,9 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
1563 if (unlikely(skb->len < len_rthdr)) 1534 if (unlikely(skb->len < len_rthdr))
1564 goto fail; /* skb too short for claimed rt header extent */ 1535 goto fail; /* skb too short for claimed rt header extent */
1565 1536
1566 skb->dev = local->mdev;
1567
1568 /* needed because we set skb device to master */ 1537 /* needed because we set skb device to master */
1569 skb->iif = dev->ifindex; 1538 skb->iif = dev->ifindex;
1570 1539
1571 /* sometimes we do encrypt injected frames, will be fixed
1572 * up in radiotap parser if not wanted */
1573 skb->do_not_encrypt = 0;
1574
1575 /* 1540 /*
1576 * fix up the pointers accounting for the radiotap 1541 * fix up the pointers accounting for the radiotap
1577 * header still being in there. We are being given 1542 * header still being in there. We are being given
@@ -1586,8 +1551,10 @@ int ieee80211_monitor_start_xmit(struct sk_buff *skb,
1586 skb_set_network_header(skb, len_rthdr); 1551 skb_set_network_header(skb, len_rthdr);
1587 skb_set_transport_header(skb, len_rthdr); 1552 skb_set_transport_header(skb, len_rthdr);
1588 1553
1589 /* pass the radiotap header up to the next stage intact */ 1554 memset(info, 0, sizeof(*info));
1590 dev_queue_xmit(skb); 1555
1556 /* pass the radiotap header up to xmit */
1557 ieee80211_xmit(IEEE80211_DEV_TO_SUB_IF(dev), skb);
1591 return NETDEV_TX_OK; 1558 return NETDEV_TX_OK;
1592 1559
1593fail: 1560fail:
@@ -1615,6 +1582,7 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1615{ 1582{
1616 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1583 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1617 struct ieee80211_local *local = sdata->local; 1584 struct ieee80211_local *local = sdata->local;
1585 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
1618 int ret = NETDEV_TX_BUSY, head_need; 1586 int ret = NETDEV_TX_BUSY, head_need;
1619 u16 ethertype, hdrlen, meshhdrlen = 0; 1587 u16 ethertype, hdrlen, meshhdrlen = 0;
1620 __le16 fc; 1588 __le16 fc;
@@ -1844,7 +1812,6 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1844 1812
1845 skb->iif = dev->ifindex; 1813 skb->iif = dev->ifindex;
1846 1814
1847 skb->dev = local->mdev;
1848 dev->stats.tx_packets++; 1815 dev->stats.tx_packets++;
1849 dev->stats.tx_bytes += skb->len; 1816 dev->stats.tx_bytes += skb->len;
1850 1817
@@ -1855,8 +1822,10 @@ int ieee80211_subif_start_xmit(struct sk_buff *skb,
1855 skb_set_network_header(skb, nh_pos); 1822 skb_set_network_header(skb, nh_pos);
1856 skb_set_transport_header(skb, h_pos); 1823 skb_set_transport_header(skb, h_pos);
1857 1824
1825 memset(info, 0, sizeof(*info));
1826
1858 dev->trans_start = jiffies; 1827 dev->trans_start = jiffies;
1859 dev_queue_xmit(skb); 1828 ieee80211_xmit(sdata, skb);
1860 1829
1861 return NETDEV_TX_OK; 1830 return NETDEV_TX_OK;
1862 1831
@@ -1898,7 +1867,6 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1898 return true; 1867 return true;
1899 } 1868 }
1900 1869
1901 /* validate info->control.vif against skb->iif */
1902 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1870 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1903 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1871 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN)
1904 sdata = container_of(sdata->bss, 1872 sdata = container_of(sdata->bss,
@@ -1912,12 +1880,13 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1912 } 1880 }
1913 1881
1914 if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) { 1882 if (info->flags & IEEE80211_TX_INTFL_NEED_TXPROCESSING) {
1915 ieee80211_tx(dev, skb, true); 1883 /* do not use sdata, it may have been changed above */
1884 ieee80211_tx(IEEE80211_DEV_TO_SUB_IF(dev), skb, true);
1916 } else { 1885 } else {
1917 hdr = (struct ieee80211_hdr *)skb->data; 1886 hdr = (struct ieee80211_hdr *)skb->data;
1918 sta = sta_info_get(local, hdr->addr1); 1887 sta = sta_info_get(local, hdr->addr1);
1919 1888
1920 ret = __ieee80211_tx(local, &skb, sta); 1889 ret = __ieee80211_tx(local, &skb, sta, true);
1921 if (ret != IEEE80211_TX_OK) 1890 if (ret != IEEE80211_TX_OK)
1922 result = false; 1891 result = false;
1923 } 1892 }
@@ -1929,59 +1898,43 @@ static bool ieee80211_tx_pending_skb(struct ieee80211_local *local,
1929} 1898}
1930 1899
1931/* 1900/*
1932 * Transmit all pending packets. Called from tasklet, locks master device 1901 * Transmit all pending packets. Called from tasklet.
1933 * TX lock so that no new packets can come in.
1934 */ 1902 */
1935void ieee80211_tx_pending(unsigned long data) 1903void ieee80211_tx_pending(unsigned long data)
1936{ 1904{
1937 struct ieee80211_local *local = (struct ieee80211_local *)data; 1905 struct ieee80211_local *local = (struct ieee80211_local *)data;
1938 struct net_device *dev = local->mdev;
1939 unsigned long flags; 1906 unsigned long flags;
1940 int i; 1907 int i;
1941 bool next; 1908 bool txok;
1942 1909
1943 rcu_read_lock(); 1910 rcu_read_lock();
1944 netif_tx_lock_bh(dev);
1945 1911
1912 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
1946 for (i = 0; i < local->hw.queues; i++) { 1913 for (i = 0; i < local->hw.queues; i++) {
1947 /* 1914 /*
1948 * If queue is stopped by something other than due to pending 1915 * If queue is stopped by something other than due to pending
1949 * frames, or we have no pending frames, proceed to next queue. 1916 * frames, or we have no pending frames, proceed to next queue.
1950 */ 1917 */
1951 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 1918 if (local->queue_stop_reasons[i] ||
1952 next = false;
1953 if (local->queue_stop_reasons[i] !=
1954 BIT(IEEE80211_QUEUE_STOP_REASON_PENDING) ||
1955 skb_queue_empty(&local->pending[i])) 1919 skb_queue_empty(&local->pending[i]))
1956 next = true;
1957 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
1958
1959 if (next)
1960 continue; 1920 continue;
1961 1921
1962 /*
1963 * start the queue now to allow processing our packets,
1964 * we're under the tx lock here anyway so nothing will
1965 * happen as a result of this
1966 */
1967 netif_start_subqueue(local->mdev, i);
1968
1969 while (!skb_queue_empty(&local->pending[i])) { 1922 while (!skb_queue_empty(&local->pending[i])) {
1970 struct sk_buff *skb = skb_dequeue(&local->pending[i]); 1923 struct sk_buff *skb = __skb_dequeue(&local->pending[i]);
1971 1924 spin_unlock_irqrestore(&local->queue_stop_reason_lock,
1972 if (!ieee80211_tx_pending_skb(local, skb)) { 1925 flags);
1973 skb_queue_head(&local->pending[i], skb); 1926
1927 txok = ieee80211_tx_pending_skb(local, skb);
1928 if (!txok)
1929 __skb_queue_head(&local->pending[i], skb);
1930 spin_lock_irqsave(&local->queue_stop_reason_lock,
1931 flags);
1932 if (!txok)
1974 break; 1933 break;
1975 }
1976 } 1934 }
1977
1978 /* Start regular packet processing again. */
1979 if (skb_queue_empty(&local->pending[i]))
1980 ieee80211_wake_queue_by_reason(&local->hw, i,
1981 IEEE80211_QUEUE_STOP_REASON_PENDING);
1982 } 1935 }
1936 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
1983 1937
1984 netif_tx_unlock_bh(dev);
1985 rcu_read_unlock(); 1938 rcu_read_unlock();
1986} 1939}
1987 1940
@@ -2156,8 +2109,7 @@ struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
2156 2109
2157 info = IEEE80211_SKB_CB(skb); 2110 info = IEEE80211_SKB_CB(skb);
2158 2111
2159 skb->do_not_encrypt = 1; 2112 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
2160
2161 info->band = band; 2113 info->band = band;
2162 /* 2114 /*
2163 * XXX: For now, always use the lowest rate 2115 * XXX: For now, always use the lowest rate
@@ -2228,9 +2180,6 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2228 sdata = vif_to_sdata(vif); 2180 sdata = vif_to_sdata(vif);
2229 bss = &sdata->u.ap; 2181 bss = &sdata->u.ap;
2230 2182
2231 if (!bss)
2232 return NULL;
2233
2234 rcu_read_lock(); 2183 rcu_read_lock();
2235 beacon = rcu_dereference(bss->beacon); 2184 beacon = rcu_dereference(bss->beacon);
2236 2185
@@ -2256,7 +2205,7 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2256 cpu_to_le16(IEEE80211_FCTL_MOREDATA); 2205 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
2257 } 2206 }
2258 2207
2259 if (!ieee80211_tx_prepare(local, &tx, skb)) 2208 if (!ieee80211_tx_prepare(sdata, &tx, skb))
2260 break; 2209 break;
2261 dev_kfree_skb_any(skb); 2210 dev_kfree_skb_any(skb);
2262 } 2211 }
@@ -2276,3 +2225,25 @@ ieee80211_get_buffered_bc(struct ieee80211_hw *hw,
2276 return skb; 2225 return skb;
2277} 2226}
2278EXPORT_SYMBOL(ieee80211_get_buffered_bc); 2227EXPORT_SYMBOL(ieee80211_get_buffered_bc);
2228
2229void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
2230 int encrypt)
2231{
2232 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2233 skb_set_mac_header(skb, 0);
2234 skb_set_network_header(skb, 0);
2235 skb_set_transport_header(skb, 0);
2236
2237 skb->iif = sdata->dev->ifindex;
2238 if (!encrypt)
2239 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
2240
2241 /*
2242 * The other path calling ieee80211_xmit is from the tasklet,
2243 * and while we can handle concurrent transmissions locking
2244 * requirements are that we do not come into tx with bhs on.
2245 */
2246 local_bh_disable();
2247 ieee80211_xmit(sdata, skb);
2248 local_bh_enable();
2249}
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 915e77769312..7fc55846d601 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -31,6 +31,7 @@
31#include "mesh.h" 31#include "mesh.h"
32#include "wme.h" 32#include "wme.h"
33#include "led.h" 33#include "led.h"
34#include "wep.h"
34 35
35/* privid for wiphys to determine whether they belong to us or not */ 36/* privid for wiphys to determine whether they belong to us or not */
36void *mac80211_wiphy_privid = &mac80211_wiphy_privid; 37void *mac80211_wiphy_privid = &mac80211_wiphy_privid;
@@ -274,16 +275,12 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
274 275
275 __clear_bit(reason, &local->queue_stop_reasons[queue]); 276 __clear_bit(reason, &local->queue_stop_reasons[queue]);
276 277
277 if (!skb_queue_empty(&local->pending[queue]) &&
278 local->queue_stop_reasons[queue] ==
279 BIT(IEEE80211_QUEUE_STOP_REASON_PENDING))
280 tasklet_schedule(&local->tx_pending_tasklet);
281
282 if (local->queue_stop_reasons[queue] != 0) 278 if (local->queue_stop_reasons[queue] != 0)
283 /* someone still has this queue stopped */ 279 /* someone still has this queue stopped */
284 return; 280 return;
285 281
286 netif_wake_subqueue(local->mdev, queue); 282 if (!skb_queue_empty(&local->pending[queue]))
283 tasklet_schedule(&local->tx_pending_tasklet);
287} 284}
288 285
289void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 286void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -312,14 +309,6 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
312 if (WARN_ON(queue >= hw->queues)) 309 if (WARN_ON(queue >= hw->queues))
313 return; 310 return;
314 311
315 /*
316 * Only stop if it was previously running, this is necessary
317 * for correct pending packets handling because there we may
318 * start (but not wake) the queue and rely on that.
319 */
320 if (!local->queue_stop_reasons[queue])
321 netif_stop_subqueue(local->mdev, queue);
322
323 __set_bit(reason, &local->queue_stop_reasons[queue]); 312 __set_bit(reason, &local->queue_stop_reasons[queue]);
324} 313}
325 314
@@ -350,8 +339,7 @@ void ieee80211_add_pending_skb(struct ieee80211_local *local,
350 339
351 spin_lock_irqsave(&local->queue_stop_reason_lock, flags); 340 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
352 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 341 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
353 __ieee80211_stop_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_PENDING); 342 __skb_queue_tail(&local->pending[queue], skb);
354 skb_queue_tail(&local->pending[queue], skb);
355 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 343 __ieee80211_wake_queue(hw, queue, IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
356 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 344 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
357} 345}
@@ -372,16 +360,12 @@ int ieee80211_add_pending_skbs(struct ieee80211_local *local,
372 while ((skb = skb_dequeue(skbs))) { 360 while ((skb = skb_dequeue(skbs))) {
373 ret++; 361 ret++;
374 queue = skb_get_queue_mapping(skb); 362 queue = skb_get_queue_mapping(skb);
375 skb_queue_tail(&local->pending[queue], skb); 363 __skb_queue_tail(&local->pending[queue], skb);
376 } 364 }
377 365
378 for (i = 0; i < hw->queues; i++) { 366 for (i = 0; i < hw->queues; i++)
379 if (ret)
380 __ieee80211_stop_queue(hw, i,
381 IEEE80211_QUEUE_STOP_REASON_PENDING);
382 __ieee80211_wake_queue(hw, i, 367 __ieee80211_wake_queue(hw, i,
383 IEEE80211_QUEUE_STOP_REASON_SKB_ADD); 368 IEEE80211_QUEUE_STOP_REASON_SKB_ADD);
384 }
385 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); 369 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
386 370
387 return ret; 371 return ret;
@@ -412,11 +396,16 @@ EXPORT_SYMBOL(ieee80211_stop_queues);
412int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue) 396int ieee80211_queue_stopped(struct ieee80211_hw *hw, int queue)
413{ 397{
414 struct ieee80211_local *local = hw_to_local(hw); 398 struct ieee80211_local *local = hw_to_local(hw);
399 unsigned long flags;
400 int ret;
415 401
416 if (WARN_ON(queue >= hw->queues)) 402 if (WARN_ON(queue >= hw->queues))
417 return true; 403 return true;
418 404
419 return __netif_subqueue_stopped(local->mdev, queue); 405 spin_lock_irqsave(&local->queue_stop_reason_lock, flags);
406 ret = !!local->queue_stop_reasons[queue];
407 spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
408 return ret;
420} 409}
421EXPORT_SYMBOL(ieee80211_queue_stopped); 410EXPORT_SYMBOL(ieee80211_queue_stopped);
422 411
@@ -760,20 +749,6 @@ void ieee80211_sta_def_wmm_params(struct ieee80211_sub_if_data *sdata,
760 ieee80211_set_wmm_default(sdata); 749 ieee80211_set_wmm_default(sdata);
761} 750}
762 751
763void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb,
764 int encrypt)
765{
766 skb->dev = sdata->local->mdev;
767 skb_set_mac_header(skb, 0);
768 skb_set_network_header(skb, 0);
769 skb_set_transport_header(skb, 0);
770
771 skb->iif = sdata->dev->ifindex;
772 skb->do_not_encrypt = !encrypt;
773
774 dev_queue_xmit(skb);
775}
776
777u32 ieee80211_mandatory_rates(struct ieee80211_local *local, 752u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
778 enum ieee80211_band band) 753 enum ieee80211_band band)
779{ 754{
@@ -804,12 +779,13 @@ u32 ieee80211_mandatory_rates(struct ieee80211_local *local,
804 779
805void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, 780void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
806 u16 transaction, u16 auth_alg, 781 u16 transaction, u16 auth_alg,
807 u8 *extra, size_t extra_len, 782 u8 *extra, size_t extra_len, const u8 *bssid,
808 const u8 *bssid, int encrypt) 783 const u8 *key, u8 key_len, u8 key_idx)
809{ 784{
810 struct ieee80211_local *local = sdata->local; 785 struct ieee80211_local *local = sdata->local;
811 struct sk_buff *skb; 786 struct sk_buff *skb;
812 struct ieee80211_mgmt *mgmt; 787 struct ieee80211_mgmt *mgmt;
788 int err;
813 789
814 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 790 skb = dev_alloc_skb(local->hw.extra_tx_headroom +
815 sizeof(*mgmt) + 6 + extra_len); 791 sizeof(*mgmt) + 6 + extra_len);
@@ -824,8 +800,6 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
824 memset(mgmt, 0, 24 + 6); 800 memset(mgmt, 0, 24 + 6);
825 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 801 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
826 IEEE80211_STYPE_AUTH); 802 IEEE80211_STYPE_AUTH);
827 if (encrypt)
828 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
829 memcpy(mgmt->da, bssid, ETH_ALEN); 803 memcpy(mgmt->da, bssid, ETH_ALEN);
830 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN); 804 memcpy(mgmt->sa, sdata->dev->dev_addr, ETH_ALEN);
831 memcpy(mgmt->bssid, bssid, ETH_ALEN); 805 memcpy(mgmt->bssid, bssid, ETH_ALEN);
@@ -835,7 +809,13 @@ void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
835 if (extra) 809 if (extra)
836 memcpy(skb_put(skb, extra_len), extra, extra_len); 810 memcpy(skb_put(skb, extra_len), extra, extra_len);
837 811
838 ieee80211_tx_skb(sdata, skb, encrypt); 812 if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) {
813 mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED);
814 err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx);
815 WARN_ON(err);
816 }
817
818 ieee80211_tx_skb(sdata, skb, 0);
839} 819}
840 820
841int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer, 821int ieee80211_build_preq_ies(struct ieee80211_local *local, u8 *buffer,
@@ -1043,9 +1023,9 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1043 /* reconfigure hardware */ 1023 /* reconfigure hardware */
1044 ieee80211_hw_config(local, ~0); 1024 ieee80211_hw_config(local, ~0);
1045 1025
1046 netif_addr_lock_bh(local->mdev); 1026 spin_lock_bh(&local->filter_lock);
1047 ieee80211_configure_filter(local); 1027 ieee80211_configure_filter(local);
1048 netif_addr_unlock_bh(local->mdev); 1028 spin_unlock_bh(&local->filter_lock);
1049 1029
1050 /* Finally also reconfigure all the BSS information */ 1030 /* Finally also reconfigure all the BSS information */
1051 list_for_each_entry(sdata, &local->interfaces, list) { 1031 list_for_each_entry(sdata, &local->interfaces, list) {
diff --git a/net/mac80211/wep.c b/net/mac80211/wep.c
index 4fafb2d27c84..8a980f136941 100644
--- a/net/mac80211/wep.c
+++ b/net/mac80211/wep.c
@@ -144,9 +144,9 @@ void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
144 * 144 *
145 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data)) 145 * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
146 */ 146 */
147static int ieee80211_wep_encrypt(struct ieee80211_local *local, 147int ieee80211_wep_encrypt(struct ieee80211_local *local,
148 struct sk_buff *skb, 148 struct sk_buff *skb,
149 const u8 *key, int keylen, int keyidx) 149 const u8 *key, int keylen, int keyidx)
150{ 150{
151 u8 *iv; 151 u8 *iv;
152 size_t len; 152 size_t len;
diff --git a/net/mac80211/wep.h b/net/mac80211/wep.h
index 85219ded8703..fe29d7e5759f 100644
--- a/net/mac80211/wep.h
+++ b/net/mac80211/wep.h
@@ -20,6 +20,9 @@ int ieee80211_wep_init(struct ieee80211_local *local);
20void ieee80211_wep_free(struct ieee80211_local *local); 20void ieee80211_wep_free(struct ieee80211_local *local);
21void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 21void ieee80211_wep_encrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
22 size_t klen, u8 *data, size_t data_len); 22 size_t klen, u8 *data, size_t data_len);
23int ieee80211_wep_encrypt(struct ieee80211_local *local,
24 struct sk_buff *skb,
25 const u8 *key, int keylen, int keyidx);
23int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key, 26int ieee80211_wep_decrypt_data(struct crypto_blkcipher *tfm, u8 *rc4key,
24 size_t klen, u8 *data, size_t data_len); 27 size_t klen, u8 *data, size_t data_len);
25bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key); 28bool ieee80211_wep_is_weak_iv(struct sk_buff *skb, struct ieee80211_key *key);
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index 116a923b14d6..b19b7696f3a2 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -85,10 +85,8 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
85 return ieee802_1d_to_ac[skb->priority]; 85 return ieee802_1d_to_ac[skb->priority];
86} 86}
87 87
88u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb) 88void ieee80211_select_queue(struct ieee80211_local *local, struct sk_buff *skb)
89{ 89{
90 struct ieee80211_master_priv *mpriv = netdev_priv(dev);
91 struct ieee80211_local *local = mpriv->local;
92 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 90 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
93 u16 queue; 91 u16 queue;
94 u8 tid; 92 u8 tid;
@@ -113,5 +111,5 @@ u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb)
113 *p = 0; 111 *p = 0;
114 } 112 }
115 113
116 return queue; 114 skb_set_queue_mapping(skb, queue);
117} 115}
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index 7520d2e014dc..d4fd87ca5118 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -20,6 +20,7 @@
20 20
21extern const int ieee802_1d_to_ac[8]; 21extern const int ieee802_1d_to_ac[8];
22 22
23u16 ieee80211_select_queue(struct net_device *dev, struct sk_buff *skb); 23void ieee80211_select_queue(struct ieee80211_local *local,
24 struct sk_buff *skb);
24 25
25#endif /* _WME_H */ 26#endif /* _WME_H */
diff --git a/net/wireless/core.c b/net/wireless/core.c
index 1a78b3c70cf2..6891cd0e38d5 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -548,11 +548,6 @@ void wiphy_unregister(struct wiphy *wiphy)
548 /* unlock again before freeing */ 548 /* unlock again before freeing */
549 mutex_unlock(&rdev->mtx); 549 mutex_unlock(&rdev->mtx);
550 550
551 cancel_work_sync(&rdev->conn_work);
552 cancel_work_sync(&rdev->scan_done_wk);
553 kfree(rdev->scan_req);
554 flush_work(&rdev->event_work);
555
556 cfg80211_debugfs_rdev_del(rdev); 551 cfg80211_debugfs_rdev_del(rdev);
557 552
558 /* If this device got a regulatory hint tell core its 553 /* If this device got a regulatory hint tell core its
@@ -564,6 +559,11 @@ void wiphy_unregister(struct wiphy *wiphy)
564 debugfs_remove(rdev->wiphy.debugfsdir); 559 debugfs_remove(rdev->wiphy.debugfsdir);
565 560
566 mutex_unlock(&cfg80211_mutex); 561 mutex_unlock(&cfg80211_mutex);
562
563 cancel_work_sync(&rdev->conn_work);
564 cancel_work_sync(&rdev->scan_done_wk);
565 kfree(rdev->scan_req);
566 flush_work(&rdev->event_work);
567} 567}
568EXPORT_SYMBOL(wiphy_unregister); 568EXPORT_SYMBOL(wiphy_unregister);
569 569
@@ -666,14 +666,10 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
666 wdev_lock(wdev); 666 wdev_lock(wdev);
667 switch (wdev->iftype) { 667 switch (wdev->iftype) {
668 case NL80211_IFTYPE_ADHOC: 668 case NL80211_IFTYPE_ADHOC:
669 if (wdev->wext.ibss.ssid_len) 669 cfg80211_ibss_wext_join(rdev, wdev);
670 __cfg80211_join_ibss(rdev, dev,
671 &wdev->wext.ibss);
672 break; 670 break;
673 case NL80211_IFTYPE_STATION: 671 case NL80211_IFTYPE_STATION:
674 if (wdev->wext.connect.ssid_len) 672 cfg80211_mgd_wext_connect(rdev, wdev);
675 __cfg80211_connect(rdev, dev,
676 &wdev->wext.connect);
677 break; 673 break;
678 default: 674 default:
679 break; 675 break;
@@ -690,6 +686,9 @@ static int cfg80211_netdev_notifier_call(struct notifier_block * nb,
690 } 686 }
691 mutex_unlock(&rdev->devlist_mtx); 687 mutex_unlock(&rdev->devlist_mtx);
692 mutex_destroy(&wdev->mtx); 688 mutex_destroy(&wdev->mtx);
689#ifdef CONFIG_WIRELESS_EXT
690 kfree(wdev->wext.keys);
691#endif
693 break; 692 break;
694 case NETDEV_PRE_UP: 693 case NETDEV_PRE_UP:
695 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) 694 if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype)))
diff --git a/net/wireless/core.h b/net/wireless/core.h
index e46cd6eb61d7..2ec8ddbe57de 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -238,6 +238,12 @@ struct cfg80211_event {
238 }; 238 };
239}; 239};
240 240
241struct cfg80211_cached_keys {
242 struct key_params params[6];
243 u8 data[6][WLAN_MAX_KEY_LEN];
244 int def, defmgmt;
245};
246
241 247
242/* free object */ 248/* free object */
243extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev); 249extern void cfg80211_dev_free(struct cfg80211_registered_device *rdev);
@@ -256,14 +262,18 @@ void cfg80211_bss_age(struct cfg80211_registered_device *dev,
256/* IBSS */ 262/* IBSS */
257int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 263int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
258 struct net_device *dev, 264 struct net_device *dev,
259 struct cfg80211_ibss_params *params); 265 struct cfg80211_ibss_params *params,
266 struct cfg80211_cached_keys *connkeys);
260int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 267int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
261 struct net_device *dev, 268 struct net_device *dev,
262 struct cfg80211_ibss_params *params); 269 struct cfg80211_ibss_params *params,
270 struct cfg80211_cached_keys *connkeys);
263void cfg80211_clear_ibss(struct net_device *dev, bool nowext); 271void cfg80211_clear_ibss(struct net_device *dev, bool nowext);
264int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev, 272int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
265 struct net_device *dev, bool nowext); 273 struct net_device *dev, bool nowext);
266void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid); 274void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid);
275int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
276 struct wireless_dev *wdev);
267 277
268/* MLME */ 278/* MLME */
269int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 279int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
@@ -272,12 +282,14 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
272 enum nl80211_auth_type auth_type, 282 enum nl80211_auth_type auth_type,
273 const u8 *bssid, 283 const u8 *bssid,
274 const u8 *ssid, int ssid_len, 284 const u8 *ssid, int ssid_len,
275 const u8 *ie, int ie_len); 285 const u8 *ie, int ie_len,
286 const u8 *key, int key_len, int key_idx);
276int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev, 287int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
277 struct net_device *dev, struct ieee80211_channel *chan, 288 struct net_device *dev, struct ieee80211_channel *chan,
278 enum nl80211_auth_type auth_type, const u8 *bssid, 289 enum nl80211_auth_type auth_type, const u8 *bssid,
279 const u8 *ssid, int ssid_len, 290 const u8 *ssid, int ssid_len,
280 const u8 *ie, int ie_len); 291 const u8 *ie, int ie_len,
292 const u8 *key, int key_len, int key_idx);
281int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev, 293int __cfg80211_mlme_assoc(struct cfg80211_registered_device *rdev,
282 struct net_device *dev, 294 struct net_device *dev,
283 struct ieee80211_channel *chan, 295 struct ieee80211_channel *chan,
@@ -310,10 +322,12 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
310/* SME */ 322/* SME */
311int __cfg80211_connect(struct cfg80211_registered_device *rdev, 323int __cfg80211_connect(struct cfg80211_registered_device *rdev,
312 struct net_device *dev, 324 struct net_device *dev,
313 struct cfg80211_connect_params *connect); 325 struct cfg80211_connect_params *connect,
326 struct cfg80211_cached_keys *connkeys);
314int cfg80211_connect(struct cfg80211_registered_device *rdev, 327int cfg80211_connect(struct cfg80211_registered_device *rdev,
315 struct net_device *dev, 328 struct net_device *dev,
316 struct cfg80211_connect_params *connect); 329 struct cfg80211_connect_params *connect,
330 struct cfg80211_cached_keys *connkeys);
317int __cfg80211_disconnect(struct cfg80211_registered_device *rdev, 331int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
318 struct net_device *dev, u16 reason, 332 struct net_device *dev, u16 reason,
319 bool wextev); 333 bool wextev);
@@ -323,11 +337,14 @@ int cfg80211_disconnect(struct cfg80211_registered_device *rdev,
323void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid, 337void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
324 const u8 *req_ie, size_t req_ie_len, 338 const u8 *req_ie, size_t req_ie_len,
325 const u8 *resp_ie, size_t resp_ie_len); 339 const u8 *resp_ie, size_t resp_ie_len);
340int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
341 struct wireless_dev *wdev);
326 342
327void cfg80211_conn_work(struct work_struct *work); 343void cfg80211_conn_work(struct work_struct *work);
328 344
329/* internal helpers */ 345/* internal helpers */
330int cfg80211_validate_key_settings(struct key_params *params, int key_idx, 346int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
347 struct key_params *params, int key_idx,
331 const u8 *mac_addr); 348 const u8 *mac_addr);
332void __cfg80211_disconnected(struct net_device *dev, const u8 *ie, 349void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
333 size_t ie_len, u16 reason, bool from_ap); 350 size_t ie_len, u16 reason, bool from_ap);
@@ -335,5 +352,6 @@ void cfg80211_sme_scan_done(struct net_device *dev);
335void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len); 352void cfg80211_sme_rx_auth(struct net_device *dev, const u8 *buf, size_t len);
336void cfg80211_sme_disassoc(struct net_device *dev, int idx); 353void cfg80211_sme_disassoc(struct net_device *dev, int idx);
337void __cfg80211_scan_done(struct work_struct *wk); 354void __cfg80211_scan_done(struct work_struct *wk);
355void cfg80211_upload_connect_keys(struct wireless_dev *wdev);
338 356
339#endif /* __NET_WIRELESS_CORE_H */ 357#endif /* __NET_WIRELESS_CORE_H */
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index 99ef9364b7e8..8b65e212ae49 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -39,6 +39,8 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
39 cfg80211_hold_bss(bss_from_pub(bss)); 39 cfg80211_hold_bss(bss_from_pub(bss));
40 wdev->current_bss = bss_from_pub(bss); 40 wdev->current_bss = bss_from_pub(bss);
41 41
42 cfg80211_upload_connect_keys(wdev);
43
42 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid, 44 nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid,
43 GFP_KERNEL); 45 GFP_KERNEL);
44#ifdef CONFIG_WIRELESS_EXT 46#ifdef CONFIG_WIRELESS_EXT
@@ -71,7 +73,8 @@ EXPORT_SYMBOL(cfg80211_ibss_joined);
71 73
72int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 74int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
73 struct net_device *dev, 75 struct net_device *dev,
74 struct cfg80211_ibss_params *params) 76 struct cfg80211_ibss_params *params,
77 struct cfg80211_cached_keys *connkeys)
75{ 78{
76 struct wireless_dev *wdev = dev->ieee80211_ptr; 79 struct wireless_dev *wdev = dev->ieee80211_ptr;
77 int err; 80 int err;
@@ -81,13 +84,18 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
81 if (wdev->ssid_len) 84 if (wdev->ssid_len)
82 return -EALREADY; 85 return -EALREADY;
83 86
87 if (WARN_ON(wdev->connect_keys))
88 kfree(wdev->connect_keys);
89 wdev->connect_keys = connkeys;
90
84#ifdef CONFIG_WIRELESS_EXT 91#ifdef CONFIG_WIRELESS_EXT
85 wdev->wext.ibss.channel = params->channel; 92 wdev->wext.ibss.channel = params->channel;
86#endif 93#endif
87 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params); 94 err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
88 95 if (err) {
89 if (err) 96 wdev->connect_keys = NULL;
90 return err; 97 return err;
98 }
91 99
92 memcpy(wdev->ssid, params->ssid, params->ssid_len); 100 memcpy(wdev->ssid, params->ssid, params->ssid_len);
93 wdev->ssid_len = params->ssid_len; 101 wdev->ssid_len = params->ssid_len;
@@ -97,13 +105,14 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
97 105
98int cfg80211_join_ibss(struct cfg80211_registered_device *rdev, 106int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
99 struct net_device *dev, 107 struct net_device *dev,
100 struct cfg80211_ibss_params *params) 108 struct cfg80211_ibss_params *params,
109 struct cfg80211_cached_keys *connkeys)
101{ 110{
102 struct wireless_dev *wdev = dev->ieee80211_ptr; 111 struct wireless_dev *wdev = dev->ieee80211_ptr;
103 int err; 112 int err;
104 113
105 wdev_lock(wdev); 114 wdev_lock(wdev);
106 err = __cfg80211_join_ibss(rdev, dev, params); 115 err = __cfg80211_join_ibss(rdev, dev, params, connkeys);
107 wdev_unlock(wdev); 116 wdev_unlock(wdev);
108 117
109 return err; 118 return err;
@@ -112,9 +121,22 @@ int cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
112static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext) 121static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
113{ 122{
114 struct wireless_dev *wdev = dev->ieee80211_ptr; 123 struct wireless_dev *wdev = dev->ieee80211_ptr;
124 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
125 int i;
115 126
116 ASSERT_WDEV_LOCK(wdev); 127 ASSERT_WDEV_LOCK(wdev);
117 128
129 kfree(wdev->connect_keys);
130 wdev->connect_keys = NULL;
131
132 /*
133 * Delete all the keys ... pairwise keys can't really
134 * exist any more anyway, but default keys might.
135 */
136 if (rdev->ops->del_key)
137 for (i = 0; i < 6; i++)
138 rdev->ops->del_key(wdev->wiphy, dev, i, NULL);
139
118 if (wdev->current_bss) { 140 if (wdev->current_bss) {
119 cfg80211_unhold_bss(wdev->current_bss); 141 cfg80211_unhold_bss(wdev->current_bss);
120 cfg80211_put_bss(&wdev->current_bss->pub); 142 cfg80211_put_bss(&wdev->current_bss->pub);
@@ -172,11 +194,14 @@ int cfg80211_leave_ibss(struct cfg80211_registered_device *rdev,
172} 194}
173 195
174#ifdef CONFIG_WIRELESS_EXT 196#ifdef CONFIG_WIRELESS_EXT
175static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev, 197int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
176 struct wireless_dev *wdev) 198 struct wireless_dev *wdev)
177{ 199{
200 struct cfg80211_cached_keys *ck = NULL;
178 enum ieee80211_band band; 201 enum ieee80211_band band;
179 int i; 202 int i, err;
203
204 ASSERT_WDEV_LOCK(wdev);
180 205
181 if (!wdev->wext.ibss.beacon_interval) 206 if (!wdev->wext.ibss.beacon_interval)
182 wdev->wext.ibss.beacon_interval = 100; 207 wdev->wext.ibss.beacon_interval = 100;
@@ -216,8 +241,24 @@ static int cfg80211_ibss_wext_join(struct cfg80211_registered_device *rdev,
216 if (!netif_running(wdev->netdev)) 241 if (!netif_running(wdev->netdev))
217 return 0; 242 return 0;
218 243
219 return cfg80211_join_ibss(wiphy_to_dev(wdev->wiphy), 244 if (wdev->wext.keys)
220 wdev->netdev, &wdev->wext.ibss); 245 wdev->wext.keys->def = wdev->wext.default_key;
246
247 wdev->wext.ibss.privacy = wdev->wext.default_key != -1;
248
249 if (wdev->wext.keys) {
250 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
251 if (!ck)
252 return -ENOMEM;
253 for (i = 0; i < 6; i++)
254 ck->params[i].key = ck->data[i];
255 }
256 err = __cfg80211_join_ibss(rdev, wdev->netdev,
257 &wdev->wext.ibss, ck);
258 if (err)
259 kfree(ck);
260
261 return err;
221} 262}
222 263
223int cfg80211_ibss_wext_siwfreq(struct net_device *dev, 264int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
@@ -265,7 +306,11 @@ int cfg80211_ibss_wext_siwfreq(struct net_device *dev,
265 wdev->wext.ibss.channel_fixed = false; 306 wdev->wext.ibss.channel_fixed = false;
266 } 307 }
267 308
268 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); 309 wdev_lock(wdev);
310 err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
311 wdev_unlock(wdev);
312
313 return err;
269} 314}
270/* temporary symbol - mark GPL - in the future the handler won't be */ 315/* temporary symbol - mark GPL - in the future the handler won't be */
271EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq); 316EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwfreq);
@@ -333,7 +378,11 @@ int cfg80211_ibss_wext_siwessid(struct net_device *dev,
333 memcpy(wdev->wext.ibss.ssid, ssid, len); 378 memcpy(wdev->wext.ibss.ssid, ssid, len);
334 wdev->wext.ibss.ssid_len = len; 379 wdev->wext.ibss.ssid_len = len;
335 380
336 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); 381 wdev_lock(wdev);
382 err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
383 wdev_unlock(wdev);
384
385 return err;
337} 386}
338/* temporary symbol - mark GPL - in the future the handler won't be */ 387/* temporary symbol - mark GPL - in the future the handler won't be */
339EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid); 388EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwessid);
@@ -414,7 +463,11 @@ int cfg80211_ibss_wext_siwap(struct net_device *dev,
414 } else 463 } else
415 wdev->wext.ibss.bssid = NULL; 464 wdev->wext.ibss.bssid = NULL;
416 465
417 return cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev); 466 wdev_lock(wdev);
467 err = cfg80211_ibss_wext_join(wiphy_to_dev(wdev->wiphy), wdev);
468 wdev_unlock(wdev);
469
470 return err;
418} 471}
419/* temporary symbol - mark GPL - in the future the handler won't be */ 472/* temporary symbol - mark GPL - in the future the handler won't be */
420EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap); 473EXPORT_SYMBOL_GPL(cfg80211_ibss_wext_siwap);
@@ -434,8 +487,11 @@ int cfg80211_ibss_wext_giwap(struct net_device *dev,
434 wdev_lock(wdev); 487 wdev_lock(wdev);
435 if (wdev->current_bss) 488 if (wdev->current_bss)
436 memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN); 489 memcpy(ap_addr->sa_data, wdev->current_bss->pub.bssid, ETH_ALEN);
437 else 490 else if (wdev->wext.ibss.bssid)
438 memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN); 491 memcpy(ap_addr->sa_data, wdev->wext.ibss.bssid, ETH_ALEN);
492 else
493 memset(ap_addr->sa_data, 0, ETH_ALEN);
494
439 wdev_unlock(wdev); 495 wdev_unlock(wdev);
440 496
441 return 0; 497 return 0;
diff --git a/net/wireless/mlme.c b/net/wireless/mlme.c
index 1b2ca1fea7a1..5b9b22120824 100644
--- a/net/wireless/mlme.c
+++ b/net/wireless/mlme.c
@@ -178,12 +178,12 @@ static void __cfg80211_send_disassoc(struct net_device *dev,
178 bool from_ap; 178 bool from_ap;
179 bool done = false; 179 bool done = false;
180 180
181 wdev_lock(wdev); 181 ASSERT_WDEV_LOCK(wdev);
182 182
183 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL); 183 nl80211_send_disassoc(rdev, dev, buf, len, GFP_KERNEL);
184 184
185 if (!wdev->sme_state == CFG80211_SME_CONNECTED) 185 if (wdev->sme_state != CFG80211_SME_CONNECTED)
186 goto out; 186 return;
187 187
188 if (wdev->current_bss && 188 if (wdev->current_bss &&
189 memcmp(wdev->current_bss, bssid, ETH_ALEN) == 0) { 189 memcmp(wdev->current_bss, bssid, ETH_ALEN) == 0) {
@@ -205,8 +205,6 @@ static void __cfg80211_send_disassoc(struct net_device *dev,
205 205
206 from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0; 206 from_ap = memcmp(mgmt->da, dev->dev_addr, ETH_ALEN) == 0;
207 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap); 207 __cfg80211_disconnected(dev, NULL, 0, reason_code, from_ap);
208 out:
209 wdev_unlock(wdev);
210} 208}
211 209
212void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len, 210void cfg80211_send_disassoc(struct net_device *dev, const u8 *buf, size_t len,
@@ -328,7 +326,8 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
328 enum nl80211_auth_type auth_type, 326 enum nl80211_auth_type auth_type,
329 const u8 *bssid, 327 const u8 *bssid,
330 const u8 *ssid, int ssid_len, 328 const u8 *ssid, int ssid_len,
331 const u8 *ie, int ie_len) 329 const u8 *ie, int ie_len,
330 const u8 *key, int key_len, int key_idx)
332{ 331{
333 struct wireless_dev *wdev = dev->ieee80211_ptr; 332 struct wireless_dev *wdev = dev->ieee80211_ptr;
334 struct cfg80211_auth_request req; 333 struct cfg80211_auth_request req;
@@ -337,6 +336,10 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
337 336
338 ASSERT_WDEV_LOCK(wdev); 337 ASSERT_WDEV_LOCK(wdev);
339 338
339 if (auth_type == NL80211_AUTHTYPE_SHARED_KEY)
340 if (!key || !key_len || key_idx < 0 || key_idx > 4)
341 return -EINVAL;
342
340 if (wdev->current_bss && 343 if (wdev->current_bss &&
341 memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0) 344 memcmp(bssid, wdev->current_bss->pub.bssid, ETH_ALEN) == 0)
342 return -EALREADY; 345 return -EALREADY;
@@ -359,6 +362,9 @@ int __cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
359 req.auth_type = auth_type; 362 req.auth_type = auth_type;
360 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len, 363 req.bss = cfg80211_get_bss(&rdev->wiphy, chan, bssid, ssid, ssid_len,
361 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 364 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
365 req.key = key;
366 req.key_len = key_len;
367 req.key_idx = key_idx;
362 if (!req.bss) 368 if (!req.bss)
363 return -ENOENT; 369 return -ENOENT;
364 370
@@ -396,13 +402,15 @@ int cfg80211_mlme_auth(struct cfg80211_registered_device *rdev,
396 struct net_device *dev, struct ieee80211_channel *chan, 402 struct net_device *dev, struct ieee80211_channel *chan,
397 enum nl80211_auth_type auth_type, const u8 *bssid, 403 enum nl80211_auth_type auth_type, const u8 *bssid,
398 const u8 *ssid, int ssid_len, 404 const u8 *ssid, int ssid_len,
399 const u8 *ie, int ie_len) 405 const u8 *ie, int ie_len,
406 const u8 *key, int key_len, int key_idx)
400{ 407{
401 int err; 408 int err;
402 409
403 wdev_lock(dev->ieee80211_ptr); 410 wdev_lock(dev->ieee80211_ptr);
404 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 411 err = __cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
405 ssid, ssid_len, ie, ie_len); 412 ssid, ssid_len, ie, ie_len,
413 key, key_len, key_idx);
406 wdev_unlock(dev->ieee80211_ptr); 414 wdev_unlock(dev->ieee80211_ptr);
407 415
408 return err; 416 return err;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 4478760b7dc3..da450ef1fc7e 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -73,6 +73,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
73 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN }, 73 [NL80211_ATTR_MAC] = { .type = NLA_BINARY, .len = ETH_ALEN },
74 [NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN }, 74 [NL80211_ATTR_PREV_BSSID] = { .type = NLA_BINARY, .len = ETH_ALEN },
75 75
76 [NL80211_ATTR_KEY] = { .type = NLA_NESTED, },
76 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY, 77 [NL80211_ATTR_KEY_DATA] = { .type = NLA_BINARY,
77 .len = WLAN_MAX_KEY_LEN }, 78 .len = WLAN_MAX_KEY_LEN },
78 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 }, 79 [NL80211_ATTR_KEY_IDX] = { .type = NLA_U8 },
@@ -134,6 +135,17 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
134 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 }, 135 [NL80211_ATTR_WPA_VERSIONS] = { .type = NLA_U32 },
135}; 136};
136 137
138/* policy for the attributes */
139static struct nla_policy
140nl80211_key_policy[NL80211_KEY_MAX + 1] __read_mostly = {
141 [NL80211_KEY_DATA] = { .type = NLA_BINARY, .len = WLAN_MAX_KEY_LEN },
142 [NL80211_KEY_IDX] = { .type = NLA_U8 },
143 [NL80211_KEY_CIPHER] = { .type = NLA_U32 },
144 [NL80211_KEY_SEQ] = { .type = NLA_BINARY, .len = 8 },
145 [NL80211_KEY_DEFAULT] = { .type = NLA_FLAG },
146 [NL80211_KEY_DEFAULT_MGMT] = { .type = NLA_FLAG },
147};
148
137/* IE validation */ 149/* IE validation */
138static bool is_valid_ie_attr(const struct nlattr *attr) 150static bool is_valid_ie_attr(const struct nlattr *attr)
139{ 151{
@@ -198,6 +210,177 @@ static int nl80211_msg_put_channel(struct sk_buff *msg,
198 210
199/* netlink command implementations */ 211/* netlink command implementations */
200 212
213struct key_parse {
214 struct key_params p;
215 int idx;
216 bool def, defmgmt;
217};
218
219static int nl80211_parse_key_new(struct nlattr *key, struct key_parse *k)
220{
221 struct nlattr *tb[NL80211_KEY_MAX + 1];
222 int err = nla_parse_nested(tb, NL80211_KEY_MAX, key,
223 nl80211_key_policy);
224 if (err)
225 return err;
226
227 k->def = !!tb[NL80211_KEY_DEFAULT];
228 k->defmgmt = !!tb[NL80211_KEY_DEFAULT_MGMT];
229
230 if (tb[NL80211_KEY_IDX])
231 k->idx = nla_get_u8(tb[NL80211_KEY_IDX]);
232
233 if (tb[NL80211_KEY_DATA]) {
234 k->p.key = nla_data(tb[NL80211_KEY_DATA]);
235 k->p.key_len = nla_len(tb[NL80211_KEY_DATA]);
236 }
237
238 if (tb[NL80211_KEY_SEQ]) {
239 k->p.seq = nla_data(tb[NL80211_KEY_SEQ]);
240 k->p.seq_len = nla_len(tb[NL80211_KEY_SEQ]);
241 }
242
243 if (tb[NL80211_KEY_CIPHER])
244 k->p.cipher = nla_get_u32(tb[NL80211_KEY_CIPHER]);
245
246 return 0;
247}
248
249static int nl80211_parse_key_old(struct genl_info *info, struct key_parse *k)
250{
251 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
252 k->p.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
253 k->p.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
254 }
255
256 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
257 k->p.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
258 k->p.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
259 }
260
261 if (info->attrs[NL80211_ATTR_KEY_IDX])
262 k->idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
263
264 if (info->attrs[NL80211_ATTR_KEY_CIPHER])
265 k->p.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
266
267 k->def = !!info->attrs[NL80211_ATTR_KEY_DEFAULT];
268 k->defmgmt = !!info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT];
269
270 return 0;
271}
272
273static int nl80211_parse_key(struct genl_info *info, struct key_parse *k)
274{
275 int err;
276
277 memset(k, 0, sizeof(*k));
278 k->idx = -1;
279
280 if (info->attrs[NL80211_ATTR_KEY])
281 err = nl80211_parse_key_new(info->attrs[NL80211_ATTR_KEY], k);
282 else
283 err = nl80211_parse_key_old(info, k);
284
285 if (err)
286 return err;
287
288 if (k->def && k->defmgmt)
289 return -EINVAL;
290
291 if (k->idx != -1) {
292 if (k->defmgmt) {
293 if (k->idx < 4 || k->idx > 5)
294 return -EINVAL;
295 } else if (k->def) {
296 if (k->idx < 0 || k->idx > 3)
297 return -EINVAL;
298 } else {
299 if (k->idx < 0 || k->idx > 5)
300 return -EINVAL;
301 }
302 }
303
304 return 0;
305}
306
307static struct cfg80211_cached_keys *
308nl80211_parse_connkeys(struct cfg80211_registered_device *rdev,
309 struct nlattr *keys)
310{
311 struct key_parse parse;
312 struct nlattr *key;
313 struct cfg80211_cached_keys *result;
314 int rem, err, def = 0;
315
316 result = kzalloc(sizeof(*result), GFP_KERNEL);
317 if (!result)
318 return ERR_PTR(-ENOMEM);
319
320 result->def = -1;
321 result->defmgmt = -1;
322
323 nla_for_each_nested(key, keys, rem) {
324 memset(&parse, 0, sizeof(parse));
325 parse.idx = -1;
326
327 err = nl80211_parse_key_new(key, &parse);
328 if (err)
329 goto error;
330 err = -EINVAL;
331 if (!parse.p.key)
332 goto error;
333 if (parse.idx < 0 || parse.idx > 4)
334 goto error;
335 if (parse.def) {
336 if (def)
337 goto error;
338 def = 1;
339 result->def = parse.idx;
340 } else if (parse.defmgmt)
341 goto error;
342 err = cfg80211_validate_key_settings(rdev, &parse.p,
343 parse.idx, NULL);
344 if (err)
345 goto error;
346 result->params[parse.idx].cipher = parse.p.cipher;
347 result->params[parse.idx].key_len = parse.p.key_len;
348 result->params[parse.idx].key = result->data[parse.idx];
349 memcpy(result->data[parse.idx], parse.p.key, parse.p.key_len);
350 }
351
352 return result;
353 error:
354 kfree(result);
355 return ERR_PTR(err);
356}
357
358static int nl80211_key_allowed(struct wireless_dev *wdev)
359{
360 ASSERT_WDEV_LOCK(wdev);
361
362 if (!netif_running(wdev->netdev))
363 return -ENETDOWN;
364
365 switch (wdev->iftype) {
366 case NL80211_IFTYPE_AP:
367 case NL80211_IFTYPE_AP_VLAN:
368 break;
369 case NL80211_IFTYPE_ADHOC:
370 if (!wdev->current_bss)
371 return -ENOLINK;
372 break;
373 case NL80211_IFTYPE_STATION:
374 if (wdev->sme_state != CFG80211_SME_CONNECTED)
375 return -ENOLINK;
376 break;
377 default:
378 return -EINVAL;
379 }
380
381 return 0;
382}
383
201static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags, 384static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
202 struct cfg80211_registered_device *dev) 385 struct cfg80211_registered_device *dev)
203{ 386{
@@ -943,10 +1126,12 @@ static int nl80211_del_interface(struct sk_buff *skb, struct genl_info *info)
943struct get_key_cookie { 1126struct get_key_cookie {
944 struct sk_buff *msg; 1127 struct sk_buff *msg;
945 int error; 1128 int error;
1129 int idx;
946}; 1130};
947 1131
948static void get_key_callback(void *c, struct key_params *params) 1132static void get_key_callback(void *c, struct key_params *params)
949{ 1133{
1134 struct nlattr *key;
950 struct get_key_cookie *cookie = c; 1135 struct get_key_cookie *cookie = c;
951 1136
952 if (params->key) 1137 if (params->key)
@@ -961,6 +1146,26 @@ static void get_key_callback(void *c, struct key_params *params)
961 NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER, 1146 NLA_PUT_U32(cookie->msg, NL80211_ATTR_KEY_CIPHER,
962 params->cipher); 1147 params->cipher);
963 1148
1149 key = nla_nest_start(cookie->msg, NL80211_ATTR_KEY);
1150 if (!key)
1151 goto nla_put_failure;
1152
1153 if (params->key)
1154 NLA_PUT(cookie->msg, NL80211_KEY_DATA,
1155 params->key_len, params->key);
1156
1157 if (params->seq)
1158 NLA_PUT(cookie->msg, NL80211_KEY_SEQ,
1159 params->seq_len, params->seq);
1160
1161 if (params->cipher)
1162 NLA_PUT_U32(cookie->msg, NL80211_KEY_CIPHER,
1163 params->cipher);
1164
1165 NLA_PUT_U8(cookie->msg, NL80211_ATTR_KEY_IDX, cookie->idx);
1166
1167 nla_nest_end(cookie->msg, key);
1168
964 return; 1169 return;
965 nla_put_failure: 1170 nla_put_failure:
966 cookie->error = 1; 1171 cookie->error = 1;
@@ -1014,6 +1219,7 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1014 } 1219 }
1015 1220
1016 cookie.msg = msg; 1221 cookie.msg = msg;
1222 cookie.idx = key_idx;
1017 1223
1018 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 1224 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex);
1019 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx); 1225 NLA_PUT_U8(msg, NL80211_ATTR_KEY_IDX, key_idx);
@@ -1049,26 +1255,21 @@ static int nl80211_get_key(struct sk_buff *skb, struct genl_info *info)
1049static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info) 1255static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1050{ 1256{
1051 struct cfg80211_registered_device *rdev; 1257 struct cfg80211_registered_device *rdev;
1258 struct key_parse key;
1052 int err; 1259 int err;
1053 struct net_device *dev; 1260 struct net_device *dev;
1054 u8 key_idx;
1055 int (*func)(struct wiphy *wiphy, struct net_device *netdev, 1261 int (*func)(struct wiphy *wiphy, struct net_device *netdev,
1056 u8 key_index); 1262 u8 key_index);
1057 1263
1058 if (!info->attrs[NL80211_ATTR_KEY_IDX]) 1264 err = nl80211_parse_key(info, &key);
1059 return -EINVAL; 1265 if (err)
1060 1266 return err;
1061 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1062 1267
1063 if (info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT]) { 1268 if (key.idx < 0)
1064 if (key_idx < 4 || key_idx > 5)
1065 return -EINVAL;
1066 } else if (key_idx > 3)
1067 return -EINVAL; 1269 return -EINVAL;
1068 1270
1069 /* currently only support setting default key */ 1271 /* only support setting default key */
1070 if (!info->attrs[NL80211_ATTR_KEY_DEFAULT] && 1272 if (!key.def && !key.defmgmt)
1071 !info->attrs[NL80211_ATTR_KEY_DEFAULT_MGMT])
1072 return -EINVAL; 1273 return -EINVAL;
1073 1274
1074 rtnl_lock(); 1275 rtnl_lock();
@@ -1077,7 +1278,7 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1077 if (err) 1278 if (err)
1078 goto unlock_rtnl; 1279 goto unlock_rtnl;
1079 1280
1080 if (info->attrs[NL80211_ATTR_KEY_DEFAULT]) 1281 if (key.def)
1081 func = rdev->ops->set_default_key; 1282 func = rdev->ops->set_default_key;
1082 else 1283 else
1083 func = rdev->ops->set_default_mgmt_key; 1284 func = rdev->ops->set_default_mgmt_key;
@@ -1087,15 +1288,20 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1087 goto out; 1288 goto out;
1088 } 1289 }
1089 1290
1090 err = func(&rdev->wiphy, dev, key_idx); 1291 wdev_lock(dev->ieee80211_ptr);
1292 err = nl80211_key_allowed(dev->ieee80211_ptr);
1293 if (!err)
1294 err = func(&rdev->wiphy, dev, key.idx);
1295
1091#ifdef CONFIG_WIRELESS_EXT 1296#ifdef CONFIG_WIRELESS_EXT
1092 if (!err) { 1297 if (!err) {
1093 if (func == rdev->ops->set_default_key) 1298 if (func == rdev->ops->set_default_key)
1094 dev->ieee80211_ptr->wext.default_key = key_idx; 1299 dev->ieee80211_ptr->wext.default_key = key.idx;
1095 else 1300 else
1096 dev->ieee80211_ptr->wext.default_mgmt_key = key_idx; 1301 dev->ieee80211_ptr->wext.default_mgmt_key = key.idx;
1097 } 1302 }
1098#endif 1303#endif
1304 wdev_unlock(dev->ieee80211_ptr);
1099 1305
1100 out: 1306 out:
1101 cfg80211_unlock_rdev(rdev); 1307 cfg80211_unlock_rdev(rdev);
@@ -1110,58 +1316,43 @@ static int nl80211_set_key(struct sk_buff *skb, struct genl_info *info)
1110static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info) 1316static int nl80211_new_key(struct sk_buff *skb, struct genl_info *info)
1111{ 1317{
1112 struct cfg80211_registered_device *rdev; 1318 struct cfg80211_registered_device *rdev;
1113 int err, i; 1319 int err;
1114 struct net_device *dev; 1320 struct net_device *dev;
1115 struct key_params params; 1321 struct key_parse key;
1116 u8 key_idx = 0;
1117 u8 *mac_addr = NULL; 1322 u8 *mac_addr = NULL;
1118 1323
1119 memset(&params, 0, sizeof(params)); 1324 err = nl80211_parse_key(info, &key);
1325 if (err)
1326 return err;
1120 1327
1121 if (!info->attrs[NL80211_ATTR_KEY_CIPHER]) 1328 if (!key.p.key)
1122 return -EINVAL; 1329 return -EINVAL;
1123 1330
1124 if (info->attrs[NL80211_ATTR_KEY_DATA]) {
1125 params.key = nla_data(info->attrs[NL80211_ATTR_KEY_DATA]);
1126 params.key_len = nla_len(info->attrs[NL80211_ATTR_KEY_DATA]);
1127 }
1128
1129 if (info->attrs[NL80211_ATTR_KEY_SEQ]) {
1130 params.seq = nla_data(info->attrs[NL80211_ATTR_KEY_SEQ]);
1131 params.seq_len = nla_len(info->attrs[NL80211_ATTR_KEY_SEQ]);
1132 }
1133
1134 if (info->attrs[NL80211_ATTR_KEY_IDX])
1135 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]);
1136
1137 params.cipher = nla_get_u32(info->attrs[NL80211_ATTR_KEY_CIPHER]);
1138
1139 if (info->attrs[NL80211_ATTR_MAC]) 1331 if (info->attrs[NL80211_ATTR_MAC])
1140 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1332 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
1141 1333
1142 if (cfg80211_validate_key_settings(&params, key_idx, mac_addr))
1143 return -EINVAL;
1144
1145 rtnl_lock(); 1334 rtnl_lock();
1146 1335
1147 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 1336 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
1148 if (err) 1337 if (err)
1149 goto unlock_rtnl; 1338 goto unlock_rtnl;
1150 1339
1151 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++) 1340 if (!rdev->ops->add_key) {
1152 if (params.cipher == rdev->wiphy.cipher_suites[i]) 1341 err = -EOPNOTSUPP;
1153 break;
1154 if (i == rdev->wiphy.n_cipher_suites) {
1155 err = -EINVAL;
1156 goto out; 1342 goto out;
1157 } 1343 }
1158 1344
1159 if (!rdev->ops->add_key) { 1345 if (cfg80211_validate_key_settings(rdev, &key.p, key.idx, mac_addr)) {
1160 err = -EOPNOTSUPP; 1346 err = -EINVAL;
1161 goto out; 1347 goto out;
1162 } 1348 }
1163 1349
1164 err = rdev->ops->add_key(&rdev->wiphy, dev, key_idx, mac_addr, &params); 1350 wdev_lock(dev->ieee80211_ptr);
1351 err = nl80211_key_allowed(dev->ieee80211_ptr);
1352 if (!err)
1353 err = rdev->ops->add_key(&rdev->wiphy, dev, key.idx,
1354 mac_addr, &key.p);
1355 wdev_unlock(dev->ieee80211_ptr);
1165 1356
1166 out: 1357 out:
1167 cfg80211_unlock_rdev(rdev); 1358 cfg80211_unlock_rdev(rdev);
@@ -1177,14 +1368,12 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1177 struct cfg80211_registered_device *rdev; 1368 struct cfg80211_registered_device *rdev;
1178 int err; 1369 int err;
1179 struct net_device *dev; 1370 struct net_device *dev;
1180 u8 key_idx = 0;
1181 u8 *mac_addr = NULL; 1371 u8 *mac_addr = NULL;
1372 struct key_parse key;
1182 1373
1183 if (info->attrs[NL80211_ATTR_KEY_IDX]) 1374 err = nl80211_parse_key(info, &key);
1184 key_idx = nla_get_u8(info->attrs[NL80211_ATTR_KEY_IDX]); 1375 if (err)
1185 1376 return err;
1186 if (key_idx > 5)
1187 return -EINVAL;
1188 1377
1189 if (info->attrs[NL80211_ATTR_MAC]) 1378 if (info->attrs[NL80211_ATTR_MAC])
1190 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]); 1379 mac_addr = nla_data(info->attrs[NL80211_ATTR_MAC]);
@@ -1200,16 +1389,20 @@ static int nl80211_del_key(struct sk_buff *skb, struct genl_info *info)
1200 goto out; 1389 goto out;
1201 } 1390 }
1202 1391
1203 err = rdev->ops->del_key(&rdev->wiphy, dev, key_idx, mac_addr); 1392 wdev_lock(dev->ieee80211_ptr);
1393 err = nl80211_key_allowed(dev->ieee80211_ptr);
1394 if (!err)
1395 err = rdev->ops->del_key(&rdev->wiphy, dev, key.idx, mac_addr);
1204 1396
1205#ifdef CONFIG_WIRELESS_EXT 1397#ifdef CONFIG_WIRELESS_EXT
1206 if (!err) { 1398 if (!err) {
1207 if (key_idx == dev->ieee80211_ptr->wext.default_key) 1399 if (key.idx == dev->ieee80211_ptr->wext.default_key)
1208 dev->ieee80211_ptr->wext.default_key = -1; 1400 dev->ieee80211_ptr->wext.default_key = -1;
1209 else if (key_idx == dev->ieee80211_ptr->wext.default_mgmt_key) 1401 else if (key.idx == dev->ieee80211_ptr->wext.default_mgmt_key)
1210 dev->ieee80211_ptr->wext.default_mgmt_key = -1; 1402 dev->ieee80211_ptr->wext.default_mgmt_key = -1;
1211 } 1403 }
1212#endif 1404#endif
1405 wdev_unlock(dev->ieee80211_ptr);
1213 1406
1214 out: 1407 out:
1215 cfg80211_unlock_rdev(rdev); 1408 cfg80211_unlock_rdev(rdev);
@@ -2901,11 +3094,15 @@ static int nl80211_trigger_scan(struct sk_buff *skb, struct genl_info *info)
2901 3094
2902static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags, 3095static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
2903 struct cfg80211_registered_device *rdev, 3096 struct cfg80211_registered_device *rdev,
2904 struct net_device *dev, 3097 struct wireless_dev *wdev,
2905 struct cfg80211_bss *res) 3098 struct cfg80211_internal_bss *intbss)
2906{ 3099{
3100 struct cfg80211_bss *res = &intbss->pub;
2907 void *hdr; 3101 void *hdr;
2908 struct nlattr *bss; 3102 struct nlattr *bss;
3103 int i;
3104
3105 ASSERT_WDEV_LOCK(wdev);
2909 3106
2910 hdr = nl80211hdr_put(msg, pid, seq, flags, 3107 hdr = nl80211hdr_put(msg, pid, seq, flags,
2911 NL80211_CMD_NEW_SCAN_RESULTS); 3108 NL80211_CMD_NEW_SCAN_RESULTS);
@@ -2914,7 +3111,7 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
2914 3111
2915 NLA_PUT_U32(msg, NL80211_ATTR_SCAN_GENERATION, 3112 NLA_PUT_U32(msg, NL80211_ATTR_SCAN_GENERATION,
2916 rdev->bss_generation); 3113 rdev->bss_generation);
2917 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, dev->ifindex); 3114 NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, wdev->netdev->ifindex);
2918 3115
2919 bss = nla_nest_start(msg, NL80211_ATTR_BSS); 3116 bss = nla_nest_start(msg, NL80211_ATTR_BSS);
2920 if (!bss) 3117 if (!bss)
@@ -2943,6 +3140,28 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
2943 break; 3140 break;
2944 } 3141 }
2945 3142
3143 switch (wdev->iftype) {
3144 case NL80211_IFTYPE_STATION:
3145 if (intbss == wdev->current_bss)
3146 NLA_PUT_U32(msg, NL80211_BSS_STATUS,
3147 NL80211_BSS_STATUS_ASSOCIATED);
3148 else for (i = 0; i < MAX_AUTH_BSSES; i++) {
3149 if (intbss != wdev->auth_bsses[i])
3150 continue;
3151 NLA_PUT_U32(msg, NL80211_BSS_STATUS,
3152 NL80211_BSS_STATUS_AUTHENTICATED);
3153 break;
3154 }
3155 break;
3156 case NL80211_IFTYPE_ADHOC:
3157 if (intbss == wdev->current_bss)
3158 NLA_PUT_U32(msg, NL80211_BSS_STATUS,
3159 NL80211_BSS_STATUS_IBSS_JOINED);
3160 break;
3161 default:
3162 break;
3163 }
3164
2946 nla_nest_end(msg, bss); 3165 nla_nest_end(msg, bss);
2947 3166
2948 return genlmsg_end(msg, hdr); 3167 return genlmsg_end(msg, hdr);
@@ -2955,9 +3174,10 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
2955static int nl80211_dump_scan(struct sk_buff *skb, 3174static int nl80211_dump_scan(struct sk_buff *skb,
2956 struct netlink_callback *cb) 3175 struct netlink_callback *cb)
2957{ 3176{
2958 struct cfg80211_registered_device *dev; 3177 struct cfg80211_registered_device *rdev;
2959 struct net_device *netdev; 3178 struct net_device *dev;
2960 struct cfg80211_internal_bss *scan; 3179 struct cfg80211_internal_bss *scan;
3180 struct wireless_dev *wdev;
2961 int ifidx = cb->args[0]; 3181 int ifidx = cb->args[0];
2962 int start = cb->args[1], idx = 0; 3182 int start = cb->args[1], idx = 0;
2963 int err; 3183 int err;
@@ -2978,39 +3198,43 @@ static int nl80211_dump_scan(struct sk_buff *skb,
2978 cb->args[0] = ifidx; 3198 cb->args[0] = ifidx;
2979 } 3199 }
2980 3200
2981 netdev = dev_get_by_index(&init_net, ifidx); 3201 dev = dev_get_by_index(&init_net, ifidx);
2982 if (!netdev) 3202 if (!dev)
2983 return -ENODEV; 3203 return -ENODEV;
2984 3204
2985 dev = cfg80211_get_dev_from_ifindex(ifidx); 3205 rdev = cfg80211_get_dev_from_ifindex(ifidx);
2986 if (IS_ERR(dev)) { 3206 if (IS_ERR(rdev)) {
2987 err = PTR_ERR(dev); 3207 err = PTR_ERR(rdev);
2988 goto out_put_netdev; 3208 goto out_put_netdev;
2989 } 3209 }
2990 3210
2991 spin_lock_bh(&dev->bss_lock); 3211 wdev = dev->ieee80211_ptr;
2992 cfg80211_bss_expire(dev); 3212
3213 wdev_lock(wdev);
3214 spin_lock_bh(&rdev->bss_lock);
3215 cfg80211_bss_expire(rdev);
2993 3216
2994 list_for_each_entry(scan, &dev->bss_list, list) { 3217 list_for_each_entry(scan, &rdev->bss_list, list) {
2995 if (++idx <= start) 3218 if (++idx <= start)
2996 continue; 3219 continue;
2997 if (nl80211_send_bss(skb, 3220 if (nl80211_send_bss(skb,
2998 NETLINK_CB(cb->skb).pid, 3221 NETLINK_CB(cb->skb).pid,
2999 cb->nlh->nlmsg_seq, NLM_F_MULTI, 3222 cb->nlh->nlmsg_seq, NLM_F_MULTI,
3000 dev, netdev, &scan->pub) < 0) { 3223 rdev, wdev, scan) < 0) {
3001 idx--; 3224 idx--;
3002 goto out; 3225 goto out;
3003 } 3226 }
3004 } 3227 }
3005 3228
3006 out: 3229 out:
3007 spin_unlock_bh(&dev->bss_lock); 3230 spin_unlock_bh(&rdev->bss_lock);
3231 wdev_unlock(wdev);
3008 3232
3009 cb->args[1] = idx; 3233 cb->args[1] = idx;
3010 err = skb->len; 3234 err = skb->len;
3011 cfg80211_unlock_rdev(dev); 3235 cfg80211_unlock_rdev(rdev);
3012 out_put_netdev: 3236 out_put_netdev:
3013 dev_put(netdev); 3237 dev_put(dev);
3014 3238
3015 return err; 3239 return err;
3016} 3240}
@@ -3050,6 +3274,7 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3050 const u8 *bssid, *ssid, *ie = NULL; 3274 const u8 *bssid, *ssid, *ie = NULL;
3051 int err, ssid_len, ie_len = 0; 3275 int err, ssid_len, ie_len = 0;
3052 enum nl80211_auth_type auth_type; 3276 enum nl80211_auth_type auth_type;
3277 struct key_parse key;
3053 3278
3054 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE])) 3279 if (!is_valid_ie_attr(info->attrs[NL80211_ATTR_IE]))
3055 return -EINVAL; 3280 return -EINVAL;
@@ -3066,6 +3291,25 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3066 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ]) 3291 if (!info->attrs[NL80211_ATTR_WIPHY_FREQ])
3067 return -EINVAL; 3292 return -EINVAL;
3068 3293
3294 err = nl80211_parse_key(info, &key);
3295 if (err)
3296 return err;
3297
3298 if (key.idx >= 0) {
3299 if (!key.p.key || !key.p.key_len)
3300 return -EINVAL;
3301 if ((key.p.cipher != WLAN_CIPHER_SUITE_WEP40 ||
3302 key.p.key_len != WLAN_KEY_LEN_WEP40) &&
3303 (key.p.cipher != WLAN_CIPHER_SUITE_WEP104 ||
3304 key.p.key_len != WLAN_KEY_LEN_WEP104))
3305 return -EINVAL;
3306 if (key.idx > 4)
3307 return -EINVAL;
3308 } else {
3309 key.p.key_len = 0;
3310 key.p.key = NULL;
3311 }
3312
3069 rtnl_lock(); 3313 rtnl_lock();
3070 3314
3071 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev); 3315 err = get_rdev_dev_by_info_ifindex(info->attrs, &rdev, &dev);
@@ -3110,7 +3354,8 @@ static int nl80211_authenticate(struct sk_buff *skb, struct genl_info *info)
3110 } 3354 }
3111 3355
3112 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid, 3356 err = cfg80211_mlme_auth(rdev, dev, chan, auth_type, bssid,
3113 ssid, ssid_len, ie, ie_len); 3357 ssid, ssid_len, ie, ie_len,
3358 key.p.key, key.p.key_len, key.idx);
3114 3359
3115out: 3360out:
3116 cfg80211_unlock_rdev(rdev); 3361 cfg80211_unlock_rdev(rdev);
@@ -3397,6 +3642,7 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3397 struct net_device *dev; 3642 struct net_device *dev;
3398 struct cfg80211_ibss_params ibss; 3643 struct cfg80211_ibss_params ibss;
3399 struct wiphy *wiphy; 3644 struct wiphy *wiphy;
3645 struct cfg80211_cached_keys *connkeys = NULL;
3400 int err; 3646 int err;
3401 3647
3402 memset(&ibss, 0, sizeof(ibss)); 3648 memset(&ibss, 0, sizeof(ibss));
@@ -3461,13 +3707,26 @@ static int nl80211_join_ibss(struct sk_buff *skb, struct genl_info *info)
3461 } 3707 }
3462 3708
3463 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED]; 3709 ibss.channel_fixed = !!info->attrs[NL80211_ATTR_FREQ_FIXED];
3710 ibss.privacy = !!info->attrs[NL80211_ATTR_PRIVACY];
3711
3712 if (ibss.privacy && info->attrs[NL80211_ATTR_KEYS]) {
3713 connkeys = nl80211_parse_connkeys(rdev,
3714 info->attrs[NL80211_ATTR_KEYS]);
3715 if (IS_ERR(connkeys)) {
3716 err = PTR_ERR(connkeys);
3717 connkeys = NULL;
3718 goto out;
3719 }
3720 }
3464 3721
3465 err = cfg80211_join_ibss(rdev, dev, &ibss); 3722 err = cfg80211_join_ibss(rdev, dev, &ibss, connkeys);
3466 3723
3467out: 3724out:
3468 cfg80211_unlock_rdev(rdev); 3725 cfg80211_unlock_rdev(rdev);
3469 dev_put(dev); 3726 dev_put(dev);
3470unlock_rtnl: 3727unlock_rtnl:
3728 if (err)
3729 kfree(connkeys);
3471 rtnl_unlock(); 3730 rtnl_unlock();
3472 return err; 3731 return err;
3473} 3732}
@@ -3637,6 +3896,7 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
3637 struct net_device *dev; 3896 struct net_device *dev;
3638 struct cfg80211_connect_params connect; 3897 struct cfg80211_connect_params connect;
3639 struct wiphy *wiphy; 3898 struct wiphy *wiphy;
3899 struct cfg80211_cached_keys *connkeys = NULL;
3640 int err; 3900 int err;
3641 3901
3642 memset(&connect, 0, sizeof(connect)); 3902 memset(&connect, 0, sizeof(connect));
@@ -3680,10 +3940,6 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
3680 3940
3681 wiphy = &rdev->wiphy; 3941 wiphy = &rdev->wiphy;
3682 3942
3683 connect.bssid = NULL;
3684 connect.channel = NULL;
3685 connect.auth_type = NL80211_AUTHTYPE_OPEN_SYSTEM;
3686
3687 if (info->attrs[NL80211_ATTR_MAC]) 3943 if (info->attrs[NL80211_ATTR_MAC])
3688 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]); 3944 connect.bssid = nla_data(info->attrs[NL80211_ATTR_MAC]);
3689 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]); 3945 connect.ssid = nla_data(info->attrs[NL80211_ATTR_SSID]);
@@ -3705,12 +3961,24 @@ static int nl80211_connect(struct sk_buff *skb, struct genl_info *info)
3705 } 3961 }
3706 } 3962 }
3707 3963
3708 err = cfg80211_connect(rdev, dev, &connect); 3964 if (connect.privacy && info->attrs[NL80211_ATTR_KEYS]) {
3965 connkeys = nl80211_parse_connkeys(rdev,
3966 info->attrs[NL80211_ATTR_KEYS]);
3967 if (IS_ERR(connkeys)) {
3968 err = PTR_ERR(connkeys);
3969 connkeys = NULL;
3970 goto out;
3971 }
3972 }
3973
3974 err = cfg80211_connect(rdev, dev, &connect, connkeys);
3709 3975
3710out: 3976out:
3711 cfg80211_unlock_rdev(rdev); 3977 cfg80211_unlock_rdev(rdev);
3712 dev_put(dev); 3978 dev_put(dev);
3713unlock_rtnl: 3979unlock_rtnl:
3980 if (err)
3981 kfree(connkeys);
3714 rtnl_unlock(); 3982 rtnl_unlock();
3715 return err; 3983 return err;
3716} 3984}
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 2b4a6c66f5ae..fb40428a5946 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -113,11 +113,7 @@ static const struct ieee80211_regdomain world_regdom = {
113static const struct ieee80211_regdomain *cfg80211_world_regdom = 113static const struct ieee80211_regdomain *cfg80211_world_regdom =
114 &world_regdom; 114 &world_regdom;
115 115
116#ifdef CONFIG_WIRELESS_OLD_REGULATORY
117static char *ieee80211_regdom = "US";
118#else
119static char *ieee80211_regdom = "00"; 116static char *ieee80211_regdom = "00";
120#endif
121 117
122module_param(ieee80211_regdom, charp, 0444); 118module_param(ieee80211_regdom, charp, 0444);
123MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code"); 119MODULE_PARM_DESC(ieee80211_regdom, "IEEE 802.11 regulatory domain code");
@@ -2287,22 +2283,12 @@ int regulatory_init(void)
2287 2283
2288 printk(KERN_INFO "cfg80211: Using static regulatory domain info\n"); 2284 printk(KERN_INFO "cfg80211: Using static regulatory domain info\n");
2289 print_regdomain_info(cfg80211_regdomain); 2285 print_regdomain_info(cfg80211_regdomain);
2290 /*
2291 * The old code still requests for a new regdomain and if
2292 * you have CRDA you get it updated, otherwise you get
2293 * stuck with the static values. Since "EU" is not a valid
2294 * ISO / IEC 3166 alpha2 code we can't expect userpace to
2295 * give us a regulatory domain for it. We need last_request
2296 * iniitalized though so lets just send a request which we
2297 * know will be ignored... this crap will be removed once
2298 * OLD_REG dies.
2299 */
2300 err = regulatory_hint_core(ieee80211_regdom);
2301#else 2286#else
2302 cfg80211_regdomain = cfg80211_world_regdom; 2287 cfg80211_regdomain = cfg80211_world_regdom;
2303 2288
2304 err = regulatory_hint_core(ieee80211_regdom);
2305#endif 2289#endif
2290 /* We always try to get an update for the static regdomain */
2291 err = regulatory_hint_core(cfg80211_regdomain->alpha2);
2306 if (err) { 2292 if (err) {
2307 if (err == -ENOMEM) 2293 if (err == -ENOMEM)
2308 return err; 2294 return err;
@@ -2321,6 +2307,13 @@ int regulatory_init(void)
2321#endif 2307#endif
2322 } 2308 }
2323 2309
2310 /*
2311 * Finally, if the user set the module parameter treat it
2312 * as a user hint.
2313 */
2314 if (!is_world_regdom(ieee80211_regdom))
2315 regulatory_hint_user(ieee80211_regdom);
2316
2324 return 0; 2317 return 0;
2325} 2318}
2326 2319
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index df9173f73604..82de2d9795f4 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -125,7 +125,9 @@ static int cfg80211_conn_do_work(struct wireless_dev *wdev)
125 params->channel, params->auth_type, 125 params->channel, params->auth_type,
126 params->bssid, 126 params->bssid,
127 params->ssid, params->ssid_len, 127 params->ssid, params->ssid_len,
128 NULL, 0); 128 NULL, 0,
129 params->key, params->key_len,
130 params->key_idx);
129 case CFG80211_CONN_ASSOCIATE_NEXT: 131 case CFG80211_CONN_ASSOCIATE_NEXT:
130 BUG_ON(!rdev->ops->assoc); 132 BUG_ON(!rdev->ops->assoc);
131 wdev->conn->state = CFG80211_CONN_ASSOCIATING; 133 wdev->conn->state = CFG80211_CONN_ASSOCIATING;
@@ -225,7 +227,7 @@ static void __cfg80211_sme_scan_done(struct net_device *dev)
225 if (wdev->sme_state != CFG80211_SME_CONNECTING) 227 if (wdev->sme_state != CFG80211_SME_CONNECTING)
226 return; 228 return;
227 229
228 if (WARN_ON(!wdev->conn)) 230 if (!wdev->conn)
229 return; 231 return;
230 232
231 if (wdev->conn->state != CFG80211_CONN_SCANNING && 233 if (wdev->conn->state != CFG80211_CONN_SCANNING &&
@@ -279,8 +281,12 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
279 /* select automatically between only open, shared, leap */ 281 /* select automatically between only open, shared, leap */
280 switch (wdev->conn->params.auth_type) { 282 switch (wdev->conn->params.auth_type) {
281 case NL80211_AUTHTYPE_OPEN_SYSTEM: 283 case NL80211_AUTHTYPE_OPEN_SYSTEM:
282 wdev->conn->params.auth_type = 284 if (wdev->connect_keys)
283 NL80211_AUTHTYPE_SHARED_KEY; 285 wdev->conn->params.auth_type =
286 NL80211_AUTHTYPE_SHARED_KEY;
287 else
288 wdev->conn->params.auth_type =
289 NL80211_AUTHTYPE_NETWORK_EAP;
284 break; 290 break;
285 case NL80211_AUTHTYPE_SHARED_KEY: 291 case NL80211_AUTHTYPE_SHARED_KEY:
286 wdev->conn->params.auth_type = 292 wdev->conn->params.auth_type =
@@ -295,9 +301,8 @@ void cfg80211_sme_rx_auth(struct net_device *dev,
295 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT; 301 wdev->conn->state = CFG80211_CONN_AUTHENTICATE_NEXT;
296 schedule_work(&rdev->conn_work); 302 schedule_work(&rdev->conn_work);
297 } else if (status_code != WLAN_STATUS_SUCCESS) { 303 } else if (status_code != WLAN_STATUS_SUCCESS) {
298 wdev->sme_state = CFG80211_SME_IDLE; 304 __cfg80211_connect_result(dev, mgmt->bssid, NULL, 0, NULL, 0,
299 kfree(wdev->conn); 305 status_code, false);
300 wdev->conn = NULL;
301 } else if (wdev->sme_state == CFG80211_SME_CONNECTING && 306 } else if (wdev->sme_state == CFG80211_SME_CONNECTING &&
302 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) { 307 wdev->conn->state == CFG80211_CONN_AUTHENTICATING) {
303 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT; 308 wdev->conn->state = CFG80211_CONN_ASSOCIATE_NEXT;
@@ -336,7 +341,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
336 if (req_ie && status == WLAN_STATUS_SUCCESS) { 341 if (req_ie && status == WLAN_STATUS_SUCCESS) {
337 memset(&wrqu, 0, sizeof(wrqu)); 342 memset(&wrqu, 0, sizeof(wrqu));
338 wrqu.data.length = req_ie_len; 343 wrqu.data.length = req_ie_len;
339 wireless_send_event(dev, IWEVASSOCRESPIE, &wrqu, req_ie); 344 wireless_send_event(dev, IWEVASSOCREQIE, &wrqu, req_ie);
340 } 345 }
341 346
342 if (resp_ie && status == WLAN_STATUS_SUCCESS) { 347 if (resp_ie && status == WLAN_STATUS_SUCCESS) {
@@ -354,10 +359,8 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
354#endif 359#endif
355 360
356 if (status == WLAN_STATUS_SUCCESS && 361 if (status == WLAN_STATUS_SUCCESS &&
357 wdev->sme_state == CFG80211_SME_IDLE) { 362 wdev->sme_state == CFG80211_SME_IDLE)
358 wdev->sme_state = CFG80211_SME_CONNECTED; 363 goto success;
359 return;
360 }
361 364
362 if (wdev->sme_state != CFG80211_SME_CONNECTING) 365 if (wdev->sme_state != CFG80211_SME_CONNECTING)
363 return; 366 return;
@@ -371,24 +374,29 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
371 if (wdev->conn) 374 if (wdev->conn)
372 wdev->conn->state = CFG80211_CONN_IDLE; 375 wdev->conn->state = CFG80211_CONN_IDLE;
373 376
374 if (status == WLAN_STATUS_SUCCESS) { 377 if (status != WLAN_STATUS_SUCCESS) {
375 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
376 wdev->ssid, wdev->ssid_len,
377 WLAN_CAPABILITY_ESS,
378 WLAN_CAPABILITY_ESS);
379
380 if (WARN_ON(!bss))
381 return;
382
383 cfg80211_hold_bss(bss_from_pub(bss));
384 wdev->current_bss = bss_from_pub(bss);
385
386 wdev->sme_state = CFG80211_SME_CONNECTED;
387 } else {
388 wdev->sme_state = CFG80211_SME_IDLE; 378 wdev->sme_state = CFG80211_SME_IDLE;
389 kfree(wdev->conn); 379 kfree(wdev->conn);
390 wdev->conn = NULL; 380 wdev->conn = NULL;
381 kfree(wdev->connect_keys);
382 wdev->connect_keys = NULL;
383 return;
391 } 384 }
385
386 bss = cfg80211_get_bss(wdev->wiphy, NULL, bssid,
387 wdev->ssid, wdev->ssid_len,
388 WLAN_CAPABILITY_ESS,
389 WLAN_CAPABILITY_ESS);
390
391 if (WARN_ON(!bss))
392 return;
393
394 cfg80211_hold_bss(bss_from_pub(bss));
395 wdev->current_bss = bss_from_pub(bss);
396
397 success:
398 wdev->sme_state = CFG80211_SME_CONNECTED;
399 cfg80211_upload_connect_keys(wdev);
392} 400}
393 401
394void cfg80211_connect_result(struct net_device *dev, const u8 *bssid, 402void cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
@@ -466,7 +474,7 @@ void __cfg80211_roamed(struct wireless_dev *wdev, const u8 *bssid,
466 if (req_ie) { 474 if (req_ie) {
467 memset(&wrqu, 0, sizeof(wrqu)); 475 memset(&wrqu, 0, sizeof(wrqu));
468 wrqu.data.length = req_ie_len; 476 wrqu.data.length = req_ie_len;
469 wireless_send_event(wdev->netdev, IWEVASSOCRESPIE, 477 wireless_send_event(wdev->netdev, IWEVASSOCREQIE,
470 &wrqu, req_ie); 478 &wrqu, req_ie);
471 } 479 }
472 480
@@ -517,6 +525,8 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
517 size_t ie_len, u16 reason, bool from_ap) 525 size_t ie_len, u16 reason, bool from_ap)
518{ 526{
519 struct wireless_dev *wdev = dev->ieee80211_ptr; 527 struct wireless_dev *wdev = dev->ieee80211_ptr;
528 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
529 int i;
520#ifdef CONFIG_WIRELESS_EXT 530#ifdef CONFIG_WIRELESS_EXT
521 union iwreq_data wrqu; 531 union iwreq_data wrqu;
522#endif 532#endif
@@ -544,8 +554,15 @@ void __cfg80211_disconnected(struct net_device *dev, const u8 *ie,
544 wdev->conn = NULL; 554 wdev->conn = NULL;
545 } 555 }
546 556
547 nl80211_send_disconnected(wiphy_to_dev(wdev->wiphy), dev, 557 nl80211_send_disconnected(rdev, dev, reason, ie, ie_len, from_ap);
548 reason, ie, ie_len, from_ap); 558
559 /*
560 * Delete all the keys ... pairwise keys can't really
561 * exist any more anyway, but default keys might.
562 */
563 if (rdev->ops->del_key)
564 for (i = 0; i < 6; i++)
565 rdev->ops->del_key(wdev->wiphy, dev, i, NULL);
549 566
550#ifdef CONFIG_WIRELESS_EXT 567#ifdef CONFIG_WIRELESS_EXT
551 memset(&wrqu, 0, sizeof(wrqu)); 568 memset(&wrqu, 0, sizeof(wrqu));
@@ -581,7 +598,8 @@ EXPORT_SYMBOL(cfg80211_disconnected);
581 598
582int __cfg80211_connect(struct cfg80211_registered_device *rdev, 599int __cfg80211_connect(struct cfg80211_registered_device *rdev,
583 struct net_device *dev, 600 struct net_device *dev,
584 struct cfg80211_connect_params *connect) 601 struct cfg80211_connect_params *connect,
602 struct cfg80211_cached_keys *connkeys)
585{ 603{
586 struct wireless_dev *wdev = dev->ieee80211_ptr; 604 struct wireless_dev *wdev = dev->ieee80211_ptr;
587 int err; 605 int err;
@@ -591,6 +609,24 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
591 if (wdev->sme_state != CFG80211_SME_IDLE) 609 if (wdev->sme_state != CFG80211_SME_IDLE)
592 return -EALREADY; 610 return -EALREADY;
593 611
612 if (WARN_ON(wdev->connect_keys)) {
613 kfree(wdev->connect_keys);
614 wdev->connect_keys = NULL;
615 }
616
617 if (connkeys && connkeys->def >= 0) {
618 int idx;
619
620 idx = connkeys->def;
621 /* If given a WEP key we may need it for shared key auth */
622 if (connkeys->params[idx].cipher == WLAN_CIPHER_SUITE_WEP40 ||
623 connkeys->params[idx].cipher == WLAN_CIPHER_SUITE_WEP104) {
624 connect->key_idx = idx;
625 connect->key = connkeys->params[idx].key;
626 connect->key_len = connkeys->params[idx].key_len;
627 }
628 }
629
594 if (!rdev->ops->connect) { 630 if (!rdev->ops->connect) {
595 if (!rdev->ops->auth || !rdev->ops->assoc) 631 if (!rdev->ops->auth || !rdev->ops->assoc)
596 return -EOPNOTSUPP; 632 return -EOPNOTSUPP;
@@ -641,6 +677,7 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
641 cfg80211_get_conn_bss(wdev); 677 cfg80211_get_conn_bss(wdev);
642 678
643 wdev->sme_state = CFG80211_SME_CONNECTING; 679 wdev->sme_state = CFG80211_SME_CONNECTING;
680 wdev->connect_keys = connkeys;
644 681
645 /* we're good if we have both BSSID and channel */ 682 /* we're good if we have both BSSID and channel */
646 if (wdev->conn->params.bssid && wdev->conn->params.channel) { 683 if (wdev->conn->params.bssid && wdev->conn->params.channel) {
@@ -663,13 +700,16 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
663 kfree(wdev->conn); 700 kfree(wdev->conn);
664 wdev->conn = NULL; 701 wdev->conn = NULL;
665 wdev->sme_state = CFG80211_SME_IDLE; 702 wdev->sme_state = CFG80211_SME_IDLE;
703 wdev->connect_keys = NULL;
666 } 704 }
667 705
668 return err; 706 return err;
669 } else { 707 } else {
670 wdev->sme_state = CFG80211_SME_CONNECTING; 708 wdev->sme_state = CFG80211_SME_CONNECTING;
709 wdev->connect_keys = connkeys;
671 err = rdev->ops->connect(&rdev->wiphy, dev, connect); 710 err = rdev->ops->connect(&rdev->wiphy, dev, connect);
672 if (err) { 711 if (err) {
712 wdev->connect_keys = NULL;
673 wdev->sme_state = CFG80211_SME_IDLE; 713 wdev->sme_state = CFG80211_SME_IDLE;
674 return err; 714 return err;
675 } 715 }
@@ -683,12 +723,13 @@ int __cfg80211_connect(struct cfg80211_registered_device *rdev,
683 723
684int cfg80211_connect(struct cfg80211_registered_device *rdev, 724int cfg80211_connect(struct cfg80211_registered_device *rdev,
685 struct net_device *dev, 725 struct net_device *dev,
686 struct cfg80211_connect_params *connect) 726 struct cfg80211_connect_params *connect,
727 struct cfg80211_cached_keys *connkeys)
687{ 728{
688 int err; 729 int err;
689 730
690 wdev_lock(dev->ieee80211_ptr); 731 wdev_lock(dev->ieee80211_ptr);
691 err = __cfg80211_connect(rdev, dev, connect); 732 err = __cfg80211_connect(rdev, dev, connect, connkeys);
692 wdev_unlock(dev->ieee80211_ptr); 733 wdev_unlock(dev->ieee80211_ptr);
693 734
694 return err; 735 return err;
@@ -705,6 +746,9 @@ int __cfg80211_disconnect(struct cfg80211_registered_device *rdev,
705 if (wdev->sme_state == CFG80211_SME_IDLE) 746 if (wdev->sme_state == CFG80211_SME_IDLE)
706 return -EINVAL; 747 return -EINVAL;
707 748
749 kfree(wdev->connect_keys);
750 wdev->connect_keys = NULL;
751
708 if (!rdev->ops->disconnect) { 752 if (!rdev->ops->disconnect) {
709 if (!rdev->ops->deauth) 753 if (!rdev->ops->deauth)
710 return -EOPNOTSUPP; 754 return -EOPNOTSUPP;
@@ -782,8 +826,8 @@ void cfg80211_sme_disassoc(struct net_device *dev, int idx)
782 return; 826 return;
783 827
784 memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN); 828 memcpy(bssid, wdev->auth_bsses[idx]->pub.bssid, ETH_ALEN);
785 if (cfg80211_mlme_deauth(rdev, dev, bssid, 829 if (__cfg80211_mlme_deauth(rdev, dev, bssid,
786 NULL, 0, WLAN_REASON_DEAUTH_LEAVING)) { 830 NULL, 0, WLAN_REASON_DEAUTH_LEAVING)) {
787 /* whatever -- assume gone anyway */ 831 /* whatever -- assume gone anyway */
788 cfg80211_unhold_bss(wdev->auth_bsses[idx]); 832 cfg80211_unhold_bss(wdev->auth_bsses[idx]);
789 cfg80211_put_bss(&wdev->auth_bsses[idx]->pub); 833 cfg80211_put_bss(&wdev->auth_bsses[idx]->pub);
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 28f8f96801d4..ba387d85dcfd 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -141,9 +141,12 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy)
141 set_mandatory_flags_band(wiphy->bands[band], band); 141 set_mandatory_flags_band(wiphy->bands[band], band);
142} 142}
143 143
144int cfg80211_validate_key_settings(struct key_params *params, int key_idx, 144int cfg80211_validate_key_settings(struct cfg80211_registered_device *rdev,
145 struct key_params *params, int key_idx,
145 const u8 *mac_addr) 146 const u8 *mac_addr)
146{ 147{
148 int i;
149
147 if (key_idx > 5) 150 if (key_idx > 5)
148 return -EINVAL; 151 return -EINVAL;
149 152
@@ -197,6 +200,12 @@ int cfg80211_validate_key_settings(struct key_params *params, int key_idx,
197 } 200 }
198 } 201 }
199 202
203 for (i = 0; i < rdev->wiphy.n_cipher_suites; i++)
204 if (params->cipher == rdev->wiphy.cipher_suites[i])
205 break;
206 if (i == rdev->wiphy.n_cipher_suites)
207 return -EINVAL;
208
200 return 0; 209 return 0;
201} 210}
202 211
@@ -523,3 +532,37 @@ const u8 *ieee80211_bss_get_ie(struct cfg80211_bss *bss, u8 ie)
523 return NULL; 532 return NULL;
524} 533}
525EXPORT_SYMBOL(ieee80211_bss_get_ie); 534EXPORT_SYMBOL(ieee80211_bss_get_ie);
535
536void cfg80211_upload_connect_keys(struct wireless_dev *wdev)
537{
538 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
539 struct net_device *dev = wdev->netdev;
540 int i;
541
542 if (!wdev->connect_keys)
543 return;
544
545 for (i = 0; i < 6; i++) {
546 if (!wdev->connect_keys->params[i].cipher)
547 continue;
548 if (rdev->ops->add_key(wdev->wiphy, dev, i, NULL,
549 &wdev->connect_keys->params[i])) {
550 printk(KERN_ERR "%s: failed to set key %d\n",
551 dev->name, i);
552 continue;
553 }
554 if (wdev->connect_keys->def == i)
555 if (rdev->ops->set_default_key(wdev->wiphy, dev, i)) {
556 printk(KERN_ERR "%s: failed to set defkey %d\n",
557 dev->name, i);
558 continue;
559 }
560 if (wdev->connect_keys->defmgmt == i)
561 if (rdev->ops->set_default_mgmt_key(wdev->wiphy, dev, i))
562 printk(KERN_ERR "%s: failed to set mgtdef %d\n",
563 dev->name, i);
564 }
565
566 kfree(wdev->connect_keys);
567 wdev->connect_keys = NULL;
568}
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 9d101d566bb1..c7351a98e660 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -453,15 +453,32 @@ int cfg80211_wext_giwretry(struct net_device *dev,
453} 453}
454EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry); 454EXPORT_SYMBOL_GPL(cfg80211_wext_giwretry);
455 455
456static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev, 456static int __cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
457 struct net_device *dev, const u8 *addr, 457 struct net_device *dev, const u8 *addr,
458 bool remove, bool tx_key, int idx, 458 bool remove, bool tx_key, int idx,
459 struct key_params *params) 459 struct key_params *params)
460{ 460{
461 struct wireless_dev *wdev = dev->ieee80211_ptr; 461 struct wireless_dev *wdev = dev->ieee80211_ptr;
462 int err; 462 int err, i;
463
464 if (!wdev->wext.keys) {
465 wdev->wext.keys = kzalloc(sizeof(*wdev->wext.keys),
466 GFP_KERNEL);
467 if (!wdev->wext.keys)
468 return -ENOMEM;
469 for (i = 0; i < 6; i++)
470 wdev->wext.keys->params[i].key =
471 wdev->wext.keys->data[i];
472 }
473
474 if (wdev->iftype != NL80211_IFTYPE_ADHOC &&
475 wdev->iftype != NL80211_IFTYPE_STATION)
476 return -EOPNOTSUPP;
463 477
464 if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) { 478 if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
479 if (!wdev->current_bss)
480 return -ENOLINK;
481
465 if (!rdev->ops->set_default_mgmt_key) 482 if (!rdev->ops->set_default_mgmt_key)
466 return -EOPNOTSUPP; 483 return -EOPNOTSUPP;
467 484
@@ -471,8 +488,14 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
471 return -EINVAL; 488 return -EINVAL;
472 489
473 if (remove) { 490 if (remove) {
474 err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr); 491 err = 0;
492 if (wdev->current_bss)
493 err = rdev->ops->del_key(&rdev->wiphy, dev, idx, addr);
475 if (!err) { 494 if (!err) {
495 if (!addr) {
496 wdev->wext.keys->params[idx].key_len = 0;
497 wdev->wext.keys->params[idx].cipher = 0;
498 }
476 if (idx == wdev->wext.default_key) 499 if (idx == wdev->wext.default_key)
477 wdev->wext.default_key = -1; 500 wdev->wext.default_key = -1;
478 else if (idx == wdev->wext.default_mgmt_key) 501 else if (idx == wdev->wext.default_mgmt_key)
@@ -486,36 +509,65 @@ static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
486 return 0; 509 return 0;
487 510
488 return err; 511 return err;
489 } else { 512 }
490 if (addr)
491 tx_key = false;
492 513
493 if (cfg80211_validate_key_settings(params, idx, addr)) 514 if (addr)
494 return -EINVAL; 515 tx_key = false;
495 516
517 if (cfg80211_validate_key_settings(rdev, params, idx, addr))
518 return -EINVAL;
519
520 err = 0;
521 if (wdev->current_bss)
496 err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params); 522 err = rdev->ops->add_key(&rdev->wiphy, dev, idx, addr, params);
497 if (err) 523 if (err)
498 return err; 524 return err;
499 525
500 if (tx_key || (!addr && wdev->wext.default_key == -1)) { 526 if (!addr) {
527 wdev->wext.keys->params[idx] = *params;
528 memcpy(wdev->wext.keys->data[idx],
529 params->key, params->key_len);
530 wdev->wext.keys->params[idx].key =
531 wdev->wext.keys->data[idx];
532 }
533
534 if ((params->cipher == WLAN_CIPHER_SUITE_WEP40 ||
535 params->cipher == WLAN_CIPHER_SUITE_WEP104) &&
536 (tx_key || (!addr && wdev->wext.default_key == -1))) {
537 if (wdev->current_bss)
501 err = rdev->ops->set_default_key(&rdev->wiphy, 538 err = rdev->ops->set_default_key(&rdev->wiphy,
502 dev, idx); 539 dev, idx);
503 if (!err) 540 if (!err)
504 wdev->wext.default_key = idx; 541 wdev->wext.default_key = idx;
505 return err; 542 return err;
506 } 543 }
507 544
508 if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC && 545 if (params->cipher == WLAN_CIPHER_SUITE_AES_CMAC &&
509 (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) { 546 (tx_key || (!addr && wdev->wext.default_mgmt_key == -1))) {
547 if (wdev->current_bss)
510 err = rdev->ops->set_default_mgmt_key(&rdev->wiphy, 548 err = rdev->ops->set_default_mgmt_key(&rdev->wiphy,
511 dev, idx); 549 dev, idx);
512 if (!err) 550 if (!err)
513 wdev->wext.default_mgmt_key = idx; 551 wdev->wext.default_mgmt_key = idx;
514 return err; 552 return err;
515 }
516
517 return 0;
518 } 553 }
554
555 return 0;
556}
557
558static int cfg80211_set_encryption(struct cfg80211_registered_device *rdev,
559 struct net_device *dev, const u8 *addr,
560 bool remove, bool tx_key, int idx,
561 struct key_params *params)
562{
563 int err;
564
565 wdev_lock(dev->ieee80211_ptr);
566 err = __cfg80211_set_encryption(rdev, dev, addr, remove,
567 tx_key, idx, params);
568 wdev_unlock(dev->ieee80211_ptr);
569
570 return err;
519} 571}
520 572
521int cfg80211_wext_siwencode(struct net_device *dev, 573int cfg80211_wext_siwencode(struct net_device *dev,
@@ -528,6 +580,10 @@ int cfg80211_wext_siwencode(struct net_device *dev,
528 bool remove = false; 580 bool remove = false;
529 struct key_params params; 581 struct key_params params;
530 582
583 if (wdev->iftype != NL80211_IFTYPE_STATION &&
584 wdev->iftype != NL80211_IFTYPE_ADHOC)
585 return -EOPNOTSUPP;
586
531 /* no use -- only MFP (set_default_mgmt_key) is optional */ 587 /* no use -- only MFP (set_default_mgmt_key) is optional */
532 if (!rdev->ops->del_key || 588 if (!rdev->ops->del_key ||
533 !rdev->ops->add_key || 589 !rdev->ops->add_key ||
@@ -548,9 +604,14 @@ int cfg80211_wext_siwencode(struct net_device *dev,
548 remove = true; 604 remove = true;
549 else if (erq->length == 0) { 605 else if (erq->length == 0) {
550 /* No key data - just set the default TX key index */ 606 /* No key data - just set the default TX key index */
551 err = rdev->ops->set_default_key(&rdev->wiphy, dev, idx); 607 err = 0;
608 wdev_lock(wdev);
609 if (wdev->current_bss)
610 err = rdev->ops->set_default_key(&rdev->wiphy,
611 dev, idx);
552 if (!err) 612 if (!err)
553 wdev->wext.default_key = idx; 613 wdev->wext.default_key = idx;
614 wdev_unlock(wdev);
554 return err; 615 return err;
555 } 616 }
556 617
@@ -583,6 +644,10 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
583 struct key_params params; 644 struct key_params params;
584 u32 cipher; 645 u32 cipher;
585 646
647 if (wdev->iftype != NL80211_IFTYPE_STATION &&
648 wdev->iftype != NL80211_IFTYPE_ADHOC)
649 return -EOPNOTSUPP;
650
586 /* no use -- only MFP (set_default_mgmt_key) is optional */ 651 /* no use -- only MFP (set_default_mgmt_key) is optional */
587 if (!rdev->ops->del_key || 652 if (!rdev->ops->del_key ||
588 !rdev->ops->add_key || 653 !rdev->ops->add_key ||
@@ -656,37 +721,15 @@ int cfg80211_wext_siwencodeext(struct net_device *dev,
656} 721}
657EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext); 722EXPORT_SYMBOL_GPL(cfg80211_wext_siwencodeext);
658 723
659struct giwencode_cookie {
660 size_t buflen;
661 char *keybuf;
662};
663
664static void giwencode_get_key_cb(void *cookie, struct key_params *params)
665{
666 struct giwencode_cookie *data = cookie;
667
668 if (!params->key) {
669 data->buflen = 0;
670 return;
671 }
672
673 data->buflen = min_t(size_t, data->buflen, params->key_len);
674 memcpy(data->keybuf, params->key, data->buflen);
675}
676
677int cfg80211_wext_giwencode(struct net_device *dev, 724int cfg80211_wext_giwencode(struct net_device *dev,
678 struct iw_request_info *info, 725 struct iw_request_info *info,
679 struct iw_point *erq, char *keybuf) 726 struct iw_point *erq, char *keybuf)
680{ 727{
681 struct wireless_dev *wdev = dev->ieee80211_ptr; 728 struct wireless_dev *wdev = dev->ieee80211_ptr;
682 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 729 int idx;
683 int idx, err;
684 struct giwencode_cookie data = {
685 .keybuf = keybuf,
686 .buflen = erq->length,
687 };
688 730
689 if (!rdev->ops->get_key) 731 if (wdev->iftype != NL80211_IFTYPE_STATION &&
732 wdev->iftype != NL80211_IFTYPE_ADHOC)
690 return -EOPNOTSUPP; 733 return -EOPNOTSUPP;
691 734
692 idx = erq->flags & IW_ENCODE_INDEX; 735 idx = erq->flags & IW_ENCODE_INDEX;
@@ -701,21 +744,18 @@ int cfg80211_wext_giwencode(struct net_device *dev,
701 744
702 erq->flags = idx + 1; 745 erq->flags = idx + 1;
703 746
704 err = rdev->ops->get_key(&rdev->wiphy, dev, idx, NULL, &data, 747 if (!wdev->wext.keys || !wdev->wext.keys->params[idx].cipher) {
705 giwencode_get_key_cb);
706 if (!err) {
707 erq->length = data.buflen;
708 erq->flags |= IW_ENCODE_ENABLED;
709 return 0;
710 }
711
712 if (err == -ENOENT) {
713 erq->flags |= IW_ENCODE_DISABLED; 748 erq->flags |= IW_ENCODE_DISABLED;
714 erq->length = 0; 749 erq->length = 0;
715 return 0; 750 return 0;
716 } 751 }
717 752
718 return err; 753 erq->length = min_t(size_t, erq->length,
754 wdev->wext.keys->params[idx].key_len);
755 memcpy(keybuf, wdev->wext.keys->params[idx].key, erq->length);
756 erq->flags |= IW_ENCODE_ENABLED;
757
758 return 0;
719} 759}
720EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode); 760EXPORT_SYMBOL_GPL(cfg80211_wext_giwencode);
721 761
@@ -841,9 +881,19 @@ static int cfg80211_set_wpa_version(struct wireless_dev *wdev, u32 wpa_versions)
841 wdev->wext.connect.crypto.wpa_versions = 0; 881 wdev->wext.connect.crypto.wpa_versions = 0;
842 882
843 if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA | 883 if (wpa_versions & ~(IW_AUTH_WPA_VERSION_WPA |
844 IW_AUTH_WPA_VERSION_WPA2)) 884 IW_AUTH_WPA_VERSION_WPA2|
885 IW_AUTH_WPA_VERSION_DISABLED))
845 return -EINVAL; 886 return -EINVAL;
846 887
888 if ((wpa_versions & IW_AUTH_WPA_VERSION_DISABLED) &&
889 (wpa_versions & (IW_AUTH_WPA_VERSION_WPA|
890 IW_AUTH_WPA_VERSION_WPA2)))
891 return -EINVAL;
892
893 if (wpa_versions & IW_AUTH_WPA_VERSION_DISABLED)
894 wdev->wext.connect.crypto.wpa_versions &=
895 ~(NL80211_WPA_VERSION_1|NL80211_WPA_VERSION_2);
896
847 if (wpa_versions & IW_AUTH_WPA_VERSION_WPA) 897 if (wpa_versions & IW_AUTH_WPA_VERSION_WPA)
848 wdev->wext.connect.crypto.wpa_versions |= 898 wdev->wext.connect.crypto.wpa_versions |=
849 NL80211_WPA_VERSION_1; 899 NL80211_WPA_VERSION_1;
@@ -1127,7 +1177,7 @@ int cfg80211_wext_giwrate(struct net_device *dev,
1127 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1177 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
1128 /* we are under RTNL - globally locked - so can use a static struct */ 1178 /* we are under RTNL - globally locked - so can use a static struct */
1129 static struct station_info sinfo; 1179 static struct station_info sinfo;
1130 u8 *addr; 1180 u8 addr[ETH_ALEN];
1131 int err; 1181 int err;
1132 1182
1133 if (wdev->iftype != NL80211_IFTYPE_STATION) 1183 if (wdev->iftype != NL80211_IFTYPE_STATION)
@@ -1136,12 +1186,15 @@ int cfg80211_wext_giwrate(struct net_device *dev,
1136 if (!rdev->ops->get_station) 1186 if (!rdev->ops->get_station)
1137 return -EOPNOTSUPP; 1187 return -EOPNOTSUPP;
1138 1188
1189 err = 0;
1190 wdev_lock(wdev);
1139 if (wdev->current_bss) 1191 if (wdev->current_bss)
1140 addr = wdev->current_bss->pub.bssid; 1192 memcpy(addr, wdev->current_bss->pub.bssid, ETH_ALEN);
1141 else if (wdev->wext.connect.bssid)
1142 addr = wdev->wext.connect.bssid;
1143 else 1193 else
1144 return -EOPNOTSUPP; 1194 err = -EOPNOTSUPP;
1195 wdev_unlock(wdev);
1196 if (err)
1197 return err;
1145 1198
1146 err = rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo); 1199 err = rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo);
1147 if (err) 1200 if (err)
@@ -1167,7 +1220,7 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1167 /* we are under RTNL - globally locked - so can use static structs */ 1220 /* we are under RTNL - globally locked - so can use static structs */
1168 static struct iw_statistics wstats; 1221 static struct iw_statistics wstats;
1169 static struct station_info sinfo; 1222 static struct station_info sinfo;
1170 u8 *addr; 1223 u8 bssid[ETH_ALEN];
1171 1224
1172 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION) 1225 if (dev->ieee80211_ptr->iftype != NL80211_IFTYPE_STATION)
1173 return NULL; 1226 return NULL;
@@ -1175,11 +1228,16 @@ struct iw_statistics *cfg80211_wireless_stats(struct net_device *dev)
1175 if (!rdev->ops->get_station) 1228 if (!rdev->ops->get_station)
1176 return NULL; 1229 return NULL;
1177 1230
1178 addr = wdev->wext.connect.bssid; 1231 /* Grab BSSID of current BSS, if any */
1179 if (!addr) 1232 wdev_lock(wdev);
1233 if (!wdev->current_bss) {
1234 wdev_unlock(wdev);
1180 return NULL; 1235 return NULL;
1236 }
1237 memcpy(bssid, wdev->current_bss->pub.bssid, ETH_ALEN);
1238 wdev_unlock(wdev);
1181 1239
1182 if (rdev->ops->get_station(&rdev->wiphy, dev, addr, &sinfo)) 1240 if (rdev->ops->get_station(&rdev->wiphy, dev, bssid, &sinfo))
1183 return NULL; 1241 return NULL;
1184 1242
1185 memset(&wstats, 0, sizeof(wstats)); 1243 memset(&wstats, 0, sizeof(wstats));
diff --git a/net/wireless/wext-sme.c b/net/wireless/wext-sme.c
index 6f75aaa7f795..4c689fd865b0 100644
--- a/net/wireless/wext-sme.c
+++ b/net/wireless/wext-sme.c
@@ -10,10 +10,11 @@
10#include <net/cfg80211.h> 10#include <net/cfg80211.h>
11#include "nl80211.h" 11#include "nl80211.h"
12 12
13static int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev, 13int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
14 struct wireless_dev *wdev) 14 struct wireless_dev *wdev)
15{ 15{
16 int err; 16 struct cfg80211_cached_keys *ck = NULL;
17 int err, i;
17 18
18 ASSERT_RDEV_LOCK(rdev); 19 ASSERT_RDEV_LOCK(rdev);
19 ASSERT_WDEV_LOCK(wdev); 20 ASSERT_WDEV_LOCK(wdev);
@@ -25,10 +26,25 @@ static int cfg80211_mgd_wext_connect(struct cfg80211_registered_device *rdev,
25 wdev->wext.connect.ie_len = wdev->wext.ie_len; 26 wdev->wext.connect.ie_len = wdev->wext.ie_len;
26 wdev->wext.connect.privacy = wdev->wext.default_key != -1; 27 wdev->wext.connect.privacy = wdev->wext.default_key != -1;
27 28
28 err = 0; 29 if (wdev->wext.keys) {
29 if (wdev->wext.connect.ssid_len != 0) 30 wdev->wext.keys->def = wdev->wext.default_key;
30 err = __cfg80211_connect(rdev, wdev->netdev, 31 wdev->wext.keys->defmgmt = wdev->wext.default_mgmt_key;
31 &wdev->wext.connect); 32 }
33
34 if (!wdev->wext.connect.ssid_len)
35 return 0;
36
37 if (wdev->wext.keys) {
38 ck = kmemdup(wdev->wext.keys, sizeof(*ck), GFP_KERNEL);
39 if (!ck)
40 return -ENOMEM;
41 for (i = 0; i < 6; i++)
42 ck->params[i].key = ck->data[i];
43 }
44 err = __cfg80211_connect(rdev, wdev->netdev,
45 &wdev->wext.connect, ck);
46 if (err)
47 kfree(ck);
32 48
33 return err; 49 return err;
34} 50}
@@ -56,13 +72,14 @@ int cfg80211_mgd_wext_siwfreq(struct net_device *dev,
56 cfg80211_lock_rdev(rdev); 72 cfg80211_lock_rdev(rdev);
57 wdev_lock(wdev); 73 wdev_lock(wdev);
58 74
59 if (wdev->wext.connect.channel == chan) {
60 err = 0;
61 goto out;
62 }
63
64 if (wdev->sme_state != CFG80211_SME_IDLE) { 75 if (wdev->sme_state != CFG80211_SME_IDLE) {
65 bool event = true; 76 bool event = true;
77
78 if (wdev->wext.connect.channel == chan) {
79 err = 0;
80 goto out;
81 }
82
66 /* if SSID set, we'll try right again, avoid event */ 83 /* if SSID set, we'll try right again, avoid event */
67 if (wdev->wext.connect.ssid_len) 84 if (wdev->wext.connect.ssid_len)
68 event = false; 85 event = false;
@@ -148,13 +165,14 @@ int cfg80211_mgd_wext_siwessid(struct net_device *dev,
148 165
149 err = 0; 166 err = 0;
150 167
151 if (wdev->wext.connect.ssid && len &&
152 len == wdev->wext.connect.ssid_len &&
153 memcmp(wdev->wext.connect.ssid, ssid, len))
154 goto out;
155
156 if (wdev->sme_state != CFG80211_SME_IDLE) { 168 if (wdev->sme_state != CFG80211_SME_IDLE) {
157 bool event = true; 169 bool event = true;
170
171 if (wdev->wext.connect.ssid && len &&
172 len == wdev->wext.connect.ssid_len &&
173 memcmp(wdev->wext.connect.ssid, ssid, len) == 0)
174 goto out;
175
158 /* if SSID set now, we'll try to connect, avoid event */ 176 /* if SSID set now, we'll try to connect, avoid event */
159 if (len) 177 if (len)
160 event = false; 178 event = false;
@@ -193,11 +211,7 @@ int cfg80211_mgd_wext_giwessid(struct net_device *dev,
193 data->flags = 0; 211 data->flags = 0;
194 212
195 wdev_lock(wdev); 213 wdev_lock(wdev);
196 if (wdev->ssid_len) { 214 if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) {
197 data->flags = 1;
198 data->length = wdev->ssid_len;
199 memcpy(ssid, wdev->ssid, data->length);
200 } else if (wdev->wext.connect.ssid && wdev->wext.connect.ssid_len) {
201 data->flags = 1; 215 data->flags = 1;
202 data->length = wdev->wext.connect.ssid_len; 216 data->length = wdev->wext.connect.ssid_len;
203 memcpy(ssid, wdev->wext.connect.ssid, data->length); 217 memcpy(ssid, wdev->wext.connect.ssid, data->length);
@@ -232,17 +246,17 @@ int cfg80211_mgd_wext_siwap(struct net_device *dev,
232 cfg80211_lock_rdev(wiphy_to_dev(wdev->wiphy)); 246 cfg80211_lock_rdev(wiphy_to_dev(wdev->wiphy));
233 wdev_lock(wdev); 247 wdev_lock(wdev);
234 248
235 err = 0; 249 if (wdev->sme_state != CFG80211_SME_IDLE) {
236 /* both automatic */ 250 err = 0;
237 if (!bssid && !wdev->wext.connect.bssid) 251 /* both automatic */
238 goto out; 252 if (!bssid && !wdev->wext.connect.bssid)
253 goto out;
239 254
240 /* fixed already - and no change */ 255 /* fixed already - and no change */
241 if (wdev->wext.connect.bssid && bssid && 256 if (wdev->wext.connect.bssid && bssid &&
242 compare_ether_addr(bssid, wdev->wext.connect.bssid) == 0) 257 compare_ether_addr(bssid, wdev->wext.connect.bssid) == 0)
243 goto out; 258 goto out;
244 259
245 if (wdev->sme_state != CFG80211_SME_IDLE) {
246 err = __cfg80211_disconnect(wiphy_to_dev(wdev->wiphy), 260 err = __cfg80211_disconnect(wiphy_to_dev(wdev->wiphy),
247 dev, WLAN_REASON_DEAUTH_LEAVING, 261 dev, WLAN_REASON_DEAUTH_LEAVING,
248 false); 262 false);