Browse Source

[ath9k] Add ath9k driver

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Scott K Logan 12 years ago
parent
commit
aaf7a35207
75 changed files with 43182 additions and 2 deletions
  1. 3
    1
      src/Makefile
  2. 239
    0
      src/drivers/net/ath/ath.h
  3. 0
    0
      src/drivers/net/ath/ath5k/ath5k.c
  4. 0
    0
      src/drivers/net/ath/ath5k/ath5k.h
  5. 0
    0
      src/drivers/net/ath/ath5k/ath5k_attach.c
  6. 0
    0
      src/drivers/net/ath/ath5k/ath5k_caps.c
  7. 0
    0
      src/drivers/net/ath/ath5k/ath5k_desc.c
  8. 0
    0
      src/drivers/net/ath/ath5k/ath5k_dma.c
  9. 0
    0
      src/drivers/net/ath/ath5k/ath5k_eeprom.c
  10. 0
    0
      src/drivers/net/ath/ath5k/ath5k_gpio.c
  11. 0
    0
      src/drivers/net/ath/ath5k/ath5k_initvals.c
  12. 0
    0
      src/drivers/net/ath/ath5k/ath5k_pcu.c
  13. 0
    0
      src/drivers/net/ath/ath5k/ath5k_phy.c
  14. 0
    0
      src/drivers/net/ath/ath5k/ath5k_qcu.c
  15. 0
    0
      src/drivers/net/ath/ath5k/ath5k_reset.c
  16. 0
    0
      src/drivers/net/ath/ath5k/ath5k_rfkill.c
  17. 0
    0
      src/drivers/net/ath/ath5k/base.h
  18. 0
    0
      src/drivers/net/ath/ath5k/desc.h
  19. 0
    0
      src/drivers/net/ath/ath5k/eeprom.h
  20. 0
    0
      src/drivers/net/ath/ath5k/reg.h
  21. 0
    0
      src/drivers/net/ath/ath5k/rfbuffer.h
  22. 0
    0
      src/drivers/net/ath/ath5k/rfgain.h
  23. 168
    0
      src/drivers/net/ath/ath9k/ani.h
  24. 672
    0
      src/drivers/net/ath/ath9k/ar5008_initvals.h
  25. 1356
    0
      src/drivers/net/ath/ath9k/ar9001_initvals.h
  26. 3264
    0
      src/drivers/net/ath/ath9k/ar9002_initvals.h
  27. 613
    0
      src/drivers/net/ath/ath9k/ar9002_phy.h
  28. 1864
    0
      src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h
  29. 338
    0
      src/drivers/net/ath/ath9k/ar9003_eeprom.h
  30. 125
    0
      src/drivers/net/ath/ath9k/ar9003_mac.h
  31. 1124
    0
      src/drivers/net/ath/ath9k/ar9003_phy.h
  32. 1525
    0
      src/drivers/net/ath/ath9k/ar9340_initvals.h
  33. 1161
    0
      src/drivers/net/ath/ath9k/ar9485_initvals.h
  34. 208
    0
      src/drivers/net/ath/ath9k/ath9k.c
  35. 521
    0
      src/drivers/net/ath/ath9k/ath9k.h
  36. 733
    0
      src/drivers/net/ath/ath9k/ath9k_ani.c
  37. 1663
    0
      src/drivers/net/ath/ath9k/ath9k_ar5008_phy.c
  38. 997
    0
      src/drivers/net/ath/ath9k/ath9k_ar9002_calib.c
  39. 607
    0
      src/drivers/net/ath/ath9k/ath9k_ar9002_hw.c
  40. 454
    0
      src/drivers/net/ath/ath9k/ath9k_ar9002_mac.c
  41. 578
    0
      src/drivers/net/ath/ath9k/ath9k_ar9002_phy.c
  42. 932
    0
      src/drivers/net/ath/ath9k/ath9k_ar9003_calib.c
  43. 5005
    0
      src/drivers/net/ath/ath9k/ath9k_ar9003_eeprom.c
  44. 409
    0
      src/drivers/net/ath/ath9k/ath9k_ar9003_hw.c
  45. 669
    0
      src/drivers/net/ath/ath9k/ath9k_ar9003_mac.c
  46. 1277
    0
      src/drivers/net/ath/ath9k/ath9k_ar9003_phy.c
  47. 403
    0
      src/drivers/net/ath/ath9k/ath9k_calib.c
  48. 69
    0
      src/drivers/net/ath/ath9k/ath9k_common.c
  49. 551
    0
      src/drivers/net/ath/ath9k/ath9k_eeprom.c
  50. 1078
    0
      src/drivers/net/ath/ath9k/ath9k_eeprom_4k.c
  51. 1019
    0
      src/drivers/net/ath/ath9k/ath9k_eeprom_9287.c
  52. 1351
    0
      src/drivers/net/ath/ath9k/ath9k_eeprom_def.c
  53. 2067
    0
      src/drivers/net/ath/ath9k/ath9k_hw.c
  54. 593
    0
      src/drivers/net/ath/ath9k/ath9k_init.c
  55. 733
    0
      src/drivers/net/ath/ath9k/ath9k_mac.c
  56. 916
    0
      src/drivers/net/ath/ath9k/ath9k_main.c
  57. 521
    0
      src/drivers/net/ath/ath9k/ath9k_recv.c
  58. 813
    0
      src/drivers/net/ath/ath9k/ath9k_xmit.c
  59. 115
    0
      src/drivers/net/ath/ath9k/calib.h
  60. 56
    0
      src/drivers/net/ath/ath9k/common.h
  61. 714
    0
      src/drivers/net/ath/ath9k/eeprom.h
  62. 268
    0
      src/drivers/net/ath/ath9k/hw-ops.h
  63. 995
    0
      src/drivers/net/ath/ath9k/hw.h
  64. 708
    0
      src/drivers/net/ath/ath9k/mac.h
  65. 51
    0
      src/drivers/net/ath/ath9k/phy.h
  66. 1919
    0
      src/drivers/net/ath/ath9k/reg.h
  67. 183
    0
      src/drivers/net/ath/ath_hw.c
  68. 82
    0
      src/drivers/net/ath/ath_key.c
  69. 59
    0
      src/drivers/net/ath/ath_main.c
  70. 602
    0
      src/drivers/net/ath/ath_regd.c
  71. 64
    0
      src/drivers/net/ath/reg.h
  72. 263
    0
      src/drivers/net/ath/regd.h
  73. 481
    0
      src/drivers/net/ath/regd_common.h
  74. 2
    0
      src/include/ipxe/errfile.h
  75. 1
    1
      src/include/ipxe/net80211.h

+ 3
- 1
src/Makefile View File

@@ -68,7 +68,9 @@ SRCDIRS		+= drivers/net/igb
68 68
 SRCDIRS		+= drivers/net/igbvf
69 69
 SRCDIRS		+= drivers/net/phantom
70 70
 SRCDIRS		+= drivers/net/rtl818x
71
-SRCDIRS		+= drivers/net/ath5k
71
+SRCDIRS		+= drivers/net/ath
72
+SRCDIRS		+= drivers/net/ath/ath5k
73
+SRCDIRS		+= drivers/net/ath/ath9k
72 74
 SRCDIRS		+= drivers/net/vxge
73 75
 SRCDIRS		+= drivers/net/efi
74 76
 SRCDIRS		+= drivers/block

+ 239
- 0
src/drivers/net/ath/ath.h View File

@@ -0,0 +1,239 @@
1
+/*
2
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef ATH_H
21
+#define ATH_H
22
+
23
+#include <unistd.h>
24
+#include <ipxe/net80211.h>
25
+
26
+/* This block of functions are from kernel.h v3.0.1 */
27
+#define ARRAY_SIZE(arr)		(sizeof(arr) / sizeof((arr)[0]))
28
+#define DIV_ROUND_UP(n,d)	(((n) + (d) - 1) / (d))
29
+#define BITS_PER_BYTE		8
30
+#define BITS_TO_LONGS(nr)	DIV_ROUND_UP(nr, BITS_PER_BYTE * sizeof(long))
31
+#define BIT(nr)			(1UL << (nr))
32
+
33
+#define min(x, y) ({					\
34
+	typeof(x) _min1 = (x);				\
35
+	typeof(y) _min2 = (y);				\
36
+	(void) (&_min1 == &_min2);			\
37
+	_min1 < _min2 ? _min1 : _min2; })
38
+#define max(x, y) ({					\
39
+	typeof(x) _max1 = (x);				\
40
+	typeof(y) _max2 = (y);				\
41
+	(void) (&_max1 == &_max2);			\
42
+	_max1 > _max2 ? _max1 : _max2; })
43
+#define abs(x) ({					\
44
+		long ret;				\
45
+		if (sizeof(x) == sizeof(long)) {	\
46
+			long __x = (x);			\
47
+			ret = (__x < 0) ? -__x : __x;	\
48
+		} else {				\
49
+			int __x = (x);			\
50
+			ret = (__x < 0) ? -__x : __x;	\
51
+		}					\
52
+		ret;					\
53
+	})
54
+
55
+#define ___constant_swab16(x) ((uint16_t)(			\
56
+	(((uint16_t)(x) & (uint16_t)0x00ffU) << 8) |		\
57
+	(((uint16_t)(x) & (uint16_t)0xff00U) >> 8)))
58
+#define ___constant_swab32(x) ((uint32_t)(			\
59
+	(((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) |	\
60
+	(((uint32_t)(x) & (uint32_t)0x0000ff00UL) <<  8) |	\
61
+	(((uint32_t)(x) & (uint32_t)0x00ff0000UL) >>  8) |	\
62
+	(((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
63
+#define __swab16(x) ___constant_swab16(x)
64
+#define __swab32(x) ___constant_swab32(x)
65
+#define swab16 __swab16
66
+#define swab32 __swab32
67
+
68
+static inline int32_t sign_extend32(uint32_t value, int index)
69
+{
70
+	uint8_t shift = 31 - index;
71
+	return (int32_t)(value << shift) >> shift;
72
+}
73
+
74
+static inline u16 __get_unaligned_le16(const u8 *p)
75
+{
76
+	return p[0] | p[1] << 8;
77
+}
78
+static inline u32 __get_unaligned_le32(const u8 *p)
79
+{
80
+	return p[0] | p[1] << 8 | p[2] << 16 | p[3] << 24;
81
+}
82
+static inline u16 get_unaligned_le16(const void *p)
83
+{
84
+	return __get_unaligned_le16((const u8 *)p);
85
+}
86
+static inline u32 get_unaligned_le32(const void *p)
87
+{
88
+	return __get_unaligned_le32((const u8 *)p);
89
+}
90
+/* End Kernel Block */
91
+
92
+/*
93
+ * The key cache is used for h/w cipher state and also for
94
+ * tracking station state such as the current tx antenna.
95
+ * We also setup a mapping table between key cache slot indices
96
+ * and station state to short-circuit node lookups on rx.
97
+ * Different parts have different size key caches.  We handle
98
+ * up to ATH_KEYMAX entries (could dynamically allocate state).
99
+ */
100
+#define	ATH_KEYMAX	        128     /* max key cache size we handle */
101
+
102
+static const u8 ath_bcast_mac[ETH_ALEN] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
103
+
104
+struct ath_ani {
105
+	int caldone;
106
+	unsigned int longcal_timer;
107
+	unsigned int shortcal_timer;
108
+	unsigned int resetcal_timer;
109
+	unsigned int checkani_timer;
110
+	int timer;
111
+};
112
+
113
+struct ath_cycle_counters {
114
+	u32 cycles;
115
+	u32 rx_busy;
116
+	u32 rx_frame;
117
+	u32 tx_frame;
118
+};
119
+
120
+enum ath_device_state {
121
+	ATH_HW_UNAVAILABLE,
122
+	ATH_HW_INITIALIZED,
123
+};
124
+
125
+enum ath_bus_type {
126
+	ATH_PCI,
127
+	ATH_AHB,
128
+	ATH_USB,
129
+};
130
+
131
+struct reg_dmn_pair_mapping {
132
+	u16 regDmnEnum;
133
+	u16 reg_5ghz_ctl;
134
+	u16 reg_2ghz_ctl;
135
+};
136
+
137
+struct ath_regulatory {
138
+	char alpha2[2];
139
+	u16 country_code;
140
+	u16 max_power_level;
141
+	u32 tp_scale;
142
+	u16 current_rd;
143
+	u16 current_rd_ext;
144
+	int16_t power_limit;
145
+	struct reg_dmn_pair_mapping *regpair;
146
+};
147
+
148
+enum ath_crypt_caps {
149
+	ATH_CRYPT_CAP_CIPHER_AESCCM		= BIT(0),
150
+	ATH_CRYPT_CAP_MIC_COMBINED		= BIT(1),
151
+};
152
+
153
+struct ath_keyval {
154
+	u8 kv_type;
155
+	u8 kv_pad;
156
+	u16 kv_len;
157
+	u8 kv_val[16]; /* TK */
158
+	u8 kv_mic[8]; /* Michael MIC key */
159
+	u8 kv_txmic[8]; /* Michael MIC TX key (used only if the hardware
160
+			 * supports both MIC keys in the same key cache entry;
161
+			 * in that case, kv_mic is the RX key) */
162
+};
163
+
164
+enum ath_cipher {
165
+	ATH_CIPHER_WEP = 0,
166
+	ATH_CIPHER_AES_OCB = 1,
167
+	ATH_CIPHER_AES_CCM = 2,
168
+	ATH_CIPHER_CKIP = 3,
169
+	ATH_CIPHER_TKIP = 4,
170
+	ATH_CIPHER_CLR = 5,
171
+	ATH_CIPHER_MIC = 127
172
+};
173
+
174
+/**
175
+ * struct ath_ops - Register read/write operations
176
+ *
177
+ * @read: Register read
178
+ * @multi_read: Multiple register read
179
+ * @write: Register write
180
+ * @enable_write_buffer: Enable multiple register writes
181
+ * @write_flush: flush buffered register writes and disable buffering
182
+ */
183
+struct ath_ops {
184
+	unsigned int (*read)(void *, u32 reg_offset);
185
+	void (*multi_read)(void *, u32 *addr, u32 *val, u16 count);
186
+	void (*write)(void *, u32 val, u32 reg_offset);
187
+	void (*enable_write_buffer)(void *);
188
+	void (*write_flush) (void *);
189
+	u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
190
+};
191
+
192
+struct ath_common;
193
+struct ath_bus_ops;
194
+
195
+struct ath_common {
196
+	void *ah;
197
+	void *priv;
198
+	struct net80211_device *dev;
199
+	int debug_mask;
200
+	enum ath_device_state state;
201
+
202
+	struct ath_ani ani;
203
+
204
+	u16 cachelsz;
205
+	u16 curaid;
206
+	u8 macaddr[ETH_ALEN];
207
+	u8 curbssid[ETH_ALEN];
208
+	u8 bssidmask[ETH_ALEN];
209
+
210
+	u8 tx_chainmask;
211
+	u8 rx_chainmask;
212
+
213
+	u32 rx_bufsize;
214
+
215
+	u32 keymax;
216
+	enum ath_crypt_caps crypt_caps;
217
+
218
+	unsigned int clockrate;
219
+
220
+	struct ath_cycle_counters cc_ani;
221
+	struct ath_cycle_counters cc_survey;
222
+
223
+	struct ath_regulatory regulatory;
224
+	const struct ath_ops *ops;
225
+	const struct ath_bus_ops *bus_ops;
226
+
227
+	int btcoex_enabled;
228
+};
229
+
230
+struct io_buffer *ath_rxbuf_alloc(struct ath_common *common,
231
+				u32 len,
232
+				u32 *iob_addr);
233
+
234
+void ath_hw_setbssidmask(struct ath_common *common);
235
+int ath_hw_keyreset(struct ath_common *common, u16 entry);
236
+void ath_hw_cycle_counters_update(struct ath_common *common);
237
+int32_t ath_hw_get_listen_time(struct ath_common *common);
238
+
239
+#endif /* ATH_H */

src/drivers/net/ath5k/ath5k.c → src/drivers/net/ath/ath5k/ath5k.c View File


src/drivers/net/ath5k/ath5k.h → src/drivers/net/ath/ath5k/ath5k.h View File


src/drivers/net/ath5k/ath5k_attach.c → src/drivers/net/ath/ath5k/ath5k_attach.c View File


src/drivers/net/ath5k/ath5k_caps.c → src/drivers/net/ath/ath5k/ath5k_caps.c View File


src/drivers/net/ath5k/ath5k_desc.c → src/drivers/net/ath/ath5k/ath5k_desc.c View File


src/drivers/net/ath5k/ath5k_dma.c → src/drivers/net/ath/ath5k/ath5k_dma.c View File


src/drivers/net/ath5k/ath5k_eeprom.c → src/drivers/net/ath/ath5k/ath5k_eeprom.c View File


src/drivers/net/ath5k/ath5k_gpio.c → src/drivers/net/ath/ath5k/ath5k_gpio.c View File


src/drivers/net/ath5k/ath5k_initvals.c → src/drivers/net/ath/ath5k/ath5k_initvals.c View File


src/drivers/net/ath5k/ath5k_pcu.c → src/drivers/net/ath/ath5k/ath5k_pcu.c View File


src/drivers/net/ath5k/ath5k_phy.c → src/drivers/net/ath/ath5k/ath5k_phy.c View File


src/drivers/net/ath5k/ath5k_qcu.c → src/drivers/net/ath/ath5k/ath5k_qcu.c View File


src/drivers/net/ath5k/ath5k_reset.c → src/drivers/net/ath/ath5k/ath5k_reset.c View File


src/drivers/net/ath5k/ath5k_rfkill.c → src/drivers/net/ath/ath5k/ath5k_rfkill.c View File


src/drivers/net/ath5k/base.h → src/drivers/net/ath/ath5k/base.h View File


src/drivers/net/ath5k/desc.h → src/drivers/net/ath/ath5k/desc.h View File


src/drivers/net/ath5k/eeprom.h → src/drivers/net/ath/ath5k/eeprom.h View File


src/drivers/net/ath5k/reg.h → src/drivers/net/ath/ath5k/reg.h View File


src/drivers/net/ath5k/rfbuffer.h → src/drivers/net/ath/ath5k/rfbuffer.h View File


src/drivers/net/ath5k/rfgain.h → src/drivers/net/ath/ath5k/rfgain.h View File


+ 168
- 0
src/drivers/net/ath/ath9k/ani.h View File

@@ -0,0 +1,168 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef ANI_H
21
+#define ANI_H
22
+
23
+#define HAL_PROCESS_ANI           0x00000001
24
+
25
+#define DO_ANI(ah) (((ah)->proc_phyerr & HAL_PROCESS_ANI) && ah->curchan)
26
+
27
+#define BEACON_RSSI(ahp) (ahp->stats.avgbrssi)
28
+
29
+/* units are errors per second */
30
+#define ATH9K_ANI_OFDM_TRIG_HIGH_OLD      500
31
+#define ATH9K_ANI_OFDM_TRIG_HIGH_NEW      1000
32
+
33
+/* units are errors per second */
34
+#define ATH9K_ANI_OFDM_TRIG_LOW_OLD       200
35
+#define ATH9K_ANI_OFDM_TRIG_LOW_NEW       400
36
+
37
+/* units are errors per second */
38
+#define ATH9K_ANI_CCK_TRIG_HIGH_OLD       200
39
+#define ATH9K_ANI_CCK_TRIG_HIGH_NEW       600
40
+
41
+/* units are errors per second */
42
+#define ATH9K_ANI_CCK_TRIG_LOW_OLD        100
43
+#define ATH9K_ANI_CCK_TRIG_LOW_NEW        300
44
+
45
+#define ATH9K_ANI_NOISE_IMMUNE_LVL        4
46
+#define ATH9K_ANI_USE_OFDM_WEAK_SIG       1
47
+#define ATH9K_ANI_CCK_WEAK_SIG_THR        0
48
+
49
+#define ATH9K_ANI_SPUR_IMMUNE_LVL_OLD     7
50
+#define ATH9K_ANI_SPUR_IMMUNE_LVL_NEW     3
51
+
52
+#define ATH9K_ANI_FIRSTEP_LVL_OLD         0
53
+#define ATH9K_ANI_FIRSTEP_LVL_NEW         2
54
+
55
+#define ATH9K_ANI_RSSI_THR_HIGH           40
56
+#define ATH9K_ANI_RSSI_THR_LOW            7
57
+
58
+#define ATH9K_ANI_PERIOD_OLD              100
59
+#define ATH9K_ANI_PERIOD_NEW              1000
60
+
61
+/* in ms */
62
+#define ATH9K_ANI_POLLINTERVAL_OLD        100
63
+#define ATH9K_ANI_POLLINTERVAL_NEW        1000
64
+
65
+#define HAL_NOISE_IMMUNE_MAX              4
66
+#define HAL_SPUR_IMMUNE_MAX               7
67
+#define HAL_FIRST_STEP_MAX                2
68
+
69
+#define ATH9K_SIG_FIRSTEP_SETTING_MIN     0
70
+#define ATH9K_SIG_FIRSTEP_SETTING_MAX     20
71
+#define ATH9K_SIG_SPUR_IMM_SETTING_MIN    0
72
+#define ATH9K_SIG_SPUR_IMM_SETTING_MAX    22
73
+
74
+#define ATH9K_ANI_ENABLE_MRC_CCK          1
75
+
76
+/* values here are relative to the INI */
77
+
78
+enum ath9k_ani_cmd {
79
+	ATH9K_ANI_PRESENT = 0x1,
80
+	ATH9K_ANI_NOISE_IMMUNITY_LEVEL = 0x2,
81
+	ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION = 0x4,
82
+	ATH9K_ANI_CCK_WEAK_SIGNAL_THR = 0x8,
83
+	ATH9K_ANI_FIRSTEP_LEVEL = 0x10,
84
+	ATH9K_ANI_SPUR_IMMUNITY_LEVEL = 0x20,
85
+	ATH9K_ANI_MODE = 0x40,
86
+	ATH9K_ANI_PHYERR_RESET = 0x80,
87
+	ATH9K_ANI_MRC_CCK = 0x100,
88
+	ATH9K_ANI_ALL = 0xfff
89
+};
90
+
91
+struct ath9k_mib_stats {
92
+	u32 ackrcv_bad;
93
+	u32 rts_bad;
94
+	u32 rts_good;
95
+	u32 fcs_bad;
96
+	u32 beacons;
97
+};
98
+
99
+/* INI default values for ANI registers */
100
+struct ath9k_ani_default {
101
+	u16 m1ThreshLow;
102
+	u16 m2ThreshLow;
103
+	u16 m1Thresh;
104
+	u16 m2Thresh;
105
+	u16 m2CountThr;
106
+	u16 m2CountThrLow;
107
+	u16 m1ThreshLowExt;
108
+	u16 m2ThreshLowExt;
109
+	u16 m1ThreshExt;
110
+	u16 m2ThreshExt;
111
+	u16 firstep;
112
+	u16 firstepLow;
113
+	u16 cycpwrThr1;
114
+	u16 cycpwrThr1Ext;
115
+};
116
+
117
+struct ar5416AniState {
118
+	struct ath9k_channel *c;
119
+	u8 noiseImmunityLevel;
120
+	u8 ofdmNoiseImmunityLevel;
121
+	u8 cckNoiseImmunityLevel;
122
+	int ofdmsTurn;
123
+	u8 mrcCCKOff;
124
+	u8 spurImmunityLevel;
125
+	u8 firstepLevel;
126
+	u8 ofdmWeakSigDetectOff;
127
+	u8 cckWeakSigThreshold;
128
+	u32 listenTime;
129
+	int32_t rssiThrLow;
130
+	int32_t rssiThrHigh;
131
+	u32 noiseFloor;
132
+	u32 ofdmPhyErrCount;
133
+	u32 cckPhyErrCount;
134
+	int16_t pktRssi[2];
135
+	int16_t ofdmErrRssi[2];
136
+	int16_t cckErrRssi[2];
137
+	struct ath9k_ani_default iniDef;
138
+};
139
+
140
+struct ar5416Stats {
141
+	u32 ast_ani_niup;
142
+	u32 ast_ani_nidown;
143
+	u32 ast_ani_spurup;
144
+	u32 ast_ani_spurdown;
145
+	u32 ast_ani_ofdmon;
146
+	u32 ast_ani_ofdmoff;
147
+	u32 ast_ani_cckhigh;
148
+	u32 ast_ani_ccklow;
149
+	u32 ast_ani_stepup;
150
+	u32 ast_ani_stepdown;
151
+	u32 ast_ani_ofdmerrs;
152
+	u32 ast_ani_cckerrs;
153
+	u32 ast_ani_reset;
154
+	u32 ast_ani_lzero;
155
+	u32 ast_ani_lneg;
156
+	u32 avgbrssi;
157
+	struct ath9k_mib_stats ast_mibstats;
158
+};
159
+#define ah_mibStats stats.ast_mibstats
160
+
161
+void ath9k_enable_mib_counters(struct ath_hw *ah);
162
+void ath9k_hw_disable_mib_counters(struct ath_hw *ah);
163
+void ath9k_hw_ani_setup(struct ath_hw *ah);
164
+void ath9k_hw_ani_init(struct ath_hw *ah);
165
+int ath9k_hw_get_ani_channel_idx(struct ath_hw *ah,
166
+				 struct ath9k_channel *chan);
167
+
168
+#endif /* ANI_H */

+ 672
- 0
src/drivers/net/ath/ath9k/ar5008_initvals.h View File

@@ -0,0 +1,672 @@
1
+/*
2
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+static const u32 ar5416Modes[][6] = {
18
+	{0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160, 0x000001e0},
19
+	{0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c, 0x000001e0},
20
+	{0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38, 0x00001180},
21
+	{0x000010f0, 0x0000a000, 0x00014000, 0x00016000, 0x0000b000, 0x00014008},
22
+	{0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00, 0x06e006e0},
23
+	{0x0000801c, 0x128d93a7, 0x128d93cf, 0x12e013d7, 0x12e013ab, 0x098813cf},
24
+	{0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810, 0x08f04810},
25
+	{0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a, 0x0000320a},
26
+	{0x00009804, 0x00000300, 0x000003c4, 0x000003c4, 0x00000300, 0x00000303},
27
+	{0x00009820, 0x02020200, 0x02020200, 0x02020200, 0x02020200, 0x02020200},
28
+	{0x00009824, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
29
+	{0x00009828, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001, 0x0a020001},
30
+	{0x00009834, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
31
+	{0x00009838, 0x00000007, 0x00000007, 0x00000007, 0x00000007, 0x00000007},
32
+	{0x00009844, 0x1372161e, 0x1372161e, 0x137216a0, 0x137216a0, 0x137216a0},
33
+	{0x00009848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
34
+	{0x0000a848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
35
+	{0x0000b848, 0x001a6a65, 0x001a6a65, 0x00197a68, 0x00197a68, 0x00197a68},
36
+	{0x00009850, 0x6c48b4e0, 0x6d48b4e0, 0x6d48b0de, 0x6c48b0de, 0x6c48b0de},
37
+	{0x00009858, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e, 0x7ec82d2e},
38
+	{0x0000985c, 0x31395d5e, 0x3139605e, 0x3139605e, 0x31395d5e, 0x31395d5e},
39
+	{0x00009860, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18, 0x00049d18},
40
+	{0x00009864, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00, 0x0001ce00},
41
+	{0x00009868, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190, 0x409a4190},
42
+	{0x0000986c, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081, 0x050cb081},
43
+	{0x00009914, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898, 0x000007d0},
44
+	{0x00009918, 0x000001b8, 0x00000370, 0x00000268, 0x00000134, 0x00000134},
45
+	{0x00009924, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b, 0xd0058a0b},
46
+	{0x00009944, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020, 0xffb81020},
47
+	{0x00009960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80},
48
+	{0x0000a960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80},
49
+	{0x0000b960, 0x00000900, 0x00000900, 0x00012d80, 0x00012d80, 0x00012d80},
50
+	{0x00009964, 0x00000000, 0x00000000, 0x00001120, 0x00001120, 0x00001120},
51
+	{0x000099bc, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00, 0x001a0a00},
52
+	{0x000099c0, 0x038919be, 0x038919be, 0x038919be, 0x038919be, 0x038919be},
53
+	{0x000099c4, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77, 0x06336f77},
54
+	{0x000099c8, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c, 0x6af6532c},
55
+	{0x000099cc, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8, 0x08f186c8},
56
+	{0x000099d0, 0x00046384, 0x00046384, 0x00046384, 0x00046384, 0x00046384},
57
+	{0x000099d4, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
58
+	{0x000099d8, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
59
+	{0x0000a204, 0x00000880, 0x00000880, 0x00000880, 0x00000880, 0x00000880},
60
+	{0x0000a208, 0xd6be4788, 0xd6be4788, 0xd03e4788, 0xd03e4788, 0xd03e4788},
61
+	{0x0000a20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120},
62
+	{0x0000b20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120},
63
+	{0x0000c20c, 0x002ec1e0, 0x002ec1e0, 0x002ac120, 0x002ac120, 0x002ac120},
64
+	{0x0000a21c, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a, 0x1883800a},
65
+	{0x0000a230, 0x00000000, 0x00000000, 0x00000210, 0x00000108, 0x00000000},
66
+	{0x0000a274, 0x0a1a9caa, 0x0a1a9caa, 0x0a1a7caa, 0x0a1a7caa, 0x0a1a7caa},
67
+	{0x0000a300, 0x18010000, 0x18010000, 0x18010000, 0x18010000, 0x18010000},
68
+	{0x0000a304, 0x30032602, 0x30032602, 0x2e032402, 0x2e032402, 0x2e032402},
69
+	{0x0000a308, 0x48073e06, 0x48073e06, 0x4a0a3c06, 0x4a0a3c06, 0x4a0a3c06},
70
+	{0x0000a30c, 0x560b4c0a, 0x560b4c0a, 0x621a540b, 0x621a540b, 0x621a540b},
71
+	{0x0000a310, 0x641a600f, 0x641a600f, 0x764f6c1b, 0x764f6c1b, 0x764f6c1b},
72
+	{0x0000a314, 0x7a4f6e1b, 0x7a4f6e1b, 0x845b7a5a, 0x845b7a5a, 0x845b7a5a},
73
+	{0x0000a318, 0x8c5b7e5a, 0x8c5b7e5a, 0x950f8ccf, 0x950f8ccf, 0x950f8ccf},
74
+	{0x0000a31c, 0x9d0f96cf, 0x9d0f96cf, 0xa5cf9b4f, 0xa5cf9b4f, 0xa5cf9b4f},
75
+	{0x0000a320, 0xb51fa69f, 0xb51fa69f, 0xbddfaf1f, 0xbddfaf1f, 0xbddfaf1f},
76
+	{0x0000a324, 0xcb3fbd07, 0xcb3fbcbf, 0xd1ffc93f, 0xd1ffc93f, 0xd1ffc93f},
77
+	{0x0000a328, 0x0000d7bf, 0x0000d7bf, 0x00000000, 0x00000000, 0x00000000},
78
+	{0x0000a32c, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
79
+	{0x0000a330, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
80
+	{0x0000a334, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
81
+};
82
+
83
+static const u32 ar5416Common[][2] = {
84
+	/* Addr      allmodes  */
85
+	{0x0000000c, 0x00000000},
86
+	{0x00000030, 0x00020015},
87
+	{0x00000034, 0x00000005},
88
+	{0x00000040, 0x00000000},
89
+	{0x00000044, 0x00000008},
90
+	{0x00000048, 0x00000008},
91
+	{0x0000004c, 0x00000010},
92
+	{0x00000050, 0x00000000},
93
+	{0x00000054, 0x0000001f},
94
+	{0x00000800, 0x00000000},
95
+	{0x00000804, 0x00000000},
96
+	{0x00000808, 0x00000000},
97
+	{0x0000080c, 0x00000000},
98
+	{0x00000810, 0x00000000},
99
+	{0x00000814, 0x00000000},
100
+	{0x00000818, 0x00000000},
101
+	{0x0000081c, 0x00000000},
102
+	{0x00000820, 0x00000000},
103
+	{0x00000824, 0x00000000},
104
+	{0x00001040, 0x002ffc0f},
105
+	{0x00001044, 0x002ffc0f},
106
+	{0x00001048, 0x002ffc0f},
107
+	{0x0000104c, 0x002ffc0f},
108
+	{0x00001050, 0x002ffc0f},
109
+	{0x00001054, 0x002ffc0f},
110
+	{0x00001058, 0x002ffc0f},
111
+	{0x0000105c, 0x002ffc0f},
112
+	{0x00001060, 0x002ffc0f},
113
+	{0x00001064, 0x002ffc0f},
114
+	{0x00001230, 0x00000000},
115
+	{0x00001270, 0x00000000},
116
+	{0x00001038, 0x00000000},
117
+	{0x00001078, 0x00000000},
118
+	{0x000010b8, 0x00000000},
119
+	{0x000010f8, 0x00000000},
120
+	{0x00001138, 0x00000000},
121
+	{0x00001178, 0x00000000},
122
+	{0x000011b8, 0x00000000},
123
+	{0x000011f8, 0x00000000},
124
+	{0x00001238, 0x00000000},
125
+	{0x00001278, 0x00000000},
126
+	{0x000012b8, 0x00000000},
127
+	{0x000012f8, 0x00000000},
128
+	{0x00001338, 0x00000000},
129
+	{0x00001378, 0x00000000},
130
+	{0x000013b8, 0x00000000},
131
+	{0x000013f8, 0x00000000},
132
+	{0x00001438, 0x00000000},
133
+	{0x00001478, 0x00000000},
134
+	{0x000014b8, 0x00000000},
135
+	{0x000014f8, 0x00000000},
136
+	{0x00001538, 0x00000000},
137
+	{0x00001578, 0x00000000},
138
+	{0x000015b8, 0x00000000},
139
+	{0x000015f8, 0x00000000},
140
+	{0x00001638, 0x00000000},
141
+	{0x00001678, 0x00000000},
142
+	{0x000016b8, 0x00000000},
143
+	{0x000016f8, 0x00000000},
144
+	{0x00001738, 0x00000000},
145
+	{0x00001778, 0x00000000},
146
+	{0x000017b8, 0x00000000},
147
+	{0x000017f8, 0x00000000},
148
+	{0x0000103c, 0x00000000},
149
+	{0x0000107c, 0x00000000},
150
+	{0x000010bc, 0x00000000},
151
+	{0x000010fc, 0x00000000},
152
+	{0x0000113c, 0x00000000},
153
+	{0x0000117c, 0x00000000},
154
+	{0x000011bc, 0x00000000},
155
+	{0x000011fc, 0x00000000},
156
+	{0x0000123c, 0x00000000},
157
+	{0x0000127c, 0x00000000},
158
+	{0x000012bc, 0x00000000},
159
+	{0x000012fc, 0x00000000},
160
+	{0x0000133c, 0x00000000},
161
+	{0x0000137c, 0x00000000},
162
+	{0x000013bc, 0x00000000},
163
+	{0x000013fc, 0x00000000},
164
+	{0x0000143c, 0x00000000},
165
+	{0x0000147c, 0x00000000},
166
+	{0x00004030, 0x00000002},
167
+	{0x0000403c, 0x00000002},
168
+	{0x00007010, 0x00000000},
169
+	{0x00007038, 0x000004c2},
170
+	{0x00008004, 0x00000000},
171
+	{0x00008008, 0x00000000},
172
+	{0x0000800c, 0x00000000},
173
+	{0x00008018, 0x00000700},
174
+	{0x00008020, 0x00000000},
175
+	{0x00008038, 0x00000000},
176
+	{0x0000803c, 0x00000000},
177
+	{0x00008048, 0x40000000},
178
+	{0x00008054, 0x00000000},
179
+	{0x00008058, 0x00000000},
180
+	{0x0000805c, 0x000fc78f},
181
+	{0x00008060, 0x0000000f},
182
+	{0x00008064, 0x00000000},
183
+	{0x000080c0, 0x2a82301a},
184
+	{0x000080c4, 0x05dc01e0},
185
+	{0x000080c8, 0x1f402710},
186
+	{0x000080cc, 0x01f40000},
187
+	{0x000080d0, 0x00001e00},
188
+	{0x000080d4, 0x00000000},
189
+	{0x000080d8, 0x00400000},
190
+	{0x000080e0, 0xffffffff},
191
+	{0x000080e4, 0x0000ffff},
192
+	{0x000080e8, 0x003f3f3f},
193
+	{0x000080ec, 0x00000000},
194
+	{0x000080f0, 0x00000000},
195
+	{0x000080f4, 0x00000000},
196
+	{0x000080f8, 0x00000000},
197
+	{0x000080fc, 0x00020000},
198
+	{0x00008100, 0x00020000},
199
+	{0x00008104, 0x00000001},
200
+	{0x00008108, 0x00000052},
201
+	{0x0000810c, 0x00000000},
202
+	{0x00008110, 0x00000168},
203
+	{0x00008118, 0x000100aa},
204
+	{0x0000811c, 0x00003210},
205
+	{0x00008124, 0x00000000},
206
+	{0x00008128, 0x00000000},
207
+	{0x0000812c, 0x00000000},
208
+	{0x00008130, 0x00000000},
209
+	{0x00008134, 0x00000000},
210
+	{0x00008138, 0x00000000},
211
+	{0x0000813c, 0x00000000},
212
+	{0x00008144, 0xffffffff},
213
+	{0x00008168, 0x00000000},
214
+	{0x0000816c, 0x00000000},
215
+	{0x00008170, 0x32143320},
216
+	{0x00008174, 0xfaa4fa50},
217
+	{0x00008178, 0x00000100},
218
+	{0x0000817c, 0x00000000},
219
+	{0x000081c4, 0x00000000},
220
+	{0x000081ec, 0x00000000},
221
+	{0x000081f0, 0x00000000},
222
+	{0x000081f4, 0x00000000},
223
+	{0x000081f8, 0x00000000},
224
+	{0x000081fc, 0x00000000},
225
+	{0x00008200, 0x00000000},
226
+	{0x00008204, 0x00000000},
227
+	{0x00008208, 0x00000000},
228
+	{0x0000820c, 0x00000000},
229
+	{0x00008210, 0x00000000},
230
+	{0x00008214, 0x00000000},
231
+	{0x00008218, 0x00000000},
232
+	{0x0000821c, 0x00000000},
233
+	{0x00008220, 0x00000000},
234
+	{0x00008224, 0x00000000},
235
+	{0x00008228, 0x00000000},
236
+	{0x0000822c, 0x00000000},
237
+	{0x00008230, 0x00000000},
238
+	{0x00008234, 0x00000000},
239
+	{0x00008238, 0x00000000},
240
+	{0x0000823c, 0x00000000},
241
+	{0x00008240, 0x00100000},
242
+	{0x00008244, 0x0010f400},
243
+	{0x00008248, 0x00000100},
244
+	{0x0000824c, 0x0001e800},
245
+	{0x00008250, 0x00000000},
246
+	{0x00008254, 0x00000000},
247
+	{0x00008258, 0x00000000},
248
+	{0x0000825c, 0x400000ff},
249
+	{0x00008260, 0x00080922},
250
+	{0x00008264, 0x88000010},
251
+	{0x00008270, 0x00000000},
252
+	{0x00008274, 0x40000000},
253
+	{0x00008278, 0x003e4180},
254
+	{0x0000827c, 0x00000000},
255
+	{0x00008284, 0x0000002c},
256
+	{0x00008288, 0x0000002c},
257
+	{0x0000828c, 0x00000000},
258
+	{0x00008294, 0x00000000},
259
+	{0x00008298, 0x00000000},
260
+	{0x00008300, 0x00000000},
261
+	{0x00008304, 0x00000000},
262
+	{0x00008308, 0x00000000},
263
+	{0x0000830c, 0x00000000},
264
+	{0x00008310, 0x00000000},
265
+	{0x00008314, 0x00000000},
266
+	{0x00008318, 0x00000000},
267
+	{0x00008328, 0x00000000},
268
+	{0x0000832c, 0x00000007},
269
+	{0x00008330, 0x00000302},
270
+	{0x00008334, 0x00000e00},
271
+	{0x00008338, 0x00070000},
272
+	{0x0000833c, 0x00000000},
273
+	{0x00008340, 0x000107ff},
274
+	{0x00009808, 0x00000000},
275
+	{0x0000980c, 0xad848e19},
276
+	{0x00009810, 0x7d14e000},
277
+	{0x00009814, 0x9c0a9f6b},
278
+	{0x0000981c, 0x00000000},
279
+	{0x0000982c, 0x0000a000},
280
+	{0x00009830, 0x00000000},
281
+	{0x0000983c, 0x00200400},
282
+	{0x00009840, 0x206a002e},
283
+	{0x0000984c, 0x1284233c},
284
+	{0x00009854, 0x00000859},
285
+	{0x00009900, 0x00000000},
286
+	{0x00009904, 0x00000000},
287
+	{0x00009908, 0x00000000},
288
+	{0x0000990c, 0x00000000},
289
+	{0x0000991c, 0x10000fff},
290
+	{0x00009920, 0x05100000},
291
+	{0x0000a920, 0x05100000},
292
+	{0x0000b920, 0x05100000},
293
+	{0x00009928, 0x00000001},
294
+	{0x0000992c, 0x00000004},
295
+	{0x00009934, 0x1e1f2022},
296
+	{0x00009938, 0x0a0b0c0d},
297
+	{0x0000993c, 0x00000000},
298
+	{0x00009948, 0x9280b212},
299
+	{0x0000994c, 0x00020028},
300
+	{0x00009954, 0x5d50e188},
301
+	{0x00009958, 0x00081fff},
302
+	{0x0000c95c, 0x004b6a8e},
303
+	{0x0000c968, 0x000003ce},
304
+	{0x00009970, 0x190fb515},
305
+	{0x00009974, 0x00000000},
306
+	{0x00009978, 0x00000001},
307
+	{0x0000997c, 0x00000000},
308
+	{0x00009980, 0x00000000},
309
+	{0x00009984, 0x00000000},
310
+	{0x00009988, 0x00000000},
311
+	{0x0000998c, 0x00000000},
312
+	{0x00009990, 0x00000000},
313
+	{0x00009994, 0x00000000},
314
+	{0x00009998, 0x00000000},
315
+	{0x0000999c, 0x00000000},
316
+	{0x000099a0, 0x00000000},
317
+	{0x000099a4, 0x00000001},
318
+	{0x000099a8, 0x001fff00},
319
+	{0x000099ac, 0x00000000},
320
+	{0x000099b0, 0x03051000},
321
+	{0x000099dc, 0x00000000},
322
+	{0x000099e0, 0x00000200},
323
+	{0x000099e4, 0xaaaaaaaa},
324
+	{0x000099e8, 0x3c466478},
325
+	{0x000099ec, 0x000000aa},
326
+	{0x000099fc, 0x00001042},
327
+	{0x00009b00, 0x00000000},
328
+	{0x00009b04, 0x00000001},
329
+	{0x00009b08, 0x00000002},
330
+	{0x00009b0c, 0x00000003},
331
+	{0x00009b10, 0x00000004},
332
+	{0x00009b14, 0x00000005},
333
+	{0x00009b18, 0x00000008},
334
+	{0x00009b1c, 0x00000009},
335
+	{0x00009b20, 0x0000000a},
336
+	{0x00009b24, 0x0000000b},
337
+	{0x00009b28, 0x0000000c},
338
+	{0x00009b2c, 0x0000000d},
339
+	{0x00009b30, 0x00000010},
340
+	{0x00009b34, 0x00000011},
341
+	{0x00009b38, 0x00000012},
342
+	{0x00009b3c, 0x00000013},
343
+	{0x00009b40, 0x00000014},
344
+	{0x00009b44, 0x00000015},
345
+	{0x00009b48, 0x00000018},
346
+	{0x00009b4c, 0x00000019},
347
+	{0x00009b50, 0x0000001a},
348
+	{0x00009b54, 0x0000001b},
349
+	{0x00009b58, 0x0000001c},
350
+	{0x00009b5c, 0x0000001d},
351
+	{0x00009b60, 0x00000020},
352
+	{0x00009b64, 0x00000021},
353
+	{0x00009b68, 0x00000022},
354
+	{0x00009b6c, 0x00000023},
355
+	{0x00009b70, 0x00000024},
356
+	{0x00009b74, 0x00000025},
357
+	{0x00009b78, 0x00000028},
358
+	{0x00009b7c, 0x00000029},
359
+	{0x00009b80, 0x0000002a},
360
+	{0x00009b84, 0x0000002b},
361
+	{0x00009b88, 0x0000002c},
362
+	{0x00009b8c, 0x0000002d},
363
+	{0x00009b90, 0x00000030},
364
+	{0x00009b94, 0x00000031},
365
+	{0x00009b98, 0x00000032},
366
+	{0x00009b9c, 0x00000033},
367
+	{0x00009ba0, 0x00000034},
368
+	{0x00009ba4, 0x00000035},
369
+	{0x00009ba8, 0x00000035},
370
+	{0x00009bac, 0x00000035},
371
+	{0x00009bb0, 0x00000035},
372
+	{0x00009bb4, 0x00000035},
373
+	{0x00009bb8, 0x00000035},
374
+	{0x00009bbc, 0x00000035},
375
+	{0x00009bc0, 0x00000035},
376
+	{0x00009bc4, 0x00000035},
377
+	{0x00009bc8, 0x00000035},
378
+	{0x00009bcc, 0x00000035},
379
+	{0x00009bd0, 0x00000035},
380
+	{0x00009bd4, 0x00000035},
381
+	{0x00009bd8, 0x00000035},
382
+	{0x00009bdc, 0x00000035},
383
+	{0x00009be0, 0x00000035},
384
+	{0x00009be4, 0x00000035},
385
+	{0x00009be8, 0x00000035},
386
+	{0x00009bec, 0x00000035},
387
+	{0x00009bf0, 0x00000035},
388
+	{0x00009bf4, 0x00000035},
389
+	{0x00009bf8, 0x00000010},
390
+	{0x00009bfc, 0x0000001a},
391
+	{0x0000a210, 0x40806333},
392
+	{0x0000a214, 0x00106c10},
393
+	{0x0000a218, 0x009c4060},
394
+	{0x0000a220, 0x018830c6},
395
+	{0x0000a224, 0x00000400},
396
+	{0x0000a228, 0x00000bb5},
397
+	{0x0000a22c, 0x00000011},
398
+	{0x0000a234, 0x20202020},
399
+	{0x0000a238, 0x20202020},
400
+	{0x0000a23c, 0x13c889af},
401
+	{0x0000a240, 0x38490a20},
402
+	{0x0000a244, 0x00007bb6},
403
+	{0x0000a248, 0x0fff3ffc},
404
+	{0x0000a24c, 0x00000001},
405
+	{0x0000a250, 0x0000a000},
406
+	{0x0000a254, 0x00000000},
407
+	{0x0000a258, 0x0cc75380},
408
+	{0x0000a25c, 0x0f0f0f01},
409
+	{0x0000a260, 0xdfa91f01},
410
+	{0x0000a268, 0x00000000},
411
+	{0x0000a26c, 0x0e79e5c6},
412
+	{0x0000b26c, 0x0e79e5c6},
413
+	{0x0000c26c, 0x0e79e5c6},
414
+	{0x0000d270, 0x00820820},
415
+	{0x0000a278, 0x1ce739ce},
416
+	{0x0000a27c, 0x051701ce},
417
+	{0x0000a338, 0x00000000},
418
+	{0x0000a33c, 0x00000000},
419
+	{0x0000a340, 0x00000000},
420
+	{0x0000a344, 0x00000000},
421
+	{0x0000a348, 0x3fffffff},
422
+	{0x0000a34c, 0x3fffffff},
423
+	{0x0000a350, 0x3fffffff},
424
+	{0x0000a354, 0x0003ffff},
425
+	{0x0000a358, 0x79a8aa1f},
426
+	{0x0000d35c, 0x07ffffef},
427
+	{0x0000d360, 0x0fffffe7},
428
+	{0x0000d364, 0x17ffffe5},
429
+	{0x0000d368, 0x1fffffe4},
430
+	{0x0000d36c, 0x37ffffe3},
431
+	{0x0000d370, 0x3fffffe3},
432
+	{0x0000d374, 0x57ffffe3},
433
+	{0x0000d378, 0x5fffffe2},
434
+	{0x0000d37c, 0x7fffffe2},
435
+	{0x0000d380, 0x7f3c7bba},
436
+	{0x0000d384, 0xf3307ff0},
437
+	{0x0000a388, 0x08000000},
438
+	{0x0000a38c, 0x20202020},
439
+	{0x0000a390, 0x20202020},
440
+	{0x0000a394, 0x1ce739ce},
441
+	{0x0000a398, 0x000001ce},
442
+	{0x0000a39c, 0x00000001},
443
+	{0x0000a3a0, 0x00000000},
444
+	{0x0000a3a4, 0x00000000},
445
+	{0x0000a3a8, 0x00000000},
446
+	{0x0000a3ac, 0x00000000},
447
+	{0x0000a3b0, 0x00000000},
448
+	{0x0000a3b4, 0x00000000},
449
+	{0x0000a3b8, 0x00000000},
450
+	{0x0000a3bc, 0x00000000},
451
+	{0x0000a3c0, 0x00000000},
452
+	{0x0000a3c4, 0x00000000},
453
+	{0x0000a3c8, 0x00000246},
454
+	{0x0000a3cc, 0x20202020},
455
+	{0x0000a3d0, 0x20202020},
456
+	{0x0000a3d4, 0x20202020},
457
+	{0x0000a3dc, 0x1ce739ce},
458
+	{0x0000a3e0, 0x000001ce},
459
+};
460
+
461
+static const u32 ar5416Bank0[][2] = {
462
+	/* Addr      allmodes  */
463
+	{0x000098b0, 0x1e5795e5},
464
+	{0x000098e0, 0x02008020},
465
+};
466
+
467
+static const u32 ar5416BB_RfGain[][3] = {
468
+	/* Addr      5G_HT20     5G_HT40   */
469
+	{0x00009a00, 0x00000000, 0x00000000},
470
+	{0x00009a04, 0x00000040, 0x00000040},
471
+	{0x00009a08, 0x00000080, 0x00000080},
472
+	{0x00009a0c, 0x000001a1, 0x00000141},
473
+	{0x00009a10, 0x000001e1, 0x00000181},
474
+	{0x00009a14, 0x00000021, 0x000001c1},
475
+	{0x00009a18, 0x00000061, 0x00000001},
476
+	{0x00009a1c, 0x00000168, 0x00000041},
477
+	{0x00009a20, 0x000001a8, 0x000001a8},
478
+	{0x00009a24, 0x000001e8, 0x000001e8},
479
+	{0x00009a28, 0x00000028, 0x00000028},
480
+	{0x00009a2c, 0x00000068, 0x00000068},
481
+	{0x00009a30, 0x00000189, 0x000000a8},
482
+	{0x00009a34, 0x000001c9, 0x00000169},
483
+	{0x00009a38, 0x00000009, 0x000001a9},
484
+	{0x00009a3c, 0x00000049, 0x000001e9},
485
+	{0x00009a40, 0x00000089, 0x00000029},
486
+	{0x00009a44, 0x00000170, 0x00000069},
487
+	{0x00009a48, 0x000001b0, 0x00000190},
488
+	{0x00009a4c, 0x000001f0, 0x000001d0},
489
+	{0x00009a50, 0x00000030, 0x00000010},
490
+	{0x00009a54, 0x00000070, 0x00000050},
491
+	{0x00009a58, 0x00000191, 0x00000090},
492
+	{0x00009a5c, 0x000001d1, 0x00000151},
493
+	{0x00009a60, 0x00000011, 0x00000191},
494
+	{0x00009a64, 0x00000051, 0x000001d1},
495
+	{0x00009a68, 0x00000091, 0x00000011},
496
+	{0x00009a6c, 0x000001b8, 0x00000051},
497
+	{0x00009a70, 0x000001f8, 0x00000198},
498
+	{0x00009a74, 0x00000038, 0x000001d8},
499
+	{0x00009a78, 0x00000078, 0x00000018},
500
+	{0x00009a7c, 0x00000199, 0x00000058},
501
+	{0x00009a80, 0x000001d9, 0x00000098},
502
+	{0x00009a84, 0x00000019, 0x00000159},
503
+	{0x00009a88, 0x00000059, 0x00000199},
504
+	{0x00009a8c, 0x00000099, 0x000001d9},
505
+	{0x00009a90, 0x000000d9, 0x00000019},
506
+	{0x00009a94, 0x000000f9, 0x00000059},
507
+	{0x00009a98, 0x000000f9, 0x00000099},
508
+	{0x00009a9c, 0x000000f9, 0x000000d9},
509
+	{0x00009aa0, 0x000000f9, 0x000000f9},
510
+	{0x00009aa4, 0x000000f9, 0x000000f9},
511
+	{0x00009aa8, 0x000000f9, 0x000000f9},
512
+	{0x00009aac, 0x000000f9, 0x000000f9},
513
+	{0x00009ab0, 0x000000f9, 0x000000f9},
514
+	{0x00009ab4, 0x000000f9, 0x000000f9},
515
+	{0x00009ab8, 0x000000f9, 0x000000f9},
516
+	{0x00009abc, 0x000000f9, 0x000000f9},
517
+	{0x00009ac0, 0x000000f9, 0x000000f9},
518
+	{0x00009ac4, 0x000000f9, 0x000000f9},
519
+	{0x00009ac8, 0x000000f9, 0x000000f9},
520
+	{0x00009acc, 0x000000f9, 0x000000f9},
521
+	{0x00009ad0, 0x000000f9, 0x000000f9},
522
+	{0x00009ad4, 0x000000f9, 0x000000f9},
523
+	{0x00009ad8, 0x000000f9, 0x000000f9},
524
+	{0x00009adc, 0x000000f9, 0x000000f9},
525
+	{0x00009ae0, 0x000000f9, 0x000000f9},
526
+	{0x00009ae4, 0x000000f9, 0x000000f9},
527
+	{0x00009ae8, 0x000000f9, 0x000000f9},
528
+	{0x00009aec, 0x000000f9, 0x000000f9},
529
+	{0x00009af0, 0x000000f9, 0x000000f9},
530
+	{0x00009af4, 0x000000f9, 0x000000f9},
531
+	{0x00009af8, 0x000000f9, 0x000000f9},
532
+	{0x00009afc, 0x000000f9, 0x000000f9},
533
+};
534
+
535
+static const u32 ar5416Bank1[][2] = {
536
+	/* Addr      allmodes  */
537
+	{0x000098b0, 0x02108421},
538
+	{0x000098ec, 0x00000008},
539
+};
540
+
541
+static const u32 ar5416Bank2[][2] = {
542
+	/* Addr      allmodes  */
543
+	{0x000098b0, 0x0e73ff17},
544
+	{0x000098e0, 0x00000420},
545
+};
546
+
547
+static const u32 ar5416Bank3[][3] = {
548
+	/* Addr      5G_HT20     5G_HT40   */
549
+	{0x000098f0, 0x01400018, 0x01c00018},
550
+};
551
+
552
+static const u32 ar5416Bank6[][3] = {
553
+	/* Addr      5G_HT20     5G_HT40   */
554
+	{0x0000989c, 0x00000000, 0x00000000},
555
+	{0x0000989c, 0x00000000, 0x00000000},
556
+	{0x0000989c, 0x00000000, 0x00000000},
557
+	{0x0000989c, 0x00e00000, 0x00e00000},
558
+	{0x0000989c, 0x005e0000, 0x005e0000},
559
+	{0x0000989c, 0x00120000, 0x00120000},
560
+	{0x0000989c, 0x00620000, 0x00620000},
561
+	{0x0000989c, 0x00020000, 0x00020000},
562
+	{0x0000989c, 0x00ff0000, 0x00ff0000},
563
+	{0x0000989c, 0x00ff0000, 0x00ff0000},
564
+	{0x0000989c, 0x00ff0000, 0x00ff0000},
565
+	{0x0000989c, 0x40ff0000, 0x40ff0000},
566
+	{0x0000989c, 0x005f0000, 0x005f0000},
567
+	{0x0000989c, 0x00870000, 0x00870000},
568
+	{0x0000989c, 0x00f90000, 0x00f90000},
569
+	{0x0000989c, 0x007b0000, 0x007b0000},
570
+	{0x0000989c, 0x00ff0000, 0x00ff0000},
571
+	{0x0000989c, 0x00f50000, 0x00f50000},
572
+	{0x0000989c, 0x00dc0000, 0x00dc0000},
573
+	{0x0000989c, 0x00110000, 0x00110000},
574
+	{0x0000989c, 0x006100a8, 0x006100a8},
575
+	{0x0000989c, 0x004210a2, 0x004210a2},
576
+	{0x0000989c, 0x0014008f, 0x0014008f},
577
+	{0x0000989c, 0x00c40003, 0x00c40003},
578
+	{0x0000989c, 0x003000f2, 0x003000f2},
579
+	{0x0000989c, 0x00440016, 0x00440016},
580
+	{0x0000989c, 0x00410040, 0x00410040},
581
+	{0x0000989c, 0x0001805e, 0x0001805e},
582
+	{0x0000989c, 0x0000c0ab, 0x0000c0ab},
583
+	{0x0000989c, 0x000000f1, 0x000000f1},
584
+	{0x0000989c, 0x00002081, 0x00002081},
585
+	{0x0000989c, 0x000000d4, 0x000000d4},
586
+	{0x000098d0, 0x0000000f, 0x0010000f},
587
+};
588
+
589
+static const u32 ar5416Bank6TPC[][3] = {
590
+	/* Addr      5G_HT20     5G_HT40   */
591
+	{0x0000989c, 0x00000000, 0x00000000},
592
+	{0x0000989c, 0x00000000, 0x00000000},
593
+	{0x0000989c, 0x00000000, 0x00000000},
594
+	{0x0000989c, 0x00e00000, 0x00e00000},
595
+	{0x0000989c, 0x005e0000, 0x005e0000},
596
+	{0x0000989c, 0x00120000, 0x00120000},
597
+	{0x0000989c, 0x00620000, 0x00620000},
598
+	{0x0000989c, 0x00020000, 0x00020000},
599
+	{0x0000989c, 0x00ff0000, 0x00ff0000},
600
+	{0x0000989c, 0x00ff0000, 0x00ff0000},
601
+	{0x0000989c, 0x00ff0000, 0x00ff0000},
602
+	{0x0000989c, 0x40ff0000, 0x40ff0000},
603
+	{0x0000989c, 0x005f0000, 0x005f0000},
604
+	{0x0000989c, 0x00870000, 0x00870000},
605
+	{0x0000989c, 0x00f90000, 0x00f90000},
606
+	{0x0000989c, 0x007b0000, 0x007b0000},
607
+	{0x0000989c, 0x00ff0000, 0x00ff0000},
608
+	{0x0000989c, 0x00f50000, 0x00f50000},
609
+	{0x0000989c, 0x00dc0000, 0x00dc0000},
610
+	{0x0000989c, 0x00110000, 0x00110000},
611
+	{0x0000989c, 0x006100a8, 0x006100a8},
612
+	{0x0000989c, 0x00423022, 0x00423022},
613
+	{0x0000989c, 0x201400df, 0x201400df},
614
+	{0x0000989c, 0x00c40002, 0x00c40002},
615
+	{0x0000989c, 0x003000f2, 0x003000f2},
616
+	{0x0000989c, 0x00440016, 0x00440016},
617
+	{0x0000989c, 0x00410040, 0x00410040},
618
+	{0x0000989c, 0x0001805e, 0x0001805e},
619
+	{0x0000989c, 0x0000c0ab, 0x0000c0ab},
620
+	{0x0000989c, 0x000000e1, 0x000000e1},
621
+	{0x0000989c, 0x00007081, 0x00007081},
622
+	{0x0000989c, 0x000000d4, 0x000000d4},
623
+	{0x000098d0, 0x0000000f, 0x0010000f},
624
+};
625
+
626
+static const u32 ar5416Bank7[][2] = {
627
+	/* Addr      allmodes  */
628
+	{0x0000989c, 0x00000500},
629
+	{0x0000989c, 0x00000800},
630
+	{0x000098cc, 0x0000000e},
631
+};
632
+
633
+static const u32 ar5416Addac[][2] = {
634
+	/* Addr      allmodes  */
635
+	{0x0000989c, 0x00000000},
636
+	{0x0000989c, 0x00000003},
637
+	{0x0000989c, 0x00000000},
638
+	{0x0000989c, 0x0000000c},
639
+	{0x0000989c, 0x00000000},
640
+	{0x0000989c, 0x00000030},
641
+	{0x0000989c, 0x00000000},
642
+	{0x0000989c, 0x00000000},
643
+	{0x0000989c, 0x00000000},
644
+	{0x0000989c, 0x00000000},
645
+	{0x0000989c, 0x00000000},
646
+	{0x0000989c, 0x00000000},
647
+	{0x0000989c, 0x00000000},
648
+	{0x0000989c, 0x00000000},
649
+	{0x0000989c, 0x00000000},
650
+	{0x0000989c, 0x00000000},
651
+	{0x0000989c, 0x00000000},
652
+	{0x0000989c, 0x00000000},
653
+	{0x0000989c, 0x00000060},
654
+	{0x0000989c, 0x00000000},
655
+	{0x0000989c, 0x00000000},
656
+	{0x0000989c, 0x00000000},
657
+	{0x0000989c, 0x00000000},
658
+	{0x0000989c, 0x00000000},
659
+	{0x0000989c, 0x00000000},
660
+	{0x0000989c, 0x00000000},
661
+	{0x0000989c, 0x00000000},
662
+	{0x0000989c, 0x00000000},
663
+	{0x0000989c, 0x00000000},
664
+	{0x0000989c, 0x00000000},
665
+	{0x0000989c, 0x00000000},
666
+	{0x0000989c, 0x00000058},
667
+	{0x0000989c, 0x00000000},
668
+	{0x0000989c, 0x00000000},
669
+	{0x0000989c, 0x00000000},
670
+	{0x0000989c, 0x00000000},
671
+	{0x000098cc, 0x00000000},
672
+};

+ 1356
- 0
src/drivers/net/ath/ath9k/ar9001_initvals.h
File diff suppressed because it is too large
View File


+ 3264
- 0
src/drivers/net/ath/ath9k/ar9002_initvals.h
File diff suppressed because it is too large
View File


+ 613
- 0
src/drivers/net/ath/ath9k/ar9002_phy.h View File

@@ -0,0 +1,613 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+#ifndef AR9002_PHY_H
17
+#define AR9002_PHY_H
18
+
19
+#define AR_PHY_TEST             0x9800
20
+#define PHY_AGC_CLR             0x10000000
21
+#define RFSILENT_BB             0x00002000
22
+
23
+#define AR_PHY_TURBO                0x9804
24
+#define AR_PHY_FC_TURBO_MODE        0x00000001
25
+#define AR_PHY_FC_TURBO_SHORT       0x00000002
26
+#define AR_PHY_FC_DYN2040_EN        0x00000004
27
+#define AR_PHY_FC_DYN2040_PRI_ONLY  0x00000008
28
+#define AR_PHY_FC_DYN2040_PRI_CH    0x00000010
29
+/* For 25 MHz channel spacing -- not used but supported by hw */
30
+#define AR_PHY_FC_DYN2040_EXT_CH    0x00000020
31
+#define AR_PHY_FC_HT_EN             0x00000040
32
+#define AR_PHY_FC_SHORT_GI_40       0x00000080
33
+#define AR_PHY_FC_WALSH             0x00000100
34
+#define AR_PHY_FC_SINGLE_HT_LTF1    0x00000200
35
+#define AR_PHY_FC_ENABLE_DAC_FIFO   0x00000800
36
+
37
+#define AR_PHY_TEST2			0x9808
38
+
39
+#define AR_PHY_TIMING2           0x9810
40
+#define AR_PHY_TIMING3           0x9814
41
+#define AR_PHY_TIMING3_DSC_MAN   0xFFFE0000
42
+#define AR_PHY_TIMING3_DSC_MAN_S 17
43
+#define AR_PHY_TIMING3_DSC_EXP   0x0001E000
44
+#define AR_PHY_TIMING3_DSC_EXP_S 13
45
+
46
+#define AR_PHY_CHIP_ID_REV_0      0x80
47
+#define AR_PHY_CHIP_ID_REV_1      0x81
48
+#define AR_PHY_CHIP_ID_9160_REV_0 0xb0
49
+
50
+#define AR_PHY_ACTIVE       0x981C
51
+#define AR_PHY_ACTIVE_EN    0x00000001
52
+#define AR_PHY_ACTIVE_DIS   0x00000000
53
+
54
+#define AR_PHY_RF_CTL2             0x9824
55
+#define AR_PHY_TX_END_DATA_START   0x000000FF
56
+#define AR_PHY_TX_END_DATA_START_S 0
57
+#define AR_PHY_TX_END_PA_ON        0x0000FF00
58
+#define AR_PHY_TX_END_PA_ON_S      8
59
+
60
+#define AR_PHY_RF_CTL3                  0x9828
61
+#define AR_PHY_TX_END_TO_A2_RX_ON       0x00FF0000
62
+#define AR_PHY_TX_END_TO_A2_RX_ON_S     16
63
+
64
+#define AR_PHY_ADC_CTL                  0x982C
65
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN    0x00000003
66
+#define AR_PHY_ADC_CTL_OFF_INBUFGAIN_S  0
67
+#define AR_PHY_ADC_CTL_OFF_PWDDAC       0x00002000
68
+#define AR_PHY_ADC_CTL_OFF_PWDBANDGAP   0x00004000
69
+#define AR_PHY_ADC_CTL_OFF_PWDADC       0x00008000
70
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN     0x00030000
71
+#define AR_PHY_ADC_CTL_ON_INBUFGAIN_S   16
72
+
73
+#define AR_PHY_ADC_SERIAL_CTL       0x9830
74
+#define AR_PHY_SEL_INTERNAL_ADDAC   0x00000000
75
+#define AR_PHY_SEL_EXTERNAL_RADIO   0x00000001
76
+
77
+#define AR_PHY_RF_CTL4                    0x9834
78
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF    0xFF000000
79
+#define AR_PHY_RF_CTL4_TX_END_XPAB_OFF_S  24
80
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF    0x00FF0000
81
+#define AR_PHY_RF_CTL4_TX_END_XPAA_OFF_S  16
82
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON      0x0000FF00
83
+#define AR_PHY_RF_CTL4_FRAME_XPAB_ON_S    8
84
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON      0x000000FF
85
+#define AR_PHY_RF_CTL4_FRAME_XPAA_ON_S    0
86
+
87
+#define AR_PHY_TSTDAC_CONST               0x983c
88
+
89
+#define AR_PHY_SETTLING          0x9844
90
+#define AR_PHY_SETTLING_SWITCH   0x00003F80
91
+#define AR_PHY_SETTLING_SWITCH_S 7
92
+
93
+#define AR_PHY_RXGAIN                   0x9848
94
+#define AR_PHY_RXGAIN_TXRX_ATTEN        0x0003F000
95
+#define AR_PHY_RXGAIN_TXRX_ATTEN_S      12
96
+#define AR_PHY_RXGAIN_TXRX_RF_MAX       0x007C0000
97
+#define AR_PHY_RXGAIN_TXRX_RF_MAX_S     18
98
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN    0x00003F80
99
+#define AR9280_PHY_RXGAIN_TXRX_ATTEN_S  7
100
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN   0x001FC000
101
+#define AR9280_PHY_RXGAIN_TXRX_MARGIN_S 14
102
+
103
+#define AR_PHY_DESIRED_SZ           0x9850
104
+#define AR_PHY_DESIRED_SZ_ADC       0x000000FF
105
+#define AR_PHY_DESIRED_SZ_ADC_S     0
106
+#define AR_PHY_DESIRED_SZ_PGA       0x0000FF00
107
+#define AR_PHY_DESIRED_SZ_PGA_S     8
108
+#define AR_PHY_DESIRED_SZ_TOT_DES   0x0FF00000
109
+#define AR_PHY_DESIRED_SZ_TOT_DES_S 20
110
+
111
+#define AR_PHY_FIND_SIG           0x9858
112
+#define AR_PHY_FIND_SIG_FIRSTEP   0x0003F000
113
+#define AR_PHY_FIND_SIG_FIRSTEP_S 12
114
+#define AR_PHY_FIND_SIG_FIRPWR    0x03FC0000
115
+#define AR_PHY_FIND_SIG_FIRPWR_S  18
116
+
117
+#define AR_PHY_FIND_SIG_LOW           0x9840
118
+#define AR_PHY_FIND_SIG_FIRSTEP_LOW   0x00000FC0L
119
+#define AR_PHY_FIND_SIG_FIRSTEP_LOW_S 6
120
+
121
+#define AR_PHY_AGC_CTL1                  0x985C
122
+#define AR_PHY_AGC_CTL1_COARSE_LOW       0x00007F80
123
+#define AR_PHY_AGC_CTL1_COARSE_LOW_S     7
124
+#define AR_PHY_AGC_CTL1_COARSE_HIGH      0x003F8000
125
+#define AR_PHY_AGC_CTL1_COARSE_HIGH_S    15
126
+
127
+#define AR_PHY_CCA                  0x9864
128
+#define AR_PHY_MINCCA_PWR           0x0FF80000
129
+#define AR_PHY_MINCCA_PWR_S         19
130
+#define AR_PHY_CCA_THRESH62         0x0007F000
131
+#define AR_PHY_CCA_THRESH62_S       12
132
+#define AR9280_PHY_MINCCA_PWR       0x1FF00000
133
+#define AR9280_PHY_MINCCA_PWR_S     20
134
+#define AR9280_PHY_CCA_THRESH62     0x000FF000
135
+#define AR9280_PHY_CCA_THRESH62_S   12
136
+
137
+#define AR_PHY_SFCORR_LOW                    0x986C
138
+#define AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW  0x00000001
139
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW    0x00003F00
140
+#define AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW_S  8
141
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW      0x001FC000
142
+#define AR_PHY_SFCORR_LOW_M1_THRESH_LOW_S    14
143
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW      0x0FE00000
144
+#define AR_PHY_SFCORR_LOW_M2_THRESH_LOW_S    21
145
+
146
+#define AR_PHY_SFCORR                0x9868
147
+#define AR_PHY_SFCORR_M2COUNT_THR    0x0000001F
148
+#define AR_PHY_SFCORR_M2COUNT_THR_S  0
149
+#define AR_PHY_SFCORR_M1_THRESH      0x00FE0000
150
+#define AR_PHY_SFCORR_M1_THRESH_S    17
151
+#define AR_PHY_SFCORR_M2_THRESH      0x7F000000
152
+#define AR_PHY_SFCORR_M2_THRESH_S    24
153
+
154
+#define AR_PHY_SLEEP_CTR_CONTROL    0x9870
155
+#define AR_PHY_SLEEP_CTR_LIMIT      0x9874
156
+#define AR_PHY_SYNTH_CONTROL        0x9874
157
+#define AR_PHY_SLEEP_SCAL           0x9878
158
+
159
+#define AR_PHY_PLL_CTL          0x987c
160
+#define AR_PHY_PLL_CTL_40       0xaa
161
+#define AR_PHY_PLL_CTL_40_5413  0x04
162
+#define AR_PHY_PLL_CTL_44       0xab
163
+#define AR_PHY_PLL_CTL_44_2133  0xeb
164
+#define AR_PHY_PLL_CTL_40_2133  0xea
165
+
166
+#define AR_PHY_SPECTRAL_SCAN			0x9910  /* AR9280 spectral scan configuration register */
167
+#define	AR_PHY_SPECTRAL_SCAN_ENABLE		0x1
168
+#define AR_PHY_SPECTRAL_SCAN_ENA		0x00000001  /* Enable spectral scan, reg 68, bit 0 */
169
+#define AR_PHY_SPECTRAL_SCAN_ENA_S		0  /* Enable spectral scan, reg 68, bit 0 */
170
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE		0x00000002  /* Activate spectral scan reg 68, bit 1*/
171
+#define AR_PHY_SPECTRAL_SCAN_ACTIVE_S		1  /* Activate spectral scan reg 68, bit 1*/
172
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD		0x000000F0  /* Interval for FFT reports, reg 68, bits 4-7*/
173
+#define AR_PHY_SPECTRAL_SCAN_FFT_PERIOD_S	4
174
+#define AR_PHY_SPECTRAL_SCAN_PERIOD		0x0000FF00  /* Interval for FFT reports, reg 68, bits 8-15*/
175
+#define AR_PHY_SPECTRAL_SCAN_PERIOD_S		8
176
+#define AR_PHY_SPECTRAL_SCAN_COUNT		0x00FF0000  /* Number of reports, reg 68, bits 16-23*/
177
+#define AR_PHY_SPECTRAL_SCAN_COUNT_S		16
178
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT	0x01000000  /* Short repeat, reg 68, bit 24*/
179
+#define AR_PHY_SPECTRAL_SCAN_SHORT_REPEAT_S	24  /* Short repeat, reg 68, bit 24*/
180
+
181
+#define AR_PHY_RX_DELAY           0x9914
182
+#define AR_PHY_SEARCH_START_DELAY 0x9918
183
+#define AR_PHY_RX_DELAY_DELAY     0x00003FFF
184
+
185
+#define AR_PHY_TIMING_CTRL4(_i)     (0x9920 + ((_i) << 12))
186
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF 0x01F
187
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF_S   0
188
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF 0x7E0
189
+#define AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF_S   5
190
+#define AR_PHY_TIMING_CTRL4_IQCORR_ENABLE   0x800
191
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX 0xF000
192
+#define AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX_S   12
193
+#define AR_PHY_TIMING_CTRL4_DO_CAL    0x10000
194
+
195
+#define AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI	0x80000000
196
+#define	AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER	0x40000000
197
+#define	AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK	0x20000000
198
+#define	AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK	0x10000000
199
+
200
+#define AR_PHY_TIMING5               0x9924
201
+#define AR_PHY_TIMING5_CYCPWR_THR1   0x000000FE
202
+#define AR_PHY_TIMING5_CYCPWR_THR1_S 1
203
+
204
+#define AR_PHY_POWER_TX_RATE1               0x9934
205
+#define AR_PHY_POWER_TX_RATE2               0x9938
206
+#define AR_PHY_POWER_TX_RATE_MAX            0x993c
207
+#define AR_PHY_POWER_TX_RATE_MAX_TPC_ENABLE 0x00000040
208
+
209
+#define AR_PHY_FRAME_CTL            0x9944
210
+#define AR_PHY_FRAME_CTL_TX_CLIP    0x00000038
211
+#define AR_PHY_FRAME_CTL_TX_CLIP_S  3
212
+
213
+#define AR_PHY_TXPWRADJ                   0x994C
214
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA    0x00000FC0
215
+#define AR_PHY_TXPWRADJ_CCK_GAIN_DELTA_S  6
216
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX   0x00FC0000
217
+#define AR_PHY_TXPWRADJ_CCK_PCDAC_INDEX_S 18
218
+
219
+#define AR_PHY_RADAR_EXT      0x9940
220
+#define AR_PHY_RADAR_EXT_ENA  0x00004000
221
+
222
+#define AR_PHY_RADAR_0          0x9954
223
+#define AR_PHY_RADAR_0_ENA      0x00000001
224
+#define AR_PHY_RADAR_0_FFT_ENA  0x80000000
225
+#define AR_PHY_RADAR_0_INBAND   0x0000003e
226
+#define AR_PHY_RADAR_0_INBAND_S 1
227
+#define AR_PHY_RADAR_0_PRSSI    0x00000FC0
228
+#define AR_PHY_RADAR_0_PRSSI_S  6
229
+#define AR_PHY_RADAR_0_HEIGHT   0x0003F000
230
+#define AR_PHY_RADAR_0_HEIGHT_S 12
231
+#define AR_PHY_RADAR_0_RRSSI    0x00FC0000
232
+#define AR_PHY_RADAR_0_RRSSI_S  18
233
+#define AR_PHY_RADAR_0_FIRPWR   0x7F000000
234
+#define AR_PHY_RADAR_0_FIRPWR_S 24
235
+
236
+#define AR_PHY_RADAR_1                  0x9958
237
+#define AR_PHY_RADAR_1_RELPWR_ENA       0x00800000
238
+#define AR_PHY_RADAR_1_USE_FIR128       0x00400000
239
+#define AR_PHY_RADAR_1_RELPWR_THRESH    0x003F0000
240
+#define AR_PHY_RADAR_1_RELPWR_THRESH_S  16
241
+#define AR_PHY_RADAR_1_BLOCK_CHECK      0x00008000
242
+#define AR_PHY_RADAR_1_MAX_RRSSI        0x00004000
243
+#define AR_PHY_RADAR_1_RELSTEP_CHECK    0x00002000
244
+#define AR_PHY_RADAR_1_RELSTEP_THRESH   0x00001F00
245
+#define AR_PHY_RADAR_1_RELSTEP_THRESH_S 8
246
+#define AR_PHY_RADAR_1_MAXLEN           0x000000FF
247
+#define AR_PHY_RADAR_1_MAXLEN_S         0
248
+
249
+#define AR_PHY_SWITCH_CHAIN_0     0x9960
250
+#define AR_PHY_SWITCH_COM         0x9964
251
+
252
+#define AR_PHY_SIGMA_DELTA            0x996C
253
+#define AR_PHY_SIGMA_DELTA_ADC_SEL    0x00000003
254
+#define AR_PHY_SIGMA_DELTA_ADC_SEL_S  0
255
+#define AR_PHY_SIGMA_DELTA_FILT2      0x000000F8
256
+#define AR_PHY_SIGMA_DELTA_FILT2_S    3
257
+#define AR_PHY_SIGMA_DELTA_FILT1      0x00001F00
258
+#define AR_PHY_SIGMA_DELTA_FILT1_S    8
259
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP   0x01FFE000
260
+#define AR_PHY_SIGMA_DELTA_ADC_CLIP_S 13
261
+
262
+#define AR_PHY_RESTART          0x9970
263
+#define AR_PHY_RESTART_DIV_GC   0x001C0000
264
+#define AR_PHY_RESTART_DIV_GC_S 18
265
+
266
+#define AR_PHY_RFBUS_REQ        0x997C
267
+#define AR_PHY_RFBUS_REQ_EN     0x00000001
268
+
269
+#define	AR_PHY_TIMING7		        0x9980
270
+#define	AR_PHY_TIMING8		        0x9984
271
+#define	AR_PHY_TIMING8_PILOT_MASK_2	0x000FFFFF
272
+#define	AR_PHY_TIMING8_PILOT_MASK_2_S	0
273
+
274
+#define	AR_PHY_BIN_MASK2_1	0x9988
275
+#define	AR_PHY_BIN_MASK2_2	0x998c
276
+#define	AR_PHY_BIN_MASK2_3	0x9990
277
+#define	AR_PHY_BIN_MASK2_4	0x9994
278
+
279
+#define	AR_PHY_BIN_MASK_1	0x9900
280
+#define	AR_PHY_BIN_MASK_2	0x9904
281
+#define	AR_PHY_BIN_MASK_3	0x9908
282
+
283
+#define	AR_PHY_MASK_CTL		0x990c
284
+
285
+#define	AR_PHY_BIN_MASK2_4_MASK_4	0x00003FFF
286
+#define	AR_PHY_BIN_MASK2_4_MASK_4_S	0
287
+
288
+#define	AR_PHY_TIMING9		        0x9998
289
+#define	AR_PHY_TIMING10		        0x999c
290
+#define	AR_PHY_TIMING10_PILOT_MASK_2	0x000FFFFF
291
+#define	AR_PHY_TIMING10_PILOT_MASK_2_S	0
292
+
293
+#define	AR_PHY_TIMING11			        0x99a0
294
+#define	AR_PHY_TIMING11_SPUR_DELTA_PHASE	0x000FFFFF
295
+#define	AR_PHY_TIMING11_SPUR_DELTA_PHASE_S	0
296
+#define AR_PHY_TIMING11_USE_SPUR_IN_AGC		0x40000000
297
+#define AR_PHY_TIMING11_USE_SPUR_IN_SELFCOR	0x80000000
298
+
299
+#define AR_PHY_RX_CHAINMASK     0x99a4
300
+#define AR_PHY_NEW_ADC_DC_GAIN_CORR(_i) (0x99b4 + ((_i) << 12))
301
+#define AR_PHY_NEW_ADC_GAIN_CORR_ENABLE 0x40000000
302
+#define AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE 0x80000000
303
+
304
+#define AR_PHY_MULTICHAIN_GAIN_CTL          0x99ac
305
+#define AR_PHY_9285_FAST_DIV_BIAS	    0x00007E00
306
+#define AR_PHY_9285_FAST_DIV_BIAS_S	    9
307
+#define AR_PHY_9285_ANT_DIV_CTL_ALL         0x7f000000
308
+#define AR_PHY_9285_ANT_DIV_CTL             0x01000000
309
+#define AR_PHY_9285_ANT_DIV_CTL_S           24
310
+#define AR_PHY_9285_ANT_DIV_ALT_LNACONF     0x06000000
311
+#define AR_PHY_9285_ANT_DIV_ALT_LNACONF_S   25
312
+#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF    0x18000000
313
+#define AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S  27
314
+#define AR_PHY_9285_ANT_DIV_ALT_GAINTB      0x20000000
315
+#define AR_PHY_9285_ANT_DIV_ALT_GAINTB_S    29
316
+#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB     0x40000000
317
+#define AR_PHY_9285_ANT_DIV_MAIN_GAINTB_S   30
318
+#define AR_PHY_9285_ANT_DIV_LNA1            2
319
+#define AR_PHY_9285_ANT_DIV_LNA2            1
320
+#define AR_PHY_9285_ANT_DIV_LNA1_PLUS_LNA2  3
321
+#define AR_PHY_9285_ANT_DIV_LNA1_MINUS_LNA2 0
322
+#define AR_PHY_9285_ANT_DIV_GAINTB_0        0
323
+#define AR_PHY_9285_ANT_DIV_GAINTB_1        1
324
+
325
+#define AR_PHY_EXT_CCA0             0x99b8
326
+#define AR_PHY_EXT_CCA0_THRESH62    0x000000FF
327
+#define AR_PHY_EXT_CCA0_THRESH62_S  0
328
+
329
+#define AR_PHY_EXT_CCA                  0x99bc
330
+#define AR_PHY_EXT_CCA_CYCPWR_THR1      0x0000FE00
331
+#define AR_PHY_EXT_CCA_CYCPWR_THR1_S    9
332
+#define AR_PHY_EXT_CCA_THRESH62         0x007F0000
333
+#define AR_PHY_EXT_CCA_THRESH62_S       16
334
+#define AR_PHY_EXT_TIMING5_CYCPWR_THR1   0x0000FE00L
335
+#define AR_PHY_EXT_TIMING5_CYCPWR_THR1_S 9
336
+
337
+#define AR_PHY_EXT_MINCCA_PWR           0xFF800000
338
+#define AR_PHY_EXT_MINCCA_PWR_S         23
339
+#define AR9280_PHY_EXT_MINCCA_PWR       0x01FF0000
340
+#define AR9280_PHY_EXT_MINCCA_PWR_S     16
341
+
342
+#define AR_PHY_SFCORR_EXT                 0x99c0
343
+#define AR_PHY_SFCORR_EXT_M1_THRESH       0x0000007F
344
+#define AR_PHY_SFCORR_EXT_M1_THRESH_S     0
345
+#define AR_PHY_SFCORR_EXT_M2_THRESH       0x00003F80
346
+#define AR_PHY_SFCORR_EXT_M2_THRESH_S     7
347
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW   0x001FC000
348
+#define AR_PHY_SFCORR_EXT_M1_THRESH_LOW_S 14
349
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW   0x0FE00000
350
+#define AR_PHY_SFCORR_EXT_M2_THRESH_LOW_S 21
351
+#define AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S   28
352
+
353
+#define AR_PHY_HALFGI           0x99D0
354
+#define AR_PHY_HALFGI_DSC_MAN   0x0007FFF0
355
+#define AR_PHY_HALFGI_DSC_MAN_S 4
356
+#define AR_PHY_HALFGI_DSC_EXP   0x0000000F
357
+#define AR_PHY_HALFGI_DSC_EXP_S 0
358
+
359
+#define AR_PHY_CHAN_INFO_MEMORY               0x99DC
360
+#define AR_PHY_CHAN_INFO_MEMORY_CAPTURE_MASK  0x0001
361
+
362
+#define AR_PHY_HEAVY_CLIP_ENABLE         0x99E0
363
+
364
+#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS    0x99EC
365
+#define AR_PHY_RIFS_INIT_DELAY         0x03ff0000
366
+
367
+#define AR_PHY_M_SLEEP      0x99f0
368
+#define AR_PHY_REFCLKDLY    0x99f4
369
+#define AR_PHY_REFCLKPD     0x99f8
370
+
371
+#define AR_PHY_CALMODE      0x99f0
372
+
373
+#define AR_PHY_CALMODE_IQ           0x00000000
374
+#define AR_PHY_CALMODE_ADC_GAIN     0x00000001
375
+#define AR_PHY_CALMODE_ADC_DC_PER   0x00000002
376
+#define AR_PHY_CALMODE_ADC_DC_INIT  0x00000003
377
+
378
+#define AR_PHY_CAL_MEAS_0(_i)     (0x9c10 + ((_i) << 12))
379
+#define AR_PHY_CAL_MEAS_1(_i)     (0x9c14 + ((_i) << 12))
380
+#define AR_PHY_CAL_MEAS_2(_i)     (0x9c18 + ((_i) << 12))
381
+#define AR_PHY_CAL_MEAS_3(_i)     (0x9c1c + ((_i) << 12))
382
+
383
+#define AR_PHY_CURRENT_RSSI 0x9c1c
384
+#define AR9280_PHY_CURRENT_RSSI 0x9c3c
385
+
386
+#define AR_PHY_RFBUS_GRANT       0x9C20
387
+#define AR_PHY_RFBUS_GRANT_EN    0x00000001
388
+
389
+#define AR_PHY_CHAN_INFO_GAIN_DIFF             0x9CF4
390
+#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320
391
+
392
+#define AR_PHY_CHAN_INFO_GAIN          0x9CFC
393
+
394
+#define AR_PHY_MODE         0xA200
395
+#define AR_PHY_MODE_ASYNCFIFO 0x80
396
+#define AR_PHY_MODE_AR2133  0x08
397
+#define AR_PHY_MODE_AR5111  0x00
398
+#define AR_PHY_MODE_AR5112  0x08
399
+#define AR_PHY_MODE_DYNAMIC 0x04
400
+#define AR_PHY_MODE_RF2GHZ  0x02
401
+#define AR_PHY_MODE_RF5GHZ  0x00
402
+#define AR_PHY_MODE_CCK     0x01
403
+#define AR_PHY_MODE_OFDM    0x00
404
+#define AR_PHY_MODE_DYN_CCK_DISABLE 0x100
405
+
406
+#define AR_PHY_CCK_TX_CTRL       0xA204
407
+#define AR_PHY_CCK_TX_CTRL_JAPAN 0x00000010
408
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK         0x0000000C
409
+#define AR_PHY_CCK_TX_CTRL_TX_DAC_SCALE_CCK_S       2
410
+
411
+#define AR_PHY_CCK_DETECT                           0xA208
412
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK          0x0000003F
413
+#define AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK_S        0
414
+/* [12:6] settling time for antenna switch */
415
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME           0x00001FC0
416
+#define AR_PHY_CCK_DETECT_ANT_SWITCH_TIME_S         6
417
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV    0x2000
418
+#define AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV_S  13
419
+
420
+#define AR_PHY_GAIN_2GHZ                0xA20C
421
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN    0x00FC0000
422
+#define AR_PHY_GAIN_2GHZ_RXTX_MARGIN_S  18
423
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN     0x00003C00
424
+#define AR_PHY_GAIN_2GHZ_BSW_MARGIN_S   10
425
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN      0x0000001F
426
+#define AR_PHY_GAIN_2GHZ_BSW_ATTEN_S    0
427
+
428
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN     0x003E0000
429
+#define AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN_S   17
430
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN     0x0001F000
431
+#define AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN_S   12
432
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB         0x00000FC0
433
+#define AR_PHY_GAIN_2GHZ_XATTEN2_DB_S       6
434
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB         0x0000003F
435
+#define AR_PHY_GAIN_2GHZ_XATTEN1_DB_S       0
436
+
437
+#define AR_PHY_CCK_RXCTRL4  0xA21C
438
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT   0x01F80000
439
+#define AR_PHY_CCK_RXCTRL4_FREQ_EST_SHORT_S 19
440
+
441
+#define AR_PHY_DAG_CTRLCCK  0xA228
442
+#define AR_PHY_DAG_CTRLCCK_EN_RSSI_THR  0x00000200
443
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR     0x0001FC00
444
+#define AR_PHY_DAG_CTRLCCK_RSSI_THR_S   10
445
+
446
+#define AR_PHY_FORCE_CLKEN_CCK              0xA22C
447
+#define AR_PHY_FORCE_CLKEN_CCK_MRC_MUX      0x00000040
448
+
449
+#define AR_PHY_POWER_TX_RATE3   0xA234
450
+#define AR_PHY_POWER_TX_RATE4   0xA238
451
+
452
+#define AR_PHY_SCRM_SEQ_XR       0xA23C
453
+#define AR_PHY_HEADER_DETECT_XR  0xA240
454
+#define AR_PHY_CHIRP_DETECTED_XR 0xA244
455
+#define AR_PHY_BLUETOOTH         0xA254
456
+
457
+#define AR_PHY_TPCRG1   0xA258
458
+#define AR_PHY_TPCRG1_NUM_PD_GAIN   0x0000c000
459
+#define AR_PHY_TPCRG1_NUM_PD_GAIN_S 14
460
+
461
+#define AR_PHY_TPCRG1_PD_GAIN_1    0x00030000
462
+#define AR_PHY_TPCRG1_PD_GAIN_1_S  16
463
+#define AR_PHY_TPCRG1_PD_GAIN_2    0x000C0000
464
+#define AR_PHY_TPCRG1_PD_GAIN_2_S  18
465
+#define AR_PHY_TPCRG1_PD_GAIN_3    0x00300000
466
+#define AR_PHY_TPCRG1_PD_GAIN_3_S  20
467
+
468
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE   0x00400000
469
+#define AR_PHY_TPCRG1_PD_CAL_ENABLE_S 22
470
+
471
+#define AR_PHY_TX_PWRCTRL4       0xa264
472
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID     0x00000001
473
+#define AR_PHY_TX_PWRCTRL_PD_AVG_VALID_S   0
474
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT       0x000001FE
475
+#define AR_PHY_TX_PWRCTRL_PD_AVG_OUT_S     1
476
+
477
+#define AR_PHY_TX_PWRCTRL6_0     0xa270
478
+#define AR_PHY_TX_PWRCTRL6_1     0xb270
479
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE     0x03000000
480
+#define AR_PHY_TX_PWRCTRL_ERR_EST_MODE_S   24
481
+
482
+#define AR_PHY_TX_PWRCTRL7       0xa274
483
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN     0x01F80000
484
+#define AR_PHY_TX_PWRCTRL_INIT_TX_GAIN_S   19
485
+
486
+#define AR_PHY_TX_PWRCTRL8       0xa278
487
+
488
+#define AR_PHY_TX_PWRCTRL9       0xa27C
489
+
490
+#define AR_PHY_TX_PWRCTRL10       0xa394
491
+#define AR_PHY_TX_DESIRED_SCALE_CCK        0x00007C00
492
+#define AR_PHY_TX_DESIRED_SCALE_CCK_S      10
493
+#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL  0x80000000
494
+#define AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL_S 31
495
+
496
+#define AR_PHY_TX_GAIN_TBL1      0xa300
497
+#define AR_PHY_TX_GAIN                     0x0007F000
498
+#define AR_PHY_TX_GAIN_S                   12
499
+
500
+#define AR_PHY_CH0_TX_PWRCTRL11  0xa398
501
+#define AR_PHY_CH1_TX_PWRCTRL11  0xb398
502
+#define AR_PHY_CH0_TX_PWRCTRL12  0xa3dc
503
+#define AR_PHY_CH0_TX_PWRCTRL13  0xa3e0
504
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP   0x0000FC00
505
+#define AR_PHY_TX_PWRCTRL_OLPC_TEMP_COMP_S 10
506
+
507
+#define AR_PHY_VIT_MASK2_M_46_61 0xa3a0
508
+#define AR_PHY_MASK2_M_31_45     0xa3a4
509
+#define AR_PHY_MASK2_M_16_30     0xa3a8
510
+#define AR_PHY_MASK2_M_00_15     0xa3ac
511
+#define AR_PHY_MASK2_P_15_01     0xa3b8
512
+#define AR_PHY_MASK2_P_30_16     0xa3bc
513
+#define AR_PHY_MASK2_P_45_31     0xa3c0
514
+#define AR_PHY_MASK2_P_61_45     0xa3c4
515
+#define AR_PHY_SPUR_REG          0x994c
516
+
517
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL       (0xFF << 18)
518
+#define AR_PHY_SPUR_REG_MASK_RATE_CNTL_S     18
519
+
520
+#define AR_PHY_SPUR_REG_ENABLE_MASK_PPM      0x20000
521
+#define AR_PHY_SPUR_REG_MASK_RATE_SELECT     (0xFF << 9)
522
+#define AR_PHY_SPUR_REG_MASK_RATE_SELECT_S   9
523
+#define AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI 0x100
524
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH     0x7F
525
+#define AR_PHY_SPUR_REG_SPUR_RSSI_THRESH_S   0
526
+
527
+#define AR_PHY_PILOT_MASK_01_30   0xa3b0
528
+#define AR_PHY_PILOT_MASK_31_60   0xa3b4
529
+
530
+#define AR_PHY_CHANNEL_MASK_01_30 0x99d4
531
+#define AR_PHY_CHANNEL_MASK_31_60 0x99d8
532
+
533
+#define AR_PHY_ANALOG_SWAP      0xa268
534
+#define AR_PHY_SWAP_ALT_CHAIN   0x00000040
535
+
536
+#define AR_PHY_TPCRG5   0xA26C
537
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP       0x0000000F
538
+#define AR_PHY_TPCRG5_PD_GAIN_OVERLAP_S     0
539
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1    0x000003F0
540
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1_S  4
541
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2    0x0000FC00
542
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2_S  10
543
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3    0x003F0000
544
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3_S  16
545
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4    0x0FC00000
546
+#define AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4_S  22
547
+
548
+/* Carrier leak calibration control, do it after AGC calibration */
549
+#define AR_PHY_CL_CAL_CTL       0xA358
550
+#define AR_PHY_CL_CAL_ENABLE    0x00000002
551
+#define AR_PHY_PARALLEL_CAL_ENABLE    0x00000001
552
+
553
+#define AR_PHY_POWER_TX_RATE5   0xA38C
554
+#define AR_PHY_POWER_TX_RATE6   0xA390
555
+
556
+#define AR_PHY_CAL_CHAINMASK    0xA39C
557
+
558
+#define AR_PHY_POWER_TX_SUB     0xA3C8
559
+#define AR_PHY_POWER_TX_RATE7   0xA3CC
560
+#define AR_PHY_POWER_TX_RATE8   0xA3D0
561
+#define AR_PHY_POWER_TX_RATE9   0xA3D4
562
+
563
+#define AR_PHY_XPA_CFG		0xA3D8
564
+#define AR_PHY_FORCE_XPA_CFG	0x000000001
565
+#define AR_PHY_FORCE_XPA_CFG_S	0
566
+
567
+#define AR_PHY_CH1_CCA          0xa864
568
+#define AR_PHY_CH1_MINCCA_PWR   0x0FF80000
569
+#define AR_PHY_CH1_MINCCA_PWR_S 19
570
+#define AR9280_PHY_CH1_MINCCA_PWR   0x1FF00000
571
+#define AR9280_PHY_CH1_MINCCA_PWR_S 20
572
+
573
+#define AR_PHY_CH2_CCA          0xb864
574
+#define AR_PHY_CH2_MINCCA_PWR   0x0FF80000
575
+#define AR_PHY_CH2_MINCCA_PWR_S 19
576
+
577
+#define AR_PHY_CH1_EXT_CCA          0xa9bc
578
+#define AR_PHY_CH1_EXT_MINCCA_PWR   0xFF800000
579
+#define AR_PHY_CH1_EXT_MINCCA_PWR_S 23
580
+#define AR9280_PHY_CH1_EXT_MINCCA_PWR   0x01FF0000
581
+#define AR9280_PHY_CH1_EXT_MINCCA_PWR_S 16
582
+
583
+#define AR_PHY_CH2_EXT_CCA          0xb9bc
584
+#define AR_PHY_CH2_EXT_MINCCA_PWR   0xFF800000
585
+#define AR_PHY_CH2_EXT_MINCCA_PWR_S 23
586
+
587
+#define AR_PHY_CCA_NOM_VAL_5416_2GHZ            -90
588
+#define AR_PHY_CCA_NOM_VAL_5416_5GHZ            -100
589
+#define AR_PHY_CCA_MIN_GOOD_VAL_5416_2GHZ     -100
590
+#define AR_PHY_CCA_MIN_GOOD_VAL_5416_5GHZ     -110
591
+#define AR_PHY_CCA_MAX_GOOD_VAL_5416_2GHZ     -80
592
+#define AR_PHY_CCA_MAX_GOOD_VAL_5416_5GHZ     -90
593
+
594
+#define AR_PHY_CCA_NOM_VAL_9280_2GHZ         -112
595
+#define AR_PHY_CCA_NOM_VAL_9280_5GHZ         -112
596
+#define AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ  -127
597
+#define AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ  -122
598
+#define AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ  -97
599
+#define AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ  -102
600
+
601
+#define AR_PHY_CCA_NOM_VAL_9285_2GHZ           -118
602
+#define AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ    -127
603
+#define AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ    -108
604
+
605
+#define AR_PHY_CCA_NOM_VAL_9271_2GHZ             -118
606
+#define AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ      -127
607
+#define AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ      -116
608
+
609
+#define AR_PHY_CCA_NOM_VAL_9287_2GHZ           -120
610
+#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ    -127
611
+#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ    -110
612
+
613
+#endif

+ 1864
- 0
src/drivers/net/ath/ath9k/ar9003_2p2_initvals.h
File diff suppressed because it is too large
View File


+ 338
- 0
src/drivers/net/ath/ath9k/ar9003_eeprom.h View File

@@ -0,0 +1,338 @@
1
+/*
2
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef AR9003_EEPROM_H
21
+#define AR9003_EEPROM_H
22
+
23
+#define AR9300_EEP_VER               0xD000
24
+#define AR9300_EEP_VER_MINOR_MASK    0xFFF
25
+#define AR9300_EEP_MINOR_VER_1       0x1
26
+#define AR9300_EEP_MINOR_VER         AR9300_EEP_MINOR_VER_1
27
+
28
+/* 16-bit offset location start of calibration struct */
29
+#define AR9300_EEP_START_LOC         256
30
+#define AR9300_NUM_5G_CAL_PIERS      8
31
+#define AR9300_NUM_2G_CAL_PIERS      3
32
+#define AR9300_NUM_5G_20_TARGET_POWERS  8
33
+#define AR9300_NUM_5G_40_TARGET_POWERS  8
34
+#define AR9300_NUM_2G_CCK_TARGET_POWERS 2
35
+#define AR9300_NUM_2G_20_TARGET_POWERS  3
36
+#define AR9300_NUM_2G_40_TARGET_POWERS  3
37
+/* #define AR9300_NUM_CTLS              21 */
38
+#define AR9300_NUM_CTLS_5G           9
39
+#define AR9300_NUM_CTLS_2G           12
40
+#define AR9300_NUM_BAND_EDGES_5G     8
41
+#define AR9300_NUM_BAND_EDGES_2G     4
42
+#define AR9300_EEPMISC_BIG_ENDIAN    0x01
43
+#define AR9300_EEPMISC_WOW           0x02
44
+#define AR9300_CUSTOMER_DATA_SIZE    20
45
+
46
+#define FBIN2FREQ(x, y) ((y) ? (2300 + x) : (4800 + 5 * x))
47
+#define AR9300_MAX_CHAINS            3
48
+#define AR9300_ANT_16S               25
49
+#define AR9300_FUTURE_MODAL_SZ       6
50
+
51
+#define AR9300_PAPRD_RATE_MASK		0x01ffffff
52
+#define AR9300_PAPRD_SCALE_1		0x0e000000
53
+#define AR9300_PAPRD_SCALE_1_S		25
54
+#define AR9300_PAPRD_SCALE_2		0x70000000
55
+#define AR9300_PAPRD_SCALE_2_S		28
56
+
57
+/* Delta from which to start power to pdadc table */
58
+/* This offset is used in both open loop and closed loop power control
59
+ * schemes. In open loop power control, it is not really needed, but for
60
+ * the "sake of consistency" it was kept. For certain AP designs, this
61
+ * value is overwritten by the value in the flag "pwrTableOffset" just
62
+ * before writing the pdadc vs pwr into the chip registers.
63
+ */
64
+#define AR9300_PWR_TABLE_OFFSET  0
65
+
66
+/* byte addressable */
67
+#define AR9300_EEPROM_SIZE (16*1024)
68
+
69
+#define AR9300_BASE_ADDR_4K 0xfff
70
+#define AR9300_BASE_ADDR 0x3ff
71
+#define AR9300_BASE_ADDR_512 0x1ff
72
+
73
+#define AR9300_OTP_BASE			0x14000
74
+#define AR9300_OTP_STATUS		0x15f18
75
+#define AR9300_OTP_STATUS_TYPE		0x7
76
+#define AR9300_OTP_STATUS_VALID		0x4
77
+#define AR9300_OTP_STATUS_ACCESS_BUSY	0x2
78
+#define AR9300_OTP_STATUS_SM_BUSY	0x1
79
+#define AR9300_OTP_READ_DATA		0x15f1c
80
+
81
+enum targetPowerHTRates {
82
+	HT_TARGET_RATE_0_8_16,
83
+	HT_TARGET_RATE_1_3_9_11_17_19,
84
+	HT_TARGET_RATE_4,
85
+	HT_TARGET_RATE_5,
86
+	HT_TARGET_RATE_6,
87
+	HT_TARGET_RATE_7,
88
+	HT_TARGET_RATE_12,
89
+	HT_TARGET_RATE_13,
90
+	HT_TARGET_RATE_14,
91
+	HT_TARGET_RATE_15,
92
+	HT_TARGET_RATE_20,
93
+	HT_TARGET_RATE_21,
94
+	HT_TARGET_RATE_22,
95
+	HT_TARGET_RATE_23
96
+};
97
+
98
+enum targetPowerLegacyRates {
99
+	LEGACY_TARGET_RATE_6_24,
100
+	LEGACY_TARGET_RATE_36,
101
+	LEGACY_TARGET_RATE_48,
102
+	LEGACY_TARGET_RATE_54
103
+};
104
+
105
+enum targetPowerCckRates {
106
+	LEGACY_TARGET_RATE_1L_5L,
107
+	LEGACY_TARGET_RATE_5S,
108
+	LEGACY_TARGET_RATE_11L,
109
+	LEGACY_TARGET_RATE_11S
110
+};
111
+
112
+enum ar9300_Rates {
113
+	ALL_TARGET_LEGACY_6_24,
114
+	ALL_TARGET_LEGACY_36,
115
+	ALL_TARGET_LEGACY_48,
116
+	ALL_TARGET_LEGACY_54,
117
+	ALL_TARGET_LEGACY_1L_5L,
118
+	ALL_TARGET_LEGACY_5S,
119
+	ALL_TARGET_LEGACY_11L,
120
+	ALL_TARGET_LEGACY_11S,
121
+	ALL_TARGET_HT20_0_8_16,
122
+	ALL_TARGET_HT20_1_3_9_11_17_19,
123
+	ALL_TARGET_HT20_4,
124
+	ALL_TARGET_HT20_5,
125
+	ALL_TARGET_HT20_6,
126
+	ALL_TARGET_HT20_7,
127
+	ALL_TARGET_HT20_12,
128
+	ALL_TARGET_HT20_13,
129
+	ALL_TARGET_HT20_14,
130
+	ALL_TARGET_HT20_15,
131
+	ALL_TARGET_HT20_20,
132
+	ALL_TARGET_HT20_21,
133
+	ALL_TARGET_HT20_22,
134
+	ALL_TARGET_HT20_23,
135
+	ALL_TARGET_HT40_0_8_16,
136
+	ALL_TARGET_HT40_1_3_9_11_17_19,
137
+	ALL_TARGET_HT40_4,
138
+	ALL_TARGET_HT40_5,
139
+	ALL_TARGET_HT40_6,
140
+	ALL_TARGET_HT40_7,
141
+	ALL_TARGET_HT40_12,
142
+	ALL_TARGET_HT40_13,
143
+	ALL_TARGET_HT40_14,
144
+	ALL_TARGET_HT40_15,
145
+	ALL_TARGET_HT40_20,
146
+	ALL_TARGET_HT40_21,
147
+	ALL_TARGET_HT40_22,
148
+	ALL_TARGET_HT40_23,
149
+	ar9300RateSize,
150
+};
151
+
152
+
153
+struct eepFlags {
154
+	u8 opFlags;
155
+	u8 eepMisc;
156
+} __attribute__((packed));
157
+
158
+enum CompressAlgorithm {
159
+	_CompressNone = 0,
160
+	_CompressLzma,
161
+	_CompressPairs,
162
+	_CompressBlock,
163
+	_Compress4,
164
+	_Compress5,
165
+	_Compress6,
166
+	_Compress7,
167
+};
168
+
169
+struct ar9300_base_eep_hdr {
170
+	uint16_t regDmn[2];
171
+	/* 4 bits tx and 4 bits rx */
172
+	u8 txrxMask;
173
+	struct eepFlags opCapFlags;
174
+	u8 rfSilent;
175
+	u8 blueToothOptions;
176
+	u8 deviceCap;
177
+	/* takes lower byte in eeprom location */
178
+	u8 deviceType;
179
+	/* offset in dB to be added to beginning
180
+	 * of pdadc table in calibration
181
+	 */
182
+	int8_t pwrTableOffset;
183
+	u8 params_for_tuning_caps[2];
184
+	/*
185
+	 * bit0 - enable tx temp comp
186
+	 * bit1 - enable tx volt comp
187
+	 * bit2 - enable fastClock - default to 1
188
+	 * bit3 - enable doubling - default to 1
189
+	 * bit4 - enable internal regulator - default to 1
190
+	 */
191
+	u8 featureEnable;
192
+	/* misc flags: bit0 - turn down drivestrength */
193
+	u8 miscConfiguration;
194
+	u8 eepromWriteEnableGpio;
195
+	u8 wlanDisableGpio;
196
+	u8 wlanLedGpio;
197
+	u8 rxBandSelectGpio;
198
+	u8 txrxgain;
199
+	/* SW controlled internal regulator fields */
200
+	uint32_t swreg;
201
+} __attribute__((packed));
202
+
203
+struct ar9300_modal_eep_header {
204
+	/* 4 idle, t1, t2, b (4 bits per setting) */
205
+	uint32_t antCtrlCommon;
206
+	/* 4 ra1l1, ra2l1, ra1l2, ra2l2, ra12 */
207
+	uint32_t antCtrlCommon2;
208
+	/* 6 idle, t, r, rx1, rx12, b (2 bits each) */
209
+	uint16_t antCtrlChain[AR9300_MAX_CHAINS];
210
+	/* 3 xatten1_db for AR9280 (0xa20c/b20c 5:0) */
211
+	u8 xatten1DB[AR9300_MAX_CHAINS];
212
+	/* 3  xatten1_margin for merlin (0xa20c/b20c 16:12 */
213
+	u8 xatten1Margin[AR9300_MAX_CHAINS];
214
+	int8_t tempSlope;
215
+	int8_t voltSlope;
216
+	/* spur channels in usual fbin coding format */
217
+	u8 spurChans[AR_EEPROM_MODAL_SPURS];
218
+	/* 3  Check if the register is per chain */
219
+	int8_t noiseFloorThreshCh[AR9300_MAX_CHAINS];
220
+	u8 ob[AR9300_MAX_CHAINS];
221
+	u8 db_stage2[AR9300_MAX_CHAINS];
222
+	u8 db_stage3[AR9300_MAX_CHAINS];
223
+	u8 db_stage4[AR9300_MAX_CHAINS];
224
+	u8 xpaBiasLvl;
225
+	u8 txFrameToDataStart;
226
+	u8 txFrameToPaOn;
227
+	u8 txClip;
228
+	int8_t antennaGain;
229
+	u8 switchSettling;
230
+	int8_t adcDesiredSize;
231
+	u8 txEndToXpaOff;
232
+	u8 txEndToRxOn;
233
+	u8 txFrameToXpaOn;
234
+	u8 thresh62;
235
+	uint32_t papdRateMaskHt20;
236
+	uint32_t papdRateMaskHt40;
237
+	u8 futureModal[10];
238
+} __attribute__((packed));
239
+
240
+struct ar9300_cal_data_per_freq_op_loop {
241
+	int8_t refPower;
242
+	/* pdadc voltage at power measurement */
243
+	u8 voltMeas;
244
+	/* pcdac used for power measurement   */
245
+	u8 tempMeas;
246
+	/* range is -60 to -127 create a mapping equation 1db resolution */
247
+	int8_t rxNoisefloorCal;
248
+	/*range is same as noisefloor */
249
+	int8_t rxNoisefloorPower;
250
+	/* temp measured when noisefloor cal was performed */
251
+	u8 rxTempMeas;
252
+} __attribute__((packed));
253
+
254
+struct cal_tgt_pow_legacy {
255
+	u8 tPow2x[4];
256
+} __attribute__((packed));
257
+
258
+struct cal_tgt_pow_ht {
259
+	u8 tPow2x[14];
260
+} __attribute__((packed));
261
+
262
+struct cal_ctl_data_2g {
263
+	u8 ctlEdges[AR9300_NUM_BAND_EDGES_2G];
264
+} __attribute__((packed));
265
+
266
+struct cal_ctl_data_5g {
267
+	u8 ctlEdges[AR9300_NUM_BAND_EDGES_5G];
268
+} __attribute__((packed));
269
+
270
+struct ar9300_BaseExtension_1 {
271
+	u8 ant_div_control;
272
+	u8 future[13];
273
+} __attribute__((packed));
274
+
275
+struct ar9300_BaseExtension_2 {
276
+	int8_t    tempSlopeLow;
277
+	int8_t    tempSlopeHigh;
278
+	u8   xatten1DBLow[AR9300_MAX_CHAINS];
279
+	u8   xatten1MarginLow[AR9300_MAX_CHAINS];
280
+	u8   xatten1DBHigh[AR9300_MAX_CHAINS];
281
+	u8   xatten1MarginHigh[AR9300_MAX_CHAINS];
282
+} __attribute__((packed));
283
+
284
+struct ar9300_eeprom {
285
+	u8 eepromVersion;
286
+	u8 templateVersion;
287
+	u8 macAddr[6];
288
+	u8 custData[AR9300_CUSTOMER_DATA_SIZE];
289
+
290
+	struct ar9300_base_eep_hdr baseEepHeader;
291
+
292
+	struct ar9300_modal_eep_header modalHeader2G;
293
+	struct ar9300_BaseExtension_1 base_ext1;
294
+	u8 calFreqPier2G[AR9300_NUM_2G_CAL_PIERS];
295
+	struct ar9300_cal_data_per_freq_op_loop
296
+	 calPierData2G[AR9300_MAX_CHAINS][AR9300_NUM_2G_CAL_PIERS];
297
+	u8 calTarget_freqbin_Cck[AR9300_NUM_2G_CCK_TARGET_POWERS];
298
+	u8 calTarget_freqbin_2G[AR9300_NUM_2G_20_TARGET_POWERS];
299
+	u8 calTarget_freqbin_2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
300
+	u8 calTarget_freqbin_2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
301
+	struct cal_tgt_pow_legacy
302
+	 calTargetPowerCck[AR9300_NUM_2G_CCK_TARGET_POWERS];
303
+	struct cal_tgt_pow_legacy
304
+	 calTargetPower2G[AR9300_NUM_2G_20_TARGET_POWERS];
305
+	struct cal_tgt_pow_ht
306
+	 calTargetPower2GHT20[AR9300_NUM_2G_20_TARGET_POWERS];
307
+	struct cal_tgt_pow_ht
308
+	 calTargetPower2GHT40[AR9300_NUM_2G_40_TARGET_POWERS];
309
+	u8 ctlIndex_2G[AR9300_NUM_CTLS_2G];
310
+	u8 ctl_freqbin_2G[AR9300_NUM_CTLS_2G][AR9300_NUM_BAND_EDGES_2G];
311
+	struct cal_ctl_data_2g ctlPowerData_2G[AR9300_NUM_CTLS_2G];
312
+	struct ar9300_modal_eep_header modalHeader5G;
313
+	struct ar9300_BaseExtension_2 base_ext2;
314
+	u8 calFreqPier5G[AR9300_NUM_5G_CAL_PIERS];
315
+	struct ar9300_cal_data_per_freq_op_loop
316
+	 calPierData5G[AR9300_MAX_CHAINS][AR9300_NUM_5G_CAL_PIERS];
317
+	u8 calTarget_freqbin_5G[AR9300_NUM_5G_20_TARGET_POWERS];
318
+	u8 calTarget_freqbin_5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
319
+	u8 calTarget_freqbin_5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
320
+	struct cal_tgt_pow_legacy
321
+	 calTargetPower5G[AR9300_NUM_5G_20_TARGET_POWERS];
322
+	struct cal_tgt_pow_ht
323
+	 calTargetPower5GHT20[AR9300_NUM_5G_20_TARGET_POWERS];
324
+	struct cal_tgt_pow_ht
325
+	 calTargetPower5GHT40[AR9300_NUM_5G_40_TARGET_POWERS];
326
+	u8 ctlIndex_5G[AR9300_NUM_CTLS_5G];
327
+	u8 ctl_freqbin_5G[AR9300_NUM_CTLS_5G][AR9300_NUM_BAND_EDGES_5G];
328
+	struct cal_ctl_data_5g ctlPowerData_5G[AR9300_NUM_CTLS_5G];
329
+} __attribute__((packed));
330
+
331
+s32 ar9003_hw_get_tx_gain_idx(struct ath_hw *ah);
332
+s32 ar9003_hw_get_rx_gain_idx(struct ath_hw *ah);
333
+
334
+u8 *ar9003_get_spur_chan_ptr(struct ath_hw *ah, int is_2ghz);
335
+
336
+unsigned int ar9003_get_paprd_scale_factor(struct ath_hw *ah,
337
+					   struct ath9k_channel *chan);
338
+#endif

+ 125
- 0
src/drivers/net/ath/ath9k/ar9003_mac.h View File

@@ -0,0 +1,125 @@
1
+/*
2
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef AR9003_MAC_H
21
+#define AR9003_MAC_H
22
+
23
+#define AR_DescId	0xffff0000
24
+#define AR_DescId_S	16
25
+#define AR_CtrlStat	0x00004000
26
+#define AR_CtrlStat_S	14
27
+#define AR_TxRxDesc	0x00008000
28
+#define AR_TxRxDesc_S	15
29
+#define AR_TxQcuNum	0x00000f00
30
+#define AR_TxQcuNum_S	8
31
+
32
+#define AR_BufLen	0x0fff0000
33
+#define AR_BufLen_S	16
34
+
35
+#define AR_TxDescId	0xffff0000
36
+#define AR_TxDescId_S	16
37
+#define AR_TxPtrChkSum	0x0000ffff
38
+
39
+#define AR_LowRxChain	0x00004000
40
+
41
+#define AR_Not_Sounding	0x20000000
42
+
43
+/* ctl 12 */
44
+#define AR_PAPRDChainMask	0x00000e00
45
+#define AR_PAPRDChainMask_S	9
46
+
47
+#define MAP_ISR_S2_CST          6
48
+#define MAP_ISR_S2_GTT          6
49
+#define MAP_ISR_S2_TIM          3
50
+#define MAP_ISR_S2_CABEND       0
51
+#define MAP_ISR_S2_DTIMSYNC     7
52
+#define MAP_ISR_S2_DTIM         7
53
+#define MAP_ISR_S2_TSFOOR       4
54
+#define MAP_ISR_S2_BB_WATCHDOG  6
55
+
56
+#define AR9003TXC_CONST(_ds) ((const struct ar9003_txc *) _ds)
57
+
58
+struct ar9003_rxs {
59
+	u32 ds_info;
60
+	u32 status1;
61
+	u32 status2;
62
+	u32 status3;
63
+	u32 status4;
64
+	u32 status5;
65
+	u32 status6;
66
+	u32 status7;
67
+	u32 status8;
68
+	u32 status9;
69
+	u32 status10;
70
+	u32 status11;
71
+} __attribute__((packed, aligned(4)));
72
+
73
+/* Transmit Control Descriptor */
74
+struct ar9003_txc {
75
+	u32 info;   /* descriptor information */
76
+	u32 link;   /* link pointer */
77
+	u32 data0;  /* data pointer to 1st buffer */
78
+	u32 ctl3;   /* DMA control 3  */
79
+	u32 data1;  /* data pointer to 2nd buffer */
80
+	u32 ctl5;   /* DMA control 5  */
81
+	u32 data2;  /* data pointer to 3rd buffer */
82
+	u32 ctl7;   /* DMA control 7  */
83
+	u32 data3;  /* data pointer to 4th buffer */
84
+	u32 ctl9;   /* DMA control 9  */
85
+	u32 ctl10;  /* DMA control 10 */
86
+	u32 ctl11;  /* DMA control 11 */
87
+	u32 ctl12;  /* DMA control 12 */
88
+	u32 ctl13;  /* DMA control 13 */
89
+	u32 ctl14;  /* DMA control 14 */
90
+	u32 ctl15;  /* DMA control 15 */
91
+	u32 ctl16;  /* DMA control 16 */
92
+	u32 ctl17;  /* DMA control 17 */
93
+	u32 ctl18;  /* DMA control 18 */
94
+	u32 ctl19;  /* DMA control 19 */
95
+	u32 ctl20;  /* DMA control 20 */
96
+	u32 ctl21;  /* DMA control 21 */
97
+	u32 ctl22;  /* DMA control 22 */
98
+	u32 pad[9]; /* pad to cache line (128 bytes/32 dwords) */
99
+} __attribute__((packed, aligned(4)));
100
+
101
+struct ar9003_txs {
102
+	u32 ds_info;
103
+	u32 status1;
104
+	u32 status2;
105
+	u32 status3;
106
+	u32 status4;
107
+	u32 status5;
108
+	u32 status6;
109
+	u32 status7;
110
+	u32 status8;
111
+} __attribute__((packed, aligned(4)));
112
+
113
+void ar9003_hw_attach_mac_ops(struct ath_hw *hw);
114
+void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size);
115
+void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
116
+			    enum ath9k_rx_qtype qtype);
117
+
118
+int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah,
119
+				 struct ath_rx_status *rxs,
120
+				 void *buf_addr);
121
+void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah);
122
+void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
123
+			       u32 ts_paddr_start,
124
+			       u8 size);
125
+#endif

+ 1124
- 0
src/drivers/net/ath/ath9k/ar9003_phy.h
File diff suppressed because it is too large
View File


+ 1525
- 0
src/drivers/net/ath/ath9k/ar9340_initvals.h
File diff suppressed because it is too large
View File


+ 1161
- 0
src/drivers/net/ath/ath9k/ar9485_initvals.h
File diff suppressed because it is too large
View File


+ 208
- 0
src/drivers/net/ath/ath9k/ath9k.c View File

@@ -0,0 +1,208 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/pci.h>
21
+
22
+#include "ath9k.h"
23
+
24
+static struct pci_device_id ath_pci_id_table[] = {
25
+        PCI_ROM(0x168c, 0x0023, "ar5416", "Atheros 5416 PCI", 0),	/* PCI   */
26
+        PCI_ROM(0x168c, 0x0024, "ar5416", "Atheros 5416 PCI-E", 0),	/* PCI-E */
27
+        PCI_ROM(0x168c, 0x0027, "ar9160", "Atheros 9160 PCI", 0),	/* PCI   */
28
+        PCI_ROM(0x168c, 0x0029, "ar9280", "Atheros 9280 PCI", 0),	/* PCI   */
29
+        PCI_ROM(0x168c, 0x002A, "ar9280", "Atheros 9280 PCI-E", 0),	/* PCI-E */
30
+        PCI_ROM(0x168c, 0x002B, "ar9285", "Atheros 9285 PCI-E", 0),	/* PCI-E */
31
+        PCI_ROM(0x168c, 0x002C, "ar2427", "Atheros 2427 PCI-E", 0),	/* PCI-E 802.11n bonded out */
32
+        PCI_ROM(0x168c, 0x002D, "ar9287", "Atheros 9287 PCI", 0),	/* PCI   */
33
+        PCI_ROM(0x168c, 0x002E, "ar9287", "Atheros 9287 PCI-E", 0),	/* PCI-E */
34
+        PCI_ROM(0x168c, 0x0030, "ar9300", "Atheros 9300 PCI-E", 0),	/* PCI-E  AR9300 */
35
+        PCI_ROM(0x168c, 0x0032, "ar9485", "Atheros 9485 PCI-E", 0),	/* PCI-E  AR9485 */
36
+};
37
+
38
+
39
+/* return bus cachesize in 4B word units */
40
+static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
41
+{
42
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
43
+	u8 u8tmp;
44
+
45
+	pci_read_config_byte(sc->pdev, PCI_CACHE_LINE_SIZE, &u8tmp);
46
+	*csz = (int)u8tmp;
47
+
48
+	/*
49
+	 * This check was put in to avoid "unpleasant" consequences if
50
+	 * the bootrom has not fully initialized all PCI devices.
51
+	 * Sometimes the cache line size register is not set
52
+	 */
53
+
54
+	if (*csz == 0)
55
+		*csz = DEFAULT_CACHELINE >> 2;   /* Use the default size */
56
+}
57
+
58
+static int ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
59
+{
60
+	struct ath_hw *ah = (struct ath_hw *) common->ah;
61
+
62
+	common->ops->read(ah, AR5416_EEPROM_OFFSET +
63
+			      (off << AR5416_EEPROM_S));
64
+
65
+	if (!ath9k_hw_wait(ah,
66
+			   AR_EEPROM_STATUS_DATA,
67
+			   AR_EEPROM_STATUS_DATA_BUSY |
68
+			   AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0,
69
+			   AH_WAIT_TIMEOUT)) {
70
+		return 0;
71
+	}
72
+
73
+	*data = MS(common->ops->read(ah, AR_EEPROM_STATUS_DATA),
74
+		   AR_EEPROM_STATUS_DATA_VAL);
75
+
76
+	return 1;
77
+}
78
+
79
+static void ath_pci_extn_synch_enable(struct ath_common *common)
80
+{
81
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
82
+	struct pci_device *pdev = sc->pdev;
83
+	u8 lnkctl;
84
+
85
+	pci_read_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, &lnkctl);
86
+	lnkctl |= 0x0080;
87
+	pci_write_config_byte(pdev, sc->sc_ah->caps.pcie_lcr_offset, lnkctl);
88
+}
89
+
90
+static const struct ath_bus_ops ath_pci_bus_ops = {
91
+	.ath_bus_type = ATH_PCI,
92
+	.read_cachesize = ath_pci_read_cachesize,
93
+	.eeprom_read = ath_pci_eeprom_read,
94
+	.extn_synch_en = ath_pci_extn_synch_enable,
95
+};
96
+
97
+static int ath_pci_probe(struct pci_device *pdev)
98
+{
99
+	void *mem;
100
+	struct ath_softc *sc;
101
+	struct net80211_device *dev;
102
+	u8 csz;
103
+	u16 subsysid;
104
+	u32 val;
105
+	int ret = 0;
106
+	char hw_name[64];
107
+
108
+	adjust_pci_device(pdev);
109
+
110
+	/*
111
+	 * Cache line size is used to size and align various
112
+	 * structures used to communicate with the hardware.
113
+	 */
114
+	pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &csz);
115
+	if (csz == 0) {
116
+		/*
117
+		 * Linux 2.4.18 (at least) writes the cache line size
118
+		 * register as a 16-bit wide register which is wrong.
119
+		 * We must have this setup properly for rx buffer
120
+		 * DMA to work so force a reasonable value here if it
121
+		 * comes up zero.
122
+		 */
123
+		csz =16;
124
+		pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, csz);
125
+	}
126
+	/*
127
+	 * The default setting of latency timer yields poor results,
128
+	 * set it to the value used by other systems. It may be worth
129
+	 * tweaking this setting more.
130
+	 */
131
+	pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xa8);
132
+
133
+	/*
134
+	 * Disable the RETRY_TIMEOUT register (0x41) to keep
135
+	 * PCI Tx retries from interfering with C3 CPU state.
136
+	 */
137
+	pci_read_config_dword(pdev, 0x40, &val);
138
+	if ((val & 0x0000ff00) != 0)
139
+		pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
140
+
141
+	mem = ioremap(pdev->membase, 0x10000);
142
+	if (!mem) {
143
+		DBG("ath9K: PCI memory map error\n") ;
144
+		ret = -EIO;
145
+		goto err_iomap;
146
+	}
147
+
148
+	dev = net80211_alloc(sizeof(struct ath_softc));
149
+	if (!dev) {
150
+		DBG("ath9k: No memory for net80211_device\n");
151
+		ret = -ENOMEM;
152
+		goto err_alloc_hw;
153
+	}
154
+
155
+	pci_set_drvdata(pdev, dev);
156
+	dev->netdev->dev = (struct device *)pdev;
157
+
158
+	sc = dev->priv;
159
+	sc->dev = dev;
160
+	sc->pdev = pdev;
161
+	sc->mem = mem;
162
+
163
+	/* Will be cleared in ath9k_start() */
164
+	sc->sc_flags |= SC_OP_INVALID;
165
+
166
+	sc->irq = pdev->irq;
167
+
168
+	pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsysid);
169
+	ret = ath9k_init_device(pdev->device, sc, subsysid, &ath_pci_bus_ops);
170
+	if (ret) {
171
+		DBG("ath9k: Failed to initialize device\n");
172
+		goto err_init;
173
+	}
174
+
175
+	ath9k_hw_name(sc->sc_ah, hw_name, sizeof(hw_name));
176
+	DBG("ath9k: %s mem=0x%lx, irq=%d\n",
177
+		   hw_name, (unsigned long)mem, pdev->irq);
178
+
179
+	return 0;
180
+
181
+err_init:
182
+	net80211_free(dev);
183
+err_alloc_hw:
184
+	iounmap(mem);
185
+err_iomap:
186
+	return ret;
187
+}
188
+
189
+static void ath_pci_remove(struct pci_device *pdev)
190
+{
191
+	struct net80211_device *dev = pci_get_drvdata(pdev);
192
+	struct ath_softc *sc = dev->priv;
193
+	void *mem = sc->mem;
194
+
195
+	if (!is_ath9k_unloaded)
196
+		sc->sc_ah->ah_flags |= AH_UNPLUGGED;
197
+	ath9k_deinit_device(sc);
198
+	net80211_free(sc->dev);
199
+
200
+	iounmap(mem);
201
+}
202
+
203
+struct pci_driver ath_pci_driver __pci_driver = {
204
+        .id_count   = ARRAY_SIZE(ath_pci_id_table),
205
+	.ids        = ath_pci_id_table,
206
+	.probe      = ath_pci_probe,
207
+	.remove     = ath_pci_remove,
208
+};

+ 521
- 0
src/drivers/net/ath/ath9k/ath9k.h View File

@@ -0,0 +1,521 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef ATH9K_H
21
+#define ATH9K_H
22
+
23
+#include "common.h"
24
+
25
+/*
26
+ * Header for the ath9k.ko driver core *only* -- hw code nor any other driver
27
+ * should rely on this file or its contents.
28
+ */
29
+
30
+struct ath_node;
31
+struct ath_softc;
32
+
33
+/* Macro to expand scalars to 64-bit objects */
34
+
35
+#define	ito64(x) (sizeof(x) == 1) ?			\
36
+	(((unsigned long long int)(x)) & (0xff)) :	\
37
+	(sizeof(x) == 2) ?				\
38
+	(((unsigned long long int)(x)) & 0xffff) :	\
39
+	((sizeof(x) == 4) ?				\
40
+	 (((unsigned long long int)(x)) & 0xffffffff) : \
41
+	 (unsigned long long int)(x))
42
+
43
+/* increment with wrap-around */
44
+#define INCR(_l, _sz)   do {			\
45
+		(_l)++;				\
46
+		(_l) &= ((_sz) - 1);		\
47
+	} while (0)
48
+
49
+/* decrement with wrap-around */
50
+#define DECR(_l,  _sz)  do {			\
51
+		(_l)--;				\
52
+		(_l) &= ((_sz) - 1);		\
53
+	} while (0)
54
+
55
+#define A_MAX(a, b) ((a) > (b) ? (a) : (b))
56
+
57
+#define TSF_TO_TU(_h,_l) \
58
+	((((u32)(_h)) << 22) | (((u32)(_l)) >> 10))
59
+
60
+#define	ATH_TXQ_SETUP(sc, i)        ((sc)->tx.txqsetup & (1<<i))
61
+
62
+struct ath_config {
63
+	u16 txpowlimit;
64
+	u8 cabqReadytime;
65
+};
66
+
67
+/*************************/
68
+/* Descriptor Management */
69
+/*************************/
70
+
71
+#define ATH_TXBUF_RESET(_bf) do {				\
72
+		(_bf)->bf_stale = 0;			\
73
+		(_bf)->bf_lastbf = NULL;			\
74
+		(_bf)->bf_next = NULL;				\
75
+		memset(&((_bf)->bf_state), 0,			\
76
+		       sizeof(struct ath_buf_state));		\
77
+	} while (0)
78
+
79
+#define ATH_RXBUF_RESET(_bf) do {		\
80
+		(_bf)->bf_stale = 0;	\
81
+	} while (0)
82
+
83
+/**
84
+ * enum buffer_type - Buffer type flags
85
+ *
86
+ * @BUF_AMPDU: This buffer is an ampdu, as part of an aggregate (during TX)
87
+ * @BUF_AGGR: Indicates whether the buffer can be aggregated
88
+ *	(used in aggregation scheduling)
89
+ * @BUF_XRETRY: To denote excessive retries of the buffer
90
+ */
91
+enum buffer_type {
92
+	BUF_AMPDU		= BIT(0),
93
+	BUF_AGGR		= BIT(1),
94
+	BUF_XRETRY		= BIT(2),
95
+};
96
+
97
+#define bf_isampdu(bf)		(bf->bf_state.bf_type & BUF_AMPDU)
98
+#define bf_isaggr(bf)		(bf->bf_state.bf_type & BUF_AGGR)
99
+#define bf_isxretried(bf)	(bf->bf_state.bf_type & BUF_XRETRY)
100
+
101
+#define ATH_TXSTATUS_RING_SIZE 64
102
+
103
+struct ath_descdma {
104
+	void *dd_desc;
105
+	u32 dd_desc_paddr;
106
+	u32 dd_desc_len;
107
+	struct ath_buf *dd_bufptr;
108
+};
109
+
110
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
111
+		      struct list_head *head, const char *name,
112
+		      int nbuf, int ndesc, int is_tx);
113
+void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *dd,
114
+			 struct list_head *head);
115
+
116
+/***********/
117
+/* RX / TX */
118
+/***********/
119
+
120
+#define ATH_RXBUF               16
121
+#define ATH_TXBUF               16
122
+#define ATH_TXBUF_RESERVE       5
123
+#define ATH_MAX_QDEPTH          (ATH_TXBUF / 4 - ATH_TXBUF_RESERVE)
124
+#define ATH_TXMAXTRY            13
125
+
126
+#define TID_TO_WME_AC(_tid)				\
127
+	((((_tid) == 0) || ((_tid) == 3)) ? WME_AC_BE :	\
128
+	 (((_tid) == 1) || ((_tid) == 2)) ? WME_AC_BK :	\
129
+	 (((_tid) == 4) || ((_tid) == 5)) ? WME_AC_VI :	\
130
+	 WME_AC_VO)
131
+
132
+#define ATH_AGGR_DELIM_SZ          4
133
+#define ATH_AGGR_MINPLEN           256 /* in bytes, minimum packet length */
134
+/* number of delimiters for encryption padding */
135
+#define ATH_AGGR_ENCRYPTDELIM      10
136
+/* minimum h/w qdepth to be sustained to maximize aggregation */
137
+#define ATH_AGGR_MIN_QDEPTH        2
138
+#define ATH_AMPDU_SUBFRAME_DEFAULT 32
139
+
140
+#define FCS_LEN                    4
141
+#define IEEE80211_SEQ_SEQ_SHIFT    4
142
+#define IEEE80211_SEQ_MAX          4096
143
+#define IEEE80211_WEP_IVLEN        3
144
+#define IEEE80211_WEP_KIDLEN       1
145
+#define IEEE80211_WEP_CRCLEN       4
146
+#define IEEE80211_MAX_MPDU_LEN     (3840 + FCS_LEN +		\
147
+				    (IEEE80211_WEP_IVLEN +	\
148
+				     IEEE80211_WEP_KIDLEN +	\
149
+				     IEEE80211_WEP_CRCLEN))
150
+
151
+/* return whether a bit at index _n in bitmap _bm is set
152
+ * _sz is the size of the bitmap  */
153
+#define ATH_BA_ISSET(_bm, _n)  (((_n) < (WME_BA_BMP_SIZE)) &&		\
154
+				((_bm)[(_n) >> 5] & (1 << ((_n) & 31))))
155
+
156
+/* return block-ack bitmap index given sequence and starting sequence */
157
+#define ATH_BA_INDEX(_st, _seq) (((_seq) - (_st)) & (IEEE80211_SEQ_MAX - 1))
158
+
159
+/* returns delimiter padding required given the packet length */
160
+#define ATH_AGGR_GET_NDELIM(_len)					\
161
+       (((_len) >= ATH_AGGR_MINPLEN) ? 0 :                             \
162
+        DIV_ROUND_UP(ATH_AGGR_MINPLEN - (_len), ATH_AGGR_DELIM_SZ))
163
+
164
+#define BAW_WITHIN(_start, _bawsz, _seqno) \
165
+	((((_seqno) - (_start)) & 4095) < (_bawsz))
166
+
167
+#define ATH_AN_2_TID(_an, _tidno)  (&(_an)->tid[(_tidno)])
168
+
169
+#define ATH_TX_COMPLETE_POLL_INT	1000
170
+
171
+enum ATH_AGGR_STATUS {
172
+	ATH_AGGR_DONE,
173
+	ATH_AGGR_BAW_CLOSED,
174
+	ATH_AGGR_LIMITED,
175
+};
176
+
177
+#define ATH_TXFIFO_DEPTH 8
178
+struct ath_txq {
179
+	int mac80211_qnum; /* mac80211 queue number, -1 means not mac80211 Q */
180
+	u32 axq_qnum; /* ath9k hardware queue number */
181
+	u32 *axq_link;
182
+	struct list_head axq_q;
183
+	u32 axq_depth;
184
+	u32 axq_ampdu_depth;
185
+	int stopped;
186
+	int axq_tx_inprogress;
187
+	struct list_head axq_acq;
188
+	struct list_head txq_fifo[ATH_TXFIFO_DEPTH];
189
+	struct list_head txq_fifo_pending;
190
+	u8 txq_headidx;
191
+	u8 txq_tailidx;
192
+	int pending_frames;
193
+};
194
+
195
+struct ath_atx_ac {
196
+	struct ath_txq *txq;
197
+	int sched;
198
+	struct list_head list;
199
+	struct list_head tid_q;
200
+	int clear_ps_filter;
201
+};
202
+
203
+struct ath_frame_info {
204
+	int framelen;
205
+	u32 keyix;
206
+	enum ath9k_key_type keytype;
207
+	u8 retries;
208
+	u16 seqno;
209
+};
210
+
211
+struct ath_buf_state {
212
+	u8 bf_type;
213
+	u8 bfs_paprd;
214
+	unsigned long bfs_paprd_timestamp;
215
+};
216
+
217
+struct ath_buf {
218
+	struct list_head list;
219
+	struct ath_buf *bf_lastbf;	/* last buf of this unit (a frame or
220
+					   an aggregate) */
221
+	struct ath_buf *bf_next;	/* next subframe in the aggregate */
222
+	struct io_buffer *bf_mpdu;	/* enclosing frame structure */
223
+	void *bf_desc;			/* virtual addr of desc */
224
+	u32 bf_daddr;			/* physical addr of desc */
225
+	u32 bf_buf_addr;		/* physical addr of data buffer, for DMA */
226
+	int bf_stale;
227
+	u16 bf_flags;
228
+	struct ath_buf_state bf_state;
229
+};
230
+
231
+struct ath_atx_tid {
232
+	struct list_head list;
233
+	struct list_head buf_q;
234
+	struct ath_node *an;
235
+	struct ath_atx_ac *ac;
236
+	unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
237
+	u16 seq_start;
238
+	u16 seq_next;
239
+	u16 baw_size;
240
+	int tidno;
241
+	int baw_head;   /* first un-acked tx buffer */
242
+	int baw_tail;   /* next unused tx buffer slot */
243
+	int sched;
244
+	int paused;
245
+	u8 state;
246
+};
247
+
248
+struct ath_node {
249
+	struct ath_atx_tid tid[WME_NUM_TID];
250
+	struct ath_atx_ac ac[WME_NUM_AC];
251
+	int ps_key;
252
+
253
+	u16 maxampdu;
254
+	u8 mpdudensity;
255
+
256
+	int sleeping;
257
+};
258
+
259
+#define AGGR_CLEANUP         BIT(1)
260
+#define AGGR_ADDBA_COMPLETE  BIT(2)
261
+#define AGGR_ADDBA_PROGRESS  BIT(3)
262
+
263
+struct ath_tx_control {
264
+	struct ath_txq *txq;
265
+	struct ath_node *an;
266
+	int if_id;
267
+	u8 paprd;
268
+};
269
+
270
+#define ATH_TX_ERROR        0x01
271
+#define ATH_TX_XRETRY       0x02
272
+#define ATH_TX_BAR          0x04
273
+
274
+/**
275
+ * @txq_map:  Index is mac80211 queue number.  This is
276
+ *  not necessarily the same as the hardware queue number
277
+ *  (axq_qnum).
278
+ */
279
+struct ath_tx {
280
+	u16 seq_no;
281
+	u32 txqsetup;
282
+	struct list_head txbuf;
283
+	struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
284
+	struct ath_descdma txdma;
285
+	struct ath_txq *txq_map[WME_NUM_AC];
286
+};
287
+
288
+struct ath_rx_edma {
289
+	struct list_head rx_fifo;
290
+	struct list_head rx_buffers;
291
+	u32 rx_fifo_hwsize;
292
+};
293
+
294
+struct ath_rx {
295
+	u8 defant;
296
+	u8 rxotherant;
297
+	u32 *rxlink;
298
+	unsigned int rxfilter;
299
+	struct list_head rxbuf;
300
+	struct ath_descdma rxdma;
301
+	struct ath_buf *rx_bufptr;
302
+	struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
303
+
304
+	struct io_buffer *frag;
305
+};
306
+
307
+int ath_startrecv(struct ath_softc *sc);
308
+int ath_stoprecv(struct ath_softc *sc);
309
+void ath_flushrecv(struct ath_softc *sc);
310
+u32 ath_calcrxfilter(struct ath_softc *sc);
311
+int ath_rx_init(struct ath_softc *sc, int nbufs);
312
+void ath_rx_cleanup(struct ath_softc *sc);
313
+int ath_rx_tasklet(struct ath_softc *sc, int flush, int hp);
314
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype);
315
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq);
316
+int ath_drain_all_txq(struct ath_softc *sc, int retry_tx);
317
+void ath_draintxq(struct ath_softc *sc,
318
+		     struct ath_txq *txq, int retry_tx);
319
+void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq);
320
+int ath_tx_init(struct ath_softc *sc, int nbufs);
321
+void ath_tx_cleanup(struct ath_softc *sc);
322
+int ath_txq_update(struct ath_softc *sc, int qnum,
323
+		   struct ath9k_tx_queue_info *q);
324
+int ath_tx_start(struct net80211_device *dev, struct io_buffer *iob,
325
+		 struct ath_tx_control *txctl);
326
+void ath_tx_tasklet(struct ath_softc *sc);
327
+
328
+/*******/
329
+/* ANI */
330
+/*******/
331
+
332
+#define ATH_STA_SHORT_CALINTERVAL 1000    /* 1 second */
333
+#define ATH_AP_SHORT_CALINTERVAL  100     /* 100 ms */
334
+#define ATH_ANI_POLLINTERVAL_OLD  100     /* 100 ms */
335
+#define ATH_ANI_POLLINTERVAL_NEW  1000    /* 1000 ms */
336
+#define ATH_LONG_CALINTERVAL_INT  1000    /* 1000 ms */
337
+#define ATH_LONG_CALINTERVAL      30000   /* 30 seconds */
338
+#define ATH_RESTART_CALINTERVAL   1200000 /* 20 minutes */
339
+
340
+void ath_hw_pll_work(struct ath_softc *sc);
341
+void ath_ani_calibrate(struct ath_softc *sc);
342
+
343
+/********************/
344
+/* Main driver core */
345
+/********************/
346
+
347
+/*
348
+ * Default cache line size, in bytes.
349
+ * Used when PCI device not fully initialized by bootrom/BIOS
350
+*/
351
+#define DEFAULT_CACHELINE       32
352
+#define ATH_REGCLASSIDS_MAX     10
353
+#define ATH_CABQ_READY_TIME     80      /* % of beacon interval */
354
+#define ATH_MAX_SW_RETRIES      10
355
+#define ATH_CHAN_MAX            255
356
+
357
+#define ATH_TXPOWER_MAX         100     /* .5 dBm units */
358
+#define ATH_RATE_DUMMY_MARKER   0
359
+
360
+#define SC_OP_INVALID                BIT(0)
361
+#define SC_OP_BEACONS                BIT(1)
362
+#define SC_OP_RXAGGR                 BIT(2)
363
+#define SC_OP_TXAGGR                 BIT(3)
364
+#define SC_OP_OFFCHANNEL             BIT(4)
365
+#define SC_OP_PREAMBLE_SHORT         BIT(5)
366
+#define SC_OP_PROTECT_ENABLE         BIT(6)
367
+#define SC_OP_RXFLUSH                BIT(7)
368
+#define SC_OP_LED_ASSOCIATED         BIT(8)
369
+#define SC_OP_LED_ON                 BIT(9)
370
+#define SC_OP_TSF_RESET              BIT(11)
371
+#define SC_OP_BT_PRIORITY_DETECTED   BIT(12)
372
+#define SC_OP_BT_SCAN		     BIT(13)
373
+#define SC_OP_ANI_RUN		     BIT(14)
374
+#define SC_OP_ENABLE_APM	     BIT(15)
375
+#define SC_OP_PRIM_STA_VIF	     BIT(16)
376
+
377
+/* Powersave flags */
378
+#define PS_WAIT_FOR_BEACON        BIT(0)
379
+#define PS_WAIT_FOR_CAB           BIT(1)
380
+#define PS_WAIT_FOR_PSPOLL_DATA   BIT(2)
381
+#define PS_WAIT_FOR_TX_ACK        BIT(3)
382
+#define PS_BEACON_SYNC            BIT(4)
383
+#define PS_TSFOOR_SYNC            BIT(5)
384
+
385
+struct ath_rate_table;
386
+
387
+struct ath9k_legacy_rate {
388
+        u16 bitrate;
389
+        u32 flags;
390
+        u16 hw_value;
391
+        u16 hw_value_short;
392
+};
393
+
394
+enum ath9k_rate_control_flags {
395
+	IEEE80211_TX_RC_USE_RTS_CTS		= BIT(0),
396
+	IEEE80211_TX_RC_USE_CTS_PROTECT		= BIT(1),
397
+	IEEE80211_TX_RC_USE_SHORT_PREAMBLE	= BIT(2),
398
+
399
+	/* rate index is an MCS rate number instead of an index */
400
+	IEEE80211_TX_RC_MCS			= BIT(3),
401
+	IEEE80211_TX_RC_GREEN_FIELD		= BIT(4),
402
+	IEEE80211_TX_RC_40_MHZ_WIDTH		= BIT(5),
403
+	IEEE80211_TX_RC_DUP_DATA		= BIT(6),
404
+	IEEE80211_TX_RC_SHORT_GI		= BIT(7),
405
+};
406
+
407
+struct survey_info {
408
+	struct net80211_channel *channel;
409
+	u64 channel_time;
410
+	u64 channel_time_busy;
411
+	u64 channel_time_ext_busy;
412
+	u64 channel_time_rx;
413
+	u64 channel_time_tx;
414
+	u32 filled;
415
+	s8 noise;
416
+};
417
+
418
+enum survey_info_flags {
419
+	SURVEY_INFO_NOISE_DBM = 1<<0,
420
+	SURVEY_INFO_IN_USE = 1<<1,
421
+	SURVEY_INFO_CHANNEL_TIME = 1<<2,
422
+	SURVEY_INFO_CHANNEL_TIME_BUSY = 1<<3,
423
+	SURVEY_INFO_CHANNEL_TIME_EXT_BUSY = 1<<4,
424
+	SURVEY_INFO_CHANNEL_TIME_RX = 1<<5,
425
+	SURVEY_INFO_CHANNEL_TIME_TX = 1<<6,
426
+};
427
+
428
+struct ath9k_vif_iter_data {
429
+	const u8 *hw_macaddr; /* phy's hardware address, set
430
+			       * before starting iteration for
431
+			       * valid bssid mask.
432
+			       */
433
+	u8 mask[ETH_ALEN]; /* bssid mask */
434
+	int naps;      /* number of AP vifs */
435
+	int nmeshes;   /* number of mesh vifs */
436
+	int nstations; /* number of station vifs */
437
+	int nwds;      /* number of nwd vifs */
438
+	int nadhocs;   /* number of adhoc vifs */
439
+	int nothers;   /* number of vifs not specified above. */
440
+};
441
+
442
+struct ath_softc {
443
+	struct net80211_device *dev;
444
+	struct pci_device *pdev;
445
+
446
+	int chan_idx;
447
+	int chan_is_ht;
448
+	struct survey_info *cur_survey;
449
+	struct survey_info survey[ATH9K_NUM_CHANNELS];
450
+
451
+	void (*intr_tq)(struct ath_softc *sc);
452
+	struct ath_hw *sc_ah;
453
+	void *mem;
454
+	int irq;
455
+
456
+	void (*paprd_work)(struct ath_softc *sc);
457
+	void (*hw_check_work)(struct ath_softc *sc);
458
+	void (*paprd_complete)(struct ath_softc *sc);
459
+
460
+	unsigned int hw_busy_count;
461
+
462
+	u32 intrstatus;
463
+	u32 sc_flags; /* SC_OP_* */
464
+	u16 ps_flags; /* PS_* */
465
+	u16 curtxpow;
466
+	int ps_enabled;
467
+	int ps_idle;
468
+	short nbcnvifs;
469
+	short nvifs;
470
+	unsigned long ps_usecount;
471
+
472
+	struct ath_config config;
473
+	struct ath_rx rx;
474
+	struct ath_tx tx;
475
+	struct net80211_hw_info *hwinfo;
476
+	struct ath9k_legacy_rate rates[NET80211_MAX_RATES];
477
+	int hw_rix;
478
+
479
+	struct ath9k_hw_cal_data caldata;
480
+	int last_rssi;
481
+
482
+	void (*tx_complete_work)(struct ath_softc *sc);
483
+	unsigned long tx_complete_work_timer;
484
+	void (*hw_pll_work)(struct ath_softc *sc);
485
+	unsigned long hw_pll_work_timer;
486
+
487
+	struct ath_descdma txsdma;
488
+};
489
+
490
+void ath9k_tasklet(struct ath_softc *sc);
491
+int ath_reset(struct ath_softc *sc, int retry_tx);
492
+
493
+static inline void ath_read_cachesize(struct ath_common *common, int *csz)
494
+{
495
+	common->bus_ops->read_cachesize(common, csz);
496
+}
497
+
498
+extern struct net80211_device_operations ath9k_ops;
499
+extern int ath9k_modparam_nohwcrypt;
500
+extern int is_ath9k_unloaded;
501
+
502
+void ath_isr(struct net80211_device *dev);
503
+void ath9k_init_crypto(struct ath_softc *sc);
504
+int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
505
+		    const struct ath_bus_ops *bus_ops);
506
+void ath9k_deinit_device(struct ath_softc *sc);
507
+void ath9k_set_hw_capab(struct ath_softc *sc, struct net80211_device *dev);
508
+int ath_set_channel(struct ath_softc *sc, struct net80211_device *dev,
509
+		    struct ath9k_channel *hchan);
510
+
511
+void ath_radio_enable(struct ath_softc *sc, struct net80211_device *dev);
512
+void ath_radio_disable(struct ath_softc *sc, struct net80211_device *dev);
513
+int ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode);
514
+int ath9k_uses_beacons(int type);
515
+
516
+u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate);
517
+
518
+void ath_start_rfkill_poll(struct ath_softc *sc);
519
+extern void ath9k_rfkill_poll_state(struct net80211_device *dev);
520
+
521
+#endif /* ATH9K_H */

+ 733
- 0
src/drivers/net/ath/ath9k/ath9k_ani.c View File

@@ -0,0 +1,733 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 "hw.h"
21
+#include "hw-ops.h"
22
+
23
+struct ani_ofdm_level_entry {
24
+	int spur_immunity_level;
25
+	int fir_step_level;
26
+	int ofdm_weak_signal_on;
27
+};
28
+
29
+/* values here are relative to the INI */
30
+
31
+/*
32
+ * Legend:
33
+ *
34
+ * SI: Spur immunity
35
+ * FS: FIR Step
36
+ * WS: OFDM / CCK Weak Signal detection
37
+ * MRC-CCK: Maximal Ratio Combining for CCK
38
+ */
39
+
40
+static const struct ani_ofdm_level_entry ofdm_level_table[] = {
41
+	/* SI  FS  WS */
42
+	{  0,  0,  1  }, /* lvl 0 */
43
+	{  1,  1,  1  }, /* lvl 1 */
44
+	{  2,  2,  1  }, /* lvl 2 */
45
+	{  3,  2,  1  }, /* lvl 3  (default) */
46
+	{  4,  3,  1  }, /* lvl 4 */
47
+	{  5,  4,  1  }, /* lvl 5 */
48
+	{  6,  5,  1  }, /* lvl 6 */
49
+	{  7,  6,  1  }, /* lvl 7 */
50
+	{  7,  7,  1  }, /* lvl 8 */
51
+	{  7,  8,  0  }  /* lvl 9 */
52
+};
53
+#define ATH9K_ANI_OFDM_NUM_LEVEL \
54
+	ARRAY_SIZE(ofdm_level_table)
55
+#define ATH9K_ANI_OFDM_MAX_LEVEL \
56
+	(ATH9K_ANI_OFDM_NUM_LEVEL-1)
57
+#define ATH9K_ANI_OFDM_DEF_LEVEL \
58
+	3 /* default level - matches the INI settings */
59
+
60
+/*
61
+ * MRC (Maximal Ratio Combining) has always been used with multi-antenna ofdm.
62
+ * With OFDM for single stream you just add up all antenna inputs, you're
63
+ * only interested in what you get after FFT. Signal aligment is also not
64
+ * required for OFDM because any phase difference adds up in the frequency
65
+ * domain.
66
+ *
67
+ * MRC requires extra work for use with CCK. You need to align the antenna
68
+ * signals from the different antenna before you can add the signals together.
69
+ * You need aligment of signals as CCK is in time domain, so addition can cancel
70
+ * your signal completely if phase is 180 degrees (think of adding sine waves).
71
+ * You also need to remove noise before the addition and this is where ANI
72
+ * MRC CCK comes into play. One of the antenna inputs may be stronger but
73
+ * lower SNR, so just adding after alignment can be dangerous.
74
+ *
75
+ * Regardless of alignment in time, the antenna signals add constructively after
76
+ * FFT and improve your reception. For more information:
77
+ *
78
+ * http://en.wikipedia.org/wiki/Maximal-ratio_combining
79
+ */
80
+
81
+struct ani_cck_level_entry {
82
+	int fir_step_level;
83
+	int mrc_cck_on;
84
+};
85
+
86
+static const struct ani_cck_level_entry cck_level_table[] = {
87
+	/* FS  MRC-CCK  */
88
+	{  0,  1  }, /* lvl 0 */
89
+	{  1,  1  }, /* lvl 1 */
90
+	{  2,  1  }, /* lvl 2  (default) */
91
+	{  3,  1  }, /* lvl 3 */
92
+	{  4,  0  }, /* lvl 4 */
93
+	{  5,  0  }, /* lvl 5 */
94
+	{  6,  0  }, /* lvl 6 */
95
+	{  7,  0  }, /* lvl 7 (only for high rssi) */
96
+	{  8,  0  }  /* lvl 8 (only for high rssi) */
97
+};
98
+
99
+#define ATH9K_ANI_CCK_NUM_LEVEL \
100
+	ARRAY_SIZE(cck_level_table)
101
+#define ATH9K_ANI_CCK_MAX_LEVEL \
102
+	(ATH9K_ANI_CCK_NUM_LEVEL-1)
103
+#define ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI \
104
+	(ATH9K_ANI_CCK_NUM_LEVEL-3)
105
+#define ATH9K_ANI_CCK_DEF_LEVEL \
106
+	2 /* default level - matches the INI settings */
107
+
108
+static int use_new_ani(struct ath_hw *ah)
109
+{
110
+	return AR_SREV_9300_20_OR_LATER(ah) || modparam_force_new_ani;
111
+}
112
+
113
+static void ath9k_hw_update_mibstats(struct ath_hw *ah,
114
+				     struct ath9k_mib_stats *stats)
115
+{
116
+	stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
117
+	stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
118
+	stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
119
+	stats->rts_good += REG_READ(ah, AR_RTS_OK);
120
+	stats->beacons += REG_READ(ah, AR_BEACON_CNT);
121
+}
122
+
123
+static void ath9k_ani_restart(struct ath_hw *ah)
124
+{
125
+	struct ar5416AniState *aniState;
126
+	u32 ofdm_base = 0, cck_base = 0;
127
+
128
+	if (!DO_ANI(ah))
129
+		return;
130
+
131
+	aniState = &ah->curchan->ani;
132
+	aniState->listenTime = 0;
133
+
134
+	if (!use_new_ani(ah)) {
135
+		ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
136
+		cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
137
+	}
138
+
139
+	DBG2("ath9k: "
140
+		"Writing ofdmbase=%d   cckbase=%d\n", ofdm_base, cck_base);
141
+
142
+	ENABLE_REGWRITE_BUFFER(ah);
143
+
144
+	REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
145
+	REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
146
+	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
147
+	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
148
+
149
+	REGWRITE_BUFFER_FLUSH(ah);
150
+
151
+	ath9k_hw_update_mibstats(ah, &ah->ah_mibStats);
152
+
153
+	aniState->ofdmPhyErrCount = 0;
154
+	aniState->cckPhyErrCount = 0;
155
+}
156
+
157
+static void ath9k_hw_ani_ofdm_err_trigger_old(struct ath_hw *ah)
158
+{
159
+	struct ar5416AniState *aniState;
160
+	int32_t rssi;
161
+
162
+	aniState = &ah->curchan->ani;
163
+
164
+	if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
165
+		if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
166
+					 aniState->noiseImmunityLevel + 1)) {
167
+			return;
168
+		}
169
+	}
170
+
171
+	if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
172
+		if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
173
+					 aniState->spurImmunityLevel + 1)) {
174
+			return;
175
+		}
176
+	}
177
+
178
+	rssi = BEACON_RSSI(ah);
179
+	if (rssi > aniState->rssiThrHigh) {
180
+		if (!aniState->ofdmWeakSigDetectOff) {
181
+			if (ath9k_hw_ani_control(ah,
182
+					 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
183
+					 0)) {
184
+				ath9k_hw_ani_control(ah,
185
+					ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
186
+				return;
187
+			}
188
+		}
189
+		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
190
+			ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
191
+					     aniState->firstepLevel + 1);
192
+			return;
193
+		}
194
+	} else if (rssi > aniState->rssiThrLow) {
195
+		if (aniState->ofdmWeakSigDetectOff)
196
+			ath9k_hw_ani_control(ah,
197
+				     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
198
+				     1);
199
+		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
200
+			ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
201
+					     aniState->firstepLevel + 1);
202
+		return;
203
+	} else {
204
+		if ((ah->dev->channels + ah->dev->channel)->band == NET80211_BAND_2GHZ) {
205
+			if (!aniState->ofdmWeakSigDetectOff)
206
+				ath9k_hw_ani_control(ah,
207
+				     ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
208
+				     0);
209
+			if (aniState->firstepLevel > 0)
210
+				ath9k_hw_ani_control(ah,
211
+					     ATH9K_ANI_FIRSTEP_LEVEL, 0);
212
+			return;
213
+		}
214
+	}
215
+}
216
+
217
+static void ath9k_hw_ani_cck_err_trigger_old(struct ath_hw *ah)
218
+{
219
+	struct ar5416AniState *aniState;
220
+	int32_t rssi;
221
+
222
+	aniState = &ah->curchan->ani;
223
+	if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
224
+		if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
225
+					 aniState->noiseImmunityLevel + 1)) {
226
+			return;
227
+		}
228
+	}
229
+	rssi = BEACON_RSSI(ah);
230
+	if (rssi > aniState->rssiThrLow) {
231
+		if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
232
+			ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
233
+					     aniState->firstepLevel + 1);
234
+	} else {
235
+		if ((ah->dev->channels + ah->dev->channel)->band == NET80211_BAND_2GHZ) {
236
+			if (aniState->firstepLevel > 0)
237
+				ath9k_hw_ani_control(ah,
238
+					     ATH9K_ANI_FIRSTEP_LEVEL, 0);
239
+		}
240
+	}
241
+}
242
+
243
+/* Adjust the OFDM Noise Immunity Level */
244
+static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel)
245
+{
246
+	struct ar5416AniState *aniState = &ah->curchan->ani;
247
+	const struct ani_ofdm_level_entry *entry_ofdm;
248
+	const struct ani_cck_level_entry *entry_cck;
249
+
250
+	aniState->noiseFloor = BEACON_RSSI(ah);
251
+
252
+	DBG2("ath9k: "
253
+		"**** ofdmlevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
254
+		aniState->ofdmNoiseImmunityLevel,
255
+		immunityLevel, aniState->noiseFloor,
256
+		aniState->rssiThrLow, aniState->rssiThrHigh);
257
+
258
+	aniState->ofdmNoiseImmunityLevel = immunityLevel;
259
+
260
+	entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
261
+	entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
262
+
263
+	if (aniState->spurImmunityLevel != entry_ofdm->spur_immunity_level)
264
+		ath9k_hw_ani_control(ah,
265
+				     ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
266
+				     entry_ofdm->spur_immunity_level);
267
+
268
+	if (aniState->firstepLevel != entry_ofdm->fir_step_level &&
269
+	    entry_ofdm->fir_step_level >= entry_cck->fir_step_level)
270
+		ath9k_hw_ani_control(ah,
271
+				     ATH9K_ANI_FIRSTEP_LEVEL,
272
+				     entry_ofdm->fir_step_level);
273
+}
274
+
275
+static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hw *ah)
276
+{
277
+	struct ar5416AniState *aniState;
278
+
279
+	if (!DO_ANI(ah))
280
+		return;
281
+
282
+	if (!use_new_ani(ah)) {
283
+		ath9k_hw_ani_ofdm_err_trigger_old(ah);
284
+		return;
285
+	}
286
+
287
+	aniState = &ah->curchan->ani;
288
+
289
+	if (aniState->ofdmNoiseImmunityLevel < ATH9K_ANI_OFDM_MAX_LEVEL)
290
+		ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel + 1);
291
+}
292
+
293
+/*
294
+ * Set the ANI settings to match an CCK level.
295
+ */
296
+static void ath9k_hw_set_cck_nil(struct ath_hw *ah, uint8_t immunityLevel)
297
+{
298
+	struct ar5416AniState *aniState = &ah->curchan->ani;
299
+	const struct ani_ofdm_level_entry *entry_ofdm;
300
+	const struct ani_cck_level_entry *entry_cck;
301
+
302
+	aniState->noiseFloor = BEACON_RSSI(ah);
303
+	DBG2("ath9k: "
304
+		"**** ccklevel %d=>%d, rssi=%d[lo=%d hi=%d]\n",
305
+		aniState->cckNoiseImmunityLevel, immunityLevel,
306
+		aniState->noiseFloor, aniState->rssiThrLow,
307
+		aniState->rssiThrHigh);
308
+
309
+	if (aniState->noiseFloor <= (unsigned int)aniState->rssiThrLow &&
310
+	    immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
311
+		immunityLevel = ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI;
312
+
313
+	aniState->cckNoiseImmunityLevel = immunityLevel;
314
+
315
+	entry_ofdm = &ofdm_level_table[aniState->ofdmNoiseImmunityLevel];
316
+	entry_cck = &cck_level_table[aniState->cckNoiseImmunityLevel];
317
+
318
+	if (aniState->firstepLevel != entry_cck->fir_step_level &&
319
+	    entry_cck->fir_step_level >= entry_ofdm->fir_step_level)
320
+		ath9k_hw_ani_control(ah,
321
+				     ATH9K_ANI_FIRSTEP_LEVEL,
322
+				     entry_cck->fir_step_level);
323
+
324
+	/* Skip MRC CCK for pre AR9003 families */
325
+	if (!AR_SREV_9300_20_OR_LATER(ah) || AR_SREV_9485(ah))
326
+		return;
327
+
328
+	if (aniState->mrcCCKOff == entry_cck->mrc_cck_on)
329
+		ath9k_hw_ani_control(ah,
330
+				     ATH9K_ANI_MRC_CCK,
331
+				     entry_cck->mrc_cck_on);
332
+}
333
+
334
+static void ath9k_hw_ani_cck_err_trigger(struct ath_hw *ah)
335
+{
336
+	struct ar5416AniState *aniState;
337
+
338
+	if (!DO_ANI(ah))
339
+		return;
340
+
341
+	if (!use_new_ani(ah)) {
342
+		ath9k_hw_ani_cck_err_trigger_old(ah);
343
+		return;
344
+	}
345
+
346
+	aniState = &ah->curchan->ani;
347
+
348
+	if (aniState->cckNoiseImmunityLevel < ATH9K_ANI_CCK_MAX_LEVEL)
349
+		ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel + 1);
350
+}
351
+
352
+static void ath9k_hw_ani_lower_immunity_old(struct ath_hw *ah)
353
+{
354
+	struct ar5416AniState *aniState;
355
+	int32_t rssi;
356
+
357
+	aniState = &ah->curchan->ani;
358
+
359
+	rssi = BEACON_RSSI(ah);
360
+	if (rssi > aniState->rssiThrHigh) {
361
+		/* XXX: Handle me */
362
+	} else if (rssi > aniState->rssiThrLow) {
363
+		if (aniState->ofdmWeakSigDetectOff) {
364
+			if (ath9k_hw_ani_control(ah,
365
+				 ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
366
+				 1) == 1)
367
+				return;
368
+		}
369
+		if (aniState->firstepLevel > 0) {
370
+			if (ath9k_hw_ani_control(ah,
371
+				 ATH9K_ANI_FIRSTEP_LEVEL,
372
+				 aniState->firstepLevel - 1) == 1)
373
+				return;
374
+		}
375
+	} else {
376
+		if (aniState->firstepLevel > 0) {
377
+			if (ath9k_hw_ani_control(ah,
378
+				 ATH9K_ANI_FIRSTEP_LEVEL,
379
+				 aniState->firstepLevel - 1) == 1)
380
+				return;
381
+		}
382
+	}
383
+
384
+	if (aniState->spurImmunityLevel > 0) {
385
+		if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
386
+					 aniState->spurImmunityLevel - 1))
387
+			return;
388
+	}
389
+
390
+	if (aniState->noiseImmunityLevel > 0) {
391
+		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
392
+				     aniState->noiseImmunityLevel - 1);
393
+		return;
394
+	}
395
+}
396
+
397
+/*
398
+ * only lower either OFDM or CCK errors per turn
399
+ * we lower the other one next time
400
+ */
401
+static void ath9k_hw_ani_lower_immunity(struct ath_hw *ah)
402
+{
403
+	struct ar5416AniState *aniState;
404
+
405
+	aniState = &ah->curchan->ani;
406
+
407
+	if (!use_new_ani(ah)) {
408
+		ath9k_hw_ani_lower_immunity_old(ah);
409
+		return;
410
+	}
411
+
412
+	/* lower OFDM noise immunity */
413
+	if (aniState->ofdmNoiseImmunityLevel > 0 &&
414
+	    (aniState->ofdmsTurn || aniState->cckNoiseImmunityLevel == 0)) {
415
+		ath9k_hw_set_ofdm_nil(ah, aniState->ofdmNoiseImmunityLevel - 1);
416
+		return;
417
+	}
418
+
419
+	/* lower CCK noise immunity */
420
+	if (aniState->cckNoiseImmunityLevel > 0)
421
+		ath9k_hw_set_cck_nil(ah, aniState->cckNoiseImmunityLevel - 1);
422
+}
423
+
424
+static void ath9k_ani_reset_old(struct ath_hw *ah)
425
+{
426
+	struct ar5416AniState *aniState;
427
+
428
+	if (!DO_ANI(ah))
429
+		return;
430
+
431
+	aniState = &ah->curchan->ani;
432
+
433
+	if (aniState->noiseImmunityLevel != 0)
434
+		ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
435
+				     aniState->noiseImmunityLevel);
436
+	if (aniState->spurImmunityLevel != 0)
437
+		ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
438
+				     aniState->spurImmunityLevel);
439
+	if (aniState->ofdmWeakSigDetectOff)
440
+		ath9k_hw_ani_control(ah, ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
441
+				     !aniState->ofdmWeakSigDetectOff);
442
+	if (aniState->cckWeakSigThreshold)
443
+		ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
444
+				     aniState->cckWeakSigThreshold);
445
+	if (aniState->firstepLevel != 0)
446
+		ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
447
+				     aniState->firstepLevel);
448
+
449
+	ath9k_hw_setrxfilter(ah, ath9k_hw_getrxfilter(ah) &
450
+			     ~ATH9K_RX_FILTER_PHYERR);
451
+	ath9k_ani_restart(ah);
452
+
453
+	ENABLE_REGWRITE_BUFFER(ah);
454
+
455
+	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
456
+	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
457
+
458
+	REGWRITE_BUFFER_FLUSH(ah);
459
+}
460
+
461
+/*
462
+ * Restore the ANI parameters in the HAL and reset the statistics.
463
+ * This routine should be called for every hardware reset and for
464
+ * every channel change.
465
+ */
466
+void ath9k_ani_reset(struct ath_hw *ah, int is_scanning)
467
+{
468
+	struct ar5416AniState *aniState = &ah->curchan->ani;
469
+	struct ath9k_channel *chan = ah->curchan;
470
+
471
+	if (!DO_ANI(ah))
472
+		return;
473
+
474
+	if (!use_new_ani(ah))
475
+		return ath9k_ani_reset_old(ah);
476
+
477
+	ah->stats.ast_ani_reset++;
478
+
479
+	/* always allow mode (on/off) to be controlled */
480
+	ah->ani_function |= ATH9K_ANI_MODE;
481
+
482
+	if (is_scanning) {
483
+		/*
484
+		 * If we're scanning or in AP mode, the defaults (ini)
485
+		 * should be in place. For an AP we assume the historical
486
+		 * levels for this channel are probably outdated so start
487
+		 * from defaults instead.
488
+		 */
489
+		if (aniState->ofdmNoiseImmunityLevel !=
490
+		    ATH9K_ANI_OFDM_DEF_LEVEL ||
491
+		    aniState->cckNoiseImmunityLevel !=
492
+		    ATH9K_ANI_CCK_DEF_LEVEL) {
493
+			DBG("ath9k: "
494
+				"Restore defaults: chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
495
+				chan->channel,
496
+				chan->channelFlags,
497
+				is_scanning,
498
+				aniState->ofdmNoiseImmunityLevel,
499
+				aniState->cckNoiseImmunityLevel);
500
+
501
+			ath9k_hw_set_ofdm_nil(ah, ATH9K_ANI_OFDM_DEF_LEVEL);
502
+			ath9k_hw_set_cck_nil(ah, ATH9K_ANI_CCK_DEF_LEVEL);
503
+		}
504
+	} else {
505
+		/*
506
+		 * restore historical levels for this channel
507
+		 */
508
+		DBG2("ath9k: "
509
+			"Restore history: chan %d Mhz/0x%x is_scanning=%d ofdm:%d cck:%d\n",
510
+			chan->channel,
511
+			chan->channelFlags,
512
+			is_scanning,
513
+			aniState->ofdmNoiseImmunityLevel,
514
+			aniState->cckNoiseImmunityLevel);
515
+
516
+			ath9k_hw_set_ofdm_nil(ah,
517
+					      aniState->ofdmNoiseImmunityLevel);
518
+			ath9k_hw_set_cck_nil(ah,
519
+					     aniState->cckNoiseImmunityLevel);
520
+	}
521
+
522
+	/*
523
+	 * enable phy counters if hw supports or if not, enable phy
524
+	 * interrupts (so we can count each one)
525
+	 */
526
+	ath9k_ani_restart(ah);
527
+
528
+	ENABLE_REGWRITE_BUFFER(ah);
529
+
530
+	REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
531
+	REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
532
+
533
+	REGWRITE_BUFFER_FLUSH(ah);
534
+}
535
+
536
+static int ath9k_hw_ani_read_counters(struct ath_hw *ah)
537
+{
538
+	struct ath_common *common = ath9k_hw_common(ah);
539
+	struct ar5416AniState *aniState = &ah->curchan->ani;
540
+	u32 ofdm_base = 0;
541
+	u32 cck_base = 0;
542
+	u32 ofdmPhyErrCnt, cckPhyErrCnt;
543
+	u32 phyCnt1, phyCnt2;
544
+	int32_t listenTime;
545
+
546
+	ath_hw_cycle_counters_update(common);
547
+	listenTime = ath_hw_get_listen_time(common);
548
+
549
+	if (listenTime <= 0) {
550
+		ah->stats.ast_ani_lneg++;
551
+		ath9k_ani_restart(ah);
552
+		return 0;
553
+	}
554
+
555
+	if (!use_new_ani(ah)) {
556
+		ofdm_base = AR_PHY_COUNTMAX - ah->config.ofdm_trig_high;
557
+		cck_base = AR_PHY_COUNTMAX - ah->config.cck_trig_high;
558
+	}
559
+
560
+	aniState->listenTime += listenTime;
561
+
562
+	phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
563
+	phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
564
+
565
+	if (!use_new_ani(ah) && (phyCnt1 < ofdm_base || phyCnt2 < cck_base)) {
566
+		if (phyCnt1 < ofdm_base) {
567
+			DBG2("ath9k: "
568
+				"phyCnt1 0x%x, resetting counter value to 0x%x\n",
569
+				phyCnt1, ofdm_base);
570
+			REG_WRITE(ah, AR_PHY_ERR_1, ofdm_base);
571
+			REG_WRITE(ah, AR_PHY_ERR_MASK_1,
572
+				  AR_PHY_ERR_OFDM_TIMING);
573
+		}
574
+		if (phyCnt2 < cck_base) {
575
+			DBG2("ath9k: "
576
+				"phyCnt2 0x%x, resetting counter value to 0x%x\n",
577
+				phyCnt2, cck_base);
578
+			REG_WRITE(ah, AR_PHY_ERR_2, cck_base);
579
+			REG_WRITE(ah, AR_PHY_ERR_MASK_2,
580
+				  AR_PHY_ERR_CCK_TIMING);
581
+		}
582
+		return 0;
583
+	}
584
+
585
+	ofdmPhyErrCnt = phyCnt1 - ofdm_base;
586
+	ah->stats.ast_ani_ofdmerrs +=
587
+		ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
588
+	aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
589
+
590
+	cckPhyErrCnt = phyCnt2 - cck_base;
591
+	ah->stats.ast_ani_cckerrs +=
592
+		cckPhyErrCnt - aniState->cckPhyErrCount;
593
+	aniState->cckPhyErrCount = cckPhyErrCnt;
594
+	return 1;
595
+}
596
+
597
+void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan __unused)
598
+{
599
+	struct ar5416AniState *aniState;
600
+	u32 ofdmPhyErrRate, cckPhyErrRate;
601
+
602
+	if (!DO_ANI(ah))
603
+		return;
604
+
605
+	aniState = &ah->curchan->ani;
606
+	if (!aniState)
607
+		return;
608
+
609
+	if (!ath9k_hw_ani_read_counters(ah))
610
+		return;
611
+
612
+	ofdmPhyErrRate = aniState->ofdmPhyErrCount * 1000 /
613
+			 aniState->listenTime;
614
+	cckPhyErrRate =  aniState->cckPhyErrCount * 1000 /
615
+			 aniState->listenTime;
616
+
617
+	DBG2("ath9k: "
618
+		"listenTime=%d OFDM:%d errs=%d/s CCK:%d errs=%d/s ofdm_turn=%d\n",
619
+		aniState->listenTime,
620
+		aniState->ofdmNoiseImmunityLevel,
621
+		ofdmPhyErrRate, aniState->cckNoiseImmunityLevel,
622
+		cckPhyErrRate, aniState->ofdmsTurn);
623
+
624
+	if (aniState->listenTime > 5 * ah->aniperiod) {
625
+		if (ofdmPhyErrRate <= ah->config.ofdm_trig_low &&
626
+		    cckPhyErrRate <= ah->config.cck_trig_low) {
627
+			ath9k_hw_ani_lower_immunity(ah);
628
+			aniState->ofdmsTurn = !aniState->ofdmsTurn;
629
+		}
630
+		ath9k_ani_restart(ah);
631
+	} else if (aniState->listenTime > ah->aniperiod) {
632
+		/* check to see if need to raise immunity */
633
+		if (ofdmPhyErrRate > ah->config.ofdm_trig_high &&
634
+		    (cckPhyErrRate <= ah->config.cck_trig_high ||
635
+		     aniState->ofdmsTurn)) {
636
+			ath9k_hw_ani_ofdm_err_trigger(ah);
637
+			ath9k_ani_restart(ah);
638
+			aniState->ofdmsTurn = 0;
639
+		} else if (cckPhyErrRate > ah->config.cck_trig_high) {
640
+			ath9k_hw_ani_cck_err_trigger(ah);
641
+			ath9k_ani_restart(ah);
642
+			aniState->ofdmsTurn = 1;
643
+		}
644
+	}
645
+}
646
+
647
+void ath9k_hw_ani_setup(struct ath_hw *ah)
648
+{
649
+	int i;
650
+
651
+	static const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
652
+	static const int coarseHigh[] = { -14, -14, -14, -14, -12 };
653
+	static const int coarseLow[] = { -64, -64, -64, -64, -70 };
654
+	static const int firpwr[] = { -78, -78, -78, -78, -80 };
655
+
656
+	for (i = 0; i < 5; i++) {
657
+		ah->totalSizeDesired[i] = totalSizeDesired[i];
658
+		ah->coarse_high[i] = coarseHigh[i];
659
+		ah->coarse_low[i] = coarseLow[i];
660
+		ah->firpwr[i] = firpwr[i];
661
+	}
662
+}
663
+
664
+void ath9k_hw_ani_init(struct ath_hw *ah)
665
+{
666
+	unsigned int i;
667
+
668
+	DBG2("ath9k: Initialize ANI\n");
669
+
670
+	if (use_new_ani(ah)) {
671
+		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_NEW;
672
+		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_NEW;
673
+
674
+		ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_NEW;
675
+		ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_NEW;
676
+	} else {
677
+		ah->config.ofdm_trig_high = ATH9K_ANI_OFDM_TRIG_HIGH_OLD;
678
+		ah->config.ofdm_trig_low = ATH9K_ANI_OFDM_TRIG_LOW_OLD;
679
+
680
+		ah->config.cck_trig_high = ATH9K_ANI_CCK_TRIG_HIGH_OLD;
681
+		ah->config.cck_trig_low = ATH9K_ANI_CCK_TRIG_LOW_OLD;
682
+	}
683
+
684
+	for (i = 0; i < ARRAY_SIZE(ah->channels); i++) {
685
+		struct ath9k_channel *chan = &ah->channels[i];
686
+		struct ar5416AniState *ani = &chan->ani;
687
+
688
+		if (use_new_ani(ah)) {
689
+			ani->spurImmunityLevel =
690
+				ATH9K_ANI_SPUR_IMMUNE_LVL_NEW;
691
+
692
+			ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_NEW;
693
+
694
+			if (AR_SREV_9300_20_OR_LATER(ah))
695
+				ani->mrcCCKOff =
696
+					!ATH9K_ANI_ENABLE_MRC_CCK;
697
+			else
698
+				ani->mrcCCKOff = 1;
699
+
700
+			ani->ofdmsTurn = 1;
701
+		} else {
702
+			ani->spurImmunityLevel =
703
+				ATH9K_ANI_SPUR_IMMUNE_LVL_OLD;
704
+			ani->firstepLevel = ATH9K_ANI_FIRSTEP_LVL_OLD;
705
+
706
+			ani->cckWeakSigThreshold =
707
+				ATH9K_ANI_CCK_WEAK_SIG_THR;
708
+		}
709
+
710
+		ani->rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
711
+		ani->rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
712
+		ani->ofdmWeakSigDetectOff =
713
+			!ATH9K_ANI_USE_OFDM_WEAK_SIG;
714
+		ani->cckNoiseImmunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
715
+	}
716
+
717
+	/*
718
+	 * since we expect some ongoing maintenance on the tables, let's sanity
719
+	 * check here default level should not modify INI setting.
720
+	 */
721
+	if (use_new_ani(ah)) {
722
+		ah->aniperiod = ATH9K_ANI_PERIOD_NEW;
723
+		ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_NEW;
724
+	} else {
725
+		ah->aniperiod = ATH9K_ANI_PERIOD_OLD;
726
+		ah->config.ani_poll_interval = ATH9K_ANI_POLLINTERVAL_OLD;
727
+	}
728
+
729
+	if (ah->config.enable_ani)
730
+		ah->proc_phyerr |= HAL_PROCESS_ANI;
731
+
732
+	ath9k_ani_restart(ah);
733
+}

+ 1663
- 0
src/drivers/net/ath/ath9k/ath9k_ar5008_phy.c
File diff suppressed because it is too large
View File


+ 997
- 0
src/drivers/net/ath/ath9k/ath9k_ar9002_calib.c
File diff suppressed because it is too large
View File


+ 607
- 0
src/drivers/net/ath/ath9k/ath9k_ar9002_hw.c View File

@@ -0,0 +1,607 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 "hw.h"
21
+#include "ar5008_initvals.h"
22
+#include "ar9001_initvals.h"
23
+#include "ar9002_initvals.h"
24
+#include "ar9002_phy.h"
25
+
26
+int modparam_force_new_ani;
27
+
28
+/* General hardware code for the A5008/AR9001/AR9002 hadware families */
29
+
30
+static void ar9002_hw_init_mode_regs(struct ath_hw *ah)
31
+{
32
+	if (AR_SREV_9271(ah)) {
33
+		INIT_INI_ARRAY(&ah->iniModes, ar9271Modes_9271,
34
+			       ARRAY_SIZE(ar9271Modes_9271), 6);
35
+		INIT_INI_ARRAY(&ah->iniCommon, ar9271Common_9271,
36
+			       ARRAY_SIZE(ar9271Common_9271), 2);
37
+		INIT_INI_ARRAY(&ah->iniCommon_normal_cck_fir_coeff_9271,
38
+			       ar9271Common_normal_cck_fir_coeff_9271,
39
+			       ARRAY_SIZE(ar9271Common_normal_cck_fir_coeff_9271), 2);
40
+		INIT_INI_ARRAY(&ah->iniCommon_japan_2484_cck_fir_coeff_9271,
41
+			       ar9271Common_japan_2484_cck_fir_coeff_9271,
42
+			       ARRAY_SIZE(ar9271Common_japan_2484_cck_fir_coeff_9271), 2);
43
+		INIT_INI_ARRAY(&ah->iniModes_9271_1_0_only,
44
+			       ar9271Modes_9271_1_0_only,
45
+			       ARRAY_SIZE(ar9271Modes_9271_1_0_only), 6);
46
+		INIT_INI_ARRAY(&ah->iniModes_9271_ANI_reg, ar9271Modes_9271_ANI_reg,
47
+			       ARRAY_SIZE(ar9271Modes_9271_ANI_reg), 6);
48
+		INIT_INI_ARRAY(&ah->iniModes_high_power_tx_gain_9271,
49
+			       ar9271Modes_high_power_tx_gain_9271,
50
+			       ARRAY_SIZE(ar9271Modes_high_power_tx_gain_9271), 6);
51
+		INIT_INI_ARRAY(&ah->iniModes_normal_power_tx_gain_9271,
52
+			       ar9271Modes_normal_power_tx_gain_9271,
53
+			       ARRAY_SIZE(ar9271Modes_normal_power_tx_gain_9271), 6);
54
+		return;
55
+	}
56
+
57
+	if (AR_SREV_9287_11_OR_LATER(ah)) {
58
+		INIT_INI_ARRAY(&ah->iniModes, ar9287Modes_9287_1_1,
59
+				ARRAY_SIZE(ar9287Modes_9287_1_1), 6);
60
+		INIT_INI_ARRAY(&ah->iniCommon, ar9287Common_9287_1_1,
61
+				ARRAY_SIZE(ar9287Common_9287_1_1), 2);
62
+		if (ah->config.pcie_clock_req)
63
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
64
+			ar9287PciePhy_clkreq_off_L1_9287_1_1,
65
+			ARRAY_SIZE(ar9287PciePhy_clkreq_off_L1_9287_1_1), 2);
66
+		else
67
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
68
+			ar9287PciePhy_clkreq_always_on_L1_9287_1_1,
69
+			ARRAY_SIZE(ar9287PciePhy_clkreq_always_on_L1_9287_1_1),
70
+					2);
71
+	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
72
+
73
+
74
+		INIT_INI_ARRAY(&ah->iniModes, ar9285Modes_9285_1_2,
75
+			       ARRAY_SIZE(ar9285Modes_9285_1_2), 6);
76
+		INIT_INI_ARRAY(&ah->iniCommon, ar9285Common_9285_1_2,
77
+			       ARRAY_SIZE(ar9285Common_9285_1_2), 2);
78
+
79
+		if (ah->config.pcie_clock_req) {
80
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
81
+			ar9285PciePhy_clkreq_off_L1_9285_1_2,
82
+			ARRAY_SIZE(ar9285PciePhy_clkreq_off_L1_9285_1_2), 2);
83
+		} else {
84
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
85
+			ar9285PciePhy_clkreq_always_on_L1_9285_1_2,
86
+			ARRAY_SIZE(ar9285PciePhy_clkreq_always_on_L1_9285_1_2),
87
+				  2);
88
+		}
89
+	} else if (AR_SREV_9280_20_OR_LATER(ah)) {
90
+		INIT_INI_ARRAY(&ah->iniModes, ar9280Modes_9280_2,
91
+			       ARRAY_SIZE(ar9280Modes_9280_2), 6);
92
+		INIT_INI_ARRAY(&ah->iniCommon, ar9280Common_9280_2,
93
+			       ARRAY_SIZE(ar9280Common_9280_2), 2);
94
+
95
+		if (ah->config.pcie_clock_req) {
96
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
97
+			       ar9280PciePhy_clkreq_off_L1_9280,
98
+			       ARRAY_SIZE(ar9280PciePhy_clkreq_off_L1_9280), 2);
99
+		} else {
100
+			INIT_INI_ARRAY(&ah->iniPcieSerdes,
101
+			       ar9280PciePhy_clkreq_always_on_L1_9280,
102
+			       ARRAY_SIZE(ar9280PciePhy_clkreq_always_on_L1_9280), 2);
103
+		}
104
+		INIT_INI_ARRAY(&ah->iniModesAdditional,
105
+			       ar9280Modes_fast_clock_9280_2,
106
+			       ARRAY_SIZE(ar9280Modes_fast_clock_9280_2), 3);
107
+	} else if (AR_SREV_9160_10_OR_LATER(ah)) {
108
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9160,
109
+			       ARRAY_SIZE(ar5416Modes_9160), 6);
110
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9160,
111
+			       ARRAY_SIZE(ar5416Common_9160), 2);
112
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9160,
113
+			       ARRAY_SIZE(ar5416Bank0_9160), 2);
114
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9160,
115
+			       ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
116
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9160,
117
+			       ARRAY_SIZE(ar5416Bank1_9160), 2);
118
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9160,
119
+			       ARRAY_SIZE(ar5416Bank2_9160), 2);
120
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9160,
121
+			       ARRAY_SIZE(ar5416Bank3_9160), 3);
122
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9160,
123
+			       ARRAY_SIZE(ar5416Bank6_9160), 3);
124
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9160,
125
+			       ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
126
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9160,
127
+			       ARRAY_SIZE(ar5416Bank7_9160), 2);
128
+		if (AR_SREV_9160_11(ah)) {
129
+			INIT_INI_ARRAY(&ah->iniAddac,
130
+				       ar5416Addac_9160_1_1,
131
+				       ARRAY_SIZE(ar5416Addac_9160_1_1), 2);
132
+		} else {
133
+			INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9160,
134
+				       ARRAY_SIZE(ar5416Addac_9160), 2);
135
+		}
136
+	} else if (AR_SREV_9100_OR_LATER(ah)) {
137
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes_9100,
138
+			       ARRAY_SIZE(ar5416Modes_9100), 6);
139
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common_9100,
140
+			       ARRAY_SIZE(ar5416Common_9100), 2);
141
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0_9100,
142
+			       ARRAY_SIZE(ar5416Bank0_9100), 2);
143
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain_9100,
144
+			       ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
145
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1_9100,
146
+			       ARRAY_SIZE(ar5416Bank1_9100), 2);
147
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2_9100,
148
+			       ARRAY_SIZE(ar5416Bank2_9100), 2);
149
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3_9100,
150
+			       ARRAY_SIZE(ar5416Bank3_9100), 3);
151
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6_9100,
152
+			       ARRAY_SIZE(ar5416Bank6_9100), 3);
153
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC_9100,
154
+			       ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
155
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7_9100,
156
+			       ARRAY_SIZE(ar5416Bank7_9100), 2);
157
+		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac_9100,
158
+			       ARRAY_SIZE(ar5416Addac_9100), 2);
159
+	} else {
160
+		INIT_INI_ARRAY(&ah->iniModes, ar5416Modes,
161
+			       ARRAY_SIZE(ar5416Modes), 6);
162
+		INIT_INI_ARRAY(&ah->iniCommon, ar5416Common,
163
+			       ARRAY_SIZE(ar5416Common), 2);
164
+		INIT_INI_ARRAY(&ah->iniBank0, ar5416Bank0,
165
+			       ARRAY_SIZE(ar5416Bank0), 2);
166
+		INIT_INI_ARRAY(&ah->iniBB_RfGain, ar5416BB_RfGain,
167
+			       ARRAY_SIZE(ar5416BB_RfGain), 3);
168
+		INIT_INI_ARRAY(&ah->iniBank1, ar5416Bank1,
169
+			       ARRAY_SIZE(ar5416Bank1), 2);
170
+		INIT_INI_ARRAY(&ah->iniBank2, ar5416Bank2,
171
+			       ARRAY_SIZE(ar5416Bank2), 2);
172
+		INIT_INI_ARRAY(&ah->iniBank3, ar5416Bank3,
173
+			       ARRAY_SIZE(ar5416Bank3), 3);
174
+		INIT_INI_ARRAY(&ah->iniBank6, ar5416Bank6,
175
+			       ARRAY_SIZE(ar5416Bank6), 3);
176
+		INIT_INI_ARRAY(&ah->iniBank6TPC, ar5416Bank6TPC,
177
+			       ARRAY_SIZE(ar5416Bank6TPC), 3);
178
+		INIT_INI_ARRAY(&ah->iniBank7, ar5416Bank7,
179
+			       ARRAY_SIZE(ar5416Bank7), 2);
180
+		INIT_INI_ARRAY(&ah->iniAddac, ar5416Addac,
181
+			       ARRAY_SIZE(ar5416Addac), 2);
182
+	}
183
+}
184
+
185
+/* Support for Japan ch.14 (2484) spread */
186
+void ar9002_hw_cck_chan14_spread(struct ath_hw *ah)
187
+{
188
+	if (AR_SREV_9287_11_OR_LATER(ah)) {
189
+		INIT_INI_ARRAY(&ah->iniCckfirNormal,
190
+		       ar9287Common_normal_cck_fir_coeff_9287_1_1,
191
+		       ARRAY_SIZE(ar9287Common_normal_cck_fir_coeff_9287_1_1),
192
+		       2);
193
+		INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
194
+		       ar9287Common_japan_2484_cck_fir_coeff_9287_1_1,
195
+		       ARRAY_SIZE(ar9287Common_japan_2484_cck_fir_coeff_9287_1_1),
196
+		       2);
197
+	}
198
+}
199
+
200
+static void ar9280_20_hw_init_rxgain_ini(struct ath_hw *ah)
201
+{
202
+	u32 rxgain_type;
203
+
204
+	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
205
+	    AR5416_EEP_MINOR_VER_17) {
206
+		rxgain_type = ah->eep_ops->get_eeprom(ah, EEP_RXGAIN_TYPE);
207
+
208
+		if (rxgain_type == AR5416_EEP_RXGAIN_13DB_BACKOFF)
209
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
210
+			ar9280Modes_backoff_13db_rxgain_9280_2,
211
+			ARRAY_SIZE(ar9280Modes_backoff_13db_rxgain_9280_2), 6);
212
+		else if (rxgain_type == AR5416_EEP_RXGAIN_23DB_BACKOFF)
213
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
214
+			ar9280Modes_backoff_23db_rxgain_9280_2,
215
+			ARRAY_SIZE(ar9280Modes_backoff_23db_rxgain_9280_2), 6);
216
+		else
217
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
218
+			ar9280Modes_original_rxgain_9280_2,
219
+			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
220
+	} else {
221
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
222
+			ar9280Modes_original_rxgain_9280_2,
223
+			ARRAY_SIZE(ar9280Modes_original_rxgain_9280_2), 6);
224
+	}
225
+}
226
+
227
+static void ar9280_20_hw_init_txgain_ini(struct ath_hw *ah)
228
+{
229
+	u32 txgain_type;
230
+
231
+	if (ah->eep_ops->get_eeprom(ah, EEP_MINOR_REV) >=
232
+	    AR5416_EEP_MINOR_VER_19) {
233
+		txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
234
+
235
+		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER)
236
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
237
+			ar9280Modes_high_power_tx_gain_9280_2,
238
+			ARRAY_SIZE(ar9280Modes_high_power_tx_gain_9280_2), 6);
239
+		else
240
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
241
+			ar9280Modes_original_tx_gain_9280_2,
242
+			ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
243
+	} else {
244
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
245
+		ar9280Modes_original_tx_gain_9280_2,
246
+		ARRAY_SIZE(ar9280Modes_original_tx_gain_9280_2), 6);
247
+	}
248
+}
249
+
250
+static void ar9002_hw_init_mode_gain_regs(struct ath_hw *ah)
251
+{
252
+	if (AR_SREV_9287_11_OR_LATER(ah))
253
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
254
+		ar9287Modes_rx_gain_9287_1_1,
255
+		ARRAY_SIZE(ar9287Modes_rx_gain_9287_1_1), 6);
256
+	else if (AR_SREV_9280_20(ah))
257
+		ar9280_20_hw_init_rxgain_ini(ah);
258
+
259
+	if (AR_SREV_9287_11_OR_LATER(ah)) {
260
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
261
+		ar9287Modes_tx_gain_9287_1_1,
262
+		ARRAY_SIZE(ar9287Modes_tx_gain_9287_1_1), 6);
263
+	} else if (AR_SREV_9280_20(ah)) {
264
+		ar9280_20_hw_init_txgain_ini(ah);
265
+	} else if (AR_SREV_9285_12_OR_LATER(ah)) {
266
+		u32 txgain_type = ah->eep_ops->get_eeprom(ah, EEP_TXGAIN_TYPE);
267
+
268
+		/* txgain table */
269
+		if (txgain_type == AR5416_EEP_TXGAIN_HIGH_POWER) {
270
+			if (AR_SREV_9285E_20(ah)) {
271
+				INIT_INI_ARRAY(&ah->iniModesTxGain,
272
+				ar9285Modes_XE2_0_high_power,
273
+				ARRAY_SIZE(
274
+				  ar9285Modes_XE2_0_high_power), 6);
275
+			} else {
276
+				INIT_INI_ARRAY(&ah->iniModesTxGain,
277
+				ar9285Modes_high_power_tx_gain_9285_1_2,
278
+				ARRAY_SIZE(
279
+				  ar9285Modes_high_power_tx_gain_9285_1_2), 6);
280
+			}
281
+		} else {
282
+			if (AR_SREV_9285E_20(ah)) {
283
+				INIT_INI_ARRAY(&ah->iniModesTxGain,
284
+				ar9285Modes_XE2_0_normal_power,
285
+				ARRAY_SIZE(
286
+				  ar9285Modes_XE2_0_normal_power), 6);
287
+			} else {
288
+				INIT_INI_ARRAY(&ah->iniModesTxGain,
289
+				ar9285Modes_original_tx_gain_9285_1_2,
290
+				ARRAY_SIZE(
291
+				  ar9285Modes_original_tx_gain_9285_1_2), 6);
292
+			}
293
+		}
294
+	}
295
+}
296
+
297
+/*
298
+ * Helper for ASPM support.
299
+ *
300
+ * Disable PLL when in L0s as well as receiver clock when in L1.
301
+ * This power saving option must be enabled through the SerDes.
302
+ *
303
+ * Programming the SerDes must go through the same 288 bit serial shift
304
+ * register as the other analog registers.  Hence the 9 writes.
305
+ */
306
+static void ar9002_hw_configpcipowersave(struct ath_hw *ah,
307
+					 int restore,
308
+					 int power_off)
309
+{
310
+	u8 i;
311
+	u32 val;
312
+
313
+	if (ah->is_pciexpress != 1)
314
+		return;
315
+
316
+	/* Do not touch SerDes registers */
317
+	if (ah->config.pcie_powersave_enable == 2)
318
+		return;
319
+
320
+	/* Nothing to do on restore for 11N */
321
+	if (!restore) {
322
+		if (AR_SREV_9280_20_OR_LATER(ah)) {
323
+			/*
324
+			 * AR9280 2.0 or later chips use SerDes values from the
325
+			 * initvals.h initialized depending on chipset during
326
+			 * __ath9k_hw_init()
327
+			 */
328
+			for (i = 0; i < ah->iniPcieSerdes.ia_rows; i++) {
329
+				REG_WRITE(ah, INI_RA(&ah->iniPcieSerdes, i, 0),
330
+					  INI_RA(&ah->iniPcieSerdes, i, 1));
331
+			}
332
+		} else {
333
+			ENABLE_REGWRITE_BUFFER(ah);
334
+
335
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
336
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
337
+
338
+			/* RX shut off when elecidle is asserted */
339
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
340
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
341
+			REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
342
+
343
+			/*
344
+			 * Ignore ah->ah_config.pcie_clock_req setting for
345
+			 * pre-AR9280 11n
346
+			 */
347
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
348
+
349
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
350
+			REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
351
+			REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
352
+
353
+			/* Load the new settings */
354
+			REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
355
+
356
+			REGWRITE_BUFFER_FLUSH(ah);
357
+		}
358
+
359
+		udelay(1000);
360
+	}
361
+
362
+	if (power_off) {
363
+		/* clear bit 19 to disable L1 */
364
+		REG_CLR_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
365
+
366
+		val = REG_READ(ah, AR_WA);
367
+
368
+		/*
369
+		 * Set PCIe workaround bits
370
+		 * In AR9280 and AR9285, bit 14 in WA register (disable L1)
371
+		 * should only  be set when device enters D3 and be
372
+		 * cleared when device comes back to D0.
373
+		 */
374
+		if (ah->config.pcie_waen) {
375
+			if (ah->config.pcie_waen & AR_WA_D3_L1_DISABLE)
376
+				val |= AR_WA_D3_L1_DISABLE;
377
+		} else {
378
+			if (((AR_SREV_9285(ah) ||
379
+			      AR_SREV_9271(ah) ||
380
+			      AR_SREV_9287(ah)) &&
381
+			     (AR9285_WA_DEFAULT & AR_WA_D3_L1_DISABLE)) ||
382
+			    (AR_SREV_9280(ah) &&
383
+			     (AR9280_WA_DEFAULT & AR_WA_D3_L1_DISABLE))) {
384
+				val |= AR_WA_D3_L1_DISABLE;
385
+			}
386
+		}
387
+
388
+		if (AR_SREV_9280(ah) || AR_SREV_9285(ah) || AR_SREV_9287(ah)) {
389
+			/*
390
+			 * Disable bit 6 and 7 before entering D3 to
391
+			 * prevent system hang.
392
+			 */
393
+			val &= ~(AR_WA_BIT6 | AR_WA_BIT7);
394
+		}
395
+
396
+		if (AR_SREV_9280(ah))
397
+			val |= AR_WA_BIT22;
398
+
399
+		if (AR_SREV_9285E_20(ah))
400
+			val |= AR_WA_BIT23;
401
+
402
+		REG_WRITE(ah, AR_WA, val);
403
+	} else {
404
+		if (ah->config.pcie_waen) {
405
+			val = ah->config.pcie_waen;
406
+			if (!power_off)
407
+				val &= (~AR_WA_D3_L1_DISABLE);
408
+		} else {
409
+			if (AR_SREV_9285(ah) ||
410
+			    AR_SREV_9271(ah) ||
411
+			    AR_SREV_9287(ah)) {
412
+				val = AR9285_WA_DEFAULT;
413
+				if (!power_off)
414
+					val &= (~AR_WA_D3_L1_DISABLE);
415
+			}
416
+			else if (AR_SREV_9280(ah)) {
417
+				/*
418
+				 * For AR9280 chips, bit 22 of 0x4004
419
+				 * needs to be set.
420
+				 */
421
+				val = AR9280_WA_DEFAULT;
422
+				if (!power_off)
423
+					val &= (~AR_WA_D3_L1_DISABLE);
424
+			} else {
425
+				val = AR_WA_DEFAULT;
426
+			}
427
+		}
428
+
429
+		/* WAR for ASPM system hang */
430
+		if (AR_SREV_9285(ah) || AR_SREV_9287(ah))
431
+			val |= (AR_WA_BIT6 | AR_WA_BIT7);
432
+
433
+		if (AR_SREV_9285E_20(ah))
434
+			val |= AR_WA_BIT23;
435
+
436
+		REG_WRITE(ah, AR_WA, val);
437
+
438
+		/* set bit 19 to allow forcing of pcie core into L1 state */
439
+		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
440
+	}
441
+}
442
+
443
+static int ar9002_hw_get_radiorev(struct ath_hw *ah)
444
+{
445
+	u32 val;
446
+	int i;
447
+
448
+	ENABLE_REGWRITE_BUFFER(ah);
449
+
450
+	REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
451
+	for (i = 0; i < 8; i++)
452
+		REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
453
+
454
+	REGWRITE_BUFFER_FLUSH(ah);
455
+
456
+	val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
457
+	val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
458
+
459
+	return ath9k_hw_reverse_bits(val, 8);
460
+}
461
+
462
+int ar9002_hw_rf_claim(struct ath_hw *ah)
463
+{
464
+	u32 val;
465
+
466
+	REG_WRITE(ah, AR_PHY(0), 0x00000007);
467
+
468
+	val = ar9002_hw_get_radiorev(ah);
469
+	switch (val & AR_RADIO_SREV_MAJOR) {
470
+	case 0:
471
+		val = AR_RAD5133_SREV_MAJOR;
472
+		break;
473
+	case AR_RAD5133_SREV_MAJOR:
474
+	case AR_RAD5122_SREV_MAJOR:
475
+	case AR_RAD2133_SREV_MAJOR:
476
+	case AR_RAD2122_SREV_MAJOR:
477
+		break;
478
+	default:
479
+		DBG("ath9k: "
480
+			"Radio Chip Rev 0x%02X not supported\n",
481
+			val & AR_RADIO_SREV_MAJOR);
482
+		return -EOPNOTSUPP;
483
+	}
484
+
485
+	ah->hw_version.analog5GhzRev = val;
486
+
487
+	return 0;
488
+}
489
+
490
+void ar9002_hw_enable_async_fifo(struct ath_hw *ah)
491
+{
492
+	if (AR_SREV_9287_13_OR_LATER(ah)) {
493
+		REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
494
+				AR_MAC_PCU_ASYNC_FIFO_REG3_DATAPATH_SEL);
495
+		REG_SET_BIT(ah, AR_PHY_MODE, AR_PHY_MODE_ASYNCFIFO);
496
+		REG_CLR_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
497
+				AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
498
+		REG_SET_BIT(ah, AR_MAC_PCU_ASYNC_FIFO_REG3,
499
+				AR_MAC_PCU_ASYNC_FIFO_REG3_SOFT_RESET);
500
+	}
501
+}
502
+
503
+/*
504
+ * If Async FIFO is enabled, the following counters change as MAC now runs
505
+ * at 117 Mhz instead of 88/44MHz when async FIFO is disabled.
506
+ *
507
+ * The values below tested for ht40 2 chain.
508
+ * Overwrite the delay/timeouts initialized in process ini.
509
+ */
510
+void ar9002_hw_update_async_fifo(struct ath_hw *ah)
511
+{
512
+	if (AR_SREV_9287_13_OR_LATER(ah)) {
513
+		REG_WRITE(ah, AR_D_GBL_IFS_SIFS,
514
+			  AR_D_GBL_IFS_SIFS_ASYNC_FIFO_DUR);
515
+		REG_WRITE(ah, AR_D_GBL_IFS_SLOT,
516
+			  AR_D_GBL_IFS_SLOT_ASYNC_FIFO_DUR);
517
+		REG_WRITE(ah, AR_D_GBL_IFS_EIFS,
518
+			  AR_D_GBL_IFS_EIFS_ASYNC_FIFO_DUR);
519
+
520
+		REG_WRITE(ah, AR_TIME_OUT, AR_TIME_OUT_ACK_CTS_ASYNC_FIFO_DUR);
521
+		REG_WRITE(ah, AR_USEC, AR_USEC_ASYNC_FIFO_DUR);
522
+
523
+		REG_SET_BIT(ah, AR_MAC_PCU_LOGIC_ANALYZER,
524
+			    AR_MAC_PCU_LOGIC_ANALYZER_DISBUG20768);
525
+		REG_RMW_FIELD(ah, AR_AHB_MODE, AR_AHB_CUSTOM_BURST_EN,
526
+			      AR_AHB_CUSTOM_BURST_ASYNC_FIFO_VAL);
527
+	}
528
+}
529
+
530
+/*
531
+ * We don't enable WEP aggregation on mac80211 but we keep this
532
+ * around for HAL unification purposes.
533
+ */
534
+void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah)
535
+{
536
+	if (AR_SREV_9287_13_OR_LATER(ah)) {
537
+		REG_SET_BIT(ah, AR_PCU_MISC_MODE2,
538
+			    AR_PCU_MISC_MODE2_ENABLE_AGGWEP);
539
+	}
540
+}
541
+
542
+/* Sets up the AR5008/AR9001/AR9002 hardware familiy callbacks */
543
+void ar9002_hw_attach_ops(struct ath_hw *ah)
544
+{
545
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
546
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
547
+
548
+	priv_ops->init_mode_regs = ar9002_hw_init_mode_regs;
549
+	priv_ops->init_mode_gain_regs = ar9002_hw_init_mode_gain_regs;
550
+
551
+	ops->config_pci_powersave = ar9002_hw_configpcipowersave;
552
+
553
+	ar5008_hw_attach_phy_ops(ah);
554
+	if (AR_SREV_9280_20_OR_LATER(ah))
555
+		ar9002_hw_attach_phy_ops(ah);
556
+
557
+	ar9002_hw_attach_calib_ops(ah);
558
+	ar9002_hw_attach_mac_ops(ah);
559
+}
560
+
561
+void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan)
562
+{
563
+	u32 modesIndex;
564
+	unsigned int i;
565
+
566
+	switch (chan->chanmode) {
567
+	case CHANNEL_A:
568
+	case CHANNEL_A_HT20:
569
+		modesIndex = 1;
570
+		break;
571
+	case CHANNEL_A_HT40PLUS:
572
+	case CHANNEL_A_HT40MINUS:
573
+		modesIndex = 2;
574
+		break;
575
+	case CHANNEL_G:
576
+	case CHANNEL_G_HT20:
577
+	case CHANNEL_B:
578
+		modesIndex = 4;
579
+		break;
580
+	case CHANNEL_G_HT40PLUS:
581
+	case CHANNEL_G_HT40MINUS:
582
+		modesIndex = 3;
583
+		break;
584
+
585
+	default:
586
+		return;
587
+	}
588
+
589
+	ENABLE_REGWRITE_BUFFER(ah);
590
+
591
+	for (i = 0; i < ah->iniModes_9271_ANI_reg.ia_rows; i++) {
592
+		u32 reg = INI_RA(&ah->iniModes_9271_ANI_reg, i, 0);
593
+		u32 val = INI_RA(&ah->iniModes_9271_ANI_reg, i, modesIndex);
594
+		u32 val_orig;
595
+
596
+		if (reg == AR_PHY_CCK_DETECT) {
597
+			val_orig = REG_READ(ah, reg);
598
+			val &= AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
599
+			val_orig &= ~AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK;
600
+
601
+			REG_WRITE(ah, reg, val|val_orig);
602
+		} else
603
+			REG_WRITE(ah, reg, val);
604
+	}
605
+
606
+	REGWRITE_BUFFER_FLUSH(ah);
607
+}

+ 454
- 0
src/drivers/net/ath/ath9k/ath9k_ar9002_mac.c View File

@@ -0,0 +1,454 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/io.h>
21
+
22
+#include "hw.h"
23
+
24
+#define AR_BufLen           0x00000fff
25
+
26
+static void ar9002_hw_rx_enable(struct ath_hw *ah)
27
+{
28
+	REG_WRITE(ah, AR_CR, AR_CR_RXE);
29
+}
30
+
31
+static void ar9002_hw_set_desc_link(void *ds, u32 ds_link)
32
+{
33
+	((struct ath_desc*) ds)->ds_link = ds_link;
34
+}
35
+
36
+static void ar9002_hw_get_desc_link(void *ds, u32 **ds_link)
37
+{
38
+	*ds_link = &((struct ath_desc *)ds)->ds_link;
39
+}
40
+
41
+static int ar9002_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
42
+{
43
+	u32 isr = 0;
44
+	u32 mask2 = 0;
45
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
46
+	u32 sync_cause = 0;
47
+	int fatal_int = 0;
48
+
49
+	if (!AR_SREV_9100(ah) && (ah->ah_ier & AR_IER_ENABLE)) {
50
+		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
51
+			if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
52
+			    == AR_RTC_STATUS_ON) {
53
+				isr = REG_READ(ah, AR_ISR);
54
+			}
55
+		}
56
+
57
+		sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) &
58
+			AR_INTR_SYNC_DEFAULT;
59
+
60
+		*masked = 0;
61
+
62
+		if (!isr && !sync_cause)
63
+			return 0;
64
+	} else {
65
+		*masked = 0;
66
+		isr = REG_READ(ah, AR_ISR);
67
+	}
68
+
69
+	if (isr) {
70
+		if (isr & AR_ISR_BCNMISC) {
71
+			u32 isr2;
72
+			isr2 = REG_READ(ah, AR_ISR_S2);
73
+			if (isr2 & AR_ISR_S2_TIM)
74
+				mask2 |= ATH9K_INT_TIM;
75
+			if (isr2 & AR_ISR_S2_DTIM)
76
+				mask2 |= ATH9K_INT_DTIM;
77
+			if (isr2 & AR_ISR_S2_DTIMSYNC)
78
+				mask2 |= ATH9K_INT_DTIMSYNC;
79
+			if (isr2 & (AR_ISR_S2_CABEND))
80
+				mask2 |= ATH9K_INT_CABEND;
81
+			if (isr2 & AR_ISR_S2_GTT)
82
+				mask2 |= ATH9K_INT_GTT;
83
+			if (isr2 & AR_ISR_S2_CST)
84
+				mask2 |= ATH9K_INT_CST;
85
+			if (isr2 & AR_ISR_S2_TSFOOR)
86
+				mask2 |= ATH9K_INT_TSFOOR;
87
+		}
88
+
89
+		isr = REG_READ(ah, AR_ISR_RAC);
90
+		if (isr == 0xffffffff) {
91
+			*masked = 0;
92
+			return 0;
93
+		}
94
+
95
+		*masked = isr & ATH9K_INT_COMMON;
96
+
97
+		if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM |
98
+			   AR_ISR_RXOK | AR_ISR_RXERR))
99
+			*masked |= ATH9K_INT_RX;
100
+
101
+		if (isr &
102
+		    (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
103
+		     AR_ISR_TXEOL)) {
104
+			u32 s0_s, s1_s;
105
+
106
+			*masked |= ATH9K_INT_TX;
107
+
108
+			s0_s = REG_READ(ah, AR_ISR_S0_S);
109
+			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
110
+			ah->intr_txqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
111
+
112
+			s1_s = REG_READ(ah, AR_ISR_S1_S);
113
+			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
114
+			ah->intr_txqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
115
+		}
116
+
117
+		if (isr & AR_ISR_RXORN) {
118
+			DBG("ath9k: "
119
+				"receive FIFO overrun interrupt\n");
120
+		}
121
+
122
+		*masked |= mask2;
123
+	}
124
+
125
+	if (AR_SREV_9100(ah))
126
+		return 1;
127
+
128
+	if (isr & AR_ISR_GENTMR) {
129
+		u32 s5_s;
130
+
131
+		s5_s = REG_READ(ah, AR_ISR_S5_S);
132
+		ah->intr_gen_timer_trigger =
133
+				MS(s5_s, AR_ISR_S5_GENTIMER_TRIG);
134
+
135
+		ah->intr_gen_timer_thresh =
136
+			MS(s5_s, AR_ISR_S5_GENTIMER_THRESH);
137
+
138
+		if (ah->intr_gen_timer_trigger)
139
+			*masked |= ATH9K_INT_GENTIMER;
140
+
141
+		if ((s5_s & AR_ISR_S5_TIM_TIMER) &&
142
+		    !(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
143
+			*masked |= ATH9K_INT_TIM_TIMER;
144
+	}
145
+
146
+	if (sync_cause) {
147
+		fatal_int =
148
+			(sync_cause &
149
+			 (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
150
+			? 1 : 0;
151
+
152
+		if (fatal_int) {
153
+			if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
154
+				DBG("ath9k: "
155
+					"received PCI FATAL interrupt\n");
156
+			}
157
+			if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
158
+				DBG("ath9k: "
159
+					"received PCI PERR interrupt\n");
160
+			}
161
+			*masked |= ATH9K_INT_FATAL;
162
+		}
163
+		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
164
+			DBG("ath9k: "
165
+				"AR_INTR_SYNC_RADM_CPL_TIMEOUT\n");
166
+			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
167
+			REG_WRITE(ah, AR_RC, 0);
168
+			*masked |= ATH9K_INT_FATAL;
169
+		}
170
+		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
171
+			DBG("ath9k: "
172
+				"AR_INTR_SYNC_LOCAL_TIMEOUT\n");
173
+		}
174
+
175
+		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
176
+		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
177
+	}
178
+
179
+	return 1;
180
+}
181
+
182
+static void ar9002_hw_fill_txdesc(struct ath_hw *ah __unused, void *ds, u32 seglen,
183
+				  int is_firstseg, int is_lastseg,
184
+				  const void *ds0, u32 buf_addr,
185
+				  unsigned int qcu __unused)
186
+{
187
+	struct ar5416_desc *ads = AR5416DESC(ds);
188
+
189
+	ads->ds_data = buf_addr;
190
+
191
+	if (is_firstseg) {
192
+		ads->ds_ctl1 |= seglen | (is_lastseg ? 0 : AR_TxMore);
193
+	} else if (is_lastseg) {
194
+		ads->ds_ctl0 = 0;
195
+		ads->ds_ctl1 = seglen;
196
+		ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
197
+		ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
198
+	} else {
199
+		ads->ds_ctl0 = 0;
200
+		ads->ds_ctl1 = seglen | AR_TxMore;
201
+		ads->ds_ctl2 = 0;
202
+		ads->ds_ctl3 = 0;
203
+	}
204
+	ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
205
+	ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
206
+	ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
207
+	ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
208
+	ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
209
+}
210
+
211
+static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
212
+				 struct ath_tx_status *ts)
213
+{
214
+	struct ar5416_desc *ads = AR5416DESC(ds);
215
+	u32 status;
216
+
217
+	status = *(volatile typeof(ads->ds_txstatus9) *)&(ads->ds_txstatus9);
218
+	if ((status & AR_TxDone) == 0)
219
+		return -EINPROGRESS;
220
+
221
+	ts->ts_tstamp = ads->AR_SendTimestamp;
222
+	ts->ts_status = 0;
223
+	ts->ts_flags = 0;
224
+
225
+	if (status & AR_TxOpExceeded)
226
+		ts->ts_status |= ATH9K_TXERR_XTXOP;
227
+	ts->tid = MS(status, AR_TxTid);
228
+	ts->ts_rateindex = MS(status, AR_FinalTxIdx);
229
+	ts->ts_seqnum = MS(status, AR_SeqNum);
230
+
231
+	status = *(volatile typeof(ads->ds_txstatus0) *)&(ads->ds_txstatus0);
232
+	ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
233
+	ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
234
+	ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
235
+	if (status & AR_TxBaStatus) {
236
+		ts->ts_flags |= ATH9K_TX_BA;
237
+		ts->ba_low = ads->AR_BaBitmapLow;
238
+		ts->ba_high = ads->AR_BaBitmapHigh;
239
+	}
240
+
241
+	status = *(volatile typeof(ads->ds_txstatus1) *)&(ads->ds_txstatus1);
242
+	if (status & AR_FrmXmitOK)
243
+		ts->ts_status |= ATH9K_TX_ACKED;
244
+	else {
245
+		if (status & AR_ExcessiveRetries)
246
+			ts->ts_status |= ATH9K_TXERR_XRETRY;
247
+		if (status & AR_Filtered)
248
+			ts->ts_status |= ATH9K_TXERR_FILT;
249
+		if (status & AR_FIFOUnderrun) {
250
+			ts->ts_status |= ATH9K_TXERR_FIFO;
251
+			ath9k_hw_updatetxtriglevel(ah, 1);
252
+		}
253
+	}
254
+	if (status & AR_TxTimerExpired)
255
+		ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
256
+	if (status & AR_DescCfgErr)
257
+		ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
258
+	if (status & AR_TxDataUnderrun) {
259
+		ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
260
+		ath9k_hw_updatetxtriglevel(ah, 1);
261
+	}
262
+	if (status & AR_TxDelimUnderrun) {
263
+		ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
264
+		ath9k_hw_updatetxtriglevel(ah, 1);
265
+	}
266
+	ts->ts_shortretry = MS(status, AR_RTSFailCnt);
267
+	ts->ts_longretry = MS(status, AR_DataFailCnt);
268
+	ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
269
+
270
+	status = *(volatile typeof(ads->ds_txstatus5) *)&(ads->ds_txstatus5);
271
+	ts->ts_rssi = MS(status, AR_TxRSSICombined);
272
+	ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
273
+	ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
274
+	ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
275
+
276
+	ts->evm0 = ads->AR_TxEVM0;
277
+	ts->evm1 = ads->AR_TxEVM1;
278
+	ts->evm2 = ads->AR_TxEVM2;
279
+
280
+	return 0;
281
+}
282
+
283
+static void ar9002_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
284
+				    u32 pktLen, enum ath9k_pkt_type type,
285
+				    u32 txPower, u32 keyIx,
286
+				    enum ath9k_key_type keyType, u32 flags)
287
+{
288
+	struct ar5416_desc *ads = AR5416DESC(ds);
289
+
290
+	if (txPower > 63)
291
+		txPower = 63;
292
+
293
+	ads->ds_ctl0 = (pktLen & AR_FrameLen)
294
+		| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
295
+		| SM(txPower, AR_XmitPower)
296
+		| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
297
+		| (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
298
+		| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
299
+
300
+	ads->ds_ctl1 =
301
+		(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
302
+		| SM(type, AR_FrameType)
303
+		| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
304
+		| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
305
+		| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
306
+
307
+	ads->ds_ctl6 = SM(keyType, AR_EncrType);
308
+
309
+	if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
310
+		ads->ds_ctl8 = 0;
311
+		ads->ds_ctl9 = 0;
312
+		ads->ds_ctl10 = 0;
313
+		ads->ds_ctl11 = 0;
314
+	}
315
+}
316
+
317
+static void ar9002_hw_set_clrdmask(struct ath_hw *ah __unused, void *ds, int val)
318
+{
319
+	struct ar5416_desc *ads = AR5416DESC(ds);
320
+
321
+	if (val)
322
+		ads->ds_ctl0 |= AR_ClrDestMask;
323
+	else
324
+		ads->ds_ctl0 &= ~AR_ClrDestMask;
325
+}
326
+
327
+static void ar9002_hw_set11n_ratescenario(struct ath_hw *ah __unused, void *ds,
328
+					  void *lastds,
329
+					  u32 durUpdateEn, u32 rtsctsRate,
330
+					  u32 rtsctsDuration __unused,
331
+					  struct ath9k_11n_rate_series series[],
332
+					  u32 nseries __unused, u32 flags)
333
+{
334
+	struct ar5416_desc *ads = AR5416DESC(ds);
335
+	struct ar5416_desc *last_ads = AR5416DESC(lastds);
336
+	u32 ds_ctl0;
337
+
338
+	if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
339
+		ds_ctl0 = ads->ds_ctl0;
340
+
341
+		if (flags & ATH9K_TXDESC_RTSENA) {
342
+			ds_ctl0 &= ~AR_CTSEnable;
343
+			ds_ctl0 |= AR_RTSEnable;
344
+		} else {
345
+			ds_ctl0 &= ~AR_RTSEnable;
346
+			ds_ctl0 |= AR_CTSEnable;
347
+		}
348
+
349
+		ads->ds_ctl0 = ds_ctl0;
350
+	} else {
351
+		ads->ds_ctl0 =
352
+			(ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
353
+	}
354
+
355
+	ads->ds_ctl2 = set11nTries(series, 0)
356
+		| set11nTries(series, 1)
357
+		| set11nTries(series, 2)
358
+		| set11nTries(series, 3)
359
+		| (durUpdateEn ? AR_DurUpdateEna : 0)
360
+		| SM(0, AR_BurstDur);
361
+
362
+	ads->ds_ctl3 = set11nRate(series, 0)
363
+		| set11nRate(series, 1)
364
+		| set11nRate(series, 2)
365
+		| set11nRate(series, 3);
366
+
367
+	ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
368
+		| set11nPktDurRTSCTS(series, 1);
369
+
370
+	ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
371
+		| set11nPktDurRTSCTS(series, 3);
372
+
373
+	ads->ds_ctl7 = set11nRateFlags(series, 0)
374
+		| set11nRateFlags(series, 1)
375
+		| set11nRateFlags(series, 2)
376
+		| set11nRateFlags(series, 3)
377
+		| SM(rtsctsRate, AR_RTSCTSRate);
378
+	last_ads->ds_ctl2 = ads->ds_ctl2;
379
+	last_ads->ds_ctl3 = ads->ds_ctl3;
380
+}
381
+
382
+static void ar9002_hw_set11n_aggr_first(struct ath_hw *ah __unused, void *ds,
383
+					u32 aggrLen)
384
+{
385
+	struct ar5416_desc *ads = AR5416DESC(ds);
386
+
387
+	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
388
+	ads->ds_ctl6 &= ~AR_AggrLen;
389
+	ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
390
+}
391
+
392
+static void ar9002_hw_set11n_aggr_middle(struct ath_hw *ah __unused, void *ds,
393
+					 u32 numDelims)
394
+{
395
+	struct ar5416_desc *ads = AR5416DESC(ds);
396
+	unsigned int ctl6;
397
+
398
+	ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
399
+
400
+	ctl6 = ads->ds_ctl6;
401
+	ctl6 &= ~AR_PadDelim;
402
+	ctl6 |= SM(numDelims, AR_PadDelim);
403
+	ads->ds_ctl6 = ctl6;
404
+}
405
+
406
+static void ar9002_hw_set11n_aggr_last(struct ath_hw *ah __unused, void *ds)
407
+{
408
+	struct ar5416_desc *ads = AR5416DESC(ds);
409
+
410
+	ads->ds_ctl1 |= AR_IsAggr;
411
+	ads->ds_ctl1 &= ~AR_MoreAggr;
412
+	ads->ds_ctl6 &= ~AR_PadDelim;
413
+}
414
+
415
+static void ar9002_hw_clr11n_aggr(struct ath_hw *ah __unused, void *ds)
416
+{
417
+	struct ar5416_desc *ads = AR5416DESC(ds);
418
+
419
+	ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
420
+}
421
+
422
+void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
423
+			  u32 size, u32 flags)
424
+{
425
+	struct ar5416_desc *ads = AR5416DESC(ds);
426
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
427
+
428
+	ads->ds_ctl1 = size & AR_BufLen;
429
+	if (flags & ATH9K_RXDESC_INTREQ)
430
+		ads->ds_ctl1 |= AR_RxIntrReq;
431
+
432
+	ads->ds_rxstatus8 &= ~AR_RxDone;
433
+	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
434
+		memset(&(ads->u), 0, sizeof(ads->u));
435
+}
436
+
437
+void ar9002_hw_attach_mac_ops(struct ath_hw *ah)
438
+{
439
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
440
+
441
+	ops->rx_enable = ar9002_hw_rx_enable;
442
+	ops->set_desc_link = ar9002_hw_set_desc_link;
443
+	ops->get_desc_link = ar9002_hw_get_desc_link;
444
+	ops->get_isr = ar9002_hw_get_isr;
445
+	ops->fill_txdesc = ar9002_hw_fill_txdesc;
446
+	ops->proc_txdesc = ar9002_hw_proc_txdesc;
447
+	ops->set11n_txdesc = ar9002_hw_set11n_txdesc;
448
+	ops->set11n_ratescenario = ar9002_hw_set11n_ratescenario;
449
+	ops->set11n_aggr_first = ar9002_hw_set11n_aggr_first;
450
+	ops->set11n_aggr_middle = ar9002_hw_set11n_aggr_middle;
451
+	ops->set11n_aggr_last = ar9002_hw_set11n_aggr_last;
452
+	ops->clr11n_aggr = ar9002_hw_clr11n_aggr;
453
+	ops->set_clrdmask = ar9002_hw_set_clrdmask;
454
+}

+ 578
- 0
src/drivers/net/ath/ath9k/ath9k_ar9002_phy.c View File

@@ -0,0 +1,578 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+/**
21
+ * DOC: Programming Atheros 802.11n analog front end radios
22
+ *
23
+ * AR5416 MAC based PCI devices and AR518 MAC based PCI-Express
24
+ * devices have either an external AR2133 analog front end radio for single
25
+ * band 2.4 GHz communication or an AR5133 analog front end radio for dual
26
+ * band 2.4 GHz / 5 GHz communication.
27
+ *
28
+ * All devices after the AR5416 and AR5418 family starting with the AR9280
29
+ * have their analog front radios, MAC/BB and host PCIe/USB interface embedded
30
+ * into a single-chip and require less programming.
31
+ *
32
+ * The following single-chips exist with a respective embedded radio:
33
+ *
34
+ * AR9280 - 11n dual-band 2x2 MIMO for PCIe
35
+ * AR9281 - 11n single-band 1x2 MIMO for PCIe
36
+ * AR9285 - 11n single-band 1x1 for PCIe
37
+ * AR9287 - 11n single-band 2x2 MIMO for PCIe
38
+ *
39
+ * AR9220 - 11n dual-band 2x2 MIMO for PCI
40
+ * AR9223 - 11n single-band 2x2 MIMO for PCI
41
+ *
42
+ * AR9287 - 11n single-band 1x1 MIMO for USB
43
+ */
44
+
45
+#include <ipxe/io.h>
46
+
47
+#include "hw.h"
48
+#include "ar9002_phy.h"
49
+
50
+/**
51
+ * ar9002_hw_set_channel - set channel on single-chip device
52
+ * @ah: atheros hardware structure
53
+ * @chan:
54
+ *
55
+ * This is the function to change channel on single-chip devices, that is
56
+ * all devices after ar9280.
57
+ *
58
+ * This function takes the channel value in MHz and sets
59
+ * hardware channel value. Assumes writes have been enabled to analog bus.
60
+ *
61
+ * Actual Expression,
62
+ *
63
+ * For 2GHz channel,
64
+ * Channel Frequency = (3/4) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^17)
65
+ * (freq_ref = 40MHz)
66
+ *
67
+ * For 5GHz channel,
68
+ * Channel Frequency = (3/2) * freq_ref * (chansel[8:0] + chanfrac[16:0]/2^10)
69
+ * (freq_ref = 40MHz/(24>>amodeRefSel))
70
+ */
71
+static int ar9002_hw_set_channel(struct ath_hw *ah, struct ath9k_channel *chan)
72
+{
73
+	u16 bMode, fracMode, aModeRefSel = 0;
74
+	u32 freq, ndiv, channelSel = 0, channelFrac = 0, reg32 = 0;
75
+	struct chan_centers centers;
76
+	u32 refDivA = 24;
77
+
78
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
79
+	freq = centers.synth_center;
80
+
81
+	reg32 = REG_READ(ah, AR_PHY_SYNTH_CONTROL);
82
+	reg32 &= 0xc0000000;
83
+
84
+	if (freq < 4800) { /* 2 GHz, fractional mode */
85
+		u32 txctl;
86
+		unsigned int regWrites = 0;
87
+
88
+		bMode = 1;
89
+		fracMode = 1;
90
+		aModeRefSel = 0;
91
+		channelSel = CHANSEL_2G(freq);
92
+
93
+		if (AR_SREV_9287_11_OR_LATER(ah)) {
94
+			if (freq == 2484) {
95
+				/* Enable channel spreading for channel 14 */
96
+				REG_WRITE_ARRAY(&ah->iniCckfirJapan2484,
97
+						1, regWrites);
98
+			} else {
99
+				REG_WRITE_ARRAY(&ah->iniCckfirNormal,
100
+						1, regWrites);
101
+			}
102
+		} else {
103
+			txctl = REG_READ(ah, AR_PHY_CCK_TX_CTRL);
104
+			if (freq == 2484) {
105
+				/* Enable channel spreading for channel 14 */
106
+				REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
107
+					  txctl | AR_PHY_CCK_TX_CTRL_JAPAN);
108
+			} else {
109
+				REG_WRITE(ah, AR_PHY_CCK_TX_CTRL,
110
+					  txctl & ~AR_PHY_CCK_TX_CTRL_JAPAN);
111
+			}
112
+		}
113
+	} else {
114
+		bMode = 0;
115
+		fracMode = 0;
116
+
117
+		switch (ah->eep_ops->get_eeprom(ah, EEP_FRAC_N_5G)) {
118
+		case 0:
119
+			if ((freq % 20) == 0)
120
+				aModeRefSel = 3;
121
+			else if ((freq % 10) == 0)
122
+				aModeRefSel = 2;
123
+			if (aModeRefSel)
124
+				break;
125
+		case 1:
126
+		default:
127
+			aModeRefSel = 0;
128
+			/*
129
+			 * Enable 2G (fractional) mode for channels
130
+			 * which are 5MHz spaced.
131
+			 */
132
+			fracMode = 1;
133
+			refDivA = 1;
134
+			channelSel = CHANSEL_5G(freq);
135
+
136
+			/* RefDivA setting */
137
+			REG_RMW_FIELD(ah, AR_AN_SYNTH9,
138
+				      AR_AN_SYNTH9_REFDIVA, refDivA);
139
+
140
+		}
141
+
142
+		if (!fracMode) {
143
+			ndiv = (freq * (refDivA >> aModeRefSel)) / 60;
144
+			channelSel = ndiv & 0x1ff;
145
+			channelFrac = (ndiv & 0xfffffe00) * 2;
146
+			channelSel = (channelSel << 17) | channelFrac;
147
+		}
148
+	}
149
+
150
+	reg32 = reg32 |
151
+	    (bMode << 29) |
152
+	    (fracMode << 28) | (aModeRefSel << 26) | (channelSel);
153
+
154
+	REG_WRITE(ah, AR_PHY_SYNTH_CONTROL, reg32);
155
+
156
+	ah->curchan = chan;
157
+	ah->curchan_rad_index = -1;
158
+
159
+	return 0;
160
+}
161
+
162
+/**
163
+ * ar9002_hw_spur_mitigate - convert baseband spur frequency
164
+ * @ah: atheros hardware structure
165
+ * @chan:
166
+ *
167
+ * For single-chip solutions. Converts to baseband spur frequency given the
168
+ * input channel frequency and compute register settings below.
169
+ */
170
+static void ar9002_hw_spur_mitigate(struct ath_hw *ah,
171
+				    struct ath9k_channel *chan)
172
+{
173
+	int bb_spur = AR_NO_SPUR;
174
+	int freq;
175
+	int bin, cur_bin;
176
+	int bb_spur_off, spur_subchannel_sd;
177
+	int spur_freq_sd;
178
+	int spur_delta_phase;
179
+	int denominator;
180
+	int upper, lower, cur_vit_mask;
181
+	int tmp, newVal;
182
+	int i;
183
+	static const int pilot_mask_reg[4] = {
184
+		AR_PHY_TIMING7, AR_PHY_TIMING8,
185
+		AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
186
+	};
187
+	static const int chan_mask_reg[4] = {
188
+		AR_PHY_TIMING9, AR_PHY_TIMING10,
189
+		AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
190
+	};
191
+	static const int inc[4] = { 0, 100, 0, 0 };
192
+	struct chan_centers centers;
193
+
194
+	int8_t mask_m[123];
195
+	int8_t mask_p[123];
196
+	int8_t mask_amt;
197
+	int tmp_mask;
198
+	int cur_bb_spur;
199
+	int is2GHz = IS_CHAN_2GHZ(chan);
200
+
201
+	memset(&mask_m, 0, sizeof(int8_t) * 123);
202
+	memset(&mask_p, 0, sizeof(int8_t) * 123);
203
+
204
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
205
+	freq = centers.synth_center;
206
+
207
+	ah->config.spurmode = SPUR_ENABLE_EEPROM;
208
+	for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
209
+		cur_bb_spur = ah->eep_ops->get_spur_channel(ah, i, is2GHz);
210
+
211
+		if (AR_NO_SPUR == cur_bb_spur)
212
+			break;
213
+
214
+		if (is2GHz)
215
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
216
+		else
217
+			cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
218
+
219
+		cur_bb_spur = cur_bb_spur - freq;
220
+
221
+		if (IS_CHAN_HT40(chan)) {
222
+			if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
223
+			    (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
224
+				bb_spur = cur_bb_spur;
225
+				break;
226
+			}
227
+		} else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
228
+			   (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
229
+			bb_spur = cur_bb_spur;
230
+			break;
231
+		}
232
+	}
233
+
234
+	if (AR_NO_SPUR == bb_spur) {
235
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
236
+			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
237
+		return;
238
+	} else {
239
+		REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
240
+			    AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
241
+	}
242
+
243
+	bin = bb_spur * 320;
244
+
245
+	tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
246
+
247
+	ENABLE_REGWRITE_BUFFER(ah);
248
+
249
+	newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
250
+			AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
251
+			AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
252
+			AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
253
+	REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
254
+
255
+	newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
256
+		  AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
257
+		  AR_PHY_SPUR_REG_MASK_RATE_SELECT |
258
+		  AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
259
+		  SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
260
+	REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
261
+
262
+	if (IS_CHAN_HT40(chan)) {
263
+		if (bb_spur < 0) {
264
+			spur_subchannel_sd = 1;
265
+			bb_spur_off = bb_spur + 10;
266
+		} else {
267
+			spur_subchannel_sd = 0;
268
+			bb_spur_off = bb_spur - 10;
269
+		}
270
+	} else {
271
+		spur_subchannel_sd = 0;
272
+		bb_spur_off = bb_spur;
273
+	}
274
+
275
+	if (IS_CHAN_HT40(chan))
276
+		spur_delta_phase =
277
+			((bb_spur * 262144) /
278
+			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
279
+	else
280
+		spur_delta_phase =
281
+			((bb_spur * 524288) /
282
+			 10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
283
+
284
+	denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
285
+	spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
286
+
287
+	newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
288
+		  SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
289
+		  SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
290
+	REG_WRITE(ah, AR_PHY_TIMING11, newVal);
291
+
292
+	newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
293
+	REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
294
+
295
+	cur_bin = -6000;
296
+	upper = bin + 100;
297
+	lower = bin - 100;
298
+
299
+	for (i = 0; i < 4; i++) {
300
+		int pilot_mask = 0;
301
+		int chan_mask = 0;
302
+		int bp = 0;
303
+		for (bp = 0; bp < 30; bp++) {
304
+			if ((cur_bin > lower) && (cur_bin < upper)) {
305
+				pilot_mask = pilot_mask | 0x1 << bp;
306
+				chan_mask = chan_mask | 0x1 << bp;
307
+			}
308
+			cur_bin += 100;
309
+		}
310
+		cur_bin += inc[i];
311
+		REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
312
+		REG_WRITE(ah, chan_mask_reg[i], chan_mask);
313
+	}
314
+
315
+	cur_vit_mask = 6100;
316
+	upper = bin + 120;
317
+	lower = bin - 120;
318
+
319
+	for (i = 0; i < 123; i++) {
320
+		if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
321
+
322
+			/* workaround for gcc bug #37014 */
323
+			volatile int tmp_v = abs(cur_vit_mask - bin);
324
+
325
+			if (tmp_v < 75)
326
+				mask_amt = 1;
327
+			else
328
+				mask_amt = 0;
329
+			if (cur_vit_mask < 0)
330
+				mask_m[abs(cur_vit_mask / 100)] = mask_amt;
331
+			else
332
+				mask_p[cur_vit_mask / 100] = mask_amt;
333
+		}
334
+		cur_vit_mask -= 100;
335
+	}
336
+
337
+	tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
338
+		| (mask_m[48] << 26) | (mask_m[49] << 24)
339
+		| (mask_m[50] << 22) | (mask_m[51] << 20)
340
+		| (mask_m[52] << 18) | (mask_m[53] << 16)
341
+		| (mask_m[54] << 14) | (mask_m[55] << 12)
342
+		| (mask_m[56] << 10) | (mask_m[57] << 8)
343
+		| (mask_m[58] << 6) | (mask_m[59] << 4)
344
+		| (mask_m[60] << 2) | (mask_m[61] << 0);
345
+	REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
346
+	REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
347
+
348
+	tmp_mask = (mask_m[31] << 28)
349
+		| (mask_m[32] << 26) | (mask_m[33] << 24)
350
+		| (mask_m[34] << 22) | (mask_m[35] << 20)
351
+		| (mask_m[36] << 18) | (mask_m[37] << 16)
352
+		| (mask_m[48] << 14) | (mask_m[39] << 12)
353
+		| (mask_m[40] << 10) | (mask_m[41] << 8)
354
+		| (mask_m[42] << 6) | (mask_m[43] << 4)
355
+		| (mask_m[44] << 2) | (mask_m[45] << 0);
356
+	REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
357
+	REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
358
+
359
+	tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
360
+		| (mask_m[18] << 26) | (mask_m[18] << 24)
361
+		| (mask_m[20] << 22) | (mask_m[20] << 20)
362
+		| (mask_m[22] << 18) | (mask_m[22] << 16)
363
+		| (mask_m[24] << 14) | (mask_m[24] << 12)
364
+		| (mask_m[25] << 10) | (mask_m[26] << 8)
365
+		| (mask_m[27] << 6) | (mask_m[28] << 4)
366
+		| (mask_m[29] << 2) | (mask_m[30] << 0);
367
+	REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
368
+	REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
369
+
370
+	tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
371
+		| (mask_m[2] << 26) | (mask_m[3] << 24)
372
+		| (mask_m[4] << 22) | (mask_m[5] << 20)
373
+		| (mask_m[6] << 18) | (mask_m[7] << 16)
374
+		| (mask_m[8] << 14) | (mask_m[9] << 12)
375
+		| (mask_m[10] << 10) | (mask_m[11] << 8)
376
+		| (mask_m[12] << 6) | (mask_m[13] << 4)
377
+		| (mask_m[14] << 2) | (mask_m[15] << 0);
378
+	REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
379
+	REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
380
+
381
+	tmp_mask = (mask_p[15] << 28)
382
+		| (mask_p[14] << 26) | (mask_p[13] << 24)
383
+		| (mask_p[12] << 22) | (mask_p[11] << 20)
384
+		| (mask_p[10] << 18) | (mask_p[9] << 16)
385
+		| (mask_p[8] << 14) | (mask_p[7] << 12)
386
+		| (mask_p[6] << 10) | (mask_p[5] << 8)
387
+		| (mask_p[4] << 6) | (mask_p[3] << 4)
388
+		| (mask_p[2] << 2) | (mask_p[1] << 0);
389
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
390
+	REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
391
+
392
+	tmp_mask = (mask_p[30] << 28)
393
+		| (mask_p[29] << 26) | (mask_p[28] << 24)
394
+		| (mask_p[27] << 22) | (mask_p[26] << 20)
395
+		| (mask_p[25] << 18) | (mask_p[24] << 16)
396
+		| (mask_p[23] << 14) | (mask_p[22] << 12)
397
+		| (mask_p[21] << 10) | (mask_p[20] << 8)
398
+		| (mask_p[19] << 6) | (mask_p[18] << 4)
399
+		| (mask_p[17] << 2) | (mask_p[16] << 0);
400
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
401
+	REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
402
+
403
+	tmp_mask = (mask_p[45] << 28)
404
+		| (mask_p[44] << 26) | (mask_p[43] << 24)
405
+		| (mask_p[42] << 22) | (mask_p[41] << 20)
406
+		| (mask_p[40] << 18) | (mask_p[39] << 16)
407
+		| (mask_p[38] << 14) | (mask_p[37] << 12)
408
+		| (mask_p[36] << 10) | (mask_p[35] << 8)
409
+		| (mask_p[34] << 6) | (mask_p[33] << 4)
410
+		| (mask_p[32] << 2) | (mask_p[31] << 0);
411
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
412
+	REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
413
+
414
+	tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
415
+		| (mask_p[59] << 26) | (mask_p[58] << 24)
416
+		| (mask_p[57] << 22) | (mask_p[56] << 20)
417
+		| (mask_p[55] << 18) | (mask_p[54] << 16)
418
+		| (mask_p[53] << 14) | (mask_p[52] << 12)
419
+		| (mask_p[51] << 10) | (mask_p[50] << 8)
420
+		| (mask_p[49] << 6) | (mask_p[48] << 4)
421
+		| (mask_p[47] << 2) | (mask_p[46] << 0);
422
+	REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
423
+	REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
424
+
425
+	REGWRITE_BUFFER_FLUSH(ah);
426
+}
427
+
428
+static void ar9002_olc_init(struct ath_hw *ah)
429
+{
430
+	u32 i;
431
+
432
+	if (!OLC_FOR_AR9280_20_LATER)
433
+		return;
434
+
435
+	if (OLC_FOR_AR9287_10_LATER) {
436
+		REG_SET_BIT(ah, AR_PHY_TX_PWRCTRL9,
437
+				AR_PHY_TX_PWRCTRL9_RES_DC_REMOVAL);
438
+		ath9k_hw_analog_shift_rmw(ah, AR9287_AN_TXPC0,
439
+				AR9287_AN_TXPC0_TXPCMODE,
440
+				AR9287_AN_TXPC0_TXPCMODE_S,
441
+				AR9287_AN_TXPC0_TXPCMODE_TEMPSENSE);
442
+		udelay(100);
443
+	} else {
444
+		for (i = 0; i < AR9280_TX_GAIN_TABLE_SIZE; i++)
445
+			ah->originalGain[i] =
446
+				MS(REG_READ(ah, AR_PHY_TX_GAIN_TBL1 + i * 4),
447
+						AR_PHY_TX_GAIN);
448
+		ah->PDADCdelta = 0;
449
+	}
450
+}
451
+
452
+static u32 ar9002_hw_compute_pll_control(struct ath_hw *ah,
453
+					 struct ath9k_channel *chan)
454
+{
455
+	u32 pll;
456
+
457
+	pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
458
+
459
+	if (chan && IS_CHAN_HALF_RATE(chan))
460
+		pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
461
+	else if (chan && IS_CHAN_QUARTER_RATE(chan))
462
+		pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
463
+
464
+	if (chan && IS_CHAN_5GHZ(chan)) {
465
+		if (IS_CHAN_A_FAST_CLOCK(ah, chan))
466
+			pll = 0x142c;
467
+		else if (AR_SREV_9280_20(ah))
468
+			pll = 0x2850;
469
+		else
470
+			pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
471
+	} else {
472
+		pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
473
+	}
474
+
475
+	return pll;
476
+}
477
+
478
+static void ar9002_hw_do_getnf(struct ath_hw *ah,
479
+			      int16_t nfarray[NUM_NF_READINGS])
480
+{
481
+	int16_t nf;
482
+
483
+	nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
484
+	nfarray[0] = sign_extend32(nf, 8);
485
+
486
+	nf = MS(REG_READ(ah, AR_PHY_EXT_CCA), AR9280_PHY_EXT_MINCCA_PWR);
487
+	if (IS_CHAN_HT40(ah->curchan))
488
+		nfarray[3] = sign_extend32(nf, 8);
489
+
490
+	if (AR_SREV_9285(ah) || AR_SREV_9271(ah))
491
+		return;
492
+
493
+	nf = MS(REG_READ(ah, AR_PHY_CH1_CCA), AR9280_PHY_CH1_MINCCA_PWR);
494
+	nfarray[1] = sign_extend32(nf, 8);
495
+
496
+	nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA), AR9280_PHY_CH1_EXT_MINCCA_PWR);
497
+	if (IS_CHAN_HT40(ah->curchan))
498
+		nfarray[4] = sign_extend32(nf, 8);
499
+}
500
+
501
+static void ar9002_hw_set_nf_limits(struct ath_hw *ah)
502
+{
503
+	if (AR_SREV_9285(ah)) {
504
+		ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9285_2GHZ;
505
+		ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9285_2GHZ;
506
+		ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9285_2GHZ;
507
+	} else if (AR_SREV_9287(ah)) {
508
+		ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ;
509
+		ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ;
510
+		ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9287_2GHZ;
511
+	} else if (AR_SREV_9271(ah)) {
512
+		ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ;
513
+		ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ;
514
+		ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9271_2GHZ;
515
+	} else {
516
+		ah->nf_2g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_2GHZ;
517
+		ah->nf_2g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_2GHZ;
518
+		ah->nf_2g.nominal = AR_PHY_CCA_NOM_VAL_9280_2GHZ;
519
+		ah->nf_5g.max = AR_PHY_CCA_MAX_GOOD_VAL_9280_5GHZ;
520
+		ah->nf_5g.min = AR_PHY_CCA_MIN_GOOD_VAL_9280_5GHZ;
521
+		ah->nf_5g.nominal = AR_PHY_CCA_NOM_VAL_9280_5GHZ;
522
+	}
523
+}
524
+
525
+static void ar9002_hw_antdiv_comb_conf_get(struct ath_hw *ah,
526
+				   struct ath_hw_antcomb_conf *antconf)
527
+{
528
+	u32 regval;
529
+
530
+	regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
531
+	antconf->main_lna_conf = (regval & AR_PHY_9285_ANT_DIV_MAIN_LNACONF) >>
532
+				  AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S;
533
+	antconf->alt_lna_conf = (regval & AR_PHY_9285_ANT_DIV_ALT_LNACONF) >>
534
+				 AR_PHY_9285_ANT_DIV_ALT_LNACONF_S;
535
+	antconf->fast_div_bias = (regval & AR_PHY_9285_FAST_DIV_BIAS) >>
536
+				  AR_PHY_9285_FAST_DIV_BIAS_S;
537
+	antconf->lna1_lna2_delta = -3;
538
+	antconf->div_group = 0;
539
+}
540
+
541
+static void ar9002_hw_antdiv_comb_conf_set(struct ath_hw *ah,
542
+				   struct ath_hw_antcomb_conf *antconf)
543
+{
544
+	u32 regval;
545
+
546
+	regval = REG_READ(ah, AR_PHY_MULTICHAIN_GAIN_CTL);
547
+	regval &= ~(AR_PHY_9285_ANT_DIV_MAIN_LNACONF |
548
+		    AR_PHY_9285_ANT_DIV_ALT_LNACONF |
549
+		    AR_PHY_9285_FAST_DIV_BIAS);
550
+	regval |= ((antconf->main_lna_conf << AR_PHY_9285_ANT_DIV_MAIN_LNACONF_S)
551
+		   & AR_PHY_9285_ANT_DIV_MAIN_LNACONF);
552
+	regval |= ((antconf->alt_lna_conf << AR_PHY_9285_ANT_DIV_ALT_LNACONF_S)
553
+		   & AR_PHY_9285_ANT_DIV_ALT_LNACONF);
554
+	regval |= ((antconf->fast_div_bias << AR_PHY_9285_FAST_DIV_BIAS_S)
555
+		   & AR_PHY_9285_FAST_DIV_BIAS);
556
+
557
+	REG_WRITE(ah, AR_PHY_MULTICHAIN_GAIN_CTL, regval);
558
+}
559
+
560
+void ar9002_hw_attach_phy_ops(struct ath_hw *ah)
561
+{
562
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
563
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
564
+
565
+	priv_ops->set_rf_regs = NULL;
566
+	priv_ops->rf_alloc_ext_banks = NULL;
567
+	priv_ops->rf_free_ext_banks = NULL;
568
+	priv_ops->rf_set_freq = ar9002_hw_set_channel;
569
+	priv_ops->spur_mitigate_freq = ar9002_hw_spur_mitigate;
570
+	priv_ops->olc_init = ar9002_olc_init;
571
+	priv_ops->compute_pll_control = ar9002_hw_compute_pll_control;
572
+	priv_ops->do_getnf = ar9002_hw_do_getnf;
573
+
574
+	ops->antdiv_comb_conf_get = ar9002_hw_antdiv_comb_conf_get;
575
+	ops->antdiv_comb_conf_set = ar9002_hw_antdiv_comb_conf_set;
576
+
577
+	ar9002_hw_set_nf_limits(ah);
578
+}

+ 932
- 0
src/drivers/net/ath/ath9k/ath9k_ar9003_calib.c View File

@@ -0,0 +1,932 @@
1
+/*
2
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/io.h>
21
+
22
+#include "hw.h"
23
+#include "hw-ops.h"
24
+#include "ar9003_phy.h"
25
+
26
+#define MAX_MEASUREMENT	8
27
+#define MAX_MAG_DELTA	11
28
+#define MAX_PHS_DELTA	10
29
+
30
+struct coeff {
31
+	int mag_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
32
+	int phs_coeff[AR9300_MAX_CHAINS][MAX_MEASUREMENT];
33
+	int iqc_coeff[2];
34
+};
35
+
36
+enum ar9003_cal_types {
37
+	IQ_MISMATCH_CAL = BIT(0),
38
+	TEMP_COMP_CAL = BIT(1),
39
+};
40
+
41
+static void ar9003_hw_setup_calibration(struct ath_hw *ah,
42
+					struct ath9k_cal_list *currCal)
43
+{
44
+	/* Select calibration to run */
45
+	switch (currCal->calData->calType) {
46
+	case IQ_MISMATCH_CAL:
47
+		/*
48
+		 * Start calibration with
49
+		 * 2^(INIT_IQCAL_LOG_COUNT_MAX+1) samples
50
+		 */
51
+		REG_RMW_FIELD(ah, AR_PHY_TIMING4,
52
+			      AR_PHY_TIMING4_IQCAL_LOG_COUNT_MAX,
53
+		currCal->calData->calCountMax);
54
+		REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
55
+
56
+		DBG2("ath9k: "
57
+			"starting IQ Mismatch Calibration\n");
58
+
59
+		/* Kick-off cal */
60
+		REG_SET_BIT(ah, AR_PHY_TIMING4, AR_PHY_TIMING4_DO_CAL);
61
+		break;
62
+	case TEMP_COMP_CAL:
63
+		REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
64
+			      AR_PHY_65NM_CH0_THERM_LOCAL, 1);
65
+		REG_RMW_FIELD(ah, AR_PHY_65NM_CH0_THERM,
66
+			      AR_PHY_65NM_CH0_THERM_START, 1);
67
+
68
+		DBG2("ath9k: "
69
+			"starting Temperature Compensation Calibration\n");
70
+		break;
71
+	}
72
+}
73
+
74
+/*
75
+ * Generic calibration routine.
76
+ * Recalibrate the lower PHY chips to account for temperature/environment
77
+ * changes.
78
+ */
79
+static int ar9003_hw_per_calibration(struct ath_hw *ah,
80
+				      struct ath9k_channel *ichan __unused,
81
+				      u8 rxchainmask,
82
+				      struct ath9k_cal_list *currCal)
83
+{
84
+	struct ath9k_hw_cal_data *caldata = ah->caldata;
85
+	/* Cal is assumed not done until explicitly set below */
86
+	int iscaldone = 0;
87
+
88
+	/* Calibration in progress. */
89
+	if (currCal->calState == CAL_RUNNING) {
90
+		/* Check to see if it has finished. */
91
+		if (!(REG_READ(ah, AR_PHY_TIMING4) & AR_PHY_TIMING4_DO_CAL)) {
92
+			/*
93
+			* Accumulate cal measures for active chains
94
+			*/
95
+			currCal->calData->calCollect(ah);
96
+			ah->cal_samples++;
97
+
98
+			if (ah->cal_samples >=
99
+			    currCal->calData->calNumSamples) {
100
+				unsigned int i, numChains = 0;
101
+				for (i = 0; i < AR9300_MAX_CHAINS; i++) {
102
+					if (rxchainmask & (1 << i))
103
+						numChains++;
104
+				}
105
+
106
+				/*
107
+				* Process accumulated data
108
+				*/
109
+				currCal->calData->calPostProc(ah, numChains);
110
+
111
+				/* Calibration has finished. */
112
+				caldata->CalValid |= currCal->calData->calType;
113
+				currCal->calState = CAL_DONE;
114
+				iscaldone = 1;
115
+			} else {
116
+			/*
117
+			 * Set-up collection of another sub-sample until we
118
+			 * get desired number
119
+			 */
120
+			ar9003_hw_setup_calibration(ah, currCal);
121
+			}
122
+		}
123
+	} else if (!(caldata->CalValid & currCal->calData->calType)) {
124
+		/* If current cal is marked invalid in channel, kick it off */
125
+		ath9k_hw_reset_calibration(ah, currCal);
126
+	}
127
+
128
+	return iscaldone;
129
+}
130
+
131
+static int ar9003_hw_calibrate(struct ath_hw *ah,
132
+				struct ath9k_channel *chan,
133
+				u8 rxchainmask,
134
+				int longcal)
135
+{
136
+	int iscaldone = 1;
137
+	struct ath9k_cal_list *currCal = ah->cal_list_curr;
138
+
139
+	/*
140
+	 * For given calibration:
141
+	 * 1. Call generic cal routine
142
+	 * 2. When this cal is done (isCalDone) if we have more cals waiting
143
+	 *    (eg after reset), mask this to upper layers by not propagating
144
+	 *    isCalDone if it is set to TRUE.
145
+	 *    Instead, change isCalDone to FALSE and setup the waiting cal(s)
146
+	 *    to be run.
147
+	 */
148
+	if (currCal &&
149
+	    (currCal->calState == CAL_RUNNING ||
150
+	     currCal->calState == CAL_WAITING)) {
151
+		iscaldone = ar9003_hw_per_calibration(ah, chan,
152
+						      rxchainmask, currCal);
153
+		if (iscaldone) {
154
+			ah->cal_list_curr = currCal = currCal->calNext;
155
+
156
+			if (currCal->calState == CAL_WAITING) {
157
+				iscaldone = 0;
158
+				ath9k_hw_reset_calibration(ah, currCal);
159
+			}
160
+		}
161
+	}
162
+
163
+	/* Do NF cal only at longer intervals */
164
+	if (longcal) {
165
+		/*
166
+		 * Get the value from the previous NF cal and update
167
+		 * history buffer.
168
+		 */
169
+		ath9k_hw_getnf(ah, chan);
170
+
171
+		/*
172
+		 * Load the NF from history buffer of the current channel.
173
+		 * NF is slow time-variant, so it is OK to use a historical
174
+		 * value.
175
+		 */
176
+		ath9k_hw_loadnf(ah, ah->curchan);
177
+
178
+		/* start NF calibration, without updating BB NF register */
179
+		ath9k_hw_start_nfcal(ah, 0);
180
+	}
181
+
182
+	return iscaldone;
183
+}
184
+
185
+static void ar9003_hw_iqcal_collect(struct ath_hw *ah)
186
+{
187
+	int i;
188
+
189
+	/* Accumulate IQ cal measures for active chains */
190
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
191
+		if (ah->txchainmask & BIT(i)) {
192
+			ah->totalPowerMeasI[i] +=
193
+				REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
194
+			ah->totalPowerMeasQ[i] +=
195
+				REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
196
+			ah->totalIqCorrMeas[i] +=
197
+				(int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
198
+			DBG2("ath9k: "
199
+				"%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
200
+				ah->cal_samples, i, ah->totalPowerMeasI[i],
201
+				ah->totalPowerMeasQ[i],
202
+				ah->totalIqCorrMeas[i]);
203
+		}
204
+	}
205
+}
206
+
207
+static void ar9003_hw_iqcalibrate(struct ath_hw *ah, u8 numChains)
208
+{
209
+	u32 powerMeasQ, powerMeasI, iqCorrMeas;
210
+	u32 qCoffDenom, iCoffDenom;
211
+	int32_t qCoff, iCoff;
212
+	int iqCorrNeg, i;
213
+	static const uint32_t offset_array[3] = {
214
+		AR_PHY_RX_IQCAL_CORR_B0,
215
+		AR_PHY_RX_IQCAL_CORR_B1,
216
+		AR_PHY_RX_IQCAL_CORR_B2,
217
+	};
218
+
219
+	for (i = 0; i < numChains; i++) {
220
+		powerMeasI = ah->totalPowerMeasI[i];
221
+		powerMeasQ = ah->totalPowerMeasQ[i];
222
+		iqCorrMeas = ah->totalIqCorrMeas[i];
223
+
224
+		DBG2("ath9k: "
225
+			"Starting IQ Cal and Correction for Chain %d\n",
226
+			i);
227
+
228
+		DBG2("ath9k: "
229
+			"Orignal: Chn %diq_corr_meas = 0x%08x\n",
230
+			i, ah->totalIqCorrMeas[i]);
231
+
232
+		iqCorrNeg = 0;
233
+
234
+		if (iqCorrMeas > 0x80000000) {
235
+			iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
236
+			iqCorrNeg = 1;
237
+		}
238
+
239
+		DBG2("ath9k: "
240
+			"Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
241
+		DBG2("ath9k: "
242
+			"Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
243
+		DBG2("ath9k: iqCorrNeg is 0x%08x\n",
244
+			iqCorrNeg);
245
+
246
+		iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 256;
247
+		qCoffDenom = powerMeasQ / 64;
248
+
249
+		if ((iCoffDenom != 0) && (qCoffDenom != 0)) {
250
+			iCoff = iqCorrMeas / iCoffDenom;
251
+			qCoff = powerMeasI / qCoffDenom - 64;
252
+			DBG2("ath9k: "
253
+				"Chn %d iCoff = 0x%08x\n", i, iCoff);
254
+			DBG2("ath9k: "
255
+				"Chn %d qCoff = 0x%08x\n", i, qCoff);
256
+
257
+			/* Force bounds on iCoff */
258
+			if (iCoff >= 63)
259
+				iCoff = 63;
260
+			else if (iCoff <= -63)
261
+				iCoff = -63;
262
+
263
+			/* Negate iCoff if iqCorrNeg == 0 */
264
+			if (iqCorrNeg == 0x0)
265
+				iCoff = -iCoff;
266
+
267
+			/* Force bounds on qCoff */
268
+			if (qCoff >= 63)
269
+				qCoff = 63;
270
+			else if (qCoff <= -63)
271
+				qCoff = -63;
272
+
273
+			iCoff = iCoff & 0x7f;
274
+			qCoff = qCoff & 0x7f;
275
+
276
+			DBG2("ath9k: "
277
+				"Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
278
+				i, iCoff, qCoff);
279
+			DBG2("ath9k: "
280
+				"Register offset (0x%04x) before update = 0x%x\n",
281
+				offset_array[i],
282
+				REG_READ(ah, offset_array[i]));
283
+
284
+			REG_RMW_FIELD(ah, offset_array[i],
285
+				      AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
286
+				      iCoff);
287
+			REG_RMW_FIELD(ah, offset_array[i],
288
+				      AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
289
+				      qCoff);
290
+			DBG2("ath9k: "
291
+				"Register offset (0x%04x) QI COFF (bitfields 0x%08x) after update = 0x%x\n",
292
+				offset_array[i],
293
+				AR_PHY_RX_IQCAL_CORR_IQCORR_Q_I_COFF,
294
+				REG_READ(ah, offset_array[i]));
295
+			DBG2("ath9k: "
296
+				"Register offset (0x%04x) QQ COFF (bitfields 0x%08x) after update = 0x%x\n",
297
+				offset_array[i],
298
+				AR_PHY_RX_IQCAL_CORR_IQCORR_Q_Q_COFF,
299
+				REG_READ(ah, offset_array[i]));
300
+
301
+			DBG2("ath9k: "
302
+				"IQ Cal and Correction done for Chain %d\n", i);
303
+		}
304
+	}
305
+
306
+	REG_SET_BIT(ah, AR_PHY_RX_IQCAL_CORR_B0,
307
+		    AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE);
308
+	DBG2("ath9k: "
309
+		"IQ Cal and Correction (offset 0x%04x) enabled (bit position 0x%08x). New Value 0x%08x\n",
310
+		(unsigned) (AR_PHY_RX_IQCAL_CORR_B0),
311
+		AR_PHY_RX_IQCAL_CORR_IQCORR_ENABLE,
312
+		REG_READ(ah, AR_PHY_RX_IQCAL_CORR_B0));
313
+}
314
+
315
+static const struct ath9k_percal_data iq_cal_single_sample = {
316
+	IQ_MISMATCH_CAL,
317
+	MIN_CAL_SAMPLES,
318
+	PER_MAX_LOG_COUNT,
319
+	ar9003_hw_iqcal_collect,
320
+	ar9003_hw_iqcalibrate
321
+};
322
+
323
+static void ar9003_hw_init_cal_settings(struct ath_hw *ah)
324
+{
325
+	ah->iq_caldata.calData = &iq_cal_single_sample;
326
+}
327
+
328
+/*
329
+ * solve 4x4 linear equation used in loopback iq cal.
330
+ */
331
+static int ar9003_hw_solve_iq_cal(struct ath_hw *ah __unused,
332
+				   s32 sin_2phi_1,
333
+				   s32 cos_2phi_1,
334
+				   s32 sin_2phi_2,
335
+				   s32 cos_2phi_2,
336
+				   s32 mag_a0_d0,
337
+				   s32 phs_a0_d0,
338
+				   s32 mag_a1_d0,
339
+				   s32 phs_a1_d0,
340
+				   s32 solved_eq[])
341
+{
342
+	s32 f1 = cos_2phi_1 - cos_2phi_2,
343
+	    f3 = sin_2phi_1 - sin_2phi_2,
344
+	    f2;
345
+	s32 mag_tx, phs_tx, mag_rx, phs_rx;
346
+	const s32 result_shift = 1 << 15;
347
+
348
+	f2 = (f1 * f1 + f3 * f3) / result_shift;
349
+
350
+	if (!f2) {
351
+		DBG("ath9k: Divide by 0\n");
352
+		return 0;
353
+	}
354
+
355
+	/* mag mismatch, tx */
356
+	mag_tx = f1 * (mag_a0_d0  - mag_a1_d0) + f3 * (phs_a0_d0 - phs_a1_d0);
357
+	/* phs mismatch, tx */
358
+	phs_tx = f3 * (-mag_a0_d0 + mag_a1_d0) + f1 * (phs_a0_d0 - phs_a1_d0);
359
+
360
+	mag_tx = (mag_tx / f2);
361
+	phs_tx = (phs_tx / f2);
362
+
363
+	/* mag mismatch, rx */
364
+	mag_rx = mag_a0_d0 - (cos_2phi_1 * mag_tx + sin_2phi_1 * phs_tx) /
365
+		 result_shift;
366
+	/* phs mismatch, rx */
367
+	phs_rx = phs_a0_d0 + (sin_2phi_1 * mag_tx - cos_2phi_1 * phs_tx) /
368
+		 result_shift;
369
+
370
+	solved_eq[0] = mag_tx;
371
+	solved_eq[1] = phs_tx;
372
+	solved_eq[2] = mag_rx;
373
+	solved_eq[3] = phs_rx;
374
+
375
+	return 1;
376
+}
377
+
378
+static s32 ar9003_hw_find_mag_approx(struct ath_hw *ah __unused, s32 in_re, s32 in_im)
379
+{
380
+	s32 abs_i = abs(in_re),
381
+	    abs_q = abs(in_im),
382
+	    max_abs, min_abs;
383
+
384
+	if (abs_i > abs_q) {
385
+		max_abs = abs_i;
386
+		min_abs = abs_q;
387
+	} else {
388
+		max_abs = abs_q;
389
+		min_abs = abs_i;
390
+	}
391
+
392
+	return max_abs - (max_abs / 32) + (min_abs / 8) + (min_abs / 4);
393
+}
394
+
395
+#define DELPT 32
396
+
397
+static int ar9003_hw_calc_iq_corr(struct ath_hw *ah,
398
+				   s32 chain_idx,
399
+				   const s32 iq_res[],
400
+				   s32 iqc_coeff[])
401
+{
402
+	s32 i2_m_q2_a0_d0, i2_p_q2_a0_d0, iq_corr_a0_d0,
403
+	    i2_m_q2_a0_d1, i2_p_q2_a0_d1, iq_corr_a0_d1,
404
+	    i2_m_q2_a1_d0, i2_p_q2_a1_d0, iq_corr_a1_d0,
405
+	    i2_m_q2_a1_d1, i2_p_q2_a1_d1, iq_corr_a1_d1;
406
+	s32 mag_a0_d0, mag_a1_d0, mag_a0_d1, mag_a1_d1,
407
+	    phs_a0_d0, phs_a1_d0, phs_a0_d1, phs_a1_d1,
408
+	    sin_2phi_1, cos_2phi_1,
409
+	    sin_2phi_2, cos_2phi_2;
410
+	s32 mag_tx, phs_tx, mag_rx, phs_rx;
411
+	s32 solved_eq[4], mag_corr_tx, phs_corr_tx, mag_corr_rx, phs_corr_rx,
412
+	    q_q_coff, q_i_coff;
413
+	const s32 res_scale = 1 << 15;
414
+	const s32 delpt_shift = 1 << 8;
415
+	s32 mag1, mag2;
416
+
417
+	i2_m_q2_a0_d0 = iq_res[0] & 0xfff;
418
+	i2_p_q2_a0_d0 = (iq_res[0] >> 12) & 0xfff;
419
+	iq_corr_a0_d0 = ((iq_res[0] >> 24) & 0xff) + ((iq_res[1] & 0xf) << 8);
420
+
421
+	if (i2_m_q2_a0_d0 > 0x800)
422
+		i2_m_q2_a0_d0 = -((0xfff - i2_m_q2_a0_d0) + 1);
423
+
424
+	if (i2_p_q2_a0_d0 > 0x800)
425
+		i2_p_q2_a0_d0 = -((0xfff - i2_p_q2_a0_d0) + 1);
426
+
427
+	if (iq_corr_a0_d0 > 0x800)
428
+		iq_corr_a0_d0 = -((0xfff - iq_corr_a0_d0) + 1);
429
+
430
+	i2_m_q2_a0_d1 = (iq_res[1] >> 4) & 0xfff;
431
+	i2_p_q2_a0_d1 = (iq_res[2] & 0xfff);
432
+	iq_corr_a0_d1 = (iq_res[2] >> 12) & 0xfff;
433
+
434
+	if (i2_m_q2_a0_d1 > 0x800)
435
+		i2_m_q2_a0_d1 = -((0xfff - i2_m_q2_a0_d1) + 1);
436
+
437
+	if (i2_p_q2_a0_d1 > 0x800)
438
+		i2_p_q2_a0_d1 = -((0xfff - i2_p_q2_a0_d1) + 1);
439
+
440
+	if (iq_corr_a0_d1 > 0x800)
441
+		iq_corr_a0_d1 = -((0xfff - iq_corr_a0_d1) + 1);
442
+
443
+	i2_m_q2_a1_d0 = ((iq_res[2] >> 24) & 0xff) + ((iq_res[3] & 0xf) << 8);
444
+	i2_p_q2_a1_d0 = (iq_res[3] >> 4) & 0xfff;
445
+	iq_corr_a1_d0 = iq_res[4] & 0xfff;
446
+
447
+	if (i2_m_q2_a1_d0 > 0x800)
448
+		i2_m_q2_a1_d0 = -((0xfff - i2_m_q2_a1_d0) + 1);
449
+
450
+	if (i2_p_q2_a1_d0 > 0x800)
451
+		i2_p_q2_a1_d0 = -((0xfff - i2_p_q2_a1_d0) + 1);
452
+
453
+	if (iq_corr_a1_d0 > 0x800)
454
+		iq_corr_a1_d0 = -((0xfff - iq_corr_a1_d0) + 1);
455
+
456
+	i2_m_q2_a1_d1 = (iq_res[4] >> 12) & 0xfff;
457
+	i2_p_q2_a1_d1 = ((iq_res[4] >> 24) & 0xff) + ((iq_res[5] & 0xf) << 8);
458
+	iq_corr_a1_d1 = (iq_res[5] >> 4) & 0xfff;
459
+
460
+	if (i2_m_q2_a1_d1 > 0x800)
461
+		i2_m_q2_a1_d1 = -((0xfff - i2_m_q2_a1_d1) + 1);
462
+
463
+	if (i2_p_q2_a1_d1 > 0x800)
464
+		i2_p_q2_a1_d1 = -((0xfff - i2_p_q2_a1_d1) + 1);
465
+
466
+	if (iq_corr_a1_d1 > 0x800)
467
+		iq_corr_a1_d1 = -((0xfff - iq_corr_a1_d1) + 1);
468
+
469
+	if ((i2_p_q2_a0_d0 == 0) || (i2_p_q2_a0_d1 == 0) ||
470
+	    (i2_p_q2_a1_d0 == 0) || (i2_p_q2_a1_d1 == 0)) {
471
+		DBG("ath9k: "
472
+			"Divide by 0:\n"
473
+			"a0_d0=%d\n"
474
+			"a0_d1=%d\n"
475
+			"a2_d0=%d\n"
476
+			"a1_d1=%d\n",
477
+			i2_p_q2_a0_d0, i2_p_q2_a0_d1,
478
+			i2_p_q2_a1_d0, i2_p_q2_a1_d1);
479
+		return 0;
480
+	}
481
+
482
+	mag_a0_d0 = (i2_m_q2_a0_d0 * res_scale) / i2_p_q2_a0_d0;
483
+	phs_a0_d0 = (iq_corr_a0_d0 * res_scale) / i2_p_q2_a0_d0;
484
+
485
+	mag_a0_d1 = (i2_m_q2_a0_d1 * res_scale) / i2_p_q2_a0_d1;
486
+	phs_a0_d1 = (iq_corr_a0_d1 * res_scale) / i2_p_q2_a0_d1;
487
+
488
+	mag_a1_d0 = (i2_m_q2_a1_d0 * res_scale) / i2_p_q2_a1_d0;
489
+	phs_a1_d0 = (iq_corr_a1_d0 * res_scale) / i2_p_q2_a1_d0;
490
+
491
+	mag_a1_d1 = (i2_m_q2_a1_d1 * res_scale) / i2_p_q2_a1_d1;
492
+	phs_a1_d1 = (iq_corr_a1_d1 * res_scale) / i2_p_q2_a1_d1;
493
+
494
+	/* w/o analog phase shift */
495
+	sin_2phi_1 = (((mag_a0_d0 - mag_a0_d1) * delpt_shift) / DELPT);
496
+	/* w/o analog phase shift */
497
+	cos_2phi_1 = (((phs_a0_d1 - phs_a0_d0) * delpt_shift) / DELPT);
498
+	/* w/  analog phase shift */
499
+	sin_2phi_2 = (((mag_a1_d0 - mag_a1_d1) * delpt_shift) / DELPT);
500
+	/* w/  analog phase shift */
501
+	cos_2phi_2 = (((phs_a1_d1 - phs_a1_d0) * delpt_shift) / DELPT);
502
+
503
+	/*
504
+	 * force sin^2 + cos^2 = 1;
505
+	 * find magnitude by approximation
506
+	 */
507
+	mag1 = ar9003_hw_find_mag_approx(ah, cos_2phi_1, sin_2phi_1);
508
+	mag2 = ar9003_hw_find_mag_approx(ah, cos_2phi_2, sin_2phi_2);
509
+
510
+	if ((mag1 == 0) || (mag2 == 0)) {
511
+		DBG("ath9k: "
512
+			"Divide by 0: mag1=%d, mag2=%d\n",
513
+			mag1, mag2);
514
+		return 0;
515
+	}
516
+
517
+	/* normalization sin and cos by mag */
518
+	sin_2phi_1 = (sin_2phi_1 * res_scale / mag1);
519
+	cos_2phi_1 = (cos_2phi_1 * res_scale / mag1);
520
+	sin_2phi_2 = (sin_2phi_2 * res_scale / mag2);
521
+	cos_2phi_2 = (cos_2phi_2 * res_scale / mag2);
522
+
523
+	/* calculate IQ mismatch */
524
+	if (!ar9003_hw_solve_iq_cal(ah,
525
+			     sin_2phi_1, cos_2phi_1,
526
+			     sin_2phi_2, cos_2phi_2,
527
+			     mag_a0_d0, phs_a0_d0,
528
+			     mag_a1_d0,
529
+			     phs_a1_d0, solved_eq)) {
530
+		DBG("ath9k: "
531
+			"Call to ar9003_hw_solve_iq_cal() failed.\n");
532
+		return 0;
533
+	}
534
+
535
+	mag_tx = solved_eq[0];
536
+	phs_tx = solved_eq[1];
537
+	mag_rx = solved_eq[2];
538
+	phs_rx = solved_eq[3];
539
+
540
+	DBG2("ath9k: "
541
+		"chain %d: mag mismatch=%d phase mismatch=%d\n",
542
+		chain_idx, mag_tx/res_scale, phs_tx/res_scale);
543
+
544
+	if (res_scale == mag_tx) {
545
+		DBG("ath9k: "
546
+			"Divide by 0: mag_tx=%d, res_scale=%d\n",
547
+			mag_tx, res_scale);
548
+		return 0;
549
+	}
550
+
551
+	/* calculate and quantize Tx IQ correction factor */
552
+	mag_corr_tx = (mag_tx * res_scale) / (res_scale - mag_tx);
553
+	phs_corr_tx = -phs_tx;
554
+
555
+	q_q_coff = (mag_corr_tx * 128 / res_scale);
556
+	q_i_coff = (phs_corr_tx * 256 / res_scale);
557
+
558
+	DBG2("ath9k: "
559
+		"tx chain %d: mag corr=%d  phase corr=%d\n",
560
+		chain_idx, q_q_coff, q_i_coff);
561
+
562
+	if (q_i_coff < -63)
563
+		q_i_coff = -63;
564
+	if (q_i_coff > 63)
565
+		q_i_coff = 63;
566
+	if (q_q_coff < -63)
567
+		q_q_coff = -63;
568
+	if (q_q_coff > 63)
569
+		q_q_coff = 63;
570
+
571
+	iqc_coeff[0] = (q_q_coff * 128) + q_i_coff;
572
+
573
+	DBG2("ath9k: "
574
+		"tx chain %d: iq corr coeff=%x\n",
575
+		chain_idx, iqc_coeff[0]);
576
+
577
+	if (-mag_rx == res_scale) {
578
+		DBG("ath9k: "
579
+			"Divide by 0: mag_rx=%d, res_scale=%d\n",
580
+			mag_rx, res_scale);
581
+		return 0;
582
+	}
583
+
584
+	/* calculate and quantize Rx IQ correction factors */
585
+	mag_corr_rx = (-mag_rx * res_scale) / (res_scale + mag_rx);
586
+	phs_corr_rx = -phs_rx;
587
+
588
+	q_q_coff = (mag_corr_rx * 128 / res_scale);
589
+	q_i_coff = (phs_corr_rx * 256 / res_scale);
590
+
591
+	DBG("ath9k: "
592
+		"rx chain %d: mag corr=%d  phase corr=%d\n",
593
+		chain_idx, q_q_coff, q_i_coff);
594
+
595
+	if (q_i_coff < -63)
596
+		q_i_coff = -63;
597
+	if (q_i_coff > 63)
598
+		q_i_coff = 63;
599
+	if (q_q_coff < -63)
600
+		q_q_coff = -63;
601
+	if (q_q_coff > 63)
602
+		q_q_coff = 63;
603
+
604
+	iqc_coeff[1] = (q_q_coff * 128) + q_i_coff;
605
+
606
+	DBG2("ath9k: "
607
+		"rx chain %d: iq corr coeff=%x\n",
608
+		chain_idx, iqc_coeff[1]);
609
+
610
+	return 1;
611
+}
612
+
613
+static void ar9003_hw_detect_outlier(int *mp_coeff, int nmeasurement,
614
+				     int max_delta)
615
+{
616
+	int mp_max = -64, max_idx = 0;
617
+	int mp_min = 63, min_idx = 0;
618
+	int mp_avg = 0, i, outlier_idx = 0;
619
+
620
+	/* find min/max mismatch across all calibrated gains */
621
+	for (i = 0; i < nmeasurement; i++) {
622
+		mp_avg += mp_coeff[i];
623
+		if (mp_coeff[i] > mp_max) {
624
+			mp_max = mp_coeff[i];
625
+			max_idx = i;
626
+		} else if (mp_coeff[i] < mp_min) {
627
+			mp_min = mp_coeff[i];
628
+			min_idx = i;
629
+		}
630
+	}
631
+
632
+	/* find average (exclude max abs value) */
633
+	for (i = 0; i < nmeasurement; i++) {
634
+		if ((abs(mp_coeff[i]) < abs(mp_max)) ||
635
+		    (abs(mp_coeff[i]) < abs(mp_min)))
636
+			mp_avg += mp_coeff[i];
637
+	}
638
+	mp_avg /= (nmeasurement - 1);
639
+
640
+	/* detect outlier */
641
+	if (abs(mp_max - mp_min) > max_delta) {
642
+		if (abs(mp_max - mp_avg) > abs(mp_min - mp_avg))
643
+			outlier_idx = max_idx;
644
+		else
645
+			outlier_idx = min_idx;
646
+	}
647
+	mp_coeff[outlier_idx] = mp_avg;
648
+}
649
+
650
+static void ar9003_hw_tx_iqcal_load_avg_2_passes(struct ath_hw *ah,
651
+						 u8 num_chains,
652
+						 struct coeff *coeff)
653
+{
654
+	int i, im, nmeasurement;
655
+	u32 tx_corr_coeff[MAX_MEASUREMENT][AR9300_MAX_CHAINS];
656
+
657
+	memset(tx_corr_coeff, 0, sizeof(tx_corr_coeff));
658
+	for (i = 0; i < MAX_MEASUREMENT / 2; i++) {
659
+		tx_corr_coeff[i * 2][0] = tx_corr_coeff[(i * 2) + 1][0] =
660
+					AR_PHY_TX_IQCAL_CORR_COEFF_B0(i);
661
+		if (!AR_SREV_9485(ah)) {
662
+			tx_corr_coeff[i * 2][1] =
663
+			tx_corr_coeff[(i * 2) + 1][1] =
664
+					AR_PHY_TX_IQCAL_CORR_COEFF_B1(i);
665
+
666
+			tx_corr_coeff[i * 2][2] =
667
+			tx_corr_coeff[(i * 2) + 1][2] =
668
+					AR_PHY_TX_IQCAL_CORR_COEFF_B2(i);
669
+		}
670
+	}
671
+
672
+	/* Load the average of 2 passes */
673
+	for (i = 0; i < num_chains; i++) {
674
+		nmeasurement = REG_READ_FIELD(ah,
675
+				AR_PHY_TX_IQCAL_STATUS_B0,
676
+				AR_PHY_CALIBRATED_GAINS_0);
677
+
678
+		if (nmeasurement > MAX_MEASUREMENT)
679
+			nmeasurement = MAX_MEASUREMENT;
680
+
681
+		/* detect outlier only if nmeasurement > 1 */
682
+		if (nmeasurement > 1) {
683
+			/* Detect magnitude outlier */
684
+			ar9003_hw_detect_outlier(coeff->mag_coeff[i],
685
+					nmeasurement, MAX_MAG_DELTA);
686
+
687
+			/* Detect phase outlier */
688
+			ar9003_hw_detect_outlier(coeff->phs_coeff[i],
689
+					nmeasurement, MAX_PHS_DELTA);
690
+		}
691
+
692
+		for (im = 0; im < nmeasurement; im++) {
693
+
694
+			coeff->iqc_coeff[0] = (coeff->mag_coeff[i][im] & 0x7f) |
695
+				((coeff->phs_coeff[i][im] & 0x7f) << 7);
696
+
697
+			if ((im % 2) == 0)
698
+				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
699
+					AR_PHY_TX_IQCAL_CORR_COEFF_00_COEFF_TABLE,
700
+					coeff->iqc_coeff[0]);
701
+			else
702
+				REG_RMW_FIELD(ah, tx_corr_coeff[im][i],
703
+					AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE,
704
+					coeff->iqc_coeff[0]);
705
+		}
706
+	}
707
+
708
+	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_3,
709
+		      AR_PHY_TX_IQCAL_CONTROL_3_IQCORR_EN, 0x1);
710
+	REG_RMW_FIELD(ah, AR_PHY_RX_IQCAL_CORR_B0,
711
+		      AR_PHY_RX_IQCAL_CORR_B0_LOOPBACK_IQCORR_EN, 0x1);
712
+
713
+	return;
714
+
715
+}
716
+
717
+static int ar9003_hw_tx_iq_cal_run(struct ath_hw *ah)
718
+{
719
+	u8 tx_gain_forced;
720
+
721
+	tx_gain_forced = REG_READ_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
722
+					AR_PHY_TXGAIN_FORCE);
723
+	if (tx_gain_forced)
724
+		REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
725
+			      AR_PHY_TXGAIN_FORCE, 0);
726
+
727
+	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_START,
728
+		      AR_PHY_TX_IQCAL_START_DO_CAL, 1);
729
+
730
+	if (!ath9k_hw_wait(ah, AR_PHY_TX_IQCAL_START,
731
+			AR_PHY_TX_IQCAL_START_DO_CAL, 0,
732
+			AH_WAIT_TIMEOUT)) {
733
+		DBG2("ath9k: "
734
+			"Tx IQ Cal is not completed.\n");
735
+		return 0;
736
+	}
737
+	return 1;
738
+}
739
+
740
+static void ar9003_hw_tx_iq_cal_post_proc(struct ath_hw *ah)
741
+{
742
+	const u32 txiqcal_status[AR9300_MAX_CHAINS] = {
743
+		AR_PHY_TX_IQCAL_STATUS_B0,
744
+		AR_PHY_TX_IQCAL_STATUS_B1,
745
+		AR_PHY_TX_IQCAL_STATUS_B2,
746
+	};
747
+	const uint32_t chan_info_tab[] = {
748
+		AR_PHY_CHAN_INFO_TAB_0,
749
+		AR_PHY_CHAN_INFO_TAB_1,
750
+		AR_PHY_CHAN_INFO_TAB_2,
751
+	};
752
+	struct coeff coeff;
753
+	s32 iq_res[6];
754
+	u8 num_chains = 0;
755
+	int i, im, j;
756
+	int nmeasurement;
757
+
758
+	for (i = 0; i < AR9300_MAX_CHAINS; i++) {
759
+		if (ah->txchainmask & (1 << i))
760
+			num_chains++;
761
+	}
762
+
763
+	for (i = 0; i < num_chains; i++) {
764
+		nmeasurement = REG_READ_FIELD(ah,
765
+				AR_PHY_TX_IQCAL_STATUS_B0,
766
+				AR_PHY_CALIBRATED_GAINS_0);
767
+		if (nmeasurement > MAX_MEASUREMENT)
768
+			nmeasurement = MAX_MEASUREMENT;
769
+
770
+		for (im = 0; im < nmeasurement; im++) {
771
+			DBG2("ath9k: "
772
+				"Doing Tx IQ Cal for chain %d.\n", i);
773
+
774
+			if (REG_READ(ah, txiqcal_status[i]) &
775
+					AR_PHY_TX_IQCAL_STATUS_FAILED) {
776
+				DBG("ath9k: "
777
+					"Tx IQ Cal failed for chain %d.\n", i);
778
+				goto tx_iqcal_fail;
779
+			}
780
+
781
+			for (j = 0; j < 3; j++) {
782
+				u32 idx = 2 * j, offset = 4 * (3 * im + j);
783
+
784
+				REG_RMW_FIELD(ah,
785
+						AR_PHY_CHAN_INFO_MEMORY,
786
+						AR_PHY_CHAN_INFO_TAB_S2_READ,
787
+						0);
788
+
789
+				/* 32 bits */
790
+				iq_res[idx] = REG_READ(ah,
791
+						chan_info_tab[i] +
792
+						offset);
793
+
794
+				REG_RMW_FIELD(ah,
795
+						AR_PHY_CHAN_INFO_MEMORY,
796
+						AR_PHY_CHAN_INFO_TAB_S2_READ,
797
+						1);
798
+
799
+				/* 16 bits */
800
+				iq_res[idx + 1] = 0xffff & REG_READ(ah,
801
+						chan_info_tab[i] + offset);
802
+
803
+				DBG2("ath9k: "
804
+					"IQ RES[%d]=0x%x"
805
+					"IQ_RES[%d]=0x%x\n",
806
+					idx, iq_res[idx], idx + 1,
807
+					iq_res[idx + 1]);
808
+			}
809
+
810
+			if (!ar9003_hw_calc_iq_corr(ah, i, iq_res,
811
+						coeff.iqc_coeff)) {
812
+				DBG("ath9k: "
813
+					"Failed in calculation of \
814
+					IQ correction.\n");
815
+				goto tx_iqcal_fail;
816
+			}
817
+
818
+			coeff.mag_coeff[i][im] = coeff.iqc_coeff[0] & 0x7f;
819
+			coeff.phs_coeff[i][im] =
820
+				(coeff.iqc_coeff[0] >> 7) & 0x7f;
821
+
822
+			if (coeff.mag_coeff[i][im] > 63)
823
+				coeff.mag_coeff[i][im] -= 128;
824
+			if (coeff.phs_coeff[i][im] > 63)
825
+				coeff.phs_coeff[i][im] -= 128;
826
+		}
827
+	}
828
+	ar9003_hw_tx_iqcal_load_avg_2_passes(ah, num_chains, &coeff);
829
+
830
+	return;
831
+
832
+tx_iqcal_fail:
833
+	DBG("ath9k: Tx IQ Cal failed\n");
834
+	return;
835
+}
836
+static int ar9003_hw_init_cal(struct ath_hw *ah,
837
+			       struct ath9k_channel *chan __unused)
838
+{
839
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
840
+	int val;
841
+	int txiqcal_done = 0;
842
+
843
+	val = REG_READ(ah, AR_ENT_OTP);
844
+	DBG2("ath9k: ath9k: AR_ENT_OTP 0x%x\n", val);
845
+
846
+	/* Configure rx/tx chains before running AGC/TxiQ cals */
847
+	if (val & AR_ENT_OTP_CHAIN2_DISABLE)
848
+		ar9003_hw_set_chain_masks(ah, 0x3, 0x3);
849
+	else
850
+		ar9003_hw_set_chain_masks(ah, pCap->rx_chainmask,
851
+					  pCap->tx_chainmask);
852
+
853
+	/* Do Tx IQ Calibration */
854
+	REG_RMW_FIELD(ah, AR_PHY_TX_IQCAL_CONTROL_1,
855
+		      AR_PHY_TX_IQCAL_CONTROL_1_IQCORR_I_Q_COFF_DELPT,
856
+		      DELPT);
857
+
858
+	/*
859
+	 * For AR9485 or later chips, TxIQ cal runs as part of
860
+	 * AGC calibration
861
+	 */
862
+	if (AR_SREV_9485_OR_LATER(ah))
863
+		txiqcal_done = 1;
864
+	else {
865
+		txiqcal_done = ar9003_hw_tx_iq_cal_run(ah);
866
+		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
867
+		udelay(5);
868
+		REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
869
+	}
870
+
871
+	/* Calibrate the AGC */
872
+	REG_WRITE(ah, AR_PHY_AGC_CONTROL,
873
+		  REG_READ(ah, AR_PHY_AGC_CONTROL) |
874
+		  AR_PHY_AGC_CONTROL_CAL);
875
+
876
+	/* Poll for offset calibration complete */
877
+	if (!ath9k_hw_wait(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL,
878
+			   0, AH_WAIT_TIMEOUT)) {
879
+		DBG("ath9k: "
880
+			"offset calibration failed to complete in 1ms; noisy environment?\n");
881
+		return 0;
882
+	}
883
+
884
+	if (txiqcal_done)
885
+		ar9003_hw_tx_iq_cal_post_proc(ah);
886
+
887
+	/* Revert chainmasks to their original values before NF cal */
888
+	ar9003_hw_set_chain_masks(ah, ah->rxchainmask, ah->txchainmask);
889
+
890
+	ath9k_hw_start_nfcal(ah, 1);
891
+
892
+	/* Initialize list pointers */
893
+	ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
894
+	ah->supp_cals = IQ_MISMATCH_CAL;
895
+
896
+	if (ah->supp_cals & IQ_MISMATCH_CAL) {
897
+		INIT_CAL(&ah->iq_caldata);
898
+		INSERT_CAL(ah, &ah->iq_caldata);
899
+		DBG2("ath9k: "
900
+			"enabling IQ Calibration.\n");
901
+	}
902
+
903
+	if (ah->supp_cals & TEMP_COMP_CAL) {
904
+		INIT_CAL(&ah->tempCompCalData);
905
+		INSERT_CAL(ah, &ah->tempCompCalData);
906
+		DBG2("ath9k: "
907
+			"enabling Temperature Compensation Calibration.\n");
908
+	}
909
+
910
+	/* Initialize current pointer to first element in list */
911
+	ah->cal_list_curr = ah->cal_list;
912
+
913
+	if (ah->cal_list_curr)
914
+		ath9k_hw_reset_calibration(ah, ah->cal_list_curr);
915
+
916
+	if (ah->caldata)
917
+		ah->caldata->CalValid = 0;
918
+
919
+	return 1;
920
+}
921
+
922
+void ar9003_hw_attach_calib_ops(struct ath_hw *ah)
923
+{
924
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
925
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
926
+
927
+	priv_ops->init_cal_settings = ar9003_hw_init_cal_settings;
928
+	priv_ops->init_cal = ar9003_hw_init_cal;
929
+	priv_ops->setup_calibration = ar9003_hw_setup_calibration;
930
+
931
+	ops->calibrate = ar9003_hw_calibrate;
932
+}

+ 5005
- 0
src/drivers/net/ath/ath9k/ath9k_ar9003_eeprom.c
File diff suppressed because it is too large
View File


+ 409
- 0
src/drivers/net/ath/ath9k/ath9k_ar9003_hw.c View File

@@ -0,0 +1,409 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 "hw.h"
21
+#include "ar9003_mac.h"
22
+#include "ar9003_2p2_initvals.h"
23
+#include "ar9485_initvals.h"
24
+#include "ar9340_initvals.h"
25
+
26
+/* General hardware code for the AR9003 hadware family */
27
+
28
+/*
29
+ * The AR9003 family uses a new INI format (pre, core, post
30
+ * arrays per subsystem). This provides support for the
31
+ * AR9003 2.2 chipsets.
32
+ */
33
+static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
34
+{
35
+	if (AR_SREV_9340(ah)) {
36
+		/* mac */
37
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
38
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
39
+				ar9340_1p0_mac_core,
40
+				ARRAY_SIZE(ar9340_1p0_mac_core), 2);
41
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
42
+				ar9340_1p0_mac_postamble,
43
+				ARRAY_SIZE(ar9340_1p0_mac_postamble), 5);
44
+
45
+		/* bb */
46
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
47
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
48
+				ar9340_1p0_baseband_core,
49
+				ARRAY_SIZE(ar9340_1p0_baseband_core), 2);
50
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
51
+				ar9340_1p0_baseband_postamble,
52
+				ARRAY_SIZE(ar9340_1p0_baseband_postamble), 5);
53
+
54
+		/* radio */
55
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
56
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
57
+				ar9340_1p0_radio_core,
58
+				ARRAY_SIZE(ar9340_1p0_radio_core), 2);
59
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
60
+				ar9340_1p0_radio_postamble,
61
+				ARRAY_SIZE(ar9340_1p0_radio_postamble), 5);
62
+
63
+		/* soc */
64
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
65
+				ar9340_1p0_soc_preamble,
66
+				ARRAY_SIZE(ar9340_1p0_soc_preamble), 2);
67
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
68
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
69
+				ar9340_1p0_soc_postamble,
70
+				ARRAY_SIZE(ar9340_1p0_soc_postamble), 5);
71
+
72
+		/* rx/tx gain */
73
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
74
+				ar9340Common_wo_xlna_rx_gain_table_1p0,
75
+				ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
76
+				5);
77
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
78
+				ar9340Modes_high_ob_db_tx_gain_table_1p0,
79
+				ARRAY_SIZE(ar9340Modes_high_ob_db_tx_gain_table_1p0),
80
+				5);
81
+
82
+		INIT_INI_ARRAY(&ah->iniModesAdditional,
83
+				ar9340Modes_fast_clock_1p0,
84
+				ARRAY_SIZE(ar9340Modes_fast_clock_1p0),
85
+				3);
86
+
87
+		INIT_INI_ARRAY(&ah->iniModesAdditional_40M,
88
+				ar9340_1p0_radio_core_40M,
89
+				ARRAY_SIZE(ar9340_1p0_radio_core_40M),
90
+				2);
91
+	} else if (AR_SREV_9485_11(ah)) {
92
+		/* mac */
93
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
94
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
95
+				ar9485_1_1_mac_core,
96
+				ARRAY_SIZE(ar9485_1_1_mac_core), 2);
97
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
98
+				ar9485_1_1_mac_postamble,
99
+				ARRAY_SIZE(ar9485_1_1_mac_postamble), 5);
100
+
101
+		/* bb */
102
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], ar9485_1_1,
103
+				ARRAY_SIZE(ar9485_1_1), 2);
104
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
105
+				ar9485_1_1_baseband_core,
106
+				ARRAY_SIZE(ar9485_1_1_baseband_core), 2);
107
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
108
+				ar9485_1_1_baseband_postamble,
109
+				ARRAY_SIZE(ar9485_1_1_baseband_postamble), 5);
110
+
111
+		/* radio */
112
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
113
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
114
+				ar9485_1_1_radio_core,
115
+				ARRAY_SIZE(ar9485_1_1_radio_core), 2);
116
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
117
+				ar9485_1_1_radio_postamble,
118
+				ARRAY_SIZE(ar9485_1_1_radio_postamble), 2);
119
+
120
+		/* soc */
121
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
122
+				ar9485_1_1_soc_preamble,
123
+				ARRAY_SIZE(ar9485_1_1_soc_preamble), 2);
124
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
125
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST], NULL, 0, 0);
126
+
127
+		/* rx/tx gain */
128
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
129
+				ar9485Common_wo_xlna_rx_gain_1_1,
130
+				ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1), 2);
131
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
132
+				ar9485_modes_lowest_ob_db_tx_gain_1_1,
133
+				ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
134
+				5);
135
+
136
+		/* Load PCIE SERDES settings from INI */
137
+
138
+		/* Awake Setting */
139
+
140
+		INIT_INI_ARRAY(&ah->iniPcieSerdes,
141
+				ar9485_1_1_pcie_phy_clkreq_disable_L1,
142
+				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
143
+				2);
144
+
145
+		/* Sleep Setting */
146
+
147
+		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
148
+				ar9485_1_1_pcie_phy_clkreq_disable_L1,
149
+				ARRAY_SIZE(ar9485_1_1_pcie_phy_clkreq_disable_L1),
150
+				2);
151
+	} else {
152
+		/* mac */
153
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_PRE], NULL, 0, 0);
154
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
155
+				ar9300_2p2_mac_core,
156
+				ARRAY_SIZE(ar9300_2p2_mac_core), 2);
157
+		INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
158
+				ar9300_2p2_mac_postamble,
159
+				ARRAY_SIZE(ar9300_2p2_mac_postamble), 5);
160
+
161
+		/* bb */
162
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_PRE], NULL, 0, 0);
163
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
164
+				ar9300_2p2_baseband_core,
165
+				ARRAY_SIZE(ar9300_2p2_baseband_core), 2);
166
+		INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
167
+				ar9300_2p2_baseband_postamble,
168
+				ARRAY_SIZE(ar9300_2p2_baseband_postamble), 5);
169
+
170
+		/* radio */
171
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_PRE], NULL, 0, 0);
172
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
173
+				ar9300_2p2_radio_core,
174
+				ARRAY_SIZE(ar9300_2p2_radio_core), 2);
175
+		INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
176
+				ar9300_2p2_radio_postamble,
177
+				ARRAY_SIZE(ar9300_2p2_radio_postamble), 5);
178
+
179
+		/* soc */
180
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
181
+				ar9300_2p2_soc_preamble,
182
+				ARRAY_SIZE(ar9300_2p2_soc_preamble), 2);
183
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_CORE], NULL, 0, 0);
184
+		INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
185
+				ar9300_2p2_soc_postamble,
186
+				ARRAY_SIZE(ar9300_2p2_soc_postamble), 5);
187
+
188
+		/* rx/tx gain */
189
+		INIT_INI_ARRAY(&ah->iniModesRxGain,
190
+				ar9300Common_rx_gain_table_2p2,
191
+				ARRAY_SIZE(ar9300Common_rx_gain_table_2p2), 2);
192
+		INIT_INI_ARRAY(&ah->iniModesTxGain,
193
+				ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
194
+				ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
195
+				5);
196
+
197
+		/* Load PCIE SERDES settings from INI */
198
+
199
+		/* Awake Setting */
200
+
201
+		INIT_INI_ARRAY(&ah->iniPcieSerdes,
202
+				ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
203
+				ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
204
+				2);
205
+
206
+		/* Sleep Setting */
207
+
208
+		INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
209
+				ar9300PciePhy_pll_on_clkreq_disable_L1_2p2,
210
+				ARRAY_SIZE(ar9300PciePhy_pll_on_clkreq_disable_L1_2p2),
211
+				2);
212
+
213
+		/* Fast clock modal settings */
214
+		INIT_INI_ARRAY(&ah->iniModesAdditional,
215
+				ar9300Modes_fast_clock_2p2,
216
+				ARRAY_SIZE(ar9300Modes_fast_clock_2p2),
217
+				3);
218
+	}
219
+}
220
+
221
+static void ar9003_tx_gain_table_apply(struct ath_hw *ah)
222
+{
223
+	switch (ar9003_hw_get_tx_gain_idx(ah)) {
224
+	case 0:
225
+	default:
226
+		if (AR_SREV_9340(ah))
227
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
228
+					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
229
+				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
230
+				       5);
231
+		else if (AR_SREV_9485_11(ah))
232
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
233
+				       ar9485_modes_lowest_ob_db_tx_gain_1_1,
234
+				       ARRAY_SIZE(ar9485_modes_lowest_ob_db_tx_gain_1_1),
235
+				       5);
236
+		else
237
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
238
+				       ar9300Modes_lowest_ob_db_tx_gain_table_2p2,
239
+				       ARRAY_SIZE(ar9300Modes_lowest_ob_db_tx_gain_table_2p2),
240
+				       5);
241
+		break;
242
+	case 1:
243
+		if (AR_SREV_9340(ah))
244
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
245
+					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
246
+				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
247
+				       5);
248
+		else if (AR_SREV_9485_11(ah))
249
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
250
+				       ar9485Modes_high_ob_db_tx_gain_1_1,
251
+				       ARRAY_SIZE(ar9485Modes_high_ob_db_tx_gain_1_1),
252
+				       5);
253
+		else
254
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
255
+				       ar9300Modes_high_ob_db_tx_gain_table_2p2,
256
+				       ARRAY_SIZE(ar9300Modes_high_ob_db_tx_gain_table_2p2),
257
+				       5);
258
+		break;
259
+	case 2:
260
+		if (AR_SREV_9340(ah))
261
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
262
+					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
263
+				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
264
+				       5);
265
+		else if (AR_SREV_9485_11(ah))
266
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
267
+				       ar9485Modes_low_ob_db_tx_gain_1_1,
268
+				       ARRAY_SIZE(ar9485Modes_low_ob_db_tx_gain_1_1),
269
+				       5);
270
+		else
271
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
272
+				       ar9300Modes_low_ob_db_tx_gain_table_2p2,
273
+				       ARRAY_SIZE(ar9300Modes_low_ob_db_tx_gain_table_2p2),
274
+				       5);
275
+		break;
276
+	case 3:
277
+		if (AR_SREV_9340(ah))
278
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
279
+					ar9340Modes_lowest_ob_db_tx_gain_table_1p0,
280
+				       ARRAY_SIZE(ar9340Modes_lowest_ob_db_tx_gain_table_1p0),
281
+				       5);
282
+		else if (AR_SREV_9485_11(ah))
283
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
284
+				       ar9485Modes_high_power_tx_gain_1_1,
285
+				       ARRAY_SIZE(ar9485Modes_high_power_tx_gain_1_1),
286
+				       5);
287
+		else
288
+			INIT_INI_ARRAY(&ah->iniModesTxGain,
289
+				       ar9300Modes_high_power_tx_gain_table_2p2,
290
+				       ARRAY_SIZE(ar9300Modes_high_power_tx_gain_table_2p2),
291
+				       5);
292
+		break;
293
+	}
294
+}
295
+
296
+static void ar9003_rx_gain_table_apply(struct ath_hw *ah)
297
+{
298
+	switch (ar9003_hw_get_rx_gain_idx(ah)) {
299
+	case 0:
300
+	default:
301
+		if (AR_SREV_9340(ah))
302
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
303
+				       ar9340Common_rx_gain_table_1p0,
304
+				       ARRAY_SIZE(ar9340Common_rx_gain_table_1p0),
305
+				       2);
306
+		else if (AR_SREV_9485_11(ah))
307
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
308
+				       ar9485Common_wo_xlna_rx_gain_1_1,
309
+				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
310
+				       2);
311
+		else
312
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
313
+				       ar9300Common_rx_gain_table_2p2,
314
+				       ARRAY_SIZE(ar9300Common_rx_gain_table_2p2),
315
+				       2);
316
+		break;
317
+	case 1:
318
+		if (AR_SREV_9340(ah))
319
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
320
+				       ar9340Common_wo_xlna_rx_gain_table_1p0,
321
+				       ARRAY_SIZE(ar9340Common_wo_xlna_rx_gain_table_1p0),
322
+				       2);
323
+		else if (AR_SREV_9485_11(ah))
324
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
325
+				       ar9485Common_wo_xlna_rx_gain_1_1,
326
+				       ARRAY_SIZE(ar9485Common_wo_xlna_rx_gain_1_1),
327
+				       2);
328
+		else
329
+			INIT_INI_ARRAY(&ah->iniModesRxGain,
330
+				       ar9300Common_wo_xlna_rx_gain_table_2p2,
331
+				       ARRAY_SIZE(ar9300Common_wo_xlna_rx_gain_table_2p2),
332
+				       2);
333
+		break;
334
+	}
335
+}
336
+
337
+/* set gain table pointers according to values read from the eeprom */
338
+static void ar9003_hw_init_mode_gain_regs(struct ath_hw *ah)
339
+{
340
+	ar9003_tx_gain_table_apply(ah);
341
+	ar9003_rx_gain_table_apply(ah);
342
+}
343
+
344
+/*
345
+ * Helper for ASPM support.
346
+ *
347
+ * Disable PLL when in L0s as well as receiver clock when in L1.
348
+ * This power saving option must be enabled through the SerDes.
349
+ *
350
+ * Programming the SerDes must go through the same 288 bit serial shift
351
+ * register as the other analog registers.  Hence the 9 writes.
352
+ */
353
+static void ar9003_hw_configpcipowersave(struct ath_hw *ah,
354
+					 int restore,
355
+					 int power_off)
356
+{
357
+	if (ah->is_pciexpress != 1)
358
+		return;
359
+
360
+	/* Do not touch SerDes registers */
361
+	if (ah->config.pcie_powersave_enable == 2)
362
+		return;
363
+
364
+	/* Nothing to do on restore for 11N */
365
+	if (!restore) {
366
+		/* set bit 19 to allow forcing of pcie core into L1 state */
367
+		REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
368
+
369
+		/* Several PCIe massages to ensure proper behaviour */
370
+		if (ah->config.pcie_waen)
371
+			REG_WRITE(ah, AR_WA, ah->config.pcie_waen);
372
+		else
373
+			REG_WRITE(ah, AR_WA, ah->WARegVal);
374
+	}
375
+
376
+	/*
377
+	 * Configire PCIE after Ini init. SERDES values now come from ini file
378
+	 * This enables PCIe low power mode.
379
+	 */
380
+	if (ah->config.pcieSerDesWrite) {
381
+		unsigned int i;
382
+		struct ar5416IniArray *array;
383
+
384
+		array = power_off ? &ah->iniPcieSerdes :
385
+				    &ah->iniPcieSerdesLowPower;
386
+
387
+		for (i = 0; i < array->ia_rows; i++) {
388
+			REG_WRITE(ah,
389
+				  INI_RA(array, i, 0),
390
+				  INI_RA(array, i, 1));
391
+		}
392
+	}
393
+}
394
+
395
+/* Sets up the AR9003 hardware familiy callbacks */
396
+void ar9003_hw_attach_ops(struct ath_hw *ah)
397
+{
398
+	struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
399
+	struct ath_hw_ops *ops = ath9k_hw_ops(ah);
400
+
401
+	priv_ops->init_mode_regs = ar9003_hw_init_mode_regs;
402
+	priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
403
+
404
+	ops->config_pci_powersave = ar9003_hw_configpcipowersave;
405
+
406
+	ar9003_hw_attach_phy_ops(ah);
407
+	ar9003_hw_attach_calib_ops(ah);
408
+	ar9003_hw_attach_mac_ops(ah);
409
+}

+ 669
- 0
src/drivers/net/ath/ath9k/ath9k_ar9003_mac.c View File

@@ -0,0 +1,669 @@
1
+/*
2
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#include <ipxe/io.h>
20
+
21
+#include "hw.h"
22
+#include "ar9003_mac.h"
23
+
24
+static void ar9003_hw_rx_enable(struct ath_hw *hw)
25
+{
26
+	REG_WRITE(hw, AR_CR, 0);
27
+}
28
+
29
+static u16 ar9003_calc_ptr_chksum(struct ar9003_txc *ads)
30
+{
31
+	int checksum;
32
+
33
+	checksum = ads->info + ads->link
34
+		+ ads->data0 + ads->ctl3
35
+		+ ads->data1 + ads->ctl5
36
+		+ ads->data2 + ads->ctl7
37
+		+ ads->data3 + ads->ctl9;
38
+
39
+	return ((checksum & 0xffff) + (checksum >> 16)) & AR_TxPtrChkSum;
40
+}
41
+
42
+static void ar9003_hw_set_desc_link(void *ds, u32 ds_link)
43
+{
44
+	struct ar9003_txc *ads = ds;
45
+
46
+	ads->link = ds_link;
47
+	ads->ctl10 &= ~AR_TxPtrChkSum;
48
+	ads->ctl10 |= ar9003_calc_ptr_chksum(ads);
49
+}
50
+
51
+static void ar9003_hw_get_desc_link(void *ds, u32 **ds_link)
52
+{
53
+	struct ar9003_txc *ads = ds;
54
+
55
+	*ds_link = &ads->link;
56
+}
57
+
58
+static int ar9003_hw_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
59
+{
60
+	u32 isr = 0;
61
+	u32 mask2 = 0;
62
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
63
+	u32 sync_cause = 0;
64
+
65
+	if (ah->ah_ier & AR_IER_ENABLE) {
66
+		if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
67
+			if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
68
+					== AR_RTC_STATUS_ON)
69
+				isr = REG_READ(ah, AR_ISR);
70
+		}
71
+
72
+		sync_cause = REG_READ(ah, AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
73
+
74
+		*masked = 0;
75
+
76
+		if (!isr && !sync_cause)
77
+			return 0;
78
+	} else {
79
+		*masked = 0;
80
+		isr = REG_READ(ah, AR_ISR);
81
+	}
82
+
83
+	if (isr) {
84
+		if (isr & AR_ISR_BCNMISC) {
85
+			u32 isr2;
86
+			isr2 = REG_READ(ah, AR_ISR_S2);
87
+
88
+			mask2 |= ((isr2 & AR_ISR_S2_TIM) >>
89
+				  MAP_ISR_S2_TIM);
90
+			mask2 |= ((isr2 & AR_ISR_S2_DTIM) >>
91
+				  MAP_ISR_S2_DTIM);
92
+			mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >>
93
+				  MAP_ISR_S2_DTIMSYNC);
94
+			mask2 |= ((isr2 & AR_ISR_S2_CABEND) >>
95
+				  MAP_ISR_S2_CABEND);
96
+			mask2 |= ((isr2 & AR_ISR_S2_GTT) <<
97
+				  MAP_ISR_S2_GTT);
98
+			mask2 |= ((isr2 & AR_ISR_S2_CST) <<
99
+				  MAP_ISR_S2_CST);
100
+			mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >>
101
+				  MAP_ISR_S2_TSFOOR);
102
+			mask2 |= ((isr2 & AR_ISR_S2_BB_WATCHDOG) >>
103
+				  MAP_ISR_S2_BB_WATCHDOG);
104
+
105
+			if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
106
+				REG_WRITE(ah, AR_ISR_S2, isr2);
107
+				isr &= ~AR_ISR_BCNMISC;
108
+			}
109
+		}
110
+
111
+		if ((pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED))
112
+			isr = REG_READ(ah, AR_ISR_RAC);
113
+
114
+		if (isr == 0xffffffff) {
115
+			*masked = 0;
116
+			return 0;
117
+		}
118
+
119
+		*masked = isr & ATH9K_INT_COMMON;
120
+
121
+		if (ah->config.rx_intr_mitigation)
122
+			if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
123
+				*masked |= ATH9K_INT_RXLP;
124
+
125
+		if (ah->config.tx_intr_mitigation)
126
+			if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM))
127
+				*masked |= ATH9K_INT_TX;
128
+
129
+		if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR))
130
+			*masked |= ATH9K_INT_RXLP;
131
+
132
+		if (isr & AR_ISR_HP_RXOK)
133
+			*masked |= ATH9K_INT_RXHP;
134
+
135
+		if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
136
+			*masked |= ATH9K_INT_TX;
137
+
138
+			if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
139
+				u32 s0, s1;
140
+				s0 = REG_READ(ah, AR_ISR_S0);
141
+				REG_WRITE(ah, AR_ISR_S0, s0);
142
+				s1 = REG_READ(ah, AR_ISR_S1);
143
+				REG_WRITE(ah, AR_ISR_S1, s1);
144
+
145
+				isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR |
146
+					 AR_ISR_TXEOL);
147
+			}
148
+		}
149
+
150
+		if (isr & AR_ISR_GENTMR) {
151
+			u32 s5;
152
+
153
+			if (pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)
154
+				s5 = REG_READ(ah, AR_ISR_S5_S);
155
+			else
156
+				s5 = REG_READ(ah, AR_ISR_S5);
157
+
158
+			ah->intr_gen_timer_trigger =
159
+				MS(s5, AR_ISR_S5_GENTIMER_TRIG);
160
+
161
+			ah->intr_gen_timer_thresh =
162
+				MS(s5, AR_ISR_S5_GENTIMER_THRESH);
163
+
164
+			if (ah->intr_gen_timer_trigger)
165
+				*masked |= ATH9K_INT_GENTIMER;
166
+
167
+			if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
168
+				REG_WRITE(ah, AR_ISR_S5, s5);
169
+				isr &= ~AR_ISR_GENTMR;
170
+			}
171
+
172
+		}
173
+
174
+		*masked |= mask2;
175
+
176
+		if (!(pCap->hw_caps & ATH9K_HW_CAP_RAC_SUPPORTED)) {
177
+			REG_WRITE(ah, AR_ISR, isr);
178
+
179
+			(void) REG_READ(ah, AR_ISR);
180
+		}
181
+	}
182
+
183
+	if (sync_cause) {
184
+		if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
185
+			REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
186
+			REG_WRITE(ah, AR_RC, 0);
187
+			*masked |= ATH9K_INT_FATAL;
188
+		}
189
+
190
+		if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT)
191
+			DBG("ath9k: "
192
+				"AR_INTR_SYNC_LOCAL_TIMEOUT\n");
193
+
194
+		REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
195
+		(void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
196
+
197
+	}
198
+	return 1;
199
+}
200
+
201
+static void ar9003_hw_fill_txdesc(struct ath_hw *ah __unused, void *ds, u32 seglen,
202
+				  int is_firstseg, int is_lastseg,
203
+				  const void *ds0, u32 buf_addr,
204
+				  unsigned int qcu)
205
+{
206
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
207
+	unsigned int descid = 0;
208
+
209
+	ads->info = (ATHEROS_VENDOR_ID << AR_DescId_S) |
210
+				     (1 << AR_TxRxDesc_S) |
211
+				     (1 << AR_CtrlStat_S) |
212
+				     (qcu << AR_TxQcuNum_S) | 0x17;
213
+
214
+	ads->data0 = buf_addr;
215
+	ads->data1 = 0;
216
+	ads->data2 = 0;
217
+	ads->data3 = 0;
218
+
219
+	ads->ctl3 = (seglen << AR_BufLen_S);
220
+	ads->ctl3 &= AR_BufLen;
221
+
222
+	/* Fill in pointer checksum and descriptor id */
223
+	ads->ctl10 = ar9003_calc_ptr_chksum(ads);
224
+	ads->ctl10 |= (descid << AR_TxDescId_S);
225
+
226
+	if (is_firstseg) {
227
+		ads->ctl12 |= (is_lastseg ? 0 : AR_TxMore);
228
+	} else if (is_lastseg) {
229
+		ads->ctl11 = 0;
230
+		ads->ctl12 = 0;
231
+		ads->ctl13 = AR9003TXC_CONST(ds0)->ctl13;
232
+		ads->ctl14 = AR9003TXC_CONST(ds0)->ctl14;
233
+	} else {
234
+		/* XXX Intermediate descriptor in a multi-descriptor frame.*/
235
+		ads->ctl11 = 0;
236
+		ads->ctl12 = AR_TxMore;
237
+		ads->ctl13 = 0;
238
+		ads->ctl14 = 0;
239
+	}
240
+}
241
+
242
+static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds __unused,
243
+				 struct ath_tx_status *ts)
244
+{
245
+	struct ar9003_txs *ads;
246
+	u32 status;
247
+
248
+	ads = &ah->ts_ring[ah->ts_tail];
249
+
250
+	status = *(volatile typeof(ads->status8) *)&(ads->status8);
251
+	if ((status & AR_TxDone) == 0)
252
+		return -EINPROGRESS;
253
+
254
+	ah->ts_tail = (ah->ts_tail + 1) % ah->ts_size;
255
+
256
+	if ((MS(ads->ds_info, AR_DescId) != ATHEROS_VENDOR_ID) ||
257
+	    (MS(ads->ds_info, AR_TxRxDesc) != 1)) {
258
+		DBG("ath9k: "
259
+			"Tx Descriptor error %x\n", ads->ds_info);
260
+		memset(ads, 0, sizeof(*ads));
261
+		return -EIO;
262
+	}
263
+
264
+	if (status & AR_TxOpExceeded)
265
+		ts->ts_status |= ATH9K_TXERR_XTXOP;
266
+	ts->ts_rateindex = MS(status, AR_FinalTxIdx);
267
+	ts->ts_seqnum = MS(status, AR_SeqNum);
268
+	ts->tid = MS(status, AR_TxTid);
269
+
270
+	ts->qid = MS(ads->ds_info, AR_TxQcuNum);
271
+	ts->desc_id = MS(ads->status1, AR_TxDescId);
272
+	ts->ts_tstamp = ads->status4;
273
+	ts->ts_status = 0;
274
+	ts->ts_flags  = 0;
275
+
276
+	status = *(volatile typeof(ads->status2) *)&(ads->status2);
277
+	ts->ts_rssi_ctl0 = MS(status, AR_TxRSSIAnt00);
278
+	ts->ts_rssi_ctl1 = MS(status, AR_TxRSSIAnt01);
279
+	ts->ts_rssi_ctl2 = MS(status, AR_TxRSSIAnt02);
280
+	if (status & AR_TxBaStatus) {
281
+		ts->ts_flags |= ATH9K_TX_BA;
282
+		ts->ba_low = ads->status5;
283
+		ts->ba_high = ads->status6;
284
+	}
285
+
286
+	status = *(volatile typeof(ads->status3) *)&(ads->status3);
287
+	if (status & AR_ExcessiveRetries)
288
+		ts->ts_status |= ATH9K_TXERR_XRETRY;
289
+	if (status & AR_Filtered)
290
+		ts->ts_status |= ATH9K_TXERR_FILT;
291
+	if (status & AR_FIFOUnderrun) {
292
+		ts->ts_status |= ATH9K_TXERR_FIFO;
293
+		ath9k_hw_updatetxtriglevel(ah, 1);
294
+	}
295
+	if (status & AR_TxTimerExpired)
296
+		ts->ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
297
+	if (status & AR_DescCfgErr)
298
+		ts->ts_flags |= ATH9K_TX_DESC_CFG_ERR;
299
+	if (status & AR_TxDataUnderrun) {
300
+		ts->ts_flags |= ATH9K_TX_DATA_UNDERRUN;
301
+		ath9k_hw_updatetxtriglevel(ah, 1);
302
+	}
303
+	if (status & AR_TxDelimUnderrun) {
304
+		ts->ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
305
+		ath9k_hw_updatetxtriglevel(ah, 1);
306
+	}
307
+	ts->ts_shortretry = MS(status, AR_RTSFailCnt);
308
+	ts->ts_longretry = MS(status, AR_DataFailCnt);
309
+	ts->ts_virtcol = MS(status, AR_VirtRetryCnt);
310
+
311
+	status = *(volatile typeof(ads->status7) *)&(ads->status7);
312
+	ts->ts_rssi = MS(status, AR_TxRSSICombined);
313
+	ts->ts_rssi_ext0 = MS(status, AR_TxRSSIAnt10);
314
+	ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
315
+	ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
316
+
317
+	memset(ads, 0, sizeof(*ads));
318
+
319
+	return 0;
320
+}
321
+
322
+static void ar9003_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
323
+		u32 pktlen, enum ath9k_pkt_type type, u32 txpower,
324
+		u32 keyIx, enum ath9k_key_type keyType, u32 flags)
325
+{
326
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
327
+
328
+	if (txpower > ah->txpower_limit)
329
+		txpower = ah->txpower_limit;
330
+
331
+	if (txpower > 63)
332
+		txpower = 63;
333
+
334
+	ads->ctl11 = (pktlen & AR_FrameLen)
335
+		| (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
336
+		| SM(txpower, AR_XmitPower)
337
+		| (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
338
+		| (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0)
339
+		| (flags & ATH9K_TXDESC_LOWRXCHAIN ? AR_LowRxChain : 0);
340
+
341
+	ads->ctl12 =
342
+		(keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
343
+		| SM(type, AR_FrameType)
344
+		| (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
345
+		| (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
346
+		| (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
347
+
348
+	ads->ctl17 = SM(keyType, AR_EncrType) |
349
+		     (flags & ATH9K_TXDESC_LDPC ? AR_LDPC : 0);
350
+	ads->ctl18 = 0;
351
+	ads->ctl19 = AR_Not_Sounding;
352
+
353
+	ads->ctl20 = 0;
354
+	ads->ctl21 = 0;
355
+	ads->ctl22 = 0;
356
+}
357
+
358
+static void ar9003_hw_set_clrdmask(struct ath_hw *ah __unused, void *ds, int val)
359
+{
360
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
361
+
362
+	if (val)
363
+		ads->ctl11 |= AR_ClrDestMask;
364
+	else
365
+		ads->ctl11 &= ~AR_ClrDestMask;
366
+}
367
+
368
+static void ar9003_hw_set11n_ratescenario(struct ath_hw *ah __unused, void *ds,
369
+					  void *lastds,
370
+					  u32 durUpdateEn, u32 rtsctsRate,
371
+					  u32 rtsctsDuration __unused,
372
+					  struct ath9k_11n_rate_series series[],
373
+					  u32 nseries __unused, u32 flags)
374
+{
375
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
376
+	struct ar9003_txc *last_ads = (struct ar9003_txc *) lastds;
377
+	uint32_t ctl11;
378
+
379
+	if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
380
+		ctl11 = ads->ctl11;
381
+
382
+		if (flags & ATH9K_TXDESC_RTSENA) {
383
+			ctl11 &= ~AR_CTSEnable;
384
+			ctl11 |= AR_RTSEnable;
385
+		} else {
386
+			ctl11 &= ~AR_RTSEnable;
387
+			ctl11 |= AR_CTSEnable;
388
+		}
389
+
390
+		ads->ctl11 = ctl11;
391
+	} else {
392
+		ads->ctl11 = (ads->ctl11 & ~(AR_RTSEnable | AR_CTSEnable));
393
+	}
394
+
395
+	ads->ctl13 = set11nTries(series, 0)
396
+		|  set11nTries(series, 1)
397
+		|  set11nTries(series, 2)
398
+		|  set11nTries(series, 3)
399
+		|  (durUpdateEn ? AR_DurUpdateEna : 0)
400
+		|  SM(0, AR_BurstDur);
401
+
402
+	ads->ctl14 = set11nRate(series, 0)
403
+		|  set11nRate(series, 1)
404
+		|  set11nRate(series, 2)
405
+		|  set11nRate(series, 3);
406
+
407
+	ads->ctl15 = set11nPktDurRTSCTS(series, 0)
408
+		|  set11nPktDurRTSCTS(series, 1);
409
+
410
+	ads->ctl16 = set11nPktDurRTSCTS(series, 2)
411
+		|  set11nPktDurRTSCTS(series, 3);
412
+
413
+	ads->ctl18 = set11nRateFlags(series, 0)
414
+		|  set11nRateFlags(series, 1)
415
+		|  set11nRateFlags(series, 2)
416
+		|  set11nRateFlags(series, 3)
417
+		| SM(rtsctsRate, AR_RTSCTSRate);
418
+	ads->ctl19 = AR_Not_Sounding;
419
+
420
+	last_ads->ctl13 = ads->ctl13;
421
+	last_ads->ctl14 = ads->ctl14;
422
+}
423
+
424
+static void ar9003_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
425
+					u32 aggrLen)
426
+{
427
+#define FIRST_DESC_NDELIMS 60
428
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
429
+
430
+	ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
431
+
432
+	if (ah->ent_mode & AR_ENT_OTP_MPSD) {
433
+		u32 ctl17, ndelim;
434
+		/*
435
+		 * Add delimiter when using RTS/CTS with aggregation
436
+		 * and non enterprise AR9003 card
437
+		 */
438
+		ctl17 = ads->ctl17;
439
+		ndelim = MS(ctl17, AR_PadDelim);
440
+
441
+		if (ndelim < FIRST_DESC_NDELIMS) {
442
+			aggrLen += (FIRST_DESC_NDELIMS - ndelim) * 4;
443
+			ndelim = FIRST_DESC_NDELIMS;
444
+		}
445
+
446
+		ctl17 &= ~AR_AggrLen;
447
+		ctl17 |= SM(aggrLen, AR_AggrLen);
448
+
449
+		ctl17 &= ~AR_PadDelim;
450
+		ctl17 |= SM(ndelim, AR_PadDelim);
451
+
452
+		ads->ctl17 = ctl17;
453
+	} else {
454
+		ads->ctl17 &= ~AR_AggrLen;
455
+		ads->ctl17 |= SM(aggrLen, AR_AggrLen);
456
+	}
457
+}
458
+
459
+static void ar9003_hw_set11n_aggr_middle(struct ath_hw *ah __unused, void *ds,
460
+					 u32 numDelims)
461
+{
462
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
463
+	unsigned int ctl17;
464
+
465
+	ads->ctl12 |= (AR_IsAggr | AR_MoreAggr);
466
+
467
+	/*
468
+	 * We use a stack variable to manipulate ctl6 to reduce uncached
469
+	 * read modify, modfiy, write.
470
+	 */
471
+	ctl17 = ads->ctl17;
472
+	ctl17 &= ~AR_PadDelim;
473
+	ctl17 |= SM(numDelims, AR_PadDelim);
474
+	ads->ctl17 = ctl17;
475
+}
476
+
477
+static void ar9003_hw_set11n_aggr_last(struct ath_hw *ah __unused, void *ds)
478
+{
479
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
480
+
481
+	ads->ctl12 |= AR_IsAggr;
482
+	ads->ctl12 &= ~AR_MoreAggr;
483
+	ads->ctl17 &= ~AR_PadDelim;
484
+}
485
+
486
+static void ar9003_hw_clr11n_aggr(struct ath_hw *ah __unused, void *ds)
487
+{
488
+	struct ar9003_txc *ads = (struct ar9003_txc *) ds;
489
+
490
+	ads->ctl12 &= (~AR_IsAggr & ~AR_MoreAggr);
491
+}
492
+
493
+void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah __unused, void *ds, u8 chains)
494
+{
495
+	struct ar9003_txc *ads = ds;
496
+
497
+	ads->ctl12 |= SM(chains, AR_PAPRDChainMask);
498
+}
499
+
500
+void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
501
+{
502
+	struct ath_hw_ops *ops = ath9k_hw_ops(hw);
503
+
504
+	ops->rx_enable = ar9003_hw_rx_enable;
505
+	ops->set_desc_link = ar9003_hw_set_desc_link;
506
+	ops->get_desc_link = ar9003_hw_get_desc_link;
507
+	ops->get_isr = ar9003_hw_get_isr;
508
+	ops->fill_txdesc = ar9003_hw_fill_txdesc;
509
+	ops->proc_txdesc = ar9003_hw_proc_txdesc;
510
+	ops->set11n_txdesc = ar9003_hw_set11n_txdesc;
511
+	ops->set11n_ratescenario = ar9003_hw_set11n_ratescenario;
512
+	ops->set11n_aggr_first = ar9003_hw_set11n_aggr_first;
513
+	ops->set11n_aggr_middle = ar9003_hw_set11n_aggr_middle;
514
+	ops->set11n_aggr_last = ar9003_hw_set11n_aggr_last;
515
+	ops->clr11n_aggr = ar9003_hw_clr11n_aggr;
516
+	ops->set_clrdmask = ar9003_hw_set_clrdmask;
517
+}
518
+
519
+void ath9k_hw_set_rx_bufsize(struct ath_hw *ah, u16 buf_size)
520
+{
521
+	REG_WRITE(ah, AR_DATABUF_SIZE, buf_size & AR_DATABUF_SIZE_MASK);
522
+}
523
+
524
+void ath9k_hw_addrxbuf_edma(struct ath_hw *ah, u32 rxdp,
525
+			    enum ath9k_rx_qtype qtype)
526
+{
527
+	if (qtype == ATH9K_RX_QUEUE_HP)
528
+		REG_WRITE(ah, AR_HP_RXDP, rxdp);
529
+	else
530
+		REG_WRITE(ah, AR_LP_RXDP, rxdp);
531
+}
532
+
533
+int ath9k_hw_process_rxdesc_edma(struct ath_hw *ah __unused, struct ath_rx_status *rxs,
534
+				 void *buf_addr)
535
+{
536
+	struct ar9003_rxs *rxsp = (struct ar9003_rxs *) buf_addr;
537
+	unsigned int phyerr;
538
+
539
+	/* TODO: byte swap on big endian for ar9300_10 */
540
+
541
+	if ((rxsp->status11 & AR_RxDone) == 0)
542
+		return -EINPROGRESS;
543
+
544
+	if (MS(rxsp->ds_info, AR_DescId) != 0x168c)
545
+		return -EINVAL;
546
+
547
+	if ((rxsp->ds_info & (AR_TxRxDesc | AR_CtrlStat)) != 0)
548
+		return -EINPROGRESS;
549
+
550
+	if (!rxs)
551
+		return 0;
552
+
553
+	rxs->rs_status = 0;
554
+	rxs->rs_flags =  0;
555
+
556
+	rxs->rs_datalen = rxsp->status2 & AR_DataLen;
557
+	rxs->rs_tstamp =  rxsp->status3;
558
+
559
+	/* XXX: Keycache */
560
+	rxs->rs_rssi = MS(rxsp->status5, AR_RxRSSICombined);
561
+	rxs->rs_rssi_ctl0 = MS(rxsp->status1, AR_RxRSSIAnt00);
562
+	rxs->rs_rssi_ctl1 = MS(rxsp->status1, AR_RxRSSIAnt01);
563
+	rxs->rs_rssi_ctl2 = MS(rxsp->status1, AR_RxRSSIAnt02);
564
+	rxs->rs_rssi_ext0 = MS(rxsp->status5, AR_RxRSSIAnt10);
565
+	rxs->rs_rssi_ext1 = MS(rxsp->status5, AR_RxRSSIAnt11);
566
+	rxs->rs_rssi_ext2 = MS(rxsp->status5, AR_RxRSSIAnt12);
567
+
568
+	if (rxsp->status11 & AR_RxKeyIdxValid)
569
+		rxs->rs_keyix = MS(rxsp->status11, AR_KeyIdx);
570
+	else
571
+		rxs->rs_keyix = ATH9K_RXKEYIX_INVALID;
572
+
573
+	rxs->rs_rate = MS(rxsp->status1, AR_RxRate);
574
+	rxs->rs_more = (rxsp->status2 & AR_RxMore) ? 1 : 0;
575
+
576
+	rxs->rs_isaggr = (rxsp->status11 & AR_RxAggr) ? 1 : 0;
577
+	rxs->rs_moreaggr = (rxsp->status11 & AR_RxMoreAggr) ? 1 : 0;
578
+	rxs->rs_antenna = (MS(rxsp->status4, AR_RxAntenna) & 0x7);
579
+	rxs->rs_flags  = (rxsp->status4 & AR_GI) ? ATH9K_RX_GI : 0;
580
+	rxs->rs_flags  |= (rxsp->status4 & AR_2040) ? ATH9K_RX_2040 : 0;
581
+
582
+	rxs->evm0 = rxsp->status6;
583
+	rxs->evm1 = rxsp->status7;
584
+	rxs->evm2 = rxsp->status8;
585
+	rxs->evm3 = rxsp->status9;
586
+	rxs->evm4 = (rxsp->status10 & 0xffff);
587
+
588
+	if (rxsp->status11 & AR_PreDelimCRCErr)
589
+		rxs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
590
+
591
+	if (rxsp->status11 & AR_PostDelimCRCErr)
592
+		rxs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
593
+
594
+	if (rxsp->status11 & AR_DecryptBusyErr)
595
+		rxs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
596
+
597
+	if ((rxsp->status11 & AR_RxFrameOK) == 0) {
598
+		/*
599
+		 * AR_CRCErr will bet set to true if we're on the last
600
+		 * subframe and the AR_PostDelimCRCErr is caught.
601
+		 * In a way this also gives us a guarantee that when
602
+		 * (!(AR_CRCErr) && (AR_PostDelimCRCErr)) we cannot
603
+		 * possibly be reviewing the last subframe. AR_CRCErr
604
+		 * is the CRC of the actual data.
605
+		 */
606
+		if (rxsp->status11 & AR_CRCErr)
607
+			rxs->rs_status |= ATH9K_RXERR_CRC;
608
+		else if (rxsp->status11 & AR_PHYErr) {
609
+			phyerr = MS(rxsp->status11, AR_PHYErrCode);
610
+			/*
611
+			 * If we reach a point here where AR_PostDelimCRCErr is
612
+			 * true it implies we're *not* on the last subframe. In
613
+			 * in that case that we know already that the CRC of
614
+			 * the frame was OK, and MAC would send an ACK for that
615
+			 * subframe, even if we did get a phy error of type
616
+			 * ATH9K_PHYERR_OFDM_RESTART. This is only applicable
617
+			 * to frame that are prior to the last subframe.
618
+			 * The AR_PostDelimCRCErr is the CRC for the MPDU
619
+			 * delimiter, which contains the 4 reserved bits,
620
+			 * the MPDU length (12 bits), and follows the MPDU
621
+			 * delimiter for an A-MPDU subframe (0x4E = 'N' ASCII).
622
+			 */
623
+			if ((phyerr == ATH9K_PHYERR_OFDM_RESTART) &&
624
+			    (rxsp->status11 & AR_PostDelimCRCErr)) {
625
+				rxs->rs_phyerr = 0;
626
+			} else {
627
+				rxs->rs_status |= ATH9K_RXERR_PHY;
628
+				rxs->rs_phyerr = phyerr;
629
+			}
630
+
631
+		} else if (rxsp->status11 & AR_DecryptCRCErr)
632
+			rxs->rs_status |= ATH9K_RXERR_DECRYPT;
633
+		else if (rxsp->status11 & AR_MichaelErr)
634
+			rxs->rs_status |= ATH9K_RXERR_MIC;
635
+		else if (rxsp->status11 & AR_KeyMiss)
636
+			rxs->rs_status |= ATH9K_RXERR_DECRYPT;
637
+	}
638
+
639
+	return 0;
640
+}
641
+
642
+void ath9k_hw_reset_txstatus_ring(struct ath_hw *ah)
643
+{
644
+	ah->ts_tail = 0;
645
+
646
+	memset((void *) ah->ts_ring, 0,
647
+		ah->ts_size * sizeof(struct ar9003_txs));
648
+
649
+	DBG2("ath9k: "
650
+		"TS Start 0x%x End 0x%x Virt %p, Size %d\n",
651
+		ah->ts_paddr_start, ah->ts_paddr_end,
652
+		ah->ts_ring, ah->ts_size);
653
+
654
+	REG_WRITE(ah, AR_Q_STATUS_RING_START, ah->ts_paddr_start);
655
+	REG_WRITE(ah, AR_Q_STATUS_RING_END, ah->ts_paddr_end);
656
+}
657
+
658
+void ath9k_hw_setup_statusring(struct ath_hw *ah, void *ts_start,
659
+			       u32 ts_paddr_start,
660
+			       u8 size)
661
+{
662
+
663
+	ah->ts_paddr_start = ts_paddr_start;
664
+	ah->ts_paddr_end = ts_paddr_start + (size * sizeof(struct ar9003_txs));
665
+	ah->ts_size = size;
666
+	ah->ts_ring = (struct ar9003_txs *) ts_start;
667
+
668
+	ath9k_hw_reset_txstatus_ring(ah);
669
+}

+ 1277
- 0
src/drivers/net/ath/ath9k/ath9k_ar9003_phy.c
File diff suppressed because it is too large
View File


+ 403
- 0
src/drivers/net/ath/ath9k/ath9k_calib.c View File

@@ -0,0 +1,403 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 "hw.h"
21
+#include "hw-ops.h"
22
+
23
+/* Common calibration code */
24
+
25
+#define ATH9K_NF_TOO_HIGH	-60
26
+
27
+static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
28
+{
29
+	int16_t nfval;
30
+	int16_t sort[ATH9K_NF_CAL_HIST_MAX];
31
+	int i, j;
32
+
33
+	for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
34
+		sort[i] = nfCalBuffer[i];
35
+
36
+	for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
37
+		for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
38
+			if (sort[j] > sort[j - 1]) {
39
+				nfval = sort[j];
40
+				sort[j] = sort[j - 1];
41
+				sort[j - 1] = nfval;
42
+			}
43
+		}
44
+	}
45
+	nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
46
+
47
+	return nfval;
48
+}
49
+
50
+static struct ath_nf_limits *ath9k_hw_get_nf_limits(struct ath_hw *ah,
51
+						    struct ath9k_channel *chan)
52
+{
53
+	struct ath_nf_limits *limit;
54
+
55
+	if (!chan || IS_CHAN_2GHZ(chan))
56
+		limit = &ah->nf_2g;
57
+	else
58
+		limit = &ah->nf_5g;
59
+
60
+	return limit;
61
+}
62
+
63
+static s16 ath9k_hw_get_default_nf(struct ath_hw *ah,
64
+				   struct ath9k_channel *chan)
65
+{
66
+	return ath9k_hw_get_nf_limits(ah, chan)->nominal;
67
+}
68
+
69
+
70
+static void ath9k_hw_update_nfcal_hist_buffer(struct ath_hw *ah,
71
+					      struct ath9k_hw_cal_data *cal,
72
+					      int16_t *nfarray)
73
+{
74
+	struct ath_nf_limits *limit;
75
+	struct ath9k_nfcal_hist *h;
76
+	int high_nf_mid = 0;
77
+	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
78
+	int i;
79
+
80
+	h = cal->nfCalHist;
81
+	limit = ath9k_hw_get_nf_limits(ah, ah->curchan);
82
+
83
+	for (i = 0; i < NUM_NF_READINGS; i++) {
84
+		if (!(chainmask & (1 << i)) ||
85
+		    (i >= AR5416_MAX_CHAINS))
86
+			continue;
87
+
88
+		h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
89
+
90
+		if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
91
+			h[i].currIndex = 0;
92
+
93
+		if (h[i].invalidNFcount > 0) {
94
+			h[i].invalidNFcount--;
95
+			h[i].privNF = nfarray[i];
96
+		} else {
97
+			h[i].privNF =
98
+				ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
99
+		}
100
+
101
+		if (!h[i].privNF)
102
+			continue;
103
+
104
+		if (h[i].privNF > limit->max) {
105
+			high_nf_mid = 1;
106
+
107
+			DBG2("ath9k: "
108
+				"NFmid[%d] (%d) > MAX (%d), %s\n",
109
+				i, h[i].privNF, limit->max,
110
+				(cal->nfcal_interference ?
111
+				 "not corrected (due to interference)" :
112
+				 "correcting to MAX"));
113
+
114
+			/*
115
+			 * Normally we limit the average noise floor by the
116
+			 * hardware specific maximum here. However if we have
117
+			 * encountered stuck beacons because of interference,
118
+			 * we bypass this limit here in order to better deal
119
+			 * with our environment.
120
+			 */
121
+			if (!cal->nfcal_interference)
122
+				h[i].privNF = limit->max;
123
+		}
124
+	}
125
+
126
+	/*
127
+	 * If the noise floor seems normal for all chains, assume that
128
+	 * there is no significant interference in the environment anymore.
129
+	 * Re-enable the enforcement of the NF maximum again.
130
+	 */
131
+	if (!high_nf_mid)
132
+		cal->nfcal_interference = 0;
133
+}
134
+
135
+static int ath9k_hw_get_nf_thresh(struct ath_hw *ah,
136
+				   int band,
137
+				   int16_t *nft)
138
+{
139
+	switch (band) {
140
+	case NET80211_BAND_5GHZ:
141
+		*nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_5);
142
+		break;
143
+	case NET80211_BAND_2GHZ:
144
+		*nft = (int8_t)ah->eep_ops->get_eeprom(ah, EEP_NFTHRESH_2);
145
+		break;
146
+	default:
147
+		return 0;
148
+	}
149
+
150
+	return 1;
151
+}
152
+
153
+void ath9k_hw_reset_calibration(struct ath_hw *ah,
154
+				struct ath9k_cal_list *currCal)
155
+{
156
+	int i;
157
+
158
+	ath9k_hw_setup_calibration(ah, currCal);
159
+
160
+	currCal->calState = CAL_RUNNING;
161
+
162
+	for (i = 0; i < AR5416_MAX_CHAINS; i++) {
163
+		ah->meas0.sign[i] = 0;
164
+		ah->meas1.sign[i] = 0;
165
+		ah->meas2.sign[i] = 0;
166
+		ah->meas3.sign[i] = 0;
167
+	}
168
+
169
+	ah->cal_samples = 0;
170
+}
171
+
172
+/* This is done for the currently configured channel */
173
+int ath9k_hw_reset_calvalid(struct ath_hw *ah)
174
+{
175
+	struct ath9k_cal_list *currCal = ah->cal_list_curr;
176
+
177
+	if (!ah->caldata)
178
+		return 1;
179
+
180
+	if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
181
+		return 1;
182
+
183
+	if (currCal == NULL)
184
+		return 1;
185
+
186
+	if (currCal->calState != CAL_DONE) {
187
+		DBG("ath9k: "
188
+			"Calibration state incorrect, %d\n",
189
+			currCal->calState);
190
+		return 1;
191
+	}
192
+
193
+	if (!(ah->supp_cals & currCal->calData->calType))
194
+		return 1;
195
+
196
+	DBG("ath9k: "
197
+		"Resetting Cal %d state for channel %d\n",
198
+		currCal->calData->calType, (ah->dev->channels + ah->dev->channel)->center_freq);
199
+
200
+	ah->caldata->CalValid &= ~currCal->calData->calType;
201
+	currCal->calState = CAL_WAITING;
202
+
203
+	return 0;
204
+}
205
+
206
+void ath9k_hw_start_nfcal(struct ath_hw *ah, int update)
207
+{
208
+	if (ah->caldata)
209
+		ah->caldata->nfcal_pending = 1;
210
+
211
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
212
+		    AR_PHY_AGC_CONTROL_ENABLE_NF);
213
+
214
+	if (update)
215
+		REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
216
+		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
217
+	else
218
+		REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
219
+		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
220
+
221
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
222
+}
223
+
224
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
225
+{
226
+	struct ath9k_nfcal_hist *h = NULL;
227
+	unsigned i, j;
228
+	int32_t val;
229
+	u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
230
+	s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
231
+
232
+	if (ah->caldata)
233
+		h = ah->caldata->nfCalHist;
234
+
235
+	for (i = 0; i < NUM_NF_READINGS; i++) {
236
+		if (chainmask & (1 << i)) {
237
+			s16 nfval;
238
+
239
+			if (i >= AR5416_MAX_CHAINS)
240
+				continue;
241
+
242
+			if (h)
243
+				nfval = h[i].privNF;
244
+			else
245
+				nfval = default_nf;
246
+
247
+			val = REG_READ(ah, ah->nf_regs[i]);
248
+			val &= 0xFFFFFE00;
249
+			val |= (((u32) nfval << 1) & 0x1ff);
250
+			REG_WRITE(ah, ah->nf_regs[i], val);
251
+		}
252
+	}
253
+
254
+	/*
255
+	 * Load software filtered NF value into baseband internal minCCApwr
256
+	 * variable.
257
+	 */
258
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
259
+		    AR_PHY_AGC_CONTROL_ENABLE_NF);
260
+	REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
261
+		    AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
262
+	REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
263
+
264
+	/*
265
+	 * Wait for load to complete, should be fast, a few 10s of us.
266
+	 * The max delay was changed from an original 250us to 10000us
267
+	 * since 250us often results in NF load timeout and causes deaf
268
+	 * condition during stress testing 12/12/2009
269
+	 */
270
+	for (j = 0; j < 10000; j++) {
271
+		if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
272
+		     AR_PHY_AGC_CONTROL_NF) == 0)
273
+			break;
274
+		udelay(10);
275
+	}
276
+
277
+	/*
278
+	 * We timed out waiting for the noisefloor to load, probably due to an
279
+	 * in-progress rx. Simply return here and allow the load plenty of time
280
+	 * to complete before the next calibration interval.  We need to avoid
281
+	 * trying to load -50 (which happens below) while the previous load is
282
+	 * still in progress as this can cause rx deafness. Instead by returning
283
+	 * here, the baseband nf cal will just be capped by our present
284
+	 * noisefloor until the next calibration timer.
285
+	 */
286
+	if (j == 10000) {
287
+		DBG("ath9k: "
288
+			"Timeout while waiting for nf to load: AR_PHY_AGC_CONTROL=0x%x\n",
289
+			REG_READ(ah, AR_PHY_AGC_CONTROL));
290
+		return;
291
+	}
292
+
293
+	/*
294
+	 * Restore maxCCAPower register parameter again so that we're not capped
295
+	 * by the median we just loaded.  This will be initial (and max) value
296
+	 * of next noise floor calibration the baseband does.
297
+	 */
298
+	ENABLE_REGWRITE_BUFFER(ah);
299
+	for (i = 0; i < NUM_NF_READINGS; i++) {
300
+		if (chainmask & (1 << i)) {
301
+			if (i >= AR5416_MAX_CHAINS)
302
+				continue;
303
+
304
+			val = REG_READ(ah, ah->nf_regs[i]);
305
+			val &= 0xFFFFFE00;
306
+			val |= (((u32) (-50) << 1) & 0x1ff);
307
+			REG_WRITE(ah, ah->nf_regs[i], val);
308
+		}
309
+	}
310
+	REGWRITE_BUFFER_FLUSH(ah);
311
+}
312
+
313
+
314
+static void ath9k_hw_nf_sanitize(struct ath_hw *ah, s16 *nf)
315
+{
316
+	struct ath_nf_limits *limit;
317
+	int i;
318
+
319
+	if (IS_CHAN_2GHZ(ah->curchan))
320
+		limit = &ah->nf_2g;
321
+	else
322
+		limit = &ah->nf_5g;
323
+
324
+	for (i = 0; i < NUM_NF_READINGS; i++) {
325
+		if (!nf[i])
326
+			continue;
327
+
328
+		DBG2("ath9k: "
329
+			"NF calibrated [%s] [chain %d] is %d\n",
330
+			(i >= 3 ? "ext" : "ctl"), i % 3, nf[i]);
331
+
332
+		if (nf[i] > ATH9K_NF_TOO_HIGH) {
333
+			DBG("ath9k: "
334
+				"NF[%d] (%d) > MAX (%d), correcting to MAX\n",
335
+				i, nf[i], ATH9K_NF_TOO_HIGH);
336
+			nf[i] = limit->max;
337
+		} else if (nf[i] < limit->min) {
338
+			DBG("ath9k: "
339
+				"NF[%d] (%d) < MIN (%d), correcting to NOM\n",
340
+				i, nf[i], limit->min);
341
+			nf[i] = limit->nominal;
342
+		}
343
+	}
344
+}
345
+
346
+int ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan)
347
+{
348
+	int16_t nf, nfThresh;
349
+	int16_t nfarray[NUM_NF_READINGS] = { 0 };
350
+	struct ath9k_nfcal_hist *h;
351
+	struct net80211_channel *c = chan->chan;
352
+	struct ath9k_hw_cal_data *caldata = ah->caldata;
353
+
354
+	chan->channelFlags &= (~CHANNEL_CW_INT);
355
+	if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
356
+		DBG("ath9k: "
357
+			"NF did not complete in calibration window\n");
358
+		return 0;
359
+	}
360
+
361
+	ath9k_hw_do_getnf(ah, nfarray);
362
+	ath9k_hw_nf_sanitize(ah, nfarray);
363
+	nf = nfarray[0];
364
+	if (ath9k_hw_get_nf_thresh(ah, c->band, &nfThresh)
365
+	    && nf > nfThresh) {
366
+		DBG2("ath9k: "
367
+			"noise floor failed detected; detected %d, threshold %d\n",
368
+			nf, nfThresh);
369
+		chan->channelFlags |= CHANNEL_CW_INT;
370
+	}
371
+
372
+	if (!caldata) {
373
+		chan->noisefloor = nf;
374
+		return 0;
375
+	}
376
+
377
+	h = caldata->nfCalHist;
378
+	caldata->nfcal_pending = 0;
379
+	ath9k_hw_update_nfcal_hist_buffer(ah, caldata, nfarray);
380
+	chan->noisefloor = h[0].privNF;
381
+	return 1;
382
+}
383
+
384
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
385
+				  struct ath9k_channel *chan)
386
+{
387
+	struct ath9k_nfcal_hist *h;
388
+	s16 default_nf;
389
+	int i, j;
390
+
391
+	ah->caldata->channel = chan->channel;
392
+	ah->caldata->channelFlags = chan->channelFlags & ~CHANNEL_CW_INT;
393
+	h = ah->caldata->nfCalHist;
394
+	default_nf = ath9k_hw_get_default_nf(ah, chan);
395
+	for (i = 0; i < NUM_NF_READINGS; i++) {
396
+		h[i].currIndex = 0;
397
+		h[i].privNF = default_nf;
398
+		h[i].invalidNFcount = AR_PHY_CCA_FILTERWINDOW_LENGTH;
399
+		for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
400
+			h[i].nfCalBuffer[j] = default_nf;
401
+		}
402
+	}
403
+}

+ 69
- 0
src/drivers/net/ath/ath9k/ath9k_common.c View File

@@ -0,0 +1,69 @@
1
+/*
2
+ * Copyright (c) 2009-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+/*
21
+ * Module for common driver code between ath9k and ath9k_htc
22
+ */
23
+
24
+#include "common.h"
25
+
26
+/*
27
+ * Update internal channel flags.
28
+ */
29
+void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
30
+			       struct net80211_channel *chan)
31
+{
32
+	ichan->channel = chan->center_freq;
33
+	ichan->chan = chan;
34
+
35
+	if (chan->band == NET80211_BAND_2GHZ) {
36
+		ichan->chanmode = CHANNEL_G;
37
+		ichan->channelFlags = CHANNEL_2GHZ | CHANNEL_OFDM;
38
+	} else {
39
+		ichan->chanmode = CHANNEL_A;
40
+		ichan->channelFlags = CHANNEL_5GHZ | CHANNEL_OFDM;
41
+	}
42
+}
43
+
44
+/*
45
+ * Get the internal channel reference.
46
+ */
47
+struct ath9k_channel *ath9k_cmn_get_curchannel(struct net80211_device *dev,
48
+					       struct ath_hw *ah)
49
+{
50
+	struct net80211_channel *curchan = dev->channels + dev->channel;
51
+	struct ath9k_channel *channel;
52
+	u8 chan_idx;
53
+
54
+	chan_idx = curchan->hw_value;
55
+	channel = &ah->channels[chan_idx];
56
+	ath9k_cmn_update_ichannel(channel, curchan);
57
+
58
+	return channel;
59
+}
60
+
61
+void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
62
+			    u16 new_txpow, u16 *txpower)
63
+{
64
+	if (cur_txpow != new_txpow) {
65
+		ath9k_hw_set_txpowerlimit(ah, new_txpow, 0);
66
+		/* read back in case value is clamped */
67
+		*txpower = ath9k_hw_regulatory(ah)->power_limit;
68
+	}
69
+}

+ 551
- 0
src/drivers/net/ath/ath9k/ath9k_eeprom.c View File

@@ -0,0 +1,551 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/io.h>
21
+
22
+#include "hw.h"
23
+
24
+static inline u16 ath9k_hw_fbin2freq(u8 fbin, int is2GHz)
25
+{
26
+	if (fbin == AR5416_BCHAN_UNUSED)
27
+		return fbin;
28
+
29
+	return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
30
+}
31
+
32
+void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
33
+{
34
+        REG_WRITE(ah, reg, val);
35
+
36
+        if (ah->config.analog_shiftreg)
37
+		udelay(100);
38
+}
39
+
40
+void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
41
+			       u32 shift, u32 val)
42
+{
43
+	u32 regVal;
44
+
45
+	regVal = REG_READ(ah, reg) & ~mask;
46
+	regVal |= (val << shift) & mask;
47
+
48
+	REG_WRITE(ah, reg, regVal);
49
+
50
+	if (ah->config.analog_shiftreg)
51
+		udelay(100);
52
+}
53
+
54
+int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
55
+			     int16_t targetLeft, int16_t targetRight)
56
+{
57
+	int16_t rv;
58
+
59
+	if (srcRight == srcLeft) {
60
+		rv = targetLeft;
61
+	} else {
62
+		rv = (int16_t) (((target - srcLeft) * targetRight +
63
+				 (srcRight - target) * targetLeft) /
64
+				(srcRight - srcLeft));
65
+	}
66
+	return rv;
67
+}
68
+
69
+int ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
70
+				    u16 *indexL, u16 *indexR)
71
+{
72
+	u16 i;
73
+
74
+	if (target <= pList[0]) {
75
+		*indexL = *indexR = 0;
76
+		return 1;
77
+	}
78
+	if (target >= pList[listSize - 1]) {
79
+		*indexL = *indexR = (u16) (listSize - 1);
80
+		return 1;
81
+	}
82
+
83
+	for (i = 0; i < listSize - 1; i++) {
84
+		if (pList[i] == target) {
85
+			*indexL = *indexR = i;
86
+			return 1;
87
+		}
88
+		if (target < pList[i + 1]) {
89
+			*indexL = i;
90
+			*indexR = (u16) (i + 1);
91
+			return 0;
92
+		}
93
+	}
94
+	return 0;
95
+}
96
+
97
+void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
98
+				  int eep_start_loc, int size)
99
+{
100
+	int i = 0, j, addr;
101
+	u32 addrdata[8];
102
+	u32 data[8];
103
+
104
+	for (addr = 0; addr < size; addr++) {
105
+		addrdata[i] = AR5416_EEPROM_OFFSET +
106
+			((addr + eep_start_loc) << AR5416_EEPROM_S);
107
+		i++;
108
+		if (i == 8) {
109
+			REG_READ_MULTI(ah, addrdata, data, i);
110
+
111
+			for (j = 0; j < i; j++) {
112
+				*eep_data = data[j];
113
+				eep_data++;
114
+			}
115
+			i = 0;
116
+		}
117
+	}
118
+
119
+	if (i != 0) {
120
+		REG_READ_MULTI(ah, addrdata, data, i);
121
+
122
+		for (j = 0; j < i; j++) {
123
+			*eep_data = data[j];
124
+			eep_data++;
125
+		}
126
+	}
127
+}
128
+
129
+int ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data)
130
+{
131
+	return common->bus_ops->eeprom_read(common, off, data);
132
+}
133
+
134
+void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
135
+			     u8 *pVpdList, u16 numIntercepts,
136
+			     u8 *pRetVpdList)
137
+{
138
+	u16 i, k;
139
+	u8 currPwr = pwrMin;
140
+	u16 idxL = 0, idxR = 0;
141
+
142
+	for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
143
+		ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
144
+					       numIntercepts, &(idxL),
145
+					       &(idxR));
146
+		if (idxR < 1)
147
+			idxR = 1;
148
+		if (idxL == numIntercepts - 1)
149
+			idxL = (u16) (numIntercepts - 2);
150
+		if (pPwrList[idxL] == pPwrList[idxR])
151
+			k = pVpdList[idxL];
152
+		else
153
+			k = (u16)(((currPwr - pPwrList[idxL]) * pVpdList[idxR] +
154
+				   (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
155
+				  (pPwrList[idxR] - pPwrList[idxL]));
156
+		pRetVpdList[i] = (u8) k;
157
+		currPwr += 2;
158
+	}
159
+}
160
+
161
+void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
162
+				       struct ath9k_channel *chan,
163
+				       struct cal_target_power_leg *powInfo,
164
+				       u16 numChannels,
165
+				       struct cal_target_power_leg *pNewPower,
166
+				       u16 numRates, int isExtTarget)
167
+{
168
+	struct chan_centers centers;
169
+	u16 clo, chi;
170
+	int i;
171
+	int matchIndex = -1, lowIndex = -1;
172
+	u16 freq;
173
+
174
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
175
+	freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
176
+
177
+	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
178
+				       IS_CHAN_2GHZ(chan))) {
179
+		matchIndex = 0;
180
+	} else {
181
+		for (i = 0; (i < numChannels) &&
182
+			     (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
183
+			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
184
+						       IS_CHAN_2GHZ(chan))) {
185
+				matchIndex = i;
186
+				break;
187
+			} else if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
188
+						IS_CHAN_2GHZ(chan)) && i > 0 &&
189
+				   freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
190
+						IS_CHAN_2GHZ(chan))) {
191
+				lowIndex = i - 1;
192
+				break;
193
+			}
194
+		}
195
+		if ((matchIndex == -1) && (lowIndex == -1))
196
+			matchIndex = i - 1;
197
+	}
198
+
199
+	if (matchIndex != -1) {
200
+		*pNewPower = powInfo[matchIndex];
201
+	} else {
202
+		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
203
+					 IS_CHAN_2GHZ(chan));
204
+		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
205
+					 IS_CHAN_2GHZ(chan));
206
+
207
+		for (i = 0; i < numRates; i++) {
208
+			pNewPower->tPow2x[i] =
209
+				(u8)ath9k_hw_interpolate(freq, clo, chi,
210
+						powInfo[lowIndex].tPow2x[i],
211
+						powInfo[lowIndex + 1].tPow2x[i]);
212
+		}
213
+	}
214
+}
215
+
216
+void ath9k_hw_get_target_powers(struct ath_hw *ah,
217
+				struct ath9k_channel *chan,
218
+				struct cal_target_power_ht *powInfo,
219
+				u16 numChannels,
220
+				struct cal_target_power_ht *pNewPower,
221
+				u16 numRates, int isHt40Target)
222
+{
223
+	struct chan_centers centers;
224
+	u16 clo, chi;
225
+	int i;
226
+	int matchIndex = -1, lowIndex = -1;
227
+	u16 freq;
228
+
229
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
230
+	freq = isHt40Target ? centers.synth_center : centers.ctl_center;
231
+
232
+	if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
233
+		matchIndex = 0;
234
+	} else {
235
+		for (i = 0; (i < numChannels) &&
236
+			     (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
237
+			if (freq == ath9k_hw_fbin2freq(powInfo[i].bChannel,
238
+						       IS_CHAN_2GHZ(chan))) {
239
+				matchIndex = i;
240
+				break;
241
+			} else
242
+				if (freq < ath9k_hw_fbin2freq(powInfo[i].bChannel,
243
+						IS_CHAN_2GHZ(chan)) && i > 0 &&
244
+				    freq > ath9k_hw_fbin2freq(powInfo[i - 1].bChannel,
245
+						IS_CHAN_2GHZ(chan))) {
246
+					lowIndex = i - 1;
247
+					break;
248
+				}
249
+		}
250
+		if ((matchIndex == -1) && (lowIndex == -1))
251
+			matchIndex = i - 1;
252
+	}
253
+
254
+	if (matchIndex != -1) {
255
+		*pNewPower = powInfo[matchIndex];
256
+	} else {
257
+		clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
258
+					 IS_CHAN_2GHZ(chan));
259
+		chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
260
+					 IS_CHAN_2GHZ(chan));
261
+
262
+		for (i = 0; i < numRates; i++) {
263
+			pNewPower->tPow2x[i] = (u8)ath9k_hw_interpolate(freq,
264
+						clo, chi,
265
+						powInfo[lowIndex].tPow2x[i],
266
+						powInfo[lowIndex + 1].tPow2x[i]);
267
+		}
268
+	}
269
+}
270
+
271
+u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
272
+				int is2GHz, int num_band_edges)
273
+{
274
+	u16 twiceMaxEdgePower = MAX_RATE_POWER;
275
+	int i;
276
+
277
+	for (i = 0; (i < num_band_edges) &&
278
+		     (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
279
+		if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel, is2GHz)) {
280
+			twiceMaxEdgePower = CTL_EDGE_TPOWER(pRdEdgesPower[i].ctl);
281
+			break;
282
+		} else if ((i > 0) &&
283
+			   (freq < ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
284
+						      is2GHz))) {
285
+			if (ath9k_hw_fbin2freq(pRdEdgesPower[i - 1].bChannel,
286
+					       is2GHz) < freq &&
287
+			    CTL_EDGE_FLAGS(pRdEdgesPower[i - 1].ctl)) {
288
+				twiceMaxEdgePower =
289
+					CTL_EDGE_TPOWER(pRdEdgesPower[i - 1].ctl);
290
+			}
291
+			break;
292
+		}
293
+	}
294
+
295
+	return twiceMaxEdgePower;
296
+}
297
+
298
+void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah)
299
+{
300
+	struct ath_regulatory *regulatory = ath9k_hw_regulatory(ah);
301
+
302
+	switch (ar5416_get_ntxchains(ah->txchainmask)) {
303
+	case 1:
304
+		break;
305
+	case 2:
306
+		regulatory->max_power_level += INCREASE_MAXPOW_BY_TWO_CHAIN;
307
+		break;
308
+	case 3:
309
+		regulatory->max_power_level += INCREASE_MAXPOW_BY_THREE_CHAIN;
310
+		break;
311
+	default:
312
+		DBG2("ath9k: "
313
+			"Invalid chainmask configuration\n");
314
+		break;
315
+	}
316
+}
317
+
318
+void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
319
+				struct ath9k_channel *chan,
320
+				void *pRawDataSet,
321
+				u8 *bChans, u16 availPiers,
322
+				u16 tPdGainOverlap,
323
+				u16 *pPdGainBoundaries, u8 *pPDADCValues,
324
+				u16 numXpdGains)
325
+{
326
+	int i, j, k;
327
+	int16_t ss;
328
+	u16 idxL = 0, idxR = 0, numPiers;
329
+	static u8 vpdTableL[AR5416_NUM_PD_GAINS]
330
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
331
+	static u8 vpdTableR[AR5416_NUM_PD_GAINS]
332
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
333
+	static u8 vpdTableI[AR5416_NUM_PD_GAINS]
334
+		[AR5416_MAX_PWR_RANGE_IN_HALF_DB];
335
+
336
+	u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
337
+	u8 minPwrT4[AR5416_NUM_PD_GAINS];
338
+	u8 maxPwrT4[AR5416_NUM_PD_GAINS];
339
+	int16_t vpdStep;
340
+	int16_t tmpVal;
341
+	u16 sizeCurrVpdTable, maxIndex, tgtIndex;
342
+	int match;
343
+	int16_t minDelta = 0;
344
+	struct chan_centers centers;
345
+	int pdgain_boundary_default;
346
+	struct cal_data_per_freq *data_def = pRawDataSet;
347
+	struct cal_data_per_freq_4k *data_4k = pRawDataSet;
348
+	struct cal_data_per_freq_ar9287 *data_9287 = pRawDataSet;
349
+	int eeprom_4k = AR_SREV_9285(ah) || AR_SREV_9271(ah);
350
+	int intercepts;
351
+
352
+	if (AR_SREV_9287(ah))
353
+		intercepts = AR9287_PD_GAIN_ICEPTS;
354
+	else
355
+		intercepts = AR5416_PD_GAIN_ICEPTS;
356
+
357
+	memset(&minPwrT4, 0, AR5416_NUM_PD_GAINS);
358
+	ath9k_hw_get_channel_centers(ah, chan, &centers);
359
+
360
+	for (numPiers = 0; numPiers < availPiers; numPiers++) {
361
+		if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
362
+			break;
363
+	}
364
+
365
+	match = ath9k_hw_get_lower_upper_index((u8)FREQ2FBIN(centers.synth_center,
366
+							     IS_CHAN_2GHZ(chan)),
367
+					       bChans, numPiers, &idxL, &idxR);
368
+
369
+	if (match) {
370
+		if (AR_SREV_9287(ah)) {
371
+			/* FIXME: array overrun? */
372
+			for (i = 0; i < numXpdGains; i++) {
373
+				minPwrT4[i] = data_9287[idxL].pwrPdg[i][0];
374
+				maxPwrT4[i] = data_9287[idxL].pwrPdg[i][4];
375
+				ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
376
+						data_9287[idxL].pwrPdg[i],
377
+						data_9287[idxL].vpdPdg[i],
378
+						intercepts,
379
+						vpdTableI[i]);
380
+			}
381
+		} else if (eeprom_4k) {
382
+			for (i = 0; i < numXpdGains; i++) {
383
+				minPwrT4[i] = data_4k[idxL].pwrPdg[i][0];
384
+				maxPwrT4[i] = data_4k[idxL].pwrPdg[i][4];
385
+				ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
386
+						data_4k[idxL].pwrPdg[i],
387
+						data_4k[idxL].vpdPdg[i],
388
+						intercepts,
389
+						vpdTableI[i]);
390
+			}
391
+		} else {
392
+			for (i = 0; i < numXpdGains; i++) {
393
+				minPwrT4[i] = data_def[idxL].pwrPdg[i][0];
394
+				maxPwrT4[i] = data_def[idxL].pwrPdg[i][4];
395
+				ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
396
+						data_def[idxL].pwrPdg[i],
397
+						data_def[idxL].vpdPdg[i],
398
+						intercepts,
399
+						vpdTableI[i]);
400
+			}
401
+		}
402
+	} else {
403
+		for (i = 0; i < numXpdGains; i++) {
404
+			if (AR_SREV_9287(ah)) {
405
+				pVpdL = data_9287[idxL].vpdPdg[i];
406
+				pPwrL = data_9287[idxL].pwrPdg[i];
407
+				pVpdR = data_9287[idxR].vpdPdg[i];
408
+				pPwrR = data_9287[idxR].pwrPdg[i];
409
+			} else if (eeprom_4k) {
410
+				pVpdL = data_4k[idxL].vpdPdg[i];
411
+				pPwrL = data_4k[idxL].pwrPdg[i];
412
+				pVpdR = data_4k[idxR].vpdPdg[i];
413
+				pPwrR = data_4k[idxR].pwrPdg[i];
414
+			} else {
415
+				pVpdL = data_def[idxL].vpdPdg[i];
416
+				pPwrL = data_def[idxL].pwrPdg[i];
417
+				pVpdR = data_def[idxR].vpdPdg[i];
418
+				pPwrR = data_def[idxR].pwrPdg[i];
419
+			}
420
+
421
+			minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
422
+
423
+			maxPwrT4[i] =
424
+				min(pPwrL[intercepts - 1],
425
+				    pPwrR[intercepts - 1]);
426
+
427
+
428
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
429
+						pPwrL, pVpdL,
430
+						intercepts,
431
+						vpdTableL[i]);
432
+			ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
433
+						pPwrR, pVpdR,
434
+						intercepts,
435
+						vpdTableR[i]);
436
+
437
+			for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
438
+				vpdTableI[i][j] =
439
+					(u8)(ath9k_hw_interpolate((u16)
440
+					     FREQ2FBIN(centers.
441
+						       synth_center,
442
+						       IS_CHAN_2GHZ
443
+						       (chan)),
444
+					     bChans[idxL], bChans[idxR],
445
+					     vpdTableL[i][j], vpdTableR[i][j]));
446
+			}
447
+		}
448
+	}
449
+
450
+	k = 0;
451
+
452
+	for (i = 0; i < numXpdGains; i++) {
453
+		if (i == (numXpdGains - 1))
454
+			pPdGainBoundaries[i] =
455
+				(u16)(maxPwrT4[i] / 2);
456
+		else
457
+			pPdGainBoundaries[i] =
458
+				(u16)((maxPwrT4[i] + minPwrT4[i + 1]) / 4);
459
+
460
+		pPdGainBoundaries[i] =
461
+			min((u16)MAX_RATE_POWER, pPdGainBoundaries[i]);
462
+
463
+		if ((i == 0) && !AR_SREV_5416_20_OR_LATER(ah)) {
464
+			minDelta = pPdGainBoundaries[0] - 23;
465
+			pPdGainBoundaries[0] = 23;
466
+		} else {
467
+			minDelta = 0;
468
+		}
469
+
470
+		if (i == 0) {
471
+			if (AR_SREV_9280_20_OR_LATER(ah))
472
+				ss = (int16_t)(0 - (minPwrT4[i] / 2));
473
+			else
474
+				ss = 0;
475
+		} else {
476
+			ss = (int16_t)((pPdGainBoundaries[i - 1] -
477
+					(minPwrT4[i] / 2)) -
478
+				       tPdGainOverlap + 1 + minDelta);
479
+		}
480
+		vpdStep = (int16_t)(vpdTableI[i][1] - vpdTableI[i][0]);
481
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
482
+
483
+		while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
484
+			tmpVal = (int16_t)(vpdTableI[i][0] + ss * vpdStep);
485
+			pPDADCValues[k++] = (u8)((tmpVal < 0) ? 0 : tmpVal);
486
+			ss++;
487
+		}
488
+
489
+		sizeCurrVpdTable = (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
490
+		tgtIndex = (u8)(pPdGainBoundaries[i] + tPdGainOverlap -
491
+				(minPwrT4[i] / 2));
492
+		maxIndex = (tgtIndex < sizeCurrVpdTable) ?
493
+			tgtIndex : sizeCurrVpdTable;
494
+
495
+		while ((ss < maxIndex) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
496
+			pPDADCValues[k++] = vpdTableI[i][ss++];
497
+		}
498
+
499
+		vpdStep = (int16_t)(vpdTableI[i][sizeCurrVpdTable - 1] -
500
+				    vpdTableI[i][sizeCurrVpdTable - 2]);
501
+		vpdStep = (int16_t)((vpdStep < 1) ? 1 : vpdStep);
502
+
503
+		if (tgtIndex >= maxIndex) {
504
+			while ((ss <= tgtIndex) &&
505
+			       (k < (AR5416_NUM_PDADC_VALUES - 1))) {
506
+				tmpVal = (int16_t)((vpdTableI[i][sizeCurrVpdTable - 1] +
507
+						    (ss - maxIndex + 1) * vpdStep));
508
+				pPDADCValues[k++] = (u8)((tmpVal > 255) ?
509
+							 255 : tmpVal);
510
+				ss++;
511
+			}
512
+		}
513
+	}
514
+
515
+	if (eeprom_4k)
516
+		pdgain_boundary_default = 58;
517
+	else
518
+		pdgain_boundary_default = pPdGainBoundaries[i - 1];
519
+
520
+	while (i < AR5416_PD_GAINS_IN_MASK) {
521
+		pPdGainBoundaries[i] = pdgain_boundary_default;
522
+		i++;
523
+	}
524
+
525
+	while (k < AR5416_NUM_PDADC_VALUES) {
526
+		pPDADCValues[k] = pPDADCValues[k - 1];
527
+		k++;
528
+	}
529
+}
530
+
531
+int ath9k_hw_eeprom_init(struct ath_hw *ah)
532
+{
533
+	int status;
534
+
535
+	if (AR_SREV_9300_20_OR_LATER(ah))
536
+		ah->eep_ops = &eep_ar9300_ops;
537
+	else if (AR_SREV_9287(ah)) {
538
+		ah->eep_ops = &eep_ar9287_ops;
539
+	} else if (AR_SREV_9285(ah) || AR_SREV_9271(ah)) {
540
+		ah->eep_ops = &eep_4k_ops;
541
+	} else {
542
+		ah->eep_ops = &eep_def_ops;
543
+	}
544
+
545
+	if (!ah->eep_ops->fill_eeprom(ah))
546
+		return -EIO;
547
+
548
+	status = ah->eep_ops->check_eeprom(ah);
549
+
550
+	return status;
551
+}

+ 1078
- 0
src/drivers/net/ath/ath9k/ath9k_eeprom_4k.c
File diff suppressed because it is too large
View File


+ 1019
- 0
src/drivers/net/ath/ath9k/ath9k_eeprom_9287.c
File diff suppressed because it is too large
View File


+ 1351
- 0
src/drivers/net/ath/ath9k/ath9k_eeprom_def.c
File diff suppressed because it is too large
View File


+ 2067
- 0
src/drivers/net/ath/ath9k/ath9k_hw.c
File diff suppressed because it is too large
View File


+ 593
- 0
src/drivers/net/ath/ath9k/ath9k_init.c View File

@@ -0,0 +1,593 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/malloc.h>
21
+#include <ipxe/pci_io.h>
22
+#include <ipxe/pci.h>
23
+
24
+#include "ath9k.h"
25
+
26
+int is_ath9k_unloaded;
27
+/* We use the hw_value as an index into our private channel structure */
28
+
29
+#define CHAN2G(_freq, _idx)  { \
30
+	.band = NET80211_BAND_2GHZ, \
31
+	.center_freq = (_freq), \
32
+	.hw_value = (_idx), \
33
+	.maxpower = 20, \
34
+}
35
+
36
+#define CHAN5G(_freq, _idx) { \
37
+	.band = NET80211_BAND_5GHZ, \
38
+	.center_freq = (_freq), \
39
+	.hw_value = (_idx), \
40
+	.maxpower = 20, \
41
+}
42
+
43
+/* Some 2 GHz radios are actually tunable on 2312-2732
44
+ * on 5 MHz steps, we support the channels which we know
45
+ * we have calibration data for all cards though to make
46
+ * this static */
47
+static const struct net80211_channel ath9k_2ghz_chantable[] = {
48
+	CHAN2G(2412, 0), /* Channel 1 */
49
+	CHAN2G(2417, 1), /* Channel 2 */
50
+	CHAN2G(2422, 2), /* Channel 3 */
51
+	CHAN2G(2427, 3), /* Channel 4 */
52
+	CHAN2G(2432, 4), /* Channel 5 */
53
+	CHAN2G(2437, 5), /* Channel 6 */
54
+	CHAN2G(2442, 6), /* Channel 7 */
55
+	CHAN2G(2447, 7), /* Channel 8 */
56
+	CHAN2G(2452, 8), /* Channel 9 */
57
+	CHAN2G(2457, 9), /* Channel 10 */
58
+	CHAN2G(2462, 10), /* Channel 11 */
59
+	CHAN2G(2467, 11), /* Channel 12 */
60
+	CHAN2G(2472, 12), /* Channel 13 */
61
+	CHAN2G(2484, 13), /* Channel 14 */
62
+};
63
+
64
+/* Some 5 GHz radios are actually tunable on XXXX-YYYY
65
+ * on 5 MHz steps, we support the channels which we know
66
+ * we have calibration data for all cards though to make
67
+ * this static */
68
+static const struct net80211_channel ath9k_5ghz_chantable[] = {
69
+	/* _We_ call this UNII 1 */
70
+	CHAN5G(5180, 14), /* Channel 36 */
71
+	CHAN5G(5200, 15), /* Channel 40 */
72
+	CHAN5G(5220, 16), /* Channel 44 */
73
+	CHAN5G(5240, 17), /* Channel 48 */
74
+	/* _We_ call this UNII 2 */
75
+	CHAN5G(5260, 18), /* Channel 52 */
76
+	CHAN5G(5280, 19), /* Channel 56 */
77
+	CHAN5G(5300, 20), /* Channel 60 */
78
+	CHAN5G(5320, 21), /* Channel 64 */
79
+	/* _We_ call this "Middle band" */
80
+	CHAN5G(5500, 22), /* Channel 100 */
81
+	CHAN5G(5520, 23), /* Channel 104 */
82
+	CHAN5G(5540, 24), /* Channel 108 */
83
+	CHAN5G(5560, 25), /* Channel 112 */
84
+	CHAN5G(5580, 26), /* Channel 116 */
85
+	CHAN5G(5600, 27), /* Channel 120 */
86
+	CHAN5G(5620, 28), /* Channel 124 */
87
+	CHAN5G(5640, 29), /* Channel 128 */
88
+	CHAN5G(5660, 30), /* Channel 132 */
89
+	CHAN5G(5680, 31), /* Channel 136 */
90
+	CHAN5G(5700, 32), /* Channel 140 */
91
+	/* _We_ call this UNII 3 */
92
+	CHAN5G(5745, 33), /* Channel 149 */
93
+	CHAN5G(5765, 34), /* Channel 153 */
94
+	CHAN5G(5785, 35), /* Channel 157 */
95
+	CHAN5G(5805, 36), /* Channel 161 */
96
+	CHAN5G(5825, 37), /* Channel 165 */
97
+};
98
+
99
+/* Atheros hardware rate code addition for short premble */
100
+#define SHPCHECK(__hw_rate, __flags) \
101
+	((__flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE) ? (__hw_rate | 0x04 ) : 0)
102
+
103
+#define RATE(_bitrate, _hw_rate, _flags) {              \
104
+	.bitrate        = (_bitrate),                   \
105
+	.flags          = (_flags),                     \
106
+	.hw_value       = (_hw_rate),                   \
107
+	.hw_value_short = (SHPCHECK(_hw_rate, _flags))  \
108
+}
109
+
110
+static struct ath9k_legacy_rate ath9k_legacy_rates[] = {
111
+	RATE(10, 0x1b, 0),
112
+	RATE(20, 0x1a, IEEE80211_TX_RC_USE_SHORT_PREAMBLE),
113
+	RATE(55, 0x19, IEEE80211_TX_RC_USE_SHORT_PREAMBLE),
114
+	RATE(110, 0x18, IEEE80211_TX_RC_USE_SHORT_PREAMBLE),
115
+	RATE(60, 0x0b, 0),
116
+	RATE(90, 0x0f, 0),
117
+	RATE(120, 0x0a, 0),
118
+	RATE(180, 0x0e, 0),
119
+	RATE(240, 0x09, 0),
120
+	RATE(360, 0x0d, 0),
121
+	RATE(480, 0x08, 0),
122
+	RATE(540, 0x0c, 0),
123
+};
124
+
125
+static void ath9k_deinit_softc(struct ath_softc *sc);
126
+
127
+/*
128
+ * Read and write, they both share the same lock. We do this to serialize
129
+ * reads and writes on Atheros 802.11n PCI devices only. This is required
130
+ * as the FIFO on these devices can only accept sanely 2 requests.
131
+ */
132
+
133
+static void ath9k_iowrite32(void *hw_priv, u32 val, u32 reg_offset)
134
+{
135
+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
136
+	struct ath_common *common = ath9k_hw_common(ah);
137
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
138
+
139
+	writel(val, sc->mem + reg_offset);
140
+}
141
+
142
+static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
143
+{
144
+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
145
+	struct ath_common *common = ath9k_hw_common(ah);
146
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
147
+	u32 val;
148
+
149
+	val = readl(sc->mem + reg_offset);
150
+	return val;
151
+}
152
+
153
+static unsigned int ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
154
+{
155
+	struct ath_hw *ah = (struct ath_hw *) hw_priv;
156
+	struct ath_common *common = ath9k_hw_common(ah);
157
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
158
+	u32 val;
159
+
160
+	val = readl(sc->mem + reg_offset);
161
+	val &= ~clr;
162
+	val |= set;
163
+	writel(val, sc->mem + reg_offset);
164
+
165
+	return val;
166
+}
167
+
168
+/**************************/
169
+/*     Initialization     */
170
+/**************************/
171
+
172
+/*
173
+ *  This function will allocate both the DMA descriptor structure, and the
174
+ *  buffers it contains.  These are used to contain the descriptors used
175
+ *  by the system.
176
+*/
177
+int ath_descdma_setup(struct ath_softc *sc, struct ath_descdma *dd,
178
+		      struct list_head *head, const char *name,
179
+		      int nbuf, int ndesc, int is_tx)
180
+{
181
+#define	DS2PHYS(_dd, _ds)						\
182
+	((_dd)->dd_desc_paddr + ((char *)(_ds) - (char *)(_dd)->dd_desc))
183
+#define ATH_DESC_4KB_BOUND_CHECK(_daddr) ((((_daddr) & 0xFFF) > 0xF9F) ? 1 : 0)
184
+	u8 *ds;
185
+	struct ath_buf *bf;
186
+	int i, bsize, error, desc_len;
187
+
188
+	DBG2("ath9k: %s DMA: %d buffers %d desc/buf\n",
189
+		name, nbuf, ndesc);
190
+
191
+	INIT_LIST_HEAD(head);
192
+
193
+	if (is_tx)
194
+		desc_len = sc->sc_ah->caps.tx_desc_len;
195
+	else
196
+		desc_len = sizeof(struct ath_desc);
197
+
198
+	/* ath_desc must be a multiple of DWORDs */
199
+	if ((desc_len % 4) != 0) {
200
+		DBG("ath9k: ath_desc not DWORD aligned\n");
201
+		error = -ENOMEM;
202
+		goto fail;
203
+	}
204
+
205
+	dd->dd_desc_len = desc_len * nbuf * ndesc;
206
+
207
+	/*
208
+	 * Need additional DMA memory because we can't use
209
+	 * descriptors that cross the 4K page boundary.
210
+	 * However, iPXE only utilizes 16 buffers, which
211
+	 * will never make up more than half of one page,
212
+	 * so we will only ever skip 1 descriptor, if that.
213
+	 */
214
+	if (!(sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_4KB_SPLITTRANS)) {
215
+		u32 ndesc_skipped = 1;
216
+		u32 dma_len;
217
+
218
+		dma_len = ndesc_skipped * desc_len;
219
+		dd->dd_desc_len += dma_len;
220
+	}
221
+
222
+	/* allocate descriptors */
223
+	dd->dd_desc = malloc_dma(dd->dd_desc_len, 16);
224
+	if (dd->dd_desc == NULL) {
225
+		error = -ENOMEM;
226
+		goto fail;
227
+	}
228
+	dd->dd_desc_paddr = virt_to_bus(dd->dd_desc);
229
+	ds = (u8 *) dd->dd_desc;
230
+	DBG2("ath9k: %s DMA map: %p (%d) -> %llx (%d)\n",
231
+		name, ds, (u32) dd->dd_desc_len,
232
+		ito64(dd->dd_desc_paddr), /*XXX*/(u32) dd->dd_desc_len);
233
+
234
+	/* allocate buffers */
235
+	bsize = sizeof(struct ath_buf) * nbuf;
236
+	bf = zalloc(bsize);
237
+	if (bf == NULL) {
238
+		error = -ENOMEM;
239
+		goto fail2;
240
+	}
241
+	dd->dd_bufptr = bf;
242
+
243
+	for (i = 0; i < nbuf; i++, bf++, ds += (desc_len * ndesc)) {
244
+		bf->bf_desc = ds;
245
+		bf->bf_daddr = DS2PHYS(dd, ds);
246
+
247
+		if (!(sc->sc_ah->caps.hw_caps &
248
+		      ATH9K_HW_CAP_4KB_SPLITTRANS)) {
249
+			/*
250
+			 * Skip descriptor addresses which can cause 4KB
251
+			 * boundary crossing (addr + length) with a 32 dword
252
+			 * descriptor fetch.
253
+			 */
254
+			while (ATH_DESC_4KB_BOUND_CHECK(bf->bf_daddr)) {
255
+				ds += (desc_len * ndesc);
256
+				bf->bf_desc = ds;
257
+				bf->bf_daddr = DS2PHYS(dd, ds);
258
+			}
259
+		}
260
+		list_add_tail(&bf->list, head);
261
+	}
262
+	return 0;
263
+fail2:
264
+	free_dma(dd->dd_desc, dd->dd_desc_len);
265
+fail:
266
+	memset(dd, 0, sizeof(*dd));
267
+	return error;
268
+#undef ATH_DESC_4KB_BOUND_CHECK
269
+#undef DS2PHYS
270
+}
271
+
272
+void ath9k_init_crypto(struct ath_softc *sc)
273
+{
274
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
275
+	unsigned int i = 0;
276
+
277
+	/* Get the hardware key cache size. */
278
+	common->keymax = AR_KEYTABLE_SIZE;
279
+
280
+	/*
281
+	 * Reset the key cache since some parts do not
282
+	 * reset the contents on initial power up.
283
+	 */
284
+	for (i = 0; i < common->keymax; i++)
285
+		ath_hw_keyreset(common, (u16) i);
286
+
287
+	/*
288
+	 * Check whether the separate key cache entries
289
+	 * are required to handle both tx+rx MIC keys.
290
+	 * With split mic keys the number of stations is limited
291
+	 * to 27 otherwise 59.
292
+	 */
293
+	if (sc->sc_ah->misc_mode & AR_PCU_MIC_NEW_LOC_ENA)
294
+		common->crypt_caps |= ATH_CRYPT_CAP_MIC_COMBINED;
295
+}
296
+
297
+static int ath9k_init_queues(struct ath_softc *sc)
298
+{
299
+	int i = 0;
300
+
301
+	for (i = 0; i < WME_NUM_AC; i++) {
302
+		sc->tx.txq_map[i] = ath_txq_setup(sc, ATH9K_TX_QUEUE_DATA, i);
303
+		sc->tx.txq_map[i]->mac80211_qnum = i;
304
+	}
305
+	return 0;
306
+}
307
+
308
+static int ath9k_init_channels_rates(struct ath_softc *sc)
309
+{
310
+	unsigned int i;
311
+
312
+	memcpy(&sc->rates, ath9k_legacy_rates, sizeof(ath9k_legacy_rates));
313
+
314
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ) {
315
+		memcpy(&sc->hwinfo->channels[sc->hwinfo->nr_channels], ath9k_2ghz_chantable, sizeof(ath9k_2ghz_chantable));
316
+
317
+		sc->hwinfo->nr_channels += ARRAY_SIZE(ath9k_2ghz_chantable);
318
+
319
+		for (i = 0; i < ARRAY_SIZE(ath9k_legacy_rates); i++)
320
+			sc->hwinfo->rates[NET80211_BAND_2GHZ][i] = ath9k_legacy_rates[i].bitrate;
321
+		sc->hwinfo->nr_rates[NET80211_BAND_2GHZ] = ARRAY_SIZE(ath9k_legacy_rates);
322
+	}
323
+
324
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ) {
325
+		memcpy(&sc->hwinfo->channels[sc->hwinfo->nr_channels], ath9k_5ghz_chantable, sizeof(ath9k_5ghz_chantable));
326
+
327
+		sc->hwinfo->nr_channels += ARRAY_SIZE(ath9k_5ghz_chantable);
328
+
329
+		for (i = 4; i < ARRAY_SIZE(ath9k_legacy_rates); i++)
330
+			sc->hwinfo->rates[NET80211_BAND_5GHZ][i - 4] = ath9k_legacy_rates[i].bitrate;
331
+		sc->hwinfo->nr_rates[NET80211_BAND_5GHZ] = ARRAY_SIZE(ath9k_legacy_rates) - 4;
332
+	}
333
+	return 0;
334
+}
335
+
336
+static void ath9k_init_misc(struct ath_softc *sc)
337
+{
338
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
339
+
340
+	common->ani.timer = 0;
341
+
342
+	sc->config.txpowlimit = ATH_TXPOWER_MAX;
343
+
344
+	common->tx_chainmask = sc->sc_ah->caps.tx_chainmask;
345
+	common->rx_chainmask = sc->sc_ah->caps.rx_chainmask;
346
+
347
+	ath9k_hw_set_diversity(sc->sc_ah, 1);
348
+	sc->rx.defant = ath9k_hw_getdefantenna(sc->sc_ah);
349
+
350
+	memcpy(common->bssidmask, ath_bcast_mac, ETH_ALEN);
351
+}
352
+
353
+static int ath9k_init_softc(u16 devid, struct ath_softc *sc, u16 subsysid,
354
+			    const struct ath_bus_ops *bus_ops)
355
+{
356
+	struct ath_hw *ah = NULL;
357
+	struct ath_common *common;
358
+	int ret = 0, i;
359
+	int csz = 0;
360
+
361
+	ah = zalloc(sizeof(struct ath_hw));
362
+	if (!ah)
363
+		return -ENOMEM;
364
+
365
+	ah->dev = sc->dev;
366
+	ah->hw_version.devid = devid;
367
+	ah->hw_version.subsysid = subsysid;
368
+	ah->reg_ops.read = ath9k_ioread32;
369
+	ah->reg_ops.write = ath9k_iowrite32;
370
+	ah->reg_ops.rmw = ath9k_reg_rmw;
371
+	sc->sc_ah = ah;
372
+
373
+	sc->hwinfo = zalloc(sizeof(*sc->hwinfo));
374
+	if (!sc->hwinfo) {
375
+		DBG("ath9k: cannot allocate 802.11 hardware info structure\n");
376
+		return -ENOMEM;
377
+	}
378
+
379
+	ah->ah_flags |= AH_USE_EEPROM;
380
+	sc->sc_ah->led_pin = -1;
381
+
382
+	common = ath9k_hw_common(ah);
383
+	common->ops = &ah->reg_ops;
384
+	common->bus_ops = bus_ops;
385
+	common->ah = ah;
386
+	common->dev = sc->dev;
387
+	common->priv = sc;
388
+
389
+	sc->intr_tq = ath9k_tasklet;
390
+
391
+	/*
392
+	 * Cache line size is used to size and align various
393
+	 * structures used to communicate with the hardware.
394
+	 */
395
+	ath_read_cachesize(common, &csz);
396
+	common->cachelsz = csz << 2; /* convert to bytes */
397
+
398
+	/* Initializes the hardware for all supported chipsets */
399
+	ret = ath9k_hw_init(ah);
400
+	if (ret)
401
+		goto err_hw;
402
+
403
+	memcpy(sc->hwinfo->hwaddr, common->macaddr, ETH_ALEN);
404
+
405
+	ret = ath9k_init_queues(sc);
406
+	if (ret)
407
+		goto err_queues;
408
+
409
+	ret = ath9k_init_channels_rates(sc);
410
+	if (ret)
411
+		goto err_btcoex;
412
+
413
+	ath9k_init_crypto(sc);
414
+	ath9k_init_misc(sc);
415
+
416
+	return 0;
417
+
418
+err_btcoex:
419
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
420
+		if (ATH_TXQ_SETUP(sc, i))
421
+			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
422
+err_queues:
423
+	ath9k_hw_deinit(ah);
424
+err_hw:
425
+	free(sc->hwinfo);
426
+	sc->hwinfo = NULL;
427
+
428
+	free(ah);
429
+	sc->sc_ah = NULL;
430
+
431
+	return ret;
432
+}
433
+
434
+static void ath9k_init_band_txpower(struct ath_softc *sc, int band)
435
+{
436
+	struct net80211_channel *chan;
437
+	struct ath_hw *ah = sc->sc_ah;
438
+	struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
439
+	int i;
440
+
441
+	for (i = 0; i < sc->hwinfo->nr_channels; i++) {
442
+		chan = &sc->hwinfo->channels[i];
443
+		if(chan->band != band)
444
+			continue;
445
+		ah->curchan = &ah->channels[chan->hw_value];
446
+		ath9k_hw_set_txpowerlimit(ah, MAX_RATE_POWER, 1);
447
+		chan->maxpower = reg->max_power_level / 2;
448
+	}
449
+}
450
+
451
+static void ath9k_init_txpower_limits(struct ath_softc *sc)
452
+{
453
+	struct ath_hw *ah = sc->sc_ah;
454
+	struct ath9k_channel *curchan = ah->curchan;
455
+
456
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
457
+		ath9k_init_band_txpower(sc, NET80211_BAND_2GHZ);
458
+	if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
459
+		ath9k_init_band_txpower(sc, NET80211_BAND_5GHZ);
460
+
461
+	ah->curchan = curchan;
462
+}
463
+
464
+void ath9k_set_hw_capab(struct ath_softc *sc, struct net80211_device *dev __unused)
465
+{
466
+	sc->hwinfo->flags = NET80211_HW_RX_HAS_FCS;
467
+	sc->hwinfo->signal_type = NET80211_SIGNAL_DB;
468
+	sc->hwinfo->signal_max = 40; /* 35dB should give perfect 54Mbps */
469
+	sc->hwinfo->channel_change_time = 5000;
470
+
471
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_2GHZ)
472
+	{
473
+		sc->hwinfo->bands |= NET80211_BAND_BIT_2GHZ;
474
+		sc->hwinfo->modes |= NET80211_MODE_B | NET80211_MODE_G;
475
+	}
476
+	if (sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
477
+	{
478
+		sc->hwinfo->bands |= NET80211_BAND_BIT_5GHZ;
479
+		sc->hwinfo->modes |= NET80211_MODE_A;
480
+	}
481
+}
482
+
483
+int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
484
+		    const struct ath_bus_ops *bus_ops)
485
+{
486
+	struct net80211_device *dev = sc->dev;
487
+	/*struct ath_common *common;
488
+	struct ath_hw *ah;*/
489
+	int error = 0;
490
+	/*struct ath_regulatory *reg;*/
491
+
492
+	/* Bring up device */
493
+	error = ath9k_init_softc(devid, sc, subsysid, bus_ops);
494
+	if (error != 0)
495
+		goto error_init;
496
+
497
+	/*ah = sc->sc_ah;
498
+	common = ath9k_hw_common(ah);*/
499
+	ath9k_set_hw_capab(sc, dev);
500
+	/* TODO Cottsay: reg */
501
+	/* Initialize regulatory */
502
+	/*error = ath_regd_init(&common->regulatory, sc->dev->wiphy,
503
+			      ath9k_reg_notifier);
504
+	if (error)
505
+		goto error_regd;
506
+
507
+	reg = &common->regulatory;*/
508
+
509
+	/* Setup TX DMA */
510
+	error = ath_tx_init(sc, ATH_TXBUF);
511
+	if (error != 0)
512
+		goto error_tx;
513
+
514
+	/* Setup RX DMA */
515
+	error = ath_rx_init(sc, ATH_RXBUF);
516
+	if (error != 0)
517
+		goto error_rx;
518
+
519
+	ath9k_init_txpower_limits(sc);
520
+
521
+	/* Register with mac80211 */
522
+	error = net80211_register(dev, &ath9k_ops, sc->hwinfo);
523
+	if (error)
524
+		goto error_register;
525
+
526
+	/* TODO Cottsay: reg */
527
+	/* Handle world regulatory */
528
+	/*if (!ath_is_world_regd(reg)) {
529
+		error = regulatory_hint(hw->wiphy, reg->alpha2);
530
+		if (error)
531
+			goto error_world;
532
+	}*/
533
+
534
+	sc->hw_pll_work = ath_hw_pll_work;
535
+	sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
536
+
537
+	/* TODO Cottsay: rfkill */
538
+	/*ath_start_rfkill_poll(sc);*/
539
+
540
+	return 0;
541
+
542
+//error_world:
543
+//	net80211_unregister(dev);
544
+error_register:
545
+	ath_rx_cleanup(sc);
546
+error_rx:
547
+	ath_tx_cleanup(sc);
548
+error_tx:
549
+	ath9k_deinit_softc(sc);
550
+error_init:
551
+	return error;
552
+}
553
+
554
+/*****************************/
555
+/*     De-Initialization     */
556
+/*****************************/
557
+
558
+static void ath9k_deinit_softc(struct ath_softc *sc)
559
+{
560
+	int i = 0;
561
+
562
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
563
+		if (ATH_TXQ_SETUP(sc, i))
564
+			ath_tx_cleanupq(sc, &sc->tx.txq[i]);
565
+
566
+	ath9k_hw_deinit(sc->sc_ah);
567
+
568
+	free(sc->hwinfo);
569
+	sc->hwinfo = NULL;
570
+	free(sc->sc_ah);
571
+	sc->sc_ah = NULL;
572
+}
573
+
574
+void ath9k_deinit_device(struct ath_softc *sc)
575
+{
576
+	struct net80211_device *dev = sc->dev;
577
+
578
+	net80211_unregister(dev);
579
+	ath_rx_cleanup(sc);
580
+	ath_tx_cleanup(sc);
581
+	ath9k_deinit_softc(sc);
582
+}
583
+
584
+void ath_descdma_cleanup(struct ath_softc *sc __unused,
585
+			 struct ath_descdma *dd,
586
+			 struct list_head *head)
587
+{
588
+	free_dma(dd->dd_desc, dd->dd_desc_len);
589
+
590
+	INIT_LIST_HEAD(head);
591
+	free(dd->dd_bufptr);
592
+	memset(dd, 0, sizeof(*dd));
593
+}

+ 733
- 0
src/drivers/net/ath/ath9k/ath9k_mac.c View File

@@ -0,0 +1,733 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/io.h>
21
+
22
+#include "hw.h"
23
+#include "hw-ops.h"
24
+
25
+static void ath9k_hw_set_txq_interrupts(struct ath_hw *ah,
26
+					struct ath9k_tx_queue_info *qi __unused)
27
+{
28
+	DBG2("ath9k: "
29
+		"tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
30
+		ah->txok_interrupt_mask, ah->txerr_interrupt_mask,
31
+		ah->txdesc_interrupt_mask, ah->txeol_interrupt_mask,
32
+		ah->txurn_interrupt_mask);
33
+
34
+	ENABLE_REGWRITE_BUFFER(ah);
35
+
36
+	REG_WRITE(ah, AR_IMR_S0,
37
+		  SM(ah->txok_interrupt_mask, AR_IMR_S0_QCU_TXOK)
38
+		  | SM(ah->txdesc_interrupt_mask, AR_IMR_S0_QCU_TXDESC));
39
+	REG_WRITE(ah, AR_IMR_S1,
40
+		  SM(ah->txerr_interrupt_mask, AR_IMR_S1_QCU_TXERR)
41
+		  | SM(ah->txeol_interrupt_mask, AR_IMR_S1_QCU_TXEOL));
42
+
43
+	ah->imrs2_reg &= ~AR_IMR_S2_QCU_TXURN;
44
+	ah->imrs2_reg |= (ah->txurn_interrupt_mask & AR_IMR_S2_QCU_TXURN);
45
+	REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
46
+
47
+	REGWRITE_BUFFER_FLUSH(ah);
48
+}
49
+
50
+void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp)
51
+{
52
+	REG_WRITE(ah, AR_QTXDP(q), txdp);
53
+}
54
+
55
+void ath9k_hw_txstart(struct ath_hw *ah, u32 q)
56
+{
57
+	DBG2("ath9k: "
58
+		"Enable TXE on queue: %d\n", q);
59
+	REG_WRITE(ah, AR_Q_TXE, 1 << q);
60
+}
61
+
62
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q)
63
+{
64
+	u32 npend;
65
+
66
+	npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
67
+	if (npend == 0) {
68
+
69
+		if (REG_READ(ah, AR_Q_TXE) & (1 << q))
70
+			npend = 1;
71
+	}
72
+
73
+	return npend;
74
+}
75
+
76
+/**
77
+ * ath9k_hw_updatetxtriglevel - adjusts the frame trigger level
78
+ *
79
+ * @ah: atheros hardware struct
80
+ * @bIncTrigLevel: whether or not the frame trigger level should be updated
81
+ *
82
+ * The frame trigger level specifies the minimum number of bytes,
83
+ * in units of 64 bytes, that must be DMA'ed into the PCU TX FIFO
84
+ * before the PCU will initiate sending the frame on the air. This can
85
+ * mean we initiate transmit before a full frame is on the PCU TX FIFO.
86
+ * Resets to 0x1 (meaning 64 bytes or a full frame, whichever occurs
87
+ * first)
88
+ *
89
+ * Caution must be taken to ensure to set the frame trigger level based
90
+ * on the DMA request size. For example if the DMA request size is set to
91
+ * 128 bytes the trigger level cannot exceed 6 * 64 = 384. This is because
92
+ * there need to be enough space in the tx FIFO for the requested transfer
93
+ * size. Hence the tx FIFO will stop with 512 - 128 = 384 bytes. If we set
94
+ * the threshold to a value beyond 6, then the transmit will hang.
95
+ *
96
+ * Current dual   stream devices have a PCU TX FIFO size of 8 KB.
97
+ * Current single stream devices have a PCU TX FIFO size of 4 KB, however,
98
+ * there is a hardware issue which forces us to use 2 KB instead so the
99
+ * frame trigger level must not exceed 2 KB for these chipsets.
100
+ */
101
+int ath9k_hw_updatetxtriglevel(struct ath_hw *ah, int bIncTrigLevel)
102
+{
103
+	u32 txcfg, curLevel, newLevel;
104
+
105
+	if (ah->tx_trig_level >= ah->config.max_txtrig_level)
106
+		return 0;
107
+
108
+	ath9k_hw_disable_interrupts(ah);
109
+
110
+	txcfg = REG_READ(ah, AR_TXCFG);
111
+	curLevel = MS(txcfg, AR_FTRIG);
112
+	newLevel = curLevel;
113
+	if (bIncTrigLevel) {
114
+		if (curLevel < ah->config.max_txtrig_level)
115
+			newLevel++;
116
+	} else if (curLevel > MIN_TX_FIFO_THRESHOLD)
117
+		newLevel--;
118
+	if (newLevel != curLevel)
119
+		REG_WRITE(ah, AR_TXCFG,
120
+			  (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
121
+
122
+	ath9k_hw_enable_interrupts(ah);
123
+
124
+	ah->tx_trig_level = newLevel;
125
+
126
+	return newLevel != curLevel;
127
+}
128
+
129
+void ath9k_hw_abort_tx_dma(struct ath_hw *ah)
130
+{
131
+	int i, q;
132
+
133
+	REG_WRITE(ah, AR_Q_TXD, AR_Q_TXD_M);
134
+
135
+	REG_SET_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
136
+	REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
137
+	REG_SET_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
138
+
139
+	for (q = 0; q < AR_NUM_QCU; q++) {
140
+		for (i = 0; i < 1000; i++) {
141
+			if (i)
142
+				udelay(5);
143
+
144
+			if (!ath9k_hw_numtxpending(ah, q))
145
+				break;
146
+		}
147
+	}
148
+
149
+	REG_CLR_BIT(ah, AR_PCU_MISC, AR_PCU_FORCE_QUIET_COLL | AR_PCU_CLEAR_VMF);
150
+	REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
151
+	REG_CLR_BIT(ah, AR_D_GBL_IFS_MISC, AR_D_GBL_IFS_MISC_IGNORE_BACKOFF);
152
+
153
+	REG_WRITE(ah, AR_Q_TXD, 0);
154
+}
155
+
156
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs)
157
+{
158
+	*txqs &= ah->intr_txqs;
159
+	ah->intr_txqs &= ~(*txqs);
160
+}
161
+
162
+int ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
163
+			    const struct ath9k_tx_queue_info *qinfo)
164
+{
165
+	u32 cw;
166
+	struct ath9k_tx_queue_info *qi;
167
+
168
+	qi = &ah->txq[q];
169
+	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
170
+		DBG("ath9k: "
171
+			"Set TXQ properties, inactive queue: %d\n", q);
172
+		return 0;
173
+	}
174
+
175
+	DBG2("ath9k: Set queue properties for: %d\n", q);
176
+
177
+	qi->tqi_ver = qinfo->tqi_ver;
178
+	qi->tqi_subtype = qinfo->tqi_subtype;
179
+	qi->tqi_qflags = qinfo->tqi_qflags;
180
+	qi->tqi_priority = qinfo->tqi_priority;
181
+	if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
182
+		qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
183
+	else
184
+		qi->tqi_aifs = INIT_AIFS;
185
+	if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
186
+		cw = min(qinfo->tqi_cwmin, 1024U);
187
+		qi->tqi_cwmin = 1;
188
+		while (qi->tqi_cwmin < cw)
189
+			qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
190
+	} else
191
+		qi->tqi_cwmin = qinfo->tqi_cwmin;
192
+	if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
193
+		cw = min(qinfo->tqi_cwmax, 1024U);
194
+		qi->tqi_cwmax = 1;
195
+		while (qi->tqi_cwmax < cw)
196
+			qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
197
+	} else
198
+		qi->tqi_cwmax = INIT_CWMAX;
199
+
200
+	if (qinfo->tqi_shretry != 0)
201
+		qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
202
+	else
203
+		qi->tqi_shretry = INIT_SH_RETRY;
204
+	if (qinfo->tqi_lgretry != 0)
205
+		qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
206
+	else
207
+		qi->tqi_lgretry = INIT_LG_RETRY;
208
+	qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
209
+	qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
210
+	qi->tqi_burstTime = qinfo->tqi_burstTime;
211
+	qi->tqi_readyTime = qinfo->tqi_readyTime;
212
+
213
+	return 1;
214
+}
215
+
216
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
217
+			  const struct ath9k_tx_queue_info *qinfo)
218
+{
219
+	struct ath9k_tx_queue_info *qi;
220
+	int q;
221
+
222
+	for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
223
+		if (ah->txq[q].tqi_type ==
224
+		    ATH9K_TX_QUEUE_INACTIVE)
225
+			break;
226
+	if (q == ATH9K_NUM_TX_QUEUES) {
227
+		DBG("No available TX queue\n");
228
+		return -1;
229
+	}
230
+
231
+	DBG2("ath9K: Setup TX queue: %d\n", q);
232
+
233
+	qi = &ah->txq[q];
234
+	if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
235
+		DBG("ath9k: TX queue: %d already active\n", q);
236
+		return -1;
237
+	}
238
+	memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
239
+	qi->tqi_type = type;
240
+	if (qinfo == NULL) {
241
+		qi->tqi_qflags =
242
+			TXQ_FLAG_TXOKINT_ENABLE
243
+			| TXQ_FLAG_TXERRINT_ENABLE
244
+			| TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
245
+		qi->tqi_aifs = INIT_AIFS;
246
+		qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
247
+		qi->tqi_cwmax = INIT_CWMAX;
248
+		qi->tqi_shretry = INIT_SH_RETRY;
249
+		qi->tqi_lgretry = INIT_LG_RETRY;
250
+		qi->tqi_physCompBuf = 0;
251
+	} else {
252
+		qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
253
+		(void) ath9k_hw_set_txq_props(ah, q, qinfo);
254
+	}
255
+
256
+	return q;
257
+}
258
+
259
+int ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q)
260
+{
261
+	struct ath9k_tx_queue_info *qi;
262
+
263
+	qi = &ah->txq[q];
264
+	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
265
+		DBG("ath9k: "
266
+			"Release TXQ, inactive queue: %d\n", q);
267
+		return 0;
268
+	}
269
+
270
+	DBG2("ath9k: Release TX queue: %d\n", q);
271
+
272
+	qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
273
+	ah->txok_interrupt_mask &= ~(1 << q);
274
+	ah->txerr_interrupt_mask &= ~(1 << q);
275
+	ah->txdesc_interrupt_mask &= ~(1 << q);
276
+	ah->txeol_interrupt_mask &= ~(1 << q);
277
+	ah->txurn_interrupt_mask &= ~(1 << q);
278
+	ath9k_hw_set_txq_interrupts(ah, qi);
279
+
280
+	return 1;
281
+}
282
+
283
+int ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q)
284
+{
285
+	struct ath9k_channel *chan = ah->curchan;
286
+	struct ath9k_tx_queue_info *qi;
287
+	u32 cwMin, chanCwMin, value __unused;
288
+
289
+	qi = &ah->txq[q];
290
+	if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
291
+		DBG("ath9k: "
292
+			"Reset TXQ, inactive queue: %d\n", q);
293
+		return 1;
294
+	}
295
+
296
+	DBG2("ath9k: Reset TX queue: %d\n", q);
297
+
298
+	if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
299
+		if (chan && IS_CHAN_B(chan))
300
+			chanCwMin = INIT_CWMIN_11B;
301
+		else
302
+			chanCwMin = INIT_CWMIN;
303
+
304
+		for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
305
+	} else
306
+		cwMin = qi->tqi_cwmin;
307
+
308
+	ENABLE_REGWRITE_BUFFER(ah);
309
+
310
+	REG_WRITE(ah, AR_DLCL_IFS(q),
311
+		  SM(cwMin, AR_D_LCL_IFS_CWMIN) |
312
+		  SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX) |
313
+		  SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
314
+
315
+	REG_WRITE(ah, AR_DRETRY_LIMIT(q),
316
+		  SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH) |
317
+		  SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG) |
318
+		  SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH));
319
+
320
+	REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
321
+
322
+	if (AR_SREV_9340(ah))
323
+		REG_WRITE(ah, AR_DMISC(q),
324
+			  AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x1);
325
+	else
326
+		REG_WRITE(ah, AR_DMISC(q),
327
+			  AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
328
+
329
+	if (qi->tqi_cbrPeriod) {
330
+		REG_WRITE(ah, AR_QCBRCFG(q),
331
+			  SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL) |
332
+			  SM(qi->tqi_cbrOverflowLimit, AR_Q_CBRCFG_OVF_THRESH));
333
+		REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_FSP_CBR |
334
+			    (qi->tqi_cbrOverflowLimit ?
335
+			     AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN : 0));
336
+	}
337
+	if (qi->tqi_readyTime) {
338
+		REG_WRITE(ah, AR_QRDYTIMECFG(q),
339
+			  SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
340
+			  AR_Q_RDYTIMECFG_EN);
341
+	}
342
+
343
+	REG_WRITE(ah, AR_DCHNTIME(q),
344
+		  SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
345
+		  (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
346
+
347
+	if (qi->tqi_burstTime
348
+	    && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE))
349
+		REG_SET_BIT(ah, AR_QMISC(q), AR_Q_MISC_RDYTIME_EXP_POLICY);
350
+
351
+	if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE)
352
+		REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_POST_FR_BKOFF_DIS);
353
+
354
+	REGWRITE_BUFFER_FLUSH(ah);
355
+
356
+	if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE)
357
+		REG_SET_BIT(ah, AR_DMISC(q), AR_D_MISC_FRAG_BKOFF_EN);
358
+
359
+	if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
360
+		REG_SET_BIT(ah, AR_DMISC(q),
361
+			    SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
362
+			       AR_D_MISC_ARB_LOCKOUT_CNTRL) |
363
+			    AR_D_MISC_POST_FR_BKOFF_DIS);
364
+	}
365
+
366
+	if (AR_SREV_9300_20_OR_LATER(ah))
367
+		REG_WRITE(ah, AR_Q_DESC_CRCCHK, AR_Q_DESC_CRCCHK_EN);
368
+
369
+	if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
370
+		ah->txok_interrupt_mask |= 1 << q;
371
+	else
372
+		ah->txok_interrupt_mask &= ~(1 << q);
373
+	if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
374
+		ah->txerr_interrupt_mask |= 1 << q;
375
+	else
376
+		ah->txerr_interrupt_mask &= ~(1 << q);
377
+	if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
378
+		ah->txdesc_interrupt_mask |= 1 << q;
379
+	else
380
+		ah->txdesc_interrupt_mask &= ~(1 << q);
381
+	if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
382
+		ah->txeol_interrupt_mask |= 1 << q;
383
+	else
384
+		ah->txeol_interrupt_mask &= ~(1 << q);
385
+	if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
386
+		ah->txurn_interrupt_mask |= 1 << q;
387
+	else
388
+		ah->txurn_interrupt_mask &= ~(1 << q);
389
+	ath9k_hw_set_txq_interrupts(ah, qi);
390
+
391
+	return 1;
392
+}
393
+
394
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
395
+			struct ath_rx_status *rs, u64 tsf __unused)
396
+{
397
+	struct ar5416_desc ads;
398
+	struct ar5416_desc *adsp = AR5416DESC(ds);
399
+	u32 phyerr;
400
+
401
+	if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
402
+		return -EINPROGRESS;
403
+
404
+	ads.u.rx = adsp->u.rx;
405
+
406
+	rs->rs_status = 0;
407
+	rs->rs_flags = 0;
408
+
409
+	rs->rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
410
+	rs->rs_tstamp = ads.AR_RcvTimestamp;
411
+
412
+	if (ads.ds_rxstatus8 & AR_PostDelimCRCErr) {
413
+		rs->rs_rssi = ATH9K_RSSI_BAD;
414
+		rs->rs_rssi_ctl0 = ATH9K_RSSI_BAD;
415
+		rs->rs_rssi_ctl1 = ATH9K_RSSI_BAD;
416
+		rs->rs_rssi_ctl2 = ATH9K_RSSI_BAD;
417
+		rs->rs_rssi_ext0 = ATH9K_RSSI_BAD;
418
+		rs->rs_rssi_ext1 = ATH9K_RSSI_BAD;
419
+		rs->rs_rssi_ext2 = ATH9K_RSSI_BAD;
420
+	} else {
421
+		rs->rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
422
+		rs->rs_rssi_ctl0 = MS(ads.ds_rxstatus0,
423
+						AR_RxRSSIAnt00);
424
+		rs->rs_rssi_ctl1 = MS(ads.ds_rxstatus0,
425
+						AR_RxRSSIAnt01);
426
+		rs->rs_rssi_ctl2 = MS(ads.ds_rxstatus0,
427
+						AR_RxRSSIAnt02);
428
+		rs->rs_rssi_ext0 = MS(ads.ds_rxstatus4,
429
+						AR_RxRSSIAnt10);
430
+		rs->rs_rssi_ext1 = MS(ads.ds_rxstatus4,
431
+						AR_RxRSSIAnt11);
432
+		rs->rs_rssi_ext2 = MS(ads.ds_rxstatus4,
433
+						AR_RxRSSIAnt12);
434
+	}
435
+	if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
436
+		rs->rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
437
+	else
438
+		rs->rs_keyix = ATH9K_RXKEYIX_INVALID;
439
+
440
+	rs->rs_rate = RXSTATUS_RATE(ah, (&ads));
441
+	rs->rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
442
+
443
+	rs->rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
444
+	rs->rs_moreaggr =
445
+		(ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
446
+	rs->rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
447
+	rs->rs_flags =
448
+		(ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
449
+	rs->rs_flags |=
450
+		(ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
451
+
452
+	if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
453
+		rs->rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
454
+	if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
455
+		rs->rs_flags |= ATH9K_RX_DELIM_CRC_POST;
456
+	if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
457
+		rs->rs_flags |= ATH9K_RX_DECRYPT_BUSY;
458
+
459
+	if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
460
+		/*
461
+		 * Treat these errors as mutually exclusive to avoid spurious
462
+		 * extra error reports from the hardware. If a CRC error is
463
+		 * reported, then decryption and MIC errors are irrelevant,
464
+		 * the frame is going to be dropped either way
465
+		 */
466
+		if (ads.ds_rxstatus8 & AR_CRCErr)
467
+			rs->rs_status |= ATH9K_RXERR_CRC;
468
+		else if (ads.ds_rxstatus8 & AR_PHYErr) {
469
+			rs->rs_status |= ATH9K_RXERR_PHY;
470
+			phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
471
+			rs->rs_phyerr = phyerr;
472
+		} else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
473
+			rs->rs_status |= ATH9K_RXERR_DECRYPT;
474
+		else if (ads.ds_rxstatus8 & AR_MichaelErr)
475
+			rs->rs_status |= ATH9K_RXERR_MIC;
476
+		else if (ads.ds_rxstatus8 & AR_KeyMiss)
477
+			rs->rs_status |= ATH9K_RXERR_DECRYPT;
478
+	}
479
+
480
+	return 0;
481
+}
482
+
483
+/*
484
+ * This can stop or re-enables RX.
485
+ *
486
+ * If bool is set this will kill any frame which is currently being
487
+ * transferred between the MAC and baseband and also prevent any new
488
+ * frames from getting started.
489
+ */
490
+int ath9k_hw_setrxabort(struct ath_hw *ah, int set)
491
+{
492
+	u32 reg;
493
+
494
+	if (set) {
495
+		REG_SET_BIT(ah, AR_DIAG_SW,
496
+			    (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
497
+
498
+		if (!ath9k_hw_wait(ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE,
499
+				   0, AH_WAIT_TIMEOUT)) {
500
+			REG_CLR_BIT(ah, AR_DIAG_SW,
501
+				    (AR_DIAG_RX_DIS |
502
+				     AR_DIAG_RX_ABORT));
503
+
504
+			reg = REG_READ(ah, AR_OBS_BUS_1);
505
+			DBG("ath9k: "
506
+				"RX failed to go idle in 10 ms RXSM=0x%x\n",
507
+				reg);
508
+
509
+			return 0;
510
+		}
511
+	} else {
512
+		REG_CLR_BIT(ah, AR_DIAG_SW,
513
+			    (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
514
+	}
515
+
516
+	return 1;
517
+}
518
+
519
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp)
520
+{
521
+	REG_WRITE(ah, AR_RXDP, rxdp);
522
+}
523
+
524
+void ath9k_hw_startpcureceive(struct ath_hw *ah, int is_scanning)
525
+{
526
+	ath9k_ani_reset(ah, is_scanning);
527
+
528
+	REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
529
+}
530
+
531
+void ath9k_hw_abortpcurecv(struct ath_hw *ah)
532
+{
533
+	REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
534
+}
535
+
536
+int ath9k_hw_stopdmarecv(struct ath_hw *ah, int *reset)
537
+{
538
+#define AH_RX_STOP_DMA_TIMEOUT 10000   /* usec */
539
+	u32 mac_status, last_mac_status = 0;
540
+	int i;
541
+
542
+	/* Enable access to the DMA observation bus */
543
+	REG_WRITE(ah, AR_MACMISC,
544
+		  ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
545
+		   (AR_MACMISC_MISC_OBS_BUS_1 <<
546
+		    AR_MACMISC_MISC_OBS_BUS_MSB_S)));
547
+
548
+	REG_WRITE(ah, AR_CR, AR_CR_RXD);
549
+
550
+	/* Wait for rx enable bit to go low */
551
+	for (i = AH_RX_STOP_DMA_TIMEOUT / AH_TIME_QUANTUM; i != 0; i--) {
552
+		if ((REG_READ(ah, AR_CR) & AR_CR_RXE) == 0)
553
+			break;
554
+
555
+		if (!AR_SREV_9300_20_OR_LATER(ah)) {
556
+			mac_status = REG_READ(ah, AR_DMADBG_7) & 0x7f0;
557
+			if (mac_status == 0x1c0 && mac_status == last_mac_status) {
558
+				*reset = 1;
559
+				break;
560
+			}
561
+
562
+			last_mac_status = mac_status;
563
+		}
564
+
565
+		udelay(AH_TIME_QUANTUM);
566
+	}
567
+
568
+	if (i == 0) {
569
+		DBG("ath9k: "
570
+			"DMA failed to stop in %d ms AR_CR=0x%08x AR_DIAG_SW=0x%08x DMADBG_7=0x%08x\n",
571
+			AH_RX_STOP_DMA_TIMEOUT / 1000,
572
+			REG_READ(ah, AR_CR),
573
+			REG_READ(ah, AR_DIAG_SW),
574
+			REG_READ(ah, AR_DMADBG_7));
575
+		return 0;
576
+	} else {
577
+		return 1;
578
+	}
579
+
580
+#undef AH_RX_STOP_DMA_TIMEOUT
581
+}
582
+
583
+int ath9k_hw_intrpend(struct ath_hw *ah)
584
+{
585
+	u32 host_isr;
586
+
587
+	if (AR_SREV_9100(ah) || !(ah->ah_ier & AR_IER_ENABLE))
588
+		return 1;
589
+
590
+	host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
591
+	if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
592
+		return 1;
593
+
594
+	host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
595
+	if ((host_isr & AR_INTR_SYNC_DEFAULT)
596
+	    && (host_isr != AR_INTR_SPURIOUS))
597
+		return 1;
598
+
599
+	return 0;
600
+}
601
+
602
+void ath9k_hw_disable_interrupts(struct ath_hw *ah)
603
+{
604
+	DBG2("ath9k: disable IER\n");
605
+	REG_WRITE(ah, AR_IER, ah->ah_ier);
606
+	(void) REG_READ(ah, AR_IER);
607
+	if (!AR_SREV_9100(ah)) {
608
+		REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
609
+		(void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
610
+
611
+		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
612
+		(void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
613
+	}
614
+}
615
+
616
+void ath9k_hw_enable_interrupts(struct ath_hw *ah)
617
+{
618
+	u32 sync_default = AR_INTR_SYNC_DEFAULT;
619
+
620
+	if (!(ah->imask & ATH9K_INT_GLOBAL))
621
+		return;
622
+
623
+	if (AR_SREV_9340(ah))
624
+		sync_default &= ~AR_INTR_SYNC_HOST1_FATAL;
625
+
626
+	DBG2("ath9k: enable IER\n");
627
+	REG_WRITE(ah, AR_IER, ah->ah_ier);
628
+	if (!AR_SREV_9100(ah)) {
629
+		REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
630
+			  AR_INTR_MAC_IRQ);
631
+		REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
632
+
633
+
634
+		REG_WRITE(ah, AR_INTR_SYNC_ENABLE, sync_default);
635
+		REG_WRITE(ah, AR_INTR_SYNC_MASK, sync_default);
636
+	}
637
+	DBG2("ath9k: AR_IMR 0x%x IER 0x%x\n",
638
+		REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
639
+}
640
+
641
+void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints)
642
+{
643
+	enum ath9k_int omask = ah->imask;
644
+	u32 mask, mask2;
645
+	struct ath9k_hw_capabilities *pCap = &ah->caps;
646
+
647
+	if (!(ints & ATH9K_INT_GLOBAL))
648
+		ath9k_hw_disable_interrupts(ah);
649
+
650
+	DBG2("ath9k: 0x%x => 0x%x\n", omask, ints);
651
+
652
+	/* TODO: global int Ref count */
653
+	mask = ints & ATH9K_INT_COMMON;
654
+	mask2 = 0;
655
+
656
+	if (ints & ATH9K_INT_TX) {
657
+		if (ah->config.tx_intr_mitigation)
658
+			mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
659
+		else {
660
+			if (ah->txok_interrupt_mask)
661
+				mask |= AR_IMR_TXOK;
662
+			if (ah->txdesc_interrupt_mask)
663
+				mask |= AR_IMR_TXDESC;
664
+		}
665
+		if (ah->txerr_interrupt_mask)
666
+			mask |= AR_IMR_TXERR;
667
+		if (ah->txeol_interrupt_mask)
668
+			mask |= AR_IMR_TXEOL;
669
+	}
670
+	if (ints & ATH9K_INT_RX) {
671
+		if (AR_SREV_9300_20_OR_LATER(ah)) {
672
+			mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
673
+			if (ah->config.rx_intr_mitigation) {
674
+				mask &= ~AR_IMR_RXOK_LP;
675
+				mask |=  AR_IMR_RXMINTR | AR_IMR_RXINTM;
676
+			} else {
677
+				mask |= AR_IMR_RXOK_LP;
678
+			}
679
+		} else {
680
+			if (ah->config.rx_intr_mitigation)
681
+				mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
682
+			else
683
+				mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
684
+		}
685
+		if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
686
+			mask |= AR_IMR_GENTMR;
687
+	}
688
+
689
+	if (ints & ATH9K_INT_GENTIMER)
690
+		mask |= AR_IMR_GENTMR;
691
+
692
+	if (ints & (ATH9K_INT_BMISC)) {
693
+		mask |= AR_IMR_BCNMISC;
694
+		if (ints & ATH9K_INT_TIM)
695
+			mask2 |= AR_IMR_S2_TIM;
696
+		if (ints & ATH9K_INT_DTIM)
697
+			mask2 |= AR_IMR_S2_DTIM;
698
+		if (ints & ATH9K_INT_DTIMSYNC)
699
+			mask2 |= AR_IMR_S2_DTIMSYNC;
700
+		if (ints & ATH9K_INT_CABEND)
701
+			mask2 |= AR_IMR_S2_CABEND;
702
+		if (ints & ATH9K_INT_TSFOOR)
703
+			mask2 |= AR_IMR_S2_TSFOOR;
704
+	}
705
+
706
+	if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
707
+		mask |= AR_IMR_BCNMISC;
708
+		if (ints & ATH9K_INT_GTT)
709
+			mask2 |= AR_IMR_S2_GTT;
710
+		if (ints & ATH9K_INT_CST)
711
+			mask2 |= AR_IMR_S2_CST;
712
+	}
713
+
714
+	DBG2("ath9k: new IMR 0x%x\n", mask);
715
+	REG_WRITE(ah, AR_IMR, mask);
716
+	ah->imrs2_reg &= ~(AR_IMR_S2_TIM | AR_IMR_S2_DTIM | AR_IMR_S2_DTIMSYNC |
717
+			   AR_IMR_S2_CABEND | AR_IMR_S2_CABTO |
718
+			   AR_IMR_S2_TSFOOR | AR_IMR_S2_GTT | AR_IMR_S2_CST);
719
+	ah->imrs2_reg |= mask2;
720
+	REG_WRITE(ah, AR_IMR_S2, ah->imrs2_reg);
721
+
722
+	if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
723
+		if (ints & ATH9K_INT_TIM_TIMER)
724
+			REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
725
+		else
726
+			REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
727
+	}
728
+
729
+	if (ints & ATH9K_INT_GLOBAL)
730
+		ath9k_hw_enable_interrupts(ah);
731
+
732
+	return;
733
+}

+ 916
- 0
src/drivers/net/ath/ath9k/ath9k_main.c View File

@@ -0,0 +1,916 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/io.h>
21
+
22
+#include "ath9k.h"
23
+
24
+static void ath9k_bss_info_changed(struct net80211_device *dev, u32 changed);
25
+
26
+int ath9k_setpower(struct ath_softc *sc, enum ath9k_power_mode mode)
27
+{
28
+	int ret;
29
+
30
+	ret = ath9k_hw_setpower(sc->sc_ah, mode);
31
+
32
+	return ret;
33
+}
34
+
35
+static void ath_start_ani(struct ath_common *common)
36
+{
37
+	struct ath_hw *ah = common->ah;
38
+	unsigned long timestamp = ( currticks() * 1000 ) / TICKS_PER_SEC;
39
+	struct ath_softc *sc = (struct ath_softc *) common->priv;
40
+
41
+	if (!(sc->sc_flags & SC_OP_ANI_RUN))
42
+		return;
43
+
44
+	if (sc->sc_flags & SC_OP_OFFCHANNEL)
45
+		return;
46
+
47
+	common->ani.longcal_timer = timestamp;
48
+	common->ani.shortcal_timer = timestamp;
49
+	common->ani.checkani_timer = timestamp;
50
+
51
+	common->ani.timer = timestamp + ah->config.ani_poll_interval;
52
+}
53
+
54
+static void ath_update_survey_nf(struct ath_softc *sc, int channel)
55
+{
56
+	struct ath_hw *ah = sc->sc_ah;
57
+	struct ath9k_channel *chan = &ah->channels[channel];
58
+	struct survey_info *survey = &sc->survey[channel];
59
+
60
+	if (chan->noisefloor) {
61
+		survey->filled |= SURVEY_INFO_NOISE_DBM;
62
+		survey->noise = chan->noisefloor;
63
+	}
64
+}
65
+
66
+/*
67
+ * Updates the survey statistics and returns the busy time since last
68
+ * update in %, if the measurement duration was long enough for the
69
+ * result to be useful, -1 otherwise.
70
+ */
71
+static int ath_update_survey_stats(struct ath_softc *sc)
72
+{
73
+	struct ath_hw *ah = sc->sc_ah;
74
+	struct ath_common *common = ath9k_hw_common(ah);
75
+	int pos = ah->curchan - &ah->channels[0];
76
+	struct survey_info *survey = &sc->survey[pos];
77
+	struct ath_cycle_counters *cc = &common->cc_survey;
78
+	unsigned int div = common->clockrate * 1000;
79
+	int ret = 0;
80
+
81
+	if (!ah->curchan)
82
+		return -1;
83
+
84
+	if (ah->power_mode == ATH9K_PM_AWAKE)
85
+		ath_hw_cycle_counters_update(common);
86
+
87
+	if (cc->cycles > 0) {
88
+		survey->filled |= SURVEY_INFO_CHANNEL_TIME |
89
+			SURVEY_INFO_CHANNEL_TIME_BUSY |
90
+			SURVEY_INFO_CHANNEL_TIME_RX |
91
+			SURVEY_INFO_CHANNEL_TIME_TX;
92
+		survey->channel_time += cc->cycles / div;
93
+		survey->channel_time_busy += cc->rx_busy / div;
94
+		survey->channel_time_rx += cc->rx_frame / div;
95
+		survey->channel_time_tx += cc->tx_frame / div;
96
+	}
97
+
98
+	if (cc->cycles < div)
99
+		return -1;
100
+
101
+	if (cc->cycles > 0)
102
+		ret = cc->rx_busy * 100 / cc->cycles;
103
+
104
+	memset(cc, 0, sizeof(*cc));
105
+
106
+	ath_update_survey_nf(sc, pos);
107
+
108
+	return ret;
109
+}
110
+
111
+/*
112
+ * Set/change channels.  If the channel is really being changed, it's done
113
+ * by reseting the chip.  To accomplish this we must first cleanup any pending
114
+ * DMA, then restart stuff.
115
+*/
116
+int ath_set_channel(struct ath_softc *sc, struct net80211_device *dev,
117
+		    struct ath9k_channel *hchan)
118
+{
119
+	struct ath_hw *ah = sc->sc_ah;
120
+	struct ath_common *common = ath9k_hw_common(ah);
121
+	int fastcc __unused = 1, stopped __unused;
122
+	struct net80211_channel *channel = dev->channels + dev->channel;
123
+	struct ath9k_hw_cal_data *caldata = NULL;
124
+	int r;
125
+
126
+	if (sc->sc_flags & SC_OP_INVALID)
127
+		return -EIO;
128
+
129
+	sc->hw_busy_count = 0;
130
+
131
+	common->ani.timer = 0;
132
+	sc->tx_complete_work_timer = 0;
133
+	sc->hw_pll_work_timer = 0;
134
+
135
+	/*
136
+	 * This is only performed if the channel settings have
137
+	 * actually changed.
138
+	 *
139
+	 * To switch channels clear any pending DMA operations;
140
+	 * wait long enough for the RX fifo to drain, reset the
141
+	 * hardware at the new frequency, and then re-enable
142
+	 * the relevant bits of the h/w.
143
+	 */
144
+	ath9k_hw_disable_interrupts(ah);
145
+	stopped = ath_drain_all_txq(sc, 0);
146
+
147
+	if (!ath_stoprecv(sc))
148
+		stopped = 0;
149
+
150
+	if (!ath9k_hw_check_alive(ah))
151
+		stopped = 0;
152
+
153
+	/* XXX: do not flush receive queue here. We don't want
154
+	 * to flush data frames already in queue because of
155
+	 * changing channel. */
156
+
157
+	if (!(sc->sc_flags & SC_OP_OFFCHANNEL))
158
+		caldata = &sc->caldata;
159
+
160
+	DBG2("ath9k: "
161
+		"(%d MHz) -> (%d MHz)\n",
162
+		sc->sc_ah->curchan->channel,
163
+		channel->center_freq);
164
+
165
+	r = ath9k_hw_reset(ah, hchan, caldata, fastcc);
166
+	if (r) {
167
+		DBG("ath9k: "
168
+			"Unable to reset channel (%d MHz), reset status %d\n",
169
+			channel->center_freq, r);
170
+		goto ps_restore;
171
+	}
172
+
173
+	if (ath_startrecv(sc) != 0) {
174
+		DBG("ath9k: Unable to restart recv logic\n");
175
+		r = -EIO;
176
+		goto ps_restore;
177
+	}
178
+
179
+	ath9k_cmn_update_txpow(ah, sc->curtxpow,
180
+			       sc->config.txpowlimit, &sc->curtxpow);
181
+	ath9k_hw_set_interrupts(ah, ah->imask);
182
+
183
+	if (!(sc->sc_flags & (SC_OP_OFFCHANNEL))) {
184
+		sc->tx_complete_work(sc);
185
+		sc->hw_pll_work_timer = (currticks() * 1000 ) / TICKS_PER_SEC + 500;
186
+		ath_start_ani(common);
187
+	}
188
+
189
+ ps_restore:
190
+	return r;
191
+}
192
+
193
+/*
194
+ *  This routine performs the periodic noise floor calibration function
195
+ *  that is used to adjust and optimize the chip performance.  This
196
+ *  takes environmental changes (location, temperature) into account.
197
+ *  When the task is complete, it reschedules itself depending on the
198
+ *  appropriate interval that was calculated.
199
+ */
200
+void ath_ani_calibrate(struct ath_softc *sc)
201
+{
202
+	struct ath_hw *ah = sc->sc_ah;
203
+	struct ath_common *common = ath9k_hw_common(ah);
204
+	int longcal = 0;
205
+	int shortcal = 0;
206
+	int aniflag = 0;
207
+	unsigned int timestamp = (currticks() * 1000 ) / TICKS_PER_SEC;
208
+	u32 cal_interval, short_cal_interval, long_cal_interval;
209
+
210
+	if (ah->caldata && ah->caldata->nfcal_interference)
211
+		long_cal_interval = ATH_LONG_CALINTERVAL_INT;
212
+	else
213
+		long_cal_interval = ATH_LONG_CALINTERVAL;
214
+
215
+	short_cal_interval = ATH_STA_SHORT_CALINTERVAL;
216
+
217
+	/* Only calibrate if awake */
218
+	if (sc->sc_ah->power_mode != ATH9K_PM_AWAKE)
219
+		goto set_timer;
220
+
221
+	/* Long calibration runs independently of short calibration. */
222
+	if ((timestamp - common->ani.longcal_timer) >= long_cal_interval) {
223
+		longcal = 1;
224
+		DBG2("ath9k: longcal @%d\n", timestamp);
225
+		common->ani.longcal_timer = timestamp;
226
+	}
227
+
228
+	/* Short calibration applies only while caldone is false */
229
+	if (!common->ani.caldone) {
230
+		if ((timestamp - common->ani.shortcal_timer) >= short_cal_interval) {
231
+			shortcal = 1;
232
+			DBG2("ath9k: "
233
+				"shortcal @%d\n", timestamp);
234
+			common->ani.shortcal_timer = timestamp;
235
+			common->ani.resetcal_timer = timestamp;
236
+		}
237
+	} else {
238
+		if ((timestamp - common->ani.resetcal_timer) >=
239
+		    ATH_RESTART_CALINTERVAL) {
240
+			common->ani.caldone = ath9k_hw_reset_calvalid(ah);
241
+			if (common->ani.caldone)
242
+				common->ani.resetcal_timer = timestamp;
243
+		}
244
+	}
245
+
246
+	/* Verify whether we must check ANI */
247
+	if ((timestamp - common->ani.checkani_timer) >=
248
+	     ah->config.ani_poll_interval) {
249
+		aniflag = 1;
250
+		common->ani.checkani_timer = timestamp;
251
+	}
252
+
253
+	/* Skip all processing if there's nothing to do. */
254
+	if (longcal || shortcal || aniflag) {
255
+		/* Call ANI routine if necessary */
256
+		if (aniflag) {
257
+			ath9k_hw_ani_monitor(ah, ah->curchan);
258
+			ath_update_survey_stats(sc);
259
+		}
260
+
261
+		/* Perform calibration if necessary */
262
+		if (longcal || shortcal) {
263
+			common->ani.caldone =
264
+				ath9k_hw_calibrate(ah,
265
+						   ah->curchan,
266
+						   common->rx_chainmask,
267
+						   longcal);
268
+		}
269
+	}
270
+
271
+set_timer:
272
+	/*
273
+	* Set timer interval based on previous results.
274
+	* The interval must be the shortest necessary to satisfy ANI,
275
+	* short calibration and long calibration.
276
+	*/
277
+	cal_interval = ATH_LONG_CALINTERVAL;
278
+	if (sc->sc_ah->config.enable_ani)
279
+		cal_interval = min(cal_interval,
280
+				   (u32)ah->config.ani_poll_interval);
281
+	if (!common->ani.caldone)
282
+		cal_interval = min(cal_interval, (u32)short_cal_interval);
283
+
284
+	common->ani.timer = timestamp + cal_interval;
285
+}
286
+
287
+void ath_hw_check(struct ath_softc *sc)
288
+{
289
+	int busy;
290
+
291
+	if (ath9k_hw_check_alive(sc->sc_ah))
292
+		goto out;
293
+
294
+	busy = ath_update_survey_stats(sc);
295
+
296
+	DBG("ath9k: Possible baseband hang, "
297
+		"busy=%d (try %d)\n", busy, sc->hw_busy_count + 1);
298
+	if (busy >= 99) {
299
+		if (++sc->hw_busy_count >= 3)
300
+			ath_reset(sc, 1);
301
+	} else if (busy >= 0)
302
+		sc->hw_busy_count = 0;
303
+
304
+out:
305
+	return;
306
+}
307
+
308
+static void ath_hw_pll_rx_hang_check(struct ath_softc *sc, u32 pll_sqsum)
309
+{
310
+	static int count;
311
+
312
+	if (pll_sqsum >= 0x40000) {
313
+		count++;
314
+		if (count == 3) {
315
+			/* Rx is hung for more than 500ms. Reset it */
316
+			DBG("ath9k: "
317
+				"Possible RX hang, resetting");
318
+			ath_reset(sc, 1);
319
+			count = 0;
320
+		}
321
+	} else
322
+		count = 0;
323
+}
324
+
325
+void ath_hw_pll_work(struct ath_softc *sc)
326
+{
327
+	u32 pll_sqsum;
328
+
329
+	if (AR_SREV_9485(sc->sc_ah)) {
330
+		pll_sqsum = ar9003_get_pll_sqsum_dvc(sc->sc_ah);
331
+
332
+		ath_hw_pll_rx_hang_check(sc, pll_sqsum);
333
+
334
+		sc->hw_pll_work_timer = (currticks() * 1000 ) / TICKS_PER_SEC + 200;
335
+	}
336
+}
337
+
338
+
339
+void ath9k_tasklet(struct ath_softc *sc)
340
+{
341
+	struct ath_hw *ah = sc->sc_ah;
342
+
343
+	u32 status = sc->intrstatus;
344
+	u32 rxmask;
345
+
346
+	if ((status & ATH9K_INT_FATAL) ||
347
+	    (status & ATH9K_INT_BB_WATCHDOG)) {
348
+		ath_reset(sc, 1);
349
+		return;
350
+	}
351
+
352
+	rxmask = (ATH9K_INT_RX | ATH9K_INT_RXEOL | ATH9K_INT_RXORN);
353
+
354
+	if (status & rxmask) {
355
+		ath_rx_tasklet(sc, 0, 0);
356
+	}
357
+
358
+	if (status & ATH9K_INT_TX) {
359
+		ath_tx_tasklet(sc);
360
+	}
361
+
362
+	/* re-enable hardware interrupt */
363
+	ath9k_hw_enable_interrupts(ah);
364
+}
365
+
366
+void ath_isr(struct net80211_device *dev)
367
+{
368
+#define SCHED_INTR (				\
369
+		ATH9K_INT_FATAL |		\
370
+		ATH9K_INT_BB_WATCHDOG |		\
371
+		ATH9K_INT_RXORN |		\
372
+		ATH9K_INT_RXEOL |		\
373
+		ATH9K_INT_RX |			\
374
+		ATH9K_INT_RXLP |		\
375
+		ATH9K_INT_RXHP |		\
376
+		ATH9K_INT_TX |			\
377
+		ATH9K_INT_BMISS |		\
378
+		ATH9K_INT_CST |			\
379
+		ATH9K_INT_TSFOOR |		\
380
+		ATH9K_INT_GENTIMER)
381
+
382
+	struct ath_softc *sc = dev->priv;
383
+	struct ath_hw *ah = sc->sc_ah;
384
+	struct ath_common *common = ath9k_hw_common(ah);
385
+	enum ath9k_int status;
386
+	unsigned long timestamp = (currticks() * 1000 ) / TICKS_PER_SEC;
387
+	int sched = 0;
388
+
389
+	/*
390
+	 * The hardware is not ready/present, don't
391
+	 * touch anything. Note this can happen early
392
+	 * on if the IRQ is shared.
393
+	 */
394
+	if (sc->sc_flags & SC_OP_INVALID)
395
+		return;
396
+
397
+
398
+	/* Check calibration */
399
+	if(timestamp >= (unsigned int)common->ani.timer && common->ani.timer)
400
+		ath_ani_calibrate(sc);
401
+
402
+	/* Check tx_complete_work */
403
+	if(timestamp >= (unsigned int)sc->tx_complete_work_timer && sc->tx_complete_work_timer)
404
+		sc->tx_complete_work(sc);
405
+
406
+	/* Check hw_pll_work */
407
+	if(timestamp >= (unsigned int)sc->hw_pll_work_timer && sc->hw_pll_work_timer)
408
+		sc->hw_pll_work(sc);
409
+
410
+	/* shared irq, not for us */
411
+
412
+	if (!ath9k_hw_intrpend(ah))
413
+		return;
414
+
415
+	/*
416
+	 * Figure out the reason(s) for the interrupt.  Note
417
+	 * that the hal returns a pseudo-ISR that may include
418
+	 * bits we haven't explicitly enabled so we mask the
419
+	 * value to insure we only process bits we requested.
420
+	 */
421
+	ath9k_hw_getisr(ah, &status);	/* NB: clears ISR too */
422
+	status &= ah->imask;	/* discard unasked-for bits */
423
+
424
+	/*
425
+	 * If there are no status bits set, then this interrupt was not
426
+	 * for me (should have been caught above).
427
+	 */
428
+	if (!status)
429
+		return;
430
+
431
+	/* Cache the status */
432
+	sc->intrstatus = status;
433
+
434
+	if (status & SCHED_INTR)
435
+		sched = 1;
436
+
437
+	/*
438
+	 * If a FATAL or RXORN interrupt is received, we have to reset the
439
+	 * chip immediately.
440
+	 */
441
+	if ((status & ATH9K_INT_FATAL) || (status & ATH9K_INT_RXORN))
442
+		goto chip_reset;
443
+
444
+	if (status & ATH9K_INT_TXURN)
445
+		ath9k_hw_updatetxtriglevel(ah, 1);
446
+
447
+	if (!(ah->caps.hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
448
+		if (status & ATH9K_INT_TIM_TIMER) {
449
+			if (sc->ps_idle)
450
+				goto chip_reset;
451
+			/* Clear RxAbort bit so that we can
452
+			 * receive frames */
453
+			ath9k_setpower(sc, ATH9K_PM_AWAKE);
454
+			ath9k_hw_setrxabort(sc->sc_ah, 0);
455
+			sc->ps_flags |= PS_WAIT_FOR_BEACON;
456
+		}
457
+
458
+chip_reset:
459
+
460
+	if (sched) {
461
+		/* turn off every interrupt */
462
+		ath9k_hw_disable_interrupts(ah);
463
+		sc->intr_tq(sc);
464
+	}
465
+
466
+	return;
467
+
468
+#undef SCHED_INTR
469
+}
470
+
471
+void ath_radio_disable(struct ath_softc *sc, struct net80211_device *dev)
472
+{
473
+	struct ath_hw *ah = sc->sc_ah;
474
+	struct net80211_channel *channel = dev->channels + dev->channel;
475
+	int r;
476
+
477
+	sc->hw_pll_work_timer = 0;
478
+
479
+	/*
480
+	 * Keep the LED on when the radio is disabled
481
+	 * during idle unassociated state.
482
+	 */
483
+	if (!sc->ps_idle) {
484
+		ath9k_hw_set_gpio(ah, ah->led_pin, 1);
485
+		ath9k_hw_cfg_gpio_input(ah, ah->led_pin);
486
+	}
487
+
488
+	/* Disable interrupts */
489
+	ath9k_hw_disable_interrupts(ah);
490
+
491
+	ath_drain_all_txq(sc, 0);	/* clear pending tx frames */
492
+
493
+	ath_stoprecv(sc);		/* turn off frame recv */
494
+	ath_flushrecv(sc);		/* flush recv queue */
495
+
496
+	if (!ah->curchan)
497
+		ah->curchan = ath9k_cmn_get_curchannel(dev, ah);
498
+
499
+	r = ath9k_hw_reset(ah, ah->curchan, ah->caldata, 0);
500
+	if (r) {
501
+		DBG("ath9k: "
502
+			"Unable to reset channel (%d MHz), reset status %d\n",
503
+			channel->center_freq, r);
504
+	}
505
+
506
+	ath9k_hw_phy_disable(ah);
507
+
508
+	ath9k_hw_configpcipowersave(ah, 1, 1);
509
+}
510
+
511
+int ath_reset(struct ath_softc *sc, int retry_tx)
512
+{
513
+	struct ath_hw *ah = sc->sc_ah;
514
+	struct ath_common *common = ath9k_hw_common(ah);
515
+	int r;
516
+
517
+	sc->hw_busy_count = 0;
518
+
519
+	/* Stop ANI */
520
+	common->ani.timer = 0;
521
+
522
+	ath9k_hw_disable_interrupts(ah);
523
+	ath_drain_all_txq(sc, retry_tx);
524
+
525
+	ath_stoprecv(sc);
526
+	ath_flushrecv(sc);
527
+
528
+	r = ath9k_hw_reset(ah, sc->sc_ah->curchan, ah->caldata, 0);
529
+	if (r)
530
+		DBG("ath9k: "
531
+			"Unable to reset hardware; reset status %d\n", r);
532
+
533
+	if (ath_startrecv(sc) != 0)
534
+		DBG("ath9k: Unable to start recv logic\n");
535
+
536
+	/*
537
+	 * We may be doing a reset in response to a request
538
+	 * that changes the channel so update any state that
539
+	 * might change as a result.
540
+	 */
541
+	ath9k_cmn_update_txpow(ah, sc->curtxpow,
542
+			       sc->config.txpowlimit, &sc->curtxpow);
543
+
544
+	ath9k_hw_set_interrupts(ah, ah->imask);
545
+
546
+	if (retry_tx) {
547
+		int i;
548
+		for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
549
+			if (ATH_TXQ_SETUP(sc, i)) {
550
+				ath_txq_schedule(sc, &sc->tx.txq[i]);
551
+			}
552
+		}
553
+	}
554
+
555
+	/* Start ANI */
556
+	ath_start_ani(common);
557
+
558
+	return r;
559
+}
560
+
561
+/**********************/
562
+/* mac80211 callbacks */
563
+/**********************/
564
+
565
+static int ath9k_start(struct net80211_device *dev)
566
+{
567
+	struct ath_softc *sc = dev->priv;
568
+	struct ath_hw *ah = sc->sc_ah;
569
+	struct ath_common *common = ath9k_hw_common(ah);
570
+	struct net80211_channel *curchan = dev->channels + dev->channel;
571
+	struct ath9k_channel *init_channel;
572
+	int r;
573
+
574
+	DBG("ath9k: "
575
+		"Starting driver with initial channel: %d MHz\n",
576
+		curchan->center_freq);
577
+
578
+	/* setup initial channel */
579
+	sc->chan_idx = curchan->hw_value;
580
+
581
+	init_channel = ath9k_cmn_get_curchannel(dev, ah);
582
+
583
+	/* Reset SERDES registers */
584
+	ath9k_hw_configpcipowersave(ah, 0, 0);
585
+
586
+	/*
587
+	 * The basic interface to setting the hardware in a good
588
+	 * state is ``reset''.  On return the hardware is known to
589
+	 * be powered up and with interrupts disabled.  This must
590
+	 * be followed by initialization of the appropriate bits
591
+	 * and then setup of the interrupt mask.
592
+	 */
593
+	r = ath9k_hw_reset(ah, init_channel, ah->caldata, 0);
594
+	if (r) {
595
+		DBG("ath9k: "
596
+			"Unable to reset hardware; reset status %d (freq %d MHz)\n",
597
+			r, curchan->center_freq);
598
+		goto mutex_unlock;
599
+	}
600
+
601
+	/*
602
+	 * This is needed only to setup initial state
603
+	 * but it's best done after a reset.
604
+	 */
605
+	ath9k_cmn_update_txpow(ah, sc->curtxpow,
606
+			sc->config.txpowlimit, &sc->curtxpow);
607
+
608
+	/*
609
+	 * Setup the hardware after reset:
610
+	 * The receive engine is set going.
611
+	 * Frame transmit is handled entirely
612
+	 * in the frame output path; there's nothing to do
613
+	 * here except setup the interrupt mask.
614
+	 */
615
+	if (ath_startrecv(sc) != 0) {
616
+		DBG("ath9k: Unable to start recv logic\n");
617
+		r = -EIO;
618
+		goto mutex_unlock;
619
+	}
620
+
621
+	/* Setup our intr mask. */
622
+	ah->imask = ATH9K_INT_TX | ATH9K_INT_RXEOL |
623
+		    ATH9K_INT_RXORN | ATH9K_INT_FATAL |
624
+		    ATH9K_INT_GLOBAL;
625
+
626
+	ah->imask |= ATH9K_INT_RX;
627
+
628
+	sc->sc_flags &= ~SC_OP_INVALID;
629
+	sc->sc_ah->is_monitoring = 0;
630
+
631
+	ath9k_hw_set_interrupts(ah, ah->imask);
632
+
633
+	sc->tx_complete_work(sc);
634
+
635
+	if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
636
+		common->bus_ops->extn_synch_en(common);
637
+
638
+mutex_unlock:
639
+	return r;
640
+}
641
+
642
+static int ath9k_tx(struct net80211_device *dev, struct io_buffer *iob)
643
+{
644
+	struct ath_softc *sc = dev->priv;
645
+	struct ath_tx_control txctl;
646
+	int ret = 0;
647
+
648
+	memset(&txctl, 0, sizeof(struct ath_tx_control));
649
+	txctl.txq = sc->tx.txq_map[0];
650
+
651
+	DBGIO("ath9k: transmitting packet, iob: %p\n", iob);
652
+
653
+	ret = ath_tx_start(dev, iob, &txctl);
654
+	if (ret) {
655
+		DBG("ath9k: TX failed\n");
656
+		goto exit;
657
+	}
658
+
659
+	return ret;
660
+exit:
661
+	free_iob(iob);
662
+	return ret;
663
+}
664
+
665
+static void ath9k_stop(struct net80211_device *dev)
666
+{
667
+	struct ath_softc *sc = dev->priv;
668
+	struct ath_hw *ah = sc->sc_ah;
669
+
670
+	sc->tx_complete_work_timer = 0;
671
+	sc->hw_pll_work_timer = 0;
672
+
673
+	if (sc->sc_flags & SC_OP_INVALID) {
674
+		DBG("ath9k: Device not present\n");
675
+		return;
676
+	}
677
+
678
+	/* prevent tasklets to enable interrupts once we disable them */
679
+	ah->imask &= ~ATH9K_INT_GLOBAL;
680
+
681
+	/* make sure h/w will not generate any interrupt
682
+	 * before setting the invalid flag. */
683
+	ath9k_hw_disable_interrupts(ah);
684
+
685
+	if (!(sc->sc_flags & SC_OP_INVALID)) {
686
+		ath_drain_all_txq(sc, 0);
687
+		ath_stoprecv(sc);
688
+		ath9k_hw_phy_disable(ah);
689
+	} else
690
+		sc->rx.rxlink = NULL;
691
+
692
+	if (sc->rx.frag) {
693
+		free_iob(sc->rx.frag);
694
+		sc->rx.frag = NULL;
695
+	}
696
+
697
+	/* disable HAL and put h/w to sleep */
698
+	ath9k_hw_disable(ah);
699
+	ath9k_hw_configpcipowersave(ah, 1, 1);
700
+
701
+	ath_radio_disable(sc, dev);
702
+
703
+	sc->sc_flags |= SC_OP_INVALID;
704
+
705
+	DBG("ath9k: Driver halt\n");
706
+}
707
+
708
+static int ath9k_config(struct net80211_device *dev, int changed)
709
+{
710
+	struct ath_softc *sc = dev->priv;
711
+	struct ath_hw *ah = sc->sc_ah;
712
+
713
+	if ((changed & NET80211_CFG_RATE) ||
714
+			(changed & NET80211_CFG_PHY_PARAMS)) {
715
+		int spmbl = (sc->sc_flags & SC_OP_PREAMBLE_SHORT) ? IEEE80211_TX_RC_USE_SHORT_PREAMBLE : 0;
716
+		u16 rate = dev->rates[dev->rate];
717
+		u16 slowrate = dev->rates[dev->rtscts_rate];
718
+		int i;
719
+
720
+		for (i = 0; i < NET80211_MAX_RATES; i++) {
721
+			if (sc->rates[i].bitrate == rate &&
722
+			    (sc->rates[i].flags & spmbl))
723
+				sc->hw_rix = i;
724
+
725
+			if (sc->rates[i].bitrate == slowrate &&
726
+			    (sc->rates[i].flags & spmbl))
727
+				sc->hw_rix = i;
728
+		}
729
+	}
730
+
731
+	ath9k_bss_info_changed(dev, changed);
732
+
733
+	if (changed & NET80211_CFG_CHANNEL) {
734
+		struct net80211_channel *curchan = dev->channels + dev->channel;
735
+		int pos = curchan->hw_value;
736
+		int old_pos = -1;
737
+
738
+		if (ah->curchan)
739
+			old_pos = ah->curchan - &ah->channels[0];
740
+
741
+		sc->sc_flags &= ~SC_OP_OFFCHANNEL;
742
+
743
+		DBG2("ath9k: "
744
+			"Set channel: %d MHz\n",
745
+			curchan->center_freq);
746
+
747
+		ath9k_cmn_update_ichannel(&sc->sc_ah->channels[pos],
748
+					  curchan);
749
+
750
+		/* update survey stats for the old channel before switching */
751
+		ath_update_survey_stats(sc);
752
+
753
+		/*
754
+		 * If the operating channel changes, change the survey in-use flags
755
+		 * along with it.
756
+		 * Reset the survey data for the new channel, unless we're switching
757
+		 * back to the operating channel from an off-channel operation.
758
+		 */
759
+		if (sc->cur_survey != &sc->survey[pos]) {
760
+
761
+			if (sc->cur_survey)
762
+				sc->cur_survey->filled &= ~SURVEY_INFO_IN_USE;
763
+
764
+			sc->cur_survey = &sc->survey[pos];
765
+
766
+			memset(sc->cur_survey, 0, sizeof(struct survey_info));
767
+			sc->cur_survey->filled |= SURVEY_INFO_IN_USE;
768
+		} else if (!(sc->survey[pos].filled & SURVEY_INFO_IN_USE)) {
769
+			memset(&sc->survey[pos], 0, sizeof(struct survey_info));
770
+		}
771
+
772
+		if (ath_set_channel(sc, dev, &sc->sc_ah->channels[pos]) < 0) {
773
+			DBG("ath9k: Unable to set channel\n");
774
+			return -EINVAL;
775
+		}
776
+
777
+		/*
778
+		 * The most recent snapshot of channel->noisefloor for the old
779
+		 * channel is only available after the hardware reset. Copy it to
780
+		 * the survey stats now.
781
+		 */
782
+		if (old_pos >= 0)
783
+			ath_update_survey_nf(sc, old_pos);
784
+	}
785
+
786
+	if (changed & NET80211_CFG_CHANNEL) {
787
+		DBG2("ath9k: "
788
+			"Set power: %d\n", (dev->channels + dev->channel)->maxpower);
789
+		sc->config.txpowlimit = 2 * (dev->channels + dev->channel)->maxpower;
790
+		ath9k_cmn_update_txpow(ah, sc->curtxpow,
791
+				       sc->config.txpowlimit, &sc->curtxpow);
792
+	}
793
+
794
+	return 0;
795
+}
796
+
797
+static void ath9k_bss_iter(struct ath_softc *sc)
798
+{
799
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
800
+
801
+	if (common->dev->state & NET80211_ASSOCIATED) {
802
+		sc->sc_flags |= SC_OP_PRIM_STA_VIF;
803
+		memcpy(common->curbssid, common->dev->bssid, ETH_ALEN);
804
+		common->curaid = common->dev->aid;
805
+		ath9k_hw_write_associd(sc->sc_ah);
806
+		DBG("ath9k: "
807
+			"Bss Info ASSOC %d, bssid: %pM\n",
808
+			common->dev->aid, common->curbssid);
809
+
810
+		/*
811
+		 * Request a re-configuration of Beacon related timers
812
+		 * on the receipt of the first Beacon frame (i.e.,
813
+		 * after time sync with the AP).
814
+		 */
815
+		sc->ps_flags |= PS_BEACON_SYNC | PS_WAIT_FOR_BEACON;
816
+		/* Reset rssi stats */
817
+		sc->last_rssi = ATH_RSSI_DUMMY_MARKER;
818
+		sc->sc_ah->stats.avgbrssi = ATH_RSSI_DUMMY_MARKER;
819
+
820
+		sc->sc_flags |= SC_OP_ANI_RUN;
821
+		ath_start_ani(common);
822
+	}
823
+}
824
+
825
+static void ath9k_config_bss(struct ath_softc *sc)
826
+{
827
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
828
+	struct net80211_device *dev = common->dev;
829
+
830
+	/* Reconfigure bss info */
831
+	if (!(dev->state & NET80211_ASSOCIATED)) {
832
+		DBG2("ath9k: "
833
+			"ath9k: Bss Info DISASSOC %d, bssid %pM\n",
834
+			common->curaid, common->curbssid);
835
+		sc->sc_flags &= ~(SC_OP_PRIM_STA_VIF | SC_OP_BEACONS);
836
+		memset(common->curbssid, 0, ETH_ALEN);
837
+		common->curaid = 0;
838
+	}
839
+
840
+	ath9k_bss_iter(sc);
841
+
842
+	/*
843
+	 * None of station vifs are associated.
844
+	 * Clear bssid & aid
845
+	 */
846
+	if (!(sc->sc_flags & SC_OP_PRIM_STA_VIF)) {
847
+		ath9k_hw_write_associd(sc->sc_ah);
848
+		/* Stop ANI */
849
+		sc->sc_flags &= ~SC_OP_ANI_RUN;
850
+		common->ani.timer = 0;
851
+	}
852
+}
853
+
854
+static void ath9k_bss_info_changed(struct net80211_device *dev,
855
+				   u32 changed)
856
+{
857
+	struct ath_softc *sc = dev->priv;
858
+	struct ath_hw *ah = sc->sc_ah;
859
+	struct ath_common *common = ath9k_hw_common(ah);
860
+	int slottime;
861
+
862
+	if (changed & NET80211_CFG_ASSOC) {
863
+		ath9k_config_bss(sc);
864
+
865
+		DBG2("ath9k: BSSID: %pM aid: 0x%x\n",
866
+			common->curbssid, common->curaid);
867
+	}
868
+
869
+	if (changed & NET80211_CFG_PHY_PARAMS) {
870
+		if (dev->phy_flags & NET80211_PHY_USE_PROTECTION)
871
+			slottime = 9;
872
+		else
873
+			slottime = 20;
874
+		ah->slottime = slottime;
875
+		ath9k_hw_init_global_settings(ah);
876
+
877
+		DBG2("ath9k: BSS Changed PREAMBLE %d\n",
878
+				!!(dev->phy_flags & NET80211_PHY_USE_SHORT_PREAMBLE));
879
+		if (dev->phy_flags & NET80211_PHY_USE_SHORT_PREAMBLE)
880
+			sc->sc_flags |= SC_OP_PREAMBLE_SHORT;
881
+		else
882
+			sc->sc_flags &= ~SC_OP_PREAMBLE_SHORT;
883
+
884
+		DBG2("ath9k: BSS Changed CTS PROT %d\n",
885
+			!!(dev->phy_flags & NET80211_PHY_USE_PROTECTION));
886
+		if ((dev->phy_flags & NET80211_PHY_USE_PROTECTION) &&
887
+		    (dev->channels + dev->channel)->band != NET80211_BAND_5GHZ)
888
+			sc->sc_flags |= SC_OP_PROTECT_ENABLE;
889
+		else
890
+			sc->sc_flags &= ~SC_OP_PROTECT_ENABLE;
891
+	}
892
+}
893
+
894
+static void ath9k_poll(struct net80211_device *dev)
895
+{
896
+	ath_isr(dev);
897
+}
898
+
899
+static void ath9k_irq(struct net80211_device *dev, int enable)
900
+{
901
+	struct ath_softc *sc = dev->priv;
902
+	struct ath_hw *ah = sc->sc_ah;
903
+
904
+	ah->ah_ier = enable ? AR_IER_ENABLE : AR_IER_DISABLE;
905
+
906
+	ath9k_hw_set_interrupts(ah, ah->imask);
907
+}
908
+
909
+struct net80211_device_operations ath9k_ops = {
910
+	.transmit	= ath9k_tx,
911
+	.open		= ath9k_start,
912
+	.close		= ath9k_stop,
913
+	.config		= ath9k_config,
914
+	.poll		= ath9k_poll,
915
+	.irq		= ath9k_irq,
916
+};

+ 521
- 0
src/drivers/net/ath/ath9k/ath9k_recv.c View File

@@ -0,0 +1,521 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/io.h>
21
+
22
+#include "ath9k.h"
23
+#include "ar9003_mac.h"
24
+
25
+/*
26
+ * Setup and link descriptors.
27
+ *
28
+ * 11N: we can no longer afford to self link the last descriptor.
29
+ * MAC acknowledges BA status as long as it copies frames to host
30
+ * buffer (or rx fifo). This can incorrectly acknowledge packets
31
+ * to a sender if last desc is self-linked.
32
+ */
33
+static void ath_rx_buf_link(struct ath_softc *sc, struct ath_buf *bf)
34
+{
35
+	struct ath_hw *ah = sc->sc_ah;
36
+	struct ath_common *common = ath9k_hw_common(ah);
37
+	struct ath_desc *ds;
38
+//	struct io_buffer *iob;
39
+
40
+	ATH_RXBUF_RESET(bf);
41
+
42
+	ds = bf->bf_desc;
43
+	ds->ds_link = 0; /* link to null */
44
+	ds->ds_data = bf->bf_buf_addr;
45
+
46
+//	/* virtual addr of the beginning of the buffer. */
47
+//	iob = bf->bf_mpdu;
48
+//	ds->ds_vdata = iob->data;
49
+
50
+	/*
51
+	 * setup rx descriptors. The rx_bufsize here tells the hardware
52
+	 * how much data it can DMA to us and that we are prepared
53
+	 * to process
54
+	 */
55
+	ath9k_hw_setuprxdesc(ah, ds,
56
+			     common->rx_bufsize,
57
+			     0);
58
+
59
+	if (sc->rx.rxlink == NULL)
60
+		ath9k_hw_putrxbuf(ah, bf->bf_daddr);
61
+	else
62
+		*sc->rx.rxlink = bf->bf_daddr;
63
+
64
+	sc->rx.rxlink = &ds->ds_link;
65
+}
66
+
67
+static void ath_setdefantenna(struct ath_softc *sc, u32 antenna)
68
+{
69
+	/* XXX block beacon interrupts */
70
+	ath9k_hw_setantenna(sc->sc_ah, antenna);
71
+	sc->rx.defant = antenna;
72
+	sc->rx.rxotherant = 0;
73
+}
74
+
75
+static void ath_opmode_init(struct ath_softc *sc)
76
+{
77
+	struct ath_hw *ah = sc->sc_ah;
78
+	struct ath_common *common = ath9k_hw_common(ah);
79
+
80
+	u32 rfilt, mfilt[2];
81
+
82
+	/* configure rx filter */
83
+	rfilt = ath_calcrxfilter(sc);
84
+	ath9k_hw_setrxfilter(ah, rfilt);
85
+
86
+	/* configure bssid mask */
87
+	ath_hw_setbssidmask(common);
88
+
89
+	/* configure operational mode */
90
+	ath9k_hw_setopmode(ah);
91
+
92
+	/* calculate and install multicast filter */
93
+	mfilt[0] = mfilt[1] = ~0;
94
+	ath9k_hw_setmcastfilter(ah, mfilt[0], mfilt[1]);
95
+}
96
+
97
+int ath_rx_init(struct ath_softc *sc, int nbufs)
98
+{
99
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
100
+	struct io_buffer *iob;
101
+	u32 *iob_addr = NULL;
102
+	struct ath_buf *bf;
103
+	int error = 0;
104
+
105
+	sc->sc_flags &= ~SC_OP_RXFLUSH;
106
+
107
+	common->rx_bufsize = IEEE80211_MAX_MPDU_LEN / 2 +
108
+			     sc->sc_ah->caps.rx_status_len;
109
+
110
+	DBG2("ath9k: cachelsz %d rxbufsize %d\n",
111
+		common->cachelsz, common->rx_bufsize);
112
+
113
+	/* Initialize rx descriptors */
114
+
115
+	error = ath_descdma_setup(sc, &sc->rx.rxdma, &sc->rx.rxbuf,
116
+			"rx", nbufs, 1, 0);
117
+	if (error != 0) {
118
+		DBG("ath9k: "
119
+			"failed to allocate rx descriptors: %d\n",
120
+			error);
121
+		goto err;
122
+	}
123
+
124
+	list_for_each_entry(bf, &sc->rx.rxbuf, list) {
125
+		iob = ath_rxbuf_alloc(common, common->rx_bufsize,
126
+				      iob_addr);
127
+		if (iob == NULL) {
128
+			error = -ENOMEM;
129
+			goto err;
130
+		}
131
+
132
+		bf->bf_mpdu = iob;
133
+		bf->bf_buf_addr = *iob_addr;
134
+	}
135
+	sc->rx.rxlink = NULL;
136
+
137
+err:
138
+	if (error)
139
+		ath_rx_cleanup(sc);
140
+
141
+	return error;
142
+}
143
+
144
+void ath_rx_cleanup(struct ath_softc *sc)
145
+{
146
+	struct io_buffer *iob;
147
+	struct ath_buf *bf;
148
+
149
+	list_for_each_entry(bf, &sc->rx.rxbuf, list) {
150
+		iob = bf->bf_mpdu;
151
+		if (iob) {
152
+			free_iob(iob);
153
+			bf->bf_buf_addr = 0;
154
+			bf->bf_mpdu = NULL;
155
+		}
156
+	}
157
+
158
+	if (sc->rx.rxdma.dd_desc_len != 0)
159
+		ath_descdma_cleanup(sc, &sc->rx.rxdma, &sc->rx.rxbuf);
160
+}
161
+
162
+/*
163
+ * Calculate the receive filter according to the
164
+ * operating mode and state:
165
+ *
166
+ * o always accept unicast, broadcast, and multicast traffic
167
+ * o maintain current state of phy error reception (the hal
168
+ *   may enable phy error frames for noise immunity work)
169
+ * o probe request frames are accepted only when operating in
170
+ *   hostap, adhoc, or monitor modes
171
+ * o enable promiscuous mode according to the interface state
172
+ * o accept beacons:
173
+ *   - when operating in adhoc mode so the 802.11 layer creates
174
+ *     node table entries for peers,
175
+ *   - when operating in station mode for collecting rssi data when
176
+ *     the station is otherwise quiet, or
177
+ *   - when operating as a repeater so we see repeater-sta beacons
178
+ *   - when scanning
179
+ */
180
+
181
+u32 ath_calcrxfilter(struct ath_softc *sc)
182
+{
183
+#define	RX_FILTER_PRESERVE (ATH9K_RX_FILTER_PHYERR | ATH9K_RX_FILTER_PHYRADAR)
184
+
185
+	u32 rfilt;
186
+
187
+	rfilt = (ath9k_hw_getrxfilter(sc->sc_ah) & RX_FILTER_PRESERVE)
188
+		| ATH9K_RX_FILTER_UCAST | ATH9K_RX_FILTER_BCAST
189
+		| ATH9K_RX_FILTER_MCAST | ATH9K_RX_FILTER_BEACON;
190
+
191
+	return rfilt;
192
+
193
+#undef RX_FILTER_PRESERVE
194
+}
195
+
196
+int ath_startrecv(struct ath_softc *sc)
197
+{
198
+	struct ath_hw *ah = sc->sc_ah;
199
+	struct ath_buf *bf, *tbf;
200
+
201
+	if (list_empty(&sc->rx.rxbuf))
202
+		goto start_recv;
203
+
204
+	sc->rx.rxlink = NULL;
205
+	list_for_each_entry_safe(bf, tbf, &sc->rx.rxbuf, list) {
206
+		ath_rx_buf_link(sc, bf);
207
+	}
208
+
209
+	/* We could have deleted elements so the list may be empty now */
210
+	if (list_empty(&sc->rx.rxbuf))
211
+		goto start_recv;
212
+
213
+	bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
214
+	ath9k_hw_putrxbuf(ah, bf->bf_daddr);
215
+	ath9k_hw_rxena(ah);
216
+
217
+start_recv:
218
+	ath_opmode_init(sc);
219
+	ath9k_hw_startpcureceive(ah, (sc->sc_flags & SC_OP_OFFCHANNEL));
220
+
221
+	return 0;
222
+}
223
+
224
+int ath_stoprecv(struct ath_softc *sc)
225
+{
226
+	struct ath_hw *ah = sc->sc_ah;
227
+	int stopped, reset = 0;
228
+
229
+	ath9k_hw_abortpcurecv(ah);
230
+	ath9k_hw_setrxfilter(ah, 0);
231
+	stopped = ath9k_hw_stopdmarecv(ah, &reset);
232
+
233
+	sc->rx.rxlink = NULL;
234
+
235
+	if (!(ah->ah_flags & AH_UNPLUGGED) &&
236
+	    !stopped) {
237
+		DBG("ath9k: "
238
+			"Could not stop RX, we could be "
239
+			"confusing the DMA engine when we start RX up\n");
240
+	}
241
+	return stopped && !reset;
242
+}
243
+
244
+void ath_flushrecv(struct ath_softc *sc)
245
+{
246
+	sc->sc_flags |= SC_OP_RXFLUSH;
247
+	ath_rx_tasklet(sc, 1, 0);
248
+	sc->sc_flags &= ~SC_OP_RXFLUSH;
249
+}
250
+
251
+static struct ath_buf *ath_get_next_rx_buf(struct ath_softc *sc,
252
+					   struct ath_rx_status *rs)
253
+{
254
+	struct ath_hw *ah = sc->sc_ah;
255
+	struct ath_desc *ds;
256
+	struct ath_buf *bf;
257
+	int ret;
258
+
259
+	if (list_empty(&sc->rx.rxbuf)) {
260
+		sc->rx.rxlink = NULL;
261
+		return NULL;
262
+	}
263
+
264
+	bf = list_first_entry(&sc->rx.rxbuf, struct ath_buf, list);
265
+	ds = bf->bf_desc;
266
+
267
+	/*
268
+	 * Must provide the virtual address of the current
269
+	 * descriptor, the physical address, and the virtual
270
+	 * address of the next descriptor in the h/w chain.
271
+	 * This allows the HAL to look ahead to see if the
272
+	 * hardware is done with a descriptor by checking the
273
+	 * done bit in the following descriptor and the address
274
+	 * of the current descriptor the DMA engine is working
275
+	 * on.  All this is necessary because of our use of
276
+	 * a self-linked list to avoid rx overruns.
277
+	 */
278
+	ret = ath9k_hw_rxprocdesc(ah, ds, rs, 0);
279
+	if (ret == -EINPROGRESS) {
280
+		struct ath_rx_status trs;
281
+		struct ath_buf *tbf;
282
+		struct ath_desc *tds;
283
+
284
+		memset(&trs, 0, sizeof(trs));
285
+		if ((&bf->list)->next == &sc->rx.rxbuf) {
286
+			sc->rx.rxlink = NULL;
287
+			return NULL;
288
+		}
289
+
290
+		tbf = list_entry(bf->list.next, struct ath_buf, list);
291
+
292
+		/*
293
+		 * On some hardware the descriptor status words could
294
+		 * get corrupted, including the done bit. Because of
295
+		 * this, check if the next descriptor's done bit is
296
+		 * set or not.
297
+		 *
298
+		 * If the next descriptor's done bit is set, the current
299
+		 * descriptor has been corrupted. Force s/w to discard
300
+		 * this descriptor and continue...
301
+		 */
302
+
303
+		tds = tbf->bf_desc;
304
+		ret = ath9k_hw_rxprocdesc(ah, tds, &trs, 0);
305
+		if (ret == -EINPROGRESS)
306
+			return NULL;
307
+	}
308
+
309
+	if (!bf->bf_mpdu)
310
+		return bf;
311
+
312
+	return bf;
313
+}
314
+
315
+/* Assumes you've already done the endian to CPU conversion */
316
+static int ath9k_rx_accept(struct ath_common *common,
317
+			    struct ath_rx_status *rx_stats,
318
+			    int *decrypt_error)
319
+{
320
+	struct ath_hw *ah = common->ah;
321
+	u8 rx_status_len = ah->caps.rx_status_len;
322
+
323
+
324
+	if (!rx_stats->rs_datalen)
325
+		return 0;
326
+        /*
327
+         * rs_status follows rs_datalen so if rs_datalen is too large
328
+         * we can take a hint that hardware corrupted it, so ignore
329
+         * those frames.
330
+         */
331
+	if (rx_stats->rs_datalen > (common->rx_bufsize - rx_status_len))
332
+		return 0;
333
+
334
+	/* Only use error bits from the last fragment */
335
+	if (rx_stats->rs_more)
336
+		return 1;
337
+
338
+	/*
339
+	 * The rx_stats->rs_status will not be set until the end of the
340
+	 * chained descriptors so it can be ignored if rs_more is set. The
341
+	 * rs_more will be false at the last element of the chained
342
+	 * descriptors.
343
+	 */
344
+	if (rx_stats->rs_status != 0) {
345
+		if (rx_stats->rs_status & ATH9K_RXERR_PHY)
346
+			return 0;
347
+
348
+		if (rx_stats->rs_status & ATH9K_RXERR_DECRYPT) {
349
+			*decrypt_error = 1;
350
+		}
351
+		/*
352
+		 * Reject error frames with the exception of
353
+		 * decryption and MIC failures. For monitor mode,
354
+		 * we also ignore the CRC error.
355
+		 */
356
+		if (ah->is_monitoring) {
357
+			if (rx_stats->rs_status &
358
+			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC |
359
+			      ATH9K_RXERR_CRC))
360
+				return 0;
361
+		} else {
362
+			if (rx_stats->rs_status &
363
+			    ~(ATH9K_RXERR_DECRYPT | ATH9K_RXERR_MIC)) {
364
+				return 0;
365
+			}
366
+		}
367
+	}
368
+	return 1;
369
+}
370
+
371
+static int ath9k_process_rate(struct ath_common *common __unused,
372
+			      struct net80211_device *dev,
373
+			      struct ath_rx_status *rx_stats,
374
+			      int *rix)
375
+{
376
+	struct ath_softc *sc = (struct ath_softc *)dev->priv;
377
+	int band;
378
+	int i = 0;
379
+
380
+	band = (dev->channels + sc->dev->channel)->band;
381
+
382
+	for (i = 0; i < sc->hwinfo->nr_rates[band]; i++) {
383
+		if (sc->rates[i].hw_value == rx_stats->rs_rate) {
384
+			*rix = i;
385
+			return 0;
386
+		}
387
+		if (sc->rates[i].hw_value_short == rx_stats->rs_rate) {
388
+			*rix = i;
389
+			return 0;
390
+		}
391
+	}
392
+
393
+	/*
394
+	 * No valid hardware bitrate found -- we should not get here
395
+	 * because hardware has already validated this frame as OK.
396
+	 */
397
+	DBG("ath9k: "
398
+		"unsupported hw bitrate detected 0x%02x using 1 Mbit\n",
399
+		rx_stats->rs_rate);
400
+
401
+	return -EINVAL;
402
+}
403
+
404
+/*
405
+ * For Decrypt or Demic errors, we only mark packet status here and always push
406
+ * up the frame up to let mac80211 handle the actual error case, be it no
407
+ * decryption key or real decryption error. This let us keep statistics there.
408
+ */
409
+static int ath9k_rx_iob_preprocess(struct ath_common *common,
410
+				   struct net80211_device *dev,
411
+				   struct ath_rx_status *rx_stats,
412
+				   int *rix,
413
+				   int *decrypt_error)
414
+{
415
+	/*
416
+	 * everything but the rate is checked here, the rate check is done
417
+	 * separately to avoid doing two lookups for a rate for each frame.
418
+	 */
419
+	if (!ath9k_rx_accept(common, rx_stats, decrypt_error))
420
+		return -EINVAL;
421
+
422
+	/* Only use status info from the last fragment */
423
+	if (rx_stats->rs_more)
424
+		return 0;
425
+
426
+	if (ath9k_process_rate(common, dev, rx_stats, rix))
427
+		return -EINVAL;
428
+
429
+	return 0;
430
+}
431
+
432
+int ath_rx_tasklet(struct ath_softc *sc, int flush, int hp __unused)
433
+{
434
+	struct ath_buf *bf;
435
+	struct io_buffer *iob = NULL, *requeue_iob;
436
+	u32 *requeue_iob_addr = NULL;
437
+	struct ath_hw *ah = sc->sc_ah;
438
+	struct ath_common *common = ath9k_hw_common(ah);
439
+	/*
440
+	 * The hw can technically differ from common->hw when using ath9k
441
+	 * virtual wiphy so to account for that we iterate over the active
442
+	 * wiphys and find the appropriate wiphy and therefore hw.
443
+	 */
444
+	struct net80211_device *dev = sc->dev;
445
+	int retval;
446
+	int decrypt_error = 0;
447
+	struct ath_rx_status rs;
448
+	int rix = 0;
449
+
450
+	do {
451
+		/* If handling rx interrupt and flush is in progress => exit */
452
+		if ((sc->sc_flags & SC_OP_RXFLUSH) && (flush == 0))
453
+			break;
454
+
455
+		memset(&rs, 0, sizeof(rs));
456
+		bf = ath_get_next_rx_buf(sc, &rs);
457
+
458
+		if (!bf)
459
+			break;
460
+
461
+		iob = bf->bf_mpdu;
462
+		if (!iob)
463
+			continue;
464
+
465
+		/*
466
+		 * If we're asked to flush receive queue, directly
467
+		 * chain it back at the queue without processing it.
468
+		 */
469
+		if (flush)
470
+			goto requeue_drop_frag;
471
+
472
+		retval = ath9k_rx_iob_preprocess(common, dev, &rs,
473
+						 &rix, &decrypt_error);
474
+		if (retval)
475
+			goto requeue_drop_frag;
476
+
477
+		/* Ensure we always have an iob to requeue once we are done
478
+		 * processing the current buffer's iob */
479
+		requeue_iob = ath_rxbuf_alloc(common, common->rx_bufsize, requeue_iob_addr);
480
+
481
+		/* If there is no memory we ignore the current RX'd frame,
482
+		 * tell hardware it can give us a new frame using the old
483
+		 * iob and put it at the tail of the sc->rx.rxbuf list for
484
+		 * processing. */
485
+		if (!requeue_iob)
486
+			goto requeue_drop_frag;
487
+
488
+		iob_put(iob, rs.rs_datalen + ah->caps.rx_status_len);
489
+		if (ah->caps.rx_status_len)
490
+			iob_pull(iob, ah->caps.rx_status_len);
491
+
492
+		/* We will now give hardware our shiny new allocated iob */
493
+		bf->bf_mpdu = requeue_iob;
494
+		bf->bf_buf_addr = *requeue_iob_addr;
495
+
496
+		/*
497
+		 * change the default rx antenna if rx diversity chooses the
498
+		 * other antenna 3 times in a row.
499
+		 */
500
+		if (sc->rx.defant != rs.rs_antenna) {
501
+			if (++sc->rx.rxotherant >= 3)
502
+				ath_setdefantenna(sc, rs.rs_antenna);
503
+		} else {
504
+			sc->rx.rxotherant = 0;
505
+		}
506
+
507
+		DBGIO("ath9k: rx %d bytes, signal %d, bitrate %d, hw_value %d\n", rs.rs_datalen,
508
+		                                rs.rs_rssi, sc->rates[rix].bitrate, rs.rs_rate);
509
+
510
+		net80211_rx(dev, iob, rs.rs_rssi,
511
+				sc->rates[rix].bitrate);
512
+
513
+requeue_drop_frag:
514
+		list_del(&bf->list);
515
+		list_add_tail(&bf->list, &sc->rx.rxbuf);
516
+		ath_rx_buf_link(sc, bf);
517
+		ath9k_hw_rxena(ah);
518
+	} while (1);
519
+
520
+	return 0;
521
+}

+ 813
- 0
src/drivers/net/ath/ath9k/ath9k_xmit.c View File

@@ -0,0 +1,813 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/io.h>
21
+
22
+#include "ath9k.h"
23
+#include "ar9003_mac.h"
24
+
25
+#define BITS_PER_BYTE           8
26
+#define OFDM_PLCP_BITS          22
27
+#define HT_RC_2_STREAMS(_rc)    ((((_rc) & 0x78) >> 3) + 1)
28
+#define L_STF                   8
29
+#define L_LTF                   8
30
+#define L_SIG                   4
31
+#define HT_SIG                  8
32
+#define HT_STF                  4
33
+#define HT_LTF(_ns)             (4 * (_ns))
34
+#define SYMBOL_TIME(_ns)        ((_ns) << 2) /* ns * 4 us */
35
+#define SYMBOL_TIME_HALFGI(_ns) (((_ns) * 18 + 4) / 5)  /* ns * 3.6 us */
36
+#define NUM_SYMBOLS_PER_USEC(_usec) (_usec >> 2)
37
+#define NUM_SYMBOLS_PER_USEC_HALFGI(_usec) (((_usec*5)-4)/18)
38
+
39
+
40
+#define IS_HT_RATE(_rate)     ((_rate) & 0x80)
41
+
42
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
43
+			       struct ath_atx_tid *tid,
44
+			       struct list_head *bf_head);
45
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
46
+				struct ath_txq *txq, struct list_head *bf_q,
47
+				struct ath_tx_status *ts, int txok, int sendbar);
48
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
49
+			     struct list_head *head);
50
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len);
51
+
52
+enum {
53
+	MCS_HT20,
54
+	MCS_HT20_SGI,
55
+	MCS_HT40,
56
+	MCS_HT40_SGI,
57
+};
58
+
59
+/*********************/
60
+/* Aggregation logic */
61
+/*********************/
62
+
63
+static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
64
+{
65
+	struct ath_atx_ac *ac = tid->ac;
66
+
67
+	if (tid->paused)
68
+		return;
69
+
70
+	if (tid->sched)
71
+		return;
72
+
73
+	tid->sched = 1;
74
+	list_add_tail(&tid->list, &ac->tid_q);
75
+
76
+	if (ac->sched)
77
+		return;
78
+
79
+	ac->sched = 1;
80
+	list_add_tail(&ac->list, &txq->axq_acq);
81
+}
82
+
83
+static struct ath_buf *ath_tx_get_buffer(struct ath_softc *sc)
84
+{
85
+	struct ath_buf *bf = NULL;
86
+
87
+	if (list_empty(&sc->tx.txbuf)) {
88
+		return NULL;
89
+	}
90
+
91
+	bf = list_first_entry(&sc->tx.txbuf, struct ath_buf, list);
92
+	list_del(&bf->list);
93
+
94
+	return bf;
95
+}
96
+
97
+static void ath_tx_return_buffer(struct ath_softc *sc, struct ath_buf *bf)
98
+{
99
+	list_add_tail(&bf->list, &sc->tx.txbuf);
100
+}
101
+
102
+/********************/
103
+/* Queue Management */
104
+/********************/
105
+
106
+struct ath_txq *ath_txq_setup(struct ath_softc *sc, int qtype, int subtype)
107
+{
108
+	struct ath_hw *ah = sc->sc_ah;
109
+	struct ath9k_tx_queue_info qi;
110
+	static const int subtype_txq_to_hwq[] = {
111
+		[WME_AC_BE] = ATH_TXQ_AC_BE,
112
+	};
113
+	int axq_qnum, i;
114
+
115
+	memset(&qi, 0, sizeof(qi));
116
+	qi.tqi_subtype = subtype_txq_to_hwq[subtype];
117
+	qi.tqi_aifs = ATH9K_TXQ_USEDEFAULT;
118
+	qi.tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
119
+	qi.tqi_cwmax = ATH9K_TXQ_USEDEFAULT;
120
+	qi.tqi_physCompBuf = 0;
121
+
122
+	/*
123
+	 * Enable interrupts only for EOL and DESC conditions.
124
+	 * We mark tx descriptors to receive a DESC interrupt
125
+	 * when a tx queue gets deep; otherwise waiting for the
126
+	 * EOL to reap descriptors.  Note that this is done to
127
+	 * reduce interrupt load and this only defers reaping
128
+	 * descriptors, never transmitting frames.  Aside from
129
+	 * reducing interrupts this also permits more concurrency.
130
+	 * The only potential downside is if the tx queue backs
131
+	 * up in which case the top half of the kernel may backup
132
+	 * due to a lack of tx descriptors.
133
+	 *
134
+	 * The UAPSD queue is an exception, since we take a desc-
135
+	 * based intr on the EOSP frames.
136
+	 */
137
+	qi.tqi_qflags = TXQ_FLAG_TXEOLINT_ENABLE |
138
+			TXQ_FLAG_TXDESCINT_ENABLE;
139
+
140
+	axq_qnum = ath9k_hw_setuptxqueue(ah, qtype, &qi);
141
+	if (axq_qnum == -1) {
142
+		/*
143
+		 * NB: don't print a message, this happens
144
+		 * normally on parts with too few tx queues
145
+		 */
146
+		return NULL;
147
+	}
148
+	if ((unsigned int)axq_qnum >= ARRAY_SIZE(sc->tx.txq)) {
149
+		DBG("ath9k: qnum %d out of range, max %zd!\n",
150
+			axq_qnum, ARRAY_SIZE(sc->tx.txq));
151
+		ath9k_hw_releasetxqueue(ah, axq_qnum);
152
+		return NULL;
153
+	}
154
+	if (!ATH_TXQ_SETUP(sc, axq_qnum)) {
155
+		struct ath_txq *txq = &sc->tx.txq[axq_qnum];
156
+
157
+		txq->axq_qnum = axq_qnum;
158
+		txq->mac80211_qnum = -1;
159
+		txq->axq_link = NULL;
160
+		INIT_LIST_HEAD(&txq->axq_q);
161
+		INIT_LIST_HEAD(&txq->axq_acq);
162
+		txq->axq_depth = 0;
163
+		txq->axq_ampdu_depth = 0;
164
+		txq->axq_tx_inprogress = 0;
165
+		sc->tx.txqsetup |= 1<<axq_qnum;
166
+
167
+		txq->txq_headidx = txq->txq_tailidx = 0;
168
+		for (i = 0; i < ATH_TXFIFO_DEPTH; i++)
169
+			INIT_LIST_HEAD(&txq->txq_fifo[i]);
170
+		INIT_LIST_HEAD(&txq->txq_fifo_pending);
171
+	}
172
+	return &sc->tx.txq[axq_qnum];
173
+}
174
+
175
+/*
176
+ * Drain a given TX queue (could be Beacon or Data)
177
+ *
178
+ * This assumes output has been stopped and
179
+ * we do not need to block ath_tx_tasklet.
180
+ */
181
+void ath_draintxq(struct ath_softc *sc, struct ath_txq *txq, int retry_tx __unused)
182
+{
183
+	struct ath_buf *bf, *lastbf __unused;
184
+	struct list_head bf_head;
185
+	struct ath_tx_status ts;
186
+
187
+	memset(&ts, 0, sizeof(ts));
188
+	INIT_LIST_HEAD(&bf_head);
189
+
190
+	for (;;) {
191
+		if (list_empty(&txq->axq_q)) {
192
+			txq->axq_link = NULL;
193
+			break;
194
+		}
195
+		bf = list_first_entry(&txq->axq_q, struct ath_buf,
196
+				      list);
197
+
198
+		if (bf->bf_stale) {
199
+			list_del(&bf->list);
200
+
201
+			ath_tx_return_buffer(sc, bf);
202
+			continue;
203
+		}
204
+
205
+		lastbf = bf->bf_lastbf;
206
+
207
+		list_cut_position(&bf_head, &txq->axq_q, &lastbf->list);
208
+
209
+		txq->axq_depth--;
210
+		ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0, 0);
211
+	}
212
+
213
+	txq->axq_tx_inprogress = 0;
214
+}
215
+
216
+int ath_drain_all_txq(struct ath_softc *sc, int retry_tx)
217
+{
218
+	struct ath_hw *ah = sc->sc_ah;
219
+	struct ath_txq *txq;
220
+	int i, npend = 0;
221
+
222
+	if (sc->sc_flags & SC_OP_INVALID)
223
+		return 1;
224
+
225
+	ath9k_hw_abort_tx_dma(ah);
226
+
227
+	/* Check if any queue remains active */
228
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
229
+		if (!ATH_TXQ_SETUP(sc, i))
230
+			continue;
231
+
232
+		npend += ath9k_hw_numtxpending(ah, sc->tx.txq[i].axq_qnum);
233
+	}
234
+
235
+	if (npend)
236
+		DBG("ath9k: Failed to stop TX DMA!\n");
237
+
238
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
239
+		if (!ATH_TXQ_SETUP(sc, i))
240
+			continue;
241
+
242
+		/*
243
+		 * The caller will resume queues with ieee80211_wake_queues.
244
+		 * Mark the queue as not stopped to prevent ath_tx_complete
245
+		 * from waking the queue too early.
246
+		 */
247
+		txq = &sc->tx.txq[i];
248
+		txq->stopped = 0;
249
+		ath_draintxq(sc, txq, retry_tx);
250
+	}
251
+
252
+	return !npend;
253
+}
254
+
255
+void ath_tx_cleanupq(struct ath_softc *sc, struct ath_txq *txq)
256
+{
257
+	ath9k_hw_releasetxqueue(sc->sc_ah, txq->axq_qnum);
258
+	sc->tx.txqsetup &= ~(1<<txq->axq_qnum);
259
+}
260
+
261
+/* For each axq_acq entry, for each tid, try to schedule packets
262
+ * for transmit until ampdu_depth has reached min Q depth.
263
+ */
264
+void ath_txq_schedule(struct ath_softc *sc __unused, struct ath_txq *txq)
265
+{
266
+	struct ath_atx_ac *ac, *ac_tmp, *last_ac;
267
+	struct ath_atx_tid *tid, *last_tid;
268
+
269
+	if (list_empty(&txq->axq_acq) ||
270
+	    txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
271
+		return;
272
+
273
+	ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
274
+	last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);
275
+
276
+	list_for_each_entry_safe(ac, ac_tmp, &txq->axq_acq, list) {
277
+		last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
278
+		list_del(&ac->list);
279
+		ac->sched = 0;
280
+
281
+		while (!list_empty(&ac->tid_q)) {
282
+			tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
283
+					       list);
284
+			list_del(&tid->list);
285
+			tid->sched = 0;
286
+
287
+			if (tid->paused)
288
+				continue;
289
+
290
+			/*
291
+			 * add tid to round-robin queue if more frames
292
+			 * are pending for the tid
293
+			 */
294
+			if (!list_empty(&tid->buf_q))
295
+				ath_tx_queue_tid(txq, tid);
296
+
297
+			if (tid == last_tid ||
298
+			    txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
299
+				break;
300
+		}
301
+
302
+		if (!list_empty(&ac->tid_q)) {
303
+			if (!ac->sched) {
304
+				ac->sched = 1;
305
+				list_add_tail(&ac->list, &txq->axq_acq);
306
+			}
307
+		}
308
+
309
+		if (ac == last_ac ||
310
+		    txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
311
+			return;
312
+	}
313
+}
314
+
315
+/***********/
316
+/* TX, DMA */
317
+/***********/
318
+
319
+/*
320
+ * Insert a chain of ath_buf (descriptors) on a txq and
321
+ * assume the descriptors are already chained together by caller.
322
+ */
323
+static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
324
+			     struct list_head *head)
325
+{
326
+	struct ath_hw *ah = sc->sc_ah;
327
+	struct ath_buf *bf;
328
+
329
+	/*
330
+	 * Insert the frame on the outbound list and
331
+	 * pass it on to the hardware.
332
+	 */
333
+
334
+	if (list_empty(head))
335
+		return;
336
+
337
+	bf = list_first_entry(head, struct ath_buf, list);
338
+
339
+	DBGIO("ath9k: "
340
+		"qnum: %d, txq depth: %d\n", txq->axq_qnum, txq->axq_depth);
341
+
342
+	list_splice_tail_init(head, &txq->axq_q);
343
+
344
+	if (txq->axq_link == NULL) {
345
+		ath9k_hw_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr);
346
+		DBGIO("ath9k: TXDP[%d] = %llx (%p)\n",
347
+			txq->axq_qnum, ito64(bf->bf_daddr),
348
+			bf->bf_desc);
349
+	} else {
350
+		*txq->axq_link = bf->bf_daddr;
351
+		DBGIO("ath9k: "
352
+			"link[%d] (%p)=%llx (%p)\n",
353
+			txq->axq_qnum, txq->axq_link,
354
+			ito64(bf->bf_daddr), bf->bf_desc);
355
+	}
356
+	ath9k_hw_get_desc_link(ah, bf->bf_lastbf->bf_desc,
357
+			       &txq->axq_link);
358
+	ath9k_hw_txstart(ah, txq->axq_qnum);
359
+
360
+	txq->axq_depth++;
361
+}
362
+
363
+static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
364
+			       struct ath_atx_tid *tid,
365
+			       struct list_head *bf_head)
366
+{
367
+	struct ath_buf *bf;
368
+
369
+	bf = list_first_entry(bf_head, struct ath_buf, list);
370
+	bf->bf_state.bf_type &= ~BUF_AMPDU;
371
+
372
+	/* update starting sequence number for subsequent ADDBA request */
373
+	if (tid)
374
+		INCR(tid->seq_start, IEEE80211_SEQ_MAX);
375
+
376
+	bf->bf_lastbf = bf;
377
+	ath_buf_set_rate(sc, bf, iob_len(bf->bf_mpdu) + FCS_LEN);
378
+	ath_tx_txqaddbuf(sc, txq, bf_head);
379
+}
380
+
381
+static enum ath9k_pkt_type get_hw_packet_type(struct io_buffer *iob)
382
+{
383
+	struct ieee80211_frame *hdr;
384
+	enum ath9k_pkt_type htype;
385
+	u16 fc;
386
+
387
+	hdr = (struct ieee80211_frame *)iob->data;
388
+	fc = hdr->fc;
389
+
390
+	if ((fc & (IEEE80211_FC_TYPE | IEEE80211_FC_SUBTYPE)) == (IEEE80211_TYPE_MGMT | IEEE80211_STYPE_BEACON))
391
+		htype = ATH9K_PKT_TYPE_BEACON;
392
+	else if ((fc & (IEEE80211_FC_TYPE | IEEE80211_FC_SUBTYPE)) == (IEEE80211_TYPE_MGMT | IEEE80211_STYPE_PROBE_RESP))
393
+		htype = ATH9K_PKT_TYPE_PROBE_RESP;
394
+	else
395
+		htype = ATH9K_PKT_TYPE_NORMAL;
396
+
397
+	return htype;
398
+}
399
+
400
+static int setup_tx_flags(struct io_buffer *iob __unused)
401
+{
402
+	int flags = 0;
403
+
404
+	flags |= ATH9K_TXDESC_INTREQ;
405
+
406
+	return flags;
407
+}
408
+
409
+u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
410
+{
411
+	struct ath_hw *ah = sc->sc_ah;
412
+	struct ath9k_channel *curchan = ah->curchan;
413
+	if ((sc->sc_flags & SC_OP_ENABLE_APM) &&
414
+			(curchan->channelFlags & CHANNEL_5GHZ) &&
415
+			(chainmask == 0x7) && (rate < 0x90))
416
+		return 0x3;
417
+	else
418
+		return chainmask;
419
+}
420
+
421
+static void ath_buf_set_rate(struct ath_softc *sc, struct ath_buf *bf, int len)
422
+{
423
+	struct ath_common *common = ath9k_hw_common(sc->sc_ah);
424
+	struct ath9k_11n_rate_series series[4];
425
+	const struct ath9k_legacy_rate *rate;
426
+	int i, flags = 0;
427
+	u8 rix = 0, ctsrate = 0;
428
+	int is_pspoll;
429
+
430
+	memset(series, 0, sizeof(struct ath9k_11n_rate_series) * 4);
431
+
432
+	is_pspoll = 0;
433
+
434
+	/*
435
+	 * We check if Short Preamble is needed for the CTS rate by
436
+	 * checking the BSS's global flag.
437
+	 * But for the rate series, IEEE80211_TX_RC_USE_SHORT_PREAMBLE is used.
438
+	 */
439
+	rate = &sc->rates[sc->hw_rix];
440
+	ctsrate = rate->hw_value;
441
+	if (sc->sc_flags & SC_OP_PREAMBLE_SHORT)
442
+		ctsrate |= rate->hw_value_short;
443
+
444
+	for (i = 0; i < 4; i++) {
445
+		int is_40 __unused, is_sgi __unused, is_sp;
446
+		int phy;
447
+
448
+		rix = sc->hw_rix;
449
+		series[i].Tries = ATH_TXMAXTRY;
450
+
451
+		if (sc->sc_flags & SC_OP_PROTECT_ENABLE) {
452
+			series[i].RateFlags |= ATH9K_RATESERIES_RTS_CTS;
453
+			flags |= ATH9K_TXDESC_CTSENA;
454
+		}
455
+
456
+		is_sp = !!(rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE);
457
+
458
+		/* legacy rates */
459
+		if ((sc->dev->channels + sc->dev->channel)->band == NET80211_BAND_2GHZ)
460
+			phy = CHANNEL_CCK;
461
+		else
462
+			phy = CHANNEL_OFDM;
463
+
464
+		series[i].Rate = rate->hw_value;
465
+		if (rate->hw_value_short && (sc->sc_flags & SC_OP_PREAMBLE_SHORT)) {
466
+			if (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
467
+				series[i].Rate |= rate->hw_value_short;
468
+		} else {
469
+			is_sp = 0;
470
+		}
471
+
472
+		if (bf->bf_state.bfs_paprd)
473
+			series[i].ChSel = common->tx_chainmask;
474
+		else
475
+			series[i].ChSel = ath_txchainmask_reduction(sc,
476
+					common->tx_chainmask, series[i].Rate);
477
+
478
+		series[i].PktDuration = ath9k_hw_computetxtime(sc->sc_ah,
479
+			phy, rate->bitrate * 100, len, rix, is_sp);
480
+	}
481
+
482
+	/* For AR5416 - RTS cannot be followed by a frame larger than 8K */
483
+	if (bf_isaggr(bf) && (len > sc->sc_ah->caps.rts_aggr_limit))
484
+		flags &= ~ATH9K_TXDESC_RTSENA;
485
+
486
+	/* ATH9K_TXDESC_RTSENA and ATH9K_TXDESC_CTSENA are mutually exclusive. */
487
+	if (flags & ATH9K_TXDESC_RTSENA)
488
+		flags &= ~ATH9K_TXDESC_CTSENA;
489
+
490
+	/* set dur_update_en for l-sig computation except for PS-Poll frames */
491
+	ath9k_hw_set11n_ratescenario(sc->sc_ah, bf->bf_desc,
492
+				     bf->bf_lastbf->bf_desc,
493
+				     !is_pspoll, ctsrate,
494
+				     0, series, 4, flags);
495
+
496
+}
497
+
498
+static struct ath_buf *ath_tx_setup_buffer(struct net80211_device *dev,
499
+					   struct ath_txq *txq,
500
+					   struct io_buffer *iob)
501
+{
502
+	struct ath_softc *sc = dev->priv;
503
+	struct ath_hw *ah = sc->sc_ah;
504
+	struct ath_buf *bf;
505
+	struct ath_desc *ds;
506
+	int frm_type;
507
+	static const enum ath9k_key_type net80211_keytype_to_ath[] = {
508
+			[NET80211_CRYPT_NONE] = ATH9K_KEY_TYPE_CLEAR,
509
+			[NET80211_CRYPT_WEP] = ATH9K_KEY_TYPE_WEP,
510
+			[NET80211_CRYPT_TKIP] = ATH9K_KEY_TYPE_TKIP,
511
+			[NET80211_CRYPT_CCMP] = ATH9K_KEY_TYPE_AES,
512
+			[NET80211_CRYPT_UNKNOWN] = ATH9K_KEY_TYPE_CLEAR,
513
+	};
514
+
515
+	bf = ath_tx_get_buffer(sc);
516
+	if (!bf) {
517
+		DBG("ath9k: TX buffers are full\n");
518
+		return NULL;
519
+	}
520
+
521
+	ATH_TXBUF_RESET(bf);
522
+
523
+	bf->bf_flags = setup_tx_flags(iob);
524
+	bf->bf_mpdu = iob;
525
+
526
+	bf->bf_buf_addr = virt_to_bus(iob->data);
527
+
528
+	frm_type = get_hw_packet_type(iob);
529
+
530
+	ds = bf->bf_desc;
531
+	ath9k_hw_set_desc_link(ah, ds, 0);
532
+
533
+	ath9k_hw_set11n_txdesc(ah, ds, iob_len(iob) + FCS_LEN, frm_type, MAX_RATE_POWER,
534
+			       ATH9K_TXKEYIX_INVALID, net80211_keytype_to_ath[dev->crypto->algorithm], bf->bf_flags);
535
+
536
+	ath9k_hw_filltxdesc(ah, ds,
537
+			    iob_len(iob),	/* segment length */
538
+			    1,		/* first segment */
539
+			    1,		/* last segment */
540
+			    ds,		/* first descriptor */
541
+			    bf->bf_buf_addr,
542
+			    txq->axq_qnum);
543
+
544
+
545
+	return bf;
546
+}
547
+
548
+/* FIXME: tx power */
549
+static void ath_tx_start_dma(struct ath_softc *sc, struct ath_buf *bf,
550
+			     struct ath_tx_control *txctl)
551
+{
552
+	struct list_head bf_head;
553
+	struct ath_atx_tid *tid = NULL;
554
+
555
+	INIT_LIST_HEAD(&bf_head);
556
+	list_add_tail(&bf->list, &bf_head);
557
+
558
+	bf->bf_state.bfs_paprd = txctl->paprd;
559
+
560
+	if (txctl->paprd)
561
+		bf->bf_state.bfs_paprd_timestamp = ( currticks() * 1000 ) / TICKS_PER_SEC;
562
+
563
+	ath9k_hw_set_clrdmask(sc->sc_ah, bf->bf_desc, 1);
564
+
565
+	ath_tx_send_normal(sc, txctl->txq, tid, &bf_head);
566
+}
567
+
568
+/* Upon failure caller should free iob */
569
+int ath_tx_start(struct net80211_device *dev, struct io_buffer *iob,
570
+		 struct ath_tx_control *txctl)
571
+{
572
+	struct ath_softc *sc = dev->priv;
573
+	struct ath_txq *txq = txctl->txq;
574
+	struct ath_buf *bf;
575
+	int q;
576
+
577
+	/*
578
+	 * At this point, the vif, hw_key and sta pointers in the tx control
579
+	 * info are no longer valid (overwritten by the ath_frame_info data.
580
+	 */
581
+
582
+	bf = ath_tx_setup_buffer(dev, txctl->txq, iob);
583
+	if (!bf)
584
+		return -ENOMEM;
585
+
586
+	q = 0;
587
+	if (txq == sc->tx.txq_map[q] &&
588
+	    ++txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
589
+		txq->stopped = 1;
590
+	}
591
+
592
+	ath_tx_start_dma(sc, bf, txctl);
593
+
594
+	return 0;
595
+}
596
+
597
+/*****************/
598
+/* TX Completion */
599
+/*****************/
600
+
601
+static void ath_tx_complete(struct ath_softc *sc, struct io_buffer *iob,
602
+			    int tx_flags __unused, struct ath_tx_status *ts, struct ath_txq *txq)
603
+{
604
+	struct net80211_device *dev = sc->dev;
605
+	int q, padpos __unused, padsize __unused;
606
+
607
+	DBGIO("ath9k: TX complete: iob: %p\n", iob);
608
+
609
+	q = 0;
610
+	if (txq == sc->tx.txq_map[q]) {
611
+		if (--txq->pending_frames < 0)
612
+			txq->pending_frames = 0;
613
+
614
+		if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
615
+			txq->stopped = 0;
616
+		}
617
+	}
618
+
619
+	net80211_tx_complete(dev, iob, ts->ts_longretry,
620
+			(ts->ts_status & ATH9K_TXERR_MASK) ? EIO : 0);
621
+}
622
+
623
+static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
624
+				struct ath_txq *txq, struct list_head *bf_q,
625
+				struct ath_tx_status *ts, int txok, int sendbar)
626
+{
627
+	struct io_buffer *iob = bf->bf_mpdu;
628
+	int tx_flags = 0;
629
+
630
+	if (sendbar)
631
+		tx_flags = ATH_TX_BAR;
632
+
633
+	if (!txok) {
634
+		tx_flags |= ATH_TX_ERROR;
635
+
636
+		if (bf_isxretried(bf))
637
+			tx_flags |= ATH_TX_XRETRY;
638
+	}
639
+
640
+	bf->bf_buf_addr = 0;
641
+
642
+	ath_tx_complete(sc, iob, tx_flags,
643
+			ts, txq);
644
+
645
+	/* At this point, iob (bf->bf_mpdu) is consumed...make sure we don't
646
+	 * accidentally reference it later.
647
+	 */
648
+	bf->bf_mpdu = NULL;
649
+
650
+	/*
651
+	 * Return the list of ath_buf of this mpdu to free queue
652
+	 */
653
+	list_splice_tail_init(bf_q, &sc->tx.txbuf);
654
+}
655
+
656
+static void ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq)
657
+{
658
+	struct ath_hw *ah = sc->sc_ah;
659
+	struct ath_buf *bf, *lastbf, *bf_held = NULL;
660
+	struct list_head bf_head;
661
+	struct ath_desc *ds;
662
+	struct ath_tx_status ts;
663
+	int txok;
664
+	int status;
665
+
666
+	DBGIO("ath9k: tx queue %d (%x), link %p\n",
667
+		txq->axq_qnum, ath9k_hw_gettxbuf(sc->sc_ah, txq->axq_qnum),
668
+		txq->axq_link);
669
+
670
+	for (;;) {
671
+		if (list_empty(&txq->axq_q)) {
672
+			txq->axq_link = NULL;
673
+			if (sc->sc_flags & SC_OP_TXAGGR)
674
+				ath_txq_schedule(sc, txq);
675
+			break;
676
+		}
677
+		bf = list_first_entry(&txq->axq_q, struct ath_buf, list);
678
+
679
+		/*
680
+		 * There is a race condition that a BH gets scheduled
681
+		 * after sw writes TxE and before hw re-load the last
682
+		 * descriptor to get the newly chained one.
683
+		 * Software must keep the last DONE descriptor as a
684
+		 * holding descriptor - software does so by marking
685
+		 * it with the STALE flag.
686
+		 */
687
+		bf_held = NULL;
688
+		if (bf->bf_stale) {
689
+			bf_held = bf;
690
+			if (list_is_last(&bf_held->list, &txq->axq_q)) {
691
+				break;
692
+			} else {
693
+				bf = list_entry(bf_held->list.next,
694
+						struct ath_buf, list);
695
+			}
696
+		}
697
+
698
+		lastbf = bf->bf_lastbf;
699
+		ds = lastbf->bf_desc;
700
+
701
+		memset(&ts, 0, sizeof(ts));
702
+		status = ath9k_hw_txprocdesc(ah, ds, &ts);
703
+		if (status == -EINPROGRESS) {
704
+			break;
705
+		}
706
+
707
+		/*
708
+		 * Remove ath_buf's of the same transmit unit from txq,
709
+		 * however leave the last descriptor back as the holding
710
+		 * descriptor for hw.
711
+		 */
712
+		lastbf->bf_stale = 1;
713
+		INIT_LIST_HEAD(&bf_head);
714
+		if (!list_is_singular(&lastbf->list))
715
+			list_cut_position(&bf_head,
716
+				&txq->axq_q, lastbf->list.prev);
717
+
718
+		txq->axq_depth--;
719
+		txok = !(ts.ts_status & ATH9K_TXERR_MASK);
720
+		txq->axq_tx_inprogress = 0;
721
+		if (bf_held)
722
+			list_del(&bf_held->list);
723
+
724
+		if (bf_held)
725
+			ath_tx_return_buffer(sc, bf_held);
726
+
727
+		/*
728
+		 * This frame is sent out as a single frame.
729
+		 * Use hardware retry status for this frame.
730
+		 */
731
+		if (ts.ts_status & ATH9K_TXERR_XRETRY)
732
+			bf->bf_state.bf_type |= BUF_XRETRY;
733
+
734
+		ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, txok, 0);
735
+
736
+		if (sc->sc_flags & SC_OP_TXAGGR)
737
+			ath_txq_schedule(sc, txq);
738
+	}
739
+}
740
+
741
+static void ath_tx_complete_poll_work(struct ath_softc *sc)
742
+{
743
+	struct ath_txq *txq;
744
+	int i;
745
+	int needreset = 0;
746
+
747
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++)
748
+		if (ATH_TXQ_SETUP(sc, i)) {
749
+			txq = &sc->tx.txq[i];
750
+			if (txq->axq_depth) {
751
+				if (txq->axq_tx_inprogress) {
752
+					needreset = 1;
753
+					break;
754
+				} else {
755
+					txq->axq_tx_inprogress = 1;
756
+				}
757
+			}
758
+		}
759
+
760
+	if (needreset) {
761
+		DBG("ath9k: "
762
+			"tx hung, resetting the chip\n");
763
+		ath_reset(sc, 1);
764
+	}
765
+
766
+	sc->tx_complete_work_timer = ( currticks() * 1000 ) / TICKS_PER_SEC + ATH_TX_COMPLETE_POLL_INT;
767
+}
768
+
769
+
770
+
771
+void ath_tx_tasklet(struct ath_softc *sc)
772
+{
773
+	int i;
774
+	u32 qcumask = ((1 << ATH9K_NUM_TX_QUEUES) - 1);
775
+
776
+	ath9k_hw_gettxintrtxqs(sc->sc_ah, &qcumask);
777
+
778
+	for (i = 0; i < ATH9K_NUM_TX_QUEUES; i++) {
779
+		if (ATH_TXQ_SETUP(sc, i) && (qcumask & (1 << i)))
780
+			ath_tx_processq(sc, &sc->tx.txq[i]);
781
+	}
782
+}
783
+
784
+/*****************/
785
+/* Init, Cleanup */
786
+/*****************/
787
+
788
+int ath_tx_init(struct ath_softc *sc, int nbufs)
789
+{
790
+	int error = 0;
791
+
792
+	error = ath_descdma_setup(sc, &sc->tx.txdma, &sc->tx.txbuf,
793
+				  "tx", nbufs, 1, 1);
794
+	if (error != 0) {
795
+		DBG("ath9k: "
796
+			"Failed to allocate tx descriptors: %d\n", error);
797
+		goto err;
798
+	}
799
+
800
+	sc->tx_complete_work = ath_tx_complete_poll_work;
801
+
802
+err:
803
+	if (error != 0)
804
+		ath_tx_cleanup(sc);
805
+
806
+	return error;
807
+}
808
+
809
+void ath_tx_cleanup(struct ath_softc *sc)
810
+{
811
+	if (sc->tx.txdma.dd_desc_len != 0)
812
+		ath_descdma_cleanup(sc, &sc->tx.txdma, &sc->tx.txbuf);
813
+}

+ 115
- 0
src/drivers/net/ath/ath9k/calib.h View File

@@ -0,0 +1,115 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef CALIB_H
21
+#define CALIB_H
22
+
23
+#include "hw.h"
24
+
25
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH_INIT     3
26
+#define AR_PHY_CCA_FILTERWINDOW_LENGTH          5
27
+
28
+#define NUM_NF_READINGS       6
29
+#define ATH9K_NF_CAL_HIST_MAX 5
30
+
31
+struct ar5416IniArray {
32
+	u32 *ia_array;
33
+	u32 ia_rows;
34
+	u32 ia_columns;
35
+};
36
+
37
+#define INIT_INI_ARRAY(iniarray, array, rows, columns) do {	\
38
+		(iniarray)->ia_array = (u32 *)(array);		\
39
+		(iniarray)->ia_rows = (rows);			\
40
+		(iniarray)->ia_columns = (columns);		\
41
+	} while (0)
42
+
43
+#define INI_RA(iniarray, row, column) \
44
+	(((iniarray)->ia_array)[(row) *	((iniarray)->ia_columns) + (column)])
45
+
46
+#define INIT_CAL(_perCal) do {				\
47
+		(_perCal)->calState = CAL_WAITING;	\
48
+		(_perCal)->calNext = NULL;		\
49
+	} while (0)
50
+
51
+#define INSERT_CAL(_ahp, _perCal)					\
52
+	do {								\
53
+		if ((_ahp)->cal_list_last == NULL) {			\
54
+			(_ahp)->cal_list =				\
55
+				(_ahp)->cal_list_last = (_perCal);	\
56
+			((_ahp)->cal_list_last)->calNext = (_perCal); \
57
+		} else {						\
58
+			((_ahp)->cal_list_last)->calNext = (_perCal); \
59
+			(_ahp)->cal_list_last = (_perCal);		\
60
+			(_perCal)->calNext = (_ahp)->cal_list;	\
61
+		}							\
62
+	} while (0)
63
+
64
+enum ath9k_cal_state {
65
+	CAL_INACTIVE,
66
+	CAL_WAITING,
67
+	CAL_RUNNING,
68
+	CAL_DONE
69
+};
70
+
71
+#define MIN_CAL_SAMPLES     1
72
+#define MAX_CAL_SAMPLES    64
73
+#define INIT_LOG_COUNT      5
74
+#define PER_MIN_LOG_COUNT   2
75
+#define PER_MAX_LOG_COUNT  10
76
+
77
+struct ath9k_percal_data {
78
+	u32 calType;
79
+	u32 calNumSamples;
80
+	u32 calCountMax;
81
+	void (*calCollect) (struct ath_hw *);
82
+	void (*calPostProc) (struct ath_hw *, u8);
83
+};
84
+
85
+struct ath9k_cal_list {
86
+	const struct ath9k_percal_data *calData;
87
+	enum ath9k_cal_state calState;
88
+	struct ath9k_cal_list *calNext;
89
+};
90
+
91
+struct ath9k_nfcal_hist {
92
+	int16_t nfCalBuffer[ATH9K_NF_CAL_HIST_MAX];
93
+	u8 currIndex;
94
+	int16_t privNF;
95
+	u8 invalidNFcount;
96
+};
97
+
98
+#define MAX_PACAL_SKIPCOUNT 8
99
+struct ath9k_pacal_info{
100
+	int32_t prev_offset;	/* Previous value of PA offset value */
101
+	int8_t max_skipcount;	/* Max No. of times PACAL can be skipped */
102
+	int8_t skipcount;	/* No. of times the PACAL to be skipped */
103
+};
104
+
105
+int ath9k_hw_reset_calvalid(struct ath_hw *ah);
106
+void ath9k_hw_start_nfcal(struct ath_hw *ah, int update);
107
+void ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan);
108
+int ath9k_hw_getnf(struct ath_hw *ah, struct ath9k_channel *chan);
109
+void ath9k_init_nfcal_hist_buffer(struct ath_hw *ah,
110
+				  struct ath9k_channel *chan);
111
+void ath9k_hw_reset_calibration(struct ath_hw *ah,
112
+				struct ath9k_cal_list *currCal);
113
+
114
+
115
+#endif /* CALIB_H */

+ 56
- 0
src/drivers/net/ath/ath9k/common.h View File

@@ -0,0 +1,56 @@
1
+/*
2
+ * Copyright (c) 2009-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 "../ath.h"
21
+
22
+#include "hw.h"
23
+#include "hw-ops.h"
24
+
25
+/* Common header for Atheros 802.11n base driver cores */
26
+
27
+#define WME_NUM_TID             16
28
+#define WME_BA_BMP_SIZE         64
29
+#define WME_MAX_BA              WME_BA_BMP_SIZE
30
+#define ATH_TID_MAX_BUFS        (2 * WME_MAX_BA)
31
+
32
+#define WME_AC_BE   2
33
+#define WME_NUM_AC  1
34
+
35
+#define ATH_RSSI_DUMMY_MARKER   0x127
36
+#define ATH_RSSI_LPF_LEN 		10
37
+#define RSSI_LPF_THRESHOLD		-20
38
+#define ATH_RSSI_EP_MULTIPLIER     (1<<7)
39
+#define ATH_EP_MUL(x, mul)         ((x) * (mul))
40
+#define ATH_RSSI_IN(x)             (ATH_EP_MUL((x), ATH_RSSI_EP_MULTIPLIER))
41
+#define ATH_LPF_RSSI(x, y, len) \
42
+    ((x != ATH_RSSI_DUMMY_MARKER) ? (((x) * ((len) - 1) + (y)) / (len)) : (y))
43
+#define ATH_RSSI_LPF(x, y) do {                     			\
44
+    if ((y) >= RSSI_LPF_THRESHOLD)                         		\
45
+	x = ATH_LPF_RSSI((x), ATH_RSSI_IN((y)), ATH_RSSI_LPF_LEN);  	\
46
+} while (0)
47
+#define ATH_EP_RND(x, mul) 						\
48
+	((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul))
49
+
50
+
51
+void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
52
+			       struct net80211_channel *chan);
53
+struct ath9k_channel *ath9k_cmn_get_curchannel(struct net80211_device *dev,
54
+					       struct ath_hw *ah);
55
+void ath9k_cmn_update_txpow(struct ath_hw *ah, u16 cur_txpow,
56
+			    u16 new_txpow, u16 *txpower);

+ 714
- 0
src/drivers/net/ath/ath9k/eeprom.h View File

@@ -0,0 +1,714 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef EEPROM_H
21
+#define EEPROM_H
22
+
23
+#define AR_EEPROM_MODAL_SPURS   5
24
+
25
+#include "../ath.h"
26
+#include "ar9003_eeprom.h"
27
+
28
+#if __BYTE_ORDER == __BIG_ENDIAN
29
+#define AR5416_EEPROM_MAGIC 0x5aa5
30
+#else
31
+#define AR5416_EEPROM_MAGIC 0xa55a
32
+#endif
33
+
34
+#define CTRY_DEBUG   0x1ff
35
+#define	CTRY_DEFAULT 0
36
+
37
+#define AR_EEPROM_EEPCAP_COMPRESS_DIS   0x0001
38
+#define AR_EEPROM_EEPCAP_AES_DIS        0x0002
39
+#define AR_EEPROM_EEPCAP_FASTFRAME_DIS  0x0004
40
+#define AR_EEPROM_EEPCAP_BURST_DIS      0x0008
41
+#define AR_EEPROM_EEPCAP_MAXQCU         0x01F0
42
+#define AR_EEPROM_EEPCAP_MAXQCU_S       4
43
+#define AR_EEPROM_EEPCAP_HEAVY_CLIP_EN  0x0200
44
+#define AR_EEPROM_EEPCAP_KC_ENTRIES     0xF000
45
+#define AR_EEPROM_EEPCAP_KC_ENTRIES_S   12
46
+
47
+#define AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND   0x0040
48
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN    0x0080
49
+#define AR_EEPROM_EEREGCAP_EN_KK_U2         0x0100
50
+#define AR_EEPROM_EEREGCAP_EN_KK_MIDBAND    0x0200
51
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD     0x0400
52
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A    0x0800
53
+
54
+#define AR_EEPROM_EEREGCAP_EN_KK_U1_ODD_PRE4_0  0x4000
55
+#define AR_EEPROM_EEREGCAP_EN_KK_NEW_11A_PRE4_0 0x8000
56
+
57
+#define AR5416_EEPROM_MAGIC_OFFSET  0x0
58
+#define AR5416_EEPROM_S             2
59
+#define AR5416_EEPROM_OFFSET        0x2000
60
+#define AR5416_EEPROM_MAX           0xae0
61
+
62
+#define AR5416_EEPROM_START_ADDR \
63
+	(AR_SREV_9100(ah)) ? 0x1fff1000 : 0x503f1200
64
+
65
+#define SD_NO_CTL               0xE0
66
+#define NO_CTL                  0xff
67
+#define CTL_MODE_M              0xf
68
+#define CTL_11A                 0
69
+#define CTL_11B                 1
70
+#define CTL_11G                 2
71
+#define CTL_2GHT20              5
72
+#define CTL_5GHT20              6
73
+#define CTL_2GHT40              7
74
+#define CTL_5GHT40              8
75
+
76
+#define EXT_ADDITIVE (0x8000)
77
+#define CTL_11A_EXT (CTL_11A | EXT_ADDITIVE)
78
+#define CTL_11G_EXT (CTL_11G | EXT_ADDITIVE)
79
+#define CTL_11B_EXT (CTL_11B | EXT_ADDITIVE)
80
+
81
+#define SUB_NUM_CTL_MODES_AT_5G_40 2
82
+#define SUB_NUM_CTL_MODES_AT_2G_40 3
83
+
84
+#define INCREASE_MAXPOW_BY_TWO_CHAIN     6  /* 10*log10(2)*2 */
85
+#define INCREASE_MAXPOW_BY_THREE_CHAIN   10 /* 10*log10(3)*2 */
86
+
87
+/*
88
+ * For AR9285 and later chipsets, the following bits are not being programmed
89
+ * in EEPROM and so need to be enabled always.
90
+ *
91
+ * Bit 0: en_fcc_mid
92
+ * Bit 1: en_jap_mid
93
+ * Bit 2: en_fcc_dfs_ht40
94
+ * Bit 3: en_jap_ht40
95
+ * Bit 4: en_jap_dfs_ht40
96
+ */
97
+#define AR9285_RDEXT_DEFAULT    0x1F
98
+
99
+#define ATH9K_POW_SM(_r, _s)	(((_r) & 0x3f) << (_s))
100
+#define FREQ2FBIN(x, y)		((y) ? ((x) - 2300) : (((x) - 4800) / 5))
101
+#define ath9k_hw_use_flash(_ah)	(!(_ah->ah_flags & AH_USE_EEPROM))
102
+
103
+#define AR5416_VER_MASK (eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK)
104
+#define OLC_FOR_AR9280_20_LATER (AR_SREV_9280_20_OR_LATER(ah) && \
105
+				 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
106
+#define OLC_FOR_AR9287_10_LATER (AR_SREV_9287_11_OR_LATER(ah) && \
107
+				 ah->eep_ops->get_eeprom(ah, EEP_OL_PWRCTRL))
108
+
109
+#define AR_EEPROM_RFSILENT_GPIO_SEL     0x001c
110
+#define AR_EEPROM_RFSILENT_GPIO_SEL_S   2
111
+#define AR_EEPROM_RFSILENT_POLARITY     0x0002
112
+#define AR_EEPROM_RFSILENT_POLARITY_S   1
113
+
114
+#define EEP_RFSILENT_ENABLED        0x0001
115
+#define EEP_RFSILENT_ENABLED_S      0
116
+#define EEP_RFSILENT_POLARITY       0x0002
117
+#define EEP_RFSILENT_POLARITY_S     1
118
+#define EEP_RFSILENT_GPIO_SEL       0x001c
119
+#define EEP_RFSILENT_GPIO_SEL_S     2
120
+
121
+#define AR5416_OPFLAGS_11A           0x01
122
+#define AR5416_OPFLAGS_11G           0x02
123
+#define AR5416_OPFLAGS_N_5G_HT40     0x04
124
+#define AR5416_OPFLAGS_N_2G_HT40     0x08
125
+#define AR5416_OPFLAGS_N_5G_HT20     0x10
126
+#define AR5416_OPFLAGS_N_2G_HT20     0x20
127
+
128
+#define AR5416_EEP_NO_BACK_VER       0x1
129
+#define AR5416_EEP_VER               0xE
130
+#define AR5416_EEP_VER_MINOR_MASK    0x0FFF
131
+#define AR5416_EEP_MINOR_VER_2       0x2
132
+#define AR5416_EEP_MINOR_VER_3       0x3
133
+#define AR5416_EEP_MINOR_VER_7       0x7
134
+#define AR5416_EEP_MINOR_VER_9       0x9
135
+#define AR5416_EEP_MINOR_VER_16      0x10
136
+#define AR5416_EEP_MINOR_VER_17      0x11
137
+#define AR5416_EEP_MINOR_VER_19      0x13
138
+#define AR5416_EEP_MINOR_VER_20      0x14
139
+#define AR5416_EEP_MINOR_VER_21      0x15
140
+#define AR5416_EEP_MINOR_VER_22      0x16
141
+
142
+#define AR5416_NUM_5G_CAL_PIERS         8
143
+#define AR5416_NUM_2G_CAL_PIERS         4
144
+#define AR5416_NUM_5G_20_TARGET_POWERS  8
145
+#define AR5416_NUM_5G_40_TARGET_POWERS  8
146
+#define AR5416_NUM_2G_CCK_TARGET_POWERS 3
147
+#define AR5416_NUM_2G_20_TARGET_POWERS  4
148
+#define AR5416_NUM_2G_40_TARGET_POWERS  4
149
+#define AR5416_NUM_CTLS                 24
150
+#define AR5416_NUM_BAND_EDGES           8
151
+#define AR5416_NUM_PD_GAINS             4
152
+#define AR5416_PD_GAINS_IN_MASK         4
153
+#define AR5416_PD_GAIN_ICEPTS           5
154
+#define AR5416_NUM_PDADC_VALUES         128
155
+#define AR5416_BCHAN_UNUSED             0xFF
156
+#define AR5416_MAX_PWR_RANGE_IN_HALF_DB 64
157
+#define AR5416_MAX_CHAINS               3
158
+#define AR9300_MAX_CHAINS		3
159
+#define AR5416_PWR_TABLE_OFFSET_DB     -5
160
+
161
+/* Rx gain type values */
162
+#define AR5416_EEP_RXGAIN_23DB_BACKOFF     0
163
+#define AR5416_EEP_RXGAIN_13DB_BACKOFF     1
164
+#define AR5416_EEP_RXGAIN_ORIG             2
165
+
166
+/* Tx gain type values */
167
+#define AR5416_EEP_TXGAIN_ORIGINAL         0
168
+#define AR5416_EEP_TXGAIN_HIGH_POWER       1
169
+
170
+#define AR5416_EEP4K_START_LOC                64
171
+#define AR5416_EEP4K_NUM_2G_CAL_PIERS         3
172
+#define AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS 3
173
+#define AR5416_EEP4K_NUM_2G_20_TARGET_POWERS  3
174
+#define AR5416_EEP4K_NUM_2G_40_TARGET_POWERS  3
175
+#define AR5416_EEP4K_NUM_CTLS                 12
176
+#define AR5416_EEP4K_NUM_BAND_EDGES           4
177
+#define AR5416_EEP4K_NUM_PD_GAINS             2
178
+#define AR5416_EEP4K_MAX_CHAINS               1
179
+
180
+#define AR9280_TX_GAIN_TABLE_SIZE 22
181
+
182
+#define AR9287_EEP_VER               0xE
183
+#define AR9287_EEP_VER_MINOR_MASK    0xFFF
184
+#define AR9287_EEP_MINOR_VER_1       0x1
185
+#define AR9287_EEP_MINOR_VER_2       0x2
186
+#define AR9287_EEP_MINOR_VER_3       0x3
187
+#define AR9287_EEP_MINOR_VER         AR9287_EEP_MINOR_VER_3
188
+#define AR9287_EEP_MINOR_VER_b       AR9287_EEP_MINOR_VER
189
+#define AR9287_EEP_NO_BACK_VER       AR9287_EEP_MINOR_VER_1
190
+
191
+#define AR9287_EEP_START_LOC            128
192
+#define AR9287_HTC_EEP_START_LOC        256
193
+#define AR9287_NUM_2G_CAL_PIERS         3
194
+#define AR9287_NUM_2G_CCK_TARGET_POWERS 3
195
+#define AR9287_NUM_2G_20_TARGET_POWERS  3
196
+#define AR9287_NUM_2G_40_TARGET_POWERS  3
197
+#define AR9287_NUM_CTLS              	12
198
+#define AR9287_NUM_BAND_EDGES        	4
199
+#define AR9287_PD_GAIN_ICEPTS           1
200
+#define AR9287_EEPMISC_BIG_ENDIAN       0x01
201
+#define AR9287_EEPMISC_WOW              0x02
202
+#define AR9287_MAX_CHAINS               2
203
+#define AR9287_ANT_16S                  32
204
+
205
+#define AR9287_DATA_SZ                  32
206
+
207
+#define AR9287_PWR_TABLE_OFFSET_DB  -5
208
+
209
+#define AR9287_CHECKSUM_LOCATION (AR9287_EEP_START_LOC + 1)
210
+
211
+#define CTL_EDGE_TPOWER(_ctl) ((_ctl) & 0x3f)
212
+#define CTL_EDGE_FLAGS(_ctl) (((_ctl) >> 6) & 0x03)
213
+
214
+#define LNA_CTL_BUF_MODE	BIT(0)
215
+#define LNA_CTL_ISEL_LO		BIT(1)
216
+#define LNA_CTL_ISEL_HI		BIT(2)
217
+#define LNA_CTL_BUF_IN		BIT(3)
218
+#define LNA_CTL_FEM_BAND	BIT(4)
219
+#define LNA_CTL_LOCAL_BIAS	BIT(5)
220
+#define LNA_CTL_FORCE_XPA	BIT(6)
221
+#define LNA_CTL_USE_ANT1	BIT(7)
222
+
223
+enum eeprom_param {
224
+	EEP_NFTHRESH_5,
225
+	EEP_NFTHRESH_2,
226
+	EEP_MAC_MSW,
227
+	EEP_MAC_MID,
228
+	EEP_MAC_LSW,
229
+	EEP_REG_0,
230
+	EEP_REG_1,
231
+	EEP_OP_CAP,
232
+	EEP_OP_MODE,
233
+	EEP_RF_SILENT,
234
+	EEP_OB_5,
235
+	EEP_DB_5,
236
+	EEP_OB_2,
237
+	EEP_DB_2,
238
+	EEP_MINOR_REV,
239
+	EEP_TX_MASK,
240
+	EEP_RX_MASK,
241
+	EEP_FSTCLK_5G,
242
+	EEP_RXGAIN_TYPE,
243
+	EEP_OL_PWRCTRL,
244
+	EEP_TXGAIN_TYPE,
245
+	EEP_RC_CHAIN_MASK,
246
+	EEP_DAC_HPWR_5G,
247
+	EEP_FRAC_N_5G,
248
+	EEP_DEV_TYPE,
249
+	EEP_TEMPSENSE_SLOPE,
250
+	EEP_TEMPSENSE_SLOPE_PAL_ON,
251
+	EEP_PWR_TABLE_OFFSET,
252
+	EEP_DRIVE_STRENGTH,
253
+	EEP_INTERNAL_REGULATOR,
254
+	EEP_SWREG,
255
+	EEP_PAPRD,
256
+	EEP_MODAL_VER,
257
+	EEP_ANT_DIV_CTL1,
258
+	EEP_CHAIN_MASK_REDUCE
259
+};
260
+
261
+enum ar5416_rates {
262
+	rate6mb, rate9mb, rate12mb, rate18mb,
263
+	rate24mb, rate36mb, rate48mb, rate54mb,
264
+	rate1l, rate2l, rate2s, rate5_5l,
265
+	rate5_5s, rate11l, rate11s, rateXr,
266
+	rateHt20_0, rateHt20_1, rateHt20_2, rateHt20_3,
267
+	rateHt20_4, rateHt20_5, rateHt20_6, rateHt20_7,
268
+	rateHt40_0, rateHt40_1, rateHt40_2, rateHt40_3,
269
+	rateHt40_4, rateHt40_5, rateHt40_6, rateHt40_7,
270
+	rateDupCck, rateDupOfdm, rateExtCck, rateExtOfdm,
271
+	Ar5416RateSize
272
+};
273
+
274
+enum ath9k_hal_freq_band {
275
+	ATH9K_HAL_FREQ_BAND_5GHZ = 0,
276
+	ATH9K_HAL_FREQ_BAND_2GHZ = 1
277
+};
278
+
279
+struct base_eep_header {
280
+	u16 length;
281
+	u16 checksum;
282
+	u16 version;
283
+	u8 opCapFlags;
284
+	u8 eepMisc;
285
+	u16 regDmn[2];
286
+	u8 macAddr[6];
287
+	u8 rxMask;
288
+	u8 txMask;
289
+	u16 rfSilent;
290
+	u16 blueToothOptions;
291
+	u16 deviceCap;
292
+	u32 binBuildNumber;
293
+	u8 deviceType;
294
+	u8 pwdclkind;
295
+	u8 fastClk5g;
296
+	u8 divChain;
297
+	u8 rxGainType;
298
+	u8 dacHiPwrMode_5G;
299
+	u8 openLoopPwrCntl;
300
+	u8 dacLpMode;
301
+	u8 txGainType;
302
+	u8 rcChainMask;
303
+	u8 desiredScaleCCK;
304
+	u8 pwr_table_offset;
305
+	u8 frac_n_5g;
306
+	u8 futureBase_3[21];
307
+} __attribute__((packed));
308
+
309
+struct base_eep_header_4k {
310
+	u16 length;
311
+	u16 checksum;
312
+	u16 version;
313
+	u8 opCapFlags;
314
+	u8 eepMisc;
315
+	u16 regDmn[2];
316
+	u8 macAddr[6];
317
+	u8 rxMask;
318
+	u8 txMask;
319
+	u16 rfSilent;
320
+	u16 blueToothOptions;
321
+	u16 deviceCap;
322
+	u32 binBuildNumber;
323
+	u8 deviceType;
324
+	u8 txGainType;
325
+} __attribute__((packed));
326
+
327
+
328
+struct spur_chan {
329
+	u16 spurChan;
330
+	u8 spurRangeLow;
331
+	u8 spurRangeHigh;
332
+} __attribute__((packed));
333
+
334
+struct modal_eep_header {
335
+	u32 antCtrlChain[AR5416_MAX_CHAINS];
336
+	u32 antCtrlCommon;
337
+	u8 antennaGainCh[AR5416_MAX_CHAINS];
338
+	u8 switchSettling;
339
+	u8 txRxAttenCh[AR5416_MAX_CHAINS];
340
+	u8 rxTxMarginCh[AR5416_MAX_CHAINS];
341
+	u8 adcDesiredSize;
342
+	u8 pgaDesiredSize;
343
+	u8 xlnaGainCh[AR5416_MAX_CHAINS];
344
+	u8 txEndToXpaOff;
345
+	u8 txEndToRxOn;
346
+	u8 txFrameToXpaOn;
347
+	u8 thresh62;
348
+	u8 noiseFloorThreshCh[AR5416_MAX_CHAINS];
349
+	u8 xpdGain;
350
+	u8 xpd;
351
+	u8 iqCalICh[AR5416_MAX_CHAINS];
352
+	u8 iqCalQCh[AR5416_MAX_CHAINS];
353
+	u8 pdGainOverlap;
354
+	u8 ob;
355
+	u8 db;
356
+	u8 xpaBiasLvl;
357
+	u8 pwrDecreaseFor2Chain;
358
+	u8 pwrDecreaseFor3Chain;
359
+	u8 txFrameToDataStart;
360
+	u8 txFrameToPaOn;
361
+	u8 ht40PowerIncForPdadc;
362
+	u8 bswAtten[AR5416_MAX_CHAINS];
363
+	u8 bswMargin[AR5416_MAX_CHAINS];
364
+	u8 swSettleHt40;
365
+	u8 xatten2Db[AR5416_MAX_CHAINS];
366
+	u8 xatten2Margin[AR5416_MAX_CHAINS];
367
+	u8 ob_ch1;
368
+	u8 db_ch1;
369
+	u8 lna_ctl;
370
+	u8 miscBits;
371
+	u16 xpaBiasLvlFreq[3];
372
+	u8 futureModal[6];
373
+
374
+	struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
375
+} __attribute__((packed));
376
+
377
+struct calDataPerFreqOpLoop {
378
+	u8 pwrPdg[2][5];
379
+	u8 vpdPdg[2][5];
380
+	u8 pcdac[2][5];
381
+	u8 empty[2][5];
382
+} __attribute__((packed));
383
+
384
+struct modal_eep_4k_header {
385
+	u32 antCtrlChain[AR5416_EEP4K_MAX_CHAINS];
386
+	u32 antCtrlCommon;
387
+	u8 antennaGainCh[AR5416_EEP4K_MAX_CHAINS];
388
+	u8 switchSettling;
389
+	u8 txRxAttenCh[AR5416_EEP4K_MAX_CHAINS];
390
+	u8 rxTxMarginCh[AR5416_EEP4K_MAX_CHAINS];
391
+	u8 adcDesiredSize;
392
+	u8 pgaDesiredSize;
393
+	u8 xlnaGainCh[AR5416_EEP4K_MAX_CHAINS];
394
+	u8 txEndToXpaOff;
395
+	u8 txEndToRxOn;
396
+	u8 txFrameToXpaOn;
397
+	u8 thresh62;
398
+	u8 noiseFloorThreshCh[AR5416_EEP4K_MAX_CHAINS];
399
+	u8 xpdGain;
400
+	u8 xpd;
401
+	u8 iqCalICh[AR5416_EEP4K_MAX_CHAINS];
402
+	u8 iqCalQCh[AR5416_EEP4K_MAX_CHAINS];
403
+	u8 pdGainOverlap;
404
+#ifdef __BIG_ENDIAN_BITFIELD
405
+	u8 ob_1:4, ob_0:4;
406
+	u8 db1_1:4, db1_0:4;
407
+#else
408
+	u8 ob_0:4, ob_1:4;
409
+	u8 db1_0:4, db1_1:4;
410
+#endif
411
+	u8 xpaBiasLvl;
412
+	u8 txFrameToDataStart;
413
+	u8 txFrameToPaOn;
414
+	u8 ht40PowerIncForPdadc;
415
+	u8 bswAtten[AR5416_EEP4K_MAX_CHAINS];
416
+	u8 bswMargin[AR5416_EEP4K_MAX_CHAINS];
417
+	u8 swSettleHt40;
418
+	u8 xatten2Db[AR5416_EEP4K_MAX_CHAINS];
419
+	u8 xatten2Margin[AR5416_EEP4K_MAX_CHAINS];
420
+#ifdef __BIG_ENDIAN_BITFIELD
421
+	u8 db2_1:4, db2_0:4;
422
+#else
423
+	u8 db2_0:4, db2_1:4;
424
+#endif
425
+	u8 version;
426
+#ifdef __BIG_ENDIAN_BITFIELD
427
+	u8 ob_3:4, ob_2:4;
428
+	u8 antdiv_ctl1:4, ob_4:4;
429
+	u8 db1_3:4, db1_2:4;
430
+	u8 antdiv_ctl2:4, db1_4:4;
431
+	u8 db2_2:4, db2_3:4;
432
+	u8 reserved:4, db2_4:4;
433
+#else
434
+	u8 ob_2:4, ob_3:4;
435
+	u8 ob_4:4, antdiv_ctl1:4;
436
+	u8 db1_2:4, db1_3:4;
437
+	u8 db1_4:4, antdiv_ctl2:4;
438
+	u8 db2_2:4, db2_3:4;
439
+	u8 db2_4:4, reserved:4;
440
+#endif
441
+	u8 tx_diversity;
442
+	u8 flc_pwr_thresh;
443
+	u8 bb_scale_smrt_antenna;
444
+#define EEP_4K_BB_DESIRED_SCALE_MASK	0x1f
445
+	u8 futureModal[1];
446
+	struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
447
+} __attribute__((packed));
448
+
449
+struct base_eep_ar9287_header {
450
+	u16 length;
451
+	u16 checksum;
452
+	u16 version;
453
+	u8 opCapFlags;
454
+	u8 eepMisc;
455
+	u16 regDmn[2];
456
+	u8 macAddr[6];
457
+	u8 rxMask;
458
+	u8 txMask;
459
+	u16 rfSilent;
460
+	u16 blueToothOptions;
461
+	u16 deviceCap;
462
+	u32 binBuildNumber;
463
+	u8 deviceType;
464
+	u8 openLoopPwrCntl;
465
+	int8_t pwrTableOffset;
466
+	int8_t tempSensSlope;
467
+	int8_t tempSensSlopePalOn;
468
+	u8 futureBase[29];
469
+} __attribute__((packed));
470
+
471
+struct modal_eep_ar9287_header {
472
+	u32 antCtrlChain[AR9287_MAX_CHAINS];
473
+	u32 antCtrlCommon;
474
+	int8_t antennaGainCh[AR9287_MAX_CHAINS];
475
+	u8 switchSettling;
476
+	u8 txRxAttenCh[AR9287_MAX_CHAINS];
477
+	u8 rxTxMarginCh[AR9287_MAX_CHAINS];
478
+	int8_t adcDesiredSize;
479
+	u8 txEndToXpaOff;
480
+	u8 txEndToRxOn;
481
+	u8 txFrameToXpaOn;
482
+	u8 thresh62;
483
+	int8_t noiseFloorThreshCh[AR9287_MAX_CHAINS];
484
+	u8 xpdGain;
485
+	u8 xpd;
486
+	int8_t iqCalICh[AR9287_MAX_CHAINS];
487
+	int8_t iqCalQCh[AR9287_MAX_CHAINS];
488
+	u8 pdGainOverlap;
489
+	u8 xpaBiasLvl;
490
+	u8 txFrameToDataStart;
491
+	u8 txFrameToPaOn;
492
+	u8 ht40PowerIncForPdadc;
493
+	u8 bswAtten[AR9287_MAX_CHAINS];
494
+	u8 bswMargin[AR9287_MAX_CHAINS];
495
+	u8 swSettleHt40;
496
+	u8 version;
497
+	u8 db1;
498
+	u8 db2;
499
+	u8 ob_cck;
500
+	u8 ob_psk;
501
+	u8 ob_qam;
502
+	u8 ob_pal_off;
503
+	u8 futureModal[30];
504
+	struct spur_chan spurChans[AR_EEPROM_MODAL_SPURS];
505
+} __attribute__((packed));
506
+
507
+struct cal_data_per_freq {
508
+	u8 pwrPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
509
+	u8 vpdPdg[AR5416_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
510
+} __attribute__((packed));
511
+
512
+struct cal_data_per_freq_4k {
513
+	u8 pwrPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
514
+	u8 vpdPdg[AR5416_EEP4K_NUM_PD_GAINS][AR5416_PD_GAIN_ICEPTS];
515
+} __attribute__((packed));
516
+
517
+struct cal_target_power_leg {
518
+	u8 bChannel;
519
+	u8 tPow2x[4];
520
+} __attribute__((packed));
521
+
522
+struct cal_target_power_ht {
523
+	u8 bChannel;
524
+	u8 tPow2x[8];
525
+} __attribute__((packed));
526
+
527
+struct cal_ctl_edges {
528
+	u8 bChannel;
529
+	u8 ctl;
530
+} __attribute__((packed));
531
+
532
+struct cal_data_op_loop_ar9287 {
533
+	u8 pwrPdg[2][5];
534
+	u8 vpdPdg[2][5];
535
+	u8 pcdac[2][5];
536
+	u8 empty[2][5];
537
+} __attribute__((packed));
538
+
539
+struct cal_data_per_freq_ar9287 {
540
+	u8 pwrPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
541
+	u8 vpdPdg[AR5416_NUM_PD_GAINS][AR9287_PD_GAIN_ICEPTS];
542
+} __attribute__((packed));
543
+
544
+union cal_data_per_freq_ar9287_u {
545
+	struct cal_data_op_loop_ar9287 calDataOpen;
546
+	struct cal_data_per_freq_ar9287 calDataClose;
547
+} __attribute__((packed));
548
+
549
+struct cal_ctl_data_ar9287 {
550
+	struct cal_ctl_edges
551
+	ctlEdges[AR9287_MAX_CHAINS][AR9287_NUM_BAND_EDGES];
552
+} __attribute__((packed));
553
+
554
+struct cal_ctl_data {
555
+	struct cal_ctl_edges
556
+	ctlEdges[AR5416_MAX_CHAINS][AR5416_NUM_BAND_EDGES];
557
+} __attribute__((packed));
558
+
559
+struct cal_ctl_data_4k {
560
+	struct cal_ctl_edges
561
+	ctlEdges[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_BAND_EDGES];
562
+} __attribute__((packed));
563
+
564
+struct ar5416_eeprom_def {
565
+	struct base_eep_header baseEepHeader;
566
+	u8 custData[64];
567
+	struct modal_eep_header modalHeader[2];
568
+	u8 calFreqPier5G[AR5416_NUM_5G_CAL_PIERS];
569
+	u8 calFreqPier2G[AR5416_NUM_2G_CAL_PIERS];
570
+	struct cal_data_per_freq
571
+	 calPierData5G[AR5416_MAX_CHAINS][AR5416_NUM_5G_CAL_PIERS];
572
+	struct cal_data_per_freq
573
+	 calPierData2G[AR5416_MAX_CHAINS][AR5416_NUM_2G_CAL_PIERS];
574
+	struct cal_target_power_leg
575
+	 calTargetPower5G[AR5416_NUM_5G_20_TARGET_POWERS];
576
+	struct cal_target_power_ht
577
+	 calTargetPower5GHT20[AR5416_NUM_5G_20_TARGET_POWERS];
578
+	struct cal_target_power_ht
579
+	 calTargetPower5GHT40[AR5416_NUM_5G_40_TARGET_POWERS];
580
+	struct cal_target_power_leg
581
+	 calTargetPowerCck[AR5416_NUM_2G_CCK_TARGET_POWERS];
582
+	struct cal_target_power_leg
583
+	 calTargetPower2G[AR5416_NUM_2G_20_TARGET_POWERS];
584
+	struct cal_target_power_ht
585
+	 calTargetPower2GHT20[AR5416_NUM_2G_20_TARGET_POWERS];
586
+	struct cal_target_power_ht
587
+	 calTargetPower2GHT40[AR5416_NUM_2G_40_TARGET_POWERS];
588
+	u8 ctlIndex[AR5416_NUM_CTLS];
589
+	struct cal_ctl_data ctlData[AR5416_NUM_CTLS];
590
+	u8 padding;
591
+} __attribute__((packed));
592
+
593
+struct ar5416_eeprom_4k {
594
+	struct base_eep_header_4k baseEepHeader;
595
+	u8 custData[20];
596
+	struct modal_eep_4k_header modalHeader;
597
+	u8 calFreqPier2G[AR5416_EEP4K_NUM_2G_CAL_PIERS];
598
+	struct cal_data_per_freq_4k
599
+	calPierData2G[AR5416_EEP4K_MAX_CHAINS][AR5416_EEP4K_NUM_2G_CAL_PIERS];
600
+	struct cal_target_power_leg
601
+	calTargetPowerCck[AR5416_EEP4K_NUM_2G_CCK_TARGET_POWERS];
602
+	struct cal_target_power_leg
603
+	calTargetPower2G[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
604
+	struct cal_target_power_ht
605
+	calTargetPower2GHT20[AR5416_EEP4K_NUM_2G_20_TARGET_POWERS];
606
+	struct cal_target_power_ht
607
+	calTargetPower2GHT40[AR5416_EEP4K_NUM_2G_40_TARGET_POWERS];
608
+	u8 ctlIndex[AR5416_EEP4K_NUM_CTLS];
609
+	struct cal_ctl_data_4k ctlData[AR5416_EEP4K_NUM_CTLS];
610
+	u8 padding;
611
+} __attribute__((packed));
612
+
613
+struct ar9287_eeprom {
614
+	struct base_eep_ar9287_header baseEepHeader;
615
+	u8 custData[AR9287_DATA_SZ];
616
+	struct modal_eep_ar9287_header modalHeader;
617
+	u8 calFreqPier2G[AR9287_NUM_2G_CAL_PIERS];
618
+	union cal_data_per_freq_ar9287_u
619
+	calPierData2G[AR9287_MAX_CHAINS][AR9287_NUM_2G_CAL_PIERS];
620
+	struct cal_target_power_leg
621
+	calTargetPowerCck[AR9287_NUM_2G_CCK_TARGET_POWERS];
622
+	struct cal_target_power_leg
623
+	calTargetPower2G[AR9287_NUM_2G_20_TARGET_POWERS];
624
+	struct cal_target_power_ht
625
+	calTargetPower2GHT20[AR9287_NUM_2G_20_TARGET_POWERS];
626
+	struct cal_target_power_ht
627
+	calTargetPower2GHT40[AR9287_NUM_2G_40_TARGET_POWERS];
628
+	u8 ctlIndex[AR9287_NUM_CTLS];
629
+	struct cal_ctl_data_ar9287 ctlData[AR9287_NUM_CTLS];
630
+	u8 padding;
631
+} __attribute__((packed));
632
+
633
+enum reg_ext_bitmap {
634
+	REG_EXT_FCC_MIDBAND = 0,
635
+	REG_EXT_JAPAN_MIDBAND = 1,
636
+	REG_EXT_FCC_DFS_HT40 = 2,
637
+	REG_EXT_JAPAN_NONDFS_HT40 = 3,
638
+	REG_EXT_JAPAN_DFS_HT40 = 4
639
+};
640
+
641
+struct ath9k_country_entry {
642
+	u16 countryCode;
643
+	u16 regDmnEnum;
644
+	u16 regDmn5G;
645
+	u16 regDmn2G;
646
+	u8 isMultidomain;
647
+	u8 iso[3];
648
+};
649
+
650
+struct eeprom_ops {
651
+	int (*check_eeprom)(struct ath_hw *hw);
652
+	u32 (*get_eeprom)(struct ath_hw *hw, enum eeprom_param param);
653
+	int (*fill_eeprom)(struct ath_hw *hw);
654
+	int (*get_eeprom_ver)(struct ath_hw *hw);
655
+	int (*get_eeprom_rev)(struct ath_hw *hw);
656
+	void (*set_board_values)(struct ath_hw *hw, struct ath9k_channel *chan);
657
+	void (*set_addac)(struct ath_hw *hw, struct ath9k_channel *chan);
658
+	void (*set_txpower)(struct ath_hw *hw, struct ath9k_channel *chan,
659
+			   u16 cfgCtl, u8 twiceAntennaReduction,
660
+			   u8 twiceMaxRegulatoryPower, u8 powerLimit,
661
+			   int test);
662
+	u16 (*get_spur_channel)(struct ath_hw *ah, u16 i, int is2GHz);
663
+};
664
+
665
+void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val);
666
+void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
667
+			       u32 shift, u32 val);
668
+int16_t ath9k_hw_interpolate(u16 target, u16 srcLeft, u16 srcRight,
669
+			     int16_t targetLeft,
670
+			     int16_t targetRight);
671
+int ath9k_hw_get_lower_upper_index(u8 target, u8 *pList, u16 listSize,
672
+				    u16 *indexL, u16 *indexR);
673
+int ath9k_hw_nvram_read(struct ath_common *common, u32 off, u16 *data);
674
+void ath9k_hw_usb_gen_fill_eeprom(struct ath_hw *ah, u16 *eep_data,
675
+				  int eep_start_loc, int size);
676
+void ath9k_hw_fill_vpd_table(u8 pwrMin, u8 pwrMax, u8 *pPwrList,
677
+			     u8 *pVpdList, u16 numIntercepts,
678
+			     u8 *pRetVpdList);
679
+void ath9k_hw_get_legacy_target_powers(struct ath_hw *ah,
680
+				       struct ath9k_channel *chan,
681
+				       struct cal_target_power_leg *powInfo,
682
+				       u16 numChannels,
683
+				       struct cal_target_power_leg *pNewPower,
684
+				       u16 numRates, int isExtTarget);
685
+void ath9k_hw_get_target_powers(struct ath_hw *ah,
686
+				struct ath9k_channel *chan,
687
+				struct cal_target_power_ht *powInfo,
688
+				u16 numChannels,
689
+				struct cal_target_power_ht *pNewPower,
690
+				u16 numRates, int isHt40Target);
691
+u16 ath9k_hw_get_max_edge_power(u16 freq, struct cal_ctl_edges *pRdEdgesPower,
692
+				int is2GHz, int num_band_edges);
693
+void ath9k_hw_update_regulatory_maxpower(struct ath_hw *ah);
694
+int ath9k_hw_eeprom_init(struct ath_hw *ah);
695
+
696
+void ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hw *ah,
697
+				struct ath9k_channel *chan,
698
+				void *pRawDataSet,
699
+				u8 *bChans, u16 availPiers,
700
+				u16 tPdGainOverlap,
701
+				u16 *pPdGainBoundaries, u8 *pPDADCValues,
702
+				u16 numXpdGains);
703
+
704
+#define ar5416_get_ntxchains(_txchainmask)			\
705
+	(((_txchainmask >> 2) & 1) +                            \
706
+	 ((_txchainmask >> 1) & 1) + (_txchainmask & 1))
707
+
708
+extern const struct eeprom_ops eep_def_ops;
709
+extern const struct eeprom_ops eep_4k_ops;
710
+extern const struct eeprom_ops eep_ar9287_ops;
711
+extern const struct eeprom_ops eep_ar9287_ops;
712
+extern const struct eeprom_ops eep_ar9300_ops;
713
+
714
+#endif /* EEPROM_H */

+ 268
- 0
src/drivers/net/ath/ath9k/hw-ops.h View File

@@ -0,0 +1,268 @@
1
+/*
2
+ * Copyright (c) 2010-2011 Atheros Communications Inc.
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+#ifndef ATH9K_HW_OPS_H
18
+#define ATH9K_HW_OPS_H
19
+
20
+#include "hw.h"
21
+
22
+/* Hardware core and driver accessible callbacks */
23
+
24
+static inline void ath9k_hw_configpcipowersave(struct ath_hw *ah,
25
+					       int restore,
26
+					       int power_off)
27
+{
28
+	ath9k_hw_ops(ah)->config_pci_powersave(ah, restore, power_off);
29
+}
30
+
31
+static inline void ath9k_hw_rxena(struct ath_hw *ah)
32
+{
33
+	ath9k_hw_ops(ah)->rx_enable(ah);
34
+}
35
+
36
+static inline void ath9k_hw_set_desc_link(struct ath_hw *ah, void *ds,
37
+					  u32 link)
38
+{
39
+	ath9k_hw_ops(ah)->set_desc_link(ds, link);
40
+}
41
+
42
+static inline void ath9k_hw_get_desc_link(struct ath_hw *ah, void *ds,
43
+					  u32 **link)
44
+{
45
+	ath9k_hw_ops(ah)->get_desc_link(ds, link);
46
+}
47
+static inline int ath9k_hw_calibrate(struct ath_hw *ah,
48
+				      struct ath9k_channel *chan,
49
+				      u8 rxchainmask,
50
+				      int longcal)
51
+{
52
+	return ath9k_hw_ops(ah)->calibrate(ah, chan, rxchainmask, longcal);
53
+}
54
+
55
+static inline int ath9k_hw_getisr(struct ath_hw *ah, enum ath9k_int *masked)
56
+{
57
+	return ath9k_hw_ops(ah)->get_isr(ah, masked);
58
+}
59
+
60
+static inline void ath9k_hw_filltxdesc(struct ath_hw *ah, void *ds, u32 seglen,
61
+				  int is_firstseg, int is_lastseg,
62
+				  const void *ds0, u32 buf_addr,
63
+				  unsigned int qcu)
64
+{
65
+	ath9k_hw_ops(ah)->fill_txdesc(ah, ds, seglen, is_firstseg, is_lastseg,
66
+				      ds0, buf_addr, qcu);
67
+}
68
+
69
+static inline int ath9k_hw_txprocdesc(struct ath_hw *ah, void *ds,
70
+				      struct ath_tx_status *ts)
71
+{
72
+	return ath9k_hw_ops(ah)->proc_txdesc(ah, ds, ts);
73
+}
74
+
75
+static inline void ath9k_hw_set11n_txdesc(struct ath_hw *ah, void *ds,
76
+					  u32 pktLen, enum ath9k_pkt_type type,
77
+					  u32 txPower, u32 keyIx,
78
+					  enum ath9k_key_type keyType,
79
+					  u32 flags)
80
+{
81
+	ath9k_hw_ops(ah)->set11n_txdesc(ah, ds, pktLen, type, txPower, keyIx,
82
+				      keyType, flags);
83
+}
84
+
85
+static inline void ath9k_hw_set11n_ratescenario(struct ath_hw *ah, void *ds,
86
+					void *lastds,
87
+					u32 durUpdateEn, u32 rtsctsRate,
88
+					u32 rtsctsDuration,
89
+					struct ath9k_11n_rate_series series[],
90
+					u32 nseries, u32 flags)
91
+{
92
+	ath9k_hw_ops(ah)->set11n_ratescenario(ah, ds, lastds, durUpdateEn,
93
+					    rtsctsRate, rtsctsDuration, series,
94
+					    nseries, flags);
95
+}
96
+
97
+static inline void ath9k_hw_set11n_aggr_first(struct ath_hw *ah, void *ds,
98
+					u32 aggrLen)
99
+{
100
+	ath9k_hw_ops(ah)->set11n_aggr_first(ah, ds, aggrLen);
101
+}
102
+
103
+static inline void ath9k_hw_set11n_aggr_middle(struct ath_hw *ah, void *ds,
104
+					       u32 numDelims)
105
+{
106
+	ath9k_hw_ops(ah)->set11n_aggr_middle(ah, ds, numDelims);
107
+}
108
+
109
+static inline void ath9k_hw_set11n_aggr_last(struct ath_hw *ah, void *ds)
110
+{
111
+	ath9k_hw_ops(ah)->set11n_aggr_last(ah, ds);
112
+}
113
+
114
+static inline void ath9k_hw_clr11n_aggr(struct ath_hw *ah, void *ds)
115
+{
116
+	ath9k_hw_ops(ah)->clr11n_aggr(ah, ds);
117
+}
118
+
119
+static inline void ath9k_hw_set_clrdmask(struct ath_hw *ah, void *ds, int val)
120
+{
121
+	ath9k_hw_ops(ah)->set_clrdmask(ah, ds, val);
122
+}
123
+
124
+static inline void ath9k_hw_antdiv_comb_conf_get(struct ath_hw *ah,
125
+		struct ath_hw_antcomb_conf *antconf)
126
+{
127
+	ath9k_hw_ops(ah)->antdiv_comb_conf_get(ah, antconf);
128
+}
129
+
130
+static inline void ath9k_hw_antdiv_comb_conf_set(struct ath_hw *ah,
131
+		struct ath_hw_antcomb_conf *antconf)
132
+{
133
+	ath9k_hw_ops(ah)->antdiv_comb_conf_set(ah, antconf);
134
+}
135
+
136
+/* Private hardware call ops */
137
+
138
+/* PHY ops */
139
+
140
+static inline int ath9k_hw_rf_set_freq(struct ath_hw *ah,
141
+				       struct ath9k_channel *chan)
142
+{
143
+	return ath9k_hw_private_ops(ah)->rf_set_freq(ah, chan);
144
+}
145
+
146
+static inline void ath9k_hw_spur_mitigate_freq(struct ath_hw *ah,
147
+					       struct ath9k_channel *chan)
148
+{
149
+	ath9k_hw_private_ops(ah)->spur_mitigate_freq(ah, chan);
150
+}
151
+
152
+static inline int ath9k_hw_rf_alloc_ext_banks(struct ath_hw *ah)
153
+{
154
+	if (!ath9k_hw_private_ops(ah)->rf_alloc_ext_banks)
155
+		return 0;
156
+
157
+	return ath9k_hw_private_ops(ah)->rf_alloc_ext_banks(ah);
158
+}
159
+
160
+static inline void ath9k_hw_rf_free_ext_banks(struct ath_hw *ah)
161
+{
162
+	if (!ath9k_hw_private_ops(ah)->rf_free_ext_banks)
163
+		return;
164
+
165
+	ath9k_hw_private_ops(ah)->rf_free_ext_banks(ah);
166
+}
167
+
168
+static inline int ath9k_hw_set_rf_regs(struct ath_hw *ah,
169
+					struct ath9k_channel *chan,
170
+					u16 modesIndex)
171
+{
172
+	if (!ath9k_hw_private_ops(ah)->set_rf_regs)
173
+		return 1;
174
+
175
+	return ath9k_hw_private_ops(ah)->set_rf_regs(ah, chan, modesIndex);
176
+}
177
+
178
+static inline void ath9k_hw_init_bb(struct ath_hw *ah,
179
+				    struct ath9k_channel *chan)
180
+{
181
+	return ath9k_hw_private_ops(ah)->init_bb(ah, chan);
182
+}
183
+
184
+static inline void ath9k_hw_set_channel_regs(struct ath_hw *ah,
185
+					     struct ath9k_channel *chan)
186
+{
187
+	return ath9k_hw_private_ops(ah)->set_channel_regs(ah, chan);
188
+}
189
+
190
+static inline int ath9k_hw_process_ini(struct ath_hw *ah,
191
+					struct ath9k_channel *chan)
192
+{
193
+	return ath9k_hw_private_ops(ah)->process_ini(ah, chan);
194
+}
195
+
196
+static inline void ath9k_olc_init(struct ath_hw *ah)
197
+{
198
+	if (!ath9k_hw_private_ops(ah)->olc_init)
199
+		return;
200
+
201
+	return ath9k_hw_private_ops(ah)->olc_init(ah);
202
+}
203
+
204
+static inline void ath9k_hw_set_rfmode(struct ath_hw *ah,
205
+				       struct ath9k_channel *chan)
206
+{
207
+	return ath9k_hw_private_ops(ah)->set_rfmode(ah, chan);
208
+}
209
+
210
+static inline void ath9k_hw_mark_phy_inactive(struct ath_hw *ah)
211
+{
212
+	return ath9k_hw_private_ops(ah)->mark_phy_inactive(ah);
213
+}
214
+
215
+static inline void ath9k_hw_set_delta_slope(struct ath_hw *ah,
216
+					    struct ath9k_channel *chan)
217
+{
218
+	return ath9k_hw_private_ops(ah)->set_delta_slope(ah, chan);
219
+}
220
+
221
+static inline int ath9k_hw_rfbus_req(struct ath_hw *ah)
222
+{
223
+	return ath9k_hw_private_ops(ah)->rfbus_req(ah);
224
+}
225
+
226
+static inline void ath9k_hw_rfbus_done(struct ath_hw *ah)
227
+{
228
+	return ath9k_hw_private_ops(ah)->rfbus_done(ah);
229
+}
230
+
231
+static inline void ath9k_hw_restore_chainmask(struct ath_hw *ah)
232
+{
233
+	if (!ath9k_hw_private_ops(ah)->restore_chainmask)
234
+		return;
235
+
236
+	return ath9k_hw_private_ops(ah)->restore_chainmask(ah);
237
+}
238
+
239
+static inline void ath9k_hw_set_diversity(struct ath_hw *ah, int value)
240
+{
241
+	return ath9k_hw_private_ops(ah)->set_diversity(ah, value);
242
+}
243
+
244
+static inline int ath9k_hw_ani_control(struct ath_hw *ah,
245
+					enum ath9k_ani_cmd cmd, int param)
246
+{
247
+	return ath9k_hw_private_ops(ah)->ani_control(ah, cmd, param);
248
+}
249
+
250
+static inline void ath9k_hw_do_getnf(struct ath_hw *ah,
251
+				     int16_t nfarray[NUM_NF_READINGS])
252
+{
253
+	ath9k_hw_private_ops(ah)->do_getnf(ah, nfarray);
254
+}
255
+
256
+static inline int ath9k_hw_init_cal(struct ath_hw *ah,
257
+				     struct ath9k_channel *chan)
258
+{
259
+	return ath9k_hw_private_ops(ah)->init_cal(ah, chan);
260
+}
261
+
262
+static inline void ath9k_hw_setup_calibration(struct ath_hw *ah,
263
+					      struct ath9k_cal_list *currCal)
264
+{
265
+	ath9k_hw_private_ops(ah)->setup_calibration(ah, currCal);
266
+}
267
+
268
+#endif /* ATH9K_HW_OPS_H */

+ 995
- 0
src/drivers/net/ath/ath9k/hw.h View File

@@ -0,0 +1,995 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef HW_H
21
+#define HW_H
22
+
23
+#include <errno.h>
24
+
25
+#include "mac.h"
26
+#include "ani.h"
27
+#include "eeprom.h"
28
+#include "calib.h"
29
+#include "reg.h"
30
+#include "phy.h"
31
+
32
+#include "../regd.h"
33
+
34
+/* Keep all ath9k files under one errfile ID */
35
+#undef ERRFILE
36
+#define ERRFILE ERRFILE_ath9k
37
+
38
+#define ATHEROS_VENDOR_ID	0x168c
39
+
40
+#define AR5416_DEVID_PCI	0x0023
41
+#define AR5416_DEVID_PCIE	0x0024
42
+#define AR9160_DEVID_PCI	0x0027
43
+#define AR9280_DEVID_PCI	0x0029
44
+#define AR9280_DEVID_PCIE	0x002a
45
+#define AR9285_DEVID_PCIE	0x002b
46
+#define AR2427_DEVID_PCIE	0x002c
47
+#define AR9287_DEVID_PCI	0x002d
48
+#define AR9287_DEVID_PCIE	0x002e
49
+#define AR9300_DEVID_PCIE	0x0030
50
+#define AR9300_DEVID_AR9340	0x0031
51
+#define AR9300_DEVID_AR9485_PCIE 0x0032
52
+
53
+#define AR5416_AR9100_DEVID	0x000b
54
+
55
+#define	AR_SUBVENDOR_ID_NOG	0x0e11
56
+#define AR_SUBVENDOR_ID_NEW_A	0x7065
57
+#define AR5416_MAGIC		0x19641014
58
+
59
+#define AR9280_COEX2WIRE_SUBSYSID	0x309b
60
+#define AT9285_COEX3WIRE_SA_SUBSYSID	0x30aa
61
+#define AT9285_COEX3WIRE_DA_SUBSYSID	0x30ab
62
+
63
+#define AR9300_NUM_BT_WEIGHTS   4
64
+#define AR9300_NUM_WLAN_WEIGHTS 4
65
+
66
+#define ATH_AMPDU_LIMIT_MAX        (64 * 1024 - 1)
67
+
68
+#define	ATH_DEFAULT_NOISE_FLOOR -95
69
+
70
+#define ATH9K_RSSI_BAD			-128
71
+
72
+#define ATH9K_NUM_CHANNELS	38
73
+
74
+/* Register read/write primitives */
75
+#define REG_WRITE(_ah, _reg, _val) \
76
+	(_ah)->reg_ops.write((_ah), (_val), (_reg))
77
+
78
+#define REG_READ(_ah, _reg) \
79
+	(_ah)->reg_ops.read((_ah), (_reg))
80
+
81
+#define REG_READ_MULTI(_ah, _addr, _val, _cnt)		\
82
+	(_ah)->reg_ops.multi_read((_ah), (_addr), (_val), (_cnt))
83
+
84
+#define REG_RMW(_ah, _reg, _set, _clr) \
85
+	(_ah)->reg_ops.rmw((_ah), (_reg), (_set), (_clr))
86
+
87
+#define ENABLE_REGWRITE_BUFFER(_ah)					\
88
+	do {								\
89
+		if ((_ah)->reg_ops.enable_write_buffer)	\
90
+			(_ah)->reg_ops.enable_write_buffer((_ah)); \
91
+	} while (0)
92
+
93
+#define REGWRITE_BUFFER_FLUSH(_ah)					\
94
+	do {								\
95
+		if ((_ah)->reg_ops.write_flush)		\
96
+			(_ah)->reg_ops.write_flush((_ah));	\
97
+	} while (0)
98
+
99
+#define SM(_v, _f)  (((_v) << _f##_S) & _f)
100
+#define MS(_v, _f)  (((_v) & _f) >> _f##_S)
101
+#define REG_RMW_FIELD(_a, _r, _f, _v) \
102
+	REG_RMW(_a, _r, (((_v) << _f##_S) & _f), (_f))
103
+#define REG_READ_FIELD(_a, _r, _f) \
104
+	(((REG_READ(_a, _r) & _f) >> _f##_S))
105
+#define REG_SET_BIT(_a, _r, _f) \
106
+	REG_RMW(_a, _r, (_f), 0)
107
+#define REG_CLR_BIT(_a, _r, _f) \
108
+	REG_RMW(_a, _r, 0, (_f))
109
+
110
+#define DO_DELAY(x) do {					\
111
+		if (((++(x) % 64) == 0) &&			\
112
+		    (ath9k_hw_common(ah)->bus_ops->ath_bus_type	\
113
+			!= ATH_USB))				\
114
+			udelay(1);				\
115
+	} while (0)
116
+
117
+#define REG_WRITE_ARRAY(iniarray, column, regWr) \
118
+	ath9k_hw_write_array(ah, iniarray, column, &(regWr))
119
+
120
+#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT             0
121
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
122
+#define AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED     2
123
+#define AR_GPIO_OUTPUT_MUX_AS_TX_FRAME           3
124
+#define AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL  4
125
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED    5
126
+#define AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED      6
127
+
128
+#define AR_GPIOD_MASK               0x00001FFF
129
+#define AR_GPIO_BIT(_gpio)          (1 << (_gpio))
130
+
131
+#define BASE_ACTIVATE_DELAY         100
132
+#define RTC_PLL_SETTLE_DELAY        (AR_SREV_9340(ah) ? 1000 : 100)
133
+#define COEF_SCALE_S                24
134
+#define HT40_CHANNEL_CENTER_SHIFT   10
135
+
136
+#define ATH9K_ANTENNA0_CHAINMASK    0x1
137
+#define ATH9K_ANTENNA1_CHAINMASK    0x2
138
+
139
+#define ATH9K_NUM_DMA_DEBUG_REGS    8
140
+#define ATH9K_NUM_QUEUES            10
141
+
142
+#define MAX_RATE_POWER              63
143
+#define AH_WAIT_TIMEOUT             100000 /* (us) */
144
+#define AH_TSF_WRITE_TIMEOUT        100    /* (us) */
145
+#define AH_TIME_QUANTUM             10
146
+#define AR_KEYTABLE_SIZE            128
147
+#define POWER_UP_TIME               10000
148
+#define SPUR_RSSI_THRESH            40
149
+
150
+#define CAB_TIMEOUT_VAL             10
151
+#define BEACON_TIMEOUT_VAL          10
152
+#define MIN_BEACON_TIMEOUT_VAL      1
153
+#define SLEEP_SLOP                  3
154
+
155
+#define INIT_CONFIG_STATUS          0x00000000
156
+#define INIT_RSSI_THR               0x00000700
157
+#define INIT_BCON_CNTRL_REG         0x00000000
158
+
159
+#define TU_TO_USEC(_tu)             ((_tu) << 10)
160
+
161
+#define ATH9K_HW_RX_HP_QDEPTH	16
162
+#define ATH9K_HW_RX_LP_QDEPTH	128
163
+
164
+#define PAPRD_GAIN_TABLE_ENTRIES    32
165
+#define PAPRD_TABLE_SZ              24
166
+
167
+enum ath_hw_txq_subtype {
168
+	ATH_TXQ_AC_BE = 0,
169
+};
170
+
171
+enum ath_ini_subsys {
172
+	ATH_INI_PRE = 0,
173
+	ATH_INI_CORE,
174
+	ATH_INI_POST,
175
+	ATH_INI_NUM_SPLIT,
176
+};
177
+
178
+enum ath9k_hw_caps {
179
+	ATH9K_HW_CAP_HT                         = BIT(0),
180
+	ATH9K_HW_CAP_RFSILENT                   = BIT(1),
181
+	ATH9K_HW_CAP_CST                        = BIT(2),
182
+	ATH9K_HW_CAP_AUTOSLEEP                  = BIT(4),
183
+	ATH9K_HW_CAP_4KB_SPLITTRANS             = BIT(5),
184
+	ATH9K_HW_CAP_EDMA			= BIT(6),
185
+	ATH9K_HW_CAP_RAC_SUPPORTED		= BIT(7),
186
+	ATH9K_HW_CAP_LDPC			= BIT(8),
187
+	ATH9K_HW_CAP_FASTCLOCK			= BIT(9),
188
+	ATH9K_HW_CAP_SGI_20			= BIT(10),
189
+	ATH9K_HW_CAP_PAPRD			= BIT(11),
190
+	ATH9K_HW_CAP_ANT_DIV_COMB		= BIT(12),
191
+	ATH9K_HW_CAP_2GHZ			= BIT(13),
192
+	ATH9K_HW_CAP_5GHZ			= BIT(14),
193
+	ATH9K_HW_CAP_APM			= BIT(15),
194
+};
195
+
196
+struct ath9k_hw_capabilities {
197
+	u32 hw_caps; /* ATH9K_HW_CAP_* from ath9k_hw_caps */
198
+	u16 rts_aggr_limit;
199
+	u8 tx_chainmask;
200
+	u8 rx_chainmask;
201
+	u8 max_txchains;
202
+	u8 max_rxchains;
203
+	u8 num_gpio_pins;
204
+	u8 rx_hp_qdepth;
205
+	u8 rx_lp_qdepth;
206
+	u8 rx_status_len;
207
+	u8 tx_desc_len;
208
+	u8 txs_len;
209
+	u16 pcie_lcr_offset;
210
+	int pcie_lcr_extsync_en;
211
+};
212
+
213
+struct ath9k_ops_config {
214
+	int dma_beacon_response_time;
215
+	int sw_beacon_response_time;
216
+	int additional_swba_backoff;
217
+	int ack_6mb;
218
+	u32 cwm_ignore_extcca;
219
+	u8 pcie_powersave_enable;
220
+	int pcieSerDesWrite;
221
+	u8 pcie_clock_req;
222
+	u32 pcie_waen;
223
+	u8 analog_shiftreg;
224
+	u8 paprd_disable;
225
+	u32 ofdm_trig_low;
226
+	u32 ofdm_trig_high;
227
+	u32 cck_trig_high;
228
+	u32 cck_trig_low;
229
+	u32 enable_ani;
230
+	int serialize_regmode;
231
+	int rx_intr_mitigation;
232
+	int tx_intr_mitigation;
233
+#define SPUR_DISABLE        	0
234
+#define SPUR_ENABLE_IOCTL   	1
235
+#define SPUR_ENABLE_EEPROM  	2
236
+#define AR_SPUR_5413_1      	1640
237
+#define AR_SPUR_5413_2      	1200
238
+#define AR_NO_SPUR      	0x8000
239
+#define AR_BASE_FREQ_2GHZ   	2300
240
+#define AR_BASE_FREQ_5GHZ   	4900
241
+#define AR_SPUR_FEEQ_BOUND_HT40 19
242
+#define AR_SPUR_FEEQ_BOUND_HT20 10
243
+	int spurmode;
244
+	u16 spurchans[AR_EEPROM_MODAL_SPURS][2];
245
+	u8 max_txtrig_level;
246
+	u16 ani_poll_interval; /* ANI poll interval in ms */
247
+};
248
+
249
+enum ath9k_int {
250
+	ATH9K_INT_RX = 0x00000001,
251
+	ATH9K_INT_RXDESC = 0x00000002,
252
+	ATH9K_INT_RXHP = 0x00000001,
253
+	ATH9K_INT_RXLP = 0x00000002,
254
+	ATH9K_INT_RXNOFRM = 0x00000008,
255
+	ATH9K_INT_RXEOL = 0x00000010,
256
+	ATH9K_INT_RXORN = 0x00000020,
257
+	ATH9K_INT_TX = 0x00000040,
258
+	ATH9K_INT_TXDESC = 0x00000080,
259
+	ATH9K_INT_TIM_TIMER = 0x00000100,
260
+	ATH9K_INT_BB_WATCHDOG = 0x00000400,
261
+	ATH9K_INT_TXURN = 0x00000800,
262
+	ATH9K_INT_MIB = 0x00001000,
263
+	ATH9K_INT_RXPHY = 0x00004000,
264
+	ATH9K_INT_RXKCM = 0x00008000,
265
+	ATH9K_INT_SWBA = 0x00010000,
266
+	ATH9K_INT_BMISS = 0x00040000,
267
+	ATH9K_INT_BNR = 0x00100000,
268
+	ATH9K_INT_TIM = 0x00200000,
269
+	ATH9K_INT_DTIM = 0x00400000,
270
+	ATH9K_INT_DTIMSYNC = 0x00800000,
271
+	ATH9K_INT_GPIO = 0x01000000,
272
+	ATH9K_INT_CABEND = 0x02000000,
273
+	ATH9K_INT_TSFOOR = 0x04000000,
274
+	ATH9K_INT_GENTIMER = 0x08000000,
275
+	ATH9K_INT_CST = 0x10000000,
276
+	ATH9K_INT_GTT = 0x20000000,
277
+	ATH9K_INT_FATAL = 0x40000000,
278
+	ATH9K_INT_GLOBAL = 0x80000000,
279
+	ATH9K_INT_BMISC = ATH9K_INT_TIM |
280
+		ATH9K_INT_DTIM |
281
+		ATH9K_INT_DTIMSYNC |
282
+		ATH9K_INT_TSFOOR |
283
+		ATH9K_INT_CABEND,
284
+	ATH9K_INT_COMMON = ATH9K_INT_RXNOFRM |
285
+		ATH9K_INT_RXDESC |
286
+		ATH9K_INT_RXEOL |
287
+		ATH9K_INT_RXORN |
288
+		ATH9K_INT_TXURN |
289
+		ATH9K_INT_TXDESC |
290
+		ATH9K_INT_MIB |
291
+		ATH9K_INT_RXPHY |
292
+		ATH9K_INT_RXKCM |
293
+		ATH9K_INT_SWBA |
294
+		ATH9K_INT_BMISS |
295
+		ATH9K_INT_GPIO,
296
+	ATH9K_INT_NOCARD = 0xffffffff
297
+};
298
+
299
+#define CHANNEL_CW_INT    0x00002
300
+#define CHANNEL_CCK       0x00020
301
+#define CHANNEL_OFDM      0x00040
302
+#define CHANNEL_2GHZ      0x00080
303
+#define CHANNEL_5GHZ      0x00100
304
+#define CHANNEL_PASSIVE   0x00200
305
+#define CHANNEL_DYN       0x00400
306
+#define CHANNEL_HALF      0x04000
307
+#define CHANNEL_QUARTER   0x08000
308
+#define CHANNEL_HT20      0x10000
309
+#define CHANNEL_HT40PLUS  0x20000
310
+#define CHANNEL_HT40MINUS 0x40000
311
+
312
+#define CHANNEL_A           (CHANNEL_5GHZ|CHANNEL_OFDM)
313
+#define CHANNEL_B           (CHANNEL_2GHZ|CHANNEL_CCK)
314
+#define CHANNEL_G           (CHANNEL_2GHZ|CHANNEL_OFDM)
315
+#define CHANNEL_G_HT20      (CHANNEL_2GHZ|CHANNEL_HT20)
316
+#define CHANNEL_A_HT20      (CHANNEL_5GHZ|CHANNEL_HT20)
317
+#define CHANNEL_G_HT40PLUS  (CHANNEL_2GHZ|CHANNEL_HT40PLUS)
318
+#define CHANNEL_G_HT40MINUS (CHANNEL_2GHZ|CHANNEL_HT40MINUS)
319
+#define CHANNEL_A_HT40PLUS  (CHANNEL_5GHZ|CHANNEL_HT40PLUS)
320
+#define CHANNEL_A_HT40MINUS (CHANNEL_5GHZ|CHANNEL_HT40MINUS)
321
+#define CHANNEL_ALL				\
322
+	(CHANNEL_OFDM|				\
323
+	 CHANNEL_CCK|				\
324
+	 CHANNEL_2GHZ |				\
325
+	 CHANNEL_5GHZ |				\
326
+	 CHANNEL_HT20 |				\
327
+	 CHANNEL_HT40PLUS |			\
328
+	 CHANNEL_HT40MINUS)
329
+
330
+struct ath9k_hw_cal_data {
331
+	u16 channel;
332
+	u32 channelFlags;
333
+	int32_t CalValid;
334
+	int8_t iCoff;
335
+	int8_t qCoff;
336
+	int paprd_done;
337
+	int nfcal_pending;
338
+	int nfcal_interference;
339
+	u16 small_signal_gain[AR9300_MAX_CHAINS];
340
+	u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
341
+	struct ath9k_nfcal_hist nfCalHist[NUM_NF_READINGS];
342
+};
343
+
344
+struct ath9k_channel {
345
+	struct net80211_channel *chan;
346
+	struct ar5416AniState ani;
347
+	u16 channel;
348
+	u32 channelFlags;
349
+	u32 chanmode;
350
+	s16 noisefloor;
351
+};
352
+
353
+#define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
354
+       (((_c)->channelFlags & CHANNEL_G_HT20) == CHANNEL_G_HT20) || \
355
+       (((_c)->channelFlags & CHANNEL_G_HT40PLUS) == CHANNEL_G_HT40PLUS) || \
356
+       (((_c)->channelFlags & CHANNEL_G_HT40MINUS) == CHANNEL_G_HT40MINUS))
357
+#define IS_CHAN_OFDM(_c) (((_c)->channelFlags & CHANNEL_OFDM) != 0)
358
+#define IS_CHAN_5GHZ(_c) (((_c)->channelFlags & CHANNEL_5GHZ) != 0)
359
+#define IS_CHAN_2GHZ(_c) (((_c)->channelFlags & CHANNEL_2GHZ) != 0)
360
+#define IS_CHAN_HALF_RATE(_c) (((_c)->channelFlags & CHANNEL_HALF) != 0)
361
+#define IS_CHAN_QUARTER_RATE(_c) (((_c)->channelFlags & CHANNEL_QUARTER) != 0)
362
+#define IS_CHAN_A_FAST_CLOCK(_ah, _c)			\
363
+	((((_c)->channelFlags & CHANNEL_5GHZ) != 0) &&	\
364
+	 ((_ah)->caps.hw_caps & ATH9K_HW_CAP_FASTCLOCK))
365
+
366
+/* These macros check chanmode and not channelFlags */
367
+#define IS_CHAN_B(_c) ((_c)->chanmode == CHANNEL_B)
368
+#define IS_CHAN_HT20(_c) (((_c)->chanmode == CHANNEL_A_HT20) ||	\
369
+			  ((_c)->chanmode == CHANNEL_G_HT20))
370
+#define IS_CHAN_HT40(_c) (((_c)->chanmode == CHANNEL_A_HT40PLUS) ||	\
371
+			  ((_c)->chanmode == CHANNEL_A_HT40MINUS) ||	\
372
+			  ((_c)->chanmode == CHANNEL_G_HT40PLUS) ||	\
373
+			  ((_c)->chanmode == CHANNEL_G_HT40MINUS))
374
+#define IS_CHAN_HT(_c) (IS_CHAN_HT20((_c)) || IS_CHAN_HT40((_c)))
375
+
376
+enum ath9k_power_mode {
377
+	ATH9K_PM_AWAKE = 0,
378
+	ATH9K_PM_FULL_SLEEP,
379
+	ATH9K_PM_NETWORK_SLEEP,
380
+	ATH9K_PM_UNDEFINED
381
+};
382
+
383
+enum ath9k_tp_scale {
384
+	ATH9K_TP_SCALE_MAX = 0,
385
+	ATH9K_TP_SCALE_50,
386
+	ATH9K_TP_SCALE_25,
387
+	ATH9K_TP_SCALE_12,
388
+	ATH9K_TP_SCALE_MIN
389
+};
390
+
391
+enum ser_reg_mode {
392
+	SER_REG_MODE_OFF = 0,
393
+	SER_REG_MODE_ON = 1,
394
+	SER_REG_MODE_AUTO = 2,
395
+};
396
+
397
+enum ath9k_rx_qtype {
398
+	ATH9K_RX_QUEUE_HP,
399
+	ATH9K_RX_QUEUE_LP,
400
+	ATH9K_RX_QUEUE_MAX,
401
+};
402
+
403
+struct ath9k_beacon_state {
404
+	u32 bs_nexttbtt;
405
+	u32 bs_nextdtim;
406
+	u32 bs_intval;
407
+#define ATH9K_BEACON_PERIOD       0x0000ffff
408
+#define ATH9K_TSFOOR_THRESHOLD    0x00004240 /* 16k us */
409
+	u32 bs_dtimperiod;
410
+	u16 bs_cfpperiod;
411
+	u16 bs_cfpmaxduration;
412
+	u32 bs_cfpnext;
413
+	u16 bs_timoffset;
414
+	u16 bs_bmissthreshold;
415
+	u32 bs_sleepduration;
416
+	u32 bs_tsfoor_threshold;
417
+};
418
+
419
+struct chan_centers {
420
+	u16 synth_center;
421
+	u16 ctl_center;
422
+	u16 ext_center;
423
+};
424
+
425
+enum {
426
+	ATH9K_RESET_POWER_ON,
427
+	ATH9K_RESET_WARM,
428
+	ATH9K_RESET_COLD,
429
+};
430
+
431
+struct ath9k_hw_version {
432
+	u32 magic;
433
+	u16 devid;
434
+	u16 subvendorid;
435
+	u32 macVersion;
436
+	u16 macRev;
437
+	u16 phyRev;
438
+	u16 analog5GhzRev;
439
+	u16 analog2GhzRev;
440
+	u16 subsysid;
441
+	enum ath_usb_dev usbdev;
442
+};
443
+
444
+/* Generic TSF timer definitions */
445
+
446
+#define ATH_MAX_GEN_TIMER	16
447
+
448
+#define AR_GENTMR_BIT(_index)	(1 << (_index))
449
+
450
+/*
451
+ * Using de Bruijin sequence to look up 1's index in a 32 bit number
452
+ * debruijn32 = 0000 0111 0111 1100 1011 0101 0011 0001
453
+ */
454
+#define debruijn32 0x077CB531U
455
+
456
+struct ath_gen_timer_configuration {
457
+	u32 next_addr;
458
+	u32 period_addr;
459
+	u32 mode_addr;
460
+	u32 mode_mask;
461
+};
462
+
463
+struct ath_gen_timer {
464
+	void (*trigger)(void *arg);
465
+	void (*overflow)(void *arg);
466
+	void *arg;
467
+	u8 index;
468
+};
469
+
470
+struct ath_gen_timer_table {
471
+	u32 gen_timer_index[32];
472
+	struct ath_gen_timer *timers[ATH_MAX_GEN_TIMER];
473
+	union {
474
+		unsigned long timer_bits;
475
+		u16 val;
476
+	} timer_mask;
477
+};
478
+
479
+struct ath_hw_antcomb_conf {
480
+	u8 main_lna_conf;
481
+	u8 alt_lna_conf;
482
+	u8 fast_div_bias;
483
+	u8 main_gaintb;
484
+	u8 alt_gaintb;
485
+	int lna1_lna2_delta;
486
+	u8 div_group;
487
+};
488
+
489
+/**
490
+ * struct ath_hw_radar_conf - radar detection initialization parameters
491
+ *
492
+ * @pulse_inband: threshold for checking the ratio of in-band power
493
+ *	to total power for short radar pulses (half dB steps)
494
+ * @pulse_inband_step: threshold for checking an in-band power to total
495
+ *	power ratio increase for short radar pulses (half dB steps)
496
+ * @pulse_height: threshold for detecting the beginning of a short
497
+ *	radar pulse (dB step)
498
+ * @pulse_rssi: threshold for detecting if a short radar pulse is
499
+ *	gone (dB step)
500
+ * @pulse_maxlen: maximum pulse length (0.8 us steps)
501
+ *
502
+ * @radar_rssi: RSSI threshold for starting long radar detection (dB steps)
503
+ * @radar_inband: threshold for checking the ratio of in-band power
504
+ *	to total power for long radar pulses (half dB steps)
505
+ * @fir_power: threshold for detecting the end of a long radar pulse (dB)
506
+ *
507
+ * @ext_channel: enable extension channel radar detection
508
+ */
509
+struct ath_hw_radar_conf {
510
+	unsigned int pulse_inband;
511
+	unsigned int pulse_inband_step;
512
+	unsigned int pulse_height;
513
+	unsigned int pulse_rssi;
514
+	unsigned int pulse_maxlen;
515
+
516
+	unsigned int radar_rssi;
517
+	unsigned int radar_inband;
518
+	int fir_power;
519
+
520
+	int ext_channel;
521
+};
522
+
523
+/**
524
+ * struct ath_hw_private_ops - callbacks used internally by hardware code
525
+ *
526
+ * This structure contains private callbacks designed to only be used internally
527
+ * by the hardware core.
528
+ *
529
+ * @init_cal_settings: setup types of calibrations supported
530
+ * @init_cal: starts actual calibration
531
+ *
532
+ * @init_mode_regs: Initializes mode registers
533
+ * @init_mode_gain_regs: Initialize TX/RX gain registers
534
+ *
535
+ * @rf_set_freq: change frequency
536
+ * @spur_mitigate_freq: spur mitigation
537
+ * @rf_alloc_ext_banks:
538
+ * @rf_free_ext_banks:
539
+ * @set_rf_regs:
540
+ * @compute_pll_control: compute the PLL control value to use for
541
+ *	AR_RTC_PLL_CONTROL for a given channel
542
+ * @setup_calibration: set up calibration
543
+ * @iscal_supported: used to query if a type of calibration is supported
544
+ *
545
+ * @ani_cache_ini_regs: cache the values for ANI from the initial
546
+ *	register settings through the register initialization.
547
+ */
548
+struct ath_hw_private_ops {
549
+	/* Calibration ops */
550
+	void (*init_cal_settings)(struct ath_hw *ah);
551
+	int (*init_cal)(struct ath_hw *ah, struct ath9k_channel *chan);
552
+
553
+	void (*init_mode_regs)(struct ath_hw *ah);
554
+	void (*init_mode_gain_regs)(struct ath_hw *ah);
555
+	void (*setup_calibration)(struct ath_hw *ah,
556
+				  struct ath9k_cal_list *currCal);
557
+
558
+	/* PHY ops */
559
+	int (*rf_set_freq)(struct ath_hw *ah,
560
+			   struct ath9k_channel *chan);
561
+	void (*spur_mitigate_freq)(struct ath_hw *ah,
562
+				   struct ath9k_channel *chan);
563
+	int (*rf_alloc_ext_banks)(struct ath_hw *ah);
564
+	void (*rf_free_ext_banks)(struct ath_hw *ah);
565
+	int (*set_rf_regs)(struct ath_hw *ah,
566
+			    struct ath9k_channel *chan,
567
+			    u16 modesIndex);
568
+	void (*set_channel_regs)(struct ath_hw *ah, struct ath9k_channel *chan);
569
+	void (*init_bb)(struct ath_hw *ah,
570
+			struct ath9k_channel *chan);
571
+	int (*process_ini)(struct ath_hw *ah, struct ath9k_channel *chan);
572
+	void (*olc_init)(struct ath_hw *ah);
573
+	void (*set_rfmode)(struct ath_hw *ah, struct ath9k_channel *chan);
574
+	void (*mark_phy_inactive)(struct ath_hw *ah);
575
+	void (*set_delta_slope)(struct ath_hw *ah, struct ath9k_channel *chan);
576
+	int (*rfbus_req)(struct ath_hw *ah);
577
+	void (*rfbus_done)(struct ath_hw *ah);
578
+	void (*restore_chainmask)(struct ath_hw *ah);
579
+	void (*set_diversity)(struct ath_hw *ah, int value);
580
+	u32 (*compute_pll_control)(struct ath_hw *ah,
581
+				   struct ath9k_channel *chan);
582
+	int (*ani_control)(struct ath_hw *ah, enum ath9k_ani_cmd cmd,
583
+			    int param);
584
+	void (*do_getnf)(struct ath_hw *ah, int16_t nfarray[NUM_NF_READINGS]);
585
+	void (*set_radar_params)(struct ath_hw *ah,
586
+				 struct ath_hw_radar_conf *conf);
587
+
588
+	/* ANI */
589
+	void (*ani_cache_ini_regs)(struct ath_hw *ah);
590
+};
591
+
592
+/**
593
+ * struct ath_hw_ops - callbacks used by hardware code and driver code
594
+ *
595
+ * This structure contains callbacks designed to to be used internally by
596
+ * hardware code and also by the lower level driver.
597
+ *
598
+ * @config_pci_powersave:
599
+ * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
600
+ */
601
+struct ath_hw_ops {
602
+	void (*config_pci_powersave)(struct ath_hw *ah,
603
+				     int restore,
604
+				     int power_off);
605
+	void (*rx_enable)(struct ath_hw *ah);
606
+	void (*set_desc_link)(void *ds, u32 link);
607
+	void (*get_desc_link)(void *ds, u32 **link);
608
+	int (*calibrate)(struct ath_hw *ah,
609
+			  struct ath9k_channel *chan,
610
+			  u8 rxchainmask,
611
+			  int longcal);
612
+	int (*get_isr)(struct ath_hw *ah, enum ath9k_int *masked);
613
+	void (*fill_txdesc)(struct ath_hw *ah, void *ds, u32 seglen,
614
+			    int is_firstseg, int is_is_lastseg,
615
+			    const void *ds0, u32 buf_addr,
616
+			    unsigned int qcu);
617
+	int (*proc_txdesc)(struct ath_hw *ah, void *ds,
618
+			   struct ath_tx_status *ts);
619
+	void (*set11n_txdesc)(struct ath_hw *ah, void *ds,
620
+			      u32 pktLen, enum ath9k_pkt_type type,
621
+			      u32 txPower, u32 keyIx,
622
+			      enum ath9k_key_type keyType,
623
+			      u32 flags);
624
+	void (*set11n_ratescenario)(struct ath_hw *ah, void *ds,
625
+				void *lastds,
626
+				u32 durUpdateEn, u32 rtsctsRate,
627
+				u32 rtsctsDuration,
628
+				struct ath9k_11n_rate_series series[],
629
+				u32 nseries, u32 flags);
630
+	void (*set11n_aggr_first)(struct ath_hw *ah, void *ds,
631
+				  u32 aggrLen);
632
+	void (*set11n_aggr_middle)(struct ath_hw *ah, void *ds,
633
+				   u32 numDelims);
634
+	void (*set11n_aggr_last)(struct ath_hw *ah, void *ds);
635
+	void (*clr11n_aggr)(struct ath_hw *ah, void *ds);
636
+	void (*set_clrdmask)(struct ath_hw *ah, void *ds, int val);
637
+	void (*antdiv_comb_conf_get)(struct ath_hw *ah,
638
+			struct ath_hw_antcomb_conf *antconf);
639
+	void (*antdiv_comb_conf_set)(struct ath_hw *ah,
640
+			struct ath_hw_antcomb_conf *antconf);
641
+
642
+};
643
+
644
+struct ath_nf_limits {
645
+	s16 max;
646
+	s16 min;
647
+	s16 nominal;
648
+};
649
+
650
+/* ah_flags */
651
+#define AH_USE_EEPROM   0x1
652
+#define AH_UNPLUGGED    0x2 /* The card has been physically removed. */
653
+
654
+struct ath_hw {
655
+	struct ath_ops reg_ops;
656
+
657
+	struct net80211_device *dev;
658
+	struct ath_common common;
659
+	struct ath9k_hw_version hw_version;
660
+	struct ath9k_ops_config config;
661
+	struct ath9k_hw_capabilities caps;
662
+	struct ath9k_channel channels[ATH9K_NUM_CHANNELS];
663
+	struct ath9k_channel *curchan;
664
+
665
+	union {
666
+		struct ar5416_eeprom_def def;
667
+		struct ar5416_eeprom_4k map4k;
668
+		struct ar9287_eeprom map9287;
669
+		struct ar9300_eeprom ar9300_eep;
670
+	} eeprom;
671
+	const struct eeprom_ops *eep_ops;
672
+
673
+	int sw_mgmt_crypto;
674
+	int is_pciexpress;
675
+	int is_monitoring;
676
+	int need_an_top2_fixup;
677
+	u16 tx_trig_level;
678
+
679
+	u32 nf_regs[6];
680
+	struct ath_nf_limits nf_2g;
681
+	struct ath_nf_limits nf_5g;
682
+	u16 rfsilent;
683
+	u32 rfkill_gpio;
684
+	u32 rfkill_polarity;
685
+	u32 ah_flags;
686
+
687
+	int htc_reset_init;
688
+
689
+	enum ath9k_power_mode power_mode;
690
+
691
+	struct ath9k_hw_cal_data *caldata;
692
+	struct ath9k_pacal_info pacal_info;
693
+	struct ar5416Stats stats;
694
+	struct ath9k_tx_queue_info txq[ATH9K_NUM_TX_QUEUES];
695
+
696
+	int16_t curchan_rad_index;
697
+	int ah_ier;
698
+	enum ath9k_int imask;
699
+	u32 imrs2_reg;
700
+	u32 txok_interrupt_mask;
701
+	u32 txerr_interrupt_mask;
702
+	u32 txdesc_interrupt_mask;
703
+	u32 txeol_interrupt_mask;
704
+	u32 txurn_interrupt_mask;
705
+	int chip_fullsleep;
706
+	u32 atim_window;
707
+
708
+	/* Calibration */
709
+	u32 supp_cals;
710
+	struct ath9k_cal_list iq_caldata;
711
+	struct ath9k_cal_list adcgain_caldata;
712
+	struct ath9k_cal_list adcdc_caldata;
713
+	struct ath9k_cal_list tempCompCalData;
714
+	struct ath9k_cal_list *cal_list;
715
+	struct ath9k_cal_list *cal_list_last;
716
+	struct ath9k_cal_list *cal_list_curr;
717
+#define totalPowerMeasI meas0.unsign
718
+#define totalPowerMeasQ meas1.unsign
719
+#define totalIqCorrMeas meas2.sign
720
+#define totalAdcIOddPhase  meas0.unsign
721
+#define totalAdcIEvenPhase meas1.unsign
722
+#define totalAdcQOddPhase  meas2.unsign
723
+#define totalAdcQEvenPhase meas3.unsign
724
+#define totalAdcDcOffsetIOddPhase  meas0.sign
725
+#define totalAdcDcOffsetIEvenPhase meas1.sign
726
+#define totalAdcDcOffsetQOddPhase  meas2.sign
727
+#define totalAdcDcOffsetQEvenPhase meas3.sign
728
+	union {
729
+		u32 unsign[AR5416_MAX_CHAINS];
730
+		int32_t sign[AR5416_MAX_CHAINS];
731
+	} meas0;
732
+	union {
733
+		u32 unsign[AR5416_MAX_CHAINS];
734
+		int32_t sign[AR5416_MAX_CHAINS];
735
+	} meas1;
736
+	union {
737
+		u32 unsign[AR5416_MAX_CHAINS];
738
+		int32_t sign[AR5416_MAX_CHAINS];
739
+	} meas2;
740
+	union {
741
+		u32 unsign[AR5416_MAX_CHAINS];
742
+		int32_t sign[AR5416_MAX_CHAINS];
743
+	} meas3;
744
+	u16 cal_samples;
745
+
746
+	u32 sta_id1_defaults;
747
+	u32 misc_mode;
748
+	enum {
749
+		AUTO_32KHZ,
750
+		USE_32KHZ,
751
+		DONT_USE_32KHZ,
752
+	} enable_32kHz_clock;
753
+
754
+	/* Private to hardware code */
755
+	struct ath_hw_private_ops private_ops;
756
+	/* Accessed by the lower level driver */
757
+	struct ath_hw_ops ops;
758
+
759
+	/* Used to program the radio on non single-chip devices */
760
+	u32 *analogBank0Data;
761
+	u32 *analogBank1Data;
762
+	u32 *analogBank2Data;
763
+	u32 *analogBank3Data;
764
+	u32 *analogBank6Data;
765
+	u32 *analogBank6TPCData;
766
+	u32 *analogBank7Data;
767
+	u32 *addac5416_21;
768
+	u32 *bank6Temp;
769
+
770
+	u8 txpower_limit;
771
+	int coverage_class;
772
+	u32 slottime;
773
+	u32 globaltxtimeout;
774
+
775
+	/* ANI */
776
+	u32 proc_phyerr;
777
+	u32 aniperiod;
778
+	int totalSizeDesired[5];
779
+	int coarse_high[5];
780
+	int coarse_low[5];
781
+	int firpwr[5];
782
+	enum ath9k_ani_cmd ani_function;
783
+
784
+	u32 intr_txqs;
785
+	u8 txchainmask;
786
+	u8 rxchainmask;
787
+
788
+	struct ath_hw_radar_conf radar_conf;
789
+
790
+	u32 originalGain[22];
791
+	int initPDADC;
792
+	int PDADCdelta;
793
+	int led_pin;
794
+	u32 gpio_mask;
795
+	u32 gpio_val;
796
+
797
+	struct ar5416IniArray iniModes;
798
+	struct ar5416IniArray iniCommon;
799
+	struct ar5416IniArray iniBank0;
800
+	struct ar5416IniArray iniBB_RfGain;
801
+	struct ar5416IniArray iniBank1;
802
+	struct ar5416IniArray iniBank2;
803
+	struct ar5416IniArray iniBank3;
804
+	struct ar5416IniArray iniBank6;
805
+	struct ar5416IniArray iniBank6TPC;
806
+	struct ar5416IniArray iniBank7;
807
+	struct ar5416IniArray iniAddac;
808
+	struct ar5416IniArray iniPcieSerdes;
809
+	struct ar5416IniArray iniPcieSerdesLowPower;
810
+	struct ar5416IniArray iniModesAdditional;
811
+	struct ar5416IniArray iniModesAdditional_40M;
812
+	struct ar5416IniArray iniModesRxGain;
813
+	struct ar5416IniArray iniModesTxGain;
814
+	struct ar5416IniArray iniModes_9271_1_0_only;
815
+	struct ar5416IniArray iniCckfirNormal;
816
+	struct ar5416IniArray iniCckfirJapan2484;
817
+	struct ar5416IniArray iniCommon_normal_cck_fir_coeff_9271;
818
+	struct ar5416IniArray iniCommon_japan_2484_cck_fir_coeff_9271;
819
+	struct ar5416IniArray iniModes_9271_ANI_reg;
820
+	struct ar5416IniArray iniModes_high_power_tx_gain_9271;
821
+	struct ar5416IniArray iniModes_normal_power_tx_gain_9271;
822
+
823
+	struct ar5416IniArray iniMac[ATH_INI_NUM_SPLIT];
824
+	struct ar5416IniArray iniBB[ATH_INI_NUM_SPLIT];
825
+	struct ar5416IniArray iniRadio[ATH_INI_NUM_SPLIT];
826
+	struct ar5416IniArray iniSOC[ATH_INI_NUM_SPLIT];
827
+
828
+	u32 intr_gen_timer_trigger;
829
+	u32 intr_gen_timer_thresh;
830
+	struct ath_gen_timer_table hw_gen_timers;
831
+
832
+	struct ar9003_txs *ts_ring;
833
+	void *ts_start;
834
+	u32 ts_paddr_start;
835
+	u32 ts_paddr_end;
836
+	u16 ts_tail;
837
+	u8 ts_size;
838
+
839
+	unsigned int paprd_target_power;
840
+	unsigned int paprd_training_power;
841
+	unsigned int paprd_ratemask;
842
+	unsigned int paprd_ratemask_ht40;
843
+	int paprd_table_write_done;
844
+	u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
845
+	u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
846
+	/*
847
+	 * Store the permanent value of Reg 0x4004in WARegVal
848
+	 * so we dont have to R/M/W. We should not be reading
849
+	 * this register when in sleep states.
850
+	 */
851
+	u32 WARegVal;
852
+
853
+	/* Enterprise mode cap */
854
+	u32 ent_mode;
855
+
856
+	int is_clk_25mhz;
857
+};
858
+
859
+struct ath_bus_ops {
860
+	enum ath_bus_type ath_bus_type;
861
+	void (*read_cachesize)(struct ath_common *common, int *csz);
862
+	int (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
863
+	void (*bt_coex_prep)(struct ath_common *common);
864
+	void (*extn_synch_en)(struct ath_common *common);
865
+};
866
+
867
+static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
868
+{
869
+	return &ah->common;
870
+}
871
+
872
+static inline struct ath_regulatory *ath9k_hw_regulatory(struct ath_hw *ah)
873
+{
874
+	return &(ath9k_hw_common(ah)->regulatory);
875
+}
876
+
877
+static inline struct ath_hw_private_ops *ath9k_hw_private_ops(struct ath_hw *ah)
878
+{
879
+	return &ah->private_ops;
880
+}
881
+
882
+static inline struct ath_hw_ops *ath9k_hw_ops(struct ath_hw *ah)
883
+{
884
+	return &ah->ops;
885
+}
886
+
887
+static inline u8 get_streams(int mask)
888
+{
889
+	return !!(mask & BIT(0)) + !!(mask & BIT(1)) + !!(mask & BIT(2));
890
+}
891
+
892
+/* Initialization, Detach, Reset */
893
+const char *ath9k_hw_probe(u16 vendorid, u16 devid);
894
+void ath9k_hw_deinit(struct ath_hw *ah);
895
+int ath9k_hw_init(struct ath_hw *ah);
896
+int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
897
+		   struct ath9k_hw_cal_data *caldata, int bChannelChange);
898
+int ath9k_hw_fill_cap_info(struct ath_hw *ah);
899
+u32 ath9k_regd_get_ctl(struct ath_regulatory *reg, struct ath9k_channel *chan);
900
+
901
+/* GPIO / RFKILL / Antennae */
902
+void ath9k_hw_cfg_gpio_input(struct ath_hw *ah, u32 gpio);
903
+u32 ath9k_hw_gpio_get(struct ath_hw *ah, u32 gpio);
904
+void ath9k_hw_cfg_output(struct ath_hw *ah, u32 gpio,
905
+			 u32 ah_signal_type);
906
+void ath9k_hw_set_gpio(struct ath_hw *ah, u32 gpio, u32 val);
907
+u32 ath9k_hw_getdefantenna(struct ath_hw *ah);
908
+void ath9k_hw_setantenna(struct ath_hw *ah, u32 antenna);
909
+
910
+/* General Operation */
911
+int ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
912
+void ath9k_hw_write_array(struct ath_hw *ah, struct ar5416IniArray *array,
913
+			  int column, unsigned int *writecnt);
914
+u32 ath9k_hw_reverse_bits(u32 val, u32 n);
915
+u16 ath9k_hw_computetxtime(struct ath_hw *ah,
916
+			   u8 phy, int kbps,
917
+			   u32 frameLen, u16 rateix, int shortPreamble);
918
+void ath9k_hw_get_channel_centers(struct ath_hw *ah,
919
+				  struct ath9k_channel *chan,
920
+				  struct chan_centers *centers);
921
+u32 ath9k_hw_getrxfilter(struct ath_hw *ah);
922
+void ath9k_hw_setrxfilter(struct ath_hw *ah, u32 bits);
923
+int ath9k_hw_phy_disable(struct ath_hw *ah);
924
+int ath9k_hw_disable(struct ath_hw *ah);
925
+void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, int test);
926
+void ath9k_hw_setopmode(struct ath_hw *ah);
927
+void ath9k_hw_setmcastfilter(struct ath_hw *ah, u32 filter0, u32 filter1);
928
+void ath9k_hw_setbssidmask(struct ath_hw *ah);
929
+void ath9k_hw_write_associd(struct ath_hw *ah);
930
+void ath9k_hw_init_global_settings(struct ath_hw *ah);
931
+u32 ar9003_get_pll_sqsum_dvc(struct ath_hw *ah);
932
+void ath9k_hw_set11nmac2040(struct ath_hw *ah);
933
+int ath9k_hw_check_alive(struct ath_hw *ah);
934
+
935
+int ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
936
+
937
+void ath9k_hw_name(struct ath_hw *ah, char *hw_name, size_t len);
938
+
939
+/* HTC */
940
+void ath9k_hw_htc_resetinit(struct ath_hw *ah);
941
+
942
+/* PHY */
943
+void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
944
+				   u32 *coef_mantissa, u32 *coef_exponent);
945
+
946
+/*
947
+ * Code Specific to AR5008, AR9001 or AR9002,
948
+ * we stuff these here to avoid callbacks for AR9003.
949
+ */
950
+void ar9002_hw_cck_chan14_spread(struct ath_hw *ah);
951
+int ar9002_hw_rf_claim(struct ath_hw *ah);
952
+void ar9002_hw_enable_async_fifo(struct ath_hw *ah);
953
+void ar9002_hw_update_async_fifo(struct ath_hw *ah);
954
+void ar9002_hw_enable_wep_aggregation(struct ath_hw *ah);
955
+
956
+/*
957
+ * Code specific to AR9003, we stuff these here to avoid callbacks
958
+ * for older families
959
+ */
960
+void ar9003_hw_disable_phy_restart(struct ath_hw *ah);
961
+
962
+/* Hardware family op attach helpers */
963
+void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
964
+void ar9002_hw_attach_phy_ops(struct ath_hw *ah);
965
+void ar9003_hw_attach_phy_ops(struct ath_hw *ah);
966
+
967
+void ar9002_hw_attach_calib_ops(struct ath_hw *ah);
968
+void ar9003_hw_attach_calib_ops(struct ath_hw *ah);
969
+
970
+void ar9002_hw_attach_ops(struct ath_hw *ah);
971
+void ar9003_hw_attach_ops(struct ath_hw *ah);
972
+
973
+void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
974
+/*
975
+ * ANI work can be shared between all families but a next
976
+ * generation implementation of ANI will be used only for AR9003 only
977
+ * for now as the other families still need to be tested with the same
978
+ * next generation ANI. Feel free to start testing it though for the
979
+ * older families (AR5008, AR9001, AR9002) by using modparam_force_new_ani.
980
+ */
981
+extern int modparam_force_new_ani;
982
+void ath9k_ani_reset(struct ath_hw *ah, int is_scanning);
983
+void ath9k_hw_proc_mib_event(struct ath_hw *ah);
984
+void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
985
+
986
+#define ATH_PCIE_CAP_LINK_CTRL	0x70
987
+#define ATH_PCIE_CAP_LINK_L0S	1
988
+#define ATH_PCIE_CAP_LINK_L1	2
989
+
990
+#define ATH9K_CLOCK_RATE_CCK		22
991
+#define ATH9K_CLOCK_RATE_5GHZ_OFDM	40
992
+#define ATH9K_CLOCK_RATE_2GHZ_OFDM	44
993
+#define ATH9K_CLOCK_FAST_RATE_5GHZ_OFDM 44
994
+
995
+#endif

+ 708
- 0
src/drivers/net/ath/ath9k/mac.h View File

@@ -0,0 +1,708 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef MAC_H
21
+#define MAC_H
22
+
23
+#include <unistd.h>
24
+
25
+#define RXSTATUS_RATE(ah, ads) (AR_SREV_5416_20_OR_LATER(ah) ?		\
26
+				MS(ads->ds_rxstatus0, AR_RxRate) :	\
27
+				(ads->ds_rxstatus3 >> 2) & 0xFF)
28
+
29
+#define set11nTries(_series, _index) \
30
+	(SM((_series)[_index].Tries, AR_XmitDataTries##_index))
31
+
32
+#define set11nRate(_series, _index) \
33
+	(SM((_series)[_index].Rate, AR_XmitRate##_index))
34
+
35
+#define set11nPktDurRTSCTS(_series, _index)				\
36
+	(SM((_series)[_index].PktDuration, AR_PacketDur##_index) |	\
37
+	 ((_series)[_index].RateFlags & ATH9K_RATESERIES_RTS_CTS   ?	\
38
+	  AR_RTSCTSQual##_index : 0))
39
+
40
+#define set11nRateFlags(_series, _index)				\
41
+	(((_series)[_index].RateFlags & ATH9K_RATESERIES_2040 ?		\
42
+	  AR_2040_##_index : 0)						\
43
+	 |((_series)[_index].RateFlags & ATH9K_RATESERIES_HALFGI ?	\
44
+	   AR_GI##_index : 0)						\
45
+	 |((_series)[_index].RateFlags & ATH9K_RATESERIES_STBC ?	\
46
+	   AR_STBC##_index : 0)						\
47
+	 |SM((_series)[_index].ChSel, AR_ChainSel##_index))
48
+
49
+#define CCK_SIFS_TIME        10
50
+#define CCK_PREAMBLE_BITS   144
51
+#define CCK_PLCP_BITS        48
52
+
53
+#define OFDM_SIFS_TIME        16
54
+#define OFDM_PREAMBLE_TIME    20
55
+#define OFDM_PLCP_BITS        22
56
+#define OFDM_SYMBOL_TIME      4
57
+
58
+#define OFDM_SIFS_TIME_HALF     32
59
+#define OFDM_PREAMBLE_TIME_HALF 40
60
+#define OFDM_PLCP_BITS_HALF     22
61
+#define OFDM_SYMBOL_TIME_HALF   8
62
+
63
+#define OFDM_SIFS_TIME_QUARTER      64
64
+#define OFDM_PREAMBLE_TIME_QUARTER  80
65
+#define OFDM_PLCP_BITS_QUARTER      22
66
+#define OFDM_SYMBOL_TIME_QUARTER    16
67
+
68
+#define INIT_AIFS       2
69
+#define INIT_CWMIN      15
70
+#define INIT_CWMIN_11B  31
71
+#define INIT_CWMAX      1023
72
+#define INIT_SH_RETRY   10
73
+#define INIT_LG_RETRY   10
74
+#define INIT_SSH_RETRY  32
75
+#define INIT_SLG_RETRY  32
76
+
77
+#define ATH9K_SLOT_TIME_6 6
78
+#define ATH9K_SLOT_TIME_9 9
79
+#define ATH9K_SLOT_TIME_20 20
80
+
81
+#define ATH9K_TXERR_XRETRY         0x01
82
+#define ATH9K_TXERR_FILT           0x02
83
+#define ATH9K_TXERR_FIFO           0x04
84
+#define ATH9K_TXERR_XTXOP          0x08
85
+#define ATH9K_TXERR_TIMER_EXPIRED  0x10
86
+#define ATH9K_TX_ACKED		   0x20
87
+#define ATH9K_TXERR_MASK						\
88
+	(ATH9K_TXERR_XRETRY | ATH9K_TXERR_FILT | ATH9K_TXERR_FIFO |	\
89
+	 ATH9K_TXERR_XTXOP | ATH9K_TXERR_TIMER_EXPIRED)
90
+
91
+#define ATH9K_TX_BA                0x01
92
+#define ATH9K_TX_PWRMGMT           0x02
93
+#define ATH9K_TX_DESC_CFG_ERR      0x04
94
+#define ATH9K_TX_DATA_UNDERRUN     0x08
95
+#define ATH9K_TX_DELIM_UNDERRUN    0x10
96
+#define ATH9K_TX_SW_FILTERED       0x80
97
+
98
+/* 64 bytes */
99
+#define MIN_TX_FIFO_THRESHOLD   0x1
100
+
101
+/*
102
+ * Single stream device AR9285 and AR9271 require 2 KB
103
+ * to work around a hardware issue, all other devices
104
+ * have can use the max 4 KB limit.
105
+ */
106
+#define MAX_TX_FIFO_THRESHOLD   ((4096 / 64) - 1)
107
+
108
+struct ath_tx_status {
109
+	u32 ts_tstamp;
110
+	u16 ts_seqnum;
111
+	u8 ts_status;
112
+	u8 ts_rateindex;
113
+	int8_t ts_rssi;
114
+	u8 ts_shortretry;
115
+	u8 ts_longretry;
116
+	u8 ts_virtcol;
117
+	u8 ts_flags;
118
+	int8_t ts_rssi_ctl0;
119
+	int8_t ts_rssi_ctl1;
120
+	int8_t ts_rssi_ctl2;
121
+	int8_t ts_rssi_ext0;
122
+	int8_t ts_rssi_ext1;
123
+	int8_t ts_rssi_ext2;
124
+	u8 qid;
125
+	u16 desc_id;
126
+	u8 tid;
127
+	u32 ba_low;
128
+	u32 ba_high;
129
+	u32 evm0;
130
+	u32 evm1;
131
+	u32 evm2;
132
+};
133
+
134
+struct ath_rx_status {
135
+	u32 rs_tstamp;
136
+	u16 rs_datalen;
137
+	u8 rs_status;
138
+	u8 rs_phyerr;
139
+	int8_t rs_rssi;
140
+	u8 rs_keyix;
141
+	u8 rs_rate;
142
+	u8 rs_antenna;
143
+	u8 rs_more;
144
+	int8_t rs_rssi_ctl0;
145
+	int8_t rs_rssi_ctl1;
146
+	int8_t rs_rssi_ctl2;
147
+	int8_t rs_rssi_ext0;
148
+	int8_t rs_rssi_ext1;
149
+	int8_t rs_rssi_ext2;
150
+	u8 rs_isaggr;
151
+	u8 rs_moreaggr;
152
+	u8 rs_num_delims;
153
+	u8 rs_flags;
154
+	u32 evm0;
155
+	u32 evm1;
156
+	u32 evm2;
157
+	u32 evm3;
158
+	u32 evm4;
159
+};
160
+
161
+struct ath_htc_rx_status {
162
+	uint64_t rs_tstamp;
163
+	uint16_t rs_datalen;
164
+	u8 rs_status;
165
+	u8 rs_phyerr;
166
+	int8_t rs_rssi;
167
+	int8_t rs_rssi_ctl0;
168
+	int8_t rs_rssi_ctl1;
169
+	int8_t rs_rssi_ctl2;
170
+	int8_t rs_rssi_ext0;
171
+	int8_t rs_rssi_ext1;
172
+	int8_t rs_rssi_ext2;
173
+	u8 rs_keyix;
174
+	u8 rs_rate;
175
+	u8 rs_antenna;
176
+	u8 rs_more;
177
+	u8 rs_isaggr;
178
+	u8 rs_moreaggr;
179
+	u8 rs_num_delims;
180
+	u8 rs_flags;
181
+	u8 rs_dummy;
182
+	uint32_t evm0;
183
+	uint32_t evm1;
184
+	uint32_t evm2;
185
+};
186
+
187
+#define ATH9K_RXERR_CRC           0x01
188
+#define ATH9K_RXERR_PHY           0x02
189
+#define ATH9K_RXERR_FIFO          0x04
190
+#define ATH9K_RXERR_DECRYPT       0x08
191
+#define ATH9K_RXERR_MIC           0x10
192
+
193
+#define ATH9K_RX_MORE             0x01
194
+#define ATH9K_RX_MORE_AGGR        0x02
195
+#define ATH9K_RX_GI               0x04
196
+#define ATH9K_RX_2040             0x08
197
+#define ATH9K_RX_DELIM_CRC_PRE    0x10
198
+#define ATH9K_RX_DELIM_CRC_POST   0x20
199
+#define ATH9K_RX_DECRYPT_BUSY     0x40
200
+
201
+#define ATH9K_RXKEYIX_INVALID	((u8)-1)
202
+#define ATH9K_TXKEYIX_INVALID	((u32)-1)
203
+
204
+enum ath9k_phyerr {
205
+	ATH9K_PHYERR_UNDERRUN             = 0,  /* Transmit underrun */
206
+	ATH9K_PHYERR_TIMING               = 1,  /* Timing error */
207
+	ATH9K_PHYERR_PARITY               = 2,  /* Illegal parity */
208
+	ATH9K_PHYERR_RATE                 = 3,  /* Illegal rate */
209
+	ATH9K_PHYERR_LENGTH               = 4,  /* Illegal length */
210
+	ATH9K_PHYERR_RADAR                = 5,  /* Radar detect */
211
+	ATH9K_PHYERR_SERVICE              = 6,  /* Illegal service */
212
+	ATH9K_PHYERR_TOR                  = 7,  /* Transmit override receive */
213
+
214
+	ATH9K_PHYERR_OFDM_TIMING          = 17,
215
+	ATH9K_PHYERR_OFDM_SIGNAL_PARITY   = 18,
216
+	ATH9K_PHYERR_OFDM_RATE_ILLEGAL    = 19,
217
+	ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL  = 20,
218
+	ATH9K_PHYERR_OFDM_POWER_DROP      = 21,
219
+	ATH9K_PHYERR_OFDM_SERVICE         = 22,
220
+	ATH9K_PHYERR_OFDM_RESTART         = 23,
221
+	ATH9K_PHYERR_FALSE_RADAR_EXT      = 24,
222
+
223
+	ATH9K_PHYERR_CCK_TIMING           = 25,
224
+	ATH9K_PHYERR_CCK_HEADER_CRC       = 26,
225
+	ATH9K_PHYERR_CCK_RATE_ILLEGAL     = 27,
226
+	ATH9K_PHYERR_CCK_SERVICE          = 30,
227
+	ATH9K_PHYERR_CCK_RESTART          = 31,
228
+	ATH9K_PHYERR_CCK_LENGTH_ILLEGAL   = 32,
229
+	ATH9K_PHYERR_CCK_POWER_DROP       = 33,
230
+
231
+	ATH9K_PHYERR_HT_CRC_ERROR         = 34,
232
+	ATH9K_PHYERR_HT_LENGTH_ILLEGAL    = 35,
233
+	ATH9K_PHYERR_HT_RATE_ILLEGAL      = 36,
234
+
235
+	ATH9K_PHYERR_MAX                  = 37,
236
+};
237
+
238
+struct ath_desc {
239
+	u32 ds_link;
240
+	u32 ds_data;
241
+	u32 ds_ctl0;
242
+	u32 ds_ctl1;
243
+	u32 ds_hw[20];
244
+//	void *ds_vdata;
245
+} __attribute__((packed, aligned(4)));
246
+
247
+#define ATH9K_TXDESC_NOACK		0x0002
248
+#define ATH9K_TXDESC_RTSENA		0x0004
249
+#define ATH9K_TXDESC_CTSENA		0x0008
250
+/* ATH9K_TXDESC_INTREQ forces a tx interrupt to be generated for
251
+ * the descriptor its marked on.  We take a tx interrupt to reap
252
+ * descriptors when the h/w hits an EOL condition or
253
+ * when the descriptor is specifically marked to generate
254
+ * an interrupt with this flag. Descriptors should be
255
+ * marked periodically to insure timely replenishing of the
256
+ * supply needed for sending frames. Defering interrupts
257
+ * reduces system load and potentially allows more concurrent
258
+ * work to be done but if done to aggressively can cause
259
+ * senders to backup. When the hardware queue is left too
260
+ * large rate control information may also be too out of
261
+ * date. An Alternative for this is TX interrupt mitigation
262
+ * but this needs more testing. */
263
+#define ATH9K_TXDESC_INTREQ		0x0010
264
+#define ATH9K_TXDESC_VEOL		0x0020
265
+#define ATH9K_TXDESC_EXT_ONLY		0x0040
266
+#define ATH9K_TXDESC_EXT_AND_CTL	0x0080
267
+#define ATH9K_TXDESC_VMF		0x0100
268
+#define ATH9K_TXDESC_FRAG_IS_ON 	0x0200
269
+#define ATH9K_TXDESC_LOWRXCHAIN		0x0400
270
+#define ATH9K_TXDESC_LDPC		0x00010000
271
+
272
+#define ATH9K_RXDESC_INTREQ		0x0020
273
+
274
+struct ar5416_desc {
275
+	u32 ds_link;
276
+	u32 ds_data;
277
+	u32 ds_ctl0;
278
+	u32 ds_ctl1;
279
+	union {
280
+		struct {
281
+			u32 ctl2;
282
+			u32 ctl3;
283
+			u32 ctl4;
284
+			u32 ctl5;
285
+			u32 ctl6;
286
+			u32 ctl7;
287
+			u32 ctl8;
288
+			u32 ctl9;
289
+			u32 ctl10;
290
+			u32 ctl11;
291
+			u32 status0;
292
+			u32 status1;
293
+			u32 status2;
294
+			u32 status3;
295
+			u32 status4;
296
+			u32 status5;
297
+			u32 status6;
298
+			u32 status7;
299
+			u32 status8;
300
+			u32 status9;
301
+		} tx;
302
+		struct {
303
+			u32 status0;
304
+			u32 status1;
305
+			u32 status2;
306
+			u32 status3;
307
+			u32 status4;
308
+			u32 status5;
309
+			u32 status6;
310
+			u32 status7;
311
+			u32 status8;
312
+		} rx;
313
+	} u;
314
+} __attribute__((packed, aligned(4)));
315
+
316
+#define AR5416DESC(_ds)         ((struct ar5416_desc *)(_ds))
317
+#define AR5416DESC_CONST(_ds)   ((const struct ar5416_desc *)(_ds))
318
+
319
+#define ds_ctl2     u.tx.ctl2
320
+#define ds_ctl3     u.tx.ctl3
321
+#define ds_ctl4     u.tx.ctl4
322
+#define ds_ctl5     u.tx.ctl5
323
+#define ds_ctl6     u.tx.ctl6
324
+#define ds_ctl7     u.tx.ctl7
325
+#define ds_ctl8     u.tx.ctl8
326
+#define ds_ctl9     u.tx.ctl9
327
+#define ds_ctl10    u.tx.ctl10
328
+#define ds_ctl11    u.tx.ctl11
329
+
330
+#define ds_txstatus0    u.tx.status0
331
+#define ds_txstatus1    u.tx.status1
332
+#define ds_txstatus2    u.tx.status2
333
+#define ds_txstatus3    u.tx.status3
334
+#define ds_txstatus4    u.tx.status4
335
+#define ds_txstatus5    u.tx.status5
336
+#define ds_txstatus6    u.tx.status6
337
+#define ds_txstatus7    u.tx.status7
338
+#define ds_txstatus8    u.tx.status8
339
+#define ds_txstatus9    u.tx.status9
340
+
341
+#define ds_rxstatus0    u.rx.status0
342
+#define ds_rxstatus1    u.rx.status1
343
+#define ds_rxstatus2    u.rx.status2
344
+#define ds_rxstatus3    u.rx.status3
345
+#define ds_rxstatus4    u.rx.status4
346
+#define ds_rxstatus5    u.rx.status5
347
+#define ds_rxstatus6    u.rx.status6
348
+#define ds_rxstatus7    u.rx.status7
349
+#define ds_rxstatus8    u.rx.status8
350
+
351
+#define AR_FrameLen         0x00000fff
352
+#define AR_VirtMoreFrag     0x00001000
353
+#define AR_TxCtlRsvd00      0x0000e000
354
+#define AR_XmitPower        0x003f0000
355
+#define AR_XmitPower_S      16
356
+#define AR_RTSEnable        0x00400000
357
+#define AR_VEOL             0x00800000
358
+#define AR_ClrDestMask      0x01000000
359
+#define AR_TxCtlRsvd01      0x1e000000
360
+#define AR_TxIntrReq        0x20000000
361
+#define AR_DestIdxValid     0x40000000
362
+#define AR_CTSEnable        0x80000000
363
+
364
+#define AR_TxMore           0x00001000
365
+#define AR_DestIdx          0x000fe000
366
+#define AR_DestIdx_S        13
367
+#define AR_FrameType        0x00f00000
368
+#define AR_FrameType_S      20
369
+#define AR_NoAck            0x01000000
370
+#define AR_InsertTS         0x02000000
371
+#define AR_CorruptFCS       0x04000000
372
+#define AR_ExtOnly          0x08000000
373
+#define AR_ExtAndCtl        0x10000000
374
+#define AR_MoreAggr         0x20000000
375
+#define AR_IsAggr           0x40000000
376
+
377
+#define AR_BurstDur         0x00007fff
378
+#define AR_BurstDur_S       0
379
+#define AR_DurUpdateEna     0x00008000
380
+#define AR_XmitDataTries0   0x000f0000
381
+#define AR_XmitDataTries0_S 16
382
+#define AR_XmitDataTries1   0x00f00000
383
+#define AR_XmitDataTries1_S 20
384
+#define AR_XmitDataTries2   0x0f000000
385
+#define AR_XmitDataTries2_S 24
386
+#define AR_XmitDataTries3   0xf0000000
387
+#define AR_XmitDataTries3_S 28
388
+
389
+#define AR_XmitRate0        0x000000ff
390
+#define AR_XmitRate0_S      0
391
+#define AR_XmitRate1        0x0000ff00
392
+#define AR_XmitRate1_S      8
393
+#define AR_XmitRate2        0x00ff0000
394
+#define AR_XmitRate2_S      16
395
+#define AR_XmitRate3        0xff000000
396
+#define AR_XmitRate3_S      24
397
+
398
+#define AR_PacketDur0       0x00007fff
399
+#define AR_PacketDur0_S     0
400
+#define AR_RTSCTSQual0      0x00008000
401
+#define AR_PacketDur1       0x7fff0000
402
+#define AR_PacketDur1_S     16
403
+#define AR_RTSCTSQual1      0x80000000
404
+
405
+#define AR_PacketDur2       0x00007fff
406
+#define AR_PacketDur2_S     0
407
+#define AR_RTSCTSQual2      0x00008000
408
+#define AR_PacketDur3       0x7fff0000
409
+#define AR_PacketDur3_S     16
410
+#define AR_RTSCTSQual3      0x80000000
411
+
412
+#define AR_AggrLen          0x0000ffff
413
+#define AR_AggrLen_S        0
414
+#define AR_TxCtlRsvd60      0x00030000
415
+#define AR_PadDelim         0x03fc0000
416
+#define AR_PadDelim_S       18
417
+#define AR_EncrType         0x0c000000
418
+#define AR_EncrType_S       26
419
+#define AR_TxCtlRsvd61      0xf0000000
420
+#define AR_LDPC             0x80000000
421
+
422
+#define AR_2040_0           0x00000001
423
+#define AR_GI0              0x00000002
424
+#define AR_ChainSel0        0x0000001c
425
+#define AR_ChainSel0_S      2
426
+#define AR_2040_1           0x00000020
427
+#define AR_GI1              0x00000040
428
+#define AR_ChainSel1        0x00000380
429
+#define AR_ChainSel1_S      7
430
+#define AR_2040_2           0x00000400
431
+#define AR_GI2              0x00000800
432
+#define AR_ChainSel2        0x00007000
433
+#define AR_ChainSel2_S      12
434
+#define AR_2040_3           0x00008000
435
+#define AR_GI3              0x00010000
436
+#define AR_ChainSel3        0x000e0000
437
+#define AR_ChainSel3_S      17
438
+#define AR_RTSCTSRate       0x0ff00000
439
+#define AR_RTSCTSRate_S     20
440
+#define AR_STBC0            0x10000000
441
+#define AR_STBC1            0x20000000
442
+#define AR_STBC2            0x40000000
443
+#define AR_STBC3            0x80000000
444
+
445
+#define AR_TxRSSIAnt00      0x000000ff
446
+#define AR_TxRSSIAnt00_S    0
447
+#define AR_TxRSSIAnt01      0x0000ff00
448
+#define AR_TxRSSIAnt01_S    8
449
+#define AR_TxRSSIAnt02      0x00ff0000
450
+#define AR_TxRSSIAnt02_S    16
451
+#define AR_TxStatusRsvd00   0x3f000000
452
+#define AR_TxBaStatus       0x40000000
453
+#define AR_TxStatusRsvd01   0x80000000
454
+
455
+/*
456
+ * AR_FrmXmitOK - Frame transmission success flag. If set, the frame was
457
+ * transmitted successfully. If clear, no ACK or BA was received to indicate
458
+ * successful transmission when we were expecting an ACK or BA.
459
+ */
460
+#define AR_FrmXmitOK            0x00000001
461
+#define AR_ExcessiveRetries     0x00000002
462
+#define AR_FIFOUnderrun         0x00000004
463
+#define AR_Filtered             0x00000008
464
+#define AR_RTSFailCnt           0x000000f0
465
+#define AR_RTSFailCnt_S         4
466
+#define AR_DataFailCnt          0x00000f00
467
+#define AR_DataFailCnt_S        8
468
+#define AR_VirtRetryCnt         0x0000f000
469
+#define AR_VirtRetryCnt_S       12
470
+#define AR_TxDelimUnderrun      0x00010000
471
+#define AR_TxDataUnderrun       0x00020000
472
+#define AR_DescCfgErr           0x00040000
473
+#define AR_TxTimerExpired       0x00080000
474
+#define AR_TxStatusRsvd10       0xfff00000
475
+
476
+#define AR_SendTimestamp    ds_txstatus2
477
+#define AR_BaBitmapLow      ds_txstatus3
478
+#define AR_BaBitmapHigh     ds_txstatus4
479
+
480
+#define AR_TxRSSIAnt10      0x000000ff
481
+#define AR_TxRSSIAnt10_S    0
482
+#define AR_TxRSSIAnt11      0x0000ff00
483
+#define AR_TxRSSIAnt11_S    8
484
+#define AR_TxRSSIAnt12      0x00ff0000
485
+#define AR_TxRSSIAnt12_S    16
486
+#define AR_TxRSSICombined   0xff000000
487
+#define AR_TxRSSICombined_S 24
488
+
489
+#define AR_TxTid	0xf0000000
490
+#define AR_TxTid_S	28
491
+
492
+#define AR_TxEVM0           ds_txstatus5
493
+#define AR_TxEVM1           ds_txstatus6
494
+#define AR_TxEVM2           ds_txstatus7
495
+
496
+#define AR_TxDone           0x00000001
497
+#define AR_SeqNum           0x00001ffe
498
+#define AR_SeqNum_S         1
499
+#define AR_TxStatusRsvd80   0x0001e000
500
+#define AR_TxOpExceeded     0x00020000
501
+#define AR_TxStatusRsvd81   0x001c0000
502
+#define AR_FinalTxIdx       0x00600000
503
+#define AR_FinalTxIdx_S     21
504
+#define AR_TxStatusRsvd82   0x01800000
505
+#define AR_PowerMgmt        0x02000000
506
+#define AR_TxStatusRsvd83   0xfc000000
507
+
508
+#define AR_RxCTLRsvd00  0xffffffff
509
+
510
+#define AR_RxCtlRsvd00  0x00001000
511
+#define AR_RxIntrReq    0x00002000
512
+#define AR_RxCtlRsvd01  0xffffc000
513
+
514
+#define AR_RxRSSIAnt00      0x000000ff
515
+#define AR_RxRSSIAnt00_S    0
516
+#define AR_RxRSSIAnt01      0x0000ff00
517
+#define AR_RxRSSIAnt01_S    8
518
+#define AR_RxRSSIAnt02      0x00ff0000
519
+#define AR_RxRSSIAnt02_S    16
520
+#define AR_RxRate           0xff000000
521
+#define AR_RxRate_S         24
522
+#define AR_RxStatusRsvd00   0xff000000
523
+
524
+#define AR_DataLen          0x00000fff
525
+#define AR_RxMore           0x00001000
526
+#define AR_NumDelim         0x003fc000
527
+#define AR_NumDelim_S       14
528
+#define AR_RxStatusRsvd10   0xff800000
529
+
530
+#define AR_RcvTimestamp     ds_rxstatus2
531
+
532
+#define AR_GI               0x00000001
533
+#define AR_2040             0x00000002
534
+#define AR_Parallel40       0x00000004
535
+#define AR_Parallel40_S     2
536
+#define AR_RxStatusRsvd30   0x000000f8
537
+#define AR_RxAntenna	    0xffffff00
538
+#define AR_RxAntenna_S	    8
539
+
540
+#define AR_RxRSSIAnt10            0x000000ff
541
+#define AR_RxRSSIAnt10_S          0
542
+#define AR_RxRSSIAnt11            0x0000ff00
543
+#define AR_RxRSSIAnt11_S          8
544
+#define AR_RxRSSIAnt12            0x00ff0000
545
+#define AR_RxRSSIAnt12_S          16
546
+#define AR_RxRSSICombined         0xff000000
547
+#define AR_RxRSSICombined_S       24
548
+
549
+#define AR_RxEVM0           ds_rxstatus4
550
+#define AR_RxEVM1           ds_rxstatus5
551
+#define AR_RxEVM2           ds_rxstatus6
552
+
553
+#define AR_RxDone           0x00000001
554
+#define AR_RxFrameOK        0x00000002
555
+#define AR_CRCErr           0x00000004
556
+#define AR_DecryptCRCErr    0x00000008
557
+#define AR_PHYErr           0x00000010
558
+#define AR_MichaelErr       0x00000020
559
+#define AR_PreDelimCRCErr   0x00000040
560
+#define AR_RxStatusRsvd70   0x00000080
561
+#define AR_RxKeyIdxValid    0x00000100
562
+#define AR_KeyIdx           0x0000fe00
563
+#define AR_KeyIdx_S         9
564
+#define AR_PHYErrCode       0x0000ff00
565
+#define AR_PHYErrCode_S     8
566
+#define AR_RxMoreAggr       0x00010000
567
+#define AR_RxAggr           0x00020000
568
+#define AR_PostDelimCRCErr  0x00040000
569
+#define AR_RxStatusRsvd71   0x3ff80000
570
+#define AR_DecryptBusyErr   0x40000000
571
+#define AR_KeyMiss          0x80000000
572
+
573
+enum ath9k_tx_queue {
574
+	ATH9K_TX_QUEUE_INACTIVE = 0,
575
+	ATH9K_TX_QUEUE_DATA,
576
+};
577
+
578
+#define	ATH9K_NUM_TX_QUEUES 1
579
+
580
+/* Used as a queue subtype instead of a WMM AC */
581
+#define ATH9K_WME_UPSD	4
582
+
583
+enum ath9k_tx_queue_flags {
584
+	TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
585
+	TXQ_FLAG_TXERRINT_ENABLE = 0x0001,
586
+	TXQ_FLAG_TXDESCINT_ENABLE = 0x0002,
587
+	TXQ_FLAG_TXEOLINT_ENABLE = 0x0004,
588
+	TXQ_FLAG_TXURNINT_ENABLE = 0x0008,
589
+	TXQ_FLAG_BACKOFF_DISABLE = 0x0010,
590
+	TXQ_FLAG_COMPRESSION_ENABLE = 0x0020,
591
+	TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE = 0x0040,
592
+	TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE = 0x0080,
593
+};
594
+
595
+#define ATH9K_TXQ_USEDEFAULT ((u32) -1)
596
+#define ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS 0x00000001
597
+
598
+#define ATH9K_DECOMP_MASK_SIZE     128
599
+#define ATH9K_READY_TIME_LO_BOUND  50
600
+#define ATH9K_READY_TIME_HI_BOUND  96
601
+
602
+enum ath9k_pkt_type {
603
+	ATH9K_PKT_TYPE_NORMAL = 0,
604
+	ATH9K_PKT_TYPE_ATIM,
605
+	ATH9K_PKT_TYPE_PSPOLL,
606
+	ATH9K_PKT_TYPE_BEACON,
607
+	ATH9K_PKT_TYPE_PROBE_RESP,
608
+	ATH9K_PKT_TYPE_CHIRP,
609
+	ATH9K_PKT_TYPE_GRP_POLL,
610
+};
611
+
612
+struct ath9k_tx_queue_info {
613
+	u32 tqi_ver;
614
+	enum ath9k_tx_queue tqi_type;
615
+	int tqi_subtype;
616
+	enum ath9k_tx_queue_flags tqi_qflags;
617
+	u32 tqi_priority;
618
+	u32 tqi_aifs;
619
+	u32 tqi_cwmin;
620
+	u32 tqi_cwmax;
621
+	u16 tqi_shretry;
622
+	u16 tqi_lgretry;
623
+	u32 tqi_cbrPeriod;
624
+	u32 tqi_cbrOverflowLimit;
625
+	u32 tqi_burstTime;
626
+	u32 tqi_readyTime;
627
+	u32 tqi_physCompBuf;
628
+	u32 tqi_intFlags;
629
+};
630
+
631
+enum ath9k_rx_filter {
632
+	ATH9K_RX_FILTER_UCAST = 0x00000001,
633
+	ATH9K_RX_FILTER_MCAST = 0x00000002,
634
+	ATH9K_RX_FILTER_BCAST = 0x00000004,
635
+	ATH9K_RX_FILTER_CONTROL = 0x00000008,
636
+	ATH9K_RX_FILTER_BEACON = 0x00000010,
637
+	ATH9K_RX_FILTER_PROM = 0x00000020,
638
+	ATH9K_RX_FILTER_PROBEREQ = 0x00000080,
639
+	ATH9K_RX_FILTER_PHYERR = 0x00000100,
640
+	ATH9K_RX_FILTER_MYBEACON = 0x00000200,
641
+	ATH9K_RX_FILTER_COMP_BAR = 0x00000400,
642
+	ATH9K_RX_FILTER_COMP_BA = 0x00000800,
643
+	ATH9K_RX_FILTER_UNCOMP_BA_BAR = 0x00001000,
644
+	ATH9K_RX_FILTER_PSPOLL = 0x00004000,
645
+	ATH9K_RX_FILTER_PHYRADAR = 0x00002000,
646
+	ATH9K_RX_FILTER_MCAST_BCAST_ALL = 0x00008000,
647
+};
648
+
649
+#define ATH9K_RATESERIES_RTS_CTS  0x0001
650
+#define ATH9K_RATESERIES_2040     0x0002
651
+#define ATH9K_RATESERIES_HALFGI   0x0004
652
+#define ATH9K_RATESERIES_STBC     0x0008
653
+
654
+struct ath9k_11n_rate_series {
655
+	u32 Tries;
656
+	u32 Rate;
657
+	u32 PktDuration;
658
+	u32 ChSel;
659
+	u32 RateFlags;
660
+};
661
+
662
+enum ath9k_key_type {
663
+	ATH9K_KEY_TYPE_CLEAR,
664
+	ATH9K_KEY_TYPE_WEP,
665
+	ATH9K_KEY_TYPE_AES,
666
+	ATH9K_KEY_TYPE_TKIP,
667
+};
668
+
669
+struct ath_hw;
670
+struct ath9k_channel;
671
+enum ath9k_int;
672
+
673
+u32 ath9k_hw_gettxbuf(struct ath_hw *ah, u32 q);
674
+void ath9k_hw_puttxbuf(struct ath_hw *ah, u32 q, u32 txdp);
675
+void ath9k_hw_txstart(struct ath_hw *ah, u32 q);
676
+void ath9k_hw_cleartxdesc(struct ath_hw *ah, void *ds);
677
+u32 ath9k_hw_numtxpending(struct ath_hw *ah, u32 q);
678
+int ath9k_hw_updatetxtriglevel(struct ath_hw *ah, int bIncTrigLevel);
679
+int ath9k_hw_stop_dma_queue(struct ath_hw *ah, u32 q);
680
+void ath9k_hw_abort_tx_dma(struct ath_hw *ah);
681
+void ath9k_hw_gettxintrtxqs(struct ath_hw *ah, u32 *txqs);
682
+int ath9k_hw_set_txq_props(struct ath_hw *ah, int q,
683
+			    const struct ath9k_tx_queue_info *qinfo);
684
+int ath9k_hw_get_txq_props(struct ath_hw *ah, int q,
685
+			    struct ath9k_tx_queue_info *qinfo);
686
+int ath9k_hw_setuptxqueue(struct ath_hw *ah, enum ath9k_tx_queue type,
687
+			  const struct ath9k_tx_queue_info *qinfo);
688
+int ath9k_hw_releasetxqueue(struct ath_hw *ah, u32 q);
689
+int ath9k_hw_resettxqueue(struct ath_hw *ah, u32 q);
690
+int ath9k_hw_rxprocdesc(struct ath_hw *ah, struct ath_desc *ds,
691
+			struct ath_rx_status *rs, u64 tsf);
692
+void ath9k_hw_setuprxdesc(struct ath_hw *ah, struct ath_desc *ds,
693
+			  u32 size, u32 flags);
694
+int ath9k_hw_setrxabort(struct ath_hw *ah, int set);
695
+void ath9k_hw_putrxbuf(struct ath_hw *ah, u32 rxdp);
696
+void ath9k_hw_startpcureceive(struct ath_hw *ah, int is_scanning);
697
+void ath9k_hw_abortpcurecv(struct ath_hw *ah);
698
+int ath9k_hw_stopdmarecv(struct ath_hw *ah, int *reset);
699
+
700
+/* Interrupt Handling */
701
+int ath9k_hw_intrpend(struct ath_hw *ah);
702
+void ath9k_hw_set_interrupts(struct ath_hw *ah, enum ath9k_int ints);
703
+void ath9k_hw_enable_interrupts(struct ath_hw *ah);
704
+void ath9k_hw_disable_interrupts(struct ath_hw *ah);
705
+
706
+void ar9002_hw_attach_mac_ops(struct ath_hw *ah);
707
+
708
+#endif /* MAC_H */

+ 51
- 0
src/drivers/net/ath/ath9k/phy.h View File

@@ -0,0 +1,51 @@
1
+/*
2
+ * Copyright (c) 2008-2011 Atheros Communications Inc.
3
+ *
4
+ * Permission to use, copy, modify, and/or distribute this software for any
5
+ * purpose with or without fee is hereby granted, provided that the above
6
+ * copyright notice and this permission notice appear in all copies.
7
+ *
8
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
+ */
16
+
17
+#ifndef PHY_H
18
+#define PHY_H
19
+
20
+#define CHANSEL_DIV		15
21
+#define CHANSEL_2G(_freq)	(((_freq) * 0x10000) / CHANSEL_DIV)
22
+#define CHANSEL_5G(_freq)	(((_freq) * 0x8000) / CHANSEL_DIV)
23
+
24
+#define AR_PHY_BASE     0x9800
25
+#define AR_PHY(_n)      (AR_PHY_BASE + ((_n)<<2))
26
+
27
+#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX   0x0007E000
28
+#define AR_PHY_TX_PWRCTRL_TX_GAIN_TAB_MAX_S 13
29
+#define AR_PHY_TX_GAIN_CLC       0x0000001E
30
+#define AR_PHY_TX_GAIN_CLC_S     1
31
+#define AR_PHY_TX_GAIN           0x0007F000
32
+#define AR_PHY_TX_GAIN_S         12
33
+
34
+#define AR_PHY_CLC_TBL1      0xa35c
35
+#define AR_PHY_CLC_I0        0x07ff0000
36
+#define AR_PHY_CLC_I0_S      16
37
+#define AR_PHY_CLC_Q0        0x0000ffd0
38
+#define AR_PHY_CLC_Q0_S      5
39
+
40
+#define ANTSWAP_AB 0x0001
41
+#define REDUCE_CHAIN_0 0x00000050
42
+#define REDUCE_CHAIN_1 0x00000051
43
+#define AR_PHY_CHIP_ID 0x9818
44
+
45
+#define	AR_PHY_TIMING11_SPUR_FREQ_SD		0x3FF00000
46
+#define	AR_PHY_TIMING11_SPUR_FREQ_SD_S		20
47
+
48
+#define AR_PHY_PLL_CONTROL 0x16180
49
+#define AR_PHY_PLL_MODE 0x16184
50
+
51
+#endif

+ 1919
- 0
src/drivers/net/ath/ath9k/reg.h
File diff suppressed because it is too large
View File


+ 183
- 0
src/drivers/net/ath/ath_hw.c View File

@@ -0,0 +1,183 @@
1
+/*
2
+ * Copyright (c) 2009 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/io.h>
21
+
22
+#include "ath.h"
23
+#include "reg.h"
24
+
25
+#define REG_READ	(common->ops->read)
26
+#define REG_WRITE	(common->ops->write)
27
+
28
+/**
29
+ * ath_hw_set_bssid_mask - filter out bssids we listen
30
+ *
31
+ * @common: the ath_common struct for the device.
32
+ *
33
+ * BSSID masking is a method used by AR5212 and newer hardware to inform PCU
34
+ * which bits of the interface's MAC address should be looked at when trying
35
+ * to decide which packets to ACK. In station mode and AP mode with a single
36
+ * BSS every bit matters since we lock to only one BSS. In AP mode with
37
+ * multiple BSSes (virtual interfaces) not every bit matters because hw must
38
+ * accept frames for all BSSes and so we tweak some bits of our mac address
39
+ * in order to have multiple BSSes.
40
+ *
41
+ * NOTE: This is a simple filter and does *not* filter out all
42
+ * relevant frames. Some frames that are not for us might get ACKed from us
43
+ * by PCU because they just match the mask.
44
+ *
45
+ * When handling multiple BSSes you can get the BSSID mask by computing the
46
+ * set of  ~ ( MAC XOR BSSID ) for all bssids we handle.
47
+ *
48
+ * When you do this you are essentially computing the common bits of all your
49
+ * BSSes. Later it is assumed the hardware will "and" (&) the BSSID mask with
50
+ * the MAC address to obtain the relevant bits and compare the result with
51
+ * (frame's BSSID & mask) to see if they match.
52
+ *
53
+ * Simple example: on your card you have have two BSSes you have created with
54
+ * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address.
55
+ * There is another BSSID-03 but you are not part of it. For simplicity's sake,
56
+ * assuming only 4 bits for a mac address and for BSSIDs you can then have:
57
+ *
58
+ *                  \
59
+ * MAC:        0001 |
60
+ * BSSID-01:   0100 | --> Belongs to us
61
+ * BSSID-02:   1001 |
62
+ *                  /
63
+ * -------------------
64
+ * BSSID-03:   0110  | --> External
65
+ * -------------------
66
+ *
67
+ * Our bssid_mask would then be:
68
+ *
69
+ *             On loop iteration for BSSID-01:
70
+ *             ~(0001 ^ 0100)  -> ~(0101)
71
+ *                             ->   1010
72
+ *             bssid_mask      =    1010
73
+ *
74
+ *             On loop iteration for BSSID-02:
75
+ *             bssid_mask &= ~(0001   ^   1001)
76
+ *             bssid_mask =   (1010)  & ~(0001 ^ 1001)
77
+ *             bssid_mask =   (1010)  & ~(1000)
78
+ *             bssid_mask =   (1010)  &  (0111)
79
+ *             bssid_mask =   0010
80
+ *
81
+ * A bssid_mask of 0010 means "only pay attention to the second least
82
+ * significant bit". This is because its the only bit common
83
+ * amongst the MAC and all BSSIDs we support. To findout what the real
84
+ * common bit is we can simply "&" the bssid_mask now with any BSSID we have
85
+ * or our MAC address (we assume the hardware uses the MAC address).
86
+ *
87
+ * Now, suppose there's an incoming frame for BSSID-03:
88
+ *
89
+ * IFRAME-01:  0110
90
+ *
91
+ * An easy eye-inspeciton of this already should tell you that this frame
92
+ * will not pass our check. This is because the bssid_mask tells the
93
+ * hardware to only look at the second least significant bit and the
94
+ * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB
95
+ * as 1, which does not match 0.
96
+ *
97
+ * So with IFRAME-01 we *assume* the hardware will do:
98
+ *
99
+ *     allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
100
+ *  --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0;
101
+ *  --> allow = (0010) == 0000 ? 1 : 0;
102
+ *  --> allow = 0
103
+ *
104
+ *  Lets now test a frame that should work:
105
+ *
106
+ * IFRAME-02:  0001 (we should allow)
107
+ *
108
+ *     allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0;
109
+ *  --> allow = (0001 & 0010) ==  (0010 & 0001) ? 1 :0;
110
+ *  --> allow = (0000) == (0000)
111
+ *  --> allow = 1
112
+ *
113
+ * Other examples:
114
+ *
115
+ * IFRAME-03:  0100 --> allowed
116
+ * IFRAME-04:  1001 --> allowed
117
+ * IFRAME-05:  1101 --> allowed but its not for us!!!
118
+ *
119
+ */
120
+void ath_hw_setbssidmask(struct ath_common *common)
121
+{
122
+	void *ah = common->ah;
123
+
124
+	REG_WRITE(ah, get_unaligned_le32(common->bssidmask), AR_BSSMSKL);
125
+	REG_WRITE(ah, get_unaligned_le16(common->bssidmask + 4), AR_BSSMSKU);
126
+}
127
+
128
+
129
+/**
130
+ * ath_hw_cycle_counters_update - common function to update cycle counters
131
+ *
132
+ * @common: the ath_common struct for the device.
133
+ *
134
+ * This function is used to update all cycle counters in one place.
135
+ * It has to be called while holding common->cc_lock!
136
+ */
137
+void ath_hw_cycle_counters_update(struct ath_common *common)
138
+{
139
+	u32 cycles, busy, rx, tx;
140
+	void *ah = common->ah;
141
+
142
+	/* freeze */
143
+	REG_WRITE(ah, AR_MIBC_FMC, AR_MIBC);
144
+
145
+	/* read */
146
+	cycles = REG_READ(ah, AR_CCCNT);
147
+	busy = REG_READ(ah, AR_RCCNT);
148
+	rx = REG_READ(ah, AR_RFCNT);
149
+	tx = REG_READ(ah, AR_TFCNT);
150
+
151
+	/* clear */
152
+	REG_WRITE(ah, 0, AR_CCCNT);
153
+	REG_WRITE(ah, 0, AR_RFCNT);
154
+	REG_WRITE(ah, 0, AR_RCCNT);
155
+	REG_WRITE(ah, 0, AR_TFCNT);
156
+
157
+	/* unfreeze */
158
+	REG_WRITE(ah, 0, AR_MIBC);
159
+
160
+	/* update all cycle counters here */
161
+	common->cc_ani.cycles += cycles;
162
+	common->cc_ani.rx_busy += busy;
163
+	common->cc_ani.rx_frame += rx;
164
+	common->cc_ani.tx_frame += tx;
165
+
166
+	common->cc_survey.cycles += cycles;
167
+	common->cc_survey.rx_busy += busy;
168
+	common->cc_survey.rx_frame += rx;
169
+	common->cc_survey.tx_frame += tx;
170
+}
171
+
172
+int32_t ath_hw_get_listen_time(struct ath_common *common)
173
+{
174
+	struct ath_cycle_counters *cc = &common->cc_ani;
175
+	int32_t listen_time;
176
+
177
+	listen_time = (cc->cycles - cc->rx_frame - cc->tx_frame) /
178
+		      (common->clockrate * 1000);
179
+
180
+	memset(cc, 0, sizeof(*cc));
181
+
182
+	return listen_time;
183
+}

+ 82
- 0
src/drivers/net/ath/ath_key.c View File

@@ -0,0 +1,82 @@
1
+/*
2
+ * Copyright (c) 2009 Atheros Communications Inc.
3
+ * Copyright (c) 2010 Bruno Randolf <br1@einfach.org>
4
+ *
5
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
6
+ * Original from Linux kernel 3.0.1
7
+ *
8
+ * Permission to use, copy, modify, and/or 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
+#include "ath.h"
22
+#include "reg.h"
23
+
24
+#define REG_READ			(common->ops->read)
25
+#define REG_WRITE(_ah, _reg, _val)	(common->ops->write)(_ah, _val, _reg)
26
+#define ENABLE_REGWRITE_BUFFER(_ah)			\
27
+	if (common->ops->enable_write_buffer)		\
28
+		common->ops->enable_write_buffer((_ah));
29
+
30
+#define REGWRITE_BUFFER_FLUSH(_ah)			\
31
+	if (common->ops->write_flush)			\
32
+		common->ops->write_flush((_ah));
33
+
34
+
35
+#define IEEE80211_WEP_NKID      4       /* number of key ids */
36
+
37
+/************************/
38
+/* Key Cache Management */
39
+/************************/
40
+
41
+int ath_hw_keyreset(struct ath_common *common, u16 entry)
42
+{
43
+	u32 keyType;
44
+	void *ah = common->ah;
45
+
46
+	if (entry >= common->keymax) {
47
+		DBG("ath: keycache entry %d out of range\n", entry);
48
+		return 0;
49
+	}
50
+
51
+	keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
52
+
53
+	ENABLE_REGWRITE_BUFFER(ah);
54
+
55
+	REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
56
+	REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
57
+	REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
58
+	REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
59
+	REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
60
+	REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
61
+	REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
62
+	REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
63
+
64
+	if (keyType == AR_KEYTABLE_TYPE_TKIP) {
65
+		u16 micentry = entry + 64;
66
+
67
+		REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
68
+		REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
69
+		REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
70
+		REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
71
+		if (common->crypt_caps & ATH_CRYPT_CAP_MIC_COMBINED) {
72
+			REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
73
+			REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
74
+				  AR_KEYTABLE_TYPE_CLR);
75
+		}
76
+
77
+	}
78
+
79
+	REGWRITE_BUFFER_FLUSH(ah);
80
+
81
+	return 1;
82
+}

+ 59
- 0
src/drivers/net/ath/ath_main.c View File

@@ -0,0 +1,59 @@
1
+/*
2
+ * Copyright (c) 2009 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 <ipxe/io.h>
21
+
22
+#include "ath.h"
23
+
24
+struct io_buffer *ath_rxbuf_alloc(struct ath_common *common,
25
+				u32 len,
26
+				u32 *iob_addr)
27
+{
28
+	struct io_buffer *iob;
29
+	u32 off;
30
+
31
+	/*
32
+	 * Cache-line-align.  This is important (for the
33
+	 * 5210 at least) as not doing so causes bogus data
34
+	 * in rx'd frames.
35
+	 */
36
+
37
+	/* Note: the kernel can allocate a value greater than
38
+	 * what we ask it to give us. We really only need 4 KB as that
39
+	 * is this hardware supports and in fact we need at least 3849
40
+	 * as that is the MAX AMSDU size this hardware supports.
41
+	 * Unfortunately this means we may get 8 KB here from the
42
+	 * kernel... and that is actually what is observed on some
43
+	 * systems :( */
44
+	iob = alloc_iob(len + common->cachelsz - 1);
45
+	if (iob != NULL) {
46
+		*iob_addr = virt_to_bus(iob->data);
47
+		off = ((unsigned long) iob->data) % common->cachelsz;
48
+		if (off != 0)
49
+		{
50
+			iob_reserve(iob, common->cachelsz - off);
51
+			*iob_addr += common->cachelsz - off;
52
+		}
53
+	} else {
54
+		DBG("ath: iobuffer alloc of size %d failed\n", len);
55
+		return NULL;
56
+	}
57
+
58
+	return iob;
59
+}

+ 602
- 0
src/drivers/net/ath/ath_regd.c View File

@@ -0,0 +1,602 @@
1
+/*
2
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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 "regd.h"
21
+#include "regd_common.h"
22
+
23
+/*
24
+ * This is a set of common rules used by our world regulatory domains.
25
+ * We have 12 world regulatory domains. To save space we consolidate
26
+ * the regulatory domains in 5 structures by frequency and change
27
+ * the flags on our reg_notifier() on a case by case basis.
28
+ */
29
+
30
+/* Only these channels all allow active scan on all world regulatory domains */
31
+#define ATH9K_2GHZ_CH01_11	REG_RULE(2412-10, 2462+10, 40, 0, 20, 0)
32
+
33
+/* We enable active scan on these a case by case basis by regulatory domain */
34
+#define ATH9K_2GHZ_CH12_13	REG_RULE(2467-10, 2472+10, 40, 0, 20,\
35
+					NL80211_RRF_PASSIVE_SCAN)
36
+#define ATH9K_2GHZ_CH14		REG_RULE(2484-10, 2484+10, 40, 0, 20,\
37
+				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_OFDM)
38
+
39
+/* We allow IBSS on these on a case by case basis by regulatory domain */
40
+#define ATH9K_5GHZ_5150_5350	REG_RULE(5150-10, 5350+10, 40, 0, 30,\
41
+				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
42
+#define ATH9K_5GHZ_5470_5850	REG_RULE(5470-10, 5850+10, 40, 0, 30,\
43
+				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
44
+#define ATH9K_5GHZ_5725_5850	REG_RULE(5725-10, 5850+10, 40, 0, 30,\
45
+				NL80211_RRF_PASSIVE_SCAN | NL80211_RRF_NO_IBSS)
46
+
47
+#define ATH9K_2GHZ_ALL		ATH9K_2GHZ_CH01_11, \
48
+				ATH9K_2GHZ_CH12_13, \
49
+				ATH9K_2GHZ_CH14
50
+
51
+#define ATH9K_5GHZ_ALL		ATH9K_5GHZ_5150_5350, \
52
+				ATH9K_5GHZ_5470_5850
53
+
54
+/* This one skips what we call "mid band" */
55
+#define ATH9K_5GHZ_NO_MIDBAND	ATH9K_5GHZ_5150_5350, \
56
+				ATH9K_5GHZ_5725_5850
57
+
58
+///* Can be used for:
59
+// * 0x60, 0x61, 0x62 */
60
+//static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
61
+//	.n_reg_rules = 5,
62
+//	.alpha2 =  "99",
63
+//	.reg_rules = {
64
+//		ATH9K_2GHZ_ALL,
65
+//		ATH9K_5GHZ_ALL,
66
+//	}
67
+//};
68
+//
69
+///* Can be used by 0x63 and 0x65 */
70
+//static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
71
+//	.n_reg_rules = 4,
72
+//	.alpha2 =  "99",
73
+//	.reg_rules = {
74
+//		ATH9K_2GHZ_CH01_11,
75
+//		ATH9K_2GHZ_CH12_13,
76
+//		ATH9K_5GHZ_NO_MIDBAND,
77
+//	}
78
+//};
79
+//
80
+///* Can be used by 0x64 only */
81
+//static const struct ieee80211_regdomain ath_world_regdom_64 = {
82
+//	.n_reg_rules = 3,
83
+//	.alpha2 =  "99",
84
+//	.reg_rules = {
85
+//		ATH9K_2GHZ_CH01_11,
86
+//		ATH9K_5GHZ_NO_MIDBAND,
87
+//	}
88
+//};
89
+//
90
+///* Can be used by 0x66 and 0x69 */
91
+//static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
92
+//	.n_reg_rules = 3,
93
+//	.alpha2 =  "99",
94
+//	.reg_rules = {
95
+//		ATH9K_2GHZ_CH01_11,
96
+//		ATH9K_5GHZ_ALL,
97
+//	}
98
+//};
99
+//
100
+///* Can be used by 0x67, 0x68, 0x6A and 0x6C */
101
+//static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
102
+//	.n_reg_rules = 4,
103
+//	.alpha2 =  "99",
104
+//	.reg_rules = {
105
+//		ATH9K_2GHZ_CH01_11,
106
+//		ATH9K_2GHZ_CH12_13,
107
+//		ATH9K_5GHZ_ALL,
108
+//	}
109
+//};
110
+//
111
+//static inline int is_wwr_sku(u16 regd)
112
+//{
113
+//	return ((regd & COUNTRY_ERD_FLAG) != COUNTRY_ERD_FLAG) &&
114
+//		(((regd & WORLD_SKU_MASK) == WORLD_SKU_PREFIX) ||
115
+//		(regd == WORLD));
116
+//}
117
+//
118
+//static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
119
+//{
120
+//	return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
121
+//}
122
+//
123
+//int ath_is_world_regd(struct ath_regulatory *reg)
124
+//{
125
+//	return is_wwr_sku(ath_regd_get_eepromRD(reg));
126
+//}
127
+//
128
+//static const struct ieee80211_regdomain *ath_default_world_regdomain(void)
129
+//{
130
+//	/* this is the most restrictive */
131
+//	return &ath_world_regdom_64;
132
+//}
133
+//
134
+//static const struct
135
+//ieee80211_regdomain *ath_world_regdomain(struct ath_regulatory *reg)
136
+//{
137
+//	switch (reg->regpair->regDmnEnum) {
138
+//	case 0x60:
139
+//	case 0x61:
140
+//	case 0x62:
141
+//		return &ath_world_regdom_60_61_62;
142
+//	case 0x63:
143
+//	case 0x65:
144
+//		return &ath_world_regdom_63_65;
145
+//	case 0x64:
146
+//		return &ath_world_regdom_64;
147
+//	case 0x66:
148
+//	case 0x69:
149
+//		return &ath_world_regdom_66_69;
150
+//	case 0x67:
151
+//	case 0x68:
152
+//	case 0x6A:
153
+//	case 0x6C:
154
+//		return &ath_world_regdom_67_68_6A_6C;
155
+//	default:
156
+//		WARN_ON(1);
157
+//		return ath_default_world_regdomain();
158
+//	}
159
+//}
160
+//
161
+//int ath_is_49ghz_allowed(u16 regdomain)
162
+//{
163
+//	/* possibly more */
164
+//	return regdomain == MKK9_MKKC;
165
+//}
166
+//
167
+///* Frequency is one where radar detection is required */
168
+//static int ath_is_radar_freq(u16 center_freq)
169
+//{
170
+//	return (center_freq >= 5260 && center_freq <= 5700);
171
+//}
172
+//
173
+///*
174
+// * N.B: These exception rules do not apply radar freqs.
175
+// *
176
+// * - We enable adhoc (or beaconing) if allowed by 11d
177
+// * - We enable active scan if the channel is allowed by 11d
178
+// * - If no country IE has been processed and a we determine we have
179
+// *   received a beacon on a channel we can enable active scan and
180
+// *   adhoc (or beaconing).
181
+// */
182
+//static void
183
+//ath_reg_apply_beaconing_flags(struct wiphy *wiphy,
184
+//			      enum nl80211_reg_initiator initiator)
185
+//{
186
+//	int band;
187
+//	struct ieee80211_supported_band *sband;
188
+//	const struct ieee80211_reg_rule *reg_rule;
189
+//	struct net80211_channel *ch;
190
+//	unsigned int i;
191
+//	u32 bandwidth = 0;
192
+//	int r;
193
+//
194
+//	for (band = 0; band < NET80211_NR_BANDS; band++) {
195
+//
196
+//		if (!wiphy->bands[band])
197
+//			continue;
198
+//
199
+//		sband = wiphy->bands[band];
200
+//
201
+//		for (i = 0; i < sband->n_channels; i++) {
202
+//
203
+//			ch = &sband->channels[i];
204
+//
205
+//			if (ath_is_radar_freq(ch->center_freq) ||
206
+//			    (ch->flags & IEEE80211_CHAN_RADAR))
207
+//				continue;
208
+//
209
+//			if (initiator == NL80211_REGDOM_SET_BY_COUNTRY_IE) {
210
+//				r = freq_reg_info(wiphy,
211
+//						  ch->center_freq,
212
+//						  bandwidth,
213
+//						  &reg_rule);
214
+//				if (r)
215
+//					continue;
216
+//				/*
217
+//				 * If 11d had a rule for this channel ensure
218
+//				 * we enable adhoc/beaconing if it allows us to
219
+//				 * use it. Note that we would have disabled it
220
+//				 * by applying our static world regdomain by
221
+//				 * default during init, prior to calling our
222
+//				 * regulatory_hint().
223
+//				 */
224
+//				if (!(reg_rule->flags &
225
+//				    NL80211_RRF_NO_IBSS))
226
+//					ch->flags &=
227
+//					  ~IEEE80211_CHAN_NO_IBSS;
228
+//				if (!(reg_rule->flags &
229
+//				    NL80211_RRF_PASSIVE_SCAN))
230
+//					ch->flags &=
231
+//					  ~IEEE80211_CHAN_PASSIVE_SCAN;
232
+//			} else {
233
+//				if (ch->beacon_found)
234
+//					ch->flags &= ~(IEEE80211_CHAN_NO_IBSS |
235
+//					  IEEE80211_CHAN_PASSIVE_SCAN);
236
+//			}
237
+//		}
238
+//	}
239
+//
240
+//}
241
+//
242
+///* Allows active scan scan on Ch 12 and 13 */
243
+//static void
244
+//ath_reg_apply_active_scan_flags(struct wiphy *wiphy,
245
+//				enum nl80211_reg_initiator initiator)
246
+//{
247
+//	struct ieee80211_supported_band *sband;
248
+//	struct net80211_channel *ch;
249
+//	const struct ieee80211_reg_rule *reg_rule;
250
+//	u32 bandwidth = 0;
251
+//	int r;
252
+//
253
+//	sband = wiphy->bands[NET80211_BAND_2GHZ];
254
+//
255
+//	/*
256
+//	 * If no country IE has been received always enable active scan
257
+//	 * on these channels. This is only done for specific regulatory SKUs
258
+//	 */
259
+//	if (initiator != NL80211_REGDOM_SET_BY_COUNTRY_IE) {
260
+//		ch = &sband->channels[11]; /* CH 12 */
261
+//		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
262
+//			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
263
+//		ch = &sband->channels[12]; /* CH 13 */
264
+//		if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
265
+//			ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
266
+//		return;
267
+//	}
268
+//
269
+//	/*
270
+//	 * If a country IE has been received check its rule for this
271
+//	 * channel first before enabling active scan. The passive scan
272
+//	 * would have been enforced by the initial processing of our
273
+//	 * custom regulatory domain.
274
+//	 */
275
+//
276
+//	ch = &sband->channels[11]; /* CH 12 */
277
+//	r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
278
+//	if (!r) {
279
+//		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
280
+//			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
281
+//				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
282
+//	}
283
+//
284
+//	ch = &sband->channels[12]; /* CH 13 */
285
+//	r = freq_reg_info(wiphy, ch->center_freq, bandwidth, &reg_rule);
286
+//	if (!r) {
287
+//		if (!(reg_rule->flags & NL80211_RRF_PASSIVE_SCAN))
288
+//			if (ch->flags & IEEE80211_CHAN_PASSIVE_SCAN)
289
+//				ch->flags &= ~IEEE80211_CHAN_PASSIVE_SCAN;
290
+//	}
291
+//}
292
+//
293
+///* Always apply Radar/DFS rules on freq range 5260 MHz - 5700 MHz */
294
+//static void ath_reg_apply_radar_flags(struct wiphy *wiphy)
295
+//{
296
+//	struct ieee80211_supported_band *sband;
297
+//	struct net80211_channel *ch;
298
+//	unsigned int i;
299
+//
300
+//	if (!wiphy->bands[NET80211_BAND_5GHZ])
301
+//		return;
302
+//
303
+//	sband = wiphy->bands[NET80211_BAND_5GHZ];
304
+//
305
+//	for (i = 0; i < sband->n_channels; i++) {
306
+//		ch = &sband->channels[i];
307
+//		if (!ath_is_radar_freq(ch->center_freq))
308
+//			continue;
309
+//		/* We always enable radar detection/DFS on this
310
+//		 * frequency range. Additionally we also apply on
311
+//		 * this frequency range:
312
+//		 * - If STA mode does not yet have DFS supports disable
313
+//		 *   active scanning
314
+//		 * - If adhoc mode does not support DFS yet then
315
+//		 *   disable adhoc in the frequency.
316
+//		 * - If AP mode does not yet support radar detection/DFS
317
+//		 *   do not allow AP mode
318
+//		 */
319
+//		if (!(ch->flags & IEEE80211_CHAN_DISABLED))
320
+//			ch->flags |= IEEE80211_CHAN_RADAR |
321
+//				     IEEE80211_CHAN_NO_IBSS |
322
+//				     IEEE80211_CHAN_PASSIVE_SCAN;
323
+//	}
324
+//}
325
+//
326
+//static void ath_reg_apply_world_flags(struct wiphy *wiphy,
327
+//				      enum nl80211_reg_initiator initiator,
328
+//				      struct ath_regulatory *reg)
329
+//{
330
+//	switch (reg->regpair->regDmnEnum) {
331
+//	case 0x60:
332
+//	case 0x63:
333
+//	case 0x66:
334
+//	case 0x67:
335
+//	case 0x6C:
336
+//		ath_reg_apply_beaconing_flags(wiphy, initiator);
337
+//		break;
338
+//	case 0x68:
339
+//		ath_reg_apply_beaconing_flags(wiphy, initiator);
340
+//		ath_reg_apply_active_scan_flags(wiphy, initiator);
341
+//		break;
342
+//	}
343
+//}
344
+//
345
+//int ath_reg_notifier_apply(struct wiphy *wiphy,
346
+//			   struct regulatory_request *request,
347
+//			   struct ath_regulatory *reg)
348
+//{
349
+//	/* We always apply this */
350
+//	ath_reg_apply_radar_flags(wiphy);
351
+//
352
+//	/*
353
+//	 * This would happen when we have sent a custom regulatory request
354
+//	 * a world regulatory domain and the scheduler hasn't yet processed
355
+//	 * any pending requests in the queue.
356
+//	 */
357
+//	if (!request)
358
+//		return 0;
359
+//
360
+//	switch (request->initiator) {
361
+//	case NL80211_REGDOM_SET_BY_DRIVER:
362
+//	case NL80211_REGDOM_SET_BY_CORE:
363
+//	case NL80211_REGDOM_SET_BY_USER:
364
+//		break;
365
+//	case NL80211_REGDOM_SET_BY_COUNTRY_IE:
366
+//		if (ath_is_world_regd(reg))
367
+//			ath_reg_apply_world_flags(wiphy, request->initiator,
368
+//						  reg);
369
+//		break;
370
+//	}
371
+//
372
+//	return 0;
373
+//}
374
+//
375
+//static int ath_regd_is_eeprom_valid(struct ath_regulatory *reg)
376
+//{
377
+//	u16 rd = ath_regd_get_eepromRD(reg);
378
+//	int i;
379
+//
380
+//	if (rd & COUNTRY_ERD_FLAG) {
381
+//		/* EEPROM value is a country code */
382
+//		u16 cc = rd & ~COUNTRY_ERD_FLAG;
383
+//		DBG2(
384
+//		       "ath: EEPROM indicates we should expect "
385
+//			"a country code\n");
386
+//		for (i = 0; i < ARRAY_SIZE(allCountries); i++)
387
+//			if (allCountries[i].countryCode == cc)
388
+//				return 1;
389
+//	} else {
390
+//		/* EEPROM value is a regpair value */
391
+//		if (rd != CTRY_DEFAULT)
392
+//			DBG2("ath: EEPROM indicates we "
393
+//			       "should expect a direct regpair map\n");
394
+//		for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++)
395
+//			if (regDomainPairs[i].regDmnEnum == rd)
396
+//				return 1;
397
+//	}
398
+//	DBG(
399
+//		 "ath: invalid regulatory domain/country code 0x%x\n", rd);
400
+//	return 0;
401
+//}
402
+//
403
+///* EEPROM country code to regpair mapping */
404
+//static struct country_code_to_enum_rd*
405
+//ath_regd_find_country(u16 countryCode)
406
+//{
407
+//	int i;
408
+//
409
+//	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
410
+//		if (allCountries[i].countryCode == countryCode)
411
+//			return &allCountries[i];
412
+//	}
413
+//	return NULL;
414
+//}
415
+//
416
+///* EEPROM rd code to regpair mapping */
417
+//static struct country_code_to_enum_rd*
418
+//ath_regd_find_country_by_rd(int regdmn)
419
+//{
420
+//	int i;
421
+//
422
+//	for (i = 0; i < ARRAY_SIZE(allCountries); i++) {
423
+//		if (allCountries[i].regDmnEnum == regdmn)
424
+//			return &allCountries[i];
425
+//	}
426
+//	return NULL;
427
+//}
428
+//
429
+///* Returns the map of the EEPROM set RD to a country code */
430
+//static u16 ath_regd_get_default_country(u16 rd)
431
+//{
432
+//	if (rd & COUNTRY_ERD_FLAG) {
433
+//		struct country_code_to_enum_rd *country = NULL;
434
+//		u16 cc = rd & ~COUNTRY_ERD_FLAG;
435
+//
436
+//		country = ath_regd_find_country(cc);
437
+//		if (country != NULL)
438
+//			return cc;
439
+//	}
440
+//
441
+//	return CTRY_DEFAULT;
442
+//}
443
+//
444
+//static struct reg_dmn_pair_mapping*
445
+//ath_get_regpair(int regdmn)
446
+//{
447
+//	int i;
448
+//
449
+//	if (regdmn == NO_ENUMRD)
450
+//		return NULL;
451
+//	for (i = 0; i < ARRAY_SIZE(regDomainPairs); i++) {
452
+//		if (regDomainPairs[i].regDmnEnum == regdmn)
453
+//			return &regDomainPairs[i];
454
+//	}
455
+//	return NULL;
456
+//}
457
+//
458
+//static int
459
+//ath_regd_init_wiphy(struct ath_regulatory *reg,
460
+//		    struct wiphy *wiphy,
461
+//		    int (*reg_notifier)(struct wiphy *wiphy,
462
+//					struct regulatory_request *request))
463
+//{
464
+//	const struct ieee80211_regdomain *regd;
465
+//
466
+//	wiphy->reg_notifier = reg_notifier;
467
+//	wiphy->flags |= WIPHY_FLAG_STRICT_REGULATORY;
468
+//
469
+//	if (ath_is_world_regd(reg)) {
470
+//		/*
471
+//		 * Anything applied here (prior to wiphy registration) gets
472
+//		 * saved on the wiphy orig_* parameters
473
+//		 */
474
+//		regd = ath_world_regdomain(reg);
475
+//		wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
476
+//	} else {
477
+//		/*
478
+//		 * This gets applied in the case of the absence of CRDA,
479
+//		 * it's our own custom world regulatory domain, similar to
480
+//		 * cfg80211's but we enable passive scanning.
481
+//		 */
482
+//		regd = ath_default_world_regdomain();
483
+//	}
484
+//	wiphy_apply_custom_regulatory(wiphy, regd);
485
+//	ath_reg_apply_radar_flags(wiphy);
486
+//	ath_reg_apply_world_flags(wiphy, NL80211_REGDOM_SET_BY_DRIVER, reg);
487
+//	return 0;
488
+//}
489
+//
490
+///*
491
+// * Some users have reported their EEPROM programmed with
492
+// * 0x8000 set, this is not a supported regulatory domain
493
+// * but since we have more than one user with it we need
494
+// * a solution for them. We default to 0x64, which is the
495
+// * default Atheros world regulatory domain.
496
+// */
497
+//static void ath_regd_sanitize(struct ath_regulatory *reg)
498
+//{
499
+//	if (reg->current_rd != COUNTRY_ERD_FLAG)
500
+//		return;
501
+//	DBG2("ath: EEPROM regdomain sanitized\n");
502
+//	reg->current_rd = 0x64;
503
+//}
504
+//
505
+//int
506
+//ath_regd_init(struct ath_regulatory *reg,
507
+//	      struct wiphy *wiphy,
508
+//	      int (*reg_notifier)(struct wiphy *wiphy,
509
+//				  struct regulatory_request *request))
510
+//{
511
+//	struct country_code_to_enum_rd *country = NULL;
512
+//	u16 regdmn;
513
+//
514
+//	if (!reg)
515
+//		return -EINVAL;
516
+//
517
+//	ath_regd_sanitize(reg);
518
+//
519
+//	DBG2("ath: EEPROM regdomain: 0x%0x\n", reg->current_rd);
520
+//
521
+//	if (!ath_regd_is_eeprom_valid(reg)) {
522
+//		DBG("ath: Invalid EEPROM contents\n");
523
+//		return -EINVAL;
524
+//	}
525
+//
526
+//	regdmn = ath_regd_get_eepromRD(reg);
527
+//	reg->country_code = ath_regd_get_default_country(regdmn);
528
+//
529
+//	if (reg->country_code == CTRY_DEFAULT &&
530
+//	    regdmn == CTRY_DEFAULT) {
531
+//		DBG2("ath: EEPROM indicates default "
532
+//		       "country code should be used\n");
533
+//		reg->country_code = CTRY_UNITED_STATES;
534
+//	}
535
+//
536
+//	if (reg->country_code == CTRY_DEFAULT) {
537
+//		country = NULL;
538
+//	} else {
539
+//		DBG2("ath: doing EEPROM country->regdmn "
540
+//		       "map search\n");
541
+//		country = ath_regd_find_country(reg->country_code);
542
+//		if (country == NULL) {
543
+//			DBG(
544
+//				"ath: no valid country maps found for "
545
+//				"country code: 0x%0x\n",
546
+//				reg->country_code);
547
+//			return -EINVAL;
548
+//		} else {
549
+//			regdmn = country->regDmnEnum;
550
+//			DBG2("ath: country maps to "
551
+//			       "regdmn code: 0x%0x\n",
552
+//			       regdmn);
553
+//		}
554
+//	}
555
+//
556
+//	reg->regpair = ath_get_regpair(regdmn);
557
+//
558
+//	if (!reg->regpair) {
559
+//		DBG("ath: "
560
+//			"No regulatory domain pair found, cannot continue\n");
561
+//		return -EINVAL;
562
+//	}
563
+//
564
+//	if (!country)
565
+//		country = ath_regd_find_country_by_rd(regdmn);
566
+//
567
+//	if (country) {
568
+//		reg->alpha2[0] = country->isoName[0];
569
+//		reg->alpha2[1] = country->isoName[1];
570
+//	} else {
571
+//		reg->alpha2[0] = '0';
572
+//		reg->alpha2[1] = '0';
573
+//	}
574
+//
575
+//	DBG2("ath: Country alpha2 being used: %c%c\n",
576
+//		reg->alpha2[0], reg->alpha2[1]);
577
+//	DBG2("ath: Regpair used: 0x%0x\n",
578
+//		reg->regpair->regDmnEnum);
579
+//
580
+//	ath_regd_init_wiphy(reg, wiphy, reg_notifier);
581
+//	return 0;
582
+//}
583
+
584
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
585
+			  int band)
586
+{
587
+	/* TODO Cottsay: reg */
588
+//	if (!reg->regpair ||
589
+//	    (reg->country_code == CTRY_DEFAULT &&
590
+//	     is_wwr_sku(ath_regd_get_eepromRD(reg)))) {
591
+//		return SD_NO_CTL;
592
+//	}
593
+
594
+	switch (band) {
595
+	case NET80211_BAND_2GHZ:
596
+		return reg->regpair->reg_2ghz_ctl;
597
+	case NET80211_BAND_5GHZ:
598
+		return reg->regpair->reg_5ghz_ctl;
599
+	default:
600
+		return NO_CTL;
601
+	}
602
+}

+ 64
- 0
src/drivers/net/ath/reg.h View File

@@ -0,0 +1,64 @@
1
+/*
2
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef ATH_REGISTERS_H
21
+#define ATH_REGISTERS_H
22
+
23
+#define AR_MIBC			0x0040
24
+#define AR_MIBC_COW		0x00000001
25
+#define AR_MIBC_FMC		0x00000002
26
+#define AR_MIBC_CMC		0x00000004
27
+#define AR_MIBC_MCS		0x00000008
28
+
29
+/*
30
+ * BSSID mask registers. See ath_hw_set_bssid_mask()
31
+ * for detailed documentation about these registers.
32
+ */
33
+#define AR_BSSMSKL		0x80e0
34
+#define AR_BSSMSKU		0x80e4
35
+
36
+#define AR_TFCNT		0x80ec
37
+#define AR_RFCNT		0x80f0
38
+#define AR_RCCNT		0x80f4
39
+#define AR_CCCNT		0x80f8
40
+
41
+#define AR_KEYTABLE_0           0x8800
42
+#define AR_KEYTABLE(_n)         (AR_KEYTABLE_0 + ((_n)*32))
43
+#define AR_KEY_CACHE_SIZE       128
44
+#define AR_RSVD_KEYTABLE_ENTRIES 4
45
+#define AR_KEY_TYPE             0x00000007
46
+#define AR_KEYTABLE_TYPE_40     0x00000000
47
+#define AR_KEYTABLE_TYPE_104    0x00000001
48
+#define AR_KEYTABLE_TYPE_128    0x00000003
49
+#define AR_KEYTABLE_TYPE_TKIP   0x00000004
50
+#define AR_KEYTABLE_TYPE_AES    0x00000005
51
+#define AR_KEYTABLE_TYPE_CCM    0x00000006
52
+#define AR_KEYTABLE_TYPE_CLR    0x00000007
53
+#define AR_KEYTABLE_ANT         0x00000008
54
+#define AR_KEYTABLE_VALID       0x00008000
55
+#define AR_KEYTABLE_KEY0(_n)    (AR_KEYTABLE(_n) + 0)
56
+#define AR_KEYTABLE_KEY1(_n)    (AR_KEYTABLE(_n) + 4)
57
+#define AR_KEYTABLE_KEY2(_n)    (AR_KEYTABLE(_n) + 8)
58
+#define AR_KEYTABLE_KEY3(_n)    (AR_KEYTABLE(_n) + 12)
59
+#define AR_KEYTABLE_KEY4(_n)    (AR_KEYTABLE(_n) + 16)
60
+#define AR_KEYTABLE_TYPE(_n)    (AR_KEYTABLE(_n) + 20)
61
+#define AR_KEYTABLE_MAC0(_n)    (AR_KEYTABLE(_n) + 24)
62
+#define AR_KEYTABLE_MAC1(_n)    (AR_KEYTABLE(_n) + 28)
63
+
64
+#endif /* ATH_REGISTERS_H */

+ 263
- 0
src/drivers/net/ath/regd.h View File

@@ -0,0 +1,263 @@
1
+/*
2
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef REGD_H
21
+#define REGD_H
22
+
23
+#include "ath.h"
24
+
25
+enum ctl_group {
26
+	CTL_FCC = 0x10,
27
+	CTL_MKK = 0x40,
28
+	CTL_ETSI = 0x30,
29
+};
30
+
31
+#define NO_CTL 0xff
32
+#define SD_NO_CTL               0xE0
33
+#define NO_CTL                  0xff
34
+#define CTL_11A                 0
35
+#define CTL_11B                 1
36
+#define CTL_11G                 2
37
+#define CTL_2GHT20              5
38
+#define CTL_5GHT20              6
39
+#define CTL_2GHT40              7
40
+#define CTL_5GHT40              8
41
+
42
+#define CTRY_DEBUG 0x1ff
43
+#define CTRY_DEFAULT 0
44
+
45
+#define COUNTRY_ERD_FLAG        0x8000
46
+#define WORLDWIDE_ROAMING_FLAG  0x4000
47
+
48
+#define MULTI_DOMAIN_MASK 0xFF00
49
+
50
+#define WORLD_SKU_MASK          0x00F0
51
+#define WORLD_SKU_PREFIX        0x0060
52
+
53
+#define CHANNEL_HALF_BW         10
54
+#define CHANNEL_QUARTER_BW      5
55
+
56
+struct country_code_to_enum_rd {
57
+	u16 countryCode;
58
+	u16 regDmnEnum;
59
+	const char *isoName;
60
+};
61
+
62
+enum CountryCode {
63
+	CTRY_ALBANIA = 8,
64
+	CTRY_ALGERIA = 12,
65
+	CTRY_ARGENTINA = 32,
66
+	CTRY_ARMENIA = 51,
67
+	CTRY_ARUBA = 533,
68
+	CTRY_AUSTRALIA = 36,
69
+	CTRY_AUSTRIA = 40,
70
+	CTRY_AZERBAIJAN = 31,
71
+	CTRY_BAHRAIN = 48,
72
+	CTRY_BANGLADESH = 50,
73
+	CTRY_BARBADOS = 52,
74
+	CTRY_BELARUS = 112,
75
+	CTRY_BELGIUM = 56,
76
+	CTRY_BELIZE = 84,
77
+	CTRY_BOLIVIA = 68,
78
+	CTRY_BOSNIA_HERZ = 70,
79
+	CTRY_BRAZIL = 76,
80
+	CTRY_BRUNEI_DARUSSALAM = 96,
81
+	CTRY_BULGARIA = 100,
82
+	CTRY_CAMBODIA = 116,
83
+	CTRY_CANADA = 124,
84
+	CTRY_CHILE = 152,
85
+	CTRY_CHINA = 156,
86
+	CTRY_COLOMBIA = 170,
87
+	CTRY_COSTA_RICA = 188,
88
+	CTRY_CROATIA = 191,
89
+	CTRY_CYPRUS = 196,
90
+	CTRY_CZECH = 203,
91
+	CTRY_DENMARK = 208,
92
+	CTRY_DOMINICAN_REPUBLIC = 214,
93
+	CTRY_ECUADOR = 218,
94
+	CTRY_EGYPT = 818,
95
+	CTRY_EL_SALVADOR = 222,
96
+	CTRY_ESTONIA = 233,
97
+	CTRY_FAEROE_ISLANDS = 234,
98
+	CTRY_FINLAND = 246,
99
+	CTRY_FRANCE = 250,
100
+	CTRY_GEORGIA = 268,
101
+	CTRY_GERMANY = 276,
102
+	CTRY_GREECE = 300,
103
+	CTRY_GREENLAND = 304,
104
+	CTRY_GRENEDA = 308,
105
+	CTRY_GUAM = 316,
106
+	CTRY_GUATEMALA = 320,
107
+	CTRY_HAITI = 332,
108
+	CTRY_HONDURAS = 340,
109
+	CTRY_HONG_KONG = 344,
110
+	CTRY_HUNGARY = 348,
111
+	CTRY_ICELAND = 352,
112
+	CTRY_INDIA = 356,
113
+	CTRY_INDONESIA = 360,
114
+	CTRY_IRAN = 364,
115
+	CTRY_IRAQ = 368,
116
+	CTRY_IRELAND = 372,
117
+	CTRY_ISRAEL = 376,
118
+	CTRY_ITALY = 380,
119
+	CTRY_JAMAICA = 388,
120
+	CTRY_JAPAN = 392,
121
+	CTRY_JORDAN = 400,
122
+	CTRY_KAZAKHSTAN = 398,
123
+	CTRY_KENYA = 404,
124
+	CTRY_KOREA_NORTH = 408,
125
+	CTRY_KOREA_ROC = 410,
126
+	CTRY_KOREA_ROC2 = 411,
127
+	CTRY_KOREA_ROC3 = 412,
128
+	CTRY_KUWAIT = 414,
129
+	CTRY_LATVIA = 428,
130
+	CTRY_LEBANON = 422,
131
+	CTRY_LIBYA = 434,
132
+	CTRY_LIECHTENSTEIN = 438,
133
+	CTRY_LITHUANIA = 440,
134
+	CTRY_LUXEMBOURG = 442,
135
+	CTRY_MACAU = 446,
136
+	CTRY_MACEDONIA = 807,
137
+	CTRY_MALAYSIA = 458,
138
+	CTRY_MALTA = 470,
139
+	CTRY_MEXICO = 484,
140
+	CTRY_MONACO = 492,
141
+	CTRY_MOROCCO = 504,
142
+	CTRY_NEPAL = 524,
143
+	CTRY_NETHERLANDS = 528,
144
+	CTRY_NETHERLANDS_ANTILLES = 530,
145
+	CTRY_NEW_ZEALAND = 554,
146
+	CTRY_NICARAGUA = 558,
147
+	CTRY_NORWAY = 578,
148
+	CTRY_OMAN = 512,
149
+	CTRY_PAKISTAN = 586,
150
+	CTRY_PANAMA = 591,
151
+	CTRY_PAPUA_NEW_GUINEA = 598,
152
+	CTRY_PARAGUAY = 600,
153
+	CTRY_PERU = 604,
154
+	CTRY_PHILIPPINES = 608,
155
+	CTRY_POLAND = 616,
156
+	CTRY_PORTUGAL = 620,
157
+	CTRY_PUERTO_RICO = 630,
158
+	CTRY_QATAR = 634,
159
+	CTRY_ROMANIA = 642,
160
+	CTRY_RUSSIA = 643,
161
+	CTRY_SAUDI_ARABIA = 682,
162
+	CTRY_SERBIA_MONTENEGRO = 891,
163
+	CTRY_SINGAPORE = 702,
164
+	CTRY_SLOVAKIA = 703,
165
+	CTRY_SLOVENIA = 705,
166
+	CTRY_SOUTH_AFRICA = 710,
167
+	CTRY_SPAIN = 724,
168
+	CTRY_SRI_LANKA = 144,
169
+	CTRY_SWEDEN = 752,
170
+	CTRY_SWITZERLAND = 756,
171
+	CTRY_SYRIA = 760,
172
+	CTRY_TAIWAN = 158,
173
+	CTRY_THAILAND = 764,
174
+	CTRY_TRINIDAD_Y_TOBAGO = 780,
175
+	CTRY_TUNISIA = 788,
176
+	CTRY_TURKEY = 792,
177
+	CTRY_UAE = 784,
178
+	CTRY_UKRAINE = 804,
179
+	CTRY_UNITED_KINGDOM = 826,
180
+	CTRY_UNITED_STATES = 840,
181
+	CTRY_UNITED_STATES_FCC49 = 842,
182
+	CTRY_URUGUAY = 858,
183
+	CTRY_UZBEKISTAN = 860,
184
+	CTRY_VENEZUELA = 862,
185
+	CTRY_VIET_NAM = 704,
186
+	CTRY_YEMEN = 887,
187
+	CTRY_ZIMBABWE = 716,
188
+	CTRY_JAPAN1 = 393,
189
+	CTRY_JAPAN2 = 394,
190
+	CTRY_JAPAN3 = 395,
191
+	CTRY_JAPAN4 = 396,
192
+	CTRY_JAPAN5 = 397,
193
+	CTRY_JAPAN6 = 4006,
194
+	CTRY_JAPAN7 = 4007,
195
+	CTRY_JAPAN8 = 4008,
196
+	CTRY_JAPAN9 = 4009,
197
+	CTRY_JAPAN10 = 4010,
198
+	CTRY_JAPAN11 = 4011,
199
+	CTRY_JAPAN12 = 4012,
200
+	CTRY_JAPAN13 = 4013,
201
+	CTRY_JAPAN14 = 4014,
202
+	CTRY_JAPAN15 = 4015,
203
+	CTRY_JAPAN16 = 4016,
204
+	CTRY_JAPAN17 = 4017,
205
+	CTRY_JAPAN18 = 4018,
206
+	CTRY_JAPAN19 = 4019,
207
+	CTRY_JAPAN20 = 4020,
208
+	CTRY_JAPAN21 = 4021,
209
+	CTRY_JAPAN22 = 4022,
210
+	CTRY_JAPAN23 = 4023,
211
+	CTRY_JAPAN24 = 4024,
212
+	CTRY_JAPAN25 = 4025,
213
+	CTRY_JAPAN26 = 4026,
214
+	CTRY_JAPAN27 = 4027,
215
+	CTRY_JAPAN28 = 4028,
216
+	CTRY_JAPAN29 = 4029,
217
+	CTRY_JAPAN30 = 4030,
218
+	CTRY_JAPAN31 = 4031,
219
+	CTRY_JAPAN32 = 4032,
220
+	CTRY_JAPAN33 = 4033,
221
+	CTRY_JAPAN34 = 4034,
222
+	CTRY_JAPAN35 = 4035,
223
+	CTRY_JAPAN36 = 4036,
224
+	CTRY_JAPAN37 = 4037,
225
+	CTRY_JAPAN38 = 4038,
226
+	CTRY_JAPAN39 = 4039,
227
+	CTRY_JAPAN40 = 4040,
228
+	CTRY_JAPAN41 = 4041,
229
+	CTRY_JAPAN42 = 4042,
230
+	CTRY_JAPAN43 = 4043,
231
+	CTRY_JAPAN44 = 4044,
232
+	CTRY_JAPAN45 = 4045,
233
+	CTRY_JAPAN46 = 4046,
234
+	CTRY_JAPAN47 = 4047,
235
+	CTRY_JAPAN48 = 4048,
236
+	CTRY_JAPAN49 = 4049,
237
+	CTRY_JAPAN50 = 4050,
238
+	CTRY_JAPAN51 = 4051,
239
+	CTRY_JAPAN52 = 4052,
240
+	CTRY_JAPAN53 = 4053,
241
+	CTRY_JAPAN54 = 4054,
242
+	CTRY_JAPAN55 = 4055,
243
+	CTRY_JAPAN56 = 4056,
244
+	CTRY_JAPAN57 = 4057,
245
+	CTRY_JAPAN58 = 4058,
246
+	CTRY_JAPAN59 = 4059,
247
+	CTRY_AUSTRALIA2 = 5000,
248
+	CTRY_CANADA2 = 5001,
249
+	CTRY_BELGIUM2 = 5002
250
+};
251
+
252
+int ath_is_world_regd(struct ath_regulatory *reg);
253
+int ath_is_49ghz_allowed(u16 redomain);
254
+//int ath_regd_init(struct ath_regulatory *reg, struct wiphy *wiphy,
255
+//		  int (*reg_notifier)(struct wiphy *wiphy,
256
+//		  struct regulatory_request *request));
257
+u32 ath_regd_get_band_ctl(struct ath_regulatory *reg,
258
+			  int band);
259
+//int ath_reg_notifier_apply(struct wiphy *wiphy,
260
+//			   struct regulatory_request *request,
261
+//			   struct ath_regulatory *reg);
262
+
263
+#endif

+ 481
- 0
src/drivers/net/ath/regd_common.h View File

@@ -0,0 +1,481 @@
1
+/*
2
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
3
+ *
4
+ * Modified for iPXE by Scott K Logan <logans@cottsay.net> July 2011
5
+ * Original from Linux kernel 3.0.1
6
+ *
7
+ * Permission to use, copy, modify, and/or 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
+#ifndef REGD_COMMON_H
21
+#define REGD_COMMON_H
22
+
23
+enum EnumRd {
24
+	NO_ENUMRD = 0x00,
25
+	NULL1_WORLD = 0x03,
26
+	NULL1_ETSIB = 0x07,
27
+	NULL1_ETSIC = 0x08,
28
+	FCC1_FCCA = 0x10,
29
+	FCC1_WORLD = 0x11,
30
+	FCC4_FCCA = 0x12,
31
+	FCC5_FCCA = 0x13,
32
+	FCC6_FCCA = 0x14,
33
+
34
+	FCC2_FCCA = 0x20,
35
+	FCC2_WORLD = 0x21,
36
+	FCC2_ETSIC = 0x22,
37
+	FCC6_WORLD = 0x23,
38
+	FRANCE_RES = 0x31,
39
+	FCC3_FCCA = 0x3A,
40
+	FCC3_WORLD = 0x3B,
41
+
42
+	ETSI1_WORLD = 0x37,
43
+	ETSI3_ETSIA = 0x32,
44
+	ETSI2_WORLD = 0x35,
45
+	ETSI3_WORLD = 0x36,
46
+	ETSI4_WORLD = 0x30,
47
+	ETSI4_ETSIC = 0x38,
48
+	ETSI5_WORLD = 0x39,
49
+	ETSI6_WORLD = 0x34,
50
+	ETSI_RESERVED = 0x33,
51
+
52
+	MKK1_MKKA = 0x40,
53
+	MKK1_MKKB = 0x41,
54
+	APL4_WORLD = 0x42,
55
+	MKK2_MKKA = 0x43,
56
+	APL_RESERVED = 0x44,
57
+	APL2_WORLD = 0x45,
58
+	APL2_APLC = 0x46,
59
+	APL3_WORLD = 0x47,
60
+	MKK1_FCCA = 0x48,
61
+	APL2_APLD = 0x49,
62
+	MKK1_MKKA1 = 0x4A,
63
+	MKK1_MKKA2 = 0x4B,
64
+	MKK1_MKKC = 0x4C,
65
+
66
+	APL3_FCCA = 0x50,
67
+	APL1_WORLD = 0x52,
68
+	APL1_FCCA = 0x53,
69
+	APL1_APLA = 0x54,
70
+	APL1_ETSIC = 0x55,
71
+	APL2_ETSIC = 0x56,
72
+	APL5_WORLD = 0x58,
73
+	APL6_WORLD = 0x5B,
74
+	APL7_FCCA = 0x5C,
75
+	APL8_WORLD = 0x5D,
76
+	APL9_WORLD = 0x5E,
77
+
78
+	WOR0_WORLD = 0x60,
79
+	WOR1_WORLD = 0x61,
80
+	WOR2_WORLD = 0x62,
81
+	WOR3_WORLD = 0x63,
82
+	WOR4_WORLD = 0x64,
83
+	WOR5_ETSIC = 0x65,
84
+
85
+	WOR01_WORLD = 0x66,
86
+	WOR02_WORLD = 0x67,
87
+	EU1_WORLD = 0x68,
88
+
89
+	WOR9_WORLD = 0x69,
90
+	WORA_WORLD = 0x6A,
91
+	WORB_WORLD = 0x6B,
92
+	WORC_WORLD = 0x6C,
93
+
94
+	MKK3_MKKB = 0x80,
95
+	MKK3_MKKA2 = 0x81,
96
+	MKK3_MKKC = 0x82,
97
+
98
+	MKK4_MKKB = 0x83,
99
+	MKK4_MKKA2 = 0x84,
100
+	MKK4_MKKC = 0x85,
101
+
102
+	MKK5_MKKB = 0x86,
103
+	MKK5_MKKA2 = 0x87,
104
+	MKK5_MKKC = 0x88,
105
+
106
+	MKK6_MKKB = 0x89,
107
+	MKK6_MKKA2 = 0x8A,
108
+	MKK6_MKKC = 0x8B,
109
+
110
+	MKK7_MKKB = 0x8C,
111
+	MKK7_MKKA2 = 0x8D,
112
+	MKK7_MKKC = 0x8E,
113
+
114
+	MKK8_MKKB = 0x8F,
115
+	MKK8_MKKA2 = 0x90,
116
+	MKK8_MKKC = 0x91,
117
+
118
+	MKK14_MKKA1 = 0x92,
119
+	MKK15_MKKA1 = 0x93,
120
+
121
+	MKK10_FCCA = 0xD0,
122
+	MKK10_MKKA1 = 0xD1,
123
+	MKK10_MKKC = 0xD2,
124
+	MKK10_MKKA2 = 0xD3,
125
+
126
+	MKK11_MKKA = 0xD4,
127
+	MKK11_FCCA = 0xD5,
128
+	MKK11_MKKA1 = 0xD6,
129
+	MKK11_MKKC = 0xD7,
130
+	MKK11_MKKA2 = 0xD8,
131
+
132
+	MKK12_MKKA = 0xD9,
133
+	MKK12_FCCA = 0xDA,
134
+	MKK12_MKKA1 = 0xDB,
135
+	MKK12_MKKC = 0xDC,
136
+	MKK12_MKKA2 = 0xDD,
137
+
138
+	MKK13_MKKB = 0xDE,
139
+
140
+	MKK3_MKKA = 0xF0,
141
+	MKK3_MKKA1 = 0xF1,
142
+	MKK3_FCCA = 0xF2,
143
+	MKK4_MKKA = 0xF3,
144
+	MKK4_MKKA1 = 0xF4,
145
+	MKK4_FCCA = 0xF5,
146
+	MKK9_MKKA = 0xF6,
147
+	MKK10_MKKA = 0xF7,
148
+	MKK6_MKKA1 = 0xF8,
149
+	MKK6_FCCA = 0xF9,
150
+	MKK7_MKKA1 = 0xFA,
151
+	MKK7_FCCA = 0xFB,
152
+	MKK9_FCCA = 0xFC,
153
+	MKK9_MKKA1 = 0xFD,
154
+	MKK9_MKKC = 0xFE,
155
+	MKK9_MKKA2 = 0xFF,
156
+
157
+	WORLD = 0x0199,
158
+	DEBUG_REG_DMN = 0x01ff,
159
+};
160
+
161
+///* Regpair to CTL band mapping */
162
+//static struct reg_dmn_pair_mapping regDomainPairs[] = {
163
+//	/* regpair, 5 GHz CTL, 2 GHz CTL */
164
+//	{NO_ENUMRD, DEBUG_REG_DMN, DEBUG_REG_DMN},
165
+//	{NULL1_WORLD, NO_CTL, CTL_ETSI},
166
+//	{NULL1_ETSIB, NO_CTL, CTL_ETSI},
167
+//	{NULL1_ETSIC, NO_CTL, CTL_ETSI},
168
+//
169
+//	{FCC2_FCCA, CTL_FCC, CTL_FCC},
170
+//	{FCC2_WORLD, CTL_FCC, CTL_ETSI},
171
+//	{FCC2_ETSIC, CTL_FCC, CTL_ETSI},
172
+//	{FCC3_FCCA, CTL_FCC, CTL_FCC},
173
+//	{FCC3_WORLD, CTL_FCC, CTL_ETSI},
174
+//	{FCC4_FCCA, CTL_FCC, CTL_FCC},
175
+//	{FCC5_FCCA, CTL_FCC, CTL_FCC},
176
+//	{FCC6_FCCA, CTL_FCC, CTL_FCC},
177
+//	{FCC6_WORLD, CTL_FCC, CTL_ETSI},
178
+//
179
+//	{ETSI1_WORLD, CTL_ETSI, CTL_ETSI},
180
+//	{ETSI2_WORLD, CTL_ETSI, CTL_ETSI},
181
+//	{ETSI3_WORLD, CTL_ETSI, CTL_ETSI},
182
+//	{ETSI4_WORLD, CTL_ETSI, CTL_ETSI},
183
+//	{ETSI5_WORLD, CTL_ETSI, CTL_ETSI},
184
+//	{ETSI6_WORLD, CTL_ETSI, CTL_ETSI},
185
+//
186
+//	/* XXX: For ETSI3_ETSIA, Was NO_CTL meant for the 2 GHz band ? */
187
+//	{ETSI3_ETSIA, CTL_ETSI, CTL_ETSI},
188
+//	{FRANCE_RES, CTL_ETSI, CTL_ETSI},
189
+//
190
+//	{FCC1_WORLD, CTL_FCC, CTL_ETSI},
191
+//	{FCC1_FCCA, CTL_FCC, CTL_FCC},
192
+//	{APL1_WORLD, CTL_FCC, CTL_ETSI},
193
+//	{APL2_WORLD, CTL_FCC, CTL_ETSI},
194
+//	{APL3_WORLD, CTL_FCC, CTL_ETSI},
195
+//	{APL4_WORLD, CTL_FCC, CTL_ETSI},
196
+//	{APL5_WORLD, CTL_FCC, CTL_ETSI},
197
+//	{APL6_WORLD, CTL_ETSI, CTL_ETSI},
198
+//	{APL8_WORLD, CTL_ETSI, CTL_ETSI},
199
+//	{APL9_WORLD, CTL_ETSI, CTL_ETSI},
200
+//
201
+//	{APL3_FCCA, CTL_FCC, CTL_FCC},
202
+//	{APL7_FCCA, CTL_FCC, CTL_FCC},
203
+//	{APL1_ETSIC, CTL_FCC, CTL_ETSI},
204
+//	{APL2_ETSIC, CTL_FCC, CTL_ETSI},
205
+//	{APL2_APLD, CTL_FCC, NO_CTL},
206
+//
207
+//	{MKK1_MKKA, CTL_MKK, CTL_MKK},
208
+//	{MKK1_MKKB, CTL_MKK, CTL_MKK},
209
+//	{MKK1_FCCA, CTL_MKK, CTL_FCC},
210
+//	{MKK1_MKKA1, CTL_MKK, CTL_MKK},
211
+//	{MKK1_MKKA2, CTL_MKK, CTL_MKK},
212
+//	{MKK1_MKKC, CTL_MKK, CTL_MKK},
213
+//
214
+//	{MKK2_MKKA, CTL_MKK, CTL_MKK},
215
+//	{MKK3_MKKA, CTL_MKK, CTL_MKK},
216
+//	{MKK3_MKKB, CTL_MKK, CTL_MKK},
217
+//	{MKK3_MKKA1, CTL_MKK, CTL_MKK},
218
+//	{MKK3_MKKA2, CTL_MKK, CTL_MKK},
219
+//	{MKK3_MKKC, CTL_MKK, CTL_MKK},
220
+//	{MKK3_FCCA, CTL_MKK, CTL_FCC},
221
+//
222
+//	{MKK4_MKKA, CTL_MKK, CTL_MKK},
223
+//	{MKK4_MKKB, CTL_MKK, CTL_MKK},
224
+//	{MKK4_MKKA1, CTL_MKK, CTL_MKK},
225
+//	{MKK4_MKKA2, CTL_MKK, CTL_MKK},
226
+//	{MKK4_MKKC, CTL_MKK, CTL_MKK},
227
+//	{MKK4_FCCA, CTL_MKK, CTL_FCC},
228
+//
229
+//	{MKK5_MKKB, CTL_MKK, CTL_MKK},
230
+//	{MKK5_MKKA2, CTL_MKK, CTL_MKK},
231
+//	{MKK5_MKKC, CTL_MKK, CTL_MKK},
232
+//
233
+//	{MKK6_MKKB, CTL_MKK, CTL_MKK},
234
+//	{MKK6_MKKA1, CTL_MKK, CTL_MKK},
235
+//	{MKK6_MKKA2, CTL_MKK, CTL_MKK},
236
+//	{MKK6_MKKC, CTL_MKK, CTL_MKK},
237
+//	{MKK6_FCCA, CTL_MKK, CTL_FCC},
238
+//
239
+//	{MKK7_MKKB, CTL_MKK, CTL_MKK},
240
+//	{MKK7_MKKA1, CTL_MKK, CTL_MKK},
241
+//	{MKK7_MKKA2, CTL_MKK, CTL_MKK},
242
+//	{MKK7_MKKC, CTL_MKK, CTL_MKK},
243
+//	{MKK7_FCCA, CTL_MKK, CTL_FCC},
244
+//
245
+//	{MKK8_MKKB, CTL_MKK, CTL_MKK},
246
+//	{MKK8_MKKA2, CTL_MKK, CTL_MKK},
247
+//	{MKK8_MKKC, CTL_MKK, CTL_MKK},
248
+//
249
+//	{MKK9_MKKA, CTL_MKK, CTL_MKK},
250
+//	{MKK9_FCCA, CTL_MKK, CTL_FCC},
251
+//	{MKK9_MKKA1, CTL_MKK, CTL_MKK},
252
+//	{MKK9_MKKA2, CTL_MKK, CTL_MKK},
253
+//	{MKK9_MKKC, CTL_MKK, CTL_MKK},
254
+//
255
+//	{MKK10_MKKA, CTL_MKK, CTL_MKK},
256
+//	{MKK10_FCCA, CTL_MKK, CTL_FCC},
257
+//	{MKK10_MKKA1, CTL_MKK, CTL_MKK},
258
+//	{MKK10_MKKA2, CTL_MKK, CTL_MKK},
259
+//	{MKK10_MKKC, CTL_MKK, CTL_MKK},
260
+//
261
+//	{MKK11_MKKA, CTL_MKK, CTL_MKK},
262
+//	{MKK11_FCCA, CTL_MKK, CTL_FCC},
263
+//	{MKK11_MKKA1, CTL_MKK, CTL_MKK},
264
+//	{MKK11_MKKA2, CTL_MKK, CTL_MKK},
265
+//	{MKK11_MKKC, CTL_MKK, CTL_MKK},
266
+//
267
+//	{MKK12_MKKA, CTL_MKK, CTL_MKK},
268
+//	{MKK12_FCCA, CTL_MKK, CTL_FCC},
269
+//	{MKK12_MKKA1, CTL_MKK, CTL_MKK},
270
+//	{MKK12_MKKA2, CTL_MKK, CTL_MKK},
271
+//	{MKK12_MKKC, CTL_MKK, CTL_MKK},
272
+//
273
+//	{MKK13_MKKB, CTL_MKK, CTL_MKK},
274
+//	{MKK14_MKKA1, CTL_MKK, CTL_MKK},
275
+//	{MKK15_MKKA1, CTL_MKK, CTL_MKK},
276
+//
277
+//	{WOR0_WORLD, NO_CTL, NO_CTL},
278
+//	{WOR1_WORLD, NO_CTL, NO_CTL},
279
+//	{WOR2_WORLD, NO_CTL, NO_CTL},
280
+//	{WOR3_WORLD, NO_CTL, NO_CTL},
281
+//	{WOR4_WORLD, NO_CTL, NO_CTL},
282
+//	{WOR5_ETSIC, NO_CTL, NO_CTL},
283
+//	{WOR01_WORLD, NO_CTL, NO_CTL},
284
+//	{WOR02_WORLD, NO_CTL, NO_CTL},
285
+//	{EU1_WORLD, NO_CTL, NO_CTL},
286
+//	{WOR9_WORLD, NO_CTL, NO_CTL},
287
+//	{WORA_WORLD, NO_CTL, NO_CTL},
288
+//	{WORB_WORLD, NO_CTL, NO_CTL},
289
+//	{WORC_WORLD, NO_CTL, NO_CTL},
290
+//};
291
+//
292
+//static struct country_code_to_enum_rd allCountries[] = {
293
+//	{CTRY_DEBUG, NO_ENUMRD, "DB"},
294
+//	{CTRY_DEFAULT, FCC1_FCCA, "CO"},
295
+//	{CTRY_ALBANIA, NULL1_WORLD, "AL"},
296
+//	{CTRY_ALGERIA, NULL1_WORLD, "DZ"},
297
+//	{CTRY_ARGENTINA, FCC3_WORLD, "AR"},
298
+//	{CTRY_ARMENIA, ETSI4_WORLD, "AM"},
299
+//	{CTRY_ARUBA, ETSI1_WORLD, "AW"},
300
+//	{CTRY_AUSTRALIA, FCC2_WORLD, "AU"},
301
+//	{CTRY_AUSTRALIA2, FCC6_WORLD, "AU"},
302
+//	{CTRY_AUSTRIA, ETSI1_WORLD, "AT"},
303
+//	{CTRY_AZERBAIJAN, ETSI4_WORLD, "AZ"},
304
+//	{CTRY_BAHRAIN, APL6_WORLD, "BH"},
305
+//	{CTRY_BANGLADESH, NULL1_WORLD, "BD"},
306
+//	{CTRY_BARBADOS, FCC2_WORLD, "BB"},
307
+//	{CTRY_BELARUS, ETSI1_WORLD, "BY"},
308
+//	{CTRY_BELGIUM, ETSI1_WORLD, "BE"},
309
+//	{CTRY_BELGIUM2, ETSI4_WORLD, "BL"},
310
+//	{CTRY_BELIZE, APL1_ETSIC, "BZ"},
311
+//	{CTRY_BOLIVIA, APL1_ETSIC, "BO"},
312
+//	{CTRY_BOSNIA_HERZ, ETSI1_WORLD, "BA"},
313
+//	{CTRY_BRAZIL, FCC3_WORLD, "BR"},
314
+//	{CTRY_BRUNEI_DARUSSALAM, APL1_WORLD, "BN"},
315
+//	{CTRY_BULGARIA, ETSI6_WORLD, "BG"},
316
+//	{CTRY_CAMBODIA, ETSI1_WORLD, "KH"},
317
+//	{CTRY_CANADA, FCC3_FCCA, "CA"},
318
+//	{CTRY_CANADA2, FCC6_FCCA, "CA"},
319
+//	{CTRY_CHILE, APL6_WORLD, "CL"},
320
+//	{CTRY_CHINA, APL1_WORLD, "CN"},
321
+//	{CTRY_COLOMBIA, FCC1_FCCA, "CO"},
322
+//	{CTRY_COSTA_RICA, FCC1_WORLD, "CR"},
323
+//	{CTRY_CROATIA, ETSI1_WORLD, "HR"},
324
+//	{CTRY_CYPRUS, ETSI1_WORLD, "CY"},
325
+//	{CTRY_CZECH, ETSI3_WORLD, "CZ"},
326
+//	{CTRY_DENMARK, ETSI1_WORLD, "DK"},
327
+//	{CTRY_DOMINICAN_REPUBLIC, FCC1_FCCA, "DO"},
328
+//	{CTRY_ECUADOR, FCC1_WORLD, "EC"},
329
+//	{CTRY_EGYPT, ETSI3_WORLD, "EG"},
330
+//	{CTRY_EL_SALVADOR, FCC1_WORLD, "SV"},
331
+//	{CTRY_ESTONIA, ETSI1_WORLD, "EE"},
332
+//	{CTRY_FINLAND, ETSI1_WORLD, "FI"},
333
+//	{CTRY_FRANCE, ETSI1_WORLD, "FR"},
334
+//	{CTRY_GEORGIA, ETSI4_WORLD, "GE"},
335
+//	{CTRY_GERMANY, ETSI1_WORLD, "DE"},
336
+//	{CTRY_GREECE, ETSI1_WORLD, "GR"},
337
+//	{CTRY_GREENLAND, ETSI1_WORLD, "GL"},
338
+//	{CTRY_GRENEDA, FCC3_FCCA, "GD"},
339
+//	{CTRY_GUAM, FCC1_FCCA, "GU"},
340
+//	{CTRY_GUATEMALA, FCC1_FCCA, "GT"},
341
+//	{CTRY_HAITI, ETSI1_WORLD, "HT"},
342
+//	{CTRY_HONDURAS, NULL1_WORLD, "HN"},
343
+//	{CTRY_HONG_KONG, FCC3_WORLD, "HK"},
344
+//	{CTRY_HUNGARY, ETSI1_WORLD, "HU"},
345
+//	{CTRY_ICELAND, ETSI1_WORLD, "IS"},
346
+//	{CTRY_INDIA, APL6_WORLD, "IN"},
347
+//	{CTRY_INDONESIA, NULL1_WORLD, "ID"},
348
+//	{CTRY_IRAN, APL1_WORLD, "IR"},
349
+//	{CTRY_IRELAND, ETSI1_WORLD, "IE"},
350
+//	{CTRY_ISRAEL, NULL1_WORLD, "IL"},
351
+//	{CTRY_ITALY, ETSI1_WORLD, "IT"},
352
+//	{CTRY_JAMAICA, FCC3_WORLD, "JM"},
353
+//
354
+//	{CTRY_JAPAN, MKK1_MKKA, "JP"},
355
+//	{CTRY_JAPAN1, MKK1_MKKB, "JP"},
356
+//	{CTRY_JAPAN2, MKK1_FCCA, "JP"},
357
+//	{CTRY_JAPAN3, MKK2_MKKA, "JP"},
358
+//	{CTRY_JAPAN4, MKK1_MKKA1, "JP"},
359
+//	{CTRY_JAPAN5, MKK1_MKKA2, "JP"},
360
+//	{CTRY_JAPAN6, MKK1_MKKC, "JP"},
361
+//	{CTRY_JAPAN7, MKK3_MKKB, "JP"},
362
+//	{CTRY_JAPAN8, MKK3_MKKA2, "JP"},
363
+//	{CTRY_JAPAN9, MKK3_MKKC, "JP"},
364
+//	{CTRY_JAPAN10, MKK4_MKKB, "JP"},
365
+//	{CTRY_JAPAN11, MKK4_MKKA2, "JP"},
366
+//	{CTRY_JAPAN12, MKK4_MKKC, "JP"},
367
+//	{CTRY_JAPAN13, MKK5_MKKB, "JP"},
368
+//	{CTRY_JAPAN14, MKK5_MKKA2, "JP"},
369
+//	{CTRY_JAPAN15, MKK5_MKKC, "JP"},
370
+//	{CTRY_JAPAN16, MKK6_MKKB, "JP"},
371
+//	{CTRY_JAPAN17, MKK6_MKKA2, "JP"},
372
+//	{CTRY_JAPAN18, MKK6_MKKC, "JP"},
373
+//	{CTRY_JAPAN19, MKK7_MKKB, "JP"},
374
+//	{CTRY_JAPAN20, MKK7_MKKA2, "JP"},
375
+//	{CTRY_JAPAN21, MKK7_MKKC, "JP"},
376
+//	{CTRY_JAPAN22, MKK8_MKKB, "JP"},
377
+//	{CTRY_JAPAN23, MKK8_MKKA2, "JP"},
378
+//	{CTRY_JAPAN24, MKK8_MKKC, "JP"},
379
+//	{CTRY_JAPAN25, MKK3_MKKA, "JP"},
380
+//	{CTRY_JAPAN26, MKK3_MKKA1, "JP"},
381
+//	{CTRY_JAPAN27, MKK3_FCCA, "JP"},
382
+//	{CTRY_JAPAN28, MKK4_MKKA1, "JP"},
383
+//	{CTRY_JAPAN29, MKK4_FCCA, "JP"},
384
+//	{CTRY_JAPAN30, MKK6_MKKA1, "JP"},
385
+//	{CTRY_JAPAN31, MKK6_FCCA, "JP"},
386
+//	{CTRY_JAPAN32, MKK7_MKKA1, "JP"},
387
+//	{CTRY_JAPAN33, MKK7_FCCA, "JP"},
388
+//	{CTRY_JAPAN34, MKK9_MKKA, "JP"},
389
+//	{CTRY_JAPAN35, MKK10_MKKA, "JP"},
390
+//	{CTRY_JAPAN36, MKK4_MKKA, "JP"},
391
+//	{CTRY_JAPAN37, MKK9_FCCA, "JP"},
392
+//	{CTRY_JAPAN38, MKK9_MKKA1, "JP"},
393
+//	{CTRY_JAPAN39, MKK9_MKKC, "JP"},
394
+//	{CTRY_JAPAN40, MKK9_MKKA2, "JP"},
395
+//	{CTRY_JAPAN41, MKK10_FCCA, "JP"},
396
+//	{CTRY_JAPAN42, MKK10_MKKA1, "JP"},
397
+//	{CTRY_JAPAN43, MKK10_MKKC, "JP"},
398
+//	{CTRY_JAPAN44, MKK10_MKKA2, "JP"},
399
+//	{CTRY_JAPAN45, MKK11_MKKA, "JP"},
400
+//	{CTRY_JAPAN46, MKK11_FCCA, "JP"},
401
+//	{CTRY_JAPAN47, MKK11_MKKA1, "JP"},
402
+//	{CTRY_JAPAN48, MKK11_MKKC, "JP"},
403
+//	{CTRY_JAPAN49, MKK11_MKKA2, "JP"},
404
+//	{CTRY_JAPAN50, MKK12_MKKA, "JP"},
405
+//	{CTRY_JAPAN51, MKK12_FCCA, "JP"},
406
+//	{CTRY_JAPAN52, MKK12_MKKA1, "JP"},
407
+//	{CTRY_JAPAN53, MKK12_MKKC, "JP"},
408
+//	{CTRY_JAPAN54, MKK12_MKKA2, "JP"},
409
+//	{CTRY_JAPAN57, MKK13_MKKB, "JP"},
410
+//	{CTRY_JAPAN58, MKK14_MKKA1, "JP"},
411
+//	{CTRY_JAPAN59, MKK15_MKKA1, "JP"},
412
+//
413
+//	{CTRY_JORDAN, ETSI2_WORLD, "JO"},
414
+//	{CTRY_KAZAKHSTAN, NULL1_WORLD, "KZ"},
415
+//	{CTRY_KOREA_NORTH, APL9_WORLD, "KP"},
416
+//	{CTRY_KOREA_ROC, APL9_WORLD, "KR"},
417
+//	{CTRY_KOREA_ROC2, APL2_WORLD, "K2"},
418
+//	{CTRY_KOREA_ROC3, APL9_WORLD, "K3"},
419
+//	{CTRY_KUWAIT, ETSI3_WORLD, "KW"},
420
+//	{CTRY_LATVIA, ETSI1_WORLD, "LV"},
421
+//	{CTRY_LEBANON, NULL1_WORLD, "LB"},
422
+//	{CTRY_LIECHTENSTEIN, ETSI1_WORLD, "LI"},
423
+//	{CTRY_LITHUANIA, ETSI1_WORLD, "LT"},
424
+//	{CTRY_LUXEMBOURG, ETSI1_WORLD, "LU"},
425
+//	{CTRY_MACAU, FCC2_WORLD, "MO"},
426
+//	{CTRY_MACEDONIA, NULL1_WORLD, "MK"},
427
+//	{CTRY_MALAYSIA, APL8_WORLD, "MY"},
428
+//	{CTRY_MALTA, ETSI1_WORLD, "MT"},
429
+//	{CTRY_MEXICO, FCC1_FCCA, "MX"},
430
+//	{CTRY_MONACO, ETSI4_WORLD, "MC"},
431
+//	{CTRY_MOROCCO, APL4_WORLD, "MA"},
432
+//	{CTRY_NEPAL, APL1_WORLD, "NP"},
433
+//	{CTRY_NETHERLANDS, ETSI1_WORLD, "NL"},
434
+//	{CTRY_NETHERLANDS_ANTILLES, ETSI1_WORLD, "AN"},
435
+//	{CTRY_NEW_ZEALAND, FCC2_ETSIC, "NZ"},
436
+//	{CTRY_NORWAY, ETSI1_WORLD, "NO"},
437
+//	{CTRY_OMAN, FCC3_WORLD, "OM"},
438
+//	{CTRY_PAKISTAN, NULL1_WORLD, "PK"},
439
+//	{CTRY_PANAMA, FCC1_FCCA, "PA"},
440
+//	{CTRY_PAPUA_NEW_GUINEA, FCC1_WORLD, "PG"},
441
+//	{CTRY_PERU, APL1_WORLD, "PE"},
442
+//	{CTRY_PHILIPPINES, APL1_WORLD, "PH"},
443
+//	{CTRY_POLAND, ETSI1_WORLD, "PL"},
444
+//	{CTRY_PORTUGAL, ETSI1_WORLD, "PT"},
445
+//	{CTRY_PUERTO_RICO, FCC1_FCCA, "PR"},
446
+//	{CTRY_QATAR, APL1_WORLD, "QA"},
447
+//	{CTRY_ROMANIA, NULL1_WORLD, "RO"},
448
+//	{CTRY_RUSSIA, NULL1_WORLD, "RU"},
449
+//	{CTRY_SAUDI_ARABIA, NULL1_WORLD, "SA"},
450
+//	{CTRY_SERBIA_MONTENEGRO, ETSI1_WORLD, "CS"},
451
+//	{CTRY_SINGAPORE, APL6_WORLD, "SG"},
452
+//	{CTRY_SLOVAKIA, ETSI1_WORLD, "SK"},
453
+//	{CTRY_SLOVENIA, ETSI1_WORLD, "SI"},
454
+//	{CTRY_SOUTH_AFRICA, FCC3_WORLD, "ZA"},
455
+//	{CTRY_SPAIN, ETSI1_WORLD, "ES"},
456
+//	{CTRY_SRI_LANKA, FCC3_WORLD, "LK"},
457
+//	{CTRY_SWEDEN, ETSI1_WORLD, "SE"},
458
+//	{CTRY_SWITZERLAND, ETSI1_WORLD, "CH"},
459
+//	{CTRY_SYRIA, NULL1_WORLD, "SY"},
460
+//	{CTRY_TAIWAN, APL3_FCCA, "TW"},
461
+//	{CTRY_THAILAND, FCC3_WORLD, "TH"},
462
+//	{CTRY_TRINIDAD_Y_TOBAGO, FCC3_WORLD, "TT"},
463
+//	{CTRY_TUNISIA, ETSI3_WORLD, "TN"},
464
+//	{CTRY_TURKEY, ETSI3_WORLD, "TR"},
465
+//	{CTRY_UKRAINE, NULL1_WORLD, "UA"},
466
+//	{CTRY_UAE, NULL1_WORLD, "AE"},
467
+//	{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
468
+//	{CTRY_UNITED_STATES, FCC3_FCCA, "US"},
469
+//	/* This "PS" is for US public safety actually... to support this we
470
+//	 * would need to assign new special alpha2 to CRDA db as with the world
471
+//	 * regdomain and use another alpha2 */
472
+//	{CTRY_UNITED_STATES_FCC49, FCC4_FCCA, "PS"},
473
+//	{CTRY_URUGUAY, FCC3_WORLD, "UY"},
474
+//	{CTRY_UZBEKISTAN, FCC3_FCCA, "UZ"},
475
+//	{CTRY_VENEZUELA, APL2_ETSIC, "VE"},
476
+//	{CTRY_VIET_NAM, NULL1_WORLD, "VN"},
477
+//	{CTRY_YEMEN, NULL1_WORLD, "YE"},
478
+//	{CTRY_ZIMBABWE, NULL1_WORLD, "ZW"},
479
+//};
480
+
481
+#endif

+ 2
- 0
src/include/ipxe/errfile.h View File

@@ -137,6 +137,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
137 137
 #define ERRFILE_virtio_net	     ( ERRFILE_DRIVER | 0x005c0000 )
138 138
 #define ERRFILE_tap		     ( ERRFILE_DRIVER | 0x005d0000 )
139 139
 #define ERRFILE_igbvf_main	     ( ERRFILE_DRIVER | 0x005e0000 )
140
+#define ERRFILE_ath9k		     ( ERRFILE_DRIVER | 0x005f0000 )
141
+#define ERRFILE_ath		     ( ERRFILE_DRIVER | 0x00600000 )
140 142
 
141 143
 #define ERRFILE_scsi		     ( ERRFILE_DRIVER | 0x00700000 )
142 144
 #define ERRFILE_arbel		     ( ERRFILE_DRIVER | 0x00710000 )

+ 1
- 1
src/include/ipxe/net80211.h View File

@@ -272,7 +272,7 @@ enum net80211_crypto_alg {
272 272
 #define NET80211_MAX_RATES	16
273 273
 
274 274
 /** The maximum number of channels we allow to be configured simultaneously */
275
-#define NET80211_MAX_CHANNELS	32
275
+#define NET80211_MAX_CHANNELS	40
276 276
 
277 277
 /** Seconds we'll wait to get all fragments of a packet */
278 278
 #define NET80211_FRAG_TIMEOUT	2

Loading…
Cancel
Save