aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2008-08-04 03:16:41 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-08-07 09:49:42 -0400
commitf078f209704849c86bd43c0beccfc1f410ed1c66 (patch)
tree9b965db2c86e7369002a05808f6b418c8a9aa985
parentb1a5215004130689aeee9e522585c879d3b71472 (diff)
ath9k: Add new Atheros IEEE 802.11n driver
This adds the new mac80211 11n ath9k Atheros driver. Only STA support is currently enabled and tested. Signed-off-by: Senthil Balasubramanian <senthilkumar@atheros.com> Signed-off-by: Felix Fietkau <nbd@openwrt.org> Signed-off-by: Jack Howarth <howarth@bromo.msbb.uc.edu> Signed-off-by: Jouni Malinen <jouni.malinen@atheros.com> Signed-off-by: Sujith Manoharan <Sujith.Manoharan@atheros.com> Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: Pavel Roskin <proski@gnu.org> Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--MAINTAINERS9
-rw-r--r--drivers/net/wireless/Kconfig1
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/ath9k/Kconfig8
-rw-r--r--drivers/net/wireless/ath9k/Makefile11
-rw-r--r--drivers/net/wireless/ath9k/ath9k.h1066
-rw-r--r--drivers/net/wireless/ath9k/beacon.c977
-rw-r--r--drivers/net/wireless/ath9k/core.c1961
-rw-r--r--drivers/net/wireless/ath9k/core.h1097
-rw-r--r--drivers/net/wireless/ath9k/hw.c8563
-rw-r--r--drivers/net/wireless/ath9k/hw.h969
-rw-r--r--drivers/net/wireless/ath9k/initvals.h3146
-rw-r--r--drivers/net/wireless/ath9k/main.c1533
-rw-r--r--drivers/net/wireless/ath9k/phy.c436
-rw-r--r--drivers/net/wireless/ath9k/phy.h543
-rw-r--r--drivers/net/wireless/ath9k/rc.c2126
-rw-r--r--drivers/net/wireless/ath9k/rc.h316
-rw-r--r--drivers/net/wireless/ath9k/recv.c1318
-rw-r--r--drivers/net/wireless/ath9k/reg.h1385
-rw-r--r--drivers/net/wireless/ath9k/regd.c1031
-rw-r--r--drivers/net/wireless/ath9k/regd.h412
-rw-r--r--drivers/net/wireless/ath9k/regd_common.h1915
-rw-r--r--drivers/net/wireless/ath9k/xmit.c2870
23 files changed, 31694 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index 8223a521d7c3..c67a402a6857 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -720,6 +720,15 @@ L: linux-wireless@vger.kernel.org
720L: ath5k-devel@lists.ath5k.org 720L: ath5k-devel@lists.ath5k.org
721S: Maintained 721S: Maintained
722 722
723ATHEROS ATH9K WIRELESS DRIVER
724P: Luis R. Rodriguez
725M: lrodriguez@atheros.com
726P: Jouni Malinen
727M: jmalinen@atheros.com
728L: linux-wireless@vger.kernel.org
729L: ath9k-devel@lists.ath9k.org
730S: Supported
731
723ATI_REMOTE2 DRIVER 732ATI_REMOTE2 DRIVER
724P: Ville Syrjala 733P: Ville Syrjala
725M: syrjala@sci.fi 734M: syrjala@sci.fi
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 4c7ff61a1a9c..9931b5ab59cd 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -695,6 +695,7 @@ config MAC80211_HWSIM
695 695
696source "drivers/net/wireless/p54/Kconfig" 696source "drivers/net/wireless/p54/Kconfig"
697source "drivers/net/wireless/ath5k/Kconfig" 697source "drivers/net/wireless/ath5k/Kconfig"
698source "drivers/net/wireless/ath9k/Kconfig"
698source "drivers/net/wireless/iwlwifi/Kconfig" 699source "drivers/net/wireless/iwlwifi/Kconfig"
699source "drivers/net/wireless/hostap/Kconfig" 700source "drivers/net/wireless/hostap/Kconfig"
700source "drivers/net/wireless/b43/Kconfig" 701source "drivers/net/wireless/b43/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 54a4f6f1db67..59aa89ec6e81 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -62,5 +62,6 @@ obj-$(CONFIG_RT2X00) += rt2x00/
62obj-$(CONFIG_P54_COMMON) += p54/ 62obj-$(CONFIG_P54_COMMON) += p54/
63 63
64obj-$(CONFIG_ATH5K) += ath5k/ 64obj-$(CONFIG_ATH5K) += ath5k/
65obj-$(CONFIG_ATH9K) += ath9k/
65 66
66obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o 67obj-$(CONFIG_MAC80211_HWSIM) += mac80211_hwsim.o
diff --git a/drivers/net/wireless/ath9k/Kconfig b/drivers/net/wireless/ath9k/Kconfig
new file mode 100644
index 000000000000..9e19dcceb3a2
--- /dev/null
+++ b/drivers/net/wireless/ath9k/Kconfig
@@ -0,0 +1,8 @@
1config ATH9K
2 tristate "Atheros 802.11n wireless cards support"
3 depends on PCI && MAC80211 && WLAN_80211
4 ---help---
5 This module adds support for wireless adapters based on
6 Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
7
8 If you choose to build a module, it'll be called ath9k.
diff --git a/drivers/net/wireless/ath9k/Makefile b/drivers/net/wireless/ath9k/Makefile
new file mode 100644
index 000000000000..a6411517e5f8
--- /dev/null
+++ b/drivers/net/wireless/ath9k/Makefile
@@ -0,0 +1,11 @@
1ath9k-y += hw.o \
2 phy.o \
3 regd.o \
4 beacon.o \
5 main.o \
6 recv.o \
7 xmit.o \
8 rc.o \
9 core.o
10
11obj-$(CONFIG_ATH9K) += ath9k.o
diff --git a/drivers/net/wireless/ath9k/ath9k.h b/drivers/net/wireless/ath9k/ath9k.h
new file mode 100644
index 000000000000..dc1da64d2d7c
--- /dev/null
+++ b/drivers/net/wireless/ath9k/ath9k.h
@@ -0,0 +1,1066 @@
1/*
2 * Copyright (c) 2008 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#ifndef ATH9K_H
18#define ATH9K_H
19
20#include <linux/io.h>
21
22#define ATHEROS_VENDOR_ID 0x168c
23
24#define AR5416_DEVID_PCI 0x0023
25#define AR5416_DEVID_PCIE 0x0024
26#define AR9160_DEVID_PCI 0x0027
27#define AR9280_DEVID_PCI 0x0029
28#define AR9280_DEVID_PCIE 0x002a
29
30#define AR5416_AR9100_DEVID 0x000b
31
32#define AR_SUBVENDOR_ID_NOG 0x0e11
33#define AR_SUBVENDOR_ID_NEW_A 0x7065
34
35#define ATH9K_TXERR_XRETRY 0x01
36#define ATH9K_TXERR_FILT 0x02
37#define ATH9K_TXERR_FIFO 0x04
38#define ATH9K_TXERR_XTXOP 0x08
39#define ATH9K_TXERR_TIMER_EXPIRED 0x10
40
41#define ATH9K_TX_BA 0x01
42#define ATH9K_TX_PWRMGMT 0x02
43#define ATH9K_TX_DESC_CFG_ERR 0x04
44#define ATH9K_TX_DATA_UNDERRUN 0x08
45#define ATH9K_TX_DELIM_UNDERRUN 0x10
46#define ATH9K_TX_SW_ABORTED 0x40
47#define ATH9K_TX_SW_FILTERED 0x80
48
49#define NBBY 8
50
51struct ath_tx_status {
52 u32 ts_tstamp;
53 u16 ts_seqnum;
54 u8 ts_status;
55 u8 ts_ratecode;
56 u8 ts_rateindex;
57 int8_t ts_rssi;
58 u8 ts_shortretry;
59 u8 ts_longretry;
60 u8 ts_virtcol;
61 u8 ts_antenna;
62 u8 ts_flags;
63 int8_t ts_rssi_ctl0;
64 int8_t ts_rssi_ctl1;
65 int8_t ts_rssi_ctl2;
66 int8_t ts_rssi_ext0;
67 int8_t ts_rssi_ext1;
68 int8_t ts_rssi_ext2;
69 u8 pad[3];
70 u32 ba_low;
71 u32 ba_high;
72 u32 evm0;
73 u32 evm1;
74 u32 evm2;
75};
76
77struct ath_rx_status {
78 u32 rs_tstamp;
79 u16 rs_datalen;
80 u8 rs_status;
81 u8 rs_phyerr;
82 int8_t rs_rssi;
83 u8 rs_keyix;
84 u8 rs_rate;
85 u8 rs_antenna;
86 u8 rs_more;
87 int8_t rs_rssi_ctl0;
88 int8_t rs_rssi_ctl1;
89 int8_t rs_rssi_ctl2;
90 int8_t rs_rssi_ext0;
91 int8_t rs_rssi_ext1;
92 int8_t rs_rssi_ext2;
93 u8 rs_isaggr;
94 u8 rs_moreaggr;
95 u8 rs_num_delims;
96 u8 rs_flags;
97 u32 evm0;
98 u32 evm1;
99 u32 evm2;
100};
101
102#define ATH9K_RXERR_CRC 0x01
103#define ATH9K_RXERR_PHY 0x02
104#define ATH9K_RXERR_FIFO 0x04
105#define ATH9K_RXERR_DECRYPT 0x08
106#define ATH9K_RXERR_MIC 0x10
107
108#define ATH9K_RX_MORE 0x01
109#define ATH9K_RX_MORE_AGGR 0x02
110#define ATH9K_RX_GI 0x04
111#define ATH9K_RX_2040 0x08
112#define ATH9K_RX_DELIM_CRC_PRE 0x10
113#define ATH9K_RX_DELIM_CRC_POST 0x20
114#define ATH9K_RX_DECRYPT_BUSY 0x40
115
116#define ATH9K_RXKEYIX_INVALID ((u8)-1)
117#define ATH9K_TXKEYIX_INVALID ((u32)-1)
118
119struct ath_desc {
120 u32 ds_link;
121 u32 ds_data;
122 u32 ds_ctl0;
123 u32 ds_ctl1;
124 u32 ds_hw[20];
125 union {
126 struct ath_tx_status tx;
127 struct ath_rx_status rx;
128 void *stats;
129 } ds_us;
130 void *ds_vdata;
131} __packed;
132
133#define ds_txstat ds_us.tx
134#define ds_rxstat ds_us.rx
135#define ds_stat ds_us.stats
136
137#define ATH9K_TXDESC_CLRDMASK 0x0001
138#define ATH9K_TXDESC_NOACK 0x0002
139#define ATH9K_TXDESC_RTSENA 0x0004
140#define ATH9K_TXDESC_CTSENA 0x0008
141#define ATH9K_TXDESC_INTREQ 0x0010
142#define ATH9K_TXDESC_VEOL 0x0020
143#define ATH9K_TXDESC_EXT_ONLY 0x0040
144#define ATH9K_TXDESC_EXT_AND_CTL 0x0080
145#define ATH9K_TXDESC_VMF 0x0100
146#define ATH9K_TXDESC_FRAG_IS_ON 0x0200
147
148#define ATH9K_RXDESC_INTREQ 0x0020
149
150enum hal_capability_type {
151 HAL_CAP_CIPHER = 0,
152 HAL_CAP_TKIP_MIC,
153 HAL_CAP_TKIP_SPLIT,
154 HAL_CAP_PHYCOUNTERS,
155 HAL_CAP_DIVERSITY,
156 HAL_CAP_PSPOLL,
157 HAL_CAP_TXPOW,
158 HAL_CAP_PHYDIAG,
159 HAL_CAP_MCAST_KEYSRCH,
160 HAL_CAP_TSF_ADJUST,
161 HAL_CAP_WME_TKIPMIC,
162 HAL_CAP_RFSILENT,
163 HAL_CAP_ANT_CFG_2GHZ,
164 HAL_CAP_ANT_CFG_5GHZ
165};
166
167struct hal_capabilities {
168 u32 halChanSpreadSupport:1,
169 halChapTuningSupport:1,
170 halMicAesCcmSupport:1,
171 halMicCkipSupport:1,
172 halMicTkipSupport:1,
173 halCipherAesCcmSupport:1,
174 halCipherCkipSupport:1,
175 halCipherTkipSupport:1,
176 halVEOLSupport:1,
177 halBssIdMaskSupport:1,
178 halMcastKeySrchSupport:1,
179 halTsfAddSupport:1,
180 halChanHalfRate:1,
181 halChanQuarterRate:1,
182 halHTSupport:1,
183 halGTTSupport:1,
184 halFastCCSupport:1,
185 halRfSilentSupport:1,
186 halWowSupport:1,
187 halCSTSupport:1,
188 halEnhancedPmSupport:1,
189 halAutoSleepSupport:1,
190 hal4kbSplitTransSupport:1,
191 halWowMatchPatternExact:1;
192 u32 halWirelessModes;
193 u16 halTotalQueues;
194 u16 halKeyCacheSize;
195 u16 halLow5GhzChan, halHigh5GhzChan;
196 u16 halLow2GhzChan, halHigh2GhzChan;
197 u16 halNumMRRetries;
198 u16 halRtsAggrLimit;
199 u8 halTxChainMask;
200 u8 halRxChainMask;
201 u16 halTxTrigLevelMax;
202 u16 halRegCap;
203 u8 halNumGpioPins;
204 u8 halNumAntCfg2GHz;
205 u8 halNumAntCfg5GHz;
206};
207
208struct hal_ops_config {
209 int ath_hal_dma_beacon_response_time;
210 int ath_hal_sw_beacon_response_time;
211 int ath_hal_additional_swba_backoff;
212 int ath_hal_6mb_ack;
213 int ath_hal_cwmIgnoreExtCCA;
214 u8 ath_hal_pciePowerSaveEnable;
215 u8 ath_hal_pcieL1SKPEnable;
216 u8 ath_hal_pcieClockReq;
217 u32 ath_hal_pcieWaen;
218 int ath_hal_pciePowerReset;
219 u8 ath_hal_pcieRestore;
220 u8 ath_hal_analogShiftReg;
221 u8 ath_hal_htEnable;
222 u32 ath_hal_ofdmTrigLow;
223 u32 ath_hal_ofdmTrigHigh;
224 u32 ath_hal_cckTrigHigh;
225 u32 ath_hal_cckTrigLow;
226 u32 ath_hal_enableANI;
227 u8 ath_hal_noiseImmunityLvl;
228 u32 ath_hal_ofdmWeakSigDet;
229 u32 ath_hal_cckWeakSigThr;
230 u8 ath_hal_spurImmunityLvl;
231 u8 ath_hal_firStepLvl;
232 int8_t ath_hal_rssiThrHigh;
233 int8_t ath_hal_rssiThrLow;
234 u16 ath_hal_diversityControl;
235 u16 ath_hal_antennaSwitchSwap;
236 int ath_hal_serializeRegMode;
237 int ath_hal_intrMitigation;
238#define SPUR_DISABLE 0
239#define SPUR_ENABLE_IOCTL 1
240#define SPUR_ENABLE_EEPROM 2
241#define AR_EEPROM_MODAL_SPURS 5
242#define AR_SPUR_5413_1 1640
243#define AR_SPUR_5413_2 1200
244#define AR_NO_SPUR 0x8000
245#define AR_BASE_FREQ_2GHZ 2300
246#define AR_BASE_FREQ_5GHZ 4900
247#define AR_SPUR_FEEQ_BOUND_HT40 19
248#define AR_SPUR_FEEQ_BOUND_HT20 10
249 int ath_hal_spurMode;
250 u16 ath_hal_spurChans[AR_EEPROM_MODAL_SPURS][2];
251};
252
253enum ath9k_tx_queue {
254 ATH9K_TX_QUEUE_INACTIVE = 0,
255 ATH9K_TX_QUEUE_DATA,
256 ATH9K_TX_QUEUE_BEACON,
257 ATH9K_TX_QUEUE_CAB,
258 ATH9K_TX_QUEUE_UAPSD,
259 ATH9K_TX_QUEUE_PSPOLL
260};
261
262#define ATH9K_NUM_TX_QUEUES 10
263
264enum ath9k_tx_queue_subtype {
265 ATH9K_WME_AC_BK = 0,
266 ATH9K_WME_AC_BE,
267 ATH9K_WME_AC_VI,
268 ATH9K_WME_AC_VO,
269 ATH9K_WME_UPSD
270};
271
272enum ath9k_tx_queue_flags {
273 TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
274 TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
275 TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
276 TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
277 TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
278 TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
279 TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
280 TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
281 TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
282};
283
284struct ath9k_txq_info {
285 u32 tqi_ver;
286 enum ath9k_tx_queue_subtype tqi_subtype;
287 enum ath9k_tx_queue_flags tqi_qflags;
288 u32 tqi_priority;
289 u32 tqi_aifs;
290 u32 tqi_cwmin;
291 u32 tqi_cwmax;
292 u16 tqi_shretry;
293 u16 tqi_lgretry;
294 u32 tqi_cbrPeriod;
295 u32 tqi_cbrOverflowLimit;
296 u32 tqi_burstTime;
297 u32 tqi_readyTime;
298 u32 tqi_compBuf;
299};
300
301#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
302
303#define ATH9K_DECOMP_MASK_SIZE 128
304#define ATH9K_READY_TIME_LO_BOUND 50
305#define ATH9K_READY_TIME_HI_BOUND 96
306
307enum ath9k_pkt_type {
308 ATH9K_PKT_TYPE_NORMAL = 0,
309 ATH9K_PKT_TYPE_ATIM,
310 ATH9K_PKT_TYPE_PSPOLL,
311 ATH9K_PKT_TYPE_BEACON,
312 ATH9K_PKT_TYPE_PROBE_RESP,
313 ATH9K_PKT_TYPE_CHIRP,
314 ATH9K_PKT_TYPE_GRP_POLL,
315};
316
317struct ath9k_tx_queue_info {
318 u32 tqi_ver;
319 enum ath9k_tx_queue tqi_type;
320 enum ath9k_tx_queue_subtype tqi_subtype;
321 enum ath9k_tx_queue_flags tqi_qflags;
322 u32 tqi_priority;
323 u32 tqi_aifs;
324 u32 tqi_cwmin;
325 u32 tqi_cwmax;
326 u16 tqi_shretry;
327 u16 tqi_lgretry;
328 u32 tqi_cbrPeriod;
329 u32 tqi_cbrOverflowLimit;
330 u32 tqi_burstTime;
331 u32 tqi_readyTime;
332 u32 tqi_physCompBuf;
333 u32 tqi_intFlags;
334};
335
336enum ath9k_rx_filter {
337 ATH9K_RX_FILTER_UCAST = 0x00000001,
338 ATH9K_RX_FILTER_MCAST = 0x00000002,
339 ATH9K_RX_FILTER_BCAST = 0x00000004,
340 ATH9K_RX_FILTER_CONTROL = 0x00000008,
341 ATH9K_RX_FILTER_BEACON = 0x00000010,
342 ATH9K_RX_FILTER_PROM = 0x00000020,
343 ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
344 ATH9K_RX_FILTER_PSPOLL = 0x00004000,
345 ATH9K_RX_FILTER_PHYERR = 0x00000100,
346 ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
347};
348
349enum ath9k_int {
350 ATH9K_INT_RX = 0x00000001,
351 ATH9K_INT_RXDESC = 0x00000002,
352 ATH9K_INT_RXNOFRM = 0x00000008,
353 ATH9K_INT_RXEOL = 0x00000010,
354 ATH9K_INT_RXORN = 0x00000020,
355 ATH9K_INT_TX = 0x00000040,
356 ATH9K_INT_TXDESC = 0x00000080,
357 ATH9K_INT_TIM_TIMER = 0x00000100,
358 ATH9K_INT_TXURN = 0x00000800,
359 ATH9K_INT_MIB = 0x00001000,
360 ATH9K_INT_RXPHY = 0x00004000,
361 ATH9K_INT_RXKCM = 0x00008000,
362 ATH9K_INT_SWBA = 0x00010000,
363 ATH9K_INT_BMISS = 0x00040000,
364 ATH9K_INT_BNR = 0x00100000,
365 ATH9K_INT_TIM = 0x00200000,
366 ATH9K_INT_DTIM = 0x00400000,
367 ATH9K_INT_DTIMSYNC = 0x00800000,
368 ATH9K_INT_GPIO = 0x01000000,
369 ATH9K_INT_CABEND = 0x02000000,
370 ATH9K_INT_CST = 0x10000000,
371 ATH9K_INT_GTT = 0x20000000,
372 ATH9K_INT_FATAL = 0x40000000,
373 ATH9K_INT_GLOBAL = 0x80000000,
374 ATH9K_INT_BMISC = ATH9K_INT_TIM |
375 ATH9K_INT_DTIM |
376 ATH9K_INT_DTIMSYNC |
377 ATH9K_INT_CABEND,
378 ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
379 ATH9K_INT_RXDESC |
380 ATH9K_INT_RXEOL |
381 ATH9K_INT_RXORN |
382 ATH9K_INT_TXURN |
383 ATH9K_INT_TXDESC |
384 ATH9K_INT_MIB |
385 ATH9K_INT_RXPHY |
386 ATH9K_INT_RXKCM |
387 ATH9K_INT_SWBA |
388 ATH9K_INT_BMISS |
389 ATH9K_INT_GPIO,
390 ATH9K_INT_NOCARD = 0xffffffff
391};
392
393struct ath9k_rate_table {
394 int rateCount;
395 u8 rateCodeToIndex[256];
396 struct {
397 u8 valid;
398 u8 phy;
399 u32 rateKbps;
400 u8 rateCode;
401 u8 shortPreamble;
402 u8 dot11Rate;
403 u8 controlRate;
404 u16 lpAckDuration;
405 u16 spAckDuration;
406 } info[32];
407};
408
409#define ATH9K_RATESERIES_RTS_CTS 0x0001
410#define ATH9K_RATESERIES_2040 0x0002
411#define ATH9K_RATESERIES_HALFGI 0x0004
412
413struct ath9k_11n_rate_series {
414 u32 Tries;
415 u32 Rate;
416 u32 PktDuration;
417 u32 ChSel;
418 u32 RateFlags;
419};
420
421#define CHANNEL_CW_INT 0x00002
422#define CHANNEL_CCK 0x00020
423#define CHANNEL_OFDM 0x00040
424#define CHANNEL_2GHZ 0x00080
425#define CHANNEL_5GHZ 0x00100
426#define CHANNEL_PASSIVE 0x00200
427#define CHANNEL_DYN 0x00400
428#define CHANNEL_HALF 0x04000
429#define CHANNEL_QUARTER 0x08000
430#define CHANNEL_HT20 0x10000
431#define CHANNEL_HT40PLUS 0x20000
432#define CHANNEL_HT40MINUS 0x40000
433
434#define CHANNEL_INTERFERENCE 0x01
435#define CHANNEL_DFS 0x02
436#define CHANNEL_4MS_LIMIT 0x04
437#define CHANNEL_DFS_CLEAR 0x08
438#define CHANNEL_DISALLOW_ADHOC 0x10
439#define CHANNEL_PER_11D_ADHOC 0x20
440
441#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
442#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
443#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
444#define CHANNEL_G_HT20 (CHANNEL_2GHZ|CHANNEL_HT20)
445#define CHANNEL_A_HT20 (CHANNEL_5GHZ|CHANNEL_HT20)
446#define CHANNEL_G_HT40PLUS (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
447#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
448#define CHANNEL_A_HT40PLUS (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
449#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
450#define CHANNEL_ALL \
451 (CHANNEL_OFDM| \
452 CHANNEL_CCK| \
453 CHANNEL_2GHZ | \
454 CHANNEL_5GHZ | \
455 CHANNEL_HT20 | \
456 CHANNEL_HT40PLUS | \
457 CHANNEL_HT40MINUS)
458
459struct ath9k_channel {
460 u16 channel;
461 u32 channelFlags;
462 u8 privFlags;
463 int8_t maxRegTxPower;
464 int8_t maxTxPower;
465 int8_t minTxPower;
466 u32 chanmode;
467 int32_t CalValid;
468 bool oneTimeCalsDone;
469 int8_t iCoff;
470 int8_t qCoff;
471 int16_t rawNoiseFloor;
472 int8_t antennaMax;
473 u32 regDmnFlags;
474 u32 conformanceTestLimit[3]; /* 0:11a, 1: 11b, 2:11g */
475#ifdef ATH_NF_PER_CHAN
476 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
477#endif
478};
479
480#define IS_CHAN_A(_c) ((((_c)->channelFlags & CHANNEL_A) == CHANNEL_A) || \
481 (((_c)->channelFlags & CHANNEL_A_HT20) == CHANNEL_A_HT20) || \
482 (((_c)->channelFlags & CHANNEL_A_HT40PLUS) == CHANNEL_A_HT40PLUS) || \
483 (((_c)->channelFlags & CHANNEL_A_HT40MINUS) == CHANNEL_A_HT40MINUS))
484#define IS_CHAN_B(_c) (((_c)->channelFlags & CHANNEL_B) == CHANNEL_B)
485#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
486 (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
487 (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
488 (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
489#define IS_CHAN_CCK(_c) (((_c)->channelFlags & CHANNEL_CCK) != 0)
490#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
491#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
492#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
493#define IS_CHAN_PASSIVE(_c) (((_c)->channelFlags & CHANNEL_PASSIVE) != 0)
494#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
495#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
496
497/* These macros check chanmode and not channelFlags */
498#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) || \
499 ((_c)->chanmode == CHANNEL_G_HT20))
500#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) || \
501 ((_c)->chanmode == CHANNEL_A_HT40MINUS) || \
502 ((_c)->chanmode == CHANNEL_G_HT40PLUS) || \
503 ((_c)->chanmode == CHANNEL_G_HT40MINUS))
504#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
505
506#define IS_CHAN_IN_PUBLIC_SAFETY_BAND(_c) ((_c) > 4940 && (_c) < 4990)
507#define IS_CHAN_A_5MHZ_SPACED(_c) \
508 ((((_c)->channelFlags & CHANNEL_5GHZ) != 0) && \
509 (((_c)->channel % 20) != 0) && \
510 (((_c)->channel % 10) != 0))
511
512struct ath9k_keyval {
513 u8 kv_type;
514 u8 kv_pad;
515 u16 kv_len;
516 u8 kv_val[16];
517 u8 kv_mic[8];
518 u8 kv_txmic[8];
519};
520
521enum ath9k_key_type {
522 ATH9K_KEY_TYPE_CLEAR,
523 ATH9K_KEY_TYPE_WEP,
524 ATH9K_KEY_TYPE_AES,
525 ATH9K_KEY_TYPE_TKIP,
526};
527
528enum ath9k_cipher {
529 ATH9K_CIPHER_WEP = 0,
530 ATH9K_CIPHER_AES_OCB = 1,
531 ATH9K_CIPHER_AES_CCM = 2,
532 ATH9K_CIPHER_CKIP = 3,
533 ATH9K_CIPHER_TKIP = 4,
534 ATH9K_CIPHER_CLR = 5,
535 ATH9K_CIPHER_MIC = 127
536};
537
538#define AR_EEPROM_EEPCAP_COMPRESS_DIS 0x0001
539#define AR_EEPROM_EEPCAP_AES_DIS 0x0002
540#define AR_EEPROM_EEPCAP_FASTFRAME_DIS 0x0004
541#define AR_EEPROM_EEPCAP_BURST_DIS 0x0008
542#define AR_EEPROM_EEPCAP_MAXQCU 0x01F0
543#define AR_EEPROM_EEPCAP_MAXQCU_S 4
544#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN 0x0200
545#define AR_EEPROM_EEPCAP_KC_ENTRIES 0xF000
546#define AR_EEPROM_EEPCAP_KC_ENTRIES_S 12
547
548#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND 0x0040
549#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN 0x0080
550#define AR_EEPROM_EEREGCAP_EN_KK_U2 0x0100
551#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND 0x0200
552#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD 0x0400
553#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A 0x0800
554
555#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0 0x4000
556#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
557
558#define SD_NO_CTL 0xE0
559#define NO_CTL 0xff
560#define CTL_MODE_M 7
561#define CTL_11A 0
562#define CTL_11B 1
563#define CTL_11G 2
564#define CTL_2GHT20 5
565#define CTL_5GHT20 6
566#define CTL_2GHT40 7
567#define CTL_5GHT40 8
568
569#define AR_EEPROM_MAC(i) (0x1d+(i))
570#define EEP_SCALE 100
571#define EEP_DELTA 10
572
573#define AR_EEPROM_RFSILENT_GPIO_SEL 0x001c
574#define AR_EEPROM_RFSILENT_GPIO_SEL_S 2
575#define AR_EEPROM_RFSILENT_POLARITY 0x0002
576#define AR_EEPROM_RFSILENT_POLARITY_S 1
577
578#define CTRY_DEBUG 0x1ff
579#define CTRY_DEFAULT 0
580
581enum reg_ext_bitmap {
582 REG_EXT_JAPAN_MIDBAND = 1,
583 REG_EXT_FCC_DFS_HT40 = 2,
584 REG_EXT_JAPAN_NONDFS_HT40 = 3,
585 REG_EXT_JAPAN_DFS_HT40 = 4
586};
587
588struct ath9k_country_entry {
589 u16 countryCode;
590 u16 regDmnEnum;
591 u16 regDmn5G;
592 u16 regDmn2G;
593 u8 isMultidomain;
594 u8 iso[3];
595};
596
597#define REG_WRITE(_ah, _reg, _val) iowrite32(_val, _ah->ah_sh + _reg)
598#define REG_READ(_ah, _reg) ioread32(_ah->ah_sh + _reg)
599
600#define SM(_v, _f) (((_v) << _f##_S) & _f)
601#define MS(_v, _f) (((_v) & _f) >> _f##_S)
602#define REG_RMW(_a, _r, _set, _clr) \
603 REG_WRITE(_a, _r, (REG_READ(_a, _r) & ~(_clr)) | (_set))
604#define REG_RMW_FIELD(_a, _r, _f, _v) \
605 REG_WRITE(_a, _r, \
606 (REG_READ(_a, _r) & ~_f) | (((_v) << _f##_S) & _f))
607#define REG_SET_BIT(_a, _r, _f) \
608 REG_WRITE(_a, _r, REG_READ(_a, _r) | _f)
609#define REG_CLR_BIT(_a, _r, _f) \
610 REG_WRITE(_a, _r, REG_READ(_a, _r) & ~_f)
611
612#define ATH9K_COMP_BUF_MAX_SIZE 9216
613#define ATH9K_COMP_BUF_ALIGN_SIZE 512
614
615#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
616
617#define INIT_AIFS 2
618#define INIT_CWMIN 15
619#define INIT_CWMIN_11B 31
620#define INIT_CWMAX 1023
621#define INIT_SH_RETRY 10
622#define INIT_LG_RETRY 10
623#define INIT_SSH_RETRY 32
624#define INIT_SLG_RETRY 32
625
626#define WLAN_CTRL_FRAME_SIZE (2+2+6+4)
627
628#define ATH_AMPDU_LIMIT_MAX (64 * 1024 - 1)
629#define ATH_AMPDU_LIMIT_DEFAULT ATH_AMPDU_LIMIT_MAX
630
631#define IEEE80211_WEP_IVLEN 3
632#define IEEE80211_WEP_KIDLEN 1
633#define IEEE80211_WEP_CRCLEN 4
634#define IEEE80211_MAX_MPDU_LEN (3840 + FCS_LEN + \
635 (IEEE80211_WEP_IVLEN + \
636 IEEE80211_WEP_KIDLEN + \
637 IEEE80211_WEP_CRCLEN))
638#define IEEE80211_MAX_LEN (2300 + FCS_LEN + \
639 (IEEE80211_WEP_IVLEN + \
640 IEEE80211_WEP_KIDLEN + \
641 IEEE80211_WEP_CRCLEN))
642
643#define MAX_REG_ADD_COUNT 129
644#define MAX_RATE_POWER 63
645
646enum ath9k_power_mode {
647 ATH9K_PM_AWAKE = 0,
648 ATH9K_PM_FULL_SLEEP,
649 ATH9K_PM_NETWORK_SLEEP,
650 ATH9K_PM_UNDEFINED
651};
652
653#define HAL_ANTENNA_MIN_MODE 0
654#define HAL_ANTENNA_FIXED_A 1
655#define HAL_ANTENNA_FIXED_B 2
656#define HAL_ANTENNA_MAX_MODE 3
657
658struct ath9k_mib_stats {
659 u32 ackrcv_bad;
660 u32 rts_bad;
661 u32 rts_good;
662 u32 fcs_bad;
663 u32 beacons;
664};
665
666enum ath9k_ant_setting {
667 ATH9K_ANT_VARIABLE = 0,
668 ATH9K_ANT_FIXED_A,
669 ATH9K_ANT_FIXED_B
670};
671
672enum ath9k_opmode {
673 ATH9K_M_STA = 1,
674 ATH9K_M_IBSS = 0,
675 ATH9K_M_HOSTAP = 6,
676 ATH9K_M_MONITOR = 8
677};
678
679#define ATH9K_SLOT_TIME_6 6
680#define ATH9K_SLOT_TIME_9 9
681#define ATH9K_SLOT_TIME_20 20
682
683enum ath9k_ht_macmode {
684 ATH9K_HT_MACMODE_20 = 0,
685 ATH9K_HT_MACMODE_2040 = 1,
686};
687
688enum ath9k_ht_extprotspacing {
689 ATH9K_HT_EXTPROTSPACING_20 = 0,
690 ATH9K_HT_EXTPROTSPACING_25 = 1,
691};
692
693struct ath9k_ht_cwm {
694 enum ath9k_ht_macmode ht_macmode;
695 enum ath9k_ht_extprotspacing ht_extprotspacing;
696};
697
698enum hal_freq_band {
699 HAL_FREQ_BAND_5GHZ = 0,
700 HAL_FREQ_BAND_2GHZ = 1,
701};
702
703enum ath9k_ani_cmd {
704 ATH9K_ANI_PRESENT = 0x1,
705 ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
706 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
707 ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
708 ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
709 ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
710 ATH9K_ANI_MODE = 0x40,
711 ATH9K_ANI_PHYERR_RESET = 0x80,
712 ATH9K_ANI_ALL = 0xff
713};
714
715enum phytype {
716 PHY_DS,
717 PHY_FH,
718 PHY_OFDM,
719 PHY_HT,
720 PHY_MAX
721};
722#define PHY_CCK PHY_DS
723
724enum start_adhoc_option {
725 START_ADHOC_NO_11A,
726 START_ADHOC_PER_11D,
727 START_ADHOC_IN_11A,
728 START_ADHOC_IN_11B,
729};
730
731enum ath9k_tp_scale {
732 ATH9K_TP_SCALE_MAX = 0,
733 ATH9K_TP_SCALE_50,
734 ATH9K_TP_SCALE_25,
735 ATH9K_TP_SCALE_12,
736 ATH9K_TP_SCALE_MIN
737};
738
739enum ser_reg_mode {
740 SER_REG_MODE_OFF = 0,
741 SER_REG_MODE_ON = 1,
742 SER_REG_MODE_AUTO = 2,
743};
744
745#define AR_PHY_CCA_MAX_GOOD_VALUE -85
746#define AR_PHY_CCA_MAX_HIGH_VALUE -62
747#define AR_PHY_CCA_MIN_BAD_VALUE -121
748#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT 3
749#define AR_PHY_CCA_FILTERWINDOW_LENGTH 5
750
751#define ATH9K_NF_CAL_HIST_MAX 5
752#define NUM_NF_READINGS 6
753
754struct ath9k_nfcal_hist {
755 int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
756 u8 currIndex;
757 int16_t privNF;
758 u8 invalidNFcount;
759};
760
761struct ath9k_beacon_state {
762 u32 bs_nexttbtt;
763 u32 bs_nextdtim;
764 u32 bs_intval;
765#define ATH9K_BEACON_PERIOD 0x0000ffff
766#define ATH9K_BEACON_ENA 0x00800000
767#define ATH9K_BEACON_RESET_TSF 0x01000000
768 u32 bs_dtimperiod;
769 u16 bs_cfpperiod;
770 u16 bs_cfpmaxduration;
771 u32 bs_cfpnext;
772 u16 bs_timoffset;
773 u16 bs_bmissthreshold;
774 u32 bs_sleepduration;
775};
776
777struct ath9k_node_stats {
778 u32 ns_avgbrssi;
779 u32 ns_avgrssi;
780 u32 ns_avgtxrssi;
781 u32 ns_avgtxrate;
782};
783
784#define ATH9K_RSSI_EP_MULTIPLIER (1<<7)
785
786enum ath9k_gpio_output_mux_type {
787 ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT,
788 ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
789 ATH9K_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
790 ATH9K_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
791 ATH9K_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
792 ATH9K_GPIO_OUTPUT_MUX_NUM_ENTRIES
793};
794
795enum {
796 ATH9K_RESET_POWER_ON,
797 ATH9K_RESET_WARM,
798 ATH9K_RESET_COLD,
799};
800
801#define AH_USE_EEPROM 0x1
802
803struct ath_hal {
804 u32 ah_magic;
805 u16 ah_devid;
806 u16 ah_subvendorid;
807 struct ath_softc *ah_sc;
808 void __iomem *ah_sh;
809 u16 ah_countryCode;
810 u32 ah_macVersion;
811 u16 ah_macRev;
812 u16 ah_phyRev;
813 u16 ah_analog5GhzRev;
814 u16 ah_analog2GhzRev;
815 u8 ah_decompMask[ATH9K_DECOMP_MASK_SIZE];
816 u32 ah_flags;
817 enum ath9k_opmode ah_opmode;
818 struct hal_ops_config ah_config;
819 struct hal_capabilities ah_caps;
820 int16_t ah_powerLimit;
821 u16 ah_maxPowerLevel;
822 u32 ah_tpScale;
823 u16 ah_currentRD;
824 u16 ah_currentRDExt;
825 u16 ah_currentRDInUse;
826 u16 ah_currentRD5G;
827 u16 ah_currentRD2G;
828 char ah_iso[4];
829 enum start_adhoc_option ah_adHocMode;
830 bool ah_commonMode;
831 struct ath9k_channel ah_channels[150];
832 u32 ah_nchan;
833 struct ath9k_channel *ah_curchan;
834 u16 ah_rfsilent;
835 bool ah_rfkillEnabled;
836 bool ah_isPciExpress;
837 u16 ah_txTrigLevel;
838#ifndef ATH_NF_PER_CHAN
839 struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
840#endif
841};
842
843enum wireless_mode {
844 WIRELESS_MODE_11a = 0,
845 WIRELESS_MODE_11b = 2,
846 WIRELESS_MODE_11g = 3,
847 WIRELESS_MODE_11NA_HT20 = 6,
848 WIRELESS_MODE_11NG_HT20 = 7,
849 WIRELESS_MODE_11NA_HT40PLUS = 8,
850 WIRELESS_MODE_11NA_HT40MINUS = 9,
851 WIRELESS_MODE_11NG_HT40PLUS = 10,
852 WIRELESS_MODE_11NG_HT40MINUS = 11,
853 WIRELESS_MODE_MAX
854};
855
856enum {
857 ATH9K_MODE_SEL_11A = 0x00001,
858 ATH9K_MODE_SEL_11B = 0x00002,
859 ATH9K_MODE_SEL_11G = 0x00004,
860 ATH9K_MODE_SEL_11NG_HT20 = 0x00008,
861 ATH9K_MODE_SEL_11NA_HT20 = 0x00010,
862 ATH9K_MODE_SEL_11NG_HT40PLUS = 0x00020,
863 ATH9K_MODE_SEL_11NG_HT40MINUS = 0x00040,
864 ATH9K_MODE_SEL_11NA_HT40PLUS = 0x00080,
865 ATH9K_MODE_SEL_11NA_HT40MINUS = 0x00100,
866 ATH9K_MODE_SEL_2GHZ = (ATH9K_MODE_SEL_11B |
867 ATH9K_MODE_SEL_11G |
868 ATH9K_MODE_SEL_11NG_HT20),
869 ATH9K_MODE_SEL_5GHZ = (ATH9K_MODE_SEL_11A |
870 ATH9K_MODE_SEL_11NA_HT20),
871 ATH9K_MODE_SEL_ALL = 0xffffffff
872};
873
874struct chan_centers {
875 u16 synth_center;
876 u16 ctl_center;
877 u16 ext_center;
878};
879
880int ath_hal_getcapability(struct ath_hal *ah,
881 enum hal_capability_type type,
882 u32 capability,
883 u32 *result);
884const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
885 u32 mode);
886void ath9k_hw_detach(struct ath_hal *ah);
887struct ath_hal *ath9k_hw_attach(u16 devid,
888 struct ath_softc *sc,
889 void __iomem *mem,
890 int *error);
891bool ath9k_regd_init_channels(struct ath_hal *ah,
892 u32 maxchans, u32 *nchans,
893 u8 *regclassids,
894 u32 maxregids, u32 *nregids,
895 u16 cc, u32 modeSelect,
896 bool enableOutdoor,
897 bool enableExtendedChannels);
898u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
899enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah,
900 enum ath9k_int ints);
901bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
902 struct ath9k_channel *chan,
903 enum ath9k_ht_macmode macmode,
904 u8 txchainmask, u8 rxchainmask,
905 enum ath9k_ht_extprotspacing extprotspacing,
906 bool bChannelChange,
907 int *status);
908bool ath9k_hw_phy_disable(struct ath_hal *ah);
909void ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
910 bool *isCalDone);
911void ath9k_hw_ani_monitor(struct ath_hal *ah,
912 const struct ath9k_node_stats *stats,
913 struct ath9k_channel *chan);
914bool ath9k_hw_calibrate(struct ath_hal *ah,
915 struct ath9k_channel *chan,
916 u8 rxchainmask,
917 bool longcal,
918 bool *isCalDone);
919int16_t ath9k_hw_getchan_noise(struct ath_hal *ah,
920 struct ath9k_channel *chan);
921void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
922 u16 assocId);
923void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits);
924void ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
925 u16 assocId);
926bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q);
927void ath9k_hw_reset_tsf(struct ath_hal *ah);
928bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry);
929bool ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
930 const u8 *mac);
931bool ath9k_hw_set_keycache_entry(struct ath_hal *ah,
932 u16 entry,
933 const struct ath9k_keyval *k,
934 const u8 *mac,
935 int xorKey);
936bool ath9k_hw_set_tsfadjust(struct ath_hal *ah,
937 u32 setting);
938void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore);
939bool ath9k_hw_intrpend(struct ath_hal *ah);
940bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked);
941bool ath9k_hw_updatetxtriglevel(struct ath_hal *ah,
942 bool bIncTrigLevel);
943void ath9k_hw_procmibevent(struct ath_hal *ah,
944 const struct ath9k_node_stats *stats);
945bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set);
946void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode);
947bool ath9k_hw_phycounters(struct ath_hal *ah);
948bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry);
949bool ath9k_hw_getcapability(struct ath_hal *ah,
950 enum hal_capability_type type,
951 u32 capability,
952 u32 *result);
953bool ath9k_hw_setcapability(struct ath_hal *ah,
954 enum hal_capability_type type,
955 u32 capability,
956 u32 setting,
957 int *status);
958u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
959void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac);
960void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask);
961bool ath9k_hw_setbssidmask(struct ath_hal *ah,
962 const u8 *mask);
963bool ath9k_hw_setpower(struct ath_hal *ah,
964 enum ath9k_power_mode mode);
965enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah);
966u64 ath9k_hw_gettsf64(struct ath_hal *ah);
967u32 ath9k_hw_getdefantenna(struct ath_hal *ah);
968bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us);
969bool ath9k_hw_setantennaswitch(struct ath_hal *ah,
970 enum ath9k_ant_setting settings,
971 struct ath9k_channel *chan,
972 u8 *tx_chainmask,
973 u8 *rx_chainmask,
974 u8 *antenna_cfgd);
975void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna);
976int ath9k_hw_select_antconfig(struct ath_hal *ah,
977 u32 cfg);
978bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
979 u32 txdp);
980bool ath9k_hw_txstart(struct ath_hal *ah, u32 q);
981u16 ath9k_hw_computetxtime(struct ath_hal *ah,
982 const struct ath9k_rate_table *rates,
983 u32 frameLen, u16 rateix,
984 bool shortPreamble);
985void ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
986 struct ath_desc *lastds,
987 u32 durUpdateEn, u32 rtsctsRate,
988 u32 rtsctsDuration,
989 struct ath9k_11n_rate_series series[],
990 u32 nseries, u32 flags);
991void ath9k_hw_set11n_burstduration(struct ath_hal *ah,
992 struct ath_desc *ds,
993 u32 burstDuration);
994void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds);
995u32 ath9k_hw_reverse_bits(u32 val, u32 n);
996bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q);
997u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan);
998u32 ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
999 struct ath9k_channel *chan);
1000u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags);
1001bool ath9k_hw_gettxqueueprops(struct ath_hal *ah, int q,
1002 struct ath9k_txq_info *qInfo);
1003bool ath9k_hw_settxqueueprops(struct ath_hal *ah, int q,
1004 const struct ath9k_txq_info *qInfo);
1005struct ath9k_channel *ath9k_regd_check_channel(struct ath_hal *ah,
1006 const struct ath9k_channel *c);
1007void ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
1008 u32 pktLen, enum ath9k_pkt_type type,
1009 u32 txPower, u32 keyIx,
1010 enum ath9k_key_type keyType, u32 flags);
1011bool ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
1012 u32 segLen, bool firstSeg,
1013 bool lastSeg,
1014 const struct ath_desc *ds0);
1015u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
1016 u32 *rxc_pcnt,
1017 u32 *rxf_pcnt,
1018 u32 *txf_pcnt);
1019void ath9k_hw_dmaRegDump(struct ath_hal *ah);
1020void ath9k_hw_beaconinit(struct ath_hal *ah,
1021 u32 next_beacon, u32 beacon_period);
1022void ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
1023 const struct ath9k_beacon_state *bs);
1024bool ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
1025 u32 size, u32 flags);
1026void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp);
1027void ath9k_hw_rxena(struct ath_hal *ah);
1028void ath9k_hw_setopmode(struct ath_hal *ah);
1029bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac);
1030void ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
1031 u32 filter1);
1032u32 ath9k_hw_getrxfilter(struct ath_hal *ah);
1033void ath9k_hw_startpcureceive(struct ath_hal *ah);
1034void ath9k_hw_stoppcurecv(struct ath_hal *ah);
1035bool ath9k_hw_stopdmarecv(struct ath_hal *ah);
1036int ath9k_hw_rxprocdesc(struct ath_hal *ah,
1037 struct ath_desc *ds, u32 pa,
1038 struct ath_desc *nds, u64 tsf);
1039u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q);
1040int ath9k_hw_txprocdesc(struct ath_hal *ah,
1041 struct ath_desc *ds);
1042void ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
1043 u32 numDelims);
1044void ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
1045 u32 aggrLen);
1046void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds);
1047bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q);
1048void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs);
1049void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds);
1050void ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah,
1051 struct ath_desc *ds, u32 vmf);
1052bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit);
1053bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah);
1054int ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
1055 const struct ath9k_txq_info *qInfo);
1056u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q);
1057const char *ath9k_hw_probe(u16 vendorid, u16 devid);
1058bool ath9k_hw_disable(struct ath_hal *ah);
1059void ath9k_hw_rfdetach(struct ath_hal *ah);
1060void ath9k_hw_get_channel_centers(struct ath_hal *ah,
1061 struct ath9k_channel *chan,
1062 struct chan_centers *centers);
1063bool ath9k_get_channel_edges(struct ath_hal *ah,
1064 u16 flags, u16 *low,
1065 u16 *high);
1066#endif
diff --git a/drivers/net/wireless/ath9k/beacon.c b/drivers/net/wireless/ath9k/beacon.c
new file mode 100644
index 000000000000..00993f828c5c
--- /dev/null
+++ b/drivers/net/wireless/ath9k/beacon.c
@@ -0,0 +1,977 @@
1/*
2 * Copyright (c) 2008 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 /* Implementation of beacon processing. */
18
19#include <asm/unaligned.h>
20#include "core.h"
21
22/*
23 * Configure parameters for the beacon queue
24 *
25 * This function will modify certain transmit queue properties depending on
26 * the operating mode of the station (AP or AdHoc). Parameters are AIFS
27 * settings and channel width min/max
28*/
29
30static int ath_beaconq_config(struct ath_softc *sc)
31{
32 struct ath_hal *ah = sc->sc_ah;
33 struct ath9k_txq_info qi;
34
35 ath9k_hw_gettxqueueprops(ah, sc->sc_bhalq, &qi);
36 if (sc->sc_opmode == ATH9K_M_HOSTAP) {
37 /* Always burst out beacon and CAB traffic. */
38 qi.tqi_aifs = 1;
39 qi.tqi_cwmin = 0;
40 qi.tqi_cwmax = 0;
41 } else {
42 /* Adhoc mode; important thing is to use 2x cwmin. */
43 qi.tqi_aifs = sc->sc_beacon_qi.tqi_aifs;
44 qi.tqi_cwmin = 2*sc->sc_beacon_qi.tqi_cwmin;
45 qi.tqi_cwmax = sc->sc_beacon_qi.tqi_cwmax;
46 }
47
48 if (!ath9k_hw_settxqueueprops(ah, sc->sc_bhalq, &qi)) {
49 DPRINTF(sc, ATH_DBG_FATAL,
50 "%s: unable to update h/w beacon queue parameters\n",
51 __func__);
52 return 0;
53 } else {
54 ath9k_hw_resettxqueue(ah, sc->sc_bhalq); /* push to h/w */
55 return 1;
56 }
57}
58
59/*
60 * Setup the beacon frame for transmit.
61 *
62 * Associates the beacon frame buffer with a transmit descriptor. Will set
63 * up all required antenna switch parameters, rate codes, and channel flags.
64 * Beacons are always sent out at the lowest rate, and are not retried.
65*/
66
67static void ath_beacon_setup(struct ath_softc *sc,
68 struct ath_vap *avp, struct ath_buf *bf)
69{
70 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
71 struct ath_hal *ah = sc->sc_ah;
72 struct ath_desc *ds;
73 int flags, antenna;
74 const struct ath9k_rate_table *rt;
75 u8 rix, rate;
76 int ctsrate = 0;
77 int ctsduration = 0;
78 struct ath9k_11n_rate_series series[4];
79
80 DPRINTF(sc, ATH_DBG_BEACON, "%s: m %p len %u\n",
81 __func__, skb, skb->len);
82
83 /* setup descriptors */
84 ds = bf->bf_desc;
85
86 flags = ATH9K_TXDESC_NOACK;
87
88 if (sc->sc_opmode == ATH9K_M_IBSS && ah->ah_caps.halVEOLSupport) {
89 ds->ds_link = bf->bf_daddr; /* self-linked */
90 flags |= ATH9K_TXDESC_VEOL;
91 /* Let hardware handle antenna switching. */
92 antenna = 0;
93 } else {
94 ds->ds_link = 0;
95 /*
96 * Switch antenna every beacon.
97 * Should only switch every beacon period, not for every
98 * SWBA's
99 * XXX assumes two antenna
100 */
101 antenna = ((sc->ast_be_xmit / sc->sc_nbcnvaps) & 1 ? 2 : 1);
102 }
103
104 ds->ds_data = bf->bf_buf_addr;
105
106 /*
107 * Calculate rate code.
108 * XXX everything at min xmit rate
109 */
110 rix = sc->sc_minrateix;
111 rt = sc->sc_currates;
112 rate = rt->info[rix].rateCode;
113 if (sc->sc_flags & ATH_PREAMBLE_SHORT)
114 rate |= rt->info[rix].shortPreamble;
115
116 ath9k_hw_set11n_txdesc(ah, ds
117 , skb->len + FCS_LEN /* frame length */
118 , ATH9K_PKT_TYPE_BEACON /* Atheros packet type */
119 , avp->av_btxctl.txpower /* txpower XXX */
120 , ATH9K_TXKEYIX_INVALID /* no encryption */
121 , ATH9K_KEY_TYPE_CLEAR /* no encryption */
122 , flags /* no ack, veol for beacons */
123 );
124
125 /* NB: beacon's BufLen must be a multiple of 4 bytes */
126 ath9k_hw_filltxdesc(ah, ds
127 , roundup(skb->len, 4) /* buffer length */
128 , true /* first segment */
129 , true /* last segment */
130 , ds /* first descriptor */
131 );
132
133 memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
134 series[0].Tries = 1;
135 series[0].Rate = rate;
136 series[0].ChSel = sc->sc_tx_chainmask;
137 series[0].RateFlags = (ctsrate) ? ATH9K_RATESERIES_RTS_CTS : 0;
138 ath9k_hw_set11n_ratescenario(ah, ds, ds, 0,
139 ctsrate, ctsduration, series, 4, 0);
140}
141
142/* Move everything from the vap's mcast queue to the hardware cab queue.
143 * Caller must hold mcasq lock and cabq lock
144 * XXX MORE_DATA bit?
145 */
146static void empty_mcastq_into_cabq(struct ath_hal *ah,
147 struct ath_txq *mcastq, struct ath_txq *cabq)
148{
149 struct ath_buf *bfmcast;
150
151 BUG_ON(list_empty(&mcastq->axq_q));
152
153 bfmcast = list_first_entry(&mcastq->axq_q, struct ath_buf, list);
154
155 /* link the descriptors */
156 if (!cabq->axq_link)
157 ath9k_hw_puttxbuf(ah, cabq->axq_qnum, bfmcast->bf_daddr);
158 else
159 *cabq->axq_link = bfmcast->bf_daddr;
160
161 /* append the private vap mcast list to the cabq */
162
163 cabq->axq_depth += mcastq->axq_depth;
164 cabq->axq_totalqueued += mcastq->axq_totalqueued;
165 cabq->axq_linkbuf = mcastq->axq_linkbuf;
166 cabq->axq_link = mcastq->axq_link;
167 list_splice_tail_init(&mcastq->axq_q, &cabq->axq_q);
168 mcastq->axq_depth = 0;
169 mcastq->axq_totalqueued = 0;
170 mcastq->axq_linkbuf = NULL;
171 mcastq->axq_link = NULL;
172}
173
174/* This is only run at DTIM. We move everything from the vap's mcast queue
175 * to the hardware cab queue. Caller must hold the mcastq lock. */
176static void trigger_mcastq(struct ath_hal *ah,
177 struct ath_txq *mcastq, struct ath_txq *cabq)
178{
179 spin_lock_bh(&cabq->axq_lock);
180
181 if (!list_empty(&mcastq->axq_q))
182 empty_mcastq_into_cabq(ah, mcastq, cabq);
183
184 /* cabq is gated by beacon so it is safe to start here */
185 if (!list_empty(&cabq->axq_q))
186 ath9k_hw_txstart(ah, cabq->axq_qnum);
187
188 spin_unlock_bh(&cabq->axq_lock);
189}
190
191/*
192 * Generate beacon frame and queue cab data for a vap.
193 *
194 * Updates the contents of the beacon frame. It is assumed that the buffer for
195 * the beacon frame has been allocated in the ATH object, and simply needs to
196 * be filled for this cycle. Also, any CAB (crap after beacon?) traffic will
197 * be added to the beacon frame at this point.
198*/
199static struct ath_buf *ath_beacon_generate(struct ath_softc *sc, int if_id)
200{
201 struct ath_hal *ah = sc->sc_ah;
202 struct ath_buf *bf;
203 struct ath_vap *avp;
204 struct sk_buff *skb;
205 int cabq_depth;
206 int mcastq_depth;
207 int is_beacon_dtim = 0;
208 unsigned int curlen;
209 struct ath_txq *cabq;
210 struct ath_txq *mcastq;
211 avp = sc->sc_vaps[if_id];
212
213 mcastq = &avp->av_mcastq;
214 cabq = sc->sc_cabq;
215
216 ASSERT(avp);
217
218 if (avp->av_bcbuf == NULL) {
219 DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
220 __func__, avp, avp->av_bcbuf);
221 return NULL;
222 }
223 bf = avp->av_bcbuf;
224 skb = (struct sk_buff *) bf->bf_mpdu;
225
226 /*
227 * Update dynamic beacon contents. If this returns
228 * non-zero then we need to remap the memory because
229 * the beacon frame changed size (probably because
230 * of the TIM bitmap).
231 */
232 curlen = skb->len;
233
234 /* XXX: spin_lock_bh should not be used here, but sparse bitches
235 * otherwise. We should fix sparse :) */
236 spin_lock_bh(&mcastq->axq_lock);
237 mcastq_depth = avp->av_mcastq.axq_depth;
238
239 if (ath_update_beacon(sc, if_id, &avp->av_boff, skb, mcastq_depth) ==
240 1) {
241 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
242 get_dma_mem_context(bf, bf_dmacontext));
243 bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
244 get_dma_mem_context(bf, bf_dmacontext));
245 } else {
246 pci_dma_sync_single_for_cpu(sc->pdev,
247 bf->bf_buf_addr,
248 skb_tailroom(skb),
249 PCI_DMA_TODEVICE);
250 }
251
252 /*
253 * if the CABQ traffic from previous DTIM is pending and the current
254 * beacon is also a DTIM.
255 * 1) if there is only one vap let the cab traffic continue.
256 * 2) if there are more than one vap and we are using staggered
257 * beacons, then drain the cabq by dropping all the frames in
258 * the cabq so that the current vaps cab traffic can be scheduled.
259 */
260 spin_lock_bh(&cabq->axq_lock);
261 cabq_depth = cabq->axq_depth;
262 spin_unlock_bh(&cabq->axq_lock);
263
264 is_beacon_dtim = avp->av_boff.bo_tim[4] & 1;
265
266 if (mcastq_depth && is_beacon_dtim && cabq_depth) {
267 /*
268 * Unlock the cabq lock as ath_tx_draintxq acquires
269 * the lock again which is a common function and that
270 * acquires txq lock inside.
271 */
272 if (sc->sc_nvaps > 1) {
273 ath_tx_draintxq(sc, cabq, false);
274 DPRINTF(sc, ATH_DBG_BEACON,
275 "%s: flush previous cabq traffic\n", __func__);
276 }
277 }
278
279 /* Construct tx descriptor. */
280 ath_beacon_setup(sc, avp, bf);
281
282 /*
283 * Enable the CAB queue before the beacon queue to
284 * insure cab frames are triggered by this beacon.
285 */
286 if (is_beacon_dtim)
287 trigger_mcastq(ah, mcastq, cabq);
288
289 spin_unlock_bh(&mcastq->axq_lock);
290 return bf;
291}
292
293/*
294 * Startup beacon transmission for adhoc mode when they are sent entirely
295 * by the hardware using the self-linked descriptor + veol trick.
296*/
297
298static void ath_beacon_start_adhoc(struct ath_softc *sc, int if_id)
299{
300 struct ath_hal *ah = sc->sc_ah;
301 struct ath_buf *bf;
302 struct ath_vap *avp;
303 struct sk_buff *skb;
304
305 avp = sc->sc_vaps[if_id];
306 ASSERT(avp);
307
308 if (avp->av_bcbuf == NULL) {
309 DPRINTF(sc, ATH_DBG_BEACON, "%s: avp=%p av_bcbuf=%p\n",
310 __func__, avp, avp != NULL ? avp->av_bcbuf : NULL);
311 return;
312 }
313 bf = avp->av_bcbuf;
314 skb = (struct sk_buff *) bf->bf_mpdu;
315
316 /* Construct tx descriptor. */
317 ath_beacon_setup(sc, avp, bf);
318
319 /* NB: caller is known to have already stopped tx dma */
320 ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr);
321 ath9k_hw_txstart(ah, sc->sc_bhalq);
322 DPRINTF(sc, ATH_DBG_BEACON, "%s: TXDP%u = %llx (%p)\n", __func__,
323 sc->sc_bhalq, ito64(bf->bf_daddr), bf->bf_desc);
324}
325
326/*
327 * Setup a h/w transmit queue for beacons.
328 *
329 * This function allocates an information structure (struct ath9k_txq_info)
330 * on the stack, sets some specific parameters (zero out channel width
331 * min/max, and enable aifs). The info structure does not need to be
332 * persistant.
333*/
334
335int ath_beaconq_setup(struct ath_hal *ah)
336{
337 struct ath9k_txq_info qi;
338
339 memzero(&qi, sizeof(qi));
340 qi.tqi_aifs = 1;
341 qi.tqi_cwmin = 0;
342 qi.tqi_cwmax = 0;
343 /* NB: don't enable any interrupts */
344 return ath9k_hw_setuptxqueue(ah, ATH9K_TX_QUEUE_BEACON, &qi);
345}
346
347
348/*
349 * Allocate and setup an initial beacon frame.
350 *
351 * Allocate a beacon state variable for a specific VAP instance created on
352 * the ATH interface. This routine also calculates the beacon "slot" for
353 * staggared beacons in the mBSSID case.
354*/
355
356int ath_beacon_alloc(struct ath_softc *sc, int if_id)
357{
358 struct ath_vap *avp;
359 struct ieee80211_hdr *wh;
360 struct ath_buf *bf;
361 struct sk_buff *skb;
362
363 avp = sc->sc_vaps[if_id];
364 ASSERT(avp);
365
366 /* Allocate a beacon descriptor if we haven't done so. */
367 if (!avp->av_bcbuf) {
368 /*
369 * Allocate beacon state for hostap/ibss. We know
370 * a buffer is available.
371 */
372
373 avp->av_bcbuf = list_first_entry(&sc->sc_bbuf,
374 struct ath_buf, list);
375 list_del(&avp->av_bcbuf->list);
376
377 if (sc->sc_opmode == ATH9K_M_HOSTAP ||
378 !sc->sc_ah->ah_caps.halVEOLSupport) {
379 int slot;
380 /*
381 * Assign the vap to a beacon xmit slot. As
382 * above, this cannot fail to find one.
383 */
384 avp->av_bslot = 0;
385 for (slot = 0; slot < ATH_BCBUF; slot++)
386 if (sc->sc_bslot[slot] == ATH_IF_ID_ANY) {
387 /*
388 * XXX hack, space out slots to better
389 * deal with misses
390 */
391 if (slot+1 < ATH_BCBUF &&
392 sc->sc_bslot[slot+1] ==
393 ATH_IF_ID_ANY) {
394 avp->av_bslot = slot+1;
395 break;
396 }
397 avp->av_bslot = slot;
398 /* NB: keep looking for a double slot */
399 }
400 BUG_ON(sc->sc_bslot[avp->av_bslot] != ATH_IF_ID_ANY);
401 sc->sc_bslot[avp->av_bslot] = if_id;
402 sc->sc_nbcnvaps++;
403 }
404 }
405
406 /* release the previous beacon frame , if it already exists. */
407 bf = avp->av_bcbuf;
408 if (bf->bf_mpdu != NULL) {
409 skb = (struct sk_buff *)bf->bf_mpdu;
410 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
411 get_dma_mem_context(bf, bf_dmacontext));
412 dev_kfree_skb_any(skb);
413 bf->bf_mpdu = NULL;
414 }
415
416 /*
417 * NB: the beacon data buffer must be 32-bit aligned;
418 * we assume the wbuf routines will return us something
419 * with this alignment (perhaps should assert).
420 * FIXME: Fill avp->av_boff.bo_tim,avp->av_btxctl.txpower and
421 * avp->av_btxctl.shortPreamble
422 */
423 skb = ieee80211_beacon_get(sc->hw, avp->av_if_data);
424 if (skb == NULL) {
425 DPRINTF(sc, ATH_DBG_BEACON, "%s: cannot get skb\n",
426 __func__);
427 return -ENOMEM;
428 }
429
430 /*
431 * Calculate a TSF adjustment factor required for
432 * staggered beacons. Note that we assume the format
433 * of the beacon frame leaves the tstamp field immediately
434 * following the header.
435 */
436 if (avp->av_bslot > 0) {
437 u64 tsfadjust;
438 __le64 val;
439 int intval;
440
441 /* FIXME: Use default value for now: Sujith */
442
443 intval = ATH_DEFAULT_BINTVAL;
444
445 /*
446 * The beacon interval is in TU's; the TSF in usecs.
447 * We figure out how many TU's to add to align the
448 * timestamp then convert to TSF units and handle
449 * byte swapping before writing it in the frame.
450 * The hardware will then add this each time a beacon
451 * frame is sent. Note that we align vap's 1..N
452 * and leave vap 0 untouched. This means vap 0
453 * has a timestamp in one beacon interval while the
454 * others get a timestamp aligned to the next interval.
455 */
456 tsfadjust = (intval * (ATH_BCBUF - avp->av_bslot)) / ATH_BCBUF;
457 val = cpu_to_le64(tsfadjust << 10); /* TU->TSF */
458
459 DPRINTF(sc, ATH_DBG_BEACON,
460 "%s: %s beacons, bslot %d intval %u tsfadjust %llu\n",
461 __func__, "stagger",
462 avp->av_bslot, intval, (unsigned long long)tsfadjust);
463
464 wh = (struct ieee80211_hdr *)skb->data;
465 memcpy(&wh[1], &val, sizeof(val));
466 }
467
468 bf->bf_buf_addr = ath_skb_map_single(sc, skb, PCI_DMA_TODEVICE,
469 get_dma_mem_context(bf, bf_dmacontext));
470 bf->bf_mpdu = skb;
471
472 return 0;
473}
474
475/*
476 * Reclaim beacon resources and return buffer to the pool.
477 *
478 * Checks the VAP to put the beacon frame buffer back to the ATH object
479 * queue, and de-allocates any wbuf frames that were sent as CAB traffic.
480*/
481
482void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp)
483{
484 if (avp->av_bcbuf != NULL) {
485 struct ath_buf *bf;
486
487 if (avp->av_bslot != -1) {
488 sc->sc_bslot[avp->av_bslot] = ATH_IF_ID_ANY;
489 sc->sc_nbcnvaps--;
490 }
491
492 bf = avp->av_bcbuf;
493 if (bf->bf_mpdu != NULL) {
494 struct sk_buff *skb = (struct sk_buff *)bf->bf_mpdu;
495 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
496 get_dma_mem_context(bf, bf_dmacontext));
497 dev_kfree_skb_any(skb);
498 bf->bf_mpdu = NULL;
499 }
500 list_add_tail(&bf->list, &sc->sc_bbuf);
501
502 avp->av_bcbuf = NULL;
503 }
504}
505
506/*
507 * Reclaim beacon resources and return buffer to the pool.
508 *
509 * This function will free any wbuf frames that are still attached to the
510 * beacon buffers in the ATH object. Note that this does not de-allocate
511 * any wbuf objects that are in the transmit queue and have not yet returned
512 * to the ATH object.
513*/
514
515void ath_beacon_free(struct ath_softc *sc)
516{
517 struct ath_buf *bf;
518
519 list_for_each_entry(bf, &sc->sc_bbuf, list) {
520 if (bf->bf_mpdu != NULL) {
521 struct sk_buff *skb = (struct sk_buff *) bf->bf_mpdu;
522 ath_skb_unmap_single(sc, skb, PCI_DMA_TODEVICE,
523 get_dma_mem_context(bf, bf_dmacontext));
524 dev_kfree_skb_any(skb);
525 bf->bf_mpdu = NULL;
526 }
527 }
528}
529
530/*
531 * Tasklet for Sending Beacons
532 *
533 * Transmit one or more beacon frames at SWBA. Dynamic updates to the frame
534 * contents are done as needed and the slot time is also adjusted based on
535 * current state.
536 *
537 * This tasklet is not scheduled, it's called in ISR context.
538*/
539
540void ath9k_beacon_tasklet(unsigned long data)
541{
542#define TSF_TO_TU(_h,_l) \
543 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
544
545 struct ath_softc *sc = (struct ath_softc *)data;
546 struct ath_hal *ah = sc->sc_ah;
547 struct ath_buf *bf = NULL;
548 int slot, if_id;
549 u32 bfaddr;
550 u32 rx_clear = 0, rx_frame = 0, tx_frame = 0;
551 u32 show_cycles = 0;
552 u32 bc = 0; /* beacon count */
553 u64 tsf;
554 u32 tsftu;
555 u16 intval;
556
557 if (sc->sc_noreset) {
558 show_cycles = ath9k_hw_GetMibCycleCountsPct(ah,
559 &rx_clear,
560 &rx_frame,
561 &tx_frame);
562 }
563
564 /*
565 * Check if the previous beacon has gone out. If
566 * not don't try to post another, skip this period
567 * and wait for the next. Missed beacons indicate
568 * a problem and should not occur. If we miss too
569 * many consecutive beacons reset the device.
570 */
571 if (ath9k_hw_numtxpending(ah, sc->sc_bhalq) != 0) {
572 sc->sc_bmisscount++;
573 /* XXX: doth needs the chanchange IE countdown decremented.
574 * We should consider adding a mac80211 call to indicate
575 * a beacon miss so appropriate action could be taken
576 * (in that layer).
577 */
578 if (sc->sc_bmisscount < BSTUCK_THRESH) {
579 if (sc->sc_noreset) {
580 DPRINTF(sc, ATH_DBG_BEACON,
581 "%s: missed %u consecutive beacons\n",
582 __func__, sc->sc_bmisscount);
583 if (show_cycles) {
584 /*
585 * Display cycle counter stats
586 * from HW to aide in debug of
587 * stickiness.
588 */
589 DPRINTF(sc,
590 ATH_DBG_BEACON,
591 "%s: busy times: rx_clear=%d, "
592 "rx_frame=%d, tx_frame=%d\n",
593 __func__, rx_clear, rx_frame,
594 tx_frame);
595 } else {
596 DPRINTF(sc,
597 ATH_DBG_BEACON,
598 "%s: unable to obtain "
599 "busy times\n", __func__);
600 }
601 } else {
602 DPRINTF(sc, ATH_DBG_BEACON,
603 "%s: missed %u consecutive beacons\n",
604 __func__, sc->sc_bmisscount);
605 }
606 } else if (sc->sc_bmisscount >= BSTUCK_THRESH) {
607 if (sc->sc_noreset) {
608 if (sc->sc_bmisscount == BSTUCK_THRESH) {
609 DPRINTF(sc,
610 ATH_DBG_BEACON,
611 "%s: beacon is officially "
612 "stuck\n", __func__);
613 ath9k_hw_dmaRegDump(ah);
614 }
615 } else {
616 DPRINTF(sc, ATH_DBG_BEACON,
617 "%s: beacon is officially stuck\n",
618 __func__);
619 ath_bstuck_process(sc);
620 }
621 }
622
623 return;
624 }
625 if (sc->sc_bmisscount != 0) {
626 if (sc->sc_noreset) {
627 DPRINTF(sc,
628 ATH_DBG_BEACON,
629 "%s: resume beacon xmit after %u misses\n",
630 __func__, sc->sc_bmisscount);
631 } else {
632 DPRINTF(sc, ATH_DBG_BEACON,
633 "%s: resume beacon xmit after %u misses\n",
634 __func__, sc->sc_bmisscount);
635 }
636 sc->sc_bmisscount = 0;
637 }
638
639 /*
640 * Generate beacon frames. we are sending frames
641 * staggered so calculate the slot for this frame based
642 * on the tsf to safeguard against missing an swba.
643 */
644
645 /* FIXME: Use default value for now - Sujith */
646 intval = ATH_DEFAULT_BINTVAL;
647
648 tsf = ath9k_hw_gettsf64(ah);
649 tsftu = TSF_TO_TU(tsf>>32, tsf);
650 slot = ((tsftu % intval) * ATH_BCBUF) / intval;
651 if_id = sc->sc_bslot[(slot + 1) % ATH_BCBUF];
652 DPRINTF(sc, ATH_DBG_BEACON,
653 "%s: slot %d [tsf %llu tsftu %u intval %u] if_id %d\n",
654 __func__, slot, (unsigned long long) tsf, tsftu,
655 intval, if_id);
656 bfaddr = 0;
657 if (if_id != ATH_IF_ID_ANY) {
658 bf = ath_beacon_generate(sc, if_id);
659 if (bf != NULL) {
660 bfaddr = bf->bf_daddr;
661 bc = 1;
662 }
663 }
664 /*
665 * Handle slot time change when a non-ERP station joins/leaves
666 * an 11g network. The 802.11 layer notifies us via callback,
667 * we mark updateslot, then wait one beacon before effecting
668 * the change. This gives associated stations at least one
669 * beacon interval to note the state change.
670 *
671 * NB: The slot time change state machine is clocked according
672 * to whether we are bursting or staggering beacons. We
673 * recognize the request to update and record the current
674 * slot then don't transition until that slot is reached
675 * again. If we miss a beacon for that slot then we'll be
676 * slow to transition but we'll be sure at least one beacon
677 * interval has passed. When bursting slot is always left
678 * set to ATH_BCBUF so this check is a noop.
679 */
680 /* XXX locking */
681 if (sc->sc_updateslot == UPDATE) {
682 sc->sc_updateslot = COMMIT; /* commit next beacon */
683 sc->sc_slotupdate = slot;
684 } else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot)
685 ath_setslottime(sc); /* commit change to hardware */
686
687 if (bfaddr != 0) {
688 /*
689 * Stop any current dma and put the new frame(s) on the queue.
690 * This should never fail since we check above that no frames
691 * are still pending on the queue.
692 */
693 if (!ath9k_hw_stoptxdma(ah, sc->sc_bhalq)) {
694 DPRINTF(sc, ATH_DBG_FATAL,
695 "%s: beacon queue %u did not stop?\n",
696 __func__, sc->sc_bhalq);
697 /* NB: the HAL still stops DMA, so proceed */
698 }
699
700 /* NB: cabq traffic should already be queued and primed */
701 ath9k_hw_puttxbuf(ah, sc->sc_bhalq, bfaddr);
702 ath9k_hw_txstart(ah, sc->sc_bhalq);
703
704 sc->ast_be_xmit += bc; /* XXX per-vap? */
705 }
706#undef TSF_TO_TU
707}
708
709/*
710 * Tasklet for Beacon Stuck processing
711 *
712 * Processing for Beacon Stuck.
713 * Basically calls the ath_internal_reset function to reset the chip.
714*/
715
716void ath_bstuck_process(struct ath_softc *sc)
717{
718 DPRINTF(sc, ATH_DBG_BEACON,
719 "%s: stuck beacon; resetting (bmiss count %u)\n",
720 __func__, sc->sc_bmisscount);
721 ath_internal_reset(sc);
722}
723
724/*
725 * Configure the beacon and sleep timers.
726 *
727 * When operating as an AP this resets the TSF and sets
728 * up the hardware to notify us when we need to issue beacons.
729 *
730 * When operating in station mode this sets up the beacon
731 * timers according to the timestamp of the last received
732 * beacon and the current TSF, configures PCF and DTIM
733 * handling, programs the sleep registers so the hardware
734 * will wakeup in time to receive beacons, and configures
735 * the beacon miss handling so we'll receive a BMISS
736 * interrupt when we stop seeing beacons from the AP
737 * we've associated with.
738 */
739
740void ath_beacon_config(struct ath_softc *sc, int if_id)
741{
742#define TSF_TO_TU(_h,_l) \
743 ((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
744 struct ath_hal *ah = sc->sc_ah;
745 u32 nexttbtt, intval;
746 struct ath_beacon_config conf;
747 enum ath9k_opmode av_opmode;
748
749 if (if_id != ATH_IF_ID_ANY)
750 av_opmode = sc->sc_vaps[if_id]->av_opmode;
751 else
752 av_opmode = sc->sc_opmode;
753
754 memzero(&conf, sizeof(struct ath_beacon_config));
755
756 /* FIXME: Use default values for now - Sujith */
757 /* Query beacon configuration first */
758 /*
759 * Protocol stack doesn't support dynamic beacon configuration,
760 * use default configurations.
761 */
762 conf.beacon_interval = ATH_DEFAULT_BINTVAL;
763 conf.listen_interval = 1;
764 conf.dtim_period = conf.beacon_interval;
765 conf.dtim_count = 1;
766 conf.bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf.beacon_interval;
767
768 /* extract tstamp from last beacon and convert to TU */
769 nexttbtt = TSF_TO_TU(get_unaligned_le32(conf.u.last_tstamp + 4),
770 get_unaligned_le32(conf.u.last_tstamp));
771 /* XXX conditionalize multi-bss support? */
772 if (sc->sc_opmode == ATH9K_M_HOSTAP) {
773 /*
774 * For multi-bss ap support beacons are either staggered
775 * evenly over N slots or burst together. For the former
776 * arrange for the SWBA to be delivered for each slot.
777 * Slots that are not occupied will generate nothing.
778 */
779 /* NB: the beacon interval is kept internally in TU's */
780 intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
781 intval /= ATH_BCBUF; /* for staggered beacons */
782 } else {
783 intval = conf.beacon_interval & ATH9K_BEACON_PERIOD;
784 }
785
786 if (nexttbtt == 0) /* e.g. for ap mode */
787 nexttbtt = intval;
788 else if (intval) /* NB: can be 0 for monitor mode */
789 nexttbtt = roundup(nexttbtt, intval);
790 DPRINTF(sc, ATH_DBG_BEACON, "%s: nexttbtt %u intval %u (%u)\n",
791 __func__, nexttbtt, intval, conf.beacon_interval);
792 /* Check for ATH9K_M_HOSTAP and sc_nostabeacons for WDS client */
793 if (sc->sc_opmode == ATH9K_M_STA) {
794 struct ath9k_beacon_state bs;
795 u64 tsf;
796 u32 tsftu;
797 int dtimperiod, dtimcount, sleepduration;
798 int cfpperiod, cfpcount;
799
800 /*
801 * Setup dtim and cfp parameters according to
802 * last beacon we received (which may be none).
803 */
804 dtimperiod = conf.dtim_period;
805 if (dtimperiod <= 0) /* NB: 0 if not known */
806 dtimperiod = 1;
807 dtimcount = conf.dtim_count;
808 if (dtimcount >= dtimperiod) /* NB: sanity check */
809 dtimcount = 0; /* XXX? */
810 cfpperiod = 1; /* NB: no PCF support yet */
811 cfpcount = 0;
812
813 sleepduration = conf.listen_interval * intval;
814 if (sleepduration <= 0)
815 sleepduration = intval;
816
817#define FUDGE 2
818 /*
819 * Pull nexttbtt forward to reflect the current
820 * TSF and calculate dtim+cfp state for the result.
821 */
822 tsf = ath9k_hw_gettsf64(ah);
823 tsftu = TSF_TO_TU(tsf>>32, tsf) + FUDGE;
824 do {
825 nexttbtt += intval;
826 if (--dtimcount < 0) {
827 dtimcount = dtimperiod - 1;
828 if (--cfpcount < 0)
829 cfpcount = cfpperiod - 1;
830 }
831 } while (nexttbtt < tsftu);
832#undef FUDGE
833 memzero(&bs, sizeof(bs));
834 bs.bs_intval = intval;
835 bs.bs_nexttbtt = nexttbtt;
836 bs.bs_dtimperiod = dtimperiod*intval;
837 bs.bs_nextdtim = bs.bs_nexttbtt + dtimcount*intval;
838 bs.bs_cfpperiod = cfpperiod*bs.bs_dtimperiod;
839 bs.bs_cfpnext = bs.bs_nextdtim + cfpcount*bs.bs_dtimperiod;
840 bs.bs_cfpmaxduration = 0;
841 /*
842 * Calculate the number of consecutive beacons to miss
843 * before taking a BMISS interrupt. The configuration
844 * is specified in TU so we only need calculate based
845 * on the beacon interval. Note that we clamp the
846 * result to at most 15 beacons.
847 */
848 if (sleepduration > intval) {
849 bs.bs_bmissthreshold =
850 conf.listen_interval *
851 ATH_DEFAULT_BMISS_LIMIT / 2;
852 } else {
853 bs.bs_bmissthreshold =
854 DIV_ROUND_UP(conf.bmiss_timeout, intval);
855 if (bs.bs_bmissthreshold > 15)
856 bs.bs_bmissthreshold = 15;
857 else if (bs.bs_bmissthreshold <= 0)
858 bs.bs_bmissthreshold = 1;
859 }
860
861 /*
862 * Calculate sleep duration. The configuration is
863 * given in ms. We insure a multiple of the beacon
864 * period is used. Also, if the sleep duration is
865 * greater than the DTIM period then it makes senses
866 * to make it a multiple of that.
867 *
868 * XXX fixed at 100ms
869 */
870
871 bs.bs_sleepduration =
872 roundup(IEEE80211_MS_TO_TU(100), sleepduration);
873 if (bs.bs_sleepduration > bs.bs_dtimperiod)
874 bs.bs_sleepduration = bs.bs_dtimperiod;
875
876 DPRINTF(sc, ATH_DBG_BEACON,
877 "%s: tsf %llu "
878 "tsf:tu %u "
879 "intval %u "
880 "nexttbtt %u "
881 "dtim %u "
882 "nextdtim %u "
883 "bmiss %u "
884 "sleep %u "
885 "cfp:period %u "
886 "maxdur %u "
887 "next %u "
888 "timoffset %u\n"
889 , __func__
890 , (unsigned long long)tsf, tsftu
891 , bs.bs_intval
892 , bs.bs_nexttbtt
893 , bs.bs_dtimperiod
894 , bs.bs_nextdtim
895 , bs.bs_bmissthreshold
896 , bs.bs_sleepduration
897 , bs.bs_cfpperiod
898 , bs.bs_cfpmaxduration
899 , bs.bs_cfpnext
900 , bs.bs_timoffset
901 );
902
903 ath9k_hw_set_interrupts(ah, 0);
904 ath9k_hw_set_sta_beacon_timers(ah, &bs);
905 sc->sc_imask |= ATH9K_INT_BMISS;
906 ath9k_hw_set_interrupts(ah, sc->sc_imask);
907 } else {
908 u64 tsf;
909 u32 tsftu;
910 ath9k_hw_set_interrupts(ah, 0);
911 if (nexttbtt == intval)
912 intval |= ATH9K_BEACON_RESET_TSF;
913 if (sc->sc_opmode == ATH9K_M_IBSS) {
914 /*
915 * Pull nexttbtt forward to reflect the current
916 * TSF .
917 */
918#define FUDGE 2
919 if (!(intval & ATH9K_BEACON_RESET_TSF)) {
920 tsf = ath9k_hw_gettsf64(ah);
921 tsftu = TSF_TO_TU((u32)(tsf>>32),
922 (u32)tsf) + FUDGE;
923 do {
924 nexttbtt += intval;
925 } while (nexttbtt < tsftu);
926 }
927#undef FUDGE
928 DPRINTF(sc, ATH_DBG_BEACON,
929 "%s: IBSS nexttbtt %u intval %u (%u)\n",
930 __func__, nexttbtt,
931 intval & ~ATH9K_BEACON_RESET_TSF,
932 conf.beacon_interval);
933
934 /*
935 * In IBSS mode enable the beacon timers but only
936 * enable SWBA interrupts if we need to manually
937 * prepare beacon frames. Otherwise we use a
938 * self-linked tx descriptor and let the hardware
939 * deal with things.
940 */
941 intval |= ATH9K_BEACON_ENA;
942 if (!ah->ah_caps.halVEOLSupport)
943 sc->sc_imask |= ATH9K_INT_SWBA;
944 ath_beaconq_config(sc);
945 } else if (sc->sc_opmode == ATH9K_M_HOSTAP) {
946 /*
947 * In AP mode we enable the beacon timers and
948 * SWBA interrupts to prepare beacon frames.
949 */
950 intval |= ATH9K_BEACON_ENA;
951 sc->sc_imask |= ATH9K_INT_SWBA; /* beacon prepare */
952 ath_beaconq_config(sc);
953 }
954 ath9k_hw_beaconinit(ah, nexttbtt, intval);
955 sc->sc_bmisscount = 0;
956 ath9k_hw_set_interrupts(ah, sc->sc_imask);
957 /*
958 * When using a self-linked beacon descriptor in
959 * ibss mode load it once here.
960 */
961 if (sc->sc_opmode == ATH9K_M_IBSS && ah->ah_caps.halVEOLSupport)
962 ath_beacon_start_adhoc(sc, 0);
963 }
964#undef TSF_TO_TU
965}
966
967/* Function to collect beacon rssi data and resync beacon if necessary */
968
969void ath_beacon_sync(struct ath_softc *sc, int if_id)
970{
971 /*
972 * Resync beacon timers using the tsf of the
973 * beacon frame we just received.
974 */
975 ath_beacon_config(sc, if_id);
976 sc->sc_beacons = 1;
977}
diff --git a/drivers/net/wireless/ath9k/core.c b/drivers/net/wireless/ath9k/core.c
new file mode 100644
index 000000000000..e8b3f1fabb31
--- /dev/null
+++ b/drivers/net/wireless/ath9k/core.c
@@ -0,0 +1,1961 @@
1/*
2 * Copyright (c) 2008, 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 /* Implementation of the main "ATH" layer. */
18
19#include "core.h"
20#include "regd.h"
21
22static int ath_outdoor; /* enable outdoor use */
23
24static const u8 ath_bcast_mac[ETH_ALEN] =
25 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
26
27static u32 ath_chainmask_sel_up_rssi_thres =
28 ATH_CHAINMASK_SEL_UP_RSSI_THRES;
29static u32 ath_chainmask_sel_down_rssi_thres =
30 ATH_CHAINMASK_SEL_DOWN_RSSI_THRES;
31static u32 ath_chainmask_sel_period =
32 ATH_CHAINMASK_SEL_TIMEOUT;
33
34/* return bus cachesize in 4B word units */
35
36static void bus_read_cachesize(struct ath_softc *sc, int *csz)
37{
38 u8 u8tmp;
39
40 pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, (u8 *)&u8tmp);
41 *csz = (int)u8tmp;
42
43 /*
44 * This check was put in to avoid "unplesant" consequences if
45 * the bootrom has not fully initialized all PCI devices.
46 * Sometimes the cache line size register is not set
47 */
48
49 if (*csz == 0)
50 *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
51}
52
53/*
54 * Set current operating mode
55 *
56 * This function initializes and fills the rate table in the ATH object based
57 * on the operating mode. The blink rates are also set up here, although
58 * they have been superceeded by the ath_led module.
59*/
60
61static void ath_setcurmode(struct ath_softc *sc, enum wireless_mode mode)
62{
63 const struct ath9k_rate_table *rt;
64 int i;
65
66 memset(sc->sc_rixmap, 0xff, sizeof(sc->sc_rixmap));
67 rt = sc->sc_rates[mode];
68 BUG_ON(!rt);
69
70 for (i = 0; i < rt->rateCount; i++)
71 sc->sc_rixmap[rt->info[i].rateCode] = (u8) i;
72
73 memzero(sc->sc_hwmap, sizeof(sc->sc_hwmap));
74 for (i = 0; i < 256; i++) {
75 u8 ix = rt->rateCodeToIndex[i];
76
77 if (ix == 0xff)
78 continue;
79
80 sc->sc_hwmap[i].ieeerate =
81 rt->info[ix].dot11Rate & IEEE80211_RATE_VAL;
82 sc->sc_hwmap[i].rateKbps = rt->info[ix].rateKbps;
83
84 if (rt->info[ix].shortPreamble ||
85 rt->info[ix].phy == PHY_OFDM) {
86 /* XXX: Handle this */
87 }
88
89 /* NB: this uses the last entry if the rate isn't found */
90 /* XXX beware of overlow */
91 }
92 sc->sc_currates = rt;
93 sc->sc_curmode = mode;
94 /*
95 * All protection frames are transmited at 2Mb/s for
96 * 11g, otherwise at 1Mb/s.
97 * XXX select protection rate index from rate table.
98 */
99 sc->sc_protrix = (mode == WIRELESS_MODE_11g ? 1 : 0);
100 /* rate index used to send mgt frames */
101 sc->sc_minrateix = 0;
102}
103
104/*
105 * Select Rate Table
106 *
107 * Based on the wireless mode passed in, the rate table in the ATH object
108 * is set to the mode specific rate table. This also calls the callback
109 * function to set the rate in the protocol layer object.
110*/
111
112static int ath_rate_setup(struct ath_softc *sc, enum wireless_mode mode)
113{
114 struct ath_hal *ah = sc->sc_ah;
115 const struct ath9k_rate_table *rt;
116
117 switch (mode) {
118 case WIRELESS_MODE_11a:
119 sc->sc_rates[mode] =
120 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11A);
121 break;
122 case WIRELESS_MODE_11b:
123 sc->sc_rates[mode] =
124 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11B);
125 break;
126 case WIRELESS_MODE_11g:
127 sc->sc_rates[mode] =
128 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11G);
129 break;
130 case WIRELESS_MODE_11NA_HT20:
131 sc->sc_rates[mode] =
132 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11NA_HT20);
133 break;
134 case WIRELESS_MODE_11NG_HT20:
135 sc->sc_rates[mode] =
136 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11NG_HT20);
137 break;
138 case WIRELESS_MODE_11NA_HT40PLUS:
139 sc->sc_rates[mode] =
140 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11NA_HT40PLUS);
141 break;
142 case WIRELESS_MODE_11NA_HT40MINUS:
143 sc->sc_rates[mode] =
144 ath9k_hw_getratetable(ah,
145 ATH9K_MODE_SEL_11NA_HT40MINUS);
146 break;
147 case WIRELESS_MODE_11NG_HT40PLUS:
148 sc->sc_rates[mode] =
149 ath9k_hw_getratetable(ah, ATH9K_MODE_SEL_11NG_HT40PLUS);
150 break;
151 case WIRELESS_MODE_11NG_HT40MINUS:
152 sc->sc_rates[mode] =
153 ath9k_hw_getratetable(ah,
154 ATH9K_MODE_SEL_11NG_HT40MINUS);
155 break;
156 default:
157 DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid mode %u\n",
158 __func__, mode);
159 return 0;
160 }
161 rt = sc->sc_rates[mode];
162 if (rt == NULL)
163 return 0;
164
165 /* setup rate set in 802.11 protocol layer */
166 ath_setup_rate(sc, mode, NORMAL_RATE, rt);
167
168 return 1;
169}
170
171/*
172 * Set up channel list
173 */
174static int ath_setup_channels(struct ath_softc *sc)
175{
176 struct ath_hal *ah = sc->sc_ah;
177 int nchan, i, a = 0, b = 0;
178 u8 regclassids[ATH_REGCLASSIDS_MAX];
179 u32 nregclass = 0;
180 struct ieee80211_supported_band *band_2ghz;
181 struct ieee80211_supported_band *band_5ghz;
182 struct ieee80211_channel *chan_2ghz;
183 struct ieee80211_channel *chan_5ghz;
184 struct ath9k_channel *c;
185
186 /* Fill in ah->ah_channels */
187 if (!ath9k_regd_init_channels(ah,
188 ATH_CHAN_MAX,
189 (u32 *)&nchan,
190 regclassids,
191 ATH_REGCLASSIDS_MAX,
192 &nregclass,
193 CTRY_DEFAULT,
194 ATH9K_MODE_SEL_ALL,
195 false,
196 1)) {
197 u32 rd = ah->ah_currentRD;
198
199 DPRINTF(sc, ATH_DBG_FATAL,
200 "%s: unable to collect channel list; "
201 "regdomain likely %u country code %u\n",
202 __func__, rd, CTRY_DEFAULT);
203 return -EINVAL;
204 }
205
206 band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ];
207 band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ];
208 chan_2ghz = sc->channels[IEEE80211_BAND_2GHZ];
209 chan_5ghz = sc->channels[IEEE80211_BAND_5GHZ];
210
211 for (i = 0; i < nchan; i++) {
212 c = &ah->ah_channels[i];
213 if (IS_CHAN_2GHZ(c)) {
214 chan_2ghz[a].band = IEEE80211_BAND_2GHZ;
215 chan_2ghz[a].center_freq = c->channel;
216 chan_2ghz[a].max_power = c->maxTxPower;
217
218 if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
219 chan_2ghz[a].flags |=
220 IEEE80211_CHAN_NO_IBSS;
221 if (c->channelFlags & CHANNEL_PASSIVE)
222 chan_2ghz[a].flags |=
223 IEEE80211_CHAN_PASSIVE_SCAN;
224
225 band_2ghz->n_channels = ++a;
226
227 DPRINTF(sc, ATH_DBG_CONFIG,
228 "%s: 2MHz channel: %d, "
229 "channelFlags: 0x%x\n",
230 __func__,
231 c->channel,
232 c->channelFlags);
233 } else if (IS_CHAN_5GHZ(c)) {
234 chan_5ghz[b].band = IEEE80211_BAND_5GHZ;
235 chan_5ghz[b].center_freq = c->channel;
236 chan_5ghz[b].max_power = c->maxTxPower;
237
238 if (c->privFlags & CHANNEL_DISALLOW_ADHOC)
239 chan_5ghz[b].flags |=
240 IEEE80211_CHAN_NO_IBSS;
241 if (c->channelFlags & CHANNEL_PASSIVE)
242 chan_5ghz[b].flags |=
243 IEEE80211_CHAN_PASSIVE_SCAN;
244
245 band_5ghz->n_channels = ++b;
246
247 DPRINTF(sc, ATH_DBG_CONFIG,
248 "%s: 5MHz channel: %d, "
249 "channelFlags: 0x%x\n",
250 __func__,
251 c->channel,
252 c->channelFlags);
253 }
254 }
255
256 return 0;
257}
258
259/*
260 * Determine mode from channel flags
261 *
262 * This routine will provide the enumerated WIRELESSS_MODE value based
263 * on the settings of the channel flags. If ho valid set of flags
264 * exist, the lowest mode (11b) is selected.
265*/
266
267static enum wireless_mode ath_chan2mode(struct ath9k_channel *chan)
268{
269 if (chan->chanmode == CHANNEL_A)
270 return WIRELESS_MODE_11a;
271 else if (chan->chanmode == CHANNEL_G)
272 return WIRELESS_MODE_11g;
273 else if (chan->chanmode == CHANNEL_B)
274 return WIRELESS_MODE_11b;
275 else if (chan->chanmode == CHANNEL_A_HT20)
276 return WIRELESS_MODE_11NA_HT20;
277 else if (chan->chanmode == CHANNEL_G_HT20)
278 return WIRELESS_MODE_11NG_HT20;
279 else if (chan->chanmode == CHANNEL_A_HT40PLUS)
280 return WIRELESS_MODE_11NA_HT40PLUS;
281 else if (chan->chanmode == CHANNEL_A_HT40MINUS)
282 return WIRELESS_MODE_11NA_HT40MINUS;
283 else if (chan->chanmode == CHANNEL_G_HT40PLUS)
284 return WIRELESS_MODE_11NG_HT40PLUS;
285 else if (chan->chanmode == CHANNEL_G_HT40MINUS)
286 return WIRELESS_MODE_11NG_HT40MINUS;
287
288 /* NB: should not get here */
289 return WIRELESS_MODE_11b;
290}
291
292/*
293 * Change Channels
294 *
295 * Performs the actions to change the channel in the hardware, and set up
296 * the current operating mode for the new channel.
297*/
298
299static void ath_chan_change(struct ath_softc *sc, struct ath9k_channel *chan)
300{
301 enum wireless_mode mode;
302
303 mode = ath_chan2mode(chan);
304
305 ath_rate_setup(sc, mode);
306 ath_setcurmode(sc, mode);
307}
308
309/*
310 * Stop the device, grabbing the top-level lock to protect
311 * against concurrent entry through ath_init (which can happen
312 * if another thread does a system call and the thread doing the
313 * stop is preempted).
314 */
315
316static int ath_stop(struct ath_softc *sc)
317{
318 struct ath_hal *ah = sc->sc_ah;
319
320 DPRINTF(sc, ATH_DBG_CONFIG, "%s: invalid %u\n",
321 __func__, sc->sc_invalid);
322
323 /*
324 * Shutdown the hardware and driver:
325 * stop output from above
326 * reset 802.11 state machine
327 * (sends station deassoc/deauth frames)
328 * turn off timers
329 * disable interrupts
330 * clear transmit machinery
331 * clear receive machinery
332 * turn off the radio
333 * reclaim beacon resources
334 *
335 * Note that some of this work is not possible if the
336 * hardware is gone (invalid).
337 */
338
339 if (!sc->sc_invalid)
340 ath9k_hw_set_interrupts(ah, 0);
341 ath_draintxq(sc, false);
342 if (!sc->sc_invalid) {
343 ath_stoprecv(sc);
344 ath9k_hw_phy_disable(ah);
345 } else
346 sc->sc_rxlink = NULL;
347
348 return 0;
349}
350
351/*
352 * Start Scan
353 *
354 * This function is called when starting a channel scan. It will perform
355 * power save wakeup processing, set the filter for the scan, and get the
356 * chip ready to send broadcast packets out during the scan.
357*/
358
359void ath_scan_start(struct ath_softc *sc)
360{
361 struct ath_hal *ah = sc->sc_ah;
362 u32 rfilt;
363 u32 now = (u32) jiffies_to_msecs(get_timestamp());
364
365 sc->sc_scanning = 1;
366 rfilt = ath_calcrxfilter(sc);
367 ath9k_hw_setrxfilter(ah, rfilt);
368 ath9k_hw_write_associd(ah, ath_bcast_mac, 0);
369
370 /* Restore previous power management state. */
371
372 DPRINTF(sc, ATH_DBG_CONFIG, "%d.%03d | %s: RX filter 0x%x aid 0\n",
373 now / 1000, now % 1000, __func__, rfilt);
374}
375
376/*
377 * Scan End
378 *
379 * This routine is called by the upper layer when the scan is completed. This
380 * will set the filters back to normal operating mode, set the BSSID to the
381 * correct value, and restore the power save state.
382*/
383
384void ath_scan_end(struct ath_softc *sc)
385{
386 struct ath_hal *ah = sc->sc_ah;
387 u32 rfilt;
388 u32 now = (u32) jiffies_to_msecs(get_timestamp());
389
390 sc->sc_scanning = 0;
391 /* Request for a full reset due to rx packet filter changes */
392 sc->sc_full_reset = 1;
393 rfilt = ath_calcrxfilter(sc);
394 ath9k_hw_setrxfilter(ah, rfilt);
395 ath9k_hw_write_associd(ah, sc->sc_curbssid, sc->sc_curaid);
396
397 DPRINTF(sc, ATH_DBG_CONFIG, "%d.%03d | %s: RX filter 0x%x aid 0x%x\n",
398 now / 1000, now % 1000, __func__, rfilt, sc->sc_curaid);
399}
400
401/*
402 * Set the current channel
403 *
404 * Set/change channels. If the channel is really being changed, it's done
405 * by reseting the chip. To accomplish this we must first cleanup any pending
406 * DMA, then restart stuff after a la ath_init.
407*/
408int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan)
409{
410 struct ath_hal *ah = sc->sc_ah;
411 bool fastcc = true, stopped;
412 enum ath9k_ht_macmode ht_macmode;
413
414 if (sc->sc_invalid) /* if the device is invalid or removed */
415 return -EIO;
416
417 DPRINTF(sc, ATH_DBG_CONFIG,
418 "%s: %u (%u MHz) -> %u (%u MHz), cflags:%x\n",
419 __func__,
420 ath9k_hw_mhz2ieee(ah, sc->sc_curchan.channel,
421 sc->sc_curchan.channelFlags),
422 sc->sc_curchan.channel,
423 ath9k_hw_mhz2ieee(ah, hchan->channel, hchan->channelFlags),
424 hchan->channel, hchan->channelFlags);
425
426 ht_macmode = ath_cwm_macmode(sc);
427
428 if (hchan->channel != sc->sc_curchan.channel ||
429 hchan->channelFlags != sc->sc_curchan.channelFlags ||
430 sc->sc_update_chainmask || sc->sc_full_reset) {
431 int status;
432 /*
433 * This is only performed if the channel settings have
434 * actually changed.
435 *
436 * To switch channels clear any pending DMA operations;
437 * wait long enough for the RX fifo to drain, reset the
438 * hardware at the new frequency, and then re-enable
439 * the relevant bits of the h/w.
440 */
441 ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
442 ath_draintxq(sc, false); /* clear pending tx frames */
443 stopped = ath_stoprecv(sc); /* turn off frame recv */
444
445 /* XXX: do not flush receive queue here. We don't want
446 * to flush data frames already in queue because of
447 * changing channel. */
448
449 if (!stopped || sc->sc_full_reset)
450 fastcc = false;
451
452 spin_lock_bh(&sc->sc_resetlock);
453 if (!ath9k_hw_reset(ah, sc->sc_opmode, hchan,
454 ht_macmode, sc->sc_tx_chainmask,
455 sc->sc_rx_chainmask,
456 sc->sc_ht_extprotspacing,
457 fastcc, &status)) {
458 DPRINTF(sc, ATH_DBG_FATAL,
459 "%s: unable to reset channel %u (%uMhz) "
460 "flags 0x%x hal status %u\n", __func__,
461 ath9k_hw_mhz2ieee(ah, hchan->channel,
462 hchan->channelFlags),
463 hchan->channel, hchan->channelFlags, status);
464 spin_unlock_bh(&sc->sc_resetlock);
465 return -EIO;
466 }
467 spin_unlock_bh(&sc->sc_resetlock);
468
469 sc->sc_curchan = *hchan;
470 sc->sc_update_chainmask = 0;
471 sc->sc_full_reset = 0;
472
473 /* Re-enable rx framework */
474 if (ath_startrecv(sc) != 0) {
475 DPRINTF(sc, ATH_DBG_FATAL,
476 "%s: unable to restart recv logic\n", __func__);
477 return -EIO;
478 }
479 /*
480 * Change channels and update the h/w rate map
481 * if we're switching; e.g. 11a to 11b/g.
482 */
483 ath_chan_change(sc, hchan);
484 ath_update_txpow(sc); /* update tx power state */
485 /*
486 * Re-enable interrupts.
487 */
488 ath9k_hw_set_interrupts(ah, sc->sc_imask);
489 }
490 return 0;
491}
492
493/**********************/
494/* Chainmask Handling */
495/**********************/
496
497static void ath_chainmask_sel_timertimeout(unsigned long data)
498{
499 struct ath_chainmask_sel *cm = (struct ath_chainmask_sel *)data;
500 cm->switch_allowed = 1;
501}
502
503/* Start chainmask select timer */
504static void ath_chainmask_sel_timerstart(struct ath_chainmask_sel *cm)
505{
506 cm->switch_allowed = 0;
507 mod_timer(&cm->timer, ath_chainmask_sel_period);
508}
509
510/* Stop chainmask select timer */
511static void ath_chainmask_sel_timerstop(struct ath_chainmask_sel *cm)
512{
513 cm->switch_allowed = 0;
514 del_timer_sync(&cm->timer);
515}
516
517static void ath_chainmask_sel_init(struct ath_softc *sc, struct ath_node *an)
518{
519 struct ath_chainmask_sel *cm = &an->an_chainmask_sel;
520
521 memzero(cm, sizeof(struct ath_chainmask_sel));
522
523 cm->cur_tx_mask = sc->sc_tx_chainmask;
524 cm->cur_rx_mask = sc->sc_rx_chainmask;
525 cm->tx_avgrssi = ATH_RSSI_DUMMY_MARKER;
526 setup_timer(&cm->timer,
527 ath_chainmask_sel_timertimeout, (unsigned long) cm);
528}
529
530int ath_chainmask_sel_logic(struct ath_softc *sc, struct ath_node *an)
531{
532 struct ath_chainmask_sel *cm = &an->an_chainmask_sel;
533
534 /*
535 * Disable auto-swtiching in one of the following if conditions.
536 * sc_chainmask_auto_sel is used for internal global auto-switching
537 * enabled/disabled setting
538 */
539 if (sc->sc_ah->ah_caps.halTxChainMask != ATH_CHAINMASK_SEL_3X3) {
540 cm->cur_tx_mask = sc->sc_tx_chainmask;
541 return cm->cur_tx_mask;
542 }
543
544 if (cm->tx_avgrssi == ATH_RSSI_DUMMY_MARKER)
545 return cm->cur_tx_mask;
546
547 if (cm->switch_allowed) {
548 /* Switch down from tx 3 to tx 2. */
549 if (cm->cur_tx_mask == ATH_CHAINMASK_SEL_3X3 &&
550 ATH_RSSI_OUT(cm->tx_avgrssi) >=
551 ath_chainmask_sel_down_rssi_thres) {
552 cm->cur_tx_mask = sc->sc_tx_chainmask;
553
554 /* Don't let another switch happen until
555 * this timer expires */
556 ath_chainmask_sel_timerstart(cm);
557 }
558 /* Switch up from tx 2 to 3. */
559 else if (cm->cur_tx_mask == sc->sc_tx_chainmask &&
560 ATH_RSSI_OUT(cm->tx_avgrssi) <=
561 ath_chainmask_sel_up_rssi_thres) {
562 cm->cur_tx_mask = ATH_CHAINMASK_SEL_3X3;
563
564 /* Don't let another switch happen
565 * until this timer expires */
566 ath_chainmask_sel_timerstart(cm);
567 }
568 }
569
570 return cm->cur_tx_mask;
571}
572
573/*
574 * Update tx/rx chainmask. For legacy association,
575 * hard code chainmask to 1x1, for 11n association, use
576 * the chainmask configuration.
577 */
578
579void ath_update_chainmask(struct ath_softc *sc, int is_ht)
580{
581 sc->sc_update_chainmask = 1;
582 if (is_ht) {
583 sc->sc_tx_chainmask = sc->sc_ah->ah_caps.halTxChainMask;
584 sc->sc_rx_chainmask = sc->sc_ah->ah_caps.halRxChainMask;
585 } else {
586 sc->sc_tx_chainmask = 1;
587 sc->sc_rx_chainmask = 1;
588 }
589
590 DPRINTF(sc, ATH_DBG_CONFIG, "%s: tx chmask: %d, rx chmask: %d\n",
591 __func__, sc->sc_tx_chainmask, sc->sc_rx_chainmask);
592}
593
594/******************/
595/* VAP management */
596/******************/
597
598/*
599 * VAP in Listen mode
600 *
601 * This routine brings the VAP out of the down state into a "listen" state
602 * where it waits for association requests. This is used in AP and AdHoc
603 * modes.
604*/
605
606int ath_vap_listen(struct ath_softc *sc, int if_id)
607{
608 struct ath_hal *ah = sc->sc_ah;
609 struct ath_vap *avp;
610 u32 rfilt = 0;
611 DECLARE_MAC_BUF(mac);
612
613 avp = sc->sc_vaps[if_id];
614 if (avp == NULL) {
615 DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid interface id %u\n",
616 __func__, if_id);
617 return -EINVAL;
618 }
619
620#ifdef CONFIG_SLOW_ANT_DIV
621 ath_slow_ant_div_stop(&sc->sc_antdiv);
622#endif
623
624 /* update ratectrl about the new state */
625 ath_rate_newstate(sc, avp);
626
627 rfilt = ath_calcrxfilter(sc);
628 ath9k_hw_setrxfilter(ah, rfilt);
629
630 if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS) {
631 memcpy(sc->sc_curbssid, ath_bcast_mac, ETH_ALEN);
632 ath9k_hw_write_associd(ah, sc->sc_curbssid, sc->sc_curaid);
633 } else
634 sc->sc_curaid = 0;
635
636 DPRINTF(sc, ATH_DBG_CONFIG,
637 "%s: RX filter 0x%x bssid %s aid 0x%x\n",
638 __func__, rfilt, print_mac(mac,
639 sc->sc_curbssid), sc->sc_curaid);
640
641 /*
642 * XXXX
643 * Disable BMISS interrupt when we're not associated
644 */
645 ath9k_hw_set_interrupts(ah,
646 sc->sc_imask & ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS));
647 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
648 /* need to reconfigure the beacons when it moves to RUN */
649 sc->sc_beacons = 0;
650
651 return 0;
652}
653
654int ath_vap_attach(struct ath_softc *sc,
655 int if_id,
656 struct ieee80211_vif *if_data,
657 enum ath9k_opmode opmode)
658{
659 struct ath_vap *avp;
660
661 if (if_id >= ATH_BCBUF || sc->sc_vaps[if_id] != NULL) {
662 DPRINTF(sc, ATH_DBG_FATAL,
663 "%s: Invalid interface id = %u\n", __func__, if_id);
664 return -EINVAL;
665 }
666
667 switch (opmode) {
668 case ATH9K_M_STA:
669 case ATH9K_M_IBSS:
670 case ATH9K_M_MONITOR:
671 break;
672 case ATH9K_M_HOSTAP:
673 /* XXX not right, beacon buffer is allocated on RUN trans */
674 if (list_empty(&sc->sc_bbuf))
675 return -ENOMEM;
676 break;
677 default:
678 return -EINVAL;
679 }
680
681 /* create ath_vap */
682 avp = kmalloc(sizeof(struct ath_vap), GFP_KERNEL);
683 if (avp == NULL)
684 return -ENOMEM;
685
686 memzero(avp, sizeof(struct ath_vap));
687 avp->av_if_data = if_data;
688 /* Set the VAP opmode */
689 avp->av_opmode = opmode;
690 avp->av_bslot = -1;
691 INIT_LIST_HEAD(&avp->av_mcastq.axq_q);
692 INIT_LIST_HEAD(&avp->av_mcastq.axq_acq);
693 spin_lock_init(&avp->av_mcastq.axq_lock);
694
695 ath9k_hw_set_tsfadjust(sc->sc_ah, 1);
696
697 sc->sc_vaps[if_id] = avp;
698 sc->sc_nvaps++;
699 /* Set the device opmode */
700 sc->sc_opmode = opmode;
701
702 /* default VAP configuration */
703 avp->av_config.av_fixed_rateset = IEEE80211_FIXED_RATE_NONE;
704 avp->av_config.av_fixed_retryset = 0x03030303;
705
706 return 0;
707}
708
709int ath_vap_detach(struct ath_softc *sc, int if_id)
710{
711 struct ath_hal *ah = sc->sc_ah;
712 struct ath_vap *avp;
713
714 avp = sc->sc_vaps[if_id];
715 if (avp == NULL) {
716 DPRINTF(sc, ATH_DBG_FATAL, "%s: invalid interface id %u\n",
717 __func__, if_id);
718 return -EINVAL;
719 }
720
721 /*
722 * Quiesce the hardware while we remove the vap. In
723 * particular we need to reclaim all references to the
724 * vap state by any frames pending on the tx queues.
725 *
726 * XXX can we do this w/o affecting other vap's?
727 */
728 ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
729 ath_draintxq(sc, false); /* stop xmit side */
730 ath_stoprecv(sc); /* stop recv side */
731 ath_flushrecv(sc); /* flush recv queue */
732
733 /* Reclaim any pending mcast bufs on the vap. */
734 ath_tx_draintxq(sc, &avp->av_mcastq, false);
735
736 kfree(avp);
737 sc->sc_vaps[if_id] = NULL;
738 sc->sc_nvaps--;
739
740 return 0;
741}
742
743int ath_vap_config(struct ath_softc *sc,
744 int if_id, struct ath_vap_config *if_config)
745{
746 struct ath_vap *avp;
747
748 if (if_id >= ATH_BCBUF) {
749 DPRINTF(sc, ATH_DBG_FATAL,
750 "%s: Invalid interface id = %u\n", __func__, if_id);
751 return -EINVAL;
752 }
753
754 avp = sc->sc_vaps[if_id];
755 ASSERT(avp != NULL);
756
757 if (avp)
758 memcpy(&avp->av_config, if_config, sizeof(avp->av_config));
759
760 return 0;
761}
762
763/********/
764/* Core */
765/********/
766
767int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan)
768{
769 struct ath_hal *ah = sc->sc_ah;
770 int status;
771 int error = 0;
772 enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
773
774 DPRINTF(sc, ATH_DBG_CONFIG, "%s: mode %d\n", __func__, sc->sc_opmode);
775
776 /*
777 * Stop anything previously setup. This is safe
778 * whether this is the first time through or not.
779 */
780 ath_stop(sc);
781
782 /* Initialize chanmask selection */
783 sc->sc_tx_chainmask = ah->ah_caps.halTxChainMask;
784 sc->sc_rx_chainmask = ah->ah_caps.halRxChainMask;
785
786 /* Reset SERDES registers */
787 ath9k_hw_configpcipowersave(ah, 0);
788
789 /*
790 * The basic interface to setting the hardware in a good
791 * state is ``reset''. On return the hardware is known to
792 * be powered up and with interrupts disabled. This must
793 * be followed by initialization of the appropriate bits
794 * and then setup of the interrupt mask.
795 */
796 sc->sc_curchan = *initial_chan;
797
798 spin_lock_bh(&sc->sc_resetlock);
799 if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan, ht_macmode,
800 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
801 sc->sc_ht_extprotspacing, false, &status)) {
802 DPRINTF(sc, ATH_DBG_FATAL,
803 "%s: unable to reset hardware; hal status %u "
804 "(freq %u flags 0x%x)\n", __func__, status,
805 sc->sc_curchan.channel, sc->sc_curchan.channelFlags);
806 error = -EIO;
807 spin_unlock_bh(&sc->sc_resetlock);
808 goto done;
809 }
810 spin_unlock_bh(&sc->sc_resetlock);
811 /*
812 * This is needed only to setup initial state
813 * but it's best done after a reset.
814 */
815 ath_update_txpow(sc);
816
817 /*
818 * Setup the hardware after reset:
819 * The receive engine is set going.
820 * Frame transmit is handled entirely
821 * in the frame output path; there's nothing to do
822 * here except setup the interrupt mask.
823 */
824 if (ath_startrecv(sc) != 0) {
825 DPRINTF(sc, ATH_DBG_FATAL,
826 "%s: unable to start recv logic\n", __func__);
827 error = -EIO;
828 goto done;
829 }
830 /* Setup our intr mask. */
831 sc->sc_imask = ATH9K_INT_RX | ATH9K_INT_TX
832 | ATH9K_INT_RXEOL | ATH9K_INT_RXORN
833 | ATH9K_INT_FATAL | ATH9K_INT_GLOBAL;
834
835 if (ah->ah_caps.halGTTSupport)
836 sc->sc_imask |= ATH9K_INT_GTT;
837
838 if (ah->ah_caps.halHTSupport)
839 sc->sc_imask |= ATH9K_INT_CST;
840
841 /*
842 * Enable MIB interrupts when there are hardware phy counters.
843 * Note we only do this (at the moment) for station mode.
844 */
845 if (ath9k_hw_phycounters(ah) &&
846 ((sc->sc_opmode == ATH9K_M_STA) || (sc->sc_opmode == ATH9K_M_IBSS)))
847 sc->sc_imask |= ATH9K_INT_MIB;
848 /*
849 * Some hardware processes the TIM IE and fires an
850 * interrupt when the TIM bit is set. For hardware
851 * that does, if not overridden by configuration,
852 * enable the TIM interrupt when operating as station.
853 */
854 if (ah->ah_caps.halEnhancedPmSupport && sc->sc_opmode == ATH9K_M_STA &&
855 !sc->sc_config.swBeaconProcess)
856 sc->sc_imask |= ATH9K_INT_TIM;
857 /*
858 * Don't enable interrupts here as we've not yet built our
859 * vap and node data structures, which will be needed as soon
860 * as we start receiving.
861 */
862 ath_chan_change(sc, initial_chan);
863
864 /* XXX: we must make sure h/w is ready and clear invalid flag
865 * before turning on interrupt. */
866 sc->sc_invalid = 0;
867done:
868 return error;
869}
870
871/*
872 * Reset the hardware w/o losing operational state. This is
873 * basically a more efficient way of doing ath_stop, ath_init,
874 * followed by state transitions to the current 802.11
875 * operational state. Used to recover from errors rx overrun
876 * and to reset the hardware when rf gain settings must be reset.
877 */
878
879static int ath_reset_start(struct ath_softc *sc, u32 flag)
880{
881 struct ath_hal *ah = sc->sc_ah;
882
883 ath9k_hw_set_interrupts(ah, 0); /* disable interrupts */
884 ath_draintxq(sc, flag & RESET_RETRY_TXQ); /* stop xmit side */
885 ath_stoprecv(sc); /* stop recv side */
886 ath_flushrecv(sc); /* flush recv queue */
887
888 return 0;
889}
890
891static int ath_reset_end(struct ath_softc *sc, u32 flag)
892{
893 struct ath_hal *ah = sc->sc_ah;
894
895 if (ath_startrecv(sc) != 0) /* restart recv */
896 DPRINTF(sc, ATH_DBG_FATAL,
897 "%s: unable to start recv logic\n", __func__);
898
899 /*
900 * We may be doing a reset in response to a request
901 * that changes the channel so update any state that
902 * might change as a result.
903 */
904 ath_chan_change(sc, &sc->sc_curchan);
905
906 ath_update_txpow(sc); /* update tx power state */
907
908 if (sc->sc_beacons)
909 ath_beacon_config(sc, ATH_IF_ID_ANY); /* restart beacons */
910 ath9k_hw_set_interrupts(ah, sc->sc_imask);
911
912 /* Restart the txq */
913 if (flag & RESET_RETRY_TXQ) {
914 int i;
915 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
916 if (ATH_TXQ_SETUP(sc, i)) {
917 spin_lock_bh(&sc->sc_txq[i].axq_lock);
918 ath_txq_schedule(sc, &sc->sc_txq[i]);
919 spin_unlock_bh(&sc->sc_txq[i].axq_lock);
920 }
921 }
922 }
923 return 0;
924}
925
926int ath_reset(struct ath_softc *sc)
927{
928 struct ath_hal *ah = sc->sc_ah;
929 int status;
930 int error = 0;
931 enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
932
933 /* NB: indicate channel change so we do a full reset */
934 spin_lock_bh(&sc->sc_resetlock);
935 if (!ath9k_hw_reset(ah, sc->sc_opmode, &sc->sc_curchan,
936 ht_macmode,
937 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
938 sc->sc_ht_extprotspacing, false, &status)) {
939 DPRINTF(sc, ATH_DBG_FATAL,
940 "%s: unable to reset hardware; hal status %u\n",
941 __func__, status);
942 error = -EIO;
943 }
944 spin_unlock_bh(&sc->sc_resetlock);
945
946 return error;
947}
948
949int ath_suspend(struct ath_softc *sc)
950{
951 struct ath_hal *ah = sc->sc_ah;
952
953 /* No I/O if device has been surprise removed */
954 if (sc->sc_invalid)
955 return -EIO;
956
957 /* Shut off the interrupt before setting sc->sc_invalid to '1' */
958 ath9k_hw_set_interrupts(ah, 0);
959
960 /* XXX: we must make sure h/w will not generate any interrupt
961 * before setting the invalid flag. */
962 sc->sc_invalid = 1;
963
964 /* disable HAL and put h/w to sleep */
965 ath9k_hw_disable(sc->sc_ah);
966
967 ath9k_hw_configpcipowersave(sc->sc_ah, 1);
968
969 return 0;
970}
971
972/* Interrupt handler. Most of the actual processing is deferred.
973 * It's the caller's responsibility to ensure the chip is awake. */
974
975irqreturn_t ath_isr(int irq, void *dev)
976{
977 struct ath_softc *sc = dev;
978 struct ath_hal *ah = sc->sc_ah;
979 enum ath9k_int status;
980 bool sched = false;
981
982 do {
983 if (sc->sc_invalid) {
984 /*
985 * The hardware is not ready/present, don't
986 * touch anything. Note this can happen early
987 * on if the IRQ is shared.
988 */
989 return IRQ_NONE;
990 }
991 if (!ath9k_hw_intrpend(ah)) { /* shared irq, not for us */
992 return IRQ_NONE;
993 }
994
995 /*
996 * Figure out the reason(s) for the interrupt. Note
997 * that the hal returns a pseudo-ISR that may include
998 * bits we haven't explicitly enabled so we mask the
999 * value to insure we only process bits we requested.
1000 */
1001 ath9k_hw_getisr(ah, &status); /* NB: clears ISR too */
1002
1003 status &= sc->sc_imask; /* discard unasked-for bits */
1004
1005 /*
1006 * If there are no status bits set, then this interrupt was not
1007 * for me (should have been caught above).
1008 */
1009
1010 if (!status)
1011 return IRQ_NONE;
1012
1013 sc->sc_intrstatus = status;
1014
1015 if (status & ATH9K_INT_FATAL) {
1016 /* need a chip reset */
1017 sched = true;
1018 } else if (status & ATH9K_INT_RXORN) {
1019 /* need a chip reset */
1020 sched = true;
1021 } else {
1022 if (status & ATH9K_INT_SWBA) {
1023 /* schedule a tasklet for beacon handling */
1024 tasklet_schedule(&sc->bcon_tasklet);
1025 }
1026 if (status & ATH9K_INT_RXEOL) {
1027 /*
1028 * NB: the hardware should re-read the link when
1029 * RXE bit is written, but it doesn't work
1030 * at least on older hardware revs.
1031 */
1032 sched = true;
1033 }
1034
1035 if (status & ATH9K_INT_TXURN)
1036 /* bump tx trigger level */
1037 ath9k_hw_updatetxtriglevel(ah, true);
1038 /* XXX: optimize this */
1039 if (status & ATH9K_INT_RX)
1040 sched = true;
1041 if (status & ATH9K_INT_TX)
1042 sched = true;
1043 if (status & ATH9K_INT_BMISS)
1044 sched = true;
1045 /* carrier sense timeout */
1046 if (status & ATH9K_INT_CST)
1047 sched = true;
1048 if (status & ATH9K_INT_MIB) {
1049 /*
1050 * Disable interrupts until we service the MIB
1051 * interrupt; otherwise it will continue to
1052 * fire.
1053 */
1054 ath9k_hw_set_interrupts(ah, 0);
1055 /*
1056 * Let the hal handle the event. We assume
1057 * it will clear whatever condition caused
1058 * the interrupt.
1059 */
1060 ath9k_hw_procmibevent(ah, &sc->sc_halstats);
1061 ath9k_hw_set_interrupts(ah, sc->sc_imask);
1062 }
1063 if (status & ATH9K_INT_TIM_TIMER) {
1064 if (!ah->ah_caps.halAutoSleepSupport) {
1065 /* Clear RxAbort bit so that we can
1066 * receive frames */
1067 ath9k_hw_setrxabort(ah, 0);
1068 sched = true;
1069 }
1070 }
1071 }
1072 } while (0);
1073
1074 if (sched) {
1075 /* turn off every interrupt except SWBA */
1076 ath9k_hw_set_interrupts(ah, (sc->sc_imask & ATH9K_INT_SWBA));
1077 tasklet_schedule(&sc->intr_tq);
1078 }
1079
1080 return IRQ_HANDLED;
1081}
1082
1083/* Deferred interrupt processing */
1084
1085static void ath9k_tasklet(unsigned long data)
1086{
1087 struct ath_softc *sc = (struct ath_softc *)data;
1088 u32 status = sc->sc_intrstatus;
1089
1090 if (status & ATH9K_INT_FATAL) {
1091 /* need a chip reset */
1092 ath_internal_reset(sc);
1093 return;
1094 } else {
1095
1096 if (status &
1097 (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN)) {
1098 /* XXX: fill me in */
1099 /*
1100 if (status & ATH9K_INT_RXORN) {
1101 }
1102 if (status & ATH9K_INT_RXEOL) {
1103 }
1104 */
1105 spin_lock_bh(&sc->sc_rxflushlock);
1106 ath_rx_tasklet(sc, 0);
1107 spin_unlock_bh(&sc->sc_rxflushlock);
1108 }
1109 /* XXX: optimize this */
1110 if (status & ATH9K_INT_TX)
1111 ath_tx_tasklet(sc);
1112 /* XXX: fill me in */
1113 /*
1114 if (status & ATH9K_INT_BMISS) {
1115 }
1116 if (status & (ATH9K_INT_TIM | ATH9K_INT_DTIMSYNC)) {
1117 if (status & ATH9K_INT_TIM) {
1118 }
1119 if (status & ATH9K_INT_DTIMSYNC) {
1120 }
1121 }
1122 */
1123 }
1124
1125 /* re-enable hardware interrupt */
1126 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask);
1127}
1128
1129int ath_init(u16 devid, struct ath_softc *sc)
1130{
1131 struct ath_hal *ah = NULL;
1132 int status;
1133 int error = 0, i;
1134 int csz = 0;
1135 u32 rd;
1136
1137 /* XXX: hardware will not be ready until ath_open() being called */
1138 sc->sc_invalid = 1;
1139
1140 sc->sc_debug = DBG_DEFAULT;
1141 DPRINTF(sc, ATH_DBG_CONFIG, "%s: devid 0x%x\n", __func__, devid);
1142
1143 /* Initialize tasklet */
1144 tasklet_init(&sc->intr_tq, ath9k_tasklet, (unsigned long)sc);
1145 tasklet_init(&sc->bcon_tasklet, ath9k_beacon_tasklet,
1146 (unsigned long)sc);
1147
1148 /*
1149 * Cache line size is used to size and align various
1150 * structures used to communicate with the hardware.
1151 */
1152 bus_read_cachesize(sc, &csz);
1153 /* XXX assert csz is non-zero */
1154 sc->sc_cachelsz = csz << 2; /* convert to bytes */
1155
1156 spin_lock_init(&sc->sc_resetlock);
1157
1158 ah = ath9k_hw_attach(devid, sc, sc->mem, &status);
1159 if (ah == NULL) {
1160 DPRINTF(sc, ATH_DBG_FATAL,
1161 "%s: unable to attach hardware; HAL status %u\n",
1162 __func__, status);
1163 error = -ENXIO;
1164 goto bad;
1165 }
1166 sc->sc_ah = ah;
1167
1168 /* Get the chipset-specific aggr limit. */
1169 sc->sc_rtsaggrlimit = ah->ah_caps.halRtsAggrLimit;
1170
1171 /* Get the hardware key cache size. */
1172 sc->sc_keymax = ah->ah_caps.halKeyCacheSize;
1173 if (sc->sc_keymax > ATH_KEYMAX) {
1174 DPRINTF(sc, ATH_DBG_KEYCACHE,
1175 "%s: Warning, using only %u entries in %u key cache\n",
1176 __func__, ATH_KEYMAX, sc->sc_keymax);
1177 sc->sc_keymax = ATH_KEYMAX;
1178 }
1179
1180 /*
1181 * Reset the key cache since some parts do not
1182 * reset the contents on initial power up.
1183 */
1184 for (i = 0; i < sc->sc_keymax; i++)
1185 ath9k_hw_keyreset(ah, (u16) i);
1186 /*
1187 * Mark key cache slots associated with global keys
1188 * as in use. If we knew TKIP was not to be used we
1189 * could leave the +32, +64, and +32+64 slots free.
1190 * XXX only for splitmic.
1191 */
1192 for (i = 0; i < IEEE80211_WEP_NKID; i++) {
1193 set_bit(i, sc->sc_keymap);
1194 set_bit(i + 32, sc->sc_keymap);
1195 set_bit(i + 64, sc->sc_keymap);
1196 set_bit(i + 32 + 64, sc->sc_keymap);
1197 }
1198 /*
1199 * Collect the channel list using the default country
1200 * code and including outdoor channels. The 802.11 layer
1201 * is resposible for filtering this list based on settings
1202 * like the phy mode.
1203 */
1204 rd = ah->ah_currentRD;
1205
1206 error = ath_setup_channels(sc);
1207 if (error)
1208 goto bad;
1209
1210 /* default to STA mode */
1211 sc->sc_opmode = ATH9K_M_MONITOR;
1212
1213 /* Setup rate tables for all potential media types. */
1214 /* 11g encompasses b,g */
1215
1216 ath_rate_setup(sc, WIRELESS_MODE_11a);
1217 ath_rate_setup(sc, WIRELESS_MODE_11g);
1218
1219 /* NB: setup here so ath_rate_update is happy */
1220 ath_setcurmode(sc, WIRELESS_MODE_11a);
1221
1222 /*
1223 * Allocate hardware transmit queues: one queue for
1224 * beacon frames and one data queue for each QoS
1225 * priority. Note that the hal handles reseting
1226 * these queues at the needed time.
1227 */
1228 sc->sc_bhalq = ath_beaconq_setup(ah);
1229 if (sc->sc_bhalq == -1) {
1230 DPRINTF(sc, ATH_DBG_FATAL,
1231 "%s: unable to setup a beacon xmit queue\n", __func__);
1232 error = -EIO;
1233 goto bad2;
1234 }
1235 sc->sc_cabq = ath_txq_setup(sc, ATH9K_TX_QUEUE_CAB, 0);
1236 if (sc->sc_cabq == NULL) {
1237 DPRINTF(sc, ATH_DBG_FATAL,
1238 "%s: unable to setup CAB xmit queue\n", __func__);
1239 error = -EIO;
1240 goto bad2;
1241 }
1242
1243 sc->sc_config.cabqReadytime = ATH_CABQ_READY_TIME;
1244 ath_cabq_update(sc);
1245
1246 for (i = 0; i < ARRAY_SIZE(sc->sc_haltype2q); i++)
1247 sc->sc_haltype2q[i] = -1;
1248
1249 /* Setup data queues */
1250 /* NB: ensure BK queue is the lowest priority h/w queue */
1251 if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
1252 DPRINTF(sc, ATH_DBG_FATAL,
1253 "%s: unable to setup xmit queue for BK traffic\n",
1254 __func__);
1255 error = -EIO;
1256 goto bad2;
1257 }
1258
1259 if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
1260 DPRINTF(sc, ATH_DBG_FATAL,
1261 "%s: unable to setup xmit queue for BE traffic\n",
1262 __func__);
1263 error = -EIO;
1264 goto bad2;
1265 }
1266 if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
1267 DPRINTF(sc, ATH_DBG_FATAL,
1268 "%s: unable to setup xmit queue for VI traffic\n",
1269 __func__);
1270 error = -EIO;
1271 goto bad2;
1272 }
1273 if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
1274 DPRINTF(sc, ATH_DBG_FATAL,
1275 "%s: unable to setup xmit queue for VO traffic\n",
1276 __func__);
1277 error = -EIO;
1278 goto bad2;
1279 }
1280
1281 sc->sc_rc = ath_rate_attach(ah);
1282 if (sc->sc_rc == NULL) {
1283 error = EIO;
1284 goto bad2;
1285 }
1286
1287 if (ath9k_hw_getcapability(ah, HAL_CAP_CIPHER,
1288 ATH9K_CIPHER_TKIP, NULL)) {
1289 /*
1290 * Whether we should enable h/w TKIP MIC.
1291 * XXX: if we don't support WME TKIP MIC, then we wouldn't
1292 * report WMM capable, so it's always safe to turn on
1293 * TKIP MIC in this case.
1294 */
1295 ath9k_hw_setcapability(sc->sc_ah, HAL_CAP_TKIP_MIC, 0, 1, NULL);
1296 }
1297
1298 /*
1299 * Check whether the separate key cache entries
1300 * are required to handle both tx+rx MIC keys.
1301 * With split mic keys the number of stations is limited
1302 * to 27 otherwise 59.
1303 */
1304 if (ath9k_hw_getcapability(ah, HAL_CAP_CIPHER,
1305 ATH9K_CIPHER_TKIP, NULL)
1306 && ath9k_hw_getcapability(ah, HAL_CAP_CIPHER,
1307 ATH9K_CIPHER_MIC, NULL)
1308 && ath9k_hw_getcapability(ah, HAL_CAP_TKIP_SPLIT,
1309 0, NULL))
1310 sc->sc_splitmic = 1;
1311
1312 /* turn on mcast key search if possible */
1313 if (!ath9k_hw_getcapability(ah, HAL_CAP_MCAST_KEYSRCH, 0, NULL))
1314 (void)ath9k_hw_setcapability(ah, HAL_CAP_MCAST_KEYSRCH, 1,
1315 1, NULL);
1316
1317 sc->sc_config.txpowlimit = ATH_TXPOWER_MAX;
1318 sc->sc_config.txpowlimit_override = 0;
1319
1320 /* 11n Capabilities */
1321 if (ah->ah_caps.halHTSupport) {
1322 sc->sc_txaggr = 1;
1323 sc->sc_rxaggr = 1;
1324 }
1325
1326 sc->sc_tx_chainmask = ah->ah_caps.halTxChainMask;
1327 sc->sc_rx_chainmask = ah->ah_caps.halRxChainMask;
1328
1329 /* Configuration for rx chain detection */
1330 sc->sc_rxchaindetect_ref = 0;
1331 sc->sc_rxchaindetect_thresh5GHz = 35;
1332 sc->sc_rxchaindetect_thresh2GHz = 35;
1333 sc->sc_rxchaindetect_delta5GHz = 30;
1334 sc->sc_rxchaindetect_delta2GHz = 30;
1335
1336 ath9k_hw_setcapability(ah, HAL_CAP_DIVERSITY, 1, true, NULL);
1337 sc->sc_defant = ath9k_hw_getdefantenna(ah);
1338
1339 ath9k_hw_getmac(ah, sc->sc_myaddr);
1340 if (ah->ah_caps.halBssIdMaskSupport) {
1341 ath9k_hw_getbssidmask(ah, sc->sc_bssidmask);
1342 ATH_SET_VAP_BSSID_MASK(sc->sc_bssidmask);
1343 ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
1344 }
1345 sc->sc_slottime = ATH9K_SLOT_TIME_9; /* default to short slot time */
1346
1347 /* initialize beacon slots */
1348 for (i = 0; i < ARRAY_SIZE(sc->sc_bslot); i++)
1349 sc->sc_bslot[i] = ATH_IF_ID_ANY;
1350
1351 /* save MISC configurations */
1352 sc->sc_config.swBeaconProcess = 1;
1353
1354#ifdef CONFIG_SLOW_ANT_DIV
1355 /* range is 40 - 255, we use something in the middle */
1356 ath_slow_ant_div_init(&sc->sc_antdiv, sc, 0x127);
1357#endif
1358
1359 return 0;
1360bad2:
1361 /* cleanup tx queues */
1362 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1363 if (ATH_TXQ_SETUP(sc, i))
1364 ath_tx_cleanupq(sc, &sc->sc_txq[i]);
1365bad:
1366 if (ah)
1367 ath9k_hw_detach(ah);
1368 return error;
1369}
1370
1371void ath_deinit(struct ath_softc *sc)
1372{
1373 struct ath_hal *ah = sc->sc_ah;
1374 int i;
1375
1376 DPRINTF(sc, ATH_DBG_CONFIG, "%s\n", __func__);
1377
1378 ath_stop(sc);
1379 if (!sc->sc_invalid)
1380 ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_AWAKE);
1381 ath_rate_detach(sc->sc_rc);
1382 /* cleanup tx queues */
1383 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
1384 if (ATH_TXQ_SETUP(sc, i))
1385 ath_tx_cleanupq(sc, &sc->sc_txq[i]);
1386 ath9k_hw_detach(ah);
1387}
1388
1389/*******************/
1390/* Node Management */
1391/*******************/
1392
1393struct ath_node *ath_node_attach(struct ath_softc *sc, u8 *addr, int if_id)
1394{
1395 struct ath_vap *avp;
1396 struct ath_node *an;
1397 DECLARE_MAC_BUF(mac);
1398
1399 avp = sc->sc_vaps[if_id];
1400 ASSERT(avp != NULL);
1401
1402 /* mac80211 sta_notify callback is from an IRQ context, so no sleep */
1403 an = kmalloc(sizeof(struct ath_node), GFP_ATOMIC);
1404 if (an == NULL)
1405 return NULL;
1406 memzero(an, sizeof(*an));
1407
1408 an->an_sc = sc;
1409 memcpy(an->an_addr, addr, ETH_ALEN);
1410 atomic_set(&an->an_refcnt, 1);
1411
1412 /* set up per-node tx/rx state */
1413 ath_tx_node_init(sc, an);
1414 ath_rx_node_init(sc, an);
1415
1416 ath_chainmask_sel_init(sc, an);
1417 ath_chainmask_sel_timerstart(&an->an_chainmask_sel);
1418 list_add(&an->list, &sc->node_list);
1419
1420 return an;
1421}
1422
1423void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag)
1424{
1425 unsigned long flags;
1426
1427 DECLARE_MAC_BUF(mac);
1428
1429 ath_chainmask_sel_timerstop(&an->an_chainmask_sel);
1430 an->an_flags |= ATH_NODE_CLEAN;
1431 ath_tx_node_cleanup(sc, an, bh_flag);
1432 ath_rx_node_cleanup(sc, an);
1433
1434 ath_tx_node_free(sc, an);
1435 ath_rx_node_free(sc, an);
1436
1437 spin_lock_irqsave(&sc->node_lock, flags);
1438
1439 list_del(&an->list);
1440
1441 spin_unlock_irqrestore(&sc->node_lock, flags);
1442
1443 kfree(an);
1444}
1445
1446/* Finds a node and increases the refcnt if found */
1447
1448struct ath_node *ath_node_get(struct ath_softc *sc, u8 *addr)
1449{
1450 struct ath_node *an = NULL, *an_found = NULL;
1451
1452 if (list_empty(&sc->node_list)) /* FIXME */
1453 goto out;
1454 list_for_each_entry(an, &sc->node_list, list) {
1455 if (!compare_ether_addr(an->an_addr, addr)) {
1456 atomic_inc(&an->an_refcnt);
1457 an_found = an;
1458 break;
1459 }
1460 }
1461out:
1462 return an_found;
1463}
1464
1465/* Decrements the refcnt and if it drops to zero, detach the node */
1466
1467void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag)
1468{
1469 if (atomic_dec_and_test(&an->an_refcnt))
1470 ath_node_detach(sc, an, bh_flag);
1471}
1472
1473/* Finds a node, doesn't increment refcnt. Caller must hold sc->node_lock */
1474struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr)
1475{
1476 struct ath_node *an = NULL, *an_found = NULL;
1477
1478 if (list_empty(&sc->node_list))
1479 return NULL;
1480
1481 list_for_each_entry(an, &sc->node_list, list)
1482 if (!compare_ether_addr(an->an_addr, addr)) {
1483 an_found = an;
1484 break;
1485 }
1486
1487 return an_found;
1488}
1489
1490/*
1491 * Set up New Node
1492 *
1493 * Setup driver-specific state for a newly associated node. This routine
1494 * really only applies if compression or XR are enabled, there is no code
1495 * covering any other cases.
1496*/
1497
1498void ath_newassoc(struct ath_softc *sc,
1499 struct ath_node *an, int isnew, int isuapsd)
1500{
1501 int tidno;
1502
1503 /* if station reassociates, tear down the aggregation state. */
1504 if (!isnew) {
1505 for (tidno = 0; tidno < WME_NUM_TID; tidno++) {
1506 if (sc->sc_txaggr)
1507 ath_tx_aggr_teardown(sc, an, tidno);
1508 if (sc->sc_rxaggr)
1509 ath_rx_aggr_teardown(sc, an, tidno);
1510 }
1511 }
1512 an->an_flags = 0;
1513}
1514
1515/**************/
1516/* Encryption */
1517/**************/
1518
1519void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot)
1520{
1521 ath9k_hw_keyreset(sc->sc_ah, keyix);
1522 if (freeslot)
1523 clear_bit(keyix, sc->sc_keymap);
1524}
1525
1526int ath_keyset(struct ath_softc *sc,
1527 u16 keyix,
1528 struct ath9k_keyval *hk,
1529 const u8 mac[ETH_ALEN])
1530{
1531 bool status;
1532
1533 status = ath9k_hw_set_keycache_entry(sc->sc_ah,
1534 keyix, hk, mac, false);
1535
1536 return status != false;
1537}
1538
1539/***********************/
1540/* TX Power/Regulatory */
1541/***********************/
1542
1543/*
1544 * Set Transmit power in HAL
1545 *
1546 * This routine makes the actual HAL calls to set the new transmit power
1547 * limit.
1548*/
1549
1550void ath_update_txpow(struct ath_softc *sc)
1551{
1552 struct ath_hal *ah = sc->sc_ah;
1553 u32 txpow;
1554
1555 if (sc->sc_curtxpow != sc->sc_config.txpowlimit) {
1556 ath9k_hw_set_txpowerlimit(ah, sc->sc_config.txpowlimit);
1557 /* read back in case value is clamped */
1558 ath9k_hw_getcapability(ah, HAL_CAP_TXPOW, 1, &txpow);
1559 sc->sc_curtxpow = txpow;
1560 }
1561}
1562
1563/* Return the current country and domain information */
1564void ath_get_currentCountry(struct ath_softc *sc,
1565 struct ath9k_country_entry *ctry)
1566{
1567 ath9k_regd_get_current_country(sc->sc_ah, ctry);
1568
1569 /* If HAL not specific yet, since it is band dependent,
1570 * use the one we passed in. */
1571 if (ctry->countryCode == CTRY_DEFAULT) {
1572 ctry->iso[0] = 0;
1573 ctry->iso[1] = 0;
1574 } else if (ctry->iso[0] && ctry->iso[1]) {
1575 if (!ctry->iso[2]) {
1576 if (ath_outdoor)
1577 ctry->iso[2] = 'O';
1578 else
1579 ctry->iso[2] = 'I';
1580 }
1581 }
1582}
1583
1584/**************************/
1585/* Slow Antenna Diversity */
1586/**************************/
1587
1588void ath_slow_ant_div_init(struct ath_antdiv *antdiv,
1589 struct ath_softc *sc,
1590 int32_t rssitrig)
1591{
1592 int trig;
1593
1594 /* antdivf_rssitrig can range from 40 - 0xff */
1595 trig = (rssitrig > 0xff) ? 0xff : rssitrig;
1596 trig = (rssitrig < 40) ? 40 : rssitrig;
1597
1598 antdiv->antdiv_sc = sc;
1599 antdiv->antdivf_rssitrig = trig;
1600}
1601
1602void ath_slow_ant_div_start(struct ath_antdiv *antdiv,
1603 u8 num_antcfg,
1604 const u8 *bssid)
1605{
1606 antdiv->antdiv_num_antcfg =
1607 num_antcfg < ATH_ANT_DIV_MAX_CFG ?
1608 num_antcfg : ATH_ANT_DIV_MAX_CFG;
1609 antdiv->antdiv_state = ATH_ANT_DIV_IDLE;
1610 antdiv->antdiv_curcfg = 0;
1611 antdiv->antdiv_bestcfg = 0;
1612 antdiv->antdiv_laststatetsf = 0;
1613
1614 memcpy(antdiv->antdiv_bssid, bssid, sizeof(antdiv->antdiv_bssid));
1615
1616 antdiv->antdiv_start = 1;
1617}
1618
1619void ath_slow_ant_div_stop(struct ath_antdiv *antdiv)
1620{
1621 antdiv->antdiv_start = 0;
1622}
1623
1624static int32_t ath_find_max_val(int32_t *val,
1625 u8 num_val, u8 *max_index)
1626{
1627 u32 MaxVal = *val++;
1628 u32 cur_index = 0;
1629
1630 *max_index = 0;
1631 while (++cur_index < num_val) {
1632 if (*val > MaxVal) {
1633 MaxVal = *val;
1634 *max_index = cur_index;
1635 }
1636
1637 val++;
1638 }
1639
1640 return MaxVal;
1641}
1642
1643void ath_slow_ant_div(struct ath_antdiv *antdiv,
1644 struct ieee80211_hdr *hdr,
1645 struct ath_rx_status *rx_stats)
1646{
1647 struct ath_softc *sc = antdiv->antdiv_sc;
1648 struct ath_hal *ah = sc->sc_ah;
1649 u64 curtsf = 0;
1650 u8 bestcfg, curcfg = antdiv->antdiv_curcfg;
1651 __le16 fc = hdr->frame_control;
1652
1653 if (antdiv->antdiv_start && ieee80211_is_beacon(fc)
1654 && !compare_ether_addr(hdr->addr3, antdiv->antdiv_bssid)) {
1655 antdiv->antdiv_lastbrssi[curcfg] = rx_stats->rs_rssi;
1656 antdiv->antdiv_lastbtsf[curcfg] = ath9k_hw_gettsf64(sc->sc_ah);
1657 curtsf = antdiv->antdiv_lastbtsf[curcfg];
1658 } else {
1659 return;
1660 }
1661
1662 switch (antdiv->antdiv_state) {
1663 case ATH_ANT_DIV_IDLE:
1664 if ((antdiv->antdiv_lastbrssi[curcfg] <
1665 antdiv->antdivf_rssitrig)
1666 && ((curtsf - antdiv->antdiv_laststatetsf) >
1667 ATH_ANT_DIV_MIN_IDLE_US)) {
1668
1669 curcfg++;
1670 if (curcfg == antdiv->antdiv_num_antcfg)
1671 curcfg = 0;
1672
1673 if (!ath9k_hw_select_antconfig(ah, curcfg)) {
1674 antdiv->antdiv_bestcfg = antdiv->antdiv_curcfg;
1675 antdiv->antdiv_curcfg = curcfg;
1676 antdiv->antdiv_laststatetsf = curtsf;
1677 antdiv->antdiv_state = ATH_ANT_DIV_SCAN;
1678 }
1679 }
1680 break;
1681
1682 case ATH_ANT_DIV_SCAN:
1683 if ((curtsf - antdiv->antdiv_laststatetsf) <
1684 ATH_ANT_DIV_MIN_SCAN_US)
1685 break;
1686
1687 curcfg++;
1688 if (curcfg == antdiv->antdiv_num_antcfg)
1689 curcfg = 0;
1690
1691 if (curcfg == antdiv->antdiv_bestcfg) {
1692 ath_find_max_val(antdiv->antdiv_lastbrssi,
1693 antdiv->antdiv_num_antcfg, &bestcfg);
1694 if (!ath9k_hw_select_antconfig(ah, bestcfg)) {
1695 antdiv->antdiv_bestcfg = bestcfg;
1696 antdiv->antdiv_curcfg = bestcfg;
1697 antdiv->antdiv_laststatetsf = curtsf;
1698 antdiv->antdiv_state = ATH_ANT_DIV_IDLE;
1699 }
1700 } else {
1701 if (!ath9k_hw_select_antconfig(ah, curcfg)) {
1702 antdiv->antdiv_curcfg = curcfg;
1703 antdiv->antdiv_laststatetsf = curtsf;
1704 antdiv->antdiv_state = ATH_ANT_DIV_SCAN;
1705 }
1706 }
1707
1708 break;
1709 }
1710}
1711
1712/***********************/
1713/* Descriptor Handling */
1714/***********************/
1715
1716/*
1717 * Set up DMA descriptors
1718 *
1719 * This function will allocate both the DMA descriptor structure, and the
1720 * buffers it contains. These are used to contain the descriptors used
1721 * by the system.
1722*/
1723
1724int ath_descdma_setup(struct ath_softc *sc,
1725 struct ath_descdma *dd,
1726 struct list_head *head,
1727 const char *name,
1728 int nbuf,
1729 int ndesc)
1730{
1731#define DS2PHYS(_dd, _ds) \
1732 ((_dd)->dd_desc_paddr + ((caddr_t)(_ds) - (caddr_t)(_dd)->dd_desc))
1733#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF7F) ? 1 : 0)
1734#define ATH_DESC_4KB_BOUND_NUM_SKIPPED(_len) ((_len) / 4096)
1735
1736 struct ath_desc *ds;
1737 struct ath_buf *bf;
1738 int i, bsize, error;
1739
1740 DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA: %u buffers %u desc/buf\n",
1741 __func__, name, nbuf, ndesc);
1742
1743 /* ath_desc must be a multiple of DWORDs */
1744 if ((sizeof(struct ath_desc) % 4) != 0) {
1745 DPRINTF(sc, ATH_DBG_FATAL, "%s: ath_desc not DWORD aligned\n",
1746 __func__);
1747 ASSERT((sizeof(struct ath_desc) % 4) == 0);
1748 error = -ENOMEM;
1749 goto fail;
1750 }
1751
1752 dd->dd_name = name;
1753 dd->dd_desc_len = sizeof(struct ath_desc) * nbuf * ndesc;
1754
1755 /*
1756 * Need additional DMA memory because we can't use
1757 * descriptors that cross the 4K page boundary. Assume
1758 * one skipped descriptor per 4K page.
1759 */
1760 if (!(sc->sc_ah->ah_caps.hal4kbSplitTransSupport)) {
1761 u32 ndesc_skipped =
1762 ATH_DESC_4KB_BOUND_NUM_SKIPPED(dd->dd_desc_len);
1763 u32 dma_len;
1764
1765 while (ndesc_skipped) {
1766 dma_len = ndesc_skipped * sizeof(struct ath_desc);
1767 dd->dd_desc_len += dma_len;
1768
1769 ndesc_skipped = ATH_DESC_4KB_BOUND_NUM_SKIPPED(dma_len);
1770 };
1771 }
1772
1773 /* allocate descriptors */
1774 dd->dd_desc = pci_alloc_consistent(sc->pdev,
1775 dd->dd_desc_len,
1776 &dd->dd_desc_paddr);
1777 if (dd->dd_desc == NULL) {
1778 error = -ENOMEM;
1779 goto fail;
1780 }
1781 ds = dd->dd_desc;
1782 DPRINTF(sc, ATH_DBG_CONFIG, "%s: %s DMA map: %p (%u) -> %llx (%u)\n",
1783 __func__, dd->dd_name, ds, (u32) dd->dd_desc_len,
1784 ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
1785
1786 /* allocate buffers */
1787 bsize = sizeof(struct ath_buf) * nbuf;
1788 bf = kmalloc(bsize, GFP_KERNEL);
1789 if (bf == NULL) {
1790 error = -ENOMEM;
1791 goto fail2;
1792 }
1793 memzero(bf, bsize);
1794 dd->dd_bufptr = bf;
1795
1796 INIT_LIST_HEAD(head);
1797 for (i = 0; i < nbuf; i++, bf++, ds += ndesc) {
1798 bf->bf_desc = ds;
1799 bf->bf_daddr = DS2PHYS(dd, ds);
1800
1801 if (!(sc->sc_ah->ah_caps.hal4kbSplitTransSupport)) {
1802 /*
1803 * Skip descriptor addresses which can cause 4KB
1804 * boundary crossing (addr + length) with a 32 dword
1805 * descriptor fetch.
1806 */
1807 while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
1808 ASSERT((caddr_t) bf->bf_desc <
1809 ((caddr_t) dd->dd_desc +
1810 dd->dd_desc_len));
1811
1812 ds += ndesc;
1813 bf->bf_desc = ds;
1814 bf->bf_daddr = DS2PHYS(dd, ds);
1815 }
1816 }
1817 list_add_tail(&bf->list, head);
1818 }
1819 return 0;
1820fail2:
1821 pci_free_consistent(sc->pdev,
1822 dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
1823fail:
1824 memzero(dd, sizeof(*dd));
1825 return error;
1826#undef ATH_DESC_4KB_BOUND_CHECK
1827#undef ATH_DESC_4KB_BOUND_NUM_SKIPPED
1828#undef DS2PHYS
1829}
1830
1831/*
1832 * Cleanup DMA descriptors
1833 *
1834 * This function will free the DMA block that was allocated for the descriptor
1835 * pool. Since this was allocated as one "chunk", it is freed in the same
1836 * manner.
1837*/
1838
1839void ath_descdma_cleanup(struct ath_softc *sc,
1840 struct ath_descdma *dd,
1841 struct list_head *head)
1842{
1843 /* Free memory associated with descriptors */
1844 pci_free_consistent(sc->pdev,
1845 dd->dd_desc_len, dd->dd_desc, dd->dd_desc_paddr);
1846
1847 INIT_LIST_HEAD(head);
1848 kfree(dd->dd_bufptr);
1849 memzero(dd, sizeof(*dd));
1850}
1851
1852/*************/
1853/* Utilities */
1854/*************/
1855
1856void ath_internal_reset(struct ath_softc *sc)
1857{
1858 ath_reset_start(sc, 0);
1859 ath_reset(sc);
1860 ath_reset_end(sc, 0);
1861}
1862
1863int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
1864{
1865 int qnum;
1866
1867 switch (queue) {
1868 case 0:
1869 qnum = sc->sc_haltype2q[ATH9K_WME_AC_VO];
1870 break;
1871 case 1:
1872 qnum = sc->sc_haltype2q[ATH9K_WME_AC_VI];
1873 break;
1874 case 2:
1875 qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
1876 break;
1877 case 3:
1878 qnum = sc->sc_haltype2q[ATH9K_WME_AC_BK];
1879 break;
1880 default:
1881 qnum = sc->sc_haltype2q[ATH9K_WME_AC_BE];
1882 break;
1883 }
1884
1885 return qnum;
1886}
1887
1888int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc)
1889{
1890 int qnum;
1891
1892 switch (queue) {
1893 case ATH9K_WME_AC_VO:
1894 qnum = 0;
1895 break;
1896 case ATH9K_WME_AC_VI:
1897 qnum = 1;
1898 break;
1899 case ATH9K_WME_AC_BE:
1900 qnum = 2;
1901 break;
1902 case ATH9K_WME_AC_BK:
1903 qnum = 3;
1904 break;
1905 default:
1906 qnum = -1;
1907 break;
1908 }
1909
1910 return qnum;
1911}
1912
1913
1914/*
1915 * Expand time stamp to TSF
1916 *
1917 * Extend 15-bit time stamp from rx descriptor to
1918 * a full 64-bit TSF using the current h/w TSF.
1919*/
1920
1921u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp)
1922{
1923 u64 tsf;
1924
1925 tsf = ath9k_hw_gettsf64(sc->sc_ah);
1926 if ((tsf & 0x7fff) < rstamp)
1927 tsf -= 0x8000;
1928 return (tsf & ~0x7fff) | rstamp;
1929}
1930
1931/*
1932 * Set Default Antenna
1933 *
1934 * Call into the HAL to set the default antenna to use. Not really valid for
1935 * MIMO technology.
1936*/
1937
1938void ath_setdefantenna(void *context, u32 antenna)
1939{
1940 struct ath_softc *sc = (struct ath_softc *)context;
1941 struct ath_hal *ah = sc->sc_ah;
1942
1943 /* XXX block beacon interrupts */
1944 ath9k_hw_setantenna(ah, antenna);
1945 sc->sc_defant = antenna;
1946 sc->sc_rxotherant = 0;
1947}
1948
1949/*
1950 * Set Slot Time
1951 *
1952 * This will wake up the chip if required, and set the slot time for the
1953 * frame (maximum transmit time). Slot time is assumed to be already set
1954 * in the ATH object member sc_slottime
1955*/
1956
1957void ath_setslottime(struct ath_softc *sc)
1958{
1959 ath9k_hw_setslottime(sc->sc_ah, sc->sc_slottime);
1960 sc->sc_updateslot = OK;
1961}
diff --git a/drivers/net/wireless/ath9k/core.h b/drivers/net/wireless/ath9k/core.h
new file mode 100644
index 000000000000..cf76b36d1757
--- /dev/null
+++ b/drivers/net/wireless/ath9k/core.h
@@ -0,0 +1,1097 @@
1/*
2 * Copyright (c) 2008 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#ifndef CORE_H
18#define CORE_H
19
20#include <linux/version.h>
21#include <linux/autoconf.h>
22#include <linux/kernel.h>
23#include <linux/module.h>
24#include <linux/spinlock.h>
25#include <linux/errno.h>
26#include <linux/skbuff.h>
27#include <linux/netdevice.h>
28#include <linux/etherdevice.h>
29#include <linux/ip.h>
30#include <linux/tcp.h>
31#include <linux/in.h>
32#include <linux/delay.h>
33#include <linux/wait.h>
34#include <linux/pci.h>
35#include <linux/interrupt.h>
36#include <linux/sched.h>
37#include <linux/list.h>
38#include <asm/byteorder.h>
39#include <linux/scatterlist.h>
40#include <asm/page.h>
41#include <net/mac80211.h>
42
43#include "ath9k.h"
44#include "rc.h"
45
46struct ath_node;
47
48/******************/
49/* Utility macros */
50/******************/
51
52/* Macro to expand scalars to 64-bit objects */
53
54#define ito64(x) (sizeof(x) == 8) ? \
55 (((unsigned long long int)(x)) & (0xff)) : \
56 (sizeof(x) == 16) ? \
57 (((unsigned long long int)(x)) & 0xffff) : \
58 ((sizeof(x) == 32) ? \
59 (((unsigned long long int)(x)) & 0xffffffff) : \
60 (unsigned long long int)(x))
61
62/* increment with wrap-around */
63#define INCR(_l, _sz) do { \
64 (_l)++; \
65 (_l) &= ((_sz) - 1); \
66 } while (0)
67
68/* decrement with wrap-around */
69#define DECR(_l, _sz) do { \
70 (_l)--; \
71 (_l) &= ((_sz) - 1); \
72 } while (0)
73
74#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
75
76#define ASSERT(exp) do { \
77 if (unlikely(!(exp))) { \
78 BUG(); \
79 } \
80 } while (0)
81
82/* XXX: remove */
83#define memzero(_buf, _len) memset(_buf, 0, _len)
84
85#define get_dma_mem_context(var, field) (&((var)->field))
86#define copy_dma_mem_context(dst, src) (*dst = *src)
87
88#define ATH9K_BH_STATUS_INTACT 0
89#define ATH9K_BH_STATUS_CHANGE 1
90
91#define ATH_TXQ_SETUP(sc, i) ((sc)->sc_txqsetup & (1<<i))
92
93static inline unsigned long get_timestamp(void)
94{
95 return ((jiffies / HZ) * 1000) + (jiffies % HZ) * (1000 / HZ);
96}
97
98/*************/
99/* Debugging */
100/*************/
101
102enum ATH_DEBUG {
103 ATH_DBG_RESET = 0x00000001,
104 ATH_DBG_PHY_IO = 0x00000002,
105 ATH_DBG_REG_IO = 0x00000004,
106 ATH_DBG_QUEUE = 0x00000008,
107 ATH_DBG_EEPROM = 0x00000010,
108 ATH_DBG_NF_CAL = 0x00000020,
109 ATH_DBG_CALIBRATE = 0x00000040,
110 ATH_DBG_CHANNEL = 0x00000080,
111 ATH_DBG_INTERRUPT = 0x00000100,
112 ATH_DBG_REGULATORY = 0x00000200,
113 ATH_DBG_ANI = 0x00000400,
114 ATH_DBG_POWER_MGMT = 0x00000800,
115 ATH_DBG_XMIT = 0x00001000,
116 ATH_DBG_BEACON = 0x00002000,
117 ATH_DBG_RATE = 0x00004000,
118 ATH_DBG_CONFIG = 0x00008000,
119 ATH_DBG_KEYCACHE = 0x00010000,
120 ATH_DBG_AGGR = 0x00020000,
121 ATH_DBG_FATAL = 0x00040000,
122 ATH_DBG_ANY = 0xffffffff
123};
124
125#define DBG_DEFAULT (ATH_DBG_FATAL)
126
127#define DPRINTF(sc, _m, _fmt, ...) do { \
128 if (sc->sc_debug & (_m)) \
129 printk(_fmt , ##__VA_ARGS__); \
130 } while (0)
131
132/***************************/
133/* Load-time Configuration */
134/***************************/
135
136/* Per-instance load-time (note: NOT run-time) configurations
137 * for Atheros Device */
138struct ath_config {
139 u32 ath_aggr_prot;
140 u16 txpowlimit;
141 u16 txpowlimit_override;
142 u8 cabqReadytime; /* Cabq Readytime % */
143 u8 swBeaconProcess; /* Process received beacons
144 in SW (vs HW) */
145};
146
147/***********************/
148/* Chainmask Selection */
149/***********************/
150
151#define ATH_CHAINMASK_SEL_TIMEOUT 6000
152/* Default - Number of last RSSI values that is used for
153 * chainmask selection */
154#define ATH_CHAINMASK_SEL_RSSI_CNT 10
155/* Means use 3x3 chainmask instead of configured chainmask */
156#define ATH_CHAINMASK_SEL_3X3 7
157/* Default - Rssi threshold below which we have to switch to 3x3 */
158#define ATH_CHAINMASK_SEL_UP_RSSI_THRES 20
159/* Default - Rssi threshold above which we have to switch to
160 * user configured values */
161#define ATH_CHAINMASK_SEL_DOWN_RSSI_THRES 35
162/* Struct to store the chainmask select related info */
163struct ath_chainmask_sel {
164 struct timer_list timer;
165 int cur_tx_mask; /* user configured or 3x3 */
166 int cur_rx_mask; /* user configured or 3x3 */
167 int tx_avgrssi;
168 u8 switch_allowed:1, /* timer will set this */
169 cm_sel_enabled:1;
170};
171
172int ath_chainmask_sel_logic(struct ath_softc *sc, struct ath_node *an);
173void ath_update_chainmask(struct ath_softc *sc, int is_ht);
174
175/*************************/
176/* Descriptor Management */
177/*************************/
178
179/* Number of descriptors per buffer. The only case where we see skbuff
180chains is due to FF aggregation in the driver. */
181#define ATH_TXDESC 1
182/* if there's more fragment for this MSDU */
183#define ATH_BF_MORE_MPDU 1
184#define ATH_TXBUF_RESET(_bf) do { \
185 (_bf)->bf_status = 0; \
186 (_bf)->bf_lastbf = NULL; \
187 (_bf)->bf_lastfrm = NULL; \
188 (_bf)->bf_next = NULL; \
189 memzero(&((_bf)->bf_state), \
190 sizeof(struct ath_buf_state)); \
191 } while (0)
192
193struct ath_buf_state {
194 int bfs_nframes; /* # frames in aggregate */
195 u16 bfs_al; /* length of aggregate */
196 u16 bfs_frmlen; /* length of frame */
197 int bfs_seqno; /* sequence number */
198 int bfs_tidno; /* tid of this frame */
199 int bfs_retries; /* current retries */
200 struct ath_rc_series bfs_rcs[4]; /* rate series */
201 u8 bfs_isdata:1; /* is a data frame/aggregate */
202 u8 bfs_isaggr:1; /* is an aggregate */
203 u8 bfs_isampdu:1; /* is an a-mpdu, aggregate or not */
204 u8 bfs_ht:1; /* is an HT frame */
205 u8 bfs_isretried:1; /* is retried */
206 u8 bfs_isxretried:1; /* is excessive retried */
207 u8 bfs_shpreamble:1; /* is short preamble */
208 u8 bfs_isbar:1; /* is a BAR */
209 u8 bfs_ispspoll:1; /* is a PS-Poll */
210 u8 bfs_aggrburst:1; /* is a aggr burst */
211 u8 bfs_calcairtime:1; /* requests airtime be calculated
212 when set for tx frame */
213 int bfs_rifsburst_elem; /* RIFS burst/bar */
214 int bfs_nrifsubframes; /* # of elements in burst */
215 /* key type use to encrypt this frame */
216 enum ath9k_key_type bfs_keytype;
217};
218
219#define bf_nframes bf_state.bfs_nframes
220#define bf_al bf_state.bfs_al
221#define bf_frmlen bf_state.bfs_frmlen
222#define bf_retries bf_state.bfs_retries
223#define bf_seqno bf_state.bfs_seqno
224#define bf_tidno bf_state.bfs_tidno
225#define bf_rcs bf_state.bfs_rcs
226#define bf_isdata bf_state.bfs_isdata
227#define bf_isaggr bf_state.bfs_isaggr
228#define bf_isampdu bf_state.bfs_isampdu
229#define bf_ht bf_state.bfs_ht
230#define bf_isretried bf_state.bfs_isretried
231#define bf_isxretried bf_state.bfs_isxretried
232#define bf_shpreamble bf_state.bfs_shpreamble
233#define bf_rifsburst_elem bf_state.bfs_rifsburst_elem
234#define bf_nrifsubframes bf_state.bfs_nrifsubframes
235#define bf_keytype bf_state.bfs_keytype
236#define bf_isbar bf_state.bfs_isbar
237#define bf_ispspoll bf_state.bfs_ispspoll
238#define bf_aggrburst bf_state.bfs_aggrburst
239#define bf_calcairtime bf_state.bfs_calcairtime
240
241/*
242 * Abstraction of a contiguous buffer to transmit/receive. There is only
243 * a single hw descriptor encapsulated here.
244 */
245
246struct ath_buf {
247 struct list_head list;
248 struct list_head *last;
249 struct ath_buf *bf_lastbf; /* last buf of this unit (a frame or
250 an aggregate) */
251 struct ath_buf *bf_lastfrm; /* last buf of this frame */
252 struct ath_buf *bf_next; /* next subframe in the aggregate */
253 struct ath_buf *bf_rifslast; /* last buf for RIFS burst */
254 void *bf_mpdu; /* enclosing frame structure */
255 void *bf_node; /* pointer to the node */
256 struct ath_desc *bf_desc; /* virtual addr of desc */
257 dma_addr_t bf_daddr; /* physical addr of desc */
258 dma_addr_t bf_buf_addr; /* physical addr of data buffer */
259 u32 bf_status;
260 u16 bf_flags; /* tx descriptor flags */
261 struct ath_buf_state bf_state; /* buffer state */
262 dma_addr_t bf_dmacontext;
263};
264
265/*
266 * reset the rx buffer.
267 * any new fields added to the athbuf and require
268 * reset need to be added to this macro.
269 * currently bf_status is the only one requires that
270 * requires reset.
271 */
272#define ATH_RXBUF_RESET(_bf) ((_bf)->bf_status = 0)
273
274/* hw processing complete, desc processed by hal */
275#define ATH_BUFSTATUS_DONE 0x00000001
276/* hw processing complete, desc hold for hw */
277#define ATH_BUFSTATUS_STALE 0x00000002
278/* Rx-only: OS is done with this packet and it's ok to queued it to hw */
279#define ATH_BUFSTATUS_FREE 0x00000004
280
281/* DMA state for tx/rx descriptors */
282
283struct ath_descdma {
284 const char *dd_name;
285 struct ath_desc *dd_desc; /* descriptors */
286 dma_addr_t dd_desc_paddr; /* physical addr of dd_desc */
287 u32 dd_desc_len; /* size of dd_desc */
288 struct ath_buf *dd_bufptr; /* associated buffers */
289 dma_addr_t dd_dmacontext;
290};
291
292/* Abstraction of a received RX MPDU/MMPDU, or a RX fragment */
293
294struct ath_rx_context {
295 struct ath_buf *ctx_rxbuf; /* associated ath_buf for rx */
296};
297#define ATH_RX_CONTEXT(skb) ((struct ath_rx_context *)skb->cb)
298
299int ath_descdma_setup(struct ath_softc *sc,
300 struct ath_descdma *dd,
301 struct list_head *head,
302 const char *name,
303 int nbuf,
304 int ndesc);
305int ath_desc_alloc(struct ath_softc *sc);
306void ath_desc_free(struct ath_softc *sc);
307void ath_descdma_cleanup(struct ath_softc *sc,
308 struct ath_descdma *dd,
309 struct list_head *head);
310
311/******/
312/* RX */
313/******/
314
315#define ATH_MAX_ANTENNA 3
316#define ATH_RXBUF 512
317#define ATH_RX_TIMEOUT 40 /* 40 milliseconds */
318#define WME_NUM_TID 16
319#define IEEE80211_BAR_CTL_TID_M 0xF000 /* tid mask */
320#define IEEE80211_BAR_CTL_TID_S 2 /* tid shift */
321
322enum ATH_RX_TYPE {
323 ATH_RX_NON_CONSUMED = 0,
324 ATH_RX_CONSUMED
325};
326
327/* per frame rx status block */
328struct ath_recv_status {
329 u64 tsf; /* mac tsf */
330 int8_t rssi; /* RSSI (noise floor ajusted) */
331 int8_t rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
332 int8_t rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
333 int8_t abs_rssi; /* absolute RSSI */
334 u8 rateieee; /* data rate received (IEEE rate code) */
335 u8 ratecode; /* phy rate code */
336 int rateKbps; /* data rate received (Kbps) */
337 int antenna; /* rx antenna */
338 int flags; /* status of associated skb */
339#define ATH_RX_FCS_ERROR 0x01
340#define ATH_RX_MIC_ERROR 0x02
341#define ATH_RX_DECRYPT_ERROR 0x04
342#define ATH_RX_RSSI_VALID 0x08
343/* if any of ctl,extn chainrssis are valid */
344#define ATH_RX_CHAIN_RSSI_VALID 0x10
345/* if extn chain rssis are valid */
346#define ATH_RX_RSSI_EXTN_VALID 0x20
347/* set if 40Mhz, clear if 20Mhz */
348#define ATH_RX_40MHZ 0x40
349/* set if short GI, clear if full GI */
350#define ATH_RX_SHORT_GI 0x80
351};
352
353struct ath_rxbuf {
354 struct sk_buff *rx_wbuf; /* buffer */
355 unsigned long rx_time; /* system time when received */
356 struct ath_recv_status rx_status; /* cached rx status */
357};
358
359/* Per-TID aggregate receiver state for a node */
360struct ath_arx_tid {
361 struct ath_node *an; /* parent ath node */
362 struct ath_rxbuf *rxbuf; /* re-ordering buffer */
363 struct timer_list timer;
364 spinlock_t tidlock; /* lock to protect this TID structure */
365 int baw_head; /* seq_next at head */
366 int baw_tail; /* tail of block-ack window */
367 int seq_reset; /* need to reset start sequence */
368 int addba_exchangecomplete;
369 u16 seq_next; /* next expected sequence */
370 u16 baw_size; /* block-ack window size */
371};
372
373/* Per-node receiver aggregate state */
374struct ath_arx {
375 struct ath_arx_tid tid[WME_NUM_TID];
376};
377
378int ath_startrecv(struct ath_softc *sc);
379bool ath_stoprecv(struct ath_softc *sc);
380void ath_flushrecv(struct ath_softc *sc);
381u32 ath_calcrxfilter(struct ath_softc *sc);
382void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an);
383void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an);
384void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an);
385void ath_handle_rx_intr(struct ath_softc *sc);
386int ath_rx_init(struct ath_softc *sc, int nbufs);
387void ath_rx_cleanup(struct ath_softc *sc);
388int ath_rx_tasklet(struct ath_softc *sc, int flush);
389int ath_rx_input(struct ath_softc *sc,
390 struct ath_node *node,
391 int is_ampdu,
392 struct sk_buff *skb,
393 struct ath_recv_status *rx_status,
394 enum ATH_RX_TYPE *status);
395int ath__rx_indicate(struct ath_softc *sc,
396 struct sk_buff *skb,
397 struct ath_recv_status *status,
398 u16 keyix);
399int ath_rx_subframe(struct ath_node *an, struct sk_buff *skb,
400 struct ath_recv_status *status);
401
402/******/
403/* TX */
404/******/
405
406#define ATH_FRAG_PER_MSDU 1
407#define ATH_TXBUF (512/ATH_FRAG_PER_MSDU)
408/* max number of transmit attempts (tries) */
409#define ATH_TXMAXTRY 13
410/* max number of 11n transmit attempts (tries) */
411#define ATH_11N_TXMAXTRY 10
412/* max number of tries for management and control frames */
413#define ATH_MGT_TXMAXTRY 4
414#define WME_BA_BMP_SIZE 64
415#define WME_MAX_BA WME_BA_BMP_SIZE
416#define ATH_TID_MAX_BUFS (2 * WME_MAX_BA)
417#define TID_TO_WME_AC(_tid) \
418 ((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE : \
419 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK : \
420 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI : \
421 WME_AC_VO)
422
423
424/* Wireless Multimedia Extension Defines */
425#define WME_AC_BE 0 /* best effort */
426#define WME_AC_BK 1 /* background */
427#define WME_AC_VI 2 /* video */
428#define WME_AC_VO 3 /* voice */
429#define WME_NUM_AC 4
430
431enum ATH_SM_PWRSAV{
432 ATH_SM_ENABLE,
433 ATH_SM_PWRSAV_STATIC,
434 ATH_SM_PWRSAV_DYNAMIC,
435};
436
437/*
438 * Data transmit queue state. One of these exists for each
439 * hardware transmit queue. Packets sent to us from above
440 * are assigned to queues based on their priority. Not all
441 * devices support a complete set of hardware transmit queues.
442 * For those devices the array sc_ac2q will map multiple
443 * priorities to fewer hardware queues (typically all to one
444 * hardware queue).
445 */
446struct ath_txq {
447 u32 axq_qnum; /* hardware q number */
448 u32 *axq_link; /* link ptr in last TX desc */
449 struct list_head axq_q; /* transmit queue */
450 spinlock_t axq_lock; /* lock on q and link */
451 unsigned long axq_lockflags; /* intr state when must cli */
452 u32 axq_depth; /* queue depth */
453 u8 axq_aggr_depth; /* aggregates queued */
454 u32 axq_totalqueued;/* total ever queued */
455 u32 axq_intrcnt; /* count to determine
456 if descriptor should generate
457 int on this txq. */
458 bool stopped; /* Is mac80211 queue
459 stopped ? */
460 /* State for patching up CTS when bursting */
461 struct ath_buf *axq_linkbuf; /* virtual addr of last buffer*/
462 struct ath_desc *axq_lastdsWithCTS; /* first desc of the
463 last descriptor that contains CTS */
464 struct ath_desc *axq_gatingds; /* final desc of the gating desc
465 * that determines whether lastdsWithCTS has
466 * been DMA'ed or not */
467 struct list_head axq_acq;
468};
469
470/* per TID aggregate tx state for a destination */
471struct ath_atx_tid {
472 struct list_head list; /* round-robin tid entry */
473 struct list_head buf_q; /* pending buffers */
474 struct ath_node *an; /* parent node structure */
475 struct ath_atx_ac *ac; /* parent access category */
476 struct ath_buf *tx_buf[ATH_TID_MAX_BUFS];/* active tx frames */
477 u16 seq_start; /* starting seq of BA window */
478 u16 seq_next; /* next seq to be used */
479 u16 baw_size; /* BA window size */
480 int tidno; /* TID number */
481 int baw_head; /* first un-acked tx buffer */
482 int baw_tail; /* next unused tx buffer slot */
483 int sched; /* TID is scheduled */
484 int paused; /* TID is paused */
485 int cleanup_inprogress; /* aggr of this TID is
486 being teared down */
487 u32 addba_exchangecomplete:1; /* ADDBA state */
488 int32_t addba_exchangeinprogress;
489 int addba_exchangeattempts;
490};
491
492/* per access-category aggregate tx state for a destination */
493struct ath_atx_ac {
494 int sched; /* dest-ac is scheduled */
495 int qnum; /* H/W queue number associated
496 with this AC */
497 struct list_head list; /* round-robin txq entry */
498 struct list_head tid_q; /* queue of TIDs with buffers */
499};
500
501/* per dest tx state */
502struct ath_atx {
503 struct ath_atx_tid tid[WME_NUM_TID];
504 struct ath_atx_ac ac[WME_NUM_AC];
505};
506
507/* per-frame tx control block */
508struct ath_tx_control {
509 struct ath_node *an; /* destination to sent to */
510 int if_id; /* only valid for cab traffic */
511 int qnum; /* h/w queue number */
512 u32 ht:1; /* if it can be transmitted using HT */
513 u32 ps:1; /* if one or more stations are in PS mode */
514 u32 use_minrate:1; /* if this frame should transmitted using
515 minimum rate */
516 enum ath9k_pkt_type atype; /* Atheros packet type */
517 enum ath9k_key_type keytype; /* key type */
518 u32 flags; /* HAL flags */
519 u16 seqno; /* sequence number */
520 u16 tidno; /* tid number */
521 u16 txpower; /* transmit power */
522 u16 frmlen; /* frame length */
523 u32 keyix; /* key index */
524 int min_rate; /* minimum rate */
525 int mcast_rate; /* multicast rate */
526 u16 nextfraglen; /* next fragment length */
527 /* below is set only by ath_dev */
528 struct ath_softc *dev; /* device handle */
529 dma_addr_t dmacontext;
530};
531
532/* per frame tx status block */
533struct ath_xmit_status {
534 int retries; /* number of retries to successufully
535 transmit this frame */
536 int flags; /* status of transmit */
537#define ATH_TX_ERROR 0x01
538#define ATH_TX_XRETRY 0x02
539#define ATH_TX_BAR 0x04
540};
541
542struct ath_tx_stat {
543 int rssi; /* RSSI (noise floor ajusted) */
544 int rssictl[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
545 int rssiextn[ATH_MAX_ANTENNA]; /* RSSI (noise floor ajusted) */
546 int rateieee; /* data rate xmitted (IEEE rate code) */
547 int rateKbps; /* data rate xmitted (Kbps) */
548 int ratecode; /* phy rate code */
549 int flags; /* validity flags */
550/* if any of ctl,extn chain rssis are valid */
551#define ATH_TX_CHAIN_RSSI_VALID 0x01
552/* if extn chain rssis are valid */
553#define ATH_TX_RSSI_EXTN_VALID 0x02
554 u32 airtime; /* time on air per final tx rate */
555};
556
557struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
558void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
559int ath_tx_setup(struct ath_softc *sc, int haltype);
560void ath_draintxq(struct ath_softc *sc, bool retry_tx);
561void ath_tx_draintxq(struct ath_softc *sc,
562 struct ath_txq *txq, bool retry_tx);
563void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an);
564void ath_tx_node_cleanup(struct ath_softc *sc,
565 struct ath_node *an, bool bh_flag);
566void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an);
567void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
568int ath_tx_init(struct ath_softc *sc, int nbufs);
569int ath_tx_cleanup(struct ath_softc *sc);
570int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
571int ath_txq_update(struct ath_softc *sc, int qnum, struct ath9k_txq_info *q);
572int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb);
573void ath_tx_tasklet(struct ath_softc *sc);
574u32 ath_txq_depth(struct ath_softc *sc, int qnum);
575u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum);
576void ath_notify_txq_status(struct ath_softc *sc, u16 queue_depth);
577void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
578 struct ath_xmit_status *tx_status, struct ath_node *an);
579
580/**********************/
581/* Node / Aggregation */
582/**********************/
583
584/* indicates the node is clened up */
585#define ATH_NODE_CLEAN 0x1
586/* indicates the node is 80211 power save */
587#define ATH_NODE_PWRSAVE 0x2
588
589#define ADDBA_TIMEOUT 200 /* 200 milliseconds */
590#define ADDBA_EXCHANGE_ATTEMPTS 10
591#define ATH_AGGR_DELIM_SZ 4 /* delimiter size */
592#define ATH_AGGR_MINPLEN 256 /* in bytes, minimum packet length */
593/* number of delimiters for encryption padding */
594#define ATH_AGGR_ENCRYPTDELIM 10
595/* minimum h/w qdepth to be sustained to maximize aggregation */
596#define ATH_AGGR_MIN_QDEPTH 2
597#define ATH_AMPDU_SUBFRAME_DEFAULT 32
598#define IEEE80211_SEQ_SEQ_SHIFT 4
599#define IEEE80211_SEQ_MAX 4096
600#define IEEE80211_MIN_AMPDU_BUF 0x8
601
602/* return whether a bit at index _n in bitmap _bm is set
603 * _sz is the size of the bitmap */
604#define ATH_BA_ISSET(_bm, _n) (((_n) < (WME_BA_BMP_SIZE)) && \
605 ((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
606
607/* return block-ack bitmap index given sequence and starting sequence */
608#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
609
610/* returns delimiter padding required given the packet length */
611#define ATH_AGGR_GET_NDELIM(_len) \
612 (((((_len) + ATH_AGGR_DELIM_SZ) < ATH_AGGR_MINPLEN) ? \
613 (ATH_AGGR_MINPLEN - (_len) - ATH_AGGR_DELIM_SZ) : 0) >> 2)
614
615#define BAW_WITHIN(_start, _bawsz, _seqno) \
616 ((((_seqno) - (_start)) & 4095) < (_bawsz))
617
618#define ATH_DS_BA_SEQ(_ds) ((_ds)->ds_us.tx.ts_seqnum)
619#define ATH_DS_BA_BITMAP(_ds) (&(_ds)->ds_us.tx.ba_low)
620#define ATH_DS_TX_BA(_ds) ((_ds)->ds_us.tx.ts_flags & ATH9K_TX_BA)
621#define ATH_AN_2_TID(_an, _tidno) (&(_an)->an_aggr.tx.tid[(_tidno)])
622
623enum ATH_AGGR_STATUS {
624 ATH_AGGR_DONE,
625 ATH_AGGR_BAW_CLOSED,
626 ATH_AGGR_LIMITED,
627 ATH_AGGR_SHORTPKT,
628 ATH_AGGR_8K_LIMITED,
629};
630
631enum ATH_AGGR_CHECK {
632 AGGR_NOT_REQUIRED,
633 AGGR_REQUIRED,
634 AGGR_CLEANUP_PROGRESS,
635 AGGR_EXCHANGE_PROGRESS,
636 AGGR_EXCHANGE_DONE
637};
638
639struct aggr_rifs_param {
640 int param_max_frames;
641 int param_max_len;
642 int param_rl;
643 int param_al;
644 struct ath_rc_series *param_rcs;
645};
646
647/* Per-node aggregation state */
648struct ath_node_aggr {
649 struct ath_atx tx; /* node transmit state */
650 struct ath_arx rx; /* node receive state */
651};
652
653/* driver-specific node state */
654struct ath_node {
655 struct list_head list;
656 struct ath_softc *an_sc; /* back pointer */
657 atomic_t an_refcnt;
658 struct ath_chainmask_sel an_chainmask_sel;
659 struct ath_node_aggr an_aggr; /* A-MPDU aggregation state */
660 u8 an_smmode; /* SM Power save mode */
661 u8 an_flags;
662 u8 an_addr[ETH_ALEN];
663};
664
665void ath_tx_resume_tid(struct ath_softc *sc,
666 struct ath_atx_tid *tid);
667enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc,
668 struct ath_node *an, u8 tidno);
669void ath_tx_aggr_teardown(struct ath_softc *sc,
670 struct ath_node *an, u8 tidno);
671void ath_rx_aggr_teardown(struct ath_softc *sc,
672 struct ath_node *an, u8 tidno);
673int ath_rx_aggr_start(struct ath_softc *sc,
674 const u8 *addr,
675 u16 tid,
676 u16 *ssn);
677int ath_rx_aggr_stop(struct ath_softc *sc,
678 const u8 *addr,
679 u16 tid);
680int ath_tx_aggr_start(struct ath_softc *sc,
681 const u8 *addr,
682 u16 tid,
683 u16 *ssn);
684int ath_tx_aggr_stop(struct ath_softc *sc,
685 const u8 *addr,
686 u16 tid);
687void ath_newassoc(struct ath_softc *sc,
688 struct ath_node *node, int isnew, int isuapsd);
689struct ath_node *ath_node_attach(struct ath_softc *sc,
690 u8 addr[ETH_ALEN], int if_id);
691void ath_node_detach(struct ath_softc *sc, struct ath_node *an, bool bh_flag);
692struct ath_node *ath_node_get(struct ath_softc *sc, u8 addr[ETH_ALEN]);
693void ath_node_put(struct ath_softc *sc, struct ath_node *an, bool bh_flag);
694struct ath_node *ath_node_find(struct ath_softc *sc, u8 *addr);
695
696/*******************/
697/* Beacon Handling */
698/*******************/
699
700/*
701 * Regardless of the number of beacons we stagger, (i.e. regardless of the
702 * number of BSSIDs) if a given beacon does not go out even after waiting this
703 * number of beacon intervals, the game's up.
704 */
705#define BSTUCK_THRESH (9 * ATH_BCBUF)
706#define ATH_BCBUF 4 /* number of beacon buffers */
707#define ATH_DEFAULT_BINTVAL 100 /* default beacon interval in TU */
708#define ATH_DEFAULT_BMISS_LIMIT 10
709#define ATH_BEACON_AIFS_DEFAULT 0 /* Default aifs for ap beacon q */
710#define ATH_BEACON_CWMIN_DEFAULT 0 /* Default cwmin for ap beacon q */
711#define ATH_BEACON_CWMAX_DEFAULT 0 /* Default cwmax for ap beacon q */
712#define IEEE80211_MS_TO_TU(x) (((x) * 1000) / 1024)
713
714/* beacon configuration */
715struct ath_beacon_config {
716 u16 beacon_interval;
717 u16 listen_interval;
718 u16 dtim_period;
719 u16 bmiss_timeout;
720 u8 dtim_count;
721 u8 tim_offset;
722 union {
723 u64 last_tsf;
724 u8 last_tstamp[8];
725 } u; /* last received beacon/probe response timestamp of this BSS. */
726};
727
728/* offsets in a beacon frame for
729 * quick acess of beacon content by low-level driver */
730struct ath_beacon_offset {
731 u8 *bo_tim; /* start of atim/dtim */
732};
733
734void ath9k_beacon_tasklet(unsigned long data);
735void ath_beacon_config(struct ath_softc *sc, int if_id);
736int ath_beaconq_setup(struct ath_hal *ah);
737int ath_beacon_alloc(struct ath_softc *sc, int if_id);
738void ath_bstuck_process(struct ath_softc *sc);
739void ath_beacon_tasklet(struct ath_softc *sc, int *needmark);
740void ath_beacon_free(struct ath_softc *sc);
741void ath_beacon_return(struct ath_softc *sc, struct ath_vap *avp);
742void ath_beacon_sync(struct ath_softc *sc, int if_id);
743void ath_update_beacon_info(struct ath_softc *sc, int avgbrssi);
744void ath_get_beaconconfig(struct ath_softc *sc,
745 int if_id,
746 struct ath_beacon_config *conf);
747int ath_update_beacon(struct ath_softc *sc,
748 int if_id,
749 struct ath_beacon_offset *bo,
750 struct sk_buff *skb,
751 int mcast);
752/********/
753/* VAPs */
754/********/
755
756#define ATH_IF_HW_OFF 0x0001 /* hardware state needs to turn off */
757#define ATH_IF_HW_ON 0x0002 /* hardware state needs to turn on */
758/* STA only: the associated AP is HT capable */
759#define ATH_IF_HT 0x0004
760/* AP/IBSS only: current BSS has privacy on */
761#define ATH_IF_PRIVACY 0x0008
762#define ATH_IF_BEACON_ENABLE 0x0010 /* AP/IBSS only: enable beacon */
763#define ATH_IF_BEACON_SYNC 0x0020 /* IBSS only: need to sync beacon */
764
765/*
766 * Define the scheme that we select MAC address for multiple
767 * BSS on the same radio. The very first VAP will just use the MAC
768 * address from the EEPROM. For the next 3 VAPs, we set the
769 * U/L bit (bit 1) in MAC address, and use the next two bits as the
770 * index of the VAP.
771 */
772
773#define ATH_SET_VAP_BSSID_MASK(bssid_mask) \
774 ((bssid_mask)[0] &= ~(((ATH_BCBUF-1)<<2)|0x02))
775
776/* VAP configuration (from protocol layer) */
777struct ath_vap_config {
778 u32 av_fixed_rateset;
779 u32 av_fixed_retryset;
780};
781
782/* driver-specific vap state */
783struct ath_vap {
784 struct ieee80211_vif *av_if_data; /* interface(vap)
785 instance from 802.11 protocal layer */
786 enum ath9k_opmode av_opmode; /* VAP operational mode */
787 struct ath_buf *av_bcbuf; /* beacon buffer */
788 struct ath_beacon_offset av_boff; /* dynamic update state */
789 struct ath_tx_control av_btxctl; /* tx control information
790 for beacon */
791 int av_bslot; /* beacon slot index */
792 struct ath_txq av_mcastq; /* multicast
793 transmit queue */
794 struct ath_vap_config av_config; /* vap configuration
795 parameters from 802.11 protocol layer*/
796 struct ath_rate_node *rc_node;
797};
798
799int ath_vap_attach(struct ath_softc *sc,
800 int if_id,
801 struct ieee80211_vif *if_data,
802 enum ath9k_opmode opmode);
803int ath_vap_detach(struct ath_softc *sc, int if_id);
804int ath_vap_config(struct ath_softc *sc,
805 int if_id, struct ath_vap_config *if_config);
806int ath_vap_listen(struct ath_softc *sc, int if_id);
807
808/*********************/
809/* Antenna diversity */
810/*********************/
811
812#define ATH_ANT_DIV_MAX_CFG 2
813#define ATH_ANT_DIV_MIN_IDLE_US 1000000 /* us */
814#define ATH_ANT_DIV_MIN_SCAN_US 50000 /* us */
815
816enum ATH_ANT_DIV_STATE{
817 ATH_ANT_DIV_IDLE,
818 ATH_ANT_DIV_SCAN, /* evaluating antenna */
819};
820
821struct ath_antdiv {
822 struct ath_softc *antdiv_sc;
823 u8 antdiv_start;
824 enum ATH_ANT_DIV_STATE antdiv_state;
825 u8 antdiv_num_antcfg;
826 u8 antdiv_curcfg;
827 u8 antdiv_bestcfg;
828 int32_t antdivf_rssitrig;
829 int32_t antdiv_lastbrssi[ATH_ANT_DIV_MAX_CFG];
830 u64 antdiv_lastbtsf[ATH_ANT_DIV_MAX_CFG];
831 u64 antdiv_laststatetsf;
832 u8 antdiv_bssid[ETH_ALEN];
833};
834
835void ath_slow_ant_div_init(struct ath_antdiv *antdiv,
836 struct ath_softc *sc, int32_t rssitrig);
837void ath_slow_ant_div_start(struct ath_antdiv *antdiv,
838 u8 num_antcfg,
839 const u8 *bssid);
840void ath_slow_ant_div_stop(struct ath_antdiv *antdiv);
841void ath_slow_ant_div(struct ath_antdiv *antdiv,
842 struct ieee80211_hdr *wh,
843 struct ath_rx_status *rx_stats);
844void ath_setdefantenna(void *sc, u32 antenna);
845
846/********************/
847/* Main driver core */
848/********************/
849
850/*
851 * Default cache line size, in bytes.
852 * Used when PCI device not fully initialized by bootrom/BIOS
853*/
854#define DEFAULT_CACHELINE 32
855#define ATH_DEFAULT_NOISE_FLOOR -95
856#define ATH_REGCLASSIDS_MAX 10
857#define ATH_CABQ_READY_TIME 80 /* % of beacon interval */
858#define ATH_PREAMBLE_SHORT (1<<0)
859#define ATH_PROTECT_ENABLE (1<<1)
860#define ATH_MAX_SW_RETRIES 10
861/* Num farmes difference in tx to flip default recv */
862#define ATH_ANTENNA_DIFF 2
863#define ATH_CHAN_MAX 255
864#define IEEE80211_WEP_NKID 4 /* number of key ids */
865#define IEEE80211_RATE_VAL 0x7f
866/*
867 * The key cache is used for h/w cipher state and also for
868 * tracking station state such as the current tx antenna.
869 * We also setup a mapping table between key cache slot indices
870 * and station state to short-circuit node lookups on rx.
871 * Different parts have different size key caches. We handle
872 * up to ATH_KEYMAX entries (could dynamically allocate state).
873 */
874#define ATH_KEYMAX 128 /* max key cache size we handle */
875
876#define RESET_RETRY_TXQ 0x00000001
877#define ATH_IF_ID_ANY 0xff
878
879#define ATH_TXPOWER_MAX 100 /* .5 dBm units */
880
881#define RSSI_LPF_THRESHOLD -20
882#define ATH_RSSI_EP_MULTIPLIER (1<<7) /* pow2 to optimize out * and / */
883#define ATH_RATE_DUMMY_MARKER 0
884#define ATH_RSSI_LPF_LEN 10
885#define ATH_RSSI_DUMMY_MARKER 0x127
886
887#define ATH_EP_MUL(x, mul) ((x) * (mul))
888#define ATH_EP_RND(x, mul) \
889 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
890#define ATH_RSSI_OUT(x) \
891 (((x) != ATH_RSSI_DUMMY_MARKER) ? \
892 (ATH_EP_RND((x), ATH_RSSI_EP_MULTIPLIER)) : ATH_RSSI_DUMMY_MARKER)
893#define ATH_RSSI_IN(x) \
894 (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER))
895#define ATH_LPF_RSSI(x, y, len) \
896 ((x != ATH_RSSI_DUMMY_MARKER) ? \
897 (((x) * ((len) - 1) + (y)) / (len)) : (y))
898#define ATH_RSSI_LPF(x, y) do { \
899 if ((y) >= RSSI_LPF_THRESHOLD) \
900 x = ATH_LPF_RSSI((x), \
901 ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN); \
902 } while (0)
903
904
905enum PROT_MODE {
906 PROT_M_NONE = 0,
907 PROT_M_RTSCTS,
908 PROT_M_CTSONLY
909};
910
911enum RATE_TYPE {
912 NORMAL_RATE = 0,
913 HALF_RATE,
914 QUARTER_RATE
915};
916
917struct ath_ht_info {
918 enum ath9k_ht_macmode tx_chan_width;
919 u16 maxampdu;
920 u8 mpdudensity;
921 u8 ext_chan_offset;
922};
923
924struct ath_softc {
925 struct ieee80211_hw *hw; /* mac80211 instance */
926 struct pci_dev *pdev; /* Bus handle */
927 void __iomem *mem; /* address of the device */
928 struct tasklet_struct intr_tq; /* General tasklet */
929 struct tasklet_struct bcon_tasklet; /* Beacon tasklet */
930 struct ath_config sc_config; /* per-instance load-time
931 parameters */
932 int sc_debug; /* Debug masks */
933 struct ath_hal *sc_ah; /* HAL Instance */
934 struct ath_rate_softc *sc_rc; /* tx rate control support */
935 u32 sc_intrstatus; /* HAL_STATUS */
936 enum ath9k_opmode sc_opmode; /* current operating mode */
937
938 /* Properties, Config */
939 u8 sc_invalid; /* being detached */
940 u8 sc_beacons; /* beacons running */
941 u8 sc_scanning; /* scanning active */
942 u8 sc_txaggr; /* enable 11n tx aggregation */
943 u8 sc_rxaggr; /* enable 11n rx aggregation */
944 u8 sc_update_chainmask; /* change chain mask */
945 u8 sc_full_reset; /* force full reset */
946 enum wireless_mode sc_curmode; /* current phy mode */
947 u16 sc_curtxpow; /* current tx power limit */
948 u16 sc_curaid; /* current association id */
949 u8 sc_curbssid[ETH_ALEN];
950 u8 sc_myaddr[ETH_ALEN];
951 enum PROT_MODE sc_protmode; /* protection mode */
952 u8 sc_mcastantenna;/* Multicast antenna number */
953 u8 sc_txantenna; /* data tx antenna
954 (fixed or auto) */
955 u8 sc_nbcnvaps; /* # of vaps sending beacons */
956 u16 sc_nvaps; /* # of active virtual ap's */
957 struct ath_vap *sc_vaps[ATH_BCBUF]; /* interface id
958 to avp map */
959 enum ath9k_int sc_imask; /* interrupt mask copy */
960 u8 sc_bssidmask[ETH_ALEN];
961 u8 sc_defant; /* current default antenna */
962 u8 sc_rxotherant; /* rx's on non-default antenna*/
963 u16 sc_cachelsz; /* cache line size */
964 int sc_slotupdate; /* slot to next advance fsm */
965 int sc_slottime; /* slot time */
966 u8 sc_noreset;
967 int sc_bslot[ATH_BCBUF];/* beacon xmit slots */
968 struct ath9k_node_stats sc_halstats; /* station-mode rssi stats */
969 struct list_head node_list;
970 struct ath_ht_info sc_ht_info;
971 int16_t sc_noise_floor; /* signal noise floor in dBm */
972 enum ath9k_ht_extprotspacing sc_ht_extprotspacing;
973 u8 sc_tx_chainmask;
974 u8 sc_rx_chainmask;
975 u8 sc_rxchaindetect_ref;
976 u8 sc_rxchaindetect_thresh5GHz;
977 u8 sc_rxchaindetect_thresh2GHz;
978 u8 sc_rxchaindetect_delta5GHz;
979 u8 sc_rxchaindetect_delta2GHz;
980 u32 sc_rtsaggrlimit; /* Chipset specific
981 aggr limit */
982 u32 sc_flags;
983#ifdef CONFIG_SLOW_ANT_DIV
984 /* Slow antenna diversity */
985 struct ath_antdiv sc_antdiv;
986#endif
987 enum {
988 OK, /* no change needed */
989 UPDATE, /* update pending */
990 COMMIT /* beacon sent, commit change */
991 } sc_updateslot; /* slot time update fsm */
992
993 /* Crypto */
994 u32 sc_keymax; /* size of key cache */
995 DECLARE_BITMAP(sc_keymap, ATH_KEYMAX); /* key use bit map */
996 u8 sc_splitmic; /* split TKIP MIC keys */
997 int sc_keytype; /* type of the key being used */
998
999 /* RX */
1000 struct list_head sc_rxbuf; /* receive buffer */
1001 struct ath_descdma sc_rxdma; /* RX descriptors */
1002 int sc_rxbufsize; /* rx size based on mtu */
1003 u32 *sc_rxlink; /* link ptr in last RX desc */
1004 u32 sc_rxflush; /* rx flush in progress */
1005 u64 sc_lastrx; /* tsf of last rx'd frame */
1006
1007 /* TX */
1008 struct list_head sc_txbuf; /* transmit buffer */
1009 struct ath_txq sc_txq[ATH9K_NUM_TX_QUEUES];
1010 struct ath_descdma sc_txdma; /* TX descriptors */
1011 u32 sc_txqsetup; /* h/w queues setup */
1012 u32 sc_txintrperiod;/* tx interrupt batching */
1013 int sc_haltype2q[ATH9K_WME_AC_VO+1]; /* HAL WME
1014 AC -> h/w qnum */
1015 u32 sc_ant_tx[8]; /* recent tx frames/antenna */
1016
1017 /* Beacon */
1018 struct ath9k_txq_info sc_beacon_qi; /* adhoc only: beacon
1019 queue parameters */
1020 struct ath_descdma sc_bdma; /* beacon descriptors */
1021 struct ath_txq *sc_cabq; /* tx q for cab frames */
1022 struct list_head sc_bbuf; /* beacon buffers */
1023 u32 sc_bhalq; /* HAL q for outgoing beacons */
1024 u32 sc_bmisscount; /* missed beacon transmits */
1025 u32 ast_be_xmit; /* beacons transmitted */
1026
1027 /* Rate */
1028 struct ieee80211_rate rates[IEEE80211_NUM_BANDS][ATH_RATE_MAX];
1029 const struct ath9k_rate_table *sc_rates[WIRELESS_MODE_MAX];
1030 const struct ath9k_rate_table *sc_currates; /* current rate table */
1031 u8 sc_rixmap[256]; /* IEEE to h/w
1032 rate table ix */
1033 u8 sc_minrateix; /* min h/w rate index */
1034 u8 sc_protrix; /* protection rate index */
1035 struct {
1036 u32 rateKbps; /* transfer rate in kbs */
1037 u8 ieeerate; /* IEEE rate */
1038 } sc_hwmap[256]; /* h/w rate ix mappings */
1039
1040 /* Channel, Band */
1041 struct ieee80211_channel channels[IEEE80211_NUM_BANDS][ATH_CHAN_MAX];
1042 struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS];
1043 struct ath9k_channel sc_curchan; /* current h/w channel */
1044
1045 /* Locks */
1046 spinlock_t sc_rxflushlock; /* lock of RX flush */
1047 spinlock_t sc_rxbuflock; /* rxbuf lock */
1048 spinlock_t sc_txbuflock; /* txbuf lock */
1049 spinlock_t sc_resetlock;
1050 spinlock_t node_lock;
1051};
1052
1053int ath_init(u16 devid, struct ath_softc *sc);
1054void ath_deinit(struct ath_softc *sc);
1055int ath_open(struct ath_softc *sc, struct ath9k_channel *initial_chan);
1056int ath_suspend(struct ath_softc *sc);
1057irqreturn_t ath_isr(int irq, void *dev);
1058int ath_reset(struct ath_softc *sc);
1059void ath_scan_start(struct ath_softc *sc);
1060void ath_scan_end(struct ath_softc *sc);
1061int ath_set_channel(struct ath_softc *sc, struct ath9k_channel *hchan);
1062void ath_setup_rate(struct ath_softc *sc,
1063 enum wireless_mode wMode,
1064 enum RATE_TYPE type,
1065 const struct ath9k_rate_table *rt);
1066
1067/*********************/
1068/* Utility Functions */
1069/*********************/
1070
1071void ath_key_reset(struct ath_softc *sc, u16 keyix, int freeslot);
1072int ath_keyset(struct ath_softc *sc,
1073 u16 keyix,
1074 struct ath9k_keyval *hk,
1075 const u8 mac[ETH_ALEN]);
1076int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
1077int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
1078void ath_setslottime(struct ath_softc *sc);
1079void ath_update_txpow(struct ath_softc *sc);
1080int ath_cabq_update(struct ath_softc *);
1081void ath_get_currentCountry(struct ath_softc *sc,
1082 struct ath9k_country_entry *ctry);
1083u64 ath_extend_tsf(struct ath_softc *sc, u32 rstamp);
1084void ath_internal_reset(struct ath_softc *sc);
1085u32 ath_chan2flags(struct ieee80211_channel *chan, struct ath_softc *sc);
1086dma_addr_t ath_skb_map_single(struct ath_softc *sc,
1087 struct sk_buff *skb,
1088 int direction,
1089 dma_addr_t *pa);
1090void ath_skb_unmap_single(struct ath_softc *sc,
1091 struct sk_buff *skb,
1092 int direction,
1093 dma_addr_t *pa);
1094void ath_mcast_merge(struct ath_softc *sc, u32 mfilt[2]);
1095enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc);
1096
1097#endif /* CORE_H */
diff --git a/drivers/net/wireless/ath9k/hw.c b/drivers/net/wireless/ath9k/hw.c
new file mode 100644
index 000000000000..1f6f3934d379
--- /dev/null
+++ b/drivers/net/wireless/ath9k/hw.c
@@ -0,0 +1,8563 @@
1/*
2 * Copyright (c) 2008 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 <linux/io.h>
18#include <asm/unaligned.h>
19
20#include "core.h"
21#include "hw.h"
22#include "reg.h"
23#include "phy.h"
24#include "initvals.h"
25
26static void ath9k_hw_iqcal_collect(struct ath_hal *ah);
27static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains);
28static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah);
29static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah,
30 u8 numChains);
31static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah);
32static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah,
33 u8 numChains);
34
35static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
36static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
37
38static const struct hal_percal_data iq_cal_multi_sample = {
39 IQ_MISMATCH_CAL,
40 MAX_CAL_SAMPLES,
41 PER_MIN_LOG_COUNT,
42 ath9k_hw_iqcal_collect,
43 ath9k_hw_iqcalibrate
44};
45static const struct hal_percal_data iq_cal_single_sample = {
46 IQ_MISMATCH_CAL,
47 MIN_CAL_SAMPLES,
48 PER_MAX_LOG_COUNT,
49 ath9k_hw_iqcal_collect,
50 ath9k_hw_iqcalibrate
51};
52static const struct hal_percal_data adc_gain_cal_multi_sample = {
53 ADC_GAIN_CAL,
54 MAX_CAL_SAMPLES,
55 PER_MIN_LOG_COUNT,
56 ath9k_hw_adc_gaincal_collect,
57 ath9k_hw_adc_gaincal_calibrate
58};
59static const struct hal_percal_data adc_gain_cal_single_sample = {
60 ADC_GAIN_CAL,
61 MIN_CAL_SAMPLES,
62 PER_MAX_LOG_COUNT,
63 ath9k_hw_adc_gaincal_collect,
64 ath9k_hw_adc_gaincal_calibrate
65};
66static const struct hal_percal_data adc_dc_cal_multi_sample = {
67 ADC_DC_CAL,
68 MAX_CAL_SAMPLES,
69 PER_MIN_LOG_COUNT,
70 ath9k_hw_adc_dccal_collect,
71 ath9k_hw_adc_dccal_calibrate
72};
73static const struct hal_percal_data adc_dc_cal_single_sample = {
74 ADC_DC_CAL,
75 MIN_CAL_SAMPLES,
76 PER_MAX_LOG_COUNT,
77 ath9k_hw_adc_dccal_collect,
78 ath9k_hw_adc_dccal_calibrate
79};
80static const struct hal_percal_data adc_init_dc_cal = {
81 ADC_DC_INIT_CAL,
82 MIN_CAL_SAMPLES,
83 INIT_LOG_COUNT,
84 ath9k_hw_adc_dccal_collect,
85 ath9k_hw_adc_dccal_calibrate
86};
87
88static const struct ath_hal ar5416hal = {
89 AR5416_MAGIC,
90 0,
91 0,
92 NULL,
93 NULL,
94 CTRY_DEFAULT,
95 0,
96 0,
97 0,
98 0,
99 0,
100 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108 },
109};
110
111static struct ath9k_rate_table ar5416_11a_table = {
112 8,
113 {0},
114 {
115 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
116 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
117 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
118 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
119 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
120 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
121 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
122 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}
123 },
124};
125
126static struct ath9k_rate_table ar5416_11b_table = {
127 4,
128 {0},
129 {
130 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
131 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
132 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1},
133 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1}
134 },
135};
136
137static struct ath9k_rate_table ar5416_11g_table = {
138 12,
139 {0},
140 {
141 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
142 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
143 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
144 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
145
146 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
147 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
148 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
149 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
150 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
151 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
152 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
153 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}
154 },
155};
156
157static struct ath9k_rate_table ar5416_11ng_table = {
158 28,
159 {0},
160 {
161 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
162 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
163 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
164 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
165
166 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
167 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
168 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
169 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
170 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
171 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
172 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
173 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8},
174 {true, PHY_HT, 6500, 0x80, 0x00, 0, 4},
175 {true, PHY_HT, 13000, 0x81, 0x00, 1, 6},
176 {true, PHY_HT, 19500, 0x82, 0x00, 2, 6},
177 {true, PHY_HT, 26000, 0x83, 0x00, 3, 8},
178 {true, PHY_HT, 39000, 0x84, 0x00, 4, 8},
179 {true, PHY_HT, 52000, 0x85, 0x00, 5, 8},
180 {true, PHY_HT, 58500, 0x86, 0x00, 6, 8},
181 {true, PHY_HT, 65000, 0x87, 0x00, 7, 8},
182 {true, PHY_HT, 13000, 0x88, 0x00, 8, 4},
183 {true, PHY_HT, 26000, 0x89, 0x00, 9, 6},
184 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6},
185 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8},
186 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8},
187 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8},
188 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8},
189 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8},
190 },
191};
192
193static struct ath9k_rate_table ar5416_11na_table = {
194 24,
195 {0},
196 {
197 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
198 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
199 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
200 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
201 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
202 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
203 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
204 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4},
205 {true, PHY_HT, 6500, 0x80, 0x00, 0, 0},
206 {true, PHY_HT, 13000, 0x81, 0x00, 1, 2},
207 {true, PHY_HT, 19500, 0x82, 0x00, 2, 2},
208 {true, PHY_HT, 26000, 0x83, 0x00, 3, 4},
209 {true, PHY_HT, 39000, 0x84, 0x00, 4, 4},
210 {true, PHY_HT, 52000, 0x85, 0x00, 5, 4},
211 {true, PHY_HT, 58500, 0x86, 0x00, 6, 4},
212 {true, PHY_HT, 65000, 0x87, 0x00, 7, 4},
213 {true, PHY_HT, 13000, 0x88, 0x00, 8, 0},
214 {true, PHY_HT, 26000, 0x89, 0x00, 9, 2},
215 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2},
216 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4},
217 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4},
218 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4},
219 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4},
220 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4},
221 },
222};
223
224static enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
225 const struct ath9k_channel *chan)
226{
227 if (IS_CHAN_CCK(chan))
228 return WIRELESS_MODE_11b;
229 if (IS_CHAN_G(chan))
230 return WIRELESS_MODE_11g;
231 return WIRELESS_MODE_11a;
232}
233
234static bool ath9k_hw_wait(struct ath_hal *ah,
235 u32 reg,
236 u32 mask,
237 u32 val)
238{
239 int i;
240
241 for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
242 if ((REG_READ(ah, reg) & mask) == val)
243 return true;
244
245 udelay(AH_TIME_QUANTUM);
246 }
247 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
248 "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
249 __func__, reg, REG_READ(ah, reg), mask, val);
250 return false;
251}
252
253static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off,
254 u16 *data)
255{
256 (void) REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
257
258 if (!ath9k_hw_wait(ah,
259 AR_EEPROM_STATUS_DATA,
260 AR_EEPROM_STATUS_DATA_BUSY |
261 AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
262 return false;
263 }
264
265 *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
266 AR_EEPROM_STATUS_DATA_VAL);
267
268 return true;
269}
270
271static int ath9k_hw_flash_map(struct ath_hal *ah)
272{
273 struct ath_hal_5416 *ahp = AH5416(ah);
274
275 ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
276
277 if (!ahp->ah_cal_mem) {
278 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
279 "%s: cannot remap eeprom region \n", __func__);
280 return -EIO;
281 }
282
283 return 0;
284}
285
286static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off,
287 u16 *data)
288{
289 struct ath_hal_5416 *ahp = AH5416(ah);
290
291 *data = ioread16(ahp->ah_cal_mem + off);
292 return true;
293}
294
295static void ath9k_hw_read_revisions(struct ath_hal *ah)
296{
297 u32 val;
298
299 val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
300
301 if (val == 0xFF) {
302 val = REG_READ(ah, AR_SREV);
303
304 ah->ah_macVersion =
305 (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
306
307 ah->ah_macRev = MS(val, AR_SREV_REVISION2);
308 ah->ah_isPciExpress =
309 (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
310
311 } else {
312 if (!AR_SREV_9100(ah))
313 ah->ah_macVersion = MS(val, AR_SREV_VERSION);
314
315 ah->ah_macRev = val & AR_SREV_REVISION;
316
317 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
318 ah->ah_isPciExpress = true;
319 }
320}
321
322u32 ath9k_hw_reverse_bits(u32 val, u32 n)
323{
324 u32 retval;
325 int i;
326
327 for (i = 0, retval = 0; i < n; i++) {
328 retval = (retval << 1) | (val & 1);
329 val >>= 1;
330 }
331 return retval;
332}
333
334static void ath9k_hw_set_defaults(struct ath_hal *ah)
335{
336 int i;
337
338 ah->ah_config.ath_hal_dma_beacon_response_time = 2;
339 ah->ah_config.ath_hal_sw_beacon_response_time = 10;
340 ah->ah_config.ath_hal_additional_swba_backoff = 0;
341 ah->ah_config.ath_hal_6mb_ack = 0x0;
342 ah->ah_config.ath_hal_cwmIgnoreExtCCA = 0;
343 ah->ah_config.ath_hal_pciePowerSaveEnable = 0;
344 ah->ah_config.ath_hal_pcieL1SKPEnable = 0;
345 ah->ah_config.ath_hal_pcieClockReq = 0;
346 ah->ah_config.ath_hal_pciePowerReset = 0x100;
347 ah->ah_config.ath_hal_pcieRestore = 0;
348 ah->ah_config.ath_hal_pcieWaen = 0;
349 ah->ah_config.ath_hal_analogShiftReg = 1;
350 ah->ah_config.ath_hal_htEnable = 1;
351 ah->ah_config.ath_hal_ofdmTrigLow = 200;
352 ah->ah_config.ath_hal_ofdmTrigHigh = 500;
353 ah->ah_config.ath_hal_cckTrigHigh = 200;
354 ah->ah_config.ath_hal_cckTrigLow = 100;
355 ah->ah_config.ath_hal_enableANI = 0;
356 ah->ah_config.ath_hal_noiseImmunityLvl = 4;
357 ah->ah_config.ath_hal_ofdmWeakSigDet = 1;
358 ah->ah_config.ath_hal_cckWeakSigThr = 0;
359 ah->ah_config.ath_hal_spurImmunityLvl = 2;
360 ah->ah_config.ath_hal_firStepLvl = 0;
361 ah->ah_config.ath_hal_rssiThrHigh = 40;
362 ah->ah_config.ath_hal_rssiThrLow = 7;
363 ah->ah_config.ath_hal_diversityControl = 0;
364 ah->ah_config.ath_hal_antennaSwitchSwap = 0;
365
366 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
367 ah->ah_config.ath_hal_spurChans[i][0] = AR_NO_SPUR;
368 ah->ah_config.ath_hal_spurChans[i][1] = AR_NO_SPUR;
369 }
370
371 ah->ah_config.ath_hal_intrMitigation = 0;
372}
373
374static inline void ath9k_hw_override_ini(struct ath_hal *ah,
375 struct ath9k_channel *chan)
376{
377 if (!AR_SREV_5416_V20_OR_LATER(ah)
378 || AR_SREV_9280_10_OR_LATER(ah))
379 return;
380
381 REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
382}
383
384static inline void ath9k_hw_init_bb(struct ath_hal *ah,
385 struct ath9k_channel *chan)
386{
387 u32 synthDelay;
388
389 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
390 if (IS_CHAN_CCK(chan))
391 synthDelay = (4 * synthDelay) / 22;
392 else
393 synthDelay /= 10;
394
395 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
396
397 udelay(synthDelay + BASE_ACTIVATE_DELAY);
398}
399
400static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
401 enum ath9k_opmode opmode)
402{
403 struct ath_hal_5416 *ahp = AH5416(ah);
404
405 ahp->ah_maskReg = AR_IMR_TXERR |
406 AR_IMR_TXURN |
407 AR_IMR_RXERR |
408 AR_IMR_RXORN |
409 AR_IMR_BCNMISC;
410
411 if (ahp->ah_intrMitigation)
412 ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
413 else
414 ahp->ah_maskReg |= AR_IMR_RXOK;
415
416 ahp->ah_maskReg |= AR_IMR_TXOK;
417
418 if (opmode == ATH9K_M_HOSTAP)
419 ahp->ah_maskReg |= AR_IMR_MIB;
420
421 REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
422 REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
423
424 if (!AR_SREV_9100(ah)) {
425 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
426 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
427 REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
428 }
429}
430
431static inline void ath9k_hw_init_qos(struct ath_hal *ah)
432{
433 REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
434 REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
435
436 REG_WRITE(ah, AR_QOS_NO_ACK,
437 SM(2, AR_QOS_NO_ACK_TWO_BIT) |
438 SM(5, AR_QOS_NO_ACK_BIT_OFF) |
439 SM(0, AR_QOS_NO_ACK_BYTE_OFF));
440
441 REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
442 REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
443 REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
444 REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
445 REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
446}
447
448static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
449 u32 reg,
450 u32 mask,
451 u32 shift,
452 u32 val)
453{
454 u32 regVal;
455
456 regVal = REG_READ(ah, reg) & ~mask;
457 regVal |= (val << shift) & mask;
458
459 REG_WRITE(ah, reg, regVal);
460
461 if (ah->ah_config.ath_hal_analogShiftReg)
462 udelay(100);
463
464 return;
465}
466
467static u8 ath9k_hw_get_num_ant_config(struct ath_hal_5416 *ahp,
468 enum hal_freq_band freq_band)
469{
470 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
471 struct modal_eep_header *pModal =
472 &(eep->modalHeader[HAL_FREQ_BAND_2GHZ == freq_band]);
473 struct base_eep_header *pBase = &eep->baseEepHeader;
474 u8 num_ant_config;
475
476 num_ant_config = 1;
477
478 if (pBase->version >= 0x0E0D)
479 if (pModal->useAnt1)
480 num_ant_config += 1;
481
482 return num_ant_config;
483}
484
485static int
486ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal_5416 *ahp,
487 struct ath9k_channel *chan,
488 u8 index,
489 u16 *config)
490{
491 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
492 struct modal_eep_header *pModal =
493 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
494 struct base_eep_header *pBase = &eep->baseEepHeader;
495
496 switch (index) {
497 case 0:
498 *config = pModal->antCtrlCommon & 0xFFFF;
499 return 0;
500 case 1:
501 if (pBase->version >= 0x0E0D) {
502 if (pModal->useAnt1) {
503 *config =
504 ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
505 return 0;
506 }
507 }
508 break;
509 default:
510 break;
511 }
512
513 return -EINVAL;
514}
515
516static inline bool ath9k_hw_nvram_read(struct ath_hal *ah,
517 u32 off,
518 u16 *data)
519{
520 if (ath9k_hw_use_flash(ah))
521 return ath9k_hw_flash_read(ah, off, data);
522 else
523 return ath9k_hw_eeprom_read(ah, off, data);
524}
525
526static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
527{
528 struct ath_hal_5416 *ahp = AH5416(ah);
529 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
530 u16 *eep_data;
531 int addr, ar5416_eep_start_loc = 0;
532
533 if (!ath9k_hw_use_flash(ah)) {
534 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
535 "%s: Reading from EEPROM, not flash\n", __func__);
536 ar5416_eep_start_loc = 256;
537 }
538 if (AR_SREV_9100(ah))
539 ar5416_eep_start_loc = 256;
540
541 eep_data = (u16 *) eep;
542 for (addr = 0;
543 addr < sizeof(struct ar5416_eeprom) / sizeof(u16);
544 addr++) {
545 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
546 eep_data)) {
547 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
548 "%s: Unable to read eeprom region \n",
549 __func__);
550 return false;
551 }
552 eep_data++;
553 }
554 return true;
555}
556
557/* XXX: Clean me up, make me more legible */
558static bool
559ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
560 struct ath9k_channel *chan)
561{
562 struct modal_eep_header *pModal;
563 int i, regChainOffset;
564 struct ath_hal_5416 *ahp = AH5416(ah);
565 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
566 u8 txRxAttenLocal;
567 u16 ant_config;
568
569 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
570
571 txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
572
573 ath9k_hw_get_eeprom_antenna_cfg(ahp, chan, 1, &ant_config);
574 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
575
576 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
577 if (AR_SREV_9280(ah)) {
578 if (i >= 2)
579 break;
580 }
581
582 if (AR_SREV_5416_V20_OR_LATER(ah) &&
583 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
584 && (i != 0))
585 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
586 else
587 regChainOffset = i * 0x1000;
588
589 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
590 pModal->antCtrlChain[i]);
591
592 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
593 (REG_READ(ah,
594 AR_PHY_TIMING_CTRL4(0) +
595 regChainOffset) &
596 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
597 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
598 SM(pModal->iqCalICh[i],
599 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
600 SM(pModal->iqCalQCh[i],
601 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
602
603 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
604 if ((eep->baseEepHeader.version &
605 AR5416_EEP_VER_MINOR_MASK) >=
606 AR5416_EEP_MINOR_VER_3) {
607 txRxAttenLocal = pModal->txRxAttenCh[i];
608 if (AR_SREV_9280_10_OR_LATER(ah)) {
609 REG_RMW_FIELD(ah,
610 AR_PHY_GAIN_2GHZ +
611 regChainOffset,
612 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
613 pModal->
614 bswMargin[i]);
615 REG_RMW_FIELD(ah,
616 AR_PHY_GAIN_2GHZ +
617 regChainOffset,
618 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
619 pModal->
620 bswAtten[i]);
621 REG_RMW_FIELD(ah,
622 AR_PHY_GAIN_2GHZ +
623 regChainOffset,
624 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
625 pModal->
626 xatten2Margin[i]);
627 REG_RMW_FIELD(ah,
628 AR_PHY_GAIN_2GHZ +
629 regChainOffset,
630 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
631 pModal->
632 xatten2Db[i]);
633 } else {
634 REG_WRITE(ah,
635 AR_PHY_GAIN_2GHZ +
636 regChainOffset,
637 (REG_READ(ah,
638 AR_PHY_GAIN_2GHZ +
639 regChainOffset) &
640 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
641 | SM(pModal->
642 bswMargin[i],
643 AR_PHY_GAIN_2GHZ_BSW_MARGIN));
644 REG_WRITE(ah,
645 AR_PHY_GAIN_2GHZ +
646 regChainOffset,
647 (REG_READ(ah,
648 AR_PHY_GAIN_2GHZ +
649 regChainOffset) &
650 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
651 | SM(pModal->bswAtten[i],
652 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
653 }
654 }
655 if (AR_SREV_9280_10_OR_LATER(ah)) {
656 REG_RMW_FIELD(ah,
657 AR_PHY_RXGAIN +
658 regChainOffset,
659 AR9280_PHY_RXGAIN_TXRX_ATTEN,
660 txRxAttenLocal);
661 REG_RMW_FIELD(ah,
662 AR_PHY_RXGAIN +
663 regChainOffset,
664 AR9280_PHY_RXGAIN_TXRX_MARGIN,
665 pModal->rxTxMarginCh[i]);
666 } else {
667 REG_WRITE(ah,
668 AR_PHY_RXGAIN + regChainOffset,
669 (REG_READ(ah,
670 AR_PHY_RXGAIN +
671 regChainOffset) &
672 ~AR_PHY_RXGAIN_TXRX_ATTEN) |
673 SM(txRxAttenLocal,
674 AR_PHY_RXGAIN_TXRX_ATTEN));
675 REG_WRITE(ah,
676 AR_PHY_GAIN_2GHZ +
677 regChainOffset,
678 (REG_READ(ah,
679 AR_PHY_GAIN_2GHZ +
680 regChainOffset) &
681 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
682 SM(pModal->rxTxMarginCh[i],
683 AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
684 }
685 }
686 }
687
688 if (AR_SREV_9280_10_OR_LATER(ah)) {
689 if (IS_CHAN_2GHZ(chan)) {
690 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
691 AR_AN_RF2G1_CH0_OB,
692 AR_AN_RF2G1_CH0_OB_S,
693 pModal->ob);
694 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
695 AR_AN_RF2G1_CH0_DB,
696 AR_AN_RF2G1_CH0_DB_S,
697 pModal->db);
698 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
699 AR_AN_RF2G1_CH1_OB,
700 AR_AN_RF2G1_CH1_OB_S,
701 pModal->ob_ch1);
702 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
703 AR_AN_RF2G1_CH1_DB,
704 AR_AN_RF2G1_CH1_DB_S,
705 pModal->db_ch1);
706 } else {
707 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
708 AR_AN_RF5G1_CH0_OB5,
709 AR_AN_RF5G1_CH0_OB5_S,
710 pModal->ob);
711 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
712 AR_AN_RF5G1_CH0_DB5,
713 AR_AN_RF5G1_CH0_DB5_S,
714 pModal->db);
715 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
716 AR_AN_RF5G1_CH1_OB5,
717 AR_AN_RF5G1_CH1_OB5_S,
718 pModal->ob_ch1);
719 ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
720 AR_AN_RF5G1_CH1_DB5,
721 AR_AN_RF5G1_CH1_DB5_S,
722 pModal->db_ch1);
723 }
724 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
725 AR_AN_TOP2_XPABIAS_LVL,
726 AR_AN_TOP2_XPABIAS_LVL_S,
727 pModal->xpaBiasLvl);
728 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
729 AR_AN_TOP2_LOCALBIAS,
730 AR_AN_TOP2_LOCALBIAS_S,
731 pModal->local_bias);
732 DPRINTF(ah->ah_sc, ATH_DBG_ANY, "ForceXPAon: %d\n",
733 pModal->force_xpaon);
734 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
735 pModal->force_xpaon);
736 }
737
738 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
739 pModal->switchSettling);
740 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
741 pModal->adcDesiredSize);
742
743 if (!AR_SREV_9280_10_OR_LATER(ah))
744 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
745 AR_PHY_DESIRED_SZ_PGA,
746 pModal->pgaDesiredSize);
747
748 REG_WRITE(ah, AR_PHY_RF_CTL4,
749 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
750 | SM(pModal->txEndToXpaOff,
751 AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
752 | SM(pModal->txFrameToXpaOn,
753 AR_PHY_RF_CTL4_FRAME_XPAA_ON)
754 | SM(pModal->txFrameToXpaOn,
755 AR_PHY_RF_CTL4_FRAME_XPAB_ON));
756
757 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
758 pModal->txEndToRxOn);
759 if (AR_SREV_9280_10_OR_LATER(ah)) {
760 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
761 pModal->thresh62);
762 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
763 AR_PHY_EXT_CCA0_THRESH62,
764 pModal->thresh62);
765 } else {
766 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
767 pModal->thresh62);
768 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
769 AR_PHY_EXT_CCA_THRESH62,
770 pModal->thresh62);
771 }
772
773 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
774 AR5416_EEP_MINOR_VER_2) {
775 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
776 AR_PHY_TX_END_DATA_START,
777 pModal->txFrameToDataStart);
778 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
779 pModal->txFrameToPaOn);
780 }
781
782 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
783 AR5416_EEP_MINOR_VER_3) {
784 if (IS_CHAN_HT40(chan))
785 REG_RMW_FIELD(ah, AR_PHY_SETTLING,
786 AR_PHY_SETTLING_SWITCH,
787 pModal->swSettleHt40);
788 }
789
790 return true;
791}
792
793static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
794{
795 u32 sum = 0, el;
796 u16 *eepdata;
797 int i;
798 struct ath_hal_5416 *ahp = AH5416(ah);
799 bool need_swap = false;
800 struct ar5416_eeprom *eep =
801 (struct ar5416_eeprom *) &ahp->ah_eeprom;
802
803 if (!ath9k_hw_use_flash(ah)) {
804 u16 magic, magic2;
805 int addr;
806
807 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
808 &magic)) {
809 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
810 "%s: Reading Magic # failed\n", __func__);
811 return false;
812 }
813 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n",
814 __func__, magic);
815
816 if (magic != AR5416_EEPROM_MAGIC) {
817 magic2 = swab16(magic);
818
819 if (magic2 == AR5416_EEPROM_MAGIC) {
820 need_swap = true;
821 eepdata = (u16 *) (&ahp->ah_eeprom);
822
823 for (addr = 0;
824 addr <
825 sizeof(struct ar5416_eeprom) /
826 sizeof(u16); addr++) {
827 u16 temp;
828
829 temp = swab16(*eepdata);
830 *eepdata = temp;
831 eepdata++;
832
833 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
834 "0x%04X ", *eepdata);
835 if (((addr + 1) % 6) == 0)
836 DPRINTF(ah->ah_sc,
837 ATH_DBG_EEPROM,
838 "\n");
839 }
840 } else {
841 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
842 "Invalid EEPROM Magic. "
843 "endianness missmatch.\n");
844 return -EINVAL;
845 }
846 }
847 }
848 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
849 need_swap ? "True" : "False");
850
851 if (need_swap)
852 el = swab16(ahp->ah_eeprom.baseEepHeader.length);
853 else
854 el = ahp->ah_eeprom.baseEepHeader.length;
855
856 if (el > sizeof(struct ar5416_eeprom))
857 el = sizeof(struct ar5416_eeprom) / sizeof(u16);
858 else
859 el = el / sizeof(u16);
860
861 eepdata = (u16 *) (&ahp->ah_eeprom);
862
863 for (i = 0; i < el; i++)
864 sum ^= *eepdata++;
865
866 if (need_swap) {
867 u32 integer, j;
868 u16 word;
869
870 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
871 "EEPROM Endianness is not native.. Changing \n");
872
873 word = swab16(eep->baseEepHeader.length);
874 eep->baseEepHeader.length = word;
875
876 word = swab16(eep->baseEepHeader.checksum);
877 eep->baseEepHeader.checksum = word;
878
879 word = swab16(eep->baseEepHeader.version);
880 eep->baseEepHeader.version = word;
881
882 word = swab16(eep->baseEepHeader.regDmn[0]);
883 eep->baseEepHeader.regDmn[0] = word;
884
885 word = swab16(eep->baseEepHeader.regDmn[1]);
886 eep->baseEepHeader.regDmn[1] = word;
887
888 word = swab16(eep->baseEepHeader.rfSilent);
889 eep->baseEepHeader.rfSilent = word;
890
891 word = swab16(eep->baseEepHeader.blueToothOptions);
892 eep->baseEepHeader.blueToothOptions = word;
893
894 word = swab16(eep->baseEepHeader.deviceCap);
895 eep->baseEepHeader.deviceCap = word;
896
897 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
898 struct modal_eep_header *pModal =
899 &eep->modalHeader[j];
900 integer = swab32(pModal->antCtrlCommon);
901 pModal->antCtrlCommon = integer;
902
903 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
904 integer = swab32(pModal->antCtrlChain[i]);
905 pModal->antCtrlChain[i] = integer;
906 }
907
908 for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
909 word = swab16(pModal->spurChans[i].spurChan);
910 pModal->spurChans[i].spurChan = word;
911 }
912 }
913 }
914
915 if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
916 ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
917 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
918 "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
919 sum, ar5416_get_eep_ver(ahp));
920 return -EINVAL;
921 }
922
923 return 0;
924}
925
926static bool ath9k_hw_chip_test(struct ath_hal *ah)
927{
928 u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
929 u32 regHold[2];
930 u32 patternData[4] = { 0x55555555,
931 0xaaaaaaaa,
932 0x66666666,
933 0x99999999 };
934 int i, j;
935
936 for (i = 0; i < 2; i++) {
937 u32 addr = regAddr[i];
938 u32 wrData, rdData;
939
940 regHold[i] = REG_READ(ah, addr);
941 for (j = 0; j < 0x100; j++) {
942 wrData = (j << 16) | j;
943 REG_WRITE(ah, addr, wrData);
944 rdData = REG_READ(ah, addr);
945 if (rdData != wrData) {
946 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
947 "%s: address test failed "
948 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
949 __func__, addr, wrData, rdData);
950 return false;
951 }
952 }
953 for (j = 0; j < 4; j++) {
954 wrData = patternData[j];
955 REG_WRITE(ah, addr, wrData);
956 rdData = REG_READ(ah, addr);
957 if (wrData != rdData) {
958 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
959 "%s: address test failed "
960 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
961 __func__, addr, wrData, rdData);
962 return false;
963 }
964 }
965 REG_WRITE(ah, regAddr[i], regHold[i]);
966 }
967 udelay(100);
968 return true;
969}
970
971u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
972{
973 u32 bits = REG_READ(ah, AR_RX_FILTER);
974 u32 phybits = REG_READ(ah, AR_PHY_ERR);
975
976 if (phybits & AR_PHY_ERR_RADAR)
977 bits |= ATH9K_RX_FILTER_PHYRADAR;
978 if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
979 bits |= ATH9K_RX_FILTER_PHYERR;
980 return bits;
981}
982
983void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
984{
985 u32 phybits;
986
987 REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
988 phybits = 0;
989 if (bits & ATH9K_RX_FILTER_PHYRADAR)
990 phybits |= AR_PHY_ERR_RADAR;
991 if (bits & ATH9K_RX_FILTER_PHYERR)
992 phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
993 REG_WRITE(ah, AR_PHY_ERR, phybits);
994
995 if (phybits)
996 REG_WRITE(ah, AR_RXCFG,
997 REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
998 else
999 REG_WRITE(ah, AR_RXCFG,
1000 REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
1001}
1002
1003bool ath9k_hw_setcapability(struct ath_hal *ah,
1004 enum hal_capability_type type,
1005 u32 capability,
1006 u32 setting,
1007 int *status)
1008{
1009 struct ath_hal_5416 *ahp = AH5416(ah);
1010 u32 v;
1011
1012 switch (type) {
1013 case HAL_CAP_TKIP_MIC:
1014 if (setting)
1015 ahp->ah_staId1Defaults |=
1016 AR_STA_ID1_CRPT_MIC_ENABLE;
1017 else
1018 ahp->ah_staId1Defaults &=
1019 ~AR_STA_ID1_CRPT_MIC_ENABLE;
1020 return true;
1021 case HAL_CAP_DIVERSITY:
1022 v = REG_READ(ah, AR_PHY_CCK_DETECT);
1023 if (setting)
1024 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1025 else
1026 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1027 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
1028 return true;
1029 case HAL_CAP_MCAST_KEYSRCH:
1030 if (setting)
1031 ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
1032 else
1033 ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
1034 return true;
1035 case HAL_CAP_TSF_ADJUST:
1036 if (setting)
1037 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
1038 else
1039 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
1040 return true;
1041 default:
1042 return false;
1043 }
1044}
1045
1046void ath9k_hw_dmaRegDump(struct ath_hal *ah)
1047{
1048 u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
1049 int qcuOffset = 0, dcuOffset = 0;
1050 u32 *qcuBase = &val[0], *dcuBase = &val[4];
1051 int i;
1052
1053 REG_WRITE(ah, AR_MACMISC,
1054 ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
1055 (AR_MACMISC_MISC_OBS_BUS_1 <<
1056 AR_MACMISC_MISC_OBS_BUS_MSB_S)));
1057
1058 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
1059 for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
1060 if (i % 4 == 0)
1061 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1062
1063 val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
1064 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
1065 }
1066
1067 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
1068 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1069 "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
1070
1071 for (i = 0; i < ATH9K_NUM_QUEUES;
1072 i++, qcuOffset += 4, dcuOffset += 5) {
1073 if (i == 8) {
1074 qcuOffset = 0;
1075 qcuBase++;
1076 }
1077
1078 if (i == 6) {
1079 dcuOffset = 0;
1080 dcuBase++;
1081 }
1082
1083 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1084 "%2d %2x %1x %2x %2x\n",
1085 i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
1086 (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset +
1087 3),
1088 val[2] & (0x7 << (i * 3)) >> (i * 3),
1089 (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
1090 }
1091
1092 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1093 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1094 "qcu_stitch state: %2x qcu_fetch state: %2x\n",
1095 (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
1096 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1097 "qcu_complete state: %2x dcu_complete state: %2x\n",
1098 (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
1099 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1100 "dcu_arb state: %2x dcu_fp state: %2x\n",
1101 (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
1102 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1103 "chan_idle_dur: %3d chan_idle_dur_valid: %1d\n",
1104 (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
1105 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1106 "txfifo_valid_0: %1d txfifo_valid_1: %1d\n",
1107 (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
1108 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1109 "txfifo_dcu_num_0: %2d txfifo_dcu_num_1: %2d\n",
1110 (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
1111
1112 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
1113 REG_READ(ah, AR_OBS_BUS_1));
1114 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1115 "AR_CR 0x%x \n", REG_READ(ah, AR_CR));
1116}
1117
1118u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
1119 u32 *rxc_pcnt,
1120 u32 *rxf_pcnt,
1121 u32 *txf_pcnt)
1122{
1123 static u32 cycles, rx_clear, rx_frame, tx_frame;
1124 u32 good = 1;
1125
1126 u32 rc = REG_READ(ah, AR_RCCNT);
1127 u32 rf = REG_READ(ah, AR_RFCNT);
1128 u32 tf = REG_READ(ah, AR_TFCNT);
1129 u32 cc = REG_READ(ah, AR_CCCNT);
1130
1131 if (cycles == 0 || cycles > cc) {
1132 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1133 "%s: cycle counter wrap. ExtBusy = 0\n",
1134 __func__);
1135 good = 0;
1136 } else {
1137 u32 cc_d = cc - cycles;
1138 u32 rc_d = rc - rx_clear;
1139 u32 rf_d = rf - rx_frame;
1140 u32 tf_d = tf - tx_frame;
1141
1142 if (cc_d != 0) {
1143 *rxc_pcnt = rc_d * 100 / cc_d;
1144 *rxf_pcnt = rf_d * 100 / cc_d;
1145 *txf_pcnt = tf_d * 100 / cc_d;
1146 } else {
1147 good = 0;
1148 }
1149 }
1150
1151 cycles = cc;
1152 rx_frame = rf;
1153 rx_clear = rc;
1154 tx_frame = tf;
1155
1156 return good;
1157}
1158
1159void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
1160{
1161 u32 macmode;
1162
1163 if (mode == ATH9K_HT_MACMODE_2040 &&
1164 !ah->ah_config.ath_hal_cwmIgnoreExtCCA)
1165 macmode = AR_2040_JOINED_RX_CLEAR;
1166 else
1167 macmode = 0;
1168
1169 REG_WRITE(ah, AR_2040_MODE, macmode);
1170}
1171
1172static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
1173{
1174 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1175}
1176
1177
1178static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
1179 struct ath_softc *sc,
1180 void __iomem *mem,
1181 int *status)
1182{
1183 static const u8 defbssidmask[ETH_ALEN] =
1184 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1185 struct ath_hal_5416 *ahp;
1186 struct ath_hal *ah;
1187
1188 ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
1189 if (ahp == NULL) {
1190 DPRINTF(sc, ATH_DBG_FATAL,
1191 "%s: cannot allocate memory for state block\n",
1192 __func__);
1193 *status = -ENOMEM;
1194 return NULL;
1195 }
1196
1197 ah = &ahp->ah;
1198
1199 memcpy(&ahp->ah, &ar5416hal, sizeof(struct ath_hal));
1200
1201 ah->ah_sc = sc;
1202 ah->ah_sh = mem;
1203
1204 ah->ah_devid = devid;
1205 ah->ah_subvendorid = 0;
1206
1207 ah->ah_flags = 0;
1208 if ((devid == AR5416_AR9100_DEVID))
1209 ah->ah_macVersion = AR_SREV_VERSION_9100;
1210 if (!AR_SREV_9100(ah))
1211 ah->ah_flags = AH_USE_EEPROM;
1212
1213 ah->ah_powerLimit = MAX_RATE_POWER;
1214 ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
1215
1216 ahp->ah_atimWindow = 0;
1217 ahp->ah_diversityControl = ah->ah_config.ath_hal_diversityControl;
1218 ahp->ah_antennaSwitchSwap =
1219 ah->ah_config.ath_hal_antennaSwitchSwap;
1220
1221 ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
1222 ahp->ah_beaconInterval = 100;
1223 ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
1224 ahp->ah_slottime = (u32) -1;
1225 ahp->ah_acktimeout = (u32) -1;
1226 ahp->ah_ctstimeout = (u32) -1;
1227 ahp->ah_globaltxtimeout = (u32) -1;
1228 memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN);
1229
1230 ahp->ah_gBeaconRate = 0;
1231
1232 return ahp;
1233}
1234
1235static int ath9k_hw_eeprom_attach(struct ath_hal *ah)
1236{
1237 int status;
1238
1239 if (ath9k_hw_use_flash(ah))
1240 ath9k_hw_flash_map(ah);
1241
1242 if (!ath9k_hw_fill_eeprom(ah))
1243 return -EIO;
1244
1245 status = ath9k_hw_check_eeprom(ah);
1246
1247 return status;
1248}
1249
1250u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
1251 enum eeprom_param param)
1252{
1253 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
1254 struct modal_eep_header *pModal = eep->modalHeader;
1255 struct base_eep_header *pBase = &eep->baseEepHeader;
1256
1257 switch (param) {
1258 case EEP_NFTHRESH_5:
1259 return -pModal[0].noiseFloorThreshCh[0];
1260 case EEP_NFTHRESH_2:
1261 return -pModal[1].noiseFloorThreshCh[0];
1262 case AR_EEPROM_MAC(0):
1263 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
1264 case AR_EEPROM_MAC(1):
1265 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
1266 case AR_EEPROM_MAC(2):
1267 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
1268 case EEP_REG_0:
1269 return pBase->regDmn[0];
1270 case EEP_REG_1:
1271 return pBase->regDmn[1];
1272 case EEP_OP_CAP:
1273 return pBase->deviceCap;
1274 case EEP_OP_MODE:
1275 return pBase->opCapFlags;
1276 case EEP_RF_SILENT:
1277 return pBase->rfSilent;
1278 case EEP_OB_5:
1279 return pModal[0].ob;
1280 case EEP_DB_5:
1281 return pModal[0].db;
1282 case EEP_OB_2:
1283 return pModal[1].ob;
1284 case EEP_DB_2:
1285 return pModal[1].db;
1286 case EEP_MINOR_REV:
1287 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
1288 case EEP_TX_MASK:
1289 return pBase->txMask;
1290 case EEP_RX_MASK:
1291 return pBase->rxMask;
1292 default:
1293 return 0;
1294 }
1295}
1296
1297static inline int ath9k_hw_get_radiorev(struct ath_hal *ah)
1298{
1299 u32 val;
1300 int i;
1301
1302 REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
1303 for (i = 0; i < 8; i++)
1304 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
1305 val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
1306 val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
1307 return ath9k_hw_reverse_bits(val, 8);
1308}
1309
1310static inline int ath9k_hw_init_macaddr(struct ath_hal *ah)
1311{
1312 u32 sum;
1313 int i;
1314 u16 eeval;
1315 struct ath_hal_5416 *ahp = AH5416(ah);
1316 DECLARE_MAC_BUF(mac);
1317
1318 sum = 0;
1319 for (i = 0; i < 3; i++) {
1320 eeval = ath9k_hw_get_eeprom(ahp, AR_EEPROM_MAC(i));
1321 sum += eeval;
1322 ahp->ah_macaddr[2 * i] = eeval >> 8;
1323 ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
1324 }
1325 if (sum == 0 || sum == 0xffff * 3) {
1326 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1327 "%s: mac address read failed: %s\n", __func__,
1328 print_mac(mac, ahp->ah_macaddr));
1329 return -EADDRNOTAVAIL;
1330 }
1331
1332 return 0;
1333}
1334
1335static inline int16_t ath9k_hw_interpolate(u16 target,
1336 u16 srcLeft,
1337 u16 srcRight,
1338 int16_t targetLeft,
1339 int16_t targetRight)
1340{
1341 int16_t rv;
1342
1343 if (srcRight == srcLeft) {
1344 rv = targetLeft;
1345 } else {
1346 rv = (int16_t) (((target - srcLeft) * targetRight +
1347 (srcRight - target) * targetLeft) /
1348 (srcRight - srcLeft));
1349 }
1350 return rv;
1351}
1352
1353static inline u16 ath9k_hw_fbin2freq(u8 fbin,
1354 bool is2GHz)
1355{
1356
1357 if (fbin == AR5416_BCHAN_UNUSED)
1358 return fbin;
1359
1360 return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
1361}
1362
1363static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah,
1364 u16 i,
1365 bool is2GHz)
1366{
1367 struct ath_hal_5416 *ahp = AH5416(ah);
1368 struct ar5416_eeprom *eep =
1369 (struct ar5416_eeprom *) &ahp->ah_eeprom;
1370 u16 spur_val = AR_NO_SPUR;
1371
1372 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1373 "Getting spur idx %d is2Ghz. %d val %x\n",
1374 i, is2GHz, ah->ah_config.ath_hal_spurChans[i][is2GHz]);
1375
1376 switch (ah->ah_config.ath_hal_spurMode) {
1377 case SPUR_DISABLE:
1378 break;
1379 case SPUR_ENABLE_IOCTL:
1380 spur_val = ah->ah_config.ath_hal_spurChans[i][is2GHz];
1381 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1382 "Getting spur val from new loc. %d\n", spur_val);
1383 break;
1384 case SPUR_ENABLE_EEPROM:
1385 spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan;
1386 break;
1387
1388 }
1389 return spur_val;
1390}
1391
1392static inline int ath9k_hw_rfattach(struct ath_hal *ah)
1393{
1394 bool rfStatus = false;
1395 int ecode = 0;
1396
1397 rfStatus = ath9k_hw_init_rf(ah, &ecode);
1398 if (!rfStatus) {
1399 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1400 "%s: RF setup failed, status %u\n", __func__,
1401 ecode);
1402 return ecode;
1403 }
1404
1405 return 0;
1406}
1407
1408static int ath9k_hw_rf_claim(struct ath_hal *ah)
1409{
1410 u32 val;
1411
1412 REG_WRITE(ah, AR_PHY(0), 0x00000007);
1413
1414 val = ath9k_hw_get_radiorev(ah);
1415 switch (val & AR_RADIO_SREV_MAJOR) {
1416 case 0:
1417 val = AR_RAD5133_SREV_MAJOR;
1418 break;
1419 case AR_RAD5133_SREV_MAJOR:
1420 case AR_RAD5122_SREV_MAJOR:
1421 case AR_RAD2133_SREV_MAJOR:
1422 case AR_RAD2122_SREV_MAJOR:
1423 break;
1424 default:
1425 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1426 "%s: 5G Radio Chip Rev 0x%02X is not "
1427 "supported by this driver\n",
1428 __func__, ah->ah_analog5GhzRev);
1429 return -EOPNOTSUPP;
1430 }
1431
1432 ah->ah_analog5GhzRev = val;
1433
1434 return 0;
1435}
1436
1437static inline void ath9k_hw_init_pll(struct ath_hal *ah,
1438 struct ath9k_channel *chan)
1439{
1440 u32 pll;
1441
1442 if (AR_SREV_9100(ah)) {
1443 if (chan && IS_CHAN_5GHZ(chan))
1444 pll = 0x1450;
1445 else
1446 pll = 0x1458;
1447 } else {
1448 if (AR_SREV_9280_10_OR_LATER(ah)) {
1449 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1450
1451 if (chan && IS_CHAN_HALF_RATE(chan))
1452 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1453 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1454 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1455
1456 if (chan && IS_CHAN_5GHZ(chan)) {
1457 pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
1458
1459
1460 if (AR_SREV_9280_20(ah)) {
1461 if (((chan->channel % 20) == 0)
1462 || ((chan->channel % 10) == 0))
1463 pll = 0x2850;
1464 else
1465 pll = 0x142c;
1466 }
1467 } else {
1468 pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
1469 }
1470
1471 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
1472
1473 pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1474
1475 if (chan && IS_CHAN_HALF_RATE(chan))
1476 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1477 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1478 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1479
1480 if (chan && IS_CHAN_5GHZ(chan))
1481 pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
1482 else
1483 pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
1484 } else {
1485 pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1486
1487 if (chan && IS_CHAN_HALF_RATE(chan))
1488 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1489 else if (chan && IS_CHAN_QUARTER_RATE(chan))
1490 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1491
1492 if (chan && IS_CHAN_5GHZ(chan))
1493 pll |= SM(0xa, AR_RTC_PLL_DIV);
1494 else
1495 pll |= SM(0xb, AR_RTC_PLL_DIV);
1496 }
1497 }
1498 REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
1499
1500 udelay(RTC_PLL_SETTLE_DELAY);
1501
1502 REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
1503}
1504
1505static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
1506 enum ath9k_ht_macmode macmode)
1507{
1508 u32 phymode;
1509 struct ath_hal_5416 *ahp = AH5416(ah);
1510
1511 phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
1512 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
1513
1514 if (IS_CHAN_HT40(chan)) {
1515 phymode |= AR_PHY_FC_DYN2040_EN;
1516
1517 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
1518 (chan->chanmode == CHANNEL_G_HT40PLUS))
1519 phymode |= AR_PHY_FC_DYN2040_PRI_CH;
1520
1521 if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
1522 phymode |= AR_PHY_FC_DYN2040_EXT_CH;
1523 }
1524 REG_WRITE(ah, AR_PHY_TURBO, phymode);
1525
1526 ath9k_hw_set11nmac2040(ah, macmode);
1527
1528 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
1529 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
1530}
1531
1532static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
1533{
1534 u32 val;
1535
1536 val = REG_READ(ah, AR_STA_ID1);
1537 val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1538 switch (opmode) {
1539 case ATH9K_M_HOSTAP:
1540 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
1541 | AR_STA_ID1_KSRCH_MODE);
1542 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1543 break;
1544 case ATH9K_M_IBSS:
1545 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
1546 | AR_STA_ID1_KSRCH_MODE);
1547 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1548 break;
1549 case ATH9K_M_STA:
1550 case ATH9K_M_MONITOR:
1551 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1552 break;
1553 }
1554}
1555
1556static inline void
1557ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
1558{
1559 u32 rfMode = 0;
1560
1561 if (chan == NULL)
1562 return;
1563
1564 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
1565 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
1566
1567 if (!AR_SREV_9280_10_OR_LATER(ah))
1568 rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ :
1569 AR_PHY_MODE_RF2GHZ;
1570
1571 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
1572 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
1573
1574 REG_WRITE(ah, AR_PHY_MODE, rfMode);
1575}
1576
1577static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
1578{
1579 u32 rst_flags;
1580 u32 tmpReg;
1581
1582 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1583 AR_RTC_FORCE_WAKE_ON_INT);
1584
1585 if (AR_SREV_9100(ah)) {
1586 rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
1587 AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
1588 } else {
1589 tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
1590 if (tmpReg &
1591 (AR_INTR_SYNC_LOCAL_TIMEOUT |
1592 AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1593 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1594 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
1595 } else {
1596 REG_WRITE(ah, AR_RC, AR_RC_AHB);
1597 }
1598
1599 rst_flags = AR_RTC_RC_MAC_WARM;
1600 if (type == ATH9K_RESET_COLD)
1601 rst_flags |= AR_RTC_RC_MAC_COLD;
1602 }
1603
1604 REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
1605 udelay(50);
1606
1607 REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
1608 if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
1609 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1610 "%s: RTC stuck in MAC reset\n",
1611 __func__);
1612 return false;
1613 }
1614
1615 if (!AR_SREV_9100(ah))
1616 REG_WRITE(ah, AR_RC, 0);
1617
1618 ath9k_hw_init_pll(ah, NULL);
1619
1620 if (AR_SREV_9100(ah))
1621 udelay(50);
1622
1623 return true;
1624}
1625
1626static inline bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
1627{
1628 REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1629 AR_RTC_FORCE_WAKE_ON_INT);
1630
1631 REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
1632 REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
1633
1634 if (!ath9k_hw_wait(ah,
1635 AR_RTC_STATUS,
1636 AR_RTC_STATUS_M,
1637 AR_RTC_STATUS_ON)) {
1638 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n",
1639 __func__);
1640 return false;
1641 }
1642
1643 ath9k_hw_read_revisions(ah);
1644
1645 return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
1646}
1647
1648static bool ath9k_hw_set_reset_reg(struct ath_hal *ah,
1649 u32 type)
1650{
1651 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1652 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1653
1654 switch (type) {
1655 case ATH9K_RESET_POWER_ON:
1656 return ath9k_hw_set_reset_power_on(ah);
1657 break;
1658 case ATH9K_RESET_WARM:
1659 case ATH9K_RESET_COLD:
1660 return ath9k_hw_set_reset(ah, type);
1661 break;
1662 default:
1663 return false;
1664 }
1665}
1666
1667static inline
1668struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
1669 struct ath9k_channel *chan)
1670{
1671 if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
1672 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1673 "%s: invalid channel %u/0x%x; not marked as "
1674 "2GHz or 5GHz\n", __func__, chan->channel,
1675 chan->channelFlags);
1676 return NULL;
1677 }
1678
1679 if (!IS_CHAN_OFDM(chan) &&
1680 !IS_CHAN_CCK(chan) &&
1681 !IS_CHAN_HT20(chan) &&
1682 !IS_CHAN_HT40(chan)) {
1683 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1684 "%s: invalid channel %u/0x%x; not marked as "
1685 "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
1686 __func__, chan->channel, chan->channelFlags);
1687 return NULL;
1688 }
1689
1690 return ath9k_regd_check_channel(ah, chan);
1691}
1692
1693static inline bool
1694ath9k_hw_get_lower_upper_index(u8 target,
1695 u8 *pList,
1696 u16 listSize,
1697 u16 *indexL,
1698 u16 *indexR)
1699{
1700 u16 i;
1701
1702 if (target <= pList[0]) {
1703 *indexL = *indexR = 0;
1704 return true;
1705 }
1706 if (target >= pList[listSize - 1]) {
1707 *indexL = *indexR = (u16) (listSize - 1);
1708 return true;
1709 }
1710
1711 for (i = 0; i < listSize - 1; i++) {
1712 if (pList[i] == target) {
1713 *indexL = *indexR = i;
1714 return true;
1715 }
1716 if (target < pList[i + 1]) {
1717 *indexL = i;
1718 *indexR = (u16) (i + 1);
1719 return false;
1720 }
1721 }
1722 return false;
1723}
1724
1725static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
1726{
1727 int16_t nfval;
1728 int16_t sort[ATH9K_NF_CAL_HIST_MAX];
1729 int i, j;
1730
1731 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
1732 sort[i] = nfCalBuffer[i];
1733
1734 for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
1735 for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
1736 if (sort[j] > sort[j - 1]) {
1737 nfval = sort[j];
1738 sort[j] = sort[j - 1];
1739 sort[j - 1] = nfval;
1740 }
1741 }
1742 }
1743 nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
1744
1745 return nfval;
1746}
1747
1748static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
1749 int16_t *nfarray)
1750{
1751 int i;
1752
1753 for (i = 0; i < NUM_NF_READINGS; i++) {
1754 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
1755
1756 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
1757 h[i].currIndex = 0;
1758
1759 if (h[i].invalidNFcount > 0) {
1760 if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE
1761 || nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
1762 h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
1763 } else {
1764 h[i].invalidNFcount--;
1765 h[i].privNF = nfarray[i];
1766 }
1767 } else {
1768 h[i].privNF =
1769 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
1770 }
1771 }
1772 return;
1773}
1774
1775static void ar5416GetNoiseFloor(struct ath_hal *ah,
1776 int16_t nfarray[NUM_NF_READINGS])
1777{
1778 int16_t nf;
1779
1780 if (AR_SREV_9280_10_OR_LATER(ah))
1781 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
1782 else
1783 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
1784
1785 if (nf & 0x100)
1786 nf = 0 - ((nf ^ 0x1ff) + 1);
1787 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1788 "NF calibrated [ctl] [chain 0] is %d\n", nf);
1789 nfarray[0] = nf;
1790
1791 if (AR_SREV_9280_10_OR_LATER(ah))
1792 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1793 AR9280_PHY_CH1_MINCCA_PWR);
1794 else
1795 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1796 AR_PHY_CH1_MINCCA_PWR);
1797
1798 if (nf & 0x100)
1799 nf = 0 - ((nf ^ 0x1ff) + 1);
1800 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1801 "NF calibrated [ctl] [chain 1] is %d\n", nf);
1802 nfarray[1] = nf;
1803
1804 if (!AR_SREV_9280(ah)) {
1805 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
1806 AR_PHY_CH2_MINCCA_PWR);
1807 if (nf & 0x100)
1808 nf = 0 - ((nf ^ 0x1ff) + 1);
1809 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1810 "NF calibrated [ctl] [chain 2] is %d\n", nf);
1811 nfarray[2] = nf;
1812 }
1813
1814 if (AR_SREV_9280_10_OR_LATER(ah))
1815 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1816 AR9280_PHY_EXT_MINCCA_PWR);
1817 else
1818 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1819 AR_PHY_EXT_MINCCA_PWR);
1820
1821 if (nf & 0x100)
1822 nf = 0 - ((nf ^ 0x1ff) + 1);
1823 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1824 "NF calibrated [ext] [chain 0] is %d\n", nf);
1825 nfarray[3] = nf;
1826
1827 if (AR_SREV_9280_10_OR_LATER(ah))
1828 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1829 AR9280_PHY_CH1_EXT_MINCCA_PWR);
1830 else
1831 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1832 AR_PHY_CH1_EXT_MINCCA_PWR);
1833
1834 if (nf & 0x100)
1835 nf = 0 - ((nf ^ 0x1ff) + 1);
1836 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1837 "NF calibrated [ext] [chain 1] is %d\n", nf);
1838 nfarray[4] = nf;
1839
1840 if (!AR_SREV_9280(ah)) {
1841 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
1842 AR_PHY_CH2_EXT_MINCCA_PWR);
1843 if (nf & 0x100)
1844 nf = 0 - ((nf ^ 0x1ff) + 1);
1845 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1846 "NF calibrated [ext] [chain 2] is %d\n", nf);
1847 nfarray[5] = nf;
1848 }
1849}
1850
1851static bool
1852getNoiseFloorThresh(struct ath_hal *ah,
1853 const struct ath9k_channel *chan,
1854 int16_t *nft)
1855{
1856 struct ath_hal_5416 *ahp = AH5416(ah);
1857
1858 switch (chan->chanmode) {
1859 case CHANNEL_A:
1860 case CHANNEL_A_HT20:
1861 case CHANNEL_A_HT40PLUS:
1862 case CHANNEL_A_HT40MINUS:
1863 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_5);
1864 break;
1865 case CHANNEL_B:
1866 case CHANNEL_G:
1867 case CHANNEL_G_HT20:
1868 case CHANNEL_G_HT40PLUS:
1869 case CHANNEL_G_HT40MINUS:
1870 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_2);
1871 break;
1872 default:
1873 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1874 "%s: invalid channel flags 0x%x\n", __func__,
1875 chan->channelFlags);
1876 return false;
1877 }
1878 return true;
1879}
1880
1881static void ath9k_hw_start_nfcal(struct ath_hal *ah)
1882{
1883 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1884 AR_PHY_AGC_CONTROL_ENABLE_NF);
1885 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1886 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1887 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1888}
1889
1890static void
1891ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
1892{
1893 struct ath9k_nfcal_hist *h;
1894 int i, j;
1895 int32_t val;
1896 const u32 ar5416_cca_regs[6] = {
1897 AR_PHY_CCA,
1898 AR_PHY_CH1_CCA,
1899 AR_PHY_CH2_CCA,
1900 AR_PHY_EXT_CCA,
1901 AR_PHY_CH1_EXT_CCA,
1902 AR_PHY_CH2_EXT_CCA
1903 };
1904 u8 chainmask;
1905
1906 if (AR_SREV_9280(ah))
1907 chainmask = 0x1B;
1908 else
1909 chainmask = 0x3F;
1910
1911#ifdef ATH_NF_PER_CHAN
1912 h = chan->nfCalHist;
1913#else
1914 h = ah->nfCalHist;
1915#endif
1916
1917 for (i = 0; i < NUM_NF_READINGS; i++) {
1918 if (chainmask & (1 << i)) {
1919 val = REG_READ(ah, ar5416_cca_regs[i]);
1920 val &= 0xFFFFFE00;
1921 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1922 REG_WRITE(ah, ar5416_cca_regs[i], val);
1923 }
1924 }
1925
1926 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1927 AR_PHY_AGC_CONTROL_ENABLE_NF);
1928 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1929 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1930 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1931
1932 for (j = 0; j < 1000; j++) {
1933 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1934 AR_PHY_AGC_CONTROL_NF) == 0)
1935 break;
1936 udelay(10);
1937 }
1938
1939 for (i = 0; i < NUM_NF_READINGS; i++) {
1940 if (chainmask & (1 << i)) {
1941 val = REG_READ(ah, ar5416_cca_regs[i]);
1942 val &= 0xFFFFFE00;
1943 val |= (((u32) (-50) << 1) & 0x1ff);
1944 REG_WRITE(ah, ar5416_cca_regs[i], val);
1945 }
1946 }
1947}
1948
1949static int16_t ath9k_hw_getnf(struct ath_hal *ah,
1950 struct ath9k_channel *chan)
1951{
1952 int16_t nf, nfThresh;
1953 int16_t nfarray[NUM_NF_READINGS] = { 0 };
1954 struct ath9k_nfcal_hist *h;
1955 u8 chainmask;
1956
1957 if (AR_SREV_9280(ah))
1958 chainmask = 0x1B;
1959 else
1960 chainmask = 0x3F;
1961
1962 chan->channelFlags &= (~CHANNEL_CW_INT);
1963 if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
1964 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1965 "%s: NF did not complete in calibration window\n",
1966 __func__);
1967 nf = 0;
1968 chan->rawNoiseFloor = nf;
1969 return chan->rawNoiseFloor;
1970 } else {
1971 ar5416GetNoiseFloor(ah, nfarray);
1972 nf = nfarray[0];
1973 if (getNoiseFloorThresh(ah, chan, &nfThresh)
1974 && nf > nfThresh) {
1975 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1976 "%s: noise floor failed detected; "
1977 "detected %d, threshold %d\n", __func__,
1978 nf, nfThresh);
1979 chan->channelFlags |= CHANNEL_CW_INT;
1980 }
1981 }
1982
1983#ifdef ATH_NF_PER_CHAN
1984 h = chan->nfCalHist;
1985#else
1986 h = ah->nfCalHist;
1987#endif
1988
1989 ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
1990 chan->rawNoiseFloor = h[0].privNF;
1991
1992 return chan->rawNoiseFloor;
1993}
1994
1995static void ath9k_hw_update_mibstats(struct ath_hal *ah,
1996 struct ath9k_mib_stats *stats)
1997{
1998 stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
1999 stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
2000 stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
2001 stats->rts_good += REG_READ(ah, AR_RTS_OK);
2002 stats->beacons += REG_READ(ah, AR_BEACON_CNT);
2003}
2004
2005static void ath9k_enable_mib_counters(struct ath_hal *ah)
2006{
2007 struct ath_hal_5416 *ahp = AH5416(ah);
2008
2009 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable mib counters\n");
2010
2011 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2012
2013 REG_WRITE(ah, AR_FILT_OFDM, 0);
2014 REG_WRITE(ah, AR_FILT_CCK, 0);
2015 REG_WRITE(ah, AR_MIBC,
2016 ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
2017 & 0x0f);
2018 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2019 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2020}
2021
2022static void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
2023{
2024 struct ath_hal_5416 *ahp = AH5416(ah);
2025
2026 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling MIB counters\n");
2027
2028 REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
2029
2030 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2031
2032 REG_WRITE(ah, AR_FILT_OFDM, 0);
2033 REG_WRITE(ah, AR_FILT_CCK, 0);
2034}
2035
2036static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
2037 struct ath9k_channel *chan)
2038{
2039 struct ath_hal_5416 *ahp = AH5416(ah);
2040 int i;
2041
2042 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2043 if (ahp->ah_ani[i].c.channel == chan->channel)
2044 return i;
2045 if (ahp->ah_ani[i].c.channel == 0) {
2046 ahp->ah_ani[i].c.channel = chan->channel;
2047 ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
2048 return i;
2049 }
2050 }
2051
2052 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2053 "No more channel states left. Using channel 0\n");
2054 return 0;
2055}
2056
2057static void ath9k_hw_ani_attach(struct ath_hal *ah)
2058{
2059 struct ath_hal_5416 *ahp = AH5416(ah);
2060 int i;
2061
2062 ahp->ah_hasHwPhyCounters = 1;
2063
2064 memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
2065 for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2066 ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
2067 ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
2068 ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
2069 ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
2070 ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
2071 ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
2072 ahp->ah_ani[i].ofdmWeakSigDetectOff =
2073 !ATH9K_ANI_USE_OFDM_WEAK_SIG;
2074 ahp->ah_ani[i].cckWeakSigThreshold =
2075 ATH9K_ANI_CCK_WEAK_SIG_THR;
2076 ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
2077 ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
2078 if (ahp->ah_hasHwPhyCounters) {
2079 ahp->ah_ani[i].ofdmPhyErrBase =
2080 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
2081 ahp->ah_ani[i].cckPhyErrBase =
2082 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
2083 }
2084 }
2085 if (ahp->ah_hasHwPhyCounters) {
2086 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2087 "Setting OfdmErrBase = 0x%08x\n",
2088 ahp->ah_ani[0].ofdmPhyErrBase);
2089 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
2090 ahp->ah_ani[0].cckPhyErrBase);
2091
2092 REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
2093 REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
2094 ath9k_enable_mib_counters(ah);
2095 }
2096 ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
2097 if (ah->ah_config.ath_hal_enableANI)
2098 ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
2099}
2100
2101static inline void ath9k_hw_ani_setup(struct ath_hal *ah)
2102{
2103 struct ath_hal_5416 *ahp = AH5416(ah);
2104 int i;
2105
2106 const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
2107 const int coarseHigh[] = { -14, -14, -14, -14, -12 };
2108 const int coarseLow[] = { -64, -64, -64, -64, -70 };
2109 const int firpwr[] = { -78, -78, -78, -78, -80 };
2110
2111 for (i = 0; i < 5; i++) {
2112 ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
2113 ahp->ah_coarseHigh[i] = coarseHigh[i];
2114 ahp->ah_coarseLow[i] = coarseLow[i];
2115 ahp->ah_firpwr[i] = firpwr[i];
2116 }
2117}
2118
2119static void ath9k_hw_ani_detach(struct ath_hal *ah)
2120{
2121 struct ath_hal_5416 *ahp = AH5416(ah);
2122
2123 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detaching Ani\n");
2124 if (ahp->ah_hasHwPhyCounters) {
2125 ath9k_hw_disable_mib_counters(ah);
2126 REG_WRITE(ah, AR_PHY_ERR_1, 0);
2127 REG_WRITE(ah, AR_PHY_ERR_2, 0);
2128 }
2129}
2130
2131
2132static bool ath9k_hw_ani_control(struct ath_hal *ah,
2133 enum ath9k_ani_cmd cmd, int param)
2134{
2135 struct ath_hal_5416 *ahp = AH5416(ah);
2136 struct ar5416AniState *aniState = ahp->ah_curani;
2137
2138 switch (cmd & ahp->ah_ani_function) {
2139 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
2140 u32 level = param;
2141
2142 if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
2143 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2144 "%s: level out of range (%u > %u)\n",
2145 __func__, level,
2146 (unsigned) ARRAY_SIZE(ahp->
2147 ah_totalSizeDesired));
2148 return false;
2149 }
2150
2151 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
2152 AR_PHY_DESIRED_SZ_TOT_DES,
2153 ahp->ah_totalSizeDesired[level]);
2154 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2155 AR_PHY_AGC_CTL1_COARSE_LOW,
2156 ahp->ah_coarseLow[level]);
2157 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2158 AR_PHY_AGC_CTL1_COARSE_HIGH,
2159 ahp->ah_coarseHigh[level]);
2160 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2161 AR_PHY_FIND_SIG_FIRPWR,
2162 ahp->ah_firpwr[level]);
2163
2164 if (level > aniState->noiseImmunityLevel)
2165 ahp->ah_stats.ast_ani_niup++;
2166 else if (level < aniState->noiseImmunityLevel)
2167 ahp->ah_stats.ast_ani_nidown++;
2168 aniState->noiseImmunityLevel = level;
2169 break;
2170 }
2171 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
2172 const int m1ThreshLow[] = { 127, 50 };
2173 const int m2ThreshLow[] = { 127, 40 };
2174 const int m1Thresh[] = { 127, 0x4d };
2175 const int m2Thresh[] = { 127, 0x40 };
2176 const int m2CountThr[] = { 31, 16 };
2177 const int m2CountThrLow[] = { 63, 48 };
2178 u32 on = param ? 1 : 0;
2179
2180 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2181 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
2182 m1ThreshLow[on]);
2183 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2184 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
2185 m2ThreshLow[on]);
2186 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2187 AR_PHY_SFCORR_M1_THRESH,
2188 m1Thresh[on]);
2189 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2190 AR_PHY_SFCORR_M2_THRESH,
2191 m2Thresh[on]);
2192 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2193 AR_PHY_SFCORR_M2COUNT_THR,
2194 m2CountThr[on]);
2195 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2196 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
2197 m2CountThrLow[on]);
2198
2199 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2200 AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
2201 m1ThreshLow[on]);
2202 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2203 AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
2204 m2ThreshLow[on]);
2205 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2206 AR_PHY_SFCORR_EXT_M1_THRESH,
2207 m1Thresh[on]);
2208 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2209 AR_PHY_SFCORR_EXT_M2_THRESH,
2210 m2Thresh[on]);
2211
2212 if (on)
2213 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
2214 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2215 else
2216 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
2217 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2218
2219 if (!on != aniState->ofdmWeakSigDetectOff) {
2220 if (on)
2221 ahp->ah_stats.ast_ani_ofdmon++;
2222 else
2223 ahp->ah_stats.ast_ani_ofdmoff++;
2224 aniState->ofdmWeakSigDetectOff = !on;
2225 }
2226 break;
2227 }
2228 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
2229 const int weakSigThrCck[] = { 8, 6 };
2230 u32 high = param ? 1 : 0;
2231
2232 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
2233 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
2234 weakSigThrCck[high]);
2235 if (high != aniState->cckWeakSigThreshold) {
2236 if (high)
2237 ahp->ah_stats.ast_ani_cckhigh++;
2238 else
2239 ahp->ah_stats.ast_ani_ccklow++;
2240 aniState->cckWeakSigThreshold = high;
2241 }
2242 break;
2243 }
2244 case ATH9K_ANI_FIRSTEP_LEVEL:{
2245 const int firstep[] = { 0, 4, 8 };
2246 u32 level = param;
2247
2248 if (level >= ARRAY_SIZE(firstep)) {
2249 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2250 "%s: level out of range (%u > %u)\n",
2251 __func__, level,
2252 (unsigned) ARRAY_SIZE(firstep));
2253 return false;
2254 }
2255 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2256 AR_PHY_FIND_SIG_FIRSTEP,
2257 firstep[level]);
2258 if (level > aniState->firstepLevel)
2259 ahp->ah_stats.ast_ani_stepup++;
2260 else if (level < aniState->firstepLevel)
2261 ahp->ah_stats.ast_ani_stepdown++;
2262 aniState->firstepLevel = level;
2263 break;
2264 }
2265 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
2266 const int cycpwrThr1[] =
2267 { 2, 4, 6, 8, 10, 12, 14, 16 };
2268 u32 level = param;
2269
2270 if (level >= ARRAY_SIZE(cycpwrThr1)) {
2271 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2272 "%s: level out of range (%u > %u)\n",
2273 __func__, level,
2274 (unsigned)
2275 ARRAY_SIZE(cycpwrThr1));
2276 return false;
2277 }
2278 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
2279 AR_PHY_TIMING5_CYCPWR_THR1,
2280 cycpwrThr1[level]);
2281 if (level > aniState->spurImmunityLevel)
2282 ahp->ah_stats.ast_ani_spurup++;
2283 else if (level < aniState->spurImmunityLevel)
2284 ahp->ah_stats.ast_ani_spurdown++;
2285 aniState->spurImmunityLevel = level;
2286 break;
2287 }
2288 case ATH9K_ANI_PRESENT:
2289 break;
2290 default:
2291 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2292 "%s: invalid cmd %u\n", __func__, cmd);
2293 return false;
2294 }
2295
2296 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__);
2297 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2298 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
2299 "ofdmWeakSigDetectOff=%d\n",
2300 aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
2301 !aniState->ofdmWeakSigDetectOff);
2302 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2303 "cckWeakSigThreshold=%d, "
2304 "firstepLevel=%d, listenTime=%d\n",
2305 aniState->cckWeakSigThreshold, aniState->firstepLevel,
2306 aniState->listenTime);
2307 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2308 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
2309 aniState->cycleCount, aniState->ofdmPhyErrCount,
2310 aniState->cckPhyErrCount);
2311 return true;
2312}
2313
2314static void ath9k_ani_restart(struct ath_hal *ah)
2315{
2316 struct ath_hal_5416 *ahp = AH5416(ah);
2317 struct ar5416AniState *aniState;
2318
2319 if (!DO_ANI(ah))
2320 return;
2321
2322 aniState = ahp->ah_curani;
2323
2324 aniState->listenTime = 0;
2325 if (ahp->ah_hasHwPhyCounters) {
2326 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
2327 aniState->ofdmPhyErrBase = 0;
2328 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2329 "OFDM Trigger is too high for hw counters\n");
2330 } else {
2331 aniState->ofdmPhyErrBase =
2332 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
2333 }
2334 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
2335 aniState->cckPhyErrBase = 0;
2336 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2337 "CCK Trigger is too high for hw counters\n");
2338 } else {
2339 aniState->cckPhyErrBase =
2340 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
2341 }
2342 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2343 "%s: Writing ofdmbase=%u cckbase=%u\n",
2344 __func__, aniState->ofdmPhyErrBase,
2345 aniState->cckPhyErrBase);
2346 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
2347 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
2348 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2349 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2350
2351 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2352 }
2353 aniState->ofdmPhyErrCount = 0;
2354 aniState->cckPhyErrCount = 0;
2355}
2356
2357static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
2358{
2359 struct ath_hal_5416 *ahp = AH5416(ah);
2360 struct ath9k_channel *chan = ah->ah_curchan;
2361 struct ar5416AniState *aniState;
2362 enum wireless_mode mode;
2363 int32_t rssi;
2364
2365 if (!DO_ANI(ah))
2366 return;
2367
2368 aniState = ahp->ah_curani;
2369
2370 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2371 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2372 aniState->noiseImmunityLevel + 1)) {
2373 return;
2374 }
2375 }
2376
2377 if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
2378 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2379 aniState->spurImmunityLevel + 1)) {
2380 return;
2381 }
2382 }
2383
2384 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2385 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2386 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2387 aniState->firstepLevel + 1);
2388 }
2389 return;
2390 }
2391 rssi = BEACON_RSSI(ahp);
2392 if (rssi > aniState->rssiThrHigh) {
2393 if (!aniState->ofdmWeakSigDetectOff) {
2394 if (ath9k_hw_ani_control(ah,
2395 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2396 false)) {
2397 ath9k_hw_ani_control(ah,
2398 ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2399 0);
2400 return;
2401 }
2402 }
2403 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2404 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2405 aniState->firstepLevel + 1);
2406 return;
2407 }
2408 } else if (rssi > aniState->rssiThrLow) {
2409 if (aniState->ofdmWeakSigDetectOff)
2410 ath9k_hw_ani_control(ah,
2411 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2412 true);
2413 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2414 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2415 aniState->firstepLevel + 1);
2416 return;
2417 } else {
2418 mode = ath9k_hw_chan2wmode(ah, chan);
2419 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
2420 if (!aniState->ofdmWeakSigDetectOff)
2421 ath9k_hw_ani_control(ah,
2422 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2423 false);
2424 if (aniState->firstepLevel > 0)
2425 ath9k_hw_ani_control(ah,
2426 ATH9K_ANI_FIRSTEP_LEVEL,
2427 0);
2428 return;
2429 }
2430 }
2431}
2432
2433static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
2434{
2435 struct ath_hal_5416 *ahp = AH5416(ah);
2436 struct ath9k_channel *chan = ah->ah_curchan;
2437 struct ar5416AniState *aniState;
2438 enum wireless_mode mode;
2439 int32_t rssi;
2440
2441 if (!DO_ANI(ah))
2442 return;
2443
2444 aniState = ahp->ah_curani;
2445 if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2446 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2447 aniState->noiseImmunityLevel + 1)) {
2448 return;
2449 }
2450 }
2451 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2452 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2453 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2454 aniState->firstepLevel + 1);
2455 }
2456 return;
2457 }
2458 rssi = BEACON_RSSI(ahp);
2459 if (rssi > aniState->rssiThrLow) {
2460 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2461 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2462 aniState->firstepLevel + 1);
2463 } else {
2464 mode = ath9k_hw_chan2wmode(ah, chan);
2465 if (mode == WIRELESS_MODE_11g || mode == WIRELESS_MODE_11b) {
2466 if (aniState->firstepLevel > 0)
2467 ath9k_hw_ani_control(ah,
2468 ATH9K_ANI_FIRSTEP_LEVEL,
2469 0);
2470 }
2471 }
2472}
2473
2474static void ath9k_ani_reset(struct ath_hal *ah)
2475{
2476 struct ath_hal_5416 *ahp = AH5416(ah);
2477 struct ar5416AniState *aniState;
2478 struct ath9k_channel *chan = ah->ah_curchan;
2479 int index;
2480
2481 if (!DO_ANI(ah))
2482 return;
2483
2484 index = ath9k_hw_get_ani_channel_idx(ah, chan);
2485 aniState = &ahp->ah_ani[index];
2486 ahp->ah_curani = aniState;
2487
2488 if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA
2489 && ah->ah_opmode != ATH9K_M_IBSS) {
2490 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2491 "%s: Reset ANI state opmode %u\n", __func__,
2492 ah->ah_opmode);
2493 ahp->ah_stats.ast_ani_reset++;
2494 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
2495 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
2496 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
2497 ath9k_hw_ani_control(ah,
2498 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2499 !ATH9K_ANI_USE_OFDM_WEAK_SIG);
2500 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2501 ATH9K_ANI_CCK_WEAK_SIG_THR);
2502 ath9k_hw_setrxfilter(ah,
2503 ath9k_hw_getrxfilter(ah) |
2504 ATH9K_RX_FILTER_PHYERR);
2505 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2506 ahp->ah_curani->ofdmTrigHigh =
2507 ah->ah_config.ath_hal_ofdmTrigHigh;
2508 ahp->ah_curani->ofdmTrigLow =
2509 ah->ah_config.ath_hal_ofdmTrigLow;
2510 ahp->ah_curani->cckTrigHigh =
2511 ah->ah_config.ath_hal_cckTrigHigh;
2512 ahp->ah_curani->cckTrigLow =
2513 ah->ah_config.ath_hal_cckTrigLow;
2514 }
2515 ath9k_ani_restart(ah);
2516 return;
2517 }
2518
2519 if (aniState->noiseImmunityLevel != 0)
2520 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2521 aniState->noiseImmunityLevel);
2522 if (aniState->spurImmunityLevel != 0)
2523 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2524 aniState->spurImmunityLevel);
2525 if (aniState->ofdmWeakSigDetectOff)
2526 ath9k_hw_ani_control(ah,
2527 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2528 !aniState->ofdmWeakSigDetectOff);
2529 if (aniState->cckWeakSigThreshold)
2530 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2531 aniState->cckWeakSigThreshold);
2532 if (aniState->firstepLevel != 0)
2533 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2534 aniState->firstepLevel);
2535 if (ahp->ah_hasHwPhyCounters) {
2536 ath9k_hw_setrxfilter(ah,
2537 ath9k_hw_getrxfilter(ah) &
2538 ~ATH9K_RX_FILTER_PHYERR);
2539 ath9k_ani_restart(ah);
2540 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2541 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2542
2543 } else {
2544 ath9k_ani_restart(ah);
2545 ath9k_hw_setrxfilter(ah,
2546 ath9k_hw_getrxfilter(ah) |
2547 ATH9K_RX_FILTER_PHYERR);
2548 }
2549}
2550
2551void ath9k_hw_procmibevent(struct ath_hal *ah,
2552 const struct ath9k_node_stats *stats)
2553{
2554 struct ath_hal_5416 *ahp = AH5416(ah);
2555 u32 phyCnt1, phyCnt2;
2556
2557 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n");
2558
2559 REG_WRITE(ah, AR_FILT_OFDM, 0);
2560 REG_WRITE(ah, AR_FILT_CCK, 0);
2561 if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
2562 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
2563
2564 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2565 ahp->ah_stats.ast_nodestats = *stats;
2566
2567 if (!DO_ANI(ah))
2568 return;
2569
2570 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2571 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2572 if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
2573 ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
2574 struct ar5416AniState *aniState = ahp->ah_curani;
2575 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2576
2577 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2578 ahp->ah_stats.ast_ani_ofdmerrs +=
2579 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2580 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2581
2582 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2583 ahp->ah_stats.ast_ani_cckerrs +=
2584 cckPhyErrCnt - aniState->cckPhyErrCount;
2585 aniState->cckPhyErrCount = cckPhyErrCnt;
2586
2587 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
2588 ath9k_hw_ani_ofdm_err_trigger(ah);
2589 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
2590 ath9k_hw_ani_cck_err_trigger(ah);
2591
2592 ath9k_ani_restart(ah);
2593 }
2594}
2595
2596static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
2597{
2598 struct ath_hal_5416 *ahp = AH5416(ah);
2599 struct ar5416AniState *aniState;
2600 int32_t rssi;
2601
2602 aniState = ahp->ah_curani;
2603
2604 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2605 if (aniState->firstepLevel > 0) {
2606 if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2607 aniState->firstepLevel - 1)) {
2608 return;
2609 }
2610 }
2611 } else {
2612 rssi = BEACON_RSSI(ahp);
2613 if (rssi > aniState->rssiThrHigh) {
2614 /* XXX: Handle me */
2615 } else if (rssi > aniState->rssiThrLow) {
2616 if (aniState->ofdmWeakSigDetectOff) {
2617 if (ath9k_hw_ani_control(ah,
2618 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2619 true) ==
2620 true) {
2621 return;
2622 }
2623 }
2624 if (aniState->firstepLevel > 0) {
2625 if (ath9k_hw_ani_control
2626 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2627 aniState->firstepLevel - 1) ==
2628 true) {
2629 return;
2630 }
2631 }
2632 } else {
2633 if (aniState->firstepLevel > 0) {
2634 if (ath9k_hw_ani_control
2635 (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2636 aniState->firstepLevel - 1) ==
2637 true) {
2638 return;
2639 }
2640 }
2641 }
2642 }
2643
2644 if (aniState->spurImmunityLevel > 0) {
2645 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2646 aniState->spurImmunityLevel - 1)) {
2647 return;
2648 }
2649 }
2650
2651 if (aniState->noiseImmunityLevel > 0) {
2652 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2653 aniState->noiseImmunityLevel - 1);
2654 return;
2655 }
2656}
2657
2658static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
2659{
2660 struct ath_hal_5416 *ahp = AH5416(ah);
2661 struct ar5416AniState *aniState;
2662 u32 txFrameCount, rxFrameCount, cycleCount;
2663 int32_t listenTime;
2664
2665 txFrameCount = REG_READ(ah, AR_TFCNT);
2666 rxFrameCount = REG_READ(ah, AR_RFCNT);
2667 cycleCount = REG_READ(ah, AR_CCCNT);
2668
2669 aniState = ahp->ah_curani;
2670 if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
2671
2672 listenTime = 0;
2673 ahp->ah_stats.ast_ani_lzero++;
2674 } else {
2675 int32_t ccdelta = cycleCount - aniState->cycleCount;
2676 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
2677 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
2678 listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
2679 }
2680 aniState->cycleCount = cycleCount;
2681 aniState->txFrameCount = txFrameCount;
2682 aniState->rxFrameCount = rxFrameCount;
2683
2684 return listenTime;
2685}
2686
2687void ath9k_hw_ani_monitor(struct ath_hal *ah,
2688 const struct ath9k_node_stats *stats,
2689 struct ath9k_channel *chan)
2690{
2691 struct ath_hal_5416 *ahp = AH5416(ah);
2692 struct ar5416AniState *aniState;
2693 int32_t listenTime;
2694
2695 aniState = ahp->ah_curani;
2696 ahp->ah_stats.ast_nodestats = *stats;
2697
2698 listenTime = ath9k_hw_ani_get_listen_time(ah);
2699 if (listenTime < 0) {
2700 ahp->ah_stats.ast_ani_lneg++;
2701 ath9k_ani_restart(ah);
2702 return;
2703 }
2704
2705 aniState->listenTime += listenTime;
2706
2707 if (ahp->ah_hasHwPhyCounters) {
2708 u32 phyCnt1, phyCnt2;
2709 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2710
2711 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2712
2713 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2714 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2715
2716 if (phyCnt1 < aniState->ofdmPhyErrBase ||
2717 phyCnt2 < aniState->cckPhyErrBase) {
2718 if (phyCnt1 < aniState->ofdmPhyErrBase) {
2719 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2720 "%s: phyCnt1 0x%x, resetting "
2721 "counter value to 0x%x\n",
2722 __func__, phyCnt1,
2723 aniState->ofdmPhyErrBase);
2724 REG_WRITE(ah, AR_PHY_ERR_1,
2725 aniState->ofdmPhyErrBase);
2726 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
2727 AR_PHY_ERR_OFDM_TIMING);
2728 }
2729 if (phyCnt2 < aniState->cckPhyErrBase) {
2730 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2731 "%s: phyCnt2 0x%x, resetting "
2732 "counter value to 0x%x\n",
2733 __func__, phyCnt2,
2734 aniState->cckPhyErrBase);
2735 REG_WRITE(ah, AR_PHY_ERR_2,
2736 aniState->cckPhyErrBase);
2737 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
2738 AR_PHY_ERR_CCK_TIMING);
2739 }
2740 return;
2741 }
2742
2743 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2744 ahp->ah_stats.ast_ani_ofdmerrs +=
2745 ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2746 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2747
2748 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2749 ahp->ah_stats.ast_ani_cckerrs +=
2750 cckPhyErrCnt - aniState->cckPhyErrCount;
2751 aniState->cckPhyErrCount = cckPhyErrCnt;
2752 }
2753
2754 if (!DO_ANI(ah))
2755 return;
2756
2757 if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
2758 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
2759 aniState->ofdmTrigLow / 1000 &&
2760 aniState->cckPhyErrCount <= aniState->listenTime *
2761 aniState->cckTrigLow / 1000)
2762 ath9k_hw_ani_lower_immunity(ah);
2763 ath9k_ani_restart(ah);
2764 } else if (aniState->listenTime > ahp->ah_aniPeriod) {
2765 if (aniState->ofdmPhyErrCount > aniState->listenTime *
2766 aniState->ofdmTrigHigh / 1000) {
2767 ath9k_hw_ani_ofdm_err_trigger(ah);
2768 ath9k_ani_restart(ah);
2769 } else if (aniState->cckPhyErrCount >
2770 aniState->listenTime * aniState->cckTrigHigh /
2771 1000) {
2772 ath9k_hw_ani_cck_err_trigger(ah);
2773 ath9k_ani_restart(ah);
2774 }
2775 }
2776}
2777
2778#ifndef ATH_NF_PER_CHAN
2779static void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
2780{
2781 int i, j;
2782
2783 for (i = 0; i < NUM_NF_READINGS; i++) {
2784 ah->nfCalHist[i].currIndex = 0;
2785 ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
2786 ah->nfCalHist[i].invalidNFcount =
2787 AR_PHY_CCA_FILTERWINDOW_LENGTH;
2788 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
2789 ah->nfCalHist[i].nfCalBuffer[j] =
2790 AR_PHY_CCA_MAX_GOOD_VALUE;
2791 }
2792 }
2793 return;
2794}
2795#endif
2796
2797static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
2798 u32 gpio, u32 type)
2799{
2800 int addr;
2801 u32 gpio_shift, tmp;
2802
2803 if (gpio > 11)
2804 addr = AR_GPIO_OUTPUT_MUX3;
2805 else if (gpio > 5)
2806 addr = AR_GPIO_OUTPUT_MUX2;
2807 else
2808 addr = AR_GPIO_OUTPUT_MUX1;
2809
2810 gpio_shift = (gpio % 6) * 5;
2811
2812 if (AR_SREV_9280_20_OR_LATER(ah)
2813 || (addr != AR_GPIO_OUTPUT_MUX1)) {
2814 REG_RMW(ah, addr, (type << gpio_shift),
2815 (0x1f << gpio_shift));
2816 } else {
2817 tmp = REG_READ(ah, addr);
2818 tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
2819 tmp &= ~(0x1f << gpio_shift);
2820 tmp |= (type << gpio_shift);
2821 REG_WRITE(ah, addr, tmp);
2822 }
2823}
2824
2825static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
2826 enum ath9k_gpio_output_mux_type
2827 halSignalType)
2828{
2829 u32 ah_signal_type;
2830 u32 gpio_shift;
2831
2832 static u32 MuxSignalConversionTable[] = {
2833
2834 AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
2835
2836 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
2837
2838 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
2839
2840 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
2841
2842 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
2843 };
2844
2845 if ((halSignalType >= 0)
2846 && (halSignalType < ARRAY_SIZE(MuxSignalConversionTable)))
2847 ah_signal_type = MuxSignalConversionTable[halSignalType];
2848 else
2849 return false;
2850
2851 ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
2852
2853 gpio_shift = 2 * gpio;
2854
2855 REG_RMW(ah,
2856 AR_GPIO_OE_OUT,
2857 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
2858 (AR_GPIO_OE_OUT_DRV << gpio_shift));
2859
2860 return true;
2861}
2862
2863static bool ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio,
2864 u32 val)
2865{
2866 REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
2867 AR_GPIO_BIT(gpio));
2868 return true;
2869}
2870
2871static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
2872{
2873 if (gpio >= ah->ah_caps.halNumGpioPins)
2874 return 0xffffffff;
2875
2876 if (AR_SREV_9280_10_OR_LATER(ah)) {
2877 return (MS
2878 (REG_READ(ah, AR_GPIO_IN_OUT),
2879 AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
2880 } else {
2881 return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
2882 AR_GPIO_BIT(gpio)) != 0;
2883 }
2884}
2885
2886static inline int ath9k_hw_post_attach(struct ath_hal *ah)
2887{
2888 int ecode;
2889
2890 if (!ath9k_hw_chip_test(ah)) {
2891 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2892 "%s: hardware self-test failed\n", __func__);
2893 return -ENODEV;
2894 }
2895
2896 ecode = ath9k_hw_rf_claim(ah);
2897 if (ecode != 0)
2898 return ecode;
2899
2900 ecode = ath9k_hw_eeprom_attach(ah);
2901 if (ecode != 0)
2902 return ecode;
2903 ecode = ath9k_hw_rfattach(ah);
2904 if (ecode != 0)
2905 return ecode;
2906
2907 if (!AR_SREV_9100(ah)) {
2908 ath9k_hw_ani_setup(ah);
2909 ath9k_hw_ani_attach(ah);
2910 }
2911 return 0;
2912}
2913
2914static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
2915 struct ar5416_eeprom *pEepData,
2916 u32 reg, u32 value)
2917{
2918 struct base_eep_header *pBase = &(pEepData->baseEepHeader);
2919
2920 switch (ah->ah_devid) {
2921 case AR9280_DEVID_PCI:
2922 if (reg == 0x7894) {
2923 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2924 "ini VAL: %x EEPROM: %x\n", value,
2925 (pBase->version & 0xff));
2926
2927 if ((pBase->version & 0xff) > 0x0a) {
2928 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2929 "PWDCLKIND: %d\n",
2930 pBase->pwdclkind);
2931 value &= ~AR_AN_TOP2_PWDCLKIND;
2932 value |= AR_AN_TOP2_PWDCLKIND & (pBase->
2933 pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
2934 } else {
2935 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2936 "PWDCLKIND Earlier Rev\n");
2937 }
2938
2939 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2940 "final ini VAL: %x\n", value);
2941 }
2942 break;
2943 }
2944 return value;
2945}
2946
2947static bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
2948{
2949 struct ath_hal_5416 *ahp = AH5416(ah);
2950 struct hal_capabilities *pCap = &ah->ah_caps;
2951 u16 capField = 0, eeval;
2952
2953 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_0);
2954
2955 ah->ah_currentRD = eeval;
2956
2957 eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_1);
2958 ah->ah_currentRDExt = eeval;
2959
2960 capField = ath9k_hw_get_eeprom(ahp, EEP_OP_CAP);
2961
2962 if (ah->ah_opmode != ATH9K_M_HOSTAP &&
2963 ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
2964 if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
2965 ah->ah_currentRD += 5;
2966 else if (ah->ah_currentRD == 0x41)
2967 ah->ah_currentRD = 0x43;
2968 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
2969 "%s: regdomain mapped to 0x%x\n", __func__,
2970 ah->ah_currentRD);
2971 }
2972
2973 pCap->halWirelessModes = 0;
2974 eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
2975
2976 if (eeval & AR5416_OPFLAGS_11A) {
2977 pCap->halWirelessModes |= ATH9K_MODE_SEL_11A |
2978 ((!ah->ah_config.ath_hal_htEnable
2979 || (eeval & AR5416_OPFLAGS_N_5G_HT20)) ? 0
2980 : (ATH9K_MODE_SEL_11NA_HT20 |
2981 ((eeval & AR5416_OPFLAGS_N_5G_HT40) ? 0
2982 : (ATH9K_MODE_SEL_11NA_HT40PLUS |
2983 ATH9K_MODE_SEL_11NA_HT40MINUS))));
2984 }
2985 if (eeval & AR5416_OPFLAGS_11G) {
2986 pCap->halWirelessModes |=
2987 ATH9K_MODE_SEL_11B | ATH9K_MODE_SEL_11G |
2988 ((!ah->ah_config.ath_hal_htEnable
2989 || (eeval & AR5416_OPFLAGS_N_2G_HT20)) ? 0
2990 : (ATH9K_MODE_SEL_11NG_HT20 |
2991 ((eeval & AR5416_OPFLAGS_N_2G_HT40) ? 0
2992 : (ATH9K_MODE_SEL_11NG_HT40PLUS |
2993 ATH9K_MODE_SEL_11NG_HT40MINUS))));
2994
2995 }
2996 pCap->halTxChainMask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
2997 if ((ah->ah_isPciExpress)
2998 || (eeval & AR5416_OPFLAGS_11A)) {
2999 pCap->halRxChainMask =
3000 ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
3001 } else {
3002 pCap->halRxChainMask =
3003 (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
3004 }
3005
3006 if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
3007 ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
3008
3009 pCap->halLow2GhzChan = 2312;
3010 pCap->halHigh2GhzChan = 2732;
3011
3012 pCap->halLow5GhzChan = 4920;
3013 pCap->halHigh5GhzChan = 6100;
3014
3015 pCap->halCipherCkipSupport = false;
3016 pCap->halCipherTkipSupport = true;
3017 pCap->halCipherAesCcmSupport = true;
3018
3019 pCap->halMicCkipSupport = false;
3020 pCap->halMicTkipSupport = true;
3021 pCap->halMicAesCcmSupport = true;
3022
3023 pCap->halChanSpreadSupport = true;
3024
3025 pCap->halHTSupport =
3026 ah->ah_config.ath_hal_htEnable ? true : false;
3027 pCap->halGTTSupport = true;
3028 pCap->halVEOLSupport = true;
3029 pCap->halBssIdMaskSupport = true;
3030 pCap->halMcastKeySrchSupport = false;
3031
3032 if (capField & AR_EEPROM_EEPCAP_MAXQCU)
3033 pCap->halTotalQueues =
3034 MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
3035 else
3036 pCap->halTotalQueues = ATH9K_NUM_TX_QUEUES;
3037
3038 if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
3039 pCap->halKeyCacheSize =
3040 1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
3041 else
3042 pCap->halKeyCacheSize = AR_KEYTABLE_SIZE;
3043
3044 pCap->halFastCCSupport = true;
3045 pCap->halNumMRRetries = 4;
3046 pCap->halTxTrigLevelMax = MAX_TX_FIFO_THRESHOLD;
3047
3048 if (AR_SREV_9280_10_OR_LATER(ah))
3049 pCap->halNumGpioPins = AR928X_NUM_GPIO;
3050 else
3051 pCap->halNumGpioPins = AR_NUM_GPIO;
3052
3053 if (AR_SREV_9280_10_OR_LATER(ah)) {
3054 pCap->halWowSupport = true;
3055 pCap->halWowMatchPatternExact = true;
3056 } else {
3057 pCap->halWowSupport = false;
3058 pCap->halWowMatchPatternExact = false;
3059 }
3060
3061 if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
3062 pCap->halCSTSupport = true;
3063 pCap->halRtsAggrLimit = ATH_AMPDU_LIMIT_MAX;
3064 } else {
3065 pCap->halRtsAggrLimit = (8 * 1024);
3066 }
3067
3068 pCap->halEnhancedPmSupport = true;
3069
3070 ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
3071 if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
3072 ahp->ah_gpioSelect =
3073 MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
3074 ahp->ah_polarity =
3075 MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
3076
3077 ath9k_hw_setcapability(ah, HAL_CAP_RFSILENT, 1, true,
3078 NULL);
3079 pCap->halRfSilentSupport = true;
3080 }
3081
3082 if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
3083 (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
3084 (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
3085 (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
3086 (ah->ah_macVersion == AR_SREV_VERSION_9280))
3087 pCap->halAutoSleepSupport = false;
3088 else
3089 pCap->halAutoSleepSupport = true;
3090
3091 if (AR_SREV_9280(ah))
3092 pCap->hal4kbSplitTransSupport = false;
3093 else
3094 pCap->hal4kbSplitTransSupport = true;
3095
3096 if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
3097 pCap->halRegCap =
3098 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3099 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
3100 AR_EEPROM_EEREGCAP_EN_KK_U2 |
3101 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
3102 } else {
3103 pCap->halRegCap =
3104 AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3105 AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
3106 }
3107
3108 pCap->halRegCap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
3109
3110 pCap->halNumAntCfg5GHz =
3111 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_5GHZ);
3112 pCap->halNumAntCfg2GHz =
3113 ath9k_hw_get_num_ant_config(ahp, HAL_FREQ_BAND_2GHZ);
3114
3115 return true;
3116}
3117
3118static void ar5416DisablePciePhy(struct ath_hal *ah)
3119{
3120 if (!AR_SREV_9100(ah))
3121 return;
3122
3123 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3124 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3125 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
3126 REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
3127 REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
3128 REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
3129 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3130 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3131 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
3132
3133 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3134}
3135
3136static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
3137{
3138 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3139 if (setChip) {
3140 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3141 AR_RTC_FORCE_WAKE_EN);
3142 if (!AR_SREV_9100(ah))
3143 REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
3144
3145 REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
3146 AR_RTC_RESET_EN);
3147 }
3148}
3149
3150static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
3151{
3152 REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3153 if (setChip) {
3154 struct hal_capabilities *pCap = &ah->ah_caps;
3155
3156 if (!pCap->halAutoSleepSupport) {
3157 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
3158 AR_RTC_FORCE_WAKE_ON_INT);
3159 } else {
3160 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3161 AR_RTC_FORCE_WAKE_EN);
3162 }
3163 }
3164}
3165
3166static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
3167 int setChip)
3168{
3169 u32 val;
3170 int i;
3171
3172 if (setChip) {
3173 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
3174 AR_RTC_STATUS_SHUTDOWN) {
3175 if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
3176 != true) {
3177 return false;
3178 }
3179 }
3180 if (AR_SREV_9100(ah))
3181 REG_SET_BIT(ah, AR_RTC_RESET,
3182 AR_RTC_RESET_EN);
3183
3184 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3185 AR_RTC_FORCE_WAKE_EN);
3186 udelay(50);
3187
3188 for (i = POWER_UP_TIME / 50; i > 0; i--) {
3189 val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
3190 if (val == AR_RTC_STATUS_ON)
3191 break;
3192 udelay(50);
3193 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3194 AR_RTC_FORCE_WAKE_EN);
3195 }
3196 if (i == 0) {
3197 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3198 "%s: Failed to wakeup in %uus\n",
3199 __func__, POWER_UP_TIME / 20);
3200 return false;
3201 }
3202 }
3203
3204 REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3205 return true;
3206}
3207
3208bool ath9k_hw_setpower(struct ath_hal *ah,
3209 enum ath9k_power_mode mode)
3210{
3211 struct ath_hal_5416 *ahp = AH5416(ah);
3212 static const char *modes[] = {
3213 "AWAKE",
3214 "FULL-SLEEP",
3215 "NETWORK SLEEP",
3216 "UNDEFINED"
3217 };
3218 int status = true, setChip = true;
3219
3220 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
3221 modes[ahp->ah_powerMode], modes[mode],
3222 setChip ? "set chip " : "");
3223
3224 switch (mode) {
3225 case ATH9K_PM_AWAKE:
3226 status = ath9k_hw_set_power_awake(ah, setChip);
3227 break;
3228 case ATH9K_PM_FULL_SLEEP:
3229 ath9k_set_power_sleep(ah, setChip);
3230 ahp->ah_chipFullSleep = true;
3231 break;
3232 case ATH9K_PM_NETWORK_SLEEP:
3233 ath9k_set_power_network_sleep(ah, setChip);
3234 break;
3235 default:
3236 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3237 "%s: unknown power mode %u\n", __func__, mode);
3238 return false;
3239 }
3240 ahp->ah_powerMode = mode;
3241 return status;
3242}
3243
3244static struct ath_hal *ath9k_hw_do_attach(u16 devid,
3245 struct ath_softc *sc,
3246 void __iomem *mem,
3247 int *status)
3248{
3249 struct ath_hal_5416 *ahp;
3250 struct ath_hal *ah;
3251 int ecode;
3252#ifndef CONFIG_SLOW_ANT_DIV
3253 u32 i;
3254 u32 j;
3255#endif
3256
3257 ahp = ath9k_hw_newstate(devid, sc, mem, status);
3258 if (ahp == NULL)
3259 return NULL;
3260
3261 ah = &ahp->ah;
3262
3263 ath9k_hw_set_defaults(ah);
3264
3265 if (ah->ah_config.ath_hal_intrMitigation != 0)
3266 ahp->ah_intrMitigation = true;
3267
3268 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
3269 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
3270 __func__);
3271 ecode = -EIO;
3272 goto bad;
3273 }
3274
3275 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
3276 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
3277 __func__);
3278 ecode = -EIO;
3279 goto bad;
3280 }
3281
3282 if (ah->ah_config.ath_hal_serializeRegMode == SER_REG_MODE_AUTO) {
3283 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
3284 ah->ah_config.ath_hal_serializeRegMode =
3285 SER_REG_MODE_ON;
3286 } else {
3287 ah->ah_config.ath_hal_serializeRegMode =
3288 SER_REG_MODE_OFF;
3289 }
3290 }
3291 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3292 "%s: ath_hal_serializeRegMode is %d\n",
3293 __func__, ah->ah_config.ath_hal_serializeRegMode);
3294
3295 if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
3296 (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
3297 (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
3298 (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
3299 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3300 "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3301 "this driver\n", __func__,
3302 ah->ah_macVersion, ah->ah_macRev);
3303 ecode = -EOPNOTSUPP;
3304 goto bad;
3305 }
3306
3307 if (AR_SREV_9100(ah)) {
3308 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3309 ahp->ah_suppCals = IQ_MISMATCH_CAL;
3310 ah->ah_isPciExpress = false;
3311 }
3312 ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
3313
3314 if (AR_SREV_9160_10_OR_LATER(ah)) {
3315 if (AR_SREV_9280_10_OR_LATER(ah)) {
3316 ahp->ah_iqCalData.calData = &iq_cal_single_sample;
3317 ahp->ah_adcGainCalData.calData =
3318 &adc_gain_cal_single_sample;
3319 ahp->ah_adcDcCalData.calData =
3320 &adc_dc_cal_single_sample;
3321 ahp->ah_adcDcCalInitData.calData =
3322 &adc_init_dc_cal;
3323 } else {
3324 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3325 ahp->ah_adcGainCalData.calData =
3326 &adc_gain_cal_multi_sample;
3327 ahp->ah_adcDcCalData.calData =
3328 &adc_dc_cal_multi_sample;
3329 ahp->ah_adcDcCalInitData.calData =
3330 &adc_init_dc_cal;
3331 }
3332 ahp->ah_suppCals =
3333 ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
3334 }
3335
3336 if (AR_SREV_9160(ah)) {
3337 ah->ah_config.ath_hal_enableANI = 1;
3338 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
3339 ATH9K_ANI_FIRSTEP_LEVEL);
3340 } else {
3341 ahp->ah_ani_function = ATH9K_ANI_ALL;
3342 if (AR_SREV_9280_10_OR_LATER(ah)) {
3343 ahp->ah_ani_function &=
3344 ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
3345 }
3346 }
3347
3348 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3349 "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
3350 ah->ah_macVersion, ah->ah_macRev);
3351
3352 if (AR_SREV_9280_20_OR_LATER(ah)) {
3353 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
3354 ARRAY_SIZE(ar9280Modes_9280_2), 6);
3355 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
3356 ARRAY_SIZE(ar9280Common_9280_2), 2);
3357
3358 if (ah->ah_config.ath_hal_pcieClockReq) {
3359 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3360 ar9280PciePhy_clkreq_off_L1_9280,
3361 ARRAY_SIZE
3362 (ar9280PciePhy_clkreq_off_L1_9280),
3363 2);
3364 } else {
3365 INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3366 ar9280PciePhy_clkreq_always_on_L1_9280,
3367 ARRAY_SIZE
3368 (ar9280PciePhy_clkreq_always_on_L1_9280),
3369 2);
3370 }
3371 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
3372 ar9280Modes_fast_clock_9280_2,
3373 ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
3374 3);
3375 } else if (AR_SREV_9280_10_OR_LATER(ah)) {
3376 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
3377 ARRAY_SIZE(ar9280Modes_9280), 6);
3378 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
3379 ARRAY_SIZE(ar9280Common_9280), 2);
3380 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
3381 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
3382 ARRAY_SIZE(ar5416Modes_9160), 6);
3383 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
3384 ARRAY_SIZE(ar5416Common_9160), 2);
3385 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
3386 ARRAY_SIZE(ar5416Bank0_9160), 2);
3387 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
3388 ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
3389 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
3390 ARRAY_SIZE(ar5416Bank1_9160), 2);
3391 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
3392 ARRAY_SIZE(ar5416Bank2_9160), 2);
3393 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
3394 ARRAY_SIZE(ar5416Bank3_9160), 3);
3395 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
3396 ARRAY_SIZE(ar5416Bank6_9160), 3);
3397 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
3398 ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
3399 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
3400 ARRAY_SIZE(ar5416Bank7_9160), 2);
3401 if (AR_SREV_9160_11(ah)) {
3402 INIT_INI_ARRAY(&ahp->ah_iniAddac,
3403 ar5416Addac_91601_1,
3404 ARRAY_SIZE(ar5416Addac_91601_1), 2);
3405 } else {
3406 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
3407 ARRAY_SIZE(ar5416Addac_9160), 2);
3408 }
3409 } else if (AR_SREV_9100_OR_LATER(ah)) {
3410 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
3411 ARRAY_SIZE(ar5416Modes_9100), 6);
3412 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
3413 ARRAY_SIZE(ar5416Common_9100), 2);
3414 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
3415 ARRAY_SIZE(ar5416Bank0_9100), 2);
3416 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
3417 ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
3418 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
3419 ARRAY_SIZE(ar5416Bank1_9100), 2);
3420 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
3421 ARRAY_SIZE(ar5416Bank2_9100), 2);
3422 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
3423 ARRAY_SIZE(ar5416Bank3_9100), 3);
3424 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
3425 ARRAY_SIZE(ar5416Bank6_9100), 3);
3426 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
3427 ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
3428 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
3429 ARRAY_SIZE(ar5416Bank7_9100), 2);
3430 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
3431 ARRAY_SIZE(ar5416Addac_9100), 2);
3432 } else {
3433 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
3434 ARRAY_SIZE(ar5416Modes), 6);
3435 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
3436 ARRAY_SIZE(ar5416Common), 2);
3437 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
3438 ARRAY_SIZE(ar5416Bank0), 2);
3439 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
3440 ARRAY_SIZE(ar5416BB_RfGain), 3);
3441 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
3442 ARRAY_SIZE(ar5416Bank1), 2);
3443 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
3444 ARRAY_SIZE(ar5416Bank2), 2);
3445 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
3446 ARRAY_SIZE(ar5416Bank3), 3);
3447 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
3448 ARRAY_SIZE(ar5416Bank6), 3);
3449 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
3450 ARRAY_SIZE(ar5416Bank6TPC), 3);
3451 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
3452 ARRAY_SIZE(ar5416Bank7), 2);
3453 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
3454 ARRAY_SIZE(ar5416Addac), 2);
3455 }
3456
3457 if (ah->ah_isPciExpress)
3458 ath9k_hw_configpcipowersave(ah, 0);
3459 else
3460 ar5416DisablePciePhy(ah);
3461
3462 ecode = ath9k_hw_post_attach(ah);
3463 if (ecode != 0)
3464 goto bad;
3465
3466#ifndef CONFIG_SLOW_ANT_DIV
3467 if (ah->ah_devid == AR9280_DEVID_PCI) {
3468 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
3469 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
3470
3471 for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
3472 u32 val = INI_RA(&ahp->ah_iniModes, i, j);
3473
3474 INI_RA(&ahp->ah_iniModes, i, j) =
3475 ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
3476 reg, val);
3477 }
3478 }
3479 }
3480#endif
3481
3482 if (!ath9k_hw_fill_cap_info(ah)) {
3483 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3484 "%s:failed ath9k_hw_fill_cap_info\n", __func__);
3485 ecode = -EINVAL;
3486 goto bad;
3487 }
3488
3489 ecode = ath9k_hw_init_macaddr(ah);
3490 if (ecode != 0) {
3491 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3492 "%s: failed initializing mac address\n",
3493 __func__);
3494 goto bad;
3495 }
3496
3497 if (AR_SREV_9285(ah))
3498 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
3499 else
3500 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
3501
3502#ifndef ATH_NF_PER_CHAN
3503
3504 ath9k_init_nfcal_hist_buffer(ah);
3505#endif
3506
3507 return ah;
3508
3509bad:
3510 if (ahp)
3511 ath9k_hw_detach((struct ath_hal *) ahp);
3512 if (status)
3513 *status = ecode;
3514 return NULL;
3515}
3516
3517void ath9k_hw_detach(struct ath_hal *ah)
3518{
3519 if (!AR_SREV_9100(ah))
3520 ath9k_hw_ani_detach(ah);
3521 ath9k_hw_rfdetach(ah);
3522
3523 ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
3524 kfree(ah);
3525}
3526
3527bool ath9k_get_channel_edges(struct ath_hal *ah,
3528 u16 flags, u16 *low,
3529 u16 *high)
3530{
3531 struct hal_capabilities *pCap = &ah->ah_caps;
3532
3533 if (flags & CHANNEL_5GHZ) {
3534 *low = pCap->halLow5GhzChan;
3535 *high = pCap->halHigh5GhzChan;
3536 return true;
3537 }
3538 if ((flags & CHANNEL_2GHZ)) {
3539 *low = pCap->halLow2GhzChan;
3540 *high = pCap->halHigh2GhzChan;
3541
3542 return true;
3543 }
3544 return false;
3545}
3546
3547static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3548 u8 pwrMax,
3549 u8 *pPwrList,
3550 u8 *pVpdList,
3551 u16
3552 numIntercepts,
3553 u8 *pRetVpdList)
3554{
3555 u16 i, k;
3556 u8 currPwr = pwrMin;
3557 u16 idxL = 0, idxR = 0;
3558
3559 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
3560 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
3561 numIntercepts, &(idxL),
3562 &(idxR));
3563 if (idxR < 1)
3564 idxR = 1;
3565 if (idxL == numIntercepts - 1)
3566 idxL = (u16) (numIntercepts - 2);
3567 if (pPwrList[idxL] == pPwrList[idxR])
3568 k = pVpdList[idxL];
3569 else
3570 k = (u16) (((currPwr -
3571 pPwrList[idxL]) *
3572 pVpdList[idxR] +
3573 (pPwrList[idxR] -
3574 currPwr) * pVpdList[idxL]) /
3575 (pPwrList[idxR] -
3576 pPwrList[idxL]));
3577 pRetVpdList[i] = (u8) k;
3578 currPwr += 2;
3579 }
3580
3581 return true;
3582}
3583
3584static inline void
3585ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3586 struct ath9k_channel *chan,
3587 struct cal_data_per_freq *pRawDataSet,
3588 u8 *bChans,
3589 u16 availPiers,
3590 u16 tPdGainOverlap,
3591 int16_t *pMinCalPower,
3592 u16 *pPdGainBoundaries,
3593 u8 *pPDADCValues,
3594 u16 numXpdGains)
3595{
3596 int i, j, k;
3597 int16_t ss;
3598 u16 idxL = 0, idxR = 0, numPiers;
3599 static u8 vpdTableL[AR5416_NUM_PD_GAINS]
3600 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3601 static u8 vpdTableR[AR5416_NUM_PD_GAINS]
3602 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3603 static u8 vpdTableI[AR5416_NUM_PD_GAINS]
3604 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3605
3606 u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3607 u8 minPwrT4[AR5416_NUM_PD_GAINS];
3608 u8 maxPwrT4[AR5416_NUM_PD_GAINS];
3609 int16_t vpdStep;
3610 int16_t tmpVal;
3611 u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3612 bool match;
3613 int16_t minDelta = 0;
3614 struct chan_centers centers;
3615
3616 ath9k_hw_get_channel_centers(ah, chan, &centers);
3617
3618 for (numPiers = 0; numPiers < availPiers; numPiers++) {
3619 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
3620 break;
3621 }
3622
3623 match = ath9k_hw_get_lower_upper_index((u8)
3624 FREQ2FBIN(centers.
3625 synth_center,
3626 IS_CHAN_2GHZ
3627 (chan)), bChans,
3628 numPiers, &idxL, &idxR);
3629
3630 if (match) {
3631 for (i = 0; i < numXpdGains; i++) {
3632 minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3633 maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3634 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3635 pRawDataSet[idxL].
3636 pwrPdg[i],
3637 pRawDataSet[idxL].
3638 vpdPdg[i],
3639 AR5416_PD_GAIN_ICEPTS,
3640 vpdTableI[i]);
3641 }
3642 } else {
3643 for (i = 0; i < numXpdGains; i++) {
3644 pVpdL = pRawDataSet[idxL].vpdPdg[i];
3645 pPwrL = pRawDataSet[idxL].pwrPdg[i];
3646 pVpdR = pRawDataSet[idxR].vpdPdg[i];
3647 pPwrR = pRawDataSet[idxR].pwrPdg[i];
3648
3649 minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3650
3651 maxPwrT4[i] =
3652 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
3653 pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
3654
3655
3656 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3657 pPwrL, pVpdL,
3658 AR5416_PD_GAIN_ICEPTS,
3659 vpdTableL[i]);
3660 ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3661 pPwrR, pVpdR,
3662 AR5416_PD_GAIN_ICEPTS,
3663 vpdTableR[i]);
3664
3665 for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3666 vpdTableI[i][j] =
3667 (u8) (ath9k_hw_interpolate
3668 ((u16)
3669 FREQ2FBIN(centers.
3670 synth_center,
3671 IS_CHAN_2GHZ
3672 (chan)),
3673 bChans[idxL],
3674 bChans[idxR], vpdTableL[i]
3675 [j], vpdTableR[i]
3676 [j]));
3677 }
3678 }
3679 }
3680
3681 *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
3682
3683 k = 0;
3684 for (i = 0; i < numXpdGains; i++) {
3685 if (i == (numXpdGains - 1))
3686 pPdGainBoundaries[i] =
3687 (u16) (maxPwrT4[i] / 2);
3688 else
3689 pPdGainBoundaries[i] =
3690 (u16) ((maxPwrT4[i] +
3691 minPwrT4[i + 1]) / 4);
3692
3693 pPdGainBoundaries[i] =
3694 min((u16) AR5416_MAX_RATE_POWER,
3695 pPdGainBoundaries[i]);
3696
3697 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
3698 minDelta = pPdGainBoundaries[0] - 23;
3699 pPdGainBoundaries[0] = 23;
3700 } else {
3701 minDelta = 0;
3702 }
3703
3704 if (i == 0) {
3705 if (AR_SREV_9280_10_OR_LATER(ah))
3706 ss = (int16_t) (0 - (minPwrT4[i] / 2));
3707 else
3708 ss = 0;
3709 } else {
3710 ss = (int16_t) ((pPdGainBoundaries[i - 1] -
3711 (minPwrT4[i] / 2)) -
3712 tPdGainOverlap + 1 + minDelta);
3713 }
3714 vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
3715 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3716
3717 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3718 tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
3719 pPDADCValues[k++] =
3720 (u8) ((tmpVal < 0) ? 0 : tmpVal);
3721 ss++;
3722 }
3723
3724 sizeCurrVpdTable =
3725 (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3726 tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
3727 (minPwrT4[i] / 2));
3728 maxIndex = (tgtIndex <
3729 sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
3730
3731 while ((ss < maxIndex)
3732 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3733 pPDADCValues[k++] = vpdTableI[i][ss++];
3734 }
3735
3736 vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
3737 vpdTableI[i][sizeCurrVpdTable - 2]);
3738 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3739
3740 if (tgtIndex > maxIndex) {
3741 while ((ss <= tgtIndex)
3742 && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3743 tmpVal = (int16_t) ((vpdTableI[i]
3744 [sizeCurrVpdTable -
3745 1] + (ss - maxIndex +
3746 1) * vpdStep));
3747 pPDADCValues[k++] = (u8) ((tmpVal >
3748 255) ? 255 : tmpVal);
3749 ss++;
3750 }
3751 }
3752 }
3753
3754 while (i < AR5416_PD_GAINS_IN_MASK) {
3755 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
3756 i++;
3757 }
3758
3759 while (k < AR5416_NUM_PDADC_VALUES) {
3760 pPDADCValues[k] = pPDADCValues[k - 1];
3761 k++;
3762 }
3763 return;
3764}
3765
3766static inline bool
3767ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3768 struct ar5416_eeprom *pEepData,
3769 struct ath9k_channel *chan,
3770 int16_t *pTxPowerIndexOffset)
3771{
3772 struct cal_data_per_freq *pRawDataset;
3773 u8 *pCalBChans = NULL;
3774 u16 pdGainOverlap_t2;
3775 static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
3776 u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
3777 u16 numPiers, i, j;
3778 int16_t tMinCalPower;
3779 u16 numXpdGain, xpdMask;
3780 u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
3781 u32 reg32, regOffset, regChainOffset;
3782 int16_t modalIdx;
3783 struct ath_hal_5416 *ahp = AH5416(ah);
3784
3785 modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3786 xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
3787
3788 if ((pEepData->baseEepHeader.
3789 version & AR5416_EEP_VER_MINOR_MASK) >=
3790 AR5416_EEP_MINOR_VER_2) {
3791 pdGainOverlap_t2 =
3792 pEepData->modalHeader[modalIdx].pdGainOverlap;
3793 } else {
3794 pdGainOverlap_t2 =
3795 (u16) (MS
3796 (REG_READ(ah, AR_PHY_TPCRG5),
3797 AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3798 }
3799
3800 if (IS_CHAN_2GHZ(chan)) {
3801 pCalBChans = pEepData->calFreqPier2G;
3802 numPiers = AR5416_NUM_2G_CAL_PIERS;
3803 } else {
3804 pCalBChans = pEepData->calFreqPier5G;
3805 numPiers = AR5416_NUM_5G_CAL_PIERS;
3806 }
3807
3808 numXpdGain = 0;
3809
3810 for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
3811 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
3812 if (numXpdGain >= AR5416_NUM_PD_GAINS)
3813 break;
3814 xpdGainValues[numXpdGain] =
3815 (u16) (AR5416_PD_GAINS_IN_MASK - i);
3816 numXpdGain++;
3817 }
3818 }
3819
3820 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3821 (numXpdGain - 1) & 0x3);
3822 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3823 xpdGainValues[0]);
3824 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3825 xpdGainValues[1]);
3826 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3827 xpdGainValues[2]);
3828
3829 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
3830 if (AR_SREV_5416_V20_OR_LATER(ah) &&
3831 (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
3832 && (i != 0)) {
3833 regChainOffset = (i == 1) ? 0x2000 : 0x1000;
3834 } else
3835 regChainOffset = i * 0x1000;
3836 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3837 if (IS_CHAN_2GHZ(chan))
3838 pRawDataset = pEepData->calPierData2G[i];
3839 else
3840 pRawDataset = pEepData->calPierData5G[i];
3841
3842 ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
3843 pRawDataset,
3844 pCalBChans,
3845 numPiers,
3846 pdGainOverlap_t2,
3847 &tMinCalPower,
3848 gainBoundaries,
3849 pdadcValues,
3850 numXpdGain);
3851
3852 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
3853
3854 REG_WRITE(ah,
3855 AR_PHY_TPCRG5 + regChainOffset,
3856 SM(pdGainOverlap_t2,
3857 AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
3858 | SM(gainBoundaries[0],
3859 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3860 | SM(gainBoundaries[1],
3861 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3862 | SM(gainBoundaries[2],
3863 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3864 | SM(gainBoundaries[3],
3865 AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3866 }
3867
3868 regOffset =
3869 AR_PHY_BASE + (672 << 2) + regChainOffset;
3870 for (j = 0; j < 32; j++) {
3871 reg32 =
3872 ((pdadcValues[4 * j + 0] & 0xFF) << 0)
3873 | ((pdadcValues[4 * j + 1] & 0xFF) <<
3874 8) | ((pdadcValues[4 * j + 2] &
3875 0xFF) << 16) |
3876 ((pdadcValues[4 * j + 3] & 0xFF) <<
3877 24);
3878 REG_WRITE(ah, regOffset, reg32);
3879
3880 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3881 "PDADC (%d,%4x): %4.4x %8.8x\n",
3882 i, regChainOffset, regOffset,
3883 reg32);
3884 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3885 "PDADC: Chain %d | PDADC %3d Value %3d | "
3886 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3887 "PDADC %3d Value %3d |\n",
3888 i, 4 * j, pdadcValues[4 * j],
3889 4 * j + 1, pdadcValues[4 * j + 1],
3890 4 * j + 2, pdadcValues[4 * j + 2],
3891 4 * j + 3,
3892 pdadcValues[4 * j + 3]);
3893
3894 regOffset += 4;
3895 }
3896 }
3897 }
3898 *pTxPowerIndexOffset = 0;
3899
3900 return true;
3901}
3902
3903void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3904{
3905 struct ath_hal_5416 *ahp = AH5416(ah);
3906 u8 i;
3907
3908 if (ah->ah_isPciExpress != true)
3909 return;
3910
3911 if (ah->ah_config.ath_hal_pciePowerSaveEnable == 2)
3912 return;
3913
3914 if (restore)
3915 return;
3916
3917 if (AR_SREV_9280_20_OR_LATER(ah)) {
3918 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
3919 REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
3920 INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
3921 }
3922 udelay(1000);
3923 } else if (AR_SREV_9280(ah)
3924 && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
3925 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3926 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3927
3928 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3929 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3930 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3931
3932 if (ah->ah_config.ath_hal_pcieClockReq)
3933 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3934 else
3935 REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3936
3937 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3938 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3939 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3940
3941 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3942
3943 udelay(1000);
3944 } else {
3945 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3946 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3947 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3948 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3949 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3950 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3951 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3952 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3953 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3954 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3955 }
3956
3957 REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3958
3959 if (ah->ah_config.ath_hal_pcieWaen) {
3960 REG_WRITE(ah, AR_WA, ah->ah_config.ath_hal_pcieWaen);
3961 } else {
3962 if (AR_SREV_9280(ah))
3963 REG_WRITE(ah, AR_WA, 0x0040073f);
3964 else
3965 REG_WRITE(ah, AR_WA, 0x0000073f);
3966 }
3967}
3968
3969static inline void
3970ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3971 struct ath9k_channel *chan,
3972 struct cal_target_power_leg *powInfo,
3973 u16 numChannels,
3974 struct cal_target_power_leg *pNewPower,
3975 u16 numRates,
3976 bool isExtTarget)
3977{
3978 u16 clo, chi;
3979 int i;
3980 int matchIndex = -1, lowIndex = -1;
3981 u16 freq;
3982 struct chan_centers centers;
3983
3984 ath9k_hw_get_channel_centers(ah, chan, &centers);
3985 freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
3986
3987 if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
3988 IS_CHAN_2GHZ(chan))) {
3989 matchIndex = 0;
3990 } else {
3991 for (i = 0; (i < numChannels)
3992 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
3993 if (freq ==
3994 ath9k_hw_fbin2freq(powInfo[i].bChannel,
3995 IS_CHAN_2GHZ(chan))) {
3996 matchIndex = i;
3997 break;
3998 } else if ((freq <
3999 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4000 IS_CHAN_2GHZ(chan)))
4001 && (freq >
4002 ath9k_hw_fbin2freq(powInfo[i - 1].
4003 bChannel,
4004 IS_CHAN_2GHZ
4005 (chan)))) {
4006 lowIndex = i - 1;
4007 break;
4008 }
4009 }
4010 if ((matchIndex == -1) && (lowIndex == -1))
4011 matchIndex = i - 1;
4012 }
4013
4014 if (matchIndex != -1) {
4015 *pNewPower = powInfo[matchIndex];
4016 } else {
4017 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4018 IS_CHAN_2GHZ(chan));
4019 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4020 IS_CHAN_2GHZ(chan));
4021
4022 for (i = 0; i < numRates; i++) {
4023 pNewPower->tPow2x[i] =
4024 (u8) ath9k_hw_interpolate(freq, clo, chi,
4025 powInfo
4026 [lowIndex].
4027 tPow2x[i],
4028 powInfo
4029 [lowIndex +
4030 1].tPow2x[i]);
4031 }
4032 }
4033}
4034
4035static inline void
4036ath9k_hw_get_target_powers(struct ath_hal *ah,
4037 struct ath9k_channel *chan,
4038 struct cal_target_power_ht *powInfo,
4039 u16 numChannels,
4040 struct cal_target_power_ht *pNewPower,
4041 u16 numRates,
4042 bool isHt40Target)
4043{
4044 u16 clo, chi;
4045 int i;
4046 int matchIndex = -1, lowIndex = -1;
4047 u16 freq;
4048 struct chan_centers centers;
4049
4050 ath9k_hw_get_channel_centers(ah, chan, &centers);
4051 freq = isHt40Target ? centers.synth_center : centers.ctl_center;
4052
4053 if (freq <=
4054 ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
4055 matchIndex = 0;
4056 } else {
4057 for (i = 0; (i < numChannels)
4058 && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4059 if (freq ==
4060 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4061 IS_CHAN_2GHZ(chan))) {
4062 matchIndex = i;
4063 break;
4064 } else
4065 if ((freq <
4066 ath9k_hw_fbin2freq(powInfo[i].bChannel,
4067 IS_CHAN_2GHZ(chan)))
4068 && (freq >
4069 ath9k_hw_fbin2freq(powInfo[i - 1].
4070 bChannel,
4071 IS_CHAN_2GHZ
4072 (chan)))) {
4073 lowIndex = i - 1;
4074 break;
4075 }
4076 }
4077 if ((matchIndex == -1) && (lowIndex == -1))
4078 matchIndex = i - 1;
4079 }
4080
4081 if (matchIndex != -1) {
4082 *pNewPower = powInfo[matchIndex];
4083 } else {
4084 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4085 IS_CHAN_2GHZ(chan));
4086 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4087 IS_CHAN_2GHZ(chan));
4088
4089 for (i = 0; i < numRates; i++) {
4090 pNewPower->tPow2x[i] =
4091 (u8) ath9k_hw_interpolate(freq, clo, chi,
4092 powInfo
4093 [lowIndex].
4094 tPow2x[i],
4095 powInfo
4096 [lowIndex +
4097 1].tPow2x[i]);
4098 }
4099 }
4100}
4101
4102static inline u16
4103ath9k_hw_get_max_edge_power(u16 freq,
4104 struct cal_ctl_edges *pRdEdgesPower,
4105 bool is2GHz)
4106{
4107 u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4108 int i;
4109
4110 for (i = 0; (i < AR5416_NUM_BAND_EDGES)
4111 && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4112 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
4113 is2GHz)) {
4114 twiceMaxEdgePower = pRdEdgesPower[i].tPower;
4115 break;
4116 } else if ((i > 0)
4117 && (freq <
4118 ath9k_hw_fbin2freq(pRdEdgesPower[i].
4119 bChannel, is2GHz))) {
4120 if (ath9k_hw_fbin2freq
4121 (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
4122 && pRdEdgesPower[i - 1].flag) {
4123 twiceMaxEdgePower =
4124 pRdEdgesPower[i - 1].tPower;
4125 }
4126 break;
4127 }
4128 }
4129 return twiceMaxEdgePower;
4130}
4131
4132static inline bool
4133ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4134 struct ar5416_eeprom *pEepData,
4135 struct ath9k_channel *chan,
4136 int16_t *ratesArray,
4137 u16 cfgCtl,
4138 u8 AntennaReduction,
4139 u8 twiceMaxRegulatoryPower,
4140 u8 powerLimit)
4141{
4142 u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4143 static const u16 tpScaleReductionTable[5] =
4144 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
4145
4146 int i;
4147 int8_t twiceLargestAntenna;
4148 struct cal_ctl_data *rep;
4149 struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
4150 0, { 0, 0, 0, 0}
4151 };
4152 struct cal_target_power_leg targetPowerOfdmExt = {
4153 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
4154 0, { 0, 0, 0, 0 }
4155 };
4156 struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
4157 0, {0, 0, 0, 0}
4158 };
4159 u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4160 u16 ctlModesFor11a[] =
4161 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
4162 u16 ctlModesFor11g[] =
4163 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
4164 CTL_2GHT40
4165 };
4166 u16 numCtlModes, *pCtlMode, ctlMode, freq;
4167 struct chan_centers centers;
4168 int tx_chainmask;
4169 u8 twiceMinEdgePower;
4170 struct ath_hal_5416 *ahp = AH5416(ah);
4171
4172 tx_chainmask = ahp->ah_txchainmask;
4173
4174 ath9k_hw_get_channel_centers(ah, chan, &centers);
4175
4176 twiceLargestAntenna = max(
4177 pEepData->modalHeader
4178 [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
4179 pEepData->modalHeader
4180 [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
4181
4182 twiceLargestAntenna = max((u8) twiceLargestAntenna,
4183 pEepData->modalHeader
4184 [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
4185
4186 twiceLargestAntenna =
4187 (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
4188
4189 maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4190
4191 if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
4192 maxRegAllowedPower -=
4193 (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
4194 }
4195
4196 scaledPower = min(powerLimit, maxRegAllowedPower);
4197
4198 switch (ar5416_get_ntxchains(tx_chainmask)) {
4199 case 1:
4200 break;
4201 case 2:
4202 scaledPower -=
4203 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4204 pwrDecreaseFor2Chain;
4205 break;
4206 case 3:
4207 scaledPower -=
4208 pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4209 pwrDecreaseFor3Chain;
4210 break;
4211 }
4212
4213 scaledPower = max(0, (int32_t) scaledPower);
4214
4215 if (IS_CHAN_2GHZ(chan)) {
4216 numCtlModes =
4217 ARRAY_SIZE(ctlModesFor11g) -
4218 SUB_NUM_CTL_MODES_AT_2G_40;
4219 pCtlMode = ctlModesFor11g;
4220
4221 ath9k_hw_get_legacy_target_powers(ah, chan,
4222 pEepData->
4223 calTargetPowerCck,
4224 AR5416_NUM_2G_CCK_TARGET_POWERS,
4225 &targetPowerCck, 4,
4226 false);
4227 ath9k_hw_get_legacy_target_powers(ah, chan,
4228 pEepData->
4229 calTargetPower2G,
4230 AR5416_NUM_2G_20_TARGET_POWERS,
4231 &targetPowerOfdm, 4,
4232 false);
4233 ath9k_hw_get_target_powers(ah, chan,
4234 pEepData->calTargetPower2GHT20,
4235 AR5416_NUM_2G_20_TARGET_POWERS,
4236 &targetPowerHt20, 8, false);
4237
4238 if (IS_CHAN_HT40(chan)) {
4239 numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4240 ath9k_hw_get_target_powers(ah, chan,
4241 pEepData->
4242 calTargetPower2GHT40,
4243 AR5416_NUM_2G_40_TARGET_POWERS,
4244 &targetPowerHt40, 8,
4245 true);
4246 ath9k_hw_get_legacy_target_powers(ah, chan,
4247 pEepData->
4248 calTargetPowerCck,
4249 AR5416_NUM_2G_CCK_TARGET_POWERS,
4250 &targetPowerCckExt,
4251 4, true);
4252 ath9k_hw_get_legacy_target_powers(ah, chan,
4253 pEepData->
4254 calTargetPower2G,
4255 AR5416_NUM_2G_20_TARGET_POWERS,
4256 &targetPowerOfdmExt,
4257 4, true);
4258 }
4259 } else {
4260
4261 numCtlModes =
4262 ARRAY_SIZE(ctlModesFor11a) -
4263 SUB_NUM_CTL_MODES_AT_5G_40;
4264 pCtlMode = ctlModesFor11a;
4265
4266 ath9k_hw_get_legacy_target_powers(ah, chan,
4267 pEepData->
4268 calTargetPower5G,
4269 AR5416_NUM_5G_20_TARGET_POWERS,
4270 &targetPowerOfdm, 4,
4271 false);
4272 ath9k_hw_get_target_powers(ah, chan,
4273 pEepData->calTargetPower5GHT20,
4274 AR5416_NUM_5G_20_TARGET_POWERS,
4275 &targetPowerHt20, 8, false);
4276
4277 if (IS_CHAN_HT40(chan)) {
4278 numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4279 ath9k_hw_get_target_powers(ah, chan,
4280 pEepData->
4281 calTargetPower5GHT40,
4282 AR5416_NUM_5G_40_TARGET_POWERS,
4283 &targetPowerHt40, 8,
4284 true);
4285 ath9k_hw_get_legacy_target_powers(ah, chan,
4286 pEepData->
4287 calTargetPower5G,
4288 AR5416_NUM_5G_20_TARGET_POWERS,
4289 &targetPowerOfdmExt,
4290 4, true);
4291 }
4292 }
4293
4294 for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4295 bool isHt40CtlMode =
4296 (pCtlMode[ctlMode] == CTL_5GHT40)
4297 || (pCtlMode[ctlMode] == CTL_2GHT40);
4298 if (isHt40CtlMode)
4299 freq = centers.synth_center;
4300 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4301 freq = centers.ext_center;
4302 else
4303 freq = centers.ctl_center;
4304
4305 if (ar5416_get_eep_ver(ahp) == 14
4306 && ar5416_get_eep_rev(ahp) <= 2)
4307 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4308
4309 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4310 "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4311 "EXT_ADDITIVE %d\n",
4312 ctlMode, numCtlModes, isHt40CtlMode,
4313 (pCtlMode[ctlMode] & EXT_ADDITIVE));
4314
4315 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
4316 i++) {
4317 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4318 " LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4319 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4320 "chan %d\n",
4321 i, cfgCtl, pCtlMode[ctlMode],
4322 pEepData->ctlIndex[i], chan->channel);
4323
4324 if ((((cfgCtl & ~CTL_MODE_M) |
4325 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4326 pEepData->ctlIndex[i])
4327 ||
4328 (((cfgCtl & ~CTL_MODE_M) |
4329 (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4330 ((pEepData->
4331 ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
4332 rep = &(pEepData->ctlData[i]);
4333
4334 twiceMinEdgePower =
4335 ath9k_hw_get_max_edge_power(freq,
4336 rep->
4337 ctlEdges
4338 [ar5416_get_ntxchains
4339 (tx_chainmask)
4340 - 1],
4341 IS_CHAN_2GHZ
4342 (chan));
4343
4344 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4345 " MATCH-EE_IDX %d: ch %d is2 %d "
4346 "2xMinEdge %d chainmask %d chains %d\n",
4347 i, freq, IS_CHAN_2GHZ(chan),
4348 twiceMinEdgePower, tx_chainmask,
4349 ar5416_get_ntxchains
4350 (tx_chainmask));
4351 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
4352 twiceMaxEdgePower =
4353 min(twiceMaxEdgePower,
4354 twiceMinEdgePower);
4355 } else {
4356 twiceMaxEdgePower =
4357 twiceMinEdgePower;
4358 break;
4359 }
4360 }
4361 }
4362
4363 minCtlPower = min(twiceMaxEdgePower, scaledPower);
4364
4365 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4366 " SEL-Min ctlMode %d pCtlMode %d "
4367 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4368 ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4369 scaledPower, minCtlPower);
4370
4371 switch (pCtlMode[ctlMode]) {
4372 case CTL_11B:
4373 for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
4374 i++) {
4375 targetPowerCck.tPow2x[i] =
4376 min(targetPowerCck.tPow2x[i],
4377 minCtlPower);
4378 }
4379 break;
4380 case CTL_11A:
4381 case CTL_11G:
4382 for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
4383 i++) {
4384 targetPowerOfdm.tPow2x[i] =
4385 min(targetPowerOfdm.tPow2x[i],
4386 minCtlPower);
4387 }
4388 break;
4389 case CTL_5GHT20:
4390 case CTL_2GHT20:
4391 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
4392 i++) {
4393 targetPowerHt20.tPow2x[i] =
4394 min(targetPowerHt20.tPow2x[i],
4395 minCtlPower);
4396 }
4397 break;
4398 case CTL_11B_EXT:
4399 targetPowerCckExt.tPow2x[0] =
4400 min(targetPowerCckExt.tPow2x[0], minCtlPower);
4401 break;
4402 case CTL_11A_EXT:
4403 case CTL_11G_EXT:
4404 targetPowerOfdmExt.tPow2x[0] =
4405 min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
4406 break;
4407 case CTL_5GHT40:
4408 case CTL_2GHT40:
4409 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
4410 i++) {
4411 targetPowerHt40.tPow2x[i] =
4412 min(targetPowerHt40.tPow2x[i],
4413 minCtlPower);
4414 }
4415 break;
4416 default:
4417 break;
4418 }
4419 }
4420
4421 ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
4422 ratesArray[rate18mb] = ratesArray[rate24mb] =
4423 targetPowerOfdm.tPow2x[0];
4424 ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
4425 ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
4426 ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
4427 ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
4428
4429 for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
4430 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
4431
4432 if (IS_CHAN_2GHZ(chan)) {
4433 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
4434 ratesArray[rate2s] = ratesArray[rate2l] =
4435 targetPowerCck.tPow2x[1];
4436 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
4437 targetPowerCck.tPow2x[2];
4438 ;
4439 ratesArray[rate11s] = ratesArray[rate11l] =
4440 targetPowerCck.tPow2x[3];
4441 ;
4442 }
4443 if (IS_CHAN_HT40(chan)) {
4444 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
4445 ratesArray[rateHt40_0 + i] =
4446 targetPowerHt40.tPow2x[i];
4447 }
4448 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
4449 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
4450 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
4451 if (IS_CHAN_2GHZ(chan)) {
4452 ratesArray[rateExtCck] =
4453 targetPowerCckExt.tPow2x[0];
4454 }
4455 }
4456 return true;
4457}
4458
4459static int
4460ath9k_hw_set_txpower(struct ath_hal *ah,
4461 struct ar5416_eeprom *pEepData,
4462 struct ath9k_channel *chan,
4463 u16 cfgCtl,
4464 u8 twiceAntennaReduction,
4465 u8 twiceMaxRegulatoryPower,
4466 u8 powerLimit)
4467{
4468 struct modal_eep_header *pModal =
4469 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
4470 int16_t ratesArray[Ar5416RateSize];
4471 int16_t txPowerIndexOffset = 0;
4472 u8 ht40PowerIncForPdadc = 2;
4473 int i;
4474
4475 memset(ratesArray, 0, sizeof(ratesArray));
4476
4477 if ((pEepData->baseEepHeader.
4478 version & AR5416_EEP_VER_MINOR_MASK) >=
4479 AR5416_EEP_MINOR_VER_2) {
4480 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
4481 }
4482
4483 if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
4484 &ratesArray[0], cfgCtl,
4485 twiceAntennaReduction,
4486 twiceMaxRegulatoryPower,
4487 powerLimit)) {
4488 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4489 "ath9k_hw_set_txpower: unable to set "
4490 "tx power per rate table\n");
4491 return -EIO;
4492 }
4493
4494 if (!ath9k_hw_set_power_cal_table
4495 (ah, pEepData, chan, &txPowerIndexOffset)) {
4496 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4497 "ath9k_hw_set_txpower: unable to set power table\n");
4498 return -EIO;
4499 }
4500
4501 for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
4502 ratesArray[i] =
4503 (int16_t) (txPowerIndexOffset + ratesArray[i]);
4504 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
4505 ratesArray[i] = AR5416_MAX_RATE_POWER;
4506 }
4507
4508 if (AR_SREV_9280_10_OR_LATER(ah)) {
4509 for (i = 0; i < Ar5416RateSize; i++)
4510 ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
4511 }
4512
4513 REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
4514 ATH9K_POW_SM(ratesArray[rate18mb], 24)
4515 | ATH9K_POW_SM(ratesArray[rate12mb], 16)
4516 | ATH9K_POW_SM(ratesArray[rate9mb], 8)
4517 | ATH9K_POW_SM(ratesArray[rate6mb], 0)
4518 );
4519 REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
4520 ATH9K_POW_SM(ratesArray[rate54mb], 24)
4521 | ATH9K_POW_SM(ratesArray[rate48mb], 16)
4522 | ATH9K_POW_SM(ratesArray[rate36mb], 8)
4523 | ATH9K_POW_SM(ratesArray[rate24mb], 0)
4524 );
4525
4526 if (IS_CHAN_2GHZ(chan)) {
4527 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
4528 ATH9K_POW_SM(ratesArray[rate2s], 24)
4529 | ATH9K_POW_SM(ratesArray[rate2l], 16)
4530 | ATH9K_POW_SM(ratesArray[rateXr], 8)
4531 | ATH9K_POW_SM(ratesArray[rate1l], 0)
4532 );
4533 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
4534 ATH9K_POW_SM(ratesArray[rate11s], 24)
4535 | ATH9K_POW_SM(ratesArray[rate11l], 16)
4536 | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
4537 | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
4538 );
4539 }
4540
4541 REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
4542 ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
4543 | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
4544 | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
4545 | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
4546 );
4547 REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
4548 ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
4549 | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
4550 | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
4551 | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
4552 );
4553
4554 if (IS_CHAN_HT40(chan)) {
4555 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
4556 ATH9K_POW_SM(ratesArray[rateHt40_3] +
4557 ht40PowerIncForPdadc, 24)
4558 | ATH9K_POW_SM(ratesArray[rateHt40_2] +
4559 ht40PowerIncForPdadc, 16)
4560 | ATH9K_POW_SM(ratesArray[rateHt40_1] +
4561 ht40PowerIncForPdadc, 8)
4562 | ATH9K_POW_SM(ratesArray[rateHt40_0] +
4563 ht40PowerIncForPdadc, 0)
4564 );
4565 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
4566 ATH9K_POW_SM(ratesArray[rateHt40_7] +
4567 ht40PowerIncForPdadc, 24)
4568 | ATH9K_POW_SM(ratesArray[rateHt40_6] +
4569 ht40PowerIncForPdadc, 16)
4570 | ATH9K_POW_SM(ratesArray[rateHt40_5] +
4571 ht40PowerIncForPdadc, 8)
4572 | ATH9K_POW_SM(ratesArray[rateHt40_4] +
4573 ht40PowerIncForPdadc, 0)
4574 );
4575
4576 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
4577 ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
4578 | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
4579 | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
4580 | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
4581 );
4582 }
4583
4584 REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
4585 ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
4586 | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
4587 );
4588
4589 i = rate6mb;
4590 if (IS_CHAN_HT40(chan))
4591 i = rateHt40_0;
4592 else if (IS_CHAN_HT20(chan))
4593 i = rateHt20_0;
4594
4595 if (AR_SREV_9280_10_OR_LATER(ah))
4596 ah->ah_maxPowerLevel =
4597 ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
4598 else
4599 ah->ah_maxPowerLevel = ratesArray[i];
4600
4601 return 0;
4602}
4603
4604static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
4605 u32 coef_scaled,
4606 u32 *coef_mantissa,
4607 u32 *coef_exponent)
4608{
4609 u32 coef_exp, coef_man;
4610
4611 for (coef_exp = 31; coef_exp > 0; coef_exp--)
4612 if ((coef_scaled >> coef_exp) & 0x1)
4613 break;
4614
4615 coef_exp = 14 - (coef_exp - COEF_SCALE_S);
4616
4617 coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
4618
4619 *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
4620 *coef_exponent = coef_exp - 16;
4621}
4622
4623static void
4624ath9k_hw_set_delta_slope(struct ath_hal *ah,
4625 struct ath9k_channel *chan)
4626{
4627 u32 coef_scaled, ds_coef_exp, ds_coef_man;
4628 u32 clockMhzScaled = 0x64000000;
4629 struct chan_centers centers;
4630
4631 if (IS_CHAN_HALF_RATE(chan))
4632 clockMhzScaled = clockMhzScaled >> 1;
4633 else if (IS_CHAN_QUARTER_RATE(chan))
4634 clockMhzScaled = clockMhzScaled >> 2;
4635
4636 ath9k_hw_get_channel_centers(ah, chan, &centers);
4637 coef_scaled = clockMhzScaled / centers.synth_center;
4638
4639 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4640 &ds_coef_exp);
4641
4642 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4643 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
4644 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4645 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
4646
4647 coef_scaled = (9 * coef_scaled) / 10;
4648
4649 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4650 &ds_coef_exp);
4651
4652 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4653 AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
4654 REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4655 AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
4656}
4657
4658static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
4659 struct ath9k_channel *chan)
4660{
4661 int bb_spur = AR_NO_SPUR;
4662 int freq;
4663 int bin, cur_bin;
4664 int bb_spur_off, spur_subchannel_sd;
4665 int spur_freq_sd;
4666 int spur_delta_phase;
4667 int denominator;
4668 int upper, lower, cur_vit_mask;
4669 int tmp, newVal;
4670 int i;
4671 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4672 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4673 };
4674 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4675 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4676 };
4677 int inc[4] = { 0, 100, 0, 0 };
4678 struct chan_centers centers;
4679
4680 int8_t mask_m[123];
4681 int8_t mask_p[123];
4682 int8_t mask_amt;
4683 int tmp_mask;
4684 int cur_bb_spur;
4685 bool is2GHz = IS_CHAN_2GHZ(chan);
4686
4687 memset(&mask_m, 0, sizeof(int8_t) * 123);
4688 memset(&mask_p, 0, sizeof(int8_t) * 123);
4689
4690 ath9k_hw_get_channel_centers(ah, chan, &centers);
4691 freq = centers.synth_center;
4692
4693 ah->ah_config.ath_hal_spurMode = SPUR_ENABLE_EEPROM;
4694 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4695 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4696
4697 if (is2GHz)
4698 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
4699 else
4700 cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
4701
4702 if (AR_NO_SPUR == cur_bb_spur)
4703 break;
4704 cur_bb_spur = cur_bb_spur - freq;
4705
4706 if (IS_CHAN_HT40(chan)) {
4707 if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
4708 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
4709 bb_spur = cur_bb_spur;
4710 break;
4711 }
4712 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
4713 (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
4714 bb_spur = cur_bb_spur;
4715 break;
4716 }
4717 }
4718
4719 if (AR_NO_SPUR == bb_spur) {
4720 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4721 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4722 return;
4723 } else {
4724 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4725 AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4726 }
4727
4728 bin = bb_spur * 320;
4729
4730 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4731
4732 newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4733 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4734 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4735 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4736 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
4737
4738 newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4739 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4740 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4741 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4742 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4743 REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
4744
4745 if (IS_CHAN_HT40(chan)) {
4746 if (bb_spur < 0) {
4747 spur_subchannel_sd = 1;
4748 bb_spur_off = bb_spur + 10;
4749 } else {
4750 spur_subchannel_sd = 0;
4751 bb_spur_off = bb_spur - 10;
4752 }
4753 } else {
4754 spur_subchannel_sd = 0;
4755 bb_spur_off = bb_spur;
4756 }
4757
4758 if (IS_CHAN_HT40(chan))
4759 spur_delta_phase =
4760 ((bb_spur * 262144) /
4761 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4762 else
4763 spur_delta_phase =
4764 ((bb_spur * 524288) /
4765 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4766
4767 denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
4768 spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
4769
4770 newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4771 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4772 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4773 REG_WRITE(ah, AR_PHY_TIMING11, newVal);
4774
4775 newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
4776 REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
4777
4778 cur_bin = -6000;
4779 upper = bin + 100;
4780 lower = bin - 100;
4781
4782 for (i = 0; i < 4; i++) {
4783 int pilot_mask = 0;
4784 int chan_mask = 0;
4785 int bp = 0;
4786 for (bp = 0; bp < 30; bp++) {
4787 if ((cur_bin > lower) && (cur_bin < upper)) {
4788 pilot_mask = pilot_mask | 0x1 << bp;
4789 chan_mask = chan_mask | 0x1 << bp;
4790 }
4791 cur_bin += 100;
4792 }
4793 cur_bin += inc[i];
4794 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4795 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4796 }
4797
4798 cur_vit_mask = 6100;
4799 upper = bin + 120;
4800 lower = bin - 120;
4801
4802 for (i = 0; i < 123; i++) {
4803 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
4804 if ((abs(cur_vit_mask - bin)) < 75)
4805 mask_amt = 1;
4806 else
4807 mask_amt = 0;
4808 if (cur_vit_mask < 0)
4809 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4810 else
4811 mask_p[cur_vit_mask / 100] = mask_amt;
4812 }
4813 cur_vit_mask -= 100;
4814 }
4815
4816 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4817 | (mask_m[48] << 26) | (mask_m[49] << 24)
4818 | (mask_m[50] << 22) | (mask_m[51] << 20)
4819 | (mask_m[52] << 18) | (mask_m[53] << 16)
4820 | (mask_m[54] << 14) | (mask_m[55] << 12)
4821 | (mask_m[56] << 10) | (mask_m[57] << 8)
4822 | (mask_m[58] << 6) | (mask_m[59] << 4)
4823 | (mask_m[60] << 2) | (mask_m[61] << 0);
4824 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4825 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4826
4827 tmp_mask = (mask_m[31] << 28)
4828 | (mask_m[32] << 26) | (mask_m[33] << 24)
4829 | (mask_m[34] << 22) | (mask_m[35] << 20)
4830 | (mask_m[36] << 18) | (mask_m[37] << 16)
4831 | (mask_m[48] << 14) | (mask_m[39] << 12)
4832 | (mask_m[40] << 10) | (mask_m[41] << 8)
4833 | (mask_m[42] << 6) | (mask_m[43] << 4)
4834 | (mask_m[44] << 2) | (mask_m[45] << 0);
4835 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4836 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4837
4838 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4839 | (mask_m[18] << 26) | (mask_m[18] << 24)
4840 | (mask_m[20] << 22) | (mask_m[20] << 20)
4841 | (mask_m[22] << 18) | (mask_m[22] << 16)
4842 | (mask_m[24] << 14) | (mask_m[24] << 12)
4843 | (mask_m[25] << 10) | (mask_m[26] << 8)
4844 | (mask_m[27] << 6) | (mask_m[28] << 4)
4845 | (mask_m[29] << 2) | (mask_m[30] << 0);
4846 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4847 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4848
4849 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4850 | (mask_m[2] << 26) | (mask_m[3] << 24)
4851 | (mask_m[4] << 22) | (mask_m[5] << 20)
4852 | (mask_m[6] << 18) | (mask_m[7] << 16)
4853 | (mask_m[8] << 14) | (mask_m[9] << 12)
4854 | (mask_m[10] << 10) | (mask_m[11] << 8)
4855 | (mask_m[12] << 6) | (mask_m[13] << 4)
4856 | (mask_m[14] << 2) | (mask_m[15] << 0);
4857 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4858 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4859
4860 tmp_mask = (mask_p[15] << 28)
4861 | (mask_p[14] << 26) | (mask_p[13] << 24)
4862 | (mask_p[12] << 22) | (mask_p[11] << 20)
4863 | (mask_p[10] << 18) | (mask_p[9] << 16)
4864 | (mask_p[8] << 14) | (mask_p[7] << 12)
4865 | (mask_p[6] << 10) | (mask_p[5] << 8)
4866 | (mask_p[4] << 6) | (mask_p[3] << 4)
4867 | (mask_p[2] << 2) | (mask_p[1] << 0);
4868 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4869 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4870
4871 tmp_mask = (mask_p[30] << 28)
4872 | (mask_p[29] << 26) | (mask_p[28] << 24)
4873 | (mask_p[27] << 22) | (mask_p[26] << 20)
4874 | (mask_p[25] << 18) | (mask_p[24] << 16)
4875 | (mask_p[23] << 14) | (mask_p[22] << 12)
4876 | (mask_p[21] << 10) | (mask_p[20] << 8)
4877 | (mask_p[19] << 6) | (mask_p[18] << 4)
4878 | (mask_p[17] << 2) | (mask_p[16] << 0);
4879 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4880 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4881
4882 tmp_mask = (mask_p[45] << 28)
4883 | (mask_p[44] << 26) | (mask_p[43] << 24)
4884 | (mask_p[42] << 22) | (mask_p[41] << 20)
4885 | (mask_p[40] << 18) | (mask_p[39] << 16)
4886 | (mask_p[38] << 14) | (mask_p[37] << 12)
4887 | (mask_p[36] << 10) | (mask_p[35] << 8)
4888 | (mask_p[34] << 6) | (mask_p[33] << 4)
4889 | (mask_p[32] << 2) | (mask_p[31] << 0);
4890 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4891 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4892
4893 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4894 | (mask_p[59] << 26) | (mask_p[58] << 24)
4895 | (mask_p[57] << 22) | (mask_p[56] << 20)
4896 | (mask_p[55] << 18) | (mask_p[54] << 16)
4897 | (mask_p[53] << 14) | (mask_p[52] << 12)
4898 | (mask_p[51] << 10) | (mask_p[50] << 8)
4899 | (mask_p[49] << 6) | (mask_p[48] << 4)
4900 | (mask_p[47] << 2) | (mask_p[46] << 0);
4901 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4902 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4903}
4904
4905static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4906 struct ath9k_channel *chan)
4907{
4908 int bb_spur = AR_NO_SPUR;
4909 int bin, cur_bin;
4910 int spur_freq_sd;
4911 int spur_delta_phase;
4912 int denominator;
4913 int upper, lower, cur_vit_mask;
4914 int tmp, new;
4915 int i;
4916 int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4917 AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4918 };
4919 int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4920 AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4921 };
4922 int inc[4] = { 0, 100, 0, 0 };
4923
4924 int8_t mask_m[123];
4925 int8_t mask_p[123];
4926 int8_t mask_amt;
4927 int tmp_mask;
4928 int cur_bb_spur;
4929 bool is2GHz = IS_CHAN_2GHZ(chan);
4930
4931 memset(&mask_m, 0, sizeof(int8_t) * 123);
4932 memset(&mask_p, 0, sizeof(int8_t) * 123);
4933
4934 for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4935 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4936 if (AR_NO_SPUR == cur_bb_spur)
4937 break;
4938 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4939 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4940 bb_spur = cur_bb_spur;
4941 break;
4942 }
4943 }
4944
4945 if (AR_NO_SPUR == bb_spur)
4946 return;
4947
4948 bin = bb_spur * 32;
4949
4950 tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4951 new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4952 AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4953 AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4954 AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4955
4956 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4957
4958 new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4959 AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4960 AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4961 AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4962 SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4963 REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4964
4965 spur_delta_phase = ((bb_spur * 524288) / 100) &
4966 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4967
4968 denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4969 spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4970
4971 new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4972 SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4973 SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4974 REG_WRITE(ah, AR_PHY_TIMING11, new);
4975
4976 cur_bin = -6000;
4977 upper = bin + 100;
4978 lower = bin - 100;
4979
4980 for (i = 0; i < 4; i++) {
4981 int pilot_mask = 0;
4982 int chan_mask = 0;
4983 int bp = 0;
4984 for (bp = 0; bp < 30; bp++) {
4985 if ((cur_bin > lower) && (cur_bin < upper)) {
4986 pilot_mask = pilot_mask | 0x1 << bp;
4987 chan_mask = chan_mask | 0x1 << bp;
4988 }
4989 cur_bin += 100;
4990 }
4991 cur_bin += inc[i];
4992 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4993 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4994 }
4995
4996 cur_vit_mask = 6100;
4997 upper = bin + 120;
4998 lower = bin - 120;
4999
5000 for (i = 0; i < 123; i++) {
5001 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
5002 if ((abs(cur_vit_mask - bin)) < 75)
5003 mask_amt = 1;
5004 else
5005 mask_amt = 0;
5006 if (cur_vit_mask < 0)
5007 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5008 else
5009 mask_p[cur_vit_mask / 100] = mask_amt;
5010 }
5011 cur_vit_mask -= 100;
5012 }
5013
5014 tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5015 | (mask_m[48] << 26) | (mask_m[49] << 24)
5016 | (mask_m[50] << 22) | (mask_m[51] << 20)
5017 | (mask_m[52] << 18) | (mask_m[53] << 16)
5018 | (mask_m[54] << 14) | (mask_m[55] << 12)
5019 | (mask_m[56] << 10) | (mask_m[57] << 8)
5020 | (mask_m[58] << 6) | (mask_m[59] << 4)
5021 | (mask_m[60] << 2) | (mask_m[61] << 0);
5022 REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5023 REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5024
5025 tmp_mask = (mask_m[31] << 28)
5026 | (mask_m[32] << 26) | (mask_m[33] << 24)
5027 | (mask_m[34] << 22) | (mask_m[35] << 20)
5028 | (mask_m[36] << 18) | (mask_m[37] << 16)
5029 | (mask_m[48] << 14) | (mask_m[39] << 12)
5030 | (mask_m[40] << 10) | (mask_m[41] << 8)
5031 | (mask_m[42] << 6) | (mask_m[43] << 4)
5032 | (mask_m[44] << 2) | (mask_m[45] << 0);
5033 REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5034 REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5035
5036 tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5037 | (mask_m[18] << 26) | (mask_m[18] << 24)
5038 | (mask_m[20] << 22) | (mask_m[20] << 20)
5039 | (mask_m[22] << 18) | (mask_m[22] << 16)
5040 | (mask_m[24] << 14) | (mask_m[24] << 12)
5041 | (mask_m[25] << 10) | (mask_m[26] << 8)
5042 | (mask_m[27] << 6) | (mask_m[28] << 4)
5043 | (mask_m[29] << 2) | (mask_m[30] << 0);
5044 REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5045 REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5046
5047 tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5048 | (mask_m[2] << 26) | (mask_m[3] << 24)
5049 | (mask_m[4] << 22) | (mask_m[5] << 20)
5050 | (mask_m[6] << 18) | (mask_m[7] << 16)
5051 | (mask_m[8] << 14) | (mask_m[9] << 12)
5052 | (mask_m[10] << 10) | (mask_m[11] << 8)
5053 | (mask_m[12] << 6) | (mask_m[13] << 4)
5054 | (mask_m[14] << 2) | (mask_m[15] << 0);
5055 REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5056 REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5057
5058 tmp_mask = (mask_p[15] << 28)
5059 | (mask_p[14] << 26) | (mask_p[13] << 24)
5060 | (mask_p[12] << 22) | (mask_p[11] << 20)
5061 | (mask_p[10] << 18) | (mask_p[9] << 16)
5062 | (mask_p[8] << 14) | (mask_p[7] << 12)
5063 | (mask_p[6] << 10) | (mask_p[5] << 8)
5064 | (mask_p[4] << 6) | (mask_p[3] << 4)
5065 | (mask_p[2] << 2) | (mask_p[1] << 0);
5066 REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5067 REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5068
5069 tmp_mask = (mask_p[30] << 28)
5070 | (mask_p[29] << 26) | (mask_p[28] << 24)
5071 | (mask_p[27] << 22) | (mask_p[26] << 20)
5072 | (mask_p[25] << 18) | (mask_p[24] << 16)
5073 | (mask_p[23] << 14) | (mask_p[22] << 12)
5074 | (mask_p[21] << 10) | (mask_p[20] << 8)
5075 | (mask_p[19] << 6) | (mask_p[18] << 4)
5076 | (mask_p[17] << 2) | (mask_p[16] << 0);
5077 REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5078 REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5079
5080 tmp_mask = (mask_p[45] << 28)
5081 | (mask_p[44] << 26) | (mask_p[43] << 24)
5082 | (mask_p[42] << 22) | (mask_p[41] << 20)
5083 | (mask_p[40] << 18) | (mask_p[39] << 16)
5084 | (mask_p[38] << 14) | (mask_p[37] << 12)
5085 | (mask_p[36] << 10) | (mask_p[35] << 8)
5086 | (mask_p[34] << 6) | (mask_p[33] << 4)
5087 | (mask_p[32] << 2) | (mask_p[31] << 0);
5088 REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5089 REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5090
5091 tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5092 | (mask_p[59] << 26) | (mask_p[58] << 24)
5093 | (mask_p[57] << 22) | (mask_p[56] << 20)
5094 | (mask_p[55] << 18) | (mask_p[54] << 16)
5095 | (mask_p[53] << 14) | (mask_p[52] << 12)
5096 | (mask_p[51] << 10) | (mask_p[50] << 8)
5097 | (mask_p[49] << 6) | (mask_p[48] << 4)
5098 | (mask_p[47] << 2) | (mask_p[46] << 0);
5099 REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5100 REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5101}
5102
5103static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5104{
5105 struct ath_hal_5416 *ahp = AH5416(ah);
5106 int rx_chainmask, tx_chainmask;
5107
5108 rx_chainmask = ahp->ah_rxchainmask;
5109 tx_chainmask = ahp->ah_txchainmask;
5110
5111 switch (rx_chainmask) {
5112 case 0x5:
5113 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5114 AR_PHY_SWAP_ALT_CHAIN);
5115 case 0x3:
5116 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5117 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5118 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5119 break;
5120 }
5121 case 0x1:
5122 case 0x2:
5123 if (!AR_SREV_9280(ah))
5124 break;
5125 case 0x7:
5126 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5127 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5128 break;
5129 default:
5130 break;
5131 }
5132
5133 REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5134 if (tx_chainmask == 0x5) {
5135 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5136 AR_PHY_SWAP_ALT_CHAIN);
5137 }
5138 if (AR_SREV_9100(ah))
5139 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5140 REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5141}
5142
5143static void ath9k_hw_set_addac(struct ath_hal *ah,
5144 struct ath9k_channel *chan)
5145{
5146 struct modal_eep_header *pModal;
5147 struct ath_hal_5416 *ahp = AH5416(ah);
5148 struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5149 u8 biaslevel;
5150
5151 if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5152 return;
5153
5154 if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5155 return;
5156
5157 pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5158
5159 if (pModal->xpaBiasLvl != 0xff) {
5160 biaslevel = pModal->xpaBiasLvl;
5161 } else {
5162
5163 u16 resetFreqBin, freqBin, freqCount = 0;
5164 struct chan_centers centers;
5165
5166 ath9k_hw_get_channel_centers(ah, chan, &centers);
5167
5168 resetFreqBin =
5169 FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5170 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5171 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5172
5173 freqCount++;
5174
5175 while (freqCount < 3) {
5176 if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5177 break;
5178
5179 freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5180 if (resetFreqBin >= freqBin) {
5181 biaslevel =
5182 (u8) (pModal->
5183 xpaBiasLvlFreq[freqCount]
5184 >> 14);
5185 } else {
5186 break;
5187 }
5188 freqCount++;
5189 }
5190 }
5191
5192 if (IS_CHAN_2GHZ(chan)) {
5193 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5194 (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5195 << 3;
5196 } else {
5197 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5198 (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5199 << 6;
5200 }
5201}
5202
5203static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5204{
5205 if (ah->ah_curchan != NULL)
5206 return clks /
5207 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5208 else
5209 return clks / CLOCK_RATE[WIRELESS_MODE_11b];
5210}
5211
5212static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5213{
5214 struct ath9k_channel *chan = ah->ah_curchan;
5215
5216 if (chan && IS_CHAN_HT40(chan))
5217 return ath9k_hw_mac_usec(ah, clks) / 2;
5218 else
5219 return ath9k_hw_mac_usec(ah, clks);
5220}
5221
5222static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5223{
5224 if (ah->ah_curchan != NULL)
5225 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5226 ah->ah_curchan)];
5227 else
5228 return usecs * CLOCK_RATE[WIRELESS_MODE_11b];
5229}
5230
5231static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5232{
5233 struct ath9k_channel *chan = ah->ah_curchan;
5234
5235 if (chan && IS_CHAN_HT40(chan))
5236 return ath9k_hw_mac_clks(ah, usecs) * 2;
5237 else
5238 return ath9k_hw_mac_clks(ah, usecs);
5239}
5240
5241static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5242{
5243 struct ath_hal_5416 *ahp = AH5416(ah);
5244
5245 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5246 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5247 __func__, us);
5248 ahp->ah_acktimeout = (u32) -1;
5249 return false;
5250 } else {
5251 REG_RMW_FIELD(ah, AR_TIME_OUT,
5252 AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5253 ahp->ah_acktimeout = us;
5254 return true;
5255 }
5256}
5257
5258static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5259{
5260 struct ath_hal_5416 *ahp = AH5416(ah);
5261
5262 if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5263 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5264 __func__, us);
5265 ahp->ah_ctstimeout = (u32) -1;
5266 return false;
5267 } else {
5268 REG_RMW_FIELD(ah, AR_TIME_OUT,
5269 AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5270 ahp->ah_ctstimeout = us;
5271 return true;
5272 }
5273}
5274static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5275 u32 tu)
5276{
5277 struct ath_hal_5416 *ahp = AH5416(ah);
5278
5279 if (tu > 0xFFFF) {
5280 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5281 "%s: bad global tx timeout %u\n", __func__, tu);
5282 ahp->ah_globaltxtimeout = (u32) -1;
5283 return false;
5284 } else {
5285 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5286 ahp->ah_globaltxtimeout = tu;
5287 return true;
5288 }
5289}
5290
5291bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5292{
5293 struct ath_hal_5416 *ahp = AH5416(ah);
5294
5295 if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5296 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5297 __func__, us);
5298 ahp->ah_slottime = (u32) -1;
5299 return false;
5300 } else {
5301 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5302 ahp->ah_slottime = us;
5303 return true;
5304 }
5305}
5306
5307static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5308{
5309 struct ath_hal_5416 *ahp = AH5416(ah);
5310
5311 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5312 __func__, ahp->ah_miscMode);
5313 if (ahp->ah_miscMode != 0)
5314 REG_WRITE(ah, AR_PCU_MISC,
5315 REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5316 if (ahp->ah_slottime != (u32) -1)
5317 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5318 if (ahp->ah_acktimeout != (u32) -1)
5319 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5320 if (ahp->ah_ctstimeout != (u32) -1)
5321 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5322 if (ahp->ah_globaltxtimeout != (u32) -1)
5323 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5324}
5325
5326static inline int
5327ath9k_hw_process_ini(struct ath_hal *ah,
5328 struct ath9k_channel *chan,
5329 enum ath9k_ht_macmode macmode)
5330{
5331 int i, regWrites = 0;
5332 struct ath_hal_5416 *ahp = AH5416(ah);
5333 u32 modesIndex, freqIndex;
5334 int status;
5335
5336 switch (chan->chanmode) {
5337 case CHANNEL_A:
5338 case CHANNEL_A_HT20:
5339 modesIndex = 1;
5340 freqIndex = 1;
5341 break;
5342 case CHANNEL_A_HT40PLUS:
5343 case CHANNEL_A_HT40MINUS:
5344 modesIndex = 2;
5345 freqIndex = 1;
5346 break;
5347 case CHANNEL_G:
5348 case CHANNEL_G_HT20:
5349 case CHANNEL_B:
5350 modesIndex = 4;
5351 freqIndex = 2;
5352 break;
5353 case CHANNEL_G_HT40PLUS:
5354 case CHANNEL_G_HT40MINUS:
5355 modesIndex = 3;
5356 freqIndex = 2;
5357 break;
5358
5359 default:
5360 return -EINVAL;
5361 }
5362
5363 REG_WRITE(ah, AR_PHY(0), 0x00000007);
5364
5365 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5366
5367 ath9k_hw_set_addac(ah, chan);
5368
5369 if (AR_SREV_5416_V22_OR_LATER(ah)) {
5370 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5371 } else {
5372 struct ar5416IniArray temp;
5373 u32 addacSize =
5374 sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5375 ahp->ah_iniAddac.ia_columns;
5376
5377 memcpy(ahp->ah_addac5416_21,
5378 ahp->ah_iniAddac.ia_array, addacSize);
5379
5380 (ahp->ah_addac5416_21)[31 *
5381 ahp->ah_iniAddac.ia_columns + 1] = 0;
5382
5383 temp.ia_array = ahp->ah_addac5416_21;
5384 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5385 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5386 REG_WRITE_ARRAY(&temp, 1, regWrites);
5387 }
5388 REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5389
5390 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5391 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5392 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5393
5394#ifdef CONFIG_SLOW_ANT_DIV
5395 if (ah->ah_devid == AR9280_DEVID_PCI)
5396 val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5397 val);
5398#endif
5399
5400 REG_WRITE(ah, reg, val);
5401
5402 if (reg >= 0x7800 && reg < 0x78a0
5403 && ah->ah_config.ath_hal_analogShiftReg) {
5404 udelay(100);
5405 }
5406
5407 DO_DELAY(regWrites);
5408 }
5409
5410 for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5411 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5412 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5413
5414 REG_WRITE(ah, reg, val);
5415
5416 if (reg >= 0x7800 && reg < 0x78a0
5417 && ah->ah_config.ath_hal_analogShiftReg) {
5418 udelay(100);
5419 }
5420
5421 DO_DELAY(regWrites);
5422 }
5423
5424 ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5425
5426 if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5427 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5428 regWrites);
5429 }
5430
5431 ath9k_hw_override_ini(ah, chan);
5432 ath9k_hw_set_regs(ah, chan, macmode);
5433 ath9k_hw_init_chain_masks(ah);
5434
5435 status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5436 ath9k_regd_get_ctl(ah, chan),
5437 ath9k_regd_get_antenna_allowed(ah,
5438 chan),
5439 chan->maxRegTxPower * 2,
5440 min((u32) MAX_RATE_POWER,
5441 (u32) ah->ah_powerLimit));
5442 if (status != 0) {
5443 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5444 "%s: error init'ing transmit power\n", __func__);
5445 return -EIO;
5446 }
5447
5448 if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5449 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5450 "%s: ar5416SetRfRegs failed\n", __func__);
5451 return -EIO;
5452 }
5453
5454 return 0;
5455}
5456
5457static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5458 struct hal_cal_list *currCal)
5459{
5460 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5461 AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5462 currCal->calData->calCountMax);
5463
5464 switch (currCal->calData->calType) {
5465 case IQ_MISMATCH_CAL:
5466 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5467 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5468 "%s: starting IQ Mismatch Calibration\n",
5469 __func__);
5470 break;
5471 case ADC_GAIN_CAL:
5472 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5473 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5474 "%s: starting ADC Gain Calibration\n", __func__);
5475 break;
5476 case ADC_DC_CAL:
5477 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5478 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5479 "%s: starting ADC DC Calibration\n", __func__);
5480 break;
5481 case ADC_DC_INIT_CAL:
5482 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5483 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5484 "%s: starting Init ADC DC Calibration\n",
5485 __func__);
5486 break;
5487 }
5488
5489 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5490 AR_PHY_TIMING_CTRL4_DO_CAL);
5491}
5492
5493static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5494 struct hal_cal_list *currCal)
5495{
5496 struct ath_hal_5416 *ahp = AH5416(ah);
5497 int i;
5498
5499 ath9k_hw_setup_calibration(ah, currCal);
5500
5501 currCal->calState = CAL_RUNNING;
5502
5503 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5504 ahp->ah_Meas0.sign[i] = 0;
5505 ahp->ah_Meas1.sign[i] = 0;
5506 ahp->ah_Meas2.sign[i] = 0;
5507 ahp->ah_Meas3.sign[i] = 0;
5508 }
5509
5510 ahp->ah_CalSamples = 0;
5511}
5512
5513static inline void
5514ath9k_hw_per_calibration(struct ath_hal *ah,
5515 struct ath9k_channel *ichan,
5516 u8 rxchainmask,
5517 struct hal_cal_list *currCal,
5518 bool *isCalDone)
5519{
5520 struct ath_hal_5416 *ahp = AH5416(ah);
5521
5522 *isCalDone = false;
5523
5524 if (currCal->calState == CAL_RUNNING) {
5525 if (!(REG_READ(ah,
5526 AR_PHY_TIMING_CTRL4(0)) &
5527 AR_PHY_TIMING_CTRL4_DO_CAL)) {
5528
5529 currCal->calData->calCollect(ah);
5530
5531 ahp->ah_CalSamples++;
5532
5533 if (ahp->ah_CalSamples >=
5534 currCal->calData->calNumSamples) {
5535 int i, numChains = 0;
5536 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5537 if (rxchainmask & (1 << i))
5538 numChains++;
5539 }
5540
5541 currCal->calData->calPostProc(ah,
5542 numChains);
5543
5544 ichan->CalValid |=
5545 currCal->calData->calType;
5546 currCal->calState = CAL_DONE;
5547 *isCalDone = true;
5548 } else {
5549 ath9k_hw_setup_calibration(ah, currCal);
5550 }
5551 }
5552 } else if (!(ichan->CalValid & currCal->calData->calType)) {
5553 ath9k_hw_reset_calibration(ah, currCal);
5554 }
5555}
5556
5557static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5558 int init_cal_count)
5559{
5560 struct ath_hal_5416 *ahp = AH5416(ah);
5561 struct ath9k_channel ichan;
5562 bool isCalDone;
5563 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5564 const struct hal_percal_data *calData = currCal->calData;
5565 int i;
5566
5567 if (currCal == NULL)
5568 return false;
5569
5570 ichan.CalValid = 0;
5571
5572 for (i = 0; i < init_cal_count; i++) {
5573 ath9k_hw_reset_calibration(ah, currCal);
5574
5575 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5576 AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5577 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5578 "%s: Cal %d failed to complete in 100ms.\n",
5579 __func__, calData->calType);
5580
5581 ahp->ah_cal_list = ahp->ah_cal_list_last =
5582 ahp->ah_cal_list_curr = NULL;
5583 return false;
5584 }
5585
5586 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5587 currCal, &isCalDone);
5588 if (!isCalDone) {
5589 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5590 "%s: Not able to run Init Cal %d.\n",
5591 __func__, calData->calType);
5592 }
5593 if (currCal->calNext) {
5594 currCal = currCal->calNext;
5595 calData = currCal->calData;
5596 }
5597 }
5598
5599 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5600 return true;
5601}
5602
5603static inline bool
5604ath9k_hw_channel_change(struct ath_hal *ah,
5605 struct ath9k_channel *chan,
5606 enum ath9k_ht_macmode macmode)
5607{
5608 u32 synthDelay, qnum;
5609 struct ath_hal_5416 *ahp = AH5416(ah);
5610
5611 for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5612 if (ath9k_hw_numtxpending(ah, qnum)) {
5613 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5614 "%s: Transmit frames pending on queue %d\n",
5615 __func__, qnum);
5616 return false;
5617 }
5618 }
5619
5620 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5621 if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5622 AR_PHY_RFBUS_GRANT_EN)) {
5623 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5624 "%s: Could not kill baseband RX\n", __func__);
5625 return false;
5626 }
5627
5628 ath9k_hw_set_regs(ah, chan, macmode);
5629
5630 if (AR_SREV_9280_10_OR_LATER(ah)) {
5631 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5632 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5633 "%s: failed to set channel\n", __func__);
5634 return false;
5635 }
5636 } else {
5637 if (!(ath9k_hw_set_channel(ah, chan))) {
5638 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5639 "%s: failed to set channel\n", __func__);
5640 return false;
5641 }
5642 }
5643
5644 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5645 ath9k_regd_get_ctl(ah, chan),
5646 ath9k_regd_get_antenna_allowed(ah, chan),
5647 chan->maxRegTxPower * 2,
5648 min((u32) MAX_RATE_POWER,
5649 (u32) ah->ah_powerLimit)) != 0) {
5650 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5651 "%s: error init'ing transmit power\n", __func__);
5652 return false;
5653 }
5654
5655 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5656 if (IS_CHAN_CCK(chan))
5657 synthDelay = (4 * synthDelay) / 22;
5658 else
5659 synthDelay /= 10;
5660
5661 udelay(synthDelay + BASE_ACTIVATE_DELAY);
5662
5663 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5664
5665 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5666 ath9k_hw_set_delta_slope(ah, chan);
5667
5668 if (AR_SREV_9280_10_OR_LATER(ah))
5669 ath9k_hw_9280_spur_mitigate(ah, chan);
5670 else
5671 ath9k_hw_spur_mitigate(ah, chan);
5672
5673 if (!chan->oneTimeCalsDone)
5674 chan->oneTimeCalsDone = true;
5675
5676 return true;
5677}
5678
5679static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5680 struct ath9k_channel *chan)
5681{
5682 struct ath_hal_5416 *ahp = AH5416(ah);
5683
5684 if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5685 return false;
5686
5687 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5688 return false;
5689
5690 ahp->ah_chipFullSleep = false;
5691
5692 ath9k_hw_init_pll(ah, chan);
5693
5694 ath9k_hw_set_rfmode(ah, chan);
5695
5696 return true;
5697}
5698
5699static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5700{
5701 u32 regval;
5702
5703 regval = REG_READ(ah, AR_AHB_MODE);
5704 REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5705
5706 regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5707 REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5708
5709 REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5710
5711 regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5712 REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5713
5714 REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5715
5716 if (AR_SREV_9285(ah)) {
5717 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5718 AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5719 } else {
5720 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5721 AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5722 }
5723}
5724
5725bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5726{
5727 REG_WRITE(ah, AR_CR, AR_CR_RXD);
5728 if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5729 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5730 "%s: dma failed to stop in 10ms\n"
5731 "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5732 __func__,
5733 REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5734 return false;
5735 } else {
5736 return true;
5737 }
5738}
5739
5740void ath9k_hw_startpcureceive(struct ath_hal *ah)
5741{
5742 REG_CLR_BIT(ah, AR_DIAG_SW,
5743 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5744
5745 ath9k_enable_mib_counters(ah);
5746
5747 ath9k_ani_reset(ah);
5748}
5749
5750void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5751{
5752 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5753
5754 ath9k_hw_disable_mib_counters(ah);
5755}
5756
5757static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5758 struct ath9k_channel *chan,
5759 enum hal_cal_types calType)
5760{
5761 struct ath_hal_5416 *ahp = AH5416(ah);
5762 bool retval = false;
5763
5764 switch (calType & ahp->ah_suppCals) {
5765 case IQ_MISMATCH_CAL:
5766 if (!IS_CHAN_B(chan))
5767 retval = true;
5768 break;
5769 case ADC_GAIN_CAL:
5770 case ADC_DC_CAL:
5771 if (!IS_CHAN_B(chan)
5772 && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5773 retval = true;
5774 break;
5775 }
5776
5777 return retval;
5778}
5779
5780static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5781 struct ath9k_channel *chan)
5782{
5783 struct ath_hal_5416 *ahp = AH5416(ah);
5784 struct ath9k_channel *ichan =
5785 ath9k_regd_check_channel(ah, chan);
5786
5787 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5788 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5789 AR_PHY_AGC_CONTROL_CAL);
5790
5791 if (!ath9k_hw_wait
5792 (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5793 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5794 "%s: offset calibration failed to complete in 1ms; "
5795 "noisy environment?\n", __func__);
5796 return false;
5797 }
5798
5799 REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5800 REG_READ(ah, AR_PHY_AGC_CONTROL) |
5801 AR_PHY_AGC_CONTROL_NF);
5802
5803 ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5804 NULL;
5805
5806 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5807 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5808 INIT_CAL(&ahp->ah_adcGainCalData);
5809 INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5810 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5811 "%s: enabling ADC Gain Calibration.\n",
5812 __func__);
5813 }
5814 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5815 INIT_CAL(&ahp->ah_adcDcCalData);
5816 INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5817 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5818 "%s: enabling ADC DC Calibration.\n",
5819 __func__);
5820 }
5821 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5822 INIT_CAL(&ahp->ah_iqCalData);
5823 INSERT_CAL(ahp, &ahp->ah_iqCalData);
5824 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5825 "%s: enabling IQ Calibration.\n",
5826 __func__);
5827 }
5828
5829 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5830
5831 if (ahp->ah_cal_list_curr)
5832 ath9k_hw_reset_calibration(ah,
5833 ahp->ah_cal_list_curr);
5834 }
5835
5836 ichan->CalValid = 0;
5837
5838 return true;
5839}
5840
5841
5842bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5843 struct ath9k_channel *chan,
5844 enum ath9k_ht_macmode macmode,
5845 u8 txchainmask, u8 rxchainmask,
5846 enum ath9k_ht_extprotspacing extprotspacing,
5847 bool bChannelChange,
5848 int *status)
5849{
5850#define FAIL(_code) do { ecode = _code; goto bad; } while (0)
5851 u32 saveLedState;
5852 struct ath_hal_5416 *ahp = AH5416(ah);
5853 struct ath9k_channel *curchan = ah->ah_curchan;
5854 u32 saveDefAntenna;
5855 u32 macStaId1;
5856 int ecode;
5857 int i, rx_chainmask;
5858
5859 ahp->ah_extprotspacing = extprotspacing;
5860 ahp->ah_txchainmask = txchainmask;
5861 ahp->ah_rxchainmask = rxchainmask;
5862
5863 if (AR_SREV_9280(ah)) {
5864 ahp->ah_txchainmask &= 0x3;
5865 ahp->ah_rxchainmask &= 0x3;
5866 }
5867
5868 if (ath9k_hw_check_chan(ah, chan) == NULL) {
5869 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5870 "%s: invalid channel %u/0x%x; no mapping\n",
5871 __func__, chan->channel, chan->channelFlags);
5872 FAIL(-EINVAL);
5873 }
5874
5875 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5876 return false;
5877
5878 if (curchan)
5879 ath9k_hw_getnf(ah, curchan);
5880
5881 if (bChannelChange &&
5882 (ahp->ah_chipFullSleep != true) &&
5883 (ah->ah_curchan != NULL) &&
5884 (chan->channel != ah->ah_curchan->channel) &&
5885 ((chan->channelFlags & CHANNEL_ALL) ==
5886 (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5887 (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5888 !IS_CHAN_A_5MHZ_SPACED(ah->
5889 ah_curchan)))) {
5890
5891 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5892 ath9k_hw_loadnf(ah, ah->ah_curchan);
5893 ath9k_hw_start_nfcal(ah);
5894 return true;
5895 }
5896 }
5897
5898 saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5899 if (saveDefAntenna == 0)
5900 saveDefAntenna = 1;
5901
5902 macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5903
5904 saveLedState = REG_READ(ah, AR_CFG_LED) &
5905 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5906 AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5907
5908 ath9k_hw_mark_phy_inactive(ah);
5909
5910 if (!ath9k_hw_chip_reset(ah, chan)) {
5911 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5912 __func__);
5913 FAIL(-EIO);
5914 }
5915
5916 if (AR_SREV_9280(ah)) {
5917 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5918 AR_GPIO_JTAG_DISABLE);
5919
5920 if (ah->ah_caps.halWirelessModes & ATH9K_MODE_SEL_11A) {
5921 if (IS_CHAN_5GHZ(chan))
5922 ath9k_hw_set_gpio(ah, 9, 0);
5923 else
5924 ath9k_hw_set_gpio(ah, 9, 1);
5925 }
5926 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5927 }
5928
5929 ecode = ath9k_hw_process_ini(ah, chan, macmode);
5930 if (ecode != 0)
5931 goto bad;
5932
5933 if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5934 ath9k_hw_set_delta_slope(ah, chan);
5935
5936 if (AR_SREV_9280_10_OR_LATER(ah))
5937 ath9k_hw_9280_spur_mitigate(ah, chan);
5938 else
5939 ath9k_hw_spur_mitigate(ah, chan);
5940
5941 if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5942 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5943 "%s: error setting board options\n", __func__);
5944 FAIL(-EIO);
5945 }
5946
5947 ath9k_hw_decrease_chain_power(ah, chan);
5948
5949 REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5950 REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5951 | macStaId1
5952 | AR_STA_ID1_RTS_USE_DEF
5953 | (ah->ah_config.
5954 ath_hal_6mb_ack ? AR_STA_ID1_ACKCTS_6MB : 0)
5955 | ahp->ah_staId1Defaults);
5956 ath9k_hw_set_operating_mode(ah, opmode);
5957
5958 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5959 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5960
5961 REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5962
5963 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5964 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5965 ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5966
5967 REG_WRITE(ah, AR_ISR, ~0);
5968
5969 REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5970
5971 if (AR_SREV_9280_10_OR_LATER(ah)) {
5972 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5973 FAIL(-EIO);
5974 } else {
5975 if (!(ath9k_hw_set_channel(ah, chan)))
5976 FAIL(-EIO);
5977 }
5978
5979 for (i = 0; i < AR_NUM_DCU; i++)
5980 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
5981
5982 ahp->ah_intrTxqs = 0;
5983 for (i = 0; i < ah->ah_caps.halTotalQueues; i++)
5984 ath9k_hw_resettxqueue(ah, i);
5985
5986 ath9k_hw_init_interrupt_masks(ah, opmode);
5987 ath9k_hw_init_qos(ah);
5988
5989 ath9k_hw_init_user_settings(ah);
5990
5991 ah->ah_opmode = opmode;
5992
5993 REG_WRITE(ah, AR_STA_ID1,
5994 REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
5995
5996 ath9k_hw_set_dma(ah);
5997
5998 REG_WRITE(ah, AR_OBS, 8);
5999
6000 if (ahp->ah_intrMitigation) {
6001
6002 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6003 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6004 }
6005
6006 ath9k_hw_init_bb(ah, chan);
6007
6008 if (!ath9k_hw_init_cal(ah, chan))
6009 FAIL(-ENODEV);
6010
6011 rx_chainmask = ahp->ah_rxchainmask;
6012 if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6013 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6014 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6015 }
6016
6017 REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6018
6019 if (AR_SREV_9100(ah)) {
6020 u32 mask;
6021 mask = REG_READ(ah, AR_CFG);
6022 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6023 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6024 "%s CFG Byte Swap Set 0x%x\n", __func__,
6025 mask);
6026 } else {
6027 mask =
6028 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6029 REG_WRITE(ah, AR_CFG, mask);
6030 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6031 "%s Setting CFG 0x%x\n", __func__,
6032 REG_READ(ah, AR_CFG));
6033 }
6034 } else {
6035#ifdef __BIG_ENDIAN
6036 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6037#endif
6038 }
6039
6040 return true;
6041bad:
6042 if (status)
6043 *status = ecode;
6044 return false;
6045#undef FAIL
6046}
6047
6048bool ath9k_hw_phy_disable(struct ath_hal *ah)
6049{
6050 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6051}
6052
6053bool ath9k_hw_disable(struct ath_hal *ah)
6054{
6055 if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6056 return false;
6057
6058 return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6059}
6060
6061bool
6062ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6063 u8 rxchainmask, bool longcal,
6064 bool *isCalDone)
6065{
6066 struct ath_hal_5416 *ahp = AH5416(ah);
6067 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6068 struct ath9k_channel *ichan =
6069 ath9k_regd_check_channel(ah, chan);
6070
6071 *isCalDone = true;
6072
6073 if (ichan == NULL) {
6074 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6075 "%s: invalid channel %u/0x%x; no mapping\n",
6076 __func__, chan->channel, chan->channelFlags);
6077 return false;
6078 }
6079
6080 if (currCal &&
6081 (currCal->calState == CAL_RUNNING ||
6082 currCal->calState == CAL_WAITING)) {
6083 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6084 isCalDone);
6085 if (*isCalDone) {
6086 ahp->ah_cal_list_curr = currCal = currCal->calNext;
6087
6088 if (currCal->calState == CAL_WAITING) {
6089 *isCalDone = false;
6090 ath9k_hw_reset_calibration(ah, currCal);
6091 }
6092 }
6093 }
6094
6095 if (longcal) {
6096 ath9k_hw_getnf(ah, ichan);
6097 ath9k_hw_loadnf(ah, ah->ah_curchan);
6098 ath9k_hw_start_nfcal(ah);
6099
6100 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6101
6102 chan->channelFlags |= CHANNEL_CW_INT;
6103 ichan->channelFlags &= ~CHANNEL_CW_INT;
6104 }
6105 }
6106
6107 return true;
6108}
6109
6110static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6111{
6112 struct ath_hal_5416 *ahp = AH5416(ah);
6113 int i;
6114
6115 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6116 ahp->ah_totalPowerMeasI[i] +=
6117 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6118 ahp->ah_totalPowerMeasQ[i] +=
6119 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6120 ahp->ah_totalIqCorrMeas[i] +=
6121 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6122 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6123 "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6124 ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6125 ahp->ah_totalPowerMeasQ[i],
6126 ahp->ah_totalIqCorrMeas[i]);
6127 }
6128}
6129
6130static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6131{
6132 struct ath_hal_5416 *ahp = AH5416(ah);
6133 int i;
6134
6135 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6136 ahp->ah_totalAdcIOddPhase[i] +=
6137 REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6138 ahp->ah_totalAdcIEvenPhase[i] +=
6139 REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6140 ahp->ah_totalAdcQOddPhase[i] +=
6141 REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6142 ahp->ah_totalAdcQEvenPhase[i] +=
6143 REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6144
6145 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6146 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6147 "oddq=0x%08x; evenq=0x%08x;\n",
6148 ahp->ah_CalSamples, i,
6149 ahp->ah_totalAdcIOddPhase[i],
6150 ahp->ah_totalAdcIEvenPhase[i],
6151 ahp->ah_totalAdcQOddPhase[i],
6152 ahp->ah_totalAdcQEvenPhase[i]);
6153 }
6154}
6155
6156static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6157{
6158 struct ath_hal_5416 *ahp = AH5416(ah);
6159 int i;
6160
6161 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6162 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6163 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6164 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6165 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6166 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6167 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6168 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6169 (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6170
6171 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6172 "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6173 "oddq=0x%08x; evenq=0x%08x;\n",
6174 ahp->ah_CalSamples, i,
6175 ahp->ah_totalAdcDcOffsetIOddPhase[i],
6176 ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6177 ahp->ah_totalAdcDcOffsetQOddPhase[i],
6178 ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6179 }
6180}
6181
6182static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6183{
6184 struct ath_hal_5416 *ahp = AH5416(ah);
6185 u32 powerMeasQ, powerMeasI, iqCorrMeas;
6186 u32 qCoffDenom, iCoffDenom;
6187 int32_t qCoff, iCoff;
6188 int iqCorrNeg, i;
6189
6190 for (i = 0; i < numChains; i++) {
6191 powerMeasI = ahp->ah_totalPowerMeasI[i];
6192 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6193 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6194
6195 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6196 "Starting IQ Cal and Correction for Chain %d\n",
6197 i);
6198
6199 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6200 "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6201 i, ahp->ah_totalIqCorrMeas[i]);
6202
6203 iqCorrNeg = 0;
6204
6205
6206 if (iqCorrMeas > 0x80000000) {
6207 iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6208 iqCorrNeg = 1;
6209 }
6210
6211 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6212 "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6213 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6214 "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6215 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6216 iqCorrNeg);
6217
6218 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6219 qCoffDenom = powerMeasQ / 64;
6220
6221 if (powerMeasQ != 0) {
6222
6223 iCoff = iqCorrMeas / iCoffDenom;
6224 qCoff = powerMeasI / qCoffDenom - 64;
6225 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6226 "Chn %d iCoff = 0x%08x\n", i, iCoff);
6227 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6228 "Chn %d qCoff = 0x%08x\n", i, qCoff);
6229
6230
6231 iCoff = iCoff & 0x3f;
6232 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6233 "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6234 if (iqCorrNeg == 0x0)
6235 iCoff = 0x40 - iCoff;
6236
6237 if (qCoff > 15)
6238 qCoff = 15;
6239 else if (qCoff <= -16)
6240 qCoff = 16;
6241
6242 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6243 "Chn %d : iCoff = 0x%x qCoff = 0x%x\n",
6244 i, iCoff, qCoff);
6245
6246 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6247 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6248 iCoff);
6249 REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6250 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6251 qCoff);
6252 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6253 "IQ Cal and Correction done for Chain %d\n",
6254 i);
6255 }
6256 }
6257
6258 REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6259 AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6260}
6261
6262static void
6263ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6264{
6265 struct ath_hal_5416 *ahp = AH5416(ah);
6266 u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6267 qEvenMeasOffset;
6268 u32 qGainMismatch, iGainMismatch, val, i;
6269
6270 for (i = 0; i < numChains; i++) {
6271 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6272 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6273 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6274 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6275
6276 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6277 "Starting ADC Gain Cal for Chain %d\n", i);
6278
6279 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6280 "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6281 iOddMeasOffset);
6282 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6283 "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6284 iEvenMeasOffset);
6285 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6286 "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6287 qOddMeasOffset);
6288 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6289 "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6290 qEvenMeasOffset);
6291
6292 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6293 iGainMismatch =
6294 ((iEvenMeasOffset * 32) /
6295 iOddMeasOffset) & 0x3f;
6296 qGainMismatch =
6297 ((qOddMeasOffset * 32) /
6298 qEvenMeasOffset) & 0x3f;
6299
6300 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6301 "Chn %d gain_mismatch_i = 0x%08x\n", i,
6302 iGainMismatch);
6303 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6304 "Chn %d gain_mismatch_q = 0x%08x\n", i,
6305 qGainMismatch);
6306
6307 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6308 val &= 0xfffff000;
6309 val |= (qGainMismatch) | (iGainMismatch << 6);
6310 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6311
6312 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6313 "ADC Gain Cal done for Chain %d\n", i);
6314 }
6315 }
6316
6317 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6318 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6319 AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6320}
6321
6322static void
6323ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6324{
6325 struct ath_hal_5416 *ahp = AH5416(ah);
6326 u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6327 int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6328 const struct hal_percal_data *calData =
6329 ahp->ah_cal_list_curr->calData;
6330 u32 numSamples =
6331 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6332
6333 for (i = 0; i < numChains; i++) {
6334 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6335 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6336 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6337 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6338
6339 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6340 "Starting ADC DC Offset Cal for Chain %d\n", i);
6341
6342 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6343 "Chn %d pwr_meas_odd_i = %d\n", i,
6344 iOddMeasOffset);
6345 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6346 "Chn %d pwr_meas_even_i = %d\n", i,
6347 iEvenMeasOffset);
6348 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6349 "Chn %d pwr_meas_odd_q = %d\n", i,
6350 qOddMeasOffset);
6351 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6352 "Chn %d pwr_meas_even_q = %d\n", i,
6353 qEvenMeasOffset);
6354
6355 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6356 numSamples) & 0x1ff;
6357 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6358 numSamples) & 0x1ff;
6359
6360 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6361 "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6362 iDcMismatch);
6363 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6364 "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6365 qDcMismatch);
6366
6367 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6368 val &= 0xc0000fff;
6369 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6370 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6371
6372 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6373 "ADC DC Offset Cal done for Chain %d\n", i);
6374 }
6375
6376 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6377 REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6378 AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6379}
6380
6381bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6382{
6383 struct ath_hal_5416 *ahp = AH5416(ah);
6384 struct ath9k_channel *chan = ah->ah_curchan;
6385
6386 ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6387
6388 if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6389 ath9k_regd_get_ctl(ah, chan),
6390 ath9k_regd_get_antenna_allowed(ah,
6391 chan),
6392 chan->maxRegTxPower * 2,
6393 min((u32) MAX_RATE_POWER,
6394 (u32) ah->ah_powerLimit)) != 0)
6395 return false;
6396
6397 return true;
6398}
6399
6400void
6401ath9k_hw_get_channel_centers(struct ath_hal *ah,
6402 struct ath9k_channel *chan,
6403 struct chan_centers *centers)
6404{
6405 int8_t extoff;
6406 struct ath_hal_5416 *ahp = AH5416(ah);
6407
6408 if (!IS_CHAN_HT40(chan)) {
6409 centers->ctl_center = centers->ext_center =
6410 centers->synth_center = chan->channel;
6411 return;
6412 }
6413
6414 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6415 (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6416 centers->synth_center =
6417 chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6418 extoff = 1;
6419 } else {
6420 centers->synth_center =
6421 chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6422 extoff = -1;
6423 }
6424
6425 centers->ctl_center = centers->synth_center - (extoff *
6426 HT40_CHANNEL_CENTER_SHIFT);
6427 centers->ext_center = centers->synth_center + (extoff *
6428 ((ahp->
6429 ah_extprotspacing
6430 ==
6431 ATH9K_HT_EXTPROTSPACING_20)
6432 ?
6433 HT40_CHANNEL_CENTER_SHIFT
6434 : 15));
6435
6436}
6437
6438void
6439ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6440 bool *isCalDone)
6441{
6442 struct ath_hal_5416 *ahp = AH5416(ah);
6443 struct ath9k_channel *ichan =
6444 ath9k_regd_check_channel(ah, chan);
6445 struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6446
6447 *isCalDone = true;
6448
6449 if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6450 return;
6451
6452 if (currCal == NULL)
6453 return;
6454
6455 if (ichan == NULL) {
6456 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6457 "%s: invalid channel %u/0x%x; no mapping\n",
6458 __func__, chan->channel, chan->channelFlags);
6459 return;
6460 }
6461
6462
6463 if (currCal->calState != CAL_DONE) {
6464 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6465 "%s: Calibration state incorrect, %d\n",
6466 __func__, currCal->calState);
6467 return;
6468 }
6469
6470
6471 if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6472 return;
6473
6474 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6475 "%s: Resetting Cal %d state for channel %u/0x%x\n",
6476 __func__, currCal->calData->calType, chan->channel,
6477 chan->channelFlags);
6478
6479 ichan->CalValid &= ~currCal->calData->calType;
6480 currCal->calState = CAL_WAITING;
6481
6482 *isCalDone = false;
6483}
6484
6485void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6486{
6487 struct ath_hal_5416 *ahp = AH5416(ah);
6488
6489 memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6490}
6491
6492bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6493{
6494 struct ath_hal_5416 *ahp = AH5416(ah);
6495
6496 memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6497 return true;
6498}
6499
6500void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6501{
6502 struct ath_hal_5416 *ahp = AH5416(ah);
6503
6504 memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6505}
6506
6507bool
6508ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6509{
6510 struct ath_hal_5416 *ahp = AH5416(ah);
6511
6512 memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6513
6514 REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6515 REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6516
6517 return true;
6518}
6519
6520#ifdef CONFIG_ATH9K_RFKILL
6521static void ath9k_enable_rfkill(struct ath_hal *ah)
6522{
6523 struct ath_hal_5416 *ahp = AH5416(ah);
6524
6525 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6526 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6527
6528 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6529 AR_GPIO_INPUT_MUX2_RFSILENT);
6530
6531 ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6532 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6533
6534 if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6535
6536 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6537 !ahp->ah_gpioBit);
6538 } else {
6539 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6540 ahp->ah_gpioBit);
6541 }
6542}
6543#endif
6544
6545void
6546ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6547 u16 assocId)
6548{
6549 struct ath_hal_5416 *ahp = AH5416(ah);
6550
6551 memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6552 ahp->ah_assocId = assocId;
6553
6554 REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6555 REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6556 ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6557}
6558
6559u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6560{
6561 u64 tsf;
6562
6563 tsf = REG_READ(ah, AR_TSF_U32);
6564 tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6565 return tsf;
6566}
6567
6568void ath9k_hw_reset_tsf(struct ath_hal *ah)
6569{
6570 int count;
6571
6572 count = 0;
6573 while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6574 count++;
6575 if (count > 10) {
6576 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6577 "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6578 __func__);
6579 break;
6580 }
6581 udelay(10);
6582 }
6583 REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6584}
6585
6586u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6587{
6588 return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6589}
6590
6591void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6592{
6593 REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6594}
6595
6596bool
6597ath9k_hw_setantennaswitch(struct ath_hal *ah,
6598 enum ath9k_ant_setting settings,
6599 struct ath9k_channel *chan,
6600 u8 *tx_chainmask,
6601 u8 *rx_chainmask,
6602 u8 *antenna_cfgd)
6603{
6604 struct ath_hal_5416 *ahp = AH5416(ah);
6605 static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6606
6607 if (AR_SREV_9280(ah)) {
6608 if (!tx_chainmask_cfg) {
6609
6610 tx_chainmask_cfg = *tx_chainmask;
6611 rx_chainmask_cfg = *rx_chainmask;
6612 }
6613
6614 switch (settings) {
6615 case ATH9K_ANT_FIXED_A:
6616 *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6617 *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6618 *antenna_cfgd = true;
6619 break;
6620 case ATH9K_ANT_FIXED_B:
6621 if (ah->ah_caps.halTxChainMask >
6622 ATH9K_ANTENNA1_CHAINMASK) {
6623 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6624 }
6625 *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6626 *antenna_cfgd = true;
6627 break;
6628 case ATH9K_ANT_VARIABLE:
6629 *tx_chainmask = tx_chainmask_cfg;
6630 *rx_chainmask = rx_chainmask_cfg;
6631 *antenna_cfgd = true;
6632 break;
6633 default:
6634 break;
6635 }
6636 } else {
6637 ahp->ah_diversityControl = settings;
6638 }
6639
6640 return true;
6641}
6642
6643void ath9k_hw_setopmode(struct ath_hal *ah)
6644{
6645 ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6646}
6647
6648bool
6649ath9k_hw_getcapability(struct ath_hal *ah, enum hal_capability_type type,
6650 u32 capability, u32 *result)
6651{
6652 struct ath_hal_5416 *ahp = AH5416(ah);
6653 const struct hal_capabilities *pCap = &ah->ah_caps;
6654
6655 switch (type) {
6656 case HAL_CAP_CIPHER:
6657 switch (capability) {
6658 case ATH9K_CIPHER_AES_CCM:
6659 case ATH9K_CIPHER_AES_OCB:
6660 case ATH9K_CIPHER_TKIP:
6661 case ATH9K_CIPHER_WEP:
6662 case ATH9K_CIPHER_MIC:
6663 case ATH9K_CIPHER_CLR:
6664 return true;
6665 default:
6666 return false;
6667 }
6668 case HAL_CAP_TKIP_MIC:
6669 switch (capability) {
6670 case 0:
6671 return true;
6672 case 1:
6673 return (ahp->ah_staId1Defaults &
6674 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6675 false;
6676 }
6677 case HAL_CAP_TKIP_SPLIT:
6678 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6679 false : true;
6680 case HAL_CAP_WME_TKIPMIC:
6681 return 0;
6682 case HAL_CAP_PHYCOUNTERS:
6683 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6684 case HAL_CAP_DIVERSITY:
6685 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6686 AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6687 true : false;
6688 case HAL_CAP_PHYDIAG:
6689 return true;
6690 case HAL_CAP_MCAST_KEYSRCH:
6691 switch (capability) {
6692 case 0:
6693 return true;
6694 case 1:
6695 if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6696 return false;
6697 } else {
6698 return (ahp->ah_staId1Defaults &
6699 AR_STA_ID1_MCAST_KSRCH) ? true :
6700 false;
6701 }
6702 }
6703 return false;
6704 case HAL_CAP_TSF_ADJUST:
6705 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6706 true : false;
6707 case HAL_CAP_RFSILENT:
6708 if (capability == 3)
6709 return false;
6710 case HAL_CAP_ANT_CFG_2GHZ:
6711 *result = pCap->halNumAntCfg2GHz;
6712 return true;
6713 case HAL_CAP_ANT_CFG_5GHZ:
6714 *result = pCap->halNumAntCfg5GHz;
6715 return true;
6716 case HAL_CAP_TXPOW:
6717 switch (capability) {
6718 case 0:
6719 return 0;
6720 case 1:
6721 *result = ah->ah_powerLimit;
6722 return 0;
6723 case 2:
6724 *result = ah->ah_maxPowerLevel;
6725 return 0;
6726 case 3:
6727 *result = ah->ah_tpScale;
6728 return 0;
6729 }
6730 return false;
6731 default:
6732 return false;
6733 }
6734}
6735
6736int
6737ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6738{
6739 struct ath_hal_5416 *ahp = AH5416(ah);
6740 struct ath9k_channel *chan = ah->ah_curchan;
6741 const struct hal_capabilities *pCap = &ah->ah_caps;
6742 u16 ant_config;
6743 u32 halNumAntConfig;
6744
6745 halNumAntConfig =
6746 IS_CHAN_2GHZ(chan) ? pCap->halNumAntCfg2GHz : pCap->
6747 halNumAntCfg5GHz;
6748
6749 if (cfg < halNumAntConfig) {
6750 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6751 cfg, &ant_config)) {
6752 REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6753 return 0;
6754 }
6755 }
6756
6757 return -EINVAL;
6758}
6759
6760bool ath9k_hw_intrpend(struct ath_hal *ah)
6761{
6762 u32 host_isr;
6763
6764 if (AR_SREV_9100(ah))
6765 return true;
6766
6767 host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6768 if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6769 return true;
6770
6771 host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6772 if ((host_isr & AR_INTR_SYNC_DEFAULT)
6773 && (host_isr != AR_INTR_SPURIOUS))
6774 return true;
6775
6776 return false;
6777}
6778
6779bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6780{
6781 u32 isr = 0;
6782 u32 mask2 = 0;
6783 struct hal_capabilities *pCap = &ah->ah_caps;
6784 u32 sync_cause = 0;
6785 bool fatal_int = false;
6786
6787 if (!AR_SREV_9100(ah)) {
6788 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6789 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6790 == AR_RTC_STATUS_ON) {
6791 isr = REG_READ(ah, AR_ISR);
6792 }
6793 }
6794
6795 sync_cause =
6796 REG_READ(ah,
6797 AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6798
6799 *masked = 0;
6800
6801 if (!isr && !sync_cause)
6802 return false;
6803 } else {
6804 *masked = 0;
6805 isr = REG_READ(ah, AR_ISR);
6806 }
6807
6808 if (isr) {
6809 struct ath_hal_5416 *ahp = AH5416(ah);
6810
6811 if (isr & AR_ISR_BCNMISC) {
6812 u32 isr2;
6813 isr2 = REG_READ(ah, AR_ISR_S2);
6814 if (isr2 & AR_ISR_S2_TIM)
6815 mask2 |= ATH9K_INT_TIM;
6816 if (isr2 & AR_ISR_S2_DTIM)
6817 mask2 |= ATH9K_INT_DTIM;
6818 if (isr2 & AR_ISR_S2_DTIMSYNC)
6819 mask2 |= ATH9K_INT_DTIMSYNC;
6820 if (isr2 & (AR_ISR_S2_CABEND))
6821 mask2 |= ATH9K_INT_CABEND;
6822 if (isr2 & AR_ISR_S2_GTT)
6823 mask2 |= ATH9K_INT_GTT;
6824 if (isr2 & AR_ISR_S2_CST)
6825 mask2 |= ATH9K_INT_CST;
6826 }
6827
6828 isr = REG_READ(ah, AR_ISR_RAC);
6829 if (isr == 0xffffffff) {
6830 *masked = 0;
6831 return false;
6832 }
6833
6834 *masked = isr & ATH9K_INT_COMMON;
6835
6836 if (ahp->ah_intrMitigation) {
6837
6838 if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6839 *masked |= ATH9K_INT_RX;
6840 }
6841
6842 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6843 *masked |= ATH9K_INT_RX;
6844 if (isr &
6845 (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6846 AR_ISR_TXEOL)) {
6847 u32 s0_s, s1_s;
6848
6849 *masked |= ATH9K_INT_TX;
6850
6851 s0_s = REG_READ(ah, AR_ISR_S0_S);
6852 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6853 ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6854
6855 s1_s = REG_READ(ah, AR_ISR_S1_S);
6856 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6857 ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6858 }
6859
6860 if (isr & AR_ISR_RXORN) {
6861 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6862 "%s: receive FIFO overrun interrupt\n",
6863 __func__);
6864 }
6865
6866 if (!AR_SREV_9100(ah)) {
6867 if (!pCap->halAutoSleepSupport) {
6868 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6869 if (isr5 & AR_ISR_S5_TIM_TIMER)
6870 *masked |= ATH9K_INT_TIM_TIMER;
6871 }
6872 }
6873
6874 *masked |= mask2;
6875 }
6876 if (AR_SREV_9100(ah))
6877 return true;
6878 if (sync_cause) {
6879 fatal_int =
6880 (sync_cause &
6881 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6882 ? true : false;
6883
6884 if (fatal_int) {
6885 if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6886 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6887 "%s: received PCI FATAL interrupt\n",
6888 __func__);
6889 }
6890 if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6891 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6892 "%s: received PCI PERR interrupt\n",
6893 __func__);
6894 }
6895 }
6896 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6897 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6898 "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6899 __func__);
6900 REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6901 REG_WRITE(ah, AR_RC, 0);
6902 *masked |= ATH9K_INT_FATAL;
6903 }
6904 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6905 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6906 "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6907 __func__);
6908 }
6909
6910 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6911 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6912 }
6913 return true;
6914}
6915
6916enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6917{
6918 return AH5416(ah)->ah_maskReg;
6919}
6920
6921enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6922{
6923 struct ath_hal_5416 *ahp = AH5416(ah);
6924 u32 omask = ahp->ah_maskReg;
6925 u32 mask, mask2;
6926 struct hal_capabilities *pCap = &ah->ah_caps;
6927
6928 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6929 omask, ints);
6930
6931 if (omask & ATH9K_INT_GLOBAL) {
6932 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6933 __func__);
6934 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6935 (void) REG_READ(ah, AR_IER);
6936 if (!AR_SREV_9100(ah)) {
6937 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6938 (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6939
6940 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6941 (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6942 }
6943 }
6944
6945 mask = ints & ATH9K_INT_COMMON;
6946 mask2 = 0;
6947
6948 if (ints & ATH9K_INT_TX) {
6949 if (ahp->ah_txOkInterruptMask)
6950 mask |= AR_IMR_TXOK;
6951 if (ahp->ah_txDescInterruptMask)
6952 mask |= AR_IMR_TXDESC;
6953 if (ahp->ah_txErrInterruptMask)
6954 mask |= AR_IMR_TXERR;
6955 if (ahp->ah_txEolInterruptMask)
6956 mask |= AR_IMR_TXEOL;
6957 }
6958 if (ints & ATH9K_INT_RX) {
6959 mask |= AR_IMR_RXERR;
6960 if (ahp->ah_intrMitigation)
6961 mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6962 else
6963 mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6964 if (!pCap->halAutoSleepSupport)
6965 mask |= AR_IMR_GENTMR;
6966 }
6967
6968 if (ints & (ATH9K_INT_BMISC)) {
6969 mask |= AR_IMR_BCNMISC;
6970 if (ints & ATH9K_INT_TIM)
6971 mask2 |= AR_IMR_S2_TIM;
6972 if (ints & ATH9K_INT_DTIM)
6973 mask2 |= AR_IMR_S2_DTIM;
6974 if (ints & ATH9K_INT_DTIMSYNC)
6975 mask2 |= AR_IMR_S2_DTIMSYNC;
6976 if (ints & ATH9K_INT_CABEND)
6977 mask2 |= (AR_IMR_S2_CABEND);
6978 }
6979
6980 if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
6981 mask |= AR_IMR_BCNMISC;
6982 if (ints & ATH9K_INT_GTT)
6983 mask2 |= AR_IMR_S2_GTT;
6984 if (ints & ATH9K_INT_CST)
6985 mask2 |= AR_IMR_S2_CST;
6986 }
6987
6988 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
6989 mask);
6990 REG_WRITE(ah, AR_IMR, mask);
6991 mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
6992 AR_IMR_S2_DTIM |
6993 AR_IMR_S2_DTIMSYNC |
6994 AR_IMR_S2_CABEND |
6995 AR_IMR_S2_CABTO |
6996 AR_IMR_S2_TSFOOR |
6997 AR_IMR_S2_GTT | AR_IMR_S2_CST);
6998 REG_WRITE(ah, AR_IMR_S2, mask | mask2);
6999 ahp->ah_maskReg = ints;
7000
7001 if (!pCap->halAutoSleepSupport) {
7002 if (ints & ATH9K_INT_TIM_TIMER)
7003 REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7004 else
7005 REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7006 }
7007
7008 if (ints & ATH9K_INT_GLOBAL) {
7009 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7010 __func__);
7011 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7012 if (!AR_SREV_9100(ah)) {
7013 REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7014 AR_INTR_MAC_IRQ);
7015 REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7016
7017
7018 REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7019 AR_INTR_SYNC_DEFAULT);
7020 REG_WRITE(ah, AR_INTR_SYNC_MASK,
7021 AR_INTR_SYNC_DEFAULT);
7022 }
7023 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7024 REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7025 }
7026
7027 return omask;
7028}
7029
7030void
7031ath9k_hw_beaconinit(struct ath_hal *ah,
7032 u32 next_beacon, u32 beacon_period)
7033{
7034 struct ath_hal_5416 *ahp = AH5416(ah);
7035 int flags = 0;
7036
7037 ahp->ah_beaconInterval = beacon_period;
7038
7039 switch (ah->ah_opmode) {
7040 case ATH9K_M_STA:
7041 case ATH9K_M_MONITOR:
7042 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7043 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7044 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7045 flags |= AR_TBTT_TIMER_EN;
7046 break;
7047 case ATH9K_M_IBSS:
7048 REG_SET_BIT(ah, AR_TXCFG,
7049 AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7050 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7051 TU_TO_USEC(next_beacon +
7052 (ahp->ah_atimWindow ? ahp->
7053 ah_atimWindow : 1)));
7054 flags |= AR_NDP_TIMER_EN;
7055 case ATH9K_M_HOSTAP:
7056 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7057 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7058 TU_TO_USEC(next_beacon -
7059 ah->ah_config.
7060 ath_hal_dma_beacon_response_time));
7061 REG_WRITE(ah, AR_NEXT_SWBA,
7062 TU_TO_USEC(next_beacon -
7063 ah->ah_config.
7064 ath_hal_sw_beacon_response_time));
7065 flags |=
7066 AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7067 break;
7068 }
7069
7070 REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7071 REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7072 REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7073 REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7074
7075 beacon_period &= ~ATH9K_BEACON_ENA;
7076 if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7077 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7078 ath9k_hw_reset_tsf(ah);
7079 }
7080
7081 REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7082}
7083
7084void
7085ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7086 const struct ath9k_beacon_state *bs)
7087{
7088 u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7089 struct hal_capabilities *pCap = &ah->ah_caps;
7090
7091 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7092
7093 REG_WRITE(ah, AR_BEACON_PERIOD,
7094 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7095 REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7096 TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7097
7098 REG_RMW_FIELD(ah, AR_RSSI_THR,
7099 AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7100
7101 beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7102
7103 if (bs->bs_sleepduration > beaconintval)
7104 beaconintval = bs->bs_sleepduration;
7105
7106 dtimperiod = bs->bs_dtimperiod;
7107 if (bs->bs_sleepduration > dtimperiod)
7108 dtimperiod = bs->bs_sleepduration;
7109
7110 if (beaconintval == dtimperiod)
7111 nextTbtt = bs->bs_nextdtim;
7112 else
7113 nextTbtt = bs->bs_nexttbtt;
7114
7115 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7116 bs->bs_nextdtim);
7117 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7118 nextTbtt);
7119 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7120 beaconintval);
7121 DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7122 dtimperiod);
7123
7124 REG_WRITE(ah, AR_NEXT_DTIM,
7125 TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7126 REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7127
7128 REG_WRITE(ah, AR_SLEEP1,
7129 SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7130 | AR_SLEEP1_ASSUME_DTIM);
7131
7132 if (pCap->halAutoSleepSupport)
7133 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7134 else
7135 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7136
7137 REG_WRITE(ah, AR_SLEEP2,
7138 SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7139
7140 REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7141 REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7142
7143 REG_SET_BIT(ah, AR_TIMER_MODE,
7144 AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7145 AR_DTIM_TIMER_EN);
7146
7147}
7148
7149bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7150{
7151 if (entry < ah->ah_caps.halKeyCacheSize) {
7152 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7153 if (val & AR_KEYTABLE_VALID)
7154 return true;
7155 }
7156 return false;
7157}
7158
7159bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7160{
7161 u32 keyType;
7162
7163 if (entry >= ah->ah_caps.halKeyCacheSize) {
7164 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7165 "%s: entry %u out of range\n", __func__, entry);
7166 return false;
7167 }
7168 keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7169
7170 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7171 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7172 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7173 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7174 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7175 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7176 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7177 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7178
7179 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7180 u16 micentry = entry + 64;
7181
7182 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7183 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7184 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7185 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7186
7187 }
7188
7189 if (ah->ah_curchan == NULL)
7190 return true;
7191
7192 return true;
7193}
7194
7195bool
7196ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7197 const u8 *mac)
7198{
7199 u32 macHi, macLo;
7200
7201 if (entry >= ah->ah_caps.halKeyCacheSize) {
7202 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7203 "%s: entry %u out of range\n", __func__, entry);
7204 return false;
7205 }
7206
7207 if (mac != NULL) {
7208 macHi = (mac[5] << 8) | mac[4];
7209 macLo = (mac[3] << 24) | (mac[2] << 16)
7210 | (mac[1] << 8) | mac[0];
7211 macLo >>= 1;
7212 macLo |= (macHi & 1) << 31;
7213 macHi >>= 1;
7214 } else {
7215 macLo = macHi = 0;
7216 }
7217 REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7218 REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7219
7220 return true;
7221}
7222
7223bool
7224ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7225 const struct ath9k_keyval *k,
7226 const u8 *mac, int xorKey)
7227{
7228 const struct hal_capabilities *pCap = &ah->ah_caps;
7229 u32 key0, key1, key2, key3, key4;
7230 u32 keyType;
7231 u32 xorMask = xorKey ?
7232 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7233 | ATH9K_KEY_XOR) : 0;
7234 struct ath_hal_5416 *ahp = AH5416(ah);
7235
7236 if (entry >= pCap->halKeyCacheSize) {
7237 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7238 "%s: entry %u out of range\n", __func__, entry);
7239 return false;
7240 }
7241 switch (k->kv_type) {
7242 case ATH9K_CIPHER_AES_OCB:
7243 keyType = AR_KEYTABLE_TYPE_AES;
7244 break;
7245 case ATH9K_CIPHER_AES_CCM:
7246 if (!pCap->halCipherAesCcmSupport) {
7247 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7248 "%s: AES-CCM not supported by "
7249 "mac rev 0x%x\n", __func__,
7250 ah->ah_macRev);
7251 return false;
7252 }
7253 keyType = AR_KEYTABLE_TYPE_CCM;
7254 break;
7255 case ATH9K_CIPHER_TKIP:
7256 keyType = AR_KEYTABLE_TYPE_TKIP;
7257 if (ATH9K_IS_MIC_ENABLED(ah)
7258 && entry + 64 >= pCap->halKeyCacheSize) {
7259 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7260 "%s: entry %u inappropriate for TKIP\n",
7261 __func__, entry);
7262 return false;
7263 }
7264 break;
7265 case ATH9K_CIPHER_WEP:
7266 if (k->kv_len < 40 / NBBY) {
7267 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7268 "%s: WEP key length %u too small\n",
7269 __func__, k->kv_len);
7270 return false;
7271 }
7272 if (k->kv_len <= 40 / NBBY)
7273 keyType = AR_KEYTABLE_TYPE_40;
7274 else if (k->kv_len <= 104 / NBBY)
7275 keyType = AR_KEYTABLE_TYPE_104;
7276 else
7277 keyType = AR_KEYTABLE_TYPE_128;
7278 break;
7279 case ATH9K_CIPHER_CLR:
7280 keyType = AR_KEYTABLE_TYPE_CLR;
7281 break;
7282 default:
7283 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7284 "%s: cipher %u not supported\n", __func__,
7285 k->kv_type);
7286 return false;
7287 }
7288
7289 key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7290 key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7291 key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7292 key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7293 key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7294 if (k->kv_len <= 104 / NBBY)
7295 key4 &= 0xff;
7296
7297 if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7298 u16 micentry = entry + 64;
7299
7300 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7301 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7302 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7303 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7304 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7305 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7306 (void) ath9k_hw_keysetmac(ah, entry, mac);
7307
7308 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7309 u32 mic0, mic1, mic2, mic3, mic4;
7310
7311 mic0 = get_unaligned_le32(k->kv_mic + 0);
7312 mic2 = get_unaligned_le32(k->kv_mic + 4);
7313 mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7314 mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7315 mic4 = get_unaligned_le32(k->kv_txmic + 4);
7316 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7317 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7318 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7319 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7320 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7321 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7322 AR_KEYTABLE_TYPE_CLR);
7323
7324 } else {
7325 u32 mic0, mic2;
7326
7327 mic0 = get_unaligned_le32(k->kv_mic + 0);
7328 mic2 = get_unaligned_le32(k->kv_mic + 4);
7329 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7330 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7331 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7332 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7333 REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7334 REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7335 AR_KEYTABLE_TYPE_CLR);
7336 }
7337 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7338 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7339 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7340 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7341 } else {
7342 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7343 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7344 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7345 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7346 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7347 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7348
7349 (void) ath9k_hw_keysetmac(ah, entry, mac);
7350 }
7351
7352 if (ah->ah_curchan == NULL)
7353 return true;
7354
7355 return true;
7356}
7357
7358bool
7359ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7360{
7361 struct ath_hal_5416 *ahp = AH5416(ah);
7362 u32 txcfg, curLevel, newLevel;
7363 enum ath9k_int omask;
7364
7365 if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7366 return false;
7367
7368 omask = ath9k_hw_set_interrupts(ah,
7369 ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7370
7371 txcfg = REG_READ(ah, AR_TXCFG);
7372 curLevel = MS(txcfg, AR_FTRIG);
7373 newLevel = curLevel;
7374 if (bIncTrigLevel) {
7375 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7376 newLevel++;
7377 } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7378 newLevel--;
7379 if (newLevel != curLevel)
7380 REG_WRITE(ah, AR_TXCFG,
7381 (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7382
7383 ath9k_hw_set_interrupts(ah, omask);
7384
7385 ah->ah_txTrigLevel = newLevel;
7386
7387 return newLevel != curLevel;
7388}
7389
7390static bool ath9k_hw_set_txq_props(struct ath_hal *ah,
7391 struct ath9k_tx_queue_info *qi,
7392 const struct ath9k_txq_info *qInfo)
7393{
7394 u32 cw;
7395
7396 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7397 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7398 __func__);
7399 return false;
7400 }
7401
7402 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7403
7404 qi->tqi_ver = qInfo->tqi_ver;
7405 qi->tqi_subtype = qInfo->tqi_subtype;
7406 qi->tqi_qflags = qInfo->tqi_qflags;
7407 qi->tqi_priority = qInfo->tqi_priority;
7408 if (qInfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7409 qi->tqi_aifs = min(qInfo->tqi_aifs, 255U);
7410 else
7411 qi->tqi_aifs = INIT_AIFS;
7412 if (qInfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7413 cw = min(qInfo->tqi_cwmin, 1024U);
7414 qi->tqi_cwmin = 1;
7415 while (qi->tqi_cwmin < cw)
7416 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7417 } else
7418 qi->tqi_cwmin = qInfo->tqi_cwmin;
7419 if (qInfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7420 cw = min(qInfo->tqi_cwmax, 1024U);
7421 qi->tqi_cwmax = 1;
7422 while (qi->tqi_cwmax < cw)
7423 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7424 } else
7425 qi->tqi_cwmax = INIT_CWMAX;
7426
7427 if (qInfo->tqi_shretry != 0)
7428 qi->tqi_shretry = min((u32) qInfo->tqi_shretry, 15U);
7429 else
7430 qi->tqi_shretry = INIT_SH_RETRY;
7431 if (qInfo->tqi_lgretry != 0)
7432 qi->tqi_lgretry = min((u32) qInfo->tqi_lgretry, 15U);
7433 else
7434 qi->tqi_lgretry = INIT_LG_RETRY;
7435 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod;
7436 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit;
7437 qi->tqi_burstTime = qInfo->tqi_burstTime;
7438 qi->tqi_readyTime = qInfo->tqi_readyTime;
7439
7440 switch (qInfo->tqi_subtype) {
7441 case ATH9K_WME_UPSD:
7442 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7443 qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7444 break;
7445 default:
7446 break;
7447 }
7448 return true;
7449}
7450
7451bool ath9k_hw_settxqueueprops(struct ath_hal *ah, int q,
7452 const struct ath9k_txq_info *qInfo)
7453{
7454 struct ath_hal_5416 *ahp = AH5416(ah);
7455 struct hal_capabilities *pCap = &ah->ah_caps;
7456
7457 if (q >= pCap->halTotalQueues) {
7458 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7459 __func__, q);
7460 return false;
7461 }
7462 return ath9k_hw_set_txq_props(ah, &ahp->ah_txq[q], qInfo);
7463}
7464
7465static bool ath9k_hw_get_txq_props(struct ath_hal *ah,
7466 struct ath9k_txq_info *qInfo,
7467 const struct ath9k_tx_queue_info *qi)
7468{
7469 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7470 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7471 __func__);
7472 return false;
7473 }
7474
7475 qInfo->tqi_qflags = qi->tqi_qflags;
7476 qInfo->tqi_ver = qi->tqi_ver;
7477 qInfo->tqi_subtype = qi->tqi_subtype;
7478 qInfo->tqi_qflags = qi->tqi_qflags;
7479 qInfo->tqi_priority = qi->tqi_priority;
7480 qInfo->tqi_aifs = qi->tqi_aifs;
7481 qInfo->tqi_cwmin = qi->tqi_cwmin;
7482 qInfo->tqi_cwmax = qi->tqi_cwmax;
7483 qInfo->tqi_shretry = qi->tqi_shretry;
7484 qInfo->tqi_lgretry = qi->tqi_lgretry;
7485 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7486 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7487 qInfo->tqi_burstTime = qi->tqi_burstTime;
7488 qInfo->tqi_readyTime = qi->tqi_readyTime;
7489
7490 return true;
7491}
7492
7493bool
7494ath9k_hw_gettxqueueprops(struct ath_hal *ah, int q,
7495 struct ath9k_txq_info *qInfo)
7496{
7497 struct ath_hal_5416 *ahp = AH5416(ah);
7498 struct hal_capabilities *pCap = &ah->ah_caps;
7499
7500 if (q >= pCap->halTotalQueues) {
7501 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7502 __func__, q);
7503 return false;
7504 }
7505 return ath9k_hw_get_txq_props(ah, qInfo, &ahp->ah_txq[q]);
7506}
7507
7508int
7509ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7510 const struct ath9k_txq_info *qInfo)
7511{
7512 struct ath_hal_5416 *ahp = AH5416(ah);
7513 struct ath9k_tx_queue_info *qi;
7514 struct hal_capabilities *pCap = &ah->ah_caps;
7515 int q;
7516
7517 switch (type) {
7518 case ATH9K_TX_QUEUE_BEACON:
7519 q = pCap->halTotalQueues - 1;
7520 break;
7521 case ATH9K_TX_QUEUE_CAB:
7522 q = pCap->halTotalQueues - 2;
7523 break;
7524 case ATH9K_TX_QUEUE_PSPOLL:
7525 q = 1;
7526 break;
7527 case ATH9K_TX_QUEUE_UAPSD:
7528 q = pCap->halTotalQueues - 3;
7529 break;
7530 case ATH9K_TX_QUEUE_DATA:
7531 for (q = 0; q < pCap->halTotalQueues; q++)
7532 if (ahp->ah_txq[q].tqi_type ==
7533 ATH9K_TX_QUEUE_INACTIVE)
7534 break;
7535 if (q == pCap->halTotalQueues) {
7536 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7537 "%s: no available tx queue\n", __func__);
7538 return -1;
7539 }
7540 break;
7541 default:
7542 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7543 __func__, type);
7544 return -1;
7545 }
7546
7547 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7548
7549 qi = &ahp->ah_txq[q];
7550 if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7551 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7552 "%s: tx queue %u already active\n", __func__, q);
7553 return -1;
7554 }
7555 memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7556 qi->tqi_type = type;
7557 if (qInfo == NULL) {
7558 qi->tqi_qflags =
7559 TXQ_FLAG_TXOKINT_ENABLE
7560 | TXQ_FLAG_TXERRINT_ENABLE
7561 | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7562 qi->tqi_aifs = INIT_AIFS;
7563 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7564 qi->tqi_cwmax = INIT_CWMAX;
7565 qi->tqi_shretry = INIT_SH_RETRY;
7566 qi->tqi_lgretry = INIT_LG_RETRY;
7567 qi->tqi_physCompBuf = 0;
7568 } else {
7569 qi->tqi_physCompBuf = qInfo->tqi_compBuf;
7570 (void) ath9k_hw_settxqueueprops(ah, q, qInfo);
7571 }
7572
7573 return q;
7574}
7575
7576static void
7577ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7578 struct ath9k_tx_queue_info *qi)
7579{
7580 struct ath_hal_5416 *ahp = AH5416(ah);
7581
7582 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7583 "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7584 __func__, ahp->ah_txOkInterruptMask,
7585 ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7586 ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7587
7588 REG_WRITE(ah, AR_IMR_S0,
7589 SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7590 | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7591 REG_WRITE(ah, AR_IMR_S1,
7592 SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7593 | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7594 REG_RMW_FIELD(ah, AR_IMR_S2,
7595 AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7596}
7597
7598bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7599{
7600 struct ath_hal_5416 *ahp = AH5416(ah);
7601 struct hal_capabilities *pCap = &ah->ah_caps;
7602 struct ath9k_tx_queue_info *qi;
7603
7604 if (q >= pCap->halTotalQueues) {
7605 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7606 __func__, q);
7607 return false;
7608 }
7609 qi = &ahp->ah_txq[q];
7610 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7611 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7612 __func__, q);
7613 return false;
7614 }
7615
7616 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7617 __func__, q);
7618
7619 qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7620 ahp->ah_txOkInterruptMask &= ~(1 << q);
7621 ahp->ah_txErrInterruptMask &= ~(1 << q);
7622 ahp->ah_txDescInterruptMask &= ~(1 << q);
7623 ahp->ah_txEolInterruptMask &= ~(1 << q);
7624 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7625 ath9k_hw_set_txq_interrupts(ah, qi);
7626
7627 return true;
7628}
7629
7630bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7631{
7632 struct ath_hal_5416 *ahp = AH5416(ah);
7633 struct hal_capabilities *pCap = &ah->ah_caps;
7634 struct ath9k_channel *chan = ah->ah_curchan;
7635 struct ath9k_tx_queue_info *qi;
7636 u32 cwMin, chanCwMin, value;
7637
7638 if (q >= pCap->halTotalQueues) {
7639 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7640 __func__, q);
7641 return false;
7642 }
7643 qi = &ahp->ah_txq[q];
7644 if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7645 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7646 __func__, q);
7647 return true;
7648 }
7649
7650 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7651
7652 if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7653 if (chan && IS_CHAN_B(chan))
7654 chanCwMin = INIT_CWMIN_11B;
7655 else
7656 chanCwMin = INIT_CWMIN;
7657
7658 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7659 } else
7660 cwMin = qi->tqi_cwmin;
7661
7662 REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7663 | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7664 | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7665
7666 REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7667 SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7668 | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7669 | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7670 );
7671
7672 REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7673 REG_WRITE(ah, AR_DMISC(q),
7674 AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7675
7676 if (qi->tqi_cbrPeriod) {
7677 REG_WRITE(ah, AR_QCBRCFG(q),
7678 SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7679 | SM(qi->tqi_cbrOverflowLimit,
7680 AR_Q_CBRCFG_OVF_THRESH));
7681 REG_WRITE(ah, AR_QMISC(q),
7682 REG_READ(ah,
7683 AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7684 tqi_cbrOverflowLimit
7685 ?
7686 AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7687 :
7688 0));
7689 }
7690 if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7691 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7692 SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7693 AR_Q_RDYTIMECFG_EN);
7694 }
7695
7696 REG_WRITE(ah, AR_DCHNTIME(q),
7697 SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7698 (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7699
7700 if (qi->tqi_burstTime
7701 && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7702 REG_WRITE(ah, AR_QMISC(q),
7703 REG_READ(ah,
7704 AR_QMISC(q)) |
7705 AR_Q_MISC_RDYTIME_EXP_POLICY);
7706
7707 }
7708
7709 if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7710 REG_WRITE(ah, AR_DMISC(q),
7711 REG_READ(ah, AR_DMISC(q)) |
7712 AR_D_MISC_POST_FR_BKOFF_DIS);
7713 }
7714 if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7715 REG_WRITE(ah, AR_DMISC(q),
7716 REG_READ(ah, AR_DMISC(q)) |
7717 AR_D_MISC_FRAG_BKOFF_EN);
7718 }
7719 switch (qi->tqi_type) {
7720 case ATH9K_TX_QUEUE_BEACON:
7721 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7722 | AR_Q_MISC_FSP_DBA_GATED
7723 | AR_Q_MISC_BEACON_USE
7724 | AR_Q_MISC_CBR_INCR_DIS1);
7725
7726 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7727 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7728 AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7729 | AR_D_MISC_BEACON_USE
7730 | AR_D_MISC_POST_FR_BKOFF_DIS);
7731 break;
7732 case ATH9K_TX_QUEUE_CAB:
7733 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7734 | AR_Q_MISC_FSP_DBA_GATED
7735 | AR_Q_MISC_CBR_INCR_DIS1
7736 | AR_Q_MISC_CBR_INCR_DIS0);
7737 value = (qi->tqi_readyTime
7738 - (ah->ah_config.ath_hal_sw_beacon_response_time -
7739 ah->ah_config.ath_hal_dma_beacon_response_time)
7740 -
7741 ah->ah_config.ath_hal_additional_swba_backoff) *
7742 1024;
7743 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7744 value | AR_Q_RDYTIMECFG_EN);
7745 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7746 | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7747 AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7748 break;
7749 case ATH9K_TX_QUEUE_PSPOLL:
7750 REG_WRITE(ah, AR_QMISC(q),
7751 REG_READ(ah,
7752 AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7753 break;
7754 case ATH9K_TX_QUEUE_UAPSD:
7755 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7756 | AR_D_MISC_POST_FR_BKOFF_DIS);
7757 break;
7758 default:
7759 break;
7760 }
7761
7762 if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7763 REG_WRITE(ah, AR_DMISC(q),
7764 REG_READ(ah, AR_DMISC(q)) |
7765 SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7766 AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7767 AR_D_MISC_POST_FR_BKOFF_DIS);
7768 }
7769
7770 if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7771 ahp->ah_txOkInterruptMask |= 1 << q;
7772 else
7773 ahp->ah_txOkInterruptMask &= ~(1 << q);
7774 if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7775 ahp->ah_txErrInterruptMask |= 1 << q;
7776 else
7777 ahp->ah_txErrInterruptMask &= ~(1 << q);
7778 if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7779 ahp->ah_txDescInterruptMask |= 1 << q;
7780 else
7781 ahp->ah_txDescInterruptMask &= ~(1 << q);
7782 if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7783 ahp->ah_txEolInterruptMask |= 1 << q;
7784 else
7785 ahp->ah_txEolInterruptMask &= ~(1 << q);
7786 if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7787 ahp->ah_txUrnInterruptMask |= 1 << q;
7788 else
7789 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7790 ath9k_hw_set_txq_interrupts(ah, qi);
7791
7792 return true;
7793}
7794
7795void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7796{
7797 struct ath_hal_5416 *ahp = AH5416(ah);
7798 *txqs &= ahp->ah_intrTxqs;
7799 ahp->ah_intrTxqs &= ~(*txqs);
7800}
7801
7802bool
7803ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7804 u32 segLen, bool firstSeg,
7805 bool lastSeg, const struct ath_desc *ds0)
7806{
7807 struct ar5416_desc *ads = AR5416DESC(ds);
7808
7809 if (firstSeg) {
7810 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7811 } else if (lastSeg) {
7812 ads->ds_ctl0 = 0;
7813 ads->ds_ctl1 = segLen;
7814 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7815 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7816 } else {
7817 ads->ds_ctl0 = 0;
7818 ads->ds_ctl1 = segLen | AR_TxMore;
7819 ads->ds_ctl2 = 0;
7820 ads->ds_ctl3 = 0;
7821 }
7822 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7823 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7824 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7825 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7826 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7827 return true;
7828}
7829
7830void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7831{
7832 struct ar5416_desc *ads = AR5416DESC(ds);
7833
7834 ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7835 ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7836 ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7837 ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7838 ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7839}
7840
7841int
7842ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7843{
7844 struct ar5416_desc *ads = AR5416DESC(ds);
7845
7846 if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7847 return -EINPROGRESS;
7848
7849 ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7850 ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7851 ds->ds_txstat.ts_status = 0;
7852 ds->ds_txstat.ts_flags = 0;
7853
7854 if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7855 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7856 if (ads->ds_txstatus1 & AR_Filtered)
7857 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7858 if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7859 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7860 if (ads->ds_txstatus9 & AR_TxOpExceeded)
7861 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7862 if (ads->ds_txstatus1 & AR_TxTimerExpired)
7863 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7864
7865 if (ads->ds_txstatus1 & AR_DescCfgErr)
7866 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7867 if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7868 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7869 ath9k_hw_updatetxtriglevel(ah, true);
7870 }
7871 if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7872 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7873 ath9k_hw_updatetxtriglevel(ah, true);
7874 }
7875 if (ads->ds_txstatus0 & AR_TxBaStatus) {
7876 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7877 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7878 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7879 }
7880
7881 ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7882 switch (ds->ds_txstat.ts_rateindex) {
7883 case 0:
7884 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7885 break;
7886 case 1:
7887 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7888 break;
7889 case 2:
7890 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7891 break;
7892 case 3:
7893 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7894 break;
7895 }
7896
7897 ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7898 ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7899 ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7900 ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7901 ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7902 ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7903 ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7904 ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7905 ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7906 ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7907 ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7908 ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7909 ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7910 ds->ds_txstat.ts_antenna = 1;
7911
7912 return 0;
7913}
7914
7915void
7916ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7917 u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7918 u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7919{
7920 struct ar5416_desc *ads = AR5416DESC(ds);
7921 struct ath_hal_5416 *ahp = AH5416(ah);
7922
7923 txPower += ahp->ah_txPowerIndexOffset;
7924 if (txPower > 63)
7925 txPower = 63;
7926
7927 ads->ds_ctl0 = (pktLen & AR_FrameLen)
7928 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7929 | SM(txPower, AR_XmitPower)
7930 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7931 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7932 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7933 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7934
7935 ads->ds_ctl1 =
7936 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7937 | SM(type, AR_FrameType)
7938 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7939 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7940 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7941
7942 ads->ds_ctl6 = SM(keyType, AR_EncrType);
7943
7944 if (AR_SREV_9285(ah)) {
7945
7946 ads->ds_ctl8 = 0;
7947 ads->ds_ctl9 = 0;
7948 ads->ds_ctl10 = 0;
7949 ads->ds_ctl11 = 0;
7950 }
7951}
7952
7953void
7954ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7955 struct ath_desc *lastds,
7956 u32 durUpdateEn, u32 rtsctsRate,
7957 u32 rtsctsDuration,
7958 struct ath9k_11n_rate_series series[],
7959 u32 nseries, u32 flags)
7960{
7961 struct ar5416_desc *ads = AR5416DESC(ds);
7962 struct ar5416_desc *last_ads = AR5416DESC(lastds);
7963 u32 ds_ctl0;
7964
7965 (void) nseries;
7966 (void) rtsctsDuration;
7967
7968 if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7969 ds_ctl0 = ads->ds_ctl0;
7970
7971 if (flags & ATH9K_TXDESC_RTSENA) {
7972 ds_ctl0 &= ~AR_CTSEnable;
7973 ds_ctl0 |= AR_RTSEnable;
7974 } else {
7975 ds_ctl0 &= ~AR_RTSEnable;
7976 ds_ctl0 |= AR_CTSEnable;
7977 }
7978
7979 ads->ds_ctl0 = ds_ctl0;
7980 } else {
7981 ads->ds_ctl0 =
7982 (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7983 }
7984
7985 ads->ds_ctl2 = set11nTries(series, 0)
7986 | set11nTries(series, 1)
7987 | set11nTries(series, 2)
7988 | set11nTries(series, 3)
7989 | (durUpdateEn ? AR_DurUpdateEna : 0)
7990 | SM(0, AR_BurstDur);
7991
7992 ads->ds_ctl3 = set11nRate(series, 0)
7993 | set11nRate(series, 1)
7994 | set11nRate(series, 2)
7995 | set11nRate(series, 3);
7996
7997 ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
7998 | set11nPktDurRTSCTS(series, 1);
7999
8000 ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8001 | set11nPktDurRTSCTS(series, 3);
8002
8003 ads->ds_ctl7 = set11nRateFlags(series, 0)
8004 | set11nRateFlags(series, 1)
8005 | set11nRateFlags(series, 2)
8006 | set11nRateFlags(series, 3)
8007 | SM(rtsctsRate, AR_RTSCTSRate);
8008 last_ads->ds_ctl2 = ads->ds_ctl2;
8009 last_ads->ds_ctl3 = ads->ds_ctl3;
8010}
8011
8012void
8013ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8014 u32 aggrLen)
8015{
8016 struct ar5416_desc *ads = AR5416DESC(ds);
8017
8018 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8019
8020 ads->ds_ctl6 &= ~AR_AggrLen;
8021 ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8022}
8023
8024void
8025ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8026 u32 numDelims)
8027{
8028 struct ar5416_desc *ads = AR5416DESC(ds);
8029 unsigned int ctl6;
8030
8031 ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8032
8033 ctl6 = ads->ds_ctl6;
8034 ctl6 &= ~AR_PadDelim;
8035 ctl6 |= SM(numDelims, AR_PadDelim);
8036 ads->ds_ctl6 = ctl6;
8037}
8038
8039void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8040{
8041 struct ar5416_desc *ads = AR5416DESC(ds);
8042
8043 ads->ds_ctl1 |= AR_IsAggr;
8044 ads->ds_ctl1 &= ~AR_MoreAggr;
8045 ads->ds_ctl6 &= ~AR_PadDelim;
8046}
8047
8048void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8049{
8050 struct ar5416_desc *ads = AR5416DESC(ds);
8051
8052 ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8053}
8054
8055void
8056ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8057 u32 burstDuration)
8058{
8059 struct ar5416_desc *ads = AR5416DESC(ds);
8060
8061 ads->ds_ctl2 &= ~AR_BurstDur;
8062 ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8063}
8064
8065void
8066ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8067 u32 vmf)
8068{
8069 struct ar5416_desc *ads = AR5416DESC(ds);
8070
8071 if (vmf)
8072 ads->ds_ctl0 |= AR_VirtMoreFrag;
8073 else
8074 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8075}
8076
8077void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8078{
8079 REG_WRITE(ah, AR_RXDP, rxdp);
8080}
8081
8082void ath9k_hw_rxena(struct ath_hal *ah)
8083{
8084 REG_WRITE(ah, AR_CR, AR_CR_RXE);
8085}
8086
8087bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8088{
8089 if (set) {
8090
8091 REG_SET_BIT(ah, AR_DIAG_SW,
8092 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8093
8094 if (!ath9k_hw_wait
8095 (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8096 u32 reg;
8097
8098 REG_CLR_BIT(ah, AR_DIAG_SW,
8099 (AR_DIAG_RX_DIS |
8100 AR_DIAG_RX_ABORT));
8101
8102 reg = REG_READ(ah, AR_OBS_BUS_1);
8103 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8104 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8105 __func__, reg);
8106
8107 return false;
8108 }
8109 } else {
8110 REG_CLR_BIT(ah, AR_DIAG_SW,
8111 (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8112 }
8113
8114 return true;
8115}
8116
8117void
8118ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8119 u32 filter1)
8120{
8121 REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8122 REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8123}
8124
8125bool
8126ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8127 u32 size, u32 flags)
8128{
8129 struct ar5416_desc *ads = AR5416DESC(ds);
8130 struct hal_capabilities *pCap = &ah->ah_caps;
8131
8132 ads->ds_ctl1 = size & AR_BufLen;
8133 if (flags & ATH9K_RXDESC_INTREQ)
8134 ads->ds_ctl1 |= AR_RxIntrReq;
8135
8136 ads->ds_rxstatus8 &= ~AR_RxDone;
8137 if (!pCap->halAutoSleepSupport)
8138 memset(&(ads->u), 0, sizeof(ads->u));
8139 return true;
8140}
8141
8142int
8143ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8144 u32 pa, struct ath_desc *nds, u64 tsf)
8145{
8146 struct ar5416_desc ads;
8147 struct ar5416_desc *adsp = AR5416DESC(ds);
8148
8149 if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8150 return -EINPROGRESS;
8151
8152 ads.u.rx = adsp->u.rx;
8153
8154 ds->ds_rxstat.rs_status = 0;
8155 ds->ds_rxstat.rs_flags = 0;
8156
8157 ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8158 ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8159
8160 ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8161 ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8162 ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8163 ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8164 ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8165 ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8166 ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8167 if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8168 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8169 else
8170 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8171
8172 ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8173 ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8174
8175 ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8176 ds->ds_rxstat.rs_moreaggr =
8177 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8178 ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8179 ds->ds_rxstat.rs_flags =
8180 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8181 ds->ds_rxstat.rs_flags |=
8182 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8183
8184 if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8185 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8186 if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8187 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8188 if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8189 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8190
8191 if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8192
8193 if (ads.ds_rxstatus8 & AR_CRCErr)
8194 ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8195 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8196 u32 phyerr;
8197
8198 ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8199 phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8200 ds->ds_rxstat.rs_phyerr = phyerr;
8201 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8202 ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8203 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8204 ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8205 }
8206
8207 return 0;
8208}
8209
8210static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8211 struct ath9k_rate_table *rt)
8212{
8213 int i;
8214
8215 if (rt->rateCodeToIndex[0] != 0)
8216 return;
8217 for (i = 0; i < 256; i++)
8218 rt->rateCodeToIndex[i] = (u8) -1;
8219 for (i = 0; i < rt->rateCount; i++) {
8220 u8 code = rt->info[i].rateCode;
8221 u8 cix = rt->info[i].controlRate;
8222
8223 rt->rateCodeToIndex[code] = i;
8224 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8225
8226 rt->info[i].lpAckDuration =
8227 ath9k_hw_computetxtime(ah, rt,
8228 WLAN_CTRL_FRAME_SIZE,
8229 cix,
8230 false);
8231 rt->info[i].spAckDuration =
8232 ath9k_hw_computetxtime(ah, rt,
8233 WLAN_CTRL_FRAME_SIZE,
8234 cix,
8235 true);
8236 }
8237}
8238
8239const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8240 u32 mode)
8241{
8242 struct ath9k_rate_table *rt;
8243 switch (mode) {
8244 case ATH9K_MODE_SEL_11A:
8245 rt = &ar5416_11a_table;
8246 break;
8247 case ATH9K_MODE_SEL_11B:
8248 rt = &ar5416_11b_table;
8249 break;
8250 case ATH9K_MODE_SEL_11G:
8251 rt = &ar5416_11g_table;
8252 break;
8253 case ATH9K_MODE_SEL_11NG_HT20:
8254 case ATH9K_MODE_SEL_11NG_HT40PLUS:
8255 case ATH9K_MODE_SEL_11NG_HT40MINUS:
8256 rt = &ar5416_11ng_table;
8257 break;
8258 case ATH9K_MODE_SEL_11NA_HT20:
8259 case ATH9K_MODE_SEL_11NA_HT40PLUS:
8260 case ATH9K_MODE_SEL_11NA_HT40MINUS:
8261 rt = &ar5416_11na_table;
8262 break;
8263 default:
8264 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8265 __func__, mode);
8266 return NULL;
8267 }
8268 ath9k_hw_setup_rate_table(ah, rt);
8269 return rt;
8270}
8271
8272static const char *ath9k_hw_devname(u16 devid)
8273{
8274 switch (devid) {
8275 case AR5416_DEVID_PCI:
8276 case AR5416_DEVID_PCIE:
8277 return "Atheros 5416";
8278 case AR9160_DEVID_PCI:
8279 return "Atheros 9160";
8280 case AR9280_DEVID_PCI:
8281 case AR9280_DEVID_PCIE:
8282 return "Atheros 9280";
8283 }
8284 return NULL;
8285}
8286
8287const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8288{
8289 return vendorid == ATHEROS_VENDOR_ID ?
8290 ath9k_hw_devname(devid) : NULL;
8291}
8292
8293struct ath_hal *ath9k_hw_attach(u16 devid,
8294 struct ath_softc *sc,
8295 void __iomem *mem,
8296 int *error)
8297{
8298 struct ath_hal *ah = NULL;
8299
8300 switch (devid) {
8301 case AR5416_DEVID_PCI:
8302 case AR5416_DEVID_PCIE:
8303 case AR9160_DEVID_PCI:
8304 case AR9280_DEVID_PCI:
8305 case AR9280_DEVID_PCIE:
8306 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8307 break;
8308 default:
8309 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8310 "devid=0x%x not supported.\n", devid);
8311 ah = NULL;
8312 *error = -ENXIO;
8313 break;
8314 }
8315 if (ah != NULL) {
8316 ah->ah_devid = ah->ah_devid;
8317 ah->ah_subvendorid = ah->ah_subvendorid;
8318 ah->ah_macVersion = ah->ah_macVersion;
8319 ah->ah_macRev = ah->ah_macRev;
8320 ah->ah_phyRev = ah->ah_phyRev;
8321 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8322 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8323 }
8324 return ah;
8325}
8326
8327u16
8328ath9k_hw_computetxtime(struct ath_hal *ah,
8329 const struct ath9k_rate_table *rates,
8330 u32 frameLen, u16 rateix,
8331 bool shortPreamble)
8332{
8333 u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8334 u32 kbps;
8335
8336 kbps = rates->info[rateix].rateKbps;
8337
8338 if (kbps == 0)
8339 return 0;
8340 switch (rates->info[rateix].phy) {
8341
8342 case PHY_CCK:
8343 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8344 if (shortPreamble && rates->info[rateix].shortPreamble)
8345 phyTime >>= 1;
8346 numBits = frameLen << 3;
8347 txTime = CCK_SIFS_TIME + phyTime
8348 + ((numBits * 1000) / kbps);
8349 break;
8350 case PHY_OFDM:
8351 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8352 bitsPerSymbol =
8353 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8354
8355 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8356 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8357 txTime = OFDM_SIFS_TIME_QUARTER
8358 + OFDM_PREAMBLE_TIME_QUARTER
8359 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8360 } else if (ah->ah_curchan &&
8361 IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8362 bitsPerSymbol =
8363 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8364
8365 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8366 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8367 txTime = OFDM_SIFS_TIME_HALF +
8368 OFDM_PREAMBLE_TIME_HALF
8369 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8370 } else {
8371 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8372
8373 numBits = OFDM_PLCP_BITS + (frameLen << 3);
8374 numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8375 txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8376 + (numSymbols * OFDM_SYMBOL_TIME);
8377 }
8378 break;
8379
8380 default:
8381 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8382 "%s: unknown phy %u (rate ix %u)\n", __func__,
8383 rates->info[rateix].phy, rateix);
8384 txTime = 0;
8385 break;
8386 }
8387 return txTime;
8388}
8389
8390u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8391{
8392 if (flags & CHANNEL_2GHZ) {
8393 if (freq == 2484)
8394 return 14;
8395 if (freq < 2484)
8396 return (freq - 2407) / 5;
8397 else
8398 return 15 + ((freq - 2512) / 20);
8399 } else if (flags & CHANNEL_5GHZ) {
8400 if (ath9k_regd_is_public_safety_sku(ah) &&
8401 IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8402 return ((freq * 10) +
8403 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8404 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8405 return (freq - 4000) / 5;
8406 } else {
8407 return (freq - 5000) / 5;
8408 }
8409 } else {
8410 if (freq == 2484)
8411 return 14;
8412 if (freq < 2484)
8413 return (freq - 2407) / 5;
8414 if (freq < 5000) {
8415 if (ath9k_regd_is_public_safety_sku(ah)
8416 && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8417 return ((freq * 10) +
8418 (((freq % 5) ==
8419 2) ? 5 : 0) - 49400) / 5;
8420 } else if (freq > 4900) {
8421 return (freq - 4000) / 5;
8422 } else {
8423 return 15 + ((freq - 2512) / 20);
8424 }
8425 }
8426 return (freq - 5000) / 5;
8427 }
8428}
8429
8430int16_t
8431ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8432{
8433 struct ath9k_channel *ichan;
8434
8435 ichan = ath9k_regd_check_channel(ah, chan);
8436 if (ichan == NULL) {
8437 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8438 "%s: invalid channel %u/0x%x; no mapping\n",
8439 __func__, chan->channel, chan->channelFlags);
8440 return 0;
8441 }
8442 if (ichan->rawNoiseFloor == 0) {
8443 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8444 return NOISE_FLOOR[mode];
8445 } else
8446 return ichan->rawNoiseFloor;
8447}
8448
8449bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8450{
8451 struct ath_hal_5416 *ahp = AH5416(ah);
8452
8453 if (setting)
8454 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8455 else
8456 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8457 return true;
8458}
8459
8460bool ath9k_hw_phycounters(struct ath_hal *ah)
8461{
8462 struct ath_hal_5416 *ahp = AH5416(ah);
8463
8464 return ahp->ah_hasHwPhyCounters ? true : false;
8465}
8466
8467u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8468{
8469 return REG_READ(ah, AR_QTXDP(q));
8470}
8471
8472bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8473 u32 txdp)
8474{
8475 REG_WRITE(ah, AR_QTXDP(q), txdp);
8476
8477 return true;
8478}
8479
8480bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8481{
8482 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8483
8484 REG_WRITE(ah, AR_Q_TXE, 1 << q);
8485
8486 return true;
8487}
8488
8489u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8490{
8491 u32 npend;
8492
8493 npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8494 if (npend == 0) {
8495
8496 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8497 npend = 1;
8498 }
8499 return npend;
8500}
8501
8502bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8503{
8504 u32 wait;
8505
8506 REG_WRITE(ah, AR_Q_TXD, 1 << q);
8507
8508 for (wait = 1000; wait != 0; wait--) {
8509 if (ath9k_hw_numtxpending(ah, q) == 0)
8510 break;
8511 udelay(100);
8512 }
8513
8514 if (ath9k_hw_numtxpending(ah, q)) {
8515 u32 tsfLow, j;
8516
8517 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8518 "%s: Num of pending TX Frames %d on Q %d\n",
8519 __func__, ath9k_hw_numtxpending(ah, q), q);
8520
8521 for (j = 0; j < 2; j++) {
8522 tsfLow = REG_READ(ah, AR_TSF_L32);
8523 REG_WRITE(ah, AR_QUIET2,
8524 SM(10, AR_QUIET2_QUIET_DUR));
8525 REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8526 REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8527 REG_SET_BIT(ah, AR_TIMER_MODE,
8528 AR_QUIET_TIMER_EN);
8529
8530 if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8531 (tsfLow >> 10)) {
8532 break;
8533 }
8534 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8535 "%s: TSF have moved while trying to set "
8536 "quiet time TSF: 0x%08x\n",
8537 __func__, tsfLow);
8538 }
8539
8540 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8541
8542 udelay(200);
8543 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8544
8545 wait = 1000;
8546
8547 while (ath9k_hw_numtxpending(ah, q)) {
8548 if ((--wait) == 0) {
8549 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8550 "%s: Failed to stop Tx DMA in 100 "
8551 "msec after killing last frame\n",
8552 __func__);
8553 break;
8554 }
8555 udelay(100);
8556 }
8557
8558 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8559 }
8560
8561 REG_WRITE(ah, AR_Q_TXD, 0);
8562 return wait != 0;
8563}
diff --git a/drivers/net/wireless/ath9k/hw.h b/drivers/net/wireless/ath9k/hw.h
new file mode 100644
index 000000000000..ae680f21ba7e
--- /dev/null
+++ b/drivers/net/wireless/ath9k/hw.h
@@ -0,0 +1,969 @@
1/*
2 * Copyright (c) 2008 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#ifndef HW_H
18#define HW_H
19
20#include <linux/if_ether.h>
21#include <linux/delay.h>
22
23struct ar5416_desc {
24 u32 ds_link;
25 u32 ds_data;
26 u32 ds_ctl0;
27 u32 ds_ctl1;
28 union {
29 struct {
30 u32 ctl2;
31 u32 ctl3;
32 u32 ctl4;
33 u32 ctl5;
34 u32 ctl6;
35 u32 ctl7;
36 u32 ctl8;
37 u32 ctl9;
38 u32 ctl10;
39 u32 ctl11;
40 u32 status0;
41 u32 status1;
42 u32 status2;
43 u32 status3;
44 u32 status4;
45 u32 status5;
46 u32 status6;
47 u32 status7;
48 u32 status8;
49 u32 status9;
50 } tx;
51 struct {
52 u32 status0;
53 u32 status1;
54 u32 status2;
55 u32 status3;
56 u32 status4;
57 u32 status5;
58 u32 status6;
59 u32 status7;
60 u32 status8;
61 } rx;
62 } u;
63} __packed;
64
65#define AR5416DESC(_ds) ((struct ar5416_desc *)(_ds))
66#define AR5416DESC_CONST(_ds) ((const struct ar5416_desc *)(_ds))
67
68#define ds_ctl2 u.tx.ctl2
69#define ds_ctl3 u.tx.ctl3
70#define ds_ctl4 u.tx.ctl4
71#define ds_ctl5 u.tx.ctl5
72#define ds_ctl6 u.tx.ctl6
73#define ds_ctl7 u.tx.ctl7
74#define ds_ctl8 u.tx.ctl8
75#define ds_ctl9 u.tx.ctl9
76#define ds_ctl10 u.tx.ctl10
77#define ds_ctl11 u.tx.ctl11
78
79#define ds_txstatus0 u.tx.status0
80#define ds_txstatus1 u.tx.status1
81#define ds_txstatus2 u.tx.status2
82#define ds_txstatus3 u.tx.status3
83#define ds_txstatus4 u.tx.status4
84#define ds_txstatus5 u.tx.status5
85#define ds_txstatus6 u.tx.status6
86#define ds_txstatus7 u.tx.status7
87#define ds_txstatus8 u.tx.status8
88#define ds_txstatus9 u.tx.status9
89
90#define ds_rxstatus0 u.rx.status0
91#define ds_rxstatus1 u.rx.status1
92#define ds_rxstatus2 u.rx.status2
93#define ds_rxstatus3 u.rx.status3
94#define ds_rxstatus4 u.rx.status4
95#define ds_rxstatus5 u.rx.status5
96#define ds_rxstatus6 u.rx.status6
97#define ds_rxstatus7 u.rx.status7
98#define ds_rxstatus8 u.rx.status8
99
100#define AR_FrameLen 0x00000fff
101#define AR_VirtMoreFrag 0x00001000
102#define AR_TxCtlRsvd00 0x0000e000
103#define AR_XmitPower 0x003f0000
104#define AR_XmitPower_S 16
105#define AR_RTSEnable 0x00400000
106#define AR_VEOL 0x00800000
107#define AR_ClrDestMask 0x01000000
108#define AR_TxCtlRsvd01 0x1e000000
109#define AR_TxIntrReq 0x20000000
110#define AR_DestIdxValid 0x40000000
111#define AR_CTSEnable 0x80000000
112
113#define AR_BufLen 0x00000fff
114#define AR_TxMore 0x00001000
115#define AR_DestIdx 0x000fe000
116#define AR_DestIdx_S 13
117#define AR_FrameType 0x00f00000
118#define AR_FrameType_S 20
119#define AR_NoAck 0x01000000
120#define AR_InsertTS 0x02000000
121#define AR_CorruptFCS 0x04000000
122#define AR_ExtOnly 0x08000000
123#define AR_ExtAndCtl 0x10000000
124#define AR_MoreAggr 0x20000000
125#define AR_IsAggr 0x40000000
126
127#define AR_BurstDur 0x00007fff
128#define AR_BurstDur_S 0
129#define AR_DurUpdateEna 0x00008000
130#define AR_XmitDataTries0 0x000f0000
131#define AR_XmitDataTries0_S 16
132#define AR_XmitDataTries1 0x00f00000
133#define AR_XmitDataTries1_S 20
134#define AR_XmitDataTries2 0x0f000000
135#define AR_XmitDataTries2_S 24
136#define AR_XmitDataTries3 0xf0000000
137#define AR_XmitDataTries3_S 28
138
139#define AR_XmitRate0 0x000000ff
140#define AR_XmitRate0_S 0
141#define AR_XmitRate1 0x0000ff00
142#define AR_XmitRate1_S 8
143#define AR_XmitRate2 0x00ff0000
144#define AR_XmitRate2_S 16
145#define AR_XmitRate3 0xff000000
146#define AR_XmitRate3_S 24
147
148#define AR_PacketDur0 0x00007fff
149#define AR_PacketDur0_S 0
150#define AR_RTSCTSQual0 0x00008000
151#define AR_PacketDur1 0x7fff0000
152#define AR_PacketDur1_S 16
153#define AR_RTSCTSQual1 0x80000000
154
155#define AR_PacketDur2 0x00007fff
156#define AR_PacketDur2_S 0
157#define AR_RTSCTSQual2 0x00008000
158#define AR_PacketDur3 0x7fff0000
159#define AR_PacketDur3_S 16
160#define AR_RTSCTSQual3 0x80000000
161
162#define AR_AggrLen 0x0000ffff
163#define AR_AggrLen_S 0
164#define AR_TxCtlRsvd60 0x00030000
165#define AR_PadDelim 0x03fc0000
166#define AR_PadDelim_S 18
167#define AR_EncrType 0x0c000000
168#define AR_EncrType_S 26
169#define AR_TxCtlRsvd61 0xf0000000
170
171#define AR_2040_0 0x00000001
172#define AR_GI0 0x00000002
173#define AR_ChainSel0 0x0000001c
174#define AR_ChainSel0_S 2
175#define AR_2040_1 0x00000020
176#define AR_GI1 0x00000040
177#define AR_ChainSel1 0x00000380
178#define AR_ChainSel1_S 7
179#define AR_2040_2 0x00000400
180#define AR_GI2 0x00000800
181#define AR_ChainSel2 0x00007000
182#define AR_ChainSel2_S 12
183#define AR_2040_3 0x00008000
184#define AR_GI3 0x00010000
185#define AR_ChainSel3 0x000e0000
186#define AR_ChainSel3_S 17
187#define AR_RTSCTSRate 0x0ff00000
188#define AR_RTSCTSRate_S 20
189#define AR_TxCtlRsvd70 0xf0000000
190
191#define AR_TxRSSIAnt00 0x000000ff
192#define AR_TxRSSIAnt00_S 0
193#define AR_TxRSSIAnt01 0x0000ff00
194#define AR_TxRSSIAnt01_S 8
195#define AR_TxRSSIAnt02 0x00ff0000
196#define AR_TxRSSIAnt02_S 16
197#define AR_TxStatusRsvd00 0x3f000000
198#define AR_TxBaStatus 0x40000000
199#define AR_TxStatusRsvd01 0x80000000
200
201#define AR_FrmXmitOK 0x00000001
202#define AR_ExcessiveRetries 0x00000002
203#define AR_FIFOUnderrun 0x00000004
204#define AR_Filtered 0x00000008
205#define AR_RTSFailCnt 0x000000f0
206#define AR_RTSFailCnt_S 4
207#define AR_DataFailCnt 0x00000f00
208#define AR_DataFailCnt_S 8
209#define AR_VirtRetryCnt 0x0000f000
210#define AR_VirtRetryCnt_S 12
211#define AR_TxDelimUnderrun 0x00010000
212#define AR_TxDataUnderrun 0x00020000
213#define AR_DescCfgErr 0x00040000
214#define AR_TxTimerExpired 0x00080000
215#define AR_TxStatusRsvd10 0xfff00000
216
217#define AR_SendTimestamp ds_txstatus2
218#define AR_BaBitmapLow ds_txstatus3
219#define AR_BaBitmapHigh ds_txstatus4
220
221#define AR_TxRSSIAnt10 0x000000ff
222#define AR_TxRSSIAnt10_S 0
223#define AR_TxRSSIAnt11 0x0000ff00
224#define AR_TxRSSIAnt11_S 8
225#define AR_TxRSSIAnt12 0x00ff0000
226#define AR_TxRSSIAnt12_S 16
227#define AR_TxRSSICombined 0xff000000
228#define AR_TxRSSICombined_S 24
229
230#define AR_TxEVM0 ds_txstatus5
231#define AR_TxEVM1 ds_txstatus6
232#define AR_TxEVM2 ds_txstatus7
233
234#define AR_TxDone 0x00000001
235#define AR_SeqNum 0x00001ffe
236#define AR_SeqNum_S 1
237#define AR_TxStatusRsvd80 0x0001e000
238#define AR_TxOpExceeded 0x00020000
239#define AR_TxStatusRsvd81 0x001c0000
240#define AR_FinalTxIdx 0x00600000
241#define AR_FinalTxIdx_S 21
242#define AR_TxStatusRsvd82 0x01800000
243#define AR_PowerMgmt 0x02000000
244#define AR_TxStatusRsvd83 0xfc000000
245
246#define AR_RxCTLRsvd00 0xffffffff
247
248#define AR_BufLen 0x00000fff
249#define AR_RxCtlRsvd00 0x00001000
250#define AR_RxIntrReq 0x00002000
251#define AR_RxCtlRsvd01 0xffffc000
252
253#define AR_RxRSSIAnt00 0x000000ff
254#define AR_RxRSSIAnt00_S 0
255#define AR_RxRSSIAnt01 0x0000ff00
256#define AR_RxRSSIAnt01_S 8
257#define AR_RxRSSIAnt02 0x00ff0000
258#define AR_RxRSSIAnt02_S 16
259#define AR_RxRate 0xff000000
260#define AR_RxRate_S 24
261#define AR_RxStatusRsvd00 0xff000000
262
263#define AR_DataLen 0x00000fff
264#define AR_RxMore 0x00001000
265#define AR_NumDelim 0x003fc000
266#define AR_NumDelim_S 14
267#define AR_RxStatusRsvd10 0xff800000
268
269#define AR_RcvTimestamp ds_rxstatus2
270
271#define AR_GI 0x00000001
272#define AR_2040 0x00000002
273#define AR_Parallel40 0x00000004
274#define AR_Parallel40_S 2
275#define AR_RxStatusRsvd30 0x000000f8
276#define AR_RxAntenna 0xffffff00
277#define AR_RxAntenna_S 8
278
279#define AR_RxRSSIAnt10 0x000000ff
280#define AR_RxRSSIAnt10_S 0
281#define AR_RxRSSIAnt11 0x0000ff00
282#define AR_RxRSSIAnt11_S 8
283#define AR_RxRSSIAnt12 0x00ff0000
284#define AR_RxRSSIAnt12_S 16
285#define AR_RxRSSICombined 0xff000000
286#define AR_RxRSSICombined_S 24
287
288#define AR_RxEVM0 ds_rxstatus4
289#define AR_RxEVM1 ds_rxstatus5
290#define AR_RxEVM2 ds_rxstatus6
291
292#define AR_RxDone 0x00000001
293#define AR_RxFrameOK 0x00000002
294#define AR_CRCErr 0x00000004
295#define AR_DecryptCRCErr 0x00000008
296#define AR_PHYErr 0x00000010
297#define AR_MichaelErr 0x00000020
298#define AR_PreDelimCRCErr 0x00000040
299#define AR_RxStatusRsvd70 0x00000080
300#define AR_RxKeyIdxValid 0x00000100
301#define AR_KeyIdx 0x0000fe00
302#define AR_KeyIdx_S 9
303#define AR_PHYErrCode 0x0000ff00
304#define AR_PHYErrCode_S 8
305#define AR_RxMoreAggr 0x00010000
306#define AR_RxAggr 0x00020000
307#define AR_PostDelimCRCErr 0x00040000
308#define AR_RxStatusRsvd71 0x3ff80000
309#define AR_DecryptBusyErr 0x40000000
310#define AR_KeyMiss 0x80000000
311
312#define AR5416_MAGIC 0x19641014
313
314#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
315 MS(ads->ds_rxstatus0, AR_RxRate) : \
316 (ads->ds_rxstatus3 >> 2) & 0xFF)
317#define RXSTATUS_DUPLICATE(ah, ads) (AR_SREV_5416_V20_OR_LATER(ah) ? \
318 MS(ads->ds_rxstatus3, AR_Parallel40) : \
319 (ads->ds_rxstatus3 >> 10) & 0x1)
320
321#define set11nTries(_series, _index) \
322 (SM((_series)[_index].Tries, AR_XmitDataTries##_index))
323
324#define set11nRate(_series, _index) \
325 (SM((_series)[_index].Rate, AR_XmitRate##_index))
326
327#define set11nPktDurRTSCTS(_series, _index) \
328 (SM((_series)[_index].PktDuration, AR_PacketDur##_index) | \
329 ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS ? \
330 AR_RTSCTSQual##_index : 0))
331
332#define set11nRateFlags(_series, _index) \
333 (((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ? \
334 AR_2040_##_index : 0) \
335 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ? \
336 AR_GI##_index : 0) \
337 |SM((_series)[_index].ChSel, AR_ChainSel##_index))
338
339#define AR_SREV_9100(ah) ((ah->ah_macVersion) == AR_SREV_VERSION_9100)
340
341#define INIT_CONFIG_STATUS 0x00000000
342#define INIT_RSSI_THR 0x00000700
343#define INIT_BCON_CNTRL_REG 0x00000000
344
345#define MIN_TX_FIFO_THRESHOLD 0x1
346#define MAX_TX_FIFO_THRESHOLD ((4096 / 64) - 1)
347#define INIT_TX_FIFO_THRESHOLD MIN_TX_FIFO_THRESHOLD
348
349#define NUM_CORNER_FIX_BITS_2133 7
350#define CCK_OFDM_GAIN_DELTA 15
351
352struct ar5416AniState {
353 struct ath9k_channel c;
354 u8 noiseImmunityLevel;
355 u8 spurImmunityLevel;
356 u8 firstepLevel;
357 u8 ofdmWeakSigDetectOff;
358 u8 cckWeakSigThreshold;
359 u32 listenTime;
360 u32 ofdmTrigHigh;
361 u32 ofdmTrigLow;
362 int32_t cckTrigHigh;
363 int32_t cckTrigLow;
364 int32_t rssiThrLow;
365 int32_t rssiThrHigh;
366 u32 noiseFloor;
367 u32 txFrameCount;
368 u32 rxFrameCount;
369 u32 cycleCount;
370 u32 ofdmPhyErrCount;
371 u32 cckPhyErrCount;
372 u32 ofdmPhyErrBase;
373 u32 cckPhyErrBase;
374 int16_t pktRssi[2];
375 int16_t ofdmErrRssi[2];
376 int16_t cckErrRssi[2];
377};
378
379#define HAL_PROCESS_ANI 0x00000001
380#define HAL_RADAR_EN 0x80000000
381#define HAL_AR_EN 0x40000000
382
383#define DO_ANI(ah) \
384 ((AH5416(ah)->ah_procPhyErr & HAL_PROCESS_ANI))
385
386struct ar5416Stats {
387 u32 ast_ani_niup;
388 u32 ast_ani_nidown;
389 u32 ast_ani_spurup;
390 u32 ast_ani_spurdown;
391 u32 ast_ani_ofdmon;
392 u32 ast_ani_ofdmoff;
393 u32 ast_ani_cckhigh;
394 u32 ast_ani_ccklow;
395 u32 ast_ani_stepup;
396 u32 ast_ani_stepdown;
397 u32 ast_ani_ofdmerrs;
398 u32 ast_ani_cckerrs;
399 u32 ast_ani_reset;
400 u32 ast_ani_lzero;
401 u32 ast_ani_lneg;
402 struct ath9k_mib_stats ast_mibstats;
403 struct ath9k_node_stats ast_nodestats;
404};
405
406#define AR5416_OPFLAGS_11A 0x01
407#define AR5416_OPFLAGS_11G 0x02
408#define AR5416_OPFLAGS_N_5G_HT40 0x04
409#define AR5416_OPFLAGS_N_2G_HT40 0x08
410#define AR5416_OPFLAGS_N_5G_HT20 0x10
411#define AR5416_OPFLAGS_N_2G_HT20 0x20
412
413#define EEP_RFSILENT_ENABLED 0x0001
414#define EEP_RFSILENT_ENABLED_S 0
415#define EEP_RFSILENT_POLARITY 0x0002
416#define EEP_RFSILENT_POLARITY_S 1
417#define EEP_RFSILENT_GPIO_SEL 0x001c
418#define EEP_RFSILENT_GPIO_SEL_S 2
419
420#define AR5416_EEP_NO_BACK_VER 0x1
421#define AR5416_EEP_VER 0xE
422#define AR5416_EEP_VER_MINOR_MASK 0x0FFF
423#define AR5416_EEP_MINOR_VER_2 0x2
424#define AR5416_EEP_MINOR_VER_3 0x3
425#define AR5416_EEP_MINOR_VER_7 0x7
426#define AR5416_EEP_MINOR_VER_9 0x9
427
428#define AR5416_EEP_START_LOC 256
429#define AR5416_NUM_5G_CAL_PIERS 8
430#define AR5416_NUM_2G_CAL_PIERS 4
431#define AR5416_NUM_5G_20_TARGET_POWERS 8
432#define AR5416_NUM_5G_40_TARGET_POWERS 8
433#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
434#define AR5416_NUM_2G_20_TARGET_POWERS 4
435#define AR5416_NUM_2G_40_TARGET_POWERS 4
436#define AR5416_NUM_CTLS 24
437#define AR5416_NUM_BAND_EDGES 8
438#define AR5416_NUM_PD_GAINS 4
439#define AR5416_PD_GAINS_IN_MASK 4
440#define AR5416_PD_GAIN_ICEPTS 5
441#define AR5416_EEPROM_MODAL_SPURS 5
442#define AR5416_MAX_RATE_POWER 63
443#define AR5416_NUM_PDADC_VALUES 128
444#define AR5416_NUM_RATES 16
445#define AR5416_BCHAN_UNUSED 0xFF
446#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
447#define AR5416_EEPMISC_BIG_ENDIAN 0x01
448#define AR5416_MAX_CHAINS 3
449#define AR5416_ANT_16S 25
450
451#define AR5416_NUM_ANT_CHAIN_FIELDS 7
452#define AR5416_NUM_ANT_COMMON_FIELDS 4
453#define AR5416_SIZE_ANT_CHAIN_FIELD 3
454#define AR5416_SIZE_ANT_COMMON_FIELD 4
455#define AR5416_ANT_CHAIN_MASK 0x7
456#define AR5416_ANT_COMMON_MASK 0xf
457#define AR5416_CHAIN_0_IDX 0
458#define AR5416_CHAIN_1_IDX 1
459#define AR5416_CHAIN_2_IDX 2
460
461#define AR5416_PWR_TABLE_OFFSET -5
462#define AR5416_LEGACY_CHAINMASK 1
463
464enum eeprom_param {
465 EEP_NFTHRESH_5,
466 EEP_NFTHRESH_2,
467 EEP_MAC_MSW,
468 EEP_MAC_MID,
469 EEP_MAC_LSW,
470 EEP_REG_0,
471 EEP_REG_1,
472 EEP_OP_CAP,
473 EEP_OP_MODE,
474 EEP_RF_SILENT,
475 EEP_OB_5,
476 EEP_DB_5,
477 EEP_OB_2,
478 EEP_DB_2,
479 EEP_MINOR_REV,
480 EEP_TX_MASK,
481 EEP_RX_MASK,
482};
483
484enum ar5416_rates {
485 rate6mb, rate9mb, rate12mb, rate18mb,
486 rate24mb, rate36mb, rate48mb, rate54mb,
487 rate1l, rate2l, rate2s, rate5_5l,
488 rate5_5s, rate11l, rate11s, rateXr,
489 rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
490 rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
491 rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
492 rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
493 rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
494 Ar5416RateSize
495};
496
497struct base_eep_header {
498 u16 length;
499 u16 checksum;
500 u16 version;
501 u8 opCapFlags;
502 u8 eepMisc;
503 u16 regDmn[2];
504 u8 macAddr[6];
505 u8 rxMask;
506 u8 txMask;
507 u16 rfSilent;
508 u16 blueToothOptions;
509 u16 deviceCap;
510 u32 binBuildNumber;
511 u8 deviceType;
512 u8 pwdclkind;
513 u8 futureBase[32];
514} __packed;
515
516struct spur_chan {
517 u16 spurChan;
518 u8 spurRangeLow;
519 u8 spurRangeHigh;
520} __packed;
521
522struct modal_eep_header {
523 u32 antCtrlChain[AR5416_MAX_CHAINS];
524 u32 antCtrlCommon;
525 u8 antennaGainCh[AR5416_MAX_CHAINS];
526 u8 switchSettling;
527 u8 txRxAttenCh[AR5416_MAX_CHAINS];
528 u8 rxTxMarginCh[AR5416_MAX_CHAINS];
529 u8 adcDesiredSize;
530 u8 pgaDesiredSize;
531 u8 xlnaGainCh[AR5416_MAX_CHAINS];
532 u8 txEndToXpaOff;
533 u8 txEndToRxOn;
534 u8 txFrameToXpaOn;
535 u8 thresh62;
536 u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
537 u8 xpdGain;
538 u8 xpd;
539 u8 iqCalICh[AR5416_MAX_CHAINS];
540 u8 iqCalQCh[AR5416_MAX_CHAINS];
541 u8 pdGainOverlap;
542 u8 ob;
543 u8 db;
544 u8 xpaBiasLvl;
545 u8 pwrDecreaseFor2Chain;
546 u8 pwrDecreaseFor3Chain;
547 u8 txFrameToDataStart;
548 u8 txFrameToPaOn;
549 u8 ht40PowerIncForPdadc;
550 u8 bswAtten[AR5416_MAX_CHAINS];
551 u8 bswMargin[AR5416_MAX_CHAINS];
552 u8 swSettleHt40;
553 u8 xatten2Db[AR5416_MAX_CHAINS];
554 u8 xatten2Margin[AR5416_MAX_CHAINS];
555 u8 ob_ch1;
556 u8 db_ch1;
557 u8 useAnt1:1,
558 force_xpaon:1,
559 local_bias:1,
560 femBandSelectUsed:1, xlnabufin:1, xlnaisel:2, xlnabufmode:1;
561 u8 futureModalar9280;
562 u16 xpaBiasLvlFreq[3];
563 u8 futureModal[6];
564
565 struct spur_chan spurChans[AR5416_EEPROM_MODAL_SPURS];
566} __packed;
567
568struct cal_data_per_freq {
569 u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
570 u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
571} __packed;
572
573struct cal_target_power_leg {
574 u8 bChannel;
575 u8 tPow2x[4];
576} __packed;
577
578struct cal_target_power_ht {
579 u8 bChannel;
580 u8 tPow2x[8];
581} __packed;
582
583#ifdef __BIG_ENDIAN_BITFIELD
584struct cal_ctl_edges {
585 u8 bChannel;
586 u8 flag:2, tPower:6;
587} __packed;
588#else
589struct cal_ctl_edges {
590 u8 bChannel;
591 u8 tPower:6, flag:2;
592} __packed;
593#endif
594
595struct cal_ctl_data {
596 struct cal_ctl_edges
597 ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
598} __packed;
599
600struct ar5416_eeprom {
601 struct base_eep_header baseEepHeader;
602 u8 custData[64];
603 struct modal_eep_header modalHeader[2];
604 u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
605 u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
606 struct cal_data_per_freq
607 calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
608 struct cal_data_per_freq
609 calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
610 struct cal_target_power_leg
611 calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
612 struct cal_target_power_ht
613 calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
614 struct cal_target_power_ht
615 calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
616 struct cal_target_power_leg
617 calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
618 struct cal_target_power_leg
619 calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
620 struct cal_target_power_ht
621 calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
622 struct cal_target_power_ht
623 calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
624 u8 ctlIndex[AR5416_NUM_CTLS];
625 struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
626 u8 padding;
627} __packed;
628
629struct ar5416IniArray {
630 u32 *ia_array;
631 u32 ia_rows;
632 u32 ia_columns;
633};
634
635#define INIT_INI_ARRAY(iniarray, array, rows, columns) do { \
636 (iniarray)->ia_array = (u32 *)(array); \
637 (iniarray)->ia_rows = (rows); \
638 (iniarray)->ia_columns = (columns); \
639 } while (0)
640
641#define INI_RA(iniarray, row, column) \
642 (((iniarray)->ia_array)[(row) * ((iniarray)->ia_columns) + (column)])
643
644#define INIT_CAL(_perCal) do { \
645 (_perCal)->calState = CAL_WAITING; \
646 (_perCal)->calNext = NULL; \
647 } while (0)
648
649#define INSERT_CAL(_ahp, _perCal) \
650 do { \
651 if ((_ahp)->ah_cal_list_last == NULL) { \
652 (_ahp)->ah_cal_list = \
653 (_ahp)->ah_cal_list_last = (_perCal); \
654 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
655 } else { \
656 ((_ahp)->ah_cal_list_last)->calNext = (_perCal); \
657 (_ahp)->ah_cal_list_last = (_perCal); \
658 (_perCal)->calNext = (_ahp)->ah_cal_list; \
659 } \
660 } while (0)
661
662enum hal_cal_types {
663 ADC_DC_INIT_CAL = 0x1,
664 ADC_GAIN_CAL = 0x2,
665 ADC_DC_CAL = 0x4,
666 IQ_MISMATCH_CAL = 0x8
667};
668
669enum hal_cal_state {
670 CAL_INACTIVE,
671 CAL_WAITING,
672 CAL_RUNNING,
673 CAL_DONE
674};
675
676#define MIN_CAL_SAMPLES 1
677#define MAX_CAL_SAMPLES 64
678#define INIT_LOG_COUNT 5
679#define PER_MIN_LOG_COUNT 2
680#define PER_MAX_LOG_COUNT 10
681
682struct hal_percal_data {
683 enum hal_cal_types calType;
684 u32 calNumSamples;
685 u32 calCountMax;
686 void (*calCollect) (struct ath_hal *);
687 void (*calPostProc) (struct ath_hal *, u8);
688};
689
690struct hal_cal_list {
691 const struct hal_percal_data *calData;
692 enum hal_cal_state calState;
693 struct hal_cal_list *calNext;
694};
695
696struct ath_hal_5416 {
697 struct ath_hal ah;
698 struct ar5416_eeprom ah_eeprom;
699 u8 ah_macaddr[ETH_ALEN];
700 u8 ah_bssid[ETH_ALEN];
701 u8 ah_bssidmask[ETH_ALEN];
702 u16 ah_assocId;
703 int16_t ah_curchanRadIndex;
704 u32 ah_maskReg;
705 struct ar5416Stats ah_stats;
706 u32 ah_txDescMask;
707 u32 ah_txOkInterruptMask;
708 u32 ah_txErrInterruptMask;
709 u32 ah_txDescInterruptMask;
710 u32 ah_txEolInterruptMask;
711 u32 ah_txUrnInterruptMask;
712 struct ath9k_tx_queue_info ah_txq[ATH9K_NUM_TX_QUEUES];
713 enum ath9k_power_mode ah_powerMode;
714 bool ah_chipFullSleep;
715 u32 ah_atimWindow;
716 enum ath9k_ant_setting ah_diversityControl;
717 u16 ah_antennaSwitchSwap;
718 enum hal_cal_types ah_suppCals;
719 struct hal_cal_list ah_iqCalData;
720 struct hal_cal_list ah_adcGainCalData;
721 struct hal_cal_list ah_adcDcCalInitData;
722 struct hal_cal_list ah_adcDcCalData;
723 struct hal_cal_list *ah_cal_list;
724 struct hal_cal_list *ah_cal_list_last;
725 struct hal_cal_list *ah_cal_list_curr;
726#define ah_totalPowerMeasI ah_Meas0.unsign
727#define ah_totalPowerMeasQ ah_Meas1.unsign
728#define ah_totalIqCorrMeas ah_Meas2.sign
729#define ah_totalAdcIOddPhase ah_Meas0.unsign
730#define ah_totalAdcIEvenPhase ah_Meas1.unsign
731#define ah_totalAdcQOddPhase ah_Meas2.unsign
732#define ah_totalAdcQEvenPhase ah_Meas3.unsign
733#define ah_totalAdcDcOffsetIOddPhase ah_Meas0.sign
734#define ah_totalAdcDcOffsetIEvenPhase ah_Meas1.sign
735#define ah_totalAdcDcOffsetQOddPhase ah_Meas2.sign
736#define ah_totalAdcDcOffsetQEvenPhase ah_Meas3.sign
737 union {
738 u32 unsign[AR5416_MAX_CHAINS];
739 int32_t sign[AR5416_MAX_CHAINS];
740 } ah_Meas0;
741 union {
742 u32 unsign[AR5416_MAX_CHAINS];
743 int32_t sign[AR5416_MAX_CHAINS];
744 } ah_Meas1;
745 union {
746 u32 unsign[AR5416_MAX_CHAINS];
747 int32_t sign[AR5416_MAX_CHAINS];
748 } ah_Meas2;
749 union {
750 u32 unsign[AR5416_MAX_CHAINS];
751 int32_t sign[AR5416_MAX_CHAINS];
752 } ah_Meas3;
753 u16 ah_CalSamples;
754 u32 ah_tx6PowerInHalfDbm;
755 u32 ah_staId1Defaults;
756 u32 ah_miscMode;
757 bool ah_tpcEnabled;
758 u32 ah_beaconInterval;
759 enum {
760 AUTO_32KHZ,
761 USE_32KHZ,
762 DONT_USE_32KHZ,
763 } ah_enable32kHzClock;
764 u32 *ah_analogBank0Data;
765 u32 *ah_analogBank1Data;
766 u32 *ah_analogBank2Data;
767 u32 *ah_analogBank3Data;
768 u32 *ah_analogBank6Data;
769 u32 *ah_analogBank6TPCData;
770 u32 *ah_analogBank7Data;
771 u32 *ah_addac5416_21;
772 u32 *ah_bank6Temp;
773 u32 ah_ofdmTxPower;
774 int16_t ah_txPowerIndexOffset;
775 u32 ah_slottime;
776 u32 ah_acktimeout;
777 u32 ah_ctstimeout;
778 u32 ah_globaltxtimeout;
779 u8 ah_gBeaconRate;
780 u32 ah_gpioSelect;
781 u32 ah_polarity;
782 u32 ah_gpioBit;
783 bool ah_eepEnabled;
784 u32 ah_procPhyErr;
785 bool ah_hasHwPhyCounters;
786 u32 ah_aniPeriod;
787 struct ar5416AniState *ah_curani;
788 struct ar5416AniState ah_ani[255];
789 int ah_totalSizeDesired[5];
790 int ah_coarseHigh[5];
791 int ah_coarseLow[5];
792 int ah_firpwr[5];
793 u16 ah_ratesArray[16];
794 u32 ah_intrTxqs;
795 bool ah_intrMitigation;
796 u32 ah_cycleCount;
797 u32 ah_ctlBusy;
798 u32 ah_extBusy;
799 enum ath9k_ht_extprotspacing ah_extprotspacing;
800 u8 ah_txchainmask;
801 u8 ah_rxchainmask;
802 int ah_hwp;
803 void __iomem *ah_cal_mem;
804 enum ath9k_ani_cmd ah_ani_function;
805 struct ar5416IniArray ah_iniModes;
806 struct ar5416IniArray ah_iniCommon;
807 struct ar5416IniArray ah_iniBank0;
808 struct ar5416IniArray ah_iniBB_RfGain;
809 struct ar5416IniArray ah_iniBank1;
810 struct ar5416IniArray ah_iniBank2;
811 struct ar5416IniArray ah_iniBank3;
812 struct ar5416IniArray ah_iniBank6;
813 struct ar5416IniArray ah_iniBank6TPC;
814 struct ar5416IniArray ah_iniBank7;
815 struct ar5416IniArray ah_iniAddac;
816 struct ar5416IniArray ah_iniPcieSerdes;
817 struct ar5416IniArray ah_iniModesAdditional;
818};
819#define AH5416(_ah) ((struct ath_hal_5416 *)(_ah))
820
821#define FREQ2FBIN(x, y) ((y) ? ((x) - 2300) : (((x) - 4800) / 5))
822
823#define IS_5416_EMU(ah) \
824 ((ah->ah_devid == AR5416_DEVID_EMU) || \
825 (ah->ah_devid == AR5416_DEVID_EMU_PCIE))
826
827#define ar5416RfDetach(ah) do { \
828 if (AH5416(ah)->ah_rfHal.rfDetach != NULL) \
829 AH5416(ah)->ah_rfHal.rfDetach(ah); \
830 } while (0)
831
832#define ath9k_hw_use_flash(_ah) \
833 (!(_ah->ah_flags & AH_USE_EEPROM))
834
835
836#define DO_DELAY(x) do { \
837 if ((++(x) % 64) == 0) \
838 udelay(1); \
839 } while (0)
840
841#define REG_WRITE_ARRAY(iniarray, column, regWr) do { \
842 int r; \
843 for (r = 0; r < ((iniarray)->ia_rows); r++) { \
844 REG_WRITE(ah, INI_RA((iniarray), (r), 0), \
845 INI_RA((iniarray), r, (column))); \
846 DO_DELAY(regWr); \
847 } \
848 } while (0)
849
850#define BASE_ACTIVATE_DELAY 100
851#define RTC_PLL_SETTLE_DELAY 1000
852#define COEF_SCALE_S 24
853#define HT40_CHANNEL_CENTER_SHIFT 10
854
855#define ar5416CheckOpMode(_opmode) \
856 ((_opmode == ATH9K_M_STA) || (_opmode == ATH9K_M_IBSS) || \
857 (_opmode == ATH9K_M_HOSTAP) || (_opmode == ATH9K_M_MONITOR))
858
859#define AR5416_EEPROM_MAGIC_OFFSET 0x0
860
861#define AR5416_EEPROM_S 2
862#define AR5416_EEPROM_OFFSET 0x2000
863#define AR5416_EEPROM_START_ADDR \
864 (AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
865#define AR5416_EEPROM_MAX 0xae0
866#define ar5416_get_eep_ver(_ahp) \
867 (((_ahp)->ah_eeprom.baseEepHeader.version >> 12) & 0xF)
868#define ar5416_get_eep_rev(_ahp) \
869 (((_ahp)->ah_eeprom.baseEepHeader.version) & 0xFFF)
870#define ar5416_get_ntxchains(_txchainmask) \
871 (((_txchainmask >> 2) & 1) + \
872 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
873
874#define IS_EEP_MINOR_V3(_ahp) \
875 (ath9k_hw_get_eeprom((_ahp), EEP_MINOR_REV) >= AR5416_EEP_MINOR_VER_3)
876
877#define FIXED_CCA_THRESHOLD 15
878
879#ifdef __BIG_ENDIAN
880#define AR5416_EEPROM_MAGIC 0x5aa5
881#else
882#define AR5416_EEPROM_MAGIC 0xa55a
883#endif
884
885#define ATH9K_POW_SM(_r, _s) (((_r) & 0x3f) << (_s))
886
887#define ATH9K_ANTENNA0_CHAINMASK 0x1
888#define ATH9K_ANTENNA1_CHAINMASK 0x2
889
890#define ATH9K_NUM_DMA_DEBUG_REGS 8
891#define ATH9K_NUM_QUEUES 10
892
893#define HAL_NOISE_IMMUNE_MAX 4
894#define HAL_SPUR_IMMUNE_MAX 7
895#define HAL_FIRST_STEP_MAX 2
896
897#define ATH9K_ANI_OFDM_TRIG_HIGH 500
898#define ATH9K_ANI_OFDM_TRIG_LOW 200
899#define ATH9K_ANI_CCK_TRIG_HIGH 200
900#define ATH9K_ANI_CCK_TRIG_LOW 100
901#define ATH9K_ANI_NOISE_IMMUNE_LVL 4
902#define ATH9K_ANI_USE_OFDM_WEAK_SIG true
903#define ATH9K_ANI_CCK_WEAK_SIG_THR false
904#define ATH9K_ANI_SPUR_IMMUNE_LVL 7
905#define ATH9K_ANI_FIRSTEP_LVL 0
906#define ATH9K_ANI_RSSI_THR_HIGH 40
907#define ATH9K_ANI_RSSI_THR_LOW 7
908#define ATH9K_ANI_PERIOD 100
909
910#define AR_GPIOD_MASK 0x00001FFF
911#define AR_GPIO_BIT(_gpio) (1 << (_gpio))
912
913#define MAX_ANALOG_START 319
914
915#define HAL_EP_RND(x, mul) \
916 ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
917#define BEACON_RSSI(ahp) \
918 HAL_EP_RND(ahp->ah_stats.ast_nodestats.ns_avgbrssi, \
919 ATH9K_RSSI_EP_MULTIPLIER)
920
921#define ah_mibStats ah_stats.ast_mibstats
922
923#define AH_TIMEOUT 100000
924#define AH_TIME_QUANTUM 10
925
926#define IS(_c, _f) (((_c)->channelFlags & _f) || 0)
927
928#define AR_KEYTABLE_SIZE 128
929#define POWER_UP_TIME 200000
930
931#define EXT_ADDITIVE (0x8000)
932#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
933#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
934#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
935
936#define SUB_NUM_CTL_MODES_AT_5G_40 2
937#define SUB_NUM_CTL_MODES_AT_2G_40 3
938#define SPUR_RSSI_THRESH 40
939
940#define TU_TO_USEC(_tu) ((_tu) << 10)
941
942#define CAB_TIMEOUT_VAL 10
943#define BEACON_TIMEOUT_VAL 10
944#define MIN_BEACON_TIMEOUT_VAL 1
945#define SLEEP_SLOP 3
946
947#define CCK_SIFS_TIME 10
948#define CCK_PREAMBLE_BITS 144
949#define CCK_PLCP_BITS 48
950
951#define OFDM_SIFS_TIME 16
952#define OFDM_PREAMBLE_TIME 20
953#define OFDM_PLCP_BITS 22
954#define OFDM_SYMBOL_TIME 4
955
956#define OFDM_SIFS_TIME_HALF 32
957#define OFDM_PREAMBLE_TIME_HALF 40
958#define OFDM_PLCP_BITS_HALF 22
959#define OFDM_SYMBOL_TIME_HALF 8
960
961#define OFDM_SIFS_TIME_QUARTER 64
962#define OFDM_PREAMBLE_TIME_QUARTER 80
963#define OFDM_PLCP_BITS_QUARTER 22
964#define OFDM_SYMBOL_TIME_QUARTER 16
965
966u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
967 enum eeprom_param param);
968
969#endif
diff --git a/drivers/net/wireless/ath9k/initvals.h b/drivers/net/wireless/ath9k/initvals.h
new file mode 100644
index 000000000000..3dd3815940a4
--- /dev/null
+++ b/drivers/net/wireless/ath9k/initvals.h
@@ -0,0 +1,3146 @@
1/*
2 * Copyright (c) 2008 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
17static const u32 ar5416Modes_9100[][6] = {
18 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
19 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
20 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
21 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
22 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
23 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
24 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
25 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
26 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
27 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
28 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
29 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
30 { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
31 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
32 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
33 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
34 { 0x00009850, 0x6de8b4e0, 0x6de8b4e0, 0x6de8b0de, 0x6de8b0de, 0x6de8b0de },
35 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
36 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
37 { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18 },
38 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
39 { 0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 },
40 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
41 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
42 { 0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134 },
43 { 0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b },
44 { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
45 { 0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
46 { 0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
47 { 0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80 },
48 { 0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120 },
49 { 0x0000c9bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00 },
50 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
51 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
52 { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
53 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
54 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
55 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
56 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
57 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
58 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
59 { 0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
60 { 0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
61 { 0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 },
62 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
63 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
64 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
65 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
66 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
67 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
68 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
69 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
70 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
71 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
72 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
73 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
74 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
75 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
76 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
77 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
78 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
79};
80
81static const u32 ar5416Common_9100[][2] = {
82 { 0x0000000c, 0x00000000 },
83 { 0x00000030, 0x00020015 },
84 { 0x00000034, 0x00000005 },
85 { 0x00000040, 0x00000000 },
86 { 0x00000044, 0x00000008 },
87 { 0x00000048, 0x00000008 },
88 { 0x0000004c, 0x00000010 },
89 { 0x00000050, 0x00000000 },
90 { 0x00000054, 0x0000001f },
91 { 0x00000800, 0x00000000 },
92 { 0x00000804, 0x00000000 },
93 { 0x00000808, 0x00000000 },
94 { 0x0000080c, 0x00000000 },
95 { 0x00000810, 0x00000000 },
96 { 0x00000814, 0x00000000 },
97 { 0x00000818, 0x00000000 },
98 { 0x0000081c, 0x00000000 },
99 { 0x00000820, 0x00000000 },
100 { 0x00000824, 0x00000000 },
101 { 0x00001040, 0x002ffc0f },
102 { 0x00001044, 0x002ffc0f },
103 { 0x00001048, 0x002ffc0f },
104 { 0x0000104c, 0x002ffc0f },
105 { 0x00001050, 0x002ffc0f },
106 { 0x00001054, 0x002ffc0f },
107 { 0x00001058, 0x002ffc0f },
108 { 0x0000105c, 0x002ffc0f },
109 { 0x00001060, 0x002ffc0f },
110 { 0x00001064, 0x002ffc0f },
111 { 0x00001230, 0x00000000 },
112 { 0x00001270, 0x00000000 },
113 { 0x00001038, 0x00000000 },
114 { 0x00001078, 0x00000000 },
115 { 0x000010b8, 0x00000000 },
116 { 0x000010f8, 0x00000000 },
117 { 0x00001138, 0x00000000 },
118 { 0x00001178, 0x00000000 },
119 { 0x000011b8, 0x00000000 },
120 { 0x000011f8, 0x00000000 },
121 { 0x00001238, 0x00000000 },
122 { 0x00001278, 0x00000000 },
123 { 0x000012b8, 0x00000000 },
124 { 0x000012f8, 0x00000000 },
125 { 0x00001338, 0x00000000 },
126 { 0x00001378, 0x00000000 },
127 { 0x000013b8, 0x00000000 },
128 { 0x000013f8, 0x00000000 },
129 { 0x00001438, 0x00000000 },
130 { 0x00001478, 0x00000000 },
131 { 0x000014b8, 0x00000000 },
132 { 0x000014f8, 0x00000000 },
133 { 0x00001538, 0x00000000 },
134 { 0x00001578, 0x00000000 },
135 { 0x000015b8, 0x00000000 },
136 { 0x000015f8, 0x00000000 },
137 { 0x00001638, 0x00000000 },
138 { 0x00001678, 0x00000000 },
139 { 0x000016b8, 0x00000000 },
140 { 0x000016f8, 0x00000000 },
141 { 0x00001738, 0x00000000 },
142 { 0x00001778, 0x00000000 },
143 { 0x000017b8, 0x00000000 },
144 { 0x000017f8, 0x00000000 },
145 { 0x0000103c, 0x00000000 },
146 { 0x0000107c, 0x00000000 },
147 { 0x000010bc, 0x00000000 },
148 { 0x000010fc, 0x00000000 },
149 { 0x0000113c, 0x00000000 },
150 { 0x0000117c, 0x00000000 },
151 { 0x000011bc, 0x00000000 },
152 { 0x000011fc, 0x00000000 },
153 { 0x0000123c, 0x00000000 },
154 { 0x0000127c, 0x00000000 },
155 { 0x000012bc, 0x00000000 },
156 { 0x000012fc, 0x00000000 },
157 { 0x0000133c, 0x00000000 },
158 { 0x0000137c, 0x00000000 },
159 { 0x000013bc, 0x00000000 },
160 { 0x000013fc, 0x00000000 },
161 { 0x0000143c, 0x00000000 },
162 { 0x0000147c, 0x00000000 },
163 { 0x00004030, 0x00000002 },
164 { 0x0000403c, 0x00000002 },
165 { 0x00007010, 0x00000000 },
166 { 0x00007038, 0x000004c2 },
167 { 0x00008004, 0x00000000 },
168 { 0x00008008, 0x00000000 },
169 { 0x0000800c, 0x00000000 },
170 { 0x00008018, 0x00000700 },
171 { 0x00008020, 0x00000000 },
172 { 0x00008038, 0x00000000 },
173 { 0x0000803c, 0x00000000 },
174 { 0x00008048, 0x40000000 },
175 { 0x00008054, 0x00000000 },
176 { 0x00008058, 0x00000000 },
177 { 0x0000805c, 0x000fc78f },
178 { 0x00008060, 0x0000000f },
179 { 0x00008064, 0x00000000 },
180 { 0x000080c0, 0x2a82301a },
181 { 0x000080c4, 0x05dc01e0 },
182 { 0x000080c8, 0x1f402710 },
183 { 0x000080cc, 0x01f40000 },
184 { 0x000080d0, 0x00001e00 },
185 { 0x000080d4, 0x00000000 },
186 { 0x000080d8, 0x00400000 },
187 { 0x000080e0, 0xffffffff },
188 { 0x000080e4, 0x0000ffff },
189 { 0x000080e8, 0x003f3f3f },
190 { 0x000080ec, 0x00000000 },
191 { 0x000080f0, 0x00000000 },
192 { 0x000080f4, 0x00000000 },
193 { 0x000080f8, 0x00000000 },
194 { 0x000080fc, 0x00020000 },
195 { 0x00008100, 0x00020000 },
196 { 0x00008104, 0x00000001 },
197 { 0x00008108, 0x00000052 },
198 { 0x0000810c, 0x00000000 },
199 { 0x00008110, 0x00000168 },
200 { 0x00008118, 0x000100aa },
201 { 0x0000811c, 0x00003210 },
202 { 0x00008120, 0x08f04800 },
203 { 0x00008124, 0x00000000 },
204 { 0x00008128, 0x00000000 },
205 { 0x0000812c, 0x00000000 },
206 { 0x00008130, 0x00000000 },
207 { 0x00008134, 0x00000000 },
208 { 0x00008138, 0x00000000 },
209 { 0x0000813c, 0x00000000 },
210 { 0x00008144, 0x00000000 },
211 { 0x00008168, 0x00000000 },
212 { 0x0000816c, 0x00000000 },
213 { 0x00008170, 0x32143320 },
214 { 0x00008174, 0xfaa4fa50 },
215 { 0x00008178, 0x00000100 },
216 { 0x0000817c, 0x00000000 },
217 { 0x000081c4, 0x00000000 },
218 { 0x000081d0, 0x00003210 },
219 { 0x000081ec, 0x00000000 },
220 { 0x000081f0, 0x00000000 },
221 { 0x000081f4, 0x00000000 },
222 { 0x000081f8, 0x00000000 },
223 { 0x000081fc, 0x00000000 },
224 { 0x00008200, 0x00000000 },
225 { 0x00008204, 0x00000000 },
226 { 0x00008208, 0x00000000 },
227 { 0x0000820c, 0x00000000 },
228 { 0x00008210, 0x00000000 },
229 { 0x00008214, 0x00000000 },
230 { 0x00008218, 0x00000000 },
231 { 0x0000821c, 0x00000000 },
232 { 0x00008220, 0x00000000 },
233 { 0x00008224, 0x00000000 },
234 { 0x00008228, 0x00000000 },
235 { 0x0000822c, 0x00000000 },
236 { 0x00008230, 0x00000000 },
237 { 0x00008234, 0x00000000 },
238 { 0x00008238, 0x00000000 },
239 { 0x0000823c, 0x00000000 },
240 { 0x00008240, 0x00100000 },
241 { 0x00008244, 0x0010f400 },
242 { 0x00008248, 0x00000100 },
243 { 0x0000824c, 0x0001e800 },
244 { 0x00008250, 0x00000000 },
245 { 0x00008254, 0x00000000 },
246 { 0x00008258, 0x00000000 },
247 { 0x0000825c, 0x400000ff },
248 { 0x00008260, 0x00080922 },
249 { 0x00008270, 0x00000000 },
250 { 0x00008274, 0x40000000 },
251 { 0x00008278, 0x003e4180 },
252 { 0x0000827c, 0x00000000 },
253 { 0x00008284, 0x0000002c },
254 { 0x00008288, 0x0000002c },
255 { 0x0000828c, 0x00000000 },
256 { 0x00008294, 0x00000000 },
257 { 0x00008298, 0x00000000 },
258 { 0x00008300, 0x00000000 },
259 { 0x00008304, 0x00000000 },
260 { 0x00008308, 0x00000000 },
261 { 0x0000830c, 0x00000000 },
262 { 0x00008310, 0x00000000 },
263 { 0x00008314, 0x00000000 },
264 { 0x00008318, 0x00000000 },
265 { 0x00008328, 0x00000000 },
266 { 0x0000832c, 0x00000007 },
267 { 0x00008330, 0x00000302 },
268 { 0x00008334, 0x00000e00 },
269 { 0x00008338, 0x00000000 },
270 { 0x0000833c, 0x00000000 },
271 { 0x00008340, 0x000107ff },
272 { 0x00009808, 0x00000000 },
273 { 0x0000980c, 0xad848e19 },
274 { 0x00009810, 0x7d14e000 },
275 { 0x00009814, 0x9c0a9f6b },
276 { 0x0000981c, 0x00000000 },
277 { 0x0000982c, 0x0000a000 },
278 { 0x00009830, 0x00000000 },
279 { 0x0000983c, 0x00200400 },
280 { 0x00009840, 0x206a002e },
281 { 0x0000984c, 0x1284233c },
282 { 0x00009854, 0x00000859 },
283 { 0x00009900, 0x00000000 },
284 { 0x00009904, 0x00000000 },
285 { 0x00009908, 0x00000000 },
286 { 0x0000990c, 0x00000000 },
287 { 0x0000991c, 0x10000fff },
288 { 0x00009920, 0x05100000 },
289 { 0x0000a920, 0x05100000 },
290 { 0x0000b920, 0x05100000 },
291 { 0x00009928, 0x00000001 },
292 { 0x0000992c, 0x00000004 },
293 { 0x00009934, 0x1e1f2022 },
294 { 0x00009938, 0x0a0b0c0d },
295 { 0x0000993c, 0x00000000 },
296 { 0x00009948, 0x9280b212 },
297 { 0x0000994c, 0x00020028 },
298 { 0x00009954, 0x5d50e188 },
299 { 0x00009958, 0x00081fff },
300 { 0x0000c95c, 0x004b6a8e },
301 { 0x0000c968, 0x000003ce },
302 { 0x00009970, 0x190fb515 },
303 { 0x00009974, 0x00000000 },
304 { 0x00009978, 0x00000001 },
305 { 0x0000997c, 0x00000000 },
306 { 0x00009980, 0x00000000 },
307 { 0x00009984, 0x00000000 },
308 { 0x00009988, 0x00000000 },
309 { 0x0000998c, 0x00000000 },
310 { 0x00009990, 0x00000000 },
311 { 0x00009994, 0x00000000 },
312 { 0x00009998, 0x00000000 },
313 { 0x0000999c, 0x00000000 },
314 { 0x000099a0, 0x00000000 },
315 { 0x000099a4, 0x00000001 },
316 { 0x000099a8, 0x001fff00 },
317 { 0x000099ac, 0x00000000 },
318 { 0x000099b0, 0x03051000 },
319 { 0x000099dc, 0x00000000 },
320 { 0x000099e0, 0x00000200 },
321 { 0x000099e4, 0xaaaaaaaa },
322 { 0x000099e8, 0x3c466478 },
323 { 0x000099ec, 0x000000aa },
324 { 0x000099fc, 0x00001042 },
325 { 0x00009b00, 0x00000000 },
326 { 0x00009b04, 0x00000001 },
327 { 0x00009b08, 0x00000002 },
328 { 0x00009b0c, 0x00000003 },
329 { 0x00009b10, 0x00000004 },
330 { 0x00009b14, 0x00000005 },
331 { 0x00009b18, 0x00000008 },
332 { 0x00009b1c, 0x00000009 },
333 { 0x00009b20, 0x0000000a },
334 { 0x00009b24, 0x0000000b },
335 { 0x00009b28, 0x0000000c },
336 { 0x00009b2c, 0x0000000d },
337 { 0x00009b30, 0x00000010 },
338 { 0x00009b34, 0x00000011 },
339 { 0x00009b38, 0x00000012 },
340 { 0x00009b3c, 0x00000013 },
341 { 0x00009b40, 0x00000014 },
342 { 0x00009b44, 0x00000015 },
343 { 0x00009b48, 0x00000018 },
344 { 0x00009b4c, 0x00000019 },
345 { 0x00009b50, 0x0000001a },
346 { 0x00009b54, 0x0000001b },
347 { 0x00009b58, 0x0000001c },
348 { 0x00009b5c, 0x0000001d },
349 { 0x00009b60, 0x00000020 },
350 { 0x00009b64, 0x00000021 },
351 { 0x00009b68, 0x00000022 },
352 { 0x00009b6c, 0x00000023 },
353 { 0x00009b70, 0x00000024 },
354 { 0x00009b74, 0x00000025 },
355 { 0x00009b78, 0x00000028 },
356 { 0x00009b7c, 0x00000029 },
357 { 0x00009b80, 0x0000002a },
358 { 0x00009b84, 0x0000002b },
359 { 0x00009b88, 0x0000002c },
360 { 0x00009b8c, 0x0000002d },
361 { 0x00009b90, 0x00000030 },
362 { 0x00009b94, 0x00000031 },
363 { 0x00009b98, 0x00000032 },
364 { 0x00009b9c, 0x00000033 },
365 { 0x00009ba0, 0x00000034 },
366 { 0x00009ba4, 0x00000035 },
367 { 0x00009ba8, 0x00000035 },
368 { 0x00009bac, 0x00000035 },
369 { 0x00009bb0, 0x00000035 },
370 { 0x00009bb4, 0x00000035 },
371 { 0x00009bb8, 0x00000035 },
372 { 0x00009bbc, 0x00000035 },
373 { 0x00009bc0, 0x00000035 },
374 { 0x00009bc4, 0x00000035 },
375 { 0x00009bc8, 0x00000035 },
376 { 0x00009bcc, 0x00000035 },
377 { 0x00009bd0, 0x00000035 },
378 { 0x00009bd4, 0x00000035 },
379 { 0x00009bd8, 0x00000035 },
380 { 0x00009bdc, 0x00000035 },
381 { 0x00009be0, 0x00000035 },
382 { 0x00009be4, 0x00000035 },
383 { 0x00009be8, 0x00000035 },
384 { 0x00009bec, 0x00000035 },
385 { 0x00009bf0, 0x00000035 },
386 { 0x00009bf4, 0x00000035 },
387 { 0x00009bf8, 0x00000010 },
388 { 0x00009bfc, 0x0000001a },
389 { 0x0000a210, 0x40806333 },
390 { 0x0000a214, 0x00106c10 },
391 { 0x0000a218, 0x009c4060 },
392 { 0x0000a220, 0x018830c6 },
393 { 0x0000a224, 0x00000400 },
394 { 0x0000a228, 0x00000bb5 },
395 { 0x0000a22c, 0x00000011 },
396 { 0x0000a234, 0x20202020 },
397 { 0x0000a238, 0x20202020 },
398 { 0x0000a23c, 0x13c889af },
399 { 0x0000a240, 0x38490a20 },
400 { 0x0000a244, 0x00007bb6 },
401 { 0x0000a248, 0x0fff3ffc },
402 { 0x0000a24c, 0x00000001 },
403 { 0x0000a250, 0x0000a000 },
404 { 0x0000a254, 0x00000000 },
405 { 0x0000a258, 0x0cc75380 },
406 { 0x0000a25c, 0x0f0f0f01 },
407 { 0x0000a260, 0xdfa91f01 },
408 { 0x0000a268, 0x00000000 },
409 { 0x0000a26c, 0x0ebae9c6 },
410 { 0x0000b26c, 0x0ebae9c6 },
411 { 0x0000c26c, 0x0ebae9c6 },
412 { 0x0000d270, 0x00820820 },
413 { 0x0000a278, 0x1ce739ce },
414 { 0x0000a27c, 0x051701ce },
415 { 0x0000a338, 0x00000000 },
416 { 0x0000a33c, 0x00000000 },
417 { 0x0000a340, 0x00000000 },
418 { 0x0000a344, 0x00000000 },
419 { 0x0000a348, 0x3fffffff },
420 { 0x0000a34c, 0x3fffffff },
421 { 0x0000a350, 0x3fffffff },
422 { 0x0000a354, 0x0003ffff },
423 { 0x0000a358, 0x79a8aa1f },
424 { 0x0000d35c, 0x07ffffef },
425 { 0x0000d360, 0x0fffffe7 },
426 { 0x0000d364, 0x17ffffe5 },
427 { 0x0000d368, 0x1fffffe4 },
428 { 0x0000d36c, 0x37ffffe3 },
429 { 0x0000d370, 0x3fffffe3 },
430 { 0x0000d374, 0x57ffffe3 },
431 { 0x0000d378, 0x5fffffe2 },
432 { 0x0000d37c, 0x7fffffe2 },
433 { 0x0000d380, 0x7f3c7bba },
434 { 0x0000d384, 0xf3307ff0 },
435 { 0x0000a388, 0x08000000 },
436 { 0x0000a38c, 0x20202020 },
437 { 0x0000a390, 0x20202020 },
438 { 0x0000a394, 0x1ce739ce },
439 { 0x0000a398, 0x000001ce },
440 { 0x0000a39c, 0x00000001 },
441 { 0x0000a3a0, 0x00000000 },
442 { 0x0000a3a4, 0x00000000 },
443 { 0x0000a3a8, 0x00000000 },
444 { 0x0000a3ac, 0x00000000 },
445 { 0x0000a3b0, 0x00000000 },
446 { 0x0000a3b4, 0x00000000 },
447 { 0x0000a3b8, 0x00000000 },
448 { 0x0000a3bc, 0x00000000 },
449 { 0x0000a3c0, 0x00000000 },
450 { 0x0000a3c4, 0x00000000 },
451 { 0x0000a3c8, 0x00000246 },
452 { 0x0000a3cc, 0x20202020 },
453 { 0x0000a3d0, 0x20202020 },
454 { 0x0000a3d4, 0x20202020 },
455 { 0x0000a3dc, 0x1ce739ce },
456 { 0x0000a3e0, 0x000001ce },
457};
458
459static const u32 ar5416Bank0_9100[][2] = {
460 { 0x000098b0, 0x1e5795e5 },
461 { 0x000098e0, 0x02008020 },
462};
463
464static const u32 ar5416BB_RfGain_9100[][3] = {
465 { 0x00009a00, 0x00000000, 0x00000000 },
466 { 0x00009a04, 0x00000040, 0x00000040 },
467 { 0x00009a08, 0x00000080, 0x00000080 },
468 { 0x00009a0c, 0x000001a1, 0x00000141 },
469 { 0x00009a10, 0x000001e1, 0x00000181 },
470 { 0x00009a14, 0x00000021, 0x000001c1 },
471 { 0x00009a18, 0x00000061, 0x00000001 },
472 { 0x00009a1c, 0x00000168, 0x00000041 },
473 { 0x00009a20, 0x000001a8, 0x000001a8 },
474 { 0x00009a24, 0x000001e8, 0x000001e8 },
475 { 0x00009a28, 0x00000028, 0x00000028 },
476 { 0x00009a2c, 0x00000068, 0x00000068 },
477 { 0x00009a30, 0x00000189, 0x000000a8 },
478 { 0x00009a34, 0x000001c9, 0x00000169 },
479 { 0x00009a38, 0x00000009, 0x000001a9 },
480 { 0x00009a3c, 0x00000049, 0x000001e9 },
481 { 0x00009a40, 0x00000089, 0x00000029 },
482 { 0x00009a44, 0x00000170, 0x00000069 },
483 { 0x00009a48, 0x000001b0, 0x00000190 },
484 { 0x00009a4c, 0x000001f0, 0x000001d0 },
485 { 0x00009a50, 0x00000030, 0x00000010 },
486 { 0x00009a54, 0x00000070, 0x00000050 },
487 { 0x00009a58, 0x00000191, 0x00000090 },
488 { 0x00009a5c, 0x000001d1, 0x00000151 },
489 { 0x00009a60, 0x00000011, 0x00000191 },
490 { 0x00009a64, 0x00000051, 0x000001d1 },
491 { 0x00009a68, 0x00000091, 0x00000011 },
492 { 0x00009a6c, 0x000001b8, 0x00000051 },
493 { 0x00009a70, 0x000001f8, 0x00000198 },
494 { 0x00009a74, 0x00000038, 0x000001d8 },
495 { 0x00009a78, 0x00000078, 0x00000018 },
496 { 0x00009a7c, 0x00000199, 0x00000058 },
497 { 0x00009a80, 0x000001d9, 0x00000098 },
498 { 0x00009a84, 0x00000019, 0x00000159 },
499 { 0x00009a88, 0x00000059, 0x00000199 },
500 { 0x00009a8c, 0x00000099, 0x000001d9 },
501 { 0x00009a90, 0x000000d9, 0x00000019 },
502 { 0x00009a94, 0x000000f9, 0x00000059 },
503 { 0x00009a98, 0x000000f9, 0x00000099 },
504 { 0x00009a9c, 0x000000f9, 0x000000d9 },
505 { 0x00009aa0, 0x000000f9, 0x000000f9 },
506 { 0x00009aa4, 0x000000f9, 0x000000f9 },
507 { 0x00009aa8, 0x000000f9, 0x000000f9 },
508 { 0x00009aac, 0x000000f9, 0x000000f9 },
509 { 0x00009ab0, 0x000000f9, 0x000000f9 },
510 { 0x00009ab4, 0x000000f9, 0x000000f9 },
511 { 0x00009ab8, 0x000000f9, 0x000000f9 },
512 { 0x00009abc, 0x000000f9, 0x000000f9 },
513 { 0x00009ac0, 0x000000f9, 0x000000f9 },
514 { 0x00009ac4, 0x000000f9, 0x000000f9 },
515 { 0x00009ac8, 0x000000f9, 0x000000f9 },
516 { 0x00009acc, 0x000000f9, 0x000000f9 },
517 { 0x00009ad0, 0x000000f9, 0x000000f9 },
518 { 0x00009ad4, 0x000000f9, 0x000000f9 },
519 { 0x00009ad8, 0x000000f9, 0x000000f9 },
520 { 0x00009adc, 0x000000f9, 0x000000f9 },
521 { 0x00009ae0, 0x000000f9, 0x000000f9 },
522 { 0x00009ae4, 0x000000f9, 0x000000f9 },
523 { 0x00009ae8, 0x000000f9, 0x000000f9 },
524 { 0x00009aec, 0x000000f9, 0x000000f9 },
525 { 0x00009af0, 0x000000f9, 0x000000f9 },
526 { 0x00009af4, 0x000000f9, 0x000000f9 },
527 { 0x00009af8, 0x000000f9, 0x000000f9 },
528 { 0x00009afc, 0x000000f9, 0x000000f9 },
529};
530
531static const u32 ar5416Bank1_9100[][2] = {
532 { 0x000098b0, 0x02108421 },
533 { 0x000098ec, 0x00000008 },
534};
535
536static const u32 ar5416Bank2_9100[][2] = {
537 { 0x000098b0, 0x0e73ff17 },
538 { 0x000098e0, 0x00000420 },
539};
540
541static const u32 ar5416Bank3_9100[][3] = {
542 { 0x000098f0, 0x01400018, 0x01c00018 },
543};
544
545static const u32 ar5416Bank6_9100[][3] = {
546
547 { 0x0000989c, 0x00000000, 0x00000000 },
548 { 0x0000989c, 0x00000000, 0x00000000 },
549 { 0x0000989c, 0x00000000, 0x00000000 },
550 { 0x0000989c, 0x00e00000, 0x00e00000 },
551 { 0x0000989c, 0x005e0000, 0x005e0000 },
552 { 0x0000989c, 0x00120000, 0x00120000 },
553 { 0x0000989c, 0x00620000, 0x00620000 },
554 { 0x0000989c, 0x00020000, 0x00020000 },
555 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
556 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
557 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
558 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
559 { 0x0000989c, 0x005f0000, 0x005f0000 },
560 { 0x0000989c, 0x00870000, 0x00870000 },
561 { 0x0000989c, 0x00f90000, 0x00f90000 },
562 { 0x0000989c, 0x007b0000, 0x007b0000 },
563 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
564 { 0x0000989c, 0x00f50000, 0x00f50000 },
565 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
566 { 0x0000989c, 0x00110000, 0x00110000 },
567 { 0x0000989c, 0x006100a8, 0x006100a8 },
568 { 0x0000989c, 0x004210a2, 0x004210a2 },
569 { 0x0000989c, 0x0014008f, 0x0014008f },
570 { 0x0000989c, 0x00c40003, 0x00c40003 },
571 { 0x0000989c, 0x003000f2, 0x003000f2 },
572 { 0x0000989c, 0x00440016, 0x00440016 },
573 { 0x0000989c, 0x00410040, 0x00410040 },
574 { 0x0000989c, 0x0001805e, 0x0001805e },
575 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
576 { 0x0000989c, 0x000000f1, 0x000000f1 },
577 { 0x0000989c, 0x00002081, 0x00002081 },
578 { 0x0000989c, 0x000000d4, 0x000000d4 },
579 { 0x000098d0, 0x0000000f, 0x0010000f },
580};
581
582static const u32 ar5416Bank6TPC_9100[][3] = {
583 { 0x0000989c, 0x00000000, 0x00000000 },
584 { 0x0000989c, 0x00000000, 0x00000000 },
585 { 0x0000989c, 0x00000000, 0x00000000 },
586 { 0x0000989c, 0x00e00000, 0x00e00000 },
587 { 0x0000989c, 0x005e0000, 0x005e0000 },
588 { 0x0000989c, 0x00120000, 0x00120000 },
589 { 0x0000989c, 0x00620000, 0x00620000 },
590 { 0x0000989c, 0x00020000, 0x00020000 },
591 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
592 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
593 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
594 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
595 { 0x0000989c, 0x005f0000, 0x005f0000 },
596 { 0x0000989c, 0x00870000, 0x00870000 },
597 { 0x0000989c, 0x00f90000, 0x00f90000 },
598 { 0x0000989c, 0x007b0000, 0x007b0000 },
599 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
600 { 0x0000989c, 0x00f50000, 0x00f50000 },
601 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
602 { 0x0000989c, 0x00110000, 0x00110000 },
603 { 0x0000989c, 0x006100a8, 0x006100a8 },
604 { 0x0000989c, 0x00423022, 0x00423022 },
605 { 0x0000989c, 0x201400df, 0x201400df },
606 { 0x0000989c, 0x00c40002, 0x00c40002 },
607 { 0x0000989c, 0x003000f2, 0x003000f2 },
608 { 0x0000989c, 0x00440016, 0x00440016 },
609 { 0x0000989c, 0x00410040, 0x00410040 },
610 { 0x0000989c, 0x0001805e, 0x0001805e },
611 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
612 { 0x0000989c, 0x000000e1, 0x000000e1 },
613 { 0x0000989c, 0x00007081, 0x00007081 },
614 { 0x0000989c, 0x000000d4, 0x000000d4 },
615 { 0x000098d0, 0x0000000f, 0x0010000f },
616};
617
618static const u32 ar5416Bank7_9100[][2] = {
619 { 0x0000989c, 0x00000500 },
620 { 0x0000989c, 0x00000800 },
621 { 0x000098cc, 0x0000000e },
622};
623
624static const u32 ar5416Addac_9100[][2] = {
625 {0x0000989c, 0x00000000 },
626 {0x0000989c, 0x00000003 },
627 {0x0000989c, 0x00000000 },
628 {0x0000989c, 0x0000000c },
629 {0x0000989c, 0x00000000 },
630 {0x0000989c, 0x00000030 },
631 {0x0000989c, 0x00000000 },
632 {0x0000989c, 0x00000000 },
633 {0x0000989c, 0x00000000 },
634 {0x0000989c, 0x00000000 },
635 {0x0000989c, 0x00000000 },
636 {0x0000989c, 0x00000000 },
637 {0x0000989c, 0x00000000 },
638 {0x0000989c, 0x00000000 },
639 {0x0000989c, 0x00000000 },
640 {0x0000989c, 0x00000000 },
641 {0x0000989c, 0x00000000 },
642 {0x0000989c, 0x00000000 },
643 {0x0000989c, 0x00000060 },
644 {0x0000989c, 0x00000000 },
645 {0x0000989c, 0x00000000 },
646 {0x0000989c, 0x00000000 },
647 {0x0000989c, 0x00000000 },
648 {0x0000989c, 0x00000000 },
649 {0x0000989c, 0x00000000 },
650 {0x0000989c, 0x00000000 },
651 {0x0000989c, 0x00000000 },
652 {0x0000989c, 0x00000000 },
653 {0x0000989c, 0x00000000 },
654 {0x0000989c, 0x00000000 },
655 {0x0000989c, 0x00000000 },
656 {0x0000989c, 0x00000058 },
657 {0x0000989c, 0x00000000 },
658 {0x0000989c, 0x00000000 },
659 {0x0000989c, 0x00000000 },
660 {0x0000989c, 0x00000000 },
661 {0x000098c4, 0x00000000 },
662};
663
664static const u32 ar5416Modes[][6] = {
665 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
666 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
667 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
668 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
669 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
670 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
671 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
672 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
673 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
674 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
675 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
676 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
677 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
678 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
679 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
680 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
681 { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
682 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec86d2e, 0x7ec84d2e, 0x7ec82d2e },
683 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
684 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
685 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
686 { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
687 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
688 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
689 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
690 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a11, 0xd00a8a0d, 0xd00a8a0d },
691 { 0x00009940, 0x00754604, 0x00754604, 0xfff81204, 0xfff81204, 0xfff81204 },
692 { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
693 { 0x00009954, 0x5f3ca3de, 0x5f3ca3de, 0xe250a51e, 0xe250a51e, 0xe250a51e },
694 { 0x00009958, 0x2108ecff, 0x2108ecff, 0x3388ffff, 0x3388ffff, 0x3388ffff },
695#ifdef TB243
696 { 0x00009960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
697 { 0x0000a960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
698 { 0x0000b960, 0x00000900, 0x00000900, 0x00009b40, 0x00009b40, 0x00012d80 },
699 { 0x00009964, 0x00000000, 0x00000000, 0x00002210, 0x00002210, 0x00001120 },
700#else
701 { 0x00009960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
702 { 0x0000a960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
703 { 0x0000b960, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0, 0x0001bfc0 },
704 { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
705#endif
706 { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a1000, 0x001a0c00, 0x001a0c00 },
707 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
708 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
709 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
710 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
711 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
712 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
713 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
714 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
715 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
716 { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
717 { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
718 { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
719 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
720 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
721 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
722 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
723 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
724 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
725 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
726 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
727 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
728 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
729 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
730 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
731 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
732 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
733 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
734 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
735 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
736};
737
738static const u32 ar5416Common[][2] = {
739 { 0x0000000c, 0x00000000 },
740 { 0x00000030, 0x00020015 },
741 { 0x00000034, 0x00000005 },
742 { 0x00000040, 0x00000000 },
743 { 0x00000044, 0x00000008 },
744 { 0x00000048, 0x00000008 },
745 { 0x0000004c, 0x00000010 },
746 { 0x00000050, 0x00000000 },
747 { 0x00000054, 0x0000001f },
748 { 0x00000800, 0x00000000 },
749 { 0x00000804, 0x00000000 },
750 { 0x00000808, 0x00000000 },
751 { 0x0000080c, 0x00000000 },
752 { 0x00000810, 0x00000000 },
753 { 0x00000814, 0x00000000 },
754 { 0x00000818, 0x00000000 },
755 { 0x0000081c, 0x00000000 },
756 { 0x00000820, 0x00000000 },
757 { 0x00000824, 0x00000000 },
758 { 0x00001040, 0x002ffc0f },
759 { 0x00001044, 0x002ffc0f },
760 { 0x00001048, 0x002ffc0f },
761 { 0x0000104c, 0x002ffc0f },
762 { 0x00001050, 0x002ffc0f },
763 { 0x00001054, 0x002ffc0f },
764 { 0x00001058, 0x002ffc0f },
765 { 0x0000105c, 0x002ffc0f },
766 { 0x00001060, 0x002ffc0f },
767 { 0x00001064, 0x002ffc0f },
768 { 0x00001230, 0x00000000 },
769 { 0x00001270, 0x00000000 },
770 { 0x00001038, 0x00000000 },
771 { 0x00001078, 0x00000000 },
772 { 0x000010b8, 0x00000000 },
773 { 0x000010f8, 0x00000000 },
774 { 0x00001138, 0x00000000 },
775 { 0x00001178, 0x00000000 },
776 { 0x000011b8, 0x00000000 },
777 { 0x000011f8, 0x00000000 },
778 { 0x00001238, 0x00000000 },
779 { 0x00001278, 0x00000000 },
780 { 0x000012b8, 0x00000000 },
781 { 0x000012f8, 0x00000000 },
782 { 0x00001338, 0x00000000 },
783 { 0x00001378, 0x00000000 },
784 { 0x000013b8, 0x00000000 },
785 { 0x000013f8, 0x00000000 },
786 { 0x00001438, 0x00000000 },
787 { 0x00001478, 0x00000000 },
788 { 0x000014b8, 0x00000000 },
789 { 0x000014f8, 0x00000000 },
790 { 0x00001538, 0x00000000 },
791 { 0x00001578, 0x00000000 },
792 { 0x000015b8, 0x00000000 },
793 { 0x000015f8, 0x00000000 },
794 { 0x00001638, 0x00000000 },
795 { 0x00001678, 0x00000000 },
796 { 0x000016b8, 0x00000000 },
797 { 0x000016f8, 0x00000000 },
798 { 0x00001738, 0x00000000 },
799 { 0x00001778, 0x00000000 },
800 { 0x000017b8, 0x00000000 },
801 { 0x000017f8, 0x00000000 },
802 { 0x0000103c, 0x00000000 },
803 { 0x0000107c, 0x00000000 },
804 { 0x000010bc, 0x00000000 },
805 { 0x000010fc, 0x00000000 },
806 { 0x0000113c, 0x00000000 },
807 { 0x0000117c, 0x00000000 },
808 { 0x000011bc, 0x00000000 },
809 { 0x000011fc, 0x00000000 },
810 { 0x0000123c, 0x00000000 },
811 { 0x0000127c, 0x00000000 },
812 { 0x000012bc, 0x00000000 },
813 { 0x000012fc, 0x00000000 },
814 { 0x0000133c, 0x00000000 },
815 { 0x0000137c, 0x00000000 },
816 { 0x000013bc, 0x00000000 },
817 { 0x000013fc, 0x00000000 },
818 { 0x0000143c, 0x00000000 },
819 { 0x0000147c, 0x00000000 },
820 { 0x00020010, 0x00000003 },
821 { 0x00020038, 0x000004c2 },
822 { 0x00008004, 0x00000000 },
823 { 0x00008008, 0x00000000 },
824 { 0x0000800c, 0x00000000 },
825 { 0x00008018, 0x00000700 },
826 { 0x00008020, 0x00000000 },
827 { 0x00008038, 0x00000000 },
828 { 0x0000803c, 0x00000000 },
829 { 0x00008048, 0x40000000 },
830 { 0x00008054, 0x00004000 },
831 { 0x00008058, 0x00000000 },
832 { 0x0000805c, 0x000fc78f },
833 { 0x00008060, 0x0000000f },
834 { 0x00008064, 0x00000000 },
835 { 0x000080c0, 0x2a82301a },
836 { 0x000080c4, 0x05dc01e0 },
837 { 0x000080c8, 0x1f402710 },
838 { 0x000080cc, 0x01f40000 },
839 { 0x000080d0, 0x00001e00 },
840 { 0x000080d4, 0x00000000 },
841 { 0x000080d8, 0x00400000 },
842 { 0x000080e0, 0xffffffff },
843 { 0x000080e4, 0x0000ffff },
844 { 0x000080e8, 0x003f3f3f },
845 { 0x000080ec, 0x00000000 },
846 { 0x000080f0, 0x00000000 },
847 { 0x000080f4, 0x00000000 },
848 { 0x000080f8, 0x00000000 },
849 { 0x000080fc, 0x00020000 },
850 { 0x00008100, 0x00020000 },
851 { 0x00008104, 0x00000001 },
852 { 0x00008108, 0x00000052 },
853 { 0x0000810c, 0x00000000 },
854 { 0x00008110, 0x00000168 },
855 { 0x00008118, 0x000100aa },
856 { 0x0000811c, 0x00003210 },
857 { 0x00008120, 0x08f04800 },
858 { 0x00008124, 0x00000000 },
859 { 0x00008128, 0x00000000 },
860 { 0x0000812c, 0x00000000 },
861 { 0x00008130, 0x00000000 },
862 { 0x00008134, 0x00000000 },
863 { 0x00008138, 0x00000000 },
864 { 0x0000813c, 0x00000000 },
865 { 0x00008144, 0x00000000 },
866 { 0x00008168, 0x00000000 },
867 { 0x0000816c, 0x00000000 },
868 { 0x00008170, 0x32143320 },
869 { 0x00008174, 0xfaa4fa50 },
870 { 0x00008178, 0x00000100 },
871 { 0x0000817c, 0x00000000 },
872 { 0x000081c4, 0x00000000 },
873 { 0x000081d0, 0x00003210 },
874 { 0x000081ec, 0x00000000 },
875 { 0x000081f0, 0x00000000 },
876 { 0x000081f4, 0x00000000 },
877 { 0x000081f8, 0x00000000 },
878 { 0x000081fc, 0x00000000 },
879 { 0x00008200, 0x00000000 },
880 { 0x00008204, 0x00000000 },
881 { 0x00008208, 0x00000000 },
882 { 0x0000820c, 0x00000000 },
883 { 0x00008210, 0x00000000 },
884 { 0x00008214, 0x00000000 },
885 { 0x00008218, 0x00000000 },
886 { 0x0000821c, 0x00000000 },
887 { 0x00008220, 0x00000000 },
888 { 0x00008224, 0x00000000 },
889 { 0x00008228, 0x00000000 },
890 { 0x0000822c, 0x00000000 },
891 { 0x00008230, 0x00000000 },
892 { 0x00008234, 0x00000000 },
893 { 0x00008238, 0x00000000 },
894 { 0x0000823c, 0x00000000 },
895 { 0x00008240, 0x00100000 },
896 { 0x00008244, 0x0010f400 },
897 { 0x00008248, 0x00000100 },
898 { 0x0000824c, 0x0001e800 },
899 { 0x00008250, 0x00000000 },
900 { 0x00008254, 0x00000000 },
901 { 0x00008258, 0x00000000 },
902 { 0x0000825c, 0x400000ff },
903 { 0x00008260, 0x00080922 },
904 { 0x00008270, 0x00000000 },
905 { 0x00008274, 0x40000000 },
906 { 0x00008278, 0x003e4180 },
907 { 0x0000827c, 0x00000000 },
908 { 0x00008284, 0x0000002c },
909 { 0x00008288, 0x0000002c },
910 { 0x0000828c, 0x00000000 },
911 { 0x00008294, 0x00000000 },
912 { 0x00008298, 0x00000000 },
913 { 0x00008300, 0x00000000 },
914 { 0x00008304, 0x00000000 },
915 { 0x00008308, 0x00000000 },
916 { 0x0000830c, 0x00000000 },
917 { 0x00008310, 0x00000000 },
918 { 0x00008314, 0x00000000 },
919 { 0x00008318, 0x00000000 },
920 { 0x00008328, 0x00000000 },
921 { 0x0000832c, 0x00000007 },
922 { 0x00008330, 0x00000302 },
923 { 0x00008334, 0x00000e00 },
924 { 0x00008338, 0x00000000 },
925 { 0x0000833c, 0x00000000 },
926 { 0x00008340, 0x000107ff },
927 { 0x00009808, 0x00000000 },
928 { 0x0000980c, 0xad848e19 },
929 { 0x00009810, 0x7d14e000 },
930 { 0x00009814, 0x9c0a9f6b },
931 { 0x0000981c, 0x00000000 },
932 { 0x0000982c, 0x0000a000 },
933 { 0x00009830, 0x00000000 },
934 { 0x0000983c, 0x00200400 },
935 { 0x00009840, 0x206a01ae },
936 { 0x0000984c, 0x1284233c },
937 { 0x00009854, 0x00000859 },
938 { 0x00009900, 0x00000000 },
939 { 0x00009904, 0x00000000 },
940 { 0x00009908, 0x00000000 },
941 { 0x0000990c, 0x00000000 },
942 { 0x0000991c, 0x10000fff },
943 { 0x00009920, 0x05100000 },
944 { 0x0000a920, 0x05100000 },
945 { 0x0000b920, 0x05100000 },
946 { 0x00009928, 0x00000001 },
947 { 0x0000992c, 0x00000004 },
948 { 0x00009934, 0x1e1f2022 },
949 { 0x00009938, 0x0a0b0c0d },
950 { 0x0000993c, 0x00000000 },
951 { 0x00009948, 0x9280b212 },
952 { 0x0000994c, 0x00020028 },
953 { 0x0000c95c, 0x004b6a8e },
954 { 0x0000c968, 0x000003ce },
955 { 0x00009970, 0x190fb514 },
956 { 0x00009974, 0x00000000 },
957 { 0x00009978, 0x00000001 },
958 { 0x0000997c, 0x00000000 },
959 { 0x00009980, 0x00000000 },
960 { 0x00009984, 0x00000000 },
961 { 0x00009988, 0x00000000 },
962 { 0x0000998c, 0x00000000 },
963 { 0x00009990, 0x00000000 },
964 { 0x00009994, 0x00000000 },
965 { 0x00009998, 0x00000000 },
966 { 0x0000999c, 0x00000000 },
967 { 0x000099a0, 0x00000000 },
968 { 0x000099a4, 0x00000001 },
969 { 0x000099a8, 0x201fff00 },
970 { 0x000099ac, 0x006f0000 },
971 { 0x000099b0, 0x03051000 },
972 { 0x000099dc, 0x00000000 },
973 { 0x000099e0, 0x00000200 },
974 { 0x000099e4, 0xaaaaaaaa },
975 { 0x000099e8, 0x3c466478 },
976 { 0x000099ec, 0x0cc80caa },
977 { 0x000099fc, 0x00001042 },
978 { 0x00009b00, 0x00000000 },
979 { 0x00009b04, 0x00000001 },
980 { 0x00009b08, 0x00000002 },
981 { 0x00009b0c, 0x00000003 },
982 { 0x00009b10, 0x00000004 },
983 { 0x00009b14, 0x00000005 },
984 { 0x00009b18, 0x00000008 },
985 { 0x00009b1c, 0x00000009 },
986 { 0x00009b20, 0x0000000a },
987 { 0x00009b24, 0x0000000b },
988 { 0x00009b28, 0x0000000c },
989 { 0x00009b2c, 0x0000000d },
990 { 0x00009b30, 0x00000010 },
991 { 0x00009b34, 0x00000011 },
992 { 0x00009b38, 0x00000012 },
993 { 0x00009b3c, 0x00000013 },
994 { 0x00009b40, 0x00000014 },
995 { 0x00009b44, 0x00000015 },
996 { 0x00009b48, 0x00000018 },
997 { 0x00009b4c, 0x00000019 },
998 { 0x00009b50, 0x0000001a },
999 { 0x00009b54, 0x0000001b },
1000 { 0x00009b58, 0x0000001c },
1001 { 0x00009b5c, 0x0000001d },
1002 { 0x00009b60, 0x00000020 },
1003 { 0x00009b64, 0x00000021 },
1004 { 0x00009b68, 0x00000022 },
1005 { 0x00009b6c, 0x00000023 },
1006 { 0x00009b70, 0x00000024 },
1007 { 0x00009b74, 0x00000025 },
1008 { 0x00009b78, 0x00000028 },
1009 { 0x00009b7c, 0x00000029 },
1010 { 0x00009b80, 0x0000002a },
1011 { 0x00009b84, 0x0000002b },
1012 { 0x00009b88, 0x0000002c },
1013 { 0x00009b8c, 0x0000002d },
1014 { 0x00009b90, 0x00000030 },
1015 { 0x00009b94, 0x00000031 },
1016 { 0x00009b98, 0x00000032 },
1017 { 0x00009b9c, 0x00000033 },
1018 { 0x00009ba0, 0x00000034 },
1019 { 0x00009ba4, 0x00000035 },
1020 { 0x00009ba8, 0x00000035 },
1021 { 0x00009bac, 0x00000035 },
1022 { 0x00009bb0, 0x00000035 },
1023 { 0x00009bb4, 0x00000035 },
1024 { 0x00009bb8, 0x00000035 },
1025 { 0x00009bbc, 0x00000035 },
1026 { 0x00009bc0, 0x00000035 },
1027 { 0x00009bc4, 0x00000035 },
1028 { 0x00009bc8, 0x00000035 },
1029 { 0x00009bcc, 0x00000035 },
1030 { 0x00009bd0, 0x00000035 },
1031 { 0x00009bd4, 0x00000035 },
1032 { 0x00009bd8, 0x00000035 },
1033 { 0x00009bdc, 0x00000035 },
1034 { 0x00009be0, 0x00000035 },
1035 { 0x00009be4, 0x00000035 },
1036 { 0x00009be8, 0x00000035 },
1037 { 0x00009bec, 0x00000035 },
1038 { 0x00009bf0, 0x00000035 },
1039 { 0x00009bf4, 0x00000035 },
1040 { 0x00009bf8, 0x00000010 },
1041 { 0x00009bfc, 0x0000001a },
1042 { 0x0000a210, 0x40806333 },
1043 { 0x0000a214, 0x00106c10 },
1044 { 0x0000a218, 0x009c4060 },
1045 { 0x0000a220, 0x018830c6 },
1046 { 0x0000a224, 0x00000400 },
1047 { 0x0000a228, 0x001a0bb5 },
1048 { 0x0000a22c, 0x00000000 },
1049 { 0x0000a234, 0x20202020 },
1050 { 0x0000a238, 0x20202020 },
1051 { 0x0000a23c, 0x13c889ae },
1052 { 0x0000a240, 0x38490a20 },
1053 { 0x0000a244, 0x00007bb6 },
1054 { 0x0000a248, 0x0fff3ffc },
1055 { 0x0000a24c, 0x00000001 },
1056 { 0x0000a250, 0x0000a000 },
1057 { 0x0000a254, 0x00000000 },
1058 { 0x0000a258, 0x0cc75380 },
1059 { 0x0000a25c, 0x0f0f0f01 },
1060 { 0x0000a260, 0xdfa91f01 },
1061 { 0x0000a268, 0x00000001 },
1062 { 0x0000a26c, 0x0ebae9c6 },
1063 { 0x0000b26c, 0x0ebae9c6 },
1064 { 0x0000c26c, 0x0ebae9c6 },
1065 { 0x0000d270, 0x00820820 },
1066 { 0x0000a278, 0x1ce739ce },
1067 { 0x0000a27c, 0x050701ce },
1068 { 0x0000a338, 0x00000000 },
1069 { 0x0000a33c, 0x00000000 },
1070 { 0x0000a340, 0x00000000 },
1071 { 0x0000a344, 0x00000000 },
1072 { 0x0000a348, 0x3fffffff },
1073 { 0x0000a34c, 0x3fffffff },
1074 { 0x0000a350, 0x3fffffff },
1075 { 0x0000a354, 0x0003ffff },
1076 { 0x0000a358, 0x79a8aa33 },
1077 { 0x0000d35c, 0x07ffffef },
1078 { 0x0000d360, 0x0fffffe7 },
1079 { 0x0000d364, 0x17ffffe5 },
1080 { 0x0000d368, 0x1fffffe4 },
1081 { 0x0000d36c, 0x37ffffe3 },
1082 { 0x0000d370, 0x3fffffe3 },
1083 { 0x0000d374, 0x57ffffe3 },
1084 { 0x0000d378, 0x5fffffe2 },
1085 { 0x0000d37c, 0x7fffffe2 },
1086 { 0x0000d380, 0x7f3c7bba },
1087 { 0x0000d384, 0xf3307ff0 },
1088 { 0x0000a388, 0x0c000000 },
1089 { 0x0000a38c, 0x20202020 },
1090 { 0x0000a390, 0x20202020 },
1091 { 0x0000a394, 0x1ce739ce },
1092 { 0x0000a398, 0x000001ce },
1093 { 0x0000a39c, 0x00000001 },
1094 { 0x0000a3a0, 0x00000000 },
1095 { 0x0000a3a4, 0x00000000 },
1096 { 0x0000a3a8, 0x00000000 },
1097 { 0x0000a3ac, 0x00000000 },
1098 { 0x0000a3b0, 0x00000000 },
1099 { 0x0000a3b4, 0x00000000 },
1100 { 0x0000a3b8, 0x00000000 },
1101 { 0x0000a3bc, 0x00000000 },
1102 { 0x0000a3c0, 0x00000000 },
1103 { 0x0000a3c4, 0x00000000 },
1104 { 0x0000a3c8, 0x00000246 },
1105 { 0x0000a3cc, 0x20202020 },
1106 { 0x0000a3d0, 0x20202020 },
1107 { 0x0000a3d4, 0x20202020 },
1108 { 0x0000a3dc, 0x1ce739ce },
1109 { 0x0000a3e0, 0x000001ce },
1110};
1111
1112static const u32 ar5416Bank0[][2] = {
1113 { 0x000098b0, 0x1e5795e5 },
1114 { 0x000098e0, 0x02008020 },
1115};
1116
1117static const u32 ar5416BB_RfGain[][3] = {
1118 { 0x00009a00, 0x00000000, 0x00000000 },
1119 { 0x00009a04, 0x00000040, 0x00000040 },
1120 { 0x00009a08, 0x00000080, 0x00000080 },
1121 { 0x00009a0c, 0x000001a1, 0x00000141 },
1122 { 0x00009a10, 0x000001e1, 0x00000181 },
1123 { 0x00009a14, 0x00000021, 0x000001c1 },
1124 { 0x00009a18, 0x00000061, 0x00000001 },
1125 { 0x00009a1c, 0x00000168, 0x00000041 },
1126 { 0x00009a20, 0x000001a8, 0x000001a8 },
1127 { 0x00009a24, 0x000001e8, 0x000001e8 },
1128 { 0x00009a28, 0x00000028, 0x00000028 },
1129 { 0x00009a2c, 0x00000068, 0x00000068 },
1130 { 0x00009a30, 0x00000189, 0x000000a8 },
1131 { 0x00009a34, 0x000001c9, 0x00000169 },
1132 { 0x00009a38, 0x00000009, 0x000001a9 },
1133 { 0x00009a3c, 0x00000049, 0x000001e9 },
1134 { 0x00009a40, 0x00000089, 0x00000029 },
1135 { 0x00009a44, 0x00000170, 0x00000069 },
1136 { 0x00009a48, 0x000001b0, 0x00000190 },
1137 { 0x00009a4c, 0x000001f0, 0x000001d0 },
1138 { 0x00009a50, 0x00000030, 0x00000010 },
1139 { 0x00009a54, 0x00000070, 0x00000050 },
1140 { 0x00009a58, 0x00000191, 0x00000090 },
1141 { 0x00009a5c, 0x000001d1, 0x00000151 },
1142 { 0x00009a60, 0x00000011, 0x00000191 },
1143 { 0x00009a64, 0x00000051, 0x000001d1 },
1144 { 0x00009a68, 0x00000091, 0x00000011 },
1145 { 0x00009a6c, 0x000001b8, 0x00000051 },
1146 { 0x00009a70, 0x000001f8, 0x00000198 },
1147 { 0x00009a74, 0x00000038, 0x000001d8 },
1148 { 0x00009a78, 0x00000078, 0x00000018 },
1149 { 0x00009a7c, 0x00000199, 0x00000058 },
1150 { 0x00009a80, 0x000001d9, 0x00000098 },
1151 { 0x00009a84, 0x00000019, 0x00000159 },
1152 { 0x00009a88, 0x00000059, 0x00000199 },
1153 { 0x00009a8c, 0x00000099, 0x000001d9 },
1154 { 0x00009a90, 0x000000d9, 0x00000019 },
1155 { 0x00009a94, 0x000000f9, 0x00000059 },
1156 { 0x00009a98, 0x000000f9, 0x00000099 },
1157 { 0x00009a9c, 0x000000f9, 0x000000d9 },
1158 { 0x00009aa0, 0x000000f9, 0x000000f9 },
1159 { 0x00009aa4, 0x000000f9, 0x000000f9 },
1160 { 0x00009aa8, 0x000000f9, 0x000000f9 },
1161 { 0x00009aac, 0x000000f9, 0x000000f9 },
1162 { 0x00009ab0, 0x000000f9, 0x000000f9 },
1163 { 0x00009ab4, 0x000000f9, 0x000000f9 },
1164 { 0x00009ab8, 0x000000f9, 0x000000f9 },
1165 { 0x00009abc, 0x000000f9, 0x000000f9 },
1166 { 0x00009ac0, 0x000000f9, 0x000000f9 },
1167 { 0x00009ac4, 0x000000f9, 0x000000f9 },
1168 { 0x00009ac8, 0x000000f9, 0x000000f9 },
1169 { 0x00009acc, 0x000000f9, 0x000000f9 },
1170 { 0x00009ad0, 0x000000f9, 0x000000f9 },
1171 { 0x00009ad4, 0x000000f9, 0x000000f9 },
1172 { 0x00009ad8, 0x000000f9, 0x000000f9 },
1173 { 0x00009adc, 0x000000f9, 0x000000f9 },
1174 { 0x00009ae0, 0x000000f9, 0x000000f9 },
1175 { 0x00009ae4, 0x000000f9, 0x000000f9 },
1176 { 0x00009ae8, 0x000000f9, 0x000000f9 },
1177 { 0x00009aec, 0x000000f9, 0x000000f9 },
1178 { 0x00009af0, 0x000000f9, 0x000000f9 },
1179 { 0x00009af4, 0x000000f9, 0x000000f9 },
1180 { 0x00009af8, 0x000000f9, 0x000000f9 },
1181 { 0x00009afc, 0x000000f9, 0x000000f9 },
1182};
1183
1184static const u32 ar5416Bank1[][2] = {
1185 { 0x000098b0, 0x02108421},
1186 { 0x000098ec, 0x00000008},
1187};
1188
1189static const u32 ar5416Bank2[][2] = {
1190 { 0x000098b0, 0x0e73ff17},
1191 { 0x000098e0, 0x00000420},
1192};
1193
1194static const u32 ar5416Bank3[][3] = {
1195 { 0x000098f0, 0x01400018, 0x01c00018 },
1196};
1197
1198static const u32 ar5416Bank6[][3] = {
1199
1200 { 0x0000989c, 0x00000000, 0x00000000 },
1201 { 0x0000989c, 0x00000000, 0x00000000 },
1202 { 0x0000989c, 0x00000000, 0x00000000 },
1203 { 0x0000989c, 0x00e00000, 0x00e00000 },
1204 { 0x0000989c, 0x005e0000, 0x005e0000 },
1205 { 0x0000989c, 0x00120000, 0x00120000 },
1206 { 0x0000989c, 0x00620000, 0x00620000 },
1207 { 0x0000989c, 0x00020000, 0x00020000 },
1208 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1209 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1210 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1211 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1212 { 0x0000989c, 0x005f0000, 0x005f0000 },
1213 { 0x0000989c, 0x00870000, 0x00870000 },
1214 { 0x0000989c, 0x00f90000, 0x00f90000 },
1215 { 0x0000989c, 0x007b0000, 0x007b0000 },
1216 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1217 { 0x0000989c, 0x00f50000, 0x00f50000 },
1218 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1219 { 0x0000989c, 0x00110000, 0x00110000 },
1220 { 0x0000989c, 0x006100a8, 0x006100a8 },
1221 { 0x0000989c, 0x004210a2, 0x004210a2 },
1222 { 0x0000989c, 0x0014000f, 0x0014000f },
1223 { 0x0000989c, 0x00c40002, 0x00c40002 },
1224 { 0x0000989c, 0x003000f2, 0x003000f2 },
1225 { 0x0000989c, 0x00440016, 0x00440016 },
1226 { 0x0000989c, 0x00410040, 0x00410040 },
1227 { 0x0000989c, 0x000180d6, 0x000180d6 },
1228 { 0x0000989c, 0x0000c0aa, 0x0000c0aa },
1229 { 0x0000989c, 0x000000b1, 0x000000b1 },
1230 { 0x0000989c, 0x00002000, 0x00002000 },
1231 { 0x0000989c, 0x000000d4, 0x000000d4 },
1232 { 0x000098d0, 0x0000000f, 0x0010000f },
1233};
1234
1235
1236static const u32 ar5416Bank6TPC[][3] = {
1237
1238 { 0x0000989c, 0x00000000, 0x00000000 },
1239 { 0x0000989c, 0x00000000, 0x00000000 },
1240 { 0x0000989c, 0x00000000, 0x00000000 },
1241 { 0x0000989c, 0x00e00000, 0x00e00000 },
1242 { 0x0000989c, 0x005e0000, 0x005e0000 },
1243 { 0x0000989c, 0x00120000, 0x00120000 },
1244 { 0x0000989c, 0x00620000, 0x00620000 },
1245 { 0x0000989c, 0x00020000, 0x00020000 },
1246 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1247 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1248 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1249 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1250 { 0x0000989c, 0x005f0000, 0x005f0000 },
1251 { 0x0000989c, 0x00870000, 0x00870000 },
1252 { 0x0000989c, 0x00f90000, 0x00f90000 },
1253 { 0x0000989c, 0x007b0000, 0x007b0000 },
1254 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1255 { 0x0000989c, 0x00f50000, 0x00f50000 },
1256 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1257 { 0x0000989c, 0x00110000, 0x00110000 },
1258 { 0x0000989c, 0x006100a8, 0x006100a8 },
1259 { 0x0000989c, 0x00423022, 0x00423022 },
1260 { 0x0000989c, 0x2014008f, 0x2014008f },
1261 { 0x0000989c, 0x00c40002, 0x00c40002 },
1262 { 0x0000989c, 0x003000f2, 0x003000f2 },
1263 { 0x0000989c, 0x00440016, 0x00440016 },
1264 { 0x0000989c, 0x00410040, 0x00410040 },
1265 { 0x0000989c, 0x0001805e, 0x0001805e },
1266 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1267 { 0x0000989c, 0x000000e1, 0x000000e1 },
1268 { 0x0000989c, 0x00007080, 0x00007080 },
1269 { 0x0000989c, 0x000000d4, 0x000000d4 },
1270 { 0x000098d0, 0x0000000f, 0x0010000f },
1271};
1272
1273static const u32 ar5416Bank7[][2] = {
1274 { 0x0000989c, 0x00000500 },
1275 { 0x0000989c, 0x00000800 },
1276 { 0x000098cc, 0x0000000e },
1277};
1278
1279static const u32 ar5416Addac[][2] = {
1280 {0x0000989c, 0x00000000 },
1281 {0x0000989c, 0x00000000 },
1282 {0x0000989c, 0x00000000 },
1283 {0x0000989c, 0x00000000 },
1284 {0x0000989c, 0x00000000 },
1285 {0x0000989c, 0x00000000 },
1286 {0x0000989c, 0x00000000 },
1287 {0x0000989c, 0x00000010 },
1288 {0x0000989c, 0x00000000 },
1289 {0x0000989c, 0x00000000 },
1290 {0x0000989c, 0x00000000 },
1291 {0x0000989c, 0x00000000 },
1292 {0x0000989c, 0x00000000 },
1293 {0x0000989c, 0x00000000 },
1294 {0x0000989c, 0x00000000 },
1295 {0x0000989c, 0x00000000 },
1296 {0x0000989c, 0x00000000 },
1297 {0x0000989c, 0x00000000 },
1298 {0x0000989c, 0x00000000 },
1299 {0x0000989c, 0x00000000 },
1300 {0x0000989c, 0x00000000 },
1301 {0x0000989c, 0x000000c0 },
1302 {0x0000989c, 0x00000015 },
1303 {0x0000989c, 0x00000000 },
1304 {0x0000989c, 0x00000000 },
1305 {0x0000989c, 0x00000000 },
1306 {0x0000989c, 0x00000000 },
1307 {0x0000989c, 0x00000000 },
1308 {0x0000989c, 0x00000000 },
1309 {0x0000989c, 0x00000000 },
1310 {0x0000989c, 0x00000000 },
1311 {0x000098cc, 0x00000000 },
1312};
1313
1314
1315static const u32 ar5416Modes_9160[][6] = {
1316 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
1317 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
1318 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
1319 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
1320 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
1321 { 0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf },
1322 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
1323 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
1324 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
1325 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
1326 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
1327 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
1328 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
1329 { 0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
1330 { 0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
1331 { 0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68 },
1332 { 0x00009850, 0x6d48b4e2, 0x6d48b4e2, 0x6d48b0e2, 0x6d48b0e2, 0x6d48b0e2 },
1333 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
1334 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
1335 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
1336 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
1337 { 0x00009868, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0, 0x409a40d0 },
1338 { 0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 },
1339 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
1340 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
1341 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
1342 { 0x00009944, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020, 0xdfb81020 },
1343 { 0x00009960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
1344 { 0x0000a960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
1345 { 0x0000b960, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40, 0x00009b40 },
1346 { 0x00009964, 0x00001120, 0x00001120, 0x00001120, 0x00001120, 0x00001120 },
1347 { 0x0000c9bc, 0x001a0600, 0x001a0600, 0x001a0c00, 0x001a0c00, 0x001a0c00 },
1348 { 0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be },
1349 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
1350 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
1351 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
1352 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
1353 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1354 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1355 { 0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880 },
1356 { 0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788 },
1357 { 0x0000a20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
1358 { 0x0000b20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
1359 { 0x0000c20c, 0x002fc160, 0x002fc160, 0x002ac120, 0x002ac120, 0x002ac120 },
1360 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
1361 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
1362 { 0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa },
1363 { 0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 },
1364 { 0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402 },
1365 { 0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06 },
1366 { 0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b },
1367 { 0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b },
1368 { 0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a },
1369 { 0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf },
1370 { 0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f },
1371 { 0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f },
1372 { 0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f },
1373 { 0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000 },
1374 { 0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1375 { 0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1376 { 0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
1377};
1378
1379static const u32 ar5416Common_9160[][2] = {
1380 { 0x0000000c, 0x00000000 },
1381 { 0x00000030, 0x00020015 },
1382 { 0x00000034, 0x00000005 },
1383 { 0x00000040, 0x00000000 },
1384 { 0x00000044, 0x00000008 },
1385 { 0x00000048, 0x00000008 },
1386 { 0x0000004c, 0x00000010 },
1387 { 0x00000050, 0x00000000 },
1388 { 0x00000054, 0x0000001f },
1389 { 0x00000800, 0x00000000 },
1390 { 0x00000804, 0x00000000 },
1391 { 0x00000808, 0x00000000 },
1392 { 0x0000080c, 0x00000000 },
1393 { 0x00000810, 0x00000000 },
1394 { 0x00000814, 0x00000000 },
1395 { 0x00000818, 0x00000000 },
1396 { 0x0000081c, 0x00000000 },
1397 { 0x00000820, 0x00000000 },
1398 { 0x00000824, 0x00000000 },
1399 { 0x00001040, 0x002ffc0f },
1400 { 0x00001044, 0x002ffc0f },
1401 { 0x00001048, 0x002ffc0f },
1402 { 0x0000104c, 0x002ffc0f },
1403 { 0x00001050, 0x002ffc0f },
1404 { 0x00001054, 0x002ffc0f },
1405 { 0x00001058, 0x002ffc0f },
1406 { 0x0000105c, 0x002ffc0f },
1407 { 0x00001060, 0x002ffc0f },
1408 { 0x00001064, 0x002ffc0f },
1409 { 0x00001230, 0x00000000 },
1410 { 0x00001270, 0x00000000 },
1411 { 0x00001038, 0x00000000 },
1412 { 0x00001078, 0x00000000 },
1413 { 0x000010b8, 0x00000000 },
1414 { 0x000010f8, 0x00000000 },
1415 { 0x00001138, 0x00000000 },
1416 { 0x00001178, 0x00000000 },
1417 { 0x000011b8, 0x00000000 },
1418 { 0x000011f8, 0x00000000 },
1419 { 0x00001238, 0x00000000 },
1420 { 0x00001278, 0x00000000 },
1421 { 0x000012b8, 0x00000000 },
1422 { 0x000012f8, 0x00000000 },
1423 { 0x00001338, 0x00000000 },
1424 { 0x00001378, 0x00000000 },
1425 { 0x000013b8, 0x00000000 },
1426 { 0x000013f8, 0x00000000 },
1427 { 0x00001438, 0x00000000 },
1428 { 0x00001478, 0x00000000 },
1429 { 0x000014b8, 0x00000000 },
1430 { 0x000014f8, 0x00000000 },
1431 { 0x00001538, 0x00000000 },
1432 { 0x00001578, 0x00000000 },
1433 { 0x000015b8, 0x00000000 },
1434 { 0x000015f8, 0x00000000 },
1435 { 0x00001638, 0x00000000 },
1436 { 0x00001678, 0x00000000 },
1437 { 0x000016b8, 0x00000000 },
1438 { 0x000016f8, 0x00000000 },
1439 { 0x00001738, 0x00000000 },
1440 { 0x00001778, 0x00000000 },
1441 { 0x000017b8, 0x00000000 },
1442 { 0x000017f8, 0x00000000 },
1443 { 0x0000103c, 0x00000000 },
1444 { 0x0000107c, 0x00000000 },
1445 { 0x000010bc, 0x00000000 },
1446 { 0x000010fc, 0x00000000 },
1447 { 0x0000113c, 0x00000000 },
1448 { 0x0000117c, 0x00000000 },
1449 { 0x000011bc, 0x00000000 },
1450 { 0x000011fc, 0x00000000 },
1451 { 0x0000123c, 0x00000000 },
1452 { 0x0000127c, 0x00000000 },
1453 { 0x000012bc, 0x00000000 },
1454 { 0x000012fc, 0x00000000 },
1455 { 0x0000133c, 0x00000000 },
1456 { 0x0000137c, 0x00000000 },
1457 { 0x000013bc, 0x00000000 },
1458 { 0x000013fc, 0x00000000 },
1459 { 0x0000143c, 0x00000000 },
1460 { 0x0000147c, 0x00000000 },
1461 { 0x00004030, 0x00000002 },
1462 { 0x0000403c, 0x00000002 },
1463 { 0x00007010, 0x00000020 },
1464 { 0x00007038, 0x000004c2 },
1465 { 0x00008004, 0x00000000 },
1466 { 0x00008008, 0x00000000 },
1467 { 0x0000800c, 0x00000000 },
1468 { 0x00008018, 0x00000700 },
1469 { 0x00008020, 0x00000000 },
1470 { 0x00008038, 0x00000000 },
1471 { 0x0000803c, 0x00000000 },
1472 { 0x00008048, 0x40000000 },
1473 { 0x00008054, 0x00000000 },
1474 { 0x00008058, 0x00000000 },
1475 { 0x0000805c, 0x000fc78f },
1476 { 0x00008060, 0x0000000f },
1477 { 0x00008064, 0x00000000 },
1478 { 0x000080c0, 0x2a82301a },
1479 { 0x000080c4, 0x05dc01e0 },
1480 { 0x000080c8, 0x1f402710 },
1481 { 0x000080cc, 0x01f40000 },
1482 { 0x000080d0, 0x00001e00 },
1483 { 0x000080d4, 0x00000000 },
1484 { 0x000080d8, 0x00400000 },
1485 { 0x000080e0, 0xffffffff },
1486 { 0x000080e4, 0x0000ffff },
1487 { 0x000080e8, 0x003f3f3f },
1488 { 0x000080ec, 0x00000000 },
1489 { 0x000080f0, 0x00000000 },
1490 { 0x000080f4, 0x00000000 },
1491 { 0x000080f8, 0x00000000 },
1492 { 0x000080fc, 0x00020000 },
1493 { 0x00008100, 0x00020000 },
1494 { 0x00008104, 0x00000001 },
1495 { 0x00008108, 0x00000052 },
1496 { 0x0000810c, 0x00000000 },
1497 { 0x00008110, 0x00000168 },
1498 { 0x00008118, 0x000100aa },
1499 { 0x0000811c, 0x00003210 },
1500 { 0x00008120, 0x08f04800 },
1501 { 0x00008124, 0x00000000 },
1502 { 0x00008128, 0x00000000 },
1503 { 0x0000812c, 0x00000000 },
1504 { 0x00008130, 0x00000000 },
1505 { 0x00008134, 0x00000000 },
1506 { 0x00008138, 0x00000000 },
1507 { 0x0000813c, 0x00000000 },
1508 { 0x00008144, 0x00000000 },
1509 { 0x00008168, 0x00000000 },
1510 { 0x0000816c, 0x00000000 },
1511 { 0x00008170, 0x32143320 },
1512 { 0x00008174, 0xfaa4fa50 },
1513 { 0x00008178, 0x00000100 },
1514 { 0x0000817c, 0x00000000 },
1515 { 0x000081c4, 0x00000000 },
1516 { 0x000081d0, 0x00003210 },
1517 { 0x000081ec, 0x00000000 },
1518 { 0x000081f0, 0x00000000 },
1519 { 0x000081f4, 0x00000000 },
1520 { 0x000081f8, 0x00000000 },
1521 { 0x000081fc, 0x00000000 },
1522 { 0x00008200, 0x00000000 },
1523 { 0x00008204, 0x00000000 },
1524 { 0x00008208, 0x00000000 },
1525 { 0x0000820c, 0x00000000 },
1526 { 0x00008210, 0x00000000 },
1527 { 0x00008214, 0x00000000 },
1528 { 0x00008218, 0x00000000 },
1529 { 0x0000821c, 0x00000000 },
1530 { 0x00008220, 0x00000000 },
1531 { 0x00008224, 0x00000000 },
1532 { 0x00008228, 0x00000000 },
1533 { 0x0000822c, 0x00000000 },
1534 { 0x00008230, 0x00000000 },
1535 { 0x00008234, 0x00000000 },
1536 { 0x00008238, 0x00000000 },
1537 { 0x0000823c, 0x00000000 },
1538 { 0x00008240, 0x00100000 },
1539 { 0x00008244, 0x0010f400 },
1540 { 0x00008248, 0x00000100 },
1541 { 0x0000824c, 0x0001e800 },
1542 { 0x00008250, 0x00000000 },
1543 { 0x00008254, 0x00000000 },
1544 { 0x00008258, 0x00000000 },
1545 { 0x0000825c, 0x400000ff },
1546 { 0x00008260, 0x00080922 },
1547 { 0x00008270, 0x00000000 },
1548 { 0x00008274, 0x40000000 },
1549 { 0x00008278, 0x003e4180 },
1550 { 0x0000827c, 0x00000000 },
1551 { 0x00008284, 0x0000002c },
1552 { 0x00008288, 0x0000002c },
1553 { 0x0000828c, 0x00000000 },
1554 { 0x00008294, 0x00000000 },
1555 { 0x00008298, 0x00000000 },
1556 { 0x00008300, 0x00000000 },
1557 { 0x00008304, 0x00000000 },
1558 { 0x00008308, 0x00000000 },
1559 { 0x0000830c, 0x00000000 },
1560 { 0x00008310, 0x00000000 },
1561 { 0x00008314, 0x00000000 },
1562 { 0x00008318, 0x00000000 },
1563 { 0x00008328, 0x00000000 },
1564 { 0x0000832c, 0x00000007 },
1565 { 0x00008330, 0x00000302 },
1566 { 0x00008334, 0x00000e00 },
1567 { 0x00008338, 0x00000000 },
1568 { 0x0000833c, 0x00000000 },
1569 { 0x00008340, 0x000107ff },
1570 { 0x00009808, 0x00000000 },
1571 { 0x0000980c, 0xad848e19 },
1572 { 0x00009810, 0x7d14e000 },
1573 { 0x00009814, 0x9c0a9f6b },
1574 { 0x0000981c, 0x00000000 },
1575 { 0x0000982c, 0x0000a000 },
1576 { 0x00009830, 0x00000000 },
1577 { 0x0000983c, 0x00200400 },
1578 { 0x00009840, 0x206a01ae },
1579 { 0x0000984c, 0x1284233c },
1580 { 0x00009854, 0x00000859 },
1581 { 0x00009900, 0x00000000 },
1582 { 0x00009904, 0x00000000 },
1583 { 0x00009908, 0x00000000 },
1584 { 0x0000990c, 0x00000000 },
1585 { 0x0000991c, 0x10000fff },
1586 { 0x00009920, 0x05100000 },
1587 { 0x0000a920, 0x05100000 },
1588 { 0x0000b920, 0x05100000 },
1589 { 0x00009928, 0x00000001 },
1590 { 0x0000992c, 0x00000004 },
1591 { 0x00009934, 0x1e1f2022 },
1592 { 0x00009938, 0x0a0b0c0d },
1593 { 0x0000993c, 0x00000000 },
1594 { 0x00009948, 0x9280b212 },
1595 { 0x0000994c, 0x00020028 },
1596 { 0x00009954, 0x5f3ca3de },
1597 { 0x00009958, 0x2108ecff },
1598 { 0x00009940, 0x00750604 },
1599 { 0x0000c95c, 0x004b6a8e },
1600 { 0x0000c968, 0x000003ce },
1601 { 0x00009970, 0x190fb515 },
1602 { 0x00009974, 0x00000000 },
1603 { 0x00009978, 0x00000001 },
1604 { 0x0000997c, 0x00000000 },
1605 { 0x00009980, 0x00000000 },
1606 { 0x00009984, 0x00000000 },
1607 { 0x00009988, 0x00000000 },
1608 { 0x0000998c, 0x00000000 },
1609 { 0x00009990, 0x00000000 },
1610 { 0x00009994, 0x00000000 },
1611 { 0x00009998, 0x00000000 },
1612 { 0x0000999c, 0x00000000 },
1613 { 0x000099a0, 0x00000000 },
1614 { 0x000099a4, 0x00000001 },
1615 { 0x000099a8, 0x201fff00 },
1616 { 0x000099ac, 0x006f0000 },
1617 { 0x000099b0, 0x03051000 },
1618 { 0x000099dc, 0x00000000 },
1619 { 0x000099e0, 0x00000200 },
1620 { 0x000099e4, 0xaaaaaaaa },
1621 { 0x000099e8, 0x3c466478 },
1622 { 0x000099ec, 0x0cc80caa },
1623 { 0x000099fc, 0x00001042 },
1624 { 0x00009b00, 0x00000000 },
1625 { 0x00009b04, 0x00000001 },
1626 { 0x00009b08, 0x00000002 },
1627 { 0x00009b0c, 0x00000003 },
1628 { 0x00009b10, 0x00000004 },
1629 { 0x00009b14, 0x00000005 },
1630 { 0x00009b18, 0x00000008 },
1631 { 0x00009b1c, 0x00000009 },
1632 { 0x00009b20, 0x0000000a },
1633 { 0x00009b24, 0x0000000b },
1634 { 0x00009b28, 0x0000000c },
1635 { 0x00009b2c, 0x0000000d },
1636 { 0x00009b30, 0x00000010 },
1637 { 0x00009b34, 0x00000011 },
1638 { 0x00009b38, 0x00000012 },
1639 { 0x00009b3c, 0x00000013 },
1640 { 0x00009b40, 0x00000014 },
1641 { 0x00009b44, 0x00000015 },
1642 { 0x00009b48, 0x00000018 },
1643 { 0x00009b4c, 0x00000019 },
1644 { 0x00009b50, 0x0000001a },
1645 { 0x00009b54, 0x0000001b },
1646 { 0x00009b58, 0x0000001c },
1647 { 0x00009b5c, 0x0000001d },
1648 { 0x00009b60, 0x00000020 },
1649 { 0x00009b64, 0x00000021 },
1650 { 0x00009b68, 0x00000022 },
1651 { 0x00009b6c, 0x00000023 },
1652 { 0x00009b70, 0x00000024 },
1653 { 0x00009b74, 0x00000025 },
1654 { 0x00009b78, 0x00000028 },
1655 { 0x00009b7c, 0x00000029 },
1656 { 0x00009b80, 0x0000002a },
1657 { 0x00009b84, 0x0000002b },
1658 { 0x00009b88, 0x0000002c },
1659 { 0x00009b8c, 0x0000002d },
1660 { 0x00009b90, 0x00000030 },
1661 { 0x00009b94, 0x00000031 },
1662 { 0x00009b98, 0x00000032 },
1663 { 0x00009b9c, 0x00000033 },
1664 { 0x00009ba0, 0x00000034 },
1665 { 0x00009ba4, 0x00000035 },
1666 { 0x00009ba8, 0x00000035 },
1667 { 0x00009bac, 0x00000035 },
1668 { 0x00009bb0, 0x00000035 },
1669 { 0x00009bb4, 0x00000035 },
1670 { 0x00009bb8, 0x00000035 },
1671 { 0x00009bbc, 0x00000035 },
1672 { 0x00009bc0, 0x00000035 },
1673 { 0x00009bc4, 0x00000035 },
1674 { 0x00009bc8, 0x00000035 },
1675 { 0x00009bcc, 0x00000035 },
1676 { 0x00009bd0, 0x00000035 },
1677 { 0x00009bd4, 0x00000035 },
1678 { 0x00009bd8, 0x00000035 },
1679 { 0x00009bdc, 0x00000035 },
1680 { 0x00009be0, 0x00000035 },
1681 { 0x00009be4, 0x00000035 },
1682 { 0x00009be8, 0x00000035 },
1683 { 0x00009bec, 0x00000035 },
1684 { 0x00009bf0, 0x00000035 },
1685 { 0x00009bf4, 0x00000035 },
1686 { 0x00009bf8, 0x00000010 },
1687 { 0x00009bfc, 0x0000001a },
1688 { 0x0000a210, 0x40806333 },
1689 { 0x0000a214, 0x00106c10 },
1690 { 0x0000a218, 0x009c4060 },
1691 { 0x0000a220, 0x018830c6 },
1692 { 0x0000a224, 0x00000400 },
1693 { 0x0000a228, 0x001a0bb5 },
1694 { 0x0000a22c, 0x00000000 },
1695 { 0x0000a234, 0x20202020 },
1696 { 0x0000a238, 0x20202020 },
1697 { 0x0000a23c, 0x13c889af },
1698 { 0x0000a240, 0x38490a20 },
1699 { 0x0000a244, 0x00007bb6 },
1700 { 0x0000a248, 0x0fff3ffc },
1701 { 0x0000a24c, 0x00000001 },
1702 { 0x0000a250, 0x0000a000 },
1703 { 0x0000a254, 0x00000000 },
1704 { 0x0000a258, 0x0cc75380 },
1705 { 0x0000a25c, 0x0f0f0f01 },
1706 { 0x0000a260, 0xdfa91f01 },
1707 { 0x0000a268, 0x00000001 },
1708 { 0x0000a26c, 0x0ebae9c6 },
1709 { 0x0000b26c, 0x0ebae9c6 },
1710 { 0x0000c26c, 0x0ebae9c6 },
1711 { 0x0000d270, 0x00820820 },
1712 { 0x0000a278, 0x1ce739ce },
1713 { 0x0000a27c, 0x050701ce },
1714 { 0x0000a338, 0x00000000 },
1715 { 0x0000a33c, 0x00000000 },
1716 { 0x0000a340, 0x00000000 },
1717 { 0x0000a344, 0x00000000 },
1718 { 0x0000a348, 0x3fffffff },
1719 { 0x0000a34c, 0x3fffffff },
1720 { 0x0000a350, 0x3fffffff },
1721 { 0x0000a354, 0x0003ffff },
1722 { 0x0000a358, 0x79a8aa33 },
1723 { 0x0000d35c, 0x07ffffef },
1724 { 0x0000d360, 0x0fffffe7 },
1725 { 0x0000d364, 0x17ffffe5 },
1726 { 0x0000d368, 0x1fffffe4 },
1727 { 0x0000d36c, 0x37ffffe3 },
1728 { 0x0000d370, 0x3fffffe3 },
1729 { 0x0000d374, 0x57ffffe3 },
1730 { 0x0000d378, 0x5fffffe2 },
1731 { 0x0000d37c, 0x7fffffe2 },
1732 { 0x0000d380, 0x7f3c7bba },
1733 { 0x0000d384, 0xf3307ff0 },
1734 { 0x0000a388, 0x0c000000 },
1735 { 0x0000a38c, 0x20202020 },
1736 { 0x0000a390, 0x20202020 },
1737 { 0x0000a394, 0x1ce739ce },
1738 { 0x0000a398, 0x000001ce },
1739 { 0x0000a39c, 0x00000001 },
1740 { 0x0000a3a0, 0x00000000 },
1741 { 0x0000a3a4, 0x00000000 },
1742 { 0x0000a3a8, 0x00000000 },
1743 { 0x0000a3ac, 0x00000000 },
1744 { 0x0000a3b0, 0x00000000 },
1745 { 0x0000a3b4, 0x00000000 },
1746 { 0x0000a3b8, 0x00000000 },
1747 { 0x0000a3bc, 0x00000000 },
1748 { 0x0000a3c0, 0x00000000 },
1749 { 0x0000a3c4, 0x00000000 },
1750 { 0x0000a3c8, 0x00000246 },
1751 { 0x0000a3cc, 0x20202020 },
1752 { 0x0000a3d0, 0x20202020 },
1753 { 0x0000a3d4, 0x20202020 },
1754 { 0x0000a3dc, 0x1ce739ce },
1755 { 0x0000a3e0, 0x000001ce },
1756};
1757
1758static const u32 ar5416Bank0_9160[][2] = {
1759 { 0x000098b0, 0x1e5795e5 },
1760 { 0x000098e0, 0x02008020 },
1761};
1762
1763static const u32 ar5416BB_RfGain_9160[][3] = {
1764 { 0x00009a00, 0x00000000, 0x00000000 },
1765 { 0x00009a04, 0x00000040, 0x00000040 },
1766 { 0x00009a08, 0x00000080, 0x00000080 },
1767 { 0x00009a0c, 0x000001a1, 0x00000141 },
1768 { 0x00009a10, 0x000001e1, 0x00000181 },
1769 { 0x00009a14, 0x00000021, 0x000001c1 },
1770 { 0x00009a18, 0x00000061, 0x00000001 },
1771 { 0x00009a1c, 0x00000168, 0x00000041 },
1772 { 0x00009a20, 0x000001a8, 0x000001a8 },
1773 { 0x00009a24, 0x000001e8, 0x000001e8 },
1774 { 0x00009a28, 0x00000028, 0x00000028 },
1775 { 0x00009a2c, 0x00000068, 0x00000068 },
1776 { 0x00009a30, 0x00000189, 0x000000a8 },
1777 { 0x00009a34, 0x000001c9, 0x00000169 },
1778 { 0x00009a38, 0x00000009, 0x000001a9 },
1779 { 0x00009a3c, 0x00000049, 0x000001e9 },
1780 { 0x00009a40, 0x00000089, 0x00000029 },
1781 { 0x00009a44, 0x00000170, 0x00000069 },
1782 { 0x00009a48, 0x000001b0, 0x00000190 },
1783 { 0x00009a4c, 0x000001f0, 0x000001d0 },
1784 { 0x00009a50, 0x00000030, 0x00000010 },
1785 { 0x00009a54, 0x00000070, 0x00000050 },
1786 { 0x00009a58, 0x00000191, 0x00000090 },
1787 { 0x00009a5c, 0x000001d1, 0x00000151 },
1788 { 0x00009a60, 0x00000011, 0x00000191 },
1789 { 0x00009a64, 0x00000051, 0x000001d1 },
1790 { 0x00009a68, 0x00000091, 0x00000011 },
1791 { 0x00009a6c, 0x000001b8, 0x00000051 },
1792 { 0x00009a70, 0x000001f8, 0x00000198 },
1793 { 0x00009a74, 0x00000038, 0x000001d8 },
1794 { 0x00009a78, 0x00000078, 0x00000018 },
1795 { 0x00009a7c, 0x00000199, 0x00000058 },
1796 { 0x00009a80, 0x000001d9, 0x00000098 },
1797 { 0x00009a84, 0x00000019, 0x00000159 },
1798 { 0x00009a88, 0x00000059, 0x00000199 },
1799 { 0x00009a8c, 0x00000099, 0x000001d9 },
1800 { 0x00009a90, 0x000000d9, 0x00000019 },
1801 { 0x00009a94, 0x000000f9, 0x00000059 },
1802 { 0x00009a98, 0x000000f9, 0x00000099 },
1803 { 0x00009a9c, 0x000000f9, 0x000000d9 },
1804 { 0x00009aa0, 0x000000f9, 0x000000f9 },
1805 { 0x00009aa4, 0x000000f9, 0x000000f9 },
1806 { 0x00009aa8, 0x000000f9, 0x000000f9 },
1807 { 0x00009aac, 0x000000f9, 0x000000f9 },
1808 { 0x00009ab0, 0x000000f9, 0x000000f9 },
1809 { 0x00009ab4, 0x000000f9, 0x000000f9 },
1810 { 0x00009ab8, 0x000000f9, 0x000000f9 },
1811 { 0x00009abc, 0x000000f9, 0x000000f9 },
1812 { 0x00009ac0, 0x000000f9, 0x000000f9 },
1813 { 0x00009ac4, 0x000000f9, 0x000000f9 },
1814 { 0x00009ac8, 0x000000f9, 0x000000f9 },
1815 { 0x00009acc, 0x000000f9, 0x000000f9 },
1816 { 0x00009ad0, 0x000000f9, 0x000000f9 },
1817 { 0x00009ad4, 0x000000f9, 0x000000f9 },
1818 { 0x00009ad8, 0x000000f9, 0x000000f9 },
1819 { 0x00009adc, 0x000000f9, 0x000000f9 },
1820 { 0x00009ae0, 0x000000f9, 0x000000f9 },
1821 { 0x00009ae4, 0x000000f9, 0x000000f9 },
1822 { 0x00009ae8, 0x000000f9, 0x000000f9 },
1823 { 0x00009aec, 0x000000f9, 0x000000f9 },
1824 { 0x00009af0, 0x000000f9, 0x000000f9 },
1825 { 0x00009af4, 0x000000f9, 0x000000f9 },
1826 { 0x00009af8, 0x000000f9, 0x000000f9 },
1827 { 0x00009afc, 0x000000f9, 0x000000f9 },
1828};
1829
1830static const u32 ar5416Bank1_9160[][2] = {
1831 { 0x000098b0, 0x02108421 },
1832 { 0x000098ec, 0x00000008 },
1833};
1834
1835static const u32 ar5416Bank2_9160[][2] = {
1836 { 0x000098b0, 0x0e73ff17 },
1837 { 0x000098e0, 0x00000420 },
1838};
1839
1840static const u32 ar5416Bank3_9160[][3] = {
1841 { 0x000098f0, 0x01400018, 0x01c00018 },
1842};
1843
1844static const u32 ar5416Bank6_9160[][3] = {
1845
1846 { 0x0000989c, 0x00000000, 0x00000000 },
1847 { 0x0000989c, 0x00000000, 0x00000000 },
1848 { 0x0000989c, 0x00000000, 0x00000000 },
1849 { 0x0000989c, 0x00e00000, 0x00e00000 },
1850 { 0x0000989c, 0x005e0000, 0x005e0000 },
1851 { 0x0000989c, 0x00120000, 0x00120000 },
1852 { 0x0000989c, 0x00620000, 0x00620000 },
1853 { 0x0000989c, 0x00020000, 0x00020000 },
1854 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1855 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1856 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1857 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1858 { 0x0000989c, 0x005f0000, 0x005f0000 },
1859 { 0x0000989c, 0x00870000, 0x00870000 },
1860 { 0x0000989c, 0x00f90000, 0x00f90000 },
1861 { 0x0000989c, 0x007b0000, 0x007b0000 },
1862 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1863 { 0x0000989c, 0x00f50000, 0x00f50000 },
1864 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1865 { 0x0000989c, 0x00110000, 0x00110000 },
1866 { 0x0000989c, 0x006100a8, 0x006100a8 },
1867 { 0x0000989c, 0x004210a2, 0x004210a2 },
1868 { 0x0000989c, 0x0014008f, 0x0014008f },
1869 { 0x0000989c, 0x00c40003, 0x00c40003 },
1870 { 0x0000989c, 0x003000f2, 0x003000f2 },
1871 { 0x0000989c, 0x00440016, 0x00440016 },
1872 { 0x0000989c, 0x00410040, 0x00410040 },
1873 { 0x0000989c, 0x0001805e, 0x0001805e },
1874 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1875 { 0x0000989c, 0x000000f1, 0x000000f1 },
1876 { 0x0000989c, 0x00002081, 0x00002081 },
1877 { 0x0000989c, 0x000000d4, 0x000000d4 },
1878 { 0x000098d0, 0x0000000f, 0x0010000f },
1879};
1880
1881static const u32 ar5416Bank6TPC_9160[][3] = {
1882 { 0x0000989c, 0x00000000, 0x00000000 },
1883 { 0x0000989c, 0x00000000, 0x00000000 },
1884 { 0x0000989c, 0x00000000, 0x00000000 },
1885 { 0x0000989c, 0x00e00000, 0x00e00000 },
1886 { 0x0000989c, 0x005e0000, 0x005e0000 },
1887 { 0x0000989c, 0x00120000, 0x00120000 },
1888 { 0x0000989c, 0x00620000, 0x00620000 },
1889 { 0x0000989c, 0x00020000, 0x00020000 },
1890 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1891 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1892 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1893 { 0x0000989c, 0x40ff0000, 0x40ff0000 },
1894 { 0x0000989c, 0x005f0000, 0x005f0000 },
1895 { 0x0000989c, 0x00870000, 0x00870000 },
1896 { 0x0000989c, 0x00f90000, 0x00f90000 },
1897 { 0x0000989c, 0x007b0000, 0x007b0000 },
1898 { 0x0000989c, 0x00ff0000, 0x00ff0000 },
1899 { 0x0000989c, 0x00f50000, 0x00f50000 },
1900 { 0x0000989c, 0x00dc0000, 0x00dc0000 },
1901 { 0x0000989c, 0x00110000, 0x00110000 },
1902 { 0x0000989c, 0x006100a8, 0x006100a8 },
1903 { 0x0000989c, 0x00423022, 0x00423022 },
1904 { 0x0000989c, 0x2014008f, 0x2014008f },
1905 { 0x0000989c, 0x00c40002, 0x00c40002 },
1906 { 0x0000989c, 0x003000f2, 0x003000f2 },
1907 { 0x0000989c, 0x00440016, 0x00440016 },
1908 { 0x0000989c, 0x00410040, 0x00410040 },
1909 { 0x0000989c, 0x0001805e, 0x0001805e },
1910 { 0x0000989c, 0x0000c0ab, 0x0000c0ab },
1911 { 0x0000989c, 0x000000e1, 0x000000e1 },
1912 { 0x0000989c, 0x00007080, 0x00007080 },
1913 { 0x0000989c, 0x000000d4, 0x000000d4 },
1914 { 0x000098d0, 0x0000000f, 0x0010000f },
1915};
1916
1917static const u32 ar5416Bank7_9160[][2] = {
1918 { 0x0000989c, 0x00000500 },
1919 { 0x0000989c, 0x00000800 },
1920 { 0x000098cc, 0x0000000e },
1921};
1922
1923
1924static u32 ar5416Addac_9160[][2] = {
1925 {0x0000989c, 0x00000000 },
1926 {0x0000989c, 0x00000000 },
1927 {0x0000989c, 0x00000000 },
1928 {0x0000989c, 0x00000000 },
1929 {0x0000989c, 0x00000000 },
1930 {0x0000989c, 0x00000000 },
1931 {0x0000989c, 0x000000c0 },
1932 {0x0000989c, 0x00000018 },
1933 {0x0000989c, 0x00000004 },
1934 {0x0000989c, 0x00000000 },
1935 {0x0000989c, 0x00000000 },
1936 {0x0000989c, 0x00000000 },
1937 {0x0000989c, 0x00000000 },
1938 {0x0000989c, 0x00000000 },
1939 {0x0000989c, 0x00000000 },
1940 {0x0000989c, 0x00000000 },
1941 {0x0000989c, 0x00000000 },
1942 {0x0000989c, 0x00000000 },
1943 {0x0000989c, 0x00000000 },
1944 {0x0000989c, 0x00000000 },
1945 {0x0000989c, 0x00000000 },
1946 {0x0000989c, 0x000000c0 },
1947 {0x0000989c, 0x00000019 },
1948 {0x0000989c, 0x00000004 },
1949 {0x0000989c, 0x00000000 },
1950 {0x0000989c, 0x00000000 },
1951 {0x0000989c, 0x00000000 },
1952 {0x0000989c, 0x00000004 },
1953 {0x0000989c, 0x00000003 },
1954 {0x0000989c, 0x00000008 },
1955 {0x0000989c, 0x00000000 },
1956 {0x000098cc, 0x00000000 },
1957};
1958
1959
1960static u32 ar5416Addac_91601_1[][2] = {
1961 {0x0000989c, 0x00000000 },
1962 {0x0000989c, 0x00000000 },
1963 {0x0000989c, 0x00000000 },
1964 {0x0000989c, 0x00000000 },
1965 {0x0000989c, 0x00000000 },
1966 {0x0000989c, 0x00000000 },
1967 {0x0000989c, 0x000000c0 },
1968 {0x0000989c, 0x00000018 },
1969 {0x0000989c, 0x00000004 },
1970 {0x0000989c, 0x00000000 },
1971 {0x0000989c, 0x00000000 },
1972 {0x0000989c, 0x00000000 },
1973 {0x0000989c, 0x00000000 },
1974 {0x0000989c, 0x00000000 },
1975 {0x0000989c, 0x00000000 },
1976 {0x0000989c, 0x00000000 },
1977 {0x0000989c, 0x00000000 },
1978 {0x0000989c, 0x00000000 },
1979 {0x0000989c, 0x00000000 },
1980 {0x0000989c, 0x00000000 },
1981 {0x0000989c, 0x00000000 },
1982 {0x0000989c, 0x000000c0 },
1983 {0x0000989c, 0x00000019 },
1984 {0x0000989c, 0x00000004 },
1985 {0x0000989c, 0x00000000 },
1986 {0x0000989c, 0x00000000 },
1987 {0x0000989c, 0x00000000 },
1988 {0x0000989c, 0x00000000 },
1989 {0x0000989c, 0x00000000 },
1990 {0x0000989c, 0x00000000 },
1991 {0x0000989c, 0x00000000 },
1992 {0x000098cc, 0x00000000 },
1993};
1994
1995
1996
1997static const u32 ar9280Modes_9280[][6] = {
1998 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
1999 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
2000 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
2001 { 0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008 },
2002 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801080, 0x08400840, 0x06e006e0 },
2003 { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
2004 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
2005 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
2006 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
2007 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
2008 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
2009 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
2010 { 0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0 },
2011 { 0x00009848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 },
2012 { 0x0000a848, 0x00028566, 0x00028566, 0x00028563, 0x00028563, 0x00028563 },
2013 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
2014 { 0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e },
2015 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
2016 { 0x00009860, 0x00049d18, 0x00049d18, 0x00049d20, 0x00049d20, 0x00049d18 },
2017 { 0x0000c864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
2018 { 0x00009868, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190, 0x5ac64190 },
2019 { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
2020 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
2021 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
2022 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
2023 { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010 },
2024 { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
2025 { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
2026 { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 },
2027 { 0x0000c9b8, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a },
2028 { 0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
2029 { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
2030 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
2031 { 0x000099c8, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c, 0x60f6532c },
2032 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
2033 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
2034 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2035 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2036 { 0x00009a00, 0x00008184, 0x00008184, 0x00000214, 0x00000214, 0x00000214 },
2037 { 0x00009a04, 0x00008188, 0x00008188, 0x00000218, 0x00000218, 0x00000218 },
2038 { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000224, 0x00000224, 0x00000224 },
2039 { 0x00009a0c, 0x00008190, 0x00008190, 0x00000228, 0x00000228, 0x00000228 },
2040 { 0x00009a10, 0x00008194, 0x00008194, 0x0000022c, 0x0000022c, 0x0000022c },
2041 { 0x00009a14, 0x00008200, 0x00008200, 0x00000230, 0x00000230, 0x00000230 },
2042 { 0x00009a18, 0x00008204, 0x00008204, 0x000002a4, 0x000002a4, 0x000002a4 },
2043 { 0x00009a1c, 0x00008208, 0x00008208, 0x000002a8, 0x000002a8, 0x000002a8 },
2044 { 0x00009a20, 0x0000820c, 0x0000820c, 0x000002ac, 0x000002ac, 0x000002ac },
2045 { 0x00009a24, 0x00008210, 0x00008210, 0x000002b0, 0x000002b0, 0x000002b0 },
2046 { 0x00009a28, 0x00008214, 0x00008214, 0x000002b4, 0x000002b4, 0x000002b4 },
2047 { 0x00009a2c, 0x00008280, 0x00008280, 0x000002b8, 0x000002b8, 0x000002b8 },
2048 { 0x00009a30, 0x00008284, 0x00008284, 0x00000390, 0x00000390, 0x00000390 },
2049 { 0x00009a34, 0x00008288, 0x00008288, 0x00000394, 0x00000394, 0x00000394 },
2050 { 0x00009a38, 0x0000828c, 0x0000828c, 0x00000398, 0x00000398, 0x00000398 },
2051 { 0x00009a3c, 0x00008290, 0x00008290, 0x00000334, 0x00000334, 0x00000334 },
2052 { 0x00009a40, 0x00008300, 0x00008300, 0x00000338, 0x00000338, 0x00000338 },
2053 { 0x00009a44, 0x00008304, 0x00008304, 0x000003ac, 0x000003ac, 0x000003ac },
2054 { 0x00009a48, 0x00008308, 0x00008308, 0x000003b0, 0x000003b0, 0x000003b0 },
2055 { 0x00009a4c, 0x0000830c, 0x0000830c, 0x000003b4, 0x000003b4, 0x000003b4 },
2056 { 0x00009a50, 0x00008310, 0x00008310, 0x000003b8, 0x000003b8, 0x000003b8 },
2057 { 0x00009a54, 0x00008314, 0x00008314, 0x000003a5, 0x000003a5, 0x000003a5 },
2058 { 0x00009a58, 0x00008380, 0x00008380, 0x000003a9, 0x000003a9, 0x000003a9 },
2059 { 0x00009a5c, 0x00008384, 0x00008384, 0x000003ad, 0x000003ad, 0x000003ad },
2060 { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
2061 { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
2062 { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
2063 { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
2064 { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
2065 { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
2066 { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
2067 { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
2068 { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
2069 { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
2070 { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
2071 { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
2072 { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
2073 { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
2074 { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
2075 { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
2076 { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
2077 { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
2078 { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
2079 { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
2080 { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
2081 { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
2082 { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
2083 { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
2084 { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
2085 { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
2086 { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
2087 { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
2088 { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
2089 { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
2090 { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
2091 { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
2092 { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
2093 { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
2094 { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c },
2095 { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 },
2096 { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 },
2097 { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 },
2098 { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 },
2099 { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 },
2100 { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 },
2101 { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 },
2102 { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 },
2103 { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 },
2104 { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 },
2105 { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 },
2106 { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 },
2107 { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c },
2108 { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 },
2109 { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 },
2110 { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 },
2111 { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 },
2112 { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 },
2113 { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 },
2114 { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 },
2115 { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 },
2116 { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad },
2117 { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 },
2118 { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 },
2119 { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 },
2120 { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 },
2121 { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 },
2122 { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 },
2123 { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 },
2124 { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 },
2125 { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 },
2126 { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca },
2127 { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce },
2128 { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 },
2129 { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 },
2130 { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 },
2131 { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 },
2132 { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb },
2133 { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf },
2134 { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 },
2135 { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db },
2136 { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db },
2137 { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db },
2138 { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2139 { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2140 { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2141 { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2142 { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2143 { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2144 { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2145 { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2146 { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2147 { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2148 { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2149 { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2150 { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2151 { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2152 { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2153 { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2154 { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2155 { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2156 { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2157 { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2158 { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2159 { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2160 { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2161 { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2162 { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2163 { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2164 { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 },
2165 { 0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788 },
2166 { 0x0000a20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 },
2167 { 0x0000b20c, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019, 0x000c6019 },
2168 { 0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a },
2169 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
2170 { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
2171 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2172 { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 },
2173 { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 },
2174 { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b },
2175 { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 },
2176 { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 },
2177 { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a },
2178 { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 },
2179 { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
2180 { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b },
2181 { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 },
2182 { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 },
2183 { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a },
2184 { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 },
2185 { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b },
2186 { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 },
2187 { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 },
2188 { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a },
2189 { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 },
2190 { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a },
2191 { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 },
2192 { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
2193 { 0x0000784c, 0x0e4f048c, 0x0e4f048c, 0x0e4d048c, 0x0e4d048c, 0x0e4d048c },
2194 { 0x00007854, 0x12031828, 0x12031828, 0x12035828, 0x12035828, 0x12035828 },
2195 { 0x00007870, 0x807ec400, 0x807ec400, 0x807ec000, 0x807ec000, 0x807ec000 },
2196 { 0x0000788c, 0x00010000, 0x00010000, 0x00110000, 0x00110000, 0x00110000 },
2197};
2198
2199static const u32 ar9280Common_9280[][2] = {
2200 { 0x0000000c, 0x00000000 },
2201 { 0x00000030, 0x00020015 },
2202 { 0x00000034, 0x00000005 },
2203 { 0x00000040, 0x00000000 },
2204 { 0x00000044, 0x00000008 },
2205 { 0x00000048, 0x00000008 },
2206 { 0x0000004c, 0x00000010 },
2207 { 0x00000050, 0x00000000 },
2208 { 0x00000054, 0x0000001f },
2209 { 0x00000800, 0x00000000 },
2210 { 0x00000804, 0x00000000 },
2211 { 0x00000808, 0x00000000 },
2212 { 0x0000080c, 0x00000000 },
2213 { 0x00000810, 0x00000000 },
2214 { 0x00000814, 0x00000000 },
2215 { 0x00000818, 0x00000000 },
2216 { 0x0000081c, 0x00000000 },
2217 { 0x00000820, 0x00000000 },
2218 { 0x00000824, 0x00000000 },
2219 { 0x00001040, 0x002ffc0f },
2220 { 0x00001044, 0x002ffc0f },
2221 { 0x00001048, 0x002ffc0f },
2222 { 0x0000104c, 0x002ffc0f },
2223 { 0x00001050, 0x002ffc0f },
2224 { 0x00001054, 0x002ffc0f },
2225 { 0x00001058, 0x002ffc0f },
2226 { 0x0000105c, 0x002ffc0f },
2227 { 0x00001060, 0x002ffc0f },
2228 { 0x00001064, 0x002ffc0f },
2229 { 0x00001230, 0x00000000 },
2230 { 0x00001270, 0x00000000 },
2231 { 0x00001038, 0x00000000 },
2232 { 0x00001078, 0x00000000 },
2233 { 0x000010b8, 0x00000000 },
2234 { 0x000010f8, 0x00000000 },
2235 { 0x00001138, 0x00000000 },
2236 { 0x00001178, 0x00000000 },
2237 { 0x000011b8, 0x00000000 },
2238 { 0x000011f8, 0x00000000 },
2239 { 0x00001238, 0x00000000 },
2240 { 0x00001278, 0x00000000 },
2241 { 0x000012b8, 0x00000000 },
2242 { 0x000012f8, 0x00000000 },
2243 { 0x00001338, 0x00000000 },
2244 { 0x00001378, 0x00000000 },
2245 { 0x000013b8, 0x00000000 },
2246 { 0x000013f8, 0x00000000 },
2247 { 0x00001438, 0x00000000 },
2248 { 0x00001478, 0x00000000 },
2249 { 0x000014b8, 0x00000000 },
2250 { 0x000014f8, 0x00000000 },
2251 { 0x00001538, 0x00000000 },
2252 { 0x00001578, 0x00000000 },
2253 { 0x000015b8, 0x00000000 },
2254 { 0x000015f8, 0x00000000 },
2255 { 0x00001638, 0x00000000 },
2256 { 0x00001678, 0x00000000 },
2257 { 0x000016b8, 0x00000000 },
2258 { 0x000016f8, 0x00000000 },
2259 { 0x00001738, 0x00000000 },
2260 { 0x00001778, 0x00000000 },
2261 { 0x000017b8, 0x00000000 },
2262 { 0x000017f8, 0x00000000 },
2263 { 0x0000103c, 0x00000000 },
2264 { 0x0000107c, 0x00000000 },
2265 { 0x000010bc, 0x00000000 },
2266 { 0x000010fc, 0x00000000 },
2267 { 0x0000113c, 0x00000000 },
2268 { 0x0000117c, 0x00000000 },
2269 { 0x000011bc, 0x00000000 },
2270 { 0x000011fc, 0x00000000 },
2271 { 0x0000123c, 0x00000000 },
2272 { 0x0000127c, 0x00000000 },
2273 { 0x000012bc, 0x00000000 },
2274 { 0x000012fc, 0x00000000 },
2275 { 0x0000133c, 0x00000000 },
2276 { 0x0000137c, 0x00000000 },
2277 { 0x000013bc, 0x00000000 },
2278 { 0x000013fc, 0x00000000 },
2279 { 0x0000143c, 0x00000000 },
2280 { 0x0000147c, 0x00000000 },
2281 { 0x00004030, 0x00000002 },
2282 { 0x0000403c, 0x00000002 },
2283 { 0x00004024, 0x0000001f },
2284 { 0x00007010, 0x00000033 },
2285 { 0x00007038, 0x000004c2 },
2286 { 0x00008004, 0x00000000 },
2287 { 0x00008008, 0x00000000 },
2288 { 0x0000800c, 0x00000000 },
2289 { 0x00008018, 0x00000700 },
2290 { 0x00008020, 0x00000000 },
2291 { 0x00008038, 0x00000000 },
2292 { 0x0000803c, 0x00000000 },
2293 { 0x00008048, 0x40000000 },
2294 { 0x00008054, 0x00000000 },
2295 { 0x00008058, 0x00000000 },
2296 { 0x0000805c, 0x000fc78f },
2297 { 0x00008060, 0x0000000f },
2298 { 0x00008064, 0x00000000 },
2299 { 0x00008070, 0x00000000 },
2300 { 0x000080c0, 0x2a82301a },
2301 { 0x000080c4, 0x05dc01e0 },
2302 { 0x000080c8, 0x1f402710 },
2303 { 0x000080cc, 0x01f40000 },
2304 { 0x000080d0, 0x00001e00 },
2305 { 0x000080d4, 0x00000000 },
2306 { 0x000080d8, 0x00400000 },
2307 { 0x000080e0, 0xffffffff },
2308 { 0x000080e4, 0x0000ffff },
2309 { 0x000080e8, 0x003f3f3f },
2310 { 0x000080ec, 0x00000000 },
2311 { 0x000080f0, 0x00000000 },
2312 { 0x000080f4, 0x00000000 },
2313 { 0x000080f8, 0x00000000 },
2314 { 0x000080fc, 0x00020000 },
2315 { 0x00008100, 0x00020000 },
2316 { 0x00008104, 0x00000001 },
2317 { 0x00008108, 0x00000052 },
2318 { 0x0000810c, 0x00000000 },
2319 { 0x00008110, 0x00000168 },
2320 { 0x00008118, 0x000100aa },
2321 { 0x0000811c, 0x00003210 },
2322 { 0x00008120, 0x08f04800 },
2323 { 0x00008124, 0x00000000 },
2324 { 0x00008128, 0x00000000 },
2325 { 0x0000812c, 0x00000000 },
2326 { 0x00008130, 0x00000000 },
2327 { 0x00008134, 0x00000000 },
2328 { 0x00008138, 0x00000000 },
2329 { 0x0000813c, 0x00000000 },
2330 { 0x00008144, 0x00000000 },
2331 { 0x00008168, 0x00000000 },
2332 { 0x0000816c, 0x00000000 },
2333 { 0x00008170, 0x32143320 },
2334 { 0x00008174, 0xfaa4fa50 },
2335 { 0x00008178, 0x00000100 },
2336 { 0x0000817c, 0x00000000 },
2337 { 0x000081c4, 0x00000000 },
2338 { 0x000081d0, 0x00003210 },
2339 { 0x000081ec, 0x00000000 },
2340 { 0x000081f0, 0x00000000 },
2341 { 0x000081f4, 0x00000000 },
2342 { 0x000081f8, 0x00000000 },
2343 { 0x000081fc, 0x00000000 },
2344 { 0x00008200, 0x00000000 },
2345 { 0x00008204, 0x00000000 },
2346 { 0x00008208, 0x00000000 },
2347 { 0x0000820c, 0x00000000 },
2348 { 0x00008210, 0x00000000 },
2349 { 0x00008214, 0x00000000 },
2350 { 0x00008218, 0x00000000 },
2351 { 0x0000821c, 0x00000000 },
2352 { 0x00008220, 0x00000000 },
2353 { 0x00008224, 0x00000000 },
2354 { 0x00008228, 0x00000000 },
2355 { 0x0000822c, 0x00000000 },
2356 { 0x00008230, 0x00000000 },
2357 { 0x00008234, 0x00000000 },
2358 { 0x00008238, 0x00000000 },
2359 { 0x0000823c, 0x00000000 },
2360 { 0x00008240, 0x00100000 },
2361 { 0x00008244, 0x0010f400 },
2362 { 0x00008248, 0x00000100 },
2363 { 0x0000824c, 0x0001e800 },
2364 { 0x00008250, 0x00000000 },
2365 { 0x00008254, 0x00000000 },
2366 { 0x00008258, 0x00000000 },
2367 { 0x0000825c, 0x400000ff },
2368 { 0x00008260, 0x00080922 },
2369 { 0x00008270, 0x00000000 },
2370 { 0x00008274, 0x40000000 },
2371 { 0x00008278, 0x003e4180 },
2372 { 0x0000827c, 0x00000000 },
2373 { 0x00008284, 0x0000002c },
2374 { 0x00008288, 0x0000002c },
2375 { 0x0000828c, 0x00000000 },
2376 { 0x00008294, 0x00000000 },
2377 { 0x00008298, 0x00000000 },
2378 { 0x00008300, 0x00000000 },
2379 { 0x00008304, 0x00000000 },
2380 { 0x00008308, 0x00000000 },
2381 { 0x0000830c, 0x00000000 },
2382 { 0x00008310, 0x00000000 },
2383 { 0x00008314, 0x00000000 },
2384 { 0x00008318, 0x00000000 },
2385 { 0x00008328, 0x00000000 },
2386 { 0x0000832c, 0x00000007 },
2387 { 0x00008330, 0x00000302 },
2388 { 0x00008334, 0x00000e00 },
2389 { 0x00008338, 0x00000000 },
2390 { 0x0000833c, 0x00000000 },
2391 { 0x00008340, 0x000107ff },
2392 { 0x00008344, 0x00000000 },
2393 { 0x00009808, 0x00000000 },
2394 { 0x0000980c, 0xaf268e30 },
2395 { 0x00009810, 0xfd14e000 },
2396 { 0x00009814, 0x9c0a9f6b },
2397 { 0x0000981c, 0x00000000 },
2398 { 0x0000982c, 0x0000a000 },
2399 { 0x00009830, 0x00000000 },
2400 { 0x0000983c, 0x00200400 },
2401 { 0x00009840, 0x206a01ae },
2402 { 0x0000984c, 0x0040233c },
2403 { 0x0000a84c, 0x0040233c },
2404 { 0x00009854, 0x00000044 },
2405 { 0x00009900, 0x00000000 },
2406 { 0x00009904, 0x00000000 },
2407 { 0x00009908, 0x00000000 },
2408 { 0x0000990c, 0x00000000 },
2409 { 0x0000991c, 0x10000fff },
2410 { 0x00009920, 0x04900000 },
2411 { 0x0000a920, 0x04900000 },
2412 { 0x00009928, 0x00000001 },
2413 { 0x0000992c, 0x00000004 },
2414 { 0x00009934, 0x1e1f2022 },
2415 { 0x00009938, 0x0a0b0c0d },
2416 { 0x0000993c, 0x00000000 },
2417 { 0x00009948, 0x9280c00a },
2418 { 0x0000994c, 0x00020028 },
2419 { 0x00009954, 0xe250a51e },
2420 { 0x00009958, 0x3388ffff },
2421 { 0x00009940, 0x00781204 },
2422 { 0x0000c95c, 0x004b6a8e },
2423 { 0x0000c968, 0x000003ce },
2424 { 0x00009970, 0x190fb514 },
2425 { 0x00009974, 0x00000000 },
2426 { 0x00009978, 0x00000001 },
2427 { 0x0000997c, 0x00000000 },
2428 { 0x00009980, 0x00000000 },
2429 { 0x00009984, 0x00000000 },
2430 { 0x00009988, 0x00000000 },
2431 { 0x0000998c, 0x00000000 },
2432 { 0x00009990, 0x00000000 },
2433 { 0x00009994, 0x00000000 },
2434 { 0x00009998, 0x00000000 },
2435 { 0x0000999c, 0x00000000 },
2436 { 0x000099a0, 0x00000000 },
2437 { 0x000099a4, 0x00000001 },
2438 { 0x000099a8, 0x201fff00 },
2439 { 0x000099ac, 0x006f00c4 },
2440 { 0x000099b0, 0x03051000 },
2441 { 0x000099b4, 0x00000820 },
2442 { 0x000099dc, 0x00000000 },
2443 { 0x000099e0, 0x00000000 },
2444 { 0x000099e4, 0xaaaaaaaa },
2445 { 0x000099e8, 0x3c466478 },
2446 { 0x000099ec, 0x0cc80caa },
2447 { 0x000099fc, 0x00001042 },
2448 { 0x0000a210, 0x4080a333 },
2449 { 0x0000a214, 0x40206c10 },
2450 { 0x0000a218, 0x009c4060 },
2451 { 0x0000a220, 0x01834061 },
2452 { 0x0000a224, 0x00000400 },
2453 { 0x0000a228, 0x000003b5 },
2454 { 0x0000a22c, 0x23277200 },
2455 { 0x0000a234, 0x20202020 },
2456 { 0x0000a238, 0x20202020 },
2457 { 0x0000a23c, 0x13c889af },
2458 { 0x0000a240, 0x38490a20 },
2459 { 0x0000a244, 0x00007bb6 },
2460 { 0x0000a248, 0x0fff3ffc },
2461 { 0x0000a24c, 0x00000001 },
2462 { 0x0000a250, 0x001da000 },
2463 { 0x0000a254, 0x00000000 },
2464 { 0x0000a258, 0x0cdbd380 },
2465 { 0x0000a25c, 0x0f0f0f01 },
2466 { 0x0000a260, 0xdfa91f01 },
2467 { 0x0000a268, 0x00000000 },
2468 { 0x0000a26c, 0x0ebae9c6 },
2469 { 0x0000b26c, 0x0ebae9c6 },
2470 { 0x0000d270, 0x00820820 },
2471 { 0x0000a278, 0x1ce739ce },
2472 { 0x0000a27c, 0x050701ce },
2473 { 0x0000a358, 0x7999aa0f },
2474 { 0x0000d35c, 0x07ffffef },
2475 { 0x0000d360, 0x0fffffe7 },
2476 { 0x0000d364, 0x17ffffe5 },
2477 { 0x0000d368, 0x1fffffe4 },
2478 { 0x0000d36c, 0x37ffffe3 },
2479 { 0x0000d370, 0x3fffffe3 },
2480 { 0x0000d374, 0x57ffffe3 },
2481 { 0x0000d378, 0x5fffffe2 },
2482 { 0x0000d37c, 0x7fffffe2 },
2483 { 0x0000d380, 0x7f3c7bba },
2484 { 0x0000d384, 0xf3307ff0 },
2485 { 0x0000a388, 0x0c000000 },
2486 { 0x0000a38c, 0x20202020 },
2487 { 0x0000a390, 0x20202020 },
2488 { 0x0000a394, 0x1ce739ce },
2489 { 0x0000a398, 0x000001ce },
2490 { 0x0000a39c, 0x00000001 },
2491 { 0x0000a3a0, 0x00000000 },
2492 { 0x0000a3a4, 0x00000000 },
2493 { 0x0000a3a8, 0x00000000 },
2494 { 0x0000a3ac, 0x00000000 },
2495 { 0x0000a3b0, 0x00000000 },
2496 { 0x0000a3b4, 0x00000000 },
2497 { 0x0000a3b8, 0x00000000 },
2498 { 0x0000a3bc, 0x00000000 },
2499 { 0x0000a3c0, 0x00000000 },
2500 { 0x0000a3c4, 0x00000000 },
2501 { 0x0000a3c8, 0x00000246 },
2502 { 0x0000a3cc, 0x20202020 },
2503 { 0x0000a3d0, 0x20202020 },
2504 { 0x0000a3d4, 0x20202020 },
2505 { 0x0000a3dc, 0x1ce739ce },
2506 { 0x0000a3e0, 0x000001ce },
2507 { 0x0000a3e4, 0x00000000 },
2508 { 0x0000a3e8, 0x18c43433 },
2509 { 0x0000a3ec, 0x00f38081 },
2510 { 0x00007800, 0x00040000 },
2511 { 0x00007804, 0xdb005012 },
2512 { 0x00007808, 0x04924914 },
2513 { 0x0000780c, 0x21084210 },
2514 { 0x00007810, 0x6d801300 },
2515 { 0x00007814, 0x0019beff },
2516 { 0x00007818, 0x07e40000 },
2517 { 0x0000781c, 0x00492000 },
2518 { 0x00007820, 0x92492480 },
2519 { 0x00007824, 0x00040000 },
2520 { 0x00007828, 0xdb005012 },
2521 { 0x0000782c, 0x04924914 },
2522 { 0x00007830, 0x21084210 },
2523 { 0x00007834, 0x6d801300 },
2524 { 0x00007838, 0x0019beff },
2525 { 0x0000783c, 0x07e40000 },
2526 { 0x00007840, 0x00492000 },
2527 { 0x00007844, 0x92492480 },
2528 { 0x00007848, 0x00120000 },
2529 { 0x00007850, 0x54214514 },
2530 { 0x00007858, 0x92592692 },
2531 { 0x00007860, 0x52802000 },
2532 { 0x00007864, 0x0a8e370e },
2533 { 0x00007868, 0xc0102850 },
2534 { 0x0000786c, 0x812d4000 },
2535 { 0x00007874, 0x001b6db0 },
2536 { 0x00007878, 0x00376b63 },
2537 { 0x0000787c, 0x06db6db6 },
2538 { 0x00007880, 0x006d8000 },
2539 { 0x00007884, 0xffeffffe },
2540 { 0x00007888, 0xffeffffe },
2541 { 0x00007890, 0x00060aeb },
2542 { 0x00007894, 0x5a108000 },
2543 { 0x00007898, 0x2a850160 },
2544};
2545
2546
2547
2548
2549static const u32 ar9280Modes_9280_2[][6] = {
2550 { 0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0 },
2551 { 0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0 },
2552 { 0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180 },
2553 { 0x000010f0, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000008 },
2554 { 0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0 },
2555 { 0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b, 0x0988004f },
2556 { 0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440, 0x00006880 },
2557 { 0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303 },
2558 { 0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200 },
2559 { 0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
2560 { 0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001 },
2561 { 0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e },
2562 { 0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 },
2563 { 0x00009840, 0x206a012e, 0x206a012e, 0x206a022e, 0x206a022e, 0x206a022e },
2564 { 0x00009844, 0x0372161e, 0x0372161e, 0x037216a0, 0x037216a0, 0x037216a0 },
2565 { 0x00009848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 },
2566 { 0x0000a848, 0x00001066, 0x00001066, 0x00001063, 0x00001063, 0x00001063 },
2567 { 0x00009850, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2, 0x6d4000e2 },
2568 { 0x00009858, 0x7ec84d2e, 0x7ec84d2e, 0x7ec88d2e, 0x7ec88d2e, 0x7ec88d2e },
2569 { 0x0000985c, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e },
2570 { 0x00009860, 0x00048d18, 0x00048d18, 0x00048d20, 0x00048d20, 0x00048d18 },
2571 { 0x0000c864, 0x0000fe00, 0x0000fe00, 0x0001ce00, 0x0001ce00, 0x0001ce00 },
2572 { 0x00009868, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0, 0x5ac640d0 },
2573 { 0x0000986c, 0x06903081, 0x06903081, 0x06903881, 0x06903881, 0x06903881 },
2574 { 0x00009914, 0x000007d0, 0x000007d0, 0x00000898, 0x00000898, 0x000007d0 },
2575 { 0x00009918, 0x0000000a, 0x00000014, 0x00000016, 0x0000000b, 0x00000016 },
2576 { 0x00009924, 0xd00a8a07, 0xd00a8a07, 0xd00a8a0d, 0xd00a8a0d, 0xd00a8a0d },
2577 { 0x00009944, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010, 0xdfbc1010 },
2578 { 0x00009960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
2579 { 0x0000a960, 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 },
2580 { 0x00009964, 0x00000210, 0x00000210, 0x00000210, 0x00000210, 0x00000210 },
2581 { 0x0000c9b8, 0x0000000f, 0x0000000f, 0x0000001c, 0x0000001c, 0x0000001c },
2582 { 0x0000c9bc, 0x00000600, 0x00000600, 0x00000c00, 0x00000c00, 0x00000c00 },
2583 { 0x000099c0, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4 },
2584 { 0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77 },
2585 { 0x000099c8, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329, 0x60f65329 },
2586 { 0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8 },
2587 { 0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384 },
2588 { 0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2589 { 0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2590 { 0x00009a00, 0x00008184, 0x00008184, 0x00000290, 0x00000290, 0x00000290 },
2591 { 0x00009a04, 0x00008188, 0x00008188, 0x00000300, 0x00000300, 0x00000300 },
2592 { 0x00009a08, 0x0000818c, 0x0000818c, 0x00000304, 0x00000304, 0x00000304 },
2593 { 0x00009a0c, 0x00008190, 0x00008190, 0x00000308, 0x00000308, 0x00000308 },
2594 { 0x00009a10, 0x00008194, 0x00008194, 0x0000030c, 0x0000030c, 0x0000030c },
2595 { 0x00009a14, 0x00008200, 0x00008200, 0x00008000, 0x00008000, 0x00008000 },
2596 { 0x00009a18, 0x00008204, 0x00008204, 0x00008004, 0x00008004, 0x00008004 },
2597 { 0x00009a1c, 0x00008208, 0x00008208, 0x00008008, 0x00008008, 0x00008008 },
2598 { 0x00009a20, 0x0000820c, 0x0000820c, 0x0000800c, 0x0000800c, 0x0000800c },
2599 { 0x00009a24, 0x00008210, 0x00008210, 0x00008080, 0x00008080, 0x00008080 },
2600 { 0x00009a28, 0x00008214, 0x00008214, 0x00008084, 0x00008084, 0x00008084 },
2601 { 0x00009a2c, 0x00008280, 0x00008280, 0x00008088, 0x00008088, 0x00008088 },
2602 { 0x00009a30, 0x00008284, 0x00008284, 0x0000808c, 0x0000808c, 0x0000808c },
2603 { 0x00009a34, 0x00008288, 0x00008288, 0x00008100, 0x00008100, 0x00008100 },
2604 { 0x00009a38, 0x0000828c, 0x0000828c, 0x00008104, 0x00008104, 0x00008104 },
2605 { 0x00009a3c, 0x00008290, 0x00008290, 0x00008108, 0x00008108, 0x00008108 },
2606 { 0x00009a40, 0x00008300, 0x00008300, 0x0000810c, 0x0000810c, 0x0000810c },
2607 { 0x00009a44, 0x00008304, 0x00008304, 0x00008110, 0x00008110, 0x00008110 },
2608 { 0x00009a48, 0x00008308, 0x00008308, 0x00008114, 0x00008114, 0x00008114 },
2609 { 0x00009a4c, 0x0000830c, 0x0000830c, 0x00008180, 0x00008180, 0x00008180 },
2610 { 0x00009a50, 0x00008310, 0x00008310, 0x00008184, 0x00008184, 0x00008184 },
2611 { 0x00009a54, 0x00008314, 0x00008314, 0x00008188, 0x00008188, 0x00008188 },
2612 { 0x00009a58, 0x00008380, 0x00008380, 0x0000818c, 0x0000818c, 0x0000818c },
2613 { 0x00009a5c, 0x00008384, 0x00008384, 0x00008190, 0x00008190, 0x00008190 },
2614 { 0x00009a60, 0x00008388, 0x00008388, 0x00008194, 0x00008194, 0x00008194 },
2615 { 0x00009a64, 0x0000838c, 0x0000838c, 0x000081a0, 0x000081a0, 0x000081a0 },
2616 { 0x00009a68, 0x00008390, 0x00008390, 0x0000820c, 0x0000820c, 0x0000820c },
2617 { 0x00009a6c, 0x00008394, 0x00008394, 0x000081a8, 0x000081a8, 0x000081a8 },
2618 { 0x00009a70, 0x0000a380, 0x0000a380, 0x00008284, 0x00008284, 0x00008284 },
2619 { 0x00009a74, 0x0000a384, 0x0000a384, 0x00008288, 0x00008288, 0x00008288 },
2620 { 0x00009a78, 0x0000a388, 0x0000a388, 0x00008224, 0x00008224, 0x00008224 },
2621 { 0x00009a7c, 0x0000a38c, 0x0000a38c, 0x00008290, 0x00008290, 0x00008290 },
2622 { 0x00009a80, 0x0000a390, 0x0000a390, 0x00008300, 0x00008300, 0x00008300 },
2623 { 0x00009a84, 0x0000a394, 0x0000a394, 0x00008304, 0x00008304, 0x00008304 },
2624 { 0x00009a88, 0x0000a780, 0x0000a780, 0x00008308, 0x00008308, 0x00008308 },
2625 { 0x00009a8c, 0x0000a784, 0x0000a784, 0x0000830c, 0x0000830c, 0x0000830c },
2626 { 0x00009a90, 0x0000a788, 0x0000a788, 0x00008380, 0x00008380, 0x00008380 },
2627 { 0x00009a94, 0x0000a78c, 0x0000a78c, 0x00008384, 0x00008384, 0x00008384 },
2628 { 0x00009a98, 0x0000a790, 0x0000a790, 0x00008700, 0x00008700, 0x00008700 },
2629 { 0x00009a9c, 0x0000a794, 0x0000a794, 0x00008704, 0x00008704, 0x00008704 },
2630 { 0x00009aa0, 0x0000ab84, 0x0000ab84, 0x00008708, 0x00008708, 0x00008708 },
2631 { 0x00009aa4, 0x0000ab88, 0x0000ab88, 0x0000870c, 0x0000870c, 0x0000870c },
2632 { 0x00009aa8, 0x0000ab8c, 0x0000ab8c, 0x00008780, 0x00008780, 0x00008780 },
2633 { 0x00009aac, 0x0000ab90, 0x0000ab90, 0x00008784, 0x00008784, 0x00008784 },
2634 { 0x00009ab0, 0x0000ab94, 0x0000ab94, 0x00008b00, 0x00008b00, 0x00008b00 },
2635 { 0x00009ab4, 0x0000af80, 0x0000af80, 0x00008b04, 0x00008b04, 0x00008b04 },
2636 { 0x00009ab8, 0x0000af84, 0x0000af84, 0x00008b08, 0x00008b08, 0x00008b08 },
2637 { 0x00009abc, 0x0000af88, 0x0000af88, 0x00008b0c, 0x00008b0c, 0x00008b0c },
2638 { 0x00009ac0, 0x0000af8c, 0x0000af8c, 0x00008b80, 0x00008b80, 0x00008b80 },
2639 { 0x00009ac4, 0x0000af90, 0x0000af90, 0x00008b84, 0x00008b84, 0x00008b84 },
2640 { 0x00009ac8, 0x0000af94, 0x0000af94, 0x00008b88, 0x00008b88, 0x00008b88 },
2641 { 0x00009acc, 0x0000b380, 0x0000b380, 0x00008b8c, 0x00008b8c, 0x00008b8c },
2642 { 0x00009ad0, 0x0000b384, 0x0000b384, 0x00008b90, 0x00008b90, 0x00008b90 },
2643 { 0x00009ad4, 0x0000b388, 0x0000b388, 0x00008f80, 0x00008f80, 0x00008f80 },
2644 { 0x00009ad8, 0x0000b38c, 0x0000b38c, 0x00008f84, 0x00008f84, 0x00008f84 },
2645 { 0x00009adc, 0x0000b390, 0x0000b390, 0x00008f88, 0x00008f88, 0x00008f88 },
2646 { 0x00009ae0, 0x0000b394, 0x0000b394, 0x00008f8c, 0x00008f8c, 0x00008f8c },
2647 { 0x00009ae4, 0x0000b398, 0x0000b398, 0x00008f90, 0x00008f90, 0x00008f90 },
2648 { 0x00009ae8, 0x0000b780, 0x0000b780, 0x0000930c, 0x0000930c, 0x0000930c },
2649 { 0x00009aec, 0x0000b784, 0x0000b784, 0x00009310, 0x00009310, 0x00009310 },
2650 { 0x00009af0, 0x0000b788, 0x0000b788, 0x00009384, 0x00009384, 0x00009384 },
2651 { 0x00009af4, 0x0000b78c, 0x0000b78c, 0x00009388, 0x00009388, 0x00009388 },
2652 { 0x00009af8, 0x0000b790, 0x0000b790, 0x00009324, 0x00009324, 0x00009324 },
2653 { 0x00009afc, 0x0000b794, 0x0000b794, 0x00009704, 0x00009704, 0x00009704 },
2654 { 0x00009b00, 0x0000b798, 0x0000b798, 0x000096a4, 0x000096a4, 0x000096a4 },
2655 { 0x00009b04, 0x0000d784, 0x0000d784, 0x000096a8, 0x000096a8, 0x000096a8 },
2656 { 0x00009b08, 0x0000d788, 0x0000d788, 0x00009710, 0x00009710, 0x00009710 },
2657 { 0x00009b0c, 0x0000d78c, 0x0000d78c, 0x00009714, 0x00009714, 0x00009714 },
2658 { 0x00009b10, 0x0000d790, 0x0000d790, 0x00009720, 0x00009720, 0x00009720 },
2659 { 0x00009b14, 0x0000f780, 0x0000f780, 0x00009724, 0x00009724, 0x00009724 },
2660 { 0x00009b18, 0x0000f784, 0x0000f784, 0x00009728, 0x00009728, 0x00009728 },
2661 { 0x00009b1c, 0x0000f788, 0x0000f788, 0x0000972c, 0x0000972c, 0x0000972c },
2662 { 0x00009b20, 0x0000f78c, 0x0000f78c, 0x000097a0, 0x000097a0, 0x000097a0 },
2663 { 0x00009b24, 0x0000f790, 0x0000f790, 0x000097a4, 0x000097a4, 0x000097a4 },
2664 { 0x00009b28, 0x0000f794, 0x0000f794, 0x000097a8, 0x000097a8, 0x000097a8 },
2665 { 0x00009b2c, 0x0000f7a4, 0x0000f7a4, 0x000097b0, 0x000097b0, 0x000097b0 },
2666 { 0x00009b30, 0x0000f7a8, 0x0000f7a8, 0x000097b4, 0x000097b4, 0x000097b4 },
2667 { 0x00009b34, 0x0000f7ac, 0x0000f7ac, 0x000097b8, 0x000097b8, 0x000097b8 },
2668 { 0x00009b38, 0x0000f7b0, 0x0000f7b0, 0x000097a5, 0x000097a5, 0x000097a5 },
2669 { 0x00009b3c, 0x0000f7b4, 0x0000f7b4, 0x000097a9, 0x000097a9, 0x000097a9 },
2670 { 0x00009b40, 0x0000f7a1, 0x0000f7a1, 0x000097ad, 0x000097ad, 0x000097ad },
2671 { 0x00009b44, 0x0000f7a5, 0x0000f7a5, 0x000097b1, 0x000097b1, 0x000097b1 },
2672 { 0x00009b48, 0x0000f7a9, 0x0000f7a9, 0x000097b5, 0x000097b5, 0x000097b5 },
2673 { 0x00009b4c, 0x0000f7ad, 0x0000f7ad, 0x000097b9, 0x000097b9, 0x000097b9 },
2674 { 0x00009b50, 0x0000f7b1, 0x0000f7b1, 0x000097c5, 0x000097c5, 0x000097c5 },
2675 { 0x00009b54, 0x0000f7b5, 0x0000f7b5, 0x000097c9, 0x000097c9, 0x000097c9 },
2676 { 0x00009b58, 0x0000f7c5, 0x0000f7c5, 0x000097d1, 0x000097d1, 0x000097d1 },
2677 { 0x00009b5c, 0x0000f7c9, 0x0000f7c9, 0x000097d5, 0x000097d5, 0x000097d5 },
2678 { 0x00009b60, 0x0000f7cd, 0x0000f7cd, 0x000097d9, 0x000097d9, 0x000097d9 },
2679 { 0x00009b64, 0x0000f7d1, 0x0000f7d1, 0x000097c6, 0x000097c6, 0x000097c6 },
2680 { 0x00009b68, 0x0000f7d5, 0x0000f7d5, 0x000097ca, 0x000097ca, 0x000097ca },
2681 { 0x00009b6c, 0x0000f7c2, 0x0000f7c2, 0x000097ce, 0x000097ce, 0x000097ce },
2682 { 0x00009b70, 0x0000f7c6, 0x0000f7c6, 0x000097d2, 0x000097d2, 0x000097d2 },
2683 { 0x00009b74, 0x0000f7ca, 0x0000f7ca, 0x000097d6, 0x000097d6, 0x000097d6 },
2684 { 0x00009b78, 0x0000f7ce, 0x0000f7ce, 0x000097c3, 0x000097c3, 0x000097c3 },
2685 { 0x00009b7c, 0x0000f7d2, 0x0000f7d2, 0x000097c7, 0x000097c7, 0x000097c7 },
2686 { 0x00009b80, 0x0000f7d6, 0x0000f7d6, 0x000097cb, 0x000097cb, 0x000097cb },
2687 { 0x00009b84, 0x0000f7c3, 0x0000f7c3, 0x000097cf, 0x000097cf, 0x000097cf },
2688 { 0x00009b88, 0x0000f7c7, 0x0000f7c7, 0x000097d7, 0x000097d7, 0x000097d7 },
2689 { 0x00009b8c, 0x0000f7cb, 0x0000f7cb, 0x000097db, 0x000097db, 0x000097db },
2690 { 0x00009b90, 0x0000f7d3, 0x0000f7d3, 0x000097db, 0x000097db, 0x000097db },
2691 { 0x00009b94, 0x0000f7d7, 0x0000f7d7, 0x000097db, 0x000097db, 0x000097db },
2692 { 0x00009b98, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2693 { 0x00009b9c, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2694 { 0x00009ba0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2695 { 0x00009ba4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2696 { 0x00009ba8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2697 { 0x00009bac, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2698 { 0x00009bb0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2699 { 0x00009bb4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2700 { 0x00009bb8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2701 { 0x00009bbc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2702 { 0x00009bc0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2703 { 0x00009bc4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2704 { 0x00009bc8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2705 { 0x00009bcc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2706 { 0x00009bd0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2707 { 0x00009bd4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2708 { 0x00009bd8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2709 { 0x00009bdc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2710 { 0x00009be0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2711 { 0x00009be4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2712 { 0x00009be8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2713 { 0x00009bec, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2714 { 0x00009bf0, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2715 { 0x00009bf4, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2716 { 0x00009bf8, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2717 { 0x00009bfc, 0x0000f7db, 0x0000f7db, 0x000097db, 0x000097db, 0x000097db },
2718 { 0x0000a204, 0x00000444, 0x00000444, 0x00000444, 0x00000444, 0x00000444 },
2719 { 0x0000a208, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788, 0x803e4788 },
2720 { 0x0000a20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 },
2721 { 0x0000b20c, 0x00000014, 0x00000014, 0x0001f019, 0x0001f019, 0x0001f019 },
2722 { 0x0000a21c, 0x1463800a, 0x1463800a, 0x1463800a, 0x1463800a, 0x1463800a },
2723 { 0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000 },
2724 { 0x0000a250, 0x001ff000, 0x001ff000, 0x001da000, 0x001da000, 0x001da000 },
2725 { 0x0000a274, 0x0a19c652, 0x0a19c652, 0x0a1aa652, 0x0a1aa652, 0x0a1aa652 },
2726 { 0x0000a300, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2727 { 0x0000a304, 0x00003002, 0x00003002, 0x00003002, 0x00003002, 0x00003002 },
2728 { 0x0000a308, 0x00006004, 0x00006004, 0x00008009, 0x00008009, 0x00008009 },
2729 { 0x0000a30c, 0x0000a006, 0x0000a006, 0x0000b00b, 0x0000b00b, 0x0000b00b },
2730 { 0x0000a310, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012, 0x0000e012 },
2731 { 0x0000a314, 0x00011014, 0x00011014, 0x00012048, 0x00012048, 0x00012048 },
2732 { 0x0000a318, 0x0001504a, 0x0001504a, 0x0001604a, 0x0001604a, 0x0001604a },
2733 { 0x0000a31c, 0x0001904c, 0x0001904c, 0x0001a211, 0x0001a211, 0x0001a211 },
2734 { 0x0000a320, 0x0001c04e, 0x0001c04e, 0x0001e213, 0x0001e213, 0x0001e213 },
2735 { 0x0000a324, 0x00020092, 0x00020092, 0x0002121b, 0x0002121b, 0x0002121b },
2736 { 0x0000a328, 0x0002410a, 0x0002410a, 0x00024412, 0x00024412, 0x00024412 },
2737 { 0x0000a32c, 0x0002710c, 0x0002710c, 0x00028414, 0x00028414, 0x00028414 },
2738 { 0x0000a330, 0x0002b18b, 0x0002b18b, 0x0002b44a, 0x0002b44a, 0x0002b44a },
2739 { 0x0000a334, 0x0002e1cc, 0x0002e1cc, 0x00030649, 0x00030649, 0x00030649 },
2740 { 0x0000a338, 0x000321ec, 0x000321ec, 0x0003364b, 0x0003364b, 0x0003364b },
2741 { 0x0000a33c, 0x000321ec, 0x000321ec, 0x00038a49, 0x00038a49, 0x00038a49 },
2742 { 0x0000a340, 0x000321ec, 0x000321ec, 0x0003be48, 0x0003be48, 0x0003be48 },
2743 { 0x0000a344, 0x000321ec, 0x000321ec, 0x0003ee4a, 0x0003ee4a, 0x0003ee4a },
2744 { 0x0000a348, 0x000321ec, 0x000321ec, 0x00042e88, 0x00042e88, 0x00042e88 },
2745 { 0x0000a34c, 0x000321ec, 0x000321ec, 0x00046e8a, 0x00046e8a, 0x00046e8a },
2746 { 0x0000a350, 0x000321ec, 0x000321ec, 0x00049ec9, 0x00049ec9, 0x00049ec9 },
2747 { 0x0000a354, 0x000321ec, 0x000321ec, 0x0004bf42, 0x0004bf42, 0x0004bf42 },
2748 { 0x0000a358, 0x7999aa02, 0x7999aa02, 0x7999aa0e, 0x7999aa0e, 0x7999aa0e },
2749 { 0x0000a3d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
2750 { 0x00007894, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000, 0x5a508000 },
2751};
2752
2753static const u32 ar9280Common_9280_2[][2] = {
2754 { 0x0000000c, 0x00000000 },
2755 { 0x00000030, 0x00020015 },
2756 { 0x00000034, 0x00000005 },
2757 { 0x00000040, 0x00000000 },
2758 { 0x00000044, 0x00000008 },
2759 { 0x00000048, 0x00000008 },
2760 { 0x0000004c, 0x00000010 },
2761 { 0x00000050, 0x00000000 },
2762 { 0x00000054, 0x0000001f },
2763 { 0x00000800, 0x00000000 },
2764 { 0x00000804, 0x00000000 },
2765 { 0x00000808, 0x00000000 },
2766 { 0x0000080c, 0x00000000 },
2767 { 0x00000810, 0x00000000 },
2768 { 0x00000814, 0x00000000 },
2769 { 0x00000818, 0x00000000 },
2770 { 0x0000081c, 0x00000000 },
2771 { 0x00000820, 0x00000000 },
2772 { 0x00000824, 0x00000000 },
2773 { 0x00001040, 0x002ffc0f },
2774 { 0x00001044, 0x002ffc0f },
2775 { 0x00001048, 0x002ffc0f },
2776 { 0x0000104c, 0x002ffc0f },
2777 { 0x00001050, 0x002ffc0f },
2778 { 0x00001054, 0x002ffc0f },
2779 { 0x00001058, 0x002ffc0f },
2780 { 0x0000105c, 0x002ffc0f },
2781 { 0x00001060, 0x002ffc0f },
2782 { 0x00001064, 0x002ffc0f },
2783 { 0x00001230, 0x00000000 },
2784 { 0x00001270, 0x00000000 },
2785 { 0x00001038, 0x00000000 },
2786 { 0x00001078, 0x00000000 },
2787 { 0x000010b8, 0x00000000 },
2788 { 0x000010f8, 0x00000000 },
2789 { 0x00001138, 0x00000000 },
2790 { 0x00001178, 0x00000000 },
2791 { 0x000011b8, 0x00000000 },
2792 { 0x000011f8, 0x00000000 },
2793 { 0x00001238, 0x00000000 },
2794 { 0x00001278, 0x00000000 },
2795 { 0x000012b8, 0x00000000 },
2796 { 0x000012f8, 0x00000000 },
2797 { 0x00001338, 0x00000000 },
2798 { 0x00001378, 0x00000000 },
2799 { 0x000013b8, 0x00000000 },
2800 { 0x000013f8, 0x00000000 },
2801 { 0x00001438, 0x00000000 },
2802 { 0x00001478, 0x00000000 },
2803 { 0x000014b8, 0x00000000 },
2804 { 0x000014f8, 0x00000000 },
2805 { 0x00001538, 0x00000000 },
2806 { 0x00001578, 0x00000000 },
2807 { 0x000015b8, 0x00000000 },
2808 { 0x000015f8, 0x00000000 },
2809 { 0x00001638, 0x00000000 },
2810 { 0x00001678, 0x00000000 },
2811 { 0x000016b8, 0x00000000 },
2812 { 0x000016f8, 0x00000000 },
2813 { 0x00001738, 0x00000000 },
2814 { 0x00001778, 0x00000000 },
2815 { 0x000017b8, 0x00000000 },
2816 { 0x000017f8, 0x00000000 },
2817 { 0x0000103c, 0x00000000 },
2818 { 0x0000107c, 0x00000000 },
2819 { 0x000010bc, 0x00000000 },
2820 { 0x000010fc, 0x00000000 },
2821 { 0x0000113c, 0x00000000 },
2822 { 0x0000117c, 0x00000000 },
2823 { 0x000011bc, 0x00000000 },
2824 { 0x000011fc, 0x00000000 },
2825 { 0x0000123c, 0x00000000 },
2826 { 0x0000127c, 0x00000000 },
2827 { 0x000012bc, 0x00000000 },
2828 { 0x000012fc, 0x00000000 },
2829 { 0x0000133c, 0x00000000 },
2830 { 0x0000137c, 0x00000000 },
2831 { 0x000013bc, 0x00000000 },
2832 { 0x000013fc, 0x00000000 },
2833 { 0x0000143c, 0x00000000 },
2834 { 0x0000147c, 0x00000000 },
2835 { 0x00004030, 0x00000002 },
2836 { 0x0000403c, 0x00000002 },
2837 { 0x00004024, 0x0000001f },
2838 { 0x00004060, 0x00000000 },
2839 { 0x00004064, 0x00000000 },
2840 { 0x00007010, 0x00000033 },
2841 { 0x00007034, 0x00000002 },
2842 { 0x00007038, 0x000004c2 },
2843 { 0x00008004, 0x00000000 },
2844 { 0x00008008, 0x00000000 },
2845 { 0x0000800c, 0x00000000 },
2846 { 0x00008018, 0x00000700 },
2847 { 0x00008020, 0x00000000 },
2848 { 0x00008038, 0x00000000 },
2849 { 0x0000803c, 0x00000000 },
2850 { 0x00008048, 0x40000000 },
2851 { 0x00008054, 0x00000000 },
2852 { 0x00008058, 0x00000000 },
2853 { 0x0000805c, 0x000fc78f },
2854 { 0x00008060, 0x0000000f },
2855 { 0x00008064, 0x00000000 },
2856 { 0x00008070, 0x00000000 },
2857 { 0x000080c0, 0x2a80001a },
2858 { 0x000080c4, 0x05dc01e0 },
2859 { 0x000080c8, 0x1f402710 },
2860 { 0x000080cc, 0x01f40000 },
2861 { 0x000080d0, 0x00001e00 },
2862 { 0x000080d4, 0x00000000 },
2863 { 0x000080d8, 0x00400000 },
2864 { 0x000080e0, 0xffffffff },
2865 { 0x000080e4, 0x0000ffff },
2866 { 0x000080e8, 0x003f3f3f },
2867 { 0x000080ec, 0x00000000 },
2868 { 0x000080f0, 0x00000000 },
2869 { 0x000080f4, 0x00000000 },
2870 { 0x000080f8, 0x00000000 },
2871 { 0x000080fc, 0x00020000 },
2872 { 0x00008100, 0x00020000 },
2873 { 0x00008104, 0x00000001 },
2874 { 0x00008108, 0x00000052 },
2875 { 0x0000810c, 0x00000000 },
2876 { 0x00008110, 0x00000168 },
2877 { 0x00008118, 0x000100aa },
2878 { 0x0000811c, 0x00003210 },
2879 { 0x00008120, 0x08f04800 },
2880 { 0x00008124, 0x00000000 },
2881 { 0x00008128, 0x00000000 },
2882 { 0x0000812c, 0x00000000 },
2883 { 0x00008130, 0x00000000 },
2884 { 0x00008134, 0x00000000 },
2885 { 0x00008138, 0x00000000 },
2886 { 0x0000813c, 0x00000000 },
2887 { 0x00008144, 0x00000000 },
2888 { 0x00008168, 0x00000000 },
2889 { 0x0000816c, 0x00000000 },
2890 { 0x00008170, 0x32143320 },
2891 { 0x00008174, 0xfaa4fa50 },
2892 { 0x00008178, 0x00000100 },
2893 { 0x0000817c, 0x00000000 },
2894 { 0x000081c0, 0x00000000 },
2895 { 0x000081d0, 0x00003210 },
2896 { 0x000081ec, 0x00000000 },
2897 { 0x000081f0, 0x00000000 },
2898 { 0x000081f4, 0x00000000 },
2899 { 0x000081f8, 0x00000000 },
2900 { 0x000081fc, 0x00000000 },
2901 { 0x00008200, 0x00000000 },
2902 { 0x00008204, 0x00000000 },
2903 { 0x00008208, 0x00000000 },
2904 { 0x0000820c, 0x00000000 },
2905 { 0x00008210, 0x00000000 },
2906 { 0x00008214, 0x00000000 },
2907 { 0x00008218, 0x00000000 },
2908 { 0x0000821c, 0x00000000 },
2909 { 0x00008220, 0x00000000 },
2910 { 0x00008224, 0x00000000 },
2911 { 0x00008228, 0x00000000 },
2912 { 0x0000822c, 0x00000000 },
2913 { 0x00008230, 0x00000000 },
2914 { 0x00008234, 0x00000000 },
2915 { 0x00008238, 0x00000000 },
2916 { 0x0000823c, 0x00000000 },
2917 { 0x00008240, 0x00100000 },
2918 { 0x00008244, 0x0010f400 },
2919 { 0x00008248, 0x00000100 },
2920 { 0x0000824c, 0x0001e800 },
2921 { 0x00008250, 0x00000000 },
2922 { 0x00008254, 0x00000000 },
2923 { 0x00008258, 0x00000000 },
2924 { 0x0000825c, 0x400000ff },
2925 { 0x00008260, 0x00080922 },
2926 { 0x00008270, 0x00000000 },
2927 { 0x00008274, 0x40000000 },
2928 { 0x00008278, 0x003e4180 },
2929 { 0x0000827c, 0x00000000 },
2930 { 0x00008284, 0x0000002c },
2931 { 0x00008288, 0x0000002c },
2932 { 0x0000828c, 0x00000000 },
2933 { 0x00008294, 0x00000000 },
2934 { 0x00008298, 0x00000000 },
2935 { 0x0000829c, 0x00000000 },
2936 { 0x00008300, 0x00000040 },
2937 { 0x00008314, 0x00000000 },
2938 { 0x00008328, 0x00000000 },
2939 { 0x0000832c, 0x00000007 },
2940 { 0x00008330, 0x00000302 },
2941 { 0x00008334, 0x00000e00 },
2942 { 0x00008338, 0x00000000 },
2943 { 0x0000833c, 0x00000000 },
2944 { 0x00008340, 0x000107ff },
2945 { 0x00008344, 0x00581043 },
2946 { 0x00009808, 0x00000000 },
2947 { 0x0000980c, 0xafa68e30 },
2948 { 0x00009810, 0xfd14e000 },
2949 { 0x00009814, 0x9c0a9f6b },
2950 { 0x0000981c, 0x00000000 },
2951 { 0x0000982c, 0x0000a000 },
2952 { 0x00009830, 0x00000000 },
2953 { 0x0000983c, 0x00200400 },
2954 { 0x0000984c, 0x0040233c },
2955 { 0x0000a84c, 0x0040233c },
2956 { 0x00009854, 0x00000044 },
2957 { 0x00009900, 0x00000000 },
2958 { 0x00009904, 0x00000000 },
2959 { 0x00009908, 0x00000000 },
2960 { 0x0000990c, 0x00000000 },
2961 { 0x00009910, 0x01002310 },
2962 { 0x0000991c, 0x10000fff },
2963 { 0x00009920, 0x04900000 },
2964 { 0x0000a920, 0x04900000 },
2965 { 0x00009928, 0x00000001 },
2966 { 0x0000992c, 0x00000004 },
2967 { 0x00009934, 0x1e1f2022 },
2968 { 0x00009938, 0x0a0b0c0d },
2969 { 0x0000993c, 0x00000000 },
2970 { 0x00009948, 0x9280c00a },
2971 { 0x0000994c, 0x00020028 },
2972 { 0x00009954, 0x5f3ca3de },
2973 { 0x00009958, 0x2108ecff },
2974 { 0x00009940, 0x14750604 },
2975 { 0x0000c95c, 0x004b6a8e },
2976 { 0x0000c968, 0x000003ce },
2977 { 0x00009970, 0x190fb515 },
2978 { 0x00009974, 0x00000000 },
2979 { 0x00009978, 0x00000001 },
2980 { 0x0000997c, 0x00000000 },
2981 { 0x00009980, 0x00000000 },
2982 { 0x00009984, 0x00000000 },
2983 { 0x00009988, 0x00000000 },
2984 { 0x0000998c, 0x00000000 },
2985 { 0x00009990, 0x00000000 },
2986 { 0x00009994, 0x00000000 },
2987 { 0x00009998, 0x00000000 },
2988 { 0x0000999c, 0x00000000 },
2989 { 0x000099a0, 0x00000000 },
2990 { 0x000099a4, 0x00000001 },
2991 { 0x000099a8, 0x201fff00 },
2992 { 0x000099ac, 0x006f0000 },
2993 { 0x000099b0, 0x03051000 },
2994 { 0x000099b4, 0x00000820 },
2995 { 0x000099dc, 0x00000000 },
2996 { 0x000099e0, 0x00000000 },
2997 { 0x000099e4, 0xaaaaaaaa },
2998 { 0x000099e8, 0x3c466478 },
2999 { 0x000099ec, 0x0cc80caa },
3000 { 0x000099f0, 0x00000000 },
3001 { 0x000099fc, 0x00001042 },
3002 { 0x0000a210, 0x4080a333 },
3003 { 0x0000a214, 0x40206c10 },
3004 { 0x0000a218, 0x009c4060 },
3005 { 0x0000a220, 0x01834061 },
3006 { 0x0000a224, 0x00000400 },
3007 { 0x0000a228, 0x000003b5 },
3008 { 0x0000a22c, 0x233f71c0 },
3009 { 0x0000a234, 0x20202020 },
3010 { 0x0000a238, 0x20202020 },
3011 { 0x0000a23c, 0x13c88000 },
3012 { 0x0000a240, 0x38490a20 },
3013 { 0x0000a244, 0x00007bb6 },
3014 { 0x0000a248, 0x0fff3ffc },
3015 { 0x0000a24c, 0x00000000 },
3016 { 0x0000a254, 0x00000000 },
3017 { 0x0000a258, 0x0cdbd380 },
3018 { 0x0000a25c, 0x0f0f0f01 },
3019 { 0x0000a260, 0xdfa91f01 },
3020 { 0x0000a268, 0x00000000 },
3021 { 0x0000a26c, 0x0ebae9c6 },
3022 { 0x0000b26c, 0x0ebae9c6 },
3023 { 0x0000d270, 0x00820820 },
3024 { 0x0000a278, 0x1ce739ce },
3025 { 0x0000a27c, 0x050701ce },
3026 { 0x0000d35c, 0x07ffffef },
3027 { 0x0000d360, 0x0fffffe7 },
3028 { 0x0000d364, 0x17ffffe5 },
3029 { 0x0000d368, 0x1fffffe4 },
3030 { 0x0000d36c, 0x37ffffe3 },
3031 { 0x0000d370, 0x3fffffe3 },
3032 { 0x0000d374, 0x57ffffe3 },
3033 { 0x0000d378, 0x5fffffe2 },
3034 { 0x0000d37c, 0x7fffffe2 },
3035 { 0x0000d380, 0x7f3c7bba },
3036 { 0x0000d384, 0xf3307ff0 },
3037 { 0x0000a388, 0x0c000000 },
3038 { 0x0000a38c, 0x20202020 },
3039 { 0x0000a390, 0x20202020 },
3040 { 0x0000a394, 0x1ce739ce },
3041 { 0x0000a398, 0x000001ce },
3042 { 0x0000a39c, 0x00000001 },
3043 { 0x0000a3a0, 0x00000000 },
3044 { 0x0000a3a4, 0x00000000 },
3045 { 0x0000a3a8, 0x00000000 },
3046 { 0x0000a3ac, 0x00000000 },
3047 { 0x0000a3b0, 0x00000000 },
3048 { 0x0000a3b4, 0x00000000 },
3049 { 0x0000a3b8, 0x00000000 },
3050 { 0x0000a3bc, 0x00000000 },
3051 { 0x0000a3c0, 0x00000000 },
3052 { 0x0000a3c4, 0x00000000 },
3053 { 0x0000a3c8, 0x00000246 },
3054 { 0x0000a3cc, 0x20202020 },
3055 { 0x0000a3d0, 0x20202020 },
3056 { 0x0000a3d4, 0x20202020 },
3057 { 0x0000a3dc, 0x1ce739ce },
3058 { 0x0000a3e0, 0x000001ce },
3059 { 0x0000a3e4, 0x00000000 },
3060 { 0x0000a3e8, 0x18c43433 },
3061 { 0x0000a3ec, 0x00f70081 },
3062 { 0x00007800, 0x00040000 },
3063 { 0x00007804, 0xdb005012 },
3064 { 0x00007808, 0x04924914 },
3065 { 0x0000780c, 0x21084210 },
3066 { 0x00007810, 0x6d801300 },
3067 { 0x00007814, 0x0019beff },
3068 { 0x00007818, 0x07e41000 },
3069 { 0x0000781c, 0x00392000 },
3070 { 0x00007820, 0x92592480 },
3071 { 0x00007824, 0x00040000 },
3072 { 0x00007828, 0xdb005012 },
3073 { 0x0000782c, 0x04924914 },
3074 { 0x00007830, 0x21084210 },
3075 { 0x00007834, 0x6d801300 },
3076 { 0x00007838, 0x0019beff },
3077 { 0x0000783c, 0x07e40000 },
3078 { 0x00007840, 0x00392000 },
3079 { 0x00007844, 0x92592480 },
3080 { 0x00007848, 0x00100000 },
3081 { 0x0000784c, 0x773f0567 },
3082 { 0x00007850, 0x54214514 },
3083 { 0x00007854, 0x12035828 },
3084 { 0x00007858, 0x9259269a },
3085 { 0x00007860, 0x52802000 },
3086 { 0x00007864, 0x0a8e370e },
3087 { 0x00007868, 0xc0102850 },
3088 { 0x0000786c, 0x812d4000 },
3089 { 0x00007870, 0x807ec400 },
3090 { 0x00007874, 0x001b6db0 },
3091 { 0x00007878, 0x00376b63 },
3092 { 0x0000787c, 0x06db6db6 },
3093 { 0x00007880, 0x006d8000 },
3094 { 0x00007884, 0xffeffffe },
3095 { 0x00007888, 0xffeffffe },
3096 { 0x0000788c, 0x00010000 },
3097 { 0x00007890, 0x02060aeb },
3098 { 0x00007898, 0x2a850160 },
3099};
3100
3101static const u32 ar9280Modes_fast_clock_9280_2[][3] = {
3102 { 0x00001030, 0x00000268, 0x000004d0 },
3103 { 0x00001070, 0x0000018c, 0x00000318 },
3104 { 0x000010b0, 0x00000fd0, 0x00001fa0 },
3105 { 0x00008014, 0x044c044c, 0x08980898 },
3106 { 0x0000801c, 0x148ec02b, 0x148ec057 },
3107 { 0x00008318, 0x000044c0, 0x00008980 },
3108 { 0x00009820, 0x02020200, 0x02020200 },
3109 { 0x00009824, 0x00000f0f, 0x00000f0f },
3110 { 0x00009828, 0x0b020001, 0x0b020001 },
3111 { 0x00009834, 0x00000f0f, 0x00000f0f },
3112 { 0x00009844, 0x03721821, 0x03721821 },
3113 { 0x00009914, 0x00000898, 0x00000898 },
3114 { 0x00009918, 0x0000000b, 0x00000016 },
3115 { 0x00009944, 0xdfbc1210, 0xdfbc1210 },
3116};
3117
3118
3119
3120static const u32 ar9280PciePhy_clkreq_off_L1_9280[][2] = {
3121 {0x00004040, 0x9248fd00 },
3122 {0x00004040, 0x24924924 },
3123 {0x00004040, 0xa8000019 },
3124 {0x00004040, 0x13160820 },
3125 {0x00004040, 0xe5980560 },
3126 {0x00004040, 0x401dcffc },
3127 {0x00004040, 0x1aaabe40 },
3128 {0x00004040, 0xbe105554 },
3129 {0x00004040, 0x00043007 },
3130 {0x00004044, 0x00000000 },
3131};
3132
3133
3134
3135static const u32 ar9280PciePhy_clkreq_always_on_L1_9280[][2] = {
3136 {0x00004040, 0x9248fd00 },
3137 {0x00004040, 0x24924924 },
3138 {0x00004040, 0xa8000019 },
3139 {0x00004040, 0x13160820 },
3140 {0x00004040, 0xe5980560 },
3141 {0x00004040, 0x401dcffd },
3142 {0x00004040, 0x1aaabe40 },
3143 {0x00004040, 0xbe105554 },
3144 {0x00004040, 0x00043007 },
3145 {0x00004044, 0x00000000 },
3146};
diff --git a/drivers/net/wireless/ath9k/main.c b/drivers/net/wireless/ath9k/main.c
new file mode 100644
index 000000000000..9549524630f7
--- /dev/null
+++ b/drivers/net/wireless/ath9k/main.c
@@ -0,0 +1,1533 @@
1/*
2 * Copyright (c) 2008 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/* mac80211 and PCI callbacks */
18
19#include <linux/nl80211.h>
20#include "core.h"
21
22#define ATH_PCI_VERSION "0.1"
23
24#define IEEE80211_HTCAP_MAXRXAMPDU_FACTOR 13
25#define IEEE80211_ACTION_CAT_HT 7
26#define IEEE80211_ACTION_HT_TXCHWIDTH 0
27
28static char *dev_info = "ath9k";
29
30MODULE_AUTHOR("Atheros Communications");
31MODULE_DESCRIPTION("Support for Atheros 802.11n wireless LAN cards.");
32MODULE_SUPPORTED_DEVICE("Atheros 802.11n WLAN cards");
33MODULE_LICENSE("Dual BSD/GPL");
34
35static struct pci_device_id ath_pci_id_table[] __devinitdata = {
36 { PCI_VDEVICE(ATHEROS, 0x0023) }, /* PCI */
37 { PCI_VDEVICE(ATHEROS, 0x0024) }, /* PCI-E */
38 { PCI_VDEVICE(ATHEROS, 0x0027) }, /* PCI */
39 { PCI_VDEVICE(ATHEROS, 0x0029) }, /* PCI */
40 { PCI_VDEVICE(ATHEROS, 0x002A) }, /* PCI-E */
41 { 0 }
42};
43
44static int ath_get_channel(struct ath_softc *sc,
45 struct ieee80211_channel *chan)
46{
47 int i;
48
49 for (i = 0; i < sc->sc_ah->ah_nchan; i++) {
50 if (sc->sc_ah->ah_channels[i].channel == chan->center_freq)
51 return i;
52 }
53
54 return -1;
55}
56
57static u32 ath_get_extchanmode(struct ath_softc *sc,
58 struct ieee80211_channel *chan)
59{
60 u32 chanmode = 0;
61 u8 ext_chan_offset = sc->sc_ht_info.ext_chan_offset;
62 enum ath9k_ht_macmode tx_chan_width = sc->sc_ht_info.tx_chan_width;
63
64 switch (chan->band) {
65 case IEEE80211_BAND_2GHZ:
66 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) &&
67 (tx_chan_width == ATH9K_HT_MACMODE_20))
68 chanmode = CHANNEL_G_HT20;
69 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) &&
70 (tx_chan_width == ATH9K_HT_MACMODE_2040))
71 chanmode = CHANNEL_G_HT40PLUS;
72 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) &&
73 (tx_chan_width == ATH9K_HT_MACMODE_2040))
74 chanmode = CHANNEL_G_HT40MINUS;
75 break;
76 case IEEE80211_BAND_5GHZ:
77 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_NONE) &&
78 (tx_chan_width == ATH9K_HT_MACMODE_20))
79 chanmode = CHANNEL_A_HT20;
80 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_ABOVE) &&
81 (tx_chan_width == ATH9K_HT_MACMODE_2040))
82 chanmode = CHANNEL_A_HT40PLUS;
83 if ((ext_chan_offset == IEEE80211_HT_IE_CHA_SEC_BELOW) &&
84 (tx_chan_width == ATH9K_HT_MACMODE_2040))
85 chanmode = CHANNEL_A_HT40MINUS;
86 break;
87 default:
88 break;
89 }
90
91 return chanmode;
92}
93
94
95static int ath_setkey_tkip(struct ath_softc *sc,
96 struct ieee80211_key_conf *key,
97 struct ath9k_keyval *hk,
98 const u8 *addr)
99{
100 u8 *key_rxmic = NULL;
101 u8 *key_txmic = NULL;
102
103 key_txmic = key->key + NL80211_TKIP_DATA_OFFSET_TX_MIC_KEY;
104 key_rxmic = key->key + NL80211_TKIP_DATA_OFFSET_RX_MIC_KEY;
105
106 if (addr == NULL) {
107 /* Group key installation */
108 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
109 return ath_keyset(sc, key->keyidx, hk, addr);
110 }
111 if (!sc->sc_splitmic) {
112 /*
113 * data key goes at first index,
114 * the hal handles the MIC keys at index+64.
115 */
116 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
117 memcpy(hk->kv_txmic, key_txmic, sizeof(hk->kv_txmic));
118 return ath_keyset(sc, key->keyidx, hk, addr);
119 }
120 /*
121 * TX key goes at first index, RX key at +32.
122 * The hal handles the MIC keys at index+64.
123 */
124 memcpy(hk->kv_mic, key_txmic, sizeof(hk->kv_mic));
125 if (!ath_keyset(sc, key->keyidx, hk, NULL)) {
126 /* Txmic entry failed. No need to proceed further */
127 DPRINTF(sc, ATH_DBG_KEYCACHE,
128 "%s Setting TX MIC Key Failed\n", __func__);
129 return 0;
130 }
131
132 memcpy(hk->kv_mic, key_rxmic, sizeof(hk->kv_mic));
133 /* XXX delete tx key on failure? */
134 return ath_keyset(sc, key->keyidx+32, hk, addr);
135}
136
137static int ath_key_config(struct ath_softc *sc,
138 const u8 *addr,
139 struct ieee80211_key_conf *key)
140{
141 struct ieee80211_vif *vif;
142 struct ath9k_keyval hk;
143 const u8 *mac = NULL;
144 int ret = 0;
145 enum ieee80211_if_types opmode;
146
147 memset(&hk, 0, sizeof(hk));
148
149 switch (key->alg) {
150 case ALG_WEP:
151 hk.kv_type = ATH9K_CIPHER_WEP;
152 break;
153 case ALG_TKIP:
154 hk.kv_type = ATH9K_CIPHER_TKIP;
155 break;
156 case ALG_CCMP:
157 hk.kv_type = ATH9K_CIPHER_AES_CCM;
158 break;
159 default:
160 return -EINVAL;
161 }
162
163 hk.kv_len = key->keylen;
164 memcpy(hk.kv_val, key->key, key->keylen);
165
166 if (!sc->sc_vaps[0])
167 return -EIO;
168
169 vif = sc->sc_vaps[0]->av_if_data;
170 opmode = vif->type;
171
172 /*
173 * Strategy:
174 * For _M_STA mc tx, we will not setup a key at all since we never
175 * tx mc.
176 * _M_STA mc rx, we will use the keyID.
177 * for _M_IBSS mc tx, we will use the keyID, and no macaddr.
178 * for _M_IBSS mc rx, we will alloc a slot and plumb the mac of the
179 * peer node. BUT we will plumb a cleartext key so that we can do
180 * perSta default key table lookup in software.
181 */
182 if (is_broadcast_ether_addr(addr)) {
183 switch (opmode) {
184 case IEEE80211_IF_TYPE_STA:
185 /* default key: could be group WPA key
186 * or could be static WEP key */
187 mac = NULL;
188 break;
189 case IEEE80211_IF_TYPE_IBSS:
190 break;
191 case IEEE80211_IF_TYPE_AP:
192 break;
193 default:
194 ASSERT(0);
195 break;
196 }
197 } else {
198 mac = addr;
199 }
200
201 if (key->alg == ALG_TKIP)
202 ret = ath_setkey_tkip(sc, key, &hk, mac);
203 else
204 ret = ath_keyset(sc, key->keyidx, &hk, mac);
205
206 if (!ret)
207 return -EIO;
208
209 sc->sc_keytype = hk.kv_type;
210 return 0;
211}
212
213static void ath_key_delete(struct ath_softc *sc, struct ieee80211_key_conf *key)
214{
215#define ATH_MAX_NUM_KEYS 4
216 int freeslot;
217
218 freeslot = (key->keyidx >= ATH_MAX_NUM_KEYS) ? 1 : 0;
219 ath_key_reset(sc, key->keyidx, freeslot);
220#undef ATH_MAX_NUM_KEYS
221}
222
223static void setup_ht_cap(struct ieee80211_ht_info *ht_info)
224{
225/* Until mac80211 includes these fields */
226
227#define IEEE80211_HT_CAP_DSSSCCK40 0x1000
228#define IEEE80211_HT_CAP_MAXRXAMPDU_65536 0x3 /* 2 ^ 16 */
229#define IEEE80211_HT_CAP_MPDUDENSITY_8 0x6 /* 8 usec */
230
231 ht_info->ht_supported = 1;
232 ht_info->cap = (u16)IEEE80211_HT_CAP_SUP_WIDTH
233 |(u16)IEEE80211_HT_CAP_MIMO_PS
234 |(u16)IEEE80211_HT_CAP_SGI_40
235 |(u16)IEEE80211_HT_CAP_DSSSCCK40;
236
237 ht_info->ampdu_factor = IEEE80211_HT_CAP_MAXRXAMPDU_65536;
238 ht_info->ampdu_density = IEEE80211_HT_CAP_MPDUDENSITY_8;
239 /* setup supported mcs set */
240 memset(ht_info->supp_mcs_set, 0, 16);
241 ht_info->supp_mcs_set[0] = 0xff;
242 ht_info->supp_mcs_set[1] = 0xff;
243 ht_info->supp_mcs_set[12] = IEEE80211_HT_CAP_MCS_TX_DEFINED;
244}
245
246static int ath_rate2idx(struct ath_softc *sc, int rate)
247{
248 int i = 0, cur_band, n_rates;
249 struct ieee80211_hw *hw = sc->hw;
250
251 cur_band = hw->conf.channel->band;
252 n_rates = sc->sbands[cur_band].n_bitrates;
253
254 for (i = 0; i < n_rates; i++) {
255 if (sc->sbands[cur_band].bitrates[i].bitrate == rate)
256 break;
257 }
258
259 /*
260 * NB:mac80211 validates rx rate index against the supported legacy rate
261 * index only (should be done against ht rates also), return the highest
262 * legacy rate index for rx rate which does not match any one of the
263 * supported basic and extended rates to make mac80211 happy.
264 * The following hack will be cleaned up once the issue with
265 * the rx rate index validation in mac80211 is fixed.
266 */
267 if (i == n_rates)
268 return n_rates - 1;
269 return i;
270}
271
272static void ath9k_rx_prepare(struct ath_softc *sc,
273 struct sk_buff *skb,
274 struct ath_recv_status *status,
275 struct ieee80211_rx_status *rx_status)
276{
277 struct ieee80211_hw *hw = sc->hw;
278 struct ieee80211_channel *curchan = hw->conf.channel;
279
280 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
281
282 rx_status->mactime = status->tsf;
283 rx_status->band = curchan->band;
284 rx_status->freq = curchan->center_freq;
285 rx_status->noise = ATH_DEFAULT_NOISE_FLOOR;
286 rx_status->signal = rx_status->noise + status->rssi;
287 rx_status->rate_idx = ath_rate2idx(sc, (status->rateKbps / 100));
288 rx_status->antenna = status->antenna;
289 rx_status->qual = status->rssi * 100 / 64;
290
291 if (status->flags & ATH_RX_MIC_ERROR)
292 rx_status->flag |= RX_FLAG_MMIC_ERROR;
293 if (status->flags & ATH_RX_FCS_ERROR)
294 rx_status->flag |= RX_FLAG_FAILED_FCS_CRC;
295
296 rx_status->flag |= RX_FLAG_TSFT;
297}
298
299static u8 parse_mpdudensity(u8 mpdudensity)
300{
301 /*
302 * 802.11n D2.0 defined values for "Minimum MPDU Start Spacing":
303 * 0 for no restriction
304 * 1 for 1/4 us
305 * 2 for 1/2 us
306 * 3 for 1 us
307 * 4 for 2 us
308 * 5 for 4 us
309 * 6 for 8 us
310 * 7 for 16 us
311 */
312 switch (mpdudensity) {
313 case 0:
314 return 0;
315 case 1:
316 case 2:
317 case 3:
318 /* Our lower layer calculations limit our precision to
319 1 microsecond */
320 return 1;
321 case 4:
322 return 2;
323 case 5:
324 return 4;
325 case 6:
326 return 8;
327 case 7:
328 return 16;
329 default:
330 return 0;
331 }
332}
333
334static int ath9k_start(struct ieee80211_hw *hw)
335{
336 struct ath_softc *sc = hw->priv;
337 struct ieee80211_channel *curchan = hw->conf.channel;
338 int error = 0, pos;
339
340 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Starting driver with "
341 "initial channel: %d MHz\n", __func__, curchan->center_freq);
342
343 /* setup initial channel */
344
345 pos = ath_get_channel(sc, curchan);
346 if (pos == -1) {
347 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__);
348 return -EINVAL;
349 }
350
351 sc->sc_ah->ah_channels[pos].chanmode =
352 (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
353
354 /* open ath_dev */
355 error = ath_open(sc, &sc->sc_ah->ah_channels[pos]);
356 if (error) {
357 DPRINTF(sc, ATH_DBG_FATAL,
358 "%s: Unable to complete ath_open\n", __func__);
359 return error;
360 }
361
362 ieee80211_wake_queues(hw);
363 return 0;
364}
365
366static int ath9k_tx(struct ieee80211_hw *hw,
367 struct sk_buff *skb)
368{
369 struct ath_softc *sc = hw->priv;
370 int hdrlen, padsize;
371
372 /* Add the padding after the header if this is not already done */
373 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
374 if (hdrlen & 3) {
375 padsize = hdrlen % 4;
376 if (skb_headroom(skb) < padsize)
377 return -1;
378 skb_push(skb, padsize);
379 memmove(skb->data, skb->data + padsize, hdrlen);
380 }
381
382 DPRINTF(sc, ATH_DBG_XMIT, "%s: transmitting packet, skb: %p\n",
383 __func__,
384 skb);
385
386 if (ath_tx_start(sc, skb) != 0) {
387 DPRINTF(sc, ATH_DBG_XMIT, "%s: TX failed\n", __func__);
388 dev_kfree_skb_any(skb);
389 /* FIXME: Check for proper return value from ATH_DEV */
390 return 0;
391 }
392
393 return 0;
394}
395
396static void ath9k_stop(struct ieee80211_hw *hw)
397{
398 struct ath_softc *sc = hw->priv;
399 int error;
400
401 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Driver halt\n", __func__);
402
403 error = ath_suspend(sc);
404 if (error)
405 DPRINTF(sc, ATH_DBG_CONFIG,
406 "%s: Device is no longer present\n", __func__);
407
408 ieee80211_stop_queues(hw);
409}
410
411static int ath9k_add_interface(struct ieee80211_hw *hw,
412 struct ieee80211_if_init_conf *conf)
413{
414 struct ath_softc *sc = hw->priv;
415 int error, ic_opmode = 0;
416
417 /* Support only vap for now */
418
419 if (sc->sc_nvaps)
420 return -ENOBUFS;
421
422 switch (conf->type) {
423 case IEEE80211_IF_TYPE_STA:
424 ic_opmode = ATH9K_M_STA;
425 break;
426 case IEEE80211_IF_TYPE_IBSS:
427 ic_opmode = ATH9K_M_IBSS;
428 break;
429 default:
430 DPRINTF(sc, ATH_DBG_FATAL,
431 "%s: Only STA and IBSS are supported currently\n",
432 __func__);
433 return -EOPNOTSUPP;
434 }
435
436 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a VAP of type: %d\n",
437 __func__,
438 ic_opmode);
439
440 error = ath_vap_attach(sc, 0, conf->vif, ic_opmode);
441 if (error) {
442 DPRINTF(sc, ATH_DBG_FATAL,
443 "%s: Unable to attach vap, error: %d\n",
444 __func__, error);
445 return error;
446 }
447
448 return 0;
449}
450
451static void ath9k_remove_interface(struct ieee80211_hw *hw,
452 struct ieee80211_if_init_conf *conf)
453{
454 struct ath_softc *sc = hw->priv;
455 struct ath_vap *avp;
456 int error;
457
458 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach VAP\n", __func__);
459
460 avp = sc->sc_vaps[0];
461 if (avp == NULL) {
462 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
463 __func__);
464 return;
465 }
466
467#ifdef CONFIG_SLOW_ANT_DIV
468 ath_slow_ant_div_stop(&sc->sc_antdiv);
469#endif
470
471 /* Update ratectrl */
472 ath_rate_newstate(sc, avp);
473
474 /* Reclaim beacon resources */
475 if (sc->sc_opmode == ATH9K_M_HOSTAP || sc->sc_opmode == ATH9K_M_IBSS) {
476 ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
477 ath_beacon_return(sc, avp);
478 }
479
480 /* Set interrupt mask */
481 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
482 ath9k_hw_set_interrupts(sc->sc_ah, sc->sc_imask & ~ATH9K_INT_GLOBAL);
483 sc->sc_beacons = 0;
484
485 error = ath_vap_detach(sc, 0);
486 if (error)
487 DPRINTF(sc, ATH_DBG_FATAL,
488 "%s: Unable to detach vap, error: %d\n",
489 __func__, error);
490}
491
492static int ath9k_config(struct ieee80211_hw *hw,
493 struct ieee80211_conf *conf)
494{
495 struct ath_softc *sc = hw->priv;
496 struct ieee80211_channel *curchan = hw->conf.channel;
497 int pos;
498
499 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
500 __func__,
501 curchan->center_freq);
502
503 pos = ath_get_channel(sc, curchan);
504 if (pos == -1) {
505 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid channel\n", __func__);
506 return -EINVAL;
507 }
508
509 sc->sc_ah->ah_channels[pos].chanmode =
510 (curchan->band == IEEE80211_BAND_2GHZ) ? CHANNEL_G : CHANNEL_A;
511 sc->sc_config.txpowlimit = 2 * conf->power_level;
512
513 /* set h/w channel */
514 if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0)
515 DPRINTF(sc, ATH_DBG_FATAL, "%s: Unable to set channel\n",
516 __func__);
517
518 return 0;
519}
520
521static int ath9k_config_interface(struct ieee80211_hw *hw,
522 struct ieee80211_vif *vif,
523 struct ieee80211_if_conf *conf)
524{
525 struct ath_softc *sc = hw->priv;
526 struct ath_vap *avp;
527 u32 rfilt = 0;
528 int error, i;
529 DECLARE_MAC_BUF(mac);
530
531 avp = sc->sc_vaps[0];
532 if (avp == NULL) {
533 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
534 __func__);
535 return -EINVAL;
536 }
537
538 if ((conf->changed & IEEE80211_IFCC_BSSID) &&
539 !is_zero_ether_addr(conf->bssid)) {
540 switch (vif->type) {
541 case IEEE80211_IF_TYPE_STA:
542 case IEEE80211_IF_TYPE_IBSS:
543 /* Update ratectrl about the new state */
544 ath_rate_newstate(sc, avp);
545
546 /* Set rx filter */
547 rfilt = ath_calcrxfilter(sc);
548 ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
549
550 /* Set BSSID */
551 memcpy(sc->sc_curbssid, conf->bssid, ETH_ALEN);
552 sc->sc_curaid = 0;
553 ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
554 sc->sc_curaid);
555
556 /* Set aggregation protection mode parameters */
557 sc->sc_config.ath_aggr_prot = 0;
558
559 /*
560 * Reset our TSF so that its value is lower than the
561 * beacon that we are trying to catch.
562 * Only then hw will update its TSF register with the
563 * new beacon. Reset the TSF before setting the BSSID
564 * to avoid allowing in any frames that would update
565 * our TSF only to have us clear it
566 * immediately thereafter.
567 */
568 ath9k_hw_reset_tsf(sc->sc_ah);
569
570 /* Disable BMISS interrupt when we're not associated */
571 ath9k_hw_set_interrupts(sc->sc_ah,
572 sc->sc_imask &
573 ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS));
574 sc->sc_imask &= ~(ATH9K_INT_SWBA | ATH9K_INT_BMISS);
575
576 DPRINTF(sc, ATH_DBG_CONFIG,
577 "%s: RX filter 0x%x bssid %s aid 0x%x\n",
578 __func__, rfilt,
579 print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
580
581 /* need to reconfigure the beacon */
582 sc->sc_beacons = 0;
583
584 break;
585 default:
586 break;
587 }
588 }
589
590 if ((conf->changed & IEEE80211_IFCC_BEACON) &&
591 (vif->type == IEEE80211_IF_TYPE_IBSS)) {
592 /*
593 * Allocate and setup the beacon frame.
594 *
595 * Stop any previous beacon DMA. This may be
596 * necessary, for example, when an ibss merge
597 * causes reconfiguration; we may be called
598 * with beacon transmission active.
599 */
600 ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
601
602 error = ath_beacon_alloc(sc, 0);
603 if (error != 0)
604 return error;
605
606 ath_beacon_sync(sc, 0);
607 }
608
609 /* Check for WLAN_CAPABILITY_PRIVACY ? */
610 if ((avp->av_opmode != IEEE80211_IF_TYPE_STA)) {
611 for (i = 0; i < IEEE80211_WEP_NKID; i++)
612 if (ath9k_hw_keyisvalid(sc->sc_ah, (u16)i))
613 ath9k_hw_keysetmac(sc->sc_ah,
614 (u16)i,
615 sc->sc_curbssid);
616 }
617
618 /* Only legacy IBSS for now */
619 if (vif->type == IEEE80211_IF_TYPE_IBSS)
620 ath_update_chainmask(sc, 0);
621
622 return 0;
623}
624
625#define SUPPORTED_FILTERS \
626 (FIF_PROMISC_IN_BSS | \
627 FIF_ALLMULTI | \
628 FIF_CONTROL | \
629 FIF_OTHER_BSS | \
630 FIF_BCN_PRBRESP_PROMISC | \
631 FIF_FCSFAIL)
632
633/* Accept unicast, bcast and mcast frames */
634
635static void ath9k_configure_filter(struct ieee80211_hw *hw,
636 unsigned int changed_flags,
637 unsigned int *total_flags,
638 int mc_count,
639 struct dev_mc_list *mclist)
640{
641 struct ath_softc *sc = hw->priv;
642
643 changed_flags &= SUPPORTED_FILTERS;
644 *total_flags &= SUPPORTED_FILTERS;
645
646 if (changed_flags & FIF_BCN_PRBRESP_PROMISC) {
647 if (*total_flags & FIF_BCN_PRBRESP_PROMISC)
648 ath_scan_start(sc);
649 else
650 ath_scan_end(sc);
651 }
652}
653
654static void ath9k_sta_notify(struct ieee80211_hw *hw,
655 struct ieee80211_vif *vif,
656 enum sta_notify_cmd cmd,
657 const u8 *addr)
658{
659 struct ath_softc *sc = hw->priv;
660 struct ath_node *an;
661 unsigned long flags;
662 DECLARE_MAC_BUF(mac);
663
664 spin_lock_irqsave(&sc->node_lock, flags);
665 an = ath_node_find(sc, (u8 *) addr);
666 spin_unlock_irqrestore(&sc->node_lock, flags);
667
668 switch (cmd) {
669 case STA_NOTIFY_ADD:
670 spin_lock_irqsave(&sc->node_lock, flags);
671 if (!an) {
672 ath_node_attach(sc, (u8 *)addr, 0);
673 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach a node: %s\n",
674 __func__,
675 print_mac(mac, addr));
676 } else {
677 ath_node_get(sc, (u8 *)addr);
678 }
679 spin_unlock_irqrestore(&sc->node_lock, flags);
680 break;
681 case STA_NOTIFY_REMOVE:
682 if (!an)
683 DPRINTF(sc, ATH_DBG_FATAL,
684 "%s: Removal of a non-existent node\n",
685 __func__);
686 else {
687 ath_node_put(sc, an, ATH9K_BH_STATUS_INTACT);
688 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Put a node: %s\n",
689 __func__,
690 print_mac(mac, addr));
691 }
692 break;
693 default:
694 break;
695 }
696}
697
698static int ath9k_conf_tx(struct ieee80211_hw *hw,
699 u16 queue,
700 const struct ieee80211_tx_queue_params *params)
701{
702 struct ath_softc *sc = hw->priv;
703 struct ath9k_txq_info qi;
704 int ret = 0, qnum;
705
706 if (queue >= WME_NUM_AC)
707 return 0;
708
709 qi.tqi_aifs = params->aifs;
710 qi.tqi_cwmin = params->cw_min;
711 qi.tqi_cwmax = params->cw_max;
712 qi.tqi_burstTime = params->txop;
713 qnum = ath_get_hal_qnum(queue, sc);
714
715 DPRINTF(sc, ATH_DBG_CONFIG,
716 "%s: Configure tx [queue/halq] [%d/%d], "
717 "aifs: %d, cw_min: %d, cw_max: %d, txop: %d\n",
718 __func__,
719 queue,
720 qnum,
721 params->aifs,
722 params->cw_min,
723 params->cw_max,
724 params->txop);
725
726 ret = ath_txq_update(sc, qnum, &qi);
727 if (ret)
728 DPRINTF(sc, ATH_DBG_FATAL,
729 "%s: TXQ Update failed\n", __func__);
730
731 return ret;
732}
733
734static int ath9k_set_key(struct ieee80211_hw *hw,
735 enum set_key_cmd cmd,
736 const u8 *local_addr,
737 const u8 *addr,
738 struct ieee80211_key_conf *key)
739{
740 struct ath_softc *sc = hw->priv;
741 int ret = 0;
742
743 DPRINTF(sc, ATH_DBG_KEYCACHE, " %s: Set HW Key\n", __func__);
744
745 switch (cmd) {
746 case SET_KEY:
747 ret = ath_key_config(sc, addr, key);
748 if (!ret) {
749 set_bit(key->keyidx, sc->sc_keymap);
750 key->hw_key_idx = key->keyidx;
751 /* push IV and Michael MIC generation to stack */
752 key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
753 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
754 }
755 break;
756 case DISABLE_KEY:
757 ath_key_delete(sc, key);
758 clear_bit(key->keyidx, sc->sc_keymap);
759 sc->sc_keytype = ATH9K_CIPHER_CLR;
760 break;
761 default:
762 ret = -EINVAL;
763 }
764
765 return ret;
766}
767
768static void ath9k_ht_conf(struct ath_softc *sc,
769 struct ieee80211_bss_conf *bss_conf)
770{
771#define IEEE80211_HT_CAP_40MHZ_INTOLERANT BIT(14)
772 struct ath_ht_info *ht_info = &sc->sc_ht_info;
773
774 if (bss_conf->assoc_ht) {
775 ht_info->ext_chan_offset =
776 bss_conf->ht_bss_conf->bss_cap &
777 IEEE80211_HT_IE_CHA_SEC_OFFSET;
778
779 if (!(bss_conf->ht_conf->cap &
780 IEEE80211_HT_CAP_40MHZ_INTOLERANT) &&
781 (bss_conf->ht_bss_conf->bss_cap &
782 IEEE80211_HT_IE_CHA_WIDTH))
783 ht_info->tx_chan_width = ATH9K_HT_MACMODE_2040;
784 else
785 ht_info->tx_chan_width = ATH9K_HT_MACMODE_20;
786
787 ath9k_hw_set11nmac2040(sc->sc_ah, ht_info->tx_chan_width);
788 ht_info->maxampdu = 1 << (IEEE80211_HTCAP_MAXRXAMPDU_FACTOR +
789 bss_conf->ht_conf->ampdu_factor);
790 ht_info->mpdudensity =
791 parse_mpdudensity(bss_conf->ht_conf->ampdu_density);
792
793 }
794
795#undef IEEE80211_HT_CAP_40MHZ_INTOLERANT
796}
797
798static void ath9k_bss_assoc_info(struct ath_softc *sc,
799 struct ieee80211_bss_conf *bss_conf)
800{
801 struct ieee80211_hw *hw = sc->hw;
802 struct ieee80211_channel *curchan = hw->conf.channel;
803 struct ath_vap *avp;
804 int pos;
805 DECLARE_MAC_BUF(mac);
806
807 if (bss_conf->assoc) {
808 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Bss Info ASSOC %d\n",
809 __func__,
810 bss_conf->aid);
811
812 avp = sc->sc_vaps[0];
813 if (avp == NULL) {
814 DPRINTF(sc, ATH_DBG_FATAL, "%s: Invalid interface\n",
815 __func__);
816 return;
817 }
818
819 /* New association, store aid */
820 if (avp->av_opmode == ATH9K_M_STA) {
821 sc->sc_curaid = bss_conf->aid;
822 ath9k_hw_write_associd(sc->sc_ah, sc->sc_curbssid,
823 sc->sc_curaid);
824 }
825
826 /* Configure the beacon */
827 ath_beacon_config(sc, 0);
828 sc->sc_beacons = 1;
829
830 /* Reset rssi stats */
831 sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER;
832 sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER;
833 sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER;
834 sc->sc_halstats.ns_avgtxrate = ATH_RATE_DUMMY_MARKER;
835
836 /* Update chainmask */
837 ath_update_chainmask(sc, bss_conf->assoc_ht);
838
839 DPRINTF(sc, ATH_DBG_CONFIG,
840 "%s: bssid %s aid 0x%x\n",
841 __func__,
842 print_mac(mac, sc->sc_curbssid), sc->sc_curaid);
843
844 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Set channel: %d MHz\n",
845 __func__,
846 curchan->center_freq);
847
848 pos = ath_get_channel(sc, curchan);
849 if (pos == -1) {
850 DPRINTF(sc, ATH_DBG_FATAL,
851 "%s: Invalid channel\n", __func__);
852 return;
853 }
854
855 if (hw->conf.ht_conf.ht_supported)
856 sc->sc_ah->ah_channels[pos].chanmode =
857 ath_get_extchanmode(sc, curchan);
858 else
859 sc->sc_ah->ah_channels[pos].chanmode =
860 (curchan->band == IEEE80211_BAND_2GHZ) ?
861 CHANNEL_G : CHANNEL_A;
862
863 /* set h/w channel */
864 if (ath_set_channel(sc, &sc->sc_ah->ah_channels[pos]) < 0)
865 DPRINTF(sc, ATH_DBG_FATAL,
866 "%s: Unable to set channel\n",
867 __func__);
868
869 ath_rate_newstate(sc, avp);
870 /* Update ratectrl about the new state */
871 ath_rc_node_update(hw, avp->rc_node);
872 } else {
873 DPRINTF(sc, ATH_DBG_CONFIG,
874 "%s: Bss Info DISSOC\n", __func__);
875 sc->sc_curaid = 0;
876 }
877}
878
879static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
880 struct ieee80211_vif *vif,
881 struct ieee80211_bss_conf *bss_conf,
882 u32 changed)
883{
884 struct ath_softc *sc = hw->priv;
885
886 if (changed & BSS_CHANGED_ERP_PREAMBLE) {
887 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed PREAMBLE %d\n",
888 __func__,
889 bss_conf->use_short_preamble);
890 if (bss_conf->use_short_preamble)
891 sc->sc_flags |= ATH_PREAMBLE_SHORT;
892 else
893 sc->sc_flags &= ~ATH_PREAMBLE_SHORT;
894 }
895
896 if (changed & BSS_CHANGED_ERP_CTS_PROT) {
897 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed CTS PROT %d\n",
898 __func__,
899 bss_conf->use_cts_prot);
900 if (bss_conf->use_cts_prot &&
901 hw->conf.channel->band != IEEE80211_BAND_5GHZ)
902 sc->sc_flags |= ATH_PROTECT_ENABLE;
903 else
904 sc->sc_flags &= ~ATH_PROTECT_ENABLE;
905 }
906
907 if (changed & BSS_CHANGED_HT) {
908 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed HT %d\n",
909 __func__,
910 bss_conf->assoc_ht);
911 ath9k_ht_conf(sc, bss_conf);
912 }
913
914 if (changed & BSS_CHANGED_ASSOC) {
915 DPRINTF(sc, ATH_DBG_CONFIG, "%s: BSS Changed ASSOC %d\n",
916 __func__,
917 bss_conf->assoc);
918 ath9k_bss_assoc_info(sc, bss_conf);
919 }
920}
921
922static u64 ath9k_get_tsf(struct ieee80211_hw *hw)
923{
924 u64 tsf;
925 struct ath_softc *sc = hw->priv;
926 struct ath_hal *ah = sc->sc_ah;
927
928 tsf = ath9k_hw_gettsf64(ah);
929
930 return tsf;
931}
932
933static void ath9k_reset_tsf(struct ieee80211_hw *hw)
934{
935 struct ath_softc *sc = hw->priv;
936 struct ath_hal *ah = sc->sc_ah;
937
938 ath9k_hw_reset_tsf(ah);
939}
940
941static int ath9k_ampdu_action(struct ieee80211_hw *hw,
942 enum ieee80211_ampdu_mlme_action action,
943 const u8 *addr,
944 u16 tid,
945 u16 *ssn)
946{
947 struct ath_softc *sc = hw->priv;
948 int ret = 0;
949
950 switch (action) {
951 case IEEE80211_AMPDU_RX_START:
952 ret = ath_rx_aggr_start(sc, addr, tid, ssn);
953 if (ret < 0)
954 DPRINTF(sc, ATH_DBG_FATAL,
955 "%s: Unable to start RX aggregation\n",
956 __func__);
957 break;
958 case IEEE80211_AMPDU_RX_STOP:
959 ret = ath_rx_aggr_stop(sc, addr, tid);
960 if (ret < 0)
961 DPRINTF(sc, ATH_DBG_FATAL,
962 "%s: Unable to stop RX aggregation\n",
963 __func__);
964 break;
965 case IEEE80211_AMPDU_TX_START:
966 ret = ath_tx_aggr_start(sc, addr, tid, ssn);
967 if (ret < 0)
968 DPRINTF(sc, ATH_DBG_FATAL,
969 "%s: Unable to start TX aggregation\n",
970 __func__);
971 else
972 ieee80211_start_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid);
973 break;
974 case IEEE80211_AMPDU_TX_STOP:
975 ret = ath_tx_aggr_stop(sc, addr, tid);
976 if (ret < 0)
977 DPRINTF(sc, ATH_DBG_FATAL,
978 "%s: Unable to stop TX aggregation\n",
979 __func__);
980
981 ieee80211_stop_tx_ba_cb_irqsafe(hw, (u8 *)addr, tid);
982 break;
983 default:
984 DPRINTF(sc, ATH_DBG_FATAL,
985 "%s: Unknown AMPDU action\n", __func__);
986 }
987
988 return ret;
989}
990
991static struct ieee80211_ops ath9k_ops = {
992 .tx = ath9k_tx,
993 .start = ath9k_start,
994 .stop = ath9k_stop,
995 .add_interface = ath9k_add_interface,
996 .remove_interface = ath9k_remove_interface,
997 .config = ath9k_config,
998 .config_interface = ath9k_config_interface,
999 .configure_filter = ath9k_configure_filter,
1000 .get_stats = NULL,
1001 .sta_notify = ath9k_sta_notify,
1002 .conf_tx = ath9k_conf_tx,
1003 .get_tx_stats = NULL,
1004 .bss_info_changed = ath9k_bss_info_changed,
1005 .set_tim = NULL,
1006 .set_key = ath9k_set_key,
1007 .hw_scan = NULL,
1008 .get_tkip_seq = NULL,
1009 .set_rts_threshold = NULL,
1010 .set_frag_threshold = NULL,
1011 .set_retry_limit = NULL,
1012 .get_tsf = ath9k_get_tsf,
1013 .reset_tsf = ath9k_reset_tsf,
1014 .tx_last_beacon = NULL,
1015 .ampdu_action = ath9k_ampdu_action
1016};
1017
1018void ath_get_beaconconfig(struct ath_softc *sc,
1019 int if_id,
1020 struct ath_beacon_config *conf)
1021{
1022 struct ieee80211_hw *hw = sc->hw;
1023
1024 /* fill in beacon config data */
1025
1026 conf->beacon_interval = hw->conf.beacon_int;
1027 conf->listen_interval = 100;
1028 conf->dtim_count = 1;
1029 conf->bmiss_timeout = ATH_DEFAULT_BMISS_LIMIT * conf->listen_interval;
1030}
1031
1032int ath_update_beacon(struct ath_softc *sc,
1033 int if_id,
1034 struct ath_beacon_offset *bo,
1035 struct sk_buff *skb,
1036 int mcast)
1037{
1038 return 0;
1039}
1040
1041void ath_tx_complete(struct ath_softc *sc, struct sk_buff *skb,
1042 struct ath_xmit_status *tx_status, struct ath_node *an)
1043{
1044 struct ieee80211_hw *hw = sc->hw;
1045 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1046
1047 DPRINTF(sc, ATH_DBG_XMIT,
1048 "%s: TX complete: skb: %p\n", __func__, skb);
1049
1050 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK ||
1051 tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED) {
1052 /* free driver's private data area of tx_info */
1053 if (tx_info->driver_data[0] != NULL)
1054 kfree(tx_info->driver_data[0]);
1055 tx_info->driver_data[0] = NULL;
1056 }
1057
1058 if (tx_status->flags & ATH_TX_BAR) {
1059 tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK;
1060 tx_status->flags &= ~ATH_TX_BAR;
1061 }
1062 if (tx_status->flags)
1063 tx_info->status.excessive_retries = 1;
1064
1065 tx_info->status.retry_count = tx_status->retries;
1066
1067 ieee80211_tx_status(hw, skb);
1068 if (an)
1069 ath_node_put(sc, an, ATH9K_BH_STATUS_CHANGE);
1070}
1071
1072int ath__rx_indicate(struct ath_softc *sc,
1073 struct sk_buff *skb,
1074 struct ath_recv_status *status,
1075 u16 keyix)
1076{
1077 struct ieee80211_hw *hw = sc->hw;
1078 struct ath_node *an = NULL;
1079 struct ieee80211_rx_status rx_status;
1080 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
1081 int hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1082 int padsize;
1083 enum ATH_RX_TYPE st;
1084
1085 /* see if any padding is done by the hw and remove it */
1086 if (hdrlen & 3) {
1087 padsize = hdrlen % 4;
1088 memmove(skb->data + padsize, skb->data, hdrlen);
1089 skb_pull(skb, padsize);
1090 }
1091
1092 /* remove FCS before passing up to protocol stack */
1093 skb_trim(skb, (skb->len - FCS_LEN));
1094
1095 /* Prepare rx status */
1096 ath9k_rx_prepare(sc, skb, status, &rx_status);
1097
1098 if (!(keyix == ATH9K_RXKEYIX_INVALID) &&
1099 !(status->flags & ATH_RX_DECRYPT_ERROR)) {
1100 rx_status.flag |= RX_FLAG_DECRYPTED;
1101 } else if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED)
1102 && !(status->flags & ATH_RX_DECRYPT_ERROR)
1103 && skb->len >= hdrlen + 4) {
1104 keyix = skb->data[hdrlen + 3] >> 6;
1105
1106 if (test_bit(keyix, sc->sc_keymap))
1107 rx_status.flag |= RX_FLAG_DECRYPTED;
1108 }
1109
1110 spin_lock_bh(&sc->node_lock);
1111 an = ath_node_find(sc, hdr->addr2);
1112 spin_unlock_bh(&sc->node_lock);
1113
1114 if (an) {
1115 ath_rx_input(sc, an,
1116 hw->conf.ht_conf.ht_supported,
1117 skb, status, &st);
1118 }
1119 if (!an || (st != ATH_RX_CONSUMED))
1120 __ieee80211_rx(hw, skb, &rx_status);
1121
1122 return 0;
1123}
1124
1125int ath_rx_subframe(struct ath_node *an,
1126 struct sk_buff *skb,
1127 struct ath_recv_status *status)
1128{
1129 struct ath_softc *sc = an->an_sc;
1130 struct ieee80211_hw *hw = sc->hw;
1131 struct ieee80211_rx_status rx_status;
1132
1133 /* Prepare rx status */
1134 ath9k_rx_prepare(sc, skb, status, &rx_status);
1135 if (!(status->flags & ATH_RX_DECRYPT_ERROR))
1136 rx_status.flag |= RX_FLAG_DECRYPTED;
1137
1138 __ieee80211_rx(hw, skb, &rx_status);
1139
1140 return 0;
1141}
1142
1143enum ath9k_ht_macmode ath_cwm_macmode(struct ath_softc *sc)
1144{
1145 return sc->sc_ht_info.tx_chan_width;
1146}
1147
1148void ath_setup_rate(struct ath_softc *sc,
1149 enum wireless_mode wMode,
1150 enum RATE_TYPE type,
1151 const struct ath9k_rate_table *rt)
1152{
1153 int i, maxrates, a = 0, b = 0;
1154 struct ieee80211_supported_band *band_2ghz;
1155 struct ieee80211_supported_band *band_5ghz;
1156 struct ieee80211_rate *rates_2ghz;
1157 struct ieee80211_rate *rates_5ghz;
1158
1159 if ((wMode >= WIRELESS_MODE_MAX) || (type != NORMAL_RATE))
1160 return;
1161
1162 band_2ghz = &sc->sbands[IEEE80211_BAND_2GHZ];
1163 band_5ghz = &sc->sbands[IEEE80211_BAND_5GHZ];
1164 rates_2ghz = sc->rates[IEEE80211_BAND_2GHZ];
1165 rates_5ghz = sc->rates[IEEE80211_BAND_5GHZ];
1166
1167 if (rt->rateCount > ATH_RATE_MAX)
1168 maxrates = ATH_RATE_MAX;
1169 else
1170 maxrates = rt->rateCount;
1171
1172 if ((band_2ghz->n_bitrates != 0) && (band_5ghz->n_bitrates != 0)) {
1173 DPRINTF(sc, ATH_DBG_CONFIG,
1174 "%s: Rates already setup\n", __func__);
1175 return;
1176 }
1177
1178 for (i = 0; i < maxrates; i++) {
1179 switch (wMode) {
1180 case WIRELESS_MODE_11b:
1181 case WIRELESS_MODE_11g:
1182 rates_2ghz[a].bitrate = rt->info[i].rateKbps / 100;
1183 rates_2ghz[a].hw_value = rt->info[i].rateCode;
1184 a++;
1185 band_2ghz->n_bitrates = a;
1186 break;
1187 case WIRELESS_MODE_11a:
1188 rates_5ghz[b].bitrate = rt->info[i].rateKbps / 100;
1189 rates_5ghz[b].hw_value = rt->info[i].rateCode;
1190 b++;
1191 band_5ghz->n_bitrates = b;
1192 break;
1193 default:
1194 break;
1195 }
1196 }
1197
1198 if (band_2ghz->n_bitrates) {
1199 for (i = 0; i < band_2ghz->n_bitrates; i++) {
1200 DPRINTF(sc, ATH_DBG_CONFIG,
1201 "%s: 2GHz Rate: %2dMbps, ratecode: %2d\n",
1202 __func__,
1203 rates_2ghz[i].bitrate / 10,
1204 rates_2ghz[i].hw_value);
1205 }
1206 } else if (band_5ghz->n_bitrates) {
1207 for (i = 0; i < band_5ghz->n_bitrates; i++) {
1208 DPRINTF(sc, ATH_DBG_CONFIG,
1209 "%s: 5Ghz Rate: %2dMbps, ratecode: %2d\n",
1210 __func__,
1211 rates_5ghz[i].bitrate / 10,
1212 rates_5ghz[i].hw_value);
1213 }
1214 }
1215}
1216
1217static int ath_detach(struct ath_softc *sc)
1218{
1219 struct ieee80211_hw *hw = sc->hw;
1220
1221 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Detach ATH hw\n", __func__);
1222
1223 /* Unregister hw */
1224
1225 ieee80211_unregister_hw(hw);
1226
1227 /* unregister Rate control */
1228 ath_rate_control_unregister();
1229
1230 /* tx/rx cleanup */
1231
1232 ath_rx_cleanup(sc);
1233 ath_tx_cleanup(sc);
1234
1235 /* Deinit */
1236
1237 ath_deinit(sc);
1238
1239 return 0;
1240}
1241
1242static int ath_attach(u16 devid,
1243 struct ath_softc *sc)
1244{
1245 struct ieee80211_hw *hw = sc->hw;
1246 int error = 0;
1247
1248 DPRINTF(sc, ATH_DBG_CONFIG, "%s: Attach ATH hw\n", __func__);
1249
1250 error = ath_init(devid, sc);
1251 if (error != 0)
1252 return error;
1253
1254 /* Init nodes */
1255
1256 INIT_LIST_HEAD(&sc->node_list);
1257 spin_lock_init(&sc->node_lock);
1258
1259 /* get mac address from hardware and set in mac80211 */
1260
1261 SET_IEEE80211_PERM_ADDR(hw, sc->sc_myaddr);
1262
1263 /* setup channels and rates */
1264
1265 sc->sbands[IEEE80211_BAND_2GHZ].channels =
1266 sc->channels[IEEE80211_BAND_2GHZ];
1267 sc->sbands[IEEE80211_BAND_2GHZ].bitrates =
1268 sc->rates[IEEE80211_BAND_2GHZ];
1269 sc->sbands[IEEE80211_BAND_2GHZ].band = IEEE80211_BAND_2GHZ;
1270
1271 if (sc->sc_ah->ah_caps.halHTSupport)
1272 /* Setup HT capabilities for 2.4Ghz*/
1273 setup_ht_cap(&sc->sbands[IEEE80211_BAND_2GHZ].ht_info);
1274
1275 hw->wiphy->bands[IEEE80211_BAND_2GHZ] =
1276 &sc->sbands[IEEE80211_BAND_2GHZ];
1277
1278 if (sc->sc_ah->ah_caps.halWirelessModes & ATH9K_MODE_SEL_11A) {
1279 sc->sbands[IEEE80211_BAND_5GHZ].channels =
1280 sc->channels[IEEE80211_BAND_5GHZ];
1281 sc->sbands[IEEE80211_BAND_5GHZ].bitrates =
1282 sc->rates[IEEE80211_BAND_5GHZ];
1283 sc->sbands[IEEE80211_BAND_5GHZ].band =
1284 IEEE80211_BAND_5GHZ;
1285
1286 if (sc->sc_ah->ah_caps.halHTSupport)
1287 /* Setup HT capabilities for 5Ghz*/
1288 setup_ht_cap(&sc->sbands[IEEE80211_BAND_5GHZ].ht_info);
1289
1290 hw->wiphy->bands[IEEE80211_BAND_5GHZ] =
1291 &sc->sbands[IEEE80211_BAND_5GHZ];
1292 }
1293
1294 /* FIXME: Have to figure out proper hw init values later */
1295
1296 hw->queues = 4;
1297 hw->ampdu_queues = 1;
1298
1299 /* Register rate control */
1300 hw->rate_control_algorithm = "ath9k_rate_control";
1301 error = ath_rate_control_register();
1302 if (error != 0) {
1303 DPRINTF(sc, ATH_DBG_FATAL,
1304 "%s: Unable to register rate control "
1305 "algorithm:%d\n", __func__, error);
1306 ath_rate_control_unregister();
1307 goto bad;
1308 }
1309
1310 error = ieee80211_register_hw(hw);
1311 if (error != 0) {
1312 ath_rate_control_unregister();
1313 goto bad;
1314 }
1315
1316 /* initialize tx/rx engine */
1317
1318 error = ath_tx_init(sc, ATH_TXBUF);
1319 if (error != 0)
1320 goto bad1;
1321
1322 error = ath_rx_init(sc, ATH_RXBUF);
1323 if (error != 0)
1324 goto bad1;
1325
1326 return 0;
1327bad1:
1328 ath_detach(sc);
1329bad:
1330 return error;
1331}
1332
1333static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
1334{
1335 void __iomem *mem;
1336 struct ath_softc *sc;
1337 struct ieee80211_hw *hw;
1338 const char *athname;
1339 u8 csz;
1340 u32 val;
1341 int ret = 0;
1342
1343 if (pci_enable_device(pdev))
1344 return -EIO;
1345
1346 /* XXX 32-bit addressing only */
1347 if (pci_set_dma_mask(pdev, 0xffffffff)) {
1348 printk(KERN_ERR "ath_pci: 32-bit DMA not available\n");
1349 ret = -ENODEV;
1350 goto bad;
1351 }
1352
1353 /*
1354 * Cache line size is used to size and align various
1355 * structures used to communicate with the hardware.
1356 */
1357 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
1358 if (csz == 0) {
1359 /*
1360 * Linux 2.4.18 (at least) writes the cache line size
1361 * register as a 16-bit wide register which is wrong.
1362 * We must have this setup properly for rx buffer
1363 * DMA to work so force a reasonable value here if it
1364 * comes up zero.
1365 */
1366 csz = L1_CACHE_BYTES / sizeof(u32);
1367 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
1368 }
1369 /*
1370 * The default setting of latency timer yields poor results,
1371 * set it to the value used by other systems. It may be worth
1372 * tweaking this setting more.
1373 */
1374 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
1375
1376 pci_set_master(pdev);
1377
1378 /*
1379 * Disable the RETRY_TIMEOUT register (0x41) to keep
1380 * PCI Tx retries from interfering with C3 CPU state.
1381 */
1382 pci_read_config_dword(pdev, 0x40, &val);
1383 if ((val & 0x0000ff00) != 0)
1384 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1385
1386 ret = pci_request_region(pdev, 0, "ath9k");
1387 if (ret) {
1388 dev_err(&pdev->dev, "PCI memory region reserve error\n");
1389 ret = -ENODEV;
1390 goto bad;
1391 }
1392
1393 mem = pci_iomap(pdev, 0, 0);
1394 if (!mem) {
1395 printk(KERN_ERR "PCI memory map error\n") ;
1396 ret = -EIO;
1397 goto bad1;
1398 }
1399
1400 hw = ieee80211_alloc_hw(sizeof(struct ath_softc), &ath9k_ops);
1401 if (hw == NULL) {
1402 printk(KERN_ERR "ath_pci: no memory for ieee80211_hw\n");
1403 goto bad2;
1404 }
1405
1406 hw->flags = IEEE80211_HW_SIGNAL_DBM |
1407 IEEE80211_HW_NOISE_DBM;
1408
1409 SET_IEEE80211_DEV(hw, &pdev->dev);
1410 pci_set_drvdata(pdev, hw);
1411
1412 sc = hw->priv;
1413 sc->hw = hw;
1414 sc->pdev = pdev;
1415 sc->mem = mem;
1416
1417 if (ath_attach(id->device, sc) != 0) {
1418 ret = -ENODEV;
1419 goto bad3;
1420 }
1421
1422 /* setup interrupt service routine */
1423
1424 if (request_irq(pdev->irq, ath_isr, IRQF_SHARED, "ath", sc)) {
1425 printk(KERN_ERR "%s: request_irq failed\n",
1426 wiphy_name(hw->wiphy));
1427 ret = -EIO;
1428 goto bad4;
1429 }
1430
1431 athname = ath9k_hw_probe(id->vendor, id->device);
1432
1433 printk(KERN_INFO "%s: %s: mem=0x%lx, irq=%d\n",
1434 wiphy_name(hw->wiphy),
1435 athname ? athname : "Atheros ???",
1436 (unsigned long)mem, pdev->irq);
1437
1438 return 0;
1439bad4:
1440 ath_detach(sc);
1441bad3:
1442 ieee80211_free_hw(hw);
1443bad2:
1444 pci_iounmap(pdev, mem);
1445bad1:
1446 pci_release_region(pdev, 0);
1447bad:
1448 pci_disable_device(pdev);
1449 return ret;
1450}
1451
1452static void ath_pci_remove(struct pci_dev *pdev)
1453{
1454 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
1455 struct ath_softc *sc = hw->priv;
1456
1457 if (pdev->irq)
1458 free_irq(pdev->irq, sc);
1459 ath_detach(sc);
1460 pci_iounmap(pdev, sc->mem);
1461 pci_release_region(pdev, 0);
1462 pci_disable_device(pdev);
1463 ieee80211_free_hw(hw);
1464}
1465
1466#ifdef CONFIG_PM
1467
1468static int ath_pci_suspend(struct pci_dev *pdev, pm_message_t state)
1469{
1470 pci_save_state(pdev);
1471 pci_disable_device(pdev);
1472 pci_set_power_state(pdev, 3);
1473
1474 return 0;
1475}
1476
1477static int ath_pci_resume(struct pci_dev *pdev)
1478{
1479 u32 val;
1480 int err;
1481
1482 err = pci_enable_device(pdev);
1483 if (err)
1484 return err;
1485 pci_restore_state(pdev);
1486 /*
1487 * Suspend/Resume resets the PCI configuration space, so we have to
1488 * re-disable the RETRY_TIMEOUT register (0x41) to keep
1489 * PCI Tx retries from interfering with C3 CPU state
1490 */
1491 pci_read_config_dword(pdev, 0x40, &val);
1492 if ((val & 0x0000ff00) != 0)
1493 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
1494
1495 return 0;
1496}
1497
1498#endif /* CONFIG_PM */
1499
1500MODULE_DEVICE_TABLE(pci, ath_pci_id_table);
1501
1502static struct pci_driver ath_pci_driver = {
1503 .name = "ath9k",
1504 .id_table = ath_pci_id_table,
1505 .probe = ath_pci_probe,
1506 .remove = ath_pci_remove,
1507#ifdef CONFIG_PM
1508 .suspend = ath_pci_suspend,
1509 .resume = ath_pci_resume,
1510#endif /* CONFIG_PM */
1511};
1512
1513static int __init init_ath_pci(void)
1514{
1515 printk(KERN_INFO "%s: %s\n", dev_info, ATH_PCI_VERSION);
1516
1517 if (pci_register_driver(&ath_pci_driver) < 0) {
1518 printk(KERN_ERR
1519 "ath_pci: No devices found, driver not installed.\n");
1520 pci_unregister_driver(&ath_pci_driver);
1521 return -ENODEV;
1522 }
1523
1524 return 0;
1525}
1526module_init(init_ath_pci);
1527
1528static void __exit exit_ath_pci(void)
1529{
1530 pci_unregister_driver(&ath_pci_driver);
1531 printk(KERN_INFO "%s: driver unloaded\n", dev_info);
1532}
1533module_exit(exit_ath_pci);
diff --git a/drivers/net/wireless/ath9k/phy.c b/drivers/net/wireless/ath9k/phy.c
new file mode 100644
index 000000000000..eb9121fdfd38
--- /dev/null
+++ b/drivers/net/wireless/ath9k/phy.c
@@ -0,0 +1,436 @@
1/*
2 * Copyright (c) 2008 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 "core.h"
18#include "hw.h"
19#include "reg.h"
20#include "phy.h"
21
22void
23ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex, u32 freqIndex,
24 int regWrites)
25{
26 struct ath_hal_5416 *ahp = AH5416(ah);
27
28 REG_WRITE_ARRAY(&ahp->ah_iniBB_RfGain, freqIndex, regWrites);
29}
30
31bool
32ath9k_hw_set_channel(struct ath_hal *ah, struct ath9k_channel *chan)
33{
34 u32 channelSel = 0;
35 u32 bModeSynth = 0;
36 u32 aModeRefSel = 0;
37 u32 reg32 = 0;
38 u16 freq;
39 struct chan_centers centers;
40
41 ath9k_hw_get_channel_centers(ah, chan, &centers);
42 freq = centers.synth_center;
43
44 if (freq < 4800) {
45 u32 txctl;
46
47 if (((freq - 2192) % 5) == 0) {
48 channelSel = ((freq - 672) * 2 - 3040) / 10;
49 bModeSynth = 0;
50 } else if (((freq - 2224) % 5) == 0) {
51 channelSel = ((freq - 704) * 2 - 3040) / 10;
52 bModeSynth = 1;
53 } else {
54 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
55 "%s: invalid channel %u MHz\n", __func__,
56 freq);
57 return false;
58 }
59
60 channelSel = (channelSel << 2) & 0xff;
61 channelSel = ath9k_hw_reverse_bits(channelSel, 8);
62
63 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
64 if (freq == 2484) {
65
66 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
67 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
68 } else {
69 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
70 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
71 }
72
73 } else if ((freq % 20) == 0 && freq >= 5120) {
74 channelSel =
75 ath9k_hw_reverse_bits(((freq - 4800) / 20 << 2), 8);
76 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
77 } else if ((freq % 10) == 0) {
78 channelSel =
79 ath9k_hw_reverse_bits(((freq - 4800) / 10 << 1), 8);
80 if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah))
81 aModeRefSel = ath9k_hw_reverse_bits(2, 2);
82 else
83 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
84 } else if ((freq % 5) == 0) {
85 channelSel = ath9k_hw_reverse_bits((freq - 4800) / 5, 8);
86 aModeRefSel = ath9k_hw_reverse_bits(1, 2);
87 } else {
88 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
89 "%s: invalid channel %u MHz\n", __func__, freq);
90 return false;
91 }
92
93 reg32 =
94 (channelSel << 8) | (aModeRefSel << 2) | (bModeSynth << 1) |
95 (1 << 5) | 0x1;
96
97 REG_WRITE(ah, AR_PHY(0x37), reg32);
98
99 ah->ah_curchan = chan;
100
101 AH5416(ah)->ah_curchanRadIndex = -1;
102
103 return true;
104}
105
106bool
107ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
108 struct ath9k_channel *chan)
109{
110 u16 bMode, fracMode, aModeRefSel = 0;
111 u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
112 struct chan_centers centers;
113 u32 refDivA = 24;
114
115 ath9k_hw_get_channel_centers(ah, chan, &centers);
116 freq = centers.synth_center;
117
118 reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
119 reg32 &= 0xc0000000;
120
121 if (freq < 4800) {
122 u32 txctl;
123
124 bMode = 1;
125 fracMode = 1;
126 aModeRefSel = 0;
127 channelSel = (freq * 0x10000) / 15;
128
129 txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
130 if (freq == 2484) {
131
132 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
133 txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
134 } else {
135 REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
136 txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
137 }
138 } else {
139 bMode = 0;
140 fracMode = 0;
141
142 if ((freq % 20) == 0) {
143 aModeRefSel = 3;
144 } else if ((freq % 10) == 0) {
145 aModeRefSel = 2;
146 } else {
147 aModeRefSel = 0;
148
149 fracMode = 1;
150 refDivA = 1;
151 channelSel = (freq * 0x8000) / 15;
152
153 REG_RMW_FIELD(ah, AR_AN_SYNTH9,
154 AR_AN_SYNTH9_REFDIVA, refDivA);
155 }
156 if (!fracMode) {
157 ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
158 channelSel = ndiv & 0x1ff;
159 channelFrac = (ndiv & 0xfffffe00) * 2;
160 channelSel = (channelSel << 17) | channelFrac;
161 }
162 }
163
164 reg32 = reg32 |
165 (bMode << 29) |
166 (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
167
168 REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
169
170 ah->ah_curchan = chan;
171
172 AH5416(ah)->ah_curchanRadIndex = -1;
173
174 return true;
175}
176
177static void
178ath9k_phy_modify_rx_buffer(u32 *rfBuf, u32 reg32,
179 u32 numBits, u32 firstBit,
180 u32 column)
181{
182 u32 tmp32, mask, arrayEntry, lastBit;
183 int32_t bitPosition, bitsLeft;
184
185 tmp32 = ath9k_hw_reverse_bits(reg32, numBits);
186 arrayEntry = (firstBit - 1) / 8;
187 bitPosition = (firstBit - 1) % 8;
188 bitsLeft = numBits;
189 while (bitsLeft > 0) {
190 lastBit = (bitPosition + bitsLeft > 8) ?
191 8 : bitPosition + bitsLeft;
192 mask = (((1 << lastBit) - 1) ^ ((1 << bitPosition) - 1)) <<
193 (column * 8);
194 rfBuf[arrayEntry] &= ~mask;
195 rfBuf[arrayEntry] |= ((tmp32 << bitPosition) <<
196 (column * 8)) & mask;
197 bitsLeft -= 8 - bitPosition;
198 tmp32 = tmp32 >> (8 - bitPosition);
199 bitPosition = 0;
200 arrayEntry++;
201 }
202}
203
204bool
205ath9k_hw_set_rf_regs(struct ath_hal *ah, struct ath9k_channel *chan,
206 u16 modesIndex)
207{
208 struct ath_hal_5416 *ahp = AH5416(ah);
209
210 u32 eepMinorRev;
211 u32 ob5GHz = 0, db5GHz = 0;
212 u32 ob2GHz = 0, db2GHz = 0;
213 int regWrites = 0;
214
215 if (AR_SREV_9280_10_OR_LATER(ah))
216 return true;
217
218 eepMinorRev = ath9k_hw_get_eeprom(ahp, EEP_MINOR_REV);
219
220 RF_BANK_SETUP(ahp->ah_analogBank0Data, &ahp->ah_iniBank0, 1);
221
222 RF_BANK_SETUP(ahp->ah_analogBank1Data, &ahp->ah_iniBank1, 1);
223
224 RF_BANK_SETUP(ahp->ah_analogBank2Data, &ahp->ah_iniBank2, 1);
225
226 RF_BANK_SETUP(ahp->ah_analogBank3Data, &ahp->ah_iniBank3,
227 modesIndex);
228 {
229 int i;
230 for (i = 0; i < ahp->ah_iniBank6TPC.ia_rows; i++) {
231 ahp->ah_analogBank6Data[i] =
232 INI_RA(&ahp->ah_iniBank6TPC, i, modesIndex);
233 }
234 }
235
236 if (eepMinorRev >= 2) {
237 if (IS_CHAN_2GHZ(chan)) {
238 ob2GHz = ath9k_hw_get_eeprom(ahp, EEP_OB_2);
239 db2GHz = ath9k_hw_get_eeprom(ahp, EEP_DB_2);
240 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
241 ob2GHz, 3, 197, 0);
242 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
243 db2GHz, 3, 194, 0);
244 } else {
245 ob5GHz = ath9k_hw_get_eeprom(ahp, EEP_OB_5);
246 db5GHz = ath9k_hw_get_eeprom(ahp, EEP_DB_5);
247 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
248 ob5GHz, 3, 203, 0);
249 ath9k_phy_modify_rx_buffer(ahp->ah_analogBank6Data,
250 db5GHz, 3, 200, 0);
251 }
252 }
253
254 RF_BANK_SETUP(ahp->ah_analogBank7Data, &ahp->ah_iniBank7, 1);
255
256 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank0, ahp->ah_analogBank0Data,
257 regWrites);
258 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank1, ahp->ah_analogBank1Data,
259 regWrites);
260 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank2, ahp->ah_analogBank2Data,
261 regWrites);
262 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank3, ahp->ah_analogBank3Data,
263 regWrites);
264 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6TPC, ahp->ah_analogBank6Data,
265 regWrites);
266 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank7, ahp->ah_analogBank7Data,
267 regWrites);
268
269 return true;
270}
271
272void
273ath9k_hw_rfdetach(struct ath_hal *ah)
274{
275 struct ath_hal_5416 *ahp = AH5416(ah);
276
277 if (ahp->ah_analogBank0Data != NULL) {
278 kfree(ahp->ah_analogBank0Data);
279 ahp->ah_analogBank0Data = NULL;
280 }
281 if (ahp->ah_analogBank1Data != NULL) {
282 kfree(ahp->ah_analogBank1Data);
283 ahp->ah_analogBank1Data = NULL;
284 }
285 if (ahp->ah_analogBank2Data != NULL) {
286 kfree(ahp->ah_analogBank2Data);
287 ahp->ah_analogBank2Data = NULL;
288 }
289 if (ahp->ah_analogBank3Data != NULL) {
290 kfree(ahp->ah_analogBank3Data);
291 ahp->ah_analogBank3Data = NULL;
292 }
293 if (ahp->ah_analogBank6Data != NULL) {
294 kfree(ahp->ah_analogBank6Data);
295 ahp->ah_analogBank6Data = NULL;
296 }
297 if (ahp->ah_analogBank6TPCData != NULL) {
298 kfree(ahp->ah_analogBank6TPCData);
299 ahp->ah_analogBank6TPCData = NULL;
300 }
301 if (ahp->ah_analogBank7Data != NULL) {
302 kfree(ahp->ah_analogBank7Data);
303 ahp->ah_analogBank7Data = NULL;
304 }
305 if (ahp->ah_addac5416_21 != NULL) {
306 kfree(ahp->ah_addac5416_21);
307 ahp->ah_addac5416_21 = NULL;
308 }
309 if (ahp->ah_bank6Temp != NULL) {
310 kfree(ahp->ah_bank6Temp);
311 ahp->ah_bank6Temp = NULL;
312 }
313}
314
315bool ath9k_hw_init_rf(struct ath_hal *ah, int *status)
316{
317 struct ath_hal_5416 *ahp = AH5416(ah);
318
319 if (!AR_SREV_9280_10_OR_LATER(ah)) {
320
321 ahp->ah_analogBank0Data =
322 kzalloc((sizeof(u32) *
323 ahp->ah_iniBank0.ia_rows), GFP_KERNEL);
324 ahp->ah_analogBank1Data =
325 kzalloc((sizeof(u32) *
326 ahp->ah_iniBank1.ia_rows), GFP_KERNEL);
327 ahp->ah_analogBank2Data =
328 kzalloc((sizeof(u32) *
329 ahp->ah_iniBank2.ia_rows), GFP_KERNEL);
330 ahp->ah_analogBank3Data =
331 kzalloc((sizeof(u32) *
332 ahp->ah_iniBank3.ia_rows), GFP_KERNEL);
333 ahp->ah_analogBank6Data =
334 kzalloc((sizeof(u32) *
335 ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
336 ahp->ah_analogBank6TPCData =
337 kzalloc((sizeof(u32) *
338 ahp->ah_iniBank6TPC.ia_rows), GFP_KERNEL);
339 ahp->ah_analogBank7Data =
340 kzalloc((sizeof(u32) *
341 ahp->ah_iniBank7.ia_rows), GFP_KERNEL);
342
343 if (ahp->ah_analogBank0Data == NULL
344 || ahp->ah_analogBank1Data == NULL
345 || ahp->ah_analogBank2Data == NULL
346 || ahp->ah_analogBank3Data == NULL
347 || ahp->ah_analogBank6Data == NULL
348 || ahp->ah_analogBank6TPCData == NULL
349 || ahp->ah_analogBank7Data == NULL) {
350 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
351 "%s: cannot allocate RF banks\n",
352 __func__);
353 *status = -ENOMEM;
354 return false;
355 }
356
357 ahp->ah_addac5416_21 =
358 kzalloc((sizeof(u32) *
359 ahp->ah_iniAddac.ia_rows *
360 ahp->ah_iniAddac.ia_columns), GFP_KERNEL);
361 if (ahp->ah_addac5416_21 == NULL) {
362 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
363 "%s: cannot allocate ah_addac5416_21\n",
364 __func__);
365 *status = -ENOMEM;
366 return false;
367 }
368
369 ahp->ah_bank6Temp =
370 kzalloc((sizeof(u32) *
371 ahp->ah_iniBank6.ia_rows), GFP_KERNEL);
372 if (ahp->ah_bank6Temp == NULL) {
373 DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
374 "%s: cannot allocate ah_bank6Temp\n",
375 __func__);
376 *status = -ENOMEM;
377 return false;
378 }
379 }
380
381 return true;
382}
383
384void
385ath9k_hw_decrease_chain_power(struct ath_hal *ah, struct ath9k_channel *chan)
386{
387 int i, regWrites = 0;
388 struct ath_hal_5416 *ahp = AH5416(ah);
389 u32 bank6SelMask;
390 u32 *bank6Temp = ahp->ah_bank6Temp;
391
392 switch (ahp->ah_diversityControl) {
393 case ATH9K_ANT_FIXED_A:
394 bank6SelMask =
395 (ahp->
396 ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_0 :
397 REDUCE_CHAIN_1;
398 break;
399 case ATH9K_ANT_FIXED_B:
400 bank6SelMask =
401 (ahp->
402 ah_antennaSwitchSwap & ANTSWAP_AB) ? REDUCE_CHAIN_1 :
403 REDUCE_CHAIN_0;
404 break;
405 case ATH9K_ANT_VARIABLE:
406 return;
407 break;
408 default:
409 return;
410 break;
411 }
412
413 for (i = 0; i < ahp->ah_iniBank6.ia_rows; i++)
414 bank6Temp[i] = ahp->ah_analogBank6Data[i];
415
416 REG_WRITE(ah, AR_PHY_BASE + 0xD8, bank6SelMask);
417
418 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 189, 0);
419 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 190, 0);
420 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 191, 0);
421 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 192, 0);
422 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 193, 0);
423 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 222, 0);
424 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 245, 0);
425 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 246, 0);
426 ath9k_phy_modify_rx_buffer(bank6Temp, 1, 1, 247, 0);
427
428 REG_WRITE_RF_ARRAY(&ahp->ah_iniBank6, bank6Temp, regWrites);
429
430 REG_WRITE(ah, AR_PHY_BASE + 0xD8, 0x00000053);
431#ifdef ALTER_SWITCH
432 REG_WRITE(ah, PHY_SWITCH_CHAIN_0,
433 (REG_READ(ah, PHY_SWITCH_CHAIN_0) & ~0x38)
434 | ((REG_READ(ah, PHY_SWITCH_CHAIN_0) >> 3) & 0x38));
435#endif
436}
diff --git a/drivers/net/wireless/ath9k/phy.h b/drivers/net/wireless/ath9k/phy.h
new file mode 100644
index 000000000000..0cd399a5344a
--- /dev/null
+++ b/drivers/net/wireless/ath9k/phy.h
@@ -0,0 +1,543 @@
1/*
2 * Copyright (c) 2008 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#ifndef PHY_H
18#define PHY_H
19
20bool ath9k_hw_ar9280_set_channel(struct ath_hal *ah,
21 struct ath9k_channel
22 *chan);
23bool ath9k_hw_set_channel(struct ath_hal *ah,
24 struct ath9k_channel *chan);
25void ath9k_hw_write_regs(struct ath_hal *ah, u32 modesIndex,
26 u32 freqIndex, int regWrites);
27bool ath9k_hw_set_rf_regs(struct ath_hal *ah,
28 struct ath9k_channel *chan,
29 u16 modesIndex);
30void ath9k_hw_decrease_chain_power(struct ath_hal *ah,
31 struct ath9k_channel *chan);
32bool ath9k_hw_init_rf(struct ath_hal *ah,
33 int *status);
34
35#define AR_PHY_BASE 0x9800
36#define AR_PHY(_n) (AR_PHY_BASE + ((_n)<<2))
37
38#define AR_PHY_TEST 0x9800
39#define PHY_AGC_CLR 0x10000000
40#define RFSILENT_BB 0x00002000
41
42#define AR_PHY_TURBO 0x9804
43#define AR_PHY_FC_TURBO_MODE 0x00000001
44#define AR_PHY_FC_TURBO_SHORT 0x00000002
45#define AR_PHY_FC_DYN2040_EN 0x00000004
46#define AR_PHY_FC_DYN2040_PRI_ONLY 0x00000008
47#define AR_PHY_FC_DYN2040_PRI_CH 0x00000010
48#define AR_PHY_FC_DYN2040_EXT_CH 0x00000020
49#define AR_PHY_FC_HT_EN 0x00000040
50#define AR_PHY_FC_SHORT_GI_40 0x00000080
51#define AR_PHY_FC_WALSH 0x00000100
52#define AR_PHY_FC_SINGLE_HT_LTF1 0x00000200
53
54#define AR_PHY_TIMING2 0x9810
55#define AR_PHY_TIMING3 0x9814
56#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
57#define AR_PHY_TIMING3_DSC_MAN_S 17
58#define AR_PHY_TIMING3_DSC_EXP 0x0001E000
59#define AR_PHY_TIMING3_DSC_EXP_S 13
60
61#define AR_PHY_CHIP_ID 0x9818
62#define AR_PHY_CHIP_ID_REV_0 0x80
63#define AR_PHY_CHIP_ID_REV_1 0x81
64#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
65
66#define AR_PHY_ACTIVE 0x981C
67#define AR_PHY_ACTIVE_EN 0x00000001
68#define AR_PHY_ACTIVE_DIS 0x00000000
69
70#define AR_PHY_RF_CTL2 0x9824
71#define AR_PHY_TX_END_DATA_START 0x000000FF
72#define AR_PHY_TX_END_DATA_START_S 0
73#define AR_PHY_TX_END_PA_ON 0x0000FF00
74#define AR_PHY_TX_END_PA_ON_S 8
75
76#define AR_PHY_RF_CTL3 0x9828
77#define AR_PHY_TX_END_TO_A2_RX_ON 0x00FF0000
78#define AR_PHY_TX_END_TO_A2_RX_ON_S 16
79
80#define AR_PHY_ADC_CTL 0x982C
81#define AR_PHY_ADC_CTL_OFF_INBUFGAIN 0x00000003
82#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S 0
83#define AR_PHY_ADC_CTL_OFF_PWDDAC 0x00002000
84#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP 0x00004000
85#define AR_PHY_ADC_CTL_OFF_PWDADC 0x00008000
86#define AR_PHY_ADC_CTL_ON_INBUFGAIN 0x00030000
87#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S 16
88
89#define AR_PHY_ADC_SERIAL_CTL 0x9830
90#define AR_PHY_SEL_INTERNAL_ADDAC 0x00000000
91#define AR_PHY_SEL_EXTERNAL_RADIO 0x00000001
92
93#define AR_PHY_RF_CTL4 0x9834
94#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF 0xFF000000
95#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S 24
96#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF 0x00FF0000
97#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S 16
98#define AR_PHY_RF_CTL4_FRAME_XPAB_ON 0x0000FF00
99#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S 8
100#define AR_PHY_RF_CTL4_FRAME_XPAA_ON 0x000000FF
101#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S 0
102
103#define AR_PHY_SETTLING 0x9844
104#define AR_PHY_SETTLING_SWITCH 0x00003F80
105#define AR_PHY_SETTLING_SWITCH_S 7
106
107#define AR_PHY_RXGAIN 0x9848
108#define AR_PHY_RXGAIN_TXRX_ATTEN 0x0003F000
109#define AR_PHY_RXGAIN_TXRX_ATTEN_S 12
110#define AR_PHY_RXGAIN_TXRX_RF_MAX 0x007C0000
111#define AR_PHY_RXGAIN_TXRX_RF_MAX_S 18
112#define AR9280_PHY_RXGAIN_TXRX_ATTEN 0x00003F80
113#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S 7
114#define AR9280_PHY_RXGAIN_TXRX_MARGIN 0x001FC000
115#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
116
117#define AR_PHY_DESIRED_SZ 0x9850
118#define AR_PHY_DESIRED_SZ_ADC 0x000000FF
119#define AR_PHY_DESIRED_SZ_ADC_S 0
120#define AR_PHY_DESIRED_SZ_PGA 0x0000FF00
121#define AR_PHY_DESIRED_SZ_PGA_S 8
122#define AR_PHY_DESIRED_SZ_TOT_DES 0x0FF00000
123#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
124
125#define AR_PHY_FIND_SIG 0x9858
126#define AR_PHY_FIND_SIG_FIRSTEP 0x0003F000
127#define AR_PHY_FIND_SIG_FIRSTEP_S 12
128#define AR_PHY_FIND_SIG_FIRPWR 0x03FC0000
129#define AR_PHY_FIND_SIG_FIRPWR_S 18
130
131#define AR_PHY_AGC_CTL1 0x985C
132#define AR_PHY_AGC_CTL1_COARSE_LOW 0x00007F80
133#define AR_PHY_AGC_CTL1_COARSE_LOW_S 7
134#define AR_PHY_AGC_CTL1_COARSE_HIGH 0x003F8000
135#define AR_PHY_AGC_CTL1_COARSE_HIGH_S 15
136
137#define AR_PHY_AGC_CONTROL 0x9860
138#define AR_PHY_AGC_CONTROL_CAL 0x00000001
139#define AR_PHY_AGC_CONTROL_NF 0x00000002
140#define AR_PHY_AGC_CONTROL_ENABLE_NF 0x00008000
141#define AR_PHY_AGC_CONTROL_FLTR_CAL 0x00010000
142#define AR_PHY_AGC_CONTROL_NO_UPDATE_NF 0x00020000
143
144#define AR_PHY_CCA 0x9864
145#define AR_PHY_MINCCA_PWR 0x0FF80000
146#define AR_PHY_MINCCA_PWR_S 19
147#define AR_PHY_CCA_THRESH62 0x0007F000
148#define AR_PHY_CCA_THRESH62_S 12
149#define AR9280_PHY_MINCCA_PWR 0x1FF00000
150#define AR9280_PHY_MINCCA_PWR_S 20
151#define AR9280_PHY_CCA_THRESH62 0x000FF000
152#define AR9280_PHY_CCA_THRESH62_S 12
153
154#define AR_PHY_SFCORR_LOW 0x986C
155#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW 0x00000001
156#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW 0x00003F00
157#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S 8
158#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW 0x001FC000
159#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S 14
160#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW 0x0FE00000
161#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S 21
162
163#define AR_PHY_SFCORR 0x9868
164#define AR_PHY_SFCORR_M2COUNT_THR 0x0000001F
165#define AR_PHY_SFCORR_M2COUNT_THR_S 0
166#define AR_PHY_SFCORR_M1_THRESH 0x00FE0000
167#define AR_PHY_SFCORR_M1_THRESH_S 17
168#define AR_PHY_SFCORR_M2_THRESH 0x7F000000
169#define AR_PHY_SFCORR_M2_THRESH_S 24
170
171#define AR_PHY_SLEEP_CTR_CONTROL 0x9870
172#define AR_PHY_SLEEP_CTR_LIMIT 0x9874
173#define AR_PHY_SYNTH_CONTROL 0x9874
174#define AR_PHY_SLEEP_SCAL 0x9878
175
176#define AR_PHY_PLL_CTL 0x987c
177#define AR_PHY_PLL_CTL_40 0xaa
178#define AR_PHY_PLL_CTL_40_5413 0x04
179#define AR_PHY_PLL_CTL_44 0xab
180#define AR_PHY_PLL_CTL_44_2133 0xeb
181#define AR_PHY_PLL_CTL_40_2133 0xea
182
183#define AR_PHY_RX_DELAY 0x9914
184#define AR_PHY_SEARCH_START_DELAY 0x9918
185#define AR_PHY_RX_DELAY_DELAY 0x00003FFF
186
187#define AR_PHY_TIMING_CTRL4(_i) (0x9920 + ((_i) << 12))
188#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
189#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S 0
190#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
191#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S 5
192#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE 0x800
193#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
194#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S 12
195#define AR_PHY_TIMING_CTRL4_DO_CAL 0x10000
196
197#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI 0x80000000
198#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER 0x40000000
199#define AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK 0x20000000
200#define AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK 0x10000000
201
202#define AR_PHY_TIMING5 0x9924
203#define AR_PHY_TIMING5_CYCPWR_THR1 0x000000FE
204#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
205
206#define AR_PHY_POWER_TX_RATE1 0x9934
207#define AR_PHY_POWER_TX_RATE2 0x9938
208#define AR_PHY_POWER_TX_RATE_MAX 0x993c
209#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
210
211#define AR_PHY_FRAME_CTL 0x9944
212#define AR_PHY_FRAME_CTL_TX_CLIP 0x00000038
213#define AR_PHY_FRAME_CTL_TX_CLIP_S 3
214
215#define AR_PHY_TXPWRADJ 0x994C
216#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA 0x00000FC0
217#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S 6
218#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX 0x00FC0000
219#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
220
221#define AR_PHY_RADAR_EXT 0x9940
222#define AR_PHY_RADAR_EXT_ENA 0x00004000
223
224#define AR_PHY_RADAR_0 0x9954
225#define AR_PHY_RADAR_0_ENA 0x00000001
226#define AR_PHY_RADAR_0_FFT_ENA 0x80000000
227#define AR_PHY_RADAR_0_INBAND 0x0000003e
228#define AR_PHY_RADAR_0_INBAND_S 1
229#define AR_PHY_RADAR_0_PRSSI 0x00000FC0
230#define AR_PHY_RADAR_0_PRSSI_S 6
231#define AR_PHY_RADAR_0_HEIGHT 0x0003F000
232#define AR_PHY_RADAR_0_HEIGHT_S 12
233#define AR_PHY_RADAR_0_RRSSI 0x00FC0000
234#define AR_PHY_RADAR_0_RRSSI_S 18
235#define AR_PHY_RADAR_0_FIRPWR 0x7F000000
236#define AR_PHY_RADAR_0_FIRPWR_S 24
237
238#define AR_PHY_RADAR_1 0x9958
239#define AR_PHY_RADAR_1_RELPWR_ENA 0x00800000
240#define AR_PHY_RADAR_1_USE_FIR128 0x00400000
241#define AR_PHY_RADAR_1_RELPWR_THRESH 0x003F0000
242#define AR_PHY_RADAR_1_RELPWR_THRESH_S 16
243#define AR_PHY_RADAR_1_BLOCK_CHECK 0x00008000
244#define AR_PHY_RADAR_1_MAX_RRSSI 0x00004000
245#define AR_PHY_RADAR_1_RELSTEP_CHECK 0x00002000
246#define AR_PHY_RADAR_1_RELSTEP_THRESH 0x00001F00
247#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
248#define AR_PHY_RADAR_1_MAXLEN 0x000000FF
249#define AR_PHY_RADAR_1_MAXLEN_S 0
250
251#define AR_PHY_SWITCH_CHAIN_0 0x9960
252#define AR_PHY_SWITCH_COM 0x9964
253
254#define AR_PHY_SIGMA_DELTA 0x996C
255#define AR_PHY_SIGMA_DELTA_ADC_SEL 0x00000003
256#define AR_PHY_SIGMA_DELTA_ADC_SEL_S 0
257#define AR_PHY_SIGMA_DELTA_FILT2 0x000000F8
258#define AR_PHY_SIGMA_DELTA_FILT2_S 3
259#define AR_PHY_SIGMA_DELTA_FILT1 0x00001F00
260#define AR_PHY_SIGMA_DELTA_FILT1_S 8
261#define AR_PHY_SIGMA_DELTA_ADC_CLIP 0x01FFE000
262#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
263
264#define AR_PHY_RESTART 0x9970
265#define AR_PHY_RESTART_DIV_GC 0x001C0000
266#define AR_PHY_RESTART_DIV_GC_S 18
267
268#define AR_PHY_RFBUS_REQ 0x997C
269#define AR_PHY_RFBUS_REQ_EN 0x00000001
270
271#define AR_PHY_TIMING7 0x9980
272#define AR_PHY_TIMING8 0x9984
273#define AR_PHY_TIMING8_PILOT_MASK_2 0x000FFFFF
274#define AR_PHY_TIMING8_PILOT_MASK_2_S 0
275
276#define AR_PHY_BIN_MASK2_1 0x9988
277#define AR_PHY_BIN_MASK2_2 0x998c
278#define AR_PHY_BIN_MASK2_3 0x9990
279#define AR_PHY_BIN_MASK2_4 0x9994
280
281#define AR_PHY_BIN_MASK_1 0x9900
282#define AR_PHY_BIN_MASK_2 0x9904
283#define AR_PHY_BIN_MASK_3 0x9908
284
285#define AR_PHY_MASK_CTL 0x990c
286
287#define AR_PHY_BIN_MASK2_4_MASK_4 0x00003FFF
288#define AR_PHY_BIN_MASK2_4_MASK_4_S 0
289
290#define AR_PHY_TIMING9 0x9998
291#define AR_PHY_TIMING10 0x999c
292#define AR_PHY_TIMING10_PILOT_MASK_2 0x000FFFFF
293#define AR_PHY_TIMING10_PILOT_MASK_2_S 0
294
295#define AR_PHY_TIMING11 0x99a0
296#define AR_PHY_TIMING11_SPUR_DELTA_PHASE 0x000FFFFF
297#define AR_PHY_TIMING11_SPUR_DELTA_PHASE_S 0
298#define AR_PHY_TIMING11_SPUR_FREQ_SD 0x3FF00000
299#define AR_PHY_TIMING11_SPUR_FREQ_SD_S 20
300#define AR_PHY_TIMING11_USE_SPUR_IN_AGC 0x40000000
301#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR 0x80000000
302
303#define AR_PHY_RX_CHAINMASK 0x99a4
304#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
305#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
306#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
307#define AR_PHY_MULTICHAIN_GAIN_CTL 0x99ac
308
309#define AR_PHY_EXT_CCA0 0x99b8
310#define AR_PHY_EXT_CCA0_THRESH62 0x000000FF
311#define AR_PHY_EXT_CCA0_THRESH62_S 0
312
313#define AR_PHY_EXT_CCA 0x99bc
314#define AR_PHY_EXT_CCA_CYCPWR_THR1 0x0000FE00
315#define AR_PHY_EXT_CCA_CYCPWR_THR1_S 9
316#define AR_PHY_EXT_CCA_THRESH62 0x007F0000
317#define AR_PHY_EXT_CCA_THRESH62_S 16
318#define AR_PHY_EXT_MINCCA_PWR 0xFF800000
319#define AR_PHY_EXT_MINCCA_PWR_S 23
320#define AR9280_PHY_EXT_MINCCA_PWR 0x01FF0000
321#define AR9280_PHY_EXT_MINCCA_PWR_S 16
322
323#define AR_PHY_SFCORR_EXT 0x99c0
324#define AR_PHY_SFCORR_EXT_M1_THRESH 0x0000007F
325#define AR_PHY_SFCORR_EXT_M1_THRESH_S 0
326#define AR_PHY_SFCORR_EXT_M2_THRESH 0x00003F80
327#define AR_PHY_SFCORR_EXT_M2_THRESH_S 7
328#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW 0x001FC000
329#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
330#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW 0x0FE00000
331#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
332#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S 28
333
334#define AR_PHY_HALFGI 0x99D0
335#define AR_PHY_HALFGI_DSC_MAN 0x0007FFF0
336#define AR_PHY_HALFGI_DSC_MAN_S 4
337#define AR_PHY_HALFGI_DSC_EXP 0x0000000F
338#define AR_PHY_HALFGI_DSC_EXP_S 0
339
340#define AR_PHY_CHAN_INFO_MEMORY 0x99DC
341#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK 0x0001
342
343#define AR_PHY_HEAVY_CLIP_ENABLE 0x99E0
344
345#define AR_PHY_M_SLEEP 0x99f0
346#define AR_PHY_REFCLKDLY 0x99f4
347#define AR_PHY_REFCLKPD 0x99f8
348
349#define AR_PHY_CALMODE 0x99f0
350
351#define AR_PHY_CALMODE_IQ 0x00000000
352#define AR_PHY_CALMODE_ADC_GAIN 0x00000001
353#define AR_PHY_CALMODE_ADC_DC_PER 0x00000002
354#define AR_PHY_CALMODE_ADC_DC_INIT 0x00000003
355
356#define AR_PHY_CAL_MEAS_0(_i) (0x9c10 + ((_i) << 12))
357#define AR_PHY_CAL_MEAS_1(_i) (0x9c14 + ((_i) << 12))
358#define AR_PHY_CAL_MEAS_2(_i) (0x9c18 + ((_i) << 12))
359#define AR_PHY_CAL_MEAS_3(_i) (0x9c1c + ((_i) << 12))
360
361#define AR_PHY_CURRENT_RSSI 0x9c1c
362#define AR9280_PHY_CURRENT_RSSI 0x9c3c
363
364#define AR_PHY_RFBUS_GRANT 0x9C20
365#define AR_PHY_RFBUS_GRANT_EN 0x00000001
366
367#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
368#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
369
370#define AR_PHY_CHAN_INFO_GAIN 0x9CFC
371
372#define AR_PHY_MODE 0xA200
373#define AR_PHY_MODE_AR2133 0x08
374#define AR_PHY_MODE_AR5111 0x00
375#define AR_PHY_MODE_AR5112 0x08
376#define AR_PHY_MODE_DYNAMIC 0x04
377#define AR_PHY_MODE_RF2GHZ 0x02
378#define AR_PHY_MODE_RF5GHZ 0x00
379#define AR_PHY_MODE_CCK 0x01
380#define AR_PHY_MODE_OFDM 0x00
381#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
382
383#define AR_PHY_CCK_TX_CTRL 0xA204
384#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
385
386#define AR_PHY_CCK_DETECT 0xA208
387#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK 0x0000003F
388#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S 0
389/* [12:6] settling time for antenna switch */
390#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME 0x00001FC0
391#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S 6
392#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV 0x2000
393
394#define AR_PHY_GAIN_2GHZ 0xA20C
395#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN 0x00FC0000
396#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S 18
397#define AR_PHY_GAIN_2GHZ_BSW_MARGIN 0x00003C00
398#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S 10
399#define AR_PHY_GAIN_2GHZ_BSW_ATTEN 0x0000001F
400#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S 0
401
402#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN 0x003E0000
403#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S 17
404#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN 0x0001F000
405#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S 12
406#define AR_PHY_GAIN_2GHZ_XATTEN2_DB 0x00000FC0
407#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S 6
408#define AR_PHY_GAIN_2GHZ_XATTEN1_DB 0x0000003F
409#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S 0
410
411#define AR_PHY_CCK_RXCTRL4 0xA21C
412#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT 0x01F80000
413#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
414
415#define AR_PHY_DAG_CTRLCCK 0xA228
416#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR 0x00000200
417#define AR_PHY_DAG_CTRLCCK_RSSI_THR 0x0001FC00
418#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S 10
419
420#define AR_PHY_FORCE_CLKEN_CCK 0xA22C
421#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX 0x00000040
422
423#define AR_PHY_POWER_TX_RATE3 0xA234
424#define AR_PHY_POWER_TX_RATE4 0xA238
425
426#define AR_PHY_SCRM_SEQ_XR 0xA23C
427#define AR_PHY_HEADER_DETECT_XR 0xA240
428#define AR_PHY_CHIRP_DETECTED_XR 0xA244
429#define AR_PHY_BLUETOOTH 0xA254
430
431#define AR_PHY_TPCRG1 0xA258
432#define AR_PHY_TPCRG1_NUM_PD_GAIN 0x0000c000
433#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
434
435#define AR_PHY_TPCRG1_PD_GAIN_1 0x00030000
436#define AR_PHY_TPCRG1_PD_GAIN_1_S 16
437#define AR_PHY_TPCRG1_PD_GAIN_2 0x000C0000
438#define AR_PHY_TPCRG1_PD_GAIN_2_S 18
439#define AR_PHY_TPCRG1_PD_GAIN_3 0x00300000
440#define AR_PHY_TPCRG1_PD_GAIN_3_S 20
441
442#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
443#define AR_PHY_MASK2_M_31_45 0xa3a4
444#define AR_PHY_MASK2_M_16_30 0xa3a8
445#define AR_PHY_MASK2_M_00_15 0xa3ac
446#define AR_PHY_MASK2_P_15_01 0xa3b8
447#define AR_PHY_MASK2_P_30_16 0xa3bc
448#define AR_PHY_MASK2_P_45_31 0xa3c0
449#define AR_PHY_MASK2_P_61_45 0xa3c4
450#define AR_PHY_SPUR_REG 0x994c
451
452#define AR_PHY_SPUR_REG_MASK_RATE_CNTL (0xFF << 18)
453#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S 18
454
455#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM 0x20000
456#define AR_PHY_SPUR_REG_MASK_RATE_SELECT (0xFF << 9)
457#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S 9
458#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
459#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH 0x7F
460#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S 0
461
462#define AR_PHY_PILOT_MASK_01_30 0xa3b0
463#define AR_PHY_PILOT_MASK_31_60 0xa3b4
464
465#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
466#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
467
468#define AR_PHY_ANALOG_SWAP 0xa268
469#define AR_PHY_SWAP_ALT_CHAIN 0x00000040
470
471#define AR_PHY_TPCRG5 0xA26C
472#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP 0x0000000F
473#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S 0
474#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1 0x000003F0
475#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S 4
476#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2 0x0000FC00
477#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S 10
478#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3 0x003F0000
479#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S 16
480#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4 0x0FC00000
481#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S 22
482
483#define AR_PHY_POWER_TX_RATE5 0xA38C
484#define AR_PHY_POWER_TX_RATE6 0xA390
485
486#define AR_PHY_CAL_CHAINMASK 0xA39C
487
488#define AR_PHY_POWER_TX_SUB 0xA3C8
489#define AR_PHY_POWER_TX_RATE7 0xA3CC
490#define AR_PHY_POWER_TX_RATE8 0xA3D0
491#define AR_PHY_POWER_TX_RATE9 0xA3D4
492
493#define AR_PHY_XPA_CFG 0xA3D8
494#define AR_PHY_FORCE_XPA_CFG 0x000000001
495#define AR_PHY_FORCE_XPA_CFG_S 0
496
497#define AR_PHY_CH1_CCA 0xa864
498#define AR_PHY_CH1_MINCCA_PWR 0x0FF80000
499#define AR_PHY_CH1_MINCCA_PWR_S 19
500#define AR9280_PHY_CH1_MINCCA_PWR 0x1FF00000
501#define AR9280_PHY_CH1_MINCCA_PWR_S 20
502
503#define AR_PHY_CH2_CCA 0xb864
504#define AR_PHY_CH2_MINCCA_PWR 0x0FF80000
505#define AR_PHY_CH2_MINCCA_PWR_S 19
506
507#define AR_PHY_CH1_EXT_CCA 0xa9bc
508#define AR_PHY_CH1_EXT_MINCCA_PWR 0xFF800000
509#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
510#define AR9280_PHY_CH1_EXT_MINCCA_PWR 0x01FF0000
511#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
512
513#define AR_PHY_CH2_EXT_CCA 0xb9bc
514#define AR_PHY_CH2_EXT_MINCCA_PWR 0xFF800000
515#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
516
517#define REG_WRITE_RF_ARRAY(iniarray, regData, regWr) do { \
518 int r; \
519 for (r = 0; r < ((iniarray)->ia_rows); r++) { \
520 REG_WRITE(ah, INI_RA((iniarray), r, 0), (regData)[r]); \
521 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, \
522 "RF 0x%x V 0x%x\n", \
523 INI_RA((iniarray), r, 0), (regData)[r]); \
524 DO_DELAY(regWr); \
525 } \
526 } while (0)
527
528#define ATH9K_KEY_XOR 0xaa
529
530#define ATH9K_IS_MIC_ENABLED(ah) \
531 (AH5416(ah)->ah_staId1Defaults & AR_STA_ID1_CRPT_MIC_ENABLE)
532
533#define ANTSWAP_AB 0x0001
534#define REDUCE_CHAIN_0 0x00000050
535#define REDUCE_CHAIN_1 0x00000051
536
537#define RF_BANK_SETUP(_bank, _iniarray, _col) do { \
538 int i; \
539 for (i = 0; i < (_iniarray)->ia_rows; i++) \
540 (_bank)[i] = INI_RA((_iniarray), i, _col);; \
541 } while (0)
542
543#endif
diff --git a/drivers/net/wireless/ath9k/rc.c b/drivers/net/wireless/ath9k/rc.c
new file mode 100644
index 000000000000..e0797afee52b
--- /dev/null
+++ b/drivers/net/wireless/ath9k/rc.c
@@ -0,0 +1,2126 @@
1/*
2 * Copyright (c) 2004 Video54 Technologies, Inc.
3 * Copyright (c) 2004-2008 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/*
19 * Atheros rate control algorithm
20 */
21
22#include "core.h"
23#include "../net/mac80211/rate.h"
24
25static u32 tx_triglevel_max;
26
27static struct ath_rate_table ar5416_11na_ratetable = {
28 42,
29 {
30 { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */
31 5400, 0x0b, 0x00, 12,
32 0, 2, 1, 0, 0, 0, 0, 0 },
33 { TRUE, TRUE, WLAN_PHY_OFDM, 9000, /* 9 Mb */
34 7800, 0x0f, 0x00, 18,
35 0, 3, 1, 1, 1, 1, 1, 0 },
36 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 12 Mb */
37 10000, 0x0a, 0x00, 24,
38 2, 4, 2, 2, 2, 2, 2, 0 },
39 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 18 Mb */
40 13900, 0x0e, 0x00, 36,
41 2, 6, 2, 3, 3, 3, 3, 0 },
42 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 24 Mb */
43 17300, 0x09, 0x00, 48,
44 4, 10, 3, 4, 4, 4, 4, 0 },
45 { TRUE, TRUE, WLAN_PHY_OFDM, 36000, /* 36 Mb */
46 23000, 0x0d, 0x00, 72,
47 4, 14, 3, 5, 5, 5, 5, 0 },
48 { TRUE, TRUE, WLAN_PHY_OFDM, 48000, /* 48 Mb */
49 27400, 0x08, 0x00, 96,
50 4, 20, 3, 6, 6, 6, 6, 0 },
51 { TRUE, TRUE, WLAN_PHY_OFDM, 54000, /* 54 Mb */
52 29300, 0x0c, 0x00, 108,
53 4, 23, 3, 7, 7, 7, 7, 0 },
54 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 6500, /* 6.5 Mb */
55 6400, 0x80, 0x00, 0,
56 0, 2, 3, 8, 24, 8, 24, 3216 },
57 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 13000, /* 13 Mb */
58 12700, 0x81, 0x00, 1,
59 2, 4, 3, 9, 25, 9, 25, 6434 },
60 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 19500, /* 19.5 Mb */
61 18800, 0x82, 0x00, 2,
62 2, 6, 3, 10, 26, 10, 26, 9650 },
63 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 26000, /* 26 Mb */
64 25000, 0x83, 0x00, 3,
65 4, 10, 3, 11, 27, 11, 27, 12868 },
66 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 39000, /* 39 Mb */
67 36700, 0x84, 0x00, 4,
68 4, 14, 3, 12, 28, 12, 28, 19304 },
69 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 52000, /* 52 Mb */
70 48100, 0x85, 0x00, 5,
71 4, 20, 3, 13, 29, 13, 29, 25740 },
72 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 58500, /* 58.5 Mb */
73 53500, 0x86, 0x00, 6,
74 4, 23, 3, 14, 30, 14, 30, 28956 },
75 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 65000, /* 65 Mb */
76 59000, 0x87, 0x00, 7,
77 4, 25, 3, 15, 31, 15, 32, 32180 },
78 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 13000, /* 13 Mb */
79 12700, 0x88, 0x00,
80 8, 0, 2, 3, 16, 33, 16, 33, 6430 },
81 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 26000, /* 26 Mb */
82 24800, 0x89, 0x00, 9,
83 2, 4, 3, 17, 34, 17, 34, 12860 },
84 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 39000, /* 39 Mb */
85 36600, 0x8a, 0x00, 10,
86 2, 6, 3, 18, 35, 18, 35, 19300 },
87 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 52000, /* 52 Mb */
88 48100, 0x8b, 0x00, 11,
89 4, 10, 3, 19, 36, 19, 36, 25736 },
90 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 78000, /* 78 Mb */
91 69500, 0x8c, 0x00, 12,
92 4, 14, 3, 20, 37, 20, 37, 38600 },
93 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 104000, /* 104 Mb */
94 89500, 0x8d, 0x00, 13,
95 4, 20, 3, 21, 38, 21, 38, 51472 },
96 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 117000, /* 117 Mb */
97 98900, 0x8e, 0x00, 14,
98 4, 23, 3, 22, 39, 22, 39, 57890 },
99 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 130000, /* 130 Mb */
100 108300, 0x8f, 0x00, 15,
101 4, 25, 3, 23, 40, 23, 41, 64320 },
102 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 13500, /* 13.5 Mb */
103 13200, 0x80, 0x00, 0,
104 0, 2, 3, 8, 24, 24, 24, 6684 },
105 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 27500, /* 27.0 Mb */
106 25900, 0x81, 0x00, 1,
107 2, 4, 3, 9, 25, 25, 25, 13368 },
108 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 40500, /* 40.5 Mb */
109 38600, 0x82, 0x00, 2,
110 2, 6, 3, 10, 26, 26, 26, 20052 },
111 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 54000, /* 54 Mb */
112 49800, 0x83, 0x00, 3,
113 4, 10, 3, 11, 27, 27, 27, 26738 },
114 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 81500, /* 81 Mb */
115 72200, 0x84, 0x00, 4,
116 4, 14, 3, 12, 28, 28, 28, 40104 },
117 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 108000, /* 108 Mb */
118 92900, 0x85, 0x00, 5,
119 4, 20, 3, 13, 29, 29, 29, 53476 },
120 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 121500, /* 121.5 Mb */
121 102700, 0x86, 0x00, 6,
122 4, 23, 3, 14, 30, 30, 30, 60156 },
123 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 135000, /* 135 Mb */
124 112000, 0x87, 0x00, 7,
125 4, 25, 3, 15, 31, 32, 32, 66840 },
126 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
127 122000, 0x87, 0x00, 7,
128 4, 25, 3, 15, 31, 32, 32, 74200 },
129 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 27000, /* 27 Mb */
130 25800, 0x88, 0x00, 8,
131 0, 2, 3, 16, 33, 33, 33, 13360 },
132 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 54000, /* 54 Mb */
133 49800, 0x89, 0x00, 9,
134 2, 4, 3, 17, 34, 34, 34, 26720 },
135 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 81000, /* 81 Mb */
136 71900, 0x8a, 0x00, 10,
137 2, 6, 3, 18, 35, 35, 35, 40080 },
138 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 108000, /* 108 Mb */
139 92500, 0x8b, 0x00, 11,
140 4, 10, 3, 19, 36, 36, 36, 53440 },
141 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 162000, /* 162 Mb */
142 130300, 0x8c, 0x00, 12,
143 4, 14, 3, 20, 37, 37, 37, 80160 },
144 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 216000, /* 216 Mb */
145 162800, 0x8d, 0x00, 13,
146 4, 20, 3, 21, 38, 38, 38, 106880 },
147 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 243000, /* 243 Mb */
148 178200, 0x8e, 0x00, 14,
149 4, 23, 3, 22, 39, 39, 39, 120240 },
150 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 270000, /* 270 Mb */
151 192100, 0x8f, 0x00, 15,
152 4, 25, 3, 23, 40, 41, 41, 133600 },
153 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
154 207000, 0x8f, 0x00, 15,
155 4, 25, 3, 23, 40, 41, 41, 148400 },
156 },
157 50, /* probe interval */
158 50, /* rssi reduce interval */
159 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
160};
161
162/* TRUE_ALL - valid for 20/40/Legacy,
163 * TRUE - Legacy only,
164 * TRUE_20 - HT 20 only,
165 * TRUE_40 - HT 40 only */
166
167/* 4ms frame limit not used for NG mode. The values filled
168 * for HT are the 64K max aggregate limit */
169
170static struct ath_rate_table ar5416_11ng_ratetable = {
171 46,
172 {
173 { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 1000, /* 1 Mb */
174 900, 0x1b, 0x00, 2,
175 0, 0, 1, 0, 0, 0, 0, 0 },
176 { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 2000, /* 2 Mb */
177 1900, 0x1a, 0x04, 4,
178 1, 1, 1, 1, 1, 1, 1, 0 },
179 { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 5500, /* 5.5 Mb */
180 4900, 0x19, 0x04, 11,
181 2, 2, 2, 2, 2, 2, 2, 0 },
182 { TRUE_ALL, TRUE_ALL, WLAN_PHY_CCK, 11000, /* 11 Mb */
183 8100, 0x18, 0x04, 22,
184 3, 3, 2, 3, 3, 3, 3, 0 },
185 { FALSE, FALSE, WLAN_PHY_OFDM, 6000, /* 6 Mb */
186 5400, 0x0b, 0x00, 12,
187 4, 2, 1, 4, 4, 4, 4, 0 },
188 { FALSE, FALSE, WLAN_PHY_OFDM, 9000, /* 9 Mb */
189 7800, 0x0f, 0x00, 18,
190 4, 3, 1, 5, 5, 5, 5, 0 },
191 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 12 Mb */
192 10100, 0x0a, 0x00, 24,
193 6, 4, 1, 6, 6, 6, 6, 0 },
194 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 18 Mb */
195 14100, 0x0e, 0x00, 36,
196 6, 6, 2, 7, 7, 7, 7, 0 },
197 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 24 Mb */
198 17700, 0x09, 0x00, 48,
199 8, 10, 3, 8, 8, 8, 8, 0 },
200 { TRUE, TRUE, WLAN_PHY_OFDM, 36000, /* 36 Mb */
201 23700, 0x0d, 0x00, 72,
202 8, 14, 3, 9, 9, 9, 9, 0 },
203 { TRUE, TRUE, WLAN_PHY_OFDM, 48000, /* 48 Mb */
204 27400, 0x08, 0x00, 96,
205 8, 20, 3, 10, 10, 10, 10, 0 },
206 { TRUE, TRUE, WLAN_PHY_OFDM, 54000, /* 54 Mb */
207 30900, 0x0c, 0x00, 108,
208 8, 23, 3, 11, 11, 11, 11, 0 },
209 { FALSE, FALSE, WLAN_PHY_HT_20_SS, 6500, /* 6.5 Mb */
210 6400, 0x80, 0x00, 0,
211 4, 2, 3, 12, 28, 12, 28, 3216 },
212 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 13000, /* 13 Mb */
213 12700, 0x81, 0x00, 1,
214 6, 4, 3, 13, 29, 13, 29, 6434 },
215 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 19500, /* 19.5 Mb */
216 18800, 0x82, 0x00, 2,
217 6, 6, 3, 14, 30, 14, 30, 9650 },
218 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 26000, /* 26 Mb */
219 25000, 0x83, 0x00, 3,
220 8, 10, 3, 15, 31, 15, 31, 12868 },
221 { TRUE_20, TRUE_20, WLAN_PHY_HT_20_SS, 39000, /* 39 Mb */
222 36700, 0x84, 0x00, 4,
223 8, 14, 3, 16, 32, 16, 32, 19304 },
224 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 52000, /* 52 Mb */
225 48100, 0x85, 0x00, 5,
226 8, 20, 3, 17, 33, 17, 33, 25740 },
227 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 58500, /* 58.5 Mb */
228 53500, 0x86, 0x00, 6,
229 8, 23, 3, 18, 34, 18, 34, 28956 },
230 { FALSE, TRUE_20, WLAN_PHY_HT_20_SS, 65000, /* 65 Mb */
231 59000, 0x87, 0x00, 7,
232 8, 25, 3, 19, 35, 19, 36, 32180 },
233 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 13000, /* 13 Mb */
234 12700, 0x88, 0x00, 8,
235 4, 2, 3, 20, 37, 20, 37, 6430 },
236 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 26000, /* 26 Mb */
237 24800, 0x89, 0x00, 9,
238 6, 4, 3, 21, 38, 21, 38, 12860 },
239 { FALSE, FALSE, WLAN_PHY_HT_20_DS, 39000, /* 39 Mb */
240 36600, 0x8a, 0x00, 10,
241 6, 6, 3, 22, 39, 22, 39, 19300 },
242 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 52000, /* 52 Mb */
243 48100, 0x8b, 0x00, 11,
244 8, 10, 3, 23, 40, 23, 40, 25736 },
245 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 78000, /* 78 Mb */
246 69500, 0x8c, 0x00, 12,
247 8, 14, 3, 24, 41, 24, 41, 38600 },
248 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 104000, /* 104 Mb */
249 89500, 0x8d, 0x00, 13,
250 8, 20, 3, 25, 42, 25, 42, 51472 },
251 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 117000, /* 117 Mb */
252 98900, 0x8e, 0x00, 14,
253 8, 23, 3, 26, 43, 26, 44, 57890 },
254 { TRUE_20, FALSE, WLAN_PHY_HT_20_DS, 130000, /* 130 Mb */
255 108300, 0x8f, 0x00, 15,
256 8, 25, 3, 27, 44, 27, 45, 64320 },
257 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 13500, /* 13.5 Mb */
258 13200, 0x80, 0x00, 0,
259 8, 2, 3, 12, 28, 28, 28, 6684 },
260 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 27500, /* 27.0 Mb */
261 25900, 0x81, 0x00, 1,
262 8, 4, 3, 13, 29, 29, 29, 13368 },
263 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 40500, /* 40.5 Mb */
264 38600, 0x82, 0x00, 2,
265 8, 6, 3, 14, 30, 30, 30, 20052 },
266 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 54000, /* 54 Mb */
267 49800, 0x83, 0x00, 3,
268 8, 10, 3, 15, 31, 31, 31, 26738 },
269 { TRUE_40, TRUE_40, WLAN_PHY_HT_40_SS, 81500, /* 81 Mb */
270 72200, 0x84, 0x00, 4,
271 8, 14, 3, 16, 32, 32, 32, 40104 },
272 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 108000, /* 108 Mb */
273 92900, 0x85, 0x00, 5,
274 8, 20, 3, 17, 33, 33, 33, 53476 },
275 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 121500, /* 121.5 Mb */
276 102700, 0x86, 0x00, 6,
277 8, 23, 3, 18, 34, 34, 34, 60156 },
278 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS, 135000, /* 135 Mb */
279 112000, 0x87, 0x00, 7,
280 8, 23, 3, 19, 35, 36, 36, 66840 },
281 { FALSE, TRUE_40, WLAN_PHY_HT_40_SS_HGI, 150000, /* 150 Mb */
282 122000, 0x87, 0x00, 7,
283 8, 25, 3, 19, 35, 36, 36, 74200 },
284 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 27000, /* 27 Mb */
285 25800, 0x88, 0x00, 8,
286 8, 2, 3, 20, 37, 37, 37, 13360 },
287 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 54000, /* 54 Mb */
288 49800, 0x89, 0x00, 9,
289 8, 4, 3, 21, 38, 38, 38, 26720 },
290 { FALSE, FALSE, WLAN_PHY_HT_40_DS, 81000, /* 81 Mb */
291 71900, 0x8a, 0x00, 10,
292 8, 6, 3, 22, 39, 39, 39, 40080 },
293 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 108000, /* 108 Mb */
294 92500, 0x8b, 0x00, 11,
295 8, 10, 3, 23, 40, 40, 40, 53440 },
296 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 162000, /* 162 Mb */
297 130300, 0x8c, 0x00, 12,
298 8, 14, 3, 24, 41, 41, 41, 80160 },
299 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 216000, /* 216 Mb */
300 162800, 0x8d, 0x00, 13,
301 8, 20, 3, 25, 42, 42, 42, 106880 },
302 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 243000, /* 243 Mb */
303 178200, 0x8e, 0x00, 14,
304 8, 23, 3, 26, 43, 43, 43, 120240 },
305 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS, 270000, /* 270 Mb */
306 192100, 0x8f, 0x00, 15,
307 8, 23, 3, 27, 44, 45, 45, 133600 },
308 { TRUE_40, FALSE, WLAN_PHY_HT_40_DS_HGI, 300000, /* 300 Mb */
309 207000, 0x8f, 0x00, 15,
310 8, 25, 3, 27, 44, 45, 45, 148400 },
311 },
312 50, /* probe interval */
313 50, /* rssi reduce interval */
314 WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
315};
316
317static struct ath_rate_table ar5416_11a_ratetable = {
318 8,
319 {
320 { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 6 Mb */
321 5400, 0x0b, 0x00, (0x80|12),
322 0, 2, 1, 0, 0 },
323 { TRUE, TRUE, WLAN_PHY_OFDM, 9000, /* 9 Mb */
324 7800, 0x0f, 0x00, 18,
325 0, 3, 1, 1, 0 },
326 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 12 Mb */
327 10000, 0x0a, 0x00, (0x80|24),
328 2, 4, 2, 2, 0 },
329 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 18 Mb */
330 13900, 0x0e, 0x00, 36,
331 2, 6, 2, 3, 0 },
332 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 24 Mb */
333 17300, 0x09, 0x00, (0x80|48),
334 4, 10, 3, 4, 0 },
335 { TRUE, TRUE, WLAN_PHY_OFDM, 36000, /* 36 Mb */
336 23000, 0x0d, 0x00, 72,
337 4, 14, 3, 5, 0 },
338 { TRUE, TRUE, WLAN_PHY_OFDM, 48000, /* 48 Mb */
339 27400, 0x08, 0x00, 96,
340 4, 19, 3, 6, 0 },
341 { TRUE, TRUE, WLAN_PHY_OFDM, 54000, /* 54 Mb */
342 29300, 0x0c, 0x00, 108,
343 4, 23, 3, 7, 0 },
344 },
345 50, /* probe interval */
346 50, /* rssi reduce interval */
347 0, /* Phy rates allowed initially */
348};
349
350static struct ath_rate_table ar5416_11a_ratetable_Half = {
351 8,
352 {
353 { TRUE, TRUE, WLAN_PHY_OFDM, 3000, /* 6 Mb */
354 2700, 0x0b, 0x00, (0x80|6),
355 0, 2, 1, 0, 0},
356 { TRUE, TRUE, WLAN_PHY_OFDM, 4500, /* 9 Mb */
357 3900, 0x0f, 0x00, 9,
358 0, 3, 1, 1, 0 },
359 { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 12 Mb */
360 5000, 0x0a, 0x00, (0x80|12),
361 2, 4, 2, 2, 0 },
362 { TRUE, TRUE, WLAN_PHY_OFDM, 9000, /* 18 Mb */
363 6950, 0x0e, 0x00, 18,
364 2, 6, 2, 3, 0 },
365 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 24 Mb */
366 8650, 0x09, 0x00, (0x80|24),
367 4, 10, 3, 4, 0 },
368 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 36 Mb */
369 11500, 0x0d, 0x00, 36,
370 4, 14, 3, 5, 0 },
371 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 48 Mb */
372 13700, 0x08, 0x00, 48,
373 4, 19, 3, 6, 0 },
374 { TRUE, TRUE, WLAN_PHY_OFDM, 27000, /* 54 Mb */
375 14650, 0x0c, 0x00, 54,
376 4, 23, 3, 7, 0 },
377 },
378 50, /* probe interval */
379 50, /* rssi reduce interval */
380 0, /* Phy rates allowed initially */
381};
382
383static struct ath_rate_table ar5416_11a_ratetable_Quarter = {
384 8,
385 {
386 { TRUE, TRUE, WLAN_PHY_OFDM, 1500, /* 6 Mb */
387 1350, 0x0b, 0x00, (0x80|3),
388 0, 2, 1, 0, 0 },
389 { TRUE, TRUE, WLAN_PHY_OFDM, 2250, /* 9 Mb */
390 1950, 0x0f, 0x00, 4,
391 0, 3, 1, 1, 0 },
392 { TRUE, TRUE, WLAN_PHY_OFDM, 3000, /* 12 Mb */
393 2500, 0x0a, 0x00, (0x80|6),
394 2, 4, 2, 2, 0 },
395 { TRUE, TRUE, WLAN_PHY_OFDM, 4500, /* 18 Mb */
396 3475, 0x0e, 0x00, 9,
397 2, 6, 2, 3, 0 },
398 { TRUE, TRUE, WLAN_PHY_OFDM, 6000, /* 25 Mb */
399 4325, 0x09, 0x00, (0x80|12),
400 4, 10, 3, 4, 0 },
401 { TRUE, TRUE, WLAN_PHY_OFDM, 9000, /* 36 Mb */
402 5750, 0x0d, 0x00, 18,
403 4, 14, 3, 5, 0 },
404 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 48 Mb */
405 6850, 0x08, 0x00, 24,
406 4, 19, 3, 6, 0 },
407 { TRUE, TRUE, WLAN_PHY_OFDM, 13500, /* 54 Mb */
408 7325, 0x0c, 0x00, 27,
409 4, 23, 3, 7, 0 },
410 },
411 50, /* probe interval */
412 50, /* rssi reduce interval */
413 0, /* Phy rates allowed initially */
414};
415
416static struct ath_rate_table ar5416_11g_ratetable = {
417 12,
418 {
419 { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */
420 900, 0x1b, 0x00, 2,
421 0, 0, 1, 0, 0 },
422 { TRUE, TRUE, WLAN_PHY_CCK, 2000, /* 2 Mb */
423 1900, 0x1a, 0x04, 4,
424 1, 1, 1, 1, 0 },
425 { TRUE, TRUE, WLAN_PHY_CCK, 5500, /* 5.5 Mb */
426 4900, 0x19, 0x04, 11,
427 2, 2, 2, 2, 0 },
428 { TRUE, TRUE, WLAN_PHY_CCK, 11000, /* 11 Mb */
429 8100, 0x18, 0x04, 22,
430 3, 3, 2, 3, 0 },
431 { FALSE, FALSE, WLAN_PHY_OFDM, 6000, /* 6 Mb */
432 5400, 0x0b, 0x00, 12,
433 4, 2, 1, 4, 0 },
434 { FALSE, FALSE, WLAN_PHY_OFDM, 9000, /* 9 Mb */
435 7800, 0x0f, 0x00, 18,
436 4, 3, 1, 5, 0 },
437 { TRUE, TRUE, WLAN_PHY_OFDM, 12000, /* 12 Mb */
438 10000, 0x0a, 0x00, 24,
439 6, 4, 1, 6, 0 },
440 { TRUE, TRUE, WLAN_PHY_OFDM, 18000, /* 18 Mb */
441 13900, 0x0e, 0x00, 36,
442 6, 6, 2, 7, 0 },
443 { TRUE, TRUE, WLAN_PHY_OFDM, 24000, /* 24 Mb */
444 17300, 0x09, 0x00, 48,
445 8, 10, 3, 8, 0 },
446 { TRUE, TRUE, WLAN_PHY_OFDM, 36000, /* 36 Mb */
447 23000, 0x0d, 0x00, 72,
448 8, 14, 3, 9, 0 },
449 { TRUE, TRUE, WLAN_PHY_OFDM, 48000, /* 48 Mb */
450 27400, 0x08, 0x00, 96,
451 8, 19, 3, 10, 0 },
452 { TRUE, TRUE, WLAN_PHY_OFDM, 54000, /* 54 Mb */
453 29300, 0x0c, 0x00, 108,
454 8, 23, 3, 11, 0 },
455 },
456 50, /* probe interval */
457 50, /* rssi reduce interval */
458 0, /* Phy rates allowed initially */
459};
460
461static struct ath_rate_table ar5416_11b_ratetable = {
462 4,
463 {
464 { TRUE, TRUE, WLAN_PHY_CCK, 1000, /* 1 Mb */
465 900, 0x1b, 0x00, (0x80|2),
466 0, 0, 1, 0, 0 },
467 { TRUE, TRUE, WLAN_PHY_CCK, 2000, /* 2 Mb */
468 1800, 0x1a, 0x04, (0x80|4),
469 1, 1, 1, 1, 0 },
470 { TRUE, TRUE, WLAN_PHY_CCK, 5500, /* 5.5 Mb */
471 4300, 0x19, 0x04, (0x80|11),
472 1, 2, 2, 2, 0 },
473 { TRUE, TRUE, WLAN_PHY_CCK, 11000, /* 11 Mb */
474 7100, 0x18, 0x04, (0x80|22),
475 1, 4, 100, 3, 0 },
476 },
477 100, /* probe interval */
478 100, /* rssi reduce interval */
479 0, /* Phy rates allowed initially */
480};
481
482static void ar5416_attach_ratetables(struct ath_rate_softc *sc)
483{
484 /*
485 * Attach rate tables.
486 */
487 sc->hw_rate_table[WIRELESS_MODE_11b] = &ar5416_11b_ratetable;
488 sc->hw_rate_table[WIRELESS_MODE_11a] = &ar5416_11a_ratetable;
489 sc->hw_rate_table[WIRELESS_MODE_11g] = &ar5416_11g_ratetable;
490
491 sc->hw_rate_table[WIRELESS_MODE_11NA_HT20] = &ar5416_11na_ratetable;
492 sc->hw_rate_table[WIRELESS_MODE_11NG_HT20] = &ar5416_11ng_ratetable;
493 sc->hw_rate_table[WIRELESS_MODE_11NA_HT40PLUS] =
494 &ar5416_11na_ratetable;
495 sc->hw_rate_table[WIRELESS_MODE_11NA_HT40MINUS] =
496 &ar5416_11na_ratetable;
497 sc->hw_rate_table[WIRELESS_MODE_11NG_HT40PLUS] =
498 &ar5416_11ng_ratetable;
499 sc->hw_rate_table[WIRELESS_MODE_11NG_HT40MINUS] =
500 &ar5416_11ng_ratetable;
501}
502
503static void ar5416_setquarter_ratetable(struct ath_rate_softc *sc)
504{
505 sc->hw_rate_table[WIRELESS_MODE_11a] = &ar5416_11a_ratetable_Quarter;
506 return;
507}
508
509static void ar5416_sethalf_ratetable(struct ath_rate_softc *sc)
510{
511 sc->hw_rate_table[WIRELESS_MODE_11a] = &ar5416_11a_ratetable_Half;
512 return;
513}
514
515static void ar5416_setfull_ratetable(struct ath_rate_softc *sc)
516{
517 sc->hw_rate_table[WIRELESS_MODE_11a] = &ar5416_11a_ratetable;
518 return;
519}
520
521/*
522 * Return the median of three numbers
523 */
524static inline int8_t median(int8_t a, int8_t b, int8_t c)
525{
526 if (a >= b) {
527 if (b >= c)
528 return b;
529 else if (a > c)
530 return c;
531 else
532 return a;
533 } else {
534 if (a >= c)
535 return a;
536 else if (b >= c)
537 return c;
538 else
539 return b;
540 }
541}
542
543static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
544 struct ath_tx_ratectrl *rate_ctrl)
545{
546 u8 i, j, idx, idx_next;
547
548 for (i = rate_ctrl->max_valid_rate - 1; i > 0; i--) {
549 for (j = 0; j <= i-1; j++) {
550 idx = rate_ctrl->valid_rate_index[j];
551 idx_next = rate_ctrl->valid_rate_index[j+1];
552
553 if (rate_table->info[idx].ratekbps >
554 rate_table->info[idx_next].ratekbps) {
555 rate_ctrl->valid_rate_index[j] = idx_next;
556 rate_ctrl->valid_rate_index[j+1] = idx;
557 }
558 }
559 }
560}
561
562/* Access functions for valid_txrate_mask */
563
564static void ath_rc_init_valid_txmask(struct ath_tx_ratectrl *rate_ctrl)
565{
566 u8 i;
567
568 for (i = 0; i < rate_ctrl->rate_table_size; i++)
569 rate_ctrl->valid_rate_index[i] = FALSE;
570}
571
572static inline void ath_rc_set_valid_txmask(struct ath_tx_ratectrl *rate_ctrl,
573 u8 index, int valid_tx_rate)
574{
575 ASSERT(index <= rate_ctrl->rate_table_size);
576 rate_ctrl->valid_rate_index[index] = valid_tx_rate ? TRUE : FALSE;
577}
578
579static inline int ath_rc_isvalid_txmask(struct ath_tx_ratectrl *rate_ctrl,
580 u8 index)
581{
582 ASSERT(index <= rate_ctrl->rate_table_size);
583 return rate_ctrl->valid_rate_index[index];
584}
585
586/* Iterators for valid_txrate_mask */
587static inline int
588ath_rc_get_nextvalid_txrate(const struct ath_rate_table *rate_table,
589 struct ath_tx_ratectrl *rate_ctrl,
590 u8 cur_valid_txrate,
591 u8 *next_idx)
592{
593 u8 i;
594
595 for (i = 0; i < rate_ctrl->max_valid_rate - 1; i++) {
596 if (rate_ctrl->valid_rate_index[i] == cur_valid_txrate) {
597 *next_idx = rate_ctrl->valid_rate_index[i+1];
598 return TRUE;
599 }
600 }
601
602 /* No more valid rates */
603 *next_idx = 0;
604 return FALSE;
605}
606
607/* Return true only for single stream */
608
609static int ath_rc_valid_phyrate(u32 phy, u32 capflag, int ignore_cw)
610{
611 if (WLAN_RC_PHY_HT(phy) & !(capflag & WLAN_RC_HT_FLAG))
612 return FALSE;
613 if (WLAN_RC_PHY_DS(phy) && !(capflag & WLAN_RC_DS_FLAG))
614 return FALSE;
615 if (WLAN_RC_PHY_SGI(phy) && !(capflag & WLAN_RC_SGI_FLAG))
616 return FALSE;
617 if (!ignore_cw && WLAN_RC_PHY_HT(phy))
618 if (WLAN_RC_PHY_40(phy) && !(capflag & WLAN_RC_40_FLAG))
619 return FALSE;
620 if (!WLAN_RC_PHY_40(phy) && (capflag & WLAN_RC_40_FLAG))
621 return FALSE;
622 return TRUE;
623}
624
625static inline int
626ath_rc_get_nextlowervalid_txrate(const struct ath_rate_table *rate_table,
627 struct ath_tx_ratectrl *rate_ctrl,
628 u8 cur_valid_txrate, u8 *next_idx)
629{
630 int8_t i;
631
632 for (i = 1; i < rate_ctrl->max_valid_rate ; i++) {
633 if (rate_ctrl->valid_rate_index[i] == cur_valid_txrate) {
634 *next_idx = rate_ctrl->valid_rate_index[i-1];
635 return TRUE;
636 }
637 }
638 return FALSE;
639}
640
641/*
642 * Initialize the Valid Rate Index from valid entries in Rate Table
643 */
644static u8
645ath_rc_sib_init_validrates(struct ath_rate_node *ath_rc_priv,
646 const struct ath_rate_table *rate_table,
647 u32 capflag)
648{
649 struct ath_tx_ratectrl *rate_ctrl;
650 u8 i, hi = 0;
651 u32 valid;
652
653 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
654 for (i = 0; i < rate_table->rate_cnt; i++) {
655 valid = (ath_rc_priv->single_stream ?
656 rate_table->info[i].valid_single_stream :
657 rate_table->info[i].valid);
658 if (valid == TRUE) {
659 u32 phy = rate_table->info[i].phy;
660 u8 valid_rate_count = 0;
661
662 if (!ath_rc_valid_phyrate(phy, capflag, FALSE))
663 continue;
664
665 valid_rate_count = rate_ctrl->valid_phy_ratecnt[phy];
666
667 rate_ctrl->valid_phy_rateidx[phy][valid_rate_count] = i;
668 rate_ctrl->valid_phy_ratecnt[phy] += 1;
669 ath_rc_set_valid_txmask(rate_ctrl, i, TRUE);
670 hi = A_MAX(hi, i);
671 }
672 }
673 return hi;
674}
675
676/*
677 * Initialize the Valid Rate Index from Rate Set
678 */
679static u8
680ath_rc_sib_setvalid_rates(struct ath_rate_node *ath_rc_priv,
681 const struct ath_rate_table *rate_table,
682 struct ath_rateset *rateset,
683 u32 capflag)
684{
685 /* XXX: Clean me up and make identation friendly */
686 u8 i, j, hi = 0;
687 struct ath_tx_ratectrl *rate_ctrl =
688 (struct ath_tx_ratectrl *)(ath_rc_priv);
689
690 /* Use intersection of working rates and valid rates */
691 for (i = 0; i < rateset->rs_nrates; i++) {
692 for (j = 0; j < rate_table->rate_cnt; j++) {
693 u32 phy = rate_table->info[j].phy;
694 u32 valid = (ath_rc_priv->single_stream ?
695 rate_table->info[j].valid_single_stream :
696 rate_table->info[j].valid);
697
698 /* We allow a rate only if its valid and the
699 * capflag matches one of the validity
700 * (TRUE/TRUE_20/TRUE_40) flags */
701
702 /* XXX: catch the negative of this branch
703 * first and then continue */
704 if (((rateset->rs_rates[i] & 0x7F) ==
705 (rate_table->info[j].dot11rate & 0x7F)) &&
706 ((valid & WLAN_RC_CAP_MODE(capflag)) ==
707 WLAN_RC_CAP_MODE(capflag)) &&
708 !WLAN_RC_PHY_HT(phy)) {
709
710 u8 valid_rate_count = 0;
711
712 if (!ath_rc_valid_phyrate(phy, capflag, FALSE))
713 continue;
714
715 valid_rate_count =
716 rate_ctrl->valid_phy_ratecnt[phy];
717
718 rate_ctrl->valid_phy_rateidx[phy]
719 [valid_rate_count] = j;
720 rate_ctrl->valid_phy_ratecnt[phy] += 1;
721 ath_rc_set_valid_txmask(rate_ctrl, j, TRUE);
722 hi = A_MAX(hi, j);
723 }
724 }
725 }
726 return hi;
727}
728
729static u8
730ath_rc_sib_setvalid_htrates(struct ath_rate_node *ath_rc_priv,
731 const struct ath_rate_table *rate_table,
732 u8 *mcs_set, u32 capflag)
733{
734 u8 i, j, hi = 0;
735 struct ath_tx_ratectrl *rate_ctrl =
736 (struct ath_tx_ratectrl *)(ath_rc_priv);
737
738 /* Use intersection of working rates and valid rates */
739 for (i = 0; i < ((struct ath_rateset *)mcs_set)->rs_nrates; i++) {
740 for (j = 0; j < rate_table->rate_cnt; j++) {
741 u32 phy = rate_table->info[j].phy;
742 u32 valid = (ath_rc_priv->single_stream ?
743 rate_table->info[j].valid_single_stream :
744 rate_table->info[j].valid);
745
746 if (((((struct ath_rateset *)
747 mcs_set)->rs_rates[i] & 0x7F) !=
748 (rate_table->info[j].dot11rate & 0x7F)) ||
749 !WLAN_RC_PHY_HT(phy) ||
750 !WLAN_RC_PHY_HT_VALID(valid, capflag))
751 continue;
752
753 if (!ath_rc_valid_phyrate(phy, capflag, FALSE))
754 continue;
755
756 rate_ctrl->valid_phy_rateidx[phy]
757 [rate_ctrl->valid_phy_ratecnt[phy]] = j;
758 rate_ctrl->valid_phy_ratecnt[phy] += 1;
759 ath_rc_set_valid_txmask(rate_ctrl, j, TRUE);
760 hi = A_MAX(hi, j);
761 }
762 }
763 return hi;
764}
765
766/*
767 * Attach to a device instance. Setup the public definition
768 * of how much per-node space we need and setup the private
769 * phy tables that have rate control parameters.
770 */
771struct ath_rate_softc *ath_rate_attach(struct ath_hal *ah)
772{
773 struct ath_rate_softc *asc;
774
775 /* we are only in user context so we can sleep for memory */
776 asc = kzalloc(sizeof(struct ath_rate_softc), GFP_KERNEL);
777 if (asc == NULL)
778 return NULL;
779
780 ar5416_attach_ratetables(asc);
781
782 /* Save Maximum TX Trigger Level (used for 11n) */
783 tx_triglevel_max = ah->ah_caps.halTxTrigLevelMax;
784 /* return alias for ath_rate_softc * */
785 return asc;
786}
787
788static struct ath_rate_node *ath_rate_node_alloc(struct ath_vap *avp,
789 struct ath_rate_softc *rsc,
790 gfp_t gfp)
791{
792 struct ath_rate_node *anode;
793
794 anode = kzalloc(sizeof(struct ath_rate_node), gfp);
795 if (anode == NULL)
796 return NULL;
797
798 anode->avp = avp;
799 anode->asc = rsc;
800 avp->rc_node = anode;
801
802 return anode;
803}
804
805static void ath_rate_node_free(struct ath_rate_node *anode)
806{
807 if (anode != NULL)
808 kfree(anode);
809}
810
811void ath_rate_detach(struct ath_rate_softc *asc)
812{
813 if (asc != NULL)
814 kfree(asc);
815}
816
817u8 ath_rate_findrateix(struct ath_softc *sc,
818 u8 dot11rate)
819{
820 const struct ath_rate_table *ratetable;
821 struct ath_rate_softc *rsc = sc->sc_rc;
822 int i;
823
824 ratetable = rsc->hw_rate_table[sc->sc_curmode];
825
826 if (WARN_ON(!ratetable))
827 return 0;
828
829 for (i = 0; i < ratetable->rate_cnt; i++) {
830 if ((ratetable->info[i].dot11rate & 0x7f) == (dot11rate & 0x7f))
831 return i;
832 }
833
834 return 0;
835}
836
837/*
838 * Update rate-control state on a device state change. When
839 * operating as a station this includes associate/reassociate
840 * with an AP. Otherwise this gets called, for example, when
841 * the we transition to run state when operating as an AP.
842 */
843void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp)
844{
845 struct ath_rate_softc *asc = sc->sc_rc;
846
847 /* For half and quarter rate channles use different
848 * rate tables
849 */
850 if (sc->sc_curchan.channelFlags & CHANNEL_HALF)
851 ar5416_sethalf_ratetable(asc);
852 else if (sc->sc_curchan.channelFlags & CHANNEL_QUARTER)
853 ar5416_setquarter_ratetable(asc);
854 else /* full rate */
855 ar5416_setfull_ratetable(asc);
856
857 if (avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE) {
858 asc->fixedrix =
859 sc->sc_rixmap[avp->av_config.av_fixed_rateset & 0xff];
860 /* NB: check the fixed rate exists */
861 if (asc->fixedrix == 0xff)
862 asc->fixedrix = IEEE80211_FIXED_RATE_NONE;
863 } else {
864 asc->fixedrix = IEEE80211_FIXED_RATE_NONE;
865 }
866}
867
868static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
869 struct ath_rate_node *ath_rc_priv,
870 const struct ath_rate_table *rate_table,
871 int probe_allowed, int *is_probing,
872 int is_retry)
873{
874 u32 dt, best_thruput, this_thruput, now_msec;
875 u8 rate, next_rate, best_rate, maxindex, minindex;
876 int8_t rssi_last, rssi_reduce = 0, index = 0;
877 struct ath_tx_ratectrl *rate_ctrl = NULL;
878
879 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv ?
880 (ath_rc_priv) : NULL);
881
882 *is_probing = FALSE;
883
884 rssi_last = median(rate_ctrl->rssi_last,
885 rate_ctrl->rssi_last_prev,
886 rate_ctrl->rssi_last_prev2);
887
888 /*
889 * Age (reduce) last ack rssi based on how old it is.
890 * The bizarre numbers are so the delta is 160msec,
891 * meaning we divide by 16.
892 * 0msec <= dt <= 25msec: don't derate
893 * 25msec <= dt <= 185msec: derate linearly from 0 to 10dB
894 * 185msec <= dt: derate by 10dB
895 */
896
897 now_msec = jiffies_to_msecs(jiffies);
898 dt = now_msec - rate_ctrl->rssi_time;
899
900 if (dt >= 185)
901 rssi_reduce = 10;
902 else if (dt >= 25)
903 rssi_reduce = (u8)((dt - 25) >> 4);
904
905 /* Now reduce rssi_last by rssi_reduce */
906 if (rssi_last < rssi_reduce)
907 rssi_last = 0;
908 else
909 rssi_last -= rssi_reduce;
910
911 /*
912 * Now look up the rate in the rssi table and return it.
913 * If no rates match then we return 0 (lowest rate)
914 */
915
916 best_thruput = 0;
917 maxindex = rate_ctrl->max_valid_rate-1;
918
919 minindex = 0;
920 best_rate = minindex;
921
922 /*
923 * Try the higher rate first. It will reduce memory moving time
924 * if we have very good channel characteristics.
925 */
926 for (index = maxindex; index >= minindex ; index--) {
927 u8 per_thres;
928
929 rate = rate_ctrl->valid_rate_index[index];
930 if (rate > rate_ctrl->rate_max_phy)
931 continue;
932
933 /*
934 * For TCP the average collision rate is around 11%,
935 * so we ignore PERs less than this. This is to
936 * prevent the rate we are currently using (whose
937 * PER might be in the 10-15 range because of TCP
938 * collisions) looking worse than the next lower
939 * rate whose PER has decayed close to 0. If we
940 * used to next lower rate, its PER would grow to
941 * 10-15 and we would be worse off then staying
942 * at the current rate.
943 */
944 per_thres = rate_ctrl->state[rate].per;
945 if (per_thres < 12)
946 per_thres = 12;
947
948 this_thruput = rate_table->info[rate].user_ratekbps *
949 (100 - per_thres);
950
951 if (best_thruput <= this_thruput) {
952 best_thruput = this_thruput;
953 best_rate = rate;
954 }
955 }
956
957 rate = best_rate;
958
959 /* if we are retrying for more than half the number
960 * of max retries, use the min rate for the next retry
961 */
962 if (is_retry)
963 rate = rate_ctrl->valid_rate_index[minindex];
964
965 rate_ctrl->rssi_last_lookup = rssi_last;
966
967 /*
968 * Must check the actual rate (ratekbps) to account for
969 * non-monoticity of 11g's rate table
970 */
971
972 if (rate >= rate_ctrl->rate_max_phy && probe_allowed) {
973 rate = rate_ctrl->rate_max_phy;
974
975 /* Probe the next allowed phy state */
976 /* FIXME:XXXX Check to make sure ratMax is checked properly */
977 if (ath_rc_get_nextvalid_txrate(rate_table,
978 rate_ctrl, rate, &next_rate) &&
979 (now_msec - rate_ctrl->probe_time >
980 rate_table->probe_interval) &&
981 (rate_ctrl->hw_maxretry_pktcnt >= 1)) {
982 rate = next_rate;
983 rate_ctrl->probe_rate = rate;
984 rate_ctrl->probe_time = now_msec;
985 rate_ctrl->hw_maxretry_pktcnt = 0;
986 *is_probing = TRUE;
987 }
988 }
989
990 /*
991 * Make sure rate is not higher than the allowed maximum.
992 * We should also enforce the min, but I suspect the min is
993 * normally 1 rather than 0 because of the rate 9 vs 6 issue
994 * in the old code.
995 */
996 if (rate > (rate_ctrl->rate_table_size - 1))
997 rate = rate_ctrl->rate_table_size - 1;
998
999 ASSERT((rate_table->info[rate].valid && !ath_rc_priv->single_stream) ||
1000 (rate_table->info[rate].valid_single_stream &&
1001 ath_rc_priv->single_stream));
1002
1003 return rate;
1004}
1005
1006static void ath_rc_rate_set_series(const struct ath_rate_table *rate_table ,
1007 struct ath_rc_series *series,
1008 u8 tries,
1009 u8 rix,
1010 int rtsctsenable)
1011{
1012 series->tries = tries;
1013 series->flags = (rtsctsenable ? ATH_RC_RTSCTS_FLAG : 0) |
1014 (WLAN_RC_PHY_DS(rate_table->info[rix].phy) ?
1015 ATH_RC_DS_FLAG : 0) |
1016 (WLAN_RC_PHY_40(rate_table->info[rix].phy) ?
1017 ATH_RC_CW40_FLAG : 0) |
1018 (WLAN_RC_PHY_SGI(rate_table->info[rix].phy) ?
1019 ATH_RC_SGI_FLAG : 0);
1020
1021 series->rix = rate_table->info[rix].base_index;
1022 series->max_4ms_framelen = rate_table->info[rix].max_4ms_framelen;
1023}
1024
1025static u8 ath_rc_rate_getidx(struct ath_softc *sc,
1026 struct ath_rate_node *ath_rc_priv,
1027 const struct ath_rate_table *rate_table,
1028 u8 rix, u16 stepdown,
1029 u16 min_rate)
1030{
1031 u32 j;
1032 u8 nextindex;
1033 struct ath_tx_ratectrl *rate_ctrl =
1034 (struct ath_tx_ratectrl *)(ath_rc_priv);
1035
1036 if (min_rate) {
1037 for (j = RATE_TABLE_SIZE; j > 0; j--) {
1038 if (ath_rc_get_nextlowervalid_txrate(rate_table,
1039 rate_ctrl, rix, &nextindex))
1040 rix = nextindex;
1041 else
1042 break;
1043 }
1044 } else {
1045 for (j = stepdown; j > 0; j--) {
1046 if (ath_rc_get_nextlowervalid_txrate(rate_table,
1047 rate_ctrl, rix, &nextindex))
1048 rix = nextindex;
1049 else
1050 break;
1051 }
1052 }
1053 return rix;
1054}
1055
1056static void ath_rc_ratefind(struct ath_softc *sc,
1057 struct ath_rate_node *ath_rc_priv,
1058 int num_tries, int num_rates, unsigned int rcflag,
1059 struct ath_rc_series series[], int *is_probe,
1060 int is_retry)
1061{
1062 u8 try_per_rate = 0, i = 0, rix, nrix;
1063 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1064 struct ath_rate_table *rate_table;
1065
1066 rate_table =
1067 (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode];
1068 rix = ath_rc_ratefind_ht(sc, ath_rc_priv, rate_table,
1069 (rcflag & ATH_RC_PROBE_ALLOWED) ? 1 : 0,
1070 is_probe, is_retry);
1071 nrix = rix;
1072
1073 if ((rcflag & ATH_RC_PROBE_ALLOWED) && (*is_probe)) {
1074 /* set one try for probe rates. For the
1075 * probes don't enable rts */
1076 ath_rc_rate_set_series(rate_table,
1077 &series[i++], 1, nrix, FALSE);
1078
1079 try_per_rate = (num_tries/num_rates);
1080 /* Get the next tried/allowed rate. No RTS for the next series
1081 * after the probe rate
1082 */
1083 nrix = ath_rc_rate_getidx(sc,
1084 ath_rc_priv, rate_table, nrix, 1, FALSE);
1085 ath_rc_rate_set_series(rate_table,
1086 &series[i++], try_per_rate, nrix, 0);
1087 } else {
1088 try_per_rate = (num_tries/num_rates);
1089 /* Set the choosen rate. No RTS for first series entry. */
1090 ath_rc_rate_set_series(rate_table,
1091 &series[i++], try_per_rate, nrix, FALSE);
1092 }
1093
1094 /* Fill in the other rates for multirate retry */
1095 for ( ; i < num_rates; i++) {
1096 u8 try_num;
1097 u8 min_rate;
1098
1099 try_num = ((i + 1) == num_rates) ?
1100 num_tries - (try_per_rate * i) : try_per_rate ;
1101 min_rate = (((i + 1) == num_rates) &&
1102 (rcflag & ATH_RC_MINRATE_LASTRATE)) ? 1 : 0;
1103
1104 nrix = ath_rc_rate_getidx(sc, ath_rc_priv,
1105 rate_table, nrix, 1, min_rate);
1106 /* All other rates in the series have RTS enabled */
1107 ath_rc_rate_set_series(rate_table,
1108 &series[i], try_num, nrix, TRUE);
1109 }
1110
1111 /*
1112 * NB:Change rate series to enable aggregation when operating
1113 * at lower MCS rates. When first rate in series is MCS2
1114 * in HT40 @ 2.4GHz, series should look like:
1115 *
1116 * {MCS2, MCS1, MCS0, MCS0}.
1117 *
1118 * When first rate in series is MCS3 in HT20 @ 2.4GHz, series should
1119 * look like:
1120 *
1121 * {MCS3, MCS2, MCS1, MCS1}
1122 *
1123 * So, set fourth rate in series to be same as third one for
1124 * above conditions.
1125 */
1126 if ((sc->sc_curmode == WIRELESS_MODE_11NG_HT20) ||
1127 (sc->sc_curmode == WIRELESS_MODE_11NG_HT40PLUS) ||
1128 (sc->sc_curmode == WIRELESS_MODE_11NG_HT40MINUS)) {
1129 u8 dot11rate = rate_table->info[rix].dot11rate;
1130 u8 phy = rate_table->info[rix].phy;
1131 if (i == 4 &&
1132 ((dot11rate == 2 && phy == WLAN_RC_PHY_HT_40_SS) ||
1133 (dot11rate == 3 && phy == WLAN_RC_PHY_HT_20_SS))) {
1134 series[3].rix = series[2].rix;
1135 series[3].flags = series[2].flags;
1136 series[3].max_4ms_framelen = series[2].max_4ms_framelen;
1137 }
1138 }
1139}
1140
1141/*
1142 * Return the Tx rate series.
1143 */
1144void ath_rate_findrate(struct ath_softc *sc,
1145 struct ath_rate_node *ath_rc_priv,
1146 int num_tries,
1147 int num_rates,
1148 unsigned int rcflag,
1149 struct ath_rc_series series[],
1150 int *is_probe,
1151 int is_retry)
1152{
1153 struct ath_vap *avp = ath_rc_priv->avp;
1154
1155 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
1156 if (!num_rates || !num_tries)
1157 return;
1158
1159 if (avp->av_config.av_fixed_rateset == IEEE80211_FIXED_RATE_NONE) {
1160 ath_rc_ratefind(sc, ath_rc_priv, num_tries, num_rates,
1161 rcflag, series, is_probe, is_retry);
1162 } else {
1163 /* Fixed rate */
1164 int idx;
1165 u8 flags;
1166 u32 rix;
1167 struct ath_rate_softc *asc = ath_rc_priv->asc;
1168 struct ath_rate_table *rate_table;
1169
1170 rate_table = (struct ath_rate_table *)
1171 asc->hw_rate_table[sc->sc_curmode];
1172
1173 for (idx = 0; idx < 4; idx++) {
1174 unsigned int mcs;
1175 u8 series_rix = 0;
1176
1177 series[idx].tries =
1178 IEEE80211_RATE_IDX_ENTRY(
1179 avp->av_config.av_fixed_retryset, idx);
1180
1181 mcs = IEEE80211_RATE_IDX_ENTRY(
1182 avp->av_config.av_fixed_rateset, idx);
1183
1184 if (idx == 3 && (mcs & 0xf0) == 0x70)
1185 mcs = (mcs & ~0xf0)|0x80;
1186
1187 if (!(mcs & 0x80))
1188 flags = 0;
1189 else
1190 flags = ((ath_rc_priv->ht_cap &
1191 WLAN_RC_DS_FLAG) ?
1192 ATH_RC_DS_FLAG : 0) |
1193 ((ath_rc_priv->ht_cap &
1194 WLAN_RC_40_FLAG) ?
1195 ATH_RC_CW40_FLAG : 0) |
1196 ((ath_rc_priv->ht_cap &
1197 WLAN_RC_SGI_FLAG) ?
1198 ((ath_rc_priv->ht_cap &
1199 WLAN_RC_40_FLAG) ?
1200 ATH_RC_SGI_FLAG : 0) : 0);
1201
1202 series[idx].rix = sc->sc_rixmap[mcs];
1203 series_rix = series[idx].rix;
1204
1205 /* XXX: Give me some cleanup love */
1206 if ((flags & ATH_RC_CW40_FLAG) &&
1207 (flags & ATH_RC_SGI_FLAG))
1208 rix = rate_table->info[series_rix].ht_index;
1209 else if (flags & ATH_RC_SGI_FLAG)
1210 rix = rate_table->info[series_rix].sgi_index;
1211 else if (flags & ATH_RC_CW40_FLAG)
1212 rix = rate_table->info[series_rix].cw40index;
1213 else
1214 rix = rate_table->info[series_rix].base_index;
1215 series[idx].max_4ms_framelen =
1216 rate_table->info[rix].max_4ms_framelen;
1217 series[idx].flags = flags;
1218 }
1219 }
1220}
1221
1222static void ath_rc_update_ht(struct ath_softc *sc,
1223 struct ath_rate_node *ath_rc_priv,
1224 struct ath_tx_info_priv *info_priv,
1225 int tx_rate, int xretries, int retries)
1226{
1227 struct ath_tx_ratectrl *rate_ctrl;
1228 u32 now_msec = jiffies_to_msecs(jiffies);
1229 int state_change = FALSE, rate, count;
1230 u8 last_per;
1231 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1232 struct ath_rate_table *rate_table =
1233 (struct ath_rate_table *)asc->hw_rate_table[sc->sc_curmode];
1234
1235 static u32 nretry_to_per_lookup[10] = {
1236 100 * 0 / 1,
1237 100 * 1 / 4,
1238 100 * 1 / 2,
1239 100 * 3 / 4,
1240 100 * 4 / 5,
1241 100 * 5 / 6,
1242 100 * 6 / 7,
1243 100 * 7 / 8,
1244 100 * 8 / 9,
1245 100 * 9 / 10
1246 };
1247
1248 if (!ath_rc_priv)
1249 return;
1250
1251 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
1252
1253 ASSERT(tx_rate >= 0);
1254 if (tx_rate < 0)
1255 return;
1256
1257 /* To compensate for some imbalance between ctrl and ext. channel */
1258
1259 if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
1260 info_priv->tx.ts_rssi =
1261 info_priv->tx.ts_rssi < 3 ? 0 :
1262 info_priv->tx.ts_rssi - 3;
1263
1264 last_per = rate_ctrl->state[tx_rate].per;
1265
1266 if (xretries) {
1267 /* Update the PER. */
1268 if (xretries == 1) {
1269 rate_ctrl->state[tx_rate].per += 30;
1270 if (rate_ctrl->state[tx_rate].per > 100)
1271 rate_ctrl->state[tx_rate].per = 100;
1272 } else {
1273 /* xretries == 2 */
1274 count = sizeof(nretry_to_per_lookup) /
1275 sizeof(nretry_to_per_lookup[0]);
1276 if (retries >= count)
1277 retries = count - 1;
1278 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
1279 rate_ctrl->state[tx_rate].per =
1280 (u8)(rate_ctrl->state[tx_rate].per -
1281 (rate_ctrl->state[tx_rate].per >> 3) +
1282 ((100) >> 3));
1283 }
1284
1285 /* xretries == 1 or 2 */
1286
1287 if (rate_ctrl->probe_rate == tx_rate)
1288 rate_ctrl->probe_rate = 0;
1289
1290 } else { /* xretries == 0 */
1291 /* Update the PER. */
1292 /* Make sure it doesn't index out of array's bounds. */
1293 count = sizeof(nretry_to_per_lookup) /
1294 sizeof(nretry_to_per_lookup[0]);
1295 if (retries >= count)
1296 retries = count - 1;
1297 if (info_priv->n_bad_frames) {
1298 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
1299 /*
1300 * Assuming that n_frames is not 0. The current PER
1301 * from the retries is 100 * retries / (retries+1),
1302 * since the first retries attempts failed, and the
1303 * next one worked. For the one that worked,
1304 * n_bad_frames subframes out of n_frames wored,
1305 * so the PER for that part is
1306 * 100 * n_bad_frames / n_frames, and it contributes
1307 * 100 * n_bad_frames / (n_frames * (retries+1)) to
1308 * the above PER. The expression below is a
1309 * simplified version of the sum of these two terms.
1310 */
1311 if (info_priv->n_frames > 0)
1312 rate_ctrl->state[tx_rate].per
1313 = (u8)
1314 (rate_ctrl->state[tx_rate].per -
1315 (rate_ctrl->state[tx_rate].per >> 3) +
1316 ((100*(retries*info_priv->n_frames +
1317 info_priv->n_bad_frames) /
1318 (info_priv->n_frames *
1319 (retries+1))) >> 3));
1320 } else {
1321 /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
1322
1323 rate_ctrl->state[tx_rate].per = (u8)
1324 (rate_ctrl->state[tx_rate].per -
1325 (rate_ctrl->state[tx_rate].per >> 3) +
1326 (nretry_to_per_lookup[retries] >> 3));
1327 }
1328
1329 rate_ctrl->rssi_last_prev2 = rate_ctrl->rssi_last_prev;
1330 rate_ctrl->rssi_last_prev = rate_ctrl->rssi_last;
1331 rate_ctrl->rssi_last = info_priv->tx.ts_rssi;
1332 rate_ctrl->rssi_time = now_msec;
1333
1334 /*
1335 * If we got at most one retry then increase the max rate if
1336 * this was a probe. Otherwise, ignore the probe.
1337 */
1338
1339 if (rate_ctrl->probe_rate && rate_ctrl->probe_rate == tx_rate) {
1340 if (retries > 0 || 2 * info_priv->n_bad_frames >
1341 info_priv->n_frames) {
1342 /*
1343 * Since we probed with just a single attempt,
1344 * any retries means the probe failed. Also,
1345 * if the attempt worked, but more than half
1346 * the subframes were bad then also consider
1347 * the probe a failure.
1348 */
1349 rate_ctrl->probe_rate = 0;
1350 } else {
1351 u8 probe_rate = 0;
1352
1353 rate_ctrl->rate_max_phy = rate_ctrl->probe_rate;
1354 probe_rate = rate_ctrl->probe_rate;
1355
1356 if (rate_ctrl->state[probe_rate].per > 30)
1357 rate_ctrl->state[probe_rate].per = 20;
1358
1359 rate_ctrl->probe_rate = 0;
1360
1361 /*
1362 * Since this probe succeeded, we allow the next
1363 * probe twice as soon. This allows the maxRate
1364 * to move up faster if the probes are
1365 * succesful.
1366 */
1367 rate_ctrl->probe_time = now_msec -
1368 rate_table->probe_interval / 2;
1369 }
1370 }
1371
1372 if (retries > 0) {
1373 /*
1374 * Don't update anything. We don't know if
1375 * this was because of collisions or poor signal.
1376 *
1377 * Later: if rssi_ack is close to
1378 * rate_ctrl->state[txRate].rssi_thres and we see lots
1379 * of retries, then we could increase
1380 * rate_ctrl->state[txRate].rssi_thres.
1381 */
1382 rate_ctrl->hw_maxretry_pktcnt = 0;
1383 } else {
1384 /*
1385 * It worked with no retries. First ignore bogus (small)
1386 * rssi_ack values.
1387 */
1388 if (tx_rate == rate_ctrl->rate_max_phy &&
1389 rate_ctrl->hw_maxretry_pktcnt < 255) {
1390 rate_ctrl->hw_maxretry_pktcnt++;
1391 }
1392
1393 if (info_priv->tx.ts_rssi >=
1394 rate_table->info[tx_rate].rssi_ack_validmin) {
1395 /* Average the rssi */
1396 if (tx_rate != rate_ctrl->rssi_sum_rate) {
1397 rate_ctrl->rssi_sum_rate = tx_rate;
1398 rate_ctrl->rssi_sum =
1399 rate_ctrl->rssi_sum_cnt = 0;
1400 }
1401
1402 rate_ctrl->rssi_sum += info_priv->tx.ts_rssi;
1403 rate_ctrl->rssi_sum_cnt++;
1404
1405 if (rate_ctrl->rssi_sum_cnt > 4) {
1406 int32_t rssi_ackAvg =
1407 (rate_ctrl->rssi_sum + 2) / 4;
1408 int8_t rssi_thres =
1409 rate_ctrl->state[tx_rate].
1410 rssi_thres;
1411 int8_t rssi_ack_vmin =
1412 rate_table->info[tx_rate].
1413 rssi_ack_validmin;
1414
1415 rate_ctrl->rssi_sum =
1416 rate_ctrl->rssi_sum_cnt = 0;
1417
1418 /* Now reduce the current
1419 * rssi threshold. */
1420 if ((rssi_ackAvg < rssi_thres + 2) &&
1421 (rssi_thres > rssi_ack_vmin)) {
1422 rate_ctrl->state[tx_rate].
1423 rssi_thres--;
1424 }
1425
1426 state_change = TRUE;
1427 }
1428 }
1429 }
1430 }
1431
1432 /* For all cases */
1433
1434 /*
1435 * If this rate looks bad (high PER) then stop using it for
1436 * a while (except if we are probing).
1437 */
1438 if (rate_ctrl->state[tx_rate].per >= 55 && tx_rate > 0 &&
1439 rate_table->info[tx_rate].ratekbps <=
1440 rate_table->info[rate_ctrl->rate_max_phy].ratekbps) {
1441 ath_rc_get_nextlowervalid_txrate(rate_table, rate_ctrl,
1442 (u8) tx_rate, &rate_ctrl->rate_max_phy);
1443
1444 /* Don't probe for a little while. */
1445 rate_ctrl->probe_time = now_msec;
1446 }
1447
1448 if (state_change) {
1449 /*
1450 * Make sure the rates above this have higher rssi thresholds.
1451 * (Note: Monotonicity is kept within the OFDM rates and
1452 * within the CCK rates. However, no adjustment is
1453 * made to keep the rssi thresholds monotonically
1454 * increasing between the CCK and OFDM rates.)
1455 */
1456 for (rate = tx_rate; rate <
1457 rate_ctrl->rate_table_size - 1; rate++) {
1458 if (rate_table->info[rate+1].phy !=
1459 rate_table->info[tx_rate].phy)
1460 break;
1461
1462 if (rate_ctrl->state[rate].rssi_thres +
1463 rate_table->info[rate].rssi_ack_deltamin >
1464 rate_ctrl->state[rate+1].rssi_thres) {
1465 rate_ctrl->state[rate+1].rssi_thres =
1466 rate_ctrl->state[rate].
1467 rssi_thres +
1468 rate_table->info[rate].
1469 rssi_ack_deltamin;
1470 }
1471 }
1472
1473 /* Make sure the rates below this have lower rssi thresholds. */
1474 for (rate = tx_rate - 1; rate >= 0; rate--) {
1475 if (rate_table->info[rate].phy !=
1476 rate_table->info[tx_rate].phy)
1477 break;
1478
1479 if (rate_ctrl->state[rate].rssi_thres +
1480 rate_table->info[rate].rssi_ack_deltamin >
1481 rate_ctrl->state[rate+1].rssi_thres) {
1482 if (rate_ctrl->state[rate+1].rssi_thres <
1483 rate_table->info[rate].
1484 rssi_ack_deltamin)
1485 rate_ctrl->state[rate].rssi_thres = 0;
1486 else {
1487 rate_ctrl->state[rate].rssi_thres =
1488 rate_ctrl->state[rate+1].
1489 rssi_thres -
1490 rate_table->info[rate].
1491 rssi_ack_deltamin;
1492 }
1493
1494 if (rate_ctrl->state[rate].rssi_thres <
1495 rate_table->info[rate].
1496 rssi_ack_validmin) {
1497 rate_ctrl->state[rate].rssi_thres =
1498 rate_table->info[rate].
1499 rssi_ack_validmin;
1500 }
1501 }
1502 }
1503 }
1504
1505 /* Make sure the rates below this have lower PER */
1506 /* Monotonicity is kept only for rates below the current rate. */
1507 if (rate_ctrl->state[tx_rate].per < last_per) {
1508 for (rate = tx_rate - 1; rate >= 0; rate--) {
1509 if (rate_table->info[rate].phy !=
1510 rate_table->info[tx_rate].phy)
1511 break;
1512
1513 if (rate_ctrl->state[rate].per >
1514 rate_ctrl->state[rate+1].per) {
1515 rate_ctrl->state[rate].per =
1516 rate_ctrl->state[rate+1].per;
1517 }
1518 }
1519 }
1520
1521 /* Maintain monotonicity for rates above the current rate */
1522 for (rate = tx_rate; rate < rate_ctrl->rate_table_size - 1; rate++) {
1523 if (rate_ctrl->state[rate+1].per < rate_ctrl->state[rate].per)
1524 rate_ctrl->state[rate+1].per =
1525 rate_ctrl->state[rate].per;
1526 }
1527
1528 /* Every so often, we reduce the thresholds and
1529 * PER (different for CCK and OFDM). */
1530 if (now_msec - rate_ctrl->rssi_down_time >=
1531 rate_table->rssi_reduce_interval) {
1532
1533 for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) {
1534 if (rate_ctrl->state[rate].rssi_thres >
1535 rate_table->info[rate].rssi_ack_validmin)
1536 rate_ctrl->state[rate].rssi_thres -= 1;
1537 }
1538 rate_ctrl->rssi_down_time = now_msec;
1539 }
1540
1541 /* Every so often, we reduce the thresholds
1542 * and PER (different for CCK and OFDM). */
1543 if (now_msec - rate_ctrl->per_down_time >=
1544 rate_table->rssi_reduce_interval) {
1545 for (rate = 0; rate < rate_ctrl->rate_table_size; rate++) {
1546 rate_ctrl->state[rate].per =
1547 7 * rate_ctrl->state[rate].per / 8;
1548 }
1549
1550 rate_ctrl->per_down_time = now_msec;
1551 }
1552}
1553
1554/*
1555 * This routine is called in rate control callback tx_status() to give
1556 * the status of previous frames.
1557 */
1558static void ath_rc_update(struct ath_softc *sc,
1559 struct ath_rate_node *ath_rc_priv,
1560 struct ath_tx_info_priv *info_priv, int final_ts_idx,
1561 int xretries, int long_retry)
1562{
1563 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1564 struct ath_rate_table *rate_table;
1565 struct ath_tx_ratectrl *rate_ctrl;
1566 struct ath_rc_series rcs[4];
1567 u8 flags;
1568 u32 series = 0, rix;
1569
1570 memcpy(rcs, info_priv->rcs, 4 * sizeof(rcs[0]));
1571 rate_table = (struct ath_rate_table *)
1572 asc->hw_rate_table[sc->sc_curmode];
1573 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
1574 ASSERT(rcs[0].tries != 0);
1575
1576 /*
1577 * If the first rate is not the final index, there
1578 * are intermediate rate failures to be processed.
1579 */
1580 if (final_ts_idx != 0) {
1581 /* Process intermediate rates that failed.*/
1582 for (series = 0; series < final_ts_idx ; series++) {
1583 if (rcs[series].tries != 0) {
1584 flags = rcs[series].flags;
1585 /* If HT40 and we have switched mode from
1586 * 40 to 20 => don't update */
1587 if ((flags & ATH_RC_CW40_FLAG) &&
1588 (rate_ctrl->rc_phy_mode !=
1589 (flags & ATH_RC_CW40_FLAG)))
1590 return;
1591 if ((flags & ATH_RC_CW40_FLAG) &&
1592 (flags & ATH_RC_SGI_FLAG))
1593 rix = rate_table->info[
1594 rcs[series].rix].ht_index;
1595 else if (flags & ATH_RC_SGI_FLAG)
1596 rix = rate_table->info[
1597 rcs[series].rix].sgi_index;
1598 else if (flags & ATH_RC_CW40_FLAG)
1599 rix = rate_table->info[
1600 rcs[series].rix].cw40index;
1601 else
1602 rix = rate_table->info[
1603 rcs[series].rix].base_index;
1604 ath_rc_update_ht(sc, ath_rc_priv,
1605 info_priv, rix,
1606 xretries ? 1 : 2,
1607 rcs[series].tries);
1608 }
1609 }
1610 } else {
1611 /*
1612 * Handle the special case of MIMO PS burst, where the second
1613 * aggregate is sent out with only one rate and one try.
1614 * Treating it as an excessive retry penalizes the rate
1615 * inordinately.
1616 */
1617 if (rcs[0].tries == 1 && xretries == 1)
1618 xretries = 2;
1619 }
1620
1621 flags = rcs[series].flags;
1622 /* If HT40 and we have switched mode from 40 to 20 => don't update */
1623 if ((flags & ATH_RC_CW40_FLAG) &&
1624 (rate_ctrl->rc_phy_mode != (flags & ATH_RC_CW40_FLAG)))
1625 return;
1626
1627 if ((flags & ATH_RC_CW40_FLAG) && (flags & ATH_RC_SGI_FLAG))
1628 rix = rate_table->info[rcs[series].rix].ht_index;
1629 else if (flags & ATH_RC_SGI_FLAG)
1630 rix = rate_table->info[rcs[series].rix].sgi_index;
1631 else if (flags & ATH_RC_CW40_FLAG)
1632 rix = rate_table->info[rcs[series].rix].cw40index;
1633 else
1634 rix = rate_table->info[rcs[series].rix].base_index;
1635
1636 ath_rc_update_ht(sc, ath_rc_priv, info_priv, rix,
1637 xretries, long_retry);
1638}
1639
1640
1641/*
1642 * Process a tx descriptor for a completed transmit (success or failure).
1643 */
1644static void ath_rate_tx_complete(struct ath_softc *sc,
1645 struct ath_node *an,
1646 struct ath_rate_node *rc_priv,
1647 struct ath_tx_info_priv *info_priv)
1648{
1649 int final_ts_idx = info_priv->tx.ts_rateindex;
1650 int tx_status = 0, is_underrun = 0;
1651 struct ath_vap *avp;
1652
1653 avp = rc_priv->avp;
1654 if ((avp->av_config.av_fixed_rateset != IEEE80211_FIXED_RATE_NONE)
1655 || info_priv->tx.ts_status & ATH9K_TXERR_FILT)
1656 return;
1657
1658 if (info_priv->tx.ts_rssi > 0) {
1659 ATH_RSSI_LPF(an->an_chainmask_sel.tx_avgrssi,
1660 info_priv->tx.ts_rssi);
1661 }
1662
1663 /*
1664 * If underrun error is seen assume it as an excessive retry only
1665 * if prefetch trigger level have reached the max (0x3f for 5416)
1666 * Adjust the long retry as if the frame was tried ATH_11N_TXMAXTRY
1667 * times. This affects how ratectrl updates PER for the failed rate.
1668 */
1669 if (info_priv->tx.ts_flags &
1670 (ATH9K_TX_DATA_UNDERRUN | ATH9K_TX_DELIM_UNDERRUN) &&
1671 ((sc->sc_ah->ah_txTrigLevel) >= tx_triglevel_max)) {
1672 tx_status = 1;
1673 is_underrun = 1;
1674 }
1675
1676 if ((info_priv->tx.ts_status & ATH9K_TXERR_XRETRY) ||
1677 (info_priv->tx.ts_status & ATH9K_TXERR_FIFO))
1678 tx_status = 1;
1679
1680 ath_rc_update(sc, rc_priv, info_priv, final_ts_idx, tx_status,
1681 (is_underrun) ? ATH_11N_TXMAXTRY :
1682 info_priv->tx.ts_longretry);
1683}
1684
1685
1686/*
1687 * Update the SIB's rate control information
1688 *
1689 * This should be called when the supported rates change
1690 * (e.g. SME operation, wireless mode change)
1691 *
1692 * It will determine which rates are valid for use.
1693 */
1694static void ath_rc_sib_update(struct ath_softc *sc,
1695 struct ath_rate_node *ath_rc_priv,
1696 u32 capflag, int keep_state,
1697 struct ath_rateset *negotiated_rates,
1698 struct ath_rateset *negotiated_htrates)
1699{
1700 struct ath_rate_table *rate_table = NULL;
1701 struct ath_rate_softc *asc = (struct ath_rate_softc *)sc->sc_rc;
1702 struct ath_rateset *rateset = negotiated_rates;
1703 u8 *ht_mcs = (u8 *)negotiated_htrates;
1704 struct ath_tx_ratectrl *rate_ctrl = (struct ath_tx_ratectrl *)
1705 (ath_rc_priv);
1706 u8 i, j, k, hi = 0, hthi = 0;
1707
1708 rate_table = (struct ath_rate_table *)
1709 asc->hw_rate_table[sc->sc_curmode];
1710
1711 /* Initial rate table size. Will change depending
1712 * on the working rate set */
1713 rate_ctrl->rate_table_size = MAX_TX_RATE_TBL;
1714
1715 /* Initialize thresholds according to the global rate table */
1716 for (i = 0 ; (i < rate_ctrl->rate_table_size) && (!keep_state); i++) {
1717 rate_ctrl->state[i].rssi_thres =
1718 rate_table->info[i].rssi_ack_validmin;
1719 rate_ctrl->state[i].per = 0;
1720 }
1721
1722 /* Determine the valid rates */
1723 ath_rc_init_valid_txmask(rate_ctrl);
1724
1725 for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
1726 for (j = 0; j < MAX_TX_RATE_PHY; j++)
1727 rate_ctrl->valid_phy_rateidx[i][j] = 0;
1728 rate_ctrl->valid_phy_ratecnt[i] = 0;
1729 }
1730 rate_ctrl->rc_phy_mode = (capflag & WLAN_RC_40_FLAG);
1731
1732 /* Set stream capability */
1733 ath_rc_priv->single_stream = (capflag & WLAN_RC_DS_FLAG) ? 0 : 1;
1734
1735 if (!rateset->rs_nrates) {
1736 /* No working rate, just initialize valid rates */
1737 hi = ath_rc_sib_init_validrates(ath_rc_priv, rate_table,
1738 capflag);
1739 } else {
1740 /* Use intersection of working rates and valid rates */
1741 hi = ath_rc_sib_setvalid_rates(ath_rc_priv, rate_table,
1742 rateset, capflag);
1743 if (capflag & WLAN_RC_HT_FLAG) {
1744 hthi = ath_rc_sib_setvalid_htrates(ath_rc_priv,
1745 rate_table,
1746 ht_mcs,
1747 capflag);
1748 }
1749 hi = A_MAX(hi, hthi);
1750 }
1751
1752 rate_ctrl->rate_table_size = hi + 1;
1753 rate_ctrl->rate_max_phy = 0;
1754 ASSERT(rate_ctrl->rate_table_size <= MAX_TX_RATE_TBL);
1755
1756 for (i = 0, k = 0; i < WLAN_RC_PHY_MAX; i++) {
1757 for (j = 0; j < rate_ctrl->valid_phy_ratecnt[i]; j++) {
1758 rate_ctrl->valid_rate_index[k++] =
1759 rate_ctrl->valid_phy_rateidx[i][j];
1760 }
1761
1762 if (!ath_rc_valid_phyrate(i, rate_table->initial_ratemax, TRUE)
1763 || !rate_ctrl->valid_phy_ratecnt[i])
1764 continue;
1765
1766 rate_ctrl->rate_max_phy = rate_ctrl->valid_phy_rateidx[i][j-1];
1767 }
1768 ASSERT(rate_ctrl->rate_table_size <= MAX_TX_RATE_TBL);
1769 ASSERT(k <= MAX_TX_RATE_TBL);
1770
1771 rate_ctrl->max_valid_rate = k;
1772 /*
1773 * Some third party vendors don't send the supported rate series in
1774 * order. So sorting to make sure its in order, otherwise our RateFind
1775 * Algo will select wrong rates
1776 */
1777 ath_rc_sort_validrates(rate_table, rate_ctrl);
1778 rate_ctrl->rate_max_phy = rate_ctrl->valid_rate_index[k-4];
1779}
1780
1781/*
1782 * Update rate-control state on station associate/reassociate.
1783 */
1784static int ath_rate_newassoc(struct ath_softc *sc,
1785 struct ath_rate_node *ath_rc_priv,
1786 unsigned int capflag,
1787 struct ath_rateset *negotiated_rates,
1788 struct ath_rateset *negotiated_htrates)
1789{
1790
1791
1792 ath_rc_priv->ht_cap =
1793 ((capflag & ATH_RC_DS_FLAG) ? WLAN_RC_DS_FLAG : 0) |
1794 ((capflag & ATH_RC_SGI_FLAG) ? WLAN_RC_SGI_FLAG : 0) |
1795 ((capflag & ATH_RC_HT_FLAG) ? WLAN_RC_HT_FLAG : 0) |
1796 ((capflag & ATH_RC_CW40_FLAG) ? WLAN_RC_40_FLAG : 0);
1797
1798 ath_rc_sib_update(sc, ath_rc_priv, ath_rc_priv->ht_cap, 0,
1799 negotiated_rates, negotiated_htrates);
1800
1801 return 0;
1802}
1803
1804/*
1805 * This routine is called to initialize the rate control parameters
1806 * in the SIB. It is called initially during system initialization
1807 * or when a station is associated with the AP.
1808 */
1809static void ath_rc_sib_init(struct ath_rate_node *ath_rc_priv)
1810{
1811 struct ath_tx_ratectrl *rate_ctrl;
1812
1813 rate_ctrl = (struct ath_tx_ratectrl *)(ath_rc_priv);
1814 rate_ctrl->rssi_down_time = jiffies_to_msecs(jiffies);
1815}
1816
1817
1818static void ath_setup_rates(struct ieee80211_local *local, struct sta_info *sta)
1819
1820{
1821 struct ieee80211_supported_band *sband;
1822 struct ieee80211_hw *hw = local_to_hw(local);
1823 struct ath_softc *sc = hw->priv;
1824 struct ath_rate_node *rc_priv = sta->rate_ctrl_priv;
1825 int i, j = 0;
1826
1827 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
1828 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
1829 for (i = 0; i < sband->n_bitrates; i++) {
1830 if (sta->supp_rates[local->hw.conf.channel->band] & BIT(i)) {
1831 rc_priv->neg_rates.rs_rates[j]
1832 = (sband->bitrates[i].bitrate * 2) / 10;
1833 j++;
1834 }
1835 }
1836 rc_priv->neg_rates.rs_nrates = j;
1837}
1838
1839void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv)
1840{
1841 struct ath_softc *sc = hw->priv;
1842 u32 capflag = 0;
1843
1844 if (hw->conf.ht_conf.ht_supported) {
1845 capflag |= ATH_RC_HT_FLAG | ATH_RC_DS_FLAG;
1846 if (sc->sc_ht_info.tx_chan_width == ATH9K_HT_MACMODE_2040)
1847 capflag |= ATH_RC_CW40_FLAG;
1848 }
1849
1850 ath_rate_newassoc(sc, rc_priv, capflag,
1851 &rc_priv->neg_rates,
1852 &rc_priv->neg_ht_rates);
1853
1854}
1855
1856/* Rate Control callbacks */
1857static void ath_tx_status(void *priv, struct net_device *dev,
1858 struct sk_buff *skb)
1859{
1860 struct ath_softc *sc = priv;
1861 struct ath_tx_info_priv *tx_info_priv;
1862 struct ath_node *an;
1863 struct sta_info *sta;
1864 struct ieee80211_local *local;
1865 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1866 struct ieee80211_hdr *hdr;
1867 __le16 fc;
1868
1869 local = hw_to_local(sc->hw);
1870 hdr = (struct ieee80211_hdr *)skb->data;
1871 fc = hdr->frame_control;
1872 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
1873
1874 spin_lock_bh(&sc->node_lock);
1875 an = ath_node_find(sc, hdr->addr1);
1876 spin_unlock_bh(&sc->node_lock);
1877
1878 sta = sta_info_get(local, hdr->addr1);
1879 if (!an || !sta || !ieee80211_is_data(fc)) {
1880 if (tx_info->driver_data[0] != NULL) {
1881 kfree(tx_info->driver_data[0]);
1882 tx_info->driver_data[0] = NULL;
1883 }
1884 return;
1885 }
1886 if (tx_info->driver_data[0] != NULL) {
1887 ath_rate_tx_complete(sc, an, sta->rate_ctrl_priv, tx_info_priv);
1888 kfree(tx_info->driver_data[0]);
1889 tx_info->driver_data[0] = NULL;
1890 }
1891}
1892
1893static void ath_tx_aggr_resp(struct ath_softc *sc,
1894 struct sta_info *sta,
1895 struct ath_node *an,
1896 u8 tidno)
1897{
1898 struct ieee80211_hw *hw = sc->hw;
1899 struct ieee80211_local *local;
1900 struct ath_atx_tid *txtid;
1901 struct ieee80211_supported_band *sband;
1902 u16 buffersize = 0;
1903 int state;
1904 DECLARE_MAC_BUF(mac);
1905
1906 if (!sc->sc_txaggr)
1907 return;
1908
1909 txtid = ATH_AN_2_TID(an, tidno);
1910 if (!txtid->paused)
1911 return;
1912
1913 local = hw_to_local(sc->hw);
1914 sband = hw->wiphy->bands[hw->conf.channel->band];
1915 buffersize = IEEE80211_MIN_AMPDU_BUF <<
1916 sband->ht_info.ampdu_factor; /* FIXME */
1917 state = sta->ampdu_mlme.tid_state_tx[tidno];
1918
1919 if (state & HT_ADDBA_RECEIVED_MSK) {
1920 txtid->addba_exchangecomplete = 1;
1921 txtid->addba_exchangeinprogress = 0;
1922 txtid->baw_size = buffersize;
1923
1924 DPRINTF(sc, ATH_DBG_AGGR,
1925 "%s: Resuming tid, buffersize: %d\n",
1926 __func__,
1927 buffersize);
1928
1929 ath_tx_resume_tid(sc, txtid);
1930 }
1931}
1932
1933static void ath_get_rate(void *priv, struct net_device *dev,
1934 struct ieee80211_supported_band *sband,
1935 struct sk_buff *skb,
1936 struct rate_selection *sel)
1937{
1938 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1939 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1940 struct sta_info *sta;
1941 struct ath_softc *sc = (struct ath_softc *)priv;
1942 struct ieee80211_hw *hw = sc->hw;
1943 struct ath_tx_info_priv *tx_info_priv;
1944 struct ath_rate_node *ath_rc_priv;
1945 struct ath_node *an;
1946 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1947 int is_probe, chk, ret;
1948 s8 lowest_idx;
1949 __le16 fc = hdr->frame_control;
1950 u8 *qc, tid;
1951 DECLARE_MAC_BUF(mac);
1952
1953 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
1954
1955 /* allocate driver private area of tx_info */
1956 tx_info->driver_data[0] = kzalloc(sizeof(*tx_info_priv), GFP_ATOMIC);
1957 ASSERT(tx_info->driver_data[0] != NULL);
1958 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
1959
1960 sta = sta_info_get(local, hdr->addr1);
1961 lowest_idx = rate_lowest_index(local, sband, sta);
1962 tx_info_priv->min_rate = (sband->bitrates[lowest_idx].bitrate * 2) / 10;
1963 /* lowest rate for management and multicast/broadcast frames */
1964 if (!ieee80211_is_data(fc) ||
1965 is_multicast_ether_addr(hdr->addr1) || !sta) {
1966 sel->rate_idx = lowest_idx;
1967 return;
1968 }
1969
1970 ath_rc_priv = sta->rate_ctrl_priv;
1971
1972 /* Find tx rate for unicast frames */
1973 ath_rate_findrate(sc, ath_rc_priv,
1974 ATH_11N_TXMAXTRY, 4,
1975 ATH_RC_PROBE_ALLOWED,
1976 tx_info_priv->rcs,
1977 &is_probe,
1978 false);
1979 if (is_probe)
1980 sel->probe_idx = ((struct ath_tx_ratectrl *)
1981 sta->rate_ctrl_priv)->probe_rate;
1982
1983 /* Ratecontrol sometimes returns invalid rate index */
1984 if (tx_info_priv->rcs[0].rix != 0xff)
1985 ath_rc_priv->prev_data_rix = tx_info_priv->rcs[0].rix;
1986 else
1987 tx_info_priv->rcs[0].rix = ath_rc_priv->prev_data_rix;
1988
1989 sel->rate_idx = tx_info_priv->rcs[0].rix;
1990
1991 /* Check if aggregation has to be enabled for this tid */
1992
1993 if (hw->conf.ht_conf.ht_supported) {
1994 if (ieee80211_is_data_qos(fc)) {
1995 qc = ieee80211_get_qos_ctl(hdr);
1996 tid = qc[0] & 0xf;
1997
1998 spin_lock_bh(&sc->node_lock);
1999 an = ath_node_find(sc, hdr->addr1);
2000 spin_unlock_bh(&sc->node_lock);
2001
2002 if (!an) {
2003 DPRINTF(sc, ATH_DBG_AGGR,
2004 "%s: Node not found to "
2005 "init/chk TX aggr\n", __func__);
2006 return;
2007 }
2008
2009 chk = ath_tx_aggr_check(sc, an, tid);
2010 if (chk == AGGR_REQUIRED) {
2011 ret = ieee80211_start_tx_ba_session(hw,
2012 hdr->addr1, tid);
2013 if (ret)
2014 DPRINTF(sc, ATH_DBG_AGGR,
2015 "%s: Unable to start tx "
2016 "aggr for: %s\n",
2017 __func__,
2018 print_mac(mac, hdr->addr1));
2019 else
2020 DPRINTF(sc, ATH_DBG_AGGR,
2021 "%s: Started tx aggr for: %s\n",
2022 __func__,
2023 print_mac(mac, hdr->addr1));
2024 } else if (chk == AGGR_EXCHANGE_PROGRESS)
2025 ath_tx_aggr_resp(sc, sta, an, tid);
2026 }
2027 }
2028}
2029
2030static void ath_rate_init(void *priv, void *priv_sta,
2031 struct ieee80211_local *local,
2032 struct sta_info *sta)
2033{
2034 struct ieee80211_supported_band *sband;
2035 struct ieee80211_hw *hw = local_to_hw(local);
2036 struct ieee80211_conf *conf = &local->hw.conf;
2037 struct ath_softc *sc = hw->priv;
2038 int i, j = 0;
2039
2040 DPRINTF(sc, ATH_DBG_RATE, "%s\n", __func__);
2041
2042 sband = local->hw.wiphy->bands[local->hw.conf.channel->band];
2043 sta->txrate_idx = rate_lowest_index(local, sband, sta);
2044
2045 ath_setup_rates(local, sta);
2046 if (conf->flags & IEEE80211_CONF_SUPPORT_HT_MODE) {
2047 for (i = 0; i < MCS_SET_SIZE; i++) {
2048 if (conf->ht_conf.supp_mcs_set[i/8] & (1<<(i%8)))
2049 ((struct ath_rate_node *)
2050 priv_sta)->neg_ht_rates.rs_rates[j++] = i;
2051 if (j == ATH_RATE_MAX)
2052 break;
2053 }
2054 ((struct ath_rate_node *)priv_sta)->neg_ht_rates.rs_nrates = j;
2055 }
2056 ath_rc_node_update(hw, priv_sta);
2057}
2058
2059static void ath_rate_clear(void *priv)
2060{
2061 return;
2062}
2063
2064static void *ath_rate_alloc(struct ieee80211_local *local)
2065{
2066 struct ieee80211_hw *hw = local_to_hw(local);
2067 struct ath_softc *sc = hw->priv;
2068
2069 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
2070 return local->hw.priv;
2071}
2072
2073static void ath_rate_free(void *priv)
2074{
2075 return;
2076}
2077
2078static void *ath_rate_alloc_sta(void *priv, gfp_t gfp)
2079{
2080 struct ath_softc *sc = priv;
2081 struct ath_vap *avp = sc->sc_vaps[0];
2082 struct ath_rate_node *rate_priv;
2083
2084 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
2085 rate_priv = ath_rate_node_alloc(avp, sc->sc_rc, gfp);
2086 if (!rate_priv) {
2087 DPRINTF(sc, ATH_DBG_FATAL, "%s:Unable to allocate"
2088 "private rate control structure", __func__);
2089 return NULL;
2090 }
2091 ath_rc_sib_init(rate_priv);
2092 return rate_priv;
2093}
2094
2095static void ath_rate_free_sta(void *priv, void *priv_sta)
2096{
2097 struct ath_rate_node *rate_priv = priv_sta;
2098 struct ath_softc *sc = priv;
2099
2100 DPRINTF(sc, ATH_DBG_RATE, "%s", __func__);
2101 ath_rate_node_free(rate_priv);
2102}
2103
2104static struct rate_control_ops ath_rate_ops = {
2105 .module = NULL,
2106 .name = "ath9k_rate_control",
2107 .tx_status = ath_tx_status,
2108 .get_rate = ath_get_rate,
2109 .rate_init = ath_rate_init,
2110 .clear = ath_rate_clear,
2111 .alloc = ath_rate_alloc,
2112 .free = ath_rate_free,
2113 .alloc_sta = ath_rate_alloc_sta,
2114 .free_sta = ath_rate_free_sta
2115};
2116
2117int ath_rate_control_register(void)
2118{
2119 return ieee80211_rate_control_register(&ath_rate_ops);
2120}
2121
2122void ath_rate_control_unregister(void)
2123{
2124 ieee80211_rate_control_unregister(&ath_rate_ops);
2125}
2126
diff --git a/drivers/net/wireless/ath9k/rc.h b/drivers/net/wireless/ath9k/rc.h
new file mode 100644
index 000000000000..8f6c28e65191
--- /dev/null
+++ b/drivers/net/wireless/ath9k/rc.h
@@ -0,0 +1,316 @@
1/*
2 * Copyright (c) 2004 Sam Leffler, Errno Consulting
3 * Copyright (c) 2004 Video54 Technologies, Inc.
4 * Copyright (c) 2008 Atheros Communications Inc.
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#ifndef RC_H
20#define RC_H
21
22#include "ath9k.h"
23/*
24 * Interface definitions for transmit rate control modules for the
25 * Atheros driver.
26 *
27 * A rate control module is responsible for choosing the transmit rate
28 * for each data frame. Management+control frames are always sent at
29 * a fixed rate.
30 *
31 * Only one module may be present at a time; the driver references
32 * rate control interfaces by symbol name. If multiple modules are
33 * to be supported we'll need to switch to a registration-based scheme
34 * as is currently done, for example, for authentication modules.
35 *
36 * An instance of the rate control module is attached to each device
37 * at attach time and detached when the device is destroyed. The module
38 * may associate data with each device and each node (station). Both
39 * sets of storage are opaque except for the size of the per-node storage
40 * which must be provided when the module is attached.
41 *
42 * The rate control module is notified for each state transition and
43 * station association/reassociation. Otherwise it is queried for a
44 * rate for each outgoing frame and provided status from each transmitted
45 * frame. Any ancillary processing is the responsibility of the module
46 * (e.g. if periodic processing is required then the module should setup
47 * it's own timer).
48 *
49 * In addition to the transmit rate for each frame the module must also
50 * indicate the number of attempts to make at the specified rate. If this
51 * number is != ATH_TXMAXTRY then an additional callback is made to setup
52 * additional transmit state. The rate control code is assumed to write
53 * this additional data directly to the transmit descriptor.
54 */
55
56struct ath_softc;
57
58#define TRUE 1
59#define FALSE 0
60
61#define ATH_RATE_MAX 30
62#define MCS_SET_SIZE 128
63
64enum ieee80211_fixed_rate_mode {
65 IEEE80211_FIXED_RATE_NONE = 0,
66 IEEE80211_FIXED_RATE_MCS = 1 /* HT rates */
67};
68
69/*
70 * Use the hal os glue code to get ms time
71 */
72#define IEEE80211_RATE_IDX_ENTRY(val, idx) (((val&(0xff<<(idx*8)))>>(idx*8)))
73
74#define SHORT_PRE 1
75#define LONG_PRE 0
76
77#define WLAN_PHY_HT_20_SS WLAN_RC_PHY_HT_20_SS
78#define WLAN_PHY_HT_20_DS WLAN_RC_PHY_HT_20_DS
79#define WLAN_PHY_HT_20_DS_HGI WLAN_RC_PHY_HT_20_DS_HGI
80#define WLAN_PHY_HT_40_SS WLAN_RC_PHY_HT_40_SS
81#define WLAN_PHY_HT_40_SS_HGI WLAN_RC_PHY_HT_40_SS_HGI
82#define WLAN_PHY_HT_40_DS WLAN_RC_PHY_HT_40_DS
83#define WLAN_PHY_HT_40_DS_HGI WLAN_RC_PHY_HT_40_DS_HGI
84
85#define WLAN_PHY_OFDM PHY_OFDM
86#define WLAN_PHY_CCK PHY_CCK
87
88#define TRUE_20 0x2
89#define TRUE_40 0x4
90#define TRUE_2040 (TRUE_20|TRUE_40)
91#define TRUE_ALL (TRUE_2040|TRUE)
92
93enum {
94 WLAN_RC_PHY_HT_20_SS = 4,
95 WLAN_RC_PHY_HT_20_DS,
96 WLAN_RC_PHY_HT_40_SS,
97 WLAN_RC_PHY_HT_40_DS,
98 WLAN_RC_PHY_HT_20_SS_HGI,
99 WLAN_RC_PHY_HT_20_DS_HGI,
100 WLAN_RC_PHY_HT_40_SS_HGI,
101 WLAN_RC_PHY_HT_40_DS_HGI,
102 WLAN_RC_PHY_MAX
103};
104
105#define WLAN_RC_PHY_DS(_phy) ((_phy == WLAN_RC_PHY_HT_20_DS) \
106 || (_phy == WLAN_RC_PHY_HT_40_DS) \
107 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
108 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
109#define WLAN_RC_PHY_40(_phy) ((_phy == WLAN_RC_PHY_HT_40_SS) \
110 || (_phy == WLAN_RC_PHY_HT_40_DS) \
111 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
112 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
113#define WLAN_RC_PHY_SGI(_phy) ((_phy == WLAN_RC_PHY_HT_20_SS_HGI) \
114 || (_phy == WLAN_RC_PHY_HT_20_DS_HGI) \
115 || (_phy == WLAN_RC_PHY_HT_40_SS_HGI) \
116 || (_phy == WLAN_RC_PHY_HT_40_DS_HGI))
117
118#define WLAN_RC_PHY_HT(_phy) (_phy >= WLAN_RC_PHY_HT_20_SS)
119
120/* Returns the capflag mode */
121#define WLAN_RC_CAP_MODE(capflag) (((capflag & WLAN_RC_HT_FLAG) ? \
122 (capflag & WLAN_RC_40_FLAG) ? TRUE_40 : TRUE_20 : TRUE))
123
124/* Return TRUE if flag supports HT20 && client supports HT20 or
125 * return TRUE if flag supports HT40 && client supports HT40.
126 * This is used becos some rates overlap between HT20/HT40.
127 */
128
129#define WLAN_RC_PHY_HT_VALID(flag, capflag) (((flag & TRUE_20) && !(capflag \
130 & WLAN_RC_40_FLAG)) || ((flag & TRUE_40) && \
131 (capflag & WLAN_RC_40_FLAG)))
132
133#define WLAN_RC_DS_FLAG (0x01)
134#define WLAN_RC_40_FLAG (0x02)
135#define WLAN_RC_SGI_FLAG (0x04)
136#define WLAN_RC_HT_FLAG (0x08)
137
138/* Index into the rate table */
139#define INIT_RATE_MAX_20 23
140#define INIT_RATE_MAX_40 40
141
142#define RATE_TABLE_SIZE 64
143
144/* XXX: Convert to kdoc */
145struct ath_rate_table {
146 int rate_cnt;
147 struct {
148 int valid; /* Valid for use in rate control */
149 int valid_single_stream;/* Valid for use in rate control
150 for single stream operation */
151 u8 phy; /* CCK/OFDM/TURBO/XR */
152 u32 ratekbps; /* Rate in Kbits per second */
153 u32 user_ratekbps; /* User rate in KBits per second */
154 u8 ratecode; /* rate that goes into
155 hw descriptors */
156 u8 short_preamble; /* Mask for enabling short preamble
157 in rate code for CCK */
158 u8 dot11rate; /* Value that goes into supported
159 rates info element of MLME */
160 u8 ctrl_rate; /* Index of next lower basic rate,
161 used for duration computation */
162 int8_t rssi_ack_validmin; /* Rate control related */
163 int8_t rssi_ack_deltamin; /* Rate control related */
164 u8 base_index; /* base rate index */
165 u8 cw40index; /* 40cap rate index */
166 u8 sgi_index; /* shortgi rate index */
167 u8 ht_index; /* shortgi rate index */
168 u32 max_4ms_framelen; /* Maximum frame length(bytes)
169 for 4ms tx duration */
170 } info[RATE_TABLE_SIZE];
171 u32 probe_interval; /* interval for ratectrl to
172 probe for other rates */
173 u32 rssi_reduce_interval; /* interval for ratectrl
174 to reduce RSSI */
175 u8 initial_ratemax; /* the initial ratemax value used
176 in ath_rc_sib_update() */
177};
178
179#define ATH_RC_PROBE_ALLOWED 0x00000001
180#define ATH_RC_MINRATE_LASTRATE 0x00000002
181#define ATH_RC_SHORT_PREAMBLE 0x00000004
182
183struct ath_rc_series {
184 u8 rix;
185 u8 tries;
186 u8 flags;
187 u32 max_4ms_framelen;
188};
189
190/* rcs_flags definition */
191#define ATH_RC_DS_FLAG 0x01
192#define ATH_RC_CW40_FLAG 0x02 /* CW 40 */
193#define ATH_RC_SGI_FLAG 0x04 /* Short Guard Interval */
194#define ATH_RC_HT_FLAG 0x08 /* HT */
195#define ATH_RC_RTSCTS_FLAG 0x10 /* RTS-CTS */
196
197/*
198 * State structures for new rate adaptation code
199 */
200#define MAX_TX_RATE_TBL 64
201#define MAX_TX_RATE_PHY 48
202
203struct ath_tx_ratectrl_state {
204 int8_t rssi_thres; /* required rssi for this rate (dB) */
205 u8 per; /* recent estimate of packet error rate (%) */
206};
207
208struct ath_tx_ratectrl {
209 struct ath_tx_ratectrl_state state[MAX_TX_RATE_TBL]; /* state */
210 int8_t rssi_last; /* last ack rssi */
211 int8_t rssi_last_lookup; /* last ack rssi used for lookup */
212 int8_t rssi_last_prev; /* previous last ack rssi */
213 int8_t rssi_last_prev2; /* 2nd previous last ack rssi */
214 int32_t rssi_sum_cnt; /* count of rssi_sum for averaging */
215 int32_t rssi_sum_rate; /* rate that we are averaging */
216 int32_t rssi_sum; /* running sum of rssi for averaging */
217 u32 valid_txrate_mask; /* mask of valid rates */
218 u8 rate_table_size; /* rate table size */
219 u8 rate_max; /* max rate that has recently worked */
220 u8 probe_rate; /* rate we are probing at */
221 u32 rssi_time; /* msec timestamp for last ack rssi */
222 u32 rssi_down_time; /* msec timestamp for last down step */
223 u32 probe_time; /* msec timestamp for last probe */
224 u8 hw_maxretry_pktcnt; /* num packets since we got
225 HW max retry error */
226 u8 max_valid_rate; /* maximum number of valid rate */
227 u8 valid_rate_index[MAX_TX_RATE_TBL]; /* valid rate index */
228 u32 per_down_time; /* msec timstamp for last
229 PER down step */
230
231 /* 11n state */
232 u8 valid_phy_ratecnt[WLAN_RC_PHY_MAX]; /* valid rate count */
233 u8 valid_phy_rateidx[WLAN_RC_PHY_MAX][MAX_TX_RATE_TBL];
234 u8 rc_phy_mode;
235 u8 rate_max_phy; /* Phy index for the max rate */
236 u32 rate_max_lastused; /* msec timstamp of when we
237 last used rateMaxPhy */
238 u32 probe_interval; /* interval for ratectrl to probe
239 for other rates */
240};
241
242struct ath_rateset {
243 u8 rs_nrates;
244 u8 rs_rates[ATH_RATE_MAX];
245};
246
247/* per-device state */
248struct ath_rate_softc {
249 /* phy tables that contain rate control data */
250 const void *hw_rate_table[WIRELESS_MODE_MAX];
251 int fixedrix; /* -1 or index of fixed rate */
252};
253
254/* per-node state */
255struct ath_rate_node {
256 struct ath_tx_ratectrl tx_ratectrl; /* rate control state proper */
257 u32 prev_data_rix; /* rate idx of last data frame */
258
259 /* map of rate ix -> negotiated rate set ix */
260 u8 rixmap[MAX_TX_RATE_TBL];
261
262 /* map of ht rate ix -> negotiated rate set ix */
263 u8 ht_rixmap[MAX_TX_RATE_TBL];
264
265 u8 ht_cap; /* ht capabilities */
266 u8 ant_tx; /* current transmit antenna */
267
268 u8 single_stream; /* When TRUE, only single
269 stream Tx possible */
270 struct ath_rateset neg_rates; /* Negotiated rates */
271 struct ath_rateset neg_ht_rates; /* Negotiated HT rates */
272 struct ath_rate_softc *asc; /* back pointer to atheros softc */
273 struct ath_vap *avp; /* back pointer to vap */
274};
275
276/* Driver data of ieee80211_tx_info */
277struct ath_tx_info_priv {
278 struct ath_rc_series rcs[4];
279 struct ath_tx_status tx;
280 int n_frames;
281 int n_bad_frames;
282 u8 min_rate;
283};
284
285/*
286 * Attach/detach a rate control module.
287 */
288struct ath_rate_softc *ath_rate_attach(struct ath_hal *ah);
289void ath_rate_detach(struct ath_rate_softc *asc);
290
291/*
292 * Update/reset rate control state for 802.11 state transitions.
293 * Important mostly as the analog to ath_rate_newassoc when operating
294 * in station mode.
295 */
296void ath_rc_node_update(struct ieee80211_hw *hw, struct ath_rate_node *rc_priv);
297void ath_rate_newstate(struct ath_softc *sc, struct ath_vap *avp);
298
299/*
300 * Return the tx rate series.
301 */
302void ath_rate_findrate(struct ath_softc *sc, struct ath_rate_node *ath_rc_priv,
303 int num_tries, int num_rates,
304 unsigned int rcflag, struct ath_rc_series[],
305 int *is_probe, int isretry);
306/*
307 * Return rate index for given Dot11 Rate.
308 */
309u8 ath_rate_findrateix(struct ath_softc *sc,
310 u8 dot11_rate);
311
312/* Routines to register/unregister rate control algorithm */
313int ath_rate_control_register(void);
314void ath_rate_control_unregister(void);
315
316#endif /* RC_H */
diff --git a/drivers/net/wireless/ath9k/recv.c b/drivers/net/wireless/ath9k/recv.c
new file mode 100644
index 000000000000..8e14e643e994
--- /dev/null
+++ b/drivers/net/wireless/ath9k/recv.c
@@ -0,0 +1,1318 @@
1/*
2 * Copyright (c) 2008 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/*
18 * Implementation of receive path.
19 */
20
21#include "core.h"
22
23/*
24 * Setup and link descriptors.
25 *
26 * 11N: we can no longer afford to self link the last descriptor.
27 * MAC acknowledges BA status as long as it copies frames to host
28 * buffer (or rx fifo). This can incorrectly acknowledge packets
29 * to a sender if last desc is self-linked.
30 *
31 * NOTE: Caller should hold the rxbuf lock.
32 */
33
34static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
35{
36 struct ath_hal *ah = sc->sc_ah;
37 struct ath_desc *ds;
38 struct sk_buff *skb;
39
40 ATH_RXBUF_RESET(bf);
41
42 ds = bf->bf_desc;
43 ds->ds_link = 0; /* link to null */
44 ds->ds_data = bf->bf_buf_addr;
45
46 /* XXX For RADAR?
47 * virtual addr of the beginning of the buffer. */
48 skb = bf->bf_mpdu;
49 ASSERT(skb != NULL);
50 ds->ds_vdata = skb->data;
51
52 /* setup rx descriptors */
53 ath9k_hw_setuprxdesc(ah,
54 ds,
55 skb_tailroom(skb), /* buffer size */
56 0);
57
58 if (sc->sc_rxlink == NULL)
59 ath9k_hw_putrxbuf(ah, bf->bf_daddr);
60 else
61 *sc->sc_rxlink = bf->bf_daddr;
62
63 sc->sc_rxlink = &ds->ds_link;
64 ath9k_hw_rxena(ah);
65}
66
67/* Process received BAR frame */
68
69static int ath_bar_rx(struct ath_softc *sc,
70 struct ath_node *an,
71 struct sk_buff *skb)
72{
73 struct ieee80211_bar *bar;
74 struct ath_arx_tid *rxtid;
75 struct sk_buff *tskb;
76 struct ath_recv_status *rx_status;
77 int tidno, index, cindex;
78 u16 seqno;
79
80 /* look at BAR contents */
81
82 bar = (struct ieee80211_bar *)skb->data;
83 tidno = (le16_to_cpu(bar->control) & IEEE80211_BAR_CTL_TID_M)
84 >> IEEE80211_BAR_CTL_TID_S;
85 seqno = le16_to_cpu(bar->start_seq_num) >> IEEE80211_SEQ_SEQ_SHIFT;
86
87 /* process BAR - indicate all pending RX frames till the BAR seqno */
88
89 rxtid = &an->an_aggr.rx.tid[tidno];
90
91 spin_lock_bh(&rxtid->tidlock);
92
93 /* get relative index */
94
95 index = ATH_BA_INDEX(rxtid->seq_next, seqno);
96
97 /* drop BAR if old sequence (index is too large) */
98
99 if ((index > rxtid->baw_size) &&
100 (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2))))
101 /* discard frame, ieee layer may not treat frame as a dup */
102 goto unlock_and_free;
103
104 /* complete receive processing for all pending frames upto BAR seqno */
105
106 cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
107 while ((rxtid->baw_head != rxtid->baw_tail) &&
108 (rxtid->baw_head != cindex)) {
109 tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf;
110 rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status;
111 rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL;
112
113 if (tskb != NULL)
114 ath_rx_subframe(an, tskb, rx_status);
115
116 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
117 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
118 }
119
120 /* ... and indicate rest of the frames in-order */
121
122 while (rxtid->baw_head != rxtid->baw_tail &&
123 rxtid->rxbuf[rxtid->baw_head].rx_wbuf != NULL) {
124 tskb = rxtid->rxbuf[rxtid->baw_head].rx_wbuf;
125 rx_status = &rxtid->rxbuf[rxtid->baw_head].rx_status;
126 rxtid->rxbuf[rxtid->baw_head].rx_wbuf = NULL;
127
128 ath_rx_subframe(an, tskb, rx_status);
129
130 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
131 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
132 }
133
134unlock_and_free:
135 spin_unlock_bh(&rxtid->tidlock);
136 /* free bar itself */
137 dev_kfree_skb(skb);
138 return IEEE80211_FTYPE_CTL;
139}
140
141/* Function to handle a subframe of aggregation when HT is enabled */
142
143static int ath_ampdu_input(struct ath_softc *sc,
144 struct ath_node *an,
145 struct sk_buff *skb,
146 struct ath_recv_status *rx_status)
147{
148 struct ieee80211_hdr *hdr;
149 struct ath_arx_tid *rxtid;
150 struct ath_rxbuf *rxbuf;
151 u8 type, subtype;
152 u16 rxseq;
153 int tid = 0, index, cindex, rxdiff;
154 __le16 fc;
155 u8 *qc;
156
157 hdr = (struct ieee80211_hdr *)skb->data;
158 fc = hdr->frame_control;
159
160 /* collect stats of frames with non-zero version */
161
162 if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_VERS) != 0) {
163 dev_kfree_skb(skb);
164 return -1;
165 }
166
167 type = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_FTYPE;
168 subtype = le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_STYPE;
169
170 if (ieee80211_is_back_req(fc))
171 return ath_bar_rx(sc, an, skb);
172
173 /* special aggregate processing only for qos unicast data frames */
174
175 if (!ieee80211_is_data(fc) ||
176 !ieee80211_is_data_qos(fc) ||
177 is_multicast_ether_addr(hdr->addr1))
178 return ath_rx_subframe(an, skb, rx_status);
179
180 /* lookup rx tid state */
181
182 if (ieee80211_is_data_qos(fc)) {
183 qc = ieee80211_get_qos_ctl(hdr);
184 tid = qc[0] & 0xf;
185 }
186
187 if (sc->sc_opmode == ATH9K_M_STA) {
188 /* Drop the frame not belonging to me. */
189 if (memcmp(hdr->addr1, sc->sc_myaddr, ETH_ALEN)) {
190 dev_kfree_skb(skb);
191 return -1;
192 }
193 }
194
195 rxtid = &an->an_aggr.rx.tid[tid];
196
197 spin_lock(&rxtid->tidlock);
198
199 rxdiff = (rxtid->baw_tail - rxtid->baw_head) &
200 (ATH_TID_MAX_BUFS - 1);
201
202 /*
203 * If the ADDBA exchange has not been completed by the source,
204 * process via legacy path (i.e. no reordering buffer is needed)
205 */
206 if (!rxtid->addba_exchangecomplete) {
207 spin_unlock(&rxtid->tidlock);
208 return ath_rx_subframe(an, skb, rx_status);
209 }
210
211 /* extract sequence number from recvd frame */
212
213 rxseq = le16_to_cpu(hdr->seq_ctrl) >> IEEE80211_SEQ_SEQ_SHIFT;
214
215 if (rxtid->seq_reset) {
216 rxtid->seq_reset = 0;
217 rxtid->seq_next = rxseq;
218 }
219
220 index = ATH_BA_INDEX(rxtid->seq_next, rxseq);
221
222 /* drop frame if old sequence (index is too large) */
223
224 if (index > (IEEE80211_SEQ_MAX - (rxtid->baw_size << 2))) {
225 /* discard frame, ieee layer may not treat frame as a dup */
226 spin_unlock(&rxtid->tidlock);
227 dev_kfree_skb(skb);
228 return IEEE80211_FTYPE_DATA;
229 }
230
231 /* sequence number is beyond block-ack window */
232
233 if (index >= rxtid->baw_size) {
234
235 /* complete receive processing for all pending frames */
236
237 while (index >= rxtid->baw_size) {
238
239 rxbuf = rxtid->rxbuf + rxtid->baw_head;
240
241 if (rxbuf->rx_wbuf != NULL) {
242 ath_rx_subframe(an, rxbuf->rx_wbuf,
243 &rxbuf->rx_status);
244 rxbuf->rx_wbuf = NULL;
245 }
246
247 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
248 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
249
250 index--;
251 }
252 }
253
254 /* add buffer to the recv ba window */
255
256 cindex = (rxtid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
257 rxbuf = rxtid->rxbuf + cindex;
258
259 if (rxbuf->rx_wbuf != NULL) {
260 spin_unlock(&rxtid->tidlock);
261 /* duplicate frame */
262 dev_kfree_skb(skb);
263 return IEEE80211_FTYPE_DATA;
264 }
265
266 rxbuf->rx_wbuf = skb;
267 rxbuf->rx_time = get_timestamp();
268 rxbuf->rx_status = *rx_status;
269
270 /* advance tail if sequence received is newer
271 * than any received so far */
272
273 if (index >= rxdiff) {
274 rxtid->baw_tail = cindex;
275 INCR(rxtid->baw_tail, ATH_TID_MAX_BUFS);
276 }
277
278 /* indicate all in-order received frames */
279
280 while (rxtid->baw_head != rxtid->baw_tail) {
281 rxbuf = rxtid->rxbuf + rxtid->baw_head;
282 if (!rxbuf->rx_wbuf)
283 break;
284
285 ath_rx_subframe(an, rxbuf->rx_wbuf, &rxbuf->rx_status);
286 rxbuf->rx_wbuf = NULL;
287
288 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
289 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
290 }
291
292 /*
293 * start a timer to flush all received frames if there are pending
294 * receive frames
295 */
296 if (rxtid->baw_head != rxtid->baw_tail)
297 mod_timer(&rxtid->timer, ATH_RX_TIMEOUT);
298 else
299 del_timer_sync(&rxtid->timer);
300
301 spin_unlock(&rxtid->tidlock);
302 return IEEE80211_FTYPE_DATA;
303}
304
305/* Timer to flush all received sub-frames */
306
307static void ath_rx_timer(unsigned long data)
308{
309 struct ath_arx_tid *rxtid = (struct ath_arx_tid *)data;
310 struct ath_node *an = rxtid->an;
311 struct ath_rxbuf *rxbuf;
312 int nosched;
313
314 spin_lock_bh(&rxtid->tidlock);
315 while (rxtid->baw_head != rxtid->baw_tail) {
316 rxbuf = rxtid->rxbuf + rxtid->baw_head;
317 if (!rxbuf->rx_wbuf) {
318 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
319 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
320 continue;
321 }
322
323 /*
324 * Stop if the next one is a very recent frame.
325 *
326 * Call get_timestamp in every iteration to protect against the
327 * case in which a new frame is received while we are executing
328 * this function. Using a timestamp obtained before entering
329 * the loop could lead to a very large time interval
330 * (a negative value typecast to unsigned), breaking the
331 * function's logic.
332 */
333 if ((get_timestamp() - rxbuf->rx_time) <
334 (ATH_RX_TIMEOUT * HZ / 1000))
335 break;
336
337 ath_rx_subframe(an, rxbuf->rx_wbuf,
338 &rxbuf->rx_status);
339 rxbuf->rx_wbuf = NULL;
340
341 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
342 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
343 }
344
345 /*
346 * start a timer to flush all received frames if there are pending
347 * receive frames
348 */
349 if (rxtid->baw_head != rxtid->baw_tail)
350 nosched = 0;
351 else
352 nosched = 1; /* no need to re-arm the timer again */
353
354 spin_unlock_bh(&rxtid->tidlock);
355}
356
357/* Free all pending sub-frames in the re-ordering buffer */
358
359static void ath_rx_flush_tid(struct ath_softc *sc,
360 struct ath_arx_tid *rxtid, int drop)
361{
362 struct ath_rxbuf *rxbuf;
363
364 spin_lock_bh(&rxtid->tidlock);
365 while (rxtid->baw_head != rxtid->baw_tail) {
366 rxbuf = rxtid->rxbuf + rxtid->baw_head;
367 if (!rxbuf->rx_wbuf) {
368 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
369 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
370 continue;
371 }
372
373 if (drop)
374 dev_kfree_skb(rxbuf->rx_wbuf);
375 else
376 ath_rx_subframe(rxtid->an,
377 rxbuf->rx_wbuf,
378 &rxbuf->rx_status);
379
380 rxbuf->rx_wbuf = NULL;
381
382 INCR(rxtid->baw_head, ATH_TID_MAX_BUFS);
383 INCR(rxtid->seq_next, IEEE80211_SEQ_MAX);
384 }
385 spin_unlock_bh(&rxtid->tidlock);
386}
387
388static struct sk_buff *ath_rxbuf_alloc(struct ath_softc *sc,
389 u32 len)
390{
391 struct sk_buff *skb;
392 u32 off;
393
394 /*
395 * Cache-line-align. This is important (for the
396 * 5210 at least) as not doing so causes bogus data
397 * in rx'd frames.
398 */
399
400 skb = dev_alloc_skb(len + sc->sc_cachelsz - 1);
401 if (skb != NULL) {
402 off = ((unsigned long) skb->data) % sc->sc_cachelsz;
403 if (off != 0)
404 skb_reserve(skb, sc->sc_cachelsz - off);
405 } else {
406 DPRINTF(sc, ATH_DBG_FATAL,
407 "%s: skbuff alloc of size %u failed\n",
408 __func__, len);
409 return NULL;
410 }
411
412 return skb;
413}
414
415static void ath_rx_requeue(struct ath_softc *sc, struct sk_buff *skb)
416{
417 struct ath_buf *bf = ATH_RX_CONTEXT(skb)->ctx_rxbuf;
418
419 ASSERT(bf != NULL);
420
421 spin_lock_bh(&sc->sc_rxbuflock);
422 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
423 /*
424 * This buffer is still held for hw acess.
425 * Mark it as free to be re-queued it later.
426 */
427 bf->bf_status |= ATH_BUFSTATUS_FREE;
428 } else {
429 /* XXX: we probably never enter here, remove after
430 * verification */
431 list_add_tail(&bf->list, &sc->sc_rxbuf);
432 ath_rx_buf_link(sc, bf);
433 }
434 spin_unlock_bh(&sc->sc_rxbuflock);
435}
436
437/*
438 * The skb indicated to upper stack won't be returned to us.
439 * So we have to allocate a new one and queue it by ourselves.
440 */
441static int ath_rx_indicate(struct ath_softc *sc,
442 struct sk_buff *skb,
443 struct ath_recv_status *status,
444 u16 keyix)
445{
446 struct ath_buf *bf = ATH_RX_CONTEXT(skb)->ctx_rxbuf;
447 struct sk_buff *nskb;
448 int type;
449
450 /* indicate frame to the stack, which will free the old skb. */
451 type = ath__rx_indicate(sc, skb, status, keyix);
452
453 /* allocate a new skb and queue it to for H/W processing */
454 nskb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
455 if (nskb != NULL) {
456 bf->bf_mpdu = nskb;
457 bf->bf_buf_addr = ath_skb_map_single(sc,
458 nskb,
459 PCI_DMA_FROMDEVICE,
460 /* XXX: Remove get_dma_mem_context() */
461 get_dma_mem_context(bf, bf_dmacontext));
462 ATH_RX_CONTEXT(nskb)->ctx_rxbuf = bf;
463
464 /* queue the new wbuf to H/W */
465 ath_rx_requeue(sc, nskb);
466 }
467
468 return type;
469}
470
471static void ath_opmode_init(struct ath_softc *sc)
472{
473 struct ath_hal *ah = sc->sc_ah;
474 u32 rfilt, mfilt[2];
475
476 /* configure rx filter */
477 rfilt = ath_calcrxfilter(sc);
478 ath9k_hw_setrxfilter(ah, rfilt);
479
480 /* configure bssid mask */
481 if (ah->ah_caps.halBssIdMaskSupport)
482 ath9k_hw_setbssidmask(ah, sc->sc_bssidmask);
483
484 /* configure operational mode */
485 ath9k_hw_setopmode(ah);
486
487 /* Handle any link-level address change. */
488 ath9k_hw_setmac(ah, sc->sc_myaddr);
489
490 /* calculate and install multicast filter */
491 mfilt[0] = mfilt[1] = ~0;
492
493 ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
494 DPRINTF(sc, ATH_DBG_CONFIG ,
495 "%s: RX filter 0x%x, MC filter %08x:%08x\n",
496 __func__, rfilt, mfilt[0], mfilt[1]);
497}
498
499int ath_rx_init(struct ath_softc *sc, int nbufs)
500{
501 struct sk_buff *skb;
502 struct ath_buf *bf;
503 int error = 0;
504
505 do {
506 spin_lock_init(&sc->sc_rxflushlock);
507 sc->sc_rxflush = 0;
508 spin_lock_init(&sc->sc_rxbuflock);
509
510 /*
511 * Cisco's VPN software requires that drivers be able to
512 * receive encapsulated frames that are larger than the MTU.
513 * Since we can't be sure how large a frame we'll get, setup
514 * to handle the larges on possible.
515 */
516 sc->sc_rxbufsize = roundup(IEEE80211_MAX_MPDU_LEN,
517 min(sc->sc_cachelsz,
518 (u16)64));
519
520 DPRINTF(sc, ATH_DBG_CONFIG, "%s: cachelsz %u rxbufsize %u\n",
521 __func__, sc->sc_cachelsz, sc->sc_rxbufsize);
522
523 /* Initialize rx descriptors */
524
525 error = ath_descdma_setup(sc, &sc->sc_rxdma, &sc->sc_rxbuf,
526 "rx", nbufs, 1);
527 if (error != 0) {
528 DPRINTF(sc, ATH_DBG_FATAL,
529 "%s: failed to allocate rx descriptors: %d\n",
530 __func__, error);
531 break;
532 }
533
534 /* Pre-allocate a wbuf for each rx buffer */
535
536 list_for_each_entry(bf, &sc->sc_rxbuf, list) {
537 skb = ath_rxbuf_alloc(sc, sc->sc_rxbufsize);
538 if (skb == NULL) {
539 error = -ENOMEM;
540 break;
541 }
542
543 bf->bf_mpdu = skb;
544 bf->bf_buf_addr =
545 ath_skb_map_single(sc, skb, PCI_DMA_FROMDEVICE,
546 get_dma_mem_context(bf, bf_dmacontext));
547 ATH_RX_CONTEXT(skb)->ctx_rxbuf = bf;
548 }
549 sc->sc_rxlink = NULL;
550
551 } while (0);
552
553 if (error)
554 ath_rx_cleanup(sc);
555
556 return error;
557}
558
559/* Reclaim all rx queue resources */
560
561void ath_rx_cleanup(struct ath_softc *sc)
562{
563 struct sk_buff *skb;
564 struct ath_buf *bf;
565
566 list_for_each_entry(bf, &sc->sc_rxbuf, list) {
567 skb = bf->bf_mpdu;
568 if (skb)
569 dev_kfree_skb(skb);
570 }
571
572 /* cleanup rx descriptors */
573
574 if (sc->sc_rxdma.dd_desc_len != 0)
575 ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf);
576}
577
578/*
579 * Calculate the receive filter according to the
580 * operating mode and state:
581 *
582 * o always accept unicast, broadcast, and multicast traffic
583 * o maintain current state of phy error reception (the hal
584 * may enable phy error frames for noise immunity work)
585 * o probe request frames are accepted only when operating in
586 * hostap, adhoc, or monitor modes
587 * o enable promiscuous mode according to the interface state
588 * o accept beacons:
589 * - when operating in adhoc mode so the 802.11 layer creates
590 * node table entries for peers,
591 * - when operating in station mode for collecting rssi data when
592 * the station is otherwise quiet, or
593 * - when operating as a repeater so we see repeater-sta beacons
594 * - when scanning
595 */
596
597u32 ath_calcrxfilter(struct ath_softc *sc)
598{
599#define RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
600 u32 rfilt;
601
602 rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
603 | ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
604 | ATH9K_RX_FILTER_MCAST;
605
606 /* If not a STA, enable processing of Probe Requests */
607 if (sc->sc_opmode != ATH9K_M_STA)
608 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
609
610 /* Can't set HOSTAP into promiscous mode */
611 if (sc->sc_opmode == ATH9K_M_MONITOR) {
612 rfilt |= ATH9K_RX_FILTER_PROM;
613 /* ??? To prevent from sending ACK */
614 rfilt &= ~ATH9K_RX_FILTER_UCAST;
615 }
616
617 if (sc->sc_opmode == ATH9K_M_STA || sc->sc_opmode == ATH9K_M_IBSS ||
618 sc->sc_scanning)
619 rfilt |= ATH9K_RX_FILTER_BEACON;
620
621 /* If in HOSTAP mode, want to enable reception of PSPOLL frames
622 & beacon frames */
623 if (sc->sc_opmode == ATH9K_M_HOSTAP)
624 rfilt |= (ATH9K_RX_FILTER_BEACON | ATH9K_RX_FILTER_PSPOLL);
625 return rfilt;
626#undef RX_FILTER_PRESERVE
627}
628
629/* Enable the receive h/w following a reset. */
630
631int ath_startrecv(struct ath_softc *sc)
632{
633 struct ath_hal *ah = sc->sc_ah;
634 struct ath_buf *bf, *tbf;
635
636 spin_lock_bh(&sc->sc_rxbuflock);
637 if (list_empty(&sc->sc_rxbuf))
638 goto start_recv;
639
640 sc->sc_rxlink = NULL;
641 list_for_each_entry_safe(bf, tbf, &sc->sc_rxbuf, list) {
642 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
643 /* restarting h/w, no need for holding descriptors */
644 bf->bf_status &= ~ATH_BUFSTATUS_STALE;
645 /*
646 * Upper layer may not be done with the frame yet so
647 * we can't just re-queue it to hardware. Remove it
648 * from h/w queue. It'll be re-queued when upper layer
649 * returns the frame and ath_rx_requeue_mpdu is called.
650 */
651 if (!(bf->bf_status & ATH_BUFSTATUS_FREE)) {
652 list_del(&bf->list);
653 continue;
654 }
655 }
656 /* chain descriptors */
657 ath_rx_buf_link(sc, bf);
658 }
659
660 /* We could have deleted elements so the list may be empty now */
661 if (list_empty(&sc->sc_rxbuf))
662 goto start_recv;
663
664 bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);
665 ath9k_hw_putrxbuf(ah, bf->bf_daddr);
666 ath9k_hw_rxena(ah); /* enable recv descriptors */
667
668start_recv:
669 spin_unlock_bh(&sc->sc_rxbuflock);
670 ath_opmode_init(sc); /* set filters, etc. */
671 ath9k_hw_startpcureceive(ah); /* re-enable PCU/DMA engine */
672 return 0;
673}
674
675/* Disable the receive h/w in preparation for a reset. */
676
677bool ath_stoprecv(struct ath_softc *sc)
678{
679 struct ath_hal *ah = sc->sc_ah;
680 u64 tsf;
681 bool stopped;
682
683 ath9k_hw_stoppcurecv(ah); /* disable PCU */
684 ath9k_hw_setrxfilter(ah, 0); /* clear recv filter */
685 stopped = ath9k_hw_stopdmarecv(ah); /* disable DMA engine */
686 mdelay(3); /* 3ms is long enough for 1 frame */
687 tsf = ath9k_hw_gettsf64(ah);
688 sc->sc_rxlink = NULL; /* just in case */
689 return stopped;
690}
691
692/* Flush receive queue */
693
694void ath_flushrecv(struct ath_softc *sc)
695{
696 /*
697 * ath_rx_tasklet may be used to handle rx interrupt and flush receive
698 * queue at the same time. Use a lock to serialize the access of rx
699 * queue.
700 * ath_rx_tasklet cannot hold the spinlock while indicating packets.
701 * Instead, do not claim the spinlock but check for a flush in
702 * progress (see references to sc_rxflush)
703 */
704 spin_lock_bh(&sc->sc_rxflushlock);
705 sc->sc_rxflush = 1;
706
707 ath_rx_tasklet(sc, 1);
708
709 sc->sc_rxflush = 0;
710 spin_unlock_bh(&sc->sc_rxflushlock);
711}
712
713/* Process an individual frame */
714
715int ath_rx_input(struct ath_softc *sc,
716 struct ath_node *an,
717 int is_ampdu,
718 struct sk_buff *skb,
719 struct ath_recv_status *rx_status,
720 enum ATH_RX_TYPE *status)
721{
722 if (is_ampdu && sc->sc_rxaggr) {
723 *status = ATH_RX_CONSUMED;
724 return ath_ampdu_input(sc, an, skb, rx_status);
725 } else {
726 *status = ATH_RX_NON_CONSUMED;
727 return -1;
728 }
729}
730
731/* Process receive queue, as well as LED, etc. */
732
733int ath_rx_tasklet(struct ath_softc *sc, int flush)
734{
735#define PA2DESC(_sc, _pa) \
736 ((struct ath_desc *)((caddr_t)(_sc)->sc_rxdma.dd_desc + \
737 ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr)))
738
739 struct ath_buf *bf, *bf_held = NULL;
740 struct ath_desc *ds;
741 struct ieee80211_hdr *hdr;
742 struct sk_buff *skb = NULL;
743 struct ath_recv_status rx_status;
744 struct ath_hal *ah = sc->sc_ah;
745 int type, rx_processed = 0;
746 u32 phyerr;
747 u8 chainreset = 0;
748 int retval;
749 __le16 fc;
750
751 do {
752 /* If handling rx interrupt and flush is in progress => exit */
753 if (sc->sc_rxflush && (flush == 0))
754 break;
755
756 spin_lock_bh(&sc->sc_rxbuflock);
757 if (list_empty(&sc->sc_rxbuf)) {
758 sc->sc_rxlink = NULL;
759 spin_unlock_bh(&sc->sc_rxbuflock);
760 break;
761 }
762
763 bf = list_first_entry(&sc->sc_rxbuf, struct ath_buf, list);
764
765 /*
766 * There is a race condition that BH gets scheduled after sw
767 * writes RxE and before hw re-load the last descriptor to get
768 * the newly chained one. Software must keep the last DONE
769 * descriptor as a holding descriptor - software does so by
770 * marking it with the STALE flag.
771 */
772 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
773 bf_held = bf;
774 if (list_is_last(&bf_held->list, &sc->sc_rxbuf)) {
775 /*
776 * The holding descriptor is the last
777 * descriptor in queue. It's safe to
778 * remove the last holding descriptor
779 * in BH context.
780 */
781 list_del(&bf_held->list);
782 bf_held->bf_status &= ~ATH_BUFSTATUS_STALE;
783 sc->sc_rxlink = NULL;
784
785 if (bf_held->bf_status & ATH_BUFSTATUS_FREE) {
786 list_add_tail(&bf_held->list,
787 &sc->sc_rxbuf);
788 ath_rx_buf_link(sc, bf_held);
789 }
790 spin_unlock_bh(&sc->sc_rxbuflock);
791 break;
792 }
793 bf = list_entry(bf->list.next, struct ath_buf, list);
794 }
795
796 ds = bf->bf_desc;
797 ++rx_processed;
798
799 /*
800 * Must provide the virtual address of the current
801 * descriptor, the physical address, and the virtual
802 * address of the next descriptor in the h/w chain.
803 * This allows the HAL to look ahead to see if the
804 * hardware is done with a descriptor by checking the
805 * done bit in the following descriptor and the address
806 * of the current descriptor the DMA engine is working
807 * on. All this is necessary because of our use of
808 * a self-linked list to avoid rx overruns.
809 */
810 retval = ath9k_hw_rxprocdesc(ah,
811 ds,
812 bf->bf_daddr,
813 PA2DESC(sc, ds->ds_link),
814 0);
815 if (retval == -EINPROGRESS) {
816 struct ath_buf *tbf;
817 struct ath_desc *tds;
818
819 if (list_is_last(&bf->list, &sc->sc_rxbuf)) {
820 spin_unlock_bh(&sc->sc_rxbuflock);
821 break;
822 }
823
824 tbf = list_entry(bf->list.next, struct ath_buf, list);
825
826 /*
827 * On some hardware the descriptor status words could
828 * get corrupted, including the done bit. Because of
829 * this, check if the next descriptor's done bit is
830 * set or not.
831 *
832 * If the next descriptor's done bit is set, the current
833 * descriptor has been corrupted. Force s/w to discard
834 * this descriptor and continue...
835 */
836
837 tds = tbf->bf_desc;
838 retval = ath9k_hw_rxprocdesc(ah,
839 tds, tbf->bf_daddr,
840 PA2DESC(sc, tds->ds_link), 0);
841 if (retval == -EINPROGRESS) {
842 spin_unlock_bh(&sc->sc_rxbuflock);
843 break;
844 }
845 }
846
847 /* XXX: we do not support frames spanning
848 * multiple descriptors */
849 bf->bf_status |= ATH_BUFSTATUS_DONE;
850
851 skb = bf->bf_mpdu;
852 if (skb == NULL) { /* XXX ??? can this happen */
853 spin_unlock_bh(&sc->sc_rxbuflock);
854 continue;
855 }
856 /*
857 * Now we know it's a completed frame, we can indicate the
858 * frame. Remove the previous holding descriptor and leave
859 * this one in the queue as the new holding descriptor.
860 */
861 if (bf_held) {
862 list_del(&bf_held->list);
863 bf_held->bf_status &= ~ATH_BUFSTATUS_STALE;
864 if (bf_held->bf_status & ATH_BUFSTATUS_FREE) {
865 list_add_tail(&bf_held->list, &sc->sc_rxbuf);
866 /* try to requeue this descriptor */
867 ath_rx_buf_link(sc, bf_held);
868 }
869 }
870
871 bf->bf_status |= ATH_BUFSTATUS_STALE;
872 bf_held = bf;
873 /*
874 * Release the lock here in case ieee80211_input() return
875 * the frame immediately by calling ath_rx_mpdu_requeue().
876 */
877 spin_unlock_bh(&sc->sc_rxbuflock);
878
879 if (flush) {
880 /*
881 * If we're asked to flush receive queue, directly
882 * chain it back at the queue without processing it.
883 */
884 goto rx_next;
885 }
886
887 hdr = (struct ieee80211_hdr *)skb->data;
888 fc = hdr->frame_control;
889 memzero(&rx_status, sizeof(struct ath_recv_status));
890
891 if (ds->ds_rxstat.rs_more) {
892 /*
893 * Frame spans multiple descriptors; this
894 * cannot happen yet as we don't support
895 * jumbograms. If not in monitor mode,
896 * discard the frame.
897 */
898#ifndef ERROR_FRAMES
899 /*
900 * Enable this if you want to see
901 * error frames in Monitor mode.
902 */
903 if (sc->sc_opmode != ATH9K_M_MONITOR)
904 goto rx_next;
905#endif
906 /* fall thru for monitor mode handling... */
907 } else if (ds->ds_rxstat.rs_status != 0) {
908 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_CRC)
909 rx_status.flags |= ATH_RX_FCS_ERROR;
910 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_PHY) {
911 phyerr = ds->ds_rxstat.rs_phyerr & 0x1f;
912 goto rx_next;
913 }
914
915 if (ds->ds_rxstat.rs_status & ATH9K_RXERR_DECRYPT) {
916 /*
917 * Decrypt error. We only mark packet status
918 * here and always push up the frame up to let
919 * mac80211 handle the actual error case, be
920 * it no decryption key or real decryption
921 * error. This let us keep statistics there.
922 */
923 rx_status.flags |= ATH_RX_DECRYPT_ERROR;
924 } else if (ds->ds_rxstat.rs_status & ATH9K_RXERR_MIC) {
925 /*
926 * Demic error. We only mark frame status here
927 * and always push up the frame up to let
928 * mac80211 handle the actual error case. This
929 * let us keep statistics there. Hardware may
930 * post a false-positive MIC error.
931 */
932 if (ieee80211_is_ctl(fc))
933 /*
934 * Sometimes, we get invalid
935 * MIC failures on valid control frames.
936 * Remove these mic errors.
937 */
938 ds->ds_rxstat.rs_status &=
939 ~ATH9K_RXERR_MIC;
940 else
941 rx_status.flags |= ATH_RX_MIC_ERROR;
942 }
943 /*
944 * Reject error frames with the exception of
945 * decryption and MIC failures. For monitor mode,
946 * we also ignore the CRC error.
947 */
948 if (sc->sc_opmode == ATH9K_M_MONITOR) {
949 if (ds->ds_rxstat.rs_status &
950 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
951 ATH9K_RXERR_CRC))
952 goto rx_next;
953 } else {
954 if (ds->ds_rxstat.rs_status &
955 ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
956 goto rx_next;
957 }
958 }
959 }
960 /*
961 * The status portion of the descriptor could get corrupted.
962 */
963 if (sc->sc_rxbufsize < ds->ds_rxstat.rs_datalen)
964 goto rx_next;
965 /*
966 * Sync and unmap the frame. At this point we're
967 * committed to passing the sk_buff somewhere so
968 * clear buf_skb; this means a new sk_buff must be
969 * allocated when the rx descriptor is setup again
970 * to receive another frame.
971 */
972 skb_put(skb, ds->ds_rxstat.rs_datalen);
973 skb->protocol = cpu_to_be16(ETH_P_CONTROL);
974 rx_status.tsf = ath_extend_tsf(sc, ds->ds_rxstat.rs_tstamp);
975 rx_status.rateieee =
976 sc->sc_hwmap[ds->ds_rxstat.rs_rate].ieeerate;
977 rx_status.rateKbps =
978 sc->sc_hwmap[ds->ds_rxstat.rs_rate].rateKbps;
979 rx_status.ratecode = ds->ds_rxstat.rs_rate;
980
981 /* HT rate */
982 if (rx_status.ratecode & 0x80) {
983 /* TODO - add table to avoid division */
984 if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) {
985 rx_status.flags |= ATH_RX_40MHZ;
986 rx_status.rateKbps =
987 (rx_status.rateKbps * 27) / 13;
988 }
989 if (ds->ds_rxstat.rs_flags & ATH9K_RX_GI)
990 rx_status.rateKbps =
991 (rx_status.rateKbps * 10) / 9;
992 else
993 rx_status.flags |= ATH_RX_SHORT_GI;
994 }
995
996 /* sc->sc_noise_floor is only available when the station
997 attaches to an AP, so we use a default value
998 if we are not yet attached. */
999
1000 /* XXX we should use either sc->sc_noise_floor or
1001 * ath_hal_getChanNoise(ah, &sc->sc_curchan)
1002 * to calculate the noise floor.
1003 * However, the value returned by ath_hal_getChanNoise
1004 * seems to be incorrect (-31dBm on the last test),
1005 * so we will use a hard-coded value until we
1006 * figure out what is going on.
1007 */
1008 rx_status.abs_rssi =
1009 ds->ds_rxstat.rs_rssi + ATH_DEFAULT_NOISE_FLOOR;
1010
1011 pci_dma_sync_single_for_cpu(sc->pdev,
1012 bf->bf_buf_addr,
1013 skb_tailroom(skb),
1014 PCI_DMA_FROMDEVICE);
1015 pci_unmap_single(sc->pdev,
1016 bf->bf_buf_addr,
1017 sc->sc_rxbufsize,
1018 PCI_DMA_FROMDEVICE);
1019
1020 /* XXX: Ah! make me more readable, use a helper */
1021 if (ah->ah_caps.halHTSupport) {
1022 if (ds->ds_rxstat.rs_moreaggr == 0) {
1023 rx_status.rssictl[0] =
1024 ds->ds_rxstat.rs_rssi_ctl0;
1025 rx_status.rssictl[1] =
1026 ds->ds_rxstat.rs_rssi_ctl1;
1027 rx_status.rssictl[2] =
1028 ds->ds_rxstat.rs_rssi_ctl2;
1029 rx_status.rssi = ds->ds_rxstat.rs_rssi;
1030 if (ds->ds_rxstat.rs_flags & ATH9K_RX_2040) {
1031 rx_status.rssiextn[0] =
1032 ds->ds_rxstat.rs_rssi_ext0;
1033 rx_status.rssiextn[1] =
1034 ds->ds_rxstat.rs_rssi_ext1;
1035 rx_status.rssiextn[2] =
1036 ds->ds_rxstat.rs_rssi_ext2;
1037 rx_status.flags |=
1038 ATH_RX_RSSI_EXTN_VALID;
1039 }
1040 rx_status.flags |= ATH_RX_RSSI_VALID |
1041 ATH_RX_CHAIN_RSSI_VALID;
1042 }
1043 } else {
1044 /*
1045 * Need to insert the "combined" rssi into the
1046 * status structure for upper layer processing
1047 */
1048 rx_status.rssi = ds->ds_rxstat.rs_rssi;
1049 rx_status.flags |= ATH_RX_RSSI_VALID;
1050 }
1051
1052 /* Pass frames up to the stack. */
1053
1054 type = ath_rx_indicate(sc, skb,
1055 &rx_status, ds->ds_rxstat.rs_keyix);
1056
1057 /*
1058 * change the default rx antenna if rx diversity chooses the
1059 * other antenna 3 times in a row.
1060 */
1061 if (sc->sc_defant != ds->ds_rxstat.rs_antenna) {
1062 if (++sc->sc_rxotherant >= 3)
1063 ath_setdefantenna(sc,
1064 ds->ds_rxstat.rs_antenna);
1065 } else {
1066 sc->sc_rxotherant = 0;
1067 }
1068
1069#ifdef CONFIG_SLOW_ANT_DIV
1070 if ((rx_status.flags & ATH_RX_RSSI_VALID) &&
1071 ieee80211_is_beacon(fc)) {
1072 ath_slow_ant_div(&sc->sc_antdiv, hdr, &ds->ds_rxstat);
1073 }
1074#endif
1075 /*
1076 * For frames successfully indicated, the buffer will be
1077 * returned to us by upper layers by calling
1078 * ath_rx_mpdu_requeue, either synchronusly or asynchronously.
1079 * So we don't want to do it here in this loop.
1080 */
1081 continue;
1082
1083rx_next:
1084 bf->bf_status |= ATH_BUFSTATUS_FREE;
1085 } while (TRUE);
1086
1087 if (chainreset) {
1088 DPRINTF(sc, ATH_DBG_CONFIG,
1089 "%s: Reset rx chain mask. "
1090 "Do internal reset\n", __func__);
1091 ASSERT(flush == 0);
1092 ath_internal_reset(sc);
1093 }
1094
1095 return 0;
1096#undef PA2DESC
1097}
1098
1099/* Process ADDBA request in per-TID data structure */
1100
1101int ath_rx_aggr_start(struct ath_softc *sc,
1102 const u8 *addr,
1103 u16 tid,
1104 u16 *ssn)
1105{
1106 struct ath_arx_tid *rxtid;
1107 struct ath_node *an;
1108 struct ieee80211_hw *hw = sc->hw;
1109 struct ieee80211_supported_band *sband;
1110 u16 buffersize = 0;
1111
1112 spin_lock_bh(&sc->node_lock);
1113 an = ath_node_find(sc, (u8 *) addr);
1114 spin_unlock_bh(&sc->node_lock);
1115
1116 if (!an) {
1117 DPRINTF(sc, ATH_DBG_AGGR,
1118 "%s: Node not found to initialize RX aggregation\n",
1119 __func__);
1120 return -1;
1121 }
1122
1123 sband = hw->wiphy->bands[hw->conf.channel->band];
1124 buffersize = IEEE80211_MIN_AMPDU_BUF <<
1125 sband->ht_info.ampdu_factor; /* FIXME */
1126
1127 rxtid = &an->an_aggr.rx.tid[tid];
1128
1129 spin_lock_bh(&rxtid->tidlock);
1130 if (sc->sc_rxaggr) {
1131 /* Allow aggregation reception
1132 * Adjust rx BA window size. Peer might indicate a
1133 * zero buffer size for a _dont_care_ condition.
1134 */
1135 if (buffersize)
1136 rxtid->baw_size = min(buffersize, rxtid->baw_size);
1137
1138 /* set rx sequence number */
1139 rxtid->seq_next = *ssn;
1140
1141 /* Allocate the receive buffers for this TID */
1142 DPRINTF(sc, ATH_DBG_AGGR,
1143 "%s: Allcating rxbuffer for TID %d\n", __func__, tid);
1144
1145 if (rxtid->rxbuf == NULL) {
1146 /*
1147 * If the rxbuff is not NULL at this point, we *probably*
1148 * already allocated the buffer on a previous ADDBA,
1149 * and this is a subsequent ADDBA that got through.
1150 * Don't allocate, but use the value in the pointer,
1151 * we zero it out when we de-allocate.
1152 */
1153 rxtid->rxbuf = kmalloc(ATH_TID_MAX_BUFS *
1154 sizeof(struct ath_rxbuf), GFP_ATOMIC);
1155 }
1156 if (rxtid->rxbuf == NULL) {
1157 DPRINTF(sc, ATH_DBG_AGGR,
1158 "%s: Unable to allocate RX buffer, "
1159 "refusing ADDBA\n", __func__);
1160 } else {
1161 /* Ensure the memory is zeroed out (all internal
1162 * pointers are null) */
1163 memzero(rxtid->rxbuf, ATH_TID_MAX_BUFS *
1164 sizeof(struct ath_rxbuf));
1165 DPRINTF(sc, ATH_DBG_AGGR,
1166 "%s: Allocated @%p\n", __func__, rxtid->rxbuf);
1167
1168 /* Allow aggregation reception */
1169 rxtid->addba_exchangecomplete = 1;
1170 }
1171 }
1172 spin_unlock_bh(&rxtid->tidlock);
1173
1174 return 0;
1175}
1176
1177/* Process DELBA */
1178
1179int ath_rx_aggr_stop(struct ath_softc *sc,
1180 const u8 *addr,
1181 u16 tid)
1182{
1183 struct ath_node *an;
1184
1185 spin_lock_bh(&sc->node_lock);
1186 an = ath_node_find(sc, (u8 *) addr);
1187 spin_unlock_bh(&sc->node_lock);
1188
1189 if (!an) {
1190 DPRINTF(sc, ATH_DBG_AGGR,
1191 "%s: RX aggr stop for non-existent node\n", __func__);
1192 return -1;
1193 }
1194
1195 ath_rx_aggr_teardown(sc, an, tid);
1196 return 0;
1197}
1198
1199/* Rx aggregation tear down */
1200
1201void ath_rx_aggr_teardown(struct ath_softc *sc,
1202 struct ath_node *an, u8 tid)
1203{
1204 struct ath_arx_tid *rxtid = &an->an_aggr.rx.tid[tid];
1205
1206 if (!rxtid->addba_exchangecomplete)
1207 return;
1208
1209 del_timer_sync(&rxtid->timer);
1210 ath_rx_flush_tid(sc, rxtid, 0);
1211 rxtid->addba_exchangecomplete = 0;
1212
1213 /* De-allocate the receive buffer array allocated when addba started */
1214
1215 if (rxtid->rxbuf) {
1216 DPRINTF(sc, ATH_DBG_AGGR,
1217 "%s: Deallocating TID %d rxbuff @%p\n",
1218 __func__, tid, rxtid->rxbuf);
1219 kfree(rxtid->rxbuf);
1220
1221 /* Set pointer to null to avoid reuse*/
1222 rxtid->rxbuf = NULL;
1223 }
1224}
1225
1226/* Initialize per-node receive state */
1227
1228void ath_rx_node_init(struct ath_softc *sc, struct ath_node *an)
1229{
1230 if (sc->sc_rxaggr) {
1231 struct ath_arx_tid *rxtid;
1232 int tidno;
1233
1234 /* Init per tid rx state */
1235 for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno];
1236 tidno < WME_NUM_TID;
1237 tidno++, rxtid++) {
1238 rxtid->an = an;
1239 rxtid->seq_reset = 1;
1240 rxtid->seq_next = 0;
1241 rxtid->baw_size = WME_MAX_BA;
1242 rxtid->baw_head = rxtid->baw_tail = 0;
1243
1244 /*
1245 * Ensure the buffer pointer is null at this point
1246 * (needs to be allocated when addba is received)
1247 */
1248
1249 rxtid->rxbuf = NULL;
1250 setup_timer(&rxtid->timer, ath_rx_timer,
1251 (unsigned long)rxtid);
1252 spin_lock_init(&rxtid->tidlock);
1253
1254 /* ADDBA state */
1255 rxtid->addba_exchangecomplete = 0;
1256 }
1257 }
1258}
1259
1260void ath_rx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
1261{
1262 if (sc->sc_rxaggr) {
1263 struct ath_arx_tid *rxtid;
1264 int tidno, i;
1265
1266 /* Init per tid rx state */
1267 for (tidno = 0, rxtid = &an->an_aggr.rx.tid[tidno];
1268 tidno < WME_NUM_TID;
1269 tidno++, rxtid++) {
1270
1271 if (!rxtid->addba_exchangecomplete)
1272 continue;
1273
1274 /* must cancel timer first */
1275 del_timer_sync(&rxtid->timer);
1276
1277 /* drop any pending sub-frames */
1278 ath_rx_flush_tid(sc, rxtid, 1);
1279
1280 for (i = 0; i < ATH_TID_MAX_BUFS; i++)
1281 ASSERT(rxtid->rxbuf[i].rx_wbuf == NULL);
1282
1283 rxtid->addba_exchangecomplete = 0;
1284 }
1285 }
1286
1287}
1288
1289/* Cleanup per-node receive state */
1290
1291void ath_rx_node_free(struct ath_softc *sc, struct ath_node *an)
1292{
1293 ath_rx_node_cleanup(sc, an);
1294}
1295
1296dma_addr_t ath_skb_map_single(struct ath_softc *sc,
1297 struct sk_buff *skb,
1298 int direction,
1299 dma_addr_t *pa)
1300{
1301 /*
1302 * NB: do NOT use skb->len, which is 0 on initialization.
1303 * Use skb's entire data area instead.
1304 */
1305 *pa = pci_map_single(sc->pdev, skb->data,
1306 skb_end_pointer(skb) - skb->head, direction);
1307 return *pa;
1308}
1309
1310void ath_skb_unmap_single(struct ath_softc *sc,
1311 struct sk_buff *skb,
1312 int direction,
1313 dma_addr_t *pa)
1314{
1315 /* Unmap skb's entire data area */
1316 pci_unmap_single(sc->pdev, *pa,
1317 skb_end_pointer(skb) - skb->head, direction);
1318}
diff --git a/drivers/net/wireless/ath9k/reg.h b/drivers/net/wireless/ath9k/reg.h
new file mode 100644
index 000000000000..42b0890a4685
--- /dev/null
+++ b/drivers/net/wireless/ath9k/reg.h
@@ -0,0 +1,1385 @@
1/*
2 * Copyright (c) 2008 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#ifndef REG_H
18#define REG_H
19
20#define AR_CR 0x0008
21#define AR_CR_RXE 0x00000004
22#define AR_CR_RXD 0x00000020
23#define AR_CR_SWI 0x00000040
24
25#define AR_RXDP 0x000C
26
27#define AR_CFG 0x0014
28#define AR_CFG_SWTD 0x00000001
29#define AR_CFG_SWTB 0x00000002
30#define AR_CFG_SWRD 0x00000004
31#define AR_CFG_SWRB 0x00000008
32#define AR_CFG_SWRG 0x00000010
33#define AR_CFG_AP_ADHOC_INDICATION 0x00000020
34#define AR_CFG_PHOK 0x00000100
35#define AR_CFG_CLK_GATE_DIS 0x00000400
36#define AR_CFG_EEBS 0x00000200
37#define AR_CFG_PCI_MASTER_REQ_Q_THRESH 0x00060000
38#define AR_CFG_PCI_MASTER_REQ_Q_THRESH_S 17
39
40#define AR_MIRT 0x0020
41#define AR_MIRT_VAL 0x0000ffff
42#define AR_MIRT_VAL_S 16
43
44#define AR_IER 0x0024
45#define AR_IER_ENABLE 0x00000001
46#define AR_IER_DISABLE 0x00000000
47
48#define AR_TIMT 0x0028
49#define AR_TIMT_LAST 0x0000ffff
50#define AR_TIMT_LAST_S 0
51#define AR_TIMT_FIRST 0xffff0000
52#define AR_TIMT_FIRST_S 16
53
54#define AR_RIMT 0x002C
55#define AR_RIMT_LAST 0x0000ffff
56#define AR_RIMT_LAST_S 0
57#define AR_RIMT_FIRST 0xffff0000
58#define AR_RIMT_FIRST_S 16
59
60#define AR_DMASIZE_4B 0x00000000
61#define AR_DMASIZE_8B 0x00000001
62#define AR_DMASIZE_16B 0x00000002
63#define AR_DMASIZE_32B 0x00000003
64#define AR_DMASIZE_64B 0x00000004
65#define AR_DMASIZE_128B 0x00000005
66#define AR_DMASIZE_256B 0x00000006
67#define AR_DMASIZE_512B 0x00000007
68
69#define AR_TXCFG 0x0030
70#define AR_TXCFG_DMASZ_MASK 0x00000003
71#define AR_TXCFG_DMASZ_4B 0
72#define AR_TXCFG_DMASZ_8B 1
73#define AR_TXCFG_DMASZ_16B 2
74#define AR_TXCFG_DMASZ_32B 3
75#define AR_TXCFG_DMASZ_64B 4
76#define AR_TXCFG_DMASZ_128B 5
77#define AR_TXCFG_DMASZ_256B 6
78#define AR_TXCFG_DMASZ_512B 7
79#define AR_FTRIG 0x000003F0
80#define AR_FTRIG_S 4
81#define AR_FTRIG_IMMED 0x00000000
82#define AR_FTRIG_64B 0x00000010
83#define AR_FTRIG_128B 0x00000020
84#define AR_FTRIG_192B 0x00000030
85#define AR_FTRIG_256B 0x00000040
86#define AR_FTRIG_512B 0x00000080
87#define AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY 0x00000800
88
89#define AR_RXCFG 0x0034
90#define AR_RXCFG_CHIRP 0x00000008
91#define AR_RXCFG_ZLFDMA 0x00000010
92#define AR_RXCFG_DMASZ_MASK 0x00000007
93#define AR_RXCFG_DMASZ_4B 0
94#define AR_RXCFG_DMASZ_8B 1
95#define AR_RXCFG_DMASZ_16B 2
96#define AR_RXCFG_DMASZ_32B 3
97#define AR_RXCFG_DMASZ_64B 4
98#define AR_RXCFG_DMASZ_128B 5
99#define AR_RXCFG_DMASZ_256B 6
100#define AR_RXCFG_DMASZ_512B 7
101
102#define AR_MIBC 0x0040
103#define AR_MIBC_COW 0x00000001
104#define AR_MIBC_FMC 0x00000002
105#define AR_MIBC_CMC 0x00000004
106#define AR_MIBC_MCS 0x00000008
107
108#define AR_TOPS 0x0044
109#define AR_TOPS_MASK 0x0000FFFF
110
111#define AR_RXNPTO 0x0048
112#define AR_RXNPTO_MASK 0x000003FF
113
114#define AR_TXNPTO 0x004C
115#define AR_TXNPTO_MASK 0x000003FF
116#define AR_TXNPTO_QCU_MASK 0x000FFC00
117
118#define AR_RPGTO 0x0050
119#define AR_RPGTO_MASK 0x000003FF
120
121#define AR_RPCNT 0x0054
122#define AR_RPCNT_MASK 0x0000001F
123
124#define AR_MACMISC 0x0058
125#define AR_MACMISC_PCI_EXT_FORCE 0x00000010
126#define AR_MACMISC_DMA_OBS 0x000001E0
127#define AR_MACMISC_DMA_OBS_S 5
128#define AR_MACMISC_DMA_OBS_LINE_0 0
129#define AR_MACMISC_DMA_OBS_LINE_1 1
130#define AR_MACMISC_DMA_OBS_LINE_2 2
131#define AR_MACMISC_DMA_OBS_LINE_3 3
132#define AR_MACMISC_DMA_OBS_LINE_4 4
133#define AR_MACMISC_DMA_OBS_LINE_5 5
134#define AR_MACMISC_DMA_OBS_LINE_6 6
135#define AR_MACMISC_DMA_OBS_LINE_7 7
136#define AR_MACMISC_DMA_OBS_LINE_8 8
137#define AR_MACMISC_MISC_OBS 0x00000E00
138#define AR_MACMISC_MISC_OBS_S 9
139#define AR_MACMISC_MISC_OBS_BUS_LSB 0x00007000
140#define AR_MACMISC_MISC_OBS_BUS_LSB_S 12
141#define AR_MACMISC_MISC_OBS_BUS_MSB 0x00038000
142#define AR_MACMISC_MISC_OBS_BUS_MSB_S 15
143#define AR_MACMISC_MISC_OBS_BUS_1 1
144
145#define AR_GTXTO 0x0064
146#define AR_GTXTO_TIMEOUT_COUNTER 0x0000FFFF
147#define AR_GTXTO_TIMEOUT_LIMIT 0xFFFF0000
148#define AR_GTXTO_TIMEOUT_LIMIT_S 16
149
150#define AR_GTTM 0x0068
151#define AR_GTTM_USEC 0x00000001
152#define AR_GTTM_IGNORE_IDLE 0x00000002
153#define AR_GTTM_RESET_IDLE 0x00000004
154#define AR_GTTM_CST_USEC 0x00000008
155
156#define AR_CST 0x006C
157#define AR_CST_TIMEOUT_COUNTER 0x0000FFFF
158#define AR_CST_TIMEOUT_LIMIT 0xFFFF0000
159#define AR_CST_TIMEOUT_LIMIT_S 16
160
161#define AR_SREV_VERSION_9100 0x014
162
163#define AR_SREV_5416_V20_OR_LATER(_ah) \
164 (AR_SREV_9100((_ah)) || AR_SREV_5416_20_OR_LATER(_ah))
165#define AR_SREV_5416_V22_OR_LATER(_ah) \
166 (AR_SREV_9100((_ah)) || AR_SREV_5416_22_OR_LATER(_ah))
167
168#define AR_ISR 0x0080
169#define AR_ISR_RXOK 0x00000001
170#define AR_ISR_RXDESC 0x00000002
171#define AR_ISR_RXERR 0x00000004
172#define AR_ISR_RXNOPKT 0x00000008
173#define AR_ISR_RXEOL 0x00000010
174#define AR_ISR_RXORN 0x00000020
175#define AR_ISR_TXOK 0x00000040
176#define AR_ISR_TXDESC 0x00000080
177#define AR_ISR_TXERR 0x00000100
178#define AR_ISR_TXNOPKT 0x00000200
179#define AR_ISR_TXEOL 0x00000400
180#define AR_ISR_TXURN 0x00000800
181#define AR_ISR_MIB 0x00001000
182#define AR_ISR_SWI 0x00002000
183#define AR_ISR_RXPHY 0x00004000
184#define AR_ISR_RXKCM 0x00008000
185#define AR_ISR_SWBA 0x00010000
186#define AR_ISR_BRSSI 0x00020000
187#define AR_ISR_BMISS 0x00040000
188#define AR_ISR_BNR 0x00100000
189#define AR_ISR_RXCHIRP 0x00200000
190#define AR_ISR_BCNMISC 0x00800000
191#define AR_ISR_TIM 0x00800000
192#define AR_ISR_QCBROVF 0x02000000
193#define AR_ISR_QCBRURN 0x04000000
194#define AR_ISR_QTRIG 0x08000000
195#define AR_ISR_GENTMR 0x10000000
196
197#define AR_ISR_TXMINTR 0x00080000
198#define AR_ISR_RXMINTR 0x01000000
199#define AR_ISR_TXINTM 0x40000000
200#define AR_ISR_RXINTM 0x80000000
201
202#define AR_ISR_S0 0x0084
203#define AR_ISR_S0_QCU_TXOK 0x000003FF
204#define AR_ISR_S0_QCU_TXOK_S 0
205#define AR_ISR_S0_QCU_TXDESC 0x03FF0000
206#define AR_ISR_S0_QCU_TXDESC_S 16
207
208#define AR_ISR_S1 0x0088
209#define AR_ISR_S1_QCU_TXERR 0x000003FF
210#define AR_ISR_S1_QCU_TXERR_S 0
211#define AR_ISR_S1_QCU_TXEOL 0x03FF0000
212#define AR_ISR_S1_QCU_TXEOL_S 16
213
214#define AR_ISR_S2 0x008c
215#define AR_ISR_S2_QCU_TXURN 0x000003FF
216#define AR_ISR_S2_CST 0x00400000
217#define AR_ISR_S2_GTT 0x00800000
218#define AR_ISR_S2_TIM 0x01000000
219#define AR_ISR_S2_CABEND 0x02000000
220#define AR_ISR_S2_DTIMSYNC 0x04000000
221#define AR_ISR_S2_BCNTO 0x08000000
222#define AR_ISR_S2_CABTO 0x10000000
223#define AR_ISR_S2_DTIM 0x20000000
224#define AR_ISR_S2_TSFOOR 0x40000000
225#define AR_ISR_S2_TBTT_TIME 0x80000000
226
227#define AR_ISR_S3 0x0090
228#define AR_ISR_S3_QCU_QCBROVF 0x000003FF
229#define AR_ISR_S3_QCU_QCBRURN 0x03FF0000
230
231#define AR_ISR_S4 0x0094
232#define AR_ISR_S4_QCU_QTRIG 0x000003FF
233#define AR_ISR_S4_RESV0 0xFFFFFC00
234
235#define AR_ISR_S5 0x0098
236#define AR_ISR_S5_TIMER_TRIG 0x000000FF
237#define AR_ISR_S5_TIMER_THRESH 0x0007FE00
238#define AR_ISR_S5_TIM_TIMER 0x00000010
239#define AR_ISR_S5_DTIM_TIMER 0x00000020
240#define AR_ISR_S5_S 0x00d8
241#define AR_IMR_S5 0x00b8
242#define AR_IMR_S5_TIM_TIMER 0x00000010
243#define AR_IMR_S5_DTIM_TIMER 0x00000020
244
245
246#define AR_IMR 0x00a0
247#define AR_IMR_RXOK 0x00000001
248#define AR_IMR_RXDESC 0x00000002
249#define AR_IMR_RXERR 0x00000004
250#define AR_IMR_RXNOPKT 0x00000008
251#define AR_IMR_RXEOL 0x00000010
252#define AR_IMR_RXORN 0x00000020
253#define AR_IMR_TXOK 0x00000040
254#define AR_IMR_TXDESC 0x00000080
255#define AR_IMR_TXERR 0x00000100
256#define AR_IMR_TXNOPKT 0x00000200
257#define AR_IMR_TXEOL 0x00000400
258#define AR_IMR_TXURN 0x00000800
259#define AR_IMR_MIB 0x00001000
260#define AR_IMR_SWI 0x00002000
261#define AR_IMR_RXPHY 0x00004000
262#define AR_IMR_RXKCM 0x00008000
263#define AR_IMR_SWBA 0x00010000
264#define AR_IMR_BRSSI 0x00020000
265#define AR_IMR_BMISS 0x00040000
266#define AR_IMR_BNR 0x00100000
267#define AR_IMR_RXCHIRP 0x00200000
268#define AR_IMR_BCNMISC 0x00800000
269#define AR_IMR_TIM 0x00800000
270#define AR_IMR_QCBROVF 0x02000000
271#define AR_IMR_QCBRURN 0x04000000
272#define AR_IMR_QTRIG 0x08000000
273#define AR_IMR_GENTMR 0x10000000
274
275#define AR_IMR_TXMINTR 0x00080000
276#define AR_IMR_RXMINTR 0x01000000
277#define AR_IMR_TXINTM 0x40000000
278#define AR_IMR_RXINTM 0x80000000
279
280#define AR_IMR_S0 0x00a4
281#define AR_IMR_S0_QCU_TXOK 0x000003FF
282#define AR_IMR_S0_QCU_TXOK_S 0
283#define AR_IMR_S0_QCU_TXDESC 0x03FF0000
284#define AR_IMR_S0_QCU_TXDESC_S 16
285
286#define AR_IMR_S1 0x00a8
287#define AR_IMR_S1_QCU_TXERR 0x000003FF
288#define AR_IMR_S1_QCU_TXERR_S 0
289#define AR_IMR_S1_QCU_TXEOL 0x03FF0000
290#define AR_IMR_S1_QCU_TXEOL_S 16
291
292#define AR_IMR_S2 0x00ac
293#define AR_IMR_S2_QCU_TXURN 0x000003FF
294#define AR_IMR_S2_QCU_TXURN_S 0
295#define AR_IMR_S2_CST 0x00400000
296#define AR_IMR_S2_GTT 0x00800000
297#define AR_IMR_S2_TIM 0x01000000
298#define AR_IMR_S2_CABEND 0x02000000
299#define AR_IMR_S2_DTIMSYNC 0x04000000
300#define AR_IMR_S2_BCNTO 0x08000000
301#define AR_IMR_S2_CABTO 0x10000000
302#define AR_IMR_S2_DTIM 0x20000000
303#define AR_IMR_S2_TSFOOR 0x40000000
304
305#define AR_IMR_S3 0x00b0
306#define AR_IMR_S3_QCU_QCBROVF 0x000003FF
307#define AR_IMR_S3_QCU_QCBRURN 0x03FF0000
308#define AR_IMR_S3_QCU_QCBRURN_S 16
309
310#define AR_IMR_S4 0x00b4
311#define AR_IMR_S4_QCU_QTRIG 0x000003FF
312#define AR_IMR_S4_RESV0 0xFFFFFC00
313
314#define AR_IMR_S5 0x00b8
315#define AR_IMR_S5_TIMER_TRIG 0x000000FF
316#define AR_IMR_S5_TIMER_THRESH 0x0000FF00
317
318
319#define AR_ISR_RAC 0x00c0
320#define AR_ISR_S0_S 0x00c4
321#define AR_ISR_S0_QCU_TXOK 0x000003FF
322#define AR_ISR_S0_QCU_TXOK_S 0
323#define AR_ISR_S0_QCU_TXDESC 0x03FF0000
324#define AR_ISR_S0_QCU_TXDESC_S 16
325
326#define AR_ISR_S1_S 0x00c8
327#define AR_ISR_S1_QCU_TXERR 0x000003FF
328#define AR_ISR_S1_QCU_TXERR_S 0
329#define AR_ISR_S1_QCU_TXEOL 0x03FF0000
330#define AR_ISR_S1_QCU_TXEOL_S 16
331
332#define AR_ISR_S2_S 0x00cc
333#define AR_ISR_S3_S 0x00d0
334#define AR_ISR_S4_S 0x00d4
335#define AR_ISR_S5_S 0x00d8
336#define AR_DMADBG_0 0x00e0
337#define AR_DMADBG_1 0x00e4
338#define AR_DMADBG_2 0x00e8
339#define AR_DMADBG_3 0x00ec
340#define AR_DMADBG_4 0x00f0
341#define AR_DMADBG_5 0x00f4
342#define AR_DMADBG_6 0x00f8
343#define AR_DMADBG_7 0x00fc
344
345#define AR_NUM_QCU 10
346#define AR_QCU_0 0x0001
347#define AR_QCU_1 0x0002
348#define AR_QCU_2 0x0004
349#define AR_QCU_3 0x0008
350#define AR_QCU_4 0x0010
351#define AR_QCU_5 0x0020
352#define AR_QCU_6 0x0040
353#define AR_QCU_7 0x0080
354#define AR_QCU_8 0x0100
355#define AR_QCU_9 0x0200
356
357#define AR_Q0_TXDP 0x0800
358#define AR_Q1_TXDP 0x0804
359#define AR_Q2_TXDP 0x0808
360#define AR_Q3_TXDP 0x080c
361#define AR_Q4_TXDP 0x0810
362#define AR_Q5_TXDP 0x0814
363#define AR_Q6_TXDP 0x0818
364#define AR_Q7_TXDP 0x081c
365#define AR_Q8_TXDP 0x0820
366#define AR_Q9_TXDP 0x0824
367#define AR_QTXDP(_i) (AR_Q0_TXDP + ((_i)<<2))
368
369#define AR_Q_TXE 0x0840
370#define AR_Q_TXE_M 0x000003FF
371
372#define AR_Q_TXD 0x0880
373#define AR_Q_TXD_M 0x000003FF
374
375#define AR_Q0_CBRCFG 0x08c0
376#define AR_Q1_CBRCFG 0x08c4
377#define AR_Q2_CBRCFG 0x08c8
378#define AR_Q3_CBRCFG 0x08cc
379#define AR_Q4_CBRCFG 0x08d0
380#define AR_Q5_CBRCFG 0x08d4
381#define AR_Q6_CBRCFG 0x08d8
382#define AR_Q7_CBRCFG 0x08dc
383#define AR_Q8_CBRCFG 0x08e0
384#define AR_Q9_CBRCFG 0x08e4
385#define AR_QCBRCFG(_i) (AR_Q0_CBRCFG + ((_i)<<2))
386#define AR_Q_CBRCFG_INTERVAL 0x00FFFFFF
387#define AR_Q_CBRCFG_INTERVAL_S 0
388#define AR_Q_CBRCFG_OVF_THRESH 0xFF000000
389#define AR_Q_CBRCFG_OVF_THRESH_S 24
390
391#define AR_Q0_RDYTIMECFG 0x0900
392#define AR_Q1_RDYTIMECFG 0x0904
393#define AR_Q2_RDYTIMECFG 0x0908
394#define AR_Q3_RDYTIMECFG 0x090c
395#define AR_Q4_RDYTIMECFG 0x0910
396#define AR_Q5_RDYTIMECFG 0x0914
397#define AR_Q6_RDYTIMECFG 0x0918
398#define AR_Q7_RDYTIMECFG 0x091c
399#define AR_Q8_RDYTIMECFG 0x0920
400#define AR_Q9_RDYTIMECFG 0x0924
401#define AR_QRDYTIMECFG(_i) (AR_Q0_RDYTIMECFG + ((_i)<<2))
402#define AR_Q_RDYTIMECFG_DURATION 0x00FFFFFF
403#define AR_Q_RDYTIMECFG_DURATION_S 0
404#define AR_Q_RDYTIMECFG_EN 0x01000000
405
406#define AR_Q_ONESHOTARM_SC 0x0940
407#define AR_Q_ONESHOTARM_SC_M 0x000003FF
408#define AR_Q_ONESHOTARM_SC_RESV0 0xFFFFFC00
409
410#define AR_Q_ONESHOTARM_CC 0x0980
411#define AR_Q_ONESHOTARM_CC_M 0x000003FF
412#define AR_Q_ONESHOTARM_CC_RESV0 0xFFFFFC00
413
414#define AR_Q0_MISC 0x09c0
415#define AR_Q1_MISC 0x09c4
416#define AR_Q2_MISC 0x09c8
417#define AR_Q3_MISC 0x09cc
418#define AR_Q4_MISC 0x09d0
419#define AR_Q5_MISC 0x09d4
420#define AR_Q6_MISC 0x09d8
421#define AR_Q7_MISC 0x09dc
422#define AR_Q8_MISC 0x09e0
423#define AR_Q9_MISC 0x09e4
424#define AR_QMISC(_i) (AR_Q0_MISC + ((_i)<<2))
425#define AR_Q_MISC_FSP 0x0000000F
426#define AR_Q_MISC_FSP_ASAP 0
427#define AR_Q_MISC_FSP_CBR 1
428#define AR_Q_MISC_FSP_DBA_GATED 2
429#define AR_Q_MISC_FSP_TIM_GATED 3
430#define AR_Q_MISC_FSP_BEACON_SENT_GATED 4
431#define AR_Q_MISC_FSP_BEACON_RCVD_GATED 5
432#define AR_Q_MISC_ONE_SHOT_EN 0x00000010
433#define AR_Q_MISC_CBR_INCR_DIS1 0x00000020
434#define AR_Q_MISC_CBR_INCR_DIS0 0x00000040
435#define AR_Q_MISC_BEACON_USE 0x00000080
436#define AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN 0x00000100
437#define AR_Q_MISC_RDYTIME_EXP_POLICY 0x00000200
438#define AR_Q_MISC_RESET_CBR_EXP_CTR 0x00000400
439#define AR_Q_MISC_DCU_EARLY_TERM_REQ 0x00000800
440#define AR_Q_MISC_RESV0 0xFFFFF000
441
442#define AR_Q0_STS 0x0a00
443#define AR_Q1_STS 0x0a04
444#define AR_Q2_STS 0x0a08
445#define AR_Q3_STS 0x0a0c
446#define AR_Q4_STS 0x0a10
447#define AR_Q5_STS 0x0a14
448#define AR_Q6_STS 0x0a18
449#define AR_Q7_STS 0x0a1c
450#define AR_Q8_STS 0x0a20
451#define AR_Q9_STS 0x0a24
452#define AR_QSTS(_i) (AR_Q0_STS + ((_i)<<2))
453#define AR_Q_STS_PEND_FR_CNT 0x00000003
454#define AR_Q_STS_RESV0 0x000000FC
455#define AR_Q_STS_CBR_EXP_CNT 0x0000FF00
456#define AR_Q_STS_RESV1 0xFFFF0000
457
458#define AR_Q_RDYTIMESHDN 0x0a40
459#define AR_Q_RDYTIMESHDN_M 0x000003FF
460
461
462#define AR_NUM_DCU 10
463#define AR_DCU_0 0x0001
464#define AR_DCU_1 0x0002
465#define AR_DCU_2 0x0004
466#define AR_DCU_3 0x0008
467#define AR_DCU_4 0x0010
468#define AR_DCU_5 0x0020
469#define AR_DCU_6 0x0040
470#define AR_DCU_7 0x0080
471#define AR_DCU_8 0x0100
472#define AR_DCU_9 0x0200
473
474#define AR_D0_QCUMASK 0x1000
475#define AR_D1_QCUMASK 0x1004
476#define AR_D2_QCUMASK 0x1008
477#define AR_D3_QCUMASK 0x100c
478#define AR_D4_QCUMASK 0x1010
479#define AR_D5_QCUMASK 0x1014
480#define AR_D6_QCUMASK 0x1018
481#define AR_D7_QCUMASK 0x101c
482#define AR_D8_QCUMASK 0x1020
483#define AR_D9_QCUMASK 0x1024
484#define AR_DQCUMASK(_i) (AR_D0_QCUMASK + ((_i)<<2))
485#define AR_D_QCUMASK 0x000003FF
486#define AR_D_QCUMASK_RESV0 0xFFFFFC00
487
488#define AR_D_TXBLK_CMD 0x1038
489#define AR_D_TXBLK_DATA(i) (AR_D_TXBLK_CMD+(i))
490
491#define AR_D0_LCL_IFS 0x1040
492#define AR_D1_LCL_IFS 0x1044
493#define AR_D2_LCL_IFS 0x1048
494#define AR_D3_LCL_IFS 0x104c
495#define AR_D4_LCL_IFS 0x1050
496#define AR_D5_LCL_IFS 0x1054
497#define AR_D6_LCL_IFS 0x1058
498#define AR_D7_LCL_IFS 0x105c
499#define AR_D8_LCL_IFS 0x1060
500#define AR_D9_LCL_IFS 0x1064
501#define AR_DLCL_IFS(_i) (AR_D0_LCL_IFS + ((_i)<<2))
502#define AR_D_LCL_IFS_CWMIN 0x000003FF
503#define AR_D_LCL_IFS_CWMIN_S 0
504#define AR_D_LCL_IFS_CWMAX 0x000FFC00
505#define AR_D_LCL_IFS_CWMAX_S 10
506#define AR_D_LCL_IFS_AIFS 0x0FF00000
507#define AR_D_LCL_IFS_AIFS_S 20
508
509#define AR_D_LCL_IFS_RESV0 0xF0000000
510
511#define AR_D0_RETRY_LIMIT 0x1080
512#define AR_D1_RETRY_LIMIT 0x1084
513#define AR_D2_RETRY_LIMIT 0x1088
514#define AR_D3_RETRY_LIMIT 0x108c
515#define AR_D4_RETRY_LIMIT 0x1090
516#define AR_D5_RETRY_LIMIT 0x1094
517#define AR_D6_RETRY_LIMIT 0x1098
518#define AR_D7_RETRY_LIMIT 0x109c
519#define AR_D8_RETRY_LIMIT 0x10a0
520#define AR_D9_RETRY_LIMIT 0x10a4
521#define AR_DRETRY_LIMIT(_i) (AR_D0_RETRY_LIMIT + ((_i)<<2))
522#define AR_D_RETRY_LIMIT_FR_SH 0x0000000F
523#define AR_D_RETRY_LIMIT_FR_SH_S 0
524#define AR_D_RETRY_LIMIT_STA_SH 0x00003F00
525#define AR_D_RETRY_LIMIT_STA_SH_S 8
526#define AR_D_RETRY_LIMIT_STA_LG 0x000FC000
527#define AR_D_RETRY_LIMIT_STA_LG_S 14
528#define AR_D_RETRY_LIMIT_RESV0 0xFFF00000
529
530#define AR_D0_CHNTIME 0x10c0
531#define AR_D1_CHNTIME 0x10c4
532#define AR_D2_CHNTIME 0x10c8
533#define AR_D3_CHNTIME 0x10cc
534#define AR_D4_CHNTIME 0x10d0
535#define AR_D5_CHNTIME 0x10d4
536#define AR_D6_CHNTIME 0x10d8
537#define AR_D7_CHNTIME 0x10dc
538#define AR_D8_CHNTIME 0x10e0
539#define AR_D9_CHNTIME 0x10e4
540#define AR_DCHNTIME(_i) (AR_D0_CHNTIME + ((_i)<<2))
541#define AR_D_CHNTIME_DUR 0x000FFFFF
542#define AR_D_CHNTIME_DUR_S 0
543#define AR_D_CHNTIME_EN 0x00100000
544#define AR_D_CHNTIME_RESV0 0xFFE00000
545
546#define AR_D0_MISC 0x1100
547#define AR_D1_MISC 0x1104
548#define AR_D2_MISC 0x1108
549#define AR_D3_MISC 0x110c
550#define AR_D4_MISC 0x1110
551#define AR_D5_MISC 0x1114
552#define AR_D6_MISC 0x1118
553#define AR_D7_MISC 0x111c
554#define AR_D8_MISC 0x1120
555#define AR_D9_MISC 0x1124
556#define AR_DMISC(_i) (AR_D0_MISC + ((_i)<<2))
557#define AR_D_MISC_BKOFF_THRESH 0x0000003F
558#define AR_D_MISC_RETRY_CNT_RESET_EN 0x00000040
559#define AR_D_MISC_CW_RESET_EN 0x00000080
560#define AR_D_MISC_FRAG_WAIT_EN 0x00000100
561#define AR_D_MISC_FRAG_BKOFF_EN 0x00000200
562#define AR_D_MISC_CW_BKOFF_EN 0x00001000
563#define AR_D_MISC_VIR_COL_HANDLING 0x0000C000
564#define AR_D_MISC_VIR_COL_HANDLING_S 14
565#define AR_D_MISC_VIR_COL_HANDLING_DEFAULT 0
566#define AR_D_MISC_VIR_COL_HANDLING_IGNORE 1
567#define AR_D_MISC_BEACON_USE 0x00010000
568#define AR_D_MISC_ARB_LOCKOUT_CNTRL 0x00060000
569#define AR_D_MISC_ARB_LOCKOUT_CNTRL_S 17
570#define AR_D_MISC_ARB_LOCKOUT_CNTRL_NONE 0
571#define AR_D_MISC_ARB_LOCKOUT_CNTRL_INTRA_FR 1
572#define AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL 2
573#define AR_D_MISC_ARB_LOCKOUT_IGNORE 0x00080000
574#define AR_D_MISC_SEQ_NUM_INCR_DIS 0x00100000
575#define AR_D_MISC_POST_FR_BKOFF_DIS 0x00200000
576#define AR_D_MISC_VIT_COL_CW_BKOFF_EN 0x00400000
577#define AR_D_MISC_BLOWN_IFS_RETRY_EN 0x00800000
578#define AR_D_MISC_RESV0 0xFF000000
579
580#define AR_D_SEQNUM 0x1140
581
582#define AR_D_GBL_IFS_SIFS 0x1030
583#define AR_D_GBL_IFS_SIFS_M 0x0000FFFF
584#define AR_D_GBL_IFS_SIFS_RESV0 0xFFFFFFFF
585
586#define AR_D_TXBLK_BASE 0x1038
587#define AR_D_TXBLK_WRITE_BITMASK 0x0000FFFF
588#define AR_D_TXBLK_WRITE_BITMASK_S 0
589#define AR_D_TXBLK_WRITE_SLICE 0x000F0000
590#define AR_D_TXBLK_WRITE_SLICE_S 16
591#define AR_D_TXBLK_WRITE_DCU 0x00F00000
592#define AR_D_TXBLK_WRITE_DCU_S 20
593#define AR_D_TXBLK_WRITE_COMMAND 0x0F000000
594#define AR_D_TXBLK_WRITE_COMMAND_S 24
595
596#define AR_D_GBL_IFS_SLOT 0x1070
597#define AR_D_GBL_IFS_SLOT_M 0x0000FFFF
598#define AR_D_GBL_IFS_SLOT_RESV0 0xFFFF0000
599
600#define AR_D_GBL_IFS_EIFS 0x10b0
601#define AR_D_GBL_IFS_EIFS_M 0x0000FFFF
602#define AR_D_GBL_IFS_EIFS_RESV0 0xFFFF0000
603
604#define AR_D_GBL_IFS_MISC 0x10f0
605#define AR_D_GBL_IFS_MISC_LFSR_SLICE_SEL 0x00000007
606#define AR_D_GBL_IFS_MISC_TURBO_MODE 0x00000008
607#define AR_D_GBL_IFS_MISC_USEC_DURATION 0x000FFC00
608#define AR_D_GBL_IFS_MISC_DCU_ARBITER_DLY 0x00300000
609#define AR_D_GBL_IFS_MISC_RANDOM_LFSR_SLICE_DIS 0x01000000
610#define AR_D_GBL_IFS_MISC_SLOT_XMIT_WIND_LEN 0x06000000
611#define AR_D_GBL_IFS_MISC_FORCE_XMIT_SLOT_BOUND 0x08000000
612#define AR_D_GBL_IFS_MISC_IGNORE_BACKOFF 0x10000000
613
614#define AR_D_FPCTL 0x1230
615#define AR_D_FPCTL_DCU 0x0000000F
616#define AR_D_FPCTL_DCU_S 0
617#define AR_D_FPCTL_PREFETCH_EN 0x00000010
618#define AR_D_FPCTL_BURST_PREFETCH 0x00007FE0
619#define AR_D_FPCTL_BURST_PREFETCH_S 5
620
621#define AR_D_TXPSE 0x1270
622#define AR_D_TXPSE_CTRL 0x000003FF
623#define AR_D_TXPSE_RESV0 0x0000FC00
624#define AR_D_TXPSE_STATUS 0x00010000
625#define AR_D_TXPSE_RESV1 0xFFFE0000
626
627#define AR_D_TXSLOTMASK 0x12f0
628#define AR_D_TXSLOTMASK_NUM 0x0000000F
629
630#define AR_CFG_LED 0x1f04
631#define AR_CFG_SCLK_RATE_IND 0x00000003
632#define AR_CFG_SCLK_RATE_IND_S 0
633#define AR_CFG_SCLK_32MHZ 0x00000000
634#define AR_CFG_SCLK_4MHZ 0x00000001
635#define AR_CFG_SCLK_1MHZ 0x00000002
636#define AR_CFG_SCLK_32KHZ 0x00000003
637#define AR_CFG_LED_BLINK_SLOW 0x00000008
638#define AR_CFG_LED_BLINK_THRESH_SEL 0x00000070
639#define AR_CFG_LED_MODE_SEL 0x00000380
640#define AR_CFG_LED_MODE_SEL_S 7
641#define AR_CFG_LED_POWER 0x00000280
642#define AR_CFG_LED_POWER_S 7
643#define AR_CFG_LED_NETWORK 0x00000300
644#define AR_CFG_LED_NETWORK_S 7
645#define AR_CFG_LED_MODE_PROP 0x0
646#define AR_CFG_LED_MODE_RPROP 0x1
647#define AR_CFG_LED_MODE_SPLIT 0x2
648#define AR_CFG_LED_MODE_RAND 0x3
649#define AR_CFG_LED_MODE_POWER_OFF 0x4
650#define AR_CFG_LED_MODE_POWER_ON 0x5
651#define AR_CFG_LED_MODE_NETWORK_OFF 0x4
652#define AR_CFG_LED_MODE_NETWORK_ON 0x6
653#define AR_CFG_LED_ASSOC_CTL 0x00000c00
654#define AR_CFG_LED_ASSOC_CTL_S 10
655#define AR_CFG_LED_ASSOC_NONE 0x0
656#define AR_CFG_LED_ASSOC_ACTIVE 0x1
657#define AR_CFG_LED_ASSOC_PENDING 0x2
658
659#define AR_CFG_LED_BLINK_SLOW 0x00000008
660#define AR_CFG_LED_BLINK_SLOW_S 3
661
662#define AR_CFG_LED_BLINK_THRESH_SEL 0x00000070
663#define AR_CFG_LED_BLINK_THRESH_SEL_S 4
664
665#define AR_MAC_SLEEP 0x1f00
666#define AR_MAC_SLEEP_MAC_AWAKE 0x00000000
667#define AR_MAC_SLEEP_MAC_ASLEEP 0x00000001
668
669#define AR_RC 0x4000
670#define AR_RC_AHB 0x00000001
671#define AR_RC_APB 0x00000002
672#define AR_RC_HOSTIF 0x00000100
673
674#define AR_WA 0x4004
675
676#define AR_PM_STATE 0x4008
677#define AR_PM_STATE_PME_D3COLD_VAUX 0x00100000
678
679#define AR_HOST_TIMEOUT 0x4018
680#define AR_HOST_TIMEOUT_APB_CNTR 0x0000FFFF
681#define AR_HOST_TIMEOUT_APB_CNTR_S 0
682#define AR_HOST_TIMEOUT_LCL_CNTR 0xFFFF0000
683#define AR_HOST_TIMEOUT_LCL_CNTR_S 16
684
685#define AR_EEPROM 0x401c
686#define AR_EEPROM_ABSENT 0x00000100
687#define AR_EEPROM_CORRUPT 0x00000200
688#define AR_EEPROM_PROT_MASK 0x03FFFC00
689#define AR_EEPROM_PROT_MASK_S 10
690
691#define EEPROM_PROTECT_RP_0_31 0x0001
692#define EEPROM_PROTECT_WP_0_31 0x0002
693#define EEPROM_PROTECT_RP_32_63 0x0004
694#define EEPROM_PROTECT_WP_32_63 0x0008
695#define EEPROM_PROTECT_RP_64_127 0x0010
696#define EEPROM_PROTECT_WP_64_127 0x0020
697#define EEPROM_PROTECT_RP_128_191 0x0040
698#define EEPROM_PROTECT_WP_128_191 0x0080
699#define EEPROM_PROTECT_RP_192_255 0x0100
700#define EEPROM_PROTECT_WP_192_255 0x0200
701#define EEPROM_PROTECT_RP_256_511 0x0400
702#define EEPROM_PROTECT_WP_256_511 0x0800
703#define EEPROM_PROTECT_RP_512_1023 0x1000
704#define EEPROM_PROTECT_WP_512_1023 0x2000
705#define EEPROM_PROTECT_RP_1024_2047 0x4000
706#define EEPROM_PROTECT_WP_1024_2047 0x8000
707
708#define AR_SREV \
709 ((AR_SREV_9100(ah)) ? 0x0600 : 0x4020)
710
711#define AR_SREV_ID \
712 ((AR_SREV_9100(ah)) ? 0x00000FFF : 0x000000FF)
713#define AR_SREV_VERSION 0x000000F0
714#define AR_SREV_VERSION_S 4
715#define AR_SREV_REVISION 0x00000007
716
717#define AR_SREV_ID2 0xFFFFFFFF
718#define AR_SREV_VERSION2 0xFFFC0000
719#define AR_SREV_VERSION2_S 18
720#define AR_SREV_TYPE2 0x0003F000
721#define AR_SREV_TYPE2_S 12
722#define AR_SREV_TYPE2_CHAIN 0x00001000
723#define AR_SREV_TYPE2_HOST_MODE 0x00002000
724#define AR_SREV_REVISION2 0x00000F00
725#define AR_SREV_REVISION2_S 8
726
727#define AR_SREV_VERSION_5416_PCI 0xD
728#define AR_SREV_VERSION_5416_PCIE 0xC
729#define AR_SREV_REVISION_5416_10 0
730#define AR_SREV_REVISION_5416_20 1
731#define AR_SREV_REVISION_5416_22 2
732#define AR_SREV_VERSION_9160 0x40
733#define AR_SREV_REVISION_9160_10 0
734#define AR_SREV_REVISION_9160_11 1
735#define AR_SREV_VERSION_9280 0x80
736#define AR_SREV_REVISION_9280_10 0
737#define AR_SREV_REVISION_9280_20 1
738#define AR_SREV_REVISION_9280_21 2
739#define AR_SREV_VERSION_9285 0xC0
740#define AR_SREV_REVISION_9285_10 0
741
742#define AR_SREV_9100_OR_LATER(_ah) \
743 (((_ah)->ah_macVersion >= AR_SREV_VERSION_5416_PCIE))
744#define AR_SREV_5416_20_OR_LATER(_ah) \
745 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
746 ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_20))
747#define AR_SREV_5416_22_OR_LATER(_ah) \
748 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160) || \
749 ((_ah)->ah_macRev >= AR_SREV_REVISION_5416_22))
750#define AR_SREV_9160(_ah) \
751 (((_ah)->ah_macVersion == AR_SREV_VERSION_9160))
752#define AR_SREV_9160_10_OR_LATER(_ah) \
753 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9160))
754#define AR_SREV_9160_11(_ah) \
755 (AR_SREV_9160(_ah) && ((_ah)->ah_macRev == AR_SREV_REVISION_9160_11))
756#define AR_SREV_9280(_ah) \
757 (((_ah)->ah_macVersion == AR_SREV_VERSION_9280))
758#define AR_SREV_9280_10_OR_LATER(_ah) \
759 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9280))
760#define AR_SREV_9280_20(_ah) \
761 (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
762 ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20))
763#define AR_SREV_9280_20_OR_LATER(_ah) \
764 (((_ah)->ah_macVersion > AR_SREV_VERSION_9280) || \
765 (((_ah)->ah_macVersion == AR_SREV_VERSION_9280) && \
766 ((_ah)->ah_macRev >= AR_SREV_REVISION_9280_20)))
767
768#define AR_SREV_9285(_ah) (((_ah)->ah_macVersion == AR_SREV_VERSION_9285))
769#define AR_SREV_9285_10_OR_LATER(_ah) \
770 (((_ah)->ah_macVersion >= AR_SREV_VERSION_9285))
771
772#define AR_RADIO_SREV_MAJOR 0xf0
773#define AR_RAD5133_SREV_MAJOR 0xc0
774#define AR_RAD2133_SREV_MAJOR 0xd0
775#define AR_RAD5122_SREV_MAJOR 0xe0
776#define AR_RAD2122_SREV_MAJOR 0xf0
777
778#define AR_AHB_MODE 0x4024
779#define AR_AHB_EXACT_WR_EN 0x00000000
780#define AR_AHB_BUF_WR_EN 0x00000001
781#define AR_AHB_EXACT_RD_EN 0x00000000
782#define AR_AHB_CACHELINE_RD_EN 0x00000002
783#define AR_AHB_PREFETCH_RD_EN 0x00000004
784#define AR_AHB_PAGE_SIZE_1K 0x00000000
785#define AR_AHB_PAGE_SIZE_2K 0x00000008
786#define AR_AHB_PAGE_SIZE_4K 0x00000010
787
788#define AR_INTR_RTC_IRQ 0x00000001
789#define AR_INTR_MAC_IRQ 0x00000002
790#define AR_INTR_EEP_PROT_ACCESS 0x00000004
791#define AR_INTR_MAC_AWAKE 0x00020000
792#define AR_INTR_MAC_ASLEEP 0x00040000
793#define AR_INTR_SPURIOUS 0xFFFFFFFF
794
795
796#define AR_INTR_SYNC_CAUSE_CLR 0x4028
797
798#define AR_INTR_SYNC_CAUSE 0x4028
799
800#define AR_INTR_SYNC_ENABLE 0x402c
801#define AR_INTR_SYNC_ENABLE_GPIO 0xFFFC0000
802#define AR_INTR_SYNC_ENABLE_GPIO_S 18
803
804enum {
805 AR_INTR_SYNC_RTC_IRQ = 0x00000001,
806 AR_INTR_SYNC_MAC_IRQ = 0x00000002,
807 AR_INTR_SYNC_EEPROM_ILLEGAL_ACCESS = 0x00000004,
808 AR_INTR_SYNC_APB_TIMEOUT = 0x00000008,
809 AR_INTR_SYNC_PCI_MODE_CONFLICT = 0x00000010,
810 AR_INTR_SYNC_HOST1_FATAL = 0x00000020,
811 AR_INTR_SYNC_HOST1_PERR = 0x00000040,
812 AR_INTR_SYNC_TRCV_FIFO_PERR = 0x00000080,
813 AR_INTR_SYNC_RADM_CPL_EP = 0x00000100,
814 AR_INTR_SYNC_RADM_CPL_DLLP_ABORT = 0x00000200,
815 AR_INTR_SYNC_RADM_CPL_TLP_ABORT = 0x00000400,
816 AR_INTR_SYNC_RADM_CPL_ECRC_ERR = 0x00000800,
817 AR_INTR_SYNC_RADM_CPL_TIMEOUT = 0x00001000,
818 AR_INTR_SYNC_LOCAL_TIMEOUT = 0x00002000,
819 AR_INTR_SYNC_PM_ACCESS = 0x00004000,
820 AR_INTR_SYNC_MAC_AWAKE = 0x00008000,
821 AR_INTR_SYNC_MAC_ASLEEP = 0x00010000,
822 AR_INTR_SYNC_MAC_SLEEP_ACCESS = 0x00020000,
823 AR_INTR_SYNC_ALL = 0x0003FFFF,
824
825
826 AR_INTR_SYNC_DEFAULT = (AR_INTR_SYNC_HOST1_FATAL |
827 AR_INTR_SYNC_HOST1_PERR |
828 AR_INTR_SYNC_RADM_CPL_EP |
829 AR_INTR_SYNC_RADM_CPL_DLLP_ABORT |
830 AR_INTR_SYNC_RADM_CPL_TLP_ABORT |
831 AR_INTR_SYNC_RADM_CPL_ECRC_ERR |
832 AR_INTR_SYNC_RADM_CPL_TIMEOUT |
833 AR_INTR_SYNC_LOCAL_TIMEOUT |
834 AR_INTR_SYNC_MAC_SLEEP_ACCESS),
835
836 AR_INTR_SYNC_SPURIOUS = 0xFFFFFFFF,
837
838};
839
840#define AR_INTR_ASYNC_MASK 0x4030
841#define AR_INTR_ASYNC_MASK_GPIO 0xFFFC0000
842#define AR_INTR_ASYNC_MASK_GPIO_S 18
843
844#define AR_INTR_SYNC_MASK 0x4034
845#define AR_INTR_SYNC_MASK_GPIO 0xFFFC0000
846#define AR_INTR_SYNC_MASK_GPIO_S 18
847
848#define AR_INTR_ASYNC_CAUSE_CLR 0x4038
849#define AR_INTR_ASYNC_CAUSE 0x4038
850
851#define AR_INTR_ASYNC_ENABLE 0x403c
852#define AR_INTR_ASYNC_ENABLE_GPIO 0xFFFC0000
853#define AR_INTR_ASYNC_ENABLE_GPIO_S 18
854
855#define AR_PCIE_SERDES 0x4040
856#define AR_PCIE_SERDES2 0x4044
857#define AR_PCIE_PM_CTRL 0x4014
858#define AR_PCIE_PM_CTRL_ENA 0x00080000
859
860#define AR_NUM_GPIO 14
861#define AR928X_NUM_GPIO 10
862
863#define AR_GPIO_IN_OUT 0x4048
864#define AR_GPIO_IN_VAL 0x0FFFC000
865#define AR_GPIO_IN_VAL_S 14
866#define AR928X_GPIO_IN_VAL 0x000FFC00
867#define AR928X_GPIO_IN_VAL_S 10
868
869#define AR_GPIO_OE_OUT 0x404c
870#define AR_GPIO_OE_OUT_DRV 0x3
871#define AR_GPIO_OE_OUT_DRV_NO 0x0
872#define AR_GPIO_OE_OUT_DRV_LOW 0x1
873#define AR_GPIO_OE_OUT_DRV_HI 0x2
874#define AR_GPIO_OE_OUT_DRV_ALL 0x3
875
876#define AR_GPIO_INTR_POL 0x4050
877#define AR_GPIO_INTR_POL_VAL 0x00001FFF
878#define AR_GPIO_INTR_POL_VAL_S 0
879
880#define AR_GPIO_INPUT_EN_VAL 0x4054
881#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF 0x00000080
882#define AR_GPIO_INPUT_EN_VAL_RFSILENT_DEF_S 7
883#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB 0x00008000
884#define AR_GPIO_INPUT_EN_VAL_RFSILENT_BB_S 15
885#define AR_GPIO_RTC_RESET_OVERRIDE_ENABLE 0x00010000
886#define AR_GPIO_JTAG_DISABLE 0x00020000
887
888#define AR_GPIO_INPUT_MUX1 0x4058
889
890#define AR_GPIO_INPUT_MUX2 0x405c
891#define AR_GPIO_INPUT_MUX2_CLK25 0x0000000f
892#define AR_GPIO_INPUT_MUX2_CLK25_S 0
893#define AR_GPIO_INPUT_MUX2_RFSILENT 0x000000f0
894#define AR_GPIO_INPUT_MUX2_RFSILENT_S 4
895#define AR_GPIO_INPUT_MUX2_RTC_RESET 0x00000f00
896#define AR_GPIO_INPUT_MUX2_RTC_RESET_S 8
897
898#define AR_GPIO_OUTPUT_MUX1 0x4060
899#define AR_GPIO_OUTPUT_MUX2 0x4064
900#define AR_GPIO_OUTPUT_MUX3 0x4068
901
902#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
903#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
904#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED 2
905#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED 5
906#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED 6
907
908#define AR_INPUT_STATE 0x406c
909
910#define AR_EEPROM_STATUS_DATA 0x407c
911#define AR_EEPROM_STATUS_DATA_VAL 0x0000ffff
912#define AR_EEPROM_STATUS_DATA_VAL_S 0
913#define AR_EEPROM_STATUS_DATA_BUSY 0x00010000
914#define AR_EEPROM_STATUS_DATA_BUSY_ACCESS 0x00020000
915#define AR_EEPROM_STATUS_DATA_PROT_ACCESS 0x00040000
916#define AR_EEPROM_STATUS_DATA_ABSENT_ACCESS 0x00080000
917
918#define AR_OBS 0x4080
919
920#define AR_PCIE_MSI 0x4094
921#define AR_PCIE_MSI_ENABLE 0x00000001
922
923
924#define AR_RTC_9160_PLL_DIV 0x000003ff
925#define AR_RTC_9160_PLL_DIV_S 0
926#define AR_RTC_9160_PLL_REFDIV 0x00003C00
927#define AR_RTC_9160_PLL_REFDIV_S 10
928#define AR_RTC_9160_PLL_CLKSEL 0x0000C000
929#define AR_RTC_9160_PLL_CLKSEL_S 14
930
931#define AR_RTC_BASE 0x00020000
932#define AR_RTC_RC \
933 (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0000) : 0x7000
934#define AR_RTC_RC_M 0x00000003
935#define AR_RTC_RC_MAC_WARM 0x00000001
936#define AR_RTC_RC_MAC_COLD 0x00000002
937#define AR_RTC_RC_COLD_RESET 0x00000004
938#define AR_RTC_RC_WARM_RESET 0x00000008
939
940#define AR_RTC_PLL_CONTROL \
941 (AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0014) : 0x7014
942
943#define AR_RTC_PLL_DIV 0x0000001f
944#define AR_RTC_PLL_DIV_S 0
945#define AR_RTC_PLL_DIV2 0x00000020
946#define AR_RTC_PLL_REFDIV_5 0x000000c0
947#define AR_RTC_PLL_CLKSEL 0x00000300
948#define AR_RTC_PLL_CLKSEL_S 8
949
950
951
952#define AR_RTC_RESET \
953 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0040) : 0x7040)
954#define AR_RTC_RESET_EN (0x00000001)
955
956#define AR_RTC_STATUS \
957 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0044) : 0x7044)
958
959#define AR_RTC_STATUS_M \
960 ((AR_SREV_9100(ah)) ? 0x0000003f : 0x0000000f)
961
962#define AR_RTC_PM_STATUS_M 0x0000000f
963
964#define AR_RTC_STATUS_SHUTDOWN 0x00000001
965#define AR_RTC_STATUS_ON 0x00000002
966#define AR_RTC_STATUS_SLEEP 0x00000004
967#define AR_RTC_STATUS_WAKEUP 0x00000008
968
969#define AR_RTC_SLEEP_CLK \
970 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0048) : 0x7048)
971#define AR_RTC_FORCE_DERIVED_CLK 0x2
972
973#define AR_RTC_FORCE_WAKE \
974 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x004c) : 0x704c)
975#define AR_RTC_FORCE_WAKE_EN 0x00000001
976#define AR_RTC_FORCE_WAKE_ON_INT 0x00000002
977
978
979#define AR_RTC_INTR_CAUSE \
980 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0050) : 0x7050)
981
982#define AR_RTC_INTR_ENABLE \
983 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0054) : 0x7054)
984
985#define AR_RTC_INTR_MASK \
986 ((AR_SREV_9100(ah)) ? (AR_RTC_BASE + 0x0058) : 0x7058)
987
988#define AR_SEQ_MASK 0x8060
989
990#define AR_AN_RF2G1_CH0 0x7810
991#define AR_AN_RF2G1_CH0_OB 0x03800000
992#define AR_AN_RF2G1_CH0_OB_S 23
993#define AR_AN_RF2G1_CH0_DB 0x1C000000
994#define AR_AN_RF2G1_CH0_DB_S 26
995
996#define AR_AN_RF5G1_CH0 0x7818
997#define AR_AN_RF5G1_CH0_OB5 0x00070000
998#define AR_AN_RF5G1_CH0_OB5_S 16
999#define AR_AN_RF5G1_CH0_DB5 0x00380000
1000#define AR_AN_RF5G1_CH0_DB5_S 19
1001
1002#define AR_AN_RF2G1_CH1 0x7834
1003#define AR_AN_RF2G1_CH1_OB 0x03800000
1004#define AR_AN_RF2G1_CH1_OB_S 23
1005#define AR_AN_RF2G1_CH1_DB 0x1C000000
1006#define AR_AN_RF2G1_CH1_DB_S 26
1007
1008#define AR_AN_RF5G1_CH1 0x783C
1009#define AR_AN_RF5G1_CH1_OB5 0x00070000
1010#define AR_AN_RF5G1_CH1_OB5_S 16
1011#define AR_AN_RF5G1_CH1_DB5 0x00380000
1012#define AR_AN_RF5G1_CH1_DB5_S 19
1013
1014#define AR_AN_TOP2 0x7894
1015#define AR_AN_TOP2_XPABIAS_LVL 0xC0000000
1016#define AR_AN_TOP2_XPABIAS_LVL_S 30
1017#define AR_AN_TOP2_LOCALBIAS 0x00200000
1018#define AR_AN_TOP2_LOCALBIAS_S 21
1019#define AR_AN_TOP2_PWDCLKIND 0x00400000
1020#define AR_AN_TOP2_PWDCLKIND_S 22
1021
1022#define AR_AN_SYNTH9 0x7868
1023#define AR_AN_SYNTH9_REFDIVA 0xf8000000
1024#define AR_AN_SYNTH9_REFDIVA_S 27
1025
1026#define AR_STA_ID0 0x8000
1027#define AR_STA_ID1 0x8004
1028#define AR_STA_ID1_SADH_MASK 0x0000FFFF
1029#define AR_STA_ID1_STA_AP 0x00010000
1030#define AR_STA_ID1_ADHOC 0x00020000
1031#define AR_STA_ID1_PWR_SAV 0x00040000
1032#define AR_STA_ID1_KSRCHDIS 0x00080000
1033#define AR_STA_ID1_PCF 0x00100000
1034#define AR_STA_ID1_USE_DEFANT 0x00200000
1035#define AR_STA_ID1_DEFANT_UPDATE 0x00400000
1036#define AR_STA_ID1_RTS_USE_DEF 0x00800000
1037#define AR_STA_ID1_ACKCTS_6MB 0x01000000
1038#define AR_STA_ID1_BASE_RATE_11B 0x02000000
1039#define AR_STA_ID1_SECTOR_SELF_GEN 0x04000000
1040#define AR_STA_ID1_CRPT_MIC_ENABLE 0x08000000
1041#define AR_STA_ID1_KSRCH_MODE 0x10000000
1042#define AR_STA_ID1_PRESERVE_SEQNUM 0x20000000
1043#define AR_STA_ID1_CBCIV_ENDIAN 0x40000000
1044#define AR_STA_ID1_MCAST_KSRCH 0x80000000
1045
1046#define AR_BSS_ID0 0x8008
1047#define AR_BSS_ID1 0x800C
1048#define AR_BSS_ID1_U16 0x0000FFFF
1049#define AR_BSS_ID1_AID 0x07FF0000
1050#define AR_BSS_ID1_AID_S 16
1051
1052#define AR_BCN_RSSI_AVE 0x8010
1053#define AR_BCN_RSSI_AVE_MASK 0x00000FFF
1054
1055#define AR_TIME_OUT 0x8014
1056#define AR_TIME_OUT_ACK 0x00003FFF
1057#define AR_TIME_OUT_ACK_S 0
1058#define AR_TIME_OUT_CTS 0x3FFF0000
1059#define AR_TIME_OUT_CTS_S 16
1060
1061#define AR_RSSI_THR 0x8018
1062#define AR_RSSI_THR_MASK 0x000000FF
1063#define AR_RSSI_THR_BM_THR 0x0000FF00
1064#define AR_RSSI_THR_BM_THR_S 8
1065#define AR_RSSI_BCN_WEIGHT 0x1F000000
1066#define AR_RSSI_BCN_WEIGHT_S 24
1067#define AR_RSSI_BCN_RSSI_RST 0x20000000
1068
1069#define AR_USEC 0x801c
1070#define AR_USEC_USEC 0x0000007F
1071#define AR_USEC_TX_LAT 0x007FC000
1072#define AR_USEC_TX_LAT_S 14
1073#define AR_USEC_RX_LAT 0x1F800000
1074#define AR_USEC_RX_LAT_S 23
1075
1076#define AR_RESET_TSF 0x8020
1077#define AR_RESET_TSF_ONCE 0x01000000
1078
1079#define AR_MAX_CFP_DUR 0x8038
1080#define AR_CFP_VAL 0x0000FFFF
1081
1082#define AR_RX_FILTER 0x803C
1083#define AR_RX_FILTER_ALL 0x00000000
1084#define AR_RX_UCAST 0x00000001
1085#define AR_RX_MCAST 0x00000002
1086#define AR_RX_BCAST 0x00000004
1087#define AR_RX_CONTROL 0x00000008
1088#define AR_RX_BEACON 0x00000010
1089#define AR_RX_PROM 0x00000020
1090#define AR_RX_PROBE_REQ 0x00000080
1091#define AR_RX_MY_BEACON 0x00000200
1092#define AR_RX_COMPR_BAR 0x00000400
1093#define AR_RX_COMPR_BA 0x00000800
1094#define AR_RX_UNCOM_BA_BAR 0x00001000
1095
1096#define AR_MCAST_FIL0 0x8040
1097#define AR_MCAST_FIL1 0x8044
1098
1099#define AR_DIAG_SW 0x8048
1100#define AR_DIAG_CACHE_ACK 0x00000001
1101#define AR_DIAG_ACK_DIS 0x00000002
1102#define AR_DIAG_CTS_DIS 0x00000004
1103#define AR_DIAG_ENCRYPT_DIS 0x00000008
1104#define AR_DIAG_DECRYPT_DIS 0x00000010
1105#define AR_DIAG_RX_DIS 0x00000020
1106#define AR_DIAG_LOOP_BACK 0x00000040
1107#define AR_DIAG_CORR_FCS 0x00000080
1108#define AR_DIAG_CHAN_INFO 0x00000100
1109#define AR_DIAG_SCRAM_SEED 0x0001FE00
1110#define AR_DIAG_SCRAM_SEED_S 8
1111#define AR_DIAG_FRAME_NV0 0x00020000
1112#define AR_DIAG_OBS_PT_SEL1 0x000C0000
1113#define AR_DIAG_OBS_PT_SEL1_S 18
1114#define AR_DIAG_FORCE_RX_CLEAR 0x00100000
1115#define AR_DIAG_IGNORE_VIRT_CS 0x00200000
1116#define AR_DIAG_FORCE_CH_IDLE_HIGH 0x00400000
1117#define AR_DIAG_EIFS_CTRL_ENA 0x00800000
1118#define AR_DIAG_DUAL_CHAIN_INFO 0x01000000
1119#define AR_DIAG_RX_ABORT 0x02000000
1120#define AR_DIAG_SATURATE_CYCLE_CNT 0x04000000
1121#define AR_DIAG_OBS_PT_SEL2 0x08000000
1122#define AR_DIAG_RX_CLEAR_CTL_LOW 0x10000000
1123#define AR_DIAG_RX_CLEAR_EXT_LOW 0x20000000
1124
1125#define AR_TSF_L32 0x804c
1126#define AR_TSF_U32 0x8050
1127
1128#define AR_TST_ADDAC 0x8054
1129#define AR_DEF_ANTENNA 0x8058
1130
1131#define AR_AES_MUTE_MASK0 0x805c
1132#define AR_AES_MUTE_MASK0_FC 0x0000FFFF
1133#define AR_AES_MUTE_MASK0_QOS 0xFFFF0000
1134#define AR_AES_MUTE_MASK0_QOS_S 16
1135
1136#define AR_AES_MUTE_MASK1 0x8060
1137#define AR_AES_MUTE_MASK1_SEQ 0x0000FFFF
1138
1139#define AR_GATED_CLKS 0x8064
1140#define AR_GATED_CLKS_TX 0x00000002
1141#define AR_GATED_CLKS_RX 0x00000004
1142#define AR_GATED_CLKS_REG 0x00000008
1143
1144#define AR_OBS_BUS_CTRL 0x8068
1145#define AR_OBS_BUS_SEL_1 0x00040000
1146#define AR_OBS_BUS_SEL_2 0x00080000
1147#define AR_OBS_BUS_SEL_3 0x000C0000
1148#define AR_OBS_BUS_SEL_4 0x08040000
1149#define AR_OBS_BUS_SEL_5 0x08080000
1150
1151#define AR_OBS_BUS_1 0x806c
1152#define AR_OBS_BUS_1_PCU 0x00000001
1153#define AR_OBS_BUS_1_RX_END 0x00000002
1154#define AR_OBS_BUS_1_RX_WEP 0x00000004
1155#define AR_OBS_BUS_1_RX_BEACON 0x00000008
1156#define AR_OBS_BUS_1_RX_FILTER 0x00000010
1157#define AR_OBS_BUS_1_TX_HCF 0x00000020
1158#define AR_OBS_BUS_1_QUIET_TIME 0x00000040
1159#define AR_OBS_BUS_1_CHAN_IDLE 0x00000080
1160#define AR_OBS_BUS_1_TX_HOLD 0x00000100
1161#define AR_OBS_BUS_1_TX_FRAME 0x00000200
1162#define AR_OBS_BUS_1_RX_FRAME 0x00000400
1163#define AR_OBS_BUS_1_RX_CLEAR 0x00000800
1164#define AR_OBS_BUS_1_WEP_STATE 0x0003F000
1165#define AR_OBS_BUS_1_WEP_STATE_S 12
1166#define AR_OBS_BUS_1_RX_STATE 0x01F00000
1167#define AR_OBS_BUS_1_RX_STATE_S 20
1168#define AR_OBS_BUS_1_TX_STATE 0x7E000000
1169#define AR_OBS_BUS_1_TX_STATE_S 25
1170
1171#define AR_LAST_TSTP 0x8080
1172#define AR_NAV 0x8084
1173#define AR_RTS_OK 0x8088
1174#define AR_RTS_FAIL 0x808c
1175#define AR_ACK_FAIL 0x8090
1176#define AR_FCS_FAIL 0x8094
1177#define AR_BEACON_CNT 0x8098
1178
1179#define AR_SLEEP1 0x80d4
1180#define AR_SLEEP1_ASSUME_DTIM 0x00080000
1181#define AR_SLEEP1_CAB_TIMEOUT 0xFFE00000
1182#define AR_SLEEP1_CAB_TIMEOUT_S 21
1183
1184#define AR_SLEEP2 0x80d8
1185#define AR_SLEEP2_BEACON_TIMEOUT 0xFFE00000
1186#define AR_SLEEP2_BEACON_TIMEOUT_S 21
1187
1188#define AR_BSSMSKL 0x80e0
1189#define AR_BSSMSKU 0x80e4
1190
1191#define AR_TPC 0x80e8
1192#define AR_TPC_ACK 0x0000003f
1193#define AR_TPC_ACK_S 0x00
1194#define AR_TPC_CTS 0x00003f00
1195#define AR_TPC_CTS_S 0x08
1196#define AR_TPC_CHIRP 0x003f0000
1197#define AR_TPC_CHIRP_S 0x16
1198
1199#define AR_TFCNT 0x80ec
1200#define AR_RFCNT 0x80f0
1201#define AR_RCCNT 0x80f4
1202#define AR_CCCNT 0x80f8
1203
1204#define AR_QUIET1 0x80fc
1205#define AR_QUIET1_NEXT_QUIET_S 0
1206#define AR_QUIET1_NEXT_QUIET_M 0x0000ffff
1207#define AR_QUIET1_QUIET_ENABLE 0x00010000
1208#define AR_QUIET1_QUIET_ACK_CTS_ENABLE 0x00020000
1209#define AR_QUIET2 0x8100
1210#define AR_QUIET2_QUIET_PERIOD_S 0
1211#define AR_QUIET2_QUIET_PERIOD_M 0x0000ffff
1212#define AR_QUIET2_QUIET_DUR_S 16
1213#define AR_QUIET2_QUIET_DUR 0xffff0000
1214
1215#define AR_TSF_PARM 0x8104
1216#define AR_TSF_INCREMENT_M 0x000000ff
1217#define AR_TSF_INCREMENT_S 0x00
1218
1219#define AR_QOS_NO_ACK 0x8108
1220#define AR_QOS_NO_ACK_TWO_BIT 0x0000000f
1221#define AR_QOS_NO_ACK_TWO_BIT_S 0
1222#define AR_QOS_NO_ACK_BIT_OFF 0x00000070
1223#define AR_QOS_NO_ACK_BIT_OFF_S 4
1224#define AR_QOS_NO_ACK_BYTE_OFF 0x00000180
1225#define AR_QOS_NO_ACK_BYTE_OFF_S 7
1226
1227#define AR_PHY_ERR 0x810c
1228
1229#define AR_PHY_ERR_DCHIRP 0x00000008
1230#define AR_PHY_ERR_RADAR 0x00000020
1231#define AR_PHY_ERR_OFDM_TIMING 0x00020000
1232#define AR_PHY_ERR_CCK_TIMING 0x02000000
1233
1234#define AR_RXFIFO_CFG 0x8114
1235
1236
1237#define AR_MIC_QOS_CONTROL 0x8118
1238#define AR_MIC_QOS_SELECT 0x811c
1239
1240#define AR_PCU_MISC 0x8120
1241#define AR_PCU_FORCE_BSSID_MATCH 0x00000001
1242#define AR_PCU_MIC_NEW_LOC_ENA 0x00000004
1243#define AR_PCU_TX_ADD_TSF 0x00000008
1244#define AR_PCU_CCK_SIFS_MODE 0x00000010
1245#define AR_PCU_RX_ANT_UPDT 0x00000800
1246#define AR_PCU_TXOP_TBTT_LIMIT_ENA 0x00001000
1247#define AR_PCU_MISS_BCN_IN_SLEEP 0x00004000
1248#define AR_PCU_BUG_12306_FIX_ENA 0x00020000
1249#define AR_PCU_FORCE_QUIET_COLL 0x00040000
1250#define AR_PCU_TBTT_PROTECT 0x00200000
1251#define AR_PCU_CLEAR_VMF 0x01000000
1252#define AR_PCU_CLEAR_BA_VALID 0x04000000
1253
1254
1255#define AR_FILT_OFDM 0x8124
1256#define AR_FILT_OFDM_COUNT 0x00FFFFFF
1257
1258#define AR_FILT_CCK 0x8128
1259#define AR_FILT_CCK_COUNT 0x00FFFFFF
1260
1261#define AR_PHY_ERR_1 0x812c
1262#define AR_PHY_ERR_1_COUNT 0x00FFFFFF
1263#define AR_PHY_ERR_MASK_1 0x8130
1264
1265#define AR_PHY_ERR_2 0x8134
1266#define AR_PHY_ERR_2_COUNT 0x00FFFFFF
1267#define AR_PHY_ERR_MASK_2 0x8138
1268
1269#define AR_PHY_COUNTMAX (3 << 22)
1270#define AR_MIBCNT_INTRMASK (3 << 22)
1271
1272#define AR_TSF_THRESHOLD 0x813c
1273#define AR_TSF_THRESHOLD_VAL 0x0000FFFF
1274
1275#define AR_PHY_ERR_EIFS_MASK 8144
1276
1277#define AR_PHY_ERR_3 0x8168
1278#define AR_PHY_ERR_3_COUNT 0x00FFFFFF
1279#define AR_PHY_ERR_MASK_3 0x816c
1280
1281#define AR_TXSIFS 0x81d0
1282#define AR_TXSIFS_TIME 0x000000FF
1283#define AR_TXSIFS_TX_LATENCY 0x00000F00
1284#define AR_TXSIFS_TX_LATENCY_S 8
1285#define AR_TXSIFS_ACK_SHIFT 0x00007000
1286#define AR_TXSIFS_ACK_SHIFT_S 12
1287
1288#define AR_TXOP_X 0x81ec
1289#define AR_TXOP_X_VAL 0x000000FF
1290
1291
1292#define AR_TXOP_0_3 0x81f0
1293#define AR_TXOP_4_7 0x81f4
1294#define AR_TXOP_8_11 0x81f8
1295#define AR_TXOP_12_15 0x81fc
1296
1297
1298#define AR_NEXT_TBTT_TIMER 0x8200
1299#define AR_NEXT_DMA_BEACON_ALERT 0x8204
1300#define AR_NEXT_SWBA 0x8208
1301#define AR_NEXT_CFP 0x8208
1302#define AR_NEXT_HCF 0x820C
1303#define AR_NEXT_TIM 0x8210
1304#define AR_NEXT_DTIM 0x8214
1305#define AR_NEXT_QUIET_TIMER 0x8218
1306#define AR_NEXT_NDP_TIMER 0x821C
1307
1308#define AR_BEACON_PERIOD 0x8220
1309#define AR_DMA_BEACON_PERIOD 0x8224
1310#define AR_SWBA_PERIOD 0x8228
1311#define AR_HCF_PERIOD 0x822C
1312#define AR_TIM_PERIOD 0x8230
1313#define AR_DTIM_PERIOD 0x8234
1314#define AR_QUIET_PERIOD 0x8238
1315#define AR_NDP_PERIOD 0x823C
1316
1317#define AR_TIMER_MODE 0x8240
1318#define AR_TBTT_TIMER_EN 0x00000001
1319#define AR_DBA_TIMER_EN 0x00000002
1320#define AR_SWBA_TIMER_EN 0x00000004
1321#define AR_HCF_TIMER_EN 0x00000008
1322#define AR_TIM_TIMER_EN 0x00000010
1323#define AR_DTIM_TIMER_EN 0x00000020
1324#define AR_QUIET_TIMER_EN 0x00000040
1325#define AR_NDP_TIMER_EN 0x00000080
1326#define AR_TIMER_OVERFLOW_INDEX 0x00000700
1327#define AR_TIMER_OVERFLOW_INDEX_S 8
1328#define AR_TIMER_THRESH 0xFFFFF000
1329#define AR_TIMER_THRESH_S 12
1330
1331#define AR_SLP32_MODE 0x8244
1332#define AR_SLP32_HALF_CLK_LATENCY 0x000FFFFF
1333#define AR_SLP32_ENA 0x00100000
1334#define AR_SLP32_TSF_WRITE_STATUS 0x00200000
1335
1336#define AR_SLP32_WAKE 0x8248
1337#define AR_SLP32_WAKE_XTL_TIME 0x0000FFFF
1338
1339#define AR_SLP32_INC 0x824c
1340#define AR_SLP32_TST_INC 0x000FFFFF
1341
1342#define AR_SLP_CNT 0x8250
1343#define AR_SLP_CYCLE_CNT 0x8254
1344
1345#define AR_SLP_MIB_CTRL 0x8258
1346#define AR_SLP_MIB_CLEAR 0x00000001
1347#define AR_SLP_MIB_PENDING 0x00000002
1348
1349#define AR_2040_MODE 0x8318
1350#define AR_2040_JOINED_RX_CLEAR 0x00000001
1351
1352
1353#define AR_EXTRCCNT 0x8328
1354
1355#define AR_SELFGEN_MASK 0x832c
1356
1357#define AR_PCU_TXBUF_CTRL 0x8340
1358#define AR_PCU_TXBUF_CTRL_SIZE_MASK 0x7FF
1359#define AR_PCU_TXBUF_CTRL_USABLE_SIZE 0x700
1360#define AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE 0x380
1361
1362#define AR_KEYTABLE_0 0x8800
1363#define AR_KEYTABLE(_n) (AR_KEYTABLE_0 + ((_n)*32))
1364#define AR_KEY_CACHE_SIZE 128
1365#define AR_RSVD_KEYTABLE_ENTRIES 4
1366#define AR_KEY_TYPE 0x00000007
1367#define AR_KEYTABLE_TYPE_40 0x00000000
1368#define AR_KEYTABLE_TYPE_104 0x00000001
1369#define AR_KEYTABLE_TYPE_128 0x00000003
1370#define AR_KEYTABLE_TYPE_TKIP 0x00000004
1371#define AR_KEYTABLE_TYPE_AES 0x00000005
1372#define AR_KEYTABLE_TYPE_CCM 0x00000006
1373#define AR_KEYTABLE_TYPE_CLR 0x00000007
1374#define AR_KEYTABLE_ANT 0x00000008
1375#define AR_KEYTABLE_VALID 0x00008000
1376#define AR_KEYTABLE_KEY0(_n) (AR_KEYTABLE(_n) + 0)
1377#define AR_KEYTABLE_KEY1(_n) (AR_KEYTABLE(_n) + 4)
1378#define AR_KEYTABLE_KEY2(_n) (AR_KEYTABLE(_n) + 8)
1379#define AR_KEYTABLE_KEY3(_n) (AR_KEYTABLE(_n) + 12)
1380#define AR_KEYTABLE_KEY4(_n) (AR_KEYTABLE(_n) + 16)
1381#define AR_KEYTABLE_TYPE(_n) (AR_KEYTABLE(_n) + 20)
1382#define AR_KEYTABLE_MAC0(_n) (AR_KEYTABLE(_n) + 24)
1383#define AR_KEYTABLE_MAC1(_n) (AR_KEYTABLE(_n) + 28)
1384
1385#endif
diff --git a/drivers/net/wireless/ath9k/regd.c b/drivers/net/wireless/ath9k/regd.c
new file mode 100644
index 000000000000..7b0176e3eb40
--- /dev/null
+++ b/drivers/net/wireless/ath9k/regd.c
@@ -0,0 +1,1031 @@
1/*
2 * Copyright (c) 2008 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 <linux/kernel.h>
18#include <linux/slab.h>
19#include "core.h"
20#include "hw.h"
21#include "regd.h"
22#include "regd_common.h"
23
24static int ath9k_regd_chansort(const void *a, const void *b)
25{
26 const struct ath9k_channel *ca = a;
27 const struct ath9k_channel *cb = b;
28
29 return (ca->channel == cb->channel) ?
30 (ca->channelFlags & CHAN_FLAGS) -
31 (cb->channelFlags & CHAN_FLAGS) : ca->channel - cb->channel;
32}
33
34static void
35ath9k_regd_sort(void *a, u32 n, u32 size, ath_hal_cmp_t *cmp)
36{
37 u8 *aa = a;
38 u8 *ai, *t;
39
40 for (ai = aa + size; --n >= 1; ai += size)
41 for (t = ai; t > aa; t -= size) {
42 u8 *u = t - size;
43 if (cmp(u, t) <= 0)
44 break;
45 swap(u, t, size);
46 }
47}
48
49static u16 ath9k_regd_get_eepromRD(struct ath_hal *ah)
50{
51 return ah->ah_currentRD & ~WORLDWIDE_ROAMING_FLAG;
52}
53
54static bool ath9k_regd_is_chan_bm_zero(u64 *bitmask)
55{
56 int i;
57
58 for (i = 0; i < BMLEN; i++) {
59 if (bitmask[i] != 0)
60 return false;
61 }
62 return true;
63}
64
65static bool ath9k_regd_is_eeprom_valid(struct ath_hal *ah)
66{
67 u16 rd = ath9k_regd_get_eepromRD(ah);
68 int i;
69
70 if (rd & COUNTRY_ERD_FLAG) {
71 u16 cc = rd & ~COUNTRY_ERD_FLAG;
72 for (i = 0; i < ARRAY_SIZE(allCountries); i++)
73 if (allCountries[i].countryCode == cc)
74 return true;
75 } else {
76 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
77 if (regDomainPairs[i].regDmnEnum == rd)
78 return true;
79 }
80 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
81 "%s: invalid regulatory domain/country code 0x%x\n",
82 __func__, rd);
83 return false;
84}
85
86static bool ath9k_regd_is_fcc_midband_supported(struct ath_hal *ah)
87{
88 u32 regcap;
89
90 regcap = ah->ah_caps.halRegCap;
91
92 if (regcap & AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND)
93 return true;
94 else
95 return false;
96}
97
98static bool ath9k_regd_is_ccode_valid(struct ath_hal *ah,
99 u16 cc)
100{
101 u16 rd;
102 int i;
103
104 if (cc == CTRY_DEFAULT)
105 return true;
106 if (cc == CTRY_DEBUG)
107 return true;
108
109 rd = ath9k_regd_get_eepromRD(ah);
110 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: EEPROM regdomain 0x%x\n",
111 __func__, rd);
112
113 if (rd & COUNTRY_ERD_FLAG) {
114 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
115 "%s: EEPROM setting is country code %u\n",
116 __func__, rd & ~COUNTRY_ERD_FLAG);
117 return cc == (rd & ~COUNTRY_ERD_FLAG);
118 }
119
120 for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
121 if (cc == allCountries[i].countryCode) {
122#ifdef AH_SUPPORT_11D
123 if ((rd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX)
124 return true;
125#endif
126 if (allCountries[i].regDmnEnum == rd ||
127 rd == DEBUG_REG_DMN || rd == NO_ENUMRD)
128 return true;
129 }
130 }
131 return false;
132}
133
134static u32
135ath9k_regd_get_wmodes_nreg(struct ath_hal *ah,
136 struct country_code_to_enum_rd *country,
137 struct regDomain *rd5GHz)
138{
139 u32 modesAvail;
140
141 modesAvail = ah->ah_caps.halWirelessModes;
142
143 if ((modesAvail & ATH9K_MODE_SEL_11G) && (!country->allow11g))
144 modesAvail &= ~ATH9K_MODE_SEL_11G;
145 if ((modesAvail & ATH9K_MODE_SEL_11A) &&
146 (ath9k_regd_is_chan_bm_zero(rd5GHz->chan11a)))
147 modesAvail &= ~ATH9K_MODE_SEL_11A;
148
149 if ((modesAvail & ATH9K_MODE_SEL_11NG_HT20)
150 && (!country->allow11ng20))
151 modesAvail &= ~ATH9K_MODE_SEL_11NG_HT20;
152
153 if ((modesAvail & ATH9K_MODE_SEL_11NA_HT20)
154 && (!country->allow11na20))
155 modesAvail &= ~ATH9K_MODE_SEL_11NA_HT20;
156
157 if ((modesAvail & ATH9K_MODE_SEL_11NG_HT40PLUS) &&
158 (!country->allow11ng40))
159 modesAvail &= ~ATH9K_MODE_SEL_11NG_HT40PLUS;
160
161 if ((modesAvail & ATH9K_MODE_SEL_11NG_HT40MINUS) &&
162 (!country->allow11ng40))
163 modesAvail &= ~ATH9K_MODE_SEL_11NG_HT40MINUS;
164
165 if ((modesAvail & ATH9K_MODE_SEL_11NA_HT40PLUS) &&
166 (!country->allow11na40))
167 modesAvail &= ~ATH9K_MODE_SEL_11NA_HT40PLUS;
168
169 if ((modesAvail & ATH9K_MODE_SEL_11NA_HT40MINUS) &&
170 (!country->allow11na40))
171 modesAvail &= ~ATH9K_MODE_SEL_11NA_HT40MINUS;
172
173 return modesAvail;
174}
175
176bool ath9k_regd_is_public_safety_sku(struct ath_hal *ah)
177{
178 u16 rd;
179
180 rd = ath9k_regd_get_eepromRD(ah);
181
182 switch (rd) {
183 case FCC4_FCCA:
184 case (CTRY_UNITED_STATES_FCC49 | COUNTRY_ERD_FLAG):
185 return true;
186 case DEBUG_REG_DMN:
187 case NO_ENUMRD:
188 if (ah->ah_countryCode == CTRY_UNITED_STATES_FCC49)
189 return true;
190 break;
191 }
192 return false;
193}
194
195static struct country_code_to_enum_rd*
196ath9k_regd_find_country(u16 countryCode)
197{
198 int i;
199
200 for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
201 if (allCountries[i].countryCode == countryCode)
202 return &allCountries[i];
203 }
204 return NULL;
205}
206
207static u16 ath9k_regd_get_default_country(struct ath_hal *ah)
208{
209 u16 rd;
210 int i;
211
212 rd = ath9k_regd_get_eepromRD(ah);
213 if (rd & COUNTRY_ERD_FLAG) {
214 struct country_code_to_enum_rd *country = NULL;
215 u16 cc = rd & ~COUNTRY_ERD_FLAG;
216
217 country = ath9k_regd_find_country(cc);
218 if (country != NULL)
219 return cc;
220 }
221
222 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
223 if (regDomainPairs[i].regDmnEnum == rd) {
224 if (regDomainPairs[i].singleCC != 0)
225 return regDomainPairs[i].singleCC;
226 else
227 i = ARRAY_SIZE(regDomainPairs);
228 }
229 return CTRY_DEFAULT;
230}
231
232static bool ath9k_regd_is_valid_reg_domain(int regDmn,
233 struct regDomain *rd)
234{
235 int i;
236
237 for (i = 0; i < ARRAY_SIZE(regDomains); i++) {
238 if (regDomains[i].regDmnEnum == regDmn) {
239 if (rd != NULL) {
240 memcpy(rd, &regDomains[i],
241 sizeof(struct regDomain));
242 }
243 return true;
244 }
245 }
246 return false;
247}
248
249static bool ath9k_regd_is_valid_reg_domainPair(int regDmnPair)
250{
251 int i;
252
253 if (regDmnPair == NO_ENUMRD)
254 return false;
255 for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
256 if (regDomainPairs[i].regDmnEnum == regDmnPair)
257 return true;
258 }
259 return false;
260}
261
262static bool
263ath9k_regd_get_wmode_regdomain(struct ath_hal *ah, int regDmn,
264 u16 channelFlag, struct regDomain *rd)
265{
266 int i, found;
267 u64 flags = NO_REQ;
268 struct reg_dmn_pair_mapping *regPair = NULL;
269 int regOrg;
270
271 regOrg = regDmn;
272 if (regDmn == CTRY_DEFAULT) {
273 u16 rdnum;
274 rdnum = ath9k_regd_get_eepromRD(ah);
275
276 if (!(rdnum & COUNTRY_ERD_FLAG)) {
277 if (ath9k_regd_is_valid_reg_domain(rdnum, NULL) ||
278 ath9k_regd_is_valid_reg_domainPair(rdnum)) {
279 regDmn = rdnum;
280 }
281 }
282 }
283
284 if ((regDmn & MULTI_DOMAIN_MASK) == 0) {
285 for (i = 0, found = 0;
286 (i < ARRAY_SIZE(regDomainPairs)) && (!found); i++) {
287 if (regDomainPairs[i].regDmnEnum == regDmn) {
288 regPair = &regDomainPairs[i];
289 found = 1;
290 }
291 }
292 if (!found) {
293 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
294 "%s: Failed to find reg domain pair %u\n",
295 __func__, regDmn);
296 return false;
297 }
298 if (!(channelFlag & CHANNEL_2GHZ)) {
299 regDmn = regPair->regDmn5GHz;
300 flags = regPair->flags5GHz;
301 }
302 if (channelFlag & CHANNEL_2GHZ) {
303 regDmn = regPair->regDmn2GHz;
304 flags = regPair->flags2GHz;
305 }
306 }
307
308 found = ath9k_regd_is_valid_reg_domain(regDmn, rd);
309 if (!found) {
310 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
311 "%s: Failed to find unitary reg domain %u\n",
312 __func__, regDmn);
313 return false;
314 } else {
315 rd->pscan &= regPair->pscanMask;
316 if (((regOrg & MULTI_DOMAIN_MASK) == 0) &&
317 (flags != NO_REQ)) {
318 rd->flags = flags;
319 }
320
321 rd->flags &= (channelFlag & CHANNEL_2GHZ) ?
322 REG_DOMAIN_2GHZ_MASK : REG_DOMAIN_5GHZ_MASK;
323 return true;
324 }
325}
326
327static bool ath9k_regd_is_bit_set(int bit, u64 *bitmask)
328{
329 int byteOffset, bitnum;
330 u64 val;
331
332 byteOffset = bit / 64;
333 bitnum = bit - byteOffset * 64;
334 val = ((u64) 1) << bitnum;
335 if (bitmask[byteOffset] & val)
336 return true;
337 else
338 return false;
339}
340
341static void
342ath9k_regd_add_reg_classid(u8 *regclassids, u32 maxregids,
343 u32 *nregids, u8 regclassid)
344{
345 int i;
346
347 if (regclassid == 0)
348 return;
349
350 for (i = 0; i < maxregids; i++) {
351 if (regclassids[i] == regclassid)
352 return;
353 if (regclassids[i] == 0)
354 break;
355 }
356
357 if (i == maxregids)
358 return;
359 else {
360 regclassids[i] = regclassid;
361 *nregids += 1;
362 }
363
364 return;
365}
366
367static bool
368ath9k_regd_get_eeprom_reg_ext_bits(struct ath_hal *ah,
369 enum reg_ext_bitmap bit)
370{
371 return (ah->ah_currentRDExt & (1 << bit)) ? true : false;
372}
373
374#ifdef ATH_NF_PER_CHAN
375
376static void ath9k_regd_init_rf_buffer(struct ath9k_channel *ichans,
377 int nchans)
378{
379 int i, j, next;
380
381 for (next = 0; next < nchans; next++) {
382 for (i = 0; i < NUM_NF_READINGS; i++) {
383 ichans[next].nfCalHist[i].currIndex = 0;
384 ichans[next].nfCalHist[i].privNF =
385 AR_PHY_CCA_MAX_GOOD_VALUE;
386 ichans[next].nfCalHist[i].invalidNFcount =
387 AR_PHY_CCA_FILTERWINDOW_LENGTH;
388 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
389 ichans[next].nfCalHist[i].nfCalBuffer[j] =
390 AR_PHY_CCA_MAX_GOOD_VALUE;
391 }
392 }
393 }
394}
395#endif
396
397static int ath9k_regd_is_chan_present(struct ath_hal *ah,
398 u16 c)
399{
400 int i;
401
402 for (i = 0; i < 150; i++) {
403 if (!ah->ah_channels[i].channel)
404 return -1;
405 else if (ah->ah_channels[i].channel == c)
406 return i;
407 }
408
409 return -1;
410}
411
412static bool
413ath9k_regd_add_channel(struct ath_hal *ah,
414 u16 c,
415 u16 c_lo,
416 u16 c_hi,
417 u16 maxChan,
418 u8 ctl,
419 int pos,
420 struct regDomain rd5GHz,
421 struct RegDmnFreqBand *fband,
422 struct regDomain *rd,
423 const struct cmode *cm,
424 struct ath9k_channel *ichans,
425 bool enableExtendedChannels)
426{
427 struct ath9k_channel *chan;
428 int ret;
429 u32 channelFlags = 0;
430 u8 privFlags = 0;
431
432 if (!(c_lo <= c && c <= c_hi)) {
433 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
434 "%s: c %u out of range [%u..%u]\n",
435 __func__, c, c_lo, c_hi);
436 return false;
437 }
438 if ((fband->channelBW == CHANNEL_HALF_BW) &&
439 !ah->ah_caps.halChanHalfRate) {
440 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
441 "%s: Skipping %u half rate channel\n",
442 __func__, c);
443 return false;
444 }
445
446 if ((fband->channelBW == CHANNEL_QUARTER_BW) &&
447 !ah->ah_caps.halChanQuarterRate) {
448 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
449 "%s: Skipping %u quarter rate channel\n",
450 __func__, c);
451 return false;
452 }
453
454 if (((c + fband->channelSep) / 2) > (maxChan + HALF_MAXCHANBW)) {
455 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
456 "%s: c %u > maxChan %u\n",
457 __func__, c, maxChan);
458 return false;
459 }
460
461 if ((fband->usePassScan & IS_ECM_CHAN) && !enableExtendedChannels) {
462 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
463 "Skipping ecm channel\n");
464 return false;
465 }
466
467 if ((rd->flags & NO_HOSTAP) && (ah->ah_opmode == ATH9K_M_HOSTAP)) {
468 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
469 "Skipping HOSTAP channel\n");
470 return false;
471 }
472
473 if (IS_HT40_MODE(cm->mode) &&
474 !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_FCC_DFS_HT40)) &&
475 (fband->useDfs) &&
476 (rd->conformanceTestLimit != MKK)) {
477 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
478 "Skipping HT40 channel (en_fcc_dfs_ht40 = 0)\n");
479 return false;
480 }
481
482 if (IS_HT40_MODE(cm->mode) &&
483 !(ath9k_regd_get_eeprom_reg_ext_bits(ah,
484 REG_EXT_JAPAN_NONDFS_HT40)) &&
485 !(fband->useDfs) && (rd->conformanceTestLimit == MKK)) {
486 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
487 "Skipping HT40 channel (en_jap_ht40 = 0)\n");
488 return false;
489 }
490
491 if (IS_HT40_MODE(cm->mode) &&
492 !(ath9k_regd_get_eeprom_reg_ext_bits(ah, REG_EXT_JAPAN_DFS_HT40)) &&
493 (fband->useDfs) &&
494 (rd->conformanceTestLimit == MKK)) {
495 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
496 "Skipping HT40 channel (en_jap_dfs_ht40 = 0)\n");
497 return false;
498 }
499
500 /* Calculate channel flags */
501
502 channelFlags = cm->flags;
503
504 switch (fband->channelBW) {
505 case CHANNEL_HALF_BW:
506 channelFlags |= CHANNEL_HALF;
507 break;
508 case CHANNEL_QUARTER_BW:
509 channelFlags |= CHANNEL_QUARTER;
510 break;
511 }
512
513 if (fband->usePassScan & rd->pscan)
514 channelFlags |= CHANNEL_PASSIVE;
515 else
516 channelFlags &= ~CHANNEL_PASSIVE;
517 if (fband->useDfs & rd->dfsMask)
518 privFlags = CHANNEL_DFS;
519 else
520 privFlags = 0;
521 if (rd->flags & LIMIT_FRAME_4MS)
522 privFlags |= CHANNEL_4MS_LIMIT;
523 if (privFlags & CHANNEL_DFS)
524 privFlags |= CHANNEL_DISALLOW_ADHOC;
525 if (rd->flags & ADHOC_PER_11D)
526 privFlags |= CHANNEL_PER_11D_ADHOC;
527
528 if (channelFlags & CHANNEL_PASSIVE) {
529 if ((c < 2412) || (c > 2462)) {
530 if (rd5GHz.regDmnEnum == MKK1 ||
531 rd5GHz.regDmnEnum == MKK2) {
532 u32 regcap = ah->ah_caps.halRegCap;
533 if (!(regcap &
534 (AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
535 AR_EEPROM_EEREGCAP_EN_KK_U2 |
536 AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) &&
537 isUNII1OddChan(c)) {
538 channelFlags &= ~CHANNEL_PASSIVE;
539 } else {
540 privFlags |= CHANNEL_DISALLOW_ADHOC;
541 }
542 } else {
543 privFlags |= CHANNEL_DISALLOW_ADHOC;
544 }
545 }
546 }
547
548 if (cm->mode & (ATH9K_MODE_SEL_11A |
549 ATH9K_MODE_SEL_11NA_HT20 |
550 ATH9K_MODE_SEL_11NA_HT40PLUS |
551 ATH9K_MODE_SEL_11NA_HT40MINUS)) {
552 if (rd->flags & (ADHOC_NO_11A | DISALLOW_ADHOC_11A))
553 privFlags |= CHANNEL_DISALLOW_ADHOC;
554 }
555
556 /* Fill in channel details */
557
558 ret = ath9k_regd_is_chan_present(ah, c);
559 if (ret == -1) {
560 chan = &ah->ah_channels[pos];
561 chan->channel = c;
562 chan->maxRegTxPower = fband->powerDfs;
563 chan->antennaMax = fband->antennaMax;
564 chan->regDmnFlags = rd->flags;
565 chan->maxTxPower = AR5416_MAX_RATE_POWER;
566 chan->minTxPower = AR5416_MAX_RATE_POWER;
567 chan->channelFlags = channelFlags;
568 chan->privFlags = privFlags;
569 } else {
570 chan = &ah->ah_channels[ret];
571 chan->channelFlags |= channelFlags;
572 chan->privFlags |= privFlags;
573 }
574
575 /* Set CTLs */
576
577 if ((cm->flags & CHANNEL_ALL) == CHANNEL_A)
578 chan->conformanceTestLimit[0] = ctl;
579 else if ((cm->flags & CHANNEL_ALL) == CHANNEL_B)
580 chan->conformanceTestLimit[1] = ctl;
581 else if ((cm->flags & CHANNEL_ALL) == CHANNEL_G)
582 chan->conformanceTestLimit[2] = ctl;
583
584 return (ret == -1) ? true : false;
585}
586
587static bool ath9k_regd_japan_check(struct ath_hal *ah,
588 int b,
589 struct regDomain *rd5GHz)
590{
591 bool skipband = false;
592 int i;
593 u32 regcap;
594
595 for (i = 0; i < ARRAY_SIZE(j_bandcheck); i++) {
596 if (j_bandcheck[i].freqbandbit == b) {
597 regcap = ah->ah_caps.halRegCap;
598 if ((j_bandcheck[i].eepromflagtocheck & regcap) == 0) {
599 skipband = true;
600 } else if ((regcap & AR_EEPROM_EEREGCAP_EN_KK_U2) ||
601 (regcap & AR_EEPROM_EEREGCAP_EN_KK_MIDBAND)) {
602 rd5GHz->dfsMask |= DFS_MKK4;
603 rd5GHz->pscan |= PSCAN_MKK3;
604 }
605 break;
606 }
607 }
608
609 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
610 "%s: Skipping %d freq band\n",
611 __func__, j_bandcheck[i].freqbandbit);
612
613 return skipband;
614}
615
616bool
617ath9k_regd_init_channels(struct ath_hal *ah,
618 u32 maxchans,
619 u32 *nchans, u8 *regclassids,
620 u32 maxregids, u32 *nregids, u16 cc,
621 u32 modeSelect, bool enableOutdoor,
622 bool enableExtendedChannels)
623{
624 u32 modesAvail;
625 u16 maxChan = 7000;
626 struct country_code_to_enum_rd *country = NULL;
627 struct regDomain rd5GHz, rd2GHz;
628 const struct cmode *cm;
629 struct ath9k_channel *ichans = &ah->ah_channels[0];
630 int next = 0, b;
631 u8 ctl;
632 int regdmn;
633 u16 chanSep;
634
635 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: cc %u mode 0x%x%s%s\n",
636 __func__, cc, modeSelect,
637 enableOutdoor ? " Enable outdoor" : " ",
638 enableExtendedChannels ? " Enable ecm" : "");
639
640 if (!ath9k_regd_is_ccode_valid(ah, cc)) {
641 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
642 "%s: invalid country code %d\n", __func__, cc);
643 return false;
644 }
645
646 if (!ath9k_regd_is_eeprom_valid(ah)) {
647 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
648 "%s: invalid EEPROM contents\n", __func__);
649 return false;
650 }
651
652 ah->ah_countryCode = ath9k_regd_get_default_country(ah);
653
654 if (ah->ah_countryCode == CTRY_DEFAULT) {
655 ah->ah_countryCode = cc & COUNTRY_CODE_MASK;
656 if ((ah->ah_countryCode == CTRY_DEFAULT) &&
657 (ath9k_regd_get_eepromRD(ah) == CTRY_DEFAULT)) {
658 ah->ah_countryCode = CTRY_UNITED_STATES;
659 }
660 }
661
662#ifdef AH_SUPPORT_11D
663 if (ah->ah_countryCode == CTRY_DEFAULT) {
664 regdmn = ath9k_regd_get_eepromRD(ah);
665 country = NULL;
666 } else {
667#endif
668 country = ath9k_regd_find_country(ah->ah_countryCode);
669 if (country == NULL) {
670 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
671 "Country is NULL!!!!, cc= %d\n",
672 ah->ah_countryCode);
673 return false;
674 } else {
675 regdmn = country->regDmnEnum;
676#ifdef AH_SUPPORT_11D
677 if (((ath9k_regd_get_eepromRD(ah) &
678 WORLD_SKU_MASK) == WORLD_SKU_PREFIX) &&
679 (cc == CTRY_UNITED_STATES)) {
680 if (!isWwrSKU_NoMidband(ah)
681 && ath9k_regd_is_fcc_midband_supported(ah))
682 regdmn = FCC3_FCCA;
683 else
684 regdmn = FCC1_FCCA;
685 }
686#endif
687 }
688#ifdef AH_SUPPORT_11D
689 }
690#endif
691 if (!ath9k_regd_get_wmode_regdomain(ah,
692 regdmn,
693 ~CHANNEL_2GHZ,
694 &rd5GHz)) {
695 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
696 "%s: couldn't find unitary "
697 "5GHz reg domain for country %u\n",
698 __func__, ah->ah_countryCode);
699 return false;
700 }
701 if (!ath9k_regd_get_wmode_regdomain(ah,
702 regdmn,
703 CHANNEL_2GHZ,
704 &rd2GHz)) {
705 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
706 "%s: couldn't find unitary 2GHz "
707 "reg domain for country %u\n",
708 __func__, ah->ah_countryCode);
709 return false;
710 }
711
712 if (!isWwrSKU(ah) && ((rd5GHz.regDmnEnum == FCC1) ||
713 (rd5GHz.regDmnEnum == FCC2))) {
714 if (ath9k_regd_is_fcc_midband_supported(ah)) {
715 if (!ath9k_regd_get_wmode_regdomain(ah,
716 FCC3_FCCA,
717 ~CHANNEL_2GHZ,
718 &rd5GHz)) {
719 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
720 "%s: couldn't find unitary 5GHz "
721 "reg domain for country %u\n",
722 __func__, ah->ah_countryCode);
723 return false;
724 }
725 }
726 }
727
728 if (country == NULL) {
729 modesAvail = ah->ah_caps.halWirelessModes;
730 } else {
731 modesAvail = ath9k_regd_get_wmodes_nreg(ah, country, &rd5GHz);
732 if (!enableOutdoor)
733 maxChan = country->outdoorChanStart;
734 }
735
736 next = 0;
737
738 if (maxchans > ARRAY_SIZE(ah->ah_channels))
739 maxchans = ARRAY_SIZE(ah->ah_channels);
740
741 for (cm = modes; cm < &modes[ARRAY_SIZE(modes)]; cm++) {
742 u16 c, c_hi, c_lo;
743 u64 *channelBM = NULL;
744 struct regDomain *rd = NULL;
745 struct RegDmnFreqBand *fband = NULL, *freqs;
746 int8_t low_adj = 0, hi_adj = 0;
747
748 if ((cm->mode & modeSelect) == 0) {
749 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
750 "%s: skip mode 0x%x flags 0x%x\n",
751 __func__, cm->mode, cm->flags);
752 continue;
753 }
754 if ((cm->mode & modesAvail) == 0) {
755 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
756 "%s: !avail mode 0x%x (0x%x) flags 0x%x\n",
757 __func__, modesAvail, cm->mode,
758 cm->flags);
759 continue;
760 }
761 if (!ath9k_get_channel_edges(ah, cm->flags, &c_lo, &c_hi)) {
762 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
763 "%s: channels 0x%x not supported "
764 "by hardware\n",
765 __func__, cm->flags);
766 continue;
767 }
768
769 switch (cm->mode) {
770 case ATH9K_MODE_SEL_11A:
771 case ATH9K_MODE_SEL_11NA_HT20:
772 case ATH9K_MODE_SEL_11NA_HT40PLUS:
773 case ATH9K_MODE_SEL_11NA_HT40MINUS:
774 rd = &rd5GHz;
775 channelBM = rd->chan11a;
776 freqs = &regDmn5GhzFreq[0];
777 ctl = rd->conformanceTestLimit;
778 break;
779 case ATH9K_MODE_SEL_11B:
780 rd = &rd2GHz;
781 channelBM = rd->chan11b;
782 freqs = &regDmn2GhzFreq[0];
783 ctl = rd->conformanceTestLimit | CTL_11B;
784 break;
785 case ATH9K_MODE_SEL_11G:
786 case ATH9K_MODE_SEL_11NG_HT20:
787 case ATH9K_MODE_SEL_11NG_HT40PLUS:
788 case ATH9K_MODE_SEL_11NG_HT40MINUS:
789 rd = &rd2GHz;
790 channelBM = rd->chan11g;
791 freqs = &regDmn2Ghz11gFreq[0];
792 ctl = rd->conformanceTestLimit | CTL_11G;
793 break;
794 default:
795 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
796 "%s: Unknown HAL mode 0x%x\n", __func__,
797 cm->mode);
798 continue;
799 }
800
801 if (ath9k_regd_is_chan_bm_zero(channelBM))
802 continue;
803
804 if ((cm->mode == ATH9K_MODE_SEL_11NA_HT40PLUS) ||
805 (cm->mode == ATH9K_MODE_SEL_11NG_HT40PLUS)) {
806 hi_adj = -20;
807 }
808
809 if ((cm->mode == ATH9K_MODE_SEL_11NA_HT40MINUS) ||
810 (cm->mode == ATH9K_MODE_SEL_11NG_HT40MINUS)) {
811 low_adj = 20;
812 }
813
814 /* XXX: Add a helper here instead */
815 for (b = 0; b < 64 * BMLEN; b++) {
816 if (ath9k_regd_is_bit_set(b, channelBM)) {
817 fband = &freqs[b];
818 if (rd5GHz.regDmnEnum == MKK1
819 || rd5GHz.regDmnEnum == MKK2) {
820 if (ath9k_regd_japan_check(ah,
821 b,
822 &rd5GHz))
823 continue;
824 }
825
826 ath9k_regd_add_reg_classid(regclassids,
827 maxregids,
828 nregids,
829 fband->
830 regClassId);
831
832 if (IS_HT40_MODE(cm->mode) && (rd == &rd5GHz)) {
833 chanSep = 40;
834 if (fband->lowChannel == 5280)
835 low_adj += 20;
836
837 if (fband->lowChannel == 5170)
838 continue;
839 } else
840 chanSep = fband->channelSep;
841
842 for (c = fband->lowChannel + low_adj;
843 ((c <= (fband->highChannel + hi_adj)) &&
844 (c >= (fband->lowChannel + low_adj)));
845 c += chanSep) {
846 if (next >= maxchans) {
847 DPRINTF(ah->ah_sc,
848 ATH_DBG_REGULATORY,
849 "%s: too many channels "
850 "for channel table\n",
851 __func__);
852 goto done;
853 }
854 if (ath9k_regd_add_channel(ah,
855 c, c_lo, c_hi,
856 maxChan, ctl,
857 next,
858 rd5GHz,
859 fband, rd, cm,
860 ichans,
861 enableExtendedChannels))
862 next++;
863 }
864 if (IS_HT40_MODE(cm->mode) &&
865 (fband->lowChannel == 5280)) {
866 low_adj -= 20;
867 }
868 }
869 }
870 }
871done:
872 if (next != 0) {
873 int i;
874
875 if (next > ARRAY_SIZE(ah->ah_channels)) {
876 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
877 "%s: too many channels %u; truncating to %u\n",
878 __func__, next,
879 (int) ARRAY_SIZE(ah->ah_channels));
880 next = ARRAY_SIZE(ah->ah_channels);
881 }
882#ifdef ATH_NF_PER_CHAN
883 ath9k_regd_init_rf_buffer(ichans, next);
884#endif
885 ath9k_regd_sort(ichans, next,
886 sizeof(struct ath9k_channel),
887 ath9k_regd_chansort);
888
889 ah->ah_nchan = next;
890
891 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "Channel list:\n");
892 for (i = 0; i < next; i++) {
893 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
894 "chan: %d flags: 0x%x\n",
895 ah->ah_channels[i].channel,
896 ah->ah_channels[i].channelFlags);
897 }
898 }
899 *nchans = next;
900
901 ah->ah_countryCode = ah->ah_countryCode;
902
903 ah->ah_currentRDInUse = regdmn;
904 ah->ah_currentRD5G = rd5GHz.regDmnEnum;
905 ah->ah_currentRD2G = rd2GHz.regDmnEnum;
906 if (country == NULL) {
907 ah->ah_iso[0] = 0;
908 ah->ah_iso[1] = 0;
909 } else {
910 ah->ah_iso[0] = country->isoName[0];
911 ah->ah_iso[1] = country->isoName[1];
912 }
913
914 return next != 0;
915}
916
917struct ath9k_channel*
918ath9k_regd_check_channel(struct ath_hal *ah,
919 const struct ath9k_channel *c)
920{
921 struct ath9k_channel *base, *cc;
922
923 int flags = c->channelFlags & CHAN_FLAGS;
924 int n, lim;
925
926 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
927 "%s: channel %u/0x%x (0x%x) requested\n", __func__,
928 c->channel, c->channelFlags, flags);
929
930 cc = ah->ah_curchan;
931 if (cc != NULL && cc->channel == c->channel &&
932 (cc->channelFlags & CHAN_FLAGS) == flags) {
933 if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
934 (cc->privFlags & CHANNEL_DFS))
935 return NULL;
936 else
937 return cc;
938 }
939
940 base = ah->ah_channels;
941 n = ah->ah_nchan;
942
943 for (lim = n; lim != 0; lim >>= 1) {
944 int d;
945 cc = &base[lim >> 1];
946 d = c->channel - cc->channel;
947 if (d == 0) {
948 if ((cc->channelFlags & CHAN_FLAGS) == flags) {
949 if ((cc->privFlags & CHANNEL_INTERFERENCE) &&
950 (cc->privFlags & CHANNEL_DFS))
951 return NULL;
952 else
953 return cc;
954 }
955 d = flags - (cc->channelFlags & CHAN_FLAGS);
956 }
957 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
958 "%s: channel %u/0x%x d %d\n", __func__,
959 cc->channel, cc->channelFlags, d);
960 if (d > 0) {
961 base = cc + 1;
962 lim--;
963 }
964 }
965 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY, "%s: no match for %u/0x%x\n",
966 __func__, c->channel, c->channelFlags);
967 return NULL;
968}
969
970u32
971ath9k_regd_get_antenna_allowed(struct ath_hal *ah,
972 struct ath9k_channel *chan)
973{
974 struct ath9k_channel *ichan = NULL;
975
976 ichan = ath9k_regd_check_channel(ah, chan);
977 if (!ichan)
978 return 0;
979
980 return ichan->antennaMax;
981}
982
983u32 ath9k_regd_get_ctl(struct ath_hal *ah, struct ath9k_channel *chan)
984{
985 u32 ctl = NO_CTL;
986 struct ath9k_channel *ichan;
987
988 if (ah->ah_countryCode == CTRY_DEFAULT && isWwrSKU(ah)) {
989 if (IS_CHAN_B(chan))
990 ctl = SD_NO_CTL | CTL_11B;
991 else if (IS_CHAN_G(chan))
992 ctl = SD_NO_CTL | CTL_11G;
993 else
994 ctl = SD_NO_CTL | CTL_11A;
995 } else {
996 ichan = ath9k_regd_check_channel(ah, chan);
997 if (ichan != NULL) {
998 /* FIXME */
999 if (IS_CHAN_A(ichan))
1000 ctl = ichan->conformanceTestLimit[0];
1001 else if (IS_CHAN_B(ichan))
1002 ctl = ichan->conformanceTestLimit[1];
1003 else if (IS_CHAN_G(ichan))
1004 ctl = ichan->conformanceTestLimit[2];
1005
1006 if (IS_CHAN_G(chan) && (ctl & 0xf) == CTL_11B)
1007 ctl = (ctl & ~0xf) | CTL_11G;
1008 }
1009 }
1010 return ctl;
1011}
1012
1013void ath9k_regd_get_current_country(struct ath_hal *ah,
1014 struct ath9k_country_entry *ctry)
1015{
1016 u16 rd = ath9k_regd_get_eepromRD(ah);
1017
1018 ctry->isMultidomain = false;
1019 if (rd == CTRY_DEFAULT)
1020 ctry->isMultidomain = true;
1021 else if (!(rd & COUNTRY_ERD_FLAG))
1022 ctry->isMultidomain = isWwrSKU(ah);
1023
1024 ctry->countryCode = ah->ah_countryCode;
1025 ctry->regDmnEnum = ah->ah_currentRD;
1026 ctry->regDmn5G = ah->ah_currentRD5G;
1027 ctry->regDmn2G = ah->ah_currentRD2G;
1028 ctry->iso[0] = ah->ah_iso[0];
1029 ctry->iso[1] = ah->ah_iso[1];
1030 ctry->iso[2] = ah->ah_iso[2];
1031}
diff --git a/drivers/net/wireless/ath9k/regd.h b/drivers/net/wireless/ath9k/regd.h
new file mode 100644
index 000000000000..ae77496bfde3
--- /dev/null
+++ b/drivers/net/wireless/ath9k/regd.h
@@ -0,0 +1,412 @@
1/*
2 * Copyright (c) 2008 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#ifndef REGD_H
18#define REGD_H
19
20#include "ath9k.h"
21
22#define BMLEN 2
23#define BMZERO {(u64) 0, (u64) 0}
24
25#define BM(_fa, _fb, _fc, _fd, _fe, _ff, _fg, _fh, _fi, _fj, _fk, _fl) \
26 {((((_fa >= 0) && (_fa < 64)) ? \
27 (((u64) 1) << _fa) : (u64) 0) | \
28 (((_fb >= 0) && (_fb < 64)) ? \
29 (((u64) 1) << _fb) : (u64) 0) | \
30 (((_fc >= 0) && (_fc < 64)) ? \
31 (((u64) 1) << _fc) : (u64) 0) | \
32 (((_fd >= 0) && (_fd < 64)) ? \
33 (((u64) 1) << _fd) : (u64) 0) | \
34 (((_fe >= 0) && (_fe < 64)) ? \
35 (((u64) 1) << _fe) : (u64) 0) | \
36 (((_ff >= 0) && (_ff < 64)) ? \
37 (((u64) 1) << _ff) : (u64) 0) | \
38 (((_fg >= 0) && (_fg < 64)) ? \
39 (((u64) 1) << _fg) : (u64) 0) | \
40 (((_fh >= 0) && (_fh < 64)) ? \
41 (((u64) 1) << _fh) : (u64) 0) | \
42 (((_fi >= 0) && (_fi < 64)) ? \
43 (((u64) 1) << _fi) : (u64) 0) | \
44 (((_fj >= 0) && (_fj < 64)) ? \
45 (((u64) 1) << _fj) : (u64) 0) | \
46 (((_fk >= 0) && (_fk < 64)) ? \
47 (((u64) 1) << _fk) : (u64) 0) | \
48 (((_fl >= 0) && (_fl < 64)) ? \
49 (((u64) 1) << _fl) : (u64) 0) | \
50 ((((_fa > 63) && (_fa < 128)) ? \
51 (((u64) 1) << (_fa - 64)) : (u64) 0) | \
52 (((_fb > 63) && (_fb < 128)) ? \
53 (((u64) 1) << (_fb - 64)) : (u64) 0) | \
54 (((_fc > 63) && (_fc < 128)) ? \
55 (((u64) 1) << (_fc - 64)) : (u64) 0) | \
56 (((_fd > 63) && (_fd < 128)) ? \
57 (((u64) 1) << (_fd - 64)) : (u64) 0) | \
58 (((_fe > 63) && (_fe < 128)) ? \
59 (((u64) 1) << (_fe - 64)) : (u64) 0) | \
60 (((_ff > 63) && (_ff < 128)) ? \
61 (((u64) 1) << (_ff - 64)) : (u64) 0) | \
62 (((_fg > 63) && (_fg < 128)) ? \
63 (((u64) 1) << (_fg - 64)) : (u64) 0) | \
64 (((_fh > 63) && (_fh < 128)) ? \
65 (((u64) 1) << (_fh - 64)) : (u64) 0) | \
66 (((_fi > 63) && (_fi < 128)) ? \
67 (((u64) 1) << (_fi - 64)) : (u64) 0) | \
68 (((_fj > 63) && (_fj < 128)) ? \
69 (((u64) 1) << (_fj - 64)) : (u64) 0) | \
70 (((_fk > 63) && (_fk < 128)) ? \
71 (((u64) 1) << (_fk - 64)) : (u64) 0) | \
72 (((_fl > 63) && (_fl < 128)) ? \
73 (((u64) 1) << (_fl - 64)) : (u64) 0)))}
74
75#define DEF_REGDMN FCC1_FCCA
76#define DEF_DMN_5 FCC1
77#define DEF_DMN_2 FCCA
78#define COUNTRY_ERD_FLAG 0x8000
79#define WORLDWIDE_ROAMING_FLAG 0x4000
80#define SUPER_DOMAIN_MASK 0x0fff
81#define COUNTRY_CODE_MASK 0x3fff
82#define CF_INTERFERENCE (CHANNEL_CW_INT | CHANNEL_RADAR_INT)
83#define CHANNEL_14 (2484)
84#define IS_11G_CH14(_ch,_cf) \
85 (((_ch) == CHANNEL_14) && ((_cf) == CHANNEL_G))
86
87#define NO_PSCAN 0x0ULL
88#define PSCAN_FCC 0x0000000000000001ULL
89#define PSCAN_FCC_T 0x0000000000000002ULL
90#define PSCAN_ETSI 0x0000000000000004ULL
91#define PSCAN_MKK1 0x0000000000000008ULL
92#define PSCAN_MKK2 0x0000000000000010ULL
93#define PSCAN_MKKA 0x0000000000000020ULL
94#define PSCAN_MKKA_G 0x0000000000000040ULL
95#define PSCAN_ETSIA 0x0000000000000080ULL
96#define PSCAN_ETSIB 0x0000000000000100ULL
97#define PSCAN_ETSIC 0x0000000000000200ULL
98#define PSCAN_WWR 0x0000000000000400ULL
99#define PSCAN_MKKA1 0x0000000000000800ULL
100#define PSCAN_MKKA1_G 0x0000000000001000ULL
101#define PSCAN_MKKA2 0x0000000000002000ULL
102#define PSCAN_MKKA2_G 0x0000000000004000ULL
103#define PSCAN_MKK3 0x0000000000008000ULL
104#define PSCAN_DEFER 0x7FFFFFFFFFFFFFFFULL
105#define IS_ECM_CHAN 0x8000000000000000ULL
106
107#define isWwrSKU(_ah) \
108 (((ath9k_regd_get_eepromRD((_ah)) & WORLD_SKU_MASK) == \
109 WORLD_SKU_PREFIX) || \
110 (ath9k_regd_get_eepromRD(_ah) == WORLD))
111
112#define isWwrSKU_NoMidband(_ah) \
113 ((ath9k_regd_get_eepromRD((_ah)) == WOR3_WORLD) || \
114 (ath9k_regd_get_eepromRD(_ah) == WOR4_WORLD) || \
115 (ath9k_regd_get_eepromRD(_ah) == WOR5_ETSIC))
116
117#define isUNII1OddChan(ch) \
118 ((ch == 5170) || (ch == 5190) || (ch == 5210) || (ch == 5230))
119
120#define IS_HT40_MODE(_mode) \
121 (((_mode == ATH9K_MODE_SEL_11NA_HT40PLUS || \
122 _mode == ATH9K_MODE_SEL_11NG_HT40PLUS || \
123 _mode == ATH9K_MODE_SEL_11NA_HT40MINUS || \
124 _mode == ATH9K_MODE_SEL_11NG_HT40MINUS) ? true : false))
125
126#define CHAN_FLAGS (CHANNEL_ALL|CHANNEL_HALF|CHANNEL_QUARTER)
127
128#define swap(_a, _b, _size) { \
129 u8 *s = _b; \
130 int i = _size; \
131 do { \
132 u8 tmp = *_a; \
133 *_a++ = *s; \
134 *s++ = tmp; \
135 } while (--i); \
136 _a -= _size; \
137}
138
139
140#define HALF_MAXCHANBW 10
141
142#define MULTI_DOMAIN_MASK 0xFF00
143
144#define WORLD_SKU_MASK 0x00F0
145#define WORLD_SKU_PREFIX 0x0060
146
147#define CHANNEL_HALF_BW 10
148#define CHANNEL_QUARTER_BW 5
149
150typedef int ath_hal_cmp_t(const void *, const void *);
151
152struct reg_dmn_pair_mapping {
153 u16 regDmnEnum;
154 u16 regDmn5GHz;
155 u16 regDmn2GHz;
156 u32 flags5GHz;
157 u32 flags2GHz;
158 u64 pscanMask;
159 u16 singleCC;
160};
161
162struct ccmap {
163 char isoName[3];
164 u16 countryCode;
165};
166
167struct country_code_to_enum_rd {
168 u16 countryCode;
169 u16 regDmnEnum;
170 const char *isoName;
171 const char *name;
172 bool allow11g;
173 bool allow11aTurbo;
174 bool allow11gTurbo;
175 bool allow11ng20;
176 bool allow11ng40;
177 bool allow11na20;
178 bool allow11na40;
179 u16 outdoorChanStart;
180};
181
182struct RegDmnFreqBand {
183 u16 lowChannel;
184 u16 highChannel;
185 u8 powerDfs;
186 u8 antennaMax;
187 u8 channelBW;
188 u8 channelSep;
189 u64 useDfs;
190 u64 usePassScan;
191 u8 regClassId;
192};
193
194struct regDomain {
195 u16 regDmnEnum;
196 u8 conformanceTestLimit;
197 u64 dfsMask;
198 u64 pscan;
199 u32 flags;
200 u64 chan11a[BMLEN];
201 u64 chan11a_turbo[BMLEN];
202 u64 chan11a_dyn_turbo[BMLEN];
203 u64 chan11b[BMLEN];
204 u64 chan11g[BMLEN];
205 u64 chan11g_turbo[BMLEN];
206};
207
208struct cmode {
209 u32 mode;
210 u32 flags;
211};
212
213#define YES true
214#define NO false
215
216struct japan_bandcheck {
217 u16 freqbandbit;
218 u32 eepromflagtocheck;
219};
220
221struct common_mode_power {
222 u16 lchan;
223 u16 hchan;
224 u8 pwrlvl;
225};
226
227enum CountryCode {
228 CTRY_ALBANIA = 8,
229 CTRY_ALGERIA = 12,
230 CTRY_ARGENTINA = 32,
231 CTRY_ARMENIA = 51,
232 CTRY_AUSTRALIA = 36,
233 CTRY_AUSTRIA = 40,
234 CTRY_AZERBAIJAN = 31,
235 CTRY_BAHRAIN = 48,
236 CTRY_BELARUS = 112,
237 CTRY_BELGIUM = 56,
238 CTRY_BELIZE = 84,
239 CTRY_BOLIVIA = 68,
240 CTRY_BOSNIA_HERZ = 70,
241 CTRY_BRAZIL = 76,
242 CTRY_BRUNEI_DARUSSALAM = 96,
243 CTRY_BULGARIA = 100,
244 CTRY_CANADA = 124,
245 CTRY_CHILE = 152,
246 CTRY_CHINA = 156,
247 CTRY_COLOMBIA = 170,
248 CTRY_COSTA_RICA = 188,
249 CTRY_CROATIA = 191,
250 CTRY_CYPRUS = 196,
251 CTRY_CZECH = 203,
252 CTRY_DENMARK = 208,
253 CTRY_DOMINICAN_REPUBLIC = 214,
254 CTRY_ECUADOR = 218,
255 CTRY_EGYPT = 818,
256 CTRY_EL_SALVADOR = 222,
257 CTRY_ESTONIA = 233,
258 CTRY_FAEROE_ISLANDS = 234,
259 CTRY_FINLAND = 246,
260 CTRY_FRANCE = 250,
261 CTRY_GEORGIA = 268,
262 CTRY_GERMANY = 276,
263 CTRY_GREECE = 300,
264 CTRY_GUATEMALA = 320,
265 CTRY_HONDURAS = 340,
266 CTRY_HONG_KONG = 344,
267 CTRY_HUNGARY = 348,
268 CTRY_ICELAND = 352,
269 CTRY_INDIA = 356,
270 CTRY_INDONESIA = 360,
271 CTRY_IRAN = 364,
272 CTRY_IRAQ = 368,
273 CTRY_IRELAND = 372,
274 CTRY_ISRAEL = 376,
275 CTRY_ITALY = 380,
276 CTRY_JAMAICA = 388,
277 CTRY_JAPAN = 392,
278 CTRY_JORDAN = 400,
279 CTRY_KAZAKHSTAN = 398,
280 CTRY_KENYA = 404,
281 CTRY_KOREA_NORTH = 408,
282 CTRY_KOREA_ROC = 410,
283 CTRY_KOREA_ROC2 = 411,
284 CTRY_KOREA_ROC3 = 412,
285 CTRY_KUWAIT = 414,
286 CTRY_LATVIA = 428,
287 CTRY_LEBANON = 422,
288 CTRY_LIBYA = 434,
289 CTRY_LIECHTENSTEIN = 438,
290 CTRY_LITHUANIA = 440,
291 CTRY_LUXEMBOURG = 442,
292 CTRY_MACAU = 446,
293 CTRY_MACEDONIA = 807,
294 CTRY_MALAYSIA = 458,
295 CTRY_MALTA = 470,
296 CTRY_MEXICO = 484,
297 CTRY_MONACO = 492,
298 CTRY_MOROCCO = 504,
299 CTRY_NEPAL = 524,
300 CTRY_NETHERLANDS = 528,
301 CTRY_NETHERLANDS_ANTILLES = 530,
302 CTRY_NEW_ZEALAND = 554,
303 CTRY_NICARAGUA = 558,
304 CTRY_NORWAY = 578,
305 CTRY_OMAN = 512,
306 CTRY_PAKISTAN = 586,
307 CTRY_PANAMA = 591,
308 CTRY_PAPUA_NEW_GUINEA = 598,
309 CTRY_PARAGUAY = 600,
310 CTRY_PERU = 604,
311 CTRY_PHILIPPINES = 608,
312 CTRY_POLAND = 616,
313 CTRY_PORTUGAL = 620,
314 CTRY_PUERTO_RICO = 630,
315 CTRY_QATAR = 634,
316 CTRY_ROMANIA = 642,
317 CTRY_RUSSIA = 643,
318 CTRY_SAUDI_ARABIA = 682,
319 CTRY_SERBIA_MONTENEGRO = 891,
320 CTRY_SINGAPORE = 702,
321 CTRY_SLOVAKIA = 703,
322 CTRY_SLOVENIA = 705,
323 CTRY_SOUTH_AFRICA = 710,
324 CTRY_SPAIN = 724,
325 CTRY_SRI_LANKA = 144,
326 CTRY_SWEDEN = 752,
327 CTRY_SWITZERLAND = 756,
328 CTRY_SYRIA = 760,
329 CTRY_TAIWAN = 158,
330 CTRY_THAILAND = 764,
331 CTRY_TRINIDAD_Y_TOBAGO = 780,
332 CTRY_TUNISIA = 788,
333 CTRY_TURKEY = 792,
334 CTRY_UAE = 784,
335 CTRY_UKRAINE = 804,
336 CTRY_UNITED_KINGDOM = 826,
337 CTRY_UNITED_STATES = 840,
338 CTRY_UNITED_STATES_FCC49 = 842,
339 CTRY_URUGUAY = 858,
340 CTRY_UZBEKISTAN = 860,
341 CTRY_VENEZUELA = 862,
342 CTRY_VIET_NAM = 704,
343 CTRY_YEMEN = 887,
344 CTRY_ZIMBABWE = 716,
345 CTRY_JAPAN1 = 393,
346 CTRY_JAPAN2 = 394,
347 CTRY_JAPAN3 = 395,
348 CTRY_JAPAN4 = 396,
349 CTRY_JAPAN5 = 397,
350 CTRY_JAPAN6 = 4006,
351 CTRY_JAPAN7 = 4007,
352 CTRY_JAPAN8 = 4008,
353 CTRY_JAPAN9 = 4009,
354 CTRY_JAPAN10 = 4010,
355 CTRY_JAPAN11 = 4011,
356 CTRY_JAPAN12 = 4012,
357 CTRY_JAPAN13 = 4013,
358 CTRY_JAPAN14 = 4014,
359 CTRY_JAPAN15 = 4015,
360 CTRY_JAPAN16 = 4016,
361 CTRY_JAPAN17 = 4017,
362 CTRY_JAPAN18 = 4018,
363 CTRY_JAPAN19 = 4019,
364 CTRY_JAPAN20 = 4020,
365 CTRY_JAPAN21 = 4021,
366 CTRY_JAPAN22 = 4022,
367 CTRY_JAPAN23 = 4023,
368 CTRY_JAPAN24 = 4024,
369 CTRY_JAPAN25 = 4025,
370 CTRY_JAPAN26 = 4026,
371 CTRY_JAPAN27 = 4027,
372 CTRY_JAPAN28 = 4028,
373 CTRY_JAPAN29 = 4029,
374 CTRY_JAPAN30 = 4030,
375 CTRY_JAPAN31 = 4031,
376 CTRY_JAPAN32 = 4032,
377 CTRY_JAPAN33 = 4033,
378 CTRY_JAPAN34 = 4034,
379 CTRY_JAPAN35 = 4035,
380 CTRY_JAPAN36 = 4036,
381 CTRY_JAPAN37 = 4037,
382 CTRY_JAPAN38 = 4038,
383 CTRY_JAPAN39 = 4039,
384 CTRY_JAPAN40 = 4040,
385 CTRY_JAPAN41 = 4041,
386 CTRY_JAPAN42 = 4042,
387 CTRY_JAPAN43 = 4043,
388 CTRY_JAPAN44 = 4044,
389 CTRY_JAPAN45 = 4045,
390 CTRY_JAPAN46 = 4046,
391 CTRY_JAPAN47 = 4047,
392 CTRY_JAPAN48 = 4048,
393 CTRY_JAPAN49 = 4049,
394 CTRY_JAPAN50 = 4050,
395 CTRY_JAPAN51 = 4051,
396 CTRY_JAPAN52 = 4052,
397 CTRY_JAPAN53 = 4053,
398 CTRY_JAPAN54 = 4054,
399 CTRY_JAPAN55 = 4055,
400 CTRY_JAPAN56 = 4056,
401 CTRY_JAPAN57 = 4057,
402 CTRY_JAPAN58 = 4058,
403 CTRY_JAPAN59 = 4059,
404 CTRY_AUSTRALIA2 = 5000,
405 CTRY_CANADA2 = 5001,
406 CTRY_BELGIUM2 = 5002
407};
408
409void ath9k_regd_get_current_country(struct ath_hal *ah,
410 struct ath9k_country_entry *ctry);
411
412#endif
diff --git a/drivers/net/wireless/ath9k/regd_common.h b/drivers/net/wireless/ath9k/regd_common.h
new file mode 100644
index 000000000000..b3bfae4fc99c
--- /dev/null
+++ b/drivers/net/wireless/ath9k/regd_common.h
@@ -0,0 +1,1915 @@
1/*
2 * Copyright (c) 2008 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#ifndef REGD_COMMON_H
18#define REGD_COMMON_H
19
20enum EnumRd {
21 NO_ENUMRD = 0x00,
22 NULL1_WORLD = 0x03,
23 NULL1_ETSIB = 0x07,
24 NULL1_ETSIC = 0x08,
25 FCC1_FCCA = 0x10,
26 FCC1_WORLD = 0x11,
27 FCC4_FCCA = 0x12,
28 FCC5_FCCA = 0x13,
29 FCC6_FCCA = 0x14,
30
31 FCC2_FCCA = 0x20,
32 FCC2_WORLD = 0x21,
33 FCC2_ETSIC = 0x22,
34 FCC6_WORLD = 0x23,
35 FRANCE_RES = 0x31,
36 FCC3_FCCA = 0x3A,
37 FCC3_WORLD = 0x3B,
38
39 ETSI1_WORLD = 0x37,
40 ETSI3_ETSIA = 0x32,
41 ETSI2_WORLD = 0x35,
42 ETSI3_WORLD = 0x36,
43 ETSI4_WORLD = 0x30,
44 ETSI4_ETSIC = 0x38,
45 ETSI5_WORLD = 0x39,
46 ETSI6_WORLD = 0x34,
47 ETSI_RESERVED = 0x33,
48
49 MKK1_MKKA = 0x40,
50 MKK1_MKKB = 0x41,
51 APL4_WORLD = 0x42,
52 MKK2_MKKA = 0x43,
53 APL_RESERVED = 0x44,
54 APL2_WORLD = 0x45,
55 APL2_APLC = 0x46,
56 APL3_WORLD = 0x47,
57 MKK1_FCCA = 0x48,
58 APL2_APLD = 0x49,
59 MKK1_MKKA1 = 0x4A,
60 MKK1_MKKA2 = 0x4B,
61 MKK1_MKKC = 0x4C,
62
63 APL3_FCCA = 0x50,
64 APL1_WORLD = 0x52,
65 APL1_FCCA = 0x53,
66 APL1_APLA = 0x54,
67 APL1_ETSIC = 0x55,
68 APL2_ETSIC = 0x56,
69 APL5_WORLD = 0x58,
70 APL6_WORLD = 0x5B,
71 APL7_FCCA = 0x5C,
72 APL8_WORLD = 0x5D,
73 APL9_WORLD = 0x5E,
74
75 WOR0_WORLD = 0x60,
76 WOR1_WORLD = 0x61,
77 WOR2_WORLD = 0x62,
78 WOR3_WORLD = 0x63,
79 WOR4_WORLD = 0x64,
80 WOR5_ETSIC = 0x65,
81
82 WOR01_WORLD = 0x66,
83 WOR02_WORLD = 0x67,
84 EU1_WORLD = 0x68,
85
86 WOR9_WORLD = 0x69,
87 WORA_WORLD = 0x6A,
88 WORB_WORLD = 0x6B,
89
90 MKK3_MKKB = 0x80,
91 MKK3_MKKA2 = 0x81,
92 MKK3_MKKC = 0x82,
93
94 MKK4_MKKB = 0x83,
95 MKK4_MKKA2 = 0x84,
96 MKK4_MKKC = 0x85,
97
98 MKK5_MKKB = 0x86,
99 MKK5_MKKA2 = 0x87,
100 MKK5_MKKC = 0x88,
101
102 MKK6_MKKB = 0x89,
103 MKK6_MKKA2 = 0x8A,
104 MKK6_MKKC = 0x8B,
105
106 MKK7_MKKB = 0x8C,
107 MKK7_MKKA2 = 0x8D,
108 MKK7_MKKC = 0x8E,
109
110 MKK8_MKKB = 0x8F,
111 MKK8_MKKA2 = 0x90,
112 MKK8_MKKC = 0x91,
113
114 MKK14_MKKA1 = 0x92,
115 MKK15_MKKA1 = 0x93,
116
117 MKK10_FCCA = 0xD0,
118 MKK10_MKKA1 = 0xD1,
119 MKK10_MKKC = 0xD2,
120 MKK10_MKKA2 = 0xD3,
121
122 MKK11_MKKA = 0xD4,
123 MKK11_FCCA = 0xD5,
124 MKK11_MKKA1 = 0xD6,
125 MKK11_MKKC = 0xD7,
126 MKK11_MKKA2 = 0xD8,
127
128 MKK12_MKKA = 0xD9,
129 MKK12_FCCA = 0xDA,
130 MKK12_MKKA1 = 0xDB,
131 MKK12_MKKC = 0xDC,
132 MKK12_MKKA2 = 0xDD,
133
134 MKK13_MKKB = 0xDE,
135
136 MKK3_MKKA = 0xF0,
137 MKK3_MKKA1 = 0xF1,
138 MKK3_FCCA = 0xF2,
139 MKK4_MKKA = 0xF3,
140 MKK4_MKKA1 = 0xF4,
141 MKK4_FCCA = 0xF5,
142 MKK9_MKKA = 0xF6,
143 MKK10_MKKA = 0xF7,
144 MKK6_MKKA1 = 0xF8,
145 MKK6_FCCA = 0xF9,
146 MKK7_MKKA1 = 0xFA,
147 MKK7_FCCA = 0xFB,
148 MKK9_FCCA = 0xFC,
149 MKK9_MKKA1 = 0xFD,
150 MKK9_MKKC = 0xFE,
151 MKK9_MKKA2 = 0xFF,
152
153 APL1 = 0x0150,
154 APL2 = 0x0250,
155 APL3 = 0x0350,
156 APL4 = 0x0450,
157 APL5 = 0x0550,
158 APL6 = 0x0650,
159 APL7 = 0x0750,
160 APL8 = 0x0850,
161 APL9 = 0x0950,
162 APL10 = 0x1050,
163
164 ETSI1 = 0x0130,
165 ETSI2 = 0x0230,
166 ETSI3 = 0x0330,
167 ETSI4 = 0x0430,
168 ETSI5 = 0x0530,
169 ETSI6 = 0x0630,
170 ETSIA = 0x0A30,
171 ETSIB = 0x0B30,
172 ETSIC = 0x0C30,
173
174 FCC1 = 0x0110,
175 FCC2 = 0x0120,
176 FCC3 = 0x0160,
177 FCC4 = 0x0165,
178 FCC5 = 0x0510,
179 FCC6 = 0x0610,
180 FCCA = 0x0A10,
181
182 APLD = 0x0D50,
183
184 MKK1 = 0x0140,
185 MKK2 = 0x0240,
186 MKK3 = 0x0340,
187 MKK4 = 0x0440,
188 MKK5 = 0x0540,
189 MKK6 = 0x0640,
190 MKK7 = 0x0740,
191 MKK8 = 0x0840,
192 MKK9 = 0x0940,
193 MKK10 = 0x0B40,
194 MKK11 = 0x1140,
195 MKK12 = 0x1240,
196 MKK13 = 0x0C40,
197 MKK14 = 0x1440,
198 MKK15 = 0x1540,
199 MKKA = 0x0A40,
200 MKKC = 0x0A50,
201
202 NULL1 = 0x0198,
203 WORLD = 0x0199,
204 DEBUG_REG_DMN = 0x01ff,
205};
206
207enum {
208 FCC = 0x10,
209 MKK = 0x40,
210 ETSI = 0x30,
211};
212
213enum {
214 NO_REQ = 0x00000000,
215 DISALLOW_ADHOC_11A = 0x00000001,
216 DISALLOW_ADHOC_11A_TURB = 0x00000002,
217 NEED_NFC = 0x00000004,
218
219 ADHOC_PER_11D = 0x00000008,
220 ADHOC_NO_11A = 0x00000010,
221
222 PUBLIC_SAFETY_DOMAIN = 0x00000020,
223 LIMIT_FRAME_4MS = 0x00000040,
224
225 NO_HOSTAP = 0x00000080,
226
227 REQ_MASK = 0x000000FF,
228};
229
230#define REG_DOMAIN_2GHZ_MASK (REQ_MASK & \
231 (!(ADHOC_NO_11A | DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB)))
232#define REG_DOMAIN_5GHZ_MASK REQ_MASK
233
234static struct reg_dmn_pair_mapping regDomainPairs[] = {
235 {NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN, NO_REQ, NO_REQ,
236 PSCAN_DEFER, 0},
237 {NULL1_WORLD, NULL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
238 {NULL1_ETSIB, NULL1, ETSIB, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
239 {NULL1_ETSIC, NULL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
240
241 {FCC2_FCCA, FCC2, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
242 {FCC2_WORLD, FCC2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
243 {FCC2_ETSIC, FCC2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
244 {FCC3_FCCA, FCC3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
245 {FCC3_WORLD, FCC3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
246 {FCC4_FCCA, FCC4, FCCA,
247 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
248 0},
249 {FCC5_FCCA, FCC5, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
250 {FCC6_FCCA, FCC6, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
251 {FCC6_WORLD, FCC6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
252
253 {ETSI1_WORLD, ETSI1, WORLD,
254 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
255 0},
256 {ETSI2_WORLD, ETSI2, WORLD,
257 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
258 0},
259 {ETSI3_WORLD, ETSI3, WORLD,
260 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
261 0},
262 {ETSI4_WORLD, ETSI4, WORLD,
263 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
264 0},
265 {ETSI5_WORLD, ETSI5, WORLD,
266 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
267 0},
268 {ETSI6_WORLD, ETSI6, WORLD,
269 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
270 0},
271
272 {ETSI3_ETSIA, ETSI3, WORLD,
273 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
274 0},
275 {FRANCE_RES, ETSI3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
276
277 {FCC1_WORLD, FCC1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
278 {FCC1_FCCA, FCC1, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
279 {APL1_WORLD, APL1, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
280 {APL2_WORLD, APL2, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
281 {APL3_WORLD, APL3, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
282 {APL4_WORLD, APL4, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
283 {APL5_WORLD, APL5, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
284 {APL6_WORLD, APL6, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
285 {APL8_WORLD, APL8, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
286 {APL9_WORLD, APL9, WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
287
288 {APL3_FCCA, APL3, FCCA, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
289 {APL1_ETSIC, APL1, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
290 {APL2_ETSIC, APL2, ETSIC, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
291 {APL2_APLD, APL2, APLD, NO_REQ, NO_REQ, PSCAN_DEFER,},
292
293 {MKK1_MKKA, MKK1, MKKA,
294 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
295 PSCAN_MKK1 | PSCAN_MKKA, CTRY_JAPAN},
296 {MKK1_MKKB, MKK1, MKKA,
297 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
298 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G,
299 CTRY_JAPAN1},
300 {MKK1_FCCA, MKK1, FCCA,
301 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
302 PSCAN_MKK1, CTRY_JAPAN2},
303 {MKK1_MKKA1, MKK1, MKKA,
304 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
305 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN4},
306 {MKK1_MKKA2, MKK1, MKKA,
307 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
308 PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN5},
309 {MKK1_MKKC, MKK1, MKKC,
310 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
311 PSCAN_MKK1, CTRY_JAPAN6},
312
313 {MKK2_MKKA, MKK2, MKKA,
314 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
315 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKKA | PSCAN_MKKA_G,
316 CTRY_JAPAN3},
317
318 {MKK3_MKKA, MKK3, MKKA,
319 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
320 PSCAN_MKKA, CTRY_JAPAN25},
321 {MKK3_MKKB, MKK3, MKKA,
322 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
323 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKKA | PSCAN_MKKA_G,
324 CTRY_JAPAN7},
325 {MKK3_MKKA1, MKK3, MKKA,
326 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
327 PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN26},
328 {MKK3_MKKA2, MKK3, MKKA,
329 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
330 PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN8},
331 {MKK3_MKKC, MKK3, MKKC,
332 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
333 NO_PSCAN, CTRY_JAPAN9},
334 {MKK3_FCCA, MKK3, FCCA,
335 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
336 NO_PSCAN, CTRY_JAPAN27},
337
338 {MKK4_MKKA, MKK4, MKKA,
339 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
340 PSCAN_MKK3, CTRY_JAPAN36},
341 {MKK4_MKKB, MKK4, MKKA,
342 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
343 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
344 CTRY_JAPAN10},
345 {MKK4_MKKA1, MKK4, MKKA,
346 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
347 PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN28},
348 {MKK4_MKKA2, MKK4, MKKA,
349 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
350 PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN11},
351 {MKK4_MKKC, MKK4, MKKC,
352 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
353 PSCAN_MKK3, CTRY_JAPAN12},
354 {MKK4_FCCA, MKK4, FCCA,
355 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
356 PSCAN_MKK3, CTRY_JAPAN29},
357
358 {MKK5_MKKB, MKK5, MKKA,
359 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
360 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
361 CTRY_JAPAN13},
362 {MKK5_MKKA2, MKK5, MKKA,
363 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
364 PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN14},
365 {MKK5_MKKC, MKK5, MKKC,
366 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
367 PSCAN_MKK3, CTRY_JAPAN15},
368
369 {MKK6_MKKB, MKK6, MKKA,
370 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
371 PSCAN_MKK1 | PSCAN_MKKA | PSCAN_MKKA_G, CTRY_JAPAN16},
372 {MKK6_MKKA1, MKK6, MKKA,
373 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
374 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN30},
375 {MKK6_MKKA2, MKK6, MKKA,
376 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
377 PSCAN_MKK1 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN17},
378 {MKK6_MKKC, MKK6, MKKC,
379 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
380 PSCAN_MKK1, CTRY_JAPAN18},
381 {MKK6_FCCA, MKK6, FCCA,
382 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
383 NO_PSCAN, CTRY_JAPAN31},
384
385 {MKK7_MKKB, MKK7, MKKA,
386 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
387 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
388 CTRY_JAPAN19},
389 {MKK7_MKKA1, MKK7, MKKA,
390 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
391 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN32},
392 {MKK7_MKKA2, MKK7, MKKA,
393 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
394 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
395 CTRY_JAPAN20},
396 {MKK7_MKKC, MKK7, MKKC,
397 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
398 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN21},
399 {MKK7_FCCA, MKK7, FCCA,
400 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
401 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN33},
402
403 {MKK8_MKKB, MKK8, MKKA,
404 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
405 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
406 CTRY_JAPAN22},
407 {MKK8_MKKA2, MKK8, MKKA,
408 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
409 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
410 CTRY_JAPAN23},
411 {MKK8_MKKC, MKK8, MKKC,
412 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
413 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN24},
414
415 {MKK9_MKKA, MKK9, MKKA,
416 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
417 LIMIT_FRAME_4MS, NEED_NFC,
418 PSCAN_MKK2 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
419 CTRY_JAPAN34},
420 {MKK9_FCCA, MKK9, FCCA,
421 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
422 NO_PSCAN, CTRY_JAPAN37},
423 {MKK9_MKKA1, MKK9, MKKA,
424 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
425 PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN38},
426 {MKK9_MKKA2, MKK9, MKKA,
427 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
428 PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN40},
429 {MKK9_MKKC, MKK9, MKKC,
430 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
431 NO_PSCAN, CTRY_JAPAN39},
432
433 {MKK10_MKKA, MKK10, MKKA,
434 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
435 LIMIT_FRAME_4MS, NEED_NFC, PSCAN_MKK2 | PSCAN_MKK3, CTRY_JAPAN35},
436 {MKK10_FCCA, MKK10, FCCA,
437 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
438 NO_PSCAN, CTRY_JAPAN41},
439 {MKK10_MKKA1, MKK10, MKKA,
440 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
441 PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN42},
442 {MKK10_MKKA2, MKK10, MKKA,
443 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
444 PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN44},
445 {MKK10_MKKC, MKK10, MKKC,
446 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
447 NO_PSCAN, CTRY_JAPAN43},
448
449 {MKK11_MKKA, MKK11, MKKA,
450 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
451 PSCAN_MKK3, CTRY_JAPAN45},
452 {MKK11_FCCA, MKK11, FCCA,
453 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
454 PSCAN_MKK3, CTRY_JAPAN46},
455 {MKK11_MKKA1, MKK11, MKKA,
456 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
457 PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN47},
458 {MKK11_MKKA2, MKK11, MKKA,
459 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
460 PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G, CTRY_JAPAN49},
461 {MKK11_MKKC, MKK11, MKKC,
462 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
463 PSCAN_MKK3, CTRY_JAPAN48},
464
465 {MKK12_MKKA, MKK12, MKKA,
466 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
467 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN50},
468 {MKK12_FCCA, MKK12, FCCA,
469 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
470 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN51},
471 {MKK12_MKKA1, MKK12, MKKA,
472 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
473 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA1 | PSCAN_MKKA1_G,
474 CTRY_JAPAN52},
475 {MKK12_MKKA2, MKK12, MKKA,
476 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
477 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA2 | PSCAN_MKKA2_G,
478 CTRY_JAPAN54},
479 {MKK12_MKKC, MKK12, MKKC,
480 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
481 PSCAN_MKK1 | PSCAN_MKK3, CTRY_JAPAN53},
482
483 {MKK13_MKKB, MKK13, MKKA,
484 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB | NEED_NFC |
485 LIMIT_FRAME_4MS, NEED_NFC,
486 PSCAN_MKK1 | PSCAN_MKK3 | PSCAN_MKKA | PSCAN_MKKA_G,
487 CTRY_JAPAN57},
488
489 {MKK14_MKKA1, MKK14, MKKA,
490 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
491 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN58},
492 {MKK15_MKKA1, MKK15, MKKA,
493 DISALLOW_ADHOC_11A_TURB | NEED_NFC | LIMIT_FRAME_4MS, NEED_NFC,
494 PSCAN_MKK1 | PSCAN_MKKA1 | PSCAN_MKKA1_G, CTRY_JAPAN59},
495
496 {WOR0_WORLD, WOR0_WORLD, WOR0_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
497 0},
498 {WOR1_WORLD, WOR1_WORLD, WOR1_WORLD,
499 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
500 0},
501 {WOR2_WORLD, WOR2_WORLD, WOR2_WORLD, DISALLOW_ADHOC_11A_TURB,
502 NO_REQ, PSCAN_DEFER, 0},
503 {WOR3_WORLD, WOR3_WORLD, WOR3_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER,
504 0},
505 {WOR4_WORLD, WOR4_WORLD, WOR4_WORLD,
506 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
507 0},
508 {WOR5_ETSIC, WOR5_ETSIC, WOR5_ETSIC,
509 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
510 0},
511 {WOR01_WORLD, WOR01_WORLD, WOR01_WORLD, NO_REQ, NO_REQ,
512 PSCAN_DEFER, 0},
513 {WOR02_WORLD, WOR02_WORLD, WOR02_WORLD, NO_REQ, NO_REQ,
514 PSCAN_DEFER, 0},
515 {EU1_WORLD, EU1_WORLD, EU1_WORLD, NO_REQ, NO_REQ, PSCAN_DEFER, 0},
516 {WOR9_WORLD, WOR9_WORLD, WOR9_WORLD,
517 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
518 0},
519 {WORA_WORLD, WORA_WORLD, WORA_WORLD,
520 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
521 0},
522 {WORB_WORLD, WORB_WORLD, WORB_WORLD,
523 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB, NO_REQ, PSCAN_DEFER,
524 0},
525};
526
527#define NO_INTERSECT_REQ 0xFFFFFFFF
528#define NO_UNION_REQ 0
529
530static struct country_code_to_enum_rd allCountries[] = {
531 {CTRY_DEBUG, NO_ENUMRD, "DB", "DEBUG", YES, YES, YES, YES, YES,
532 YES, YES, 7000},
533 {CTRY_DEFAULT, DEF_REGDMN, "NA", "NO_COUNTRY_SET", YES, YES, YES,
534 YES, YES, YES, YES, 7000},
535 {CTRY_ALBANIA, NULL1_WORLD, "AL", "ALBANIA", YES, NO, YES, YES, NO,
536 NO, NO, 7000},
537 {CTRY_ALGERIA, NULL1_WORLD, "DZ", "ALGERIA", YES, NO, YES, YES, NO,
538 NO, NO, 7000},
539 {CTRY_ARGENTINA, APL3_WORLD, "AR", "ARGENTINA", YES, NO, NO, YES,
540 NO, YES, NO, 7000},
541 {CTRY_ARMENIA, ETSI4_WORLD, "AM", "ARMENIA", YES, NO, YES, YES,
542 YES, NO, NO, 7000},
543 {CTRY_AUSTRALIA, FCC2_WORLD, "AU", "AUSTRALIA", YES, YES, YES, YES,
544 YES, YES, YES, 7000},
545 {CTRY_AUSTRALIA2, FCC6_WORLD, "AU", "AUSTRALIA2", YES, YES, YES,
546 YES, YES, YES, YES, 7000},
547 {CTRY_AUSTRIA, ETSI1_WORLD, "AT", "AUSTRIA", YES, NO, YES, YES,
548 YES, YES, YES, 7000},
549 {CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ", "AZERBAIJAN", YES, YES, YES,
550 YES, YES, YES, YES, 7000},
551 {CTRY_BAHRAIN, APL6_WORLD, "BH", "BAHRAIN", YES, NO, YES, YES, YES,
552 YES, NO, 7000},
553 {CTRY_BELARUS, ETSI1_WORLD, "BY", "BELARUS", YES, NO, YES, YES,
554 YES, YES, YES, 7000},
555 {CTRY_BELGIUM, ETSI1_WORLD, "BE", "BELGIUM", YES, NO, YES, YES,
556 YES, YES, YES, 7000},
557 {CTRY_BELGIUM2, ETSI4_WORLD, "BL", "BELGIUM", YES, NO, YES, YES,
558 YES, YES, YES, 7000},
559 {CTRY_BELIZE, APL1_ETSIC, "BZ", "BELIZE", YES, YES, YES, YES, YES,
560 YES, YES, 7000},
561 {CTRY_BOLIVIA, APL1_ETSIC, "BO", "BOLVIA", YES, YES, YES, YES, YES,
562 YES, YES, 7000},
563 {CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA", "BOSNIA_HERZGOWINA", YES, NO,
564 YES, YES, YES, YES, NO, 7000},
565 {CTRY_BRAZIL, FCC3_WORLD, "BR", "BRAZIL", YES, NO, NO, YES, NO,
566 YES, NO, 7000},
567 {CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN", "BRUNEI DARUSSALAM",
568 YES, YES, YES, YES, YES, YES, YES, 7000},
569 {CTRY_BULGARIA, ETSI6_WORLD, "BG", "BULGARIA", YES, NO, YES, YES,
570 YES, YES, YES, 7000},
571 {CTRY_CANADA, FCC2_FCCA, "CA", "CANADA", YES, YES, YES, YES, YES,
572 YES, YES, 7000},
573 {CTRY_CANADA2, FCC6_FCCA, "CA", "CANADA2", YES, YES, YES, YES, YES,
574 YES, YES, 7000},
575 {CTRY_CHILE, APL6_WORLD, "CL", "CHILE", YES, YES, YES, YES, YES,
576 YES, YES, 7000},
577 {CTRY_CHINA, APL1_WORLD, "CN", "CHINA", YES, YES, YES, YES, YES,
578 YES, YES, 7000},
579 {CTRY_COLOMBIA, FCC1_FCCA, "CO", "COLOMBIA", YES, NO, YES, YES,
580 YES, YES, NO, 7000},
581 {CTRY_COSTA_RICA, FCC1_WORLD, "CR", "COSTA RICA", YES, NO, YES,
582 YES, YES, YES, NO, 7000},
583 {CTRY_CROATIA, ETSI3_WORLD, "HR", "CROATIA", YES, NO, YES, YES,
584 YES, YES, NO, 7000},
585 {CTRY_CYPRUS, ETSI1_WORLD, "CY", "CYPRUS", YES, YES, YES, YES, YES,
586 YES, YES, 7000},
587 {CTRY_CZECH, ETSI3_WORLD, "CZ", "CZECH REPUBLIC", YES, NO, YES,
588 YES, YES, YES, YES, 7000},
589 {CTRY_DENMARK, ETSI1_WORLD, "DK", "DENMARK", YES, NO, YES, YES,
590 YES, YES, YES, 7000},
591 {CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO", "DOMINICAN REPUBLIC",
592 YES, YES, YES, YES, YES, YES, YES, 7000},
593 {CTRY_ECUADOR, FCC1_WORLD, "EC", "ECUADOR", YES, NO, NO, YES, YES,
594 YES, NO, 7000},
595 {CTRY_EGYPT, ETSI3_WORLD, "EG", "EGYPT", YES, NO, YES, YES, YES,
596 YES, NO, 7000},
597 {CTRY_EL_SALVADOR, FCC1_WORLD, "SV", "EL SALVADOR", YES, NO, YES,
598 YES, YES, YES, NO, 7000},
599 {CTRY_ESTONIA, ETSI1_WORLD, "EE", "ESTONIA", YES, NO, YES, YES,
600 YES, YES, YES, 7000},
601 {CTRY_FINLAND, ETSI1_WORLD, "FI", "FINLAND", YES, NO, YES, YES,
602 YES, YES, YES, 7000},
603 {CTRY_FRANCE, ETSI1_WORLD, "FR", "FRANCE", YES, NO, YES, YES, YES,
604 YES, YES, 7000},
605 {CTRY_GEORGIA, ETSI4_WORLD, "GE", "GEORGIA", YES, YES, YES, YES,
606 YES, YES, YES, 7000},
607 {CTRY_GERMANY, ETSI1_WORLD, "DE", "GERMANY", YES, NO, YES, YES,
608 YES, YES, YES, 7000},
609 {CTRY_GREECE, ETSI1_WORLD, "GR", "GREECE", YES, NO, YES, YES, YES,
610 YES, YES, 7000},
611 {CTRY_GUATEMALA, FCC1_FCCA, "GT", "GUATEMALA", YES, YES, YES, YES,
612 YES, YES, YES, 7000},
613 {CTRY_HONDURAS, NULL1_WORLD, "HN", "HONDURAS", YES, NO, YES, YES,
614 YES, NO, NO, 7000},
615 {CTRY_HONG_KONG, FCC2_WORLD, "HK", "HONG KONG", YES, YES, YES, YES,
616 YES, YES, YES, 7000},
617 {CTRY_HUNGARY, ETSI1_WORLD, "HU", "HUNGARY", YES, NO, YES, YES,
618 YES, YES, YES, 7000},
619 {CTRY_ICELAND, ETSI1_WORLD, "IS", "ICELAND", YES, NO, YES, YES,
620 YES, YES, YES, 7000},
621 {CTRY_INDIA, APL6_WORLD, "IN", "INDIA", YES, NO, YES, YES, YES,
622 YES, NO, 7000},
623 {CTRY_INDONESIA, APL1_WORLD, "ID", "INDONESIA", YES, NO, YES, YES,
624 YES, YES, NO, 7000},
625 {CTRY_IRAN, APL1_WORLD, "IR", "IRAN", YES, YES, YES, YES, YES, YES,
626 YES, 7000},
627 {CTRY_IRELAND, ETSI1_WORLD, "IE", "IRELAND", YES, NO, YES, YES,
628 YES, YES, YES, 7000},
629 {CTRY_ISRAEL, NULL1_WORLD, "IL", "ISRAEL", YES, NO, YES, YES, YES,
630 NO, NO, 7000},
631 {CTRY_ITALY, ETSI1_WORLD, "IT", "ITALY", YES, NO, YES, YES, YES,
632 YES, YES, 7000},
633 {CTRY_JAMAICA, ETSI1_WORLD, "JM", "JAMAICA", YES, NO, YES, YES,
634 YES, YES, YES, 7000},
635
636 {CTRY_JAPAN, MKK1_MKKA, "JP", "JAPAN", YES, NO, NO, YES, YES, YES,
637 YES, 7000},
638 {CTRY_JAPAN1, MKK1_MKKB, "JP", "JAPAN1", YES, NO, NO, YES, YES,
639 YES, YES, 7000},
640 {CTRY_JAPAN2, MKK1_FCCA, "JP", "JAPAN2", YES, NO, NO, YES, YES,
641 YES, YES, 7000},
642 {CTRY_JAPAN3, MKK2_MKKA, "JP", "JAPAN3", YES, NO, NO, YES, YES,
643 YES, YES, 7000},
644 {CTRY_JAPAN4, MKK1_MKKA1, "JP", "JAPAN4", YES, NO, NO, YES, YES,
645 YES, YES, 7000},
646 {CTRY_JAPAN5, MKK1_MKKA2, "JP", "JAPAN5", YES, NO, NO, YES, YES,
647 YES, YES, 7000},
648 {CTRY_JAPAN6, MKK1_MKKC, "JP", "JAPAN6", YES, NO, NO, YES, YES,
649 YES, YES, 7000},
650
651 {CTRY_JAPAN7, MKK3_MKKB, "JP", "JAPAN7", YES, NO, NO, YES, YES,
652 YES, YES, 7000},
653 {CTRY_JAPAN8, MKK3_MKKA2, "JP", "JAPAN8", YES, NO, NO, YES, YES,
654 YES, YES, 7000},
655 {CTRY_JAPAN9, MKK3_MKKC, "JP", "JAPAN9", YES, NO, NO, YES, YES,
656 YES, YES, 7000},
657
658 {CTRY_JAPAN10, MKK4_MKKB, "JP", "JAPAN10", YES, NO, NO, YES, YES,
659 YES, YES, 7000},
660 {CTRY_JAPAN11, MKK4_MKKA2, "JP", "JAPAN11", YES, NO, NO, YES, YES,
661 YES, YES, 7000},
662 {CTRY_JAPAN12, MKK4_MKKC, "JP", "JAPAN12", YES, NO, NO, YES, YES,
663 YES, YES, 7000},
664
665 {CTRY_JAPAN13, MKK5_MKKB, "JP", "JAPAN13", YES, NO, NO, YES, YES,
666 YES, YES, 7000},
667 {CTRY_JAPAN14, MKK5_MKKA2, "JP", "JAPAN14", YES, NO, NO, YES, YES,
668 YES, YES, 7000},
669 {CTRY_JAPAN15, MKK5_MKKC, "JP", "JAPAN15", YES, NO, NO, YES, YES,
670 YES, YES, 7000},
671
672 {CTRY_JAPAN16, MKK6_MKKB, "JP", "JAPAN16", YES, NO, NO, YES, YES,
673 YES, YES, 7000},
674 {CTRY_JAPAN17, MKK6_MKKA2, "JP", "JAPAN17", YES, NO, NO, YES, YES,
675 YES, YES, 7000},
676 {CTRY_JAPAN18, MKK6_MKKC, "JP", "JAPAN18", YES, NO, NO, YES, YES,
677 YES, YES, 7000},
678
679 {CTRY_JAPAN19, MKK7_MKKB, "JP", "JAPAN19", YES, NO, NO, YES, YES,
680 YES, YES, 7000},
681 {CTRY_JAPAN20, MKK7_MKKA2, "JP", "JAPAN20", YES, NO, NO, YES, YES,
682 YES, YES, 7000},
683 {CTRY_JAPAN21, MKK7_MKKC, "JP", "JAPAN21", YES, NO, NO, YES, YES,
684 YES, YES, 7000},
685
686 {CTRY_JAPAN22, MKK8_MKKB, "JP", "JAPAN22", YES, NO, NO, YES, YES,
687 YES, YES, 7000},
688 {CTRY_JAPAN23, MKK8_MKKA2, "JP", "JAPAN23", YES, NO, NO, YES, YES,
689 YES, YES, 7000},
690 {CTRY_JAPAN24, MKK8_MKKC, "JP", "JAPAN24", YES, NO, NO, YES, YES,
691 YES, YES, 7000},
692
693 {CTRY_JAPAN25, MKK3_MKKA, "JP", "JAPAN25", YES, NO, NO, YES, YES,
694 YES, YES, 7000},
695 {CTRY_JAPAN26, MKK3_MKKA1, "JP", "JAPAN26", YES, NO, NO, YES, YES,
696 YES, YES, 7000},
697 {CTRY_JAPAN27, MKK3_FCCA, "JP", "JAPAN27", YES, NO, NO, YES, YES,
698 YES, YES, 7000},
699 {CTRY_JAPAN28, MKK4_MKKA1, "JP", "JAPAN28", YES, NO, NO, YES, YES,
700 YES, YES, 7000},
701 {CTRY_JAPAN29, MKK4_FCCA, "JP", "JAPAN29", YES, NO, NO, YES, YES,
702 YES, YES, 7000},
703 {CTRY_JAPAN30, MKK6_MKKA1, "JP", "JAPAN30", YES, NO, NO, YES, YES,
704 YES, YES, 7000},
705 {CTRY_JAPAN31, MKK6_FCCA, "JP", "JAPAN31", YES, NO, NO, YES, YES,
706 YES, YES, 7000},
707 {CTRY_JAPAN32, MKK7_MKKA1, "JP", "JAPAN32", YES, NO, NO, YES, YES,
708 YES, YES, 7000},
709 {CTRY_JAPAN33, MKK7_FCCA, "JP", "JAPAN33", YES, NO, NO, YES, YES,
710 YES, YES, 7000},
711 {CTRY_JAPAN34, MKK9_MKKA, "JP", "JAPAN34", YES, NO, NO, YES, YES,
712 YES, YES, 7000},
713 {CTRY_JAPAN35, MKK10_MKKA, "JP", "JAPAN35", YES, NO, NO, YES, YES,
714 YES, YES, 7000},
715 {CTRY_JAPAN36, MKK4_MKKA, "JP", "JAPAN36", YES, NO, NO, YES, YES,
716 YES, YES, 7000},
717 {CTRY_JAPAN37, MKK9_FCCA, "JP", "JAPAN37", YES, NO, NO, YES, YES,
718 YES, YES, 7000},
719 {CTRY_JAPAN38, MKK9_MKKA1, "JP", "JAPAN38", YES, NO, NO, YES, YES,
720 YES, YES, 7000},
721 {CTRY_JAPAN39, MKK9_MKKC, "JP", "JAPAN39", YES, NO, NO, YES, YES,
722 YES, YES, 7000},
723 {CTRY_JAPAN40, MKK9_MKKA2, "JP", "JAPAN40", YES, NO, NO, YES, YES,
724 YES, YES, 7000},
725 {CTRY_JAPAN41, MKK10_FCCA, "JP", "JAPAN41", YES, NO, NO, YES, YES,
726 YES, YES, 7000},
727 {CTRY_JAPAN42, MKK10_MKKA1, "JP", "JAPAN42", YES, NO, NO, YES, YES,
728 YES, YES, 7000},
729 {CTRY_JAPAN43, MKK10_MKKC, "JP", "JAPAN43", YES, NO, NO, YES, YES,
730 YES, YES, 7000},
731 {CTRY_JAPAN44, MKK10_MKKA2, "JP", "JAPAN44", YES, NO, NO, YES, YES,
732 YES, YES, 7000},
733 {CTRY_JAPAN45, MKK11_MKKA, "JP", "JAPAN45", YES, NO, NO, YES, YES,
734 YES, YES, 7000},
735 {CTRY_JAPAN46, MKK11_FCCA, "JP", "JAPAN46", YES, NO, NO, YES, YES,
736 YES, YES, 7000},
737 {CTRY_JAPAN47, MKK11_MKKA1, "JP", "JAPAN47", YES, NO, NO, YES, YES,
738 YES, YES, 7000},
739 {CTRY_JAPAN48, MKK11_MKKC, "JP", "JAPAN48", YES, NO, NO, YES, YES,
740 YES, YES, 7000},
741 {CTRY_JAPAN49, MKK11_MKKA2, "JP", "JAPAN49", YES, NO, NO, YES, YES,
742 YES, YES, 7000},
743 {CTRY_JAPAN50, MKK12_MKKA, "JP", "JAPAN50", YES, NO, NO, YES, YES,
744 YES, YES, 7000},
745 {CTRY_JAPAN51, MKK12_FCCA, "JP", "JAPAN51", YES, NO, NO, YES, YES,
746 YES, YES, 7000},
747 {CTRY_JAPAN52, MKK12_MKKA1, "JP", "JAPAN52", YES, NO, NO, YES, YES,
748 YES, YES, 7000},
749 {CTRY_JAPAN53, MKK12_MKKC, "JP", "JAPAN53", YES, NO, NO, YES, YES,
750 YES, YES, 7000},
751 {CTRY_JAPAN54, MKK12_MKKA2, "JP", "JAPAN54", YES, NO, NO, YES, YES,
752 YES, YES, 7000},
753
754 {CTRY_JAPAN57, MKK13_MKKB, "JP", "JAPAN57", YES, NO, NO, YES, YES,
755 YES, YES, 7000},
756 {CTRY_JAPAN58, MKK14_MKKA1, "JP", "JAPAN58", YES, NO, NO, YES, YES,
757 YES, YES, 7000},
758 {CTRY_JAPAN59, MKK15_MKKA1, "JP", "JAPAN59", YES, NO, NO, YES, YES,
759 YES, YES, 7000},
760
761 {CTRY_JORDAN, ETSI2_WORLD, "JO", "JORDAN", YES, NO, YES, YES, YES,
762 YES, NO, 7000},
763 {CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ", "KAZAKHSTAN", YES, NO, YES,
764 YES, YES, NO, NO, 7000},
765 {CTRY_KOREA_NORTH, APL9_WORLD, "KP", "NORTH KOREA", YES, NO, NO,
766 YES, YES, YES, YES, 7000},
767 {CTRY_KOREA_ROC, APL9_WORLD, "KR", "KOREA REPUBLIC", YES, NO, NO,
768 YES, NO, YES, NO, 7000},
769 {CTRY_KOREA_ROC2, APL2_WORLD, "K2", "KOREA REPUBLIC2", YES, NO, NO,
770 YES, NO, YES, NO, 7000},
771 {CTRY_KOREA_ROC3, APL9_WORLD, "K3", "KOREA REPUBLIC3", YES, NO, NO,
772 YES, NO, YES, NO, 7000},
773 {CTRY_KUWAIT, NULL1_WORLD, "KW", "KUWAIT", YES, NO, YES, YES, YES,
774 NO, NO, 7000},
775 {CTRY_LATVIA, ETSI1_WORLD, "LV", "LATVIA", YES, NO, YES, YES, YES,
776 YES, YES, 7000},
777 {CTRY_LEBANON, NULL1_WORLD, "LB", "LEBANON", YES, NO, YES, YES,
778 YES, NO, NO, 7000},
779 {CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI", "LIECHTENSTEIN", YES, NO,
780 YES, YES, YES, YES, YES, 7000},
781 {CTRY_LITHUANIA, ETSI1_WORLD, "LT", "LITHUANIA", YES, NO, YES, YES,
782 YES, YES, YES, 7000},
783 {CTRY_LUXEMBOURG, ETSI1_WORLD, "LU", "LUXEMBOURG", YES, NO, YES,
784 YES, YES, YES, YES, 7000},
785 {CTRY_MACAU, FCC2_WORLD, "MO", "MACAU", YES, YES, YES, YES, YES,
786 YES, YES, 7000},
787 {CTRY_MACEDONIA, NULL1_WORLD, "MK", "MACEDONIA", YES, NO, YES, YES,
788 YES, NO, NO, 7000},
789 {CTRY_MALAYSIA, APL8_WORLD, "MY", "MALAYSIA", YES, NO, NO, YES, NO,
790 YES, NO, 7000},
791 {CTRY_MALTA, ETSI1_WORLD, "MT", "MALTA", YES, NO, YES, YES, YES,
792 YES, YES, 7000},
793 {CTRY_MEXICO, FCC1_FCCA, "MX", "MEXICO", YES, YES, YES, YES, YES,
794 YES, YES, 7000},
795 {CTRY_MONACO, ETSI4_WORLD, "MC", "MONACO", YES, YES, YES, YES, YES,
796 YES, YES, 7000},
797 {CTRY_MOROCCO, NULL1_WORLD, "MA", "MOROCCO", YES, NO, YES, YES,
798 YES, NO, NO, 7000},
799 {CTRY_NEPAL, APL1_WORLD, "NP", "NEPAL", YES, NO, YES, YES, YES,
800 YES, YES, 7000},
801 {CTRY_NETHERLANDS, ETSI1_WORLD, "NL", "NETHERLANDS", YES, NO, YES,
802 YES, YES, YES, YES, 7000},
803 {CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN",
804 "NETHERLANDS-ANTILLES", YES, NO, YES, YES, YES, YES, YES, 7000},
805 {CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ", "NEW ZEALAND", YES, NO, YES,
806 YES, YES, YES, NO, 7000},
807 {CTRY_NORWAY, ETSI1_WORLD, "NO", "NORWAY", YES, NO, YES, YES, YES,
808 YES, YES, 7000},
809 {CTRY_OMAN, APL6_WORLD, "OM", "OMAN", YES, NO, YES, YES, YES, YES,
810 NO, 7000},
811 {CTRY_PAKISTAN, NULL1_WORLD, "PK", "PAKISTAN", YES, NO, YES, YES,
812 YES, NO, NO, 7000},
813 {CTRY_PANAMA, FCC1_FCCA, "PA", "PANAMA", YES, YES, YES, YES, YES,
814 YES, YES, 7000},
815 {CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG", "PAPUA NEW GUINEA", YES,
816 YES, YES, YES, YES, YES, YES, 7000},
817 {CTRY_PERU, APL1_WORLD, "PE", "PERU", YES, NO, YES, YES, YES, YES,
818 NO, 7000},
819 {CTRY_PHILIPPINES, APL1_WORLD, "PH", "PHILIPPINES", YES, YES, YES,
820 YES, YES, YES, YES, 7000},
821 {CTRY_POLAND, ETSI1_WORLD, "PL", "POLAND", YES, NO, YES, YES, YES,
822 YES, YES, 7000},
823 {CTRY_PORTUGAL, ETSI1_WORLD, "PT", "PORTUGAL", YES, NO, YES, YES,
824 YES, YES, YES, 7000},
825 {CTRY_PUERTO_RICO, FCC1_FCCA, "PR", "PUERTO RICO", YES, YES, YES,
826 YES, YES, YES, YES, 7000},
827 {CTRY_QATAR, NULL1_WORLD, "QA", "QATAR", YES, NO, YES, YES, YES,
828 NO, NO, 7000},
829 {CTRY_ROMANIA, NULL1_WORLD, "RO", "ROMANIA", YES, NO, YES, YES,
830 YES, NO, NO, 7000},
831 {CTRY_RUSSIA, NULL1_WORLD, "RU", "RUSSIA", YES, NO, YES, YES, YES,
832 NO, NO, 7000},
833 {CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA", "SAUDI ARABIA", YES, NO,
834 YES, YES, YES, NO, NO, 7000},
835 {CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS", "SERBIA & MONTENEGRO",
836 YES, NO, YES, YES, YES, YES, YES, 7000},
837 {CTRY_SINGAPORE, APL6_WORLD, "SG", "SINGAPORE", YES, YES, YES, YES,
838 YES, YES, YES, 7000},
839 {CTRY_SLOVAKIA, ETSI1_WORLD, "SK", "SLOVAK REPUBLIC", YES, NO, YES,
840 YES, YES, YES, YES, 7000},
841 {CTRY_SLOVENIA, ETSI1_WORLD, "SI", "SLOVENIA", YES, NO, YES, YES,
842 YES, YES, YES, 7000},
843 {CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA", "SOUTH AFRICA", YES, NO, YES,
844 YES, YES, YES, NO, 7000},
845 {CTRY_SPAIN, ETSI1_WORLD, "ES", "SPAIN", YES, NO, YES, YES, YES,
846 YES, YES, 7000},
847 {CTRY_SRI_LANKA, FCC3_WORLD, "LK", "SRI LANKA", YES, NO, YES, YES,
848 YES, YES, NO, 7000},
849 {CTRY_SWEDEN, ETSI1_WORLD, "SE", "SWEDEN", YES, NO, YES, YES, YES,
850 YES, YES, 7000},
851 {CTRY_SWITZERLAND, ETSI1_WORLD, "CH", "SWITZERLAND", YES, NO, YES,
852 YES, YES, YES, YES, 7000},
853 {CTRY_SYRIA, NULL1_WORLD, "SY", "SYRIA", YES, NO, YES, YES, YES,
854 NO, NO, 7000},
855 {CTRY_TAIWAN, APL3_FCCA, "TW", "TAIWAN", YES, YES, YES, YES, YES,
856 YES, YES, 7000},
857 {CTRY_THAILAND, NULL1_WORLD, "TH", "THAILAND", YES, NO, YES, YES,
858 YES, NO, NO, 7000},
859 {CTRY_TRINIDAD_Y_TOBAGO, ETSI4_WORLD, "TT", "TRINIDAD & TOBAGO",
860 YES, NO, YES, YES, YES, YES, NO, 7000},
861 {CTRY_TUNISIA, ETSI3_WORLD, "TN", "TUNISIA", YES, NO, YES, YES,
862 YES, YES, NO, 7000},
863 {CTRY_TURKEY, ETSI3_WORLD, "TR", "TURKEY", YES, NO, YES, YES, YES,
864 YES, NO, 7000},
865 {CTRY_UKRAINE, NULL1_WORLD, "UA", "UKRAINE", YES, NO, YES, YES,
866 YES, NO, NO, 7000},
867 {CTRY_UAE, NULL1_WORLD, "AE", "UNITED ARAB EMIRATES", YES, NO, YES,
868 YES, YES, NO, NO, 7000},
869 {CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB", "UNITED KINGDOM", YES, NO,
870 YES, YES, YES, YES, YES, 7000},
871 {CTRY_UNITED_STATES, FCC3_FCCA, "US", "UNITED STATES", YES, YES,
872 YES, YES, YES, YES, YES, 5825},
873 {CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS",
874 "UNITED STATES (PUBLIC SAFETY)", YES, YES, YES, YES, YES, YES,
875 YES, 7000},
876 {CTRY_URUGUAY, APL2_WORLD, "UY", "URUGUAY", YES, NO, YES, YES, YES,
877 YES, NO, 7000},
878 {CTRY_UZBEKISTAN, FCC3_FCCA, "UZ", "UZBEKISTAN", YES, YES, YES,
879 YES, YES, YES, YES, 7000},
880 {CTRY_VENEZUELA, APL2_ETSIC, "VE", "VENEZUELA", YES, NO, YES, YES,
881 YES, YES, NO, 7000},
882 {CTRY_VIET_NAM, NULL1_WORLD, "VN", "VIET NAM", YES, NO, YES, YES,
883 YES, NO, NO, 7000},
884 {CTRY_YEMEN, NULL1_WORLD, "YE", "YEMEN", YES, NO, YES, YES, YES,
885 NO, NO, 7000},
886 {CTRY_ZIMBABWE, NULL1_WORLD, "ZW", "ZIMBABWE", YES, NO, YES, YES,
887 YES, NO, NO, 7000}
888};
889
890enum {
891 NO_DFS = 0x0000000000000000ULL,
892 DFS_FCC3 = 0x0000000000000001ULL,
893 DFS_ETSI = 0x0000000000000002ULL,
894 DFS_MKK4 = 0x0000000000000004ULL,
895};
896
897enum {
898 F1_4915_4925,
899 F1_4935_4945,
900 F1_4920_4980,
901 F1_4942_4987,
902 F1_4945_4985,
903 F1_4950_4980,
904 F1_5035_5040,
905 F1_5040_5080,
906 F1_5055_5055,
907
908 F1_5120_5240,
909
910 F1_5170_5230,
911 F2_5170_5230,
912
913 F1_5180_5240,
914 F2_5180_5240,
915 F3_5180_5240,
916 F4_5180_5240,
917 F5_5180_5240,
918 F6_5180_5240,
919 F7_5180_5240,
920 F8_5180_5240,
921
922 F1_5180_5320,
923
924 F1_5240_5280,
925
926 F1_5260_5280,
927
928 F1_5260_5320,
929 F2_5260_5320,
930 F3_5260_5320,
931 F4_5260_5320,
932 F5_5260_5320,
933 F6_5260_5320,
934
935 F1_5260_5700,
936
937 F1_5280_5320,
938
939 F1_5500_5580,
940
941 F1_5500_5620,
942
943 F1_5500_5700,
944 F2_5500_5700,
945 F3_5500_5700,
946 F4_5500_5700,
947 F5_5500_5700,
948
949 F1_5660_5700,
950
951 F1_5745_5805,
952 F2_5745_5805,
953 F3_5745_5805,
954
955 F1_5745_5825,
956 F2_5745_5825,
957 F3_5745_5825,
958 F4_5745_5825,
959 F5_5745_5825,
960 F6_5745_5825,
961
962 W1_4920_4980,
963 W1_5040_5080,
964 W1_5170_5230,
965 W1_5180_5240,
966 W1_5260_5320,
967 W1_5745_5825,
968 W1_5500_5700,
969 A_DEMO_ALL_CHANNELS
970};
971
972static struct RegDmnFreqBand regDmn5GhzFreq[] = {
973 {4915, 4925, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
974 {4935, 4945, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 16},
975 {4920, 4980, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 7},
976 {4942, 4987, 27, 6, 5, 5, NO_DFS, PSCAN_FCC, 0},
977 {4945, 4985, 30, 6, 10, 5, NO_DFS, PSCAN_FCC, 0},
978 {4950, 4980, 33, 6, 20, 5, NO_DFS, PSCAN_FCC, 0},
979 {5035, 5040, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
980 {5040, 5080, 23, 0, 20, 20, NO_DFS, PSCAN_MKK2, 2},
981 {5055, 5055, 23, 0, 10, 5, NO_DFS, PSCAN_MKK2, 12},
982
983 {5120, 5240, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
984
985 {5170, 5230, 23, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
986 {5170, 5230, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK2, 1},
987
988 {5180, 5240, 15, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
989 {5180, 5240, 17, 6, 20, 20, NO_DFS, NO_PSCAN, 1},
990 {5180, 5240, 18, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
991 {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
992 {5180, 5240, 23, 0, 20, 20, NO_DFS, PSCAN_FCC | PSCAN_ETSI, 0},
993 {5180, 5240, 23, 6, 20, 20, NO_DFS, PSCAN_FCC, 0},
994 {5180, 5240, 20, 0, 20, 20, NO_DFS, PSCAN_MKK1 | PSCAN_MKK3, 0},
995 {5180, 5240, 23, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
996
997 {5180, 5320, 20, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
998
999 {5240, 5280, 23, 0, 20, 20, DFS_FCC3, PSCAN_FCC | PSCAN_ETSI, 0},
1000
1001 {5260, 5280, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
1002 PSCAN_FCC | PSCAN_ETSI, 0},
1003
1004 {5260, 5320, 18, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
1005 PSCAN_FCC | PSCAN_ETSI, 0},
1006
1007 {5260, 5320, 20, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
1008 PSCAN_FCC | PSCAN_ETSI | PSCAN_MKK3, 0},
1009
1010
1011 {5260, 5320, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI,
1012 PSCAN_FCC | PSCAN_ETSI, 2},
1013 {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 2},
1014 {5260, 5320, 23, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
1015 {5260, 5320, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1016
1017 {5260, 5700, 5, 6, 20, 20, DFS_FCC3 | DFS_ETSI, NO_PSCAN, 0},
1018
1019 {5280, 5320, 17, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 0},
1020
1021 {5500, 5580, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
1022
1023 {5500, 5620, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
1024
1025 {5500, 5700, 20, 6, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_FCC, 4},
1026 {5500, 5700, 27, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
1027 PSCAN_FCC | PSCAN_ETSI, 0},
1028 {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI,
1029 PSCAN_FCC | PSCAN_ETSI, 0},
1030 {5500, 5700, 23, 0, 20, 20, DFS_FCC3 | DFS_ETSI | DFS_MKK4,
1031 PSCAN_MKK3 | PSCAN_FCC, 0},
1032 {5500, 5700, 30, 6, 20, 20, DFS_ETSI, PSCAN_ETSI, 0},
1033
1034 {5660, 5700, 23, 6, 20, 20, DFS_FCC3, PSCAN_FCC, 0},
1035
1036 {5745, 5805, 23, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1037 {5745, 5805, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
1038 {5745, 5805, 30, 6, 20, 20, NO_DFS, PSCAN_ETSI, 0},
1039 {5745, 5825, 5, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
1040 {5745, 5825, 17, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1041 {5745, 5825, 20, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1042 {5745, 5825, 30, 0, 20, 20, NO_DFS, NO_PSCAN, 0},
1043 {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 3},
1044 {5745, 5825, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
1045
1046
1047 {4920, 4980, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1048 {5040, 5080, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1049 {5170, 5230, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1050 {5180, 5240, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1051 {5260, 5320, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
1052 {5745, 5825, 30, 0, 20, 20, NO_DFS, PSCAN_WWR, 0},
1053 {5500, 5700, 30, 0, 20, 20, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, 0},
1054 {4920, 6100, 30, 6, 20, 20, NO_DFS, NO_PSCAN, 0},
1055};
1056
1057enum {
1058 T1_5130_5650,
1059 T1_5150_5670,
1060
1061 T1_5200_5200,
1062 T2_5200_5200,
1063 T3_5200_5200,
1064 T4_5200_5200,
1065 T5_5200_5200,
1066 T6_5200_5200,
1067 T7_5200_5200,
1068 T8_5200_5200,
1069
1070 T1_5200_5280,
1071 T2_5200_5280,
1072 T3_5200_5280,
1073 T4_5200_5280,
1074 T5_5200_5280,
1075 T6_5200_5280,
1076
1077 T1_5200_5240,
1078 T1_5210_5210,
1079 T2_5210_5210,
1080 T3_5210_5210,
1081 T4_5210_5210,
1082 T5_5210_5210,
1083 T6_5210_5210,
1084 T7_5210_5210,
1085 T8_5210_5210,
1086 T9_5210_5210,
1087 T10_5210_5210,
1088 T1_5240_5240,
1089
1090 T1_5210_5250,
1091 T1_5210_5290,
1092 T2_5210_5290,
1093 T3_5210_5290,
1094
1095 T1_5280_5280,
1096 T2_5280_5280,
1097 T1_5290_5290,
1098 T2_5290_5290,
1099 T3_5290_5290,
1100 T1_5250_5290,
1101 T2_5250_5290,
1102 T3_5250_5290,
1103 T4_5250_5290,
1104
1105 T1_5540_5660,
1106 T2_5540_5660,
1107 T3_5540_5660,
1108 T1_5760_5800,
1109 T2_5760_5800,
1110 T3_5760_5800,
1111 T4_5760_5800,
1112 T5_5760_5800,
1113 T6_5760_5800,
1114 T7_5760_5800,
1115
1116 T1_5765_5805,
1117 T2_5765_5805,
1118 T3_5765_5805,
1119 T4_5765_5805,
1120 T5_5765_5805,
1121 T6_5765_5805,
1122 T7_5765_5805,
1123 T8_5765_5805,
1124 T9_5765_5805,
1125
1126 WT1_5210_5250,
1127 WT1_5290_5290,
1128 WT1_5540_5660,
1129 WT1_5760_5800,
1130};
1131
1132enum {
1133 F1_2312_2372,
1134 F2_2312_2372,
1135
1136 F1_2412_2472,
1137 F2_2412_2472,
1138 F3_2412_2472,
1139
1140 F1_2412_2462,
1141 F2_2412_2462,
1142
1143 F1_2432_2442,
1144
1145 F1_2457_2472,
1146
1147 F1_2467_2472,
1148
1149 F1_2484_2484,
1150 F2_2484_2484,
1151
1152 F1_2512_2732,
1153
1154 W1_2312_2372,
1155 W1_2412_2412,
1156 W1_2417_2432,
1157 W1_2437_2442,
1158 W1_2447_2457,
1159 W1_2462_2462,
1160 W1_2467_2467,
1161 W2_2467_2467,
1162 W1_2472_2472,
1163 W2_2472_2472,
1164 W1_2484_2484,
1165 W2_2484_2484,
1166};
1167
1168static struct RegDmnFreqBand regDmn2GhzFreq[] = {
1169 {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1170 {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1171
1172 {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1173 {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
1174 {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1175
1176 {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1177 {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA, 0},
1178
1179 {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1180
1181 {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1182
1183 {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
1184
1185 {2484, 2484, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1186 {2484, 2484, 20, 0, 20, 5, NO_DFS,
1187 PSCAN_MKKA | PSCAN_MKKA1 | PSCAN_MKKA2, 0},
1188
1189 {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1190
1191 {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1192 {2412, 2412, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1193 {2417, 2432, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1194 {2437, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1195 {2447, 2457, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1196 {2462, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1197 {2467, 2467, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1198 {2467, 2467, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1199 {2472, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1200 {2472, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1201 {2484, 2484, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1202 {2484, 2484, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1203};
1204
1205enum {
1206 G1_2312_2372,
1207 G2_2312_2372,
1208
1209 G1_2412_2472,
1210 G2_2412_2472,
1211 G3_2412_2472,
1212
1213 G1_2412_2462,
1214 G2_2412_2462,
1215
1216 G1_2432_2442,
1217
1218 G1_2457_2472,
1219
1220 G1_2512_2732,
1221
1222 G1_2467_2472,
1223
1224 WG1_2312_2372,
1225 WG1_2412_2462,
1226 WG1_2467_2472,
1227 WG2_2467_2472,
1228 G_DEMO_ALL_CHANNELS
1229};
1230
1231static struct RegDmnFreqBand regDmn2Ghz11gFreq[] = {
1232 {2312, 2372, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1233 {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1234
1235 {2412, 2472, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1236 {2412, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
1237 {2412, 2472, 30, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1238
1239 {2412, 2462, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1240 {2412, 2462, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA_G, 0},
1241
1242 {2432, 2442, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1243
1244 {2457, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1245
1246 {2512, 2732, 5, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1247
1248 {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_MKKA2 | PSCAN_MKKA, 0},
1249
1250 {2312, 2372, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1251 {2412, 2462, 20, 0, 20, 5, NO_DFS, NO_PSCAN, 0},
1252 {2467, 2472, 20, 0, 20, 5, NO_DFS, PSCAN_WWR | IS_ECM_CHAN, 0},
1253 {2467, 2472, 20, 0, 20, 5, NO_DFS, NO_PSCAN | IS_ECM_CHAN, 0},
1254 {2312, 2732, 27, 6, 20, 5, NO_DFS, NO_PSCAN, 0},
1255};
1256
1257enum {
1258 T1_2312_2372,
1259 T1_2437_2437,
1260 T2_2437_2437,
1261 T3_2437_2437,
1262 T1_2512_2732
1263};
1264
1265static struct regDomain regDomains[] = {
1266
1267 {DEBUG_REG_DMN, FCC, DFS_FCC3, NO_PSCAN, NO_REQ,
1268 BM(A_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1269 -1),
1270 BM(T1_5130_5650, T1_5150_5670, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1271 -1),
1272 BM(T1_5200_5240, T1_5280_5280, T1_5540_5660, T1_5765_5805, -1, -1,
1273 -1, -1, -1, -1, -1, -1),
1274 BM(F1_2312_2372, F1_2412_2472, F1_2484_2484, F1_2512_2732, -1, -1,
1275 -1, -1, -1, -1, -1, -1),
1276 BM(G_DEMO_ALL_CHANNELS, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1277 -1),
1278 BM(T1_2312_2372, T1_2437_2437, T1_2512_2732, -1, -1, -1, -1, -1,
1279 -1, -1, -1, -1)},
1280
1281 {APL1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1282 BM(F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1283 BM(T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1284 BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1285 BMZERO,
1286 BMZERO,
1287 BMZERO},
1288
1289 {APL2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1290 BM(F1_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1291 BM(T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1292 BM(T2_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1293 BMZERO,
1294 BMZERO,
1295 BMZERO},
1296
1297 {APL3, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1298 BM(F1_5280_5320, F2_5745_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1299 -1),
1300 BM(T1_5290_5290, T1_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1301 -1),
1302 BM(T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1303 BMZERO,
1304 BMZERO,
1305 BMZERO},
1306
1307 {APL4, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1308 BM(F4_5180_5240, F3_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1309 -1),
1310 BM(T1_5210_5210, T3_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1311 -1),
1312 BM(T1_5200_5200, T3_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1313 -1),
1314 BMZERO,
1315 BMZERO,
1316 BMZERO},
1317
1318 {APL5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1319 BM(F2_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1320 BM(T4_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1321 BM(T4_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1322 BMZERO,
1323 BMZERO,
1324 BMZERO},
1325
1326 {APL6, ETSI, DFS_ETSI, PSCAN_FCC_T | PSCAN_FCC, NO_REQ,
1327 BM(F4_5180_5240, F2_5260_5320, F3_5745_5825, -1, -1, -1, -1, -1,
1328 -1, -1, -1, -1),
1329 BM(T2_5210_5210, T1_5250_5290, T1_5760_5800, -1, -1, -1, -1, -1,
1330 -1, -1, -1, -1),
1331 BM(T1_5200_5280, T5_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1332 -1),
1333 BMZERO,
1334 BMZERO,
1335 BMZERO},
1336
1337 {APL7, ETSI, DFS_ETSI, PSCAN_ETSI, NO_REQ,
1338 BM(F1_5280_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
1339 -1, -1, -1, -1),
1340 BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1341 -1),
1342 BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1343 -1),
1344 BMZERO,
1345 BMZERO,
1346 BMZERO},
1347
1348 {APL8, ETSI, NO_DFS, NO_PSCAN,
1349 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1350 BM(F6_5260_5320, F4_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1351 -1),
1352 BM(T2_5290_5290, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1353 -1),
1354 BM(T1_5280_5280, T1_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1355 -1),
1356 BMZERO,
1357 BMZERO,
1358 BMZERO},
1359
1360 {APL9, ETSI, DFS_ETSI, PSCAN_ETSI,
1361 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1362 BM(F1_5180_5320, F1_5500_5620, F3_5745_5805, -1, -1, -1, -1, -1,
1363 -1, -1, -1, -1),
1364 BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1365 -1),
1366 BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1367 -1),
1368 BMZERO,
1369 BMZERO,
1370 BMZERO},
1371
1372 {APL10, ETSI, DFS_ETSI, PSCAN_ETSI,
1373 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1374 BM(F1_5180_5320, F5_5500_5700, F3_5745_5805, -1, -1, -1, -1, -1,
1375 -1, -1, -1, -1),
1376 BM(T3_5290_5290, T5_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1377 -1),
1378 BM(T1_5540_5660, T6_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1379 -1),
1380 BMZERO,
1381 BMZERO,
1382 BMZERO},
1383
1384 {ETSI1, ETSI, DFS_ETSI, PSCAN_ETSI,
1385 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1386 BM(F4_5180_5240, F2_5260_5320, F2_5500_5700, -1, -1, -1, -1, -1,
1387 -1, -1, -1, -1),
1388 BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1389 BM(T2_5200_5280, T2_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1390 -1),
1391 BMZERO,
1392 BMZERO,
1393 BMZERO},
1394
1395 {ETSI2, ETSI, DFS_ETSI, PSCAN_ETSI,
1396 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1397 BM(F3_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1398 BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1399 BM(T2_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1400 BMZERO,
1401 BMZERO,
1402 BMZERO},
1403
1404 {ETSI3, ETSI, DFS_ETSI, PSCAN_ETSI,
1405 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1406 BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1407 -1),
1408 BM(T1_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1409 BM(T2_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1410 BMZERO,
1411 BMZERO,
1412 BMZERO},
1413
1414 {ETSI4, ETSI, DFS_ETSI, PSCAN_ETSI,
1415 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1416 BM(F3_5180_5240, F1_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1417 -1),
1418 BM(T2_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1419 BM(T3_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1420 BMZERO,
1421 BMZERO,
1422 BMZERO},
1423
1424 {ETSI5, ETSI, DFS_ETSI, PSCAN_ETSI,
1425 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1426 BM(F1_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1427 BM(T4_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1428 BM(T3_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1429 BMZERO,
1430 BMZERO,
1431 BMZERO},
1432
1433 {ETSI6, ETSI, DFS_ETSI, PSCAN_ETSI,
1434 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1435 BM(F5_5180_5240, F1_5260_5280, F3_5500_5700, -1, -1, -1, -1, -1,
1436 -1, -1, -1, -1),
1437 BM(T1_5210_5250, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1438 BM(T4_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1439 BMZERO,
1440 BMZERO,
1441 BMZERO},
1442
1443 {FCC1, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1444 BM(F2_5180_5240, F4_5260_5320, F5_5745_5825, -1, -1, -1, -1, -1,
1445 -1, -1, -1, -1),
1446 BM(T6_5210_5210, T2_5250_5290, T6_5760_5800, -1, -1, -1, -1, -1,
1447 -1, -1, -1, -1),
1448 BM(T1_5200_5240, T2_5280_5280, T7_5765_5805, -1, -1, -1, -1, -1,
1449 -1, -1, -1, -1),
1450 BMZERO,
1451 BMZERO,
1452 BMZERO},
1453
1454 {FCC2, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1455 BM(F6_5180_5240, F5_5260_5320, F6_5745_5825, -1, -1, -1, -1, -1,
1456 -1, -1, -1, -1),
1457 BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
1458 -1, -1, -1, -1),
1459 BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
1460 -1, -1, -1, -1, -1, -1),
1461 BMZERO,
1462 BMZERO,
1463 BMZERO},
1464
1465 {FCC3, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
1466 BM(F2_5180_5240, F3_5260_5320, F1_5500_5700, F5_5745_5825, -1, -1,
1467 -1, -1, -1, -1, -1, -1),
1468 BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1469 -1),
1470 BM(T4_5200_5200, T8_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1471 -1),
1472 BMZERO,
1473 BMZERO,
1474 BMZERO},
1475
1476 {FCC4, FCC, DFS_FCC3, PSCAN_FCC | PSCAN_FCC_T, NO_REQ,
1477 BM(F1_4942_4987, F1_4945_4985, F1_4950_4980, -1, -1, -1, -1, -1,
1478 -1, -1, -1, -1),
1479 BM(T8_5210_5210, T4_5250_5290, T7_5760_5800, -1, -1, -1, -1, -1,
1480 -1, -1, -1, -1),
1481 BM(T1_5200_5240, T1_5280_5280, T9_5765_5805, -1, -1, -1, -1, -1,
1482 -1, -1, -1, -1),
1483 BMZERO,
1484 BMZERO,
1485 BMZERO},
1486
1487 {FCC5, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1488 BM(F2_5180_5240, F6_5745_5825, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1489 -1),
1490 BM(T6_5210_5210, T2_5760_5800, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1491 -1),
1492 BM(T8_5200_5200, T7_5765_5805, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1493 -1),
1494 BMZERO,
1495 BMZERO,
1496 BMZERO},
1497
1498 {FCC6, FCC, DFS_FCC3, PSCAN_FCC, NO_REQ,
1499 BM(F8_5180_5240, F5_5260_5320, F1_5500_5580, F1_5660_5700,
1500 F6_5745_5825, -1, -1, -1, -1, -1, -1, -1),
1501 BM(T7_5210_5210, T3_5250_5290, T2_5760_5800, -1, -1, -1, -1, -1,
1502 -1, -1, -1, -1),
1503 BM(T7_5200_5200, T1_5240_5240, T2_5280_5280, T1_5765_5805, -1, -1,
1504 -1, -1, -1, -1, -1, -1),
1505 BMZERO,
1506 BMZERO,
1507 BMZERO},
1508
1509 {MKK1, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1510 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
1511 -1, -1, -1, -1, -1, -1),
1512 BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1513 BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1514 BMZERO,
1515 BMZERO,
1516 BMZERO},
1517
1518 {MKK2, MKK, NO_DFS, PSCAN_MKK2, DISALLOW_ADHOC_11A_TURB,
1519 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1520 F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
1521 F2_5260_5320, F4_5500_5700, -1, -1),
1522 BM(T7_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1523 BM(T5_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1524 BMZERO,
1525 BMZERO,
1526 BMZERO},
1527
1528
1529 {MKK3, MKK, NO_DFS, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1530 BM(F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1531 BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1532 BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1533 BMZERO,
1534 BMZERO,
1535 BMZERO},
1536
1537
1538 {MKK4, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1539 BM(F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1540 -1),
1541 BM(T10_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1542 BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1543 BMZERO,
1544 BMZERO,
1545 BMZERO},
1546
1547
1548 {MKK5, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1549 BM(F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1, -1, -1, -1,
1550 -1, -1, -1, -1),
1551 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1552 BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1553 -1),
1554 BMZERO,
1555 BMZERO,
1556 BMZERO},
1557
1558
1559 {MKK6, MKK, NO_DFS, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1560 BM(F2_5170_5230, F4_5180_5240, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1561 -1),
1562 BM(T3_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1563 BM(T6_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1564 BMZERO,
1565 BMZERO,
1566 BMZERO},
1567
1568
1569 {MKK7, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
1570 DISALLOW_ADHOC_11A_TURB,
1571 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, -1, -1, -1, -1, -1,
1572 -1, -1, -1, -1),
1573 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1574 BM(T5_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1575 BMZERO,
1576 BMZERO,
1577 BMZERO},
1578
1579
1580 {MKK8, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
1581 DISALLOW_ADHOC_11A_TURB,
1582 BM(F1_5170_5230, F4_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
1583 -1, -1, -1, -1, -1, -1),
1584 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1585 BM(T5_5200_5280, T3_5540_5660, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1586 -1),
1587 BMZERO,
1588 BMZERO,
1589 BMZERO},
1590
1591
1592 {MKK9, MKK, NO_DFS, PSCAN_MKK2 | PSCAN_MKK3,
1593 DISALLOW_ADHOC_11A_TURB,
1594 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1595 F1_5055_5055, F1_5040_5080, F4_5180_5240, -1, -1, -1, -1, -1),
1596 BM(T9_5210_5210, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1597 BM(T1_5200_5200, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1598 BMZERO,
1599 BMZERO,
1600 BMZERO},
1601
1602
1603 {MKK10, MKK, DFS_MKK4, PSCAN_MKK2 | PSCAN_MKK3,
1604 DISALLOW_ADHOC_11A_TURB,
1605 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1606 F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320, -1, -1,
1607 -1, -1),
1608 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1609 BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1610 BMZERO,
1611 BMZERO,
1612 BMZERO},
1613
1614
1615 {MKK11, MKK, DFS_MKK4, PSCAN_MKK3, DISALLOW_ADHOC_11A_TURB,
1616 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1617 F1_5055_5055, F1_5040_5080, F4_5180_5240, F2_5260_5320,
1618 F4_5500_5700, -1, -1, -1),
1619 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1620 BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1621 BMZERO,
1622 BMZERO,
1623 BMZERO},
1624
1625
1626 {MKK12, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
1627 DISALLOW_ADHOC_11A_TURB,
1628 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1629 F1_5055_5055, F1_5040_5080, F1_5170_5230, F4_5180_5240,
1630 F2_5260_5320, F4_5500_5700, -1, -1),
1631 BM(T3_5210_5290, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1632 BM(T1_5200_5280, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1633 BMZERO,
1634 BMZERO,
1635 BMZERO},
1636
1637
1638 {MKK13, MKK, DFS_MKK4, PSCAN_MKK1 | PSCAN_MKK3,
1639 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1640 BM(F1_5170_5230, F7_5180_5240, F2_5260_5320, F4_5500_5700, -1, -1,
1641 -1, -1, -1, -1, -1, -1),
1642 BMZERO,
1643 BMZERO,
1644 BMZERO,
1645 BMZERO,
1646 BMZERO},
1647
1648
1649 {MKK14, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1650 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1651 F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240, -1, -1,
1652 -1, -1),
1653 BMZERO,
1654 BMZERO,
1655 BMZERO,
1656 BMZERO,
1657 BMZERO},
1658
1659
1660 {MKK15, MKK, DFS_MKK4, PSCAN_MKK1, DISALLOW_ADHOC_11A_TURB,
1661 BM(F1_4915_4925, F1_4935_4945, F1_4920_4980, F1_5035_5040,
1662 F1_5040_5080, F1_5055_5055, F1_5170_5230, F4_5180_5240,
1663 F2_5260_5320, -1, -1, -1),
1664 BMZERO,
1665 BMZERO,
1666 BMZERO,
1667 BMZERO,
1668 BMZERO},
1669
1670
1671 {APLD, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
1672 BMZERO,
1673 BMZERO,
1674 BMZERO,
1675 BM(F2_2312_2372, F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1676 -1),
1677 BM(G2_2312_2372, G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1678 -1),
1679 BMZERO},
1680
1681 {ETSIA, NO_CTL, NO_DFS, PSCAN_ETSIA,
1682 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1683 BMZERO,
1684 BMZERO,
1685 BMZERO,
1686 BM(F1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1687 BM(G1_2457_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1688 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1689
1690 {ETSIB, ETSI, NO_DFS, PSCAN_ETSIB,
1691 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1692 BMZERO,
1693 BMZERO,
1694 BMZERO,
1695 BM(F1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1696 BM(G1_2432_2442, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1697 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1698
1699 {ETSIC, ETSI, NO_DFS, PSCAN_ETSIC,
1700 DISALLOW_ADHOC_11A | DISALLOW_ADHOC_11A_TURB,
1701 BMZERO,
1702 BMZERO,
1703 BMZERO,
1704 BM(F3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1705 BM(G3_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1706 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1707
1708 {FCCA, FCC, NO_DFS, NO_PSCAN, NO_REQ,
1709 BMZERO,
1710 BMZERO,
1711 BMZERO,
1712 BM(F1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1713 BM(G1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1714 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1715
1716 {MKKA, MKK, NO_DFS,
1717 PSCAN_MKKA | PSCAN_MKKA_G | PSCAN_MKKA1 | PSCAN_MKKA1_G |
1718 PSCAN_MKKA2 | PSCAN_MKKA2_G, DISALLOW_ADHOC_11A_TURB,
1719 BMZERO,
1720 BMZERO,
1721 BMZERO,
1722 BM(F2_2412_2462, F1_2467_2472, F2_2484_2484, -1, -1, -1, -1, -1,
1723 -1, -1, -1, -1),
1724 BM(G2_2412_2462, G1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1725 -1),
1726 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1727
1728 {MKKC, MKK, NO_DFS, NO_PSCAN, NO_REQ,
1729 BMZERO,
1730 BMZERO,
1731 BMZERO,
1732 BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1733 BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1734 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1735
1736 {WORLD, ETSI, NO_DFS, NO_PSCAN, NO_REQ,
1737 BMZERO,
1738 BMZERO,
1739 BMZERO,
1740 BM(F2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1741 BM(G2_2412_2472, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1742 BM(T2_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1743
1744 {WOR0_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1745 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1746 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1747 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1748 -1, -1, -1, -1, -1),
1749 BMZERO,
1750 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1751 W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
1752 -1, -1),
1753 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1754 -1, -1),
1755 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1756
1757 {WOR01_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
1758 ADHOC_PER_11D,
1759 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1760 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1761 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1762 -1, -1, -1, -1, -1),
1763 BMZERO,
1764 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
1765 W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1766 BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1767 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1768
1769 {WOR02_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR,
1770 ADHOC_PER_11D,
1771 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1772 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1773 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1774 -1, -1, -1, -1, -1),
1775 BMZERO,
1776 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1777 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1778 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1779 -1, -1),
1780 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1781
1782 {EU1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1783 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1784 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1785 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1786 -1, -1, -1, -1, -1),
1787 BMZERO,
1788 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W2_2472_2472,
1789 W1_2417_2432, W1_2447_2457, W2_2467_2467, -1, -1, -1, -1, -1),
1790 BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1791 -1, -1),
1792 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1793
1794 {WOR1_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1795 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1796 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1797 BMZERO,
1798 BMZERO,
1799 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1800 W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
1801 -1, -1),
1802 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1803 -1, -1),
1804 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1805
1806 {WOR2_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1807 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825,
1808 W1_5500_5700, -1, -1, -1, -1, -1, -1, -1),
1809 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1810 -1, -1, -1, -1, -1),
1811 BMZERO,
1812 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1813 W1_2417_2432, W1_2447_2457, W1_2467_2467, W1_2484_2484, -1, -1,
1814 -1, -1),
1815 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1816 -1, -1),
1817 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1818
1819 {WOR3_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_PER_11D,
1820 BM(W1_5260_5320, W1_5180_5240, W1_5170_5230, W1_5745_5825, -1, -1,
1821 -1, -1, -1, -1, -1, -1),
1822 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1823 -1, -1, -1, -1, -1),
1824 BMZERO,
1825 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1826 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1827 BM(WG1_2412_2462, WG2_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1828 -1, -1),
1829 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1830
1831 {WOR4_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1832 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
1833 -1, -1, -1, -1),
1834 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1835 -1, -1, -1, -1, -1),
1836 BMZERO,
1837 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
1838 W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1839 BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1840 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1841
1842 {WOR5_ETSIC, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1843 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, -1, -1, -1, -1, -1,
1844 -1, -1, -1, -1),
1845 BMZERO,
1846 BMZERO,
1847 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1848 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1849 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1850 -1, -1),
1851 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1852
1853 {WOR9_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1854 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
1855 -1, -1, -1, -1, -1, -1),
1856 BM(WT1_5210_5250, WT1_5290_5290, WT1_5760_5800, -1, -1, -1, -1,
1857 -1, -1, -1, -1, -1),
1858 BMZERO,
1859 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2417_2432,
1860 W1_2447_2457, -1, -1, -1, -1, -1, -1, -1),
1861 BM(WG1_2412_2462, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1),
1862 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1863
1864 {WORA_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1865 BM(W1_5260_5320, W1_5180_5240, W1_5745_5825, W1_5500_5700, -1, -1,
1866 -1, -1, -1, -1, -1, -1),
1867 BMZERO,
1868 BMZERO,
1869 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1870 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1871 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1872 -1, -1),
1873 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1874
1875 {WORB_WORLD, NO_CTL, DFS_FCC3 | DFS_ETSI, PSCAN_WWR, ADHOC_NO_11A,
1876 BM(W1_5260_5320, W1_5180_5240, W1_5500_5700, -1, -1, -1, -1, -1,
1877 -1, -1, -1, -1),
1878 BMZERO,
1879 BMZERO,
1880 BM(W1_2412_2412, W1_2437_2442, W1_2462_2462, W1_2472_2472,
1881 W1_2417_2432, W1_2447_2457, W1_2467_2467, -1, -1, -1, -1, -1),
1882 BM(WG1_2412_2462, WG1_2467_2472, -1, -1, -1, -1, -1, -1, -1, -1,
1883 -1, -1),
1884 BM(T3_2437_2437, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)},
1885
1886 {NULL1, NO_CTL, NO_DFS, NO_PSCAN, NO_REQ,
1887 BMZERO,
1888 BMZERO,
1889 BMZERO,
1890 BMZERO,
1891 BMZERO,
1892 BMZERO}
1893};
1894
1895static const struct cmode modes[] = {
1896 {ATH9K_MODE_SEL_11A, CHANNEL_A},
1897 {ATH9K_MODE_SEL_11B, CHANNEL_B},
1898 {ATH9K_MODE_SEL_11G, CHANNEL_G},
1899 {ATH9K_MODE_SEL_11NG_HT20, CHANNEL_G_HT20},
1900 {ATH9K_MODE_SEL_11NG_HT40PLUS, CHANNEL_G_HT40PLUS},
1901 {ATH9K_MODE_SEL_11NG_HT40MINUS, CHANNEL_G_HT40MINUS},
1902 {ATH9K_MODE_SEL_11NA_HT20, CHANNEL_A_HT20},
1903 {ATH9K_MODE_SEL_11NA_HT40PLUS, CHANNEL_A_HT40PLUS},
1904 {ATH9K_MODE_SEL_11NA_HT40MINUS, CHANNEL_A_HT40MINUS},
1905};
1906
1907static struct japan_bandcheck j_bandcheck[] = {
1908 {F1_5170_5230, AR_EEPROM_EEREGCAP_EN_KK_U1_ODD},
1909 {F4_5180_5240, AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN},
1910 {F2_5260_5320, AR_EEPROM_EEREGCAP_EN_KK_U2},
1911 {F4_5500_5700, AR_EEPROM_EEREGCAP_EN_KK_MIDBAND}
1912};
1913
1914
1915#endif
diff --git a/drivers/net/wireless/ath9k/xmit.c b/drivers/net/wireless/ath9k/xmit.c
new file mode 100644
index 000000000000..f0297ee5d053
--- /dev/null
+++ b/drivers/net/wireless/ath9k/xmit.c
@@ -0,0 +1,2870 @@
1/*
2 * Copyright (c) 2008 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/*
18 * Implementation of transmit path.
19 */
20
21#include "core.h"
22
23#define BITS_PER_BYTE 8
24#define OFDM_PLCP_BITS 22
25#define HT_RC_2_MCS(_rc) ((_rc) & 0x0f)
26#define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1)
27#define L_STF 8
28#define L_LTF 8
29#define L_SIG 4
30#define HT_SIG 8
31#define HT_STF 4
32#define HT_LTF(_ns) (4 * (_ns))
33#define SYMBOL_TIME(_ns) ((_ns) << 2) /* ns * 4 us */
34#define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5) /* ns * 3.6 us */
35#define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
36#define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
37
38#define OFDM_SIFS_TIME 16
39
40static u32 bits_per_symbol[][2] = {
41 /* 20MHz 40MHz */
42 { 26, 54 }, /* 0: BPSK */
43 { 52, 108 }, /* 1: QPSK 1/2 */
44 { 78, 162 }, /* 2: QPSK 3/4 */
45 { 104, 216 }, /* 3: 16-QAM 1/2 */
46 { 156, 324 }, /* 4: 16-QAM 3/4 */
47 { 208, 432 }, /* 5: 64-QAM 2/3 */
48 { 234, 486 }, /* 6: 64-QAM 3/4 */
49 { 260, 540 }, /* 7: 64-QAM 5/6 */
50 { 52, 108 }, /* 8: BPSK */
51 { 104, 216 }, /* 9: QPSK 1/2 */
52 { 156, 324 }, /* 10: QPSK 3/4 */
53 { 208, 432 }, /* 11: 16-QAM 1/2 */
54 { 312, 648 }, /* 12: 16-QAM 3/4 */
55 { 416, 864 }, /* 13: 64-QAM 2/3 */
56 { 468, 972 }, /* 14: 64-QAM 3/4 */
57 { 520, 1080 }, /* 15: 64-QAM 5/6 */
58};
59
60#define IS_HT_RATE(_rate) ((_rate) & 0x80)
61
62/*
63 * Insert a chain of ath_buf (descriptors) on a multicast txq
64 * but do NOT start tx DMA on this queue.
65 * NB: must be called with txq lock held
66 */
67
68static void ath_tx_mcastqaddbuf(struct ath_softc *sc,
69 struct ath_txq *txq,
70 struct list_head *head)
71{
72 struct ath_hal *ah = sc->sc_ah;
73 struct ath_buf *bf;
74
75 if (list_empty(head))
76 return;
77
78 /*
79 * Insert the frame on the outbound list and
80 * pass it on to the hardware.
81 */
82 bf = list_first_entry(head, struct ath_buf, list);
83
84 /*
85 * The CAB queue is started from the SWBA handler since
86 * frames only go out on DTIM and to avoid possible races.
87 */
88 ath9k_hw_set_interrupts(ah, 0);
89
90 /*
91 * If there is anything in the mcastq, we want to set
92 * the "more data" bit in the last item in the queue to
93 * indicate that there is "more data". It makes sense to add
94 * it here since you are *always* going to have
95 * more data when adding to this queue, no matter where
96 * you call from.
97 */
98
99 if (txq->axq_depth) {
100 struct ath_buf *lbf;
101 struct ieee80211_hdr *hdr;
102
103 /*
104 * Add the "more data flag" to the last frame
105 */
106
107 lbf = list_entry(txq->axq_q.prev, struct ath_buf, list);
108 hdr = (struct ieee80211_hdr *)
109 ((struct sk_buff *)(lbf->bf_mpdu))->data;
110 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_MOREDATA);
111 }
112
113 /*
114 * Now, concat the frame onto the queue
115 */
116 list_splice_tail_init(head, &txq->axq_q);
117 txq->axq_depth++;
118 txq->axq_totalqueued++;
119 txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
120
121 DPRINTF(sc, ATH_DBG_QUEUE,
122 "%s: txq depth = %d\n", __func__, txq->axq_depth);
123 if (txq->axq_link != NULL) {
124 *txq->axq_link = bf->bf_daddr;
125 DPRINTF(sc, ATH_DBG_XMIT,
126 "%s: link[%u](%p)=%llx (%p)\n",
127 __func__,
128 txq->axq_qnum, txq->axq_link,
129 ito64(bf->bf_daddr), bf->bf_desc);
130 }
131 txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
132 ath9k_hw_set_interrupts(ah, sc->sc_imask);
133}
134
135/*
136 * Insert a chain of ath_buf (descriptors) on a txq and
137 * assume the descriptors are already chained together by caller.
138 * NB: must be called with txq lock held
139 */
140
141static void ath_tx_txqaddbuf(struct ath_softc *sc,
142 struct ath_txq *txq, struct list_head *head)
143{
144 struct ath_hal *ah = sc->sc_ah;
145 struct ath_buf *bf;
146 /*
147 * Insert the frame on the outbound list and
148 * pass it on to the hardware.
149 */
150
151 if (list_empty(head))
152 return;
153
154 bf = list_first_entry(head, struct ath_buf, list);
155
156 list_splice_tail_init(head, &txq->axq_q);
157 txq->axq_depth++;
158 txq->axq_totalqueued++;
159 txq->axq_linkbuf = list_entry(txq->axq_q.prev, struct ath_buf, list);
160
161 DPRINTF(sc, ATH_DBG_QUEUE,
162 "%s: txq depth = %d\n", __func__, txq->axq_depth);
163
164 if (txq->axq_link == NULL) {
165 ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
166 DPRINTF(sc, ATH_DBG_XMIT,
167 "%s: TXDP[%u] = %llx (%p)\n",
168 __func__, txq->axq_qnum,
169 ito64(bf->bf_daddr), bf->bf_desc);
170 } else {
171 *txq->axq_link = bf->bf_daddr;
172 DPRINTF(sc, ATH_DBG_XMIT, "%s: link[%u] (%p)=%llx (%p)\n",
173 __func__,
174 txq->axq_qnum, txq->axq_link,
175 ito64(bf->bf_daddr), bf->bf_desc);
176 }
177 txq->axq_link = &(bf->bf_lastbf->bf_desc->ds_link);
178 ath9k_hw_txstart(ah, txq->axq_qnum);
179}
180
181/* Get transmit rate index using rate in Kbps */
182
183static int ath_tx_findindex(const struct ath9k_rate_table *rt, int rate)
184{
185 int i;
186 int ndx = 0;
187
188 for (i = 0; i < rt->rateCount; i++) {
189 if (rt->info[i].rateKbps == rate) {
190 ndx = i;
191 break;
192 }
193 }
194
195 return ndx;
196}
197
198/* Check if it's okay to send out aggregates */
199
200static int ath_aggr_query(struct ath_softc *sc,
201 struct ath_node *an, u8 tidno)
202{
203 struct ath_atx_tid *tid;
204 tid = ATH_AN_2_TID(an, tidno);
205
206 if (tid->addba_exchangecomplete || tid->addba_exchangeinprogress)
207 return 1;
208 else
209 return 0;
210}
211
212static enum ath9k_pkt_type get_hal_packet_type(struct ieee80211_hdr *hdr)
213{
214 enum ath9k_pkt_type htype;
215 __le16 fc;
216
217 fc = hdr->frame_control;
218
219 /* Calculate Atheros packet type from IEEE80211 packet header */
220
221 if (ieee80211_is_beacon(fc))
222 htype = ATH9K_PKT_TYPE_BEACON;
223 else if (ieee80211_is_probe_resp(fc))
224 htype = ATH9K_PKT_TYPE_PROBE_RESP;
225 else if (ieee80211_is_atim(fc))
226 htype = ATH9K_PKT_TYPE_ATIM;
227 else if (ieee80211_is_pspoll(fc))
228 htype = ATH9K_PKT_TYPE_PSPOLL;
229 else
230 htype = ATH9K_PKT_TYPE_NORMAL;
231
232 return htype;
233}
234
235static void fill_min_rates(struct sk_buff *skb, struct ath_tx_control *txctl)
236{
237 struct ieee80211_hdr *hdr;
238 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
239 struct ath_tx_info_priv *tx_info_priv;
240 __le16 fc;
241
242 hdr = (struct ieee80211_hdr *)skb->data;
243 fc = hdr->frame_control;
244 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
245
246 if (ieee80211_is_mgmt(fc) || ieee80211_is_ctl(fc)) {
247 txctl->use_minrate = 1;
248 txctl->min_rate = tx_info_priv->min_rate;
249 } else if (ieee80211_is_data(fc)) {
250 if (ieee80211_is_nullfunc(fc) ||
251 /* Port Access Entity (IEEE 802.1X) */
252 (skb->protocol == cpu_to_be16(0x888E))) {
253 txctl->use_minrate = 1;
254 txctl->min_rate = tx_info_priv->min_rate;
255 }
256 if (is_multicast_ether_addr(hdr->addr1))
257 txctl->mcast_rate = tx_info_priv->min_rate;
258 }
259
260}
261
262/* This function will setup additional txctl information, mostly rate stuff */
263/* FIXME: seqno, ps */
264static int ath_tx_prepare(struct ath_softc *sc,
265 struct sk_buff *skb,
266 struct ath_tx_control *txctl)
267{
268 struct ieee80211_hw *hw = sc->hw;
269 struct ieee80211_hdr *hdr;
270 struct ath_rc_series *rcs;
271 struct ath_txq *txq = NULL;
272 const struct ath9k_rate_table *rt;
273 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
274 struct ath_tx_info_priv *tx_info_priv;
275 int hdrlen;
276 u8 rix, antenna;
277 __le16 fc;
278 u8 *qc;
279
280 memset(txctl, 0, sizeof(struct ath_tx_control));
281
282 txctl->dev = sc;
283 hdr = (struct ieee80211_hdr *)skb->data;
284 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
285 fc = hdr->frame_control;
286
287 rt = sc->sc_currates;
288 BUG_ON(!rt);
289
290 /* Fill misc fields */
291
292 spin_lock_bh(&sc->node_lock);
293 txctl->an = ath_node_get(sc, hdr->addr1);
294 /* create a temp node, if the node is not there already */
295 if (!txctl->an)
296 txctl->an = ath_node_attach(sc, hdr->addr1, 0);
297 spin_unlock_bh(&sc->node_lock);
298
299 if (ieee80211_is_data_qos(fc)) {
300 qc = ieee80211_get_qos_ctl(hdr);
301 txctl->tidno = qc[0] & 0xf;
302 }
303
304 txctl->if_id = 0;
305 txctl->nextfraglen = 0;
306 txctl->frmlen = skb->len + FCS_LEN - (hdrlen & 3);
307 txctl->txpower = MAX_RATE_POWER; /* FIXME */
308
309 /* Fill Key related fields */
310
311 txctl->keytype = ATH9K_KEY_TYPE_CLEAR;
312 txctl->keyix = ATH9K_TXKEYIX_INVALID;
313
314 if (tx_info->control.hw_key) {
315 txctl->keyix = tx_info->control.hw_key->hw_key_idx;
316 txctl->frmlen += tx_info->control.icv_len;
317
318 if (sc->sc_keytype == ATH9K_CIPHER_WEP)
319 txctl->keytype = ATH9K_KEY_TYPE_WEP;
320 else if (sc->sc_keytype == ATH9K_CIPHER_TKIP)
321 txctl->keytype = ATH9K_KEY_TYPE_TKIP;
322 else if (sc->sc_keytype == ATH9K_CIPHER_AES_CCM)
323 txctl->keytype = ATH9K_KEY_TYPE_AES;
324 }
325
326 /* Fill packet type */
327
328 txctl->atype = get_hal_packet_type(hdr);
329
330 /* Fill qnum */
331
332 txctl->qnum = ath_get_hal_qnum(skb_get_queue_mapping(skb), sc);
333 txq = &sc->sc_txq[txctl->qnum];
334 spin_lock_bh(&txq->axq_lock);
335
336 /* Try to avoid running out of descriptors */
337 if (txq->axq_depth >= (ATH_TXBUF - 20)) {
338 DPRINTF(sc, ATH_DBG_FATAL,
339 "%s: TX queue: %d is full, depth: %d\n",
340 __func__,
341 txctl->qnum,
342 txq->axq_depth);
343 ieee80211_stop_queue(hw, skb_get_queue_mapping(skb));
344 txq->stopped = 1;
345 spin_unlock_bh(&txq->axq_lock);
346 return -1;
347 }
348
349 spin_unlock_bh(&txq->axq_lock);
350
351 /* Fill rate */
352
353 fill_min_rates(skb, txctl);
354
355 /* Fill flags */
356
357 txctl->flags = ATH9K_TXDESC_CLRDMASK; /* needed for crypto errors */
358
359 if (tx_info->flags & IEEE80211_TX_CTL_NO_ACK)
360 tx_info->flags |= ATH9K_TXDESC_NOACK;
361 if (tx_info->flags & IEEE80211_TX_CTL_USE_RTS_CTS)
362 tx_info->flags |= ATH9K_TXDESC_RTSENA;
363
364 /*
365 * Setup for rate calculations.
366 */
367 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
368 rcs = tx_info_priv->rcs;
369
370 if (ieee80211_is_data(fc) && !txctl->use_minrate) {
371
372 /* Enable HT only for DATA frames and not for EAPOL */
373 txctl->ht = (hw->conf.ht_conf.ht_supported &&
374 (tx_info->flags & IEEE80211_TX_CTL_AMPDU));
375
376 if (is_multicast_ether_addr(hdr->addr1)) {
377 rcs[0].rix = (u8)
378 ath_tx_findindex(rt, txctl->mcast_rate);
379
380 /*
381 * mcast packets are not re-tried.
382 */
383 rcs[0].tries = 1;
384 }
385 /* For HT capable stations, we save tidno for later use.
386 * We also override seqno set by upper layer with the one
387 * in tx aggregation state.
388 *
389 * First, the fragmentation stat is determined.
390 * If fragmentation is on, the sequence number is
391 * not overridden, since it has been
392 * incremented by the fragmentation routine.
393 */
394 if (likely(!(txctl->flags & ATH9K_TXDESC_FRAG_IS_ON)) &&
395 txctl->ht && sc->sc_txaggr) {
396 struct ath_atx_tid *tid;
397
398 tid = ATH_AN_2_TID(txctl->an, txctl->tidno);
399
400 hdr->seq_ctrl = cpu_to_le16(tid->seq_next <<
401 IEEE80211_SEQ_SEQ_SHIFT);
402 txctl->seqno = tid->seq_next;
403 INCR(tid->seq_next, IEEE80211_SEQ_MAX);
404 }
405 } else {
406 /* for management and control frames,
407 * or for NULL and EAPOL frames */
408 if (txctl->min_rate)
409 rcs[0].rix = ath_rate_findrateix(sc, txctl->min_rate);
410 else
411 rcs[0].rix = sc->sc_minrateix;
412 rcs[0].tries = ATH_MGT_TXMAXTRY;
413 }
414 rix = rcs[0].rix;
415
416 /*
417 * Calculate duration. This logically belongs in the 802.11
418 * layer but it lacks sufficient information to calculate it.
419 */
420 if ((txctl->flags & ATH9K_TXDESC_NOACK) == 0 && !ieee80211_is_ctl(fc)) {
421 u16 dur;
422 /*
423 * XXX not right with fragmentation.
424 */
425 if (sc->sc_flags & ATH_PREAMBLE_SHORT)
426 dur = rt->info[rix].spAckDuration;
427 else
428 dur = rt->info[rix].lpAckDuration;
429
430 if (le16_to_cpu(hdr->frame_control) &
431 IEEE80211_FCTL_MOREFRAGS) {
432 dur += dur; /* Add additional 'SIFS + ACK' */
433
434 /*
435 ** Compute size of next fragment in order to compute
436 ** durations needed to update NAV.
437 ** The last fragment uses the ACK duration only.
438 ** Add time for next fragment.
439 */
440 dur += ath9k_hw_computetxtime(sc->sc_ah, rt,
441 txctl->nextfraglen,
442 rix, sc->sc_flags & ATH_PREAMBLE_SHORT);
443 }
444
445 if (ieee80211_has_morefrags(fc) ||
446 (le16_to_cpu(hdr->seq_ctrl) & IEEE80211_SCTL_FRAG)) {
447 /*
448 ** Force hardware to use computed duration for next
449 ** fragment by disabling multi-rate retry, which
450 ** updates duration based on the multi-rate
451 ** duration table.
452 */
453 rcs[1].tries = rcs[2].tries = rcs[3].tries = 0;
454 rcs[1].rix = rcs[2].rix = rcs[3].rix = 0;
455 /* reset tries but keep rate index */
456 rcs[0].tries = ATH_TXMAXTRY;
457 }
458
459 hdr->duration_id = cpu_to_le16(dur);
460 }
461
462 /*
463 * Determine if a tx interrupt should be generated for
464 * this descriptor. We take a tx interrupt to reap
465 * descriptors when the h/w hits an EOL condition or
466 * when the descriptor is specifically marked to generate
467 * an interrupt. We periodically mark descriptors in this
468 * way to insure timely replenishing of the supply needed
469 * for sending frames. Defering interrupts reduces system
470 * load and potentially allows more concurrent work to be
471 * done but if done to aggressively can cause senders to
472 * backup.
473 *
474 * NB: use >= to deal with sc_txintrperiod changing
475 * dynamically through sysctl.
476 */
477 spin_lock_bh(&txq->axq_lock);
478 if ((++txq->axq_intrcnt >= sc->sc_txintrperiod)) {
479 txctl->flags |= ATH9K_TXDESC_INTREQ;
480 txq->axq_intrcnt = 0;
481 }
482 spin_unlock_bh(&txq->axq_lock);
483
484 if (is_multicast_ether_addr(hdr->addr1)) {
485 antenna = sc->sc_mcastantenna + 1;
486 sc->sc_mcastantenna = (sc->sc_mcastantenna + 1) & 0x1;
487 } else
488 antenna = sc->sc_txantenna;
489
490#ifdef USE_LEGACY_HAL
491 txctl->antenna = antenna;
492#endif
493 return 0;
494}
495
496/* To complete a chain of buffers associated a frame */
497
498static void ath_tx_complete_buf(struct ath_softc *sc,
499 struct ath_buf *bf,
500 struct list_head *bf_q,
501 int txok, int sendbar)
502{
503 struct sk_buff *skb = bf->bf_mpdu;
504 struct ath_xmit_status tx_status;
505 dma_addr_t *pa;
506
507 /*
508 * Set retry information.
509 * NB: Don't use the information in the descriptor, because the frame
510 * could be software retried.
511 */
512 tx_status.retries = bf->bf_retries;
513 tx_status.flags = 0;
514
515 if (sendbar)
516 tx_status.flags = ATH_TX_BAR;
517
518 if (!txok) {
519 tx_status.flags |= ATH_TX_ERROR;
520
521 if (bf->bf_isxretried)
522 tx_status.flags |= ATH_TX_XRETRY;
523 }
524 /* Unmap this frame */
525 pa = get_dma_mem_context(bf, bf_dmacontext);
526 pci_unmap_single(sc->pdev,
527 *pa,
528 skb->len,
529 PCI_DMA_TODEVICE);
530 /* complete this frame */
531 ath_tx_complete(sc, skb, &tx_status, bf->bf_node);
532
533 /*
534 * Return the list of ath_buf of this mpdu to free queue
535 */
536 spin_lock_bh(&sc->sc_txbuflock);
537 list_splice_tail_init(bf_q, &sc->sc_txbuf);
538 spin_unlock_bh(&sc->sc_txbuflock);
539}
540
541/*
542 * queue up a dest/ac pair for tx scheduling
543 * NB: must be called with txq lock held
544 */
545
546static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
547{
548 struct ath_atx_ac *ac = tid->ac;
549
550 /*
551 * if tid is paused, hold off
552 */
553 if (tid->paused)
554 return;
555
556 /*
557 * add tid to ac atmost once
558 */
559 if (tid->sched)
560 return;
561
562 tid->sched = true;
563 list_add_tail(&tid->list, &ac->tid_q);
564
565 /*
566 * add node ac to txq atmost once
567 */
568 if (ac->sched)
569 return;
570
571 ac->sched = true;
572 list_add_tail(&ac->list, &txq->axq_acq);
573}
574
575/* pause a tid */
576
577static void ath_tx_pause_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
578{
579 struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
580
581 spin_lock_bh(&txq->axq_lock);
582
583 tid->paused++;
584
585 spin_unlock_bh(&txq->axq_lock);
586}
587
588/* resume a tid and schedule aggregate */
589
590void ath_tx_resume_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
591{
592 struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
593
594 ASSERT(tid->paused > 0);
595 spin_lock_bh(&txq->axq_lock);
596
597 tid->paused--;
598
599 if (tid->paused > 0)
600 goto unlock;
601
602 if (list_empty(&tid->buf_q))
603 goto unlock;
604
605 /*
606 * Add this TID to scheduler and try to send out aggregates
607 */
608 ath_tx_queue_tid(txq, tid);
609 ath_txq_schedule(sc, txq);
610unlock:
611 spin_unlock_bh(&txq->axq_lock);
612}
613
614/* Compute the number of bad frames */
615
616static int ath_tx_num_badfrms(struct ath_softc *sc,
617 struct ath_buf *bf, int txok)
618{
619 struct ath_node *an = bf->bf_node;
620 int isnodegone = (an->an_flags & ATH_NODE_CLEAN);
621 struct ath_buf *bf_last = bf->bf_lastbf;
622 struct ath_desc *ds = bf_last->bf_desc;
623 u16 seq_st = 0;
624 u32 ba[WME_BA_BMP_SIZE >> 5];
625 int ba_index;
626 int nbad = 0;
627 int isaggr = 0;
628
629 if (isnodegone || ds->ds_txstat.ts_flags == ATH9K_TX_SW_ABORTED)
630 return 0;
631
632 isaggr = bf->bf_isaggr;
633 if (isaggr) {
634 seq_st = ATH_DS_BA_SEQ(ds);
635 memcpy(ba, ATH_DS_BA_BITMAP(ds), WME_BA_BMP_SIZE >> 3);
636 }
637
638 while (bf) {
639 ba_index = ATH_BA_INDEX(seq_st, bf->bf_seqno);
640 if (!txok || (isaggr && !ATH_BA_ISSET(ba, ba_index)))
641 nbad++;
642
643 bf = bf->bf_next;
644 }
645
646 return nbad;
647}
648
649static void ath_tx_set_retry(struct ath_softc *sc, struct ath_buf *bf)
650{
651 struct sk_buff *skb;
652 struct ieee80211_hdr *hdr;
653
654 bf->bf_isretried = 1;
655 bf->bf_retries++;
656
657 skb = bf->bf_mpdu;
658 hdr = (struct ieee80211_hdr *)skb->data;
659 hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_RETRY);
660}
661
662/* Update block ack window */
663
664static void ath_tx_update_baw(struct ath_softc *sc,
665 struct ath_atx_tid *tid, int seqno)
666{
667 int index, cindex;
668
669 index = ATH_BA_INDEX(tid->seq_start, seqno);
670 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
671
672 tid->tx_buf[cindex] = NULL;
673
674 while (tid->baw_head != tid->baw_tail && !tid->tx_buf[tid->baw_head]) {
675 INCR(tid->seq_start, IEEE80211_SEQ_MAX);
676 INCR(tid->baw_head, ATH_TID_MAX_BUFS);
677 }
678}
679
680/*
681 * ath_pkt_dur - compute packet duration (NB: not NAV)
682 *
683 * rix - rate index
684 * pktlen - total bytes (delims + data + fcs + pads + pad delims)
685 * width - 0 for 20 MHz, 1 for 40 MHz
686 * half_gi - to use 4us v/s 3.6 us for symbol time
687 */
688
689static u32 ath_pkt_duration(struct ath_softc *sc,
690 u8 rix,
691 struct ath_buf *bf,
692 int width,
693 int half_gi,
694 bool shortPreamble)
695{
696 const struct ath9k_rate_table *rt = sc->sc_currates;
697 u32 nbits, nsymbits, duration, nsymbols;
698 u8 rc;
699 int streams, pktlen;
700
701 pktlen = bf->bf_isaggr ? bf->bf_al : bf->bf_frmlen;
702 rc = rt->info[rix].rateCode;
703
704 /*
705 * for legacy rates, use old function to compute packet duration
706 */
707 if (!IS_HT_RATE(rc))
708 return ath9k_hw_computetxtime(sc->sc_ah,
709 rt,
710 pktlen,
711 rix,
712 shortPreamble);
713 /*
714 * find number of symbols: PLCP + data
715 */
716 nbits = (pktlen << 3) + OFDM_PLCP_BITS;
717 nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
718 nsymbols = (nbits + nsymbits - 1) / nsymbits;
719
720 if (!half_gi)
721 duration = SYMBOL_TIME(nsymbols);
722 else
723 duration = SYMBOL_TIME_HALFGI(nsymbols);
724
725 /*
726 * addup duration for legacy/ht training and signal fields
727 */
728 streams = HT_RC_2_STREAMS(rc);
729 duration += L_STF + L_LTF + L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
730 return duration;
731}
732
733/* Rate module function to set rate related fields in tx descriptor */
734
735static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf)
736{
737 struct ath_hal *ah = sc->sc_ah;
738 const struct ath9k_rate_table *rt;
739 struct ath_desc *ds = bf->bf_desc;
740 struct ath_desc *lastds = bf->bf_lastbf->bf_desc;
741 struct ath9k_11n_rate_series series[4];
742 int i, flags, rtsctsena = 0, dynamic_mimops = 0;
743 u32 ctsduration = 0;
744 u8 rix = 0, cix, ctsrate = 0;
745 u32 aggr_limit_with_rts = sc->sc_rtsaggrlimit;
746 struct ath_node *an = (struct ath_node *) bf->bf_node;
747
748 /*
749 * get the cix for the lowest valid rix.
750 */
751 rt = sc->sc_currates;
752 for (i = 4; i--;) {
753 if (bf->bf_rcs[i].tries) {
754 rix = bf->bf_rcs[i].rix;
755 break;
756 }
757 }
758 flags = (bf->bf_flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA));
759 cix = rt->info[rix].controlRate;
760
761 /*
762 * If 802.11g protection is enabled, determine whether
763 * to use RTS/CTS or just CTS. Note that this is only
764 * done for OFDM/HT unicast frames.
765 */
766 if (sc->sc_protmode != PROT_M_NONE &&
767 (rt->info[rix].phy == PHY_OFDM ||
768 rt->info[rix].phy == PHY_HT) &&
769 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
770 if (sc->sc_protmode == PROT_M_RTSCTS)
771 flags = ATH9K_TXDESC_RTSENA;
772 else if (sc->sc_protmode == PROT_M_CTSONLY)
773 flags = ATH9K_TXDESC_CTSENA;
774
775 cix = rt->info[sc->sc_protrix].controlRate;
776 rtsctsena = 1;
777 }
778
779 /* For 11n, the default behavior is to enable RTS for
780 * hw retried frames. We enable the global flag here and
781 * let rate series flags determine which rates will actually
782 * use RTS.
783 */
784 if (ah->ah_caps.halHTSupport && bf->bf_isdata) {
785 BUG_ON(!an);
786 /*
787 * 802.11g protection not needed, use our default behavior
788 */
789 if (!rtsctsena)
790 flags = ATH9K_TXDESC_RTSENA;
791 /*
792 * For dynamic MIMO PS, RTS needs to precede the first aggregate
793 * and the second aggregate should have any protection at all.
794 */
795 if (an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) {
796 if (!bf->bf_aggrburst) {
797 flags = ATH9K_TXDESC_RTSENA;
798 dynamic_mimops = 1;
799 } else {
800 flags = 0;
801 }
802 }
803 }
804
805 /*
806 * Set protection if aggregate protection on
807 */
808 if (sc->sc_config.ath_aggr_prot &&
809 (!bf->bf_isaggr || (bf->bf_isaggr && bf->bf_al < 8192))) {
810 flags = ATH9K_TXDESC_RTSENA;
811 cix = rt->info[sc->sc_protrix].controlRate;
812 rtsctsena = 1;
813 }
814
815 /*
816 * For AR5416 - RTS cannot be followed by a frame larger than 8K.
817 */
818 if (bf->bf_isaggr && (bf->bf_al > aggr_limit_with_rts)) {
819 /*
820 * Ensure that in the case of SM Dynamic power save
821 * while we are bursting the second aggregate the
822 * RTS is cleared.
823 */
824 flags &= ~(ATH9K_TXDESC_RTSENA);
825 }
826
827 /*
828 * CTS transmit rate is derived from the transmit rate
829 * by looking in the h/w rate table. We must also factor
830 * in whether or not a short preamble is to be used.
831 */
832 /* NB: cix is set above where RTS/CTS is enabled */
833 BUG_ON(cix == 0xff);
834 ctsrate = rt->info[cix].rateCode |
835 (bf->bf_shpreamble ? rt->info[cix].shortPreamble : 0);
836
837 /*
838 * Setup HAL rate series
839 */
840 memzero(series, sizeof(struct ath9k_11n_rate_series) * 4);
841
842 for (i = 0; i < 4; i++) {
843 if (!bf->bf_rcs[i].tries)
844 continue;
845
846 rix = bf->bf_rcs[i].rix;
847
848 series[i].Rate = rt->info[rix].rateCode |
849 (bf->bf_shpreamble ? rt->info[rix].shortPreamble : 0);
850
851 series[i].Tries = bf->bf_rcs[i].tries;
852
853 series[i].RateFlags = (
854 (bf->bf_rcs[i].flags & ATH_RC_RTSCTS_FLAG) ?
855 ATH9K_RATESERIES_RTS_CTS : 0) |
856 ((bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) ?
857 ATH9K_RATESERIES_2040 : 0) |
858 ((bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG) ?
859 ATH9K_RATESERIES_HALFGI : 0);
860
861 series[i].PktDuration = ath_pkt_duration(
862 sc, rix, bf,
863 (bf->bf_rcs[i].flags & ATH_RC_CW40_FLAG) != 0,
864 (bf->bf_rcs[i].flags & ATH_RC_SGI_FLAG),
865 bf->bf_shpreamble);
866
867 if ((an->an_smmode == ATH_SM_PWRSAV_STATIC) &&
868 (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG) == 0) {
869 /*
870 * When sending to an HT node that has enabled static
871 * SM/MIMO power save, send at single stream rates but
872 * use maximum allowed transmit chains per user,
873 * hardware, regulatory, or country limits for
874 * better range.
875 */
876 series[i].ChSel = sc->sc_tx_chainmask;
877 } else {
878 if (bf->bf_ht)
879 series[i].ChSel =
880 ath_chainmask_sel_logic(sc, an);
881 else
882 series[i].ChSel = sc->sc_tx_chainmask;
883 }
884
885 if (rtsctsena)
886 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
887
888 /*
889 * Set RTS for all rates if node is in dynamic powersave
890 * mode and we are using dual stream rates.
891 */
892 if (dynamic_mimops && (bf->bf_rcs[i].flags & ATH_RC_DS_FLAG))
893 series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
894 }
895
896 /*
897 * For non-HT devices, calculate RTS/CTS duration in software
898 * and disable multi-rate retry.
899 */
900 if (flags && !ah->ah_caps.halHTSupport) {
901 /*
902 * Compute the transmit duration based on the frame
903 * size and the size of an ACK frame. We call into the
904 * HAL to do the computation since it depends on the
905 * characteristics of the actual PHY being used.
906 *
907 * NB: CTS is assumed the same size as an ACK so we can
908 * use the precalculated ACK durations.
909 */
910 if (flags & ATH9K_TXDESC_RTSENA) { /* SIFS + CTS */
911 ctsduration += bf->bf_shpreamble ?
912 rt->info[cix].spAckDuration :
913 rt->info[cix].lpAckDuration;
914 }
915
916 ctsduration += series[0].PktDuration;
917
918 if ((bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) { /* SIFS + ACK */
919 ctsduration += bf->bf_shpreamble ?
920 rt->info[rix].spAckDuration :
921 rt->info[rix].lpAckDuration;
922 }
923
924 /*
925 * Disable multi-rate retry when using RTS/CTS by clearing
926 * series 1, 2 and 3.
927 */
928 memzero(&series[1], sizeof(struct ath9k_11n_rate_series) * 3);
929 }
930
931 /*
932 * set dur_update_en for l-sig computation except for PS-Poll frames
933 */
934 ath9k_hw_set11n_ratescenario(ah, ds, lastds,
935 !bf->bf_ispspoll,
936 ctsrate,
937 ctsduration,
938 series, 4, flags);
939 if (sc->sc_config.ath_aggr_prot && flags)
940 ath9k_hw_set11n_burstduration(ah, ds, 8192);
941}
942
943/*
944 * Function to send a normal HT (non-AMPDU) frame
945 * NB: must be called with txq lock held
946 */
947
948static int ath_tx_send_normal(struct ath_softc *sc,
949 struct ath_txq *txq,
950 struct ath_atx_tid *tid,
951 struct list_head *bf_head)
952{
953 struct ath_buf *bf;
954 struct sk_buff *skb;
955 struct ieee80211_tx_info *tx_info;
956 struct ath_tx_info_priv *tx_info_priv;
957
958 BUG_ON(list_empty(bf_head));
959
960 bf = list_first_entry(bf_head, struct ath_buf, list);
961 bf->bf_isampdu = 0; /* regular HT frame */
962
963 skb = (struct sk_buff *)bf->bf_mpdu;
964 tx_info = IEEE80211_SKB_CB(skb);
965 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
966 memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
967
968 /* update starting sequence number for subsequent ADDBA request */
969 INCR(tid->seq_start, IEEE80211_SEQ_MAX);
970
971 /* Queue to h/w without aggregation */
972 bf->bf_nframes = 1;
973 bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
974 ath_buf_set_rate(sc, bf);
975 ath_tx_txqaddbuf(sc, txq, bf_head);
976
977 return 0;
978}
979
980/* flush tid's software queue and send frames as non-ampdu's */
981
982static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
983{
984 struct ath_txq *txq = &sc->sc_txq[tid->ac->qnum];
985 struct ath_buf *bf;
986 struct list_head bf_head;
987 INIT_LIST_HEAD(&bf_head);
988
989 ASSERT(tid->paused > 0);
990 spin_lock_bh(&txq->axq_lock);
991
992 tid->paused--;
993
994 if (tid->paused > 0) {
995 spin_unlock_bh(&txq->axq_lock);
996 return;
997 }
998
999 while (!list_empty(&tid->buf_q)) {
1000 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
1001 ASSERT(!bf->bf_isretried);
1002 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
1003 ath_tx_send_normal(sc, txq, tid, &bf_head);
1004 }
1005
1006 spin_unlock_bh(&txq->axq_lock);
1007}
1008
1009/* Completion routine of an aggregate */
1010
1011static void ath_tx_complete_aggr_rifs(struct ath_softc *sc,
1012 struct ath_txq *txq,
1013 struct ath_buf *bf,
1014 struct list_head *bf_q,
1015 int txok)
1016{
1017 struct ath_node *an = bf->bf_node;
1018 struct ath_atx_tid *tid = ATH_AN_2_TID(an, bf->bf_tidno);
1019 struct ath_buf *bf_last = bf->bf_lastbf;
1020 struct ath_desc *ds = bf_last->bf_desc;
1021 struct ath_buf *bf_next, *bf_lastq = NULL;
1022 struct list_head bf_head, bf_pending;
1023 u16 seq_st = 0;
1024 u32 ba[WME_BA_BMP_SIZE >> 5];
1025 int isaggr, txfail, txpending, sendbar = 0, needreset = 0;
1026 int isnodegone = (an->an_flags & ATH_NODE_CLEAN);
1027
1028 isaggr = bf->bf_isaggr;
1029 if (isaggr) {
1030 if (txok) {
1031 if (ATH_DS_TX_BA(ds)) {
1032 /*
1033 * extract starting sequence and
1034 * block-ack bitmap
1035 */
1036 seq_st = ATH_DS_BA_SEQ(ds);
1037 memcpy(ba,
1038 ATH_DS_BA_BITMAP(ds),
1039 WME_BA_BMP_SIZE >> 3);
1040 } else {
1041 memzero(ba, WME_BA_BMP_SIZE >> 3);
1042
1043 /*
1044 * AR5416 can become deaf/mute when BA
1045 * issue happens. Chip needs to be reset.
1046 * But AP code may have sychronization issues
1047 * when perform internal reset in this routine.
1048 * Only enable reset in STA mode for now.
1049 */
1050 if (sc->sc_opmode == ATH9K_M_STA)
1051 needreset = 1;
1052 }
1053 } else {
1054 memzero(ba, WME_BA_BMP_SIZE >> 3);
1055 }
1056 }
1057
1058 INIT_LIST_HEAD(&bf_pending);
1059 INIT_LIST_HEAD(&bf_head);
1060
1061 while (bf) {
1062 txfail = txpending = 0;
1063 bf_next = bf->bf_next;
1064
1065 if (ATH_BA_ISSET(ba, ATH_BA_INDEX(seq_st, bf->bf_seqno))) {
1066 /* transmit completion, subframe is
1067 * acked by block ack */
1068 } else if (!isaggr && txok) {
1069 /* transmit completion */
1070 } else {
1071
1072 if (!tid->cleanup_inprogress && !isnodegone &&
1073 ds->ds_txstat.ts_flags != ATH9K_TX_SW_ABORTED) {
1074 if (bf->bf_retries < ATH_MAX_SW_RETRIES) {
1075 ath_tx_set_retry(sc, bf);
1076 txpending = 1;
1077 } else {
1078 bf->bf_isxretried = 1;
1079 txfail = 1;
1080 sendbar = 1;
1081 }
1082 } else {
1083 /*
1084 * cleanup in progress, just fail
1085 * the un-acked sub-frames
1086 */
1087 txfail = 1;
1088 }
1089 }
1090 /*
1091 * Remove ath_buf's of this sub-frame from aggregate queue.
1092 */
1093 if (bf_next == NULL) { /* last subframe in the aggregate */
1094 ASSERT(bf->bf_lastfrm == bf_last);
1095
1096 /*
1097 * The last descriptor of the last sub frame could be
1098 * a holding descriptor for h/w. If that's the case,
1099 * bf->bf_lastfrm won't be in the bf_q.
1100 * Make sure we handle bf_q properly here.
1101 */
1102
1103 if (!list_empty(bf_q)) {
1104 bf_lastq = list_entry(bf_q->prev,
1105 struct ath_buf, list);
1106 list_cut_position(&bf_head,
1107 bf_q, &bf_lastq->list);
1108 } else {
1109 /*
1110 * XXX: if the last subframe only has one
1111 * descriptor which is also being used as
1112 * a holding descriptor. Then the ath_buf
1113 * is not in the bf_q at all.
1114 */
1115 INIT_LIST_HEAD(&bf_head);
1116 }
1117 } else {
1118 ASSERT(!list_empty(bf_q));
1119 list_cut_position(&bf_head,
1120 bf_q, &bf->bf_lastfrm->list);
1121 }
1122
1123 if (!txpending) {
1124 /*
1125 * complete the acked-ones/xretried ones; update
1126 * block-ack window
1127 */
1128 spin_lock_bh(&txq->axq_lock);
1129 ath_tx_update_baw(sc, tid, bf->bf_seqno);
1130 spin_unlock_bh(&txq->axq_lock);
1131
1132 /* complete this sub-frame */
1133 ath_tx_complete_buf(sc, bf, &bf_head, !txfail, sendbar);
1134 } else {
1135 /*
1136 * retry the un-acked ones
1137 */
1138 /*
1139 * XXX: if the last descriptor is holding descriptor,
1140 * in order to requeue the frame to software queue, we
1141 * need to allocate a new descriptor and
1142 * copy the content of holding descriptor to it.
1143 */
1144 if (bf->bf_next == NULL &&
1145 bf_last->bf_status & ATH_BUFSTATUS_STALE) {
1146 struct ath_buf *tbf;
1147
1148 /* allocate new descriptor */
1149 spin_lock_bh(&sc->sc_txbuflock);
1150 ASSERT(!list_empty((&sc->sc_txbuf)));
1151 tbf = list_first_entry(&sc->sc_txbuf,
1152 struct ath_buf, list);
1153 list_del(&tbf->list);
1154 spin_unlock_bh(&sc->sc_txbuflock);
1155
1156 ATH_TXBUF_RESET(tbf);
1157
1158 /* copy descriptor content */
1159 tbf->bf_mpdu = bf_last->bf_mpdu;
1160 tbf->bf_node = bf_last->bf_node;
1161 tbf->bf_buf_addr = bf_last->bf_buf_addr;
1162 *(tbf->bf_desc) = *(bf_last->bf_desc);
1163
1164 /* link it to the frame */
1165 if (bf_lastq) {
1166 bf_lastq->bf_desc->ds_link =
1167 tbf->bf_daddr;
1168 bf->bf_lastfrm = tbf;
1169 ath9k_hw_cleartxdesc(sc->sc_ah,
1170 bf->bf_lastfrm->bf_desc);
1171 } else {
1172 tbf->bf_state = bf_last->bf_state;
1173 tbf->bf_lastfrm = tbf;
1174 ath9k_hw_cleartxdesc(sc->sc_ah,
1175 tbf->bf_lastfrm->bf_desc);
1176
1177 /* copy the DMA context */
1178 copy_dma_mem_context(
1179 get_dma_mem_context(tbf,
1180 bf_dmacontext),
1181 get_dma_mem_context(bf_last,
1182 bf_dmacontext));
1183 }
1184 list_add_tail(&tbf->list, &bf_head);
1185 } else {
1186 /*
1187 * Clear descriptor status words for
1188 * software retry
1189 */
1190 ath9k_hw_cleartxdesc(sc->sc_ah,
1191 bf->bf_lastfrm->bf_desc);
1192 }
1193
1194 /*
1195 * Put this buffer to the temporary pending
1196 * queue to retain ordering
1197 */
1198 list_splice_tail_init(&bf_head, &bf_pending);
1199 }
1200
1201 bf = bf_next;
1202 }
1203
1204 /*
1205 * node is already gone. no more assocication
1206 * with the node. the node might have been freed
1207 * any node acces can result in panic.note tid
1208 * is part of the node.
1209 */
1210 if (isnodegone)
1211 return;
1212
1213 if (tid->cleanup_inprogress) {
1214 /* check to see if we're done with cleaning the h/w queue */
1215 spin_lock_bh(&txq->axq_lock);
1216
1217 if (tid->baw_head == tid->baw_tail) {
1218 tid->addba_exchangecomplete = 0;
1219 tid->addba_exchangeattempts = 0;
1220 spin_unlock_bh(&txq->axq_lock);
1221
1222 tid->cleanup_inprogress = false;
1223
1224 /* send buffered frames as singles */
1225 ath_tx_flush_tid(sc, tid);
1226 } else
1227 spin_unlock_bh(&txq->axq_lock);
1228
1229 return;
1230 }
1231
1232 /*
1233 * prepend un-acked frames to the beginning of the pending frame queue
1234 */
1235 if (!list_empty(&bf_pending)) {
1236 spin_lock_bh(&txq->axq_lock);
1237 /* Note: we _prepend_, we _do_not_ at to
1238 * the end of the queue ! */
1239 list_splice(&bf_pending, &tid->buf_q);
1240 ath_tx_queue_tid(txq, tid);
1241 spin_unlock_bh(&txq->axq_lock);
1242 }
1243
1244 if (needreset)
1245 ath_internal_reset(sc);
1246
1247 return;
1248}
1249
1250/* Process completed xmit descriptors from the specified queue */
1251
1252static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
1253{
1254 struct ath_hal *ah = sc->sc_ah;
1255 struct ath_buf *bf, *lastbf, *bf_held = NULL;
1256 struct list_head bf_head;
1257 struct ath_desc *ds, *tmp_ds;
1258 struct sk_buff *skb;
1259 struct ieee80211_tx_info *tx_info;
1260 struct ath_tx_info_priv *tx_info_priv;
1261 int nacked, txok, nbad = 0, isrifs = 0;
1262 int status;
1263
1264 DPRINTF(sc, ATH_DBG_QUEUE,
1265 "%s: tx queue %d (%x), link %p\n", __func__,
1266 txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
1267 txq->axq_link);
1268
1269 nacked = 0;
1270 for (;;) {
1271 spin_lock_bh(&txq->axq_lock);
1272 txq->axq_intrcnt = 0; /* reset periodic desc intr count */
1273 if (list_empty(&txq->axq_q)) {
1274 txq->axq_link = NULL;
1275 txq->axq_linkbuf = NULL;
1276 spin_unlock_bh(&txq->axq_lock);
1277 break;
1278 }
1279 bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
1280
1281 /*
1282 * There is a race condition that a BH gets scheduled
1283 * after sw writes TxE and before hw re-load the last
1284 * descriptor to get the newly chained one.
1285 * Software must keep the last DONE descriptor as a
1286 * holding descriptor - software does so by marking
1287 * it with the STALE flag.
1288 */
1289 bf_held = NULL;
1290 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
1291 bf_held = bf;
1292 if (list_is_last(&bf_held->list, &txq->axq_q)) {
1293 /* FIXME:
1294 * The holding descriptor is the last
1295 * descriptor in queue. It's safe to remove
1296 * the last holding descriptor in BH context.
1297 */
1298 spin_unlock_bh(&txq->axq_lock);
1299 break;
1300 } else {
1301 /* Lets work with the next buffer now */
1302 bf = list_entry(bf_held->list.next,
1303 struct ath_buf, list);
1304 }
1305 }
1306
1307 lastbf = bf->bf_lastbf;
1308 ds = lastbf->bf_desc; /* NB: last decriptor */
1309
1310 status = ath9k_hw_txprocdesc(ah, ds);
1311 if (status == -EINPROGRESS) {
1312 spin_unlock_bh(&txq->axq_lock);
1313 break;
1314 }
1315 if (bf->bf_desc == txq->axq_lastdsWithCTS)
1316 txq->axq_lastdsWithCTS = NULL;
1317 if (ds == txq->axq_gatingds)
1318 txq->axq_gatingds = NULL;
1319
1320 /*
1321 * Remove ath_buf's of the same transmit unit from txq,
1322 * however leave the last descriptor back as the holding
1323 * descriptor for hw.
1324 */
1325 lastbf->bf_status |= ATH_BUFSTATUS_STALE;
1326 INIT_LIST_HEAD(&bf_head);
1327
1328 if (!list_is_singular(&lastbf->list))
1329 list_cut_position(&bf_head,
1330 &txq->axq_q, lastbf->list.prev);
1331
1332 txq->axq_depth--;
1333
1334 if (bf->bf_isaggr)
1335 txq->axq_aggr_depth--;
1336
1337 txok = (ds->ds_txstat.ts_status == 0);
1338
1339 spin_unlock_bh(&txq->axq_lock);
1340
1341 if (bf_held) {
1342 list_del(&bf_held->list);
1343 spin_lock_bh(&sc->sc_txbuflock);
1344 list_add_tail(&bf_held->list, &sc->sc_txbuf);
1345 spin_unlock_bh(&sc->sc_txbuflock);
1346 }
1347
1348 if (!bf->bf_isampdu) {
1349 /*
1350 * This frame is sent out as a single frame.
1351 * Use hardware retry status for this frame.
1352 */
1353 bf->bf_retries = ds->ds_txstat.ts_longretry;
1354 if (ds->ds_txstat.ts_status & ATH9K_TXERR_XRETRY)
1355 bf->bf_isxretried = 1;
1356 nbad = 0;
1357 } else {
1358 nbad = ath_tx_num_badfrms(sc, bf, txok);
1359 }
1360 skb = bf->bf_mpdu;
1361 tx_info = IEEE80211_SKB_CB(skb);
1362 tx_info_priv = (struct ath_tx_info_priv *)
1363 tx_info->driver_data[0];
1364 if (ds->ds_txstat.ts_status & ATH9K_TXERR_FILT)
1365 tx_info->flags |= IEEE80211_TX_STAT_TX_FILTERED;
1366 if ((ds->ds_txstat.ts_status & ATH9K_TXERR_FILT) == 0 &&
1367 (bf->bf_flags & ATH9K_TXDESC_NOACK) == 0) {
1368 if (ds->ds_txstat.ts_status == 0)
1369 nacked++;
1370
1371 if (bf->bf_isdata) {
1372 if (isrifs)
1373 tmp_ds = bf->bf_rifslast->bf_desc;
1374 else
1375 tmp_ds = ds;
1376 memcpy(&tx_info_priv->tx,
1377 &tmp_ds->ds_txstat,
1378 sizeof(tx_info_priv->tx));
1379 tx_info_priv->n_frames = bf->bf_nframes;
1380 tx_info_priv->n_bad_frames = nbad;
1381 }
1382 }
1383
1384 /*
1385 * Complete this transmit unit
1386 */
1387 if (bf->bf_isampdu)
1388 ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, txok);
1389 else
1390 ath_tx_complete_buf(sc, bf, &bf_head, txok, 0);
1391
1392 /* Wake up mac80211 queue */
1393
1394 spin_lock_bh(&txq->axq_lock);
1395 if (txq->stopped && ath_txq_depth(sc, txq->axq_qnum) <=
1396 (ATH_TXBUF - 20)) {
1397 int qnum;
1398 qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
1399 if (qnum != -1) {
1400 ieee80211_wake_queue(sc->hw, qnum);
1401 txq->stopped = 0;
1402 }
1403
1404 }
1405
1406 /*
1407 * schedule any pending packets if aggregation is enabled
1408 */
1409 if (sc->sc_txaggr)
1410 ath_txq_schedule(sc, txq);
1411 spin_unlock_bh(&txq->axq_lock);
1412 }
1413 return nacked;
1414}
1415
1416static void ath_tx_stopdma(struct ath_softc *sc, struct ath_txq *txq)
1417{
1418 struct ath_hal *ah = sc->sc_ah;
1419
1420 (void) ath9k_hw_stoptxdma(ah, txq->axq_qnum);
1421 DPRINTF(sc, ATH_DBG_XMIT, "%s: tx queue [%u] %x, link %p\n",
1422 __func__, txq->axq_qnum,
1423 ath9k_hw_gettxbuf(ah, txq->axq_qnum), txq->axq_link);
1424}
1425
1426/* Drain only the data queues */
1427
1428static void ath_drain_txdataq(struct ath_softc *sc, bool retry_tx)
1429{
1430 struct ath_hal *ah = sc->sc_ah;
1431 int i;
1432 int npend = 0;
1433 enum ath9k_ht_macmode ht_macmode = ath_cwm_macmode(sc);
1434
1435 /* XXX return value */
1436 if (!sc->sc_invalid) {
1437 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1438 if (ATH_TXQ_SETUP(sc, i)) {
1439 ath_tx_stopdma(sc, &sc->sc_txq[i]);
1440
1441 /* The TxDMA may not really be stopped.
1442 * Double check the hal tx pending count */
1443 npend += ath9k_hw_numtxpending(ah,
1444 sc->sc_txq[i].axq_qnum);
1445 }
1446 }
1447 }
1448
1449 if (npend) {
1450 int status;
1451
1452 /* TxDMA not stopped, reset the hal */
1453 DPRINTF(sc, ATH_DBG_XMIT,
1454 "%s: Unable to stop TxDMA. Reset HAL!\n", __func__);
1455
1456 spin_lock_bh(&sc->sc_resetlock);
1457 if (!ath9k_hw_reset(ah, sc->sc_opmode,
1458 &sc->sc_curchan, ht_macmode,
1459 sc->sc_tx_chainmask, sc->sc_rx_chainmask,
1460 sc->sc_ht_extprotspacing, true, &status)) {
1461
1462 DPRINTF(sc, ATH_DBG_FATAL,
1463 "%s: unable to reset hardware; hal status %u\n",
1464 __func__,
1465 status);
1466 }
1467 spin_unlock_bh(&sc->sc_resetlock);
1468 }
1469
1470 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
1471 if (ATH_TXQ_SETUP(sc, i))
1472 ath_tx_draintxq(sc, &sc->sc_txq[i], retry_tx);
1473 }
1474}
1475
1476/* Add a sub-frame to block ack window */
1477
1478static void ath_tx_addto_baw(struct ath_softc *sc,
1479 struct ath_atx_tid *tid,
1480 struct ath_buf *bf)
1481{
1482 int index, cindex;
1483
1484 if (bf->bf_isretried)
1485 return;
1486
1487 index = ATH_BA_INDEX(tid->seq_start, bf->bf_seqno);
1488 cindex = (tid->baw_head + index) & (ATH_TID_MAX_BUFS - 1);
1489
1490 ASSERT(tid->tx_buf[cindex] == NULL);
1491 tid->tx_buf[cindex] = bf;
1492
1493 if (index >= ((tid->baw_tail - tid->baw_head) &
1494 (ATH_TID_MAX_BUFS - 1))) {
1495 tid->baw_tail = cindex;
1496 INCR(tid->baw_tail, ATH_TID_MAX_BUFS);
1497 }
1498}
1499
1500/*
1501 * Function to send an A-MPDU
1502 * NB: must be called with txq lock held
1503 */
1504
1505static int ath_tx_send_ampdu(struct ath_softc *sc,
1506 struct ath_txq *txq,
1507 struct ath_atx_tid *tid,
1508 struct list_head *bf_head,
1509 struct ath_tx_control *txctl)
1510{
1511 struct ath_buf *bf;
1512 struct sk_buff *skb;
1513 struct ieee80211_tx_info *tx_info;
1514 struct ath_tx_info_priv *tx_info_priv;
1515
1516 BUG_ON(list_empty(bf_head));
1517
1518 bf = list_first_entry(bf_head, struct ath_buf, list);
1519 bf->bf_isampdu = 1;
1520 bf->bf_seqno = txctl->seqno; /* save seqno and tidno in buffer */
1521 bf->bf_tidno = txctl->tidno;
1522
1523 /*
1524 * Do not queue to h/w when any of the following conditions is true:
1525 * - there are pending frames in software queue
1526 * - the TID is currently paused for ADDBA/BAR request
1527 * - seqno is not within block-ack window
1528 * - h/w queue depth exceeds low water mark
1529 */
1530 if (!list_empty(&tid->buf_q) || tid->paused ||
1531 !BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno) ||
1532 txq->axq_depth >= ATH_AGGR_MIN_QDEPTH) {
1533 /*
1534 * Add this frame to software queue for scheduling later
1535 * for aggregation.
1536 */
1537 list_splice_tail_init(bf_head, &tid->buf_q);
1538 ath_tx_queue_tid(txq, tid);
1539 return 0;
1540 }
1541
1542 skb = (struct sk_buff *)bf->bf_mpdu;
1543 tx_info = IEEE80211_SKB_CB(skb);
1544 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
1545 memcpy(bf->bf_rcs, tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
1546
1547 /* Add sub-frame to BAW */
1548 ath_tx_addto_baw(sc, tid, bf);
1549
1550 /* Queue to h/w without aggregation */
1551 bf->bf_nframes = 1;
1552 bf->bf_lastbf = bf->bf_lastfrm; /* one single frame */
1553 ath_buf_set_rate(sc, bf);
1554 ath_tx_txqaddbuf(sc, txq, bf_head);
1555 return 0;
1556}
1557
1558/*
1559 * looks up the rate
1560 * returns aggr limit based on lowest of the rates
1561 */
1562
1563static u32 ath_lookup_rate(struct ath_softc *sc,
1564 struct ath_buf *bf)
1565{
1566 const struct ath9k_rate_table *rt = sc->sc_currates;
1567 struct sk_buff *skb;
1568 struct ieee80211_tx_info *tx_info;
1569 struct ath_tx_info_priv *tx_info_priv;
1570 u32 max_4ms_framelen, frame_length;
1571 u16 aggr_limit, legacy = 0, maxampdu;
1572 int i;
1573
1574
1575 skb = (struct sk_buff *)bf->bf_mpdu;
1576 tx_info = IEEE80211_SKB_CB(skb);
1577 tx_info_priv = (struct ath_tx_info_priv *)
1578 tx_info->driver_data[0];
1579 memcpy(bf->bf_rcs,
1580 tx_info_priv->rcs, 4 * sizeof(tx_info_priv->rcs[0]));
1581
1582 /*
1583 * Find the lowest frame length among the rate series that will have a
1584 * 4ms transmit duration.
1585 * TODO - TXOP limit needs to be considered.
1586 */
1587 max_4ms_framelen = ATH_AMPDU_LIMIT_MAX;
1588
1589 for (i = 0; i < 4; i++) {
1590 if (bf->bf_rcs[i].tries) {
1591 frame_length = bf->bf_rcs[i].max_4ms_framelen;
1592
1593 if (rt->info[bf->bf_rcs[i].rix].phy != PHY_HT) {
1594 legacy = 1;
1595 break;
1596 }
1597
1598 max_4ms_framelen = min(max_4ms_framelen, frame_length);
1599 }
1600 }
1601
1602 /*
1603 * limit aggregate size by the minimum rate if rate selected is
1604 * not a probe rate, if rate selected is a probe rate then
1605 * avoid aggregation of this packet.
1606 */
1607 if (tx_info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE || legacy)
1608 return 0;
1609
1610 aggr_limit = min(max_4ms_framelen,
1611 (u32)ATH_AMPDU_LIMIT_DEFAULT);
1612
1613 /*
1614 * h/w can accept aggregates upto 16 bit lengths (65535).
1615 * The IE, however can hold upto 65536, which shows up here
1616 * as zero. Ignore 65536 since we are constrained by hw.
1617 */
1618 maxampdu = sc->sc_ht_info.maxampdu;
1619 if (maxampdu)
1620 aggr_limit = min(aggr_limit, maxampdu);
1621
1622 return aggr_limit;
1623}
1624
1625/*
1626 * returns the number of delimiters to be added to
1627 * meet the minimum required mpdudensity.
1628 * caller should make sure that the rate is HT rate .
1629 */
1630
1631static int ath_compute_num_delims(struct ath_softc *sc,
1632 struct ath_buf *bf,
1633 u16 frmlen)
1634{
1635 const struct ath9k_rate_table *rt = sc->sc_currates;
1636 u32 nsymbits, nsymbols, mpdudensity;
1637 u16 minlen;
1638 u8 rc, flags, rix;
1639 int width, half_gi, ndelim, mindelim;
1640
1641 /* Select standard number of delimiters based on frame length alone */
1642 ndelim = ATH_AGGR_GET_NDELIM(frmlen);
1643
1644 /*
1645 * If encryption enabled, hardware requires some more padding between
1646 * subframes.
1647 * TODO - this could be improved to be dependent on the rate.
1648 * The hardware can keep up at lower rates, but not higher rates
1649 */
1650 if (bf->bf_keytype != ATH9K_KEY_TYPE_CLEAR)
1651 ndelim += ATH_AGGR_ENCRYPTDELIM;
1652
1653 /*
1654 * Convert desired mpdu density from microeconds to bytes based
1655 * on highest rate in rate series (i.e. first rate) to determine
1656 * required minimum length for subframe. Take into account
1657 * whether high rate is 20 or 40Mhz and half or full GI.
1658 */
1659 mpdudensity = sc->sc_ht_info.mpdudensity;
1660
1661 /*
1662 * If there is no mpdu density restriction, no further calculation
1663 * is needed.
1664 */
1665 if (mpdudensity == 0)
1666 return ndelim;
1667
1668 rix = bf->bf_rcs[0].rix;
1669 flags = bf->bf_rcs[0].flags;
1670 rc = rt->info[rix].rateCode;
1671 width = (flags & ATH_RC_CW40_FLAG) ? 1 : 0;
1672 half_gi = (flags & ATH_RC_SGI_FLAG) ? 1 : 0;
1673
1674 if (half_gi)
1675 nsymbols = NUM_SYMBOLS_PER_USEC_HALFGI(mpdudensity);
1676 else
1677 nsymbols = NUM_SYMBOLS_PER_USEC(mpdudensity);
1678
1679 if (nsymbols == 0)
1680 nsymbols = 1;
1681
1682 nsymbits = bits_per_symbol[HT_RC_2_MCS(rc)][width];
1683 minlen = (nsymbols * nsymbits) / BITS_PER_BYTE;
1684
1685 /* Is frame shorter than required minimum length? */
1686 if (frmlen < minlen) {
1687 /* Get the minimum number of delimiters required. */
1688 mindelim = (minlen - frmlen) / ATH_AGGR_DELIM_SZ;
1689 ndelim = max(mindelim, ndelim);
1690 }
1691
1692 return ndelim;
1693}
1694
1695/*
1696 * For aggregation from software buffer queue.
1697 * NB: must be called with txq lock held
1698 */
1699
1700static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
1701 struct ath_atx_tid *tid,
1702 struct list_head *bf_q,
1703 struct ath_buf **bf_last,
1704 struct aggr_rifs_param *param,
1705 int *prev_frames)
1706{
1707#define PADBYTES(_len) ((4 - ((_len) % 4)) % 4)
1708 struct ath_buf *bf, *tbf, *bf_first, *bf_prev = NULL;
1709 struct list_head bf_head;
1710 int rl = 0, nframes = 0, ndelim;
1711 u16 aggr_limit = 0, al = 0, bpad = 0,
1712 al_delta, h_baw = tid->baw_size / 2;
1713 enum ATH_AGGR_STATUS status = ATH_AGGR_DONE;
1714 int prev_al = 0, is_ds_rate = 0;
1715 INIT_LIST_HEAD(&bf_head);
1716
1717 BUG_ON(list_empty(&tid->buf_q));
1718
1719 bf_first = list_first_entry(&tid->buf_q, struct ath_buf, list);
1720
1721 do {
1722 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
1723
1724 /*
1725 * do not step over block-ack window
1726 */
1727 if (!BAW_WITHIN(tid->seq_start, tid->baw_size, bf->bf_seqno)) {
1728 status = ATH_AGGR_BAW_CLOSED;
1729 break;
1730 }
1731
1732 if (!rl) {
1733 aggr_limit = ath_lookup_rate(sc, bf);
1734 rl = 1;
1735 /*
1736 * Is rate dual stream
1737 */
1738 is_ds_rate =
1739 (bf->bf_rcs[0].flags & ATH_RC_DS_FLAG) ? 1 : 0;
1740 }
1741
1742 /*
1743 * do not exceed aggregation limit
1744 */
1745 al_delta = ATH_AGGR_DELIM_SZ + bf->bf_frmlen;
1746
1747 if (nframes && (aggr_limit <
1748 (al + bpad + al_delta + prev_al))) {
1749 status = ATH_AGGR_LIMITED;
1750 break;
1751 }
1752
1753 /*
1754 * do not exceed subframe limit
1755 */
1756 if ((nframes + *prev_frames) >=
1757 min((int)h_baw, ATH_AMPDU_SUBFRAME_DEFAULT)) {
1758 status = ATH_AGGR_LIMITED;
1759 break;
1760 }
1761
1762 /*
1763 * add padding for previous frame to aggregation length
1764 */
1765 al += bpad + al_delta;
1766
1767 /*
1768 * Get the delimiters needed to meet the MPDU
1769 * density for this node.
1770 */
1771 ndelim = ath_compute_num_delims(sc, bf_first, bf->bf_frmlen);
1772
1773 bpad = PADBYTES(al_delta) + (ndelim << 2);
1774
1775 bf->bf_next = NULL;
1776 bf->bf_lastfrm->bf_desc->ds_link = 0;
1777
1778 /*
1779 * this packet is part of an aggregate
1780 * - remove all descriptors belonging to this frame from
1781 * software queue
1782 * - add it to block ack window
1783 * - set up descriptors for aggregation
1784 */
1785 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
1786 ath_tx_addto_baw(sc, tid, bf);
1787
1788 list_for_each_entry(tbf, &bf_head, list) {
1789 ath9k_hw_set11n_aggr_middle(sc->sc_ah,
1790 tbf->bf_desc, ndelim);
1791 }
1792
1793 /*
1794 * link buffers of this frame to the aggregate
1795 */
1796 list_splice_tail_init(&bf_head, bf_q);
1797 nframes++;
1798
1799 if (bf_prev) {
1800 bf_prev->bf_next = bf;
1801 bf_prev->bf_lastfrm->bf_desc->ds_link = bf->bf_daddr;
1802 }
1803 bf_prev = bf;
1804
1805#ifdef AGGR_NOSHORT
1806 /*
1807 * terminate aggregation on a small packet boundary
1808 */
1809 if (bf->bf_frmlen < ATH_AGGR_MINPLEN) {
1810 status = ATH_AGGR_SHORTPKT;
1811 break;
1812 }
1813#endif
1814 } while (!list_empty(&tid->buf_q));
1815
1816 bf_first->bf_al = al;
1817 bf_first->bf_nframes = nframes;
1818 *bf_last = bf_prev;
1819 return status;
1820#undef PADBYTES
1821}
1822
1823/*
1824 * process pending frames possibly doing a-mpdu aggregation
1825 * NB: must be called with txq lock held
1826 */
1827
1828static void ath_tx_sched_aggr(struct ath_softc *sc,
1829 struct ath_txq *txq, struct ath_atx_tid *tid)
1830{
1831 struct ath_buf *bf, *tbf, *bf_last, *bf_lastaggr = NULL;
1832 enum ATH_AGGR_STATUS status;
1833 struct list_head bf_q;
1834 struct aggr_rifs_param param = {0, 0, 0, 0, NULL};
1835 int prev_frames = 0;
1836
1837 do {
1838 if (list_empty(&tid->buf_q))
1839 return;
1840
1841 INIT_LIST_HEAD(&bf_q);
1842
1843 status = ath_tx_form_aggr(sc, tid, &bf_q, &bf_lastaggr, &param,
1844 &prev_frames);
1845
1846 /*
1847 * no frames picked up to be aggregated; block-ack
1848 * window is not open
1849 */
1850 if (list_empty(&bf_q))
1851 break;
1852
1853 bf = list_first_entry(&bf_q, struct ath_buf, list);
1854 bf_last = list_entry(bf_q.prev, struct ath_buf, list);
1855 bf->bf_lastbf = bf_last;
1856
1857 /*
1858 * if only one frame, send as non-aggregate
1859 */
1860 if (bf->bf_nframes == 1) {
1861 ASSERT(bf->bf_lastfrm == bf_last);
1862
1863 bf->bf_isaggr = 0;
1864 /*
1865 * clear aggr bits for every descriptor
1866 * XXX TODO: is there a way to optimize it?
1867 */
1868 list_for_each_entry(tbf, &bf_q, list) {
1869 ath9k_hw_clr11n_aggr(sc->sc_ah, tbf->bf_desc);
1870 }
1871
1872 ath_buf_set_rate(sc, bf);
1873 ath_tx_txqaddbuf(sc, txq, &bf_q);
1874 continue;
1875 }
1876
1877 /*
1878 * setup first desc with rate and aggr info
1879 */
1880 bf->bf_isaggr = 1;
1881 ath_buf_set_rate(sc, bf);
1882 ath9k_hw_set11n_aggr_first(sc->sc_ah, bf->bf_desc, bf->bf_al);
1883
1884 /*
1885 * anchor last frame of aggregate correctly
1886 */
1887 ASSERT(bf_lastaggr);
1888 ASSERT(bf_lastaggr->bf_lastfrm == bf_last);
1889 tbf = bf_lastaggr;
1890 ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
1891
1892 /* XXX: We don't enter into this loop, consider removing this */
1893 while (!list_empty(&bf_q) && !list_is_last(&tbf->list, &bf_q)) {
1894 tbf = list_entry(tbf->list.next, struct ath_buf, list);
1895 ath9k_hw_set11n_aggr_last(sc->sc_ah, tbf->bf_desc);
1896 }
1897
1898 txq->axq_aggr_depth++;
1899
1900 /*
1901 * Normal aggregate, queue to hardware
1902 */
1903 ath_tx_txqaddbuf(sc, txq, &bf_q);
1904
1905 } while (txq->axq_depth < ATH_AGGR_MIN_QDEPTH &&
1906 status != ATH_AGGR_BAW_CLOSED);
1907}
1908
1909/* Called with txq lock held */
1910
1911static void ath_tid_drain(struct ath_softc *sc,
1912 struct ath_txq *txq,
1913 struct ath_atx_tid *tid,
1914 bool bh_flag)
1915{
1916 struct ath_buf *bf;
1917 struct list_head bf_head;
1918 INIT_LIST_HEAD(&bf_head);
1919
1920 for (;;) {
1921 if (list_empty(&tid->buf_q))
1922 break;
1923 bf = list_first_entry(&tid->buf_q, struct ath_buf, list);
1924
1925 list_cut_position(&bf_head, &tid->buf_q, &bf->bf_lastfrm->list);
1926
1927 /* update baw for software retried frame */
1928 if (bf->bf_isretried)
1929 ath_tx_update_baw(sc, tid, bf->bf_seqno);
1930
1931 /*
1932 * do not indicate packets while holding txq spinlock.
1933 * unlock is intentional here
1934 */
1935 if (likely(bh_flag))
1936 spin_unlock_bh(&txq->axq_lock);
1937 else
1938 spin_unlock(&txq->axq_lock);
1939
1940 /* complete this sub-frame */
1941 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
1942
1943 if (likely(bh_flag))
1944 spin_lock_bh(&txq->axq_lock);
1945 else
1946 spin_lock(&txq->axq_lock);
1947 }
1948
1949 /*
1950 * TODO: For frame(s) that are in the retry state, we will reuse the
1951 * sequence number(s) without setting the retry bit. The
1952 * alternative is to give up on these and BAR the receiver's window
1953 * forward.
1954 */
1955 tid->seq_next = tid->seq_start;
1956 tid->baw_tail = tid->baw_head;
1957}
1958
1959/*
1960 * Drain all pending buffers
1961 * NB: must be called with txq lock held
1962 */
1963
1964static void ath_txq_drain_pending_buffers(struct ath_softc *sc,
1965 struct ath_txq *txq,
1966 bool bh_flag)
1967{
1968 struct ath_atx_ac *ac, *ac_tmp;
1969 struct ath_atx_tid *tid, *tid_tmp;
1970
1971 list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
1972 list_del(&ac->list);
1973 ac->sched = false;
1974 list_for_each_entry_safe(tid, tid_tmp, &ac->tid_q, list) {
1975 list_del(&tid->list);
1976 tid->sched = false;
1977 ath_tid_drain(sc, txq, tid, bh_flag);
1978 }
1979 }
1980}
1981
1982static int ath_tx_start_dma(struct ath_softc *sc,
1983 struct sk_buff *skb,
1984 struct scatterlist *sg,
1985 u32 n_sg,
1986 struct ath_tx_control *txctl)
1987{
1988 struct ath_node *an = txctl->an;
1989 struct ath_buf *bf = NULL;
1990 struct list_head bf_head;
1991 struct ath_desc *ds;
1992 struct ath_hal *ah = sc->sc_ah;
1993 struct ath_txq *txq = &sc->sc_txq[txctl->qnum];
1994 struct ath_tx_info_priv *tx_info_priv;
1995 struct ath_rc_series *rcs;
1996 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
1997 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1998 __le16 fc = hdr->frame_control;
1999
2000 /* For each sglist entry, allocate an ath_buf for DMA */
2001 INIT_LIST_HEAD(&bf_head);
2002 spin_lock_bh(&sc->sc_txbuflock);
2003 if (unlikely(list_empty(&sc->sc_txbuf))) {
2004 spin_unlock_bh(&sc->sc_txbuflock);
2005 return -ENOMEM;
2006 }
2007
2008 bf = list_first_entry(&sc->sc_txbuf, struct ath_buf, list);
2009 list_del(&bf->list);
2010 spin_unlock_bh(&sc->sc_txbuflock);
2011
2012 list_add_tail(&bf->list, &bf_head);
2013
2014 /* set up this buffer */
2015 ATH_TXBUF_RESET(bf);
2016 bf->bf_frmlen = txctl->frmlen;
2017 bf->bf_isdata = ieee80211_is_data(fc);
2018 bf->bf_isbar = ieee80211_is_back_req(fc);
2019 bf->bf_ispspoll = ieee80211_is_pspoll(fc);
2020 bf->bf_flags = txctl->flags;
2021 bf->bf_shpreamble = sc->sc_flags & ATH_PREAMBLE_SHORT;
2022 bf->bf_keytype = txctl->keytype;
2023 tx_info_priv = (struct ath_tx_info_priv *)tx_info->driver_data[0];
2024 rcs = tx_info_priv->rcs;
2025 bf->bf_rcs[0] = rcs[0];
2026 bf->bf_rcs[1] = rcs[1];
2027 bf->bf_rcs[2] = rcs[2];
2028 bf->bf_rcs[3] = rcs[3];
2029 bf->bf_node = an;
2030 bf->bf_mpdu = skb;
2031 bf->bf_buf_addr = sg_dma_address(sg);
2032
2033 /* setup descriptor */
2034 ds = bf->bf_desc;
2035 ds->ds_link = 0;
2036 ds->ds_data = bf->bf_buf_addr;
2037
2038 /*
2039 * Save the DMA context in the first ath_buf
2040 */
2041 copy_dma_mem_context(get_dma_mem_context(bf, bf_dmacontext),
2042 get_dma_mem_context(txctl, dmacontext));
2043
2044 /*
2045 * Formulate first tx descriptor with tx controls.
2046 */
2047 ath9k_hw_set11n_txdesc(ah,
2048 ds,
2049 bf->bf_frmlen, /* frame length */
2050 txctl->atype, /* Atheros packet type */
2051 min(txctl->txpower, (u16)60), /* txpower */
2052 txctl->keyix, /* key cache index */
2053 txctl->keytype, /* key type */
2054 txctl->flags); /* flags */
2055 ath9k_hw_filltxdesc(ah,
2056 ds,
2057 sg_dma_len(sg), /* segment length */
2058 true, /* first segment */
2059 (n_sg == 1) ? true : false, /* last segment */
2060 ds); /* first descriptor */
2061
2062 bf->bf_lastfrm = bf;
2063 bf->bf_ht = txctl->ht;
2064
2065 spin_lock_bh(&txq->axq_lock);
2066
2067 if (txctl->ht && sc->sc_txaggr) {
2068 struct ath_atx_tid *tid = ATH_AN_2_TID(an, txctl->tidno);
2069 if (ath_aggr_query(sc, an, txctl->tidno)) {
2070 /*
2071 * Try aggregation if it's a unicast data frame
2072 * and the destination is HT capable.
2073 */
2074 ath_tx_send_ampdu(sc, txq, tid, &bf_head, txctl);
2075 } else {
2076 /*
2077 * Send this frame as regular when ADDBA exchange
2078 * is neither complete nor pending.
2079 */
2080 ath_tx_send_normal(sc, txq, tid, &bf_head);
2081 }
2082 } else {
2083 bf->bf_lastbf = bf;
2084 bf->bf_nframes = 1;
2085 ath_buf_set_rate(sc, bf);
2086
2087 if (ieee80211_is_back_req(fc)) {
2088 /* This is required for resuming tid
2089 * during BAR completion */
2090 bf->bf_tidno = txctl->tidno;
2091 }
2092
2093 if (is_multicast_ether_addr(hdr->addr1)) {
2094 struct ath_vap *avp = sc->sc_vaps[txctl->if_id];
2095
2096 /*
2097 * When servicing one or more stations in power-save
2098 * mode (or) if there is some mcast data waiting on
2099 * mcast queue (to prevent out of order delivery of
2100 * mcast,bcast packets) multicast frames must be
2101 * buffered until after the beacon. We use the private
2102 * mcast queue for that.
2103 */
2104 /* XXX? more bit in 802.11 frame header */
2105 spin_lock_bh(&avp->av_mcastq.axq_lock);
2106 if (txctl->ps || avp->av_mcastq.axq_depth)
2107 ath_tx_mcastqaddbuf(sc,
2108 &avp->av_mcastq, &bf_head);
2109 else
2110 ath_tx_txqaddbuf(sc, txq, &bf_head);
2111 spin_unlock_bh(&avp->av_mcastq.axq_lock);
2112 } else
2113 ath_tx_txqaddbuf(sc, txq, &bf_head);
2114 }
2115 spin_unlock_bh(&txq->axq_lock);
2116 return 0;
2117}
2118
2119static void xmit_map_sg(struct ath_softc *sc,
2120 struct sk_buff *skb,
2121 dma_addr_t *pa,
2122 struct ath_tx_control *txctl)
2123{
2124 struct ath_xmit_status tx_status;
2125 struct ath_atx_tid *tid;
2126 struct scatterlist sg;
2127
2128 *pa = pci_map_single(sc->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
2129
2130 /* setup S/G list */
2131 memset(&sg, 0, sizeof(struct scatterlist));
2132 sg_dma_address(&sg) = *pa;
2133 sg_dma_len(&sg) = skb->len;
2134
2135 if (ath_tx_start_dma(sc, skb, &sg, 1, txctl) != 0) {
2136 /*
2137 * We have to do drop frame here.
2138 */
2139 pci_unmap_single(sc->pdev, *pa, skb->len, PCI_DMA_TODEVICE);
2140
2141 tx_status.retries = 0;
2142 tx_status.flags = ATH_TX_ERROR;
2143
2144 if (txctl->ht && sc->sc_txaggr) {
2145 /* Reclaim the seqno. */
2146 tid = ATH_AN_2_TID((struct ath_node *)
2147 txctl->an, txctl->tidno);
2148 DECR(tid->seq_next, IEEE80211_SEQ_MAX);
2149 }
2150 ath_tx_complete(sc, skb, &tx_status, txctl->an);
2151 }
2152}
2153
2154/* Initialize TX queue and h/w */
2155
2156int ath_tx_init(struct ath_softc *sc, int nbufs)
2157{
2158 int error = 0;
2159
2160 do {
2161 spin_lock_init(&sc->sc_txbuflock);
2162
2163 /* Setup tx descriptors */
2164 error = ath_descdma_setup(sc, &sc->sc_txdma, &sc->sc_txbuf,
2165 "tx", nbufs * ATH_FRAG_PER_MSDU, ATH_TXDESC);
2166 if (error != 0) {
2167 DPRINTF(sc, ATH_DBG_FATAL,
2168 "%s: failed to allocate tx descriptors: %d\n",
2169 __func__, error);
2170 break;
2171 }
2172
2173 /* XXX allocate beacon state together with vap */
2174 error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf,
2175 "beacon", ATH_BCBUF, 1);
2176 if (error != 0) {
2177 DPRINTF(sc, ATH_DBG_FATAL,
2178 "%s: failed to allocate "
2179 "beacon descripotrs: %d\n",
2180 __func__, error);
2181 break;
2182 }
2183
2184 } while (0);
2185
2186 if (error != 0)
2187 ath_tx_cleanup(sc);
2188
2189 return error;
2190}
2191
2192/* Reclaim all tx queue resources */
2193
2194int ath_tx_cleanup(struct ath_softc *sc)
2195{
2196 /* cleanup beacon descriptors */
2197 if (sc->sc_bdma.dd_desc_len != 0)
2198 ath_descdma_cleanup(sc, &sc->sc_bdma, &sc->sc_bbuf);
2199
2200 /* cleanup tx descriptors */
2201 if (sc->sc_txdma.dd_desc_len != 0)
2202 ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf);
2203
2204 return 0;
2205}
2206
2207/* Setup a h/w transmit queue */
2208
2209struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
2210{
2211 struct ath_hal *ah = sc->sc_ah;
2212 struct ath9k_txq_info qi;
2213 int qnum;
2214
2215 memzero(&qi, sizeof(qi));
2216 qi.tqi_subtype = subtype;
2217 qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
2218 qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
2219 qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
2220 qi.tqi_compBuf = 0;
2221
2222 /*
2223 * Enable interrupts only for EOL and DESC conditions.
2224 * We mark tx descriptors to receive a DESC interrupt
2225 * when a tx queue gets deep; otherwise waiting for the
2226 * EOL to reap descriptors. Note that this is done to
2227 * reduce interrupt load and this only defers reaping
2228 * descriptors, never transmitting frames. Aside from
2229 * reducing interrupts this also permits more concurrency.
2230 * The only potential downside is if the tx queue backs
2231 * up in which case the top half of the kernel may backup
2232 * due to a lack of tx descriptors.
2233 *
2234 * The UAPSD queue is an exception, since we take a desc-
2235 * based intr on the EOSP frames.
2236 */
2237 if (qtype == ATH9K_TX_QUEUE_UAPSD)
2238 qi.tqi_qflags = TXQ_FLAG_TXDESCINT_ENABLE;
2239 else
2240 qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
2241 TXQ_FLAG_TXDESCINT_ENABLE;
2242 qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
2243 if (qnum == -1) {
2244 /*
2245 * NB: don't print a message, this happens
2246 * normally on parts with too few tx queues
2247 */
2248 return NULL;
2249 }
2250 if (qnum >= ARRAY_SIZE(sc->sc_txq)) {
2251 DPRINTF(sc, ATH_DBG_FATAL,
2252 "%s: hal qnum %u out of range, max %u!\n",
2253 __func__, qnum, (unsigned int)ARRAY_SIZE(sc->sc_txq));
2254 ath9k_hw_releasetxqueue(ah, qnum);
2255 return NULL;
2256 }
2257 if (!ATH_TXQ_SETUP(sc, qnum)) {
2258 struct ath_txq *txq = &sc->sc_txq[qnum];
2259
2260 txq->axq_qnum = qnum;
2261 txq->axq_link = NULL;
2262 INIT_LIST_HEAD(&txq->axq_q);
2263 INIT_LIST_HEAD(&txq->axq_acq);
2264 spin_lock_init(&txq->axq_lock);
2265 txq->axq_depth = 0;
2266 txq->axq_aggr_depth = 0;
2267 txq->axq_totalqueued = 0;
2268 txq->axq_intrcnt = 0;
2269 txq->axq_linkbuf = NULL;
2270 sc->sc_txqsetup |= 1<<qnum;
2271 }
2272 return &sc->sc_txq[qnum];
2273}
2274
2275/* Reclaim resources for a setup queue */
2276
2277void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
2278{
2279 ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
2280 sc->sc_txqsetup &= ~(1<<txq->axq_qnum);
2281}
2282
2283/*
2284 * Setup a hardware data transmit queue for the specified
2285 * access control. The hal may not support all requested
2286 * queues in which case it will return a reference to a
2287 * previously setup queue. We record the mapping from ac's
2288 * to h/w queues for use by ath_tx_start and also track
2289 * the set of h/w queues being used to optimize work in the
2290 * transmit interrupt handler and related routines.
2291 */
2292
2293int ath_tx_setup(struct ath_softc *sc, int haltype)
2294{
2295 struct ath_txq *txq;
2296
2297 if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
2298 DPRINTF(sc, ATH_DBG_FATAL,
2299 "%s: HAL AC %u out of range, max %zu!\n",
2300 __func__, haltype, ARRAY_SIZE(sc->sc_haltype2q));
2301 return 0;
2302 }
2303 txq = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, haltype);
2304 if (txq != NULL) {
2305 sc->sc_haltype2q[haltype] = txq->axq_qnum;
2306 return 1;
2307 } else
2308 return 0;
2309}
2310
2311int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
2312{
2313 int qnum;
2314
2315 switch (qtype) {
2316 case ATH9K_TX_QUEUE_DATA:
2317 if (haltype >= ARRAY_SIZE(sc->sc_haltype2q)) {
2318 DPRINTF(sc, ATH_DBG_FATAL,
2319 "%s: HAL AC %u out of range, max %zu!\n",
2320 __func__,
2321 haltype, ARRAY_SIZE(sc->sc_haltype2q));
2322 return -1;
2323 }
2324 qnum = sc->sc_haltype2q[haltype];
2325 break;
2326 case ATH9K_TX_QUEUE_BEACON:
2327 qnum = sc->sc_bhalq;
2328 break;
2329 case ATH9K_TX_QUEUE_CAB:
2330 qnum = sc->sc_cabq->axq_qnum;
2331 break;
2332 default:
2333 qnum = -1;
2334 }
2335 return qnum;
2336}
2337
2338/* Update parameters for a transmit queue */
2339
2340int ath_txq_update(struct ath_softc *sc, int qnum, struct ath9k_txq_info *qi0)
2341{
2342 struct ath_hal *ah = sc->sc_ah;
2343 int error = 0;
2344 struct ath9k_txq_info qi;
2345
2346 if (qnum == sc->sc_bhalq) {
2347 /*
2348 * XXX: for beacon queue, we just save the parameter.
2349 * It will be picked up by ath_beaconq_config when
2350 * it's necessary.
2351 */
2352 sc->sc_beacon_qi = *qi0;
2353 return 0;
2354 }
2355
2356 ASSERT(sc->sc_txq[qnum].axq_qnum == qnum);
2357
2358 ath9k_hw_gettxqueueprops(ah, qnum, &qi);
2359 qi.tqi_aifs = qi0->tqi_aifs;
2360 qi.tqi_cwmin = qi0->tqi_cwmin;
2361 qi.tqi_cwmax = qi0->tqi_cwmax;
2362 qi.tqi_burstTime = qi0->tqi_burstTime;
2363 qi.tqi_readyTime = qi0->tqi_readyTime;
2364
2365 if (!ath9k_hw_settxqueueprops(ah, qnum, &qi)) {
2366 DPRINTF(sc, ATH_DBG_FATAL,
2367 "%s: unable to update hardware queue %u!\n",
2368 __func__, qnum);
2369 error = -EIO;
2370 } else {
2371 ath9k_hw_resettxqueue(ah, qnum); /* push to h/w */
2372 }
2373
2374 return error;
2375}
2376
2377int ath_cabq_update(struct ath_softc *sc)
2378{
2379 struct ath9k_txq_info qi;
2380 int qnum = sc->sc_cabq->axq_qnum;
2381 struct ath_beacon_config conf;
2382
2383 ath9k_hw_gettxqueueprops(sc->sc_ah, qnum, &qi);
2384 /*
2385 * Ensure the readytime % is within the bounds.
2386 */
2387 if (sc->sc_config.cabqReadytime < ATH9K_READY_TIME_LO_BOUND)
2388 sc->sc_config.cabqReadytime = ATH9K_READY_TIME_LO_BOUND;
2389 else if (sc->sc_config.cabqReadytime > ATH9K_READY_TIME_HI_BOUND)
2390 sc->sc_config.cabqReadytime = ATH9K_READY_TIME_HI_BOUND;
2391
2392 ath_get_beaconconfig(sc, ATH_IF_ID_ANY, &conf);
2393 qi.tqi_readyTime =
2394 (conf.beacon_interval * sc->sc_config.cabqReadytime) / 100;
2395 ath_txq_update(sc, qnum, &qi);
2396
2397 return 0;
2398}
2399
2400int ath_tx_start(struct ath_softc *sc, struct sk_buff *skb)
2401{
2402 struct ath_tx_control txctl;
2403 int error = 0;
2404
2405 error = ath_tx_prepare(sc, skb, &txctl);
2406 if (error == 0)
2407 /*
2408 * Start DMA mapping.
2409 * ath_tx_start_dma() will be called either synchronously
2410 * or asynchrounsly once DMA is complete.
2411 */
2412 xmit_map_sg(sc, skb,
2413 get_dma_mem_context(&txctl, dmacontext),
2414 &txctl);
2415 else
2416 ath_node_put(sc, txctl.an, ATH9K_BH_STATUS_CHANGE);
2417
2418 /* failed packets will be dropped by the caller */
2419 return error;
2420}
2421
2422/* Deferred processing of transmit interrupt */
2423
2424void ath_tx_tasklet(struct ath_softc *sc)
2425{
2426 u64 tsf = ath9k_hw_gettsf64(sc->sc_ah);
2427 int i, nacked = 0;
2428 u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
2429
2430 ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
2431
2432 /*
2433 * Process each active queue.
2434 */
2435 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
2436 if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
2437 nacked += ath_tx_processq(sc, &sc->sc_txq[i]);
2438 }
2439 if (nacked)
2440 sc->sc_lastrx = tsf;
2441}
2442
2443void ath_tx_draintxq(struct ath_softc *sc,
2444 struct ath_txq *txq, bool retry_tx)
2445{
2446 struct ath_buf *bf, *lastbf;
2447 struct list_head bf_head;
2448
2449 INIT_LIST_HEAD(&bf_head);
2450
2451 /*
2452 * NB: this assumes output has been stopped and
2453 * we do not need to block ath_tx_tasklet
2454 */
2455 for (;;) {
2456 spin_lock_bh(&txq->axq_lock);
2457
2458 if (list_empty(&txq->axq_q)) {
2459 txq->axq_link = NULL;
2460 txq->axq_linkbuf = NULL;
2461 spin_unlock_bh(&txq->axq_lock);
2462 break;
2463 }
2464
2465 bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
2466
2467 if (bf->bf_status & ATH_BUFSTATUS_STALE) {
2468 list_del(&bf->list);
2469 spin_unlock_bh(&txq->axq_lock);
2470
2471 spin_lock_bh(&sc->sc_txbuflock);
2472 list_add_tail(&bf->list, &sc->sc_txbuf);
2473 spin_unlock_bh(&sc->sc_txbuflock);
2474 continue;
2475 }
2476
2477 lastbf = bf->bf_lastbf;
2478 if (!retry_tx)
2479 lastbf->bf_desc->ds_txstat.ts_flags =
2480 ATH9K_TX_SW_ABORTED;
2481
2482 /* remove ath_buf's of the same mpdu from txq */
2483 list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
2484 txq->axq_depth--;
2485
2486 spin_unlock_bh(&txq->axq_lock);
2487
2488 if (bf->bf_isampdu)
2489 ath_tx_complete_aggr_rifs(sc, txq, bf, &bf_head, 0);
2490 else
2491 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
2492 }
2493
2494 /* flush any pending frames if aggregation is enabled */
2495 if (sc->sc_txaggr) {
2496 if (!retry_tx) {
2497 spin_lock_bh(&txq->axq_lock);
2498 ath_txq_drain_pending_buffers(sc, txq,
2499 ATH9K_BH_STATUS_CHANGE);
2500 spin_unlock_bh(&txq->axq_lock);
2501 }
2502 }
2503}
2504
2505/* Drain the transmit queues and reclaim resources */
2506
2507void ath_draintxq(struct ath_softc *sc, bool retry_tx)
2508{
2509 /* stop beacon queue. The beacon will be freed when
2510 * we go to INIT state */
2511 if (!sc->sc_invalid) {
2512 (void) ath9k_hw_stoptxdma(sc->sc_ah, sc->sc_bhalq);
2513 DPRINTF(sc, ATH_DBG_XMIT, "%s: beacon queue %x\n", __func__,
2514 ath9k_hw_gettxbuf(sc->sc_ah, sc->sc_bhalq));
2515 }
2516
2517 ath_drain_txdataq(sc, retry_tx);
2518}
2519
2520u32 ath_txq_depth(struct ath_softc *sc, int qnum)
2521{
2522 return sc->sc_txq[qnum].axq_depth;
2523}
2524
2525u32 ath_txq_aggr_depth(struct ath_softc *sc, int qnum)
2526{
2527 return sc->sc_txq[qnum].axq_aggr_depth;
2528}
2529
2530/* Check if an ADDBA is required. A valid node must be passed. */
2531enum ATH_AGGR_CHECK ath_tx_aggr_check(struct ath_softc *sc,
2532 struct ath_node *an,
2533 u8 tidno)
2534{
2535 struct ath_atx_tid *txtid;
2536 DECLARE_MAC_BUF(mac);
2537
2538 if (!sc->sc_txaggr)
2539 return AGGR_NOT_REQUIRED;
2540
2541 /* ADDBA exchange must be completed before sending aggregates */
2542 txtid = ATH_AN_2_TID(an, tidno);
2543
2544 if (txtid->addba_exchangecomplete)
2545 return AGGR_EXCHANGE_DONE;
2546
2547 if (txtid->cleanup_inprogress)
2548 return AGGR_CLEANUP_PROGRESS;
2549
2550 if (txtid->addba_exchangeinprogress)
2551 return AGGR_EXCHANGE_PROGRESS;
2552
2553 if (!txtid->addba_exchangecomplete) {
2554 if (!txtid->addba_exchangeinprogress &&
2555 (txtid->addba_exchangeattempts < ADDBA_EXCHANGE_ATTEMPTS)) {
2556 txtid->addba_exchangeattempts++;
2557 return AGGR_REQUIRED;
2558 }
2559 }
2560
2561 return AGGR_NOT_REQUIRED;
2562}
2563
2564/* Start TX aggregation */
2565
2566int ath_tx_aggr_start(struct ath_softc *sc,
2567 const u8 *addr,
2568 u16 tid,
2569 u16 *ssn)
2570{
2571 struct ath_atx_tid *txtid;
2572 struct ath_node *an;
2573
2574 spin_lock_bh(&sc->node_lock);
2575 an = ath_node_find(sc, (u8 *) addr);
2576 spin_unlock_bh(&sc->node_lock);
2577
2578 if (!an) {
2579 DPRINTF(sc, ATH_DBG_AGGR,
2580 "%s: Node not found to initialize "
2581 "TX aggregation\n", __func__);
2582 return -1;
2583 }
2584
2585 if (sc->sc_txaggr) {
2586 txtid = ATH_AN_2_TID(an, tid);
2587 txtid->addba_exchangeinprogress = 1;
2588 ath_tx_pause_tid(sc, txtid);
2589 }
2590
2591 return 0;
2592}
2593
2594/* Stop tx aggregation */
2595
2596int ath_tx_aggr_stop(struct ath_softc *sc,
2597 const u8 *addr,
2598 u16 tid)
2599{
2600 struct ath_node *an;
2601
2602 spin_lock_bh(&sc->node_lock);
2603 an = ath_node_find(sc, (u8 *) addr);
2604 spin_unlock_bh(&sc->node_lock);
2605
2606 if (!an) {
2607 DPRINTF(sc, ATH_DBG_AGGR,
2608 "%s: TX aggr stop for non-existent node\n", __func__);
2609 return -1;
2610 }
2611
2612 ath_tx_aggr_teardown(sc, an, tid);
2613 return 0;
2614}
2615
2616/*
2617 * Performs transmit side cleanup when TID changes from aggregated to
2618 * unaggregated.
2619 * - Pause the TID and mark cleanup in progress
2620 * - Discard all retry frames from the s/w queue.
2621 */
2622
2623void ath_tx_aggr_teardown(struct ath_softc *sc,
2624 struct ath_node *an, u8 tid)
2625{
2626 struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
2627 struct ath_txq *txq = &sc->sc_txq[txtid->ac->qnum];
2628 struct ath_buf *bf;
2629 struct list_head bf_head;
2630 INIT_LIST_HEAD(&bf_head);
2631
2632 DPRINTF(sc, ATH_DBG_AGGR, "%s: teardown TX aggregation\n", __func__);
2633
2634 if (txtid->cleanup_inprogress) /* cleanup is in progress */
2635 return;
2636
2637 if (!txtid->addba_exchangecomplete) {
2638 txtid->addba_exchangeattempts = 0;
2639 return;
2640 }
2641
2642 /* TID must be paused first */
2643 ath_tx_pause_tid(sc, txtid);
2644
2645 /* drop all software retried frames and mark this TID */
2646 spin_lock_bh(&txq->axq_lock);
2647 while (!list_empty(&txtid->buf_q)) {
2648 bf = list_first_entry(&txtid->buf_q, struct ath_buf, list);
2649 if (!bf->bf_isretried) {
2650 /*
2651 * NB: it's based on the assumption that
2652 * software retried frame will always stay
2653 * at the head of software queue.
2654 */
2655 break;
2656 }
2657 list_cut_position(&bf_head,
2658 &txtid->buf_q, &bf->bf_lastfrm->list);
2659 ath_tx_update_baw(sc, txtid, bf->bf_seqno);
2660
2661 /* complete this sub-frame */
2662 ath_tx_complete_buf(sc, bf, &bf_head, 0, 0);
2663 }
2664
2665 if (txtid->baw_head != txtid->baw_tail) {
2666 spin_unlock_bh(&txq->axq_lock);
2667 txtid->cleanup_inprogress = true;
2668 } else {
2669 txtid->addba_exchangecomplete = 0;
2670 txtid->addba_exchangeattempts = 0;
2671 spin_unlock_bh(&txq->axq_lock);
2672 ath_tx_flush_tid(sc, txtid);
2673 }
2674}
2675
2676/*
2677 * Tx scheduling logic
2678 * NB: must be called with txq lock held
2679 */
2680
2681void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
2682{
2683 struct ath_atx_ac *ac;
2684 struct ath_atx_tid *tid;
2685
2686 /* nothing to schedule */
2687 if (list_empty(&txq->axq_acq))
2688 return;
2689 /*
2690 * get the first node/ac pair on the queue
2691 */
2692 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
2693 list_del(&ac->list);
2694 ac->sched = false;
2695
2696 /*
2697 * process a single tid per destination
2698 */
2699 do {
2700 /* nothing to schedule */
2701 if (list_empty(&ac->tid_q))
2702 return;
2703
2704 tid = list_first_entry(&ac->tid_q, struct ath_atx_tid, list);
2705 list_del(&tid->list);
2706 tid->sched = false;
2707
2708 if (tid->paused) /* check next tid to keep h/w busy */
2709 continue;
2710
2711 if (!(tid->an->an_smmode == ATH_SM_PWRSAV_DYNAMIC) ||
2712 ((txq->axq_depth % 2) == 0)) {
2713 ath_tx_sched_aggr(sc, txq, tid);
2714 }
2715
2716 /*
2717 * add tid to round-robin queue if more frames
2718 * are pending for the tid
2719 */
2720 if (!list_empty(&tid->buf_q))
2721 ath_tx_queue_tid(txq, tid);
2722
2723 /* only schedule one TID at a time */
2724 break;
2725 } while (!list_empty(&ac->tid_q));
2726
2727 /*
2728 * schedule AC if more TIDs need processing
2729 */
2730 if (!list_empty(&ac->tid_q)) {
2731 /*
2732 * add dest ac to txq if not already added
2733 */
2734 if (!ac->sched) {
2735 ac->sched = true;
2736 list_add_tail(&ac->list, &txq->axq_acq);
2737 }
2738 }
2739}
2740
2741/* Initialize per-node transmit state */
2742
2743void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
2744{
2745 if (sc->sc_txaggr) {
2746 struct ath_atx_tid *tid;
2747 struct ath_atx_ac *ac;
2748 int tidno, acno;
2749
2750 sc->sc_ht_info.maxampdu = ATH_AMPDU_LIMIT_DEFAULT;
2751
2752 /*
2753 * Init per tid tx state
2754 */
2755 for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
2756 tidno < WME_NUM_TID;
2757 tidno++, tid++) {
2758 tid->an = an;
2759 tid->tidno = tidno;
2760 tid->seq_start = tid->seq_next = 0;
2761 tid->baw_size = WME_MAX_BA;
2762 tid->baw_head = tid->baw_tail = 0;
2763 tid->sched = false;
2764 tid->paused = false;
2765 tid->cleanup_inprogress = false;
2766 INIT_LIST_HEAD(&tid->buf_q);
2767
2768 acno = TID_TO_WME_AC(tidno);
2769 tid->ac = &an->an_aggr.tx.ac[acno];
2770
2771 /* ADDBA state */
2772 tid->addba_exchangecomplete = 0;
2773 tid->addba_exchangeinprogress = 0;
2774 tid->addba_exchangeattempts = 0;
2775 }
2776
2777 /*
2778 * Init per ac tx state
2779 */
2780 for (acno = 0, ac = &an->an_aggr.tx.ac[acno];
2781 acno < WME_NUM_AC; acno++, ac++) {
2782 ac->sched = false;
2783 INIT_LIST_HEAD(&ac->tid_q);
2784
2785 switch (acno) {
2786 case WME_AC_BE:
2787 ac->qnum = ath_tx_get_qnum(sc,
2788 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
2789 break;
2790 case WME_AC_BK:
2791 ac->qnum = ath_tx_get_qnum(sc,
2792 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
2793 break;
2794 case WME_AC_VI:
2795 ac->qnum = ath_tx_get_qnum(sc,
2796 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
2797 break;
2798 case WME_AC_VO:
2799 ac->qnum = ath_tx_get_qnum(sc,
2800 ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
2801 break;
2802 }
2803 }
2804 }
2805}
2806
2807/* Cleanupthe pending buffers for the node. */
2808
2809void ath_tx_node_cleanup(struct ath_softc *sc,
2810 struct ath_node *an, bool bh_flag)
2811{
2812 int i;
2813 struct ath_atx_ac *ac, *ac_tmp;
2814 struct ath_atx_tid *tid, *tid_tmp;
2815 struct ath_txq *txq;
2816 for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
2817 if (ATH_TXQ_SETUP(sc, i)) {
2818 txq = &sc->sc_txq[i];
2819
2820 if (likely(bh_flag))
2821 spin_lock_bh(&txq->axq_lock);
2822 else
2823 spin_lock(&txq->axq_lock);
2824
2825 list_for_each_entry_safe(ac,
2826 ac_tmp, &txq->axq_acq, list) {
2827 tid = list_first_entry(&ac->tid_q,
2828 struct ath_atx_tid, list);
2829 if (tid && tid->an != an)
2830 continue;
2831 list_del(&ac->list);
2832 ac->sched = false;
2833
2834 list_for_each_entry_safe(tid,
2835 tid_tmp, &ac->tid_q, list) {
2836 list_del(&tid->list);
2837 tid->sched = false;
2838 ath_tid_drain(sc, txq, tid, bh_flag);
2839 tid->addba_exchangecomplete = 0;
2840 tid->addba_exchangeattempts = 0;
2841 tid->cleanup_inprogress = false;
2842 }
2843 }
2844
2845 if (likely(bh_flag))
2846 spin_unlock_bh(&txq->axq_lock);
2847 else
2848 spin_unlock(&txq->axq_lock);
2849 }
2850 }
2851}
2852
2853/* Cleanup per node transmit state */
2854
2855void ath_tx_node_free(struct ath_softc *sc, struct ath_node *an)
2856{
2857 if (sc->sc_txaggr) {
2858 struct ath_atx_tid *tid;
2859 int tidno, i;
2860
2861 /* Init per tid rx state */
2862 for (tidno = 0, tid = &an->an_aggr.tx.tid[tidno];
2863 tidno < WME_NUM_TID;
2864 tidno++, tid++) {
2865
2866 for (i = 0; i < ATH_TID_MAX_BUFS; i++)
2867 ASSERT(tid->tx_buf[i] == NULL);
2868 }
2869 }
2870}