aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2010-01-19 14:43:42 -0500
committerDavid S. Miller <davem@davemloft.net>2010-01-19 14:43:42 -0500
commit6373464288cab09bc641be301d8d30fc9f64ba71 (patch)
treec1bc92dc630aa15da2e12bc0d09c92169817a702
parent6d955180b2f9ccff444df06265160868cabb289a (diff)
parent730dd70549e0ec755dd55615ba5cfc38a482a947 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6
Conflicts: drivers/net/wireless/iwlwifi/iwl-core.h
-rw-r--r--Documentation/DocBook/mac80211.tmpl2
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h24
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c22
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.c32
-rw-r--r--drivers/net/wireless/ath/ath5k/eeprom.h8
-rw-r--r--drivers/net/wireless/ath/ath5k/pcu.c121
-rw-r--r--drivers/net/wireless/ath/ath5k/qcu.c20
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig2
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile2
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h76
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c118
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h32
-rw-r--r--drivers/net/wireless/ath/ath9k/gpio.c428
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c110
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c861
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h34
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c1326
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c58
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c38
-rw-r--r--drivers/net/wireless/ath/ath9k/virtual.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c18
-rw-r--r--drivers/net/wireless/b43/b43.h8
-rw-r--r--drivers/net/wireless/b43/main.c8
-rw-r--r--drivers/net/wireless/b43/phy_lp.c24
-rw-r--r--drivers/net/wireless/b43/phy_n.c1795
-rw-r--r--drivers/net/wireless/b43/phy_n.h87
-rw-r--r--drivers/net/wireless/b43/tables_nphy.c577
-rw-r--r--drivers/net/wireless/b43/tables_nphy.h71
-rw-r--r--drivers/net/wireless/b43legacy/main.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c49
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-hcmd.c1
-rw-r--r--drivers/net/wireless/iwmc3200wifi/iwm.h2
-rw-r--r--drivers/net/wireless/mwl8k.c1363
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c29
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c24
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c22
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h6
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00dev.c12
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00queue.c6
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_cmd.c83
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_cmd.h22
-rw-r--r--drivers/net/wireless/wl12xx/wl1251_main.c291
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_reg.h99
-rw-r--r--drivers/net/wireless/wl12xx/wl1271_spi.c3
-rw-r--r--drivers/net/wireless/zd1211rw/zd_mac.c13
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211.h9
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c24
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c4
-rw-r--r--include/linux/ieee80211.h37
-rw-r--r--include/linux/nl80211.h58
-rw-r--r--include/net/cfg80211.h31
-rw-r--r--include/net/mac80211.h151
-rw-r--r--net/mac80211/agg-tx.c5
-rw-r--r--net/mac80211/cfg.c65
-rw-r--r--net/mac80211/debugfs.c94
-rw-r--r--net/mac80211/debugfs_netdev.c44
-rw-r--r--net/mac80211/driver-ops.h15
-rw-r--r--net/mac80211/driver-trace.h23
-rw-r--r--net/mac80211/ieee80211_i.h31
-rw-r--r--net/mac80211/iface.c56
-rw-r--r--net/mac80211/main.c7
-rw-r--r--net/mac80211/mlme.c104
-rw-r--r--net/mac80211/offchannel.c8
-rw-r--r--net/mac80211/rate.c88
-rw-r--r--net/mac80211/rate.h5
-rw-r--r--net/mac80211/rx.c16
-rw-r--r--net/mac80211/scan.c20
-rw-r--r--net/mac80211/sta_info.c21
-rw-r--r--net/mac80211/sta_info.h3
-rw-r--r--net/mac80211/tx.c278
-rw-r--r--net/mac80211/util.c60
-rw-r--r--net/mac80211/wme.c96
-rw-r--r--net/mac80211/wme.h8
-rw-r--r--net/mac80211/work.c28
-rw-r--r--net/wireless/core.c1
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/nl80211.c130
-rw-r--r--net/wireless/reg.c319
-rw-r--r--net/wireless/reg.h11
-rw-r--r--net/wireless/scan.c120
-rw-r--r--net/wireless/sme.c1
-rw-r--r--net/wireless/wext-compat.c34
92 files changed, 7260 insertions, 2757 deletions
diff --git a/Documentation/DocBook/mac80211.tmpl b/Documentation/DocBook/mac80211.tmpl
index f3f37f141dbd..971d1c0c83e5 100644
--- a/Documentation/DocBook/mac80211.tmpl
+++ b/Documentation/DocBook/mac80211.tmpl
@@ -144,7 +144,7 @@ usage should require reading the full document.
144 this though and the recommendation to allow only a single 144 this though and the recommendation to allow only a single
145 interface in STA mode at first! 145 interface in STA mode at first!
146 </para> 146 </para>
147!Finclude/net/mac80211.h ieee80211_if_init_conf 147!Finclude/net/mac80211.h ieee80211_vif
148 </chapter> 148 </chapter>
149 149
150 <chapter id="rx-tx"> 150 <chapter id="rx-tx">
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 6a2a96761111..66bcb506a112 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1063,6 +1063,7 @@ struct ath5k_hw {
1063 u32 ah_cw_min; 1063 u32 ah_cw_min;
1064 u32 ah_cw_max; 1064 u32 ah_cw_max;
1065 u32 ah_limit_tx_retries; 1065 u32 ah_limit_tx_retries;
1066 u8 ah_coverage_class;
1066 1067
1067 /* Antenna Control */ 1068 /* Antenna Control */
1068 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX]; 1069 u32 ah_ant_ctl[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
@@ -1200,6 +1201,7 @@ extern bool ath5k_eeprom_is_hb63(struct ath5k_hw *ah);
1200 1201
1201/* Protocol Control Unit Functions */ 1202/* Protocol Control Unit Functions */
1202extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); 1203extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
1204extern void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class);
1203/* BSSID Functions */ 1205/* BSSID Functions */
1204extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac); 1206extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
1205extern void ath5k_hw_set_associd(struct ath5k_hw *ah); 1207extern void ath5k_hw_set_associd(struct ath5k_hw *ah);
@@ -1231,6 +1233,10 @@ extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
1231extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah); 1233extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
1232extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout); 1234extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
1233extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah); 1235extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
1236/* Clock rate related functions */
1237unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec);
1238unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock);
1239unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah);
1234/* Key table (WEP) functions */ 1240/* Key table (WEP) functions */
1235extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); 1241extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1236extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); 1242extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
@@ -1310,24 +1316,6 @@ extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
1310 * Functions used internaly 1316 * Functions used internaly
1311 */ 1317 */
1312 1318
1313/*
1314 * Translate usec to hw clock units
1315 * TODO: Half/quarter rate
1316 */
1317static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
1318{
1319 return turbo ? (usec * 80) : (usec * 40);
1320}
1321
1322/*
1323 * Translate hw clock units to usec
1324 * TODO: Half/quarter rate
1325 */
1326static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
1327{
1328 return turbo ? (clock / 80) : (clock / 40);
1329}
1330
1331static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah) 1319static inline struct ath_common *ath5k_hw_common(struct ath5k_hw *ah)
1332{ 1320{
1333 return &ah->common; 1321 return &ah->common;
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 72e5ed51c0af..5577bcc80eac 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -254,6 +254,8 @@ static void ath5k_bss_info_changed(struct ieee80211_hw *hw,
254 u32 changes); 254 u32 changes);
255static void ath5k_sw_scan_start(struct ieee80211_hw *hw); 255static void ath5k_sw_scan_start(struct ieee80211_hw *hw);
256static void ath5k_sw_scan_complete(struct ieee80211_hw *hw); 256static void ath5k_sw_scan_complete(struct ieee80211_hw *hw);
257static void ath5k_set_coverage_class(struct ieee80211_hw *hw,
258 u8 coverage_class);
257 259
258static const struct ieee80211_ops ath5k_hw_ops = { 260static const struct ieee80211_ops ath5k_hw_ops = {
259 .tx = ath5k_tx, 261 .tx = ath5k_tx,
@@ -274,6 +276,7 @@ static const struct ieee80211_ops ath5k_hw_ops = {
274 .bss_info_changed = ath5k_bss_info_changed, 276 .bss_info_changed = ath5k_bss_info_changed,
275 .sw_scan_start = ath5k_sw_scan_start, 277 .sw_scan_start = ath5k_sw_scan_start,
276 .sw_scan_complete = ath5k_sw_scan_complete, 278 .sw_scan_complete = ath5k_sw_scan_complete,
279 .set_coverage_class = ath5k_set_coverage_class,
277}; 280};
278 281
279/* 282/*
@@ -3262,3 +3265,22 @@ static void ath5k_sw_scan_complete(struct ieee80211_hw *hw)
3262 ath5k_hw_set_ledstate(sc->ah, sc->assoc ? 3265 ath5k_hw_set_ledstate(sc->ah, sc->assoc ?
3263 AR5K_LED_ASSOC : AR5K_LED_INIT); 3266 AR5K_LED_ASSOC : AR5K_LED_INIT);
3264} 3267}
3268
3269/**
3270 * ath5k_set_coverage_class - Set IEEE 802.11 coverage class
3271 *
3272 * @hw: struct ieee80211_hw pointer
3273 * @coverage_class: IEEE 802.11 coverage class number
3274 *
3275 * Mac80211 callback. Sets slot time, ACK timeout and CTS timeout for given
3276 * coverage class. The values are persistent, they are restored after device
3277 * reset.
3278 */
3279static void ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
3280{
3281 struct ath5k_softc *sc = hw->priv;
3282
3283 mutex_lock(&sc->lock);
3284 ath5k_hw_set_coverage_class(sc->ah, coverage_class);
3285 mutex_unlock(&sc->lock);
3286}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 5d1c8677f180..6a3f4da7fb48 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -97,7 +97,7 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
97 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; 97 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
98 int ret; 98 int ret;
99 u16 val; 99 u16 val;
100 u32 cksum, offset; 100 u32 cksum, offset, eep_max = AR5K_EEPROM_INFO_MAX;
101 101
102 /* 102 /*
103 * Read values from EEPROM and store them in the capability structure 103 * Read values from EEPROM and store them in the capability structure
@@ -116,12 +116,38 @@ ath5k_eeprom_init_header(struct ath5k_hw *ah)
116 * Validate the checksum of the EEPROM date. There are some 116 * Validate the checksum of the EEPROM date. There are some
117 * devices with invalid EEPROMs. 117 * devices with invalid EEPROMs.
118 */ 118 */
119 for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { 119 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_UPPER, val);
120 if (val) {
121 eep_max = (val & AR5K_EEPROM_SIZE_UPPER_MASK) <<
122 AR5K_EEPROM_SIZE_ENDLOC_SHIFT;
123 AR5K_EEPROM_READ(AR5K_EEPROM_SIZE_LOWER, val);
124 eep_max = (eep_max | val) - AR5K_EEPROM_INFO_BASE;
125
126 /*
127 * Fail safe check to prevent stupid loops due
128 * to busted EEPROMs. XXX: This value is likely too
129 * big still, waiting on a better value.
130 */
131 if (eep_max > (3 * AR5K_EEPROM_INFO_MAX)) {
132 ATH5K_ERR(ah->ah_sc, "Invalid max custom EEPROM size: "
133 "%d (0x%04x) max expected: %d (0x%04x)\n",
134 eep_max, eep_max,
135 3 * AR5K_EEPROM_INFO_MAX,
136 3 * AR5K_EEPROM_INFO_MAX);
137 return -EIO;
138 }
139 }
140
141 for (cksum = 0, offset = 0; offset < eep_max; offset++) {
120 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); 142 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
121 cksum ^= val; 143 cksum ^= val;
122 } 144 }
123 if (cksum != AR5K_EEPROM_INFO_CKSUM) { 145 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
124 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); 146 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM "
147 "checksum: 0x%04x eep_max: 0x%04x (%s)\n",
148 cksum, eep_max,
149 eep_max == AR5K_EEPROM_INFO_MAX ?
150 "default size" : "custom size");
125 return -EIO; 151 return -EIO;
126 } 152 }
127 153
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 0123f3521a0b..473a483bb9c3 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -37,6 +37,14 @@
37#define AR5K_EEPROM_RFKILL_POLARITY_S 1 37#define AR5K_EEPROM_RFKILL_POLARITY_S 1
38 38
39#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ 39#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
40
41/* FLASH(EEPROM) Defines for AR531X chips */
42#define AR5K_EEPROM_SIZE_LOWER 0x1b /* size info -- lower */
43#define AR5K_EEPROM_SIZE_UPPER 0x1c /* size info -- upper */
44#define AR5K_EEPROM_SIZE_UPPER_MASK 0xfff0
45#define AR5K_EEPROM_SIZE_UPPER_SHIFT 4
46#define AR5K_EEPROM_SIZE_ENDLOC_SHIFT 12
47
40#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */ 48#define AR5K_EEPROM_CHECKSUM 0x00c0 /* EEPROM checksum */
41#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ 49#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
42#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) 50#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
diff --git a/drivers/net/wireless/ath/ath5k/pcu.c b/drivers/net/wireless/ath/ath5k/pcu.c
index 64fc1eb9b6d9..aefe84f9c04b 100644
--- a/drivers/net/wireless/ath/ath5k/pcu.c
+++ b/drivers/net/wireless/ath/ath5k/pcu.c
@@ -187,8 +187,8 @@ unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
187{ 187{
188 ATH5K_TRACE(ah->ah_sc); 188 ATH5K_TRACE(ah->ah_sc);
189 189
190 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, 190 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
191 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo); 191 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK));
192} 192}
193 193
194/** 194/**
@@ -200,12 +200,12 @@ unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
200int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) 200int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
201{ 201{
202 ATH5K_TRACE(ah->ah_sc); 202 ATH5K_TRACE(ah->ah_sc);
203 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK), 203 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK))
204 ah->ah_turbo) <= timeout) 204 <= timeout)
205 return -EINVAL; 205 return -EINVAL;
206 206
207 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, 207 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
208 ath5k_hw_htoclock(timeout, ah->ah_turbo)); 208 ath5k_hw_htoclock(ah, timeout));
209 209
210 return 0; 210 return 0;
211} 211}
@@ -218,8 +218,8 @@ int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
218unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) 218unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
219{ 219{
220 ATH5K_TRACE(ah->ah_sc); 220 ATH5K_TRACE(ah->ah_sc);
221 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, 221 return ath5k_hw_clocktoh(ah, AR5K_REG_MS(ath5k_hw_reg_read(ah,
222 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo); 222 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS));
223} 223}
224 224
225/** 225/**
@@ -231,17 +231,97 @@ unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
231int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) 231int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
232{ 232{
233 ATH5K_TRACE(ah->ah_sc); 233 ATH5K_TRACE(ah->ah_sc);
234 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS), 234 if (ath5k_hw_clocktoh(ah, AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS))
235 ah->ah_turbo) <= timeout) 235 <= timeout)
236 return -EINVAL; 236 return -EINVAL;
237 237
238 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, 238 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
239 ath5k_hw_htoclock(timeout, ah->ah_turbo)); 239 ath5k_hw_htoclock(ah, timeout));
240 240
241 return 0; 241 return 0;
242} 242}
243 243
244/** 244/**
245 * ath5k_hw_htoclock - Translate usec to hw clock units
246 *
247 * @ah: The &struct ath5k_hw
248 * @usec: value in microseconds
249 */
250unsigned int ath5k_hw_htoclock(struct ath5k_hw *ah, unsigned int usec)
251{
252 return usec * ath5k_hw_get_clockrate(ah);
253}
254
255/**
256 * ath5k_hw_clocktoh - Translate hw clock units to usec
257 * @clock: value in hw clock units
258 */
259unsigned int ath5k_hw_clocktoh(struct ath5k_hw *ah, unsigned int clock)
260{
261 return clock / ath5k_hw_get_clockrate(ah);
262}
263
264/**
265 * ath5k_hw_get_clockrate - Get the clock rate for current mode
266 *
267 * @ah: The &struct ath5k_hw
268 */
269unsigned int ath5k_hw_get_clockrate(struct ath5k_hw *ah)
270{
271 struct ieee80211_channel *channel = ah->ah_current_channel;
272 int clock;
273
274 if (channel->hw_value & CHANNEL_5GHZ)
275 clock = 40; /* 802.11a */
276 else if (channel->hw_value & CHANNEL_CCK)
277 clock = 22; /* 802.11b */
278 else
279 clock = 44; /* 802.11g */
280
281 /* Clock rate in turbo modes is twice the normal rate */
282 if (channel->hw_value & CHANNEL_TURBO)
283 clock *= 2;
284
285 return clock;
286}
287
288/**
289 * ath5k_hw_get_default_slottime - Get the default slot time for current mode
290 *
291 * @ah: The &struct ath5k_hw
292 */
293unsigned int ath5k_hw_get_default_slottime(struct ath5k_hw *ah)
294{
295 struct ieee80211_channel *channel = ah->ah_current_channel;
296
297 if (channel->hw_value & CHANNEL_TURBO)
298 return 6; /* both turbo modes */
299
300 if (channel->hw_value & CHANNEL_CCK)
301 return 20; /* 802.11b */
302
303 return 9; /* 802.11 a/g */
304}
305
306/**
307 * ath5k_hw_get_default_sifs - Get the default SIFS for current mode
308 *
309 * @ah: The &struct ath5k_hw
310 */
311unsigned int ath5k_hw_get_default_sifs(struct ath5k_hw *ah)
312{
313 struct ieee80211_channel *channel = ah->ah_current_channel;
314
315 if (channel->hw_value & CHANNEL_TURBO)
316 return 8; /* both turbo modes */
317
318 if (channel->hw_value & CHANNEL_5GHZ)
319 return 16; /* 802.11a */
320
321 return 10; /* 802.11 b/g */
322}
323
324/**
245 * ath5k_hw_set_lladdr - Set station id 325 * ath5k_hw_set_lladdr - Set station id
246 * 326 *
247 * @ah: The &struct ath5k_hw 327 * @ah: The &struct ath5k_hw
@@ -1050,3 +1130,24 @@ int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
1050 return 0; 1130 return 0;
1051} 1131}
1052 1132
1133/**
1134 * ath5k_hw_set_coverage_class - Set IEEE 802.11 coverage class
1135 *
1136 * @ah: The &struct ath5k_hw
1137 * @coverage_class: IEEE 802.11 coverage class number
1138 *
1139 * Sets slot time, ACK timeout and CTS timeout for given coverage class.
1140 */
1141void ath5k_hw_set_coverage_class(struct ath5k_hw *ah, u8 coverage_class)
1142{
1143 /* As defined by IEEE 802.11-2007 17.3.8.6 */
1144 int slot_time = ath5k_hw_get_default_slottime(ah) + 3 * coverage_class;
1145 int ack_timeout = ath5k_hw_get_default_sifs(ah) + slot_time;
1146 int cts_timeout = ack_timeout;
1147
1148 ath5k_hw_set_slot_time(ah, slot_time);
1149 ath5k_hw_set_ack_timeout(ah, ack_timeout);
1150 ath5k_hw_set_cts_timeout(ah, cts_timeout);
1151
1152 ah->ah_coverage_class = coverage_class;
1153}
diff --git a/drivers/net/wireless/ath/ath5k/qcu.c b/drivers/net/wireless/ath/ath5k/qcu.c
index eeebb9aef206..abe36c0d139c 100644
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -520,12 +520,16 @@ int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
520 */ 520 */
521unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) 521unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
522{ 522{
523 unsigned int slot_time_clock;
524
523 ATH5K_TRACE(ah->ah_sc); 525 ATH5K_TRACE(ah->ah_sc);
526
524 if (ah->ah_version == AR5K_AR5210) 527 if (ah->ah_version == AR5K_AR5210)
525 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah, 528 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_SLOT_TIME);
526 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
527 else 529 else
528 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff; 530 slot_time_clock = ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT);
531
532 return ath5k_hw_clocktoh(ah, slot_time_clock & 0xffff);
529} 533}
530 534
531/* 535/*
@@ -533,15 +537,17 @@ unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
533 */ 537 */
534int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) 538int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
535{ 539{
540 u32 slot_time_clock = ath5k_hw_htoclock(ah, slot_time);
541
536 ATH5K_TRACE(ah->ah_sc); 542 ATH5K_TRACE(ah->ah_sc);
537 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX) 543
544 if (slot_time < 6 || slot_time_clock > AR5K_SLOT_TIME_MAX)
538 return -EINVAL; 545 return -EINVAL;
539 546
540 if (ah->ah_version == AR5K_AR5210) 547 if (ah->ah_version == AR5K_AR5210)
541 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time, 548 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_SLOT_TIME);
542 ah->ah_turbo), AR5K_SLOT_TIME);
543 else 549 else
544 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT); 550 ath5k_hw_reg_write(ah, slot_time_clock, AR5K_DCU_GBL_IFS_SLOT);
545 551
546 return 0; 552 return 0;
547} 553}
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 62954fc77869..6690923fd78c 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -60,12 +60,11 @@ static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
60 !(channel->hw_value & CHANNEL_OFDM)); 60 !(channel->hw_value & CHANNEL_OFDM));
61 61
62 /* Get coefficient 62 /* Get coefficient
63 * ALGO: coef = (5 * clock * carrier_freq) / 2) 63 * ALGO: coef = (5 * clock / carrier_freq) / 2
64 * we scale coef by shifting clock value by 24 for 64 * we scale coef by shifting clock value by 24 for
65 * better precision since we use integers */ 65 * better precision since we use integers */
66 /* TODO: Half/quarter rate */ 66 /* TODO: Half/quarter rate */
67 clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO); 67 clock = (channel->hw_value & CHANNEL_TURBO) ? 80 : 40;
68
69 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; 68 coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq;
70 69
71 /* Get exponent 70 /* Get exponent
@@ -1317,6 +1316,10 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1317 /* Restore antenna mode */ 1316 /* Restore antenna mode */
1318 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode); 1317 ath5k_hw_set_antenna_mode(ah, ah->ah_ant_mode);
1319 1318
1319 /* Restore slot time and ACK timeouts */
1320 if (ah->ah_coverage_class > 0)
1321 ath5k_hw_set_coverage_class(ah, ah->ah_coverage_class);
1322
1320 /* 1323 /*
1321 * Configure QCUs/DCUs 1324 * Configure QCUs/DCUs
1322 */ 1325 */
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index 03a1106ad725..5774cea23a3b 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -25,7 +25,7 @@ config ATH9K
25 25
26config ATH9K_DEBUGFS 26config ATH9K_DEBUGFS
27 bool "Atheros ath9k debugging" 27 bool "Atheros ath9k debugging"
28 depends on ATH9K 28 depends on ATH9K && DEBUG_FS
29 ---help--- 29 ---help---
30 Say Y, if you need access to ath9k's statistics for 30 Say Y, if you need access to ath9k's statistics for
31 interrupts, rate control, etc. 31 interrupts, rate control, etc.
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 4985b2b1b0a9..6b50d5eb9ec3 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -1,4 +1,6 @@
1ath9k-y += beacon.o \ 1ath9k-y += beacon.o \
2 gpio.o \
3 init.o \
2 main.o \ 4 main.o \
3 recv.o \ 5 recv.o \
4 xmit.o \ 6 xmit.o \
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 329e6bc137ab..9e62a569e816 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -121,16 +121,19 @@ static int ath_ahb_probe(struct platform_device *pdev)
121 sc->mem = mem; 121 sc->mem = mem;
122 sc->irq = irq; 122 sc->irq = irq;
123 123
124 ret = ath_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops); 124 /* Will be cleared in ath9k_start() */
125 sc->sc_flags |= SC_OP_INVALID;
126
127 ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
125 if (ret) { 128 if (ret) {
126 dev_err(&pdev->dev, "failed to initialize device\n"); 129 dev_err(&pdev->dev, "request_irq failed\n");
127 goto err_free_hw; 130 goto err_free_hw;
128 } 131 }
129 132
130 ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc); 133 ret = ath9k_init_device(AR5416_AR9100_DEVID, sc, 0x0, &ath_ahb_bus_ops);
131 if (ret) { 134 if (ret) {
132 dev_err(&pdev->dev, "request_irq failed\n"); 135 dev_err(&pdev->dev, "failed to initialize device\n");
133 goto err_detach; 136 goto err_irq;
134 } 137 }
135 138
136 ah = sc->sc_ah; 139 ah = sc->sc_ah;
@@ -143,8 +146,8 @@ static int ath_ahb_probe(struct platform_device *pdev)
143 146
144 return 0; 147 return 0;
145 148
146 err_detach: 149 err_irq:
147 ath_detach(sc); 150 free_irq(irq, sc);
148 err_free_hw: 151 err_free_hw:
149 ieee80211_free_hw(hw); 152 ieee80211_free_hw(hw);
150 platform_set_drvdata(pdev, NULL); 153 platform_set_drvdata(pdev, NULL);
@@ -161,8 +164,12 @@ static int ath_ahb_remove(struct platform_device *pdev)
161 if (hw) { 164 if (hw) {
162 struct ath_wiphy *aphy = hw->priv; 165 struct ath_wiphy *aphy = hw->priv;
163 struct ath_softc *sc = aphy->sc; 166 struct ath_softc *sc = aphy->sc;
167 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
164 168
165 ath_cleanup(sc); 169 ath9k_deinit_device(sc);
170 free_irq(sc->irq, sc);
171 ieee80211_free_hw(sc->hw);
172 ath_bus_cleanup(common);
166 platform_set_drvdata(pdev, NULL); 173 platform_set_drvdata(pdev, NULL);
167 } 174 }
168 175
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 9f1f523e02eb..bf3d4c4bfa52 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -33,11 +33,11 @@ struct ath_node;
33 33
34/* Macro to expand scalars to 64-bit objects */ 34/* Macro to expand scalars to 64-bit objects */
35 35
36#define ito64(x) (sizeof(x) == 8) ? \ 36#define ito64(x) (sizeof(x) == 1) ? \
37 (((unsigned long long int)(x)) & (0xff)) : \ 37 (((unsigned long long int)(x)) & (0xff)) : \
38 (sizeof(x) == 16) ? \ 38 (sizeof(x) == 2) ? \
39 (((unsigned long long int)(x)) & 0xffff) : \ 39 (((unsigned long long int)(x)) & 0xffff) : \
40 ((sizeof(x) == 32) ? \ 40 ((sizeof(x) == 4) ? \
41 (((unsigned long long int)(x)) & 0xffffffff) : \ 41 (((unsigned long long int)(x)) & 0xffffffff) : \
42 (unsigned long long int)(x)) 42 (unsigned long long int)(x))
43 43
@@ -341,6 +341,12 @@ int ath_beaconq_config(struct ath_softc *sc);
341#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */ 341#define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
342#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */ 342#define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
343 343
344void ath_ani_calibrate(unsigned long data);
345
346/**********/
347/* BTCOEX */
348/**********/
349
344/* Defines the BT AR_BT_COEX_WGHT used */ 350/* Defines the BT AR_BT_COEX_WGHT used */
345enum ath_stomp_type { 351enum ath_stomp_type {
346 ATH_BTCOEX_NO_STOMP, 352 ATH_BTCOEX_NO_STOMP,
@@ -361,6 +367,10 @@ struct ath_btcoex {
361 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */ 367 struct ath_gen_timer *no_stomp_timer; /* Timer for no BT stomping */
362}; 368};
363 369
370int ath_init_btcoex_timer(struct ath_softc *sc);
371void ath9k_btcoex_timer_resume(struct ath_softc *sc);
372void ath9k_btcoex_timer_pause(struct ath_softc *sc);
373
364/********************/ 374/********************/
365/* LED Control */ 375/* LED Control */
366/********************/ 376/********************/
@@ -385,6 +395,9 @@ struct ath_led {
385 bool registered; 395 bool registered;
386}; 396};
387 397
398void ath_init_leds(struct ath_softc *sc);
399void ath_deinit_leds(struct ath_softc *sc);
400
388/********************/ 401/********************/
389/* Main driver core */ 402/* Main driver core */
390/********************/ 403/********************/
@@ -403,26 +416,28 @@ struct ath_led {
403#define ATH_TXPOWER_MAX 100 /* .5 dBm units */ 416#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
404#define ATH_RATE_DUMMY_MARKER 0 417#define ATH_RATE_DUMMY_MARKER 0
405 418
406#define SC_OP_INVALID BIT(0) 419#define SC_OP_INVALID BIT(0)
407#define SC_OP_BEACONS BIT(1) 420#define SC_OP_BEACONS BIT(1)
408#define SC_OP_RXAGGR BIT(2) 421#define SC_OP_RXAGGR BIT(2)
409#define SC_OP_TXAGGR BIT(3) 422#define SC_OP_TXAGGR BIT(3)
410#define SC_OP_FULL_RESET BIT(4) 423#define SC_OP_FULL_RESET BIT(4)
411#define SC_OP_PREAMBLE_SHORT BIT(5) 424#define SC_OP_PREAMBLE_SHORT BIT(5)
412#define SC_OP_PROTECT_ENABLE BIT(6) 425#define SC_OP_PROTECT_ENABLE BIT(6)
413#define SC_OP_RXFLUSH BIT(7) 426#define SC_OP_RXFLUSH BIT(7)
414#define SC_OP_LED_ASSOCIATED BIT(8) 427#define SC_OP_LED_ASSOCIATED BIT(8)
415#define SC_OP_WAIT_FOR_BEACON BIT(12) 428#define SC_OP_LED_ON BIT(9)
416#define SC_OP_LED_ON BIT(13) 429#define SC_OP_SCANNING BIT(10)
417#define SC_OP_SCANNING BIT(14) 430#define SC_OP_TSF_RESET BIT(11)
418#define SC_OP_TSF_RESET BIT(15) 431#define SC_OP_BT_PRIORITY_DETECTED BIT(12)
419#define SC_OP_WAIT_FOR_CAB BIT(16) 432
420#define SC_OP_WAIT_FOR_PSPOLL_DATA BIT(17) 433/* Powersave flags */
421#define SC_OP_WAIT_FOR_TX_ACK BIT(18) 434#define PS_WAIT_FOR_BEACON BIT(0)
422#define SC_OP_BEACON_SYNC BIT(19) 435#define PS_WAIT_FOR_CAB BIT(1)
423#define SC_OP_BT_PRIORITY_DETECTED BIT(21) 436#define PS_WAIT_FOR_PSPOLL_DATA BIT(2)
424#define SC_OP_NULLFUNC_COMPLETED BIT(22) 437#define PS_WAIT_FOR_TX_ACK BIT(3)
425#define SC_OP_PS_ENABLED BIT(23) 438#define PS_BEACON_SYNC BIT(4)
439#define PS_NULLFUNC_COMPLETED BIT(5)
440#define PS_ENABLED BIT(6)
426 441
427struct ath_wiphy; 442struct ath_wiphy;
428struct ath_rate_table; 443struct ath_rate_table;
@@ -458,6 +473,7 @@ struct ath_softc {
458 473
459 u32 intrstatus; 474 u32 intrstatus;
460 u32 sc_flags; /* SC_OP_* */ 475 u32 sc_flags; /* SC_OP_* */
476 u16 ps_flags; /* PS_* */
461 u16 curtxpow; 477 u16 curtxpow;
462 u8 nbcnvifs; 478 u8 nbcnvifs;
463 u16 nvifs; 479 u16 nvifs;
@@ -508,6 +524,7 @@ struct ath_wiphy {
508 int chan_is_ht; 524 int chan_is_ht;
509}; 525};
510 526
527void ath9k_tasklet(unsigned long data);
511int ath_reset(struct ath_softc *sc, bool retry_tx); 528int ath_reset(struct ath_softc *sc, bool retry_tx);
512int ath_get_hal_qnum(u16 queue, struct ath_softc *sc); 529int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
513int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc); 530int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
@@ -524,15 +541,15 @@ static inline void ath_bus_cleanup(struct ath_common *common)
524} 541}
525 542
526extern struct ieee80211_ops ath9k_ops; 543extern struct ieee80211_ops ath9k_ops;
544extern int modparam_nohwcrypt;
527 545
528irqreturn_t ath_isr(int irq, void *dev); 546irqreturn_t ath_isr(int irq, void *dev);
529void ath_cleanup(struct ath_softc *sc); 547int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
530int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
531 const struct ath_bus_ops *bus_ops); 548 const struct ath_bus_ops *bus_ops);
532void ath_detach(struct ath_softc *sc); 549void ath9k_deinit_device(struct ath_softc *sc);
533const char *ath_mac_bb_name(u32 mac_bb_version); 550const char *ath_mac_bb_name(u32 mac_bb_version);
534const char *ath_rf_name(u16 rf_version); 551const char *ath_rf_name(u16 rf_version);
535void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw); 552void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
536void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw, 553void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
537 struct ath9k_channel *ichan); 554 struct ath9k_channel *ichan);
538void ath_update_chainmask(struct ath_softc *sc, int is_ht); 555void ath_update_chainmask(struct ath_softc *sc, int is_ht);
@@ -541,6 +558,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
541 558
542void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw); 559void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw);
543void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw); 560void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw);
561bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
544 562
545#ifdef CONFIG_PCI 563#ifdef CONFIG_PCI
546int ath_pci_init(void); 564int ath_pci_init(void);
@@ -582,4 +600,8 @@ void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
582void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue); 600void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
583 601
584int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype); 602int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
603
604void ath_start_rfkill_poll(struct ath_softc *sc);
605extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
606
585#endif /* ATH9K_H */ 607#endif /* ATH9K_H */
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 1660ef17aaf5..422454fe4ff0 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -480,7 +480,8 @@ void ath_beacon_tasklet(unsigned long data)
480 sc->beacon.updateslot = COMMIT; /* commit next beacon */ 480 sc->beacon.updateslot = COMMIT; /* commit next beacon */
481 sc->beacon.slotupdate = slot; 481 sc->beacon.slotupdate = slot;
482 } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) { 482 } else if (sc->beacon.updateslot == COMMIT && sc->beacon.slotupdate == slot) {
483 ath9k_hw_setslottime(sc->sc_ah, sc->beacon.slottime); 483 ah->slottime = sc->beacon.slottime;
484 ath9k_hw_init_global_settings(ah);
484 sc->beacon.updateslot = OK; 485 sc->beacon.updateslot = OK;
485 } 486 }
486 if (bfaddr != 0) { 487 if (bfaddr != 0) {
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 592f1b70f55a..9489b6b25b5f 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -580,6 +580,116 @@ static const struct file_operations fops_xmit = {
580 .owner = THIS_MODULE 580 .owner = THIS_MODULE
581}; 581};
582 582
583static ssize_t read_file_recv(struct file *file, char __user *user_buf,
584 size_t count, loff_t *ppos)
585{
586#define PHY_ERR(s, p) \
587 len += snprintf(buf + len, size - len, "%18s : %10u\n", s, \
588 sc->debug.stats.rxstats.phy_err_stats[p]);
589
590 struct ath_softc *sc = file->private_data;
591 char *buf;
592 unsigned int len = 0, size = 1152;
593 ssize_t retval = 0;
594
595 buf = kzalloc(size, GFP_KERNEL);
596 if (buf == NULL)
597 return 0;
598
599 len += snprintf(buf + len, size - len,
600 "%18s : %10u\n", "CRC ERR",
601 sc->debug.stats.rxstats.crc_err);
602 len += snprintf(buf + len, size - len,
603 "%18s : %10u\n", "DECRYPT CRC ERR",
604 sc->debug.stats.rxstats.decrypt_crc_err);
605 len += snprintf(buf + len, size - len,
606 "%18s : %10u\n", "PHY ERR",
607 sc->debug.stats.rxstats.phy_err);
608 len += snprintf(buf + len, size - len,
609 "%18s : %10u\n", "MIC ERR",
610 sc->debug.stats.rxstats.mic_err);
611 len += snprintf(buf + len, size - len,
612 "%18s : %10u\n", "PRE-DELIM CRC ERR",
613 sc->debug.stats.rxstats.pre_delim_crc_err);
614 len += snprintf(buf + len, size - len,
615 "%18s : %10u\n", "POST-DELIM CRC ERR",
616 sc->debug.stats.rxstats.post_delim_crc_err);
617 len += snprintf(buf + len, size - len,
618 "%18s : %10u\n", "DECRYPT BUSY ERR",
619 sc->debug.stats.rxstats.decrypt_busy_err);
620
621 PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
622 PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
623 PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
624 PHY_ERR("RATE", ATH9K_PHYERR_RATE);
625 PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
626 PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
627 PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
628 PHY_ERR("TOR", ATH9K_PHYERR_TOR);
629 PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
630 PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
631 PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
632 PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
633 PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
634 PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
635 PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
636 PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
637 PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
638 PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
639 PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
640 PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
641 PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
642 PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
643 PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
644 PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
645 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
646 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
647
648 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
649 kfree(buf);
650
651 return retval;
652
653#undef PHY_ERR
654}
655
656void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf)
657{
658#define RX_STAT_INC(c) sc->debug.stats.rxstats.c++
659#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++
660
661 struct ath_desc *ds = bf->bf_desc;
662 u32 phyerr;
663
664 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
665 RX_STAT_INC(crc_err);
666 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT)
667 RX_STAT_INC(decrypt_crc_err);
668 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC)
669 RX_STAT_INC(mic_err);
670 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_PRE)
671 RX_STAT_INC(pre_delim_crc_err);
672 if (ds->ds_rxstat.rs_status & ATH9K_RX_DELIM_CRC_POST)
673 RX_STAT_INC(post_delim_crc_err);
674 if (ds->ds_rxstat.rs_status & ATH9K_RX_DECRYPT_BUSY)
675 RX_STAT_INC(decrypt_busy_err);
676
677 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) {
678 RX_STAT_INC(phy_err);
679 phyerr = ds->ds_rxstat.rs_phyerr & 0x24;
680 RX_PHY_ERR_INC(phyerr);
681 }
682
683#undef RX_STAT_INC
684#undef RX_PHY_ERR_INC
685}
686
687static const struct file_operations fops_recv = {
688 .read = read_file_recv,
689 .open = ath9k_debugfs_open,
690 .owner = THIS_MODULE
691};
692
583int ath9k_init_debug(struct ath_hw *ah) 693int ath9k_init_debug(struct ath_hw *ah)
584{ 694{
585 struct ath_common *common = ath9k_hw_common(ah); 695 struct ath_common *common = ath9k_hw_common(ah);
@@ -632,6 +742,13 @@ int ath9k_init_debug(struct ath_hw *ah)
632 if (!sc->debug.debugfs_xmit) 742 if (!sc->debug.debugfs_xmit)
633 goto err; 743 goto err;
634 744
745 sc->debug.debugfs_recv = debugfs_create_file("recv",
746 S_IRUSR,
747 sc->debug.debugfs_phy,
748 sc, &fops_recv);
749 if (!sc->debug.debugfs_recv)
750 goto err;
751
635 return 0; 752 return 0;
636err: 753err:
637 ath9k_exit_debug(ah); 754 ath9k_exit_debug(ah);
@@ -643,6 +760,7 @@ void ath9k_exit_debug(struct ath_hw *ah)
643 struct ath_common *common = ath9k_hw_common(ah); 760 struct ath_common *common = ath9k_hw_common(ah);
644 struct ath_softc *sc = (struct ath_softc *) common->priv; 761 struct ath_softc *sc = (struct ath_softc *) common->priv;
645 762
763 debugfs_remove(sc->debug.debugfs_recv);
646 debugfs_remove(sc->debug.debugfs_xmit); 764 debugfs_remove(sc->debug.debugfs_xmit);
647 debugfs_remove(sc->debug.debugfs_wiphy); 765 debugfs_remove(sc->debug.debugfs_wiphy);
648 debugfs_remove(sc->debug.debugfs_rcstat); 766 debugfs_remove(sc->debug.debugfs_rcstat);
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 536663e3ee11..86780e68b31e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -116,10 +116,35 @@ struct ath_tx_stats {
116 u32 delim_underrun; 116 u32 delim_underrun;
117}; 117};
118 118
119/**
120 * struct ath_rx_stats - RX Statistics
121 * @crc_err: No. of frames with incorrect CRC value
122 * @decrypt_crc_err: No. of frames whose CRC check failed after
123 decryption process completed
124 * @phy_err: No. of frames whose reception failed because the PHY
125 encountered an error
126 * @mic_err: No. of frames with incorrect TKIP MIC verification failure
127 * @pre_delim_crc_err: Pre-Frame delimiter CRC error detections
128 * @post_delim_crc_err: Post-Frame delimiter CRC error detections
129 * @decrypt_busy_err: Decryption interruptions counter
130 * @phy_err_stats: Individual PHY error statistics
131 */
132struct ath_rx_stats {
133 u32 crc_err;
134 u32 decrypt_crc_err;
135 u32 phy_err;
136 u32 mic_err;
137 u32 pre_delim_crc_err;
138 u32 post_delim_crc_err;
139 u32 decrypt_busy_err;
140 u32 phy_err_stats[ATH9K_PHYERR_MAX];
141};
142
119struct ath_stats { 143struct ath_stats {
120 struct ath_interrupt_stats istats; 144 struct ath_interrupt_stats istats;
121 struct ath_rc_stats rcstats[RATE_TABLE_SIZE]; 145 struct ath_rc_stats rcstats[RATE_TABLE_SIZE];
122 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES]; 146 struct ath_tx_stats txstats[ATH9K_NUM_TX_QUEUES];
147 struct ath_rx_stats rxstats;
123}; 148};
124 149
125struct ath9k_debug { 150struct ath9k_debug {
@@ -130,6 +155,7 @@ struct ath9k_debug {
130 struct dentry *debugfs_rcstat; 155 struct dentry *debugfs_rcstat;
131 struct dentry *debugfs_wiphy; 156 struct dentry *debugfs_wiphy;
132 struct dentry *debugfs_xmit; 157 struct dentry *debugfs_xmit;
158 struct dentry *debugfs_recv;
133 struct ath_stats stats; 159 struct ath_stats stats;
134}; 160};
135 161
@@ -142,6 +168,7 @@ void ath_debug_stat_interrupt(struct ath_softc *sc, enum ath9k_int status);
142void ath_debug_stat_rc(struct ath_softc *sc, int final_rate); 168void ath_debug_stat_rc(struct ath_softc *sc, int final_rate);
143void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq, 169void ath_debug_stat_tx(struct ath_softc *sc, struct ath_txq *txq,
144 struct ath_buf *bf); 170 struct ath_buf *bf);
171void ath_debug_stat_rx(struct ath_softc *sc, struct ath_buf *bf);
145void ath_debug_stat_retries(struct ath_softc *sc, int rix, 172void ath_debug_stat_retries(struct ath_softc *sc, int rix,
146 int xretries, int retries, u8 per); 173 int xretries, int retries, u8 per);
147 174
@@ -181,6 +208,11 @@ static inline void ath_debug_stat_tx(struct ath_softc *sc,
181{ 208{
182} 209}
183 210
211static inline void ath_debug_stat_rx(struct ath_softc *sc,
212 struct ath_buf *bf)
213{
214}
215
184static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix, 216static inline void ath_debug_stat_retries(struct ath_softc *sc, int rix,
185 int xretries, int retries, u8 per) 217 int xretries, int retries, u8 per)
186{ 218{
diff --git a/drivers/net/wireless/ath/ath9k/gpio.c b/drivers/net/wireless/ath/ath9k/gpio.c
new file mode 100644
index 000000000000..e204bd25ff65
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -0,0 +1,428 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19/********************************/
20/* LED functions */
21/********************************/
22
23static void ath_led_blink_work(struct work_struct *work)
24{
25 struct ath_softc *sc = container_of(work, struct ath_softc,
26 ath_led_blink_work.work);
27
28 if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
29 return;
30
31 if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
32 (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
33 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
34 else
35 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
36 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
37
38 ieee80211_queue_delayed_work(sc->hw,
39 &sc->ath_led_blink_work,
40 (sc->sc_flags & SC_OP_LED_ON) ?
41 msecs_to_jiffies(sc->led_off_duration) :
42 msecs_to_jiffies(sc->led_on_duration));
43
44 sc->led_on_duration = sc->led_on_cnt ?
45 max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
46 ATH_LED_ON_DURATION_IDLE;
47 sc->led_off_duration = sc->led_off_cnt ?
48 max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
49 ATH_LED_OFF_DURATION_IDLE;
50 sc->led_on_cnt = sc->led_off_cnt = 0;
51 if (sc->sc_flags & SC_OP_LED_ON)
52 sc->sc_flags &= ~SC_OP_LED_ON;
53 else
54 sc->sc_flags |= SC_OP_LED_ON;
55}
56
57static void ath_led_brightness(struct led_classdev *led_cdev,
58 enum led_brightness brightness)
59{
60 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
61 struct ath_softc *sc = led->sc;
62
63 switch (brightness) {
64 case LED_OFF:
65 if (led->led_type == ATH_LED_ASSOC ||
66 led->led_type == ATH_LED_RADIO) {
67 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
68 (led->led_type == ATH_LED_RADIO));
69 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
70 if (led->led_type == ATH_LED_RADIO)
71 sc->sc_flags &= ~SC_OP_LED_ON;
72 } else {
73 sc->led_off_cnt++;
74 }
75 break;
76 case LED_FULL:
77 if (led->led_type == ATH_LED_ASSOC) {
78 sc->sc_flags |= SC_OP_LED_ASSOCIATED;
79 ieee80211_queue_delayed_work(sc->hw,
80 &sc->ath_led_blink_work, 0);
81 } else if (led->led_type == ATH_LED_RADIO) {
82 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
83 sc->sc_flags |= SC_OP_LED_ON;
84 } else {
85 sc->led_on_cnt++;
86 }
87 break;
88 default:
89 break;
90 }
91}
92
93static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
94 char *trigger)
95{
96 int ret;
97
98 led->sc = sc;
99 led->led_cdev.name = led->name;
100 led->led_cdev.default_trigger = trigger;
101 led->led_cdev.brightness_set = ath_led_brightness;
102
103 ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
104 if (ret)
105 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
106 "Failed to register led:%s", led->name);
107 else
108 led->registered = 1;
109 return ret;
110}
111
112static void ath_unregister_led(struct ath_led *led)
113{
114 if (led->registered) {
115 led_classdev_unregister(&led->led_cdev);
116 led->registered = 0;
117 }
118}
119
120void ath_deinit_leds(struct ath_softc *sc)
121{
122 ath_unregister_led(&sc->assoc_led);
123 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
124 ath_unregister_led(&sc->tx_led);
125 ath_unregister_led(&sc->rx_led);
126 ath_unregister_led(&sc->radio_led);
127 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
128}
129
130void ath_init_leds(struct ath_softc *sc)
131{
132 char *trigger;
133 int ret;
134
135 if (AR_SREV_9287(sc->sc_ah))
136 sc->sc_ah->led_pin = ATH_LED_PIN_9287;
137 else
138 sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
139
140 /* Configure gpio 1 for output */
141 ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
142 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
143 /* LED off, active low */
144 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
145
146 INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
147
148 trigger = ieee80211_get_radio_led_name(sc->hw);
149 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
150 "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
151 ret = ath_register_led(sc, &sc->radio_led, trigger);
152 sc->radio_led.led_type = ATH_LED_RADIO;
153 if (ret)
154 goto fail;
155
156 trigger = ieee80211_get_assoc_led_name(sc->hw);
157 snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
158 "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
159 ret = ath_register_led(sc, &sc->assoc_led, trigger);
160 sc->assoc_led.led_type = ATH_LED_ASSOC;
161 if (ret)
162 goto fail;
163
164 trigger = ieee80211_get_tx_led_name(sc->hw);
165 snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
166 "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
167 ret = ath_register_led(sc, &sc->tx_led, trigger);
168 sc->tx_led.led_type = ATH_LED_TX;
169 if (ret)
170 goto fail;
171
172 trigger = ieee80211_get_rx_led_name(sc->hw);
173 snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
174 "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
175 ret = ath_register_led(sc, &sc->rx_led, trigger);
176 sc->rx_led.led_type = ATH_LED_RX;
177 if (ret)
178 goto fail;
179
180 return;
181
182fail:
183 cancel_delayed_work_sync(&sc->ath_led_blink_work);
184 ath_deinit_leds(sc);
185}
186
187/*******************/
188/* Rfkill */
189/*******************/
190
191static bool ath_is_rfkill_set(struct ath_softc *sc)
192{
193 struct ath_hw *ah = sc->sc_ah;
194
195 return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
196 ah->rfkill_polarity;
197}
198
199void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
200{
201 struct ath_wiphy *aphy = hw->priv;
202 struct ath_softc *sc = aphy->sc;
203 bool blocked = !!ath_is_rfkill_set(sc);
204
205 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
206}
207
208void ath_start_rfkill_poll(struct ath_softc *sc)
209{
210 struct ath_hw *ah = sc->sc_ah;
211
212 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
213 wiphy_rfkill_start_polling(sc->hw->wiphy);
214}
215
216/******************/
217/* BTCOEX */
218/******************/
219
220/*
221 * Detects if there is any priority bt traffic
222 */
223static void ath_detect_bt_priority(struct ath_softc *sc)
224{
225 struct ath_btcoex *btcoex = &sc->btcoex;
226 struct ath_hw *ah = sc->sc_ah;
227
228 if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio))
229 btcoex->bt_priority_cnt++;
230
231 if (time_after(jiffies, btcoex->bt_priority_time +
232 msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
233 if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
234 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
235 "BT priority traffic detected");
236 sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
237 } else {
238 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
239 }
240
241 btcoex->bt_priority_cnt = 0;
242 btcoex->bt_priority_time = jiffies;
243 }
244}
245
246/*
247 * Configures appropriate weight based on stomp type.
248 */
249static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
250 enum ath_stomp_type stomp_type)
251{
252 struct ath_hw *ah = sc->sc_ah;
253
254 switch (stomp_type) {
255 case ATH_BTCOEX_STOMP_ALL:
256 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
257 AR_STOMP_ALL_WLAN_WGHT);
258 break;
259 case ATH_BTCOEX_STOMP_LOW:
260 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
261 AR_STOMP_LOW_WLAN_WGHT);
262 break;
263 case ATH_BTCOEX_STOMP_NONE:
264 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
265 AR_STOMP_NONE_WLAN_WGHT);
266 break;
267 default:
268 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
269 "Invalid Stomptype\n");
270 break;
271 }
272
273 ath9k_hw_btcoex_enable(ah);
274}
275
276static void ath9k_gen_timer_start(struct ath_hw *ah,
277 struct ath_gen_timer *timer,
278 u32 timer_next,
279 u32 timer_period)
280{
281 struct ath_common *common = ath9k_hw_common(ah);
282 struct ath_softc *sc = (struct ath_softc *) common->priv;
283
284 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
285
286 if ((sc->imask & ATH9K_INT_GENTIMER) == 0) {
287 ath9k_hw_set_interrupts(ah, 0);
288 sc->imask |= ATH9K_INT_GENTIMER;
289 ath9k_hw_set_interrupts(ah, sc->imask);
290 }
291}
292
293static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
294{
295 struct ath_common *common = ath9k_hw_common(ah);
296 struct ath_softc *sc = (struct ath_softc *) common->priv;
297 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
298
299 ath9k_hw_gen_timer_stop(ah, timer);
300
301 /* if no timer is enabled, turn off interrupt mask */
302 if (timer_table->timer_mask.val == 0) {
303 ath9k_hw_set_interrupts(ah, 0);
304 sc->imask &= ~ATH9K_INT_GENTIMER;
305 ath9k_hw_set_interrupts(ah, sc->imask);
306 }
307}
308
309/*
310 * This is the master bt coex timer which runs for every
311 * 45ms, bt traffic will be given priority during 55% of this
312 * period while wlan gets remaining 45%
313 */
314static void ath_btcoex_period_timer(unsigned long data)
315{
316 struct ath_softc *sc = (struct ath_softc *) data;
317 struct ath_hw *ah = sc->sc_ah;
318 struct ath_btcoex *btcoex = &sc->btcoex;
319
320 ath_detect_bt_priority(sc);
321
322 spin_lock_bh(&btcoex->btcoex_lock);
323
324 ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type);
325
326 spin_unlock_bh(&btcoex->btcoex_lock);
327
328 if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
329 if (btcoex->hw_timer_enabled)
330 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
331
332 ath9k_gen_timer_start(ah,
333 btcoex->no_stomp_timer,
334 (ath9k_hw_gettsf32(ah) +
335 btcoex->btcoex_no_stomp),
336 btcoex->btcoex_no_stomp * 10);
337 btcoex->hw_timer_enabled = true;
338 }
339
340 mod_timer(&btcoex->period_timer, jiffies +
341 msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
342}
343
344/*
345 * Generic tsf based hw timer which configures weight
346 * registers to time slice between wlan and bt traffic
347 */
348static void ath_btcoex_no_stomp_timer(void *arg)
349{
350 struct ath_softc *sc = (struct ath_softc *)arg;
351 struct ath_hw *ah = sc->sc_ah;
352 struct ath_btcoex *btcoex = &sc->btcoex;
353
354 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
355 "no stomp timer running \n");
356
357 spin_lock_bh(&btcoex->btcoex_lock);
358
359 if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
360 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
361 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
362 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
363
364 spin_unlock_bh(&btcoex->btcoex_lock);
365}
366
367int ath_init_btcoex_timer(struct ath_softc *sc)
368{
369 struct ath_btcoex *btcoex = &sc->btcoex;
370
371 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
372 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
373 btcoex->btcoex_period / 100;
374
375 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
376 (unsigned long) sc);
377
378 spin_lock_init(&btcoex->btcoex_lock);
379
380 btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
381 ath_btcoex_no_stomp_timer,
382 ath_btcoex_no_stomp_timer,
383 (void *) sc, AR_FIRST_NDP_TIMER);
384
385 if (!btcoex->no_stomp_timer)
386 return -ENOMEM;
387
388 return 0;
389}
390
391/*
392 * (Re)start btcoex timers
393 */
394void ath9k_btcoex_timer_resume(struct ath_softc *sc)
395{
396 struct ath_btcoex *btcoex = &sc->btcoex;
397 struct ath_hw *ah = sc->sc_ah;
398
399 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
400 "Starting btcoex timers");
401
402 /* make sure duty cycle timer is also stopped when resuming */
403 if (btcoex->hw_timer_enabled)
404 ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
405
406 btcoex->bt_priority_cnt = 0;
407 btcoex->bt_priority_time = jiffies;
408 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
409
410 mod_timer(&btcoex->period_timer, jiffies);
411}
412
413
414/*
415 * Pause btcoex timer and bt duty cycle timer
416 */
417void ath9k_btcoex_timer_pause(struct ath_softc *sc)
418{
419 struct ath_btcoex *btcoex = &sc->btcoex;
420 struct ath_hw *ah = sc->sc_ah;
421
422 del_timer_sync(&btcoex->period_timer);
423
424 if (btcoex->hw_timer_enabled)
425 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
426
427 btcoex->hw_timer_enabled = false;
428}
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 9474f9f6d400..0b1dd10f1d84 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -52,28 +52,6 @@ module_exit(ath9k_exit);
52/* Helper Functions */ 52/* Helper Functions */
53/********************/ 53/********************/
54 54
55static u32 ath9k_hw_mac_usec(struct ath_hw *ah, u32 clks)
56{
57 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
58
59 if (!ah->curchan) /* should really check for CCK instead */
60 return clks / ATH9K_CLOCK_RATE_CCK;
61 if (conf->channel->band == IEEE80211_BAND_2GHZ)
62 return clks / ATH9K_CLOCK_RATE_2GHZ_OFDM;
63
64 return clks / ATH9K_CLOCK_RATE_5GHZ_OFDM;
65}
66
67static u32 ath9k_hw_mac_to_usec(struct ath_hw *ah, u32 clks)
68{
69 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
70
71 if (conf_is_ht40(conf))
72 return ath9k_hw_mac_usec(ah, clks) / 2;
73 else
74 return ath9k_hw_mac_usec(ah, clks);
75}
76
77static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs) 55static u32 ath9k_hw_mac_clks(struct ath_hw *ah, u32 usecs)
78{ 56{
79 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 57 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
@@ -413,8 +391,6 @@ static void ath9k_hw_init_defaults(struct ath_hw *ah)
413 ah->beacon_interval = 100; 391 ah->beacon_interval = 100;
414 ah->enable_32kHz_clock = DONT_USE_32KHZ; 392 ah->enable_32kHz_clock = DONT_USE_32KHZ;
415 ah->slottime = (u32) -1; 393 ah->slottime = (u32) -1;
416 ah->acktimeout = (u32) -1;
417 ah->ctstimeout = (u32) -1;
418 ah->globaltxtimeout = (u32) -1; 394 ah->globaltxtimeout = (u32) -1;
419 ah->power_mode = ATH9K_PM_UNDEFINED; 395 ah->power_mode = ATH9K_PM_UNDEFINED;
420} 396}
@@ -1180,34 +1156,25 @@ static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,
1180 } 1156 }
1181} 1157}
1182 1158
1183static bool ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) 1159static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
1184{ 1160{
1185 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { 1161 u32 val = ath9k_hw_mac_to_clks(ah, us);
1186 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, 1162 val = min(val, (u32) 0xFFFF);
1187 "bad ack timeout %u\n", us); 1163 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
1188 ah->acktimeout = (u32) -1;
1189 return false;
1190 } else {
1191 REG_RMW_FIELD(ah, AR_TIME_OUT,
1192 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
1193 ah->acktimeout = us;
1194 return true;
1195 }
1196} 1164}
1197 1165
1198static bool ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) 1166static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
1199{ 1167{
1200 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { 1168 u32 val = ath9k_hw_mac_to_clks(ah, us);
1201 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, 1169 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
1202 "bad cts timeout %u\n", us); 1170 REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
1203 ah->ctstimeout = (u32) -1; 1171}
1204 return false; 1172
1205 } else { 1173static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
1206 REG_RMW_FIELD(ah, AR_TIME_OUT, 1174{
1207 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us)); 1175 u32 val = ath9k_hw_mac_to_clks(ah, us);
1208 ah->ctstimeout = us; 1176 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
1209 return true; 1177 REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_CTS, val);
1210 }
1211} 1178}
1212 1179
1213static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu) 1180static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
@@ -1224,25 +1191,37 @@ static bool ath9k_hw_set_global_txtimeout(struct ath_hw *ah, u32 tu)
1224 } 1191 }
1225} 1192}
1226 1193
1227static void ath9k_hw_init_user_settings(struct ath_hw *ah) 1194void ath9k_hw_init_global_settings(struct ath_hw *ah)
1228{ 1195{
1196 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
1197 int acktimeout;
1198 int slottime;
1199 int sifstime;
1200
1229 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n", 1201 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET, "ah->misc_mode 0x%x\n",
1230 ah->misc_mode); 1202 ah->misc_mode);
1231 1203
1232 if (ah->misc_mode != 0) 1204 if (ah->misc_mode != 0)
1233 REG_WRITE(ah, AR_PCU_MISC, 1205 REG_WRITE(ah, AR_PCU_MISC,
1234 REG_READ(ah, AR_PCU_MISC) | ah->misc_mode); 1206 REG_READ(ah, AR_PCU_MISC) | ah->misc_mode);
1235 if (ah->slottime != (u32) -1) 1207
1236 ath9k_hw_setslottime(ah, ah->slottime); 1208 if (conf->channel && conf->channel->band == IEEE80211_BAND_5GHZ)
1237 if (ah->acktimeout != (u32) -1) 1209 sifstime = 16;
1238 ath9k_hw_set_ack_timeout(ah, ah->acktimeout); 1210 else
1239 if (ah->ctstimeout != (u32) -1) 1211 sifstime = 10;
1240 ath9k_hw_set_cts_timeout(ah, ah->ctstimeout); 1212
1213 /* As defined by IEEE 802.11-2007 17.3.8.6 */
1214 slottime = ah->slottime + 3 * ah->coverage_class;
1215 acktimeout = slottime + sifstime;
1216 ath9k_hw_setslottime(ah, slottime);
1217 ath9k_hw_set_ack_timeout(ah, acktimeout);
1218 ath9k_hw_set_cts_timeout(ah, acktimeout);
1241 if (ah->globaltxtimeout != (u32) -1) 1219 if (ah->globaltxtimeout != (u32) -1)
1242 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout); 1220 ath9k_hw_set_global_txtimeout(ah, ah->globaltxtimeout);
1243} 1221}
1222EXPORT_SYMBOL(ath9k_hw_init_global_settings);
1244 1223
1245void ath9k_hw_detach(struct ath_hw *ah) 1224void ath9k_hw_deinit(struct ath_hw *ah)
1246{ 1225{
1247 struct ath_common *common = ath9k_hw_common(ah); 1226 struct ath_common *common = ath9k_hw_common(ah);
1248 1227
@@ -1260,7 +1239,7 @@ free_hw:
1260 kfree(ah); 1239 kfree(ah);
1261 ah = NULL; 1240 ah = NULL;
1262} 1241}
1263EXPORT_SYMBOL(ath9k_hw_detach); 1242EXPORT_SYMBOL(ath9k_hw_deinit);
1264 1243
1265/*******/ 1244/*******/
1266/* INI */ 1245/* INI */
@@ -2061,7 +2040,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
2061 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT) 2040 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
2062 ath9k_enable_rfkill(ah); 2041 ath9k_enable_rfkill(ah);
2063 2042
2064 ath9k_hw_init_user_settings(ah); 2043 ath9k_hw_init_global_settings(ah);
2065 2044
2066 if (AR_SREV_9287_12_OR_LATER(ah)) { 2045 if (AR_SREV_9287_12_OR_LATER(ah)) {
2067 REG_WRITE(ah, AR_D_GBL_IFS_SIFS, 2046 REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
@@ -3658,21 +3637,6 @@ u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp)
3658} 3637}
3659EXPORT_SYMBOL(ath9k_hw_extend_tsf); 3638EXPORT_SYMBOL(ath9k_hw_extend_tsf);
3660 3639
3661bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
3662{
3663 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
3664 ath_print(ath9k_hw_common(ah), ATH_DBG_RESET,
3665 "bad slot time %u\n", us);
3666 ah->slottime = (u32) -1;
3667 return false;
3668 } else {
3669 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
3670 ah->slottime = us;
3671 return true;
3672 }
3673}
3674EXPORT_SYMBOL(ath9k_hw_setslottime);
3675
3676void ath9k_hw_set11nmac2040(struct ath_hw *ah) 3640void ath9k_hw_set11nmac2040(struct ath_hw *ah)
3677{ 3641{
3678 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf; 3642 struct ieee80211_conf *conf = &ath9k_hw_common(ah)->hw->conf;
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 8849450dc591..ab1f1981d857 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -551,10 +551,9 @@ struct ath_hw {
551 u32 *bank6Temp; 551 u32 *bank6Temp;
552 552
553 int16_t txpower_indexoffset; 553 int16_t txpower_indexoffset;
554 int coverage_class;
554 u32 beacon_interval; 555 u32 beacon_interval;
555 u32 slottime; 556 u32 slottime;
556 u32 acktimeout;
557 u32 ctstimeout;
558 u32 globaltxtimeout; 557 u32 globaltxtimeout;
559 558
560 /* ANI */ 559 /* ANI */
@@ -616,7 +615,7 @@ static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
616 615
617/* Initialization, Detach, Reset */ 616/* Initialization, Detach, Reset */
618const char *ath9k_hw_probe(u16 vendorid, u16 devid); 617const char *ath9k_hw_probe(u16 vendorid, u16 devid);
619void ath9k_hw_detach(struct ath_hw *ah); 618void ath9k_hw_deinit(struct ath_hw *ah);
620int ath9k_hw_init(struct ath_hw *ah); 619int ath9k_hw_init(struct ath_hw *ah);
621int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, 620int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
622 bool bChannelChange); 621 bool bChannelChange);
@@ -668,7 +667,7 @@ void ath9k_hw_settsf64(struct ath_hw *ah, u64 tsf64);
668void ath9k_hw_reset_tsf(struct ath_hw *ah); 667void ath9k_hw_reset_tsf(struct ath_hw *ah);
669void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting); 668void ath9k_hw_set_tsfadjust(struct ath_hw *ah, u32 setting);
670u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp); 669u64 ath9k_hw_extend_tsf(struct ath_hw *ah, u32 rstamp);
671bool ath9k_hw_setslottime(struct ath_hw *ah, u32 us); 670void ath9k_hw_init_global_settings(struct ath_hw *ah);
672void ath9k_hw_set11nmac2040(struct ath_hw *ah); 671void ath9k_hw_set11nmac2040(struct ath_hw *ah);
673void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period); 672void ath9k_hw_beaconinit(struct ath_hw *ah, u32 next_beacon, u32 beacon_period);
674void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah, 673void ath9k_hw_set_sta_beacon_timers(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
new file mode 100644
index 000000000000..5f78d7a5ff22
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -0,0 +1,861 @@
1/*
2 * Copyright (c) 2008-2009 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "ath9k.h"
18
19static char *dev_info = "ath9k";
20
21MODULE_AUTHOR("Atheros Communications");
22MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
23MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
24MODULE_LICENSE("Dual BSD/GPL");
25
26static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
27module_param_named(debug, ath9k_debug, uint, 0);
28MODULE_PARM_DESC(debug, "Debugging mask");
29
30int modparam_nohwcrypt;
31module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
32MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
33
34/* We use the hw_value as an index into our private channel structure */
35
36#define CHAN2G(_freq, _idx) { \
37 .center_freq = (_freq), \
38 .hw_value = (_idx), \
39 .max_power = 20, \
40}
41
42#define CHAN5G(_freq, _idx) { \
43 .band = IEEE80211_BAND_5GHZ, \
44 .center_freq = (_freq), \
45 .hw_value = (_idx), \
46 .max_power = 20, \
47}
48
49/* Some 2 GHz radios are actually tunable on 2312-2732
50 * on 5 MHz steps, we support the channels which we know
51 * we have calibration data for all cards though to make
52 * this static */
53static struct ieee80211_channel ath9k_2ghz_chantable[] = {
54 CHAN2G(2412, 0), /* Channel 1 */
55 CHAN2G(2417, 1), /* Channel 2 */
56 CHAN2G(2422, 2), /* Channel 3 */
57 CHAN2G(2427, 3), /* Channel 4 */
58 CHAN2G(2432, 4), /* Channel 5 */
59 CHAN2G(2437, 5), /* Channel 6 */
60 CHAN2G(2442, 6), /* Channel 7 */
61 CHAN2G(2447, 7), /* Channel 8 */
62 CHAN2G(2452, 8), /* Channel 9 */
63 CHAN2G(2457, 9), /* Channel 10 */
64 CHAN2G(2462, 10), /* Channel 11 */
65 CHAN2G(2467, 11), /* Channel 12 */
66 CHAN2G(2472, 12), /* Channel 13 */
67 CHAN2G(2484, 13), /* Channel 14 */
68};
69
70/* Some 5 GHz radios are actually tunable on XXXX-YYYY
71 * on 5 MHz steps, we support the channels which we know
72 * we have calibration data for all cards though to make
73 * this static */
74static struct ieee80211_channel ath9k_5ghz_chantable[] = {
75 /* _We_ call this UNII 1 */
76 CHAN5G(5180, 14), /* Channel 36 */
77 CHAN5G(5200, 15), /* Channel 40 */
78 CHAN5G(5220, 16), /* Channel 44 */
79 CHAN5G(5240, 17), /* Channel 48 */
80 /* _We_ call this UNII 2 */
81 CHAN5G(5260, 18), /* Channel 52 */
82 CHAN5G(5280, 19), /* Channel 56 */
83 CHAN5G(5300, 20), /* Channel 60 */
84 CHAN5G(5320, 21), /* Channel 64 */
85 /* _We_ call this "Middle band" */
86 CHAN5G(5500, 22), /* Channel 100 */
87 CHAN5G(5520, 23), /* Channel 104 */
88 CHAN5G(5540, 24), /* Channel 108 */
89 CHAN5G(5560, 25), /* Channel 112 */
90 CHAN5G(5580, 26), /* Channel 116 */
91 CHAN5G(5600, 27), /* Channel 120 */
92 CHAN5G(5620, 28), /* Channel 124 */
93 CHAN5G(5640, 29), /* Channel 128 */
94 CHAN5G(5660, 30), /* Channel 132 */
95 CHAN5G(5680, 31), /* Channel 136 */
96 CHAN5G(5700, 32), /* Channel 140 */
97 /* _We_ call this UNII 3 */
98 CHAN5G(5745, 33), /* Channel 149 */
99 CHAN5G(5765, 34), /* Channel 153 */
100 CHAN5G(5785, 35), /* Channel 157 */
101 CHAN5G(5805, 36), /* Channel 161 */
102 CHAN5G(5825, 37), /* Channel 165 */
103};
104
105/* Atheros hardware rate code addition for short premble */
106#define SHPCHECK(__hw_rate, __flags) \
107 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
108
109#define RATE(_bitrate, _hw_rate, _flags) { \
110 .bitrate = (_bitrate), \
111 .flags = (_flags), \
112 .hw_value = (_hw_rate), \
113 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
114}
115
116static struct ieee80211_rate ath9k_legacy_rates[] = {
117 RATE(10, 0x1b, 0),
118 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
119 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
120 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
121 RATE(60, 0x0b, 0),
122 RATE(90, 0x0f, 0),
123 RATE(120, 0x0a, 0),
124 RATE(180, 0x0e, 0),
125 RATE(240, 0x09, 0),
126 RATE(360, 0x0d, 0),
127 RATE(480, 0x08, 0),
128 RATE(540, 0x0c, 0),
129};
130
131static void ath9k_deinit_softc(struct ath_softc *sc);
132
133/*
134 * Read and write, they both share the same lock. We do this to serialize
135 * reads and writes on Atheros 802.11n PCI devices only. This is required
136 * as the FIFO on these devices can only accept sanely 2 requests.
137 */
138
139static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
140{
141 struct ath_hw *ah = (struct ath_hw *) hw_priv;
142 struct ath_common *common = ath9k_hw_common(ah);
143 struct ath_softc *sc = (struct ath_softc *) common->priv;
144
145 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
146 unsigned long flags;
147 spin_lock_irqsave(&sc->sc_serial_rw, flags);
148 iowrite32(val, sc->mem + reg_offset);
149 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
150 } else
151 iowrite32(val, sc->mem + reg_offset);
152}
153
154static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
155{
156 struct ath_hw *ah = (struct ath_hw *) hw_priv;
157 struct ath_common *common = ath9k_hw_common(ah);
158 struct ath_softc *sc = (struct ath_softc *) common->priv;
159 u32 val;
160
161 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
162 unsigned long flags;
163 spin_lock_irqsave(&sc->sc_serial_rw, flags);
164 val = ioread32(sc->mem + reg_offset);
165 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
166 } else
167 val = ioread32(sc->mem + reg_offset);
168 return val;
169}
170
171static const struct ath_ops ath9k_common_ops = {
172 .read = ath9k_ioread32,
173 .write = ath9k_iowrite32,
174};
175
176/**************************/
177/* Initialization */
178/**************************/
179
180static void setup_ht_cap(struct ath_softc *sc,
181 struct ieee80211_sta_ht_cap *ht_info)
182{
183 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
184 u8 tx_streams, rx_streams;
185
186 ht_info->ht_supported = true;
187 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
188 IEEE80211_HT_CAP_SM_PS |
189 IEEE80211_HT_CAP_SGI_40 |
190 IEEE80211_HT_CAP_DSSSCCK40;
191
192 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
193 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
194
195 /* set up supported mcs set */
196 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
197 tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ?
198 1 : 2;
199 rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ?
200 1 : 2;
201
202 if (tx_streams != rx_streams) {
203 ath_print(common, ATH_DBG_CONFIG,
204 "TX streams %d, RX streams: %d\n",
205 tx_streams, rx_streams);
206 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
207 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
208 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
209 }
210
211 ht_info->mcs.rx_mask[0] = 0xff;
212 if (rx_streams >= 2)
213 ht_info->mcs.rx_mask[1] = 0xff;
214
215 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
216}
217
218static int ath9k_reg_notifier(struct wiphy *wiphy,
219 struct regulatory_request *request)
220{
221 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
222 struct ath_wiphy *aphy = hw->priv;
223 struct ath_softc *sc = aphy->sc;
224 struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
225
226 return ath_reg_notifier_apply(wiphy, request, reg);
227}
228
229/*
230 * This function will allocate both the DMA descriptor structure, and the
231 * buffers it contains. These are used to contain the descriptors used
232 * by the system.
233*/
234int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
235 struct list_head *head, const char *name,
236 int nbuf, int ndesc)
237{
238#define DS2PHYS(_dd, _ds) \
239 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
240#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
241#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
242 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
243 struct ath_desc *ds;
244 struct ath_buf *bf;
245 int i, bsize, error;
246
247 ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
248 name, nbuf, ndesc);
249
250 INIT_LIST_HEAD(head);
251 /* ath_desc must be a multiple of DWORDs */
252 if ((sizeof(struct ath_desc) % 4) != 0) {
253 ath_print(common, ATH_DBG_FATAL,
254 "ath_desc not DWORD aligned\n");
255 BUG_ON((sizeof(struct ath_desc) % 4) != 0);
256 error = -ENOMEM;
257 goto fail;
258 }
259
260 dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
261
262 /*
263 * Need additional DMA memory because we can't use
264 * descriptors that cross the 4K page boundary. Assume
265 * one skipped descriptor per 4K page.
266 */
267 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
268 u32 ndesc_skipped =
269 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
270 u32 dma_len;
271
272 while (ndesc_skipped) {
273 dma_len = ndesc_skipped * sizeof(struct ath_desc);
274 dd->dd_desc_len += dma_len;
275
276 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
277 };
278 }
279
280 /* allocate descriptors */
281 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
282 &dd->dd_desc_paddr, GFP_KERNEL);
283 if (dd->dd_desc == NULL) {
284 error = -ENOMEM;
285 goto fail;
286 }
287 ds = dd->dd_desc;
288 ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
289 name, ds, (u32) dd->dd_desc_len,
290 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
291
292 /* allocate buffers */
293 bsize = sizeof(struct ath_buf) * nbuf;
294 bf = kzalloc(bsize, GFP_KERNEL);
295 if (bf == NULL) {
296 error = -ENOMEM;
297 goto fail2;
298 }
299 dd->dd_bufptr = bf;
300
301 for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
302 bf->bf_desc = ds;
303 bf->bf_daddr = DS2PHYS(dd, ds);
304
305 if (!(sc->sc_ah->caps.hw_caps &
306 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
307 /*
308 * Skip descriptor addresses which can cause 4KB
309 * boundary crossing (addr + length) with a 32 dword
310 * descriptor fetch.
311 */
312 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
313 BUG_ON((caddr_t) bf->bf_desc >=
314 ((caddr_t) dd->dd_desc +
315 dd->dd_desc_len));
316
317 ds += ndesc;
318 bf->bf_desc = ds;
319 bf->bf_daddr = DS2PHYS(dd, ds);
320 }
321 }
322 list_add_tail(&bf->list, head);
323 }
324 return 0;
325fail2:
326 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
327 dd->dd_desc_paddr);
328fail:
329 memset(dd, 0, sizeof(*dd));
330 return error;
331#undef ATH_DESC_4KB_BOUND_CHECK
332#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
333#undef DS2PHYS
334}
335
336static void ath9k_init_crypto(struct ath_softc *sc)
337{
338 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
339 int i = 0;
340
341 /* Get the hardware key cache size. */
342 common->keymax = sc->sc_ah->caps.keycache_size;
343 if (common->keymax > ATH_KEYMAX) {
344 ath_print(common, ATH_DBG_ANY,
345 "Warning, using only %u entries in %u key cache\n",
346 ATH_KEYMAX, common->keymax);
347 common->keymax = ATH_KEYMAX;
348 }
349
350 /*
351 * Reset the key cache since some parts do not
352 * reset the contents on initial power up.
353 */
354 for (i = 0; i < common->keymax; i++)
355 ath9k_hw_keyreset(sc->sc_ah, (u16) i);
356
357 if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
358 ATH9K_CIPHER_TKIP, NULL)) {
359 /*
360 * Whether we should enable h/w TKIP MIC.
361 * XXX: if we don't support WME TKIP MIC, then we wouldn't
362 * report WMM capable, so it's always safe to turn on
363 * TKIP MIC in this case.
364 */
365 ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC, 0, 1, NULL);
366 }
367
368 /*
369 * Check whether the separate key cache entries
370 * are required to handle both tx+rx MIC keys.
371 * With split mic keys the number of stations is limited
372 * to 27 otherwise 59.
373 */
374 if (ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
375 ATH9K_CIPHER_TKIP, NULL)
376 && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_CIPHER,
377 ATH9K_CIPHER_MIC, NULL)
378 && ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_TKIP_SPLIT,
379 0, NULL))
380 common->splitmic = 1;
381
382 /* turn on mcast key search if possible */
383 if (!ath9k_hw_getcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
384 (void)ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_MCAST_KEYSRCH,
385 1, 1, NULL);
386
387}
388
389static int ath9k_init_btcoex(struct ath_softc *sc)
390{
391 int r, qnum;
392
393 switch (sc->sc_ah->btcoex_hw.scheme) {
394 case ATH_BTCOEX_CFG_NONE:
395 break;
396 case ATH_BTCOEX_CFG_2WIRE:
397 ath9k_hw_btcoex_init_2wire(sc->sc_ah);
398 break;
399 case ATH_BTCOEX_CFG_3WIRE:
400 ath9k_hw_btcoex_init_3wire(sc->sc_ah);
401 r = ath_init_btcoex_timer(sc);
402 if (r)
403 return -1;
404 qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
405 ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
406 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
407 break;
408 default:
409 WARN_ON(1);
410 break;
411 }
412
413 return 0;
414}
415
416static int ath9k_init_queues(struct ath_softc *sc)
417{
418 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
419 int i = 0;
420
421 for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
422 sc->tx.hwq_map[i] = -1;
423
424 sc->beacon.beaconq = ath9k_hw_beaconq_setup(sc->sc_ah);
425 if (sc->beacon.beaconq == -1) {
426 ath_print(common, ATH_DBG_FATAL,
427 "Unable to setup a beacon xmit queue\n");
428 goto err;
429 }
430
431 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
432 if (sc->beacon.cabq == NULL) {
433 ath_print(common, ATH_DBG_FATAL,
434 "Unable to setup CAB xmit queue\n");
435 goto err;
436 }
437
438 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
439 ath_cabq_update(sc);
440
441 if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
442 ath_print(common, ATH_DBG_FATAL,
443 "Unable to setup xmit queue for BK traffic\n");
444 goto err;
445 }
446
447 if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
448 ath_print(common, ATH_DBG_FATAL,
449 "Unable to setup xmit queue for BE traffic\n");
450 goto err;
451 }
452 if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
453 ath_print(common, ATH_DBG_FATAL,
454 "Unable to setup xmit queue for VI traffic\n");
455 goto err;
456 }
457 if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
458 ath_print(common, ATH_DBG_FATAL,
459 "Unable to setup xmit queue for VO traffic\n");
460 goto err;
461 }
462
463 return 0;
464
465err:
466 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
467 if (ATH_TXQ_SETUP(sc, i))
468 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
469
470 return -EIO;
471}
472
473static void ath9k_init_channels_rates(struct ath_softc *sc)
474{
475 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
476 sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
477 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
478 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
479 ARRAY_SIZE(ath9k_2ghz_chantable);
480 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
481 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
482 ARRAY_SIZE(ath9k_legacy_rates);
483 }
484
485 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
486 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
487 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
488 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
489 ARRAY_SIZE(ath9k_5ghz_chantable);
490 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
491 ath9k_legacy_rates + 4;
492 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
493 ARRAY_SIZE(ath9k_legacy_rates) - 4;
494 }
495}
496
497static void ath9k_init_misc(struct ath_softc *sc)
498{
499 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
500 int i = 0;
501
502 common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
503 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
504
505 sc->config.txpowlimit = ATH_TXPOWER_MAX;
506
507 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
508 sc->sc_flags |= SC_OP_TXAGGR;
509 sc->sc_flags |= SC_OP_RXAGGR;
510 }
511
512 common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
513 common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
514
515 ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
516 sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
517
518 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
519 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
520
521 sc->beacon.slottime = ATH9K_SLOT_TIME_9;
522
523 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
524 sc->beacon.bslot[i] = NULL;
525 sc->beacon.bslot_aphy[i] = NULL;
526 }
527}
528
529static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
530 const struct ath_bus_ops *bus_ops)
531{
532 struct ath_hw *ah = NULL;
533 struct ath_common *common;
534 int ret = 0, i;
535 int csz = 0;
536
537 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
538 if (!ah)
539 return -ENOMEM;
540
541 ah->hw_version.devid = devid;
542 ah->hw_version.subsysid = subsysid;
543 sc->sc_ah = ah;
544
545 common = ath9k_hw_common(ah);
546 common->ops = &ath9k_common_ops;
547 common->bus_ops = bus_ops;
548 common->ah = ah;
549 common->hw = sc->hw;
550 common->priv = sc;
551 common->debug_mask = ath9k_debug;
552
553 spin_lock_init(&sc->wiphy_lock);
554 spin_lock_init(&sc->sc_resetlock);
555 spin_lock_init(&sc->sc_serial_rw);
556 spin_lock_init(&sc->sc_pm_lock);
557 mutex_init(&sc->mutex);
558 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
559 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
560 (unsigned long)sc);
561
562 /*
563 * Cache line size is used to size and align various
564 * structures used to communicate with the hardware.
565 */
566 ath_read_cachesize(common, &csz);
567 common->cachelsz = csz << 2; /* convert to bytes */
568
569 ret = ath9k_hw_init(ah);
570 if (ret) {
571 ath_print(common, ATH_DBG_FATAL,
572 "Unable to initialize hardware; "
573 "initialization status: %d\n", ret);
574 goto err_hw;
575 }
576
577 ret = ath9k_init_debug(ah);
578 if (ret) {
579 ath_print(common, ATH_DBG_FATAL,
580 "Unable to create debugfs files\n");
581 goto err_debug;
582 }
583
584 ret = ath9k_init_queues(sc);
585 if (ret)
586 goto err_queues;
587
588 ret = ath9k_init_btcoex(sc);
589 if (ret)
590 goto err_btcoex;
591
592 ath9k_init_crypto(sc);
593 ath9k_init_channels_rates(sc);
594 ath9k_init_misc(sc);
595
596 return 0;
597
598err_btcoex:
599 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
600 if (ATH_TXQ_SETUP(sc, i))
601 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
602err_queues:
603 ath9k_exit_debug(ah);
604err_debug:
605 ath9k_hw_deinit(ah);
606err_hw:
607 tasklet_kill(&sc->intr_tq);
608 tasklet_kill(&sc->bcon_tasklet);
609
610 kfree(ah);
611 sc->sc_ah = NULL;
612
613 return ret;
614}
615
616void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
617{
618 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
619
620 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
621 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
622 IEEE80211_HW_SIGNAL_DBM |
623 IEEE80211_HW_AMPDU_AGGREGATION |
624 IEEE80211_HW_SUPPORTS_PS |
625 IEEE80211_HW_PS_NULLFUNC_STACK |
626 IEEE80211_HW_SPECTRUM_MGMT;
627
628 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
629 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
630
631 hw->wiphy->interface_modes =
632 BIT(NL80211_IFTYPE_AP) |
633 BIT(NL80211_IFTYPE_STATION) |
634 BIT(NL80211_IFTYPE_ADHOC) |
635 BIT(NL80211_IFTYPE_MESH_POINT);
636
637 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
638
639 hw->queues = 4;
640 hw->max_rates = 4;
641 hw->channel_change_time = 5000;
642 hw->max_listen_interval = 10;
643 /* Hardware supports 10 but we use 4 */
644 hw->max_rate_tries = 4;
645 hw->sta_data_size = sizeof(struct ath_node);
646 hw->vif_data_size = sizeof(struct ath_vif);
647
648 hw->rate_control_algorithm = "ath9k_rate_control";
649
650 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
651 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
652 &sc->sbands[IEEE80211_BAND_2GHZ];
653 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
654 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
655 &sc->sbands[IEEE80211_BAND_5GHZ];
656
657 if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
658 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
659 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
660 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
661 setup_ht_cap(sc, &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
662 }
663
664 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
665}
666
667int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
668 const struct ath_bus_ops *bus_ops)
669{
670 struct ieee80211_hw *hw = sc->hw;
671 struct ath_common *common;
672 struct ath_hw *ah;
673 int error = 0;
674 struct ath_regulatory *reg;
675
676 /* Bring up device */
677 error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
678 if (error != 0)
679 goto error_init;
680
681 ah = sc->sc_ah;
682 common = ath9k_hw_common(ah);
683 ath9k_set_hw_capab(sc, hw);
684
685 /* Initialize regulatory */
686 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
687 ath9k_reg_notifier);
688 if (error)
689 goto error_regd;
690
691 reg = &common->regulatory;
692
693 /* Setup TX DMA */
694 error = ath_tx_init(sc, ATH_TXBUF);
695 if (error != 0)
696 goto error_tx;
697
698 /* Setup RX DMA */
699 error = ath_rx_init(sc, ATH_RXBUF);
700 if (error != 0)
701 goto error_rx;
702
703 /* Register with mac80211 */
704 error = ieee80211_register_hw(hw);
705 if (error)
706 goto error_register;
707
708 /* Handle world regulatory */
709 if (!ath_is_world_regd(reg)) {
710 error = regulatory_hint(hw->wiphy, reg->alpha2);
711 if (error)
712 goto error_world;
713 }
714
715 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
716 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
717 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
718
719 ath_init_leds(sc);
720 ath_start_rfkill_poll(sc);
721
722 return 0;
723
724error_world:
725 ieee80211_unregister_hw(hw);
726error_register:
727 ath_rx_cleanup(sc);
728error_rx:
729 ath_tx_cleanup(sc);
730error_tx:
731 /* Nothing */
732error_regd:
733 ath9k_deinit_softc(sc);
734error_init:
735 return error;
736}
737
738/*****************************/
739/* De-Initialization */
740/*****************************/
741
742static void ath9k_deinit_softc(struct ath_softc *sc)
743{
744 int i = 0;
745
746 if ((sc->btcoex.no_stomp_timer) &&
747 sc->sc_ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
748 ath_gen_timer_free(sc->sc_ah, sc->btcoex.no_stomp_timer);
749
750 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
751 if (ATH_TXQ_SETUP(sc, i))
752 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
753
754 ath9k_exit_debug(sc->sc_ah);
755 ath9k_hw_deinit(sc->sc_ah);
756
757 tasklet_kill(&sc->intr_tq);
758 tasklet_kill(&sc->bcon_tasklet);
759}
760
761void ath9k_deinit_device(struct ath_softc *sc)
762{
763 struct ieee80211_hw *hw = sc->hw;
764 int i = 0;
765
766 ath9k_ps_wakeup(sc);
767
768 wiphy_rfkill_stop_polling(sc->hw->wiphy);
769 ath_deinit_leds(sc);
770
771 for (i = 0; i < sc->num_sec_wiphy; i++) {
772 struct ath_wiphy *aphy = sc->sec_wiphy[i];
773 if (aphy == NULL)
774 continue;
775 sc->sec_wiphy[i] = NULL;
776 ieee80211_unregister_hw(aphy->hw);
777 ieee80211_free_hw(aphy->hw);
778 }
779 kfree(sc->sec_wiphy);
780
781 ieee80211_unregister_hw(hw);
782 ath_rx_cleanup(sc);
783 ath_tx_cleanup(sc);
784 ath9k_deinit_softc(sc);
785}
786
787void ath_descdma_cleanup(struct ath_softc *sc,
788 struct ath_descdma *dd,
789 struct list_head *head)
790{
791 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
792 dd->dd_desc_paddr);
793
794 INIT_LIST_HEAD(head);
795 kfree(dd->dd_bufptr);
796 memset(dd, 0, sizeof(*dd));
797}
798
799/************************/
800/* Module Hooks */
801/************************/
802
803static int __init ath9k_init(void)
804{
805 int error;
806
807 /* Register rate control algorithm */
808 error = ath_rate_control_register();
809 if (error != 0) {
810 printk(KERN_ERR
811 "ath9k: Unable to register rate control "
812 "algorithm: %d\n",
813 error);
814 goto err_out;
815 }
816
817 error = ath9k_debug_create_root();
818 if (error) {
819 printk(KERN_ERR
820 "ath9k: Unable to create debugfs root: %d\n",
821 error);
822 goto err_rate_unregister;
823 }
824
825 error = ath_pci_init();
826 if (error < 0) {
827 printk(KERN_ERR
828 "ath9k: No PCI devices found, driver not installed.\n");
829 error = -ENODEV;
830 goto err_remove_root;
831 }
832
833 error = ath_ahb_init();
834 if (error < 0) {
835 error = -ENODEV;
836 goto err_pci_exit;
837 }
838
839 return 0;
840
841 err_pci_exit:
842 ath_pci_exit();
843
844 err_remove_root:
845 ath9k_debug_remove_root();
846 err_rate_unregister:
847 ath_rate_control_unregister();
848 err_out:
849 return error;
850}
851module_init(ath9k_init);
852
853static void __exit ath9k_exit(void)
854{
855 ath_ahb_exit();
856 ath_pci_exit();
857 ath9k_debug_remove_root();
858 ath_rate_control_unregister();
859 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
860}
861module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index e185479e295e..29851e6376a9 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -167,6 +167,40 @@ struct ath_rx_status {
167#define ATH9K_RXKEYIX_INVALID ((u8)-1) 167#define ATH9K_RXKEYIX_INVALID ((u8)-1)
168#define ATH9K_TXKEYIX_INVALID ((u32)-1) 168#define ATH9K_TXKEYIX_INVALID ((u32)-1)
169 169
170enum ath9k_phyerr {
171 ATH9K_PHYERR_UNDERRUN = 0, /* Transmit underrun */
172 ATH9K_PHYERR_TIMING = 1, /* Timing error */
173 ATH9K_PHYERR_PARITY = 2, /* Illegal parity */
174 ATH9K_PHYERR_RATE = 3, /* Illegal rate */
175 ATH9K_PHYERR_LENGTH = 4, /* Illegal length */
176 ATH9K_PHYERR_RADAR = 5, /* Radar detect */
177 ATH9K_PHYERR_SERVICE = 6, /* Illegal service */
178 ATH9K_PHYERR_TOR = 7, /* Transmit override receive */
179
180 ATH9K_PHYERR_OFDM_TIMING = 17,
181 ATH9K_PHYERR_OFDM_SIGNAL_PARITY = 18,
182 ATH9K_PHYERR_OFDM_RATE_ILLEGAL = 19,
183 ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL = 20,
184 ATH9K_PHYERR_OFDM_POWER_DROP = 21,
185 ATH9K_PHYERR_OFDM_SERVICE = 22,
186 ATH9K_PHYERR_OFDM_RESTART = 23,
187 ATH9K_PHYERR_FALSE_RADAR_EXT = 24,
188
189 ATH9K_PHYERR_CCK_TIMING = 25,
190 ATH9K_PHYERR_CCK_HEADER_CRC = 26,
191 ATH9K_PHYERR_CCK_RATE_ILLEGAL = 27,
192 ATH9K_PHYERR_CCK_SERVICE = 30,
193 ATH9K_PHYERR_CCK_RESTART = 31,
194 ATH9K_PHYERR_CCK_LENGTH_ILLEGAL = 32,
195 ATH9K_PHYERR_CCK_POWER_DROP = 33,
196
197 ATH9K_PHYERR_HT_CRC_ERROR = 34,
198 ATH9K_PHYERR_HT_LENGTH_ILLEGAL = 35,
199 ATH9K_PHYERR_HT_RATE_ILLEGAL = 36,
200
201 ATH9K_PHYERR_MAX = 37,
202};
203
170struct ath_desc { 204struct ath_desc {
171 u32 ds_link; 205 u32 ds_link;
172 u32 ds_data; 206 u32 ds_data;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 79fbbda15493..c0c571c2e8c4 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -18,118 +18,6 @@
18#include "ath9k.h" 18#include "ath9k.h"
19#include "btcoex.h" 19#include "btcoex.h"
20 20
21static char *dev_info = "ath9k";
22
23MODULE_AUTHOR("Atheros Communications");
24MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
25MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
26MODULE_LICENSE("Dual BSD/GPL");
27
28static int modparam_nohwcrypt;
29module_param_named(nohwcrypt, modparam_nohwcrypt, int, 0444);
30MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
31
32static unsigned int ath9k_debug = ATH_DBG_DEFAULT;
33module_param_named(debug, ath9k_debug, uint, 0);
34MODULE_PARM_DESC(debug, "Debugging mask");
35
36/* We use the hw_value as an index into our private channel structure */
37
38#define CHAN2G(_freq, _idx) { \
39 .center_freq = (_freq), \
40 .hw_value = (_idx), \
41 .max_power = 20, \
42}
43
44#define CHAN5G(_freq, _idx) { \
45 .band = IEEE80211_BAND_5GHZ, \
46 .center_freq = (_freq), \
47 .hw_value = (_idx), \
48 .max_power = 20, \
49}
50
51/* Some 2 GHz radios are actually tunable on 2312-2732
52 * on 5 MHz steps, we support the channels which we know
53 * we have calibration data for all cards though to make
54 * this static */
55static struct ieee80211_channel ath9k_2ghz_chantable[] = {
56 CHAN2G(2412, 0), /* Channel 1 */
57 CHAN2G(2417, 1), /* Channel 2 */
58 CHAN2G(2422, 2), /* Channel 3 */
59 CHAN2G(2427, 3), /* Channel 4 */
60 CHAN2G(2432, 4), /* Channel 5 */
61 CHAN2G(2437, 5), /* Channel 6 */
62 CHAN2G(2442, 6), /* Channel 7 */
63 CHAN2G(2447, 7), /* Channel 8 */
64 CHAN2G(2452, 8), /* Channel 9 */
65 CHAN2G(2457, 9), /* Channel 10 */
66 CHAN2G(2462, 10), /* Channel 11 */
67 CHAN2G(2467, 11), /* Channel 12 */
68 CHAN2G(2472, 12), /* Channel 13 */
69 CHAN2G(2484, 13), /* Channel 14 */
70};
71
72/* Some 5 GHz radios are actually tunable on XXXX-YYYY
73 * on 5 MHz steps, we support the channels which we know
74 * we have calibration data for all cards though to make
75 * this static */
76static struct ieee80211_channel ath9k_5ghz_chantable[] = {
77 /* _We_ call this UNII 1 */
78 CHAN5G(5180, 14), /* Channel 36 */
79 CHAN5G(5200, 15), /* Channel 40 */
80 CHAN5G(5220, 16), /* Channel 44 */
81 CHAN5G(5240, 17), /* Channel 48 */
82 /* _We_ call this UNII 2 */
83 CHAN5G(5260, 18), /* Channel 52 */
84 CHAN5G(5280, 19), /* Channel 56 */
85 CHAN5G(5300, 20), /* Channel 60 */
86 CHAN5G(5320, 21), /* Channel 64 */
87 /* _We_ call this "Middle band" */
88 CHAN5G(5500, 22), /* Channel 100 */
89 CHAN5G(5520, 23), /* Channel 104 */
90 CHAN5G(5540, 24), /* Channel 108 */
91 CHAN5G(5560, 25), /* Channel 112 */
92 CHAN5G(5580, 26), /* Channel 116 */
93 CHAN5G(5600, 27), /* Channel 120 */
94 CHAN5G(5620, 28), /* Channel 124 */
95 CHAN5G(5640, 29), /* Channel 128 */
96 CHAN5G(5660, 30), /* Channel 132 */
97 CHAN5G(5680, 31), /* Channel 136 */
98 CHAN5G(5700, 32), /* Channel 140 */
99 /* _We_ call this UNII 3 */
100 CHAN5G(5745, 33), /* Channel 149 */
101 CHAN5G(5765, 34), /* Channel 153 */
102 CHAN5G(5785, 35), /* Channel 157 */
103 CHAN5G(5805, 36), /* Channel 161 */
104 CHAN5G(5825, 37), /* Channel 165 */
105};
106
107/* Atheros hardware rate code addition for short premble */
108#define SHPCHECK(__hw_rate, __flags) \
109 ((__flags & IEEE80211_RATE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
110
111#define RATE(_bitrate, _hw_rate, _flags) { \
112 .bitrate = (_bitrate), \
113 .flags = (_flags), \
114 .hw_value = (_hw_rate), \
115 .hw_value_short = (SHPCHECK(_hw_rate, _flags)) \
116}
117
118static struct ieee80211_rate ath9k_legacy_rates[] = {
119 RATE(10, 0x1b, 0),
120 RATE(20, 0x1a, IEEE80211_RATE_SHORT_PREAMBLE),
121 RATE(55, 0x19, IEEE80211_RATE_SHORT_PREAMBLE),
122 RATE(110, 0x18, IEEE80211_RATE_SHORT_PREAMBLE),
123 RATE(60, 0x0b, 0),
124 RATE(90, 0x0f, 0),
125 RATE(120, 0x0a, 0),
126 RATE(180, 0x0e, 0),
127 RATE(240, 0x09, 0),
128 RATE(360, 0x0d, 0),
129 RATE(480, 0x08, 0),
130 RATE(540, 0x0c, 0),
131};
132
133static void ath_cache_conf_rate(struct ath_softc *sc, 21static void ath_cache_conf_rate(struct ath_softc *sc,
134 struct ieee80211_conf *conf) 22 struct ieee80211_conf *conf)
135{ 23{
@@ -221,7 +109,7 @@ static struct ath9k_channel *ath_get_curchannel(struct ath_softc *sc,
221 return channel; 109 return channel;
222} 110}
223 111
224static bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode) 112bool ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
225{ 113{
226 unsigned long flags; 114 unsigned long flags;
227 bool ret; 115 bool ret;
@@ -256,10 +144,10 @@ void ath9k_ps_restore(struct ath_softc *sc)
256 goto unlock; 144 goto unlock;
257 145
258 if (sc->ps_enabled && 146 if (sc->ps_enabled &&
259 !(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 147 !(sc->ps_flags & (PS_WAIT_FOR_BEACON |
260 SC_OP_WAIT_FOR_CAB | 148 PS_WAIT_FOR_CAB |
261 SC_OP_WAIT_FOR_PSPOLL_DATA | 149 PS_WAIT_FOR_PSPOLL_DATA |
262 SC_OP_WAIT_FOR_TX_ACK))) 150 PS_WAIT_FOR_TX_ACK)))
263 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP); 151 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_NETWORK_SLEEP);
264 152
265 unlock: 153 unlock:
@@ -349,7 +237,7 @@ int ath_set_channel(struct ath_softc *sc, struct ieee80211_hw *hw,
349 * When the task is complete, it reschedules itself depending on the 237 * When the task is complete, it reschedules itself depending on the
350 * appropriate interval that was calculated. 238 * appropriate interval that was calculated.
351 */ 239 */
352static void ath_ani_calibrate(unsigned long data) 240void ath_ani_calibrate(unsigned long data)
353{ 241{
354 struct ath_softc *sc = (struct ath_softc *)data; 242 struct ath_softc *sc = (struct ath_softc *)data;
355 struct ath_hw *ah = sc->sc_ah; 243 struct ath_hw *ah = sc->sc_ah;
@@ -504,7 +392,7 @@ static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
504 ath_tx_node_cleanup(sc, an); 392 ath_tx_node_cleanup(sc, an);
505} 393}
506 394
507static void ath9k_tasklet(unsigned long data) 395void ath9k_tasklet(unsigned long data)
508{ 396{
509 struct ath_softc *sc = (struct ath_softc *)data; 397 struct ath_softc *sc = (struct ath_softc *)data;
510 struct ath_hw *ah = sc->sc_ah; 398 struct ath_hw *ah = sc->sc_ah;
@@ -536,7 +424,7 @@ static void ath9k_tasklet(unsigned long data)
536 */ 424 */
537 ath_print(common, ATH_DBG_PS, 425 ath_print(common, ATH_DBG_PS,
538 "TSFOOR - Sync with next Beacon\n"); 426 "TSFOOR - Sync with next Beacon\n");
539 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON | SC_OP_BEACON_SYNC; 427 sc->ps_flags |= PS_WAIT_FOR_BEACON | PS_BEACON_SYNC;
540 } 428 }
541 429
542 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE) 430 if (ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
@@ -637,7 +525,7 @@ irqreturn_t ath_isr(int irq, void *dev)
637 * receive frames */ 525 * receive frames */
638 ath9k_setpower(sc, ATH9K_PM_AWAKE); 526 ath9k_setpower(sc, ATH9K_PM_AWAKE);
639 ath9k_hw_setrxabort(sc->sc_ah, 0); 527 ath9k_hw_setrxabort(sc->sc_ah, 0);
640 sc->sc_flags |= SC_OP_WAIT_FOR_BEACON; 528 sc->ps_flags |= PS_WAIT_FOR_BEACON;
641 } 529 }
642 530
643chip_reset: 531chip_reset:
@@ -924,44 +812,6 @@ static void ath_key_delete(struct ath_common *common, struct ieee80211_key_conf
924 } 812 }
925} 813}
926 814
927static void setup_ht_cap(struct ath_softc *sc,
928 struct ieee80211_sta_ht_cap *ht_info)
929{
930 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
931 u8 tx_streams, rx_streams;
932
933 ht_info->ht_supported = true;
934 ht_info->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
935 IEEE80211_HT_CAP_SM_PS |
936 IEEE80211_HT_CAP_SGI_40 |
937 IEEE80211_HT_CAP_DSSSCCK40;
938
939 ht_info->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
940 ht_info->ampdu_density = IEEE80211_HT_MPDU_DENSITY_8;
941
942 /* set up supported mcs set */
943 memset(&ht_info->mcs, 0, sizeof(ht_info->mcs));
944 tx_streams = !(common->tx_chainmask & (common->tx_chainmask - 1)) ?
945 1 : 2;
946 rx_streams = !(common->rx_chainmask & (common->rx_chainmask - 1)) ?
947 1 : 2;
948
949 if (tx_streams != rx_streams) {
950 ath_print(common, ATH_DBG_CONFIG,
951 "TX streams %d, RX streams: %d\n",
952 tx_streams, rx_streams);
953 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
954 ht_info->mcs.tx_params |= ((tx_streams - 1) <<
955 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT);
956 }
957
958 ht_info->mcs.rx_mask[0] = 0xff;
959 if (rx_streams >= 2)
960 ht_info->mcs.rx_mask[1] = 0xff;
961
962 ht_info->mcs.tx_params |= IEEE80211_HT_MCS_TX_DEFINED;
963}
964
965static void ath9k_bss_assoc_info(struct ath_softc *sc, 815static void ath9k_bss_assoc_info(struct ath_softc *sc,
966 struct ieee80211_vif *vif, 816 struct ieee80211_vif *vif,
967 struct ieee80211_bss_conf *bss_conf) 817 struct ieee80211_bss_conf *bss_conf)
@@ -983,7 +833,7 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
983 * on the receipt of the first Beacon frame (i.e., 833 * on the receipt of the first Beacon frame (i.e.,
984 * after time sync with the AP). 834 * after time sync with the AP).
985 */ 835 */
986 sc->sc_flags |= SC_OP_BEACON_SYNC; 836 sc->ps_flags |= PS_BEACON_SYNC;
987 837
988 /* Configure the beacon */ 838 /* Configure the beacon */
989 ath_beacon_config(sc, vif); 839 ath_beacon_config(sc, vif);
@@ -1000,174 +850,6 @@ static void ath9k_bss_assoc_info(struct ath_softc *sc,
1000 } 850 }
1001} 851}
1002 852
1003/********************************/
1004/* LED functions */
1005/********************************/
1006
1007static void ath_led_blink_work(struct work_struct *work)
1008{
1009 struct ath_softc *sc = container_of(work, struct ath_softc,
1010 ath_led_blink_work.work);
1011
1012 if (!(sc->sc_flags & SC_OP_LED_ASSOCIATED))
1013 return;
1014
1015 if ((sc->led_on_duration == ATH_LED_ON_DURATION_IDLE) ||
1016 (sc->led_off_duration == ATH_LED_OFF_DURATION_IDLE))
1017 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
1018 else
1019 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
1020 (sc->sc_flags & SC_OP_LED_ON) ? 1 : 0);
1021
1022 ieee80211_queue_delayed_work(sc->hw,
1023 &sc->ath_led_blink_work,
1024 (sc->sc_flags & SC_OP_LED_ON) ?
1025 msecs_to_jiffies(sc->led_off_duration) :
1026 msecs_to_jiffies(sc->led_on_duration));
1027
1028 sc->led_on_duration = sc->led_on_cnt ?
1029 max((ATH_LED_ON_DURATION_IDLE - sc->led_on_cnt), 25) :
1030 ATH_LED_ON_DURATION_IDLE;
1031 sc->led_off_duration = sc->led_off_cnt ?
1032 max((ATH_LED_OFF_DURATION_IDLE - sc->led_off_cnt), 10) :
1033 ATH_LED_OFF_DURATION_IDLE;
1034 sc->led_on_cnt = sc->led_off_cnt = 0;
1035 if (sc->sc_flags & SC_OP_LED_ON)
1036 sc->sc_flags &= ~SC_OP_LED_ON;
1037 else
1038 sc->sc_flags |= SC_OP_LED_ON;
1039}
1040
1041static void ath_led_brightness(struct led_classdev *led_cdev,
1042 enum led_brightness brightness)
1043{
1044 struct ath_led *led = container_of(led_cdev, struct ath_led, led_cdev);
1045 struct ath_softc *sc = led->sc;
1046
1047 switch (brightness) {
1048 case LED_OFF:
1049 if (led->led_type == ATH_LED_ASSOC ||
1050 led->led_type == ATH_LED_RADIO) {
1051 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin,
1052 (led->led_type == ATH_LED_RADIO));
1053 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1054 if (led->led_type == ATH_LED_RADIO)
1055 sc->sc_flags &= ~SC_OP_LED_ON;
1056 } else {
1057 sc->led_off_cnt++;
1058 }
1059 break;
1060 case LED_FULL:
1061 if (led->led_type == ATH_LED_ASSOC) {
1062 sc->sc_flags |= SC_OP_LED_ASSOCIATED;
1063 ieee80211_queue_delayed_work(sc->hw,
1064 &sc->ath_led_blink_work, 0);
1065 } else if (led->led_type == ATH_LED_RADIO) {
1066 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 0);
1067 sc->sc_flags |= SC_OP_LED_ON;
1068 } else {
1069 sc->led_on_cnt++;
1070 }
1071 break;
1072 default:
1073 break;
1074 }
1075}
1076
1077static int ath_register_led(struct ath_softc *sc, struct ath_led *led,
1078 char *trigger)
1079{
1080 int ret;
1081
1082 led->sc = sc;
1083 led->led_cdev.name = led->name;
1084 led->led_cdev.default_trigger = trigger;
1085 led->led_cdev.brightness_set = ath_led_brightness;
1086
1087 ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->led_cdev);
1088 if (ret)
1089 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
1090 "Failed to register led:%s", led->name);
1091 else
1092 led->registered = 1;
1093 return ret;
1094}
1095
1096static void ath_unregister_led(struct ath_led *led)
1097{
1098 if (led->registered) {
1099 led_classdev_unregister(&led->led_cdev);
1100 led->registered = 0;
1101 }
1102}
1103
1104static void ath_deinit_leds(struct ath_softc *sc)
1105{
1106 ath_unregister_led(&sc->assoc_led);
1107 sc->sc_flags &= ~SC_OP_LED_ASSOCIATED;
1108 ath_unregister_led(&sc->tx_led);
1109 ath_unregister_led(&sc->rx_led);
1110 ath_unregister_led(&sc->radio_led);
1111 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
1112}
1113
1114static void ath_init_leds(struct ath_softc *sc)
1115{
1116 char *trigger;
1117 int ret;
1118
1119 if (AR_SREV_9287(sc->sc_ah))
1120 sc->sc_ah->led_pin = ATH_LED_PIN_9287;
1121 else
1122 sc->sc_ah->led_pin = ATH_LED_PIN_DEF;
1123
1124 /* Configure gpio 1 for output */
1125 ath9k_hw_cfg_output(sc->sc_ah, sc->sc_ah->led_pin,
1126 AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
1127 /* LED off, active low */
1128 ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, 1);
1129
1130 INIT_DELAYED_WORK(&sc->ath_led_blink_work, ath_led_blink_work);
1131
1132 trigger = ieee80211_get_radio_led_name(sc->hw);
1133 snprintf(sc->radio_led.name, sizeof(sc->radio_led.name),
1134 "ath9k-%s::radio", wiphy_name(sc->hw->wiphy));
1135 ret = ath_register_led(sc, &sc->radio_led, trigger);
1136 sc->radio_led.led_type = ATH_LED_RADIO;
1137 if (ret)
1138 goto fail;
1139
1140 trigger = ieee80211_get_assoc_led_name(sc->hw);
1141 snprintf(sc->assoc_led.name, sizeof(sc->assoc_led.name),
1142 "ath9k-%s::assoc", wiphy_name(sc->hw->wiphy));
1143 ret = ath_register_led(sc, &sc->assoc_led, trigger);
1144 sc->assoc_led.led_type = ATH_LED_ASSOC;
1145 if (ret)
1146 goto fail;
1147
1148 trigger = ieee80211_get_tx_led_name(sc->hw);
1149 snprintf(sc->tx_led.name, sizeof(sc->tx_led.name),
1150 "ath9k-%s::tx", wiphy_name(sc->hw->wiphy));
1151 ret = ath_register_led(sc, &sc->tx_led, trigger);
1152 sc->tx_led.led_type = ATH_LED_TX;
1153 if (ret)
1154 goto fail;
1155
1156 trigger = ieee80211_get_rx_led_name(sc->hw);
1157 snprintf(sc->rx_led.name, sizeof(sc->rx_led.name),
1158 "ath9k-%s::rx", wiphy_name(sc->hw->wiphy));
1159 ret = ath_register_led(sc, &sc->rx_led, trigger);
1160 sc->rx_led.led_type = ATH_LED_RX;
1161 if (ret)
1162 goto fail;
1163
1164 return;
1165
1166fail:
1167 cancel_delayed_work_sync(&sc->ath_led_blink_work);
1168 ath_deinit_leds(sc);
1169}
1170
1171void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw) 853void ath_radio_enable(struct ath_softc *sc, struct ieee80211_hw *hw)
1172{ 854{
1173 struct ath_hw *ah = sc->sc_ah; 855 struct ath_hw *ah = sc->sc_ah;
@@ -1252,710 +934,6 @@ void ath_radio_disable(struct ath_softc *sc, struct ieee80211_hw *hw)
1252 ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP); 934 ath9k_setpower(sc, ATH9K_PM_FULL_SLEEP);
1253} 935}
1254 936
1255/*******************/
1256/* Rfkill */
1257/*******************/
1258
1259static bool ath_is_rfkill_set(struct ath_softc *sc)
1260{
1261 struct ath_hw *ah = sc->sc_ah;
1262
1263 return ath9k_hw_gpio_get(ah, ah->rfkill_gpio) ==
1264 ah->rfkill_polarity;
1265}
1266
1267static void ath9k_rfkill_poll_state(struct ieee80211_hw *hw)
1268{
1269 struct ath_wiphy *aphy = hw->priv;
1270 struct ath_softc *sc = aphy->sc;
1271 bool blocked = !!ath_is_rfkill_set(sc);
1272
1273 wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
1274}
1275
1276static void ath_start_rfkill_poll(struct ath_softc *sc)
1277{
1278 struct ath_hw *ah = sc->sc_ah;
1279
1280 if (ah->caps.hw_caps & ATH9K_HW_CAP_RFSILENT)
1281 wiphy_rfkill_start_polling(sc->hw->wiphy);
1282}
1283
1284static void ath9k_uninit_hw(struct ath_softc *sc)
1285{
1286 struct ath_hw *ah = sc->sc_ah;
1287
1288 BUG_ON(!ah);
1289
1290 ath9k_exit_debug(ah);
1291 ath9k_hw_detach(ah);
1292 sc->sc_ah = NULL;
1293}
1294
1295static void ath_clean_core(struct ath_softc *sc)
1296{
1297 struct ieee80211_hw *hw = sc->hw;
1298 struct ath_hw *ah = sc->sc_ah;
1299 int i = 0;
1300
1301 ath9k_ps_wakeup(sc);
1302
1303 dev_dbg(sc->dev, "Detach ATH hw\n");
1304
1305 ath_deinit_leds(sc);
1306 wiphy_rfkill_stop_polling(sc->hw->wiphy);
1307
1308 for (i = 0; i < sc->num_sec_wiphy; i++) {
1309 struct ath_wiphy *aphy = sc->sec_wiphy[i];
1310 if (aphy == NULL)
1311 continue;
1312 sc->sec_wiphy[i] = NULL;
1313 ieee80211_unregister_hw(aphy->hw);
1314 ieee80211_free_hw(aphy->hw);
1315 }
1316 ieee80211_unregister_hw(hw);
1317 ath_rx_cleanup(sc);
1318 ath_tx_cleanup(sc);
1319
1320 tasklet_kill(&sc->intr_tq);
1321 tasklet_kill(&sc->bcon_tasklet);
1322
1323 if (!(sc->sc_flags & SC_OP_INVALID))
1324 ath9k_setpower(sc, ATH9K_PM_AWAKE);
1325
1326 /* cleanup tx queues */
1327 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1328 if (ATH_TXQ_SETUP(sc, i))
1329 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1330
1331 if ((sc->btcoex.no_stomp_timer) &&
1332 ah->btcoex_hw.scheme == ATH_BTCOEX_CFG_3WIRE)
1333 ath_gen_timer_free(ah, sc->btcoex.no_stomp_timer);
1334}
1335
1336void ath_detach(struct ath_softc *sc)
1337{
1338 ath_clean_core(sc);
1339 ath9k_uninit_hw(sc);
1340}
1341
1342void ath_cleanup(struct ath_softc *sc)
1343{
1344 struct ath_hw *ah = sc->sc_ah;
1345 struct ath_common *common = ath9k_hw_common(ah);
1346
1347 ath_clean_core(sc);
1348 free_irq(sc->irq, sc);
1349 ath_bus_cleanup(common);
1350 kfree(sc->sec_wiphy);
1351 ieee80211_free_hw(sc->hw);
1352
1353 ath9k_uninit_hw(sc);
1354}
1355
1356static int ath9k_reg_notifier(struct wiphy *wiphy,
1357 struct regulatory_request *request)
1358{
1359 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
1360 struct ath_wiphy *aphy = hw->priv;
1361 struct ath_softc *sc = aphy->sc;
1362 struct ath_regulatory *reg = ath9k_hw_regulatory(sc->sc_ah);
1363
1364 return ath_reg_notifier_apply(wiphy, request, reg);
1365}
1366
1367/*
1368 * Detects if there is any priority bt traffic
1369 */
1370static void ath_detect_bt_priority(struct ath_softc *sc)
1371{
1372 struct ath_btcoex *btcoex = &sc->btcoex;
1373 struct ath_hw *ah = sc->sc_ah;
1374
1375 if (ath9k_hw_gpio_get(sc->sc_ah, ah->btcoex_hw.btpriority_gpio))
1376 btcoex->bt_priority_cnt++;
1377
1378 if (time_after(jiffies, btcoex->bt_priority_time +
1379 msecs_to_jiffies(ATH_BT_PRIORITY_TIME_THRESHOLD))) {
1380 if (btcoex->bt_priority_cnt >= ATH_BT_CNT_THRESHOLD) {
1381 ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_BTCOEX,
1382 "BT priority traffic detected");
1383 sc->sc_flags |= SC_OP_BT_PRIORITY_DETECTED;
1384 } else {
1385 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
1386 }
1387
1388 btcoex->bt_priority_cnt = 0;
1389 btcoex->bt_priority_time = jiffies;
1390 }
1391}
1392
1393/*
1394 * Configures appropriate weight based on stomp type.
1395 */
1396static void ath9k_btcoex_bt_stomp(struct ath_softc *sc,
1397 enum ath_stomp_type stomp_type)
1398{
1399 struct ath_hw *ah = sc->sc_ah;
1400
1401 switch (stomp_type) {
1402 case ATH_BTCOEX_STOMP_ALL:
1403 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1404 AR_STOMP_ALL_WLAN_WGHT);
1405 break;
1406 case ATH_BTCOEX_STOMP_LOW:
1407 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1408 AR_STOMP_LOW_WLAN_WGHT);
1409 break;
1410 case ATH_BTCOEX_STOMP_NONE:
1411 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT,
1412 AR_STOMP_NONE_WLAN_WGHT);
1413 break;
1414 default:
1415 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
1416 "Invalid Stomptype\n");
1417 break;
1418 }
1419
1420 ath9k_hw_btcoex_enable(ah);
1421}
1422
1423static void ath9k_gen_timer_start(struct ath_hw *ah,
1424 struct ath_gen_timer *timer,
1425 u32 timer_next,
1426 u32 timer_period)
1427{
1428 struct ath_common *common = ath9k_hw_common(ah);
1429 struct ath_softc *sc = (struct ath_softc *) common->priv;
1430
1431 ath9k_hw_gen_timer_start(ah, timer, timer_next, timer_period);
1432
1433 if ((sc->imask & ATH9K_INT_GENTIMER) == 0) {
1434 ath9k_hw_set_interrupts(ah, 0);
1435 sc->imask |= ATH9K_INT_GENTIMER;
1436 ath9k_hw_set_interrupts(ah, sc->imask);
1437 }
1438}
1439
1440static void ath9k_gen_timer_stop(struct ath_hw *ah, struct ath_gen_timer *timer)
1441{
1442 struct ath_common *common = ath9k_hw_common(ah);
1443 struct ath_softc *sc = (struct ath_softc *) common->priv;
1444 struct ath_gen_timer_table *timer_table = &ah->hw_gen_timers;
1445
1446 ath9k_hw_gen_timer_stop(ah, timer);
1447
1448 /* if no timer is enabled, turn off interrupt mask */
1449 if (timer_table->timer_mask.val == 0) {
1450 ath9k_hw_set_interrupts(ah, 0);
1451 sc->imask &= ~ATH9K_INT_GENTIMER;
1452 ath9k_hw_set_interrupts(ah, sc->imask);
1453 }
1454}
1455
1456/*
1457 * This is the master bt coex timer which runs for every
1458 * 45ms, bt traffic will be given priority during 55% of this
1459 * period while wlan gets remaining 45%
1460 */
1461static void ath_btcoex_period_timer(unsigned long data)
1462{
1463 struct ath_softc *sc = (struct ath_softc *) data;
1464 struct ath_hw *ah = sc->sc_ah;
1465 struct ath_btcoex *btcoex = &sc->btcoex;
1466
1467 ath_detect_bt_priority(sc);
1468
1469 spin_lock_bh(&btcoex->btcoex_lock);
1470
1471 ath9k_btcoex_bt_stomp(sc, btcoex->bt_stomp_type);
1472
1473 spin_unlock_bh(&btcoex->btcoex_lock);
1474
1475 if (btcoex->btcoex_period != btcoex->btcoex_no_stomp) {
1476 if (btcoex->hw_timer_enabled)
1477 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
1478
1479 ath9k_gen_timer_start(ah,
1480 btcoex->no_stomp_timer,
1481 (ath9k_hw_gettsf32(ah) +
1482 btcoex->btcoex_no_stomp),
1483 btcoex->btcoex_no_stomp * 10);
1484 btcoex->hw_timer_enabled = true;
1485 }
1486
1487 mod_timer(&btcoex->period_timer, jiffies +
1488 msecs_to_jiffies(ATH_BTCOEX_DEF_BT_PERIOD));
1489}
1490
1491/*
1492 * Generic tsf based hw timer which configures weight
1493 * registers to time slice between wlan and bt traffic
1494 */
1495static void ath_btcoex_no_stomp_timer(void *arg)
1496{
1497 struct ath_softc *sc = (struct ath_softc *)arg;
1498 struct ath_hw *ah = sc->sc_ah;
1499 struct ath_btcoex *btcoex = &sc->btcoex;
1500
1501 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
1502 "no stomp timer running \n");
1503
1504 spin_lock_bh(&btcoex->btcoex_lock);
1505
1506 if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_LOW)
1507 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_NONE);
1508 else if (btcoex->bt_stomp_type == ATH_BTCOEX_STOMP_ALL)
1509 ath9k_btcoex_bt_stomp(sc, ATH_BTCOEX_STOMP_LOW);
1510
1511 spin_unlock_bh(&btcoex->btcoex_lock);
1512}
1513
1514static int ath_init_btcoex_timer(struct ath_softc *sc)
1515{
1516 struct ath_btcoex *btcoex = &sc->btcoex;
1517
1518 btcoex->btcoex_period = ATH_BTCOEX_DEF_BT_PERIOD * 1000;
1519 btcoex->btcoex_no_stomp = (100 - ATH_BTCOEX_DEF_DUTY_CYCLE) *
1520 btcoex->btcoex_period / 100;
1521
1522 setup_timer(&btcoex->period_timer, ath_btcoex_period_timer,
1523 (unsigned long) sc);
1524
1525 spin_lock_init(&btcoex->btcoex_lock);
1526
1527 btcoex->no_stomp_timer = ath_gen_timer_alloc(sc->sc_ah,
1528 ath_btcoex_no_stomp_timer,
1529 ath_btcoex_no_stomp_timer,
1530 (void *) sc, AR_FIRST_NDP_TIMER);
1531
1532 if (!btcoex->no_stomp_timer)
1533 return -ENOMEM;
1534
1535 return 0;
1536}
1537
1538/*
1539 * Read and write, they both share the same lock. We do this to serialize
1540 * reads and writes on Atheros 802.11n PCI devices only. This is required
1541 * as the FIFO on these devices can only accept sanely 2 requests. After
1542 * that the device goes bananas. Serializing the reads/writes prevents this
1543 * from happening.
1544 */
1545
1546static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
1547{
1548 struct ath_hw *ah = (struct ath_hw *) hw_priv;
1549 struct ath_common *common = ath9k_hw_common(ah);
1550 struct ath_softc *sc = (struct ath_softc *) common->priv;
1551
1552 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
1553 unsigned long flags;
1554 spin_lock_irqsave(&sc->sc_serial_rw, flags);
1555 iowrite32(val, sc->mem + reg_offset);
1556 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
1557 } else
1558 iowrite32(val, sc->mem + reg_offset);
1559}
1560
1561static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
1562{
1563 struct ath_hw *ah = (struct ath_hw *) hw_priv;
1564 struct ath_common *common = ath9k_hw_common(ah);
1565 struct ath_softc *sc = (struct ath_softc *) common->priv;
1566 u32 val;
1567
1568 if (ah->config.serialize_regmode == SER_REG_MODE_ON) {
1569 unsigned long flags;
1570 spin_lock_irqsave(&sc->sc_serial_rw, flags);
1571 val = ioread32(sc->mem + reg_offset);
1572 spin_unlock_irqrestore(&sc->sc_serial_rw, flags);
1573 } else
1574 val = ioread32(sc->mem + reg_offset);
1575 return val;
1576}
1577
1578static const struct ath_ops ath9k_common_ops = {
1579 .read = ath9k_ioread32,
1580 .write = ath9k_iowrite32,
1581};
1582
1583/*
1584 * Initialize and fill ath_softc, ath_sofct is the
1585 * "Software Carrier" struct. Historically it has existed
1586 * to allow the separation between hardware specific
1587 * variables (now in ath_hw) and driver specific variables.
1588 */
1589static int ath_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
1590 const struct ath_bus_ops *bus_ops)
1591{
1592 struct ath_hw *ah = NULL;
1593 struct ath_common *common;
1594 int r = 0, i;
1595 int csz = 0;
1596 int qnum;
1597
1598 /* XXX: hardware will not be ready until ath_open() being called */
1599 sc->sc_flags |= SC_OP_INVALID;
1600
1601 spin_lock_init(&sc->wiphy_lock);
1602 spin_lock_init(&sc->sc_resetlock);
1603 spin_lock_init(&sc->sc_serial_rw);
1604 spin_lock_init(&sc->sc_pm_lock);
1605 mutex_init(&sc->mutex);
1606 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
1607 tasklet_init(&sc->bcon_tasklet, ath_beacon_tasklet,
1608 (unsigned long)sc);
1609
1610 ah = kzalloc(sizeof(struct ath_hw), GFP_KERNEL);
1611 if (!ah)
1612 return -ENOMEM;
1613
1614 ah->hw_version.devid = devid;
1615 ah->hw_version.subsysid = subsysid;
1616 sc->sc_ah = ah;
1617
1618 common = ath9k_hw_common(ah);
1619 common->ops = &ath9k_common_ops;
1620 common->bus_ops = bus_ops;
1621 common->ah = ah;
1622 common->hw = sc->hw;
1623 common->priv = sc;
1624 common->debug_mask = ath9k_debug;
1625
1626 /*
1627 * Cache line size is used to size and align various
1628 * structures used to communicate with the hardware.
1629 */
1630 ath_read_cachesize(common, &csz);
1631 /* XXX assert csz is non-zero */
1632 common->cachelsz = csz << 2; /* convert to bytes */
1633
1634 r = ath9k_hw_init(ah);
1635 if (r) {
1636 ath_print(common, ATH_DBG_FATAL,
1637 "Unable to initialize hardware; "
1638 "initialization status: %d\n", r);
1639 goto bad_free_hw;
1640 }
1641
1642 if (ath9k_init_debug(ah) < 0) {
1643 ath_print(common, ATH_DBG_FATAL,
1644 "Unable to create debugfs files\n");
1645 goto bad_free_hw;
1646 }
1647
1648 /* Get the hardware key cache size. */
1649 common->keymax = ah->caps.keycache_size;
1650 if (common->keymax > ATH_KEYMAX) {
1651 ath_print(common, ATH_DBG_ANY,
1652 "Warning, using only %u entries in %u key cache\n",
1653 ATH_KEYMAX, common->keymax);
1654 common->keymax = ATH_KEYMAX;
1655 }
1656
1657 /*
1658 * Reset the key cache since some parts do not
1659 * reset the contents on initial power up.
1660 */
1661 for (i = 0; i < common->keymax; i++)
1662 ath9k_hw_keyreset(ah, (u16) i);
1663
1664 /* default to MONITOR mode */
1665 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
1666
1667 /*
1668 * Allocate hardware transmit queues: one queue for
1669 * beacon frames and one data queue for each QoS
1670 * priority. Note that the hal handles reseting
1671 * these queues at the needed time.
1672 */
1673 sc->beacon.beaconq = ath9k_hw_beaconq_setup(ah);
1674 if (sc->beacon.beaconq == -1) {
1675 ath_print(common, ATH_DBG_FATAL,
1676 "Unable to setup a beacon xmit queue\n");
1677 r = -EIO;
1678 goto bad2;
1679 }
1680 sc->beacon.cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
1681 if (sc->beacon.cabq == NULL) {
1682 ath_print(common, ATH_DBG_FATAL,
1683 "Unable to setup CAB xmit queue\n");
1684 r = -EIO;
1685 goto bad2;
1686 }
1687
1688 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
1689 ath_cabq_update(sc);
1690
1691 for (i = 0; i < ARRAY_SIZE(sc->tx.hwq_map); i++)
1692 sc->tx.hwq_map[i] = -1;
1693
1694 /* Setup data queues */
1695 /* NB: ensure BK queue is the lowest priority h/w queue */
1696 if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
1697 ath_print(common, ATH_DBG_FATAL,
1698 "Unable to setup xmit queue for BK traffic\n");
1699 r = -EIO;
1700 goto bad2;
1701 }
1702
1703 if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
1704 ath_print(common, ATH_DBG_FATAL,
1705 "Unable to setup xmit queue for BE traffic\n");
1706 r = -EIO;
1707 goto bad2;
1708 }
1709 if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
1710 ath_print(common, ATH_DBG_FATAL,
1711 "Unable to setup xmit queue for VI traffic\n");
1712 r = -EIO;
1713 goto bad2;
1714 }
1715 if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
1716 ath_print(common, ATH_DBG_FATAL,
1717 "Unable to setup xmit queue for VO traffic\n");
1718 r = -EIO;
1719 goto bad2;
1720 }
1721
1722 /* Initializes the noise floor to a reasonable default value.
1723 * Later on this will be updated during ANI processing. */
1724
1725 common->ani.noise_floor = ATH_DEFAULT_NOISE_FLOOR;
1726 setup_timer(&common->ani.timer, ath_ani_calibrate, (unsigned long)sc);
1727
1728 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1729 ATH9K_CIPHER_TKIP, NULL)) {
1730 /*
1731 * Whether we should enable h/w TKIP MIC.
1732 * XXX: if we don't support WME TKIP MIC, then we wouldn't
1733 * report WMM capable, so it's always safe to turn on
1734 * TKIP MIC in this case.
1735 */
1736 ath9k_hw_setcapability(sc->sc_ah, ATH9K_CAP_TKIP_MIC,
1737 0, 1, NULL);
1738 }
1739
1740 /*
1741 * Check whether the separate key cache entries
1742 * are required to handle both tx+rx MIC keys.
1743 * With split mic keys the number of stations is limited
1744 * to 27 otherwise 59.
1745 */
1746 if (ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1747 ATH9K_CIPHER_TKIP, NULL)
1748 && ath9k_hw_getcapability(ah, ATH9K_CAP_CIPHER,
1749 ATH9K_CIPHER_MIC, NULL)
1750 && ath9k_hw_getcapability(ah, ATH9K_CAP_TKIP_SPLIT,
1751 0, NULL))
1752 common->splitmic = 1;
1753
1754 /* turn on mcast key search if possible */
1755 if (!ath9k_hw_getcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 0, NULL))
1756 (void)ath9k_hw_setcapability(ah, ATH9K_CAP_MCAST_KEYSRCH, 1,
1757 1, NULL);
1758
1759 sc->config.txpowlimit = ATH_TXPOWER_MAX;
1760
1761 /* 11n Capabilities */
1762 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
1763 sc->sc_flags |= SC_OP_TXAGGR;
1764 sc->sc_flags |= SC_OP_RXAGGR;
1765 }
1766
1767 common->tx_chainmask = ah->caps.tx_chainmask;
1768 common->rx_chainmask = ah->caps.rx_chainmask;
1769
1770 ath9k_hw_setcapability(ah, ATH9K_CAP_DIVERSITY, 1, true, NULL);
1771 sc->rx.defant = ath9k_hw_getdefantenna(ah);
1772
1773 if (ah->caps.hw_caps & ATH9K_HW_CAP_BSSIDMASK)
1774 memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
1775
1776 sc->beacon.slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
1777
1778 /* initialize beacon slots */
1779 for (i = 0; i < ARRAY_SIZE(sc->beacon.bslot); i++) {
1780 sc->beacon.bslot[i] = NULL;
1781 sc->beacon.bslot_aphy[i] = NULL;
1782 }
1783
1784 /* setup channels and rates */
1785
1786 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes)) {
1787 sc->sbands[IEEE80211_BAND_2GHZ].channels = ath9k_2ghz_chantable;
1788 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
1789 sc->sbands[IEEE80211_BAND_2GHZ].n_channels =
1790 ARRAY_SIZE(ath9k_2ghz_chantable);
1791 sc->sbands[IEEE80211_BAND_2GHZ].bitrates = ath9k_legacy_rates;
1792 sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates =
1793 ARRAY_SIZE(ath9k_legacy_rates);
1794 }
1795
1796 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes)) {
1797 sc->sbands[IEEE80211_BAND_5GHZ].channels = ath9k_5ghz_chantable;
1798 sc->sbands[IEEE80211_BAND_5GHZ].band = IEEE80211_BAND_5GHZ;
1799 sc->sbands[IEEE80211_BAND_5GHZ].n_channels =
1800 ARRAY_SIZE(ath9k_5ghz_chantable);
1801 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
1802 ath9k_legacy_rates + 4;
1803 sc->sbands[IEEE80211_BAND_5GHZ].n_bitrates =
1804 ARRAY_SIZE(ath9k_legacy_rates) - 4;
1805 }
1806
1807 switch (ah->btcoex_hw.scheme) {
1808 case ATH_BTCOEX_CFG_NONE:
1809 break;
1810 case ATH_BTCOEX_CFG_2WIRE:
1811 ath9k_hw_btcoex_init_2wire(ah);
1812 break;
1813 case ATH_BTCOEX_CFG_3WIRE:
1814 ath9k_hw_btcoex_init_3wire(ah);
1815 r = ath_init_btcoex_timer(sc);
1816 if (r)
1817 goto bad2;
1818 qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
1819 ath9k_hw_init_btcoex_hw(ah, qnum);
1820 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
1821 break;
1822 default:
1823 WARN_ON(1);
1824 break;
1825 }
1826
1827 return 0;
1828bad2:
1829 /* cleanup tx queues */
1830 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1831 if (ATH_TXQ_SETUP(sc, i))
1832 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1833
1834bad_free_hw:
1835 ath9k_uninit_hw(sc);
1836 return r;
1837}
1838
1839void ath_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
1840{
1841 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS |
1842 IEEE80211_HW_HOST_BROADCAST_PS_BUFFERING |
1843 IEEE80211_HW_SIGNAL_DBM |
1844 IEEE80211_HW_AMPDU_AGGREGATION |
1845 IEEE80211_HW_SUPPORTS_PS |
1846 IEEE80211_HW_PS_NULLFUNC_STACK |
1847 IEEE80211_HW_SPECTRUM_MGMT;
1848
1849 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || modparam_nohwcrypt)
1850 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
1851
1852 hw->wiphy->interface_modes =
1853 BIT(NL80211_IFTYPE_AP) |
1854 BIT(NL80211_IFTYPE_STATION) |
1855 BIT(NL80211_IFTYPE_ADHOC) |
1856 BIT(NL80211_IFTYPE_MESH_POINT);
1857
1858 hw->wiphy->flags &= ~WIPHY_FLAG_PS_ON_BY_DEFAULT;
1859
1860 hw->queues = 4;
1861 hw->max_rates = 4;
1862 hw->channel_change_time = 5000;
1863 hw->max_listen_interval = 10;
1864 /* Hardware supports 10 but we use 4 */
1865 hw->max_rate_tries = 4;
1866 hw->sta_data_size = sizeof(struct ath_node);
1867 hw->vif_data_size = sizeof(struct ath_vif);
1868
1869 hw->rate_control_algorithm = "ath9k_rate_control";
1870
1871 if (test_bit(ATH9K_MODE_11G, sc->sc_ah->caps.wireless_modes))
1872 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
1873 &sc->sbands[IEEE80211_BAND_2GHZ];
1874 if (test_bit(ATH9K_MODE_11A, sc->sc_ah->caps.wireless_modes))
1875 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1876 &sc->sbands[IEEE80211_BAND_5GHZ];
1877}
1878
1879/* Device driver core initialization */
1880int ath_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
1881 const struct ath_bus_ops *bus_ops)
1882{
1883 struct ieee80211_hw *hw = sc->hw;
1884 struct ath_common *common;
1885 struct ath_hw *ah;
1886 int error = 0, i;
1887 struct ath_regulatory *reg;
1888
1889 dev_dbg(sc->dev, "Attach ATH hw\n");
1890
1891 error = ath_init_softc(devid, sc, subsysid, bus_ops);
1892 if (error != 0)
1893 return error;
1894
1895 ah = sc->sc_ah;
1896 common = ath9k_hw_common(ah);
1897
1898 /* get mac address from hardware and set in mac80211 */
1899
1900 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
1901
1902 ath_set_hw_capab(sc, hw);
1903
1904 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
1905 ath9k_reg_notifier);
1906 if (error)
1907 return error;
1908
1909 reg = &common->regulatory;
1910
1911 if (ah->caps.hw_caps & ATH9K_HW_CAP_HT) {
1912 if (test_bit(ATH9K_MODE_11G, ah->caps.wireless_modes))
1913 setup_ht_cap(sc,
1914 &sc->sbands[IEEE80211_BAND_2GHZ].ht_cap);
1915 if (test_bit(ATH9K_MODE_11A, ah->caps.wireless_modes))
1916 setup_ht_cap(sc,
1917 &sc->sbands[IEEE80211_BAND_5GHZ].ht_cap);
1918 }
1919
1920 /* initialize tx/rx engine */
1921 error = ath_tx_init(sc, ATH_TXBUF);
1922 if (error != 0)
1923 goto error_attach;
1924
1925 error = ath_rx_init(sc, ATH_RXBUF);
1926 if (error != 0)
1927 goto error_attach;
1928
1929 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
1930 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
1931 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
1932
1933 error = ieee80211_register_hw(hw);
1934
1935 if (!ath_is_world_regd(reg)) {
1936 error = regulatory_hint(hw->wiphy, reg->alpha2);
1937 if (error)
1938 goto error_attach;
1939 }
1940
1941 /* Initialize LED control */
1942 ath_init_leds(sc);
1943
1944 ath_start_rfkill_poll(sc);
1945
1946 return 0;
1947
1948error_attach:
1949 /* cleanup tx queues */
1950 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1951 if (ATH_TXQ_SETUP(sc, i))
1952 ath_tx_cleanupq(sc, &sc->tx.txq[i]);
1953
1954 ath9k_uninit_hw(sc);
1955
1956 return error;
1957}
1958
1959int ath_reset(struct ath_softc *sc, bool retry_tx) 937int ath_reset(struct ath_softc *sc, bool retry_tx)
1960{ 938{
1961 struct ath_hw *ah = sc->sc_ah; 939 struct ath_hw *ah = sc->sc_ah;
@@ -1966,6 +944,8 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
1966 /* Stop ANI */ 944 /* Stop ANI */
1967 del_timer_sync(&common->ani.timer); 945 del_timer_sync(&common->ani.timer);
1968 946
947 ieee80211_stop_queues(hw);
948
1969 ath9k_hw_set_interrupts(ah, 0); 949 ath9k_hw_set_interrupts(ah, 0);
1970 ath_drain_all_txq(sc, retry_tx); 950 ath_drain_all_txq(sc, retry_tx);
1971 ath_stoprecv(sc); 951 ath_stoprecv(sc);
@@ -2007,131 +987,14 @@ int ath_reset(struct ath_softc *sc, bool retry_tx)
2007 } 987 }
2008 } 988 }
2009 989
990 ieee80211_wake_queues(hw);
991
2010 /* Start ANI */ 992 /* Start ANI */
2011 ath_start_ani(common); 993 ath_start_ani(common);
2012 994
2013 return r; 995 return r;
2014} 996}
2015 997
2016/*
2017 * This function will allocate both the DMA descriptor structure, and the
2018 * buffers it contains. These are used to contain the descriptors used
2019 * by the system.
2020*/
2021int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
2022 struct list_head *head, const char *name,
2023 int nbuf, int ndesc)
2024{
2025#define DS2PHYS(_dd, _ds) \
2026 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
2027#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
2028#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
2029 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
2030 struct ath_desc *ds;
2031 struct ath_buf *bf;
2032 int i, bsize, error;
2033
2034 ath_print(common, ATH_DBG_CONFIG, "%s DMA: %u buffers %u desc/buf\n",
2035 name, nbuf, ndesc);
2036
2037 INIT_LIST_HEAD(head);
2038 /* ath_desc must be a multiple of DWORDs */
2039 if ((sizeof(struct ath_desc) % 4) != 0) {
2040 ath_print(common, ATH_DBG_FATAL,
2041 "ath_desc not DWORD aligned\n");
2042 BUG_ON((sizeof(struct ath_desc) % 4) != 0);
2043 error = -ENOMEM;
2044 goto fail;
2045 }
2046
2047 dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
2048
2049 /*
2050 * Need additional DMA memory because we can't use
2051 * descriptors that cross the 4K page boundary. Assume
2052 * one skipped descriptor per 4K page.
2053 */
2054 if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
2055 u32 ndesc_skipped =
2056 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
2057 u32 dma_len;
2058
2059 while (ndesc_skipped) {
2060 dma_len = ndesc_skipped * sizeof(struct ath_desc);
2061 dd->dd_desc_len += dma_len;
2062
2063 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
2064 };
2065 }
2066
2067 /* allocate descriptors */
2068 dd->dd_desc = dma_alloc_coherent(sc->dev, dd->dd_desc_len,
2069 &dd->dd_desc_paddr, GFP_KERNEL);
2070 if (dd->dd_desc == NULL) {
2071 error = -ENOMEM;
2072 goto fail;
2073 }
2074 ds = dd->dd_desc;
2075 ath_print(common, ATH_DBG_CONFIG, "%s DMA map: %p (%u) -> %llx (%u)\n",
2076 name, ds, (u32) dd->dd_desc_len,
2077 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
2078
2079 /* allocate buffers */
2080 bsize = sizeof(struct ath_buf) * nbuf;
2081 bf = kzalloc(bsize, GFP_KERNEL);
2082 if (bf == NULL) {
2083 error = -ENOMEM;
2084 goto fail2;
2085 }
2086 dd->dd_bufptr = bf;
2087
2088 for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
2089 bf->bf_desc = ds;
2090 bf->bf_daddr = DS2PHYS(dd, ds);
2091
2092 if (!(sc->sc_ah->caps.hw_caps &
2093 ATH9K_HW_CAP_4KB_SPLITTRANS)) {
2094 /*
2095 * Skip descriptor addresses which can cause 4KB
2096 * boundary crossing (addr + length) with a 32 dword
2097 * descriptor fetch.
2098 */
2099 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
2100 BUG_ON((caddr_t) bf->bf_desc >=
2101 ((caddr_t) dd->dd_desc +
2102 dd->dd_desc_len));
2103
2104 ds += ndesc;
2105 bf->bf_desc = ds;
2106 bf->bf_daddr = DS2PHYS(dd, ds);
2107 }
2108 }
2109 list_add_tail(&bf->list, head);
2110 }
2111 return 0;
2112fail2:
2113 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
2114 dd->dd_desc_paddr);
2115fail:
2116 memset(dd, 0, sizeof(*dd));
2117 return error;
2118#undef ATH_DESC_4KB_BOUND_CHECK
2119#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
2120#undef DS2PHYS
2121}
2122
2123void ath_descdma_cleanup(struct ath_softc *sc,
2124 struct ath_descdma *dd,
2125 struct list_head *head)
2126{
2127 dma_free_coherent(sc->dev, dd->dd_desc_len, dd->dd_desc,
2128 dd->dd_desc_paddr);
2129
2130 INIT_LIST_HEAD(head);
2131 kfree(dd->dd_bufptr);
2132 memset(dd, 0, sizeof(*dd));
2133}
2134
2135int ath_get_hal_qnum(u16 queue, struct ath_softc *sc) 998int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
2136{ 999{
2137 int qnum; 1000 int qnum;
@@ -2210,28 +1073,6 @@ void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
2210/* mac80211 callbacks */ 1073/* mac80211 callbacks */
2211/**********************/ 1074/**********************/
2212 1075
2213/*
2214 * (Re)start btcoex timers
2215 */
2216static void ath9k_btcoex_timer_resume(struct ath_softc *sc)
2217{
2218 struct ath_btcoex *btcoex = &sc->btcoex;
2219 struct ath_hw *ah = sc->sc_ah;
2220
2221 ath_print(ath9k_hw_common(ah), ATH_DBG_BTCOEX,
2222 "Starting btcoex timers");
2223
2224 /* make sure duty cycle timer is also stopped when resuming */
2225 if (btcoex->hw_timer_enabled)
2226 ath9k_gen_timer_stop(sc->sc_ah, btcoex->no_stomp_timer);
2227
2228 btcoex->bt_priority_cnt = 0;
2229 btcoex->bt_priority_time = jiffies;
2230 sc->sc_flags &= ~SC_OP_BT_PRIORITY_DETECTED;
2231
2232 mod_timer(&btcoex->period_timer, jiffies);
2233}
2234
2235static int ath9k_start(struct ieee80211_hw *hw) 1076static int ath9k_start(struct ieee80211_hw *hw)
2236{ 1077{
2237 struct ath_wiphy *aphy = hw->priv; 1078 struct ath_wiphy *aphy = hw->priv;
@@ -2401,11 +1242,11 @@ static int ath9k_tx(struct ieee80211_hw *hw,
2401 if (ieee80211_is_pspoll(hdr->frame_control)) { 1242 if (ieee80211_is_pspoll(hdr->frame_control)) {
2402 ath_print(common, ATH_DBG_PS, 1243 ath_print(common, ATH_DBG_PS,
2403 "Sending PS-Poll to pick a buffered frame\n"); 1244 "Sending PS-Poll to pick a buffered frame\n");
2404 sc->sc_flags |= SC_OP_WAIT_FOR_PSPOLL_DATA; 1245 sc->ps_flags |= PS_WAIT_FOR_PSPOLL_DATA;
2405 } else { 1246 } else {
2406 ath_print(common, ATH_DBG_PS, 1247 ath_print(common, ATH_DBG_PS,
2407 "Wake up to complete TX\n"); 1248 "Wake up to complete TX\n");
2408 sc->sc_flags |= SC_OP_WAIT_FOR_TX_ACK; 1249 sc->ps_flags |= PS_WAIT_FOR_TX_ACK;
2409 } 1250 }
2410 /* 1251 /*
2411 * The actual restore operation will happen only after 1252 * The actual restore operation will happen only after
@@ -2458,22 +1299,6 @@ exit:
2458 return 0; 1299 return 0;
2459} 1300}
2460 1301
2461/*
2462 * Pause btcoex timer and bt duty cycle timer
2463 */
2464static void ath9k_btcoex_timer_pause(struct ath_softc *sc)
2465{
2466 struct ath_btcoex *btcoex = &sc->btcoex;
2467 struct ath_hw *ah = sc->sc_ah;
2468
2469 del_timer_sync(&btcoex->period_timer);
2470
2471 if (btcoex->hw_timer_enabled)
2472 ath9k_gen_timer_stop(ah, btcoex->no_stomp_timer);
2473
2474 btcoex->hw_timer_enabled = false;
2475}
2476
2477static void ath9k_stop(struct ieee80211_hw *hw) 1302static void ath9k_stop(struct ieee80211_hw *hw)
2478{ 1303{
2479 struct ath_wiphy *aphy = hw->priv; 1304 struct ath_wiphy *aphy = hw->priv;
@@ -2717,7 +1542,7 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2717 */ 1542 */
2718 if (changed & IEEE80211_CONF_CHANGE_PS) { 1543 if (changed & IEEE80211_CONF_CHANGE_PS) {
2719 if (conf->flags & IEEE80211_CONF_PS) { 1544 if (conf->flags & IEEE80211_CONF_PS) {
2720 sc->sc_flags |= SC_OP_PS_ENABLED; 1545 sc->ps_flags |= PS_ENABLED;
2721 if (!(ah->caps.hw_caps & 1546 if (!(ah->caps.hw_caps &
2722 ATH9K_HW_CAP_AUTOSLEEP)) { 1547 ATH9K_HW_CAP_AUTOSLEEP)) {
2723 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) { 1548 if ((sc->imask & ATH9K_INT_TIM_TIMER) == 0) {
@@ -2730,23 +1555,23 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2730 * At this point we know hardware has received an ACK 1555 * At this point we know hardware has received an ACK
2731 * of a previously sent null data frame. 1556 * of a previously sent null data frame.
2732 */ 1557 */
2733 if ((sc->sc_flags & SC_OP_NULLFUNC_COMPLETED)) { 1558 if ((sc->ps_flags & PS_NULLFUNC_COMPLETED)) {
2734 sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; 1559 sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
2735 sc->ps_enabled = true; 1560 sc->ps_enabled = true;
2736 ath9k_hw_setrxabort(sc->sc_ah, 1); 1561 ath9k_hw_setrxabort(sc->sc_ah, 1);
2737 } 1562 }
2738 } else { 1563 } else {
2739 sc->ps_enabled = false; 1564 sc->ps_enabled = false;
2740 sc->sc_flags &= ~(SC_OP_PS_ENABLED | 1565 sc->ps_flags &= ~(PS_ENABLED |
2741 SC_OP_NULLFUNC_COMPLETED); 1566 PS_NULLFUNC_COMPLETED);
2742 ath9k_setpower(sc, ATH9K_PM_AWAKE); 1567 ath9k_setpower(sc, ATH9K_PM_AWAKE);
2743 if (!(ah->caps.hw_caps & 1568 if (!(ah->caps.hw_caps &
2744 ATH9K_HW_CAP_AUTOSLEEP)) { 1569 ATH9K_HW_CAP_AUTOSLEEP)) {
2745 ath9k_hw_setrxabort(sc->sc_ah, 0); 1570 ath9k_hw_setrxabort(sc->sc_ah, 0);
2746 sc->sc_flags &= ~(SC_OP_WAIT_FOR_BEACON | 1571 sc->ps_flags &= ~(PS_WAIT_FOR_BEACON |
2747 SC_OP_WAIT_FOR_CAB | 1572 PS_WAIT_FOR_CAB |
2748 SC_OP_WAIT_FOR_PSPOLL_DATA | 1573 PS_WAIT_FOR_PSPOLL_DATA |
2749 SC_OP_WAIT_FOR_TX_ACK); 1574 PS_WAIT_FOR_TX_ACK);
2750 if (sc->imask & ATH9K_INT_TIM_TIMER) { 1575 if (sc->imask & ATH9K_INT_TIM_TIMER) {
2751 sc->imask &= ~ATH9K_INT_TIM_TIMER; 1576 sc->imask &= ~ATH9K_INT_TIM_TIMER;
2752 ath9k_hw_set_interrupts(sc->sc_ah, 1577 ath9k_hw_set_interrupts(sc->sc_ah,
@@ -2756,6 +1581,14 @@ static int ath9k_config(struct ieee80211_hw *hw, u32 changed)
2756 } 1581 }
2757 } 1582 }
2758 1583
1584 if (changed & IEEE80211_CONF_CHANGE_MONITOR) {
1585 if (conf->flags & IEEE80211_CONF_MONITOR) {
1586 ath_print(common, ATH_DBG_CONFIG,
1587 "HW opmode set to Monitor mode\n");
1588 sc->sc_ah->opmode = NL80211_IFTYPE_MONITOR;
1589 }
1590 }
1591
2759 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 1592 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
2760 struct ieee80211_channel *curchan = hw->conf.channel; 1593 struct ieee80211_channel *curchan = hw->conf.channel;
2761 int pos = curchan->hw_value; 1594 int pos = curchan->hw_value;
@@ -2956,6 +1789,7 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2956 struct ath_hw *ah = sc->sc_ah; 1789 struct ath_hw *ah = sc->sc_ah;
2957 struct ath_common *common = ath9k_hw_common(ah); 1790 struct ath_common *common = ath9k_hw_common(ah);
2958 struct ath_vif *avp = (void *)vif->drv_priv; 1791 struct ath_vif *avp = (void *)vif->drv_priv;
1792 int slottime;
2959 int error; 1793 int error;
2960 1794
2961 mutex_lock(&sc->mutex); 1795 mutex_lock(&sc->mutex);
@@ -2991,6 +1825,25 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
2991 ath_beacon_config(sc, vif); 1825 ath_beacon_config(sc, vif);
2992 } 1826 }
2993 1827
1828 if (changed & BSS_CHANGED_ERP_SLOT) {
1829 if (bss_conf->use_short_slot)
1830 slottime = 9;
1831 else
1832 slottime = 20;
1833 if (vif->type == NL80211_IFTYPE_AP) {
1834 /*
1835 * Defer update, so that connected stations can adjust
1836 * their settings at the same time.
1837 * See beacon.c for more details
1838 */
1839 sc->beacon.slottime = slottime;
1840 sc->beacon.updateslot = UPDATE;
1841 } else {
1842 ah->slottime = slottime;
1843 ath9k_hw_init_global_settings(ah);
1844 }
1845 }
1846
2994 /* Disable transmission of beacons */ 1847 /* Disable transmission of beacons */
2995 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon) 1848 if ((changed & BSS_CHANGED_BEACON_ENABLED) && !bss_conf->enable_beacon)
2996 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq); 1849 ath9k_hw_stoptxdma(sc->sc_ah, sc->beacon.beaconq);
@@ -3161,6 +2014,18 @@ static void ath9k_sw_scan_complete(struct ieee80211_hw *hw)
3161 mutex_unlock(&sc->mutex); 2014 mutex_unlock(&sc->mutex);
3162} 2015}
3163 2016
2017static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
2018{
2019 struct ath_wiphy *aphy = hw->priv;
2020 struct ath_softc *sc = aphy->sc;
2021 struct ath_hw *ah = sc->sc_ah;
2022
2023 mutex_lock(&sc->mutex);
2024 ah->coverage_class = coverage_class;
2025 ath9k_hw_init_global_settings(ah);
2026 mutex_unlock(&sc->mutex);
2027}
2028
3164struct ieee80211_ops ath9k_ops = { 2029struct ieee80211_ops ath9k_ops = {
3165 .tx = ath9k_tx, 2030 .tx = ath9k_tx,
3166 .start = ath9k_start, 2031 .start = ath9k_start,
@@ -3180,64 +2045,5 @@ struct ieee80211_ops ath9k_ops = {
3180 .sw_scan_start = ath9k_sw_scan_start, 2045 .sw_scan_start = ath9k_sw_scan_start,
3181 .sw_scan_complete = ath9k_sw_scan_complete, 2046 .sw_scan_complete = ath9k_sw_scan_complete,
3182 .rfkill_poll = ath9k_rfkill_poll_state, 2047 .rfkill_poll = ath9k_rfkill_poll_state,
2048 .set_coverage_class = ath9k_set_coverage_class,
3183}; 2049};
3184
3185static int __init ath9k_init(void)
3186{
3187 int error;
3188
3189 /* Register rate control algorithm */
3190 error = ath_rate_control_register();
3191 if (error != 0) {
3192 printk(KERN_ERR
3193 "ath9k: Unable to register rate control "
3194 "algorithm: %d\n",
3195 error);
3196 goto err_out;
3197 }
3198
3199 error = ath9k_debug_create_root();
3200 if (error) {
3201 printk(KERN_ERR
3202 "ath9k: Unable to create debugfs root: %d\n",
3203 error);
3204 goto err_rate_unregister;
3205 }
3206
3207 error = ath_pci_init();
3208 if (error < 0) {
3209 printk(KERN_ERR
3210 "ath9k: No PCI devices found, driver not installed.\n");
3211 error = -ENODEV;
3212 goto err_remove_root;
3213 }
3214
3215 error = ath_ahb_init();
3216 if (error < 0) {
3217 error = -ENODEV;
3218 goto err_pci_exit;
3219 }
3220
3221 return 0;
3222
3223 err_pci_exit:
3224 ath_pci_exit();
3225
3226 err_remove_root:
3227 ath9k_debug_remove_root();
3228 err_rate_unregister:
3229 ath_rate_control_unregister();
3230 err_out:
3231 return error;
3232}
3233module_init(ath9k_init);
3234
3235static void __exit ath9k_exit(void)
3236{
3237 ath_ahb_exit();
3238 ath_pci_exit();
3239 ath9k_debug_remove_root();
3240 ath_rate_control_unregister();
3241 printk(KERN_INFO "%s: Driver unloaded\n", dev_info);
3242}
3243module_exit(ath9k_exit);
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index ee617205cb4a..fe2c3a644a6e 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -113,25 +113,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
113 u16 subsysid; 113 u16 subsysid;
114 u32 val; 114 u32 val;
115 int ret = 0; 115 int ret = 0;
116 struct ath_hw *ah;
117 char hw_name[64]; 116 char hw_name[64];
118 117
119 if (pci_enable_device(pdev)) 118 if (pci_enable_device(pdev))
120 return -EIO; 119 return -EIO;
121 120
122 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); 121 ret = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
123
124 if (ret) { 122 if (ret) {
125 printk(KERN_ERR "ath9k: 32-bit DMA not available\n"); 123 printk(KERN_ERR "ath9k: 32-bit DMA not available\n");
126 goto bad; 124 goto err_dma;
127 } 125 }
128 126
129 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); 127 ret = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
130
131 if (ret) { 128 if (ret) {
132 printk(KERN_ERR "ath9k: 32-bit DMA consistent " 129 printk(KERN_ERR "ath9k: 32-bit DMA consistent "
133 "DMA enable failed\n"); 130 "DMA enable failed\n");
134 goto bad; 131 goto err_dma;
135 } 132 }
136 133
137 /* 134 /*
@@ -171,22 +168,22 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
171 if (ret) { 168 if (ret) {
172 dev_err(&pdev->dev, "PCI memory region reserve error\n"); 169 dev_err(&pdev->dev, "PCI memory region reserve error\n");
173 ret = -ENODEV; 170 ret = -ENODEV;
174 goto bad; 171 goto err_region;
175 } 172 }
176 173
177 mem = pci_iomap(pdev, 0, 0); 174 mem = pci_iomap(pdev, 0, 0);
178 if (!mem) { 175 if (!mem) {
179 printk(KERN_ERR "PCI memory map error\n") ; 176 printk(KERN_ERR "PCI memory map error\n") ;
180 ret = -EIO; 177 ret = -EIO;
181 goto bad1; 178 goto err_iomap;
182 } 179 }
183 180
184 hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) + 181 hw = ieee80211_alloc_hw(sizeof(struct ath_wiphy) +
185 sizeof(struct ath_softc), &ath9k_ops); 182 sizeof(struct ath_softc), &ath9k_ops);
186 if (!hw) { 183 if (!hw) {
187 dev_err(&pdev->dev, "no memory for ieee80211_hw\n"); 184 dev_err(&pdev->dev, "No memory for ieee80211_hw\n");
188 ret = -ENOMEM; 185 ret = -ENOMEM;
189 goto bad2; 186 goto err_alloc_hw;
190 } 187 }
191 188
192 SET_IEEE80211_DEV(hw, &pdev->dev); 189 SET_IEEE80211_DEV(hw, &pdev->dev);
@@ -201,25 +198,25 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
201 sc->dev = &pdev->dev; 198 sc->dev = &pdev->dev;
202 sc->mem = mem; 199 sc->mem = mem;
203 200
204 pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid); 201 /* Will be cleared in ath9k_start() */
205 ret = ath_init_device(id->device, sc, subsysid, &ath_pci_bus_ops); 202 sc->sc_flags |= SC_OP_INVALID;
206 if (ret) {
207 dev_err(&pdev->dev, "failed to initialize device\n");
208 goto bad3;
209 }
210
211 /* setup interrupt service routine */
212 203
213 ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc); 204 ret = request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath9k", sc);
214 if (ret) { 205 if (ret) {
215 dev_err(&pdev->dev, "request_irq failed\n"); 206 dev_err(&pdev->dev, "request_irq failed\n");
216 goto bad4; 207 goto err_irq;
217 } 208 }
218 209
219 sc->irq = pdev->irq; 210 sc->irq = pdev->irq;
220 211
221 ah = sc->sc_ah; 212 pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
222 ath9k_hw_name(ah, hw_name, sizeof(hw_name)); 213 ret = ath9k_init_device(id->device, sc, subsysid, &ath_pci_bus_ops);
214 if (ret) {
215 dev_err(&pdev->dev, "Failed to initialize device\n");
216 goto err_init;
217 }
218
219 ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
223 printk(KERN_INFO 220 printk(KERN_INFO
224 "%s: %s mem=0x%lx, irq=%d\n", 221 "%s: %s mem=0x%lx, irq=%d\n",
225 wiphy_name(hw->wiphy), 222 wiphy_name(hw->wiphy),
@@ -227,15 +224,18 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
227 (unsigned long)mem, pdev->irq); 224 (unsigned long)mem, pdev->irq);
228 225
229 return 0; 226 return 0;
230bad4: 227
231 ath_detach(sc); 228err_init:
232bad3: 229 free_irq(sc->irq, sc);
230err_irq:
233 ieee80211_free_hw(hw); 231 ieee80211_free_hw(hw);
234bad2: 232err_alloc_hw:
235 pci_iounmap(pdev, mem); 233 pci_iounmap(pdev, mem);
236bad1: 234err_iomap:
237 pci_release_region(pdev, 0); 235 pci_release_region(pdev, 0);
238bad: 236err_region:
237 /* Nothing */
238err_dma:
239 pci_disable_device(pdev); 239 pci_disable_device(pdev);
240 return ret; 240 return ret;
241} 241}
@@ -245,8 +245,12 @@ static void ath_pci_remove(struct pci_dev *pdev)
245 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 245 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
246 struct ath_wiphy *aphy = hw->priv; 246 struct ath_wiphy *aphy = hw->priv;
247 struct ath_softc *sc = aphy->sc; 247 struct ath_softc *sc = aphy->sc;
248 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
248 249
249 ath_cleanup(sc); 250 ath9k_deinit_device(sc);
251 free_irq(sc->irq, sc);
252 ieee80211_free_hw(sc->hw);
253 ath_bus_cleanup(common);
250} 254}
251 255
252#ifdef CONFIG_PM 256#ifdef CONFIG_PM
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 477365e5ae69..40b5d05edcce 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -364,10 +364,10 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
364 if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0) 364 if (memcmp(common->curbssid, mgmt->bssid, ETH_ALEN) != 0)
365 return; /* not from our current AP */ 365 return; /* not from our current AP */
366 366
367 sc->sc_flags &= ~SC_OP_WAIT_FOR_BEACON; 367 sc->ps_flags &= ~PS_WAIT_FOR_BEACON;
368 368
369 if (sc->sc_flags & SC_OP_BEACON_SYNC) { 369 if (sc->ps_flags & PS_BEACON_SYNC) {
370 sc->sc_flags &= ~SC_OP_BEACON_SYNC; 370 sc->ps_flags &= ~PS_BEACON_SYNC;
371 ath_print(common, ATH_DBG_PS, 371 ath_print(common, ATH_DBG_PS,
372 "Reconfigure Beacon timers based on " 372 "Reconfigure Beacon timers based on "
373 "timestamp from the AP\n"); 373 "timestamp from the AP\n");
@@ -384,17 +384,17 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
384 */ 384 */
385 ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating " 385 ath_print(common, ATH_DBG_PS, "Received DTIM beacon indicating "
386 "buffered broadcast/multicast frame(s)\n"); 386 "buffered broadcast/multicast frame(s)\n");
387 sc->sc_flags |= SC_OP_WAIT_FOR_CAB | SC_OP_WAIT_FOR_BEACON; 387 sc->ps_flags |= PS_WAIT_FOR_CAB | PS_WAIT_FOR_BEACON;
388 return; 388 return;
389 } 389 }
390 390
391 if (sc->sc_flags & SC_OP_WAIT_FOR_CAB) { 391 if (sc->ps_flags & PS_WAIT_FOR_CAB) {
392 /* 392 /*
393 * This can happen if a broadcast frame is dropped or the AP 393 * This can happen if a broadcast frame is dropped or the AP
394 * fails to send a frame indicating that all CAB frames have 394 * fails to send a frame indicating that all CAB frames have
395 * been delivered. 395 * been delivered.
396 */ 396 */
397 sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB; 397 sc->ps_flags &= ~PS_WAIT_FOR_CAB;
398 ath_print(common, ATH_DBG_PS, 398 ath_print(common, ATH_DBG_PS,
399 "PS wait for CAB frames timed out\n"); 399 "PS wait for CAB frames timed out\n");
400 } 400 }
@@ -408,10 +408,10 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
408 hdr = (struct ieee80211_hdr *)skb->data; 408 hdr = (struct ieee80211_hdr *)skb->data;
409 409
410 /* Process Beacon and CAB receive in PS state */ 410 /* Process Beacon and CAB receive in PS state */
411 if ((sc->sc_flags & SC_OP_WAIT_FOR_BEACON) && 411 if ((sc->ps_flags & PS_WAIT_FOR_BEACON) &&
412 ieee80211_is_beacon(hdr->frame_control)) 412 ieee80211_is_beacon(hdr->frame_control))
413 ath_rx_ps_beacon(sc, skb); 413 ath_rx_ps_beacon(sc, skb);
414 else if ((sc->sc_flags & SC_OP_WAIT_FOR_CAB) && 414 else if ((sc->ps_flags & PS_WAIT_FOR_CAB) &&
415 (ieee80211_is_data(hdr->frame_control) || 415 (ieee80211_is_data(hdr->frame_control) ||
416 ieee80211_is_action(hdr->frame_control)) && 416 ieee80211_is_action(hdr->frame_control)) &&
417 is_multicast_ether_addr(hdr->addr1) && 417 is_multicast_ether_addr(hdr->addr1) &&
@@ -420,20 +420,20 @@ static void ath_rx_ps(struct ath_softc *sc, struct sk_buff *skb)
420 * No more broadcast/multicast frames to be received at this 420 * No more broadcast/multicast frames to be received at this
421 * point. 421 * point.
422 */ 422 */
423 sc->sc_flags &= ~SC_OP_WAIT_FOR_CAB; 423 sc->ps_flags &= ~PS_WAIT_FOR_CAB;
424 ath_print(common, ATH_DBG_PS, 424 ath_print(common, ATH_DBG_PS,
425 "All PS CAB frames received, back to sleep\n"); 425 "All PS CAB frames received, back to sleep\n");
426 } else if ((sc->sc_flags & SC_OP_WAIT_FOR_PSPOLL_DATA) && 426 } else if ((sc->ps_flags & PS_WAIT_FOR_PSPOLL_DATA) &&
427 !is_multicast_ether_addr(hdr->addr1) && 427 !is_multicast_ether_addr(hdr->addr1) &&
428 !ieee80211_has_morefrags(hdr->frame_control)) { 428 !ieee80211_has_morefrags(hdr->frame_control)) {
429 sc->sc_flags &= ~SC_OP_WAIT_FOR_PSPOLL_DATA; 429 sc->ps_flags &= ~PS_WAIT_FOR_PSPOLL_DATA;
430 ath_print(common, ATH_DBG_PS, 430 ath_print(common, ATH_DBG_PS,
431 "Going back to sleep after having received " 431 "Going back to sleep after having received "
432 "PS-Poll data (0x%x)\n", 432 "PS-Poll data (0x%x)\n",
433 sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 433 sc->ps_flags & (PS_WAIT_FOR_BEACON |
434 SC_OP_WAIT_FOR_CAB | 434 PS_WAIT_FOR_CAB |
435 SC_OP_WAIT_FOR_PSPOLL_DATA | 435 PS_WAIT_FOR_PSPOLL_DATA |
436 SC_OP_WAIT_FOR_TX_ACK)); 436 PS_WAIT_FOR_TX_ACK));
437 } 437 }
438} 438}
439 439
@@ -571,6 +571,8 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
571 hw = ath_get_virt_hw(sc, hdr); 571 hw = ath_get_virt_hw(sc, hdr);
572 rx_stats = &ds->ds_rxstat; 572 rx_stats = &ds->ds_rxstat;
573 573
574 ath_debug_stat_rx(sc, bf);
575
574 /* 576 /*
575 * If we're asked to flush receive queue, directly 577 * If we're asked to flush receive queue, directly
576 * chain it back at the queue without processing it. 578 * chain it back at the queue without processing it.
@@ -631,9 +633,9 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush)
631 sc->rx.rxotherant = 0; 633 sc->rx.rxotherant = 0;
632 } 634 }
633 635
634 if (unlikely(sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 636 if (unlikely(sc->ps_flags & (PS_WAIT_FOR_BEACON |
635 SC_OP_WAIT_FOR_CAB | 637 PS_WAIT_FOR_CAB |
636 SC_OP_WAIT_FOR_PSPOLL_DATA))) 638 PS_WAIT_FOR_PSPOLL_DATA)))
637 ath_rx_ps(sc, skb); 639 ath_rx_ps(sc, skb);
638 640
639 ath_rx_send_to_mac80211(hw, sc, skb, rxs); 641 ath_rx_send_to_mac80211(hw, sc, skb, rxs);
diff --git a/drivers/net/wireless/ath/ath9k/virtual.c b/drivers/net/wireless/ath/ath9k/virtual.c
index cd26caaf44e7..a43fbf84dab9 100644
--- a/drivers/net/wireless/ath/ath9k/virtual.c
+++ b/drivers/net/wireless/ath/ath9k/virtual.c
@@ -152,7 +152,7 @@ int ath9k_wiphy_add(struct ath_softc *sc)
152 152
153 SET_IEEE80211_PERM_ADDR(hw, addr); 153 SET_IEEE80211_PERM_ADDR(hw, addr);
154 154
155 ath_set_hw_capab(sc, hw); 155 ath9k_set_hw_capab(sc, hw);
156 156
157 error = ieee80211_register_hw(hw); 157 error = ieee80211_register_hw(hw);
158 158
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index fa12b9060b0b..a821bb687b3b 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1648,7 +1648,7 @@ static int ath_tx_setup_buffer(struct ieee80211_hw *hw, struct ath_buf *bf,
1648 /* tag if this is a nullfunc frame to enable PS when AP acks it */ 1648 /* tag if this is a nullfunc frame to enable PS when AP acks it */
1649 if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) { 1649 if (ieee80211_is_nullfunc(fc) && ieee80211_has_pm(fc)) {
1650 bf->bf_isnullfunc = true; 1650 bf->bf_isnullfunc = true;
1651 sc->sc_flags &= ~SC_OP_NULLFUNC_COMPLETED; 1651 sc->ps_flags &= ~PS_NULLFUNC_COMPLETED;
1652 } else 1652 } else
1653 bf->bf_isnullfunc = false; 1653 bf->bf_isnullfunc = false;
1654 1654
@@ -1858,15 +1858,15 @@ static void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1858 skb_pull(skb, padsize); 1858 skb_pull(skb, padsize);
1859 } 1859 }
1860 1860
1861 if (sc->sc_flags & SC_OP_WAIT_FOR_TX_ACK) { 1861 if (sc->ps_flags & PS_WAIT_FOR_TX_ACK) {
1862 sc->sc_flags &= ~SC_OP_WAIT_FOR_TX_ACK; 1862 sc->ps_flags &= ~PS_WAIT_FOR_TX_ACK;
1863 ath_print(common, ATH_DBG_PS, 1863 ath_print(common, ATH_DBG_PS,
1864 "Going back to sleep after having " 1864 "Going back to sleep after having "
1865 "received TX status (0x%x)\n", 1865 "received TX status (0x%x)\n",
1866 sc->sc_flags & (SC_OP_WAIT_FOR_BEACON | 1866 sc->ps_flags & (PS_WAIT_FOR_BEACON |
1867 SC_OP_WAIT_FOR_CAB | 1867 PS_WAIT_FOR_CAB |
1868 SC_OP_WAIT_FOR_PSPOLL_DATA | 1868 PS_WAIT_FOR_PSPOLL_DATA |
1869 SC_OP_WAIT_FOR_TX_ACK)); 1869 PS_WAIT_FOR_TX_ACK));
1870 } 1870 }
1871 1871
1872 if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL)) 1872 if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL))
@@ -2053,11 +2053,11 @@ static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
2053 */ 2053 */
2054 if (bf->bf_isnullfunc && 2054 if (bf->bf_isnullfunc &&
2055 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) { 2055 (ds->ds_txstat.ts_status & ATH9K_TX_ACKED)) {
2056 if ((sc->sc_flags & SC_OP_PS_ENABLED)) { 2056 if ((sc->ps_flags & PS_ENABLED)) {
2057 sc->ps_enabled = true; 2057 sc->ps_enabled = true;
2058 ath9k_hw_setrxabort(sc->sc_ah, 1); 2058 ath9k_hw_setrxabort(sc->sc_ah, 1);
2059 } else 2059 } else
2060 sc->sc_flags |= SC_OP_NULLFUNC_COMPLETED; 2060 sc->ps_flags |= PS_NULLFUNC_COMPLETED;
2061 } 2061 }
2062 2062
2063 /* 2063 /*
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 2f12a750bc98..54d6085a887b 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -253,6 +253,14 @@ enum {
253#define B43_SHM_SH_MAXBFRAMES 0x0080 /* Maximum number of frames in a burst */ 253#define B43_SHM_SH_MAXBFRAMES 0x0080 /* Maximum number of frames in a burst */
254#define B43_SHM_SH_SPUWKUP 0x0094 /* pre-wakeup for synth PU in us */ 254#define B43_SHM_SH_SPUWKUP 0x0094 /* pre-wakeup for synth PU in us */
255#define B43_SHM_SH_PRETBTT 0x0096 /* pre-TBTT in us */ 255#define B43_SHM_SH_PRETBTT 0x0096 /* pre-TBTT in us */
256/* SHM_SHARED tx iq workarounds */
257#define B43_SHM_SH_NPHY_TXIQW0 0x0700
258#define B43_SHM_SH_NPHY_TXIQW1 0x0702
259#define B43_SHM_SH_NPHY_TXIQW2 0x0704
260#define B43_SHM_SH_NPHY_TXIQW3 0x0706
261/* SHM_SHARED tx pwr ctrl */
262#define B43_SHM_SH_NPHY_TXPWR_INDX0 0x0708
263#define B43_SHM_SH_NPHY_TXPWR_INDX1 0x070E
256 264
257/* SHM_SCRATCH offsets */ 265/* SHM_SCRATCH offsets */
258#define B43_SHM_SC_MINCONT 0x0003 /* Minimum contention window */ 266#define B43_SHM_SC_MINCONT 0x0003 /* Minimum contention window */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 60290c06e950..9c5c7c9ad530 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -67,7 +67,12 @@ MODULE_AUTHOR("Gábor Stefanik");
67MODULE_LICENSE("GPL"); 67MODULE_LICENSE("GPL");
68 68
69MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID); 69MODULE_FIRMWARE(B43_SUPPORTED_FIRMWARE_ID);
70 70MODULE_FIRMWARE("b43/ucode11.fw");
71MODULE_FIRMWARE("b43/ucode13.fw");
72MODULE_FIRMWARE("b43/ucode14.fw");
73MODULE_FIRMWARE("b43/ucode15.fw");
74MODULE_FIRMWARE("b43/ucode5.fw");
75MODULE_FIRMWARE("b43/ucode9.fw");
71 76
72static int modparam_bad_frames_preempt; 77static int modparam_bad_frames_preempt;
73module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); 78module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
@@ -113,6 +118,7 @@ static const struct ssb_device_id b43_ssb_tbl[] = {
113 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9), 118 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 9),
114 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10), 119 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 10),
115 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11), 120 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 11),
121 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 12),
116 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13), 122 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 13),
117 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15), 123 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 15),
118 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16), 124 SSB_DEVICE(SSB_VENDOR_BROADCOM, SSB_DEV_80211, 16),
diff --git a/drivers/net/wireless/b43/phy_lp.c b/drivers/net/wireless/b43/phy_lp.c
index 3e046ec1ff86..b58d6cf26580 100644
--- a/drivers/net/wireless/b43/phy_lp.c
+++ b/drivers/net/wireless/b43/phy_lp.c
@@ -80,6 +80,7 @@ static void b43_lpphy_op_free(struct b43_wldev *dev)
80 dev->phy.lp = NULL; 80 dev->phy.lp = NULL;
81} 81}
82 82
83/* http://bcm-v4.sipsolutions.net/802.11/PHY/LP/ReadBandSrom */
83static void lpphy_read_band_sprom(struct b43_wldev *dev) 84static void lpphy_read_band_sprom(struct b43_wldev *dev)
84{ 85{
85 struct b43_phy_lp *lpphy = dev->phy.lp; 86 struct b43_phy_lp *lpphy = dev->phy.lp;
@@ -101,6 +102,12 @@ static void lpphy_read_band_sprom(struct b43_wldev *dev)
101 maxpwr = bus->sprom.maxpwr_bg; 102 maxpwr = bus->sprom.maxpwr_bg;
102 lpphy->max_tx_pwr_med_band = maxpwr; 103 lpphy->max_tx_pwr_med_band = maxpwr;
103 cckpo = bus->sprom.cck2gpo; 104 cckpo = bus->sprom.cck2gpo;
105 /*
106 * We don't read SPROM's opo as specs say. On rev8 SPROMs
107 * opo == ofdm2gpo and we don't know any SSB with LP-PHY
108 * and SPROM rev below 8.
109 */
110 B43_WARN_ON(bus->sprom.revision < 8);
104 ofdmpo = bus->sprom.ofdm2gpo; 111 ofdmpo = bus->sprom.ofdm2gpo;
105 if (cckpo) { 112 if (cckpo) {
106 for (i = 0; i < 4; i++) { 113 for (i = 0; i < 4; i++) {
@@ -1703,19 +1710,6 @@ static const struct lpphy_rx_iq_comp lpphy_rev2plus_iq_comp = {
1703 .c0 = 0, 1710 .c0 = 0,
1704}; 1711};
1705 1712
1706static u8 lpphy_nbits(s32 val)
1707{
1708 u32 tmp = abs(val);
1709 u8 nbits = 0;
1710
1711 while (tmp != 0) {
1712 nbits++;
1713 tmp >>= 1;
1714 }
1715
1716 return nbits;
1717}
1718
1719static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples) 1713static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples)
1720{ 1714{
1721 struct lpphy_iq_est iq_est; 1715 struct lpphy_iq_est iq_est;
@@ -1742,8 +1736,8 @@ static int lpphy_calc_rx_iq_comp(struct b43_wldev *dev, u16 samples)
1742 goto out; 1736 goto out;
1743 } 1737 }
1744 1738
1745 prod_msb = lpphy_nbits(prod); 1739 prod_msb = fls(abs(prod));
1746 q_msb = lpphy_nbits(qpwr); 1740 q_msb = fls(abs(qpwr));
1747 tmp1 = prod_msb - 20; 1741 tmp1 = prod_msb - 20;
1748 1742
1749 if (tmp1 >= 0) { 1743 if (tmp1 >= 0) {
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 992318a78077..4a817e3da163 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -28,7 +28,32 @@
28#include "b43.h" 28#include "b43.h"
29#include "phy_n.h" 29#include "phy_n.h"
30#include "tables_nphy.h" 30#include "tables_nphy.h"
31#include "main.h"
31 32
33struct nphy_txgains {
34 u16 txgm[2];
35 u16 pga[2];
36 u16 pad[2];
37 u16 ipa[2];
38};
39
40struct nphy_iqcal_params {
41 u16 txgm;
42 u16 pga;
43 u16 pad;
44 u16 ipa;
45 u16 cal_gain;
46 u16 ncorr[5];
47};
48
49struct nphy_iq_est {
50 s32 iq0_prod;
51 u32 i0_pwr;
52 u32 q0_pwr;
53 s32 iq1_prod;
54 u32 i1_pwr;
55 u32 q1_pwr;
56};
32 57
33void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna) 58void b43_nphy_set_rxantenna(struct b43_wldev *dev, int antenna)
34{//TODO 59{//TODO
@@ -197,44 +222,16 @@ void b43_nphy_radio_turn_off(struct b43_wldev *dev)
197 ~B43_NPHY_RFCTL_CMD_EN); 222 ~B43_NPHY_RFCTL_CMD_EN);
198} 223}
199 224
200#define ntab_upload(dev, offset, data) do { \ 225/*
201 unsigned int i; \ 226 * Upload the N-PHY tables.
202 for (i = 0; i < (offset##_SIZE); i++) \ 227 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/InitTables
203 b43_ntab_write(dev, (offset) + i, (data)[i]); \ 228 */
204 } while (0)
205
206/* Upload the N-PHY tables. */
207static void b43_nphy_tables_init(struct b43_wldev *dev) 229static void b43_nphy_tables_init(struct b43_wldev *dev)
208{ 230{
209 /* Static tables */ 231 if (dev->phy.rev < 3)
210 ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct); 232 b43_nphy_rev0_1_2_tables_init(dev);
211 ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup); 233 else
212 ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap); 234 b43_nphy_rev3plus_tables_init(dev);
213 ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
214 ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
215 ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
216 ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
217 ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
218 ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
219 ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
220 ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
221 ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
222 ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
223 ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
224
225 /* Volatile tables */
226 ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
227 ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
228 ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
229 ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
230 ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
231 ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
232 ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
233 ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
234 ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
235 ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
236 ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
237 ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
238} 235}
239 236
240static void b43_nphy_workarounds(struct b43_wldev *dev) 237static void b43_nphy_workarounds(struct b43_wldev *dev)
@@ -341,18 +338,386 @@ static void b43_nphy_workarounds(struct b43_wldev *dev)
341 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20); 338 b43_phy_write(dev, B43_NPHY_PHASETR_B2, 0x20);
342} 339}
343 340
341/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PA%20override */
342static void b43_nphy_pa_override(struct b43_wldev *dev, bool enable)
343{
344 struct b43_phy_n *nphy = dev->phy.n;
345 enum ieee80211_band band;
346 u16 tmp;
347
348 if (!enable) {
349 nphy->rfctrl_intc1_save = b43_phy_read(dev,
350 B43_NPHY_RFCTL_INTC1);
351 nphy->rfctrl_intc2_save = b43_phy_read(dev,
352 B43_NPHY_RFCTL_INTC2);
353 band = b43_current_band(dev->wl);
354 if (dev->phy.rev >= 3) {
355 if (band == IEEE80211_BAND_5GHZ)
356 tmp = 0x600;
357 else
358 tmp = 0x480;
359 } else {
360 if (band == IEEE80211_BAND_5GHZ)
361 tmp = 0x180;
362 else
363 tmp = 0x120;
364 }
365 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, tmp);
366 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, tmp);
367 } else {
368 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1,
369 nphy->rfctrl_intc1_save);
370 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2,
371 nphy->rfctrl_intc2_save);
372 }
373}
374
375/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxLpFbw */
376static void b43_nphy_tx_lp_fbw(struct b43_wldev *dev)
377{
378 struct b43_phy_n *nphy = dev->phy.n;
379 u16 tmp;
380 enum ieee80211_band band = b43_current_band(dev->wl);
381 bool ipa = (nphy->ipa2g_on && band == IEEE80211_BAND_2GHZ) ||
382 (nphy->ipa5g_on && band == IEEE80211_BAND_5GHZ);
383
384 if (dev->phy.rev >= 3) {
385 if (ipa) {
386 tmp = 4;
387 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S2,
388 (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
389 }
390
391 tmp = 1;
392 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S2,
393 (((((tmp << 3) | tmp) << 3) | tmp) << 3) | tmp);
394 }
395}
396
397/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/BmacPhyClkFgc */
398static void b43_nphy_bmac_clock_fgc(struct b43_wldev *dev, bool force)
399{
400 u32 tmslow;
401
402 if (dev->phy.type != B43_PHYTYPE_N)
403 return;
404
405 tmslow = ssb_read32(dev->dev, SSB_TMSLOW);
406 if (force)
407 tmslow |= SSB_TMSLOW_FGC;
408 else
409 tmslow &= ~SSB_TMSLOW_FGC;
410 ssb_write32(dev->dev, SSB_TMSLOW, tmslow);
411}
412
413/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CCA */
344static void b43_nphy_reset_cca(struct b43_wldev *dev) 414static void b43_nphy_reset_cca(struct b43_wldev *dev)
345{ 415{
346 u16 bbcfg; 416 u16 bbcfg;
347 417
348 ssb_write32(dev->dev, SSB_TMSLOW, 418 b43_nphy_bmac_clock_fgc(dev, 1);
349 ssb_read32(dev->dev, SSB_TMSLOW) | SSB_TMSLOW_FGC);
350 bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG); 419 bbcfg = b43_phy_read(dev, B43_NPHY_BBCFG);
351 b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTCCA); 420 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg | B43_NPHY_BBCFG_RSTCCA);
352 b43_phy_write(dev, B43_NPHY_BBCFG, 421 udelay(1);
353 bbcfg & ~B43_NPHY_BBCFG_RSTCCA); 422 b43_phy_write(dev, B43_NPHY_BBCFG, bbcfg & ~B43_NPHY_BBCFG_RSTCCA);
354 ssb_write32(dev->dev, SSB_TMSLOW, 423 b43_nphy_bmac_clock_fgc(dev, 0);
355 ssb_read32(dev->dev, SSB_TMSLOW) & ~SSB_TMSLOW_FGC); 424 /* TODO: N PHY Force RF Seq with argument 2 */
425}
426
427/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqEst */
428static void b43_nphy_rx_iq_est(struct b43_wldev *dev, struct nphy_iq_est *est,
429 u16 samps, u8 time, bool wait)
430{
431 int i;
432 u16 tmp;
433
434 b43_phy_write(dev, B43_NPHY_IQEST_SAMCNT, samps);
435 b43_phy_maskset(dev, B43_NPHY_IQEST_WT, ~B43_NPHY_IQEST_WT_VAL, time);
436 if (wait)
437 b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_MODE);
438 else
439 b43_phy_mask(dev, B43_NPHY_IQEST_CMD, ~B43_NPHY_IQEST_CMD_MODE);
440
441 b43_phy_set(dev, B43_NPHY_IQEST_CMD, B43_NPHY_IQEST_CMD_START);
442
443 for (i = 1000; i; i--) {
444 tmp = b43_phy_read(dev, B43_NPHY_IQEST_CMD);
445 if (!(tmp & B43_NPHY_IQEST_CMD_START)) {
446 est->i0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI0) << 16) |
447 b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO0);
448 est->q0_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI0) << 16) |
449 b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO0);
450 est->iq0_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI0) << 16) |
451 b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO0);
452
453 est->i1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_IPACC_HI1) << 16) |
454 b43_phy_read(dev, B43_NPHY_IQEST_IPACC_LO1);
455 est->q1_pwr = (b43_phy_read(dev, B43_NPHY_IQEST_QPACC_HI1) << 16) |
456 b43_phy_read(dev, B43_NPHY_IQEST_QPACC_LO1);
457 est->iq1_prod = (b43_phy_read(dev, B43_NPHY_IQEST_IQACC_HI1) << 16) |
458 b43_phy_read(dev, B43_NPHY_IQEST_IQACC_LO1);
459 return;
460 }
461 udelay(10);
462 }
463 memset(est, 0, sizeof(*est));
464}
465
466/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RxIqCoeffs */
467static void b43_nphy_rx_iq_coeffs(struct b43_wldev *dev, bool write,
468 struct b43_phy_n_iq_comp *pcomp)
469{
470 if (write) {
471 b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPA0, pcomp->a0);
472 b43_phy_write(dev, B43_NPHY_C1_RXIQ_COMPB0, pcomp->b0);
473 b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPA1, pcomp->a1);
474 b43_phy_write(dev, B43_NPHY_C2_RXIQ_COMPB1, pcomp->b1);
475 } else {
476 pcomp->a0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPA0);
477 pcomp->b0 = b43_phy_read(dev, B43_NPHY_C1_RXIQ_COMPB0);
478 pcomp->a1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPA1);
479 pcomp->b1 = b43_phy_read(dev, B43_NPHY_C2_RXIQ_COMPB1);
480 }
481}
482
483/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalcRxIqComp */
484static void b43_nphy_calc_rx_iq_comp(struct b43_wldev *dev, u8 mask)
485{
486 int i;
487 s32 iq;
488 u32 ii;
489 u32 qq;
490 int iq_nbits, qq_nbits;
491 int arsh, brsh;
492 u16 tmp, a, b;
493
494 struct nphy_iq_est est;
495 struct b43_phy_n_iq_comp old;
496 struct b43_phy_n_iq_comp new = { };
497 bool error = false;
498
499 if (mask == 0)
500 return;
501
502 b43_nphy_rx_iq_coeffs(dev, false, &old);
503 b43_nphy_rx_iq_coeffs(dev, true, &new);
504 b43_nphy_rx_iq_est(dev, &est, 0x4000, 32, false);
505 new = old;
506
507 for (i = 0; i < 2; i++) {
508 if (i == 0 && (mask & 1)) {
509 iq = est.iq0_prod;
510 ii = est.i0_pwr;
511 qq = est.q0_pwr;
512 } else if (i == 1 && (mask & 2)) {
513 iq = est.iq1_prod;
514 ii = est.i1_pwr;
515 qq = est.q1_pwr;
516 } else {
517 B43_WARN_ON(1);
518 continue;
519 }
520
521 if (ii + qq < 2) {
522 error = true;
523 break;
524 }
525
526 iq_nbits = fls(abs(iq));
527 qq_nbits = fls(qq);
528
529 arsh = iq_nbits - 20;
530 if (arsh >= 0) {
531 a = -((iq << (30 - iq_nbits)) + (ii >> (1 + arsh)));
532 tmp = ii >> arsh;
533 } else {
534 a = -((iq << (30 - iq_nbits)) + (ii << (-1 - arsh)));
535 tmp = ii << -arsh;
536 }
537 if (tmp == 0) {
538 error = true;
539 break;
540 }
541 a /= tmp;
542
543 brsh = qq_nbits - 11;
544 if (brsh >= 0) {
545 b = (qq << (31 - qq_nbits));
546 tmp = ii >> brsh;
547 } else {
548 b = (qq << (31 - qq_nbits));
549 tmp = ii << -brsh;
550 }
551 if (tmp == 0) {
552 error = true;
553 break;
554 }
555 b = int_sqrt(b / tmp - a * a) - (1 << 10);
556
557 if (i == 0 && (mask & 0x1)) {
558 if (dev->phy.rev >= 3) {
559 new.a0 = a & 0x3FF;
560 new.b0 = b & 0x3FF;
561 } else {
562 new.a0 = b & 0x3FF;
563 new.b0 = a & 0x3FF;
564 }
565 } else if (i == 1 && (mask & 0x2)) {
566 if (dev->phy.rev >= 3) {
567 new.a1 = a & 0x3FF;
568 new.b1 = b & 0x3FF;
569 } else {
570 new.a1 = b & 0x3FF;
571 new.b1 = a & 0x3FF;
572 }
573 }
574 }
575
576 if (error)
577 new = old;
578
579 b43_nphy_rx_iq_coeffs(dev, true, &new);
580}
581
582/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxIqWar */
583static void b43_nphy_tx_iq_workaround(struct b43_wldev *dev)
584{
585 u16 array[4];
586 int i;
587
588 b43_phy_write(dev, B43_NPHY_TABLE_ADDR, 0x3C50);
589 for (i = 0; i < 4; i++)
590 array[i] = b43_phy_read(dev, B43_NPHY_TABLE_DATALO);
591
592 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW0, array[0]);
593 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW1, array[1]);
594 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW2, array[2]);
595 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_NPHY_TXIQW3, array[3]);
596}
597
598/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
599static void b43_nphy_write_clip_detection(struct b43_wldev *dev, u16 *clip_st)
600{
601 b43_phy_write(dev, B43_NPHY_C1_CLIP1THRES, clip_st[0]);
602 b43_phy_write(dev, B43_NPHY_C2_CLIP1THRES, clip_st[1]);
603}
604
605/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/clip-detection */
606static void b43_nphy_read_clip_detection(struct b43_wldev *dev, u16 *clip_st)
607{
608 clip_st[0] = b43_phy_read(dev, B43_NPHY_C1_CLIP1THRES);
609 clip_st[1] = b43_phy_read(dev, B43_NPHY_C2_CLIP1THRES);
610}
611
612/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/classifier */
613static u16 b43_nphy_classifier(struct b43_wldev *dev, u16 mask, u16 val)
614{
615 u16 tmp;
616
617 if (dev->dev->id.revision == 16)
618 b43_mac_suspend(dev);
619
620 tmp = b43_phy_read(dev, B43_NPHY_CLASSCTL);
621 tmp &= (B43_NPHY_CLASSCTL_CCKEN | B43_NPHY_CLASSCTL_OFDMEN |
622 B43_NPHY_CLASSCTL_WAITEDEN);
623 tmp &= ~mask;
624 tmp |= (val & mask);
625 b43_phy_maskset(dev, B43_NPHY_CLASSCTL, 0xFFF8, tmp);
626
627 if (dev->dev->id.revision == 16)
628 b43_mac_enable(dev);
629
630 return tmp;
631}
632
633/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/carriersearch */
634static void b43_nphy_stay_in_carrier_search(struct b43_wldev *dev, bool enable)
635{
636 struct b43_phy *phy = &dev->phy;
637 struct b43_phy_n *nphy = phy->n;
638
639 if (enable) {
640 u16 clip[] = { 0xFFFF, 0xFFFF };
641 if (nphy->deaf_count++ == 0) {
642 nphy->classifier_state = b43_nphy_classifier(dev, 0, 0);
643 b43_nphy_classifier(dev, 0x7, 0);
644 b43_nphy_read_clip_detection(dev, nphy->clip_state);
645 b43_nphy_write_clip_detection(dev, clip);
646 }
647 b43_nphy_reset_cca(dev);
648 } else {
649 if (--nphy->deaf_count == 0) {
650 b43_nphy_classifier(dev, 0x7, nphy->classifier_state);
651 b43_nphy_write_clip_detection(dev, nphy->clip_state);
652 }
653 }
654}
655
656/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxPwrCtrlCoefSetup */
657static void b43_nphy_tx_pwr_ctrl_coef_setup(struct b43_wldev *dev)
658{
659 struct b43_phy_n *nphy = dev->phy.n;
660 int i, j;
661 u32 tmp;
662 u32 cur_real, cur_imag, real_part, imag_part;
663
664 u16 buffer[7];
665
666 if (nphy->hang_avoid)
667 b43_nphy_stay_in_carrier_search(dev, true);
668
669 /* TODO: Read an N PHY Table with ID 15, length 7, offset 80,
670 width 16, and data pointer buffer */
671
672 for (i = 0; i < 2; i++) {
673 tmp = ((buffer[i * 2] & 0x3FF) << 10) |
674 (buffer[i * 2 + 1] & 0x3FF);
675 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
676 (((i + 26) << 10) | 320));
677 for (j = 0; j < 128; j++) {
678 b43_phy_write(dev, B43_NPHY_TABLE_DATAHI,
679 ((tmp >> 16) & 0xFFFF));
680 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
681 (tmp & 0xFFFF));
682 }
683 }
684
685 for (i = 0; i < 2; i++) {
686 tmp = buffer[5 + i];
687 real_part = (tmp >> 8) & 0xFF;
688 imag_part = (tmp & 0xFF);
689 b43_phy_write(dev, B43_NPHY_TABLE_ADDR,
690 (((i + 26) << 10) | 448));
691
692 if (dev->phy.rev >= 3) {
693 cur_real = real_part;
694 cur_imag = imag_part;
695 tmp = ((cur_real & 0xFF) << 8) | (cur_imag & 0xFF);
696 }
697
698 for (j = 0; j < 128; j++) {
699 if (dev->phy.rev < 3) {
700 cur_real = (real_part * loscale[j] + 128) >> 8;
701 cur_imag = (imag_part * loscale[j] + 128) >> 8;
702 tmp = ((cur_real & 0xFF) << 8) |
703 (cur_imag & 0xFF);
704 }
705 b43_phy_write(dev, B43_NPHY_TABLE_DATAHI,
706 ((tmp >> 16) & 0xFFFF));
707 b43_phy_write(dev, B43_NPHY_TABLE_DATALO,
708 (tmp & 0xFFFF));
709 }
710 }
711
712 if (dev->phy.rev >= 3) {
713 b43_shm_write16(dev, B43_SHM_SHARED,
714 B43_SHM_SH_NPHY_TXPWR_INDX0, 0xFFFF);
715 b43_shm_write16(dev, B43_SHM_SHARED,
716 B43_SHM_SH_NPHY_TXPWR_INDX1, 0xFFFF);
717 }
718
719 if (nphy->hang_avoid)
720 b43_nphy_stay_in_carrier_search(dev, false);
356} 721}
357 722
358enum b43_nphy_rf_sequence { 723enum b43_nphy_rf_sequence {
@@ -411,81 +776,1339 @@ static void b43_nphy_bphy_init(struct b43_wldev *dev)
411 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); 776 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
412} 777}
413 778
414/* RSSI Calibration */ 779/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/ScaleOffsetRssi */
415static void b43_nphy_rssi_cal(struct b43_wldev *dev, u8 type) 780static void b43_nphy_scale_offset_rssi(struct b43_wldev *dev, u16 scale,
781 s8 offset, u8 core, u8 rail, u8 type)
416{ 782{
417 //TODO 783 u16 tmp;
784 bool core1or5 = (core == 1) || (core == 5);
785 bool core2or5 = (core == 2) || (core == 5);
786
787 offset = clamp_val(offset, -32, 31);
788 tmp = ((scale & 0x3F) << 8) | (offset & 0x3F);
789
790 if (core1or5 && (rail == 0) && (type == 2))
791 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, tmp);
792 if (core1or5 && (rail == 1) && (type == 2))
793 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, tmp);
794 if (core2or5 && (rail == 0) && (type == 2))
795 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, tmp);
796 if (core2or5 && (rail == 1) && (type == 2))
797 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, tmp);
798 if (core1or5 && (rail == 0) && (type == 0))
799 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, tmp);
800 if (core1or5 && (rail == 1) && (type == 0))
801 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, tmp);
802 if (core2or5 && (rail == 0) && (type == 0))
803 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, tmp);
804 if (core2or5 && (rail == 1) && (type == 0))
805 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, tmp);
806 if (core1or5 && (rail == 0) && (type == 1))
807 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, tmp);
808 if (core1or5 && (rail == 1) && (type == 1))
809 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, tmp);
810 if (core2or5 && (rail == 0) && (type == 1))
811 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, tmp);
812 if (core2or5 && (rail == 1) && (type == 1))
813 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, tmp);
814 if (core1or5 && (rail == 0) && (type == 6))
815 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TBD, tmp);
816 if (core1or5 && (rail == 1) && (type == 6))
817 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TBD, tmp);
818 if (core2or5 && (rail == 0) && (type == 6))
819 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TBD, tmp);
820 if (core2or5 && (rail == 1) && (type == 6))
821 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TBD, tmp);
822 if (core1or5 && (rail == 0) && (type == 3))
823 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_PWRDET, tmp);
824 if (core1or5 && (rail == 1) && (type == 3))
825 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_PWRDET, tmp);
826 if (core2or5 && (rail == 0) && (type == 3))
827 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_PWRDET, tmp);
828 if (core2or5 && (rail == 1) && (type == 3))
829 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_PWRDET, tmp);
830 if (core1or5 && (type == 4))
831 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_TSSI, tmp);
832 if (core2or5 && (type == 4))
833 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_TSSI, tmp);
834 if (core1or5 && (type == 5))
835 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_TSSI, tmp);
836 if (core2or5 && (type == 5))
837 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_TSSI, tmp);
838}
839
840/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSISel */
841static void b43_nphy_rssi_select(struct b43_wldev *dev, u8 code, u8 type)
842{
843 u16 val;
844
845 if (dev->phy.rev >= 3) {
846 /* TODO */
847 } else {
848 if (type < 3)
849 val = 0;
850 else if (type == 6)
851 val = 1;
852 else if (type == 3)
853 val = 2;
854 else
855 val = 3;
856
857 val = (val << 12) | (val << 14);
858 b43_phy_maskset(dev, B43_NPHY_AFECTL_C1, 0x0FFF, val);
859 b43_phy_maskset(dev, B43_NPHY_AFECTL_C2, 0x0FFF, val);
860
861 if (type < 3) {
862 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO1, 0xFFCF,
863 (type + 1) << 4);
864 b43_phy_maskset(dev, B43_NPHY_RFCTL_RSSIO2, 0xFFCF,
865 (type + 1) << 4);
866 }
867
868 /* TODO use some definitions */
869 if (code == 0) {
870 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF, 0);
871 if (type < 3) {
872 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
873 0xFEC7, 0);
874 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
875 0xEFDC, 0);
876 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
877 0xFFFE, 0);
878 udelay(20);
879 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
880 0xFFFE, 0);
881 }
882 } else {
883 b43_phy_maskset(dev, B43_NPHY_AFECTL_OVER, 0xCFFF,
884 0x3000);
885 if (type < 3) {
886 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
887 0xFEC7, 0x0180);
888 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
889 0xEFDC, (code << 1 | 0x1021));
890 b43_phy_maskset(dev, B43_NPHY_RFCTL_CMD,
891 0xFFFE, 0x0001);
892 udelay(20);
893 b43_phy_maskset(dev, B43_NPHY_RFCTL_OVER,
894 0xFFFE, 0);
895 }
896 }
897 }
898}
899
900/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/SetRssi2055Vcm */
901static void b43_nphy_set_rssi_2055_vcm(struct b43_wldev *dev, u8 type, u8 *buf)
902{
903 int i;
904 for (i = 0; i < 2; i++) {
905 if (type == 2) {
906 if (i == 0) {
907 b43_radio_maskset(dev, B2055_C1_B0NB_RSSIVCM,
908 0xFC, buf[0]);
909 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
910 0xFC, buf[1]);
911 } else {
912 b43_radio_maskset(dev, B2055_C2_B0NB_RSSIVCM,
913 0xFC, buf[2 * i]);
914 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
915 0xFC, buf[2 * i + 1]);
916 }
917 } else {
918 if (i == 0)
919 b43_radio_maskset(dev, B2055_C1_RX_BB_RSSICTL5,
920 0xF3, buf[0] << 2);
921 else
922 b43_radio_maskset(dev, B2055_C2_RX_BB_RSSICTL5,
923 0xF3, buf[2 * i + 1] << 2);
924 }
925 }
926}
927
928/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/PollRssi */
929static int b43_nphy_poll_rssi(struct b43_wldev *dev, u8 type, s32 *buf,
930 u8 nsamp)
931{
932 int i;
933 int out;
934 u16 save_regs_phy[9];
935 u16 s[2];
936
937 if (dev->phy.rev >= 3) {
938 save_regs_phy[0] = b43_phy_read(dev,
939 B43_NPHY_RFCTL_LUT_TRSW_UP1);
940 save_regs_phy[1] = b43_phy_read(dev,
941 B43_NPHY_RFCTL_LUT_TRSW_UP2);
942 save_regs_phy[2] = b43_phy_read(dev, B43_NPHY_AFECTL_C1);
943 save_regs_phy[3] = b43_phy_read(dev, B43_NPHY_AFECTL_C2);
944 save_regs_phy[4] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER1);
945 save_regs_phy[5] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
946 save_regs_phy[6] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B1S0);
947 save_regs_phy[7] = b43_phy_read(dev, B43_NPHY_TXF_40CO_B32S1);
948 }
949
950 b43_nphy_rssi_select(dev, 5, type);
951
952 if (dev->phy.rev < 2) {
953 save_regs_phy[8] = b43_phy_read(dev, B43_NPHY_GPIO_SEL);
954 b43_phy_write(dev, B43_NPHY_GPIO_SEL, 5);
955 }
956
957 for (i = 0; i < 4; i++)
958 buf[i] = 0;
959
960 for (i = 0; i < nsamp; i++) {
961 if (dev->phy.rev < 2) {
962 s[0] = b43_phy_read(dev, B43_NPHY_GPIO_LOOUT);
963 s[1] = b43_phy_read(dev, B43_NPHY_GPIO_HIOUT);
964 } else {
965 s[0] = b43_phy_read(dev, B43_NPHY_RSSI1);
966 s[1] = b43_phy_read(dev, B43_NPHY_RSSI2);
967 }
968
969 buf[0] += ((s8)((s[0] & 0x3F) << 2)) >> 2;
970 buf[1] += ((s8)(((s[0] >> 8) & 0x3F) << 2)) >> 2;
971 buf[2] += ((s8)((s[1] & 0x3F) << 2)) >> 2;
972 buf[3] += ((s8)(((s[1] >> 8) & 0x3F) << 2)) >> 2;
973 }
974 out = (buf[0] & 0xFF) << 24 | (buf[1] & 0xFF) << 16 |
975 (buf[2] & 0xFF) << 8 | (buf[3] & 0xFF);
976
977 if (dev->phy.rev < 2)
978 b43_phy_write(dev, B43_NPHY_GPIO_SEL, save_regs_phy[8]);
979
980 if (dev->phy.rev >= 3) {
981 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP1,
982 save_regs_phy[0]);
983 b43_phy_write(dev, B43_NPHY_RFCTL_LUT_TRSW_UP2,
984 save_regs_phy[1]);
985 b43_phy_write(dev, B43_NPHY_AFECTL_C1, save_regs_phy[2]);
986 b43_phy_write(dev, B43_NPHY_AFECTL_C2, save_regs_phy[3]);
987 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, save_regs_phy[4]);
988 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, save_regs_phy[5]);
989 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, save_regs_phy[6]);
990 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, save_regs_phy[7]);
991 }
992
993 return out;
994}
995
996/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal */
997static void b43_nphy_rev2_rssi_cal(struct b43_wldev *dev, u8 type)
998{
999 int i, j;
1000 u8 state[4];
1001 u8 code, val;
1002 u16 class, override;
1003 u8 regs_save_radio[2];
1004 u16 regs_save_phy[2];
1005 s8 offset[4];
1006
1007 u16 clip_state[2];
1008 u16 clip_off[2] = { 0xFFFF, 0xFFFF };
1009 s32 results_min[4] = { };
1010 u8 vcm_final[4] = { };
1011 s32 results[4][4] = { };
1012 s32 miniq[4][2] = { };
1013
1014 if (type == 2) {
1015 code = 0;
1016 val = 6;
1017 } else if (type < 2) {
1018 code = 25;
1019 val = 4;
1020 } else {
1021 B43_WARN_ON(1);
1022 return;
1023 }
1024
1025 class = b43_nphy_classifier(dev, 0, 0);
1026 b43_nphy_classifier(dev, 7, 4);
1027 b43_nphy_read_clip_detection(dev, clip_state);
1028 b43_nphy_write_clip_detection(dev, clip_off);
1029
1030 if (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ)
1031 override = 0x140;
1032 else
1033 override = 0x110;
1034
1035 regs_save_phy[0] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC1);
1036 regs_save_radio[0] = b43_radio_read16(dev, B2055_C1_PD_RXTX);
1037 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, override);
1038 b43_radio_write16(dev, B2055_C1_PD_RXTX, val);
1039
1040 regs_save_phy[1] = b43_phy_read(dev, B43_NPHY_RFCTL_INTC2);
1041 regs_save_radio[1] = b43_radio_read16(dev, B2055_C2_PD_RXTX);
1042 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, override);
1043 b43_radio_write16(dev, B2055_C2_PD_RXTX, val);
1044
1045 state[0] = b43_radio_read16(dev, B2055_C1_PD_RSSIMISC) & 0x07;
1046 state[1] = b43_radio_read16(dev, B2055_C2_PD_RSSIMISC) & 0x07;
1047 b43_radio_mask(dev, B2055_C1_PD_RSSIMISC, 0xF8);
1048 b43_radio_mask(dev, B2055_C2_PD_RSSIMISC, 0xF8);
1049 state[2] = b43_radio_read16(dev, B2055_C1_SP_RSSI) & 0x07;
1050 state[3] = b43_radio_read16(dev, B2055_C2_SP_RSSI) & 0x07;
1051
1052 b43_nphy_rssi_select(dev, 5, type);
1053 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 0, type);
1054 b43_nphy_scale_offset_rssi(dev, 0, 0, 5, 1, type);
1055
1056 for (i = 0; i < 4; i++) {
1057 u8 tmp[4];
1058 for (j = 0; j < 4; j++)
1059 tmp[j] = i;
1060 if (type != 1)
1061 b43_nphy_set_rssi_2055_vcm(dev, type, tmp);
1062 b43_nphy_poll_rssi(dev, type, results[i], 8);
1063 if (type < 2)
1064 for (j = 0; j < 2; j++)
1065 miniq[i][j] = min(results[i][2 * j],
1066 results[i][2 * j + 1]);
1067 }
1068
1069 for (i = 0; i < 4; i++) {
1070 s32 mind = 40;
1071 u8 minvcm = 0;
1072 s32 minpoll = 249;
1073 s32 curr;
1074 for (j = 0; j < 4; j++) {
1075 if (type == 2)
1076 curr = abs(results[j][i]);
1077 else
1078 curr = abs(miniq[j][i / 2] - code * 8);
1079
1080 if (curr < mind) {
1081 mind = curr;
1082 minvcm = j;
1083 }
1084
1085 if (results[j][i] < minpoll)
1086 minpoll = results[j][i];
1087 }
1088 results_min[i] = minpoll;
1089 vcm_final[i] = minvcm;
1090 }
1091
1092 if (type != 1)
1093 b43_nphy_set_rssi_2055_vcm(dev, type, vcm_final);
1094
1095 for (i = 0; i < 4; i++) {
1096 offset[i] = (code * 8) - results[vcm_final[i]][i];
1097
1098 if (offset[i] < 0)
1099 offset[i] = -((abs(offset[i]) + 4) / 8);
1100 else
1101 offset[i] = (offset[i] + 4) / 8;
1102
1103 if (results_min[i] == 248)
1104 offset[i] = code - 32;
1105
1106 if (i % 2 == 0)
1107 b43_nphy_scale_offset_rssi(dev, 0, offset[i], 1, 0,
1108 type);
1109 else
1110 b43_nphy_scale_offset_rssi(dev, 0, offset[i], 2, 1,
1111 type);
1112 }
1113
1114 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[0]);
1115 b43_radio_maskset(dev, B2055_C1_PD_RSSIMISC, 0xF8, state[1]);
1116
1117 switch (state[2]) {
1118 case 1:
1119 b43_nphy_rssi_select(dev, 1, 2);
1120 break;
1121 case 4:
1122 b43_nphy_rssi_select(dev, 1, 0);
1123 break;
1124 case 2:
1125 b43_nphy_rssi_select(dev, 1, 1);
1126 break;
1127 default:
1128 b43_nphy_rssi_select(dev, 1, 1);
1129 break;
1130 }
1131
1132 switch (state[3]) {
1133 case 1:
1134 b43_nphy_rssi_select(dev, 2, 2);
1135 break;
1136 case 4:
1137 b43_nphy_rssi_select(dev, 2, 0);
1138 break;
1139 default:
1140 b43_nphy_rssi_select(dev, 2, 1);
1141 break;
1142 }
1143
1144 b43_nphy_rssi_select(dev, 0, type);
1145
1146 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, regs_save_phy[0]);
1147 b43_radio_write16(dev, B2055_C1_PD_RXTX, regs_save_radio[0]);
1148 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, regs_save_phy[1]);
1149 b43_radio_write16(dev, B2055_C2_PD_RXTX, regs_save_radio[1]);
1150
1151 b43_nphy_classifier(dev, 7, class);
1152 b43_nphy_write_clip_detection(dev, clip_state);
1153}
1154
1155/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICalRev3 */
1156static void b43_nphy_rev3_rssi_cal(struct b43_wldev *dev)
1157{
1158 /* TODO */
1159}
1160
1161/*
1162 * RSSI Calibration
1163 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RSSICal
1164 */
1165static void b43_nphy_rssi_cal(struct b43_wldev *dev)
1166{
1167 if (dev->phy.rev >= 3) {
1168 b43_nphy_rev3_rssi_cal(dev);
1169 } else {
1170 b43_nphy_rev2_rssi_cal(dev, 2);
1171 b43_nphy_rev2_rssi_cal(dev, 0);
1172 b43_nphy_rev2_rssi_cal(dev, 1);
1173 }
1174}
1175
1176/*
1177 * Restore RSSI Calibration
1178 * http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreRssiCal
1179 */
1180static void b43_nphy_restore_rssi_cal(struct b43_wldev *dev)
1181{
1182 struct b43_phy_n *nphy = dev->phy.n;
1183
1184 u16 *rssical_radio_regs = NULL;
1185 u16 *rssical_phy_regs = NULL;
1186
1187 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1188 if (!nphy->rssical_chanspec_2G)
1189 return;
1190 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_2G;
1191 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_2G;
1192 } else {
1193 if (!nphy->rssical_chanspec_5G)
1194 return;
1195 rssical_radio_regs = nphy->rssical_cache.rssical_radio_regs_5G;
1196 rssical_phy_regs = nphy->rssical_cache.rssical_phy_regs_5G;
1197 }
1198
1199 /* TODO use some definitions */
1200 b43_radio_maskset(dev, 0x602B, 0xE3, rssical_radio_regs[0]);
1201 b43_radio_maskset(dev, 0x702B, 0xE3, rssical_radio_regs[1]);
1202
1203 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Z, rssical_phy_regs[0]);
1204 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Z, rssical_phy_regs[1]);
1205 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Z, rssical_phy_regs[2]);
1206 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Z, rssical_phy_regs[3]);
1207
1208 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_X, rssical_phy_regs[4]);
1209 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_X, rssical_phy_regs[5]);
1210 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_X, rssical_phy_regs[6]);
1211 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_X, rssical_phy_regs[7]);
1212
1213 b43_phy_write(dev, B43_NPHY_RSSIMC_0I_RSSI_Y, rssical_phy_regs[8]);
1214 b43_phy_write(dev, B43_NPHY_RSSIMC_0Q_RSSI_Y, rssical_phy_regs[9]);
1215 b43_phy_write(dev, B43_NPHY_RSSIMC_1I_RSSI_Y, rssical_phy_regs[10]);
1216 b43_phy_write(dev, B43_NPHY_RSSIMC_1Q_RSSI_Y, rssical_phy_regs[11]);
1217}
1218
1219/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetIpaGainTbl */
1220static const u32 *b43_nphy_get_ipa_gain_table(struct b43_wldev *dev)
1221{
1222 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1223 if (dev->phy.rev >= 6) {
1224 /* TODO If the chip is 47162
1225 return txpwrctrl_tx_gain_ipa_rev5 */
1226 return txpwrctrl_tx_gain_ipa_rev6;
1227 } else if (dev->phy.rev >= 5) {
1228 return txpwrctrl_tx_gain_ipa_rev5;
1229 } else {
1230 return txpwrctrl_tx_gain_ipa;
1231 }
1232 } else {
1233 return txpwrctrl_tx_gain_ipa_5g;
1234 }
1235}
1236
1237/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/TxCalRadioSetup */
1238static void b43_nphy_tx_cal_radio_setup(struct b43_wldev *dev)
1239{
1240 struct b43_phy_n *nphy = dev->phy.n;
1241 u16 *save = nphy->tx_rx_cal_radio_saveregs;
1242
1243 if (dev->phy.rev >= 3) {
1244 /* TODO */
1245 } else {
1246 save[0] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL1);
1247 b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL1, 0x29);
1248
1249 save[1] = b43_radio_read16(dev, B2055_C1_TX_RF_IQCAL2);
1250 b43_radio_write16(dev, B2055_C1_TX_RF_IQCAL2, 0x54);
1251
1252 save[2] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL1);
1253 b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL1, 0x29);
1254
1255 save[3] = b43_radio_read16(dev, B2055_C2_TX_RF_IQCAL2);
1256 b43_radio_write16(dev, B2055_C2_TX_RF_IQCAL2, 0x54);
1257
1258 save[3] = b43_radio_read16(dev, B2055_C1_PWRDET_RXTX);
1259 save[4] = b43_radio_read16(dev, B2055_C2_PWRDET_RXTX);
1260
1261 if (!(b43_phy_read(dev, B43_NPHY_BANDCTL) &
1262 B43_NPHY_BANDCTL_5GHZ)) {
1263 b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x04);
1264 b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x04);
1265 } else {
1266 b43_radio_write16(dev, B2055_C1_PWRDET_RXTX, 0x20);
1267 b43_radio_write16(dev, B2055_C2_PWRDET_RXTX, 0x20);
1268 }
1269
1270 if (dev->phy.rev < 2) {
1271 b43_radio_set(dev, B2055_C1_TX_BB_MXGM, 0x20);
1272 b43_radio_set(dev, B2055_C2_TX_BB_MXGM, 0x20);
1273 } else {
1274 b43_radio_mask(dev, B2055_C1_TX_BB_MXGM, ~0x20);
1275 b43_radio_mask(dev, B2055_C2_TX_BB_MXGM, ~0x20);
1276 }
1277 }
1278}
1279
1280/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/IqCalGainParams */
1281static void b43_nphy_iq_cal_gain_params(struct b43_wldev *dev, u16 core,
1282 struct nphy_txgains target,
1283 struct nphy_iqcal_params *params)
1284{
1285 int i, j, indx;
1286 u16 gain;
1287
1288 if (dev->phy.rev >= 3) {
1289 params->txgm = target.txgm[core];
1290 params->pga = target.pga[core];
1291 params->pad = target.pad[core];
1292 params->ipa = target.ipa[core];
1293 params->cal_gain = (params->txgm << 12) | (params->pga << 8) |
1294 (params->pad << 4) | (params->ipa);
1295 for (j = 0; j < 5; j++)
1296 params->ncorr[j] = 0x79;
1297 } else {
1298 gain = (target.pad[core]) | (target.pga[core] << 4) |
1299 (target.txgm[core] << 8);
1300
1301 indx = (b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) ?
1302 1 : 0;
1303 for (i = 0; i < 9; i++)
1304 if (tbl_iqcal_gainparams[indx][i][0] == gain)
1305 break;
1306 i = min(i, 8);
1307
1308 params->txgm = tbl_iqcal_gainparams[indx][i][1];
1309 params->pga = tbl_iqcal_gainparams[indx][i][2];
1310 params->pad = tbl_iqcal_gainparams[indx][i][3];
1311 params->cal_gain = (params->txgm << 7) | (params->pga << 4) |
1312 (params->pad << 2);
1313 for (j = 0; j < 4; j++)
1314 params->ncorr[j] = tbl_iqcal_gainparams[indx][i][4 + j];
1315 }
1316}
1317
1318/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/UpdateTxCalLadder */
1319static void b43_nphy_update_tx_cal_ladder(struct b43_wldev *dev, u16 core)
1320{
1321 struct b43_phy_n *nphy = dev->phy.n;
1322 int i;
1323 u16 scale, entry;
1324
1325 u16 tmp = nphy->txcal_bbmult;
1326 if (core == 0)
1327 tmp >>= 8;
1328 tmp &= 0xff;
1329
1330 for (i = 0; i < 18; i++) {
1331 scale = (ladder_lo[i].percent * tmp) / 100;
1332 entry = ((scale & 0xFF) << 8) | ladder_lo[i].g_env;
1333 /* TODO: Write an N PHY Table with ID 15, length 1,
1334 offset i, width 16, and data entry */
1335
1336 scale = (ladder_iq[i].percent * tmp) / 100;
1337 entry = ((scale & 0xFF) << 8) | ladder_iq[i].g_env;
1338 /* TODO: Write an N PHY Table with ID 15, length 1,
1339 offset i + 32, width 16, and data entry */
1340 }
1341}
1342
1343/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/GetTxGain */
1344static struct nphy_txgains b43_nphy_get_tx_gains(struct b43_wldev *dev)
1345{
1346 struct b43_phy_n *nphy = dev->phy.n;
1347
1348 u16 curr_gain[2];
1349 struct nphy_txgains target;
1350 const u32 *table = NULL;
1351
1352 if (nphy->txpwrctrl == 0) {
1353 int i;
1354
1355 if (nphy->hang_avoid)
1356 b43_nphy_stay_in_carrier_search(dev, true);
1357 /* TODO: Read an N PHY Table with ID 7, length 2,
1358 offset 0x110, width 16, and curr_gain */
1359 if (nphy->hang_avoid)
1360 b43_nphy_stay_in_carrier_search(dev, false);
1361
1362 for (i = 0; i < 2; ++i) {
1363 if (dev->phy.rev >= 3) {
1364 target.ipa[i] = curr_gain[i] & 0x000F;
1365 target.pad[i] = (curr_gain[i] & 0x00F0) >> 4;
1366 target.pga[i] = (curr_gain[i] & 0x0F00) >> 8;
1367 target.txgm[i] = (curr_gain[i] & 0x7000) >> 12;
1368 } else {
1369 target.ipa[i] = curr_gain[i] & 0x0003;
1370 target.pad[i] = (curr_gain[i] & 0x000C) >> 2;
1371 target.pga[i] = (curr_gain[i] & 0x0070) >> 4;
1372 target.txgm[i] = (curr_gain[i] & 0x0380) >> 7;
1373 }
1374 }
1375 } else {
1376 int i;
1377 u16 index[2];
1378 index[0] = (b43_phy_read(dev, B43_NPHY_C1_TXPCTL_STAT) &
1379 B43_NPHY_TXPCTL_STAT_BIDX) >>
1380 B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
1381 index[1] = (b43_phy_read(dev, B43_NPHY_C2_TXPCTL_STAT) &
1382 B43_NPHY_TXPCTL_STAT_BIDX) >>
1383 B43_NPHY_TXPCTL_STAT_BIDX_SHIFT;
1384
1385 for (i = 0; i < 2; ++i) {
1386 if (dev->phy.rev >= 3) {
1387 enum ieee80211_band band =
1388 b43_current_band(dev->wl);
1389
1390 if ((nphy->ipa2g_on &&
1391 band == IEEE80211_BAND_2GHZ) ||
1392 (nphy->ipa5g_on &&
1393 band == IEEE80211_BAND_5GHZ)) {
1394 table = b43_nphy_get_ipa_gain_table(dev);
1395 } else {
1396 if (band == IEEE80211_BAND_5GHZ) {
1397 if (dev->phy.rev == 3)
1398 table = b43_ntab_tx_gain_rev3_5ghz;
1399 else if (dev->phy.rev == 4)
1400 table = b43_ntab_tx_gain_rev4_5ghz;
1401 else
1402 table = b43_ntab_tx_gain_rev5plus_5ghz;
1403 } else {
1404 table = b43_ntab_tx_gain_rev3plus_2ghz;
1405 }
1406 }
1407
1408 target.ipa[i] = (table[index[i]] >> 16) & 0xF;
1409 target.pad[i] = (table[index[i]] >> 20) & 0xF;
1410 target.pga[i] = (table[index[i]] >> 24) & 0xF;
1411 target.txgm[i] = (table[index[i]] >> 28) & 0xF;
1412 } else {
1413 table = b43_ntab_tx_gain_rev0_1_2;
1414
1415 target.ipa[i] = (table[index[i]] >> 16) & 0x3;
1416 target.pad[i] = (table[index[i]] >> 18) & 0x3;
1417 target.pga[i] = (table[index[i]] >> 20) & 0x7;
1418 target.txgm[i] = (table[index[i]] >> 23) & 0x7;
1419 }
1420 }
1421 }
1422
1423 return target;
1424}
1425
1426/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/RestoreCal */
1427static void b43_nphy_restore_cal(struct b43_wldev *dev)
1428{
1429 struct b43_phy_n *nphy = dev->phy.n;
1430
1431 u16 coef[4];
1432 u16 *loft = NULL;
1433 u16 *table = NULL;
1434
1435 int i;
1436 u16 *txcal_radio_regs = NULL;
1437 struct b43_phy_n_iq_comp *rxcal_coeffs = NULL;
1438
1439 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1440 if (nphy->iqcal_chanspec_2G == 0)
1441 return;
1442 table = nphy->cal_cache.txcal_coeffs_2G;
1443 loft = &nphy->cal_cache.txcal_coeffs_2G[5];
1444 } else {
1445 if (nphy->iqcal_chanspec_5G == 0)
1446 return;
1447 table = nphy->cal_cache.txcal_coeffs_5G;
1448 loft = &nphy->cal_cache.txcal_coeffs_5G[5];
1449 }
1450
1451 /* TODO: Write an N PHY table with ID 15, length 4, offset 80,
1452 width 16, and data from table */
1453
1454 for (i = 0; i < 4; i++) {
1455 if (dev->phy.rev >= 3)
1456 table[i] = coef[i];
1457 else
1458 coef[i] = 0;
1459 }
1460
1461 /* TODO: Write an N PHY table with ID 15, length 4, offset 88,
1462 width 16, and data from coef */
1463 /* TODO: Write an N PHY table with ID 15, length 2, offset 85,
1464 width 16 and data from loft */
1465 /* TODO: Write an N PHY table with ID 15, length 2, offset 93,
1466 width 16 and data from loft */
1467
1468 if (dev->phy.rev < 2)
1469 b43_nphy_tx_iq_workaround(dev);
1470
1471 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
1472 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_2G;
1473 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_2G;
1474 } else {
1475 txcal_radio_regs = nphy->cal_cache.txcal_radio_regs_5G;
1476 rxcal_coeffs = &nphy->cal_cache.rxcal_coeffs_5G;
1477 }
1478
1479 /* TODO use some definitions */
1480 if (dev->phy.rev >= 3) {
1481 b43_radio_write(dev, 0x2021, txcal_radio_regs[0]);
1482 b43_radio_write(dev, 0x2022, txcal_radio_regs[1]);
1483 b43_radio_write(dev, 0x3021, txcal_radio_regs[2]);
1484 b43_radio_write(dev, 0x3022, txcal_radio_regs[3]);
1485 b43_radio_write(dev, 0x2023, txcal_radio_regs[4]);
1486 b43_radio_write(dev, 0x2024, txcal_radio_regs[5]);
1487 b43_radio_write(dev, 0x3023, txcal_radio_regs[6]);
1488 b43_radio_write(dev, 0x3024, txcal_radio_regs[7]);
1489 } else {
1490 b43_radio_write(dev, 0x8B, txcal_radio_regs[0]);
1491 b43_radio_write(dev, 0xBA, txcal_radio_regs[1]);
1492 b43_radio_write(dev, 0x8D, txcal_radio_regs[2]);
1493 b43_radio_write(dev, 0xBC, txcal_radio_regs[3]);
1494 }
1495 b43_nphy_rx_iq_coeffs(dev, true, rxcal_coeffs);
1496}
1497
1498/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalTxIqlo */
1499static int b43_nphy_cal_tx_iq_lo(struct b43_wldev *dev,
1500 struct nphy_txgains target,
1501 bool full, bool mphase)
1502{
1503 struct b43_phy_n *nphy = dev->phy.n;
1504 int i;
1505 int error = 0;
1506 int freq;
1507 bool avoid = false;
1508 u8 length;
1509 u16 tmp, core, type, count, max, numb, last, cmd;
1510 const u16 *table;
1511 bool phy6or5x;
1512
1513 u16 buffer[11];
1514 u16 diq_start = 0;
1515 u16 save[2];
1516 u16 gain[2];
1517 struct nphy_iqcal_params params[2];
1518 bool updated[2] = { };
1519
1520 b43_nphy_stay_in_carrier_search(dev, true);
1521
1522 if (dev->phy.rev >= 4) {
1523 avoid = nphy->hang_avoid;
1524 nphy->hang_avoid = 0;
1525 }
1526
1527 /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110,
1528 width 16, and data pointer save */
1529
1530 for (i = 0; i < 2; i++) {
1531 b43_nphy_iq_cal_gain_params(dev, i, target, &params[i]);
1532 gain[i] = params[i].cal_gain;
1533 }
1534 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110,
1535 width 16, and data pointer gain */
1536
1537 b43_nphy_tx_cal_radio_setup(dev);
1538 /* TODO: Call N PHY TX Cal PHY Setup */
1539
1540 phy6or5x = dev->phy.rev >= 6 ||
1541 (dev->phy.rev == 5 && nphy->ipa2g_on &&
1542 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ);
1543 if (phy6or5x) {
1544 /* TODO */
1545 }
1546
1547 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0x8AA9);
1548
1549 if (1 /* FIXME: the band width is 20 MHz */)
1550 freq = 2500;
1551 else
1552 freq = 5000;
1553
1554 if (nphy->mphase_cal_phase_id > 2)
1555 ;/* TODO: Call N PHY Run Samples with (band width * 8),
1556 0xFFFF, 0, 1, 0 as arguments */
1557 else
1558 ;/* TODO: Call N PHY TX Tone with freq, 250, 1, 0 as arguments
1559 and save result as error */
1560
1561 if (error == 0) {
1562 if (nphy->mphase_cal_phase_id > 2) {
1563 table = nphy->mphase_txcal_bestcoeffs;
1564 length = 11;
1565 if (dev->phy.rev < 3)
1566 length -= 2;
1567 } else {
1568 if (!full && nphy->txiqlocal_coeffsvalid) {
1569 table = nphy->txiqlocal_bestc;
1570 length = 11;
1571 if (dev->phy.rev < 3)
1572 length -= 2;
1573 } else {
1574 full = true;
1575 if (dev->phy.rev >= 3) {
1576 table = tbl_tx_iqlo_cal_startcoefs_nphyrev3;
1577 length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3;
1578 } else {
1579 table = tbl_tx_iqlo_cal_startcoefs;
1580 length = B43_NTAB_TX_IQLO_CAL_STARTCOEFS;
1581 }
1582 }
1583 }
1584
1585 /* TODO: Write an N PHY Table with ID 15, length from above,
1586 offset 64, width 16, and the data pointer from above */
1587
1588 if (full) {
1589 if (dev->phy.rev >= 3)
1590 max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3;
1591 else
1592 max = B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL;
1593 } else {
1594 if (dev->phy.rev >= 3)
1595 max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3;
1596 else
1597 max = B43_NTAB_TX_IQLO_CAL_CMDS_RECAL;
1598 }
1599
1600 if (mphase) {
1601 count = nphy->mphase_txcal_cmdidx;
1602 numb = min(max,
1603 (u16)(count + nphy->mphase_txcal_numcmds));
1604 } else {
1605 count = 0;
1606 numb = max;
1607 }
1608
1609 for (; count < numb; count++) {
1610 if (full) {
1611 if (dev->phy.rev >= 3)
1612 cmd = tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[count];
1613 else
1614 cmd = tbl_tx_iqlo_cal_cmds_fullcal[count];
1615 } else {
1616 if (dev->phy.rev >= 3)
1617 cmd = tbl_tx_iqlo_cal_cmds_recal_nphyrev3[count];
1618 else
1619 cmd = tbl_tx_iqlo_cal_cmds_recal[count];
1620 }
1621
1622 core = (cmd & 0x3000) >> 12;
1623 type = (cmd & 0x0F00) >> 8;
1624
1625 if (phy6or5x && updated[core] == 0) {
1626 b43_nphy_update_tx_cal_ladder(dev, core);
1627 updated[core] = 1;
1628 }
1629
1630 tmp = (params[core].ncorr[type] << 8) | 0x66;
1631 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDNNUM, tmp);
1632
1633 if (type == 1 || type == 3 || type == 4) {
1634 /* TODO: Read an N PHY Table with ID 15,
1635 length 1, offset 69 + core,
1636 width 16, and data pointer buffer */
1637 diq_start = buffer[0];
1638 buffer[0] = 0;
1639 /* TODO: Write an N PHY Table with ID 15,
1640 length 1, offset 69 + core, width 16,
1641 and data of 0 */
1642 }
1643
1644 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMD, cmd);
1645 for (i = 0; i < 2000; i++) {
1646 tmp = b43_phy_read(dev, B43_NPHY_IQLOCAL_CMD);
1647 if (tmp & 0xC000)
1648 break;
1649 udelay(10);
1650 }
1651
1652 /* TODO: Read an N PHY Table with ID 15,
1653 length table_length, offset 96, width 16,
1654 and data pointer buffer */
1655 /* TODO: Write an N PHY Table with ID 15,
1656 length table_length, offset 64, width 16,
1657 and data pointer buffer */
1658
1659 if (type == 1 || type == 3 || type == 4)
1660 buffer[0] = diq_start;
1661 }
1662
1663 if (mphase)
1664 nphy->mphase_txcal_cmdidx = (numb >= max) ? 0 : numb;
1665
1666 last = (dev->phy.rev < 3) ? 6 : 7;
1667
1668 if (!mphase || nphy->mphase_cal_phase_id == last) {
1669 /* TODO: Write an N PHY Table with ID 15, length 4,
1670 offset 96, width 16, and data pointer buffer */
1671 /* TODO: Read an N PHY Table with ID 15, length 4,
1672 offset 80, width 16, and data pointer buffer */
1673 if (dev->phy.rev < 3) {
1674 buffer[0] = 0;
1675 buffer[1] = 0;
1676 buffer[2] = 0;
1677 buffer[3] = 0;
1678 }
1679 /* TODO: Write an N PHY Table with ID 15, length 4,
1680 offset 88, width 16, and data pointer buffer */
1681 /* TODO: Read an N PHY Table with ID 15, length 2,
1682 offset 101, width 16, and data pointer buffer*/
1683 /* TODO: Write an N PHY Table with ID 15, length 2,
1684 offset 85, width 16, and data pointer buffer */
1685 /* TODO: Write an N PHY Table with ID 15, length 2,
1686 offset 93, width 16, and data pointer buffer */
1687 length = 11;
1688 if (dev->phy.rev < 3)
1689 length -= 2;
1690 /* TODO: Read an N PHY Table with ID 15, length length,
1691 offset 96, width 16, and data pointer
1692 nphy->txiqlocal_bestc */
1693 nphy->txiqlocal_coeffsvalid = true;
1694 /* TODO: Set nphy->txiqlocal_chanspec to
1695 the current channel */
1696 } else {
1697 length = 11;
1698 if (dev->phy.rev < 3)
1699 length -= 2;
1700 /* TODO: Read an N PHY Table with ID 5, length length,
1701 offset 96, width 16, and data pointer
1702 nphy->mphase_txcal_bestcoeffs */
1703 }
1704
1705 /* TODO: Call N PHY Stop Playback */
1706 b43_phy_write(dev, B43_NPHY_IQLOCAL_CMDGCTL, 0);
1707 }
1708
1709 /* TODO: Call N PHY TX Cal PHY Cleanup */
1710 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110,
1711 width 16, and data from save */
1712
1713 if (dev->phy.rev < 2 && (!mphase || nphy->mphase_cal_phase_id == last))
1714 b43_nphy_tx_iq_workaround(dev);
1715
1716 if (dev->phy.rev >= 4)
1717 nphy->hang_avoid = avoid;
1718
1719 b43_nphy_stay_in_carrier_search(dev, false);
1720
1721 return error;
418} 1722}
419 1723
1724/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIqRev2 */
1725static int b43_nphy_rev2_cal_rx_iq(struct b43_wldev *dev,
1726 struct nphy_txgains target, u8 type, bool debug)
1727{
1728 struct b43_phy_n *nphy = dev->phy.n;
1729 int i, j, index;
1730 u8 rfctl[2];
1731 u8 afectl_core;
1732 u16 tmp[6];
1733 u16 cur_hpf1, cur_hpf2, cur_lna;
1734 u32 real, imag;
1735 enum ieee80211_band band;
1736
1737 u8 use;
1738 u16 cur_hpf;
1739 u16 lna[3] = { 3, 3, 1 };
1740 u16 hpf1[3] = { 7, 2, 0 };
1741 u16 hpf2[3] = { 2, 0, 0 };
1742 u32 power[3];
1743 u16 gain_save[2];
1744 u16 cal_gain[2];
1745 struct nphy_iqcal_params cal_params[2];
1746 struct nphy_iq_est est;
1747 int ret = 0;
1748 bool playtone = true;
1749 int desired = 13;
1750
1751 b43_nphy_stay_in_carrier_search(dev, 1);
1752
1753 if (dev->phy.rev < 2)
1754 ;/* TODO: Call N PHY Reapply TX Cal Coeffs */
1755 /* TODO: Read an N PHY Table with ID 7, length 2, offset 0x110,
1756 width 16, and data gain_save */
1757 for (i = 0; i < 2; i++) {
1758 b43_nphy_iq_cal_gain_params(dev, i, target, &cal_params[i]);
1759 cal_gain[i] = cal_params[i].cal_gain;
1760 }
1761 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110,
1762 width 16, and data from cal_gain */
1763
1764 for (i = 0; i < 2; i++) {
1765 if (i == 0) {
1766 rfctl[0] = B43_NPHY_RFCTL_INTC1;
1767 rfctl[1] = B43_NPHY_RFCTL_INTC2;
1768 afectl_core = B43_NPHY_AFECTL_C1;
1769 } else {
1770 rfctl[0] = B43_NPHY_RFCTL_INTC2;
1771 rfctl[1] = B43_NPHY_RFCTL_INTC1;
1772 afectl_core = B43_NPHY_AFECTL_C2;
1773 }
1774
1775 tmp[1] = b43_phy_read(dev, B43_NPHY_RFSEQCA);
1776 tmp[2] = b43_phy_read(dev, afectl_core);
1777 tmp[3] = b43_phy_read(dev, B43_NPHY_AFECTL_OVER);
1778 tmp[4] = b43_phy_read(dev, rfctl[0]);
1779 tmp[5] = b43_phy_read(dev, rfctl[1]);
1780
1781 b43_phy_maskset(dev, B43_NPHY_RFSEQCA,
1782 (u16)~B43_NPHY_RFSEQCA_RXDIS,
1783 ((1 - i) << B43_NPHY_RFSEQCA_RXDIS_SHIFT));
1784 b43_phy_maskset(dev, B43_NPHY_RFSEQCA, ~B43_NPHY_RFSEQCA_TXEN,
1785 (1 - i));
1786 b43_phy_set(dev, afectl_core, 0x0006);
1787 b43_phy_set(dev, B43_NPHY_AFECTL_OVER, 0x0006);
1788
1789 band = b43_current_band(dev->wl);
1790
1791 if (nphy->rxcalparams & 0xFF000000) {
1792 if (band == IEEE80211_BAND_5GHZ)
1793 b43_phy_write(dev, rfctl[0], 0x140);
1794 else
1795 b43_phy_write(dev, rfctl[0], 0x110);
1796 } else {
1797 if (band == IEEE80211_BAND_5GHZ)
1798 b43_phy_write(dev, rfctl[0], 0x180);
1799 else
1800 b43_phy_write(dev, rfctl[0], 0x120);
1801 }
1802
1803 if (band == IEEE80211_BAND_5GHZ)
1804 b43_phy_write(dev, rfctl[1], 0x148);
1805 else
1806 b43_phy_write(dev, rfctl[1], 0x114);
1807
1808 if (nphy->rxcalparams & 0x10000) {
1809 b43_radio_maskset(dev, B2055_C1_GENSPARE2, 0xFC,
1810 (i + 1));
1811 b43_radio_maskset(dev, B2055_C2_GENSPARE2, 0xFC,
1812 (2 - i));
1813 }
1814
1815 for (j = 0; i < 4; j++) {
1816 if (j < 3) {
1817 cur_lna = lna[j];
1818 cur_hpf1 = hpf1[j];
1819 cur_hpf2 = hpf2[j];
1820 } else {
1821 if (power[1] > 10000) {
1822 use = 1;
1823 cur_hpf = cur_hpf1;
1824 index = 2;
1825 } else {
1826 if (power[0] > 10000) {
1827 use = 1;
1828 cur_hpf = cur_hpf1;
1829 index = 1;
1830 } else {
1831 index = 0;
1832 use = 2;
1833 cur_hpf = cur_hpf2;
1834 }
1835 }
1836 cur_lna = lna[index];
1837 cur_hpf1 = hpf1[index];
1838 cur_hpf2 = hpf2[index];
1839 cur_hpf += desired - hweight32(power[index]);
1840 cur_hpf = clamp_val(cur_hpf, 0, 10);
1841 if (use == 1)
1842 cur_hpf1 = cur_hpf;
1843 else
1844 cur_hpf2 = cur_hpf;
1845 }
1846
1847 tmp[0] = ((cur_hpf2 << 8) | (cur_hpf1 << 4) |
1848 (cur_lna << 2));
1849 /* TODO:Call N PHY RF Ctrl Override with 0x400, tmp[0],
1850 3, 0 as arguments */
1851 /* TODO: Call N PHY Force RF Seq with 2 as argument */
1852 /* TODO: Call N PHT Stop Playback */
1853
1854 if (playtone) {
1855 /* TODO: Call N PHY TX Tone with 4000,
1856 (nphy_rxcalparams & 0xffff), 0, 0
1857 as arguments and save result as ret */
1858 playtone = false;
1859 } else {
1860 /* TODO: Call N PHY Run Samples with 160,
1861 0xFFFF, 0, 0, 0 as arguments */
1862 }
1863
1864 if (ret == 0) {
1865 if (j < 3) {
1866 b43_nphy_rx_iq_est(dev, &est, 1024, 32,
1867 false);
1868 if (i == 0) {
1869 real = est.i0_pwr;
1870 imag = est.q0_pwr;
1871 } else {
1872 real = est.i1_pwr;
1873 imag = est.q1_pwr;
1874 }
1875 power[i] = ((real + imag) / 1024) + 1;
1876 } else {
1877 b43_nphy_calc_rx_iq_comp(dev, 1 << i);
1878 }
1879 /* TODO: Call N PHY Stop Playback */
1880 }
1881
1882 if (ret != 0)
1883 break;
1884 }
1885
1886 b43_radio_mask(dev, B2055_C1_GENSPARE2, 0xFC);
1887 b43_radio_mask(dev, B2055_C2_GENSPARE2, 0xFC);
1888 b43_phy_write(dev, rfctl[1], tmp[5]);
1889 b43_phy_write(dev, rfctl[0], tmp[4]);
1890 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, tmp[3]);
1891 b43_phy_write(dev, afectl_core, tmp[2]);
1892 b43_phy_write(dev, B43_NPHY_RFSEQCA, tmp[1]);
1893
1894 if (ret != 0)
1895 break;
1896 }
1897
1898 /* TODO: Call N PHY RF Ctrl Override with 0x400, 0, 3, 1 as arguments*/
1899 /* TODO: Call N PHY Force RF Seq with 2 as argument */
1900 /* TODO: Write an N PHY Table with ID 7, length 2, offset 0x110,
1901 width 16, and data from gain_save */
1902
1903 b43_nphy_stay_in_carrier_search(dev, 0);
1904
1905 return ret;
1906}
1907
1908static int b43_nphy_rev3_cal_rx_iq(struct b43_wldev *dev,
1909 struct nphy_txgains target, u8 type, bool debug)
1910{
1911 return -1;
1912}
1913
1914/* http://bcm-v4.sipsolutions.net/802.11/PHY/N/CalRxIq */
1915static int b43_nphy_cal_rx_iq(struct b43_wldev *dev,
1916 struct nphy_txgains target, u8 type, bool debug)
1917{
1918 if (dev->phy.rev >= 3)
1919 return b43_nphy_rev3_cal_rx_iq(dev, target, type, debug);
1920 else
1921 return b43_nphy_rev2_cal_rx_iq(dev, target, type, debug);
1922}
1923
1924/*
1925 * Init N-PHY
1926 * http://bcm-v4.sipsolutions.net/802.11/PHY/Init/N
1927 */
420int b43_phy_initn(struct b43_wldev *dev) 1928int b43_phy_initn(struct b43_wldev *dev)
421{ 1929{
1930 struct ssb_bus *bus = dev->dev->bus;
422 struct b43_phy *phy = &dev->phy; 1931 struct b43_phy *phy = &dev->phy;
1932 struct b43_phy_n *nphy = phy->n;
1933 u8 tx_pwr_state;
1934 struct nphy_txgains target;
423 u16 tmp; 1935 u16 tmp;
1936 enum ieee80211_band tmp2;
1937 bool do_rssi_cal;
1938
1939 u16 clip[2];
1940 bool do_cal = false;
424 1941
425 //TODO: Spectral management 1942 if ((dev->phy.rev >= 3) &&
1943 (bus->sprom.boardflags_lo & B43_BFL_EXTLNA) &&
1944 (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)) {
1945 chipco_set32(&dev->dev->bus->chipco, SSB_CHIPCO_CHIPCTL, 0x40);
1946 }
1947 nphy->deaf_count = 0;
426 b43_nphy_tables_init(dev); 1948 b43_nphy_tables_init(dev);
1949 nphy->crsminpwr_adjusted = false;
1950 nphy->noisevars_adjusted = false;
427 1951
428 /* Clear all overrides */ 1952 /* Clear all overrides */
429 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0); 1953 if (dev->phy.rev >= 3) {
1954 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S1, 0);
1955 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
1956 b43_phy_write(dev, B43_NPHY_TXF_40CO_B1S0, 0);
1957 b43_phy_write(dev, B43_NPHY_TXF_40CO_B32S1, 0);
1958 } else {
1959 b43_phy_write(dev, B43_NPHY_RFCTL_OVER, 0);
1960 }
430 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0); 1961 b43_phy_write(dev, B43_NPHY_RFCTL_INTC1, 0);
431 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0); 1962 b43_phy_write(dev, B43_NPHY_RFCTL_INTC2, 0);
432 b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0); 1963 if (dev->phy.rev < 6) {
433 b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0); 1964 b43_phy_write(dev, B43_NPHY_RFCTL_INTC3, 0);
1965 b43_phy_write(dev, B43_NPHY_RFCTL_INTC4, 0);
1966 }
434 b43_phy_mask(dev, B43_NPHY_RFSEQMODE, 1967 b43_phy_mask(dev, B43_NPHY_RFSEQMODE,
435 ~(B43_NPHY_RFSEQMODE_CAOVER | 1968 ~(B43_NPHY_RFSEQMODE_CAOVER |
436 B43_NPHY_RFSEQMODE_TROVER)); 1969 B43_NPHY_RFSEQMODE_TROVER));
1970 if (dev->phy.rev >= 3)
1971 b43_phy_write(dev, B43_NPHY_AFECTL_OVER1, 0);
437 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0); 1972 b43_phy_write(dev, B43_NPHY_AFECTL_OVER, 0);
438 1973
439 tmp = (phy->rev < 2) ? 64 : 59; 1974 if (dev->phy.rev <= 2) {
440 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3, 1975 tmp = (dev->phy.rev == 2) ? 0x3B : 0x40;
441 ~B43_NPHY_BPHY_CTL3_SCALE, 1976 b43_phy_maskset(dev, B43_NPHY_BPHY_CTL3,
442 tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT); 1977 ~B43_NPHY_BPHY_CTL3_SCALE,
443 1978 tmp << B43_NPHY_BPHY_CTL3_SCALE_SHIFT);
1979 }
444 b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20); 1980 b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_20M, 0x20);
445 b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20); 1981 b43_phy_write(dev, B43_NPHY_AFESEQ_TX2RX_PUD_40M, 0x20);
446 1982
447 b43_phy_write(dev, B43_NPHY_TXREALFD, 184); 1983 if (bus->sprom.boardflags2_lo & 0x100 ||
448 b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 200); 1984 (bus->boardinfo.vendor == PCI_VENDOR_ID_APPLE &&
449 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 80); 1985 bus->boardinfo.type == 0x8B))
450 b43_phy_write(dev, B43_NPHY_C2_BCLIPBKOFF, 511); 1986 b43_phy_write(dev, B43_NPHY_TXREALFD, 0xA0);
1987 else
1988 b43_phy_write(dev, B43_NPHY_TXREALFD, 0xB8);
1989 b43_phy_write(dev, B43_NPHY_MIMO_CRSTXEXT, 0xC8);
1990 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x50);
1991 b43_phy_write(dev, B43_NPHY_TXRIFS_FRDEL, 0x30);
451 1992
452 //TODO MIMO-Config 1993 /* TODO MIMO-Config */
453 //TODO Update TX/RX chain 1994 /* TODO Update TX/RX chain */
454 1995
455 if (phy->rev < 2) { 1996 if (phy->rev < 2) {
456 b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8); 1997 b43_phy_write(dev, B43_NPHY_DUP40_GFBL, 0xAA8);
457 b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4); 1998 b43_phy_write(dev, B43_NPHY_DUP40_BL, 0x9A4);
458 } 1999 }
2000
2001 tmp2 = b43_current_band(dev->wl);
2002 if ((nphy->ipa2g_on && tmp2 == IEEE80211_BAND_2GHZ) ||
2003 (nphy->ipa5g_on && tmp2 == IEEE80211_BAND_5GHZ)) {
2004 b43_phy_set(dev, B43_NPHY_PAPD_EN0, 0x1);
2005 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ0, 0x007F,
2006 nphy->papd_epsilon_offset[0] << 7);
2007 b43_phy_set(dev, B43_NPHY_PAPD_EN1, 0x1);
2008 b43_phy_maskset(dev, B43_NPHY_EPS_TABLE_ADJ1, 0x007F,
2009 nphy->papd_epsilon_offset[1] << 7);
2010 /* TODO N PHY IPA Set TX Dig Filters */
2011 } else if (phy->rev >= 5) {
2012 /* TODO N PHY Ext PA Set TX Dig Filters */
2013 }
2014
459 b43_nphy_workarounds(dev); 2015 b43_nphy_workarounds(dev);
460 b43_nphy_reset_cca(dev);
461 2016
462 ssb_write32(dev->dev, SSB_TMSLOW, 2017 /* Reset CCA, in init code it differs a little from standard way */
463 ssb_read32(dev->dev, SSB_TMSLOW) | B43_TMSLOW_MACPHYCLKEN); 2018 b43_nphy_bmac_clock_fgc(dev, 1);
2019 tmp = b43_phy_read(dev, B43_NPHY_BBCFG);
2020 b43_phy_write(dev, B43_NPHY_BBCFG, tmp | B43_NPHY_BBCFG_RSTCCA);
2021 b43_phy_write(dev, B43_NPHY_BBCFG, tmp & ~B43_NPHY_BBCFG_RSTCCA);
2022 b43_nphy_bmac_clock_fgc(dev, 0);
2023
2024 /* TODO N PHY MAC PHY Clock Set with argument 1 */
2025
2026 b43_nphy_pa_override(dev, false);
464 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX); 2027 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RX2TX);
465 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX); 2028 b43_nphy_force_rf_sequence(dev, B43_RFSEQ_RESET2RX);
2029 b43_nphy_pa_override(dev, true);
2030
2031 b43_nphy_classifier(dev, 0, 0);
2032 b43_nphy_read_clip_detection(dev, clip);
2033 tx_pwr_state = nphy->txpwrctrl;
2034 /* TODO N PHY TX power control with argument 0
2035 (turning off power control) */
2036 /* TODO Fix the TX Power Settings */
2037 /* TODO N PHY TX Power Control Idle TSSI */
2038 /* TODO N PHY TX Power Control Setup */
2039
2040 if (phy->rev >= 3) {
2041 /* TODO */
2042 } else {
2043 /* TODO Write an N PHY table with ID 26, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */
2044 /* TODO Write an N PHY table with ID 27, length 128, offset 192, width 32, and the data from Rev 2 TX Power Control Table */
2045 }
2046
2047 if (nphy->phyrxchain != 3)
2048 ;/* TODO N PHY RX Core Set State with phyrxchain as argument */
2049 if (nphy->mphase_cal_phase_id > 0)
2050 ;/* TODO PHY Periodic Calibration Multi-Phase Restart */
2051
2052 do_rssi_cal = false;
2053 if (phy->rev >= 3) {
2054 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
2055 do_rssi_cal = (nphy->rssical_chanspec_2G == 0);
2056 else
2057 do_rssi_cal = (nphy->rssical_chanspec_5G == 0);
2058
2059 if (do_rssi_cal)
2060 b43_nphy_rssi_cal(dev);
2061 else
2062 b43_nphy_restore_rssi_cal(dev);
2063 } else {
2064 b43_nphy_rssi_cal(dev);
2065 }
2066
2067 if (!((nphy->measure_hold & 0x6) != 0)) {
2068 if (b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ)
2069 do_cal = (nphy->iqcal_chanspec_2G == 0);
2070 else
2071 do_cal = (nphy->iqcal_chanspec_5G == 0);
2072
2073 if (nphy->mute)
2074 do_cal = false;
2075
2076 if (do_cal) {
2077 target = b43_nphy_get_tx_gains(dev);
2078
2079 if (nphy->antsel_type == 2)
2080 ;/*TODO NPHY Superswitch Init with argument 1*/
2081 if (nphy->perical != 2) {
2082 b43_nphy_rssi_cal(dev);
2083 if (phy->rev >= 3) {
2084 nphy->cal_orig_pwr_idx[0] =
2085 nphy->txpwrindex[0].index_internal;
2086 nphy->cal_orig_pwr_idx[1] =
2087 nphy->txpwrindex[1].index_internal;
2088 /* TODO N PHY Pre Calibrate TX Gain */
2089 target = b43_nphy_get_tx_gains(dev);
2090 }
2091 }
2092 }
2093 }
2094
2095 if (!b43_nphy_cal_tx_iq_lo(dev, target, true, false)) {
2096 if (b43_nphy_cal_rx_iq(dev, target, 2, 0) == 0)
2097 ;/* Call N PHY Save Cal */
2098 else if (nphy->mphase_cal_phase_id == 0)
2099 ;/* N PHY Periodic Calibration with argument 3 */
2100 } else {
2101 b43_nphy_restore_cal(dev);
2102 }
466 2103
467 b43_phy_read(dev, B43_NPHY_CLASSCTL); /* dummy read */ 2104 b43_nphy_tx_pwr_ctrl_coef_setup(dev);
468 //TODO read core1/2 clip1 thres regs 2105 /* TODO N PHY TX Power Control Enable with argument tx_pwr_state */
469 2106 b43_phy_write(dev, B43_NPHY_TXMACIF_HOLDOFF, 0x0015);
470 if (1 /* FIXME Band is 2.4GHz */) 2107 b43_phy_write(dev, B43_NPHY_TXMACDELAY, 0x0320);
471 b43_nphy_bphy_init(dev); 2108 if (phy->rev >= 3 && phy->rev <= 6)
472 //TODO disable TX power control 2109 b43_phy_write(dev, B43_NPHY_PLOAD_CSENSE_EXTLEN, 0x0014);
473 //TODO Fix the TX power settings 2110 b43_nphy_tx_lp_fbw(dev);
474 //TODO Init periodic calibration with reason 3 2111 /* TODO N PHY Spur Workaround */
475 b43_nphy_rssi_cal(dev, 2);
476 b43_nphy_rssi_cal(dev, 0);
477 b43_nphy_rssi_cal(dev, 1);
478 //TODO get TX gain
479 //TODO init superswitch
480 //TODO calibrate LO
481 //TODO idle TSSI TX pctl
482 //TODO TX power control power setup
483 //TODO table writes
484 //TODO TX power control coefficients
485 //TODO enable TX power control
486 //TODO control antenna selection
487 //TODO init radar detection
488 //TODO reset channel if changed
489 2112
490 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n"); 2113 b43err(dev->wl, "IEEE 802.11n devices are not supported, yet.\n");
491 return 0; 2114 return 0;
diff --git a/drivers/net/wireless/b43/phy_n.h b/drivers/net/wireless/b43/phy_n.h
index 1749aef4147d..4572866756fc 100644
--- a/drivers/net/wireless/b43/phy_n.h
+++ b/drivers/net/wireless/b43/phy_n.h
@@ -231,6 +231,7 @@
231#define B43_NPHY_C2_TXIQ_COMP_OFF B43_PHY_N(0x088) /* Core 2 TX I/Q comp offset */ 231#define B43_NPHY_C2_TXIQ_COMP_OFF B43_PHY_N(0x088) /* Core 2 TX I/Q comp offset */
232#define B43_NPHY_C1_TXCTL B43_PHY_N(0x08B) /* Core 1 TX control */ 232#define B43_NPHY_C1_TXCTL B43_PHY_N(0x08B) /* Core 1 TX control */
233#define B43_NPHY_C2_TXCTL B43_PHY_N(0x08C) /* Core 2 TX control */ 233#define B43_NPHY_C2_TXCTL B43_PHY_N(0x08C) /* Core 2 TX control */
234#define B43_NPHY_AFECTL_OVER1 B43_PHY_N(0x08F) /* AFE control override 1 */
234#define B43_NPHY_SCRAM_SIGCTL B43_PHY_N(0x090) /* Scram signal control */ 235#define B43_NPHY_SCRAM_SIGCTL B43_PHY_N(0x090) /* Scram signal control */
235#define B43_NPHY_SCRAM_SIGCTL_INITST 0x007F /* Initial state value */ 236#define B43_NPHY_SCRAM_SIGCTL_INITST 0x007F /* Initial state value */
236#define B43_NPHY_SCRAM_SIGCTL_INITST_SHIFT 0 237#define B43_NPHY_SCRAM_SIGCTL_INITST_SHIFT 0
@@ -705,6 +706,10 @@
705#define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power controll init */ 706#define B43_NPHY_TXPCTL_INIT B43_PHY_N(0x222) /* TX power controll init */
706#define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */ 707#define B43_NPHY_TXPCTL_INIT_PIDXI1 0x00FF /* Power index init 1 */
707#define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0 708#define B43_NPHY_TXPCTL_INIT_PIDXI1_SHIFT 0
709#define B43_NPHY_PAPD_EN0 B43_PHY_N(0x297) /* PAPD Enable0 TBD */
710#define B43_NPHY_EPS_TABLE_ADJ0 B43_PHY_N(0x298) /* EPS Table Adj0 TBD */
711#define B43_NPHY_PAPD_EN1 B43_PHY_N(0x29B) /* PAPD Enable1 TBD */
712#define B43_NPHY_EPS_TABLE_ADJ1 B43_PHY_N(0x29C) /* EPS Table Adj1 TBD */
708 713
709 714
710 715
@@ -919,8 +924,88 @@
919 924
920struct b43_wldev; 925struct b43_wldev;
921 926
927struct b43_phy_n_iq_comp {
928 s16 a0;
929 s16 b0;
930 s16 a1;
931 s16 b1;
932};
933
934struct b43_phy_n_rssical_cache {
935 u16 rssical_radio_regs_2G[2];
936 u16 rssical_phy_regs_2G[12];
937
938 u16 rssical_radio_regs_5G[2];
939 u16 rssical_phy_regs_5G[12];
940};
941
942struct b43_phy_n_cal_cache {
943 u16 txcal_radio_regs_2G[8];
944 u16 txcal_coeffs_2G[8];
945 struct b43_phy_n_iq_comp rxcal_coeffs_2G;
946
947 u16 txcal_radio_regs_5G[8];
948 u16 txcal_coeffs_5G[8];
949 struct b43_phy_n_iq_comp rxcal_coeffs_5G;
950};
951
952struct b43_phy_n_txpwrindex {
953 s8 index;
954 s8 index_internal;
955 s8 index_internal_save;
956 u16 AfectrlOverride;
957 u16 AfeCtrlDacGain;
958 u16 rad_gain;
959 u8 bbmult;
960 u16 iqcomp_a;
961 u16 iqcomp_b;
962 u16 locomp;
963};
964
922struct b43_phy_n { 965struct b43_phy_n {
923 //TODO lots of missing stuff 966 u8 antsel_type;
967 u8 cal_orig_pwr_idx[2];
968 u8 measure_hold;
969 u8 phyrxchain;
970 u8 perical;
971 u32 deaf_count;
972 u32 rxcalparams;
973 bool hang_avoid;
974 bool mute;
975 u16 papd_epsilon_offset[2];
976
977 u8 mphase_cal_phase_id;
978 u16 mphase_txcal_cmdidx;
979 u16 mphase_txcal_numcmds;
980 u16 mphase_txcal_bestcoeffs[11];
981
982 u8 txpwrctrl;
983 u16 txcal_bbmult;
984 u16 txiqlocal_bestc[11];
985 bool txiqlocal_coeffsvalid;
986 struct b43_phy_n_txpwrindex txpwrindex[2];
987
988 u16 tx_rx_cal_phy_saveregs[11];
989 u16 tx_rx_cal_radio_saveregs[22];
990
991 u16 rfctrl_intc1_save;
992 u16 rfctrl_intc2_save;
993
994 u16 classifier_state;
995 u16 clip_state[2];
996
997 bool ipa2g_on;
998 u8 iqcal_chanspec_2G;
999 u8 rssical_chanspec_2G;
1000
1001 bool ipa5g_on;
1002 u8 iqcal_chanspec_5G;
1003 u8 rssical_chanspec_5G;
1004
1005 struct b43_phy_n_rssical_cache rssical_cache;
1006 struct b43_phy_n_cal_cache cal_cache;
1007 bool crsminpwr_adjusted;
1008 bool noisevars_adjusted;
924}; 1009};
925 1010
926 1011
diff --git a/drivers/net/wireless/b43/tables_nphy.c b/drivers/net/wireless/b43/tables_nphy.c
index 4e2336315545..7dff853ab962 100644
--- a/drivers/net/wireless/b43/tables_nphy.c
+++ b/drivers/net/wireless/b43/tables_nphy.c
@@ -1336,7 +1336,7 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel)
1336} 1336}
1337 1337
1338 1338
1339const u8 b43_ntab_adjustpower0[] = { 1339static const u8 b43_ntab_adjustpower0[] = {
1340 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 1340 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
1341 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 1341 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
1342 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 1342 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
@@ -1355,7 +1355,7 @@ const u8 b43_ntab_adjustpower0[] = {
1355 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 1355 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
1356}; 1356};
1357 1357
1358const u8 b43_ntab_adjustpower1[] = { 1358static const u8 b43_ntab_adjustpower1[] = {
1359 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 1359 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01,
1360 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 1360 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03,
1361 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 1361 0x04, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
@@ -1374,11 +1374,11 @@ const u8 b43_ntab_adjustpower1[] = {
1374 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F, 1374 0x1E, 0x1E, 0x1E, 0x1E, 0x1F, 0x1F, 0x1F, 0x1F,
1375}; 1375};
1376 1376
1377const u16 b43_ntab_bdi[] = { 1377static const u16 b43_ntab_bdi[] = {
1378 0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2, 1378 0x0070, 0x0126, 0x012C, 0x0246, 0x048D, 0x04D2,
1379}; 1379};
1380 1380
1381const u32 b43_ntab_channelest[] = { 1381static const u32 b43_ntab_channelest[] = {
1382 0x44444444, 0x44444444, 0x44444444, 0x44444444, 1382 0x44444444, 0x44444444, 0x44444444, 0x44444444,
1383 0x44444444, 0x44444444, 0x44444444, 0x44444444, 1383 0x44444444, 0x44444444, 0x44444444, 0x44444444,
1384 0x10101010, 0x10101010, 0x10101010, 0x10101010, 1384 0x10101010, 0x10101010, 0x10101010, 0x10101010,
@@ -1405,7 +1405,7 @@ const u32 b43_ntab_channelest[] = {
1405 0x10101010, 0x10101010, 0x10101010, 0x10101010, 1405 0x10101010, 0x10101010, 0x10101010, 0x10101010,
1406}; 1406};
1407 1407
1408const u8 b43_ntab_estimatepowerlt0[] = { 1408static const u8 b43_ntab_estimatepowerlt0[] = {
1409 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 1409 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49,
1410 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 1410 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41,
1411 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 1411 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
@@ -1416,7 +1416,7 @@ const u8 b43_ntab_estimatepowerlt0[] = {
1416 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 1416 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
1417}; 1417};
1418 1418
1419const u8 b43_ntab_estimatepowerlt1[] = { 1419static const u8 b43_ntab_estimatepowerlt1[] = {
1420 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49, 1420 0x50, 0x4F, 0x4E, 0x4D, 0x4C, 0x4B, 0x4A, 0x49,
1421 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41, 1421 0x48, 0x47, 0x46, 0x45, 0x44, 0x43, 0x42, 0x41,
1422 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39, 1422 0x40, 0x3F, 0x3E, 0x3D, 0x3C, 0x3B, 0x3A, 0x39,
@@ -1427,14 +1427,14 @@ const u8 b43_ntab_estimatepowerlt1[] = {
1427 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11, 1427 0x18, 0x17, 0x16, 0x15, 0x14, 0x13, 0x12, 0x11,
1428}; 1428};
1429 1429
1430const u8 b43_ntab_framelookup[] = { 1430static const u8 b43_ntab_framelookup[] = {
1431 0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16, 1431 0x02, 0x04, 0x14, 0x14, 0x03, 0x05, 0x16, 0x16,
1432 0x0A, 0x0C, 0x1C, 0x1C, 0x0B, 0x0D, 0x1E, 0x1E, 1432 0x0A, 0x0C, 0x1C, 0x1C, 0x0B, 0x0D, 0x1E, 0x1E,
1433 0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1A, 0x1A, 1433 0x06, 0x08, 0x18, 0x18, 0x07, 0x09, 0x1A, 0x1A,
1434 0x0E, 0x10, 0x20, 0x28, 0x0F, 0x11, 0x22, 0x2A, 1434 0x0E, 0x10, 0x20, 0x28, 0x0F, 0x11, 0x22, 0x2A,
1435}; 1435};
1436 1436
1437const u32 b43_ntab_framestruct[] = { 1437static const u32 b43_ntab_framestruct[] = {
1438 0x08004A04, 0x00100000, 0x01000A05, 0x00100020, 1438 0x08004A04, 0x00100000, 0x01000A05, 0x00100020,
1439 0x09804506, 0x00100030, 0x09804507, 0x00100030, 1439 0x09804506, 0x00100030, 0x09804507, 0x00100030,
1440 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1440 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -1645,7 +1645,7 @@ const u32 b43_ntab_framestruct[] = {
1645 0x00000000, 0x00000000, 0x00000000, 0x00000000, 1645 0x00000000, 0x00000000, 0x00000000, 0x00000000,
1646}; 1646};
1647 1647
1648const u32 b43_ntab_gainctl0[] = { 1648static const u32 b43_ntab_gainctl0[] = {
1649 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, 1649 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
1650 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, 1650 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
1651 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, 1651 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
@@ -1680,7 +1680,7 @@ const u32 b43_ntab_gainctl0[] = {
1680 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, 1680 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
1681}; 1681};
1682 1682
1683const u32 b43_ntab_gainctl1[] = { 1683static const u32 b43_ntab_gainctl1[] = {
1684 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E, 1684 0x007F003F, 0x007E013F, 0x007D023E, 0x007C033E,
1685 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C, 1685 0x007B043D, 0x007A053D, 0x0079063C, 0x0078073C,
1686 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A, 1686 0x0077083B, 0x0076093B, 0x00750A3A, 0x00740B3A,
@@ -1715,12 +1715,12 @@ const u32 b43_ntab_gainctl1[] = {
1715 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00, 1715 0x00030C01, 0x00020D01, 0x00010E00, 0x00000F00,
1716}; 1716};
1717 1717
1718const u32 b43_ntab_intlevel[] = { 1718static const u32 b43_ntab_intlevel[] = {
1719 0x00802070, 0x0671188D, 0x0A60192C, 0x0A300E46, 1719 0x00802070, 0x0671188D, 0x0A60192C, 0x0A300E46,
1720 0x00C1188D, 0x080024D2, 0x00000070, 1720 0x00C1188D, 0x080024D2, 0x00000070,
1721}; 1721};
1722 1722
1723const u32 b43_ntab_iqlt0[] = { 1723static const u32 b43_ntab_iqlt0[] = {
1724 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1724 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1725 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1725 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1726 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1726 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
@@ -1755,7 +1755,7 @@ const u32 b43_ntab_iqlt0[] = {
1755 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1755 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1756}; 1756};
1757 1757
1758const u32 b43_ntab_iqlt1[] = { 1758static const u32 b43_ntab_iqlt1[] = {
1759 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1759 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1760 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1760 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1761 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1761 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
@@ -1790,7 +1790,7 @@ const u32 b43_ntab_iqlt1[] = {
1790 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F, 1790 0x0000007F, 0x0000007F, 0x0000007F, 0x0000007F,
1791}; 1791};
1792 1792
1793const u16 b43_ntab_loftlt0[] = { 1793static const u16 b43_ntab_loftlt0[] = {
1794 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, 1794 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
1795 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103, 1795 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
1796 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, 1796 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
@@ -1815,7 +1815,7 @@ const u16 b43_ntab_loftlt0[] = {
1815 0x0002, 0x0103, 1815 0x0002, 0x0103,
1816}; 1816};
1817 1817
1818const u16 b43_ntab_loftlt1[] = { 1818static const u16 b43_ntab_loftlt1[] = {
1819 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, 1819 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
1820 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103, 1820 0x0002, 0x0103, 0x0000, 0x0101, 0x0002, 0x0103,
1821 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101, 1821 0x0000, 0x0101, 0x0002, 0x0103, 0x0000, 0x0101,
@@ -1840,7 +1840,7 @@ const u16 b43_ntab_loftlt1[] = {
1840 0x0002, 0x0103, 1840 0x0002, 0x0103,
1841}; 1841};
1842 1842
1843const u8 b43_ntab_mcs[] = { 1843static const u8 b43_ntab_mcs[] = {
1844 0x00, 0x08, 0x0A, 0x10, 0x12, 0x19, 0x1A, 0x1C, 1844 0x00, 0x08, 0x0A, 0x10, 0x12, 0x19, 0x1A, 0x1C,
1845 0x40, 0x48, 0x4A, 0x50, 0x52, 0x59, 0x5A, 0x5C, 1845 0x40, 0x48, 0x4A, 0x50, 0x52, 0x59, 0x5A, 0x5C,
1846 0x80, 0x88, 0x8A, 0x90, 0x92, 0x99, 0x9A, 0x9C, 1846 0x80, 0x88, 0x8A, 0x90, 0x92, 0x99, 0x9A, 0x9C,
@@ -1859,7 +1859,7 @@ const u8 b43_ntab_mcs[] = {
1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 1859 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1860}; 1860};
1861 1861
1862const u32 b43_ntab_noisevar10[] = { 1862static const u32 b43_ntab_noisevar10[] = {
1863 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1863 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1864 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1864 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1865 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1865 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
@@ -1926,7 +1926,7 @@ const u32 b43_ntab_noisevar10[] = {
1926 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1926 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1927}; 1927};
1928 1928
1929const u32 b43_ntab_noisevar11[] = { 1929static const u32 b43_ntab_noisevar11[] = {
1930 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1930 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1931 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1931 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1932 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1932 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
@@ -1993,7 +1993,7 @@ const u32 b43_ntab_noisevar11[] = {
1993 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D, 1993 0x020C020C, 0x0000014D, 0x020C020C, 0x0000014D,
1994}; 1994};
1995 1995
1996const u16 b43_ntab_pilot[] = { 1996static const u16 b43_ntab_pilot[] = {
1997 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 1997 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08, 0xFF08,
1998 0xFF08, 0xFF08, 0x80D5, 0x80D5, 0x80D5, 0x80D5, 1998 0xFF08, 0xFF08, 0x80D5, 0x80D5, 0x80D5, 0x80D5,
1999 0x80D5, 0x80D5, 0x80D5, 0x80D5, 0xFF0A, 0xFF82, 1999 0x80D5, 0x80D5, 0x80D5, 0x80D5, 0xFF0A, 0xFF82,
@@ -2011,12 +2011,12 @@ const u16 b43_ntab_pilot[] = {
2011 0xF0A0, 0xF028, 0xFFFF, 0xFFFF, 2011 0xF0A0, 0xF028, 0xFFFF, 0xFFFF,
2012}; 2012};
2013 2013
2014const u32 b43_ntab_pilotlt[] = { 2014static const u32 b43_ntab_pilotlt[] = {
2015 0x76540123, 0x62407351, 0x76543201, 0x76540213, 2015 0x76540123, 0x62407351, 0x76543201, 0x76540213,
2016 0x76540123, 0x76430521, 2016 0x76540123, 0x76430521,
2017}; 2017};
2018 2018
2019const u32 b43_ntab_tdi20a0[] = { 2019static const u32 b43_ntab_tdi20a0[] = {
2020 0x00091226, 0x000A1429, 0x000B56AD, 0x000C58B0, 2020 0x00091226, 0x000A1429, 0x000B56AD, 0x000C58B0,
2021 0x000D5AB3, 0x000E9CB6, 0x000F9EBA, 0x0000C13D, 2021 0x000D5AB3, 0x000E9CB6, 0x000F9EBA, 0x0000C13D,
2022 0x00020301, 0x00030504, 0x00040708, 0x0005090B, 2022 0x00020301, 0x00030504, 0x00040708, 0x0005090B,
@@ -2033,7 +2033,7 @@ const u32 b43_ntab_tdi20a0[] = {
2033 0x00000000, 0x00000000, 0x00000000, 2033 0x00000000, 0x00000000, 0x00000000,
2034}; 2034};
2035 2035
2036const u32 b43_ntab_tdi20a1[] = { 2036static const u32 b43_ntab_tdi20a1[] = {
2037 0x00014B26, 0x00028D29, 0x000393AD, 0x00049630, 2037 0x00014B26, 0x00028D29, 0x000393AD, 0x00049630,
2038 0x0005D833, 0x0006DA36, 0x00099C3A, 0x000A9E3D, 2038 0x0005D833, 0x0006DA36, 0x00099C3A, 0x000A9E3D,
2039 0x000BC081, 0x000CC284, 0x000DC488, 0x000F068B, 2039 0x000BC081, 0x000CC284, 0x000DC488, 0x000F068B,
@@ -2050,7 +2050,7 @@ const u32 b43_ntab_tdi20a1[] = {
2050 0x00000000, 0x00000000, 0x00000000, 2050 0x00000000, 0x00000000, 0x00000000,
2051}; 2051};
2052 2052
2053const u32 b43_ntab_tdi40a0[] = { 2053static const u32 b43_ntab_tdi40a0[] = {
2054 0x0011A346, 0x00136CCF, 0x0014F5D9, 0x001641E2, 2054 0x0011A346, 0x00136CCF, 0x0014F5D9, 0x001641E2,
2055 0x0017CB6B, 0x00195475, 0x001B2383, 0x001CAD0C, 2055 0x0017CB6B, 0x00195475, 0x001B2383, 0x001CAD0C,
2056 0x001E7616, 0x0000821F, 0x00020BA8, 0x0003D4B2, 2056 0x001E7616, 0x0000821F, 0x00020BA8, 0x0003D4B2,
@@ -2081,7 +2081,7 @@ const u32 b43_ntab_tdi40a0[] = {
2081 0x00000000, 0x00000000, 2081 0x00000000, 0x00000000,
2082}; 2082};
2083 2083
2084const u32 b43_ntab_tdi40a1[] = { 2084static const u32 b43_ntab_tdi40a1[] = {
2085 0x001EDB36, 0x000129CA, 0x0002B353, 0x00047CDD, 2085 0x001EDB36, 0x000129CA, 0x0002B353, 0x00047CDD,
2086 0x0005C8E6, 0x000791EF, 0x00091BF9, 0x000AAA07, 2086 0x0005C8E6, 0x000791EF, 0x00091BF9, 0x000AAA07,
2087 0x000C3391, 0x000DFD1A, 0x00120923, 0x0013D22D, 2087 0x000C3391, 0x000DFD1A, 0x00120923, 0x0013D22D,
@@ -2112,7 +2112,7 @@ const u32 b43_ntab_tdi40a1[] = {
2112 0x00000000, 0x00000000, 2112 0x00000000, 0x00000000,
2113}; 2113};
2114 2114
2115const u32 b43_ntab_tdtrn[] = { 2115static const u32 b43_ntab_tdtrn[] = {
2116 0x061C061C, 0x0050EE68, 0xF592FE36, 0xFE5212F6, 2116 0x061C061C, 0x0050EE68, 0xF592FE36, 0xFE5212F6,
2117 0x00000C38, 0xFE5212F6, 0xF592FE36, 0x0050EE68, 2117 0x00000C38, 0xFE5212F6, 0xF592FE36, 0x0050EE68,
2118 0x061C061C, 0xEE680050, 0xFE36F592, 0x12F6FE52, 2118 0x061C061C, 0xEE680050, 0xFE36F592, 0x12F6FE52,
@@ -2291,7 +2291,7 @@ const u32 b43_ntab_tdtrn[] = {
2291 0xFA58FC00, 0x0B64FC7E, 0x0800F7B6, 0x00F006BE, 2291 0xFA58FC00, 0x0B64FC7E, 0x0800F7B6, 0x00F006BE,
2292}; 2292};
2293 2293
2294const u32 b43_ntab_tmap[] = { 2294static const u32 b43_ntab_tmap[] = {
2295 0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888, 2295 0x8A88AA80, 0x8AAAAA8A, 0x8A8A8AA8, 0x00000888,
2296 0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8, 2296 0x88000000, 0x8A8A88AA, 0x8AA88888, 0x8888A8A8,
2297 0xF1111110, 0x11111111, 0x11F11111, 0x00000111, 2297 0xF1111110, 0x11111111, 0x11F11111, 0x00000111,
@@ -2406,6 +2406,483 @@ const u32 b43_ntab_tmap[] = {
2406 0x00000000, 0x00000000, 0x00000000, 0x00000000, 2406 0x00000000, 0x00000000, 0x00000000, 0x00000000,
2407}; 2407};
2408 2408
2409const u32 b43_ntab_tx_gain_rev0_1_2[] = {
2410 0x03cc2b44, 0x03cc2b42, 0x03cc2a44, 0x03cc2a42,
2411 0x03cc2944, 0x03c82b44, 0x03c82b42, 0x03c82a44,
2412 0x03c82a42, 0x03c82944, 0x03c82942, 0x03c82844,
2413 0x03c82842, 0x03c42b44, 0x03c42b42, 0x03c42a44,
2414 0x03c42a42, 0x03c42944, 0x03c42942, 0x03c42844,
2415 0x03c42842, 0x03c42744, 0x03c42742, 0x03c42644,
2416 0x03c42642, 0x03c42544, 0x03c42542, 0x03c42444,
2417 0x03c42442, 0x03c02b44, 0x03c02b42, 0x03c02a44,
2418 0x03c02a42, 0x03c02944, 0x03c02942, 0x03c02844,
2419 0x03c02842, 0x03c02744, 0x03c02742, 0x03b02b44,
2420 0x03b02b42, 0x03b02a44, 0x03b02a42, 0x03b02944,
2421 0x03b02942, 0x03b02844, 0x03b02842, 0x03b02744,
2422 0x03b02742, 0x03b02644, 0x03b02642, 0x03b02544,
2423 0x03b02542, 0x03a02b44, 0x03a02b42, 0x03a02a44,
2424 0x03a02a42, 0x03a02944, 0x03a02942, 0x03a02844,
2425 0x03a02842, 0x03a02744, 0x03a02742, 0x03902b44,
2426 0x03902b42, 0x03902a44, 0x03902a42, 0x03902944,
2427 0x03902942, 0x03902844, 0x03902842, 0x03902744,
2428 0x03902742, 0x03902644, 0x03902642, 0x03902544,
2429 0x03902542, 0x03802b44, 0x03802b42, 0x03802a44,
2430 0x03802a42, 0x03802944, 0x03802942, 0x03802844,
2431 0x03802842, 0x03802744, 0x03802742, 0x03802644,
2432 0x03802642, 0x03802544, 0x03802542, 0x03802444,
2433 0x03802442, 0x03802344, 0x03802342, 0x03802244,
2434 0x03802242, 0x03802144, 0x03802142, 0x03802044,
2435 0x03802042, 0x03801f44, 0x03801f42, 0x03801e44,
2436 0x03801e42, 0x03801d44, 0x03801d42, 0x03801c44,
2437 0x03801c42, 0x03801b44, 0x03801b42, 0x03801a44,
2438 0x03801a42, 0x03801944, 0x03801942, 0x03801844,
2439 0x03801842, 0x03801744, 0x03801742, 0x03801644,
2440 0x03801642, 0x03801544, 0x03801542, 0x03801444,
2441 0x03801442, 0x03801344, 0x03801342, 0x00002b00,
2442};
2443
2444const u32 b43_ntab_tx_gain_rev3plus_2ghz[] = {
2445 0x1f410044, 0x1f410042, 0x1f410040, 0x1f41003e,
2446 0x1f41003c, 0x1f41003b, 0x1f410039, 0x1f410037,
2447 0x1e410044, 0x1e410042, 0x1e410040, 0x1e41003e,
2448 0x1e41003c, 0x1e41003b, 0x1e410039, 0x1e410037,
2449 0x1d410044, 0x1d410042, 0x1d410040, 0x1d41003e,
2450 0x1d41003c, 0x1d41003b, 0x1d410039, 0x1d410037,
2451 0x1c410044, 0x1c410042, 0x1c410040, 0x1c41003e,
2452 0x1c41003c, 0x1c41003b, 0x1c410039, 0x1c410037,
2453 0x1b410044, 0x1b410042, 0x1b410040, 0x1b41003e,
2454 0x1b41003c, 0x1b41003b, 0x1b410039, 0x1b410037,
2455 0x1a410044, 0x1a410042, 0x1a410040, 0x1a41003e,
2456 0x1a41003c, 0x1a41003b, 0x1a410039, 0x1a410037,
2457 0x19410044, 0x19410042, 0x19410040, 0x1941003e,
2458 0x1941003c, 0x1941003b, 0x19410039, 0x19410037,
2459 0x18410044, 0x18410042, 0x18410040, 0x1841003e,
2460 0x1841003c, 0x1841003b, 0x18410039, 0x18410037,
2461 0x17410044, 0x17410042, 0x17410040, 0x1741003e,
2462 0x1741003c, 0x1741003b, 0x17410039, 0x17410037,
2463 0x16410044, 0x16410042, 0x16410040, 0x1641003e,
2464 0x1641003c, 0x1641003b, 0x16410039, 0x16410037,
2465 0x15410044, 0x15410042, 0x15410040, 0x1541003e,
2466 0x1541003c, 0x1541003b, 0x15410039, 0x15410037,
2467 0x14410044, 0x14410042, 0x14410040, 0x1441003e,
2468 0x1441003c, 0x1441003b, 0x14410039, 0x14410037,
2469 0x13410044, 0x13410042, 0x13410040, 0x1341003e,
2470 0x1341003c, 0x1341003b, 0x13410039, 0x13410037,
2471 0x12410044, 0x12410042, 0x12410040, 0x1241003e,
2472 0x1241003c, 0x1241003b, 0x12410039, 0x12410037,
2473 0x11410044, 0x11410042, 0x11410040, 0x1141003e,
2474 0x1141003c, 0x1141003b, 0x11410039, 0x11410037,
2475 0x10410044, 0x10410042, 0x10410040, 0x1041003e,
2476 0x1041003c, 0x1041003b, 0x10410039, 0x10410037,
2477};
2478
2479const u32 b43_ntab_tx_gain_rev3_5ghz[] = {
2480 0xcff70044, 0xcff70042, 0xcff70040, 0xcff7003e,
2481 0xcff7003c, 0xcff7003b, 0xcff70039, 0xcff70037,
2482 0xcef70044, 0xcef70042, 0xcef70040, 0xcef7003e,
2483 0xcef7003c, 0xcef7003b, 0xcef70039, 0xcef70037,
2484 0xcdf70044, 0xcdf70042, 0xcdf70040, 0xcdf7003e,
2485 0xcdf7003c, 0xcdf7003b, 0xcdf70039, 0xcdf70037,
2486 0xccf70044, 0xccf70042, 0xccf70040, 0xccf7003e,
2487 0xccf7003c, 0xccf7003b, 0xccf70039, 0xccf70037,
2488 0xcbf70044, 0xcbf70042, 0xcbf70040, 0xcbf7003e,
2489 0xcbf7003c, 0xcbf7003b, 0xcbf70039, 0xcbf70037,
2490 0xcaf70044, 0xcaf70042, 0xcaf70040, 0xcaf7003e,
2491 0xcaf7003c, 0xcaf7003b, 0xcaf70039, 0xcaf70037,
2492 0xc9f70044, 0xc9f70042, 0xc9f70040, 0xc9f7003e,
2493 0xc9f7003c, 0xc9f7003b, 0xc9f70039, 0xc9f70037,
2494 0xc8f70044, 0xc8f70042, 0xc8f70040, 0xc8f7003e,
2495 0xc8f7003c, 0xc8f7003b, 0xc8f70039, 0xc8f70037,
2496 0xc7f70044, 0xc7f70042, 0xc7f70040, 0xc7f7003e,
2497 0xc7f7003c, 0xc7f7003b, 0xc7f70039, 0xc7f70037,
2498 0xc6f70044, 0xc6f70042, 0xc6f70040, 0xc6f7003e,
2499 0xc6f7003c, 0xc6f7003b, 0xc6f70039, 0xc6f70037,
2500 0xc5f70044, 0xc5f70042, 0xc5f70040, 0xc5f7003e,
2501 0xc5f7003c, 0xc5f7003b, 0xc5f70039, 0xc5f70037,
2502 0xc4f70044, 0xc4f70042, 0xc4f70040, 0xc4f7003e,
2503 0xc4f7003c, 0xc4f7003b, 0xc4f70039, 0xc4f70037,
2504 0xc3f70044, 0xc3f70042, 0xc3f70040, 0xc3f7003e,
2505 0xc3f7003c, 0xc3f7003b, 0xc3f70039, 0xc3f70037,
2506 0xc2f70044, 0xc2f70042, 0xc2f70040, 0xc2f7003e,
2507 0xc2f7003c, 0xc2f7003b, 0xc2f70039, 0xc2f70037,
2508 0xc1f70044, 0xc1f70042, 0xc1f70040, 0xc1f7003e,
2509 0xc1f7003c, 0xc1f7003b, 0xc1f70039, 0xc1f70037,
2510 0xc0f70044, 0xc0f70042, 0xc0f70040, 0xc0f7003e,
2511 0xc0f7003c, 0xc0f7003b, 0xc0f70039, 0xc0f70037,
2512};
2513
2514const u32 b43_ntab_tx_gain_rev4_5ghz[] = {
2515 0x2ff20044, 0x2ff20042, 0x2ff20040, 0x2ff2003e,
2516 0x2ff2003c, 0x2ff2003b, 0x2ff20039, 0x2ff20037,
2517 0x2ef20044, 0x2ef20042, 0x2ef20040, 0x2ef2003e,
2518 0x2ef2003c, 0x2ef2003b, 0x2ef20039, 0x2ef20037,
2519 0x2df20044, 0x2df20042, 0x2df20040, 0x2df2003e,
2520 0x2df2003c, 0x2df2003b, 0x2df20039, 0x2df20037,
2521 0x2cf20044, 0x2cf20042, 0x2cf20040, 0x2cf2003e,
2522 0x2cf2003c, 0x2cf2003b, 0x2cf20039, 0x2cf20037,
2523 0x2bf20044, 0x2bf20042, 0x2bf20040, 0x2bf2003e,
2524 0x2bf2003c, 0x2bf2003b, 0x2bf20039, 0x2bf20037,
2525 0x2af20044, 0x2af20042, 0x2af20040, 0x2af2003e,
2526 0x2af2003c, 0x2af2003b, 0x2af20039, 0x2af20037,
2527 0x29f20044, 0x29f20042, 0x29f20040, 0x29f2003e,
2528 0x29f2003c, 0x29f2003b, 0x29f20039, 0x29f20037,
2529 0x28f20044, 0x28f20042, 0x28f20040, 0x28f2003e,
2530 0x28f2003c, 0x28f2003b, 0x28f20039, 0x28f20037,
2531 0x27f20044, 0x27f20042, 0x27f20040, 0x27f2003e,
2532 0x27f2003c, 0x27f2003b, 0x27f20039, 0x27f20037,
2533 0x26f20044, 0x26f20042, 0x26f20040, 0x26f2003e,
2534 0x26f2003c, 0x26f2003b, 0x26f20039, 0x26f20037,
2535 0x25f20044, 0x25f20042, 0x25f20040, 0x25f2003e,
2536 0x25f2003c, 0x25f2003b, 0x25f20039, 0x25f20037,
2537 0x24f20044, 0x24f20042, 0x24f20040, 0x24f2003e,
2538 0x24f2003c, 0x24f2003b, 0x24f20039, 0x24f20038,
2539 0x23f20041, 0x23f20040, 0x23f2003f, 0x23f2003e,
2540 0x23f2003c, 0x23f2003b, 0x23f20039, 0x23f20037,
2541 0x22f20044, 0x22f20042, 0x22f20040, 0x22f2003e,
2542 0x22f2003c, 0x22f2003b, 0x22f20039, 0x22f20037,
2543 0x21f20044, 0x21f20042, 0x21f20040, 0x21f2003e,
2544 0x21f2003c, 0x21f2003b, 0x21f20039, 0x21f20037,
2545 0x20d20043, 0x20d20041, 0x20d2003e, 0x20d2003c,
2546 0x20d2003a, 0x20d20038, 0x20d20036, 0x20d20034,
2547};
2548
2549const u32 b43_ntab_tx_gain_rev5plus_5ghz[] = {
2550 0x0f62004a, 0x0f620048, 0x0f620046, 0x0f620044,
2551 0x0f620042, 0x0f620040, 0x0f62003e, 0x0f62003c,
2552 0x0e620044, 0x0e620042, 0x0e620040, 0x0e62003e,
2553 0x0e62003c, 0x0e62003d, 0x0e62003b, 0x0e62003a,
2554 0x0d620043, 0x0d620041, 0x0d620040, 0x0d62003e,
2555 0x0d62003d, 0x0d62003c, 0x0d62003b, 0x0d62003a,
2556 0x0c620041, 0x0c620040, 0x0c62003f, 0x0c62003e,
2557 0x0c62003c, 0x0c62003b, 0x0c620039, 0x0c620037,
2558 0x0b620046, 0x0b620044, 0x0b620042, 0x0b620040,
2559 0x0b62003e, 0x0b62003c, 0x0b62003b, 0x0b62003a,
2560 0x0a620041, 0x0a620040, 0x0a62003e, 0x0a62003c,
2561 0x0a62003b, 0x0a62003a, 0x0a620039, 0x0a620038,
2562 0x0962003e, 0x0962003d, 0x0962003c, 0x0962003b,
2563 0x09620039, 0x09620037, 0x09620035, 0x09620033,
2564 0x08620044, 0x08620042, 0x08620040, 0x0862003e,
2565 0x0862003c, 0x0862003b, 0x0862003a, 0x08620039,
2566 0x07620043, 0x07620042, 0x07620040, 0x0762003f,
2567 0x0762003d, 0x0762003b, 0x0762003a, 0x07620039,
2568 0x0662003e, 0x0662003d, 0x0662003c, 0x0662003b,
2569 0x06620039, 0x06620037, 0x06620035, 0x06620033,
2570 0x05620046, 0x05620044, 0x05620042, 0x05620040,
2571 0x0562003e, 0x0562003c, 0x0562003b, 0x05620039,
2572 0x04620044, 0x04620042, 0x04620040, 0x0462003e,
2573 0x0462003c, 0x0462003b, 0x04620039, 0x04620038,
2574 0x0362003c, 0x0362003b, 0x0362003a, 0x03620039,
2575 0x03620038, 0x03620037, 0x03620035, 0x03620033,
2576 0x0262004c, 0x0262004a, 0x02620048, 0x02620047,
2577 0x02620046, 0x02620044, 0x02620043, 0x02620042,
2578 0x0162004a, 0x01620048, 0x01620046, 0x01620044,
2579 0x01620043, 0x01620042, 0x01620041, 0x01620040,
2580 0x00620042, 0x00620040, 0x0062003e, 0x0062003c,
2581 0x0062003b, 0x00620039, 0x00620037, 0x00620035,
2582};
2583
2584const u32 txpwrctrl_tx_gain_ipa[] = {
2585 0x5ff7002d, 0x5ff7002b, 0x5ff7002a, 0x5ff70029,
2586 0x5ff70028, 0x5ff70027, 0x5ff70026, 0x5ff70025,
2587 0x5ef7002d, 0x5ef7002b, 0x5ef7002a, 0x5ef70029,
2588 0x5ef70028, 0x5ef70027, 0x5ef70026, 0x5ef70025,
2589 0x5df7002d, 0x5df7002b, 0x5df7002a, 0x5df70029,
2590 0x5df70028, 0x5df70027, 0x5df70026, 0x5df70025,
2591 0x5cf7002d, 0x5cf7002b, 0x5cf7002a, 0x5cf70029,
2592 0x5cf70028, 0x5cf70027, 0x5cf70026, 0x5cf70025,
2593 0x5bf7002d, 0x5bf7002b, 0x5bf7002a, 0x5bf70029,
2594 0x5bf70028, 0x5bf70027, 0x5bf70026, 0x5bf70025,
2595 0x5af7002d, 0x5af7002b, 0x5af7002a, 0x5af70029,
2596 0x5af70028, 0x5af70027, 0x5af70026, 0x5af70025,
2597 0x59f7002d, 0x59f7002b, 0x59f7002a, 0x59f70029,
2598 0x59f70028, 0x59f70027, 0x59f70026, 0x59f70025,
2599 0x58f7002d, 0x58f7002b, 0x58f7002a, 0x58f70029,
2600 0x58f70028, 0x58f70027, 0x58f70026, 0x58f70025,
2601 0x57f7002d, 0x57f7002b, 0x57f7002a, 0x57f70029,
2602 0x57f70028, 0x57f70027, 0x57f70026, 0x57f70025,
2603 0x56f7002d, 0x56f7002b, 0x56f7002a, 0x56f70029,
2604 0x56f70028, 0x56f70027, 0x56f70026, 0x56f70025,
2605 0x55f7002d, 0x55f7002b, 0x55f7002a, 0x55f70029,
2606 0x55f70028, 0x55f70027, 0x55f70026, 0x55f70025,
2607 0x54f7002d, 0x54f7002b, 0x54f7002a, 0x54f70029,
2608 0x54f70028, 0x54f70027, 0x54f70026, 0x54f70025,
2609 0x53f7002d, 0x53f7002b, 0x53f7002a, 0x53f70029,
2610 0x53f70028, 0x53f70027, 0x53f70026, 0x53f70025,
2611 0x52f7002d, 0x52f7002b, 0x52f7002a, 0x52f70029,
2612 0x52f70028, 0x52f70027, 0x52f70026, 0x52f70025,
2613 0x51f7002d, 0x51f7002b, 0x51f7002a, 0x51f70029,
2614 0x51f70028, 0x51f70027, 0x51f70026, 0x51f70025,
2615 0x50f7002d, 0x50f7002b, 0x50f7002a, 0x50f70029,
2616 0x50f70028, 0x50f70027, 0x50f70026, 0x50f70025,
2617};
2618
2619const u32 txpwrctrl_tx_gain_ipa_rev5[] = {
2620 0x1ff7002d, 0x1ff7002b, 0x1ff7002a, 0x1ff70029,
2621 0x1ff70028, 0x1ff70027, 0x1ff70026, 0x1ff70025,
2622 0x1ef7002d, 0x1ef7002b, 0x1ef7002a, 0x1ef70029,
2623 0x1ef70028, 0x1ef70027, 0x1ef70026, 0x1ef70025,
2624 0x1df7002d, 0x1df7002b, 0x1df7002a, 0x1df70029,
2625 0x1df70028, 0x1df70027, 0x1df70026, 0x1df70025,
2626 0x1cf7002d, 0x1cf7002b, 0x1cf7002a, 0x1cf70029,
2627 0x1cf70028, 0x1cf70027, 0x1cf70026, 0x1cf70025,
2628 0x1bf7002d, 0x1bf7002b, 0x1bf7002a, 0x1bf70029,
2629 0x1bf70028, 0x1bf70027, 0x1bf70026, 0x1bf70025,
2630 0x1af7002d, 0x1af7002b, 0x1af7002a, 0x1af70029,
2631 0x1af70028, 0x1af70027, 0x1af70026, 0x1af70025,
2632 0x19f7002d, 0x19f7002b, 0x19f7002a, 0x19f70029,
2633 0x19f70028, 0x19f70027, 0x19f70026, 0x19f70025,
2634 0x18f7002d, 0x18f7002b, 0x18f7002a, 0x18f70029,
2635 0x18f70028, 0x18f70027, 0x18f70026, 0x18f70025,
2636 0x17f7002d, 0x17f7002b, 0x17f7002a, 0x17f70029,
2637 0x17f70028, 0x17f70027, 0x17f70026, 0x17f70025,
2638 0x16f7002d, 0x16f7002b, 0x16f7002a, 0x16f70029,
2639 0x16f70028, 0x16f70027, 0x16f70026, 0x16f70025,
2640 0x15f7002d, 0x15f7002b, 0x15f7002a, 0x15f70029,
2641 0x15f70028, 0x15f70027, 0x15f70026, 0x15f70025,
2642 0x14f7002d, 0x14f7002b, 0x14f7002a, 0x14f70029,
2643 0x14f70028, 0x14f70027, 0x14f70026, 0x14f70025,
2644 0x13f7002d, 0x13f7002b, 0x13f7002a, 0x13f70029,
2645 0x13f70028, 0x13f70027, 0x13f70026, 0x13f70025,
2646 0x12f7002d, 0x12f7002b, 0x12f7002a, 0x12f70029,
2647 0x12f70028, 0x12f70027, 0x12f70026, 0x12f70025,
2648 0x11f7002d, 0x11f7002b, 0x11f7002a, 0x11f70029,
2649 0x11f70028, 0x11f70027, 0x11f70026, 0x11f70025,
2650 0x10f7002d, 0x10f7002b, 0x10f7002a, 0x10f70029,
2651 0x10f70028, 0x10f70027, 0x10f70026, 0x10f70025,
2652};
2653
2654const u32 txpwrctrl_tx_gain_ipa_rev6[] = {
2655 0x0ff7002d, 0x0ff7002b, 0x0ff7002a, 0x0ff70029,
2656 0x0ff70028, 0x0ff70027, 0x0ff70026, 0x0ff70025,
2657 0x0ef7002d, 0x0ef7002b, 0x0ef7002a, 0x0ef70029,
2658 0x0ef70028, 0x0ef70027, 0x0ef70026, 0x0ef70025,
2659 0x0df7002d, 0x0df7002b, 0x0df7002a, 0x0df70029,
2660 0x0df70028, 0x0df70027, 0x0df70026, 0x0df70025,
2661 0x0cf7002d, 0x0cf7002b, 0x0cf7002a, 0x0cf70029,
2662 0x0cf70028, 0x0cf70027, 0x0cf70026, 0x0cf70025,
2663 0x0bf7002d, 0x0bf7002b, 0x0bf7002a, 0x0bf70029,
2664 0x0bf70028, 0x0bf70027, 0x0bf70026, 0x0bf70025,
2665 0x0af7002d, 0x0af7002b, 0x0af7002a, 0x0af70029,
2666 0x0af70028, 0x0af70027, 0x0af70026, 0x0af70025,
2667 0x09f7002d, 0x09f7002b, 0x09f7002a, 0x09f70029,
2668 0x09f70028, 0x09f70027, 0x09f70026, 0x09f70025,
2669 0x08f7002d, 0x08f7002b, 0x08f7002a, 0x08f70029,
2670 0x08f70028, 0x08f70027, 0x08f70026, 0x08f70025,
2671 0x07f7002d, 0x07f7002b, 0x07f7002a, 0x07f70029,
2672 0x07f70028, 0x07f70027, 0x07f70026, 0x07f70025,
2673 0x06f7002d, 0x06f7002b, 0x06f7002a, 0x06f70029,
2674 0x06f70028, 0x06f70027, 0x06f70026, 0x06f70025,
2675 0x05f7002d, 0x05f7002b, 0x05f7002a, 0x05f70029,
2676 0x05f70028, 0x05f70027, 0x05f70026, 0x05f70025,
2677 0x04f7002d, 0x04f7002b, 0x04f7002a, 0x04f70029,
2678 0x04f70028, 0x04f70027, 0x04f70026, 0x04f70025,
2679 0x03f7002d, 0x03f7002b, 0x03f7002a, 0x03f70029,
2680 0x03f70028, 0x03f70027, 0x03f70026, 0x03f70025,
2681 0x02f7002d, 0x02f7002b, 0x02f7002a, 0x02f70029,
2682 0x02f70028, 0x02f70027, 0x02f70026, 0x02f70025,
2683 0x01f7002d, 0x01f7002b, 0x01f7002a, 0x01f70029,
2684 0x01f70028, 0x01f70027, 0x01f70026, 0x01f70025,
2685 0x00f7002d, 0x00f7002b, 0x00f7002a, 0x00f70029,
2686 0x00f70028, 0x00f70027, 0x00f70026, 0x00f70025,
2687};
2688
2689const u32 txpwrctrl_tx_gain_ipa_5g[] = {
2690 0x7ff70035, 0x7ff70033, 0x7ff70032, 0x7ff70031,
2691 0x7ff7002f, 0x7ff7002e, 0x7ff7002d, 0x7ff7002b,
2692 0x7ff7002a, 0x7ff70029, 0x7ff70028, 0x7ff70027,
2693 0x7ff70026, 0x7ff70024, 0x7ff70023, 0x7ff70022,
2694 0x7ef70028, 0x7ef70027, 0x7ef70026, 0x7ef70025,
2695 0x7ef70024, 0x7ef70023, 0x7df70028, 0x7df70027,
2696 0x7df70026, 0x7df70025, 0x7df70024, 0x7df70023,
2697 0x7df70022, 0x7cf70029, 0x7cf70028, 0x7cf70027,
2698 0x7cf70026, 0x7cf70025, 0x7cf70023, 0x7cf70022,
2699 0x7bf70029, 0x7bf70028, 0x7bf70026, 0x7bf70025,
2700 0x7bf70024, 0x7bf70023, 0x7bf70022, 0x7bf70021,
2701 0x7af70029, 0x7af70028, 0x7af70027, 0x7af70026,
2702 0x7af70025, 0x7af70024, 0x7af70023, 0x7af70022,
2703 0x79f70029, 0x79f70028, 0x79f70027, 0x79f70026,
2704 0x79f70025, 0x79f70024, 0x79f70023, 0x79f70022,
2705 0x78f70029, 0x78f70028, 0x78f70027, 0x78f70026,
2706 0x78f70025, 0x78f70024, 0x78f70023, 0x78f70022,
2707 0x77f70029, 0x77f70028, 0x77f70027, 0x77f70026,
2708 0x77f70025, 0x77f70024, 0x77f70023, 0x77f70022,
2709 0x76f70029, 0x76f70028, 0x76f70027, 0x76f70026,
2710 0x76f70024, 0x76f70023, 0x76f70022, 0x76f70021,
2711 0x75f70029, 0x75f70028, 0x75f70027, 0x75f70026,
2712 0x75f70025, 0x75f70024, 0x75f70023, 0x74f70029,
2713 0x74f70028, 0x74f70026, 0x74f70025, 0x74f70024,
2714 0x74f70023, 0x74f70022, 0x73f70029, 0x73f70027,
2715 0x73f70026, 0x73f70025, 0x73f70024, 0x73f70023,
2716 0x73f70022, 0x72f70028, 0x72f70027, 0x72f70026,
2717 0x72f70025, 0x72f70024, 0x72f70023, 0x72f70022,
2718 0x71f70028, 0x71f70027, 0x71f70026, 0x71f70025,
2719 0x71f70024, 0x71f70023, 0x70f70028, 0x70f70027,
2720 0x70f70026, 0x70f70024, 0x70f70023, 0x70f70022,
2721 0x70f70021, 0x70f70020, 0x70f70020, 0x70f7001f,
2722};
2723
2724const u16 tbl_iqcal_gainparams[2][9][8] = {
2725 {
2726 { 0x000, 0, 0, 2, 0x69, 0x69, 0x69, 0x69 },
2727 { 0x700, 7, 0, 0, 0x69, 0x69, 0x69, 0x69 },
2728 { 0x710, 7, 1, 0, 0x68, 0x68, 0x68, 0x68 },
2729 { 0x720, 7, 2, 0, 0x67, 0x67, 0x67, 0x67 },
2730 { 0x730, 7, 3, 0, 0x66, 0x66, 0x66, 0x66 },
2731 { 0x740, 7, 4, 0, 0x65, 0x65, 0x65, 0x65 },
2732 { 0x741, 7, 4, 1, 0x65, 0x65, 0x65, 0x65 },
2733 { 0x742, 7, 4, 2, 0x65, 0x65, 0x65, 0x65 },
2734 { 0x743, 7, 4, 3, 0x65, 0x65, 0x65, 0x65 }
2735 },
2736 {
2737 { 0x000, 7, 0, 0, 0x79, 0x79, 0x79, 0x79 },
2738 { 0x700, 7, 0, 0, 0x79, 0x79, 0x79, 0x79 },
2739 { 0x710, 7, 1, 0, 0x79, 0x79, 0x79, 0x79 },
2740 { 0x720, 7, 2, 0, 0x78, 0x78, 0x78, 0x78 },
2741 { 0x730, 7, 3, 0, 0x78, 0x78, 0x78, 0x78 },
2742 { 0x740, 7, 4, 0, 0x78, 0x78, 0x78, 0x78 },
2743 { 0x741, 7, 4, 1, 0x78, 0x78, 0x78, 0x78 },
2744 { 0x742, 7, 4, 2, 0x78, 0x78, 0x78, 0x78 },
2745 { 0x743, 7, 4, 3, 0x78, 0x78, 0x78, 0x78 }
2746 }
2747};
2748
2749const struct nphy_txiqcal_ladder ladder_lo[] = {
2750 { 3, 0 },
2751 { 4, 0 },
2752 { 6, 0 },
2753 { 9, 0 },
2754 { 13, 0 },
2755 { 18, 0 },
2756 { 25, 0 },
2757 { 25, 1 },
2758 { 25, 2 },
2759 { 25, 3 },
2760 { 25, 4 },
2761 { 25, 5 },
2762 { 25, 6 },
2763 { 25, 7 },
2764 { 35, 7 },
2765 { 50, 7 },
2766 { 71, 7 },
2767 { 100, 7 }
2768};
2769
2770const struct nphy_txiqcal_ladder ladder_iq[] = {
2771 { 3, 0 },
2772 { 4, 0 },
2773 { 6, 0 },
2774 { 9, 0 },
2775 { 13, 0 },
2776 { 18, 0 },
2777 { 25, 0 },
2778 { 35, 0 },
2779 { 50, 0 },
2780 { 71, 0 },
2781 { 100, 0 },
2782 { 100, 1 },
2783 { 100, 2 },
2784 { 100, 3 },
2785 { 100, 4 },
2786 { 100, 5 },
2787 { 100, 6 },
2788 { 100, 7 }
2789};
2790
2791const u16 loscale[] = {
2792 256, 256, 271, 271,
2793 287, 256, 256, 271,
2794 271, 287, 287, 304,
2795 304, 256, 256, 271,
2796 271, 287, 287, 304,
2797 304, 322, 322, 341,
2798 341, 362, 362, 383,
2799 383, 256, 256, 271,
2800 271, 287, 287, 304,
2801 304, 322, 322, 256,
2802 256, 271, 271, 287,
2803 287, 304, 304, 322,
2804 322, 341, 341, 362,
2805 362, 256, 256, 271,
2806 271, 287, 287, 304,
2807 304, 322, 322, 256,
2808 256, 271, 271, 287,
2809 287, 304, 304, 322,
2810 322, 341, 341, 362,
2811 362, 256, 256, 271,
2812 271, 287, 287, 304,
2813 304, 322, 322, 341,
2814 341, 362, 362, 383,
2815 383, 406, 406, 430,
2816 430, 455, 455, 482,
2817 482, 511, 511, 541,
2818 541, 573, 573, 607,
2819 607, 643, 643, 681,
2820 681, 722, 722, 764,
2821 764, 810, 810, 858,
2822 858, 908, 908, 962,
2823 962, 1019, 1019, 256
2824};
2825
2826const u16 tbl_tx_iqlo_cal_loft_ladder_40[] = {
2827 0x0200, 0x0300, 0x0400, 0x0700,
2828 0x0900, 0x0c00, 0x1200, 0x1201,
2829 0x1202, 0x1203, 0x1204, 0x1205,
2830 0x1206, 0x1207, 0x1907, 0x2307,
2831 0x3207, 0x4707
2832};
2833
2834const u16 tbl_tx_iqlo_cal_loft_ladder_20[] = {
2835 0x0300, 0x0500, 0x0700, 0x0900,
2836 0x0d00, 0x1100, 0x1900, 0x1901,
2837 0x1902, 0x1903, 0x1904, 0x1905,
2838 0x1906, 0x1907, 0x2407, 0x3207,
2839 0x4607, 0x6407
2840};
2841
2842const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[] = {
2843 0x0100, 0x0200, 0x0400, 0x0700,
2844 0x0900, 0x0c00, 0x1200, 0x1900,
2845 0x2300, 0x3200, 0x4700, 0x4701,
2846 0x4702, 0x4703, 0x4704, 0x4705,
2847 0x4706, 0x4707
2848};
2849
2850const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[] = {
2851 0x0200, 0x0300, 0x0600, 0x0900,
2852 0x0d00, 0x1100, 0x1900, 0x2400,
2853 0x3200, 0x4600, 0x6400, 0x6401,
2854 0x6402, 0x6403, 0x6404, 0x6405,
2855 0x6406, 0x6407
2856};
2857
2858const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3] = { };
2859
2860const u16 tbl_tx_iqlo_cal_startcoefs[B43_NTAB_TX_IQLO_CAL_STARTCOEFS] = { };
2861
2862const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[] = {
2863 0x8423, 0x8323, 0x8073, 0x8256,
2864 0x8045, 0x8223, 0x9423, 0x9323,
2865 0x9073, 0x9256, 0x9045, 0x9223
2866};
2867
2868const u16 tbl_tx_iqlo_cal_cmds_recal[] = {
2869 0x8101, 0x8253, 0x8053, 0x8234,
2870 0x8034, 0x9101, 0x9253, 0x9053,
2871 0x9234, 0x9034
2872};
2873
2874const u16 tbl_tx_iqlo_cal_cmds_fullcal[] = {
2875 0x8123, 0x8264, 0x8086, 0x8245,
2876 0x8056, 0x9123, 0x9264, 0x9086,
2877 0x9245, 0x9056
2878};
2879
2880const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[] = {
2881 0x8434, 0x8334, 0x8084, 0x8267,
2882 0x8056, 0x8234, 0x9434, 0x9334,
2883 0x9084, 0x9267, 0x9056, 0x9234
2884};
2885
2409static inline void assert_ntab_array_sizes(void) 2886static inline void assert_ntab_array_sizes(void)
2410{ 2887{
2411#undef check 2888#undef check
@@ -2474,3 +2951,51 @@ void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value)
2474 /* Some compiletime assertions... */ 2951 /* Some compiletime assertions... */
2475 assert_ntab_array_sizes(); 2952 assert_ntab_array_sizes();
2476} 2953}
2954
2955#define ntab_upload(dev, offset, data) do { \
2956 unsigned int i; \
2957 for (i = 0; i < (offset##_SIZE); i++) \
2958 b43_ntab_write(dev, (offset) + i, (data)[i]); \
2959 } while (0)
2960
2961void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev)
2962{
2963 /* Static tables */
2964 ntab_upload(dev, B43_NTAB_FRAMESTRUCT, b43_ntab_framestruct);
2965 ntab_upload(dev, B43_NTAB_FRAMELT, b43_ntab_framelookup);
2966 ntab_upload(dev, B43_NTAB_TMAP, b43_ntab_tmap);
2967 ntab_upload(dev, B43_NTAB_TDTRN, b43_ntab_tdtrn);
2968 ntab_upload(dev, B43_NTAB_INTLEVEL, b43_ntab_intlevel);
2969 ntab_upload(dev, B43_NTAB_PILOT, b43_ntab_pilot);
2970 ntab_upload(dev, B43_NTAB_PILOTLT, b43_ntab_pilotlt);
2971 ntab_upload(dev, B43_NTAB_TDI20A0, b43_ntab_tdi20a0);
2972 ntab_upload(dev, B43_NTAB_TDI20A1, b43_ntab_tdi20a1);
2973 ntab_upload(dev, B43_NTAB_TDI40A0, b43_ntab_tdi40a0);
2974 ntab_upload(dev, B43_NTAB_TDI40A1, b43_ntab_tdi40a1);
2975 ntab_upload(dev, B43_NTAB_BDI, b43_ntab_bdi);
2976 ntab_upload(dev, B43_NTAB_CHANEST, b43_ntab_channelest);
2977 ntab_upload(dev, B43_NTAB_MCS, b43_ntab_mcs);
2978
2979 /* Volatile tables */
2980 ntab_upload(dev, B43_NTAB_NOISEVAR10, b43_ntab_noisevar10);
2981 ntab_upload(dev, B43_NTAB_NOISEVAR11, b43_ntab_noisevar11);
2982 ntab_upload(dev, B43_NTAB_C0_ESTPLT, b43_ntab_estimatepowerlt0);
2983 ntab_upload(dev, B43_NTAB_C1_ESTPLT, b43_ntab_estimatepowerlt1);
2984 ntab_upload(dev, B43_NTAB_C0_ADJPLT, b43_ntab_adjustpower0);
2985 ntab_upload(dev, B43_NTAB_C1_ADJPLT, b43_ntab_adjustpower1);
2986 ntab_upload(dev, B43_NTAB_C0_GAINCTL, b43_ntab_gainctl0);
2987 ntab_upload(dev, B43_NTAB_C1_GAINCTL, b43_ntab_gainctl1);
2988 ntab_upload(dev, B43_NTAB_C0_IQLT, b43_ntab_iqlt0);
2989 ntab_upload(dev, B43_NTAB_C1_IQLT, b43_ntab_iqlt1);
2990 ntab_upload(dev, B43_NTAB_C0_LOFEEDTH, b43_ntab_loftlt0);
2991 ntab_upload(dev, B43_NTAB_C1_LOFEEDTH, b43_ntab_loftlt1);
2992}
2993
2994void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev)
2995{
2996 /* Static tables */
2997 /* TODO */
2998
2999 /* Volatile tables */
3000 /* TODO */
3001}
diff --git a/drivers/net/wireless/b43/tables_nphy.h b/drivers/net/wireless/b43/tables_nphy.h
index 4d498b053ec7..51636d02f8b1 100644
--- a/drivers/net/wireless/b43/tables_nphy.h
+++ b/drivers/net/wireless/b43/tables_nphy.h
@@ -46,6 +46,11 @@ struct b43_nphy_channeltab_entry {
46 46
47struct b43_wldev; 47struct b43_wldev;
48 48
49struct nphy_txiqcal_ladder {
50 u8 percent;
51 u8 g_env;
52};
53
49/* Upload the default register value table. 54/* Upload the default register value table.
50 * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz 55 * If "ghz5" is true, we upload the 5Ghz table. Otherwise the 2.4Ghz
51 * table is uploaded. If "ignore_uploadflag" is true, we upload any value 56 * table is uploaded. If "ignore_uploadflag" is true, we upload any value
@@ -126,34 +131,46 @@ b43_nphy_get_chantabent(struct b43_wldev *dev, u8 channel);
126#define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */ 131#define B43_NTAB_C1_LOFEEDTH B43_NTAB16(0x1B, 0x1C0) /* Local Oscillator Feed Through Lookup Table Core 1 */
127#define B43_NTAB_C1_LOFEEDTH_SIZE 128 132#define B43_NTAB_C1_LOFEEDTH_SIZE 128
128 133
129void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value); 134#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_40_SIZE 18
135#define B43_NTAB_TX_IQLO_CAL_LOFT_LADDER_20_SIZE 18
136#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_40_SIZE 18
137#define B43_NTAB_TX_IQLO_CAL_IQIMB_LADDER_20_SIZE 18
138#define B43_NTAB_TX_IQLO_CAL_STARTCOEFS_REV3 11
139#define B43_NTAB_TX_IQLO_CAL_STARTCOEFS 9
140#define B43_NTAB_TX_IQLO_CAL_CMDS_RECAL_REV3 12
141#define B43_NTAB_TX_IQLO_CAL_CMDS_RECAL 10
142#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL 10
143#define B43_NTAB_TX_IQLO_CAL_CMDS_FULLCAL_REV3 12
130 144
131extern const u8 b43_ntab_adjustpower0[]; 145void b43_ntab_write(struct b43_wldev *dev, u32 offset, u32 value);
132extern const u8 b43_ntab_adjustpower1[];
133extern const u16 b43_ntab_bdi[];
134extern const u32 b43_ntab_channelest[];
135extern const u8 b43_ntab_estimatepowerlt0[];
136extern const u8 b43_ntab_estimatepowerlt1[];
137extern const u8 b43_ntab_framelookup[];
138extern const u32 b43_ntab_framestruct[];
139extern const u32 b43_ntab_gainctl0[];
140extern const u32 b43_ntab_gainctl1[];
141extern const u32 b43_ntab_intlevel[];
142extern const u32 b43_ntab_iqlt0[];
143extern const u32 b43_ntab_iqlt1[];
144extern const u16 b43_ntab_loftlt0[];
145extern const u16 b43_ntab_loftlt1[];
146extern const u8 b43_ntab_mcs[];
147extern const u32 b43_ntab_noisevar10[];
148extern const u32 b43_ntab_noisevar11[];
149extern const u16 b43_ntab_pilot[];
150extern const u32 b43_ntab_pilotlt[];
151extern const u32 b43_ntab_tdi20a0[];
152extern const u32 b43_ntab_tdi20a1[];
153extern const u32 b43_ntab_tdi40a0[];
154extern const u32 b43_ntab_tdi40a1[];
155extern const u32 b43_ntab_tdtrn[];
156extern const u32 b43_ntab_tmap[];
157 146
147void b43_nphy_rev0_1_2_tables_init(struct b43_wldev *dev);
148void b43_nphy_rev3plus_tables_init(struct b43_wldev *dev);
149
150extern const u32 b43_ntab_tx_gain_rev0_1_2[];
151extern const u32 b43_ntab_tx_gain_rev3plus_2ghz[];
152extern const u32 b43_ntab_tx_gain_rev3_5ghz[];
153extern const u32 b43_ntab_tx_gain_rev4_5ghz[];
154extern const u32 b43_ntab_tx_gain_rev5plus_5ghz[];
155
156extern const u32 txpwrctrl_tx_gain_ipa[];
157extern const u32 txpwrctrl_tx_gain_ipa_rev5[];
158extern const u32 txpwrctrl_tx_gain_ipa_rev6[];
159extern const u32 txpwrctrl_tx_gain_ipa_5g[];
160extern const u16 tbl_iqcal_gainparams[2][9][8];
161extern const struct nphy_txiqcal_ladder ladder_lo[];
162extern const struct nphy_txiqcal_ladder ladder_iq[];
163extern const u16 loscale[];
164
165extern const u16 tbl_tx_iqlo_cal_loft_ladder_40[];
166extern const u16 tbl_tx_iqlo_cal_loft_ladder_20[];
167extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_40[];
168extern const u16 tbl_tx_iqlo_cal_iqimb_ladder_20[];
169extern const u16 tbl_tx_iqlo_cal_startcoefs_nphyrev3[];
170extern const u16 tbl_tx_iqlo_cal_startcoefs[];
171extern const u16 tbl_tx_iqlo_cal_cmds_recal_nphyrev3[];
172extern const u16 tbl_tx_iqlo_cal_cmds_recal[];
173extern const u16 tbl_tx_iqlo_cal_cmds_fullcal[];
174extern const u16 tbl_tx_iqlo_cal_cmds_fullcal_nphyrev3[];
158 175
159#endif /* B43_TABLES_NPHY_H_ */ 176#endif /* B43_TABLES_NPHY_H_ */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index fbae264095cc..874a64a6c610 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -61,6 +61,8 @@ MODULE_AUTHOR("Michael Buesch");
61MODULE_LICENSE("GPL"); 61MODULE_LICENSE("GPL");
62 62
63MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID); 63MODULE_FIRMWARE(B43legacy_SUPPORTED_FIRMWARE_ID);
64MODULE_FIRMWARE("b43legacy/ucode2.fw");
65MODULE_FIRMWARE("b43legacy/ucode4.fw");
64 66
65#if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO) 67#if defined(CONFIG_B43LEGACY_DMA) && defined(CONFIG_B43LEGACY_PIO)
66static int modparam_pio; 68static int modparam_pio;
@@ -3960,7 +3962,7 @@ static struct ssb_driver b43legacy_ssb_driver = {
3960 3962
3961static void b43legacy_print_driverinfo(void) 3963static void b43legacy_print_driverinfo(void)
3962{ 3964{
3963 const char *feat_pci = "", *feat_leds = "", *feat_rfkill = "", 3965 const char *feat_pci = "", *feat_leds = "",
3964 *feat_pio = "", *feat_dma = ""; 3966 *feat_pio = "", *feat_dma = "";
3965 3967
3966#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT 3968#ifdef CONFIG_B43LEGACY_PCI_AUTOSELECT
@@ -3969,9 +3971,6 @@ static void b43legacy_print_driverinfo(void)
3969#ifdef CONFIG_B43LEGACY_LEDS 3971#ifdef CONFIG_B43LEGACY_LEDS
3970 feat_leds = "L"; 3972 feat_leds = "L";
3971#endif 3973#endif
3972#ifdef CONFIG_B43LEGACY_RFKILL
3973 feat_rfkill = "R";
3974#endif
3975#ifdef CONFIG_B43LEGACY_PIO 3974#ifdef CONFIG_B43LEGACY_PIO
3976 feat_pio = "I"; 3975 feat_pio = "I";
3977#endif 3976#endif
@@ -3979,9 +3978,9 @@ static void b43legacy_print_driverinfo(void)
3979 feat_dma = "D"; 3978 feat_dma = "D";
3980#endif 3979#endif
3981 printk(KERN_INFO "Broadcom 43xx-legacy driver loaded " 3980 printk(KERN_INFO "Broadcom 43xx-legacy driver loaded "
3982 "[ Features: %s%s%s%s%s, Firmware-ID: " 3981 "[ Features: %s%s%s%s, Firmware-ID: "
3983 B43legacy_SUPPORTED_FIRMWARE_ID " ]\n", 3982 B43legacy_SUPPORTED_FIRMWARE_ID " ]\n",
3984 feat_pci, feat_leds, feat_rfkill, feat_pio, feat_dma); 3983 feat_pci, feat_leds, feat_pio, feat_dma);
3985} 3984}
3986 3985
3987static int __init b43legacy_init(void) 3986static int __init b43legacy_init(void)
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 78706ce8b7ae..cee368d4859f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -1961,7 +1961,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
1961 struct ieee80211_tx_info *info; 1961 struct ieee80211_tx_info *info;
1962 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0]; 1962 struct iwl4965_tx_resp *tx_resp = (void *)&pkt->u.raw[0];
1963 u32 status = le32_to_cpu(tx_resp->u.status); 1963 u32 status = le32_to_cpu(tx_resp->u.status);
1964 int tid = MAX_TID_COUNT; 1964 int tid = MAX_TID_COUNT - 1;
1965 int sta_id; 1965 int sta_id;
1966 int freed; 1966 int freed;
1967 u8 *qc = NULL; 1967 u8 *qc = NULL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index ec6b27689fa8..c3f8ec0a38b1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -781,7 +781,7 @@ void iwl5000_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
781 781
782 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent; 782 scd_bc_tbl[txq_id].tfd_offset[write_ptr] = bc_ent;
783 783
784 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 784 if (write_ptr < TFD_QUEUE_SIZE_BC_DUP)
785 scd_bc_tbl[txq_id]. 785 scd_bc_tbl[txq_id].
786 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent; 786 tfd_offset[TFD_QUEUE_SIZE_MAX + write_ptr] = bc_ent;
787} 787}
@@ -800,12 +800,12 @@ void iwl5000_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
800 if (txq_id != IWL_CMD_QUEUE_NUM) 800 if (txq_id != IWL_CMD_QUEUE_NUM)
801 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; 801 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
802 802
803 bc_ent = cpu_to_le16(1 | (sta_id << 12)); 803 bc_ent = cpu_to_le16(1 | (sta_id << 12));
804 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent; 804 scd_bc_tbl[txq_id].tfd_offset[read_ptr] = bc_ent;
805 805
806 if (txq->q.write_ptr < TFD_QUEUE_SIZE_BC_DUP) 806 if (read_ptr < TFD_QUEUE_SIZE_BC_DUP)
807 scd_bc_tbl[txq_id]. 807 scd_bc_tbl[txq_id].
808 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent; 808 tfd_offset[TFD_QUEUE_SIZE_MAX + read_ptr] = bc_ent;
809} 809}
810 810
811static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid, 811static int iwl5000_tx_queue_set_q2ratid(struct iwl_priv *priv, u16 ra_tid,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index c8fec626b714..344e99de4cab 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2955,6 +2955,9 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
2955 return 0; 2955 return 0;
2956 else 2956 else
2957 return ret; 2957 return ret;
2958 case IEEE80211_AMPDU_TX_OPERATIONAL:
2959 /* do nothing */
2960 return -EOPNOTSUPP;
2958 default: 2961 default:
2959 IWL_DEBUG_HT(priv, "unknown\n"); 2962 IWL_DEBUG_HT(priv, "unknown\n");
2960 return -EINVAL; 2963 return -EINVAL;
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 28f3800c560e..3320cce3d57b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -120,7 +120,6 @@ enum {
120 CALIBRATION_COMPLETE_NOTIFICATION = 0x67, 120 CALIBRATION_COMPLETE_NOTIFICATION = 0x67,
121 121
122 /* 802.11h related */ 122 /* 802.11h related */
123 RADAR_NOTIFICATION = 0x70, /* not used */
124 REPLY_QUIET_CMD = 0x71, /* not used */ 123 REPLY_QUIET_CMD = 0x71, /* not used */
125 REPLY_CHANNEL_SWITCH = 0x72, 124 REPLY_CHANNEL_SWITCH = 0x72,
126 CHANNEL_SWITCH_NOTIFICATION = 0x73, 125 CHANNEL_SWITCH_NOTIFICATION = 0x73,
@@ -2984,7 +2983,7 @@ struct statistics_rx_ht_phy {
2984 __le32 agg_crc32_good; 2983 __le32 agg_crc32_good;
2985 __le32 agg_mpdu_cnt; 2984 __le32 agg_mpdu_cnt;
2986 __le32 agg_cnt; 2985 __le32 agg_cnt;
2987 __le32 reserved2; 2986 __le32 unsupport_mcs;
2988} __attribute__ ((packed)); 2987} __attribute__ ((packed));
2989 2988
2990#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1) 2989#define INTERFERENCE_DATA_AVAILABLE cpu_to_le32(1)
@@ -3087,8 +3086,8 @@ struct statistics_div {
3087} __attribute__ ((packed)); 3086} __attribute__ ((packed));
3088 3087
3089struct statistics_general { 3088struct statistics_general {
3090 __le32 temperature; 3089 __le32 temperature; /* radio temperature */
3091 __le32 temperature_m; 3090 __le32 temperature_m; /* for 5000 and up, this is radio voltage */
3092 struct statistics_dbg dbg; 3091 struct statistics_dbg dbg;
3093 __le32 sleep_time; 3092 __le32 sleep_time;
3094 __le32 slots_out; 3093 __le32 slots_out;
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 3ef86f6c7755..8deb83bfe182 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -63,8 +63,6 @@
63#ifndef __iwl_core_h__ 63#ifndef __iwl_core_h__
64#define __iwl_core_h__ 64#define __iwl_core_h__
65 65
66#include <generated/utsrelease.h>
67
68/************************ 66/************************
69 * forward declarations * 67 * forward declarations *
70 ************************/ 68 ************************/
@@ -72,7 +70,7 @@ struct iwl_host_cmd;
72struct iwl_cmd; 70struct iwl_cmd;
73 71
74 72
75#define IWLWIFI_VERSION UTS_RELEASE "-k" 73#define IWLWIFI_VERSION "in-tree:"
76#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation" 74#define DRV_COPYRIGHT "Copyright(c) 2003-2009 Intel Corporation"
77#define DRV_AUTHOR "<ilw@linux.intel.com>" 75#define DRV_AUTHOR "<ilw@linux.intel.com>"
78 76
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index ee5aed12a4b1..4a2ac9311ba8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -125,7 +125,7 @@ static ssize_t iwl_dbgfs_tx_statistics_read(struct file *file,
125 char __user *user_buf, 125 char __user *user_buf,
126 size_t count, loff_t *ppos) { 126 size_t count, loff_t *ppos) {
127 127
128 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 128 struct iwl_priv *priv = file->private_data;
129 char *buf; 129 char *buf;
130 int pos = 0; 130 int pos = 0;
131 131
@@ -184,7 +184,7 @@ static ssize_t iwl_dbgfs_rx_statistics_read(struct file *file,
184 char __user *user_buf, 184 char __user *user_buf,
185 size_t count, loff_t *ppos) { 185 size_t count, loff_t *ppos) {
186 186
187 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 187 struct iwl_priv *priv = file->private_data;
188 char *buf; 188 char *buf;
189 int pos = 0; 189 int pos = 0;
190 int cnt; 190 int cnt;
@@ -232,7 +232,7 @@ static ssize_t iwl_dbgfs_sram_read(struct file *file,
232 ssize_t ret; 232 ssize_t ret;
233 int i; 233 int i;
234 int pos = 0; 234 int pos = 0;
235 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 235 struct iwl_priv *priv = file->private_data;
236 size_t bufsz; 236 size_t bufsz;
237 237
238 /* default is to dump the entire data segment */ 238 /* default is to dump the entire data segment */
@@ -306,7 +306,7 @@ static ssize_t iwl_dbgfs_sram_write(struct file *file,
306static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf, 306static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
307 size_t count, loff_t *ppos) 307 size_t count, loff_t *ppos)
308{ 308{
309 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 309 struct iwl_priv *priv = file->private_data;
310 struct iwl_station_entry *station; 310 struct iwl_station_entry *station;
311 int max_sta = priv->hw_params.max_stations; 311 int max_sta = priv->hw_params.max_stations;
312 char *buf; 312 char *buf;
@@ -376,7 +376,7 @@ static ssize_t iwl_dbgfs_nvm_read(struct file *file,
376 loff_t *ppos) 376 loff_t *ppos)
377{ 377{
378 ssize_t ret; 378 ssize_t ret;
379 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 379 struct iwl_priv *priv = file->private_data;
380 int pos = 0, ofs = 0, buf_size = 0; 380 int pos = 0, ofs = 0, buf_size = 0;
381 const u8 *ptr; 381 const u8 *ptr;
382 char *buf; 382 char *buf;
@@ -464,7 +464,7 @@ static ssize_t iwl_dbgfs_log_event_write(struct file *file,
464static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf, 464static ssize_t iwl_dbgfs_channels_read(struct file *file, char __user *user_buf,
465 size_t count, loff_t *ppos) 465 size_t count, loff_t *ppos)
466{ 466{
467 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 467 struct iwl_priv *priv = file->private_data;
468 struct ieee80211_channel *channels = NULL; 468 struct ieee80211_channel *channels = NULL;
469 const struct ieee80211_supported_band *supp_band = NULL; 469 const struct ieee80211_supported_band *supp_band = NULL;
470 int pos = 0, i, bufsz = PAGE_SIZE; 470 int pos = 0, i, bufsz = PAGE_SIZE;
@@ -537,7 +537,7 @@ static ssize_t iwl_dbgfs_status_read(struct file *file,
537 char __user *user_buf, 537 char __user *user_buf,
538 size_t count, loff_t *ppos) { 538 size_t count, loff_t *ppos) {
539 539
540 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 540 struct iwl_priv *priv = file->private_data;
541 char buf[512]; 541 char buf[512];
542 int pos = 0; 542 int pos = 0;
543 const size_t bufsz = sizeof(buf); 543 const size_t bufsz = sizeof(buf);
@@ -585,7 +585,7 @@ static ssize_t iwl_dbgfs_interrupt_read(struct file *file,
585 char __user *user_buf, 585 char __user *user_buf,
586 size_t count, loff_t *ppos) { 586 size_t count, loff_t *ppos) {
587 587
588 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 588 struct iwl_priv *priv = file->private_data;
589 int pos = 0; 589 int pos = 0;
590 int cnt = 0; 590 int cnt = 0;
591 char *buf; 591 char *buf;
@@ -672,7 +672,7 @@ static ssize_t iwl_dbgfs_interrupt_write(struct file *file,
672static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf, 672static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
673 size_t count, loff_t *ppos) 673 size_t count, loff_t *ppos)
674{ 674{
675 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 675 struct iwl_priv *priv = file->private_data;
676 int pos = 0, i; 676 int pos = 0, i;
677 char buf[256]; 677 char buf[256];
678 const size_t bufsz = sizeof(buf); 678 const size_t bufsz = sizeof(buf);
@@ -695,7 +695,7 @@ static ssize_t iwl_dbgfs_qos_read(struct file *file, char __user *user_buf,
695static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf, 695static ssize_t iwl_dbgfs_led_read(struct file *file, char __user *user_buf,
696 size_t count, loff_t *ppos) 696 size_t count, loff_t *ppos)
697{ 697{
698 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 698 struct iwl_priv *priv = file->private_data;
699 int pos = 0; 699 int pos = 0;
700 char buf[256]; 700 char buf[256];
701 const size_t bufsz = sizeof(buf); 701 const size_t bufsz = sizeof(buf);
@@ -721,7 +721,7 @@ static ssize_t iwl_dbgfs_thermal_throttling_read(struct file *file,
721 char __user *user_buf, 721 char __user *user_buf,
722 size_t count, loff_t *ppos) 722 size_t count, loff_t *ppos)
723{ 723{
724 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 724 struct iwl_priv *priv = file->private_data;
725 struct iwl_tt_mgmt *tt = &priv->thermal_throttle; 725 struct iwl_tt_mgmt *tt = &priv->thermal_throttle;
726 struct iwl_tt_restriction *restriction; 726 struct iwl_tt_restriction *restriction;
727 char buf[100]; 727 char buf[100];
@@ -781,7 +781,7 @@ static ssize_t iwl_dbgfs_disable_ht40_read(struct file *file,
781 char __user *user_buf, 781 char __user *user_buf,
782 size_t count, loff_t *ppos) 782 size_t count, loff_t *ppos)
783{ 783{
784 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 784 struct iwl_priv *priv = file->private_data;
785 char buf[100]; 785 char buf[100];
786 int pos = 0; 786 int pos = 0;
787 const size_t bufsz = sizeof(buf); 787 const size_t bufsz = sizeof(buf);
@@ -838,7 +838,7 @@ static ssize_t iwl_dbgfs_sleep_level_override_read(struct file *file,
838 char __user *user_buf, 838 char __user *user_buf,
839 size_t count, loff_t *ppos) 839 size_t count, loff_t *ppos)
840{ 840{
841 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 841 struct iwl_priv *priv = file->private_data;
842 char buf[10]; 842 char buf[10];
843 int pos, value; 843 int pos, value;
844 const size_t bufsz = sizeof(buf); 844 const size_t bufsz = sizeof(buf);
@@ -856,7 +856,7 @@ static ssize_t iwl_dbgfs_current_sleep_command_read(struct file *file,
856 char __user *user_buf, 856 char __user *user_buf,
857 size_t count, loff_t *ppos) 857 size_t count, loff_t *ppos)
858{ 858{
859 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 859 struct iwl_priv *priv = file->private_data;
860 char buf[200]; 860 char buf[200];
861 int pos = 0, i; 861 int pos = 0, i;
862 const size_t bufsz = sizeof(buf); 862 const size_t bufsz = sizeof(buf);
@@ -994,7 +994,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
994 char __user *user_buf, 994 char __user *user_buf,
995 size_t count, loff_t *ppos) { 995 size_t count, loff_t *ppos) {
996 996
997 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 997 struct iwl_priv *priv = file->private_data;
998 struct iwl_tx_queue *txq; 998 struct iwl_tx_queue *txq;
999 struct iwl_queue *q; 999 struct iwl_queue *q;
1000 char *buf; 1000 char *buf;
@@ -1040,7 +1040,7 @@ static ssize_t iwl_dbgfs_rx_queue_read(struct file *file,
1040 char __user *user_buf, 1040 char __user *user_buf,
1041 size_t count, loff_t *ppos) { 1041 size_t count, loff_t *ppos) {
1042 1042
1043 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1043 struct iwl_priv *priv = file->private_data;
1044 struct iwl_rx_queue *rxq = &priv->rxq; 1044 struct iwl_rx_queue *rxq = &priv->rxq;
1045 char buf[256]; 1045 char buf[256];
1046 int pos = 0; 1046 int pos = 0;
@@ -1086,7 +1086,7 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1086 char __user *user_buf, 1086 char __user *user_buf,
1087 size_t count, loff_t *ppos) 1087 size_t count, loff_t *ppos)
1088{ 1088{
1089 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1089 struct iwl_priv *priv = file->private_data;
1090 int pos = 0; 1090 int pos = 0;
1091 char *buf; 1091 char *buf;
1092 int bufsz = sizeof(struct statistics_rx_phy) * 20 + 1092 int bufsz = sizeof(struct statistics_rx_phy) * 20 +
@@ -1387,6 +1387,9 @@ static ssize_t iwl_dbgfs_ucode_rx_stats_read(struct file *file,
1387 accum_ht->agg_mpdu_cnt); 1387 accum_ht->agg_mpdu_cnt);
1388 pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n", 1388 pos += scnprintf(buf + pos, bufsz - pos, "agg_cnt:\t\t%u\t\t\t%u\n",
1389 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt); 1389 le32_to_cpu(ht->agg_cnt), accum_ht->agg_cnt);
1390 pos += scnprintf(buf + pos, bufsz - pos, "unsupport_mcs:\t\t%u\t\t\t%u\n",
1391 le32_to_cpu(ht->unsupport_mcs),
1392 accum_ht->unsupport_mcs);
1390 1393
1391 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1394 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
1392 kfree(buf); 1395 kfree(buf);
@@ -1397,7 +1400,7 @@ static ssize_t iwl_dbgfs_ucode_tx_stats_read(struct file *file,
1397 char __user *user_buf, 1400 char __user *user_buf,
1398 size_t count, loff_t *ppos) 1401 size_t count, loff_t *ppos)
1399{ 1402{
1400 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1403 struct iwl_priv *priv = file->private_data;
1401 int pos = 0; 1404 int pos = 0;
1402 char *buf; 1405 char *buf;
1403 int bufsz = (sizeof(struct statistics_tx) * 24) + 250; 1406 int bufsz = (sizeof(struct statistics_tx) * 24) + 250;
@@ -1539,7 +1542,7 @@ static ssize_t iwl_dbgfs_ucode_general_stats_read(struct file *file,
1539 char __user *user_buf, 1542 char __user *user_buf,
1540 size_t count, loff_t *ppos) 1543 size_t count, loff_t *ppos)
1541{ 1544{
1542 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1545 struct iwl_priv *priv = file->private_data;
1543 int pos = 0; 1546 int pos = 0;
1544 char *buf; 1547 char *buf;
1545 int bufsz = sizeof(struct statistics_general) * 4 + 250; 1548 int bufsz = sizeof(struct statistics_general) * 4 + 250;
@@ -1630,7 +1633,7 @@ static ssize_t iwl_dbgfs_sensitivity_read(struct file *file,
1630 char __user *user_buf, 1633 char __user *user_buf,
1631 size_t count, loff_t *ppos) { 1634 size_t count, loff_t *ppos) {
1632 1635
1633 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1636 struct iwl_priv *priv = file->private_data;
1634 int pos = 0; 1637 int pos = 0;
1635 int cnt = 0; 1638 int cnt = 0;
1636 char *buf; 1639 char *buf;
@@ -1711,7 +1714,7 @@ static ssize_t iwl_dbgfs_chain_noise_read(struct file *file,
1711 char __user *user_buf, 1714 char __user *user_buf,
1712 size_t count, loff_t *ppos) { 1715 size_t count, loff_t *ppos) {
1713 1716
1714 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1717 struct iwl_priv *priv = file->private_data;
1715 int pos = 0; 1718 int pos = 0;
1716 int cnt = 0; 1719 int cnt = 0;
1717 char *buf; 1720 char *buf;
@@ -1769,7 +1772,7 @@ static ssize_t iwl_dbgfs_tx_power_read(struct file *file,
1769 char __user *user_buf, 1772 char __user *user_buf,
1770 size_t count, loff_t *ppos) { 1773 size_t count, loff_t *ppos) {
1771 1774
1772 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1775 struct iwl_priv *priv = file->private_data;
1773 char buf[128]; 1776 char buf[128];
1774 int pos = 0; 1777 int pos = 0;
1775 ssize_t ret; 1778 ssize_t ret;
@@ -1820,7 +1823,7 @@ static ssize_t iwl_dbgfs_power_save_status_read(struct file *file,
1820 char __user *user_buf, 1823 char __user *user_buf,
1821 size_t count, loff_t *ppos) 1824 size_t count, loff_t *ppos)
1822{ 1825{
1823 struct iwl_priv *priv = (struct iwl_priv *)file->private_data; 1826 struct iwl_priv *priv = file->private_data;
1824 char buf[60]; 1827 char buf[60];
1825 int pos = 0; 1828 int pos = 0;
1826 const size_t bufsz = sizeof(buf); 1829 const size_t bufsz = sizeof(buf);
diff --git a/drivers/net/wireless/iwlwifi/iwl-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
index 30e9ea6d54ec..87d684efe110 100644
--- a/drivers/net/wireless/iwlwifi/iwl-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-hcmd.c
@@ -58,7 +58,6 @@ const char *get_cmd_string(u8 cmd)
58 IWL_CMD(COEX_PRIORITY_TABLE_CMD); 58 IWL_CMD(COEX_PRIORITY_TABLE_CMD);
59 IWL_CMD(COEX_MEDIUM_NOTIFICATION); 59 IWL_CMD(COEX_MEDIUM_NOTIFICATION);
60 IWL_CMD(COEX_EVENT_CMD); 60 IWL_CMD(COEX_EVENT_CMD);
61 IWL_CMD(RADAR_NOTIFICATION);
62 IWL_CMD(REPLY_QUIET_CMD); 61 IWL_CMD(REPLY_QUIET_CMD);
63 IWL_CMD(REPLY_CHANNEL_SWITCH); 62 IWL_CMD(REPLY_CHANNEL_SWITCH);
64 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION); 63 IWL_CMD(CHANNEL_SWITCH_NOTIFICATION);
diff --git a/drivers/net/wireless/iwmc3200wifi/iwm.h b/drivers/net/wireless/iwmc3200wifi/iwm.h
index 842811142bef..79ffa3b98d73 100644
--- a/drivers/net/wireless/iwmc3200wifi/iwm.h
+++ b/drivers/net/wireless/iwmc3200wifi/iwm.h
@@ -268,7 +268,7 @@ struct iwm_priv {
268 268
269 struct sk_buff_head rx_list; 269 struct sk_buff_head rx_list;
270 struct list_head rx_tickets; 270 struct list_head rx_tickets;
271 struct list_head rx_packets[IWM_RX_ID_HASH + 1]; 271 struct list_head rx_packets[IWM_RX_ID_HASH];
272 struct workqueue_struct *rx_wq; 272 struct workqueue_struct *rx_wq;
273 struct work_struct rx_worker; 273 struct work_struct rx_worker;
274 274
diff --git a/drivers/net/wireless/mwl8k.c b/drivers/net/wireless/mwl8k.c
index c1c6ecd0c5b3..68546ca0ba37 100644
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -2,7 +2,7 @@
2 * drivers/net/wireless/mwl8k.c 2 * drivers/net/wireless/mwl8k.c
3 * Driver for Marvell TOPDOG 802.11 Wireless cards 3 * Driver for Marvell TOPDOG 802.11 Wireless cards
4 * 4 *
5 * Copyright (C) 2008-2009 Marvell Semiconductor Inc. 5 * Copyright (C) 2008, 2009, 2010 Marvell Semiconductor Inc.
6 * 6 *
7 * This file is licensed under the terms of the GNU General Public 7 * This file is licensed under the terms of the GNU General Public
8 * License version 2. This program is licensed "as is" without any 8 * License version 2. This program is licensed "as is" without any
@@ -26,7 +26,7 @@
26 26
27#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver" 27#define MWL8K_DESC "Marvell TOPDOG(R) 802.11 Wireless Network Driver"
28#define MWL8K_NAME KBUILD_MODNAME 28#define MWL8K_NAME KBUILD_MODNAME
29#define MWL8K_VERSION "0.10" 29#define MWL8K_VERSION "0.12"
30 30
31/* Register definitions */ 31/* Register definitions */
32#define MWL8K_HIU_GEN_PTR 0x00000c10 32#define MWL8K_HIU_GEN_PTR 0x00000c10
@@ -141,6 +141,14 @@ struct mwl8k_priv {
141 /* hardware/firmware parameters */ 141 /* hardware/firmware parameters */
142 bool ap_fw; 142 bool ap_fw;
143 struct rxd_ops *rxd_ops; 143 struct rxd_ops *rxd_ops;
144 struct ieee80211_supported_band band_24;
145 struct ieee80211_channel channels_24[14];
146 struct ieee80211_rate rates_24[14];
147 struct ieee80211_supported_band band_50;
148 struct ieee80211_channel channels_50[4];
149 struct ieee80211_rate rates_50[9];
150 u32 ap_macids_supported;
151 u32 sta_macids_supported;
144 152
145 /* firmware access */ 153 /* firmware access */
146 struct mutex fw_mutex; 154 struct mutex fw_mutex;
@@ -154,9 +162,9 @@ struct mwl8k_priv {
154 /* TX quiesce completion, protected by fw_mutex and tx_lock */ 162 /* TX quiesce completion, protected by fw_mutex and tx_lock */
155 struct completion *tx_wait; 163 struct completion *tx_wait;
156 164
157 struct ieee80211_vif *vif; 165 /* List of interfaces. */
158 166 u32 macids_used;
159 struct ieee80211_channel *current_channel; 167 struct list_head vif_list;
160 168
161 /* power management status cookie from firmware */ 169 /* power management status cookie from firmware */
162 u32 *cookie; 170 u32 *cookie;
@@ -175,16 +183,15 @@ struct mwl8k_priv {
175 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES]; 183 struct mwl8k_rx_queue rxq[MWL8K_RX_QUEUES];
176 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES]; 184 struct mwl8k_tx_queue txq[MWL8K_TX_QUEUES];
177 185
178 /* PHY parameters */
179 struct ieee80211_supported_band band;
180 struct ieee80211_channel channels[14];
181 struct ieee80211_rate rates[14];
182
183 bool radio_on; 186 bool radio_on;
184 bool radio_short_preamble; 187 bool radio_short_preamble;
185 bool sniffer_enabled; 188 bool sniffer_enabled;
186 bool wmm_enabled; 189 bool wmm_enabled;
187 190
191 struct work_struct sta_notify_worker;
192 spinlock_t sta_notify_list_lock;
193 struct list_head sta_notify_list;
194
188 /* XXX need to convert this to handle multiple interfaces */ 195 /* XXX need to convert this to handle multiple interfaces */
189 bool capture_beacon; 196 bool capture_beacon;
190 u8 capture_bssid[ETH_ALEN]; 197 u8 capture_bssid[ETH_ALEN];
@@ -198,28 +205,33 @@ struct mwl8k_priv {
198 */ 205 */
199 struct work_struct finalize_join_worker; 206 struct work_struct finalize_join_worker;
200 207
201 /* Tasklet to reclaim TX descriptors and buffers after tx */ 208 /* Tasklet to perform TX reclaim. */
202 struct tasklet_struct tx_reclaim_task; 209 struct tasklet_struct poll_tx_task;
210
211 /* Tasklet to perform RX. */
212 struct tasklet_struct poll_rx_task;
203}; 213};
204 214
205/* Per interface specific private data */ 215/* Per interface specific private data */
206struct mwl8k_vif { 216struct mwl8k_vif {
207 /* Local MAC address. */ 217 struct list_head list;
208 u8 mac_addr[ETH_ALEN]; 218 struct ieee80211_vif *vif;
209
210 /* BSSID of AP. */
211 u8 bssid[ETH_ALEN];
212 219
213 /* Index into station database. Returned by UPDATE_STADB. */ 220 /* Firmware macid for this vif. */
214 u8 peer_id; 221 int macid;
215 222
216 /* Non AMPDU sequence number assigned by driver */ 223 /* Non AMPDU sequence number assigned by driver. */
217 u16 seqno; 224 u16 seqno;
218}; 225};
219
220#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv)) 226#define MWL8K_VIF(_vif) ((struct mwl8k_vif *)&((_vif)->drv_priv))
221 227
222static const struct ieee80211_channel mwl8k_channels[] = { 228struct mwl8k_sta {
229 /* Index into station database. Returned by UPDATE_STADB. */
230 u8 peer_id;
231};
232#define MWL8K_STA(_sta) ((struct mwl8k_sta *)&((_sta)->drv_priv))
233
234static const struct ieee80211_channel mwl8k_channels_24[] = {
223 { .center_freq = 2412, .hw_value = 1, }, 235 { .center_freq = 2412, .hw_value = 1, },
224 { .center_freq = 2417, .hw_value = 2, }, 236 { .center_freq = 2417, .hw_value = 2, },
225 { .center_freq = 2422, .hw_value = 3, }, 237 { .center_freq = 2422, .hw_value = 3, },
@@ -236,7 +248,7 @@ static const struct ieee80211_channel mwl8k_channels[] = {
236 { .center_freq = 2484, .hw_value = 14, }, 248 { .center_freq = 2484, .hw_value = 14, },
237}; 249};
238 250
239static const struct ieee80211_rate mwl8k_rates[] = { 251static const struct ieee80211_rate mwl8k_rates_24[] = {
240 { .bitrate = 10, .hw_value = 2, }, 252 { .bitrate = 10, .hw_value = 2, },
241 { .bitrate = 20, .hw_value = 4, }, 253 { .bitrate = 20, .hw_value = 4, },
242 { .bitrate = 55, .hw_value = 11, }, 254 { .bitrate = 55, .hw_value = 11, },
@@ -253,8 +265,23 @@ static const struct ieee80211_rate mwl8k_rates[] = {
253 { .bitrate = 720, .hw_value = 144, }, 265 { .bitrate = 720, .hw_value = 144, },
254}; 266};
255 267
256static const u8 mwl8k_rateids[12] = { 268static const struct ieee80211_channel mwl8k_channels_50[] = {
257 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108, 269 { .center_freq = 5180, .hw_value = 36, },
270 { .center_freq = 5200, .hw_value = 40, },
271 { .center_freq = 5220, .hw_value = 44, },
272 { .center_freq = 5240, .hw_value = 48, },
273};
274
275static const struct ieee80211_rate mwl8k_rates_50[] = {
276 { .bitrate = 60, .hw_value = 12, },
277 { .bitrate = 90, .hw_value = 18, },
278 { .bitrate = 120, .hw_value = 24, },
279 { .bitrate = 180, .hw_value = 36, },
280 { .bitrate = 240, .hw_value = 48, },
281 { .bitrate = 360, .hw_value = 72, },
282 { .bitrate = 480, .hw_value = 96, },
283 { .bitrate = 540, .hw_value = 108, },
284 { .bitrate = 720, .hw_value = 144, },
258}; 285};
259 286
260/* Set or get info from Firmware */ 287/* Set or get info from Firmware */
@@ -270,6 +297,7 @@ static const u8 mwl8k_rateids[12] = {
270#define MWL8K_CMD_RADIO_CONTROL 0x001c 297#define MWL8K_CMD_RADIO_CONTROL 0x001c
271#define MWL8K_CMD_RF_TX_POWER 0x001e 298#define MWL8K_CMD_RF_TX_POWER 0x001e
272#define MWL8K_CMD_RF_ANTENNA 0x0020 299#define MWL8K_CMD_RF_ANTENNA 0x0020
300#define MWL8K_CMD_SET_BEACON 0x0100 /* per-vif */
273#define MWL8K_CMD_SET_PRE_SCAN 0x0107 301#define MWL8K_CMD_SET_PRE_SCAN 0x0107
274#define MWL8K_CMD_SET_POST_SCAN 0x0108 302#define MWL8K_CMD_SET_POST_SCAN 0x0108
275#define MWL8K_CMD_SET_RF_CHANNEL 0x010a 303#define MWL8K_CMD_SET_RF_CHANNEL 0x010a
@@ -283,8 +311,10 @@ static const u8 mwl8k_rateids[12] = {
283#define MWL8K_CMD_MIMO_CONFIG 0x0125 311#define MWL8K_CMD_MIMO_CONFIG 0x0125
284#define MWL8K_CMD_USE_FIXED_RATE 0x0126 312#define MWL8K_CMD_USE_FIXED_RATE 0x0126
285#define MWL8K_CMD_ENABLE_SNIFFER 0x0150 313#define MWL8K_CMD_ENABLE_SNIFFER 0x0150
286#define MWL8K_CMD_SET_MAC_ADDR 0x0202 314#define MWL8K_CMD_SET_MAC_ADDR 0x0202 /* per-vif */
287#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203 315#define MWL8K_CMD_SET_RATEADAPT_MODE 0x0203
316#define MWL8K_CMD_BSS_START 0x1100 /* per-vif */
317#define MWL8K_CMD_SET_NEW_STN 0x1111 /* per-vif */
288#define MWL8K_CMD_UPDATE_STADB 0x1123 318#define MWL8K_CMD_UPDATE_STADB 0x1123
289 319
290static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize) 320static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
@@ -302,6 +332,7 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
302 MWL8K_CMDNAME(RADIO_CONTROL); 332 MWL8K_CMDNAME(RADIO_CONTROL);
303 MWL8K_CMDNAME(RF_TX_POWER); 333 MWL8K_CMDNAME(RF_TX_POWER);
304 MWL8K_CMDNAME(RF_ANTENNA); 334 MWL8K_CMDNAME(RF_ANTENNA);
335 MWL8K_CMDNAME(SET_BEACON);
305 MWL8K_CMDNAME(SET_PRE_SCAN); 336 MWL8K_CMDNAME(SET_PRE_SCAN);
306 MWL8K_CMDNAME(SET_POST_SCAN); 337 MWL8K_CMDNAME(SET_POST_SCAN);
307 MWL8K_CMDNAME(SET_RF_CHANNEL); 338 MWL8K_CMDNAME(SET_RF_CHANNEL);
@@ -317,6 +348,8 @@ static const char *mwl8k_cmd_name(u16 cmd, char *buf, int bufsize)
317 MWL8K_CMDNAME(ENABLE_SNIFFER); 348 MWL8K_CMDNAME(ENABLE_SNIFFER);
318 MWL8K_CMDNAME(SET_MAC_ADDR); 349 MWL8K_CMDNAME(SET_MAC_ADDR);
319 MWL8K_CMDNAME(SET_RATEADAPT_MODE); 350 MWL8K_CMDNAME(SET_RATEADAPT_MODE);
351 MWL8K_CMDNAME(BSS_START);
352 MWL8K_CMDNAME(SET_NEW_STN);
320 MWL8K_CMDNAME(UPDATE_STADB); 353 MWL8K_CMDNAME(UPDATE_STADB);
321 default: 354 default:
322 snprintf(buf, bufsize, "0x%x", cmd); 355 snprintf(buf, bufsize, "0x%x", cmd);
@@ -389,13 +422,11 @@ static int mwl8k_request_firmware(struct mwl8k_priv *priv)
389 return 0; 422 return 0;
390} 423}
391 424
392MODULE_FIRMWARE("mwl8k/helper_8687.fw");
393MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
394
395struct mwl8k_cmd_pkt { 425struct mwl8k_cmd_pkt {
396 __le16 code; 426 __le16 code;
397 __le16 length; 427 __le16 length;
398 __le16 seq_num; 428 __u8 seq_num;
429 __u8 macid;
399 __le16 result; 430 __le16 result;
400 char payload[0]; 431 char payload[0];
401} __attribute__((packed)); 432} __attribute__((packed));
@@ -453,6 +484,7 @@ static int mwl8k_load_fw_image(struct mwl8k_priv *priv,
453 484
454 cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD); 485 cmd->code = cpu_to_le16(MWL8K_CMD_CODE_DNLD);
455 cmd->seq_num = 0; 486 cmd->seq_num = 0;
487 cmd->macid = 0;
456 cmd->result = 0; 488 cmd->result = 0;
457 489
458 done = 0; 490 done = 0;
@@ -598,54 +630,6 @@ static int mwl8k_load_firmware(struct ieee80211_hw *hw)
598} 630}
599 631
600 632
601/*
602 * Defines shared between transmission and reception.
603 */
604/* HT control fields for firmware */
605struct ewc_ht_info {
606 __le16 control1;
607 __le16 control2;
608 __le16 control3;
609} __attribute__((packed));
610
611/* Firmware Station database operations */
612#define MWL8K_STA_DB_ADD_ENTRY 0
613#define MWL8K_STA_DB_MODIFY_ENTRY 1
614#define MWL8K_STA_DB_DEL_ENTRY 2
615#define MWL8K_STA_DB_FLUSH 3
616
617/* Peer Entry flags - used to define the type of the peer node */
618#define MWL8K_PEER_TYPE_ACCESSPOINT 2
619
620struct peer_capability_info {
621 /* Peer type - AP vs. STA. */
622 __u8 peer_type;
623
624 /* Basic 802.11 capabilities from assoc resp. */
625 __le16 basic_caps;
626
627 /* Set if peer supports 802.11n high throughput (HT). */
628 __u8 ht_support;
629
630 /* Valid if HT is supported. */
631 __le16 ht_caps;
632 __u8 extended_ht_caps;
633 struct ewc_ht_info ewc_info;
634
635 /* Legacy rate table. Intersection of our rates and peer rates. */
636 __u8 legacy_rates[12];
637
638 /* HT rate table. Intersection of our rates and peer rates. */
639 __u8 ht_rates[16];
640 __u8 pad[16];
641
642 /* If set, interoperability mode, no proprietary extensions. */
643 __u8 interop;
644 __u8 pad2;
645 __u8 station_id;
646 __le16 amsdu_enabled;
647} __attribute__((packed));
648
649/* DMA header used by firmware and hardware. */ 633/* DMA header used by firmware and hardware. */
650struct mwl8k_dma_data { 634struct mwl8k_dma_data {
651 __le16 fwlen; 635 __le16 fwlen;
@@ -779,15 +763,21 @@ mwl8k_rxd_8366_ap_process(void *_rxd, struct ieee80211_rx_status *status,
779 } else { 763 } else {
780 int i; 764 int i;
781 765
782 for (i = 0; i < ARRAY_SIZE(mwl8k_rates); i++) { 766 for (i = 0; i < ARRAY_SIZE(mwl8k_rates_24); i++) {
783 if (mwl8k_rates[i].hw_value == rxd->rate) { 767 if (mwl8k_rates_24[i].hw_value == rxd->rate) {
784 status->rate_idx = i; 768 status->rate_idx = i;
785 break; 769 break;
786 } 770 }
787 } 771 }
788 } 772 }
789 773
790 status->band = IEEE80211_BAND_2GHZ; 774 if (rxd->channel > 14) {
775 status->band = IEEE80211_BAND_5GHZ;
776 if (!(status->flag & RX_FLAG_HT))
777 status->rate_idx -= 5;
778 } else {
779 status->band = IEEE80211_BAND_2GHZ;
780 }
791 status->freq = ieee80211_channel_to_frequency(rxd->channel); 781 status->freq = ieee80211_channel_to_frequency(rxd->channel);
792 782
793 *qos = rxd->qos_control; 783 *qos = rxd->qos_control;
@@ -878,7 +868,13 @@ mwl8k_rxd_sta_process(void *_rxd, struct ieee80211_rx_status *status,
878 if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT) 868 if (rate_info & MWL8K_STA_RATE_INFO_MCS_FORMAT)
879 status->flag |= RX_FLAG_HT; 869 status->flag |= RX_FLAG_HT;
880 870
881 status->band = IEEE80211_BAND_2GHZ; 871 if (rxd->channel > 14) {
872 status->band = IEEE80211_BAND_5GHZ;
873 if (!(status->flag & RX_FLAG_HT))
874 status->rate_idx -= 5;
875 } else {
876 status->band = IEEE80211_BAND_2GHZ;
877 }
882 status->freq = ieee80211_channel_to_frequency(rxd->channel); 878 status->freq = ieee80211_channel_to_frequency(rxd->channel);
883 879
884 *qos = rxd->qos_control; 880 *qos = rxd->qos_control;
@@ -1225,7 +1221,7 @@ static void mwl8k_dump_tx_rings(struct ieee80211_hw *hw)
1225/* 1221/*
1226 * Must be called with priv->fw_mutex held and tx queues stopped. 1222 * Must be called with priv->fw_mutex held and tx queues stopped.
1227 */ 1223 */
1228#define MWL8K_TX_WAIT_TIMEOUT_MS 1000 1224#define MWL8K_TX_WAIT_TIMEOUT_MS 5000
1229 1225
1230static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw) 1226static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1231{ 1227{
@@ -1269,8 +1265,8 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1269 } 1265 }
1270 1266
1271 if (priv->pending_tx_pkts < oldcount) { 1267 if (priv->pending_tx_pkts < oldcount) {
1272 printk(KERN_NOTICE "%s: timeout waiting for tx " 1268 printk(KERN_NOTICE "%s: waiting for tx rings "
1273 "rings to drain (%d -> %d pkts), retrying\n", 1269 "to drain (%d -> %d pkts)\n",
1274 wiphy_name(hw->wiphy), oldcount, 1270 wiphy_name(hw->wiphy), oldcount,
1275 priv->pending_tx_pkts); 1271 priv->pending_tx_pkts);
1276 retry = 1; 1272 retry = 1;
@@ -1295,13 +1291,15 @@ static int mwl8k_tx_wait_empty(struct ieee80211_hw *hw)
1295 MWL8K_TXD_STATUS_OK_RETRY | \ 1291 MWL8K_TXD_STATUS_OK_RETRY | \
1296 MWL8K_TXD_STATUS_OK_MORE_RETRY)) 1292 MWL8K_TXD_STATUS_OK_MORE_RETRY))
1297 1293
1298static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force) 1294static int
1295mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int limit, int force)
1299{ 1296{
1300 struct mwl8k_priv *priv = hw->priv; 1297 struct mwl8k_priv *priv = hw->priv;
1301 struct mwl8k_tx_queue *txq = priv->txq + index; 1298 struct mwl8k_tx_queue *txq = priv->txq + index;
1302 int wake = 0; 1299 int processed;
1303 1300
1304 while (txq->stats.len > 0) { 1301 processed = 0;
1302 while (txq->stats.len > 0 && limit--) {
1305 int tx; 1303 int tx;
1306 struct mwl8k_tx_desc *tx_desc; 1304 struct mwl8k_tx_desc *tx_desc;
1307 unsigned long addr; 1305 unsigned long addr;
@@ -1348,11 +1346,13 @@ static void mwl8k_txq_reclaim(struct ieee80211_hw *hw, int index, int force)
1348 1346
1349 ieee80211_tx_status_irqsafe(hw, skb); 1347 ieee80211_tx_status_irqsafe(hw, skb);
1350 1348
1351 wake = 1; 1349 processed++;
1352 } 1350 }
1353 1351
1354 if (wake && priv->radio_on && !mutex_is_locked(&priv->fw_mutex)) 1352 if (processed && priv->radio_on && !mutex_is_locked(&priv->fw_mutex))
1355 ieee80211_wake_queue(hw, index); 1353 ieee80211_wake_queue(hw, index);
1354
1355 return processed;
1356} 1356}
1357 1357
1358/* must be called only when the card's transmit is completely halted */ 1358/* must be called only when the card's transmit is completely halted */
@@ -1361,7 +1361,7 @@ static void mwl8k_txq_deinit(struct ieee80211_hw *hw, int index)
1361 struct mwl8k_priv *priv = hw->priv; 1361 struct mwl8k_priv *priv = hw->priv;
1362 struct mwl8k_tx_queue *txq = priv->txq + index; 1362 struct mwl8k_tx_queue *txq = priv->txq + index;
1363 1363
1364 mwl8k_txq_reclaim(hw, index, 1); 1364 mwl8k_txq_reclaim(hw, index, INT_MAX, 1);
1365 1365
1366 kfree(txq->skb); 1366 kfree(txq->skb);
1367 txq->skb = NULL; 1367 txq->skb = NULL;
@@ -1399,11 +1399,9 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1399 mwl8k_vif = MWL8K_VIF(tx_info->control.vif); 1399 mwl8k_vif = MWL8K_VIF(tx_info->control.vif);
1400 1400
1401 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 1401 if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
1402 u16 seqno = mwl8k_vif->seqno;
1403
1404 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG); 1402 wh->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
1405 wh->seq_ctrl |= cpu_to_le16(seqno << 4); 1403 wh->seq_ctrl |= cpu_to_le16(mwl8k_vif->seqno);
1406 mwl8k_vif->seqno = seqno++ % 4096; 1404 mwl8k_vif->seqno += 0x10;
1407 } 1405 }
1408 1406
1409 /* Setup firmware control bit fields for each frame type. */ 1407 /* Setup firmware control bit fields for each frame type. */
@@ -1449,7 +1447,10 @@ mwl8k_txq_xmit(struct ieee80211_hw *hw, int index, struct sk_buff *skb)
1449 tx->pkt_phys_addr = cpu_to_le32(dma); 1447 tx->pkt_phys_addr = cpu_to_le32(dma);
1450 tx->pkt_len = cpu_to_le16(skb->len); 1448 tx->pkt_len = cpu_to_le16(skb->len);
1451 tx->rate_info = 0; 1449 tx->rate_info = 0;
1452 tx->peer_id = mwl8k_vif->peer_id; 1450 if (!priv->ap_fw && tx_info->control.sta != NULL)
1451 tx->peer_id = MWL8K_STA(tx_info->control.sta)->peer_id;
1452 else
1453 tx->peer_id = 0;
1453 wmb(); 1454 wmb();
1454 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus); 1455 tx->status = cpu_to_le32(MWL8K_TXD_STATUS_FW_OWNED | txstatus);
1455 1456
@@ -1602,6 +1603,56 @@ static int mwl8k_post_cmd(struct ieee80211_hw *hw, struct mwl8k_cmd_pkt *cmd)
1602 return rc; 1603 return rc;
1603} 1604}
1604 1605
1606static int mwl8k_post_pervif_cmd(struct ieee80211_hw *hw,
1607 struct ieee80211_vif *vif,
1608 struct mwl8k_cmd_pkt *cmd)
1609{
1610 if (vif != NULL)
1611 cmd->macid = MWL8K_VIF(vif)->macid;
1612 return mwl8k_post_cmd(hw, cmd);
1613}
1614
1615/*
1616 * Setup code shared between STA and AP firmware images.
1617 */
1618static void mwl8k_setup_2ghz_band(struct ieee80211_hw *hw)
1619{
1620 struct mwl8k_priv *priv = hw->priv;
1621
1622 BUILD_BUG_ON(sizeof(priv->channels_24) != sizeof(mwl8k_channels_24));
1623 memcpy(priv->channels_24, mwl8k_channels_24, sizeof(mwl8k_channels_24));
1624
1625 BUILD_BUG_ON(sizeof(priv->rates_24) != sizeof(mwl8k_rates_24));
1626 memcpy(priv->rates_24, mwl8k_rates_24, sizeof(mwl8k_rates_24));
1627
1628 priv->band_24.band = IEEE80211_BAND_2GHZ;
1629 priv->band_24.channels = priv->channels_24;
1630 priv->band_24.n_channels = ARRAY_SIZE(mwl8k_channels_24);
1631 priv->band_24.bitrates = priv->rates_24;
1632 priv->band_24.n_bitrates = ARRAY_SIZE(mwl8k_rates_24);
1633
1634 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band_24;
1635}
1636
1637static void mwl8k_setup_5ghz_band(struct ieee80211_hw *hw)
1638{
1639 struct mwl8k_priv *priv = hw->priv;
1640
1641 BUILD_BUG_ON(sizeof(priv->channels_50) != sizeof(mwl8k_channels_50));
1642 memcpy(priv->channels_50, mwl8k_channels_50, sizeof(mwl8k_channels_50));
1643
1644 BUILD_BUG_ON(sizeof(priv->rates_50) != sizeof(mwl8k_rates_50));
1645 memcpy(priv->rates_50, mwl8k_rates_50, sizeof(mwl8k_rates_50));
1646
1647 priv->band_50.band = IEEE80211_BAND_5GHZ;
1648 priv->band_50.channels = priv->channels_50;
1649 priv->band_50.n_channels = ARRAY_SIZE(mwl8k_channels_50);
1650 priv->band_50.bitrates = priv->rates_50;
1651 priv->band_50.n_bitrates = ARRAY_SIZE(mwl8k_rates_50);
1652
1653 hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &priv->band_50;
1654}
1655
1605/* 1656/*
1606 * CMD_GET_HW_SPEC (STA version). 1657 * CMD_GET_HW_SPEC (STA version).
1607 */ 1658 */
@@ -1624,6 +1675,89 @@ struct mwl8k_cmd_get_hw_spec_sta {
1624 __le32 total_rxd; 1675 __le32 total_rxd;
1625} __attribute__((packed)); 1676} __attribute__((packed));
1626 1677
1678#define MWL8K_CAP_MAX_AMSDU 0x20000000
1679#define MWL8K_CAP_GREENFIELD 0x08000000
1680#define MWL8K_CAP_AMPDU 0x04000000
1681#define MWL8K_CAP_RX_STBC 0x01000000
1682#define MWL8K_CAP_TX_STBC 0x00800000
1683#define MWL8K_CAP_SHORTGI_40MHZ 0x00400000
1684#define MWL8K_CAP_SHORTGI_20MHZ 0x00200000
1685#define MWL8K_CAP_RX_ANTENNA_MASK 0x000e0000
1686#define MWL8K_CAP_TX_ANTENNA_MASK 0x0001c000
1687#define MWL8K_CAP_DELAY_BA 0x00003000
1688#define MWL8K_CAP_MIMO 0x00000200
1689#define MWL8K_CAP_40MHZ 0x00000100
1690#define MWL8K_CAP_BAND_MASK 0x00000007
1691#define MWL8K_CAP_5GHZ 0x00000004
1692#define MWL8K_CAP_2GHZ4 0x00000001
1693
1694static void
1695mwl8k_set_ht_caps(struct ieee80211_hw *hw,
1696 struct ieee80211_supported_band *band, u32 cap)
1697{
1698 int rx_streams;
1699 int tx_streams;
1700
1701 band->ht_cap.ht_supported = 1;
1702
1703 if (cap & MWL8K_CAP_MAX_AMSDU)
1704 band->ht_cap.cap |= IEEE80211_HT_CAP_MAX_AMSDU;
1705 if (cap & MWL8K_CAP_GREENFIELD)
1706 band->ht_cap.cap |= IEEE80211_HT_CAP_GRN_FLD;
1707 if (cap & MWL8K_CAP_AMPDU) {
1708 hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
1709 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
1710 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_NONE;
1711 }
1712 if (cap & MWL8K_CAP_RX_STBC)
1713 band->ht_cap.cap |= IEEE80211_HT_CAP_RX_STBC;
1714 if (cap & MWL8K_CAP_TX_STBC)
1715 band->ht_cap.cap |= IEEE80211_HT_CAP_TX_STBC;
1716 if (cap & MWL8K_CAP_SHORTGI_40MHZ)
1717 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
1718 if (cap & MWL8K_CAP_SHORTGI_20MHZ)
1719 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
1720 if (cap & MWL8K_CAP_DELAY_BA)
1721 band->ht_cap.cap |= IEEE80211_HT_CAP_DELAY_BA;
1722 if (cap & MWL8K_CAP_40MHZ)
1723 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
1724
1725 rx_streams = hweight32(cap & MWL8K_CAP_RX_ANTENNA_MASK);
1726 tx_streams = hweight32(cap & MWL8K_CAP_TX_ANTENNA_MASK);
1727
1728 band->ht_cap.mcs.rx_mask[0] = 0xff;
1729 if (rx_streams >= 2)
1730 band->ht_cap.mcs.rx_mask[1] = 0xff;
1731 if (rx_streams >= 3)
1732 band->ht_cap.mcs.rx_mask[2] = 0xff;
1733 band->ht_cap.mcs.rx_mask[4] = 0x01;
1734 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
1735
1736 if (rx_streams != tx_streams) {
1737 band->ht_cap.mcs.tx_params |= IEEE80211_HT_MCS_TX_RX_DIFF;
1738 band->ht_cap.mcs.tx_params |= (tx_streams - 1) <<
1739 IEEE80211_HT_MCS_TX_MAX_STREAMS_SHIFT;
1740 }
1741}
1742
1743static void
1744mwl8k_set_caps(struct ieee80211_hw *hw, u32 caps)
1745{
1746 struct mwl8k_priv *priv = hw->priv;
1747
1748 if ((caps & MWL8K_CAP_2GHZ4) || !(caps & MWL8K_CAP_BAND_MASK)) {
1749 mwl8k_setup_2ghz_band(hw);
1750 if (caps & MWL8K_CAP_MIMO)
1751 mwl8k_set_ht_caps(hw, &priv->band_24, caps);
1752 }
1753
1754 if (caps & MWL8K_CAP_5GHZ) {
1755 mwl8k_setup_5ghz_band(hw);
1756 if (caps & MWL8K_CAP_MIMO)
1757 mwl8k_set_ht_caps(hw, &priv->band_50, caps);
1758 }
1759}
1760
1627static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw) 1761static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1628{ 1762{
1629 struct mwl8k_priv *priv = hw->priv; 1763 struct mwl8k_priv *priv = hw->priv;
@@ -1654,6 +1788,9 @@ static int mwl8k_cmd_get_hw_spec_sta(struct ieee80211_hw *hw)
1654 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1788 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1655 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1789 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1656 priv->hw_rev = cmd->hw_rev; 1790 priv->hw_rev = cmd->hw_rev;
1791 mwl8k_set_caps(hw, le32_to_cpu(cmd->caps));
1792 priv->ap_macids_supported = 0x00000000;
1793 priv->sta_macids_supported = 0x00000001;
1657 } 1794 }
1658 1795
1659 kfree(cmd); 1796 kfree(cmd);
@@ -1707,6 +1844,9 @@ static int mwl8k_cmd_get_hw_spec_ap(struct ieee80211_hw *hw)
1707 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs); 1844 priv->num_mcaddrs = le16_to_cpu(cmd->num_mcaddrs);
1708 priv->fw_rev = le32_to_cpu(cmd->fw_rev); 1845 priv->fw_rev = le32_to_cpu(cmd->fw_rev);
1709 priv->hw_rev = cmd->hw_rev; 1846 priv->hw_rev = cmd->hw_rev;
1847 mwl8k_setup_2ghz_band(hw);
1848 priv->ap_macids_supported = 0x000000ff;
1849 priv->sta_macids_supported = 0x00000000;
1710 1850
1711 off = le32_to_cpu(cmd->wcbbase0) & 0xffff; 1851 off = le32_to_cpu(cmd->wcbbase0) & 0xffff;
1712 iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off); 1852 iowrite32(cpu_to_le32(priv->txq[0].txd_dma), priv->sram + off);
@@ -1752,7 +1892,9 @@ struct mwl8k_cmd_set_hw_spec {
1752 __le32 total_rxd; 1892 __le32 total_rxd;
1753} __attribute__((packed)); 1893} __attribute__((packed));
1754 1894
1755#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080 1895#define MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT 0x00000080
1896#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP 0x00000020
1897#define MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON 0x00000010
1756 1898
1757static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw) 1899static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
1758{ 1900{
@@ -1773,7 +1915,9 @@ static int mwl8k_cmd_set_hw_spec(struct ieee80211_hw *hw)
1773 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES); 1915 cmd->num_tx_queues = cpu_to_le32(MWL8K_TX_QUEUES);
1774 for (i = 0; i < MWL8K_TX_QUEUES; i++) 1916 for (i = 0; i < MWL8K_TX_QUEUES; i++)
1775 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma); 1917 cmd->tx_queue_ptrs[i] = cpu_to_le32(priv->txq[i].txd_dma);
1776 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT); 1918 cmd->flags = cpu_to_le32(MWL8K_SET_HW_SPEC_FLAG_HOST_DECR_MGMT |
1919 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_PROBERESP |
1920 MWL8K_SET_HW_SPEC_FLAG_HOSTFORM_BEACON);
1777 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS); 1921 cmd->num_tx_desc_per_queue = cpu_to_le32(MWL8K_TX_DESCS);
1778 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS); 1922 cmd->total_rxd = cpu_to_le32(MWL8K_RX_DESCS);
1779 1923
@@ -2011,6 +2155,36 @@ mwl8k_cmd_rf_antenna(struct ieee80211_hw *hw, int antenna, int mask)
2011} 2155}
2012 2156
2013/* 2157/*
2158 * CMD_SET_BEACON.
2159 */
2160struct mwl8k_cmd_set_beacon {
2161 struct mwl8k_cmd_pkt header;
2162 __le16 beacon_len;
2163 __u8 beacon[0];
2164};
2165
2166static int mwl8k_cmd_set_beacon(struct ieee80211_hw *hw,
2167 struct ieee80211_vif *vif, u8 *beacon, int len)
2168{
2169 struct mwl8k_cmd_set_beacon *cmd;
2170 int rc;
2171
2172 cmd = kzalloc(sizeof(*cmd) + len, GFP_KERNEL);
2173 if (cmd == NULL)
2174 return -ENOMEM;
2175
2176 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_BEACON);
2177 cmd->header.length = cpu_to_le16(sizeof(*cmd) + len);
2178 cmd->beacon_len = cpu_to_le16(len);
2179 memcpy(cmd->beacon, beacon, len);
2180
2181 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2182 kfree(cmd);
2183
2184 return rc;
2185}
2186
2187/*
2014 * CMD_SET_PRE_SCAN. 2188 * CMD_SET_PRE_SCAN.
2015 */ 2189 */
2016struct mwl8k_cmd_set_pre_scan { 2190struct mwl8k_cmd_set_pre_scan {
@@ -2045,7 +2219,7 @@ struct mwl8k_cmd_set_post_scan {
2045} __attribute__((packed)); 2219} __attribute__((packed));
2046 2220
2047static int 2221static int
2048mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, __u8 *mac) 2222mwl8k_cmd_set_post_scan(struct ieee80211_hw *hw, const __u8 *mac)
2049{ 2223{
2050 struct mwl8k_cmd_set_post_scan *cmd; 2224 struct mwl8k_cmd_set_post_scan *cmd;
2051 int rc; 2225 int rc;
@@ -2076,8 +2250,9 @@ struct mwl8k_cmd_set_rf_channel {
2076} __attribute__((packed)); 2250} __attribute__((packed));
2077 2251
2078static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw, 2252static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
2079 struct ieee80211_channel *channel) 2253 struct ieee80211_conf *conf)
2080{ 2254{
2255 struct ieee80211_channel *channel = conf->channel;
2081 struct mwl8k_cmd_set_rf_channel *cmd; 2256 struct mwl8k_cmd_set_rf_channel *cmd;
2082 int rc; 2257 int rc;
2083 2258
@@ -2089,10 +2264,19 @@ static int mwl8k_cmd_set_rf_channel(struct ieee80211_hw *hw,
2089 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2264 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2090 cmd->action = cpu_to_le16(MWL8K_CMD_SET); 2265 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2091 cmd->current_channel = channel->hw_value; 2266 cmd->current_channel = channel->hw_value;
2267
2092 if (channel->band == IEEE80211_BAND_2GHZ) 2268 if (channel->band == IEEE80211_BAND_2GHZ)
2093 cmd->channel_flags = cpu_to_le32(0x00000081); 2269 cmd->channel_flags |= cpu_to_le32(0x00000001);
2094 else 2270 else if (channel->band == IEEE80211_BAND_5GHZ)
2095 cmd->channel_flags = cpu_to_le32(0x00000000); 2271 cmd->channel_flags |= cpu_to_le32(0x00000004);
2272
2273 if (conf->channel_type == NL80211_CHAN_NO_HT ||
2274 conf->channel_type == NL80211_CHAN_HT20)
2275 cmd->channel_flags |= cpu_to_le32(0x00000080);
2276 else if (conf->channel_type == NL80211_CHAN_HT40MINUS)
2277 cmd->channel_flags |= cpu_to_le32(0x000001900);
2278 else if (conf->channel_type == NL80211_CHAN_HT40PLUS)
2279 cmd->channel_flags |= cpu_to_le32(0x000000900);
2096 2280
2097 rc = mwl8k_post_cmd(hw, &cmd->header); 2281 rc = mwl8k_post_cmd(hw, &cmd->header);
2098 kfree(cmd); 2282 kfree(cmd);
@@ -2118,10 +2302,26 @@ struct mwl8k_cmd_update_set_aid {
2118 __u8 supp_rates[14]; 2302 __u8 supp_rates[14];
2119} __attribute__((packed)); 2303} __attribute__((packed));
2120 2304
2305static void legacy_rate_mask_to_array(u8 *rates, u32 mask)
2306{
2307 int i;
2308 int j;
2309
2310 /*
2311 * Clear nonstandard rates 4 and 13.
2312 */
2313 mask &= 0x1fef;
2314
2315 for (i = 0, j = 0; i < 14; i++) {
2316 if (mask & (1 << i))
2317 rates[j++] = mwl8k_rates_24[i].hw_value;
2318 }
2319}
2320
2121static int 2321static int
2122mwl8k_cmd_set_aid(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 2322mwl8k_cmd_set_aid(struct ieee80211_hw *hw,
2323 struct ieee80211_vif *vif, u32 legacy_rate_mask)
2123{ 2324{
2124 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
2125 struct mwl8k_cmd_update_set_aid *cmd; 2325 struct mwl8k_cmd_update_set_aid *cmd;
2126 u16 prot_mode; 2326 u16 prot_mode;
2127 int rc; 2327 int rc;
@@ -2133,8 +2333,7 @@ mwl8k_cmd_set_aid(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2133 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID); 2333 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_AID);
2134 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2334 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2135 cmd->aid = cpu_to_le16(vif->bss_conf.aid); 2335 cmd->aid = cpu_to_le16(vif->bss_conf.aid);
2136 2336 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
2137 memcpy(cmd->bssid, mv_vif->bssid, ETH_ALEN);
2138 2337
2139 if (vif->bss_conf.use_cts_prot) { 2338 if (vif->bss_conf.use_cts_prot) {
2140 prot_mode = MWL8K_FRAME_PROT_11G; 2339 prot_mode = MWL8K_FRAME_PROT_11G;
@@ -2154,7 +2353,7 @@ mwl8k_cmd_set_aid(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2154 } 2353 }
2155 cmd->protection_mode = cpu_to_le16(prot_mode); 2354 cmd->protection_mode = cpu_to_le16(prot_mode);
2156 2355
2157 memcpy(cmd->supp_rates, mwl8k_rateids, sizeof(mwl8k_rateids)); 2356 legacy_rate_mask_to_array(cmd->supp_rates, legacy_rate_mask);
2158 2357
2159 rc = mwl8k_post_cmd(hw, &cmd->header); 2358 rc = mwl8k_post_cmd(hw, &cmd->header);
2160 kfree(cmd); 2359 kfree(cmd);
@@ -2175,7 +2374,8 @@ struct mwl8k_cmd_set_rate {
2175} __attribute__((packed)); 2374} __attribute__((packed));
2176 2375
2177static int 2376static int
2178mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 2377mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2378 u32 legacy_rate_mask, u8 *mcs_rates)
2179{ 2379{
2180 struct mwl8k_cmd_set_rate *cmd; 2380 struct mwl8k_cmd_set_rate *cmd;
2181 int rc; 2381 int rc;
@@ -2186,7 +2386,8 @@ mwl8k_cmd_set_rate(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
2186 2386
2187 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE); 2387 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_RATE);
2188 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2388 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2189 memcpy(cmd->legacy_rates, mwl8k_rateids, sizeof(mwl8k_rateids)); 2389 legacy_rate_mask_to_array(cmd->legacy_rates, legacy_rate_mask);
2390 memcpy(cmd->mcs_set, mcs_rates, 16);
2190 2391
2191 rc = mwl8k_post_cmd(hw, &cmd->header); 2392 rc = mwl8k_post_cmd(hw, &cmd->header);
2192 kfree(cmd); 2393 kfree(cmd);
@@ -2244,8 +2445,8 @@ struct mwl8k_cmd_set_rts_threshold {
2244 __le16 threshold; 2445 __le16 threshold;
2245} __attribute__((packed)); 2446} __attribute__((packed));
2246 2447
2247static int mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, 2448static int
2248 u16 action, u16 threshold) 2449mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw, int rts_thresh)
2249{ 2450{
2250 struct mwl8k_cmd_set_rts_threshold *cmd; 2451 struct mwl8k_cmd_set_rts_threshold *cmd;
2251 int rc; 2452 int rc;
@@ -2256,8 +2457,8 @@ static int mwl8k_cmd_set_rts_threshold(struct ieee80211_hw *hw,
2256 2457
2257 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD); 2458 cmd->header.code = cpu_to_le16(MWL8K_CMD_RTS_THRESHOLD);
2258 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2459 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2259 cmd->action = cpu_to_le16(action); 2460 cmd->action = cpu_to_le16(MWL8K_CMD_SET);
2260 cmd->threshold = cpu_to_le16(threshold); 2461 cmd->threshold = cpu_to_le16(rts_thresh);
2261 2462
2262 rc = mwl8k_post_cmd(hw, &cmd->header); 2463 rc = mwl8k_post_cmd(hw, &cmd->header);
2263 kfree(cmd); 2464 kfree(cmd);
@@ -2357,12 +2558,6 @@ mwl8k_cmd_set_edca_params(struct ieee80211_hw *hw, __u8 qnum,
2357 if (cmd == NULL) 2558 if (cmd == NULL)
2358 return -ENOMEM; 2559 return -ENOMEM;
2359 2560
2360 /*
2361 * Queues 0 (BE) and 1 (BK) are swapped in hardware for
2362 * this call.
2363 */
2364 qnum ^= !(qnum >> 1);
2365
2366 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS); 2561 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_EDCA_PARAMS);
2367 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2562 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2368 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL); 2563 cmd->action = cpu_to_le16(MWL8K_SET_EDCA_ALL);
@@ -2448,49 +2643,70 @@ static int mwl8k_cmd_mimo_config(struct ieee80211_hw *hw, __u8 rx, __u8 tx)
2448} 2643}
2449 2644
2450/* 2645/*
2451 * CMD_USE_FIXED_RATE. 2646 * CMD_USE_FIXED_RATE (STA version).
2452 */ 2647 */
2453#define MWL8K_RATE_TABLE_SIZE 8 2648struct mwl8k_cmd_use_fixed_rate_sta {
2454#define MWL8K_UCAST_RATE 0 2649 struct mwl8k_cmd_pkt header;
2455#define MWL8K_USE_AUTO_RATE 0x0002 2650 __le32 action;
2651 __le32 allow_rate_drop;
2652 __le32 num_rates;
2653 struct {
2654 __le32 is_ht_rate;
2655 __le32 enable_retry;
2656 __le32 rate;
2657 __le32 retry_count;
2658 } rate_entry[8];
2659 __le32 rate_type;
2660 __le32 reserved1;
2661 __le32 reserved2;
2662} __attribute__((packed));
2456 2663
2457struct mwl8k_rate_entry { 2664#define MWL8K_USE_AUTO_RATE 0x0002
2458 /* Set to 1 if HT rate, 0 if legacy. */ 2665#define MWL8K_UCAST_RATE 0
2459 __le32 is_ht_rate;
2460 2666
2461 /* Set to 1 to use retry_count field. */ 2667static int mwl8k_cmd_use_fixed_rate_sta(struct ieee80211_hw *hw)
2462 __le32 enable_retry; 2668{
2669 struct mwl8k_cmd_use_fixed_rate_sta *cmd;
2670 int rc;
2463 2671
2464 /* Specified legacy rate or MCS. */ 2672 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2465 __le32 rate; 2673 if (cmd == NULL)
2674 return -ENOMEM;
2466 2675
2467 /* Number of allowed retries. */ 2676 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
2468 __le32 retry_count; 2677 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2469} __attribute__((packed)); 2678 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
2679 cmd->rate_type = cpu_to_le32(MWL8K_UCAST_RATE);
2470 2680
2471struct mwl8k_rate_table { 2681 rc = mwl8k_post_cmd(hw, &cmd->header);
2472 /* 1 to allow specified rate and below */ 2682 kfree(cmd);
2473 __le32 allow_rate_drop;
2474 __le32 num_rates;
2475 struct mwl8k_rate_entry rate_entry[MWL8K_RATE_TABLE_SIZE];
2476} __attribute__((packed));
2477 2683
2478struct mwl8k_cmd_use_fixed_rate { 2684 return rc;
2479 struct mwl8k_cmd_pkt header; 2685}
2480 __le32 action;
2481 struct mwl8k_rate_table rate_table;
2482 2686
2483 /* Unicast, Broadcast or Multicast */ 2687/*
2484 __le32 rate_type; 2688 * CMD_USE_FIXED_RATE (AP version).
2485 __le32 reserved1; 2689 */
2486 __le32 reserved2; 2690struct mwl8k_cmd_use_fixed_rate_ap {
2691 struct mwl8k_cmd_pkt header;
2692 __le32 action;
2693 __le32 allow_rate_drop;
2694 __le32 num_rates;
2695 struct mwl8k_rate_entry_ap {
2696 __le32 is_ht_rate;
2697 __le32 enable_retry;
2698 __le32 rate;
2699 __le32 retry_count;
2700 } rate_entry[4];
2701 u8 multicast_rate;
2702 u8 multicast_rate_type;
2703 u8 management_rate;
2487} __attribute__((packed)); 2704} __attribute__((packed));
2488 2705
2489static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw, 2706static int
2490 u32 action, u32 rate_type, struct mwl8k_rate_table *rate_table) 2707mwl8k_cmd_use_fixed_rate_ap(struct ieee80211_hw *hw, int mcast, int mgmt)
2491{ 2708{
2492 struct mwl8k_cmd_use_fixed_rate *cmd; 2709 struct mwl8k_cmd_use_fixed_rate_ap *cmd;
2493 int count;
2494 int rc; 2710 int rc;
2495 2711
2496 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2712 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2499,32 +2715,9 @@ static int mwl8k_cmd_use_fixed_rate(struct ieee80211_hw *hw,
2499 2715
2500 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE); 2716 cmd->header.code = cpu_to_le16(MWL8K_CMD_USE_FIXED_RATE);
2501 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2717 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2502 2718 cmd->action = cpu_to_le32(MWL8K_USE_AUTO_RATE);
2503 cmd->action = cpu_to_le32(action); 2719 cmd->multicast_rate = mcast;
2504 cmd->rate_type = cpu_to_le32(rate_type); 2720 cmd->management_rate = mgmt;
2505
2506 if (rate_table != NULL) {
2507 /*
2508 * Copy over each field manually so that endian
2509 * conversion can be done.
2510 */
2511 cmd->rate_table.allow_rate_drop =
2512 cpu_to_le32(rate_table->allow_rate_drop);
2513 cmd->rate_table.num_rates =
2514 cpu_to_le32(rate_table->num_rates);
2515
2516 for (count = 0; count < rate_table->num_rates; count++) {
2517 struct mwl8k_rate_entry *dst =
2518 &cmd->rate_table.rate_entry[count];
2519 struct mwl8k_rate_entry *src =
2520 &rate_table->rate_entry[count];
2521
2522 dst->is_ht_rate = cpu_to_le32(src->is_ht_rate);
2523 dst->enable_retry = cpu_to_le32(src->enable_retry);
2524 dst->rate = cpu_to_le32(src->rate);
2525 dst->retry_count = cpu_to_le32(src->retry_count);
2526 }
2527 }
2528 2721
2529 rc = mwl8k_post_cmd(hw, &cmd->header); 2722 rc = mwl8k_post_cmd(hw, &cmd->header);
2530 kfree(cmd); 2723 kfree(cmd);
@@ -2573,12 +2766,33 @@ struct mwl8k_cmd_set_mac_addr {
2573 }; 2766 };
2574} __attribute__((packed)); 2767} __attribute__((packed));
2575 2768
2576static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, u8 *mac) 2769#define MWL8K_MAC_TYPE_PRIMARY_CLIENT 0
2770#define MWL8K_MAC_TYPE_SECONDARY_CLIENT 1
2771#define MWL8K_MAC_TYPE_PRIMARY_AP 2
2772#define MWL8K_MAC_TYPE_SECONDARY_AP 3
2773
2774static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw,
2775 struct ieee80211_vif *vif, u8 *mac)
2577{ 2776{
2578 struct mwl8k_priv *priv = hw->priv; 2777 struct mwl8k_priv *priv = hw->priv;
2778 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
2579 struct mwl8k_cmd_set_mac_addr *cmd; 2779 struct mwl8k_cmd_set_mac_addr *cmd;
2780 int mac_type;
2580 int rc; 2781 int rc;
2581 2782
2783 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
2784 if (vif != NULL && vif->type == NL80211_IFTYPE_STATION) {
2785 if (mwl8k_vif->macid + 1 == ffs(priv->sta_macids_supported))
2786 mac_type = MWL8K_MAC_TYPE_PRIMARY_CLIENT;
2787 else
2788 mac_type = MWL8K_MAC_TYPE_SECONDARY_CLIENT;
2789 } else if (vif != NULL && vif->type == NL80211_IFTYPE_AP) {
2790 if (mwl8k_vif->macid + 1 == ffs(priv->ap_macids_supported))
2791 mac_type = MWL8K_MAC_TYPE_PRIMARY_AP;
2792 else
2793 mac_type = MWL8K_MAC_TYPE_SECONDARY_AP;
2794 }
2795
2582 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 2796 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2583 if (cmd == NULL) 2797 if (cmd == NULL)
2584 return -ENOMEM; 2798 return -ENOMEM;
@@ -2586,13 +2800,13 @@ static int mwl8k_cmd_set_mac_addr(struct ieee80211_hw *hw, u8 *mac)
2586 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR); 2800 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_MAC_ADDR);
2587 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 2801 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2588 if (priv->ap_fw) { 2802 if (priv->ap_fw) {
2589 cmd->mbss.mac_type = 0; 2803 cmd->mbss.mac_type = cpu_to_le16(mac_type);
2590 memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN); 2804 memcpy(cmd->mbss.mac_addr, mac, ETH_ALEN);
2591 } else { 2805 } else {
2592 memcpy(cmd->mac_addr, mac, ETH_ALEN); 2806 memcpy(cmd->mac_addr, mac, ETH_ALEN);
2593 } 2807 }
2594 2808
2595 rc = mwl8k_post_cmd(hw, &cmd->header); 2809 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2596 kfree(cmd); 2810 kfree(cmd);
2597 2811
2598 return rc; 2812 return rc;
@@ -2628,8 +2842,180 @@ static int mwl8k_cmd_set_rateadapt_mode(struct ieee80211_hw *hw, __u16 mode)
2628} 2842}
2629 2843
2630/* 2844/*
2845 * CMD_BSS_START.
2846 */
2847struct mwl8k_cmd_bss_start {
2848 struct mwl8k_cmd_pkt header;
2849 __le32 enable;
2850} __attribute__((packed));
2851
2852static int mwl8k_cmd_bss_start(struct ieee80211_hw *hw,
2853 struct ieee80211_vif *vif, int enable)
2854{
2855 struct mwl8k_cmd_bss_start *cmd;
2856 int rc;
2857
2858 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2859 if (cmd == NULL)
2860 return -ENOMEM;
2861
2862 cmd->header.code = cpu_to_le16(MWL8K_CMD_BSS_START);
2863 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2864 cmd->enable = cpu_to_le32(enable);
2865
2866 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2867 kfree(cmd);
2868
2869 return rc;
2870}
2871
2872/*
2873 * CMD_SET_NEW_STN.
2874 */
2875struct mwl8k_cmd_set_new_stn {
2876 struct mwl8k_cmd_pkt header;
2877 __le16 aid;
2878 __u8 mac_addr[6];
2879 __le16 stn_id;
2880 __le16 action;
2881 __le16 rsvd;
2882 __le32 legacy_rates;
2883 __u8 ht_rates[4];
2884 __le16 cap_info;
2885 __le16 ht_capabilities_info;
2886 __u8 mac_ht_param_info;
2887 __u8 rev;
2888 __u8 control_channel;
2889 __u8 add_channel;
2890 __le16 op_mode;
2891 __le16 stbc;
2892 __u8 add_qos_info;
2893 __u8 is_qos_sta;
2894 __le32 fw_sta_ptr;
2895} __attribute__((packed));
2896
2897#define MWL8K_STA_ACTION_ADD 0
2898#define MWL8K_STA_ACTION_REMOVE 2
2899
2900static int mwl8k_cmd_set_new_stn_add(struct ieee80211_hw *hw,
2901 struct ieee80211_vif *vif,
2902 struct ieee80211_sta *sta)
2903{
2904 struct mwl8k_cmd_set_new_stn *cmd;
2905 u32 rates;
2906 int rc;
2907
2908 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2909 if (cmd == NULL)
2910 return -ENOMEM;
2911
2912 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
2913 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2914 cmd->aid = cpu_to_le16(sta->aid);
2915 memcpy(cmd->mac_addr, sta->addr, ETH_ALEN);
2916 cmd->stn_id = cpu_to_le16(sta->aid);
2917 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_ADD);
2918 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
2919 rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
2920 else
2921 rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
2922 cmd->legacy_rates = cpu_to_le32(rates);
2923 if (sta->ht_cap.ht_supported) {
2924 cmd->ht_rates[0] = sta->ht_cap.mcs.rx_mask[0];
2925 cmd->ht_rates[1] = sta->ht_cap.mcs.rx_mask[1];
2926 cmd->ht_rates[2] = sta->ht_cap.mcs.rx_mask[2];
2927 cmd->ht_rates[3] = sta->ht_cap.mcs.rx_mask[3];
2928 cmd->ht_capabilities_info = cpu_to_le16(sta->ht_cap.cap);
2929 cmd->mac_ht_param_info = (sta->ht_cap.ampdu_factor & 3) |
2930 ((sta->ht_cap.ampdu_density & 7) << 2);
2931 cmd->is_qos_sta = 1;
2932 }
2933
2934 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2935 kfree(cmd);
2936
2937 return rc;
2938}
2939
2940static int mwl8k_cmd_set_new_stn_add_self(struct ieee80211_hw *hw,
2941 struct ieee80211_vif *vif)
2942{
2943 struct mwl8k_cmd_set_new_stn *cmd;
2944 int rc;
2945
2946 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2947 if (cmd == NULL)
2948 return -ENOMEM;
2949
2950 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
2951 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2952 memcpy(cmd->mac_addr, vif->addr, ETH_ALEN);
2953
2954 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2955 kfree(cmd);
2956
2957 return rc;
2958}
2959
2960static int mwl8k_cmd_set_new_stn_del(struct ieee80211_hw *hw,
2961 struct ieee80211_vif *vif, u8 *addr)
2962{
2963 struct mwl8k_cmd_set_new_stn *cmd;
2964 int rc;
2965
2966 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2967 if (cmd == NULL)
2968 return -ENOMEM;
2969
2970 cmd->header.code = cpu_to_le16(MWL8K_CMD_SET_NEW_STN);
2971 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2972 memcpy(cmd->mac_addr, addr, ETH_ALEN);
2973 cmd->action = cpu_to_le16(MWL8K_STA_ACTION_REMOVE);
2974
2975 rc = mwl8k_post_pervif_cmd(hw, vif, &cmd->header);
2976 kfree(cmd);
2977
2978 return rc;
2979}
2980
2981/*
2631 * CMD_UPDATE_STADB. 2982 * CMD_UPDATE_STADB.
2632 */ 2983 */
2984struct ewc_ht_info {
2985 __le16 control1;
2986 __le16 control2;
2987 __le16 control3;
2988} __attribute__((packed));
2989
2990struct peer_capability_info {
2991 /* Peer type - AP vs. STA. */
2992 __u8 peer_type;
2993
2994 /* Basic 802.11 capabilities from assoc resp. */
2995 __le16 basic_caps;
2996
2997 /* Set if peer supports 802.11n high throughput (HT). */
2998 __u8 ht_support;
2999
3000 /* Valid if HT is supported. */
3001 __le16 ht_caps;
3002 __u8 extended_ht_caps;
3003 struct ewc_ht_info ewc_info;
3004
3005 /* Legacy rate table. Intersection of our rates and peer rates. */
3006 __u8 legacy_rates[12];
3007
3008 /* HT rate table. Intersection of our rates and peer rates. */
3009 __u8 ht_rates[16];
3010 __u8 pad[16];
3011
3012 /* If set, interoperability mode, no proprietary extensions. */
3013 __u8 interop;
3014 __u8 pad2;
3015 __u8 station_id;
3016 __le16 amsdu_enabled;
3017} __attribute__((packed));
3018
2633struct mwl8k_cmd_update_stadb { 3019struct mwl8k_cmd_update_stadb {
2634 struct mwl8k_cmd_pkt header; 3020 struct mwl8k_cmd_pkt header;
2635 3021
@@ -2645,12 +3031,19 @@ struct mwl8k_cmd_update_stadb {
2645 struct peer_capability_info peer_info; 3031 struct peer_capability_info peer_info;
2646} __attribute__((packed)); 3032} __attribute__((packed));
2647 3033
2648static int mwl8k_cmd_update_stadb(struct ieee80211_hw *hw, 3034#define MWL8K_STA_DB_MODIFY_ENTRY 1
2649 struct ieee80211_vif *vif, __u32 action) 3035#define MWL8K_STA_DB_DEL_ENTRY 2
3036
3037/* Peer Entry flags - used to define the type of the peer node */
3038#define MWL8K_PEER_TYPE_ACCESSPOINT 2
3039
3040static int mwl8k_cmd_update_stadb_add(struct ieee80211_hw *hw,
3041 struct ieee80211_vif *vif,
3042 struct ieee80211_sta *sta)
2650{ 3043{
2651 struct mwl8k_vif *mv_vif = MWL8K_VIF(vif);
2652 struct mwl8k_cmd_update_stadb *cmd; 3044 struct mwl8k_cmd_update_stadb *cmd;
2653 struct peer_capability_info *peer_info; 3045 struct peer_capability_info *p;
3046 u32 rates;
2654 int rc; 3047 int rc;
2655 3048
2656 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL); 3049 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
@@ -2659,37 +3052,47 @@ static int mwl8k_cmd_update_stadb(struct ieee80211_hw *hw,
2659 3052
2660 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB); 3053 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
2661 cmd->header.length = cpu_to_le16(sizeof(*cmd)); 3054 cmd->header.length = cpu_to_le16(sizeof(*cmd));
3055 cmd->action = cpu_to_le32(MWL8K_STA_DB_MODIFY_ENTRY);
3056 memcpy(cmd->peer_addr, sta->addr, ETH_ALEN);
3057
3058 p = &cmd->peer_info;
3059 p->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
3060 p->basic_caps = cpu_to_le16(vif->bss_conf.assoc_capability);
3061 p->ht_support = sta->ht_cap.ht_supported;
3062 p->ht_caps = sta->ht_cap.cap;
3063 p->extended_ht_caps = (sta->ht_cap.ampdu_factor & 3) |
3064 ((sta->ht_cap.ampdu_density & 7) << 2);
3065 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
3066 rates = sta->supp_rates[IEEE80211_BAND_2GHZ];
3067 else
3068 rates = sta->supp_rates[IEEE80211_BAND_5GHZ] << 5;
3069 legacy_rate_mask_to_array(p->legacy_rates, rates);
3070 memcpy(p->ht_rates, sta->ht_cap.mcs.rx_mask, 16);
3071 p->interop = 1;
3072 p->amsdu_enabled = 0;
2662 3073
2663 cmd->action = cpu_to_le32(action); 3074 rc = mwl8k_post_cmd(hw, &cmd->header);
2664 peer_info = &cmd->peer_info; 3075 kfree(cmd);
2665 memcpy(cmd->peer_addr, mv_vif->bssid, ETH_ALEN);
2666 3076
2667 switch (action) { 3077 return rc ? rc : p->station_id;
2668 case MWL8K_STA_DB_ADD_ENTRY: 3078}
2669 case MWL8K_STA_DB_MODIFY_ENTRY:
2670 /* Build peer_info block */
2671 peer_info->peer_type = MWL8K_PEER_TYPE_ACCESSPOINT;
2672 peer_info->basic_caps =
2673 cpu_to_le16(vif->bss_conf.assoc_capability);
2674 memcpy(peer_info->legacy_rates, mwl8k_rateids,
2675 sizeof(mwl8k_rateids));
2676 peer_info->interop = 1;
2677 peer_info->amsdu_enabled = 0;
2678
2679 rc = mwl8k_post_cmd(hw, &cmd->header);
2680 if (rc == 0)
2681 mv_vif->peer_id = peer_info->station_id;
2682 3079
2683 break; 3080static int mwl8k_cmd_update_stadb_del(struct ieee80211_hw *hw,
3081 struct ieee80211_vif *vif, u8 *addr)
3082{
3083 struct mwl8k_cmd_update_stadb *cmd;
3084 int rc;
2684 3085
2685 case MWL8K_STA_DB_DEL_ENTRY: 3086 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
2686 case MWL8K_STA_DB_FLUSH: 3087 if (cmd == NULL)
2687 default: 3088 return -ENOMEM;
2688 rc = mwl8k_post_cmd(hw, &cmd->header); 3089
2689 if (rc == 0) 3090 cmd->header.code = cpu_to_le16(MWL8K_CMD_UPDATE_STADB);
2690 mv_vif->peer_id = 0; 3091 cmd->header.length = cpu_to_le16(sizeof(*cmd));
2691 break; 3092 cmd->action = cpu_to_le32(MWL8K_STA_DB_DEL_ENTRY);
2692 } 3093 memcpy(cmd->peer_addr, addr, ETH_ALEN);
3094
3095 rc = mwl8k_post_cmd(hw, &cmd->header);
2693 kfree(cmd); 3096 kfree(cmd);
2694 3097
2695 return rc; 3098 return rc;
@@ -2706,19 +3109,22 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2706 u32 status; 3109 u32 status;
2707 3110
2708 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 3111 status = ioread32(priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2709 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
2710
2711 if (!status) 3112 if (!status)
2712 return IRQ_NONE; 3113 return IRQ_NONE;
2713 3114
2714 if (status & MWL8K_A2H_INT_TX_DONE) 3115 if (status & MWL8K_A2H_INT_TX_DONE) {
2715 tasklet_schedule(&priv->tx_reclaim_task); 3116 status &= ~MWL8K_A2H_INT_TX_DONE;
3117 tasklet_schedule(&priv->poll_tx_task);
3118 }
2716 3119
2717 if (status & MWL8K_A2H_INT_RX_READY) { 3120 if (status & MWL8K_A2H_INT_RX_READY) {
2718 while (rxq_process(hw, 0, 1)) 3121 status &= ~MWL8K_A2H_INT_RX_READY;
2719 rxq_refill(hw, 0, 1); 3122 tasklet_schedule(&priv->poll_rx_task);
2720 } 3123 }
2721 3124
3125 if (status)
3126 iowrite32(~status, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3127
2722 if (status & MWL8K_A2H_INT_OPC_DONE) { 3128 if (status & MWL8K_A2H_INT_OPC_DONE) {
2723 if (priv->hostcmd_wait != NULL) 3129 if (priv->hostcmd_wait != NULL)
2724 complete(priv->hostcmd_wait); 3130 complete(priv->hostcmd_wait);
@@ -2733,6 +3139,53 @@ static irqreturn_t mwl8k_interrupt(int irq, void *dev_id)
2733 return IRQ_HANDLED; 3139 return IRQ_HANDLED;
2734} 3140}
2735 3141
3142static void mwl8k_tx_poll(unsigned long data)
3143{
3144 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
3145 struct mwl8k_priv *priv = hw->priv;
3146 int limit;
3147 int i;
3148
3149 limit = 32;
3150
3151 spin_lock_bh(&priv->tx_lock);
3152
3153 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3154 limit -= mwl8k_txq_reclaim(hw, i, limit, 0);
3155
3156 if (!priv->pending_tx_pkts && priv->tx_wait != NULL) {
3157 complete(priv->tx_wait);
3158 priv->tx_wait = NULL;
3159 }
3160
3161 spin_unlock_bh(&priv->tx_lock);
3162
3163 if (limit) {
3164 writel(~MWL8K_A2H_INT_TX_DONE,
3165 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3166 } else {
3167 tasklet_schedule(&priv->poll_tx_task);
3168 }
3169}
3170
3171static void mwl8k_rx_poll(unsigned long data)
3172{
3173 struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
3174 struct mwl8k_priv *priv = hw->priv;
3175 int limit;
3176
3177 limit = 32;
3178 limit -= rxq_process(hw, 0, limit);
3179 limit -= rxq_refill(hw, 0, limit);
3180
3181 if (limit) {
3182 writel(~MWL8K_A2H_INT_RX_READY,
3183 priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3184 } else {
3185 tasklet_schedule(&priv->poll_rx_task);
3186 }
3187}
3188
2736 3189
2737/* 3190/*
2738 * Core driver operations. 3191 * Core driver operations.
@@ -2743,7 +3196,7 @@ static int mwl8k_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2743 int index = skb_get_queue_mapping(skb); 3196 int index = skb_get_queue_mapping(skb);
2744 int rc; 3197 int rc;
2745 3198
2746 if (priv->current_channel == NULL) { 3199 if (!priv->radio_on) {
2747 printk(KERN_DEBUG "%s: dropped TX frame since radio " 3200 printk(KERN_DEBUG "%s: dropped TX frame since radio "
2748 "disabled\n", wiphy_name(hw->wiphy)); 3201 "disabled\n", wiphy_name(hw->wiphy));
2749 dev_kfree_skb(skb); 3202 dev_kfree_skb(skb);
@@ -2768,8 +3221,9 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2768 return -EIO; 3221 return -EIO;
2769 } 3222 }
2770 3223
2771 /* Enable tx reclaim tasklet */ 3224 /* Enable TX reclaim and RX tasklets. */
2772 tasklet_enable(&priv->tx_reclaim_task); 3225 tasklet_enable(&priv->poll_tx_task);
3226 tasklet_enable(&priv->poll_rx_task);
2773 3227
2774 /* Enable interrupts */ 3228 /* Enable interrupts */
2775 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3229 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
@@ -2802,7 +3256,8 @@ static int mwl8k_start(struct ieee80211_hw *hw)
2802 if (rc) { 3256 if (rc) {
2803 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 3257 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
2804 free_irq(priv->pdev->irq, hw); 3258 free_irq(priv->pdev->irq, hw);
2805 tasklet_disable(&priv->tx_reclaim_task); 3259 tasklet_disable(&priv->poll_tx_task);
3260 tasklet_disable(&priv->poll_rx_task);
2806 } 3261 }
2807 3262
2808 return rc; 3263 return rc;
@@ -2826,36 +3281,27 @@ static void mwl8k_stop(struct ieee80211_hw *hw)
2826 if (priv->beacon_skb != NULL) 3281 if (priv->beacon_skb != NULL)
2827 dev_kfree_skb(priv->beacon_skb); 3282 dev_kfree_skb(priv->beacon_skb);
2828 3283
2829 /* Stop tx reclaim tasklet */ 3284 /* Stop TX reclaim and RX tasklets. */
2830 tasklet_disable(&priv->tx_reclaim_task); 3285 tasklet_disable(&priv->poll_tx_task);
3286 tasklet_disable(&priv->poll_rx_task);
2831 3287
2832 /* Return all skbs to mac80211 */ 3288 /* Return all skbs to mac80211 */
2833 for (i = 0; i < MWL8K_TX_QUEUES; i++) 3289 for (i = 0; i < MWL8K_TX_QUEUES; i++)
2834 mwl8k_txq_reclaim(hw, i, 1); 3290 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
2835} 3291}
2836 3292
2837static int mwl8k_add_interface(struct ieee80211_hw *hw, 3293static int mwl8k_add_interface(struct ieee80211_hw *hw,
2838 struct ieee80211_vif *vif) 3294 struct ieee80211_vif *vif)
2839{ 3295{
2840 struct mwl8k_priv *priv = hw->priv; 3296 struct mwl8k_priv *priv = hw->priv;
2841 struct mwl8k_vif *mwl8k_vif; 3297 struct mwl8k_vif *mwl8k_vif;
2842 3298 u32 macids_supported;
2843 /* 3299 int macid;
2844 * We only support one active interface at a time.
2845 */
2846 if (priv->vif != NULL)
2847 return -EBUSY;
2848
2849 /*
2850 * We only support managed interfaces for now.
2851 */
2852 if (vif->type != NL80211_IFTYPE_STATION)
2853 return -EINVAL;
2854 3300
2855 /* 3301 /*
2856 * Reject interface creation if sniffer mode is active, as 3302 * Reject interface creation if sniffer mode is active, as
2857 * STA operation is mutually exclusive with hardware sniffer 3303 * STA operation is mutually exclusive with hardware sniffer
2858 * mode. 3304 * mode. (Sniffer mode is only used on STA firmware.)
2859 */ 3305 */
2860 if (priv->sniffer_enabled) { 3306 if (priv->sniffer_enabled) {
2861 printk(KERN_INFO "%s: unable to create STA " 3307 printk(KERN_INFO "%s: unable to create STA "
@@ -2864,19 +3310,37 @@ static int mwl8k_add_interface(struct ieee80211_hw *hw,
2864 return -EINVAL; 3310 return -EINVAL;
2865 } 3311 }
2866 3312
2867 /* Clean out driver private area */ 3313
3314 switch (vif->type) {
3315 case NL80211_IFTYPE_AP:
3316 macids_supported = priv->ap_macids_supported;
3317 break;
3318 case NL80211_IFTYPE_STATION:
3319 macids_supported = priv->sta_macids_supported;
3320 break;
3321 default:
3322 return -EINVAL;
3323 }
3324
3325 macid = ffs(macids_supported & ~priv->macids_used);
3326 if (!macid--)
3327 return -EBUSY;
3328
3329 /* Setup driver private area. */
2868 mwl8k_vif = MWL8K_VIF(vif); 3330 mwl8k_vif = MWL8K_VIF(vif);
2869 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif)); 3331 memset(mwl8k_vif, 0, sizeof(*mwl8k_vif));
3332 mwl8k_vif->vif = vif;
3333 mwl8k_vif->macid = macid;
3334 mwl8k_vif->seqno = 0;
2870 3335
2871 /* Set and save the mac address */ 3336 /* Set the mac address. */
2872 mwl8k_cmd_set_mac_addr(hw, vif->addr); 3337 mwl8k_cmd_set_mac_addr(hw, vif, vif->addr);
2873 memcpy(mwl8k_vif->mac_addr, vif->addr, ETH_ALEN);
2874 3338
2875 /* Set Initial sequence number to zero */ 3339 if (priv->ap_fw)
2876 mwl8k_vif->seqno = 0; 3340 mwl8k_cmd_set_new_stn_add_self(hw, vif);
2877 3341
2878 priv->vif = vif; 3342 priv->macids_used |= 1 << mwl8k_vif->macid;
2879 priv->current_channel = NULL; 3343 list_add_tail(&mwl8k_vif->list, &priv->vif_list);
2880 3344
2881 return 0; 3345 return 0;
2882} 3346}
@@ -2885,13 +3349,15 @@ static void mwl8k_remove_interface(struct ieee80211_hw *hw,
2885 struct ieee80211_vif *vif) 3349 struct ieee80211_vif *vif)
2886{ 3350{
2887 struct mwl8k_priv *priv = hw->priv; 3351 struct mwl8k_priv *priv = hw->priv;
3352 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif);
2888 3353
2889 if (priv->vif == NULL) 3354 if (priv->ap_fw)
2890 return; 3355 mwl8k_cmd_set_new_stn_del(hw, vif, vif->addr);
2891 3356
2892 mwl8k_cmd_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00"); 3357 mwl8k_cmd_set_mac_addr(hw, vif, "\x00\x00\x00\x00\x00\x00");
2893 3358
2894 priv->vif = NULL; 3359 priv->macids_used &= ~(1 << mwl8k_vif->macid);
3360 list_del(&mwl8k_vif->list);
2895} 3361}
2896 3362
2897static int mwl8k_config(struct ieee80211_hw *hw, u32 changed) 3363static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
@@ -2902,7 +3368,6 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
2902 3368
2903 if (conf->flags & IEEE80211_CONF_IDLE) { 3369 if (conf->flags & IEEE80211_CONF_IDLE) {
2904 mwl8k_cmd_radio_disable(hw); 3370 mwl8k_cmd_radio_disable(hw);
2905 priv->current_channel = NULL;
2906 return 0; 3371 return 0;
2907 } 3372 }
2908 3373
@@ -2914,12 +3379,10 @@ static int mwl8k_config(struct ieee80211_hw *hw, u32 changed)
2914 if (rc) 3379 if (rc)
2915 goto out; 3380 goto out;
2916 3381
2917 rc = mwl8k_cmd_set_rf_channel(hw, conf->channel); 3382 rc = mwl8k_cmd_set_rf_channel(hw, conf);
2918 if (rc) 3383 if (rc)
2919 goto out; 3384 goto out;
2920 3385
2921 priv->current_channel = conf->channel;
2922
2923 if (conf->power_level > 18) 3386 if (conf->power_level > 18)
2924 conf->power_level = 18; 3387 conf->power_level = 18;
2925 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level); 3388 rc = mwl8k_cmd_rf_tx_power(hw, conf->power_level);
@@ -2940,75 +3403,160 @@ out:
2940 return rc; 3403 return rc;
2941} 3404}
2942 3405
2943static void mwl8k_bss_info_changed(struct ieee80211_hw *hw, 3406static void
2944 struct ieee80211_vif *vif, 3407mwl8k_bss_info_changed_sta(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2945 struct ieee80211_bss_conf *info, 3408 struct ieee80211_bss_conf *info, u32 changed)
2946 u32 changed)
2947{ 3409{
2948 struct mwl8k_priv *priv = hw->priv; 3410 struct mwl8k_priv *priv = hw->priv;
2949 struct mwl8k_vif *mwl8k_vif = MWL8K_VIF(vif); 3411 u32 ap_legacy_rates;
3412 u8 ap_mcs_rates[16];
2950 int rc; 3413 int rc;
2951 3414
2952 if ((changed & BSS_CHANGED_ASSOC) == 0) 3415 if (mwl8k_fw_lock(hw))
2953 return; 3416 return;
2954 3417
2955 priv->capture_beacon = false; 3418 /*
2956 3419 * No need to capture a beacon if we're no longer associated.
2957 rc = mwl8k_fw_lock(hw); 3420 */
2958 if (rc) 3421 if ((changed & BSS_CHANGED_ASSOC) && !vif->bss_conf.assoc)
2959 return; 3422 priv->capture_beacon = false;
2960 3423
3424 /*
3425 * Get the AP's legacy and MCS rates.
3426 */
2961 if (vif->bss_conf.assoc) { 3427 if (vif->bss_conf.assoc) {
2962 memcpy(mwl8k_vif->bssid, vif->bss_conf.bssid, ETH_ALEN); 3428 struct ieee80211_sta *ap;
3429
3430 rcu_read_lock();
3431
3432 ap = ieee80211_find_sta(vif, vif->bss_conf.bssid);
3433 if (ap == NULL) {
3434 rcu_read_unlock();
3435 goto out;
3436 }
3437
3438 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ) {
3439 ap_legacy_rates = ap->supp_rates[IEEE80211_BAND_2GHZ];
3440 } else {
3441 ap_legacy_rates =
3442 ap->supp_rates[IEEE80211_BAND_5GHZ] << 5;
3443 }
3444 memcpy(ap_mcs_rates, ap->ht_cap.mcs.rx_mask, 16);
3445
3446 rcu_read_unlock();
3447 }
2963 3448
2964 /* Install rates */ 3449 if ((changed & BSS_CHANGED_ASSOC) && vif->bss_conf.assoc) {
2965 rc = mwl8k_cmd_set_rate(hw, vif); 3450 rc = mwl8k_cmd_set_rate(hw, vif, ap_legacy_rates, ap_mcs_rates);
2966 if (rc) 3451 if (rc)
2967 goto out; 3452 goto out;
2968 3453
2969 /* Turn on rate adaptation */ 3454 rc = mwl8k_cmd_use_fixed_rate_sta(hw);
2970 rc = mwl8k_cmd_use_fixed_rate(hw, MWL8K_USE_AUTO_RATE,
2971 MWL8K_UCAST_RATE, NULL);
2972 if (rc) 3455 if (rc)
2973 goto out; 3456 goto out;
3457 }
2974 3458
2975 /* Set radio preamble */ 3459 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
2976 rc = mwl8k_set_radio_preamble(hw, 3460 rc = mwl8k_set_radio_preamble(hw,
2977 vif->bss_conf.use_short_preamble); 3461 vif->bss_conf.use_short_preamble);
2978 if (rc) 3462 if (rc)
2979 goto out; 3463 goto out;
3464 }
2980 3465
2981 /* Set slot time */ 3466 if (changed & BSS_CHANGED_ERP_SLOT) {
2982 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot); 3467 rc = mwl8k_cmd_set_slot(hw, vif->bss_conf.use_short_slot);
2983 if (rc) 3468 if (rc)
2984 goto out; 3469 goto out;
3470 }
2985 3471
2986 /* Update peer rate info */ 3472 if (vif->bss_conf.assoc &&
2987 rc = mwl8k_cmd_update_stadb(hw, vif, 3473 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_ERP_CTS_PROT |
2988 MWL8K_STA_DB_MODIFY_ENTRY); 3474 BSS_CHANGED_HT))) {
2989 if (rc) 3475 rc = mwl8k_cmd_set_aid(hw, vif, ap_legacy_rates);
2990 goto out;
2991
2992 /* Set AID */
2993 rc = mwl8k_cmd_set_aid(hw, vif);
2994 if (rc) 3476 if (rc)
2995 goto out; 3477 goto out;
3478 }
2996 3479
3480 if (vif->bss_conf.assoc &&
3481 (changed & (BSS_CHANGED_ASSOC | BSS_CHANGED_BEACON_INT))) {
2997 /* 3482 /*
2998 * Finalize the join. Tell rx handler to process 3483 * Finalize the join. Tell rx handler to process
2999 * next beacon from our BSSID. 3484 * next beacon from our BSSID.
3000 */ 3485 */
3001 memcpy(priv->capture_bssid, mwl8k_vif->bssid, ETH_ALEN); 3486 memcpy(priv->capture_bssid, vif->bss_conf.bssid, ETH_ALEN);
3002 priv->capture_beacon = true; 3487 priv->capture_beacon = true;
3003 } else {
3004 rc = mwl8k_cmd_update_stadb(hw, vif, MWL8K_STA_DB_DEL_ENTRY);
3005 memset(mwl8k_vif->bssid, 0, ETH_ALEN);
3006 } 3488 }
3007 3489
3008out: 3490out:
3009 mwl8k_fw_unlock(hw); 3491 mwl8k_fw_unlock(hw);
3010} 3492}
3011 3493
3494static void
3495mwl8k_bss_info_changed_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3496 struct ieee80211_bss_conf *info, u32 changed)
3497{
3498 int rc;
3499
3500 if (mwl8k_fw_lock(hw))
3501 return;
3502
3503 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
3504 rc = mwl8k_set_radio_preamble(hw,
3505 vif->bss_conf.use_short_preamble);
3506 if (rc)
3507 goto out;
3508 }
3509
3510 if (changed & BSS_CHANGED_BASIC_RATES) {
3511 int idx;
3512 int rate;
3513
3514 /*
3515 * Use lowest supported basic rate for multicasts
3516 * and management frames (such as probe responses --
3517 * beacons will always go out at 1 Mb/s).
3518 */
3519 idx = ffs(vif->bss_conf.basic_rates);
3520 if (idx)
3521 idx--;
3522
3523 if (hw->conf.channel->band == IEEE80211_BAND_2GHZ)
3524 rate = mwl8k_rates_24[idx].hw_value;
3525 else
3526 rate = mwl8k_rates_50[idx].hw_value;
3527
3528 mwl8k_cmd_use_fixed_rate_ap(hw, rate, rate);
3529 }
3530
3531 if (changed & (BSS_CHANGED_BEACON_INT | BSS_CHANGED_BEACON)) {
3532 struct sk_buff *skb;
3533
3534 skb = ieee80211_beacon_get(hw, vif);
3535 if (skb != NULL) {
3536 mwl8k_cmd_set_beacon(hw, vif, skb->data, skb->len);
3537 kfree_skb(skb);
3538 }
3539 }
3540
3541 if (changed & BSS_CHANGED_BEACON_ENABLED)
3542 mwl8k_cmd_bss_start(hw, vif, info->enable_beacon);
3543
3544out:
3545 mwl8k_fw_unlock(hw);
3546}
3547
3548static void
3549mwl8k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3550 struct ieee80211_bss_conf *info, u32 changed)
3551{
3552 struct mwl8k_priv *priv = hw->priv;
3553
3554 if (!priv->ap_fw)
3555 mwl8k_bss_info_changed_sta(hw, vif, info, changed);
3556 else
3557 mwl8k_bss_info_changed_ap(hw, vif, info, changed);
3558}
3559
3012static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw, 3560static u64 mwl8k_prepare_multicast(struct ieee80211_hw *hw,
3013 int mc_count, struct dev_addr_list *mclist) 3561 int mc_count, struct dev_addr_list *mclist)
3014{ 3562{
@@ -3038,7 +3586,7 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
3038 * operation, so refuse to enable sniffer mode if a STA 3586 * operation, so refuse to enable sniffer mode if a STA
3039 * interface is active. 3587 * interface is active.
3040 */ 3588 */
3041 if (priv->vif != NULL) { 3589 if (!list_empty(&priv->vif_list)) {
3042 if (net_ratelimit()) 3590 if (net_ratelimit())
3043 printk(KERN_INFO "%s: not enabling sniffer " 3591 printk(KERN_INFO "%s: not enabling sniffer "
3044 "mode because STA interface is active\n", 3592 "mode because STA interface is active\n",
@@ -3059,6 +3607,14 @@ mwl8k_configure_filter_sniffer(struct ieee80211_hw *hw,
3059 return 1; 3607 return 1;
3060} 3608}
3061 3609
3610static struct mwl8k_vif *mwl8k_first_vif(struct mwl8k_priv *priv)
3611{
3612 if (!list_empty(&priv->vif_list))
3613 return list_entry(priv->vif_list.next, struct mwl8k_vif, list);
3614
3615 return NULL;
3616}
3617
3062static void mwl8k_configure_filter(struct ieee80211_hw *hw, 3618static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3063 unsigned int changed_flags, 3619 unsigned int changed_flags,
3064 unsigned int *total_flags, 3620 unsigned int *total_flags,
@@ -3090,8 +3646,10 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3090 /* Clear unsupported feature flags */ 3646 /* Clear unsupported feature flags */
3091 *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC; 3647 *total_flags &= FIF_ALLMULTI | FIF_BCN_PRBRESP_PROMISC;
3092 3648
3093 if (mwl8k_fw_lock(hw)) 3649 if (mwl8k_fw_lock(hw)) {
3650 kfree(cmd);
3094 return; 3651 return;
3652 }
3095 3653
3096 if (priv->sniffer_enabled) { 3654 if (priv->sniffer_enabled) {
3097 mwl8k_cmd_enable_sniffer(hw, 0); 3655 mwl8k_cmd_enable_sniffer(hw, 0);
@@ -3105,7 +3663,8 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3105 */ 3663 */
3106 mwl8k_cmd_set_pre_scan(hw); 3664 mwl8k_cmd_set_pre_scan(hw);
3107 } else { 3665 } else {
3108 u8 *bssid; 3666 struct mwl8k_vif *mwl8k_vif;
3667 const u8 *bssid;
3109 3668
3110 /* 3669 /*
3111 * Enable the BSS filter. 3670 * Enable the BSS filter.
@@ -3115,9 +3674,11 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3115 * (where the OUI part needs to be nonzero for 3674 * (where the OUI part needs to be nonzero for
3116 * the BSSID to be accepted by POST_SCAN). 3675 * the BSSID to be accepted by POST_SCAN).
3117 */ 3676 */
3118 bssid = "\x01\x00\x00\x00\x00\x00"; 3677 mwl8k_vif = mwl8k_first_vif(priv);
3119 if (priv->vif != NULL) 3678 if (mwl8k_vif != NULL)
3120 bssid = MWL8K_VIF(priv->vif)->bssid; 3679 bssid = mwl8k_vif->vif->bss_conf.bssid;
3680 else
3681 bssid = "\x01\x00\x00\x00\x00\x00";
3121 3682
3122 mwl8k_cmd_set_post_scan(hw, bssid); 3683 mwl8k_cmd_set_post_scan(hw, bssid);
3123 } 3684 }
@@ -3144,7 +3705,93 @@ static void mwl8k_configure_filter(struct ieee80211_hw *hw,
3144 3705
3145static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value) 3706static int mwl8k_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
3146{ 3707{
3147 return mwl8k_cmd_set_rts_threshold(hw, MWL8K_CMD_SET, value); 3708 return mwl8k_cmd_set_rts_threshold(hw, value);
3709}
3710
3711struct mwl8k_sta_notify_item
3712{
3713 struct list_head list;
3714 struct ieee80211_vif *vif;
3715 enum sta_notify_cmd cmd;
3716 struct ieee80211_sta sta;
3717};
3718
3719static void
3720mwl8k_do_sta_notify(struct ieee80211_hw *hw, struct mwl8k_sta_notify_item *s)
3721{
3722 struct mwl8k_priv *priv = hw->priv;
3723
3724 /*
3725 * STA firmware uses UPDATE_STADB, AP firmware uses SET_NEW_STN.
3726 */
3727 if (!priv->ap_fw && s->cmd == STA_NOTIFY_ADD) {
3728 int rc;
3729
3730 rc = mwl8k_cmd_update_stadb_add(hw, s->vif, &s->sta);
3731 if (rc >= 0) {
3732 struct ieee80211_sta *sta;
3733
3734 rcu_read_lock();
3735 sta = ieee80211_find_sta(s->vif, s->sta.addr);
3736 if (sta != NULL)
3737 MWL8K_STA(sta)->peer_id = rc;
3738 rcu_read_unlock();
3739 }
3740 } else if (!priv->ap_fw && s->cmd == STA_NOTIFY_REMOVE) {
3741 mwl8k_cmd_update_stadb_del(hw, s->vif, s->sta.addr);
3742 } else if (priv->ap_fw && s->cmd == STA_NOTIFY_ADD) {
3743 mwl8k_cmd_set_new_stn_add(hw, s->vif, &s->sta);
3744 } else if (priv->ap_fw && s->cmd == STA_NOTIFY_REMOVE) {
3745 mwl8k_cmd_set_new_stn_del(hw, s->vif, s->sta.addr);
3746 }
3747}
3748
3749static void mwl8k_sta_notify_worker(struct work_struct *work)
3750{
3751 struct mwl8k_priv *priv =
3752 container_of(work, struct mwl8k_priv, sta_notify_worker);
3753 struct ieee80211_hw *hw = priv->hw;
3754
3755 spin_lock_bh(&priv->sta_notify_list_lock);
3756 while (!list_empty(&priv->sta_notify_list)) {
3757 struct mwl8k_sta_notify_item *s;
3758
3759 s = list_entry(priv->sta_notify_list.next,
3760 struct mwl8k_sta_notify_item, list);
3761 list_del(&s->list);
3762
3763 spin_unlock_bh(&priv->sta_notify_list_lock);
3764
3765 mwl8k_do_sta_notify(hw, s);
3766 kfree(s);
3767
3768 spin_lock_bh(&priv->sta_notify_list_lock);
3769 }
3770 spin_unlock_bh(&priv->sta_notify_list_lock);
3771}
3772
3773static void
3774mwl8k_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3775 enum sta_notify_cmd cmd, struct ieee80211_sta *sta)
3776{
3777 struct mwl8k_priv *priv = hw->priv;
3778 struct mwl8k_sta_notify_item *s;
3779
3780 if (cmd != STA_NOTIFY_ADD && cmd != STA_NOTIFY_REMOVE)
3781 return;
3782
3783 s = kmalloc(sizeof(*s), GFP_ATOMIC);
3784 if (s != NULL) {
3785 s->vif = vif;
3786 s->cmd = cmd;
3787 s->sta = *sta;
3788
3789 spin_lock(&priv->sta_notify_list_lock);
3790 list_add_tail(&s->list, &priv->sta_notify_list);
3791 spin_unlock(&priv->sta_notify_list_lock);
3792
3793 ieee80211_queue_work(hw, &priv->sta_notify_worker);
3794 }
3148} 3795}
3149 3796
3150static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue, 3797static int mwl8k_conf_tx(struct ieee80211_hw *hw, u16 queue,
@@ -3195,6 +3842,22 @@ static int mwl8k_get_stats(struct ieee80211_hw *hw,
3195 return mwl8k_cmd_get_stat(hw, stats); 3842 return mwl8k_cmd_get_stat(hw, stats);
3196} 3843}
3197 3844
3845static int
3846mwl8k_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3847 enum ieee80211_ampdu_mlme_action action,
3848 struct ieee80211_sta *sta, u16 tid, u16 *ssn)
3849{
3850 switch (action) {
3851 case IEEE80211_AMPDU_RX_START:
3852 case IEEE80211_AMPDU_RX_STOP:
3853 if (!(hw->flags & IEEE80211_HW_AMPDU_AGGREGATION))
3854 return -ENOTSUPP;
3855 return 0;
3856 default:
3857 return -ENOTSUPP;
3858 }
3859}
3860
3198static const struct ieee80211_ops mwl8k_ops = { 3861static const struct ieee80211_ops mwl8k_ops = {
3199 .tx = mwl8k_tx, 3862 .tx = mwl8k_tx,
3200 .start = mwl8k_start, 3863 .start = mwl8k_start,
@@ -3206,47 +3869,41 @@ static const struct ieee80211_ops mwl8k_ops = {
3206 .prepare_multicast = mwl8k_prepare_multicast, 3869 .prepare_multicast = mwl8k_prepare_multicast,
3207 .configure_filter = mwl8k_configure_filter, 3870 .configure_filter = mwl8k_configure_filter,
3208 .set_rts_threshold = mwl8k_set_rts_threshold, 3871 .set_rts_threshold = mwl8k_set_rts_threshold,
3872 .sta_notify = mwl8k_sta_notify,
3209 .conf_tx = mwl8k_conf_tx, 3873 .conf_tx = mwl8k_conf_tx,
3210 .get_tx_stats = mwl8k_get_tx_stats, 3874 .get_tx_stats = mwl8k_get_tx_stats,
3211 .get_stats = mwl8k_get_stats, 3875 .get_stats = mwl8k_get_stats,
3876 .ampdu_action = mwl8k_ampdu_action,
3212}; 3877};
3213 3878
3214static void mwl8k_tx_reclaim_handler(unsigned long data)
3215{
3216 int i;
3217 struct ieee80211_hw *hw = (struct ieee80211_hw *) data;
3218 struct mwl8k_priv *priv = hw->priv;
3219
3220 spin_lock_bh(&priv->tx_lock);
3221 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3222 mwl8k_txq_reclaim(hw, i, 0);
3223
3224 if (priv->tx_wait != NULL && !priv->pending_tx_pkts) {
3225 complete(priv->tx_wait);
3226 priv->tx_wait = NULL;
3227 }
3228 spin_unlock_bh(&priv->tx_lock);
3229}
3230
3231static void mwl8k_finalize_join_worker(struct work_struct *work) 3879static void mwl8k_finalize_join_worker(struct work_struct *work)
3232{ 3880{
3233 struct mwl8k_priv *priv = 3881 struct mwl8k_priv *priv =
3234 container_of(work, struct mwl8k_priv, finalize_join_worker); 3882 container_of(work, struct mwl8k_priv, finalize_join_worker);
3235 struct sk_buff *skb = priv->beacon_skb; 3883 struct sk_buff *skb = priv->beacon_skb;
3884 struct mwl8k_vif *mwl8k_vif;
3236 3885
3237 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len, 3886 mwl8k_vif = mwl8k_first_vif(priv);
3238 priv->vif->bss_conf.dtim_period); 3887 if (mwl8k_vif != NULL)
3239 dev_kfree_skb(skb); 3888 mwl8k_cmd_finalize_join(priv->hw, skb->data, skb->len,
3889 mwl8k_vif->vif->bss_conf.dtim_period);
3240 3890
3891 dev_kfree_skb(skb);
3241 priv->beacon_skb = NULL; 3892 priv->beacon_skb = NULL;
3242} 3893}
3243 3894
3244enum { 3895enum {
3245 MWL8687 = 0, 3896 MWL8363 = 0,
3897 MWL8687,
3246 MWL8366, 3898 MWL8366,
3247}; 3899};
3248 3900
3249static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = { 3901static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
3902 [MWL8363] = {
3903 .part_name = "88w8363",
3904 .helper_image = "mwl8k/helper_8363.fw",
3905 .fw_image = "mwl8k/fmimage_8363.fw",
3906 },
3250 [MWL8687] = { 3907 [MWL8687] = {
3251 .part_name = "88w8687", 3908 .part_name = "88w8687",
3252 .helper_image = "mwl8k/helper_8687.fw", 3909 .helper_image = "mwl8k/helper_8687.fw",
@@ -3260,10 +3917,20 @@ static struct mwl8k_device_info mwl8k_info_tbl[] __devinitdata = {
3260 }, 3917 },
3261}; 3918};
3262 3919
3920MODULE_FIRMWARE("mwl8k/helper_8363.fw");
3921MODULE_FIRMWARE("mwl8k/fmimage_8363.fw");
3922MODULE_FIRMWARE("mwl8k/helper_8687.fw");
3923MODULE_FIRMWARE("mwl8k/fmimage_8687.fw");
3924MODULE_FIRMWARE("mwl8k/helper_8366.fw");
3925MODULE_FIRMWARE("mwl8k/fmimage_8366.fw");
3926
3263static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = { 3927static DEFINE_PCI_DEVICE_TABLE(mwl8k_pci_id_table) = {
3928 { PCI_VDEVICE(MARVELL, 0x2a0c), .driver_data = MWL8363, },
3929 { PCI_VDEVICE(MARVELL, 0x2a24), .driver_data = MWL8363, },
3264 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, }, 3930 { PCI_VDEVICE(MARVELL, 0x2a2b), .driver_data = MWL8687, },
3265 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, }, 3931 { PCI_VDEVICE(MARVELL, 0x2a30), .driver_data = MWL8687, },
3266 { PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, }, 3932 { PCI_VDEVICE(MARVELL, 0x2a40), .driver_data = MWL8366, },
3933 { PCI_VDEVICE(MARVELL, 0x2a43), .driver_data = MWL8366, },
3267 { }, 3934 { },
3268}; 3935};
3269MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table); 3936MODULE_DEVICE_TABLE(pci, mwl8k_pci_id_table);
@@ -3361,27 +4028,23 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3361 mwl8k_release_firmware(priv); 4028 mwl8k_release_firmware(priv);
3362 4029
3363 4030
3364 if (priv->ap_fw) 4031 if (priv->ap_fw) {
3365 priv->rxd_ops = priv->device_info->ap_rxd_ops; 4032 priv->rxd_ops = priv->device_info->ap_rxd_ops;
3366 else 4033 if (priv->rxd_ops == NULL) {
4034 printk(KERN_ERR "%s: Driver does not have AP "
4035 "firmware image support for this hardware\n",
4036 wiphy_name(hw->wiphy));
4037 goto err_stop_firmware;
4038 }
4039 } else {
3367 priv->rxd_ops = &rxd_sta_ops; 4040 priv->rxd_ops = &rxd_sta_ops;
4041 }
3368 4042
3369 priv->sniffer_enabled = false; 4043 priv->sniffer_enabled = false;
3370 priv->wmm_enabled = false; 4044 priv->wmm_enabled = false;
3371 priv->pending_tx_pkts = 0; 4045 priv->pending_tx_pkts = 0;
3372 4046
3373 4047
3374 memcpy(priv->channels, mwl8k_channels, sizeof(mwl8k_channels));
3375 priv->band.band = IEEE80211_BAND_2GHZ;
3376 priv->band.channels = priv->channels;
3377 priv->band.n_channels = ARRAY_SIZE(mwl8k_channels);
3378 priv->band.bitrates = priv->rates;
3379 priv->band.n_bitrates = ARRAY_SIZE(mwl8k_rates);
3380 hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &priv->band;
3381
3382 BUILD_BUG_ON(sizeof(priv->rates) != sizeof(mwl8k_rates));
3383 memcpy(priv->rates, mwl8k_rates, sizeof(mwl8k_rates));
3384
3385 /* 4048 /*
3386 * Extra headroom is the size of the required DMA header 4049 * Extra headroom is the size of the required DMA header
3387 * minus the size of the smallest 802.11 frame (CTS frame). 4050 * minus the size of the smallest 802.11 frame (CTS frame).
@@ -3396,19 +4059,28 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3396 /* Set rssi and noise values to dBm */ 4059 /* Set rssi and noise values to dBm */
3397 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM; 4060 hw->flags |= IEEE80211_HW_SIGNAL_DBM | IEEE80211_HW_NOISE_DBM;
3398 hw->vif_data_size = sizeof(struct mwl8k_vif); 4061 hw->vif_data_size = sizeof(struct mwl8k_vif);
3399 priv->vif = NULL; 4062 hw->sta_data_size = sizeof(struct mwl8k_sta);
4063
4064 priv->macids_used = 0;
4065 INIT_LIST_HEAD(&priv->vif_list);
3400 4066
3401 /* Set default radio state and preamble */ 4067 /* Set default radio state and preamble */
3402 priv->radio_on = 0; 4068 priv->radio_on = 0;
3403 priv->radio_short_preamble = 0; 4069 priv->radio_short_preamble = 0;
3404 4070
4071 /* Station database handling */
4072 INIT_WORK(&priv->sta_notify_worker, mwl8k_sta_notify_worker);
4073 spin_lock_init(&priv->sta_notify_list_lock);
4074 INIT_LIST_HEAD(&priv->sta_notify_list);
4075
3405 /* Finalize join worker */ 4076 /* Finalize join worker */
3406 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker); 4077 INIT_WORK(&priv->finalize_join_worker, mwl8k_finalize_join_worker);
3407 4078
3408 /* TX reclaim tasklet */ 4079 /* TX reclaim and RX tasklets. */
3409 tasklet_init(&priv->tx_reclaim_task, 4080 tasklet_init(&priv->poll_tx_task, mwl8k_tx_poll, (unsigned long)hw);
3410 mwl8k_tx_reclaim_handler, (unsigned long)hw); 4081 tasklet_disable(&priv->poll_tx_task);
3411 tasklet_disable(&priv->tx_reclaim_task); 4082 tasklet_init(&priv->poll_rx_task, mwl8k_rx_poll, (unsigned long)hw);
4083 tasklet_disable(&priv->poll_rx_task);
3412 4084
3413 /* Power management cookie */ 4085 /* Power management cookie */
3414 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma); 4086 priv->cookie = pci_alloc_consistent(priv->pdev, 4, &priv->cookie_dma);
@@ -3437,7 +4109,8 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3437 4109
3438 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS); 4110 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS);
3439 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4111 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
3440 iowrite32(0, priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL); 4112 iowrite32(MWL8K_A2H_INT_TX_DONE | MWL8K_A2H_INT_RX_READY,
4113 priv->regs + MWL8K_HIU_A2H_INTERRUPT_CLEAR_SEL);
3441 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK); 4114 iowrite32(0xffffffff, priv->regs + MWL8K_HIU_A2H_INTERRUPT_STATUS_MASK);
3442 4115
3443 rc = request_irq(priv->pdev->irq, mwl8k_interrupt, 4116 rc = request_irq(priv->pdev->irq, mwl8k_interrupt,
@@ -3450,7 +4123,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3450 4123
3451 /* 4124 /*
3452 * Temporarily enable interrupts. Initial firmware host 4125 * Temporarily enable interrupts. Initial firmware host
3453 * commands use interrupts and avoids polling. Disable 4126 * commands use interrupts and avoid polling. Disable
3454 * interrupts when done. 4127 * interrupts when done.
3455 */ 4128 */
3456 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK); 4129 iowrite32(MWL8K_A2H_EVENTS, priv->regs + MWL8K_HIU_A2H_INTERRUPT_MASK);
@@ -3462,8 +4135,6 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3462 rc = mwl8k_cmd_set_hw_spec(hw); 4135 rc = mwl8k_cmd_set_hw_spec(hw);
3463 } else { 4136 } else {
3464 rc = mwl8k_cmd_get_hw_spec_sta(hw); 4137 rc = mwl8k_cmd_get_hw_spec_sta(hw);
3465
3466 hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
3467 } 4138 }
3468 if (rc) { 4139 if (rc) {
3469 printk(KERN_ERR "%s: Cannot initialise firmware\n", 4140 printk(KERN_ERR "%s: Cannot initialise firmware\n",
@@ -3471,6 +4142,13 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3471 goto err_free_irq; 4142 goto err_free_irq;
3472 } 4143 }
3473 4144
4145 hw->wiphy->interface_modes = 0;
4146 if (priv->ap_macids_supported)
4147 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_AP);
4148 if (priv->sta_macids_supported)
4149 hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_STATION);
4150
4151
3474 /* Turn radio off */ 4152 /* Turn radio off */
3475 rc = mwl8k_cmd_radio_disable(hw); 4153 rc = mwl8k_cmd_radio_disable(hw);
3476 if (rc) { 4154 if (rc) {
@@ -3479,7 +4157,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3479 } 4157 }
3480 4158
3481 /* Clear MAC address */ 4159 /* Clear MAC address */
3482 rc = mwl8k_cmd_set_mac_addr(hw, "\x00\x00\x00\x00\x00\x00"); 4160 rc = mwl8k_cmd_set_mac_addr(hw, NULL, "\x00\x00\x00\x00\x00\x00");
3483 if (rc) { 4161 if (rc) {
3484 printk(KERN_ERR "%s: Cannot clear MAC address\n", 4162 printk(KERN_ERR "%s: Cannot clear MAC address\n",
3485 wiphy_name(hw->wiphy)); 4163 wiphy_name(hw->wiphy));
@@ -3494,7 +4172,7 @@ static int __devinit mwl8k_probe(struct pci_dev *pdev,
3494 if (rc) { 4172 if (rc) {
3495 printk(KERN_ERR "%s: Cannot register device\n", 4173 printk(KERN_ERR "%s: Cannot register device\n",
3496 wiphy_name(hw->wiphy)); 4174 wiphy_name(hw->wiphy));
3497 goto err_free_irq; 4175 goto err_free_queues;
3498 } 4176 }
3499 4177
3500 printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n", 4178 printk(KERN_INFO "%s: %s v%d, %pM, %s firmware %u.%u.%u.%u\n",
@@ -3562,15 +4240,16 @@ static void __devexit mwl8k_remove(struct pci_dev *pdev)
3562 4240
3563 ieee80211_unregister_hw(hw); 4241 ieee80211_unregister_hw(hw);
3564 4242
3565 /* Remove tx reclaim tasklet */ 4243 /* Remove TX reclaim and RX tasklets. */
3566 tasklet_kill(&priv->tx_reclaim_task); 4244 tasklet_kill(&priv->poll_tx_task);
4245 tasklet_kill(&priv->poll_rx_task);
3567 4246
3568 /* Stop hardware */ 4247 /* Stop hardware */
3569 mwl8k_hw_reset(priv); 4248 mwl8k_hw_reset(priv);
3570 4249
3571 /* Return all skbs to mac80211 */ 4250 /* Return all skbs to mac80211 */
3572 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4251 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3573 mwl8k_txq_reclaim(hw, i, 1); 4252 mwl8k_txq_reclaim(hw, i, INT_MAX, 1);
3574 4253
3575 for (i = 0; i < MWL8K_TX_QUEUES; i++) 4254 for (i = 0; i < MWL8K_TX_QUEUES; i++)
3576 mwl8k_txq_deinit(hw, i); 4255 mwl8k_txq_deinit(hw, i);
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 8ff7db853286..529a37364eb0 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -245,6 +245,25 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
245} 245}
246EXPORT_SYMBOL_GPL(rt2800_mcu_request); 246EXPORT_SYMBOL_GPL(rt2800_mcu_request);
247 247
248int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
249{
250 unsigned int i;
251 u32 reg;
252
253 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
254 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
255 if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
256 !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
257 return 0;
258
259 msleep(1);
260 }
261
262 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
263 return -EACCES;
264}
265EXPORT_SYMBOL_GPL(rt2800_wait_wpdma_ready);
266
248#ifdef CONFIG_RT2X00_LIB_DEBUGFS 267#ifdef CONFIG_RT2X00_LIB_DEBUGFS
249const struct rt2x00debug rt2800_rt2x00debug = { 268const struct rt2x00debug rt2800_rt2x00debug = {
250 .owner = THIS_MODULE, 269 .owner = THIS_MODULE,
@@ -339,7 +358,7 @@ static int rt2800_blink_set(struct led_classdev *led_cdev,
339 rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off); 358 rt2x00_set_field32(&reg, LED_CFG_OFF_PERIOD, *delay_off);
340 rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3); 359 rt2x00_set_field32(&reg, LED_CFG_SLOW_BLINK_PERIOD, 3);
341 rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3); 360 rt2x00_set_field32(&reg, LED_CFG_R_LED_MODE, 3);
342 rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 12); 361 rt2x00_set_field32(&reg, LED_CFG_G_LED_MODE, 3);
343 rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3); 362 rt2x00_set_field32(&reg, LED_CFG_Y_LED_MODE, 3);
344 rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1); 363 rt2x00_set_field32(&reg, LED_CFG_LED_POLAR, 1);
345 rt2800_register_write(led->rt2x00dev, LED_CFG, reg); 364 rt2800_register_write(led->rt2x00dev, LED_CFG, reg);
@@ -347,7 +366,7 @@ static int rt2800_blink_set(struct led_classdev *led_cdev,
347 return 0; 366 return 0;
348} 367}
349 368
350void rt2800_init_led(struct rt2x00_dev *rt2x00dev, 369static void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
351 struct rt2x00_led *led, enum led_type type) 370 struct rt2x00_led *led, enum led_type type)
352{ 371{
353 led->rt2x00dev = rt2x00dev; 372 led->rt2x00dev = rt2x00dev;
@@ -356,7 +375,6 @@ void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
356 led->led_dev.blink_set = rt2800_blink_set; 375 led->led_dev.blink_set = rt2800_blink_set;
357 led->flags = LED_INITIALIZED; 376 led->flags = LED_INITIALIZED;
358} 377}
359EXPORT_SYMBOL_GPL(rt2800_init_led);
360#endif /* CONFIG_RT2X00_LIB_LEDS */ 378#endif /* CONFIG_RT2X00_LIB_LEDS */
361 379
362/* 380/*
@@ -1862,7 +1880,8 @@ int rt2800_init_eeprom(struct rt2x00_dev *rt2x00dev)
1862 !rt2x00_rf(rt2x00dev, RF3020) && 1880 !rt2x00_rf(rt2x00dev, RF3020) &&
1863 !rt2x00_rf(rt2x00dev, RF2020) && 1881 !rt2x00_rf(rt2x00dev, RF2020) &&
1864 !rt2x00_rf(rt2x00dev, RF3021) && 1882 !rt2x00_rf(rt2x00dev, RF3021) &&
1865 !rt2x00_rf(rt2x00dev, RF3022)) { 1883 !rt2x00_rf(rt2x00dev, RF3022) &&
1884 !rt2x00_rf(rt2x00dev, RF3052)) {
1866 ERROR(rt2x00dev, "Invalid RF chipset detected.\n"); 1885 ERROR(rt2x00dev, "Invalid RF chipset detected.\n");
1867 return -ENODEV; 1886 return -ENODEV;
1868 } 1887 }
@@ -2047,7 +2066,7 @@ int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2047 2066
2048 if (rt2x00_rf(rt2x00dev, RF2820) || 2067 if (rt2x00_rf(rt2x00dev, RF2820) ||
2049 rt2x00_rf(rt2x00dev, RF2720) || 2068 rt2x00_rf(rt2x00dev, RF2720) ||
2050 (rt2x00_intf_is_pci(rt2x00dev) && rt2x00_rf(rt2x00dev, RF3052))) { 2069 rt2x00_rf(rt2x00dev, RF3052)) {
2051 spec->num_channels = 14; 2070 spec->num_channels = 14;
2052 spec->channels = rf_vals; 2071 spec->channels = rf_vals;
2053 } else if (rt2x00_rf(rt2x00dev, RF2850) || rt2x00_rf(rt2x00dev, RF2750)) { 2072 } else if (rt2x00_rf(rt2x00dev, RF2850) || rt2x00_rf(rt2x00dev, RF2750)) {
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.h b/drivers/net/wireless/rt2x00/rt2800lib.h
index 535ce22f2ac8..ebabeae62d1b 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.h
+++ b/drivers/net/wireless/rt2x00/rt2800lib.h
@@ -114,8 +114,6 @@ void rt2800_mcu_request(struct rt2x00_dev *rt2x00dev,
114extern const struct rt2x00debug rt2800_rt2x00debug; 114extern const struct rt2x00debug rt2800_rt2x00debug;
115 115
116int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev); 116int rt2800_rfkill_poll(struct rt2x00_dev *rt2x00dev);
117void rt2800_init_led(struct rt2x00_dev *rt2x00dev,
118 struct rt2x00_led *led, enum led_type type);
119int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev, 117int rt2800_config_shared_key(struct rt2x00_dev *rt2x00dev,
120 struct rt2x00lib_crypto *crypto, 118 struct rt2x00lib_crypto *crypto,
121 struct ieee80211_key_conf *key); 119 struct ieee80211_key_conf *key);
@@ -139,6 +137,7 @@ void rt2800_link_tuner(struct rt2x00_dev *rt2x00dev, struct link_qual *qual,
139int rt2800_init_registers(struct rt2x00_dev *rt2x00dev); 137int rt2800_init_registers(struct rt2x00_dev *rt2x00dev);
140int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev); 138int rt2800_init_bbp(struct rt2x00_dev *rt2x00dev);
141int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev); 139int rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev);
140int rt2800_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev);
142 141
143int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev); 142int rt2800_efuse_detect(struct rt2x00_dev *rt2x00dev);
144void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev); 143void rt2800_read_eeprom_efuse(struct rt2x00_dev *rt2x00dev);
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 99095e1ee13b..d64181cbc9cb 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -453,24 +453,6 @@ static void rt2800pci_toggle_irq(struct rt2x00_dev *rt2x00dev,
453 rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg); 453 rt2800_register_write(rt2x00dev, INT_MASK_CSR, reg);
454} 454}
455 455
456static int rt2800pci_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
457{
458 unsigned int i;
459 u32 reg;
460
461 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
462 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
463 if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
464 !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
465 return 0;
466
467 msleep(1);
468 }
469
470 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
471 return -EACCES;
472}
473
474static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev) 456static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
475{ 457{
476 u32 reg; 458 u32 reg;
@@ -479,10 +461,10 @@ static int rt2800pci_enable_radio(struct rt2x00_dev *rt2x00dev)
479 /* 461 /*
480 * Initialize all registers. 462 * Initialize all registers.
481 */ 463 */
482 if (unlikely(rt2800pci_wait_wpdma_ready(rt2x00dev) || 464 if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
483 rt2800pci_init_queues(rt2x00dev) || 465 rt2800pci_init_queues(rt2x00dev) ||
484 rt2800_init_registers(rt2x00dev) || 466 rt2800_init_registers(rt2x00dev) ||
485 rt2800pci_wait_wpdma_ready(rt2x00dev) || 467 rt2800_wait_wpdma_ready(rt2x00dev) ||
486 rt2800_init_bbp(rt2x00dev) || 468 rt2800_init_bbp(rt2x00dev) ||
487 rt2800_init_rfcsr(rt2x00dev))) 469 rt2800_init_rfcsr(rt2x00dev)))
488 return -EIO; 470 return -EIO;
@@ -562,7 +544,7 @@ static void rt2800pci_disable_radio(struct rt2x00_dev *rt2x00dev)
562 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00); 544 rt2800_register_write(rt2x00dev, PBF_SYS_CTRL, 0x00000e00);
563 545
564 /* Wait for DMA, ignore error */ 546 /* Wait for DMA, ignore error */
565 rt2800pci_wait_wpdma_ready(rt2x00dev); 547 rt2800_wait_wpdma_ready(rt2x00dev);
566} 548}
567 549
568static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev, 550static int rt2800pci_set_state(struct rt2x00_dev *rt2x00dev,
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 0510f020dcf5..82755cf8b73e 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -248,24 +248,6 @@ static void rt2800usb_toggle_rx(struct rt2x00_dev *rt2x00dev,
248 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg); 248 rt2800_register_write(rt2x00dev, MAC_SYS_CTRL, reg);
249} 249}
250 250
251static int rt2800usb_wait_wpdma_ready(struct rt2x00_dev *rt2x00dev)
252{
253 unsigned int i;
254 u32 reg;
255
256 for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
257 rt2800_register_read(rt2x00dev, WPDMA_GLO_CFG, &reg);
258 if (!rt2x00_get_field32(reg, WPDMA_GLO_CFG_TX_DMA_BUSY) &&
259 !rt2x00_get_field32(reg, WPDMA_GLO_CFG_RX_DMA_BUSY))
260 return 0;
261
262 msleep(1);
263 }
264
265 ERROR(rt2x00dev, "WPDMA TX/RX busy, aborting.\n");
266 return -EACCES;
267}
268
269static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev) 251static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
270{ 252{
271 u32 reg; 253 u32 reg;
@@ -274,7 +256,7 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
274 /* 256 /*
275 * Initialize all registers. 257 * Initialize all registers.
276 */ 258 */
277 if (unlikely(rt2800usb_wait_wpdma_ready(rt2x00dev) || 259 if (unlikely(rt2800_wait_wpdma_ready(rt2x00dev) ||
278 rt2800_init_registers(rt2x00dev) || 260 rt2800_init_registers(rt2x00dev) ||
279 rt2800_init_bbp(rt2x00dev) || 261 rt2800_init_bbp(rt2x00dev) ||
280 rt2800_init_rfcsr(rt2x00dev))) 262 rt2800_init_rfcsr(rt2x00dev)))
@@ -344,7 +326,7 @@ static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
344 rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0); 326 rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0);
345 327
346 /* Wait for DMA, ignore error */ 328 /* Wait for DMA, ignore error */
347 rt2800usb_wait_wpdma_ready(rt2x00dev); 329 rt2800_wait_wpdma_ready(rt2x00dev);
348 330
349 rt2x00usb_disable_radio(rt2x00dev); 331 rt2x00usb_disable_radio(rt2x00dev);
350} 332}
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index b4c6e0a6d7e0..096da85a66fa 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -119,6 +119,12 @@
119 ( ((unsigned long)((__skb)->data + (__header))) & 3 ) 119 ( ((unsigned long)((__skb)->data + (__header))) & 3 )
120 120
121/* 121/*
122 * Constants for extra TX headroom for alignment purposes.
123 */
124#define RT2X00_ALIGN_SIZE 4 /* Only whole frame needs alignment */
125#define RT2X00_L2PAD_SIZE 8 /* Both header & payload need alignment */
126
127/*
122 * Standard timing and size defines. 128 * Standard timing and size defines.
123 * These values should follow the ieee80211 specifications. 129 * These values should follow the ieee80211 specifications.
124 */ 130 */
diff --git a/drivers/net/wireless/rt2x00/rt2x00dev.c b/drivers/net/wireless/rt2x00/rt2x00dev.c
index d7711e4d4751..b93731b79903 100644
--- a/drivers/net/wireless/rt2x00/rt2x00dev.c
+++ b/drivers/net/wireless/rt2x00/rt2x00dev.c
@@ -688,7 +688,17 @@ static int rt2x00lib_probe_hw(struct rt2x00_dev *rt2x00dev)
688 /* 688 /*
689 * Initialize extra TX headroom required. 689 * Initialize extra TX headroom required.
690 */ 690 */
691 rt2x00dev->hw->extra_tx_headroom = rt2x00dev->ops->extra_tx_headroom; 691 rt2x00dev->hw->extra_tx_headroom =
692 max_t(unsigned int, IEEE80211_TX_STATUS_HEADROOM,
693 rt2x00dev->ops->extra_tx_headroom);
694
695 /*
696 * Take TX headroom required for alignment into account.
697 */
698 if (test_bit(DRIVER_REQUIRE_L2PAD, &rt2x00dev->flags))
699 rt2x00dev->hw->extra_tx_headroom += RT2X00_L2PAD_SIZE;
700 else if (test_bit(DRIVER_REQUIRE_DMA, &rt2x00dev->flags))
701 rt2x00dev->hw->extra_tx_headroom += RT2X00_ALIGN_SIZE;
692 702
693 /* 703 /*
694 * Register HW. 704 * Register HW.
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 3d8fb684b4eb..0b4801a14601 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -104,7 +104,7 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
104 * is also mapped to the DMA so it can be used for transfering 104 * is also mapped to the DMA so it can be used for transfering
105 * additional descriptor information to the hardware. 105 * additional descriptor information to the hardware.
106 */ 106 */
107 skb_push(skb, rt2x00dev->hw->extra_tx_headroom); 107 skb_push(skb, rt2x00dev->ops->extra_tx_headroom);
108 108
109 skbdesc->skb_dma = 109 skbdesc->skb_dma =
110 dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE); 110 dma_map_single(rt2x00dev->dev, skb->data, skb->len, DMA_TO_DEVICE);
@@ -112,7 +112,7 @@ void rt2x00queue_map_txskb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
112 /* 112 /*
113 * Restore data pointer to original location again. 113 * Restore data pointer to original location again.
114 */ 114 */
115 skb_pull(skb, rt2x00dev->hw->extra_tx_headroom); 115 skb_pull(skb, rt2x00dev->ops->extra_tx_headroom);
116 116
117 skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; 117 skbdesc->flags |= SKBDESC_DMA_MAPPED_TX;
118} 118}
@@ -134,7 +134,7 @@ void rt2x00queue_unmap_skb(struct rt2x00_dev *rt2x00dev, struct sk_buff *skb)
134 * by the driver, but it was actually mapped to DMA. 134 * by the driver, but it was actually mapped to DMA.
135 */ 135 */
136 dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma, 136 dma_unmap_single(rt2x00dev->dev, skbdesc->skb_dma,
137 skb->len + rt2x00dev->hw->extra_tx_headroom, 137 skb->len + rt2x00dev->ops->extra_tx_headroom,
138 DMA_TO_DEVICE); 138 DMA_TO_DEVICE);
139 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX; 139 skbdesc->flags &= ~SKBDESC_DMA_MAPPED_TX;
140 } 140 }
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.c b/drivers/net/wireless/wl12xx/wl1251_cmd.c
index 770f260726bd..0320b478bb3f 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.c
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.c
@@ -410,3 +410,86 @@ out:
410 kfree(cmd); 410 kfree(cmd);
411 return ret; 411 return ret;
412} 412}
413
414int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
415 struct ieee80211_channel *channels[],
416 unsigned int n_channels, unsigned int n_probes)
417{
418 struct wl1251_cmd_scan *cmd;
419 int i, ret = 0;
420
421 wl1251_debug(DEBUG_CMD, "cmd scan");
422
423 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
424 if (!cmd)
425 return -ENOMEM;
426
427 cmd->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
428 cmd->params.rx_filter_options = cpu_to_le32(CFG_RX_PRSP_EN |
429 CFG_RX_MGMT_EN |
430 CFG_RX_BCN_EN);
431 cmd->params.scan_options = 0;
432 cmd->params.num_channels = n_channels;
433 cmd->params.num_probe_requests = n_probes;
434 cmd->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
435 cmd->params.tid_trigger = 0;
436
437 for (i = 0; i < n_channels; i++) {
438 cmd->channels[i].min_duration =
439 cpu_to_le32(WL1251_SCAN_MIN_DURATION);
440 cmd->channels[i].max_duration =
441 cpu_to_le32(WL1251_SCAN_MAX_DURATION);
442 memset(&cmd->channels[i].bssid_lsb, 0xff, 4);
443 memset(&cmd->channels[i].bssid_msb, 0xff, 2);
444 cmd->channels[i].early_termination = 0;
445 cmd->channels[i].tx_power_att = 0;
446 cmd->channels[i].channel = channels[i]->hw_value;
447 }
448
449 cmd->params.ssid_len = ssid_len;
450 if (ssid)
451 memcpy(cmd->params.ssid, ssid, ssid_len);
452
453 ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
454 if (ret < 0) {
455 wl1251_error("cmd scan failed: %d", ret);
456 goto out;
457 }
458
459 wl1251_mem_read(wl, wl->cmd_box_addr, cmd, sizeof(*cmd));
460
461 if (cmd->header.status != CMD_STATUS_SUCCESS) {
462 wl1251_error("cmd scan status wasn't success: %d",
463 cmd->header.status);
464 ret = -EIO;
465 goto out;
466 }
467
468out:
469 kfree(cmd);
470 return ret;
471}
472
473int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout)
474{
475 struct wl1251_cmd_trigger_scan_to *cmd;
476 int ret;
477
478 wl1251_debug(DEBUG_CMD, "cmd trigger scan to");
479
480 cmd = kzalloc(sizeof(*cmd), GFP_KERNEL);
481 if (!cmd)
482 return -ENOMEM;
483
484 cmd->timeout = timeout;
485
486 ret = wl1251_cmd_send(wl, CMD_SCAN, cmd, sizeof(*cmd));
487 if (ret < 0) {
488 wl1251_error("cmd trigger scan to failed: %d", ret);
489 goto out;
490 }
491
492out:
493 kfree(cmd);
494 return ret;
495}
diff --git a/drivers/net/wireless/wl12xx/wl1251_cmd.h b/drivers/net/wireless/wl12xx/wl1251_cmd.h
index dff798ad0ef5..4ad67cae94d2 100644
--- a/drivers/net/wireless/wl12xx/wl1251_cmd.h
+++ b/drivers/net/wireless/wl12xx/wl1251_cmd.h
@@ -27,6 +27,8 @@
27 27
28#include "wl1251.h" 28#include "wl1251.h"
29 29
30#include <net/cfg80211.h>
31
30struct acx_header; 32struct acx_header;
31 33
32int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len); 34int wl1251_cmd_send(struct wl1251 *wl, u16 type, void *buf, size_t buf_len);
@@ -43,6 +45,10 @@ int wl1251_cmd_read_memory(struct wl1251 *wl, u32 addr, void *answer,
43 size_t len); 45 size_t len);
44int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id, 46int wl1251_cmd_template_set(struct wl1251 *wl, u16 cmd_id,
45 void *buf, size_t buf_len); 47 void *buf, size_t buf_len);
48int wl1251_cmd_scan(struct wl1251 *wl, u8 *ssid, size_t ssid_len,
49 struct ieee80211_channel *channels[],
50 unsigned int n_channels, unsigned int n_probes);
51int wl1251_cmd_trigger_scan_to(struct wl1251 *wl, u32 timeout);
46 52
47/* unit ms */ 53/* unit ms */
48#define WL1251_COMMAND_TIMEOUT 2000 54#define WL1251_COMMAND_TIMEOUT 2000
@@ -163,8 +169,12 @@ struct cmd_read_write_memory {
163#define CMDMBOX_HEADER_LEN 4 169#define CMDMBOX_HEADER_LEN 4
164#define CMDMBOX_INFO_ELEM_HEADER_LEN 4 170#define CMDMBOX_INFO_ELEM_HEADER_LEN 4
165 171
172#define WL1251_SCAN_MIN_DURATION 30000
173#define WL1251_SCAN_MAX_DURATION 60000
174
175#define WL1251_SCAN_NUM_PROBES 3
166 176
167struct basic_scan_parameters { 177struct wl1251_scan_parameters {
168 u32 rx_config_options; 178 u32 rx_config_options;
169 u32 rx_filter_options; 179 u32 rx_filter_options;
170 180
@@ -189,11 +199,11 @@ struct basic_scan_parameters {
189 199
190 u8 tid_trigger; 200 u8 tid_trigger;
191 u8 ssid_len; 201 u8 ssid_len;
192 u32 ssid[8]; 202 u8 ssid[32];
193 203
194} __attribute__ ((packed)); 204} __attribute__ ((packed));
195 205
196struct basic_scan_channel_parameters { 206struct wl1251_scan_ch_parameters {
197 u32 min_duration; /* in TU */ 207 u32 min_duration; /* in TU */
198 u32 max_duration; /* in TU */ 208 u32 max_duration; /* in TU */
199 u32 bssid_lsb; 209 u32 bssid_lsb;
@@ -213,11 +223,11 @@ struct basic_scan_channel_parameters {
213/* SCAN parameters */ 223/* SCAN parameters */
214#define SCAN_MAX_NUM_OF_CHANNELS 16 224#define SCAN_MAX_NUM_OF_CHANNELS 16
215 225
216struct cmd_scan { 226struct wl1251_cmd_scan {
217 struct wl1251_cmd_header header; 227 struct wl1251_cmd_header header;
218 228
219 struct basic_scan_parameters params; 229 struct wl1251_scan_parameters params;
220 struct basic_scan_channel_parameters channels[SCAN_MAX_NUM_OF_CHANNELS]; 230 struct wl1251_scan_ch_parameters channels[SCAN_MAX_NUM_OF_CHANNELS];
221} __attribute__ ((packed)); 231} __attribute__ ((packed));
222 232
223enum { 233enum {
diff --git a/drivers/net/wireless/wl12xx/wl1251_main.c b/drivers/net/wireless/wl12xx/wl1251_main.c
index 4e373f3dbc43..595f0f94d16e 100644
--- a/drivers/net/wireless/wl12xx/wl1251_main.c
+++ b/drivers/net/wireless/wl12xx/wl1251_main.c
@@ -563,43 +563,25 @@ static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
563 mutex_unlock(&wl->mutex); 563 mutex_unlock(&wl->mutex);
564} 564}
565 565
566static int wl1251_build_null_data(struct wl1251 *wl) 566static int wl1251_build_qos_null_data(struct wl1251 *wl)
567{ 567{
568 struct wl12xx_null_data_template template; 568 struct ieee80211_qos_hdr template;
569 569
570 if (!is_zero_ether_addr(wl->bssid)) { 570 memset(&template, 0, sizeof(template));
571 memcpy(template.header.da, wl->bssid, ETH_ALEN);
572 memcpy(template.header.bssid, wl->bssid, ETH_ALEN);
573 } else {
574 memset(template.header.da, 0xff, ETH_ALEN);
575 memset(template.header.bssid, 0xff, ETH_ALEN);
576 }
577
578 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
579 template.header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA |
580 IEEE80211_STYPE_NULLFUNC |
581 IEEE80211_FCTL_TODS);
582
583 return wl1251_cmd_template_set(wl, CMD_NULL_DATA, &template,
584 sizeof(template));
585
586}
587
588static int wl1251_build_ps_poll(struct wl1251 *wl, u16 aid)
589{
590 struct wl12xx_ps_poll_template template;
591 571
592 memcpy(template.bssid, wl->bssid, ETH_ALEN); 572 memcpy(template.addr1, wl->bssid, ETH_ALEN);
593 memcpy(template.ta, wl->mac_addr, ETH_ALEN); 573 memcpy(template.addr2, wl->mac_addr, ETH_ALEN);
574 memcpy(template.addr3, wl->bssid, ETH_ALEN);
594 575
595 /* aid in PS-Poll has its two MSBs each set to 1 */ 576 template.frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
596 template.aid = cpu_to_le16(1 << 15 | 1 << 14 | aid); 577 IEEE80211_STYPE_QOS_NULLFUNC |
578 IEEE80211_FCTL_TODS);
597 579
598 template.fc = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL); 580 /* FIXME: not sure what priority to use here */
581 template.qos_ctrl = cpu_to_le16(0);
599 582
600 return wl1251_cmd_template_set(wl, CMD_PS_POLL, &template, 583 return wl1251_cmd_template_set(wl, CMD_QOS_NULL_DATA, &template,
601 sizeof(template)); 584 sizeof(template));
602
603} 585}
604 586
605static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed) 587static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
@@ -870,199 +852,61 @@ out:
870 return ret; 852 return ret;
871} 853}
872 854
873static int wl1251_build_basic_rates(char *rates) 855static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
874{ 856 struct cfg80211_scan_request *req)
875 u8 index = 0;
876
877 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
878 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
879 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
880 rates[index++] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
881
882 return index;
883}
884
885static int wl1251_build_extended_rates(char *rates)
886{ 857{
887 u8 index = 0; 858 struct wl1251 *wl = hw->priv;
888 859 struct sk_buff *skb;
889 rates[index++] = IEEE80211_OFDM_RATE_6MB; 860 size_t ssid_len = 0;
890 rates[index++] = IEEE80211_OFDM_RATE_9MB; 861 u8 *ssid = NULL;
891 rates[index++] = IEEE80211_OFDM_RATE_12MB; 862 int ret;
892 rates[index++] = IEEE80211_OFDM_RATE_18MB;
893 rates[index++] = IEEE80211_OFDM_RATE_24MB;
894 rates[index++] = IEEE80211_OFDM_RATE_36MB;
895 rates[index++] = IEEE80211_OFDM_RATE_48MB;
896 rates[index++] = IEEE80211_OFDM_RATE_54MB;
897
898 return index;
899}
900
901 863
902static int wl1251_build_probe_req(struct wl1251 *wl, u8 *ssid, size_t ssid_len) 864 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
903{
904 struct wl12xx_probe_req_template template;
905 struct wl12xx_ie_rates *rates;
906 char *ptr;
907 u16 size;
908
909 ptr = (char *)&template;
910 size = sizeof(struct ieee80211_header);
911
912 memset(template.header.da, 0xff, ETH_ALEN);
913 memset(template.header.bssid, 0xff, ETH_ALEN);
914 memcpy(template.header.sa, wl->mac_addr, ETH_ALEN);
915 template.header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
916
917 /* IEs */
918 /* SSID */
919 template.ssid.header.id = WLAN_EID_SSID;
920 template.ssid.header.len = ssid_len;
921 if (ssid_len && ssid)
922 memcpy(template.ssid.ssid, ssid, ssid_len);
923 size += sizeof(struct wl12xx_ie_header) + ssid_len;
924 ptr += size;
925
926 /* Basic Rates */
927 rates = (struct wl12xx_ie_rates *)ptr;
928 rates->header.id = WLAN_EID_SUPP_RATES;
929 rates->header.len = wl1251_build_basic_rates(rates->rates);
930 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
931 ptr += sizeof(struct wl12xx_ie_header) + rates->header.len;
932
933 /* Extended rates */
934 rates = (struct wl12xx_ie_rates *)ptr;
935 rates->header.id = WLAN_EID_EXT_SUPP_RATES;
936 rates->header.len = wl1251_build_extended_rates(rates->rates);
937 size += sizeof(struct wl12xx_ie_header) + rates->header.len;
938
939 wl1251_dump(DEBUG_SCAN, "PROBE REQ: ", &template, size);
940
941 return wl1251_cmd_template_set(wl, CMD_PROBE_REQ, &template,
942 size);
943}
944 865
945static int wl1251_hw_scan(struct wl1251 *wl, u8 *ssid, size_t len, 866 if (req->n_ssids) {
946 u8 active_scan, u8 high_prio, u8 num_channels, 867 ssid = req->ssids[0].ssid;
947 u8 probe_requests) 868 ssid_len = req->ssids[0].ssid_len;
948{
949 struct wl1251_cmd_trigger_scan_to *trigger = NULL;
950 struct cmd_scan *params = NULL;
951 int i, ret;
952 u16 scan_options = 0;
953
954 if (wl->scanning)
955 return -EINVAL;
956
957 params = kzalloc(sizeof(*params), GFP_KERNEL);
958 if (!params)
959 return -ENOMEM;
960
961 params->params.rx_config_options = cpu_to_le32(CFG_RX_ALL_GOOD);
962 params->params.rx_filter_options =
963 cpu_to_le32(CFG_RX_PRSP_EN | CFG_RX_MGMT_EN | CFG_RX_BCN_EN);
964
965 /* High priority scan */
966 if (!active_scan)
967 scan_options |= SCAN_PASSIVE;
968 if (high_prio)
969 scan_options |= SCAN_PRIORITY_HIGH;
970 params->params.scan_options = scan_options;
971
972 params->params.num_channels = num_channels;
973 params->params.num_probe_requests = probe_requests;
974 params->params.tx_rate = cpu_to_le16(1 << 1); /* 2 Mbps */
975 params->params.tid_trigger = 0;
976
977 for (i = 0; i < num_channels; i++) {
978 params->channels[i].min_duration = cpu_to_le32(30000);
979 params->channels[i].max_duration = cpu_to_le32(60000);
980 memset(&params->channels[i].bssid_lsb, 0xff, 4);
981 memset(&params->channels[i].bssid_msb, 0xff, 2);
982 params->channels[i].early_termination = 0;
983 params->channels[i].tx_power_att = 0;
984 params->channels[i].channel = i + 1;
985 memset(params->channels[i].pad, 0, 3);
986 } 869 }
987 870
988 for (i = num_channels; i < SCAN_MAX_NUM_OF_CHANNELS; i++) 871 mutex_lock(&wl->mutex);
989 memset(&params->channels[i], 0,
990 sizeof(struct basic_scan_channel_parameters));
991
992 if (len && ssid) {
993 params->params.ssid_len = len;
994 memcpy(params->params.ssid, ssid, len);
995 } else {
996 params->params.ssid_len = 0;
997 memset(params->params.ssid, 0, 32);
998 }
999 872
1000 ret = wl1251_build_probe_req(wl, ssid, len); 873 if (wl->scanning) {
1001 if (ret < 0) { 874 wl1251_debug(DEBUG_SCAN, "scan already in progress");
1002 wl1251_error("PROBE request template failed"); 875 ret = -EINVAL;
1003 goto out; 876 goto out;
1004 } 877 }
1005 878
1006 trigger = kzalloc(sizeof(*trigger), GFP_KERNEL); 879 ret = wl1251_ps_elp_wakeup(wl);
1007 if (!trigger) 880 if (ret < 0)
1008 goto out; 881 goto out;
1009 882
1010 trigger->timeout = 0; 883 skb = ieee80211_probereq_get(wl->hw, wl->vif, ssid, ssid_len,
1011 884 req->ie, req->ie_len);
1012 ret = wl1251_cmd_send(wl, CMD_TRIGGER_SCAN_TO, trigger, 885 if (!skb) {
1013 sizeof(*trigger)); 886 ret = -ENOMEM;
1014 if (ret < 0) {
1015 wl1251_error("trigger scan to failed for hw scan");
1016 goto out; 887 goto out;
1017 } 888 }
1018 889
1019 wl1251_dump(DEBUG_SCAN, "SCAN: ", params, sizeof(*params)); 890 ret = wl1251_cmd_template_set(wl, CMD_PROBE_REQ, skb->data,
1020 891 skb->len);
1021 wl->scanning = true; 892 dev_kfree_skb(skb);
893 if (ret < 0)
894 goto out_sleep;
1022 895
1023 ret = wl1251_cmd_send(wl, CMD_SCAN, params, sizeof(*params)); 896 ret = wl1251_cmd_trigger_scan_to(wl, 0);
1024 if (ret < 0) 897 if (ret < 0)
1025 wl1251_error("SCAN failed"); 898 goto out_sleep;
1026 899
1027 wl1251_mem_read(wl, wl->cmd_box_addr, params, sizeof(*params)); 900 wl->scanning = true;
1028 901
1029 if (params->header.status != CMD_STATUS_SUCCESS) { 902 ret = wl1251_cmd_scan(wl, ssid, ssid_len, req->channels,
1030 wl1251_error("TEST command answer error: %d", 903 req->n_channels, WL1251_SCAN_NUM_PROBES);
1031 params->header.status); 904 if (ret < 0) {
1032 wl->scanning = false; 905 wl->scanning = false;
1033 ret = -EIO; 906 goto out_sleep;
1034 goto out;
1035 }
1036
1037out:
1038 kfree(params);
1039 return ret;
1040
1041}
1042
1043static int wl1251_op_hw_scan(struct ieee80211_hw *hw,
1044 struct cfg80211_scan_request *req)
1045{
1046 struct wl1251 *wl = hw->priv;
1047 int ret;
1048 u8 *ssid = NULL;
1049 size_t ssid_len = 0;
1050
1051 wl1251_debug(DEBUG_MAC80211, "mac80211 hw scan");
1052
1053 if (req->n_ssids) {
1054 ssid = req->ssids[0].ssid;
1055 ssid_len = req->ssids[0].ssid_len;
1056 } 907 }
1057 908
1058 mutex_lock(&wl->mutex); 909out_sleep:
1059
1060 ret = wl1251_ps_elp_wakeup(wl);
1061 if (ret < 0)
1062 goto out;
1063
1064 ret = wl1251_hw_scan(hw->priv, ssid, ssid_len, 1, 0, 13, 3);
1065
1066 wl1251_ps_elp_sleep(wl); 910 wl1251_ps_elp_sleep(wl);
1067 911
1068out: 912out:
@@ -1101,7 +945,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1101{ 945{
1102 enum wl1251_cmd_ps_mode mode; 946 enum wl1251_cmd_ps_mode mode;
1103 struct wl1251 *wl = hw->priv; 947 struct wl1251 *wl = hw->priv;
1104 struct sk_buff *beacon; 948 struct sk_buff *beacon, *skb;
1105 int ret; 949 int ret;
1106 950
1107 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed"); 951 wl1251_debug(DEBUG_MAC80211, "mac80211 bss info changed");
@@ -1115,7 +959,17 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1115 if (changed & BSS_CHANGED_BSSID) { 959 if (changed & BSS_CHANGED_BSSID) {
1116 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); 960 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1117 961
1118 ret = wl1251_build_null_data(wl); 962 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
963 if (!skb)
964 goto out_sleep;
965
966 ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA,
967 skb->data, skb->len);
968 dev_kfree_skb(skb);
969 if (ret < 0)
970 goto out_sleep;
971
972 ret = wl1251_build_qos_null_data(wl);
1119 if (ret < 0) 973 if (ret < 0)
1120 goto out; 974 goto out;
1121 975
@@ -1136,7 +990,14 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1136 wl->dtim_period); 990 wl->dtim_period);
1137 wl->aid = bss_conf->aid; 991 wl->aid = bss_conf->aid;
1138 992
1139 ret = wl1251_build_ps_poll(wl, wl->aid); 993 skb = ieee80211_pspoll_get(wl->hw, wl->vif);
994 if (!skb)
995 goto out_sleep;
996
997 ret = wl1251_cmd_template_set(wl, CMD_PS_POLL,
998 skb->data,
999 skb->len);
1000 dev_kfree_skb(skb);
1140 if (ret < 0) 1001 if (ret < 0)
1141 goto out_sleep; 1002 goto out_sleep;
1142 1003
@@ -1182,7 +1043,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1182 ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE); 1043 ret = wl1251_acx_cts_protect(wl, CTSPROTECT_DISABLE);
1183 if (ret < 0) { 1044 if (ret < 0) {
1184 wl1251_warning("Set ctsprotect failed %d", ret); 1045 wl1251_warning("Set ctsprotect failed %d", ret);
1185 goto out; 1046 goto out_sleep;
1186 } 1047 }
1187 } 1048 }
1188 1049
@@ -1193,7 +1054,7 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1193 1054
1194 if (ret < 0) { 1055 if (ret < 0) {
1195 dev_kfree_skb(beacon); 1056 dev_kfree_skb(beacon);
1196 goto out; 1057 goto out_sleep;
1197 } 1058 }
1198 1059
1199 ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data, 1060 ret = wl1251_cmd_template_set(wl, CMD_PROBE_RESP, beacon->data,
@@ -1202,13 +1063,13 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1202 dev_kfree_skb(beacon); 1063 dev_kfree_skb(beacon);
1203 1064
1204 if (ret < 0) 1065 if (ret < 0)
1205 goto out; 1066 goto out_sleep;
1206 1067
1207 ret = wl1251_join(wl, wl->bss_type, wl->beacon_int, 1068 ret = wl1251_join(wl, wl->bss_type, wl->beacon_int,
1208 wl->channel, wl->dtim_period); 1069 wl->channel, wl->dtim_period);
1209 1070
1210 if (ret < 0) 1071 if (ret < 0)
1211 goto out; 1072 goto out_sleep;
1212 } 1073 }
1213 1074
1214out_sleep: 1075out_sleep:
@@ -1282,6 +1143,7 @@ static struct ieee80211_channel wl1251_channels[] = {
1282static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue, 1143static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1283 const struct ieee80211_tx_queue_params *params) 1144 const struct ieee80211_tx_queue_params *params)
1284{ 1145{
1146 enum wl1251_acx_ps_scheme ps_scheme;
1285 struct wl1251 *wl = hw->priv; 1147 struct wl1251 *wl = hw->priv;
1286 int ret; 1148 int ret;
1287 1149
@@ -1299,10 +1161,14 @@ static int wl1251_op_conf_tx(struct ieee80211_hw *hw, u16 queue,
1299 if (ret < 0) 1161 if (ret < 0)
1300 goto out_sleep; 1162 goto out_sleep;
1301 1163
1164 if (params->uapsd)
1165 ps_scheme = WL1251_ACX_PS_SCHEME_UPSD_TRIGGER;
1166 else
1167 ps_scheme = WL1251_ACX_PS_SCHEME_LEGACY;
1168
1302 ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue), 1169 ret = wl1251_acx_tid_cfg(wl, wl1251_tx_get_queue(queue),
1303 CHANNEL_TYPE_EDCF, 1170 CHANNEL_TYPE_EDCF,
1304 wl1251_tx_get_queue(queue), 1171 wl1251_tx_get_queue(queue), ps_scheme,
1305 WL1251_ACX_PS_SCHEME_LEGACY,
1306 WL1251_ACX_ACK_POLICY_LEGACY); 1172 WL1251_ACX_ACK_POLICY_LEGACY);
1307 if (ret < 0) 1173 if (ret < 0)
1308 goto out_sleep; 1174 goto out_sleep;
@@ -1376,7 +1242,8 @@ int wl1251_init_ieee80211(struct wl1251 *wl)
1376 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM | 1242 wl->hw->flags = IEEE80211_HW_SIGNAL_DBM |
1377 IEEE80211_HW_NOISE_DBM | 1243 IEEE80211_HW_NOISE_DBM |
1378 IEEE80211_HW_SUPPORTS_PS | 1244 IEEE80211_HW_SUPPORTS_PS |
1379 IEEE80211_HW_BEACON_FILTER; 1245 IEEE80211_HW_BEACON_FILTER |
1246 IEEE80211_HW_SUPPORTS_UAPSD;
1380 1247
1381 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION); 1248 wl->hw->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION);
1382 wl->hw->wiphy->max_scan_ssids = 1; 1249 wl->hw->wiphy->max_scan_ssids = 1;
diff --git a/drivers/net/wireless/wl12xx/wl1271_reg.h b/drivers/net/wireless/wl12xx/wl1271_reg.h
index 1f237389d1c7..990960771528 100644
--- a/drivers/net/wireless/wl12xx/wl1271_reg.h
+++ b/drivers/net/wireless/wl12xx/wl1271_reg.h
@@ -62,73 +62,10 @@
62#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008) 62#define WL1271_SLV_REG_DATA (REGISTERS_BASE + 0x0008)
63#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c) 63#define WL1271_SLV_REG_ADATA (REGISTERS_BASE + 0x000c)
64#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018) 64#define WL1271_SLV_MEM_DATA (REGISTERS_BASE + 0x0018)
65/*
66 * Interrupt registers.
67 * 64 bit interrupt sources registers ws ced.
68 * sme interupts were removed and new ones were added.
69 * Order was changed.
70 */
71#define FIQ_MASK (REGISTERS_BASE + 0x0400)
72#define FIQ_MASK_L (REGISTERS_BASE + 0x0400)
73#define FIQ_MASK_H (REGISTERS_BASE + 0x0404)
74#define FIQ_MASK_SET (REGISTERS_BASE + 0x0408)
75#define FIQ_MASK_SET_L (REGISTERS_BASE + 0x0408)
76#define FIQ_MASK_SET_H (REGISTERS_BASE + 0x040C)
77#define FIQ_MASK_CLR (REGISTERS_BASE + 0x0410)
78#define FIQ_MASK_CLR_L (REGISTERS_BASE + 0x0410)
79#define FIQ_MASK_CLR_H (REGISTERS_BASE + 0x0414)
80#define IRQ_MASK (REGISTERS_BASE + 0x0418)
81#define IRQ_MASK_L (REGISTERS_BASE + 0x0418)
82#define IRQ_MASK_H (REGISTERS_BASE + 0x041C)
83#define IRQ_MASK_SET (REGISTERS_BASE + 0x0420)
84#define IRQ_MASK_SET_L (REGISTERS_BASE + 0x0420)
85#define IRQ_MASK_SET_H (REGISTERS_BASE + 0x0424)
86#define IRQ_MASK_CLR (REGISTERS_BASE + 0x0428)
87#define IRQ_MASK_CLR_L (REGISTERS_BASE + 0x0428)
88#define IRQ_MASK_CLR_H (REGISTERS_BASE + 0x042C)
89#define ECPU_MASK (REGISTERS_BASE + 0x0448)
90#define FIQ_STS_L (REGISTERS_BASE + 0x044C)
91#define FIQ_STS_H (REGISTERS_BASE + 0x0450)
92#define IRQ_STS_L (REGISTERS_BASE + 0x0454)
93#define IRQ_STS_H (REGISTERS_BASE + 0x0458)
94#define INT_STS_ND (REGISTERS_BASE + 0x0464)
95#define INT_STS_RAW_L (REGISTERS_BASE + 0x0464)
96#define INT_STS_RAW_H (REGISTERS_BASE + 0x0468)
97#define INT_STS_CLR (REGISTERS_BASE + 0x04B4)
98#define INT_STS_CLR_L (REGISTERS_BASE + 0x04B4)
99#define INT_STS_CLR_H (REGISTERS_BASE + 0x04B8)
100#define INT_ACK (REGISTERS_BASE + 0x046C)
101#define INT_ACK_L (REGISTERS_BASE + 0x046C)
102#define INT_ACK_H (REGISTERS_BASE + 0x0470)
103#define INT_TRIG (REGISTERS_BASE + 0x0474)
104#define INT_TRIG_L (REGISTERS_BASE + 0x0474)
105#define INT_TRIG_H (REGISTERS_BASE + 0x0478)
106#define HOST_STS_L (REGISTERS_BASE + 0x045C)
107#define HOST_STS_H (REGISTERS_BASE + 0x0460)
108#define HOST_MASK (REGISTERS_BASE + 0x0430)
109#define HOST_MASK_L (REGISTERS_BASE + 0x0430)
110#define HOST_MASK_H (REGISTERS_BASE + 0x0434)
111#define HOST_MASK_SET (REGISTERS_BASE + 0x0438)
112#define HOST_MASK_SET_L (REGISTERS_BASE + 0x0438)
113#define HOST_MASK_SET_H (REGISTERS_BASE + 0x043C)
114#define HOST_MASK_CLR (REGISTERS_BASE + 0x0440)
115#define HOST_MASK_CLR_L (REGISTERS_BASE + 0x0440)
116#define HOST_MASK_CLR_H (REGISTERS_BASE + 0x0444)
117 65
118#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474) 66#define ACX_REG_INTERRUPT_TRIG (REGISTERS_BASE + 0x0474)
119#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478) 67#define ACX_REG_INTERRUPT_TRIG_H (REGISTERS_BASE + 0x0478)
120 68
121/* Host Interrupts*/
122#define HINT_MASK (REGISTERS_BASE + 0x0494)
123#define HINT_MASK_SET (REGISTERS_BASE + 0x0498)
124#define HINT_MASK_CLR (REGISTERS_BASE + 0x049C)
125#define HINT_STS_ND_MASKED (REGISTERS_BASE + 0x04A0)
126/*1150 spec calls this HINT_STS_RAW*/
127#define HINT_STS_ND (REGISTERS_BASE + 0x04B0)
128#define HINT_STS_CLR (REGISTERS_BASE + 0x04A4)
129#define HINT_ACK (REGISTERS_BASE + 0x04A8)
130#define HINT_TRIG (REGISTERS_BASE + 0x04AC)
131
132/*============================================= 69/*=============================================
133 Host Interrupt Mask Register - 32bit (RW) 70 Host Interrupt Mask Register - 32bit (RW)
134 ------------------------------------------ 71 ------------------------------------------
@@ -433,16 +370,6 @@
433 370
434 371
435/*=============================================== 372/*===============================================
436 Phy regs
437 ===============================================*/
438#define ACX_PHY_ADDR_REG SBB_ADDR
439#define ACX_PHY_DATA_REG SBB_DATA
440#define ACX_PHY_CTRL_REG SBB_CTL
441#define ACX_PHY_REG_WR_MASK 0x00000001ul
442#define ACX_PHY_REG_RD_MASK 0x00000002ul
443
444
445/*===============================================
446 EEPROM Read/Write Request 32bit RW 373 EEPROM Read/Write Request 32bit RW
447 ------------------------------------------ 374 ------------------------------------------
448 1 EE_READ - EEPROM Read Request 1 - Setting this bit 375 1 EE_READ - EEPROM Read Request 1 - Setting this bit
@@ -511,28 +438,6 @@
511#define ACX_CONT_WIND_MIN_MASK 0x0000007f 438#define ACX_CONT_WIND_MIN_MASK 0x0000007f
512#define ACX_CONT_WIND_MAX 0x03ff0000 439#define ACX_CONT_WIND_MAX 0x03ff0000
513 440
514/*
515 * Indirect slave register/memory registers
516 * ----------------------------------------
517 */
518#define HW_SLAVE_REG_ADDR_REG 0x00000004
519#define HW_SLAVE_REG_DATA_REG 0x00000008
520#define HW_SLAVE_REG_CTRL_REG 0x0000000c
521
522#define SLAVE_AUTO_INC 0x00010000
523#define SLAVE_NO_AUTO_INC 0x00000000
524#define SLAVE_HOST_LITTLE_ENDIAN 0x00000000
525
526#define HW_SLAVE_MEM_ADDR_REG SLV_MEM_ADDR
527#define HW_SLAVE_MEM_DATA_REG SLV_MEM_DATA
528#define HW_SLAVE_MEM_CTRL_REG SLV_MEM_CTL
529#define HW_SLAVE_MEM_ENDIAN_REG SLV_END_CTL
530
531#define HW_FUNC_EVENT_INT_EN 0x8000
532#define HW_FUNC_EVENT_MASK_REG 0x00000034
533
534#define ACX_MAC_TIMESTAMP_REG (MAC_TIMESTAMP)
535
536/*=============================================== 441/*===============================================
537 HI_CFG Interface Configuration Register Values 442 HI_CFG Interface Configuration Register Values
538 ------------------------------------------ 443 ------------------------------------------
@@ -647,10 +552,6 @@ b12-b0 - Supported Rate indicator bits as defined below.
647******************************************************************************/ 552******************************************************************************/
648 553
649 554
650#define TNETW1251_CHIP_ID_PG1_0 0x07010101
651#define TNETW1251_CHIP_ID_PG1_1 0x07020101
652#define TNETW1251_CHIP_ID_PG1_2 0x07030101
653
654/************************************************************************* 555/*************************************************************************
655 556
656 Interrupt Trigger Register (Host -> WiLink) 557 Interrupt Trigger Register (Host -> WiLink)
diff --git a/drivers/net/wireless/wl12xx/wl1271_spi.c b/drivers/net/wireless/wl12xx/wl1271_spi.c
index 02978a16e732..ee9564aa6ecc 100644
--- a/drivers/net/wireless/wl12xx/wl1271_spi.c
+++ b/drivers/net/wireless/wl12xx/wl1271_spi.c
@@ -397,8 +397,7 @@ u16 wl1271_top_reg_read(struct wl1271 *wl, int addr)
397 /* poll for data ready */ 397 /* poll for data ready */
398 do { 398 do {
399 val = wl1271_spi_read32(wl, OCP_DATA_READ); 399 val = wl1271_spi_read32(wl, OCP_DATA_READ);
400 timeout--; 400 } while (!(val & OCP_READY_MASK) && --timeout);
401 } while (!(val & OCP_READY_MASK) && timeout);
402 401
403 if (!timeout) { 402 if (!timeout) {
404 wl1271_warning("Top register access timed out."); 403 wl1271_warning("Top register access timed out.");
diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c
index 709fe5e06f73..2d555cc30508 100644
--- a/drivers/net/wireless/zd1211rw/zd_mac.c
+++ b/drivers/net/wireless/zd1211rw/zd_mac.c
@@ -987,12 +987,13 @@ static void zd_op_configure_filter(struct ieee80211_hw *hw,
987 changed_flags &= SUPPORTED_FIF_FLAGS; 987 changed_flags &= SUPPORTED_FIF_FLAGS;
988 *new_flags &= SUPPORTED_FIF_FLAGS; 988 *new_flags &= SUPPORTED_FIF_FLAGS;
989 989
990 /* changed_flags is always populated but this driver 990 /*
991 * doesn't support all FIF flags so its possible we don't 991 * If multicast parameter (as returned by zd_op_prepare_multicast)
992 * need to do anything */ 992 * has changed, no bit in changed_flags is set. To handle this
993 if (!changed_flags) 993 * situation, we do not return if changed_flags is 0. If we do so,
994 return; 994 * we will have some issue with IPv6 which uses multicast for link
995 995 * layer address resolution.
996 */
996 if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI)) 997 if (*new_flags & (FIF_PROMISC_IN_BSS | FIF_ALLMULTI))
997 zd_mc_add_all(&hash); 998 zd_mc_add_all(&hash);
998 999
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
index 0d490c164db6..9086047c32d4 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
@@ -482,15 +482,6 @@ struct ieee80211_header_data {
482 u16 seq_ctrl; 482 u16 seq_ctrl;
483}; 483};
484 484
485struct ieee80211_hdr_3addr {
486 u16 frame_ctl;
487 u16 duration_id;
488 u8 addr1[ETH_ALEN];
489 u8 addr2[ETH_ALEN];
490 u8 addr3[ETH_ALEN];
491 u16 seq_ctl;
492} __attribute__ ((packed));
493
494struct ieee80211_hdr_4addr { 485struct ieee80211_hdr_4addr {
495 u16 frame_ctl; 486 u16 frame_ctl;
496 u16 duration_id; 487 u16 duration_id;
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
index c7c645af0ebb..a2150670ef56 100644
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
@@ -203,7 +203,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee
203 203
204 enqueue_mgmt(ieee,skb); 204 enqueue_mgmt(ieee,skb);
205 }else{ 205 }else{
206 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0]<<4); 206 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
207 207
208 if (ieee->seq_ctrl[0] == 0xFFF) 208 if (ieee->seq_ctrl[0] == 0xFFF)
209 ieee->seq_ctrl[0] = 0; 209 ieee->seq_ctrl[0] = 0;
@@ -220,7 +220,7 @@ inline void softmac_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *ieee
220 spin_unlock_irqrestore(&ieee->lock, flags); 220 spin_unlock_irqrestore(&ieee->lock, flags);
221 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags); 221 spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
222 222
223 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); 223 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
224 224
225 if (ieee->seq_ctrl[0] == 0xFFF) 225 if (ieee->seq_ctrl[0] == 0xFFF)
226 ieee->seq_ctrl[0] = 0; 226 ieee->seq_ctrl[0] = 0;
@@ -246,7 +246,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i
246 246
247 if(single){ 247 if(single){
248 248
249 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); 249 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
250 250
251 if (ieee->seq_ctrl[0] == 0xFFF) 251 if (ieee->seq_ctrl[0] == 0xFFF)
252 ieee->seq_ctrl[0] = 0; 252 ieee->seq_ctrl[0] = 0;
@@ -259,7 +259,7 @@ inline void softmac_ps_mgmt_xmit(struct sk_buff *skb, struct ieee80211_device *i
259 259
260 }else{ 260 }else{
261 261
262 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); 262 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
263 263
264 if (ieee->seq_ctrl[0] == 0xFFF) 264 if (ieee->seq_ctrl[0] == 0xFFF)
265 ieee->seq_ctrl[0] = 0; 265 ieee->seq_ctrl[0] = 0;
@@ -287,7 +287,7 @@ inline struct sk_buff *ieee80211_disassociate_skb(
287 return NULL; 287 return NULL;
288 288
289 disass = (struct ieee80211_disassoc_frame *) skb_put(skb,sizeof(struct ieee80211_disassoc_frame)); 289 disass = (struct ieee80211_disassoc_frame *) skb_put(skb,sizeof(struct ieee80211_disassoc_frame));
290 disass->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_DISASSOC); 290 disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
291 disass->header.duration_id = 0; 291 disass->header.duration_id = 0;
292 292
293 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN); 293 memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
@@ -905,7 +905,7 @@ struct sk_buff* ieee80211_assoc_resp(struct ieee80211_device *ieee, u8 *dest)
905 assoc = (struct ieee80211_assoc_response_frame *) 905 assoc = (struct ieee80211_assoc_response_frame *)
906 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame)); 906 skb_put(skb,sizeof(struct ieee80211_assoc_response_frame));
907 907
908 assoc->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP); 908 assoc->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
909 memcpy(assoc->header.addr1, dest,ETH_ALEN); 909 memcpy(assoc->header.addr1, dest,ETH_ALEN);
910 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN); 910 memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
911 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN); 911 memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
@@ -981,7 +981,7 @@ struct sk_buff* ieee80211_null_func(struct ieee80211_device *ieee,short pwr)
981 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN); 981 memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
982 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN); 982 memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
983 983
984 hdr->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_DATA | 984 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
985 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS | 985 IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
986 (pwr ? IEEE80211_FCTL_PM:0)); 986 (pwr ? IEEE80211_FCTL_PM:0));
987 987
@@ -1084,7 +1084,7 @@ inline struct sk_buff *ieee80211_association_req(struct ieee80211_network *beaco
1084 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame)); 1084 skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
1085 1085
1086 1086
1087 hdr->header.frame_ctl = IEEE80211_STYPE_ASSOC_REQ; 1087 hdr->header.frame_control = IEEE80211_STYPE_ASSOC_REQ;
1088 hdr->header.duration_id= 37; //FIXME 1088 hdr->header.duration_id= 37; //FIXME
1089 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN); 1089 memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
1090 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN); 1090 memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
@@ -1786,11 +1786,11 @@ ieee80211_rx_frame_softmac(struct ieee80211_device *ieee, struct sk_buff *skb,
1786 1786
1787 tasklet_schedule(&ieee->ps_task); 1787 tasklet_schedule(&ieee->ps_task);
1788 1788
1789 if(WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_PROBE_RESP && 1789 if (WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_PROBE_RESP &&
1790 WLAN_FC_GET_STYPE(header->frame_ctl) != IEEE80211_STYPE_BEACON) 1790 WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_BEACON)
1791 ieee->last_rx_ps_time = jiffies; 1791 ieee->last_rx_ps_time = jiffies;
1792 1792
1793 switch (WLAN_FC_GET_STYPE(header->frame_ctl)) { 1793 switch (WLAN_FC_GET_STYPE(header->frame_control)) {
1794 1794
1795 case IEEE80211_STYPE_ASSOC_RESP: 1795 case IEEE80211_STYPE_ASSOC_RESP:
1796 case IEEE80211_STYPE_REASSOC_RESP: 1796 case IEEE80211_STYPE_REASSOC_RESP:
@@ -2064,7 +2064,7 @@ void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
2064 2064
2065 header = (struct ieee80211_hdr_3addr *) skb->data; 2065 header = (struct ieee80211_hdr_3addr *) skb->data;
2066 2066
2067 header->seq_ctl = cpu_to_le16(ieee->seq_ctrl[0] << 4); 2067 header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
2068 2068
2069 if (ieee->seq_ctrl[0] == 0xFFF) 2069 if (ieee->seq_ctrl[0] == 0xFFF)
2070 ieee->seq_ctrl[0] = 0; 2070 ieee->seq_ctrl[0] = 0;
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
index e0f13efdb15a..1847f38b9f22 100644
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ b/drivers/staging/rtl8187se/r8180_core.c
@@ -1890,7 +1890,7 @@ rate)
1890 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev); 1890 struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
1891 int mode; 1891 int mode;
1892 struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *) skb->data; 1892 struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *) skb->data;
1893 short morefrag = (h->frame_ctl) & IEEE80211_FCTL_MOREFRAGS; 1893 short morefrag = (h->frame_control) & IEEE80211_FCTL_MOREFRAGS;
1894 unsigned long flags; 1894 unsigned long flags;
1895 int priority; 1895 int priority;
1896 1896
@@ -2158,7 +2158,7 @@ short rtl8180_tx(struct net_device *dev, u8* txbuf, int len, int priority,
2158 TxDescDuration = ThisFrameTime + aSifsTime + AckTime; 2158 TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
2159 } 2159 }
2160 2160
2161 if(!(frag_hdr->frame_ctl & IEEE80211_FCTL_MOREFRAGS)) { //no more fragment 2161 if (!(frag_hdr->frame_control & IEEE80211_FCTL_MOREFRAGS)) {
2162 // ThisFrame-ACK. 2162 // ThisFrame-ACK.
2163 Duration = aSifsTime + AckTime; 2163 Duration = aSifsTime + AckTime;
2164 } else { // One or more fragments remained. 2164 } else { // One or more fragments remained.
diff --git a/include/linux/ieee80211.h b/include/linux/ieee80211.h
index aeea282bd2fe..842701906ae9 100644
--- a/include/linux/ieee80211.h
+++ b/include/linux/ieee80211.h
@@ -120,6 +120,24 @@
120#define IEEE80211_QOS_CTL_TID_MASK 0x000F 120#define IEEE80211_QOS_CTL_TID_MASK 0x000F
121#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007 121#define IEEE80211_QOS_CTL_TAG1D_MASK 0x0007
122 122
123/* U-APSD queue for WMM IEs sent by AP */
124#define IEEE80211_WMM_IE_AP_QOSINFO_UAPSD (1<<7)
125
126/* U-APSD queues for WMM IEs sent by STA */
127#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VO (1<<0)
128#define IEEE80211_WMM_IE_STA_QOSINFO_AC_VI (1<<1)
129#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BK (1<<2)
130#define IEEE80211_WMM_IE_STA_QOSINFO_AC_BE (1<<3)
131#define IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK 0x0f
132
133/* U-APSD max SP length for WMM IEs sent by STA */
134#define IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL 0x00
135#define IEEE80211_WMM_IE_STA_QOSINFO_SP_2 0x01
136#define IEEE80211_WMM_IE_STA_QOSINFO_SP_4 0x02
137#define IEEE80211_WMM_IE_STA_QOSINFO_SP_6 0x03
138#define IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK 0x03
139#define IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT 5
140
123struct ieee80211_hdr { 141struct ieee80211_hdr {
124 __le16 frame_control; 142 __le16 frame_control;
125 __le16 duration_id; 143 __le16 duration_id;
@@ -130,6 +148,25 @@ struct ieee80211_hdr {
130 u8 addr4[6]; 148 u8 addr4[6];
131} __attribute__ ((packed)); 149} __attribute__ ((packed));
132 150
151struct ieee80211_hdr_3addr {
152 __le16 frame_control;
153 __le16 duration_id;
154 u8 addr1[6];
155 u8 addr2[6];
156 u8 addr3[6];
157 __le16 seq_ctrl;
158} __attribute__ ((packed));
159
160struct ieee80211_qos_hdr {
161 __le16 frame_control;
162 __le16 duration_id;
163 u8 addr1[6];
164 u8 addr2[6];
165 u8 addr3[6];
166 __le16 seq_ctrl;
167 __le16 qos_ctrl;
168} __attribute__ ((packed));
169
133/** 170/**
134 * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set 171 * ieee80211_has_tods - check if IEEE80211_FCTL_TODS is set
135 * @fc: frame control bytes in little-endian byteorder 172 * @fc: frame control bytes in little-endian byteorder
diff --git a/include/linux/nl80211.h b/include/linux/nl80211.h
index 2bfbe88837ef..127a73015760 100644
--- a/include/linux/nl80211.h
+++ b/include/linux/nl80211.h
@@ -295,6 +295,10 @@
295 * This command is also used as an event to notify when a requested 295 * This command is also used as an event to notify when a requested
296 * remain-on-channel duration has expired. 296 * remain-on-channel duration has expired.
297 * 297 *
298 * @NL80211_CMD_SET_TX_BITRATE_MASK: Set the mask of rates to be used in TX
299 * rate selection. %NL80211_ATTR_IFINDEX is used to specify the interface
300 * and @NL80211_ATTR_TX_RATES the set of allowed rates.
301 *
298 * @NL80211_CMD_MAX: highest used command number 302 * @NL80211_CMD_MAX: highest used command number
299 * @__NL80211_CMD_AFTER_LAST: internal use 303 * @__NL80211_CMD_AFTER_LAST: internal use
300 */ 304 */
@@ -381,6 +385,8 @@ enum nl80211_commands {
381 NL80211_CMD_REMAIN_ON_CHANNEL, 385 NL80211_CMD_REMAIN_ON_CHANNEL,
382 NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL, 386 NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL,
383 387
388 NL80211_CMD_SET_TX_BITRATE_MASK,
389
384 /* add new commands above here */ 390 /* add new commands above here */
385 391
386 /* used to define NL80211_CMD_MAX below */ 392 /* used to define NL80211_CMD_MAX below */
@@ -430,6 +436,8 @@ enum nl80211_commands {
430 * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length 436 * @NL80211_ATTR_WIPHY_RTS_THRESHOLD: RTS threshold (TX frames with length
431 * larger than or equal to this use RTS/CTS handshake); allowed range: 437 * larger than or equal to this use RTS/CTS handshake); allowed range:
432 * 0..65536, disable with (u32)-1; dot11RTSThreshold; u32 438 * 0..65536, disable with (u32)-1; dot11RTSThreshold; u32
439 * @NL80211_ATTR_WIPHY_COVERAGE_CLASS: Coverage Class as defined by IEEE 802.11
440 * section 7.3.2.9; dot11CoverageClass; u8
433 * 441 *
434 * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on 442 * @NL80211_ATTR_IFINDEX: network interface index of the device to operate on
435 * @NL80211_ATTR_IFNAME: network interface name 443 * @NL80211_ATTR_IFNAME: network interface name
@@ -638,6 +646,13 @@ enum nl80211_commands {
638 * 646 *
639 * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects. 647 * @NL80211_ATTR_COOKIE: Generic 64-bit cookie to identify objects.
640 * 648 *
649 * @NL80211_ATTR_TX_RATES: Nested set of attributes
650 * (enum nl80211_tx_rate_attributes) describing TX rates per band. The
651 * enum nl80211_band value is used as the index (nla_type() of the nested
652 * data. If a band is not included, it will be configured to allow all
653 * rates based on negotiated supported rates information. This attribute
654 * is used with %NL80211_CMD_SET_TX_BITRATE_MASK.
655 *
641 * @NL80211_ATTR_MAX: highest attribute number currently defined 656 * @NL80211_ATTR_MAX: highest attribute number currently defined
642 * @__NL80211_ATTR_AFTER_LAST: internal use 657 * @__NL80211_ATTR_AFTER_LAST: internal use
643 */ 658 */
@@ -779,6 +794,10 @@ enum nl80211_attrs {
779 794
780 NL80211_ATTR_COOKIE, 795 NL80211_ATTR_COOKIE,
781 796
797 NL80211_ATTR_WIPHY_COVERAGE_CLASS,
798
799 NL80211_ATTR_TX_RATES,
800
782 /* add attributes here, update the policy in nl80211.c */ 801 /* add attributes here, update the policy in nl80211.c */
783 802
784 __NL80211_ATTR_AFTER_LAST, 803 __NL80211_ATTR_AFTER_LAST,
@@ -1359,13 +1378,20 @@ enum nl80211_channel_type {
1359 * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16) 1378 * @NL80211_BSS_BEACON_INTERVAL: beacon interval of the (I)BSS (u16)
1360 * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16) 1379 * @NL80211_BSS_CAPABILITY: capability field (CPU order, u16)
1361 * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the 1380 * @NL80211_BSS_INFORMATION_ELEMENTS: binary attribute containing the
1362 * raw information elements from the probe response/beacon (bin) 1381 * raw information elements from the probe response/beacon (bin);
1382 * if the %NL80211_BSS_BEACON_IES attribute is present, the IEs here are
1383 * from a Probe Response frame; otherwise they are from a Beacon frame.
1384 * However, if the driver does not indicate the source of the IEs, these
1385 * IEs may be from either frame subtype.
1363 * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon 1386 * @NL80211_BSS_SIGNAL_MBM: signal strength of probe response/beacon
1364 * in mBm (100 * dBm) (s32) 1387 * in mBm (100 * dBm) (s32)
1365 * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon 1388 * @NL80211_BSS_SIGNAL_UNSPEC: signal strength of the probe response/beacon
1366 * in unspecified units, scaled to 0..100 (u8) 1389 * in unspecified units, scaled to 0..100 (u8)
1367 * @NL80211_BSS_STATUS: status, if this BSS is "used" 1390 * @NL80211_BSS_STATUS: status, if this BSS is "used"
1368 * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms 1391 * @NL80211_BSS_SEEN_MS_AGO: age of this BSS entry in ms
1392 * @NL80211_BSS_BEACON_IES: binary attribute containing the raw information
1393 * elements from a Beacon frame (bin); not present if no Beacon frame has
1394 * yet been received
1369 * @__NL80211_BSS_AFTER_LAST: internal 1395 * @__NL80211_BSS_AFTER_LAST: internal
1370 * @NL80211_BSS_MAX: highest BSS attribute 1396 * @NL80211_BSS_MAX: highest BSS attribute
1371 */ 1397 */
@@ -1381,6 +1407,7 @@ enum nl80211_bss {
1381 NL80211_BSS_SIGNAL_UNSPEC, 1407 NL80211_BSS_SIGNAL_UNSPEC,
1382 NL80211_BSS_STATUS, 1408 NL80211_BSS_STATUS,
1383 NL80211_BSS_SEEN_MS_AGO, 1409 NL80211_BSS_SEEN_MS_AGO,
1410 NL80211_BSS_BEACON_IES,
1384 1411
1385 /* keep last */ 1412 /* keep last */
1386 __NL80211_BSS_AFTER_LAST, 1413 __NL80211_BSS_AFTER_LAST,
@@ -1478,4 +1505,33 @@ enum nl80211_key_attributes {
1478 NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1 1505 NL80211_KEY_MAX = __NL80211_KEY_AFTER_LAST - 1
1479}; 1506};
1480 1507
1508/**
1509 * enum nl80211_tx_rate_attributes - TX rate set attributes
1510 * @__NL80211_TXRATE_INVALID: invalid
1511 * @NL80211_TXRATE_LEGACY: Legacy (non-MCS) rates allowed for TX rate selection
1512 * in an array of rates as defined in IEEE 802.11 7.3.2.2 (u8 values with
1513 * 1 = 500 kbps) but without the IE length restriction (at most
1514 * %NL80211_MAX_SUPP_RATES in a single array).
1515 * @__NL80211_TXRATE_AFTER_LAST: internal
1516 * @NL80211_TXRATE_MAX: highest TX rate attribute
1517 */
1518enum nl80211_tx_rate_attributes {
1519 __NL80211_TXRATE_INVALID,
1520 NL80211_TXRATE_LEGACY,
1521
1522 /* keep last */
1523 __NL80211_TXRATE_AFTER_LAST,
1524 NL80211_TXRATE_MAX = __NL80211_TXRATE_AFTER_LAST - 1
1525};
1526
1527/**
1528 * enum nl80211_band - Frequency band
1529 * @NL80211_BAND_2GHZ - 2.4 GHz ISM band
1530 * @NL80211_BAND_5GHZ - around 5 GHz band (4.9 - 5.7 GHz)
1531 */
1532enum nl80211_band {
1533 NL80211_BAND_2GHZ,
1534 NL80211_BAND_5GHZ,
1535};
1536
1481#endif /* __LINUX_NL80211_H */ 1537#endif /* __LINUX_NL80211_H */
diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index add79930f47d..2af52704e670 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -39,8 +39,8 @@
39 * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7) 39 * @IEEE80211_BAND_5GHZ: around 5GHz band (4.9-5.7)
40 */ 40 */
41enum ieee80211_band { 41enum ieee80211_band {
42 IEEE80211_BAND_2GHZ, 42 IEEE80211_BAND_2GHZ = NL80211_BAND_2GHZ,
43 IEEE80211_BAND_5GHZ, 43 IEEE80211_BAND_5GHZ = NL80211_BAND_5GHZ,
44 44
45 /* keep last */ 45 /* keep last */
46 IEEE80211_NUM_BANDS 46 IEEE80211_NUM_BANDS
@@ -626,8 +626,14 @@ enum cfg80211_signal_type {
626 * @beacon_interval: the beacon interval as from the frame 626 * @beacon_interval: the beacon interval as from the frame
627 * @capability: the capability field in host byte order 627 * @capability: the capability field in host byte order
628 * @information_elements: the information elements (Note that there 628 * @information_elements: the information elements (Note that there
629 * is no guarantee that these are well-formed!) 629 * is no guarantee that these are well-formed!); this is a pointer to
630 * either the beacon_ies or proberesp_ies depending on whether Probe
631 * Response frame has been received
630 * @len_information_elements: total length of the information elements 632 * @len_information_elements: total length of the information elements
633 * @beacon_ies: the information elements from the last Beacon frame
634 * @len_beacon_ies: total length of the beacon_ies
635 * @proberesp_ies: the information elements from the last Probe Response frame
636 * @len_proberesp_ies: total length of the proberesp_ies
631 * @signal: signal strength value (type depends on the wiphy's signal_type) 637 * @signal: signal strength value (type depends on the wiphy's signal_type)
632 * @free_priv: function pointer to free private data 638 * @free_priv: function pointer to free private data
633 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes 639 * @priv: private area for driver use, has at least wiphy->bss_priv_size bytes
@@ -641,6 +647,10 @@ struct cfg80211_bss {
641 u16 capability; 647 u16 capability;
642 u8 *information_elements; 648 u8 *information_elements;
643 size_t len_information_elements; 649 size_t len_information_elements;
650 u8 *beacon_ies;
651 size_t len_beacon_ies;
652 u8 *proberesp_ies;
653 size_t len_proberesp_ies;
644 654
645 s32 signal; 655 s32 signal;
646 656
@@ -837,6 +847,7 @@ enum wiphy_params_flags {
837 WIPHY_PARAM_RETRY_LONG = 1 << 1, 847 WIPHY_PARAM_RETRY_LONG = 1 << 1,
838 WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2, 848 WIPHY_PARAM_FRAG_THRESHOLD = 1 << 2,
839 WIPHY_PARAM_RTS_THRESHOLD = 1 << 3, 849 WIPHY_PARAM_RTS_THRESHOLD = 1 << 3,
850 WIPHY_PARAM_COVERAGE_CLASS = 1 << 4,
840}; 851};
841 852
842/** 853/**
@@ -856,20 +867,11 @@ enum tx_power_setting {
856 * cfg80211_bitrate_mask - masks for bitrate control 867 * cfg80211_bitrate_mask - masks for bitrate control
857 */ 868 */
858struct cfg80211_bitrate_mask { 869struct cfg80211_bitrate_mask {
859/*
860 * As discussed in Berlin, this struct really
861 * should look like this:
862
863 struct { 870 struct {
864 u32 legacy; 871 u32 legacy;
865 u8 mcs[IEEE80211_HT_MCS_MASK_LEN]; 872 /* TODO: add support for masking MCS rates; e.g.: */
873 /* u8 mcs[IEEE80211_HT_MCS_MASK_LEN]; */
866 } control[IEEE80211_NUM_BANDS]; 874 } control[IEEE80211_NUM_BANDS];
867
868 * Since we can always fix in-kernel users, let's keep
869 * it simpler for now:
870 */
871 u32 fixed; /* fixed bitrate, 0 == not fixed */
872 u32 maxrate; /* in kbps, 0 == no limit */
873}; 875};
874/** 876/**
875 * struct cfg80211_pmksa - PMK Security Association 877 * struct cfg80211_pmksa - PMK Security Association
@@ -1236,6 +1238,7 @@ struct wiphy {
1236 u8 retry_long; 1238 u8 retry_long;
1237 u32 frag_threshold; 1239 u32 frag_threshold;
1238 u32 rts_threshold; 1240 u32 rts_threshold;
1241 u8 coverage_class;
1239 1242
1240 char fw_version[ETHTOOL_BUSINFO_LEN]; 1243 char fw_version[ETHTOOL_BUSINFO_LEN];
1241 u32 hw_version; 1244 u32 hw_version;
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index f073a2a50574..c90047de4428 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -107,12 +107,14 @@ enum ieee80211_max_queues {
107 * 2^n-1 in the range 1..32767] 107 * 2^n-1 in the range 1..32767]
108 * @cw_max: maximum contention window [like @cw_min] 108 * @cw_max: maximum contention window [like @cw_min]
109 * @txop: maximum burst time in units of 32 usecs, 0 meaning disabled 109 * @txop: maximum burst time in units of 32 usecs, 0 meaning disabled
110 * @uapsd: is U-APSD mode enabled for the queue
110 */ 111 */
111struct ieee80211_tx_queue_params { 112struct ieee80211_tx_queue_params {
112 u16 txop; 113 u16 txop;
113 u16 cw_min; 114 u16 cw_min;
114 u16 cw_max; 115 u16 cw_max;
115 u8 aifs; 116 u8 aifs;
117 bool uapsd;
116}; 118};
117 119
118/** 120/**
@@ -255,9 +257,6 @@ struct ieee80211_bss_conf {
255 * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be 257 * @IEEE80211_TX_CTL_RATE_CTRL_PROBE: internal to mac80211, can be
256 * set by rate control algorithms to indicate probe rate, will 258 * set by rate control algorithms to indicate probe rate, will
257 * be cleared for fragmented frames (except on the last fragment) 259 * be cleared for fragmented frames (except on the last fragment)
258 * @IEEE80211_TX_INTFL_RCALGO: mac80211 internal flag, do not test or
259 * set this flag in the driver; indicates that the rate control
260 * algorithm was used and should be notified of TX status
261 * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211, 260 * @IEEE80211_TX_INTFL_NEED_TXPROCESSING: completely internal to mac80211,
262 * used to indicate that a pending frame requires TX processing before 261 * used to indicate that a pending frame requires TX processing before
263 * it can be sent out. 262 * it can be sent out.
@@ -287,7 +286,6 @@ enum mac80211_tx_control_flags {
287 IEEE80211_TX_STAT_AMPDU = BIT(10), 286 IEEE80211_TX_STAT_AMPDU = BIT(10),
288 IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11), 287 IEEE80211_TX_STAT_AMPDU_NO_BACK = BIT(11),
289 IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12), 288 IEEE80211_TX_CTL_RATE_CTRL_PROBE = BIT(12),
290 IEEE80211_TX_INTFL_RCALGO = BIT(13),
291 IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14), 289 IEEE80211_TX_INTFL_NEED_TXPROCESSING = BIT(14),
292 IEEE80211_TX_INTFL_RETRIED = BIT(15), 290 IEEE80211_TX_INTFL_RETRIED = BIT(15),
293 IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16), 291 IEEE80211_TX_INTFL_DONT_ENCRYPT = BIT(16),
@@ -571,7 +569,13 @@ struct ieee80211_rx_status {
571 * @IEEE80211_CONF_MONITOR: there's a monitor interface present -- use this 569 * @IEEE80211_CONF_MONITOR: there's a monitor interface present -- use this
572 * to determine for example whether to calculate timestamps for packets 570 * to determine for example whether to calculate timestamps for packets
573 * or not, do not use instead of filter flags! 571 * or not, do not use instead of filter flags!
574 * @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only) 572 * @IEEE80211_CONF_PS: Enable 802.11 power save mode (managed mode only).
573 * This is the power save mode defined by IEEE 802.11-2007 section 11.2,
574 * meaning that the hardware still wakes up for beacons, is able to
575 * transmit frames and receive the possible acknowledgment frames.
576 * Not to be confused with hardware specific wakeup/sleep states,
577 * driver is responsible for that. See the section "Powersave support"
578 * for more.
575 * @IEEE80211_CONF_IDLE: The device is running, but idle; if the flag is set 579 * @IEEE80211_CONF_IDLE: The device is running, but idle; if the flag is set
576 * the driver should be prepared to handle configuration requests but 580 * the driver should be prepared to handle configuration requests but
577 * may turn the device off as much as possible. Typically, this flag will 581 * may turn the device off as much as possible. Typically, this flag will
@@ -611,7 +615,11 @@ enum ieee80211_conf_changed {
611/** 615/**
612 * enum ieee80211_smps_mode - spatial multiplexing power save mode 616 * enum ieee80211_smps_mode - spatial multiplexing power save mode
613 * 617 *
614 * @ 618 * @IEEE80211_SMPS_AUTOMATIC: automatic
619 * @IEEE80211_SMPS_OFF: off
620 * @IEEE80211_SMPS_STATIC: static
621 * @IEEE80211_SMPS_DYNAMIC: dynamic
622 * @IEEE80211_SMPS_NUM_MODES: internal, don't use
615 */ 623 */
616enum ieee80211_smps_mode { 624enum ieee80211_smps_mode {
617 IEEE80211_SMPS_AUTOMATIC, 625 IEEE80211_SMPS_AUTOMATIC,
@@ -933,6 +941,11 @@ enum ieee80211_tkip_key_type {
933 * Hardware supports dynamic spatial multiplexing powersave, 941 * Hardware supports dynamic spatial multiplexing powersave,
934 * ie. can turn off all but one chain and then wake the rest 942 * ie. can turn off all but one chain and then wake the rest
935 * up as required after, for example, rts/cts handshake. 943 * up as required after, for example, rts/cts handshake.
944 *
945 * @IEEE80211_HW_SUPPORTS_UAPSD:
946 * Hardware supports Unscheduled Automatic Power Save Delivery
947 * (U-APSD) in managed mode. The mode is configured with
948 * conf_tx() operation.
936 */ 949 */
937enum ieee80211_hw_flags { 950enum ieee80211_hw_flags {
938 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0, 951 IEEE80211_HW_HAS_RATE_CONTROL = 1<<0,
@@ -952,6 +965,7 @@ enum ieee80211_hw_flags {
952 IEEE80211_HW_BEACON_FILTER = 1<<14, 965 IEEE80211_HW_BEACON_FILTER = 1<<14,
953 IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15, 966 IEEE80211_HW_SUPPORTS_STATIC_SMPS = 1<<15,
954 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16, 967 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS = 1<<16,
968 IEEE80211_HW_SUPPORTS_UAPSD = 1<<17,
955}; 969};
956 970
957/** 971/**
@@ -1130,18 +1144,24 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
1130 * 1144 *
1131 * mac80211 has support for various powersave implementations. 1145 * mac80211 has support for various powersave implementations.
1132 * 1146 *
1133 * First, it can support hardware that handles all powersaving by 1147 * First, it can support hardware that handles all powersaving by itself,
1134 * itself, such hardware should simply set the %IEEE80211_HW_SUPPORTS_PS 1148 * such hardware should simply set the %IEEE80211_HW_SUPPORTS_PS hardware
1135 * hardware flag. In that case, it will be told about the desired 1149 * flag. In that case, it will be told about the desired powersave mode
1136 * powersave mode depending on the association status, and the driver 1150 * with the %IEEE80211_CONF_PS flag depending on the association status.
1137 * must take care of sending nullfunc frames when necessary, i.e. when 1151 * The hardware must take care of sending nullfunc frames when necessary,
1138 * entering and leaving powersave mode. The driver is required to look at 1152 * i.e. when entering and leaving powersave mode. The hardware is required
1139 * the AID in beacons and signal to the AP that it woke up when it finds 1153 * to look at the AID in beacons and signal to the AP that it woke up when
1140 * traffic directed to it. This mode supports dynamic PS by simply 1154 * it finds traffic directed to it.
1141 * enabling/disabling PS. 1155 *
1142 * 1156 * %IEEE80211_CONF_PS flag enabled means that the powersave mode defined in
1143 * Additionally, such hardware may set the %IEEE80211_HW_SUPPORTS_DYNAMIC_PS 1157 * IEEE 802.11-2007 section 11.2 is enabled. This is not to be confused
1144 * flag to indicate that it can support dynamic PS mode itself (see below). 1158 * with hardware wakeup and sleep states. Driver is responsible for waking
1159 * up the hardware before issueing commands to the hardware and putting it
1160 * back to sleep at approriate times.
1161 *
1162 * When PS is enabled, hardware needs to wakeup for beacons and receive the
1163 * buffered multicast/broadcast frames after the beacon. Also it must be
1164 * possible to send frames and receive the acknowledment frame.
1145 * 1165 *
1146 * Other hardware designs cannot send nullfunc frames by themselves and also 1166 * Other hardware designs cannot send nullfunc frames by themselves and also
1147 * need software support for parsing the TIM bitmap. This is also supported 1167 * need software support for parsing the TIM bitmap. This is also supported
@@ -1149,14 +1169,35 @@ ieee80211_get_alt_retry_rate(const struct ieee80211_hw *hw,
1149 * %IEEE80211_HW_PS_NULLFUNC_STACK flags. The hardware is of course still 1169 * %IEEE80211_HW_PS_NULLFUNC_STACK flags. The hardware is of course still
1150 * required to pass up beacons. The hardware is still required to handle 1170 * required to pass up beacons. The hardware is still required to handle
1151 * waking up for multicast traffic; if it cannot the driver must handle that 1171 * waking up for multicast traffic; if it cannot the driver must handle that
1152 * as best as it can, mac80211 is too slow. 1172 * as best as it can, mac80211 is too slow to do that.
1153 * 1173 *
1154 * Dynamic powersave mode is an extension to normal powersave mode in which 1174 * Dynamic powersave is an extension to normal powersave in which the
1155 * the hardware stays awake for a user-specified period of time after sending 1175 * hardware stays awake for a user-specified period of time after sending a
1156 * a frame so that reply frames need not be buffered and therefore delayed 1176 * frame so that reply frames need not be buffered and therefore delayed to
1157 * to the next wakeup. This can either be supported by hardware, in which case 1177 * the next wakeup. It's compromise of getting good enough latency when
1158 * the driver needs to look at the @dynamic_ps_timeout hardware configuration 1178 * there's data traffic and still saving significantly power in idle
1159 * value, or by the stack if all nullfunc handling is in the stack. 1179 * periods.
1180 *
1181 * Dynamic powersave is supported by simply mac80211 enabling and disabling
1182 * PS based on traffic. Driver needs to only set %IEEE80211_HW_SUPPORTS_PS
1183 * flag and mac80211 will handle everything automatically. Additionally,
1184 * hardware having support for the dynamic PS feature may set the
1185 * %IEEE80211_HW_SUPPORTS_DYNAMIC_PS flag to indicate that it can support
1186 * dynamic PS mode itself. The driver needs to look at the
1187 * @dynamic_ps_timeout hardware configuration value and use it that value
1188 * whenever %IEEE80211_CONF_PS is set. In this case mac80211 will disable
1189 * dynamic PS feature in stack and will just keep %IEEE80211_CONF_PS
1190 * enabled whenever user has enabled powersave.
1191 *
1192 * Driver informs U-APSD client support by enabling
1193 * %IEEE80211_HW_SUPPORTS_UAPSD flag. The mode is configured through the
1194 * uapsd paramater in conf_tx() operation. Hardware needs to send the QoS
1195 * Nullfunc frames and stay awake until the service period has ended. To
1196 * utilize U-APSD, dynamic powersave is disabled for voip AC and all frames
1197 * from that AC are transmitted with powersave enabled.
1198 *
1199 * Note: U-APSD client mode is not yet supported with
1200 * %IEEE80211_HW_PS_NULLFUNC_STACK.
1160 */ 1201 */
1161 1202
1162/** 1203/**
@@ -1533,6 +1574,10 @@ enum ieee80211_ampdu_mlme_action {
1533 * and need to call wiphy_rfkill_set_hw_state() in the callback. 1574 * and need to call wiphy_rfkill_set_hw_state() in the callback.
1534 * The callback can sleep. 1575 * The callback can sleep.
1535 * 1576 *
1577 * @set_coverage_class: Set slot time for given coverage class as specified
1578 * in IEEE 802.11-2007 section 17.3.8.6 and modify ACK timeout
1579 * accordingly. This callback is not required and may sleep.
1580 *
1536 * @testmode_cmd: Implement a cfg80211 test mode command. 1581 * @testmode_cmd: Implement a cfg80211 test mode command.
1537 * The callback can sleep. 1582 * The callback can sleep.
1538 * 1583 *
@@ -1592,6 +1637,7 @@ struct ieee80211_ops {
1592 struct ieee80211_sta *sta, u16 tid, u16 *ssn); 1637 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
1593 1638
1594 void (*rfkill_poll)(struct ieee80211_hw *hw); 1639 void (*rfkill_poll)(struct ieee80211_hw *hw);
1640 void (*set_coverage_class)(struct ieee80211_hw *hw, u8 coverage_class);
1595#ifdef CONFIG_NL80211_TESTMODE 1641#ifdef CONFIG_NL80211_TESTMODE
1596 int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len); 1642 int (*testmode_cmd)(struct ieee80211_hw *hw, void *data, int len);
1597#endif 1643#endif
@@ -1874,6 +1920,53 @@ static inline struct sk_buff *ieee80211_beacon_get(struct ieee80211_hw *hw,
1874} 1920}
1875 1921
1876/** 1922/**
1923 * ieee80211_pspoll_get - retrieve a PS Poll template
1924 * @hw: pointer obtained from ieee80211_alloc_hw().
1925 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
1926 *
1927 * Creates a PS Poll a template which can, for example, uploaded to
1928 * hardware. The template must be updated after association so that correct
1929 * AID, BSSID and MAC address is used.
1930 *
1931 * Note: Caller (or hardware) is responsible for setting the
1932 * &IEEE80211_FCTL_PM bit.
1933 */
1934struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
1935 struct ieee80211_vif *vif);
1936
1937/**
1938 * ieee80211_nullfunc_get - retrieve a nullfunc template
1939 * @hw: pointer obtained from ieee80211_alloc_hw().
1940 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
1941 *
1942 * Creates a Nullfunc template which can, for example, uploaded to
1943 * hardware. The template must be updated after association so that correct
1944 * BSSID and address is used.
1945 *
1946 * Note: Caller (or hardware) is responsible for setting the
1947 * &IEEE80211_FCTL_PM bit as well as Duration and Sequence Control fields.
1948 */
1949struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
1950 struct ieee80211_vif *vif);
1951
1952/**
1953 * ieee80211_probereq_get - retrieve a Probe Request template
1954 * @hw: pointer obtained from ieee80211_alloc_hw().
1955 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
1956 * @ssid: SSID buffer
1957 * @ssid_len: length of SSID
1958 * @ie: buffer containing all IEs except SSID for the template
1959 * @ie_len: length of the IE buffer
1960 *
1961 * Creates a Probe Request template which can, for example, be uploaded to
1962 * hardware.
1963 */
1964struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
1965 struct ieee80211_vif *vif,
1966 const u8 *ssid, size_t ssid_len,
1967 const u8 *ie, size_t ie_len);
1968
1969/**
1877 * ieee80211_rts_get - RTS frame generation function 1970 * ieee80211_rts_get - RTS frame generation function
1878 * @hw: pointer obtained from ieee80211_alloc_hw(). 1971 * @hw: pointer obtained from ieee80211_alloc_hw().
1879 * @vif: &struct ieee80211_vif pointer from the add_interface callback. 1972 * @vif: &struct ieee80211_vif pointer from the add_interface callback.
@@ -2292,8 +2385,12 @@ enum rate_control_changed {
2292 * @short_preamble: whether mac80211 will request short-preamble transmission 2385 * @short_preamble: whether mac80211 will request short-preamble transmission
2293 * if the selected rate supports it 2386 * if the selected rate supports it
2294 * @max_rate_idx: user-requested maximum rate (not MCS for now) 2387 * @max_rate_idx: user-requested maximum rate (not MCS for now)
2388 * (deprecated; this will be removed once drivers get updated to use
2389 * rate_idx_mask)
2390 * @rate_idx_mask: user-requested rate mask (not MCS for now)
2295 * @skb: the skb that will be transmitted, the control information in it needs 2391 * @skb: the skb that will be transmitted, the control information in it needs
2296 * to be filled in 2392 * to be filled in
2393 * @ap: whether this frame is sent out in AP mode
2297 */ 2394 */
2298struct ieee80211_tx_rate_control { 2395struct ieee80211_tx_rate_control {
2299 struct ieee80211_hw *hw; 2396 struct ieee80211_hw *hw;
@@ -2303,6 +2400,8 @@ struct ieee80211_tx_rate_control {
2303 struct ieee80211_tx_rate reported_rate; 2400 struct ieee80211_tx_rate reported_rate;
2304 bool rts, short_preamble; 2401 bool rts, short_preamble;
2305 u8 max_rate_idx; 2402 u8 max_rate_idx;
2403 u32 rate_idx_mask;
2404 bool ap;
2306}; 2405};
2307 2406
2308struct rate_control_ops { 2407struct rate_control_ops {
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index ceda36618d3c..718fbcff84d2 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -179,7 +179,8 @@ static void sta_addba_resp_timer_expired(unsigned long data)
179 179
180 /* check if the TID waits for addBA response */ 180 /* check if the TID waits for addBA response */
181 spin_lock_bh(&sta->lock); 181 spin_lock_bh(&sta->lock);
182 if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) != 182 if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK |
183 HT_AGG_STATE_REQ_STOP_BA_MSK)) !=
183 HT_ADDBA_REQUESTED_MSK) { 184 HT_ADDBA_REQUESTED_MSK) {
184 spin_unlock_bh(&sta->lock); 185 spin_unlock_bh(&sta->lock);
185 *state = HT_AGG_STATE_IDLE; 186 *state = HT_AGG_STATE_IDLE;
@@ -301,7 +302,7 @@ int ieee80211_start_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid)
301 * call back right away, it must see that the flow has begun */ 302 * call back right away, it must see that the flow has begun */
302 *state |= HT_ADDBA_REQUESTED_MSK; 303 *state |= HT_ADDBA_REQUESTED_MSK;
303 304
304 start_seq_num = sta->tid_seq[tid]; 305 start_seq_num = sta->tid_seq[tid] >> 4;
305 306
306 ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START, 307 ret = drv_ampdu_action(local, sdata, IEEE80211_AMPDU_TX_START,
307 pubsta, tid, &start_seq_num); 308 pubsta, tid, &start_seq_num);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 2e5e841e9b7b..b0102c538b30 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -148,7 +148,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
148 rcu_read_lock(); 148 rcu_read_lock();
149 149
150 if (mac_addr) { 150 if (mac_addr) {
151 sta = sta_info_get(sdata, mac_addr); 151 sta = sta_info_get_bss(sdata, mac_addr);
152 if (!sta) { 152 if (!sta) {
153 ieee80211_key_free(key); 153 ieee80211_key_free(key);
154 err = -ENOENT; 154 err = -ENOENT;
@@ -179,7 +179,7 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
179 if (mac_addr) { 179 if (mac_addr) {
180 ret = -ENOENT; 180 ret = -ENOENT;
181 181
182 sta = sta_info_get(sdata, mac_addr); 182 sta = sta_info_get_bss(sdata, mac_addr);
183 if (!sta) 183 if (!sta)
184 goto out_unlock; 184 goto out_unlock;
185 185
@@ -226,7 +226,7 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
226 rcu_read_lock(); 226 rcu_read_lock();
227 227
228 if (mac_addr) { 228 if (mac_addr) {
229 sta = sta_info_get(sdata, mac_addr); 229 sta = sta_info_get_bss(sdata, mac_addr);
230 if (!sta) 230 if (!sta)
231 goto out; 231 goto out;
232 232
@@ -419,7 +419,7 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
419 419
420 rcu_read_lock(); 420 rcu_read_lock();
421 421
422 sta = sta_info_get(sdata, mac); 422 sta = sta_info_get_bss(sdata, mac);
423 if (sta) { 423 if (sta) {
424 ret = 0; 424 ret = 0;
425 sta_set_sinfo(sta, sinfo); 425 sta_set_sinfo(sta, sinfo);
@@ -775,7 +775,7 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
775 if (mac) { 775 if (mac) {
776 rcu_read_lock(); 776 rcu_read_lock();
777 777
778 sta = sta_info_get(sdata, mac); 778 sta = sta_info_get_bss(sdata, mac);
779 if (!sta) { 779 if (!sta) {
780 rcu_read_unlock(); 780 rcu_read_unlock();
781 return -ENOENT; 781 return -ENOENT;
@@ -803,7 +803,7 @@ static int ieee80211_change_station(struct wiphy *wiphy,
803 803
804 rcu_read_lock(); 804 rcu_read_lock();
805 805
806 sta = sta_info_get(sdata, mac); 806 sta = sta_info_get_bss(sdata, mac);
807 if (!sta) { 807 if (!sta) {
808 rcu_read_unlock(); 808 rcu_read_unlock();
809 return -ENOENT; 809 return -ENOENT;
@@ -1085,6 +1085,13 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
1085 params->use_short_preamble; 1085 params->use_short_preamble;
1086 changed |= BSS_CHANGED_ERP_PREAMBLE; 1086 changed |= BSS_CHANGED_ERP_PREAMBLE;
1087 } 1087 }
1088
1089 if (!sdata->vif.bss_conf.use_short_slot &&
1090 sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ) {
1091 sdata->vif.bss_conf.use_short_slot = true;
1092 changed |= BSS_CHANGED_ERP_SLOT;
1093 }
1094
1088 if (params->use_short_slot_time >= 0) { 1095 if (params->use_short_slot_time >= 0) {
1089 sdata->vif.bss_conf.use_short_slot = 1096 sdata->vif.bss_conf.use_short_slot =
1090 params->use_short_slot_time; 1097 params->use_short_slot_time;
@@ -1128,6 +1135,13 @@ static int ieee80211_set_txq_params(struct wiphy *wiphy,
1128 p.cw_max = params->cwmax; 1135 p.cw_max = params->cwmax;
1129 p.cw_min = params->cwmin; 1136 p.cw_min = params->cwmin;
1130 p.txop = params->txop; 1137 p.txop = params->txop;
1138
1139 /*
1140 * Setting tx queue params disables u-apsd because it's only
1141 * called in master mode.
1142 */
1143 p.uapsd = false;
1144
1131 if (drv_conf_tx(local, params->queue, &p)) { 1145 if (drv_conf_tx(local, params->queue, &p)) {
1132 printk(KERN_DEBUG "%s: failed to set TX queue " 1146 printk(KERN_DEBUG "%s: failed to set TX queue "
1133 "parameters for queue %d\n", 1147 "parameters for queue %d\n",
@@ -1230,6 +1244,13 @@ static int ieee80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1230 struct ieee80211_local *local = wiphy_priv(wiphy); 1244 struct ieee80211_local *local = wiphy_priv(wiphy);
1231 int err; 1245 int err;
1232 1246
1247 if (changed & WIPHY_PARAM_COVERAGE_CLASS) {
1248 err = drv_set_coverage_class(local, wiphy->coverage_class);
1249
1250 if (err)
1251 return err;
1252 }
1253
1233 if (changed & WIPHY_PARAM_RTS_THRESHOLD) { 1254 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1234 err = drv_set_rts_threshold(local, wiphy->rts_threshold); 1255 err = drv_set_rts_threshold(local, wiphy->rts_threshold);
1235 1256
@@ -1399,8 +1420,6 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1399 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1420 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1400 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1421 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1401 int i; 1422 int i;
1402 u32 target_rate;
1403 struct ieee80211_supported_band *sband;
1404 1423
1405 /* 1424 /*
1406 * This _could_ be supported by providing a hook for 1425 * This _could_ be supported by providing a hook for
@@ -1410,35 +1429,11 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1410 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) 1429 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
1411 return -EOPNOTSUPP; 1430 return -EOPNOTSUPP;
1412 1431
1413 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1414
1415 /*
1416 * target_rate = -1, rate->fixed = 0 means auto only, so use all rates
1417 * target_rate = X, rate->fixed = 1 means only rate X
1418 * target_rate = X, rate->fixed = 0 means all rates <= X
1419 */
1420 sdata->max_ratectrl_rateidx = -1;
1421 sdata->force_unicast_rateidx = -1;
1422
1423 if (mask->fixed)
1424 target_rate = mask->fixed / 100;
1425 else if (mask->maxrate)
1426 target_rate = mask->maxrate / 100;
1427 else
1428 return 0;
1429
1430 for (i = 0; i< sband->n_bitrates; i++) {
1431 if (target_rate != sband->bitrates[i].bitrate)
1432 continue;
1433 1432
1434 /* requested bitrate found */ 1433 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
1435 sdata->max_ratectrl_rateidx = i; 1434 sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
1436 if (mask->fixed)
1437 sdata->force_unicast_rateidx = i;
1438 return 0;
1439 }
1440 1435
1441 return -EINVAL; 1436 return 0;
1442} 1437}
1443 1438
1444static int ieee80211_remain_on_channel(struct wiphy *wiphy, 1439static int ieee80211_remain_on_channel(struct wiphy *wiphy,
diff --git a/net/mac80211/debugfs.c b/net/mac80211/debugfs.c
index e4b54093d41b..b3bc32b62a5a 100644
--- a/net/mac80211/debugfs.c
+++ b/net/mac80211/debugfs.c
@@ -158,6 +158,98 @@ static const struct file_operations noack_ops = {
158 .open = mac80211_open_file_generic 158 .open = mac80211_open_file_generic
159}; 159};
160 160
161static ssize_t uapsd_queues_read(struct file *file, char __user *user_buf,
162 size_t count, loff_t *ppos)
163{
164 struct ieee80211_local *local = file->private_data;
165 int res;
166 char buf[10];
167
168 res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_queues);
169
170 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
171}
172
173static ssize_t uapsd_queues_write(struct file *file,
174 const char __user *user_buf,
175 size_t count, loff_t *ppos)
176{
177 struct ieee80211_local *local = file->private_data;
178 unsigned long val;
179 char buf[10];
180 size_t len;
181 int ret;
182
183 len = min(count, sizeof(buf) - 1);
184 if (copy_from_user(buf, user_buf, len))
185 return -EFAULT;
186 buf[len] = '\0';
187
188 ret = strict_strtoul(buf, 0, &val);
189
190 if (ret)
191 return -EINVAL;
192
193 if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_AC_MASK)
194 return -ERANGE;
195
196 local->uapsd_queues = val;
197
198 return count;
199}
200
201static const struct file_operations uapsd_queues_ops = {
202 .read = uapsd_queues_read,
203 .write = uapsd_queues_write,
204 .open = mac80211_open_file_generic
205};
206
207static ssize_t uapsd_max_sp_len_read(struct file *file, char __user *user_buf,
208 size_t count, loff_t *ppos)
209{
210 struct ieee80211_local *local = file->private_data;
211 int res;
212 char buf[10];
213
214 res = scnprintf(buf, sizeof(buf), "0x%x\n", local->uapsd_max_sp_len);
215
216 return simple_read_from_buffer(user_buf, count, ppos, buf, res);
217}
218
219static ssize_t uapsd_max_sp_len_write(struct file *file,
220 const char __user *user_buf,
221 size_t count, loff_t *ppos)
222{
223 struct ieee80211_local *local = file->private_data;
224 unsigned long val;
225 char buf[10];
226 size_t len;
227 int ret;
228
229 len = min(count, sizeof(buf) - 1);
230 if (copy_from_user(buf, user_buf, len))
231 return -EFAULT;
232 buf[len] = '\0';
233
234 ret = strict_strtoul(buf, 0, &val);
235
236 if (ret)
237 return -EINVAL;
238
239 if (val & ~IEEE80211_WMM_IE_STA_QOSINFO_SP_MASK)
240 return -ERANGE;
241
242 local->uapsd_max_sp_len = val;
243
244 return count;
245}
246
247static const struct file_operations uapsd_max_sp_len_ops = {
248 .read = uapsd_max_sp_len_read,
249 .write = uapsd_max_sp_len_write,
250 .open = mac80211_open_file_generic
251};
252
161static ssize_t queues_read(struct file *file, char __user *user_buf, 253static ssize_t queues_read(struct file *file, char __user *user_buf,
162 size_t count, loff_t *ppos) 254 size_t count, loff_t *ppos)
163{ 255{
@@ -314,6 +406,8 @@ void debugfs_hw_add(struct ieee80211_local *local)
314 DEBUGFS_ADD(queues); 406 DEBUGFS_ADD(queues);
315 DEBUGFS_ADD_MODE(reset, 0200); 407 DEBUGFS_ADD_MODE(reset, 0200);
316 DEBUGFS_ADD(noack); 408 DEBUGFS_ADD(noack);
409 DEBUGFS_ADD(uapsd_queues);
410 DEBUGFS_ADD(uapsd_max_sp_len);
317 411
318 statsd = debugfs_create_dir("statistics", phyd); 412 statsd = debugfs_create_dir("statistics", phyd);
319 413
diff --git a/net/mac80211/debugfs_netdev.c b/net/mac80211/debugfs_netdev.c
index 59f6e3bcbd09..9affe2cd185f 100644
--- a/net/mac80211/debugfs_netdev.c
+++ b/net/mac80211/debugfs_netdev.c
@@ -127,8 +127,10 @@ __IEEE80211_IF_FILE(name, ieee80211_if_write_##name)
127 127
128/* common attributes */ 128/* common attributes */
129IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC); 129IEEE80211_IF_FILE(drop_unencrypted, drop_unencrypted, DEC);
130IEEE80211_IF_FILE(force_unicast_rateidx, force_unicast_rateidx, DEC); 130IEEE80211_IF_FILE(rc_rateidx_mask_2ghz, rc_rateidx_mask[IEEE80211_BAND_2GHZ],
131IEEE80211_IF_FILE(max_ratectrl_rateidx, max_ratectrl_rateidx, DEC); 131 HEX);
132IEEE80211_IF_FILE(rc_rateidx_mask_5ghz, rc_rateidx_mask[IEEE80211_BAND_5GHZ],
133 HEX);
132 134
133/* STA attributes */ 135/* STA attributes */
134IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC); 136IEEE80211_IF_FILE(bssid, u.mgd.bssid, MAC);
@@ -253,7 +255,7 @@ IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
253#endif 255#endif
254 256
255 257
256#define DEBUGFS_ADD(name, type) \ 258#define DEBUGFS_ADD(name) \
257 debugfs_create_file(#name, 0400, sdata->debugfs.dir, \ 259 debugfs_create_file(#name, 0400, sdata->debugfs.dir, \
258 sdata, &name##_ops); 260 sdata, &name##_ops);
259 261
@@ -263,40 +265,40 @@ IEEE80211_IF_FILE(dot11MeshHWMPRootMode,
263 265
264static void add_sta_files(struct ieee80211_sub_if_data *sdata) 266static void add_sta_files(struct ieee80211_sub_if_data *sdata)
265{ 267{
266 DEBUGFS_ADD(drop_unencrypted, sta); 268 DEBUGFS_ADD(drop_unencrypted);
267 DEBUGFS_ADD(force_unicast_rateidx, sta); 269 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
268 DEBUGFS_ADD(max_ratectrl_rateidx, sta); 270 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
269 271
270 DEBUGFS_ADD(bssid, sta); 272 DEBUGFS_ADD(bssid);
271 DEBUGFS_ADD(aid, sta); 273 DEBUGFS_ADD(aid);
272 DEBUGFS_ADD_MODE(smps, 0600); 274 DEBUGFS_ADD_MODE(smps, 0600);
273} 275}
274 276
275static void add_ap_files(struct ieee80211_sub_if_data *sdata) 277static void add_ap_files(struct ieee80211_sub_if_data *sdata)
276{ 278{
277 DEBUGFS_ADD(drop_unencrypted, ap); 279 DEBUGFS_ADD(drop_unencrypted);
278 DEBUGFS_ADD(force_unicast_rateidx, ap); 280 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
279 DEBUGFS_ADD(max_ratectrl_rateidx, ap); 281 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
280 282
281 DEBUGFS_ADD(num_sta_ps, ap); 283 DEBUGFS_ADD(num_sta_ps);
282 DEBUGFS_ADD(dtim_count, ap); 284 DEBUGFS_ADD(dtim_count);
283 DEBUGFS_ADD(num_buffered_multicast, ap); 285 DEBUGFS_ADD(num_buffered_multicast);
284} 286}
285 287
286static void add_wds_files(struct ieee80211_sub_if_data *sdata) 288static void add_wds_files(struct ieee80211_sub_if_data *sdata)
287{ 289{
288 DEBUGFS_ADD(drop_unencrypted, wds); 290 DEBUGFS_ADD(drop_unencrypted);
289 DEBUGFS_ADD(force_unicast_rateidx, wds); 291 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
290 DEBUGFS_ADD(max_ratectrl_rateidx, wds); 292 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
291 293
292 DEBUGFS_ADD(peer, wds); 294 DEBUGFS_ADD(peer);
293} 295}
294 296
295static void add_vlan_files(struct ieee80211_sub_if_data *sdata) 297static void add_vlan_files(struct ieee80211_sub_if_data *sdata)
296{ 298{
297 DEBUGFS_ADD(drop_unencrypted, vlan); 299 DEBUGFS_ADD(drop_unencrypted);
298 DEBUGFS_ADD(force_unicast_rateidx, vlan); 300 DEBUGFS_ADD(rc_rateidx_mask_2ghz);
299 DEBUGFS_ADD(max_ratectrl_rateidx, vlan); 301 DEBUGFS_ADD(rc_rateidx_mask_5ghz);
300} 302}
301 303
302static void add_monitor_files(struct ieee80211_sub_if_data *sdata) 304static void add_monitor_files(struct ieee80211_sub_if_data *sdata)
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 8757ea73d544..de91d39e0276 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -214,6 +214,21 @@ static inline int drv_set_rts_threshold(struct ieee80211_local *local,
214 return ret; 214 return ret;
215} 215}
216 216
217static inline int drv_set_coverage_class(struct ieee80211_local *local,
218 u8 value)
219{
220 int ret = 0;
221 might_sleep();
222
223 if (local->ops->set_coverage_class)
224 local->ops->set_coverage_class(&local->hw, value);
225 else
226 ret = -EOPNOTSUPP;
227
228 trace_drv_set_coverage_class(local, value, ret);
229 return ret;
230}
231
217static inline void drv_sta_notify(struct ieee80211_local *local, 232static inline void drv_sta_notify(struct ieee80211_local *local,
218 struct ieee80211_sub_if_data *sdata, 233 struct ieee80211_sub_if_data *sdata,
219 enum sta_notify_cmd cmd, 234 enum sta_notify_cmd cmd,
diff --git a/net/mac80211/driver-trace.h b/net/mac80211/driver-trace.h
index 977cc7528bc6..0ea258123b8e 100644
--- a/net/mac80211/driver-trace.h
+++ b/net/mac80211/driver-trace.h
@@ -491,6 +491,29 @@ TRACE_EVENT(drv_set_rts_threshold,
491 ) 491 )
492); 492);
493 493
494TRACE_EVENT(drv_set_coverage_class,
495 TP_PROTO(struct ieee80211_local *local, u8 value, int ret),
496
497 TP_ARGS(local, value, ret),
498
499 TP_STRUCT__entry(
500 LOCAL_ENTRY
501 __field(u8, value)
502 __field(int, ret)
503 ),
504
505 TP_fast_assign(
506 LOCAL_ASSIGN;
507 __entry->ret = ret;
508 __entry->value = value;
509 ),
510
511 TP_printk(
512 LOCAL_PR_FMT " value:%d ret:%d",
513 LOCAL_PR_ARG, __entry->value, __entry->ret
514 )
515);
516
494TRACE_EVENT(drv_sta_notify, 517TRACE_EVENT(drv_sta_notify,
495 TP_PROTO(struct ieee80211_local *local, 518 TP_PROTO(struct ieee80211_local *local,
496 struct ieee80211_sub_if_data *sdata, 519 struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index a27921ee6e63..c18f576f1848 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -58,6 +58,15 @@ struct ieee80211_local;
58 58
59#define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024)) 59#define TU_TO_EXP_TIME(x) (jiffies + usecs_to_jiffies((x) * 1024))
60 60
61#define IEEE80211_DEFAULT_UAPSD_QUEUES \
62 (IEEE80211_WMM_IE_STA_QOSINFO_AC_BK | \
63 IEEE80211_WMM_IE_STA_QOSINFO_AC_BE | \
64 IEEE80211_WMM_IE_STA_QOSINFO_AC_VI | \
65 IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
66
67#define IEEE80211_DEFAULT_MAX_SP_LEN \
68 IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL
69
61struct ieee80211_fragment_entry { 70struct ieee80211_fragment_entry {
62 unsigned long first_frag_time; 71 unsigned long first_frag_time;
63 unsigned int seq; 72 unsigned int seq;
@@ -78,6 +87,7 @@ struct ieee80211_bss {
78 u8 dtim_period; 87 u8 dtim_period;
79 88
80 bool wmm_used; 89 bool wmm_used;
90 bool uapsd_supported;
81 91
82 unsigned long last_probe_resp; 92 unsigned long last_probe_resp;
83 93
@@ -285,7 +295,7 @@ struct ieee80211_work {
285 u8 ssid[IEEE80211_MAX_SSID_LEN]; 295 u8 ssid[IEEE80211_MAX_SSID_LEN];
286 u8 ssid_len; 296 u8 ssid_len;
287 u8 supp_rates_len; 297 u8 supp_rates_len;
288 bool wmm_used, use_11n; 298 bool wmm_used, use_11n, uapsd_used;
289 } assoc; 299 } assoc;
290 struct { 300 struct {
291 u32 duration; 301 u32 duration;
@@ -306,6 +316,7 @@ enum ieee80211_sta_flags {
306 IEEE80211_STA_DISABLE_11N = BIT(4), 316 IEEE80211_STA_DISABLE_11N = BIT(4),
307 IEEE80211_STA_CSA_RECEIVED = BIT(5), 317 IEEE80211_STA_CSA_RECEIVED = BIT(5),
308 IEEE80211_STA_MFP_ENABLED = BIT(6), 318 IEEE80211_STA_MFP_ENABLED = BIT(6),
319 IEEE80211_STA_UAPSD_ENABLED = BIT(7),
309}; 320};
310 321
311struct ieee80211_if_managed { 322struct ieee80211_if_managed {
@@ -494,8 +505,8 @@ struct ieee80211_sub_if_data {
494 */ 505 */
495 struct ieee80211_if_ap *bss; 506 struct ieee80211_if_ap *bss;
496 507
497 int force_unicast_rateidx; /* forced TX rateidx for unicast frames */ 508 /* bitmap of allowed (non-MCS) rate indexes for rate control */
498 int max_ratectrl_rateidx; /* max TX rateidx for rate control */ 509 u32 rc_rateidx_mask[IEEE80211_NUM_BANDS];
499 510
500 union { 511 union {
501 struct ieee80211_if_ap ap; 512 struct ieee80211_if_ap ap;
@@ -797,6 +808,20 @@ struct ieee80211_local {
797 int wifi_wme_noack_test; 808 int wifi_wme_noack_test;
798 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */ 809 unsigned int wmm_acm; /* bit field of ACM bits (BIT(802.1D tag)) */
799 810
811 /*
812 * Bitmask of enabled u-apsd queues,
813 * IEEE80211_WMM_IE_STA_QOSINFO_AC_BE & co. Needs a new association
814 * to take effect.
815 */
816 unsigned int uapsd_queues;
817
818 /*
819 * Maximum number of buffered frames AP can deliver during a
820 * service period, IEEE80211_WMM_IE_STA_QOSINFO_SP_ALL or similar.
821 * Needs a new association to take effect.
822 */
823 unsigned int uapsd_max_sp_len;
824
800 bool pspolling; 825 bool pspolling;
801 bool offchannel_ps_enabled; 826 bool offchannel_ps_enabled;
802 /* 827 /*
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 00a1f4ccdaf1..fe140bf033f9 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -15,12 +15,14 @@
15#include <linux/netdevice.h> 15#include <linux/netdevice.h>
16#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
17#include <net/mac80211.h> 17#include <net/mac80211.h>
18#include <net/ieee80211_radiotap.h>
18#include "ieee80211_i.h" 19#include "ieee80211_i.h"
19#include "sta_info.h" 20#include "sta_info.h"
20#include "debugfs_netdev.h" 21#include "debugfs_netdev.h"
21#include "mesh.h" 22#include "mesh.h"
22#include "led.h" 23#include "led.h"
23#include "driver-ops.h" 24#include "driver-ops.h"
25#include "wme.h"
24 26
25/** 27/**
26 * DOC: Interface list locking 28 * DOC: Interface list locking
@@ -63,15 +65,16 @@ static int ieee80211_change_mtu(struct net_device *dev, int new_mtu)
63static int ieee80211_change_mac(struct net_device *dev, void *addr) 65static int ieee80211_change_mac(struct net_device *dev, void *addr)
64{ 66{
65 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 67 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
68 struct sockaddr *sa = addr;
66 int ret; 69 int ret;
67 70
68 if (ieee80211_sdata_running(sdata)) 71 if (ieee80211_sdata_running(sdata))
69 return -EBUSY; 72 return -EBUSY;
70 73
71 ret = eth_mac_addr(dev, addr); 74 ret = eth_mac_addr(dev, sa);
72 75
73 if (ret == 0) 76 if (ret == 0)
74 memcpy(sdata->vif.addr, addr, ETH_ALEN); 77 memcpy(sdata->vif.addr, sa->sa_data, ETH_ALEN);
75 78
76 return ret; 79 return ret;
77} 80}
@@ -326,7 +329,7 @@ static int ieee80211_open(struct net_device *dev)
326 if (sdata->vif.type == NL80211_IFTYPE_STATION) 329 if (sdata->vif.type == NL80211_IFTYPE_STATION)
327 ieee80211_queue_work(&local->hw, &sdata->u.mgd.work); 330 ieee80211_queue_work(&local->hw, &sdata->u.mgd.work);
328 331
329 netif_start_queue(dev); 332 netif_tx_start_all_queues(dev);
330 333
331 return 0; 334 return 0;
332 err_del_interface: 335 err_del_interface:
@@ -354,7 +357,7 @@ static int ieee80211_stop(struct net_device *dev)
354 /* 357 /*
355 * Stop TX on this interface first. 358 * Stop TX on this interface first.
356 */ 359 */
357 netif_stop_queue(dev); 360 netif_tx_stop_all_queues(dev);
358 361
359 /* 362 /*
360 * Purge work for this interface. 363 * Purge work for this interface.
@@ -657,6 +660,12 @@ static void ieee80211_teardown_sdata(struct net_device *dev)
657 WARN_ON(flushed); 660 WARN_ON(flushed);
658} 661}
659 662
663static u16 ieee80211_netdev_select_queue(struct net_device *dev,
664 struct sk_buff *skb)
665{
666 return ieee80211_select_queue(IEEE80211_DEV_TO_SUB_IF(dev), skb);
667}
668
660static const struct net_device_ops ieee80211_dataif_ops = { 669static const struct net_device_ops ieee80211_dataif_ops = {
661 .ndo_open = ieee80211_open, 670 .ndo_open = ieee80211_open,
662 .ndo_stop = ieee80211_stop, 671 .ndo_stop = ieee80211_stop,
@@ -665,8 +674,34 @@ static const struct net_device_ops ieee80211_dataif_ops = {
665 .ndo_set_multicast_list = ieee80211_set_multicast_list, 674 .ndo_set_multicast_list = ieee80211_set_multicast_list,
666 .ndo_change_mtu = ieee80211_change_mtu, 675 .ndo_change_mtu = ieee80211_change_mtu,
667 .ndo_set_mac_address = ieee80211_change_mac, 676 .ndo_set_mac_address = ieee80211_change_mac,
677 .ndo_select_queue = ieee80211_netdev_select_queue,
668}; 678};
669 679
680static u16 ieee80211_monitor_select_queue(struct net_device *dev,
681 struct sk_buff *skb)
682{
683 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
684 struct ieee80211_local *local = sdata->local;
685 struct ieee80211_hdr *hdr;
686 struct ieee80211_radiotap_header *rtap = (void *)skb->data;
687
688 if (local->hw.queues < 4)
689 return 0;
690
691 if (skb->len < 4 ||
692 skb->len < rtap->it_len + 2 /* frame control */)
693 return 0; /* doesn't matter, frame will be dropped */
694
695 hdr = (void *)((u8 *)skb->data + rtap->it_len);
696
697 if (!ieee80211_is_data(hdr->frame_control)) {
698 skb->priority = 7;
699 return ieee802_1d_to_ac[skb->priority];
700 }
701
702 return ieee80211_downgrade_queue(local, skb);
703}
704
670static const struct net_device_ops ieee80211_monitorif_ops = { 705static const struct net_device_ops ieee80211_monitorif_ops = {
671 .ndo_open = ieee80211_open, 706 .ndo_open = ieee80211_open,
672 .ndo_stop = ieee80211_stop, 707 .ndo_stop = ieee80211_stop,
@@ -675,6 +710,7 @@ static const struct net_device_ops ieee80211_monitorif_ops = {
675 .ndo_set_multicast_list = ieee80211_set_multicast_list, 710 .ndo_set_multicast_list = ieee80211_set_multicast_list,
676 .ndo_change_mtu = ieee80211_change_mtu, 711 .ndo_change_mtu = ieee80211_change_mtu,
677 .ndo_set_mac_address = eth_mac_addr, 712 .ndo_set_mac_address = eth_mac_addr,
713 .ndo_select_queue = ieee80211_monitor_select_queue,
678}; 714};
679 715
680static void ieee80211_if_setup(struct net_device *dev) 716static void ieee80211_if_setup(struct net_device *dev)
@@ -781,8 +817,8 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
781 817
782 ASSERT_RTNL(); 818 ASSERT_RTNL();
783 819
784 ndev = alloc_netdev(sizeof(*sdata) + local->hw.vif_data_size, 820 ndev = alloc_netdev_mq(sizeof(*sdata) + local->hw.vif_data_size,
785 name, ieee80211_if_setup); 821 name, ieee80211_if_setup, local->hw.queues);
786 if (!ndev) 822 if (!ndev)
787 return -ENOMEM; 823 return -ENOMEM;
788 dev_net_set(ndev, wiphy_net(local->hw.wiphy)); 824 dev_net_set(ndev, wiphy_net(local->hw.wiphy));
@@ -820,8 +856,12 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
820 856
821 INIT_LIST_HEAD(&sdata->key_list); 857 INIT_LIST_HEAD(&sdata->key_list);
822 858
823 sdata->force_unicast_rateidx = -1; 859 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
824 sdata->max_ratectrl_rateidx = -1; 860 struct ieee80211_supported_band *sband;
861 sband = local->hw.wiphy->bands[i];
862 sdata->rc_rateidx_mask[i] =
863 sband ? (1 << sband->n_bitrates) - 1 : 0;
864 }
825 865
826 /* setup type-dependent data */ 866 /* setup type-dependent data */
827 ieee80211_setup_sdata(sdata, type); 867 ieee80211_setup_sdata(sdata, type);
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index d0a14d953f08..ec8f767ba95b 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -17,7 +17,6 @@
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/etherdevice.h> 18#include <linux/etherdevice.h>
19#include <linux/if_arp.h> 19#include <linux/if_arp.h>
20#include <linux/wireless.h>
21#include <linux/rtnetlink.h> 20#include <linux/rtnetlink.h>
22#include <linux/bitmap.h> 21#include <linux/bitmap.h>
23#include <linux/pm_qos_params.h> 22#include <linux/pm_qos_params.h>
@@ -385,6 +384,8 @@ struct ieee80211_hw *ieee80211_alloc_hw(size_t priv_data_len,
385 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long; 384 local->hw.conf.long_frame_max_tx_count = wiphy->retry_long;
386 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short; 385 local->hw.conf.short_frame_max_tx_count = wiphy->retry_short;
387 local->user_power_level = -1; 386 local->user_power_level = -1;
387 local->uapsd_queues = IEEE80211_DEFAULT_UAPSD_QUEUES;
388 local->uapsd_max_sp_len = IEEE80211_DEFAULT_MAX_SP_LEN;
388 389
389 INIT_LIST_HEAD(&local->interfaces); 390 INIT_LIST_HEAD(&local->interfaces);
390 mutex_init(&local->iflist_mtx); 391 mutex_init(&local->iflist_mtx);
@@ -492,6 +493,10 @@ int ieee80211_register_hw(struct ieee80211_hw *hw)
492 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC) 493 else if (local->hw.flags & IEEE80211_HW_SIGNAL_UNSPEC)
493 local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC; 494 local->hw.wiphy->signal_type = CFG80211_SIGNAL_TYPE_UNSPEC;
494 495
496 WARN((local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)
497 && (local->hw.flags & IEEE80211_HW_PS_NULLFUNC_STACK),
498 "U-APSD not supported with HW_PS_NULLFUNC_STACK\n");
499
495 /* 500 /*
496 * Calculate scan IE length -- we need this to alloc 501 * Calculate scan IE length -- we need this to alloc
497 * memory and to subtract from the driver limit. It 502 * memory and to subtract from the driver limit. It
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 72920ee07885..a82564e73d91 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -249,30 +249,15 @@ static void ieee80211_send_deauth_disassoc(struct ieee80211_sub_if_data *sdata,
249void ieee80211_send_pspoll(struct ieee80211_local *local, 249void ieee80211_send_pspoll(struct ieee80211_local *local,
250 struct ieee80211_sub_if_data *sdata) 250 struct ieee80211_sub_if_data *sdata)
251{ 251{
252 struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
253 struct ieee80211_pspoll *pspoll; 252 struct ieee80211_pspoll *pspoll;
254 struct sk_buff *skb; 253 struct sk_buff *skb;
255 u16 fc;
256 254
257 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll)); 255 skb = ieee80211_pspoll_get(&local->hw, &sdata->vif);
258 if (!skb) { 256 if (!skb)
259 printk(KERN_DEBUG "%s: failed to allocate buffer for "
260 "pspoll frame\n", sdata->name);
261 return; 257 return;
262 }
263 skb_reserve(skb, local->hw.extra_tx_headroom);
264
265 pspoll = (struct ieee80211_pspoll *) skb_put(skb, sizeof(*pspoll));
266 memset(pspoll, 0, sizeof(*pspoll));
267 fc = IEEE80211_FTYPE_CTL | IEEE80211_STYPE_PSPOLL | IEEE80211_FCTL_PM;
268 pspoll->frame_control = cpu_to_le16(fc);
269 pspoll->aid = cpu_to_le16(ifmgd->aid);
270
271 /* aid in PS-Poll has its two MSBs each set to 1 */
272 pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14);
273 258
274 memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN); 259 pspoll = (struct ieee80211_pspoll *) skb->data;
275 memcpy(pspoll->ta, sdata->vif.addr, ETH_ALEN); 260 pspoll->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
276 261
277 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 262 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
278 ieee80211_tx_skb(sdata, skb); 263 ieee80211_tx_skb(sdata, skb);
@@ -283,30 +268,47 @@ void ieee80211_send_nullfunc(struct ieee80211_local *local,
283 int powersave) 268 int powersave)
284{ 269{
285 struct sk_buff *skb; 270 struct sk_buff *skb;
271 struct ieee80211_hdr_3addr *nullfunc;
272
273 skb = ieee80211_nullfunc_get(&local->hw, &sdata->vif);
274 if (!skb)
275 return;
276
277 nullfunc = (struct ieee80211_hdr_3addr *) skb->data;
278 if (powersave)
279 nullfunc->frame_control |= cpu_to_le16(IEEE80211_FCTL_PM);
280
281 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
282 ieee80211_tx_skb(sdata, skb);
283}
284
285static void ieee80211_send_4addr_nullfunc(struct ieee80211_local *local,
286 struct ieee80211_sub_if_data *sdata)
287{
288 struct sk_buff *skb;
286 struct ieee80211_hdr *nullfunc; 289 struct ieee80211_hdr *nullfunc;
287 __le16 fc; 290 __le16 fc;
288 291
289 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION)) 292 if (WARN_ON(sdata->vif.type != NL80211_IFTYPE_STATION))
290 return; 293 return;
291 294
292 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 24); 295 skb = dev_alloc_skb(local->hw.extra_tx_headroom + 30);
293 if (!skb) { 296 if (!skb) {
294 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc " 297 printk(KERN_DEBUG "%s: failed to allocate buffer for 4addr "
295 "frame\n", sdata->name); 298 "nullfunc frame\n", sdata->name);
296 return; 299 return;
297 } 300 }
298 skb_reserve(skb, local->hw.extra_tx_headroom); 301 skb_reserve(skb, local->hw.extra_tx_headroom);
299 302
300 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 24); 303 nullfunc = (struct ieee80211_hdr *) skb_put(skb, 30);
301 memset(nullfunc, 0, 24); 304 memset(nullfunc, 0, 30);
302 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC | 305 fc = cpu_to_le16(IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC |
303 IEEE80211_FCTL_TODS); 306 IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS);
304 if (powersave)
305 fc |= cpu_to_le16(IEEE80211_FCTL_PM);
306 nullfunc->frame_control = fc; 307 nullfunc->frame_control = fc;
307 memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN); 308 memcpy(nullfunc->addr1, sdata->u.mgd.bssid, ETH_ALEN);
308 memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN); 309 memcpy(nullfunc->addr2, sdata->vif.addr, ETH_ALEN);
309 memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN); 310 memcpy(nullfunc->addr3, sdata->u.mgd.bssid, ETH_ALEN);
311 memcpy(nullfunc->addr4, sdata->vif.addr, ETH_ALEN);
310 312
311 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 313 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
312 ieee80211_tx_skb(sdata, skb); 314 ieee80211_tx_skb(sdata, skb);
@@ -567,7 +569,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
567 struct ieee80211_tx_queue_params params; 569 struct ieee80211_tx_queue_params params;
568 size_t left; 570 size_t left;
569 int count; 571 int count;
570 u8 *pos; 572 u8 *pos, uapsd_queues = 0;
571 573
572 if (local->hw.queues < 4) 574 if (local->hw.queues < 4)
573 return; 575 return;
@@ -577,6 +579,10 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
577 579
578 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1) 580 if (wmm_param_len < 8 || wmm_param[5] /* version */ != 1)
579 return; 581 return;
582
583 if (ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
584 uapsd_queues = local->uapsd_queues;
585
580 count = wmm_param[6] & 0x0f; 586 count = wmm_param[6] & 0x0f;
581 if (count == ifmgd->wmm_last_param_set) 587 if (count == ifmgd->wmm_last_param_set)
582 return; 588 return;
@@ -591,6 +597,7 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
591 for (; left >= 4; left -= 4, pos += 4) { 597 for (; left >= 4; left -= 4, pos += 4) {
592 int aci = (pos[0] >> 5) & 0x03; 598 int aci = (pos[0] >> 5) & 0x03;
593 int acm = (pos[0] >> 4) & 0x01; 599 int acm = (pos[0] >> 4) & 0x01;
600 bool uapsd = false;
594 int queue; 601 int queue;
595 602
596 switch (aci) { 603 switch (aci) {
@@ -598,22 +605,30 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
598 queue = 3; 605 queue = 3;
599 if (acm) 606 if (acm)
600 local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */ 607 local->wmm_acm |= BIT(1) | BIT(2); /* BK/- */
608 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BK)
609 uapsd = true;
601 break; 610 break;
602 case 2: /* AC_VI */ 611 case 2: /* AC_VI */
603 queue = 1; 612 queue = 1;
604 if (acm) 613 if (acm)
605 local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */ 614 local->wmm_acm |= BIT(4) | BIT(5); /* CL/VI */
615 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VI)
616 uapsd = true;
606 break; 617 break;
607 case 3: /* AC_VO */ 618 case 3: /* AC_VO */
608 queue = 0; 619 queue = 0;
609 if (acm) 620 if (acm)
610 local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */ 621 local->wmm_acm |= BIT(6) | BIT(7); /* VO/NC */
622 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
623 uapsd = true;
611 break; 624 break;
612 case 0: /* AC_BE */ 625 case 0: /* AC_BE */
613 default: 626 default:
614 queue = 2; 627 queue = 2;
615 if (acm) 628 if (acm)
616 local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */ 629 local->wmm_acm |= BIT(0) | BIT(3); /* BE/EE */
630 if (uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
631 uapsd = true;
617 break; 632 break;
618 } 633 }
619 634
@@ -621,11 +636,14 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
621 params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4); 636 params.cw_max = ecw2cw((pos[1] & 0xf0) >> 4);
622 params.cw_min = ecw2cw(pos[1] & 0x0f); 637 params.cw_min = ecw2cw(pos[1] & 0x0f);
623 params.txop = get_unaligned_le16(pos + 2); 638 params.txop = get_unaligned_le16(pos + 2);
639 params.uapsd = uapsd;
640
624#ifdef CONFIG_MAC80211_VERBOSE_DEBUG 641#ifdef CONFIG_MAC80211_VERBOSE_DEBUG
625 printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d " 642 printk(KERN_DEBUG "%s: WMM queue=%d aci=%d acm=%d aifs=%d "
626 "cWmin=%d cWmax=%d txop=%d\n", 643 "cWmin=%d cWmax=%d txop=%d uapsd=%d\n",
627 wiphy_name(local->hw.wiphy), queue, aci, acm, 644 wiphy_name(local->hw.wiphy), queue, aci, acm,
628 params.aifs, params.cw_min, params.cw_max, params.txop); 645 params.aifs, params.cw_min, params.cw_max, params.txop,
646 params.uapsd);
629#endif 647#endif
630 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx) 648 if (drv_conf_tx(local, queue, &params) && local->ops->conf_tx)
631 printk(KERN_DEBUG "%s: failed to set TX queue " 649 printk(KERN_DEBUG "%s: failed to set TX queue "
@@ -652,6 +670,8 @@ static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
652 } 670 }
653 671
654 use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME); 672 use_short_slot = !!(capab & WLAN_CAPABILITY_SHORT_SLOT_TIME);
673 if (sdata->local->hw.conf.channel->band == IEEE80211_BAND_5GHZ)
674 use_short_slot = true;
655 675
656 if (use_protection != bss_conf->use_cts_prot) { 676 if (use_protection != bss_conf->use_cts_prot) {
657 bss_conf->use_cts_prot = use_protection; 677 bss_conf->use_cts_prot = use_protection;
@@ -723,7 +743,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
723 ieee80211_recalc_smps(local, sdata); 743 ieee80211_recalc_smps(local, sdata);
724 mutex_unlock(&local->iflist_mtx); 744 mutex_unlock(&local->iflist_mtx);
725 745
726 netif_start_queue(sdata->dev); 746 netif_tx_start_all_queues(sdata->dev);
727 netif_carrier_on(sdata->dev); 747 netif_carrier_on(sdata->dev);
728} 748}
729 749
@@ -759,7 +779,7 @@ static void ieee80211_set_disassoc(struct ieee80211_sub_if_data *sdata)
759 * time -- we don't want the scan code to enable queues. 779 * time -- we don't want the scan code to enable queues.
760 */ 780 */
761 781
762 netif_stop_queue(sdata->dev); 782 netif_tx_stop_all_queues(sdata->dev);
763 netif_carrier_off(sdata->dev); 783 netif_carrier_off(sdata->dev);
764 784
765 rcu_read_lock(); 785 rcu_read_lock();
@@ -1096,7 +1116,7 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1096 if (err) { 1116 if (err) {
1097 printk(KERN_DEBUG "%s: failed to insert STA entry for" 1117 printk(KERN_DEBUG "%s: failed to insert STA entry for"
1098 " the AP (error %d)\n", sdata->name, err); 1118 " the AP (error %d)\n", sdata->name, err);
1099 return RX_MGMT_CFG80211_ASSOC_ERROR; 1119 return false;
1100 } 1120 }
1101 1121
1102 if (elems.wmm_param) 1122 if (elems.wmm_param)
@@ -1120,6 +1140,13 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
1120 ieee80211_set_associated(sdata, cbss, changed); 1140 ieee80211_set_associated(sdata, cbss, changed);
1121 1141
1122 /* 1142 /*
1143 * If we're using 4-addr mode, let the AP know that we're
1144 * doing so, so that it can create the STA VLAN on its side
1145 */
1146 if (ifmgd->use_4addr)
1147 ieee80211_send_4addr_nullfunc(local, sdata);
1148
1149 /*
1123 * Start timer to probe the connection to the AP now. 1150 * Start timer to probe the connection to the AP now.
1124 * Also start the timer that will detect beacon loss. 1151 * Also start the timer that will detect beacon loss.
1125 */ 1152 */
@@ -1774,7 +1801,7 @@ int ieee80211_mgd_auth(struct ieee80211_sub_if_data *sdata,
1774 if (!wk) 1801 if (!wk)
1775 return -ENOMEM; 1802 return -ENOMEM;
1776 1803
1777 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);; 1804 memcpy(wk->filter_ta, req->bss->bssid, ETH_ALEN);
1778 1805
1779 if (req->ie && req->ie_len) { 1806 if (req->ie && req->ie_len) {
1780 memcpy(wk->ie, req->ie, req->ie_len); 1807 memcpy(wk->ie, req->ie, req->ie_len);
@@ -1897,6 +1924,15 @@ int ieee80211_mgd_assoc(struct ieee80211_sub_if_data *sdata,
1897 wk->assoc.ht_information_ie = 1924 wk->assoc.ht_information_ie =
1898 ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION); 1925 ieee80211_bss_get_ie(req->bss, WLAN_EID_HT_INFORMATION);
1899 1926
1927 if (bss->wmm_used && bss->uapsd_supported &&
1928 (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_UAPSD)) {
1929 wk->assoc.uapsd_used = true;
1930 ifmgd->flags |= IEEE80211_STA_UAPSD_ENABLED;
1931 } else {
1932 wk->assoc.uapsd_used = false;
1933 ifmgd->flags &= ~IEEE80211_STA_UAPSD_ENABLED;
1934 }
1935
1900 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID); 1936 ssid = ieee80211_bss_get_ie(req->bss, WLAN_EID_SSID);
1901 memcpy(wk->assoc.ssid, ssid + 2, ssid[1]); 1937 memcpy(wk->assoc.ssid, ssid + 2, ssid[1]);
1902 wk->assoc.ssid_len = ssid[1]; 1938 wk->assoc.ssid_len = ssid[1];
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index a7bbfc40a648..c36b1911987a 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -113,7 +113,7 @@ void ieee80211_offchannel_stop_beaconing(struct ieee80211_local *local)
113 */ 113 */
114 if (sdata->vif.type != NL80211_IFTYPE_STATION && 114 if (sdata->vif.type != NL80211_IFTYPE_STATION &&
115 sdata->vif.type != NL80211_IFTYPE_MONITOR) 115 sdata->vif.type != NL80211_IFTYPE_MONITOR)
116 netif_stop_queue(sdata->dev); 116 netif_tx_stop_all_queues(sdata->dev);
117 } 117 }
118 mutex_unlock(&local->iflist_mtx); 118 mutex_unlock(&local->iflist_mtx);
119} 119}
@@ -131,7 +131,7 @@ void ieee80211_offchannel_stop_station(struct ieee80211_local *local)
131 continue; 131 continue;
132 132
133 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 133 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
134 netif_stop_queue(sdata->dev); 134 netif_tx_stop_all_queues(sdata->dev);
135 if (sdata->u.mgd.associated) 135 if (sdata->u.mgd.associated)
136 ieee80211_offchannel_ps_enable(sdata); 136 ieee80211_offchannel_ps_enable(sdata);
137 } 137 }
@@ -153,9 +153,11 @@ void ieee80211_offchannel_return(struct ieee80211_local *local,
153 if (sdata->vif.type == NL80211_IFTYPE_STATION) { 153 if (sdata->vif.type == NL80211_IFTYPE_STATION) {
154 if (sdata->u.mgd.associated) 154 if (sdata->u.mgd.associated)
155 ieee80211_offchannel_ps_disable(sdata); 155 ieee80211_offchannel_ps_disable(sdata);
156 netif_wake_queue(sdata->dev);
157 } 156 }
158 157
158 if (sdata->vif.type != NL80211_IFTYPE_MONITOR)
159 netif_tx_wake_all_queues(sdata->dev);
160
159 /* re-enable beaconing */ 161 /* re-enable beaconing */
160 if (enable_beaconing && 162 if (enable_beaconing &&
161 (sdata->vif.type == NL80211_IFTYPE_AP || 163 (sdata->vif.type == NL80211_IFTYPE_AP ||
diff --git a/net/mac80211/rate.c b/net/mac80211/rate.c
index b9007f80cb92..c74b7c85403c 100644
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -207,6 +207,27 @@ static bool rc_no_data_or_no_ack(struct ieee80211_tx_rate_control *txrc)
207 return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc)); 207 return ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !ieee80211_is_data(fc));
208} 208}
209 209
210static void rc_send_low_broadcast(s8 *idx, u32 basic_rates, u8 max_rate_idx)
211{
212 u8 i;
213
214 if (basic_rates == 0)
215 return; /* assume basic rates unknown and accept rate */
216 if (*idx < 0)
217 return;
218 if (basic_rates & (1 << *idx))
219 return; /* selected rate is a basic rate */
220
221 for (i = *idx + 1; i <= max_rate_idx; i++) {
222 if (basic_rates & (1 << i)) {
223 *idx = i;
224 return;
225 }
226 }
227
228 /* could not find a basic rate; use original selection */
229}
230
210bool rate_control_send_low(struct ieee80211_sta *sta, 231bool rate_control_send_low(struct ieee80211_sta *sta,
211 void *priv_sta, 232 void *priv_sta,
212 struct ieee80211_tx_rate_control *txrc) 233 struct ieee80211_tx_rate_control *txrc)
@@ -218,12 +239,48 @@ bool rate_control_send_low(struct ieee80211_sta *sta,
218 info->control.rates[0].count = 239 info->control.rates[0].count =
219 (info->flags & IEEE80211_TX_CTL_NO_ACK) ? 240 (info->flags & IEEE80211_TX_CTL_NO_ACK) ?
220 1 : txrc->hw->max_rate_tries; 241 1 : txrc->hw->max_rate_tries;
242 if (!sta && txrc->ap)
243 rc_send_low_broadcast(&info->control.rates[0].idx,
244 txrc->bss_conf->basic_rates,
245 txrc->sband->n_bitrates);
221 return true; 246 return true;
222 } 247 }
223 return false; 248 return false;
224} 249}
225EXPORT_SYMBOL(rate_control_send_low); 250EXPORT_SYMBOL(rate_control_send_low);
226 251
252static void rate_idx_match_mask(struct ieee80211_tx_rate *rate,
253 int n_bitrates, u32 mask)
254{
255 int j;
256
257 /* See whether the selected rate or anything below it is allowed. */
258 for (j = rate->idx; j >= 0; j--) {
259 if (mask & (1 << j)) {
260 /* Okay, found a suitable rate. Use it. */
261 rate->idx = j;
262 return;
263 }
264 }
265
266 /* Try to find a higher rate that would be allowed */
267 for (j = rate->idx + 1; j < n_bitrates; j++) {
268 if (mask & (1 << j)) {
269 /* Okay, found a suitable rate. Use it. */
270 rate->idx = j;
271 return;
272 }
273 }
274
275 /*
276 * Uh.. No suitable rate exists. This should not really happen with
277 * sane TX rate mask configurations. However, should someone manage to
278 * configure supported rates and TX rate mask in incompatible way,
279 * allow the frame to be transmitted with whatever the rate control
280 * selected.
281 */
282}
283
227void rate_control_get_rate(struct ieee80211_sub_if_data *sdata, 284void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
228 struct sta_info *sta, 285 struct sta_info *sta,
229 struct ieee80211_tx_rate_control *txrc) 286 struct ieee80211_tx_rate_control *txrc)
@@ -233,6 +290,7 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
233 struct ieee80211_sta *ista = NULL; 290 struct ieee80211_sta *ista = NULL;
234 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb); 291 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(txrc->skb);
235 int i; 292 int i;
293 u32 mask;
236 294
237 if (sta) { 295 if (sta) {
238 ista = &sta->sta; 296 ista = &sta->sta;
@@ -245,23 +303,31 @@ void rate_control_get_rate(struct ieee80211_sub_if_data *sdata,
245 info->control.rates[i].count = 1; 303 info->control.rates[i].count = 1;
246 } 304 }
247 305
248 if (sta && sdata->force_unicast_rateidx > -1) { 306 ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
249 info->control.rates[0].idx = sdata->force_unicast_rateidx;
250 } else {
251 ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
252 info->flags |= IEEE80211_TX_INTFL_RCALGO;
253 }
254 307
255 /* 308 /*
256 * try to enforce the maximum rate the user wanted 309 * Try to enforce the rateidx mask the user wanted. skip this if the
310 * default mask (allow all rates) is used to save some processing for
311 * the common case.
257 */ 312 */
258 if (sdata->max_ratectrl_rateidx > -1) 313 mask = sdata->rc_rateidx_mask[info->band];
314 if (mask != (1 << txrc->sband->n_bitrates) - 1) {
315 if (sta) {
316 /* Filter out rates that the STA does not support */
317 mask &= sta->sta.supp_rates[info->band];
318 }
319 /*
320 * Make sure the rate index selected for each TX rate is
321 * included in the configured mask and change the rate indexes
322 * if needed.
323 */
259 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) { 324 for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
325 /* Rate masking supports only legacy rates for now */
260 if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS) 326 if (info->control.rates[i].flags & IEEE80211_TX_RC_MCS)
261 continue; 327 continue;
262 info->control.rates[i].idx = 328 rate_idx_match_mask(&info->control.rates[i],
263 min_t(s8, info->control.rates[i].idx, 329 txrc->sband->n_bitrates, mask);
264 sdata->max_ratectrl_rateidx); 330 }
265 } 331 }
266 332
267 BUG_ON(info->control.rates[0].idx < 0); 333 BUG_ON(info->control.rates[0].idx < 0);
diff --git a/net/mac80211/rate.h b/net/mac80211/rate.h
index cb9bd1f65e27..669dddd40521 100644
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -44,10 +44,7 @@ static inline void rate_control_tx_status(struct ieee80211_local *local,
44 struct rate_control_ref *ref = local->rate_ctrl; 44 struct rate_control_ref *ref = local->rate_ctrl;
45 struct ieee80211_sta *ista = &sta->sta; 45 struct ieee80211_sta *ista = &sta->sta;
46 void *priv_sta = sta->rate_ctrl_priv; 46 void *priv_sta = sta->rate_ctrl_priv;
47 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 47 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
48
49 if (likely(info->flags & IEEE80211_TX_INTFL_RCALGO))
50 ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
51} 48}
52 49
53 50
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index bfcf09eb64b4..efa6d3689c5e 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1111,6 +1111,18 @@ ieee80211_rx_h_sta_process(struct ieee80211_rx_data *rx)
1111 if (ieee80211_is_nullfunc(hdr->frame_control) || 1111 if (ieee80211_is_nullfunc(hdr->frame_control) ||
1112 ieee80211_is_qos_nullfunc(hdr->frame_control)) { 1112 ieee80211_is_qos_nullfunc(hdr->frame_control)) {
1113 I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc); 1113 I802_DEBUG_INC(rx->local->rx_handlers_drop_nullfunc);
1114
1115 /*
1116 * If we receive a 4-addr nullfunc frame from a STA
1117 * that was not moved to a 4-addr STA vlan yet, drop
1118 * the frame to the monitor interface, to make sure
1119 * that hostapd sees it
1120 */
1121 if (ieee80211_has_a4(hdr->frame_control) &&
1122 (rx->sdata->vif.type == NL80211_IFTYPE_AP ||
1123 (rx->sdata->vif.type == NL80211_IFTYPE_AP_VLAN &&
1124 !rx->sdata->u.vlan.sta)))
1125 return RX_DROP_MONITOR;
1114 /* 1126 /*
1115 * Update counter and free packet here to avoid 1127 * Update counter and free packet here to avoid
1116 * counting this as a dropped packed. 1128 * counting this as a dropped packed.
@@ -1665,7 +1677,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
1665 memset(info, 0, sizeof(*info)); 1677 memset(info, 0, sizeof(*info));
1666 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; 1678 info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
1667 info->control.vif = &rx->sdata->vif; 1679 info->control.vif = &rx->sdata->vif;
1668 ieee80211_select_queue(local, fwd_skb); 1680 skb_set_queue_mapping(skb,
1681 ieee80211_select_queue(rx->sdata, fwd_skb));
1682 ieee80211_set_qos_hdr(local, skb);
1669 if (is_multicast_ether_addr(fwd_hdr->addr1)) 1683 if (is_multicast_ether_addr(fwd_hdr->addr1))
1670 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh, 1684 IEEE80211_IFSTA_MESH_CTR_INC(&sdata->u.mesh,
1671 fwded_mcast); 1685 fwded_mcast);
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 365f40975511..9afe2f9885dc 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -12,7 +12,6 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 */ 13 */
14 14
15#include <linux/wireless.h>
16#include <linux/if_arp.h> 15#include <linux/if_arp.h>
17#include <linux/rtnetlink.h> 16#include <linux/rtnetlink.h>
18#include <net/mac80211.h> 17#include <net/mac80211.h>
@@ -55,6 +54,23 @@ void ieee80211_rx_bss_put(struct ieee80211_local *local,
55 cfg80211_put_bss(container_of((void *)bss, struct cfg80211_bss, priv)); 54 cfg80211_put_bss(container_of((void *)bss, struct cfg80211_bss, priv));
56} 55}
57 56
57static bool is_uapsd_supported(struct ieee802_11_elems *elems)
58{
59 u8 qos_info;
60
61 if (elems->wmm_info && elems->wmm_info_len == 7
62 && elems->wmm_info[5] == 1)
63 qos_info = elems->wmm_info[6];
64 else if (elems->wmm_param && elems->wmm_param_len == 24
65 && elems->wmm_param[5] == 1)
66 qos_info = elems->wmm_param[6];
67 else
68 /* no valid wmm information or parameter element found */
69 return false;
70
71 return qos_info & IEEE80211_WMM_IE_AP_QOSINFO_UAPSD;
72}
73
58struct ieee80211_bss * 74struct ieee80211_bss *
59ieee80211_bss_info_update(struct ieee80211_local *local, 75ieee80211_bss_info_update(struct ieee80211_local *local,
60 struct ieee80211_rx_status *rx_status, 76 struct ieee80211_rx_status *rx_status,
@@ -118,6 +134,7 @@ ieee80211_bss_info_update(struct ieee80211_local *local,
118 } 134 }
119 135
120 bss->wmm_used = elems->wmm_param || elems->wmm_info; 136 bss->wmm_used = elems->wmm_param || elems->wmm_info;
137 bss->uapsd_supported = is_uapsd_supported(elems);
121 138
122 if (!beacon) 139 if (!beacon)
123 bss->last_probe_resp = jiffies; 140 bss->last_probe_resp = jiffies;
@@ -285,6 +302,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw, bool aborted)
285 ieee80211_mlme_notify_scan_completed(local); 302 ieee80211_mlme_notify_scan_completed(local);
286 ieee80211_ibss_notify_scan_completed(local); 303 ieee80211_ibss_notify_scan_completed(local);
287 ieee80211_mesh_notify_scan_completed(local); 304 ieee80211_mesh_notify_scan_completed(local);
305 ieee80211_queue_work(&local->hw, &local->work_work);
288} 306}
289EXPORT_SYMBOL(ieee80211_scan_completed); 307EXPORT_SYMBOL(ieee80211_scan_completed);
290 308
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 47da552ce8a6..f735826f055c 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -119,6 +119,27 @@ struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
119 return sta; 119 return sta;
120} 120}
121 121
122/*
123 * Get sta info either from the specified interface
124 * or from one of its vlans
125 */
126struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
127 const u8 *addr)
128{
129 struct ieee80211_local *local = sdata->local;
130 struct sta_info *sta;
131
132 sta = rcu_dereference(local->sta_hash[STA_HASH(addr)]);
133 while (sta) {
134 if ((sta->sdata == sdata ||
135 sta->sdata->bss == sdata->bss) &&
136 memcmp(sta->sta.addr, addr, ETH_ALEN) == 0)
137 break;
138 sta = rcu_dereference(sta->hnext);
139 }
140 return sta;
141}
142
122struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata, 143struct sta_info *sta_info_get_by_idx(struct ieee80211_sub_if_data *sdata,
123 int idx) 144 int idx)
124{ 145{
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index c8208236e896..6f79bba5706e 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -408,6 +408,9 @@ static inline u32 get_sta_flags(struct sta_info *sta)
408struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata, 408struct sta_info *sta_info_get(struct ieee80211_sub_if_data *sdata,
409 const u8 *addr); 409 const u8 *addr);
410 410
411struct sta_info *sta_info_get_bss(struct ieee80211_sub_if_data *sdata,
412 const u8 *addr);
413
411static inline 414static inline
412void for_each_sta_info_type_check(struct ieee80211_local *local, 415void for_each_sta_info_type_check(struct ieee80211_local *local,
413 const u8 *addr, 416 const u8 *addr,
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 7bba49d2b6ca..daf81048c1f7 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -180,6 +180,71 @@ static int inline is_ieee80211_device(struct ieee80211_local *local,
180} 180}
181 181
182/* tx handlers */ 182/* tx handlers */
183static ieee80211_tx_result debug_noinline
184ieee80211_tx_h_dynamic_ps(struct ieee80211_tx_data *tx)
185{
186 struct ieee80211_local *local = tx->local;
187 struct ieee80211_if_managed *ifmgd;
188
189 /* driver doesn't support power save */
190 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
191 return TX_CONTINUE;
192
193 /* hardware does dynamic power save */
194 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
195 return TX_CONTINUE;
196
197 /* dynamic power save disabled */
198 if (local->hw.conf.dynamic_ps_timeout <= 0)
199 return TX_CONTINUE;
200
201 /* we are scanning, don't enable power save */
202 if (local->scanning)
203 return TX_CONTINUE;
204
205 if (!local->ps_sdata)
206 return TX_CONTINUE;
207
208 /* No point if we're going to suspend */
209 if (local->quiescing)
210 return TX_CONTINUE;
211
212 /* dynamic ps is supported only in managed mode */
213 if (tx->sdata->vif.type != NL80211_IFTYPE_STATION)
214 return TX_CONTINUE;
215
216 ifmgd = &tx->sdata->u.mgd;
217
218 /*
219 * Don't wakeup from power save if u-apsd is enabled, voip ac has
220 * u-apsd enabled and the frame is in voip class. This effectively
221 * means that even if all access categories have u-apsd enabled, in
222 * practise u-apsd is only used with the voip ac. This is a
223 * workaround for the case when received voip class packets do not
224 * have correct qos tag for some reason, due the network or the
225 * peer application.
226 *
227 * Note: local->uapsd_queues access is racy here. If the value is
228 * changed via debugfs, user needs to reassociate manually to have
229 * everything in sync.
230 */
231 if ((ifmgd->flags & IEEE80211_STA_UAPSD_ENABLED)
232 && (local->uapsd_queues & IEEE80211_WMM_IE_STA_QOSINFO_AC_VO)
233 && skb_get_queue_mapping(tx->skb) == 0)
234 return TX_CONTINUE;
235
236 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
237 ieee80211_stop_queues_by_reason(&local->hw,
238 IEEE80211_QUEUE_STOP_REASON_PS);
239 ieee80211_queue_work(&local->hw,
240 &local->dynamic_ps_disable_work);
241 }
242
243 mod_timer(&local->dynamic_ps_timer, jiffies +
244 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
245
246 return TX_CONTINUE;
247}
183 248
184static ieee80211_tx_result debug_noinline 249static ieee80211_tx_result debug_noinline
185ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx) 250ieee80211_tx_h_check_assoc(struct ieee80211_tx_data *tx)
@@ -519,7 +584,12 @@ ieee80211_tx_h_rate_ctrl(struct ieee80211_tx_data *tx)
519 txrc.bss_conf = &tx->sdata->vif.bss_conf; 584 txrc.bss_conf = &tx->sdata->vif.bss_conf;
520 txrc.skb = tx->skb; 585 txrc.skb = tx->skb;
521 txrc.reported_rate.idx = -1; 586 txrc.reported_rate.idx = -1;
522 txrc.max_rate_idx = tx->sdata->max_ratectrl_rateidx; 587 txrc.rate_idx_mask = tx->sdata->rc_rateidx_mask[tx->channel->band];
588 if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1)
589 txrc.max_rate_idx = -1;
590 else
591 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
592 txrc.ap = tx->sdata->vif.type == NL80211_IFTYPE_AP;
523 593
524 /* set up RTS protection if desired */ 594 /* set up RTS protection if desired */
525 if (len > tx->local->hw.wiphy->rts_threshold) { 595 if (len > tx->local->hw.wiphy->rts_threshold) {
@@ -1051,8 +1121,11 @@ ieee80211_tx_prepare(struct ieee80211_sub_if_data *sdata,
1051 1121
1052 hdr = (struct ieee80211_hdr *) skb->data; 1122 hdr = (struct ieee80211_hdr *) skb->data;
1053 1123
1054 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) 1124 if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
1055 tx->sta = rcu_dereference(sdata->u.vlan.sta); 1125 tx->sta = rcu_dereference(sdata->u.vlan.sta);
1126 if (!tx->sta && sdata->dev->ieee80211_ptr->use_4addr)
1127 return TX_DROP;
1128 }
1056 if (!tx->sta) 1129 if (!tx->sta)
1057 tx->sta = sta_info_get(sdata, hdr->addr1); 1130 tx->sta = sta_info_get(sdata, hdr->addr1);
1058 1131
@@ -1215,6 +1288,7 @@ static int invoke_tx_handlers(struct ieee80211_tx_data *tx)
1215 goto txh_done; \ 1288 goto txh_done; \
1216 } while (0) 1289 } while (0)
1217 1290
1291 CALL_TXH(ieee80211_tx_h_dynamic_ps);
1218 CALL_TXH(ieee80211_tx_h_check_assoc); 1292 CALL_TXH(ieee80211_tx_h_check_assoc);
1219 CALL_TXH(ieee80211_tx_h_ps_buf); 1293 CALL_TXH(ieee80211_tx_h_ps_buf);
1220 CALL_TXH(ieee80211_tx_h_select_key); 1294 CALL_TXH(ieee80211_tx_h_select_key);
@@ -1397,34 +1471,6 @@ static int ieee80211_skb_resize(struct ieee80211_local *local,
1397 return 0; 1471 return 0;
1398} 1472}
1399 1473
1400static bool need_dynamic_ps(struct ieee80211_local *local)
1401{
1402 /* driver doesn't support power save */
1403 if (!(local->hw.flags & IEEE80211_HW_SUPPORTS_PS))
1404 return false;
1405
1406 /* hardware does dynamic power save */
1407 if (local->hw.flags & IEEE80211_HW_SUPPORTS_DYNAMIC_PS)
1408 return false;
1409
1410 /* dynamic power save disabled */
1411 if (local->hw.conf.dynamic_ps_timeout <= 0)
1412 return false;
1413
1414 /* we are scanning, don't enable power save */
1415 if (local->scanning)
1416 return false;
1417
1418 if (!local->ps_sdata)
1419 return false;
1420
1421 /* No point if we're going to suspend */
1422 if (local->quiescing)
1423 return false;
1424
1425 return true;
1426}
1427
1428static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata, 1474static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1429 struct sk_buff *skb) 1475 struct sk_buff *skb)
1430{ 1476{
@@ -1435,18 +1481,6 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1435 int headroom; 1481 int headroom;
1436 bool may_encrypt; 1482 bool may_encrypt;
1437 1483
1438 if (need_dynamic_ps(local)) {
1439 if (local->hw.conf.flags & IEEE80211_CONF_PS) {
1440 ieee80211_stop_queues_by_reason(&local->hw,
1441 IEEE80211_QUEUE_STOP_REASON_PS);
1442 ieee80211_queue_work(&local->hw,
1443 &local->dynamic_ps_disable_work);
1444 }
1445
1446 mod_timer(&local->dynamic_ps_timer, jiffies +
1447 msecs_to_jiffies(local->hw.conf.dynamic_ps_timeout));
1448 }
1449
1450 rcu_read_lock(); 1484 rcu_read_lock();
1451 1485
1452 if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) { 1486 if (unlikely(sdata->vif.type == NL80211_IFTYPE_MONITOR)) {
@@ -1511,7 +1545,7 @@ static void ieee80211_xmit(struct ieee80211_sub_if_data *sdata,
1511 return; 1545 return;
1512 } 1546 }
1513 1547
1514 ieee80211_select_queue(local, skb); 1548 ieee80211_set_qos_hdr(local, skb);
1515 ieee80211_tx(sdata, skb, false); 1549 ieee80211_tx(sdata, skb, false);
1516 rcu_read_unlock(); 1550 rcu_read_unlock();
1517} 1551}
@@ -2060,6 +2094,7 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2060 struct beacon_data *beacon; 2094 struct beacon_data *beacon;
2061 struct ieee80211_supported_band *sband; 2095 struct ieee80211_supported_band *sband;
2062 enum ieee80211_band band = local->hw.conf.channel->band; 2096 enum ieee80211_band band = local->hw.conf.channel->band;
2097 struct ieee80211_tx_rate_control txrc;
2063 2098
2064 sband = local->hw.wiphy->bands[band]; 2099 sband = local->hw.wiphy->bands[band];
2065 2100
@@ -2167,21 +2202,25 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2167 info = IEEE80211_SKB_CB(skb); 2202 info = IEEE80211_SKB_CB(skb);
2168 2203
2169 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 2204 info->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
2205 info->flags |= IEEE80211_TX_CTL_NO_ACK;
2170 info->band = band; 2206 info->band = band;
2171 /* 2207
2172 * XXX: For now, always use the lowest rate 2208 memset(&txrc, 0, sizeof(txrc));
2173 */ 2209 txrc.hw = hw;
2174 info->control.rates[0].idx = 0; 2210 txrc.sband = sband;
2175 info->control.rates[0].count = 1; 2211 txrc.bss_conf = &sdata->vif.bss_conf;
2176 info->control.rates[1].idx = -1; 2212 txrc.skb = skb;
2177 info->control.rates[2].idx = -1; 2213 txrc.reported_rate.idx = -1;
2178 info->control.rates[3].idx = -1; 2214 txrc.rate_idx_mask = sdata->rc_rateidx_mask[band];
2179 info->control.rates[4].idx = -1; 2215 if (txrc.rate_idx_mask == (1 << sband->n_bitrates) - 1)
2180 BUILD_BUG_ON(IEEE80211_TX_MAX_RATES != 5); 2216 txrc.max_rate_idx = -1;
2217 else
2218 txrc.max_rate_idx = fls(txrc.rate_idx_mask) - 1;
2219 txrc.ap = true;
2220 rate_control_get_rate(sdata, NULL, &txrc);
2181 2221
2182 info->control.vif = vif; 2222 info->control.vif = vif;
2183 2223
2184 info->flags |= IEEE80211_TX_CTL_NO_ACK;
2185 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT; 2224 info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
2186 info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ; 2225 info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
2187 out: 2226 out:
@@ -2190,6 +2229,134 @@ struct sk_buff *ieee80211_beacon_get_tim(struct ieee80211_hw *hw,
2190} 2229}
2191EXPORT_SYMBOL(ieee80211_beacon_get_tim); 2230EXPORT_SYMBOL(ieee80211_beacon_get_tim);
2192 2231
2232struct sk_buff *ieee80211_pspoll_get(struct ieee80211_hw *hw,
2233 struct ieee80211_vif *vif)
2234{
2235 struct ieee80211_sub_if_data *sdata;
2236 struct ieee80211_if_managed *ifmgd;
2237 struct ieee80211_pspoll *pspoll;
2238 struct ieee80211_local *local;
2239 struct sk_buff *skb;
2240
2241 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
2242 return NULL;
2243
2244 sdata = vif_to_sdata(vif);
2245 ifmgd = &sdata->u.mgd;
2246 local = sdata->local;
2247
2248 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*pspoll));
2249 if (!skb) {
2250 printk(KERN_DEBUG "%s: failed to allocate buffer for "
2251 "pspoll template\n", sdata->name);
2252 return NULL;
2253 }
2254 skb_reserve(skb, local->hw.extra_tx_headroom);
2255
2256 pspoll = (struct ieee80211_pspoll *) skb_put(skb, sizeof(*pspoll));
2257 memset(pspoll, 0, sizeof(*pspoll));
2258 pspoll->frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL |
2259 IEEE80211_STYPE_PSPOLL);
2260 pspoll->aid = cpu_to_le16(ifmgd->aid);
2261
2262 /* aid in PS-Poll has its two MSBs each set to 1 */
2263 pspoll->aid |= cpu_to_le16(1 << 15 | 1 << 14);
2264
2265 memcpy(pspoll->bssid, ifmgd->bssid, ETH_ALEN);
2266 memcpy(pspoll->ta, vif->addr, ETH_ALEN);
2267
2268 return skb;
2269}
2270EXPORT_SYMBOL(ieee80211_pspoll_get);
2271
2272struct sk_buff *ieee80211_nullfunc_get(struct ieee80211_hw *hw,
2273 struct ieee80211_vif *vif)
2274{
2275 struct ieee80211_hdr_3addr *nullfunc;
2276 struct ieee80211_sub_if_data *sdata;
2277 struct ieee80211_if_managed *ifmgd;
2278 struct ieee80211_local *local;
2279 struct sk_buff *skb;
2280
2281 if (WARN_ON(vif->type != NL80211_IFTYPE_STATION))
2282 return NULL;
2283
2284 sdata = vif_to_sdata(vif);
2285 ifmgd = &sdata->u.mgd;
2286 local = sdata->local;
2287
2288 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*nullfunc));
2289 if (!skb) {
2290 printk(KERN_DEBUG "%s: failed to allocate buffer for nullfunc "
2291 "template\n", sdata->name);
2292 return NULL;
2293 }
2294 skb_reserve(skb, local->hw.extra_tx_headroom);
2295
2296 nullfunc = (struct ieee80211_hdr_3addr *) skb_put(skb,
2297 sizeof(*nullfunc));
2298 memset(nullfunc, 0, sizeof(*nullfunc));
2299 nullfunc->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
2300 IEEE80211_STYPE_NULLFUNC |
2301 IEEE80211_FCTL_TODS);
2302 memcpy(nullfunc->addr1, ifmgd->bssid, ETH_ALEN);
2303 memcpy(nullfunc->addr2, vif->addr, ETH_ALEN);
2304 memcpy(nullfunc->addr3, ifmgd->bssid, ETH_ALEN);
2305
2306 return skb;
2307}
2308EXPORT_SYMBOL(ieee80211_nullfunc_get);
2309
2310struct sk_buff *ieee80211_probereq_get(struct ieee80211_hw *hw,
2311 struct ieee80211_vif *vif,
2312 const u8 *ssid, size_t ssid_len,
2313 const u8 *ie, size_t ie_len)
2314{
2315 struct ieee80211_sub_if_data *sdata;
2316 struct ieee80211_local *local;
2317 struct ieee80211_hdr_3addr *hdr;
2318 struct sk_buff *skb;
2319 size_t ie_ssid_len;
2320 u8 *pos;
2321
2322 sdata = vif_to_sdata(vif);
2323 local = sdata->local;
2324 ie_ssid_len = 2 + ssid_len;
2325
2326 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*hdr) +
2327 ie_ssid_len + ie_len);
2328 if (!skb) {
2329 printk(KERN_DEBUG "%s: failed to allocate buffer for probe "
2330 "request template\n", sdata->name);
2331 return NULL;
2332 }
2333
2334 skb_reserve(skb, local->hw.extra_tx_headroom);
2335
2336 hdr = (struct ieee80211_hdr_3addr *) skb_put(skb, sizeof(*hdr));
2337 memset(hdr, 0, sizeof(*hdr));
2338 hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
2339 IEEE80211_STYPE_PROBE_REQ);
2340 memset(hdr->addr1, 0xff, ETH_ALEN);
2341 memcpy(hdr->addr2, vif->addr, ETH_ALEN);
2342 memset(hdr->addr3, 0xff, ETH_ALEN);
2343
2344 pos = skb_put(skb, ie_ssid_len);
2345 *pos++ = WLAN_EID_SSID;
2346 *pos++ = ssid_len;
2347 if (ssid)
2348 memcpy(pos, ssid, ssid_len);
2349 pos += ssid_len;
2350
2351 if (ie) {
2352 pos = skb_put(skb, ie_len);
2353 memcpy(pos, ie, ie_len);
2354 }
2355
2356 return skb;
2357}
2358EXPORT_SYMBOL(ieee80211_probereq_get);
2359
2193void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 2360void ieee80211_rts_get(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
2194 const void *frame, size_t frame_len, 2361 const void *frame, size_t frame_len,
2195 const struct ieee80211_tx_info *frame_txctl, 2362 const struct ieee80211_tx_info *frame_txctl,
@@ -2289,6 +2456,9 @@ void ieee80211_tx_skb(struct ieee80211_sub_if_data *sdata, struct sk_buff *skb)
2289 skb_set_network_header(skb, 0); 2456 skb_set_network_header(skb, 0);
2290 skb_set_transport_header(skb, 0); 2457 skb_set_transport_header(skb, 0);
2291 2458
2459 /* send all internal mgmt frames on VO */
2460 skb_set_queue_mapping(skb, 0);
2461
2292 /* 2462 /*
2293 * The other path calling ieee80211_xmit is from the tasklet, 2463 * The other path calling ieee80211_xmit is from the tasklet,
2294 * and while we can handle concurrent transmissions locking 2464 * and while we can handle concurrent transmissions locking
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index 7e38858a9280..ca170b417da6 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -18,7 +18,6 @@
18#include <linux/skbuff.h> 18#include <linux/skbuff.h>
19#include <linux/etherdevice.h> 19#include <linux/etherdevice.h>
20#include <linux/if_arp.h> 20#include <linux/if_arp.h>
21#include <linux/wireless.h>
22#include <linux/bitmap.h> 21#include <linux/bitmap.h>
23#include <linux/crc32.h> 22#include <linux/crc32.h>
24#include <net/net_namespace.h> 23#include <net/net_namespace.h>
@@ -269,6 +268,7 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
269 enum queue_stop_reason reason) 268 enum queue_stop_reason reason)
270{ 269{
271 struct ieee80211_local *local = hw_to_local(hw); 270 struct ieee80211_local *local = hw_to_local(hw);
271 struct ieee80211_sub_if_data *sdata;
272 272
273 if (WARN_ON(queue >= hw->queues)) 273 if (WARN_ON(queue >= hw->queues))
274 return; 274 return;
@@ -281,6 +281,11 @@ static void __ieee80211_wake_queue(struct ieee80211_hw *hw, int queue,
281 281
282 if (!skb_queue_empty(&local->pending[queue])) 282 if (!skb_queue_empty(&local->pending[queue]))
283 tasklet_schedule(&local->tx_pending_tasklet); 283 tasklet_schedule(&local->tx_pending_tasklet);
284
285 rcu_read_lock();
286 list_for_each_entry_rcu(sdata, &local->interfaces, list)
287 netif_tx_wake_queue(netdev_get_tx_queue(sdata->dev, queue));
288 rcu_read_unlock();
284} 289}
285 290
286void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, 291void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -305,11 +310,17 @@ static void __ieee80211_stop_queue(struct ieee80211_hw *hw, int queue,
305 enum queue_stop_reason reason) 310 enum queue_stop_reason reason)
306{ 311{
307 struct ieee80211_local *local = hw_to_local(hw); 312 struct ieee80211_local *local = hw_to_local(hw);
313 struct ieee80211_sub_if_data *sdata;
308 314
309 if (WARN_ON(queue >= hw->queues)) 315 if (WARN_ON(queue >= hw->queues))
310 return; 316 return;
311 317
312 __set_bit(reason, &local->queue_stop_reasons[queue]); 318 __set_bit(reason, &local->queue_stop_reasons[queue]);
319
320 rcu_read_lock();
321 list_for_each_entry_rcu(sdata, &local->interfaces, list)
322 netif_tx_stop_queue(netdev_get_tx_queue(sdata->dev, queue));
323 rcu_read_unlock();
313} 324}
314 325
315void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue, 326void ieee80211_stop_queue_by_reason(struct ieee80211_hw *hw, int queue,
@@ -781,6 +792,8 @@ void ieee80211_set_wmm_default(struct ieee80211_sub_if_data *sdata)
781 break; 792 break;
782 } 793 }
783 794
795 qparam.uapsd = false;
796
784 drv_conf_tx(local, queue, &qparam); 797 drv_conf_tx(local, queue, &qparam);
785 } 798 }
786} 799}
@@ -989,40 +1002,33 @@ void ieee80211_send_probe_req(struct ieee80211_sub_if_data *sdata, u8 *dst,
989 struct ieee80211_local *local = sdata->local; 1002 struct ieee80211_local *local = sdata->local;
990 struct sk_buff *skb; 1003 struct sk_buff *skb;
991 struct ieee80211_mgmt *mgmt; 1004 struct ieee80211_mgmt *mgmt;
992 u8 *pos; 1005 size_t buf_len;
993 1006 u8 *buf;
994 skb = dev_alloc_skb(local->hw.extra_tx_headroom + sizeof(*mgmt) + 200 + 1007
995 ie_len); 1008 /* FIXME: come up with a proper value */
996 if (!skb) { 1009 buf = kmalloc(200 + ie_len, GFP_KERNEL);
997 printk(KERN_DEBUG "%s: failed to allocate buffer for probe " 1010 if (!buf) {
998 "request\n", sdata->name); 1011 printk(KERN_DEBUG "%s: failed to allocate temporary IE "
1012 "buffer\n", sdata->name);
999 return; 1013 return;
1000 } 1014 }
1001 skb_reserve(skb, local->hw.extra_tx_headroom);
1002 1015
1003 mgmt = (struct ieee80211_mgmt *) skb_put(skb, 24); 1016 buf_len = ieee80211_build_preq_ies(local, buf, ie, ie_len,
1004 memset(mgmt, 0, 24); 1017 local->hw.conf.channel->band);
1005 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT | 1018
1006 IEEE80211_STYPE_PROBE_REQ); 1019 skb = ieee80211_probereq_get(&local->hw, &sdata->vif,
1007 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN); 1020 ssid, ssid_len,
1021 buf, buf_len);
1022
1008 if (dst) { 1023 if (dst) {
1024 mgmt = (struct ieee80211_mgmt *) skb->data;
1009 memcpy(mgmt->da, dst, ETH_ALEN); 1025 memcpy(mgmt->da, dst, ETH_ALEN);
1010 memcpy(mgmt->bssid, dst, ETH_ALEN); 1026 memcpy(mgmt->bssid, dst, ETH_ALEN);
1011 } else {
1012 memset(mgmt->da, 0xff, ETH_ALEN);
1013 memset(mgmt->bssid, 0xff, ETH_ALEN);
1014 } 1027 }
1015 pos = skb_put(skb, 2 + ssid_len);
1016 *pos++ = WLAN_EID_SSID;
1017 *pos++ = ssid_len;
1018 memcpy(pos, ssid, ssid_len);
1019 pos += ssid_len;
1020
1021 skb_put(skb, ieee80211_build_preq_ies(local, pos, ie, ie_len,
1022 local->hw.conf.channel->band));
1023 1028
1024 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT; 1029 IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
1025 ieee80211_tx_skb(sdata, skb); 1030 ieee80211_tx_skb(sdata, skb);
1031 kfree(buf);
1026} 1032}
1027 1033
1028u32 ieee80211_sta_get_rates(struct ieee80211_local *local, 1034u32 ieee80211_sta_get_rates(struct ieee80211_local *local,
@@ -1066,9 +1072,9 @@ void ieee80211_stop_device(struct ieee80211_local *local)
1066 ieee80211_led_radio(local, false); 1072 ieee80211_led_radio(local, false);
1067 1073
1068 cancel_work_sync(&local->reconfig_filter); 1074 cancel_work_sync(&local->reconfig_filter);
1069 drv_stop(local);
1070 1075
1071 flush_workqueue(local->workqueue); 1076 flush_workqueue(local->workqueue);
1077 drv_stop(local);
1072} 1078}
1073 1079
1074int ieee80211_reconfig(struct ieee80211_local *local) 1080int ieee80211_reconfig(struct ieee80211_local *local)
@@ -1094,7 +1100,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
1094 if (res) { 1100 if (res) {
1095 WARN(local->suspended, "Harware became unavailable " 1101 WARN(local->suspended, "Harware became unavailable "
1096 "upon resume. This is could be a software issue" 1102 "upon resume. This is could be a software issue"
1097 "prior to suspend or a harware issue\n"); 1103 "prior to suspend or a hardware issue\n");
1098 return res; 1104 return res;
1099 } 1105 }
1100 1106
diff --git a/net/mac80211/wme.c b/net/mac80211/wme.c
index b19b7696f3a2..34e6d02da779 100644
--- a/net/mac80211/wme.c
+++ b/net/mac80211/wme.c
@@ -44,22 +44,69 @@ static int wme_downgrade_ac(struct sk_buff *skb)
44} 44}
45 45
46 46
47/* Indicate which queue to use. */ 47/* Indicate which queue to use. */
48static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb) 48u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
49 struct sk_buff *skb)
49{ 50{
50 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 51 struct ieee80211_local *local = sdata->local;
52 struct sta_info *sta = NULL;
53 u32 sta_flags = 0;
54 const u8 *ra = NULL;
55 bool qos = false;
51 56
52 if (!ieee80211_is_data(hdr->frame_control)) { 57 if (local->hw.queues < 4 || skb->len < 6) {
53 /* management frames go on AC_VO queue, but are sent 58 skb->priority = 0; /* required for correct WPA/11i MIC */
54 * without QoS control fields */ 59 return min_t(u16, local->hw.queues - 1,
55 return 0; 60 ieee802_1d_to_ac[skb->priority]);
61 }
62
63 rcu_read_lock();
64 switch (sdata->vif.type) {
65 case NL80211_IFTYPE_AP_VLAN:
66 rcu_read_lock();
67 sta = rcu_dereference(sdata->u.vlan.sta);
68 if (sta)
69 sta_flags = get_sta_flags(sta);
70 rcu_read_unlock();
71 if (sta)
72 break;
73 case NL80211_IFTYPE_AP:
74 ra = skb->data;
75 break;
76 case NL80211_IFTYPE_WDS:
77 ra = sdata->u.wds.remote_addr;
78 break;
79#ifdef CONFIG_MAC80211_MESH
80 case NL80211_IFTYPE_MESH_POINT:
81 /*
82 * XXX: This is clearly broken ... but already was before,
83 * because ieee80211_fill_mesh_addresses() would clear A1
84 * except for multicast addresses.
85 */
86 break;
87#endif
88 case NL80211_IFTYPE_STATION:
89 ra = sdata->u.mgd.bssid;
90 break;
91 case NL80211_IFTYPE_ADHOC:
92 ra = skb->data;
93 break;
94 default:
95 break;
56 } 96 }
57 97
58 if (0 /* injected */) { 98 if (!sta && ra && !is_multicast_ether_addr(ra)) {
59 /* use AC from radiotap */ 99 sta = sta_info_get(sdata, ra);
100 if (sta)
101 sta_flags = get_sta_flags(sta);
60 } 102 }
61 103
62 if (!ieee80211_is_data_qos(hdr->frame_control)) { 104 if (sta_flags & WLAN_STA_WME)
105 qos = true;
106
107 rcu_read_unlock();
108
109 if (!qos) {
63 skb->priority = 0; /* required for correct WPA/11i MIC */ 110 skb->priority = 0; /* required for correct WPA/11i MIC */
64 return ieee802_1d_to_ac[skb->priority]; 111 return ieee802_1d_to_ac[skb->priority];
65 } 112 }
@@ -68,6 +115,12 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
68 * data frame has */ 115 * data frame has */
69 skb->priority = cfg80211_classify8021d(skb); 116 skb->priority = cfg80211_classify8021d(skb);
70 117
118 return ieee80211_downgrade_queue(local, skb);
119}
120
121u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
122 struct sk_buff *skb)
123{
71 /* in case we are a client verify acm is not set for this ac */ 124 /* in case we are a client verify acm is not set for this ac */
72 while (unlikely(local->wmm_acm & BIT(skb->priority))) { 125 while (unlikely(local->wmm_acm & BIT(skb->priority))) {
73 if (wme_downgrade_ac(skb)) { 126 if (wme_downgrade_ac(skb)) {
@@ -85,24 +138,17 @@ static u16 classify80211(struct ieee80211_local *local, struct sk_buff *skb)
85 return ieee802_1d_to_ac[skb->priority]; 138 return ieee802_1d_to_ac[skb->priority];
86} 139}
87 140
88void ieee80211_select_queue(struct ieee80211_local *local, struct sk_buff *skb) 141void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb)
89{ 142{
90 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 143 struct ieee80211_hdr *hdr = (void *)skb->data;
91 u16 queue; 144
92 u8 tid; 145 /* Fill in the QoS header if there is one. */
93
94 queue = classify80211(local, skb);
95 if (unlikely(queue >= local->hw.queues))
96 queue = local->hw.queues - 1;
97
98 /*
99 * Now we know the 1d priority, fill in the QoS header if
100 * there is one (and we haven't done this before).
101 */
102 if (ieee80211_is_data_qos(hdr->frame_control)) { 146 if (ieee80211_is_data_qos(hdr->frame_control)) {
103 u8 *p = ieee80211_get_qos_ctl(hdr); 147 u8 *p = ieee80211_get_qos_ctl(hdr);
104 u8 ack_policy = 0; 148 u8 ack_policy = 0, tid;
149
105 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK; 150 tid = skb->priority & IEEE80211_QOS_CTL_TAG1D_MASK;
151
106 if (unlikely(local->wifi_wme_noack_test)) 152 if (unlikely(local->wifi_wme_noack_test))
107 ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK << 153 ack_policy |= QOS_CONTROL_ACK_POLICY_NOACK <<
108 QOS_CONTROL_ACK_POLICY_SHIFT; 154 QOS_CONTROL_ACK_POLICY_SHIFT;
@@ -110,6 +156,4 @@ void ieee80211_select_queue(struct ieee80211_local *local, struct sk_buff *skb)
110 *p++ = ack_policy | tid; 156 *p++ = ack_policy | tid;
111 *p = 0; 157 *p = 0;
112 } 158 }
113
114 skb_set_queue_mapping(skb, queue);
115} 159}
diff --git a/net/mac80211/wme.h b/net/mac80211/wme.h
index d4fd87ca5118..6053b1c9feee 100644
--- a/net/mac80211/wme.h
+++ b/net/mac80211/wme.h
@@ -20,7 +20,11 @@
20 20
21extern const int ieee802_1d_to_ac[8]; 21extern const int ieee802_1d_to_ac[8];
22 22
23void ieee80211_select_queue(struct ieee80211_local *local, 23u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata,
24 struct sk_buff *skb); 24 struct sk_buff *skb);
25void ieee80211_set_qos_hdr(struct ieee80211_local *local, struct sk_buff *skb);
26u16 ieee80211_downgrade_queue(struct ieee80211_local *local,
27 struct sk_buff *skb);
28
25 29
26#endif /* _WME_H */ 30#endif /* _WME_H */
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index ea89ed70734d..81bd5d592bb4 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -202,7 +202,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
202 struct ieee80211_local *local = sdata->local; 202 struct ieee80211_local *local = sdata->local;
203 struct sk_buff *skb; 203 struct sk_buff *skb;
204 struct ieee80211_mgmt *mgmt; 204 struct ieee80211_mgmt *mgmt;
205 u8 *pos; 205 u8 *pos, qos_info;
206 const u8 *ies; 206 const u8 *ies;
207 size_t offset = 0, noffset; 207 size_t offset = 0, noffset;
208 int i, len, count, rates_len, supp_rates_len; 208 int i, len, count, rates_len, supp_rates_len;
@@ -375,6 +375,14 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
375 } 375 }
376 376
377 if (wk->assoc.wmm_used && local->hw.queues >= 4) { 377 if (wk->assoc.wmm_used && local->hw.queues >= 4) {
378 if (wk->assoc.uapsd_used) {
379 qos_info = local->uapsd_queues;
380 qos_info |= (local->uapsd_max_sp_len <<
381 IEEE80211_WMM_IE_STA_QOSINFO_SP_SHIFT);
382 } else {
383 qos_info = 0;
384 }
385
378 pos = skb_put(skb, 9); 386 pos = skb_put(skb, 9);
379 *pos++ = WLAN_EID_VENDOR_SPECIFIC; 387 *pos++ = WLAN_EID_VENDOR_SPECIFIC;
380 *pos++ = 7; /* len */ 388 *pos++ = 7; /* len */
@@ -384,7 +392,7 @@ static void ieee80211_send_assoc(struct ieee80211_sub_if_data *sdata,
384 *pos++ = 2; /* WME */ 392 *pos++ = 2; /* WME */
385 *pos++ = 0; /* WME info */ 393 *pos++ = 0; /* WME info */
386 *pos++ = 1; /* WME ver */ 394 *pos++ = 1; /* WME ver */
387 *pos++ = 0; 395 *pos++ = qos_info;
388 } 396 }
389 397
390 /* add any remaining custom (i.e. vendor specific here) IEs */ 398 /* add any remaining custom (i.e. vendor specific here) IEs */
@@ -531,9 +539,9 @@ ieee80211_remain_on_channel_timeout(struct ieee80211_work *wk)
531 wk->remain.started = true; 539 wk->remain.started = true;
532 wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration); 540 wk->timeout = jiffies + msecs_to_jiffies(wk->remain.duration);
533 541
534 cfg80211_ready_on_channel(wk->sdata->dev, (u64)wk, wk->chan, 542 cfg80211_ready_on_channel(wk->sdata->dev, (unsigned long) wk,
535 wk->chan_type, wk->remain.duration, 543 wk->chan, wk->chan_type,
536 GFP_KERNEL); 544 wk->remain.duration, GFP_KERNEL);
537 545
538 return WORK_ACT_NONE; 546 return WORK_ACT_NONE;
539 } 547 }
@@ -818,6 +826,7 @@ static void ieee80211_work_work(struct work_struct *work)
818 wk->chan == local->tmp_channel && 826 wk->chan == local->tmp_channel &&
819 wk->chan_type == local->tmp_channel_type) { 827 wk->chan_type == local->tmp_channel_type) {
820 wk->started = true; 828 wk->started = true;
829 wk->timeout = jiffies;
821 } 830 }
822 831
823 if (!wk->started && !local->tmp_channel) { 832 if (!wk->started && !local->tmp_channel) {
@@ -935,6 +944,9 @@ void ieee80211_add_work(struct ieee80211_work *wk)
935 if (WARN_ON(!wk->done)) 944 if (WARN_ON(!wk->done))
936 return; 945 return;
937 946
947 if (WARN_ON(!ieee80211_sdata_running(wk->sdata)))
948 return;
949
938 wk->started = false; 950 wk->started = false;
939 951
940 local = wk->sdata->local; 952 local = wk->sdata->local;
@@ -1027,7 +1039,7 @@ static enum work_done_result ieee80211_remain_done(struct ieee80211_work *wk,
1027 /* 1039 /*
1028 * We are done serving the remain-on-channel command. 1040 * We are done serving the remain-on-channel command.
1029 */ 1041 */
1030 cfg80211_remain_on_channel_expired(wk->sdata->dev, (u64)wk, 1042 cfg80211_remain_on_channel_expired(wk->sdata->dev, (unsigned long) wk,
1031 wk->chan, wk->chan_type, 1043 wk->chan, wk->chan_type,
1032 GFP_KERNEL); 1044 GFP_KERNEL);
1033 1045
@@ -1053,7 +1065,7 @@ int ieee80211_wk_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1053 1065
1054 wk->remain.duration = duration; 1066 wk->remain.duration = duration;
1055 1067
1056 *cookie = (u64)wk; 1068 *cookie = (unsigned long) wk;
1057 1069
1058 ieee80211_add_work(wk); 1070 ieee80211_add_work(wk);
1059 1071
@@ -1069,7 +1081,7 @@ int ieee80211_wk_cancel_remain_on_channel(struct ieee80211_sub_if_data *sdata,
1069 1081
1070 mutex_lock(&local->work_mtx); 1082 mutex_lock(&local->work_mtx);
1071 list_for_each_entry_safe(wk, tmp, &local->work_list, list) { 1083 list_for_each_entry_safe(wk, tmp, &local->work_list, list) {
1072 if ((u64)wk == cookie) { 1084 if ((unsigned long) wk == cookie) {
1073 wk->timeout = jiffies; 1085 wk->timeout = jiffies;
1074 found = true; 1086 found = true;
1075 break; 1087 break;
diff --git a/net/wireless/core.c b/net/wireless/core.c
index c2a2c563d21a..0a545bb6ed05 100644
--- a/net/wireless/core.c
+++ b/net/wireless/core.c
@@ -402,6 +402,7 @@ struct wiphy *wiphy_new(const struct cfg80211_ops *ops, int sizeof_priv)
402 rdev->wiphy.retry_long = 4; 402 rdev->wiphy.retry_long = 4;
403 rdev->wiphy.frag_threshold = (u32) -1; 403 rdev->wiphy.frag_threshold = (u32) -1;
404 rdev->wiphy.rts_threshold = (u32) -1; 404 rdev->wiphy.rts_threshold = (u32) -1;
405 rdev->wiphy.coverage_class = 0;
405 406
406 return &rdev->wiphy; 407 return &rdev->wiphy;
407} 408}
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 30ec95f05b52..2d6a6b9c0c43 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -111,7 +111,8 @@ struct cfg80211_internal_bss {
111 unsigned long ts; 111 unsigned long ts;
112 struct kref ref; 112 struct kref ref;
113 atomic_t hold; 113 atomic_t hold;
114 bool ies_allocated; 114 bool beacon_ies_allocated;
115 bool proberesp_ies_allocated;
115 116
116 /* must be last because of priv member */ 117 /* must be last because of priv member */
117 struct cfg80211_bss pub; 118 struct cfg80211_bss pub;
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index e3bee3cecdfa..4af7991a9ec8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -69,6 +69,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
69 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 }, 69 [NL80211_ATTR_WIPHY_RETRY_LONG] = { .type = NLA_U8 },
70 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 }, 70 [NL80211_ATTR_WIPHY_FRAG_THRESHOLD] = { .type = NLA_U32 },
71 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 }, 71 [NL80211_ATTR_WIPHY_RTS_THRESHOLD] = { .type = NLA_U32 },
72 [NL80211_ATTR_WIPHY_COVERAGE_CLASS] = { .type = NLA_U8 },
72 73
73 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 }, 74 [NL80211_ATTR_IFTYPE] = { .type = NLA_U32 },
74 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 }, 75 [NL80211_ATTR_IFINDEX] = { .type = NLA_U32 },
@@ -143,6 +144,7 @@ static struct nla_policy nl80211_policy[NL80211_ATTR_MAX+1] __read_mostly = {
143 .len = WLAN_PMKID_LEN }, 144 .len = WLAN_PMKID_LEN },
144 [NL80211_ATTR_DURATION] = { .type = NLA_U32 }, 145 [NL80211_ATTR_DURATION] = { .type = NLA_U32 },
145 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 }, 146 [NL80211_ATTR_COOKIE] = { .type = NLA_U64 },
147 [NL80211_ATTR_TX_RATES] = { .type = NLA_NESTED },
146}; 148};
147 149
148/* policy for the attributes */ 150/* policy for the attributes */
@@ -444,6 +446,8 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
444 dev->wiphy.frag_threshold); 446 dev->wiphy.frag_threshold);
445 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD, 447 NLA_PUT_U32(msg, NL80211_ATTR_WIPHY_RTS_THRESHOLD,
446 dev->wiphy.rts_threshold); 448 dev->wiphy.rts_threshold);
449 NLA_PUT_U8(msg, NL80211_ATTR_WIPHY_COVERAGE_CLASS,
450 dev->wiphy.coverage_class);
447 451
448 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS, 452 NLA_PUT_U8(msg, NL80211_ATTR_MAX_NUM_SCAN_SSIDS,
449 dev->wiphy.max_scan_ssids); 453 dev->wiphy.max_scan_ssids);
@@ -572,6 +576,7 @@ static int nl80211_send_wiphy(struct sk_buff *msg, u32 pid, u32 seq, int flags,
572 CMD(del_pmksa, DEL_PMKSA); 576 CMD(del_pmksa, DEL_PMKSA);
573 CMD(flush_pmksa, FLUSH_PMKSA); 577 CMD(flush_pmksa, FLUSH_PMKSA);
574 CMD(remain_on_channel, REMAIN_ON_CHANNEL); 578 CMD(remain_on_channel, REMAIN_ON_CHANNEL);
579 CMD(set_bitrate_mask, SET_TX_BITRATE_MASK);
575 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) { 580 if (dev->wiphy.flags & WIPHY_FLAG_NETNS_OK) {
576 i++; 581 i++;
577 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS); 582 NLA_PUT_U32(msg, i, NL80211_CMD_SET_WIPHY_NETNS);
@@ -684,6 +689,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
684 u32 changed; 689 u32 changed;
685 u8 retry_short = 0, retry_long = 0; 690 u8 retry_short = 0, retry_long = 0;
686 u32 frag_threshold = 0, rts_threshold = 0; 691 u32 frag_threshold = 0, rts_threshold = 0;
692 u8 coverage_class = 0;
687 693
688 rtnl_lock(); 694 rtnl_lock();
689 695
@@ -806,9 +812,16 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
806 changed |= WIPHY_PARAM_RTS_THRESHOLD; 812 changed |= WIPHY_PARAM_RTS_THRESHOLD;
807 } 813 }
808 814
815 if (info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]) {
816 coverage_class = nla_get_u8(
817 info->attrs[NL80211_ATTR_WIPHY_COVERAGE_CLASS]);
818 changed |= WIPHY_PARAM_COVERAGE_CLASS;
819 }
820
809 if (changed) { 821 if (changed) {
810 u8 old_retry_short, old_retry_long; 822 u8 old_retry_short, old_retry_long;
811 u32 old_frag_threshold, old_rts_threshold; 823 u32 old_frag_threshold, old_rts_threshold;
824 u8 old_coverage_class;
812 825
813 if (!rdev->ops->set_wiphy_params) { 826 if (!rdev->ops->set_wiphy_params) {
814 result = -EOPNOTSUPP; 827 result = -EOPNOTSUPP;
@@ -819,6 +832,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
819 old_retry_long = rdev->wiphy.retry_long; 832 old_retry_long = rdev->wiphy.retry_long;
820 old_frag_threshold = rdev->wiphy.frag_threshold; 833 old_frag_threshold = rdev->wiphy.frag_threshold;
821 old_rts_threshold = rdev->wiphy.rts_threshold; 834 old_rts_threshold = rdev->wiphy.rts_threshold;
835 old_coverage_class = rdev->wiphy.coverage_class;
822 836
823 if (changed & WIPHY_PARAM_RETRY_SHORT) 837 if (changed & WIPHY_PARAM_RETRY_SHORT)
824 rdev->wiphy.retry_short = retry_short; 838 rdev->wiphy.retry_short = retry_short;
@@ -828,6 +842,8 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
828 rdev->wiphy.frag_threshold = frag_threshold; 842 rdev->wiphy.frag_threshold = frag_threshold;
829 if (changed & WIPHY_PARAM_RTS_THRESHOLD) 843 if (changed & WIPHY_PARAM_RTS_THRESHOLD)
830 rdev->wiphy.rts_threshold = rts_threshold; 844 rdev->wiphy.rts_threshold = rts_threshold;
845 if (changed & WIPHY_PARAM_COVERAGE_CLASS)
846 rdev->wiphy.coverage_class = coverage_class;
831 847
832 result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed); 848 result = rdev->ops->set_wiphy_params(&rdev->wiphy, changed);
833 if (result) { 849 if (result) {
@@ -835,6 +851,7 @@ static int nl80211_set_wiphy(struct sk_buff *skb, struct genl_info *info)
835 rdev->wiphy.retry_long = old_retry_long; 851 rdev->wiphy.retry_long = old_retry_long;
836 rdev->wiphy.frag_threshold = old_frag_threshold; 852 rdev->wiphy.frag_threshold = old_frag_threshold;
837 rdev->wiphy.rts_threshold = old_rts_threshold; 853 rdev->wiphy.rts_threshold = old_rts_threshold;
854 rdev->wiphy.coverage_class = old_coverage_class;
838 } 855 }
839 } 856 }
840 857
@@ -3146,6 +3163,10 @@ static int nl80211_send_bss(struct sk_buff *msg, u32 pid, u32 seq, int flags,
3146 NLA_PUT(msg, NL80211_BSS_INFORMATION_ELEMENTS, 3163 NLA_PUT(msg, NL80211_BSS_INFORMATION_ELEMENTS,
3147 res->len_information_elements, 3164 res->len_information_elements,
3148 res->information_elements); 3165 res->information_elements);
3166 if (res->beacon_ies && res->len_beacon_ies &&
3167 res->beacon_ies != res->information_elements)
3168 NLA_PUT(msg, NL80211_BSS_BEACON_IES,
3169 res->len_beacon_ies, res->beacon_ies);
3149 if (res->tsf) 3170 if (res->tsf)
3150 NLA_PUT_U64(msg, NL80211_BSS_TSF, res->tsf); 3171 NLA_PUT_U64(msg, NL80211_BSS_TSF, res->tsf);
3151 if (res->beacon_interval) 3172 if (res->beacon_interval)
@@ -4423,6 +4444,109 @@ static int nl80211_cancel_remain_on_channel(struct sk_buff *skb,
4423 return err; 4444 return err;
4424} 4445}
4425 4446
4447static u32 rateset_to_mask(struct ieee80211_supported_band *sband,
4448 u8 *rates, u8 rates_len)
4449{
4450 u8 i;
4451 u32 mask = 0;
4452
4453 for (i = 0; i < rates_len; i++) {
4454 int rate = (rates[i] & 0x7f) * 5;
4455 int ridx;
4456 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
4457 struct ieee80211_rate *srate =
4458 &sband->bitrates[ridx];
4459 if (rate == srate->bitrate) {
4460 mask |= 1 << ridx;
4461 break;
4462 }
4463 }
4464 if (ridx == sband->n_bitrates)
4465 return 0; /* rate not found */
4466 }
4467
4468 return mask;
4469}
4470
4471static struct nla_policy
4472nl80211_txattr_policy[NL80211_TXRATE_MAX + 1] __read_mostly = {
4473 [NL80211_TXRATE_LEGACY] = { .type = NLA_BINARY,
4474 .len = NL80211_MAX_SUPP_RATES },
4475};
4476
4477static int nl80211_set_tx_bitrate_mask(struct sk_buff *skb,
4478 struct genl_info *info)
4479{
4480 struct nlattr *tb[NL80211_TXRATE_MAX + 1];
4481 struct cfg80211_registered_device *rdev;
4482 struct cfg80211_bitrate_mask mask;
4483 int err, rem, i;
4484 struct net_device *dev;
4485 struct nlattr *tx_rates;
4486 struct ieee80211_supported_band *sband;
4487
4488 if (info->attrs[NL80211_ATTR_TX_RATES] == NULL)
4489 return -EINVAL;
4490
4491 rtnl_lock();
4492
4493 err = get_rdev_dev_by_info_ifindex(info, &rdev, &dev);
4494 if (err)
4495 goto unlock_rtnl;
4496
4497 if (!rdev->ops->set_bitrate_mask) {
4498 err = -EOPNOTSUPP;
4499 goto unlock;
4500 }
4501
4502 memset(&mask, 0, sizeof(mask));
4503 /* Default to all rates enabled */
4504 for (i = 0; i < IEEE80211_NUM_BANDS; i++) {
4505 sband = rdev->wiphy.bands[i];
4506 mask.control[i].legacy =
4507 sband ? (1 << sband->n_bitrates) - 1 : 0;
4508 }
4509
4510 /*
4511 * The nested attribute uses enum nl80211_band as the index. This maps
4512 * directly to the enum ieee80211_band values used in cfg80211.
4513 */
4514 nla_for_each_nested(tx_rates, info->attrs[NL80211_ATTR_TX_RATES], rem)
4515 {
4516 enum ieee80211_band band = nla_type(tx_rates);
4517 if (band < 0 || band >= IEEE80211_NUM_BANDS) {
4518 err = -EINVAL;
4519 goto unlock;
4520 }
4521 sband = rdev->wiphy.bands[band];
4522 if (sband == NULL) {
4523 err = -EINVAL;
4524 goto unlock;
4525 }
4526 nla_parse(tb, NL80211_TXRATE_MAX, nla_data(tx_rates),
4527 nla_len(tx_rates), nl80211_txattr_policy);
4528 if (tb[NL80211_TXRATE_LEGACY]) {
4529 mask.control[band].legacy = rateset_to_mask(
4530 sband,
4531 nla_data(tb[NL80211_TXRATE_LEGACY]),
4532 nla_len(tb[NL80211_TXRATE_LEGACY]));
4533 if (mask.control[band].legacy == 0) {
4534 err = -EINVAL;
4535 goto unlock;
4536 }
4537 }
4538 }
4539
4540 err = rdev->ops->set_bitrate_mask(&rdev->wiphy, dev, NULL, &mask);
4541
4542 unlock:
4543 dev_put(dev);
4544 cfg80211_unlock_rdev(rdev);
4545 unlock_rtnl:
4546 rtnl_unlock();
4547 return err;
4548}
4549
4426static struct genl_ops nl80211_ops[] = { 4550static struct genl_ops nl80211_ops[] = {
4427 { 4551 {
4428 .cmd = NL80211_CMD_GET_WIPHY, 4552 .cmd = NL80211_CMD_GET_WIPHY,
@@ -4697,6 +4821,12 @@ static struct genl_ops nl80211_ops[] = {
4697 .policy = nl80211_policy, 4821 .policy = nl80211_policy,
4698 .flags = GENL_ADMIN_PERM, 4822 .flags = GENL_ADMIN_PERM,
4699 }, 4823 },
4824 {
4825 .cmd = NL80211_CMD_SET_TX_BITRATE_MASK,
4826 .doit = nl80211_set_tx_bitrate_mask,
4827 .policy = nl80211_policy,
4828 .flags = GENL_ADMIN_PERM,
4829 },
4700}; 4830};
4701 4831
4702static struct genl_multicast_group nl80211_mlme_mcgrp = { 4832static struct genl_multicast_group nl80211_mlme_mcgrp = {
diff --git a/net/wireless/reg.c b/net/wireless/reg.c
index 87ea60d84c3c..5f8071de7950 100644
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -43,6 +43,15 @@
43#include "regdb.h" 43#include "regdb.h"
44#include "nl80211.h" 44#include "nl80211.h"
45 45
46#ifdef CONFIG_CFG80211_REG_DEBUG
47#define REG_DBG_PRINT(format, args...) \
48 do { \
49 printk(KERN_DEBUG format , ## args); \
50 } while (0)
51#else
52#define REG_DBG_PRINT(args...)
53#endif
54
46/* Receipt of information from last regulatory request */ 55/* Receipt of information from last regulatory request */
47static struct regulatory_request *last_request; 56static struct regulatory_request *last_request;
48 57
@@ -476,12 +485,212 @@ static bool freq_in_rule_band(const struct ieee80211_freq_range *freq_range,
476} 485}
477 486
478/* 487/*
488 * This is a work around for sanity checking ieee80211_channel_to_frequency()'s
489 * work. ieee80211_channel_to_frequency() can for example currently provide a
490 * 2 GHz channel when in fact a 5 GHz channel was desired. An example would be
491 * an AP providing channel 8 on a country IE triplet when it sent this on the
492 * 5 GHz band, that channel is designed to be channel 8 on 5 GHz, not a 2 GHz
493 * channel.
494 *
495 * This can be removed once ieee80211_channel_to_frequency() takes in a band.
496 */
497static bool chan_in_band(int chan, enum ieee80211_band band)
498{
499 int center_freq = ieee80211_channel_to_frequency(chan);
500
501 switch (band) {
502 case IEEE80211_BAND_2GHZ:
503 if (center_freq <= 2484)
504 return true;
505 return false;
506 case IEEE80211_BAND_5GHZ:
507 if (center_freq >= 5005)
508 return true;
509 return false;
510 default:
511 return false;
512 }
513}
514
515/*
516 * Some APs may send a country IE triplet for each channel they
517 * support and while this is completely overkill and silly we still
518 * need to support it. We avoid making a single rule for each channel
519 * though and to help us with this we use this helper to find the
520 * actual subband end channel. These type of country IE triplet
521 * scenerios are handled then, all yielding two regulaotry rules from
522 * parsing a country IE:
523 *
524 * [1]
525 * [2]
526 * [36]
527 * [40]
528 *
529 * [1]
530 * [2-4]
531 * [5-12]
532 * [36]
533 * [40-44]
534 *
535 * [1-4]
536 * [5-7]
537 * [36-44]
538 * [48-64]
539 *
540 * [36-36]
541 * [40-40]
542 * [44-44]
543 * [48-48]
544 * [52-52]
545 * [56-56]
546 * [60-60]
547 * [64-64]
548 * [100-100]
549 * [104-104]
550 * [108-108]
551 * [112-112]
552 * [116-116]
553 * [120-120]
554 * [124-124]
555 * [128-128]
556 * [132-132]
557 * [136-136]
558 * [140-140]
559 *
560 * Returns 0 if the IE has been found to be invalid in the middle
561 * somewhere.
562 */
563static int max_subband_chan(enum ieee80211_band band,
564 int orig_cur_chan,
565 int orig_end_channel,
566 s8 orig_max_power,
567 u8 **country_ie,
568 u8 *country_ie_len)
569{
570 u8 *triplets_start = *country_ie;
571 u8 len_at_triplet = *country_ie_len;
572 int end_subband_chan = orig_end_channel;
573
574 /*
575 * We'll deal with padding for the caller unless
576 * its not immediate and we don't process any channels
577 */
578 if (*country_ie_len == 1) {
579 *country_ie += 1;
580 *country_ie_len -= 1;
581 return orig_end_channel;
582 }
583
584 /* Move to the next triplet and then start search */
585 *country_ie += 3;
586 *country_ie_len -= 3;
587
588 if (!chan_in_band(orig_cur_chan, band))
589 return 0;
590
591 while (*country_ie_len >= 3) {
592 int end_channel = 0;
593 struct ieee80211_country_ie_triplet *triplet =
594 (struct ieee80211_country_ie_triplet *) *country_ie;
595 int cur_channel = 0, next_expected_chan;
596
597 /* means last triplet is completely unrelated to this one */
598 if (triplet->ext.reg_extension_id >=
599 IEEE80211_COUNTRY_EXTENSION_ID) {
600 *country_ie -= 3;
601 *country_ie_len += 3;
602 break;
603 }
604
605 if (triplet->chans.first_channel == 0) {
606 *country_ie += 1;
607 *country_ie_len -= 1;
608 if (*country_ie_len != 0)
609 return 0;
610 break;
611 }
612
613 if (triplet->chans.num_channels == 0)
614 return 0;
615
616 /* Monitonically increasing channel order */
617 if (triplet->chans.first_channel <= end_subband_chan)
618 return 0;
619
620 if (!chan_in_band(triplet->chans.first_channel, band))
621 return 0;
622
623 /* 2 GHz */
624 if (triplet->chans.first_channel <= 14) {
625 end_channel = triplet->chans.first_channel +
626 triplet->chans.num_channels - 1;
627 }
628 else {
629 end_channel = triplet->chans.first_channel +
630 (4 * (triplet->chans.num_channels - 1));
631 }
632
633 if (!chan_in_band(end_channel, band))
634 return 0;
635
636 if (orig_max_power != triplet->chans.max_power) {
637 *country_ie -= 3;
638 *country_ie_len += 3;
639 break;
640 }
641
642 cur_channel = triplet->chans.first_channel;
643
644 /* The key is finding the right next expected channel */
645 if (band == IEEE80211_BAND_2GHZ)
646 next_expected_chan = end_subband_chan + 1;
647 else
648 next_expected_chan = end_subband_chan + 4;
649
650 if (cur_channel != next_expected_chan) {
651 *country_ie -= 3;
652 *country_ie_len += 3;
653 break;
654 }
655
656 end_subband_chan = end_channel;
657
658 /* Move to the next one */
659 *country_ie += 3;
660 *country_ie_len -= 3;
661
662 /*
663 * Padding needs to be dealt with if we processed
664 * some channels.
665 */
666 if (*country_ie_len == 1) {
667 *country_ie += 1;
668 *country_ie_len -= 1;
669 break;
670 }
671
672 /* If seen, the IE is invalid */
673 if (*country_ie_len == 2)
674 return 0;
675 }
676
677 if (end_subband_chan == orig_end_channel) {
678 *country_ie = triplets_start;
679 *country_ie_len = len_at_triplet;
680 return orig_end_channel;
681 }
682
683 return end_subband_chan;
684}
685
686/*
479 * Converts a country IE to a regulatory domain. A regulatory domain 687 * Converts a country IE to a regulatory domain. A regulatory domain
480 * structure has a lot of information which the IE doesn't yet have, 688 * structure has a lot of information which the IE doesn't yet have,
481 * so for the other values we use upper max values as we will intersect 689 * so for the other values we use upper max values as we will intersect
482 * with our userspace regulatory agent to get lower bounds. 690 * with our userspace regulatory agent to get lower bounds.
483 */ 691 */
484static struct ieee80211_regdomain *country_ie_2_rd( 692static struct ieee80211_regdomain *country_ie_2_rd(
693 enum ieee80211_band band,
485 u8 *country_ie, 694 u8 *country_ie,
486 u8 country_ie_len, 695 u8 country_ie_len,
487 u32 *checksum) 696 u32 *checksum)
@@ -543,10 +752,29 @@ static struct ieee80211_regdomain *country_ie_2_rd(
543 continue; 752 continue;
544 } 753 }
545 754
755 /*
756 * APs can add padding to make length divisible
757 * by two, required by the spec.
758 */
759 if (triplet->chans.first_channel == 0) {
760 country_ie++;
761 country_ie_len--;
762 /* This is expected to be at the very end only */
763 if (country_ie_len != 0)
764 return NULL;
765 break;
766 }
767
768 if (triplet->chans.num_channels == 0)
769 return NULL;
770
771 if (!chan_in_band(triplet->chans.first_channel, band))
772 return NULL;
773
546 /* 2 GHz */ 774 /* 2 GHz */
547 if (triplet->chans.first_channel <= 14) 775 if (band == IEEE80211_BAND_2GHZ)
548 end_channel = triplet->chans.first_channel + 776 end_channel = triplet->chans.first_channel +
549 triplet->chans.num_channels; 777 triplet->chans.num_channels - 1;
550 else 778 else
551 /* 779 /*
552 * 5 GHz -- For example in country IEs if the first 780 * 5 GHz -- For example in country IEs if the first
@@ -561,6 +789,24 @@ static struct ieee80211_regdomain *country_ie_2_rd(
561 (4 * (triplet->chans.num_channels - 1)); 789 (4 * (triplet->chans.num_channels - 1));
562 790
563 cur_channel = triplet->chans.first_channel; 791 cur_channel = triplet->chans.first_channel;
792
793 /*
794 * Enhancement for APs that send a triplet for every channel
795 * or for whatever reason sends triplets with multiple channels
796 * separated when in fact they should be together.
797 */
798 end_channel = max_subband_chan(band,
799 cur_channel,
800 end_channel,
801 triplet->chans.max_power,
802 &country_ie,
803 &country_ie_len);
804 if (!end_channel)
805 return NULL;
806
807 if (!chan_in_band(end_channel, band))
808 return NULL;
809
564 cur_sub_max_channel = end_channel; 810 cur_sub_max_channel = end_channel;
565 811
566 /* Basic sanity check */ 812 /* Basic sanity check */
@@ -591,10 +837,13 @@ static struct ieee80211_regdomain *country_ie_2_rd(
591 837
592 last_sub_max_channel = cur_sub_max_channel; 838 last_sub_max_channel = cur_sub_max_channel;
593 839
594 country_ie += 3;
595 country_ie_len -= 3;
596 num_rules++; 840 num_rules++;
597 841
842 if (country_ie_len >= 3) {
843 country_ie += 3;
844 country_ie_len -= 3;
845 }
846
598 /* 847 /*
599 * Note: this is not a IEEE requirement but 848 * Note: this is not a IEEE requirement but
600 * simply a memory requirement 849 * simply a memory requirement
@@ -637,6 +886,12 @@ static struct ieee80211_regdomain *country_ie_2_rd(
637 continue; 886 continue;
638 } 887 }
639 888
889 if (triplet->chans.first_channel == 0) {
890 country_ie++;
891 country_ie_len--;
892 break;
893 }
894
640 reg_rule = &rd->reg_rules[i]; 895 reg_rule = &rd->reg_rules[i];
641 freq_range = &reg_rule->freq_range; 896 freq_range = &reg_rule->freq_range;
642 power_rule = &reg_rule->power_rule; 897 power_rule = &reg_rule->power_rule;
@@ -644,13 +899,20 @@ static struct ieee80211_regdomain *country_ie_2_rd(
644 reg_rule->flags = flags; 899 reg_rule->flags = flags;
645 900
646 /* 2 GHz */ 901 /* 2 GHz */
647 if (triplet->chans.first_channel <= 14) 902 if (band == IEEE80211_BAND_2GHZ)
648 end_channel = triplet->chans.first_channel + 903 end_channel = triplet->chans.first_channel +
649 triplet->chans.num_channels; 904 triplet->chans.num_channels -1;
650 else 905 else
651 end_channel = triplet->chans.first_channel + 906 end_channel = triplet->chans.first_channel +
652 (4 * (triplet->chans.num_channels - 1)); 907 (4 * (triplet->chans.num_channels - 1));
653 908
909 end_channel = max_subband_chan(band,
910 triplet->chans.first_channel,
911 end_channel,
912 triplet->chans.max_power,
913 &country_ie,
914 &country_ie_len);
915
654 /* 916 /*
655 * The +10 is since the regulatory domain expects 917 * The +10 is since the regulatory domain expects
656 * the actual band edge, not the center of freq for 918 * the actual band edge, not the center of freq for
@@ -671,12 +933,15 @@ static struct ieee80211_regdomain *country_ie_2_rd(
671 */ 933 */
672 freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40); 934 freq_range->max_bandwidth_khz = MHZ_TO_KHZ(40);
673 power_rule->max_antenna_gain = DBI_TO_MBI(100); 935 power_rule->max_antenna_gain = DBI_TO_MBI(100);
674 power_rule->max_eirp = DBM_TO_MBM(100); 936 power_rule->max_eirp = DBM_TO_MBM(triplet->chans.max_power);
675 937
676 country_ie += 3;
677 country_ie_len -= 3;
678 i++; 938 i++;
679 939
940 if (country_ie_len >= 3) {
941 country_ie += 3;
942 country_ie_len -= 3;
943 }
944
680 BUG_ON(i > NL80211_MAX_SUPP_REG_RULES); 945 BUG_ON(i > NL80211_MAX_SUPP_REG_RULES);
681 } 946 }
682 947
@@ -972,25 +1237,21 @@ static void handle_channel(struct wiphy *wiphy, enum ieee80211_band band,
972 if (r == -ERANGE && 1237 if (r == -ERANGE &&
973 last_request->initiator == 1238 last_request->initiator ==
974 NL80211_REGDOM_SET_BY_COUNTRY_IE) { 1239 NL80211_REGDOM_SET_BY_COUNTRY_IE) {
975#ifdef CONFIG_CFG80211_REG_DEBUG 1240 REG_DBG_PRINT("cfg80211: Leaving channel %d MHz "
976 printk(KERN_DEBUG "cfg80211: Leaving channel %d MHz "
977 "intact on %s - no rule found in band on " 1241 "intact on %s - no rule found in band on "
978 "Country IE\n", 1242 "Country IE\n",
979 chan->center_freq, wiphy_name(wiphy)); 1243 chan->center_freq, wiphy_name(wiphy));
980#endif
981 } else { 1244 } else {
982 /* 1245 /*
983 * In this case we know the country IE has at least one reg rule 1246 * In this case we know the country IE has at least one reg rule
984 * for the band so we respect its band definitions 1247 * for the band so we respect its band definitions
985 */ 1248 */
986#ifdef CONFIG_CFG80211_REG_DEBUG
987 if (last_request->initiator == 1249 if (last_request->initiator ==
988 NL80211_REGDOM_SET_BY_COUNTRY_IE) 1250 NL80211_REGDOM_SET_BY_COUNTRY_IE)
989 printk(KERN_DEBUG "cfg80211: Disabling " 1251 REG_DBG_PRINT("cfg80211: Disabling "
990 "channel %d MHz on %s due to " 1252 "channel %d MHz on %s due to "
991 "Country IE\n", 1253 "Country IE\n",
992 chan->center_freq, wiphy_name(wiphy)); 1254 chan->center_freq, wiphy_name(wiphy));
993#endif
994 flags |= IEEE80211_CHAN_DISABLED; 1255 flags |= IEEE80211_CHAN_DISABLED;
995 chan->flags = flags; 1256 chan->flags = flags;
996 } 1257 }
@@ -1685,7 +1946,7 @@ int regulatory_hint_user(const char *alpha2)
1685 request->wiphy_idx = WIPHY_IDX_STALE; 1946 request->wiphy_idx = WIPHY_IDX_STALE;
1686 request->alpha2[0] = alpha2[0]; 1947 request->alpha2[0] = alpha2[0];
1687 request->alpha2[1] = alpha2[1]; 1948 request->alpha2[1] = alpha2[1];
1688 request->initiator = NL80211_REGDOM_SET_BY_USER, 1949 request->initiator = NL80211_REGDOM_SET_BY_USER;
1689 1950
1690 queue_regulatory_request(request); 1951 queue_regulatory_request(request);
1691 1952
@@ -1753,8 +2014,9 @@ static bool reg_same_country_ie_hint(struct wiphy *wiphy,
1753 * therefore cannot iterate over the rdev list here. 2014 * therefore cannot iterate over the rdev list here.
1754 */ 2015 */
1755void regulatory_hint_11d(struct wiphy *wiphy, 2016void regulatory_hint_11d(struct wiphy *wiphy,
1756 u8 *country_ie, 2017 enum ieee80211_band band,
1757 u8 country_ie_len) 2018 u8 *country_ie,
2019 u8 country_ie_len)
1758{ 2020{
1759 struct ieee80211_regdomain *rd = NULL; 2021 struct ieee80211_regdomain *rd = NULL;
1760 char alpha2[2]; 2022 char alpha2[2];
@@ -1800,9 +2062,11 @@ void regulatory_hint_11d(struct wiphy *wiphy,
1800 wiphy_idx_valid(last_request->wiphy_idx))) 2062 wiphy_idx_valid(last_request->wiphy_idx)))
1801 goto out; 2063 goto out;
1802 2064
1803 rd = country_ie_2_rd(country_ie, country_ie_len, &checksum); 2065 rd = country_ie_2_rd(band, country_ie, country_ie_len, &checksum);
1804 if (!rd) 2066 if (!rd) {
2067 REG_DBG_PRINT("cfg80211: Ignoring bogus country IE\n");
1805 goto out; 2068 goto out;
2069 }
1806 2070
1807 /* 2071 /*
1808 * This will not happen right now but we leave it here for the 2072 * This will not happen right now but we leave it here for the
@@ -1870,13 +2134,12 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
1870 if (!reg_beacon) 2134 if (!reg_beacon)
1871 return -ENOMEM; 2135 return -ENOMEM;
1872 2136
1873#ifdef CONFIG_CFG80211_REG_DEBUG 2137 REG_DBG_PRINT("cfg80211: Found new beacon on "
1874 printk(KERN_DEBUG "cfg80211: Found new beacon on " 2138 "frequency: %d MHz (Ch %d) on %s\n",
1875 "frequency: %d MHz (Ch %d) on %s\n", 2139 beacon_chan->center_freq,
1876 beacon_chan->center_freq, 2140 ieee80211_frequency_to_channel(beacon_chan->center_freq),
1877 ieee80211_frequency_to_channel(beacon_chan->center_freq), 2141 wiphy_name(wiphy));
1878 wiphy_name(wiphy)); 2142
1879#endif
1880 memcpy(&reg_beacon->chan, beacon_chan, 2143 memcpy(&reg_beacon->chan, beacon_chan,
1881 sizeof(struct ieee80211_channel)); 2144 sizeof(struct ieee80211_channel));
1882 2145
diff --git a/net/wireless/reg.h b/net/wireless/reg.h
index 3362c7c069b2..3018508226ab 100644
--- a/net/wireless/reg.h
+++ b/net/wireless/reg.h
@@ -41,14 +41,25 @@ int regulatory_hint_found_beacon(struct wiphy *wiphy,
41 * regulatory_hint_11d - hints a country IE as a regulatory domain 41 * regulatory_hint_11d - hints a country IE as a regulatory domain
42 * @wiphy: the wireless device giving the hint (used only for reporting 42 * @wiphy: the wireless device giving the hint (used only for reporting
43 * conflicts) 43 * conflicts)
44 * @band: the band on which the country IE was received on. This determines
45 * the band we'll process the country IE channel triplets for.
44 * @country_ie: pointer to the country IE 46 * @country_ie: pointer to the country IE
45 * @country_ie_len: length of the country IE 47 * @country_ie_len: length of the country IE
46 * 48 *
47 * We will intersect the rd with the what CRDA tells us should apply 49 * We will intersect the rd with the what CRDA tells us should apply
48 * for the alpha2 this country IE belongs to, this prevents APs from 50 * for the alpha2 this country IE belongs to, this prevents APs from
49 * sending us incorrect or outdated information against a country. 51 * sending us incorrect or outdated information against a country.
52 *
53 * The AP is expected to provide Country IE channel triplets for the
54 * band it is on. It is technically possible for APs to send channel
55 * country IE triplets even for channels outside of the band they are
56 * in but for that they would have to use the regulatory extension
57 * in combination with a triplet but this behaviour is currently
58 * not observed. For this reason if a triplet is seen with channel
59 * information for a band the BSS is not present in it will be ignored.
50 */ 60 */
51void regulatory_hint_11d(struct wiphy *wiphy, 61void regulatory_hint_11d(struct wiphy *wiphy,
62 enum ieee80211_band band,
52 u8 *country_ie, 63 u8 *country_ie,
53 u8 country_ie_len); 64 u8 country_ie_len);
54 65
diff --git a/net/wireless/scan.c b/net/wireless/scan.c
index 0c2cbbebca95..06b0231ee5e3 100644
--- a/net/wireless/scan.c
+++ b/net/wireless/scan.c
@@ -100,8 +100,10 @@ static void bss_release(struct kref *ref)
100 if (bss->pub.free_priv) 100 if (bss->pub.free_priv)
101 bss->pub.free_priv(&bss->pub); 101 bss->pub.free_priv(&bss->pub);
102 102
103 if (bss->ies_allocated) 103 if (bss->beacon_ies_allocated)
104 kfree(bss->pub.information_elements); 104 kfree(bss->pub.beacon_ies);
105 if (bss->proberesp_ies_allocated)
106 kfree(bss->pub.proberesp_ies);
105 107
106 BUG_ON(atomic_read(&bss->hold)); 108 BUG_ON(atomic_read(&bss->hold));
107 109
@@ -375,8 +377,7 @@ rb_find_bss(struct cfg80211_registered_device *dev,
375 377
376static struct cfg80211_internal_bss * 378static struct cfg80211_internal_bss *
377cfg80211_bss_update(struct cfg80211_registered_device *dev, 379cfg80211_bss_update(struct cfg80211_registered_device *dev,
378 struct cfg80211_internal_bss *res, 380 struct cfg80211_internal_bss *res)
379 bool overwrite)
380{ 381{
381 struct cfg80211_internal_bss *found = NULL; 382 struct cfg80211_internal_bss *found = NULL;
382 const u8 *meshid, *meshcfg; 383 const u8 *meshid, *meshcfg;
@@ -418,28 +419,64 @@ cfg80211_bss_update(struct cfg80211_registered_device *dev,
418 found->pub.capability = res->pub.capability; 419 found->pub.capability = res->pub.capability;
419 found->ts = res->ts; 420 found->ts = res->ts;
420 421
421 /* overwrite IEs */ 422 /* Update IEs */
422 if (overwrite) { 423 if (res->pub.proberesp_ies) {
423 size_t used = dev->wiphy.bss_priv_size + sizeof(*res); 424 size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
424 size_t ielen = res->pub.len_information_elements; 425 size_t ielen = res->pub.len_proberesp_ies;
426
427 if (found->pub.proberesp_ies &&
428 !found->proberesp_ies_allocated &&
429 ksize(found) >= used + ielen) {
430 memcpy(found->pub.proberesp_ies,
431 res->pub.proberesp_ies, ielen);
432 found->pub.len_proberesp_ies = ielen;
433 } else {
434 u8 *ies = found->pub.proberesp_ies;
435
436 if (found->proberesp_ies_allocated)
437 ies = krealloc(ies, ielen, GFP_ATOMIC);
438 else
439 ies = kmalloc(ielen, GFP_ATOMIC);
440
441 if (ies) {
442 memcpy(ies, res->pub.proberesp_ies,
443 ielen);
444 found->proberesp_ies_allocated = true;
445 found->pub.proberesp_ies = ies;
446 found->pub.len_proberesp_ies = ielen;
447 }
448 }
425 449
426 if (!found->ies_allocated && ksize(found) >= used + ielen) { 450 /* Override possible earlier Beacon frame IEs */
427 memcpy(found->pub.information_elements, 451 found->pub.information_elements =
428 res->pub.information_elements, ielen); 452 found->pub.proberesp_ies;
429 found->pub.len_information_elements = ielen; 453 found->pub.len_information_elements =
454 found->pub.len_proberesp_ies;
455 }
456 if (res->pub.beacon_ies) {
457 size_t used = dev->wiphy.bss_priv_size + sizeof(*res);
458 size_t ielen = res->pub.len_beacon_ies;
459
460 if (found->pub.beacon_ies &&
461 !found->beacon_ies_allocated &&
462 ksize(found) >= used + ielen) {
463 memcpy(found->pub.beacon_ies,
464 res->pub.beacon_ies, ielen);
465 found->pub.len_beacon_ies = ielen;
430 } else { 466 } else {
431 u8 *ies = found->pub.information_elements; 467 u8 *ies = found->pub.beacon_ies;
432 468
433 if (found->ies_allocated) 469 if (found->beacon_ies_allocated)
434 ies = krealloc(ies, ielen, GFP_ATOMIC); 470 ies = krealloc(ies, ielen, GFP_ATOMIC);
435 else 471 else
436 ies = kmalloc(ielen, GFP_ATOMIC); 472 ies = kmalloc(ielen, GFP_ATOMIC);
437 473
438 if (ies) { 474 if (ies) {
439 memcpy(ies, res->pub.information_elements, ielen); 475 memcpy(ies, res->pub.beacon_ies,
440 found->ies_allocated = true; 476 ielen);
441 found->pub.information_elements = ies; 477 found->beacon_ies_allocated = true;
442 found->pub.len_information_elements = ielen; 478 found->pub.beacon_ies = ies;
479 found->pub.len_beacon_ies = ielen;
443 } 480 }
444 } 481 }
445 } 482 }
@@ -489,14 +526,26 @@ cfg80211_inform_bss(struct wiphy *wiphy,
489 res->pub.tsf = timestamp; 526 res->pub.tsf = timestamp;
490 res->pub.beacon_interval = beacon_interval; 527 res->pub.beacon_interval = beacon_interval;
491 res->pub.capability = capability; 528 res->pub.capability = capability;
492 /* point to after the private area */ 529 /*
493 res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz; 530 * Since we do not know here whether the IEs are from a Beacon or Probe
494 memcpy(res->pub.information_elements, ie, ielen); 531 * Response frame, we need to pick one of the options and only use it
495 res->pub.len_information_elements = ielen; 532 * with the driver that does not provide the full Beacon/Probe Response
533 * frame. Use Beacon frame pointer to avoid indicating that this should
534 * override the information_elements pointer should we have received an
535 * earlier indication of Probe Response data.
536 *
537 * The initial buffer for the IEs is allocated with the BSS entry and
538 * is located after the private area.
539 */
540 res->pub.beacon_ies = (u8 *)res + sizeof(*res) + privsz;
541 memcpy(res->pub.beacon_ies, ie, ielen);
542 res->pub.len_beacon_ies = ielen;
543 res->pub.information_elements = res->pub.beacon_ies;
544 res->pub.len_information_elements = res->pub.len_beacon_ies;
496 545
497 kref_init(&res->ref); 546 kref_init(&res->ref);
498 547
499 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, 0); 548 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res);
500 if (!res) 549 if (!res)
501 return NULL; 550 return NULL;
502 551
@@ -517,7 +566,6 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
517 struct cfg80211_internal_bss *res; 566 struct cfg80211_internal_bss *res;
518 size_t ielen = len - offsetof(struct ieee80211_mgmt, 567 size_t ielen = len - offsetof(struct ieee80211_mgmt,
519 u.probe_resp.variable); 568 u.probe_resp.variable);
520 bool overwrite;
521 size_t privsz = wiphy->bss_priv_size; 569 size_t privsz = wiphy->bss_priv_size;
522 570
523 if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC && 571 if (WARN_ON(wiphy->signal_type == NL80211_BSS_SIGNAL_UNSPEC &&
@@ -538,16 +586,28 @@ cfg80211_inform_bss_frame(struct wiphy *wiphy,
538 res->pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp); 586 res->pub.tsf = le64_to_cpu(mgmt->u.probe_resp.timestamp);
539 res->pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int); 587 res->pub.beacon_interval = le16_to_cpu(mgmt->u.probe_resp.beacon_int);
540 res->pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info); 588 res->pub.capability = le16_to_cpu(mgmt->u.probe_resp.capab_info);
541 /* point to after the private area */ 589 /*
542 res->pub.information_elements = (u8 *)res + sizeof(*res) + privsz; 590 * The initial buffer for the IEs is allocated with the BSS entry and
543 memcpy(res->pub.information_elements, mgmt->u.probe_resp.variable, ielen); 591 * is located after the private area.
544 res->pub.len_information_elements = ielen; 592 */
593 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
594 res->pub.proberesp_ies = (u8 *) res + sizeof(*res) + privsz;
595 memcpy(res->pub.proberesp_ies, mgmt->u.probe_resp.variable,
596 ielen);
597 res->pub.len_proberesp_ies = ielen;
598 res->pub.information_elements = res->pub.proberesp_ies;
599 res->pub.len_information_elements = res->pub.len_proberesp_ies;
600 } else {
601 res->pub.beacon_ies = (u8 *) res + sizeof(*res) + privsz;
602 memcpy(res->pub.beacon_ies, mgmt->u.beacon.variable, ielen);
603 res->pub.len_beacon_ies = ielen;
604 res->pub.information_elements = res->pub.beacon_ies;
605 res->pub.len_information_elements = res->pub.len_beacon_ies;
606 }
545 607
546 kref_init(&res->ref); 608 kref_init(&res->ref);
547 609
548 overwrite = ieee80211_is_probe_resp(mgmt->frame_control); 610 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res);
549
550 res = cfg80211_bss_update(wiphy_to_dev(wiphy), res, overwrite);
551 if (!res) 611 if (!res)
552 return NULL; 612 return NULL;
553 613
diff --git a/net/wireless/sme.c b/net/wireless/sme.c
index 2333d78187e4..2ce5e1609a3d 100644
--- a/net/wireless/sme.c
+++ b/net/wireless/sme.c
@@ -454,6 +454,7 @@ void __cfg80211_connect_result(struct net_device *dev, const u8 *bssid,
454 * - and country_ie[1] which is the IE length 454 * - and country_ie[1] which is the IE length
455 */ 455 */
456 regulatory_hint_11d(wdev->wiphy, 456 regulatory_hint_11d(wdev->wiphy,
457 bss->channel->band,
457 country_ie + 2, 458 country_ie + 2,
458 country_ie[1]); 459 country_ie[1]);
459} 460}
diff --git a/net/wireless/wext-compat.c b/net/wireless/wext-compat.c
index 4198243a3dff..966d2f01beac 100644
--- a/net/wireless/wext-compat.c
+++ b/net/wireless/wext-compat.c
@@ -1204,21 +1204,47 @@ int cfg80211_wext_siwrate(struct net_device *dev,
1204 struct wireless_dev *wdev = dev->ieee80211_ptr; 1204 struct wireless_dev *wdev = dev->ieee80211_ptr;
1205 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy); 1205 struct cfg80211_registered_device *rdev = wiphy_to_dev(wdev->wiphy);
1206 struct cfg80211_bitrate_mask mask; 1206 struct cfg80211_bitrate_mask mask;
1207 u32 fixed, maxrate;
1208 struct ieee80211_supported_band *sband;
1209 int band, ridx;
1210 bool match = false;
1207 1211
1208 if (!rdev->ops->set_bitrate_mask) 1212 if (!rdev->ops->set_bitrate_mask)
1209 return -EOPNOTSUPP; 1213 return -EOPNOTSUPP;
1210 1214
1211 mask.fixed = 0; 1215 memset(&mask, 0, sizeof(mask));
1212 mask.maxrate = 0; 1216 fixed = 0;
1217 maxrate = 0;
1213 1218
1214 if (rate->value < 0) { 1219 if (rate->value < 0) {
1215 /* nothing */ 1220 /* nothing */
1216 } else if (rate->fixed) { 1221 } else if (rate->fixed) {
1217 mask.fixed = rate->value / 1000; /* kbps */ 1222 fixed = rate->value / 100000;
1218 } else { 1223 } else {
1219 mask.maxrate = rate->value / 1000; /* kbps */ 1224 maxrate = rate->value / 100000;
1225 }
1226
1227 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
1228 sband = wdev->wiphy->bands[band];
1229 if (sband == NULL)
1230 continue;
1231 for (ridx = 0; ridx < sband->n_bitrates; ridx++) {
1232 struct ieee80211_rate *srate = &sband->bitrates[ridx];
1233 if (fixed == srate->bitrate) {
1234 mask.control[band].legacy = 1 << ridx;
1235 match = true;
1236 break;
1237 }
1238 if (srate->bitrate <= maxrate) {
1239 mask.control[band].legacy |= 1 << ridx;
1240 match = true;
1241 }
1242 }
1220 } 1243 }
1221 1244
1245 if (!match)
1246 return -EINVAL;
1247
1222 return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask); 1248 return rdev->ops->set_bitrate_mask(wdev->wiphy, dev, NULL, &mask);
1223} 1249}
1224EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate); 1250EXPORT_SYMBOL_GPL(cfg80211_wext_siwrate);