aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
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 /drivers/net/wireless
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
Diffstat (limited to 'drivers/net/wireless')
-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
54 files changed, 5619 insertions, 2388 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 6a2a9676111..66bcb506a11 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 72e5ed51c0a..5577bcc80ea 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 5d1c8677f18..6a3f4da7fb4 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 0123f3521a0..473a483bb9c 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 64fc1eb9b6d..aefe84f9c04 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 eeebb9aef20..abe36c0d139 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 62954fc7786..6690923fd78 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 03a1106ad72..5774cea23a3 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 4985b2b1b0a..6b50d5eb9ec 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 329e6bc137a..9e62a569e81 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 9f1f523e02e..bf3d4c4bfa5 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 1660ef17aaf..422454fe4ff 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 592f1b70f55..9489b6b25b5 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 536663e3ee1..86780e68b31 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 00000000000..e204bd25ff6
--- /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 9474f9f6d40..0b1dd10f1d8 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 8849450dc59..ab1f1981d85 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 00000000000..5f78d7a5ff2
--- /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 e185479e295..29851e6376a 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 79fbbda1549..c0c571c2e8c 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 ee617205cb4..fe2c3a644a6 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 477365e5ae6..40b5d05edcc 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 cd26caaf44e..a43fbf84dab 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 fa12b9060b0..a821bb687b3 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 2f12a750bc9..54d6085a887 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 60290c06e95..9c5c7c9ad53 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 3e046ec1ff8..b58d6cf2658 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 992318a7807..4a817e3da16 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 1749aef4147..4572866756f 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 4e233631554..7dff853ab96 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 4d498b053ec..51636d02f8b 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 fbae264095c..874a64a6c61 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 78706ce8b7a..cee368d4859 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 ec6b27689fa..c3f8ec0a38b 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 c8fec626b71..344e99de4ca 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 28f3800c560..3320cce3d57 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 3ef86f6c775..8deb83bfe18 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 ee5aed12a4b..4a2ac9311ba 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 30e9ea6d54e..87d684efe11 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 842811142be..79ffa3b98d7 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 c1c6ecd0c5b..68546ca0ba3 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 8ff7db85328..529a37364eb 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 535ce22f2ac..ebabeae62d1 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 99095e1ee13..d64181cbc9c 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 0510f020dcf..82755cf8b73 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 b4c6e0a6d7e..096da85a66f 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 d7711e4d475..b93731b7990 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 3d8fb684b4e..0b4801a1460 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 770f260726b..0320b478bb3 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 dff798ad0ef..4ad67cae94d 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 4e373f3dbc4..595f0f94d16 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 1f237389d1c..99096077152 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 02978a16e73..ee9564aa6ec 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 709fe5e06f7..2d555cc3050 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