aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorJiri Slaby <jirislaby@gmail.com>2007-08-12 11:33:16 -0400
committerDavid S. Miller <davem@davemloft.net>2008-01-28 18:09:35 -0500
commitfa1c114fdaa605496045e56c42d0c8aa4c139e57 (patch)
treedf8345d8ef17cea23da3c0bbe388729b79920bfe /drivers/net
parent3543f8069d3cc932202e64095d1d3986a10d34ed (diff)
[PATCH] Net: add ath5k wireless driver
add ath5k wireless driver Portions of this driver are covered by one or both of the ISC and 3-clause BSD licenses. Specific license information is cited at the top of each file. Acked-by and Signed-off-by information is collected from individual patches as collected in the wireless-2.6 tree prior to upstream submission. Acked-by: Matthew W. S. Bell <mentor@madwifi.org> Acked-by: Michael Taylor <mike.taylor@apprion.com> Acked-by: Pavel Roskin <proski@gnu.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Bradley M. Kuhn <bkuhn@softwarefreedom.org> Signed-off-by: Bruno Randolf <bruno@thinktube.com> Signed-off-by: Dave Young <hidave.darkstar@gmail.com> Signed-off-by: Francesco Gringoli <francesco.gringoli@ing.unibs.it> Signed-off-by: Jiri Slaby <jirislaby@gmail.com> Signed-off-by: Johannes Berg <johannes@sipsolutions.net> Signed-off-by: Karen Sandler <karen@softwarefreedom.org> Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl> Signed-off-by: Luis R. Rodriguez <mcgrof@gmail.com> Signed-off-by: Matt Norwood <norwood@softwarefreedom.org> Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: Richard Fontana <fontana@softwarefreedom.org> Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Ulrich Meis <meis@nets.rwth-aachen.de> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/Kconfig17
-rw-r--r--drivers/net/wireless/Makefile2
-rw-r--r--drivers/net/wireless/ath5k/Makefile2
-rw-r--r--drivers/net/wireless/ath5k/ath5k.h1173
-rw-r--r--drivers/net/wireless/ath5k/base.c2817
-rw-r--r--drivers/net/wireless/ath5k/base.h178
-rw-r--r--drivers/net/wireless/ath5k/debug.c469
-rw-r--r--drivers/net/wireless/ath5k/debug.h216
-rw-r--r--drivers/net/wireless/ath5k/hw.c4349
-rw-r--r--drivers/net/wireless/ath5k/hw.h588
-rw-r--r--drivers/net/wireless/ath5k/initvals.c1347
-rw-r--r--drivers/net/wireless/ath5k/phy.c2071
-rw-r--r--drivers/net/wireless/ath5k/reg.h1987
-rw-r--r--drivers/net/wireless/ath5k/regdom.c121
-rw-r--r--drivers/net/wireless/ath5k/regdom.h500
15 files changed, 15837 insertions, 0 deletions
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index 2c08c0a5a0df..50a8b6c2fa00 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -648,6 +648,23 @@ config P54_PCI
648 648
649 If you choose to build a module, it'll be called p54pci. 649 If you choose to build a module, it'll be called p54pci.
650 650
651config ATH5K
652 tristate "Atheros 5xxx wireless cards support"
653 depends on PCI && MAC80211 && WLAN_80211 && EXPERIMENTAL
654 ---help---
655 This module adds support for wireless adapters based on
656 Atheros 5xxx chipset.
657
658 Currently the following chip versions are supported:
659
660 MAC: AR5211 AR5212
661 PHY: RF5111/2111 RF5112/2112 RF5413/2413
662
663 This driver uses the kernel's mac80211 subsystem.
664
665 If you choose to build a module, it'll be called ath5k. Say M if
666 unsure.
667
651source "drivers/net/wireless/iwlwifi/Kconfig" 668source "drivers/net/wireless/iwlwifi/Kconfig"
652source "drivers/net/wireless/hostap/Kconfig" 669source "drivers/net/wireless/hostap/Kconfig"
653source "drivers/net/wireless/bcm43xx/Kconfig" 670source "drivers/net/wireless/bcm43xx/Kconfig"
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index d48f7d19745b..7e1535ece17a 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -59,3 +59,5 @@ obj-$(CONFIG_RT2X00) += rt2x00/
59obj-$(CONFIG_P54_COMMON) += p54common.o 59obj-$(CONFIG_P54_COMMON) += p54common.o
60obj-$(CONFIG_P54_USB) += p54usb.o 60obj-$(CONFIG_P54_USB) += p54usb.o
61obj-$(CONFIG_P54_PCI) += p54pci.o 61obj-$(CONFIG_P54_PCI) += p54pci.o
62
63obj-$(CONFIG_ATH5K) += ath5k/
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile
new file mode 100644
index 000000000000..321641f99e13
--- /dev/null
+++ b/drivers/net/wireless/ath5k/Makefile
@@ -0,0 +1,2 @@
1ath5k-objs = base.o hw.o regdom.o initvals.o phy.o debug.o
2obj-$(CONFIG_ATH5K) += ath5k.o
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h
new file mode 100644
index 000000000000..878609f1bf39
--- /dev/null
+++ b/drivers/net/wireless/ath5k/ath5k.h
@@ -0,0 +1,1173 @@
1/*
2 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
4 *
5 * Permission to use, copy, modify, and 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#ifndef _ATH5K_H
19#define _ATH5K_H
20
21/* Set this to 1 to disable regulatory domain restrictions for channel tests.
22 * WARNING: This is for debuging only and has side effects (eg. scan takes too
23 * long and results timeouts). It's also illegal to tune to some of the
24 * supported frequencies in some countries, so use this at your own risk,
25 * you've been warned. */
26#define CHAN_DEBUG 0
27
28#include <linux/io.h>
29#include <linux/types.h>
30#include <net/mac80211.h>
31
32#include "hw.h"
33#include "regdom.h"
34
35/* PCI IDs */
36#define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */
37#define PCI_DEVICE_ID_ATHEROS_AR5311 0x0011 /* AR5311 */
38#define PCI_DEVICE_ID_ATHEROS_AR5211 0x0012 /* AR5211 */
39#define PCI_DEVICE_ID_ATHEROS_AR5212 0x0013 /* AR5212 */
40#define PCI_DEVICE_ID_3COM_3CRDAG675 0x0013 /* 3CRDAG675 (Atheros AR5212) */
41#define PCI_DEVICE_ID_3COM_2_3CRPAG175 0x0013 /* 3CRPAG175 (Atheros AR5212) */
42#define PCI_DEVICE_ID_ATHEROS_AR5210_AP 0x0207 /* AR5210 (Early) */
43#define PCI_DEVICE_ID_ATHEROS_AR5212_IBM 0x1014 /* AR5212 (IBM MiniPCI) */
44#define PCI_DEVICE_ID_ATHEROS_AR5210_DEFAULT 0x1107 /* AR5210 (no eeprom) */
45#define PCI_DEVICE_ID_ATHEROS_AR5212_DEFAULT 0x1113 /* AR5212 (no eeprom) */
46#define PCI_DEVICE_ID_ATHEROS_AR5211_DEFAULT 0x1112 /* AR5211 (no eeprom) */
47#define PCI_DEVICE_ID_ATHEROS_AR5212_FPGA 0xf013 /* AR5212 (emulation board) */
48#define PCI_DEVICE_ID_ATHEROS_AR5211_LEGACY 0xff12 /* AR5211 (emulation board) */
49#define PCI_DEVICE_ID_ATHEROS_AR5211_FPGA11B 0xf11b /* AR5211 (emulation board) */
50#define PCI_DEVICE_ID_ATHEROS_AR5312_REV2 0x0052 /* AR5312 WMAC (AP31) */
51#define PCI_DEVICE_ID_ATHEROS_AR5312_REV7 0x0057 /* AR5312 WMAC (AP30-040) */
52#define PCI_DEVICE_ID_ATHEROS_AR5312_REV8 0x0058 /* AR5312 WMAC (AP43-030) */
53#define PCI_DEVICE_ID_ATHEROS_AR5212_0014 0x0014 /* AR5212 compatible */
54#define PCI_DEVICE_ID_ATHEROS_AR5212_0015 0x0015 /* AR5212 compatible */
55#define PCI_DEVICE_ID_ATHEROS_AR5212_0016 0x0016 /* AR5212 compatible */
56#define PCI_DEVICE_ID_ATHEROS_AR5212_0017 0x0017 /* AR5212 compatible */
57#define PCI_DEVICE_ID_ATHEROS_AR5212_0018 0x0018 /* AR5212 compatible */
58#define PCI_DEVICE_ID_ATHEROS_AR5212_0019 0x0019 /* AR5212 compatible */
59#define PCI_DEVICE_ID_ATHEROS_AR2413 0x001a /* AR2413 (Griffin-lite) */
60#define PCI_DEVICE_ID_ATHEROS_AR5413 0x001b /* AR5413 (Eagle) */
61#define PCI_DEVICE_ID_ATHEROS_AR5424 0x001c /* AR5424 (Condor PCI-E) */
62#define PCI_DEVICE_ID_ATHEROS_AR5416 0x0023 /* AR5416 */
63#define PCI_DEVICE_ID_ATHEROS_AR5418 0x0024 /* AR5418 */
64
65/****************************\
66 GENERIC DRIVER DEFINITIONS
67\****************************/
68
69#define ATH5K_PRINTF(fmt, ...) printk("%s: " fmt, __func__, ##__VA_ARGS__)
70
71#define ATH5K_PRINTK(_sc, _level, _fmt, ...) \
72 printk(_level "ath5k %s: " _fmt, \
73 ((_sc) && (_sc)->hw) ? wiphy_name((_sc)->hw->wiphy) : "", \
74 ##__VA_ARGS__)
75
76#define ATH5K_PRINTK_LIMIT(_sc, _level, _fmt, ...) do { \
77 if (net_ratelimit()) \
78 ATH5K_PRINTK(_sc, _level, _fmt, ##__VA_ARGS__); \
79 } while (0)
80
81#define ATH5K_INFO(_sc, _fmt, ...) \
82 ATH5K_PRINTK(_sc, KERN_INFO, _fmt, ##__VA_ARGS__)
83
84#define ATH5K_WARN(_sc, _fmt, ...) \
85 ATH5K_PRINTK_LIMIT(_sc, KERN_WARNING, _fmt, ##__VA_ARGS__)
86
87#define ATH5K_ERR(_sc, _fmt, ...) \
88 ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__)
89
90/*
91 * Some tuneable values (these should be changeable by the user)
92 */
93#define AR5K_TUNE_DMA_BEACON_RESP 2
94#define AR5K_TUNE_SW_BEACON_RESP 10
95#define AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF 0
96#define AR5K_TUNE_RADAR_ALERT false
97#define AR5K_TUNE_MIN_TX_FIFO_THRES 1
98#define AR5K_TUNE_MAX_TX_FIFO_THRES ((IEEE80211_MAX_LEN / 64) + 1)
99#define AR5K_TUNE_REGISTER_TIMEOUT 20000
100/* Register for RSSI threshold has a mask of 0xff, so 255 seems to
101 * be the max value. */
102#define AR5K_TUNE_RSSI_THRES 129
103/* This must be set when setting the RSSI threshold otherwise it can
104 * prevent a reset. If AR5K_RSSI_THR is read after writing to it
105 * the BMISS_THRES will be seen as 0, seems harware doesn't keep
106 * track of it. Max value depends on harware. For AR5210 this is just 7.
107 * For AR5211+ this seems to be up to 255. */
108#define AR5K_TUNE_BMISS_THRES 7
109#define AR5K_TUNE_REGISTER_DWELL_TIME 20000
110#define AR5K_TUNE_BEACON_INTERVAL 100
111#define AR5K_TUNE_AIFS 2
112#define AR5K_TUNE_AIFS_11B 2
113#define AR5K_TUNE_AIFS_XR 0
114#define AR5K_TUNE_CWMIN 15
115#define AR5K_TUNE_CWMIN_11B 31
116#define AR5K_TUNE_CWMIN_XR 3
117#define AR5K_TUNE_CWMAX 1023
118#define AR5K_TUNE_CWMAX_11B 1023
119#define AR5K_TUNE_CWMAX_XR 7
120#define AR5K_TUNE_NOISE_FLOOR -72
121#define AR5K_TUNE_MAX_TXPOWER 60
122#define AR5K_TUNE_DEFAULT_TXPOWER 30
123#define AR5K_TUNE_TPC_TXPOWER true
124#define AR5K_TUNE_ANT_DIVERSITY true
125#define AR5K_TUNE_HWTXTRIES 4
126
127/* token to use for aifs, cwmin, cwmax in MadWiFi */
128#define AR5K_TXQ_USEDEFAULT ((u32) -1)
129
130/* GENERIC CHIPSET DEFINITIONS */
131
132/* MAC Chips */
133enum ath5k_version {
134 AR5K_AR5210 = 0,
135 AR5K_AR5211 = 1,
136 AR5K_AR5212 = 2,
137};
138
139/* PHY Chips */
140enum ath5k_radio {
141 AR5K_RF5110 = 0,
142 AR5K_RF5111 = 1,
143 AR5K_RF5112 = 2,
144 AR5K_RF5413 = 3,
145};
146
147/*
148 * Common silicon revision/version values
149 */
150
151enum ath5k_srev_type {
152 AR5K_VERSION_VER,
153 AR5K_VERSION_RAD,
154};
155
156struct ath5k_srev_name {
157 const char *sr_name;
158 enum ath5k_srev_type sr_type;
159 u_int sr_val;
160};
161
162#define AR5K_SREV_UNKNOWN 0xffff
163
164#define AR5K_SREV_VER_AR5210 0x00
165#define AR5K_SREV_VER_AR5311 0x10
166#define AR5K_SREV_VER_AR5311A 0x20
167#define AR5K_SREV_VER_AR5311B 0x30
168#define AR5K_SREV_VER_AR5211 0x40
169#define AR5K_SREV_VER_AR5212 0x50
170#define AR5K_SREV_VER_AR5213 0x55
171#define AR5K_SREV_VER_AR5213A 0x59
172#define AR5K_SREV_VER_AR2424 0xa0
173#define AR5K_SREV_VER_AR5424 0xa3
174#define AR5K_SREV_VER_AR5413 0xa4
175#define AR5K_SREV_VER_AR5414 0xa5
176#define AR5K_SREV_VER_AR5416 0xc0 /* ? */
177#define AR5K_SREV_VER_AR5418 0xca
178
179#define AR5K_SREV_RAD_5110 0x00
180#define AR5K_SREV_RAD_5111 0x10
181#define AR5K_SREV_RAD_5111A 0x15
182#define AR5K_SREV_RAD_2111 0x20
183#define AR5K_SREV_RAD_5112 0x30
184#define AR5K_SREV_RAD_5112A 0x35
185#define AR5K_SREV_RAD_2112 0x40
186#define AR5K_SREV_RAD_2112A 0x45
187#define AR5K_SREV_RAD_SC1 0x63 /* Found on 5413/5414 */
188#define AR5K_SREV_RAD_SC2 0xa2 /* Found on 2424/5424 */
189#define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */
190
191/* IEEE defs */
192
193#define IEEE80211_MAX_LEN 2500
194
195/* TODO add support to mac80211 for vendor-specific rates and modes */
196
197/*
198 * Some of this information is based on Documentation from:
199 *
200 * http://madwifi.org/wiki/ChipsetFeatures/SuperAG
201 *
202 * Modulation for Atheros' eXtended Range - range enhancing extension that is
203 * supposed to double the distance an Atheros client device can keep a
204 * connection with an Atheros access point. This is achieved by increasing
205 * the receiver sensitivity up to, -105dBm, which is about 20dB above what
206 * the 802.11 specifications demand. In addition, new (proprietary) data rates
207 * are introduced: 3, 2, 1, 0.5 and 0.25 MBit/s.
208 *
209 * Please note that can you either use XR or TURBO but you cannot use both,
210 * they are exclusive.
211 *
212 */
213#define MODULATION_XR 0x00000200
214/*
215 * Modulation for Atheros' Turbo G and Turbo A, its supposed to provide a
216 * throughput transmission speed up to 40Mbit/s-60Mbit/s at a 108Mbit/s
217 * signaling rate achieved through the bonding of two 54Mbit/s 802.11g
218 * channels. To use this feature your Access Point must also suport it.
219 * There is also a distinction between "static" and "dynamic" turbo modes:
220 *
221 * - Static: is the dumb version: devices set to this mode stick to it until
222 * the mode is turned off.
223 * - Dynamic: is the intelligent version, the network decides itself if it
224 * is ok to use turbo. As soon as traffic is detected on adjacent channels
225 * (which would get used in turbo mode), or when a non-turbo station joins
226 * the network, turbo mode won't be used until the situation changes again.
227 * Dynamic mode is achieved by Atheros' Adaptive Radio (AR) feature which
228 * monitors the used radio band in order to decide whether turbo mode may
229 * be used or not.
230 *
231 * This article claims Super G sticks to bonding of channels 5 and 6 for
232 * USA:
233 *
234 * http://www.pcworld.com/article/id,113428-page,1/article.html
235 *
236 * The channel bonding seems to be driver specific though. In addition to
237 * deciding what channels will be used, these "Turbo" modes are accomplished
238 * by also enabling the following features:
239 *
240 * - Bursting: allows multiple frames to be sent at once, rather than pausing
241 * after each frame. Bursting is a standards-compliant feature that can be
242 * used with any Access Point.
243 * - Fast frames: increases the amount of information that can be sent per
244 * frame, also resulting in a reduction of transmission overhead. It is a
245 * proprietary feature that needs to be supported by the Access Point.
246 * - Compression: data frames are compressed in real time using a Lempel Ziv
247 * algorithm. This is done transparently. Once this feature is enabled,
248 * compression and decompression takes place inside the chipset, without
249 * putting additional load on the host CPU.
250 *
251 */
252#define MODULATION_TURBO 0x00000080
253
254enum ath5k_vendor_mode {
255 MODE_ATHEROS_TURBO = NUM_IEEE80211_MODES+1,
256 MODE_ATHEROS_TURBOG
257};
258
259/* Number of supported mac80211 enum ieee80211_phymode modes by this driver */
260#define NUM_DRIVER_MODES 3
261
262/* adding this flag to rate_code enables short preamble, see ar5212_reg.h */
263#define AR5K_SET_SHORT_PREAMBLE 0x04
264
265#define HAS_SHPREAMBLE(_ix) (rt->rates[_ix].modulation == IEEE80211_RATE_CCK_2)
266#define SHPREAMBLE_FLAG(_ix) (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0)
267
268/****************\
269 TX DEFINITIONS
270\****************/
271
272/*
273 * Tx Descriptor
274 */
275struct ath5k_tx_status {
276 u16 ts_seqnum;
277 u16 ts_tstamp;
278 u8 ts_status;
279 u8 ts_rate;
280 s8 ts_rssi;
281 u8 ts_shortretry;
282 u8 ts_longretry;
283 u8 ts_virtcol;
284 u8 ts_antenna;
285};
286
287#define AR5K_TXSTAT_ALTRATE 0x80
288#define AR5K_TXERR_XRETRY 0x01
289#define AR5K_TXERR_FILT 0x02
290#define AR5K_TXERR_FIFO 0x04
291
292/**
293 * enum ath5k_tx_queue - Queue types used to classify tx queues.
294 * @AR5K_TX_QUEUE_INACTIVE: q is unused -- see ath5k_hw_release_tx_queue
295 * @AR5K_TX_QUEUE_DATA: A normal data queue
296 * @AR5K_TX_QUEUE_XR_DATA: An XR-data queue
297 * @AR5K_TX_QUEUE_BEACON: The beacon queue
298 * @AR5K_TX_QUEUE_CAB: The after-beacon queue
299 * @AR5K_TX_QUEUE_UAPSD: Unscheduled Automatic Power Save Delivery queue
300 */
301enum ath5k_tx_queue {
302 AR5K_TX_QUEUE_INACTIVE = 0,
303 AR5K_TX_QUEUE_DATA,
304 AR5K_TX_QUEUE_XR_DATA,
305 AR5K_TX_QUEUE_BEACON,
306 AR5K_TX_QUEUE_CAB,
307 AR5K_TX_QUEUE_UAPSD,
308};
309
310#define AR5K_NUM_TX_QUEUES 10
311#define AR5K_NUM_TX_QUEUES_NOQCU 2
312
313/*
314 * Queue syb-types to classify normal data queues.
315 * These are the 4 Access Categories as defined in
316 * WME spec. 0 is the lowest priority and 4 is the
317 * highest. Normal data that hasn't been classified
318 * goes to the Best Effort AC.
319 */
320enum ath5k_tx_queue_subtype {
321 AR5K_WME_AC_BK = 0, /*Background traffic*/
322 AR5K_WME_AC_BE, /*Best-effort (normal) traffic)*/
323 AR5K_WME_AC_VI, /*Video traffic*/
324 AR5K_WME_AC_VO, /*Voice traffic*/
325};
326
327/*
328 * Queue ID numbers as returned by the hw functions, each number
329 * represents a hw queue. If hw does not support hw queues
330 * (eg 5210) all data goes in one queue. These match
331 * d80211 definitions (net80211/MadWiFi don't use them).
332 */
333enum ath5k_tx_queue_id {
334 AR5K_TX_QUEUE_ID_NOQCU_DATA = 0,
335 AR5K_TX_QUEUE_ID_NOQCU_BEACON = 1,
336 AR5K_TX_QUEUE_ID_DATA_MIN = 0, /*IEEE80211_TX_QUEUE_DATA0*/
337 AR5K_TX_QUEUE_ID_DATA_MAX = 4, /*IEEE80211_TX_QUEUE_DATA4*/
338 AR5K_TX_QUEUE_ID_DATA_SVP = 5, /*IEEE80211_TX_QUEUE_SVP - Spectralink Voice Protocol*/
339 AR5K_TX_QUEUE_ID_CAB = 6, /*IEEE80211_TX_QUEUE_AFTER_BEACON*/
340 AR5K_TX_QUEUE_ID_BEACON = 7, /*IEEE80211_TX_QUEUE_BEACON*/
341 AR5K_TX_QUEUE_ID_UAPSD = 8,
342 AR5K_TX_QUEUE_ID_XR_DATA = 9,
343};
344
345
346/*
347 * Flags to set hw queue's parameters...
348 */
349#define AR5K_TXQ_FLAG_TXOKINT_ENABLE 0x0001 /* Enable TXOK interrupt */
350#define AR5K_TXQ_FLAG_TXERRINT_ENABLE 0x0002 /* Enable TXERR interrupt */
351#define AR5K_TXQ_FLAG_TXEOLINT_ENABLE 0x0004 /* Enable TXEOL interrupt -not used- */
352#define AR5K_TXQ_FLAG_TXDESCINT_ENABLE 0x0008 /* Enable TXDESC interrupt -not used- */
353#define AR5K_TXQ_FLAG_TXURNINT_ENABLE 0x0010 /* Enable TXURN interrupt */
354#define AR5K_TXQ_FLAG_BACKOFF_DISABLE 0x0020 /* Disable random post-backoff */
355#define AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE 0x0040 /* Enable ready time expiry policy (?)*/
356#define AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE 0x0080 /* Enable backoff while bursting */
357#define AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS 0x0100 /* Disable backoff while bursting */
358#define AR5K_TXQ_FLAG_COMPRESSION_ENABLE 0x0200 /* Enable hw compression -not implemented-*/
359
360/*
361 * A struct to hold tx queue's parameters
362 */
363struct ath5k_txq_info {
364 enum ath5k_tx_queue tqi_type;
365 enum ath5k_tx_queue_subtype tqi_subtype;
366 u16 tqi_flags; /* Tx queue flags (see above) */
367 u32 tqi_aifs; /* Arbitrated Interframe Space */
368 s32 tqi_cw_min; /* Minimum Contention Window */
369 s32 tqi_cw_max; /* Maximum Contention Window */
370 u32 tqi_cbr_period; /* Constant bit rate period */
371 u32 tqi_cbr_overflow_limit;
372 u32 tqi_burst_time;
373 u32 tqi_ready_time; /* Not used */
374};
375
376/*
377 * Transmit packet types.
378 * These are not fully used inside OpenHAL yet
379 */
380enum ath5k_pkt_type {
381 AR5K_PKT_TYPE_NORMAL = 0,
382 AR5K_PKT_TYPE_ATIM = 1,
383 AR5K_PKT_TYPE_PSPOLL = 2,
384 AR5K_PKT_TYPE_BEACON = 3,
385 AR5K_PKT_TYPE_PROBE_RESP = 4,
386 AR5K_PKT_TYPE_PIFS = 5,
387};
388
389/*
390 * TX power and TPC settings
391 */
392#define AR5K_TXPOWER_OFDM(_r, _v) ( \
393 ((0 & 1) << ((_v) + 6)) | \
394 (((ah->ah_txpower.txp_rates[(_r)]) & 0x3f) << (_v)) \
395)
396
397#define AR5K_TXPOWER_CCK(_r, _v) ( \
398 (ah->ah_txpower.txp_rates[(_r)] & 0x3f) << (_v) \
399)
400
401/*
402 * DMA size definitions (2^n+2)
403 */
404enum ath5k_dmasize {
405 AR5K_DMASIZE_4B = 0,
406 AR5K_DMASIZE_8B,
407 AR5K_DMASIZE_16B,
408 AR5K_DMASIZE_32B,
409 AR5K_DMASIZE_64B,
410 AR5K_DMASIZE_128B,
411 AR5K_DMASIZE_256B,
412 AR5K_DMASIZE_512B
413};
414
415
416/****************\
417 RX DEFINITIONS
418\****************/
419
420/*
421 * Rx Descriptor
422 */
423struct ath5k_rx_status {
424 u16 rs_datalen;
425 u16 rs_tstamp;
426 u8 rs_status;
427 u8 rs_phyerr;
428 s8 rs_rssi;
429 u8 rs_keyix;
430 u8 rs_rate;
431 u8 rs_antenna;
432 u8 rs_more;
433};
434
435#define AR5K_RXERR_CRC 0x01
436#define AR5K_RXERR_PHY 0x02
437#define AR5K_RXERR_FIFO 0x04
438#define AR5K_RXERR_DECRYPT 0x08
439#define AR5K_RXERR_MIC 0x10
440#define AR5K_RXKEYIX_INVALID ((u8) - 1)
441#define AR5K_TXKEYIX_INVALID ((u32) - 1)
442
443struct ath5k_mib_stats {
444 u32 ackrcv_bad;
445 u32 rts_bad;
446 u32 rts_good;
447 u32 fcs_bad;
448 u32 beacons;
449};
450
451
452
453
454/**************************\
455 BEACON TIMERS DEFINITIONS
456\**************************/
457
458#define AR5K_BEACON_PERIOD 0x0000ffff
459#define AR5K_BEACON_ENA 0x00800000 /*enable beacon xmit*/
460#define AR5K_BEACON_RESET_TSF 0x01000000 /*force a TSF reset*/
461
462#if 0
463/**
464 * struct ath5k_beacon_state - Per-station beacon timer state.
465 * @bs_interval: in TU's, can also include the above flags
466 * @bs_cfp_max_duration: if non-zero hw is setup to coexist with a
467 * Point Coordination Function capable AP
468 */
469struct ath5k_beacon_state {
470 u32 bs_next_beacon;
471 u32 bs_next_dtim;
472 u32 bs_interval;
473 u8 bs_dtim_period;
474 u8 bs_cfp_period;
475 u16 bs_cfp_max_duration;
476 u16 bs_cfp_du_remain;
477 u16 bs_tim_offset;
478 u16 bs_sleep_duration;
479 u16 bs_bmiss_threshold;
480 u32 bs_cfp_next;
481};
482#endif
483
484
485/*
486 * TSF to TU conversion:
487 *
488 * TSF is a 64bit value in usec (microseconds).
489 * TU is a 32bit value in roughly msec (milliseconds): usec / 1024
490 * (1000ms equals 976 TU)
491 */
492#define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10)
493
494
495
496/********************\
497 COMMON DEFINITIONS
498\********************/
499
500/*
501 * Atheros descriptor
502 */
503struct ath5k_desc {
504 u32 ds_link;
505 u32 ds_data;
506 u32 ds_ctl0;
507 u32 ds_ctl1;
508 u32 ds_hw[4];
509
510 union {
511 struct ath5k_rx_status rx;
512 struct ath5k_tx_status tx;
513 } ds_us;
514
515#define ds_rxstat ds_us.rx
516#define ds_txstat ds_us.tx
517
518} __packed;
519
520#define AR5K_RXDESC_INTREQ 0x0020
521
522#define AR5K_TXDESC_CLRDMASK 0x0001
523#define AR5K_TXDESC_NOACK 0x0002 /*[5211+]*/
524#define AR5K_TXDESC_RTSENA 0x0004
525#define AR5K_TXDESC_CTSENA 0x0008
526#define AR5K_TXDESC_INTREQ 0x0010
527#define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/
528
529#define AR5K_SLOT_TIME_9 396
530#define AR5K_SLOT_TIME_20 880
531#define AR5K_SLOT_TIME_MAX 0xffff
532
533/* channel_flags */
534#define CHANNEL_CW_INT 0x0008 /* Contention Window interference detected */
535#define CHANNEL_TURBO 0x0010 /* Turbo Channel */
536#define CHANNEL_CCK 0x0020 /* CCK channel */
537#define CHANNEL_OFDM 0x0040 /* OFDM channel */
538#define CHANNEL_2GHZ 0x0080 /* 2GHz channel. */
539#define CHANNEL_5GHZ 0x0100 /* 5GHz channel */
540#define CHANNEL_PASSIVE 0x0200 /* Only passive scan allowed */
541#define CHANNEL_DYN 0x0400 /* Dynamic CCK-OFDM channel (for g operation) */
542#define CHANNEL_XR 0x0800 /* XR channel */
543
544#define CHANNEL_A (CHANNEL_5GHZ|CHANNEL_OFDM)
545#define CHANNEL_B (CHANNEL_2GHZ|CHANNEL_CCK)
546#define CHANNEL_G (CHANNEL_2GHZ|CHANNEL_OFDM)
547#define CHANNEL_T (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
548#define CHANNEL_TG (CHANNEL_2GHZ|CHANNEL_OFDM|CHANNEL_TURBO)
549#define CHANNEL_108A CHANNEL_T
550#define CHANNEL_108G CHANNEL_TG
551#define CHANNEL_X (CHANNEL_5GHZ|CHANNEL_OFDM|CHANNEL_XR)
552
553#define CHANNEL_ALL (CHANNEL_OFDM|CHANNEL_CCK|CHANNEL_2GHZ|CHANNEL_5GHZ| \
554 CHANNEL_TURBO)
555
556#define CHANNEL_ALL_NOTURBO (CHANNEL_ALL & ~CHANNEL_TURBO)
557#define CHANNEL_MODES CHANNEL_ALL
558
559/*
560 * Used internaly in OpenHAL (ar5211.c/ar5212.c
561 * for reset_tx_queue). Also see struct struct ieee80211_channel.
562 */
563#define IS_CHAN_XR(_c) ((_c.val & CHANNEL_XR) != 0)
564#define IS_CHAN_B(_c) ((_c.val & CHANNEL_B) != 0)
565
566/*
567 * The following structure will be used to map 2GHz channels to
568 * 5GHz Atheros channels.
569 */
570struct ath5k_athchan_2ghz {
571 u32 a2_flags;
572 u16 a2_athchan;
573};
574
575/*
576 * Rate definitions
577 * TODO: Clean them up or move them on mac80211 -most of these infos are
578 * used by the rate control algorytm on MadWiFi.
579 */
580
581/* Max number of rates on the rate table and what it seems
582 * Atheros hardware supports */
583#define AR5K_MAX_RATES 32
584
585/**
586 * struct ath5k_rate - rate structure
587 * @valid: is this a valid rate for the current mode
588 * @modulation: respective mac80211 modulation
589 * @rate_kbps: rate in kbit/s
590 * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on
591 * &struct ath5k_rx_status.rs_rate and on TX on
592 * &struct ath5k_tx_status.ts_rate. Seems the ar5xxx harware supports
593 * up to 32 rates, indexed by 1-32. This means we really only need
594 * 6 bits for the rate_code.
595 * @dot11_rate: respective IEEE-802.11 rate value
596 * @control_rate: index of rate assumed to be used to send control frames.
597 * This can be used to set override the value on the rate duration
598 * registers. This is only useful if we can override in the harware at
599 * what rate we want to send control frames at. Note that IEEE-802.11
600 * Ch. 9.6 (after IEEE 802.11g changes) defines the rate at which we
601 * should send ACK/CTS, if we change this value we can be breaking
602 * the spec.
603 *
604 * This structure is used to get the RX rate or set the TX rate on the
605 * hardware descriptors. It is also used for internal modulation control
606 * and settings.
607 *
608 * On RX after the &struct ath5k_desc is parsed by the appropriate
609 * ah_proc_rx_desc() the respective hardware rate value is set in
610 * &struct ath5k_rx_status.rs_rate. On TX the desired rate is set in
611 * &struct ath5k_tx_status.ts_rate which is later used to setup the
612 * &struct ath5k_desc correctly. This is the hardware rate map we are
613 * aware of:
614 *
615 * rate_code 1 2 3 4 5 6 7 8
616 * rate_kbps 3000 1000 ? ? ? 2000 500 48000
617 *
618 * rate_code 9 10 11 12 13 14 15 16
619 * rate_kbps 24000 12000 6000 54000 36000 18000 9000 ?
620 *
621 * rate_code 17 18 19 20 21 22 23 24
622 * rate_kbps ? ? ? ? ? ? ? 11000
623 *
624 * rate_code 25 26 27 28 29 30 31 32
625 * rate_kbps 5500 2000 1000 ? ? ? ? ?
626 *
627 */
628struct ath5k_rate {
629 u8 valid;
630 u32 modulation;
631 u16 rate_kbps;
632 u8 rate_code;
633 u8 dot11_rate;
634 u8 control_rate;
635};
636
637/* XXX: GRR all this stuff to get leds blinking ??? (check out setcurmode) */
638struct ath5k_rate_table {
639 u16 rate_count;
640 u8 rate_code_to_index[AR5K_MAX_RATES]; /* Back-mapping */
641 struct ath5k_rate rates[AR5K_MAX_RATES];
642};
643
644/*
645 * Rate tables...
646 */
647#define AR5K_RATES_11A { 8, { \
648 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \
649 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \
650 255, 255, 255, 255, 255, 255, 255, 255 }, { \
651 { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 0 }, \
652 { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 0 }, \
653 { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 2 }, \
654 { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 2 }, \
655 { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 4 }, \
656 { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 4 }, \
657 { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 4 }, \
658 { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 4 } } \
659}
660
661#define AR5K_RATES_11B { 4, { \
662 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \
663 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \
664 3, 2, 1, 0, 255, 255, 255, 255 }, { \
665 { 1, IEEE80211_RATE_CCK, 1000, 27, 130, 0 }, \
666 { 1, IEEE80211_RATE_CCK_2, 2000, 26, 132, 1 }, \
667 { 1, IEEE80211_RATE_CCK_2, 5500, 25, 139, 1 }, \
668 { 1, IEEE80211_RATE_CCK_2, 11000, 24, 150, 1 } } \
669}
670
671#define AR5K_RATES_11G { 12, { \
672 255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4, \
673 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \
674 3, 2, 1, 0, 255, 255, 255, 255 }, { \
675 { 1, IEEE80211_RATE_CCK, 1000, 27, 2, 0 }, \
676 { 1, IEEE80211_RATE_CCK_2, 2000, 26, 4, 1 }, \
677 { 1, IEEE80211_RATE_CCK_2, 5500, 25, 11, 1 }, \
678 { 1, IEEE80211_RATE_CCK_2, 11000, 24, 22, 1 }, \
679 { 0, IEEE80211_RATE_OFDM, 6000, 11, 12, 4 }, \
680 { 0, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \
681 { 1, IEEE80211_RATE_OFDM, 12000, 10, 24, 6 }, \
682 { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \
683 { 1, IEEE80211_RATE_OFDM, 24000, 9, 48, 8 }, \
684 { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \
685 { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \
686 { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \
687}
688
689#define AR5K_RATES_TURBO { 8, { \
690 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \
691 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \
692 255, 255, 255, 255, 255, 255, 255, 255 }, { \
693 { 1, MODULATION_TURBO, 6000, 11, 140, 0 }, \
694 { 1, MODULATION_TURBO, 9000, 15, 18, 0 }, \
695 { 1, MODULATION_TURBO, 12000, 10, 152, 2 }, \
696 { 1, MODULATION_TURBO, 18000, 14, 36, 2 }, \
697 { 1, MODULATION_TURBO, 24000, 9, 176, 4 }, \
698 { 1, MODULATION_TURBO, 36000, 13, 72, 4 }, \
699 { 1, MODULATION_TURBO, 48000, 8, 96, 4 }, \
700 { 1, MODULATION_TURBO, 54000, 12, 108, 4 } } \
701}
702
703#define AR5K_RATES_XR { 12, { \
704 255, 3, 1, 255, 255, 255, 2, 0, 10, 8, 6, 4, \
705 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \
706 255, 255, 255, 255, 255, 255, 255, 255 }, { \
707 { 1, MODULATION_XR, 500, 7, 129, 0 }, \
708 { 1, MODULATION_XR, 1000, 2, 139, 1 }, \
709 { 1, MODULATION_XR, 2000, 6, 150, 2 }, \
710 { 1, MODULATION_XR, 3000, 1, 150, 3 }, \
711 { 1, IEEE80211_RATE_OFDM, 6000, 11, 140, 4 }, \
712 { 1, IEEE80211_RATE_OFDM, 9000, 15, 18, 4 }, \
713 { 1, IEEE80211_RATE_OFDM, 12000, 10, 152, 6 }, \
714 { 1, IEEE80211_RATE_OFDM, 18000, 14, 36, 6 }, \
715 { 1, IEEE80211_RATE_OFDM, 24000, 9, 176, 8 }, \
716 { 1, IEEE80211_RATE_OFDM, 36000, 13, 72, 8 }, \
717 { 1, IEEE80211_RATE_OFDM, 48000, 8, 96, 8 }, \
718 { 1, IEEE80211_RATE_OFDM, 54000, 12, 108, 8 } } \
719}
720
721/*
722 * Crypto definitions
723 */
724
725#define AR5K_KEYCACHE_SIZE 8
726
727/***********************\
728 HW RELATED DEFINITIONS
729\***********************/
730
731/*
732 * Misc definitions
733 */
734#define AR5K_RSSI_EP_MULTIPLIER (1<<7)
735
736#define AR5K_ASSERT_ENTRY(_e, _s) do { \
737 if (_e >= _s) \
738 return (false); \
739} while (0)
740
741
742enum ath5k_ant_setting {
743 AR5K_ANT_VARIABLE = 0, /* variable by programming */
744 AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */
745 AR5K_ANT_FIXED_B = 2, /* fixed to 11b frequencies */
746 AR5K_ANT_MAX = 3,
747};
748
749/*
750 * Hardware interrupt abstraction
751 */
752
753/**
754 * enum ath5k_int - Hardware interrupt masks helpers
755 *
756 * @AR5K_INT_RX: mask to identify received frame interrupts, of type
757 * AR5K_ISR_RXOK or AR5K_ISR_RXERR
758 * @AR5K_INT_RXDESC: Request RX descriptor/Read RX descriptor (?)
759 * @AR5K_INT_RXNOFRM: No frame received (?)
760 * @AR5K_INT_RXEOL: received End Of List for VEOL (Virtual End Of List). The
761 * Queue Control Unit (QCU) signals an EOL interrupt only if a descriptor's
762 * LinkPtr is NULL. For more details, refer to:
763 * http://www.freepatentsonline.com/20030225739.html
764 * @AR5K_INT_RXORN: Indicates we got RX overrun (eg. no more descriptors).
765 * Note that Rx overrun is not always fatal, on some chips we can continue
766 * operation without reseting the card, that's why int_fatal is not
767 * common for all chips.
768 * @AR5K_INT_TX: mask to identify received frame interrupts, of type
769 * AR5K_ISR_TXOK or AR5K_ISR_TXERR
770 * @AR5K_INT_TXDESC: Request TX descriptor/Read TX status descriptor (?)
771 * @AR5K_INT_TXURN: received when we should increase the TX trigger threshold
772 * We currently do increments on interrupt by
773 * (AR5K_TUNE_MAX_TX_FIFO_THRES - current_trigger_level) / 2
774 * @AR5K_INT_MIB: Indicates the Management Information Base counters should be
775 * checked. We should do this with ath5k_hw_update_mib_counters() but
776 * it seems we should also then do some noise immunity work.
777 * @AR5K_INT_RXPHY: RX PHY Error
778 * @AR5K_INT_RXKCM: ??
779 * @AR5K_INT_SWBA: SoftWare Beacon Alert - indicates its time to send a
780 * beacon that must be handled in software. The alternative is if you
781 * have VEOL support, in that case you let the hardware deal with things.
782 * @AR5K_INT_BMISS: If in STA mode this indicates we have stopped seeing
783 * beacons from the AP have associated with, we should probably try to
784 * reassociate. When in IBSS mode this might mean we have not received
785 * any beacons from any local stations. Note that every station in an
786 * IBSS schedules to send beacons at the Target Beacon Transmission Time
787 * (TBTT) with a random backoff.
788 * @AR5K_INT_BNR: Beacon Not Ready interrupt - ??
789 * @AR5K_INT_GPIO: GPIO interrupt is used for RF Kill, disabled for now
790 * until properly handled
791 * @AR5K_INT_FATAL: Fatal errors were encountered, typically caused by DMA
792 * errors. These types of errors we can enable seem to be of type
793 * AR5K_SIMR2_MCABT, AR5K_SIMR2_SSERR and AR5K_SIMR2_DPERR.
794 * @AR5K_INT_GLOBAL: Seems to be used to clear and set the IER
795 * @AR5K_INT_NOCARD: signals the card has been removed
796 * @AR5K_INT_COMMON: common interrupts shared amogst MACs with the same
797 * bit value
798 *
799 * These are mapped to take advantage of some common bits
800 * between the MACs, to be able to set intr properties
801 * easier. Some of them are not used yet inside hw.c. Most map
802 * to the respective hw interrupt value as they are common amogst different
803 * MACs.
804 */
805enum ath5k_int {
806 AR5K_INT_RX = 0x00000001, /* Not common */
807 AR5K_INT_RXDESC = 0x00000002,
808 AR5K_INT_RXNOFRM = 0x00000008,
809 AR5K_INT_RXEOL = 0x00000010,
810 AR5K_INT_RXORN = 0x00000020,
811 AR5K_INT_TX = 0x00000040, /* Not common */
812 AR5K_INT_TXDESC = 0x00000080,
813 AR5K_INT_TXURN = 0x00000800,
814 AR5K_INT_MIB = 0x00001000,
815 AR5K_INT_RXPHY = 0x00004000,
816 AR5K_INT_RXKCM = 0x00008000,
817 AR5K_INT_SWBA = 0x00010000,
818 AR5K_INT_BMISS = 0x00040000,
819 AR5K_INT_BNR = 0x00100000, /* Not common */
820 AR5K_INT_GPIO = 0x01000000,
821 AR5K_INT_FATAL = 0x40000000, /* Not common */
822 AR5K_INT_GLOBAL = 0x80000000,
823
824 AR5K_INT_COMMON = AR5K_INT_RXNOFRM
825 | AR5K_INT_RXDESC
826 | AR5K_INT_RXEOL
827 | AR5K_INT_RXORN
828 | AR5K_INT_TXURN
829 | AR5K_INT_TXDESC
830 | AR5K_INT_MIB
831 | AR5K_INT_RXPHY
832 | AR5K_INT_RXKCM
833 | AR5K_INT_SWBA
834 | AR5K_INT_BMISS
835 | AR5K_INT_GPIO,
836 AR5K_INT_NOCARD = 0xffffffff
837};
838
839/*
840 * Power management
841 */
842enum ath5k_power_mode {
843 AR5K_PM_UNDEFINED = 0,
844 AR5K_PM_AUTO,
845 AR5K_PM_AWAKE,
846 AR5K_PM_FULL_SLEEP,
847 AR5K_PM_NETWORK_SLEEP,
848};
849
850/*
851 * These match net80211 definitions (not used in
852 * d80211).
853 */
854#define AR5K_LED_INIT 0 /*IEEE80211_S_INIT*/
855#define AR5K_LED_SCAN 1 /*IEEE80211_S_SCAN*/
856#define AR5K_LED_AUTH 2 /*IEEE80211_S_AUTH*/
857#define AR5K_LED_ASSOC 3 /*IEEE80211_S_ASSOC*/
858#define AR5K_LED_RUN 4 /*IEEE80211_S_RUN*/
859
860/* GPIO-controlled software LED */
861#define AR5K_SOFTLED_PIN 0
862#define AR5K_SOFTLED_ON 0
863#define AR5K_SOFTLED_OFF 1
864
865/*
866 * Chipset capabilities -see ath5k_hw_get_capability-
867 * get_capability function is not yet fully implemented
868 * in OpenHAL so most of these don't work yet...
869 */
870enum ath5k_capability_type {
871 AR5K_CAP_REG_DMN = 0, /* Used to get current reg. domain id */
872 AR5K_CAP_TKIP_MIC = 2, /* Can handle TKIP MIC in hardware */
873 AR5K_CAP_TKIP_SPLIT = 3, /* TKIP uses split keys */
874 AR5K_CAP_PHYCOUNTERS = 4, /* PHY error counters */
875 AR5K_CAP_DIVERSITY = 5, /* Supports fast diversity */
876 AR5K_CAP_NUM_TXQUEUES = 6, /* Used to get max number of hw txqueues */
877 AR5K_CAP_VEOL = 7, /* Supports virtual EOL */
878 AR5K_CAP_COMPRESSION = 8, /* Supports compression */
879 AR5K_CAP_BURST = 9, /* Supports packet bursting */
880 AR5K_CAP_FASTFRAME = 10, /* Supports fast frames */
881 AR5K_CAP_TXPOW = 11, /* Used to get global tx power limit */
882 AR5K_CAP_TPC = 12, /* Can do per-packet tx power control (needed for 802.11a) */
883 AR5K_CAP_BSSIDMASK = 13, /* Supports bssid mask */
884 AR5K_CAP_MCAST_KEYSRCH = 14, /* Supports multicast key search */
885 AR5K_CAP_TSF_ADJUST = 15, /* Supports beacon tsf adjust */
886 AR5K_CAP_XR = 16, /* Supports XR mode */
887 AR5K_CAP_WME_TKIPMIC = 17, /* Supports TKIP MIC when using WMM */
888 AR5K_CAP_CHAN_HALFRATE = 18, /* Supports half rate channels */
889 AR5K_CAP_CHAN_QUARTERRATE = 19, /* Supports quarter rate channels */
890 AR5K_CAP_RFSILENT = 20, /* Supports RFsilent */
891};
892
893struct ath5k_capabilities {
894 /*
895 * Supported PHY modes
896 * (ie. CHANNEL_A, CHANNEL_B, ...)
897 */
898 DECLARE_BITMAP(cap_mode, NUM_DRIVER_MODES);
899
900 /*
901 * Frequency range (without regulation restrictions)
902 */
903 struct {
904 u16 range_2ghz_min;
905 u16 range_2ghz_max;
906 u16 range_5ghz_min;
907 u16 range_5ghz_max;
908 } cap_range;
909
910 /*
911 * Active regulation domain settings
912 */
913 struct {
914 enum ath5k_regdom reg_current;
915 enum ath5k_regdom reg_hw;
916 } cap_regdomain;
917
918 /*
919 * Values stored in the EEPROM (some of them...)
920 */
921 struct ath5k_eeprom_info cap_eeprom;
922
923 /*
924 * Queue information
925 */
926 struct {
927 u8 q_tx_num;
928 } cap_queues;
929};
930
931
932/***************************************\
933 HARDWARE ABSTRACTION LAYER STRUCTURE
934\***************************************/
935
936/*
937 * Misc defines
938 */
939
940#define AR5K_MAX_GPIO 10
941#define AR5K_MAX_RF_BANKS 8
942
943struct ath5k_hw {
944 u32 ah_magic;
945
946 struct ath5k_softc *ah_sc;
947 void __iomem *ah_iobase;
948
949 enum ath5k_int ah_imr;
950
951 enum ieee80211_if_types ah_op_mode;
952 enum ath5k_power_mode ah_power_mode;
953 struct ieee80211_channel ah_current_channel;
954 bool ah_turbo;
955 bool ah_calibration;
956 bool ah_running;
957 bool ah_single_chip;
958 enum ath5k_rfgain ah_rf_gain;
959
960 u32 ah_mac_srev;
961 u16 ah_mac_version;
962 u16 ah_mac_revision;
963 u16 ah_phy_revision;
964 u16 ah_radio_5ghz_revision;
965 u16 ah_radio_2ghz_revision;
966
967 enum ath5k_version ah_version;
968 enum ath5k_radio ah_radio;
969 u32 ah_phy;
970
971 bool ah_5ghz;
972 bool ah_2ghz;
973
974#define ah_regdomain ah_capabilities.cap_regdomain.reg_current
975#define ah_regdomain_hw ah_capabilities.cap_regdomain.reg_hw
976#define ah_modes ah_capabilities.cap_mode
977#define ah_ee_version ah_capabilities.cap_eeprom.ee_version
978
979 u32 ah_atim_window;
980 u32 ah_aifs;
981 u32 ah_cw_min;
982 u32 ah_cw_max;
983 bool ah_software_retry;
984 u32 ah_limit_tx_retries;
985
986 u32 ah_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
987 bool ah_ant_diversity;
988
989 u8 ah_sta_id[ETH_ALEN];
990
991 /* Current BSSID we are trying to assoc to / creating.
992 * This is passed by mac80211 on config_interface() and cached here for
993 * use in resets */
994 u8 ah_bssid[ETH_ALEN];
995
996 u32 ah_gpio[AR5K_MAX_GPIO];
997 int ah_gpio_npins;
998
999 struct ath5k_capabilities ah_capabilities;
1000
1001 struct ath5k_txq_info ah_txq[AR5K_NUM_TX_QUEUES];
1002 u32 ah_txq_status;
1003 u32 ah_txq_imr_txok;
1004 u32 ah_txq_imr_txerr;
1005 u32 ah_txq_imr_txurn;
1006 u32 ah_txq_imr_txdesc;
1007 u32 ah_txq_imr_txeol;
1008 u32 *ah_rf_banks;
1009 size_t ah_rf_banks_size;
1010 struct ath5k_gain ah_gain;
1011 u32 ah_offset[AR5K_MAX_RF_BANKS];
1012
1013 struct {
1014 u16 txp_pcdac[AR5K_EEPROM_POWER_TABLE_SIZE];
1015 u16 txp_rates[AR5K_MAX_RATES];
1016 s16 txp_min;
1017 s16 txp_max;
1018 bool txp_tpc;
1019 s16 txp_ofdm;
1020 } ah_txpower;
1021
1022 struct {
1023 bool r_enabled;
1024 int r_last_alert;
1025 struct ieee80211_channel r_last_channel;
1026 } ah_radar;
1027
1028 /* noise floor from last periodic calibration */
1029 s32 ah_noise_floor;
1030
1031 /*
1032 * Function pointers
1033 */
1034 int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1035 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
1036 unsigned int, unsigned int, unsigned int, unsigned int,
1037 unsigned int, unsigned int, unsigned int);
1038 bool (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *,
1039 unsigned int, unsigned int, unsigned int, unsigned int,
1040 unsigned int, unsigned int);
1041 int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *);
1042 int (*ah_proc_rx_desc)(struct ath5k_hw *, struct ath5k_desc *);
1043};
1044
1045/*
1046 * Prototypes
1047 */
1048
1049/* General Functions */
1050extern int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, bool is_set);
1051/* Attach/Detach Functions */
1052extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version);
1053extern const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, unsigned int mode);
1054extern void ath5k_hw_detach(struct ath5k_hw *ah);
1055/* Reset Functions */
1056extern int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, struct ieee80211_channel *channel, bool change_channel);
1057/* Power management functions */
1058extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration);
1059/* DMA Related Functions */
1060extern void ath5k_hw_start_rx(struct ath5k_hw *ah);
1061extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah);
1062extern u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah);
1063extern void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr);
1064extern int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue);
1065extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue);
1066extern u32 ath5k_hw_get_tx_buf(struct ath5k_hw *ah, unsigned int queue);
1067extern int ath5k_hw_put_tx_buf(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr);
1068extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase);
1069/* Interrupt handling */
1070extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah);
1071extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask);
1072extern enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask);
1073/* EEPROM access functions */
1074extern int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain);
1075/* Protocol Control Unit Functions */
1076extern int ath5k_hw_set_opmode(struct ath5k_hw *ah);
1077/* BSSID Functions */
1078extern void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac);
1079extern int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac);
1080extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id);
1081extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask);
1082/* Receive start/stop functions */
1083extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah);
1084extern void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah);
1085/* RX Filter functions */
1086extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1);
1087extern int ath5k_hw_set_mcast_filterindex(struct ath5k_hw *ah, u32 index);
1088extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index);
1089extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah);
1090extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter);
1091/* Beacon related functions */
1092extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah);
1093extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah);
1094extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah);
1095extern void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval);
1096#if 0
1097extern int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, const struct ath5k_beacon_state *state);
1098extern void ath5k_hw_reset_beacon(struct ath5k_hw *ah);
1099extern int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr);
1100#endif
1101extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ath5k_mib_stats *statistics);
1102/* ACK bit rate */
1103void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high);
1104/* ACK/CTS Timeouts */
1105extern int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout);
1106extern unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah);
1107extern int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout);
1108extern unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah);
1109/* Key table (WEP) functions */
1110extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry);
1111extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry);
1112extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac);
1113extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac);
1114/* Queue Control Unit, DFS Control Unit Functions */
1115extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, struct ath5k_txq_info *queue_info);
1116extern int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue, const struct ath5k_txq_info *queue_info);
1117extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info);
1118extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1119extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue);
1120extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue);
1121extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time);
1122extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah);
1123/* Hardware Descriptor Functions */
1124extern int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, u32 size, unsigned int flags);
1125/* GPIO Functions */
1126extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state);
1127extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio);
1128extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio);
1129extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio);
1130extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val);
1131extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level);
1132/* Regulatory Domain/Channels Setup */
1133extern u16 ath5k_get_regdomain(struct ath5k_hw *ah);
1134/* Misc functions */
1135extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result);
1136
1137
1138/* Initial register settings functions */
1139extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel);
1140/* Initialize RF */
1141extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode);
1142extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq);
1143extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah);
1144extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah);
1145
1146
1147/* PHY/RF channel functions */
1148extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags);
1149extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1150/* PHY calibration */
1151extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel);
1152extern int ath5k_hw_phy_disable(struct ath5k_hw *ah);
1153/* Misc PHY functions */
1154extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan);
1155extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant);
1156extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah);
1157extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq);
1158/* TX power setup */
1159extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower);
1160extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power);
1161
1162
1163static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
1164{
1165 return ioread32(ah->ah_iobase + reg);
1166}
1167
1168static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
1169{
1170 iowrite32(val, ah->ah_iobase + reg);
1171}
1172
1173#endif
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c
new file mode 100644
index 000000000000..d3d37282f3dc
--- /dev/null
+++ b/drivers/net/wireless/ath5k/base.c
@@ -0,0 +1,2817 @@
1/*-
2 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
3 * Copyright (c) 2004-2005 Atheros Communications, Inc.
4 * Copyright (c) 2006 Devicescape Software, Inc.
5 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
6 * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
7 *
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer,
15 * without modification.
16 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
17 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
18 * redistribution must be conditioned upon including a substantially
19 * similar Disclaimer requirement for further binary redistribution.
20 * 3. Neither the names of the above-listed copyright holders nor the names
21 * of any contributors may be used to endorse or promote products derived
22 * from this software without specific prior written permission.
23 *
24 * Alternatively, this software may be distributed under the terms of the
25 * GNU General Public License ("GPL") version 2 as published by the Free
26 * Software Foundation.
27 *
28 * NO WARRANTY
29 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
30 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
31 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
32 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
33 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
34 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
37 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
39 * THE POSSIBILITY OF SUCH DAMAGES.
40 *
41 */
42
43#include <linux/version.h>
44#include <linux/module.h>
45#include <linux/delay.h>
46#include <linux/if.h>
47#include <linux/netdevice.h>
48#include <linux/cache.h>
49#include <linux/pci.h>
50#include <linux/ethtool.h>
51#include <linux/uaccess.h>
52
53#include <net/ieee80211_radiotap.h>
54
55#include <asm/unaligned.h>
56
57#include "base.h"
58#include "reg.h"
59#include "debug.h"
60
61/* unaligned little endian access */
62#define LE_READ_2(_p) (le16_to_cpu(get_unaligned((__le16 *)(_p))))
63#define LE_READ_4(_p) (le32_to_cpu(get_unaligned((__le32 *)(_p))))
64
65enum {
66 ATH_LED_TX,
67 ATH_LED_RX,
68};
69
70static int ath5k_calinterval = 10; /* Calibrate PHY every 10 secs (TODO: Fixme) */
71
72
73/******************\
74* Internal defines *
75\******************/
76
77/* Module info */
78MODULE_AUTHOR("Jiri Slaby");
79MODULE_AUTHOR("Nick Kossifidis");
80MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards.");
81MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards");
82MODULE_LICENSE("Dual BSD/GPL");
83MODULE_VERSION("0.1.1 (EXPERIMENTAL)");
84
85
86/* Known PCI ids */
87static struct pci_device_id ath5k_pci_id_table[] __devinitdata = {
88 { PCI_VDEVICE(ATHEROS, 0x0207), .driver_data = AR5K_AR5210 }, /* 5210 early */
89 { PCI_VDEVICE(ATHEROS, 0x0007), .driver_data = AR5K_AR5210 }, /* 5210 */
90 { PCI_VDEVICE(ATHEROS, 0x0011), .driver_data = AR5K_AR5211 }, /* 5311 - this is on AHB bus !*/
91 { PCI_VDEVICE(ATHEROS, 0x0012), .driver_data = AR5K_AR5211 }, /* 5211 */
92 { PCI_VDEVICE(ATHEROS, 0x0013), .driver_data = AR5K_AR5212 }, /* 5212 */
93 { PCI_VDEVICE(3COM_2, 0x0013), .driver_data = AR5K_AR5212 }, /* 3com 5212 */
94 { PCI_VDEVICE(3COM, 0x0013), .driver_data = AR5K_AR5212 }, /* 3com 3CRDAG675 5212 */
95 { PCI_VDEVICE(ATHEROS, 0x1014), .driver_data = AR5K_AR5212 }, /* IBM minipci 5212 */
96 { PCI_VDEVICE(ATHEROS, 0x0014), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
97 { PCI_VDEVICE(ATHEROS, 0x0015), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
98 { PCI_VDEVICE(ATHEROS, 0x0016), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
99 { PCI_VDEVICE(ATHEROS, 0x0017), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
100 { PCI_VDEVICE(ATHEROS, 0x0018), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
101 { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */
102 { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */
103 { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */
104 { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* 5424 Condor (PCI-E)*/
105 { PCI_VDEVICE(ATHEROS, 0x0023), .driver_data = AR5K_AR5212 }, /* 5416 */
106 { PCI_VDEVICE(ATHEROS, 0x0024), .driver_data = AR5K_AR5212 }, /* 5418 */
107 { 0 }
108};
109MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table);
110
111/* Known SREVs */
112static struct ath5k_srev_name srev_names[] = {
113 { "5210", AR5K_VERSION_VER, AR5K_SREV_VER_AR5210 },
114 { "5311", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311 },
115 { "5311A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311A },
116 { "5311B", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311B },
117 { "5211", AR5K_VERSION_VER, AR5K_SREV_VER_AR5211 },
118 { "5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212 },
119 { "5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213 },
120 { "5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A },
121 { "2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424 },
122 { "5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424 },
123 { "5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413 },
124 { "5414", AR5K_VERSION_VER, AR5K_SREV_VER_AR5414 },
125 { "5416", AR5K_VERSION_VER, AR5K_SREV_VER_AR5416 },
126 { "5418", AR5K_VERSION_VER, AR5K_SREV_VER_AR5418 },
127 { "xxxxx", AR5K_VERSION_VER, AR5K_SREV_UNKNOWN },
128 { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 },
129 { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 },
130 { "2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111 },
131 { "5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112 },
132 { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A },
133 { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 },
134 { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A },
135 { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1 },
136 { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2 },
137 { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 },
138 { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },
139};
140
141/*
142 * Prototypes - PCI stack related functions
143 */
144static int __devinit ath5k_pci_probe(struct pci_dev *pdev,
145 const struct pci_device_id *id);
146static void __devexit ath5k_pci_remove(struct pci_dev *pdev);
147#ifdef CONFIG_PM
148static int ath5k_pci_suspend(struct pci_dev *pdev,
149 pm_message_t state);
150static int ath5k_pci_resume(struct pci_dev *pdev);
151#else
152#define ath5k_pci_suspend NULL
153#define ath5k_pci_resume NULL
154#endif /* CONFIG_PM */
155
156static struct pci_driver ath5k_pci_drv_id = {
157 .name = "ath5k_pci",
158 .id_table = ath5k_pci_id_table,
159 .probe = ath5k_pci_probe,
160 .remove = __devexit_p(ath5k_pci_remove),
161 .suspend = ath5k_pci_suspend,
162 .resume = ath5k_pci_resume,
163};
164
165
166
167/*
168 * Prototypes - MAC 802.11 stack related functions
169 */
170static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
171 struct ieee80211_tx_control *ctl);
172static int ath5k_reset(struct ieee80211_hw *hw);
173static int ath5k_start(struct ieee80211_hw *hw);
174static void ath5k_stop(struct ieee80211_hw *hw);
175static int ath5k_add_interface(struct ieee80211_hw *hw,
176 struct ieee80211_if_init_conf *conf);
177static void ath5k_remove_interface(struct ieee80211_hw *hw,
178 struct ieee80211_if_init_conf *conf);
179static int ath5k_config(struct ieee80211_hw *hw,
180 struct ieee80211_conf *conf);
181static int ath5k_config_interface(struct ieee80211_hw *hw, int if_id,
182 struct ieee80211_if_conf *conf);
183static void ath5k_configure_filter(struct ieee80211_hw *hw,
184 unsigned int changed_flags,
185 unsigned int *new_flags,
186 int mc_count, struct dev_mc_list *mclist);
187static int ath5k_set_key(struct ieee80211_hw *hw,
188 enum set_key_cmd cmd,
189 const u8 *local_addr, const u8 *addr,
190 struct ieee80211_key_conf *key);
191static int ath5k_get_stats(struct ieee80211_hw *hw,
192 struct ieee80211_low_level_stats *stats);
193static int ath5k_get_tx_stats(struct ieee80211_hw *hw,
194 struct ieee80211_tx_queue_stats *stats);
195static u64 ath5k_get_tsf(struct ieee80211_hw *hw);
196static void ath5k_reset_tsf(struct ieee80211_hw *hw);
197static int ath5k_beacon_update(struct ieee80211_hw *hw,
198 struct sk_buff *skb,
199 struct ieee80211_tx_control *ctl);
200
201static struct ieee80211_ops ath5k_hw_ops = {
202 .tx = ath5k_tx,
203 .start = ath5k_start,
204 .stop = ath5k_stop,
205 .add_interface = ath5k_add_interface,
206 .remove_interface = ath5k_remove_interface,
207 .config = ath5k_config,
208 .config_interface = ath5k_config_interface,
209 .configure_filter = ath5k_configure_filter,
210 .set_key = ath5k_set_key,
211 .get_stats = ath5k_get_stats,
212 .conf_tx = NULL,
213 .get_tx_stats = ath5k_get_tx_stats,
214 .get_tsf = ath5k_get_tsf,
215 .reset_tsf = ath5k_reset_tsf,
216 .beacon_update = ath5k_beacon_update,
217};
218
219/*
220 * Prototypes - Internal functions
221 */
222/* Attach detach */
223static int ath5k_attach(struct pci_dev *pdev,
224 struct ieee80211_hw *hw);
225static void ath5k_detach(struct pci_dev *pdev,
226 struct ieee80211_hw *hw);
227/* Channel/mode setup */
228static inline short ath5k_ieee2mhz(short chan);
229static unsigned int ath5k_copy_rates(struct ieee80211_rate *rates,
230 const struct ath5k_rate_table *rt,
231 unsigned int max);
232static unsigned int ath5k_copy_channels(struct ath5k_hw *ah,
233 struct ieee80211_channel *channels,
234 unsigned int mode,
235 unsigned int max);
236static int ath5k_getchannels(struct ieee80211_hw *hw);
237static int ath5k_chan_set(struct ath5k_softc *sc,
238 struct ieee80211_channel *chan);
239static void ath5k_setcurmode(struct ath5k_softc *sc,
240 unsigned int mode);
241static void ath5k_mode_setup(struct ath5k_softc *sc);
242/* Descriptor setup */
243static int ath5k_desc_alloc(struct ath5k_softc *sc,
244 struct pci_dev *pdev);
245static void ath5k_desc_free(struct ath5k_softc *sc,
246 struct pci_dev *pdev);
247/* Buffers setup */
248static int ath5k_rxbuf_setup(struct ath5k_softc *sc,
249 struct ath5k_buf *bf);
250static int ath5k_txbuf_setup(struct ath5k_softc *sc,
251 struct ath5k_buf *bf,
252 struct ieee80211_tx_control *ctl);
253
254static inline void ath5k_txbuf_free(struct ath5k_softc *sc,
255 struct ath5k_buf *bf)
256{
257 BUG_ON(!bf);
258 if (!bf->skb)
259 return;
260 pci_unmap_single(sc->pdev, bf->skbaddr, bf->skb->len,
261 PCI_DMA_TODEVICE);
262 dev_kfree_skb(bf->skb);
263 bf->skb = NULL;
264}
265
266/* Queues setup */
267static struct ath5k_txq *ath5k_txq_setup(struct ath5k_softc *sc,
268 int qtype, int subtype);
269static int ath5k_beaconq_setup(struct ath5k_hw *ah);
270static int ath5k_beaconq_config(struct ath5k_softc *sc);
271static void ath5k_txq_drainq(struct ath5k_softc *sc,
272 struct ath5k_txq *txq);
273static void ath5k_txq_cleanup(struct ath5k_softc *sc);
274static void ath5k_txq_release(struct ath5k_softc *sc);
275/* Rx handling */
276static int ath5k_rx_start(struct ath5k_softc *sc);
277static void ath5k_rx_stop(struct ath5k_softc *sc);
278static unsigned int ath5k_rx_decrypted(struct ath5k_softc *sc,
279 struct ath5k_desc *ds,
280 struct sk_buff *skb);
281static void ath5k_tasklet_rx(unsigned long data);
282/* Tx handling */
283static void ath5k_tx_processq(struct ath5k_softc *sc,
284 struct ath5k_txq *txq);
285static void ath5k_tasklet_tx(unsigned long data);
286/* Beacon handling */
287static int ath5k_beacon_setup(struct ath5k_softc *sc,
288 struct ath5k_buf *bf,
289 struct ieee80211_tx_control *ctl);
290static void ath5k_beacon_send(struct ath5k_softc *sc);
291static void ath5k_beacon_config(struct ath5k_softc *sc);
292
293static inline u64 ath5k_extend_tsf(struct ath5k_hw *ah, u32 rstamp)
294{
295 u64 tsf = ath5k_hw_get_tsf64(ah);
296
297 if ((tsf & 0x7fff) < rstamp)
298 tsf -= 0x8000;
299
300 return (tsf & ~0x7fff) | rstamp;
301}
302
303/* Interrupt handling */
304static int ath5k_init(struct ath5k_softc *sc);
305static int ath5k_stop_locked(struct ath5k_softc *sc);
306static int ath5k_stop_hw(struct ath5k_softc *sc);
307static irqreturn_t ath5k_intr(int irq, void *dev_id);
308static void ath5k_tasklet_reset(unsigned long data);
309
310static void ath5k_calibrate(unsigned long data);
311/* LED functions */
312static void ath5k_led_off(unsigned long data);
313static void ath5k_led_blink(struct ath5k_softc *sc,
314 unsigned int on,
315 unsigned int off);
316static void ath5k_led_event(struct ath5k_softc *sc,
317 int event);
318
319
320/*
321 * Module init/exit functions
322 */
323static int __init
324init_ath5k_pci(void)
325{
326 int ret;
327
328 ath5k_debug_init();
329
330 ret = pci_register_driver(&ath5k_pci_drv_id);
331 if (ret) {
332 printk(KERN_ERR "ath5k_pci: can't register pci driver\n");
333 return ret;
334 }
335
336 return 0;
337}
338
339static void __exit
340exit_ath5k_pci(void)
341{
342 pci_unregister_driver(&ath5k_pci_drv_id);
343
344 ath5k_debug_finish();
345}
346
347module_init(init_ath5k_pci);
348module_exit(exit_ath5k_pci);
349
350
351/********************\
352* PCI Initialization *
353\********************/
354
355static const char *
356ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val)
357{
358 const char *name = "xxxxx";
359 unsigned int i;
360
361 for (i = 0; i < ARRAY_SIZE(srev_names); i++) {
362 if (srev_names[i].sr_type != type)
363 continue;
364 if ((val & 0xff) < srev_names[i + 1].sr_val) {
365 name = srev_names[i].sr_name;
366 break;
367 }
368 }
369
370 return name;
371}
372
373static int __devinit
374ath5k_pci_probe(struct pci_dev *pdev,
375 const struct pci_device_id *id)
376{
377 void __iomem *mem;
378 struct ath5k_softc *sc;
379 struct ieee80211_hw *hw;
380 int ret;
381 u8 csz;
382
383 ret = pci_enable_device(pdev);
384 if (ret) {
385 dev_err(&pdev->dev, "can't enable device\n");
386 goto err;
387 }
388
389 /* XXX 32-bit addressing only */
390 ret = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
391 if (ret) {
392 dev_err(&pdev->dev, "32-bit DMA not available\n");
393 goto err_dis;
394 }
395
396 /*
397 * Cache line size is used to size and align various
398 * structures used to communicate with the hardware.
399 */
400 pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
401 if (csz == 0) {
402 /*
403 * Linux 2.4.18 (at least) writes the cache line size
404 * register as a 16-bit wide register which is wrong.
405 * We must have this setup properly for rx buffer
406 * DMA to work so force a reasonable value here if it
407 * comes up zero.
408 */
409 csz = L1_CACHE_BYTES / sizeof(u32);
410 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
411 }
412 /*
413 * The default setting of latency timer yields poor results,
414 * set it to the value used by other systems. It may be worth
415 * tweaking this setting more.
416 */
417 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
418
419 /* Enable bus mastering */
420 pci_set_master(pdev);
421
422 /*
423 * Disable the RETRY_TIMEOUT register (0x41) to keep
424 * PCI Tx retries from interfering with C3 CPU state.
425 */
426 pci_write_config_byte(pdev, 0x41, 0);
427
428 ret = pci_request_region(pdev, 0, "ath5k");
429 if (ret) {
430 dev_err(&pdev->dev, "cannot reserve PCI memory region\n");
431 goto err_dis;
432 }
433
434 mem = pci_iomap(pdev, 0, 0);
435 if (!mem) {
436 dev_err(&pdev->dev, "cannot remap PCI memory region\n") ;
437 ret = -EIO;
438 goto err_reg;
439 }
440
441 /*
442 * Allocate hw (mac80211 main struct)
443 * and hw->priv (driver private data)
444 */
445 hw = ieee80211_alloc_hw(sizeof(*sc), &ath5k_hw_ops);
446 if (hw == NULL) {
447 dev_err(&pdev->dev, "cannot allocate ieee80211_hw\n");
448 ret = -ENOMEM;
449 goto err_map;
450 }
451
452 dev_info(&pdev->dev, "registered as '%s'\n", wiphy_name(hw->wiphy));
453
454 /* Initialize driver private data */
455 SET_IEEE80211_DEV(hw, &pdev->dev);
456 hw->flags = IEEE80211_HW_RX_INCLUDES_FCS;
457 hw->extra_tx_headroom = 2;
458 hw->channel_change_time = 5000;
459 /* these names are misleading */
460 hw->max_rssi = -110; /* signal in dBm */
461 hw->max_noise = -110; /* noise in dBm */
462 hw->max_signal = 100; /* we will provide a percentage based on rssi */
463 sc = hw->priv;
464 sc->hw = hw;
465 sc->pdev = pdev;
466
467 ath5k_debug_init_device(sc);
468
469 /*
470 * Mark the device as detached to avoid processing
471 * interrupts until setup is complete.
472 */
473 __set_bit(ATH_STAT_INVALID, sc->status);
474
475 sc->iobase = mem; /* So we can unmap it on detach */
476 sc->cachelsz = csz * sizeof(u32); /* convert to bytes */
477 sc->opmode = IEEE80211_IF_TYPE_STA;
478 mutex_init(&sc->lock);
479 spin_lock_init(&sc->rxbuflock);
480 spin_lock_init(&sc->txbuflock);
481
482 /* Set private data */
483 pci_set_drvdata(pdev, hw);
484
485 /* Enable msi for devices that support it */
486 pci_enable_msi(pdev);
487
488 /* Setup interrupt handler */
489 ret = request_irq(pdev->irq, ath5k_intr, IRQF_SHARED, "ath", sc);
490 if (ret) {
491 ATH5K_ERR(sc, "request_irq failed\n");
492 goto err_free;
493 }
494
495 /* Initialize device */
496 sc->ah = ath5k_hw_attach(sc, id->driver_data);
497 if (IS_ERR(sc->ah)) {
498 ret = PTR_ERR(sc->ah);
499 goto err_irq;
500 }
501
502 /* Finish private driver data initialization */
503 ret = ath5k_attach(pdev, hw);
504 if (ret)
505 goto err_ah;
506
507 ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n",
508 ath5k_chip_name(AR5K_VERSION_VER,sc->ah->ah_mac_srev),
509 sc->ah->ah_mac_srev,
510 sc->ah->ah_phy_revision);
511
512 if(!sc->ah->ah_single_chip){
513 /* Single chip radio (!RF5111) */
514 if(sc->ah->ah_radio_5ghz_revision && !sc->ah->ah_radio_2ghz_revision) {
515 /* No 5GHz support -> report 2GHz radio */
516 if(!test_bit(MODE_IEEE80211A, sc->ah->ah_capabilities.cap_mode)){
517 ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
518 ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision),
519 sc->ah->ah_radio_5ghz_revision);
520 /* No 2GHz support (5110 and some 5Ghz only cards) -> report 5Ghz radio */
521 } else if(!test_bit(MODE_IEEE80211B, sc->ah->ah_capabilities.cap_mode)){
522 ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
523 ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision),
524 sc->ah->ah_radio_5ghz_revision);
525 /* Multiband radio */
526 } else {
527 ATH5K_INFO(sc, "RF%s multiband radio found"
528 " (0x%x)\n",
529 ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision),
530 sc->ah->ah_radio_5ghz_revision);
531 }
532 }
533 /* Multi chip radio (RF5111 - RF2111) -> report both 2GHz/5GHz radios */
534 else if(sc->ah->ah_radio_5ghz_revision && sc->ah->ah_radio_2ghz_revision){
535 ATH5K_INFO(sc, "RF%s 5GHz radio found (0x%x)\n",
536 ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_5ghz_revision),
537 sc->ah->ah_radio_5ghz_revision);
538 ATH5K_INFO(sc, "RF%s 2GHz radio found (0x%x)\n",
539 ath5k_chip_name(AR5K_VERSION_RAD,sc->ah->ah_radio_2ghz_revision),
540 sc->ah->ah_radio_2ghz_revision);
541 }
542 }
543
544
545 /* ready to process interrupts */
546 __clear_bit(ATH_STAT_INVALID, sc->status);
547
548 return 0;
549err_ah:
550 ath5k_hw_detach(sc->ah);
551err_irq:
552 free_irq(pdev->irq, sc);
553err_free:
554 pci_disable_msi(pdev);
555 ieee80211_free_hw(hw);
556err_map:
557 pci_iounmap(pdev, mem);
558err_reg:
559 pci_release_region(pdev, 0);
560err_dis:
561 pci_disable_device(pdev);
562err:
563 return ret;
564}
565
566static void __devexit
567ath5k_pci_remove(struct pci_dev *pdev)
568{
569 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
570 struct ath5k_softc *sc = hw->priv;
571
572 ath5k_debug_finish_device(sc);
573 ath5k_detach(pdev, hw);
574 ath5k_hw_detach(sc->ah);
575 free_irq(pdev->irq, sc);
576 pci_disable_msi(pdev);
577 pci_iounmap(pdev, sc->iobase);
578 pci_release_region(pdev, 0);
579 pci_disable_device(pdev);
580 ieee80211_free_hw(hw);
581}
582
583#ifdef CONFIG_PM
584static int
585ath5k_pci_suspend(struct pci_dev *pdev, pm_message_t state)
586{
587 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
588 struct ath5k_softc *sc = hw->priv;
589
590 if (test_bit(ATH_STAT_LEDSOFT, sc->status))
591 ath5k_hw_set_gpio(sc->ah, sc->led_pin, 1);
592
593 ath5k_stop_hw(sc);
594 pci_save_state(pdev);
595 pci_disable_device(pdev);
596 pci_set_power_state(pdev, PCI_D3hot);
597
598 return 0;
599}
600
601static int
602ath5k_pci_resume(struct pci_dev *pdev)
603{
604 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
605 struct ath5k_softc *sc = hw->priv;
606 int err;
607
608 err = pci_set_power_state(pdev, PCI_D0);
609 if (err)
610 return err;
611
612 err = pci_enable_device(pdev);
613 if (err)
614 return err;
615
616 pci_restore_state(pdev);
617 /*
618 * Suspend/Resume resets the PCI configuration space, so we have to
619 * re-disable the RETRY_TIMEOUT register (0x41) to keep
620 * PCI Tx retries from interfering with C3 CPU state
621 */
622 pci_write_config_byte(pdev, 0x41, 0);
623
624 ath5k_init(sc);
625 if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
626 ath5k_hw_set_gpio_output(sc->ah, sc->led_pin);
627 ath5k_hw_set_gpio(sc->ah, sc->led_pin, 0);
628 }
629
630 return 0;
631}
632#endif /* CONFIG_PM */
633
634
635
636/***********************\
637* Driver Initialization *
638\***********************/
639
640static int
641ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw)
642{
643 struct ath5k_softc *sc = hw->priv;
644 struct ath5k_hw *ah = sc->ah;
645 u8 mac[ETH_ALEN];
646 unsigned int i;
647 int ret;
648
649 ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "devid 0x%x\n", pdev->device);
650
651 /*
652 * Check if the MAC has multi-rate retry support.
653 * We do this by trying to setup a fake extended
654 * descriptor. MAC's that don't have support will
655 * return false w/o doing anything. MAC's that do
656 * support it will return true w/o doing anything.
657 */
658 if (ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0))
659 __set_bit(ATH_STAT_MRRETRY, sc->status);
660
661 /*
662 * Reset the key cache since some parts do not
663 * reset the contents on initial power up.
664 */
665 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
666 ath5k_hw_reset_key(ah, i);
667
668 /*
669 * Collect the channel list. The 802.11 layer
670 * is resposible for filtering this list based
671 * on settings like the phy mode and regulatory
672 * domain restrictions.
673 */
674 ret = ath5k_getchannels(hw);
675 if (ret) {
676 ATH5K_ERR(sc, "can't get channels\n");
677 goto err;
678 }
679
680 /* NB: setup here so ath5k_rate_update is happy */
681 if (test_bit(MODE_IEEE80211A, ah->ah_modes))
682 ath5k_setcurmode(sc, MODE_IEEE80211A);
683 else
684 ath5k_setcurmode(sc, MODE_IEEE80211B);
685
686 /*
687 * Allocate tx+rx descriptors and populate the lists.
688 */
689 ret = ath5k_desc_alloc(sc, pdev);
690 if (ret) {
691 ATH5K_ERR(sc, "can't allocate descriptors\n");
692 goto err;
693 }
694
695 /*
696 * Allocate hardware transmit queues: one queue for
697 * beacon frames and one data queue for each QoS
698 * priority. Note that hw functions handle reseting
699 * these queues at the needed time.
700 */
701 ret = ath5k_beaconq_setup(ah);
702 if (ret < 0) {
703 ATH5K_ERR(sc, "can't setup a beacon xmit queue\n");
704 goto err_desc;
705 }
706 sc->bhalq = ret;
707
708 sc->txq = ath5k_txq_setup(sc, AR5K_TX_QUEUE_DATA, AR5K_WME_AC_BK);
709 if (IS_ERR(sc->txq)) {
710 ATH5K_ERR(sc, "can't setup xmit queue\n");
711 ret = PTR_ERR(sc->txq);
712 goto err_bhal;
713 }
714
715 tasklet_init(&sc->rxtq, ath5k_tasklet_rx, (unsigned long)sc);
716 tasklet_init(&sc->txtq, ath5k_tasklet_tx, (unsigned long)sc);
717 tasklet_init(&sc->restq, ath5k_tasklet_reset, (unsigned long)sc);
718 setup_timer(&sc->calib_tim, ath5k_calibrate, (unsigned long)sc);
719 setup_timer(&sc->led_tim, ath5k_led_off, (unsigned long)sc);
720
721 sc->led_on = 0; /* low true */
722 /*
723 * Auto-enable soft led processing for IBM cards and for
724 * 5211 minipci cards.
725 */
726 if (pdev->device == PCI_DEVICE_ID_ATHEROS_AR5212_IBM ||
727 pdev->device == PCI_DEVICE_ID_ATHEROS_AR5211) {
728 __set_bit(ATH_STAT_LEDSOFT, sc->status);
729 sc->led_pin = 0;
730 }
731 /* Enable softled on PIN1 on HP Compaq nc6xx, nc4000 & nx5000 laptops */
732 if (pdev->subsystem_vendor == PCI_VENDOR_ID_COMPAQ) {
733 __set_bit(ATH_STAT_LEDSOFT, sc->status);
734 sc->led_pin = 0;
735 }
736 if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
737 ath5k_hw_set_gpio_output(ah, sc->led_pin);
738 ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
739 }
740
741 ath5k_hw_get_lladdr(ah, mac);
742 SET_IEEE80211_PERM_ADDR(hw, mac);
743 /* All MAC address bits matter for ACKs */
744 memset(sc->bssidmask, 0xff, ETH_ALEN);
745 ath5k_hw_set_bssid_mask(sc->ah, sc->bssidmask);
746
747 ret = ieee80211_register_hw(hw);
748 if (ret) {
749 ATH5K_ERR(sc, "can't register ieee80211 hw\n");
750 goto err_queues;
751 }
752
753 return 0;
754err_queues:
755 ath5k_txq_release(sc);
756err_bhal:
757 ath5k_hw_release_tx_queue(ah, sc->bhalq);
758err_desc:
759 ath5k_desc_free(sc, pdev);
760err:
761 return ret;
762}
763
764static void
765ath5k_detach(struct pci_dev *pdev, struct ieee80211_hw *hw)
766{
767 struct ath5k_softc *sc = hw->priv;
768
769 /*
770 * NB: the order of these is important:
771 * o call the 802.11 layer before detaching ath5k_hw to
772 * insure callbacks into the driver to delete global
773 * key cache entries can be handled
774 * o reclaim the tx queue data structures after calling
775 * the 802.11 layer as we'll get called back to reclaim
776 * node state and potentially want to use them
777 * o to cleanup the tx queues the hal is called, so detach
778 * it last
779 * XXX: ??? detach ath5k_hw ???
780 * Other than that, it's straightforward...
781 */
782 ieee80211_unregister_hw(hw);
783 ath5k_desc_free(sc, pdev);
784 ath5k_txq_release(sc);
785 ath5k_hw_release_tx_queue(sc->ah, sc->bhalq);
786
787 /*
788 * NB: can't reclaim these until after ieee80211_ifdetach
789 * returns because we'll get called back to reclaim node
790 * state and potentially want to use them.
791 */
792}
793
794
795
796
797/********************\
798* Channel/mode setup *
799\********************/
800
801/*
802 * Convert IEEE channel number to MHz frequency.
803 */
804static inline short
805ath5k_ieee2mhz(short chan)
806{
807 if (chan <= 14 || chan >= 27)
808 return ieee80211chan2mhz(chan);
809 else
810 return 2212 + chan * 20;
811}
812
813static unsigned int
814ath5k_copy_rates(struct ieee80211_rate *rates,
815 const struct ath5k_rate_table *rt,
816 unsigned int max)
817{
818 unsigned int i, count;
819
820 if (rt == NULL)
821 return 0;
822
823 for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) {
824 if (!rt->rates[i].valid)
825 continue;
826 rates->rate = rt->rates[i].rate_kbps / 100;
827 rates->val = rt->rates[i].rate_code;
828 rates->flags = rt->rates[i].modulation;
829 rates++;
830 count++;
831 max--;
832 }
833
834 return count;
835}
836
837static unsigned int
838ath5k_copy_channels(struct ath5k_hw *ah,
839 struct ieee80211_channel *channels,
840 unsigned int mode,
841 unsigned int max)
842{
843 static const struct { unsigned int mode, mask, chan; } map[] = {
844 [MODE_IEEE80211A] = { CHANNEL_OFDM, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_A },
845 [MODE_ATHEROS_TURBO] = { CHANNEL_OFDM|CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_T },
846 [MODE_IEEE80211B] = { CHANNEL_CCK, CHANNEL_CCK, CHANNEL_B },
847 [MODE_IEEE80211G] = { CHANNEL_OFDM, CHANNEL_OFDM, CHANNEL_G },
848 [MODE_ATHEROS_TURBOG] = { CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_OFDM | CHANNEL_TURBO, CHANNEL_TG },
849 };
850 static const struct ath5k_regchannel chans_2ghz[] =
851 IEEE80211_CHANNELS_2GHZ;
852 static const struct ath5k_regchannel chans_5ghz[] =
853 IEEE80211_CHANNELS_5GHZ;
854 const struct ath5k_regchannel *chans;
855 enum ath5k_regdom dmn;
856 unsigned int i, count, size, chfreq, all, f, ch;
857
858 if (!test_bit(mode, ah->ah_modes))
859 return 0;
860
861 all = ah->ah_regdomain == DMN_DEFAULT || CHAN_DEBUG == 1;
862
863 switch (mode) {
864 case MODE_IEEE80211A:
865 case MODE_ATHEROS_TURBO:
866 /* 1..220, but 2GHz frequencies are filtered by check_channel */
867 size = all ? 220 : ARRAY_SIZE(chans_5ghz);
868 chans = chans_5ghz;
869 dmn = ath5k_regdom2flag(ah->ah_regdomain,
870 IEEE80211_CHANNELS_5GHZ_MIN);
871 chfreq = CHANNEL_5GHZ;
872 break;
873 case MODE_IEEE80211B:
874 case MODE_IEEE80211G:
875 case MODE_ATHEROS_TURBOG:
876 size = all ? 26 : ARRAY_SIZE(chans_2ghz);
877 chans = chans_2ghz;
878 dmn = ath5k_regdom2flag(ah->ah_regdomain,
879 IEEE80211_CHANNELS_2GHZ_MIN);
880 chfreq = CHANNEL_2GHZ;
881 break;
882 default:
883 ATH5K_WARN(ah->ah_sc, "bad mode, not copying channels\n");
884 return 0;
885 }
886
887 for (i = 0, count = 0; i < size && max > 0; i++) {
888 ch = all ? i + 1 : chans[i].chan;
889 f = ath5k_ieee2mhz(ch);
890 /* Check if channel is supported by the chipset */
891 if (!ath5k_channel_ok(ah, f, chfreq))
892 continue;
893
894 /* Match regulation domain */
895 if (!all && !(IEEE80211_DMN(chans[i].domain) &
896 IEEE80211_DMN(dmn)))
897 continue;
898
899 if (!all && (chans[i].mode & map[mode].mask) != map[mode].mode)
900 continue;
901
902 /* Write channel and increment counter */
903 channels->chan = ch;
904 channels->freq = f;
905 channels->val = map[mode].chan;
906 channels++;
907 count++;
908 max--;
909 }
910
911 return count;
912}
913
914/* Only tries to register modes our EEPROM says it can support */
915#define REGISTER_MODE(m) do { \
916 ret = ath5k_register_mode(hw, m); \
917 if (ret) \
918 return ret; \
919} while (0) \
920
921static inline int
922ath5k_register_mode(struct ieee80211_hw *hw, u8 m)
923{
924 struct ath5k_softc *sc = hw->priv;
925 struct ieee80211_hw_mode *modes = sc->modes;
926 unsigned int i;
927 int ret;
928
929 if (!test_bit(m, sc->ah->ah_capabilities.cap_mode))
930 return 0;
931
932 for (i = 0; i < NUM_DRIVER_MODES; i++) {
933 if (modes[i].mode != m || !modes[i].num_channels)
934 continue;
935 ret = ieee80211_register_hwmode(hw, &modes[i]);
936 if (ret) {
937 ATH5K_ERR(sc, "can't register hwmode %u\n", m);
938 return ret;
939 }
940 return 0;
941 }
942 BUG();
943}
944
945static int
946ath5k_getchannels(struct ieee80211_hw *hw)
947{
948 struct ath5k_softc *sc = hw->priv;
949 struct ath5k_hw *ah = sc->ah;
950 struct ieee80211_hw_mode *modes = sc->modes;
951 unsigned int i, max_r, max_c;
952 int ret;
953
954 BUILD_BUG_ON(ARRAY_SIZE(sc->modes) < 3);
955
956 /* The order here does not matter */
957 modes[0].mode = MODE_IEEE80211G;
958 modes[1].mode = MODE_IEEE80211B;
959 modes[2].mode = MODE_IEEE80211A;
960
961 max_r = ARRAY_SIZE(sc->rates);
962 max_c = ARRAY_SIZE(sc->channels);
963
964 for (i = 0; i < NUM_DRIVER_MODES; i++) {
965 struct ieee80211_hw_mode *mode = &modes[i];
966 const struct ath5k_rate_table *hw_rates;
967
968 if (i == 0) {
969 modes[0].rates = sc->rates;
970 modes->channels = sc->channels;
971 } else {
972 struct ieee80211_hw_mode *prev_mode = &modes[i-1];
973 int prev_num_r = prev_mode->num_rates;
974 int prev_num_c = prev_mode->num_channels;
975 mode->rates = &prev_mode->rates[prev_num_r];
976 mode->channels = &prev_mode->channels[prev_num_c];
977 }
978
979 hw_rates = ath5k_hw_get_rate_table(ah, mode->mode);
980 mode->num_rates = ath5k_copy_rates(mode->rates, hw_rates,
981 max_r);
982 mode->num_channels = ath5k_copy_channels(ah, mode->channels,
983 mode->mode, max_c);
984 max_r -= mode->num_rates;
985 max_c -= mode->num_channels;
986 }
987
988 /* We try to register all modes this driver supports. We don't bother
989 * with MODE_IEEE80211B for AR5212 as MODE_IEEE80211G already accounts
990 * for that as per mac80211. Then, REGISTER_MODE() will will actually
991 * check the eeprom reading for more reliable capability information.
992 * Order matters here as per mac80211's latest preference. This will
993 * all hopefullly soon go away. */
994
995 REGISTER_MODE(MODE_IEEE80211G);
996 if (ah->ah_version != AR5K_AR5212)
997 REGISTER_MODE(MODE_IEEE80211B);
998 REGISTER_MODE(MODE_IEEE80211A);
999
1000 ath5k_debug_dump_modes(sc, modes);
1001
1002 return ret;
1003}
1004
1005/*
1006 * Set/change channels. If the channel is really being changed,
1007 * it's done by reseting the chip. To accomplish this we must
1008 * first cleanup any pending DMA, then restart stuff after a la
1009 * ath5k_init.
1010 */
1011static int
1012ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan)
1013{
1014 struct ath5k_hw *ah = sc->ah;
1015 int ret;
1016
1017 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "%u (%u MHz) -> %u (%u MHz)\n",
1018 sc->curchan->chan, sc->curchan->freq,
1019 chan->chan, chan->freq);
1020
1021 if (chan->freq != sc->curchan->freq || chan->val != sc->curchan->val) {
1022 /*
1023 * To switch channels clear any pending DMA operations;
1024 * wait long enough for the RX fifo to drain, reset the
1025 * hardware at the new frequency, and then re-enable
1026 * the relevant bits of the h/w.
1027 */
1028 ath5k_hw_set_intr(ah, 0); /* disable interrupts */
1029 ath5k_txq_cleanup(sc); /* clear pending tx frames */
1030 ath5k_rx_stop(sc); /* turn off frame recv */
1031 ret = ath5k_hw_reset(ah, sc->opmode, chan, true);
1032 if (ret) {
1033 ATH5K_ERR(sc, "%s: unable to reset channel %u "
1034 "(%u Mhz)\n", __func__, chan->chan, chan->freq);
1035 return ret;
1036 }
1037 sc->curchan = chan;
1038 ath5k_hw_set_txpower_limit(sc->ah, 0);
1039
1040 /*
1041 * Re-enable rx framework.
1042 */
1043 ret = ath5k_rx_start(sc);
1044 if (ret) {
1045 ATH5K_ERR(sc, "%s: unable to restart recv logic\n",
1046 __func__);
1047 return ret;
1048 }
1049
1050 /*
1051 * Change channels and update the h/w rate map
1052 * if we're switching; e.g. 11a to 11b/g.
1053 *
1054 * XXX needed?
1055 */
1056/* ath5k_chan_change(sc, chan); */
1057
1058 ath5k_beacon_config(sc);
1059 /*
1060 * Re-enable interrupts.
1061 */
1062 ath5k_hw_set_intr(ah, sc->imask);
1063 }
1064
1065 return 0;
1066}
1067
1068static void
1069ath5k_setcurmode(struct ath5k_softc *sc, unsigned int mode)
1070{
1071 if (unlikely(test_bit(ATH_STAT_LEDSOFT, sc->status))) {
1072 /* from Atheros NDIS driver, w/ permission */
1073 static const struct {
1074 u16 rate; /* tx/rx 802.11 rate */
1075 u16 timeOn; /* LED on time (ms) */
1076 u16 timeOff; /* LED off time (ms) */
1077 } blinkrates[] = {
1078 { 108, 40, 10 },
1079 { 96, 44, 11 },
1080 { 72, 50, 13 },
1081 { 48, 57, 14 },
1082 { 36, 67, 16 },
1083 { 24, 80, 20 },
1084 { 22, 100, 25 },
1085 { 18, 133, 34 },
1086 { 12, 160, 40 },
1087 { 10, 200, 50 },
1088 { 6, 240, 58 },
1089 { 4, 267, 66 },
1090 { 2, 400, 100 },
1091 { 0, 500, 130 }
1092 };
1093 const struct ath5k_rate_table *rt =
1094 ath5k_hw_get_rate_table(sc->ah, mode);
1095 unsigned int i, j;
1096
1097 BUG_ON(rt == NULL);
1098
1099 memset(sc->hwmap, 0, sizeof(sc->hwmap));
1100 for (i = 0; i < 32; i++) {
1101 u8 ix = rt->rate_code_to_index[i];
1102 if (ix == 0xff) {
1103 sc->hwmap[i].ledon = msecs_to_jiffies(500);
1104 sc->hwmap[i].ledoff = msecs_to_jiffies(130);
1105 continue;
1106 }
1107 sc->hwmap[i].txflags = IEEE80211_RADIOTAP_F_DATAPAD;
1108 if (SHPREAMBLE_FLAG(ix) || rt->rates[ix].modulation ==
1109 IEEE80211_RATE_OFDM)
1110 sc->hwmap[i].txflags |=
1111 IEEE80211_RADIOTAP_F_SHORTPRE;
1112 /* receive frames include FCS */
1113 sc->hwmap[i].rxflags = sc->hwmap[i].txflags |
1114 IEEE80211_RADIOTAP_F_FCS;
1115 /* setup blink rate table to avoid per-packet lookup */
1116 for (j = 0; j < ARRAY_SIZE(blinkrates) - 1; j++)
1117 if (blinkrates[j].rate == /* XXX why 7f? */
1118 (rt->rates[ix].dot11_rate&0x7f))
1119 break;
1120
1121 sc->hwmap[i].ledon = msecs_to_jiffies(blinkrates[j].
1122 timeOn);
1123 sc->hwmap[i].ledoff = msecs_to_jiffies(blinkrates[j].
1124 timeOff);
1125 }
1126 }
1127
1128 sc->curmode = mode;
1129}
1130
1131static void
1132ath5k_mode_setup(struct ath5k_softc *sc)
1133{
1134 struct ath5k_hw *ah = sc->ah;
1135 u32 rfilt;
1136
1137 /* configure rx filter */
1138 rfilt = sc->filter_flags;
1139 ath5k_hw_set_rx_filter(ah, rfilt);
1140
1141 if (ath5k_hw_hasbssidmask(ah))
1142 ath5k_hw_set_bssid_mask(ah, sc->bssidmask);
1143
1144 /* configure operational mode */
1145 ath5k_hw_set_opmode(ah);
1146
1147 ath5k_hw_set_mcast_filter(ah, 0, 0);
1148 ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt);
1149}
1150
1151
1152
1153
1154/***************\
1155* Buffers setup *
1156\***************/
1157
1158static int
1159ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf)
1160{
1161 struct ath5k_hw *ah = sc->ah;
1162 struct sk_buff *skb = bf->skb;
1163 struct ath5k_desc *ds;
1164
1165 if (likely(skb == NULL)) {
1166 unsigned int off;
1167
1168 /*
1169 * Allocate buffer with headroom_needed space for the
1170 * fake physical layer header at the start.
1171 */
1172 skb = dev_alloc_skb(sc->rxbufsize + sc->cachelsz - 1);
1173 if (unlikely(skb == NULL)) {
1174 ATH5K_ERR(sc, "can't alloc skbuff of size %u\n",
1175 sc->rxbufsize + sc->cachelsz - 1);
1176 return -ENOMEM;
1177 }
1178 /*
1179 * Cache-line-align. This is important (for the
1180 * 5210 at least) as not doing so causes bogus data
1181 * in rx'd frames.
1182 */
1183 off = ((unsigned long)skb->data) % sc->cachelsz;
1184 if (off != 0)
1185 skb_reserve(skb, sc->cachelsz - off);
1186
1187 bf->skb = skb;
1188 bf->skbaddr = pci_map_single(sc->pdev,
1189 skb->data, sc->rxbufsize, PCI_DMA_FROMDEVICE);
1190 if (unlikely(pci_dma_mapping_error(bf->skbaddr))) {
1191 ATH5K_ERR(sc, "%s: DMA mapping failed\n", __func__);
1192 dev_kfree_skb(skb);
1193 bf->skb = NULL;
1194 return -ENOMEM;
1195 }
1196 }
1197
1198 /*
1199 * Setup descriptors. For receive we always terminate
1200 * the descriptor list with a self-linked entry so we'll
1201 * not get overrun under high load (as can happen with a
1202 * 5212 when ANI processing enables PHY error frames).
1203 *
1204 * To insure the last descriptor is self-linked we create
1205 * each descriptor as self-linked and add it to the end. As
1206 * each additional descriptor is added the previous self-linked
1207 * entry is ``fixed'' naturally. This should be safe even
1208 * if DMA is happening. When processing RX interrupts we
1209 * never remove/process the last, self-linked, entry on the
1210 * descriptor list. This insures the hardware always has
1211 * someplace to write a new frame.
1212 */
1213 ds = bf->desc;
1214 ds->ds_link = bf->daddr; /* link to self */
1215 ds->ds_data = bf->skbaddr;
1216 ath5k_hw_setup_rx_desc(ah, ds,
1217 skb_tailroom(skb), /* buffer size */
1218 0);
1219
1220 if (sc->rxlink != NULL)
1221 *sc->rxlink = bf->daddr;
1222 sc->rxlink = &ds->ds_link;
1223 return 0;
1224}
1225
1226static int
1227ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1228 struct ieee80211_tx_control *ctl)
1229{
1230 struct ath5k_hw *ah = sc->ah;
1231 struct ath5k_txq *txq = sc->txq;
1232 struct ath5k_desc *ds = bf->desc;
1233 struct sk_buff *skb = bf->skb;
1234 unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID;
1235 int ret;
1236
1237 flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK;
1238 bf->ctl = *ctl;
1239 /* XXX endianness */
1240 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
1241 PCI_DMA_TODEVICE);
1242
1243 if (ctl->flags & IEEE80211_TXCTL_NO_ACK)
1244 flags |= AR5K_TXDESC_NOACK;
1245
1246 pktlen = skb->len + FCS_LEN;
1247
1248 if (!(ctl->flags & IEEE80211_TXCTL_DO_NOT_ENCRYPT)) {
1249 keyidx = ctl->key_idx;
1250 pktlen += ctl->icv_len;
1251 }
1252
1253 ret = ah->ah_setup_tx_desc(ah, ds, pktlen,
1254 ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL,
1255 (ctl->power_level * 2), ctl->tx_rate, ctl->retry_limit, keyidx, 0, flags, 0, 0);
1256 if (ret)
1257 goto err_unmap;
1258
1259 ds->ds_link = 0;
1260 ds->ds_data = bf->skbaddr;
1261
1262 spin_lock_bh(&txq->lock);
1263 list_add_tail(&bf->list, &txq->q);
1264 sc->tx_stats.data[txq->qnum].len++;
1265 if (txq->link == NULL) /* is this first packet? */
1266 ath5k_hw_put_tx_buf(ah, txq->qnum, bf->daddr);
1267 else /* no, so only link it */
1268 *txq->link = bf->daddr;
1269
1270 txq->link = &ds->ds_link;
1271 ath5k_hw_tx_start(ah, txq->qnum);
1272 spin_unlock_bh(&txq->lock);
1273
1274 return 0;
1275err_unmap:
1276 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
1277 return ret;
1278}
1279
1280/*******************\
1281* Descriptors setup *
1282\*******************/
1283
1284static int
1285ath5k_desc_alloc(struct ath5k_softc *sc, struct pci_dev *pdev)
1286{
1287 struct ath5k_desc *ds;
1288 struct ath5k_buf *bf;
1289 dma_addr_t da;
1290 unsigned int i;
1291 int ret;
1292
1293 /* allocate descriptors */
1294 sc->desc_len = sizeof(struct ath5k_desc) *
1295 (ATH_TXBUF + ATH_RXBUF + ATH_BCBUF + 1);
1296 sc->desc = pci_alloc_consistent(pdev, sc->desc_len, &sc->desc_daddr);
1297 if (sc->desc == NULL) {
1298 ATH5K_ERR(sc, "can't allocate descriptors\n");
1299 ret = -ENOMEM;
1300 goto err;
1301 }
1302 ds = sc->desc;
1303 da = sc->desc_daddr;
1304 ATH5K_DBG(sc, ATH5K_DEBUG_ANY, "DMA map: %p (%zu) -> %llx\n",
1305 ds, sc->desc_len, (unsigned long long)sc->desc_daddr);
1306
1307 bf = kcalloc(1 + ATH_TXBUF + ATH_RXBUF + ATH_BCBUF,
1308 sizeof(struct ath5k_buf), GFP_KERNEL);
1309 if (bf == NULL) {
1310 ATH5K_ERR(sc, "can't allocate bufptr\n");
1311 ret = -ENOMEM;
1312 goto err_free;
1313 }
1314 sc->bufptr = bf;
1315
1316 INIT_LIST_HEAD(&sc->rxbuf);
1317 for (i = 0; i < ATH_RXBUF; i++, bf++, ds++, da += sizeof(*ds)) {
1318 bf->desc = ds;
1319 bf->daddr = da;
1320 list_add_tail(&bf->list, &sc->rxbuf);
1321 }
1322
1323 INIT_LIST_HEAD(&sc->txbuf);
1324 sc->txbuf_len = ATH_TXBUF;
1325 for (i = 0; i < ATH_TXBUF; i++, bf++, ds++,
1326 da += sizeof(*ds)) {
1327 bf->desc = ds;
1328 bf->daddr = da;
1329 list_add_tail(&bf->list, &sc->txbuf);
1330 }
1331
1332 /* beacon buffer */
1333 bf->desc = ds;
1334 bf->daddr = da;
1335 sc->bbuf = bf;
1336
1337 return 0;
1338err_free:
1339 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
1340err:
1341 sc->desc = NULL;
1342 return ret;
1343}
1344
1345static void
1346ath5k_desc_free(struct ath5k_softc *sc, struct pci_dev *pdev)
1347{
1348 struct ath5k_buf *bf;
1349
1350 ath5k_txbuf_free(sc, sc->bbuf);
1351 list_for_each_entry(bf, &sc->txbuf, list)
1352 ath5k_txbuf_free(sc, bf);
1353 list_for_each_entry(bf, &sc->rxbuf, list)
1354 ath5k_txbuf_free(sc, bf);
1355
1356 /* Free memory associated with all descriptors */
1357 pci_free_consistent(pdev, sc->desc_len, sc->desc, sc->desc_daddr);
1358
1359 kfree(sc->bufptr);
1360 sc->bufptr = NULL;
1361}
1362
1363
1364
1365
1366
1367/**************\
1368* Queues setup *
1369\**************/
1370
1371static struct ath5k_txq *
1372ath5k_txq_setup(struct ath5k_softc *sc,
1373 int qtype, int subtype)
1374{
1375 struct ath5k_hw *ah = sc->ah;
1376 struct ath5k_txq *txq;
1377 struct ath5k_txq_info qi = {
1378 .tqi_subtype = subtype,
1379 .tqi_aifs = AR5K_TXQ_USEDEFAULT,
1380 .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
1381 .tqi_cw_max = AR5K_TXQ_USEDEFAULT
1382 };
1383 int qnum;
1384
1385 /*
1386 * Enable interrupts only for EOL and DESC conditions.
1387 * We mark tx descriptors to receive a DESC interrupt
1388 * when a tx queue gets deep; otherwise waiting for the
1389 * EOL to reap descriptors. Note that this is done to
1390 * reduce interrupt load and this only defers reaping
1391 * descriptors, never transmitting frames. Aside from
1392 * reducing interrupts this also permits more concurrency.
1393 * The only potential downside is if the tx queue backs
1394 * up in which case the top half of the kernel may backup
1395 * due to a lack of tx descriptors.
1396 */
1397 qi.tqi_flags = AR5K_TXQ_FLAG_TXEOLINT_ENABLE |
1398 AR5K_TXQ_FLAG_TXDESCINT_ENABLE;
1399 qnum = ath5k_hw_setup_tx_queue(ah, qtype, &qi);
1400 if (qnum < 0) {
1401 /*
1402 * NB: don't print a message, this happens
1403 * normally on parts with too few tx queues
1404 */
1405 return ERR_PTR(qnum);
1406 }
1407 if (qnum >= ARRAY_SIZE(sc->txqs)) {
1408 ATH5K_ERR(sc, "hw qnum %u out of range, max %tu!\n",
1409 qnum, ARRAY_SIZE(sc->txqs));
1410 ath5k_hw_release_tx_queue(ah, qnum);
1411 return ERR_PTR(-EINVAL);
1412 }
1413 txq = &sc->txqs[qnum];
1414 if (!txq->setup) {
1415 txq->qnum = qnum;
1416 txq->link = NULL;
1417 INIT_LIST_HEAD(&txq->q);
1418 spin_lock_init(&txq->lock);
1419 txq->setup = true;
1420 }
1421 return &sc->txqs[qnum];
1422}
1423
1424static int
1425ath5k_beaconq_setup(struct ath5k_hw *ah)
1426{
1427 struct ath5k_txq_info qi = {
1428 .tqi_aifs = AR5K_TXQ_USEDEFAULT,
1429 .tqi_cw_min = AR5K_TXQ_USEDEFAULT,
1430 .tqi_cw_max = AR5K_TXQ_USEDEFAULT,
1431 /* NB: for dynamic turbo, don't enable any other interrupts */
1432 .tqi_flags = AR5K_TXQ_FLAG_TXDESCINT_ENABLE
1433 };
1434
1435 return ath5k_hw_setup_tx_queue(ah, AR5K_TX_QUEUE_BEACON, &qi);
1436}
1437
1438static int
1439ath5k_beaconq_config(struct ath5k_softc *sc)
1440{
1441 struct ath5k_hw *ah = sc->ah;
1442 struct ath5k_txq_info qi;
1443 int ret;
1444
1445 ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi);
1446 if (ret)
1447 return ret;
1448 if (sc->opmode == IEEE80211_IF_TYPE_AP ||
1449 sc->opmode == IEEE80211_IF_TYPE_IBSS) {
1450 /*
1451 * Always burst out beacon and CAB traffic
1452 * (aifs = cwmin = cwmax = 0)
1453 */
1454 qi.tqi_aifs = 0;
1455 qi.tqi_cw_min = 0;
1456 qi.tqi_cw_max = 0;
1457 }
1458
1459 ret = ath5k_hw_setup_tx_queueprops(ah, sc->bhalq, &qi);
1460 if (ret) {
1461 ATH5K_ERR(sc, "%s: unable to update parameters for beacon "
1462 "hardware queue!\n", __func__);
1463 return ret;
1464 }
1465
1466 return ath5k_hw_reset_tx_queue(ah, sc->bhalq); /* push to h/w */;
1467}
1468
1469static void
1470ath5k_txq_drainq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1471{
1472 struct ath5k_buf *bf, *bf0;
1473
1474 /*
1475 * NB: this assumes output has been stopped and
1476 * we do not need to block ath5k_tx_tasklet
1477 */
1478 spin_lock_bh(&txq->lock);
1479 list_for_each_entry_safe(bf, bf0, &txq->q, list) {
1480 ath5k_debug_printtxbuf(sc, bf, !sc->ah->ah_proc_tx_desc(sc->ah,
1481 bf->desc));
1482
1483 ath5k_txbuf_free(sc, bf);
1484
1485 spin_lock_bh(&sc->txbuflock);
1486 sc->tx_stats.data[txq->qnum].len--;
1487 list_move_tail(&bf->list, &sc->txbuf);
1488 sc->txbuf_len++;
1489 spin_unlock_bh(&sc->txbuflock);
1490 }
1491 txq->link = NULL;
1492 spin_unlock_bh(&txq->lock);
1493}
1494
1495/*
1496 * Drain the transmit queues and reclaim resources.
1497 */
1498static void
1499ath5k_txq_cleanup(struct ath5k_softc *sc)
1500{
1501 struct ath5k_hw *ah = sc->ah;
1502 unsigned int i;
1503
1504 /* XXX return value */
1505 if (likely(!test_bit(ATH_STAT_INVALID, sc->status))) {
1506 /* don't touch the hardware if marked invalid */
1507 ath5k_hw_stop_tx_dma(ah, sc->bhalq);
1508 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n",
1509 ath5k_hw_get_tx_buf(ah, sc->bhalq));
1510 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
1511 if (sc->txqs[i].setup) {
1512 ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum);
1513 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, "
1514 "link %p\n",
1515 sc->txqs[i].qnum,
1516 ath5k_hw_get_tx_buf(ah,
1517 sc->txqs[i].qnum),
1518 sc->txqs[i].link);
1519 }
1520 }
1521 ieee80211_start_queues(sc->hw); /* XXX move to callers */
1522
1523 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++)
1524 if (sc->txqs[i].setup)
1525 ath5k_txq_drainq(sc, &sc->txqs[i]);
1526}
1527
1528static void
1529ath5k_txq_release(struct ath5k_softc *sc)
1530{
1531 struct ath5k_txq *txq = sc->txqs;
1532 unsigned int i;
1533
1534 for (i = 0; i < ARRAY_SIZE(sc->txqs); i++, txq++)
1535 if (txq->setup) {
1536 ath5k_hw_release_tx_queue(sc->ah, txq->qnum);
1537 txq->setup = false;
1538 }
1539}
1540
1541
1542
1543
1544/*************\
1545* RX Handling *
1546\*************/
1547
1548/*
1549 * Enable the receive h/w following a reset.
1550 */
1551static int
1552ath5k_rx_start(struct ath5k_softc *sc)
1553{
1554 struct ath5k_hw *ah = sc->ah;
1555 struct ath5k_buf *bf;
1556 int ret;
1557
1558 sc->rxbufsize = roundup(IEEE80211_MAX_LEN, sc->cachelsz);
1559
1560 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "cachelsz %u rxbufsize %u\n",
1561 sc->cachelsz, sc->rxbufsize);
1562
1563 sc->rxlink = NULL;
1564
1565 spin_lock_bh(&sc->rxbuflock);
1566 list_for_each_entry(bf, &sc->rxbuf, list) {
1567 ret = ath5k_rxbuf_setup(sc, bf);
1568 if (ret != 0) {
1569 spin_unlock_bh(&sc->rxbuflock);
1570 goto err;
1571 }
1572 }
1573 bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
1574 spin_unlock_bh(&sc->rxbuflock);
1575
1576 ath5k_hw_put_rx_buf(ah, bf->daddr);
1577 ath5k_hw_start_rx(ah); /* enable recv descriptors */
1578 ath5k_mode_setup(sc); /* set filters, etc. */
1579 ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */
1580
1581 return 0;
1582err:
1583 return ret;
1584}
1585
1586/*
1587 * Disable the receive h/w in preparation for a reset.
1588 */
1589static void
1590ath5k_rx_stop(struct ath5k_softc *sc)
1591{
1592 struct ath5k_hw *ah = sc->ah;
1593
1594 ath5k_hw_stop_pcu_recv(ah); /* disable PCU */
1595 ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */
1596 ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */
1597 mdelay(3); /* 3ms is long enough for 1 frame */
1598
1599 ath5k_debug_printrxbuffs(sc, ah);
1600
1601 sc->rxlink = NULL; /* just in case */
1602}
1603
1604static unsigned int
1605ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds,
1606 struct sk_buff *skb)
1607{
1608 struct ieee80211_hdr *hdr = (void *)skb->data;
1609 unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb);
1610
1611 if (!(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) &&
1612 ds->ds_rxstat.rs_keyix != AR5K_RXKEYIX_INVALID)
1613 return RX_FLAG_DECRYPTED;
1614
1615 /* Apparently when a default key is used to decrypt the packet
1616 the hw does not set the index used to decrypt. In such cases
1617 get the index from the packet. */
1618 if ((le16_to_cpu(hdr->frame_control) & IEEE80211_FCTL_PROTECTED) &&
1619 !(ds->ds_rxstat.rs_status & AR5K_RXERR_DECRYPT) &&
1620 skb->len >= hlen + 4) {
1621 keyix = skb->data[hlen + 3] >> 6;
1622
1623 if (test_bit(keyix, sc->keymap))
1624 return RX_FLAG_DECRYPTED;
1625 }
1626
1627 return 0;
1628}
1629
1630static void
1631ath5k_tasklet_rx(unsigned long data)
1632{
1633 struct ieee80211_rx_status rxs = {};
1634 struct sk_buff *skb;
1635 struct ath5k_softc *sc = (void *)data;
1636 struct ath5k_buf *bf;
1637 struct ath5k_desc *ds;
1638 u16 len;
1639 u8 stat;
1640 int ret;
1641 int hdrlen;
1642 int pad;
1643
1644 spin_lock(&sc->rxbuflock);
1645 do {
1646 if (unlikely(list_empty(&sc->rxbuf))) {
1647 ATH5K_WARN(sc, "empty rx buf pool\n");
1648 break;
1649 }
1650 bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list);
1651 BUG_ON(bf->skb == NULL);
1652 skb = bf->skb;
1653 ds = bf->desc;
1654
1655 /* TODO only one segment */
1656 pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr,
1657 sc->desc_len, PCI_DMA_FROMDEVICE);
1658
1659 if (unlikely(ds->ds_link == bf->daddr)) /* this is the end */
1660 break;
1661
1662 ret = sc->ah->ah_proc_rx_desc(sc->ah, ds);
1663 if (unlikely(ret == -EINPROGRESS))
1664 break;
1665 else if (unlikely(ret)) {
1666 ATH5K_ERR(sc, "error in processing rx descriptor\n");
1667 return;
1668 }
1669
1670 if (unlikely(ds->ds_rxstat.rs_more)) {
1671 ATH5K_WARN(sc, "unsupported jumbo\n");
1672 goto next;
1673 }
1674
1675 stat = ds->ds_rxstat.rs_status;
1676 if (unlikely(stat)) {
1677 if (stat & AR5K_RXERR_PHY)
1678 goto next;
1679 if (stat & AR5K_RXERR_DECRYPT) {
1680 /*
1681 * Decrypt error. If the error occurred
1682 * because there was no hardware key, then
1683 * let the frame through so the upper layers
1684 * can process it. This is necessary for 5210
1685 * parts which have no way to setup a ``clear''
1686 * key cache entry.
1687 *
1688 * XXX do key cache faulting
1689 */
1690 if (ds->ds_rxstat.rs_keyix ==
1691 AR5K_RXKEYIX_INVALID &&
1692 !(stat & AR5K_RXERR_CRC))
1693 goto accept;
1694 }
1695 if (stat & AR5K_RXERR_MIC) {
1696 rxs.flag |= RX_FLAG_MMIC_ERROR;
1697 goto accept;
1698 }
1699
1700 /* let crypto-error packets fall through in MNTR */
1701 if ((stat & ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) ||
1702 sc->opmode != IEEE80211_IF_TYPE_MNTR)
1703 goto next;
1704 }
1705accept:
1706 len = ds->ds_rxstat.rs_datalen;
1707 pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, len,
1708 PCI_DMA_FROMDEVICE);
1709 pci_unmap_single(sc->pdev, bf->skbaddr, sc->rxbufsize,
1710 PCI_DMA_FROMDEVICE);
1711 bf->skb = NULL;
1712
1713 skb_put(skb, len);
1714
1715 /*
1716 * the hardware adds a padding to 4 byte boundaries between
1717 * the header and the payload data if the header length is
1718 * not multiples of 4 - remove it
1719 */
1720 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
1721 if (hdrlen & 3) {
1722 pad = hdrlen % 4;
1723 memmove(skb->data + pad, skb->data, hdrlen);
1724 skb_pull(skb, pad);
1725 }
1726
1727 if (sc->opmode == IEEE80211_IF_TYPE_MNTR)
1728 rxs.mactime = ath5k_extend_tsf(sc->ah,
1729 ds->ds_rxstat.rs_tstamp);
1730 else
1731 rxs.mactime = ds->ds_rxstat.rs_tstamp;
1732 rxs.freq = sc->curchan->freq;
1733 rxs.channel = sc->curchan->chan;
1734 rxs.phymode = sc->curmode;
1735
1736 /*
1737 * signal quality:
1738 * the names here are misleading and the usage of these
1739 * values by iwconfig makes it even worse
1740 */
1741 /* noise floor in dBm, from the last noise calibration */
1742 rxs.noise = sc->ah->ah_noise_floor;
1743 /* signal level in dBm */
1744 rxs.ssi = rxs.noise + ds->ds_rxstat.rs_rssi;
1745 /*
1746 * "signal" is actually displayed as Link Quality by iwconfig
1747 * we provide a percentage based on rssi (assuming max rssi 64)
1748 */
1749 rxs.signal = ds->ds_rxstat.rs_rssi * 100 / 64;
1750
1751 rxs.antenna = ds->ds_rxstat.rs_antenna;
1752 rxs.rate = ds->ds_rxstat.rs_rate;
1753 rxs.flag |= ath5k_rx_decrypted(sc, ds, skb);
1754
1755 ath5k_debug_dump_skb(sc, skb, "RX ", 0);
1756
1757 __ieee80211_rx(sc->hw, skb, &rxs);
1758 sc->led_rxrate = ds->ds_rxstat.rs_rate;
1759 ath5k_led_event(sc, ATH_LED_RX);
1760next:
1761 list_move_tail(&bf->list, &sc->rxbuf);
1762 } while (ath5k_rxbuf_setup(sc, bf) == 0);
1763 spin_unlock(&sc->rxbuflock);
1764}
1765
1766
1767
1768
1769/*************\
1770* TX Handling *
1771\*************/
1772
1773static void
1774ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq)
1775{
1776 struct ieee80211_tx_status txs = {};
1777 struct ath5k_buf *bf, *bf0;
1778 struct ath5k_desc *ds;
1779 struct sk_buff *skb;
1780 int ret;
1781
1782 spin_lock(&txq->lock);
1783 list_for_each_entry_safe(bf, bf0, &txq->q, list) {
1784 ds = bf->desc;
1785
1786 /* TODO only one segment */
1787 pci_dma_sync_single_for_cpu(sc->pdev, sc->desc_daddr,
1788 sc->desc_len, PCI_DMA_FROMDEVICE);
1789 ret = sc->ah->ah_proc_tx_desc(sc->ah, ds);
1790 if (unlikely(ret == -EINPROGRESS))
1791 break;
1792 else if (unlikely(ret)) {
1793 ATH5K_ERR(sc, "error %d while processing queue %u\n",
1794 ret, txq->qnum);
1795 break;
1796 }
1797
1798 skb = bf->skb;
1799 bf->skb = NULL;
1800 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len,
1801 PCI_DMA_TODEVICE);
1802
1803 txs.control = bf->ctl;
1804 txs.retry_count = ds->ds_txstat.ts_shortretry +
1805 ds->ds_txstat.ts_longretry / 6;
1806 if (unlikely(ds->ds_txstat.ts_status)) {
1807 sc->ll_stats.dot11ACKFailureCount++;
1808 if (ds->ds_txstat.ts_status & AR5K_TXERR_XRETRY)
1809 txs.excessive_retries = 1;
1810 else if (ds->ds_txstat.ts_status & AR5K_TXERR_FILT)
1811 txs.flags |= IEEE80211_TX_STATUS_TX_FILTERED;
1812 } else {
1813 txs.flags |= IEEE80211_TX_STATUS_ACK;
1814 txs.ack_signal = ds->ds_txstat.ts_rssi;
1815 }
1816
1817 ieee80211_tx_status(sc->hw, skb, &txs);
1818 sc->tx_stats.data[txq->qnum].count++;
1819
1820 spin_lock(&sc->txbuflock);
1821 sc->tx_stats.data[txq->qnum].len--;
1822 list_move_tail(&bf->list, &sc->txbuf);
1823 sc->txbuf_len++;
1824 spin_unlock(&sc->txbuflock);
1825 }
1826 if (likely(list_empty(&txq->q)))
1827 txq->link = NULL;
1828 spin_unlock(&txq->lock);
1829 if (sc->txbuf_len > ATH_TXBUF / 5)
1830 ieee80211_wake_queues(sc->hw);
1831}
1832
1833static void
1834ath5k_tasklet_tx(unsigned long data)
1835{
1836 struct ath5k_softc *sc = (void *)data;
1837
1838 ath5k_tx_processq(sc, sc->txq);
1839
1840 ath5k_led_event(sc, ATH_LED_TX);
1841}
1842
1843
1844
1845
1846/*****************\
1847* Beacon handling *
1848\*****************/
1849
1850/*
1851 * Setup the beacon frame for transmit.
1852 */
1853static int
1854ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf,
1855 struct ieee80211_tx_control *ctl)
1856{
1857 struct sk_buff *skb = bf->skb;
1858 struct ath5k_hw *ah = sc->ah;
1859 struct ath5k_desc *ds;
1860 int ret, antenna = 0;
1861 u32 flags;
1862
1863 bf->skbaddr = pci_map_single(sc->pdev, skb->data, skb->len,
1864 PCI_DMA_TODEVICE);
1865 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "skb %p [data %p len %u] "
1866 "skbaddr %llx\n", skb, skb->data, skb->len,
1867 (unsigned long long)bf->skbaddr);
1868 if (pci_dma_mapping_error(bf->skbaddr)) {
1869 ATH5K_ERR(sc, "beacon DMA mapping failed\n");
1870 return -EIO;
1871 }
1872
1873 ds = bf->desc;
1874
1875 flags = AR5K_TXDESC_NOACK;
1876 if (sc->opmode == IEEE80211_IF_TYPE_IBSS && ath5k_hw_hasveol(ah)) {
1877 ds->ds_link = bf->daddr; /* self-linked */
1878 flags |= AR5K_TXDESC_VEOL;
1879 /*
1880 * Let hardware handle antenna switching if txantenna is not set
1881 */
1882 } else {
1883 ds->ds_link = 0;
1884 /*
1885 * Switch antenna every 4 beacons if txantenna is not set
1886 * XXX assumes two antennas
1887 */
1888 if (antenna == 0)
1889 antenna = sc->bsent & 4 ? 2 : 1;
1890 }
1891
1892 ds->ds_data = bf->skbaddr;
1893 ret = ah->ah_setup_tx_desc(ah, ds, skb->len + FCS_LEN,
1894 ieee80211_get_hdrlen_from_skb(skb),
1895 AR5K_PKT_TYPE_BEACON, (ctl->power_level * 2), ctl->tx_rate, 1,
1896 AR5K_TXKEYIX_INVALID, antenna, flags, 0, 0);
1897 if (ret)
1898 goto err_unmap;
1899
1900 return 0;
1901err_unmap:
1902 pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, PCI_DMA_TODEVICE);
1903 return ret;
1904}
1905
1906/*
1907 * Transmit a beacon frame at SWBA. Dynamic updates to the
1908 * frame contents are done as needed and the slot time is
1909 * also adjusted based on current state.
1910 *
1911 * this is usually called from interrupt context (ath5k_intr())
1912 * but also from ath5k_beacon_config() in IBSS mode which in turn
1913 * can be called from a tasklet and user context
1914 */
1915static void
1916ath5k_beacon_send(struct ath5k_softc *sc)
1917{
1918 struct ath5k_buf *bf = sc->bbuf;
1919 struct ath5k_hw *ah = sc->ah;
1920
1921 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "in beacon_send\n");
1922
1923 if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA ||
1924 sc->opmode == IEEE80211_IF_TYPE_MNTR)) {
1925 ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL);
1926 return;
1927 }
1928 /*
1929 * Check if the previous beacon has gone out. If
1930 * not don't don't try to post another, skip this
1931 * period and wait for the next. Missed beacons
1932 * indicate a problem and should not occur. If we
1933 * miss too many consecutive beacons reset the device.
1934 */
1935 if (unlikely(ath5k_hw_num_tx_pending(ah, sc->bhalq) != 0)) {
1936 sc->bmisscount++;
1937 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
1938 "missed %u consecutive beacons\n", sc->bmisscount);
1939 if (sc->bmisscount > 3) { /* NB: 3 is a guess */
1940 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
1941 "stuck beacon time (%u missed)\n",
1942 sc->bmisscount);
1943 tasklet_schedule(&sc->restq);
1944 }
1945 return;
1946 }
1947 if (unlikely(sc->bmisscount != 0)) {
1948 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC,
1949 "resume beacon xmit after %u misses\n",
1950 sc->bmisscount);
1951 sc->bmisscount = 0;
1952 }
1953
1954 /*
1955 * Stop any current dma and put the new frame on the queue.
1956 * This should never fail since we check above that no frames
1957 * are still pending on the queue.
1958 */
1959 if (unlikely(ath5k_hw_stop_tx_dma(ah, sc->bhalq))) {
1960 ATH5K_WARN(sc, "beacon queue %u didn't stop?\n", sc->bhalq);
1961 /* NB: hw still stops DMA, so proceed */
1962 }
1963 pci_dma_sync_single_for_cpu(sc->pdev, bf->skbaddr, bf->skb->len,
1964 PCI_DMA_TODEVICE);
1965
1966 ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr);
1967 ath5k_hw_tx_start(ah, sc->bhalq);
1968 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON_PROC, "TXDP[%u] = %llx (%p)\n",
1969 sc->bhalq, (unsigned long long)bf->daddr, bf->desc);
1970
1971 sc->bsent++;
1972}
1973
1974
1975static void
1976ath5k_beacon_update_timers(struct ath5k_softc *sc)
1977{
1978 struct ath5k_hw *ah = sc->ah;
1979 u32 uninitialized_var(nexttbtt), intval, tsftu;
1980 u64 tsf;
1981
1982 intval = sc->bintval & AR5K_BEACON_PERIOD;
1983 if (WARN_ON(!intval))
1984 return;
1985
1986 /* current TSF converted to TU */
1987 tsf = ath5k_hw_get_tsf64(ah);
1988 tsftu = TSF_TO_TU(tsf);
1989
1990 /*
1991 * Pull nexttbtt forward to reflect the current
1992 * TSF. Add one intval otherwise the timespan
1993 * can be too short for ibss merges.
1994 */
1995 nexttbtt = tsftu + 2 * intval;
1996
1997 ATH5K_DBG(sc, ATH5K_DEBUG_BEACON,
1998 "hw tsftu %u nexttbtt %u intval %u\n", tsftu, nexttbtt, intval);
1999
2000 intval |= AR5K_BEACON_ENA;
2001
2002 ath5k_hw_init_beacon(ah, nexttbtt, intval);
2003}
2004
2005
2006/*
2007 * Configure the beacon timers and interrupts based on the operating mode
2008 *
2009 * When operating in station mode we want to receive a BMISS interrupt when we
2010 * stop seeing beacons from the AP we've associated with so we can look for
2011 * another AP to associate with.
2012 *
2013 * In IBSS mode we need to configure the beacon timers and use a self-linked tx
2014 * descriptor if possible. If the hardware cannot deal with that we enable SWBA
2015 * interrupts to send the beacons from the interrupt handler.
2016 */
2017static void
2018ath5k_beacon_config(struct ath5k_softc *sc)
2019{
2020 struct ath5k_hw *ah = sc->ah;
2021
2022 ath5k_hw_set_intr(ah, 0);
2023 sc->bmisscount = 0;
2024
2025 if (sc->opmode == IEEE80211_IF_TYPE_STA) {
2026 sc->imask |= AR5K_INT_BMISS;
2027 } else if (sc->opmode == IEEE80211_IF_TYPE_IBSS) {
2028 /*
2029 * In IBSS mode enable the beacon timers but only enable SWBA
2030 * interrupts if we need to manually prepare beacon frames.
2031 * Otherwise we use a self-linked tx descriptor and let the
2032 * hardware deal with things. In that case we have to load it
2033 * only once here.
2034 */
2035 ath5k_beaconq_config(sc);
2036 ath5k_beacon_update_timers(sc);
2037
2038 if (!ath5k_hw_hasveol(ah))
2039 sc->imask |= AR5K_INT_SWBA;
2040 else
2041 ath5k_beacon_send(sc);
2042 }
2043 /* TODO else AP */
2044
2045 ath5k_hw_set_intr(ah, sc->imask);
2046}
2047
2048
2049/********************\
2050* Interrupt handling *
2051\********************/
2052
2053static int
2054ath5k_init(struct ath5k_softc *sc)
2055{
2056 int ret;
2057
2058 mutex_lock(&sc->lock);
2059
2060 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mode %d\n", sc->opmode);
2061
2062 /*
2063 * Stop anything previously setup. This is safe
2064 * no matter this is the first time through or not.
2065 */
2066 ath5k_stop_locked(sc);
2067
2068 /*
2069 * The basic interface to setting the hardware in a good
2070 * state is ``reset''. On return the hardware is known to
2071 * be powered up and with interrupts disabled. This must
2072 * be followed by initialization of the appropriate bits
2073 * and then setup of the interrupt mask.
2074 */
2075 sc->curchan = sc->hw->conf.chan;
2076 ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false);
2077 if (ret) {
2078 ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret);
2079 goto done;
2080 }
2081 /*
2082 * This is needed only to setup initial state
2083 * but it's best done after a reset.
2084 */
2085 ath5k_hw_set_txpower_limit(sc->ah, 0);
2086
2087 /*
2088 * Setup the hardware after reset: the key cache
2089 * is filled as needed and the receive engine is
2090 * set going. Frame transmit is handled entirely
2091 * in the frame output path; there's nothing to do
2092 * here except setup the interrupt mask.
2093 */
2094 ret = ath5k_rx_start(sc);
2095 if (ret)
2096 goto done;
2097
2098 /*
2099 * Enable interrupts.
2100 */
2101 sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL |
2102 AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL;
2103
2104 ath5k_hw_set_intr(sc->ah, sc->imask);
2105 /* Set ack to be sent at low bit-rates */
2106 ath5k_hw_set_ack_bitrate_high(sc->ah, false);
2107
2108 mod_timer(&sc->calib_tim, round_jiffies(jiffies +
2109 msecs_to_jiffies(ath5k_calinterval * 1000)));
2110
2111 ret = 0;
2112done:
2113 mutex_unlock(&sc->lock);
2114 return ret;
2115}
2116
2117static int
2118ath5k_stop_locked(struct ath5k_softc *sc)
2119{
2120 struct ath5k_hw *ah = sc->ah;
2121
2122 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "invalid %u\n",
2123 test_bit(ATH_STAT_INVALID, sc->status));
2124
2125 /*
2126 * Shutdown the hardware and driver:
2127 * stop output from above
2128 * disable interrupts
2129 * turn off timers
2130 * turn off the radio
2131 * clear transmit machinery
2132 * clear receive machinery
2133 * drain and release tx queues
2134 * reclaim beacon resources
2135 * power down hardware
2136 *
2137 * Note that some of this work is not possible if the
2138 * hardware is gone (invalid).
2139 */
2140 ieee80211_stop_queues(sc->hw);
2141
2142 if (!test_bit(ATH_STAT_INVALID, sc->status)) {
2143 if (test_bit(ATH_STAT_LEDSOFT, sc->status)) {
2144 del_timer_sync(&sc->led_tim);
2145 ath5k_hw_set_gpio(ah, sc->led_pin, !sc->led_on);
2146 __clear_bit(ATH_STAT_LEDBLINKING, sc->status);
2147 }
2148 ath5k_hw_set_intr(ah, 0);
2149 }
2150 ath5k_txq_cleanup(sc);
2151 if (!test_bit(ATH_STAT_INVALID, sc->status)) {
2152 ath5k_rx_stop(sc);
2153 ath5k_hw_phy_disable(ah);
2154 } else
2155 sc->rxlink = NULL;
2156
2157 return 0;
2158}
2159
2160/*
2161 * Stop the device, grabbing the top-level lock to protect
2162 * against concurrent entry through ath5k_init (which can happen
2163 * if another thread does a system call and the thread doing the
2164 * stop is preempted).
2165 */
2166static int
2167ath5k_stop_hw(struct ath5k_softc *sc)
2168{
2169 int ret;
2170
2171 mutex_lock(&sc->lock);
2172 ret = ath5k_stop_locked(sc);
2173 if (ret == 0 && !test_bit(ATH_STAT_INVALID, sc->status)) {
2174 /*
2175 * Set the chip in full sleep mode. Note that we are
2176 * careful to do this only when bringing the interface
2177 * completely to a stop. When the chip is in this state
2178 * it must be carefully woken up or references to
2179 * registers in the PCI clock domain may freeze the bus
2180 * (and system). This varies by chip and is mostly an
2181 * issue with newer parts that go to sleep more quickly.
2182 */
2183 if (sc->ah->ah_mac_srev >= 0x78) {
2184 /*
2185 * XXX
2186 * don't put newer MAC revisions > 7.8 to sleep because
2187 * of the above mentioned problems
2188 */
2189 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "mac version > 7.8, "
2190 "not putting device to sleep\n");
2191 } else {
2192 ATH5K_DBG(sc, ATH5K_DEBUG_RESET,
2193 "putting device to full sleep\n");
2194 ath5k_hw_set_power(sc->ah, AR5K_PM_FULL_SLEEP, true, 0);
2195 }
2196 }
2197 ath5k_txbuf_free(sc, sc->bbuf);
2198 mutex_unlock(&sc->lock);
2199
2200 del_timer_sync(&sc->calib_tim);
2201
2202 return ret;
2203}
2204
2205static irqreturn_t
2206ath5k_intr(int irq, void *dev_id)
2207{
2208 struct ath5k_softc *sc = dev_id;
2209 struct ath5k_hw *ah = sc->ah;
2210 enum ath5k_int status;
2211 unsigned int counter = 1000;
2212
2213 if (unlikely(test_bit(ATH_STAT_INVALID, sc->status) ||
2214 !ath5k_hw_is_intr_pending(ah)))
2215 return IRQ_NONE;
2216
2217 do {
2218 /*
2219 * Figure out the reason(s) for the interrupt. Note
2220 * that get_isr returns a pseudo-ISR that may include
2221 * bits we haven't explicitly enabled so we mask the
2222 * value to insure we only process bits we requested.
2223 */
2224 ath5k_hw_get_isr(ah, &status); /* NB: clears IRQ too */
2225 ATH5K_DBG(sc, ATH5K_DEBUG_INTR, "status 0x%x/0x%x\n",
2226 status, sc->imask);
2227 status &= sc->imask; /* discard unasked for bits */
2228 if (unlikely(status & AR5K_INT_FATAL)) {
2229 /*
2230 * Fatal errors are unrecoverable.
2231 * Typically these are caused by DMA errors.
2232 */
2233 tasklet_schedule(&sc->restq);
2234 } else if (unlikely(status & AR5K_INT_RXORN)) {
2235 tasklet_schedule(&sc->restq);
2236 } else {
2237 if (status & AR5K_INT_SWBA) {
2238 /*
2239 * Software beacon alert--time to send a beacon.
2240 * Handle beacon transmission directly; deferring
2241 * this is too slow to meet timing constraints
2242 * under load.
2243 */
2244 ath5k_beacon_send(sc);
2245 }
2246 if (status & AR5K_INT_RXEOL) {
2247 /*
2248 * NB: the hardware should re-read the link when
2249 * RXE bit is written, but it doesn't work at
2250 * least on older hardware revs.
2251 */
2252 sc->rxlink = NULL;
2253 }
2254 if (status & AR5K_INT_TXURN) {
2255 /* bump tx trigger level */
2256 ath5k_hw_update_tx_triglevel(ah, true);
2257 }
2258 if (status & AR5K_INT_RX)
2259 tasklet_schedule(&sc->rxtq);
2260 if (status & AR5K_INT_TX)
2261 tasklet_schedule(&sc->txtq);
2262 if (status & AR5K_INT_BMISS) {
2263 }
2264 if (status & AR5K_INT_MIB) {
2265 /* TODO */
2266 }
2267 }
2268 } while (ath5k_hw_is_intr_pending(ah) && counter-- > 0);
2269
2270 if (unlikely(!counter))
2271 ATH5K_WARN(sc, "too many interrupts, giving up for now\n");
2272
2273 return IRQ_HANDLED;
2274}
2275
2276static void
2277ath5k_tasklet_reset(unsigned long data)
2278{
2279 struct ath5k_softc *sc = (void *)data;
2280
2281 ath5k_reset(sc->hw);
2282}
2283
2284/*
2285 * Periodically recalibrate the PHY to account
2286 * for temperature/environment changes.
2287 */
2288static void
2289ath5k_calibrate(unsigned long data)
2290{
2291 struct ath5k_softc *sc = (void *)data;
2292 struct ath5k_hw *ah = sc->ah;
2293
2294 ATH5K_DBG(sc, ATH5K_DEBUG_CALIBRATE, "channel %u/%x\n",
2295 sc->curchan->chan, sc->curchan->val);
2296
2297 if (ath5k_hw_get_rf_gain(ah) == AR5K_RFGAIN_NEED_CHANGE) {
2298 /*
2299 * Rfgain is out of bounds, reset the chip
2300 * to load new gain values.
2301 */
2302 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n");
2303 ath5k_reset(sc->hw);
2304 }
2305 if (ath5k_hw_phy_calibrate(ah, sc->curchan))
2306 ATH5K_ERR(sc, "calibration of channel %u failed\n",
2307 sc->curchan->chan);
2308
2309 mod_timer(&sc->calib_tim, round_jiffies(jiffies +
2310 msecs_to_jiffies(ath5k_calinterval * 1000)));
2311}
2312
2313
2314
2315/***************\
2316* LED functions *
2317\***************/
2318
2319static void
2320ath5k_led_off(unsigned long data)
2321{
2322 struct ath5k_softc *sc = (void *)data;
2323
2324 if (test_bit(ATH_STAT_LEDENDBLINK, sc->status))
2325 __clear_bit(ATH_STAT_LEDBLINKING, sc->status);
2326 else {
2327 __set_bit(ATH_STAT_LEDENDBLINK, sc->status);
2328 ath5k_hw_set_gpio(sc->ah, sc->led_pin, !sc->led_on);
2329 mod_timer(&sc->led_tim, jiffies + sc->led_off);
2330 }
2331}
2332
2333/*
2334 * Blink the LED according to the specified on/off times.
2335 */
2336static void
2337ath5k_led_blink(struct ath5k_softc *sc, unsigned int on,
2338 unsigned int off)
2339{
2340 ATH5K_DBG(sc, ATH5K_DEBUG_LED, "on %u off %u\n", on, off);
2341 ath5k_hw_set_gpio(sc->ah, sc->led_pin, sc->led_on);
2342 __set_bit(ATH_STAT_LEDBLINKING, sc->status);
2343 __clear_bit(ATH_STAT_LEDENDBLINK, sc->status);
2344 sc->led_off = off;
2345 mod_timer(&sc->led_tim, jiffies + on);
2346}
2347
2348static void
2349ath5k_led_event(struct ath5k_softc *sc, int event)
2350{
2351 if (likely(!test_bit(ATH_STAT_LEDSOFT, sc->status)))
2352 return;
2353 if (unlikely(test_bit(ATH_STAT_LEDBLINKING, sc->status)))
2354 return; /* don't interrupt active blink */
2355 switch (event) {
2356 case ATH_LED_TX:
2357 ath5k_led_blink(sc, sc->hwmap[sc->led_txrate].ledon,
2358 sc->hwmap[sc->led_txrate].ledoff);
2359 break;
2360 case ATH_LED_RX:
2361 ath5k_led_blink(sc, sc->hwmap[sc->led_rxrate].ledon,
2362 sc->hwmap[sc->led_rxrate].ledoff);
2363 break;
2364 }
2365}
2366
2367
2368
2369
2370/********************\
2371* Mac80211 functions *
2372\********************/
2373
2374static int
2375ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb,
2376 struct ieee80211_tx_control *ctl)
2377{
2378 struct ath5k_softc *sc = hw->priv;
2379 struct ath5k_buf *bf;
2380 unsigned long flags;
2381 int hdrlen;
2382 int pad;
2383
2384 ath5k_debug_dump_skb(sc, skb, "TX ", 1);
2385
2386 if (sc->opmode == IEEE80211_IF_TYPE_MNTR)
2387 ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n");
2388
2389 /*
2390 * the hardware expects the header padded to 4 byte boundaries
2391 * if this is not the case we add the padding after the header
2392 */
2393 hdrlen = ieee80211_get_hdrlen_from_skb(skb);
2394 if (hdrlen & 3) {
2395 pad = hdrlen % 4;
2396 if (skb_headroom(skb) < pad) {
2397 ATH5K_ERR(sc, "tx hdrlen not %%4: %d not enough"
2398 " headroom to pad %d\n", hdrlen, pad);
2399 return -1;
2400 }
2401 skb_push(skb, pad);
2402 memmove(skb->data, skb->data+pad, hdrlen);
2403 }
2404
2405 sc->led_txrate = ctl->tx_rate;
2406
2407 spin_lock_irqsave(&sc->txbuflock, flags);
2408 if (list_empty(&sc->txbuf)) {
2409 ATH5K_ERR(sc, "no further txbuf available, dropping packet\n");
2410 spin_unlock_irqrestore(&sc->txbuflock, flags);
2411 ieee80211_stop_queue(hw, ctl->queue);
2412 return -1;
2413 }
2414 bf = list_first_entry(&sc->txbuf, struct ath5k_buf, list);
2415 list_del(&bf->list);
2416 sc->txbuf_len--;
2417 if (list_empty(&sc->txbuf))
2418 ieee80211_stop_queues(hw);
2419 spin_unlock_irqrestore(&sc->txbuflock, flags);
2420
2421 bf->skb = skb;
2422
2423 if (ath5k_txbuf_setup(sc, bf, ctl)) {
2424 bf->skb = NULL;
2425 spin_lock_irqsave(&sc->txbuflock, flags);
2426 list_add_tail(&bf->list, &sc->txbuf);
2427 sc->txbuf_len++;
2428 spin_unlock_irqrestore(&sc->txbuflock, flags);
2429 dev_kfree_skb_any(skb);
2430 return 0;
2431 }
2432
2433 return 0;
2434}
2435
2436static int
2437ath5k_reset(struct ieee80211_hw *hw)
2438{
2439 struct ath5k_softc *sc = hw->priv;
2440 struct ath5k_hw *ah = sc->ah;
2441 int ret;
2442
2443 ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n");
2444 /*
2445 * Convert to a hw channel description with the flags
2446 * constrained to reflect the current operating mode.
2447 */
2448 sc->curchan = hw->conf.chan;
2449
2450 ath5k_hw_set_intr(ah, 0);
2451 ath5k_txq_cleanup(sc);
2452 ath5k_rx_stop(sc);
2453
2454 ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true);
2455 if (unlikely(ret)) {
2456 ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret);
2457 goto err;
2458 }
2459 ath5k_hw_set_txpower_limit(sc->ah, 0);
2460
2461 ret = ath5k_rx_start(sc);
2462 if (unlikely(ret)) {
2463 ATH5K_ERR(sc, "can't start recv logic\n");
2464 goto err;
2465 }
2466 /*
2467 * We may be doing a reset in response to an ioctl
2468 * that changes the channel so update any state that
2469 * might change as a result.
2470 *
2471 * XXX needed?
2472 */
2473/* ath5k_chan_change(sc, c); */
2474 ath5k_beacon_config(sc);
2475 /* intrs are started by ath5k_beacon_config */
2476
2477 ieee80211_wake_queues(hw);
2478
2479 return 0;
2480err:
2481 return ret;
2482}
2483
2484static int ath5k_start(struct ieee80211_hw *hw)
2485{
2486 return ath5k_init(hw->priv);
2487}
2488
2489static void ath5k_stop(struct ieee80211_hw *hw)
2490{
2491 ath5k_stop_hw(hw->priv);
2492}
2493
2494static int ath5k_add_interface(struct ieee80211_hw *hw,
2495 struct ieee80211_if_init_conf *conf)
2496{
2497 struct ath5k_softc *sc = hw->priv;
2498 int ret;
2499
2500 mutex_lock(&sc->lock);
2501 if (sc->iface_id) {
2502 ret = 0;
2503 goto end;
2504 }
2505
2506 sc->iface_id = conf->if_id;
2507
2508 switch (conf->type) {
2509 case IEEE80211_IF_TYPE_STA:
2510 case IEEE80211_IF_TYPE_IBSS:
2511 case IEEE80211_IF_TYPE_MNTR:
2512 sc->opmode = conf->type;
2513 break;
2514 default:
2515 ret = -EOPNOTSUPP;
2516 goto end;
2517 }
2518 ret = 0;
2519end:
2520 mutex_unlock(&sc->lock);
2521 return ret;
2522}
2523
2524static void
2525ath5k_remove_interface(struct ieee80211_hw *hw,
2526 struct ieee80211_if_init_conf *conf)
2527{
2528 struct ath5k_softc *sc = hw->priv;
2529
2530 mutex_lock(&sc->lock);
2531 if (sc->iface_id != conf->if_id)
2532 goto end;
2533
2534 sc->iface_id = 0;
2535end:
2536 mutex_unlock(&sc->lock);
2537}
2538
2539static int
2540ath5k_config(struct ieee80211_hw *hw,
2541 struct ieee80211_conf *conf)
2542{
2543 struct ath5k_softc *sc = hw->priv;
2544
2545 sc->bintval = conf->beacon_int * 1000 / 1024;
2546 ath5k_setcurmode(sc, conf->phymode);
2547
2548 return ath5k_chan_set(sc, conf->chan);
2549}
2550
2551static int
2552ath5k_config_interface(struct ieee80211_hw *hw, int if_id,
2553 struct ieee80211_if_conf *conf)
2554{
2555 struct ath5k_softc *sc = hw->priv;
2556 struct ath5k_hw *ah = sc->ah;
2557 int ret;
2558
2559 /* Set to a reasonable value. Note that this will
2560 * be set to mac80211's value at ath5k_config(). */
2561 sc->bintval = 1000 * 1000 / 1024;
2562 mutex_lock(&sc->lock);
2563 if (sc->iface_id != if_id) {
2564 ret = -EIO;
2565 goto unlock;
2566 }
2567 if (conf->bssid) {
2568 /* Cache for later use during resets */
2569 memcpy(ah->ah_bssid, conf->bssid, ETH_ALEN);
2570 /* XXX: assoc id is set to 0 for now, mac80211 doesn't have
2571 * a clean way of letting us retrieve this yet. */
2572 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
2573 }
2574 mutex_unlock(&sc->lock);
2575
2576 return ath5k_reset(hw);
2577unlock:
2578 mutex_unlock(&sc->lock);
2579 return ret;
2580}
2581
2582#define SUPPORTED_FIF_FLAGS \
2583 FIF_PROMISC_IN_BSS | FIF_ALLMULTI | FIF_FCSFAIL | \
2584 FIF_PLCPFAIL | FIF_CONTROL | FIF_OTHER_BSS | \
2585 FIF_BCN_PRBRESP_PROMISC
2586/*
2587 * o always accept unicast, broadcast, and multicast traffic
2588 * o multicast traffic for all BSSIDs will be enabled if mac80211
2589 * says it should be
2590 * o maintain current state of phy ofdm or phy cck error reception.
2591 * If the hardware detects any of these type of errors then
2592 * ath5k_hw_get_rx_filter() will pass to us the respective
2593 * hardware filters to be able to receive these type of frames.
2594 * o probe request frames are accepted only when operating in
2595 * hostap, adhoc, or monitor modes
2596 * o enable promiscuous mode according to the interface state
2597 * o accept beacons:
2598 * - when operating in adhoc mode so the 802.11 layer creates
2599 * node table entries for peers,
2600 * - when operating in station mode for collecting rssi data when
2601 * the station is otherwise quiet, or
2602 * - when scanning
2603 */
2604static void ath5k_configure_filter(struct ieee80211_hw *hw,
2605 unsigned int changed_flags,
2606 unsigned int *new_flags,
2607 int mc_count, struct dev_mc_list *mclist)
2608{
2609 struct ath5k_softc *sc = hw->priv;
2610 struct ath5k_hw *ah = sc->ah;
2611 u32 mfilt[2], val, rfilt;
2612 u8 pos;
2613 int i;
2614
2615 mfilt[0] = 0;
2616 mfilt[1] = 0;
2617
2618 /* Only deal with supported flags */
2619 changed_flags &= SUPPORTED_FIF_FLAGS;
2620 *new_flags &= SUPPORTED_FIF_FLAGS;
2621
2622 /* If HW detects any phy or radar errors, leave those filters on.
2623 * Also, always enable Unicast, Broadcasts and Multicast
2624 * XXX: move unicast, bssid broadcasts and multicast to mac80211 */
2625 rfilt = (ath5k_hw_get_rx_filter(ah) & (AR5K_RX_FILTER_PHYERR)) |
2626 (AR5K_RX_FILTER_UCAST | AR5K_RX_FILTER_BCAST |
2627 AR5K_RX_FILTER_MCAST);
2628
2629 if (changed_flags & (FIF_PROMISC_IN_BSS | FIF_OTHER_BSS)) {
2630 if (*new_flags & FIF_PROMISC_IN_BSS) {
2631 rfilt |= AR5K_RX_FILTER_PROM;
2632 __set_bit(ATH_STAT_PROMISC, sc->status);
2633 }
2634 else
2635 __clear_bit(ATH_STAT_PROMISC, sc->status);
2636 }
2637
2638 /* Note, AR5K_RX_FILTER_MCAST is already enabled */
2639 if (*new_flags & FIF_ALLMULTI) {
2640 mfilt[0] = ~0;
2641 mfilt[1] = ~0;
2642 } else {
2643 for (i = 0; i < mc_count; i++) {
2644 if (!mclist)
2645 break;
2646 /* calculate XOR of eight 6-bit values */
2647 val = LE_READ_4(mclist->dmi_addr + 0);
2648 pos = (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2649 val = LE_READ_4(mclist->dmi_addr + 3);
2650 pos ^= (val >> 18) ^ (val >> 12) ^ (val >> 6) ^ val;
2651 pos &= 0x3f;
2652 mfilt[pos / 32] |= (1 << (pos % 32));
2653 /* XXX: we might be able to just do this instead,
2654 * but not sure, needs testing, if we do use this we'd
2655 * neet to inform below to not reset the mcast */
2656 /* ath5k_hw_set_mcast_filterindex(ah,
2657 * mclist->dmi_addr[5]); */
2658 mclist = mclist->next;
2659 }
2660 }
2661
2662 /* This is the best we can do */
2663 if (*new_flags & (FIF_FCSFAIL | FIF_PLCPFAIL))
2664 rfilt |= AR5K_RX_FILTER_PHYERR;
2665
2666 /* FIF_BCN_PRBRESP_PROMISC really means to enable beacons
2667 * and probes for any BSSID, this needs testing */
2668 if (*new_flags & FIF_BCN_PRBRESP_PROMISC)
2669 rfilt |= AR5K_RX_FILTER_BEACON | AR5K_RX_FILTER_PROBEREQ;
2670
2671 /* FIF_CONTROL doc says that if FIF_PROMISC_IN_BSS is not
2672 * set we should only pass on control frames for this
2673 * station. This needs testing. I believe right now this
2674 * enables *all* control frames, which is OK.. but
2675 * but we should see if we can improve on granularity */
2676 if (*new_flags & FIF_CONTROL)
2677 rfilt |= AR5K_RX_FILTER_CONTROL;
2678
2679 /* Additional settings per mode -- this is per ath5k */
2680
2681 /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */
2682
2683 if (sc->opmode == IEEE80211_IF_TYPE_MNTR)
2684 rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON |
2685 AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM;
2686 if (sc->opmode != IEEE80211_IF_TYPE_STA)
2687 rfilt |= AR5K_RX_FILTER_PROBEREQ;
2688 if (sc->opmode != IEEE80211_IF_TYPE_AP &&
2689 test_bit(ATH_STAT_PROMISC, sc->status))
2690 rfilt |= AR5K_RX_FILTER_PROM;
2691 if (sc->opmode == IEEE80211_IF_TYPE_STA ||
2692 sc->opmode == IEEE80211_IF_TYPE_IBSS) {
2693 rfilt |= AR5K_RX_FILTER_BEACON;
2694 }
2695
2696 /* Set filters */
2697 ath5k_hw_set_rx_filter(ah,rfilt);
2698
2699 /* Set multicast bits */
2700 ath5k_hw_set_mcast_filter(ah, mfilt[0], mfilt[1]);
2701 /* Set the cached hw filter flags, this will alter actually
2702 * be set in HW */
2703 sc->filter_flags = rfilt;
2704}
2705
2706static int
2707ath5k_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
2708 const u8 *local_addr, const u8 *addr,
2709 struct ieee80211_key_conf *key)
2710{
2711 struct ath5k_softc *sc = hw->priv;
2712 int ret = 0;
2713
2714 switch(key->alg) {
2715 case ALG_WEP:
2716 break;
2717 case ALG_TKIP:
2718 case ALG_CCMP:
2719 return -EOPNOTSUPP;
2720 default:
2721 WARN_ON(1);
2722 return -EINVAL;
2723 }
2724
2725 mutex_lock(&sc->lock);
2726
2727 switch (cmd) {
2728 case SET_KEY:
2729 ret = ath5k_hw_set_key(sc->ah, key->keyidx, key, addr);
2730 if (ret) {
2731 ATH5K_ERR(sc, "can't set the key\n");
2732 goto unlock;
2733 }
2734 __set_bit(key->keyidx, sc->keymap);
2735 key->hw_key_idx = key->keyidx;
2736 break;
2737 case DISABLE_KEY:
2738 ath5k_hw_reset_key(sc->ah, key->keyidx);
2739 __clear_bit(key->keyidx, sc->keymap);
2740 break;
2741 default:
2742 ret = -EINVAL;
2743 goto unlock;
2744 }
2745
2746unlock:
2747 mutex_unlock(&sc->lock);
2748 return ret;
2749}
2750
2751static int
2752ath5k_get_stats(struct ieee80211_hw *hw,
2753 struct ieee80211_low_level_stats *stats)
2754{
2755 struct ath5k_softc *sc = hw->priv;
2756
2757 memcpy(stats, &sc->ll_stats, sizeof(sc->ll_stats));
2758
2759 return 0;
2760}
2761
2762static int
2763ath5k_get_tx_stats(struct ieee80211_hw *hw,
2764 struct ieee80211_tx_queue_stats *stats)
2765{
2766 struct ath5k_softc *sc = hw->priv;
2767
2768 memcpy(stats, &sc->tx_stats, sizeof(sc->tx_stats));
2769
2770 return 0;
2771}
2772
2773static u64
2774ath5k_get_tsf(struct ieee80211_hw *hw)
2775{
2776 struct ath5k_softc *sc = hw->priv;
2777
2778 return ath5k_hw_get_tsf64(sc->ah);
2779}
2780
2781static void
2782ath5k_reset_tsf(struct ieee80211_hw *hw)
2783{
2784 struct ath5k_softc *sc = hw->priv;
2785
2786 ath5k_hw_reset_tsf(sc->ah);
2787}
2788
2789static int
2790ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb,
2791 struct ieee80211_tx_control *ctl)
2792{
2793 struct ath5k_softc *sc = hw->priv;
2794 int ret;
2795
2796 ath5k_debug_dump_skb(sc, skb, "BC ", 1);
2797
2798 mutex_lock(&sc->lock);
2799
2800 if (sc->opmode != IEEE80211_IF_TYPE_IBSS) {
2801 ret = -EIO;
2802 goto end;
2803 }
2804
2805 ath5k_txbuf_free(sc, sc->bbuf);
2806 sc->bbuf->skb = skb;
2807 ret = ath5k_beacon_setup(sc, sc->bbuf, ctl);
2808 if (ret)
2809 sc->bbuf->skb = NULL;
2810 else
2811 ath5k_beacon_config(sc);
2812
2813end:
2814 mutex_unlock(&sc->lock);
2815 return ret;
2816}
2817
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h
new file mode 100644
index 000000000000..927d67db3dc2
--- /dev/null
+++ b/drivers/net/wireless/ath5k/base.h
@@ -0,0 +1,178 @@
1/*-
2 * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer,
10 * without modification.
11 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
12 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
13 * redistribution must be conditioned upon including a substantially
14 * similar Disclaimer requirement for further binary redistribution.
15 * 3. Neither the names of the above-listed copyright holders nor the names
16 * of any contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * Alternatively, this software may be distributed under the terms of the
20 * GNU General Public License ("GPL") version 2 as published by the Free
21 * Software Foundation.
22 *
23 * NO WARRANTY
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
27 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
28 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
29 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
32 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
34 * THE POSSIBILITY OF SUCH DAMAGES.
35 *
36 */
37
38/*
39 * Defintions for the Atheros Wireless LAN controller driver.
40 */
41#ifndef _DEV_ATH_ATHVAR_H
42#define _DEV_ATH_ATHVAR_H
43
44#include <linux/interrupt.h>
45#include <linux/list.h>
46#include <linux/wireless.h>
47#include <linux/if_ether.h>
48
49#include "ath5k.h"
50#include "debug.h"
51
52#define ATH_RXBUF 40 /* number of RX buffers */
53#define ATH_TXBUF 200 /* number of TX buffers */
54#define ATH_BCBUF 1 /* number of beacon buffers */
55
56struct ath5k_buf {
57 struct list_head list;
58 unsigned int flags; /* tx descriptor flags */
59 struct ath5k_desc *desc; /* virtual addr of desc */
60 dma_addr_t daddr; /* physical addr of desc */
61 struct sk_buff *skb; /* skbuff for buf */
62 dma_addr_t skbaddr;/* physical addr of skb data */
63 struct ieee80211_tx_control ctl;
64};
65
66/*
67 * Data transmit queue state. One of these exists for each
68 * hardware transmit queue. Packets sent to us from above
69 * are assigned to queues based on their priority. Not all
70 * devices support a complete set of hardware transmit queues.
71 * For those devices the array sc_ac2q will map multiple
72 * priorities to fewer hardware queues (typically all to one
73 * hardware queue).
74 */
75struct ath5k_txq {
76 unsigned int qnum; /* hardware q number */
77 u32 *link; /* link ptr in last TX desc */
78 struct list_head q; /* transmit queue */
79 spinlock_t lock; /* lock on q and link */
80 bool setup;
81};
82
83#if CHAN_DEBUG
84#define ATH_CHAN_MAX (26+26+26+200+200)
85#else
86#define ATH_CHAN_MAX (14+14+14+252+20) /* XXX what's the max? */
87#endif
88
89/* Software Carrier, keeps track of the driver state
90 * associated with an instance of a device */
91struct ath5k_softc {
92 struct pci_dev *pdev; /* for dma mapping */
93 void __iomem *iobase; /* address of the device */
94 struct mutex lock; /* dev-level lock */
95 struct ieee80211_tx_queue_stats tx_stats;
96 struct ieee80211_low_level_stats ll_stats;
97 struct ieee80211_hw *hw; /* IEEE 802.11 common */
98 struct ieee80211_hw_mode modes[NUM_DRIVER_MODES];
99 struct ieee80211_channel channels[ATH_CHAN_MAX];
100 struct ieee80211_rate rates[AR5K_MAX_RATES * NUM_DRIVER_MODES];
101 enum ieee80211_if_types opmode;
102 struct ath5k_hw *ah; /* Atheros HW */
103
104#if ATH5K_DEBUG
105 struct ath5k_dbg_info debug; /* debug info */
106#endif
107
108 struct ath5k_buf *bufptr; /* allocated buffer ptr */
109 struct ath5k_desc *desc; /* TX/RX descriptors */
110 dma_addr_t desc_daddr; /* DMA (physical) address */
111 size_t desc_len; /* size of TX/RX descriptors */
112 u16 cachelsz; /* cache line size */
113
114 DECLARE_BITMAP(status, 6);
115#define ATH_STAT_INVALID 0 /* disable hardware accesses */
116#define ATH_STAT_MRRETRY 1 /* multi-rate retry support */
117#define ATH_STAT_PROMISC 2
118#define ATH_STAT_LEDBLINKING 3 /* LED blink operation active */
119#define ATH_STAT_LEDENDBLINK 4 /* finish LED blink operation */
120#define ATH_STAT_LEDSOFT 5 /* enable LED gpio status */
121
122 unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
123 unsigned int curmode; /* current phy mode */
124 struct ieee80211_channel *curchan; /* current h/w channel */
125
126 int iface_id; /* add/remove_interface id */
127
128 struct {
129 u8 rxflags; /* radiotap rx flags */
130 u8 txflags; /* radiotap tx flags */
131 u16 ledon; /* softled on time */
132 u16 ledoff; /* softled off time */
133 } hwmap[32]; /* h/w rate ix mappings */
134
135 enum ath5k_int imask; /* interrupt mask copy */
136
137 DECLARE_BITMAP(keymap, AR5K_KEYCACHE_SIZE); /* key use bit map */
138
139 u8 bssidmask[ETH_ALEN];
140
141 unsigned int led_pin, /* GPIO pin for driving LED */
142 led_on, /* pin setting for LED on */
143 led_off; /* off time for current blink */
144 struct timer_list led_tim; /* led off timer */
145 u8 led_rxrate; /* current rx rate for LED */
146 u8 led_txrate; /* current tx rate for LED */
147
148 struct tasklet_struct restq; /* reset tasklet */
149
150 unsigned int rxbufsize; /* rx size based on mtu */
151 struct list_head rxbuf; /* receive buffer */
152 spinlock_t rxbuflock;
153 u32 *rxlink; /* link ptr in last RX desc */
154 struct tasklet_struct rxtq; /* rx intr tasklet */
155
156 struct list_head txbuf; /* transmit buffer */
157 spinlock_t txbuflock;
158 unsigned int txbuf_len; /* buf count in txbuf list */
159 struct ath5k_txq txqs[2]; /* beacon and tx */
160
161 struct ath5k_txq *txq; /* beacon and tx*/
162 struct tasklet_struct txtq; /* tx intr tasklet */
163
164 struct ath5k_buf *bbuf; /* beacon buffer */
165 unsigned int bhalq, /* SW q for outgoing beacons */
166 bmisscount, /* missed beacon transmits */
167 bintval, /* beacon interval */
168 bsent;
169
170 struct timer_list calib_tim; /* calibration timer */
171};
172
173#define ath5k_hw_hasbssidmask(_ah) \
174 (ath5k_hw_get_capability(_ah, AR5K_CAP_BSSIDMASK, 0, NULL) == 0)
175#define ath5k_hw_hasveol(_ah) \
176 (ath5k_hw_get_capability(_ah, AR5K_CAP_VEOL, 0, NULL) == 0)
177
178#endif
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c
new file mode 100644
index 000000000000..4ba649e20269
--- /dev/null
+++ b/drivers/net/wireless/ath5k/debug.c
@@ -0,0 +1,469 @@
1/*
2 * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com>
3 *
4 * This file is free software: you may copy, redistribute and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation, either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 *
18 * This file incorporates work covered by the following copyright and
19 * permission notice:
20 *
21 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
22 * Copyright (c) 2004-2005 Atheros Communications, Inc.
23 * Copyright (c) 2006 Devicescape Software, Inc.
24 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
25 * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
26 *
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer,
34 * without modification.
35 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
36 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
37 * redistribution must be conditioned upon including a substantially
38 * similar Disclaimer requirement for further binary redistribution.
39 * 3. Neither the names of the above-listed copyright holders nor the names
40 * of any contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * Alternatively, this software may be distributed under the terms of the
44 * GNU General Public License ("GPL") version 2 as published by the Free
45 * Software Foundation.
46 *
47 * NO WARRANTY
48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
51 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
52 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
53 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
56 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
58 * THE POSSIBILITY OF SUCH DAMAGES.
59 */
60
61#include "debug.h"
62#include "base.h"
63
64static unsigned int ath5k_debug;
65module_param_named(debug, ath5k_debug, uint, 0);
66
67
68#if ATH5K_DEBUG
69
70#include <linux/seq_file.h>
71#include "reg.h"
72
73static struct dentry *ath5k_global_debugfs;
74
75static int ath5k_debugfs_open(struct inode *inode, struct file *file)
76{
77 file->private_data = inode->i_private;
78 return 0;
79}
80
81
82/* debugfs: registers */
83
84struct reg {
85 char *name;
86 int addr;
87};
88
89#define REG_STRUCT_INIT(r) { #r, r }
90
91/* just a few random registers, might want to add more */
92static struct reg regs[] = {
93 REG_STRUCT_INIT(AR5K_CR),
94 REG_STRUCT_INIT(AR5K_RXDP),
95 REG_STRUCT_INIT(AR5K_CFG),
96 REG_STRUCT_INIT(AR5K_IER),
97 REG_STRUCT_INIT(AR5K_BCR),
98 REG_STRUCT_INIT(AR5K_RTSD0),
99 REG_STRUCT_INIT(AR5K_RTSD1),
100 REG_STRUCT_INIT(AR5K_TXCFG),
101 REG_STRUCT_INIT(AR5K_RXCFG),
102 REG_STRUCT_INIT(AR5K_RXJLA),
103 REG_STRUCT_INIT(AR5K_MIBC),
104 REG_STRUCT_INIT(AR5K_TOPS),
105 REG_STRUCT_INIT(AR5K_RXNOFRM),
106 REG_STRUCT_INIT(AR5K_TXNOFRM),
107 REG_STRUCT_INIT(AR5K_RPGTO),
108 REG_STRUCT_INIT(AR5K_RFCNT),
109 REG_STRUCT_INIT(AR5K_MISC),
110 REG_STRUCT_INIT(AR5K_QCUDCU_CLKGT),
111 REG_STRUCT_INIT(AR5K_ISR),
112 REG_STRUCT_INIT(AR5K_PISR),
113 REG_STRUCT_INIT(AR5K_SISR0),
114 REG_STRUCT_INIT(AR5K_SISR1),
115 REG_STRUCT_INIT(AR5K_SISR2),
116 REG_STRUCT_INIT(AR5K_SISR3),
117 REG_STRUCT_INIT(AR5K_SISR4),
118 REG_STRUCT_INIT(AR5K_IMR),
119 REG_STRUCT_INIT(AR5K_PIMR),
120 REG_STRUCT_INIT(AR5K_SIMR0),
121 REG_STRUCT_INIT(AR5K_SIMR1),
122 REG_STRUCT_INIT(AR5K_SIMR2),
123 REG_STRUCT_INIT(AR5K_SIMR3),
124 REG_STRUCT_INIT(AR5K_SIMR4),
125 REG_STRUCT_INIT(AR5K_DCM_ADDR),
126 REG_STRUCT_INIT(AR5K_DCCFG),
127 REG_STRUCT_INIT(AR5K_CCFG),
128 REG_STRUCT_INIT(AR5K_CPC0),
129 REG_STRUCT_INIT(AR5K_CPC1),
130 REG_STRUCT_INIT(AR5K_CPC2),
131 REG_STRUCT_INIT(AR5K_CPC3),
132 REG_STRUCT_INIT(AR5K_CPCORN),
133 REG_STRUCT_INIT(AR5K_RESET_CTL),
134 REG_STRUCT_INIT(AR5K_SLEEP_CTL),
135 REG_STRUCT_INIT(AR5K_INTPEND),
136 REG_STRUCT_INIT(AR5K_SFR),
137 REG_STRUCT_INIT(AR5K_PCICFG),
138 REG_STRUCT_INIT(AR5K_GPIOCR),
139 REG_STRUCT_INIT(AR5K_GPIODO),
140 REG_STRUCT_INIT(AR5K_SREV),
141};
142
143static void *reg_start(struct seq_file *seq, loff_t *pos)
144{
145 return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
146}
147
148static void reg_stop(struct seq_file *seq, void *p)
149{
150 /* nothing to do */
151}
152
153static void *reg_next(struct seq_file *seq, void *p, loff_t *pos)
154{
155 ++*pos;
156 return *pos < ARRAY_SIZE(regs) ? &regs[*pos] : NULL;
157}
158
159static int reg_show(struct seq_file *seq, void *p)
160{
161 struct ath5k_softc *sc = seq->private;
162 struct reg *r = p;
163 seq_printf(seq, "%-25s0x%08x\n", r->name,
164 ath5k_hw_reg_read(sc->ah, r->addr));
165 return 0;
166}
167
168static struct seq_operations register_seq_ops = {
169 .start = reg_start,
170 .next = reg_next,
171 .stop = reg_stop,
172 .show = reg_show
173};
174
175static int open_file_registers(struct inode *inode, struct file *file)
176{
177 struct seq_file *s;
178 int res;
179 res = seq_open(file, &register_seq_ops);
180 if (res == 0) {
181 s = file->private_data;
182 s->private = inode->i_private;
183 }
184 return res;
185}
186
187static const struct file_operations fops_registers = {
188 .open = open_file_registers,
189 .read = seq_read,
190 .llseek = seq_lseek,
191 .release = seq_release,
192 .owner = THIS_MODULE,
193};
194
195
196/* debugfs: TSF */
197
198static ssize_t read_file_tsf(struct file *file, char __user *user_buf,
199 size_t count, loff_t *ppos)
200{
201 struct ath5k_softc *sc = file->private_data;
202 char buf[100];
203 snprintf(buf, 100, "0x%016llx\n", ath5k_hw_get_tsf64(sc->ah));
204 return simple_read_from_buffer(user_buf, count, ppos, buf, 19);
205}
206
207static ssize_t write_file_tsf(struct file *file,
208 const char __user *userbuf,
209 size_t count, loff_t *ppos)
210{
211 struct ath5k_softc *sc = file->private_data;
212 if (strncmp(userbuf, "reset", 5) == 0) {
213 ath5k_hw_reset_tsf(sc->ah);
214 printk(KERN_INFO "debugfs reset TSF\n");
215 }
216 return count;
217}
218
219static const struct file_operations fops_tsf = {
220 .read = read_file_tsf,
221 .write = write_file_tsf,
222 .open = ath5k_debugfs_open,
223 .owner = THIS_MODULE,
224};
225
226
227/* debugfs: beacons */
228
229static ssize_t read_file_beacon(struct file *file, char __user *user_buf,
230 size_t count, loff_t *ppos)
231{
232 struct ath5k_softc *sc = file->private_data;
233 struct ath5k_hw *ah = sc->ah;
234 char buf[1000];
235 int len = 0;
236 unsigned int v;
237 u64 tsf;
238
239 v = ath5k_hw_reg_read(sc->ah, AR5K_BEACON);
240 len += snprintf(buf+len, sizeof(buf)-len,
241 "%-24s0x%08x\tintval: %d\tTIM: 0x%x\n",
242 "AR5K_BEACON", v, v & AR5K_BEACON_PERIOD,
243 (v & AR5K_BEACON_TIM) >> AR5K_BEACON_TIM_S);
244
245 len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n",
246 "AR5K_LAST_TSTP", ath5k_hw_reg_read(sc->ah, AR5K_LAST_TSTP));
247
248 len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\n\n",
249 "AR5K_BEACON_CNT", ath5k_hw_reg_read(sc->ah, AR5K_BEACON_CNT));
250
251 v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER0);
252 len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
253 "AR5K_TIMER0 (TBTT)", v, v);
254
255 v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER1);
256 len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
257 "AR5K_TIMER1 (DMA)", v, v >> 3);
258
259 v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER2);
260 len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
261 "AR5K_TIMER2 (SWBA)", v, v >> 3);
262
263 v = ath5k_hw_reg_read(sc->ah, AR5K_TIMER3);
264 len += snprintf(buf+len, sizeof(buf)-len, "%-24s0x%08x\tTU: %08x\n",
265 "AR5K_TIMER3 (ATIM)", v, v);
266
267 tsf = ath5k_hw_get_tsf64(sc->ah);
268 len += snprintf(buf+len, sizeof(buf)-len,
269 "TSF\t\t0x%016llx\tTU: %08x\n", tsf, TSF_TO_TU(tsf));
270
271 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
272}
273
274static ssize_t write_file_beacon(struct file *file,
275 const char __user *userbuf,
276 size_t count, loff_t *ppos)
277{
278 struct ath5k_softc *sc = file->private_data;
279 struct ath5k_hw *ah = sc->ah;
280
281 if (strncmp(userbuf, "disable", 7) == 0) {
282 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
283 printk(KERN_INFO "debugfs disable beacons\n");
284 } else if (strncmp(userbuf, "enable", 6) == 0) {
285 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE);
286 printk(KERN_INFO "debugfs enable beacons\n");
287 }
288 return count;
289}
290
291static const struct file_operations fops_beacon = {
292 .read = read_file_beacon,
293 .write = write_file_beacon,
294 .open = ath5k_debugfs_open,
295 .owner = THIS_MODULE,
296};
297
298
299/* debugfs: reset */
300
301static ssize_t write_file_reset(struct file *file,
302 const char __user *userbuf,
303 size_t count, loff_t *ppos)
304{
305 struct ath5k_softc *sc = file->private_data;
306 tasklet_schedule(&sc->restq);
307 return count;
308}
309
310static const struct file_operations fops_reset = {
311 .write = write_file_reset,
312 .open = ath5k_debugfs_open,
313 .owner = THIS_MODULE,
314};
315
316
317/* init */
318
319void
320ath5k_debug_init(void)
321{
322 ath5k_global_debugfs = debugfs_create_dir("ath5k", NULL);
323}
324
325void
326ath5k_debug_init_device(struct ath5k_softc *sc)
327{
328 sc->debug.level = ath5k_debug;
329 sc->debug.debugfs_phydir = debugfs_create_dir(wiphy_name(sc->hw->wiphy),
330 ath5k_global_debugfs);
331 sc->debug.debugfs_debug = debugfs_create_u32("debug",
332 0666, sc->debug.debugfs_phydir, &sc->debug.level);
333
334 sc->debug.debugfs_registers = debugfs_create_file("registers", 0444,
335 sc->debug.debugfs_phydir,
336 sc, &fops_registers);
337
338 sc->debug.debugfs_tsf = debugfs_create_file("tsf", 0666,
339 sc->debug.debugfs_phydir,
340 sc, &fops_tsf);
341
342 sc->debug.debugfs_beacon = debugfs_create_file("beacon", 0666,
343 sc->debug.debugfs_phydir,
344 sc, &fops_beacon);
345
346 sc->debug.debugfs_reset = debugfs_create_file("reset", 0222,
347 sc->debug.debugfs_phydir,
348 sc, &fops_reset);
349}
350
351void
352ath5k_debug_finish(void)
353{
354 debugfs_remove(ath5k_global_debugfs);
355}
356
357void
358ath5k_debug_finish_device(struct ath5k_softc *sc)
359{
360 debugfs_remove(sc->debug.debugfs_debug);
361 debugfs_remove(sc->debug.debugfs_registers);
362 debugfs_remove(sc->debug.debugfs_tsf);
363 debugfs_remove(sc->debug.debugfs_beacon);
364 debugfs_remove(sc->debug.debugfs_reset);
365 debugfs_remove(sc->debug.debugfs_phydir);
366}
367
368
369/* functions used in other places */
370
371void
372ath5k_debug_dump_modes(struct ath5k_softc *sc, struct ieee80211_hw_mode *modes)
373{
374 unsigned int m, i;
375
376 if (likely(!(sc->debug.level & ATH5K_DEBUG_DUMPMODES)))
377 return;
378
379 for (m = 0; m < NUM_DRIVER_MODES; m++) {
380 printk(KERN_DEBUG "Mode %u: channels %d, rates %d\n", m,
381 modes[m].num_channels, modes[m].num_rates);
382 printk(KERN_DEBUG " channels:\n");
383 for (i = 0; i < modes[m].num_channels; i++)
384 printk(KERN_DEBUG " %3d %d %.4x %.4x\n",
385 modes[m].channels[i].chan,
386 modes[m].channels[i].freq,
387 modes[m].channels[i].val,
388 modes[m].channels[i].flag);
389 printk(KERN_DEBUG " rates:\n");
390 for (i = 0; i < modes[m].num_rates; i++)
391 printk(KERN_DEBUG " %4d %.4x %.4x %.4x\n",
392 modes[m].rates[i].rate,
393 modes[m].rates[i].val,
394 modes[m].rates[i].flags,
395 modes[m].rates[i].val2);
396 }
397}
398
399static inline void
400ath5k_debug_printrxbuf(struct ath5k_buf *bf, int done)
401{
402 struct ath5k_desc *ds = bf->desc;
403
404 printk(KERN_DEBUG "R (%p %llx) %08x %08x %08x %08x %08x %08x %c\n",
405 ds, (unsigned long long)bf->daddr,
406 ds->ds_link, ds->ds_data, ds->ds_ctl0, ds->ds_ctl1,
407 ds->ds_hw[0], ds->ds_hw[1],
408 !done ? ' ' : (ds->ds_rxstat.rs_status == 0) ? '*' : '!');
409}
410
411void
412ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah)
413{
414 struct ath5k_desc *ds;
415 struct ath5k_buf *bf;
416 int status;
417
418 if (likely(!(sc->debug.level &
419 (ATH5K_DEBUG_RESET | ATH5K_DEBUG_FATAL))))
420 return;
421
422 printk(KERN_DEBUG "rx queue %x, link %p\n",
423 ath5k_hw_get_rx_buf(ah), sc->rxlink);
424
425 spin_lock_bh(&sc->rxbuflock);
426 list_for_each_entry(bf, &sc->rxbuf, list) {
427 ds = bf->desc;
428 status = ah->ah_proc_rx_desc(ah, ds);
429 if (!status || (sc->debug.level & ATH5K_DEBUG_FATAL))
430 ath5k_debug_printrxbuf(bf, status == 0);
431 }
432 spin_unlock_bh(&sc->rxbuflock);
433}
434
435void
436ath5k_debug_dump_skb(struct ath5k_softc *sc,
437 struct sk_buff *skb, const char *prefix, int tx)
438{
439 char buf[16];
440
441 if (likely(!((tx && (sc->debug.level & ATH5K_DEBUG_DUMP_TX)) ||
442 (!tx && (sc->debug.level & ATH5K_DEBUG_DUMP_RX)))))
443 return;
444
445 snprintf(buf, sizeof(buf), "%s %s", wiphy_name(sc->hw->wiphy), prefix);
446
447 print_hex_dump_bytes(buf, DUMP_PREFIX_NONE, skb->data,
448 min(200U, skb->len));
449
450 printk(KERN_DEBUG "\n");
451}
452
453void
454ath5k_debug_printtxbuf(struct ath5k_softc *sc,
455 struct ath5k_buf *bf, int done)
456{
457 struct ath5k_desc *ds = bf->desc;
458
459 if (likely(!(sc->debug.level & ATH5K_DEBUG_RESET)))
460 return;
461
462 printk(KERN_DEBUG "T (%p %llx) %08x %08x %08x %08x %08x %08x %08x "
463 "%08x %c\n", ds, (unsigned long long)bf->daddr, ds->ds_link,
464 ds->ds_data, ds->ds_ctl0, ds->ds_ctl1,
465 ds->ds_hw[0], ds->ds_hw[1], ds->ds_hw[2], ds->ds_hw[3],
466 !done ? ' ' : (ds->ds_txstat.ts_status == 0) ? '*' : '!');
467}
468
469#endif /* if ATH5K_DEBUG */
diff --git a/drivers/net/wireless/ath5k/debug.h b/drivers/net/wireless/ath5k/debug.h
new file mode 100644
index 000000000000..2b491cbc8c80
--- /dev/null
+++ b/drivers/net/wireless/ath5k/debug.h
@@ -0,0 +1,216 @@
1/*
2 * Copyright (c) 2007 Bruno Randolf <bruno@thinktube.com>
3 *
4 * This file is free software: you may copy, redistribute and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation, either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This file is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 *
18 * This file incorporates work covered by the following copyright and
19 * permission notice:
20 *
21 * Copyright (c) 2002-2005 Sam Leffler, Errno Consulting
22 * Copyright (c) 2004-2005 Atheros Communications, Inc.
23 * Copyright (c) 2006 Devicescape Software, Inc.
24 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
25 * Copyright (c) 2007 Luis R. Rodriguez <mcgrof@winlab.rutgers.edu>
26 *
27 * All rights reserved.
28 *
29 * Redistribution and use in source and binary forms, with or without
30 * modification, are permitted provided that the following conditions
31 * are met:
32 * 1. Redistributions of source code must retain the above copyright
33 * notice, this list of conditions and the following disclaimer,
34 * without modification.
35 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
36 * similar to the "NO WARRANTY" disclaimer below ("Disclaimer") and any
37 * redistribution must be conditioned upon including a substantially
38 * similar Disclaimer requirement for further binary redistribution.
39 * 3. Neither the names of the above-listed copyright holders nor the names
40 * of any contributors may be used to endorse or promote products derived
41 * from this software without specific prior written permission.
42 *
43 * Alternatively, this software may be distributed under the terms of the
44 * GNU General Public License ("GPL") version 2 as published by the Free
45 * Software Foundation.
46 *
47 * NO WARRANTY
48 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
49 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
50 * LIMITED TO, THE IMPLIED WARRANTIES OF NONINFRINGEMENT, MERCHANTIBILITY
51 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
52 * THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY,
53 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
54 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
55 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
56 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
57 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
58 * THE POSSIBILITY OF SUCH DAMAGES.
59 */
60
61#ifndef _ATH5K_DEBUG_H
62#define _ATH5K_DEBUG_H
63
64/* set this to 1 for debugging output */
65#ifndef ATH5K_DEBUG
66#define ATH5K_DEBUG 0
67#endif
68
69struct ath5k_softc;
70struct ath5k_hw;
71struct ieee80211_hw_mode;
72struct sk_buff;
73struct ath5k_buf;
74
75struct ath5k_dbg_info {
76 unsigned int level; /* debug level */
77 /* debugfs entries */
78 struct dentry *debugfs_phydir;
79 struct dentry *debugfs_debug;
80 struct dentry *debugfs_registers;
81 struct dentry *debugfs_tsf;
82 struct dentry *debugfs_beacon;
83 struct dentry *debugfs_reset;
84};
85
86/**
87 * enum ath5k_debug_level - ath5k debug level
88 *
89 * @ATH5K_DEBUG_RESET: reset processing
90 * @ATH5K_DEBUG_INTR: interrupt handling
91 * @ATH5K_DEBUG_MODE: mode init/setup
92 * @ATH5K_DEBUG_XMIT: basic xmit operation
93 * @ATH5K_DEBUG_BEACON: beacon handling
94 * @ATH5K_DEBUG_BEACON_PROC: beacon ISR proc
95 * @ATH5K_DEBUG_CALIBRATE: periodic calibration
96 * @ATH5K_DEBUG_TXPOWER: transmit power setting
97 * @ATH5K_DEBUG_LED: led management
98 * @ATH5K_DEBUG_DUMP_RX: print received skb content
99 * @ATH5K_DEBUG_DUMP_TX: print transmit skb content
100 * @ATH5K_DEBUG_DUMPMODES: dump modes
101 * @ATH5K_DEBUG_TRACE: trace function calls
102 * @ATH5K_DEBUG_FATAL: fatal errors
103 * @ATH5K_DEBUG_ANY: show at any debug level
104 *
105 * The debug level is used to control the amount and type of debugging output
106 * we want to see. The debug level is given in calls to ATH5K_DBG to specify
107 * where the message should appear, and the user can control the debugging
108 * messages he wants to see, either by the module parameter 'debug' on module
109 * load, or dynamically by using debugfs 'ath5k/phyX/debug'. these levels can
110 * be combined together by bitwise OR.
111 */
112enum ath5k_debug_level {
113 ATH5K_DEBUG_RESET = 0x00000001,
114 ATH5K_DEBUG_INTR = 0x00000002,
115 ATH5K_DEBUG_MODE = 0x00000004,
116 ATH5K_DEBUG_XMIT = 0x00000008,
117 ATH5K_DEBUG_BEACON = 0x00000010,
118 ATH5K_DEBUG_BEACON_PROC = 0x00000020,
119 ATH5K_DEBUG_CALIBRATE = 0x00000100,
120 ATH5K_DEBUG_TXPOWER = 0x00000200,
121 ATH5K_DEBUG_LED = 0x00000400,
122 ATH5K_DEBUG_DUMP_RX = 0x00001000,
123 ATH5K_DEBUG_DUMP_TX = 0x00002000,
124 ATH5K_DEBUG_DUMPMODES = 0x00004000,
125 ATH5K_DEBUG_TRACE = 0x00010000,
126 ATH5K_DEBUG_FATAL = 0x80000000,
127 ATH5K_DEBUG_ANY = 0xffffffff
128};
129
130#if ATH5K_DEBUG
131
132#define ATH5K_TRACE(_sc) do { \
133 if (unlikely((_sc)->debug.level & ATH5K_DEBUG_TRACE)) \
134 printk(KERN_DEBUG "ath5k trace %s:%d\n", __func__, __LINE__); \
135 } while (0)
136
137#define ATH5K_DBG(_sc, _m, _fmt, ...) do { \
138 if (unlikely((_sc)->debug.level & (_m) && net_ratelimit())) \
139 ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
140 __func__, __LINE__, ##__VA_ARGS__); \
141 } while (0)
142
143#define ATH5K_DBG_UNLIMIT(_sc, _m, _fmt, ...) do { \
144 if (unlikely((_sc)->debug.level & (_m))) \
145 ATH5K_PRINTK(_sc, KERN_DEBUG, "(%s:%d): " _fmt, \
146 __func__, __LINE__, ##__VA_ARGS__); \
147 } while (0)
148
149void
150ath5k_debug_init(void);
151
152void
153ath5k_debug_init_device(struct ath5k_softc *sc);
154
155void
156ath5k_debug_finish(void);
157
158void
159ath5k_debug_finish_device(struct ath5k_softc *sc);
160
161void
162ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah);
163
164void
165ath5k_debug_dump_modes(struct ath5k_softc *sc,
166 struct ieee80211_hw_mode *modes);
167
168void
169ath5k_debug_dump_skb(struct ath5k_softc *sc,
170 struct sk_buff *skb, const char *prefix, int tx);
171
172void
173ath5k_debug_printtxbuf(struct ath5k_softc *sc,
174 struct ath5k_buf *bf, int done);
175
176#else /* no debugging */
177
178#define ATH5K_TRACE(_sc) /* empty */
179
180static inline void __attribute__ ((format (printf, 3, 4)))
181ATH5K_DBG(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...) {}
182
183static inline void __attribute__ ((format (printf, 3, 4)))
184ATH5K_DBG_UNLIMIT(struct ath5k_softc *sc, unsigned int m, const char *fmt, ...)
185{}
186
187static inline void
188ath5k_debug_init(void) {}
189
190static inline void
191ath5k_debug_init_device(struct ath5k_softc *sc) {}
192
193static inline void
194ath5k_debug_finish(void) {}
195
196static inline void
197ath5k_debug_finish_device(struct ath5k_softc *sc) {}
198
199static inline void
200ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) {}
201
202static inline void
203ath5k_debug_dump_modes(struct ath5k_softc *sc,
204 struct ieee80211_hw_mode *modes) {}
205
206static inline void
207ath5k_debug_dump_skb(struct ath5k_softc *sc,
208 struct sk_buff *skb, const char *prefix, int tx) {}
209
210static inline void
211ath5k_debug_printtxbuf(struct ath5k_softc *sc,
212 struct ath5k_buf *bf, int done) {}
213
214#endif /* if ATH5K_DEBUG */
215
216#endif /* ifndef _ATH5K_DEBUG_H */
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c
new file mode 100644
index 000000000000..5623d7dc738e
--- /dev/null
+++ b/drivers/net/wireless/ath5k/hw.c
@@ -0,0 +1,4349 @@
1 /*
2 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org>
5 * Copyright (c) 2007 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
6 * Copyright (c) 2007 Pavel Roskin <proski@gnu.org>
7 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
8 *
9 * Permission to use, copy, modify, and distribute this software for any
10 * purpose with or without fee is hereby granted, provided that the above
11 * copyright notice and this permission notice appear in all copies.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
14 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
16 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
18 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
19 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 *
21 */
22
23/*
24 * HW related functions for Atheros Wireless LAN devices.
25 */
26
27#include <linux/pci.h>
28#include <linux/delay.h>
29
30#include "reg.h"
31#include "base.h"
32#include "debug.h"
33
34/*Rate tables*/
35static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A;
36static const struct ath5k_rate_table ath5k_rt_11b = AR5K_RATES_11B;
37static const struct ath5k_rate_table ath5k_rt_11g = AR5K_RATES_11G;
38static const struct ath5k_rate_table ath5k_rt_turbo = AR5K_RATES_TURBO;
39static const struct ath5k_rate_table ath5k_rt_xr = AR5K_RATES_XR;
40
41/*Prototypes*/
42static int ath5k_hw_nic_reset(struct ath5k_hw *, u32);
43static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool);
44static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
45 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
46 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
47 unsigned int, unsigned int);
48static bool ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
49 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
50 unsigned int);
51static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *);
52static int ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *, struct ath5k_desc *,
53 unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int,
54 unsigned int, unsigned int, unsigned int, unsigned int, unsigned int,
55 unsigned int, unsigned int);
56static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *);
57static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *, struct ath5k_desc *);
58static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *, struct ath5k_desc *);
59static int ath5k_hw_get_capabilities(struct ath5k_hw *);
60
61static int ath5k_eeprom_init(struct ath5k_hw *);
62static int ath5k_eeprom_read_mac(struct ath5k_hw *, u8 *);
63
64static int ath5k_hw_enable_pspoll(struct ath5k_hw *, u8 *, u16);
65static int ath5k_hw_disable_pspoll(struct ath5k_hw *);
66
67/*
68 * Enable to overwrite the country code (use "00" for debug)
69 */
70#if 0
71#define COUNTRYCODE "00"
72#endif
73
74/*******************\
75 General Functions
76\*******************/
77
78/*
79 * Functions used internaly
80 */
81
82static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo)
83{
84 return turbo == true ? (usec * 80) : (usec * 40);
85}
86
87static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo)
88{
89 return turbo == true ? (clock / 80) : (clock / 40);
90}
91
92/*
93 * Check if a register write has been completed
94 */
95int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val,
96 bool is_set)
97{
98 int i;
99 u32 data;
100
101 for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) {
102 data = ath5k_hw_reg_read(ah, reg);
103 if ((is_set == true) && (data & flag))
104 break;
105 else if ((data & flag) == val)
106 break;
107 udelay(15);
108 }
109
110 return (i <= 0) ? -EAGAIN : 0;
111}
112
113
114/***************************************\
115 Attach/Detach Functions
116\***************************************/
117
118/*
119 * Check if the device is supported and initialize the needed structs
120 */
121struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version)
122{
123 struct ath5k_hw *ah;
124 u8 mac[ETH_ALEN];
125 int ret;
126 u32 srev;
127
128 /*If we passed the test malloc a ath5k_hw struct*/
129 ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
130 if (ah == NULL) {
131 ret = -ENOMEM;
132 ATH5K_ERR(sc, "out of memory\n");
133 goto err;
134 }
135
136 ah->ah_sc = sc;
137 ah->ah_iobase = sc->iobase;
138
139 /*
140 * HW information
141 */
142
143 /* Get reg domain from eeprom */
144 ath5k_get_regdomain(ah);
145
146 ah->ah_op_mode = IEEE80211_IF_TYPE_STA;
147 ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT;
148 ah->ah_turbo = false;
149 ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
150 ah->ah_imr = 0;
151 ah->ah_atim_window = 0;
152 ah->ah_aifs = AR5K_TUNE_AIFS;
153 ah->ah_cw_min = AR5K_TUNE_CWMIN;
154 ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY;
155 ah->ah_software_retry = false;
156 ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY;
157
158 /*
159 * Set the mac revision based on the pci id
160 */
161 ah->ah_version = mac_version;
162
163 /*Fill the ath5k_hw struct with the needed functions*/
164 if (ah->ah_version == AR5K_AR5212)
165 ah->ah_magic = AR5K_EEPROM_MAGIC_5212;
166 else if (ah->ah_version == AR5K_AR5211)
167 ah->ah_magic = AR5K_EEPROM_MAGIC_5211;
168
169 if (ah->ah_version == AR5K_AR5212) {
170 ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc;
171 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
172 ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status;
173 } else {
174 ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc;
175 ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc;
176 ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status;
177 }
178
179 if (ah->ah_version == AR5K_AR5212)
180 ah->ah_proc_rx_desc = ath5k_hw_proc_new_rx_status;
181 else if (ah->ah_version <= AR5K_AR5211)
182 ah->ah_proc_rx_desc = ath5k_hw_proc_old_rx_status;
183
184 /* Bring device out of sleep and reset it's units */
185 ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true);
186 if (ret)
187 goto err_free;
188
189 /* Get MAC, PHY and RADIO revisions */
190 srev = ath5k_hw_reg_read(ah, AR5K_SREV);
191 ah->ah_mac_srev = srev;
192 ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER);
193 ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV);
194 ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) &
195 0xffffffff;
196 ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah,
197 CHANNEL_5GHZ);
198
199 if (ah->ah_version == AR5K_AR5210)
200 ah->ah_radio_2ghz_revision = 0;
201 else
202 ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah,
203 CHANNEL_2GHZ);
204
205 /* Return on unsuported chips (unsupported eeprom etc) */
206 if(srev >= AR5K_SREV_VER_AR5416){
207 ATH5K_ERR(sc, "Device not yet supported.\n");
208 ret = -ENODEV;
209 goto err_free;
210 }
211
212 /* Identify single chip solutions */
213 if((srev <= AR5K_SREV_VER_AR5414) &&
214 (srev >= AR5K_SREV_VER_AR2424)) {
215 ah->ah_single_chip = true;
216 } else {
217 ah->ah_single_chip = false;
218 }
219
220 /* Single chip radio */
221 if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision)
222 ah->ah_radio_2ghz_revision = 0;
223
224 /* Identify the radio chip*/
225 if (ah->ah_version == AR5K_AR5210) {
226 ah->ah_radio = AR5K_RF5110;
227 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) {
228 ah->ah_radio = AR5K_RF5111;
229 } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) {
230 ah->ah_radio = AR5K_RF5112;
231 } else {
232 ah->ah_radio = AR5K_RF5413;
233 }
234
235 ah->ah_phy = AR5K_PHY(0);
236
237 /*
238 * Get card capabilities, values, ...
239 */
240
241 ret = ath5k_eeprom_init(ah);
242 if (ret) {
243 ATH5K_ERR(sc, "unable to init EEPROM\n");
244 goto err_free;
245 }
246
247 /* Get misc capabilities */
248 ret = ath5k_hw_get_capabilities(ah);
249 if (ret) {
250 ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n",
251 sc->pdev->device);
252 goto err_free;
253 }
254
255 /* Get MAC address */
256 ret = ath5k_eeprom_read_mac(ah, mac);
257 if (ret) {
258 ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n",
259 sc->pdev->device);
260 goto err_free;
261 }
262
263 ath5k_hw_set_lladdr(ah, mac);
264 /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */
265 memset(ah->ah_bssid, 0xff, ETH_ALEN);
266 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
267 ath5k_hw_set_opmode(ah);
268
269 ath5k_hw_set_rfgain_opt(ah);
270
271 return ah;
272err_free:
273 kfree(ah);
274err:
275 return ERR_PTR(ret);
276}
277
278/*
279 * Bring up MAC + PHY Chips
280 */
281static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
282{
283 u32 turbo, mode, clock;
284 int ret;
285
286 turbo = 0;
287 mode = 0;
288 clock = 0;
289
290 ATH5K_TRACE(ah->ah_sc);
291
292 /* Wakeup the device */
293 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
294 if (ret) {
295 ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
296 return ret;
297 }
298
299 if (ah->ah_version != AR5K_AR5210) {
300 /*
301 * Get channel mode flags
302 */
303
304 if (ah->ah_radio >= AR5K_RF5112) {
305 mode = AR5K_PHY_MODE_RAD_RF5112;
306 clock = AR5K_PHY_PLL_RF5112;
307 } else {
308 mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/
309 clock = AR5K_PHY_PLL_RF5111; /*Zero*/
310 }
311
312 if (flags & CHANNEL_2GHZ) {
313 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
314 clock |= AR5K_PHY_PLL_44MHZ;
315
316 if (flags & CHANNEL_CCK) {
317 mode |= AR5K_PHY_MODE_MOD_CCK;
318 } else if (flags & CHANNEL_OFDM) {
319 /* XXX Dynamic OFDM/CCK is not supported by the
320 * AR5211 so we set MOD_OFDM for plain g (no
321 * CCK headers) operation. We need to test
322 * this, 5211 might support ofdm-only g after
323 * all, there are also initial register values
324 * in the code for g mode (see initvals.c). */
325 if (ah->ah_version == AR5K_AR5211)
326 mode |= AR5K_PHY_MODE_MOD_OFDM;
327 else
328 mode |= AR5K_PHY_MODE_MOD_DYN;
329 } else {
330 ATH5K_ERR(ah->ah_sc,
331 "invalid radio modulation mode\n");
332 return -EINVAL;
333 }
334 } else if (flags & CHANNEL_5GHZ) {
335 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
336 clock |= AR5K_PHY_PLL_40MHZ;
337
338 if (flags & CHANNEL_OFDM)
339 mode |= AR5K_PHY_MODE_MOD_OFDM;
340 else {
341 ATH5K_ERR(ah->ah_sc,
342 "invalid radio modulation mode\n");
343 return -EINVAL;
344 }
345 } else {
346 ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
347 return -EINVAL;
348 }
349
350 if (flags & CHANNEL_TURBO)
351 turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
352 } else { /* Reset the device */
353
354 /* ...enable Atheros turbo mode if requested */
355 if (flags & CHANNEL_TURBO)
356 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
357 AR5K_PHY_TURBO);
358 }
359
360 /* ...reset chipset and PCI device */
361 if (ah->ah_single_chip == false && ath5k_hw_nic_reset(ah,
362 AR5K_RESET_CTL_CHIP | AR5K_RESET_CTL_PCI)) {
363 ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip + PCI\n");
364 return -EIO;
365 }
366
367 if (ah->ah_version == AR5K_AR5210)
368 udelay(2300);
369
370 /* ...wakeup again!*/
371 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
372 if (ret) {
373 ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
374 return ret;
375 }
376
377 /* ...final warm reset */
378 if (ath5k_hw_nic_reset(ah, 0)) {
379 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
380 return -EIO;
381 }
382
383 if (ah->ah_version != AR5K_AR5210) {
384 /* ...set the PHY operating mode */
385 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
386 udelay(300);
387
388 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
389 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
390 }
391
392 return 0;
393}
394
395/*
396 * Get the rate table for a specific operation mode
397 */
398const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah,
399 unsigned int mode)
400{
401 ATH5K_TRACE(ah->ah_sc);
402
403 if (!test_bit(mode, ah->ah_capabilities.cap_mode))
404 return NULL;
405
406 /* Get rate tables */
407 switch (mode) {
408 case MODE_IEEE80211A:
409 return &ath5k_rt_11a;
410 case MODE_ATHEROS_TURBO:
411 return &ath5k_rt_turbo;
412 case MODE_IEEE80211B:
413 return &ath5k_rt_11b;
414 case MODE_IEEE80211G:
415 return &ath5k_rt_11g;
416 case MODE_ATHEROS_TURBOG:
417 return &ath5k_rt_xr;
418 }
419
420 return NULL;
421}
422
423/*
424 * Free the ath5k_hw struct
425 */
426void ath5k_hw_detach(struct ath5k_hw *ah)
427{
428 ATH5K_TRACE(ah->ah_sc);
429
430 if (ah->ah_rf_banks != NULL)
431 kfree(ah->ah_rf_banks);
432
433 /* assume interrupts are down */
434 kfree(ah);
435}
436
437/****************************\
438 Reset function and helpers
439\****************************/
440
441/**
442 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
443 *
444 * @ah: the &struct ath5k_hw
445 * @channel: the currently set channel upon reset
446 *
447 * Write the OFDM timings for the AR5212 upon reset. This is a helper for
448 * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
449 * depending on the bandwidth of the channel.
450 *
451 */
452static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
453 struct ieee80211_channel *channel)
454{
455 /* Get exponent and mantissa and set it */
456 u32 coef_scaled, coef_exp, coef_man,
457 ds_coef_exp, ds_coef_man, clock;
458
459 if (!(ah->ah_version == AR5K_AR5212) ||
460 !(channel->val & CHANNEL_OFDM))
461 BUG();
462
463 /* Seems there are two PLLs, one for baseband sampling and one
464 * for tuning. Tuning basebands are 40 MHz or 80MHz when in
465 * turbo. */
466 clock = channel->val & CHANNEL_TURBO ? 80 : 40;
467 coef_scaled = ((5 * (clock << 24)) / 2) /
468 channel->freq;
469
470 for (coef_exp = 31; coef_exp > 0; coef_exp--)
471 if ((coef_scaled >> coef_exp) & 0x1)
472 break;
473
474 if (!coef_exp)
475 return -EINVAL;
476
477 coef_exp = 14 - (coef_exp - 24);
478 coef_man = coef_scaled +
479 (1 << (24 - coef_exp - 1));
480 ds_coef_man = coef_man >> (24 - coef_exp);
481 ds_coef_exp = coef_exp - 16;
482
483 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
484 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
485 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
486 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
487
488 return 0;
489}
490
491/**
492 * ath5k_hw_write_rate_duration - set rate duration during hw resets
493 *
494 * @ah: the &struct ath5k_hw
495 * @driver_mode: one of enum ieee80211_phymode or our one of our own
496 * vendor modes
497 *
498 * Write the rate duration table for the current mode upon hw reset. This
499 * is a helper for ath5k_hw_reset(). It seems all this is doing is setting
500 * an ACK timeout for the hardware for the current mode for each rate. The
501 * rates which are capable of short preamble (802.11b rates 2Mbps, 5.5Mbps,
502 * and 11Mbps) have another register for the short preamble ACK timeout
503 * calculation.
504 *
505 */
506static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
507 unsigned int driver_mode)
508{
509 struct ath5k_softc *sc = ah->ah_sc;
510 const struct ath5k_rate_table *rt;
511 unsigned int i;
512
513 /* Get rate table for the current operating mode */
514 rt = ath5k_hw_get_rate_table(ah,
515 driver_mode);
516
517 /* Write rate duration table */
518 for (i = 0; i < rt->rate_count; i++) {
519 const struct ath5k_rate *rate, *control_rate;
520 u32 reg;
521 u16 tx_time;
522
523 rate = &rt->rates[i];
524 control_rate = &rt->rates[rate->control_rate];
525
526 /* Set ACK timeout */
527 reg = AR5K_RATE_DUR(rate->rate_code);
528
529 /* An ACK frame consists of 10 bytes. If you add the FCS,
530 * which ieee80211_generic_frame_duration() adds,
531 * its 14 bytes. Note we use the control rate and not the
532 * actual rate for this rate. See mac80211 tx.c
533 * ieee80211_duration() for a brief description of
534 * what rate we should choose to TX ACKs. */
535 tx_time = ieee80211_generic_frame_duration(sc->hw,
536 sc->iface_id, 10, control_rate->rate_kbps/100);
537
538 ath5k_hw_reg_write(ah, tx_time, reg);
539
540 if (!HAS_SHPREAMBLE(i))
541 continue;
542
543 /*
544 * We're not distinguishing short preamble here,
545 * This is true, all we'll get is a longer value here
546 * which is not necessarilly bad. We could use
547 * export ieee80211_frame_duration() but that needs to be
548 * fixed first to be properly used by mac802111 drivers:
549 *
550 * - remove erp stuff and let the routine figure ofdm
551 * erp rates
552 * - remove passing argument ieee80211_local as
553 * drivers don't have access to it
554 * - move drivers using ieee80211_generic_frame_duration()
555 * to this
556 */
557 ath5k_hw_reg_write(ah, tx_time,
558 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
559 }
560}
561
562/*
563 * Main reset function
564 */
565int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
566 struct ieee80211_channel *channel, bool change_channel)
567{
568 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
569 u32 data, s_seq, s_ant, s_led[3];
570 unsigned int i, mode, freq, ee_mode, ant[2], driver_mode = -1;
571 int ret;
572
573 ATH5K_TRACE(ah->ah_sc);
574
575 s_seq = 0;
576 s_ant = 0;
577 ee_mode = 0;
578 freq = 0;
579 mode = 0;
580
581 /*
582 * Save some registers before a reset
583 */
584 /*DCU/Antenna selection not available on 5210*/
585 if (ah->ah_version != AR5K_AR5210) {
586 if (change_channel == true) {
587 /* Seq number for queue 0 -do this for all queues ? */
588 s_seq = ath5k_hw_reg_read(ah,
589 AR5K_QUEUE_DFS_SEQNUM(0));
590 /*Default antenna*/
591 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
592 }
593 }
594
595 /*GPIOs*/
596 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
597 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
598 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
599
600 if (change_channel == true && ah->ah_rf_banks != NULL)
601 ath5k_hw_get_rf_gain(ah);
602
603
604 /*Wakeup the device*/
605 ret = ath5k_hw_nic_wakeup(ah, channel->val, false);
606 if (ret)
607 return ret;
608
609 /*
610 * Initialize operating mode
611 */
612 ah->ah_op_mode = op_mode;
613
614 /*
615 * 5111/5112 Settings
616 * 5210 only comes with RF5110
617 */
618 if (ah->ah_version != AR5K_AR5210) {
619 if (ah->ah_radio != AR5K_RF5111 &&
620 ah->ah_radio != AR5K_RF5112 &&
621 ah->ah_radio != AR5K_RF5413) {
622 ATH5K_ERR(ah->ah_sc,
623 "invalid phy radio: %u\n", ah->ah_radio);
624 return -EINVAL;
625 }
626
627 switch (channel->val & CHANNEL_MODES) {
628 case CHANNEL_A:
629 mode = AR5K_INI_VAL_11A;
630 freq = AR5K_INI_RFGAIN_5GHZ;
631 ee_mode = AR5K_EEPROM_MODE_11A;
632 driver_mode = MODE_IEEE80211A;
633 break;
634 case CHANNEL_G:
635 mode = AR5K_INI_VAL_11G;
636 freq = AR5K_INI_RFGAIN_2GHZ;
637 ee_mode = AR5K_EEPROM_MODE_11G;
638 driver_mode = MODE_IEEE80211G;
639 break;
640 case CHANNEL_B:
641 mode = AR5K_INI_VAL_11B;
642 freq = AR5K_INI_RFGAIN_2GHZ;
643 ee_mode = AR5K_EEPROM_MODE_11B;
644 driver_mode = MODE_IEEE80211B;
645 break;
646 case CHANNEL_T:
647 mode = AR5K_INI_VAL_11A_TURBO;
648 freq = AR5K_INI_RFGAIN_5GHZ;
649 ee_mode = AR5K_EEPROM_MODE_11A;
650 driver_mode = MODE_ATHEROS_TURBO;
651 break;
652 /*Is this ok on 5211 too ?*/
653 case CHANNEL_TG:
654 mode = AR5K_INI_VAL_11G_TURBO;
655 freq = AR5K_INI_RFGAIN_2GHZ;
656 ee_mode = AR5K_EEPROM_MODE_11G;
657 driver_mode = MODE_ATHEROS_TURBOG;
658 break;
659 case CHANNEL_XR:
660 if (ah->ah_version == AR5K_AR5211) {
661 ATH5K_ERR(ah->ah_sc,
662 "XR mode not available on 5211");
663 return -EINVAL;
664 }
665 mode = AR5K_INI_VAL_XR;
666 freq = AR5K_INI_RFGAIN_5GHZ;
667 ee_mode = AR5K_EEPROM_MODE_11A;
668 driver_mode = MODE_IEEE80211A;
669 break;
670 default:
671 ATH5K_ERR(ah->ah_sc,
672 "invalid channel: %d\n", channel->freq);
673 return -EINVAL;
674 }
675
676 /* PHY access enable */
677 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
678
679 }
680
681 ret = ath5k_hw_write_initvals(ah, mode, change_channel);
682 if (ret)
683 return ret;
684
685 /*
686 * 5211/5212 Specific
687 */
688 if (ah->ah_version != AR5K_AR5210) {
689 /*
690 * Write initial RF gain settings
691 * This should work for both 5111/5112
692 */
693 ret = ath5k_hw_rfgain(ah, freq);
694 if (ret)
695 return ret;
696
697 mdelay(1);
698
699 /*
700 * Write some more initial register settings
701 */
702 if (ah->ah_version > AR5K_AR5211){ /* found on 5213+ */
703 ath5k_hw_reg_write(ah, 0x0002a002, AR5K_PHY(11));
704
705 if (channel->val == CHANNEL_G)
706 ath5k_hw_reg_write(ah, 0x00f80d80, AR5K_PHY(83)); /* 0x00fc0ec0 */
707 else
708 ath5k_hw_reg_write(ah, 0x00000000, AR5K_PHY(83));
709
710 ath5k_hw_reg_write(ah, 0x000001b5, 0xa228); /* 0x000009b5 */
711 ath5k_hw_reg_write(ah, 0x000009b5, 0xa228);
712 ath5k_hw_reg_write(ah, 0x0000000f, 0x8060);
713 ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
714 ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
715 }
716
717 /* Fix for first revision of the RF5112 RF chipset */
718 if (ah->ah_radio >= AR5K_RF5112 &&
719 ah->ah_radio_5ghz_revision <
720 AR5K_SREV_RAD_5112A) {
721 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
722 AR5K_PHY_CCKTXCTL);
723 if (channel->val & CHANNEL_5GHZ)
724 data = 0xffb81020;
725 else
726 data = 0xffb80d20;
727 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
728 }
729
730 /*
731 * Set TX power (FIXME)
732 */
733 ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
734 if (ret)
735 return ret;
736
737 /* Write rate duration table */
738 if (ah->ah_version == AR5K_AR5212)
739 ath5k_hw_write_rate_duration(ah, driver_mode);
740
741 /*
742 * Write RF registers
743 * TODO:Does this work on 5211 (5111) ?
744 */
745 ret = ath5k_hw_rfregs(ah, channel, mode);
746 if (ret)
747 return ret;
748
749 /*
750 * Configure additional registers
751 */
752
753 /* Write OFDM timings on 5212*/
754 if (ah->ah_version == AR5K_AR5212 &&
755 channel->val & CHANNEL_OFDM) {
756 ret = ath5k_hw_write_ofdm_timings(ah, channel);
757 if (ret)
758 return ret;
759 }
760
761 /*Enable/disable 802.11b mode on 5111
762 (enable 2111 frequency converter + CCK)*/
763 if (ah->ah_radio == AR5K_RF5111) {
764 if (driver_mode == MODE_IEEE80211B)
765 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
766 AR5K_TXCFG_B_MODE);
767 else
768 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
769 AR5K_TXCFG_B_MODE);
770 }
771
772 /*
773 * Set channel and calibrate the PHY
774 */
775 ret = ath5k_hw_channel(ah, channel);
776 if (ret)
777 return ret;
778
779 /* Set antenna mode */
780 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x44),
781 ah->ah_antenna[ee_mode][0], 0xfffffc06);
782
783 /*
784 * In case a fixed antenna was set as default
785 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
786 * registers.
787 */
788 if (s_ant != 0){
789 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
790 ant[0] = ant[1] = AR5K_ANT_FIXED_A;
791 else /* 2 - Aux */
792 ant[0] = ant[1] = AR5K_ANT_FIXED_B;
793 } else {
794 ant[0] = AR5K_ANT_FIXED_A;
795 ant[1] = AR5K_ANT_FIXED_B;
796 }
797
798 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
799 AR5K_PHY_ANT_SWITCH_TABLE_0);
800 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
801 AR5K_PHY_ANT_SWITCH_TABLE_1);
802
803 /* Commit values from EEPROM */
804 if (ah->ah_radio == AR5K_RF5111)
805 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
806 AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
807
808 ath5k_hw_reg_write(ah,
809 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
810 AR5K_PHY(0x5a));
811
812 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x11),
813 (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
814 0xffffc07f);
815 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x12),
816 (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
817 0xfffc0fff);
818 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x14),
819 (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
820 ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
821 0xffff0000);
822
823 ath5k_hw_reg_write(ah,
824 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
825 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
826 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
827 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY(0x0d));
828
829 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x0a),
830 ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
831 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x19),
832 (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
833 AR5K_REG_MASKED_BITS(ah, AR5K_PHY(0x49), 4, 0xffffff01);
834
835 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
836 AR5K_PHY_IQ_CORR_ENABLE |
837 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
838 ee->ee_q_cal[ee_mode]);
839
840 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
841 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
842 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
843 ee->ee_margin_tx_rx[ee_mode]);
844
845 } else {
846 mdelay(1);
847 /* Disable phy and wait */
848 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
849 mdelay(1);
850 }
851
852 /*
853 * Restore saved values
854 */
855 /*DCU/Antenna selection not available on 5210*/
856 if (ah->ah_version != AR5K_AR5210) {
857 ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
858 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
859 }
860 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
861 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
862 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
863
864 /*
865 * Misc
866 */
867 /* XXX: add ah->aid once mac80211 gives this to us */
868 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
869
870 ath5k_hw_set_opmode(ah);
871 /*PISR/SISR Not available on 5210*/
872 if (ah->ah_version != AR5K_AR5210) {
873 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
874 /* If we later allow tuning for this, store into sc structure */
875 data = AR5K_TUNE_RSSI_THRES |
876 AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
877 ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
878 }
879
880 /*
881 * Set Rx/Tx DMA Configuration
882 *(passing dma size not available on 5210)
883 */
884 if (ah->ah_version != AR5K_AR5210) {
885 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, AR5K_TXCFG_SDMAMR,
886 AR5K_DMASIZE_512B | AR5K_TXCFG_DMASIZE);
887 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_SDMAMW,
888 AR5K_DMASIZE_512B);
889 }
890
891 /*
892 * Enable the PHY and wait until completion
893 */
894 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
895
896 /*
897 * 5111/5112 Specific
898 */
899 if (ah->ah_version != AR5K_AR5210) {
900 data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
901 AR5K_PHY_RX_DELAY_M;
902 data = (channel->val & CHANNEL_CCK) ?
903 ((data << 2) / 22) : (data / 10);
904
905 udelay(100 + data);
906 } else {
907 mdelay(1);
908 }
909
910 /*
911 * Enable calibration and wait until completion
912 */
913 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
914 AR5K_PHY_AGCCTL_CAL);
915
916 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
917 AR5K_PHY_AGCCTL_CAL, 0, false)) {
918 ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
919 channel->freq);
920 return -EAGAIN;
921 }
922
923 ret = ath5k_hw_noise_floor_calibration(ah, channel->freq);
924 if (ret)
925 return ret;
926
927 ah->ah_calibration = false;
928
929 /* A and G modes can use QAM modulation which requires enabling
930 * I and Q calibration. Don't bother in B mode. */
931 if (!(driver_mode == MODE_IEEE80211B)) {
932 ah->ah_calibration = true;
933 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
934 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
935 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
936 AR5K_PHY_IQ_RUN);
937 }
938
939 /*
940 * Reset queues and start beacon timers at the end of the reset routine
941 */
942 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
943 /*No QCU on 5210*/
944 if (ah->ah_version != AR5K_AR5210)
945 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
946
947 ret = ath5k_hw_reset_tx_queue(ah, i);
948 if (ret) {
949 ATH5K_ERR(ah->ah_sc,
950 "failed to reset TX queue #%d\n", i);
951 return ret;
952 }
953 }
954
955 /* Pre-enable interrupts on 5211/5212*/
956 if (ah->ah_version != AR5K_AR5210)
957 ath5k_hw_set_intr(ah, AR5K_INT_RX | AR5K_INT_TX |
958 AR5K_INT_FATAL);
959
960 /*
961 * Set RF kill flags if supported by the device (read from the EEPROM)
962 * Disable gpio_intr for now since it results system hang.
963 * TODO: Handle this in ath5k_intr
964 */
965#if 0
966 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
967 ath5k_hw_set_gpio_input(ah, 0);
968 ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
969 if (ah->ah_gpio[0] == 0)
970 ath5k_hw_set_gpio_intr(ah, 0, 1);
971 else
972 ath5k_hw_set_gpio_intr(ah, 0, 0);
973 }
974#endif
975
976 /*
977 * Set the 32MHz reference clock on 5212 phy clock sleep register
978 */
979 if (ah->ah_version == AR5K_AR5212) {
980 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
981 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
982 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
983 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
984 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
985 ath5k_hw_reg_write(ah, ah->ah_radio == AR5K_RF5111 ?
986 AR5K_PHY_SPENDING_RF5111 : AR5K_PHY_SPENDING_RF5112,
987 AR5K_PHY_SPENDING);
988 }
989
990 /*
991 * Disable beacons and reset the register
992 */
993 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
994 AR5K_BEACON_RESET_TSF);
995
996 return 0;
997}
998
999/*
1000 * Reset chipset
1001 */
1002static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
1003{
1004 int ret;
1005 u32 mask = val ? val : ~0U;
1006
1007 ATH5K_TRACE(ah->ah_sc);
1008
1009 /* Read-and-clear RX Descriptor Pointer*/
1010 ath5k_hw_reg_read(ah, AR5K_RXDP);
1011
1012 /*
1013 * Reset the device and wait until success
1014 */
1015 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
1016
1017 /* Wait at least 128 PCI clocks */
1018 udelay(15);
1019
1020 if (ah->ah_version == AR5K_AR5210) {
1021 val &= AR5K_RESET_CTL_CHIP;
1022 mask &= AR5K_RESET_CTL_CHIP;
1023 } else {
1024 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1025 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
1026 }
1027
1028 ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
1029
1030 /*
1031 * Reset configuration register (for hw byte-swap). Note that this
1032 * is only set for big endian. We do the necessary magic in
1033 * AR5K_INIT_CFG.
1034 */
1035 if ((val & AR5K_RESET_CTL_PCU) == 0)
1036 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
1037
1038 return ret;
1039}
1040
1041/*
1042 * Power management functions
1043 */
1044
1045/*
1046 * Sleep control
1047 */
1048int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
1049 bool set_chip, u16 sleep_duration)
1050{
1051 unsigned int i;
1052 u32 staid;
1053
1054 ATH5K_TRACE(ah->ah_sc);
1055 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
1056
1057 switch (mode) {
1058 case AR5K_PM_AUTO:
1059 staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
1060 /* fallthrough */
1061 case AR5K_PM_NETWORK_SLEEP:
1062 if (set_chip == true)
1063 ath5k_hw_reg_write(ah,
1064 AR5K_SLEEP_CTL_SLE | sleep_duration,
1065 AR5K_SLEEP_CTL);
1066
1067 staid |= AR5K_STA_ID1_PWR_SV;
1068 break;
1069
1070 case AR5K_PM_FULL_SLEEP:
1071 if (set_chip == true)
1072 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
1073 AR5K_SLEEP_CTL);
1074
1075 staid |= AR5K_STA_ID1_PWR_SV;
1076 break;
1077
1078 case AR5K_PM_AWAKE:
1079 if (set_chip == false)
1080 goto commit;
1081
1082 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
1083 AR5K_SLEEP_CTL);
1084
1085 for (i = 5000; i > 0; i--) {
1086 /* Check if the chip did wake up */
1087 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
1088 AR5K_PCICFG_SPWR_DN) == 0)
1089 break;
1090
1091 /* Wait a bit and retry */
1092 udelay(200);
1093 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_WAKE,
1094 AR5K_SLEEP_CTL);
1095 }
1096
1097 /* Fail if the chip didn't wake up */
1098 if (i <= 0)
1099 return -EIO;
1100
1101 staid &= ~AR5K_STA_ID1_PWR_SV;
1102 break;
1103
1104 default:
1105 return -EINVAL;
1106 }
1107
1108commit:
1109 ah->ah_power_mode = mode;
1110 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
1111
1112 return 0;
1113}
1114
1115/***********************\
1116 DMA Related Functions
1117\***********************/
1118
1119/*
1120 * Receive functions
1121 */
1122
1123/*
1124 * Start DMA receive
1125 */
1126void ath5k_hw_start_rx(struct ath5k_hw *ah)
1127{
1128 ATH5K_TRACE(ah->ah_sc);
1129 ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR);
1130}
1131
1132/*
1133 * Stop DMA receive
1134 */
1135int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah)
1136{
1137 unsigned int i;
1138
1139 ATH5K_TRACE(ah->ah_sc);
1140 ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR);
1141
1142 /*
1143 * It may take some time to disable the DMA receive unit
1144 */
1145 for (i = 2000; i > 0 &&
1146 (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0;
1147 i--)
1148 udelay(10);
1149
1150 return i ? 0 : -EBUSY;
1151}
1152
1153/*
1154 * Get the address of the RX Descriptor
1155 */
1156u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah)
1157{
1158 return ath5k_hw_reg_read(ah, AR5K_RXDP);
1159}
1160
1161/*
1162 * Set the address of the RX Descriptor
1163 */
1164void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr)
1165{
1166 ATH5K_TRACE(ah->ah_sc);
1167
1168 /*TODO:Shouldn't we check if RX is enabled first ?*/
1169 ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP);
1170}
1171
1172/*
1173 * Transmit functions
1174 */
1175
1176/*
1177 * Start DMA transmit for a specific queue
1178 * (see also QCU/DCU functions)
1179 */
1180int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue)
1181{
1182 u32 tx_queue;
1183
1184 ATH5K_TRACE(ah->ah_sc);
1185 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1186
1187 /* Return if queue is declared inactive */
1188 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1189 return -EIO;
1190
1191 if (ah->ah_version == AR5K_AR5210) {
1192 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1193
1194 /*
1195 * Set the queue by type on 5210
1196 */
1197 switch (ah->ah_txq[queue].tqi_type) {
1198 case AR5K_TX_QUEUE_DATA:
1199 tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0;
1200 break;
1201 case AR5K_TX_QUEUE_BEACON:
1202 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1203 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
1204 AR5K_BSR);
1205 break;
1206 case AR5K_TX_QUEUE_CAB:
1207 tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1;
1208 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V |
1209 AR5K_BCR_BDMAE, AR5K_BSR);
1210 break;
1211 default:
1212 return -EINVAL;
1213 }
1214 /* Start queue */
1215 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
1216 } else {
1217 /* Return if queue is disabled */
1218 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue))
1219 return -EIO;
1220
1221 /* Start queue */
1222 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue);
1223 }
1224
1225 return 0;
1226}
1227
1228/*
1229 * Stop DMA transmit for a specific queue
1230 * (see also QCU/DCU functions)
1231 */
1232int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue)
1233{
1234 unsigned int i = 100;
1235 u32 tx_queue, pending;
1236
1237 ATH5K_TRACE(ah->ah_sc);
1238 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1239
1240 /* Return if queue is declared inactive */
1241 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
1242 return -EIO;
1243
1244 if (ah->ah_version == AR5K_AR5210) {
1245 tx_queue = ath5k_hw_reg_read(ah, AR5K_CR);
1246
1247 /*
1248 * Set by queue type
1249 */
1250 switch (ah->ah_txq[queue].tqi_type) {
1251 case AR5K_TX_QUEUE_DATA:
1252 tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0;
1253 break;
1254 case AR5K_TX_QUEUE_BEACON:
1255 case AR5K_TX_QUEUE_CAB:
1256 /* XXX Fix me... */
1257 tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1;
1258 ath5k_hw_reg_write(ah, 0, AR5K_BSR);
1259 break;
1260 default:
1261 return -EINVAL;
1262 }
1263
1264 /* Stop queue */
1265 ath5k_hw_reg_write(ah, tx_queue, AR5K_CR);
1266 } else {
1267 /*
1268 * Schedule TX disable and wait until queue is empty
1269 */
1270 AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue);
1271
1272 /*Check for pending frames*/
1273 do {
1274 pending = ath5k_hw_reg_read(ah,
1275 AR5K_QUEUE_STATUS(queue)) &
1276 AR5K_QCU_STS_FRMPENDCNT;
1277 udelay(100);
1278 } while (--i && pending);
1279
1280 /* Clear register */
1281 ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD);
1282 }
1283
1284 /* TODO: Check for success else return error */
1285 return 0;
1286}
1287
1288/*
1289 * Get the address of the TX Descriptor for a specific queue
1290 * (see also QCU/DCU functions)
1291 */
1292u32 ath5k_hw_get_tx_buf(struct ath5k_hw *ah, unsigned int queue)
1293{
1294 u16 tx_reg;
1295
1296 ATH5K_TRACE(ah->ah_sc);
1297 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1298
1299 /*
1300 * Get the transmit queue descriptor pointer from the selected queue
1301 */
1302 /*5210 doesn't have QCU*/
1303 if (ah->ah_version == AR5K_AR5210) {
1304 switch (ah->ah_txq[queue].tqi_type) {
1305 case AR5K_TX_QUEUE_DATA:
1306 tx_reg = AR5K_NOQCU_TXDP0;
1307 break;
1308 case AR5K_TX_QUEUE_BEACON:
1309 case AR5K_TX_QUEUE_CAB:
1310 tx_reg = AR5K_NOQCU_TXDP1;
1311 break;
1312 default:
1313 return 0xffffffff;
1314 }
1315 } else {
1316 tx_reg = AR5K_QUEUE_TXDP(queue);
1317 }
1318
1319 return ath5k_hw_reg_read(ah, tx_reg);
1320}
1321
1322/*
1323 * Set the address of the TX Descriptor for a specific queue
1324 * (see also QCU/DCU functions)
1325 */
1326int ath5k_hw_put_tx_buf(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr)
1327{
1328 u16 tx_reg;
1329
1330 ATH5K_TRACE(ah->ah_sc);
1331 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
1332
1333 /*
1334 * Set the transmit queue descriptor pointer register by type
1335 * on 5210
1336 */
1337 if (ah->ah_version == AR5K_AR5210) {
1338 switch (ah->ah_txq[queue].tqi_type) {
1339 case AR5K_TX_QUEUE_DATA:
1340 tx_reg = AR5K_NOQCU_TXDP0;
1341 break;
1342 case AR5K_TX_QUEUE_BEACON:
1343 case AR5K_TX_QUEUE_CAB:
1344 tx_reg = AR5K_NOQCU_TXDP1;
1345 break;
1346 default:
1347 return -EINVAL;
1348 }
1349 } else {
1350 /*
1351 * Set the transmit queue descriptor pointer for
1352 * the selected queue on QCU for 5211+
1353 * (this won't work if the queue is still active)
1354 */
1355 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue))
1356 return -EIO;
1357
1358 tx_reg = AR5K_QUEUE_TXDP(queue);
1359 }
1360
1361 /* Set descriptor pointer */
1362 ath5k_hw_reg_write(ah, phys_addr, tx_reg);
1363
1364 return 0;
1365}
1366
1367/*
1368 * Update tx trigger level
1369 */
1370int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase)
1371{
1372 u32 trigger_level, imr;
1373 int ret = -EIO;
1374
1375 ATH5K_TRACE(ah->ah_sc);
1376
1377 /*
1378 * Disable interrupts by setting the mask
1379 */
1380 imr = ath5k_hw_set_intr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL);
1381
1382 /*TODO: Boundary check on trigger_level*/
1383 trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG),
1384 AR5K_TXCFG_TXFULL);
1385
1386 if (increase == false) {
1387 if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES)
1388 goto done;
1389 } else
1390 trigger_level +=
1391 ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2);
1392
1393 /*
1394 * Update trigger level on success
1395 */
1396 if (ah->ah_version == AR5K_AR5210)
1397 ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL);
1398 else
1399 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
1400 AR5K_TXCFG_TXFULL, trigger_level);
1401
1402 ret = 0;
1403
1404done:
1405 /*
1406 * Restore interrupt mask
1407 */
1408 ath5k_hw_set_intr(ah, imr);
1409
1410 return ret;
1411}
1412
1413/*
1414 * Interrupt handling
1415 */
1416
1417/*
1418 * Check if we have pending interrupts
1419 */
1420bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah)
1421{
1422 ATH5K_TRACE(ah->ah_sc);
1423 return ath5k_hw_reg_read(ah, AR5K_INTPEND);
1424}
1425
1426/*
1427 * Get interrupt mask (ISR)
1428 */
1429int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask)
1430{
1431 u32 data;
1432
1433 ATH5K_TRACE(ah->ah_sc);
1434
1435 /*
1436 * Read interrupt status from the Interrupt Status register
1437 * on 5210
1438 */
1439 if (ah->ah_version == AR5K_AR5210) {
1440 data = ath5k_hw_reg_read(ah, AR5K_ISR);
1441 if (unlikely(data == AR5K_INT_NOCARD)) {
1442 *interrupt_mask = data;
1443 return -ENODEV;
1444 }
1445 } else {
1446 /*
1447 * Read interrupt status from the Read-And-Clear shadow register
1448 * Note: PISR/SISR Not available on 5210
1449 */
1450 data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR);
1451 }
1452
1453 /*
1454 * Get abstract interrupt mask (driver-compatible)
1455 */
1456 *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr;
1457
1458 if (unlikely(data == AR5K_INT_NOCARD))
1459 return -ENODEV;
1460
1461 if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR))
1462 *interrupt_mask |= AR5K_INT_RX;
1463
1464 if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR
1465 | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL))
1466 *interrupt_mask |= AR5K_INT_TX;
1467
1468 if (ah->ah_version != AR5K_AR5210) {
1469 /*HIU = Host Interface Unit (PCI etc)*/
1470 if (unlikely(data & (AR5K_ISR_HIUERR)))
1471 *interrupt_mask |= AR5K_INT_FATAL;
1472
1473 /*Beacon Not Ready*/
1474 if (unlikely(data & (AR5K_ISR_BNR)))
1475 *interrupt_mask |= AR5K_INT_BNR;
1476 }
1477
1478 /*
1479 * XXX: BMISS interrupts may occur after association.
1480 * I found this on 5210 code but it needs testing. If this is
1481 * true we should disable them before assoc and re-enable them
1482 * after a successfull assoc + some jiffies.
1483 */
1484#if 0
1485 interrupt_mask &= ~AR5K_INT_BMISS;
1486#endif
1487
1488 /*
1489 * In case we didn't handle anything,
1490 * print the register value.
1491 */
1492 if (unlikely(*interrupt_mask == 0 && net_ratelimit()))
1493 ATH5K_PRINTF("0x%08x\n", data);
1494
1495 return 0;
1496}
1497
1498/*
1499 * Set interrupt mask
1500 */
1501enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask)
1502{
1503 enum ath5k_int old_mask, int_mask;
1504
1505 /*
1506 * Disable card interrupts to prevent any race conditions
1507 * (they will be re-enabled afterwards).
1508 */
1509 ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER);
1510
1511 old_mask = ah->ah_imr;
1512
1513 /*
1514 * Add additional, chipset-dependent interrupt mask flags
1515 * and write them to the IMR (interrupt mask register).
1516 */
1517 int_mask = new_mask & AR5K_INT_COMMON;
1518
1519 if (new_mask & AR5K_INT_RX)
1520 int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN |
1521 AR5K_IMR_RXDESC;
1522
1523 if (new_mask & AR5K_INT_TX)
1524 int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC |
1525 AR5K_IMR_TXURN;
1526
1527 if (ah->ah_version != AR5K_AR5210) {
1528 if (new_mask & AR5K_INT_FATAL) {
1529 int_mask |= AR5K_IMR_HIUERR;
1530 AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT |
1531 AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR);
1532 }
1533 }
1534
1535 ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR);
1536
1537 /* Store new interrupt mask */
1538 ah->ah_imr = new_mask;
1539
1540 /* ..re-enable interrupts */
1541 ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER);
1542
1543 return old_mask;
1544}
1545
1546
1547/*************************\
1548 EEPROM access functions
1549\*************************/
1550
1551/*
1552 * Read from eeprom
1553 */
1554static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data)
1555{
1556 u32 status, timeout;
1557
1558 ATH5K_TRACE(ah->ah_sc);
1559 /*
1560 * Initialize EEPROM access
1561 */
1562 if (ah->ah_version == AR5K_AR5210) {
1563 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1564 (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset));
1565 } else {
1566 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1567 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1568 AR5K_EEPROM_CMD_READ);
1569 }
1570
1571 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1572 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1573 if (status & AR5K_EEPROM_STAT_RDDONE) {
1574 if (status & AR5K_EEPROM_STAT_RDERR)
1575 return -EIO;
1576 *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) &
1577 0xffff);
1578 return 0;
1579 }
1580 udelay(15);
1581 }
1582
1583 return -ETIMEDOUT;
1584}
1585
1586/*
1587 * Write to eeprom - currently disabled, use at your own risk
1588 */
1589static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data)
1590{
1591#if 0
1592 u32 status, timeout;
1593
1594 ATH5K_TRACE(ah->ah_sc);
1595
1596 /*
1597 * Initialize eeprom access
1598 */
1599
1600 if (ah->ah_version == AR5K_AR5210) {
1601 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE);
1602 } else {
1603 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1604 AR5K_EEPROM_CMD_RESET);
1605 }
1606
1607 /*
1608 * Write data to data register
1609 */
1610
1611 if (ah->ah_version == AR5K_AR5210) {
1612 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_BASE + (4 * offset));
1613 } else {
1614 ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE);
1615 ath5k_hw_reg_write(ah, data, AR5K_EEPROM_DATA);
1616 AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD,
1617 AR5K_EEPROM_CMD_WRITE);
1618 }
1619
1620 /*
1621 * Check status
1622 */
1623
1624 for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) {
1625 status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS);
1626 if (status & AR5K_EEPROM_STAT_WRDONE) {
1627 if (status & AR5K_EEPROM_STAT_WRERR)
1628 return EIO;
1629 return 0;
1630 }
1631 udelay(15);
1632 }
1633#endif
1634 ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!");
1635 return -EIO;
1636}
1637
1638/*
1639 * Translate binary channel representation in EEPROM to frequency
1640 */
1641static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, unsigned int mode)
1642{
1643 u16 val;
1644
1645 if (bin == AR5K_EEPROM_CHANNEL_DIS)
1646 return bin;
1647
1648 if (mode == AR5K_EEPROM_MODE_11A) {
1649 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1650 val = (5 * bin) + 4800;
1651 else
1652 val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 :
1653 (bin * 10) + 5100;
1654 } else {
1655 if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2)
1656 val = bin + 2300;
1657 else
1658 val = bin + 2400;
1659 }
1660
1661 return val;
1662}
1663
1664/*
1665 * Read antenna infos from eeprom
1666 */
1667static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset,
1668 unsigned int mode)
1669{
1670 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1671 u32 o = *offset;
1672 u16 val;
1673 int ret, i = 0;
1674
1675 AR5K_EEPROM_READ(o++, val);
1676 ee->ee_switch_settling[mode] = (val >> 8) & 0x7f;
1677 ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f;
1678 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1679
1680 AR5K_EEPROM_READ(o++, val);
1681 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1682 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1683 ee->ee_ant_control[mode][i++] = val & 0x3f;
1684
1685 AR5K_EEPROM_READ(o++, val);
1686 ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f;
1687 ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f;
1688 ee->ee_ant_control[mode][i] = (val << 2) & 0x3f;
1689
1690 AR5K_EEPROM_READ(o++, val);
1691 ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3;
1692 ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f;
1693 ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f;
1694 ee->ee_ant_control[mode][i] = (val << 4) & 0x3f;
1695
1696 AR5K_EEPROM_READ(o++, val);
1697 ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf;
1698 ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f;
1699 ee->ee_ant_control[mode][i++] = val & 0x3f;
1700
1701 /* Get antenna modes */
1702 ah->ah_antenna[mode][0] =
1703 (ee->ee_ant_control[mode][0] << 4) | 0x1;
1704 ah->ah_antenna[mode][AR5K_ANT_FIXED_A] =
1705 ee->ee_ant_control[mode][1] |
1706 (ee->ee_ant_control[mode][2] << 6) |
1707 (ee->ee_ant_control[mode][3] << 12) |
1708 (ee->ee_ant_control[mode][4] << 18) |
1709 (ee->ee_ant_control[mode][5] << 24);
1710 ah->ah_antenna[mode][AR5K_ANT_FIXED_B] =
1711 ee->ee_ant_control[mode][6] |
1712 (ee->ee_ant_control[mode][7] << 6) |
1713 (ee->ee_ant_control[mode][8] << 12) |
1714 (ee->ee_ant_control[mode][9] << 18) |
1715 (ee->ee_ant_control[mode][10] << 24);
1716
1717 /* return new offset */
1718 *offset = o;
1719
1720 return 0;
1721}
1722
1723/*
1724 * Read supported modes from eeprom
1725 */
1726static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset,
1727 unsigned int mode)
1728{
1729 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1730 u32 o = *offset;
1731 u16 val;
1732 int ret;
1733
1734 AR5K_EEPROM_READ(o++, val);
1735 ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff;
1736 ee->ee_thr_62[mode] = val & 0xff;
1737
1738 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1739 ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28;
1740
1741 AR5K_EEPROM_READ(o++, val);
1742 ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff;
1743 ee->ee_tx_frm2xpa_enable[mode] = val & 0xff;
1744
1745 AR5K_EEPROM_READ(o++, val);
1746 ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff;
1747
1748 if ((val & 0xff) & 0x80)
1749 ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1);
1750 else
1751 ee->ee_noise_floor_thr[mode] = val & 0xff;
1752
1753 if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2)
1754 ee->ee_noise_floor_thr[mode] =
1755 mode == AR5K_EEPROM_MODE_11A ? -54 : -1;
1756
1757 AR5K_EEPROM_READ(o++, val);
1758 ee->ee_xlna_gain[mode] = (val >> 5) & 0xff;
1759 ee->ee_x_gain[mode] = (val >> 1) & 0xf;
1760 ee->ee_xpd[mode] = val & 0x1;
1761
1762 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0)
1763 ee->ee_fixed_bias[mode] = (val >> 13) & 0x1;
1764
1765 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) {
1766 AR5K_EEPROM_READ(o++, val);
1767 ee->ee_false_detect[mode] = (val >> 6) & 0x7f;
1768
1769 if (mode == AR5K_EEPROM_MODE_11A)
1770 ee->ee_xr_power[mode] = val & 0x3f;
1771 else {
1772 ee->ee_ob[mode][0] = val & 0x7;
1773 ee->ee_db[mode][0] = (val >> 3) & 0x7;
1774 }
1775 }
1776
1777 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) {
1778 ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN;
1779 ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA;
1780 } else {
1781 ee->ee_i_gain[mode] = (val >> 13) & 0x7;
1782
1783 AR5K_EEPROM_READ(o++, val);
1784 ee->ee_i_gain[mode] |= (val << 3) & 0x38;
1785
1786 if (mode == AR5K_EEPROM_MODE_11G)
1787 ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff;
1788 }
1789
1790 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 &&
1791 mode == AR5K_EEPROM_MODE_11A) {
1792 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
1793 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
1794 }
1795
1796 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 &&
1797 mode == AR5K_EEPROM_MODE_11G)
1798 ee->ee_scaled_cck_delta = (val >> 11) & 0x1f;
1799
1800 /* return new offset */
1801 *offset = o;
1802
1803 return 0;
1804}
1805
1806/*
1807 * Initialize eeprom & capabilities structs
1808 */
1809static int ath5k_eeprom_init(struct ath5k_hw *ah)
1810{
1811 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1812 unsigned int mode, i;
1813 int ret;
1814 u32 offset;
1815 u16 val;
1816
1817 /* Initial TX thermal adjustment values */
1818 ee->ee_tx_clip = 4;
1819 ee->ee_pwd_84 = ee->ee_pwd_90 = 1;
1820 ee->ee_gain_select = 1;
1821
1822 /*
1823 * Read values from EEPROM and store them in the capability structure
1824 */
1825 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic);
1826 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect);
1827 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain);
1828 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version);
1829 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header);
1830
1831 /* Return if we have an old EEPROM */
1832 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0)
1833 return 0;
1834
1835#ifdef notyet
1836 /*
1837 * Validate the checksum of the EEPROM date. There are some
1838 * devices with invalid EEPROMs.
1839 */
1840 for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) {
1841 AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val);
1842 cksum ^= val;
1843 }
1844 if (cksum != AR5K_EEPROM_INFO_CKSUM) {
1845 ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum);
1846 return -EIO;
1847 }
1848#endif
1849
1850 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version),
1851 ee_ant_gain);
1852
1853 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
1854 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0);
1855 AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1);
1856 }
1857
1858 if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) {
1859 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val);
1860 ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7;
1861 ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7;
1862
1863 AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val);
1864 ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7;
1865 ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7;
1866 }
1867
1868 /*
1869 * Get conformance test limit values
1870 */
1871 offset = AR5K_EEPROM_CTL(ah->ah_ee_version);
1872 ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version);
1873
1874 for (i = 0; i < ee->ee_ctls; i++) {
1875 AR5K_EEPROM_READ(offset++, val);
1876 ee->ee_ctl[i] = (val >> 8) & 0xff;
1877 ee->ee_ctl[i + 1] = val & 0xff;
1878 }
1879
1880 /*
1881 * Get values for 802.11a (5GHz)
1882 */
1883 mode = AR5K_EEPROM_MODE_11A;
1884
1885 ee->ee_turbo_max_power[mode] =
1886 AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header);
1887
1888 offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version);
1889
1890 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
1891 if (ret)
1892 return ret;
1893
1894 AR5K_EEPROM_READ(offset++, val);
1895 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
1896 ee->ee_ob[mode][3] = (val >> 5) & 0x7;
1897 ee->ee_db[mode][3] = (val >> 2) & 0x7;
1898 ee->ee_ob[mode][2] = (val << 1) & 0x7;
1899
1900 AR5K_EEPROM_READ(offset++, val);
1901 ee->ee_ob[mode][2] |= (val >> 15) & 0x1;
1902 ee->ee_db[mode][2] = (val >> 12) & 0x7;
1903 ee->ee_ob[mode][1] = (val >> 9) & 0x7;
1904 ee->ee_db[mode][1] = (val >> 6) & 0x7;
1905 ee->ee_ob[mode][0] = (val >> 3) & 0x7;
1906 ee->ee_db[mode][0] = val & 0x7;
1907
1908 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
1909 if (ret)
1910 return ret;
1911
1912 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) {
1913 AR5K_EEPROM_READ(offset++, val);
1914 ee->ee_margin_tx_rx[mode] = val & 0x3f;
1915 }
1916
1917 /*
1918 * Get values for 802.11b (2.4GHz)
1919 */
1920 mode = AR5K_EEPROM_MODE_11B;
1921 offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version);
1922
1923 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
1924 if (ret)
1925 return ret;
1926
1927 AR5K_EEPROM_READ(offset++, val);
1928 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
1929 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
1930 ee->ee_db[mode][1] = val & 0x7;
1931
1932 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
1933 if (ret)
1934 return ret;
1935
1936 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
1937 AR5K_EEPROM_READ(offset++, val);
1938 ee->ee_cal_pier[mode][0] =
1939 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
1940 ee->ee_cal_pier[mode][1] =
1941 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
1942
1943 AR5K_EEPROM_READ(offset++, val);
1944 ee->ee_cal_pier[mode][2] =
1945 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
1946 }
1947
1948 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
1949 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
1950
1951 /*
1952 * Get values for 802.11g (2.4GHz)
1953 */
1954 mode = AR5K_EEPROM_MODE_11G;
1955 offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version);
1956
1957 ret = ath5k_eeprom_read_ants(ah, &offset, mode);
1958 if (ret)
1959 return ret;
1960
1961 AR5K_EEPROM_READ(offset++, val);
1962 ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff);
1963 ee->ee_ob[mode][1] = (val >> 4) & 0x7;
1964 ee->ee_db[mode][1] = val & 0x7;
1965
1966 ret = ath5k_eeprom_read_modes(ah, &offset, mode);
1967 if (ret)
1968 return ret;
1969
1970 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) {
1971 AR5K_EEPROM_READ(offset++, val);
1972 ee->ee_cal_pier[mode][0] =
1973 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
1974 ee->ee_cal_pier[mode][1] =
1975 ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode);
1976
1977 AR5K_EEPROM_READ(offset++, val);
1978 ee->ee_turbo_max_power[mode] = val & 0x7f;
1979 ee->ee_xr_power[mode] = (val >> 7) & 0x3f;
1980
1981 AR5K_EEPROM_READ(offset++, val);
1982 ee->ee_cal_pier[mode][2] =
1983 ath5k_eeprom_bin2freq(ah, val & 0xff, mode);
1984
1985 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
1986 ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f;
1987
1988 AR5K_EEPROM_READ(offset++, val);
1989 ee->ee_i_cal[mode] = (val >> 8) & 0x3f;
1990 ee->ee_q_cal[mode] = (val >> 3) & 0x1f;
1991
1992 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) {
1993 AR5K_EEPROM_READ(offset++, val);
1994 ee->ee_cck_ofdm_gain_delta = val & 0xff;
1995 }
1996 }
1997
1998 /*
1999 * Read 5GHz EEPROM channels
2000 */
2001
2002 return 0;
2003}
2004
2005/*
2006 * Read the MAC address from eeprom
2007 */
2008static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
2009{
2010 u8 mac_d[ETH_ALEN];
2011 u32 total, offset;
2012 u16 data;
2013 int octet, ret;
2014
2015 memset(mac, 0, ETH_ALEN);
2016 memset(mac_d, 0, ETH_ALEN);
2017
2018 ret = ath5k_hw_eeprom_read(ah, 0x20, &data);
2019 if (ret)
2020 return ret;
2021
2022 for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {
2023 ret = ath5k_hw_eeprom_read(ah, offset, &data);
2024 if (ret)
2025 return ret;
2026
2027 total += data;
2028 mac_d[octet + 1] = data & 0xff;
2029 mac_d[octet] = data >> 8;
2030 octet += 2;
2031 }
2032
2033 memcpy(mac, mac_d, ETH_ALEN);
2034
2035 if (!total || total == 3 * 0xffff)
2036 return -EINVAL;
2037
2038 return 0;
2039}
2040
2041/*
2042 * Read/Write regulatory domain
2043 */
2044static bool ath5k_eeprom_regulation_domain(struct ath5k_hw *ah, bool write,
2045 enum ath5k_regdom *regdomain)
2046{
2047 u16 ee_regdomain;
2048
2049 /* Read current value */
2050 if (write != true) {
2051 ee_regdomain = ah->ah_capabilities.cap_eeprom.ee_regdomain;
2052 *regdomain = ath5k_regdom_to_ieee(ee_regdomain);
2053 return true;
2054 }
2055
2056 ee_regdomain = ath5k_regdom_from_ieee(*regdomain);
2057
2058 /* Try to write a new value */
2059 if (ah->ah_capabilities.cap_eeprom.ee_protect &
2060 AR5K_EEPROM_PROTECT_WR_128_191)
2061 return false;
2062 if (ath5k_hw_eeprom_write(ah, AR5K_EEPROM_REG_DOMAIN, ee_regdomain)!=0)
2063 return false;
2064
2065 ah->ah_capabilities.cap_eeprom.ee_regdomain = ee_regdomain;
2066
2067 return true;
2068}
2069
2070/*
2071 * Use the above to write a new regulatory domain
2072 */
2073int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain)
2074{
2075 enum ath5k_regdom ieee_regdomain;
2076
2077 ieee_regdomain = ath5k_regdom_to_ieee(regdomain);
2078
2079 if (ath5k_eeprom_regulation_domain(ah, true, &ieee_regdomain) == true)
2080 return 0;
2081
2082 return -EIO;
2083}
2084
2085/*
2086 * Fill the capabilities struct
2087 */
2088static int ath5k_hw_get_capabilities(struct ath5k_hw *ah)
2089{
2090 u16 ee_header;
2091
2092 ATH5K_TRACE(ah->ah_sc);
2093 /* Capabilities stored in the EEPROM */
2094 ee_header = ah->ah_capabilities.cap_eeprom.ee_header;
2095
2096 if (ah->ah_version == AR5K_AR5210) {
2097 /*
2098 * Set radio capabilities
2099 * (The AR5110 only supports the middle 5GHz band)
2100 */
2101 ah->ah_capabilities.cap_range.range_5ghz_min = 5120;
2102 ah->ah_capabilities.cap_range.range_5ghz_max = 5430;
2103 ah->ah_capabilities.cap_range.range_2ghz_min = 0;
2104 ah->ah_capabilities.cap_range.range_2ghz_max = 0;
2105
2106 /* Set supported modes */
2107 __set_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode);
2108 __set_bit(MODE_ATHEROS_TURBO, ah->ah_capabilities.cap_mode);
2109 } else {
2110 /*
2111 * XXX The tranceiver supports frequencies from 4920 to 6100GHz
2112 * XXX and from 2312 to 2732GHz. There are problems with the
2113 * XXX current ieee80211 implementation because the IEEE
2114 * XXX channel mapping does not support negative channel
2115 * XXX numbers (2312MHz is channel -19). Of course, this
2116 * XXX doesn't matter because these channels are out of range
2117 * XXX but some regulation domains like MKK (Japan) will
2118 * XXX support frequencies somewhere around 4.8GHz.
2119 */
2120
2121 /*
2122 * Set radio capabilities
2123 */
2124
2125 if (AR5K_EEPROM_HDR_11A(ee_header)) {
2126 ah->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */
2127 ah->ah_capabilities.cap_range.range_5ghz_max = 6100;
2128
2129 /* Set supported modes */
2130 __set_bit(MODE_IEEE80211A,
2131 ah->ah_capabilities.cap_mode);
2132 __set_bit(MODE_ATHEROS_TURBO,
2133 ah->ah_capabilities.cap_mode);
2134 if (ah->ah_version == AR5K_AR5212)
2135 __set_bit(MODE_ATHEROS_TURBOG,
2136 ah->ah_capabilities.cap_mode);
2137 }
2138
2139 /* Enable 802.11b if a 2GHz capable radio (2111/5112) is
2140 * connected */
2141 if (AR5K_EEPROM_HDR_11B(ee_header) ||
2142 AR5K_EEPROM_HDR_11G(ee_header)) {
2143 ah->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */
2144 ah->ah_capabilities.cap_range.range_2ghz_max = 2732;
2145
2146 if (AR5K_EEPROM_HDR_11B(ee_header))
2147 __set_bit(MODE_IEEE80211B,
2148 ah->ah_capabilities.cap_mode);
2149
2150 if (AR5K_EEPROM_HDR_11G(ee_header))
2151 __set_bit(MODE_IEEE80211G,
2152 ah->ah_capabilities.cap_mode);
2153 }
2154 }
2155
2156 /* GPIO */
2157 ah->ah_gpio_npins = AR5K_NUM_GPIO;
2158
2159 /* Set number of supported TX queues */
2160 if (ah->ah_version == AR5K_AR5210)
2161 ah->ah_capabilities.cap_queues.q_tx_num =
2162 AR5K_NUM_TX_QUEUES_NOQCU;
2163 else
2164 ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES;
2165
2166 return 0;
2167}
2168
2169/*********************************\
2170 Protocol Control Unit Functions
2171\*********************************/
2172
2173/*
2174 * Set Operation mode
2175 */
2176int ath5k_hw_set_opmode(struct ath5k_hw *ah)
2177{
2178 u32 pcu_reg, beacon_reg, low_id, high_id;
2179
2180 pcu_reg = 0;
2181 beacon_reg = 0;
2182
2183 ATH5K_TRACE(ah->ah_sc);
2184
2185 switch (ah->ah_op_mode) {
2186 case IEEE80211_IF_TYPE_IBSS:
2187 pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA |
2188 (ah->ah_version == AR5K_AR5210 ?
2189 AR5K_STA_ID1_NO_PSPOLL : 0);
2190 beacon_reg |= AR5K_BCR_ADHOC;
2191 break;
2192
2193 case IEEE80211_IF_TYPE_AP:
2194 pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA |
2195 (ah->ah_version == AR5K_AR5210 ?
2196 AR5K_STA_ID1_NO_PSPOLL : 0);
2197 beacon_reg |= AR5K_BCR_AP;
2198 break;
2199
2200 case IEEE80211_IF_TYPE_STA:
2201 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2202 (ah->ah_version == AR5K_AR5210 ?
2203 AR5K_STA_ID1_PWR_SV : 0);
2204 case IEEE80211_IF_TYPE_MNTR:
2205 pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA |
2206 (ah->ah_version == AR5K_AR5210 ?
2207 AR5K_STA_ID1_NO_PSPOLL : 0);
2208 break;
2209
2210 default:
2211 return -EINVAL;
2212 }
2213
2214 /*
2215 * Set PCU registers
2216 */
2217 low_id = AR5K_LOW_ID(ah->ah_sta_id);
2218 high_id = AR5K_HIGH_ID(ah->ah_sta_id);
2219 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2220 ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1);
2221
2222 /*
2223 * Set Beacon Control Register on 5210
2224 */
2225 if (ah->ah_version == AR5K_AR5210)
2226 ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR);
2227
2228 return 0;
2229}
2230
2231/*
2232 * BSSID Functions
2233 */
2234
2235/*
2236 * Get station id
2237 */
2238void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac)
2239{
2240 ATH5K_TRACE(ah->ah_sc);
2241 memcpy(mac, ah->ah_sta_id, ETH_ALEN);
2242}
2243
2244/*
2245 * Set station id
2246 */
2247int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac)
2248{
2249 u32 low_id, high_id;
2250
2251 ATH5K_TRACE(ah->ah_sc);
2252 /* Set new station ID */
2253 memcpy(ah->ah_sta_id, mac, ETH_ALEN);
2254
2255 low_id = AR5K_LOW_ID(mac);
2256 high_id = AR5K_HIGH_ID(mac);
2257
2258 ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0);
2259 ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1);
2260
2261 return 0;
2262}
2263
2264/*
2265 * Set BSSID
2266 */
2267void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id)
2268{
2269 u32 low_id, high_id;
2270 u16 tim_offset = 0;
2271
2272 /*
2273 * Set simple BSSID mask on 5212
2274 */
2275 if (ah->ah_version == AR5K_AR5212) {
2276 ath5k_hw_reg_write(ah, 0xfffffff, AR5K_BSS_IDM0);
2277 ath5k_hw_reg_write(ah, 0xfffffff, AR5K_BSS_IDM1);
2278 }
2279
2280 /*
2281 * Set BSSID which triggers the "SME Join" operation
2282 */
2283 low_id = AR5K_LOW_ID(bssid);
2284 high_id = AR5K_HIGH_ID(bssid);
2285 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0);
2286 ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) <<
2287 AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1);
2288
2289 if (assoc_id == 0) {
2290 ath5k_hw_disable_pspoll(ah);
2291 return;
2292 }
2293
2294 AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM,
2295 tim_offset ? tim_offset + 4 : 0);
2296
2297 ath5k_hw_enable_pspoll(ah, NULL, 0);
2298}
2299/**
2300 * ath5k_hw_set_bssid_mask - set common bits we should listen to
2301 *
2302 * The bssid_mask is a utility used by AR5212 hardware to inform the hardware
2303 * which bits of the interface's MAC address should be looked at when trying
2304 * to decide which packets to ACK. In station mode every bit matters. In AP
2305 * mode with a single BSS every bit matters as well. In AP mode with
2306 * multiple BSSes not every bit matters.
2307 *
2308 * @ah: the &struct ath5k_hw
2309 * @mask: the bssid_mask, a u8 array of size ETH_ALEN
2310 *
2311 * Note that this is a simple filter and *does* not filter out all
2312 * relevant frames. Some non-relevant frames will get through, probability
2313 * jocks are welcomed to compute.
2314 *
2315 * When handling multiple BSSes (or VAPs) you can get the BSSID mask by
2316 * computing the set of:
2317 *
2318 * ~ ( MAC XOR BSSID )
2319 *
2320 * When you do this you are essentially computing the common bits. Later it
2321 * is assumed the harware will "and" (&) the BSSID mask with the MAC address
2322 * to obtain the relevant bits which should match on the destination frame.
2323 *
2324 * Simple example: on your card you have have two BSSes you have created with
2325 * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
2326 * There is another BSSID-03 but you are not part of it. For simplicity's sake,
2327 * assuming only 4 bits for a mac address and for BSSIDs you can then have:
2328 *
2329 * \
2330 * MAC: 0001 |
2331 * BSSID-01: 0100 | --> Belongs to us
2332 * BSSID-02: 1001 |
2333 * /
2334 * -------------------
2335 * BSSID-03: 0110 | --> External
2336 * -------------------
2337 *
2338 * Our bssid_mask would then be:
2339 *
2340 * On loop iteration for BSSID-01:
2341 * ~(0001 ^ 0100) -> ~(0101)
2342 * -> 1010
2343 * bssid_mask = 1010
2344 *
2345 * On loop iteration for BSSID-02:
2346 * bssid_mask &= ~(0001 ^ 1001)
2347 * bssid_mask = (1010) & ~(0001 ^ 1001)
2348 * bssid_mask = (1010) & ~(1001)
2349 * bssid_mask = (1010) & (0110)
2350 * bssid_mask = 0010
2351 *
2352 * A bssid_mask of 0010 means "only pay attention to the second least
2353 * significant bit". This is because its the only bit common
2354 * amongst the MAC and all BSSIDs we support. To findout what the real
2355 * common bit is we can simply "&" the bssid_mask now with any BSSID we have
2356 * or our MAC address (we assume the hardware uses the MAC address).
2357 *
2358 * Now, suppose there's an incoming frame for BSSID-03:
2359 *
2360 * IFRAME-01: 0110
2361 *
2362 * An easy eye-inspeciton of this already should tell you that this frame
2363 * will not pass our check. This is beacuse the bssid_mask tells the
2364 * hardware to only look at the second least significant bit and the
2365 * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
2366 * as 1, which does not match 0.
2367 *
2368 * So with IFRAME-01 we *assume* the hardware will do:
2369 *
2370 * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2371 * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
2372 * --> allow = (0010) == 0000 ? 1 : 0;
2373 * --> allow = 0
2374 *
2375 * Lets now test a frame that should work:
2376 *
2377 * IFRAME-02: 0001 (we should allow)
2378 *
2379 * allow = (0001 & 1010) == 1010
2380 *
2381 * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
2382 * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0;
2383 * --> allow = (0010) == (0010)
2384 * --> allow = 1
2385 *
2386 * Other examples:
2387 *
2388 * IFRAME-03: 0100 --> allowed
2389 * IFRAME-04: 1001 --> allowed
2390 * IFRAME-05: 1101 --> allowed but its not for us!!!
2391 *
2392 */
2393int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask)
2394{
2395 u32 low_id, high_id;
2396 ATH5K_TRACE(ah->ah_sc);
2397
2398 if (ah->ah_version == AR5K_AR5212) {
2399 low_id = AR5K_LOW_ID(mask);
2400 high_id = AR5K_HIGH_ID(mask);
2401
2402 ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0);
2403 ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1);
2404
2405 return 0;
2406 }
2407
2408 return -EIO;
2409}
2410
2411/*
2412 * Receive start/stop functions
2413 */
2414
2415/*
2416 * Start receive on PCU
2417 */
2418void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah)
2419{
2420 ATH5K_TRACE(ah->ah_sc);
2421 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
2422}
2423
2424/*
2425 * Stop receive on PCU
2426 */
2427void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah)
2428{
2429 ATH5K_TRACE(ah->ah_sc);
2430 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX);
2431}
2432
2433/*
2434 * RX Filter functions
2435 */
2436
2437/*
2438 * Set multicast filter
2439 */
2440void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1)
2441{
2442 ATH5K_TRACE(ah->ah_sc);
2443 /* Set the multicat filter */
2444 ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0);
2445 ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1);
2446}
2447
2448/*
2449 * Set multicast filter by index
2450 */
2451int ath5k_hw_set_mcast_filterindex(struct ath5k_hw *ah, u32 index)
2452{
2453
2454 ATH5K_TRACE(ah->ah_sc);
2455 if (index >= 64)
2456 return -EINVAL;
2457 else if (index >= 32)
2458 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1,
2459 (1 << (index - 32)));
2460 else
2461 AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2462
2463 return 0;
2464}
2465
2466/*
2467 * Clear Multicast filter by index
2468 */
2469int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index)
2470{
2471
2472 ATH5K_TRACE(ah->ah_sc);
2473 if (index >= 64)
2474 return -EINVAL;
2475 else if (index >= 32)
2476 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1,
2477 (1 << (index - 32)));
2478 else
2479 AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index));
2480
2481 return 0;
2482}
2483
2484/*
2485 * Get current rx filter
2486 */
2487u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah)
2488{
2489 u32 data, filter = 0;
2490
2491 ATH5K_TRACE(ah->ah_sc);
2492 filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER);
2493
2494 /*Radar detection for 5212*/
2495 if (ah->ah_version == AR5K_AR5212) {
2496 data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL);
2497
2498 if (data & AR5K_PHY_ERR_FIL_RADAR)
2499 filter |= AR5K_RX_FILTER_RADARERR;
2500 if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK))
2501 filter |= AR5K_RX_FILTER_PHYERR;
2502 }
2503
2504 return filter;
2505}
2506
2507/*
2508 * Set rx filter
2509 */
2510void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter)
2511{
2512 u32 data = 0;
2513
2514 ATH5K_TRACE(ah->ah_sc);
2515
2516 /* Set PHY error filter register on 5212*/
2517 if (ah->ah_version == AR5K_AR5212) {
2518 if (filter & AR5K_RX_FILTER_RADARERR)
2519 data |= AR5K_PHY_ERR_FIL_RADAR;
2520 if (filter & AR5K_RX_FILTER_PHYERR)
2521 data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK;
2522 }
2523
2524 /*
2525 * The AR5210 uses promiscous mode to detect radar activity
2526 */
2527 if (ah->ah_version == AR5K_AR5210 &&
2528 (filter & AR5K_RX_FILTER_RADARERR)) {
2529 filter &= ~AR5K_RX_FILTER_RADARERR;
2530 filter |= AR5K_RX_FILTER_PROM;
2531 }
2532
2533 /*Zero length DMA*/
2534 if (data)
2535 AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2536 else
2537 AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA);
2538
2539 /*Write RX Filter register*/
2540 ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER);
2541
2542 /*Write PHY error filter register on 5212*/
2543 if (ah->ah_version == AR5K_AR5212)
2544 ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL);
2545
2546}
2547
2548/*
2549 * Beacon related functions
2550 */
2551
2552/*
2553 * Get a 32bit TSF
2554 */
2555u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah)
2556{
2557 ATH5K_TRACE(ah->ah_sc);
2558 return ath5k_hw_reg_read(ah, AR5K_TSF_L32);
2559}
2560
2561/*
2562 * Get the full 64bit TSF
2563 */
2564u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah)
2565{
2566 u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32);
2567 ATH5K_TRACE(ah->ah_sc);
2568
2569 return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32);
2570}
2571
2572/*
2573 * Force a TSF reset
2574 */
2575void ath5k_hw_reset_tsf(struct ath5k_hw *ah)
2576{
2577 ATH5K_TRACE(ah->ah_sc);
2578 AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF);
2579}
2580
2581/*
2582 * Initialize beacon timers
2583 */
2584void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval)
2585{
2586 u32 timer1, timer2, timer3;
2587
2588 ATH5K_TRACE(ah->ah_sc);
2589 /*
2590 * Set the additional timers by mode
2591 */
2592 switch (ah->ah_op_mode) {
2593 case IEEE80211_IF_TYPE_STA:
2594 if (ah->ah_version == AR5K_AR5210) {
2595 timer1 = 0xffffffff;
2596 timer2 = 0xffffffff;
2597 } else {
2598 timer1 = 0x0000ffff;
2599 timer2 = 0x0007ffff;
2600 }
2601 break;
2602
2603 default:
2604 timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) <<
2605 0x00000003;
2606 timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) <<
2607 0x00000003;
2608 }
2609
2610 timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1);
2611
2612 /*
2613 * Set the beacon register and enable all timers.
2614 * (next beacon, DMA beacon, software beacon, ATIM window time)
2615 */
2616 ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0);
2617 ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1);
2618 ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2);
2619 ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3);
2620
2621 ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD |
2622 AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE),
2623 AR5K_BEACON);
2624}
2625
2626#if 0
2627/*
2628 * Set beacon timers
2629 */
2630int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah,
2631 const struct ath5k_beacon_state *state)
2632{
2633 u32 cfp_period, next_cfp, dtim, interval, next_beacon;
2634
2635 /*
2636 * TODO: should be changed through *state
2637 * review struct ath5k_beacon_state struct
2638 *
2639 * XXX: These are used for cfp period bellow, are they
2640 * ok ? Is it O.K. for tsf here to be 0 or should we use
2641 * get_tsf ?
2642 */
2643 u32 dtim_count = 0; /* XXX */
2644 u32 cfp_count = 0; /* XXX */
2645 u32 tsf = 0; /* XXX */
2646
2647 ATH5K_TRACE(ah->ah_sc);
2648 /* Return on an invalid beacon state */
2649 if (state->bs_interval < 1)
2650 return -EINVAL;
2651
2652 interval = state->bs_interval;
2653 dtim = state->bs_dtim_period;
2654
2655 /*
2656 * PCF support?
2657 */
2658 if (state->bs_cfp_period > 0) {
2659 /*
2660 * Enable PCF mode and set the CFP
2661 * (Contention Free Period) and timer registers
2662 */
2663 cfp_period = state->bs_cfp_period * state->bs_dtim_period *
2664 state->bs_interval;
2665 next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) *
2666 state->bs_interval;
2667
2668 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
2669 AR5K_STA_ID1_DEFAULT_ANTENNA |
2670 AR5K_STA_ID1_PCF);
2671 ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD);
2672 ath5k_hw_reg_write(ah, state->bs_cfp_max_duration,
2673 AR5K_CFP_DUR);
2674 ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period :
2675 next_cfp)) << 3, AR5K_TIMER2);
2676 } else {
2677 /* Disable PCF mode */
2678 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2679 AR5K_STA_ID1_DEFAULT_ANTENNA |
2680 AR5K_STA_ID1_PCF);
2681 }
2682
2683 /*
2684 * Enable the beacon timer register
2685 */
2686 ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0);
2687
2688 /*
2689 * Start the beacon timers
2690 */
2691 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &~
2692 (AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) |
2693 AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0,
2694 AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval,
2695 AR5K_BEACON_PERIOD), AR5K_BEACON);
2696
2697 /*
2698 * Write new beacon miss threshold, if it appears to be valid
2699 * XXX: Figure out right values for min <= bs_bmiss_threshold <= max
2700 * and return if its not in range. We can test this by reading value and
2701 * setting value to a largest value and seeing which values register.
2702 */
2703
2704 AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS,
2705 state->bs_bmiss_threshold);
2706
2707 /*
2708 * Set sleep control register
2709 * XXX: Didn't find this in 5210 code but since this register
2710 * exists also in ar5k's 5210 headers i leave it as common code.
2711 */
2712 AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR,
2713 (state->bs_sleep_duration - 3) << 3);
2714
2715 /*
2716 * Set enhanced sleep registers on 5212
2717 */
2718 if (ah->ah_version == AR5K_AR5212) {
2719 if (state->bs_sleep_duration > state->bs_interval &&
2720 roundup(state->bs_sleep_duration, interval) ==
2721 state->bs_sleep_duration)
2722 interval = state->bs_sleep_duration;
2723
2724 if (state->bs_sleep_duration > dtim && (dtim == 0 ||
2725 roundup(state->bs_sleep_duration, dtim) ==
2726 state->bs_sleep_duration))
2727 dtim = state->bs_sleep_duration;
2728
2729 if (interval > dtim)
2730 return -EINVAL;
2731
2732 next_beacon = interval == dtim ? state->bs_next_dtim :
2733 state->bs_next_beacon;
2734
2735 ath5k_hw_reg_write(ah,
2736 AR5K_REG_SM((state->bs_next_dtim - 3) << 3,
2737 AR5K_SLEEP0_NEXT_DTIM) |
2738 AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) |
2739 AR5K_SLEEP0_ENH_SLEEP_EN |
2740 AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0);
2741
2742 ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3,
2743 AR5K_SLEEP1_NEXT_TIM) |
2744 AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1);
2745
2746 ath5k_hw_reg_write(ah,
2747 AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) |
2748 AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2);
2749 }
2750
2751 return 0;
2752}
2753
2754/*
2755 * Reset beacon timers
2756 */
2757void ath5k_hw_reset_beacon(struct ath5k_hw *ah)
2758{
2759 ATH5K_TRACE(ah->ah_sc);
2760 /*
2761 * Disable beacon timer
2762 */
2763 ath5k_hw_reg_write(ah, 0, AR5K_TIMER0);
2764
2765 /*
2766 * Disable some beacon register values
2767 */
2768 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
2769 AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF);
2770 ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON);
2771}
2772
2773/*
2774 * Wait for beacon queue to finish
2775 */
2776int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr)
2777{
2778 unsigned int i;
2779 int ret;
2780
2781 ATH5K_TRACE(ah->ah_sc);
2782
2783 /* 5210 doesn't have QCU*/
2784 if (ah->ah_version == AR5K_AR5210) {
2785 /*
2786 * Wait for beaconn queue to finish by checking
2787 * Control Register and Beacon Status Register.
2788 */
2789 for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) {
2790 if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F)
2791 ||
2792 !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F))
2793 break;
2794 udelay(10);
2795 }
2796
2797 /* Timeout... */
2798 if (i <= 0) {
2799 /*
2800 * Re-schedule the beacon queue
2801 */
2802 ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1);
2803 ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE,
2804 AR5K_BCR);
2805
2806 return -EIO;
2807 }
2808 ret = 0;
2809 } else {
2810 /*5211/5212*/
2811 ret = ath5k_hw_register_timeout(ah,
2812 AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON),
2813 AR5K_QCU_STS_FRMPENDCNT, 0, false);
2814
2815 if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON))
2816 return -EIO;
2817 }
2818
2819 return ret;
2820}
2821#endif
2822
2823/*
2824 * Update mib counters (statistics)
2825 */
2826void ath5k_hw_update_mib_counters(struct ath5k_hw *ah,
2827 struct ath5k_mib_stats *statistics)
2828{
2829 ATH5K_TRACE(ah->ah_sc);
2830 /* Read-And-Clear */
2831 statistics->ackrcv_bad += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL);
2832 statistics->rts_bad += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL);
2833 statistics->rts_good += ath5k_hw_reg_read(ah, AR5K_RTS_OK);
2834 statistics->fcs_bad += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL);
2835 statistics->beacons += ath5k_hw_reg_read(ah, AR5K_BEACON_CNT);
2836
2837 /* Reset profile count registers on 5212*/
2838 if (ah->ah_version == AR5K_AR5212) {
2839 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX);
2840 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX);
2841 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR);
2842 ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE);
2843 }
2844}
2845
2846/** ath5k_hw_set_ack_bitrate - set bitrate for ACKs
2847 *
2848 * @ah: the &struct ath5k_hw
2849 * @high: determines if to use low bit rate or now
2850 */
2851void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high)
2852{
2853 if (ah->ah_version != AR5K_AR5212)
2854 return;
2855 else {
2856 u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB;
2857 if (high)
2858 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val);
2859 else
2860 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val);
2861 }
2862}
2863
2864
2865/*
2866 * ACK/CTS Timeouts
2867 */
2868
2869/*
2870 * Set ACK timeout on PCU
2871 */
2872int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout)
2873{
2874 ATH5K_TRACE(ah->ah_sc);
2875 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK),
2876 ah->ah_turbo) <= timeout)
2877 return -EINVAL;
2878
2879 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK,
2880 ath5k_hw_htoclock(timeout, ah->ah_turbo));
2881
2882 return 0;
2883}
2884
2885/*
2886 * Read the ACK timeout from PCU
2887 */
2888unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah)
2889{
2890 ATH5K_TRACE(ah->ah_sc);
2891
2892 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
2893 AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo);
2894}
2895
2896/*
2897 * Set CTS timeout on PCU
2898 */
2899int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout)
2900{
2901 ATH5K_TRACE(ah->ah_sc);
2902 if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS),
2903 ah->ah_turbo) <= timeout)
2904 return -EINVAL;
2905
2906 AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS,
2907 ath5k_hw_htoclock(timeout, ah->ah_turbo));
2908
2909 return 0;
2910}
2911
2912/*
2913 * Read CTS timeout from PCU
2914 */
2915unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah)
2916{
2917 ATH5K_TRACE(ah->ah_sc);
2918 return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah,
2919 AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo);
2920}
2921
2922/*
2923 * Key table (WEP) functions
2924 */
2925
2926int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry)
2927{
2928 unsigned int i;
2929
2930 ATH5K_TRACE(ah->ah_sc);
2931 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
2932
2933 for (i = 0; i < AR5K_KEYCACHE_SIZE; i++)
2934 ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i));
2935
2936 /* Set NULL encryption on non-5210*/
2937 if (ah->ah_version != AR5K_AR5210)
2938 ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL,
2939 AR5K_KEYTABLE_TYPE(entry));
2940
2941 return 0;
2942}
2943
2944int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry)
2945{
2946 ATH5K_TRACE(ah->ah_sc);
2947 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
2948
2949 /* Check the validation flag at the end of the entry */
2950 return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) &
2951 AR5K_KEYTABLE_VALID;
2952}
2953
2954int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry,
2955 const struct ieee80211_key_conf *key, const u8 *mac)
2956{
2957 unsigned int i;
2958 __le32 key_v[5] = {};
2959 u32 keytype;
2960
2961 ATH5K_TRACE(ah->ah_sc);
2962
2963 /* key->keylen comes in from mac80211 in bytes */
2964
2965 if (key->keylen > AR5K_KEYTABLE_SIZE / 8)
2966 return -EOPNOTSUPP;
2967
2968 switch (key->keylen) {
2969 /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */
2970 case 40 / 8:
2971 memcpy(&key_v[0], key->key, 5);
2972 keytype = AR5K_KEYTABLE_TYPE_40;
2973 break;
2974
2975 /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */
2976 case 104 / 8:
2977 memcpy(&key_v[0], &key->key[0], 6);
2978 memcpy(&key_v[2], &key->key[6], 6);
2979 memcpy(&key_v[4], &key->key[12], 1);
2980 keytype = AR5K_KEYTABLE_TYPE_104;
2981 break;
2982 /* WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */
2983 case 128 / 8:
2984 memcpy(&key_v[0], &key->key[0], 6);
2985 memcpy(&key_v[2], &key->key[6], 6);
2986 memcpy(&key_v[4], &key->key[12], 4);
2987 keytype = AR5K_KEYTABLE_TYPE_128;
2988 break;
2989
2990 default:
2991 return -EINVAL; /* shouldn't happen */
2992 }
2993
2994 for (i = 0; i < ARRAY_SIZE(key_v); i++)
2995 ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]),
2996 AR5K_KEYTABLE_OFF(entry, i));
2997
2998 ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry));
2999
3000 return ath5k_hw_set_key_lladdr(ah, entry, mac);
3001}
3002
3003int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac)
3004{
3005 u32 low_id, high_id;
3006
3007 ATH5K_TRACE(ah->ah_sc);
3008 /* Invalid entry (key table overflow) */
3009 AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE);
3010
3011 /* MAC may be NULL if it's a broadcast key. In this case no need to
3012 * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */
3013 if (unlikely(mac == NULL)) {
3014 low_id = 0xffffffff;
3015 high_id = 0xffff | AR5K_KEYTABLE_VALID;
3016 } else {
3017 low_id = AR5K_LOW_ID(mac);
3018 high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID;
3019 }
3020
3021 ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry));
3022 ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry));
3023
3024 return 0;
3025}
3026
3027
3028/********************************************\
3029Queue Control Unit, DFS Control Unit Functions
3030\********************************************/
3031
3032/*
3033 * Initialize a transmit queue
3034 */
3035int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type,
3036 struct ath5k_txq_info *queue_info)
3037{
3038 unsigned int queue;
3039 int ret;
3040
3041 ATH5K_TRACE(ah->ah_sc);
3042
3043 /*
3044 * Get queue by type
3045 */
3046 /*5210 only has 2 queues*/
3047 if (ah->ah_version == AR5K_AR5210) {
3048 switch (queue_type) {
3049 case AR5K_TX_QUEUE_DATA:
3050 queue = AR5K_TX_QUEUE_ID_NOQCU_DATA;
3051 break;
3052 case AR5K_TX_QUEUE_BEACON:
3053 case AR5K_TX_QUEUE_CAB:
3054 queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON;
3055 break;
3056 default:
3057 return -EINVAL;
3058 }
3059 } else {
3060 switch (queue_type) {
3061 case AR5K_TX_QUEUE_DATA:
3062 for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
3063 ah->ah_txq[queue].tqi_type !=
3064 AR5K_TX_QUEUE_INACTIVE; queue++) {
3065
3066 if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
3067 return -EINVAL;
3068 }
3069 break;
3070 case AR5K_TX_QUEUE_UAPSD:
3071 queue = AR5K_TX_QUEUE_ID_UAPSD;
3072 break;
3073 case AR5K_TX_QUEUE_BEACON:
3074 queue = AR5K_TX_QUEUE_ID_BEACON;
3075 break;
3076 case AR5K_TX_QUEUE_CAB:
3077 queue = AR5K_TX_QUEUE_ID_CAB;
3078 break;
3079 case AR5K_TX_QUEUE_XR_DATA:
3080 if (ah->ah_version != AR5K_AR5212)
3081 ATH5K_ERR(ah->ah_sc,
3082 "XR data queues only supported in"
3083 " 5212!\n");
3084 queue = AR5K_TX_QUEUE_ID_XR_DATA;
3085 break;
3086 default:
3087 return -EINVAL;
3088 }
3089 }
3090
3091 /*
3092 * Setup internal queue structure
3093 */
3094 memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info));
3095 ah->ah_txq[queue].tqi_type = queue_type;
3096
3097 if (queue_info != NULL) {
3098 queue_info->tqi_type = queue_type;
3099 ret = ath5k_hw_setup_tx_queueprops(ah, queue, queue_info);
3100 if (ret)
3101 return ret;
3102 }
3103 /*
3104 * We use ah_txq_status to hold a temp value for
3105 * the Secondary interrupt mask registers on 5211+
3106 * check out ath5k_hw_reset_tx_queue
3107 */
3108 AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue);
3109
3110 return queue;
3111}
3112
3113/*
3114 * Setup a transmit queue
3115 */
3116int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue,
3117 const struct ath5k_txq_info *queue_info)
3118{
3119 ATH5K_TRACE(ah->ah_sc);
3120 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3121
3122 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3123 return -EIO;
3124
3125 memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info));
3126
3127 /*XXX: Is this supported on 5210 ?*/
3128 if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA &&
3129 ((queue_info->tqi_subtype == AR5K_WME_AC_VI) ||
3130 (queue_info->tqi_subtype == AR5K_WME_AC_VO))) ||
3131 queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD)
3132 ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS;
3133
3134 return 0;
3135}
3136
3137/*
3138 * Get properties for a specific transmit queue
3139 */
3140int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue,
3141 struct ath5k_txq_info *queue_info)
3142{
3143 ATH5K_TRACE(ah->ah_sc);
3144 memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info));
3145 return 0;
3146}
3147
3148/*
3149 * Set a transmit queue inactive
3150 */
3151void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3152{
3153 ATH5K_TRACE(ah->ah_sc);
3154 if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num))
3155 return;
3156
3157 /* This queue will be skipped in further operations */
3158 ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE;
3159 /*For SIMR setup*/
3160 AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue);
3161}
3162
3163/*
3164 * Set DFS params for a transmit queue
3165 */
3166int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue)
3167{
3168 u32 cw_min, cw_max, retry_lg, retry_sh;
3169 struct ath5k_txq_info *tq = &ah->ah_txq[queue];
3170
3171 ATH5K_TRACE(ah->ah_sc);
3172 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3173
3174 tq = &ah->ah_txq[queue];
3175
3176 if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE)
3177 return 0;
3178
3179 if (ah->ah_version == AR5K_AR5210) {
3180 /* Only handle data queues, others will be ignored */
3181 if (tq->tqi_type != AR5K_TX_QUEUE_DATA)
3182 return 0;
3183
3184 /* Set Slot time */
3185 ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
3186 AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME,
3187 AR5K_SLOT_TIME);
3188 /* Set ACK_CTS timeout */
3189 ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
3190 AR5K_INIT_ACK_CTS_TIMEOUT_TURBO :
3191 AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME);
3192 /* Set Transmit Latency */
3193 ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
3194 AR5K_INIT_TRANSMIT_LATENCY_TURBO :
3195 AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210);
3196 /* Set IFS0 */
3197 if (ah->ah_turbo == true)
3198 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO +
3199 (ah->ah_aifs + tq->tqi_aifs) *
3200 AR5K_INIT_SLOT_TIME_TURBO) <<
3201 AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO,
3202 AR5K_IFS0);
3203 else
3204 ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS +
3205 (ah->ah_aifs + tq->tqi_aifs) *
3206 AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) |
3207 AR5K_INIT_SIFS, AR5K_IFS0);
3208
3209 /* Set IFS1 */
3210 ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
3211 AR5K_INIT_PROTO_TIME_CNTRL_TURBO :
3212 AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1);
3213 /* Set PHY register 0x9844 (??) */
3214 ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
3215 (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x38 :
3216 (ath5k_hw_reg_read(ah, AR5K_PHY(17)) & ~0x7F) | 0x1C,
3217 AR5K_PHY(17));
3218 /* Set Frame Control Register */
3219 ath5k_hw_reg_write(ah, ah->ah_turbo == true ?
3220 (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE |
3221 AR5K_PHY_TURBO_SHORT | 0x2020) :
3222 (AR5K_PHY_FRAME_CTL_INI | 0x1020),
3223 AR5K_PHY_FRAME_CTL_5210);
3224 }
3225
3226 /*
3227 * Calculate cwmin/max by channel mode
3228 */
3229 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN;
3230 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX;
3231 ah->ah_aifs = AR5K_TUNE_AIFS;
3232 /*XR is only supported on 5212*/
3233 if (IS_CHAN_XR(ah->ah_current_channel) &&
3234 ah->ah_version == AR5K_AR5212) {
3235 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR;
3236 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR;
3237 ah->ah_aifs = AR5K_TUNE_AIFS_XR;
3238 /*B mode is not supported on 5210*/
3239 } else if (IS_CHAN_B(ah->ah_current_channel) &&
3240 ah->ah_version != AR5K_AR5210) {
3241 cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B;
3242 cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B;
3243 ah->ah_aifs = AR5K_TUNE_AIFS_11B;
3244 }
3245
3246 cw_min = 1;
3247 while (cw_min < ah->ah_cw_min)
3248 cw_min = (cw_min << 1) | 1;
3249
3250 cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) :
3251 ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1);
3252 cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) :
3253 ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1);
3254
3255 /*
3256 * Calculate and set retry limits
3257 */
3258 if (ah->ah_software_retry == true) {
3259 /* XXX Need to test this */
3260 retry_lg = ah->ah_limit_tx_retries;
3261 retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ?
3262 AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg;
3263 } else {
3264 retry_lg = AR5K_INIT_LG_RETRY;
3265 retry_sh = AR5K_INIT_SH_RETRY;
3266 }
3267
3268 /*No QCU/DCU [5210]*/
3269 if (ah->ah_version == AR5K_AR5210) {
3270 ath5k_hw_reg_write(ah,
3271 (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S)
3272 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3273 AR5K_NODCU_RETRY_LMT_SLG_RETRY)
3274 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3275 AR5K_NODCU_RETRY_LMT_SSH_RETRY)
3276 | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY)
3277 | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY),
3278 AR5K_NODCU_RETRY_LMT);
3279 } else {
3280 /*QCU/DCU [5211+]*/
3281 ath5k_hw_reg_write(ah,
3282 AR5K_REG_SM(AR5K_INIT_SLG_RETRY,
3283 AR5K_DCU_RETRY_LMT_SLG_RETRY) |
3284 AR5K_REG_SM(AR5K_INIT_SSH_RETRY,
3285 AR5K_DCU_RETRY_LMT_SSH_RETRY) |
3286 AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) |
3287 AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY),
3288 AR5K_QUEUE_DFS_RETRY_LIMIT(queue));
3289
3290 /*===Rest is also for QCU/DCU only [5211+]===*/
3291
3292 /*
3293 * Set initial content window (cw_min/cw_max)
3294 * and arbitrated interframe space (aifs)...
3295 */
3296 ath5k_hw_reg_write(ah,
3297 AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) |
3298 AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) |
3299 AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs,
3300 AR5K_DCU_LCL_IFS_AIFS),
3301 AR5K_QUEUE_DFS_LOCAL_IFS(queue));
3302
3303 /*
3304 * Set misc registers
3305 */
3306 ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY,
3307 AR5K_QUEUE_MISC(queue));
3308
3309 if (tq->tqi_cbr_period) {
3310 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period,
3311 AR5K_QCU_CBRCFG_INTVAL) |
3312 AR5K_REG_SM(tq->tqi_cbr_overflow_limit,
3313 AR5K_QCU_CBRCFG_ORN_THRES),
3314 AR5K_QUEUE_CBRCFG(queue));
3315 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3316 AR5K_QCU_MISC_FRSHED_CBR);
3317 if (tq->tqi_cbr_overflow_limit)
3318 AR5K_REG_ENABLE_BITS(ah,
3319 AR5K_QUEUE_MISC(queue),
3320 AR5K_QCU_MISC_CBR_THRES_ENABLE);
3321 }
3322
3323 if (tq->tqi_ready_time)
3324 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time,
3325 AR5K_QCU_RDYTIMECFG_INTVAL) |
3326 AR5K_QCU_RDYTIMECFG_ENABLE,
3327 AR5K_QUEUE_RDYTIMECFG(queue));
3328
3329 if (tq->tqi_burst_time) {
3330 ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time,
3331 AR5K_DCU_CHAN_TIME_DUR) |
3332 AR5K_DCU_CHAN_TIME_ENABLE,
3333 AR5K_QUEUE_DFS_CHANNEL_TIME(queue));
3334
3335 if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)
3336 AR5K_REG_ENABLE_BITS(ah,
3337 AR5K_QUEUE_MISC(queue),
3338 AR5K_QCU_MISC_TXE);
3339 }
3340
3341 if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE)
3342 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS,
3343 AR5K_QUEUE_DFS_MISC(queue));
3344
3345 if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
3346 ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG,
3347 AR5K_QUEUE_DFS_MISC(queue));
3348
3349 /*
3350 * Set registers by queue type
3351 */
3352 switch (tq->tqi_type) {
3353 case AR5K_TX_QUEUE_BEACON:
3354 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3355 AR5K_QCU_MISC_FRSHED_DBA_GT |
3356 AR5K_QCU_MISC_CBREXP_BCN |
3357 AR5K_QCU_MISC_BCN_ENABLE);
3358
3359 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3360 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3361 AR5K_DCU_MISC_ARBLOCK_CTL_S) |
3362 AR5K_DCU_MISC_POST_FR_BKOFF_DIS |
3363 AR5K_DCU_MISC_BCN_ENABLE);
3364
3365 ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL -
3366 (AR5K_TUNE_SW_BEACON_RESP -
3367 AR5K_TUNE_DMA_BEACON_RESP) -
3368 AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) |
3369 AR5K_QCU_RDYTIMECFG_ENABLE,
3370 AR5K_QUEUE_RDYTIMECFG(queue));
3371 break;
3372
3373 case AR5K_TX_QUEUE_CAB:
3374 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3375 AR5K_QCU_MISC_FRSHED_DBA_GT |
3376 AR5K_QCU_MISC_CBREXP |
3377 AR5K_QCU_MISC_CBREXP_BCN);
3378
3379 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue),
3380 (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL <<
3381 AR5K_DCU_MISC_ARBLOCK_CTL_S));
3382 break;
3383
3384 case AR5K_TX_QUEUE_UAPSD:
3385 AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue),
3386 AR5K_QCU_MISC_CBREXP);
3387 break;
3388
3389 case AR5K_TX_QUEUE_DATA:
3390 default:
3391 break;
3392 }
3393
3394 /*
3395 * Enable interrupts for this tx queue
3396 * in the secondary interrupt mask registers
3397 */
3398 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE)
3399 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue);
3400
3401 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE)
3402 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue);
3403
3404 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE)
3405 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue);
3406
3407 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE)
3408 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue);
3409
3410 if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE)
3411 AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue);
3412
3413
3414 /* Update secondary interrupt mask registers */
3415 ah->ah_txq_imr_txok &= ah->ah_txq_status;
3416 ah->ah_txq_imr_txerr &= ah->ah_txq_status;
3417 ah->ah_txq_imr_txurn &= ah->ah_txq_status;
3418 ah->ah_txq_imr_txdesc &= ah->ah_txq_status;
3419 ah->ah_txq_imr_txeol &= ah->ah_txq_status;
3420
3421 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok,
3422 AR5K_SIMR0_QCU_TXOK) |
3423 AR5K_REG_SM(ah->ah_txq_imr_txdesc,
3424 AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0);
3425 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr,
3426 AR5K_SIMR1_QCU_TXERR) |
3427 AR5K_REG_SM(ah->ah_txq_imr_txeol,
3428 AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1);
3429 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn,
3430 AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2);
3431 }
3432
3433 return 0;
3434}
3435
3436/*
3437 * Get number of pending frames
3438 * for a specific queue [5211+]
3439 */
3440u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) {
3441 ATH5K_TRACE(ah->ah_sc);
3442 AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num);
3443
3444 /* Return if queue is declared inactive */
3445 if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE)
3446 return false;
3447
3448 /* XXX: How about AR5K_CFG_TXCNT ? */
3449 if (ah->ah_version == AR5K_AR5210)
3450 return false;
3451
3452 return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT;
3453}
3454
3455/*
3456 * Set slot time
3457 */
3458int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time)
3459{
3460 ATH5K_TRACE(ah->ah_sc);
3461 if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX)
3462 return -EINVAL;
3463
3464 if (ah->ah_version == AR5K_AR5210)
3465 ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time,
3466 ah->ah_turbo), AR5K_SLOT_TIME);
3467 else
3468 ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT);
3469
3470 return 0;
3471}
3472
3473/*
3474 * Get slot time
3475 */
3476unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah)
3477{
3478 ATH5K_TRACE(ah->ah_sc);
3479 if (ah->ah_version == AR5K_AR5210)
3480 return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah,
3481 AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo);
3482 else
3483 return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff;
3484}
3485
3486
3487/******************************\
3488 Hardware Descriptor Functions
3489\******************************/
3490
3491/*
3492 * TX Descriptor
3493 */
3494
3495/*
3496 * Initialize the 2-word tx descriptor on 5210/5211
3497 */
3498static int
3499ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3500 unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type,
3501 unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0,
3502 unsigned int key_index, unsigned int antenna_mode, unsigned int flags,
3503 unsigned int rtscts_rate, unsigned int rtscts_duration)
3504{
3505 u32 frame_type;
3506 struct ath5k_hw_2w_tx_desc *tx_desc;
3507 unsigned int buff_len;
3508
3509 tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0;
3510
3511 /*
3512 * Validate input
3513 * - Zero retries don't make sense.
3514 * - A zero rate will put the HW into a mode where it continously sends
3515 * noise on the channel, so it is important to avoid this.
3516 */
3517 if (unlikely(tx_tries0 == 0)) {
3518 ATH5K_ERR(ah->ah_sc, "zero retries\n");
3519 WARN_ON(1);
3520 return -EINVAL;
3521 }
3522 if (unlikely(tx_rate0 == 0)) {
3523 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3524 WARN_ON(1);
3525 return -EINVAL;
3526 }
3527
3528 /* Clear status descriptor */
3529 memset(desc->ds_hw, 0, sizeof(struct ath5k_hw_tx_status));
3530
3531 /* Initialize control descriptor */
3532 tx_desc->tx_control_0 = 0;
3533 tx_desc->tx_control_1 = 0;
3534
3535 /* Setup control descriptor */
3536
3537 /* Verify and set frame length */
3538 if (pkt_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN)
3539 return -EINVAL;
3540
3541 tx_desc->tx_control_0 = pkt_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN;
3542
3543 /* Verify and set buffer length */
3544 buff_len = pkt_len - FCS_LEN;
3545
3546 /* NB: beacon's BufLen must be a multiple of 4 bytes */
3547 if(type == AR5K_PKT_TYPE_BEACON)
3548 buff_len = roundup(buff_len, 4);
3549
3550 if (buff_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN)
3551 return -EINVAL;
3552
3553 tx_desc->tx_control_1 = buff_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN;
3554
3555 /*
3556 * Verify and set header length
3557 * XXX: I only found that on 5210 code, does it work on 5211 ?
3558 */
3559 if (ah->ah_version == AR5K_AR5210) {
3560 if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN)
3561 return -EINVAL;
3562 tx_desc->tx_control_0 |=
3563 AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN);
3564 }
3565
3566 /*Diferences between 5210-5211*/
3567 if (ah->ah_version == AR5K_AR5210) {
3568 switch (type) {
3569 case AR5K_PKT_TYPE_BEACON:
3570 case AR5K_PKT_TYPE_PROBE_RESP:
3571 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY;
3572 case AR5K_PKT_TYPE_PIFS:
3573 frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS;
3574 default:
3575 frame_type = type /*<< 2 ?*/;
3576 }
3577
3578 tx_desc->tx_control_0 |=
3579 AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) |
3580 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3581 } else {
3582 tx_desc->tx_control_0 |=
3583 AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) |
3584 AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT);
3585 tx_desc->tx_control_1 |=
3586 AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE);
3587 }
3588#define _TX_FLAGS(_c, _flag) \
3589 if (flags & AR5K_TXDESC_##_flag) \
3590 tx_desc->tx_control_##_c |= \
3591 AR5K_2W_TX_DESC_CTL##_c##_##_flag
3592
3593 _TX_FLAGS(0, CLRDMASK);
3594 _TX_FLAGS(0, VEOL);
3595 _TX_FLAGS(0, INTREQ);
3596 _TX_FLAGS(0, RTSENA);
3597 _TX_FLAGS(1, NOACK);
3598
3599#undef _TX_FLAGS
3600
3601 /*
3602 * WEP crap
3603 */
3604 if (key_index != AR5K_TXKEYIX_INVALID) {
3605 tx_desc->tx_control_0 |=
3606 AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
3607 tx_desc->tx_control_1 |=
3608 AR5K_REG_SM(key_index,
3609 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3610 }
3611
3612 /*
3613 * RTS/CTS Duration [5210 ?]
3614 */
3615 if ((ah->ah_version == AR5K_AR5210) &&
3616 (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)))
3617 tx_desc->tx_control_1 |= rtscts_duration &
3618 AR5K_2W_TX_DESC_CTL1_RTS_DURATION;
3619
3620 return 0;
3621}
3622
3623/*
3624 * Initialize the 4-word tx descriptor on 5212
3625 */
3626static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah,
3627 struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len,
3628 enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0,
3629 unsigned int tx_tries0, unsigned int key_index,
3630 unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate,
3631 unsigned int rtscts_duration)
3632{
3633 struct ath5k_hw_4w_tx_desc *tx_desc;
3634 struct ath5k_hw_tx_status *tx_status;
3635 unsigned int buff_len;
3636
3637 ATH5K_TRACE(ah->ah_sc);
3638 tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
3639 tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2];
3640
3641 /*
3642 * Validate input
3643 * - Zero retries don't make sense.
3644 * - A zero rate will put the HW into a mode where it continously sends
3645 * noise on the channel, so it is important to avoid this.
3646 */
3647 if (unlikely(tx_tries0 == 0)) {
3648 ATH5K_ERR(ah->ah_sc, "zero retries\n");
3649 WARN_ON(1);
3650 return -EINVAL;
3651 }
3652 if (unlikely(tx_rate0 == 0)) {
3653 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3654 WARN_ON(1);
3655 return -EINVAL;
3656 }
3657
3658 /* Clear status descriptor */
3659 memset(tx_status, 0, sizeof(struct ath5k_hw_tx_status));
3660
3661 /* Initialize control descriptor */
3662 tx_desc->tx_control_0 = 0;
3663 tx_desc->tx_control_1 = 0;
3664 tx_desc->tx_control_2 = 0;
3665 tx_desc->tx_control_3 = 0;
3666
3667 /* Setup control descriptor */
3668
3669 /* Verify and set frame length */
3670 if (pkt_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN)
3671 return -EINVAL;
3672
3673 tx_desc->tx_control_0 = pkt_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN;
3674
3675 /* Verify and set buffer length */
3676 buff_len = pkt_len - FCS_LEN;
3677
3678 /* NB: beacon's BufLen must be a multiple of 4 bytes */
3679 if(type == AR5K_PKT_TYPE_BEACON)
3680 buff_len = roundup(buff_len, 4);
3681
3682 if (buff_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN)
3683 return -EINVAL;
3684
3685 tx_desc->tx_control_1 = buff_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN;
3686
3687 tx_desc->tx_control_0 |=
3688 AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) |
3689 AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT);
3690 tx_desc->tx_control_1 |= AR5K_REG_SM(type,
3691 AR5K_4W_TX_DESC_CTL1_FRAME_TYPE);
3692 tx_desc->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES,
3693 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0);
3694 tx_desc->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
3695
3696#define _TX_FLAGS(_c, _flag) \
3697 if (flags & AR5K_TXDESC_##_flag) \
3698 tx_desc->tx_control_##_c |= \
3699 AR5K_4W_TX_DESC_CTL##_c##_##_flag
3700
3701 _TX_FLAGS(0, CLRDMASK);
3702 _TX_FLAGS(0, VEOL);
3703 _TX_FLAGS(0, INTREQ);
3704 _TX_FLAGS(0, RTSENA);
3705 _TX_FLAGS(0, CTSENA);
3706 _TX_FLAGS(1, NOACK);
3707
3708#undef _TX_FLAGS
3709
3710 /*
3711 * WEP crap
3712 */
3713 if (key_index != AR5K_TXKEYIX_INVALID) {
3714 tx_desc->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID;
3715 tx_desc->tx_control_1 |= AR5K_REG_SM(key_index,
3716 AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX);
3717 }
3718
3719 /*
3720 * RTS/CTS
3721 */
3722 if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) {
3723 if ((flags & AR5K_TXDESC_RTSENA) &&
3724 (flags & AR5K_TXDESC_CTSENA))
3725 return -EINVAL;
3726 tx_desc->tx_control_2 |= rtscts_duration &
3727 AR5K_4W_TX_DESC_CTL2_RTS_DURATION;
3728 tx_desc->tx_control_3 |= AR5K_REG_SM(rtscts_rate,
3729 AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE);
3730 }
3731
3732 return 0;
3733}
3734
3735/*
3736 * Initialize a 4-word multirate tx descriptor on 5212
3737 */
3738static bool
3739ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3740 unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2,
3741 unsigned int tx_rate3, u_int tx_tries3)
3742{
3743 struct ath5k_hw_4w_tx_desc *tx_desc;
3744
3745 /*
3746 * Rates can be 0 as long as the retry count is 0 too.
3747 * A zero rate and nonzero retry count will put the HW into a mode where
3748 * it continously sends noise on the channel, so it is important to
3749 * avoid this.
3750 */
3751 if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) ||
3752 (tx_rate2 == 0 && tx_tries2 != 0) ||
3753 (tx_rate3 == 0 && tx_tries3 != 0))) {
3754 ATH5K_ERR(ah->ah_sc, "zero rate\n");
3755 WARN_ON(1);
3756 return -EINVAL;
3757 }
3758
3759 if (ah->ah_version == AR5K_AR5212) {
3760 tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
3761
3762#define _XTX_TRIES(_n) \
3763 if (tx_tries##_n) { \
3764 tx_desc->tx_control_2 |= \
3765 AR5K_REG_SM(tx_tries##_n, \
3766 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \
3767 tx_desc->tx_control_3 |= \
3768 AR5K_REG_SM(tx_rate##_n, \
3769 AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \
3770 }
3771
3772 _XTX_TRIES(1);
3773 _XTX_TRIES(2);
3774 _XTX_TRIES(3);
3775
3776#undef _XTX_TRIES
3777
3778 return true;
3779 }
3780
3781 return false;
3782}
3783
3784/*
3785 * Proccess the tx status descriptor on 5210/5211
3786 */
3787static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah,
3788 struct ath5k_desc *desc)
3789{
3790 struct ath5k_hw_tx_status *tx_status;
3791 struct ath5k_hw_2w_tx_desc *tx_desc;
3792
3793 tx_desc = (struct ath5k_hw_2w_tx_desc *)&desc->ds_ctl0;
3794 tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[0];
3795
3796 /* No frame has been send or error */
3797 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
3798 return -EINPROGRESS;
3799
3800 /*
3801 * Get descriptor status
3802 */
3803 desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
3804 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
3805 desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
3806 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
3807 desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
3808 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
3809 /*TODO: desc->ds_us.tx.ts_virtcol + test*/
3810 desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
3811 AR5K_DESC_TX_STATUS1_SEQ_NUM);
3812 desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
3813 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
3814 desc->ds_us.tx.ts_antenna = 1;
3815 desc->ds_us.tx.ts_status = 0;
3816 desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_0,
3817 AR5K_2W_TX_DESC_CTL0_XMIT_RATE);
3818
3819 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
3820 if (tx_status->tx_status_0 &
3821 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
3822 desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY;
3823
3824 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
3825 desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO;
3826
3827 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
3828 desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT;
3829 }
3830
3831 return 0;
3832}
3833
3834/*
3835 * Proccess a tx descriptor on 5212
3836 */
3837static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah,
3838 struct ath5k_desc *desc)
3839{
3840 struct ath5k_hw_tx_status *tx_status;
3841 struct ath5k_hw_4w_tx_desc *tx_desc;
3842
3843 ATH5K_TRACE(ah->ah_sc);
3844 tx_desc = (struct ath5k_hw_4w_tx_desc *)&desc->ds_ctl0;
3845 tx_status = (struct ath5k_hw_tx_status *)&desc->ds_hw[2];
3846
3847 /* No frame has been send or error */
3848 if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0))
3849 return -EINPROGRESS;
3850
3851 /*
3852 * Get descriptor status
3853 */
3854 desc->ds_us.tx.ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0,
3855 AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP);
3856 desc->ds_us.tx.ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0,
3857 AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT);
3858 desc->ds_us.tx.ts_longretry = AR5K_REG_MS(tx_status->tx_status_0,
3859 AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT);
3860 desc->ds_us.tx.ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1,
3861 AR5K_DESC_TX_STATUS1_SEQ_NUM);
3862 desc->ds_us.tx.ts_rssi = AR5K_REG_MS(tx_status->tx_status_1,
3863 AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH);
3864 desc->ds_us.tx.ts_antenna = (tx_status->tx_status_1 &
3865 AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1;
3866 desc->ds_us.tx.ts_status = 0;
3867
3868 switch (AR5K_REG_MS(tx_status->tx_status_1,
3869 AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) {
3870 case 0:
3871 desc->ds_us.tx.ts_rate = tx_desc->tx_control_3 &
3872 AR5K_4W_TX_DESC_CTL3_XMIT_RATE0;
3873 break;
3874 case 1:
3875 desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3,
3876 AR5K_4W_TX_DESC_CTL3_XMIT_RATE1);
3877 desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2,
3878 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1);
3879 break;
3880 case 2:
3881 desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3,
3882 AR5K_4W_TX_DESC_CTL3_XMIT_RATE2);
3883 desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2,
3884 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2);
3885 break;
3886 case 3:
3887 desc->ds_us.tx.ts_rate = AR5K_REG_MS(tx_desc->tx_control_3,
3888 AR5K_4W_TX_DESC_CTL3_XMIT_RATE3);
3889 desc->ds_us.tx.ts_longretry +=AR5K_REG_MS(tx_desc->tx_control_2,
3890 AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3);
3891 break;
3892 }
3893
3894 if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){
3895 if (tx_status->tx_status_0 &
3896 AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES)
3897 desc->ds_us.tx.ts_status |= AR5K_TXERR_XRETRY;
3898
3899 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN)
3900 desc->ds_us.tx.ts_status |= AR5K_TXERR_FIFO;
3901
3902 if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED)
3903 desc->ds_us.tx.ts_status |= AR5K_TXERR_FILT;
3904 }
3905
3906 return 0;
3907}
3908
3909/*
3910 * RX Descriptor
3911 */
3912
3913/*
3914 * Initialize an rx descriptor
3915 */
3916int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc,
3917 u32 size, unsigned int flags)
3918{
3919 struct ath5k_rx_desc *rx_desc;
3920
3921 ATH5K_TRACE(ah->ah_sc);
3922 rx_desc = (struct ath5k_rx_desc *)&desc->ds_ctl0;
3923
3924 /*
3925 *Clear ds_hw
3926 * If we don't clean the status descriptor,
3927 * while scanning we get too many results,
3928 * most of them virtual, after some secs
3929 * of scanning system hangs. M.F.
3930 */
3931 memset(desc->ds_hw, 0, sizeof(desc->ds_hw));
3932
3933 /*Initialize rx descriptor*/
3934 rx_desc->rx_control_0 = 0;
3935 rx_desc->rx_control_1 = 0;
3936
3937 /* Setup descriptor */
3938 rx_desc->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN;
3939 if (unlikely(rx_desc->rx_control_1 != size))
3940 return -EINVAL;
3941
3942 if (flags & AR5K_RXDESC_INTREQ)
3943 rx_desc->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ;
3944
3945 return 0;
3946}
3947
3948/*
3949 * Proccess the rx status descriptor on 5210/5211
3950 */
3951static int ath5k_hw_proc_old_rx_status(struct ath5k_hw *ah,
3952 struct ath5k_desc *desc)
3953{
3954 struct ath5k_hw_old_rx_status *rx_status;
3955
3956 rx_status = (struct ath5k_hw_old_rx_status *)&desc->ds_hw[0];
3957
3958 /* No frame received / not ready */
3959 if (unlikely((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_DONE)
3960 == 0))
3961 return -EINPROGRESS;
3962
3963 /*
3964 * Frame receive status
3965 */
3966 desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
3967 AR5K_OLD_RX_DESC_STATUS0_DATA_LEN;
3968 desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
3969 AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL);
3970 desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
3971 AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE);
3972 desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
3973 AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA;
3974 desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
3975 AR5K_OLD_RX_DESC_STATUS0_MORE;
3976 desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
3977 AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
3978 desc->ds_us.rx.rs_status = 0;
3979
3980 /*
3981 * Key table status
3982 */
3983 if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID)
3984 desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
3985 AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX);
3986 else
3987 desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID;
3988
3989 /*
3990 * Receive/descriptor errors
3991 */
3992 if ((rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK)
3993 == 0) {
3994 if (rx_status->rx_status_1 & AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR)
3995 desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC;
3996
3997 if (rx_status->rx_status_1 &
3998 AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN)
3999 desc->ds_us.rx.rs_status |= AR5K_RXERR_FIFO;
4000
4001 if (rx_status->rx_status_1 &
4002 AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR) {
4003 desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY;
4004 desc->ds_us.rx.rs_phyerr =
4005 AR5K_REG_MS(rx_status->rx_status_1,
4006 AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR);
4007 }
4008
4009 if (rx_status->rx_status_1 &
4010 AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
4011 desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT;
4012 }
4013
4014 return 0;
4015}
4016
4017/*
4018 * Proccess the rx status descriptor on 5212
4019 */
4020static int ath5k_hw_proc_new_rx_status(struct ath5k_hw *ah,
4021 struct ath5k_desc *desc)
4022{
4023 struct ath5k_hw_new_rx_status *rx_status;
4024 struct ath5k_hw_rx_error *rx_err;
4025
4026 ATH5K_TRACE(ah->ah_sc);
4027 rx_status = (struct ath5k_hw_new_rx_status *)&desc->ds_hw[0];
4028
4029 /* Overlay on error */
4030 rx_err = (struct ath5k_hw_rx_error *)&desc->ds_hw[0];
4031
4032 /* No frame received / not ready */
4033 if (unlikely((rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_DONE)
4034 == 0))
4035 return -EINPROGRESS;
4036
4037 /*
4038 * Frame receive status
4039 */
4040 desc->ds_us.rx.rs_datalen = rx_status->rx_status_0 &
4041 AR5K_NEW_RX_DESC_STATUS0_DATA_LEN;
4042 desc->ds_us.rx.rs_rssi = AR5K_REG_MS(rx_status->rx_status_0,
4043 AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL);
4044 desc->ds_us.rx.rs_rate = AR5K_REG_MS(rx_status->rx_status_0,
4045 AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE);
4046 desc->ds_us.rx.rs_antenna = rx_status->rx_status_0 &
4047 AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA;
4048 desc->ds_us.rx.rs_more = rx_status->rx_status_0 &
4049 AR5K_NEW_RX_DESC_STATUS0_MORE;
4050 desc->ds_us.rx.rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1,
4051 AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP);
4052 desc->ds_us.rx.rs_status = 0;
4053
4054 /*
4055 * Key table status
4056 */
4057 if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID)
4058 desc->ds_us.rx.rs_keyix = AR5K_REG_MS(rx_status->rx_status_1,
4059 AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX);
4060 else
4061 desc->ds_us.rx.rs_keyix = AR5K_RXKEYIX_INVALID;
4062
4063 /*
4064 * Receive/descriptor errors
4065 */
4066 if ((rx_status->rx_status_1 &
4067 AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) {
4068 if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR)
4069 desc->ds_us.rx.rs_status |= AR5K_RXERR_CRC;
4070
4071 if (rx_status->rx_status_1 &
4072 AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR) {
4073 desc->ds_us.rx.rs_status |= AR5K_RXERR_PHY;
4074 desc->ds_us.rx.rs_phyerr =
4075 AR5K_REG_MS(rx_err->rx_error_1,
4076 AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE);
4077 }
4078
4079 if (rx_status->rx_status_1 &
4080 AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR)
4081 desc->ds_us.rx.rs_status |= AR5K_RXERR_DECRYPT;
4082
4083 if (rx_status->rx_status_1 & AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR)
4084 desc->ds_us.rx.rs_status |= AR5K_RXERR_MIC;
4085 }
4086
4087 return 0;
4088}
4089
4090
4091/****************\
4092 GPIO Functions
4093\****************/
4094
4095/*
4096 * Set led state
4097 */
4098void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state)
4099{
4100 u32 led;
4101 /*5210 has different led mode handling*/
4102 u32 led_5210;
4103
4104 ATH5K_TRACE(ah->ah_sc);
4105
4106 /*Reset led status*/
4107 if (ah->ah_version != AR5K_AR5210)
4108 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG,
4109 AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED);
4110 else
4111 AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED);
4112
4113 /*
4114 * Some blinking values, define at your wish
4115 */
4116 switch (state) {
4117 case AR5K_LED_SCAN:
4118 case AR5K_LED_AUTH:
4119 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND;
4120 led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL;
4121 break;
4122
4123 case AR5K_LED_INIT:
4124 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE;
4125 led_5210 = AR5K_PCICFG_LED_PEND;
4126 break;
4127
4128 case AR5K_LED_ASSOC:
4129 case AR5K_LED_RUN:
4130 led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC;
4131 led_5210 = AR5K_PCICFG_LED_ASSOC;
4132 break;
4133
4134 default:
4135 led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE;
4136 led_5210 = AR5K_PCICFG_LED_PEND;
4137 break;
4138 }
4139
4140 /*Write new status to the register*/
4141 if (ah->ah_version != AR5K_AR5210)
4142 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led);
4143 else
4144 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210);
4145}
4146
4147/*
4148 * Set GPIO outputs
4149 */
4150int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio)
4151{
4152 ATH5K_TRACE(ah->ah_sc);
4153 if (gpio > AR5K_NUM_GPIO)
4154 return -EINVAL;
4155
4156 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4157 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR);
4158
4159 return 0;
4160}
4161
4162/*
4163 * Set GPIO inputs
4164 */
4165int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio)
4166{
4167 ATH5K_TRACE(ah->ah_sc);
4168 if (gpio > AR5K_NUM_GPIO)
4169 return -EINVAL;
4170
4171 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~
4172 AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR);
4173
4174 return 0;
4175}
4176
4177/*
4178 * Get GPIO state
4179 */
4180u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio)
4181{
4182 ATH5K_TRACE(ah->ah_sc);
4183 if (gpio > AR5K_NUM_GPIO)
4184 return 0xffffffff;
4185
4186 /* GPIO input magic */
4187 return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) &
4188 0x1;
4189}
4190
4191/*
4192 * Set GPIO state
4193 */
4194int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val)
4195{
4196 u32 data;
4197 ATH5K_TRACE(ah->ah_sc);
4198
4199 if (gpio > AR5K_NUM_GPIO)
4200 return -EINVAL;
4201
4202 /* GPIO output magic */
4203 data = ath5k_hw_reg_read(ah, AR5K_GPIODO);
4204
4205 data &= ~(1 << gpio);
4206 data |= (val & 1) << gpio;
4207
4208 ath5k_hw_reg_write(ah, data, AR5K_GPIODO);
4209
4210 return 0;
4211}
4212
4213/*
4214 * Initialize the GPIO interrupt (RFKill switch)
4215 */
4216void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio,
4217 u32 interrupt_level)
4218{
4219 u32 data;
4220
4221 ATH5K_TRACE(ah->ah_sc);
4222 if (gpio > AR5K_NUM_GPIO)
4223 return;
4224
4225 /*
4226 * Set the GPIO interrupt
4227 */
4228 data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &
4229 ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH |
4230 AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) |
4231 (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA);
4232
4233 ath5k_hw_reg_write(ah, interrupt_level ? data :
4234 (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR);
4235
4236 ah->ah_imr |= AR5K_IMR_GPIO;
4237
4238 /* Enable GPIO interrupts */
4239 AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO);
4240}
4241
4242
4243/*********************************\
4244 Regulatory Domain/Channels Setup
4245\*********************************/
4246
4247u16 ath5k_get_regdomain(struct ath5k_hw *ah)
4248{
4249 u16 regdomain;
4250 enum ath5k_regdom ieee_regdomain;
4251#ifdef COUNTRYCODE
4252 u16 code;
4253#endif
4254
4255 ath5k_eeprom_regulation_domain(ah, false, &ieee_regdomain);
4256 ah->ah_capabilities.cap_regdomain.reg_hw = ieee_regdomain;
4257
4258#ifdef COUNTRYCODE
4259 /*
4260 * Get the regulation domain by country code. This will ignore
4261 * the settings found in the EEPROM.
4262 */
4263 code = ieee80211_name2countrycode(COUNTRYCODE);
4264 ieee_regdomain = ieee80211_countrycode2regdomain(code);
4265#endif
4266
4267 regdomain = ath5k_regdom_from_ieee(ieee_regdomain);
4268 ah->ah_capabilities.cap_regdomain.reg_current = regdomain;
4269
4270 return regdomain;
4271}
4272
4273
4274/****************\
4275 Misc functions
4276\****************/
4277
4278int ath5k_hw_get_capability(struct ath5k_hw *ah,
4279 enum ath5k_capability_type cap_type,
4280 u32 capability, u32 *result)
4281{
4282 ATH5K_TRACE(ah->ah_sc);
4283
4284 switch (cap_type) {
4285 case AR5K_CAP_NUM_TXQUEUES:
4286 if (result) {
4287 if (ah->ah_version == AR5K_AR5210)
4288 *result = AR5K_NUM_TX_QUEUES_NOQCU;
4289 else
4290 *result = AR5K_NUM_TX_QUEUES;
4291 goto yes;
4292 }
4293 case AR5K_CAP_VEOL:
4294 goto yes;
4295 case AR5K_CAP_COMPRESSION:
4296 if (ah->ah_version == AR5K_AR5212)
4297 goto yes;
4298 else
4299 goto no;
4300 case AR5K_CAP_BURST:
4301 goto yes;
4302 case AR5K_CAP_TPC:
4303 goto yes;
4304 case AR5K_CAP_BSSIDMASK:
4305 if (ah->ah_version == AR5K_AR5212)
4306 goto yes;
4307 else
4308 goto no;
4309 case AR5K_CAP_XR:
4310 if (ah->ah_version == AR5K_AR5212)
4311 goto yes;
4312 else
4313 goto no;
4314 default:
4315 goto no;
4316 }
4317
4318no:
4319 return -EINVAL;
4320yes:
4321 return 0;
4322}
4323
4324static int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid,
4325 u16 assoc_id)
4326{
4327 ATH5K_TRACE(ah->ah_sc);
4328
4329 if (ah->ah_version == AR5K_AR5210) {
4330 AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1,
4331 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4332 return 0;
4333 }
4334
4335 return -EIO;
4336}
4337
4338static int ath5k_hw_disable_pspoll(struct ath5k_hw *ah)
4339{
4340 ATH5K_TRACE(ah->ah_sc);
4341
4342 if (ah->ah_version == AR5K_AR5210) {
4343 AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1,
4344 AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA);
4345 return 0;
4346 }
4347
4348 return -EIO;
4349}
diff --git a/drivers/net/wireless/ath5k/hw.h b/drivers/net/wireless/ath5k/hw.h
new file mode 100644
index 000000000000..d9a7c0973f53
--- /dev/null
+++ b/drivers/net/wireless/ath5k/hw.h
@@ -0,0 +1,588 @@
1/*
2 * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org>
5 * Copyright (c) 2007 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include <linux/delay.h>
21
22/*
23 * Gain settings
24 */
25
26enum ath5k_rfgain {
27 AR5K_RFGAIN_INACTIVE = 0,
28 AR5K_RFGAIN_READ_REQUESTED,
29 AR5K_RFGAIN_NEED_CHANGE,
30};
31
32#define AR5K_GAIN_CRN_FIX_BITS_5111 4
33#define AR5K_GAIN_CRN_FIX_BITS_5112 7
34#define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112
35#define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15
36#define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20
37#define AR5K_GAIN_CCK_PROBE_CORR 5
38#define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15
39#define AR5K_GAIN_STEP_COUNT 10
40#define AR5K_GAIN_PARAM_TX_CLIP 0
41#define AR5K_GAIN_PARAM_PD_90 1
42#define AR5K_GAIN_PARAM_PD_84 2
43#define AR5K_GAIN_PARAM_GAIN_SEL 3
44#define AR5K_GAIN_PARAM_MIX_ORN 0
45#define AR5K_GAIN_PARAM_PD_138 1
46#define AR5K_GAIN_PARAM_PD_137 2
47#define AR5K_GAIN_PARAM_PD_136 3
48#define AR5K_GAIN_PARAM_PD_132 4
49#define AR5K_GAIN_PARAM_PD_131 5
50#define AR5K_GAIN_PARAM_PD_130 6
51#define AR5K_GAIN_CHECK_ADJUST(_g) \
52 ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high)
53
54struct ath5k_gain_opt_step {
55 s16 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS];
56 s32 gos_gain;
57};
58
59struct ath5k_gain {
60 u32 g_step_idx;
61 u32 g_current;
62 u32 g_target;
63 u32 g_low;
64 u32 g_high;
65 u32 g_f_corr;
66 u32 g_active;
67 const struct ath5k_gain_opt_step *g_step;
68};
69
70
71/*
72 * HW SPECIFIC STRUCTS
73 */
74
75/* Some EEPROM defines */
76#define AR5K_EEPROM_EEP_SCALE 100
77#define AR5K_EEPROM_EEP_DELTA 10
78#define AR5K_EEPROM_N_MODES 3
79#define AR5K_EEPROM_N_5GHZ_CHAN 10
80#define AR5K_EEPROM_N_2GHZ_CHAN 3
81#define AR5K_EEPROM_MAX_CHAN 10
82#define AR5K_EEPROM_N_PCDAC 11
83#define AR5K_EEPROM_N_TEST_FREQ 8
84#define AR5K_EEPROM_N_EDGES 8
85#define AR5K_EEPROM_N_INTERCEPTS 11
86#define AR5K_EEPROM_FREQ_M(_v) AR5K_EEPROM_OFF(_v, 0x7f, 0xff)
87#define AR5K_EEPROM_PCDAC_M 0x3f
88#define AR5K_EEPROM_PCDAC_START 1
89#define AR5K_EEPROM_PCDAC_STOP 63
90#define AR5K_EEPROM_PCDAC_STEP 1
91#define AR5K_EEPROM_NON_EDGE_M 0x40
92#define AR5K_EEPROM_CHANNEL_POWER 8
93#define AR5K_EEPROM_N_OBDB 4
94#define AR5K_EEPROM_OBDB_DIS 0xffff
95#define AR5K_EEPROM_CHANNEL_DIS 0xff
96#define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10)
97#define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32)
98#define AR5K_EEPROM_MAX_CTLS 32
99#define AR5K_EEPROM_N_XPD_PER_CHANNEL 4
100#define AR5K_EEPROM_N_XPD0_POINTS 4
101#define AR5K_EEPROM_N_XPD3_POINTS 3
102#define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35
103#define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55
104#define AR5K_EEPROM_POWER_M 0x3f
105#define AR5K_EEPROM_POWER_MIN 0
106#define AR5K_EEPROM_POWER_MAX 3150
107#define AR5K_EEPROM_POWER_STEP 50
108#define AR5K_EEPROM_POWER_TABLE_SIZE 64
109#define AR5K_EEPROM_N_POWER_LOC_11B 4
110#define AR5K_EEPROM_N_POWER_LOC_11G 6
111#define AR5K_EEPROM_I_GAIN 10
112#define AR5K_EEPROM_CCK_OFDM_DELTA 15
113#define AR5K_EEPROM_N_IQ_CAL 2
114
115/* Struct to hold EEPROM calibration data */
116struct ath5k_eeprom_info {
117 u16 ee_magic;
118 u16 ee_protect;
119 u16 ee_regdomain;
120 u16 ee_version;
121 u16 ee_header;
122 u16 ee_ant_gain;
123 u16 ee_misc0;
124 u16 ee_misc1;
125 u16 ee_cck_ofdm_gain_delta;
126 u16 ee_cck_ofdm_power_delta;
127 u16 ee_scaled_cck_delta;
128
129 /* Used for tx thermal adjustment (eeprom_init, rfregs) */
130 u16 ee_tx_clip;
131 u16 ee_pwd_84;
132 u16 ee_pwd_90;
133 u16 ee_gain_select;
134
135 /* RF Calibration settings (reset, rfregs) */
136 u16 ee_i_cal[AR5K_EEPROM_N_MODES];
137 u16 ee_q_cal[AR5K_EEPROM_N_MODES];
138 u16 ee_fixed_bias[AR5K_EEPROM_N_MODES];
139 u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES];
140 u16 ee_xr_power[AR5K_EEPROM_N_MODES];
141 u16 ee_switch_settling[AR5K_EEPROM_N_MODES];
142 u16 ee_ant_tx_rx[AR5K_EEPROM_N_MODES];
143 u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC];
144 u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
145 u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB];
146 u16 ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES];
147 u16 ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES];
148 u16 ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES];
149 u16 ee_thr_62[AR5K_EEPROM_N_MODES];
150 u16 ee_xlna_gain[AR5K_EEPROM_N_MODES];
151 u16 ee_xpd[AR5K_EEPROM_N_MODES];
152 u16 ee_x_gain[AR5K_EEPROM_N_MODES];
153 u16 ee_i_gain[AR5K_EEPROM_N_MODES];
154 u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES];
155
156 /* Unused */
157 u16 ee_false_detect[AR5K_EEPROM_N_MODES];
158 u16 ee_cal_pier[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_2GHZ_CHAN];
159 u16 ee_channel[AR5K_EEPROM_N_MODES][AR5K_EEPROM_MAX_CHAN]; /*empty*/
160
161 /* Conformance test limits (Unused) */
162 u16 ee_ctls;
163 u16 ee_ctl[AR5K_EEPROM_MAX_CTLS];
164
165 /* Noise Floor Calibration settings */
166 s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES];
167 s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES];
168 s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES];
169};
170
171/*
172 * Internal RX/TX descriptor structures
173 * (rX: reserved fields possibily used by future versions of the ar5k chipset)
174 */
175
176struct ath5k_rx_desc {
177 u32 rx_control_0; /* RX control word 0 */
178
179#define AR5K_DESC_RX_CTL0 0x00000000
180
181 u32 rx_control_1; /* RX control word 1 */
182
183#define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff
184#define AR5K_DESC_RX_CTL1_INTREQ 0x00002000
185} __packed;
186
187/*
188 * 5210/5211 rx status descriptor
189 */
190struct ath5k_hw_old_rx_status {
191 u32 rx_status_0; /* RX status word 0 */
192
193#define AR5K_OLD_RX_DESC_STATUS0_DATA_LEN 0x00000fff
194#define AR5K_OLD_RX_DESC_STATUS0_MORE 0x00001000
195#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000
196#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_RATE_S 15
197#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x07f80000
198#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19
199#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000
200#define AR5K_OLD_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27
201
202 u32 rx_status_1; /* RX status word 1 */
203
204#define AR5K_OLD_RX_DESC_STATUS1_DONE 0x00000001
205#define AR5K_OLD_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
206#define AR5K_OLD_RX_DESC_STATUS1_CRC_ERROR 0x00000004
207#define AR5K_OLD_RX_DESC_STATUS1_FIFO_OVERRUN 0x00000008
208#define AR5K_OLD_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000010
209#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR 0x000000e0
210#define AR5K_OLD_RX_DESC_STATUS1_PHY_ERROR_S 5
211#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
212#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX 0x00007e00
213#define AR5K_OLD_RX_DESC_STATUS1_KEY_INDEX_S 9
214#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x0fff8000
215#define AR5K_OLD_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 15
216#define AR5K_OLD_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000
217} __packed;
218
219/*
220 * 5212 rx status descriptor
221 */
222struct ath5k_hw_new_rx_status {
223 u32 rx_status_0; /* RX status word 0 */
224
225#define AR5K_NEW_RX_DESC_STATUS0_DATA_LEN 0x00000fff
226#define AR5K_NEW_RX_DESC_STATUS0_MORE 0x00001000
227#define AR5K_NEW_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000
228#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE 0x000f8000
229#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_RATE_S 15
230#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL 0x0ff00000
231#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20
232#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000
233#define AR5K_NEW_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28
234
235 u32 rx_status_1; /* RX status word 1 */
236
237#define AR5K_NEW_RX_DESC_STATUS1_DONE 0x00000001
238#define AR5K_NEW_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002
239#define AR5K_NEW_RX_DESC_STATUS1_CRC_ERROR 0x00000004
240#define AR5K_NEW_RX_DESC_STATUS1_DECRYPT_CRC_ERROR 0x00000008
241#define AR5K_NEW_RX_DESC_STATUS1_PHY_ERROR 0x00000010
242#define AR5K_NEW_RX_DESC_STATUS1_MIC_ERROR 0x00000020
243#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_VALID 0x00000100
244#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX 0x0000fe00
245#define AR5K_NEW_RX_DESC_STATUS1_KEY_INDEX_S 9
246#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP 0x7fff0000
247#define AR5K_NEW_RX_DESC_STATUS1_RECEIVE_TIMESTAMP_S 16
248#define AR5K_NEW_RX_DESC_STATUS1_KEY_CACHE_MISS 0x80000000
249} __packed;
250
251struct ath5k_hw_rx_error {
252 u32 rx_error_0; /* RX error word 0 */
253
254#define AR5K_RX_DESC_ERROR0 0x00000000
255
256 u32 rx_error_1; /* RX error word 1 */
257
258#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00
259#define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8
260} __packed;
261
262#define AR5K_DESC_RX_PHY_ERROR_NONE 0x00
263#define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20
264#define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40
265#define AR5K_DESC_RX_PHY_ERROR_RATE 0x60
266#define AR5K_DESC_RX_PHY_ERROR_LENGTH 0x80
267#define AR5K_DESC_RX_PHY_ERROR_64QAM 0xa0
268#define AR5K_DESC_RX_PHY_ERROR_SERVICE 0xc0
269#define AR5K_DESC_RX_PHY_ERROR_TRANSMITOVR 0xe0
270
271struct ath5k_hw_2w_tx_desc {
272 u32 tx_control_0; /* TX control word 0 */
273
274#define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff
275#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN 0x0003f000 /*[5210 ?]*/
276#define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S 12
277#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE 0x003c0000
278#define AR5K_2W_TX_DESC_CTL0_XMIT_RATE_S 18
279#define AR5K_2W_TX_DESC_CTL0_RTSENA 0x00400000
280#define AR5K_2W_TX_DESC_CTL0_CLRDMASK 0x01000000
281#define AR5K_2W_TX_DESC_CTL0_LONG_PACKET 0x00800000 /*[5210]*/
282#define AR5K_2W_TX_DESC_CTL0_VEOL 0x00800000 /*[5211]*/
283#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE 0x1c000000 /*[5210]*/
284#define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S 26
285#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000
286#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000
287#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT (ah->ah_version == AR5K_AR5210 ? \
288 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \
289 AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211)
290#define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25
291#define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000
292#define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
293
294 u32 tx_control_1; /* TX control word 1 */
295
296#define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff
297#define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000
298#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 0x0007e000
299#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211 0x000fe000
300#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX (ah->ah_version == AR5K_AR5210 ? \
301 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 : \
302 AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211)
303#define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13
304#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE 0x00700000 /*[5211]*/
305#define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S 20
306#define AR5K_2W_TX_DESC_CTL1_NOACK 0x00800000 /*[5211]*/
307#define AR5K_2W_TX_DESC_CTL1_RTS_DURATION 0xfff80000 /*[5210 ?]*/
308} __packed;
309
310#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0x00
311#define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 0x04
312#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 0x08
313#define AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY 0x0c
314#define AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS 0x10
315
316/*
317 * 5212 4-word tx control descriptor
318 */
319struct ath5k_hw_4w_tx_desc {
320 u32 tx_control_0; /* TX control word 0 */
321
322#define AR5K_4W_TX_DESC_CTL0_FRAME_LEN 0x00000fff
323#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER 0x003f0000
324#define AR5K_4W_TX_DESC_CTL0_XMIT_POWER_S 16
325#define AR5K_4W_TX_DESC_CTL0_RTSENA 0x00400000
326#define AR5K_4W_TX_DESC_CTL0_VEOL 0x00800000
327#define AR5K_4W_TX_DESC_CTL0_CLRDMASK 0x01000000
328#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT 0x1e000000
329#define AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25
330#define AR5K_4W_TX_DESC_CTL0_INTREQ 0x20000000
331#define AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000
332#define AR5K_4W_TX_DESC_CTL0_CTSENA 0x80000000
333
334 u32 tx_control_1; /* TX control word 1 */
335
336#define AR5K_4W_TX_DESC_CTL1_BUF_LEN 0x00000fff
337#define AR5K_4W_TX_DESC_CTL1_MORE 0x00001000
338#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX 0x000fe000
339#define AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13
340#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE 0x00f00000
341#define AR5K_4W_TX_DESC_CTL1_FRAME_TYPE_S 20
342#define AR5K_4W_TX_DESC_CTL1_NOACK 0x01000000
343#define AR5K_4W_TX_DESC_CTL1_COMP_PROC 0x06000000
344#define AR5K_4W_TX_DESC_CTL1_COMP_PROC_S 25
345#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN 0x18000000
346#define AR5K_4W_TX_DESC_CTL1_COMP_IV_LEN_S 27
347#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN 0x60000000
348#define AR5K_4W_TX_DESC_CTL1_COMP_ICV_LEN_S 29
349
350 u32 tx_control_2; /* TX control word 2 */
351
352#define AR5K_4W_TX_DESC_CTL2_RTS_DURATION 0x00007fff
353#define AR5K_4W_TX_DESC_CTL2_DURATION_UPDATE_ENABLE 0x00008000
354#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0 0x000f0000
355#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0_S 16
356#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1 0x00f00000
357#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1_S 20
358#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2 0x0f000000
359#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2_S 24
360#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3 0xf0000000
361#define AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3_S 28
362
363 u32 tx_control_3; /* TX control word 3 */
364
365#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE0 0x0000001f
366#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1 0x000003e0
367#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE1_S 5
368#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2 0x00007c00
369#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE2_S 10
370#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3 0x000f8000
371#define AR5K_4W_TX_DESC_CTL3_XMIT_RATE3_S 15
372#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE 0x01f00000
373#define AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE_S 20
374} __packed;
375
376/*
377 * Common tx status descriptor
378 */
379struct ath5k_hw_tx_status {
380 u32 tx_status_0; /* TX status word 0 */
381
382#define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001
383#define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002
384#define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004
385#define AR5K_DESC_TX_STATUS0_FILTERED 0x00000008
386/*???
387#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT 0x000000f0
388#define AR5K_DESC_TX_STATUS0_RTS_FAIL_COUNT_S 4
389*/
390#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT 0x000000f0
391#define AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT_S 4
392/*???
393#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT 0x00000f00
394#define AR5K_DESC_TX_STATUS0_DATA_FAIL_COUNT_S 8
395*/
396#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT 0x00000f00
397#define AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT_S 8
398#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT 0x0000f000
399#define AR5K_DESC_TX_STATUS0_VIRT_COLL_COUNT_S 12
400#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000
401#define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16
402
403 u32 tx_status_1; /* TX status word 1 */
404
405#define AR5K_DESC_TX_STATUS1_DONE 0x00000001
406#define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe
407#define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1
408#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH 0x001fe000
409#define AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH_S 13
410#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX 0x00600000
411#define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S 21
412#define AR5K_DESC_TX_STATUS1_COMP_SUCCESS 0x00800000
413#define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA 0x01000000
414} __packed;
415
416
417/*
418 * AR5K REGISTER ACCESS
419 */
420
421/*Swap RX/TX Descriptor for big endian archs*/
422#if defined(__BIG_ENDIAN)
423#define AR5K_INIT_CFG ( \
424 AR5K_CFG_SWTD | AR5K_CFG_SWRD \
425)
426#else
427#define AR5K_INIT_CFG 0x00000000
428#endif
429
430/*#define AR5K_REG_READ(_reg) ath5k_hw_reg_read(ah, _reg)
431
432#define AR5K_REG_WRITE(_reg, _val) ath5k_hw_reg_write(ah, _val, _reg)*/
433
434#define AR5K_REG_SM(_val, _flags) \
435 (((_val) << _flags##_S) & (_flags))
436
437#define AR5K_REG_MS(_val, _flags) \
438 (((_val) & (_flags)) >> _flags##_S)
439
440/* Some registers can hold multiple values of interest. For this
441 * reason when we want to write to these registers we must first
442 * retrieve the values which we do not want to clear (lets call this
443 * old_data) and then set the register with this and our new_value:
444 * ( old_data | new_value) */
445#define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val) \
446 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \
447 (((_val) << _flags##_S) & (_flags)), _reg)
448
449#define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask) \
450 ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & \
451 (_mask)) | (_flags), _reg)
452
453#define AR5K_REG_ENABLE_BITS(ah, _reg, _flags) \
454 ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg)
455
456#define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \
457 ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg)
458
459#define AR5K_PHY_WRITE(ah, _reg, _val) \
460 ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2))
461
462#define AR5K_PHY_READ(ah, _reg) \
463 ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2))
464
465#define AR5K_REG_WAIT(_i) do { \
466 if (_i % 64) \
467 udelay(1); \
468} while (0)
469
470#define AR5K_EEPROM_READ(_o, _v) do { \
471 if ((ret = ath5k_hw_eeprom_read(ah, (_o), &(_v))) != 0) \
472 return (ret); \
473} while (0)
474
475#define AR5K_EEPROM_READ_HDR(_o, _v) \
476 AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \
477
478/* Read status of selected queue */
479#define AR5K_REG_READ_Q(ah, _reg, _queue) \
480 (ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \
481
482#define AR5K_REG_WRITE_Q(ah, _reg, _queue) \
483 ath5k_hw_reg_write(ah, (1 << _queue), _reg)
484
485#define AR5K_Q_ENABLE_BITS(_reg, _queue) do { \
486 _reg |= 1 << _queue; \
487} while (0)
488
489#define AR5K_Q_DISABLE_BITS(_reg, _queue) do { \
490 _reg &= ~(1 << _queue); \
491} while (0)
492
493#define AR5K_LOW_ID(_a)( \
494(_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \
495)
496
497#define AR5K_HIGH_ID(_a) ((_a)[4] | (_a)[5] << 8)
498
499/*
500 * Initial register values
501 */
502
503/*
504 * Common initial register values
505 */
506#define AR5K_INIT_MODE CHANNEL_B
507
508#define AR5K_INIT_TX_LATENCY 502
509#define AR5K_INIT_USEC 39
510#define AR5K_INIT_USEC_TURBO 79
511#define AR5K_INIT_USEC_32 31
512#define AR5K_INIT_CARR_SENSE_EN 1
513#define AR5K_INIT_PROG_IFS 920
514#define AR5K_INIT_PROG_IFS_TURBO 960
515#define AR5K_INIT_EIFS 3440
516#define AR5K_INIT_EIFS_TURBO 6880
517#define AR5K_INIT_SLOT_TIME 396
518#define AR5K_INIT_SLOT_TIME_TURBO 480
519#define AR5K_INIT_ACK_CTS_TIMEOUT 1024
520#define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800
521#define AR5K_INIT_SIFS 560
522#define AR5K_INIT_SIFS_TURBO 480
523#define AR5K_INIT_SH_RETRY 10
524#define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY
525#define AR5K_INIT_SSH_RETRY 32
526#define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY
527#define AR5K_INIT_TX_RETRY 10
528#define AR5K_INIT_TOPS 8
529#define AR5K_INIT_RXNOFRM 8
530#define AR5K_INIT_RPGTO 0
531#define AR5K_INIT_TXNOFRM 0
532#define AR5K_INIT_BEACON_PERIOD 65535
533#define AR5K_INIT_TIM_OFFSET 0
534#define AR5K_INIT_BEACON_EN 0
535#define AR5K_INIT_RESET_TSF 0
536
537#define AR5K_INIT_TRANSMIT_LATENCY ( \
538 (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
539 (AR5K_INIT_USEC) \
540)
541#define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \
542 (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \
543 (AR5K_INIT_USEC_TURBO) \
544)
545#define AR5K_INIT_PROTO_TIME_CNTRL ( \
546 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \
547 (AR5K_INIT_PROG_IFS) \
548)
549#define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \
550 (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \
551 (AR5K_INIT_PROG_IFS_TURBO) \
552)
553#define AR5K_INIT_BEACON_CONTROL ( \
554 (AR5K_INIT_RESET_TSF << 24) | (AR5K_INIT_BEACON_EN << 23) | \
555 (AR5K_INIT_TIM_OFFSET << 16) | (AR5K_INIT_BEACON_PERIOD) \
556)
557
558/*
559 * Non-common initial register values which have to be loaded into the
560 * card at boot time and after each reset.
561 */
562
563/* Register dumps are done per operation mode */
564#define AR5K_INI_RFGAIN_5GHZ 0
565#define AR5K_INI_RFGAIN_2GHZ 1
566
567#define AR5K_INI_VAL_11A 0
568#define AR5K_INI_VAL_11A_TURBO 1
569#define AR5K_INI_VAL_11B 2
570#define AR5K_INI_VAL_11G 3
571#define AR5K_INI_VAL_11G_TURBO 4
572#define AR5K_INI_VAL_XR 0
573#define AR5K_INI_VAL_MAX 5
574
575#define AR5K_RF5111_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
576#define AR5K_RF5112_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS
577
578static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits)
579{
580 u32 retval = 0, bit, i;
581
582 for (i = 0; i < bits; i++) {
583 bit = (val >> i) & 1;
584 retval = (retval << 1) | bit;
585 }
586
587 return retval;
588}
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c
new file mode 100644
index 000000000000..2c22f1d4ee64
--- /dev/null
+++ b/drivers/net/wireless/ath5k/initvals.c
@@ -0,0 +1,1347 @@
1/*
2 * Initial register settings functions
3 *
4 * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com>
6 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *
20 */
21
22#include "ath5k.h"
23#include "base.h"
24#include "reg.h"
25
26/*
27 * MAC/PHY REGISTERS
28 */
29
30
31/*
32 * Mode-independent initial register writes
33 */
34
35struct ath5k_ini {
36 u16 ini_register;
37 u32 ini_value;
38
39 enum {
40 AR5K_INI_WRITE = 0, /* Default */
41 AR5K_INI_READ = 1, /* Cleared on read */
42 } ini_mode;
43};
44
45/*
46 * Mode specific initial register values
47 */
48
49struct ath5k_ini_mode {
50 u16 mode_register;
51 u32 mode_value[5];
52};
53
54/* Initial register settings for AR5210 */
55static const struct ath5k_ini ar5210_ini[] = {
56 /* PCU and MAC registers */
57 { AR5K_NOQCU_TXDP0, 0 },
58 { AR5K_NOQCU_TXDP1, 0 },
59 { AR5K_RXDP, 0 },
60 { AR5K_CR, 0 },
61 { AR5K_ISR, 0, AR5K_INI_READ },
62 { AR5K_IMR, 0 },
63 { AR5K_IER, AR5K_IER_DISABLE },
64 { AR5K_BSR, 0, AR5K_INI_READ },
65 { AR5K_TXCFG, AR5K_DMASIZE_128B },
66 { AR5K_RXCFG, AR5K_DMASIZE_128B },
67 { AR5K_CFG, AR5K_INIT_CFG },
68 { AR5K_TOPS, AR5K_INIT_TOPS },
69 { AR5K_RXNOFRM, AR5K_INIT_RXNOFRM },
70 { AR5K_RPGTO, AR5K_INIT_RPGTO },
71 { AR5K_TXNOFRM, AR5K_INIT_TXNOFRM },
72 { AR5K_SFR, 0 },
73 { AR5K_MIBC, 0 },
74 { AR5K_MISC, 0 },
75 { AR5K_RX_FILTER_5210, 0 },
76 { AR5K_MCAST_FILTER0_5210, 0 },
77 { AR5K_MCAST_FILTER1_5210, 0 },
78 { AR5K_TX_MASK0, 0 },
79 { AR5K_TX_MASK1, 0 },
80 { AR5K_CLR_TMASK, 0 },
81 { AR5K_TRIG_LVL, AR5K_TUNE_MIN_TX_FIFO_THRES },
82 { AR5K_DIAG_SW_5210, 0 },
83 { AR5K_RSSI_THR, AR5K_TUNE_RSSI_THRES },
84 { AR5K_TSF_L32_5210, 0 },
85 { AR5K_TIMER0_5210, 0 },
86 { AR5K_TIMER1_5210, 0xffffffff },
87 { AR5K_TIMER2_5210, 0xffffffff },
88 { AR5K_TIMER3_5210, 1 },
89 { AR5K_CFP_DUR_5210, 0 },
90 { AR5K_CFP_PERIOD_5210, 0 },
91 /* PHY registers */
92 { AR5K_PHY(0), 0x00000047 },
93 { AR5K_PHY_AGC, 0x00000000 },
94 { AR5K_PHY(3), 0x09848ea6 },
95 { AR5K_PHY(4), 0x3d32e000 },
96 { AR5K_PHY(5), 0x0000076b },
97 { AR5K_PHY_ACT, AR5K_PHY_ACT_DISABLE },
98 { AR5K_PHY(8), 0x02020200 },
99 { AR5K_PHY(9), 0x00000e0e },
100 { AR5K_PHY(10), 0x0a020201 },
101 { AR5K_PHY(11), 0x00036ffc },
102 { AR5K_PHY(12), 0x00000000 },
103 { AR5K_PHY(13), 0x00000e0e },
104 { AR5K_PHY(14), 0x00000007 },
105 { AR5K_PHY(15), 0x00020100 },
106 { AR5K_PHY(16), 0x89630000 },
107 { AR5K_PHY(17), 0x1372169c },
108 { AR5K_PHY(18), 0x0018b633 },
109 { AR5K_PHY(19), 0x1284613c },
110 { AR5K_PHY(20), 0x0de8b8e0 },
111 { AR5K_PHY(21), 0x00074859 },
112 { AR5K_PHY(22), 0x7e80beba },
113 { AR5K_PHY(23), 0x313a665e },
114 { AR5K_PHY_AGCCTL, 0x00001d08 },
115 { AR5K_PHY(25), 0x0001ce00 },
116 { AR5K_PHY(26), 0x409a4190 },
117 { AR5K_PHY(28), 0x0000000f },
118 { AR5K_PHY(29), 0x00000080 },
119 { AR5K_PHY(30), 0x00000004 },
120 { AR5K_PHY(31), 0x00000018 }, /* 0x987c */
121 { AR5K_PHY(64), 0x00000000 }, /* 0x9900 */
122 { AR5K_PHY(65), 0x00000000 },
123 { AR5K_PHY(66), 0x00000000 },
124 { AR5K_PHY(67), 0x00800000 },
125 { AR5K_PHY(68), 0x00000003 },
126 /* BB gain table (64bytes) */
127 { AR5K_BB_GAIN(0), 0x00000000 },
128 { AR5K_BB_GAIN(1), 0x00000020 },
129 { AR5K_BB_GAIN(2), 0x00000010 },
130 { AR5K_BB_GAIN(3), 0x00000030 },
131 { AR5K_BB_GAIN(4), 0x00000008 },
132 { AR5K_BB_GAIN(5), 0x00000028 },
133 { AR5K_BB_GAIN(6), 0x00000028 },
134 { AR5K_BB_GAIN(7), 0x00000004 },
135 { AR5K_BB_GAIN(8), 0x00000024 },
136 { AR5K_BB_GAIN(9), 0x00000014 },
137 { AR5K_BB_GAIN(10), 0x00000034 },
138 { AR5K_BB_GAIN(11), 0x0000000c },
139 { AR5K_BB_GAIN(12), 0x0000002c },
140 { AR5K_BB_GAIN(13), 0x00000002 },
141 { AR5K_BB_GAIN(14), 0x00000022 },
142 { AR5K_BB_GAIN(15), 0x00000012 },
143 { AR5K_BB_GAIN(16), 0x00000032 },
144 { AR5K_BB_GAIN(17), 0x0000000a },
145 { AR5K_BB_GAIN(18), 0x0000002a },
146 { AR5K_BB_GAIN(19), 0x00000001 },
147 { AR5K_BB_GAIN(20), 0x00000021 },
148 { AR5K_BB_GAIN(21), 0x00000011 },
149 { AR5K_BB_GAIN(22), 0x00000031 },
150 { AR5K_BB_GAIN(23), 0x00000009 },
151 { AR5K_BB_GAIN(24), 0x00000029 },
152 { AR5K_BB_GAIN(25), 0x00000005 },
153 { AR5K_BB_GAIN(26), 0x00000025 },
154 { AR5K_BB_GAIN(27), 0x00000015 },
155 { AR5K_BB_GAIN(28), 0x00000035 },
156 { AR5K_BB_GAIN(29), 0x0000000d },
157 { AR5K_BB_GAIN(30), 0x0000002d },
158 { AR5K_BB_GAIN(31), 0x00000003 },
159 { AR5K_BB_GAIN(32), 0x00000023 },
160 { AR5K_BB_GAIN(33), 0x00000013 },
161 { AR5K_BB_GAIN(34), 0x00000033 },
162 { AR5K_BB_GAIN(35), 0x0000000b },
163 { AR5K_BB_GAIN(36), 0x0000002b },
164 { AR5K_BB_GAIN(37), 0x00000007 },
165 { AR5K_BB_GAIN(38), 0x00000027 },
166 { AR5K_BB_GAIN(39), 0x00000017 },
167 { AR5K_BB_GAIN(40), 0x00000037 },
168 { AR5K_BB_GAIN(41), 0x0000000f },
169 { AR5K_BB_GAIN(42), 0x0000002f },
170 { AR5K_BB_GAIN(43), 0x0000002f },
171 { AR5K_BB_GAIN(44), 0x0000002f },
172 { AR5K_BB_GAIN(45), 0x0000002f },
173 { AR5K_BB_GAIN(46), 0x0000002f },
174 { AR5K_BB_GAIN(47), 0x0000002f },
175 { AR5K_BB_GAIN(48), 0x0000002f },
176 { AR5K_BB_GAIN(49), 0x0000002f },
177 { AR5K_BB_GAIN(50), 0x0000002f },
178 { AR5K_BB_GAIN(51), 0x0000002f },
179 { AR5K_BB_GAIN(52), 0x0000002f },
180 { AR5K_BB_GAIN(53), 0x0000002f },
181 { AR5K_BB_GAIN(54), 0x0000002f },
182 { AR5K_BB_GAIN(55), 0x0000002f },
183 { AR5K_BB_GAIN(56), 0x0000002f },
184 { AR5K_BB_GAIN(57), 0x0000002f },
185 { AR5K_BB_GAIN(58), 0x0000002f },
186 { AR5K_BB_GAIN(59), 0x0000002f },
187 { AR5K_BB_GAIN(60), 0x0000002f },
188 { AR5K_BB_GAIN(61), 0x0000002f },
189 { AR5K_BB_GAIN(62), 0x0000002f },
190 { AR5K_BB_GAIN(63), 0x0000002f },
191 /* 5110 RF gain table (64btes) */
192 { AR5K_RF_GAIN(0), 0x0000001d },
193 { AR5K_RF_GAIN(1), 0x0000005d },
194 { AR5K_RF_GAIN(2), 0x0000009d },
195 { AR5K_RF_GAIN(3), 0x000000dd },
196 { AR5K_RF_GAIN(4), 0x0000011d },
197 { AR5K_RF_GAIN(5), 0x00000021 },
198 { AR5K_RF_GAIN(6), 0x00000061 },
199 { AR5K_RF_GAIN(7), 0x000000a1 },
200 { AR5K_RF_GAIN(8), 0x000000e1 },
201 { AR5K_RF_GAIN(9), 0x00000031 },
202 { AR5K_RF_GAIN(10), 0x00000071 },
203 { AR5K_RF_GAIN(11), 0x000000b1 },
204 { AR5K_RF_GAIN(12), 0x0000001c },
205 { AR5K_RF_GAIN(13), 0x0000005c },
206 { AR5K_RF_GAIN(14), 0x00000029 },
207 { AR5K_RF_GAIN(15), 0x00000069 },
208 { AR5K_RF_GAIN(16), 0x000000a9 },
209 { AR5K_RF_GAIN(17), 0x00000020 },
210 { AR5K_RF_GAIN(18), 0x00000019 },
211 { AR5K_RF_GAIN(19), 0x00000059 },
212 { AR5K_RF_GAIN(20), 0x00000099 },
213 { AR5K_RF_GAIN(21), 0x00000030 },
214 { AR5K_RF_GAIN(22), 0x00000005 },
215 { AR5K_RF_GAIN(23), 0x00000025 },
216 { AR5K_RF_GAIN(24), 0x00000065 },
217 { AR5K_RF_GAIN(25), 0x000000a5 },
218 { AR5K_RF_GAIN(26), 0x00000028 },
219 { AR5K_RF_GAIN(27), 0x00000068 },
220 { AR5K_RF_GAIN(28), 0x0000001f },
221 { AR5K_RF_GAIN(29), 0x0000001e },
222 { AR5K_RF_GAIN(30), 0x00000018 },
223 { AR5K_RF_GAIN(31), 0x00000058 },
224 { AR5K_RF_GAIN(32), 0x00000098 },
225 { AR5K_RF_GAIN(33), 0x00000003 },
226 { AR5K_RF_GAIN(34), 0x00000004 },
227 { AR5K_RF_GAIN(35), 0x00000044 },
228 { AR5K_RF_GAIN(36), 0x00000084 },
229 { AR5K_RF_GAIN(37), 0x00000013 },
230 { AR5K_RF_GAIN(38), 0x00000012 },
231 { AR5K_RF_GAIN(39), 0x00000052 },
232 { AR5K_RF_GAIN(40), 0x00000092 },
233 { AR5K_RF_GAIN(41), 0x000000d2 },
234 { AR5K_RF_GAIN(42), 0x0000002b },
235 { AR5K_RF_GAIN(43), 0x0000002a },
236 { AR5K_RF_GAIN(44), 0x0000006a },
237 { AR5K_RF_GAIN(45), 0x000000aa },
238 { AR5K_RF_GAIN(46), 0x0000001b },
239 { AR5K_RF_GAIN(47), 0x0000001a },
240 { AR5K_RF_GAIN(48), 0x0000005a },
241 { AR5K_RF_GAIN(49), 0x0000009a },
242 { AR5K_RF_GAIN(50), 0x000000da },
243 { AR5K_RF_GAIN(51), 0x00000006 },
244 { AR5K_RF_GAIN(52), 0x00000006 },
245 { AR5K_RF_GAIN(53), 0x00000006 },
246 { AR5K_RF_GAIN(54), 0x00000006 },
247 { AR5K_RF_GAIN(55), 0x00000006 },
248 { AR5K_RF_GAIN(56), 0x00000006 },
249 { AR5K_RF_GAIN(57), 0x00000006 },
250 { AR5K_RF_GAIN(58), 0x00000006 },
251 { AR5K_RF_GAIN(59), 0x00000006 },
252 { AR5K_RF_GAIN(60), 0x00000006 },
253 { AR5K_RF_GAIN(61), 0x00000006 },
254 { AR5K_RF_GAIN(62), 0x00000006 },
255 { AR5K_RF_GAIN(63), 0x00000006 },
256 /* PHY activation */
257 { AR5K_PHY(53), 0x00000020 },
258 { AR5K_PHY(51), 0x00000004 },
259 { AR5K_PHY(50), 0x00060106 },
260 { AR5K_PHY(39), 0x0000006d },
261 { AR5K_PHY(48), 0x00000000 },
262 { AR5K_PHY(52), 0x00000014 },
263 { AR5K_PHY_ACT, AR5K_PHY_ACT_ENABLE },
264};
265
266/* Initial register settings for AR5211 */
267static const struct ath5k_ini ar5211_ini[] = {
268 { AR5K_RXDP, 0x00000000 },
269 { AR5K_RTSD0, 0x84849c9c },
270 { AR5K_RTSD1, 0x7c7c7c7c },
271 { AR5K_RXCFG, 0x00000005 },
272 { AR5K_MIBC, 0x00000000 },
273 { AR5K_TOPS, 0x00000008 },
274 { AR5K_RXNOFRM, 0x00000008 },
275 { AR5K_TXNOFRM, 0x00000010 },
276 { AR5K_RPGTO, 0x00000000 },
277 { AR5K_RFCNT, 0x0000001f },
278 { AR5K_QUEUE_TXDP(0), 0x00000000 },
279 { AR5K_QUEUE_TXDP(1), 0x00000000 },
280 { AR5K_QUEUE_TXDP(2), 0x00000000 },
281 { AR5K_QUEUE_TXDP(3), 0x00000000 },
282 { AR5K_QUEUE_TXDP(4), 0x00000000 },
283 { AR5K_QUEUE_TXDP(5), 0x00000000 },
284 { AR5K_QUEUE_TXDP(6), 0x00000000 },
285 { AR5K_QUEUE_TXDP(7), 0x00000000 },
286 { AR5K_QUEUE_TXDP(8), 0x00000000 },
287 { AR5K_QUEUE_TXDP(9), 0x00000000 },
288 { AR5K_DCU_FP, 0x00000000 },
289 { AR5K_STA_ID1, 0x00000000 },
290 { AR5K_BSS_ID0, 0x00000000 },
291 { AR5K_BSS_ID1, 0x00000000 },
292 { AR5K_RSSI_THR, 0x00000000 },
293 { AR5K_CFP_PERIOD_5211, 0x00000000 },
294 { AR5K_TIMER0_5211, 0x00000030 },
295 { AR5K_TIMER1_5211, 0x0007ffff },
296 { AR5K_TIMER2_5211, 0x01ffffff },
297 { AR5K_TIMER3_5211, 0x00000031 },
298 { AR5K_CFP_DUR_5211, 0x00000000 },
299 { AR5K_RX_FILTER_5211, 0x00000000 },
300 { AR5K_MCAST_FILTER0_5211, 0x00000000 },
301 { AR5K_MCAST_FILTER1_5211, 0x00000002 },
302 { AR5K_DIAG_SW_5211, 0x00000000 },
303 { AR5K_ADDAC_TEST, 0x00000000 },
304 { AR5K_DEFAULT_ANTENNA, 0x00000000 },
305 /* PHY registers */
306 { AR5K_PHY_AGC, 0x00000000 },
307 { AR5K_PHY(3), 0x2d849093 },
308 { AR5K_PHY(4), 0x7d32e000 },
309 { AR5K_PHY(5), 0x00000f6b },
310 { AR5K_PHY_ACT, 0x00000000 },
311 { AR5K_PHY(11), 0x00026ffe },
312 { AR5K_PHY(12), 0x00000000 },
313 { AR5K_PHY(15), 0x00020100 },
314 { AR5K_PHY(16), 0x206a017a },
315 { AR5K_PHY(19), 0x1284613c },
316 { AR5K_PHY(21), 0x00000859 },
317 { AR5K_PHY(26), 0x409a4190 }, /* 0x9868 */
318 { AR5K_PHY(27), 0x050cb081 },
319 { AR5K_PHY(28), 0x0000000f },
320 { AR5K_PHY(29), 0x00000080 },
321 { AR5K_PHY(30), 0x0000000c },
322 { AR5K_PHY(64), 0x00000000 },
323 { AR5K_PHY(65), 0x00000000 },
324 { AR5K_PHY(66), 0x00000000 },
325 { AR5K_PHY(67), 0x00800000 },
326 { AR5K_PHY(68), 0x00000001 },
327 { AR5K_PHY(71), 0x0000092a },
328 { AR5K_PHY_IQ, 0x00000000 },
329 { AR5K_PHY(73), 0x00058a05 },
330 { AR5K_PHY(74), 0x00000001 },
331 { AR5K_PHY(75), 0x00000000 },
332 { AR5K_PHY_PAPD_PROBE, 0x00000000 },
333 { AR5K_PHY(77), 0x00000000 }, /* 0x9934 */
334 { AR5K_PHY(78), 0x00000000 }, /* 0x9938 */
335 { AR5K_PHY(79), 0x0000003f }, /* 0x993c */
336 { AR5K_PHY(80), 0x00000004 },
337 { AR5K_PHY(82), 0x00000000 },
338 { AR5K_PHY(83), 0x00000000 },
339 { AR5K_PHY(84), 0x00000000 },
340 { AR5K_PHY_RADAR, 0x5d50f14c },
341 { AR5K_PHY(86), 0x00000018 },
342 { AR5K_PHY(87), 0x004b6a8e },
343 /* Initial Power table (32bytes)
344 * common on all cards/modes.
345 * Note: Table is rewritten during
346 * txpower setup later using calibration
347 * data etc. so next write is non-common
348 { AR5K_PHY_PCDAC_TXPOWER(1), 0x06ff05ff },
349 { AR5K_PHY_PCDAC_TXPOWER(2), 0x07ff07ff },
350 { AR5K_PHY_PCDAC_TXPOWER(3), 0x08ff08ff },
351 { AR5K_PHY_PCDAC_TXPOWER(4), 0x09ff09ff },
352 { AR5K_PHY_PCDAC_TXPOWER(5), 0x0aff0aff },
353 { AR5K_PHY_PCDAC_TXPOWER(6), 0x0bff0bff },
354 { AR5K_PHY_PCDAC_TXPOWER(7), 0x0cff0cff },
355 { AR5K_PHY_PCDAC_TXPOWER(8), 0x0dff0dff },
356 { AR5K_PHY_PCDAC_TXPOWER(9), 0x0fff0eff },
357 { AR5K_PHY_PCDAC_TXPOWER(10), 0x12ff12ff },
358 { AR5K_PHY_PCDAC_TXPOWER(11), 0x14ff13ff },
359 { AR5K_PHY_PCDAC_TXPOWER(12), 0x16ff15ff },
360 { AR5K_PHY_PCDAC_TXPOWER(13), 0x19ff17ff },
361 { AR5K_PHY_PCDAC_TXPOWER(14), 0x1bff1aff },
362 { AR5K_PHY_PCDAC_TXPOWER(15), 0x1eff1dff },
363 { AR5K_PHY_PCDAC_TXPOWER(16), 0x23ff20ff },
364 { AR5K_PHY_PCDAC_TXPOWER(17), 0x27ff25ff },
365 { AR5K_PHY_PCDAC_TXPOWER(18), 0x2cff29ff },
366 { AR5K_PHY_PCDAC_TXPOWER(19), 0x31ff2fff },
367 { AR5K_PHY_PCDAC_TXPOWER(20), 0x37ff34ff },
368 { AR5K_PHY_PCDAC_TXPOWER(21), 0x3aff3aff },
369 { AR5K_PHY_PCDAC_TXPOWER(22), 0x3aff3aff },
370 { AR5K_PHY_PCDAC_TXPOWER(23), 0x3aff3aff },
371 { AR5K_PHY_PCDAC_TXPOWER(24), 0x3aff3aff },
372 { AR5K_PHY_PCDAC_TXPOWER(25), 0x3aff3aff },
373 { AR5K_PHY_PCDAC_TXPOWER(26), 0x3aff3aff },
374 { AR5K_PHY_PCDAC_TXPOWER(27), 0x3aff3aff },
375 { AR5K_PHY_PCDAC_TXPOWER(28), 0x3aff3aff },
376 { AR5K_PHY_PCDAC_TXPOWER(29), 0x3aff3aff },
377 { AR5K_PHY_PCDAC_TXPOWER(30), 0x3aff3aff },
378 { AR5K_PHY_PCDAC_TXPOWER(31), 0x3aff3aff },*/
379 { AR5K_PHY_CCKTXCTL, 0x00000000 },
380 { AR5K_PHY(642), 0x503e4646 },
381 { AR5K_PHY_GAIN_2GHZ, 0x6480416c },
382 { AR5K_PHY(644), 0x0199a003 },
383 { AR5K_PHY(645), 0x044cd610 },
384 { AR5K_PHY(646), 0x13800040 },
385 { AR5K_PHY(647), 0x1be00060 },
386 { AR5K_PHY(648), 0x0c53800a },
387 { AR5K_PHY(649), 0x0014df3b },
388 { AR5K_PHY(650), 0x000001b5 },
389 { AR5K_PHY(651), 0x00000020 },
390};
391
392/* Initial mode-specific settings for AR5211
393 * XXX: how about g / gTurbo ? RF5111 supports it, how about AR5211 ?
394 * Maybe 5211 supports OFDM-only g but we need to test it !
395 */
396static const struct ath5k_ini_mode ar5211_ini_mode[] = {
397 { AR5K_TXCFG,
398 /* a aTurbo b */
399 { 0x00000015, 0x00000015, 0x0000001d } },
400 { AR5K_QUEUE_DFS_LOCAL_IFS(0),
401 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
402 { AR5K_QUEUE_DFS_LOCAL_IFS(1),
403 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
404 { AR5K_QUEUE_DFS_LOCAL_IFS(2),
405 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
406 { AR5K_QUEUE_DFS_LOCAL_IFS(3),
407 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
408 { AR5K_QUEUE_DFS_LOCAL_IFS(4),
409 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
410 { AR5K_QUEUE_DFS_LOCAL_IFS(5),
411 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
412 { AR5K_QUEUE_DFS_LOCAL_IFS(6),
413 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
414 { AR5K_QUEUE_DFS_LOCAL_IFS(7),
415 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
416 { AR5K_QUEUE_DFS_LOCAL_IFS(8),
417 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
418 { AR5K_QUEUE_DFS_LOCAL_IFS(9),
419 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f } },
420 { AR5K_DCU_GBL_IFS_SLOT,
421 { 0x00000168, 0x000001e0, 0x000001b8 } },
422 { AR5K_DCU_GBL_IFS_SIFS,
423 { 0x00000230, 0x000001e0, 0x000000b0 } },
424 { AR5K_DCU_GBL_IFS_EIFS,
425 { 0x00000d98, 0x00001180, 0x00001f48 } },
426 { AR5K_DCU_GBL_IFS_MISC,
427 { 0x0000a0e0, 0x00014068, 0x00005880 } },
428 { AR5K_TIME_OUT,
429 { 0x04000400, 0x08000800, 0x20003000 } },
430 { AR5K_USEC_5211,
431 { 0x0e8d8fa7, 0x0e8d8fcf, 0x01608f95 } },
432 { AR5K_PHY_TURBO,
433 { 0x00000000, 0x00000003, 0x00000000 } },
434 { AR5K_PHY(8),
435 { 0x02020200, 0x02020200, 0x02010200 } },
436 { AR5K_PHY(9),
437 { 0x00000e0e, 0x00000e0e, 0x00000707 } },
438 { AR5K_PHY(10),
439 { 0x0a020001, 0x0a020001, 0x05010000 } },
440 { AR5K_PHY(13),
441 { 0x00000e0e, 0x00000e0e, 0x00000e0e } },
442 { AR5K_PHY(14),
443 { 0x00000007, 0x00000007, 0x0000000b } },
444 { AR5K_PHY(17),
445 { 0x1372169c, 0x137216a5, 0x137216a8 } },
446 { AR5K_PHY(18),
447 { 0x0018ba67, 0x0018ba67, 0x0018ba69 } },
448 { AR5K_PHY(20),
449 { 0x0c28b4e0, 0x0c28b4e0, 0x0c28b4e0 } },
450 { AR5K_PHY_SIG,
451 { 0x7e800d2e, 0x7e800d2e, 0x7ec00d2e } },
452 { AR5K_PHY_AGCCOARSE,
453 { 0x31375d5e, 0x31375d5e, 0x313a5d5e } },
454 { AR5K_PHY_AGCCTL,
455 { 0x0000bd10, 0x0000bd10, 0x0000bd38 } },
456 { AR5K_PHY_NF,
457 { 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
458 { AR5K_PHY_RX_DELAY,
459 { 0x00002710, 0x00002710, 0x0000157c } },
460 { AR5K_PHY(70),
461 { 0x00000190, 0x00000190, 0x00000084 } },
462 { AR5K_PHY_FRAME_CTL_5211,
463 { 0x6fe01020, 0x6fe01020, 0x6fe00920 } },
464 { AR5K_PHY_PCDAC_TXPOWER_BASE_5211,
465 { 0x05ff14ff, 0x05ff14ff, 0x05ff14ff } },
466 { AR5K_RF_BUFFER_CONTROL_4,
467 { 0x00000010, 0x00000014, 0x00000010 } },
468};
469
470/* Initial register settings for AR5212 */
471static const struct ath5k_ini ar5212_ini[] = {
472 { AR5K_RXDP, 0x00000000 },
473 { AR5K_RXCFG, 0x00000005 },
474 { AR5K_MIBC, 0x00000000 },
475 { AR5K_TOPS, 0x00000008 },
476 { AR5K_RXNOFRM, 0x00000008 },
477 { AR5K_TXNOFRM, 0x00000010 },
478 { AR5K_RPGTO, 0x00000000 },
479 { AR5K_RFCNT, 0x0000001f },
480 { AR5K_QUEUE_TXDP(0), 0x00000000 },
481 { AR5K_QUEUE_TXDP(1), 0x00000000 },
482 { AR5K_QUEUE_TXDP(2), 0x00000000 },
483 { AR5K_QUEUE_TXDP(3), 0x00000000 },
484 { AR5K_QUEUE_TXDP(4), 0x00000000 },
485 { AR5K_QUEUE_TXDP(5), 0x00000000 },
486 { AR5K_QUEUE_TXDP(6), 0x00000000 },
487 { AR5K_QUEUE_TXDP(7), 0x00000000 },
488 { AR5K_QUEUE_TXDP(8), 0x00000000 },
489 { AR5K_QUEUE_TXDP(9), 0x00000000 },
490 { AR5K_DCU_FP, 0x00000000 },
491 { AR5K_DCU_TXP, 0x00000000 },
492 { AR5K_DCU_TX_FILTER, 0x00000000 },
493 /* Unknown table */
494 { 0x1078, 0x00000000 },
495 { 0x10b8, 0x00000000 },
496 { 0x10f8, 0x00000000 },
497 { 0x1138, 0x00000000 },
498 { 0x1178, 0x00000000 },
499 { 0x11b8, 0x00000000 },
500 { 0x11f8, 0x00000000 },
501 { 0x1238, 0x00000000 },
502 { 0x1278, 0x00000000 },
503 { 0x12b8, 0x00000000 },
504 { 0x12f8, 0x00000000 },
505 { 0x1338, 0x00000000 },
506 { 0x1378, 0x00000000 },
507 { 0x13b8, 0x00000000 },
508 { 0x13f8, 0x00000000 },
509 { 0x1438, 0x00000000 },
510 { 0x1478, 0x00000000 },
511 { 0x14b8, 0x00000000 },
512 { 0x14f8, 0x00000000 },
513 { 0x1538, 0x00000000 },
514 { 0x1578, 0x00000000 },
515 { 0x15b8, 0x00000000 },
516 { 0x15f8, 0x00000000 },
517 { 0x1638, 0x00000000 },
518 { 0x1678, 0x00000000 },
519 { 0x16b8, 0x00000000 },
520 { 0x16f8, 0x00000000 },
521 { 0x1738, 0x00000000 },
522 { 0x1778, 0x00000000 },
523 { 0x17b8, 0x00000000 },
524 { 0x17f8, 0x00000000 },
525 { 0x103c, 0x00000000 },
526 { 0x107c, 0x00000000 },
527 { 0x10bc, 0x00000000 },
528 { 0x10fc, 0x00000000 },
529 { 0x113c, 0x00000000 },
530 { 0x117c, 0x00000000 },
531 { 0x11bc, 0x00000000 },
532 { 0x11fc, 0x00000000 },
533 { 0x123c, 0x00000000 },
534 { 0x127c, 0x00000000 },
535 { 0x12bc, 0x00000000 },
536 { 0x12fc, 0x00000000 },
537 { 0x133c, 0x00000000 },
538 { 0x137c, 0x00000000 },
539 { 0x13bc, 0x00000000 },
540 { 0x13fc, 0x00000000 },
541 { 0x143c, 0x00000000 },
542 { 0x147c, 0x00000000 },
543 { AR5K_DCU_TX_FILTER_CLR, 0x00000000 },
544 { AR5K_DCU_TX_FILTER_SET, 0x00000000 },
545 { AR5K_STA_ID1, 0x00000000 },
546 { AR5K_BSS_ID0, 0x00000000 },
547 { AR5K_BSS_ID1, 0x00000000 },
548 /*{ AR5K_RSSI_THR, 0x00000000 },*/ /* Found on SuperAG cards */
549 { AR5K_BEACON_5211, 0x00000000 }, /* Found on SuperAG cards */
550 { AR5K_CFP_PERIOD_5211, 0x00000000 }, /* Found on SuperAG cards */
551 { AR5K_TIMER0_5211, 0x00000030 }, /* Found on SuperAG cards */
552 { AR5K_TIMER1_5211, 0x0007ffff }, /* Found on SuperAG cards */
553 { AR5K_TIMER2_5211, 0x01ffffff }, /* Found on SuperAG cards */
554 { AR5K_TIMER3_5211, 0x00000031 }, /* Found on SuperAG cards */
555 { AR5K_CFP_DUR_5211, 0x00000000 }, /* Found on SuperAG cards */
556 { AR5K_RX_FILTER_5211, 0x00000000 },
557 { AR5K_DIAG_SW_5211, 0x00000000 },
558 { AR5K_ADDAC_TEST, 0x00000000 },
559 { AR5K_DEFAULT_ANTENNA, 0x00000000 },
560 { 0x8080, 0x00000000 },
561 /*{ 0x805c, 0xffffc7ff },*/ /* Old value */
562 { 0x805c, 0x000fc78f },
563 { AR5K_NAV_5211, 0x00000000 }, /* Not found on recent */
564 { AR5K_RTS_OK_5211, 0x00000000 }, /* dumps but it makes */
565 { AR5K_RTS_FAIL_5211, 0x00000000 }, /* sense to reset counters */
566 { AR5K_ACK_FAIL_5211, 0x00000000 }, /* since pcu registers */
567 { AR5K_FCS_FAIL_5211, 0x00000000 }, /* are skiped during chan*/
568 { AR5K_BEACON_CNT_5211, 0x00000000 }, /* change */
569 { AR5K_XRMODE, 0x2a82301a },
570 { AR5K_XRDELAY, 0x05dc01e0 },
571 { AR5K_XRTIMEOUT, 0x1f402710 },
572 { AR5K_XRCHIRP, 0x01f40000 },
573 { AR5K_XRSTOMP, 0x00001e1c },
574 { AR5K_SLEEP0, 0x0002aaaa }, /* Found on SuperAG cards */
575 { AR5K_SLEEP1, 0x02005555 }, /* Found on SuperAG cards */
576 { AR5K_SLEEP2, 0x00000000 }, /* Found on SuperAG cards */
577 { AR5K_BSS_IDM0, 0xffffffff },
578 { AR5K_BSS_IDM1, 0x0000ffff },
579 { AR5K_TXPC, 0x00000000 },
580 { AR5K_PROFCNT_TX, 0x00000000 },
581 { AR5K_PROFCNT_RX, 0x00000000 },
582 { AR5K_PROFCNT_RXCLR, 0x00000000 },
583 { AR5K_PROFCNT_CYCLE, 0x00000000 },
584 { 0x80fc, 0x00000088 },
585 { AR5K_RATE_DUR(0), 0x00000000 },
586 { AR5K_RATE_DUR(1), 0x0000008c },
587 { AR5K_RATE_DUR(2), 0x000000e4 },
588 { AR5K_RATE_DUR(3), 0x000002d5 },
589 { AR5K_RATE_DUR(4), 0x00000000 },
590 { AR5K_RATE_DUR(5), 0x00000000 },
591 { AR5K_RATE_DUR(6), 0x000000a0 },
592 { AR5K_RATE_DUR(7), 0x000001c9 },
593 { AR5K_RATE_DUR(8), 0x0000002c },
594 { AR5K_RATE_DUR(9), 0x0000002c },
595 { AR5K_RATE_DUR(10), 0x00000030 },
596 { AR5K_RATE_DUR(11), 0x0000003c },
597 { AR5K_RATE_DUR(12), 0x0000002c },
598 { AR5K_RATE_DUR(13), 0x0000002c },
599 { AR5K_RATE_DUR(14), 0x00000030 },
600 { AR5K_RATE_DUR(15), 0x0000003c },
601 { AR5K_RATE_DUR(16), 0x00000000 },
602 { AR5K_RATE_DUR(17), 0x00000000 },
603 { AR5K_RATE_DUR(18), 0x00000000 },
604 { AR5K_RATE_DUR(19), 0x00000000 },
605 { AR5K_RATE_DUR(20), 0x00000000 },
606 { AR5K_RATE_DUR(21), 0x00000000 },
607 { AR5K_RATE_DUR(22), 0x00000000 },
608 { AR5K_RATE_DUR(23), 0x00000000 },
609 { AR5K_RATE_DUR(24), 0x000000d5 },
610 { AR5K_RATE_DUR(25), 0x000000df },
611 { AR5K_RATE_DUR(26), 0x00000102 },
612 { AR5K_RATE_DUR(27), 0x0000013a },
613 { AR5K_RATE_DUR(28), 0x00000075 },
614 { AR5K_RATE_DUR(29), 0x0000007f },
615 { AR5K_RATE_DUR(30), 0x000000a2 },
616 { AR5K_RATE_DUR(31), 0x00000000 },
617 { 0x8100, 0x00010002},
618 { AR5K_TSF_PARM, 0x00000001 },
619 { 0x8108, 0x000000c0 },
620 { AR5K_PHY_ERR_FIL, 0x00000000 },
621 { 0x8110, 0x00000168 },
622 { 0x8114, 0x00000000 },
623 /* Some kind of table
624 * also notice ...03<-02<-01<-00) */
625 { 0x87c0, 0x03020100 },
626 { 0x87c4, 0x07060504 },
627 { 0x87c8, 0x0b0a0908 },
628 { 0x87cc, 0x0f0e0d0c },
629 { 0x87d0, 0x13121110 },
630 { 0x87d4, 0x17161514 },
631 { 0x87d8, 0x1b1a1918 },
632 { 0x87dc, 0x1f1e1d1c },
633 /* loop ? */
634 { 0x87e0, 0x03020100 },
635 { 0x87e4, 0x07060504 },
636 { 0x87e8, 0x0b0a0908 },
637 { 0x87ec, 0x0f0e0d0c },
638 { 0x87f0, 0x13121110 },
639 { 0x87f4, 0x17161514 },
640 { 0x87f8, 0x1b1a1918 },
641 { 0x87fc, 0x1f1e1d1c },
642 /* PHY registers */
643 /*{ AR5K_PHY_AGC, 0x00000000 },*/
644 { AR5K_PHY(3), 0xad848e19 },
645 { AR5K_PHY(4), 0x7d28e000 },
646 { AR5K_PHY_TIMING_3, 0x9c0a9f6b },
647 { AR5K_PHY_ACT, 0x00000000 },
648 /*{ AR5K_PHY(11), 0x00022ffe },*/
649 /*{ AR5K_PHY(15), 0x00020100 },*/
650 { AR5K_PHY(16), 0x206a017a },
651 /*{ AR5K_PHY(19), 0x1284613c },*/
652 { AR5K_PHY(21), 0x00000859 },
653 { AR5K_PHY(64), 0x00000000 },
654 { AR5K_PHY(65), 0x00000000 },
655 { AR5K_PHY(66), 0x00000000 },
656 { AR5K_PHY(67), 0x00800000 },
657 { AR5K_PHY(68), 0x00000001 },
658 /*{ AR5K_PHY(71), 0x0000092a },*/ /* Old value */
659 { AR5K_PHY(71), 0x00000c80 },
660 { AR5K_PHY_IQ, 0x05100000 },
661 { AR5K_PHY(74), 0x00000001 },
662 { AR5K_PHY(75), 0x00000004 },
663 { AR5K_PHY_TXPOWER_RATE1, 0x1e1f2022 },
664 { AR5K_PHY_TXPOWER_RATE2, 0x0a0b0c0d },
665 { AR5K_PHY_TXPOWER_RATE_MAX, 0x0000003f },
666 /*{ AR5K_PHY(80), 0x00000004 },*/
667 { AR5K_PHY(82), 0x9280b212 },
668 { AR5K_PHY_RADAR, 0x5d50e188 },
669 /*{ AR5K_PHY(86), 0x000000ff },*/
670 { AR5K_PHY(87), 0x004b6a8e },
671 { AR5K_PHY(90), 0x000003ce },
672 { AR5K_PHY(92), 0x192fb515 },
673 /*{ AR5K_PHY(93), 0x00000000 },*/
674 { AR5K_PHY(94), 0x00000001 },
675 { AR5K_PHY(95), 0x00000000 },
676 /*{ AR5K_PHY(644), 0x0080a333 },*/ /* Old value */
677 /*{ AR5K_PHY(645), 0x00206c10 },*/ /* Old value */
678 { AR5K_PHY(644), 0x00806333 },
679 { AR5K_PHY(645), 0x00106c10 },
680 { AR5K_PHY(646), 0x009c4060 },
681 /*{ AR5K_PHY(647), 0x1483800a },*/ /* Old value */
682 { AR5K_PHY(647), 0x1483800a },
683 { AR5K_PHY(648), 0x01831061 },
684 { AR5K_PHY(649), 0x00000400 },
685 /*{ AR5K_PHY(650), 0x000001b5 },*/
686 { AR5K_PHY(651), 0x00000000 },
687 { AR5K_PHY_TXPOWER_RATE3, 0x20202020 },
688 { AR5K_PHY_TXPOWER_RATE2, 0x20202020 },
689 /*{ AR5K_PHY(655), 0x13c889af },*/
690 { AR5K_PHY(656), 0x38490a20 },
691 { AR5K_PHY(657), 0x00007bb6 },
692 { AR5K_PHY(658), 0x0fff3ffc },
693 /*{ AR5K_PHY_CCKTXCTL, 0x00000000 },*/
694};
695
696/* Initial mode-specific settings for AR5212 (Written before ar5212_ini) */
697static const struct ath5k_ini_mode ar5212_ini_mode_start[] = {
698 { AR5K_PHY(640),
699 /* a/XR aTurbo b g (DYN) gTurbo */
700 { 0x00000008, 0x00000008, 0x0000000b, 0x0000000e, 0x0000000e } },
701 { AR5K_PHY(0),
702 { 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007 } },
703 { AR5K_QUEUE_DFS_LOCAL_IFS(0),
704 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
705 { AR5K_QUEUE_DFS_LOCAL_IFS(1),
706 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
707 { AR5K_QUEUE_DFS_LOCAL_IFS(2),
708 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
709 { AR5K_QUEUE_DFS_LOCAL_IFS(3),
710 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
711 { AR5K_QUEUE_DFS_LOCAL_IFS(4),
712 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
713 { AR5K_QUEUE_DFS_LOCAL_IFS(5),
714 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
715 { AR5K_QUEUE_DFS_LOCAL_IFS(6),
716 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
717 { AR5K_QUEUE_DFS_LOCAL_IFS(7),
718 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
719 { AR5K_QUEUE_DFS_LOCAL_IFS(8),
720 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
721 { AR5K_QUEUE_DFS_LOCAL_IFS(9),
722 { 0x002ffc0f, 0x002ffc0f, 0x002ffc1f, 0x002ffc0f, 0x002ffc0f } },
723 { AR5K_DCU_GBL_IFS_SIFS,
724 { 0x00000230, 0x000001e0, 0x000000b0, 0x00000160, 0x000001e0 } },
725 { AR5K_DCU_GBL_IFS_SLOT,
726 { 0x00000168, 0x000001e0, 0x000001b8, 0x0000018c, 0x000001e0 } },
727 { AR5K_DCU_GBL_IFS_EIFS,
728 { 0x00000e60, 0x00001180, 0x00001f1c, 0x00003e38, 0x00001180 } },
729 { AR5K_DCU_GBL_IFS_MISC,
730 { 0x0000a0e0, 0x00014068, 0x00005880, 0x0000b0e0, 0x00014068 } },
731 { AR5K_TIME_OUT,
732 { 0x03e803e8, 0x06e006e0, 0x04200420, 0x08400840, 0x06e006e0 } },
733 { AR5K_PHY_TURBO,
734 { 0x00000000, 0x00000003, 0x00000000, 0x00000000, 0x00000003 } },
735 { AR5K_PHY(8),
736 { 0x02020200, 0x02020200, 0x02010200, 0x02020200, 0x02020200 } },
737 { AR5K_PHY(9),
738 { 0x00000e0e, 0x00000e0e, 0x00000707, 0x00000e0e, 0x00000e0e } },
739 { AR5K_PHY(17),
740 { 0x1372161c, 0x13721c25, 0x13721722, 0x137216a2, 0x13721c25 } },
741 { AR5K_PHY_AGCCTL,
742 { 0x00009d10, 0x00009d10, 0x00009d18, 0x00009d18, 0x00009d18 } },
743 { AR5K_PHY_NF,
744 { 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00 } },
745 { AR5K_PHY(26),
746 { 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190 } },
747 { AR5K_PHY(70),
748 { 0x000001b8, 0x000001b8, 0x00000084, 0x00000108, 0x000001b8 } },
749 { AR5K_PHY(73),
750 { 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05, 0x10058a05 } },
751 { 0xa230,
752 { 0x00000000, 0x00000000, 0x00000000, 0x00000108, 0x00000000 } },
753};
754
755/* Initial mode-specific settings for AR5212 + RF5111 (Written after ar5212_ini) */
756/* New dump pending */
757static const struct ath5k_ini_mode ar5212_rf5111_ini_mode_end[] = {
758 { AR5K_PHY(640), /* This one differs from ar5212_ini_mode_start ! */
759 /* a/XR aTurbo b g (DYN) gTurbo */
760 { 0x00000000, 0x00000000, 0x00000003, 0x00000006, 0x00000006 } },
761 { AR5K_TXCFG,
762 { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
763 { AR5K_USEC_5211,
764 { 0x128d8fa7, 0x09880fcf, 0x04e00f95, 0x12e00fab, 0x09880fcf } },
765 { AR5K_PHY(10),
766 { 0x0a020001, 0x0a020001, 0x05010100, 0x0a020001, 0x0a020001 } },
767 { AR5K_PHY(13),
768 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
769 { AR5K_PHY(14),
770 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
771 { AR5K_PHY(18),
772 { 0x0018da5a, 0x0018da5a, 0x0018ca69, 0x0018ca69, 0x0018ca69 } },
773 { AR5K_PHY(20),
774 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
775 { AR5K_PHY_SIG,
776 { 0x7e800d2e, 0x7e800d2e, 0x7ee84d2e, 0x7ee84d2e, 0x7e800d2e } },
777 { AR5K_PHY_AGCCOARSE,
778 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137615e } },
779 { AR5K_PHY(27),
780 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb080, 0x050cb080 } },
781 { AR5K_PHY_RX_DELAY,
782 { 0x00002710, 0x00002710, 0x0000157c, 0x00002af8, 0x00002710 } },
783 { AR5K_PHY_FRAME_CTL_5211,
784 { 0xf7b81020, 0xf7b81020, 0xf7b80d20, 0xf7b81020, 0xf7b81020 } },
785 { AR5K_PHY_GAIN_2GHZ,
786 { 0x642c416a, 0x642c416a, 0x6440416a, 0x6440416a, 0x6440416a } },
787 { 0xa21c,
788 { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
789 { AR5K_DCU_FP,
790 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
791 { AR5K_PHY_AGC,
792 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
793 { AR5K_PHY(11),
794 { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
795 { AR5K_PHY(15),
796 { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
797 { AR5K_PHY(19),
798 { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
799 { AR5K_PHY_PAPD_PROBE,
800 { 0x00004883, 0x00004883, 0x00004883, 0x00004883, 0x00004883 } },
801 { AR5K_PHY(80),
802 { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
803 { AR5K_PHY(86),
804 { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
805 { AR5K_PHY(93),
806 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
807 { AR5K_PHY_SPENDING,
808 { 0x00000018, 0x00000018, 0x00000018, 0x00000018, 0x00000018 } },
809 { AR5K_PHY_CCKTXCTL,
810 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
811 { AR5K_PHY(642),
812 { 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
813 { 0xa23c,
814 { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
815};
816
817/* Initial mode-specific settings for AR5212 + RF5112 (Written after ar5212_ini) */
818/* XXX: No dumps for turbog yet, but i found settings from old values so it should be ok */
819static const struct ath5k_ini_mode ar5212_rf5112_ini_mode_end[] = {
820 { AR5K_TXCFG,
821 /* a/XR aTurbo b g (DYN) gTurbo */
822 { 0x00008015, 0x00008015, 0x00008015, 0x00008015, 0x00008015 } },
823 { AR5K_USEC_5211,
824 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
825 { AR5K_PHY(10),
826 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
827 { AR5K_PHY(13),
828 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
829 { AR5K_PHY(14),
830 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
831 { AR5K_PHY(18),
832 { 0x0018da6d, 0x0018da6d, 0x0018ca75, 0x0018ca75, 0x0018ca75 } },
833 { AR5K_PHY(20),
834 { 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0, 0x0de8b4e0 } },
835 { AR5K_PHY_SIG,
836 { 0x7e800d2e, 0x7e800d2e, 0x7ee80d2e, 0x7ee80d2e, 0x7ee80d2e } },
837 { AR5K_PHY_AGCCOARSE,
838 { 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e, 0x3137665e } },
839 { AR5K_PHY(27),
840 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
841 { AR5K_PHY_RX_DELAY,
842 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
843 { AR5K_PHY_FRAME_CTL_5211,
844 { 0xf7b81020, 0xf7b81020, 0xf7b80d10, 0xf7b81010, 0xf7b81010 } },
845 { AR5K_PHY_CCKTXCTL,
846 { 0x00000000, 0x00000000, 0x00000008, 0x00000008, 0x00000008 } },
847 { AR5K_PHY(642),
848 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
849 { AR5K_PHY_GAIN_2GHZ,
850 { 0x642c0140, 0x642c0140, 0x6442c160, 0x6442c160, 0x6442c160 } },
851 { 0xa21c,
852 { 0x1883800a, 0x1883800a, 0x1873800a, 0x1883800a, 0x1883800a } },
853 { AR5K_DCU_FP,
854 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
855 { AR5K_PHY_AGC,
856 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
857 { AR5K_PHY(11),
858 { 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe, 0x00022ffe } },
859 { AR5K_PHY(15),
860 { 0x00020100, 0x00020100, 0x00020100, 0x00020100, 0x00020100 } },
861 { AR5K_PHY(19),
862 { 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c, 0x1284613c } },
863 { AR5K_PHY_PAPD_PROBE,
864 { 0x00004882, 0x00004882, 0x00004882, 0x00004882, 0x00004882 } },
865 { AR5K_PHY(80),
866 { 0x00000004, 0x00000004, 0x00000004, 0x00000004, 0x00000004 } },
867 { AR5K_PHY(86),
868 { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
869 { AR5K_PHY(93),
870 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
871 { 0xa228,
872 { 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5, 0x000001b5 } },
873 { 0xa23c,
874 { 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af, 0x13c889af } },
875};
876
877/* Initial mode-specific settings for RF5413/5414 (Written after ar5212_ini) */
878/* XXX: No dumps for turbog yet, so turbog is the same with g here with some
879 * minor tweaking based on dumps from other chips */
880static const struct ath5k_ini_mode rf5413_ini_mode_end[] = {
881 { AR5K_TXCFG,
882 /* a/XR aTurbo b g gTurbo */
883 { 0x00000015, 0x00000015, 0x00000015, 0x00000015, 0x00000015 } },
884 { AR5K_USEC_5211,
885 { 0x128d93a7, 0x098813cf, 0x04e01395, 0x12e013ab, 0x098813cf } },
886 { AR5K_PHY(10),
887 { 0x0a020001, 0x0a020001, 0x05020100, 0x0a020001, 0x0a020001 } },
888 { AR5K_PHY(13),
889 { 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e } },
890 { AR5K_PHY(14),
891 { 0x00000007, 0x00000007, 0x0000000b, 0x0000000b, 0x0000000b } },
892 { AR5K_PHY(18),
893 { 0x0018fa61, 0x0018fa61, 0x001a1a63, 0x001a1a63, 0x001a1a63 } },
894 { AR5K_PHY(20),
895 { 0x0c98b4e0, 0x0c98b4e0, 0x0c98b0da, 0x0c98b0da, 0x0c98b0da } },
896 { AR5K_PHY_SIG,
897 { 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e, 0x7ec80d2e } },
898 { AR5K_PHY_AGCCOARSE,
899 { 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e, 0x3139605e } },
900 { AR5K_PHY(27),
901 { 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081 } },
902 { AR5K_PHY_RX_DELAY,
903 { 0x000007d0, 0x000007d0, 0x0000044c, 0x00000898, 0x000007d0 } },
904 { AR5K_PHY_FRAME_CTL_5211,
905 { 0xf7b81000, 0xf7b81000, 0xf7b80d00, 0xf7b81000, 0xf7b81000 } },
906 { AR5K_PHY_CCKTXCTL,
907 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
908 { AR5K_PHY(642),
909 { 0xd6be6788, 0xd6be6788, 0xd03e6788, 0xd03e6788, 0xd03e6788 } },
910 { AR5K_PHY_GAIN_2GHZ,
911 { 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120 } },
912 { 0xa21c,
913 { 0x1883800a, 0x1883800a, 0x1863800a, 0x1883800a, 0x1883800a } },
914 { 0xa300,
915 { 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000 } },
916 { 0xa304,
917 { 0x30032602, 0x30032602, 0x30032602, 0x30032602, 0x30032602 } },
918 { 0xa308,
919 { 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06, 0x48073e06 } },
920 { 0xa30c,
921 { 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a, 0x560b4c0a } },
922 { 0xa310,
923 { 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f, 0x641a600f } },
924 { 0xa314,
925 { 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b, 0x784f6e1b } },
926 { 0xa318,
927 { 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a, 0x868f7c5a } },
928 { 0xa31c,
929 { 0x90cf865b, 0x90cf865b, 0x8ecf865b, 0x8ecf865b, 0x8ecf865b } },
930 { 0xa320,
931 { 0x9d4f970f, 0x9d4f970f, 0x9b4f970f, 0x9b4f970f, 0x9b4f970f } },
932 { 0xa324,
933 { 0xa7cfa38f, 0xa7cfa38f, 0xa3cf9f8f, 0xa3cf9f8f, 0xa3cf9f8f } },
934 { 0xa328,
935 { 0xb55faf1f, 0xb55faf1f, 0xb35faf1f, 0xb35faf1f, 0xb35faf1f } },
936 { 0xa32c,
937 { 0xbddfb99f, 0xbddfb99f, 0xbbdfb99f, 0xbbdfb99f, 0xbbdfb99f } },
938 { 0xa330,
939 { 0xcb7fc53f, 0xcb7fc53f, 0xcb7fc73f, 0xcb7fc73f, 0xcb7fc73f } },
940 { 0xa334,
941 { 0xd5ffd1bf, 0xd5ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf, 0xd3ffd1bf } },
942 { AR5K_DCU_FP,
943 { 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0, 0x000003e0 } },
944 { 0x4068,
945 { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
946 { 0x8060,
947 { 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f, 0x0000000f } },
948 { 0x809c,
949 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
950 { 0x80a0,
951 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
952 { 0x8118,
953 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
954 { 0x811c,
955 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
956 { 0x8120,
957 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
958 { 0x8124,
959 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
960 { 0x8128,
961 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
962 { 0x812c,
963 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
964 { 0x8130,
965 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
966 { 0x8134,
967 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
968 { 0x8138,
969 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
970 { 0x813c,
971 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
972 { 0x8140,
973 { 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9, 0x800003f9 } },
974 { 0x8144,
975 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
976 { AR5K_PHY_AGC,
977 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
978 { AR5K_PHY(11),
979 { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
980 { AR5K_PHY(15),
981 { 0x00200400, 0x00200400, 0x00200400, 0x00200400, 0x00200400 } },
982 { AR5K_PHY(19),
983 { 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c, 0x1284233c } },
984 { AR5K_PHY_SCR,
985 { 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f, 0x0000001f } },
986 { AR5K_PHY_SLMT,
987 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
988 { AR5K_PHY_SCAL,
989 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
990 { AR5K_PHY(86),
991 { 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff, 0x00081fff } },
992 { AR5K_PHY(96),
993 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
994 { AR5K_PHY(97),
995 { 0x02800000, 0x02800000, 0x02800000, 0x02800000, 0x02800000 } },
996 { AR5K_PHY(104),
997 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
998 { AR5K_PHY(120),
999 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1000 { AR5K_PHY(121),
1001 { 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa } },
1002 { AR5K_PHY(122),
1003 { 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478, 0x3c466478 } },
1004 { AR5K_PHY(123),
1005 { 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa, 0x000000aa } },
1006 { AR5K_PHY_SCLOCK,
1007 { 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c, 0x0000000c } },
1008 { AR5K_PHY_SDELAY,
1009 { 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff, 0x000000ff } },
1010 { AR5K_PHY_SPENDING,
1011 { 0x00000014, 0x00000014, 0x00000014, 0x00000014, 0x00000014 } },
1012 { 0xa228,
1013 { 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5, 0x000009b5 } },
1014 { 0xa23c,
1015 { 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af, 0x93c889af } },
1016 { 0xa24c,
1017 { 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001 } },
1018 { 0xa250,
1019 { 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000, 0x0000a000 } },
1020 { 0xa254,
1021 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1022 { 0xa258,
1023 { 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380, 0x0cc75380 } },
1024 { 0xa25c,
1025 { 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01, 0x0f0f0f01 } },
1026 { 0xa260,
1027 { 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01, 0x5f690f01 } },
1028 { 0xa264,
1029 { 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11, 0x00418a11 } },
1030 { 0xa268,
1031 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1032 { 0xa26c,
1033 { 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a, 0x0c30c16a } },
1034 { 0xa270,
1035 { 0x00820820, 0x00820820, 0x00820820, 0x00820820, 0x00820820 } },
1036 { 0xa274,
1037 { 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa, 0x081b7caa } },
1038 { 0xa278,
1039 { 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce } },
1040 { 0xa27c,
1041 { 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce, 0x051701ce } },
1042 { 0xa338,
1043 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1044 { 0xa33c,
1045 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1046 { 0xa340,
1047 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1048 { 0xa344,
1049 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
1050 { 0xa348,
1051 { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1052 { 0xa34c,
1053 { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1054 { 0xa350,
1055 { 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff, 0x3fffffff } },
1056 { 0xa354,
1057 { 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff, 0x0003ffff } },
1058 { 0xa358,
1059 { 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f, 0x79a8aa1f } },
1060 { 0xa35c,
1061 { 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f, 0x066c420f } },
1062 { 0xa360,
1063 { 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207, 0x0f282207 } },
1064 { 0xa364,
1065 { 0x17601685, 0x17601685, 0x17601685, 0x17601685, 0x17601685 } },
1066 { 0xa368,
1067 { 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104, 0x1f801104 } },
1068 { 0xa36c,
1069 { 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03, 0x37a00c03 } },
1070 { 0xa370,
1071 { 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883, 0x3fc40883 } },
1072 { 0xa374,
1073 { 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803, 0x57c00803 } },
1074 { 0xa378,
1075 { 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682, 0x5fd80682 } },
1076 { 0xa37c,
1077 { 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482, 0x7fe00482 } },
1078 { 0xa380,
1079 { 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba, 0x7f3c7bba } },
1080 { 0xa384,
1081 { 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0, 0xf3307ff0 } },
1082};
1083
1084/*
1085 * Initial BaseBand Gain settings for RF5111/5112 (AR5210 comes with
1086 * RF5110 only so initial BB Gain settings are included in AR5K_AR5210_INI)
1087 */
1088
1089/* RF5111 Initial BaseBand Gain settings */
1090static const struct ath5k_ini rf5111_ini_bbgain[] = {
1091 { AR5K_BB_GAIN(0), 0x00000000 },
1092 { AR5K_BB_GAIN(1), 0x00000020 },
1093 { AR5K_BB_GAIN(2), 0x00000010 },
1094 { AR5K_BB_GAIN(3), 0x00000030 },
1095 { AR5K_BB_GAIN(4), 0x00000008 },
1096 { AR5K_BB_GAIN(5), 0x00000028 },
1097 { AR5K_BB_GAIN(6), 0x00000004 },
1098 { AR5K_BB_GAIN(7), 0x00000024 },
1099 { AR5K_BB_GAIN(8), 0x00000014 },
1100 { AR5K_BB_GAIN(9), 0x00000034 },
1101 { AR5K_BB_GAIN(10), 0x0000000c },
1102 { AR5K_BB_GAIN(11), 0x0000002c },
1103 { AR5K_BB_GAIN(12), 0x00000002 },
1104 { AR5K_BB_GAIN(13), 0x00000022 },
1105 { AR5K_BB_GAIN(14), 0x00000012 },
1106 { AR5K_BB_GAIN(15), 0x00000032 },
1107 { AR5K_BB_GAIN(16), 0x0000000a },
1108 { AR5K_BB_GAIN(17), 0x0000002a },
1109 { AR5K_BB_GAIN(18), 0x00000006 },
1110 { AR5K_BB_GAIN(19), 0x00000026 },
1111 { AR5K_BB_GAIN(20), 0x00000016 },
1112 { AR5K_BB_GAIN(21), 0x00000036 },
1113 { AR5K_BB_GAIN(22), 0x0000000e },
1114 { AR5K_BB_GAIN(23), 0x0000002e },
1115 { AR5K_BB_GAIN(24), 0x00000001 },
1116 { AR5K_BB_GAIN(25), 0x00000021 },
1117 { AR5K_BB_GAIN(26), 0x00000011 },
1118 { AR5K_BB_GAIN(27), 0x00000031 },
1119 { AR5K_BB_GAIN(28), 0x00000009 },
1120 { AR5K_BB_GAIN(29), 0x00000029 },
1121 { AR5K_BB_GAIN(30), 0x00000005 },
1122 { AR5K_BB_GAIN(31), 0x00000025 },
1123 { AR5K_BB_GAIN(32), 0x00000015 },
1124 { AR5K_BB_GAIN(33), 0x00000035 },
1125 { AR5K_BB_GAIN(34), 0x0000000d },
1126 { AR5K_BB_GAIN(35), 0x0000002d },
1127 { AR5K_BB_GAIN(36), 0x00000003 },
1128 { AR5K_BB_GAIN(37), 0x00000023 },
1129 { AR5K_BB_GAIN(38), 0x00000013 },
1130 { AR5K_BB_GAIN(39), 0x00000033 },
1131 { AR5K_BB_GAIN(40), 0x0000000b },
1132 { AR5K_BB_GAIN(41), 0x0000002b },
1133 { AR5K_BB_GAIN(42), 0x0000002b },
1134 { AR5K_BB_GAIN(43), 0x0000002b },
1135 { AR5K_BB_GAIN(44), 0x0000002b },
1136 { AR5K_BB_GAIN(45), 0x0000002b },
1137 { AR5K_BB_GAIN(46), 0x0000002b },
1138 { AR5K_BB_GAIN(47), 0x0000002b },
1139 { AR5K_BB_GAIN(48), 0x0000002b },
1140 { AR5K_BB_GAIN(49), 0x0000002b },
1141 { AR5K_BB_GAIN(50), 0x0000002b },
1142 { AR5K_BB_GAIN(51), 0x0000002b },
1143 { AR5K_BB_GAIN(52), 0x0000002b },
1144 { AR5K_BB_GAIN(53), 0x0000002b },
1145 { AR5K_BB_GAIN(54), 0x0000002b },
1146 { AR5K_BB_GAIN(55), 0x0000002b },
1147 { AR5K_BB_GAIN(56), 0x0000002b },
1148 { AR5K_BB_GAIN(57), 0x0000002b },
1149 { AR5K_BB_GAIN(58), 0x0000002b },
1150 { AR5K_BB_GAIN(59), 0x0000002b },
1151 { AR5K_BB_GAIN(60), 0x0000002b },
1152 { AR5K_BB_GAIN(61), 0x0000002b },
1153 { AR5K_BB_GAIN(62), 0x00000002 },
1154 { AR5K_BB_GAIN(63), 0x00000016 },
1155};
1156
1157/* RF5112 Initial BaseBand Gain settings (Same for RF5413/5414) */
1158static const struct ath5k_ini rf5112_ini_bbgain[] = {
1159 { AR5K_BB_GAIN(0), 0x00000000 },
1160 { AR5K_BB_GAIN(1), 0x00000001 },
1161 { AR5K_BB_GAIN(2), 0x00000002 },
1162 { AR5K_BB_GAIN(3), 0x00000003 },
1163 { AR5K_BB_GAIN(4), 0x00000004 },
1164 { AR5K_BB_GAIN(5), 0x00000005 },
1165 { AR5K_BB_GAIN(6), 0x00000008 },
1166 { AR5K_BB_GAIN(7), 0x00000009 },
1167 { AR5K_BB_GAIN(8), 0x0000000a },
1168 { AR5K_BB_GAIN(9), 0x0000000b },
1169 { AR5K_BB_GAIN(10), 0x0000000c },
1170 { AR5K_BB_GAIN(11), 0x0000000d },
1171 { AR5K_BB_GAIN(12), 0x00000010 },
1172 { AR5K_BB_GAIN(13), 0x00000011 },
1173 { AR5K_BB_GAIN(14), 0x00000012 },
1174 { AR5K_BB_GAIN(15), 0x00000013 },
1175 { AR5K_BB_GAIN(16), 0x00000014 },
1176 { AR5K_BB_GAIN(17), 0x00000015 },
1177 { AR5K_BB_GAIN(18), 0x00000018 },
1178 { AR5K_BB_GAIN(19), 0x00000019 },
1179 { AR5K_BB_GAIN(20), 0x0000001a },
1180 { AR5K_BB_GAIN(21), 0x0000001b },
1181 { AR5K_BB_GAIN(22), 0x0000001c },
1182 { AR5K_BB_GAIN(23), 0x0000001d },
1183 { AR5K_BB_GAIN(24), 0x00000020 },
1184 { AR5K_BB_GAIN(25), 0x00000021 },
1185 { AR5K_BB_GAIN(26), 0x00000022 },
1186 { AR5K_BB_GAIN(27), 0x00000023 },
1187 { AR5K_BB_GAIN(28), 0x00000024 },
1188 { AR5K_BB_GAIN(29), 0x00000025 },
1189 { AR5K_BB_GAIN(30), 0x00000028 },
1190 { AR5K_BB_GAIN(31), 0x00000029 },
1191 { AR5K_BB_GAIN(32), 0x0000002a },
1192 { AR5K_BB_GAIN(33), 0x0000002b },
1193 { AR5K_BB_GAIN(34), 0x0000002c },
1194 { AR5K_BB_GAIN(35), 0x0000002d },
1195 { AR5K_BB_GAIN(36), 0x00000030 },
1196 { AR5K_BB_GAIN(37), 0x00000031 },
1197 { AR5K_BB_GAIN(38), 0x00000032 },
1198 { AR5K_BB_GAIN(39), 0x00000033 },
1199 { AR5K_BB_GAIN(40), 0x00000034 },
1200 { AR5K_BB_GAIN(41), 0x00000035 },
1201 { AR5K_BB_GAIN(42), 0x00000035 },
1202 { AR5K_BB_GAIN(43), 0x00000035 },
1203 { AR5K_BB_GAIN(44), 0x00000035 },
1204 { AR5K_BB_GAIN(45), 0x00000035 },
1205 { AR5K_BB_GAIN(46), 0x00000035 },
1206 { AR5K_BB_GAIN(47), 0x00000035 },
1207 { AR5K_BB_GAIN(48), 0x00000035 },
1208 { AR5K_BB_GAIN(49), 0x00000035 },
1209 { AR5K_BB_GAIN(50), 0x00000035 },
1210 { AR5K_BB_GAIN(51), 0x00000035 },
1211 { AR5K_BB_GAIN(52), 0x00000035 },
1212 { AR5K_BB_GAIN(53), 0x00000035 },
1213 { AR5K_BB_GAIN(54), 0x00000035 },
1214 { AR5K_BB_GAIN(55), 0x00000035 },
1215 { AR5K_BB_GAIN(56), 0x00000035 },
1216 { AR5K_BB_GAIN(57), 0x00000035 },
1217 { AR5K_BB_GAIN(58), 0x00000035 },
1218 { AR5K_BB_GAIN(59), 0x00000035 },
1219 { AR5K_BB_GAIN(60), 0x00000035 },
1220 { AR5K_BB_GAIN(61), 0x00000035 },
1221 { AR5K_BB_GAIN(62), 0x00000010 },
1222 { AR5K_BB_GAIN(63), 0x0000001a },
1223};
1224
1225
1226/*
1227 * Write initial register dump
1228 */
1229static void ath5k_hw_ini_registers(struct ath5k_hw *ah, unsigned int size,
1230 const struct ath5k_ini *ini_regs, bool change_channel)
1231{
1232 unsigned int i;
1233
1234 /* Write initial registers */
1235 for (i = 0; i < size; i++) {
1236 /* On channel change there is
1237 * no need to mess with PCU */
1238 if (change_channel &&
1239 ini_regs[i].ini_register >= AR5K_PCU_MIN &&
1240 ini_regs[i].ini_register <= AR5K_PCU_MAX)
1241 continue;
1242
1243 switch (ini_regs[i].ini_mode) {
1244 case AR5K_INI_READ:
1245 /* Cleared on read */
1246 ath5k_hw_reg_read(ah, ini_regs[i].ini_register);
1247 break;
1248 case AR5K_INI_WRITE:
1249 default:
1250 AR5K_REG_WAIT(i);
1251 ath5k_hw_reg_write(ah, ini_regs[i].ini_value,
1252 ini_regs[i].ini_register);
1253 }
1254 }
1255}
1256
1257static void ath5k_hw_ini_mode_registers(struct ath5k_hw *ah,
1258 unsigned int size, const struct ath5k_ini_mode *ini_mode,
1259 u8 mode)
1260{
1261 unsigned int i;
1262
1263 for (i = 0; i < size; i++) {
1264 AR5K_REG_WAIT(i);
1265 ath5k_hw_reg_write(ah, ini_mode[i].mode_value[mode],
1266 (u32)ini_mode[i].mode_register);
1267 }
1268
1269}
1270
1271int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel)
1272{
1273 /*
1274 * Write initial register settings
1275 */
1276
1277 /* For AR5212 and combatible */
1278 if (ah->ah_version == AR5K_AR5212){
1279
1280 /* First set of mode-specific settings */
1281 ath5k_hw_ini_mode_registers(ah,
1282 ARRAY_SIZE(ar5212_ini_mode_start),
1283 ar5212_ini_mode_start, mode);
1284
1285 /*
1286 * Write initial settings common for all modes
1287 */
1288 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5212_ini),
1289 ar5212_ini, change_channel);
1290
1291 /* Second set of mode-specific settings */
1292 if (ah->ah_radio == AR5K_RF5111){
1293 ath5k_hw_ini_mode_registers(ah,
1294 ARRAY_SIZE(ar5212_rf5111_ini_mode_end),
1295 ar5212_rf5111_ini_mode_end, mode);
1296 /* Baseband gain table */
1297 ath5k_hw_ini_registers(ah,
1298 ARRAY_SIZE(rf5111_ini_bbgain),
1299 rf5111_ini_bbgain, change_channel);
1300 } else if (ah->ah_radio == AR5K_RF5112){
1301 ath5k_hw_ini_mode_registers(ah,
1302 ARRAY_SIZE(ar5212_rf5112_ini_mode_end),
1303 ar5212_rf5112_ini_mode_end, mode);
1304 /* Baseband gain table */
1305 ath5k_hw_ini_registers(ah,
1306 ARRAY_SIZE(rf5112_ini_bbgain),
1307 rf5112_ini_bbgain, change_channel);
1308 } else if (ah->ah_radio == AR5K_RF5413){
1309 ath5k_hw_ini_mode_registers(ah,
1310 ARRAY_SIZE(rf5413_ini_mode_end),
1311 rf5413_ini_mode_end, mode);
1312 /* Baseband gain table */
1313 ath5k_hw_ini_registers(ah,
1314 ARRAY_SIZE(rf5112_ini_bbgain),
1315 rf5112_ini_bbgain, change_channel);
1316 }
1317 /* For AR5211 */
1318 } else if (ah->ah_version == AR5K_AR5211) {
1319
1320 if(mode > 2){ /* AR5K_INI_VAL_11B */
1321 ATH5K_ERR(ah->ah_sc,"unsupported channel mode: %d\n", mode);
1322 return -EINVAL;
1323 }
1324
1325 /* Mode-specific settings */
1326 ath5k_hw_ini_mode_registers(ah, ARRAY_SIZE(ar5211_ini_mode),
1327 ar5211_ini_mode, mode);
1328
1329 /*
1330 * Write initial settings common for all modes
1331 */
1332 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5211_ini),
1333 ar5211_ini, change_channel);
1334
1335 /* AR5211 only comes with 5111 */
1336
1337 /* Baseband gain table */
1338 ath5k_hw_ini_registers(ah, ARRAY_SIZE(rf5111_ini_bbgain),
1339 rf5111_ini_bbgain, change_channel);
1340 /* For AR5210 (for mode settings check out ath5k_hw_reset_tx_queue) */
1341 } else if (ah->ah_version == AR5K_AR5210) {
1342 ath5k_hw_ini_registers(ah, ARRAY_SIZE(ar5210_ini),
1343 ar5210_ini, change_channel);
1344 }
1345
1346 return 0;
1347}
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
new file mode 100644
index 000000000000..b95941797141
--- /dev/null
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -0,0 +1,2071 @@
1/*
2 * PHY functions
3 *
4 * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
5 * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com>
6 * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *
20 */
21
22#include <linux/delay.h>
23
24#include "ath5k.h"
25#include "reg.h"
26#include "base.h"
27
28/* Struct to hold initial RF register values (RF Banks) */
29struct ath5k_ini_rf {
30 u8 rf_bank; /* check out ath5k_reg.h */
31 u16 rf_register; /* register address */
32 u32 rf_value[5]; /* register value for different modes (above) */
33};
34
35/*
36 * Mode-specific RF Gain table (64bytes) for RF5111/5112
37 * (RF5110 only comes with AR5210 and only supports a/turbo a mode so initial
38 * RF Gain values are included in AR5K_AR5210_INI)
39 */
40struct ath5k_ini_rfgain {
41 u16 rfg_register; /* RF Gain register address */
42 u32 rfg_value[2]; /* [freq (see below)] */
43};
44
45struct ath5k_gain_opt {
46 u32 go_default;
47 u32 go_steps_count;
48 const struct ath5k_gain_opt_step go_step[AR5K_GAIN_STEP_COUNT];
49};
50
51/* RF5111 mode-specific init registers */
52static const struct ath5k_ini_rf rfregs_5111[] = {
53 { 0, 0x989c,
54 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
55 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
56 { 0, 0x989c,
57 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
58 { 0, 0x989c,
59 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
60 { 0, 0x989c,
61 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
62 { 0, 0x989c,
63 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
64 { 0, 0x989c,
65 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
66 { 0, 0x989c,
67 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
68 { 0, 0x989c,
69 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
70 { 0, 0x989c,
71 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
72 { 0, 0x989c,
73 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
74 { 0, 0x989c,
75 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
76 { 0, 0x989c,
77 { 0x00380000, 0x00380000, 0x00380000, 0x00380000, 0x00380000 } },
78 { 0, 0x989c,
79 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
80 { 0, 0x989c,
81 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
82 { 0, 0x989c,
83 { 0x00000000, 0x00000000, 0x000000c0, 0x00000080, 0x00000080 } },
84 { 0, 0x989c,
85 { 0x000400f9, 0x000400f9, 0x000400ff, 0x000400fd, 0x000400fd } },
86 { 0, 0x98d4,
87 { 0x00000000, 0x00000000, 0x00000004, 0x00000004, 0x00000004 } },
88 { 1, 0x98d4,
89 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
90 { 2, 0x98d4,
91 { 0x00000010, 0x00000014, 0x00000010, 0x00000010, 0x00000014 } },
92 { 3, 0x98d8,
93 { 0x00601068, 0x00601068, 0x00601068, 0x00601068, 0x00601068 } },
94 { 6, 0x989c,
95 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
96 { 6, 0x989c,
97 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
98 { 6, 0x989c,
99 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
100 { 6, 0x989c,
101 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
102 { 6, 0x989c,
103 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
104 { 6, 0x989c,
105 { 0x10000000, 0x10000000, 0x10000000, 0x10000000, 0x10000000 } },
106 { 6, 0x989c,
107 { 0x04000000, 0x04000000, 0x04000000, 0x04000000, 0x04000000 } },
108 { 6, 0x989c,
109 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
110 { 6, 0x989c,
111 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
112 { 6, 0x989c,
113 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
114 { 6, 0x989c,
115 { 0x00000000, 0x00000000, 0x0a000000, 0x00000000, 0x00000000 } },
116 { 6, 0x989c,
117 { 0x003800c0, 0x00380080, 0x023800c0, 0x003800c0, 0x003800c0 } },
118 { 6, 0x989c,
119 { 0x00020006, 0x00020006, 0x00000006, 0x00020006, 0x00020006 } },
120 { 6, 0x989c,
121 { 0x00000089, 0x00000089, 0x00000089, 0x00000089, 0x00000089 } },
122 { 6, 0x989c,
123 { 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0, 0x000000a0 } },
124 { 6, 0x989c,
125 { 0x00040007, 0x00040007, 0x00040007, 0x00040007, 0x00040007 } },
126 { 6, 0x98d4,
127 { 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a, 0x0000001a } },
128 { 7, 0x989c,
129 { 0x00000040, 0x00000048, 0x00000040, 0x00000040, 0x00000040 } },
130 { 7, 0x989c,
131 { 0x00000010, 0x00000010, 0x00000010, 0x00000010, 0x00000010 } },
132 { 7, 0x989c,
133 { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
134 { 7, 0x989c,
135 { 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f, 0x0000004f } },
136 { 7, 0x989c,
137 { 0x000000f1, 0x000000f1, 0x00000061, 0x000000f1, 0x000000f1 } },
138 { 7, 0x989c,
139 { 0x0000904f, 0x0000904f, 0x0000904c, 0x0000904f, 0x0000904f } },
140 { 7, 0x989c,
141 { 0x0000125a, 0x0000125a, 0x0000129a, 0x0000125a, 0x0000125a } },
142 { 7, 0x98cc,
143 { 0x0000000e, 0x0000000e, 0x0000000f, 0x0000000e, 0x0000000e } },
144};
145
146/* Initial RF Gain settings for RF5111 */
147static const struct ath5k_ini_rfgain rfgain_5111[] = {
148 /* 5Ghz 2Ghz */
149 { AR5K_RF_GAIN(0), { 0x000001a9, 0x00000000 } },
150 { AR5K_RF_GAIN(1), { 0x000001e9, 0x00000040 } },
151 { AR5K_RF_GAIN(2), { 0x00000029, 0x00000080 } },
152 { AR5K_RF_GAIN(3), { 0x00000069, 0x00000150 } },
153 { AR5K_RF_GAIN(4), { 0x00000199, 0x00000190 } },
154 { AR5K_RF_GAIN(5), { 0x000001d9, 0x000001d0 } },
155 { AR5K_RF_GAIN(6), { 0x00000019, 0x00000010 } },
156 { AR5K_RF_GAIN(7), { 0x00000059, 0x00000044 } },
157 { AR5K_RF_GAIN(8), { 0x00000099, 0x00000084 } },
158 { AR5K_RF_GAIN(9), { 0x000001a5, 0x00000148 } },
159 { AR5K_RF_GAIN(10), { 0x000001e5, 0x00000188 } },
160 { AR5K_RF_GAIN(11), { 0x00000025, 0x000001c8 } },
161 { AR5K_RF_GAIN(12), { 0x000001c8, 0x00000014 } },
162 { AR5K_RF_GAIN(13), { 0x00000008, 0x00000042 } },
163 { AR5K_RF_GAIN(14), { 0x00000048, 0x00000082 } },
164 { AR5K_RF_GAIN(15), { 0x00000088, 0x00000178 } },
165 { AR5K_RF_GAIN(16), { 0x00000198, 0x000001b8 } },
166 { AR5K_RF_GAIN(17), { 0x000001d8, 0x000001f8 } },
167 { AR5K_RF_GAIN(18), { 0x00000018, 0x00000012 } },
168 { AR5K_RF_GAIN(19), { 0x00000058, 0x00000052 } },
169 { AR5K_RF_GAIN(20), { 0x00000098, 0x00000092 } },
170 { AR5K_RF_GAIN(21), { 0x000001a4, 0x0000017c } },
171 { AR5K_RF_GAIN(22), { 0x000001e4, 0x000001bc } },
172 { AR5K_RF_GAIN(23), { 0x00000024, 0x000001fc } },
173 { AR5K_RF_GAIN(24), { 0x00000064, 0x0000000a } },
174 { AR5K_RF_GAIN(25), { 0x000000a4, 0x0000004a } },
175 { AR5K_RF_GAIN(26), { 0x000000e4, 0x0000008a } },
176 { AR5K_RF_GAIN(27), { 0x0000010a, 0x0000015a } },
177 { AR5K_RF_GAIN(28), { 0x0000014a, 0x0000019a } },
178 { AR5K_RF_GAIN(29), { 0x0000018a, 0x000001da } },
179 { AR5K_RF_GAIN(30), { 0x000001ca, 0x0000000e } },
180 { AR5K_RF_GAIN(31), { 0x0000000a, 0x0000004e } },
181 { AR5K_RF_GAIN(32), { 0x0000004a, 0x0000008e } },
182 { AR5K_RF_GAIN(33), { 0x0000008a, 0x0000015e } },
183 { AR5K_RF_GAIN(34), { 0x000001ba, 0x0000019e } },
184 { AR5K_RF_GAIN(35), { 0x000001fa, 0x000001de } },
185 { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000009 } },
186 { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000049 } },
187 { AR5K_RF_GAIN(38), { 0x00000186, 0x00000089 } },
188 { AR5K_RF_GAIN(39), { 0x000001c6, 0x00000179 } },
189 { AR5K_RF_GAIN(40), { 0x00000006, 0x000001b9 } },
190 { AR5K_RF_GAIN(41), { 0x00000046, 0x000001f9 } },
191 { AR5K_RF_GAIN(42), { 0x00000086, 0x00000039 } },
192 { AR5K_RF_GAIN(43), { 0x000000c6, 0x00000079 } },
193 { AR5K_RF_GAIN(44), { 0x000000c6, 0x000000b9 } },
194 { AR5K_RF_GAIN(45), { 0x000000c6, 0x000001bd } },
195 { AR5K_RF_GAIN(46), { 0x000000c6, 0x000001fd } },
196 { AR5K_RF_GAIN(47), { 0x000000c6, 0x0000003d } },
197 { AR5K_RF_GAIN(48), { 0x000000c6, 0x0000007d } },
198 { AR5K_RF_GAIN(49), { 0x000000c6, 0x000000bd } },
199 { AR5K_RF_GAIN(50), { 0x000000c6, 0x000000fd } },
200 { AR5K_RF_GAIN(51), { 0x000000c6, 0x000000fd } },
201 { AR5K_RF_GAIN(52), { 0x000000c6, 0x000000fd } },
202 { AR5K_RF_GAIN(53), { 0x000000c6, 0x000000fd } },
203 { AR5K_RF_GAIN(54), { 0x000000c6, 0x000000fd } },
204 { AR5K_RF_GAIN(55), { 0x000000c6, 0x000000fd } },
205 { AR5K_RF_GAIN(56), { 0x000000c6, 0x000000fd } },
206 { AR5K_RF_GAIN(57), { 0x000000c6, 0x000000fd } },
207 { AR5K_RF_GAIN(58), { 0x000000c6, 0x000000fd } },
208 { AR5K_RF_GAIN(59), { 0x000000c6, 0x000000fd } },
209 { AR5K_RF_GAIN(60), { 0x000000c6, 0x000000fd } },
210 { AR5K_RF_GAIN(61), { 0x000000c6, 0x000000fd } },
211 { AR5K_RF_GAIN(62), { 0x000000c6, 0x000000fd } },
212 { AR5K_RF_GAIN(63), { 0x000000c6, 0x000000fd } },
213};
214
215static const struct ath5k_gain_opt rfgain_opt_5111 = {
216 4,
217 9,
218 {
219 { { 4, 1, 1, 1 }, 6 },
220 { { 4, 0, 1, 1 }, 4 },
221 { { 3, 1, 1, 1 }, 3 },
222 { { 4, 0, 0, 1 }, 1 },
223 { { 4, 1, 1, 0 }, 0 },
224 { { 4, 0, 1, 0 }, -2 },
225 { { 3, 1, 1, 0 }, -3 },
226 { { 4, 0, 0, 0 }, -4 },
227 { { 2, 1, 1, 0 }, -6 }
228 }
229};
230
231/* RF5112 mode-specific init registers */
232static const struct ath5k_ini_rf rfregs_5112[] = {
233 { 1, 0x98d4,
234 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
235 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
236 { 2, 0x98d0,
237 { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
238 { 3, 0x98dc,
239 { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
240 { 6, 0x989c,
241 { 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000, 0x00a00000 } },
242 { 6, 0x989c,
243 { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
244 { 6, 0x989c,
245 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
246 { 6, 0x989c,
247 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
248 { 6, 0x989c,
249 { 0x00660000, 0x00660000, 0x00660000, 0x00660000, 0x00660000 } },
250 { 6, 0x989c,
251 { 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000, 0x00db0000 } },
252 { 6, 0x989c,
253 { 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000, 0x00f10000 } },
254 { 6, 0x989c,
255 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
256 { 6, 0x989c,
257 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
258 { 6, 0x989c,
259 { 0x00730000, 0x00730000, 0x00730000, 0x00730000, 0x00730000 } },
260 { 6, 0x989c,
261 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
262 { 6, 0x989c,
263 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
264 { 6, 0x989c,
265 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
266 { 6, 0x989c,
267 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
268 { 6, 0x989c,
269 { 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000, 0x008b0000 } },
270 { 6, 0x989c,
271 { 0x00600000, 0x00600000, 0x00600000, 0x00600000, 0x00600000 } },
272 { 6, 0x989c,
273 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
274 { 6, 0x989c,
275 { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
276 { 6, 0x989c,
277 { 0x00640000, 0x00640000, 0x00640000, 0x00640000, 0x00640000 } },
278 { 6, 0x989c,
279 { 0x00200000, 0x00200000, 0x00200000, 0x00200000, 0x00200000 } },
280 { 6, 0x989c,
281 { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
282 { 6, 0x989c,
283 { 0x00250000, 0x00250000, 0x00250000, 0x00250000, 0x00250000 } },
284 { 6, 0x989c,
285 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
286 { 6, 0x989c,
287 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
288 { 6, 0x989c,
289 { 0x00510000, 0x00510000, 0x00510000, 0x00510000, 0x00510000 } },
290 { 6, 0x989c,
291 { 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000, 0x1c040000 } },
292 { 6, 0x989c,
293 { 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000, 0x000a0000 } },
294 { 6, 0x989c,
295 { 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000, 0x00a10000 } },
296 { 6, 0x989c,
297 { 0x00400000, 0x00400000, 0x00400000, 0x00400000, 0x00400000 } },
298 { 6, 0x989c,
299 { 0x03090000, 0x03090000, 0x03090000, 0x03090000, 0x03090000 } },
300 { 6, 0x989c,
301 { 0x06000000, 0x06000000, 0x06000000, 0x06000000, 0x06000000 } },
302 { 6, 0x989c,
303 { 0x000000b0, 0x000000b0, 0x000000a8, 0x000000a8, 0x000000a8 } },
304 { 6, 0x989c,
305 { 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e, 0x0000002e } },
306 { 6, 0x989c,
307 { 0x006c4a41, 0x006c4a41, 0x006c4af1, 0x006c4a61, 0x006c4a61 } },
308 { 6, 0x989c,
309 { 0x0050892a, 0x0050892a, 0x0050892b, 0x0050892b, 0x0050892b } },
310 { 6, 0x989c,
311 { 0x00842400, 0x00842400, 0x00842400, 0x00842400, 0x00842400 } },
312 { 6, 0x989c,
313 { 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200, 0x00c69200 } },
314 { 6, 0x98d0,
315 { 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c, 0x0002000c } },
316 { 7, 0x989c,
317 { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
318 { 7, 0x989c,
319 { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
320 { 7, 0x989c,
321 { 0x0000000a, 0x0000000a, 0x00000012, 0x00000012, 0x00000012 } },
322 { 7, 0x989c,
323 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
324 { 7, 0x989c,
325 { 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1, 0x000000c1 } },
326 { 7, 0x989c,
327 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
328 { 7, 0x989c,
329 { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
330 { 7, 0x989c,
331 { 0x00000022, 0x00000022, 0x00000022, 0x00000022, 0x00000022 } },
332 { 7, 0x989c,
333 { 0x00000092, 0x00000092, 0x00000092, 0x00000092, 0x00000092 } },
334 { 7, 0x989c,
335 { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
336 { 7, 0x989c,
337 { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
338 { 7, 0x989c,
339 { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
340 { 7, 0x98c4,
341 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
342};
343
344/* RF5112A mode-specific init registers */
345static const struct ath5k_ini_rf rfregs_5112a[] = {
346 { 1, 0x98d4,
347 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
348 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
349 { 2, 0x98d0,
350 { 0x03060408, 0x03070408, 0x03060408, 0x03060408, 0x03070408 } },
351 { 3, 0x98dc,
352 { 0x00a0c0c0, 0x00a0c0c0, 0x00e0c0c0, 0x00e0c0c0, 0x00e0c0c0 } },
353 { 6, 0x989c,
354 { 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000, 0x0f000000 } },
355 { 6, 0x989c,
356 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
357 { 6, 0x989c,
358 { 0x00800000, 0x00800000, 0x00800000, 0x00800000, 0x00800000 } },
359 { 6, 0x989c,
360 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
361 { 6, 0x989c,
362 { 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000 } },
363 { 6, 0x989c,
364 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
365 { 6, 0x989c,
366 { 0x00180000, 0x00180000, 0x00180000, 0x00180000, 0x00180000 } },
367 { 6, 0x989c,
368 { 0x00600000, 0x00600000, 0x006e0000, 0x006e0000, 0x006e0000 } },
369 { 6, 0x989c,
370 { 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000, 0x00c70000 } },
371 { 6, 0x989c,
372 { 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000, 0x004b0000 } },
373 { 6, 0x989c,
374 { 0x04480000, 0x04480000, 0x04480000, 0x04480000, 0x04480000 } },
375 { 6, 0x989c,
376 { 0x00220000, 0x00220000, 0x00220000, 0x00220000, 0x00220000 } },
377 { 6, 0x989c,
378 { 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000, 0x00e40000 } },
379 { 6, 0x989c,
380 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
381 { 6, 0x989c,
382 { 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
383 { 6, 0x989c,
384 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
385 { 6, 0x989c,
386 { 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000, 0x043f0000 } },
387 { 6, 0x989c,
388 { 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000, 0x000c0000 } },
389 { 6, 0x989c,
390 { 0x00190000, 0x00190000, 0x00190000, 0x00190000, 0x00190000 } },
391 { 6, 0x989c,
392 { 0x00240000, 0x00240000, 0x00240000, 0x00240000, 0x00240000 } },
393 { 6, 0x989c,
394 { 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000, 0x00b40000 } },
395 { 6, 0x989c,
396 { 0x00990000, 0x00990000, 0x00990000, 0x00990000, 0x00990000 } },
397 { 6, 0x989c,
398 { 0x00500000, 0x00500000, 0x00500000, 0x00500000, 0x00500000 } },
399 { 6, 0x989c,
400 { 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000, 0x002a0000 } },
401 { 6, 0x989c,
402 { 0x00120000, 0x00120000, 0x00120000, 0x00120000, 0x00120000 } },
403 { 6, 0x989c,
404 { 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000, 0xc0320000 } },
405 { 6, 0x989c,
406 { 0x01740000, 0x01740000, 0x01740000, 0x01740000, 0x01740000 } },
407 { 6, 0x989c,
408 { 0x00110000, 0x00110000, 0x00110000, 0x00110000, 0x00110000 } },
409 { 6, 0x989c,
410 { 0x86280000, 0x86280000, 0x86280000, 0x86280000, 0x86280000 } },
411 { 6, 0x989c,
412 { 0x31840000, 0x31840000, 0x31840000, 0x31840000, 0x31840000 } },
413 { 6, 0x989c,
414 { 0x00020080, 0x00020080, 0x00020080, 0x00020080, 0x00020080 } },
415 { 6, 0x989c,
416 { 0x00080009, 0x00080009, 0x00080009, 0x00080009, 0x00080009 } },
417 { 6, 0x989c,
418 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
419 { 6, 0x989c,
420 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
421 { 6, 0x989c,
422 { 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2, 0x000000b2 } },
423 { 6, 0x989c,
424 { 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084, 0x00b02084 } },
425 { 6, 0x989c,
426 { 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4, 0x004125a4 } },
427 { 6, 0x989c,
428 { 0x00119220, 0x00119220, 0x00119220, 0x00119220, 0x00119220 } },
429 { 6, 0x989c,
430 { 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800, 0x001a4800 } },
431 { 6, 0x98d8,
432 { 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230, 0x000b0230 } },
433 { 7, 0x989c,
434 { 0x00000094, 0x00000094, 0x00000094, 0x00000094, 0x00000094 } },
435 { 7, 0x989c,
436 { 0x00000091, 0x00000091, 0x00000091, 0x00000091, 0x00000091 } },
437 { 7, 0x989c,
438 { 0x00000012, 0x00000012, 0x00000012, 0x00000012, 0x00000012 } },
439 { 7, 0x989c,
440 { 0x00000080, 0x00000080, 0x00000080, 0x00000080, 0x00000080 } },
441 { 7, 0x989c,
442 { 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9, 0x000000d9 } },
443 { 7, 0x989c,
444 { 0x00000060, 0x00000060, 0x00000060, 0x00000060, 0x00000060 } },
445 { 7, 0x989c,
446 { 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0, 0x000000f0 } },
447 { 7, 0x989c,
448 { 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2, 0x000000a2 } },
449 { 7, 0x989c,
450 { 0x00000052, 0x00000052, 0x00000052, 0x00000052, 0x00000052 } },
451 { 7, 0x989c,
452 { 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4, 0x000000d4 } },
453 { 7, 0x989c,
454 { 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc, 0x000014cc } },
455 { 7, 0x989c,
456 { 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c, 0x0000048c } },
457 { 7, 0x98c4,
458 { 0x00000003, 0x00000003, 0x00000003, 0x00000003, 0x00000003 } },
459};
460
461
462static const struct ath5k_ini_rf rfregs_2112a[] = {
463 { 1, AR5K_RF_BUFFER_CONTROL_4,
464 /* mode b mode g mode gTurbo */
465 { 0x00000020, 0x00000020, 0x00000020 } },
466 { 2, AR5K_RF_BUFFER_CONTROL_3,
467 { 0x03060408, 0x03060408, 0x03070408 } },
468 { 3, AR5K_RF_BUFFER_CONTROL_6,
469 { 0x00e020c0, 0x00e020c0, 0x00e020c0 } },
470 { 6, AR5K_RF_BUFFER,
471 { 0x0a000000, 0x0a000000, 0x0a000000 } },
472 { 6, AR5K_RF_BUFFER,
473 { 0x00000000, 0x00000000, 0x00000000 } },
474 { 6, AR5K_RF_BUFFER,
475 { 0x00800000, 0x00800000, 0x00800000 } },
476 { 6, AR5K_RF_BUFFER,
477 { 0x002a0000, 0x002a0000, 0x002a0000 } },
478 { 6, AR5K_RF_BUFFER,
479 { 0x00010000, 0x00010000, 0x00010000 } },
480 { 6, AR5K_RF_BUFFER,
481 { 0x00000000, 0x00000000, 0x00000000 } },
482 { 6, AR5K_RF_BUFFER,
483 { 0x00180000, 0x00180000, 0x00180000 } },
484 { 6, AR5K_RF_BUFFER,
485 { 0x006e0000, 0x006e0000, 0x006e0000 } },
486 { 6, AR5K_RF_BUFFER,
487 { 0x00c70000, 0x00c70000, 0x00c70000 } },
488 { 6, AR5K_RF_BUFFER,
489 { 0x004b0000, 0x004b0000, 0x004b0000 } },
490 { 6, AR5K_RF_BUFFER,
491 { 0x04480000, 0x04480000, 0x04480000 } },
492 { 6, AR5K_RF_BUFFER,
493 { 0x002a0000, 0x002a0000, 0x002a0000 } },
494 { 6, AR5K_RF_BUFFER,
495 { 0x00e40000, 0x00e40000, 0x00e40000 } },
496 { 6, AR5K_RF_BUFFER,
497 { 0x00000000, 0x00000000, 0x00000000 } },
498 { 6, AR5K_RF_BUFFER,
499 { 0x00fc0000, 0x00fc0000, 0x00fc0000 } },
500 { 6, AR5K_RF_BUFFER,
501 { 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
502 { 6, AR5K_RF_BUFFER,
503 { 0x043f0000, 0x043f0000, 0x043f0000 } },
504 { 6, AR5K_RF_BUFFER,
505 { 0x0c0c0000, 0x0c0c0000, 0x0c0c0000 } },
506 { 6, AR5K_RF_BUFFER,
507 { 0x02190000, 0x02190000, 0x02190000 } },
508 { 6, AR5K_RF_BUFFER,
509 { 0x00240000, 0x00240000, 0x00240000 } },
510 { 6, AR5K_RF_BUFFER,
511 { 0x00b40000, 0x00b40000, 0x00b40000 } },
512 { 6, AR5K_RF_BUFFER,
513 { 0x00990000, 0x00990000, 0x00990000 } },
514 { 6, AR5K_RF_BUFFER,
515 { 0x00500000, 0x00500000, 0x00500000 } },
516 { 6, AR5K_RF_BUFFER,
517 { 0x002a0000, 0x002a0000, 0x002a0000 } },
518 { 6, AR5K_RF_BUFFER,
519 { 0x00120000, 0x00120000, 0x00120000 } },
520 { 6, AR5K_RF_BUFFER,
521 { 0xc0320000, 0xc0320000, 0xc0320000 } },
522 { 6, AR5K_RF_BUFFER,
523 { 0x01740000, 0x01740000, 0x01740000 } },
524 { 6, AR5K_RF_BUFFER,
525 { 0x00110000, 0x00110000, 0x00110000 } },
526 { 6, AR5K_RF_BUFFER,
527 { 0x86280000, 0x86280000, 0x86280000 } },
528 { 6, AR5K_RF_BUFFER,
529 { 0x31840000, 0x31840000, 0x31840000 } },
530 { 6, AR5K_RF_BUFFER,
531 { 0x00f20080, 0x00f20080, 0x00f20080 } },
532 { 6, AR5K_RF_BUFFER,
533 { 0x00070019, 0x00070019, 0x00070019 } },
534 { 6, AR5K_RF_BUFFER,
535 { 0x00000000, 0x00000000, 0x00000000 } },
536 { 6, AR5K_RF_BUFFER,
537 { 0x00000000, 0x00000000, 0x00000000 } },
538 { 6, AR5K_RF_BUFFER,
539 { 0x000000b2, 0x000000b2, 0x000000b2 } },
540 { 6, AR5K_RF_BUFFER,
541 { 0x00b02184, 0x00b02184, 0x00b02184 } },
542 { 6, AR5K_RF_BUFFER,
543 { 0x004125a4, 0x004125a4, 0x004125a4 } },
544 { 6, AR5K_RF_BUFFER,
545 { 0x00119220, 0x00119220, 0x00119220 } },
546 { 6, AR5K_RF_BUFFER,
547 { 0x001a4800, 0x001a4800, 0x001a4800 } },
548 { 6, AR5K_RF_BUFFER_CONTROL_5,
549 { 0x000b0230, 0x000b0230, 0x000b0230 } },
550 { 7, AR5K_RF_BUFFER,
551 { 0x00000094, 0x00000094, 0x00000094 } },
552 { 7, AR5K_RF_BUFFER,
553 { 0x00000091, 0x00000091, 0x00000091 } },
554 { 7, AR5K_RF_BUFFER,
555 { 0x00000012, 0x00000012, 0x00000012 } },
556 { 7, AR5K_RF_BUFFER,
557 { 0x00000080, 0x00000080, 0x00000080 } },
558 { 7, AR5K_RF_BUFFER,
559 { 0x000000d9, 0x000000d9, 0x000000d9 } },
560 { 7, AR5K_RF_BUFFER,
561 { 0x00000060, 0x00000060, 0x00000060 } },
562 { 7, AR5K_RF_BUFFER,
563 { 0x000000f0, 0x000000f0, 0x000000f0 } },
564 { 7, AR5K_RF_BUFFER,
565 { 0x000000a2, 0x000000a2, 0x000000a2 } },
566 { 7, AR5K_RF_BUFFER,
567 { 0x00000052, 0x00000052, 0x00000052 } },
568 { 7, AR5K_RF_BUFFER,
569 { 0x000000d4, 0x000000d4, 0x000000d4 } },
570 { 7, AR5K_RF_BUFFER,
571 { 0x000014cc, 0x000014cc, 0x000014cc } },
572 { 7, AR5K_RF_BUFFER,
573 { 0x0000048c, 0x0000048c, 0x0000048c } },
574 { 7, AR5K_RF_BUFFER_CONTROL_1,
575 { 0x00000003, 0x00000003, 0x00000003 } },
576};
577
578/* RF5413/5414 mode-specific init registers */
579static const struct ath5k_ini_rf rfregs_5413[] = {
580 { 1, 0x98d4,
581 /* mode a/XR mode aTurbo mode b mode g mode gTurbo */
582 { 0x00000020, 0x00000020, 0x00000020, 0x00000020, 0x00000020 } },
583 { 2, 0x98d0,
584 { 0x00000008, 0x00000008, 0x00000008, 0x00000008, 0x00000008 } },
585 { 3, 0x98dc,
586 { 0x00a000c0, 0x00a000c0, 0x00e000c0, 0x00e000c0, 0x00e000c0 } },
587 { 6, 0x989c,
588 { 0x33000000, 0x33000000, 0x33000000, 0x33000000, 0x33000000 } },
589 { 6, 0x989c,
590 { 0x01000000, 0x01000000, 0x01000000, 0x01000000, 0x01000000 } },
591 { 6, 0x989c,
592 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
593 { 6, 0x989c,
594 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
595 { 6, 0x989c,
596 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
597 { 6, 0x989c,
598 { 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000, 0x1f000000 } },
599 { 6, 0x989c,
600 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
601 { 6, 0x989c,
602 { 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000, 0x00b80000 } },
603 { 6, 0x989c,
604 { 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000, 0x00b70000 } },
605 { 6, 0x989c,
606 { 0x00840000, 0x00840000, 0x00840000, 0x00840000, 0x00840000 } },
607 { 6, 0x989c,
608 { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
609 { 6, 0x989c,
610 { 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000, 0x00c00000 } },
611 { 6, 0x989c,
612 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
613 { 6, 0x989c,
614 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
615 { 6, 0x989c,
616 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
617 { 6, 0x989c,
618 { 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000, 0x00ff0000 } },
619 { 6, 0x989c,
620 { 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000, 0x00d70000 } },
621 { 6, 0x989c,
622 { 0x00610000, 0x00610000, 0x00610000, 0x00610000, 0x00610000 } },
623 { 6, 0x989c,
624 { 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000, 0x00fe0000 } },
625 { 6, 0x989c,
626 { 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000, 0x00de0000 } },
627 { 6, 0x989c,
628 { 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000, 0x007f0000 } },
629 { 6, 0x989c,
630 { 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000, 0x043d0000 } },
631 { 6, 0x989c,
632 { 0x00770000, 0x00770000, 0x00770000, 0x00770000, 0x00770000 } },
633 { 6, 0x989c,
634 { 0x00440000, 0x00440000, 0x00440000, 0x00440000, 0x00440000 } },
635 { 6, 0x989c,
636 { 0x00980000, 0x00980000, 0x00980000, 0x00980000, 0x00980000 } },
637 { 6, 0x989c,
638 { 0x00100080, 0x00100080, 0x00100080, 0x00100080, 0x00100080 } },
639 { 6, 0x989c,
640 { 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034, 0x0005c034 } },
641 { 6, 0x989c,
642 { 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0, 0x003100f0 } },
643 { 6, 0x989c,
644 { 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f, 0x000c011f } },
645 { 6, 0x989c,
646 { 0x00510040, 0x00510040, 0x005100a0, 0x005100a0, 0x005100a0 } },
647 { 6, 0x989c,
648 { 0x0050006a, 0x0050006a, 0x005000dd, 0x005000dd, 0x005000dd } },
649 { 6, 0x989c,
650 { 0x00000001, 0x00000001, 0x00000000, 0x00000000, 0x00000000 } },
651 { 6, 0x989c,
652 { 0x00004044, 0x00004044, 0x00004044, 0x00004044, 0x00004044 } },
653 { 6, 0x989c,
654 { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 } },
655 { 6, 0x989c,
656 { 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0, 0x000060c0 } },
657 { 6, 0x989c,
658 { 0x00002c00, 0x00002c00, 0x00003600, 0x00003600, 0x00003600 } },
659 { 6, 0x98c8,
660 { 0x00000403, 0x00000403, 0x00040403, 0x00040403, 0x00040403 } },
661 { 7, 0x989c,
662 { 0x00006400, 0x00006400, 0x00006400, 0x00006400, 0x00006400 } },
663 { 7, 0x989c,
664 { 0x00000800, 0x00000800, 0x00000800, 0x00000800, 0x00000800 } },
665 { 7, 0x98cc,
666 { 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e, 0x0000000e } },
667};
668
669
670/* Initial RF Gain settings for RF5112 */
671static const struct ath5k_ini_rfgain rfgain_5112[] = {
672 /* 5Ghz 2Ghz */
673 { AR5K_RF_GAIN(0), { 0x00000007, 0x00000007 } },
674 { AR5K_RF_GAIN(1), { 0x00000047, 0x00000047 } },
675 { AR5K_RF_GAIN(2), { 0x00000087, 0x00000087 } },
676 { AR5K_RF_GAIN(3), { 0x000001a0, 0x000001a0 } },
677 { AR5K_RF_GAIN(4), { 0x000001e0, 0x000001e0 } },
678 { AR5K_RF_GAIN(5), { 0x00000020, 0x00000020 } },
679 { AR5K_RF_GAIN(6), { 0x00000060, 0x00000060 } },
680 { AR5K_RF_GAIN(7), { 0x000001a1, 0x000001a1 } },
681 { AR5K_RF_GAIN(8), { 0x000001e1, 0x000001e1 } },
682 { AR5K_RF_GAIN(9), { 0x00000021, 0x00000021 } },
683 { AR5K_RF_GAIN(10), { 0x00000061, 0x00000061 } },
684 { AR5K_RF_GAIN(11), { 0x00000162, 0x00000162 } },
685 { AR5K_RF_GAIN(12), { 0x000001a2, 0x000001a2 } },
686 { AR5K_RF_GAIN(13), { 0x000001e2, 0x000001e2 } },
687 { AR5K_RF_GAIN(14), { 0x00000022, 0x00000022 } },
688 { AR5K_RF_GAIN(15), { 0x00000062, 0x00000062 } },
689 { AR5K_RF_GAIN(16), { 0x00000163, 0x00000163 } },
690 { AR5K_RF_GAIN(17), { 0x000001a3, 0x000001a3 } },
691 { AR5K_RF_GAIN(18), { 0x000001e3, 0x000001e3 } },
692 { AR5K_RF_GAIN(19), { 0x00000023, 0x00000023 } },
693 { AR5K_RF_GAIN(20), { 0x00000063, 0x00000063 } },
694 { AR5K_RF_GAIN(21), { 0x00000184, 0x00000184 } },
695 { AR5K_RF_GAIN(22), { 0x000001c4, 0x000001c4 } },
696 { AR5K_RF_GAIN(23), { 0x00000004, 0x00000004 } },
697 { AR5K_RF_GAIN(24), { 0x000001ea, 0x0000000b } },
698 { AR5K_RF_GAIN(25), { 0x0000002a, 0x0000004b } },
699 { AR5K_RF_GAIN(26), { 0x0000006a, 0x0000008b } },
700 { AR5K_RF_GAIN(27), { 0x000000aa, 0x000001ac } },
701 { AR5K_RF_GAIN(28), { 0x000001ab, 0x000001ec } },
702 { AR5K_RF_GAIN(29), { 0x000001eb, 0x0000002c } },
703 { AR5K_RF_GAIN(30), { 0x0000002b, 0x00000012 } },
704 { AR5K_RF_GAIN(31), { 0x0000006b, 0x00000052 } },
705 { AR5K_RF_GAIN(32), { 0x000000ab, 0x00000092 } },
706 { AR5K_RF_GAIN(33), { 0x000001ac, 0x00000193 } },
707 { AR5K_RF_GAIN(34), { 0x000001ec, 0x000001d3 } },
708 { AR5K_RF_GAIN(35), { 0x0000002c, 0x00000013 } },
709 { AR5K_RF_GAIN(36), { 0x0000003a, 0x00000053 } },
710 { AR5K_RF_GAIN(37), { 0x0000007a, 0x00000093 } },
711 { AR5K_RF_GAIN(38), { 0x000000ba, 0x00000194 } },
712 { AR5K_RF_GAIN(39), { 0x000001bb, 0x000001d4 } },
713 { AR5K_RF_GAIN(40), { 0x000001fb, 0x00000014 } },
714 { AR5K_RF_GAIN(41), { 0x0000003b, 0x0000003a } },
715 { AR5K_RF_GAIN(42), { 0x0000007b, 0x0000007a } },
716 { AR5K_RF_GAIN(43), { 0x000000bb, 0x000000ba } },
717 { AR5K_RF_GAIN(44), { 0x000001bc, 0x000001bb } },
718 { AR5K_RF_GAIN(45), { 0x000001fc, 0x000001fb } },
719 { AR5K_RF_GAIN(46), { 0x0000003c, 0x0000003b } },
720 { AR5K_RF_GAIN(47), { 0x0000007c, 0x0000007b } },
721 { AR5K_RF_GAIN(48), { 0x000000bc, 0x000000bb } },
722 { AR5K_RF_GAIN(49), { 0x000000fc, 0x000001bc } },
723 { AR5K_RF_GAIN(50), { 0x000000fc, 0x000001fc } },
724 { AR5K_RF_GAIN(51), { 0x000000fc, 0x0000003c } },
725 { AR5K_RF_GAIN(52), { 0x000000fc, 0x0000007c } },
726 { AR5K_RF_GAIN(53), { 0x000000fc, 0x000000bc } },
727 { AR5K_RF_GAIN(54), { 0x000000fc, 0x000000fc } },
728 { AR5K_RF_GAIN(55), { 0x000000fc, 0x000000fc } },
729 { AR5K_RF_GAIN(56), { 0x000000fc, 0x000000fc } },
730 { AR5K_RF_GAIN(57), { 0x000000fc, 0x000000fc } },
731 { AR5K_RF_GAIN(58), { 0x000000fc, 0x000000fc } },
732 { AR5K_RF_GAIN(59), { 0x000000fc, 0x000000fc } },
733 { AR5K_RF_GAIN(60), { 0x000000fc, 0x000000fc } },
734 { AR5K_RF_GAIN(61), { 0x000000fc, 0x000000fc } },
735 { AR5K_RF_GAIN(62), { 0x000000fc, 0x000000fc } },
736 { AR5K_RF_GAIN(63), { 0x000000fc, 0x000000fc } },
737};
738
739/* Initial RF Gain settings for RF5413 */
740static const struct ath5k_ini_rfgain rfgain_5413[] = {
741 /* 5Ghz 2Ghz */
742 { AR5K_RF_GAIN(0), { 0x00000000, 0x00000000 } },
743 { AR5K_RF_GAIN(1), { 0x00000040, 0x00000040 } },
744 { AR5K_RF_GAIN(2), { 0x00000080, 0x00000080 } },
745 { AR5K_RF_GAIN(3), { 0x000001a1, 0x00000161 } },
746 { AR5K_RF_GAIN(4), { 0x000001e1, 0x000001a1 } },
747 { AR5K_RF_GAIN(5), { 0x00000021, 0x000001e1 } },
748 { AR5K_RF_GAIN(6), { 0x00000061, 0x00000021 } },
749 { AR5K_RF_GAIN(7), { 0x00000188, 0x00000061 } },
750 { AR5K_RF_GAIN(8), { 0x000001c8, 0x00000188 } },
751 { AR5K_RF_GAIN(9), { 0x00000008, 0x000001c8 } },
752 { AR5K_RF_GAIN(10), { 0x00000048, 0x00000008 } },
753 { AR5K_RF_GAIN(11), { 0x00000088, 0x00000048 } },
754 { AR5K_RF_GAIN(12), { 0x000001a9, 0x00000088 } },
755 { AR5K_RF_GAIN(13), { 0x000001e9, 0x00000169 } },
756 { AR5K_RF_GAIN(14), { 0x00000029, 0x000001a9 } },
757 { AR5K_RF_GAIN(15), { 0x00000069, 0x000001e9 } },
758 { AR5K_RF_GAIN(16), { 0x000001d0, 0x00000029 } },
759 { AR5K_RF_GAIN(17), { 0x00000010, 0x00000069 } },
760 { AR5K_RF_GAIN(18), { 0x00000050, 0x00000190 } },
761 { AR5K_RF_GAIN(19), { 0x00000090, 0x000001d0 } },
762 { AR5K_RF_GAIN(20), { 0x000001b1, 0x00000010 } },
763 { AR5K_RF_GAIN(21), { 0x000001f1, 0x00000050 } },
764 { AR5K_RF_GAIN(22), { 0x00000031, 0x00000090 } },
765 { AR5K_RF_GAIN(23), { 0x00000071, 0x00000171 } },
766 { AR5K_RF_GAIN(24), { 0x000001b8, 0x000001b1 } },
767 { AR5K_RF_GAIN(25), { 0x000001f8, 0x000001f1 } },
768 { AR5K_RF_GAIN(26), { 0x00000038, 0x00000031 } },
769 { AR5K_RF_GAIN(27), { 0x00000078, 0x00000071 } },
770 { AR5K_RF_GAIN(28), { 0x00000199, 0x00000198 } },
771 { AR5K_RF_GAIN(29), { 0x000001d9, 0x000001d8 } },
772 { AR5K_RF_GAIN(30), { 0x00000019, 0x00000018 } },
773 { AR5K_RF_GAIN(31), { 0x00000059, 0x00000058 } },
774 { AR5K_RF_GAIN(32), { 0x00000099, 0x00000098 } },
775 { AR5K_RF_GAIN(33), { 0x000000d9, 0x00000179 } },
776 { AR5K_RF_GAIN(34), { 0x000000f9, 0x000001b9 } },
777 { AR5K_RF_GAIN(35), { 0x000000f9, 0x000001f9 } },
778 { AR5K_RF_GAIN(36), { 0x000000f9, 0x00000039 } },
779 { AR5K_RF_GAIN(37), { 0x000000f9, 0x00000079 } },
780 { AR5K_RF_GAIN(38), { 0x000000f9, 0x000000b9 } },
781 { AR5K_RF_GAIN(39), { 0x000000f9, 0x000000f9 } },
782 { AR5K_RF_GAIN(40), { 0x000000f9, 0x000000f9 } },
783 { AR5K_RF_GAIN(41), { 0x000000f9, 0x000000f9 } },
784 { AR5K_RF_GAIN(42), { 0x000000f9, 0x000000f9 } },
785 { AR5K_RF_GAIN(43), { 0x000000f9, 0x000000f9 } },
786 { AR5K_RF_GAIN(44), { 0x000000f9, 0x000000f9 } },
787 { AR5K_RF_GAIN(45), { 0x000000f9, 0x000000f9 } },
788 { AR5K_RF_GAIN(46), { 0x000000f9, 0x000000f9 } },
789 { AR5K_RF_GAIN(47), { 0x000000f9, 0x000000f9 } },
790 { AR5K_RF_GAIN(48), { 0x000000f9, 0x000000f9 } },
791 { AR5K_RF_GAIN(49), { 0x000000f9, 0x000000f9 } },
792 { AR5K_RF_GAIN(50), { 0x000000f9, 0x000000f9 } },
793 { AR5K_RF_GAIN(51), { 0x000000f9, 0x000000f9 } },
794 { AR5K_RF_GAIN(52), { 0x000000f9, 0x000000f9 } },
795 { AR5K_RF_GAIN(53), { 0x000000f9, 0x000000f9 } },
796 { AR5K_RF_GAIN(54), { 0x000000f9, 0x000000f9 } },
797 { AR5K_RF_GAIN(55), { 0x000000f9, 0x000000f9 } },
798 { AR5K_RF_GAIN(56), { 0x000000f9, 0x000000f9 } },
799 { AR5K_RF_GAIN(57), { 0x000000f9, 0x000000f9 } },
800 { AR5K_RF_GAIN(58), { 0x000000f9, 0x000000f9 } },
801 { AR5K_RF_GAIN(59), { 0x000000f9, 0x000000f9 } },
802 { AR5K_RF_GAIN(60), { 0x000000f9, 0x000000f9 } },
803 { AR5K_RF_GAIN(61), { 0x000000f9, 0x000000f9 } },
804 { AR5K_RF_GAIN(62), { 0x000000f9, 0x000000f9 } },
805 { AR5K_RF_GAIN(63), { 0x000000f9, 0x000000f9 } },
806};
807
808static const struct ath5k_gain_opt rfgain_opt_5112 = {
809 1,
810 8,
811 {
812 { { 3, 0, 0, 0, 0, 0, 0 }, 6 },
813 { { 2, 0, 0, 0, 0, 0, 0 }, 0 },
814 { { 1, 0, 0, 0, 0, 0, 0 }, -3 },
815 { { 0, 0, 0, 0, 0, 0, 0 }, -6 },
816 { { 0, 1, 1, 0, 0, 0, 0 }, -8 },
817 { { 0, 1, 1, 0, 1, 1, 0 }, -10 },
818 { { 0, 1, 0, 1, 1, 1, 0 }, -13 },
819 { { 0, 1, 0, 1, 1, 0, 1 }, -16 },
820 }
821};
822
823/*
824 * Used to modify RF Banks before writing them to AR5K_RF_BUFFER
825 */
826static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits,
827 u32 first, u32 col, bool set)
828{
829 u32 mask, entry, last, data, shift, position;
830 s32 left;
831 int i;
832
833 data = 0;
834
835 if (rf == NULL)
836 /* should not happen */
837 return 0;
838
839 if (!(col <= 3 && bits <= 32 && first + bits <= 319)) {
840 ATH5K_PRINTF("invalid values at offset %u\n", offset);
841 return 0;
842 }
843
844 entry = ((first - 1) / 8) + offset;
845 position = (first - 1) % 8;
846
847 if (set == true)
848 data = ath5k_hw_bitswap(reg, bits);
849
850 for (i = shift = 0, left = bits; left > 0; position = 0, entry++, i++) {
851 last = (position + left > 8) ? 8 : position + left;
852 mask = (((1 << last) - 1) ^ ((1 << position) - 1)) << (col * 8);
853
854 if (set == true) {
855 rf[entry] &= ~mask;
856 rf[entry] |= ((data << position) << (col * 8)) & mask;
857 data >>= (8 - position);
858 } else {
859 data = (((rf[entry] & mask) >> (col * 8)) >> position)
860 << shift;
861 shift += last - position;
862 }
863
864 left -= 8 - position;
865 }
866
867 data = set == true ? 1 : ath5k_hw_bitswap(data, bits);
868
869 return data;
870}
871
872static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
873{
874 u32 mix, step;
875 u32 *rf;
876
877 if (ah->ah_rf_banks == NULL)
878 return 0;
879
880 rf = ah->ah_rf_banks;
881 ah->ah_gain.g_f_corr = 0;
882
883 if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1)
884 return 0;
885
886 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false);
887 mix = ah->ah_gain.g_step->gos_param[0];
888
889 switch (mix) {
890 case 3:
891 ah->ah_gain.g_f_corr = step * 2;
892 break;
893 case 2:
894 ah->ah_gain.g_f_corr = (step - 5) * 2;
895 break;
896 case 1:
897 ah->ah_gain.g_f_corr = step;
898 break;
899 default:
900 ah->ah_gain.g_f_corr = 0;
901 break;
902 }
903
904 return ah->ah_gain.g_f_corr;
905}
906
907static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
908{
909 u32 step, mix, level[4];
910 u32 *rf;
911
912 if (ah->ah_rf_banks == NULL)
913 return false;
914
915 rf = ah->ah_rf_banks;
916
917 if (ah->ah_radio == AR5K_RF5111) {
918 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0,
919 false);
920 level[0] = 0;
921 level[1] = (step == 0x3f) ? 0x32 : step + 4;
922 level[2] = (step != 0x3f) ? 0x40 : level[0];
923 level[3] = level[2] + 0x32;
924
925 ah->ah_gain.g_high = level[3] -
926 (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
927 ah->ah_gain.g_low = level[0] +
928 (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
929 } else {
930 mix = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0,
931 false);
932 level[0] = level[2] = 0;
933
934 if (mix == 1) {
935 level[1] = level[3] = 83;
936 } else {
937 level[1] = level[3] = 107;
938 ah->ah_gain.g_high = 55;
939 }
940 }
941
942 return (ah->ah_gain.g_current >= level[0] &&
943 ah->ah_gain.g_current <= level[1]) ||
944 (ah->ah_gain.g_current >= level[2] &&
945 ah->ah_gain.g_current <= level[3]);
946}
947
948static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
949{
950 const struct ath5k_gain_opt *go;
951 int ret = 0;
952
953 switch (ah->ah_radio) {
954 case AR5K_RF5111:
955 go = &rfgain_opt_5111;
956 break;
957 case AR5K_RF5112:
958 case AR5K_RF5413: /* ??? */
959 go = &rfgain_opt_5112;
960 break;
961 default:
962 return 0;
963 }
964
965 ah->ah_gain.g_step = &go->go_step[ah->ah_gain.g_step_idx];
966
967 if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
968 if (ah->ah_gain.g_step_idx == 0)
969 return -1;
970 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
971 ah->ah_gain.g_target >= ah->ah_gain.g_high &&
972 ah->ah_gain.g_step_idx > 0;
973 ah->ah_gain.g_step =
974 &go->go_step[ah->ah_gain.g_step_idx])
975 ah->ah_gain.g_target -= 2 *
976 (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
977 ah->ah_gain.g_step->gos_gain);
978
979 ret = 1;
980 goto done;
981 }
982
983 if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
984 if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
985 return -2;
986 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
987 ah->ah_gain.g_target <= ah->ah_gain.g_low &&
988 ah->ah_gain.g_step_idx < go->go_steps_count-1;
989 ah->ah_gain.g_step =
990 &go->go_step[ah->ah_gain.g_step_idx])
991 ah->ah_gain.g_target -= 2 *
992 (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
993 ah->ah_gain.g_step->gos_gain);
994
995 ret = 2;
996 goto done;
997 }
998
999done:
1000 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1001 "ret %d, gain step %u, current gain %u, target gain %u\n",
1002 ret, ah->ah_gain.g_step_idx, ah->ah_gain.g_current,
1003 ah->ah_gain.g_target);
1004
1005 return ret;
1006}
1007
1008/*
1009 * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111
1010 */
1011static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah,
1012 struct ieee80211_channel *channel, unsigned int mode)
1013{
1014 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1015 u32 *rf;
1016 const unsigned int rf_size = ARRAY_SIZE(rfregs_5111);
1017 unsigned int i;
1018 int obdb = -1, bank = -1;
1019 u32 ee_mode;
1020
1021 AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
1022
1023 rf = ah->ah_rf_banks;
1024
1025 /* Copy values to modify them */
1026 for (i = 0; i < rf_size; i++) {
1027 if (rfregs_5111[i].rf_bank >= AR5K_RF5111_INI_RF_MAX_BANKS) {
1028 ATH5K_ERR(ah->ah_sc, "invalid bank\n");
1029 return -EINVAL;
1030 }
1031
1032 if (bank != rfregs_5111[i].rf_bank) {
1033 bank = rfregs_5111[i].rf_bank;
1034 ah->ah_offset[bank] = i;
1035 }
1036
1037 rf[i] = rfregs_5111[i].rf_value[mode];
1038 }
1039
1040 /* Modify bank 0 */
1041 if (channel->val & CHANNEL_2GHZ) {
1042 if (channel->val & CHANNEL_CCK)
1043 ee_mode = AR5K_EEPROM_MODE_11B;
1044 else
1045 ee_mode = AR5K_EEPROM_MODE_11G;
1046 obdb = 0;
1047
1048 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
1049 ee->ee_ob[ee_mode][obdb], 3, 119, 0, true))
1050 return -EINVAL;
1051
1052 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[0],
1053 ee->ee_ob[ee_mode][obdb], 3, 122, 0, true))
1054 return -EINVAL;
1055
1056 obdb = 1;
1057 /* Modify bank 6 */
1058 } else {
1059 /* For 11a, Turbo and XR */
1060 ee_mode = AR5K_EEPROM_MODE_11A;
1061 obdb = channel->freq >= 5725 ? 3 :
1062 (channel->freq >= 5500 ? 2 :
1063 (channel->freq >= 5260 ? 1 :
1064 (channel->freq > 4000 ? 0 : -1)));
1065
1066 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1067 ee->ee_pwd_84, 1, 51, 3, true))
1068 return -EINVAL;
1069
1070 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1071 ee->ee_pwd_90, 1, 45, 3, true))
1072 return -EINVAL;
1073 }
1074
1075 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1076 !ee->ee_xpd[ee_mode], 1, 95, 0, true))
1077 return -EINVAL;
1078
1079 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1080 ee->ee_x_gain[ee_mode], 4, 96, 0, true))
1081 return -EINVAL;
1082
1083 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
1084 ee->ee_ob[ee_mode][obdb] : 0, 3, 104, 0, true))
1085 return -EINVAL;
1086
1087 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6], obdb >= 0 ?
1088 ee->ee_db[ee_mode][obdb] : 0, 3, 107, 0, true))
1089 return -EINVAL;
1090
1091 /* Modify bank 7 */
1092 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
1093 ee->ee_i_gain[ee_mode], 6, 29, 0, true))
1094 return -EINVAL;
1095
1096 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
1097 ee->ee_xpd[ee_mode], 1, 4, 0, true))
1098 return -EINVAL;
1099
1100 /* Write RF values */
1101 for (i = 0; i < rf_size; i++) {
1102 AR5K_REG_WAIT(i);
1103 ath5k_hw_reg_write(ah, rf[i], rfregs_5111[i].rf_register);
1104 }
1105
1106 return 0;
1107}
1108
1109/*
1110 * Read EEPROM Calibration data, modify RF Banks and Initialize RF5112
1111 */
1112static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah,
1113 struct ieee80211_channel *channel, unsigned int mode)
1114{
1115 const struct ath5k_ini_rf *rf_ini;
1116 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
1117 u32 *rf;
1118 unsigned int rf_size, i;
1119 int obdb = -1, bank = -1;
1120 u32 ee_mode;
1121
1122 AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
1123
1124 rf = ah->ah_rf_banks;
1125
1126 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_2112A
1127 && !test_bit(MODE_IEEE80211A, ah->ah_capabilities.cap_mode)){
1128 rf_ini = rfregs_2112a;
1129 rf_size = ARRAY_SIZE(rfregs_5112a);
1130 if (mode < 2) {
1131 ATH5K_ERR(ah->ah_sc,"invalid channel mode: %i\n",mode);
1132 return -EINVAL;
1133 }
1134 mode = mode - 2; /*no a/turboa modes for 2112*/
1135 } else if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
1136 rf_ini = rfregs_5112a;
1137 rf_size = ARRAY_SIZE(rfregs_5112a);
1138 } else {
1139 rf_ini = rfregs_5112;
1140 rf_size = ARRAY_SIZE(rfregs_5112);
1141 }
1142
1143 /* Copy values to modify them */
1144 for (i = 0; i < rf_size; i++) {
1145 if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
1146 ATH5K_ERR(ah->ah_sc, "invalid bank\n");
1147 return -EINVAL;
1148 }
1149
1150 if (bank != rf_ini[i].rf_bank) {
1151 bank = rf_ini[i].rf_bank;
1152 ah->ah_offset[bank] = i;
1153 }
1154
1155 rf[i] = rf_ini[i].rf_value[mode];
1156 }
1157
1158 /* Modify bank 6 */
1159 if (channel->val & CHANNEL_2GHZ) {
1160 if (channel->val & CHANNEL_OFDM)
1161 ee_mode = AR5K_EEPROM_MODE_11G;
1162 else
1163 ee_mode = AR5K_EEPROM_MODE_11B;
1164 obdb = 0;
1165
1166 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1167 ee->ee_ob[ee_mode][obdb], 3, 287, 0, true))
1168 return -EINVAL;
1169
1170 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1171 ee->ee_ob[ee_mode][obdb], 3, 290, 0, true))
1172 return -EINVAL;
1173 } else {
1174 /* For 11a, Turbo and XR */
1175 ee_mode = AR5K_EEPROM_MODE_11A;
1176 obdb = channel->freq >= 5725 ? 3 :
1177 (channel->freq >= 5500 ? 2 :
1178 (channel->freq >= 5260 ? 1 :
1179 (channel->freq > 4000 ? 0 : -1)));
1180
1181 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1182 ee->ee_ob[ee_mode][obdb], 3, 279, 0, true))
1183 return -EINVAL;
1184
1185 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1186 ee->ee_ob[ee_mode][obdb], 3, 282, 0, true))
1187 return -EINVAL;
1188 }
1189
1190 ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1191 ee->ee_x_gain[ee_mode], 2, 270, 0, true);
1192 ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1193 ee->ee_x_gain[ee_mode], 2, 257, 0, true);
1194
1195 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[6],
1196 ee->ee_xpd[ee_mode], 1, 302, 0, true))
1197 return -EINVAL;
1198
1199 /* Modify bank 7 */
1200 if (!ath5k_hw_rfregs_op(rf, ah->ah_offset[7],
1201 ee->ee_i_gain[ee_mode], 6, 14, 0, true))
1202 return -EINVAL;
1203
1204 /* Write RF values */
1205 for (i = 0; i < rf_size; i++)
1206 ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
1207
1208 return 0;
1209}
1210
1211/*
1212 * Initialize RF5413/5414
1213 */
1214static int ath5k_hw_rf5413_rfregs(struct ath5k_hw *ah,
1215 struct ieee80211_channel *channel, unsigned int mode)
1216{
1217 const struct ath5k_ini_rf *rf_ini;
1218 u32 *rf;
1219 unsigned int rf_size, i;
1220 int bank = -1;
1221
1222 AR5K_ASSERT_ENTRY(mode, AR5K_INI_VAL_MAX);
1223
1224 rf = ah->ah_rf_banks;
1225
1226 rf_ini = rfregs_5413;
1227 rf_size = ARRAY_SIZE(rfregs_5413);
1228
1229 /* Copy values to modify them */
1230 for (i = 0; i < rf_size; i++) {
1231 if (rf_ini[i].rf_bank >= AR5K_RF5112_INI_RF_MAX_BANKS) {
1232 ATH5K_ERR(ah->ah_sc, "invalid bank\n");
1233 return -EINVAL;
1234 }
1235
1236 if (bank != rf_ini[i].rf_bank) {
1237 bank = rf_ini[i].rf_bank;
1238 ah->ah_offset[bank] = i;
1239 }
1240
1241 rf[i] = rf_ini[i].rf_value[mode];
1242 }
1243
1244 /*
1245 * After compairing dumps from different cards
1246 * we get the same RF_BUFFER settings (diff returns
1247 * 0 lines). It seems that RF_BUFFER settings are static
1248 * and are written unmodified (no EEPROM stuff
1249 * is used because calibration data would be
1250 * different between different cards and would result
1251 * different RF_BUFFER settings)
1252 */
1253
1254 /* Write RF values */
1255 for (i = 0; i < rf_size; i++)
1256 ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rf_register);
1257
1258 return 0;
1259}
1260
1261/*
1262 * Initialize RF
1263 */
1264int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
1265 unsigned int mode)
1266{
1267 int (*func)(struct ath5k_hw *, struct ieee80211_channel *, unsigned int);
1268 int ret;
1269
1270 switch (ah->ah_radio) {
1271 case AR5K_RF5111:
1272 ah->ah_rf_banks_size = sizeof(rfregs_5111);
1273 func = ath5k_hw_rf5111_rfregs;
1274 break;
1275 case AR5K_RF5112:
1276 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
1277 ah->ah_rf_banks_size = sizeof(rfregs_5112a);
1278 else
1279 ah->ah_rf_banks_size = sizeof(rfregs_5112);
1280 func = ath5k_hw_rf5112_rfregs;
1281 break;
1282 case AR5K_RF5413:
1283 ah->ah_rf_banks_size = sizeof(rfregs_5413);
1284 func = ath5k_hw_rf5413_rfregs;
1285 break;
1286 default:
1287 return -EINVAL;
1288 }
1289
1290 if (ah->ah_rf_banks == NULL) {
1291 /* XXX do extra checks? */
1292 ah->ah_rf_banks = kmalloc(ah->ah_rf_banks_size, GFP_KERNEL);
1293 if (ah->ah_rf_banks == NULL) {
1294 ATH5K_ERR(ah->ah_sc, "out of memory\n");
1295 return -ENOMEM;
1296 }
1297 }
1298
1299 ret = func(ah, channel, mode);
1300 if (!ret)
1301 ah->ah_rf_gain = AR5K_RFGAIN_INACTIVE;
1302
1303 return ret;
1304}
1305
1306int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
1307{
1308 const struct ath5k_ini_rfgain *ath5k_rfg;
1309 unsigned int i, size;
1310
1311 switch (ah->ah_radio) {
1312 case AR5K_RF5111:
1313 ath5k_rfg = rfgain_5111;
1314 size = ARRAY_SIZE(rfgain_5111);
1315 break;
1316 case AR5K_RF5112:
1317 ath5k_rfg = rfgain_5112;
1318 size = ARRAY_SIZE(rfgain_5112);
1319 break;
1320 case AR5K_RF5413:
1321 ath5k_rfg = rfgain_5413;
1322 size = ARRAY_SIZE(rfgain_5413);
1323 break;
1324 default:
1325 return -EINVAL;
1326 }
1327
1328 switch (freq) {
1329 case AR5K_INI_RFGAIN_2GHZ:
1330 case AR5K_INI_RFGAIN_5GHZ:
1331 break;
1332 default:
1333 return -EINVAL;
1334 }
1335
1336 for (i = 0; i < size; i++) {
1337 AR5K_REG_WAIT(i);
1338 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
1339 (u32)ath5k_rfg[i].rfg_register);
1340 }
1341
1342 return 0;
1343}
1344
1345enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah)
1346{
1347 u32 data, type;
1348
1349 ATH5K_TRACE(ah->ah_sc);
1350
1351 if (ah->ah_rf_banks == NULL || !ah->ah_gain.g_active ||
1352 ah->ah_version <= AR5K_AR5211)
1353 return AR5K_RFGAIN_INACTIVE;
1354
1355 if (ah->ah_rf_gain != AR5K_RFGAIN_READ_REQUESTED)
1356 goto done;
1357
1358 data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
1359
1360 if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
1361 ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
1362 type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
1363
1364 if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK)
1365 ah->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
1366
1367 if (ah->ah_radio >= AR5K_RF5112) {
1368 ath5k_hw_rfregs_gainf_corr(ah);
1369 ah->ah_gain.g_current =
1370 ah->ah_gain.g_current>=ah->ah_gain.g_f_corr ?
1371 (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
1372 0;
1373 }
1374
1375 if (ath5k_hw_rfregs_gain_readback(ah) &&
1376 AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
1377 ath5k_hw_rfregs_gain_adjust(ah))
1378 ah->ah_rf_gain = AR5K_RFGAIN_NEED_CHANGE;
1379 }
1380
1381done:
1382 return ah->ah_rf_gain;
1383}
1384
1385int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah)
1386{
1387 /* Initialize the gain optimization values */
1388 switch (ah->ah_radio) {
1389 case AR5K_RF5111:
1390 ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
1391 ah->ah_gain.g_step =
1392 &rfgain_opt_5111.go_step[ah->ah_gain.g_step_idx];
1393 ah->ah_gain.g_low = 20;
1394 ah->ah_gain.g_high = 35;
1395 ah->ah_gain.g_active = 1;
1396 break;
1397 case AR5K_RF5112:
1398 case AR5K_RF5413: /* ??? */
1399 ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
1400 ah->ah_gain.g_step =
1401 &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
1402 ah->ah_gain.g_low = 20;
1403 ah->ah_gain.g_high = 85;
1404 ah->ah_gain.g_active = 1;
1405 break;
1406 default:
1407 return -EINVAL;
1408 }
1409
1410 return 0;
1411}
1412
1413/**************************\
1414 PHY/RF channel functions
1415\**************************/
1416
1417/*
1418 * Check if a channel is supported
1419 */
1420bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags)
1421{
1422 /* Check if the channel is in our supported range */
1423 if (flags & CHANNEL_2GHZ) {
1424 if ((freq >= ah->ah_capabilities.cap_range.range_2ghz_min) &&
1425 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
1426 return true;
1427 } else if (flags & CHANNEL_5GHZ)
1428 if ((freq >= ah->ah_capabilities.cap_range.range_5ghz_min) &&
1429 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
1430 return true;
1431
1432 return false;
1433}
1434
1435/*
1436 * Convertion needed for RF5110
1437 */
1438static u32 ath5k_hw_rf5110_chan2athchan(struct ieee80211_channel *channel)
1439{
1440 u32 athchan;
1441
1442 /*
1443 * Convert IEEE channel/MHz to an internal channel value used
1444 * by the AR5210 chipset. This has not been verified with
1445 * newer chipsets like the AR5212A who have a completely
1446 * different RF/PHY part.
1447 */
1448 athchan = (ath5k_hw_bitswap((channel->chan - 24) / 2, 5) << 1) |
1449 (1 << 6) | 0x1;
1450
1451 return athchan;
1452}
1453
1454/*
1455 * Set channel on RF5110
1456 */
1457static int ath5k_hw_rf5110_channel(struct ath5k_hw *ah,
1458 struct ieee80211_channel *channel)
1459{
1460 u32 data;
1461
1462 /*
1463 * Set the channel and wait
1464 */
1465 data = ath5k_hw_rf5110_chan2athchan(channel);
1466 ath5k_hw_reg_write(ah, data, AR5K_RF_BUFFER);
1467 ath5k_hw_reg_write(ah, 0, AR5K_RF_BUFFER_CONTROL_0);
1468 mdelay(1);
1469
1470 return 0;
1471}
1472
1473/*
1474 * Convertion needed for 5111
1475 */
1476static int ath5k_hw_rf5111_chan2athchan(unsigned int ieee,
1477 struct ath5k_athchan_2ghz *athchan)
1478{
1479 int channel;
1480
1481 /* Cast this value to catch negative channel numbers (>= -19) */
1482 channel = (int)ieee;
1483
1484 /*
1485 * Map 2GHz IEEE channel to 5GHz Atheros channel
1486 */
1487 if (channel <= 13) {
1488 athchan->a2_athchan = 115 + channel;
1489 athchan->a2_flags = 0x46;
1490 } else if (channel == 14) {
1491 athchan->a2_athchan = 124;
1492 athchan->a2_flags = 0x44;
1493 } else if (channel >= 15 && channel <= 26) {
1494 athchan->a2_athchan = ((channel - 14) * 4) + 132;
1495 athchan->a2_flags = 0x46;
1496 } else
1497 return -EINVAL;
1498
1499 return 0;
1500}
1501
1502/*
1503 * Set channel on 5111
1504 */
1505static int ath5k_hw_rf5111_channel(struct ath5k_hw *ah,
1506 struct ieee80211_channel *channel)
1507{
1508 struct ath5k_athchan_2ghz ath5k_channel_2ghz;
1509 unsigned int ath5k_channel = channel->chan;
1510 u32 data0, data1, clock;
1511 int ret;
1512
1513 /*
1514 * Set the channel on the RF5111 radio
1515 */
1516 data0 = data1 = 0;
1517
1518 if (channel->val & CHANNEL_2GHZ) {
1519 /* Map 2GHz channel to 5GHz Atheros channel ID */
1520 ret = ath5k_hw_rf5111_chan2athchan(channel->chan,
1521 &ath5k_channel_2ghz);
1522 if (ret)
1523 return ret;
1524
1525 ath5k_channel = ath5k_channel_2ghz.a2_athchan;
1526 data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
1527 << 5) | (1 << 4);
1528 }
1529
1530 if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
1531 clock = 1;
1532 data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
1533 (clock << 1) | (1 << 10) | 1;
1534 } else {
1535 clock = 0;
1536 data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
1537 << 2) | (clock << 1) | (1 << 10) | 1;
1538 }
1539
1540 ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
1541 AR5K_RF_BUFFER);
1542 ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
1543 AR5K_RF_BUFFER_CONTROL_3);
1544
1545 return 0;
1546}
1547
1548/*
1549 * Set channel on 5112 and newer
1550 */
1551static int ath5k_hw_rf5112_channel(struct ath5k_hw *ah,
1552 struct ieee80211_channel *channel)
1553{
1554 u32 data, data0, data1, data2;
1555 u16 c;
1556
1557 data = data0 = data1 = data2 = 0;
1558 c = channel->freq;
1559
1560 /*
1561 * Set the channel on the RF5112 or newer
1562 */
1563 if (c < 4800) {
1564 if (!((c - 2224) % 5)) {
1565 data0 = ((2 * (c - 704)) - 3040) / 10;
1566 data1 = 1;
1567 } else if (!((c - 2192) % 5)) {
1568 data0 = ((2 * (c - 672)) - 3040) / 10;
1569 data1 = 0;
1570 } else
1571 return -EINVAL;
1572
1573 data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
1574 } else {
1575 if (!(c % 20) && c >= 5120) {
1576 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1577 data2 = ath5k_hw_bitswap(3, 2);
1578 } else if (!(c % 10)) {
1579 data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1580 data2 = ath5k_hw_bitswap(2, 2);
1581 } else if (!(c % 5)) {
1582 data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
1583 data2 = ath5k_hw_bitswap(1, 2);
1584 } else
1585 return -EINVAL;
1586 }
1587
1588 data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
1589
1590 ath5k_hw_reg_write(ah, data & 0xff, AR5K_RF_BUFFER);
1591 ath5k_hw_reg_write(ah, (data >> 8) & 0x7f, AR5K_RF_BUFFER_CONTROL_5);
1592
1593 return 0;
1594}
1595
1596/*
1597 * Set a channel on the radio chip
1598 */
1599int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel)
1600{
1601 int ret;
1602
1603 /*
1604 * Check bounds supported by the PHY
1605 * (don't care about regulation restrictions at this point)
1606 */
1607 if ((channel->freq < ah->ah_capabilities.cap_range.range_2ghz_min ||
1608 channel->freq > ah->ah_capabilities.cap_range.range_2ghz_max) &&
1609 (channel->freq < ah->ah_capabilities.cap_range.range_5ghz_min ||
1610 channel->freq > ah->ah_capabilities.cap_range.range_5ghz_max)) {
1611 ATH5K_ERR(ah->ah_sc,
1612 "channel out of supported range (%u MHz)\n",
1613 channel->freq);
1614 return -EINVAL;
1615 }
1616
1617 /*
1618 * Set the channel and wait
1619 */
1620 switch (ah->ah_radio) {
1621 case AR5K_RF5110:
1622 ret = ath5k_hw_rf5110_channel(ah, channel);
1623 break;
1624 case AR5K_RF5111:
1625 ret = ath5k_hw_rf5111_channel(ah, channel);
1626 break;
1627 default:
1628 ret = ath5k_hw_rf5112_channel(ah, channel);
1629 break;
1630 }
1631
1632 if (ret)
1633 return ret;
1634
1635 ah->ah_current_channel.freq = channel->freq;
1636 ah->ah_current_channel.val = channel->val;
1637 ah->ah_turbo = channel->val == CHANNEL_T ? true : false;
1638
1639 return 0;
1640}
1641
1642/*****************\
1643 PHY calibration
1644\*****************/
1645
1646/**
1647 * ath5k_hw_noise_floor_calibration - perform PHY noise floor calibration
1648 *
1649 * @ah: struct ath5k_hw pointer we are operating on
1650 * @freq: the channel frequency, just used for error logging
1651 *
1652 * This function performs a noise floor calibration of the PHY and waits for
1653 * it to complete. Then the noise floor value is compared to some maximum
1654 * noise floor we consider valid.
1655 *
1656 * Note that this is different from what the madwifi HAL does: it reads the
1657 * noise floor and afterwards initiates the calibration. Since the noise floor
1658 * calibration can take some time to finish, depending on the current channel
1659 * use, that avoids the occasional timeout warnings we are seeing now.
1660 *
1661 * See the following link for an Atheros patent on noise floor calibration:
1662 * http://patft.uspto.gov/netacgi/nph-Parser?Sect1=PTO1&Sect2=HITOFF&d=PALL \
1663 * &p=1&u=%2Fnetahtml%2FPTO%2Fsrchnum.htm&r=1&f=G&l=50&s1=7245893.PN.&OS=PN/7
1664 *
1665 */
1666int
1667ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq)
1668{
1669 int ret;
1670 unsigned int i;
1671 s32 noise_floor;
1672
1673 /*
1674 * Enable noise floor calibration and wait until completion
1675 */
1676 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
1677 AR5K_PHY_AGCCTL_NF);
1678
1679 ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1680 AR5K_PHY_AGCCTL_NF, 0, false);
1681 if (ret) {
1682 ATH5K_ERR(ah->ah_sc,
1683 "noise floor calibration timeout (%uMHz)\n", freq);
1684 return ret;
1685 }
1686
1687 /* Wait until the noise floor is calibrated and read the value */
1688 for (i = 20; i > 0; i--) {
1689 mdelay(1);
1690 noise_floor = ath5k_hw_reg_read(ah, AR5K_PHY_NF);
1691 noise_floor = AR5K_PHY_NF_RVAL(noise_floor);
1692 if (noise_floor & AR5K_PHY_NF_ACTIVE) {
1693 noise_floor = AR5K_PHY_NF_AVAL(noise_floor);
1694
1695 if (noise_floor <= AR5K_TUNE_NOISE_FLOOR)
1696 break;
1697 }
1698 }
1699
1700 ATH5K_DBG_UNLIMIT(ah->ah_sc, ATH5K_DEBUG_CALIBRATE,
1701 "noise floor %d\n", noise_floor);
1702
1703 if (noise_floor > AR5K_TUNE_NOISE_FLOOR) {
1704 ATH5K_ERR(ah->ah_sc,
1705 "noise floor calibration failed (%uMHz)\n", freq);
1706 return -EIO;
1707 }
1708
1709 ah->ah_noise_floor = noise_floor;
1710
1711 return 0;
1712}
1713
1714/*
1715 * Perform a PHY calibration on RF5110
1716 * -Fix BPSK/QAM Constellation (I/Q correction)
1717 * -Calculate Noise Floor
1718 */
1719static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah,
1720 struct ieee80211_channel *channel)
1721{
1722 u32 phy_sig, phy_agc, phy_sat, beacon;
1723 int ret;
1724
1725 /*
1726 * Disable beacons and RX/TX queues, wait
1727 */
1728 AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5210,
1729 AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
1730 beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210);
1731 ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210);
1732
1733 udelay(2300);
1734
1735 /*
1736 * Set the channel (with AGC turned off)
1737 */
1738 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1739 udelay(10);
1740 ret = ath5k_hw_channel(ah, channel);
1741
1742 /*
1743 * Activate PHY and wait
1744 */
1745 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
1746 mdelay(1);
1747
1748 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1749
1750 if (ret)
1751 return ret;
1752
1753 /*
1754 * Calibrate the radio chip
1755 */
1756
1757 /* Remember normal state */
1758 phy_sig = ath5k_hw_reg_read(ah, AR5K_PHY_SIG);
1759 phy_agc = ath5k_hw_reg_read(ah, AR5K_PHY_AGCCOARSE);
1760 phy_sat = ath5k_hw_reg_read(ah, AR5K_PHY_ADCSAT);
1761
1762 /* Update radio registers */
1763 ath5k_hw_reg_write(ah, (phy_sig & ~(AR5K_PHY_SIG_FIRPWR)) |
1764 AR5K_REG_SM(-1, AR5K_PHY_SIG_FIRPWR), AR5K_PHY_SIG);
1765
1766 ath5k_hw_reg_write(ah, (phy_agc & ~(AR5K_PHY_AGCCOARSE_HI |
1767 AR5K_PHY_AGCCOARSE_LO)) |
1768 AR5K_REG_SM(-1, AR5K_PHY_AGCCOARSE_HI) |
1769 AR5K_REG_SM(-127, AR5K_PHY_AGCCOARSE_LO), AR5K_PHY_AGCCOARSE);
1770
1771 ath5k_hw_reg_write(ah, (phy_sat & ~(AR5K_PHY_ADCSAT_ICNT |
1772 AR5K_PHY_ADCSAT_THR)) |
1773 AR5K_REG_SM(2, AR5K_PHY_ADCSAT_ICNT) |
1774 AR5K_REG_SM(12, AR5K_PHY_ADCSAT_THR), AR5K_PHY_ADCSAT);
1775
1776 udelay(20);
1777
1778 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1779 udelay(10);
1780 ath5k_hw_reg_write(ah, AR5K_PHY_RFSTG_DISABLE, AR5K_PHY_RFSTG);
1781 AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_AGC, AR5K_PHY_AGC_DISABLE);
1782
1783 mdelay(1);
1784
1785 /*
1786 * Enable calibration and wait until completion
1787 */
1788 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, AR5K_PHY_AGCCTL_CAL);
1789
1790 ret = ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
1791 AR5K_PHY_AGCCTL_CAL, 0, false);
1792
1793 /* Reset to normal state */
1794 ath5k_hw_reg_write(ah, phy_sig, AR5K_PHY_SIG);
1795 ath5k_hw_reg_write(ah, phy_agc, AR5K_PHY_AGCCOARSE);
1796 ath5k_hw_reg_write(ah, phy_sat, AR5K_PHY_ADCSAT);
1797
1798 if (ret) {
1799 ATH5K_ERR(ah->ah_sc, "calibration timeout (%uMHz)\n",
1800 channel->freq);
1801 return ret;
1802 }
1803
1804 ret = ath5k_hw_noise_floor_calibration(ah, channel->freq);
1805 if (ret)
1806 return ret;
1807
1808 /*
1809 * Re-enable RX/TX and beacons
1810 */
1811 AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5210,
1812 AR5K_DIAG_SW_DIS_TX | AR5K_DIAG_SW_DIS_RX_5210);
1813 ath5k_hw_reg_write(ah, beacon, AR5K_BEACON_5210);
1814
1815 return 0;
1816}
1817
1818/*
1819 * Perform a PHY calibration on RF5111/5112
1820 */
1821static int ath5k_hw_rf511x_calibrate(struct ath5k_hw *ah,
1822 struct ieee80211_channel *channel)
1823{
1824 u32 i_pwr, q_pwr;
1825 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
1826 ATH5K_TRACE(ah->ah_sc);
1827
1828 if (ah->ah_calibration == false ||
1829 ath5k_hw_reg_read(ah, AR5K_PHY_IQ) & AR5K_PHY_IQ_RUN)
1830 goto done;
1831
1832 ah->ah_calibration = false;
1833
1834 iq_corr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_CORR);
1835 i_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_I);
1836 q_pwr = ath5k_hw_reg_read(ah, AR5K_PHY_IQRES_CAL_PWR_Q);
1837 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1838 q_coffd = q_pwr >> 6;
1839
1840 if (i_coffd == 0 || q_coffd == 0)
1841 goto done;
1842
1843 i_coff = ((-iq_corr) / i_coffd) & 0x3f;
1844 q_coff = (((s32)i_pwr / q_coffd) - 64) & 0x1f;
1845
1846 /* Commit new IQ value */
1847 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, AR5K_PHY_IQ_CORR_ENABLE |
1848 ((u32)q_coff) | ((u32)i_coff << AR5K_PHY_IQ_CORR_Q_I_COFF_S));
1849
1850done:
1851 ath5k_hw_noise_floor_calibration(ah, channel->freq);
1852
1853 /* Request RF gain */
1854 if (channel->val & CHANNEL_5GHZ) {
1855 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
1856 AR5K_PHY_PAPD_PROBE_TXPOWER) |
1857 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
1858 ah->ah_rf_gain = AR5K_RFGAIN_READ_REQUESTED;
1859 }
1860
1861 return 0;
1862}
1863
1864/*
1865 * Perform a PHY calibration
1866 */
1867int ath5k_hw_phy_calibrate(struct ath5k_hw *ah,
1868 struct ieee80211_channel *channel)
1869{
1870 int ret;
1871
1872 if (ah->ah_radio == AR5K_RF5110)
1873 ret = ath5k_hw_rf5110_calibrate(ah, channel);
1874 else
1875 ret = ath5k_hw_rf511x_calibrate(ah, channel);
1876
1877 return ret;
1878}
1879
1880int ath5k_hw_phy_disable(struct ath5k_hw *ah)
1881{
1882 ATH5K_TRACE(ah->ah_sc);
1883 /*Just a try M.F.*/
1884 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
1885
1886 return 0;
1887}
1888
1889/********************\
1890 Misc PHY functions
1891\********************/
1892
1893/*
1894 * Get the PHY Chip revision
1895 */
1896u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan)
1897{
1898 unsigned int i;
1899 u32 srev;
1900 u16 ret;
1901
1902 ATH5K_TRACE(ah->ah_sc);
1903
1904 /*
1905 * Set the radio chip access register
1906 */
1907 switch (chan) {
1908 case CHANNEL_2GHZ:
1909 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_2GHZ, AR5K_PHY(0));
1910 break;
1911 case CHANNEL_5GHZ:
1912 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
1913 break;
1914 default:
1915 return 0;
1916 }
1917
1918 mdelay(2);
1919
1920 /* ...wait until PHY is ready and read the selected radio revision */
1921 ath5k_hw_reg_write(ah, 0x00001c16, AR5K_PHY(0x34));
1922
1923 for (i = 0; i < 8; i++)
1924 ath5k_hw_reg_write(ah, 0x00010000, AR5K_PHY(0x20));
1925
1926 if (ah->ah_version == AR5K_AR5210) {
1927 srev = ath5k_hw_reg_read(ah, AR5K_PHY(256) >> 28) & 0xf;
1928 ret = (u16)ath5k_hw_bitswap(srev, 4) + 1;
1929 } else {
1930 srev = (ath5k_hw_reg_read(ah, AR5K_PHY(0x100)) >> 24) & 0xff;
1931 ret = (u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
1932 ((srev & 0x0f) << 4), 8);
1933 }
1934
1935 /* Reset to the 5GHz mode */
1936 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
1937
1938 return ret;
1939}
1940
1941void /*TODO:Boundary check*/
1942ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant)
1943{
1944 ATH5K_TRACE(ah->ah_sc);
1945 /*Just a try M.F.*/
1946 if (ah->ah_version != AR5K_AR5210)
1947 ath5k_hw_reg_write(ah, ant, AR5K_DEFAULT_ANTENNA);
1948}
1949
1950unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah)
1951{
1952 ATH5K_TRACE(ah->ah_sc);
1953 /*Just a try M.F.*/
1954 if (ah->ah_version != AR5K_AR5210)
1955 return ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
1956
1957 return false; /*XXX: What do we return for 5210 ?*/
1958}
1959
1960/*
1961 * TX power setup
1962 */
1963
1964/*
1965 * Initialize the tx power table (not fully implemented)
1966 */
1967static void ath5k_txpower_table(struct ath5k_hw *ah,
1968 struct ieee80211_channel *channel, s16 max_power)
1969{
1970 unsigned int i, min, max, n;
1971 u16 txpower, *rates;
1972
1973 rates = ah->ah_txpower.txp_rates;
1974
1975 txpower = AR5K_TUNE_DEFAULT_TXPOWER * 2;
1976 if (max_power > txpower)
1977 txpower = max_power > AR5K_TUNE_MAX_TXPOWER ?
1978 AR5K_TUNE_MAX_TXPOWER : max_power;
1979
1980 for (i = 0; i < AR5K_MAX_RATES; i++)
1981 rates[i] = txpower;
1982
1983 /* XXX setup target powers by rate */
1984
1985 ah->ah_txpower.txp_min = rates[7];
1986 ah->ah_txpower.txp_max = rates[0];
1987 ah->ah_txpower.txp_ofdm = rates[0];
1988
1989 /* Calculate the power table */
1990 n = ARRAY_SIZE(ah->ah_txpower.txp_pcdac);
1991 min = AR5K_EEPROM_PCDAC_START;
1992 max = AR5K_EEPROM_PCDAC_STOP;
1993 for (i = 0; i < n; i += AR5K_EEPROM_PCDAC_STEP)
1994 ah->ah_txpower.txp_pcdac[i] =
1995#ifdef notyet
1996 min + ((i * (max - min)) / n);
1997#else
1998 min;
1999#endif
2000}
2001
2002/*
2003 * Set transmition power
2004 */
2005int /*O.K. - txpower_table is unimplemented so this doesn't work*/
2006ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
2007 unsigned int txpower)
2008{
2009 bool tpc = ah->ah_txpower.txp_tpc;
2010 unsigned int i;
2011
2012 ATH5K_TRACE(ah->ah_sc);
2013 if (txpower > AR5K_TUNE_MAX_TXPOWER) {
2014 ATH5K_ERR(ah->ah_sc, "invalid tx power: %u\n", txpower);
2015 return -EINVAL;
2016 }
2017
2018 /* Reset TX power values */
2019 memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
2020 ah->ah_txpower.txp_tpc = tpc;
2021
2022 /* Initialize TX power table */
2023 ath5k_txpower_table(ah, channel, txpower);
2024
2025 /*
2026 * Write TX power values
2027 */
2028 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
2029 ath5k_hw_reg_write(ah,
2030 ((((ah->ah_txpower.txp_pcdac[(i << 1) + 1] << 8) | 0xff) & 0xffff) << 16) |
2031 (((ah->ah_txpower.txp_pcdac[(i << 1) ] << 8) | 0xff) & 0xffff),
2032 AR5K_PHY_PCDAC_TXPOWER(i));
2033 }
2034
2035 ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(3, 24) |
2036 AR5K_TXPOWER_OFDM(2, 16) | AR5K_TXPOWER_OFDM(1, 8) |
2037 AR5K_TXPOWER_OFDM(0, 0), AR5K_PHY_TXPOWER_RATE1);
2038
2039 ath5k_hw_reg_write(ah, AR5K_TXPOWER_OFDM(7, 24) |
2040 AR5K_TXPOWER_OFDM(6, 16) | AR5K_TXPOWER_OFDM(5, 8) |
2041 AR5K_TXPOWER_OFDM(4, 0), AR5K_PHY_TXPOWER_RATE2);
2042
2043 ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(10, 24) |
2044 AR5K_TXPOWER_CCK(9, 16) | AR5K_TXPOWER_CCK(15, 8) |
2045 AR5K_TXPOWER_CCK(8, 0), AR5K_PHY_TXPOWER_RATE3);
2046
2047 ath5k_hw_reg_write(ah, AR5K_TXPOWER_CCK(14, 24) |
2048 AR5K_TXPOWER_CCK(13, 16) | AR5K_TXPOWER_CCK(12, 8) |
2049 AR5K_TXPOWER_CCK(11, 0), AR5K_PHY_TXPOWER_RATE4);
2050
2051 if (ah->ah_txpower.txp_tpc == true)
2052 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE |
2053 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
2054 else
2055 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX |
2056 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX);
2057
2058 return 0;
2059}
2060
2061int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power)
2062{
2063 /*Just a try M.F.*/
2064 struct ieee80211_channel *channel = &ah->ah_current_channel;
2065
2066 ATH5K_TRACE(ah->ah_sc);
2067 ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
2068 "changing txpower to %d\n", power);
2069
2070 return ath5k_hw_txpower(ah, channel, power);
2071}
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h
new file mode 100644
index 000000000000..2f41c8398602
--- /dev/null
+++ b/drivers/net/wireless/ath5k/reg.h
@@ -0,0 +1,1987 @@
1/*
2 * Copyright (c) 2007 Nick Kossifidis <mickflemm@gmail.com>
3 * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org>
4 * Copyright (c) 2007 Michael Taylor <mike.taylor@apprion.com>
5 *
6 * Permission to use, copy, modify, and 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
20/*
21 * Register values for Atheros 5210/5211/5212 cards from OpenBSD's ar5k
22 * maintained by Reyk Floeter
23 *
24 * I tried to document those registers by looking at ar5k code, some
25 * 802.11 (802.11e mostly) papers and by reading various public available
26 * Atheros presentations and papers like these:
27 *
28 * 5210 - http://nova.stanford.edu/~bbaas/ps/isscc2002_slides.pdf
29 * http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf
30 *
31 * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf
32 */
33
34
35
36/*====MAC DMA REGISTERS====*/
37
38/*
39 * AR5210-Specific TXDP registers
40 * 5210 has only 2 transmit queues so no DCU/QCU, just
41 * 2 transmit descriptor pointers...
42 */
43#define AR5K_NOQCU_TXDP0 0x0000 /* Queue 0 - data */
44#define AR5K_NOQCU_TXDP1 0x0004 /* Queue 1 - beacons */
45
46/*
47 * Mac Control Register
48 */
49#define AR5K_CR 0x0008 /* Register Address */
50#define AR5K_CR_TXE0 0x00000001 /* TX Enable for queue 0 on 5210 */
51#define AR5K_CR_TXE1 0x00000002 /* TX Enable for queue 1 on 5210 */
52#define AR5K_CR_RXE 0x00000004 /* RX Enable */
53#define AR5K_CR_TXD0 0x00000008 /* TX Disable for queue 0 on 5210 */
54#define AR5K_CR_TXD1 0x00000010 /* TX Disable for queue 1 on 5210 */
55#define AR5K_CR_RXD 0x00000020 /* RX Disable */
56#define AR5K_CR_SWI 0x00000040
57
58/*
59 * RX Descriptor Pointer register
60 */
61#define AR5K_RXDP 0x000c
62
63/*
64 * Configuration and status register
65 */
66#define AR5K_CFG 0x0014 /* Register Address */
67#define AR5K_CFG_SWTD 0x00000001 /* Byte-swap TX descriptor (for big endian archs) */
68#define AR5K_CFG_SWTB 0x00000002 /* Byte-swap TX buffer (?) */
69#define AR5K_CFG_SWRD 0x00000004 /* Byte-swap RX descriptor */
70#define AR5K_CFG_SWRB 0x00000008 /* Byte-swap RX buffer (?) */
71#define AR5K_CFG_SWRG 0x00000010 /* Byte-swap Register values (?) */
72#define AR5K_CFG_ADHOC 0x00000020 /* [5211+] */
73#define AR5K_CFG_PHY_OK 0x00000100 /* [5211+] */
74#define AR5K_CFG_EEBS 0x00000200 /* EEPROM is busy */
75#define AR5K_CFG_CLKGD 0x00000400 /* Clock gated (?) */
76#define AR5K_CFG_TXCNT 0x00007800 /* Tx frame count (?) [5210] */
77#define AR5K_CFG_TXCNT_S 11
78#define AR5K_CFG_TXFSTAT 0x00008000 /* Tx frame status (?) [5210] */
79#define AR5K_CFG_TXFSTRT 0x00010000 /* [5210] */
80#define AR5K_CFG_PCI_THRES 0x00060000 /* [5211+] */
81#define AR5K_CFG_PCI_THRES_S 17
82
83/*
84 * Interrupt enable register
85 */
86#define AR5K_IER 0x0024 /* Register Address */
87#define AR5K_IER_DISABLE 0x00000000 /* Disable card interrupts */
88#define AR5K_IER_ENABLE 0x00000001 /* Enable card interrupts */
89
90
91/*
92 * 0x0028 is Beacon Control Register on 5210
93 * and first RTS duration register on 5211
94 */
95
96/*
97 * Beacon control register [5210]
98 */
99#define AR5K_BCR 0x0028 /* Register Address */
100#define AR5K_BCR_AP 0x00000000 /* AP mode */
101#define AR5K_BCR_ADHOC 0x00000001 /* Ad-Hoc mode */
102#define AR5K_BCR_BDMAE 0x00000002 /* DMA enable */
103#define AR5K_BCR_TQ1FV 0x00000004 /* Use Queue1 for CAB traffic */
104#define AR5K_BCR_TQ1V 0x00000008 /* Use Queue1 for Beacon traffic */
105#define AR5K_BCR_BCGET 0x00000010
106
107/*
108 * First RTS duration register [5211]
109 */
110#define AR5K_RTSD0 0x0028 /* Register Address */
111#define AR5K_RTSD0_6 0x000000ff /* 6Mb RTS duration mask (?) */
112#define AR5K_RTSD0_6_S 0 /* 6Mb RTS duration shift (?) */
113#define AR5K_RTSD0_9 0x0000ff00 /* 9Mb*/
114#define AR5K_RTSD0_9_S 8
115#define AR5K_RTSD0_12 0x00ff0000 /* 12Mb*/
116#define AR5K_RTSD0_12_S 16
117#define AR5K_RTSD0_18 0xff000000 /* 16Mb*/
118#define AR5K_RTSD0_18_S 24
119
120
121/*
122 * 0x002c is Beacon Status Register on 5210
123 * and second RTS duration register on 5211
124 */
125
126/*
127 * Beacon status register [5210]
128 *
129 * As i can see in ar5k_ar5210_tx_start Reyk uses some of the values of BCR
130 * for this register, so i guess TQ1V,TQ1FV and BDMAE have the same meaning
131 * here and SNP/SNAP means "snapshot" (so this register gets synced with BCR).
132 * So SNAPPEDBCRVALID sould also stand for "snapped BCR -values- valid", so i
133 * renamed it to SNAPSHOTSVALID to make more sense. I realy have no idea what
134 * else can it be. I also renamed SNPBCMD to SNPADHOC to match BCR.
135 */
136#define AR5K_BSR 0x002c /* Register Address */
137#define AR5K_BSR_BDLYSW 0x00000001 /* SW Beacon delay (?) */
138#define AR5K_BSR_BDLYDMA 0x00000002 /* DMA Beacon delay (?) */
139#define AR5K_BSR_TXQ1F 0x00000004 /* Beacon queue (1) finished */
140#define AR5K_BSR_ATIMDLY 0x00000008 /* ATIM delay (?) */
141#define AR5K_BSR_SNPADHOC 0x00000100 /* Ad-hoc mode set (?) */
142#define AR5K_BSR_SNPBDMAE 0x00000200 /* Beacon DMA enabled (?) */
143#define AR5K_BSR_SNPTQ1FV 0x00000400 /* Queue1 is used for CAB traffic (?) */
144#define AR5K_BSR_SNPTQ1V 0x00000800 /* Queue1 is used for Beacon traffic (?) */
145#define AR5K_BSR_SNAPSHOTSVALID 0x00001000 /* BCR snapshots are valid (?) */
146#define AR5K_BSR_SWBA_CNT 0x00ff0000
147
148/*
149 * Second RTS duration register [5211]
150 */
151#define AR5K_RTSD1 0x002c /* Register Address */
152#define AR5K_RTSD1_24 0x000000ff /* 24Mb */
153#define AR5K_RTSD1_24_S 0
154#define AR5K_RTSD1_36 0x0000ff00 /* 36Mb */
155#define AR5K_RTSD1_36_S 8
156#define AR5K_RTSD1_48 0x00ff0000 /* 48Mb */
157#define AR5K_RTSD1_48_S 16
158#define AR5K_RTSD1_54 0xff000000 /* 54Mb */
159#define AR5K_RTSD1_54_S 24
160
161
162/*
163 * Transmit configuration register
164 */
165#define AR5K_TXCFG 0x0030 /* Register Address */
166#define AR5K_TXCFG_SDMAMR 0x00000007 /* DMA size */
167#define AR5K_TXCFG_SDMAMR_S 0
168#define AR5K_TXCFG_B_MODE 0x00000008 /* Set b mode for 5111 (enable 2111) */
169#define AR5K_TXCFG_TXFSTP 0x00000008 /* TX DMA full Stop [5210] */
170#define AR5K_TXCFG_TXFULL 0x000003f0 /* TX Triger level mask */
171#define AR5K_TXCFG_TXFULL_S 4
172#define AR5K_TXCFG_TXFULL_0B 0x00000000
173#define AR5K_TXCFG_TXFULL_64B 0x00000010
174#define AR5K_TXCFG_TXFULL_128B 0x00000020
175#define AR5K_TXCFG_TXFULL_192B 0x00000030
176#define AR5K_TXCFG_TXFULL_256B 0x00000040
177#define AR5K_TXCFG_TXCONT_EN 0x00000080
178#define AR5K_TXCFG_DMASIZE 0x00000100 /* Flag for passing DMA size [5210] */
179#define AR5K_TXCFG_JUMBO_TXE 0x00000400 /* Enable jumbo frames transmition (?) [5211+] */
180#define AR5K_TXCFG_RTSRND 0x00001000 /* [5211+] */
181#define AR5K_TXCFG_FRMPAD_DIS 0x00002000 /* [5211+] */
182#define AR5K_TXCFG_RDY_DIS 0x00004000 /* [5211+] */
183
184/*
185 * Receive configuration register
186 */
187#define AR5K_RXCFG 0x0034 /* Register Address */
188#define AR5K_RXCFG_SDMAMW 0x00000007 /* DMA size */
189#define AR5K_RXCFG_SDMAMW_S 0
190#define AR5K_RXCFG_DEF_ANTENNA 0x00000008 /* Default antenna */
191#define AR5K_RXCFG_ZLFDMA 0x00000010 /* Zero-length DMA */
192#define AR5K_RXCFG_JUMBO_RXE 0x00000020 /* Enable jumbo frames reception (?) [5211+] */
193#define AR5K_RXCFG_JUMBO_WRAP 0x00000040 /* Wrap jumbo frames (?) [5211+] */
194
195/*
196 * Receive jumbo descriptor last address register
197 * Only found in 5211 (?)
198 */
199#define AR5K_RXJLA 0x0038
200
201/*
202 * MIB control register
203 */
204#define AR5K_MIBC 0x0040 /* Register Address */
205#define AR5K_MIBC_COW 0x00000001
206#define AR5K_MIBC_FMC 0x00000002 /* Freeze Mib Counters (?) */
207#define AR5K_MIBC_CMC 0x00000004 /* Clean Mib Counters (?) */
208#define AR5K_MIBC_MCS 0x00000008
209
210/*
211 * Timeout prescale register
212 */
213#define AR5K_TOPS 0x0044
214#define AR5K_TOPS_M 0x0000ffff /* [5211+] (?) */
215
216/*
217 * Receive timeout register (no frame received)
218 */
219#define AR5K_RXNOFRM 0x0048
220#define AR5K_RXNOFRM_M 0x000003ff /* [5211+] (?) */
221
222/*
223 * Transmit timeout register (no frame sent)
224 */
225#define AR5K_TXNOFRM 0x004c
226#define AR5K_TXNOFRM_M 0x000003ff /* [5211+] (?) */
227#define AR5K_TXNOFRM_QCU 0x000ffc00 /* [5211+] (?) */
228
229/*
230 * Receive frame gap timeout register
231 */
232#define AR5K_RPGTO 0x0050
233#define AR5K_RPGTO_M 0x000003ff /* [5211+] (?) */
234
235/*
236 * Receive frame count limit register
237 */
238#define AR5K_RFCNT 0x0054
239#define AR5K_RFCNT_M 0x0000001f /* [5211+] (?) */
240#define AR5K_RFCNT_RFCL 0x0000000f /* [5210] */
241
242/*
243 * Misc settings register
244 */
245#define AR5K_MISC 0x0058 /* Register Address */
246#define AR5K_MISC_DMA_OBS_M 0x000001e0
247#define AR5K_MISC_DMA_OBS_S 5
248#define AR5K_MISC_MISC_OBS_M 0x00000e00
249#define AR5K_MISC_MISC_OBS_S 9
250#define AR5K_MISC_MAC_OBS_LSB_M 0x00007000
251#define AR5K_MISC_MAC_OBS_LSB_S 12
252#define AR5K_MISC_MAC_OBS_MSB_M 0x00038000
253#define AR5K_MISC_MAC_OBS_MSB_S 15
254#define AR5K_MISC_LED_DECAY 0x001c0000 /* [5210] */
255#define AR5K_MISC_LED_BLINK 0x00e00000 /* [5210] */
256
257/*
258 * QCU/DCU clock gating register (5311)
259 */
260#define AR5K_QCUDCU_CLKGT 0x005c /* Register Address (?) */
261#define AR5K_QCUDCU_CLKGT_QCU 0x0000ffff /* Mask for QCU clock */
262#define AR5K_QCUDCU_CLKGT_DCU 0x07ff0000 /* Mask for DCU clock */
263
264/*
265 * Interrupt Status Registers
266 *
267 * For 5210 there is only one status register but for
268 * 5211/5212 we have one primary and 4 secondary registers.
269 * So we have AR5K_ISR for 5210 and AR5K_PISR /SISRx for 5211/5212.
270 * Most of these bits are common for all chipsets.
271 */
272#define AR5K_ISR 0x001c /* Register Address [5210] */
273#define AR5K_PISR 0x0080 /* Register Address [5211+] */
274#define AR5K_ISR_RXOK 0x00000001 /* Frame successfuly recieved */
275#define AR5K_ISR_RXDESC 0x00000002 /* RX descriptor request */
276#define AR5K_ISR_RXERR 0x00000004 /* Receive error */
277#define AR5K_ISR_RXNOFRM 0x00000008 /* No frame received (receive timeout) */
278#define AR5K_ISR_RXEOL 0x00000010 /* Empty RX descriptor */
279#define AR5K_ISR_RXORN 0x00000020 /* Receive FIFO overrun */
280#define AR5K_ISR_TXOK 0x00000040 /* Frame successfuly transmited */
281#define AR5K_ISR_TXDESC 0x00000080 /* TX descriptor request */
282#define AR5K_ISR_TXERR 0x00000100 /* Transmit error */
283#define AR5K_ISR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout) */
284#define AR5K_ISR_TXEOL 0x00000400 /* Empty TX descriptor */
285#define AR5K_ISR_TXURN 0x00000800 /* Transmit FIFO underrun */
286#define AR5K_ISR_MIB 0x00001000 /* Update MIB counters */
287#define AR5K_ISR_SWI 0x00002000 /* Software interrupt (?) */
288#define AR5K_ISR_RXPHY 0x00004000 /* PHY error */
289#define AR5K_ISR_RXKCM 0x00008000
290#define AR5K_ISR_SWBA 0x00010000 /* Software beacon alert */
291#define AR5K_ISR_BRSSI 0x00020000
292#define AR5K_ISR_BMISS 0x00040000 /* Beacon missed */
293#define AR5K_ISR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */
294#define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */
295#define AR5K_ISR_MCABT 0x00100000 /* [5210] */
296#define AR5K_ISR_RXCHIRP 0x00200000 /* [5212+] */
297#define AR5K_ISR_SSERR 0x00200000 /* [5210] */
298#define AR5K_ISR_DPERR 0x00400000 /* [5210] */
299#define AR5K_ISR_TIM 0x00800000 /* [5210] */
300#define AR5K_ISR_BCNMISC 0x00800000 /* [5212+] */
301#define AR5K_ISR_GPIO 0x01000000 /* GPIO (rf kill)*/
302#define AR5K_ISR_QCBRORN 0x02000000 /* CBR overrun (?) [5211+] */
303#define AR5K_ISR_QCBRURN 0x04000000 /* CBR underrun (?) [5211+] */
304#define AR5K_ISR_QTRIG 0x08000000 /* [5211+] */
305
306/*
307 * Secondary status registers [5211+] (0 - 4)
308 *
309 * I guess from the names that these give the status for each
310 * queue, that's why only masks are defined here, haven't got
311 * any info about them (couldn't find them anywhere in ar5k code).
312 */
313#define AR5K_SISR0 0x0084 /* Register Address [5211+] */
314#define AR5K_SISR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */
315#define AR5K_SISR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */
316
317#define AR5K_SISR1 0x0088 /* Register Address [5211+] */
318#define AR5K_SISR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */
319#define AR5K_SISR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */
320
321#define AR5K_SISR2 0x008c /* Register Address [5211+] */
322#define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */
323#define AR5K_SISR2_MCABT 0x00100000
324#define AR5K_SISR2_SSERR 0x00200000
325#define AR5K_SISR2_DPERR 0x00400000
326#define AR5K_SISR2_TIM 0x01000000 /* [5212+] */
327#define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */
328#define AR5K_SISR2_DTIM_SYNC 0x04000000 /* [5212+] */
329#define AR5K_SISR2_BCN_TIMEOUT 0x08000000 /* [5212+] */
330#define AR5K_SISR2_CAB_TIMEOUT 0x10000000 /* [5212+] */
331#define AR5K_SISR2_DTIM 0x20000000 /* [5212+] */
332
333#define AR5K_SISR3 0x0090 /* Register Address [5211+] */
334#define AR5K_SISR3_QCBRORN 0x000003ff /* Mask for QCBRORN */
335#define AR5K_SISR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */
336
337#define AR5K_SISR4 0x0094 /* Register Address [5211+] */
338#define AR5K_SISR4_QTRIG 0x000003ff /* Mask for QTRIG */
339
340/*
341 * Shadow read-and-clear interrupt status registers [5211+]
342 */
343#define AR5K_RAC_PISR 0x00c0 /* Read and clear PISR */
344#define AR5K_RAC_SISR0 0x00c4 /* Read and clear SISR0 */
345#define AR5K_RAC_SISR1 0x00c8 /* Read and clear SISR1 */
346#define AR5K_RAC_SISR2 0x00cc /* Read and clear SISR2 */
347#define AR5K_RAC_SISR3 0x00d0 /* Read and clear SISR3 */
348#define AR5K_RAC_SISR4 0x00d4 /* Read and clear SISR4 */
349
350/*
351 * Interrupt Mask Registers
352 *
353 * As whith ISRs 5210 has one IMR (AR5K_IMR) and 5211/5212 has one primary
354 * (AR5K_PIMR) and 4 secondary IMRs (AR5K_SIMRx). Note that ISR/IMR flags match.
355 */
356#define AR5K_IMR 0x0020 /* Register Address [5210] */
357#define AR5K_PIMR 0x00a0 /* Register Address [5211+] */
358#define AR5K_IMR_RXOK 0x00000001 /* Frame successfuly recieved*/
359#define AR5K_IMR_RXDESC 0x00000002 /* RX descriptor request*/
360#define AR5K_IMR_RXERR 0x00000004 /* Receive error*/
361#define AR5K_IMR_RXNOFRM 0x00000008 /* No frame received (receive timeout)*/
362#define AR5K_IMR_RXEOL 0x00000010 /* Empty RX descriptor*/
363#define AR5K_IMR_RXORN 0x00000020 /* Receive FIFO overrun*/
364#define AR5K_IMR_TXOK 0x00000040 /* Frame successfuly transmited*/
365#define AR5K_IMR_TXDESC 0x00000080 /* TX descriptor request*/
366#define AR5K_IMR_TXERR 0x00000100 /* Transmit error*/
367#define AR5K_IMR_TXNOFRM 0x00000200 /* No frame transmited (transmit timeout)*/
368#define AR5K_IMR_TXEOL 0x00000400 /* Empty TX descriptor*/
369#define AR5K_IMR_TXURN 0x00000800 /* Transmit FIFO underrun*/
370#define AR5K_IMR_MIB 0x00001000 /* Update MIB counters*/
371#define AR5K_IMR_SWI 0x00002000
372#define AR5K_IMR_RXPHY 0x00004000 /* PHY error*/
373#define AR5K_IMR_RXKCM 0x00008000
374#define AR5K_IMR_SWBA 0x00010000 /* Software beacon alert*/
375#define AR5K_IMR_BRSSI 0x00020000
376#define AR5K_IMR_BMISS 0x00040000 /* Beacon missed*/
377#define AR5K_IMR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */
378#define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */
379#define AR5K_IMR_MCABT 0x00100000 /* [5210] */
380#define AR5K_IMR_RXCHIRP 0x00200000 /* [5212+]*/
381#define AR5K_IMR_SSERR 0x00200000 /* [5210] */
382#define AR5K_IMR_DPERR 0x00400000 /* [5210] */
383#define AR5K_IMR_TIM 0x00800000 /* [5211+] */
384#define AR5K_IMR_BCNMISC 0x00800000 /* [5212+] */
385#define AR5K_IMR_GPIO 0x01000000 /* GPIO (rf kill)*/
386#define AR5K_IMR_QCBRORN 0x02000000 /* CBR overrun (?) [5211+] */
387#define AR5K_IMR_QCBRURN 0x04000000 /* CBR underrun (?) [5211+] */
388#define AR5K_IMR_QTRIG 0x08000000 /* [5211+] */
389
390/*
391 * Secondary interrupt mask registers [5211+] (0 - 4)
392 */
393#define AR5K_SIMR0 0x00a4 /* Register Address [5211+] */
394#define AR5K_SIMR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */
395#define AR5K_SIMR0_QCU_TXOK_S 0
396#define AR5K_SIMR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */
397#define AR5K_SIMR0_QCU_TXDESC_S 16
398
399#define AR5K_SIMR1 0x00a8 /* Register Address [5211+] */
400#define AR5K_SIMR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */
401#define AR5K_SIMR1_QCU_TXERR_S 0
402#define AR5K_SIMR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */
403#define AR5K_SIMR1_QCU_TXEOL_S 16
404
405#define AR5K_SIMR2 0x00ac /* Register Address [5211+] */
406#define AR5K_SIMR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */
407#define AR5K_SIMR2_QCU_TXURN_S 0
408#define AR5K_SIMR2_MCABT 0x00100000
409#define AR5K_SIMR2_SSERR 0x00200000
410#define AR5K_SIMR2_DPERR 0x00400000
411#define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */
412#define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */
413#define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* [5212+] */
414#define AR5K_SIMR2_BCN_TIMEOUT 0x08000000 /* [5212+] */
415#define AR5K_SIMR2_CAB_TIMEOUT 0x10000000 /* [5212+] */
416#define AR5K_SIMR2_DTIM 0x20000000 /* [5212+] */
417
418#define AR5K_SIMR3 0x00b0 /* Register Address [5211+] */
419#define AR5K_SIMR3_QCBRORN 0x000003ff /* Mask for QCBRORN */
420#define AR5K_SIMR3_QCBRORN_S 0
421#define AR5K_SIMR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */
422#define AR5K_SIMR3_QCBRURN_S 16
423
424#define AR5K_SIMR4 0x00b4 /* Register Address [5211+] */
425#define AR5K_SIMR4_QTRIG 0x000003ff /* Mask for QTRIG */
426#define AR5K_SIMR4_QTRIG_S 0
427
428
429/*
430 * Decompression mask registers [5212+]
431 */
432#define AR5K_DCM_ADDR 0x0400 /*Decompression mask address (?)*/
433#define AR5K_DCM_DATA 0x0404 /*Decompression mask data (?)*/
434
435/*
436 * Decompression configuration registers [5212+]
437 */
438#define AR5K_DCCFG 0x0420
439
440/*
441 * Compression configuration registers [5212+]
442 */
443#define AR5K_CCFG 0x0600
444#define AR5K_CCFG_CUP 0x0604
445
446/*
447 * Compression performance counter registers [5212+]
448 */
449#define AR5K_CPC0 0x0610 /* Compression performance counter 0 */
450#define AR5K_CPC1 0x0614 /* Compression performance counter 1*/
451#define AR5K_CPC2 0x0618 /* Compression performance counter 2 */
452#define AR5K_CPC3 0x061c /* Compression performance counter 3 */
453#define AR5K_CPCORN 0x0620 /* Compression performance overrun (?) */
454
455
456/*
457 * Queue control unit (QCU) registers [5211+]
458 *
459 * Card has 12 TX Queues but i see that only 0-9 are used (?)
460 * both in binary HAL (see ah.h) and ar5k. Each queue has it's own
461 * TXDP at addresses 0x0800 - 0x082c, a CBR (Constant Bit Rate)
462 * configuration register (0x08c0 - 0x08ec), a ready time configuration
463 * register (0x0900 - 0x092c), a misc configuration register (0x09c0 -
464 * 0x09ec) and a status register (0x0a00 - 0x0a2c). We also have some
465 * global registers, QCU transmit enable/disable and "one shot arm (?)"
466 * set/clear, which contain status for all queues (we shift by 1 for each
467 * queue). To access these registers easily we define some macros here
468 * that are used inside HAL. For more infos check out *_tx_queue functs.
469 *
470 * TODO: Boundary checking on macros (here?)
471 */
472
473/*
474 * Generic QCU Register access macros
475 */
476#define AR5K_QUEUE_REG(_r, _q) (((_q) << 2) + _r)
477#define AR5K_QCU_GLOBAL_READ(_r, _q) (AR5K_REG_READ(_r) & (1 << _q))
478#define AR5K_QCU_GLOBAL_WRITE(_r, _q) AR5K_REG_WRITE(_r, (1 << _q))
479
480/*
481 * QCU Transmit descriptor pointer registers
482 */
483#define AR5K_QCU_TXDP_BASE 0x0800 /* Register Address - Queue0 TXDP */
484#define AR5K_QUEUE_TXDP(_q) AR5K_QUEUE_REG(AR5K_QCU_TXDP_BASE, _q)
485
486/*
487 * QCU Transmit enable register
488 */
489#define AR5K_QCU_TXE 0x0840
490#define AR5K_ENABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXE, _q)
491#define AR5K_QUEUE_ENABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXE, _q)
492
493/*
494 * QCU Transmit disable register
495 */
496#define AR5K_QCU_TXD 0x0880
497#define AR5K_DISABLE_QUEUE(_q) AR5K_QCU_GLOBAL_WRITE(AR5K_QCU_TXD, _q)
498#define AR5K_QUEUE_DISABLED(_q) AR5K_QCU_GLOBAL_READ(AR5K_QCU_TXD, _q)
499
500/*
501 * QCU Constant Bit Rate configuration registers
502 */
503#define AR5K_QCU_CBRCFG_BASE 0x08c0 /* Register Address - Queue0 CBRCFG */
504#define AR5K_QCU_CBRCFG_INTVAL 0x00ffffff /* CBR Interval mask */
505#define AR5K_QCU_CBRCFG_INTVAL_S 0
506#define AR5K_QCU_CBRCFG_ORN_THRES 0xff000000 /* CBR overrun threshold mask */
507#define AR5K_QCU_CBRCFG_ORN_THRES_S 24
508#define AR5K_QUEUE_CBRCFG(_q) AR5K_QUEUE_REG(AR5K_QCU_CBRCFG_BASE, _q)
509
510/*
511 * QCU Ready time configuration registers
512 */
513#define AR5K_QCU_RDYTIMECFG_BASE 0x0900 /* Register Address - Queue0 RDYTIMECFG */
514#define AR5K_QCU_RDYTIMECFG_INTVAL 0x00ffffff /* Ready time interval mask */
515#define AR5K_QCU_RDYTIMECFG_INTVAL_S 0
516#define AR5K_QCU_RDYTIMECFG_DURATION 0x00ffffff /* Ready time duration mask */
517#define AR5K_QCU_RDYTIMECFG_ENABLE 0x01000000 /* Ready time enable mask */
518#define AR5K_QUEUE_RDYTIMECFG(_q) AR5K_QUEUE_REG(AR5K_QCU_RDYTIMECFG_BASE, _q)
519
520/*
521 * QCU one shot arm set registers
522 */
523#define AR5K_QCU_ONESHOTARM_SET 0x0940 /* Register Address -QCU "one shot arm set (?)" */
524#define AR5K_QCU_ONESHOTARM_SET_M 0x0000ffff
525
526/*
527 * QCU one shot arm clear registers
528 */
529#define AR5K_QCU_ONESHOTARM_CLEAR 0x0980 /* Register Address -QCU "one shot arm clear (?)" */
530#define AR5K_QCU_ONESHOTARM_CLEAR_M 0x0000ffff
531
532/*
533 * QCU misc registers
534 */
535#define AR5K_QCU_MISC_BASE 0x09c0 /* Register Address -Queue0 MISC */
536#define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame sheduling mask */
537#define AR5K_QCU_MISC_FRSHED_ASAP 0 /* ASAP */
538#define AR5K_QCU_MISC_FRSHED_CBR 1 /* Constant Bit Rate */
539#define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated (?) */
540#define AR5K_QCU_MISC_FRSHED_TIM_GT 3 /* Time gated (?) */
541#define AR5K_QCU_MISC_FRSHED_BCN_SENT_GT 4 /* Beacon sent gated (?) */
542#define AR5K_QCU_MISC_ONESHOT_ENABLE 0x00000010 /* Oneshot enable */
543#define AR5K_QCU_MISC_CBREXP 0x00000020 /* CBR expired (normal queue) */
544#define AR5K_QCU_MISC_CBREXP_BCN 0x00000040 /* CBR expired (beacon queue) */
545#define AR5K_QCU_MISC_BCN_ENABLE 0x00000080 /* Beacons enabled */
546#define AR5K_QCU_MISC_CBR_THRES_ENABLE 0x00000100 /* CBR threshold enabled (?) */
547#define AR5K_QCU_MISC_TXE 0x00000200 /* TXE reset when RDYTIME enalbed (?) */
548#define AR5K_QCU_MISC_CBR 0x00000400 /* CBR threshold reset (?) */
549#define AR5K_QCU_MISC_DCU_EARLY 0x00000800 /* DCU reset (?) */
550#define AR5K_QUEUE_MISC(_q) AR5K_QUEUE_REG(AR5K_QCU_MISC_BASE, _q)
551
552
553/*
554 * QCU status registers
555 */
556#define AR5K_QCU_STS_BASE 0x0a00 /* Register Address - Queue0 STS */
557#define AR5K_QCU_STS_FRMPENDCNT 0x00000003 /* Frames pending counter */
558#define AR5K_QCU_STS_CBREXPCNT 0x0000ff00 /* CBR expired counter (?) */
559#define AR5K_QUEUE_STATUS(_q) AR5K_QUEUE_REG(AR5K_QCU_STS_BASE, _q)
560
561/*
562 * QCU ready time shutdown register
563 */
564#define AR5K_QCU_RDYTIMESHDN 0x0a40
565#define AR5K_QCU_RDYTIMESHDN_M 0x000003ff
566
567/*
568 * QCU compression buffer base registers [5212+]
569 */
570#define AR5K_QCU_CBB_SELECT 0x0b00
571#define AR5K_QCU_CBB_ADDR 0x0b04
572
573/*
574 * QCU compression buffer configuration register [5212+]
575 */
576#define AR5K_QCU_CBCFG 0x0b08
577
578
579
580/*
581 * Distributed Coordination Function (DCF) control unit (DCU)
582 * registers [5211+]
583 *
584 * These registers control the various characteristics of each queue
585 * for 802.11e (WME) combatibility so they go together with
586 * QCU registers in pairs. For each queue we have a QCU mask register,
587 * (0x1000 - 0x102c), a local-IFS settings register (0x1040 - 0x106c),
588 * a retry limit register (0x1080 - 0x10ac), a channel time register
589 * (0x10c0 - 0x10ec), a misc-settings register (0x1100 - 0x112c) and
590 * a sequence number register (0x1140 - 0x116c). It seems that "global"
591 * registers here afect all queues (see use of DCU_GBL_IFS_SLOT in ar5k).
592 * We use the same macros here for easier register access.
593 *
594 */
595
596/*
597 * DCU QCU mask registers
598 */
599#define AR5K_DCU_QCUMASK_BASE 0x1000 /* Register Address -Queue0 DCU_QCUMASK */
600#define AR5K_DCU_QCUMASK_M 0x000003ff
601#define AR5K_QUEUE_QCUMASK(_q) AR5K_QUEUE_REG(AR5K_DCU_QCUMASK_BASE, _q)
602
603/*
604 * DCU local Inter Frame Space settings register
605 */
606#define AR5K_DCU_LCL_IFS_BASE 0x1040 /* Register Address -Queue0 DCU_LCL_IFS */
607#define AR5K_DCU_LCL_IFS_CW_MIN 0x000003ff /* Minimum Contention Window */
608#define AR5K_DCU_LCL_IFS_CW_MIN_S 0
609#define AR5K_DCU_LCL_IFS_CW_MAX 0x000ffc00 /* Maximum Contention Window */
610#define AR5K_DCU_LCL_IFS_CW_MAX_S 10
611#define AR5K_DCU_LCL_IFS_AIFS 0x0ff00000 /* Arbitrated Interframe Space */
612#define AR5K_DCU_LCL_IFS_AIFS_S 20
613#define AR5K_QUEUE_DFS_LOCAL_IFS(_q) AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q)
614
615/*
616 * DCU retry limit registers
617 */
618#define AR5K_DCU_RETRY_LMT_BASE 0x1080 /* Register Address -Queue0 DCU_RETRY_LMT */
619#define AR5K_DCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */
620#define AR5K_DCU_RETRY_LMT_SH_RETRY_S 0
621#define AR5K_DCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry limit mask */
622#define AR5K_DCU_RETRY_LMT_LG_RETRY_S 4
623#define AR5K_DCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask (?) */
624#define AR5K_DCU_RETRY_LMT_SSH_RETRY_S 8
625#define AR5K_DCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask (?) */
626#define AR5K_DCU_RETRY_LMT_SLG_RETRY_S 14
627#define AR5K_QUEUE_DFS_RETRY_LIMIT(_q) AR5K_QUEUE_REG(AR5K_DCU_RETRY_LMT_BASE, _q)
628
629/*
630 * DCU channel time registers
631 */
632#define AR5K_DCU_CHAN_TIME_BASE 0x10c0 /* Register Address -Queue0 DCU_CHAN_TIME */
633#define AR5K_DCU_CHAN_TIME_DUR 0x000fffff /* Channel time duration */
634#define AR5K_DCU_CHAN_TIME_DUR_S 0
635#define AR5K_DCU_CHAN_TIME_ENABLE 0x00100000 /* Enable channel time */
636#define AR5K_QUEUE_DFS_CHANNEL_TIME(_q) AR5K_QUEUE_REG(AR5K_DCU_CHAN_TIME_BASE, _q)
637
638/*
639 * DCU misc registers [5211+]
640 *
641 * For some of the registers i couldn't find in the code
642 * (only backoff stuff is there realy) i tried to match the
643 * names with 802.11e parameters etc, so i guess VIRTCOL here
644 * means Virtual Collision and HCFPOLL means Hybrid Coordination
645 * factor Poll (CF- Poll). Arbiter lockout control controls the
646 * behaviour on low priority queues when we have multiple queues
647 * with pending frames. Intra-frame lockout means we wait until
648 * the queue's current frame transmits (with post frame backoff and bursting)
649 * before we transmit anything else and global lockout means we
650 * wait for the whole queue to finish before higher priority queues
651 * can transmit (this is used on beacon and CAB queues).
652 * No lockout means there is no special handling.
653 */
654#define AR5K_DCU_MISC_BASE 0x1100 /* Register Address -Queue0 DCU_MISC */
655#define AR5K_DCU_MISC_BACKOFF 0x000007ff /* Mask for backoff setting (?) */
656#define AR5K_DCU_MISC_BACKOFF_FRAG 0x00000200 /* Enable backoff while bursting */
657#define AR5K_DCU_MISC_HCFPOLL_ENABLE 0x00000800 /* CF - Poll (?) */
658#define AR5K_DCU_MISC_BACKOFF_PERSIST 0x00001000 /* Persistent backoff (?) */
659#define AR5K_DCU_MISC_FRMPRFTCH_ENABLE 0x00002000 /* Enable frame pre-fetch (?) */
660#define AR5K_DCU_MISC_VIRTCOL 0x0000c000 /* Mask for Virtual Collision (?) */
661#define AR5K_DCU_MISC_VIRTCOL_NORMAL 0
662#define AR5K_DCU_MISC_VIRTCOL_MODIFIED 1
663#define AR5K_DCU_MISC_VIRTCOL_IGNORE 2
664#define AR5K_DCU_MISC_BCN_ENABLE 0x00010000 /* Beacon enable (?) */
665#define AR5K_DCU_MISC_ARBLOCK_CTL 0x00060000 /* Arbiter lockout control mask */
666#define AR5K_DCU_MISC_ARBLOCK_CTL_S 17
667#define AR5K_DCU_MISC_ARBLOCK_CTL_NONE 0 /* No arbiter lockout */
668#define AR5K_DCU_MISC_ARBLOCK_CTL_INTFRM 1 /* Intra-frame lockout */
669#define AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL 2 /* Global lockout */
670#define AR5K_DCU_MISC_ARBLOCK_IGNORE 0x00080000
671#define AR5K_DCU_MISC_SEQ_NUM_INCR_DIS 0x00100000 /* Disable sequence number increment (?) */
672#define AR5K_DCU_MISC_POST_FR_BKOFF_DIS 0x00200000 /* Disable post-frame backoff (?) */
673#define AR5K_DCU_MISC_VIRT_COLL_POLICY 0x00400000 /* Virtual Collision policy (?) */
674#define AR5K_DCU_MISC_BLOWN_IFS_POLICY 0x00800000
675#define AR5K_DCU_MISC_SEQNUM_CTL 0x01000000 /* Sequence number control (?) */
676#define AR5K_QUEUE_DFS_MISC(_q) AR5K_QUEUE_REG(AR5K_DCU_MISC_BASE, _q)
677
678/*
679 * DCU frame sequence number registers
680 */
681#define AR5K_DCU_SEQNUM_BASE 0x1140
682#define AR5K_DCU_SEQNUM_M 0x00000fff
683#define AR5K_QUEUE_DFS_SEQNUM(_q) AR5K_QUEUE_REG(AR5K_DCU_SEQNUM_BASE, _q)
684
685/*
686 * DCU global IFS SIFS registers
687 */
688#define AR5K_DCU_GBL_IFS_SIFS 0x1030
689#define AR5K_DCU_GBL_IFS_SIFS_M 0x0000ffff
690
691/*
692 * DCU global IFS slot interval registers
693 */
694#define AR5K_DCU_GBL_IFS_SLOT 0x1070
695#define AR5K_DCU_GBL_IFS_SLOT_M 0x0000ffff
696
697/*
698 * DCU global IFS EIFS registers
699 */
700#define AR5K_DCU_GBL_IFS_EIFS 0x10b0
701#define AR5K_DCU_GBL_IFS_EIFS_M 0x0000ffff
702
703/*
704 * DCU global IFS misc registers
705 */
706#define AR5K_DCU_GBL_IFS_MISC 0x10f0 /* Register Address */
707#define AR5K_DCU_GBL_IFS_MISC_LFSR_SLICE 0x00000007
708#define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode (?) */
709#define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask (?) */
710#define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00
711#define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000
712
713/*
714 * DCU frame prefetch control register
715 */
716#define AR5K_DCU_FP 0x1230
717
718/*
719 * DCU transmit pause control/status register
720 */
721#define AR5K_DCU_TXP 0x1270 /* Register Address */
722#define AR5K_DCU_TXP_M 0x000003ff /* Tx pause mask (?) */
723#define AR5K_DCU_TXP_STATUS 0x00010000 /* Tx pause status (?) */
724
725/*
726 * DCU transmit filter register
727 */
728#define AR5K_DCU_TX_FILTER 0x1038
729
730/*
731 * DCU clear transmit filter register
732 */
733#define AR5K_DCU_TX_FILTER_CLR 0x143c
734
735/*
736 * DCU set transmit filter register
737 */
738#define AR5K_DCU_TX_FILTER_SET 0x147c
739
740/*
741 * Reset control register
742 *
743 * 4 and 8 are not used in 5211/5212 and
744 * 2 means "baseband reset" on 5211/5212.
745 */
746#define AR5K_RESET_CTL 0x4000 /* Register Address */
747#define AR5K_RESET_CTL_PCU 0x00000001 /* Protocol Control Unit reset */
748#define AR5K_RESET_CTL_DMA 0x00000002 /* DMA (Rx/Tx) reset [5210] */
749#define AR5K_RESET_CTL_BASEBAND 0x00000002 /* Baseband reset [5211+] */
750#define AR5K_RESET_CTL_MAC 0x00000004 /* MAC reset (PCU+Baseband ?) [5210] */
751#define AR5K_RESET_CTL_PHY 0x00000008 /* PHY reset [5210] */
752#define AR5K_RESET_CTL_PCI 0x00000010 /* PCI Core reset (interrupts etc) */
753#define AR5K_RESET_CTL_CHIP (AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | \
754 AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY)
755
756/*
757 * Sleep control register
758 */
759#define AR5K_SLEEP_CTL 0x4004 /* Register Address */
760#define AR5K_SLEEP_CTL_SLDUR 0x0000ffff /* Sleep duration mask */
761#define AR5K_SLEEP_CTL_SLDUR_S 0
762#define AR5K_SLEEP_CTL_SLE 0x00030000 /* Sleep enable mask */
763#define AR5K_SLEEP_CTL_SLE_S 16
764#define AR5K_SLEEP_CTL_SLE_WAKE 0x00000000 /* Force chip awake */
765#define AR5K_SLEEP_CTL_SLE_SLP 0x00010000 /* Force chip sleep */
766#define AR5K_SLEEP_CTL_SLE_ALLOW 0x00020000
767#define AR5K_SLEEP_CTL_SLE_UNITS 0x00000008 /* [5211+] */
768
769/*
770 * Interrupt pending register
771 */
772#define AR5K_INTPEND 0x4008
773#define AR5K_INTPEND_M 0x00000001
774
775/*
776 * Sleep force register
777 */
778#define AR5K_SFR 0x400c
779#define AR5K_SFR_M 0x00000001
780
781/*
782 * PCI configuration register
783 */
784#define AR5K_PCICFG 0x4010 /* Register Address */
785#define AR5K_PCICFG_EEAE 0x00000001 /* Eeprom access enable [5210] */
786#define AR5K_PCICFG_CLKRUNEN 0x00000004 /* CLKRUN enable [5211+] */
787#define AR5K_PCICFG_EESIZE 0x00000018 /* Mask for EEPROM size [5211+] */
788#define AR5K_PCICFG_EESIZE_S 3
789#define AR5K_PCICFG_EESIZE_4K 0 /* 4K */
790#define AR5K_PCICFG_EESIZE_8K 1 /* 8K */
791#define AR5K_PCICFG_EESIZE_16K 2 /* 16K */
792#define AR5K_PCICFG_EESIZE_FAIL 3 /* Failed to get size (?) [5211+] */
793#define AR5K_PCICFG_LED 0x00000060 /* Led status [5211+] */
794#define AR5K_PCICFG_LED_NONE 0x00000000 /* Default [5211+] */
795#define AR5K_PCICFG_LED_PEND 0x00000020 /* Scan / Auth pending */
796#define AR5K_PCICFG_LED_ASSOC 0x00000040 /* Associated */
797#define AR5K_PCICFG_BUS_SEL 0x00000380 /* Mask for "bus select" [5211+] (?) */
798#define AR5K_PCICFG_CBEFIX_DIS 0x00000400 /* Disable CBE fix (?) */
799#define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep (?) */
800#define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */
801#define AR5K_PCICFG_SL_INPEN 0x00002800 /* Sleep even whith pending interrupts (?) */
802#define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */
803#define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */
804#define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */
805#define AR5K_PCICFG_LEDMODE_PROM 0x00020000 /* Default mode (blink on any traffic) [5211+] */
806#define AR5K_PCICFG_LEDMODE_PWR 0x00040000 /* Some other blinking mode (?) [5211+] */
807#define AR5K_PCICFG_LEDMODE_RAND 0x00060000 /* Random blinking (?) [5211+] */
808#define AR5K_PCICFG_LEDBLINK 0x00700000
809#define AR5K_PCICFG_LEDBLINK_S 20
810#define AR5K_PCICFG_LEDSLOW 0x00800000 /* Slow led blink rate (?) [5211+] */
811#define AR5K_PCICFG_LEDSTATE \
812 (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE | \
813 AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW)
814
815/*
816 * "General Purpose Input/Output" (GPIO) control register
817 *
818 * I'm not sure about this but after looking at the code
819 * for all chipsets here is what i got.
820 *
821 * We have 6 GPIOs (pins), each GPIO has 4 modes (2 bits)
822 * Mode 0 -> always input
823 * Mode 1 -> output when GPIODO for this GPIO is set to 0
824 * Mode 2 -> output when GPIODO for this GPIO is set to 1
825 * Mode 3 -> always output
826 *
827 * For more infos check out get_gpio/set_gpio and
828 * set_gpio_input/set_gpio_output functs.
829 * For more infos on gpio interrupt check out set_gpio_intr.
830 */
831#define AR5K_NUM_GPIO 6
832
833#define AR5K_GPIOCR 0x4014 /* Register Address */
834#define AR5K_GPIOCR_INT_ENA 0x00008000 /* Enable GPIO interrupt */
835#define AR5K_GPIOCR_INT_SELL 0x00000000 /* Generate interrupt when pin is off (?) */
836#define AR5K_GPIOCR_INT_SELH 0x00010000 /* Generate interrupt when pin is on */
837#define AR5K_GPIOCR_IN(n) (0 << ((n) * 2)) /* Mode 0 for pin n */
838#define AR5K_GPIOCR_OUT0(n) (1 << ((n) * 2)) /* Mode 1 for pin n */
839#define AR5K_GPIOCR_OUT1(n) (2 << ((n) * 2)) /* Mode 2 for pin n */
840#define AR5K_GPIOCR_OUT(n) (3 << ((n) * 2)) /* Mode 3 for pin n */
841#define AR5K_GPIOCR_INT_SEL(n) ((n) << 12) /* Interrupt for GPIO pin n */
842
843/*
844 * "General Purpose Input/Output" (GPIO) data output register
845 */
846#define AR5K_GPIODO 0x4018
847
848/*
849 * "General Purpose Input/Output" (GPIO) data input register
850 */
851#define AR5K_GPIODI 0x401c
852#define AR5K_GPIODI_M 0x0000002f
853
854
855/*
856 * Silicon revision register
857 */
858#define AR5K_SREV 0x4020 /* Register Address */
859#define AR5K_SREV_REV 0x0000000f /* Mask for revision */
860#define AR5K_SREV_REV_S 0
861#define AR5K_SREV_VER 0x000000ff /* Mask for version */
862#define AR5K_SREV_VER_S 4
863
864
865
866/*====EEPROM REGISTERS====*/
867
868/*
869 * EEPROM access registers
870 *
871 * Here we got a difference between 5210/5211-12
872 * read data register for 5210 is at 0x6800 and
873 * status register is at 0x6c00. There is also
874 * no eeprom command register on 5210 and the
875 * offsets are different.
876 *
877 * To read eeprom data for a specific offset:
878 * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
879 * read AR5K_EEPROM_BASE +(4 * offset)
880 * check the eeprom status register
881 * and read eeprom data register.
882 *
883 * 5211 - write offset to AR5K_EEPROM_BASE
884 * 5212 write AR5K_EEPROM_CMD_READ on AR5K_EEPROM_CMD
885 * check the eeprom status register
886 * and read eeprom data register.
887 *
888 * To write eeprom data for a specific offset:
889 * 5210 - enable eeprom access (AR5K_PCICFG_EEAE)
890 * write data to AR5K_EEPROM_BASE +(4 * offset)
891 * check the eeprom status register
892 * 5211 - write AR5K_EEPROM_CMD_RESET on AR5K_EEPROM_CMD
893 * 5212 write offset to AR5K_EEPROM_BASE
894 * write data to data register
895 * write AR5K_EEPROM_CMD_WRITE on AR5K_EEPROM_CMD
896 * check the eeprom status register
897 *
898 * For more infos check eeprom_* functs and the ar5k.c
899 * file posted in madwifi-devel mailing list.
900 * http://sourceforge.net/mailarchive/message.php?msg_id=8966525
901 *
902 */
903#define AR5K_EEPROM_BASE 0x6000
904
905/*
906 * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE)
907 */
908#define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */
909#define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */
910#define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */
911#define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */
912#define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */
913
914#define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */
915#define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */
916#define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */
917#define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */
918#define AR5K_EEPROM_PROTECT_WR_32_63 0x0008
919#define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */
920#define AR5K_EEPROM_PROTECT_WR_64_127 0x0020
921#define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */
922#define AR5K_EEPROM_PROTECT_WR_128_191 0x0080
923#define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */
924#define AR5K_EEPROM_PROTECT_WR_192_207 0x0200
925#define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */
926#define AR5K_EEPROM_PROTECT_WR_208_223 0x0800
927#define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */
928#define AR5K_EEPROM_PROTECT_WR_224_239 0x2000
929#define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */
930#define AR5K_EEPROM_PROTECT_WR_240_255 0x8000
931#define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */
932#define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */
933#define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE)
934#define AR5K_EEPROM_INFO_CKSUM 0xffff
935#define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n))
936
937#define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */
938#define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */
939#define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */
940#define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */
941#define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */
942#define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */
943#define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */
944#define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */
945#define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */
946#define AR5K_EEPROM_VERSION_4_3 0x4003
947#define AR5K_EEPROM_VERSION_4_4 0x4004
948#define AR5K_EEPROM_VERSION_4_5 0x4005
949#define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */
950#define AR5K_EEPROM_VERSION_4_7 0x3007
951
952#define AR5K_EEPROM_MODE_11A 0
953#define AR5K_EEPROM_MODE_11B 1
954#define AR5K_EEPROM_MODE_11G 2
955
956#define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */
957#define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1)
958#define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1)
959#define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1)
960#define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */
961#define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */
962#define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7)
963#define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz (?) */
964#define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */
965
966#define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c
967#define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2
968#define AR5K_EEPROM_RFKILL_POLARITY 0x00000002
969#define AR5K_EEPROM_RFKILL_POLARITY_S 1
970
971/* Newer EEPROMs are using a different offset */
972#define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \
973 (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0)
974
975#define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3)
976#define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((int8_t)(((_v) >> 8) & 0xff))
977#define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff))
978
979/* calibration settings */
980#define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4)
981#define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2)
982#define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d)
983#define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */
984
985/* [3.1 - 3.3] */
986#define AR5K_EEPROM_OBDB0_2GHZ 0x00ec
987#define AR5K_EEPROM_OBDB1_2GHZ 0x00ed
988
989/* Misc values available since EEPROM 4.0 */
990#define AR5K_EEPROM_MISC0 0x00c4
991#define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff)
992#define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3)
993#define AR5K_EEPROM_MISC1 0x00c5
994#define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff)
995#define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1)
996
997/*
998 * EEPROM data register
999 */
1000#define AR5K_EEPROM_DATA_5211 0x6004
1001#define AR5K_EEPROM_DATA_5210 0x6800
1002#define AR5K_EEPROM_DATA (ah->ah_version == AR5K_AR5210 ? \
1003 AR5K_EEPROM_DATA_5210 : AR5K_EEPROM_DATA_5211)
1004
1005/*
1006 * EEPROM command register
1007 */
1008#define AR5K_EEPROM_CMD 0x6008 /* Register Addres */
1009#define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */
1010#define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */
1011#define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */
1012
1013/*
1014 * EEPROM status register
1015 */
1016#define AR5K_EEPROM_STAT_5210 0x6c00 /* Register Address [5210] */
1017#define AR5K_EEPROM_STAT_5211 0x600c /* Register Address [5211+] */
1018#define AR5K_EEPROM_STATUS (ah->ah_version == AR5K_AR5210 ? \
1019 AR5K_EEPROM_STAT_5210 : AR5K_EEPROM_STAT_5211)
1020#define AR5K_EEPROM_STAT_RDERR 0x00000001 /* EEPROM read failed */
1021#define AR5K_EEPROM_STAT_RDDONE 0x00000002 /* EEPROM read successful */
1022#define AR5K_EEPROM_STAT_WRERR 0x00000004 /* EEPROM write failed */
1023#define AR5K_EEPROM_STAT_WRDONE 0x00000008 /* EEPROM write successful */
1024
1025/*
1026 * EEPROM config register (?)
1027 */
1028#define AR5K_EEPROM_CFG 0x6010
1029
1030
1031
1032/*
1033 * Protocol Control Unit (PCU) registers
1034 */
1035/*
1036 * Used for checking initial register writes
1037 * during channel reset (see reset func)
1038 */
1039#define AR5K_PCU_MIN 0x8000
1040#define AR5K_PCU_MAX 0x8fff
1041
1042/*
1043 * First station id register (MAC address in lower 32 bits)
1044 */
1045#define AR5K_STA_ID0 0x8000
1046
1047/*
1048 * Second station id register (MAC address in upper 16 bits)
1049 */
1050#define AR5K_STA_ID1 0x8004 /* Register Address */
1051#define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */
1052#define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */
1053#define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting (?) */
1054#define AR5K_STA_ID1_NO_KEYSRCH 0x00080000 /* No key search */
1055#define AR5K_STA_ID1_NO_PSPOLL 0x00100000 /* No power save polling [5210] */
1056#define AR5K_STA_ID1_PCF_5211 0x00100000 /* Enable PCF on [5211+] */
1057#define AR5K_STA_ID1_PCF_5210 0x00200000 /* Enable PCF on [5210]*/
1058#define AR5K_STA_ID1_PCF (ah->ah_version == AR5K_AR5210 ? \
1059 AR5K_STA_ID1_PCF_5210 : AR5K_STA_ID1_PCF_5211)
1060#define AR5K_STA_ID1_DEFAULT_ANTENNA 0x00200000 /* Use default antenna */
1061#define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */
1062#define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS (?) */
1063#define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Use 6Mbit/s for ACK/CTS (?) */
1064#define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate (for ACK/CTS ?) [5211+] */
1065
1066/*
1067 * First BSSID register (MAC address, lower 32bits)
1068 */
1069#define AR5K_BSS_ID0 0x8008
1070
1071/*
1072 * Second BSSID register (MAC address in upper 16 bits)
1073 *
1074 * AID: Association ID
1075 */
1076#define AR5K_BSS_ID1 0x800c
1077#define AR5K_BSS_ID1_AID 0xffff0000
1078#define AR5K_BSS_ID1_AID_S 16
1079
1080/*
1081 * Backoff slot time register
1082 */
1083#define AR5K_SLOT_TIME 0x8010
1084
1085/*
1086 * ACK/CTS timeout register
1087 */
1088#define AR5K_TIME_OUT 0x8014 /* Register Address */
1089#define AR5K_TIME_OUT_ACK 0x00001fff /* ACK timeout mask */
1090#define AR5K_TIME_OUT_ACK_S 0
1091#define AR5K_TIME_OUT_CTS 0x1fff0000 /* CTS timeout mask */
1092#define AR5K_TIME_OUT_CTS_S 16
1093
1094/*
1095 * RSSI threshold register
1096 */
1097#define AR5K_RSSI_THR 0x8018 /* Register Address */
1098#define AR5K_RSSI_THR_M 0x000000ff /* Mask for RSSI threshold [5211+] */
1099#define AR5K_RSSI_THR_BMISS_5210 0x00000700 /* Mask for Beacon Missed threshold [5210] */
1100#define AR5K_RSSI_THR_BMISS_5210_S 8
1101#define AR5K_RSSI_THR_BMISS_5211 0x0000ff00 /* Mask for Beacon Missed threshold [5211+] */
1102#define AR5K_RSSI_THR_BMISS_5211_S 8
1103#define AR5K_RSSI_THR_BMISS (ah->ah_version == AR5K_AR5210 ? \
1104 AR5K_RSSI_THR_BMISS_5210 : AR5K_RSSI_THR_BMISS_5211)
1105#define AR5K_RSSI_THR_BMISS_S 8
1106
1107/*
1108 * 5210 has more PCU registers because there is no QCU/DCU
1109 * so queue parameters are set here, this way a lot common
1110 * registers have different address for 5210. To make things
1111 * easier we define a macro based on ah->ah_version for common
1112 * registers with different addresses and common flags.
1113 */
1114
1115/*
1116 * Retry limit register
1117 *
1118 * Retry limit register for 5210 (no QCU/DCU so it's done in PCU)
1119 */
1120#define AR5K_NODCU_RETRY_LMT 0x801c /*Register Address */
1121#define AR5K_NODCU_RETRY_LMT_SH_RETRY 0x0000000f /* Short retry limit mask */
1122#define AR5K_NODCU_RETRY_LMT_SH_RETRY_S 0
1123#define AR5K_NODCU_RETRY_LMT_LG_RETRY 0x000000f0 /* Long retry mask */
1124#define AR5K_NODCU_RETRY_LMT_LG_RETRY_S 4
1125#define AR5K_NODCU_RETRY_LMT_SSH_RETRY 0x00003f00 /* Station short retry limit mask */
1126#define AR5K_NODCU_RETRY_LMT_SSH_RETRY_S 8
1127#define AR5K_NODCU_RETRY_LMT_SLG_RETRY 0x000fc000 /* Station long retry limit mask */
1128#define AR5K_NODCU_RETRY_LMT_SLG_RETRY_S 14
1129#define AR5K_NODCU_RETRY_LMT_CW_MIN 0x3ff00000 /* Minimum contention window mask */
1130#define AR5K_NODCU_RETRY_LMT_CW_MIN_S 20
1131
1132/*
1133 * Transmit latency register
1134 */
1135#define AR5K_USEC_5210 0x8020 /* Register Address [5210] */
1136#define AR5K_USEC_5211 0x801c /* Register Address [5211+] */
1137#define AR5K_USEC (ah->ah_version == AR5K_AR5210 ? \
1138 AR5K_USEC_5210 : AR5K_USEC_5211)
1139#define AR5K_USEC_1 0x0000007f
1140#define AR5K_USEC_1_S 0
1141#define AR5K_USEC_32 0x00003f80
1142#define AR5K_USEC_32_S 7
1143#define AR5K_USEC_TX_LATENCY_5211 0x007fc000
1144#define AR5K_USEC_TX_LATENCY_5211_S 14
1145#define AR5K_USEC_RX_LATENCY_5211 0x1f800000
1146#define AR5K_USEC_RX_LATENCY_5211_S 23
1147#define AR5K_USEC_TX_LATENCY_5210 0x000fc000 /* also for 5311 */
1148#define AR5K_USEC_TX_LATENCY_5210_S 14
1149#define AR5K_USEC_RX_LATENCY_5210 0x03f00000 /* also for 5311 */
1150#define AR5K_USEC_RX_LATENCY_5210_S 20
1151
1152/*
1153 * PCU beacon control register
1154 */
1155#define AR5K_BEACON_5210 0x8024
1156#define AR5K_BEACON_5211 0x8020
1157#define AR5K_BEACON (ah->ah_version == AR5K_AR5210 ? \
1158 AR5K_BEACON_5210 : AR5K_BEACON_5211)
1159#define AR5K_BEACON_PERIOD 0x0000ffff
1160#define AR5K_BEACON_PERIOD_S 0
1161#define AR5K_BEACON_TIM 0x007f0000
1162#define AR5K_BEACON_TIM_S 16
1163#define AR5K_BEACON_ENABLE 0x00800000
1164#define AR5K_BEACON_RESET_TSF 0x01000000
1165
1166/*
1167 * CFP period register
1168 */
1169#define AR5K_CFP_PERIOD_5210 0x8028
1170#define AR5K_CFP_PERIOD_5211 0x8024
1171#define AR5K_CFP_PERIOD (ah->ah_version == AR5K_AR5210 ? \
1172 AR5K_CFP_PERIOD_5210 : AR5K_CFP_PERIOD_5211)
1173
1174/*
1175 * Next beacon time register
1176 */
1177#define AR5K_TIMER0_5210 0x802c
1178#define AR5K_TIMER0_5211 0x8028
1179#define AR5K_TIMER0 (ah->ah_version == AR5K_AR5210 ? \
1180 AR5K_TIMER0_5210 : AR5K_TIMER0_5211)
1181
1182/*
1183 * Next DMA beacon alert register
1184 */
1185#define AR5K_TIMER1_5210 0x8030
1186#define AR5K_TIMER1_5211 0x802c
1187#define AR5K_TIMER1 (ah->ah_version == AR5K_AR5210 ? \
1188 AR5K_TIMER1_5210 : AR5K_TIMER1_5211)
1189
1190/*
1191 * Next software beacon alert register
1192 */
1193#define AR5K_TIMER2_5210 0x8034
1194#define AR5K_TIMER2_5211 0x8030
1195#define AR5K_TIMER2 (ah->ah_version == AR5K_AR5210 ? \
1196 AR5K_TIMER2_5210 : AR5K_TIMER2_5211)
1197
1198/*
1199 * Next ATIM window time register
1200 */
1201#define AR5K_TIMER3_5210 0x8038
1202#define AR5K_TIMER3_5211 0x8034
1203#define AR5K_TIMER3 (ah->ah_version == AR5K_AR5210 ? \
1204 AR5K_TIMER3_5210 : AR5K_TIMER3_5211)
1205
1206
1207/*
1208 * 5210 First inter frame spacing register (IFS)
1209 */
1210#define AR5K_IFS0 0x8040
1211#define AR5K_IFS0_SIFS 0x000007ff
1212#define AR5K_IFS0_SIFS_S 0
1213#define AR5K_IFS0_DIFS 0x007ff800
1214#define AR5K_IFS0_DIFS_S 11
1215
1216/*
1217 * 5210 Second inter frame spacing register (IFS)
1218 */
1219#define AR5K_IFS1 0x8044
1220#define AR5K_IFS1_PIFS 0x00000fff
1221#define AR5K_IFS1_PIFS_S 0
1222#define AR5K_IFS1_EIFS 0x03fff000
1223#define AR5K_IFS1_EIFS_S 12
1224#define AR5K_IFS1_CS_EN 0x04000000
1225
1226
1227/*
1228 * CFP duration register
1229 */
1230#define AR5K_CFP_DUR_5210 0x8048
1231#define AR5K_CFP_DUR_5211 0x8038
1232#define AR5K_CFP_DUR (ah->ah_version == AR5K_AR5210 ? \
1233 AR5K_CFP_DUR_5210 : AR5K_CFP_DUR_5211)
1234
1235/*
1236 * Receive filter register
1237 * TODO: Get these out of ar5xxx.h on ath5k
1238 */
1239#define AR5K_RX_FILTER_5210 0x804c /* Register Address [5210] */
1240#define AR5K_RX_FILTER_5211 0x803c /* Register Address [5211+] */
1241#define AR5K_RX_FILTER (ah->ah_version == AR5K_AR5210 ? \
1242 AR5K_RX_FILTER_5210 : AR5K_RX_FILTER_5211)
1243#define AR5K_RX_FILTER_UCAST 0x00000001 /* Don't filter unicast frames */
1244#define AR5K_RX_FILTER_MCAST 0x00000002 /* Don't filter multicast frames */
1245#define AR5K_RX_FILTER_BCAST 0x00000004 /* Don't filter broadcast frames */
1246#define AR5K_RX_FILTER_CONTROL 0x00000008 /* Don't filter control frames */
1247#define AR5K_RX_FILTER_BEACON 0x00000010 /* Don't filter beacon frames */
1248#define AR5K_RX_FILTER_PROM 0x00000020 /* Set promiscuous mode */
1249#define AR5K_RX_FILTER_XRPOLL 0x00000040 /* Don't filter XR poll frame [5212+] */
1250#define AR5K_RX_FILTER_PROBEREQ 0x00000080 /* Don't filter probe requests [5212+] */
1251#define AR5K_RX_FILTER_PHYERR_5212 0x00000100 /* Don't filter phy errors [5212+] */
1252#define AR5K_RX_FILTER_RADARERR_5212 0x00000200 /* Don't filter phy radar errors [5212+] */
1253#define AR5K_RX_FILTER_PHYERR_5211 0x00000040 /* [5211] */
1254#define AR5K_RX_FILTER_RADARERR_5211 0x00000080 /* [5211] */
1255#define AR5K_RX_FILTER_PHYERR \
1256 ((ah->ah_version == AR5K_AR5211 ? \
1257 AR5K_RX_FILTER_PHYERR_5211 : AR5K_RX_FILTER_PHYERR_5212))
1258#define AR5K_RX_FILTER_RADARERR \
1259 ((ah->ah_version == AR5K_AR5211 ? \
1260 AR5K_RX_FILTER_RADARERR_5211 : AR5K_RX_FILTER_RADARERR_5212))
1261
1262/*
1263 * Multicast filter register (lower 32 bits)
1264 */
1265#define AR5K_MCAST_FILTER0_5210 0x8050
1266#define AR5K_MCAST_FILTER0_5211 0x8040
1267#define AR5K_MCAST_FILTER0 (ah->ah_version == AR5K_AR5210 ? \
1268 AR5K_MCAST_FILTER0_5210 : AR5K_MCAST_FILTER0_5211)
1269
1270/*
1271 * Multicast filter register (higher 16 bits)
1272 */
1273#define AR5K_MCAST_FILTER1_5210 0x8054
1274#define AR5K_MCAST_FILTER1_5211 0x8044
1275#define AR5K_MCAST_FILTER1 (ah->ah_version == AR5K_AR5210 ? \
1276 AR5K_MCAST_FILTER1_5210 : AR5K_MCAST_FILTER1_5211)
1277
1278
1279/*
1280 * Transmit mask register (lower 32 bits) [5210]
1281 */
1282#define AR5K_TX_MASK0 0x8058
1283
1284/*
1285 * Transmit mask register (higher 16 bits) [5210]
1286 */
1287#define AR5K_TX_MASK1 0x805c
1288
1289/*
1290 * Clear transmit mask [5210]
1291 */
1292#define AR5K_CLR_TMASK 0x8060
1293
1294/*
1295 * Trigger level register (before transmission) [5210]
1296 */
1297#define AR5K_TRIG_LVL 0x8064
1298
1299
1300/*
1301 * PCU control register
1302 *
1303 * Only DIS_RX is used in the code, the rest i guess are
1304 * for tweaking/diagnostics.
1305 */
1306#define AR5K_DIAG_SW_5210 0x8068 /* Register Address [5210] */
1307#define AR5K_DIAG_SW_5211 0x8048 /* Register Address [5211+] */
1308#define AR5K_DIAG_SW (ah->ah_version == AR5K_AR5210 ? \
1309 AR5K_DIAG_SW_5210 : AR5K_DIAG_SW_5211)
1310#define AR5K_DIAG_SW_DIS_WEP_ACK 0x00000001
1311#define AR5K_DIAG_SW_DIS_ACK 0x00000002 /* Disable ACKs (?) */
1312#define AR5K_DIAG_SW_DIS_CTS 0x00000004 /* Disable CTSs (?) */
1313#define AR5K_DIAG_SW_DIS_ENC 0x00000008 /* Disable encryption (?) */
1314#define AR5K_DIAG_SW_DIS_DEC 0x00000010 /* Disable decryption (?) */
1315#define AR5K_DIAG_SW_DIS_TX 0x00000020 /* Disable transmit [5210] */
1316#define AR5K_DIAG_SW_DIS_RX_5210 0x00000040 /* Disable recieve */
1317#define AR5K_DIAG_SW_DIS_RX_5211 0x00000020
1318#define AR5K_DIAG_SW_DIS_RX (ah->ah_version == AR5K_AR5210 ? \
1319 AR5K_DIAG_SW_DIS_RX_5210 : AR5K_DIAG_SW_DIS_RX_5211)
1320#define AR5K_DIAG_SW_LOOP_BACK_5210 0x00000080 /* Loopback (i guess it goes with DIS_TX) [5210] */
1321#define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040
1322#define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \
1323 AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211)
1324#define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100
1325#define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080
1326#define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \
1327 AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211)
1328#define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200
1329#define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100
1330#define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \
1331 AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211)
1332#define AR5K_DIAG_SW_EN_SCRAM_SEED_5211 0x00000200 /* Scrambler seed (?) */
1333#define AR5K_DIAG_SW_EN_SCRAM_SEED_5210 0x00000400
1334#define AR5K_DIAG_SW_EN_SCRAM_SEED (ah->ah_version == AR5K_AR5210 ? \
1335 AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211)
1336#define AR5K_DIAG_SW_ECO_ENABLE 0x00000400 /* [5211+] */
1337#define AR5K_DIAG_SW_SCVRAM_SEED 0x0003f800 /* [5210] */
1338#define AR5K_DIAG_SW_SCRAM_SEED_M 0x0001fc00 /* Scrambler seed mask (?) */
1339#define AR5K_DIAG_SW_SCRAM_SEED_S 10
1340#define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */
1341#define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000
1342#define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000
1343#define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \
1344 AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211)
1345#define AR5K_DIAG_SW_OBSPT_M 0x000c0000
1346#define AR5K_DIAG_SW_OBSPT_S 18
1347
1348/*
1349 * TSF (clock) register (lower 32 bits)
1350 */
1351#define AR5K_TSF_L32_5210 0x806c
1352#define AR5K_TSF_L32_5211 0x804c
1353#define AR5K_TSF_L32 (ah->ah_version == AR5K_AR5210 ? \
1354 AR5K_TSF_L32_5210 : AR5K_TSF_L32_5211)
1355
1356/*
1357 * TSF (clock) register (higher 32 bits)
1358 */
1359#define AR5K_TSF_U32_5210 0x8070
1360#define AR5K_TSF_U32_5211 0x8050
1361#define AR5K_TSF_U32 (ah->ah_version == AR5K_AR5210 ? \
1362 AR5K_TSF_U32_5210 : AR5K_TSF_U32_5211)
1363
1364/*
1365 * Last beacon timestamp register
1366 */
1367#define AR5K_LAST_TSTP 0x8080
1368
1369/*
1370 * ADDAC test register [5211+]
1371 */
1372#define AR5K_ADDAC_TEST 0x8054
1373#define AR5K_ADDAC_TEST_TXCONT 0x00000001
1374
1375/*
1376 * Default antenna register [5211+]
1377 */
1378#define AR5K_DEFAULT_ANTENNA 0x8058
1379
1380
1381
1382/*
1383 * Retry count register [5210]
1384 */
1385#define AR5K_RETRY_CNT 0x8084 /* Register Address [5210] */
1386#define AR5K_RETRY_CNT_SSH 0x0000003f /* Station short retry count (?) */
1387#define AR5K_RETRY_CNT_SLG 0x00000fc0 /* Station long retry count (?) */
1388
1389/*
1390 * Back-off status register [5210]
1391 */
1392#define AR5K_BACKOFF 0x8088 /* Register Address [5210] */
1393#define AR5K_BACKOFF_CW 0x000003ff /* Backoff Contention Window (?) */
1394#define AR5K_BACKOFF_CNT 0x03ff0000 /* Backoff count (?) */
1395
1396
1397
1398/*
1399 * NAV register (current)
1400 */
1401#define AR5K_NAV_5210 0x808c
1402#define AR5K_NAV_5211 0x8084
1403#define AR5K_NAV (ah->ah_version == AR5K_AR5210 ? \
1404 AR5K_NAV_5210 : AR5K_NAV_5211)
1405
1406/*
1407 * RTS success register
1408 */
1409#define AR5K_RTS_OK_5210 0x8090
1410#define AR5K_RTS_OK_5211 0x8088
1411#define AR5K_RTS_OK (ah->ah_version == AR5K_AR5210 ? \
1412 AR5K_RTS_OK_5210 : AR5K_RTS_OK_5211)
1413
1414/*
1415 * RTS failure register
1416 */
1417#define AR5K_RTS_FAIL_5210 0x8094
1418#define AR5K_RTS_FAIL_5211 0x808c
1419#define AR5K_RTS_FAIL (ah->ah_version == AR5K_AR5210 ? \
1420 AR5K_RTS_FAIL_5210 : AR5K_RTS_FAIL_5211)
1421
1422/*
1423 * ACK failure register
1424 */
1425#define AR5K_ACK_FAIL_5210 0x8098
1426#define AR5K_ACK_FAIL_5211 0x8090
1427#define AR5K_ACK_FAIL (ah->ah_version == AR5K_AR5210 ? \
1428 AR5K_ACK_FAIL_5210 : AR5K_ACK_FAIL_5211)
1429
1430/*
1431 * FCS failure register
1432 */
1433#define AR5K_FCS_FAIL_5210 0x809c
1434#define AR5K_FCS_FAIL_5211 0x8094
1435#define AR5K_FCS_FAIL (ah->ah_version == AR5K_AR5210 ? \
1436 AR5K_FCS_FAIL_5210 : AR5K_FCS_FAIL_5211)
1437
1438/*
1439 * Beacon count register
1440 */
1441#define AR5K_BEACON_CNT_5210 0x80a0
1442#define AR5K_BEACON_CNT_5211 0x8098
1443#define AR5K_BEACON_CNT (ah->ah_version == AR5K_AR5210 ? \
1444 AR5K_BEACON_CNT_5210 : AR5K_BEACON_CNT_5211)
1445
1446
1447/*===5212 Specific PCU registers===*/
1448
1449/*
1450 * XR (eXtended Range) mode register
1451 */
1452#define AR5K_XRMODE 0x80c0
1453#define AR5K_XRMODE_POLL_TYPE_M 0x0000003f
1454#define AR5K_XRMODE_POLL_TYPE_S 0
1455#define AR5K_XRMODE_POLL_SUBTYPE_M 0x0000003c
1456#define AR5K_XRMODE_POLL_SUBTYPE_S 2
1457#define AR5K_XRMODE_POLL_WAIT_ALL 0x00000080
1458#define AR5K_XRMODE_SIFS_DELAY 0x000fff00
1459#define AR5K_XRMODE_FRAME_HOLD_M 0xfff00000
1460#define AR5K_XRMODE_FRAME_HOLD_S 20
1461
1462/*
1463 * XR delay register
1464 */
1465#define AR5K_XRDELAY 0x80c4
1466#define AR5K_XRDELAY_SLOT_DELAY_M 0x0000ffff
1467#define AR5K_XRDELAY_SLOT_DELAY_S 0
1468#define AR5K_XRDELAY_CHIRP_DELAY_M 0xffff0000
1469#define AR5K_XRDELAY_CHIRP_DELAY_S 16
1470
1471/*
1472 * XR timeout register
1473 */
1474#define AR5K_XRTIMEOUT 0x80c8
1475#define AR5K_XRTIMEOUT_CHIRP_M 0x0000ffff
1476#define AR5K_XRTIMEOUT_CHIRP_S 0
1477#define AR5K_XRTIMEOUT_POLL_M 0xffff0000
1478#define AR5K_XRTIMEOUT_POLL_S 16
1479
1480/*
1481 * XR chirp register
1482 */
1483#define AR5K_XRCHIRP 0x80cc
1484#define AR5K_XRCHIRP_SEND 0x00000001
1485#define AR5K_XRCHIRP_GAP 0xffff0000
1486
1487/*
1488 * XR stomp register
1489 */
1490#define AR5K_XRSTOMP 0x80d0
1491#define AR5K_XRSTOMP_TX 0x00000001
1492#define AR5K_XRSTOMP_RX_ABORT 0x00000002
1493#define AR5K_XRSTOMP_RSSI_THRES 0x0000ff00
1494
1495/*
1496 * First enhanced sleep register
1497 */
1498#define AR5K_SLEEP0 0x80d4
1499#define AR5K_SLEEP0_NEXT_DTIM 0x0007ffff
1500#define AR5K_SLEEP0_NEXT_DTIM_S 0
1501#define AR5K_SLEEP0_ASSUME_DTIM 0x00080000
1502#define AR5K_SLEEP0_ENH_SLEEP_EN 0x00100000
1503#define AR5K_SLEEP0_CABTO 0xff000000
1504#define AR5K_SLEEP0_CABTO_S 24
1505
1506/*
1507 * Second enhanced sleep register
1508 */
1509#define AR5K_SLEEP1 0x80d8
1510#define AR5K_SLEEP1_NEXT_TIM 0x0007ffff
1511#define AR5K_SLEEP1_NEXT_TIM_S 0
1512#define AR5K_SLEEP1_BEACON_TO 0xff000000
1513#define AR5K_SLEEP1_BEACON_TO_S 24
1514
1515/*
1516 * Third enhanced sleep register
1517 */
1518#define AR5K_SLEEP2 0x80dc
1519#define AR5K_SLEEP2_TIM_PER 0x0000ffff
1520#define AR5K_SLEEP2_TIM_PER_S 0
1521#define AR5K_SLEEP2_DTIM_PER 0xffff0000
1522#define AR5K_SLEEP2_DTIM_PER_S 16
1523
1524/*
1525 * BSSID mask registers
1526 */
1527#define AR5K_BSS_IDM0 0x80e0
1528#define AR5K_BSS_IDM1 0x80e4
1529
1530/*
1531 * TX power control (TPC) register
1532 */
1533#define AR5K_TXPC 0x80e8
1534#define AR5K_TXPC_ACK_M 0x0000003f
1535#define AR5K_TXPC_ACK_S 0
1536#define AR5K_TXPC_CTS_M 0x00003f00
1537#define AR5K_TXPC_CTS_S 8
1538#define AR5K_TXPC_CHIRP_M 0x003f0000
1539#define AR5K_TXPC_CHIRP_S 22
1540
1541/*
1542 * Profile count registers
1543 */
1544#define AR5K_PROFCNT_TX 0x80ec
1545#define AR5K_PROFCNT_RX 0x80f0
1546#define AR5K_PROFCNT_RXCLR 0x80f4
1547#define AR5K_PROFCNT_CYCLE 0x80f8
1548
1549/*
1550 * TSF parameter register
1551 */
1552#define AR5K_TSF_PARM 0x8104
1553#define AR5K_TSF_PARM_INC_M 0x000000ff
1554#define AR5K_TSF_PARM_INC_S 0
1555
1556/*
1557 * PHY error filter register
1558 */
1559#define AR5K_PHY_ERR_FIL 0x810c
1560#define AR5K_PHY_ERR_FIL_RADAR 0x00000020
1561#define AR5K_PHY_ERR_FIL_OFDM 0x00020000
1562#define AR5K_PHY_ERR_FIL_CCK 0x02000000
1563
1564/*
1565 * Rate duration register
1566 */
1567#define AR5K_RATE_DUR_BASE 0x8700
1568#define AR5K_RATE_DUR(_n) (AR5K_RATE_DUR_BASE + ((_n) << 2))
1569
1570/*===5212 end===*/
1571
1572/*
1573 * Key table (WEP) register
1574 */
1575#define AR5K_KEYTABLE_0_5210 0x9000
1576#define AR5K_KEYTABLE_0_5211 0x8800
1577#define AR5K_KEYTABLE_5210(_n) (AR5K_KEYTABLE_0_5210 + ((_n) << 5))
1578#define AR5K_KEYTABLE_5211(_n) (AR5K_KEYTABLE_0_5211 + ((_n) << 5))
1579#define AR5K_KEYTABLE(_n) (ah->ah_version == AR5K_AR5210 ? \
1580 AR5K_KEYTABLE_5210(_n) : AR5K_KEYTABLE_5211(_n))
1581#define AR5K_KEYTABLE_OFF(_n, x) (AR5K_KEYTABLE(_n) + (x << 2))
1582#define AR5K_KEYTABLE_TYPE(_n) AR5K_KEYTABLE_OFF(_n, 5)
1583#define AR5K_KEYTABLE_TYPE_40 0x00000000
1584#define AR5K_KEYTABLE_TYPE_104 0x00000001
1585#define AR5K_KEYTABLE_TYPE_128 0x00000003
1586#define AR5K_KEYTABLE_TYPE_TKIP 0x00000004 /* [5212+] */
1587#define AR5K_KEYTABLE_TYPE_AES 0x00000005 /* [5211+] */
1588#define AR5K_KEYTABLE_TYPE_CCM 0x00000006 /* [5212+] */
1589#define AR5K_KEYTABLE_TYPE_NULL 0x00000007 /* [5211+] */
1590#define AR5K_KEYTABLE_ANTENNA 0x00000008 /* [5212+] */
1591#define AR5K_KEYTABLE_MAC0(_n) AR5K_KEYTABLE_OFF(_n, 6)
1592#define AR5K_KEYTABLE_MAC1(_n) AR5K_KEYTABLE_OFF(_n, 7)
1593#define AR5K_KEYTABLE_VALID 0x00008000
1594
1595/* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit
1596 * WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit
1597 * WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit
1598 *
1599 * Some vendors have introduced bigger WEP keys to address
1600 * security vulnerabilities in WEP. This includes:
1601 *
1602 * WEP 232-bit = 232-bit entered key + 24 bit IV = 256-bit
1603 *
1604 * We can expand this if we find ar5k Atheros cards with a larger
1605 * key table size.
1606 */
1607#define AR5K_KEYTABLE_SIZE_5210 64
1608#define AR5K_KEYTABLE_SIZE_5211 128
1609#define AR5K_KEYTABLE_SIZE (ah->ah_version == AR5K_AR5210 ? \
1610 AR5K_KEYTABLE_SIZE_5210 : AR5K_KEYTABLE_SIZE_5211)
1611
1612
1613/*===PHY REGISTERS===*/
1614
1615/*
1616 * PHY register
1617 */
1618#define AR5K_PHY_BASE 0x9800
1619#define AR5K_PHY(_n) (AR5K_PHY_BASE + ((_n) << 2))
1620#define AR5K_PHY_SHIFT_2GHZ 0x00004007
1621#define AR5K_PHY_SHIFT_5GHZ 0x00000007
1622
1623/*
1624 * PHY frame control register [5110] /turbo mode register [5111+]
1625 *
1626 * There is another frame control register for [5111+]
1627 * at address 0x9944 (see below) but the 2 first flags
1628 * are common here between 5110 frame control register
1629 * and [5111+] turbo mode register, so this also works as
1630 * a "turbo mode register" for 5110. We treat this one as
1631 * a frame control register for 5110 below.
1632 */
1633#define AR5K_PHY_TURBO 0x9804
1634#define AR5K_PHY_TURBO_MODE 0x00000001
1635#define AR5K_PHY_TURBO_SHORT 0x00000002
1636
1637/*
1638 * PHY agility command register
1639 */
1640#define AR5K_PHY_AGC 0x9808
1641#define AR5K_PHY_AGC_DISABLE 0x08000000
1642
1643/*
1644 * PHY timing register [5112+]
1645 */
1646#define AR5K_PHY_TIMING_3 0x9814
1647#define AR5K_PHY_TIMING_3_DSC_MAN 0xfffe0000
1648#define AR5K_PHY_TIMING_3_DSC_MAN_S 17
1649#define AR5K_PHY_TIMING_3_DSC_EXP 0x0001e000
1650#define AR5K_PHY_TIMING_3_DSC_EXP_S 13
1651
1652/*
1653 * PHY chip revision register
1654 */
1655#define AR5K_PHY_CHIP_ID 0x9818
1656
1657/*
1658 * PHY activation register
1659 */
1660#define AR5K_PHY_ACT 0x981c
1661#define AR5K_PHY_ACT_ENABLE 0x00000001
1662#define AR5K_PHY_ACT_DISABLE 0x00000002
1663
1664/*
1665 * PHY signal register
1666 */
1667#define AR5K_PHY_SIG 0x9858
1668#define AR5K_PHY_SIG_FIRSTEP 0x0003f000
1669#define AR5K_PHY_SIG_FIRSTEP_S 12
1670#define AR5K_PHY_SIG_FIRPWR 0x03fc0000
1671#define AR5K_PHY_SIG_FIRPWR_S 18
1672
1673/*
1674 * PHY coarse agility control register
1675 */
1676#define AR5K_PHY_AGCCOARSE 0x985c
1677#define AR5K_PHY_AGCCOARSE_LO 0x00007f80
1678#define AR5K_PHY_AGCCOARSE_LO_S 7
1679#define AR5K_PHY_AGCCOARSE_HI 0x003f8000
1680#define AR5K_PHY_AGCCOARSE_HI_S 15
1681
1682/*
1683 * PHY agility control register
1684 */
1685#define AR5K_PHY_AGCCTL 0x9860 /* Register address */
1686#define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */
1687#define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */
1688
1689/*
1690 * PHY noise floor status register
1691 */
1692#define AR5K_PHY_NF 0x9864
1693#define AR5K_PHY_NF_M 0x000001ff
1694#define AR5K_PHY_NF_ACTIVE 0x00000100
1695#define AR5K_PHY_NF_RVAL(_n) (((_n) >> 19) & AR5K_PHY_NF_M)
1696#define AR5K_PHY_NF_AVAL(_n) (-((_n) ^ AR5K_PHY_NF_M) + 1)
1697#define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9))
1698
1699/*
1700 * PHY ADC saturation register [5110]
1701 */
1702#define AR5K_PHY_ADCSAT 0x9868
1703#define AR5K_PHY_ADCSAT_ICNT 0x0001f800
1704#define AR5K_PHY_ADCSAT_ICNT_S 11
1705#define AR5K_PHY_ADCSAT_THR 0x000007e0
1706#define AR5K_PHY_ADCSAT_THR_S 5
1707
1708/*
1709 * PHY sleep registers [5112+]
1710 */
1711#define AR5K_PHY_SCR 0x9870
1712#define AR5K_PHY_SCR_32MHZ 0x0000001f
1713#define AR5K_PHY_SLMT 0x9874
1714#define AR5K_PHY_SLMT_32MHZ 0x0000007f
1715#define AR5K_PHY_SCAL 0x9878
1716#define AR5K_PHY_SCAL_32MHZ 0x0000000e
1717
1718/*
1719 * PHY PLL (Phase Locked Loop) control register
1720 */
1721#define AR5K_PHY_PLL 0x987c
1722#define AR5K_PHY_PLL_20MHZ 0x13 /* For half rate (?) [5111+] */
1723#define AR5K_PHY_PLL_40MHZ_5211 0x18 /* For 802.11a */
1724#define AR5K_PHY_PLL_40MHZ_5212 0x000000aa
1725#define AR5K_PHY_PLL_40MHZ (ah->ah_version == AR5K_AR5211 ? \
1726 AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212)
1727#define AR5K_PHY_PLL_44MHZ_5211 0x19 /* For 802.11b/g */
1728#define AR5K_PHY_PLL_44MHZ_5212 0x000000ab
1729#define AR5K_PHY_PLL_44MHZ (ah->ah_version == AR5K_AR5211 ? \
1730 AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212)
1731#define AR5K_PHY_PLL_RF5111 0x00000000
1732#define AR5K_PHY_PLL_RF5112 0x00000040
1733
1734/*
1735 * RF Buffer register
1736 *
1737 * There are some special control registers on the RF chip
1738 * that hold various operation settings related mostly to
1739 * the analog parts (channel, gain adjustment etc).
1740 *
1741 * We don't write on those registers directly but
1742 * we send a data packet on the buffer register and
1743 * then write on another special register to notify hw
1744 * to apply the settings. This is done so that control registers
1745 * can be dynamicaly programmed during operation and the settings
1746 * are applied faster on the hw.
1747 *
1748 * We sent such data packets during rf initialization and channel change
1749 * through ath5k_hw_rf*_rfregs and ath5k_hw_rf*_channel functions.
1750 *
1751 * The data packets we send during initializadion are inside ath5k_ini_rf
1752 * struct (see ath5k_hw.h) and each one is related to an "rf register bank".
1753 * We use *rfregs functions to modify them acording to current operation
1754 * mode and eeprom values and pass them all together to the chip.
1755 *
1756 * It's obvious from the code that 0x989c is the buffer register but
1757 * for the other special registers that we write to after sending each
1758 * packet, i have no idea. So i'll name them BUFFER_CONTROL_X registers
1759 * for now. It's interesting that they are also used for some other operations.
1760 *
1761 * Also check out hw.h and U.S. Patent 6677779 B1 (about buffer
1762 * registers and control registers):
1763 *
1764 * http://www.google.com/patents?id=qNURAAAAEBAJ
1765 */
1766
1767#define AR5K_RF_BUFFER 0x989c
1768#define AR5K_RF_BUFFER_CONTROL_0 0x98c0 /* Channel on 5110 */
1769#define AR5K_RF_BUFFER_CONTROL_1 0x98c4 /* Bank 7 on 5112 */
1770#define AR5K_RF_BUFFER_CONTROL_2 0x98cc /* Bank 7 on 5111 */
1771
1772#define AR5K_RF_BUFFER_CONTROL_3 0x98d0 /* Bank 2 on 5112 */
1773 /* Channel set on 5111 */
1774 /* Used to read radio revision*/
1775
1776#define AR5K_RF_BUFFER_CONTROL_4 0x98d4 /* RF Stage register on 5110 */
1777 /* Bank 0,1,2,6 on 5111 */
1778 /* Bank 1 on 5112 */
1779 /* Used during activation on 5111 */
1780
1781#define AR5K_RF_BUFFER_CONTROL_5 0x98d8 /* Bank 3 on 5111 */
1782 /* Used during activation on 5111 */
1783 /* Channel on 5112 */
1784 /* Bank 6 on 5112 */
1785
1786#define AR5K_RF_BUFFER_CONTROL_6 0x98dc /* Bank 3 on 5112 */
1787
1788/*
1789 * PHY RF stage register [5210]
1790 */
1791#define AR5K_PHY_RFSTG 0x98d4
1792#define AR5K_PHY_RFSTG_DISABLE 0x00000021
1793
1794/*
1795 * PHY receiver delay register [5111+]
1796 */
1797#define AR5K_PHY_RX_DELAY 0x9914
1798#define AR5K_PHY_RX_DELAY_M 0x00003fff
1799
1800/*
1801 * PHY timing I(nphase) Q(adrature) control register [5111+]
1802 */
1803#define AR5K_PHY_IQ 0x9920 /* Register address */
1804#define AR5K_PHY_IQ_CORR_Q_Q_COFF 0x0000001f /* Mask for q correction info */
1805#define AR5K_PHY_IQ_CORR_Q_I_COFF 0x000007e0 /* Mask for i correction info */
1806#define AR5K_PHY_IQ_CORR_Q_I_COFF_S 5
1807#define AR5K_PHY_IQ_CORR_ENABLE 0x00000800 /* Enable i/q correction */
1808#define AR5K_PHY_IQ_CAL_NUM_LOG_MAX 0x0000f000
1809#define AR5K_PHY_IQ_CAL_NUM_LOG_MAX_S 12
1810#define AR5K_PHY_IQ_RUN 0x00010000 /* Run i/q calibration */
1811
1812
1813/*
1814 * PHY PAPD probe register [5111+ (?)]
1815 * Is this only present in 5212 ?
1816 * Because it's always 0 in 5211 initialization code
1817 */
1818#define AR5K_PHY_PAPD_PROBE 0x9930
1819#define AR5K_PHY_PAPD_PROBE_TXPOWER 0x00007e00
1820#define AR5K_PHY_PAPD_PROBE_TXPOWER_S 9
1821#define AR5K_PHY_PAPD_PROBE_TX_NEXT 0x00008000
1822#define AR5K_PHY_PAPD_PROBE_TYPE 0x01800000 /* [5112+] */
1823#define AR5K_PHY_PAPD_PROBE_TYPE_S 23
1824#define AR5K_PHY_PAPD_PROBE_TYPE_OFDM 0
1825#define AR5K_PHY_PAPD_PROBE_TYPE_XR 1
1826#define AR5K_PHY_PAPD_PROBE_TYPE_CCK 2
1827#define AR5K_PHY_PAPD_PROBE_GAINF 0xfe000000
1828#define AR5K_PHY_PAPD_PROBE_GAINF_S 25
1829#define AR5K_PHY_PAPD_PROBE_INI_5111 0x00004883 /* [5212+] */
1830#define AR5K_PHY_PAPD_PROBE_INI_5112 0x00004882 /* [5212+] */
1831
1832
1833/*
1834 * PHY TX rate power registers [5112+]
1835 */
1836#define AR5K_PHY_TXPOWER_RATE1 0x9934
1837#define AR5K_PHY_TXPOWER_RATE2 0x9938
1838#define AR5K_PHY_TXPOWER_RATE_MAX 0x993c
1839#define AR5K_PHY_TXPOWER_RATE_MAX_TPC_ENABLE 0x00000040
1840#define AR5K_PHY_TXPOWER_RATE3 0xa234
1841#define AR5K_PHY_TXPOWER_RATE4 0xa238
1842
1843/*
1844 * PHY frame control register [5111+]
1845 */
1846#define AR5K_PHY_FRAME_CTL_5210 0x9804
1847#define AR5K_PHY_FRAME_CTL_5211 0x9944
1848#define AR5K_PHY_FRAME_CTL (ah->ah_version == AR5K_AR5210 ? \
1849 AR5K_PHY_FRAME_CTL_5210 : AR5K_PHY_FRAME_CTL_5211)
1850/*---[5111+]---*/
1851#define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038
1852#define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3
1853/*---[5110/5111]---*/
1854#define AR5K_PHY_FRAME_CTL_TIMING_ERR 0x01000000
1855#define AR5K_PHY_FRAME_CTL_PARITY_ERR 0x02000000
1856#define AR5K_PHY_FRAME_CTL_ILLRATE_ERR 0x04000000 /* illegal rate */
1857#define AR5K_PHY_FRAME_CTL_ILLLEN_ERR 0x08000000 /* illegal length */
1858#define AR5K_PHY_FRAME_CTL_SERVICE_ERR 0x20000000
1859#define AR5K_PHY_FRAME_CTL_TXURN_ERR 0x40000000 /* tx underrun */
1860#define AR5K_PHY_FRAME_CTL_INI AR5K_PHY_FRAME_CTL_SERVICE_ERR | \
1861 AR5K_PHY_FRAME_CTL_TXURN_ERR | \
1862 AR5K_PHY_FRAME_CTL_ILLLEN_ERR | \
1863 AR5K_PHY_FRAME_CTL_ILLRATE_ERR | \
1864 AR5K_PHY_FRAME_CTL_PARITY_ERR | \
1865 AR5K_PHY_FRAME_CTL_TIMING_ERR
1866
1867/*
1868 * PHY radar detection register [5111+]
1869 */
1870#define AR5K_PHY_RADAR 0x9954
1871
1872/* Radar enable ........ ........ ........ .......1 */
1873#define AR5K_PHY_RADAR_ENABLE 0x00000001
1874#define AR5K_PHY_RADAR_DISABLE 0x00000000
1875#define AR5K_PHY_RADAR_ENABLE_S 0
1876
1877/* This is the value found on the card .1.111.1 .1.1.... 111....1 1...1...
1878at power on. */
1879#define AR5K_PHY_RADAR_PWONDEF_AR5213 0x5d50e188
1880
1881/* This is the value found on the card .1.1.111 ..11...1 .1...1.1 1...11.1
1882after DFS is enabled */
1883#define AR5K_PHY_RADAR_ENABLED_AR5213 0x5731458d
1884
1885/* Finite Impulse Response (FIR) filter .1111111 ........ ........ ........
1886 * power out threshold.
1887 * 7-bits, standard power range {0..127} in 1/2 dBm units. */
1888#define AR5K_PHY_RADAR_FIRPWROUTTHR 0x7f000000
1889#define AR5K_PHY_RADAR_FIRPWROUTTHR_S 24
1890
1891/* Radar RSSI/SNR threshold. ........ 111111.. ........ ........
1892 * 6-bits, dBm range {0..63} in dBm units. */
1893#define AR5K_PHY_RADAR_RADARRSSITHR 0x00fc0000
1894#define AR5K_PHY_RADAR_RADARRSSITHR_S 18
1895
1896/* Pulse height threshold ........ ......11 1111.... ........
1897 * 6-bits, dBm range {0..63} in dBm units. */
1898#define AR5K_PHY_RADAR_PULSEHEIGHTTHR 0x0003f000
1899#define AR5K_PHY_RADAR_PULSEHEIGHTTHR_S 12
1900
1901/* Pulse RSSI/SNR threshold ........ ........ ....1111 11......
1902 * 6-bits, dBm range {0..63} in dBm units. */
1903#define AR5K_PHY_RADAR_PULSERSSITHR 0x00000fc0
1904#define AR5K_PHY_RADAR_PULSERSSITHR_S 6
1905
1906/* Inband threshold ........ ........ ........ ..11111.
1907 * 5-bits, units unknown {0..31} (? MHz ?) */
1908#define AR5K_PHY_RADAR_INBANDTHR 0x0000003e
1909#define AR5K_PHY_RADAR_INBANDTHR_S 1
1910
1911/*
1912 * PHY antenna switch table registers [5110]
1913 */
1914#define AR5K_PHY_ANT_SWITCH_TABLE_0 0x9960
1915#define AR5K_PHY_ANT_SWITCH_TABLE_1 0x9964
1916
1917/*
1918 * PHY clock sleep registers [5112+]
1919 */
1920#define AR5K_PHY_SCLOCK 0x99f0
1921#define AR5K_PHY_SCLOCK_32MHZ 0x0000000c
1922#define AR5K_PHY_SDELAY 0x99f4
1923#define AR5K_PHY_SDELAY_32MHZ 0x000000ff
1924#define AR5K_PHY_SPENDING 0x99f8
1925#define AR5K_PHY_SPENDING_RF5111 0x00000018
1926#define AR5K_PHY_SPENDING_RF5112 0x00000014
1927
1928/*
1929 * Misc PHY/radio registers [5110 - 5111]
1930 */
1931#define AR5K_BB_GAIN_BASE 0x9b00 /* BaseBand Amplifier Gain table base address */
1932#define AR5K_BB_GAIN(_n) (AR5K_BB_GAIN_BASE + ((_n) << 2))
1933#define AR5K_RF_GAIN_BASE 0x9a00 /* RF Amplrifier Gain table base address */
1934#define AR5K_RF_GAIN(_n) (AR5K_RF_GAIN_BASE + ((_n) << 2))
1935
1936/*
1937 * PHY timing IQ calibration result register [5111+]
1938 */
1939#define AR5K_PHY_IQRES_CAL_PWR_I 0x9c10 /* I (Inphase) power value */
1940#define AR5K_PHY_IQRES_CAL_PWR_Q 0x9c14 /* Q (Quadrature) power value */
1941#define AR5K_PHY_IQRES_CAL_CORR 0x9c18 /* I/Q Correlation */
1942
1943/*
1944 * PHY current RSSI register [5111+]
1945 */
1946#define AR5K_PHY_CURRENT_RSSI 0x9c1c
1947
1948/*
1949 * PHY PCDAC TX power table
1950 */
1951#define AR5K_PHY_PCDAC_TXPOWER_BASE_5211 0xa180
1952#define AR5K_PHY_PCDAC_TXPOWER_BASE_5413 0xa280
1953#define AR5K_PHY_PCDAC_TXPOWER_BASE (ah->ah_radio >= AR5K_RF5413 ? \
1954 AR5K_PHY_PCDAC_TXPOWER_BASE_5413 :\
1955 AR5K_PHY_PCDAC_TXPOWER_BASE_5211)
1956#define AR5K_PHY_PCDAC_TXPOWER(_n) (AR5K_PHY_PCDAC_TXPOWER_BASE + ((_n) << 2))
1957
1958/*
1959 * PHY mode register [5111+]
1960 */
1961#define AR5K_PHY_MODE 0x0a200 /* Register address */
1962#define AR5K_PHY_MODE_MOD 0x00000001 /* PHY Modulation mask*/
1963#define AR5K_PHY_MODE_MOD_OFDM 0
1964#define AR5K_PHY_MODE_MOD_CCK 1
1965#define AR5K_PHY_MODE_FREQ 0x00000002 /* Freq mode mask */
1966#define AR5K_PHY_MODE_FREQ_5GHZ 0
1967#define AR5K_PHY_MODE_FREQ_2GHZ 2
1968#define AR5K_PHY_MODE_MOD_DYN 0x00000004 /* Dynamic OFDM/CCK mode mask [5112+] */
1969#define AR5K_PHY_MODE_RAD 0x00000008 /* [5212+] */
1970#define AR5K_PHY_MODE_RAD_RF5111 0
1971#define AR5K_PHY_MODE_RAD_RF5112 8
1972#define AR5K_PHY_MODE_XR 0x00000010 /* [5112+] */
1973
1974/*
1975 * PHY CCK transmit control register [5111+ (?)]
1976 */
1977#define AR5K_PHY_CCKTXCTL 0xa204
1978#define AR5K_PHY_CCKTXCTL_WORLD 0x00000000
1979#define AR5K_PHY_CCKTXCTL_JAPAN 0x00000010
1980
1981/*
1982 * PHY 2GHz gain register [5111+]
1983 */
1984#define AR5K_PHY_GAIN_2GHZ 0xa20c
1985#define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000
1986#define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18
1987#define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c
diff --git a/drivers/net/wireless/ath5k/regdom.c b/drivers/net/wireless/ath5k/regdom.c
new file mode 100644
index 000000000000..e851957dacfd
--- /dev/null
+++ b/drivers/net/wireless/ath5k/regdom.c
@@ -0,0 +1,121 @@
1/*
2 * Copyright (c) 2004, 2005 Reyk Floeter <reyk@vantronix.net>
3 *
4 * Permission to use, copy, modify, and 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 * Basic regulation domain extensions for the IEEE 802.11 stack
19 */
20
21#include <linux/kernel.h>
22#include <linux/string.h>
23
24#include "regdom.h"
25
26static const struct ath5k_regdommap {
27 enum ath5k_regdom dmn;
28 enum ath5k_regdom dmn5;
29 enum ath5k_regdom dmn2;
30} r_map[] = {
31 { DMN_DEFAULT, DMN_DEBUG, DMN_DEBUG },
32 { DMN_NULL_WORLD, DMN_NULL, DMN_WORLD },
33 { DMN_NULL_ETSIB, DMN_NULL, DMN_ETSIB },
34 { DMN_NULL_ETSIC, DMN_NULL, DMN_ETSIC },
35 { DMN_FCC1_FCCA, DMN_FCC1, DMN_FCCA },
36 { DMN_FCC1_WORLD, DMN_FCC1, DMN_WORLD },
37 { DMN_FCC2_FCCA, DMN_FCC2, DMN_FCCA },
38 { DMN_FCC2_WORLD, DMN_FCC2, DMN_WORLD },
39 { DMN_FCC2_ETSIC, DMN_FCC2, DMN_ETSIC },
40 { DMN_FRANCE_NULL, DMN_ETSI3, DMN_ETSI3 },
41 { DMN_FCC3_FCCA, DMN_FCC3, DMN_WORLD },
42 { DMN_ETSI1_WORLD, DMN_ETSI1, DMN_WORLD },
43 { DMN_ETSI3_ETSIA, DMN_ETSI3, DMN_WORLD },
44 { DMN_ETSI2_WORLD, DMN_ETSI2, DMN_WORLD },
45 { DMN_ETSI3_WORLD, DMN_ETSI3, DMN_WORLD },
46 { DMN_ETSI4_WORLD, DMN_ETSI4, DMN_WORLD },
47 { DMN_ETSI4_ETSIC, DMN_ETSI4, DMN_ETSIC },
48 { DMN_ETSI5_WORLD, DMN_ETSI5, DMN_WORLD },
49 { DMN_ETSI6_WORLD, DMN_ETSI6, DMN_WORLD },
50 { DMN_ETSI_NULL, DMN_ETSI1, DMN_ETSI1 },
51 { DMN_MKK1_MKKA, DMN_MKK1, DMN_MKKA },
52 { DMN_MKK1_MKKB, DMN_MKK1, DMN_MKKA },
53 { DMN_APL4_WORLD, DMN_APL4, DMN_WORLD },
54 { DMN_MKK2_MKKA, DMN_MKK2, DMN_MKKA },
55 { DMN_APL_NULL, DMN_APL1, DMN_NULL },
56 { DMN_APL2_WORLD, DMN_APL2, DMN_WORLD },
57 { DMN_APL2_APLC, DMN_APL2, DMN_WORLD },
58 { DMN_APL3_WORLD, DMN_APL3, DMN_WORLD },
59 { DMN_MKK1_FCCA, DMN_MKK1, DMN_FCCA },
60 { DMN_APL2_APLD, DMN_APL2, DMN_APLD },
61 { DMN_MKK1_MKKA1, DMN_MKK1, DMN_MKKA },
62 { DMN_MKK1_MKKA2, DMN_MKK1, DMN_MKKA },
63 { DMN_APL1_WORLD, DMN_APL1, DMN_WORLD },
64 { DMN_APL1_FCCA, DMN_APL1, DMN_FCCA },
65 { DMN_APL1_APLA, DMN_APL1, DMN_WORLD },
66 { DMN_APL1_ETSIC, DMN_APL1, DMN_ETSIC },
67 { DMN_APL2_ETSIC, DMN_APL2, DMN_ETSIC },
68 { DMN_APL5_WORLD, DMN_APL5, DMN_WORLD },
69 { DMN_WOR0_WORLD, DMN_WORLD, DMN_WORLD },
70 { DMN_WOR1_WORLD, DMN_WORLD, DMN_WORLD },
71 { DMN_WOR2_WORLD, DMN_WORLD, DMN_WORLD },
72 { DMN_WOR3_WORLD, DMN_WORLD, DMN_WORLD },
73 { DMN_WOR4_WORLD, DMN_WORLD, DMN_WORLD },
74 { DMN_WOR5_ETSIC, DMN_WORLD, DMN_WORLD },
75 { DMN_WOR01_WORLD, DMN_WORLD, DMN_WORLD },
76 { DMN_WOR02_WORLD, DMN_WORLD, DMN_WORLD },
77 { DMN_EU1_WORLD, DMN_ETSI1, DMN_WORLD },
78 { DMN_WOR9_WORLD, DMN_WORLD, DMN_WORLD },
79 { DMN_WORA_WORLD, DMN_WORLD, DMN_WORLD },
80};
81
82enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom dmn, u16 mhz)
83{
84 unsigned int i;
85
86 for (i = 0; i < ARRAY_SIZE(r_map); i++) {
87 if (r_map[i].dmn == dmn) {
88 if (mhz >= 2000 && mhz <= 3000)
89 return r_map[i].dmn2;
90 if (mhz >= IEEE80211_CHANNELS_5GHZ_MIN &&
91 mhz <= IEEE80211_CHANNELS_5GHZ_MAX)
92 return r_map[i].dmn5;
93 }
94 }
95
96 return DMN_DEBUG;
97}
98
99u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee)
100{
101 u32 regdomain = (u32)ieee;
102
103 /*
104 * Use the default regulation domain if the value is empty
105 * or not supported by the net80211 regulation code.
106 */
107 if (ath5k_regdom2flag(regdomain, IEEE80211_CHANNELS_5GHZ_MIN) ==
108 DMN_DEBUG)
109 return (u16)AR5K_TUNE_REGDOMAIN;
110
111 /* It is supported, just return the value */
112 return regdomain;
113}
114
115enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain)
116{
117 enum ath5k_regdom ieee = (enum ath5k_regdom)regdomain;
118
119 return ieee;
120}
121
diff --git a/drivers/net/wireless/ath5k/regdom.h b/drivers/net/wireless/ath5k/regdom.h
new file mode 100644
index 000000000000..f7d3c66e594e
--- /dev/null
+++ b/drivers/net/wireless/ath5k/regdom.h
@@ -0,0 +1,500 @@
1/*
2 * Copyright (c) 2004, 2005 Reyk Floeter <reyk@openbsd.org>
3 *
4 * Permission to use, copy, modify, and 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 _IEEE80211_REGDOMAIN_H_
18#define _IEEE80211_REGDOMAIN_H_
19
20#include <linux/types.h>
21
22/* Default regulation domain if stored value EEPROM value is invalid */
23#define AR5K_TUNE_REGDOMAIN DMN_FCC2_FCCA /* Canada */
24#define AR5K_TUNE_CTRY CTRY_DEFAULT
25
26
27enum ath5k_regdom {
28 DMN_DEFAULT = 0x00,
29 DMN_NULL_WORLD = 0x03,
30 DMN_NULL_ETSIB = 0x07,
31 DMN_NULL_ETSIC = 0x08,
32 DMN_FCC1_FCCA = 0x10,
33 DMN_FCC1_WORLD = 0x11,
34 DMN_FCC2_FCCA = 0x20,
35 DMN_FCC2_WORLD = 0x21,
36 DMN_FCC2_ETSIC = 0x22,
37 DMN_FRANCE_NULL = 0x31,
38 DMN_FCC3_FCCA = 0x3A,
39 DMN_ETSI1_WORLD = 0x37,
40 DMN_ETSI3_ETSIA = 0x32,
41 DMN_ETSI2_WORLD = 0x35,
42 DMN_ETSI3_WORLD = 0x36,
43 DMN_ETSI4_WORLD = 0x30,
44 DMN_ETSI4_ETSIC = 0x38,
45 DMN_ETSI5_WORLD = 0x39,
46 DMN_ETSI6_WORLD = 0x34,
47 DMN_ETSI_NULL = 0x33,
48 DMN_MKK1_MKKA = 0x40,
49 DMN_MKK1_MKKB = 0x41,
50 DMN_APL4_WORLD = 0x42,
51 DMN_MKK2_MKKA = 0x43,
52 DMN_APL_NULL = 0x44,
53 DMN_APL2_WORLD = 0x45,
54 DMN_APL2_APLC = 0x46,
55 DMN_APL3_WORLD = 0x47,
56 DMN_MKK1_FCCA = 0x48,
57 DMN_APL2_APLD = 0x49,
58 DMN_MKK1_MKKA1 = 0x4A,
59 DMN_MKK1_MKKA2 = 0x4B,
60 DMN_APL1_WORLD = 0x52,
61 DMN_APL1_FCCA = 0x53,
62 DMN_APL1_APLA = 0x54,
63 DMN_APL1_ETSIC = 0x55,
64 DMN_APL2_ETSIC = 0x56,
65 DMN_APL5_WORLD = 0x58,
66 DMN_WOR0_WORLD = 0x60,
67 DMN_WOR1_WORLD = 0x61,
68 DMN_WOR2_WORLD = 0x62,
69 DMN_WOR3_WORLD = 0x63,
70 DMN_WOR4_WORLD = 0x64,
71 DMN_WOR5_ETSIC = 0x65,
72 DMN_WOR01_WORLD = 0x66,
73 DMN_WOR02_WORLD = 0x67,
74 DMN_EU1_WORLD = 0x68,
75 DMN_WOR9_WORLD = 0x69,
76 DMN_WORA_WORLD = 0x6A,
77
78 DMN_APL1 = 0xf0000001,
79 DMN_APL2 = 0xf0000002,
80 DMN_APL3 = 0xf0000004,
81 DMN_APL4 = 0xf0000008,
82 DMN_APL5 = 0xf0000010,
83 DMN_ETSI1 = 0xf0000020,
84 DMN_ETSI2 = 0xf0000040,
85 DMN_ETSI3 = 0xf0000080,
86 DMN_ETSI4 = 0xf0000100,
87 DMN_ETSI5 = 0xf0000200,
88 DMN_ETSI6 = 0xf0000400,
89 DMN_ETSIA = 0xf0000800,
90 DMN_ETSIB = 0xf0001000,
91 DMN_ETSIC = 0xf0002000,
92 DMN_FCC1 = 0xf0004000,
93 DMN_FCC2 = 0xf0008000,
94 DMN_FCC3 = 0xf0010000,
95 DMN_FCCA = 0xf0020000,
96 DMN_APLD = 0xf0040000,
97 DMN_MKK1 = 0xf0080000,
98 DMN_MKK2 = 0xf0100000,
99 DMN_MKKA = 0xf0200000,
100 DMN_NULL = 0xf0400000,
101 DMN_WORLD = 0xf0800000,
102 DMN_DEBUG = 0xf1000000 /* used for debugging */
103};
104
105#define IEEE80211_DMN(_d) ((_d) & ~0xf0000000)
106
107enum ath5k_countrycode {
108 CTRY_DEFAULT = 0, /* Default domain (NA) */
109 CTRY_ALBANIA = 8, /* Albania */
110 CTRY_ALGERIA = 12, /* Algeria */
111 CTRY_ARGENTINA = 32, /* Argentina */
112 CTRY_ARMENIA = 51, /* Armenia */
113 CTRY_AUSTRALIA = 36, /* Australia */
114 CTRY_AUSTRIA = 40, /* Austria */
115 CTRY_AZERBAIJAN = 31, /* Azerbaijan */
116 CTRY_BAHRAIN = 48, /* Bahrain */
117 CTRY_BELARUS = 112, /* Belarus */
118 CTRY_BELGIUM = 56, /* Belgium */
119 CTRY_BELIZE = 84, /* Belize */
120 CTRY_BOLIVIA = 68, /* Bolivia */
121 CTRY_BRAZIL = 76, /* Brazil */
122 CTRY_BRUNEI_DARUSSALAM = 96, /* Brunei Darussalam */
123 CTRY_BULGARIA = 100, /* Bulgaria */
124 CTRY_CANADA = 124, /* Canada */
125 CTRY_CHILE = 152, /* Chile */
126 CTRY_CHINA = 156, /* People's Republic of China */
127 CTRY_COLOMBIA = 170, /* Colombia */
128 CTRY_COSTA_RICA = 188, /* Costa Rica */
129 CTRY_CROATIA = 191, /* Croatia */
130 CTRY_CYPRUS = 196, /* Cyprus */
131 CTRY_CZECH = 203, /* Czech Republic */
132 CTRY_DENMARK = 208, /* Denmark */
133 CTRY_DOMINICAN_REPUBLIC = 214, /* Dominican Republic */
134 CTRY_ECUADOR = 218, /* Ecuador */
135 CTRY_EGYPT = 818, /* Egypt */
136 CTRY_EL_SALVADOR = 222, /* El Salvador */
137 CTRY_ESTONIA = 233, /* Estonia */
138 CTRY_FAEROE_ISLANDS = 234, /* Faeroe Islands */
139 CTRY_FINLAND = 246, /* Finland */
140 CTRY_FRANCE = 250, /* France */
141 CTRY_FRANCE2 = 255, /* France2 */
142 CTRY_GEORGIA = 268, /* Georgia */
143 CTRY_GERMANY = 276, /* Germany */
144 CTRY_GREECE = 300, /* Greece */
145 CTRY_GUATEMALA = 320, /* Guatemala */
146 CTRY_HONDURAS = 340, /* Honduras */
147 CTRY_HONG_KONG = 344, /* Hong Kong S.A.R., P.R.C. */
148 CTRY_HUNGARY = 348, /* Hungary */
149 CTRY_ICELAND = 352, /* Iceland */
150 CTRY_INDIA = 356, /* India */
151 CTRY_INDONESIA = 360, /* Indonesia */
152 CTRY_IRAN = 364, /* Iran */
153 CTRY_IRAQ = 368, /* Iraq */
154 CTRY_IRELAND = 372, /* Ireland */
155 CTRY_ISRAEL = 376, /* Israel */
156 CTRY_ITALY = 380, /* Italy */
157 CTRY_JAMAICA = 388, /* Jamaica */
158 CTRY_JAPAN = 392, /* Japan */
159 CTRY_JAPAN1 = 393, /* Japan (JP1) */
160 CTRY_JAPAN2 = 394, /* Japan (JP0) */
161 CTRY_JAPAN3 = 395, /* Japan (JP1-1) */
162 CTRY_JAPAN4 = 396, /* Japan (JE1) */
163 CTRY_JAPAN5 = 397, /* Japan (JE2) */
164 CTRY_JORDAN = 400, /* Jordan */
165 CTRY_KAZAKHSTAN = 398, /* Kazakhstan */
166 CTRY_KENYA = 404, /* Kenya */
167 CTRY_KOREA_NORTH = 408, /* North Korea */
168 CTRY_KOREA_ROC = 410, /* South Korea */
169 CTRY_KOREA_ROC2 = 411, /* South Korea */
170 CTRY_KUWAIT = 414, /* Kuwait */
171 CTRY_LATVIA = 428, /* Latvia */
172 CTRY_LEBANON = 422, /* Lebanon */
173 CTRY_LIBYA = 434, /* Libya */
174 CTRY_LIECHTENSTEIN = 438, /* Liechtenstein */
175 CTRY_LITHUANIA = 440, /* Lithuania */
176 CTRY_LUXEMBOURG = 442, /* Luxembourg */
177 CTRY_MACAU = 446, /* Macau */
178 CTRY_MACEDONIA = 807, /* Republic of Macedonia */
179 CTRY_MALAYSIA = 458, /* Malaysia */
180 CTRY_MEXICO = 484, /* Mexico */
181 CTRY_MONACO = 492, /* Principality of Monaco */
182 CTRY_MOROCCO = 504, /* Morocco */
183 CTRY_NETHERLANDS = 528, /* Netherlands */
184 CTRY_NEW_ZEALAND = 554, /* New Zealand */
185 CTRY_NICARAGUA = 558, /* Nicaragua */
186 CTRY_NORWAY = 578, /* Norway */
187 CTRY_OMAN = 512, /* Oman */
188 CTRY_PAKISTAN = 586, /* Islamic Republic of Pakistan */
189 CTRY_PANAMA = 591, /* Panama */
190 CTRY_PARAGUAY = 600, /* Paraguay */
191 CTRY_PERU = 604, /* Peru */
192 CTRY_PHILIPPINES = 608, /* Republic of the Philippines */
193 CTRY_POLAND = 616, /* Poland */
194 CTRY_PORTUGAL = 620, /* Portugal */
195 CTRY_PUERTO_RICO = 630, /* Puerto Rico */
196 CTRY_QATAR = 634, /* Qatar */
197 CTRY_ROMANIA = 642, /* Romania */
198 CTRY_RUSSIA = 643, /* Russia */
199 CTRY_SAUDI_ARABIA = 682, /* Saudi Arabia */
200 CTRY_SINGAPORE = 702, /* Singapore */
201 CTRY_SLOVAKIA = 703, /* Slovak Republic */
202 CTRY_SLOVENIA = 705, /* Slovenia */
203 CTRY_SOUTH_AFRICA = 710, /* South Africa */
204 CTRY_SPAIN = 724, /* Spain */
205 CTRY_SRI_LANKA = 728, /* Sri Lanka */
206 CTRY_SWEDEN = 752, /* Sweden */
207 CTRY_SWITZERLAND = 756, /* Switzerland */
208 CTRY_SYRIA = 760, /* Syria */
209 CTRY_TAIWAN = 158, /* Taiwan */
210 CTRY_THAILAND = 764, /* Thailand */
211 CTRY_TRINIDAD_Y_TOBAGO = 780, /* Trinidad y Tobago */
212 CTRY_TUNISIA = 788, /* Tunisia */
213 CTRY_TURKEY = 792, /* Turkey */
214 CTRY_UAE = 784, /* U.A.E. */
215 CTRY_UKRAINE = 804, /* Ukraine */
216 CTRY_UNITED_KINGDOM = 826, /* United Kingdom */
217 CTRY_UNITED_STATES = 840, /* United States */
218 CTRY_URUGUAY = 858, /* Uruguay */
219 CTRY_UZBEKISTAN = 860, /* Uzbekistan */
220 CTRY_VENEZUELA = 862, /* Venezuela */
221 CTRY_VIET_NAM = 704, /* Viet Nam */
222 CTRY_YEMEN = 887, /* Yemen */
223 CTRY_ZIMBABWE = 716, /* Zimbabwe */
224};
225
226#define IEEE80211_CHANNELS_2GHZ_MIN 2412 /* 2GHz channel 1 */
227#define IEEE80211_CHANNELS_2GHZ_MAX 2732 /* 2GHz channel 26 */
228#define IEEE80211_CHANNELS_5GHZ_MIN 5005 /* 5GHz channel 1 */
229#define IEEE80211_CHANNELS_5GHZ_MAX 6100 /* 5GHz channel 220 */
230
231struct ath5k_regchannel {
232 u16 chan;
233 enum ath5k_regdom domain;
234 u32 mode;
235};
236
237#define IEEE80211_CHANNELS_2GHZ { \
238/*2412*/ { 1, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
239/*2417*/ { 2, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
240/*2422*/ { 3, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
241/*2427*/ { 4, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
242/*2432*/ { 5, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
243/*2437*/ { 6, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
244/*2442*/ { 7, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
245/*2447*/ { 8, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
246/*2452*/ { 9, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
247/*2457*/ { 10, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
248/*2462*/ { 11, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
249/*2467*/ { 12, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
250/*2472*/ { 13, DMN_APLD, CHANNEL_CCK|CHANNEL_OFDM }, \
251 \
252/*2432*/ { 5, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM }, \
253/*2437*/ { 6, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \
254/*2442*/ { 7, DMN_ETSIB, CHANNEL_CCK|CHANNEL_OFDM }, \
255 \
256/*2412*/ { 1, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
257/*2417*/ { 2, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
258/*2422*/ { 3, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
259/*2427*/ { 4, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
260/*2432*/ { 5, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
261/*2437*/ { 6, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \
262/*2442*/ { 7, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
263/*2447*/ { 8, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
264/*2452*/ { 9, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
265/*2457*/ { 10, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
266/*2462*/ { 11, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
267/*2467*/ { 12, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
268/*2472*/ { 13, DMN_ETSIC, CHANNEL_CCK|CHANNEL_OFDM }, \
269 \
270/*2412*/ { 1, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
271/*2417*/ { 2, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
272/*2422*/ { 3, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
273/*2427*/ { 4, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
274/*2432*/ { 5, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
275/*2437*/ { 6, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \
276/*2442*/ { 7, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
277/*2447*/ { 8, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
278/*2452*/ { 9, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
279/*2457*/ { 10, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
280/*2462*/ { 11, DMN_FCCA, CHANNEL_CCK|CHANNEL_OFDM }, \
281 \
282/*2412*/ { 1, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
283/*2417*/ { 2, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
284/*2422*/ { 3, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
285/*2427*/ { 4, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
286/*2432*/ { 5, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
287/*2437*/ { 6, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
288/*2442*/ { 7, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
289/*2447*/ { 8, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
290/*2452*/ { 9, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
291/*2457*/ { 10, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
292/*2462*/ { 11, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
293/*2467*/ { 12, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
294/*2472*/ { 13, DMN_MKKA, CHANNEL_CCK|CHANNEL_OFDM }, \
295/*2484*/ { 14, DMN_MKKA, CHANNEL_CCK }, \
296 \
297/*2412*/ { 1, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
298/*2417*/ { 2, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
299/*2422*/ { 3, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
300/*2427*/ { 4, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
301/*2432*/ { 5, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
302/*2437*/ { 6, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM|CHANNEL_TURBO }, \
303/*2442*/ { 7, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
304/*2447*/ { 8, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
305/*2452*/ { 9, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
306/*2457*/ { 10, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
307/*2462*/ { 11, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
308/*2467*/ { 12, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
309/*2472*/ { 13, DMN_WORLD, CHANNEL_CCK|CHANNEL_OFDM }, \
310}
311
312#define IEEE80211_CHANNELS_5GHZ { \
313/*5745*/ { 149, DMN_APL1, CHANNEL_OFDM }, \
314/*5765*/ { 153, DMN_APL1, CHANNEL_OFDM }, \
315/*5785*/ { 157, DMN_APL1, CHANNEL_OFDM }, \
316/*5805*/ { 161, DMN_APL1, CHANNEL_OFDM }, \
317/*5825*/ { 165, DMN_APL1, CHANNEL_OFDM }, \
318 \
319/*5745*/ { 149, DMN_APL2, CHANNEL_OFDM }, \
320/*5765*/ { 153, DMN_APL2, CHANNEL_OFDM }, \
321/*5785*/ { 157, DMN_APL2, CHANNEL_OFDM }, \
322/*5805*/ { 161, DMN_APL2, CHANNEL_OFDM }, \
323 \
324/*5280*/ { 56, DMN_APL3, CHANNEL_OFDM }, \
325/*5300*/ { 60, DMN_APL3, CHANNEL_OFDM }, \
326/*5320*/ { 64, DMN_APL3, CHANNEL_OFDM }, \
327/*5745*/ { 149, DMN_APL3, CHANNEL_OFDM }, \
328/*5765*/ { 153, DMN_APL3, CHANNEL_OFDM }, \
329/*5785*/ { 157, DMN_APL3, CHANNEL_OFDM }, \
330/*5805*/ { 161, DMN_APL3, CHANNEL_OFDM }, \
331 \
332/*5180*/ { 36, DMN_APL4, CHANNEL_OFDM }, \
333/*5200*/ { 40, DMN_APL4, CHANNEL_OFDM }, \
334/*5220*/ { 44, DMN_APL4, CHANNEL_OFDM }, \
335/*5240*/ { 48, DMN_APL4, CHANNEL_OFDM }, \
336/*5745*/ { 149, DMN_APL4, CHANNEL_OFDM }, \
337/*5765*/ { 153, DMN_APL4, CHANNEL_OFDM }, \
338/*5785*/ { 157, DMN_APL4, CHANNEL_OFDM }, \
339/*5805*/ { 161, DMN_APL4, CHANNEL_OFDM }, \
340/*5825*/ { 165, DMN_APL4, CHANNEL_OFDM }, \
341 \
342/*5745*/ { 149, DMN_APL5, CHANNEL_OFDM }, \
343/*5765*/ { 153, DMN_APL5, CHANNEL_OFDM }, \
344/*5785*/ { 157, DMN_APL5, CHANNEL_OFDM }, \
345/*5805*/ { 161, DMN_APL5, CHANNEL_OFDM }, \
346/*5825*/ { 165, DMN_APL5, CHANNEL_OFDM }, \
347 \
348/*5180*/ { 36, DMN_ETSI1, CHANNEL_OFDM }, \
349/*5200*/ { 40, DMN_ETSI1, CHANNEL_OFDM }, \
350/*5220*/ { 44, DMN_ETSI1, CHANNEL_OFDM }, \
351/*5240*/ { 48, DMN_ETSI1, CHANNEL_OFDM }, \
352/*5260*/ { 52, DMN_ETSI1, CHANNEL_OFDM }, \
353/*5280*/ { 56, DMN_ETSI1, CHANNEL_OFDM }, \
354/*5300*/ { 60, DMN_ETSI1, CHANNEL_OFDM }, \
355/*5320*/ { 64, DMN_ETSI1, CHANNEL_OFDM }, \
356/*5500*/ { 100, DMN_ETSI1, CHANNEL_OFDM }, \
357/*5520*/ { 104, DMN_ETSI1, CHANNEL_OFDM }, \
358/*5540*/ { 108, DMN_ETSI1, CHANNEL_OFDM }, \
359/*5560*/ { 112, DMN_ETSI1, CHANNEL_OFDM }, \
360/*5580*/ { 116, DMN_ETSI1, CHANNEL_OFDM }, \
361/*5600*/ { 120, DMN_ETSI1, CHANNEL_OFDM }, \
362/*5620*/ { 124, DMN_ETSI1, CHANNEL_OFDM }, \
363/*5640*/ { 128, DMN_ETSI1, CHANNEL_OFDM }, \
364/*5660*/ { 132, DMN_ETSI1, CHANNEL_OFDM }, \
365/*5680*/ { 136, DMN_ETSI1, CHANNEL_OFDM }, \
366/*5700*/ { 140, DMN_ETSI1, CHANNEL_OFDM }, \
367 \
368/*5180*/ { 36, DMN_ETSI2, CHANNEL_OFDM }, \
369/*5200*/ { 40, DMN_ETSI2, CHANNEL_OFDM }, \
370/*5220*/ { 44, DMN_ETSI2, CHANNEL_OFDM }, \
371/*5240*/ { 48, DMN_ETSI2, CHANNEL_OFDM }, \
372 \
373/*5180*/ { 36, DMN_ETSI3, CHANNEL_OFDM }, \
374/*5200*/ { 40, DMN_ETSI3, CHANNEL_OFDM }, \
375/*5220*/ { 44, DMN_ETSI3, CHANNEL_OFDM }, \
376/*5240*/ { 48, DMN_ETSI3, CHANNEL_OFDM }, \
377/*5260*/ { 52, DMN_ETSI3, CHANNEL_OFDM }, \
378/*5280*/ { 56, DMN_ETSI3, CHANNEL_OFDM }, \
379/*5300*/ { 60, DMN_ETSI3, CHANNEL_OFDM }, \
380/*5320*/ { 64, DMN_ETSI3, CHANNEL_OFDM }, \
381 \
382/*5180*/ { 36, DMN_ETSI4, CHANNEL_OFDM }, \
383/*5200*/ { 40, DMN_ETSI4, CHANNEL_OFDM }, \
384/*5220*/ { 44, DMN_ETSI4, CHANNEL_OFDM }, \
385/*5240*/ { 48, DMN_ETSI4, CHANNEL_OFDM }, \
386/*5260*/ { 52, DMN_ETSI4, CHANNEL_OFDM }, \
387/*5280*/ { 56, DMN_ETSI4, CHANNEL_OFDM }, \
388/*5300*/ { 60, DMN_ETSI4, CHANNEL_OFDM }, \
389/*5320*/ { 64, DMN_ETSI4, CHANNEL_OFDM }, \
390 \
391/*5180*/ { 36, DMN_ETSI5, CHANNEL_OFDM }, \
392/*5200*/ { 40, DMN_ETSI5, CHANNEL_OFDM }, \
393/*5220*/ { 44, DMN_ETSI5, CHANNEL_OFDM }, \
394/*5240*/ { 48, DMN_ETSI5, CHANNEL_OFDM }, \
395 \
396/*5180*/ { 36, DMN_ETSI6, CHANNEL_OFDM }, \
397/*5200*/ { 40, DMN_ETSI6, CHANNEL_OFDM }, \
398/*5220*/ { 44, DMN_ETSI6, CHANNEL_OFDM }, \
399/*5240*/ { 48, DMN_ETSI6, CHANNEL_OFDM }, \
400/*5260*/ { 52, DMN_ETSI6, CHANNEL_OFDM }, \
401/*5280*/ { 56, DMN_ETSI6, CHANNEL_OFDM }, \
402/*5500*/ { 100, DMN_ETSI6, CHANNEL_OFDM }, \
403/*5520*/ { 104, DMN_ETSI6, CHANNEL_OFDM }, \
404/*5540*/ { 108, DMN_ETSI6, CHANNEL_OFDM }, \
405/*5560*/ { 112, DMN_ETSI6, CHANNEL_OFDM }, \
406/*5580*/ { 116, DMN_ETSI6, CHANNEL_OFDM }, \
407/*5600*/ { 120, DMN_ETSI6, CHANNEL_OFDM }, \
408/*5620*/ { 124, DMN_ETSI6, CHANNEL_OFDM }, \
409/*5640*/ { 128, DMN_ETSI6, CHANNEL_OFDM }, \
410/*5660*/ { 132, DMN_ETSI6, CHANNEL_OFDM }, \
411/*5680*/ { 136, DMN_ETSI6, CHANNEL_OFDM }, \
412/*5700*/ { 140, DMN_ETSI6, CHANNEL_OFDM }, \
413 \
414/*5180*/ { 36, DMN_FCC1, CHANNEL_OFDM }, \
415/*5200*/ { 40, DMN_FCC1, CHANNEL_OFDM }, \
416/*5210*/ { 42, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
417/*5220*/ { 44, DMN_FCC1, CHANNEL_OFDM }, \
418/*5240*/ { 48, DMN_FCC1, CHANNEL_OFDM }, \
419/*5250*/ { 50, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
420/*5260*/ { 52, DMN_FCC1, CHANNEL_OFDM }, \
421/*5280*/ { 56, DMN_FCC1, CHANNEL_OFDM }, \
422/*5290*/ { 58, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
423/*5300*/ { 60, DMN_FCC1, CHANNEL_OFDM }, \
424/*5320*/ { 64, DMN_FCC1, CHANNEL_OFDM }, \
425/*5745*/ { 149, DMN_FCC1, CHANNEL_OFDM }, \
426/*5760*/ { 152, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
427/*5765*/ { 153, DMN_FCC1, CHANNEL_OFDM }, \
428/*5785*/ { 157, DMN_FCC1, CHANNEL_OFDM }, \
429/*5800*/ { 160, DMN_FCC1, CHANNEL_OFDM|CHANNEL_TURBO }, \
430/*5805*/ { 161, DMN_FCC1, CHANNEL_OFDM }, \
431/*5825*/ { 165, DMN_FCC1, CHANNEL_OFDM }, \
432 \
433/*5180*/ { 36, DMN_FCC2, CHANNEL_OFDM }, \
434/*5200*/ { 40, DMN_FCC2, CHANNEL_OFDM }, \
435/*5220*/ { 44, DMN_FCC2, CHANNEL_OFDM }, \
436/*5240*/ { 48, DMN_FCC2, CHANNEL_OFDM }, \
437/*5260*/ { 52, DMN_FCC2, CHANNEL_OFDM }, \
438/*5280*/ { 56, DMN_FCC2, CHANNEL_OFDM }, \
439/*5300*/ { 60, DMN_FCC2, CHANNEL_OFDM }, \
440/*5320*/ { 64, DMN_FCC2, CHANNEL_OFDM }, \
441/*5745*/ { 149, DMN_FCC2, CHANNEL_OFDM }, \
442/*5765*/ { 153, DMN_FCC2, CHANNEL_OFDM }, \
443/*5785*/ { 157, DMN_FCC2, CHANNEL_OFDM }, \
444/*5805*/ { 161, DMN_FCC2, CHANNEL_OFDM }, \
445/*5825*/ { 165, DMN_FCC2, CHANNEL_OFDM }, \
446 \
447/*5180*/ { 36, DMN_FCC3, CHANNEL_OFDM }, \
448/*5200*/ { 40, DMN_FCC3, CHANNEL_OFDM }, \
449/*5210*/ { 42, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
450/*5220*/ { 44, DMN_FCC3, CHANNEL_OFDM }, \
451/*5240*/ { 48, DMN_FCC3, CHANNEL_OFDM }, \
452/*5250*/ { 50, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
453/*5260*/ { 52, DMN_FCC3, CHANNEL_OFDM }, \
454/*5280*/ { 56, DMN_FCC3, CHANNEL_OFDM }, \
455/*5290*/ { 58, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
456/*5300*/ { 60, DMN_FCC3, CHANNEL_OFDM }, \
457/*5320*/ { 64, DMN_FCC3, CHANNEL_OFDM }, \
458/*5500*/ { 100, DMN_FCC3, CHANNEL_OFDM }, \
459/*5520*/ { 104, DMN_FCC3, CHANNEL_OFDM }, \
460/*5540*/ { 108, DMN_FCC3, CHANNEL_OFDM }, \
461/*5560*/ { 112, DMN_FCC3, CHANNEL_OFDM }, \
462/*5580*/ { 116, DMN_FCC3, CHANNEL_OFDM }, \
463/*5600*/ { 120, DMN_FCC3, CHANNEL_OFDM }, \
464/*5620*/ { 124, DMN_FCC3, CHANNEL_OFDM }, \
465/*5640*/ { 128, DMN_FCC3, CHANNEL_OFDM }, \
466/*5660*/ { 132, DMN_FCC3, CHANNEL_OFDM }, \
467/*5680*/ { 136, DMN_FCC3, CHANNEL_OFDM }, \
468/*5700*/ { 140, DMN_FCC3, CHANNEL_OFDM }, \
469/*5745*/ { 149, DMN_FCC3, CHANNEL_OFDM }, \
470/*5760*/ { 152, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
471/*5765*/ { 153, DMN_FCC3, CHANNEL_OFDM }, \
472/*5785*/ { 157, DMN_FCC3, CHANNEL_OFDM }, \
473/*5800*/ { 160, DMN_FCC3, CHANNEL_OFDM|CHANNEL_TURBO }, \
474/*5805*/ { 161, DMN_FCC3, CHANNEL_OFDM }, \
475/*5825*/ { 165, DMN_FCC3, CHANNEL_OFDM }, \
476 \
477/*5170*/ { 34, DMN_MKK1, CHANNEL_OFDM }, \
478/*5190*/ { 38, DMN_MKK1, CHANNEL_OFDM }, \
479/*5210*/ { 42, DMN_MKK1, CHANNEL_OFDM }, \
480/*5230*/ { 46, DMN_MKK1, CHANNEL_OFDM }, \
481 \
482/*5040*/ { 8, DMN_MKK2, CHANNEL_OFDM }, \
483/*5060*/ { 12, DMN_MKK2, CHANNEL_OFDM }, \
484/*5080*/ { 16, DMN_MKK2, CHANNEL_OFDM }, \
485/*5170*/ { 34, DMN_MKK2, CHANNEL_OFDM }, \
486/*5190*/ { 38, DMN_MKK2, CHANNEL_OFDM }, \
487/*5210*/ { 42, DMN_MKK2, CHANNEL_OFDM }, \
488/*5230*/ { 46, DMN_MKK2, CHANNEL_OFDM }, \
489 \
490/*5180*/ { 36, DMN_WORLD, CHANNEL_OFDM }, \
491/*5200*/ { 40, DMN_WORLD, CHANNEL_OFDM }, \
492/*5220*/ { 44, DMN_WORLD, CHANNEL_OFDM }, \
493/*5240*/ { 48, DMN_WORLD, CHANNEL_OFDM }, \
494}
495
496enum ath5k_regdom ath5k_regdom2flag(enum ath5k_regdom, u16);
497u16 ath5k_regdom_from_ieee(enum ath5k_regdom ieee);
498enum ath5k_regdom ath5k_regdom_to_ieee(u16 regdomain);
499
500#endif