diff options
Diffstat (limited to 'drivers/net/wireless/ath5k')
-rw-r--r-- | drivers/net/wireless/ath5k/Makefile | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/ath5k.h | 619 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/attach.c | 359 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/base.c | 574 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/base.h | 10 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/caps.c | 193 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/debug.c | 4 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/desc.c | 692 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/desc.h (renamed from drivers/net/wireless/ath5k/hw.h) | 400 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/dma.c | 605 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/eeprom.c | 466 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/eeprom.h | 215 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/gpio.c | 176 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/hw.c | 4529 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/initvals.c | 22 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/pcu.c | 1014 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/phy.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/qcu.c | 488 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/reg.h | 679 | ||||
-rw-r--r-- | drivers/net/wireless/ath5k/reset.c | 931 |
20 files changed, 6314 insertions, 5686 deletions
diff --git a/drivers/net/wireless/ath5k/Makefile b/drivers/net/wireless/ath5k/Makefile index 564ecd0c5d4b..719cfaef7085 100644 --- a/drivers/net/wireless/ath5k/Makefile +++ b/drivers/net/wireless/ath5k/Makefile | |||
@@ -1,6 +1,14 @@ | |||
1 | ath5k-y += base.o | 1 | ath5k-y += caps.o |
2 | ath5k-y += hw.o | ||
3 | ath5k-y += initvals.o | 2 | ath5k-y += initvals.o |
3 | ath5k-y += eeprom.o | ||
4 | ath5k-y += gpio.o | ||
5 | ath5k-y += desc.o | ||
6 | ath5k-y += dma.o | ||
7 | ath5k-y += qcu.o | ||
8 | ath5k-y += pcu.o | ||
4 | ath5k-y += phy.o | 9 | ath5k-y += phy.o |
10 | ath5k-y += reset.o | ||
11 | ath5k-y += attach.o | ||
12 | ath5k-y += base.o | ||
5 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o | 13 | ath5k-$(CONFIG_ATH5K_DEBUG) += debug.o |
6 | obj-$(CONFIG_ATH5K) += ath5k.o | 14 | obj-$(CONFIG_ATH5K) += ath5k.o |
diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index 9102eea3c8bf..53ea439aff48 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h | |||
@@ -18,18 +18,23 @@ | |||
18 | #ifndef _ATH5K_H | 18 | #ifndef _ATH5K_H |
19 | #define _ATH5K_H | 19 | #define _ATH5K_H |
20 | 20 | ||
21 | /* Set this to 1 to disable regulatory domain restrictions for channel tests. | 21 | /* TODO: Clean up channel debuging -doesn't work anyway- and start |
22 | * WARNING: This is for debuging only and has side effects (eg. scan takes too | 22 | * working on reg. control code using all available eeprom information |
23 | * long and results timeouts). It's also illegal to tune to some of the | 23 | * -rev. engineering needed- */ |
24 | * supported frequencies in some countries, so use this at your own risk, | ||
25 | * you've been warned. */ | ||
26 | #define CHAN_DEBUG 0 | 24 | #define CHAN_DEBUG 0 |
27 | 25 | ||
28 | #include <linux/io.h> | 26 | #include <linux/io.h> |
29 | #include <linux/types.h> | 27 | #include <linux/types.h> |
30 | #include <net/mac80211.h> | 28 | #include <net/mac80211.h> |
31 | 29 | ||
32 | #include "hw.h" | 30 | /* RX/TX descriptor hw structs |
31 | * TODO: Driver part should only see sw structs */ | ||
32 | #include "desc.h" | ||
33 | |||
34 | /* EEPROM structs/offsets | ||
35 | * TODO: Make a more generic struct (eg. add more stuff to ath5k_capabilities) | ||
36 | * and clean up common bits, then introduce set/get functions in eeprom.c */ | ||
37 | #include "eeprom.h" | ||
33 | 38 | ||
34 | /* PCI IDs */ | 39 | /* PCI IDs */ |
35 | #define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ | 40 | #define PCI_DEVICE_ID_ATHEROS_AR5210 0x0007 /* AR5210 */ |
@@ -87,7 +92,92 @@ | |||
87 | ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__) | 92 | ATH5K_PRINTK_LIMIT(_sc, KERN_ERR, _fmt, ##__VA_ARGS__) |
88 | 93 | ||
89 | /* | 94 | /* |
95 | * AR5K REGISTER ACCESS | ||
96 | */ | ||
97 | |||
98 | /* Some macros to read/write fields */ | ||
99 | |||
100 | /* First shift, then mask */ | ||
101 | #define AR5K_REG_SM(_val, _flags) \ | ||
102 | (((_val) << _flags##_S) & (_flags)) | ||
103 | |||
104 | /* First mask, then shift */ | ||
105 | #define AR5K_REG_MS(_val, _flags) \ | ||
106 | (((_val) & (_flags)) >> _flags##_S) | ||
107 | |||
108 | /* Some registers can hold multiple values of interest. For this | ||
109 | * reason when we want to write to these registers we must first | ||
110 | * retrieve the values which we do not want to clear (lets call this | ||
111 | * old_data) and then set the register with this and our new_value: | ||
112 | * ( old_data | new_value) */ | ||
113 | #define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val) \ | ||
114 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \ | ||
115 | (((_val) << _flags##_S) & (_flags)), _reg) | ||
116 | |||
117 | #define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask) \ | ||
118 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & \ | ||
119 | (_mask)) | (_flags), _reg) | ||
120 | |||
121 | #define AR5K_REG_ENABLE_BITS(ah, _reg, _flags) \ | ||
122 | ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg) | ||
123 | |||
124 | #define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \ | ||
125 | ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg) | ||
126 | |||
127 | /* Access to PHY registers */ | ||
128 | #define AR5K_PHY_READ(ah, _reg) \ | ||
129 | ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2)) | ||
130 | |||
131 | #define AR5K_PHY_WRITE(ah, _reg, _val) \ | ||
132 | ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2)) | ||
133 | |||
134 | /* Access QCU registers per queue */ | ||
135 | #define AR5K_REG_READ_Q(ah, _reg, _queue) \ | ||
136 | (ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \ | ||
137 | |||
138 | #define AR5K_REG_WRITE_Q(ah, _reg, _queue) \ | ||
139 | ath5k_hw_reg_write(ah, (1 << _queue), _reg) | ||
140 | |||
141 | #define AR5K_Q_ENABLE_BITS(_reg, _queue) do { \ | ||
142 | _reg |= 1 << _queue; \ | ||
143 | } while (0) | ||
144 | |||
145 | #define AR5K_Q_DISABLE_BITS(_reg, _queue) do { \ | ||
146 | _reg &= ~(1 << _queue); \ | ||
147 | } while (0) | ||
148 | |||
149 | /* Used while writing initvals */ | ||
150 | #define AR5K_REG_WAIT(_i) do { \ | ||
151 | if (_i % 64) \ | ||
152 | udelay(1); \ | ||
153 | } while (0) | ||
154 | |||
155 | /* Register dumps are done per operation mode */ | ||
156 | #define AR5K_INI_RFGAIN_5GHZ 0 | ||
157 | #define AR5K_INI_RFGAIN_2GHZ 1 | ||
158 | |||
159 | /* TODO: Clean this up */ | ||
160 | #define AR5K_INI_VAL_11A 0 | ||
161 | #define AR5K_INI_VAL_11A_TURBO 1 | ||
162 | #define AR5K_INI_VAL_11B 2 | ||
163 | #define AR5K_INI_VAL_11G 3 | ||
164 | #define AR5K_INI_VAL_11G_TURBO 4 | ||
165 | #define AR5K_INI_VAL_XR 0 | ||
166 | #define AR5K_INI_VAL_MAX 5 | ||
167 | |||
168 | #define AR5K_RF5111_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS | ||
169 | #define AR5K_RF5112_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS | ||
170 | |||
171 | /* Used for BSSID etc manipulation */ | ||
172 | #define AR5K_LOW_ID(_a)( \ | ||
173 | (_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \ | ||
174 | ) | ||
175 | |||
176 | #define AR5K_HIGH_ID(_a) ((_a)[4] | (_a)[5] << 8) | ||
177 | |||
178 | /* | ||
90 | * Some tuneable values (these should be changeable by the user) | 179 | * Some tuneable values (these should be changeable by the user) |
180 | * TODO: Make use of them and add more options OR use debug/configfs | ||
91 | */ | 181 | */ |
92 | #define AR5K_TUNE_DMA_BEACON_RESP 2 | 182 | #define AR5K_TUNE_DMA_BEACON_RESP 2 |
93 | #define AR5K_TUNE_SW_BEACON_RESP 10 | 183 | #define AR5K_TUNE_SW_BEACON_RESP 10 |
@@ -98,13 +188,13 @@ | |||
98 | #define AR5K_TUNE_REGISTER_TIMEOUT 20000 | 188 | #define AR5K_TUNE_REGISTER_TIMEOUT 20000 |
99 | /* Register for RSSI threshold has a mask of 0xff, so 255 seems to | 189 | /* Register for RSSI threshold has a mask of 0xff, so 255 seems to |
100 | * be the max value. */ | 190 | * be the max value. */ |
101 | #define AR5K_TUNE_RSSI_THRES 129 | 191 | #define AR5K_TUNE_RSSI_THRES 129 |
102 | /* This must be set when setting the RSSI threshold otherwise it can | 192 | /* This must be set when setting the RSSI threshold otherwise it can |
103 | * prevent a reset. If AR5K_RSSI_THR is read after writing to it | 193 | * prevent a reset. If AR5K_RSSI_THR is read after writing to it |
104 | * the BMISS_THRES will be seen as 0, seems harware doesn't keep | 194 | * the BMISS_THRES will be seen as 0, seems harware doesn't keep |
105 | * track of it. Max value depends on harware. For AR5210 this is just 7. | 195 | * track of it. Max value depends on harware. For AR5210 this is just 7. |
106 | * For AR5211+ this seems to be up to 255. */ | 196 | * For AR5211+ this seems to be up to 255. */ |
107 | #define AR5K_TUNE_BMISS_THRES 7 | 197 | #define AR5K_TUNE_BMISS_THRES 7 |
108 | #define AR5K_TUNE_REGISTER_DWELL_TIME 20000 | 198 | #define AR5K_TUNE_REGISTER_DWELL_TIME 20000 |
109 | #define AR5K_TUNE_BEACON_INTERVAL 100 | 199 | #define AR5K_TUNE_BEACON_INTERVAL 100 |
110 | #define AR5K_TUNE_AIFS 2 | 200 | #define AR5K_TUNE_AIFS 2 |
@@ -123,6 +213,55 @@ | |||
123 | #define AR5K_TUNE_ANT_DIVERSITY true | 213 | #define AR5K_TUNE_ANT_DIVERSITY true |
124 | #define AR5K_TUNE_HWTXTRIES 4 | 214 | #define AR5K_TUNE_HWTXTRIES 4 |
125 | 215 | ||
216 | #define AR5K_INIT_CARR_SENSE_EN 1 | ||
217 | |||
218 | /*Swap RX/TX Descriptor for big endian archs*/ | ||
219 | #if defined(__BIG_ENDIAN) | ||
220 | #define AR5K_INIT_CFG ( \ | ||
221 | AR5K_CFG_SWTD | AR5K_CFG_SWRD \ | ||
222 | ) | ||
223 | #else | ||
224 | #define AR5K_INIT_CFG 0x00000000 | ||
225 | #endif | ||
226 | |||
227 | /* Initial values */ | ||
228 | #define AR5K_INIT_TX_LATENCY 502 | ||
229 | #define AR5K_INIT_USEC 39 | ||
230 | #define AR5K_INIT_USEC_TURBO 79 | ||
231 | #define AR5K_INIT_USEC_32 31 | ||
232 | #define AR5K_INIT_SLOT_TIME 396 | ||
233 | #define AR5K_INIT_SLOT_TIME_TURBO 480 | ||
234 | #define AR5K_INIT_ACK_CTS_TIMEOUT 1024 | ||
235 | #define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800 | ||
236 | #define AR5K_INIT_PROG_IFS 920 | ||
237 | #define AR5K_INIT_PROG_IFS_TURBO 960 | ||
238 | #define AR5K_INIT_EIFS 3440 | ||
239 | #define AR5K_INIT_EIFS_TURBO 6880 | ||
240 | #define AR5K_INIT_SIFS 560 | ||
241 | #define AR5K_INIT_SIFS_TURBO 480 | ||
242 | #define AR5K_INIT_SH_RETRY 10 | ||
243 | #define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY | ||
244 | #define AR5K_INIT_SSH_RETRY 32 | ||
245 | #define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY | ||
246 | #define AR5K_INIT_TX_RETRY 10 | ||
247 | |||
248 | #define AR5K_INIT_TRANSMIT_LATENCY ( \ | ||
249 | (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \ | ||
250 | (AR5K_INIT_USEC) \ | ||
251 | ) | ||
252 | #define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \ | ||
253 | (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \ | ||
254 | (AR5K_INIT_USEC_TURBO) \ | ||
255 | ) | ||
256 | #define AR5K_INIT_PROTO_TIME_CNTRL ( \ | ||
257 | (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \ | ||
258 | (AR5K_INIT_PROG_IFS) \ | ||
259 | ) | ||
260 | #define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \ | ||
261 | (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \ | ||
262 | (AR5K_INIT_PROG_IFS_TURBO) \ | ||
263 | ) | ||
264 | |||
126 | /* token to use for aifs, cwmin, cwmax in MadWiFi */ | 265 | /* token to use for aifs, cwmin, cwmax in MadWiFi */ |
127 | #define AR5K_TXQ_USEDEFAULT ((u32) -1) | 266 | #define AR5K_TXQ_USEDEFAULT ((u32) -1) |
128 | 267 | ||
@@ -142,7 +281,9 @@ enum ath5k_radio { | |||
142 | AR5K_RF5112 = 2, | 281 | AR5K_RF5112 = 2, |
143 | AR5K_RF2413 = 3, | 282 | AR5K_RF2413 = 3, |
144 | AR5K_RF5413 = 4, | 283 | AR5K_RF5413 = 4, |
145 | AR5K_RF2425 = 5, | 284 | AR5K_RF2316 = 5, |
285 | AR5K_RF2317 = 6, | ||
286 | AR5K_RF2425 = 7, | ||
146 | }; | 287 | }; |
147 | 288 | ||
148 | /* | 289 | /* |
@@ -150,7 +291,7 @@ enum ath5k_radio { | |||
150 | */ | 291 | */ |
151 | 292 | ||
152 | enum ath5k_srev_type { | 293 | enum ath5k_srev_type { |
153 | AR5K_VERSION_VER, | 294 | AR5K_VERSION_MAC, |
154 | AR5K_VERSION_RAD, | 295 | AR5K_VERSION_RAD, |
155 | }; | 296 | }; |
156 | 297 | ||
@@ -162,23 +303,24 @@ struct ath5k_srev_name { | |||
162 | 303 | ||
163 | #define AR5K_SREV_UNKNOWN 0xffff | 304 | #define AR5K_SREV_UNKNOWN 0xffff |
164 | 305 | ||
165 | #define AR5K_SREV_VER_AR5210 0x00 | 306 | #define AR5K_SREV_AR5210 0x00 /* Crete */ |
166 | #define AR5K_SREV_VER_AR5311 0x10 | 307 | #define AR5K_SREV_AR5311 0x10 /* Maui 1 */ |
167 | #define AR5K_SREV_VER_AR5311A 0x20 | 308 | #define AR5K_SREV_AR5311A 0x20 /* Maui 2 */ |
168 | #define AR5K_SREV_VER_AR5311B 0x30 | 309 | #define AR5K_SREV_AR5311B 0x30 /* Spirit */ |
169 | #define AR5K_SREV_VER_AR5211 0x40 | 310 | #define AR5K_SREV_AR5211 0x40 /* Oahu */ |
170 | #define AR5K_SREV_VER_AR5212 0x50 | 311 | #define AR5K_SREV_AR5212 0x50 /* Venice */ |
171 | #define AR5K_SREV_VER_AR5213 0x55 | 312 | #define AR5K_SREV_AR5213 0x55 /* ??? */ |
172 | #define AR5K_SREV_VER_AR5213A 0x59 | 313 | #define AR5K_SREV_AR5213A 0x59 /* Hainan */ |
173 | #define AR5K_SREV_VER_AR2413 0x78 | 314 | #define AR5K_SREV_AR2413 0x78 /* Griffin lite */ |
174 | #define AR5K_SREV_VER_AR2414 0x79 | 315 | #define AR5K_SREV_AR2414 0x70 /* Griffin */ |
175 | #define AR5K_SREV_VER_AR2424 0xa0 /* PCI-E */ | 316 | #define AR5K_SREV_AR5424 0x90 /* Condor */ |
176 | #define AR5K_SREV_VER_AR5424 0xa3 /* PCI-E */ | 317 | #define AR5K_SREV_AR5413 0xa4 /* Eagle lite */ |
177 | #define AR5K_SREV_VER_AR5413 0xa4 | 318 | #define AR5K_SREV_AR5414 0xa0 /* Eagle */ |
178 | #define AR5K_SREV_VER_AR5414 0xa5 | 319 | #define AR5K_SREV_AR2415 0xb0 /* Cobra */ |
179 | #define AR5K_SREV_VER_AR5416 0xc0 /* PCI-E */ | 320 | #define AR5K_SREV_AR5416 0xc0 /* PCI-E */ |
180 | #define AR5K_SREV_VER_AR5418 0xca /* PCI-E */ | 321 | #define AR5K_SREV_AR5418 0xca /* PCI-E */ |
181 | #define AR5K_SREV_VER_AR2425 0xe2 /* PCI-E */ | 322 | #define AR5K_SREV_AR2425 0xe0 /* Swan */ |
323 | #define AR5K_SREV_AR2417 0xf0 /* Nala */ | ||
182 | 324 | ||
183 | #define AR5K_SREV_RAD_5110 0x00 | 325 | #define AR5K_SREV_RAD_5110 0x00 |
184 | #define AR5K_SREV_RAD_5111 0x10 | 326 | #define AR5K_SREV_RAD_5111 0x10 |
@@ -190,13 +332,22 @@ struct ath5k_srev_name { | |||
190 | #define AR5K_SREV_RAD_2112 0x40 | 332 | #define AR5K_SREV_RAD_2112 0x40 |
191 | #define AR5K_SREV_RAD_2112A 0x45 | 333 | #define AR5K_SREV_RAD_2112A 0x45 |
192 | #define AR5K_SREV_RAD_2112B 0x46 | 334 | #define AR5K_SREV_RAD_2112B 0x46 |
193 | #define AR5K_SREV_RAD_SC0 0x50 /* Found on 2413/2414 */ | 335 | #define AR5K_SREV_RAD_2413 0x50 |
194 | #define AR5K_SREV_RAD_SC1 0x60 /* Found on 5413/5414 */ | 336 | #define AR5K_SREV_RAD_5413 0x60 |
195 | #define AR5K_SREV_RAD_SC2 0xa0 /* Found on 2424-5/5424 */ | 337 | #define AR5K_SREV_RAD_2316 0x70 |
196 | #define AR5K_SREV_RAD_5133 0xc0 /* MIMO found on 5418 */ | 338 | #define AR5K_SREV_RAD_2317 0x80 |
339 | #define AR5K_SREV_RAD_5424 0xa0 /* Mostly same as 5413 */ | ||
340 | #define AR5K_SREV_RAD_2425 0xa2 | ||
341 | #define AR5K_SREV_RAD_5133 0xc0 | ||
342 | |||
343 | #define AR5K_SREV_PHY_5211 0x30 | ||
344 | #define AR5K_SREV_PHY_5212 0x41 | ||
345 | #define AR5K_SREV_PHY_2112B 0x43 | ||
346 | #define AR5K_SREV_PHY_2413 0x45 | ||
347 | #define AR5K_SREV_PHY_5413 0x61 | ||
348 | #define AR5K_SREV_PHY_2425 0x70 | ||
197 | 349 | ||
198 | /* IEEE defs */ | 350 | /* IEEE defs */ |
199 | |||
200 | #define IEEE80211_MAX_LEN 2500 | 351 | #define IEEE80211_MAX_LEN 2500 |
201 | 352 | ||
202 | /* TODO add support to mac80211 for vendor-specific rates and modes */ | 353 | /* TODO add support to mac80211 for vendor-specific rates and modes */ |
@@ -268,27 +419,21 @@ enum ath5k_driver_mode { | |||
268 | AR5K_MODE_MAX = 5 | 419 | AR5K_MODE_MAX = 5 |
269 | }; | 420 | }; |
270 | 421 | ||
271 | /* adding this flag to rate_code enables short preamble, see ar5212_reg.h */ | ||
272 | #define AR5K_SET_SHORT_PREAMBLE 0x04 | ||
273 | |||
274 | #define HAS_SHPREAMBLE(_ix) \ | ||
275 | (rt->rates[_ix].modulation == IEEE80211_RATE_SHORT_PREAMBLE) | ||
276 | #define SHPREAMBLE_FLAG(_ix) \ | ||
277 | (HAS_SHPREAMBLE(_ix) ? AR5K_SET_SHORT_PREAMBLE : 0) | ||
278 | |||
279 | 422 | ||
280 | /****************\ | 423 | /****************\ |
281 | TX DEFINITIONS | 424 | TX DEFINITIONS |
282 | \****************/ | 425 | \****************/ |
283 | 426 | ||
284 | /* | 427 | /* |
285 | * TX Status | 428 | * TX Status descriptor |
286 | */ | 429 | */ |
287 | struct ath5k_tx_status { | 430 | struct ath5k_tx_status { |
288 | u16 ts_seqnum; | 431 | u16 ts_seqnum; |
289 | u16 ts_tstamp; | 432 | u16 ts_tstamp; |
290 | u8 ts_status; | 433 | u8 ts_status; |
291 | u8 ts_rate; | 434 | u8 ts_rate[4]; |
435 | u8 ts_retry[4]; | ||
436 | u8 ts_final_idx; | ||
292 | s8 ts_rssi; | 437 | s8 ts_rssi; |
293 | u8 ts_shortretry; | 438 | u8 ts_shortretry; |
294 | u8 ts_longretry; | 439 | u8 ts_longretry; |
@@ -354,7 +499,6 @@ enum ath5k_tx_queue_id { | |||
354 | AR5K_TX_QUEUE_ID_XR_DATA = 9, | 499 | AR5K_TX_QUEUE_ID_XR_DATA = 9, |
355 | }; | 500 | }; |
356 | 501 | ||
357 | |||
358 | /* | 502 | /* |
359 | * Flags to set hw queue's parameters... | 503 | * Flags to set hw queue's parameters... |
360 | */ | 504 | */ |
@@ -387,7 +531,8 @@ struct ath5k_txq_info { | |||
387 | 531 | ||
388 | /* | 532 | /* |
389 | * Transmit packet types. | 533 | * Transmit packet types. |
390 | * These are not fully used inside OpenHAL yet | 534 | * used on tx control descriptor |
535 | * TODO: Use them inside base.c corectly | ||
391 | */ | 536 | */ |
392 | enum ath5k_pkt_type { | 537 | enum ath5k_pkt_type { |
393 | AR5K_PKT_TYPE_NORMAL = 0, | 538 | AR5K_PKT_TYPE_NORMAL = 0, |
@@ -430,7 +575,7 @@ enum ath5k_dmasize { | |||
430 | \****************/ | 575 | \****************/ |
431 | 576 | ||
432 | /* | 577 | /* |
433 | * RX Status | 578 | * RX Status descriptor |
434 | */ | 579 | */ |
435 | struct ath5k_rx_status { | 580 | struct ath5k_rx_status { |
436 | u16 rs_datalen; | 581 | u16 rs_datalen; |
@@ -494,34 +639,59 @@ struct ath5k_beacon_state { | |||
494 | #define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10) | 639 | #define TSF_TO_TU(_tsf) (u32)((_tsf) >> 10) |
495 | 640 | ||
496 | 641 | ||
642 | /*******************************\ | ||
643 | GAIN OPTIMIZATION DEFINITIONS | ||
644 | \*******************************/ | ||
645 | |||
646 | enum ath5k_rfgain { | ||
647 | AR5K_RFGAIN_INACTIVE = 0, | ||
648 | AR5K_RFGAIN_READ_REQUESTED, | ||
649 | AR5K_RFGAIN_NEED_CHANGE, | ||
650 | }; | ||
651 | |||
652 | #define AR5K_GAIN_CRN_FIX_BITS_5111 4 | ||
653 | #define AR5K_GAIN_CRN_FIX_BITS_5112 7 | ||
654 | #define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112 | ||
655 | #define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15 | ||
656 | #define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20 | ||
657 | #define AR5K_GAIN_CCK_PROBE_CORR 5 | ||
658 | #define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15 | ||
659 | #define AR5K_GAIN_STEP_COUNT 10 | ||
660 | #define AR5K_GAIN_PARAM_TX_CLIP 0 | ||
661 | #define AR5K_GAIN_PARAM_PD_90 1 | ||
662 | #define AR5K_GAIN_PARAM_PD_84 2 | ||
663 | #define AR5K_GAIN_PARAM_GAIN_SEL 3 | ||
664 | #define AR5K_GAIN_PARAM_MIX_ORN 0 | ||
665 | #define AR5K_GAIN_PARAM_PD_138 1 | ||
666 | #define AR5K_GAIN_PARAM_PD_137 2 | ||
667 | #define AR5K_GAIN_PARAM_PD_136 3 | ||
668 | #define AR5K_GAIN_PARAM_PD_132 4 | ||
669 | #define AR5K_GAIN_PARAM_PD_131 5 | ||
670 | #define AR5K_GAIN_PARAM_PD_130 6 | ||
671 | #define AR5K_GAIN_CHECK_ADJUST(_g) \ | ||
672 | ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high) | ||
673 | |||
674 | struct ath5k_gain_opt_step { | ||
675 | s16 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS]; | ||
676 | s32 gos_gain; | ||
677 | }; | ||
678 | |||
679 | struct ath5k_gain { | ||
680 | u32 g_step_idx; | ||
681 | u32 g_current; | ||
682 | u32 g_target; | ||
683 | u32 g_low; | ||
684 | u32 g_high; | ||
685 | u32 g_f_corr; | ||
686 | u32 g_active; | ||
687 | const struct ath5k_gain_opt_step *g_step; | ||
688 | }; | ||
689 | |||
690 | |||
497 | /********************\ | 691 | /********************\ |
498 | COMMON DEFINITIONS | 692 | COMMON DEFINITIONS |
499 | \********************/ | 693 | \********************/ |
500 | 694 | ||
501 | /* | ||
502 | * Atheros hardware descriptor | ||
503 | * This is read and written to by the hardware | ||
504 | */ | ||
505 | struct ath5k_desc { | ||
506 | u32 ds_link; /* physical address of the next descriptor */ | ||
507 | u32 ds_data; /* physical address of data buffer (skb) */ | ||
508 | |||
509 | union { | ||
510 | struct ath5k_hw_5210_tx_desc ds_tx5210; | ||
511 | struct ath5k_hw_5212_tx_desc ds_tx5212; | ||
512 | struct ath5k_hw_all_rx_desc ds_rx; | ||
513 | } ud; | ||
514 | } __packed; | ||
515 | |||
516 | #define AR5K_RXDESC_INTREQ 0x0020 | ||
517 | |||
518 | #define AR5K_TXDESC_CLRDMASK 0x0001 | ||
519 | #define AR5K_TXDESC_NOACK 0x0002 /*[5211+]*/ | ||
520 | #define AR5K_TXDESC_RTSENA 0x0004 | ||
521 | #define AR5K_TXDESC_CTSENA 0x0008 | ||
522 | #define AR5K_TXDESC_INTREQ 0x0010 | ||
523 | #define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/ | ||
524 | |||
525 | #define AR5K_SLOT_TIME_9 396 | 695 | #define AR5K_SLOT_TIME_9 396 |
526 | #define AR5K_SLOT_TIME_20 880 | 696 | #define AR5K_SLOT_TIME_20 880 |
527 | #define AR5K_SLOT_TIME_MAX 0xffff | 697 | #define AR5K_SLOT_TIME_MAX 0xffff |
@@ -553,167 +723,79 @@ struct ath5k_desc { | |||
553 | #define CHANNEL_MODES CHANNEL_ALL | 723 | #define CHANNEL_MODES CHANNEL_ALL |
554 | 724 | ||
555 | /* | 725 | /* |
556 | * Used internaly in OpenHAL (ar5211.c/ar5212.c | 726 | * Used internaly for reset_tx_queue). |
557 | * for reset_tx_queue). Also see struct struct ieee80211_channel. | 727 | * Also see struct struct ieee80211_channel. |
558 | */ | 728 | */ |
559 | #define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0) | 729 | #define IS_CHAN_XR(_c) ((_c.hw_value & CHANNEL_XR) != 0) |
560 | #define IS_CHAN_B(_c) ((_c.hw_value & CHANNEL_B) != 0) | 730 | #define IS_CHAN_B(_c) ((_c.hw_value & CHANNEL_B) != 0) |
561 | 731 | ||
562 | /* | 732 | /* |
563 | * The following structure will be used to map 2GHz channels to | 733 | * The following structure is used to map 2GHz channels to |
564 | * 5GHz Atheros channels. | 734 | * 5GHz Atheros channels. |
735 | * TODO: Clean up | ||
565 | */ | 736 | */ |
566 | struct ath5k_athchan_2ghz { | 737 | struct ath5k_athchan_2ghz { |
567 | u32 a2_flags; | 738 | u32 a2_flags; |
568 | u16 a2_athchan; | 739 | u16 a2_athchan; |
569 | }; | 740 | }; |
570 | 741 | ||
571 | /* | ||
572 | * Rate definitions | ||
573 | * TODO: Clean them up or move them on mac80211 -most of these infos are | ||
574 | * used by the rate control algorytm on MadWiFi. | ||
575 | */ | ||
576 | 742 | ||
577 | /* Max number of rates on the rate table and what it seems | 743 | /******************\ |
578 | * Atheros hardware supports */ | 744 | RATE DEFINITIONS |
579 | #define AR5K_MAX_RATES 32 | 745 | \******************/ |
580 | 746 | ||
581 | /** | 747 | /** |
582 | * struct ath5k_rate - rate structure | 748 | * Seems the ar5xxx harware supports up to 32 rates, indexed by 1-32. |
583 | * @valid: is this a valid rate for rate control (remove) | ||
584 | * @modulation: respective mac80211 modulation | ||
585 | * @rate_kbps: rate in kbit/s | ||
586 | * @rate_code: hardware rate value, used in &struct ath5k_desc, on RX on | ||
587 | * &struct ath5k_rx_status.rs_rate and on TX on | ||
588 | * &struct ath5k_tx_status.ts_rate. Seems the ar5xxx harware supports | ||
589 | * up to 32 rates, indexed by 1-32. This means we really only need | ||
590 | * 6 bits for the rate_code. | ||
591 | * @dot11_rate: respective IEEE-802.11 rate value | ||
592 | * @control_rate: index of rate assumed to be used to send control frames. | ||
593 | * This can be used to set override the value on the rate duration | ||
594 | * registers. This is only useful if we can override in the harware at | ||
595 | * what rate we want to send control frames at. Note that IEEE-802.11 | ||
596 | * Ch. 9.6 (after IEEE 802.11g changes) defines the rate at which we | ||
597 | * should send ACK/CTS, if we change this value we can be breaking | ||
598 | * the spec. | ||
599 | * | 749 | * |
600 | * This structure is used to get the RX rate or set the TX rate on the | 750 | * The rate code is used to get the RX rate or set the TX rate on the |
601 | * hardware descriptors. It is also used for internal modulation control | 751 | * hardware descriptors. It is also used for internal modulation control |
602 | * and settings. | 752 | * and settings. |
603 | * | 753 | * |
604 | * On RX after the &struct ath5k_desc is parsed by the appropriate | 754 | * This is the hardware rate map we are aware of: |
605 | * ah_proc_rx_desc() the respective hardware rate value is set in | ||
606 | * &struct ath5k_rx_status.rs_rate. On TX the desired rate is set in | ||
607 | * &struct ath5k_tx_status.ts_rate which is later used to setup the | ||
608 | * &struct ath5k_desc correctly. This is the hardware rate map we are | ||
609 | * aware of: | ||
610 | * | 755 | * |
611 | * rate_code 1 2 3 4 5 6 7 8 | 756 | * rate_code 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 |
612 | * rate_kbps 3000 1000 ? ? ? 2000 500 48000 | 757 | * rate_kbps 3000 1000 ? ? ? 2000 500 48000 |
613 | * | 758 | * |
614 | * rate_code 9 10 11 12 13 14 15 16 | 759 | * rate_code 0x09 0x0A 0x0B 0x0C 0x0D 0x0E 0x0F 0x10 |
615 | * rate_kbps 24000 12000 6000 54000 36000 18000 9000 ? | 760 | * rate_kbps 24000 12000 6000 54000 36000 18000 9000 ? |
616 | * | 761 | * |
617 | * rate_code 17 18 19 20 21 22 23 24 | 762 | * rate_code 17 18 19 20 21 22 23 24 |
618 | * rate_kbps ? ? ? ? ? ? ? 11000 | 763 | * rate_kbps ? ? ? ? ? ? ? 11000 |
619 | * | 764 | * |
620 | * rate_code 25 26 27 28 29 30 31 32 | 765 | * rate_code 25 26 27 28 29 30 31 32 |
621 | * rate_kbps 5500 2000 1000 ? ? ? ? ? | 766 | * rate_kbps 5500 2000 1000 11000S 5500S 2000S ? ? |
622 | * | 767 | * |
768 | * "S" indicates CCK rates with short preamble. | ||
769 | * | ||
770 | * AR5211 has different rate codes for CCK (802.11B) rates. It only uses the | ||
771 | * lowest 4 bits, so they are the same as below with a 0xF mask. | ||
772 | * (0xB, 0xA, 0x9 and 0x8 for 1M, 2M, 5.5M and 11M). | ||
773 | * We handle this in ath5k_setup_bands(). | ||
623 | */ | 774 | */ |
624 | struct ath5k_rate { | 775 | #define AR5K_MAX_RATES 32 |
625 | u8 valid; | ||
626 | u32 modulation; | ||
627 | u16 rate_kbps; | ||
628 | u8 rate_code; | ||
629 | u8 dot11_rate; | ||
630 | u8 control_rate; | ||
631 | }; | ||
632 | |||
633 | /* XXX: GRR all this stuff to get leds blinking ??? (check out setcurmode) */ | ||
634 | struct ath5k_rate_table { | ||
635 | u16 rate_count; | ||
636 | u8 rate_code_to_index[AR5K_MAX_RATES]; /* Back-mapping */ | ||
637 | struct ath5k_rate rates[AR5K_MAX_RATES]; | ||
638 | }; | ||
639 | |||
640 | /* | ||
641 | * Rate tables... | ||
642 | * TODO: CLEAN THIS !!! | ||
643 | */ | ||
644 | #define AR5K_RATES_11A { 8, { \ | ||
645 | 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \ | ||
646 | 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \ | ||
647 | 255, 255, 255, 255, 255, 255, 255, 255 }, { \ | ||
648 | { 1, 0, 6000, 11, 140, 0 }, \ | ||
649 | { 1, 0, 9000, 15, 18, 0 }, \ | ||
650 | { 1, 0, 12000, 10, 152, 2 }, \ | ||
651 | { 1, 0, 18000, 14, 36, 2 }, \ | ||
652 | { 1, 0, 24000, 9, 176, 4 }, \ | ||
653 | { 1, 0, 36000, 13, 72, 4 }, \ | ||
654 | { 1, 0, 48000, 8, 96, 4 }, \ | ||
655 | { 1, 0, 54000, 12, 108, 4 } } \ | ||
656 | } | ||
657 | |||
658 | #define AR5K_RATES_11B { 4, { \ | ||
659 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ | ||
660 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, \ | ||
661 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ | ||
662 | { 1, 0, 1000, 27, 130, 0 }, \ | ||
663 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 132, 1 }, \ | ||
664 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 139, 1 }, \ | ||
665 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 150, 1 } } \ | ||
666 | } | ||
667 | |||
668 | #define AR5K_RATES_11G { 12, { \ | ||
669 | 255, 255, 255, 255, 255, 255, 255, 255, 10, 8, 6, 4, \ | ||
670 | 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \ | ||
671 | 3, 2, 1, 0, 255, 255, 255, 255 }, { \ | ||
672 | { 1, 0, 1000, 27, 2, 0 }, \ | ||
673 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 2000, 26, 4, 1 }, \ | ||
674 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 5500, 25, 11, 1 }, \ | ||
675 | { 1, IEEE80211_RATE_SHORT_PREAMBLE, 11000, 24, 22, 1 }, \ | ||
676 | { 0, 0, 6000, 11, 12, 4 }, \ | ||
677 | { 0, 0, 9000, 15, 18, 4 }, \ | ||
678 | { 1, 0, 12000, 10, 24, 6 }, \ | ||
679 | { 1, 0, 18000, 14, 36, 6 }, \ | ||
680 | { 1, 0, 24000, 9, 48, 8 }, \ | ||
681 | { 1, 0, 36000, 13, 72, 8 }, \ | ||
682 | { 1, 0, 48000, 8, 96, 8 }, \ | ||
683 | { 1, 0, 54000, 12, 108, 8 } } \ | ||
684 | } | ||
685 | |||
686 | #define AR5K_RATES_TURBO { 8, { \ | ||
687 | 255, 255, 255, 255, 255, 255, 255, 255, 6, 4, 2, 0, \ | ||
688 | 7, 5, 3, 1, 255, 255, 255, 255, 255, 255, 255, 255, \ | ||
689 | 255, 255, 255, 255, 255, 255, 255, 255 }, { \ | ||
690 | { 1, MODULATION_TURBO, 6000, 11, 140, 0 }, \ | ||
691 | { 1, MODULATION_TURBO, 9000, 15, 18, 0 }, \ | ||
692 | { 1, MODULATION_TURBO, 12000, 10, 152, 2 }, \ | ||
693 | { 1, MODULATION_TURBO, 18000, 14, 36, 2 }, \ | ||
694 | { 1, MODULATION_TURBO, 24000, 9, 176, 4 }, \ | ||
695 | { 1, MODULATION_TURBO, 36000, 13, 72, 4 }, \ | ||
696 | { 1, MODULATION_TURBO, 48000, 8, 96, 4 }, \ | ||
697 | { 1, MODULATION_TURBO, 54000, 12, 108, 4 } } \ | ||
698 | } | ||
699 | 776 | ||
700 | #define AR5K_RATES_XR { 12, { \ | 777 | /* B */ |
701 | 255, 3, 1, 255, 255, 255, 2, 0, 10, 8, 6, 4, \ | 778 | #define ATH5K_RATE_CODE_1M 0x1B |
702 | 11, 9, 7, 5, 255, 255, 255, 255, 255, 255, 255, 255, \ | 779 | #define ATH5K_RATE_CODE_2M 0x1A |
703 | 255, 255, 255, 255, 255, 255, 255, 255 }, { \ | 780 | #define ATH5K_RATE_CODE_5_5M 0x19 |
704 | { 1, MODULATION_XR, 500, 7, 129, 0 }, \ | 781 | #define ATH5K_RATE_CODE_11M 0x18 |
705 | { 1, MODULATION_XR, 1000, 2, 139, 1 }, \ | 782 | /* A and G */ |
706 | { 1, MODULATION_XR, 2000, 6, 150, 2 }, \ | 783 | #define ATH5K_RATE_CODE_6M 0x0B |
707 | { 1, MODULATION_XR, 3000, 1, 150, 3 }, \ | 784 | #define ATH5K_RATE_CODE_9M 0x0F |
708 | { 1, 0, 6000, 11, 140, 4 }, \ | 785 | #define ATH5K_RATE_CODE_12M 0x0A |
709 | { 1, 0, 9000, 15, 18, 4 }, \ | 786 | #define ATH5K_RATE_CODE_18M 0x0E |
710 | { 1, 0, 12000, 10, 152, 6 }, \ | 787 | #define ATH5K_RATE_CODE_24M 0x09 |
711 | { 1, 0, 18000, 14, 36, 6 }, \ | 788 | #define ATH5K_RATE_CODE_36M 0x0D |
712 | { 1, 0, 24000, 9, 176, 8 }, \ | 789 | #define ATH5K_RATE_CODE_48M 0x08 |
713 | { 1, 0, 36000, 13, 72, 8 }, \ | 790 | #define ATH5K_RATE_CODE_54M 0x0C |
714 | { 1, 0, 48000, 8, 96, 8 }, \ | 791 | /* XR */ |
715 | { 1, 0, 54000, 12, 108, 8 } } \ | 792 | #define ATH5K_RATE_CODE_XR_500K 0x07 |
716 | } | 793 | #define ATH5K_RATE_CODE_XR_1M 0x02 |
794 | #define ATH5K_RATE_CODE_XR_2M 0x06 | ||
795 | #define ATH5K_RATE_CODE_XR_3M 0x01 | ||
796 | |||
797 | /* adding this flag to rate_code enables short preamble */ | ||
798 | #define AR5K_SET_SHORT_PREAMBLE 0x04 | ||
717 | 799 | ||
718 | /* | 800 | /* |
719 | * Crypto definitions | 801 | * Crypto definitions |
@@ -735,7 +817,6 @@ struct ath5k_rate_table { | |||
735 | return (false); \ | 817 | return (false); \ |
736 | } while (0) | 818 | } while (0) |
737 | 819 | ||
738 | |||
739 | enum ath5k_ant_setting { | 820 | enum ath5k_ant_setting { |
740 | AR5K_ANT_VARIABLE = 0, /* variable by programming */ | 821 | AR5K_ANT_VARIABLE = 0, /* variable by programming */ |
741 | AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */ | 822 | AR5K_ANT_FIXED_A = 1, /* fixed to 11a frequencies */ |
@@ -846,7 +927,8 @@ enum ath5k_power_mode { | |||
846 | 927 | ||
847 | /* | 928 | /* |
848 | * These match net80211 definitions (not used in | 929 | * These match net80211 definitions (not used in |
849 | * d80211). | 930 | * mac80211). |
931 | * TODO: Clean this up | ||
850 | */ | 932 | */ |
851 | #define AR5K_LED_INIT 0 /*IEEE80211_S_INIT*/ | 933 | #define AR5K_LED_INIT 0 /*IEEE80211_S_INIT*/ |
852 | #define AR5K_LED_SCAN 1 /*IEEE80211_S_SCAN*/ | 934 | #define AR5K_LED_SCAN 1 /*IEEE80211_S_SCAN*/ |
@@ -862,7 +944,8 @@ enum ath5k_power_mode { | |||
862 | /* | 944 | /* |
863 | * Chipset capabilities -see ath5k_hw_get_capability- | 945 | * Chipset capabilities -see ath5k_hw_get_capability- |
864 | * get_capability function is not yet fully implemented | 946 | * get_capability function is not yet fully implemented |
865 | * in OpenHAL so most of these don't work yet... | 947 | * in ath5k so most of these don't work yet... |
948 | * TODO: Implement these & merge with _TUNE_ stuff above | ||
866 | */ | 949 | */ |
867 | enum ath5k_capability_type { | 950 | enum ath5k_capability_type { |
868 | AR5K_CAP_REG_DMN = 0, /* Used to get current reg. domain id */ | 951 | AR5K_CAP_REG_DMN = 0, /* Used to get current reg. domain id */ |
@@ -931,6 +1014,7 @@ struct ath5k_capabilities { | |||
931 | #define AR5K_MAX_GPIO 10 | 1014 | #define AR5K_MAX_GPIO 10 |
932 | #define AR5K_MAX_RF_BANKS 8 | 1015 | #define AR5K_MAX_RF_BANKS 8 |
933 | 1016 | ||
1017 | /* TODO: Clean up and merge with ath5k_softc */ | ||
934 | struct ath5k_hw { | 1018 | struct ath5k_hw { |
935 | u32 ah_magic; | 1019 | u32 ah_magic; |
936 | 1020 | ||
@@ -939,7 +1023,7 @@ struct ath5k_hw { | |||
939 | 1023 | ||
940 | enum ath5k_int ah_imr; | 1024 | enum ath5k_int ah_imr; |
941 | 1025 | ||
942 | enum ieee80211_if_types ah_op_mode; | 1026 | enum nl80211_iftype ah_op_mode; |
943 | enum ath5k_power_mode ah_power_mode; | 1027 | enum ath5k_power_mode ah_power_mode; |
944 | struct ieee80211_channel ah_current_channel; | 1028 | struct ieee80211_channel ah_current_channel; |
945 | bool ah_turbo; | 1029 | bool ah_turbo; |
@@ -1023,11 +1107,13 @@ struct ath5k_hw { | |||
1023 | /* | 1107 | /* |
1024 | * Function pointers | 1108 | * Function pointers |
1025 | */ | 1109 | */ |
1110 | int (*ah_setup_rx_desc)(struct ath5k_hw *ah, struct ath5k_desc *desc, | ||
1111 | u32 size, unsigned int flags); | ||
1026 | int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, | 1112 | int (*ah_setup_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, |
1027 | unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, | 1113 | unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, |
1028 | unsigned int, unsigned int, unsigned int, unsigned int, | 1114 | unsigned int, unsigned int, unsigned int, unsigned int, |
1029 | unsigned int, unsigned int, unsigned int); | 1115 | unsigned int, unsigned int, unsigned int); |
1030 | int (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *, | 1116 | int (*ah_setup_mrr_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, |
1031 | unsigned int, unsigned int, unsigned int, unsigned int, | 1117 | unsigned int, unsigned int, unsigned int, unsigned int, |
1032 | unsigned int, unsigned int); | 1118 | unsigned int, unsigned int); |
1033 | int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, | 1119 | int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *, |
@@ -1040,33 +1126,38 @@ struct ath5k_hw { | |||
1040 | * Prototypes | 1126 | * Prototypes |
1041 | */ | 1127 | */ |
1042 | 1128 | ||
1043 | /* General Functions */ | ||
1044 | extern int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, bool is_set); | ||
1045 | /* Attach/Detach Functions */ | 1129 | /* Attach/Detach Functions */ |
1046 | extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version); | 1130 | extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version); |
1047 | extern const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, unsigned int mode); | ||
1048 | extern void ath5k_hw_detach(struct ath5k_hw *ah); | 1131 | extern void ath5k_hw_detach(struct ath5k_hw *ah); |
1132 | |||
1049 | /* Reset Functions */ | 1133 | /* Reset Functions */ |
1050 | extern int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, struct ieee80211_channel *channel, bool change_channel); | 1134 | extern int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial); |
1135 | extern int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, struct ieee80211_channel *channel, bool change_channel); | ||
1051 | /* Power management functions */ | 1136 | /* Power management functions */ |
1052 | extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration); | 1137 | extern int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, bool set_chip, u16 sleep_duration); |
1138 | |||
1053 | /* DMA Related Functions */ | 1139 | /* DMA Related Functions */ |
1054 | extern void ath5k_hw_start_rx(struct ath5k_hw *ah); | 1140 | extern void ath5k_hw_start_rx_dma(struct ath5k_hw *ah); |
1055 | extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); | 1141 | extern int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah); |
1056 | extern u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah); | 1142 | extern u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah); |
1057 | extern void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr); | 1143 | extern void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr); |
1058 | extern int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue); | 1144 | extern int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue); |
1059 | extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); | 1145 | extern int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue); |
1060 | extern u32 ath5k_hw_get_tx_buf(struct ath5k_hw *ah, unsigned int queue); | 1146 | extern u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue); |
1061 | extern int ath5k_hw_put_tx_buf(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr); | 1147 | extern int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, |
1148 | u32 phys_addr); | ||
1062 | extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); | 1149 | extern int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase); |
1063 | /* Interrupt handling */ | 1150 | /* Interrupt handling */ |
1064 | extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); | 1151 | extern bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah); |
1065 | extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); | 1152 | extern int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask); |
1066 | extern enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask); | 1153 | extern enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum |
1154 | ath5k_int new_mask); | ||
1067 | extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats); | 1155 | extern void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, struct ieee80211_low_level_stats *stats); |
1156 | |||
1068 | /* EEPROM access functions */ | 1157 | /* EEPROM access functions */ |
1069 | extern int ath5k_hw_set_regdomain(struct ath5k_hw *ah, u16 regdomain); | 1158 | extern int ath5k_eeprom_init(struct ath5k_hw *ah); |
1159 | extern int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac); | ||
1160 | |||
1070 | /* Protocol Control Unit Functions */ | 1161 | /* Protocol Control Unit Functions */ |
1071 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); | 1162 | extern int ath5k_hw_set_opmode(struct ath5k_hw *ah); |
1072 | /* BSSID Functions */ | 1163 | /* BSSID Functions */ |
@@ -1076,14 +1167,14 @@ extern void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc | |||
1076 | extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); | 1167 | extern int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask); |
1077 | /* Receive start/stop functions */ | 1168 | /* Receive start/stop functions */ |
1078 | extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); | 1169 | extern void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah); |
1079 | extern void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah); | 1170 | extern void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah); |
1080 | /* RX Filter functions */ | 1171 | /* RX Filter functions */ |
1081 | extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); | 1172 | extern void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1); |
1082 | extern int ath5k_hw_set_mcast_filterindex(struct ath5k_hw *ah, u32 index); | 1173 | extern int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index); |
1083 | extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index); | 1174 | extern int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index); |
1084 | extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); | 1175 | extern u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah); |
1085 | extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); | 1176 | extern void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter); |
1086 | /* Beacon related functions */ | 1177 | /* Beacon control functions */ |
1087 | extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); | 1178 | extern u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah); |
1088 | extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); | 1179 | extern u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah); |
1089 | extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); | 1180 | extern void ath5k_hw_reset_tsf(struct ath5k_hw *ah); |
@@ -1105,61 +1196,129 @@ extern int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry); | |||
1105 | extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); | 1196 | extern int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry); |
1106 | extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac); | 1197 | extern int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, const struct ieee80211_key_conf *key, const u8 *mac); |
1107 | extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); | 1198 | extern int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac); |
1199 | |||
1108 | /* Queue Control Unit, DFS Control Unit Functions */ | 1200 | /* Queue Control Unit, DFS Control Unit Functions */ |
1109 | extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, struct ath5k_txq_info *queue_info); | ||
1110 | extern int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue, const struct ath5k_txq_info *queue_info); | ||
1111 | extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info); | 1201 | extern int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, struct ath5k_txq_info *queue_info); |
1202 | extern int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, | ||
1203 | const struct ath5k_txq_info *queue_info); | ||
1204 | extern int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, | ||
1205 | enum ath5k_tx_queue queue_type, | ||
1206 | struct ath5k_txq_info *queue_info); | ||
1207 | extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); | ||
1112 | extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); | 1208 | extern void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue); |
1113 | extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); | 1209 | extern int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue); |
1114 | extern u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue); | ||
1115 | extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); | ||
1116 | extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah); | 1210 | extern unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah); |
1211 | extern int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time); | ||
1212 | |||
1117 | /* Hardware Descriptor Functions */ | 1213 | /* Hardware Descriptor Functions */ |
1118 | extern int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, u32 size, unsigned int flags); | 1214 | extern int ath5k_hw_init_desc_functions(struct ath5k_hw *ah); |
1215 | |||
1119 | /* GPIO Functions */ | 1216 | /* GPIO Functions */ |
1120 | extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); | 1217 | extern void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state); |
1121 | extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); | ||
1122 | extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); | 1218 | extern int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio); |
1219 | extern int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio); | ||
1123 | extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); | 1220 | extern u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio); |
1124 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); | 1221 | extern int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val); |
1125 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); | 1222 | extern void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, u32 interrupt_level); |
1223 | |||
1126 | /* Misc functions */ | 1224 | /* Misc functions */ |
1225 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah); | ||
1127 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); | 1226 | extern int ath5k_hw_get_capability(struct ath5k_hw *ah, enum ath5k_capability_type cap_type, u32 capability, u32 *result); |
1128 | 1227 | extern int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, u16 assoc_id); | |
1228 | extern int ath5k_hw_disable_pspoll(struct ath5k_hw *ah); | ||
1129 | 1229 | ||
1130 | /* Initial register settings functions */ | 1230 | /* Initial register settings functions */ |
1131 | extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); | 1231 | extern int ath5k_hw_write_initvals(struct ath5k_hw *ah, u8 mode, bool change_channel); |
1232 | |||
1132 | /* Initialize RF */ | 1233 | /* Initialize RF */ |
1133 | extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode); | 1234 | extern int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int mode); |
1134 | extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq); | 1235 | extern int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq); |
1135 | extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah); | 1236 | extern enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah); |
1136 | extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah); | 1237 | extern int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah); |
1137 | |||
1138 | |||
1139 | /* PHY/RF channel functions */ | 1238 | /* PHY/RF channel functions */ |
1140 | extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); | 1239 | extern bool ath5k_channel_ok(struct ath5k_hw *ah, u16 freq, unsigned int flags); |
1141 | extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); | 1240 | extern int ath5k_hw_channel(struct ath5k_hw *ah, struct ieee80211_channel *channel); |
1142 | /* PHY calibration */ | 1241 | /* PHY calibration */ |
1143 | extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); | 1242 | extern int ath5k_hw_phy_calibrate(struct ath5k_hw *ah, struct ieee80211_channel *channel); |
1144 | extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); | 1243 | extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); |
1145 | /* Misc PHY functions */ | 1244 | /* Misc PHY functions */ |
1146 | extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); | 1245 | extern u16 ath5k_hw_radio_revision(struct ath5k_hw *ah, unsigned int chan); |
1147 | extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant); | 1246 | extern void ath5k_hw_set_def_antenna(struct ath5k_hw *ah, unsigned int ant); |
1148 | extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah); | 1247 | extern unsigned int ath5k_hw_get_def_antenna(struct ath5k_hw *ah); |
1149 | extern int ath5k_hw_noise_floor_calibration(struct ath5k_hw *ah, short freq); | 1248 | extern int ath5k_hw_phy_disable(struct ath5k_hw *ah); |
1150 | /* TX power setup */ | 1249 | /* TX power setup */ |
1151 | extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower); | 1250 | extern int ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, unsigned int txpower); |
1152 | extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power); | 1251 | extern int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power); |
1153 | 1252 | ||
1253 | /* | ||
1254 | * Functions used internaly | ||
1255 | */ | ||
1154 | 1256 | ||
1257 | /* | ||
1258 | * Translate usec to hw clock units | ||
1259 | */ | ||
1260 | static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo) | ||
1261 | { | ||
1262 | return turbo ? (usec * 80) : (usec * 40); | ||
1263 | } | ||
1264 | |||
1265 | /* | ||
1266 | * Translate hw clock units to usec | ||
1267 | */ | ||
1268 | static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo) | ||
1269 | { | ||
1270 | return turbo ? (clock / 80) : (clock / 40); | ||
1271 | } | ||
1272 | |||
1273 | /* | ||
1274 | * Read from a register | ||
1275 | */ | ||
1155 | static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) | 1276 | static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg) |
1156 | { | 1277 | { |
1157 | return ioread32(ah->ah_iobase + reg); | 1278 | return ioread32(ah->ah_iobase + reg); |
1158 | } | 1279 | } |
1159 | 1280 | ||
1281 | /* | ||
1282 | * Write to a register | ||
1283 | */ | ||
1160 | static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) | 1284 | static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg) |
1161 | { | 1285 | { |
1162 | iowrite32(val, ah->ah_iobase + reg); | 1286 | iowrite32(val, ah->ah_iobase + reg); |
1163 | } | 1287 | } |
1164 | 1288 | ||
1289 | #if defined(_ATH5K_RESET) || defined(_ATH5K_PHY) | ||
1290 | /* | ||
1291 | * Check if a register write has been completed | ||
1292 | */ | ||
1293 | static int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, | ||
1294 | u32 val, bool is_set) | ||
1295 | { | ||
1296 | int i; | ||
1297 | u32 data; | ||
1298 | |||
1299 | for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { | ||
1300 | data = ath5k_hw_reg_read(ah, reg); | ||
1301 | if (is_set && (data & flag)) | ||
1302 | break; | ||
1303 | else if ((data & flag) == val) | ||
1304 | break; | ||
1305 | udelay(15); | ||
1306 | } | ||
1307 | |||
1308 | return (i <= 0) ? -EAGAIN : 0; | ||
1309 | } | ||
1310 | #endif | ||
1311 | |||
1312 | static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) | ||
1313 | { | ||
1314 | u32 retval = 0, bit, i; | ||
1315 | |||
1316 | for (i = 0; i < bits; i++) { | ||
1317 | bit = (val >> i) & 1; | ||
1318 | retval = (retval << 1) | bit; | ||
1319 | } | ||
1320 | |||
1321 | return retval; | ||
1322 | } | ||
1323 | |||
1165 | #endif | 1324 | #endif |
diff --git a/drivers/net/wireless/ath5k/attach.c b/drivers/net/wireless/ath5k/attach.c new file mode 100644 index 000000000000..51d569883cdd --- /dev/null +++ b/drivers/net/wireless/ath5k/attach.c | |||
@@ -0,0 +1,359 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | /*************************************\ | ||
20 | * Attach/Detach Functions and helpers * | ||
21 | \*************************************/ | ||
22 | |||
23 | #include <linux/pci.h> | ||
24 | #include "ath5k.h" | ||
25 | #include "reg.h" | ||
26 | #include "debug.h" | ||
27 | #include "base.h" | ||
28 | |||
29 | /** | ||
30 | * ath5k_hw_post - Power On Self Test helper function | ||
31 | * | ||
32 | * @ah: The &struct ath5k_hw | ||
33 | */ | ||
34 | static int ath5k_hw_post(struct ath5k_hw *ah) | ||
35 | { | ||
36 | |||
37 | int i, c; | ||
38 | u16 cur_reg; | ||
39 | u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)}; | ||
40 | u32 var_pattern; | ||
41 | u32 static_pattern[4] = { | ||
42 | 0x55555555, 0xaaaaaaaa, | ||
43 | 0x66666666, 0x99999999 | ||
44 | }; | ||
45 | u32 init_val; | ||
46 | u32 cur_val; | ||
47 | |||
48 | for (c = 0; c < 2; c++) { | ||
49 | |||
50 | cur_reg = regs[c]; | ||
51 | |||
52 | /* Save previous value */ | ||
53 | init_val = ath5k_hw_reg_read(ah, cur_reg); | ||
54 | |||
55 | for (i = 0; i < 256; i++) { | ||
56 | var_pattern = i << 16 | i; | ||
57 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); | ||
58 | cur_val = ath5k_hw_reg_read(ah, cur_reg); | ||
59 | |||
60 | if (cur_val != var_pattern) { | ||
61 | ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n"); | ||
62 | return -EAGAIN; | ||
63 | } | ||
64 | |||
65 | /* Found on ndiswrapper dumps */ | ||
66 | var_pattern = 0x0039080f; | ||
67 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); | ||
68 | } | ||
69 | |||
70 | for (i = 0; i < 4; i++) { | ||
71 | var_pattern = static_pattern[i]; | ||
72 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); | ||
73 | cur_val = ath5k_hw_reg_read(ah, cur_reg); | ||
74 | |||
75 | if (cur_val != var_pattern) { | ||
76 | ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n"); | ||
77 | return -EAGAIN; | ||
78 | } | ||
79 | |||
80 | /* Found on ndiswrapper dumps */ | ||
81 | var_pattern = 0x003b080f; | ||
82 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); | ||
83 | } | ||
84 | |||
85 | /* Restore previous value */ | ||
86 | ath5k_hw_reg_write(ah, init_val, cur_reg); | ||
87 | |||
88 | } | ||
89 | |||
90 | return 0; | ||
91 | |||
92 | } | ||
93 | |||
94 | /** | ||
95 | * ath5k_hw_attach - Check if hw is supported and init the needed structs | ||
96 | * | ||
97 | * @sc: The &struct ath5k_softc we got from the driver's attach function | ||
98 | * @mac_version: The mac version id (check out ath5k.h) based on pci id | ||
99 | * | ||
100 | * Check if the device is supported, perform a POST and initialize the needed | ||
101 | * structs. Returns -ENOMEM if we don't have memory for the needed structs, | ||
102 | * -ENODEV if the device is not supported or prints an error msg if something | ||
103 | * else went wrong. | ||
104 | */ | ||
105 | struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | ||
106 | { | ||
107 | struct ath5k_hw *ah; | ||
108 | struct pci_dev *pdev = sc->pdev; | ||
109 | u8 mac[ETH_ALEN]; | ||
110 | int ret; | ||
111 | u32 srev; | ||
112 | |||
113 | /*If we passed the test malloc a ath5k_hw struct*/ | ||
114 | ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); | ||
115 | if (ah == NULL) { | ||
116 | ret = -ENOMEM; | ||
117 | ATH5K_ERR(sc, "out of memory\n"); | ||
118 | goto err; | ||
119 | } | ||
120 | |||
121 | ah->ah_sc = sc; | ||
122 | ah->ah_iobase = sc->iobase; | ||
123 | |||
124 | /* | ||
125 | * HW information | ||
126 | */ | ||
127 | ah->ah_op_mode = NL80211_IFTYPE_STATION; | ||
128 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; | ||
129 | ah->ah_turbo = false; | ||
130 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | ||
131 | ah->ah_imr = 0; | ||
132 | ah->ah_atim_window = 0; | ||
133 | ah->ah_aifs = AR5K_TUNE_AIFS; | ||
134 | ah->ah_cw_min = AR5K_TUNE_CWMIN; | ||
135 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; | ||
136 | ah->ah_software_retry = false; | ||
137 | ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY; | ||
138 | |||
139 | /* | ||
140 | * Set the mac version based on the pci id | ||
141 | */ | ||
142 | ah->ah_version = mac_version; | ||
143 | |||
144 | /*Fill the ath5k_hw struct with the needed functions*/ | ||
145 | ret = ath5k_hw_init_desc_functions(ah); | ||
146 | if (ret) | ||
147 | goto err_free; | ||
148 | |||
149 | /* Bring device out of sleep and reset it's units */ | ||
150 | ret = ath5k_hw_nic_wakeup(ah, CHANNEL_B, true); | ||
151 | if (ret) | ||
152 | goto err_free; | ||
153 | |||
154 | /* Get MAC, PHY and RADIO revisions */ | ||
155 | srev = ath5k_hw_reg_read(ah, AR5K_SREV); | ||
156 | ah->ah_mac_srev = srev; | ||
157 | ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); | ||
158 | ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV); | ||
159 | ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & | ||
160 | 0xffffffff; | ||
161 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, | ||
162 | CHANNEL_5GHZ); | ||
163 | ah->ah_phy = AR5K_PHY(0); | ||
164 | |||
165 | /* Try to identify radio chip based on it's srev */ | ||
166 | switch (ah->ah_radio_5ghz_revision & 0xf0) { | ||
167 | case AR5K_SREV_RAD_5111: | ||
168 | ah->ah_radio = AR5K_RF5111; | ||
169 | ah->ah_single_chip = false; | ||
170 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | ||
171 | CHANNEL_2GHZ); | ||
172 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111; | ||
173 | break; | ||
174 | case AR5K_SREV_RAD_5112: | ||
175 | case AR5K_SREV_RAD_2112: | ||
176 | ah->ah_radio = AR5K_RF5112; | ||
177 | ah->ah_single_chip = false; | ||
178 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | ||
179 | CHANNEL_2GHZ); | ||
180 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; | ||
181 | break; | ||
182 | case AR5K_SREV_RAD_2413: | ||
183 | ah->ah_radio = AR5K_RF2413; | ||
184 | ah->ah_single_chip = true; | ||
185 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; | ||
186 | break; | ||
187 | case AR5K_SREV_RAD_5413: | ||
188 | ah->ah_radio = AR5K_RF5413; | ||
189 | ah->ah_single_chip = true; | ||
190 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | ||
191 | break; | ||
192 | case AR5K_SREV_RAD_2316: | ||
193 | ah->ah_radio = AR5K_RF2316; | ||
194 | ah->ah_single_chip = true; | ||
195 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316; | ||
196 | break; | ||
197 | case AR5K_SREV_RAD_2317: | ||
198 | ah->ah_radio = AR5K_RF2317; | ||
199 | ah->ah_single_chip = true; | ||
200 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2317; | ||
201 | break; | ||
202 | case AR5K_SREV_RAD_5424: | ||
203 | if (ah->ah_mac_version == AR5K_SREV_AR2425 || | ||
204 | ah->ah_mac_version == AR5K_SREV_AR2417){ | ||
205 | ah->ah_radio = AR5K_RF2425; | ||
206 | ah->ah_single_chip = true; | ||
207 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; | ||
208 | } else { | ||
209 | ah->ah_radio = AR5K_RF5413; | ||
210 | ah->ah_single_chip = true; | ||
211 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | ||
212 | } | ||
213 | break; | ||
214 | default: | ||
215 | /* Identify radio based on mac/phy srev */ | ||
216 | if (ah->ah_version == AR5K_AR5210) { | ||
217 | ah->ah_radio = AR5K_RF5110; | ||
218 | ah->ah_single_chip = false; | ||
219 | } else if (ah->ah_version == AR5K_AR5211) { | ||
220 | ah->ah_radio = AR5K_RF5111; | ||
221 | ah->ah_single_chip = false; | ||
222 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | ||
223 | CHANNEL_2GHZ); | ||
224 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2425 >> 4) || | ||
225 | ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4) || | ||
226 | ah->ah_phy_revision == AR5K_SREV_PHY_2425) { | ||
227 | ah->ah_radio = AR5K_RF2425; | ||
228 | ah->ah_single_chip = true; | ||
229 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2425; | ||
230 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; | ||
231 | } else if (srev == AR5K_SREV_AR5213A && | ||
232 | ah->ah_phy_revision == AR5K_SREV_PHY_2112B) { | ||
233 | ah->ah_radio = AR5K_RF5112; | ||
234 | ah->ah_single_chip = false; | ||
235 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2112B; | ||
236 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2415 >> 4)) { | ||
237 | ah->ah_radio = AR5K_RF2316; | ||
238 | ah->ah_single_chip = true; | ||
239 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2316; | ||
240 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2316; | ||
241 | } else if (ah->ah_mac_version == (AR5K_SREV_AR5414 >> 4) || | ||
242 | ah->ah_phy_revision == AR5K_SREV_PHY_5413) { | ||
243 | ah->ah_radio = AR5K_RF5413; | ||
244 | ah->ah_single_chip = true; | ||
245 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_5413; | ||
246 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | ||
247 | } else if (ah->ah_mac_version == (AR5K_SREV_AR2414 >> 4) || | ||
248 | ah->ah_phy_revision == AR5K_SREV_PHY_2413) { | ||
249 | ah->ah_radio = AR5K_RF2413; | ||
250 | ah->ah_single_chip = true; | ||
251 | ah->ah_radio_5ghz_revision = AR5K_SREV_RAD_2413; | ||
252 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; | ||
253 | } else { | ||
254 | ATH5K_ERR(sc, "Couldn't identify radio revision.\n"); | ||
255 | ret = -ENODEV; | ||
256 | goto err_free; | ||
257 | } | ||
258 | } | ||
259 | |||
260 | |||
261 | /* Return on unsuported chips (unsupported eeprom etc) */ | ||
262 | if ((srev >= AR5K_SREV_AR5416) && | ||
263 | (srev < AR5K_SREV_AR2425)) { | ||
264 | ATH5K_ERR(sc, "Device not yet supported.\n"); | ||
265 | ret = -ENODEV; | ||
266 | goto err_free; | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * Write PCI-E power save settings | ||
271 | */ | ||
272 | if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { | ||
273 | ath5k_hw_reg_write(ah, 0x9248fc00, AR5K_PCIE_SERDES); | ||
274 | ath5k_hw_reg_write(ah, 0x24924924, AR5K_PCIE_SERDES); | ||
275 | /* Shut off RX when elecidle is asserted */ | ||
276 | ath5k_hw_reg_write(ah, 0x28000039, AR5K_PCIE_SERDES); | ||
277 | ath5k_hw_reg_write(ah, 0x53160824, AR5K_PCIE_SERDES); | ||
278 | /* TODO: EEPROM work */ | ||
279 | ath5k_hw_reg_write(ah, 0xe5980579, AR5K_PCIE_SERDES); | ||
280 | /* Shut off PLL and CLKREQ active in L1 */ | ||
281 | ath5k_hw_reg_write(ah, 0x001defff, AR5K_PCIE_SERDES); | ||
282 | /* Preserce other settings */ | ||
283 | ath5k_hw_reg_write(ah, 0x1aaabe40, AR5K_PCIE_SERDES); | ||
284 | ath5k_hw_reg_write(ah, 0xbe105554, AR5K_PCIE_SERDES); | ||
285 | ath5k_hw_reg_write(ah, 0x000e3007, AR5K_PCIE_SERDES); | ||
286 | /* Reset SERDES to load new settings */ | ||
287 | ath5k_hw_reg_write(ah, 0x00000000, AR5K_PCIE_SERDES_RESET); | ||
288 | mdelay(1); | ||
289 | } | ||
290 | |||
291 | /* | ||
292 | * POST | ||
293 | */ | ||
294 | ret = ath5k_hw_post(ah); | ||
295 | if (ret) | ||
296 | goto err_free; | ||
297 | |||
298 | /* Enable pci core retry fix on Hainan (5213A) and later chips */ | ||
299 | if (srev >= AR5K_SREV_AR5213A) | ||
300 | ath5k_hw_reg_write(ah, AR5K_PCICFG_RETRY_FIX, AR5K_PCICFG); | ||
301 | |||
302 | /* | ||
303 | * Get card capabilities, calibration values etc | ||
304 | * TODO: EEPROM work | ||
305 | */ | ||
306 | ret = ath5k_eeprom_init(ah); | ||
307 | if (ret) { | ||
308 | ATH5K_ERR(sc, "unable to init EEPROM\n"); | ||
309 | goto err_free; | ||
310 | } | ||
311 | |||
312 | /* Get misc capabilities */ | ||
313 | ret = ath5k_hw_set_capabilities(ah); | ||
314 | if (ret) { | ||
315 | ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n", | ||
316 | sc->pdev->device); | ||
317 | goto err_free; | ||
318 | } | ||
319 | |||
320 | /* Set MAC address */ | ||
321 | ret = ath5k_eeprom_read_mac(ah, mac); | ||
322 | if (ret) { | ||
323 | ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", | ||
324 | sc->pdev->device); | ||
325 | goto err_free; | ||
326 | } | ||
327 | |||
328 | ath5k_hw_set_lladdr(ah, mac); | ||
329 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ | ||
330 | memset(ah->ah_bssid, 0xff, ETH_ALEN); | ||
331 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); | ||
332 | ath5k_hw_set_opmode(ah); | ||
333 | |||
334 | ath5k_hw_set_rfgain_opt(ah); | ||
335 | |||
336 | return ah; | ||
337 | err_free: | ||
338 | kfree(ah); | ||
339 | err: | ||
340 | return ERR_PTR(ret); | ||
341 | } | ||
342 | |||
343 | /** | ||
344 | * ath5k_hw_detach - Free the ath5k_hw struct | ||
345 | * | ||
346 | * @ah: The &struct ath5k_hw | ||
347 | */ | ||
348 | void ath5k_hw_detach(struct ath5k_hw *ah) | ||
349 | { | ||
350 | ATH5K_TRACE(ah->ah_sc); | ||
351 | |||
352 | __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); | ||
353 | |||
354 | if (ah->ah_rf_banks != NULL) | ||
355 | kfree(ah->ah_rf_banks); | ||
356 | |||
357 | /* assume interrupts are down */ | ||
358 | kfree(ah); | ||
359 | } | ||
diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 0676c6d84383..9b95c4049b31 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c | |||
@@ -72,7 +72,7 @@ MODULE_AUTHOR("Nick Kossifidis"); | |||
72 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); | 72 | MODULE_DESCRIPTION("Support for 5xxx series of Atheros 802.11 wireless LAN cards."); |
73 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); | 73 | MODULE_SUPPORTED_DEVICE("Atheros 5xxx WLAN cards"); |
74 | MODULE_LICENSE("Dual BSD/GPL"); | 74 | MODULE_LICENSE("Dual BSD/GPL"); |
75 | MODULE_VERSION("0.5.0 (EXPERIMENTAL)"); | 75 | MODULE_VERSION("0.6.0 (EXPERIMENTAL)"); |
76 | 76 | ||
77 | 77 | ||
78 | /* Known PCI ids */ | 78 | /* Known PCI ids */ |
@@ -93,45 +93,94 @@ static struct pci_device_id ath5k_pci_id_table[] __devinitdata = { | |||
93 | { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */ | 93 | { PCI_VDEVICE(ATHEROS, 0x0019), .driver_data = AR5K_AR5212 }, /* 5212 combatible */ |
94 | { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */ | 94 | { PCI_VDEVICE(ATHEROS, 0x001a), .driver_data = AR5K_AR5212 }, /* 2413 Griffin-lite */ |
95 | { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */ | 95 | { PCI_VDEVICE(ATHEROS, 0x001b), .driver_data = AR5K_AR5212 }, /* 5413 Eagle */ |
96 | { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* 5424 Condor (PCI-E)*/ | 96 | { PCI_VDEVICE(ATHEROS, 0x001c), .driver_data = AR5K_AR5212 }, /* PCI-E cards */ |
97 | { PCI_VDEVICE(ATHEROS, 0x001d), .driver_data = AR5K_AR5212 }, /* 2417 Nala */ | ||
97 | { 0 } | 98 | { 0 } |
98 | }; | 99 | }; |
99 | MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); | 100 | MODULE_DEVICE_TABLE(pci, ath5k_pci_id_table); |
100 | 101 | ||
101 | /* Known SREVs */ | 102 | /* Known SREVs */ |
102 | static struct ath5k_srev_name srev_names[] = { | 103 | static struct ath5k_srev_name srev_names[] = { |
103 | { "5210", AR5K_VERSION_VER, AR5K_SREV_VER_AR5210 }, | 104 | { "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 }, |
104 | { "5311", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311 }, | 105 | { "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 }, |
105 | { "5311A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311A }, | 106 | { "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A }, |
106 | { "5311B", AR5K_VERSION_VER, AR5K_SREV_VER_AR5311B }, | 107 | { "5311B", AR5K_VERSION_MAC, AR5K_SREV_AR5311B }, |
107 | { "5211", AR5K_VERSION_VER, AR5K_SREV_VER_AR5211 }, | 108 | { "5211", AR5K_VERSION_MAC, AR5K_SREV_AR5211 }, |
108 | { "5212", AR5K_VERSION_VER, AR5K_SREV_VER_AR5212 }, | 109 | { "5212", AR5K_VERSION_MAC, AR5K_SREV_AR5212 }, |
109 | { "5213", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213 }, | 110 | { "5213", AR5K_VERSION_MAC, AR5K_SREV_AR5213 }, |
110 | { "5213A", AR5K_VERSION_VER, AR5K_SREV_VER_AR5213A }, | 111 | { "5213A", AR5K_VERSION_MAC, AR5K_SREV_AR5213A }, |
111 | { "2413", AR5K_VERSION_VER, AR5K_SREV_VER_AR2413 }, | 112 | { "2413", AR5K_VERSION_MAC, AR5K_SREV_AR2413 }, |
112 | { "2414", AR5K_VERSION_VER, AR5K_SREV_VER_AR2414 }, | 113 | { "2414", AR5K_VERSION_MAC, AR5K_SREV_AR2414 }, |
113 | { "2424", AR5K_VERSION_VER, AR5K_SREV_VER_AR2424 }, | 114 | { "5424", AR5K_VERSION_MAC, AR5K_SREV_AR5424 }, |
114 | { "5424", AR5K_VERSION_VER, AR5K_SREV_VER_AR5424 }, | 115 | { "5413", AR5K_VERSION_MAC, AR5K_SREV_AR5413 }, |
115 | { "5413", AR5K_VERSION_VER, AR5K_SREV_VER_AR5413 }, | 116 | { "5414", AR5K_VERSION_MAC, AR5K_SREV_AR5414 }, |
116 | { "5414", AR5K_VERSION_VER, AR5K_SREV_VER_AR5414 }, | 117 | { "2415", AR5K_VERSION_MAC, AR5K_SREV_AR2415 }, |
117 | { "5416", AR5K_VERSION_VER, AR5K_SREV_VER_AR5416 }, | 118 | { "5416", AR5K_VERSION_MAC, AR5K_SREV_AR5416 }, |
118 | { "5418", AR5K_VERSION_VER, AR5K_SREV_VER_AR5418 }, | 119 | { "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 }, |
119 | { "2425", AR5K_VERSION_VER, AR5K_SREV_VER_AR2425 }, | 120 | { "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 }, |
120 | { "xxxxx", AR5K_VERSION_VER, AR5K_SREV_UNKNOWN }, | 121 | { "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 }, |
122 | { "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN }, | ||
121 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, | 123 | { "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 }, |
122 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, | 124 | { "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 }, |
125 | { "5111A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111A }, | ||
123 | { "2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111 }, | 126 | { "2111", AR5K_VERSION_RAD, AR5K_SREV_RAD_2111 }, |
124 | { "5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112 }, | 127 | { "5112", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112 }, |
125 | { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, | 128 | { "5112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112A }, |
129 | { "5112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_5112B }, | ||
126 | { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, | 130 | { "2112", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112 }, |
127 | { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, | 131 | { "2112A", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112A }, |
128 | { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC0 }, | 132 | { "2112B", AR5K_VERSION_RAD, AR5K_SREV_RAD_2112B }, |
129 | { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC1 }, | 133 | { "2413", AR5K_VERSION_RAD, AR5K_SREV_RAD_2413 }, |
130 | { "SChip", AR5K_VERSION_RAD, AR5K_SREV_RAD_SC2 }, | 134 | { "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 }, |
135 | { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 }, | ||
136 | { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 }, | ||
137 | { "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 }, | ||
131 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, | 138 | { "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 }, |
132 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, | 139 | { "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN }, |
133 | }; | 140 | }; |
134 | 141 | ||
142 | static struct ieee80211_rate ath5k_rates[] = { | ||
143 | { .bitrate = 10, | ||
144 | .hw_value = ATH5K_RATE_CODE_1M, }, | ||
145 | { .bitrate = 20, | ||
146 | .hw_value = ATH5K_RATE_CODE_2M, | ||
147 | .hw_value_short = ATH5K_RATE_CODE_2M | AR5K_SET_SHORT_PREAMBLE, | ||
148 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
149 | { .bitrate = 55, | ||
150 | .hw_value = ATH5K_RATE_CODE_5_5M, | ||
151 | .hw_value_short = ATH5K_RATE_CODE_5_5M | AR5K_SET_SHORT_PREAMBLE, | ||
152 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
153 | { .bitrate = 110, | ||
154 | .hw_value = ATH5K_RATE_CODE_11M, | ||
155 | .hw_value_short = ATH5K_RATE_CODE_11M | AR5K_SET_SHORT_PREAMBLE, | ||
156 | .flags = IEEE80211_RATE_SHORT_PREAMBLE }, | ||
157 | { .bitrate = 60, | ||
158 | .hw_value = ATH5K_RATE_CODE_6M, | ||
159 | .flags = 0 }, | ||
160 | { .bitrate = 90, | ||
161 | .hw_value = ATH5K_RATE_CODE_9M, | ||
162 | .flags = 0 }, | ||
163 | { .bitrate = 120, | ||
164 | .hw_value = ATH5K_RATE_CODE_12M, | ||
165 | .flags = 0 }, | ||
166 | { .bitrate = 180, | ||
167 | .hw_value = ATH5K_RATE_CODE_18M, | ||
168 | .flags = 0 }, | ||
169 | { .bitrate = 240, | ||
170 | .hw_value = ATH5K_RATE_CODE_24M, | ||
171 | .flags = 0 }, | ||
172 | { .bitrate = 360, | ||
173 | .hw_value = ATH5K_RATE_CODE_36M, | ||
174 | .flags = 0 }, | ||
175 | { .bitrate = 480, | ||
176 | .hw_value = ATH5K_RATE_CODE_48M, | ||
177 | .flags = 0 }, | ||
178 | { .bitrate = 540, | ||
179 | .hw_value = ATH5K_RATE_CODE_54M, | ||
180 | .flags = 0 }, | ||
181 | /* XR missing */ | ||
182 | }; | ||
183 | |||
135 | /* | 184 | /* |
136 | * Prototypes - PCI stack related functions | 185 | * Prototypes - PCI stack related functions |
137 | */ | 186 | */ |
@@ -162,7 +211,8 @@ static struct pci_driver ath5k_pci_driver = { | |||
162 | * Prototypes - MAC 802.11 stack related functions | 211 | * Prototypes - MAC 802.11 stack related functions |
163 | */ | 212 | */ |
164 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); | 213 | static int ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb); |
165 | static int ath5k_reset(struct ieee80211_hw *hw); | 214 | static int ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel); |
215 | static int ath5k_reset_wake(struct ath5k_softc *sc); | ||
166 | static int ath5k_start(struct ieee80211_hw *hw); | 216 | static int ath5k_start(struct ieee80211_hw *hw); |
167 | static void ath5k_stop(struct ieee80211_hw *hw); | 217 | static void ath5k_stop(struct ieee80211_hw *hw); |
168 | static int ath5k_add_interface(struct ieee80211_hw *hw, | 218 | static int ath5k_add_interface(struct ieee80211_hw *hw, |
@@ -218,20 +268,16 @@ static void ath5k_detach(struct pci_dev *pdev, | |||
218 | struct ieee80211_hw *hw); | 268 | struct ieee80211_hw *hw); |
219 | /* Channel/mode setup */ | 269 | /* Channel/mode setup */ |
220 | static inline short ath5k_ieee2mhz(short chan); | 270 | static inline short ath5k_ieee2mhz(short chan); |
221 | static unsigned int ath5k_copy_rates(struct ieee80211_rate *rates, | ||
222 | const struct ath5k_rate_table *rt, | ||
223 | unsigned int max); | ||
224 | static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, | 271 | static unsigned int ath5k_copy_channels(struct ath5k_hw *ah, |
225 | struct ieee80211_channel *channels, | 272 | struct ieee80211_channel *channels, |
226 | unsigned int mode, | 273 | unsigned int mode, |
227 | unsigned int max); | 274 | unsigned int max); |
228 | static int ath5k_getchannels(struct ieee80211_hw *hw); | 275 | static int ath5k_setup_bands(struct ieee80211_hw *hw); |
229 | static int ath5k_chan_set(struct ath5k_softc *sc, | 276 | static int ath5k_chan_set(struct ath5k_softc *sc, |
230 | struct ieee80211_channel *chan); | 277 | struct ieee80211_channel *chan); |
231 | static void ath5k_setcurmode(struct ath5k_softc *sc, | 278 | static void ath5k_setcurmode(struct ath5k_softc *sc, |
232 | unsigned int mode); | 279 | unsigned int mode); |
233 | static void ath5k_mode_setup(struct ath5k_softc *sc); | 280 | static void ath5k_mode_setup(struct ath5k_softc *sc); |
234 | static void ath5k_set_total_hw_rates(struct ath5k_softc *sc); | ||
235 | 281 | ||
236 | /* Descriptor setup */ | 282 | /* Descriptor setup */ |
237 | static int ath5k_desc_alloc(struct ath5k_softc *sc, | 283 | static int ath5k_desc_alloc(struct ath5k_softc *sc, |
@@ -351,7 +397,11 @@ ath5k_chip_name(enum ath5k_srev_type type, u_int16_t val) | |||
351 | for (i = 0; i < ARRAY_SIZE(srev_names); i++) { | 397 | for (i = 0; i < ARRAY_SIZE(srev_names); i++) { |
352 | if (srev_names[i].sr_type != type) | 398 | if (srev_names[i].sr_type != type) |
353 | continue; | 399 | continue; |
354 | if ((val & 0xff) < srev_names[i + 1].sr_val) { | 400 | |
401 | if ((val & 0xf0) == srev_names[i].sr_val) | ||
402 | name = srev_names[i].sr_name; | ||
403 | |||
404 | if ((val & 0xff) == srev_names[i].sr_val) { | ||
355 | name = srev_names[i].sr_name; | 405 | name = srev_names[i].sr_name; |
356 | break; | 406 | break; |
357 | } | 407 | } |
@@ -446,6 +496,12 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
446 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | | 496 | hw->flags = IEEE80211_HW_RX_INCLUDES_FCS | |
447 | IEEE80211_HW_SIGNAL_DBM | | 497 | IEEE80211_HW_SIGNAL_DBM | |
448 | IEEE80211_HW_NOISE_DBM; | 498 | IEEE80211_HW_NOISE_DBM; |
499 | |||
500 | hw->wiphy->interface_modes = | ||
501 | BIT(NL80211_IFTYPE_STATION) | | ||
502 | BIT(NL80211_IFTYPE_ADHOC) | | ||
503 | BIT(NL80211_IFTYPE_MESH_POINT); | ||
504 | |||
449 | hw->extra_tx_headroom = 2; | 505 | hw->extra_tx_headroom = 2; |
450 | hw->channel_change_time = 5000; | 506 | hw->channel_change_time = 5000; |
451 | sc = hw->priv; | 507 | sc = hw->priv; |
@@ -462,7 +518,7 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
462 | 518 | ||
463 | sc->iobase = mem; /* So we can unmap it on detach */ | 519 | sc->iobase = mem; /* So we can unmap it on detach */ |
464 | sc->cachelsz = csz * sizeof(u32); /* convert to bytes */ | 520 | sc->cachelsz = csz * sizeof(u32); /* convert to bytes */ |
465 | sc->opmode = IEEE80211_IF_TYPE_STA; | 521 | sc->opmode = NL80211_IFTYPE_STATION; |
466 | mutex_init(&sc->lock); | 522 | mutex_init(&sc->lock); |
467 | spin_lock_init(&sc->rxbuflock); | 523 | spin_lock_init(&sc->rxbuflock); |
468 | spin_lock_init(&sc->txbuflock); | 524 | spin_lock_init(&sc->txbuflock); |
@@ -485,13 +541,19 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
485 | goto err_irq; | 541 | goto err_irq; |
486 | } | 542 | } |
487 | 543 | ||
544 | /* set up multi-rate retry capabilities */ | ||
545 | if (sc->ah->ah_version == AR5K_AR5212) { | ||
546 | hw->max_altrates = 3; | ||
547 | hw->max_altrate_tries = 11; | ||
548 | } | ||
549 | |||
488 | /* Finish private driver data initialization */ | 550 | /* Finish private driver data initialization */ |
489 | ret = ath5k_attach(pdev, hw); | 551 | ret = ath5k_attach(pdev, hw); |
490 | if (ret) | 552 | if (ret) |
491 | goto err_ah; | 553 | goto err_ah; |
492 | 554 | ||
493 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", | 555 | ATH5K_INFO(sc, "Atheros AR%s chip found (MAC: 0x%x, PHY: 0x%x)\n", |
494 | ath5k_chip_name(AR5K_VERSION_VER,sc->ah->ah_mac_srev), | 556 | ath5k_chip_name(AR5K_VERSION_MAC, sc->ah->ah_mac_srev), |
495 | sc->ah->ah_mac_srev, | 557 | sc->ah->ah_mac_srev, |
496 | sc->ah->ah_phy_revision); | 558 | sc->ah->ah_phy_revision); |
497 | 559 | ||
@@ -646,7 +708,6 @@ err_no_irq: | |||
646 | #endif /* CONFIG_PM */ | 708 | #endif /* CONFIG_PM */ |
647 | 709 | ||
648 | 710 | ||
649 | |||
650 | /***********************\ | 711 | /***********************\ |
651 | * Driver Initialization * | 712 | * Driver Initialization * |
652 | \***********************/ | 713 | \***********************/ |
@@ -669,7 +730,7 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
669 | * return false w/o doing anything. MAC's that do | 730 | * return false w/o doing anything. MAC's that do |
670 | * support it will return true w/o doing anything. | 731 | * support it will return true w/o doing anything. |
671 | */ | 732 | */ |
672 | ret = ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); | 733 | ret = ah->ah_setup_mrr_tx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); |
673 | if (ret < 0) | 734 | if (ret < 0) |
674 | goto err; | 735 | goto err; |
675 | if (ret > 0) | 736 | if (ret > 0) |
@@ -688,15 +749,12 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) | |||
688 | * on settings like the phy mode and regulatory | 749 | * on settings like the phy mode and regulatory |
689 | * domain restrictions. | 750 | * domain restrictions. |
690 | */ | 751 | */ |
691 | ret = ath5k_getchannels(hw); | 752 | ret = ath5k_setup_bands(hw); |
692 | if (ret) { | 753 | if (ret) { |
693 | ATH5K_ERR(sc, "can't get channels\n"); | 754 | ATH5K_ERR(sc, "can't get channels\n"); |
694 | goto err; | 755 | goto err; |
695 | } | 756 | } |
696 | 757 | ||
697 | /* Set *_rates so we can map hw rate index */ | ||
698 | ath5k_set_total_hw_rates(sc); | ||
699 | |||
700 | /* NB: setup here so ath5k_rate_update is happy */ | 758 | /* NB: setup here so ath5k_rate_update is happy */ |
701 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) | 759 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) |
702 | ath5k_setcurmode(sc, AR5K_MODE_11A); | 760 | ath5k_setcurmode(sc, AR5K_MODE_11A); |
@@ -813,27 +871,6 @@ ath5k_ieee2mhz(short chan) | |||
813 | } | 871 | } |
814 | 872 | ||
815 | static unsigned int | 873 | static unsigned int |
816 | ath5k_copy_rates(struct ieee80211_rate *rates, | ||
817 | const struct ath5k_rate_table *rt, | ||
818 | unsigned int max) | ||
819 | { | ||
820 | unsigned int i, count; | ||
821 | |||
822 | if (rt == NULL) | ||
823 | return 0; | ||
824 | |||
825 | for (i = 0, count = 0; i < rt->rate_count && max > 0; i++) { | ||
826 | rates[count].bitrate = rt->rates[i].rate_kbps / 100; | ||
827 | rates[count].hw_value = rt->rates[i].rate_code; | ||
828 | rates[count].flags = rt->rates[i].modulation; | ||
829 | count++; | ||
830 | max--; | ||
831 | } | ||
832 | |||
833 | return count; | ||
834 | } | ||
835 | |||
836 | static unsigned int | ||
837 | ath5k_copy_channels(struct ath5k_hw *ah, | 874 | ath5k_copy_channels(struct ath5k_hw *ah, |
838 | struct ieee80211_channel *channels, | 875 | struct ieee80211_channel *channels, |
839 | unsigned int mode, | 876 | unsigned int mode, |
@@ -895,74 +932,97 @@ ath5k_copy_channels(struct ath5k_hw *ah, | |||
895 | return count; | 932 | return count; |
896 | } | 933 | } |
897 | 934 | ||
935 | static void | ||
936 | ath5k_setup_rate_idx(struct ath5k_softc *sc, struct ieee80211_supported_band *b) | ||
937 | { | ||
938 | u8 i; | ||
939 | |||
940 | for (i = 0; i < AR5K_MAX_RATES; i++) | ||
941 | sc->rate_idx[b->band][i] = -1; | ||
942 | |||
943 | for (i = 0; i < b->n_bitrates; i++) { | ||
944 | sc->rate_idx[b->band][b->bitrates[i].hw_value] = i; | ||
945 | if (b->bitrates[i].hw_value_short) | ||
946 | sc->rate_idx[b->band][b->bitrates[i].hw_value_short] = i; | ||
947 | } | ||
948 | } | ||
949 | |||
898 | static int | 950 | static int |
899 | ath5k_getchannels(struct ieee80211_hw *hw) | 951 | ath5k_setup_bands(struct ieee80211_hw *hw) |
900 | { | 952 | { |
901 | struct ath5k_softc *sc = hw->priv; | 953 | struct ath5k_softc *sc = hw->priv; |
902 | struct ath5k_hw *ah = sc->ah; | 954 | struct ath5k_hw *ah = sc->ah; |
903 | struct ieee80211_supported_band *sbands = sc->sbands; | 955 | struct ieee80211_supported_band *sband; |
904 | const struct ath5k_rate_table *hw_rates; | 956 | int max_c, count_c = 0; |
905 | unsigned int max_r, max_c, count_r, count_c; | 957 | int i; |
906 | int mode2g = AR5K_MODE_11G; | ||
907 | 958 | ||
908 | BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); | 959 | BUILD_BUG_ON(ARRAY_SIZE(sc->sbands) < IEEE80211_NUM_BANDS); |
909 | |||
910 | max_r = ARRAY_SIZE(sc->rates); | ||
911 | max_c = ARRAY_SIZE(sc->channels); | 960 | max_c = ARRAY_SIZE(sc->channels); |
912 | count_r = count_c = 0; | ||
913 | 961 | ||
914 | /* 2GHz band */ | 962 | /* 2GHz band */ |
915 | if (!test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { | 963 | sband = &sc->sbands[IEEE80211_BAND_2GHZ]; |
916 | mode2g = AR5K_MODE_11B; | 964 | sband->band = IEEE80211_BAND_2GHZ; |
917 | if (!test_bit(AR5K_MODE_11B, | 965 | sband->bitrates = &sc->rates[IEEE80211_BAND_2GHZ][0]; |
918 | sc->ah->ah_capabilities.cap_mode)) | ||
919 | mode2g = -1; | ||
920 | } | ||
921 | 966 | ||
922 | if (mode2g > 0) { | 967 | if (test_bit(AR5K_MODE_11G, sc->ah->ah_capabilities.cap_mode)) { |
923 | struct ieee80211_supported_band *sband = | 968 | /* G mode */ |
924 | &sbands[IEEE80211_BAND_2GHZ]; | 969 | memcpy(sband->bitrates, &ath5k_rates[0], |
970 | sizeof(struct ieee80211_rate) * 12); | ||
971 | sband->n_bitrates = 12; | ||
925 | 972 | ||
926 | sband->bitrates = sc->rates; | ||
927 | sband->channels = sc->channels; | 973 | sband->channels = sc->channels; |
928 | |||
929 | sband->band = IEEE80211_BAND_2GHZ; | ||
930 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | 974 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, |
931 | mode2g, max_c); | 975 | AR5K_MODE_11G, max_c); |
932 | |||
933 | hw_rates = ath5k_hw_get_rate_table(ah, mode2g); | ||
934 | sband->n_bitrates = ath5k_copy_rates(sband->bitrates, | ||
935 | hw_rates, max_r); | ||
936 | 976 | ||
977 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | ||
937 | count_c = sband->n_channels; | 978 | count_c = sband->n_channels; |
938 | count_r = sband->n_bitrates; | 979 | max_c -= count_c; |
980 | } else if (test_bit(AR5K_MODE_11B, sc->ah->ah_capabilities.cap_mode)) { | ||
981 | /* B mode */ | ||
982 | memcpy(sband->bitrates, &ath5k_rates[0], | ||
983 | sizeof(struct ieee80211_rate) * 4); | ||
984 | sband->n_bitrates = 4; | ||
985 | |||
986 | /* 5211 only supports B rates and uses 4bit rate codes | ||
987 | * (e.g normally we have 0x1B for 1M, but on 5211 we have 0x0B) | ||
988 | * fix them up here: | ||
989 | */ | ||
990 | if (ah->ah_version == AR5K_AR5211) { | ||
991 | for (i = 0; i < 4; i++) { | ||
992 | sband->bitrates[i].hw_value = | ||
993 | sband->bitrates[i].hw_value & 0xF; | ||
994 | sband->bitrates[i].hw_value_short = | ||
995 | sband->bitrates[i].hw_value_short & 0xF; | ||
996 | } | ||
997 | } | ||
939 | 998 | ||
940 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; | 999 | sband->channels = sc->channels; |
1000 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | ||
1001 | AR5K_MODE_11B, max_c); | ||
941 | 1002 | ||
942 | max_r -= count_r; | 1003 | hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband; |
1004 | count_c = sband->n_channels; | ||
943 | max_c -= count_c; | 1005 | max_c -= count_c; |
944 | |||
945 | } | 1006 | } |
1007 | ath5k_setup_rate_idx(sc, sband); | ||
946 | 1008 | ||
947 | /* 5GHz band */ | 1009 | /* 5GHz band, A mode */ |
948 | |||
949 | if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { | 1010 | if (test_bit(AR5K_MODE_11A, sc->ah->ah_capabilities.cap_mode)) { |
950 | struct ieee80211_supported_band *sband = | 1011 | sband = &sc->sbands[IEEE80211_BAND_5GHZ]; |
951 | &sbands[IEEE80211_BAND_5GHZ]; | 1012 | sband->band = IEEE80211_BAND_5GHZ; |
1013 | sband->bitrates = &sc->rates[IEEE80211_BAND_5GHZ][0]; | ||
952 | 1014 | ||
953 | sband->bitrates = &sc->rates[count_r]; | 1015 | memcpy(sband->bitrates, &ath5k_rates[4], |
954 | sband->channels = &sc->channels[count_c]; | 1016 | sizeof(struct ieee80211_rate) * 8); |
1017 | sband->n_bitrates = 8; | ||
955 | 1018 | ||
956 | sband->band = IEEE80211_BAND_5GHZ; | 1019 | sband->channels = &sc->channels[count_c]; |
957 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, | 1020 | sband->n_channels = ath5k_copy_channels(ah, sband->channels, |
958 | AR5K_MODE_11A, max_c); | 1021 | AR5K_MODE_11A, max_c); |
959 | 1022 | ||
960 | hw_rates = ath5k_hw_get_rate_table(ah, AR5K_MODE_11A); | ||
961 | sband->n_bitrates = ath5k_copy_rates(sband->bitrates, | ||
962 | hw_rates, max_r); | ||
963 | |||
964 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; | 1023 | hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband; |
965 | } | 1024 | } |
1025 | ath5k_setup_rate_idx(sc, sband); | ||
966 | 1026 | ||
967 | ath5k_debug_dump_bands(sc); | 1027 | ath5k_debug_dump_bands(sc); |
968 | 1028 | ||
@@ -978,9 +1038,6 @@ ath5k_getchannels(struct ieee80211_hw *hw) | |||
978 | static int | 1038 | static int |
979 | ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | 1039 | ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) |
980 | { | 1040 | { |
981 | struct ath5k_hw *ah = sc->ah; | ||
982 | int ret; | ||
983 | |||
984 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", | 1041 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "(%u MHz) -> (%u MHz)\n", |
985 | sc->curchan->center_freq, chan->center_freq); | 1042 | sc->curchan->center_freq, chan->center_freq); |
986 | 1043 | ||
@@ -996,41 +1053,7 @@ ath5k_chan_set(struct ath5k_softc *sc, struct ieee80211_channel *chan) | |||
996 | * hardware at the new frequency, and then re-enable | 1053 | * hardware at the new frequency, and then re-enable |
997 | * the relevant bits of the h/w. | 1054 | * the relevant bits of the h/w. |
998 | */ | 1055 | */ |
999 | ath5k_hw_set_intr(ah, 0); /* disable interrupts */ | 1056 | return ath5k_reset(sc, true, true); |
1000 | ath5k_txq_cleanup(sc); /* clear pending tx frames */ | ||
1001 | ath5k_rx_stop(sc); /* turn off frame recv */ | ||
1002 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); | ||
1003 | if (ret) { | ||
1004 | ATH5K_ERR(sc, "%s: unable to reset channel " | ||
1005 | "(%u Mhz)\n", __func__, chan->center_freq); | ||
1006 | return ret; | ||
1007 | } | ||
1008 | |||
1009 | ath5k_hw_set_txpower_limit(sc->ah, 0); | ||
1010 | |||
1011 | /* | ||
1012 | * Re-enable rx framework. | ||
1013 | */ | ||
1014 | ret = ath5k_rx_start(sc); | ||
1015 | if (ret) { | ||
1016 | ATH5K_ERR(sc, "%s: unable to restart recv logic\n", | ||
1017 | __func__); | ||
1018 | return ret; | ||
1019 | } | ||
1020 | |||
1021 | /* | ||
1022 | * Change channels and update the h/w rate map | ||
1023 | * if we're switching; e.g. 11a to 11b/g. | ||
1024 | * | ||
1025 | * XXX needed? | ||
1026 | */ | ||
1027 | /* ath5k_chan_change(sc, chan); */ | ||
1028 | |||
1029 | ath5k_beacon_config(sc); | ||
1030 | /* | ||
1031 | * Re-enable interrupts. | ||
1032 | */ | ||
1033 | ath5k_hw_set_intr(ah, sc->imask); | ||
1034 | } | 1057 | } |
1035 | 1058 | ||
1036 | return 0; | 1059 | return 0; |
@@ -1068,75 +1091,13 @@ ath5k_mode_setup(struct ath5k_softc *sc) | |||
1068 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); | 1091 | ATH5K_DBG(sc, ATH5K_DEBUG_MODE, "RX filter 0x%x\n", rfilt); |
1069 | } | 1092 | } |
1070 | 1093 | ||
1071 | /* | ||
1072 | * Match the hw provided rate index (through descriptors) | ||
1073 | * to an index for sc->curband->bitrates, so it can be used | ||
1074 | * by the stack. | ||
1075 | * | ||
1076 | * This one is a little bit tricky but i think i'm right | ||
1077 | * about this... | ||
1078 | * | ||
1079 | * We have 4 rate tables in the following order: | ||
1080 | * XR (4 rates) | ||
1081 | * 802.11a (8 rates) | ||
1082 | * 802.11b (4 rates) | ||
1083 | * 802.11g (12 rates) | ||
1084 | * that make the hw rate table. | ||
1085 | * | ||
1086 | * Lets take a 5211 for example that supports a and b modes only. | ||
1087 | * First comes the 802.11a table and then 802.11b (total 12 rates). | ||
1088 | * When hw returns eg. 11 it points to the last 802.11b rate (11Mbit), | ||
1089 | * if it returns 2 it points to the second 802.11a rate etc. | ||
1090 | * | ||
1091 | * Same goes for 5212 who has xr/a/b/g support (total 28 rates). | ||
1092 | * First comes the XR table, then 802.11a, 802.11b and 802.11g. | ||
1093 | * When hw returns eg. 27 it points to the last 802.11g rate (54Mbits) etc | ||
1094 | */ | ||
1095 | static void | ||
1096 | ath5k_set_total_hw_rates(struct ath5k_softc *sc) { | ||
1097 | |||
1098 | struct ath5k_hw *ah = sc->ah; | ||
1099 | |||
1100 | if (test_bit(AR5K_MODE_11A, ah->ah_modes)) | ||
1101 | sc->a_rates = 8; | ||
1102 | |||
1103 | if (test_bit(AR5K_MODE_11B, ah->ah_modes)) | ||
1104 | sc->b_rates = 4; | ||
1105 | |||
1106 | if (test_bit(AR5K_MODE_11G, ah->ah_modes)) | ||
1107 | sc->g_rates = 12; | ||
1108 | |||
1109 | /* XXX: Need to see what what happens when | ||
1110 | xr disable bits in eeprom are set */ | ||
1111 | if (ah->ah_version >= AR5K_AR5212) | ||
1112 | sc->xr_rates = 4; | ||
1113 | |||
1114 | } | ||
1115 | |||
1116 | static inline int | 1094 | static inline int |
1117 | ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) { | 1095 | ath5k_hw_to_driver_rix(struct ath5k_softc *sc, int hw_rix) |
1118 | 1096 | { | |
1119 | int mac80211_rix; | 1097 | WARN_ON(hw_rix < 0 || hw_rix > AR5K_MAX_RATES); |
1120 | 1098 | return sc->rate_idx[sc->curband->band][hw_rix]; | |
1121 | if(sc->curband->band == IEEE80211_BAND_2GHZ) { | ||
1122 | /* We setup a g ratetable for both b/g modes */ | ||
1123 | mac80211_rix = | ||
1124 | hw_rix - sc->b_rates - sc->a_rates - sc->xr_rates; | ||
1125 | } else { | ||
1126 | mac80211_rix = hw_rix - sc->xr_rates; | ||
1127 | } | ||
1128 | |||
1129 | /* Something went wrong, fallback to basic rate for this band */ | ||
1130 | if ((mac80211_rix >= sc->curband->n_bitrates) || | ||
1131 | (mac80211_rix <= 0 )) | ||
1132 | mac80211_rix = 1; | ||
1133 | |||
1134 | return mac80211_rix; | ||
1135 | } | 1099 | } |
1136 | 1100 | ||
1137 | |||
1138 | |||
1139 | |||
1140 | /***************\ | 1101 | /***************\ |
1141 | * Buffers setup * | 1102 | * Buffers setup * |
1142 | \***************/ | 1103 | \***************/ |
@@ -1199,7 +1160,7 @@ ath5k_rxbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1199 | ds = bf->desc; | 1160 | ds = bf->desc; |
1200 | ds->ds_link = bf->daddr; /* link to self */ | 1161 | ds->ds_link = bf->daddr; /* link to self */ |
1201 | ds->ds_data = bf->skbaddr; | 1162 | ds->ds_data = bf->skbaddr; |
1202 | ath5k_hw_setup_rx_desc(ah, ds, | 1163 | ah->ah_setup_rx_desc(ah, ds, |
1203 | skb_tailroom(skb), /* buffer size */ | 1164 | skb_tailroom(skb), /* buffer size */ |
1204 | 0); | 1165 | 0); |
1205 | 1166 | ||
@@ -1218,7 +1179,9 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1218 | struct sk_buff *skb = bf->skb; | 1179 | struct sk_buff *skb = bf->skb; |
1219 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); | 1180 | struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); |
1220 | unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; | 1181 | unsigned int pktlen, flags, keyidx = AR5K_TXKEYIX_INVALID; |
1221 | int ret; | 1182 | struct ieee80211_rate *rate; |
1183 | unsigned int mrr_rate[3], mrr_tries[3]; | ||
1184 | int i, ret; | ||
1222 | 1185 | ||
1223 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; | 1186 | flags = AR5K_TXDESC_INTREQ | AR5K_TXDESC_CLRDMASK; |
1224 | 1187 | ||
@@ -1233,7 +1196,7 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1233 | 1196 | ||
1234 | if (info->control.hw_key) { | 1197 | if (info->control.hw_key) { |
1235 | keyidx = info->control.hw_key->hw_key_idx; | 1198 | keyidx = info->control.hw_key->hw_key_idx; |
1236 | pktlen += info->control.icv_len; | 1199 | pktlen += info->control.hw_key->icv_len; |
1237 | } | 1200 | } |
1238 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, | 1201 | ret = ah->ah_setup_tx_desc(ah, ds, pktlen, |
1239 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, | 1202 | ieee80211_get_hdrlen_from_skb(skb), AR5K_PKT_TYPE_NORMAL, |
@@ -1243,6 +1206,22 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1243 | if (ret) | 1206 | if (ret) |
1244 | goto err_unmap; | 1207 | goto err_unmap; |
1245 | 1208 | ||
1209 | memset(mrr_rate, 0, sizeof(mrr_rate)); | ||
1210 | memset(mrr_tries, 0, sizeof(mrr_tries)); | ||
1211 | for (i = 0; i < 3; i++) { | ||
1212 | rate = ieee80211_get_alt_retry_rate(sc->hw, info, i); | ||
1213 | if (!rate) | ||
1214 | break; | ||
1215 | |||
1216 | mrr_rate[i] = rate->hw_value; | ||
1217 | mrr_tries[i] = info->control.retries[i].limit; | ||
1218 | } | ||
1219 | |||
1220 | ah->ah_setup_mrr_tx_desc(ah, ds, | ||
1221 | mrr_rate[0], mrr_tries[0], | ||
1222 | mrr_rate[1], mrr_tries[1], | ||
1223 | mrr_rate[2], mrr_tries[2]); | ||
1224 | |||
1246 | ds->ds_link = 0; | 1225 | ds->ds_link = 0; |
1247 | ds->ds_data = bf->skbaddr; | 1226 | ds->ds_data = bf->skbaddr; |
1248 | 1227 | ||
@@ -1250,12 +1229,12 @@ ath5k_txbuf_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1250 | list_add_tail(&bf->list, &txq->q); | 1229 | list_add_tail(&bf->list, &txq->q); |
1251 | sc->tx_stats[txq->qnum].len++; | 1230 | sc->tx_stats[txq->qnum].len++; |
1252 | if (txq->link == NULL) /* is this first packet? */ | 1231 | if (txq->link == NULL) /* is this first packet? */ |
1253 | ath5k_hw_put_tx_buf(ah, txq->qnum, bf->daddr); | 1232 | ath5k_hw_set_txdp(ah, txq->qnum, bf->daddr); |
1254 | else /* no, so only link it */ | 1233 | else /* no, so only link it */ |
1255 | *txq->link = bf->daddr; | 1234 | *txq->link = bf->daddr; |
1256 | 1235 | ||
1257 | txq->link = &ds->ds_link; | 1236 | txq->link = &ds->ds_link; |
1258 | ath5k_hw_tx_start(ah, txq->qnum); | 1237 | ath5k_hw_start_tx_dma(ah, txq->qnum); |
1259 | mmiowb(); | 1238 | mmiowb(); |
1260 | spin_unlock_bh(&txq->lock); | 1239 | spin_unlock_bh(&txq->lock); |
1261 | 1240 | ||
@@ -1433,7 +1412,8 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1433 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); | 1412 | ret = ath5k_hw_get_tx_queueprops(ah, sc->bhalq, &qi); |
1434 | if (ret) | 1413 | if (ret) |
1435 | return ret; | 1414 | return ret; |
1436 | if (sc->opmode == IEEE80211_IF_TYPE_AP) { | 1415 | if (sc->opmode == NL80211_IFTYPE_AP || |
1416 | sc->opmode == NL80211_IFTYPE_MESH_POINT) { | ||
1437 | /* | 1417 | /* |
1438 | * Always burst out beacon and CAB traffic | 1418 | * Always burst out beacon and CAB traffic |
1439 | * (aifs = cwmin = cwmax = 0) | 1419 | * (aifs = cwmin = cwmax = 0) |
@@ -1441,7 +1421,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1441 | qi.tqi_aifs = 0; | 1421 | qi.tqi_aifs = 0; |
1442 | qi.tqi_cw_min = 0; | 1422 | qi.tqi_cw_min = 0; |
1443 | qi.tqi_cw_max = 0; | 1423 | qi.tqi_cw_max = 0; |
1444 | } else if (sc->opmode == IEEE80211_IF_TYPE_IBSS) { | 1424 | } else if (sc->opmode == NL80211_IFTYPE_ADHOC) { |
1445 | /* | 1425 | /* |
1446 | * Adhoc mode; backoff between 0 and (2 * cw_min). | 1426 | * Adhoc mode; backoff between 0 and (2 * cw_min). |
1447 | */ | 1427 | */ |
@@ -1454,7 +1434,7 @@ ath5k_beaconq_config(struct ath5k_softc *sc) | |||
1454 | "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n", | 1434 | "beacon queueprops tqi_aifs:%d tqi_cw_min:%d tqi_cw_max:%d\n", |
1455 | qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max); | 1435 | qi.tqi_aifs, qi.tqi_cw_min, qi.tqi_cw_max); |
1456 | 1436 | ||
1457 | ret = ath5k_hw_setup_tx_queueprops(ah, sc->bhalq, &qi); | 1437 | ret = ath5k_hw_set_tx_queueprops(ah, sc->bhalq, &qi); |
1458 | if (ret) { | 1438 | if (ret) { |
1459 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " | 1439 | ATH5K_ERR(sc, "%s: unable to update parameters for beacon " |
1460 | "hardware queue!\n", __func__); | 1440 | "hardware queue!\n", __func__); |
@@ -1503,14 +1483,14 @@ ath5k_txq_cleanup(struct ath5k_softc *sc) | |||
1503 | /* don't touch the hardware if marked invalid */ | 1483 | /* don't touch the hardware if marked invalid */ |
1504 | ath5k_hw_stop_tx_dma(ah, sc->bhalq); | 1484 | ath5k_hw_stop_tx_dma(ah, sc->bhalq); |
1505 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", | 1485 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon queue %x\n", |
1506 | ath5k_hw_get_tx_buf(ah, sc->bhalq)); | 1486 | ath5k_hw_get_txdp(ah, sc->bhalq)); |
1507 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) | 1487 | for (i = 0; i < ARRAY_SIZE(sc->txqs); i++) |
1508 | if (sc->txqs[i].setup) { | 1488 | if (sc->txqs[i].setup) { |
1509 | ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); | 1489 | ath5k_hw_stop_tx_dma(ah, sc->txqs[i].qnum); |
1510 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " | 1490 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "txq [%u] %x, " |
1511 | "link %p\n", | 1491 | "link %p\n", |
1512 | sc->txqs[i].qnum, | 1492 | sc->txqs[i].qnum, |
1513 | ath5k_hw_get_tx_buf(ah, | 1493 | ath5k_hw_get_txdp(ah, |
1514 | sc->txqs[i].qnum), | 1494 | sc->txqs[i].qnum), |
1515 | sc->txqs[i].link); | 1495 | sc->txqs[i].link); |
1516 | } | 1496 | } |
@@ -1570,8 +1550,8 @@ ath5k_rx_start(struct ath5k_softc *sc) | |||
1570 | bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); | 1550 | bf = list_first_entry(&sc->rxbuf, struct ath5k_buf, list); |
1571 | spin_unlock_bh(&sc->rxbuflock); | 1551 | spin_unlock_bh(&sc->rxbuflock); |
1572 | 1552 | ||
1573 | ath5k_hw_put_rx_buf(ah, bf->daddr); | 1553 | ath5k_hw_set_rxdp(ah, bf->daddr); |
1574 | ath5k_hw_start_rx(ah); /* enable recv descriptors */ | 1554 | ath5k_hw_start_rx_dma(ah); /* enable recv descriptors */ |
1575 | ath5k_mode_setup(sc); /* set filters, etc. */ | 1555 | ath5k_mode_setup(sc); /* set filters, etc. */ |
1576 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ | 1556 | ath5k_hw_start_rx_pcu(ah); /* re-enable PCU/DMA engine */ |
1577 | 1557 | ||
@@ -1588,7 +1568,7 @@ ath5k_rx_stop(struct ath5k_softc *sc) | |||
1588 | { | 1568 | { |
1589 | struct ath5k_hw *ah = sc->ah; | 1569 | struct ath5k_hw *ah = sc->ah; |
1590 | 1570 | ||
1591 | ath5k_hw_stop_pcu_recv(ah); /* disable PCU */ | 1571 | ath5k_hw_stop_rx_pcu(ah); /* disable PCU */ |
1592 | ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ | 1572 | ath5k_hw_set_rx_filter(ah, 0); /* clear recv filter */ |
1593 | ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ | 1573 | ath5k_hw_stop_rx_dma(ah); /* disable DMA engine */ |
1594 | 1574 | ||
@@ -1602,7 +1582,7 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | |||
1602 | struct sk_buff *skb, struct ath5k_rx_status *rs) | 1582 | struct sk_buff *skb, struct ath5k_rx_status *rs) |
1603 | { | 1583 | { |
1604 | struct ieee80211_hdr *hdr = (void *)skb->data; | 1584 | struct ieee80211_hdr *hdr = (void *)skb->data; |
1605 | unsigned int keyix, hlen = ieee80211_get_hdrlen_from_skb(skb); | 1585 | unsigned int keyix, hlen; |
1606 | 1586 | ||
1607 | if (!(rs->rs_status & AR5K_RXERR_DECRYPT) && | 1587 | if (!(rs->rs_status & AR5K_RXERR_DECRYPT) && |
1608 | rs->rs_keyix != AR5K_RXKEYIX_INVALID) | 1588 | rs->rs_keyix != AR5K_RXKEYIX_INVALID) |
@@ -1611,6 +1591,7 @@ ath5k_rx_decrypted(struct ath5k_softc *sc, struct ath5k_desc *ds, | |||
1611 | /* Apparently when a default key is used to decrypt the packet | 1591 | /* Apparently when a default key is used to decrypt the packet |
1612 | the hw does not set the index used to decrypt. In such cases | 1592 | the hw does not set the index used to decrypt. In such cases |
1613 | get the index from the packet. */ | 1593 | get the index from the packet. */ |
1594 | hlen = ieee80211_hdrlen(hdr->frame_control); | ||
1614 | if (ieee80211_has_protected(hdr->frame_control) && | 1595 | if (ieee80211_has_protected(hdr->frame_control) && |
1615 | !(rs->rs_status & AR5K_RXERR_DECRYPT) && | 1596 | !(rs->rs_status & AR5K_RXERR_DECRYPT) && |
1616 | skb->len >= hlen + 4) { | 1597 | skb->len >= hlen + 4) { |
@@ -1768,7 +1749,7 @@ ath5k_tasklet_rx(unsigned long data) | |||
1768 | /* let crypto-error packets fall through in MNTR */ | 1749 | /* let crypto-error packets fall through in MNTR */ |
1769 | if ((rs.rs_status & | 1750 | if ((rs.rs_status & |
1770 | ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || | 1751 | ~(AR5K_RXERR_DECRYPT|AR5K_RXERR_MIC)) || |
1771 | sc->opmode != IEEE80211_IF_TYPE_MNTR) | 1752 | sc->opmode != NL80211_IFTYPE_MONITOR) |
1772 | goto next; | 1753 | goto next; |
1773 | } | 1754 | } |
1774 | accept: | 1755 | accept: |
@@ -1824,10 +1805,14 @@ accept: | |||
1824 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); | 1805 | rxs.rate_idx = ath5k_hw_to_driver_rix(sc, rs.rs_rate); |
1825 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); | 1806 | rxs.flag |= ath5k_rx_decrypted(sc, ds, skb, &rs); |
1826 | 1807 | ||
1808 | if (rxs.rate_idx >= 0 && rs.rs_rate == | ||
1809 | sc->curband->bitrates[rxs.rate_idx].hw_value_short) | ||
1810 | rxs.flag |= RX_FLAG_SHORTPRE; | ||
1811 | |||
1827 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); | 1812 | ath5k_debug_dump_skb(sc, skb, "RX ", 0); |
1828 | 1813 | ||
1829 | /* check beacons in IBSS mode */ | 1814 | /* check beacons in IBSS mode */ |
1830 | if (sc->opmode == IEEE80211_IF_TYPE_IBSS) | 1815 | if (sc->opmode == NL80211_IFTYPE_ADHOC) |
1831 | ath5k_check_ibss_tsf(sc, skb, &rxs); | 1816 | ath5k_check_ibss_tsf(sc, skb, &rxs); |
1832 | 1817 | ||
1833 | __ieee80211_rx(sc->hw, skb, &rxs); | 1818 | __ieee80211_rx(sc->hw, skb, &rxs); |
@@ -1853,7 +1838,7 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1853 | struct ath5k_desc *ds; | 1838 | struct ath5k_desc *ds; |
1854 | struct sk_buff *skb; | 1839 | struct sk_buff *skb; |
1855 | struct ieee80211_tx_info *info; | 1840 | struct ieee80211_tx_info *info; |
1856 | int ret; | 1841 | int i, ret; |
1857 | 1842 | ||
1858 | spin_lock(&txq->lock); | 1843 | spin_lock(&txq->lock); |
1859 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { | 1844 | list_for_each_entry_safe(bf, bf0, &txq->q, list) { |
@@ -1875,7 +1860,25 @@ ath5k_tx_processq(struct ath5k_softc *sc, struct ath5k_txq *txq) | |||
1875 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, | 1860 | pci_unmap_single(sc->pdev, bf->skbaddr, skb->len, |
1876 | PCI_DMA_TODEVICE); | 1861 | PCI_DMA_TODEVICE); |
1877 | 1862 | ||
1878 | info->status.retry_count = ts.ts_shortretry + ts.ts_longretry / 6; | 1863 | memset(&info->status, 0, sizeof(info->status)); |
1864 | info->tx_rate_idx = ath5k_hw_to_driver_rix(sc, | ||
1865 | ts.ts_rate[ts.ts_final_idx]); | ||
1866 | info->status.retry_count = ts.ts_longretry; | ||
1867 | |||
1868 | for (i = 0; i < 4; i++) { | ||
1869 | struct ieee80211_tx_altrate *r = | ||
1870 | &info->status.retries[i]; | ||
1871 | |||
1872 | if (ts.ts_rate[i]) { | ||
1873 | r->rate_idx = ath5k_hw_to_driver_rix(sc, ts.ts_rate[i]); | ||
1874 | r->limit = ts.ts_retry[i]; | ||
1875 | } else { | ||
1876 | r->rate_idx = -1; | ||
1877 | r->limit = 0; | ||
1878 | } | ||
1879 | } | ||
1880 | |||
1881 | info->status.excessive_retries = 0; | ||
1879 | if (unlikely(ts.ts_status)) { | 1882 | if (unlikely(ts.ts_status)) { |
1880 | sc->ll_stats.dot11ACKFailureCount++; | 1883 | sc->ll_stats.dot11ACKFailureCount++; |
1881 | if (ts.ts_status & AR5K_TXERR_XRETRY) | 1884 | if (ts.ts_status & AR5K_TXERR_XRETRY) |
@@ -1942,7 +1945,7 @@ ath5k_beacon_setup(struct ath5k_softc *sc, struct ath5k_buf *bf) | |||
1942 | ds = bf->desc; | 1945 | ds = bf->desc; |
1943 | 1946 | ||
1944 | flags = AR5K_TXDESC_NOACK; | 1947 | flags = AR5K_TXDESC_NOACK; |
1945 | if (sc->opmode == IEEE80211_IF_TYPE_IBSS && ath5k_hw_hasveol(ah)) { | 1948 | if (sc->opmode == NL80211_IFTYPE_ADHOC && ath5k_hw_hasveol(ah)) { |
1946 | ds->ds_link = bf->daddr; /* self-linked */ | 1949 | ds->ds_link = bf->daddr; /* self-linked */ |
1947 | flags |= AR5K_TXDESC_VEOL; | 1950 | flags |= AR5K_TXDESC_VEOL; |
1948 | /* | 1951 | /* |
@@ -1991,8 +1994,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
1991 | 1994 | ||
1992 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); | 1995 | ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "in beacon_send\n"); |
1993 | 1996 | ||
1994 | if (unlikely(bf->skb == NULL || sc->opmode == IEEE80211_IF_TYPE_STA || | 1997 | if (unlikely(bf->skb == NULL || sc->opmode == NL80211_IFTYPE_STATION || |
1995 | sc->opmode == IEEE80211_IF_TYPE_MNTR)) { | 1998 | sc->opmode == NL80211_IFTYPE_MONITOR)) { |
1996 | ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); | 1999 | ATH5K_WARN(sc, "bf=%p bf_skb=%p\n", bf, bf ? bf->skb : NULL); |
1997 | return; | 2000 | return; |
1998 | } | 2001 | } |
@@ -2032,8 +2035,8 @@ ath5k_beacon_send(struct ath5k_softc *sc) | |||
2032 | /* NB: hw still stops DMA, so proceed */ | 2035 | /* NB: hw still stops DMA, so proceed */ |
2033 | } | 2036 | } |
2034 | 2037 | ||
2035 | ath5k_hw_put_tx_buf(ah, sc->bhalq, bf->daddr); | 2038 | ath5k_hw_set_txdp(ah, sc->bhalq, bf->daddr); |
2036 | ath5k_hw_tx_start(ah, sc->bhalq); | 2039 | ath5k_hw_start_tx_dma(ah, sc->bhalq); |
2037 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", | 2040 | ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "TXDP[%u] = %llx (%p)\n", |
2038 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); | 2041 | sc->bhalq, (unsigned long long)bf->daddr, bf->desc); |
2039 | 2042 | ||
@@ -2162,13 +2165,13 @@ ath5k_beacon_config(struct ath5k_softc *sc) | |||
2162 | { | 2165 | { |
2163 | struct ath5k_hw *ah = sc->ah; | 2166 | struct ath5k_hw *ah = sc->ah; |
2164 | 2167 | ||
2165 | ath5k_hw_set_intr(ah, 0); | 2168 | ath5k_hw_set_imr(ah, 0); |
2166 | sc->bmisscount = 0; | 2169 | sc->bmisscount = 0; |
2167 | sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); | 2170 | sc->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); |
2168 | 2171 | ||
2169 | if (sc->opmode == IEEE80211_IF_TYPE_STA) { | 2172 | if (sc->opmode == NL80211_IFTYPE_STATION) { |
2170 | sc->imask |= AR5K_INT_BMISS; | 2173 | sc->imask |= AR5K_INT_BMISS; |
2171 | } else if (sc->opmode == IEEE80211_IF_TYPE_IBSS) { | 2174 | } else if (sc->opmode == NL80211_IFTYPE_ADHOC) { |
2172 | /* | 2175 | /* |
2173 | * In IBSS mode we use a self-linked tx descriptor and let the | 2176 | * In IBSS mode we use a self-linked tx descriptor and let the |
2174 | * hardware send the beacons automatically. We have to load it | 2177 | * hardware send the beacons automatically. We have to load it |
@@ -2188,7 +2191,7 @@ ath5k_beacon_config(struct ath5k_softc *sc) | |||
2188 | } | 2191 | } |
2189 | /* TODO else AP */ | 2192 | /* TODO else AP */ |
2190 | 2193 | ||
2191 | ath5k_hw_set_intr(ah, sc->imask); | 2194 | ath5k_hw_set_imr(ah, sc->imask); |
2192 | } | 2195 | } |
2193 | 2196 | ||
2194 | 2197 | ||
@@ -2220,36 +2223,13 @@ ath5k_init(struct ath5k_softc *sc) | |||
2220 | */ | 2223 | */ |
2221 | sc->curchan = sc->hw->conf.channel; | 2224 | sc->curchan = sc->hw->conf.channel; |
2222 | sc->curband = &sc->sbands[sc->curchan->band]; | 2225 | sc->curband = &sc->sbands[sc->curchan->band]; |
2223 | ret = ath5k_hw_reset(sc->ah, sc->opmode, sc->curchan, false); | ||
2224 | if (ret) { | ||
2225 | ATH5K_ERR(sc, "unable to reset hardware: %d\n", ret); | ||
2226 | goto done; | ||
2227 | } | ||
2228 | /* | ||
2229 | * This is needed only to setup initial state | ||
2230 | * but it's best done after a reset. | ||
2231 | */ | ||
2232 | ath5k_hw_set_txpower_limit(sc->ah, 0); | ||
2233 | |||
2234 | /* | ||
2235 | * Setup the hardware after reset: the key cache | ||
2236 | * is filled as needed and the receive engine is | ||
2237 | * set going. Frame transmit is handled entirely | ||
2238 | * in the frame output path; there's nothing to do | ||
2239 | * here except setup the interrupt mask. | ||
2240 | */ | ||
2241 | ret = ath5k_rx_start(sc); | ||
2242 | if (ret) | ||
2243 | goto done; | ||
2244 | |||
2245 | /* | ||
2246 | * Enable interrupts. | ||
2247 | */ | ||
2248 | sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL | | 2226 | sc->imask = AR5K_INT_RX | AR5K_INT_TX | AR5K_INT_RXEOL | |
2249 | AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL | | 2227 | AR5K_INT_RXORN | AR5K_INT_FATAL | AR5K_INT_GLOBAL | |
2250 | AR5K_INT_MIB; | 2228 | AR5K_INT_MIB; |
2229 | ret = ath5k_reset(sc, false, false); | ||
2230 | if (ret) | ||
2231 | goto done; | ||
2251 | 2232 | ||
2252 | ath5k_hw_set_intr(sc->ah, sc->imask); | ||
2253 | /* Set ack to be sent at low bit-rates */ | 2233 | /* Set ack to be sent at low bit-rates */ |
2254 | ath5k_hw_set_ack_bitrate_high(sc->ah, false); | 2234 | ath5k_hw_set_ack_bitrate_high(sc->ah, false); |
2255 | 2235 | ||
@@ -2290,7 +2270,7 @@ ath5k_stop_locked(struct ath5k_softc *sc) | |||
2290 | 2270 | ||
2291 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { | 2271 | if (!test_bit(ATH_STAT_INVALID, sc->status)) { |
2292 | ath5k_led_off(sc); | 2272 | ath5k_led_off(sc); |
2293 | ath5k_hw_set_intr(ah, 0); | 2273 | ath5k_hw_set_imr(ah, 0); |
2294 | synchronize_irq(sc->pdev->irq); | 2274 | synchronize_irq(sc->pdev->irq); |
2295 | } | 2275 | } |
2296 | ath5k_txq_cleanup(sc); | 2276 | ath5k_txq_cleanup(sc); |
@@ -2396,7 +2376,7 @@ ath5k_intr(int irq, void *dev_id) | |||
2396 | * transmission time) in order to detect wether | 2376 | * transmission time) in order to detect wether |
2397 | * automatic TSF updates happened. | 2377 | * automatic TSF updates happened. |
2398 | */ | 2378 | */ |
2399 | if (sc->opmode == IEEE80211_IF_TYPE_IBSS) { | 2379 | if (sc->opmode == NL80211_IFTYPE_ADHOC) { |
2400 | /* XXX: only if VEOL suppported */ | 2380 | /* XXX: only if VEOL suppported */ |
2401 | u64 tsf = ath5k_hw_get_tsf64(ah); | 2381 | u64 tsf = ath5k_hw_get_tsf64(ah); |
2402 | sc->nexttbtt += sc->bintval; | 2382 | sc->nexttbtt += sc->bintval; |
@@ -2451,7 +2431,7 @@ ath5k_tasklet_reset(unsigned long data) | |||
2451 | { | 2431 | { |
2452 | struct ath5k_softc *sc = (void *)data; | 2432 | struct ath5k_softc *sc = (void *)data; |
2453 | 2433 | ||
2454 | ath5k_reset(sc->hw); | 2434 | ath5k_reset_wake(sc); |
2455 | } | 2435 | } |
2456 | 2436 | ||
2457 | /* | 2437 | /* |
@@ -2474,7 +2454,7 @@ ath5k_calibrate(unsigned long data) | |||
2474 | * to load new gain values. | 2454 | * to load new gain values. |
2475 | */ | 2455 | */ |
2476 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); | 2456 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "calibration, resetting\n"); |
2477 | ath5k_reset(sc->hw); | 2457 | ath5k_reset_wake(sc); |
2478 | } | 2458 | } |
2479 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) | 2459 | if (ath5k_hw_phy_calibrate(ah, sc->curchan)) |
2480 | ATH5K_ERR(sc, "calibration of channel %u failed\n", | 2460 | ATH5K_ERR(sc, "calibration of channel %u failed\n", |
@@ -2626,7 +2606,7 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2626 | 2606 | ||
2627 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); | 2607 | ath5k_debug_dump_skb(sc, skb, "TX ", 1); |
2628 | 2608 | ||
2629 | if (sc->opmode == IEEE80211_IF_TYPE_MNTR) | 2609 | if (sc->opmode == NL80211_IFTYPE_MONITOR) |
2630 | ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n"); | 2610 | ATH5K_DBG(sc, ATH5K_DEBUG_XMIT, "tx in monitor (scan?)\n"); |
2631 | 2611 | ||
2632 | /* | 2612 | /* |
@@ -2675,48 +2655,67 @@ ath5k_tx(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
2675 | } | 2655 | } |
2676 | 2656 | ||
2677 | static int | 2657 | static int |
2678 | ath5k_reset(struct ieee80211_hw *hw) | 2658 | ath5k_reset(struct ath5k_softc *sc, bool stop, bool change_channel) |
2679 | { | 2659 | { |
2680 | struct ath5k_softc *sc = hw->priv; | ||
2681 | struct ath5k_hw *ah = sc->ah; | 2660 | struct ath5k_hw *ah = sc->ah; |
2682 | int ret; | 2661 | int ret; |
2683 | 2662 | ||
2684 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); | 2663 | ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "resetting\n"); |
2685 | 2664 | ||
2686 | ath5k_hw_set_intr(ah, 0); | 2665 | if (stop) { |
2687 | ath5k_txq_cleanup(sc); | 2666 | ath5k_hw_set_imr(ah, 0); |
2688 | ath5k_rx_stop(sc); | 2667 | ath5k_txq_cleanup(sc); |
2689 | 2668 | ath5k_rx_stop(sc); | |
2669 | } | ||
2690 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); | 2670 | ret = ath5k_hw_reset(ah, sc->opmode, sc->curchan, true); |
2691 | if (unlikely(ret)) { | 2671 | if (ret) { |
2692 | ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); | 2672 | ATH5K_ERR(sc, "can't reset hardware (%d)\n", ret); |
2693 | goto err; | 2673 | goto err; |
2694 | } | 2674 | } |
2675 | |||
2676 | /* | ||
2677 | * This is needed only to setup initial state | ||
2678 | * but it's best done after a reset. | ||
2679 | */ | ||
2695 | ath5k_hw_set_txpower_limit(sc->ah, 0); | 2680 | ath5k_hw_set_txpower_limit(sc->ah, 0); |
2696 | 2681 | ||
2697 | ret = ath5k_rx_start(sc); | 2682 | ret = ath5k_rx_start(sc); |
2698 | if (unlikely(ret)) { | 2683 | if (ret) { |
2699 | ATH5K_ERR(sc, "can't start recv logic\n"); | 2684 | ATH5K_ERR(sc, "can't start recv logic\n"); |
2700 | goto err; | 2685 | goto err; |
2701 | } | 2686 | } |
2687 | |||
2702 | /* | 2688 | /* |
2703 | * We may be doing a reset in response to an ioctl | 2689 | * Change channels and update the h/w rate map if we're switching; |
2704 | * that changes the channel so update any state that | 2690 | * e.g. 11a to 11b/g. |
2705 | * might change as a result. | 2691 | * |
2692 | * We may be doing a reset in response to an ioctl that changes the | ||
2693 | * channel so update any state that might change as a result. | ||
2706 | * | 2694 | * |
2707 | * XXX needed? | 2695 | * XXX needed? |
2708 | */ | 2696 | */ |
2709 | /* ath5k_chan_change(sc, c); */ | 2697 | /* ath5k_chan_change(sc, c); */ |
2710 | ath5k_beacon_config(sc); | ||
2711 | /* intrs are started by ath5k_beacon_config */ | ||
2712 | 2698 | ||
2713 | ieee80211_wake_queues(hw); | 2699 | ath5k_beacon_config(sc); |
2700 | /* intrs are enabled by ath5k_beacon_config */ | ||
2714 | 2701 | ||
2715 | return 0; | 2702 | return 0; |
2716 | err: | 2703 | err: |
2717 | return ret; | 2704 | return ret; |
2718 | } | 2705 | } |
2719 | 2706 | ||
2707 | static int | ||
2708 | ath5k_reset_wake(struct ath5k_softc *sc) | ||
2709 | { | ||
2710 | int ret; | ||
2711 | |||
2712 | ret = ath5k_reset(sc, true, true); | ||
2713 | if (!ret) | ||
2714 | ieee80211_wake_queues(sc->hw); | ||
2715 | |||
2716 | return ret; | ||
2717 | } | ||
2718 | |||
2720 | static int ath5k_start(struct ieee80211_hw *hw) | 2719 | static int ath5k_start(struct ieee80211_hw *hw) |
2721 | { | 2720 | { |
2722 | return ath5k_init(hw->priv); | 2721 | return ath5k_init(hw->priv); |
@@ -2742,9 +2741,9 @@ static int ath5k_add_interface(struct ieee80211_hw *hw, | |||
2742 | sc->vif = conf->vif; | 2741 | sc->vif = conf->vif; |
2743 | 2742 | ||
2744 | switch (conf->type) { | 2743 | switch (conf->type) { |
2745 | case IEEE80211_IF_TYPE_STA: | 2744 | case NL80211_IFTYPE_STATION: |
2746 | case IEEE80211_IF_TYPE_IBSS: | 2745 | case NL80211_IFTYPE_ADHOC: |
2747 | case IEEE80211_IF_TYPE_MNTR: | 2746 | case NL80211_IFTYPE_MONITOR: |
2748 | sc->opmode = conf->type; | 2747 | sc->opmode = conf->type; |
2749 | break; | 2748 | break; |
2750 | default: | 2749 | default: |
@@ -2815,7 +2814,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2815 | } | 2814 | } |
2816 | 2815 | ||
2817 | if (conf->changed & IEEE80211_IFCC_BEACON && | 2816 | if (conf->changed & IEEE80211_IFCC_BEACON && |
2818 | vif->type == IEEE80211_IF_TYPE_IBSS) { | 2817 | vif->type == NL80211_IFTYPE_ADHOC) { |
2819 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); | 2818 | struct sk_buff *beacon = ieee80211_beacon_get(hw, vif); |
2820 | if (!beacon) { | 2819 | if (!beacon) { |
2821 | ret = -ENOMEM; | 2820 | ret = -ENOMEM; |
@@ -2827,7 +2826,7 @@ ath5k_config_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
2827 | 2826 | ||
2828 | mutex_unlock(&sc->lock); | 2827 | mutex_unlock(&sc->lock); |
2829 | 2828 | ||
2830 | return ath5k_reset(hw); | 2829 | return ath5k_reset_wake(sc); |
2831 | unlock: | 2830 | unlock: |
2832 | mutex_unlock(&sc->lock); | 2831 | mutex_unlock(&sc->lock); |
2833 | return ret; | 2832 | return ret; |
@@ -2934,16 +2933,17 @@ static void ath5k_configure_filter(struct ieee80211_hw *hw, | |||
2934 | 2933 | ||
2935 | /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ | 2934 | /* XXX move these to mac80211, and add a beacon IFF flag to mac80211 */ |
2936 | 2935 | ||
2937 | if (sc->opmode == IEEE80211_IF_TYPE_MNTR) | 2936 | if (sc->opmode == NL80211_IFTYPE_MONITOR) |
2938 | rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON | | 2937 | rfilt |= AR5K_RX_FILTER_CONTROL | AR5K_RX_FILTER_BEACON | |
2939 | AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM; | 2938 | AR5K_RX_FILTER_PROBEREQ | AR5K_RX_FILTER_PROM; |
2940 | if (sc->opmode != IEEE80211_IF_TYPE_STA) | 2939 | if (sc->opmode != NL80211_IFTYPE_STATION) |
2941 | rfilt |= AR5K_RX_FILTER_PROBEREQ; | 2940 | rfilt |= AR5K_RX_FILTER_PROBEREQ; |
2942 | if (sc->opmode != IEEE80211_IF_TYPE_AP && | 2941 | if (sc->opmode != NL80211_IFTYPE_AP && |
2942 | sc->opmode != NL80211_IFTYPE_MESH_POINT && | ||
2943 | test_bit(ATH_STAT_PROMISC, sc->status)) | 2943 | test_bit(ATH_STAT_PROMISC, sc->status)) |
2944 | rfilt |= AR5K_RX_FILTER_PROM; | 2944 | rfilt |= AR5K_RX_FILTER_PROM; |
2945 | if (sc->opmode == IEEE80211_IF_TYPE_STA || | 2945 | if (sc->opmode == NL80211_IFTYPE_STATION || |
2946 | sc->opmode == IEEE80211_IF_TYPE_IBSS) { | 2946 | sc->opmode == NL80211_IFTYPE_ADHOC) { |
2947 | rfilt |= AR5K_RX_FILTER_BEACON; | 2947 | rfilt |= AR5K_RX_FILTER_BEACON; |
2948 | } | 2948 | } |
2949 | 2949 | ||
@@ -3048,7 +3048,7 @@ ath5k_reset_tsf(struct ieee80211_hw *hw) | |||
3048 | * in IBSS mode we need to update the beacon timers too. | 3048 | * in IBSS mode we need to update the beacon timers too. |
3049 | * this will also reset the TSF if we call it with 0 | 3049 | * this will also reset the TSF if we call it with 0 |
3050 | */ | 3050 | */ |
3051 | if (sc->opmode == IEEE80211_IF_TYPE_IBSS) | 3051 | if (sc->opmode == NL80211_IFTYPE_ADHOC) |
3052 | ath5k_beacon_update_timers(sc, 0); | 3052 | ath5k_beacon_update_timers(sc, 0); |
3053 | else | 3053 | else |
3054 | ath5k_hw_reset_tsf(sc->ah); | 3054 | ath5k_hw_reset_tsf(sc->ah); |
@@ -3063,7 +3063,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | |||
3063 | 3063 | ||
3064 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); | 3064 | ath5k_debug_dump_skb(sc, skb, "BC ", 1); |
3065 | 3065 | ||
3066 | if (sc->opmode != IEEE80211_IF_TYPE_IBSS) { | 3066 | if (sc->opmode != NL80211_IFTYPE_ADHOC) { |
3067 | ret = -EIO; | 3067 | ret = -EIO; |
3068 | goto end; | 3068 | goto end; |
3069 | } | 3069 | } |
diff --git a/drivers/net/wireless/ath5k/base.h b/drivers/net/wireless/ath5k/base.h index 7ec2f377d5c7..9d0b728928e3 100644 --- a/drivers/net/wireless/ath5k/base.h +++ b/drivers/net/wireless/ath5k/base.h | |||
@@ -111,17 +111,13 @@ struct ath5k_softc { | |||
111 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ | 111 | struct ieee80211_hw *hw; /* IEEE 802.11 common */ |
112 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; | 112 | struct ieee80211_supported_band sbands[IEEE80211_NUM_BANDS]; |
113 | struct ieee80211_channel channels[ATH_CHAN_MAX]; | 113 | struct ieee80211_channel channels[ATH_CHAN_MAX]; |
114 | struct ieee80211_rate rates[AR5K_MAX_RATES * IEEE80211_NUM_BANDS]; | 114 | struct ieee80211_rate rates[IEEE80211_NUM_BANDS][AR5K_MAX_RATES]; |
115 | enum ieee80211_if_types opmode; | 115 | u8 rate_idx[IEEE80211_NUM_BANDS][AR5K_MAX_RATES]; |
116 | enum nl80211_iftype opmode; | ||
116 | struct ath5k_hw *ah; /* Atheros HW */ | 117 | struct ath5k_hw *ah; /* Atheros HW */ |
117 | 118 | ||
118 | struct ieee80211_supported_band *curband; | 119 | struct ieee80211_supported_band *curband; |
119 | 120 | ||
120 | u8 a_rates; | ||
121 | u8 b_rates; | ||
122 | u8 g_rates; | ||
123 | u8 xr_rates; | ||
124 | |||
125 | #ifdef CONFIG_ATH5K_DEBUG | 121 | #ifdef CONFIG_ATH5K_DEBUG |
126 | struct ath5k_dbg_info debug; /* debug info */ | 122 | struct ath5k_dbg_info debug; /* debug info */ |
127 | #endif /* CONFIG_ATH5K_DEBUG */ | 123 | #endif /* CONFIG_ATH5K_DEBUG */ |
diff --git a/drivers/net/wireless/ath5k/caps.c b/drivers/net/wireless/ath5k/caps.c new file mode 100644 index 000000000000..150f5ed204a0 --- /dev/null +++ b/drivers/net/wireless/ath5k/caps.c | |||
@@ -0,0 +1,193 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> | ||
5 | * | ||
6 | * Permission to use, copy, modify, and distribute this software for any | ||
7 | * purpose with or without fee is hereby granted, provided that the above | ||
8 | * copyright notice and this permission notice appear in all copies. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | /**************\ | ||
21 | * Capabilities * | ||
22 | \**************/ | ||
23 | |||
24 | #include "ath5k.h" | ||
25 | #include "reg.h" | ||
26 | #include "debug.h" | ||
27 | #include "base.h" | ||
28 | |||
29 | /* | ||
30 | * Fill the capabilities struct | ||
31 | * TODO: Merge this with EEPROM code when we are done with it | ||
32 | */ | ||
33 | int ath5k_hw_set_capabilities(struct ath5k_hw *ah) | ||
34 | { | ||
35 | u16 ee_header; | ||
36 | |||
37 | ATH5K_TRACE(ah->ah_sc); | ||
38 | /* Capabilities stored in the EEPROM */ | ||
39 | ee_header = ah->ah_capabilities.cap_eeprom.ee_header; | ||
40 | |||
41 | if (ah->ah_version == AR5K_AR5210) { | ||
42 | /* | ||
43 | * Set radio capabilities | ||
44 | * (The AR5110 only supports the middle 5GHz band) | ||
45 | */ | ||
46 | ah->ah_capabilities.cap_range.range_5ghz_min = 5120; | ||
47 | ah->ah_capabilities.cap_range.range_5ghz_max = 5430; | ||
48 | ah->ah_capabilities.cap_range.range_2ghz_min = 0; | ||
49 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; | ||
50 | |||
51 | /* Set supported modes */ | ||
52 | __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); | ||
53 | __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode); | ||
54 | } else { | ||
55 | /* | ||
56 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz | ||
57 | * XXX and from 2312 to 2732GHz. There are problems with the | ||
58 | * XXX current ieee80211 implementation because the IEEE | ||
59 | * XXX channel mapping does not support negative channel | ||
60 | * XXX numbers (2312MHz is channel -19). Of course, this | ||
61 | * XXX doesn't matter because these channels are out of range | ||
62 | * XXX but some regulation domains like MKK (Japan) will | ||
63 | * XXX support frequencies somewhere around 4.8GHz. | ||
64 | */ | ||
65 | |||
66 | /* | ||
67 | * Set radio capabilities | ||
68 | */ | ||
69 | |||
70 | if (AR5K_EEPROM_HDR_11A(ee_header)) { | ||
71 | /* 4920 */ | ||
72 | ah->ah_capabilities.cap_range.range_5ghz_min = 5005; | ||
73 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; | ||
74 | |||
75 | /* Set supported modes */ | ||
76 | __set_bit(AR5K_MODE_11A, | ||
77 | ah->ah_capabilities.cap_mode); | ||
78 | __set_bit(AR5K_MODE_11A_TURBO, | ||
79 | ah->ah_capabilities.cap_mode); | ||
80 | if (ah->ah_version == AR5K_AR5212) | ||
81 | __set_bit(AR5K_MODE_11G_TURBO, | ||
82 | ah->ah_capabilities.cap_mode); | ||
83 | } | ||
84 | |||
85 | /* Enable 802.11b if a 2GHz capable radio (2111/5112) is | ||
86 | * connected */ | ||
87 | if (AR5K_EEPROM_HDR_11B(ee_header) || | ||
88 | AR5K_EEPROM_HDR_11G(ee_header)) { | ||
89 | /* 2312 */ | ||
90 | ah->ah_capabilities.cap_range.range_2ghz_min = 2412; | ||
91 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; | ||
92 | |||
93 | if (AR5K_EEPROM_HDR_11B(ee_header)) | ||
94 | __set_bit(AR5K_MODE_11B, | ||
95 | ah->ah_capabilities.cap_mode); | ||
96 | |||
97 | if (AR5K_EEPROM_HDR_11G(ee_header)) | ||
98 | __set_bit(AR5K_MODE_11G, | ||
99 | ah->ah_capabilities.cap_mode); | ||
100 | } | ||
101 | } | ||
102 | |||
103 | /* GPIO */ | ||
104 | ah->ah_gpio_npins = AR5K_NUM_GPIO; | ||
105 | |||
106 | /* Set number of supported TX queues */ | ||
107 | if (ah->ah_version == AR5K_AR5210) | ||
108 | ah->ah_capabilities.cap_queues.q_tx_num = | ||
109 | AR5K_NUM_TX_QUEUES_NOQCU; | ||
110 | else | ||
111 | ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | /* Main function used by the driver part to check caps */ | ||
117 | int ath5k_hw_get_capability(struct ath5k_hw *ah, | ||
118 | enum ath5k_capability_type cap_type, | ||
119 | u32 capability, u32 *result) | ||
120 | { | ||
121 | ATH5K_TRACE(ah->ah_sc); | ||
122 | |||
123 | switch (cap_type) { | ||
124 | case AR5K_CAP_NUM_TXQUEUES: | ||
125 | if (result) { | ||
126 | if (ah->ah_version == AR5K_AR5210) | ||
127 | *result = AR5K_NUM_TX_QUEUES_NOQCU; | ||
128 | else | ||
129 | *result = AR5K_NUM_TX_QUEUES; | ||
130 | goto yes; | ||
131 | } | ||
132 | case AR5K_CAP_VEOL: | ||
133 | goto yes; | ||
134 | case AR5K_CAP_COMPRESSION: | ||
135 | if (ah->ah_version == AR5K_AR5212) | ||
136 | goto yes; | ||
137 | else | ||
138 | goto no; | ||
139 | case AR5K_CAP_BURST: | ||
140 | goto yes; | ||
141 | case AR5K_CAP_TPC: | ||
142 | goto yes; | ||
143 | case AR5K_CAP_BSSIDMASK: | ||
144 | if (ah->ah_version == AR5K_AR5212) | ||
145 | goto yes; | ||
146 | else | ||
147 | goto no; | ||
148 | case AR5K_CAP_XR: | ||
149 | if (ah->ah_version == AR5K_AR5212) | ||
150 | goto yes; | ||
151 | else | ||
152 | goto no; | ||
153 | default: | ||
154 | goto no; | ||
155 | } | ||
156 | |||
157 | no: | ||
158 | return -EINVAL; | ||
159 | yes: | ||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * TODO: Following functions should be part of a new function | ||
165 | * set_capability | ||
166 | */ | ||
167 | |||
168 | int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, | ||
169 | u16 assoc_id) | ||
170 | { | ||
171 | ATH5K_TRACE(ah->ah_sc); | ||
172 | |||
173 | if (ah->ah_version == AR5K_AR5210) { | ||
174 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
175 | AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); | ||
176 | return 0; | ||
177 | } | ||
178 | |||
179 | return -EIO; | ||
180 | } | ||
181 | |||
182 | int ath5k_hw_disable_pspoll(struct ath5k_hw *ah) | ||
183 | { | ||
184 | ATH5K_TRACE(ah->ah_sc); | ||
185 | |||
186 | if (ah->ah_version == AR5K_AR5210) { | ||
187 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, | ||
188 | AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | return -EIO; | ||
193 | } | ||
diff --git a/drivers/net/wireless/ath5k/debug.c b/drivers/net/wireless/ath5k/debug.c index 6fa6c8e04ff0..8f92d670f614 100644 --- a/drivers/net/wireless/ath5k/debug.c +++ b/drivers/net/wireless/ath5k/debug.c | |||
@@ -58,8 +58,8 @@ | |||
58 | * THE POSSIBILITY OF SUCH DAMAGES. | 58 | * THE POSSIBILITY OF SUCH DAMAGES. |
59 | */ | 59 | */ |
60 | 60 | ||
61 | #include "debug.h" | ||
62 | #include "base.h" | 61 | #include "base.h" |
62 | #include "debug.h" | ||
63 | 63 | ||
64 | static unsigned int ath5k_debug; | 64 | static unsigned int ath5k_debug; |
65 | module_param_named(debug, ath5k_debug, uint, 0); | 65 | module_param_named(debug, ath5k_debug, uint, 0); |
@@ -525,7 +525,7 @@ ath5k_debug_printrxbuffs(struct ath5k_softc *sc, struct ath5k_hw *ah) | |||
525 | return; | 525 | return; |
526 | 526 | ||
527 | printk(KERN_DEBUG "rx queue %x, link %p\n", | 527 | printk(KERN_DEBUG "rx queue %x, link %p\n", |
528 | ath5k_hw_get_rx_buf(ah), sc->rxlink); | 528 | ath5k_hw_get_rxdp(ah), sc->rxlink); |
529 | 529 | ||
530 | spin_lock_bh(&sc->rxbuflock); | 530 | spin_lock_bh(&sc->rxbuflock); |
531 | list_for_each_entry(bf, &sc->rxbuf, list) { | 531 | list_for_each_entry(bf, &sc->rxbuf, list) { |
diff --git a/drivers/net/wireless/ath5k/desc.c b/drivers/net/wireless/ath5k/desc.c new file mode 100644 index 000000000000..dd1374052ba9 --- /dev/null +++ b/drivers/net/wireless/ath5k/desc.c | |||
@@ -0,0 +1,692 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org> | ||
5 | * | ||
6 | * Permission to use, copy, modify, and distribute this software for any | ||
7 | * purpose with or without fee is hereby granted, provided that the above | ||
8 | * copyright notice and this permission notice appear in all copies. | ||
9 | * | ||
10 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
11 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
12 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
13 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
14 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
15 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
16 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | /******************************\ | ||
21 | Hardware Descriptor Functions | ||
22 | \******************************/ | ||
23 | |||
24 | #include "ath5k.h" | ||
25 | #include "reg.h" | ||
26 | #include "debug.h" | ||
27 | #include "base.h" | ||
28 | |||
29 | /* | ||
30 | * TX Descriptors | ||
31 | */ | ||
32 | |||
33 | /* | ||
34 | * Initialize the 2-word tx control descriptor on 5210/5211 | ||
35 | */ | ||
36 | static int | ||
37 | ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | ||
38 | unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type, | ||
39 | unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, | ||
40 | unsigned int key_index, unsigned int antenna_mode, unsigned int flags, | ||
41 | unsigned int rtscts_rate, unsigned int rtscts_duration) | ||
42 | { | ||
43 | u32 frame_type; | ||
44 | struct ath5k_hw_2w_tx_ctl *tx_ctl; | ||
45 | unsigned int frame_len; | ||
46 | |||
47 | tx_ctl = &desc->ud.ds_tx5210.tx_ctl; | ||
48 | |||
49 | /* | ||
50 | * Validate input | ||
51 | * - Zero retries don't make sense. | ||
52 | * - A zero rate will put the HW into a mode where it continously sends | ||
53 | * noise on the channel, so it is important to avoid this. | ||
54 | */ | ||
55 | if (unlikely(tx_tries0 == 0)) { | ||
56 | ATH5K_ERR(ah->ah_sc, "zero retries\n"); | ||
57 | WARN_ON(1); | ||
58 | return -EINVAL; | ||
59 | } | ||
60 | if (unlikely(tx_rate0 == 0)) { | ||
61 | ATH5K_ERR(ah->ah_sc, "zero rate\n"); | ||
62 | WARN_ON(1); | ||
63 | return -EINVAL; | ||
64 | } | ||
65 | |||
66 | /* Clear descriptor */ | ||
67 | memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc)); | ||
68 | |||
69 | /* Setup control descriptor */ | ||
70 | |||
71 | /* Verify and set frame length */ | ||
72 | |||
73 | /* remove padding we might have added before */ | ||
74 | frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; | ||
75 | |||
76 | if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) | ||
77 | return -EINVAL; | ||
78 | |||
79 | tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; | ||
80 | |||
81 | /* Verify and set buffer length */ | ||
82 | |||
83 | /* NB: beacon's BufLen must be a multiple of 4 bytes */ | ||
84 | if (type == AR5K_PKT_TYPE_BEACON) | ||
85 | pkt_len = roundup(pkt_len, 4); | ||
86 | |||
87 | if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) | ||
88 | return -EINVAL; | ||
89 | |||
90 | tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; | ||
91 | |||
92 | /* | ||
93 | * Verify and set header length | ||
94 | * XXX: I only found that on 5210 code, does it work on 5211 ? | ||
95 | */ | ||
96 | if (ah->ah_version == AR5K_AR5210) { | ||
97 | if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN) | ||
98 | return -EINVAL; | ||
99 | tx_ctl->tx_control_0 |= | ||
100 | AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); | ||
101 | } | ||
102 | |||
103 | /*Diferences between 5210-5211*/ | ||
104 | if (ah->ah_version == AR5K_AR5210) { | ||
105 | switch (type) { | ||
106 | case AR5K_PKT_TYPE_BEACON: | ||
107 | case AR5K_PKT_TYPE_PROBE_RESP: | ||
108 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; | ||
109 | case AR5K_PKT_TYPE_PIFS: | ||
110 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; | ||
111 | default: | ||
112 | frame_type = type /*<< 2 ?*/; | ||
113 | } | ||
114 | |||
115 | tx_ctl->tx_control_0 |= | ||
116 | AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) | | ||
117 | AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); | ||
118 | |||
119 | } else { | ||
120 | tx_ctl->tx_control_0 |= | ||
121 | AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) | | ||
122 | AR5K_REG_SM(antenna_mode, | ||
123 | AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); | ||
124 | tx_ctl->tx_control_1 |= | ||
125 | AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE); | ||
126 | } | ||
127 | #define _TX_FLAGS(_c, _flag) \ | ||
128 | if (flags & AR5K_TXDESC_##_flag) { \ | ||
129 | tx_ctl->tx_control_##_c |= \ | ||
130 | AR5K_2W_TX_DESC_CTL##_c##_##_flag; \ | ||
131 | } | ||
132 | |||
133 | _TX_FLAGS(0, CLRDMASK); | ||
134 | _TX_FLAGS(0, VEOL); | ||
135 | _TX_FLAGS(0, INTREQ); | ||
136 | _TX_FLAGS(0, RTSENA); | ||
137 | _TX_FLAGS(1, NOACK); | ||
138 | |||
139 | #undef _TX_FLAGS | ||
140 | |||
141 | /* | ||
142 | * WEP crap | ||
143 | */ | ||
144 | if (key_index != AR5K_TXKEYIX_INVALID) { | ||
145 | tx_ctl->tx_control_0 |= | ||
146 | AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; | ||
147 | tx_ctl->tx_control_1 |= | ||
148 | AR5K_REG_SM(key_index, | ||
149 | AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * RTS/CTS Duration [5210 ?] | ||
154 | */ | ||
155 | if ((ah->ah_version == AR5K_AR5210) && | ||
156 | (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) | ||
157 | tx_ctl->tx_control_1 |= rtscts_duration & | ||
158 | AR5K_2W_TX_DESC_CTL1_RTS_DURATION; | ||
159 | |||
160 | return 0; | ||
161 | } | ||
162 | |||
163 | /* | ||
164 | * Initialize the 4-word tx control descriptor on 5212 | ||
165 | */ | ||
166 | static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | ||
167 | struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, | ||
168 | enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, | ||
169 | unsigned int tx_tries0, unsigned int key_index, | ||
170 | unsigned int antenna_mode, unsigned int flags, | ||
171 | unsigned int rtscts_rate, | ||
172 | unsigned int rtscts_duration) | ||
173 | { | ||
174 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | ||
175 | unsigned int frame_len; | ||
176 | |||
177 | ATH5K_TRACE(ah->ah_sc); | ||
178 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | ||
179 | |||
180 | /* | ||
181 | * Validate input | ||
182 | * - Zero retries don't make sense. | ||
183 | * - A zero rate will put the HW into a mode where it continously sends | ||
184 | * noise on the channel, so it is important to avoid this. | ||
185 | */ | ||
186 | if (unlikely(tx_tries0 == 0)) { | ||
187 | ATH5K_ERR(ah->ah_sc, "zero retries\n"); | ||
188 | WARN_ON(1); | ||
189 | return -EINVAL; | ||
190 | } | ||
191 | if (unlikely(tx_rate0 == 0)) { | ||
192 | ATH5K_ERR(ah->ah_sc, "zero rate\n"); | ||
193 | WARN_ON(1); | ||
194 | return -EINVAL; | ||
195 | } | ||
196 | |||
197 | /* Clear descriptor */ | ||
198 | memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); | ||
199 | |||
200 | /* Setup control descriptor */ | ||
201 | |||
202 | /* Verify and set frame length */ | ||
203 | |||
204 | /* remove padding we might have added before */ | ||
205 | frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; | ||
206 | |||
207 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) | ||
208 | return -EINVAL; | ||
209 | |||
210 | tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; | ||
211 | |||
212 | /* Verify and set buffer length */ | ||
213 | |||
214 | /* NB: beacon's BufLen must be a multiple of 4 bytes */ | ||
215 | if (type == AR5K_PKT_TYPE_BEACON) | ||
216 | pkt_len = roundup(pkt_len, 4); | ||
217 | |||
218 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) | ||
219 | return -EINVAL; | ||
220 | |||
221 | tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; | ||
222 | |||
223 | tx_ctl->tx_control_0 |= | ||
224 | AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | | ||
225 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); | ||
226 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, | ||
227 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); | ||
228 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, | ||
229 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); | ||
230 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
231 | |||
232 | #define _TX_FLAGS(_c, _flag) \ | ||
233 | if (flags & AR5K_TXDESC_##_flag) { \ | ||
234 | tx_ctl->tx_control_##_c |= \ | ||
235 | AR5K_4W_TX_DESC_CTL##_c##_##_flag; \ | ||
236 | } | ||
237 | |||
238 | _TX_FLAGS(0, CLRDMASK); | ||
239 | _TX_FLAGS(0, VEOL); | ||
240 | _TX_FLAGS(0, INTREQ); | ||
241 | _TX_FLAGS(0, RTSENA); | ||
242 | _TX_FLAGS(0, CTSENA); | ||
243 | _TX_FLAGS(1, NOACK); | ||
244 | |||
245 | #undef _TX_FLAGS | ||
246 | |||
247 | /* | ||
248 | * WEP crap | ||
249 | */ | ||
250 | if (key_index != AR5K_TXKEYIX_INVALID) { | ||
251 | tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; | ||
252 | tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, | ||
253 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); | ||
254 | } | ||
255 | |||
256 | /* | ||
257 | * RTS/CTS | ||
258 | */ | ||
259 | if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) { | ||
260 | if ((flags & AR5K_TXDESC_RTSENA) && | ||
261 | (flags & AR5K_TXDESC_CTSENA)) | ||
262 | return -EINVAL; | ||
263 | tx_ctl->tx_control_2 |= rtscts_duration & | ||
264 | AR5K_4W_TX_DESC_CTL2_RTS_DURATION; | ||
265 | tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, | ||
266 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); | ||
267 | } | ||
268 | |||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | /* | ||
273 | * Initialize a 4-word multi rate retry tx control descriptor on 5212 | ||
274 | */ | ||
275 | static int | ||
276 | ath5k_hw_setup_mrr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | ||
277 | unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, | ||
278 | u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) | ||
279 | { | ||
280 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | ||
281 | |||
282 | /* | ||
283 | * Rates can be 0 as long as the retry count is 0 too. | ||
284 | * A zero rate and nonzero retry count will put the HW into a mode where | ||
285 | * it continously sends noise on the channel, so it is important to | ||
286 | * avoid this. | ||
287 | */ | ||
288 | if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) || | ||
289 | (tx_rate2 == 0 && tx_tries2 != 0) || | ||
290 | (tx_rate3 == 0 && tx_tries3 != 0))) { | ||
291 | ATH5K_ERR(ah->ah_sc, "zero rate\n"); | ||
292 | WARN_ON(1); | ||
293 | return -EINVAL; | ||
294 | } | ||
295 | |||
296 | if (ah->ah_version == AR5K_AR5212) { | ||
297 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | ||
298 | |||
299 | #define _XTX_TRIES(_n) \ | ||
300 | if (tx_tries##_n) { \ | ||
301 | tx_ctl->tx_control_2 |= \ | ||
302 | AR5K_REG_SM(tx_tries##_n, \ | ||
303 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \ | ||
304 | tx_ctl->tx_control_3 |= \ | ||
305 | AR5K_REG_SM(tx_rate##_n, \ | ||
306 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \ | ||
307 | } | ||
308 | |||
309 | _XTX_TRIES(1); | ||
310 | _XTX_TRIES(2); | ||
311 | _XTX_TRIES(3); | ||
312 | |||
313 | #undef _XTX_TRIES | ||
314 | |||
315 | return 1; | ||
316 | } | ||
317 | |||
318 | return 0; | ||
319 | } | ||
320 | |||
321 | /* no mrr support for cards older than 5212 */ | ||
322 | static int | ||
323 | ath5k_hw_setup_no_mrr(struct ath5k_hw *ah, struct ath5k_desc *desc, | ||
324 | unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, | ||
325 | u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) | ||
326 | { | ||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | /* | ||
331 | * Proccess the tx status descriptor on 5210/5211 | ||
332 | */ | ||
333 | static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | ||
334 | struct ath5k_desc *desc, struct ath5k_tx_status *ts) | ||
335 | { | ||
336 | struct ath5k_hw_2w_tx_ctl *tx_ctl; | ||
337 | struct ath5k_hw_tx_status *tx_status; | ||
338 | |||
339 | ATH5K_TRACE(ah->ah_sc); | ||
340 | |||
341 | tx_ctl = &desc->ud.ds_tx5210.tx_ctl; | ||
342 | tx_status = &desc->ud.ds_tx5210.tx_stat; | ||
343 | |||
344 | /* No frame has been send or error */ | ||
345 | if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) | ||
346 | return -EINPROGRESS; | ||
347 | |||
348 | /* | ||
349 | * Get descriptor status | ||
350 | */ | ||
351 | ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, | ||
352 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | ||
353 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | ||
354 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | ||
355 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | ||
356 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | ||
357 | /*TODO: ts->ts_virtcol + test*/ | ||
358 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | ||
359 | AR5K_DESC_TX_STATUS1_SEQ_NUM); | ||
360 | ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, | ||
361 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | ||
362 | ts->ts_antenna = 1; | ||
363 | ts->ts_status = 0; | ||
364 | ts->ts_rate[0] = AR5K_REG_MS(tx_ctl->tx_control_0, | ||
365 | AR5K_2W_TX_DESC_CTL0_XMIT_RATE); | ||
366 | ts->ts_retry[0] = ts->ts_longretry; | ||
367 | ts->ts_final_idx = 0; | ||
368 | |||
369 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | ||
370 | if (tx_status->tx_status_0 & | ||
371 | AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) | ||
372 | ts->ts_status |= AR5K_TXERR_XRETRY; | ||
373 | |||
374 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) | ||
375 | ts->ts_status |= AR5K_TXERR_FIFO; | ||
376 | |||
377 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) | ||
378 | ts->ts_status |= AR5K_TXERR_FILT; | ||
379 | } | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | /* | ||
385 | * Proccess a tx status descriptor on 5212 | ||
386 | */ | ||
387 | static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, | ||
388 | struct ath5k_desc *desc, struct ath5k_tx_status *ts) | ||
389 | { | ||
390 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | ||
391 | struct ath5k_hw_tx_status *tx_status; | ||
392 | |||
393 | ATH5K_TRACE(ah->ah_sc); | ||
394 | |||
395 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | ||
396 | tx_status = &desc->ud.ds_tx5212.tx_stat; | ||
397 | |||
398 | /* No frame has been send or error */ | ||
399 | if (unlikely(!(tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE))) | ||
400 | return -EINPROGRESS; | ||
401 | |||
402 | /* | ||
403 | * Get descriptor status | ||
404 | */ | ||
405 | ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, | ||
406 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | ||
407 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | ||
408 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | ||
409 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | ||
410 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | ||
411 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | ||
412 | AR5K_DESC_TX_STATUS1_SEQ_NUM); | ||
413 | ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, | ||
414 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | ||
415 | ts->ts_antenna = (tx_status->tx_status_1 & | ||
416 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; | ||
417 | ts->ts_status = 0; | ||
418 | |||
419 | ts->ts_final_idx = AR5K_REG_MS(tx_status->tx_status_1, | ||
420 | AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX); | ||
421 | |||
422 | /* The longretry counter has the number of un-acked retries | ||
423 | * for the final rate. To get the total number of retries | ||
424 | * we have to add the retry counters for the other rates | ||
425 | * as well | ||
426 | */ | ||
427 | ts->ts_retry[ts->ts_final_idx] = ts->ts_longretry; | ||
428 | switch (ts->ts_final_idx) { | ||
429 | case 3: | ||
430 | ts->ts_rate[3] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
431 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); | ||
432 | |||
433 | ts->ts_retry[2] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
434 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); | ||
435 | ts->ts_longretry += ts->ts_retry[2]; | ||
436 | /* fall through */ | ||
437 | case 2: | ||
438 | ts->ts_rate[2] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
439 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); | ||
440 | |||
441 | ts->ts_retry[1] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
442 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
443 | ts->ts_longretry += ts->ts_retry[1]; | ||
444 | /* fall through */ | ||
445 | case 1: | ||
446 | ts->ts_rate[1] = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
447 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); | ||
448 | |||
449 | ts->ts_retry[0] = AR5K_REG_MS(tx_ctl->tx_control_2, | ||
450 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
451 | ts->ts_longretry += ts->ts_retry[0]; | ||
452 | /* fall through */ | ||
453 | case 0: | ||
454 | ts->ts_rate[0] = tx_ctl->tx_control_3 & | ||
455 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
456 | break; | ||
457 | } | ||
458 | |||
459 | /* TX error */ | ||
460 | if (!(tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK)) { | ||
461 | if (tx_status->tx_status_0 & | ||
462 | AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) | ||
463 | ts->ts_status |= AR5K_TXERR_XRETRY; | ||
464 | |||
465 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) | ||
466 | ts->ts_status |= AR5K_TXERR_FIFO; | ||
467 | |||
468 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) | ||
469 | ts->ts_status |= AR5K_TXERR_FILT; | ||
470 | } | ||
471 | |||
472 | return 0; | ||
473 | } | ||
474 | |||
475 | /* | ||
476 | * RX Descriptors | ||
477 | */ | ||
478 | |||
479 | /* | ||
480 | * Initialize an rx control descriptor | ||
481 | */ | ||
482 | static int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | ||
483 | u32 size, unsigned int flags) | ||
484 | { | ||
485 | struct ath5k_hw_rx_ctl *rx_ctl; | ||
486 | |||
487 | ATH5K_TRACE(ah->ah_sc); | ||
488 | rx_ctl = &desc->ud.ds_rx.rx_ctl; | ||
489 | |||
490 | /* | ||
491 | * Clear the descriptor | ||
492 | * If we don't clean the status descriptor, | ||
493 | * while scanning we get too many results, | ||
494 | * most of them virtual, after some secs | ||
495 | * of scanning system hangs. M.F. | ||
496 | */ | ||
497 | memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); | ||
498 | |||
499 | /* Setup descriptor */ | ||
500 | rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; | ||
501 | if (unlikely(rx_ctl->rx_control_1 != size)) | ||
502 | return -EINVAL; | ||
503 | |||
504 | if (flags & AR5K_RXDESC_INTREQ) | ||
505 | rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; | ||
506 | |||
507 | return 0; | ||
508 | } | ||
509 | |||
510 | /* | ||
511 | * Proccess the rx status descriptor on 5210/5211 | ||
512 | */ | ||
513 | static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | ||
514 | struct ath5k_desc *desc, struct ath5k_rx_status *rs) | ||
515 | { | ||
516 | struct ath5k_hw_rx_status *rx_status; | ||
517 | |||
518 | rx_status = &desc->ud.ds_rx.u.rx_stat; | ||
519 | |||
520 | /* No frame received / not ready */ | ||
521 | if (unlikely(!(rx_status->rx_status_1 & | ||
522 | AR5K_5210_RX_DESC_STATUS1_DONE))) | ||
523 | return -EINPROGRESS; | ||
524 | |||
525 | /* | ||
526 | * Frame receive status | ||
527 | */ | ||
528 | rs->rs_datalen = rx_status->rx_status_0 & | ||
529 | AR5K_5210_RX_DESC_STATUS0_DATA_LEN; | ||
530 | rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, | ||
531 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); | ||
532 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | ||
533 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); | ||
534 | rs->rs_antenna = rx_status->rx_status_0 & | ||
535 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA; | ||
536 | rs->rs_more = rx_status->rx_status_0 & | ||
537 | AR5K_5210_RX_DESC_STATUS0_MORE; | ||
538 | /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ | ||
539 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | ||
540 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | ||
541 | rs->rs_status = 0; | ||
542 | rs->rs_phyerr = 0; | ||
543 | |||
544 | /* | ||
545 | * Key table status | ||
546 | */ | ||
547 | if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID) | ||
548 | rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, | ||
549 | AR5K_5210_RX_DESC_STATUS1_KEY_INDEX); | ||
550 | else | ||
551 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; | ||
552 | |||
553 | /* | ||
554 | * Receive/descriptor errors | ||
555 | */ | ||
556 | if (!(rx_status->rx_status_1 & | ||
557 | AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { | ||
558 | if (rx_status->rx_status_1 & | ||
559 | AR5K_5210_RX_DESC_STATUS1_CRC_ERROR) | ||
560 | rs->rs_status |= AR5K_RXERR_CRC; | ||
561 | |||
562 | if (rx_status->rx_status_1 & | ||
563 | AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN) | ||
564 | rs->rs_status |= AR5K_RXERR_FIFO; | ||
565 | |||
566 | if (rx_status->rx_status_1 & | ||
567 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { | ||
568 | rs->rs_status |= AR5K_RXERR_PHY; | ||
569 | rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, | ||
570 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); | ||
571 | } | ||
572 | |||
573 | if (rx_status->rx_status_1 & | ||
574 | AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) | ||
575 | rs->rs_status |= AR5K_RXERR_DECRYPT; | ||
576 | } | ||
577 | |||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | /* | ||
582 | * Proccess the rx status descriptor on 5212 | ||
583 | */ | ||
584 | static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | ||
585 | struct ath5k_desc *desc, struct ath5k_rx_status *rs) | ||
586 | { | ||
587 | struct ath5k_hw_rx_status *rx_status; | ||
588 | struct ath5k_hw_rx_error *rx_err; | ||
589 | |||
590 | ATH5K_TRACE(ah->ah_sc); | ||
591 | rx_status = &desc->ud.ds_rx.u.rx_stat; | ||
592 | |||
593 | /* Overlay on error */ | ||
594 | rx_err = &desc->ud.ds_rx.u.rx_err; | ||
595 | |||
596 | /* No frame received / not ready */ | ||
597 | if (unlikely(!(rx_status->rx_status_1 & | ||
598 | AR5K_5212_RX_DESC_STATUS1_DONE))) | ||
599 | return -EINPROGRESS; | ||
600 | |||
601 | /* | ||
602 | * Frame receive status | ||
603 | */ | ||
604 | rs->rs_datalen = rx_status->rx_status_0 & | ||
605 | AR5K_5212_RX_DESC_STATUS0_DATA_LEN; | ||
606 | rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, | ||
607 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); | ||
608 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | ||
609 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); | ||
610 | rs->rs_antenna = rx_status->rx_status_0 & | ||
611 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA; | ||
612 | rs->rs_more = rx_status->rx_status_0 & | ||
613 | AR5K_5212_RX_DESC_STATUS0_MORE; | ||
614 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | ||
615 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | ||
616 | rs->rs_status = 0; | ||
617 | rs->rs_phyerr = 0; | ||
618 | |||
619 | /* | ||
620 | * Key table status | ||
621 | */ | ||
622 | if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) | ||
623 | rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, | ||
624 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); | ||
625 | else | ||
626 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; | ||
627 | |||
628 | /* | ||
629 | * Receive/descriptor errors | ||
630 | */ | ||
631 | if (!(rx_status->rx_status_1 & | ||
632 | AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK)) { | ||
633 | if (rx_status->rx_status_1 & | ||
634 | AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) | ||
635 | rs->rs_status |= AR5K_RXERR_CRC; | ||
636 | |||
637 | if (rx_status->rx_status_1 & | ||
638 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { | ||
639 | rs->rs_status |= AR5K_RXERR_PHY; | ||
640 | rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, | ||
641 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); | ||
642 | } | ||
643 | |||
644 | if (rx_status->rx_status_1 & | ||
645 | AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) | ||
646 | rs->rs_status |= AR5K_RXERR_DECRYPT; | ||
647 | |||
648 | if (rx_status->rx_status_1 & | ||
649 | AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) | ||
650 | rs->rs_status |= AR5K_RXERR_MIC; | ||
651 | } | ||
652 | |||
653 | return 0; | ||
654 | } | ||
655 | |||
656 | /* | ||
657 | * Init function pointers inside ath5k_hw struct | ||
658 | */ | ||
659 | int ath5k_hw_init_desc_functions(struct ath5k_hw *ah) | ||
660 | { | ||
661 | |||
662 | if (ah->ah_version != AR5K_AR5210 && | ||
663 | ah->ah_version != AR5K_AR5211 && | ||
664 | ah->ah_version != AR5K_AR5212) | ||
665 | return -ENOTSUPP; | ||
666 | |||
667 | /* XXX: What is this magic value and where is it used ? */ | ||
668 | if (ah->ah_version == AR5K_AR5212) | ||
669 | ah->ah_magic = AR5K_EEPROM_MAGIC_5212; | ||
670 | else if (ah->ah_version == AR5K_AR5211) | ||
671 | ah->ah_magic = AR5K_EEPROM_MAGIC_5211; | ||
672 | |||
673 | if (ah->ah_version == AR5K_AR5212) { | ||
674 | ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; | ||
675 | ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; | ||
676 | ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_mrr_tx_desc; | ||
677 | ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status; | ||
678 | } else { | ||
679 | ah->ah_setup_rx_desc = ath5k_hw_setup_rx_desc; | ||
680 | ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; | ||
681 | ah->ah_setup_mrr_tx_desc = ath5k_hw_setup_no_mrr; | ||
682 | ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; | ||
683 | } | ||
684 | |||
685 | if (ah->ah_version == AR5K_AR5212) | ||
686 | ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; | ||
687 | else if (ah->ah_version <= AR5K_AR5211) | ||
688 | ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; | ||
689 | |||
690 | return 0; | ||
691 | } | ||
692 | |||
diff --git a/drivers/net/wireless/ath5k/hw.h b/drivers/net/wireless/ath5k/desc.h index 64fca8dcb386..56158c804e3e 100644 --- a/drivers/net/wireless/ath5k/hw.h +++ b/drivers/net/wireless/ath5k/desc.h | |||
@@ -1,8 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> | 2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> |
3 | * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com> | 3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> |
4 | * Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org> | ||
5 | * Copyright (c) 2007 Luis Rodriguez <mcgrof@winlab.rutgers.edu> | ||
6 | * | 4 | * |
7 | * Permission to use, copy, modify, and distribute this software for any | 5 | * Permission to use, copy, modify, and distribute this software for any |
8 | * purpose with or without fee is hereby granted, provided that the above | 6 | * purpose with or without fee is hereby granted, provided that the above |
@@ -15,159 +13,9 @@ | |||
15 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | 13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
16 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | 14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
17 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | * | ||
18 | */ | 17 | */ |
19 | 18 | ||
20 | #include <linux/delay.h> | ||
21 | |||
22 | /* | ||
23 | * Gain settings | ||
24 | */ | ||
25 | |||
26 | enum ath5k_rfgain { | ||
27 | AR5K_RFGAIN_INACTIVE = 0, | ||
28 | AR5K_RFGAIN_READ_REQUESTED, | ||
29 | AR5K_RFGAIN_NEED_CHANGE, | ||
30 | }; | ||
31 | |||
32 | #define AR5K_GAIN_CRN_FIX_BITS_5111 4 | ||
33 | #define AR5K_GAIN_CRN_FIX_BITS_5112 7 | ||
34 | #define AR5K_GAIN_CRN_MAX_FIX_BITS AR5K_GAIN_CRN_FIX_BITS_5112 | ||
35 | #define AR5K_GAIN_DYN_ADJUST_HI_MARGIN 15 | ||
36 | #define AR5K_GAIN_DYN_ADJUST_LO_MARGIN 20 | ||
37 | #define AR5K_GAIN_CCK_PROBE_CORR 5 | ||
38 | #define AR5K_GAIN_CCK_OFDM_GAIN_DELTA 15 | ||
39 | #define AR5K_GAIN_STEP_COUNT 10 | ||
40 | #define AR5K_GAIN_PARAM_TX_CLIP 0 | ||
41 | #define AR5K_GAIN_PARAM_PD_90 1 | ||
42 | #define AR5K_GAIN_PARAM_PD_84 2 | ||
43 | #define AR5K_GAIN_PARAM_GAIN_SEL 3 | ||
44 | #define AR5K_GAIN_PARAM_MIX_ORN 0 | ||
45 | #define AR5K_GAIN_PARAM_PD_138 1 | ||
46 | #define AR5K_GAIN_PARAM_PD_137 2 | ||
47 | #define AR5K_GAIN_PARAM_PD_136 3 | ||
48 | #define AR5K_GAIN_PARAM_PD_132 4 | ||
49 | #define AR5K_GAIN_PARAM_PD_131 5 | ||
50 | #define AR5K_GAIN_PARAM_PD_130 6 | ||
51 | #define AR5K_GAIN_CHECK_ADJUST(_g) \ | ||
52 | ((_g)->g_current <= (_g)->g_low || (_g)->g_current >= (_g)->g_high) | ||
53 | |||
54 | struct ath5k_gain_opt_step { | ||
55 | s16 gos_param[AR5K_GAIN_CRN_MAX_FIX_BITS]; | ||
56 | s32 gos_gain; | ||
57 | }; | ||
58 | |||
59 | struct ath5k_gain { | ||
60 | u32 g_step_idx; | ||
61 | u32 g_current; | ||
62 | u32 g_target; | ||
63 | u32 g_low; | ||
64 | u32 g_high; | ||
65 | u32 g_f_corr; | ||
66 | u32 g_active; | ||
67 | const struct ath5k_gain_opt_step *g_step; | ||
68 | }; | ||
69 | |||
70 | |||
71 | /* | ||
72 | * HW SPECIFIC STRUCTS | ||
73 | */ | ||
74 | |||
75 | /* Some EEPROM defines */ | ||
76 | #define AR5K_EEPROM_EEP_SCALE 100 | ||
77 | #define AR5K_EEPROM_EEP_DELTA 10 | ||
78 | #define AR5K_EEPROM_N_MODES 3 | ||
79 | #define AR5K_EEPROM_N_5GHZ_CHAN 10 | ||
80 | #define AR5K_EEPROM_N_2GHZ_CHAN 3 | ||
81 | #define AR5K_EEPROM_MAX_CHAN 10 | ||
82 | #define AR5K_EEPROM_N_PCDAC 11 | ||
83 | #define AR5K_EEPROM_N_TEST_FREQ 8 | ||
84 | #define AR5K_EEPROM_N_EDGES 8 | ||
85 | #define AR5K_EEPROM_N_INTERCEPTS 11 | ||
86 | #define AR5K_EEPROM_FREQ_M(_v) AR5K_EEPROM_OFF(_v, 0x7f, 0xff) | ||
87 | #define AR5K_EEPROM_PCDAC_M 0x3f | ||
88 | #define AR5K_EEPROM_PCDAC_START 1 | ||
89 | #define AR5K_EEPROM_PCDAC_STOP 63 | ||
90 | #define AR5K_EEPROM_PCDAC_STEP 1 | ||
91 | #define AR5K_EEPROM_NON_EDGE_M 0x40 | ||
92 | #define AR5K_EEPROM_CHANNEL_POWER 8 | ||
93 | #define AR5K_EEPROM_N_OBDB 4 | ||
94 | #define AR5K_EEPROM_OBDB_DIS 0xffff | ||
95 | #define AR5K_EEPROM_CHANNEL_DIS 0xff | ||
96 | #define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10) | ||
97 | #define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32) | ||
98 | #define AR5K_EEPROM_MAX_CTLS 32 | ||
99 | #define AR5K_EEPROM_N_XPD_PER_CHANNEL 4 | ||
100 | #define AR5K_EEPROM_N_XPD0_POINTS 4 | ||
101 | #define AR5K_EEPROM_N_XPD3_POINTS 3 | ||
102 | #define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35 | ||
103 | #define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55 | ||
104 | #define AR5K_EEPROM_POWER_M 0x3f | ||
105 | #define AR5K_EEPROM_POWER_MIN 0 | ||
106 | #define AR5K_EEPROM_POWER_MAX 3150 | ||
107 | #define AR5K_EEPROM_POWER_STEP 50 | ||
108 | #define AR5K_EEPROM_POWER_TABLE_SIZE 64 | ||
109 | #define AR5K_EEPROM_N_POWER_LOC_11B 4 | ||
110 | #define AR5K_EEPROM_N_POWER_LOC_11G 6 | ||
111 | #define AR5K_EEPROM_I_GAIN 10 | ||
112 | #define AR5K_EEPROM_CCK_OFDM_DELTA 15 | ||
113 | #define AR5K_EEPROM_N_IQ_CAL 2 | ||
114 | |||
115 | /* Struct to hold EEPROM calibration data */ | ||
116 | struct ath5k_eeprom_info { | ||
117 | u16 ee_magic; | ||
118 | u16 ee_protect; | ||
119 | u16 ee_regdomain; | ||
120 | u16 ee_version; | ||
121 | u16 ee_header; | ||
122 | u16 ee_ant_gain; | ||
123 | u16 ee_misc0; | ||
124 | u16 ee_misc1; | ||
125 | u16 ee_cck_ofdm_gain_delta; | ||
126 | u16 ee_cck_ofdm_power_delta; | ||
127 | u16 ee_scaled_cck_delta; | ||
128 | |||
129 | /* Used for tx thermal adjustment (eeprom_init, rfregs) */ | ||
130 | u16 ee_tx_clip; | ||
131 | u16 ee_pwd_84; | ||
132 | u16 ee_pwd_90; | ||
133 | u16 ee_gain_select; | ||
134 | |||
135 | /* RF Calibration settings (reset, rfregs) */ | ||
136 | u16 ee_i_cal[AR5K_EEPROM_N_MODES]; | ||
137 | u16 ee_q_cal[AR5K_EEPROM_N_MODES]; | ||
138 | u16 ee_fixed_bias[AR5K_EEPROM_N_MODES]; | ||
139 | u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES]; | ||
140 | u16 ee_xr_power[AR5K_EEPROM_N_MODES]; | ||
141 | u16 ee_switch_settling[AR5K_EEPROM_N_MODES]; | ||
142 | u16 ee_ant_tx_rx[AR5K_EEPROM_N_MODES]; | ||
143 | u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC]; | ||
144 | u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; | ||
145 | u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; | ||
146 | u16 ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES]; | ||
147 | u16 ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES]; | ||
148 | u16 ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES]; | ||
149 | u16 ee_thr_62[AR5K_EEPROM_N_MODES]; | ||
150 | u16 ee_xlna_gain[AR5K_EEPROM_N_MODES]; | ||
151 | u16 ee_xpd[AR5K_EEPROM_N_MODES]; | ||
152 | u16 ee_x_gain[AR5K_EEPROM_N_MODES]; | ||
153 | u16 ee_i_gain[AR5K_EEPROM_N_MODES]; | ||
154 | u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES]; | ||
155 | |||
156 | /* Unused */ | ||
157 | u16 ee_false_detect[AR5K_EEPROM_N_MODES]; | ||
158 | u16 ee_cal_pier[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_2GHZ_CHAN]; | ||
159 | u16 ee_channel[AR5K_EEPROM_N_MODES][AR5K_EEPROM_MAX_CHAN]; /*empty*/ | ||
160 | |||
161 | /* Conformance test limits (Unused) */ | ||
162 | u16 ee_ctls; | ||
163 | u16 ee_ctl[AR5K_EEPROM_MAX_CTLS]; | ||
164 | |||
165 | /* Noise Floor Calibration settings */ | ||
166 | s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES]; | ||
167 | s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES]; | ||
168 | s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES]; | ||
169 | }; | ||
170 | |||
171 | /* | 19 | /* |
172 | * Internal RX/TX descriptor structures | 20 | * Internal RX/TX descriptor structures |
173 | * (rX: reserved fields possibily used by future versions of the ar5k chipset) | 21 | * (rX: reserved fields possibily used by future versions of the ar5k chipset) |
@@ -178,14 +26,15 @@ struct ath5k_eeprom_info { | |||
178 | */ | 26 | */ |
179 | struct ath5k_hw_rx_ctl { | 27 | struct ath5k_hw_rx_ctl { |
180 | u32 rx_control_0; /* RX control word 0 */ | 28 | u32 rx_control_0; /* RX control word 0 */ |
29 | u32 rx_control_1; /* RX control word 1 */ | ||
30 | } __packed; | ||
181 | 31 | ||
32 | /* RX control word 0 field/sflags */ | ||
182 | #define AR5K_DESC_RX_CTL0 0x00000000 | 33 | #define AR5K_DESC_RX_CTL0 0x00000000 |
183 | 34 | ||
184 | u32 rx_control_1; /* RX control word 1 */ | 35 | /* RX control word 1 fields/flags */ |
185 | |||
186 | #define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff | 36 | #define AR5K_DESC_RX_CTL1_BUF_LEN 0x00000fff |
187 | #define AR5K_DESC_RX_CTL1_INTREQ 0x00002000 | 37 | #define AR5K_DESC_RX_CTL1_INTREQ 0x00002000 |
188 | } __packed; | ||
189 | 38 | ||
190 | /* | 39 | /* |
191 | * common hardware RX status descriptor | 40 | * common hardware RX status descriptor |
@@ -197,6 +46,7 @@ struct ath5k_hw_rx_status { | |||
197 | } __packed; | 46 | } __packed; |
198 | 47 | ||
199 | /* 5210/5211 */ | 48 | /* 5210/5211 */ |
49 | /* RX status word 0 fields/flags */ | ||
200 | #define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff | 50 | #define AR5K_5210_RX_DESC_STATUS0_DATA_LEN 0x00000fff |
201 | #define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 | 51 | #define AR5K_5210_RX_DESC_STATUS0_MORE 0x00001000 |
202 | #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 | 52 | #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE 0x00078000 |
@@ -205,6 +55,8 @@ struct ath5k_hw_rx_status { | |||
205 | #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19 | 55 | #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 19 |
206 | #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000 | 56 | #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA 0x38000000 |
207 | #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27 | 57 | #define AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 27 |
58 | |||
59 | /* RX status word 1 fields/flags */ | ||
208 | #define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 | 60 | #define AR5K_5210_RX_DESC_STATUS1_DONE 0x00000001 |
209 | #define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 | 61 | #define AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 |
210 | #define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 | 62 | #define AR5K_5210_RX_DESC_STATUS1_CRC_ERROR 0x00000004 |
@@ -220,6 +72,7 @@ struct ath5k_hw_rx_status { | |||
220 | #define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 | 72 | #define AR5K_5210_RX_DESC_STATUS1_KEY_CACHE_MISS 0x10000000 |
221 | 73 | ||
222 | /* 5212 */ | 74 | /* 5212 */ |
75 | /* RX status word 0 fields/flags */ | ||
223 | #define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff | 76 | #define AR5K_5212_RX_DESC_STATUS0_DATA_LEN 0x00000fff |
224 | #define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 | 77 | #define AR5K_5212_RX_DESC_STATUS0_MORE 0x00001000 |
225 | #define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 | 78 | #define AR5K_5212_RX_DESC_STATUS0_DECOMP_CRC_ERROR 0x00002000 |
@@ -229,6 +82,8 @@ struct ath5k_hw_rx_status { | |||
229 | #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20 | 82 | #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL_S 20 |
230 | #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 | 83 | #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA 0xf0000000 |
231 | #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28 | 84 | #define AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA_S 28 |
85 | |||
86 | /* RX status word 1 fields/flags */ | ||
232 | #define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 | 87 | #define AR5K_5212_RX_DESC_STATUS1_DONE 0x00000001 |
233 | #define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 | 88 | #define AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK 0x00000002 |
234 | #define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 | 89 | #define AR5K_5212_RX_DESC_STATUS1_CRC_ERROR 0x00000004 |
@@ -246,16 +101,18 @@ struct ath5k_hw_rx_status { | |||
246 | * common hardware RX error descriptor | 101 | * common hardware RX error descriptor |
247 | */ | 102 | */ |
248 | struct ath5k_hw_rx_error { | 103 | struct ath5k_hw_rx_error { |
249 | u32 rx_error_0; /* RX error word 0 */ | 104 | u32 rx_error_0; /* RX status word 0 */ |
105 | u32 rx_error_1; /* RX status word 1 */ | ||
106 | } __packed; | ||
250 | 107 | ||
108 | /* RX error word 0 fields/flags */ | ||
251 | #define AR5K_RX_DESC_ERROR0 0x00000000 | 109 | #define AR5K_RX_DESC_ERROR0 0x00000000 |
252 | 110 | ||
253 | u32 rx_error_1; /* RX error word 1 */ | 111 | /* RX error word 1 fields/flags */ |
254 | |||
255 | #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 | 112 | #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE 0x0000ff00 |
256 | #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 | 113 | #define AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE_S 8 |
257 | } __packed; | ||
258 | 114 | ||
115 | /* PHY Error codes */ | ||
259 | #define AR5K_DESC_RX_PHY_ERROR_NONE 0x00 | 116 | #define AR5K_DESC_RX_PHY_ERROR_NONE 0x00 |
260 | #define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20 | 117 | #define AR5K_DESC_RX_PHY_ERROR_TIMING 0x20 |
261 | #define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40 | 118 | #define AR5K_DESC_RX_PHY_ERROR_PARITY 0x40 |
@@ -270,7 +127,10 @@ struct ath5k_hw_rx_error { | |||
270 | */ | 127 | */ |
271 | struct ath5k_hw_2w_tx_ctl { | 128 | struct ath5k_hw_2w_tx_ctl { |
272 | u32 tx_control_0; /* TX control word 0 */ | 129 | u32 tx_control_0; /* TX control word 0 */ |
130 | u32 tx_control_1; /* TX control word 1 */ | ||
131 | } __packed; | ||
273 | 132 | ||
133 | /* TX control word 0 fields/flags */ | ||
274 | #define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff | 134 | #define AR5K_2W_TX_DESC_CTL0_FRAME_LEN 0x00000fff |
275 | #define AR5K_2W_TX_DESC_CTL0_HEADER_LEN 0x0003f000 /*[5210 ?]*/ | 135 | #define AR5K_2W_TX_DESC_CTL0_HEADER_LEN 0x0003f000 /*[5210 ?]*/ |
276 | #define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S 12 | 136 | #define AR5K_2W_TX_DESC_CTL0_HEADER_LEN_S 12 |
@@ -284,29 +144,34 @@ struct ath5k_hw_2w_tx_ctl { | |||
284 | #define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S 26 | 144 | #define AR5K_2W_TX_DESC_CTL0_FRAME_TYPE_S 26 |
285 | #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000 | 145 | #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 0x02000000 |
286 | #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000 | 146 | #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211 0x1e000000 |
287 | #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT (ah->ah_version == AR5K_AR5210 ? \ | 147 | |
288 | AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \ | 148 | #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT \ |
289 | AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211) | 149 | (ah->ah_version == AR5K_AR5210 ? \ |
150 | AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5210 : \ | ||
151 | AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_5211) | ||
152 | |||
290 | #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 | 153 | #define AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT_S 25 |
291 | #define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000 | 154 | #define AR5K_2W_TX_DESC_CTL0_INTREQ 0x20000000 |
292 | #define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 | 155 | #define AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID 0x40000000 |
293 | 156 | ||
294 | u32 tx_control_1; /* TX control word 1 */ | 157 | /* TX control word 1 fields/flags */ |
295 | |||
296 | #define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff | 158 | #define AR5K_2W_TX_DESC_CTL1_BUF_LEN 0x00000fff |
297 | #define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000 | 159 | #define AR5K_2W_TX_DESC_CTL1_MORE 0x00001000 |
298 | #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 0x0007e000 | 160 | #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 0x0007e000 |
299 | #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211 0x000fe000 | 161 | #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211 0x000fe000 |
300 | #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX (ah->ah_version == AR5K_AR5210 ? \ | 162 | |
301 | AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 : \ | 163 | #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX \ |
302 | AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211) | 164 | (ah->ah_version == AR5K_AR5210 ? \ |
165 | AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5210 : \ | ||
166 | AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_5211) | ||
167 | |||
303 | #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13 | 168 | #define AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX_S 13 |
304 | #define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE 0x00700000 /*[5211]*/ | 169 | #define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE 0x00700000 /*[5211]*/ |
305 | #define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S 20 | 170 | #define AR5K_2W_TX_DESC_CTL1_FRAME_TYPE_S 20 |
306 | #define AR5K_2W_TX_DESC_CTL1_NOACK 0x00800000 /*[5211]*/ | 171 | #define AR5K_2W_TX_DESC_CTL1_NOACK 0x00800000 /*[5211]*/ |
307 | #define AR5K_2W_TX_DESC_CTL1_RTS_DURATION 0xfff80000 /*[5210 ?]*/ | 172 | #define AR5K_2W_TX_DESC_CTL1_RTS_DURATION 0xfff80000 /*[5210 ?]*/ |
308 | } __packed; | ||
309 | 173 | ||
174 | /* Frame types */ | ||
310 | #define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0x00 | 175 | #define AR5K_AR5210_TX_DESC_FRAME_TYPE_NORMAL 0x00 |
311 | #define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 0x04 | 176 | #define AR5K_AR5210_TX_DESC_FRAME_TYPE_ATIM 0x04 |
312 | #define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 0x08 | 177 | #define AR5K_AR5210_TX_DESC_FRAME_TYPE_PSPOLL 0x08 |
@@ -378,7 +243,10 @@ struct ath5k_hw_4w_tx_ctl { | |||
378 | */ | 243 | */ |
379 | struct ath5k_hw_tx_status { | 244 | struct ath5k_hw_tx_status { |
380 | u32 tx_status_0; /* TX status word 0 */ | 245 | u32 tx_status_0; /* TX status word 0 */ |
246 | u32 tx_status_1; /* TX status word 1 */ | ||
247 | } __packed; | ||
381 | 248 | ||
249 | /* TX status word 0 fields/flags */ | ||
382 | #define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 | 250 | #define AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK 0x00000001 |
383 | #define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002 | 251 | #define AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES 0x00000002 |
384 | #define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004 | 252 | #define AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN 0x00000004 |
@@ -400,8 +268,7 @@ struct ath5k_hw_tx_status { | |||
400 | #define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000 | 268 | #define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP 0xffff0000 |
401 | #define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16 | 269 | #define AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP_S 16 |
402 | 270 | ||
403 | u32 tx_status_1; /* TX status word 1 */ | 271 | /* TX status word 1 fields/flags */ |
404 | |||
405 | #define AR5K_DESC_TX_STATUS1_DONE 0x00000001 | 272 | #define AR5K_DESC_TX_STATUS1_DONE 0x00000001 |
406 | #define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe | 273 | #define AR5K_DESC_TX_STATUS1_SEQ_NUM 0x00001ffe |
407 | #define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1 | 274 | #define AR5K_DESC_TX_STATUS1_SEQ_NUM_S 1 |
@@ -411,8 +278,6 @@ struct ath5k_hw_tx_status { | |||
411 | #define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S 21 | 278 | #define AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX_S 21 |
412 | #define AR5K_DESC_TX_STATUS1_COMP_SUCCESS 0x00800000 | 279 | #define AR5K_DESC_TX_STATUS1_COMP_SUCCESS 0x00800000 |
413 | #define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA 0x01000000 | 280 | #define AR5K_DESC_TX_STATUS1_XMIT_ANTENNA 0x01000000 |
414 | } __packed; | ||
415 | |||
416 | 281 | ||
417 | /* | 282 | /* |
418 | * 5210/5211 hardware TX descriptor | 283 | * 5210/5211 hardware TX descriptor |
@@ -441,176 +306,27 @@ struct ath5k_hw_all_rx_desc { | |||
441 | } u; | 306 | } u; |
442 | } __packed; | 307 | } __packed; |
443 | 308 | ||
444 | |||
445 | /* | 309 | /* |
446 | * AR5K REGISTER ACCESS | 310 | * Atheros hardware descriptor |
311 | * This is read and written to by the hardware | ||
447 | */ | 312 | */ |
313 | struct ath5k_desc { | ||
314 | u32 ds_link; /* physical address of the next descriptor */ | ||
315 | u32 ds_data; /* physical address of data buffer (skb) */ | ||
448 | 316 | ||
449 | /*Swap RX/TX Descriptor for big endian archs*/ | 317 | union { |
450 | #if defined(__BIG_ENDIAN) | 318 | struct ath5k_hw_5210_tx_desc ds_tx5210; |
451 | #define AR5K_INIT_CFG ( \ | 319 | struct ath5k_hw_5212_tx_desc ds_tx5212; |
452 | AR5K_CFG_SWTD | AR5K_CFG_SWRD \ | 320 | struct ath5k_hw_all_rx_desc ds_rx; |
453 | ) | 321 | } ud; |
454 | #else | 322 | } __packed; |
455 | #define AR5K_INIT_CFG 0x00000000 | ||
456 | #endif | ||
457 | |||
458 | /*#define AR5K_REG_READ(_reg) ath5k_hw_reg_read(ah, _reg) | ||
459 | |||
460 | #define AR5K_REG_WRITE(_reg, _val) ath5k_hw_reg_write(ah, _val, _reg)*/ | ||
461 | |||
462 | #define AR5K_REG_SM(_val, _flags) \ | ||
463 | (((_val) << _flags##_S) & (_flags)) | ||
464 | |||
465 | #define AR5K_REG_MS(_val, _flags) \ | ||
466 | (((_val) & (_flags)) >> _flags##_S) | ||
467 | |||
468 | /* Some registers can hold multiple values of interest. For this | ||
469 | * reason when we want to write to these registers we must first | ||
470 | * retrieve the values which we do not want to clear (lets call this | ||
471 | * old_data) and then set the register with this and our new_value: | ||
472 | * ( old_data | new_value) */ | ||
473 | #define AR5K_REG_WRITE_BITS(ah, _reg, _flags, _val) \ | ||
474 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & ~(_flags)) | \ | ||
475 | (((_val) << _flags##_S) & (_flags)), _reg) | ||
476 | |||
477 | #define AR5K_REG_MASKED_BITS(ah, _reg, _flags, _mask) \ | ||
478 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, _reg) & \ | ||
479 | (_mask)) | (_flags), _reg) | ||
480 | |||
481 | #define AR5K_REG_ENABLE_BITS(ah, _reg, _flags) \ | ||
482 | ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) | (_flags), _reg) | ||
483 | |||
484 | #define AR5K_REG_DISABLE_BITS(ah, _reg, _flags) \ | ||
485 | ath5k_hw_reg_write(ah, ath5k_hw_reg_read(ah, _reg) & ~(_flags), _reg) | ||
486 | |||
487 | #define AR5K_PHY_WRITE(ah, _reg, _val) \ | ||
488 | ath5k_hw_reg_write(ah, _val, (ah)->ah_phy + ((_reg) << 2)) | ||
489 | |||
490 | #define AR5K_PHY_READ(ah, _reg) \ | ||
491 | ath5k_hw_reg_read(ah, (ah)->ah_phy + ((_reg) << 2)) | ||
492 | |||
493 | #define AR5K_REG_WAIT(_i) do { \ | ||
494 | if (_i % 64) \ | ||
495 | udelay(1); \ | ||
496 | } while (0) | ||
497 | |||
498 | #define AR5K_EEPROM_READ(_o, _v) do { \ | ||
499 | if ((ret = ath5k_hw_eeprom_read(ah, (_o), &(_v))) != 0) \ | ||
500 | return (ret); \ | ||
501 | } while (0) | ||
502 | |||
503 | #define AR5K_EEPROM_READ_HDR(_o, _v) \ | ||
504 | AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \ | ||
505 | |||
506 | /* Read status of selected queue */ | ||
507 | #define AR5K_REG_READ_Q(ah, _reg, _queue) \ | ||
508 | (ath5k_hw_reg_read(ah, _reg) & (1 << _queue)) \ | ||
509 | |||
510 | #define AR5K_REG_WRITE_Q(ah, _reg, _queue) \ | ||
511 | ath5k_hw_reg_write(ah, (1 << _queue), _reg) | ||
512 | |||
513 | #define AR5K_Q_ENABLE_BITS(_reg, _queue) do { \ | ||
514 | _reg |= 1 << _queue; \ | ||
515 | } while (0) | ||
516 | |||
517 | #define AR5K_Q_DISABLE_BITS(_reg, _queue) do { \ | ||
518 | _reg &= ~(1 << _queue); \ | ||
519 | } while (0) | ||
520 | |||
521 | #define AR5K_LOW_ID(_a)( \ | ||
522 | (_a)[0] | (_a)[1] << 8 | (_a)[2] << 16 | (_a)[3] << 24 \ | ||
523 | ) | ||
524 | |||
525 | #define AR5K_HIGH_ID(_a) ((_a)[4] | (_a)[5] << 8) | ||
526 | |||
527 | /* | ||
528 | * Initial register values | ||
529 | */ | ||
530 | |||
531 | /* | ||
532 | * Common initial register values | ||
533 | */ | ||
534 | #define AR5K_INIT_MODE CHANNEL_B | ||
535 | |||
536 | #define AR5K_INIT_TX_LATENCY 502 | ||
537 | #define AR5K_INIT_USEC 39 | ||
538 | #define AR5K_INIT_USEC_TURBO 79 | ||
539 | #define AR5K_INIT_USEC_32 31 | ||
540 | #define AR5K_INIT_CARR_SENSE_EN 1 | ||
541 | #define AR5K_INIT_PROG_IFS 920 | ||
542 | #define AR5K_INIT_PROG_IFS_TURBO 960 | ||
543 | #define AR5K_INIT_EIFS 3440 | ||
544 | #define AR5K_INIT_EIFS_TURBO 6880 | ||
545 | #define AR5K_INIT_SLOT_TIME 396 | ||
546 | #define AR5K_INIT_SLOT_TIME_TURBO 480 | ||
547 | #define AR5K_INIT_ACK_CTS_TIMEOUT 1024 | ||
548 | #define AR5K_INIT_ACK_CTS_TIMEOUT_TURBO 0x08000800 | ||
549 | #define AR5K_INIT_SIFS 560 | ||
550 | #define AR5K_INIT_SIFS_TURBO 480 | ||
551 | #define AR5K_INIT_SH_RETRY 10 | ||
552 | #define AR5K_INIT_LG_RETRY AR5K_INIT_SH_RETRY | ||
553 | #define AR5K_INIT_SSH_RETRY 32 | ||
554 | #define AR5K_INIT_SLG_RETRY AR5K_INIT_SSH_RETRY | ||
555 | #define AR5K_INIT_TX_RETRY 10 | ||
556 | #define AR5K_INIT_TOPS 8 | ||
557 | #define AR5K_INIT_RXNOFRM 8 | ||
558 | #define AR5K_INIT_RPGTO 0 | ||
559 | #define AR5K_INIT_TXNOFRM 0 | ||
560 | #define AR5K_INIT_BEACON_PERIOD 65535 | ||
561 | #define AR5K_INIT_TIM_OFFSET 0 | ||
562 | #define AR5K_INIT_BEACON_EN 0 | ||
563 | #define AR5K_INIT_RESET_TSF 0 | ||
564 | |||
565 | #define AR5K_INIT_TRANSMIT_LATENCY ( \ | ||
566 | (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \ | ||
567 | (AR5K_INIT_USEC) \ | ||
568 | ) | ||
569 | #define AR5K_INIT_TRANSMIT_LATENCY_TURBO ( \ | ||
570 | (AR5K_INIT_TX_LATENCY << 14) | (AR5K_INIT_USEC_32 << 7) | \ | ||
571 | (AR5K_INIT_USEC_TURBO) \ | ||
572 | ) | ||
573 | #define AR5K_INIT_PROTO_TIME_CNTRL ( \ | ||
574 | (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS << 12) | \ | ||
575 | (AR5K_INIT_PROG_IFS) \ | ||
576 | ) | ||
577 | #define AR5K_INIT_PROTO_TIME_CNTRL_TURBO ( \ | ||
578 | (AR5K_INIT_CARR_SENSE_EN << 26) | (AR5K_INIT_EIFS_TURBO << 12) | \ | ||
579 | (AR5K_INIT_PROG_IFS_TURBO) \ | ||
580 | ) | ||
581 | #define AR5K_INIT_BEACON_CONTROL ( \ | ||
582 | (AR5K_INIT_RESET_TSF << 24) | (AR5K_INIT_BEACON_EN << 23) | \ | ||
583 | (AR5K_INIT_TIM_OFFSET << 16) | (AR5K_INIT_BEACON_PERIOD) \ | ||
584 | ) | ||
585 | |||
586 | /* | ||
587 | * Non-common initial register values which have to be loaded into the | ||
588 | * card at boot time and after each reset. | ||
589 | */ | ||
590 | |||
591 | /* Register dumps are done per operation mode */ | ||
592 | #define AR5K_INI_RFGAIN_5GHZ 0 | ||
593 | #define AR5K_INI_RFGAIN_2GHZ 1 | ||
594 | |||
595 | #define AR5K_INI_VAL_11A 0 | ||
596 | #define AR5K_INI_VAL_11A_TURBO 1 | ||
597 | #define AR5K_INI_VAL_11B 2 | ||
598 | #define AR5K_INI_VAL_11G 3 | ||
599 | #define AR5K_INI_VAL_11G_TURBO 4 | ||
600 | #define AR5K_INI_VAL_XR 0 | ||
601 | #define AR5K_INI_VAL_MAX 5 | ||
602 | |||
603 | #define AR5K_RF5111_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS | ||
604 | #define AR5K_RF5112_INI_RF_MAX_BANKS AR5K_MAX_RF_BANKS | ||
605 | 323 | ||
606 | static inline u32 ath5k_hw_bitswap(u32 val, unsigned int bits) | 324 | #define AR5K_RXDESC_INTREQ 0x0020 |
607 | { | ||
608 | u32 retval = 0, bit, i; | ||
609 | 325 | ||
610 | for (i = 0; i < bits; i++) { | 326 | #define AR5K_TXDESC_CLRDMASK 0x0001 |
611 | bit = (val >> i) & 1; | 327 | #define AR5K_TXDESC_NOACK 0x0002 /*[5211+]*/ |
612 | retval = (retval << 1) | bit; | 328 | #define AR5K_TXDESC_RTSENA 0x0004 |
613 | } | 329 | #define AR5K_TXDESC_CTSENA 0x0008 |
330 | #define AR5K_TXDESC_INTREQ 0x0010 | ||
331 | #define AR5K_TXDESC_VEOL 0x0020 /*[5211+]*/ | ||
614 | 332 | ||
615 | return retval; | ||
616 | } | ||
diff --git a/drivers/net/wireless/ath5k/dma.c b/drivers/net/wireless/ath5k/dma.c new file mode 100644 index 000000000000..7adceb2c7fab --- /dev/null +++ b/drivers/net/wireless/ath5k/dma.c | |||
@@ -0,0 +1,605 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | /*************************************\ | ||
20 | * DMA and interrupt masking functions * | ||
21 | \*************************************/ | ||
22 | |||
23 | /* | ||
24 | * dma.c - DMA and interrupt masking functions | ||
25 | * | ||
26 | * Here we setup descriptor pointers (rxdp/txdp) start/stop dma engine and | ||
27 | * handle queue setup for 5210 chipset (rest are handled on qcu.c). | ||
28 | * Also we setup interrupt mask register (IMR) and read the various iterrupt | ||
29 | * status registers (ISR). | ||
30 | * | ||
31 | * TODO: Handle SISR on 5211+ and introduce a function to return the queue | ||
32 | * number that resulted the interrupt. | ||
33 | */ | ||
34 | |||
35 | #include "ath5k.h" | ||
36 | #include "reg.h" | ||
37 | #include "debug.h" | ||
38 | #include "base.h" | ||
39 | |||
40 | /*********\ | ||
41 | * Receive * | ||
42 | \*********/ | ||
43 | |||
44 | /** | ||
45 | * ath5k_hw_start_rx_dma - Start DMA receive | ||
46 | * | ||
47 | * @ah: The &struct ath5k_hw | ||
48 | */ | ||
49 | void ath5k_hw_start_rx_dma(struct ath5k_hw *ah) | ||
50 | { | ||
51 | ATH5K_TRACE(ah->ah_sc); | ||
52 | ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR); | ||
53 | ath5k_hw_reg_read(ah, AR5K_CR); | ||
54 | } | ||
55 | |||
56 | /** | ||
57 | * ath5k_hw_stop_rx_dma - Stop DMA receive | ||
58 | * | ||
59 | * @ah: The &struct ath5k_hw | ||
60 | */ | ||
61 | int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) | ||
62 | { | ||
63 | unsigned int i; | ||
64 | |||
65 | ATH5K_TRACE(ah->ah_sc); | ||
66 | ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR); | ||
67 | |||
68 | /* | ||
69 | * It may take some time to disable the DMA receive unit | ||
70 | */ | ||
71 | for (i = 1000; i > 0 && | ||
72 | (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0; | ||
73 | i--) | ||
74 | udelay(10); | ||
75 | |||
76 | return i ? 0 : -EBUSY; | ||
77 | } | ||
78 | |||
79 | /** | ||
80 | * ath5k_hw_get_rxdp - Get RX Descriptor's address | ||
81 | * | ||
82 | * @ah: The &struct ath5k_hw | ||
83 | * | ||
84 | * XXX: Is RXDP read and clear ? | ||
85 | */ | ||
86 | u32 ath5k_hw_get_rxdp(struct ath5k_hw *ah) | ||
87 | { | ||
88 | return ath5k_hw_reg_read(ah, AR5K_RXDP); | ||
89 | } | ||
90 | |||
91 | /** | ||
92 | * ath5k_hw_set_rxdp - Set RX Descriptor's address | ||
93 | * | ||
94 | * @ah: The &struct ath5k_hw | ||
95 | * @phys_addr: RX descriptor address | ||
96 | * | ||
97 | * XXX: Should we check if rx is enabled before setting rxdp ? | ||
98 | */ | ||
99 | void ath5k_hw_set_rxdp(struct ath5k_hw *ah, u32 phys_addr) | ||
100 | { | ||
101 | ATH5K_TRACE(ah->ah_sc); | ||
102 | |||
103 | ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP); | ||
104 | } | ||
105 | |||
106 | |||
107 | /**********\ | ||
108 | * Transmit * | ||
109 | \**********/ | ||
110 | |||
111 | /** | ||
112 | * ath5k_hw_start_tx_dma - Start DMA transmit for a specific queue | ||
113 | * | ||
114 | * @ah: The &struct ath5k_hw | ||
115 | * @queue: The hw queue number | ||
116 | * | ||
117 | * Start DMA transmit for a specific queue and since 5210 doesn't have | ||
118 | * QCU/DCU, set up queue parameters for 5210 here based on queue type (one | ||
119 | * queue for normal data and one queue for beacons). For queue setup | ||
120 | * on newer chips check out qcu.c. Returns -EINVAL if queue number is out | ||
121 | * of range or if queue is already disabled. | ||
122 | * | ||
123 | * NOTE: Must be called after setting up tx control descriptor for that | ||
124 | * queue (see below). | ||
125 | */ | ||
126 | int ath5k_hw_start_tx_dma(struct ath5k_hw *ah, unsigned int queue) | ||
127 | { | ||
128 | u32 tx_queue; | ||
129 | |||
130 | ATH5K_TRACE(ah->ah_sc); | ||
131 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
132 | |||
133 | /* Return if queue is declared inactive */ | ||
134 | if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
135 | return -EIO; | ||
136 | |||
137 | if (ah->ah_version == AR5K_AR5210) { | ||
138 | tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); | ||
139 | |||
140 | /* | ||
141 | * Set the queue by type on 5210 | ||
142 | */ | ||
143 | switch (ah->ah_txq[queue].tqi_type) { | ||
144 | case AR5K_TX_QUEUE_DATA: | ||
145 | tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0; | ||
146 | break; | ||
147 | case AR5K_TX_QUEUE_BEACON: | ||
148 | tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1; | ||
149 | ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE, | ||
150 | AR5K_BSR); | ||
151 | break; | ||
152 | case AR5K_TX_QUEUE_CAB: | ||
153 | tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1; | ||
154 | ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V | | ||
155 | AR5K_BCR_BDMAE, AR5K_BSR); | ||
156 | break; | ||
157 | default: | ||
158 | return -EINVAL; | ||
159 | } | ||
160 | /* Start queue */ | ||
161 | ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); | ||
162 | ath5k_hw_reg_read(ah, AR5K_CR); | ||
163 | } else { | ||
164 | /* Return if queue is disabled */ | ||
165 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue)) | ||
166 | return -EIO; | ||
167 | |||
168 | /* Start queue */ | ||
169 | AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue); | ||
170 | } | ||
171 | |||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | /** | ||
176 | * ath5k_hw_stop_tx_dma - Stop DMA transmit on a specific queue | ||
177 | * | ||
178 | * @ah: The &struct ath5k_hw | ||
179 | * @queue: The hw queue number | ||
180 | * | ||
181 | * Stop DMA transmit on a specific hw queue and drain queue so we don't | ||
182 | * have any pending frames. Returns -EBUSY if we still have pending frames, | ||
183 | * -EINVAL if queue number is out of range. | ||
184 | * | ||
185 | */ | ||
186 | int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) | ||
187 | { | ||
188 | unsigned int i = 40; | ||
189 | u32 tx_queue, pending; | ||
190 | |||
191 | ATH5K_TRACE(ah->ah_sc); | ||
192 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
193 | |||
194 | /* Return if queue is declared inactive */ | ||
195 | if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
196 | return -EIO; | ||
197 | |||
198 | if (ah->ah_version == AR5K_AR5210) { | ||
199 | tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); | ||
200 | |||
201 | /* | ||
202 | * Set by queue type | ||
203 | */ | ||
204 | switch (ah->ah_txq[queue].tqi_type) { | ||
205 | case AR5K_TX_QUEUE_DATA: | ||
206 | tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0; | ||
207 | break; | ||
208 | case AR5K_TX_QUEUE_BEACON: | ||
209 | case AR5K_TX_QUEUE_CAB: | ||
210 | /* XXX Fix me... */ | ||
211 | tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1; | ||
212 | ath5k_hw_reg_write(ah, 0, AR5K_BSR); | ||
213 | break; | ||
214 | default: | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | |||
218 | /* Stop queue */ | ||
219 | ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); | ||
220 | ath5k_hw_reg_read(ah, AR5K_CR); | ||
221 | } else { | ||
222 | /* | ||
223 | * Schedule TX disable and wait until queue is empty | ||
224 | */ | ||
225 | AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue); | ||
226 | |||
227 | /*Check for pending frames*/ | ||
228 | do { | ||
229 | pending = ath5k_hw_reg_read(ah, | ||
230 | AR5K_QUEUE_STATUS(queue)) & | ||
231 | AR5K_QCU_STS_FRMPENDCNT; | ||
232 | udelay(100); | ||
233 | } while (--i && pending); | ||
234 | |||
235 | /* For 2413+ order PCU to drop packets using | ||
236 | * QUIET mechanism */ | ||
237 | if (ah->ah_mac_version >= (AR5K_SREV_AR2414 >> 4) && | ||
238 | pending){ | ||
239 | /* Set periodicity and duration */ | ||
240 | ath5k_hw_reg_write(ah, | ||
241 | AR5K_REG_SM(100, AR5K_QUIET_CTL2_QT_PER)| | ||
242 | AR5K_REG_SM(10, AR5K_QUIET_CTL2_QT_DUR), | ||
243 | AR5K_QUIET_CTL2); | ||
244 | |||
245 | /* Enable quiet period for current TSF */ | ||
246 | ath5k_hw_reg_write(ah, | ||
247 | AR5K_QUIET_CTL1_QT_EN | | ||
248 | AR5K_REG_SM(ath5k_hw_reg_read(ah, | ||
249 | AR5K_TSF_L32_5211) >> 10, | ||
250 | AR5K_QUIET_CTL1_NEXT_QT_TSF), | ||
251 | AR5K_QUIET_CTL1); | ||
252 | |||
253 | /* Force channel idle high */ | ||
254 | AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, | ||
255 | AR5K_DIAG_SW_CHANEL_IDLE_HIGH); | ||
256 | |||
257 | /* Wait a while and disable mechanism */ | ||
258 | udelay(200); | ||
259 | AR5K_REG_DISABLE_BITS(ah, AR5K_QUIET_CTL1, | ||
260 | AR5K_QUIET_CTL1_QT_EN); | ||
261 | |||
262 | /* Re-check for pending frames */ | ||
263 | i = 40; | ||
264 | do { | ||
265 | pending = ath5k_hw_reg_read(ah, | ||
266 | AR5K_QUEUE_STATUS(queue)) & | ||
267 | AR5K_QCU_STS_FRMPENDCNT; | ||
268 | udelay(100); | ||
269 | } while (--i && pending); | ||
270 | |||
271 | AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW_5211, | ||
272 | AR5K_DIAG_SW_CHANEL_IDLE_HIGH); | ||
273 | } | ||
274 | |||
275 | /* Clear register */ | ||
276 | ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); | ||
277 | if (pending) | ||
278 | return -EBUSY; | ||
279 | } | ||
280 | |||
281 | /* TODO: Check for success on 5210 else return error */ | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | /** | ||
286 | * ath5k_hw_get_txdp - Get TX Descriptor's address for a specific queue | ||
287 | * | ||
288 | * @ah: The &struct ath5k_hw | ||
289 | * @queue: The hw queue number | ||
290 | * | ||
291 | * Get TX descriptor's address for a specific queue. For 5210 we ignore | ||
292 | * the queue number and use tx queue type since we only have 2 queues. | ||
293 | * We use TXDP0 for normal data queue and TXDP1 for beacon queue. | ||
294 | * For newer chips with QCU/DCU we just read the corresponding TXDP register. | ||
295 | * | ||
296 | * XXX: Is TXDP read and clear ? | ||
297 | */ | ||
298 | u32 ath5k_hw_get_txdp(struct ath5k_hw *ah, unsigned int queue) | ||
299 | { | ||
300 | u16 tx_reg; | ||
301 | |||
302 | ATH5K_TRACE(ah->ah_sc); | ||
303 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
304 | |||
305 | /* | ||
306 | * Get the transmit queue descriptor pointer from the selected queue | ||
307 | */ | ||
308 | /*5210 doesn't have QCU*/ | ||
309 | if (ah->ah_version == AR5K_AR5210) { | ||
310 | switch (ah->ah_txq[queue].tqi_type) { | ||
311 | case AR5K_TX_QUEUE_DATA: | ||
312 | tx_reg = AR5K_NOQCU_TXDP0; | ||
313 | break; | ||
314 | case AR5K_TX_QUEUE_BEACON: | ||
315 | case AR5K_TX_QUEUE_CAB: | ||
316 | tx_reg = AR5K_NOQCU_TXDP1; | ||
317 | break; | ||
318 | default: | ||
319 | return 0xffffffff; | ||
320 | } | ||
321 | } else { | ||
322 | tx_reg = AR5K_QUEUE_TXDP(queue); | ||
323 | } | ||
324 | |||
325 | return ath5k_hw_reg_read(ah, tx_reg); | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * ath5k_hw_set_txdp - Set TX Descriptor's address for a specific queue | ||
330 | * | ||
331 | * @ah: The &struct ath5k_hw | ||
332 | * @queue: The hw queue number | ||
333 | * | ||
334 | * Set TX descriptor's address for a specific queue. For 5210 we ignore | ||
335 | * the queue number and we use tx queue type since we only have 2 queues | ||
336 | * so as above we use TXDP0 for normal data queue and TXDP1 for beacon queue. | ||
337 | * For newer chips with QCU/DCU we just set the corresponding TXDP register. | ||
338 | * Returns -EINVAL if queue type is invalid for 5210 and -EIO if queue is still | ||
339 | * active. | ||
340 | */ | ||
341 | int ath5k_hw_set_txdp(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr) | ||
342 | { | ||
343 | u16 tx_reg; | ||
344 | |||
345 | ATH5K_TRACE(ah->ah_sc); | ||
346 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
347 | |||
348 | /* | ||
349 | * Set the transmit queue descriptor pointer register by type | ||
350 | * on 5210 | ||
351 | */ | ||
352 | if (ah->ah_version == AR5K_AR5210) { | ||
353 | switch (ah->ah_txq[queue].tqi_type) { | ||
354 | case AR5K_TX_QUEUE_DATA: | ||
355 | tx_reg = AR5K_NOQCU_TXDP0; | ||
356 | break; | ||
357 | case AR5K_TX_QUEUE_BEACON: | ||
358 | case AR5K_TX_QUEUE_CAB: | ||
359 | tx_reg = AR5K_NOQCU_TXDP1; | ||
360 | break; | ||
361 | default: | ||
362 | return -EINVAL; | ||
363 | } | ||
364 | } else { | ||
365 | /* | ||
366 | * Set the transmit queue descriptor pointer for | ||
367 | * the selected queue on QCU for 5211+ | ||
368 | * (this won't work if the queue is still active) | ||
369 | */ | ||
370 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) | ||
371 | return -EIO; | ||
372 | |||
373 | tx_reg = AR5K_QUEUE_TXDP(queue); | ||
374 | } | ||
375 | |||
376 | /* Set descriptor pointer */ | ||
377 | ath5k_hw_reg_write(ah, phys_addr, tx_reg); | ||
378 | |||
379 | return 0; | ||
380 | } | ||
381 | |||
382 | /** | ||
383 | * ath5k_hw_update_tx_triglevel - Update tx trigger level | ||
384 | * | ||
385 | * @ah: The &struct ath5k_hw | ||
386 | * @increase: Flag to force increase of trigger level | ||
387 | * | ||
388 | * This function increases/decreases the tx trigger level for the tx fifo | ||
389 | * buffer (aka FIFO threshold) that is used to indicate when PCU flushes | ||
390 | * the buffer and transmits it's data. Lowering this results sending small | ||
391 | * frames more quickly but can lead to tx underruns, raising it a lot can | ||
392 | * result other problems (i think bmiss is related). Right now we start with | ||
393 | * the lowest possible (64Bytes) and if we get tx underrun we increase it using | ||
394 | * the increase flag. Returns -EIO if we have have reached maximum/minimum. | ||
395 | * | ||
396 | * XXX: Link this with tx DMA size ? | ||
397 | * XXX: Use it to save interrupts ? | ||
398 | * TODO: Needs testing, i think it's related to bmiss... | ||
399 | */ | ||
400 | int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase) | ||
401 | { | ||
402 | u32 trigger_level, imr; | ||
403 | int ret = -EIO; | ||
404 | |||
405 | ATH5K_TRACE(ah->ah_sc); | ||
406 | |||
407 | /* | ||
408 | * Disable interrupts by setting the mask | ||
409 | */ | ||
410 | imr = ath5k_hw_set_imr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL); | ||
411 | |||
412 | trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG), | ||
413 | AR5K_TXCFG_TXFULL); | ||
414 | |||
415 | if (!increase) { | ||
416 | if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES) | ||
417 | goto done; | ||
418 | } else | ||
419 | trigger_level += | ||
420 | ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2); | ||
421 | |||
422 | /* | ||
423 | * Update trigger level on success | ||
424 | */ | ||
425 | if (ah->ah_version == AR5K_AR5210) | ||
426 | ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL); | ||
427 | else | ||
428 | AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, | ||
429 | AR5K_TXCFG_TXFULL, trigger_level); | ||
430 | |||
431 | ret = 0; | ||
432 | |||
433 | done: | ||
434 | /* | ||
435 | * Restore interrupt mask | ||
436 | */ | ||
437 | ath5k_hw_set_imr(ah, imr); | ||
438 | |||
439 | return ret; | ||
440 | } | ||
441 | |||
442 | /*******************\ | ||
443 | * Interrupt masking * | ||
444 | \*******************/ | ||
445 | |||
446 | /** | ||
447 | * ath5k_hw_is_intr_pending - Check if we have pending interrupts | ||
448 | * | ||
449 | * @ah: The &struct ath5k_hw | ||
450 | * | ||
451 | * Check if we have pending interrupts to process. Returns 1 if we | ||
452 | * have pending interrupts and 0 if we haven't. | ||
453 | */ | ||
454 | bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah) | ||
455 | { | ||
456 | ATH5K_TRACE(ah->ah_sc); | ||
457 | return ath5k_hw_reg_read(ah, AR5K_INTPEND) == 1 ? 1 : 0; | ||
458 | } | ||
459 | |||
460 | /** | ||
461 | * ath5k_hw_get_isr - Get interrupt status | ||
462 | * | ||
463 | * @ah: The @struct ath5k_hw | ||
464 | * @interrupt_mask: Driver's interrupt mask used to filter out | ||
465 | * interrupts in sw. | ||
466 | * | ||
467 | * This function is used inside our interrupt handler to determine the reason | ||
468 | * for the interrupt by reading Primary Interrupt Status Register. Returns an | ||
469 | * abstract interrupt status mask which is mostly ISR with some uncommon bits | ||
470 | * being mapped on some standard non hw-specific positions | ||
471 | * (check out &ath5k_int). | ||
472 | * | ||
473 | * NOTE: We use read-and-clear register, so after this function is called ISR | ||
474 | * is zeroed. | ||
475 | * | ||
476 | * XXX: Why filter interrupts in sw with interrupt_mask ? No benefit at all | ||
477 | * plus it can be misleading (one might thing that we save interrupts this way) | ||
478 | */ | ||
479 | int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask) | ||
480 | { | ||
481 | u32 data; | ||
482 | |||
483 | ATH5K_TRACE(ah->ah_sc); | ||
484 | |||
485 | /* | ||
486 | * Read interrupt status from the Interrupt Status register | ||
487 | * on 5210 | ||
488 | */ | ||
489 | if (ah->ah_version == AR5K_AR5210) { | ||
490 | data = ath5k_hw_reg_read(ah, AR5K_ISR); | ||
491 | if (unlikely(data == AR5K_INT_NOCARD)) { | ||
492 | *interrupt_mask = data; | ||
493 | return -ENODEV; | ||
494 | } | ||
495 | } else { | ||
496 | /* | ||
497 | * Read interrupt status from the Read-And-Clear | ||
498 | * shadow register. | ||
499 | * Note: PISR/SISR Not available on 5210 | ||
500 | */ | ||
501 | data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR); | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * Get abstract interrupt mask (driver-compatible) | ||
506 | */ | ||
507 | *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr; | ||
508 | |||
509 | if (unlikely(data == AR5K_INT_NOCARD)) | ||
510 | return -ENODEV; | ||
511 | |||
512 | if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR)) | ||
513 | *interrupt_mask |= AR5K_INT_RX; | ||
514 | |||
515 | if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR | ||
516 | | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL)) | ||
517 | *interrupt_mask |= AR5K_INT_TX; | ||
518 | |||
519 | if (ah->ah_version != AR5K_AR5210) { | ||
520 | /*HIU = Host Interface Unit (PCI etc)*/ | ||
521 | if (unlikely(data & (AR5K_ISR_HIUERR))) | ||
522 | *interrupt_mask |= AR5K_INT_FATAL; | ||
523 | |||
524 | /*Beacon Not Ready*/ | ||
525 | if (unlikely(data & (AR5K_ISR_BNR))) | ||
526 | *interrupt_mask |= AR5K_INT_BNR; | ||
527 | } | ||
528 | |||
529 | /* | ||
530 | * XXX: BMISS interrupts may occur after association. | ||
531 | * I found this on 5210 code but it needs testing. If this is | ||
532 | * true we should disable them before assoc and re-enable them | ||
533 | * after a successfull assoc + some jiffies. | ||
534 | */ | ||
535 | #if 0 | ||
536 | interrupt_mask &= ~AR5K_INT_BMISS; | ||
537 | #endif | ||
538 | |||
539 | /* | ||
540 | * In case we didn't handle anything, | ||
541 | * print the register value. | ||
542 | */ | ||
543 | if (unlikely(*interrupt_mask == 0 && net_ratelimit())) | ||
544 | ATH5K_PRINTF("0x%08x\n", data); | ||
545 | |||
546 | return 0; | ||
547 | } | ||
548 | |||
549 | /** | ||
550 | * ath5k_hw_set_imr - Set interrupt mask | ||
551 | * | ||
552 | * @ah: The &struct ath5k_hw | ||
553 | * @new_mask: The new interrupt mask to be set | ||
554 | * | ||
555 | * Set the interrupt mask in hw to save interrupts. We do that by mapping | ||
556 | * ath5k_int bits to hw-specific bits to remove abstraction and writing | ||
557 | * Interrupt Mask Register. | ||
558 | */ | ||
559 | enum ath5k_int ath5k_hw_set_imr(struct ath5k_hw *ah, enum ath5k_int new_mask) | ||
560 | { | ||
561 | enum ath5k_int old_mask, int_mask; | ||
562 | |||
563 | /* | ||
564 | * Disable card interrupts to prevent any race conditions | ||
565 | * (they will be re-enabled afterwards). | ||
566 | */ | ||
567 | ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER); | ||
568 | ath5k_hw_reg_read(ah, AR5K_IER); | ||
569 | |||
570 | old_mask = ah->ah_imr; | ||
571 | |||
572 | /* | ||
573 | * Add additional, chipset-dependent interrupt mask flags | ||
574 | * and write them to the IMR (interrupt mask register). | ||
575 | */ | ||
576 | int_mask = new_mask & AR5K_INT_COMMON; | ||
577 | |||
578 | if (new_mask & AR5K_INT_RX) | ||
579 | int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN | | ||
580 | AR5K_IMR_RXDESC; | ||
581 | |||
582 | if (new_mask & AR5K_INT_TX) | ||
583 | int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC | | ||
584 | AR5K_IMR_TXURN; | ||
585 | |||
586 | if (ah->ah_version != AR5K_AR5210) { | ||
587 | if (new_mask & AR5K_INT_FATAL) { | ||
588 | int_mask |= AR5K_IMR_HIUERR; | ||
589 | AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT | | ||
590 | AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR); | ||
591 | } | ||
592 | } | ||
593 | |||
594 | ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR); | ||
595 | |||
596 | /* Store new interrupt mask */ | ||
597 | ah->ah_imr = new_mask; | ||
598 | |||
599 | /* ..re-enable interrupts */ | ||
600 | ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER); | ||
601 | ath5k_hw_reg_read(ah, AR5K_IER); | ||
602 | |||
603 | return old_mask; | ||
604 | } | ||
605 | |||
diff --git a/drivers/net/wireless/ath5k/eeprom.c b/drivers/net/wireless/ath5k/eeprom.c new file mode 100644 index 000000000000..a883839b6a9f --- /dev/null +++ b/drivers/net/wireless/ath5k/eeprom.c | |||
@@ -0,0 +1,466 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | /*************************************\ | ||
20 | * EEPROM access functions and helpers * | ||
21 | \*************************************/ | ||
22 | |||
23 | #include "ath5k.h" | ||
24 | #include "reg.h" | ||
25 | #include "debug.h" | ||
26 | #include "base.h" | ||
27 | |||
28 | /* | ||
29 | * Read from eeprom | ||
30 | */ | ||
31 | static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) | ||
32 | { | ||
33 | u32 status, timeout; | ||
34 | |||
35 | ATH5K_TRACE(ah->ah_sc); | ||
36 | /* | ||
37 | * Initialize EEPROM access | ||
38 | */ | ||
39 | if (ah->ah_version == AR5K_AR5210) { | ||
40 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); | ||
41 | (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset)); | ||
42 | } else { | ||
43 | ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); | ||
44 | AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, | ||
45 | AR5K_EEPROM_CMD_READ); | ||
46 | } | ||
47 | |||
48 | for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { | ||
49 | status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); | ||
50 | if (status & AR5K_EEPROM_STAT_RDDONE) { | ||
51 | if (status & AR5K_EEPROM_STAT_RDERR) | ||
52 | return -EIO; | ||
53 | *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & | ||
54 | 0xffff); | ||
55 | return 0; | ||
56 | } | ||
57 | udelay(15); | ||
58 | } | ||
59 | |||
60 | return -ETIMEDOUT; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * Translate binary channel representation in EEPROM to frequency | ||
65 | */ | ||
66 | static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, | ||
67 | unsigned int mode) | ||
68 | { | ||
69 | u16 val; | ||
70 | |||
71 | if (bin == AR5K_EEPROM_CHANNEL_DIS) | ||
72 | return bin; | ||
73 | |||
74 | if (mode == AR5K_EEPROM_MODE_11A) { | ||
75 | if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2) | ||
76 | val = (5 * bin) + 4800; | ||
77 | else | ||
78 | val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 : | ||
79 | (bin * 10) + 5100; | ||
80 | } else { | ||
81 | if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2) | ||
82 | val = bin + 2300; | ||
83 | else | ||
84 | val = bin + 2400; | ||
85 | } | ||
86 | |||
87 | return val; | ||
88 | } | ||
89 | |||
90 | /* | ||
91 | * Read antenna infos from eeprom | ||
92 | */ | ||
93 | static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, | ||
94 | unsigned int mode) | ||
95 | { | ||
96 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
97 | u32 o = *offset; | ||
98 | u16 val; | ||
99 | int ret, i = 0; | ||
100 | |||
101 | AR5K_EEPROM_READ(o++, val); | ||
102 | ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; | ||
103 | ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f; | ||
104 | ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; | ||
105 | |||
106 | AR5K_EEPROM_READ(o++, val); | ||
107 | ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; | ||
108 | ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; | ||
109 | ee->ee_ant_control[mode][i++] = val & 0x3f; | ||
110 | |||
111 | AR5K_EEPROM_READ(o++, val); | ||
112 | ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f; | ||
113 | ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f; | ||
114 | ee->ee_ant_control[mode][i] = (val << 2) & 0x3f; | ||
115 | |||
116 | AR5K_EEPROM_READ(o++, val); | ||
117 | ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3; | ||
118 | ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f; | ||
119 | ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f; | ||
120 | ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; | ||
121 | |||
122 | AR5K_EEPROM_READ(o++, val); | ||
123 | ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; | ||
124 | ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; | ||
125 | ee->ee_ant_control[mode][i++] = val & 0x3f; | ||
126 | |||
127 | /* Get antenna modes */ | ||
128 | ah->ah_antenna[mode][0] = | ||
129 | (ee->ee_ant_control[mode][0] << 4) | 0x1; | ||
130 | ah->ah_antenna[mode][AR5K_ANT_FIXED_A] = | ||
131 | ee->ee_ant_control[mode][1] | | ||
132 | (ee->ee_ant_control[mode][2] << 6) | | ||
133 | (ee->ee_ant_control[mode][3] << 12) | | ||
134 | (ee->ee_ant_control[mode][4] << 18) | | ||
135 | (ee->ee_ant_control[mode][5] << 24); | ||
136 | ah->ah_antenna[mode][AR5K_ANT_FIXED_B] = | ||
137 | ee->ee_ant_control[mode][6] | | ||
138 | (ee->ee_ant_control[mode][7] << 6) | | ||
139 | (ee->ee_ant_control[mode][8] << 12) | | ||
140 | (ee->ee_ant_control[mode][9] << 18) | | ||
141 | (ee->ee_ant_control[mode][10] << 24); | ||
142 | |||
143 | /* return new offset */ | ||
144 | *offset = o; | ||
145 | |||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | /* | ||
150 | * Read supported modes from eeprom | ||
151 | */ | ||
152 | static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | ||
153 | unsigned int mode) | ||
154 | { | ||
155 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
156 | u32 o = *offset; | ||
157 | u16 val; | ||
158 | int ret; | ||
159 | |||
160 | AR5K_EEPROM_READ(o++, val); | ||
161 | ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff; | ||
162 | ee->ee_thr_62[mode] = val & 0xff; | ||
163 | |||
164 | if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) | ||
165 | ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28; | ||
166 | |||
167 | AR5K_EEPROM_READ(o++, val); | ||
168 | ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff; | ||
169 | ee->ee_tx_frm2xpa_enable[mode] = val & 0xff; | ||
170 | |||
171 | AR5K_EEPROM_READ(o++, val); | ||
172 | ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff; | ||
173 | |||
174 | if ((val & 0xff) & 0x80) | ||
175 | ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1); | ||
176 | else | ||
177 | ee->ee_noise_floor_thr[mode] = val & 0xff; | ||
178 | |||
179 | if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) | ||
180 | ee->ee_noise_floor_thr[mode] = | ||
181 | mode == AR5K_EEPROM_MODE_11A ? -54 : -1; | ||
182 | |||
183 | AR5K_EEPROM_READ(o++, val); | ||
184 | ee->ee_xlna_gain[mode] = (val >> 5) & 0xff; | ||
185 | ee->ee_x_gain[mode] = (val >> 1) & 0xf; | ||
186 | ee->ee_xpd[mode] = val & 0x1; | ||
187 | |||
188 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) | ||
189 | ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; | ||
190 | |||
191 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { | ||
192 | AR5K_EEPROM_READ(o++, val); | ||
193 | ee->ee_false_detect[mode] = (val >> 6) & 0x7f; | ||
194 | |||
195 | if (mode == AR5K_EEPROM_MODE_11A) | ||
196 | ee->ee_xr_power[mode] = val & 0x3f; | ||
197 | else { | ||
198 | ee->ee_ob[mode][0] = val & 0x7; | ||
199 | ee->ee_db[mode][0] = (val >> 3) & 0x7; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) { | ||
204 | ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN; | ||
205 | ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA; | ||
206 | } else { | ||
207 | ee->ee_i_gain[mode] = (val >> 13) & 0x7; | ||
208 | |||
209 | AR5K_EEPROM_READ(o++, val); | ||
210 | ee->ee_i_gain[mode] |= (val << 3) & 0x38; | ||
211 | |||
212 | if (mode == AR5K_EEPROM_MODE_11G) | ||
213 | ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff; | ||
214 | } | ||
215 | |||
216 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && | ||
217 | mode == AR5K_EEPROM_MODE_11A) { | ||
218 | ee->ee_i_cal[mode] = (val >> 8) & 0x3f; | ||
219 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; | ||
220 | } | ||
221 | |||
222 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 && | ||
223 | mode == AR5K_EEPROM_MODE_11G) | ||
224 | ee->ee_scaled_cck_delta = (val >> 11) & 0x1f; | ||
225 | |||
226 | /* return new offset */ | ||
227 | *offset = o; | ||
228 | |||
229 | return 0; | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * Initialize eeprom & capabilities structs | ||
234 | */ | ||
235 | int ath5k_eeprom_init(struct ath5k_hw *ah) | ||
236 | { | ||
237 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
238 | unsigned int mode, i; | ||
239 | int ret; | ||
240 | u32 offset; | ||
241 | u16 val; | ||
242 | |||
243 | /* Initial TX thermal adjustment values */ | ||
244 | ee->ee_tx_clip = 4; | ||
245 | ee->ee_pwd_84 = ee->ee_pwd_90 = 1; | ||
246 | ee->ee_gain_select = 1; | ||
247 | |||
248 | /* | ||
249 | * Read values from EEPROM and store them in the capability structure | ||
250 | */ | ||
251 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic); | ||
252 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect); | ||
253 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain); | ||
254 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version); | ||
255 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header); | ||
256 | |||
257 | /* Return if we have an old EEPROM */ | ||
258 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) | ||
259 | return 0; | ||
260 | |||
261 | #ifdef notyet | ||
262 | /* | ||
263 | * Validate the checksum of the EEPROM date. There are some | ||
264 | * devices with invalid EEPROMs. | ||
265 | */ | ||
266 | for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { | ||
267 | AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); | ||
268 | cksum ^= val; | ||
269 | } | ||
270 | if (cksum != AR5K_EEPROM_INFO_CKSUM) { | ||
271 | ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); | ||
272 | return -EIO; | ||
273 | } | ||
274 | #endif | ||
275 | |||
276 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), | ||
277 | ee_ant_gain); | ||
278 | |||
279 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | ||
280 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0); | ||
281 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1); | ||
282 | } | ||
283 | |||
284 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) { | ||
285 | AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val); | ||
286 | ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7; | ||
287 | ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7; | ||
288 | |||
289 | AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val); | ||
290 | ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7; | ||
291 | ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7; | ||
292 | } | ||
293 | |||
294 | /* | ||
295 | * Get conformance test limit values | ||
296 | */ | ||
297 | offset = AR5K_EEPROM_CTL(ah->ah_ee_version); | ||
298 | ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version); | ||
299 | |||
300 | for (i = 0; i < ee->ee_ctls; i++) { | ||
301 | AR5K_EEPROM_READ(offset++, val); | ||
302 | ee->ee_ctl[i] = (val >> 8) & 0xff; | ||
303 | ee->ee_ctl[i + 1] = val & 0xff; | ||
304 | } | ||
305 | |||
306 | /* | ||
307 | * Get values for 802.11a (5GHz) | ||
308 | */ | ||
309 | mode = AR5K_EEPROM_MODE_11A; | ||
310 | |||
311 | ee->ee_turbo_max_power[mode] = | ||
312 | AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header); | ||
313 | |||
314 | offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version); | ||
315 | |||
316 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | ||
317 | if (ret) | ||
318 | return ret; | ||
319 | |||
320 | AR5K_EEPROM_READ(offset++, val); | ||
321 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | ||
322 | ee->ee_ob[mode][3] = (val >> 5) & 0x7; | ||
323 | ee->ee_db[mode][3] = (val >> 2) & 0x7; | ||
324 | ee->ee_ob[mode][2] = (val << 1) & 0x7; | ||
325 | |||
326 | AR5K_EEPROM_READ(offset++, val); | ||
327 | ee->ee_ob[mode][2] |= (val >> 15) & 0x1; | ||
328 | ee->ee_db[mode][2] = (val >> 12) & 0x7; | ||
329 | ee->ee_ob[mode][1] = (val >> 9) & 0x7; | ||
330 | ee->ee_db[mode][1] = (val >> 6) & 0x7; | ||
331 | ee->ee_ob[mode][0] = (val >> 3) & 0x7; | ||
332 | ee->ee_db[mode][0] = val & 0x7; | ||
333 | |||
334 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | ||
335 | if (ret) | ||
336 | return ret; | ||
337 | |||
338 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) { | ||
339 | AR5K_EEPROM_READ(offset++, val); | ||
340 | ee->ee_margin_tx_rx[mode] = val & 0x3f; | ||
341 | } | ||
342 | |||
343 | /* | ||
344 | * Get values for 802.11b (2.4GHz) | ||
345 | */ | ||
346 | mode = AR5K_EEPROM_MODE_11B; | ||
347 | offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version); | ||
348 | |||
349 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | ||
350 | if (ret) | ||
351 | return ret; | ||
352 | |||
353 | AR5K_EEPROM_READ(offset++, val); | ||
354 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | ||
355 | ee->ee_ob[mode][1] = (val >> 4) & 0x7; | ||
356 | ee->ee_db[mode][1] = val & 0x7; | ||
357 | |||
358 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | ||
359 | if (ret) | ||
360 | return ret; | ||
361 | |||
362 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | ||
363 | AR5K_EEPROM_READ(offset++, val); | ||
364 | ee->ee_cal_pier[mode][0] = | ||
365 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | ||
366 | ee->ee_cal_pier[mode][1] = | ||
367 | ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode); | ||
368 | |||
369 | AR5K_EEPROM_READ(offset++, val); | ||
370 | ee->ee_cal_pier[mode][2] = | ||
371 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | ||
372 | } | ||
373 | |||
374 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
375 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | ||
376 | |||
377 | /* | ||
378 | * Get values for 802.11g (2.4GHz) | ||
379 | */ | ||
380 | mode = AR5K_EEPROM_MODE_11G; | ||
381 | offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version); | ||
382 | |||
383 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | ||
384 | if (ret) | ||
385 | return ret; | ||
386 | |||
387 | AR5K_EEPROM_READ(offset++, val); | ||
388 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | ||
389 | ee->ee_ob[mode][1] = (val >> 4) & 0x7; | ||
390 | ee->ee_db[mode][1] = val & 0x7; | ||
391 | |||
392 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | ||
393 | if (ret) | ||
394 | return ret; | ||
395 | |||
396 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | ||
397 | AR5K_EEPROM_READ(offset++, val); | ||
398 | ee->ee_cal_pier[mode][0] = | ||
399 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | ||
400 | ee->ee_cal_pier[mode][1] = | ||
401 | ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode); | ||
402 | |||
403 | AR5K_EEPROM_READ(offset++, val); | ||
404 | ee->ee_turbo_max_power[mode] = val & 0x7f; | ||
405 | ee->ee_xr_power[mode] = (val >> 7) & 0x3f; | ||
406 | |||
407 | AR5K_EEPROM_READ(offset++, val); | ||
408 | ee->ee_cal_pier[mode][2] = | ||
409 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | ||
410 | |||
411 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
412 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | ||
413 | |||
414 | AR5K_EEPROM_READ(offset++, val); | ||
415 | ee->ee_i_cal[mode] = (val >> 8) & 0x3f; | ||
416 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; | ||
417 | |||
418 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { | ||
419 | AR5K_EEPROM_READ(offset++, val); | ||
420 | ee->ee_cck_ofdm_gain_delta = val & 0xff; | ||
421 | } | ||
422 | } | ||
423 | |||
424 | /* | ||
425 | * Read 5GHz EEPROM channels | ||
426 | */ | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | /* | ||
432 | * Read the MAC address from eeprom | ||
433 | */ | ||
434 | int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
435 | { | ||
436 | u8 mac_d[ETH_ALEN]; | ||
437 | u32 total, offset; | ||
438 | u16 data; | ||
439 | int octet, ret; | ||
440 | |||
441 | memset(mac, 0, ETH_ALEN); | ||
442 | memset(mac_d, 0, ETH_ALEN); | ||
443 | |||
444 | ret = ath5k_hw_eeprom_read(ah, 0x20, &data); | ||
445 | if (ret) | ||
446 | return ret; | ||
447 | |||
448 | for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { | ||
449 | ret = ath5k_hw_eeprom_read(ah, offset, &data); | ||
450 | if (ret) | ||
451 | return ret; | ||
452 | |||
453 | total += data; | ||
454 | mac_d[octet + 1] = data & 0xff; | ||
455 | mac_d[octet] = data >> 8; | ||
456 | octet += 2; | ||
457 | } | ||
458 | |||
459 | memcpy(mac, mac_d, ETH_ALEN); | ||
460 | |||
461 | if (!total || total == 3 * 0xffff) | ||
462 | return -EINVAL; | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
diff --git a/drivers/net/wireless/ath5k/eeprom.h b/drivers/net/wireless/ath5k/eeprom.h new file mode 100644 index 000000000000..a468ecfbb18a --- /dev/null +++ b/drivers/net/wireless/ath5k/eeprom.h | |||
@@ -0,0 +1,215 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | /* | ||
20 | * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE) | ||
21 | */ | ||
22 | #define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ | ||
23 | #define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ | ||
24 | #define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */ | ||
25 | #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ | ||
26 | #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ | ||
27 | |||
28 | #define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */ | ||
29 | #define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */ | ||
30 | #define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */ | ||
31 | #define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */ | ||
32 | #define AR5K_EEPROM_PROTECT_WR_32_63 0x0008 | ||
33 | #define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */ | ||
34 | #define AR5K_EEPROM_PROTECT_WR_64_127 0x0020 | ||
35 | #define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */ | ||
36 | #define AR5K_EEPROM_PROTECT_WR_128_191 0x0080 | ||
37 | #define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */ | ||
38 | #define AR5K_EEPROM_PROTECT_WR_192_207 0x0200 | ||
39 | #define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */ | ||
40 | #define AR5K_EEPROM_PROTECT_WR_208_223 0x0800 | ||
41 | #define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */ | ||
42 | #define AR5K_EEPROM_PROTECT_WR_224_239 0x2000 | ||
43 | #define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */ | ||
44 | #define AR5K_EEPROM_PROTECT_WR_240_255 0x8000 | ||
45 | #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ | ||
46 | #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ | ||
47 | #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) | ||
48 | #define AR5K_EEPROM_INFO_CKSUM 0xffff | ||
49 | #define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n)) | ||
50 | |||
51 | #define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */ | ||
52 | #define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */ | ||
53 | #define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */ | ||
54 | #define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */ | ||
55 | #define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */ | ||
56 | #define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */ | ||
57 | #define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */ | ||
58 | #define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */ | ||
59 | #define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */ | ||
60 | #define AR5K_EEPROM_VERSION_4_3 0x4003 | ||
61 | #define AR5K_EEPROM_VERSION_4_4 0x4004 | ||
62 | #define AR5K_EEPROM_VERSION_4_5 0x4005 | ||
63 | #define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */ | ||
64 | #define AR5K_EEPROM_VERSION_4_7 0x4007 | ||
65 | |||
66 | #define AR5K_EEPROM_MODE_11A 0 | ||
67 | #define AR5K_EEPROM_MODE_11B 1 | ||
68 | #define AR5K_EEPROM_MODE_11G 2 | ||
69 | |||
70 | #define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */ | ||
71 | #define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) | ||
72 | #define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) | ||
73 | #define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) | ||
74 | #define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ | ||
75 | #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ | ||
76 | #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) | ||
77 | #define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz (?) */ | ||
78 | #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ | ||
79 | |||
80 | #define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c | ||
81 | #define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2 | ||
82 | #define AR5K_EEPROM_RFKILL_POLARITY 0x00000002 | ||
83 | #define AR5K_EEPROM_RFKILL_POLARITY_S 1 | ||
84 | |||
85 | /* Newer EEPROMs are using a different offset */ | ||
86 | #define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \ | ||
87 | (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0) | ||
88 | |||
89 | #define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3) | ||
90 | #define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((int8_t)(((_v) >> 8) & 0xff)) | ||
91 | #define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff)) | ||
92 | |||
93 | /* calibration settings */ | ||
94 | #define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) | ||
95 | #define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2) | ||
96 | #define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d) | ||
97 | #define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */ | ||
98 | |||
99 | /* [3.1 - 3.3] */ | ||
100 | #define AR5K_EEPROM_OBDB0_2GHZ 0x00ec | ||
101 | #define AR5K_EEPROM_OBDB1_2GHZ 0x00ed | ||
102 | |||
103 | /* Misc values available since EEPROM 4.0 */ | ||
104 | #define AR5K_EEPROM_MISC0 0x00c4 | ||
105 | #define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff) | ||
106 | #define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3) | ||
107 | #define AR5K_EEPROM_MISC1 0x00c5 | ||
108 | #define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) | ||
109 | #define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) | ||
110 | |||
111 | |||
112 | /* Some EEPROM defines */ | ||
113 | #define AR5K_EEPROM_EEP_SCALE 100 | ||
114 | #define AR5K_EEPROM_EEP_DELTA 10 | ||
115 | #define AR5K_EEPROM_N_MODES 3 | ||
116 | #define AR5K_EEPROM_N_5GHZ_CHAN 10 | ||
117 | #define AR5K_EEPROM_N_2GHZ_CHAN 3 | ||
118 | #define AR5K_EEPROM_MAX_CHAN 10 | ||
119 | #define AR5K_EEPROM_N_PCDAC 11 | ||
120 | #define AR5K_EEPROM_N_TEST_FREQ 8 | ||
121 | #define AR5K_EEPROM_N_EDGES 8 | ||
122 | #define AR5K_EEPROM_N_INTERCEPTS 11 | ||
123 | #define AR5K_EEPROM_FREQ_M(_v) AR5K_EEPROM_OFF(_v, 0x7f, 0xff) | ||
124 | #define AR5K_EEPROM_PCDAC_M 0x3f | ||
125 | #define AR5K_EEPROM_PCDAC_START 1 | ||
126 | #define AR5K_EEPROM_PCDAC_STOP 63 | ||
127 | #define AR5K_EEPROM_PCDAC_STEP 1 | ||
128 | #define AR5K_EEPROM_NON_EDGE_M 0x40 | ||
129 | #define AR5K_EEPROM_CHANNEL_POWER 8 | ||
130 | #define AR5K_EEPROM_N_OBDB 4 | ||
131 | #define AR5K_EEPROM_OBDB_DIS 0xffff | ||
132 | #define AR5K_EEPROM_CHANNEL_DIS 0xff | ||
133 | #define AR5K_EEPROM_SCALE_OC_DELTA(_x) (((_x) * 2) / 10) | ||
134 | #define AR5K_EEPROM_N_CTLS(_v) AR5K_EEPROM_OFF(_v, 16, 32) | ||
135 | #define AR5K_EEPROM_MAX_CTLS 32 | ||
136 | #define AR5K_EEPROM_N_XPD_PER_CHANNEL 4 | ||
137 | #define AR5K_EEPROM_N_XPD0_POINTS 4 | ||
138 | #define AR5K_EEPROM_N_XPD3_POINTS 3 | ||
139 | #define AR5K_EEPROM_N_INTERCEPT_10_2GHZ 35 | ||
140 | #define AR5K_EEPROM_N_INTERCEPT_10_5GHZ 55 | ||
141 | #define AR5K_EEPROM_POWER_M 0x3f | ||
142 | #define AR5K_EEPROM_POWER_MIN 0 | ||
143 | #define AR5K_EEPROM_POWER_MAX 3150 | ||
144 | #define AR5K_EEPROM_POWER_STEP 50 | ||
145 | #define AR5K_EEPROM_POWER_TABLE_SIZE 64 | ||
146 | #define AR5K_EEPROM_N_POWER_LOC_11B 4 | ||
147 | #define AR5K_EEPROM_N_POWER_LOC_11G 6 | ||
148 | #define AR5K_EEPROM_I_GAIN 10 | ||
149 | #define AR5K_EEPROM_CCK_OFDM_DELTA 15 | ||
150 | #define AR5K_EEPROM_N_IQ_CAL 2 | ||
151 | |||
152 | #define AR5K_EEPROM_READ(_o, _v) do { \ | ||
153 | ret = ath5k_hw_eeprom_read(ah, (_o), &(_v)); \ | ||
154 | if (ret) \ | ||
155 | return ret; \ | ||
156 | } while (0) | ||
157 | |||
158 | #define AR5K_EEPROM_READ_HDR(_o, _v) \ | ||
159 | AR5K_EEPROM_READ(_o, ah->ah_capabilities.cap_eeprom._v); \ | ||
160 | |||
161 | /* Struct to hold EEPROM calibration data */ | ||
162 | struct ath5k_eeprom_info { | ||
163 | u16 ee_magic; | ||
164 | u16 ee_protect; | ||
165 | u16 ee_regdomain; | ||
166 | u16 ee_version; | ||
167 | u16 ee_header; | ||
168 | u16 ee_ant_gain; | ||
169 | u16 ee_misc0; | ||
170 | u16 ee_misc1; | ||
171 | u16 ee_cck_ofdm_gain_delta; | ||
172 | u16 ee_cck_ofdm_power_delta; | ||
173 | u16 ee_scaled_cck_delta; | ||
174 | |||
175 | /* Used for tx thermal adjustment (eeprom_init, rfregs) */ | ||
176 | u16 ee_tx_clip; | ||
177 | u16 ee_pwd_84; | ||
178 | u16 ee_pwd_90; | ||
179 | u16 ee_gain_select; | ||
180 | |||
181 | /* RF Calibration settings (reset, rfregs) */ | ||
182 | u16 ee_i_cal[AR5K_EEPROM_N_MODES]; | ||
183 | u16 ee_q_cal[AR5K_EEPROM_N_MODES]; | ||
184 | u16 ee_fixed_bias[AR5K_EEPROM_N_MODES]; | ||
185 | u16 ee_turbo_max_power[AR5K_EEPROM_N_MODES]; | ||
186 | u16 ee_xr_power[AR5K_EEPROM_N_MODES]; | ||
187 | u16 ee_switch_settling[AR5K_EEPROM_N_MODES]; | ||
188 | u16 ee_ant_tx_rx[AR5K_EEPROM_N_MODES]; | ||
189 | u16 ee_ant_control[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_PCDAC]; | ||
190 | u16 ee_ob[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; | ||
191 | u16 ee_db[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_OBDB]; | ||
192 | u16 ee_tx_end2xlna_enable[AR5K_EEPROM_N_MODES]; | ||
193 | u16 ee_tx_end2xpa_disable[AR5K_EEPROM_N_MODES]; | ||
194 | u16 ee_tx_frm2xpa_enable[AR5K_EEPROM_N_MODES]; | ||
195 | u16 ee_thr_62[AR5K_EEPROM_N_MODES]; | ||
196 | u16 ee_xlna_gain[AR5K_EEPROM_N_MODES]; | ||
197 | u16 ee_xpd[AR5K_EEPROM_N_MODES]; | ||
198 | u16 ee_x_gain[AR5K_EEPROM_N_MODES]; | ||
199 | u16 ee_i_gain[AR5K_EEPROM_N_MODES]; | ||
200 | u16 ee_margin_tx_rx[AR5K_EEPROM_N_MODES]; | ||
201 | |||
202 | /* Unused */ | ||
203 | u16 ee_false_detect[AR5K_EEPROM_N_MODES]; | ||
204 | u16 ee_cal_pier[AR5K_EEPROM_N_MODES][AR5K_EEPROM_N_2GHZ_CHAN]; | ||
205 | u16 ee_channel[AR5K_EEPROM_N_MODES][AR5K_EEPROM_MAX_CHAN]; /*empty*/ | ||
206 | |||
207 | /* Conformance test limits (Unused) */ | ||
208 | u16 ee_ctls; | ||
209 | u16 ee_ctl[AR5K_EEPROM_MAX_CTLS]; | ||
210 | |||
211 | /* Noise Floor Calibration settings */ | ||
212 | s16 ee_noise_floor_thr[AR5K_EEPROM_N_MODES]; | ||
213 | s8 ee_adc_desired_size[AR5K_EEPROM_N_MODES]; | ||
214 | s8 ee_pga_desired_size[AR5K_EEPROM_N_MODES]; | ||
215 | }; | ||
diff --git a/drivers/net/wireless/ath5k/gpio.c b/drivers/net/wireless/ath5k/gpio.c new file mode 100644 index 000000000000..b77205adc180 --- /dev/null +++ b/drivers/net/wireless/ath5k/gpio.c | |||
@@ -0,0 +1,176 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | /****************\ | ||
20 | GPIO Functions | ||
21 | \****************/ | ||
22 | |||
23 | #include "ath5k.h" | ||
24 | #include "reg.h" | ||
25 | #include "debug.h" | ||
26 | #include "base.h" | ||
27 | |||
28 | /* | ||
29 | * Set led state | ||
30 | */ | ||
31 | void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state) | ||
32 | { | ||
33 | u32 led; | ||
34 | /*5210 has different led mode handling*/ | ||
35 | u32 led_5210; | ||
36 | |||
37 | ATH5K_TRACE(ah->ah_sc); | ||
38 | |||
39 | /*Reset led status*/ | ||
40 | if (ah->ah_version != AR5K_AR5210) | ||
41 | AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, | ||
42 | AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED); | ||
43 | else | ||
44 | AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED); | ||
45 | |||
46 | /* | ||
47 | * Some blinking values, define at your wish | ||
48 | */ | ||
49 | switch (state) { | ||
50 | case AR5K_LED_SCAN: | ||
51 | case AR5K_LED_AUTH: | ||
52 | led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND; | ||
53 | led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL; | ||
54 | break; | ||
55 | |||
56 | case AR5K_LED_INIT: | ||
57 | led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE; | ||
58 | led_5210 = AR5K_PCICFG_LED_PEND; | ||
59 | break; | ||
60 | |||
61 | case AR5K_LED_ASSOC: | ||
62 | case AR5K_LED_RUN: | ||
63 | led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC; | ||
64 | led_5210 = AR5K_PCICFG_LED_ASSOC; | ||
65 | break; | ||
66 | |||
67 | default: | ||
68 | led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE; | ||
69 | led_5210 = AR5K_PCICFG_LED_PEND; | ||
70 | break; | ||
71 | } | ||
72 | |||
73 | /*Write new status to the register*/ | ||
74 | if (ah->ah_version != AR5K_AR5210) | ||
75 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led); | ||
76 | else | ||
77 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210); | ||
78 | } | ||
79 | |||
80 | /* | ||
81 | * Set GPIO inputs | ||
82 | */ | ||
83 | int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) | ||
84 | { | ||
85 | ATH5K_TRACE(ah->ah_sc); | ||
86 | if (gpio > AR5K_NUM_GPIO) | ||
87 | return -EINVAL; | ||
88 | |||
89 | ath5k_hw_reg_write(ah, | ||
90 | (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio)) | ||
91 | | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR); | ||
92 | |||
93 | return 0; | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Set GPIO outputs | ||
98 | */ | ||
99 | int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) | ||
100 | { | ||
101 | ATH5K_TRACE(ah->ah_sc); | ||
102 | if (gpio > AR5K_NUM_GPIO) | ||
103 | return -EINVAL; | ||
104 | |||
105 | ath5k_hw_reg_write(ah, | ||
106 | (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & ~AR5K_GPIOCR_OUT(gpio)) | ||
107 | | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
111 | |||
112 | /* | ||
113 | * Get GPIO state | ||
114 | */ | ||
115 | u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) | ||
116 | { | ||
117 | ATH5K_TRACE(ah->ah_sc); | ||
118 | if (gpio > AR5K_NUM_GPIO) | ||
119 | return 0xffffffff; | ||
120 | |||
121 | /* GPIO input magic */ | ||
122 | return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) & | ||
123 | 0x1; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Set GPIO state | ||
128 | */ | ||
129 | int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val) | ||
130 | { | ||
131 | u32 data; | ||
132 | ATH5K_TRACE(ah->ah_sc); | ||
133 | |||
134 | if (gpio > AR5K_NUM_GPIO) | ||
135 | return -EINVAL; | ||
136 | |||
137 | /* GPIO output magic */ | ||
138 | data = ath5k_hw_reg_read(ah, AR5K_GPIODO); | ||
139 | |||
140 | data &= ~(1 << gpio); | ||
141 | data |= (val & 1) << gpio; | ||
142 | |||
143 | ath5k_hw_reg_write(ah, data, AR5K_GPIODO); | ||
144 | |||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | /* | ||
149 | * Initialize the GPIO interrupt (RFKill switch) | ||
150 | */ | ||
151 | void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, | ||
152 | u32 interrupt_level) | ||
153 | { | ||
154 | u32 data; | ||
155 | |||
156 | ATH5K_TRACE(ah->ah_sc); | ||
157 | if (gpio > AR5K_NUM_GPIO) | ||
158 | return; | ||
159 | |||
160 | /* | ||
161 | * Set the GPIO interrupt | ||
162 | */ | ||
163 | data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & | ||
164 | ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH | | ||
165 | AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) | | ||
166 | (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA); | ||
167 | |||
168 | ath5k_hw_reg_write(ah, interrupt_level ? data : | ||
169 | (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR); | ||
170 | |||
171 | ah->ah_imr |= AR5K_IMR_GPIO; | ||
172 | |||
173 | /* Enable GPIO interrupts */ | ||
174 | AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO); | ||
175 | } | ||
176 | |||
diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c deleted file mode 100644 index ad1a5b422c8c..000000000000 --- a/drivers/net/wireless/ath5k/hw.c +++ /dev/null | |||
@@ -1,4529 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * Copyright (c) 2007 Matthew W. S. Bell <mentor@madwifi.org> | ||
5 | * Copyright (c) 2007 Luis Rodriguez <mcgrof@winlab.rutgers.edu> | ||
6 | * Copyright (c) 2007 Pavel Roskin <proski@gnu.org> | ||
7 | * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> | ||
8 | * | ||
9 | * Permission to use, copy, modify, and distribute this software for any | ||
10 | * purpose with or without fee is hereby granted, provided that the above | ||
11 | * copyright notice and this permission notice appear in all copies. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
14 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
16 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
17 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
18 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
19 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * HW related functions for Atheros Wireless LAN devices. | ||
25 | */ | ||
26 | |||
27 | #include <linux/pci.h> | ||
28 | #include <linux/delay.h> | ||
29 | |||
30 | #include "reg.h" | ||
31 | #include "base.h" | ||
32 | #include "debug.h" | ||
33 | |||
34 | /* Rate tables */ | ||
35 | static const struct ath5k_rate_table ath5k_rt_11a = AR5K_RATES_11A; | ||
36 | static const struct ath5k_rate_table ath5k_rt_11b = AR5K_RATES_11B; | ||
37 | static const struct ath5k_rate_table ath5k_rt_11g = AR5K_RATES_11G; | ||
38 | static const struct ath5k_rate_table ath5k_rt_turbo = AR5K_RATES_TURBO; | ||
39 | static const struct ath5k_rate_table ath5k_rt_xr = AR5K_RATES_XR; | ||
40 | |||
41 | /* Prototypes */ | ||
42 | static int ath5k_hw_nic_reset(struct ath5k_hw *, u32); | ||
43 | static int ath5k_hw_nic_wakeup(struct ath5k_hw *, int, bool); | ||
44 | static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, | ||
45 | unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, | ||
46 | unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, | ||
47 | unsigned int, unsigned int); | ||
48 | static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *, | ||
49 | unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, | ||
50 | unsigned int); | ||
51 | static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *, | ||
52 | struct ath5k_tx_status *); | ||
53 | static int ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, | ||
54 | unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, | ||
55 | unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, | ||
56 | unsigned int, unsigned int); | ||
57 | static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *, struct ath5k_desc *, | ||
58 | struct ath5k_tx_status *); | ||
59 | static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *, struct ath5k_desc *, | ||
60 | struct ath5k_rx_status *); | ||
61 | static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *, struct ath5k_desc *, | ||
62 | struct ath5k_rx_status *); | ||
63 | static int ath5k_hw_get_capabilities(struct ath5k_hw *); | ||
64 | |||
65 | static int ath5k_eeprom_init(struct ath5k_hw *); | ||
66 | static int ath5k_eeprom_read_mac(struct ath5k_hw *, u8 *); | ||
67 | |||
68 | static int ath5k_hw_enable_pspoll(struct ath5k_hw *, u8 *, u16); | ||
69 | static int ath5k_hw_disable_pspoll(struct ath5k_hw *); | ||
70 | |||
71 | /* | ||
72 | * Enable to overwrite the country code (use "00" for debug) | ||
73 | */ | ||
74 | #if 0 | ||
75 | #define COUNTRYCODE "00" | ||
76 | #endif | ||
77 | |||
78 | /*******************\ | ||
79 | General Functions | ||
80 | \*******************/ | ||
81 | |||
82 | /* | ||
83 | * Functions used internaly | ||
84 | */ | ||
85 | |||
86 | static inline unsigned int ath5k_hw_htoclock(unsigned int usec, bool turbo) | ||
87 | { | ||
88 | return turbo ? (usec * 80) : (usec * 40); | ||
89 | } | ||
90 | |||
91 | static inline unsigned int ath5k_hw_clocktoh(unsigned int clock, bool turbo) | ||
92 | { | ||
93 | return turbo ? (clock / 80) : (clock / 40); | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * Check if a register write has been completed | ||
98 | */ | ||
99 | int ath5k_hw_register_timeout(struct ath5k_hw *ah, u32 reg, u32 flag, u32 val, | ||
100 | bool is_set) | ||
101 | { | ||
102 | int i; | ||
103 | u32 data; | ||
104 | |||
105 | for (i = AR5K_TUNE_REGISTER_TIMEOUT; i > 0; i--) { | ||
106 | data = ath5k_hw_reg_read(ah, reg); | ||
107 | if (is_set && (data & flag)) | ||
108 | break; | ||
109 | else if ((data & flag) == val) | ||
110 | break; | ||
111 | udelay(15); | ||
112 | } | ||
113 | |||
114 | return (i <= 0) ? -EAGAIN : 0; | ||
115 | } | ||
116 | |||
117 | |||
118 | /***************************************\ | ||
119 | Attach/Detach Functions | ||
120 | \***************************************/ | ||
121 | |||
122 | /* | ||
123 | * Power On Self Test helper function | ||
124 | */ | ||
125 | static int ath5k_hw_post(struct ath5k_hw *ah) | ||
126 | { | ||
127 | |||
128 | int i, c; | ||
129 | u16 cur_reg; | ||
130 | u16 regs[2] = {AR5K_STA_ID0, AR5K_PHY(8)}; | ||
131 | u32 var_pattern; | ||
132 | u32 static_pattern[4] = { | ||
133 | 0x55555555, 0xaaaaaaaa, | ||
134 | 0x66666666, 0x99999999 | ||
135 | }; | ||
136 | u32 init_val; | ||
137 | u32 cur_val; | ||
138 | |||
139 | for (c = 0; c < 2; c++) { | ||
140 | |||
141 | cur_reg = regs[c]; | ||
142 | |||
143 | /* Save previous value */ | ||
144 | init_val = ath5k_hw_reg_read(ah, cur_reg); | ||
145 | |||
146 | for (i = 0; i < 256; i++) { | ||
147 | var_pattern = i << 16 | i; | ||
148 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); | ||
149 | cur_val = ath5k_hw_reg_read(ah, cur_reg); | ||
150 | |||
151 | if (cur_val != var_pattern) { | ||
152 | ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n"); | ||
153 | return -EAGAIN; | ||
154 | } | ||
155 | |||
156 | /* Found on ndiswrapper dumps */ | ||
157 | var_pattern = 0x0039080f; | ||
158 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); | ||
159 | } | ||
160 | |||
161 | for (i = 0; i < 4; i++) { | ||
162 | var_pattern = static_pattern[i]; | ||
163 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); | ||
164 | cur_val = ath5k_hw_reg_read(ah, cur_reg); | ||
165 | |||
166 | if (cur_val != var_pattern) { | ||
167 | ATH5K_ERR(ah->ah_sc, "POST Failed !!!\n"); | ||
168 | return -EAGAIN; | ||
169 | } | ||
170 | |||
171 | /* Found on ndiswrapper dumps */ | ||
172 | var_pattern = 0x003b080f; | ||
173 | ath5k_hw_reg_write(ah, var_pattern, cur_reg); | ||
174 | } | ||
175 | |||
176 | /* Restore previous value */ | ||
177 | ath5k_hw_reg_write(ah, init_val, cur_reg); | ||
178 | |||
179 | } | ||
180 | |||
181 | return 0; | ||
182 | |||
183 | } | ||
184 | |||
185 | /* | ||
186 | * Check if the device is supported and initialize the needed structs | ||
187 | */ | ||
188 | struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc, u8 mac_version) | ||
189 | { | ||
190 | struct ath5k_hw *ah; | ||
191 | struct pci_dev *pdev = sc->pdev; | ||
192 | u8 mac[ETH_ALEN]; | ||
193 | int ret; | ||
194 | u32 srev; | ||
195 | |||
196 | /*If we passed the test malloc a ath5k_hw struct*/ | ||
197 | ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); | ||
198 | if (ah == NULL) { | ||
199 | ret = -ENOMEM; | ||
200 | ATH5K_ERR(sc, "out of memory\n"); | ||
201 | goto err; | ||
202 | } | ||
203 | |||
204 | ah->ah_sc = sc; | ||
205 | ah->ah_iobase = sc->iobase; | ||
206 | |||
207 | /* | ||
208 | * HW information | ||
209 | */ | ||
210 | |||
211 | ah->ah_op_mode = IEEE80211_IF_TYPE_STA; | ||
212 | ah->ah_radar.r_enabled = AR5K_TUNE_RADAR_ALERT; | ||
213 | ah->ah_turbo = false; | ||
214 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | ||
215 | ah->ah_imr = 0; | ||
216 | ah->ah_atim_window = 0; | ||
217 | ah->ah_aifs = AR5K_TUNE_AIFS; | ||
218 | ah->ah_cw_min = AR5K_TUNE_CWMIN; | ||
219 | ah->ah_limit_tx_retries = AR5K_INIT_TX_RETRY; | ||
220 | ah->ah_software_retry = false; | ||
221 | ah->ah_ant_diversity = AR5K_TUNE_ANT_DIVERSITY; | ||
222 | |||
223 | /* | ||
224 | * Set the mac revision based on the pci id | ||
225 | */ | ||
226 | ah->ah_version = mac_version; | ||
227 | |||
228 | /*Fill the ath5k_hw struct with the needed functions*/ | ||
229 | if (ah->ah_version == AR5K_AR5212) | ||
230 | ah->ah_magic = AR5K_EEPROM_MAGIC_5212; | ||
231 | else if (ah->ah_version == AR5K_AR5211) | ||
232 | ah->ah_magic = AR5K_EEPROM_MAGIC_5211; | ||
233 | |||
234 | if (ah->ah_version == AR5K_AR5212) { | ||
235 | ah->ah_setup_tx_desc = ath5k_hw_setup_4word_tx_desc; | ||
236 | ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc; | ||
237 | ah->ah_proc_tx_desc = ath5k_hw_proc_4word_tx_status; | ||
238 | } else { | ||
239 | ah->ah_setup_tx_desc = ath5k_hw_setup_2word_tx_desc; | ||
240 | ah->ah_setup_xtx_desc = ath5k_hw_setup_xr_tx_desc; | ||
241 | ah->ah_proc_tx_desc = ath5k_hw_proc_2word_tx_status; | ||
242 | } | ||
243 | |||
244 | if (ah->ah_version == AR5K_AR5212) | ||
245 | ah->ah_proc_rx_desc = ath5k_hw_proc_5212_rx_status; | ||
246 | else if (ah->ah_version <= AR5K_AR5211) | ||
247 | ah->ah_proc_rx_desc = ath5k_hw_proc_5210_rx_status; | ||
248 | |||
249 | /* Bring device out of sleep and reset it's units */ | ||
250 | ret = ath5k_hw_nic_wakeup(ah, AR5K_INIT_MODE, true); | ||
251 | if (ret) | ||
252 | goto err_free; | ||
253 | |||
254 | /* Get MAC, PHY and RADIO revisions */ | ||
255 | srev = ath5k_hw_reg_read(ah, AR5K_SREV); | ||
256 | ah->ah_mac_srev = srev; | ||
257 | ah->ah_mac_version = AR5K_REG_MS(srev, AR5K_SREV_VER); | ||
258 | ah->ah_mac_revision = AR5K_REG_MS(srev, AR5K_SREV_REV); | ||
259 | ah->ah_phy_revision = ath5k_hw_reg_read(ah, AR5K_PHY_CHIP_ID) & | ||
260 | 0xffffffff; | ||
261 | ah->ah_radio_5ghz_revision = ath5k_hw_radio_revision(ah, | ||
262 | CHANNEL_5GHZ); | ||
263 | |||
264 | if (ah->ah_version == AR5K_AR5210) | ||
265 | ah->ah_radio_2ghz_revision = 0; | ||
266 | else | ||
267 | ah->ah_radio_2ghz_revision = ath5k_hw_radio_revision(ah, | ||
268 | CHANNEL_2GHZ); | ||
269 | |||
270 | /* Return on unsuported chips (unsupported eeprom etc) */ | ||
271 | if ((srev >= AR5K_SREV_VER_AR5416) && | ||
272 | (srev < AR5K_SREV_VER_AR2425)) { | ||
273 | ATH5K_ERR(sc, "Device not yet supported.\n"); | ||
274 | ret = -ENODEV; | ||
275 | goto err_free; | ||
276 | } else if (srev == AR5K_SREV_VER_AR2425) { | ||
277 | ATH5K_WARN(sc, "Support for RF2425 is under development.\n"); | ||
278 | } | ||
279 | |||
280 | /* Identify single chip solutions */ | ||
281 | if (((srev <= AR5K_SREV_VER_AR5414) && | ||
282 | (srev >= AR5K_SREV_VER_AR2413)) || | ||
283 | (srev == AR5K_SREV_VER_AR2425)) { | ||
284 | ah->ah_single_chip = true; | ||
285 | } else { | ||
286 | ah->ah_single_chip = false; | ||
287 | } | ||
288 | |||
289 | /* Single chip radio */ | ||
290 | if (ah->ah_radio_2ghz_revision == ah->ah_radio_5ghz_revision) | ||
291 | ah->ah_radio_2ghz_revision = 0; | ||
292 | |||
293 | /* Identify the radio chip*/ | ||
294 | if (ah->ah_version == AR5K_AR5210) { | ||
295 | ah->ah_radio = AR5K_RF5110; | ||
296 | /* | ||
297 | * Register returns 0x0/0x04 for radio revision | ||
298 | * so ath5k_hw_radio_revision doesn't parse the value | ||
299 | * correctly. For now we are based on mac's srev to | ||
300 | * identify RF2425 radio. | ||
301 | */ | ||
302 | } else if (srev == AR5K_SREV_VER_AR2425) { | ||
303 | ah->ah_radio = AR5K_RF2425; | ||
304 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2425; | ||
305 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5112) { | ||
306 | ah->ah_radio = AR5K_RF5111; | ||
307 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5111; | ||
308 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC0) { | ||
309 | ah->ah_radio = AR5K_RF5112; | ||
310 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5112; | ||
311 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC1) { | ||
312 | ah->ah_radio = AR5K_RF2413; | ||
313 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; | ||
314 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_SC2) { | ||
315 | ah->ah_radio = AR5K_RF5413; | ||
316 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | ||
317 | } else if (ah->ah_radio_5ghz_revision < AR5K_SREV_RAD_5133) { | ||
318 | /* AR5424 */ | ||
319 | if (srev >= AR5K_SREV_VER_AR5424) { | ||
320 | ah->ah_radio = AR5K_RF5413; | ||
321 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF5413; | ||
322 | /* AR2424 */ | ||
323 | } else { | ||
324 | ah->ah_radio = AR5K_RF2413; /* For testing */ | ||
325 | ah->ah_phy_spending = AR5K_PHY_SPENDING_RF2413; | ||
326 | } | ||
327 | } | ||
328 | ah->ah_phy = AR5K_PHY(0); | ||
329 | |||
330 | /* | ||
331 | * Write PCI-E power save settings | ||
332 | */ | ||
333 | if ((ah->ah_version == AR5K_AR5212) && (pdev->is_pcie)) { | ||
334 | ath5k_hw_reg_write(ah, 0x9248fc00, 0x4080); | ||
335 | ath5k_hw_reg_write(ah, 0x24924924, 0x4080); | ||
336 | ath5k_hw_reg_write(ah, 0x28000039, 0x4080); | ||
337 | ath5k_hw_reg_write(ah, 0x53160824, 0x4080); | ||
338 | ath5k_hw_reg_write(ah, 0xe5980579, 0x4080); | ||
339 | ath5k_hw_reg_write(ah, 0x001defff, 0x4080); | ||
340 | ath5k_hw_reg_write(ah, 0x1aaabe40, 0x4080); | ||
341 | ath5k_hw_reg_write(ah, 0xbe105554, 0x4080); | ||
342 | ath5k_hw_reg_write(ah, 0x000e3007, 0x4080); | ||
343 | ath5k_hw_reg_write(ah, 0x00000000, 0x4084); | ||
344 | } | ||
345 | |||
346 | /* | ||
347 | * POST | ||
348 | */ | ||
349 | ret = ath5k_hw_post(ah); | ||
350 | if (ret) | ||
351 | goto err_free; | ||
352 | |||
353 | /* Write AR5K_PCICFG_UNK on 2112B and later chips */ | ||
354 | if (ah->ah_radio_5ghz_revision > AR5K_SREV_RAD_2112B || | ||
355 | srev > AR5K_SREV_VER_AR2413) { | ||
356 | ath5k_hw_reg_write(ah, AR5K_PCICFG_UNK, AR5K_PCICFG); | ||
357 | } | ||
358 | |||
359 | /* | ||
360 | * Get card capabilities, values, ... | ||
361 | */ | ||
362 | ret = ath5k_eeprom_init(ah); | ||
363 | if (ret) { | ||
364 | ATH5K_ERR(sc, "unable to init EEPROM\n"); | ||
365 | goto err_free; | ||
366 | } | ||
367 | |||
368 | /* Get misc capabilities */ | ||
369 | ret = ath5k_hw_get_capabilities(ah); | ||
370 | if (ret) { | ||
371 | ATH5K_ERR(sc, "unable to get device capabilities: 0x%04x\n", | ||
372 | sc->pdev->device); | ||
373 | goto err_free; | ||
374 | } | ||
375 | |||
376 | /* Get MAC address */ | ||
377 | ret = ath5k_eeprom_read_mac(ah, mac); | ||
378 | if (ret) { | ||
379 | ATH5K_ERR(sc, "unable to read address from EEPROM: 0x%04x\n", | ||
380 | sc->pdev->device); | ||
381 | goto err_free; | ||
382 | } | ||
383 | |||
384 | ath5k_hw_set_lladdr(ah, mac); | ||
385 | /* Set BSSID to bcast address: ff:ff:ff:ff:ff:ff for now */ | ||
386 | memset(ah->ah_bssid, 0xff, ETH_ALEN); | ||
387 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); | ||
388 | ath5k_hw_set_opmode(ah); | ||
389 | |||
390 | ath5k_hw_set_rfgain_opt(ah); | ||
391 | |||
392 | return ah; | ||
393 | err_free: | ||
394 | kfree(ah); | ||
395 | err: | ||
396 | return ERR_PTR(ret); | ||
397 | } | ||
398 | |||
399 | /* | ||
400 | * Bring up MAC + PHY Chips | ||
401 | */ | ||
402 | static int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) | ||
403 | { | ||
404 | struct pci_dev *pdev = ah->ah_sc->pdev; | ||
405 | u32 turbo, mode, clock, bus_flags; | ||
406 | int ret; | ||
407 | |||
408 | turbo = 0; | ||
409 | mode = 0; | ||
410 | clock = 0; | ||
411 | |||
412 | ATH5K_TRACE(ah->ah_sc); | ||
413 | |||
414 | /* Wakeup the device */ | ||
415 | ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); | ||
416 | if (ret) { | ||
417 | ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n"); | ||
418 | return ret; | ||
419 | } | ||
420 | |||
421 | if (ah->ah_version != AR5K_AR5210) { | ||
422 | /* | ||
423 | * Get channel mode flags | ||
424 | */ | ||
425 | |||
426 | if (ah->ah_radio >= AR5K_RF5112) { | ||
427 | mode = AR5K_PHY_MODE_RAD_RF5112; | ||
428 | clock = AR5K_PHY_PLL_RF5112; | ||
429 | } else { | ||
430 | mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/ | ||
431 | clock = AR5K_PHY_PLL_RF5111; /*Zero*/ | ||
432 | } | ||
433 | |||
434 | if (flags & CHANNEL_2GHZ) { | ||
435 | mode |= AR5K_PHY_MODE_FREQ_2GHZ; | ||
436 | clock |= AR5K_PHY_PLL_44MHZ; | ||
437 | |||
438 | if (flags & CHANNEL_CCK) { | ||
439 | mode |= AR5K_PHY_MODE_MOD_CCK; | ||
440 | } else if (flags & CHANNEL_OFDM) { | ||
441 | /* XXX Dynamic OFDM/CCK is not supported by the | ||
442 | * AR5211 so we set MOD_OFDM for plain g (no | ||
443 | * CCK headers) operation. We need to test | ||
444 | * this, 5211 might support ofdm-only g after | ||
445 | * all, there are also initial register values | ||
446 | * in the code for g mode (see initvals.c). */ | ||
447 | if (ah->ah_version == AR5K_AR5211) | ||
448 | mode |= AR5K_PHY_MODE_MOD_OFDM; | ||
449 | else | ||
450 | mode |= AR5K_PHY_MODE_MOD_DYN; | ||
451 | } else { | ||
452 | ATH5K_ERR(ah->ah_sc, | ||
453 | "invalid radio modulation mode\n"); | ||
454 | return -EINVAL; | ||
455 | } | ||
456 | } else if (flags & CHANNEL_5GHZ) { | ||
457 | mode |= AR5K_PHY_MODE_FREQ_5GHZ; | ||
458 | clock |= AR5K_PHY_PLL_40MHZ; | ||
459 | |||
460 | if (flags & CHANNEL_OFDM) | ||
461 | mode |= AR5K_PHY_MODE_MOD_OFDM; | ||
462 | else { | ||
463 | ATH5K_ERR(ah->ah_sc, | ||
464 | "invalid radio modulation mode\n"); | ||
465 | return -EINVAL; | ||
466 | } | ||
467 | } else { | ||
468 | ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n"); | ||
469 | return -EINVAL; | ||
470 | } | ||
471 | |||
472 | if (flags & CHANNEL_TURBO) | ||
473 | turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT; | ||
474 | } else { /* Reset the device */ | ||
475 | |||
476 | /* ...enable Atheros turbo mode if requested */ | ||
477 | if (flags & CHANNEL_TURBO) | ||
478 | ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE, | ||
479 | AR5K_PHY_TURBO); | ||
480 | } | ||
481 | |||
482 | /* reseting PCI on PCI-E cards results card to hang | ||
483 | * and always return 0xffff... so we ingore that flag | ||
484 | * for PCI-E cards */ | ||
485 | bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; | ||
486 | |||
487 | /* Reset chipset */ | ||
488 | ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | | ||
489 | AR5K_RESET_CTL_BASEBAND | bus_flags); | ||
490 | if (ret) { | ||
491 | ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n"); | ||
492 | return -EIO; | ||
493 | } | ||
494 | |||
495 | if (ah->ah_version == AR5K_AR5210) | ||
496 | udelay(2300); | ||
497 | |||
498 | /* ...wakeup again!*/ | ||
499 | ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); | ||
500 | if (ret) { | ||
501 | ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n"); | ||
502 | return ret; | ||
503 | } | ||
504 | |||
505 | /* ...final warm reset */ | ||
506 | if (ath5k_hw_nic_reset(ah, 0)) { | ||
507 | ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n"); | ||
508 | return -EIO; | ||
509 | } | ||
510 | |||
511 | if (ah->ah_version != AR5K_AR5210) { | ||
512 | /* ...set the PHY operating mode */ | ||
513 | ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL); | ||
514 | udelay(300); | ||
515 | |||
516 | ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE); | ||
517 | ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO); | ||
518 | } | ||
519 | |||
520 | return 0; | ||
521 | } | ||
522 | |||
523 | /* | ||
524 | * Get the rate table for a specific operation mode | ||
525 | */ | ||
526 | const struct ath5k_rate_table *ath5k_hw_get_rate_table(struct ath5k_hw *ah, | ||
527 | unsigned int mode) | ||
528 | { | ||
529 | ATH5K_TRACE(ah->ah_sc); | ||
530 | |||
531 | if (!test_bit(mode, ah->ah_capabilities.cap_mode)) | ||
532 | return NULL; | ||
533 | |||
534 | /* Get rate tables */ | ||
535 | switch (mode) { | ||
536 | case AR5K_MODE_11A: | ||
537 | return &ath5k_rt_11a; | ||
538 | case AR5K_MODE_11A_TURBO: | ||
539 | return &ath5k_rt_turbo; | ||
540 | case AR5K_MODE_11B: | ||
541 | return &ath5k_rt_11b; | ||
542 | case AR5K_MODE_11G: | ||
543 | return &ath5k_rt_11g; | ||
544 | case AR5K_MODE_11G_TURBO: | ||
545 | return &ath5k_rt_xr; | ||
546 | } | ||
547 | |||
548 | return NULL; | ||
549 | } | ||
550 | |||
551 | /* | ||
552 | * Free the ath5k_hw struct | ||
553 | */ | ||
554 | void ath5k_hw_detach(struct ath5k_hw *ah) | ||
555 | { | ||
556 | ATH5K_TRACE(ah->ah_sc); | ||
557 | |||
558 | __set_bit(ATH_STAT_INVALID, ah->ah_sc->status); | ||
559 | |||
560 | if (ah->ah_rf_banks != NULL) | ||
561 | kfree(ah->ah_rf_banks); | ||
562 | |||
563 | /* assume interrupts are down */ | ||
564 | kfree(ah); | ||
565 | } | ||
566 | |||
567 | /****************************\ | ||
568 | Reset function and helpers | ||
569 | \****************************/ | ||
570 | |||
571 | /** | ||
572 | * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 | ||
573 | * | ||
574 | * @ah: the &struct ath5k_hw | ||
575 | * @channel: the currently set channel upon reset | ||
576 | * | ||
577 | * Write the OFDM timings for the AR5212 upon reset. This is a helper for | ||
578 | * ath5k_hw_reset(). This seems to tune the PLL a specified frequency | ||
579 | * depending on the bandwidth of the channel. | ||
580 | * | ||
581 | */ | ||
582 | static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | ||
583 | struct ieee80211_channel *channel) | ||
584 | { | ||
585 | /* Get exponent and mantissa and set it */ | ||
586 | u32 coef_scaled, coef_exp, coef_man, | ||
587 | ds_coef_exp, ds_coef_man, clock; | ||
588 | |||
589 | if (!(ah->ah_version == AR5K_AR5212) || | ||
590 | !(channel->hw_value & CHANNEL_OFDM)) | ||
591 | BUG(); | ||
592 | |||
593 | /* Seems there are two PLLs, one for baseband sampling and one | ||
594 | * for tuning. Tuning basebands are 40 MHz or 80MHz when in | ||
595 | * turbo. */ | ||
596 | clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40; | ||
597 | coef_scaled = ((5 * (clock << 24)) / 2) / | ||
598 | channel->center_freq; | ||
599 | |||
600 | for (coef_exp = 31; coef_exp > 0; coef_exp--) | ||
601 | if ((coef_scaled >> coef_exp) & 0x1) | ||
602 | break; | ||
603 | |||
604 | if (!coef_exp) | ||
605 | return -EINVAL; | ||
606 | |||
607 | coef_exp = 14 - (coef_exp - 24); | ||
608 | coef_man = coef_scaled + | ||
609 | (1 << (24 - coef_exp - 1)); | ||
610 | ds_coef_man = coef_man >> (24 - coef_exp); | ||
611 | ds_coef_exp = coef_exp - 16; | ||
612 | |||
613 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, | ||
614 | AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man); | ||
615 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, | ||
616 | AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp); | ||
617 | |||
618 | return 0; | ||
619 | } | ||
620 | |||
621 | /** | ||
622 | * ath5k_hw_write_rate_duration - set rate duration during hw resets | ||
623 | * | ||
624 | * @ah: the &struct ath5k_hw | ||
625 | * @mode: one of enum ath5k_driver_mode | ||
626 | * | ||
627 | * Write the rate duration table for the current mode upon hw reset. This | ||
628 | * is a helper for ath5k_hw_reset(). It seems all this is doing is setting | ||
629 | * an ACK timeout for the hardware for the current mode for each rate. The | ||
630 | * rates which are capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, | ||
631 | * and 11Mbps) have another register for the short preamble ACK timeout | ||
632 | * calculation. | ||
633 | * | ||
634 | */ | ||
635 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | ||
636 | unsigned int mode) | ||
637 | { | ||
638 | struct ath5k_softc *sc = ah->ah_sc; | ||
639 | const struct ath5k_rate_table *rt; | ||
640 | struct ieee80211_rate srate = {}; | ||
641 | unsigned int i; | ||
642 | |||
643 | /* Get rate table for the current operating mode */ | ||
644 | rt = ath5k_hw_get_rate_table(ah, mode); | ||
645 | |||
646 | /* Write rate duration table */ | ||
647 | for (i = 0; i < rt->rate_count; i++) { | ||
648 | const struct ath5k_rate *rate, *control_rate; | ||
649 | |||
650 | u32 reg; | ||
651 | u16 tx_time; | ||
652 | |||
653 | rate = &rt->rates[i]; | ||
654 | control_rate = &rt->rates[rate->control_rate]; | ||
655 | |||
656 | /* Set ACK timeout */ | ||
657 | reg = AR5K_RATE_DUR(rate->rate_code); | ||
658 | |||
659 | srate.bitrate = control_rate->rate_kbps/100; | ||
660 | |||
661 | /* An ACK frame consists of 10 bytes. If you add the FCS, | ||
662 | * which ieee80211_generic_frame_duration() adds, | ||
663 | * its 14 bytes. Note we use the control rate and not the | ||
664 | * actual rate for this rate. See mac80211 tx.c | ||
665 | * ieee80211_duration() for a brief description of | ||
666 | * what rate we should choose to TX ACKs. */ | ||
667 | tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, | ||
668 | sc->vif, 10, &srate)); | ||
669 | |||
670 | ath5k_hw_reg_write(ah, tx_time, reg); | ||
671 | |||
672 | if (!HAS_SHPREAMBLE(i)) | ||
673 | continue; | ||
674 | |||
675 | /* | ||
676 | * We're not distinguishing short preamble here, | ||
677 | * This is true, all we'll get is a longer value here | ||
678 | * which is not necessarilly bad. We could use | ||
679 | * export ieee80211_frame_duration() but that needs to be | ||
680 | * fixed first to be properly used by mac802111 drivers: | ||
681 | * | ||
682 | * - remove erp stuff and let the routine figure ofdm | ||
683 | * erp rates | ||
684 | * - remove passing argument ieee80211_local as | ||
685 | * drivers don't have access to it | ||
686 | * - move drivers using ieee80211_generic_frame_duration() | ||
687 | * to this | ||
688 | */ | ||
689 | ath5k_hw_reg_write(ah, tx_time, | ||
690 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); | ||
691 | } | ||
692 | } | ||
693 | |||
694 | /* | ||
695 | * Main reset function | ||
696 | */ | ||
697 | int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode, | ||
698 | struct ieee80211_channel *channel, bool change_channel) | ||
699 | { | ||
700 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
701 | struct pci_dev *pdev = ah->ah_sc->pdev; | ||
702 | u32 data, s_seq, s_ant, s_led[3], dma_size; | ||
703 | unsigned int i, mode, freq, ee_mode, ant[2]; | ||
704 | int ret; | ||
705 | |||
706 | ATH5K_TRACE(ah->ah_sc); | ||
707 | |||
708 | s_seq = 0; | ||
709 | s_ant = 0; | ||
710 | ee_mode = 0; | ||
711 | freq = 0; | ||
712 | mode = 0; | ||
713 | |||
714 | /* | ||
715 | * Save some registers before a reset | ||
716 | */ | ||
717 | /*DCU/Antenna selection not available on 5210*/ | ||
718 | if (ah->ah_version != AR5K_AR5210) { | ||
719 | if (change_channel) { | ||
720 | /* Seq number for queue 0 -do this for all queues ? */ | ||
721 | s_seq = ath5k_hw_reg_read(ah, | ||
722 | AR5K_QUEUE_DFS_SEQNUM(0)); | ||
723 | /*Default antenna*/ | ||
724 | s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); | ||
725 | } | ||
726 | } | ||
727 | |||
728 | /*GPIOs*/ | ||
729 | s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE; | ||
730 | s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); | ||
731 | s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); | ||
732 | |||
733 | if (change_channel && ah->ah_rf_banks != NULL) | ||
734 | ath5k_hw_get_rf_gain(ah); | ||
735 | |||
736 | |||
737 | /*Wakeup the device*/ | ||
738 | ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); | ||
739 | if (ret) | ||
740 | return ret; | ||
741 | |||
742 | /* | ||
743 | * Initialize operating mode | ||
744 | */ | ||
745 | ah->ah_op_mode = op_mode; | ||
746 | |||
747 | /* | ||
748 | * 5111/5112 Settings | ||
749 | * 5210 only comes with RF5110 | ||
750 | */ | ||
751 | if (ah->ah_version != AR5K_AR5210) { | ||
752 | if (ah->ah_radio != AR5K_RF5111 && | ||
753 | ah->ah_radio != AR5K_RF5112 && | ||
754 | ah->ah_radio != AR5K_RF5413 && | ||
755 | ah->ah_radio != AR5K_RF2413 && | ||
756 | ah->ah_radio != AR5K_RF2425) { | ||
757 | ATH5K_ERR(ah->ah_sc, | ||
758 | "invalid phy radio: %u\n", ah->ah_radio); | ||
759 | return -EINVAL; | ||
760 | } | ||
761 | |||
762 | switch (channel->hw_value & CHANNEL_MODES) { | ||
763 | case CHANNEL_A: | ||
764 | mode = AR5K_MODE_11A; | ||
765 | freq = AR5K_INI_RFGAIN_5GHZ; | ||
766 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
767 | break; | ||
768 | case CHANNEL_G: | ||
769 | mode = AR5K_MODE_11G; | ||
770 | freq = AR5K_INI_RFGAIN_2GHZ; | ||
771 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
772 | break; | ||
773 | case CHANNEL_B: | ||
774 | mode = AR5K_MODE_11B; | ||
775 | freq = AR5K_INI_RFGAIN_2GHZ; | ||
776 | ee_mode = AR5K_EEPROM_MODE_11B; | ||
777 | break; | ||
778 | case CHANNEL_T: | ||
779 | mode = AR5K_MODE_11A_TURBO; | ||
780 | freq = AR5K_INI_RFGAIN_5GHZ; | ||
781 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
782 | break; | ||
783 | /*Is this ok on 5211 too ?*/ | ||
784 | case CHANNEL_TG: | ||
785 | mode = AR5K_MODE_11G_TURBO; | ||
786 | freq = AR5K_INI_RFGAIN_2GHZ; | ||
787 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
788 | break; | ||
789 | case CHANNEL_XR: | ||
790 | if (ah->ah_version == AR5K_AR5211) { | ||
791 | ATH5K_ERR(ah->ah_sc, | ||
792 | "XR mode not available on 5211"); | ||
793 | return -EINVAL; | ||
794 | } | ||
795 | mode = AR5K_MODE_XR; | ||
796 | freq = AR5K_INI_RFGAIN_5GHZ; | ||
797 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
798 | break; | ||
799 | default: | ||
800 | ATH5K_ERR(ah->ah_sc, | ||
801 | "invalid channel: %d\n", channel->center_freq); | ||
802 | return -EINVAL; | ||
803 | } | ||
804 | |||
805 | /* PHY access enable */ | ||
806 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | ||
807 | |||
808 | } | ||
809 | |||
810 | ret = ath5k_hw_write_initvals(ah, mode, change_channel); | ||
811 | if (ret) | ||
812 | return ret; | ||
813 | |||
814 | /* | ||
815 | * 5211/5212 Specific | ||
816 | */ | ||
817 | if (ah->ah_version != AR5K_AR5210) { | ||
818 | /* | ||
819 | * Write initial RF gain settings | ||
820 | * This should work for both 5111/5112 | ||
821 | */ | ||
822 | ret = ath5k_hw_rfgain(ah, freq); | ||
823 | if (ret) | ||
824 | return ret; | ||
825 | |||
826 | mdelay(1); | ||
827 | |||
828 | /* | ||
829 | * Write some more initial register settings | ||
830 | */ | ||
831 | if (ah->ah_version == AR5K_AR5212) { | ||
832 | ath5k_hw_reg_write(ah, 0x0002a002, 0x982c); | ||
833 | |||
834 | if (channel->hw_value == CHANNEL_G) | ||
835 | if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413) | ||
836 | ath5k_hw_reg_write(ah, 0x00f80d80, | ||
837 | 0x994c); | ||
838 | else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424) | ||
839 | ath5k_hw_reg_write(ah, 0x00380140, | ||
840 | 0x994c); | ||
841 | else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425) | ||
842 | ath5k_hw_reg_write(ah, 0x00fc0ec0, | ||
843 | 0x994c); | ||
844 | else /* 2425 */ | ||
845 | ath5k_hw_reg_write(ah, 0x00fc0fc0, | ||
846 | 0x994c); | ||
847 | else | ||
848 | ath5k_hw_reg_write(ah, 0x00000000, 0x994c); | ||
849 | |||
850 | /* Some bits are disabled here, we know nothing about | ||
851 | * register 0xa228 yet, most of the times this ends up | ||
852 | * with a value 0x9b5 -haven't seen any dump with | ||
853 | * a different value- */ | ||
854 | /* Got this from decompiling binary HAL */ | ||
855 | data = ath5k_hw_reg_read(ah, 0xa228); | ||
856 | data &= 0xfffffdff; | ||
857 | ath5k_hw_reg_write(ah, data, 0xa228); | ||
858 | |||
859 | data = ath5k_hw_reg_read(ah, 0xa228); | ||
860 | data &= 0xfffe03ff; | ||
861 | ath5k_hw_reg_write(ah, data, 0xa228); | ||
862 | data = 0; | ||
863 | |||
864 | /* Just write 0x9b5 ? */ | ||
865 | /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */ | ||
866 | ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK); | ||
867 | ath5k_hw_reg_write(ah, 0x00000000, 0xa254); | ||
868 | ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL); | ||
869 | } | ||
870 | |||
871 | /* Fix for first revision of the RF5112 RF chipset */ | ||
872 | if (ah->ah_radio >= AR5K_RF5112 && | ||
873 | ah->ah_radio_5ghz_revision < | ||
874 | AR5K_SREV_RAD_5112A) { | ||
875 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, | ||
876 | AR5K_PHY_CCKTXCTL); | ||
877 | if (channel->hw_value & CHANNEL_5GHZ) | ||
878 | data = 0xffb81020; | ||
879 | else | ||
880 | data = 0xffb80d20; | ||
881 | ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); | ||
882 | data = 0; | ||
883 | } | ||
884 | |||
885 | /* | ||
886 | * Set TX power (FIXME) | ||
887 | */ | ||
888 | ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER); | ||
889 | if (ret) | ||
890 | return ret; | ||
891 | |||
892 | /* Write rate duration table only on AR5212 and if | ||
893 | * virtual interface has already been brought up | ||
894 | * XXX: rethink this after new mode changes to | ||
895 | * mac80211 are integrated */ | ||
896 | if (ah->ah_version == AR5K_AR5212 && | ||
897 | ah->ah_sc->vif != NULL) | ||
898 | ath5k_hw_write_rate_duration(ah, mode); | ||
899 | |||
900 | /* | ||
901 | * Write RF registers | ||
902 | */ | ||
903 | ret = ath5k_hw_rfregs(ah, channel, mode); | ||
904 | if (ret) | ||
905 | return ret; | ||
906 | |||
907 | /* | ||
908 | * Configure additional registers | ||
909 | */ | ||
910 | |||
911 | /* Write OFDM timings on 5212*/ | ||
912 | if (ah->ah_version == AR5K_AR5212 && | ||
913 | channel->hw_value & CHANNEL_OFDM) { | ||
914 | ret = ath5k_hw_write_ofdm_timings(ah, channel); | ||
915 | if (ret) | ||
916 | return ret; | ||
917 | } | ||
918 | |||
919 | /*Enable/disable 802.11b mode on 5111 | ||
920 | (enable 2111 frequency converter + CCK)*/ | ||
921 | if (ah->ah_radio == AR5K_RF5111) { | ||
922 | if (mode == AR5K_MODE_11B) | ||
923 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, | ||
924 | AR5K_TXCFG_B_MODE); | ||
925 | else | ||
926 | AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, | ||
927 | AR5K_TXCFG_B_MODE); | ||
928 | } | ||
929 | |||
930 | /* | ||
931 | * Set channel and calibrate the PHY | ||
932 | */ | ||
933 | ret = ath5k_hw_channel(ah, channel); | ||
934 | if (ret) | ||
935 | return ret; | ||
936 | |||
937 | /* Set antenna mode */ | ||
938 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL, | ||
939 | ah->ah_antenna[ee_mode][0], 0xfffffc06); | ||
940 | |||
941 | /* | ||
942 | * In case a fixed antenna was set as default | ||
943 | * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE | ||
944 | * registers. | ||
945 | */ | ||
946 | if (s_ant != 0){ | ||
947 | if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */ | ||
948 | ant[0] = ant[1] = AR5K_ANT_FIXED_A; | ||
949 | else /* 2 - Aux */ | ||
950 | ant[0] = ant[1] = AR5K_ANT_FIXED_B; | ||
951 | } else { | ||
952 | ant[0] = AR5K_ANT_FIXED_A; | ||
953 | ant[1] = AR5K_ANT_FIXED_B; | ||
954 | } | ||
955 | |||
956 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]], | ||
957 | AR5K_PHY_ANT_SWITCH_TABLE_0); | ||
958 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]], | ||
959 | AR5K_PHY_ANT_SWITCH_TABLE_1); | ||
960 | |||
961 | /* Commit values from EEPROM */ | ||
962 | if (ah->ah_radio == AR5K_RF5111) | ||
963 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL, | ||
964 | AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip); | ||
965 | |||
966 | ath5k_hw_reg_write(ah, | ||
967 | AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), | ||
968 | AR5K_PHY_NFTHRES); | ||
969 | |||
970 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING, | ||
971 | (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, | ||
972 | 0xffffc07f); | ||
973 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN, | ||
974 | (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, | ||
975 | 0xfffc0fff); | ||
976 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
977 | (ee->ee_adc_desired_size[ee_mode] & 0x00ff) | | ||
978 | ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), | ||
979 | 0xffff0000); | ||
980 | |||
981 | ath5k_hw_reg_write(ah, | ||
982 | (ee->ee_tx_end2xpa_disable[ee_mode] << 24) | | ||
983 | (ee->ee_tx_end2xpa_disable[ee_mode] << 16) | | ||
984 | (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) | | ||
985 | (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4); | ||
986 | |||
987 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3, | ||
988 | ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff); | ||
989 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF, | ||
990 | (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff); | ||
991 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01); | ||
992 | |||
993 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
994 | AR5K_PHY_IQ_CORR_ENABLE | | ||
995 | (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | | ||
996 | ee->ee_q_cal[ee_mode]); | ||
997 | |||
998 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
999 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, | ||
1000 | AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, | ||
1001 | ee->ee_margin_tx_rx[ee_mode]); | ||
1002 | |||
1003 | } else { | ||
1004 | mdelay(1); | ||
1005 | /* Disable phy and wait */ | ||
1006 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); | ||
1007 | mdelay(1); | ||
1008 | } | ||
1009 | |||
1010 | /* | ||
1011 | * Restore saved values | ||
1012 | */ | ||
1013 | /*DCU/Antenna selection not available on 5210*/ | ||
1014 | if (ah->ah_version != AR5K_AR5210) { | ||
1015 | ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0)); | ||
1016 | ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA); | ||
1017 | } | ||
1018 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]); | ||
1019 | ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); | ||
1020 | ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); | ||
1021 | |||
1022 | /* | ||
1023 | * Misc | ||
1024 | */ | ||
1025 | /* XXX: add ah->aid once mac80211 gives this to us */ | ||
1026 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); | ||
1027 | |||
1028 | ath5k_hw_set_opmode(ah); | ||
1029 | /*PISR/SISR Not available on 5210*/ | ||
1030 | if (ah->ah_version != AR5K_AR5210) { | ||
1031 | ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); | ||
1032 | /* If we later allow tuning for this, store into sc structure */ | ||
1033 | data = AR5K_TUNE_RSSI_THRES | | ||
1034 | AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S; | ||
1035 | ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR); | ||
1036 | } | ||
1037 | |||
1038 | /* | ||
1039 | * Set Rx/Tx DMA Configuration | ||
1040 | * | ||
1041 | * Set maximum DMA size (512) except for PCI-E cards since | ||
1042 | * it causes rx overruns and tx errors (tested on 5424 but since | ||
1043 | * rx overruns also occur on 5416/5418 with madwifi we set 128 | ||
1044 | * for all PCI-E cards to be safe). | ||
1045 | * | ||
1046 | * In dumps this is 128 for allchips. | ||
1047 | * | ||
1048 | * XXX: need to check 5210 for this | ||
1049 | * TODO: Check out tx triger level, it's always 64 on dumps but I | ||
1050 | * guess we can tweak it and see how it goes ;-) | ||
1051 | */ | ||
1052 | dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B; | ||
1053 | if (ah->ah_version != AR5K_AR5210) { | ||
1054 | AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, | ||
1055 | AR5K_TXCFG_SDMAMR, dma_size); | ||
1056 | AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, | ||
1057 | AR5K_RXCFG_SDMAMW, dma_size); | ||
1058 | } | ||
1059 | |||
1060 | /* | ||
1061 | * Enable the PHY and wait until completion | ||
1062 | */ | ||
1063 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); | ||
1064 | |||
1065 | /* | ||
1066 | * On 5211+ read activation -> rx delay | ||
1067 | * and use it. | ||
1068 | */ | ||
1069 | if (ah->ah_version != AR5K_AR5210) { | ||
1070 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | ||
1071 | AR5K_PHY_RX_DELAY_M; | ||
1072 | data = (channel->hw_value & CHANNEL_CCK) ? | ||
1073 | ((data << 2) / 22) : (data / 10); | ||
1074 | |||
1075 | udelay(100 + (2 * data)); | ||
1076 | data = 0; | ||
1077 | } else { | ||
1078 | mdelay(1); | ||
1079 | } | ||
1080 | |||
1081 | /* | ||
1082 | * Perform ADC test (?) | ||
1083 | */ | ||
1084 | data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); | ||
1085 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); | ||
1086 | for (i = 0; i <= 20; i++) { | ||
1087 | if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) | ||
1088 | break; | ||
1089 | udelay(200); | ||
1090 | } | ||
1091 | ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1); | ||
1092 | data = 0; | ||
1093 | |||
1094 | /* | ||
1095 | * Start automatic gain calibration | ||
1096 | * | ||
1097 | * During AGC calibration RX path is re-routed to | ||
1098 | * a signal detector so we don't receive anything. | ||
1099 | * | ||
1100 | * This method is used to calibrate some static offsets | ||
1101 | * used together with on-the fly I/Q calibration (the | ||
1102 | * one performed via ath5k_hw_phy_calibrate), that doesn't | ||
1103 | * interrupt rx path. | ||
1104 | * | ||
1105 | * If we are in a noisy environment AGC calibration may time | ||
1106 | * out. | ||
1107 | */ | ||
1108 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | ||
1109 | AR5K_PHY_AGCCTL_CAL); | ||
1110 | |||
1111 | /* At the same time start I/Q calibration for QAM constellation | ||
1112 | * -no need for CCK- */ | ||
1113 | ah->ah_calibration = false; | ||
1114 | if (!(mode == AR5K_MODE_11B)) { | ||
1115 | ah->ah_calibration = true; | ||
1116 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, | ||
1117 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); | ||
1118 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
1119 | AR5K_PHY_IQ_RUN); | ||
1120 | } | ||
1121 | |||
1122 | /* Wait for gain calibration to finish (we check for I/Q calibration | ||
1123 | * during ath5k_phy_calibrate) */ | ||
1124 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | ||
1125 | AR5K_PHY_AGCCTL_CAL, 0, false)) { | ||
1126 | ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", | ||
1127 | channel->center_freq); | ||
1128 | return -EAGAIN; | ||
1129 | } | ||
1130 | |||
1131 | /* | ||
1132 | * Start noise floor calibration | ||
1133 | * | ||
1134 | * If we run NF calibration before AGC, it always times out. | ||
1135 | * Binary HAL starts NF and AGC calibration at the same time | ||
1136 | * and only waits for AGC to finish. I believe that's wrong because | ||
1137 | * during NF calibration, rx path is also routed to a detector, so if | ||
1138 | * it doesn't finish we won't have RX. | ||
1139 | * | ||
1140 | * XXX: Find an interval that's OK for all cards... | ||
1141 | */ | ||
1142 | ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); | ||
1143 | if (ret) | ||
1144 | return ret; | ||
1145 | |||
1146 | /* | ||
1147 | * Reset queues and start beacon timers at the end of the reset routine | ||
1148 | */ | ||
1149 | for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { | ||
1150 | /*No QCU on 5210*/ | ||
1151 | if (ah->ah_version != AR5K_AR5210) | ||
1152 | AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i); | ||
1153 | |||
1154 | ret = ath5k_hw_reset_tx_queue(ah, i); | ||
1155 | if (ret) { | ||
1156 | ATH5K_ERR(ah->ah_sc, | ||
1157 | "failed to reset TX queue #%d\n", i); | ||
1158 | return ret; | ||
1159 | } | ||
1160 | } | ||
1161 | |||
1162 | /* Pre-enable interrupts on 5211/5212*/ | ||
1163 | if (ah->ah_version != AR5K_AR5210) | ||
1164 | ath5k_hw_set_intr(ah, AR5K_INT_RX | AR5K_INT_TX | | ||
1165 | AR5K_INT_FATAL); | ||
1166 | |||
1167 | /* | ||
1168 | * Set RF kill flags if supported by the device (read from the EEPROM) | ||
1169 | * Disable gpio_intr for now since it results system hang. | ||
1170 | * TODO: Handle this in ath5k_intr | ||
1171 | */ | ||
1172 | #if 0 | ||
1173 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { | ||
1174 | ath5k_hw_set_gpio_input(ah, 0); | ||
1175 | ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0); | ||
1176 | if (ah->ah_gpio[0] == 0) | ||
1177 | ath5k_hw_set_gpio_intr(ah, 0, 1); | ||
1178 | else | ||
1179 | ath5k_hw_set_gpio_intr(ah, 0, 0); | ||
1180 | } | ||
1181 | #endif | ||
1182 | |||
1183 | /* | ||
1184 | * Set the 32MHz reference clock on 5212 phy clock sleep register | ||
1185 | * | ||
1186 | * TODO: Find out how to switch to external 32Khz clock to save power | ||
1187 | */ | ||
1188 | if (ah->ah_version == AR5K_AR5212) { | ||
1189 | ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR); | ||
1190 | ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT); | ||
1191 | ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL); | ||
1192 | ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); | ||
1193 | ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); | ||
1194 | ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING); | ||
1195 | |||
1196 | data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ; | ||
1197 | data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ? | ||
1198 | 0x00000f80 : 0x00001380 ; | ||
1199 | ath5k_hw_reg_write(ah, data, AR5K_USEC_5211); | ||
1200 | data = 0; | ||
1201 | } | ||
1202 | |||
1203 | if (ah->ah_version == AR5K_AR5212) { | ||
1204 | ath5k_hw_reg_write(ah, 0x000100aa, 0x8118); | ||
1205 | ath5k_hw_reg_write(ah, 0x00003210, 0x811c); | ||
1206 | ath5k_hw_reg_write(ah, 0x00000052, 0x8108); | ||
1207 | if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413) | ||
1208 | ath5k_hw_reg_write(ah, 0x00000004, 0x8120); | ||
1209 | } | ||
1210 | |||
1211 | /* | ||
1212 | * Disable beacons and reset the register | ||
1213 | */ | ||
1214 | AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | | ||
1215 | AR5K_BEACON_RESET_TSF); | ||
1216 | |||
1217 | return 0; | ||
1218 | } | ||
1219 | |||
1220 | /* | ||
1221 | * Reset chipset | ||
1222 | */ | ||
1223 | static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) | ||
1224 | { | ||
1225 | int ret; | ||
1226 | u32 mask = val ? val : ~0U; | ||
1227 | |||
1228 | ATH5K_TRACE(ah->ah_sc); | ||
1229 | |||
1230 | /* Read-and-clear RX Descriptor Pointer*/ | ||
1231 | ath5k_hw_reg_read(ah, AR5K_RXDP); | ||
1232 | |||
1233 | /* | ||
1234 | * Reset the device and wait until success | ||
1235 | */ | ||
1236 | ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL); | ||
1237 | |||
1238 | /* Wait at least 128 PCI clocks */ | ||
1239 | udelay(15); | ||
1240 | |||
1241 | if (ah->ah_version == AR5K_AR5210) { | ||
1242 | val &= AR5K_RESET_CTL_CHIP; | ||
1243 | mask &= AR5K_RESET_CTL_CHIP; | ||
1244 | } else { | ||
1245 | val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; | ||
1246 | mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; | ||
1247 | } | ||
1248 | |||
1249 | ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false); | ||
1250 | |||
1251 | /* | ||
1252 | * Reset configuration register (for hw byte-swap). Note that this | ||
1253 | * is only set for big endian. We do the necessary magic in | ||
1254 | * AR5K_INIT_CFG. | ||
1255 | */ | ||
1256 | if ((val & AR5K_RESET_CTL_PCU) == 0) | ||
1257 | ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG); | ||
1258 | |||
1259 | return ret; | ||
1260 | } | ||
1261 | |||
1262 | /* | ||
1263 | * Power management functions | ||
1264 | */ | ||
1265 | |||
1266 | /* | ||
1267 | * Sleep control | ||
1268 | */ | ||
1269 | int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, | ||
1270 | bool set_chip, u16 sleep_duration) | ||
1271 | { | ||
1272 | unsigned int i; | ||
1273 | u32 staid, data; | ||
1274 | |||
1275 | ATH5K_TRACE(ah->ah_sc); | ||
1276 | staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); | ||
1277 | |||
1278 | switch (mode) { | ||
1279 | case AR5K_PM_AUTO: | ||
1280 | staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA; | ||
1281 | /* fallthrough */ | ||
1282 | case AR5K_PM_NETWORK_SLEEP: | ||
1283 | if (set_chip) | ||
1284 | ath5k_hw_reg_write(ah, | ||
1285 | AR5K_SLEEP_CTL_SLE_ALLOW | | ||
1286 | sleep_duration, | ||
1287 | AR5K_SLEEP_CTL); | ||
1288 | |||
1289 | staid |= AR5K_STA_ID1_PWR_SV; | ||
1290 | break; | ||
1291 | |||
1292 | case AR5K_PM_FULL_SLEEP: | ||
1293 | if (set_chip) | ||
1294 | ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP, | ||
1295 | AR5K_SLEEP_CTL); | ||
1296 | |||
1297 | staid |= AR5K_STA_ID1_PWR_SV; | ||
1298 | break; | ||
1299 | |||
1300 | case AR5K_PM_AWAKE: | ||
1301 | |||
1302 | staid &= ~AR5K_STA_ID1_PWR_SV; | ||
1303 | |||
1304 | if (!set_chip) | ||
1305 | goto commit; | ||
1306 | |||
1307 | /* Preserve sleep duration */ | ||
1308 | data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL); | ||
1309 | if( data & 0xffc00000 ){ | ||
1310 | data = 0; | ||
1311 | } else { | ||
1312 | data = data & 0xfffcffff; | ||
1313 | } | ||
1314 | |||
1315 | ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); | ||
1316 | udelay(15); | ||
1317 | |||
1318 | for (i = 50; i > 0; i--) { | ||
1319 | /* Check if the chip did wake up */ | ||
1320 | if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) & | ||
1321 | AR5K_PCICFG_SPWR_DN) == 0) | ||
1322 | break; | ||
1323 | |||
1324 | /* Wait a bit and retry */ | ||
1325 | udelay(200); | ||
1326 | ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); | ||
1327 | } | ||
1328 | |||
1329 | /* Fail if the chip didn't wake up */ | ||
1330 | if (i <= 0) | ||
1331 | return -EIO; | ||
1332 | |||
1333 | break; | ||
1334 | |||
1335 | default: | ||
1336 | return -EINVAL; | ||
1337 | } | ||
1338 | |||
1339 | commit: | ||
1340 | ah->ah_power_mode = mode; | ||
1341 | ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1); | ||
1342 | |||
1343 | return 0; | ||
1344 | } | ||
1345 | |||
1346 | /***********************\ | ||
1347 | DMA Related Functions | ||
1348 | \***********************/ | ||
1349 | |||
1350 | /* | ||
1351 | * Receive functions | ||
1352 | */ | ||
1353 | |||
1354 | /* | ||
1355 | * Start DMA receive | ||
1356 | */ | ||
1357 | void ath5k_hw_start_rx(struct ath5k_hw *ah) | ||
1358 | { | ||
1359 | ATH5K_TRACE(ah->ah_sc); | ||
1360 | ath5k_hw_reg_write(ah, AR5K_CR_RXE, AR5K_CR); | ||
1361 | ath5k_hw_reg_read(ah, AR5K_CR); | ||
1362 | } | ||
1363 | |||
1364 | /* | ||
1365 | * Stop DMA receive | ||
1366 | */ | ||
1367 | int ath5k_hw_stop_rx_dma(struct ath5k_hw *ah) | ||
1368 | { | ||
1369 | unsigned int i; | ||
1370 | |||
1371 | ATH5K_TRACE(ah->ah_sc); | ||
1372 | ath5k_hw_reg_write(ah, AR5K_CR_RXD, AR5K_CR); | ||
1373 | |||
1374 | /* | ||
1375 | * It may take some time to disable the DMA receive unit | ||
1376 | */ | ||
1377 | for (i = 2000; i > 0 && | ||
1378 | (ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_CR_RXE) != 0; | ||
1379 | i--) | ||
1380 | udelay(10); | ||
1381 | |||
1382 | return i ? 0 : -EBUSY; | ||
1383 | } | ||
1384 | |||
1385 | /* | ||
1386 | * Get the address of the RX Descriptor | ||
1387 | */ | ||
1388 | u32 ath5k_hw_get_rx_buf(struct ath5k_hw *ah) | ||
1389 | { | ||
1390 | return ath5k_hw_reg_read(ah, AR5K_RXDP); | ||
1391 | } | ||
1392 | |||
1393 | /* | ||
1394 | * Set the address of the RX Descriptor | ||
1395 | */ | ||
1396 | void ath5k_hw_put_rx_buf(struct ath5k_hw *ah, u32 phys_addr) | ||
1397 | { | ||
1398 | ATH5K_TRACE(ah->ah_sc); | ||
1399 | |||
1400 | /*TODO:Shouldn't we check if RX is enabled first ?*/ | ||
1401 | ath5k_hw_reg_write(ah, phys_addr, AR5K_RXDP); | ||
1402 | } | ||
1403 | |||
1404 | /* | ||
1405 | * Transmit functions | ||
1406 | */ | ||
1407 | |||
1408 | /* | ||
1409 | * Start DMA transmit for a specific queue | ||
1410 | * (see also QCU/DCU functions) | ||
1411 | */ | ||
1412 | int ath5k_hw_tx_start(struct ath5k_hw *ah, unsigned int queue) | ||
1413 | { | ||
1414 | u32 tx_queue; | ||
1415 | |||
1416 | ATH5K_TRACE(ah->ah_sc); | ||
1417 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
1418 | |||
1419 | /* Return if queue is declared inactive */ | ||
1420 | if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
1421 | return -EIO; | ||
1422 | |||
1423 | if (ah->ah_version == AR5K_AR5210) { | ||
1424 | tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); | ||
1425 | |||
1426 | /* | ||
1427 | * Set the queue by type on 5210 | ||
1428 | */ | ||
1429 | switch (ah->ah_txq[queue].tqi_type) { | ||
1430 | case AR5K_TX_QUEUE_DATA: | ||
1431 | tx_queue |= AR5K_CR_TXE0 & ~AR5K_CR_TXD0; | ||
1432 | break; | ||
1433 | case AR5K_TX_QUEUE_BEACON: | ||
1434 | tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1; | ||
1435 | ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE, | ||
1436 | AR5K_BSR); | ||
1437 | break; | ||
1438 | case AR5K_TX_QUEUE_CAB: | ||
1439 | tx_queue |= AR5K_CR_TXE1 & ~AR5K_CR_TXD1; | ||
1440 | ath5k_hw_reg_write(ah, AR5K_BCR_TQ1FV | AR5K_BCR_TQ1V | | ||
1441 | AR5K_BCR_BDMAE, AR5K_BSR); | ||
1442 | break; | ||
1443 | default: | ||
1444 | return -EINVAL; | ||
1445 | } | ||
1446 | /* Start queue */ | ||
1447 | ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); | ||
1448 | ath5k_hw_reg_read(ah, AR5K_CR); | ||
1449 | } else { | ||
1450 | /* Return if queue is disabled */ | ||
1451 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXD, queue)) | ||
1452 | return -EIO; | ||
1453 | |||
1454 | /* Start queue */ | ||
1455 | AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXE, queue); | ||
1456 | } | ||
1457 | |||
1458 | return 0; | ||
1459 | } | ||
1460 | |||
1461 | /* | ||
1462 | * Stop DMA transmit for a specific queue | ||
1463 | * (see also QCU/DCU functions) | ||
1464 | */ | ||
1465 | int ath5k_hw_stop_tx_dma(struct ath5k_hw *ah, unsigned int queue) | ||
1466 | { | ||
1467 | unsigned int i = 100; | ||
1468 | u32 tx_queue, pending; | ||
1469 | |||
1470 | ATH5K_TRACE(ah->ah_sc); | ||
1471 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
1472 | |||
1473 | /* Return if queue is declared inactive */ | ||
1474 | if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
1475 | return -EIO; | ||
1476 | |||
1477 | if (ah->ah_version == AR5K_AR5210) { | ||
1478 | tx_queue = ath5k_hw_reg_read(ah, AR5K_CR); | ||
1479 | |||
1480 | /* | ||
1481 | * Set by queue type | ||
1482 | */ | ||
1483 | switch (ah->ah_txq[queue].tqi_type) { | ||
1484 | case AR5K_TX_QUEUE_DATA: | ||
1485 | tx_queue |= AR5K_CR_TXD0 & ~AR5K_CR_TXE0; | ||
1486 | break; | ||
1487 | case AR5K_TX_QUEUE_BEACON: | ||
1488 | case AR5K_TX_QUEUE_CAB: | ||
1489 | /* XXX Fix me... */ | ||
1490 | tx_queue |= AR5K_CR_TXD1 & ~AR5K_CR_TXD1; | ||
1491 | ath5k_hw_reg_write(ah, 0, AR5K_BSR); | ||
1492 | break; | ||
1493 | default: | ||
1494 | return -EINVAL; | ||
1495 | } | ||
1496 | |||
1497 | /* Stop queue */ | ||
1498 | ath5k_hw_reg_write(ah, tx_queue, AR5K_CR); | ||
1499 | ath5k_hw_reg_read(ah, AR5K_CR); | ||
1500 | } else { | ||
1501 | /* | ||
1502 | * Schedule TX disable and wait until queue is empty | ||
1503 | */ | ||
1504 | AR5K_REG_WRITE_Q(ah, AR5K_QCU_TXD, queue); | ||
1505 | |||
1506 | /*Check for pending frames*/ | ||
1507 | do { | ||
1508 | pending = ath5k_hw_reg_read(ah, | ||
1509 | AR5K_QUEUE_STATUS(queue)) & | ||
1510 | AR5K_QCU_STS_FRMPENDCNT; | ||
1511 | udelay(100); | ||
1512 | } while (--i && pending); | ||
1513 | |||
1514 | /* Clear register */ | ||
1515 | ath5k_hw_reg_write(ah, 0, AR5K_QCU_TXD); | ||
1516 | if (pending) | ||
1517 | return -EBUSY; | ||
1518 | } | ||
1519 | |||
1520 | /* TODO: Check for success else return error */ | ||
1521 | return 0; | ||
1522 | } | ||
1523 | |||
1524 | /* | ||
1525 | * Get the address of the TX Descriptor for a specific queue | ||
1526 | * (see also QCU/DCU functions) | ||
1527 | */ | ||
1528 | u32 ath5k_hw_get_tx_buf(struct ath5k_hw *ah, unsigned int queue) | ||
1529 | { | ||
1530 | u16 tx_reg; | ||
1531 | |||
1532 | ATH5K_TRACE(ah->ah_sc); | ||
1533 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
1534 | |||
1535 | /* | ||
1536 | * Get the transmit queue descriptor pointer from the selected queue | ||
1537 | */ | ||
1538 | /*5210 doesn't have QCU*/ | ||
1539 | if (ah->ah_version == AR5K_AR5210) { | ||
1540 | switch (ah->ah_txq[queue].tqi_type) { | ||
1541 | case AR5K_TX_QUEUE_DATA: | ||
1542 | tx_reg = AR5K_NOQCU_TXDP0; | ||
1543 | break; | ||
1544 | case AR5K_TX_QUEUE_BEACON: | ||
1545 | case AR5K_TX_QUEUE_CAB: | ||
1546 | tx_reg = AR5K_NOQCU_TXDP1; | ||
1547 | break; | ||
1548 | default: | ||
1549 | return 0xffffffff; | ||
1550 | } | ||
1551 | } else { | ||
1552 | tx_reg = AR5K_QUEUE_TXDP(queue); | ||
1553 | } | ||
1554 | |||
1555 | return ath5k_hw_reg_read(ah, tx_reg); | ||
1556 | } | ||
1557 | |||
1558 | /* | ||
1559 | * Set the address of the TX Descriptor for a specific queue | ||
1560 | * (see also QCU/DCU functions) | ||
1561 | */ | ||
1562 | int ath5k_hw_put_tx_buf(struct ath5k_hw *ah, unsigned int queue, u32 phys_addr) | ||
1563 | { | ||
1564 | u16 tx_reg; | ||
1565 | |||
1566 | ATH5K_TRACE(ah->ah_sc); | ||
1567 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
1568 | |||
1569 | /* | ||
1570 | * Set the transmit queue descriptor pointer register by type | ||
1571 | * on 5210 | ||
1572 | */ | ||
1573 | if (ah->ah_version == AR5K_AR5210) { | ||
1574 | switch (ah->ah_txq[queue].tqi_type) { | ||
1575 | case AR5K_TX_QUEUE_DATA: | ||
1576 | tx_reg = AR5K_NOQCU_TXDP0; | ||
1577 | break; | ||
1578 | case AR5K_TX_QUEUE_BEACON: | ||
1579 | case AR5K_TX_QUEUE_CAB: | ||
1580 | tx_reg = AR5K_NOQCU_TXDP1; | ||
1581 | break; | ||
1582 | default: | ||
1583 | return -EINVAL; | ||
1584 | } | ||
1585 | } else { | ||
1586 | /* | ||
1587 | * Set the transmit queue descriptor pointer for | ||
1588 | * the selected queue on QCU for 5211+ | ||
1589 | * (this won't work if the queue is still active) | ||
1590 | */ | ||
1591 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, queue)) | ||
1592 | return -EIO; | ||
1593 | |||
1594 | tx_reg = AR5K_QUEUE_TXDP(queue); | ||
1595 | } | ||
1596 | |||
1597 | /* Set descriptor pointer */ | ||
1598 | ath5k_hw_reg_write(ah, phys_addr, tx_reg); | ||
1599 | |||
1600 | return 0; | ||
1601 | } | ||
1602 | |||
1603 | /* | ||
1604 | * Update tx trigger level | ||
1605 | */ | ||
1606 | int ath5k_hw_update_tx_triglevel(struct ath5k_hw *ah, bool increase) | ||
1607 | { | ||
1608 | u32 trigger_level, imr; | ||
1609 | int ret = -EIO; | ||
1610 | |||
1611 | ATH5K_TRACE(ah->ah_sc); | ||
1612 | |||
1613 | /* | ||
1614 | * Disable interrupts by setting the mask | ||
1615 | */ | ||
1616 | imr = ath5k_hw_set_intr(ah, ah->ah_imr & ~AR5K_INT_GLOBAL); | ||
1617 | |||
1618 | /*TODO: Boundary check on trigger_level*/ | ||
1619 | trigger_level = AR5K_REG_MS(ath5k_hw_reg_read(ah, AR5K_TXCFG), | ||
1620 | AR5K_TXCFG_TXFULL); | ||
1621 | |||
1622 | if (!increase) { | ||
1623 | if (--trigger_level < AR5K_TUNE_MIN_TX_FIFO_THRES) | ||
1624 | goto done; | ||
1625 | } else | ||
1626 | trigger_level += | ||
1627 | ((AR5K_TUNE_MAX_TX_FIFO_THRES - trigger_level) / 2); | ||
1628 | |||
1629 | /* | ||
1630 | * Update trigger level on success | ||
1631 | */ | ||
1632 | if (ah->ah_version == AR5K_AR5210) | ||
1633 | ath5k_hw_reg_write(ah, trigger_level, AR5K_TRIG_LVL); | ||
1634 | else | ||
1635 | AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, | ||
1636 | AR5K_TXCFG_TXFULL, trigger_level); | ||
1637 | |||
1638 | ret = 0; | ||
1639 | |||
1640 | done: | ||
1641 | /* | ||
1642 | * Restore interrupt mask | ||
1643 | */ | ||
1644 | ath5k_hw_set_intr(ah, imr); | ||
1645 | |||
1646 | return ret; | ||
1647 | } | ||
1648 | |||
1649 | /* | ||
1650 | * Interrupt handling | ||
1651 | */ | ||
1652 | |||
1653 | /* | ||
1654 | * Check if we have pending interrupts | ||
1655 | */ | ||
1656 | bool ath5k_hw_is_intr_pending(struct ath5k_hw *ah) | ||
1657 | { | ||
1658 | ATH5K_TRACE(ah->ah_sc); | ||
1659 | return ath5k_hw_reg_read(ah, AR5K_INTPEND); | ||
1660 | } | ||
1661 | |||
1662 | /* | ||
1663 | * Get interrupt mask (ISR) | ||
1664 | */ | ||
1665 | int ath5k_hw_get_isr(struct ath5k_hw *ah, enum ath5k_int *interrupt_mask) | ||
1666 | { | ||
1667 | u32 data; | ||
1668 | |||
1669 | ATH5K_TRACE(ah->ah_sc); | ||
1670 | |||
1671 | /* | ||
1672 | * Read interrupt status from the Interrupt Status register | ||
1673 | * on 5210 | ||
1674 | */ | ||
1675 | if (ah->ah_version == AR5K_AR5210) { | ||
1676 | data = ath5k_hw_reg_read(ah, AR5K_ISR); | ||
1677 | if (unlikely(data == AR5K_INT_NOCARD)) { | ||
1678 | *interrupt_mask = data; | ||
1679 | return -ENODEV; | ||
1680 | } | ||
1681 | } else { | ||
1682 | /* | ||
1683 | * Read interrupt status from the Read-And-Clear shadow register | ||
1684 | * Note: PISR/SISR Not available on 5210 | ||
1685 | */ | ||
1686 | data = ath5k_hw_reg_read(ah, AR5K_RAC_PISR); | ||
1687 | } | ||
1688 | |||
1689 | /* | ||
1690 | * Get abstract interrupt mask (driver-compatible) | ||
1691 | */ | ||
1692 | *interrupt_mask = (data & AR5K_INT_COMMON) & ah->ah_imr; | ||
1693 | |||
1694 | if (unlikely(data == AR5K_INT_NOCARD)) | ||
1695 | return -ENODEV; | ||
1696 | |||
1697 | if (data & (AR5K_ISR_RXOK | AR5K_ISR_RXERR)) | ||
1698 | *interrupt_mask |= AR5K_INT_RX; | ||
1699 | |||
1700 | if (data & (AR5K_ISR_TXOK | AR5K_ISR_TXERR | ||
1701 | | AR5K_ISR_TXDESC | AR5K_ISR_TXEOL)) | ||
1702 | *interrupt_mask |= AR5K_INT_TX; | ||
1703 | |||
1704 | if (ah->ah_version != AR5K_AR5210) { | ||
1705 | /*HIU = Host Interface Unit (PCI etc)*/ | ||
1706 | if (unlikely(data & (AR5K_ISR_HIUERR))) | ||
1707 | *interrupt_mask |= AR5K_INT_FATAL; | ||
1708 | |||
1709 | /*Beacon Not Ready*/ | ||
1710 | if (unlikely(data & (AR5K_ISR_BNR))) | ||
1711 | *interrupt_mask |= AR5K_INT_BNR; | ||
1712 | } | ||
1713 | |||
1714 | /* | ||
1715 | * XXX: BMISS interrupts may occur after association. | ||
1716 | * I found this on 5210 code but it needs testing. If this is | ||
1717 | * true we should disable them before assoc and re-enable them | ||
1718 | * after a successfull assoc + some jiffies. | ||
1719 | */ | ||
1720 | #if 0 | ||
1721 | interrupt_mask &= ~AR5K_INT_BMISS; | ||
1722 | #endif | ||
1723 | |||
1724 | /* | ||
1725 | * In case we didn't handle anything, | ||
1726 | * print the register value. | ||
1727 | */ | ||
1728 | if (unlikely(*interrupt_mask == 0 && net_ratelimit())) | ||
1729 | ATH5K_PRINTF("0x%08x\n", data); | ||
1730 | |||
1731 | return 0; | ||
1732 | } | ||
1733 | |||
1734 | /* | ||
1735 | * Set interrupt mask | ||
1736 | */ | ||
1737 | enum ath5k_int ath5k_hw_set_intr(struct ath5k_hw *ah, enum ath5k_int new_mask) | ||
1738 | { | ||
1739 | enum ath5k_int old_mask, int_mask; | ||
1740 | |||
1741 | /* | ||
1742 | * Disable card interrupts to prevent any race conditions | ||
1743 | * (they will be re-enabled afterwards). | ||
1744 | */ | ||
1745 | ath5k_hw_reg_write(ah, AR5K_IER_DISABLE, AR5K_IER); | ||
1746 | ath5k_hw_reg_read(ah, AR5K_IER); | ||
1747 | |||
1748 | old_mask = ah->ah_imr; | ||
1749 | |||
1750 | /* | ||
1751 | * Add additional, chipset-dependent interrupt mask flags | ||
1752 | * and write them to the IMR (interrupt mask register). | ||
1753 | */ | ||
1754 | int_mask = new_mask & AR5K_INT_COMMON; | ||
1755 | |||
1756 | if (new_mask & AR5K_INT_RX) | ||
1757 | int_mask |= AR5K_IMR_RXOK | AR5K_IMR_RXERR | AR5K_IMR_RXORN | | ||
1758 | AR5K_IMR_RXDESC; | ||
1759 | |||
1760 | if (new_mask & AR5K_INT_TX) | ||
1761 | int_mask |= AR5K_IMR_TXOK | AR5K_IMR_TXERR | AR5K_IMR_TXDESC | | ||
1762 | AR5K_IMR_TXURN; | ||
1763 | |||
1764 | if (ah->ah_version != AR5K_AR5210) { | ||
1765 | if (new_mask & AR5K_INT_FATAL) { | ||
1766 | int_mask |= AR5K_IMR_HIUERR; | ||
1767 | AR5K_REG_ENABLE_BITS(ah, AR5K_SIMR2, AR5K_SIMR2_MCABT | | ||
1768 | AR5K_SIMR2_SSERR | AR5K_SIMR2_DPERR); | ||
1769 | } | ||
1770 | } | ||
1771 | |||
1772 | ath5k_hw_reg_write(ah, int_mask, AR5K_PIMR); | ||
1773 | |||
1774 | /* Store new interrupt mask */ | ||
1775 | ah->ah_imr = new_mask; | ||
1776 | |||
1777 | /* ..re-enable interrupts */ | ||
1778 | ath5k_hw_reg_write(ah, AR5K_IER_ENABLE, AR5K_IER); | ||
1779 | ath5k_hw_reg_read(ah, AR5K_IER); | ||
1780 | |||
1781 | return old_mask; | ||
1782 | } | ||
1783 | |||
1784 | |||
1785 | /*************************\ | ||
1786 | EEPROM access functions | ||
1787 | \*************************/ | ||
1788 | |||
1789 | /* | ||
1790 | * Read from eeprom | ||
1791 | */ | ||
1792 | static int ath5k_hw_eeprom_read(struct ath5k_hw *ah, u32 offset, u16 *data) | ||
1793 | { | ||
1794 | u32 status, timeout; | ||
1795 | |||
1796 | ATH5K_TRACE(ah->ah_sc); | ||
1797 | /* | ||
1798 | * Initialize EEPROM access | ||
1799 | */ | ||
1800 | if (ah->ah_version == AR5K_AR5210) { | ||
1801 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); | ||
1802 | (void)ath5k_hw_reg_read(ah, AR5K_EEPROM_BASE + (4 * offset)); | ||
1803 | } else { | ||
1804 | ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); | ||
1805 | AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, | ||
1806 | AR5K_EEPROM_CMD_READ); | ||
1807 | } | ||
1808 | |||
1809 | for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { | ||
1810 | status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); | ||
1811 | if (status & AR5K_EEPROM_STAT_RDDONE) { | ||
1812 | if (status & AR5K_EEPROM_STAT_RDERR) | ||
1813 | return -EIO; | ||
1814 | *data = (u16)(ath5k_hw_reg_read(ah, AR5K_EEPROM_DATA) & | ||
1815 | 0xffff); | ||
1816 | return 0; | ||
1817 | } | ||
1818 | udelay(15); | ||
1819 | } | ||
1820 | |||
1821 | return -ETIMEDOUT; | ||
1822 | } | ||
1823 | |||
1824 | /* | ||
1825 | * Write to eeprom - currently disabled, use at your own risk | ||
1826 | */ | ||
1827 | #if 0 | ||
1828 | static int ath5k_hw_eeprom_write(struct ath5k_hw *ah, u32 offset, u16 data) | ||
1829 | { | ||
1830 | |||
1831 | u32 status, timeout; | ||
1832 | |||
1833 | ATH5K_TRACE(ah->ah_sc); | ||
1834 | |||
1835 | /* | ||
1836 | * Initialize eeprom access | ||
1837 | */ | ||
1838 | |||
1839 | if (ah->ah_version == AR5K_AR5210) { | ||
1840 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_EEAE); | ||
1841 | } else { | ||
1842 | AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, | ||
1843 | AR5K_EEPROM_CMD_RESET); | ||
1844 | } | ||
1845 | |||
1846 | /* | ||
1847 | * Write data to data register | ||
1848 | */ | ||
1849 | |||
1850 | if (ah->ah_version == AR5K_AR5210) { | ||
1851 | ath5k_hw_reg_write(ah, data, AR5K_EEPROM_BASE + (4 * offset)); | ||
1852 | } else { | ||
1853 | ath5k_hw_reg_write(ah, offset, AR5K_EEPROM_BASE); | ||
1854 | ath5k_hw_reg_write(ah, data, AR5K_EEPROM_DATA); | ||
1855 | AR5K_REG_ENABLE_BITS(ah, AR5K_EEPROM_CMD, | ||
1856 | AR5K_EEPROM_CMD_WRITE); | ||
1857 | } | ||
1858 | |||
1859 | /* | ||
1860 | * Check status | ||
1861 | */ | ||
1862 | |||
1863 | for (timeout = AR5K_TUNE_REGISTER_TIMEOUT; timeout > 0; timeout--) { | ||
1864 | status = ath5k_hw_reg_read(ah, AR5K_EEPROM_STATUS); | ||
1865 | if (status & AR5K_EEPROM_STAT_WRDONE) { | ||
1866 | if (status & AR5K_EEPROM_STAT_WRERR) | ||
1867 | return EIO; | ||
1868 | return 0; | ||
1869 | } | ||
1870 | udelay(15); | ||
1871 | } | ||
1872 | |||
1873 | ATH5K_ERR(ah->ah_sc, "EEPROM Write is disabled!"); | ||
1874 | return -EIO; | ||
1875 | } | ||
1876 | #endif | ||
1877 | |||
1878 | /* | ||
1879 | * Translate binary channel representation in EEPROM to frequency | ||
1880 | */ | ||
1881 | static u16 ath5k_eeprom_bin2freq(struct ath5k_hw *ah, u16 bin, unsigned int mode) | ||
1882 | { | ||
1883 | u16 val; | ||
1884 | |||
1885 | if (bin == AR5K_EEPROM_CHANNEL_DIS) | ||
1886 | return bin; | ||
1887 | |||
1888 | if (mode == AR5K_EEPROM_MODE_11A) { | ||
1889 | if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2) | ||
1890 | val = (5 * bin) + 4800; | ||
1891 | else | ||
1892 | val = bin > 62 ? (10 * 62) + (5 * (bin - 62)) + 5100 : | ||
1893 | (bin * 10) + 5100; | ||
1894 | } else { | ||
1895 | if (ah->ah_ee_version > AR5K_EEPROM_VERSION_3_2) | ||
1896 | val = bin + 2300; | ||
1897 | else | ||
1898 | val = bin + 2400; | ||
1899 | } | ||
1900 | |||
1901 | return val; | ||
1902 | } | ||
1903 | |||
1904 | /* | ||
1905 | * Read antenna infos from eeprom | ||
1906 | */ | ||
1907 | static int ath5k_eeprom_read_ants(struct ath5k_hw *ah, u32 *offset, | ||
1908 | unsigned int mode) | ||
1909 | { | ||
1910 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
1911 | u32 o = *offset; | ||
1912 | u16 val; | ||
1913 | int ret, i = 0; | ||
1914 | |||
1915 | AR5K_EEPROM_READ(o++, val); | ||
1916 | ee->ee_switch_settling[mode] = (val >> 8) & 0x7f; | ||
1917 | ee->ee_ant_tx_rx[mode] = (val >> 2) & 0x3f; | ||
1918 | ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; | ||
1919 | |||
1920 | AR5K_EEPROM_READ(o++, val); | ||
1921 | ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; | ||
1922 | ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; | ||
1923 | ee->ee_ant_control[mode][i++] = val & 0x3f; | ||
1924 | |||
1925 | AR5K_EEPROM_READ(o++, val); | ||
1926 | ee->ee_ant_control[mode][i++] = (val >> 10) & 0x3f; | ||
1927 | ee->ee_ant_control[mode][i++] = (val >> 4) & 0x3f; | ||
1928 | ee->ee_ant_control[mode][i] = (val << 2) & 0x3f; | ||
1929 | |||
1930 | AR5K_EEPROM_READ(o++, val); | ||
1931 | ee->ee_ant_control[mode][i++] |= (val >> 14) & 0x3; | ||
1932 | ee->ee_ant_control[mode][i++] = (val >> 8) & 0x3f; | ||
1933 | ee->ee_ant_control[mode][i++] = (val >> 2) & 0x3f; | ||
1934 | ee->ee_ant_control[mode][i] = (val << 4) & 0x3f; | ||
1935 | |||
1936 | AR5K_EEPROM_READ(o++, val); | ||
1937 | ee->ee_ant_control[mode][i++] |= (val >> 12) & 0xf; | ||
1938 | ee->ee_ant_control[mode][i++] = (val >> 6) & 0x3f; | ||
1939 | ee->ee_ant_control[mode][i++] = val & 0x3f; | ||
1940 | |||
1941 | /* Get antenna modes */ | ||
1942 | ah->ah_antenna[mode][0] = | ||
1943 | (ee->ee_ant_control[mode][0] << 4) | 0x1; | ||
1944 | ah->ah_antenna[mode][AR5K_ANT_FIXED_A] = | ||
1945 | ee->ee_ant_control[mode][1] | | ||
1946 | (ee->ee_ant_control[mode][2] << 6) | | ||
1947 | (ee->ee_ant_control[mode][3] << 12) | | ||
1948 | (ee->ee_ant_control[mode][4] << 18) | | ||
1949 | (ee->ee_ant_control[mode][5] << 24); | ||
1950 | ah->ah_antenna[mode][AR5K_ANT_FIXED_B] = | ||
1951 | ee->ee_ant_control[mode][6] | | ||
1952 | (ee->ee_ant_control[mode][7] << 6) | | ||
1953 | (ee->ee_ant_control[mode][8] << 12) | | ||
1954 | (ee->ee_ant_control[mode][9] << 18) | | ||
1955 | (ee->ee_ant_control[mode][10] << 24); | ||
1956 | |||
1957 | /* return new offset */ | ||
1958 | *offset = o; | ||
1959 | |||
1960 | return 0; | ||
1961 | } | ||
1962 | |||
1963 | /* | ||
1964 | * Read supported modes from eeprom | ||
1965 | */ | ||
1966 | static int ath5k_eeprom_read_modes(struct ath5k_hw *ah, u32 *offset, | ||
1967 | unsigned int mode) | ||
1968 | { | ||
1969 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
1970 | u32 o = *offset; | ||
1971 | u16 val; | ||
1972 | int ret; | ||
1973 | |||
1974 | AR5K_EEPROM_READ(o++, val); | ||
1975 | ee->ee_tx_end2xlna_enable[mode] = (val >> 8) & 0xff; | ||
1976 | ee->ee_thr_62[mode] = val & 0xff; | ||
1977 | |||
1978 | if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) | ||
1979 | ee->ee_thr_62[mode] = mode == AR5K_EEPROM_MODE_11A ? 15 : 28; | ||
1980 | |||
1981 | AR5K_EEPROM_READ(o++, val); | ||
1982 | ee->ee_tx_end2xpa_disable[mode] = (val >> 8) & 0xff; | ||
1983 | ee->ee_tx_frm2xpa_enable[mode] = val & 0xff; | ||
1984 | |||
1985 | AR5K_EEPROM_READ(o++, val); | ||
1986 | ee->ee_pga_desired_size[mode] = (val >> 8) & 0xff; | ||
1987 | |||
1988 | if ((val & 0xff) & 0x80) | ||
1989 | ee->ee_noise_floor_thr[mode] = -((((val & 0xff) ^ 0xff)) + 1); | ||
1990 | else | ||
1991 | ee->ee_noise_floor_thr[mode] = val & 0xff; | ||
1992 | |||
1993 | if (ah->ah_ee_version <= AR5K_EEPROM_VERSION_3_2) | ||
1994 | ee->ee_noise_floor_thr[mode] = | ||
1995 | mode == AR5K_EEPROM_MODE_11A ? -54 : -1; | ||
1996 | |||
1997 | AR5K_EEPROM_READ(o++, val); | ||
1998 | ee->ee_xlna_gain[mode] = (val >> 5) & 0xff; | ||
1999 | ee->ee_x_gain[mode] = (val >> 1) & 0xf; | ||
2000 | ee->ee_xpd[mode] = val & 0x1; | ||
2001 | |||
2002 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) | ||
2003 | ee->ee_fixed_bias[mode] = (val >> 13) & 0x1; | ||
2004 | |||
2005 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_3_3) { | ||
2006 | AR5K_EEPROM_READ(o++, val); | ||
2007 | ee->ee_false_detect[mode] = (val >> 6) & 0x7f; | ||
2008 | |||
2009 | if (mode == AR5K_EEPROM_MODE_11A) | ||
2010 | ee->ee_xr_power[mode] = val & 0x3f; | ||
2011 | else { | ||
2012 | ee->ee_ob[mode][0] = val & 0x7; | ||
2013 | ee->ee_db[mode][0] = (val >> 3) & 0x7; | ||
2014 | } | ||
2015 | } | ||
2016 | |||
2017 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_4) { | ||
2018 | ee->ee_i_gain[mode] = AR5K_EEPROM_I_GAIN; | ||
2019 | ee->ee_cck_ofdm_power_delta = AR5K_EEPROM_CCK_OFDM_DELTA; | ||
2020 | } else { | ||
2021 | ee->ee_i_gain[mode] = (val >> 13) & 0x7; | ||
2022 | |||
2023 | AR5K_EEPROM_READ(o++, val); | ||
2024 | ee->ee_i_gain[mode] |= (val << 3) & 0x38; | ||
2025 | |||
2026 | if (mode == AR5K_EEPROM_MODE_11G) | ||
2027 | ee->ee_cck_ofdm_power_delta = (val >> 3) & 0xff; | ||
2028 | } | ||
2029 | |||
2030 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0 && | ||
2031 | mode == AR5K_EEPROM_MODE_11A) { | ||
2032 | ee->ee_i_cal[mode] = (val >> 8) & 0x3f; | ||
2033 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; | ||
2034 | } | ||
2035 | |||
2036 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_6 && | ||
2037 | mode == AR5K_EEPROM_MODE_11G) | ||
2038 | ee->ee_scaled_cck_delta = (val >> 11) & 0x1f; | ||
2039 | |||
2040 | /* return new offset */ | ||
2041 | *offset = o; | ||
2042 | |||
2043 | return 0; | ||
2044 | } | ||
2045 | |||
2046 | /* | ||
2047 | * Initialize eeprom & capabilities structs | ||
2048 | */ | ||
2049 | static int ath5k_eeprom_init(struct ath5k_hw *ah) | ||
2050 | { | ||
2051 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
2052 | unsigned int mode, i; | ||
2053 | int ret; | ||
2054 | u32 offset; | ||
2055 | u16 val; | ||
2056 | |||
2057 | /* Initial TX thermal adjustment values */ | ||
2058 | ee->ee_tx_clip = 4; | ||
2059 | ee->ee_pwd_84 = ee->ee_pwd_90 = 1; | ||
2060 | ee->ee_gain_select = 1; | ||
2061 | |||
2062 | /* | ||
2063 | * Read values from EEPROM and store them in the capability structure | ||
2064 | */ | ||
2065 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MAGIC, ee_magic); | ||
2066 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_PROTECT, ee_protect); | ||
2067 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_REG_DOMAIN, ee_regdomain); | ||
2068 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_VERSION, ee_version); | ||
2069 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_HDR, ee_header); | ||
2070 | |||
2071 | /* Return if we have an old EEPROM */ | ||
2072 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_0) | ||
2073 | return 0; | ||
2074 | |||
2075 | #ifdef notyet | ||
2076 | /* | ||
2077 | * Validate the checksum of the EEPROM date. There are some | ||
2078 | * devices with invalid EEPROMs. | ||
2079 | */ | ||
2080 | for (cksum = 0, offset = 0; offset < AR5K_EEPROM_INFO_MAX; offset++) { | ||
2081 | AR5K_EEPROM_READ(AR5K_EEPROM_INFO(offset), val); | ||
2082 | cksum ^= val; | ||
2083 | } | ||
2084 | if (cksum != AR5K_EEPROM_INFO_CKSUM) { | ||
2085 | ATH5K_ERR(ah->ah_sc, "Invalid EEPROM checksum 0x%04x\n", cksum); | ||
2086 | return -EIO; | ||
2087 | } | ||
2088 | #endif | ||
2089 | |||
2090 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_ANT_GAIN(ah->ah_ee_version), | ||
2091 | ee_ant_gain); | ||
2092 | |||
2093 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | ||
2094 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC0, ee_misc0); | ||
2095 | AR5K_EEPROM_READ_HDR(AR5K_EEPROM_MISC1, ee_misc1); | ||
2096 | } | ||
2097 | |||
2098 | if (ah->ah_ee_version < AR5K_EEPROM_VERSION_3_3) { | ||
2099 | AR5K_EEPROM_READ(AR5K_EEPROM_OBDB0_2GHZ, val); | ||
2100 | ee->ee_ob[AR5K_EEPROM_MODE_11B][0] = val & 0x7; | ||
2101 | ee->ee_db[AR5K_EEPROM_MODE_11B][0] = (val >> 3) & 0x7; | ||
2102 | |||
2103 | AR5K_EEPROM_READ(AR5K_EEPROM_OBDB1_2GHZ, val); | ||
2104 | ee->ee_ob[AR5K_EEPROM_MODE_11G][0] = val & 0x7; | ||
2105 | ee->ee_db[AR5K_EEPROM_MODE_11G][0] = (val >> 3) & 0x7; | ||
2106 | } | ||
2107 | |||
2108 | /* | ||
2109 | * Get conformance test limit values | ||
2110 | */ | ||
2111 | offset = AR5K_EEPROM_CTL(ah->ah_ee_version); | ||
2112 | ee->ee_ctls = AR5K_EEPROM_N_CTLS(ah->ah_ee_version); | ||
2113 | |||
2114 | for (i = 0; i < ee->ee_ctls; i++) { | ||
2115 | AR5K_EEPROM_READ(offset++, val); | ||
2116 | ee->ee_ctl[i] = (val >> 8) & 0xff; | ||
2117 | ee->ee_ctl[i + 1] = val & 0xff; | ||
2118 | } | ||
2119 | |||
2120 | /* | ||
2121 | * Get values for 802.11a (5GHz) | ||
2122 | */ | ||
2123 | mode = AR5K_EEPROM_MODE_11A; | ||
2124 | |||
2125 | ee->ee_turbo_max_power[mode] = | ||
2126 | AR5K_EEPROM_HDR_T_5GHZ_DBM(ee->ee_header); | ||
2127 | |||
2128 | offset = AR5K_EEPROM_MODES_11A(ah->ah_ee_version); | ||
2129 | |||
2130 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | ||
2131 | if (ret) | ||
2132 | return ret; | ||
2133 | |||
2134 | AR5K_EEPROM_READ(offset++, val); | ||
2135 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | ||
2136 | ee->ee_ob[mode][3] = (val >> 5) & 0x7; | ||
2137 | ee->ee_db[mode][3] = (val >> 2) & 0x7; | ||
2138 | ee->ee_ob[mode][2] = (val << 1) & 0x7; | ||
2139 | |||
2140 | AR5K_EEPROM_READ(offset++, val); | ||
2141 | ee->ee_ob[mode][2] |= (val >> 15) & 0x1; | ||
2142 | ee->ee_db[mode][2] = (val >> 12) & 0x7; | ||
2143 | ee->ee_ob[mode][1] = (val >> 9) & 0x7; | ||
2144 | ee->ee_db[mode][1] = (val >> 6) & 0x7; | ||
2145 | ee->ee_ob[mode][0] = (val >> 3) & 0x7; | ||
2146 | ee->ee_db[mode][0] = val & 0x7; | ||
2147 | |||
2148 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | ||
2149 | if (ret) | ||
2150 | return ret; | ||
2151 | |||
2152 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) { | ||
2153 | AR5K_EEPROM_READ(offset++, val); | ||
2154 | ee->ee_margin_tx_rx[mode] = val & 0x3f; | ||
2155 | } | ||
2156 | |||
2157 | /* | ||
2158 | * Get values for 802.11b (2.4GHz) | ||
2159 | */ | ||
2160 | mode = AR5K_EEPROM_MODE_11B; | ||
2161 | offset = AR5K_EEPROM_MODES_11B(ah->ah_ee_version); | ||
2162 | |||
2163 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | ||
2164 | if (ret) | ||
2165 | return ret; | ||
2166 | |||
2167 | AR5K_EEPROM_READ(offset++, val); | ||
2168 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | ||
2169 | ee->ee_ob[mode][1] = (val >> 4) & 0x7; | ||
2170 | ee->ee_db[mode][1] = val & 0x7; | ||
2171 | |||
2172 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | ||
2173 | if (ret) | ||
2174 | return ret; | ||
2175 | |||
2176 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | ||
2177 | AR5K_EEPROM_READ(offset++, val); | ||
2178 | ee->ee_cal_pier[mode][0] = | ||
2179 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | ||
2180 | ee->ee_cal_pier[mode][1] = | ||
2181 | ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode); | ||
2182 | |||
2183 | AR5K_EEPROM_READ(offset++, val); | ||
2184 | ee->ee_cal_pier[mode][2] = | ||
2185 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | ||
2186 | } | ||
2187 | |||
2188 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
2189 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | ||
2190 | |||
2191 | /* | ||
2192 | * Get values for 802.11g (2.4GHz) | ||
2193 | */ | ||
2194 | mode = AR5K_EEPROM_MODE_11G; | ||
2195 | offset = AR5K_EEPROM_MODES_11G(ah->ah_ee_version); | ||
2196 | |||
2197 | ret = ath5k_eeprom_read_ants(ah, &offset, mode); | ||
2198 | if (ret) | ||
2199 | return ret; | ||
2200 | |||
2201 | AR5K_EEPROM_READ(offset++, val); | ||
2202 | ee->ee_adc_desired_size[mode] = (s8)((val >> 8) & 0xff); | ||
2203 | ee->ee_ob[mode][1] = (val >> 4) & 0x7; | ||
2204 | ee->ee_db[mode][1] = val & 0x7; | ||
2205 | |||
2206 | ret = ath5k_eeprom_read_modes(ah, &offset, mode); | ||
2207 | if (ret) | ||
2208 | return ret; | ||
2209 | |||
2210 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_0) { | ||
2211 | AR5K_EEPROM_READ(offset++, val); | ||
2212 | ee->ee_cal_pier[mode][0] = | ||
2213 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | ||
2214 | ee->ee_cal_pier[mode][1] = | ||
2215 | ath5k_eeprom_bin2freq(ah, (val >> 8) & 0xff, mode); | ||
2216 | |||
2217 | AR5K_EEPROM_READ(offset++, val); | ||
2218 | ee->ee_turbo_max_power[mode] = val & 0x7f; | ||
2219 | ee->ee_xr_power[mode] = (val >> 7) & 0x3f; | ||
2220 | |||
2221 | AR5K_EEPROM_READ(offset++, val); | ||
2222 | ee->ee_cal_pier[mode][2] = | ||
2223 | ath5k_eeprom_bin2freq(ah, val & 0xff, mode); | ||
2224 | |||
2225 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
2226 | ee->ee_margin_tx_rx[mode] = (val >> 8) & 0x3f; | ||
2227 | |||
2228 | AR5K_EEPROM_READ(offset++, val); | ||
2229 | ee->ee_i_cal[mode] = (val >> 8) & 0x3f; | ||
2230 | ee->ee_q_cal[mode] = (val >> 3) & 0x1f; | ||
2231 | |||
2232 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_2) { | ||
2233 | AR5K_EEPROM_READ(offset++, val); | ||
2234 | ee->ee_cck_ofdm_gain_delta = val & 0xff; | ||
2235 | } | ||
2236 | } | ||
2237 | |||
2238 | /* | ||
2239 | * Read 5GHz EEPROM channels | ||
2240 | */ | ||
2241 | |||
2242 | return 0; | ||
2243 | } | ||
2244 | |||
2245 | /* | ||
2246 | * Read the MAC address from eeprom | ||
2247 | */ | ||
2248 | static int ath5k_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac) | ||
2249 | { | ||
2250 | u8 mac_d[ETH_ALEN]; | ||
2251 | u32 total, offset; | ||
2252 | u16 data; | ||
2253 | int octet, ret; | ||
2254 | |||
2255 | memset(mac, 0, ETH_ALEN); | ||
2256 | memset(mac_d, 0, ETH_ALEN); | ||
2257 | |||
2258 | ret = ath5k_hw_eeprom_read(ah, 0x20, &data); | ||
2259 | if (ret) | ||
2260 | return ret; | ||
2261 | |||
2262 | for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) { | ||
2263 | ret = ath5k_hw_eeprom_read(ah, offset, &data); | ||
2264 | if (ret) | ||
2265 | return ret; | ||
2266 | |||
2267 | total += data; | ||
2268 | mac_d[octet + 1] = data & 0xff; | ||
2269 | mac_d[octet] = data >> 8; | ||
2270 | octet += 2; | ||
2271 | } | ||
2272 | |||
2273 | memcpy(mac, mac_d, ETH_ALEN); | ||
2274 | |||
2275 | if (!total || total == 3 * 0xffff) | ||
2276 | return -EINVAL; | ||
2277 | |||
2278 | return 0; | ||
2279 | } | ||
2280 | |||
2281 | /* | ||
2282 | * Fill the capabilities struct | ||
2283 | */ | ||
2284 | static int ath5k_hw_get_capabilities(struct ath5k_hw *ah) | ||
2285 | { | ||
2286 | u16 ee_header; | ||
2287 | |||
2288 | ATH5K_TRACE(ah->ah_sc); | ||
2289 | /* Capabilities stored in the EEPROM */ | ||
2290 | ee_header = ah->ah_capabilities.cap_eeprom.ee_header; | ||
2291 | |||
2292 | if (ah->ah_version == AR5K_AR5210) { | ||
2293 | /* | ||
2294 | * Set radio capabilities | ||
2295 | * (The AR5110 only supports the middle 5GHz band) | ||
2296 | */ | ||
2297 | ah->ah_capabilities.cap_range.range_5ghz_min = 5120; | ||
2298 | ah->ah_capabilities.cap_range.range_5ghz_max = 5430; | ||
2299 | ah->ah_capabilities.cap_range.range_2ghz_min = 0; | ||
2300 | ah->ah_capabilities.cap_range.range_2ghz_max = 0; | ||
2301 | |||
2302 | /* Set supported modes */ | ||
2303 | __set_bit(AR5K_MODE_11A, ah->ah_capabilities.cap_mode); | ||
2304 | __set_bit(AR5K_MODE_11A_TURBO, ah->ah_capabilities.cap_mode); | ||
2305 | } else { | ||
2306 | /* | ||
2307 | * XXX The tranceiver supports frequencies from 4920 to 6100GHz | ||
2308 | * XXX and from 2312 to 2732GHz. There are problems with the | ||
2309 | * XXX current ieee80211 implementation because the IEEE | ||
2310 | * XXX channel mapping does not support negative channel | ||
2311 | * XXX numbers (2312MHz is channel -19). Of course, this | ||
2312 | * XXX doesn't matter because these channels are out of range | ||
2313 | * XXX but some regulation domains like MKK (Japan) will | ||
2314 | * XXX support frequencies somewhere around 4.8GHz. | ||
2315 | */ | ||
2316 | |||
2317 | /* | ||
2318 | * Set radio capabilities | ||
2319 | */ | ||
2320 | |||
2321 | if (AR5K_EEPROM_HDR_11A(ee_header)) { | ||
2322 | ah->ah_capabilities.cap_range.range_5ghz_min = 5005; /* 4920 */ | ||
2323 | ah->ah_capabilities.cap_range.range_5ghz_max = 6100; | ||
2324 | |||
2325 | /* Set supported modes */ | ||
2326 | __set_bit(AR5K_MODE_11A, | ||
2327 | ah->ah_capabilities.cap_mode); | ||
2328 | __set_bit(AR5K_MODE_11A_TURBO, | ||
2329 | ah->ah_capabilities.cap_mode); | ||
2330 | if (ah->ah_version == AR5K_AR5212) | ||
2331 | __set_bit(AR5K_MODE_11G_TURBO, | ||
2332 | ah->ah_capabilities.cap_mode); | ||
2333 | } | ||
2334 | |||
2335 | /* Enable 802.11b if a 2GHz capable radio (2111/5112) is | ||
2336 | * connected */ | ||
2337 | if (AR5K_EEPROM_HDR_11B(ee_header) || | ||
2338 | AR5K_EEPROM_HDR_11G(ee_header)) { | ||
2339 | ah->ah_capabilities.cap_range.range_2ghz_min = 2412; /* 2312 */ | ||
2340 | ah->ah_capabilities.cap_range.range_2ghz_max = 2732; | ||
2341 | |||
2342 | if (AR5K_EEPROM_HDR_11B(ee_header)) | ||
2343 | __set_bit(AR5K_MODE_11B, | ||
2344 | ah->ah_capabilities.cap_mode); | ||
2345 | |||
2346 | if (AR5K_EEPROM_HDR_11G(ee_header)) | ||
2347 | __set_bit(AR5K_MODE_11G, | ||
2348 | ah->ah_capabilities.cap_mode); | ||
2349 | } | ||
2350 | } | ||
2351 | |||
2352 | /* GPIO */ | ||
2353 | ah->ah_gpio_npins = AR5K_NUM_GPIO; | ||
2354 | |||
2355 | /* Set number of supported TX queues */ | ||
2356 | if (ah->ah_version == AR5K_AR5210) | ||
2357 | ah->ah_capabilities.cap_queues.q_tx_num = | ||
2358 | AR5K_NUM_TX_QUEUES_NOQCU; | ||
2359 | else | ||
2360 | ah->ah_capabilities.cap_queues.q_tx_num = AR5K_NUM_TX_QUEUES; | ||
2361 | |||
2362 | return 0; | ||
2363 | } | ||
2364 | |||
2365 | /*********************************\ | ||
2366 | Protocol Control Unit Functions | ||
2367 | \*********************************/ | ||
2368 | |||
2369 | /* | ||
2370 | * Set Operation mode | ||
2371 | */ | ||
2372 | int ath5k_hw_set_opmode(struct ath5k_hw *ah) | ||
2373 | { | ||
2374 | u32 pcu_reg, beacon_reg, low_id, high_id; | ||
2375 | |||
2376 | pcu_reg = 0; | ||
2377 | beacon_reg = 0; | ||
2378 | |||
2379 | ATH5K_TRACE(ah->ah_sc); | ||
2380 | |||
2381 | switch (ah->ah_op_mode) { | ||
2382 | case IEEE80211_IF_TYPE_IBSS: | ||
2383 | pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA | | ||
2384 | (ah->ah_version == AR5K_AR5210 ? | ||
2385 | AR5K_STA_ID1_NO_PSPOLL : 0); | ||
2386 | beacon_reg |= AR5K_BCR_ADHOC; | ||
2387 | break; | ||
2388 | |||
2389 | case IEEE80211_IF_TYPE_AP: | ||
2390 | pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA | | ||
2391 | (ah->ah_version == AR5K_AR5210 ? | ||
2392 | AR5K_STA_ID1_NO_PSPOLL : 0); | ||
2393 | beacon_reg |= AR5K_BCR_AP; | ||
2394 | break; | ||
2395 | |||
2396 | case IEEE80211_IF_TYPE_STA: | ||
2397 | pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
2398 | (ah->ah_version == AR5K_AR5210 ? | ||
2399 | AR5K_STA_ID1_PWR_SV : 0); | ||
2400 | case IEEE80211_IF_TYPE_MNTR: | ||
2401 | pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
2402 | (ah->ah_version == AR5K_AR5210 ? | ||
2403 | AR5K_STA_ID1_NO_PSPOLL : 0); | ||
2404 | break; | ||
2405 | |||
2406 | default: | ||
2407 | return -EINVAL; | ||
2408 | } | ||
2409 | |||
2410 | /* | ||
2411 | * Set PCU registers | ||
2412 | */ | ||
2413 | low_id = AR5K_LOW_ID(ah->ah_sta_id); | ||
2414 | high_id = AR5K_HIGH_ID(ah->ah_sta_id); | ||
2415 | ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); | ||
2416 | ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); | ||
2417 | |||
2418 | /* | ||
2419 | * Set Beacon Control Register on 5210 | ||
2420 | */ | ||
2421 | if (ah->ah_version == AR5K_AR5210) | ||
2422 | ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR); | ||
2423 | |||
2424 | return 0; | ||
2425 | } | ||
2426 | |||
2427 | /* | ||
2428 | * BSSID Functions | ||
2429 | */ | ||
2430 | |||
2431 | /* | ||
2432 | * Get station id | ||
2433 | */ | ||
2434 | void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac) | ||
2435 | { | ||
2436 | ATH5K_TRACE(ah->ah_sc); | ||
2437 | memcpy(mac, ah->ah_sta_id, ETH_ALEN); | ||
2438 | } | ||
2439 | |||
2440 | /* | ||
2441 | * Set station id | ||
2442 | */ | ||
2443 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) | ||
2444 | { | ||
2445 | u32 low_id, high_id; | ||
2446 | |||
2447 | ATH5K_TRACE(ah->ah_sc); | ||
2448 | /* Set new station ID */ | ||
2449 | memcpy(ah->ah_sta_id, mac, ETH_ALEN); | ||
2450 | |||
2451 | low_id = AR5K_LOW_ID(mac); | ||
2452 | high_id = AR5K_HIGH_ID(mac); | ||
2453 | |||
2454 | ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); | ||
2455 | ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1); | ||
2456 | |||
2457 | return 0; | ||
2458 | } | ||
2459 | |||
2460 | /* | ||
2461 | * Set BSSID | ||
2462 | */ | ||
2463 | void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id) | ||
2464 | { | ||
2465 | u32 low_id, high_id; | ||
2466 | u16 tim_offset = 0; | ||
2467 | |||
2468 | /* | ||
2469 | * Set simple BSSID mask on 5212 | ||
2470 | */ | ||
2471 | if (ah->ah_version == AR5K_AR5212) { | ||
2472 | ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0); | ||
2473 | ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1); | ||
2474 | } | ||
2475 | |||
2476 | /* | ||
2477 | * Set BSSID which triggers the "SME Join" operation | ||
2478 | */ | ||
2479 | low_id = AR5K_LOW_ID(bssid); | ||
2480 | high_id = AR5K_HIGH_ID(bssid); | ||
2481 | ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0); | ||
2482 | ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) << | ||
2483 | AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1); | ||
2484 | |||
2485 | if (assoc_id == 0) { | ||
2486 | ath5k_hw_disable_pspoll(ah); | ||
2487 | return; | ||
2488 | } | ||
2489 | |||
2490 | AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM, | ||
2491 | tim_offset ? tim_offset + 4 : 0); | ||
2492 | |||
2493 | ath5k_hw_enable_pspoll(ah, NULL, 0); | ||
2494 | } | ||
2495 | /** | ||
2496 | * ath5k_hw_set_bssid_mask - set common bits we should listen to | ||
2497 | * | ||
2498 | * The bssid_mask is a utility used by AR5212 hardware to inform the hardware | ||
2499 | * which bits of the interface's MAC address should be looked at when trying | ||
2500 | * to decide which packets to ACK. In station mode every bit matters. In AP | ||
2501 | * mode with a single BSS every bit matters as well. In AP mode with | ||
2502 | * multiple BSSes not every bit matters. | ||
2503 | * | ||
2504 | * @ah: the &struct ath5k_hw | ||
2505 | * @mask: the bssid_mask, a u8 array of size ETH_ALEN | ||
2506 | * | ||
2507 | * Note that this is a simple filter and *does* not filter out all | ||
2508 | * relevant frames. Some non-relevant frames will get through, probability | ||
2509 | * jocks are welcomed to compute. | ||
2510 | * | ||
2511 | * When handling multiple BSSes (or VAPs) you can get the BSSID mask by | ||
2512 | * computing the set of: | ||
2513 | * | ||
2514 | * ~ ( MAC XOR BSSID ) | ||
2515 | * | ||
2516 | * When you do this you are essentially computing the common bits. Later it | ||
2517 | * is assumed the harware will "and" (&) the BSSID mask with the MAC address | ||
2518 | * to obtain the relevant bits which should match on the destination frame. | ||
2519 | * | ||
2520 | * Simple example: on your card you have have two BSSes you have created with | ||
2521 | * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address. | ||
2522 | * There is another BSSID-03 but you are not part of it. For simplicity's sake, | ||
2523 | * assuming only 4 bits for a mac address and for BSSIDs you can then have: | ||
2524 | * | ||
2525 | * \ | ||
2526 | * MAC: 0001 | | ||
2527 | * BSSID-01: 0100 | --> Belongs to us | ||
2528 | * BSSID-02: 1001 | | ||
2529 | * / | ||
2530 | * ------------------- | ||
2531 | * BSSID-03: 0110 | --> External | ||
2532 | * ------------------- | ||
2533 | * | ||
2534 | * Our bssid_mask would then be: | ||
2535 | * | ||
2536 | * On loop iteration for BSSID-01: | ||
2537 | * ~(0001 ^ 0100) -> ~(0101) | ||
2538 | * -> 1010 | ||
2539 | * bssid_mask = 1010 | ||
2540 | * | ||
2541 | * On loop iteration for BSSID-02: | ||
2542 | * bssid_mask &= ~(0001 ^ 1001) | ||
2543 | * bssid_mask = (1010) & ~(0001 ^ 1001) | ||
2544 | * bssid_mask = (1010) & ~(1001) | ||
2545 | * bssid_mask = (1010) & (0110) | ||
2546 | * bssid_mask = 0010 | ||
2547 | * | ||
2548 | * A bssid_mask of 0010 means "only pay attention to the second least | ||
2549 | * significant bit". This is because its the only bit common | ||
2550 | * amongst the MAC and all BSSIDs we support. To findout what the real | ||
2551 | * common bit is we can simply "&" the bssid_mask now with any BSSID we have | ||
2552 | * or our MAC address (we assume the hardware uses the MAC address). | ||
2553 | * | ||
2554 | * Now, suppose there's an incoming frame for BSSID-03: | ||
2555 | * | ||
2556 | * IFRAME-01: 0110 | ||
2557 | * | ||
2558 | * An easy eye-inspeciton of this already should tell you that this frame | ||
2559 | * will not pass our check. This is beacuse the bssid_mask tells the | ||
2560 | * hardware to only look at the second least significant bit and the | ||
2561 | * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB | ||
2562 | * as 1, which does not match 0. | ||
2563 | * | ||
2564 | * So with IFRAME-01 we *assume* the hardware will do: | ||
2565 | * | ||
2566 | * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; | ||
2567 | * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0; | ||
2568 | * --> allow = (0010) == 0000 ? 1 : 0; | ||
2569 | * --> allow = 0 | ||
2570 | * | ||
2571 | * Lets now test a frame that should work: | ||
2572 | * | ||
2573 | * IFRAME-02: 0001 (we should allow) | ||
2574 | * | ||
2575 | * allow = (0001 & 1010) == 1010 | ||
2576 | * | ||
2577 | * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; | ||
2578 | * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0; | ||
2579 | * --> allow = (0010) == (0010) | ||
2580 | * --> allow = 1 | ||
2581 | * | ||
2582 | * Other examples: | ||
2583 | * | ||
2584 | * IFRAME-03: 0100 --> allowed | ||
2585 | * IFRAME-04: 1001 --> allowed | ||
2586 | * IFRAME-05: 1101 --> allowed but its not for us!!! | ||
2587 | * | ||
2588 | */ | ||
2589 | int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) | ||
2590 | { | ||
2591 | u32 low_id, high_id; | ||
2592 | ATH5K_TRACE(ah->ah_sc); | ||
2593 | |||
2594 | if (ah->ah_version == AR5K_AR5212) { | ||
2595 | low_id = AR5K_LOW_ID(mask); | ||
2596 | high_id = AR5K_HIGH_ID(mask); | ||
2597 | |||
2598 | ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0); | ||
2599 | ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1); | ||
2600 | |||
2601 | return 0; | ||
2602 | } | ||
2603 | |||
2604 | return -EIO; | ||
2605 | } | ||
2606 | |||
2607 | /* | ||
2608 | * Receive start/stop functions | ||
2609 | */ | ||
2610 | |||
2611 | /* | ||
2612 | * Start receive on PCU | ||
2613 | */ | ||
2614 | void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) | ||
2615 | { | ||
2616 | ATH5K_TRACE(ah->ah_sc); | ||
2617 | AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); | ||
2618 | |||
2619 | /* TODO: ANI Support */ | ||
2620 | } | ||
2621 | |||
2622 | /* | ||
2623 | * Stop receive on PCU | ||
2624 | */ | ||
2625 | void ath5k_hw_stop_pcu_recv(struct ath5k_hw *ah) | ||
2626 | { | ||
2627 | ATH5K_TRACE(ah->ah_sc); | ||
2628 | AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); | ||
2629 | |||
2630 | /* TODO: ANI Support */ | ||
2631 | } | ||
2632 | |||
2633 | /* | ||
2634 | * RX Filter functions | ||
2635 | */ | ||
2636 | |||
2637 | /* | ||
2638 | * Set multicast filter | ||
2639 | */ | ||
2640 | void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1) | ||
2641 | { | ||
2642 | ATH5K_TRACE(ah->ah_sc); | ||
2643 | /* Set the multicat filter */ | ||
2644 | ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0); | ||
2645 | ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); | ||
2646 | } | ||
2647 | |||
2648 | /* | ||
2649 | * Set multicast filter by index | ||
2650 | */ | ||
2651 | int ath5k_hw_set_mcast_filterindex(struct ath5k_hw *ah, u32 index) | ||
2652 | { | ||
2653 | |||
2654 | ATH5K_TRACE(ah->ah_sc); | ||
2655 | if (index >= 64) | ||
2656 | return -EINVAL; | ||
2657 | else if (index >= 32) | ||
2658 | AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1, | ||
2659 | (1 << (index - 32))); | ||
2660 | else | ||
2661 | AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index)); | ||
2662 | |||
2663 | return 0; | ||
2664 | } | ||
2665 | |||
2666 | /* | ||
2667 | * Clear Multicast filter by index | ||
2668 | */ | ||
2669 | int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index) | ||
2670 | { | ||
2671 | |||
2672 | ATH5K_TRACE(ah->ah_sc); | ||
2673 | if (index >= 64) | ||
2674 | return -EINVAL; | ||
2675 | else if (index >= 32) | ||
2676 | AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1, | ||
2677 | (1 << (index - 32))); | ||
2678 | else | ||
2679 | AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index)); | ||
2680 | |||
2681 | return 0; | ||
2682 | } | ||
2683 | |||
2684 | /* | ||
2685 | * Get current rx filter | ||
2686 | */ | ||
2687 | u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah) | ||
2688 | { | ||
2689 | u32 data, filter = 0; | ||
2690 | |||
2691 | ATH5K_TRACE(ah->ah_sc); | ||
2692 | filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER); | ||
2693 | |||
2694 | /*Radar detection for 5212*/ | ||
2695 | if (ah->ah_version == AR5K_AR5212) { | ||
2696 | data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL); | ||
2697 | |||
2698 | if (data & AR5K_PHY_ERR_FIL_RADAR) | ||
2699 | filter |= AR5K_RX_FILTER_RADARERR; | ||
2700 | if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK)) | ||
2701 | filter |= AR5K_RX_FILTER_PHYERR; | ||
2702 | } | ||
2703 | |||
2704 | return filter; | ||
2705 | } | ||
2706 | |||
2707 | /* | ||
2708 | * Set rx filter | ||
2709 | */ | ||
2710 | void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter) | ||
2711 | { | ||
2712 | u32 data = 0; | ||
2713 | |||
2714 | ATH5K_TRACE(ah->ah_sc); | ||
2715 | |||
2716 | /* Set PHY error filter register on 5212*/ | ||
2717 | if (ah->ah_version == AR5K_AR5212) { | ||
2718 | if (filter & AR5K_RX_FILTER_RADARERR) | ||
2719 | data |= AR5K_PHY_ERR_FIL_RADAR; | ||
2720 | if (filter & AR5K_RX_FILTER_PHYERR) | ||
2721 | data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK; | ||
2722 | } | ||
2723 | |||
2724 | /* | ||
2725 | * The AR5210 uses promiscous mode to detect radar activity | ||
2726 | */ | ||
2727 | if (ah->ah_version == AR5K_AR5210 && | ||
2728 | (filter & AR5K_RX_FILTER_RADARERR)) { | ||
2729 | filter &= ~AR5K_RX_FILTER_RADARERR; | ||
2730 | filter |= AR5K_RX_FILTER_PROM; | ||
2731 | } | ||
2732 | |||
2733 | /*Zero length DMA*/ | ||
2734 | if (data) | ||
2735 | AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); | ||
2736 | else | ||
2737 | AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); | ||
2738 | |||
2739 | /*Write RX Filter register*/ | ||
2740 | ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER); | ||
2741 | |||
2742 | /*Write PHY error filter register on 5212*/ | ||
2743 | if (ah->ah_version == AR5K_AR5212) | ||
2744 | ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL); | ||
2745 | |||
2746 | } | ||
2747 | |||
2748 | /* | ||
2749 | * Beacon related functions | ||
2750 | */ | ||
2751 | |||
2752 | /* | ||
2753 | * Get a 32bit TSF | ||
2754 | */ | ||
2755 | u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah) | ||
2756 | { | ||
2757 | ATH5K_TRACE(ah->ah_sc); | ||
2758 | return ath5k_hw_reg_read(ah, AR5K_TSF_L32); | ||
2759 | } | ||
2760 | |||
2761 | /* | ||
2762 | * Get the full 64bit TSF | ||
2763 | */ | ||
2764 | u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) | ||
2765 | { | ||
2766 | u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32); | ||
2767 | ATH5K_TRACE(ah->ah_sc); | ||
2768 | |||
2769 | return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32); | ||
2770 | } | ||
2771 | |||
2772 | /* | ||
2773 | * Force a TSF reset | ||
2774 | */ | ||
2775 | void ath5k_hw_reset_tsf(struct ath5k_hw *ah) | ||
2776 | { | ||
2777 | ATH5K_TRACE(ah->ah_sc); | ||
2778 | AR5K_REG_ENABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_RESET_TSF); | ||
2779 | } | ||
2780 | |||
2781 | /* | ||
2782 | * Initialize beacon timers | ||
2783 | */ | ||
2784 | void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | ||
2785 | { | ||
2786 | u32 timer1, timer2, timer3; | ||
2787 | |||
2788 | ATH5K_TRACE(ah->ah_sc); | ||
2789 | /* | ||
2790 | * Set the additional timers by mode | ||
2791 | */ | ||
2792 | switch (ah->ah_op_mode) { | ||
2793 | case IEEE80211_IF_TYPE_STA: | ||
2794 | if (ah->ah_version == AR5K_AR5210) { | ||
2795 | timer1 = 0xffffffff; | ||
2796 | timer2 = 0xffffffff; | ||
2797 | } else { | ||
2798 | timer1 = 0x0000ffff; | ||
2799 | timer2 = 0x0007ffff; | ||
2800 | } | ||
2801 | break; | ||
2802 | |||
2803 | default: | ||
2804 | timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3; | ||
2805 | timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3; | ||
2806 | } | ||
2807 | |||
2808 | timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1); | ||
2809 | |||
2810 | /* | ||
2811 | * Set the beacon register and enable all timers. | ||
2812 | * (next beacon, DMA beacon, software beacon, ATIM window time) | ||
2813 | */ | ||
2814 | ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); | ||
2815 | ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1); | ||
2816 | ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2); | ||
2817 | ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3); | ||
2818 | |||
2819 | ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD | | ||
2820 | AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE), | ||
2821 | AR5K_BEACON); | ||
2822 | } | ||
2823 | |||
2824 | #if 0 | ||
2825 | /* | ||
2826 | * Set beacon timers | ||
2827 | */ | ||
2828 | int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, | ||
2829 | const struct ath5k_beacon_state *state) | ||
2830 | { | ||
2831 | u32 cfp_period, next_cfp, dtim, interval, next_beacon; | ||
2832 | |||
2833 | /* | ||
2834 | * TODO: should be changed through *state | ||
2835 | * review struct ath5k_beacon_state struct | ||
2836 | * | ||
2837 | * XXX: These are used for cfp period bellow, are they | ||
2838 | * ok ? Is it O.K. for tsf here to be 0 or should we use | ||
2839 | * get_tsf ? | ||
2840 | */ | ||
2841 | u32 dtim_count = 0; /* XXX */ | ||
2842 | u32 cfp_count = 0; /* XXX */ | ||
2843 | u32 tsf = 0; /* XXX */ | ||
2844 | |||
2845 | ATH5K_TRACE(ah->ah_sc); | ||
2846 | /* Return on an invalid beacon state */ | ||
2847 | if (state->bs_interval < 1) | ||
2848 | return -EINVAL; | ||
2849 | |||
2850 | interval = state->bs_interval; | ||
2851 | dtim = state->bs_dtim_period; | ||
2852 | |||
2853 | /* | ||
2854 | * PCF support? | ||
2855 | */ | ||
2856 | if (state->bs_cfp_period > 0) { | ||
2857 | /* | ||
2858 | * Enable PCF mode and set the CFP | ||
2859 | * (Contention Free Period) and timer registers | ||
2860 | */ | ||
2861 | cfp_period = state->bs_cfp_period * state->bs_dtim_period * | ||
2862 | state->bs_interval; | ||
2863 | next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) * | ||
2864 | state->bs_interval; | ||
2865 | |||
2866 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, | ||
2867 | AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
2868 | AR5K_STA_ID1_PCF); | ||
2869 | ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD); | ||
2870 | ath5k_hw_reg_write(ah, state->bs_cfp_max_duration, | ||
2871 | AR5K_CFP_DUR); | ||
2872 | ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period : | ||
2873 | next_cfp)) << 3, AR5K_TIMER2); | ||
2874 | } else { | ||
2875 | /* Disable PCF mode */ | ||
2876 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
2877 | AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
2878 | AR5K_STA_ID1_PCF); | ||
2879 | } | ||
2880 | |||
2881 | /* | ||
2882 | * Enable the beacon timer register | ||
2883 | */ | ||
2884 | ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0); | ||
2885 | |||
2886 | /* | ||
2887 | * Start the beacon timers | ||
2888 | */ | ||
2889 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) &~ | ||
2890 | (AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) | | ||
2891 | AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0, | ||
2892 | AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval, | ||
2893 | AR5K_BEACON_PERIOD), AR5K_BEACON); | ||
2894 | |||
2895 | /* | ||
2896 | * Write new beacon miss threshold, if it appears to be valid | ||
2897 | * XXX: Figure out right values for min <= bs_bmiss_threshold <= max | ||
2898 | * and return if its not in range. We can test this by reading value and | ||
2899 | * setting value to a largest value and seeing which values register. | ||
2900 | */ | ||
2901 | |||
2902 | AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS, | ||
2903 | state->bs_bmiss_threshold); | ||
2904 | |||
2905 | /* | ||
2906 | * Set sleep control register | ||
2907 | * XXX: Didn't find this in 5210 code but since this register | ||
2908 | * exists also in ar5k's 5210 headers i leave it as common code. | ||
2909 | */ | ||
2910 | AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR, | ||
2911 | (state->bs_sleep_duration - 3) << 3); | ||
2912 | |||
2913 | /* | ||
2914 | * Set enhanced sleep registers on 5212 | ||
2915 | */ | ||
2916 | if (ah->ah_version == AR5K_AR5212) { | ||
2917 | if (state->bs_sleep_duration > state->bs_interval && | ||
2918 | roundup(state->bs_sleep_duration, interval) == | ||
2919 | state->bs_sleep_duration) | ||
2920 | interval = state->bs_sleep_duration; | ||
2921 | |||
2922 | if (state->bs_sleep_duration > dtim && (dtim == 0 || | ||
2923 | roundup(state->bs_sleep_duration, dtim) == | ||
2924 | state->bs_sleep_duration)) | ||
2925 | dtim = state->bs_sleep_duration; | ||
2926 | |||
2927 | if (interval > dtim) | ||
2928 | return -EINVAL; | ||
2929 | |||
2930 | next_beacon = interval == dtim ? state->bs_next_dtim : | ||
2931 | state->bs_next_beacon; | ||
2932 | |||
2933 | ath5k_hw_reg_write(ah, | ||
2934 | AR5K_REG_SM((state->bs_next_dtim - 3) << 3, | ||
2935 | AR5K_SLEEP0_NEXT_DTIM) | | ||
2936 | AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) | | ||
2937 | AR5K_SLEEP0_ENH_SLEEP_EN | | ||
2938 | AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0); | ||
2939 | |||
2940 | ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3, | ||
2941 | AR5K_SLEEP1_NEXT_TIM) | | ||
2942 | AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1); | ||
2943 | |||
2944 | ath5k_hw_reg_write(ah, | ||
2945 | AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) | | ||
2946 | AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2); | ||
2947 | } | ||
2948 | |||
2949 | return 0; | ||
2950 | } | ||
2951 | |||
2952 | /* | ||
2953 | * Reset beacon timers | ||
2954 | */ | ||
2955 | void ath5k_hw_reset_beacon(struct ath5k_hw *ah) | ||
2956 | { | ||
2957 | ATH5K_TRACE(ah->ah_sc); | ||
2958 | /* | ||
2959 | * Disable beacon timer | ||
2960 | */ | ||
2961 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); | ||
2962 | |||
2963 | /* | ||
2964 | * Disable some beacon register values | ||
2965 | */ | ||
2966 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
2967 | AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF); | ||
2968 | ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON); | ||
2969 | } | ||
2970 | |||
2971 | /* | ||
2972 | * Wait for beacon queue to finish | ||
2973 | */ | ||
2974 | int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr) | ||
2975 | { | ||
2976 | unsigned int i; | ||
2977 | int ret; | ||
2978 | |||
2979 | ATH5K_TRACE(ah->ah_sc); | ||
2980 | |||
2981 | /* 5210 doesn't have QCU*/ | ||
2982 | if (ah->ah_version == AR5K_AR5210) { | ||
2983 | /* | ||
2984 | * Wait for beaconn queue to finish by checking | ||
2985 | * Control Register and Beacon Status Register. | ||
2986 | */ | ||
2987 | for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) { | ||
2988 | if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F) | ||
2989 | || | ||
2990 | !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F)) | ||
2991 | break; | ||
2992 | udelay(10); | ||
2993 | } | ||
2994 | |||
2995 | /* Timeout... */ | ||
2996 | if (i <= 0) { | ||
2997 | /* | ||
2998 | * Re-schedule the beacon queue | ||
2999 | */ | ||
3000 | ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1); | ||
3001 | ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE, | ||
3002 | AR5K_BCR); | ||
3003 | |||
3004 | return -EIO; | ||
3005 | } | ||
3006 | ret = 0; | ||
3007 | } else { | ||
3008 | /*5211/5212*/ | ||
3009 | ret = ath5k_hw_register_timeout(ah, | ||
3010 | AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON), | ||
3011 | AR5K_QCU_STS_FRMPENDCNT, 0, false); | ||
3012 | |||
3013 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON)) | ||
3014 | return -EIO; | ||
3015 | } | ||
3016 | |||
3017 | return ret; | ||
3018 | } | ||
3019 | #endif | ||
3020 | |||
3021 | /* | ||
3022 | * Update mib counters (statistics) | ||
3023 | */ | ||
3024 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, | ||
3025 | struct ieee80211_low_level_stats *stats) | ||
3026 | { | ||
3027 | ATH5K_TRACE(ah->ah_sc); | ||
3028 | |||
3029 | /* Read-And-Clear */ | ||
3030 | stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); | ||
3031 | stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); | ||
3032 | stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK); | ||
3033 | stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); | ||
3034 | |||
3035 | /* XXX: Should we use this to track beacon count ? | ||
3036 | * -we read it anyway to clear the register */ | ||
3037 | ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); | ||
3038 | |||
3039 | /* Reset profile count registers on 5212*/ | ||
3040 | if (ah->ah_version == AR5K_AR5212) { | ||
3041 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); | ||
3042 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); | ||
3043 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR); | ||
3044 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE); | ||
3045 | } | ||
3046 | } | ||
3047 | |||
3048 | /** ath5k_hw_set_ack_bitrate - set bitrate for ACKs | ||
3049 | * | ||
3050 | * @ah: the &struct ath5k_hw | ||
3051 | * @high: determines if to use low bit rate or now | ||
3052 | */ | ||
3053 | void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) | ||
3054 | { | ||
3055 | if (ah->ah_version != AR5K_AR5212) | ||
3056 | return; | ||
3057 | else { | ||
3058 | u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; | ||
3059 | if (high) | ||
3060 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); | ||
3061 | else | ||
3062 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); | ||
3063 | } | ||
3064 | } | ||
3065 | |||
3066 | |||
3067 | /* | ||
3068 | * ACK/CTS Timeouts | ||
3069 | */ | ||
3070 | |||
3071 | /* | ||
3072 | * Set ACK timeout on PCU | ||
3073 | */ | ||
3074 | int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) | ||
3075 | { | ||
3076 | ATH5K_TRACE(ah->ah_sc); | ||
3077 | if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK), | ||
3078 | ah->ah_turbo) <= timeout) | ||
3079 | return -EINVAL; | ||
3080 | |||
3081 | AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, | ||
3082 | ath5k_hw_htoclock(timeout, ah->ah_turbo)); | ||
3083 | |||
3084 | return 0; | ||
3085 | } | ||
3086 | |||
3087 | /* | ||
3088 | * Read the ACK timeout from PCU | ||
3089 | */ | ||
3090 | unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah) | ||
3091 | { | ||
3092 | ATH5K_TRACE(ah->ah_sc); | ||
3093 | |||
3094 | return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, | ||
3095 | AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo); | ||
3096 | } | ||
3097 | |||
3098 | /* | ||
3099 | * Set CTS timeout on PCU | ||
3100 | */ | ||
3101 | int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) | ||
3102 | { | ||
3103 | ATH5K_TRACE(ah->ah_sc); | ||
3104 | if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS), | ||
3105 | ah->ah_turbo) <= timeout) | ||
3106 | return -EINVAL; | ||
3107 | |||
3108 | AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, | ||
3109 | ath5k_hw_htoclock(timeout, ah->ah_turbo)); | ||
3110 | |||
3111 | return 0; | ||
3112 | } | ||
3113 | |||
3114 | /* | ||
3115 | * Read CTS timeout from PCU | ||
3116 | */ | ||
3117 | unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) | ||
3118 | { | ||
3119 | ATH5K_TRACE(ah->ah_sc); | ||
3120 | return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, | ||
3121 | AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo); | ||
3122 | } | ||
3123 | |||
3124 | /* | ||
3125 | * Key table (WEP) functions | ||
3126 | */ | ||
3127 | |||
3128 | int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) | ||
3129 | { | ||
3130 | unsigned int i; | ||
3131 | |||
3132 | ATH5K_TRACE(ah->ah_sc); | ||
3133 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
3134 | |||
3135 | for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) | ||
3136 | ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); | ||
3137 | |||
3138 | /* | ||
3139 | * Set NULL encryption on AR5212+ | ||
3140 | * | ||
3141 | * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5) | ||
3142 | * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007 | ||
3143 | * | ||
3144 | * Note2: Windows driver (ndiswrapper) sets this to | ||
3145 | * 0x00000714 instead of 0x00000007 | ||
3146 | */ | ||
3147 | if (ah->ah_version > AR5K_AR5211) | ||
3148 | ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, | ||
3149 | AR5K_KEYTABLE_TYPE(entry)); | ||
3150 | |||
3151 | return 0; | ||
3152 | } | ||
3153 | |||
3154 | int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry) | ||
3155 | { | ||
3156 | ATH5K_TRACE(ah->ah_sc); | ||
3157 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
3158 | |||
3159 | /* Check the validation flag at the end of the entry */ | ||
3160 | return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) & | ||
3161 | AR5K_KEYTABLE_VALID; | ||
3162 | } | ||
3163 | |||
3164 | int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, | ||
3165 | const struct ieee80211_key_conf *key, const u8 *mac) | ||
3166 | { | ||
3167 | unsigned int i; | ||
3168 | __le32 key_v[5] = {}; | ||
3169 | u32 keytype; | ||
3170 | |||
3171 | ATH5K_TRACE(ah->ah_sc); | ||
3172 | |||
3173 | /* key->keylen comes in from mac80211 in bytes */ | ||
3174 | |||
3175 | if (key->keylen > AR5K_KEYTABLE_SIZE / 8) | ||
3176 | return -EOPNOTSUPP; | ||
3177 | |||
3178 | switch (key->keylen) { | ||
3179 | /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */ | ||
3180 | case 40 / 8: | ||
3181 | memcpy(&key_v[0], key->key, 5); | ||
3182 | keytype = AR5K_KEYTABLE_TYPE_40; | ||
3183 | break; | ||
3184 | |||
3185 | /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */ | ||
3186 | case 104 / 8: | ||
3187 | memcpy(&key_v[0], &key->key[0], 6); | ||
3188 | memcpy(&key_v[2], &key->key[6], 6); | ||
3189 | memcpy(&key_v[4], &key->key[12], 1); | ||
3190 | keytype = AR5K_KEYTABLE_TYPE_104; | ||
3191 | break; | ||
3192 | /* WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */ | ||
3193 | case 128 / 8: | ||
3194 | memcpy(&key_v[0], &key->key[0], 6); | ||
3195 | memcpy(&key_v[2], &key->key[6], 6); | ||
3196 | memcpy(&key_v[4], &key->key[12], 4); | ||
3197 | keytype = AR5K_KEYTABLE_TYPE_128; | ||
3198 | break; | ||
3199 | |||
3200 | default: | ||
3201 | return -EINVAL; /* shouldn't happen */ | ||
3202 | } | ||
3203 | |||
3204 | for (i = 0; i < ARRAY_SIZE(key_v); i++) | ||
3205 | ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), | ||
3206 | AR5K_KEYTABLE_OFF(entry, i)); | ||
3207 | |||
3208 | ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry)); | ||
3209 | |||
3210 | return ath5k_hw_set_key_lladdr(ah, entry, mac); | ||
3211 | } | ||
3212 | |||
3213 | int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) | ||
3214 | { | ||
3215 | u32 low_id, high_id; | ||
3216 | |||
3217 | ATH5K_TRACE(ah->ah_sc); | ||
3218 | /* Invalid entry (key table overflow) */ | ||
3219 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
3220 | |||
3221 | /* MAC may be NULL if it's a broadcast key. In this case no need to | ||
3222 | * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */ | ||
3223 | if (unlikely(mac == NULL)) { | ||
3224 | low_id = 0xffffffff; | ||
3225 | high_id = 0xffff | AR5K_KEYTABLE_VALID; | ||
3226 | } else { | ||
3227 | low_id = AR5K_LOW_ID(mac); | ||
3228 | high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID; | ||
3229 | } | ||
3230 | |||
3231 | ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry)); | ||
3232 | ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry)); | ||
3233 | |||
3234 | return 0; | ||
3235 | } | ||
3236 | |||
3237 | |||
3238 | /********************************************\ | ||
3239 | Queue Control Unit, DFS Control Unit Functions | ||
3240 | \********************************************/ | ||
3241 | |||
3242 | /* | ||
3243 | * Initialize a transmit queue | ||
3244 | */ | ||
3245 | int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, | ||
3246 | struct ath5k_txq_info *queue_info) | ||
3247 | { | ||
3248 | unsigned int queue; | ||
3249 | int ret; | ||
3250 | |||
3251 | ATH5K_TRACE(ah->ah_sc); | ||
3252 | |||
3253 | /* | ||
3254 | * Get queue by type | ||
3255 | */ | ||
3256 | /*5210 only has 2 queues*/ | ||
3257 | if (ah->ah_version == AR5K_AR5210) { | ||
3258 | switch (queue_type) { | ||
3259 | case AR5K_TX_QUEUE_DATA: | ||
3260 | queue = AR5K_TX_QUEUE_ID_NOQCU_DATA; | ||
3261 | break; | ||
3262 | case AR5K_TX_QUEUE_BEACON: | ||
3263 | case AR5K_TX_QUEUE_CAB: | ||
3264 | queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON; | ||
3265 | break; | ||
3266 | default: | ||
3267 | return -EINVAL; | ||
3268 | } | ||
3269 | } else { | ||
3270 | switch (queue_type) { | ||
3271 | case AR5K_TX_QUEUE_DATA: | ||
3272 | for (queue = AR5K_TX_QUEUE_ID_DATA_MIN; | ||
3273 | ah->ah_txq[queue].tqi_type != | ||
3274 | AR5K_TX_QUEUE_INACTIVE; queue++) { | ||
3275 | |||
3276 | if (queue > AR5K_TX_QUEUE_ID_DATA_MAX) | ||
3277 | return -EINVAL; | ||
3278 | } | ||
3279 | break; | ||
3280 | case AR5K_TX_QUEUE_UAPSD: | ||
3281 | queue = AR5K_TX_QUEUE_ID_UAPSD; | ||
3282 | break; | ||
3283 | case AR5K_TX_QUEUE_BEACON: | ||
3284 | queue = AR5K_TX_QUEUE_ID_BEACON; | ||
3285 | break; | ||
3286 | case AR5K_TX_QUEUE_CAB: | ||
3287 | queue = AR5K_TX_QUEUE_ID_CAB; | ||
3288 | break; | ||
3289 | case AR5K_TX_QUEUE_XR_DATA: | ||
3290 | if (ah->ah_version != AR5K_AR5212) | ||
3291 | ATH5K_ERR(ah->ah_sc, | ||
3292 | "XR data queues only supported in" | ||
3293 | " 5212!\n"); | ||
3294 | queue = AR5K_TX_QUEUE_ID_XR_DATA; | ||
3295 | break; | ||
3296 | default: | ||
3297 | return -EINVAL; | ||
3298 | } | ||
3299 | } | ||
3300 | |||
3301 | /* | ||
3302 | * Setup internal queue structure | ||
3303 | */ | ||
3304 | memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info)); | ||
3305 | ah->ah_txq[queue].tqi_type = queue_type; | ||
3306 | |||
3307 | if (queue_info != NULL) { | ||
3308 | queue_info->tqi_type = queue_type; | ||
3309 | ret = ath5k_hw_setup_tx_queueprops(ah, queue, queue_info); | ||
3310 | if (ret) | ||
3311 | return ret; | ||
3312 | } | ||
3313 | /* | ||
3314 | * We use ah_txq_status to hold a temp value for | ||
3315 | * the Secondary interrupt mask registers on 5211+ | ||
3316 | * check out ath5k_hw_reset_tx_queue | ||
3317 | */ | ||
3318 | AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue); | ||
3319 | |||
3320 | return queue; | ||
3321 | } | ||
3322 | |||
3323 | /* | ||
3324 | * Setup a transmit queue | ||
3325 | */ | ||
3326 | int ath5k_hw_setup_tx_queueprops(struct ath5k_hw *ah, int queue, | ||
3327 | const struct ath5k_txq_info *queue_info) | ||
3328 | { | ||
3329 | ATH5K_TRACE(ah->ah_sc); | ||
3330 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
3331 | |||
3332 | if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
3333 | return -EIO; | ||
3334 | |||
3335 | memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info)); | ||
3336 | |||
3337 | /*XXX: Is this supported on 5210 ?*/ | ||
3338 | if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA && | ||
3339 | ((queue_info->tqi_subtype == AR5K_WME_AC_VI) || | ||
3340 | (queue_info->tqi_subtype == AR5K_WME_AC_VO))) || | ||
3341 | queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD) | ||
3342 | ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; | ||
3343 | |||
3344 | return 0; | ||
3345 | } | ||
3346 | |||
3347 | /* | ||
3348 | * Get properties for a specific transmit queue | ||
3349 | */ | ||
3350 | int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, | ||
3351 | struct ath5k_txq_info *queue_info) | ||
3352 | { | ||
3353 | ATH5K_TRACE(ah->ah_sc); | ||
3354 | memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info)); | ||
3355 | return 0; | ||
3356 | } | ||
3357 | |||
3358 | /* | ||
3359 | * Set a transmit queue inactive | ||
3360 | */ | ||
3361 | void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) | ||
3362 | { | ||
3363 | ATH5K_TRACE(ah->ah_sc); | ||
3364 | if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) | ||
3365 | return; | ||
3366 | |||
3367 | /* This queue will be skipped in further operations */ | ||
3368 | ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE; | ||
3369 | /*For SIMR setup*/ | ||
3370 | AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue); | ||
3371 | } | ||
3372 | |||
3373 | /* | ||
3374 | * Set DFS params for a transmit queue | ||
3375 | */ | ||
3376 | int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | ||
3377 | { | ||
3378 | u32 cw_min, cw_max, retry_lg, retry_sh; | ||
3379 | struct ath5k_txq_info *tq = &ah->ah_txq[queue]; | ||
3380 | |||
3381 | ATH5K_TRACE(ah->ah_sc); | ||
3382 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
3383 | |||
3384 | tq = &ah->ah_txq[queue]; | ||
3385 | |||
3386 | if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
3387 | return 0; | ||
3388 | |||
3389 | if (ah->ah_version == AR5K_AR5210) { | ||
3390 | /* Only handle data queues, others will be ignored */ | ||
3391 | if (tq->tqi_type != AR5K_TX_QUEUE_DATA) | ||
3392 | return 0; | ||
3393 | |||
3394 | /* Set Slot time */ | ||
3395 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
3396 | AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME, | ||
3397 | AR5K_SLOT_TIME); | ||
3398 | /* Set ACK_CTS timeout */ | ||
3399 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
3400 | AR5K_INIT_ACK_CTS_TIMEOUT_TURBO : | ||
3401 | AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME); | ||
3402 | /* Set Transmit Latency */ | ||
3403 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
3404 | AR5K_INIT_TRANSMIT_LATENCY_TURBO : | ||
3405 | AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210); | ||
3406 | /* Set IFS0 */ | ||
3407 | if (ah->ah_turbo) | ||
3408 | ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + | ||
3409 | (ah->ah_aifs + tq->tqi_aifs) * | ||
3410 | AR5K_INIT_SLOT_TIME_TURBO) << | ||
3411 | AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO, | ||
3412 | AR5K_IFS0); | ||
3413 | else | ||
3414 | ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS + | ||
3415 | (ah->ah_aifs + tq->tqi_aifs) * | ||
3416 | AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) | | ||
3417 | AR5K_INIT_SIFS, AR5K_IFS0); | ||
3418 | |||
3419 | /* Set IFS1 */ | ||
3420 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
3421 | AR5K_INIT_PROTO_TIME_CNTRL_TURBO : | ||
3422 | AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); | ||
3423 | /* Set AR5K_PHY_SETTLING */ | ||
3424 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
3425 | (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) | ||
3426 | | 0x38 : | ||
3427 | (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) | ||
3428 | | 0x1C, | ||
3429 | AR5K_PHY_SETTLING); | ||
3430 | /* Set Frame Control Register */ | ||
3431 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
3432 | (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE | | ||
3433 | AR5K_PHY_TURBO_SHORT | 0x2020) : | ||
3434 | (AR5K_PHY_FRAME_CTL_INI | 0x1020), | ||
3435 | AR5K_PHY_FRAME_CTL_5210); | ||
3436 | } | ||
3437 | |||
3438 | /* | ||
3439 | * Calculate cwmin/max by channel mode | ||
3440 | */ | ||
3441 | cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN; | ||
3442 | cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX; | ||
3443 | ah->ah_aifs = AR5K_TUNE_AIFS; | ||
3444 | /*XR is only supported on 5212*/ | ||
3445 | if (IS_CHAN_XR(ah->ah_current_channel) && | ||
3446 | ah->ah_version == AR5K_AR5212) { | ||
3447 | cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR; | ||
3448 | cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR; | ||
3449 | ah->ah_aifs = AR5K_TUNE_AIFS_XR; | ||
3450 | /*B mode is not supported on 5210*/ | ||
3451 | } else if (IS_CHAN_B(ah->ah_current_channel) && | ||
3452 | ah->ah_version != AR5K_AR5210) { | ||
3453 | cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B; | ||
3454 | cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B; | ||
3455 | ah->ah_aifs = AR5K_TUNE_AIFS_11B; | ||
3456 | } | ||
3457 | |||
3458 | cw_min = 1; | ||
3459 | while (cw_min < ah->ah_cw_min) | ||
3460 | cw_min = (cw_min << 1) | 1; | ||
3461 | |||
3462 | cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) : | ||
3463 | ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1); | ||
3464 | cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) : | ||
3465 | ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1); | ||
3466 | |||
3467 | /* | ||
3468 | * Calculate and set retry limits | ||
3469 | */ | ||
3470 | if (ah->ah_software_retry) { | ||
3471 | /* XXX Need to test this */ | ||
3472 | retry_lg = ah->ah_limit_tx_retries; | ||
3473 | retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ? | ||
3474 | AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg; | ||
3475 | } else { | ||
3476 | retry_lg = AR5K_INIT_LG_RETRY; | ||
3477 | retry_sh = AR5K_INIT_SH_RETRY; | ||
3478 | } | ||
3479 | |||
3480 | /*No QCU/DCU [5210]*/ | ||
3481 | if (ah->ah_version == AR5K_AR5210) { | ||
3482 | ath5k_hw_reg_write(ah, | ||
3483 | (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) | ||
3484 | | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, | ||
3485 | AR5K_NODCU_RETRY_LMT_SLG_RETRY) | ||
3486 | | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, | ||
3487 | AR5K_NODCU_RETRY_LMT_SSH_RETRY) | ||
3488 | | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY) | ||
3489 | | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY), | ||
3490 | AR5K_NODCU_RETRY_LMT); | ||
3491 | } else { | ||
3492 | /*QCU/DCU [5211+]*/ | ||
3493 | ath5k_hw_reg_write(ah, | ||
3494 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, | ||
3495 | AR5K_DCU_RETRY_LMT_SLG_RETRY) | | ||
3496 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, | ||
3497 | AR5K_DCU_RETRY_LMT_SSH_RETRY) | | ||
3498 | AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) | | ||
3499 | AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY), | ||
3500 | AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); | ||
3501 | |||
3502 | /*===Rest is also for QCU/DCU only [5211+]===*/ | ||
3503 | |||
3504 | /* | ||
3505 | * Set initial content window (cw_min/cw_max) | ||
3506 | * and arbitrated interframe space (aifs)... | ||
3507 | */ | ||
3508 | ath5k_hw_reg_write(ah, | ||
3509 | AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | | ||
3510 | AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | | ||
3511 | AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs, | ||
3512 | AR5K_DCU_LCL_IFS_AIFS), | ||
3513 | AR5K_QUEUE_DFS_LOCAL_IFS(queue)); | ||
3514 | |||
3515 | /* | ||
3516 | * Set misc registers | ||
3517 | */ | ||
3518 | ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY, | ||
3519 | AR5K_QUEUE_MISC(queue)); | ||
3520 | |||
3521 | if (tq->tqi_cbr_period) { | ||
3522 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, | ||
3523 | AR5K_QCU_CBRCFG_INTVAL) | | ||
3524 | AR5K_REG_SM(tq->tqi_cbr_overflow_limit, | ||
3525 | AR5K_QCU_CBRCFG_ORN_THRES), | ||
3526 | AR5K_QUEUE_CBRCFG(queue)); | ||
3527 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | ||
3528 | AR5K_QCU_MISC_FRSHED_CBR); | ||
3529 | if (tq->tqi_cbr_overflow_limit) | ||
3530 | AR5K_REG_ENABLE_BITS(ah, | ||
3531 | AR5K_QUEUE_MISC(queue), | ||
3532 | AR5K_QCU_MISC_CBR_THRES_ENABLE); | ||
3533 | } | ||
3534 | |||
3535 | if (tq->tqi_ready_time) | ||
3536 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, | ||
3537 | AR5K_QCU_RDYTIMECFG_INTVAL) | | ||
3538 | AR5K_QCU_RDYTIMECFG_ENABLE, | ||
3539 | AR5K_QUEUE_RDYTIMECFG(queue)); | ||
3540 | |||
3541 | if (tq->tqi_burst_time) { | ||
3542 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time, | ||
3543 | AR5K_DCU_CHAN_TIME_DUR) | | ||
3544 | AR5K_DCU_CHAN_TIME_ENABLE, | ||
3545 | AR5K_QUEUE_DFS_CHANNEL_TIME(queue)); | ||
3546 | |||
3547 | if (tq->tqi_flags & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) | ||
3548 | AR5K_REG_ENABLE_BITS(ah, | ||
3549 | AR5K_QUEUE_MISC(queue), | ||
3550 | AR5K_QCU_MISC_RDY_VEOL_POLICY); | ||
3551 | } | ||
3552 | |||
3553 | if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) | ||
3554 | ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS, | ||
3555 | AR5K_QUEUE_DFS_MISC(queue)); | ||
3556 | |||
3557 | if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) | ||
3558 | ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG, | ||
3559 | AR5K_QUEUE_DFS_MISC(queue)); | ||
3560 | |||
3561 | /* | ||
3562 | * Set registers by queue type | ||
3563 | */ | ||
3564 | switch (tq->tqi_type) { | ||
3565 | case AR5K_TX_QUEUE_BEACON: | ||
3566 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | ||
3567 | AR5K_QCU_MISC_FRSHED_DBA_GT | | ||
3568 | AR5K_QCU_MISC_CBREXP_BCN | | ||
3569 | AR5K_QCU_MISC_BCN_ENABLE); | ||
3570 | |||
3571 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), | ||
3572 | (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << | ||
3573 | AR5K_DCU_MISC_ARBLOCK_CTL_S) | | ||
3574 | AR5K_DCU_MISC_POST_FR_BKOFF_DIS | | ||
3575 | AR5K_DCU_MISC_BCN_ENABLE); | ||
3576 | |||
3577 | ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - | ||
3578 | (AR5K_TUNE_SW_BEACON_RESP - | ||
3579 | AR5K_TUNE_DMA_BEACON_RESP) - | ||
3580 | AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | | ||
3581 | AR5K_QCU_RDYTIMECFG_ENABLE, | ||
3582 | AR5K_QUEUE_RDYTIMECFG(queue)); | ||
3583 | break; | ||
3584 | |||
3585 | case AR5K_TX_QUEUE_CAB: | ||
3586 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | ||
3587 | AR5K_QCU_MISC_FRSHED_DBA_GT | | ||
3588 | AR5K_QCU_MISC_CBREXP | | ||
3589 | AR5K_QCU_MISC_CBREXP_BCN); | ||
3590 | |||
3591 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), | ||
3592 | (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << | ||
3593 | AR5K_DCU_MISC_ARBLOCK_CTL_S)); | ||
3594 | break; | ||
3595 | |||
3596 | case AR5K_TX_QUEUE_UAPSD: | ||
3597 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | ||
3598 | AR5K_QCU_MISC_CBREXP); | ||
3599 | break; | ||
3600 | |||
3601 | case AR5K_TX_QUEUE_DATA: | ||
3602 | default: | ||
3603 | break; | ||
3604 | } | ||
3605 | |||
3606 | /* | ||
3607 | * Enable interrupts for this tx queue | ||
3608 | * in the secondary interrupt mask registers | ||
3609 | */ | ||
3610 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE) | ||
3611 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue); | ||
3612 | |||
3613 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE) | ||
3614 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue); | ||
3615 | |||
3616 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE) | ||
3617 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue); | ||
3618 | |||
3619 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE) | ||
3620 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue); | ||
3621 | |||
3622 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) | ||
3623 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); | ||
3624 | |||
3625 | |||
3626 | /* Update secondary interrupt mask registers */ | ||
3627 | ah->ah_txq_imr_txok &= ah->ah_txq_status; | ||
3628 | ah->ah_txq_imr_txerr &= ah->ah_txq_status; | ||
3629 | ah->ah_txq_imr_txurn &= ah->ah_txq_status; | ||
3630 | ah->ah_txq_imr_txdesc &= ah->ah_txq_status; | ||
3631 | ah->ah_txq_imr_txeol &= ah->ah_txq_status; | ||
3632 | |||
3633 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, | ||
3634 | AR5K_SIMR0_QCU_TXOK) | | ||
3635 | AR5K_REG_SM(ah->ah_txq_imr_txdesc, | ||
3636 | AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0); | ||
3637 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr, | ||
3638 | AR5K_SIMR1_QCU_TXERR) | | ||
3639 | AR5K_REG_SM(ah->ah_txq_imr_txeol, | ||
3640 | AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1); | ||
3641 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn, | ||
3642 | AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2); | ||
3643 | } | ||
3644 | |||
3645 | return 0; | ||
3646 | } | ||
3647 | |||
3648 | /* | ||
3649 | * Get number of pending frames | ||
3650 | * for a specific queue [5211+] | ||
3651 | */ | ||
3652 | u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) { | ||
3653 | ATH5K_TRACE(ah->ah_sc); | ||
3654 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
3655 | |||
3656 | /* Return if queue is declared inactive */ | ||
3657 | if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
3658 | return false; | ||
3659 | |||
3660 | /* XXX: How about AR5K_CFG_TXCNT ? */ | ||
3661 | if (ah->ah_version == AR5K_AR5210) | ||
3662 | return false; | ||
3663 | |||
3664 | return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT; | ||
3665 | } | ||
3666 | |||
3667 | /* | ||
3668 | * Set slot time | ||
3669 | */ | ||
3670 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) | ||
3671 | { | ||
3672 | ATH5K_TRACE(ah->ah_sc); | ||
3673 | if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX) | ||
3674 | return -EINVAL; | ||
3675 | |||
3676 | if (ah->ah_version == AR5K_AR5210) | ||
3677 | ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time, | ||
3678 | ah->ah_turbo), AR5K_SLOT_TIME); | ||
3679 | else | ||
3680 | ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT); | ||
3681 | |||
3682 | return 0; | ||
3683 | } | ||
3684 | |||
3685 | /* | ||
3686 | * Get slot time | ||
3687 | */ | ||
3688 | unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) | ||
3689 | { | ||
3690 | ATH5K_TRACE(ah->ah_sc); | ||
3691 | if (ah->ah_version == AR5K_AR5210) | ||
3692 | return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah, | ||
3693 | AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo); | ||
3694 | else | ||
3695 | return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff; | ||
3696 | } | ||
3697 | |||
3698 | |||
3699 | /******************************\ | ||
3700 | Hardware Descriptor Functions | ||
3701 | \******************************/ | ||
3702 | |||
3703 | /* | ||
3704 | * TX Descriptor | ||
3705 | */ | ||
3706 | |||
3707 | /* | ||
3708 | * Initialize the 2-word tx descriptor on 5210/5211 | ||
3709 | */ | ||
3710 | static int | ||
3711 | ath5k_hw_setup_2word_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | ||
3712 | unsigned int pkt_len, unsigned int hdr_len, enum ath5k_pkt_type type, | ||
3713 | unsigned int tx_power, unsigned int tx_rate0, unsigned int tx_tries0, | ||
3714 | unsigned int key_index, unsigned int antenna_mode, unsigned int flags, | ||
3715 | unsigned int rtscts_rate, unsigned int rtscts_duration) | ||
3716 | { | ||
3717 | u32 frame_type; | ||
3718 | struct ath5k_hw_2w_tx_ctl *tx_ctl; | ||
3719 | unsigned int frame_len; | ||
3720 | |||
3721 | tx_ctl = &desc->ud.ds_tx5210.tx_ctl; | ||
3722 | |||
3723 | /* | ||
3724 | * Validate input | ||
3725 | * - Zero retries don't make sense. | ||
3726 | * - A zero rate will put the HW into a mode where it continously sends | ||
3727 | * noise on the channel, so it is important to avoid this. | ||
3728 | */ | ||
3729 | if (unlikely(tx_tries0 == 0)) { | ||
3730 | ATH5K_ERR(ah->ah_sc, "zero retries\n"); | ||
3731 | WARN_ON(1); | ||
3732 | return -EINVAL; | ||
3733 | } | ||
3734 | if (unlikely(tx_rate0 == 0)) { | ||
3735 | ATH5K_ERR(ah->ah_sc, "zero rate\n"); | ||
3736 | WARN_ON(1); | ||
3737 | return -EINVAL; | ||
3738 | } | ||
3739 | |||
3740 | /* Clear descriptor */ | ||
3741 | memset(&desc->ud.ds_tx5210, 0, sizeof(struct ath5k_hw_5210_tx_desc)); | ||
3742 | |||
3743 | /* Setup control descriptor */ | ||
3744 | |||
3745 | /* Verify and set frame length */ | ||
3746 | |||
3747 | /* remove padding we might have added before */ | ||
3748 | frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; | ||
3749 | |||
3750 | if (frame_len & ~AR5K_2W_TX_DESC_CTL0_FRAME_LEN) | ||
3751 | return -EINVAL; | ||
3752 | |||
3753 | tx_ctl->tx_control_0 = frame_len & AR5K_2W_TX_DESC_CTL0_FRAME_LEN; | ||
3754 | |||
3755 | /* Verify and set buffer length */ | ||
3756 | |||
3757 | /* NB: beacon's BufLen must be a multiple of 4 bytes */ | ||
3758 | if(type == AR5K_PKT_TYPE_BEACON) | ||
3759 | pkt_len = roundup(pkt_len, 4); | ||
3760 | |||
3761 | if (pkt_len & ~AR5K_2W_TX_DESC_CTL1_BUF_LEN) | ||
3762 | return -EINVAL; | ||
3763 | |||
3764 | tx_ctl->tx_control_1 = pkt_len & AR5K_2W_TX_DESC_CTL1_BUF_LEN; | ||
3765 | |||
3766 | /* | ||
3767 | * Verify and set header length | ||
3768 | * XXX: I only found that on 5210 code, does it work on 5211 ? | ||
3769 | */ | ||
3770 | if (ah->ah_version == AR5K_AR5210) { | ||
3771 | if (hdr_len & ~AR5K_2W_TX_DESC_CTL0_HEADER_LEN) | ||
3772 | return -EINVAL; | ||
3773 | tx_ctl->tx_control_0 |= | ||
3774 | AR5K_REG_SM(hdr_len, AR5K_2W_TX_DESC_CTL0_HEADER_LEN); | ||
3775 | } | ||
3776 | |||
3777 | /*Diferences between 5210-5211*/ | ||
3778 | if (ah->ah_version == AR5K_AR5210) { | ||
3779 | switch (type) { | ||
3780 | case AR5K_PKT_TYPE_BEACON: | ||
3781 | case AR5K_PKT_TYPE_PROBE_RESP: | ||
3782 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_NO_DELAY; | ||
3783 | case AR5K_PKT_TYPE_PIFS: | ||
3784 | frame_type = AR5K_AR5210_TX_DESC_FRAME_TYPE_PIFS; | ||
3785 | default: | ||
3786 | frame_type = type /*<< 2 ?*/; | ||
3787 | } | ||
3788 | |||
3789 | tx_ctl->tx_control_0 |= | ||
3790 | AR5K_REG_SM(frame_type, AR5K_2W_TX_DESC_CTL0_FRAME_TYPE) | | ||
3791 | AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE); | ||
3792 | } else { | ||
3793 | tx_ctl->tx_control_0 |= | ||
3794 | AR5K_REG_SM(tx_rate0, AR5K_2W_TX_DESC_CTL0_XMIT_RATE) | | ||
3795 | AR5K_REG_SM(antenna_mode, AR5K_2W_TX_DESC_CTL0_ANT_MODE_XMIT); | ||
3796 | tx_ctl->tx_control_1 |= | ||
3797 | AR5K_REG_SM(type, AR5K_2W_TX_DESC_CTL1_FRAME_TYPE); | ||
3798 | } | ||
3799 | #define _TX_FLAGS(_c, _flag) \ | ||
3800 | if (flags & AR5K_TXDESC_##_flag) \ | ||
3801 | tx_ctl->tx_control_##_c |= \ | ||
3802 | AR5K_2W_TX_DESC_CTL##_c##_##_flag | ||
3803 | |||
3804 | _TX_FLAGS(0, CLRDMASK); | ||
3805 | _TX_FLAGS(0, VEOL); | ||
3806 | _TX_FLAGS(0, INTREQ); | ||
3807 | _TX_FLAGS(0, RTSENA); | ||
3808 | _TX_FLAGS(1, NOACK); | ||
3809 | |||
3810 | #undef _TX_FLAGS | ||
3811 | |||
3812 | /* | ||
3813 | * WEP crap | ||
3814 | */ | ||
3815 | if (key_index != AR5K_TXKEYIX_INVALID) { | ||
3816 | tx_ctl->tx_control_0 |= | ||
3817 | AR5K_2W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; | ||
3818 | tx_ctl->tx_control_1 |= | ||
3819 | AR5K_REG_SM(key_index, | ||
3820 | AR5K_2W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); | ||
3821 | } | ||
3822 | |||
3823 | /* | ||
3824 | * RTS/CTS Duration [5210 ?] | ||
3825 | */ | ||
3826 | if ((ah->ah_version == AR5K_AR5210) && | ||
3827 | (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA))) | ||
3828 | tx_ctl->tx_control_1 |= rtscts_duration & | ||
3829 | AR5K_2W_TX_DESC_CTL1_RTS_DURATION; | ||
3830 | |||
3831 | return 0; | ||
3832 | } | ||
3833 | |||
3834 | /* | ||
3835 | * Initialize the 4-word tx descriptor on 5212 | ||
3836 | */ | ||
3837 | static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, | ||
3838 | struct ath5k_desc *desc, unsigned int pkt_len, unsigned int hdr_len, | ||
3839 | enum ath5k_pkt_type type, unsigned int tx_power, unsigned int tx_rate0, | ||
3840 | unsigned int tx_tries0, unsigned int key_index, | ||
3841 | unsigned int antenna_mode, unsigned int flags, unsigned int rtscts_rate, | ||
3842 | unsigned int rtscts_duration) | ||
3843 | { | ||
3844 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | ||
3845 | unsigned int frame_len; | ||
3846 | |||
3847 | ATH5K_TRACE(ah->ah_sc); | ||
3848 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | ||
3849 | |||
3850 | /* | ||
3851 | * Validate input | ||
3852 | * - Zero retries don't make sense. | ||
3853 | * - A zero rate will put the HW into a mode where it continously sends | ||
3854 | * noise on the channel, so it is important to avoid this. | ||
3855 | */ | ||
3856 | if (unlikely(tx_tries0 == 0)) { | ||
3857 | ATH5K_ERR(ah->ah_sc, "zero retries\n"); | ||
3858 | WARN_ON(1); | ||
3859 | return -EINVAL; | ||
3860 | } | ||
3861 | if (unlikely(tx_rate0 == 0)) { | ||
3862 | ATH5K_ERR(ah->ah_sc, "zero rate\n"); | ||
3863 | WARN_ON(1); | ||
3864 | return -EINVAL; | ||
3865 | } | ||
3866 | |||
3867 | /* Clear descriptor */ | ||
3868 | memset(&desc->ud.ds_tx5212, 0, sizeof(struct ath5k_hw_5212_tx_desc)); | ||
3869 | |||
3870 | /* Setup control descriptor */ | ||
3871 | |||
3872 | /* Verify and set frame length */ | ||
3873 | |||
3874 | /* remove padding we might have added before */ | ||
3875 | frame_len = pkt_len - (hdr_len & 3) + FCS_LEN; | ||
3876 | |||
3877 | if (frame_len & ~AR5K_4W_TX_DESC_CTL0_FRAME_LEN) | ||
3878 | return -EINVAL; | ||
3879 | |||
3880 | tx_ctl->tx_control_0 = frame_len & AR5K_4W_TX_DESC_CTL0_FRAME_LEN; | ||
3881 | |||
3882 | /* Verify and set buffer length */ | ||
3883 | |||
3884 | /* NB: beacon's BufLen must be a multiple of 4 bytes */ | ||
3885 | if(type == AR5K_PKT_TYPE_BEACON) | ||
3886 | pkt_len = roundup(pkt_len, 4); | ||
3887 | |||
3888 | if (pkt_len & ~AR5K_4W_TX_DESC_CTL1_BUF_LEN) | ||
3889 | return -EINVAL; | ||
3890 | |||
3891 | tx_ctl->tx_control_1 = pkt_len & AR5K_4W_TX_DESC_CTL1_BUF_LEN; | ||
3892 | |||
3893 | tx_ctl->tx_control_0 |= | ||
3894 | AR5K_REG_SM(tx_power, AR5K_4W_TX_DESC_CTL0_XMIT_POWER) | | ||
3895 | AR5K_REG_SM(antenna_mode, AR5K_4W_TX_DESC_CTL0_ANT_MODE_XMIT); | ||
3896 | tx_ctl->tx_control_1 |= AR5K_REG_SM(type, | ||
3897 | AR5K_4W_TX_DESC_CTL1_FRAME_TYPE); | ||
3898 | tx_ctl->tx_control_2 = AR5K_REG_SM(tx_tries0 + AR5K_TUNE_HWTXTRIES, | ||
3899 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES0); | ||
3900 | tx_ctl->tx_control_3 = tx_rate0 & AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
3901 | |||
3902 | #define _TX_FLAGS(_c, _flag) \ | ||
3903 | if (flags & AR5K_TXDESC_##_flag) \ | ||
3904 | tx_ctl->tx_control_##_c |= \ | ||
3905 | AR5K_4W_TX_DESC_CTL##_c##_##_flag | ||
3906 | |||
3907 | _TX_FLAGS(0, CLRDMASK); | ||
3908 | _TX_FLAGS(0, VEOL); | ||
3909 | _TX_FLAGS(0, INTREQ); | ||
3910 | _TX_FLAGS(0, RTSENA); | ||
3911 | _TX_FLAGS(0, CTSENA); | ||
3912 | _TX_FLAGS(1, NOACK); | ||
3913 | |||
3914 | #undef _TX_FLAGS | ||
3915 | |||
3916 | /* | ||
3917 | * WEP crap | ||
3918 | */ | ||
3919 | if (key_index != AR5K_TXKEYIX_INVALID) { | ||
3920 | tx_ctl->tx_control_0 |= AR5K_4W_TX_DESC_CTL0_ENCRYPT_KEY_VALID; | ||
3921 | tx_ctl->tx_control_1 |= AR5K_REG_SM(key_index, | ||
3922 | AR5K_4W_TX_DESC_CTL1_ENCRYPT_KEY_INDEX); | ||
3923 | } | ||
3924 | |||
3925 | /* | ||
3926 | * RTS/CTS | ||
3927 | */ | ||
3928 | if (flags & (AR5K_TXDESC_RTSENA | AR5K_TXDESC_CTSENA)) { | ||
3929 | if ((flags & AR5K_TXDESC_RTSENA) && | ||
3930 | (flags & AR5K_TXDESC_CTSENA)) | ||
3931 | return -EINVAL; | ||
3932 | tx_ctl->tx_control_2 |= rtscts_duration & | ||
3933 | AR5K_4W_TX_DESC_CTL2_RTS_DURATION; | ||
3934 | tx_ctl->tx_control_3 |= AR5K_REG_SM(rtscts_rate, | ||
3935 | AR5K_4W_TX_DESC_CTL3_RTS_CTS_RATE); | ||
3936 | } | ||
3937 | |||
3938 | return 0; | ||
3939 | } | ||
3940 | |||
3941 | /* | ||
3942 | * Initialize a 4-word multirate tx descriptor on 5212 | ||
3943 | */ | ||
3944 | static int | ||
3945 | ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | ||
3946 | unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2, | ||
3947 | unsigned int tx_rate3, u_int tx_tries3) | ||
3948 | { | ||
3949 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | ||
3950 | |||
3951 | /* | ||
3952 | * Rates can be 0 as long as the retry count is 0 too. | ||
3953 | * A zero rate and nonzero retry count will put the HW into a mode where | ||
3954 | * it continously sends noise on the channel, so it is important to | ||
3955 | * avoid this. | ||
3956 | */ | ||
3957 | if (unlikely((tx_rate1 == 0 && tx_tries1 != 0) || | ||
3958 | (tx_rate2 == 0 && tx_tries2 != 0) || | ||
3959 | (tx_rate3 == 0 && tx_tries3 != 0))) { | ||
3960 | ATH5K_ERR(ah->ah_sc, "zero rate\n"); | ||
3961 | WARN_ON(1); | ||
3962 | return -EINVAL; | ||
3963 | } | ||
3964 | |||
3965 | if (ah->ah_version == AR5K_AR5212) { | ||
3966 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | ||
3967 | |||
3968 | #define _XTX_TRIES(_n) \ | ||
3969 | if (tx_tries##_n) { \ | ||
3970 | tx_ctl->tx_control_2 |= \ | ||
3971 | AR5K_REG_SM(tx_tries##_n, \ | ||
3972 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES##_n); \ | ||
3973 | tx_ctl->tx_control_3 |= \ | ||
3974 | AR5K_REG_SM(tx_rate##_n, \ | ||
3975 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE##_n); \ | ||
3976 | } | ||
3977 | |||
3978 | _XTX_TRIES(1); | ||
3979 | _XTX_TRIES(2); | ||
3980 | _XTX_TRIES(3); | ||
3981 | |||
3982 | #undef _XTX_TRIES | ||
3983 | |||
3984 | return 1; | ||
3985 | } | ||
3986 | |||
3987 | return 0; | ||
3988 | } | ||
3989 | |||
3990 | /* | ||
3991 | * Proccess the tx status descriptor on 5210/5211 | ||
3992 | */ | ||
3993 | static int ath5k_hw_proc_2word_tx_status(struct ath5k_hw *ah, | ||
3994 | struct ath5k_desc *desc, struct ath5k_tx_status *ts) | ||
3995 | { | ||
3996 | struct ath5k_hw_2w_tx_ctl *tx_ctl; | ||
3997 | struct ath5k_hw_tx_status *tx_status; | ||
3998 | |||
3999 | ATH5K_TRACE(ah->ah_sc); | ||
4000 | |||
4001 | tx_ctl = &desc->ud.ds_tx5210.tx_ctl; | ||
4002 | tx_status = &desc->ud.ds_tx5210.tx_stat; | ||
4003 | |||
4004 | /* No frame has been send or error */ | ||
4005 | if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) | ||
4006 | return -EINPROGRESS; | ||
4007 | |||
4008 | /* | ||
4009 | * Get descriptor status | ||
4010 | */ | ||
4011 | ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, | ||
4012 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | ||
4013 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | ||
4014 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | ||
4015 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | ||
4016 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | ||
4017 | /*TODO: ts->ts_virtcol + test*/ | ||
4018 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | ||
4019 | AR5K_DESC_TX_STATUS1_SEQ_NUM); | ||
4020 | ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, | ||
4021 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | ||
4022 | ts->ts_antenna = 1; | ||
4023 | ts->ts_status = 0; | ||
4024 | ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_0, | ||
4025 | AR5K_2W_TX_DESC_CTL0_XMIT_RATE); | ||
4026 | |||
4027 | if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){ | ||
4028 | if (tx_status->tx_status_0 & | ||
4029 | AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) | ||
4030 | ts->ts_status |= AR5K_TXERR_XRETRY; | ||
4031 | |||
4032 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) | ||
4033 | ts->ts_status |= AR5K_TXERR_FIFO; | ||
4034 | |||
4035 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) | ||
4036 | ts->ts_status |= AR5K_TXERR_FILT; | ||
4037 | } | ||
4038 | |||
4039 | return 0; | ||
4040 | } | ||
4041 | |||
4042 | /* | ||
4043 | * Proccess a tx descriptor on 5212 | ||
4044 | */ | ||
4045 | static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *ah, | ||
4046 | struct ath5k_desc *desc, struct ath5k_tx_status *ts) | ||
4047 | { | ||
4048 | struct ath5k_hw_4w_tx_ctl *tx_ctl; | ||
4049 | struct ath5k_hw_tx_status *tx_status; | ||
4050 | |||
4051 | ATH5K_TRACE(ah->ah_sc); | ||
4052 | |||
4053 | tx_ctl = &desc->ud.ds_tx5212.tx_ctl; | ||
4054 | tx_status = &desc->ud.ds_tx5212.tx_stat; | ||
4055 | |||
4056 | /* No frame has been send or error */ | ||
4057 | if (unlikely((tx_status->tx_status_1 & AR5K_DESC_TX_STATUS1_DONE) == 0)) | ||
4058 | return -EINPROGRESS; | ||
4059 | |||
4060 | /* | ||
4061 | * Get descriptor status | ||
4062 | */ | ||
4063 | ts->ts_tstamp = AR5K_REG_MS(tx_status->tx_status_0, | ||
4064 | AR5K_DESC_TX_STATUS0_SEND_TIMESTAMP); | ||
4065 | ts->ts_shortretry = AR5K_REG_MS(tx_status->tx_status_0, | ||
4066 | AR5K_DESC_TX_STATUS0_SHORT_RETRY_COUNT); | ||
4067 | ts->ts_longretry = AR5K_REG_MS(tx_status->tx_status_0, | ||
4068 | AR5K_DESC_TX_STATUS0_LONG_RETRY_COUNT); | ||
4069 | ts->ts_seqnum = AR5K_REG_MS(tx_status->tx_status_1, | ||
4070 | AR5K_DESC_TX_STATUS1_SEQ_NUM); | ||
4071 | ts->ts_rssi = AR5K_REG_MS(tx_status->tx_status_1, | ||
4072 | AR5K_DESC_TX_STATUS1_ACK_SIG_STRENGTH); | ||
4073 | ts->ts_antenna = (tx_status->tx_status_1 & | ||
4074 | AR5K_DESC_TX_STATUS1_XMIT_ANTENNA) ? 2 : 1; | ||
4075 | ts->ts_status = 0; | ||
4076 | |||
4077 | switch (AR5K_REG_MS(tx_status->tx_status_1, | ||
4078 | AR5K_DESC_TX_STATUS1_FINAL_TS_INDEX)) { | ||
4079 | case 0: | ||
4080 | ts->ts_rate = tx_ctl->tx_control_3 & | ||
4081 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE0; | ||
4082 | break; | ||
4083 | case 1: | ||
4084 | ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
4085 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE1); | ||
4086 | ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, | ||
4087 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES1); | ||
4088 | break; | ||
4089 | case 2: | ||
4090 | ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
4091 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE2); | ||
4092 | ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, | ||
4093 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES2); | ||
4094 | break; | ||
4095 | case 3: | ||
4096 | ts->ts_rate = AR5K_REG_MS(tx_ctl->tx_control_3, | ||
4097 | AR5K_4W_TX_DESC_CTL3_XMIT_RATE3); | ||
4098 | ts->ts_longretry += AR5K_REG_MS(tx_ctl->tx_control_2, | ||
4099 | AR5K_4W_TX_DESC_CTL2_XMIT_TRIES3); | ||
4100 | break; | ||
4101 | } | ||
4102 | |||
4103 | if ((tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FRAME_XMIT_OK) == 0){ | ||
4104 | if (tx_status->tx_status_0 & | ||
4105 | AR5K_DESC_TX_STATUS0_EXCESSIVE_RETRIES) | ||
4106 | ts->ts_status |= AR5K_TXERR_XRETRY; | ||
4107 | |||
4108 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FIFO_UNDERRUN) | ||
4109 | ts->ts_status |= AR5K_TXERR_FIFO; | ||
4110 | |||
4111 | if (tx_status->tx_status_0 & AR5K_DESC_TX_STATUS0_FILTERED) | ||
4112 | ts->ts_status |= AR5K_TXERR_FILT; | ||
4113 | } | ||
4114 | |||
4115 | return 0; | ||
4116 | } | ||
4117 | |||
4118 | /* | ||
4119 | * RX Descriptor | ||
4120 | */ | ||
4121 | |||
4122 | /* | ||
4123 | * Initialize an rx descriptor | ||
4124 | */ | ||
4125 | int ath5k_hw_setup_rx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, | ||
4126 | u32 size, unsigned int flags) | ||
4127 | { | ||
4128 | struct ath5k_hw_rx_ctl *rx_ctl; | ||
4129 | |||
4130 | ATH5K_TRACE(ah->ah_sc); | ||
4131 | rx_ctl = &desc->ud.ds_rx.rx_ctl; | ||
4132 | |||
4133 | /* | ||
4134 | * Clear the descriptor | ||
4135 | * If we don't clean the status descriptor, | ||
4136 | * while scanning we get too many results, | ||
4137 | * most of them virtual, after some secs | ||
4138 | * of scanning system hangs. M.F. | ||
4139 | */ | ||
4140 | memset(&desc->ud.ds_rx, 0, sizeof(struct ath5k_hw_all_rx_desc)); | ||
4141 | |||
4142 | /* Setup descriptor */ | ||
4143 | rx_ctl->rx_control_1 = size & AR5K_DESC_RX_CTL1_BUF_LEN; | ||
4144 | if (unlikely(rx_ctl->rx_control_1 != size)) | ||
4145 | return -EINVAL; | ||
4146 | |||
4147 | if (flags & AR5K_RXDESC_INTREQ) | ||
4148 | rx_ctl->rx_control_1 |= AR5K_DESC_RX_CTL1_INTREQ; | ||
4149 | |||
4150 | return 0; | ||
4151 | } | ||
4152 | |||
4153 | /* | ||
4154 | * Proccess the rx status descriptor on 5210/5211 | ||
4155 | */ | ||
4156 | static int ath5k_hw_proc_5210_rx_status(struct ath5k_hw *ah, | ||
4157 | struct ath5k_desc *desc, struct ath5k_rx_status *rs) | ||
4158 | { | ||
4159 | struct ath5k_hw_rx_status *rx_status; | ||
4160 | |||
4161 | rx_status = &desc->ud.ds_rx.u.rx_stat; | ||
4162 | |||
4163 | /* No frame received / not ready */ | ||
4164 | if (unlikely((rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_DONE) | ||
4165 | == 0)) | ||
4166 | return -EINPROGRESS; | ||
4167 | |||
4168 | /* | ||
4169 | * Frame receive status | ||
4170 | */ | ||
4171 | rs->rs_datalen = rx_status->rx_status_0 & | ||
4172 | AR5K_5210_RX_DESC_STATUS0_DATA_LEN; | ||
4173 | rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, | ||
4174 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_SIGNAL); | ||
4175 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | ||
4176 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_RATE); | ||
4177 | rs->rs_antenna = rx_status->rx_status_0 & | ||
4178 | AR5K_5210_RX_DESC_STATUS0_RECEIVE_ANTENNA; | ||
4179 | rs->rs_more = rx_status->rx_status_0 & | ||
4180 | AR5K_5210_RX_DESC_STATUS0_MORE; | ||
4181 | /* TODO: this timestamp is 13 bit, later on we assume 15 bit */ | ||
4182 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | ||
4183 | AR5K_5210_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | ||
4184 | rs->rs_status = 0; | ||
4185 | rs->rs_phyerr = 0; | ||
4186 | |||
4187 | /* | ||
4188 | * Key table status | ||
4189 | */ | ||
4190 | if (rx_status->rx_status_1 & AR5K_5210_RX_DESC_STATUS1_KEY_INDEX_VALID) | ||
4191 | rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, | ||
4192 | AR5K_5210_RX_DESC_STATUS1_KEY_INDEX); | ||
4193 | else | ||
4194 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; | ||
4195 | |||
4196 | /* | ||
4197 | * Receive/descriptor errors | ||
4198 | */ | ||
4199 | if ((rx_status->rx_status_1 & | ||
4200 | AR5K_5210_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) { | ||
4201 | if (rx_status->rx_status_1 & | ||
4202 | AR5K_5210_RX_DESC_STATUS1_CRC_ERROR) | ||
4203 | rs->rs_status |= AR5K_RXERR_CRC; | ||
4204 | |||
4205 | if (rx_status->rx_status_1 & | ||
4206 | AR5K_5210_RX_DESC_STATUS1_FIFO_OVERRUN) | ||
4207 | rs->rs_status |= AR5K_RXERR_FIFO; | ||
4208 | |||
4209 | if (rx_status->rx_status_1 & | ||
4210 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR) { | ||
4211 | rs->rs_status |= AR5K_RXERR_PHY; | ||
4212 | rs->rs_phyerr |= AR5K_REG_MS(rx_status->rx_status_1, | ||
4213 | AR5K_5210_RX_DESC_STATUS1_PHY_ERROR); | ||
4214 | } | ||
4215 | |||
4216 | if (rx_status->rx_status_1 & | ||
4217 | AR5K_5210_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) | ||
4218 | rs->rs_status |= AR5K_RXERR_DECRYPT; | ||
4219 | } | ||
4220 | |||
4221 | return 0; | ||
4222 | } | ||
4223 | |||
4224 | /* | ||
4225 | * Proccess the rx status descriptor on 5212 | ||
4226 | */ | ||
4227 | static int ath5k_hw_proc_5212_rx_status(struct ath5k_hw *ah, | ||
4228 | struct ath5k_desc *desc, struct ath5k_rx_status *rs) | ||
4229 | { | ||
4230 | struct ath5k_hw_rx_status *rx_status; | ||
4231 | struct ath5k_hw_rx_error *rx_err; | ||
4232 | |||
4233 | ATH5K_TRACE(ah->ah_sc); | ||
4234 | rx_status = &desc->ud.ds_rx.u.rx_stat; | ||
4235 | |||
4236 | /* Overlay on error */ | ||
4237 | rx_err = &desc->ud.ds_rx.u.rx_err; | ||
4238 | |||
4239 | /* No frame received / not ready */ | ||
4240 | if (unlikely((rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_DONE) | ||
4241 | == 0)) | ||
4242 | return -EINPROGRESS; | ||
4243 | |||
4244 | /* | ||
4245 | * Frame receive status | ||
4246 | */ | ||
4247 | rs->rs_datalen = rx_status->rx_status_0 & | ||
4248 | AR5K_5212_RX_DESC_STATUS0_DATA_LEN; | ||
4249 | rs->rs_rssi = AR5K_REG_MS(rx_status->rx_status_0, | ||
4250 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_SIGNAL); | ||
4251 | rs->rs_rate = AR5K_REG_MS(rx_status->rx_status_0, | ||
4252 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_RATE); | ||
4253 | rs->rs_antenna = rx_status->rx_status_0 & | ||
4254 | AR5K_5212_RX_DESC_STATUS0_RECEIVE_ANTENNA; | ||
4255 | rs->rs_more = rx_status->rx_status_0 & | ||
4256 | AR5K_5212_RX_DESC_STATUS0_MORE; | ||
4257 | rs->rs_tstamp = AR5K_REG_MS(rx_status->rx_status_1, | ||
4258 | AR5K_5212_RX_DESC_STATUS1_RECEIVE_TIMESTAMP); | ||
4259 | rs->rs_status = 0; | ||
4260 | rs->rs_phyerr = 0; | ||
4261 | |||
4262 | /* | ||
4263 | * Key table status | ||
4264 | */ | ||
4265 | if (rx_status->rx_status_1 & AR5K_5212_RX_DESC_STATUS1_KEY_INDEX_VALID) | ||
4266 | rs->rs_keyix = AR5K_REG_MS(rx_status->rx_status_1, | ||
4267 | AR5K_5212_RX_DESC_STATUS1_KEY_INDEX); | ||
4268 | else | ||
4269 | rs->rs_keyix = AR5K_RXKEYIX_INVALID; | ||
4270 | |||
4271 | /* | ||
4272 | * Receive/descriptor errors | ||
4273 | */ | ||
4274 | if ((rx_status->rx_status_1 & | ||
4275 | AR5K_5212_RX_DESC_STATUS1_FRAME_RECEIVE_OK) == 0) { | ||
4276 | if (rx_status->rx_status_1 & | ||
4277 | AR5K_5212_RX_DESC_STATUS1_CRC_ERROR) | ||
4278 | rs->rs_status |= AR5K_RXERR_CRC; | ||
4279 | |||
4280 | if (rx_status->rx_status_1 & | ||
4281 | AR5K_5212_RX_DESC_STATUS1_PHY_ERROR) { | ||
4282 | rs->rs_status |= AR5K_RXERR_PHY; | ||
4283 | rs->rs_phyerr |= AR5K_REG_MS(rx_err->rx_error_1, | ||
4284 | AR5K_RX_DESC_ERROR1_PHY_ERROR_CODE); | ||
4285 | } | ||
4286 | |||
4287 | if (rx_status->rx_status_1 & | ||
4288 | AR5K_5212_RX_DESC_STATUS1_DECRYPT_CRC_ERROR) | ||
4289 | rs->rs_status |= AR5K_RXERR_DECRYPT; | ||
4290 | |||
4291 | if (rx_status->rx_status_1 & | ||
4292 | AR5K_5212_RX_DESC_STATUS1_MIC_ERROR) | ||
4293 | rs->rs_status |= AR5K_RXERR_MIC; | ||
4294 | } | ||
4295 | |||
4296 | return 0; | ||
4297 | } | ||
4298 | |||
4299 | |||
4300 | /****************\ | ||
4301 | GPIO Functions | ||
4302 | \****************/ | ||
4303 | |||
4304 | /* | ||
4305 | * Set led state | ||
4306 | */ | ||
4307 | void ath5k_hw_set_ledstate(struct ath5k_hw *ah, unsigned int state) | ||
4308 | { | ||
4309 | u32 led; | ||
4310 | /*5210 has different led mode handling*/ | ||
4311 | u32 led_5210; | ||
4312 | |||
4313 | ATH5K_TRACE(ah->ah_sc); | ||
4314 | |||
4315 | /*Reset led status*/ | ||
4316 | if (ah->ah_version != AR5K_AR5210) | ||
4317 | AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, | ||
4318 | AR5K_PCICFG_LEDMODE | AR5K_PCICFG_LED); | ||
4319 | else | ||
4320 | AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, AR5K_PCICFG_LED); | ||
4321 | |||
4322 | /* | ||
4323 | * Some blinking values, define at your wish | ||
4324 | */ | ||
4325 | switch (state) { | ||
4326 | case AR5K_LED_SCAN: | ||
4327 | case AR5K_LED_AUTH: | ||
4328 | led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_PEND; | ||
4329 | led_5210 = AR5K_PCICFG_LED_PEND | AR5K_PCICFG_LED_BCTL; | ||
4330 | break; | ||
4331 | |||
4332 | case AR5K_LED_INIT: | ||
4333 | led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_NONE; | ||
4334 | led_5210 = AR5K_PCICFG_LED_PEND; | ||
4335 | break; | ||
4336 | |||
4337 | case AR5K_LED_ASSOC: | ||
4338 | case AR5K_LED_RUN: | ||
4339 | led = AR5K_PCICFG_LEDMODE_PROP | AR5K_PCICFG_LED_ASSOC; | ||
4340 | led_5210 = AR5K_PCICFG_LED_ASSOC; | ||
4341 | break; | ||
4342 | |||
4343 | default: | ||
4344 | led = AR5K_PCICFG_LEDMODE_PROM | AR5K_PCICFG_LED_NONE; | ||
4345 | led_5210 = AR5K_PCICFG_LED_PEND; | ||
4346 | break; | ||
4347 | } | ||
4348 | |||
4349 | /*Write new status to the register*/ | ||
4350 | if (ah->ah_version != AR5K_AR5210) | ||
4351 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led); | ||
4352 | else | ||
4353 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, led_5210); | ||
4354 | } | ||
4355 | |||
4356 | /* | ||
4357 | * Set GPIO outputs | ||
4358 | */ | ||
4359 | int ath5k_hw_set_gpio_output(struct ath5k_hw *ah, u32 gpio) | ||
4360 | { | ||
4361 | ATH5K_TRACE(ah->ah_sc); | ||
4362 | if (gpio > AR5K_NUM_GPIO) | ||
4363 | return -EINVAL; | ||
4364 | |||
4365 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~ | ||
4366 | AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_OUT(gpio), AR5K_GPIOCR); | ||
4367 | |||
4368 | return 0; | ||
4369 | } | ||
4370 | |||
4371 | /* | ||
4372 | * Set GPIO inputs | ||
4373 | */ | ||
4374 | int ath5k_hw_set_gpio_input(struct ath5k_hw *ah, u32 gpio) | ||
4375 | { | ||
4376 | ATH5K_TRACE(ah->ah_sc); | ||
4377 | if (gpio > AR5K_NUM_GPIO) | ||
4378 | return -EINVAL; | ||
4379 | |||
4380 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_GPIOCR) &~ | ||
4381 | AR5K_GPIOCR_OUT(gpio)) | AR5K_GPIOCR_IN(gpio), AR5K_GPIOCR); | ||
4382 | |||
4383 | return 0; | ||
4384 | } | ||
4385 | |||
4386 | /* | ||
4387 | * Get GPIO state | ||
4388 | */ | ||
4389 | u32 ath5k_hw_get_gpio(struct ath5k_hw *ah, u32 gpio) | ||
4390 | { | ||
4391 | ATH5K_TRACE(ah->ah_sc); | ||
4392 | if (gpio > AR5K_NUM_GPIO) | ||
4393 | return 0xffffffff; | ||
4394 | |||
4395 | /* GPIO input magic */ | ||
4396 | return ((ath5k_hw_reg_read(ah, AR5K_GPIODI) & AR5K_GPIODI_M) >> gpio) & | ||
4397 | 0x1; | ||
4398 | } | ||
4399 | |||
4400 | /* | ||
4401 | * Set GPIO state | ||
4402 | */ | ||
4403 | int ath5k_hw_set_gpio(struct ath5k_hw *ah, u32 gpio, u32 val) | ||
4404 | { | ||
4405 | u32 data; | ||
4406 | ATH5K_TRACE(ah->ah_sc); | ||
4407 | |||
4408 | if (gpio > AR5K_NUM_GPIO) | ||
4409 | return -EINVAL; | ||
4410 | |||
4411 | /* GPIO output magic */ | ||
4412 | data = ath5k_hw_reg_read(ah, AR5K_GPIODO); | ||
4413 | |||
4414 | data &= ~(1 << gpio); | ||
4415 | data |= (val & 1) << gpio; | ||
4416 | |||
4417 | ath5k_hw_reg_write(ah, data, AR5K_GPIODO); | ||
4418 | |||
4419 | return 0; | ||
4420 | } | ||
4421 | |||
4422 | /* | ||
4423 | * Initialize the GPIO interrupt (RFKill switch) | ||
4424 | */ | ||
4425 | void ath5k_hw_set_gpio_intr(struct ath5k_hw *ah, unsigned int gpio, | ||
4426 | u32 interrupt_level) | ||
4427 | { | ||
4428 | u32 data; | ||
4429 | |||
4430 | ATH5K_TRACE(ah->ah_sc); | ||
4431 | if (gpio > AR5K_NUM_GPIO) | ||
4432 | return; | ||
4433 | |||
4434 | /* | ||
4435 | * Set the GPIO interrupt | ||
4436 | */ | ||
4437 | data = (ath5k_hw_reg_read(ah, AR5K_GPIOCR) & | ||
4438 | ~(AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_SELH | | ||
4439 | AR5K_GPIOCR_INT_ENA | AR5K_GPIOCR_OUT(gpio))) | | ||
4440 | (AR5K_GPIOCR_INT_SEL(gpio) | AR5K_GPIOCR_INT_ENA); | ||
4441 | |||
4442 | ath5k_hw_reg_write(ah, interrupt_level ? data : | ||
4443 | (data | AR5K_GPIOCR_INT_SELH), AR5K_GPIOCR); | ||
4444 | |||
4445 | ah->ah_imr |= AR5K_IMR_GPIO; | ||
4446 | |||
4447 | /* Enable GPIO interrupts */ | ||
4448 | AR5K_REG_ENABLE_BITS(ah, AR5K_PIMR, AR5K_IMR_GPIO); | ||
4449 | } | ||
4450 | |||
4451 | |||
4452 | |||
4453 | |||
4454 | /****************\ | ||
4455 | Misc functions | ||
4456 | \****************/ | ||
4457 | |||
4458 | int ath5k_hw_get_capability(struct ath5k_hw *ah, | ||
4459 | enum ath5k_capability_type cap_type, | ||
4460 | u32 capability, u32 *result) | ||
4461 | { | ||
4462 | ATH5K_TRACE(ah->ah_sc); | ||
4463 | |||
4464 | switch (cap_type) { | ||
4465 | case AR5K_CAP_NUM_TXQUEUES: | ||
4466 | if (result) { | ||
4467 | if (ah->ah_version == AR5K_AR5210) | ||
4468 | *result = AR5K_NUM_TX_QUEUES_NOQCU; | ||
4469 | else | ||
4470 | *result = AR5K_NUM_TX_QUEUES; | ||
4471 | goto yes; | ||
4472 | } | ||
4473 | case AR5K_CAP_VEOL: | ||
4474 | goto yes; | ||
4475 | case AR5K_CAP_COMPRESSION: | ||
4476 | if (ah->ah_version == AR5K_AR5212) | ||
4477 | goto yes; | ||
4478 | else | ||
4479 | goto no; | ||
4480 | case AR5K_CAP_BURST: | ||
4481 | goto yes; | ||
4482 | case AR5K_CAP_TPC: | ||
4483 | goto yes; | ||
4484 | case AR5K_CAP_BSSIDMASK: | ||
4485 | if (ah->ah_version == AR5K_AR5212) | ||
4486 | goto yes; | ||
4487 | else | ||
4488 | goto no; | ||
4489 | case AR5K_CAP_XR: | ||
4490 | if (ah->ah_version == AR5K_AR5212) | ||
4491 | goto yes; | ||
4492 | else | ||
4493 | goto no; | ||
4494 | default: | ||
4495 | goto no; | ||
4496 | } | ||
4497 | |||
4498 | no: | ||
4499 | return -EINVAL; | ||
4500 | yes: | ||
4501 | return 0; | ||
4502 | } | ||
4503 | |||
4504 | static int ath5k_hw_enable_pspoll(struct ath5k_hw *ah, u8 *bssid, | ||
4505 | u16 assoc_id) | ||
4506 | { | ||
4507 | ATH5K_TRACE(ah->ah_sc); | ||
4508 | |||
4509 | if (ah->ah_version == AR5K_AR5210) { | ||
4510 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
4511 | AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); | ||
4512 | return 0; | ||
4513 | } | ||
4514 | |||
4515 | return -EIO; | ||
4516 | } | ||
4517 | |||
4518 | static int ath5k_hw_disable_pspoll(struct ath5k_hw *ah) | ||
4519 | { | ||
4520 | ATH5K_TRACE(ah->ah_sc); | ||
4521 | |||
4522 | if (ah->ah_version == AR5K_AR5210) { | ||
4523 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, | ||
4524 | AR5K_STA_ID1_NO_PSPOLL | AR5K_STA_ID1_DEFAULT_ANTENNA); | ||
4525 | return 0; | ||
4526 | } | ||
4527 | |||
4528 | return -EIO; | ||
4529 | } | ||
diff --git a/drivers/net/wireless/ath5k/initvals.c b/drivers/net/wireless/ath5k/initvals.c index 2806b21bf90b..ea2e1a20b499 100644 --- a/drivers/net/wireless/ath5k/initvals.c +++ b/drivers/net/wireless/ath5k/initvals.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * Initial register settings functions | 2 | * Initial register settings functions |
3 | * | 3 | * |
4 | * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> | 4 | * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> |
5 | * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com> | 5 | * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com> |
6 | * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> | 6 | * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> |
7 | * | 7 | * |
8 | * Permission to use, copy, modify, and distribute this software for any | 8 | * Permission to use, copy, modify, and distribute this software for any |
9 | * purpose with or without fee is hereby granted, provided that the above | 9 | * purpose with or without fee is hereby granted, provided that the above |
@@ -20,13 +20,9 @@ | |||
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include "ath5k.h" | 22 | #include "ath5k.h" |
23 | #include "base.h" | ||
24 | #include "reg.h" | 23 | #include "reg.h" |
25 | 24 | #include "debug.h" | |
26 | /* | 25 | #include "base.h" |
27 | * MAC/PHY REGISTERS | ||
28 | */ | ||
29 | |||
30 | 26 | ||
31 | /* | 27 | /* |
32 | * Mode-independent initial register writes | 28 | * Mode-independent initial register writes |
@@ -65,10 +61,10 @@ static const struct ath5k_ini ar5210_ini[] = { | |||
65 | { AR5K_TXCFG, AR5K_DMASIZE_128B }, | 61 | { AR5K_TXCFG, AR5K_DMASIZE_128B }, |
66 | { AR5K_RXCFG, AR5K_DMASIZE_128B }, | 62 | { AR5K_RXCFG, AR5K_DMASIZE_128B }, |
67 | { AR5K_CFG, AR5K_INIT_CFG }, | 63 | { AR5K_CFG, AR5K_INIT_CFG }, |
68 | { AR5K_TOPS, AR5K_INIT_TOPS }, | 64 | { AR5K_TOPS, 8 }, |
69 | { AR5K_RXNOFRM, AR5K_INIT_RXNOFRM }, | 65 | { AR5K_RXNOFRM, 8 }, |
70 | { AR5K_RPGTO, AR5K_INIT_RPGTO }, | 66 | { AR5K_RPGTO, 0 }, |
71 | { AR5K_TXNOFRM, AR5K_INIT_TXNOFRM }, | 67 | { AR5K_TXNOFRM, 0 }, |
72 | { AR5K_SFR, 0 }, | 68 | { AR5K_SFR, 0 }, |
73 | { AR5K_MIBC, 0 }, | 69 | { AR5K_MIBC, 0 }, |
74 | { AR5K_MISC, 0 }, | 70 | { AR5K_MISC, 0 }, |
diff --git a/drivers/net/wireless/ath5k/pcu.c b/drivers/net/wireless/ath5k/pcu.c new file mode 100644 index 000000000000..a47df9a24aa1 --- /dev/null +++ b/drivers/net/wireless/ath5k/pcu.c | |||
@@ -0,0 +1,1014 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * Copyright (c) 2007-2008 Matthew W. S. Bell <mentor@madwifi.org> | ||
5 | * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu> | ||
6 | * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org> | ||
7 | * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> | ||
8 | * | ||
9 | * Permission to use, copy, modify, and distribute this software for any | ||
10 | * purpose with or without fee is hereby granted, provided that the above | ||
11 | * copyright notice and this permission notice appear in all copies. | ||
12 | * | ||
13 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
14 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
15 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
16 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
17 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
18 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
19 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
20 | * | ||
21 | */ | ||
22 | |||
23 | /*********************************\ | ||
24 | * Protocol Control Unit Functions * | ||
25 | \*********************************/ | ||
26 | |||
27 | #include "ath5k.h" | ||
28 | #include "reg.h" | ||
29 | #include "debug.h" | ||
30 | #include "base.h" | ||
31 | |||
32 | /*******************\ | ||
33 | * Generic functions * | ||
34 | \*******************/ | ||
35 | |||
36 | /** | ||
37 | * ath5k_hw_set_opmode - Set PCU operating mode | ||
38 | * | ||
39 | * @ah: The &struct ath5k_hw | ||
40 | * | ||
41 | * Initialize PCU for the various operating modes (AP/STA etc) | ||
42 | * | ||
43 | * NOTE: ah->ah_op_mode must be set before calling this. | ||
44 | */ | ||
45 | int ath5k_hw_set_opmode(struct ath5k_hw *ah) | ||
46 | { | ||
47 | u32 pcu_reg, beacon_reg, low_id, high_id; | ||
48 | |||
49 | pcu_reg = 0; | ||
50 | beacon_reg = 0; | ||
51 | |||
52 | ATH5K_TRACE(ah->ah_sc); | ||
53 | |||
54 | switch (ah->ah_op_mode) { | ||
55 | case NL80211_IFTYPE_ADHOC: | ||
56 | pcu_reg |= AR5K_STA_ID1_ADHOC | AR5K_STA_ID1_DESC_ANTENNA | | ||
57 | (ah->ah_version == AR5K_AR5210 ? | ||
58 | AR5K_STA_ID1_NO_PSPOLL : 0); | ||
59 | beacon_reg |= AR5K_BCR_ADHOC; | ||
60 | break; | ||
61 | |||
62 | case NL80211_IFTYPE_AP: | ||
63 | case NL80211_IFTYPE_MESH_POINT: | ||
64 | pcu_reg |= AR5K_STA_ID1_AP | AR5K_STA_ID1_RTS_DEF_ANTENNA | | ||
65 | (ah->ah_version == AR5K_AR5210 ? | ||
66 | AR5K_STA_ID1_NO_PSPOLL : 0); | ||
67 | beacon_reg |= AR5K_BCR_AP; | ||
68 | break; | ||
69 | |||
70 | case NL80211_IFTYPE_STATION: | ||
71 | pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
72 | (ah->ah_version == AR5K_AR5210 ? | ||
73 | AR5K_STA_ID1_PWR_SV : 0); | ||
74 | case NL80211_IFTYPE_MONITOR: | ||
75 | pcu_reg |= AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
76 | (ah->ah_version == AR5K_AR5210 ? | ||
77 | AR5K_STA_ID1_NO_PSPOLL : 0); | ||
78 | break; | ||
79 | |||
80 | default: | ||
81 | return -EINVAL; | ||
82 | } | ||
83 | |||
84 | /* | ||
85 | * Set PCU registers | ||
86 | */ | ||
87 | low_id = AR5K_LOW_ID(ah->ah_sta_id); | ||
88 | high_id = AR5K_HIGH_ID(ah->ah_sta_id); | ||
89 | ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); | ||
90 | ath5k_hw_reg_write(ah, pcu_reg | high_id, AR5K_STA_ID1); | ||
91 | |||
92 | /* | ||
93 | * Set Beacon Control Register on 5210 | ||
94 | */ | ||
95 | if (ah->ah_version == AR5K_AR5210) | ||
96 | ath5k_hw_reg_write(ah, beacon_reg, AR5K_BCR); | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | |||
101 | /** | ||
102 | * ath5k_hw_update - Update mib counters (mac layer statistics) | ||
103 | * | ||
104 | * @ah: The &struct ath5k_hw | ||
105 | * @stats: The &struct ieee80211_low_level_stats we use to track | ||
106 | * statistics on the driver | ||
107 | * | ||
108 | * Reads MIB counters from PCU and updates sw statistics. Must be | ||
109 | * called after a MIB interrupt. | ||
110 | */ | ||
111 | void ath5k_hw_update_mib_counters(struct ath5k_hw *ah, | ||
112 | struct ieee80211_low_level_stats *stats) | ||
113 | { | ||
114 | ATH5K_TRACE(ah->ah_sc); | ||
115 | |||
116 | /* Read-And-Clear */ | ||
117 | stats->dot11ACKFailureCount += ath5k_hw_reg_read(ah, AR5K_ACK_FAIL); | ||
118 | stats->dot11RTSFailureCount += ath5k_hw_reg_read(ah, AR5K_RTS_FAIL); | ||
119 | stats->dot11RTSSuccessCount += ath5k_hw_reg_read(ah, AR5K_RTS_OK); | ||
120 | stats->dot11FCSErrorCount += ath5k_hw_reg_read(ah, AR5K_FCS_FAIL); | ||
121 | |||
122 | /* XXX: Should we use this to track beacon count ? | ||
123 | * -we read it anyway to clear the register */ | ||
124 | ath5k_hw_reg_read(ah, AR5K_BEACON_CNT); | ||
125 | |||
126 | /* Reset profile count registers on 5212*/ | ||
127 | if (ah->ah_version == AR5K_AR5212) { | ||
128 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_TX); | ||
129 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RX); | ||
130 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_RXCLR); | ||
131 | ath5k_hw_reg_write(ah, 0, AR5K_PROFCNT_CYCLE); | ||
132 | } | ||
133 | } | ||
134 | |||
135 | /** | ||
136 | * ath5k_hw_set_ack_bitrate - set bitrate for ACKs | ||
137 | * | ||
138 | * @ah: The &struct ath5k_hw | ||
139 | * @high: Flag to determine if we want to use high transmition rate | ||
140 | * for ACKs or not | ||
141 | * | ||
142 | * If high flag is set, we tell hw to use a set of control rates based on | ||
143 | * the current transmition rate (check out control_rates array inside reset.c). | ||
144 | * If not hw just uses the lowest rate available for the current modulation | ||
145 | * scheme being used (1Mbit for CCK and 6Mbits for OFDM). | ||
146 | */ | ||
147 | void ath5k_hw_set_ack_bitrate_high(struct ath5k_hw *ah, bool high) | ||
148 | { | ||
149 | if (ah->ah_version != AR5K_AR5212) | ||
150 | return; | ||
151 | else { | ||
152 | u32 val = AR5K_STA_ID1_BASE_RATE_11B | AR5K_STA_ID1_ACKCTS_6MB; | ||
153 | if (high) | ||
154 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, val); | ||
155 | else | ||
156 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, val); | ||
157 | } | ||
158 | } | ||
159 | |||
160 | |||
161 | /******************\ | ||
162 | * ACK/CTS Timeouts * | ||
163 | \******************/ | ||
164 | |||
165 | /** | ||
166 | * ath5k_hw_het_ack_timeout - Get ACK timeout from PCU in usec | ||
167 | * | ||
168 | * @ah: The &struct ath5k_hw | ||
169 | */ | ||
170 | unsigned int ath5k_hw_get_ack_timeout(struct ath5k_hw *ah) | ||
171 | { | ||
172 | ATH5K_TRACE(ah->ah_sc); | ||
173 | |||
174 | return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, | ||
175 | AR5K_TIME_OUT), AR5K_TIME_OUT_ACK), ah->ah_turbo); | ||
176 | } | ||
177 | |||
178 | /** | ||
179 | * ath5k_hw_set_ack_timeout - Set ACK timeout on PCU | ||
180 | * | ||
181 | * @ah: The &struct ath5k_hw | ||
182 | * @timeout: Timeout in usec | ||
183 | */ | ||
184 | int ath5k_hw_set_ack_timeout(struct ath5k_hw *ah, unsigned int timeout) | ||
185 | { | ||
186 | ATH5K_TRACE(ah->ah_sc); | ||
187 | if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_ACK), | ||
188 | ah->ah_turbo) <= timeout) | ||
189 | return -EINVAL; | ||
190 | |||
191 | AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_ACK, | ||
192 | ath5k_hw_htoclock(timeout, ah->ah_turbo)); | ||
193 | |||
194 | return 0; | ||
195 | } | ||
196 | |||
197 | /** | ||
198 | * ath5k_hw_get_cts_timeout - Get CTS timeout from PCU in usec | ||
199 | * | ||
200 | * @ah: The &struct ath5k_hw | ||
201 | */ | ||
202 | unsigned int ath5k_hw_get_cts_timeout(struct ath5k_hw *ah) | ||
203 | { | ||
204 | ATH5K_TRACE(ah->ah_sc); | ||
205 | return ath5k_hw_clocktoh(AR5K_REG_MS(ath5k_hw_reg_read(ah, | ||
206 | AR5K_TIME_OUT), AR5K_TIME_OUT_CTS), ah->ah_turbo); | ||
207 | } | ||
208 | |||
209 | /** | ||
210 | * ath5k_hw_set_cts_timeout - Set CTS timeout on PCU | ||
211 | * | ||
212 | * @ah: The &struct ath5k_hw | ||
213 | * @timeout: Timeout in usec | ||
214 | */ | ||
215 | int ath5k_hw_set_cts_timeout(struct ath5k_hw *ah, unsigned int timeout) | ||
216 | { | ||
217 | ATH5K_TRACE(ah->ah_sc); | ||
218 | if (ath5k_hw_clocktoh(AR5K_REG_MS(0xffffffff, AR5K_TIME_OUT_CTS), | ||
219 | ah->ah_turbo) <= timeout) | ||
220 | return -EINVAL; | ||
221 | |||
222 | AR5K_REG_WRITE_BITS(ah, AR5K_TIME_OUT, AR5K_TIME_OUT_CTS, | ||
223 | ath5k_hw_htoclock(timeout, ah->ah_turbo)); | ||
224 | |||
225 | return 0; | ||
226 | } | ||
227 | |||
228 | |||
229 | /****************\ | ||
230 | * BSSID handling * | ||
231 | \****************/ | ||
232 | |||
233 | /** | ||
234 | * ath5k_hw_get_lladdr - Get station id | ||
235 | * | ||
236 | * @ah: The &struct ath5k_hw | ||
237 | * @mac: The card's mac address | ||
238 | * | ||
239 | * Initialize ah->ah_sta_id using the mac address provided | ||
240 | * (just a memcpy). | ||
241 | * | ||
242 | * TODO: Remove it once we merge ath5k_softc and ath5k_hw | ||
243 | */ | ||
244 | void ath5k_hw_get_lladdr(struct ath5k_hw *ah, u8 *mac) | ||
245 | { | ||
246 | ATH5K_TRACE(ah->ah_sc); | ||
247 | memcpy(mac, ah->ah_sta_id, ETH_ALEN); | ||
248 | } | ||
249 | |||
250 | /** | ||
251 | * ath5k_hw_set_lladdr - Set station id | ||
252 | * | ||
253 | * @ah: The &struct ath5k_hw | ||
254 | * @mac: The card's mac address | ||
255 | * | ||
256 | * Set station id on hw using the provided mac address | ||
257 | */ | ||
258 | int ath5k_hw_set_lladdr(struct ath5k_hw *ah, const u8 *mac) | ||
259 | { | ||
260 | u32 low_id, high_id; | ||
261 | |||
262 | ATH5K_TRACE(ah->ah_sc); | ||
263 | /* Set new station ID */ | ||
264 | memcpy(ah->ah_sta_id, mac, ETH_ALEN); | ||
265 | |||
266 | low_id = AR5K_LOW_ID(mac); | ||
267 | high_id = AR5K_HIGH_ID(mac); | ||
268 | |||
269 | ath5k_hw_reg_write(ah, low_id, AR5K_STA_ID0); | ||
270 | ath5k_hw_reg_write(ah, high_id, AR5K_STA_ID1); | ||
271 | |||
272 | return 0; | ||
273 | } | ||
274 | |||
275 | /** | ||
276 | * ath5k_hw_set_associd - Set BSSID for association | ||
277 | * | ||
278 | * @ah: The &struct ath5k_hw | ||
279 | * @bssid: BSSID | ||
280 | * @assoc_id: Assoc id | ||
281 | * | ||
282 | * Sets the BSSID which trigers the "SME Join" operation | ||
283 | */ | ||
284 | void ath5k_hw_set_associd(struct ath5k_hw *ah, const u8 *bssid, u16 assoc_id) | ||
285 | { | ||
286 | u32 low_id, high_id; | ||
287 | u16 tim_offset = 0; | ||
288 | |||
289 | /* | ||
290 | * Set simple BSSID mask on 5212 | ||
291 | */ | ||
292 | if (ah->ah_version == AR5K_AR5212) { | ||
293 | ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM0); | ||
294 | ath5k_hw_reg_write(ah, 0xffffffff, AR5K_BSS_IDM1); | ||
295 | } | ||
296 | |||
297 | /* | ||
298 | * Set BSSID which triggers the "SME Join" operation | ||
299 | */ | ||
300 | low_id = AR5K_LOW_ID(bssid); | ||
301 | high_id = AR5K_HIGH_ID(bssid); | ||
302 | ath5k_hw_reg_write(ah, low_id, AR5K_BSS_ID0); | ||
303 | ath5k_hw_reg_write(ah, high_id | ((assoc_id & 0x3fff) << | ||
304 | AR5K_BSS_ID1_AID_S), AR5K_BSS_ID1); | ||
305 | |||
306 | if (assoc_id == 0) { | ||
307 | ath5k_hw_disable_pspoll(ah); | ||
308 | return; | ||
309 | } | ||
310 | |||
311 | AR5K_REG_WRITE_BITS(ah, AR5K_BEACON, AR5K_BEACON_TIM, | ||
312 | tim_offset ? tim_offset + 4 : 0); | ||
313 | |||
314 | ath5k_hw_enable_pspoll(ah, NULL, 0); | ||
315 | } | ||
316 | |||
317 | /** | ||
318 | * ath5k_hw_set_bssid_mask - filter out bssids we listen | ||
319 | * | ||
320 | * @ah: the &struct ath5k_hw | ||
321 | * @mask: the bssid_mask, a u8 array of size ETH_ALEN | ||
322 | * | ||
323 | * BSSID masking is a method used by AR5212 and newer hardware to inform PCU | ||
324 | * which bits of the interface's MAC address should be looked at when trying | ||
325 | * to decide which packets to ACK. In station mode and AP mode with a single | ||
326 | * BSS every bit matters since we lock to only one BSS. In AP mode with | ||
327 | * multiple BSSes (virtual interfaces) not every bit matters because hw must | ||
328 | * accept frames for all BSSes and so we tweak some bits of our mac address | ||
329 | * in order to have multiple BSSes. | ||
330 | * | ||
331 | * NOTE: This is a simple filter and does *not* filter out all | ||
332 | * relevant frames. Some frames that are not for us might get ACKed from us | ||
333 | * by PCU because they just match the mask. | ||
334 | * | ||
335 | * When handling multiple BSSes you can get the BSSID mask by computing the | ||
336 | * set of ~ ( MAC XOR BSSID ) for all bssids we handle. | ||
337 | * | ||
338 | * When you do this you are essentially computing the common bits of all your | ||
339 | * BSSes. Later it is assumed the harware will "and" (&) the BSSID mask with | ||
340 | * the MAC address to obtain the relevant bits and compare the result with | ||
341 | * (frame's BSSID & mask) to see if they match. | ||
342 | */ | ||
343 | /* | ||
344 | * Simple example: on your card you have have two BSSes you have created with | ||
345 | * BSSID-01 and BSSID-02. Lets assume BSSID-01 will not use the MAC address. | ||
346 | * There is another BSSID-03 but you are not part of it. For simplicity's sake, | ||
347 | * assuming only 4 bits for a mac address and for BSSIDs you can then have: | ||
348 | * | ||
349 | * \ | ||
350 | * MAC: 0001 | | ||
351 | * BSSID-01: 0100 | --> Belongs to us | ||
352 | * BSSID-02: 1001 | | ||
353 | * / | ||
354 | * ------------------- | ||
355 | * BSSID-03: 0110 | --> External | ||
356 | * ------------------- | ||
357 | * | ||
358 | * Our bssid_mask would then be: | ||
359 | * | ||
360 | * On loop iteration for BSSID-01: | ||
361 | * ~(0001 ^ 0100) -> ~(0101) | ||
362 | * -> 1010 | ||
363 | * bssid_mask = 1010 | ||
364 | * | ||
365 | * On loop iteration for BSSID-02: | ||
366 | * bssid_mask &= ~(0001 ^ 1001) | ||
367 | * bssid_mask = (1010) & ~(0001 ^ 1001) | ||
368 | * bssid_mask = (1010) & ~(1001) | ||
369 | * bssid_mask = (1010) & (0110) | ||
370 | * bssid_mask = 0010 | ||
371 | * | ||
372 | * A bssid_mask of 0010 means "only pay attention to the second least | ||
373 | * significant bit". This is because its the only bit common | ||
374 | * amongst the MAC and all BSSIDs we support. To findout what the real | ||
375 | * common bit is we can simply "&" the bssid_mask now with any BSSID we have | ||
376 | * or our MAC address (we assume the hardware uses the MAC address). | ||
377 | * | ||
378 | * Now, suppose there's an incoming frame for BSSID-03: | ||
379 | * | ||
380 | * IFRAME-01: 0110 | ||
381 | * | ||
382 | * An easy eye-inspeciton of this already should tell you that this frame | ||
383 | * will not pass our check. This is beacuse the bssid_mask tells the | ||
384 | * hardware to only look at the second least significant bit and the | ||
385 | * common bit amongst the MAC and BSSIDs is 0, this frame has the 2nd LSB | ||
386 | * as 1, which does not match 0. | ||
387 | * | ||
388 | * So with IFRAME-01 we *assume* the hardware will do: | ||
389 | * | ||
390 | * allow = (IFRAME-01 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; | ||
391 | * --> allow = (0110 & 0010) == (0010 & 0001) ? 1 : 0; | ||
392 | * --> allow = (0010) == 0000 ? 1 : 0; | ||
393 | * --> allow = 0 | ||
394 | * | ||
395 | * Lets now test a frame that should work: | ||
396 | * | ||
397 | * IFRAME-02: 0001 (we should allow) | ||
398 | * | ||
399 | * allow = (0001 & 1010) == 1010 | ||
400 | * | ||
401 | * allow = (IFRAME-02 & bssid_mask) == (bssid_mask & MAC) ? 1 : 0; | ||
402 | * --> allow = (0001 & 0010) == (0010 & 0001) ? 1 :0; | ||
403 | * --> allow = (0010) == (0010) | ||
404 | * --> allow = 1 | ||
405 | * | ||
406 | * Other examples: | ||
407 | * | ||
408 | * IFRAME-03: 0100 --> allowed | ||
409 | * IFRAME-04: 1001 --> allowed | ||
410 | * IFRAME-05: 1101 --> allowed but its not for us!!! | ||
411 | * | ||
412 | */ | ||
413 | int ath5k_hw_set_bssid_mask(struct ath5k_hw *ah, const u8 *mask) | ||
414 | { | ||
415 | u32 low_id, high_id; | ||
416 | ATH5K_TRACE(ah->ah_sc); | ||
417 | |||
418 | if (ah->ah_version == AR5K_AR5212) { | ||
419 | low_id = AR5K_LOW_ID(mask); | ||
420 | high_id = AR5K_HIGH_ID(mask); | ||
421 | |||
422 | ath5k_hw_reg_write(ah, low_id, AR5K_BSS_IDM0); | ||
423 | ath5k_hw_reg_write(ah, high_id, AR5K_BSS_IDM1); | ||
424 | |||
425 | return 0; | ||
426 | } | ||
427 | |||
428 | return -EIO; | ||
429 | } | ||
430 | |||
431 | |||
432 | /************\ | ||
433 | * RX Control * | ||
434 | \************/ | ||
435 | |||
436 | /** | ||
437 | * ath5k_hw_start_rx_pcu - Start RX engine | ||
438 | * | ||
439 | * @ah: The &struct ath5k_hw | ||
440 | * | ||
441 | * Starts RX engine on PCU so that hw can process RXed frames | ||
442 | * (ACK etc). | ||
443 | * | ||
444 | * NOTE: RX DMA should be already enabled using ath5k_hw_start_rx_dma | ||
445 | * TODO: Init ANI here | ||
446 | */ | ||
447 | void ath5k_hw_start_rx_pcu(struct ath5k_hw *ah) | ||
448 | { | ||
449 | ATH5K_TRACE(ah->ah_sc); | ||
450 | AR5K_REG_DISABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); | ||
451 | } | ||
452 | |||
453 | /** | ||
454 | * at5k_hw_stop_rx_pcu - Stop RX engine | ||
455 | * | ||
456 | * @ah: The &struct ath5k_hw | ||
457 | * | ||
458 | * Stops RX engine on PCU | ||
459 | * | ||
460 | * TODO: Detach ANI here | ||
461 | */ | ||
462 | void ath5k_hw_stop_rx_pcu(struct ath5k_hw *ah) | ||
463 | { | ||
464 | ATH5K_TRACE(ah->ah_sc); | ||
465 | AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW, AR5K_DIAG_SW_DIS_RX); | ||
466 | } | ||
467 | |||
468 | /* | ||
469 | * Set multicast filter | ||
470 | */ | ||
471 | void ath5k_hw_set_mcast_filter(struct ath5k_hw *ah, u32 filter0, u32 filter1) | ||
472 | { | ||
473 | ATH5K_TRACE(ah->ah_sc); | ||
474 | /* Set the multicat filter */ | ||
475 | ath5k_hw_reg_write(ah, filter0, AR5K_MCAST_FILTER0); | ||
476 | ath5k_hw_reg_write(ah, filter1, AR5K_MCAST_FILTER1); | ||
477 | } | ||
478 | |||
479 | /* | ||
480 | * Set multicast filter by index | ||
481 | */ | ||
482 | int ath5k_hw_set_mcast_filter_idx(struct ath5k_hw *ah, u32 index) | ||
483 | { | ||
484 | |||
485 | ATH5K_TRACE(ah->ah_sc); | ||
486 | if (index >= 64) | ||
487 | return -EINVAL; | ||
488 | else if (index >= 32) | ||
489 | AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER1, | ||
490 | (1 << (index - 32))); | ||
491 | else | ||
492 | AR5K_REG_ENABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index)); | ||
493 | |||
494 | return 0; | ||
495 | } | ||
496 | |||
497 | /* | ||
498 | * Clear Multicast filter by index | ||
499 | */ | ||
500 | int ath5k_hw_clear_mcast_filter_idx(struct ath5k_hw *ah, u32 index) | ||
501 | { | ||
502 | |||
503 | ATH5K_TRACE(ah->ah_sc); | ||
504 | if (index >= 64) | ||
505 | return -EINVAL; | ||
506 | else if (index >= 32) | ||
507 | AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER1, | ||
508 | (1 << (index - 32))); | ||
509 | else | ||
510 | AR5K_REG_DISABLE_BITS(ah, AR5K_MCAST_FILTER0, (1 << index)); | ||
511 | |||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | /** | ||
516 | * ath5k_hw_get_rx_filter - Get current rx filter | ||
517 | * | ||
518 | * @ah: The &struct ath5k_hw | ||
519 | * | ||
520 | * Returns the RX filter by reading rx filter and | ||
521 | * phy error filter registers. RX filter is used | ||
522 | * to set the allowed frame types that PCU will accept | ||
523 | * and pass to the driver. For a list of frame types | ||
524 | * check out reg.h. | ||
525 | */ | ||
526 | u32 ath5k_hw_get_rx_filter(struct ath5k_hw *ah) | ||
527 | { | ||
528 | u32 data, filter = 0; | ||
529 | |||
530 | ATH5K_TRACE(ah->ah_sc); | ||
531 | filter = ath5k_hw_reg_read(ah, AR5K_RX_FILTER); | ||
532 | |||
533 | /*Radar detection for 5212*/ | ||
534 | if (ah->ah_version == AR5K_AR5212) { | ||
535 | data = ath5k_hw_reg_read(ah, AR5K_PHY_ERR_FIL); | ||
536 | |||
537 | if (data & AR5K_PHY_ERR_FIL_RADAR) | ||
538 | filter |= AR5K_RX_FILTER_RADARERR; | ||
539 | if (data & (AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK)) | ||
540 | filter |= AR5K_RX_FILTER_PHYERR; | ||
541 | } | ||
542 | |||
543 | return filter; | ||
544 | } | ||
545 | |||
546 | /** | ||
547 | * ath5k_hw_set_rx_filter - Set rx filter | ||
548 | * | ||
549 | * @ah: The &struct ath5k_hw | ||
550 | * @filter: RX filter mask (see reg.h) | ||
551 | * | ||
552 | * Sets RX filter register and also handles PHY error filter | ||
553 | * register on 5212 and newer chips so that we have proper PHY | ||
554 | * error reporting. | ||
555 | */ | ||
556 | void ath5k_hw_set_rx_filter(struct ath5k_hw *ah, u32 filter) | ||
557 | { | ||
558 | u32 data = 0; | ||
559 | |||
560 | ATH5K_TRACE(ah->ah_sc); | ||
561 | |||
562 | /* Set PHY error filter register on 5212*/ | ||
563 | if (ah->ah_version == AR5K_AR5212) { | ||
564 | if (filter & AR5K_RX_FILTER_RADARERR) | ||
565 | data |= AR5K_PHY_ERR_FIL_RADAR; | ||
566 | if (filter & AR5K_RX_FILTER_PHYERR) | ||
567 | data |= AR5K_PHY_ERR_FIL_OFDM | AR5K_PHY_ERR_FIL_CCK; | ||
568 | } | ||
569 | |||
570 | /* | ||
571 | * The AR5210 uses promiscous mode to detect radar activity | ||
572 | */ | ||
573 | if (ah->ah_version == AR5K_AR5210 && | ||
574 | (filter & AR5K_RX_FILTER_RADARERR)) { | ||
575 | filter &= ~AR5K_RX_FILTER_RADARERR; | ||
576 | filter |= AR5K_RX_FILTER_PROM; | ||
577 | } | ||
578 | |||
579 | /*Zero length DMA*/ | ||
580 | if (data) | ||
581 | AR5K_REG_ENABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); | ||
582 | else | ||
583 | AR5K_REG_DISABLE_BITS(ah, AR5K_RXCFG, AR5K_RXCFG_ZLFDMA); | ||
584 | |||
585 | /*Write RX Filter register*/ | ||
586 | ath5k_hw_reg_write(ah, filter & 0xff, AR5K_RX_FILTER); | ||
587 | |||
588 | /*Write PHY error filter register on 5212*/ | ||
589 | if (ah->ah_version == AR5K_AR5212) | ||
590 | ath5k_hw_reg_write(ah, data, AR5K_PHY_ERR_FIL); | ||
591 | |||
592 | } | ||
593 | |||
594 | |||
595 | /****************\ | ||
596 | * Beacon control * | ||
597 | \****************/ | ||
598 | |||
599 | /** | ||
600 | * ath5k_hw_get_tsf32 - Get a 32bit TSF | ||
601 | * | ||
602 | * @ah: The &struct ath5k_hw | ||
603 | * | ||
604 | * Returns lower 32 bits of current TSF | ||
605 | */ | ||
606 | u32 ath5k_hw_get_tsf32(struct ath5k_hw *ah) | ||
607 | { | ||
608 | ATH5K_TRACE(ah->ah_sc); | ||
609 | return ath5k_hw_reg_read(ah, AR5K_TSF_L32); | ||
610 | } | ||
611 | |||
612 | /** | ||
613 | * ath5k_hw_get_tsf64 - Get the full 64bit TSF | ||
614 | * | ||
615 | * @ah: The &struct ath5k_hw | ||
616 | * | ||
617 | * Returns the current TSF | ||
618 | */ | ||
619 | u64 ath5k_hw_get_tsf64(struct ath5k_hw *ah) | ||
620 | { | ||
621 | u64 tsf = ath5k_hw_reg_read(ah, AR5K_TSF_U32); | ||
622 | ATH5K_TRACE(ah->ah_sc); | ||
623 | |||
624 | return ath5k_hw_reg_read(ah, AR5K_TSF_L32) | (tsf << 32); | ||
625 | } | ||
626 | |||
627 | /** | ||
628 | * ath5k_hw_reset_tsf - Force a TSF reset | ||
629 | * | ||
630 | * @ah: The &struct ath5k_hw | ||
631 | * | ||
632 | * Forces a TSF reset on PCU | ||
633 | */ | ||
634 | void ath5k_hw_reset_tsf(struct ath5k_hw *ah) | ||
635 | { | ||
636 | u32 val; | ||
637 | |||
638 | ATH5K_TRACE(ah->ah_sc); | ||
639 | |||
640 | val = ath5k_hw_reg_read(ah, AR5K_BEACON) | AR5K_BEACON_RESET_TSF; | ||
641 | |||
642 | /* | ||
643 | * Each write to the RESET_TSF bit toggles a hardware internal | ||
644 | * signal to reset TSF, but if left high it will cause a TSF reset | ||
645 | * on the next chip reset as well. Thus we always write the value | ||
646 | * twice to clear the signal. | ||
647 | */ | ||
648 | ath5k_hw_reg_write(ah, val, AR5K_BEACON); | ||
649 | ath5k_hw_reg_write(ah, val, AR5K_BEACON); | ||
650 | } | ||
651 | |||
652 | /* | ||
653 | * Initialize beacon timers | ||
654 | */ | ||
655 | void ath5k_hw_init_beacon(struct ath5k_hw *ah, u32 next_beacon, u32 interval) | ||
656 | { | ||
657 | u32 timer1, timer2, timer3; | ||
658 | |||
659 | ATH5K_TRACE(ah->ah_sc); | ||
660 | /* | ||
661 | * Set the additional timers by mode | ||
662 | */ | ||
663 | switch (ah->ah_op_mode) { | ||
664 | case NL80211_IFTYPE_STATION: | ||
665 | if (ah->ah_version == AR5K_AR5210) { | ||
666 | timer1 = 0xffffffff; | ||
667 | timer2 = 0xffffffff; | ||
668 | } else { | ||
669 | timer1 = 0x0000ffff; | ||
670 | timer2 = 0x0007ffff; | ||
671 | } | ||
672 | break; | ||
673 | |||
674 | default: | ||
675 | timer1 = (next_beacon - AR5K_TUNE_DMA_BEACON_RESP) << 3; | ||
676 | timer2 = (next_beacon - AR5K_TUNE_SW_BEACON_RESP) << 3; | ||
677 | } | ||
678 | |||
679 | timer3 = next_beacon + (ah->ah_atim_window ? ah->ah_atim_window : 1); | ||
680 | |||
681 | /* | ||
682 | * Set the beacon register and enable all timers. | ||
683 | * (next beacon, DMA beacon, software beacon, ATIM window time) | ||
684 | */ | ||
685 | ath5k_hw_reg_write(ah, next_beacon, AR5K_TIMER0); | ||
686 | ath5k_hw_reg_write(ah, timer1, AR5K_TIMER1); | ||
687 | ath5k_hw_reg_write(ah, timer2, AR5K_TIMER2); | ||
688 | ath5k_hw_reg_write(ah, timer3, AR5K_TIMER3); | ||
689 | |||
690 | ath5k_hw_reg_write(ah, interval & (AR5K_BEACON_PERIOD | | ||
691 | AR5K_BEACON_RESET_TSF | AR5K_BEACON_ENABLE), | ||
692 | AR5K_BEACON); | ||
693 | } | ||
694 | |||
695 | #if 0 | ||
696 | /* | ||
697 | * Set beacon timers | ||
698 | */ | ||
699 | int ath5k_hw_set_beacon_timers(struct ath5k_hw *ah, | ||
700 | const struct ath5k_beacon_state *state) | ||
701 | { | ||
702 | u32 cfp_period, next_cfp, dtim, interval, next_beacon; | ||
703 | |||
704 | /* | ||
705 | * TODO: should be changed through *state | ||
706 | * review struct ath5k_beacon_state struct | ||
707 | * | ||
708 | * XXX: These are used for cfp period bellow, are they | ||
709 | * ok ? Is it O.K. for tsf here to be 0 or should we use | ||
710 | * get_tsf ? | ||
711 | */ | ||
712 | u32 dtim_count = 0; /* XXX */ | ||
713 | u32 cfp_count = 0; /* XXX */ | ||
714 | u32 tsf = 0; /* XXX */ | ||
715 | |||
716 | ATH5K_TRACE(ah->ah_sc); | ||
717 | /* Return on an invalid beacon state */ | ||
718 | if (state->bs_interval < 1) | ||
719 | return -EINVAL; | ||
720 | |||
721 | interval = state->bs_interval; | ||
722 | dtim = state->bs_dtim_period; | ||
723 | |||
724 | /* | ||
725 | * PCF support? | ||
726 | */ | ||
727 | if (state->bs_cfp_period > 0) { | ||
728 | /* | ||
729 | * Enable PCF mode and set the CFP | ||
730 | * (Contention Free Period) and timer registers | ||
731 | */ | ||
732 | cfp_period = state->bs_cfp_period * state->bs_dtim_period * | ||
733 | state->bs_interval; | ||
734 | next_cfp = (cfp_count * state->bs_dtim_period + dtim_count) * | ||
735 | state->bs_interval; | ||
736 | |||
737 | AR5K_REG_ENABLE_BITS(ah, AR5K_STA_ID1, | ||
738 | AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
739 | AR5K_STA_ID1_PCF); | ||
740 | ath5k_hw_reg_write(ah, cfp_period, AR5K_CFP_PERIOD); | ||
741 | ath5k_hw_reg_write(ah, state->bs_cfp_max_duration, | ||
742 | AR5K_CFP_DUR); | ||
743 | ath5k_hw_reg_write(ah, (tsf + (next_cfp == 0 ? cfp_period : | ||
744 | next_cfp)) << 3, AR5K_TIMER2); | ||
745 | } else { | ||
746 | /* Disable PCF mode */ | ||
747 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
748 | AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
749 | AR5K_STA_ID1_PCF); | ||
750 | } | ||
751 | |||
752 | /* | ||
753 | * Enable the beacon timer register | ||
754 | */ | ||
755 | ath5k_hw_reg_write(ah, state->bs_next_beacon, AR5K_TIMER0); | ||
756 | |||
757 | /* | ||
758 | * Start the beacon timers | ||
759 | */ | ||
760 | ath5k_hw_reg_write(ah, (ath5k_hw_reg_read(ah, AR5K_BEACON) & | ||
761 | ~(AR5K_BEACON_PERIOD | AR5K_BEACON_TIM)) | | ||
762 | AR5K_REG_SM(state->bs_tim_offset ? state->bs_tim_offset + 4 : 0, | ||
763 | AR5K_BEACON_TIM) | AR5K_REG_SM(state->bs_interval, | ||
764 | AR5K_BEACON_PERIOD), AR5K_BEACON); | ||
765 | |||
766 | /* | ||
767 | * Write new beacon miss threshold, if it appears to be valid | ||
768 | * XXX: Figure out right values for min <= bs_bmiss_threshold <= max | ||
769 | * and return if its not in range. We can test this by reading value and | ||
770 | * setting value to a largest value and seeing which values register. | ||
771 | */ | ||
772 | |||
773 | AR5K_REG_WRITE_BITS(ah, AR5K_RSSI_THR, AR5K_RSSI_THR_BMISS, | ||
774 | state->bs_bmiss_threshold); | ||
775 | |||
776 | /* | ||
777 | * Set sleep control register | ||
778 | * XXX: Didn't find this in 5210 code but since this register | ||
779 | * exists also in ar5k's 5210 headers i leave it as common code. | ||
780 | */ | ||
781 | AR5K_REG_WRITE_BITS(ah, AR5K_SLEEP_CTL, AR5K_SLEEP_CTL_SLDUR, | ||
782 | (state->bs_sleep_duration - 3) << 3); | ||
783 | |||
784 | /* | ||
785 | * Set enhanced sleep registers on 5212 | ||
786 | */ | ||
787 | if (ah->ah_version == AR5K_AR5212) { | ||
788 | if (state->bs_sleep_duration > state->bs_interval && | ||
789 | roundup(state->bs_sleep_duration, interval) == | ||
790 | state->bs_sleep_duration) | ||
791 | interval = state->bs_sleep_duration; | ||
792 | |||
793 | if (state->bs_sleep_duration > dtim && (dtim == 0 || | ||
794 | roundup(state->bs_sleep_duration, dtim) == | ||
795 | state->bs_sleep_duration)) | ||
796 | dtim = state->bs_sleep_duration; | ||
797 | |||
798 | if (interval > dtim) | ||
799 | return -EINVAL; | ||
800 | |||
801 | next_beacon = interval == dtim ? state->bs_next_dtim : | ||
802 | state->bs_next_beacon; | ||
803 | |||
804 | ath5k_hw_reg_write(ah, | ||
805 | AR5K_REG_SM((state->bs_next_dtim - 3) << 3, | ||
806 | AR5K_SLEEP0_NEXT_DTIM) | | ||
807 | AR5K_REG_SM(10, AR5K_SLEEP0_CABTO) | | ||
808 | AR5K_SLEEP0_ENH_SLEEP_EN | | ||
809 | AR5K_SLEEP0_ASSUME_DTIM, AR5K_SLEEP0); | ||
810 | |||
811 | ath5k_hw_reg_write(ah, AR5K_REG_SM((next_beacon - 3) << 3, | ||
812 | AR5K_SLEEP1_NEXT_TIM) | | ||
813 | AR5K_REG_SM(10, AR5K_SLEEP1_BEACON_TO), AR5K_SLEEP1); | ||
814 | |||
815 | ath5k_hw_reg_write(ah, | ||
816 | AR5K_REG_SM(interval, AR5K_SLEEP2_TIM_PER) | | ||
817 | AR5K_REG_SM(dtim, AR5K_SLEEP2_DTIM_PER), AR5K_SLEEP2); | ||
818 | } | ||
819 | |||
820 | return 0; | ||
821 | } | ||
822 | |||
823 | /* | ||
824 | * Reset beacon timers | ||
825 | */ | ||
826 | void ath5k_hw_reset_beacon(struct ath5k_hw *ah) | ||
827 | { | ||
828 | ATH5K_TRACE(ah->ah_sc); | ||
829 | /* | ||
830 | * Disable beacon timer | ||
831 | */ | ||
832 | ath5k_hw_reg_write(ah, 0, AR5K_TIMER0); | ||
833 | |||
834 | /* | ||
835 | * Disable some beacon register values | ||
836 | */ | ||
837 | AR5K_REG_DISABLE_BITS(ah, AR5K_STA_ID1, | ||
838 | AR5K_STA_ID1_DEFAULT_ANTENNA | AR5K_STA_ID1_PCF); | ||
839 | ath5k_hw_reg_write(ah, AR5K_BEACON_PERIOD, AR5K_BEACON); | ||
840 | } | ||
841 | |||
842 | /* | ||
843 | * Wait for beacon queue to finish | ||
844 | */ | ||
845 | int ath5k_hw_beaconq_finish(struct ath5k_hw *ah, unsigned long phys_addr) | ||
846 | { | ||
847 | unsigned int i; | ||
848 | int ret; | ||
849 | |||
850 | ATH5K_TRACE(ah->ah_sc); | ||
851 | |||
852 | /* 5210 doesn't have QCU*/ | ||
853 | if (ah->ah_version == AR5K_AR5210) { | ||
854 | /* | ||
855 | * Wait for beaconn queue to finish by checking | ||
856 | * Control Register and Beacon Status Register. | ||
857 | */ | ||
858 | for (i = AR5K_TUNE_BEACON_INTERVAL / 2; i > 0; i--) { | ||
859 | if (!(ath5k_hw_reg_read(ah, AR5K_BSR) & AR5K_BSR_TXQ1F) | ||
860 | || | ||
861 | !(ath5k_hw_reg_read(ah, AR5K_CR) & AR5K_BSR_TXQ1F)) | ||
862 | break; | ||
863 | udelay(10); | ||
864 | } | ||
865 | |||
866 | /* Timeout... */ | ||
867 | if (i <= 0) { | ||
868 | /* | ||
869 | * Re-schedule the beacon queue | ||
870 | */ | ||
871 | ath5k_hw_reg_write(ah, phys_addr, AR5K_NOQCU_TXDP1); | ||
872 | ath5k_hw_reg_write(ah, AR5K_BCR_TQ1V | AR5K_BCR_BDMAE, | ||
873 | AR5K_BCR); | ||
874 | |||
875 | return -EIO; | ||
876 | } | ||
877 | ret = 0; | ||
878 | } else { | ||
879 | /*5211/5212*/ | ||
880 | ret = ath5k_hw_register_timeout(ah, | ||
881 | AR5K_QUEUE_STATUS(AR5K_TX_QUEUE_ID_BEACON), | ||
882 | AR5K_QCU_STS_FRMPENDCNT, 0, false); | ||
883 | |||
884 | if (AR5K_REG_READ_Q(ah, AR5K_QCU_TXE, AR5K_TX_QUEUE_ID_BEACON)) | ||
885 | return -EIO; | ||
886 | } | ||
887 | |||
888 | return ret; | ||
889 | } | ||
890 | #endif | ||
891 | |||
892 | |||
893 | /*********************\ | ||
894 | * Key table functions * | ||
895 | \*********************/ | ||
896 | |||
897 | /* | ||
898 | * Reset a key entry on the table | ||
899 | */ | ||
900 | int ath5k_hw_reset_key(struct ath5k_hw *ah, u16 entry) | ||
901 | { | ||
902 | unsigned int i; | ||
903 | |||
904 | ATH5K_TRACE(ah->ah_sc); | ||
905 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
906 | |||
907 | for (i = 0; i < AR5K_KEYCACHE_SIZE; i++) | ||
908 | ath5k_hw_reg_write(ah, 0, AR5K_KEYTABLE_OFF(entry, i)); | ||
909 | |||
910 | /* | ||
911 | * Set NULL encryption on AR5212+ | ||
912 | * | ||
913 | * Note: AR5K_KEYTABLE_TYPE -> AR5K_KEYTABLE_OFF(entry, 5) | ||
914 | * AR5K_KEYTABLE_TYPE_NULL -> 0x00000007 | ||
915 | * | ||
916 | * Note2: Windows driver (ndiswrapper) sets this to | ||
917 | * 0x00000714 instead of 0x00000007 | ||
918 | */ | ||
919 | if (ah->ah_version > AR5K_AR5211) | ||
920 | ath5k_hw_reg_write(ah, AR5K_KEYTABLE_TYPE_NULL, | ||
921 | AR5K_KEYTABLE_TYPE(entry)); | ||
922 | |||
923 | return 0; | ||
924 | } | ||
925 | |||
926 | /* | ||
927 | * Check if a table entry is valid | ||
928 | */ | ||
929 | int ath5k_hw_is_key_valid(struct ath5k_hw *ah, u16 entry) | ||
930 | { | ||
931 | ATH5K_TRACE(ah->ah_sc); | ||
932 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
933 | |||
934 | /* Check the validation flag at the end of the entry */ | ||
935 | return ath5k_hw_reg_read(ah, AR5K_KEYTABLE_MAC1(entry)) & | ||
936 | AR5K_KEYTABLE_VALID; | ||
937 | } | ||
938 | |||
939 | /* | ||
940 | * Set a key entry on the table | ||
941 | */ | ||
942 | int ath5k_hw_set_key(struct ath5k_hw *ah, u16 entry, | ||
943 | const struct ieee80211_key_conf *key, const u8 *mac) | ||
944 | { | ||
945 | unsigned int i; | ||
946 | __le32 key_v[5] = {}; | ||
947 | u32 keytype; | ||
948 | |||
949 | ATH5K_TRACE(ah->ah_sc); | ||
950 | |||
951 | /* key->keylen comes in from mac80211 in bytes */ | ||
952 | |||
953 | if (key->keylen > AR5K_KEYTABLE_SIZE / 8) | ||
954 | return -EOPNOTSUPP; | ||
955 | |||
956 | switch (key->keylen) { | ||
957 | /* WEP 40-bit = 40-bit entered key + 24 bit IV = 64-bit */ | ||
958 | case 40 / 8: | ||
959 | memcpy(&key_v[0], key->key, 5); | ||
960 | keytype = AR5K_KEYTABLE_TYPE_40; | ||
961 | break; | ||
962 | |||
963 | /* WEP 104-bit = 104-bit entered key + 24-bit IV = 128-bit */ | ||
964 | case 104 / 8: | ||
965 | memcpy(&key_v[0], &key->key[0], 6); | ||
966 | memcpy(&key_v[2], &key->key[6], 6); | ||
967 | memcpy(&key_v[4], &key->key[12], 1); | ||
968 | keytype = AR5K_KEYTABLE_TYPE_104; | ||
969 | break; | ||
970 | /* WEP 128-bit = 128-bit entered key + 24 bit IV = 152-bit */ | ||
971 | case 128 / 8: | ||
972 | memcpy(&key_v[0], &key->key[0], 6); | ||
973 | memcpy(&key_v[2], &key->key[6], 6); | ||
974 | memcpy(&key_v[4], &key->key[12], 4); | ||
975 | keytype = AR5K_KEYTABLE_TYPE_128; | ||
976 | break; | ||
977 | |||
978 | default: | ||
979 | return -EINVAL; /* shouldn't happen */ | ||
980 | } | ||
981 | |||
982 | for (i = 0; i < ARRAY_SIZE(key_v); i++) | ||
983 | ath5k_hw_reg_write(ah, le32_to_cpu(key_v[i]), | ||
984 | AR5K_KEYTABLE_OFF(entry, i)); | ||
985 | |||
986 | ath5k_hw_reg_write(ah, keytype, AR5K_KEYTABLE_TYPE(entry)); | ||
987 | |||
988 | return ath5k_hw_set_key_lladdr(ah, entry, mac); | ||
989 | } | ||
990 | |||
991 | int ath5k_hw_set_key_lladdr(struct ath5k_hw *ah, u16 entry, const u8 *mac) | ||
992 | { | ||
993 | u32 low_id, high_id; | ||
994 | |||
995 | ATH5K_TRACE(ah->ah_sc); | ||
996 | /* Invalid entry (key table overflow) */ | ||
997 | AR5K_ASSERT_ENTRY(entry, AR5K_KEYTABLE_SIZE); | ||
998 | |||
999 | /* MAC may be NULL if it's a broadcast key. In this case no need to | ||
1000 | * to compute AR5K_LOW_ID and AR5K_HIGH_ID as we already know it. */ | ||
1001 | if (unlikely(mac == NULL)) { | ||
1002 | low_id = 0xffffffff; | ||
1003 | high_id = 0xffff | AR5K_KEYTABLE_VALID; | ||
1004 | } else { | ||
1005 | low_id = AR5K_LOW_ID(mac); | ||
1006 | high_id = AR5K_HIGH_ID(mac) | AR5K_KEYTABLE_VALID; | ||
1007 | } | ||
1008 | |||
1009 | ath5k_hw_reg_write(ah, low_id, AR5K_KEYTABLE_MAC0(entry)); | ||
1010 | ath5k_hw_reg_write(ah, high_id, AR5K_KEYTABLE_MAC1(entry)); | ||
1011 | |||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c index fa0d47faf574..e43f6563e61a 100644 --- a/drivers/net/wireless/ath5k/phy.c +++ b/drivers/net/wireless/ath5k/phy.c | |||
@@ -1,9 +1,9 @@ | |||
1 | /* | 1 | /* |
2 | * PHY functions | 2 | * PHY functions |
3 | * | 3 | * |
4 | * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> | 4 | * Copyright (c) 2004-2007 Reyk Floeter <reyk@openbsd.org> |
5 | * Copyright (c) 2006, 2007 Nick Kossifidis <mickflemm@gmail.com> | 5 | * Copyright (c) 2006-2007 Nick Kossifidis <mickflemm@gmail.com> |
6 | * Copyright (c) 2007 Jiri Slaby <jirislaby@gmail.com> | 6 | * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> |
7 | * | 7 | * |
8 | * Permission to use, copy, modify, and distribute this software for any | 8 | * Permission to use, copy, modify, and distribute this software for any |
9 | * purpose with or without fee is hereby granted, provided that the above | 9 | * purpose with or without fee is hereby granted, provided that the above |
@@ -19,6 +19,8 @@ | |||
19 | * | 19 | * |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #define _ATH5K_PHY | ||
23 | |||
22 | #include <linux/delay.h> | 24 | #include <linux/delay.h> |
23 | 25 | ||
24 | #include "ath5k.h" | 26 | #include "ath5k.h" |
@@ -2122,7 +2124,7 @@ static int ath5k_hw_rf5110_calibrate(struct ath5k_hw *ah, | |||
2122 | beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); | 2124 | beacon = ath5k_hw_reg_read(ah, AR5K_BEACON_5210); |
2123 | ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); | 2125 | ath5k_hw_reg_write(ah, beacon & ~AR5K_BEACON_ENABLE, AR5K_BEACON_5210); |
2124 | 2126 | ||
2125 | udelay(2300); | 2127 | mdelay(2); |
2126 | 2128 | ||
2127 | /* | 2129 | /* |
2128 | * Set the channel (with AGC turned off) | 2130 | * Set the channel (with AGC turned off) |
@@ -2501,3 +2503,5 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, unsigned int power) | |||
2501 | 2503 | ||
2502 | return ath5k_hw_txpower(ah, channel, power); | 2504 | return ath5k_hw_txpower(ah, channel, power); |
2503 | } | 2505 | } |
2506 | |||
2507 | #undef _ATH5K_PHY | ||
diff --git a/drivers/net/wireless/ath5k/qcu.c b/drivers/net/wireless/ath5k/qcu.c new file mode 100644 index 000000000000..01bf09176d23 --- /dev/null +++ b/drivers/net/wireless/ath5k/qcu.c | |||
@@ -0,0 +1,488 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * | ||
5 | * Permission to use, copy, modify, and distribute this software for any | ||
6 | * purpose with or without fee is hereby granted, provided that the above | ||
7 | * copyright notice and this permission notice appear in all copies. | ||
8 | * | ||
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
15 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | /********************************************\ | ||
20 | Queue Control Unit, DFS Control Unit Functions | ||
21 | \********************************************/ | ||
22 | |||
23 | #include "ath5k.h" | ||
24 | #include "reg.h" | ||
25 | #include "debug.h" | ||
26 | #include "base.h" | ||
27 | |||
28 | /* | ||
29 | * Get properties for a transmit queue | ||
30 | */ | ||
31 | int ath5k_hw_get_tx_queueprops(struct ath5k_hw *ah, int queue, | ||
32 | struct ath5k_txq_info *queue_info) | ||
33 | { | ||
34 | ATH5K_TRACE(ah->ah_sc); | ||
35 | memcpy(queue_info, &ah->ah_txq[queue], sizeof(struct ath5k_txq_info)); | ||
36 | return 0; | ||
37 | } | ||
38 | |||
39 | /* | ||
40 | * Set properties for a transmit queue | ||
41 | */ | ||
42 | int ath5k_hw_set_tx_queueprops(struct ath5k_hw *ah, int queue, | ||
43 | const struct ath5k_txq_info *queue_info) | ||
44 | { | ||
45 | ATH5K_TRACE(ah->ah_sc); | ||
46 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
47 | |||
48 | if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
49 | return -EIO; | ||
50 | |||
51 | memcpy(&ah->ah_txq[queue], queue_info, sizeof(struct ath5k_txq_info)); | ||
52 | |||
53 | /*XXX: Is this supported on 5210 ?*/ | ||
54 | if ((queue_info->tqi_type == AR5K_TX_QUEUE_DATA && | ||
55 | ((queue_info->tqi_subtype == AR5K_WME_AC_VI) || | ||
56 | (queue_info->tqi_subtype == AR5K_WME_AC_VO))) || | ||
57 | queue_info->tqi_type == AR5K_TX_QUEUE_UAPSD) | ||
58 | ah->ah_txq[queue].tqi_flags |= AR5K_TXQ_FLAG_POST_FR_BKOFF_DIS; | ||
59 | |||
60 | return 0; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * Initialize a transmit queue | ||
65 | */ | ||
66 | int ath5k_hw_setup_tx_queue(struct ath5k_hw *ah, enum ath5k_tx_queue queue_type, | ||
67 | struct ath5k_txq_info *queue_info) | ||
68 | { | ||
69 | unsigned int queue; | ||
70 | int ret; | ||
71 | |||
72 | ATH5K_TRACE(ah->ah_sc); | ||
73 | |||
74 | /* | ||
75 | * Get queue by type | ||
76 | */ | ||
77 | /*5210 only has 2 queues*/ | ||
78 | if (ah->ah_version == AR5K_AR5210) { | ||
79 | switch (queue_type) { | ||
80 | case AR5K_TX_QUEUE_DATA: | ||
81 | queue = AR5K_TX_QUEUE_ID_NOQCU_DATA; | ||
82 | break; | ||
83 | case AR5K_TX_QUEUE_BEACON: | ||
84 | case AR5K_TX_QUEUE_CAB: | ||
85 | queue = AR5K_TX_QUEUE_ID_NOQCU_BEACON; | ||
86 | break; | ||
87 | default: | ||
88 | return -EINVAL; | ||
89 | } | ||
90 | } else { | ||
91 | switch (queue_type) { | ||
92 | case AR5K_TX_QUEUE_DATA: | ||
93 | for (queue = AR5K_TX_QUEUE_ID_DATA_MIN; | ||
94 | ah->ah_txq[queue].tqi_type != | ||
95 | AR5K_TX_QUEUE_INACTIVE; queue++) { | ||
96 | |||
97 | if (queue > AR5K_TX_QUEUE_ID_DATA_MAX) | ||
98 | return -EINVAL; | ||
99 | } | ||
100 | break; | ||
101 | case AR5K_TX_QUEUE_UAPSD: | ||
102 | queue = AR5K_TX_QUEUE_ID_UAPSD; | ||
103 | break; | ||
104 | case AR5K_TX_QUEUE_BEACON: | ||
105 | queue = AR5K_TX_QUEUE_ID_BEACON; | ||
106 | break; | ||
107 | case AR5K_TX_QUEUE_CAB: | ||
108 | queue = AR5K_TX_QUEUE_ID_CAB; | ||
109 | break; | ||
110 | case AR5K_TX_QUEUE_XR_DATA: | ||
111 | if (ah->ah_version != AR5K_AR5212) | ||
112 | ATH5K_ERR(ah->ah_sc, | ||
113 | "XR data queues only supported in" | ||
114 | " 5212!\n"); | ||
115 | queue = AR5K_TX_QUEUE_ID_XR_DATA; | ||
116 | break; | ||
117 | default: | ||
118 | return -EINVAL; | ||
119 | } | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * Setup internal queue structure | ||
124 | */ | ||
125 | memset(&ah->ah_txq[queue], 0, sizeof(struct ath5k_txq_info)); | ||
126 | ah->ah_txq[queue].tqi_type = queue_type; | ||
127 | |||
128 | if (queue_info != NULL) { | ||
129 | queue_info->tqi_type = queue_type; | ||
130 | ret = ath5k_hw_set_tx_queueprops(ah, queue, queue_info); | ||
131 | if (ret) | ||
132 | return ret; | ||
133 | } | ||
134 | |||
135 | /* | ||
136 | * We use ah_txq_status to hold a temp value for | ||
137 | * the Secondary interrupt mask registers on 5211+ | ||
138 | * check out ath5k_hw_reset_tx_queue | ||
139 | */ | ||
140 | AR5K_Q_ENABLE_BITS(ah->ah_txq_status, queue); | ||
141 | |||
142 | return queue; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * Get number of pending frames | ||
147 | * for a specific queue [5211+] | ||
148 | */ | ||
149 | u32 ath5k_hw_num_tx_pending(struct ath5k_hw *ah, unsigned int queue) | ||
150 | { | ||
151 | ATH5K_TRACE(ah->ah_sc); | ||
152 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
153 | |||
154 | /* Return if queue is declared inactive */ | ||
155 | if (ah->ah_txq[queue].tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
156 | return false; | ||
157 | |||
158 | /* XXX: How about AR5K_CFG_TXCNT ? */ | ||
159 | if (ah->ah_version == AR5K_AR5210) | ||
160 | return false; | ||
161 | |||
162 | return AR5K_QUEUE_STATUS(queue) & AR5K_QCU_STS_FRMPENDCNT; | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * Set a transmit queue inactive | ||
167 | */ | ||
168 | void ath5k_hw_release_tx_queue(struct ath5k_hw *ah, unsigned int queue) | ||
169 | { | ||
170 | ATH5K_TRACE(ah->ah_sc); | ||
171 | if (WARN_ON(queue >= ah->ah_capabilities.cap_queues.q_tx_num)) | ||
172 | return; | ||
173 | |||
174 | /* This queue will be skipped in further operations */ | ||
175 | ah->ah_txq[queue].tqi_type = AR5K_TX_QUEUE_INACTIVE; | ||
176 | /*For SIMR setup*/ | ||
177 | AR5K_Q_DISABLE_BITS(ah->ah_txq_status, queue); | ||
178 | } | ||
179 | |||
180 | /* | ||
181 | * Set DFS properties for a transmit queue on DCU | ||
182 | */ | ||
183 | int ath5k_hw_reset_tx_queue(struct ath5k_hw *ah, unsigned int queue) | ||
184 | { | ||
185 | u32 cw_min, cw_max, retry_lg, retry_sh; | ||
186 | struct ath5k_txq_info *tq = &ah->ah_txq[queue]; | ||
187 | |||
188 | ATH5K_TRACE(ah->ah_sc); | ||
189 | AR5K_ASSERT_ENTRY(queue, ah->ah_capabilities.cap_queues.q_tx_num); | ||
190 | |||
191 | tq = &ah->ah_txq[queue]; | ||
192 | |||
193 | if (tq->tqi_type == AR5K_TX_QUEUE_INACTIVE) | ||
194 | return 0; | ||
195 | |||
196 | if (ah->ah_version == AR5K_AR5210) { | ||
197 | /* Only handle data queues, others will be ignored */ | ||
198 | if (tq->tqi_type != AR5K_TX_QUEUE_DATA) | ||
199 | return 0; | ||
200 | |||
201 | /* Set Slot time */ | ||
202 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
203 | AR5K_INIT_SLOT_TIME_TURBO : AR5K_INIT_SLOT_TIME, | ||
204 | AR5K_SLOT_TIME); | ||
205 | /* Set ACK_CTS timeout */ | ||
206 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
207 | AR5K_INIT_ACK_CTS_TIMEOUT_TURBO : | ||
208 | AR5K_INIT_ACK_CTS_TIMEOUT, AR5K_SLOT_TIME); | ||
209 | /* Set Transmit Latency */ | ||
210 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
211 | AR5K_INIT_TRANSMIT_LATENCY_TURBO : | ||
212 | AR5K_INIT_TRANSMIT_LATENCY, AR5K_USEC_5210); | ||
213 | |||
214 | /* Set IFS0 */ | ||
215 | if (ah->ah_turbo) { | ||
216 | ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS_TURBO + | ||
217 | (ah->ah_aifs + tq->tqi_aifs) * | ||
218 | AR5K_INIT_SLOT_TIME_TURBO) << | ||
219 | AR5K_IFS0_DIFS_S) | AR5K_INIT_SIFS_TURBO, | ||
220 | AR5K_IFS0); | ||
221 | } else { | ||
222 | ath5k_hw_reg_write(ah, ((AR5K_INIT_SIFS + | ||
223 | (ah->ah_aifs + tq->tqi_aifs) * | ||
224 | AR5K_INIT_SLOT_TIME) << AR5K_IFS0_DIFS_S) | | ||
225 | AR5K_INIT_SIFS, AR5K_IFS0); | ||
226 | } | ||
227 | |||
228 | /* Set IFS1 */ | ||
229 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
230 | AR5K_INIT_PROTO_TIME_CNTRL_TURBO : | ||
231 | AR5K_INIT_PROTO_TIME_CNTRL, AR5K_IFS1); | ||
232 | /* Set AR5K_PHY_SETTLING */ | ||
233 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
234 | (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) | ||
235 | | 0x38 : | ||
236 | (ath5k_hw_reg_read(ah, AR5K_PHY_SETTLING) & ~0x7F) | ||
237 | | 0x1C, | ||
238 | AR5K_PHY_SETTLING); | ||
239 | /* Set Frame Control Register */ | ||
240 | ath5k_hw_reg_write(ah, ah->ah_turbo ? | ||
241 | (AR5K_PHY_FRAME_CTL_INI | AR5K_PHY_TURBO_MODE | | ||
242 | AR5K_PHY_TURBO_SHORT | 0x2020) : | ||
243 | (AR5K_PHY_FRAME_CTL_INI | 0x1020), | ||
244 | AR5K_PHY_FRAME_CTL_5210); | ||
245 | } | ||
246 | |||
247 | /* | ||
248 | * Calculate cwmin/max by channel mode | ||
249 | */ | ||
250 | cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN; | ||
251 | cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX; | ||
252 | ah->ah_aifs = AR5K_TUNE_AIFS; | ||
253 | /*XR is only supported on 5212*/ | ||
254 | if (IS_CHAN_XR(ah->ah_current_channel) && | ||
255 | ah->ah_version == AR5K_AR5212) { | ||
256 | cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_XR; | ||
257 | cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_XR; | ||
258 | ah->ah_aifs = AR5K_TUNE_AIFS_XR; | ||
259 | /*B mode is not supported on 5210*/ | ||
260 | } else if (IS_CHAN_B(ah->ah_current_channel) && | ||
261 | ah->ah_version != AR5K_AR5210) { | ||
262 | cw_min = ah->ah_cw_min = AR5K_TUNE_CWMIN_11B; | ||
263 | cw_max = ah->ah_cw_max = AR5K_TUNE_CWMAX_11B; | ||
264 | ah->ah_aifs = AR5K_TUNE_AIFS_11B; | ||
265 | } | ||
266 | |||
267 | cw_min = 1; | ||
268 | while (cw_min < ah->ah_cw_min) | ||
269 | cw_min = (cw_min << 1) | 1; | ||
270 | |||
271 | cw_min = tq->tqi_cw_min < 0 ? (cw_min >> (-tq->tqi_cw_min)) : | ||
272 | ((cw_min << tq->tqi_cw_min) + (1 << tq->tqi_cw_min) - 1); | ||
273 | cw_max = tq->tqi_cw_max < 0 ? (cw_max >> (-tq->tqi_cw_max)) : | ||
274 | ((cw_max << tq->tqi_cw_max) + (1 << tq->tqi_cw_max) - 1); | ||
275 | |||
276 | /* | ||
277 | * Calculate and set retry limits | ||
278 | */ | ||
279 | if (ah->ah_software_retry) { | ||
280 | /* XXX Need to test this */ | ||
281 | retry_lg = ah->ah_limit_tx_retries; | ||
282 | retry_sh = retry_lg = retry_lg > AR5K_DCU_RETRY_LMT_SH_RETRY ? | ||
283 | AR5K_DCU_RETRY_LMT_SH_RETRY : retry_lg; | ||
284 | } else { | ||
285 | retry_lg = AR5K_INIT_LG_RETRY; | ||
286 | retry_sh = AR5K_INIT_SH_RETRY; | ||
287 | } | ||
288 | |||
289 | /*No QCU/DCU [5210]*/ | ||
290 | if (ah->ah_version == AR5K_AR5210) { | ||
291 | ath5k_hw_reg_write(ah, | ||
292 | (cw_min << AR5K_NODCU_RETRY_LMT_CW_MIN_S) | ||
293 | | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, | ||
294 | AR5K_NODCU_RETRY_LMT_SLG_RETRY) | ||
295 | | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, | ||
296 | AR5K_NODCU_RETRY_LMT_SSH_RETRY) | ||
297 | | AR5K_REG_SM(retry_lg, AR5K_NODCU_RETRY_LMT_LG_RETRY) | ||
298 | | AR5K_REG_SM(retry_sh, AR5K_NODCU_RETRY_LMT_SH_RETRY), | ||
299 | AR5K_NODCU_RETRY_LMT); | ||
300 | } else { | ||
301 | /*QCU/DCU [5211+]*/ | ||
302 | ath5k_hw_reg_write(ah, | ||
303 | AR5K_REG_SM(AR5K_INIT_SLG_RETRY, | ||
304 | AR5K_DCU_RETRY_LMT_SLG_RETRY) | | ||
305 | AR5K_REG_SM(AR5K_INIT_SSH_RETRY, | ||
306 | AR5K_DCU_RETRY_LMT_SSH_RETRY) | | ||
307 | AR5K_REG_SM(retry_lg, AR5K_DCU_RETRY_LMT_LG_RETRY) | | ||
308 | AR5K_REG_SM(retry_sh, AR5K_DCU_RETRY_LMT_SH_RETRY), | ||
309 | AR5K_QUEUE_DFS_RETRY_LIMIT(queue)); | ||
310 | |||
311 | /*===Rest is also for QCU/DCU only [5211+]===*/ | ||
312 | |||
313 | /* | ||
314 | * Set initial content window (cw_min/cw_max) | ||
315 | * and arbitrated interframe space (aifs)... | ||
316 | */ | ||
317 | ath5k_hw_reg_write(ah, | ||
318 | AR5K_REG_SM(cw_min, AR5K_DCU_LCL_IFS_CW_MIN) | | ||
319 | AR5K_REG_SM(cw_max, AR5K_DCU_LCL_IFS_CW_MAX) | | ||
320 | AR5K_REG_SM(ah->ah_aifs + tq->tqi_aifs, | ||
321 | AR5K_DCU_LCL_IFS_AIFS), | ||
322 | AR5K_QUEUE_DFS_LOCAL_IFS(queue)); | ||
323 | |||
324 | /* | ||
325 | * Set misc registers | ||
326 | */ | ||
327 | ath5k_hw_reg_write(ah, AR5K_QCU_MISC_DCU_EARLY, | ||
328 | AR5K_QUEUE_MISC(queue)); | ||
329 | |||
330 | if (tq->tqi_cbr_period) { | ||
331 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_cbr_period, | ||
332 | AR5K_QCU_CBRCFG_INTVAL) | | ||
333 | AR5K_REG_SM(tq->tqi_cbr_overflow_limit, | ||
334 | AR5K_QCU_CBRCFG_ORN_THRES), | ||
335 | AR5K_QUEUE_CBRCFG(queue)); | ||
336 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | ||
337 | AR5K_QCU_MISC_FRSHED_CBR); | ||
338 | if (tq->tqi_cbr_overflow_limit) | ||
339 | AR5K_REG_ENABLE_BITS(ah, | ||
340 | AR5K_QUEUE_MISC(queue), | ||
341 | AR5K_QCU_MISC_CBR_THRES_ENABLE); | ||
342 | } | ||
343 | |||
344 | if (tq->tqi_ready_time) | ||
345 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_ready_time, | ||
346 | AR5K_QCU_RDYTIMECFG_INTVAL) | | ||
347 | AR5K_QCU_RDYTIMECFG_ENABLE, | ||
348 | AR5K_QUEUE_RDYTIMECFG(queue)); | ||
349 | |||
350 | if (tq->tqi_burst_time) { | ||
351 | ath5k_hw_reg_write(ah, AR5K_REG_SM(tq->tqi_burst_time, | ||
352 | AR5K_DCU_CHAN_TIME_DUR) | | ||
353 | AR5K_DCU_CHAN_TIME_ENABLE, | ||
354 | AR5K_QUEUE_DFS_CHANNEL_TIME(queue)); | ||
355 | |||
356 | if (tq->tqi_flags | ||
357 | & AR5K_TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE) | ||
358 | AR5K_REG_ENABLE_BITS(ah, | ||
359 | AR5K_QUEUE_MISC(queue), | ||
360 | AR5K_QCU_MISC_RDY_VEOL_POLICY); | ||
361 | } | ||
362 | |||
363 | if (tq->tqi_flags & AR5K_TXQ_FLAG_BACKOFF_DISABLE) | ||
364 | ath5k_hw_reg_write(ah, AR5K_DCU_MISC_POST_FR_BKOFF_DIS, | ||
365 | AR5K_QUEUE_DFS_MISC(queue)); | ||
366 | |||
367 | if (tq->tqi_flags & AR5K_TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) | ||
368 | ath5k_hw_reg_write(ah, AR5K_DCU_MISC_BACKOFF_FRAG, | ||
369 | AR5K_QUEUE_DFS_MISC(queue)); | ||
370 | |||
371 | /* | ||
372 | * Set registers by queue type | ||
373 | */ | ||
374 | switch (tq->tqi_type) { | ||
375 | case AR5K_TX_QUEUE_BEACON: | ||
376 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | ||
377 | AR5K_QCU_MISC_FRSHED_DBA_GT | | ||
378 | AR5K_QCU_MISC_CBREXP_BCN_DIS | | ||
379 | AR5K_QCU_MISC_BCN_ENABLE); | ||
380 | |||
381 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), | ||
382 | (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << | ||
383 | AR5K_DCU_MISC_ARBLOCK_CTL_S) | | ||
384 | AR5K_DCU_MISC_POST_FR_BKOFF_DIS | | ||
385 | AR5K_DCU_MISC_BCN_ENABLE); | ||
386 | |||
387 | ath5k_hw_reg_write(ah, ((AR5K_TUNE_BEACON_INTERVAL - | ||
388 | (AR5K_TUNE_SW_BEACON_RESP - | ||
389 | AR5K_TUNE_DMA_BEACON_RESP) - | ||
390 | AR5K_TUNE_ADDITIONAL_SWBA_BACKOFF) * 1024) | | ||
391 | AR5K_QCU_RDYTIMECFG_ENABLE, | ||
392 | AR5K_QUEUE_RDYTIMECFG(queue)); | ||
393 | break; | ||
394 | |||
395 | case AR5K_TX_QUEUE_CAB: | ||
396 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | ||
397 | AR5K_QCU_MISC_FRSHED_DBA_GT | | ||
398 | AR5K_QCU_MISC_CBREXP_DIS | | ||
399 | AR5K_QCU_MISC_CBREXP_BCN_DIS); | ||
400 | |||
401 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_DFS_MISC(queue), | ||
402 | (AR5K_DCU_MISC_ARBLOCK_CTL_GLOBAL << | ||
403 | AR5K_DCU_MISC_ARBLOCK_CTL_S)); | ||
404 | break; | ||
405 | |||
406 | case AR5K_TX_QUEUE_UAPSD: | ||
407 | AR5K_REG_ENABLE_BITS(ah, AR5K_QUEUE_MISC(queue), | ||
408 | AR5K_QCU_MISC_CBREXP_DIS); | ||
409 | break; | ||
410 | |||
411 | case AR5K_TX_QUEUE_DATA: | ||
412 | default: | ||
413 | break; | ||
414 | } | ||
415 | |||
416 | /* | ||
417 | * Enable interrupts for this tx queue | ||
418 | * in the secondary interrupt mask registers | ||
419 | */ | ||
420 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXOKINT_ENABLE) | ||
421 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txok, queue); | ||
422 | |||
423 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXERRINT_ENABLE) | ||
424 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txerr, queue); | ||
425 | |||
426 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXURNINT_ENABLE) | ||
427 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txurn, queue); | ||
428 | |||
429 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXDESCINT_ENABLE) | ||
430 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txdesc, queue); | ||
431 | |||
432 | if (tq->tqi_flags & AR5K_TXQ_FLAG_TXEOLINT_ENABLE) | ||
433 | AR5K_Q_ENABLE_BITS(ah->ah_txq_imr_txeol, queue); | ||
434 | |||
435 | |||
436 | /* Update secondary interrupt mask registers */ | ||
437 | ah->ah_txq_imr_txok &= ah->ah_txq_status; | ||
438 | ah->ah_txq_imr_txerr &= ah->ah_txq_status; | ||
439 | ah->ah_txq_imr_txurn &= ah->ah_txq_status; | ||
440 | ah->ah_txq_imr_txdesc &= ah->ah_txq_status; | ||
441 | ah->ah_txq_imr_txeol &= ah->ah_txq_status; | ||
442 | |||
443 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txok, | ||
444 | AR5K_SIMR0_QCU_TXOK) | | ||
445 | AR5K_REG_SM(ah->ah_txq_imr_txdesc, | ||
446 | AR5K_SIMR0_QCU_TXDESC), AR5K_SIMR0); | ||
447 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txerr, | ||
448 | AR5K_SIMR1_QCU_TXERR) | | ||
449 | AR5K_REG_SM(ah->ah_txq_imr_txeol, | ||
450 | AR5K_SIMR1_QCU_TXEOL), AR5K_SIMR1); | ||
451 | ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txq_imr_txurn, | ||
452 | AR5K_SIMR2_QCU_TXURN), AR5K_SIMR2); | ||
453 | } | ||
454 | |||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | /* | ||
459 | * Get slot time from DCU | ||
460 | */ | ||
461 | unsigned int ath5k_hw_get_slot_time(struct ath5k_hw *ah) | ||
462 | { | ||
463 | ATH5K_TRACE(ah->ah_sc); | ||
464 | if (ah->ah_version == AR5K_AR5210) | ||
465 | return ath5k_hw_clocktoh(ath5k_hw_reg_read(ah, | ||
466 | AR5K_SLOT_TIME) & 0xffff, ah->ah_turbo); | ||
467 | else | ||
468 | return ath5k_hw_reg_read(ah, AR5K_DCU_GBL_IFS_SLOT) & 0xffff; | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * Set slot time on DCU | ||
473 | */ | ||
474 | int ath5k_hw_set_slot_time(struct ath5k_hw *ah, unsigned int slot_time) | ||
475 | { | ||
476 | ATH5K_TRACE(ah->ah_sc); | ||
477 | if (slot_time < AR5K_SLOT_TIME_9 || slot_time > AR5K_SLOT_TIME_MAX) | ||
478 | return -EINVAL; | ||
479 | |||
480 | if (ah->ah_version == AR5K_AR5210) | ||
481 | ath5k_hw_reg_write(ah, ath5k_hw_htoclock(slot_time, | ||
482 | ah->ah_turbo), AR5K_SLOT_TIME); | ||
483 | else | ||
484 | ath5k_hw_reg_write(ah, slot_time, AR5K_DCU_GBL_IFS_SLOT); | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
diff --git a/drivers/net/wireless/ath5k/reg.h b/drivers/net/wireless/ath5k/reg.h index 7562bf173d3e..e557fe178bbf 100644 --- a/drivers/net/wireless/ath5k/reg.h +++ b/drivers/net/wireless/ath5k/reg.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2007 Nick Kossifidis <mickflemm@gmail.com> | 2 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> |
3 | * Copyright (c) 2004, 2005, 2006, 2007 Reyk Floeter <reyk@openbsd.org> | 3 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> |
4 | * Copyright (c) 2007 Michael Taylor <mike.taylor@apprion.com> | 4 | * Copyright (c) 2007-2008 Michael Taylor <mike.taylor@apprion.com> |
5 | * | 5 | * |
6 | * Permission to use, copy, modify, and distribute this software for any | 6 | * Permission to use, copy, modify, and distribute this software for any |
7 | * purpose with or without fee is hereby granted, provided that the above | 7 | * purpose with or without fee is hereby granted, provided that the above |
@@ -29,6 +29,10 @@ | |||
29 | * http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf | 29 | * http://www.it.iitb.ac.in/~janak/wifire/01222734.pdf |
30 | * | 30 | * |
31 | * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf | 31 | * 5211 - http://www.hotchips.org/archives/hc14/3_Tue/16_mcfarland.pdf |
32 | * | ||
33 | * This file also contains register values found on a memory dump of | ||
34 | * Atheros's ART program (Atheros Radio Test), on ath9k, on legacy-hal | ||
35 | * released by Atheros and on various debug messages found on the net. | ||
32 | */ | 36 | */ |
33 | 37 | ||
34 | 38 | ||
@@ -295,7 +299,7 @@ | |||
295 | #define AR5K_ISR_RXPHY 0x00004000 /* PHY error */ | 299 | #define AR5K_ISR_RXPHY 0x00004000 /* PHY error */ |
296 | #define AR5K_ISR_RXKCM 0x00008000 /* RX Key cache miss */ | 300 | #define AR5K_ISR_RXKCM 0x00008000 /* RX Key cache miss */ |
297 | #define AR5K_ISR_SWBA 0x00010000 /* Software beacon alert */ | 301 | #define AR5K_ISR_SWBA 0x00010000 /* Software beacon alert */ |
298 | #define AR5K_ISR_BRSSI 0x00020000 | 302 | #define AR5K_ISR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ |
299 | #define AR5K_ISR_BMISS 0x00040000 /* Beacon missed */ | 303 | #define AR5K_ISR_BMISS 0x00040000 /* Beacon missed */ |
300 | #define AR5K_ISR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ | 304 | #define AR5K_ISR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ |
301 | #define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */ | 305 | #define AR5K_ISR_BNR 0x00100000 /* Beacon not ready [5211+] */ |
@@ -303,46 +307,56 @@ | |||
303 | #define AR5K_ISR_RXCHIRP 0x00200000 /* CHIRP Received [5212+] */ | 307 | #define AR5K_ISR_RXCHIRP 0x00200000 /* CHIRP Received [5212+] */ |
304 | #define AR5K_ISR_SSERR 0x00200000 /* Signaled System Error [5210] */ | 308 | #define AR5K_ISR_SSERR 0x00200000 /* Signaled System Error [5210] */ |
305 | #define AR5K_ISR_DPERR 0x00400000 /* Det par Error (?) [5210] */ | 309 | #define AR5K_ISR_DPERR 0x00400000 /* Det par Error (?) [5210] */ |
306 | #define AR5K_ISR_TIM 0x00800000 /* [5210] */ | 310 | #define AR5K_ISR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ |
307 | #define AR5K_ISR_BCNMISC 0x00800000 /* [5212+] */ | 311 | #define AR5K_ISR_TIM 0x00800000 /* [5211+] */ |
308 | #define AR5K_ISR_GPIO 0x01000000 /* GPIO (rf kill)*/ | 312 | #define AR5K_ISR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, |
309 | #define AR5K_ISR_QCBRORN 0x02000000 /* CBR overrun (?) [5211+] */ | 313 | CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ |
310 | #define AR5K_ISR_QCBRURN 0x04000000 /* CBR underrun (?) [5211+] */ | 314 | #define AR5K_ISR_GPIO 0x01000000 /* GPIO (rf kill) */ |
311 | #define AR5K_ISR_QTRIG 0x08000000 /* [5211+] */ | 315 | #define AR5K_ISR_QCBRORN 0x02000000 /* QCU CBR overrun [5211+] */ |
316 | #define AR5K_ISR_QCBRURN 0x04000000 /* QCU CBR underrun [5211+] */ | ||
317 | #define AR5K_ISR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ | ||
312 | 318 | ||
313 | /* | 319 | /* |
314 | * Secondary status registers [5211+] (0 - 4) | 320 | * Secondary status registers [5211+] (0 - 4) |
315 | * | 321 | * |
316 | * I guess from the names that these give the status for each | 322 | * These give the status for each QCU, only QCUs 0-9 are |
317 | * queue, that's why only masks are defined here, haven't got | 323 | * represented. |
318 | * any info about them (couldn't find them anywhere in ar5k code). | ||
319 | */ | 324 | */ |
320 | #define AR5K_SISR0 0x0084 /* Register Address [5211+] */ | 325 | #define AR5K_SISR0 0x0084 /* Register Address [5211+] */ |
321 | #define AR5K_SISR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */ | 326 | #define AR5K_SISR0_QCU_TXOK 0x000003ff /* Mask for QCU_TXOK */ |
327 | #define AR5K_SISR0_QCU_TXOK_S 0 | ||
322 | #define AR5K_SISR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */ | 328 | #define AR5K_SISR0_QCU_TXDESC 0x03ff0000 /* Mask for QCU_TXDESC */ |
329 | #define AR5K_SISR0_QCU_TXDESC_S 16 | ||
323 | 330 | ||
324 | #define AR5K_SISR1 0x0088 /* Register Address [5211+] */ | 331 | #define AR5K_SISR1 0x0088 /* Register Address [5211+] */ |
325 | #define AR5K_SISR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */ | 332 | #define AR5K_SISR1_QCU_TXERR 0x000003ff /* Mask for QCU_TXERR */ |
333 | #define AR5K_SISR1_QCU_TXERR_S 0 | ||
326 | #define AR5K_SISR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */ | 334 | #define AR5K_SISR1_QCU_TXEOL 0x03ff0000 /* Mask for QCU_TXEOL */ |
335 | #define AR5K_SISR1_QCU_TXEOL_S 16 | ||
327 | 336 | ||
328 | #define AR5K_SISR2 0x008c /* Register Address [5211+] */ | 337 | #define AR5K_SISR2 0x008c /* Register Address [5211+] */ |
329 | #define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ | 338 | #define AR5K_SISR2_QCU_TXURN 0x000003ff /* Mask for QCU_TXURN */ |
339 | #define AR5K_SISR2_QCU_TXURN_S 0 | ||
330 | #define AR5K_SISR2_MCABT 0x00100000 /* Master Cycle Abort */ | 340 | #define AR5K_SISR2_MCABT 0x00100000 /* Master Cycle Abort */ |
331 | #define AR5K_SISR2_SSERR 0x00200000 /* Signaled System Error */ | 341 | #define AR5K_SISR2_SSERR 0x00200000 /* Signaled System Error */ |
332 | #define AR5K_SISR2_DPERR 0x00400000 /* Det par Error (?) */ | 342 | #define AR5K_SISR2_DPERR 0x00400000 /* Bus parity error */ |
333 | #define AR5K_SISR2_TIM 0x01000000 /* [5212+] */ | 343 | #define AR5K_SISR2_TIM 0x01000000 /* [5212+] */ |
334 | #define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */ | 344 | #define AR5K_SISR2_CAB_END 0x02000000 /* [5212+] */ |
335 | #define AR5K_SISR2_DTIM_SYNC 0x04000000 /* DTIM sync lost [5212+] */ | 345 | #define AR5K_SISR2_DTIM_SYNC 0x04000000 /* DTIM sync lost [5212+] */ |
336 | #define AR5K_SISR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ | 346 | #define AR5K_SISR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ |
337 | #define AR5K_SISR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ | 347 | #define AR5K_SISR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ |
338 | #define AR5K_SISR2_DTIM 0x20000000 /* [5212+] */ | 348 | #define AR5K_SISR2_DTIM 0x20000000 /* [5212+] */ |
349 | #define AR5K_SISR2_TSFOOR 0x80000000 /* TSF OOR (?) */ | ||
339 | 350 | ||
340 | #define AR5K_SISR3 0x0090 /* Register Address [5211+] */ | 351 | #define AR5K_SISR3 0x0090 /* Register Address [5211+] */ |
341 | #define AR5K_SISR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ | 352 | #define AR5K_SISR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ |
353 | #define AR5K_SISR3_QCBORN_S 0 | ||
342 | #define AR5K_SISR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */ | 354 | #define AR5K_SISR3_QCBRURN 0x03ff0000 /* Mask for QCBRURN */ |
355 | #define AR5K_SISR3_QCBRURN_S 16 | ||
343 | 356 | ||
344 | #define AR5K_SISR4 0x0094 /* Register Address [5211+] */ | 357 | #define AR5K_SISR4 0x0094 /* Register Address [5211+] */ |
345 | #define AR5K_SISR4_QTRIG 0x000003ff /* Mask for QTRIG */ | 358 | #define AR5K_SISR4_QTRIG 0x000003ff /* Mask for QTRIG */ |
359 | #define AR5K_SISR4_QTRIG_S 0 | ||
346 | 360 | ||
347 | /* | 361 | /* |
348 | * Shadow read-and-clear interrupt status registers [5211+] | 362 | * Shadow read-and-clear interrupt status registers [5211+] |
@@ -379,7 +393,7 @@ | |||
379 | #define AR5K_IMR_RXPHY 0x00004000 /* PHY error*/ | 393 | #define AR5K_IMR_RXPHY 0x00004000 /* PHY error*/ |
380 | #define AR5K_IMR_RXKCM 0x00008000 /* RX Key cache miss */ | 394 | #define AR5K_IMR_RXKCM 0x00008000 /* RX Key cache miss */ |
381 | #define AR5K_IMR_SWBA 0x00010000 /* Software beacon alert*/ | 395 | #define AR5K_IMR_SWBA 0x00010000 /* Software beacon alert*/ |
382 | #define AR5K_IMR_BRSSI 0x00020000 | 396 | #define AR5K_IMR_BRSSI 0x00020000 /* Beacon rssi below threshold (?) */ |
383 | #define AR5K_IMR_BMISS 0x00040000 /* Beacon missed*/ | 397 | #define AR5K_IMR_BMISS 0x00040000 /* Beacon missed*/ |
384 | #define AR5K_IMR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ | 398 | #define AR5K_IMR_HIUERR 0x00080000 /* Host Interface Unit error [5211+] */ |
385 | #define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */ | 399 | #define AR5K_IMR_BNR 0x00100000 /* Beacon not ready [5211+] */ |
@@ -387,12 +401,14 @@ | |||
387 | #define AR5K_IMR_RXCHIRP 0x00200000 /* CHIRP Received [5212+]*/ | 401 | #define AR5K_IMR_RXCHIRP 0x00200000 /* CHIRP Received [5212+]*/ |
388 | #define AR5K_IMR_SSERR 0x00200000 /* Signaled System Error [5210] */ | 402 | #define AR5K_IMR_SSERR 0x00200000 /* Signaled System Error [5210] */ |
389 | #define AR5K_IMR_DPERR 0x00400000 /* Det par Error (?) [5210] */ | 403 | #define AR5K_IMR_DPERR 0x00400000 /* Det par Error (?) [5210] */ |
404 | #define AR5K_IMR_RXDOPPLER 0x00400000 /* Doppler chirp received [5212+] */ | ||
390 | #define AR5K_IMR_TIM 0x00800000 /* [5211+] */ | 405 | #define AR5K_IMR_TIM 0x00800000 /* [5211+] */ |
391 | #define AR5K_IMR_BCNMISC 0x00800000 /* [5212+] */ | 406 | #define AR5K_IMR_BCNMISC 0x00800000 /* 'or' of TIM, CAB_END, DTIM_SYNC, BCN_TIMEOUT, |
407 | CAB_TIMEOUT and DTIM bits from SISR2 [5212+] */ | ||
392 | #define AR5K_IMR_GPIO 0x01000000 /* GPIO (rf kill)*/ | 408 | #define AR5K_IMR_GPIO 0x01000000 /* GPIO (rf kill)*/ |
393 | #define AR5K_IMR_QCBRORN 0x02000000 /* CBR overrun (?) [5211+] */ | 409 | #define AR5K_IMR_QCBRORN 0x02000000 /* QCU CBR overrun (?) [5211+] */ |
394 | #define AR5K_IMR_QCBRURN 0x04000000 /* CBR underrun (?) [5211+] */ | 410 | #define AR5K_IMR_QCBRURN 0x04000000 /* QCU CBR underrun (?) [5211+] */ |
395 | #define AR5K_IMR_QTRIG 0x08000000 /* [5211+] */ | 411 | #define AR5K_IMR_QTRIG 0x08000000 /* QCU scheduling trigger [5211+] */ |
396 | 412 | ||
397 | /* | 413 | /* |
398 | * Secondary interrupt mask registers [5211+] (0 - 4) | 414 | * Secondary interrupt mask registers [5211+] (0 - 4) |
@@ -414,13 +430,14 @@ | |||
414 | #define AR5K_SIMR2_QCU_TXURN_S 0 | 430 | #define AR5K_SIMR2_QCU_TXURN_S 0 |
415 | #define AR5K_SIMR2_MCABT 0x00100000 /* Master Cycle Abort */ | 431 | #define AR5K_SIMR2_MCABT 0x00100000 /* Master Cycle Abort */ |
416 | #define AR5K_SIMR2_SSERR 0x00200000 /* Signaled System Error */ | 432 | #define AR5K_SIMR2_SSERR 0x00200000 /* Signaled System Error */ |
417 | #define AR5K_SIMR2_DPERR 0x00400000 /* Det par Error (?) */ | 433 | #define AR5K_SIMR2_DPERR 0x00400000 /* Bus parity error */ |
418 | #define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */ | 434 | #define AR5K_SIMR2_TIM 0x01000000 /* [5212+] */ |
419 | #define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */ | 435 | #define AR5K_SIMR2_CAB_END 0x02000000 /* [5212+] */ |
420 | #define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* DTIM Sync lost [5212+] */ | 436 | #define AR5K_SIMR2_DTIM_SYNC 0x04000000 /* DTIM Sync lost [5212+] */ |
421 | #define AR5K_SIMR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ | 437 | #define AR5K_SIMR2_BCN_TIMEOUT 0x08000000 /* Beacon Timeout [5212+] */ |
422 | #define AR5K_SIMR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ | 438 | #define AR5K_SIMR2_CAB_TIMEOUT 0x10000000 /* CAB Timeout [5212+] */ |
423 | #define AR5K_SIMR2_DTIM 0x20000000 /* [5212+] */ | 439 | #define AR5K_SIMR2_DTIM 0x20000000 /* [5212+] */ |
440 | #define AR5K_SIMR2_TSFOOR 0x80000000 /* TSF OOR (?) */ | ||
424 | 441 | ||
425 | #define AR5K_SIMR3 0x00b0 /* Register Address [5211+] */ | 442 | #define AR5K_SIMR3 0x00b0 /* Register Address [5211+] */ |
426 | #define AR5K_SIMR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ | 443 | #define AR5K_SIMR3_QCBRORN 0x000003ff /* Mask for QCBRORN */ |
@@ -586,15 +603,15 @@ | |||
586 | #define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame sheduling mask */ | 603 | #define AR5K_QCU_MISC_FRSHED_M 0x0000000f /* Frame sheduling mask */ |
587 | #define AR5K_QCU_MISC_FRSHED_ASAP 0 /* ASAP */ | 604 | #define AR5K_QCU_MISC_FRSHED_ASAP 0 /* ASAP */ |
588 | #define AR5K_QCU_MISC_FRSHED_CBR 1 /* Constant Bit Rate */ | 605 | #define AR5K_QCU_MISC_FRSHED_CBR 1 /* Constant Bit Rate */ |
589 | #define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated (?) */ | 606 | #define AR5K_QCU_MISC_FRSHED_DBA_GT 2 /* DMA Beacon alert gated */ |
590 | #define AR5K_QCU_MISC_FRSHED_TIM_GT 3 /* Time gated (?) */ | 607 | #define AR5K_QCU_MISC_FRSHED_TIM_GT 3 /* TIMT gated */ |
591 | #define AR5K_QCU_MISC_FRSHED_BCN_SENT_GT 4 /* Beacon sent gated (?) */ | 608 | #define AR5K_QCU_MISC_FRSHED_BCN_SENT_GT 4 /* Beacon sent gated */ |
592 | #define AR5K_QCU_MISC_ONESHOT_ENABLE 0x00000010 /* Oneshot enable */ | 609 | #define AR5K_QCU_MISC_ONESHOT_ENABLE 0x00000010 /* Oneshot enable */ |
593 | #define AR5K_QCU_MISC_CBREXP 0x00000020 /* CBR expired (normal queue) */ | 610 | #define AR5K_QCU_MISC_CBREXP_DIS 0x00000020 /* Disable CBR expired counter (normal queue) */ |
594 | #define AR5K_QCU_MISC_CBREXP_BCN 0x00000040 /* CBR expired (beacon queue) */ | 611 | #define AR5K_QCU_MISC_CBREXP_BCN_DIS 0x00000040 /* Disable CBR expired counter (beacon queue) */ |
595 | #define AR5K_QCU_MISC_BCN_ENABLE 0x00000080 /* Enable Beacon use */ | 612 | #define AR5K_QCU_MISC_BCN_ENABLE 0x00000080 /* Enable Beacon use */ |
596 | #define AR5K_QCU_MISC_CBR_THRES_ENABLE 0x00000100 /* CBR threshold enabled */ | 613 | #define AR5K_QCU_MISC_CBR_THRES_ENABLE 0x00000100 /* CBR expired threshold enabled */ |
597 | #define AR5K_QCU_MISC_RDY_VEOL_POLICY 0x00000200 /* TXE reset when RDYTIME enalbed */ | 614 | #define AR5K_QCU_MISC_RDY_VEOL_POLICY 0x00000200 /* TXE reset when RDYTIME expired or VEOL */ |
598 | #define AR5K_QCU_MISC_CBR_RESET_CNT 0x00000400 /* CBR threshold (counter) reset */ | 615 | #define AR5K_QCU_MISC_CBR_RESET_CNT 0x00000400 /* CBR threshold (counter) reset */ |
599 | #define AR5K_QCU_MISC_DCU_EARLY 0x00000800 /* DCU early termination */ | 616 | #define AR5K_QCU_MISC_DCU_EARLY 0x00000800 /* DCU early termination */ |
600 | #define AR5K_QCU_MISC_DCU_CMP_EN 0x00001000 /* Enable frame compression */ | 617 | #define AR5K_QCU_MISC_DCU_CMP_EN 0x00001000 /* Enable frame compression */ |
@@ -663,6 +680,7 @@ | |||
663 | #define AR5K_DCU_LCL_IFS_CW_MAX_S 10 | 680 | #define AR5K_DCU_LCL_IFS_CW_MAX_S 10 |
664 | #define AR5K_DCU_LCL_IFS_AIFS 0x0ff00000 /* Arbitrated Interframe Space */ | 681 | #define AR5K_DCU_LCL_IFS_AIFS 0x0ff00000 /* Arbitrated Interframe Space */ |
665 | #define AR5K_DCU_LCL_IFS_AIFS_S 20 | 682 | #define AR5K_DCU_LCL_IFS_AIFS_S 20 |
683 | #define AR5K_DCU_LCL_IFS_AIFS_MAX 0xfc /* Anything above that can cause DCU to hang */ | ||
666 | #define AR5K_QUEUE_DFS_LOCAL_IFS(_q) AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q) | 684 | #define AR5K_QUEUE_DFS_LOCAL_IFS(_q) AR5K_QUEUE_REG(AR5K_DCU_LCL_IFS_BASE, _q) |
667 | 685 | ||
668 | /* | 686 | /* |
@@ -691,11 +709,7 @@ | |||
691 | /* | 709 | /* |
692 | * DCU misc registers [5211+] | 710 | * DCU misc registers [5211+] |
693 | * | 711 | * |
694 | * For some of the registers i couldn't find in the code | 712 | * Note: Arbiter lockout control controls the |
695 | * (only backoff stuff is there realy) i tried to match the | ||
696 | * names with 802.11e parameters etc, so i guess VIRTCOL here | ||
697 | * means Virtual Collision and HCFPOLL means Hybrid Coordination | ||
698 | * factor Poll (CF- Poll). Arbiter lockout control controls the | ||
699 | * behaviour on low priority queues when we have multiple queues | 713 | * behaviour on low priority queues when we have multiple queues |
700 | * with pending frames. Intra-frame lockout means we wait until | 714 | * with pending frames. Intra-frame lockout means we wait until |
701 | * the queue's current frame transmits (with post frame backoff and bursting) | 715 | * the queue's current frame transmits (with post frame backoff and bursting) |
@@ -705,15 +719,20 @@ | |||
705 | * No lockout means there is no special handling. | 719 | * No lockout means there is no special handling. |
706 | */ | 720 | */ |
707 | #define AR5K_DCU_MISC_BASE 0x1100 /* Register Address -Queue0 DCU_MISC */ | 721 | #define AR5K_DCU_MISC_BASE 0x1100 /* Register Address -Queue0 DCU_MISC */ |
708 | #define AR5K_DCU_MISC_BACKOFF 0x000007ff /* Mask for backoff threshold */ | 722 | #define AR5K_DCU_MISC_BACKOFF 0x0000003f /* Mask for backoff threshold */ |
723 | #define AR5K_DCU_MISC_ETS_RTS_POL 0x00000040 /* End of transmission series | ||
724 | station RTS/data failure count | ||
725 | reset policy (?) */ | ||
726 | #define AR5K_DCU_MISC_ETS_CW_POL 0x00000080 /* End of transmission series | ||
727 | CW reset policy */ | ||
728 | #define AR5K_DCU_MISC_FRAG_WAIT 0x00000100 /* Wait for next fragment */ | ||
709 | #define AR5K_DCU_MISC_BACKOFF_FRAG 0x00000200 /* Enable backoff while bursting */ | 729 | #define AR5K_DCU_MISC_BACKOFF_FRAG 0x00000200 /* Enable backoff while bursting */ |
710 | #define AR5K_DCU_MISC_HCFPOLL_ENABLE 0x00000800 /* CF - Poll enable */ | 730 | #define AR5K_DCU_MISC_HCFPOLL_ENABLE 0x00000800 /* CF - Poll enable */ |
711 | #define AR5K_DCU_MISC_BACKOFF_PERSIST 0x00001000 /* Persistent backoff */ | 731 | #define AR5K_DCU_MISC_BACKOFF_PERSIST 0x00001000 /* Persistent backoff */ |
712 | #define AR5K_DCU_MISC_FRMPRFTCH_ENABLE 0x00002000 /* Enable frame pre-fetch */ | 732 | #define AR5K_DCU_MISC_FRMPRFTCH_ENABLE 0x00002000 /* Enable frame pre-fetch */ |
713 | #define AR5K_DCU_MISC_VIRTCOL 0x0000c000 /* Mask for Virtual Collision (?) */ | 733 | #define AR5K_DCU_MISC_VIRTCOL 0x0000c000 /* Mask for Virtual Collision (?) */ |
714 | #define AR5K_DCU_MISC_VIRTCOL_NORMAL 0 | 734 | #define AR5K_DCU_MISC_VIRTCOL_NORMAL 0 |
715 | #define AR5K_DCU_MISC_VIRTCOL_MODIFIED 1 | 735 | #define AR5K_DCU_MISC_VIRTCOL_IGNORE 1 |
716 | #define AR5K_DCU_MISC_VIRTCOL_IGNORE 2 | ||
717 | #define AR5K_DCU_MISC_BCN_ENABLE 0x00010000 /* Enable Beacon use */ | 736 | #define AR5K_DCU_MISC_BCN_ENABLE 0x00010000 /* Enable Beacon use */ |
718 | #define AR5K_DCU_MISC_ARBLOCK_CTL 0x00060000 /* Arbiter lockout control mask */ | 737 | #define AR5K_DCU_MISC_ARBLOCK_CTL 0x00060000 /* Arbiter lockout control mask */ |
719 | #define AR5K_DCU_MISC_ARBLOCK_CTL_S 17 | 738 | #define AR5K_DCU_MISC_ARBLOCK_CTL_S 17 |
@@ -768,8 +787,9 @@ | |||
768 | #define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */ | 787 | #define AR5K_DCU_GBL_IFS_MISC_TURBO_MODE 0x00000008 /* Turbo mode */ |
769 | #define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */ | 788 | #define AR5K_DCU_GBL_IFS_MISC_SIFS_DUR_USEC 0x000003f0 /* SIFS Duration mask */ |
770 | #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */ | 789 | #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR 0x000ffc00 /* USEC Duration mask */ |
790 | #define AR5K_DCU_GBL_IFS_MISC_USEC_DUR_S 10 | ||
771 | #define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */ | 791 | #define AR5K_DCU_GBL_IFS_MISC_DCU_ARB_DELAY 0x00300000 /* DCU Arbiter delay mask */ |
772 | #define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST 0x00400000 /* SIFC cnt reset policy (?) */ | 792 | #define AR5K_DCU_GBL_IFS_MISC_SIFS_CNT_RST 0x00400000 /* SIFS cnt reset policy (?) */ |
773 | #define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST 0x00800000 /* AIFS cnt reset policy (?) */ | 793 | #define AR5K_DCU_GBL_IFS_MISC_AIFS_CNT_RST 0x00800000 /* AIFS cnt reset policy (?) */ |
774 | #define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS 0x01000000 /* Disable random LFSR slice */ | 794 | #define AR5K_DCU_GBL_IFS_MISC_RND_LFSR_SL_DIS 0x01000000 /* Disable random LFSR slice */ |
775 | 795 | ||
@@ -820,8 +840,6 @@ | |||
820 | #define AR5K_RESET_CTL_MAC 0x00000004 /* MAC reset (PCU+Baseband ?) [5210] */ | 840 | #define AR5K_RESET_CTL_MAC 0x00000004 /* MAC reset (PCU+Baseband ?) [5210] */ |
821 | #define AR5K_RESET_CTL_PHY 0x00000008 /* PHY reset [5210] */ | 841 | #define AR5K_RESET_CTL_PHY 0x00000008 /* PHY reset [5210] */ |
822 | #define AR5K_RESET_CTL_PCI 0x00000010 /* PCI Core reset (interrupts etc) */ | 842 | #define AR5K_RESET_CTL_PCI 0x00000010 /* PCI Core reset (interrupts etc) */ |
823 | #define AR5K_RESET_CTL_CHIP (AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | \ | ||
824 | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY) | ||
825 | 843 | ||
826 | /* | 844 | /* |
827 | * Sleep control register | 845 | * Sleep control register |
@@ -833,9 +851,11 @@ | |||
833 | #define AR5K_SLEEP_CTL_SLE_S 16 | 851 | #define AR5K_SLEEP_CTL_SLE_S 16 |
834 | #define AR5K_SLEEP_CTL_SLE_WAKE 0x00000000 /* Force chip awake */ | 852 | #define AR5K_SLEEP_CTL_SLE_WAKE 0x00000000 /* Force chip awake */ |
835 | #define AR5K_SLEEP_CTL_SLE_SLP 0x00010000 /* Force chip sleep */ | 853 | #define AR5K_SLEEP_CTL_SLE_SLP 0x00010000 /* Force chip sleep */ |
836 | #define AR5K_SLEEP_CTL_SLE_ALLOW 0x00020000 | 854 | #define AR5K_SLEEP_CTL_SLE_ALLOW 0x00020000 /* Normal sleep policy */ |
837 | #define AR5K_SLEEP_CTL_SLE_UNITS 0x00000008 /* [5211+] */ | 855 | #define AR5K_SLEEP_CTL_SLE_UNITS 0x00000008 /* [5211+] */ |
838 | /* more bits */ | 856 | #define AR5K_SLEEP_CTL_DUR_TIM_POL 0x00040000 /* Sleep duration timing policy */ |
857 | #define AR5K_SLEEP_CTL_DUR_WRITE_POL 0x00080000 /* Sleep duration write policy */ | ||
858 | #define AR5K_SLEEP_CTL_SLE_POL 0x00100000 /* Sleep policy mode */ | ||
839 | 859 | ||
840 | /* | 860 | /* |
841 | * Interrupt pending register | 861 | * Interrupt pending register |
@@ -851,27 +871,28 @@ | |||
851 | 871 | ||
852 | /* | 872 | /* |
853 | * PCI configuration register | 873 | * PCI configuration register |
874 | * TODO: Fix LED stuff | ||
854 | */ | 875 | */ |
855 | #define AR5K_PCICFG 0x4010 /* Register Address */ | 876 | #define AR5K_PCICFG 0x4010 /* Register Address */ |
856 | #define AR5K_PCICFG_EEAE 0x00000001 /* Eeprom access enable [5210] */ | 877 | #define AR5K_PCICFG_EEAE 0x00000001 /* Eeprom access enable [5210] */ |
857 | #define AR5K_PCICFG_SLEEP_CLOCK_EN 0x00000002 /* Enable sleep clock (?) */ | 878 | #define AR5K_PCICFG_SLEEP_CLOCK_EN 0x00000002 /* Enable sleep clock */ |
858 | #define AR5K_PCICFG_CLKRUNEN 0x00000004 /* CLKRUN enable [5211+] */ | 879 | #define AR5K_PCICFG_CLKRUNEN 0x00000004 /* CLKRUN enable [5211+] */ |
859 | #define AR5K_PCICFG_EESIZE 0x00000018 /* Mask for EEPROM size [5211+] */ | 880 | #define AR5K_PCICFG_EESIZE 0x00000018 /* Mask for EEPROM size [5211+] */ |
860 | #define AR5K_PCICFG_EESIZE_S 3 | 881 | #define AR5K_PCICFG_EESIZE_S 3 |
861 | #define AR5K_PCICFG_EESIZE_4K 0 /* 4K */ | 882 | #define AR5K_PCICFG_EESIZE_4K 0 /* 4K */ |
862 | #define AR5K_PCICFG_EESIZE_8K 1 /* 8K */ | 883 | #define AR5K_PCICFG_EESIZE_8K 1 /* 8K */ |
863 | #define AR5K_PCICFG_EESIZE_16K 2 /* 16K */ | 884 | #define AR5K_PCICFG_EESIZE_16K 2 /* 16K */ |
864 | #define AR5K_PCICFG_EESIZE_FAIL 3 /* Failed to get size (?) [5211+] */ | 885 | #define AR5K_PCICFG_EESIZE_FAIL 3 /* Failed to get size [5211+] */ |
865 | #define AR5K_PCICFG_LED 0x00000060 /* Led status [5211+] */ | 886 | #define AR5K_PCICFG_LED 0x00000060 /* Led status [5211+] */ |
866 | #define AR5K_PCICFG_LED_NONE 0x00000000 /* Default [5211+] */ | 887 | #define AR5K_PCICFG_LED_NONE 0x00000000 /* Default [5211+] */ |
867 | #define AR5K_PCICFG_LED_PEND 0x00000020 /* Scan / Auth pending */ | 888 | #define AR5K_PCICFG_LED_PEND 0x00000020 /* Scan / Auth pending */ |
868 | #define AR5K_PCICFG_LED_ASSOC 0x00000040 /* Associated */ | 889 | #define AR5K_PCICFG_LED_ASSOC 0x00000040 /* Associated */ |
869 | #define AR5K_PCICFG_BUS_SEL 0x00000380 /* Mask for "bus select" [5211+] (?) */ | 890 | #define AR5K_PCICFG_BUS_SEL 0x00000380 /* Mask for "bus select" [5211+] (?) */ |
870 | #define AR5K_PCICFG_CBEFIX_DIS 0x00000400 /* Disable CBE fix (?) */ | 891 | #define AR5K_PCICFG_CBEFIX_DIS 0x00000400 /* Disable CBE fix */ |
871 | #define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep (?) */ | 892 | #define AR5K_PCICFG_SL_INTEN 0x00000800 /* Enable interrupts when asleep */ |
872 | #define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */ | 893 | #define AR5K_PCICFG_LED_BCTL 0x00001000 /* Led blink (?) [5210] */ |
873 | #define AR5K_PCICFG_UNK 0x00001000 /* Passed on some parts durring attach (?) */ | 894 | #define AR5K_PCICFG_RETRY_FIX 0x00001000 /* Enable pci core retry fix */ |
874 | #define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even whith pending interrupts (?) */ | 895 | #define AR5K_PCICFG_SL_INPEN 0x00002000 /* Sleep even whith pending interrupts*/ |
875 | #define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */ | 896 | #define AR5K_PCICFG_SPWR_DN 0x00010000 /* Mask for power status */ |
876 | #define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */ | 897 | #define AR5K_PCICFG_LEDMODE 0x000e0000 /* Ledmode [5211+] */ |
877 | #define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */ | 898 | #define AR5K_PCICFG_LEDMODE_PROP 0x00000000 /* Blink on standard traffic [5211+] */ |
@@ -884,7 +905,8 @@ | |||
884 | #define AR5K_PCICFG_LEDSTATE \ | 905 | #define AR5K_PCICFG_LEDSTATE \ |
885 | (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE | \ | 906 | (AR5K_PCICFG_LED | AR5K_PCICFG_LEDMODE | \ |
886 | AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW) | 907 | AR5K_PCICFG_LEDBLINK | AR5K_PCICFG_LEDSLOW) |
887 | #define AR5K_PCICFG_SLEEP_CLOCK_RATE 0x03000000 /* Sleep clock rate (field) */ | 908 | #define AR5K_PCICFG_SLEEP_CLOCK_RATE 0x03000000 /* Sleep clock rate */ |
909 | #define AR5K_PCICFG_SLEEP_CLOCK_RATE_S 24 | ||
888 | 910 | ||
889 | /* | 911 | /* |
890 | * "General Purpose Input/Output" (GPIO) control register | 912 | * "General Purpose Input/Output" (GPIO) control register |
@@ -906,8 +928,8 @@ | |||
906 | 928 | ||
907 | #define AR5K_GPIOCR 0x4014 /* Register Address */ | 929 | #define AR5K_GPIOCR 0x4014 /* Register Address */ |
908 | #define AR5K_GPIOCR_INT_ENA 0x00008000 /* Enable GPIO interrupt */ | 930 | #define AR5K_GPIOCR_INT_ENA 0x00008000 /* Enable GPIO interrupt */ |
909 | #define AR5K_GPIOCR_INT_SELL 0x00000000 /* Generate interrupt when pin is off (?) */ | 931 | #define AR5K_GPIOCR_INT_SELL 0x00000000 /* Generate interrupt when pin is low */ |
910 | #define AR5K_GPIOCR_INT_SELH 0x00010000 /* Generate interrupt when pin is on */ | 932 | #define AR5K_GPIOCR_INT_SELH 0x00010000 /* Generate interrupt when pin is high */ |
911 | #define AR5K_GPIOCR_IN(n) (0 << ((n) * 2)) /* Mode 0 for pin n */ | 933 | #define AR5K_GPIOCR_IN(n) (0 << ((n) * 2)) /* Mode 0 for pin n */ |
912 | #define AR5K_GPIOCR_OUT0(n) (1 << ((n) * 2)) /* Mode 1 for pin n */ | 934 | #define AR5K_GPIOCR_OUT0(n) (1 << ((n) * 2)) /* Mode 1 for pin n */ |
913 | #define AR5K_GPIOCR_OUT1(n) (2 << ((n) * 2)) /* Mode 2 for pin n */ | 935 | #define AR5K_GPIOCR_OUT1(n) (2 << ((n) * 2)) /* Mode 2 for pin n */ |
@@ -925,7 +947,6 @@ | |||
925 | #define AR5K_GPIODI 0x401c | 947 | #define AR5K_GPIODI 0x401c |
926 | #define AR5K_GPIODI_M 0x0000002f | 948 | #define AR5K_GPIODI_M 0x0000002f |
927 | 949 | ||
928 | |||
929 | /* | 950 | /* |
930 | * Silicon revision register | 951 | * Silicon revision register |
931 | */ | 952 | */ |
@@ -935,7 +956,59 @@ | |||
935 | #define AR5K_SREV_VER 0x000000ff /* Mask for version */ | 956 | #define AR5K_SREV_VER 0x000000ff /* Mask for version */ |
936 | #define AR5K_SREV_VER_S 4 | 957 | #define AR5K_SREV_VER_S 4 |
937 | 958 | ||
959 | /* | ||
960 | * TXE write posting register | ||
961 | */ | ||
962 | #define AR5K_TXEPOST 0x4028 | ||
963 | |||
964 | /* | ||
965 | * QCU sleep mask | ||
966 | */ | ||
967 | #define AR5K_QCU_SLEEP_MASK 0x402c | ||
968 | |||
969 | /* 0x4068 is compression buffer configuration | ||
970 | * register on 5414 and pm configuration register | ||
971 | * on 5424 and newer pci-e chips. */ | ||
972 | |||
973 | /* | ||
974 | * Compression buffer configuration | ||
975 | * register (enable/disable) [5414] | ||
976 | */ | ||
977 | #define AR5K_5414_CBCFG 0x4068 | ||
978 | #define AR5K_5414_CBCFG_BUF_DIS 0x10 /* Disable buffer */ | ||
979 | |||
980 | /* | ||
981 | * PCI-E Power managment configuration | ||
982 | * and status register [5424+] | ||
983 | */ | ||
984 | #define AR5K_PCIE_PM_CTL 0x4068 /* Register address */ | ||
985 | /* Only 5424 */ | ||
986 | #define AR5K_PCIE_PM_CTL_L1_WHEN_D2 0x00000001 /* enable PCIe core enter L1 | ||
987 | when d2_sleep_en is asserted */ | ||
988 | #define AR5K_PCIE_PM_CTL_L0_L0S_CLEAR 0x00000002 /* Clear L0 and L0S counters */ | ||
989 | #define AR5K_PCIE_PM_CTL_L0_L0S_EN 0x00000004 /* Start L0 nd L0S counters */ | ||
990 | #define AR5K_PCIE_PM_CTL_LDRESET_EN 0x00000008 /* Enable reset when link goes | ||
991 | down */ | ||
992 | /* Wake On Wireless */ | ||
993 | #define AR5K_PCIE_PM_CTL_PME_EN 0x00000010 /* PME Enable */ | ||
994 | #define AR5K_PCIE_PM_CTL_AUX_PWR_DET 0x00000020 /* Aux power detect */ | ||
995 | #define AR5K_PCIE_PM_CTL_PME_CLEAR 0x00000040 /* Clear PME */ | ||
996 | #define AR5K_PCIE_PM_CTL_PSM_D0 0x00000080 | ||
997 | #define AR5K_PCIE_PM_CTL_PSM_D1 0x00000100 | ||
998 | #define AR5K_PCIE_PM_CTL_PSM_D2 0x00000200 | ||
999 | #define AR5K_PCIE_PM_CTL_PSM_D3 0x00000400 | ||
1000 | |||
1001 | /* | ||
1002 | * PCI-E Workaround enable register | ||
1003 | */ | ||
1004 | #define AR5K_PCIE_WAEN 0x407c | ||
938 | 1005 | ||
1006 | /* | ||
1007 | * PCI-E Serializer/Desirializer | ||
1008 | * registers | ||
1009 | */ | ||
1010 | #define AR5K_PCIE_SERDES 0x4080 | ||
1011 | #define AR5K_PCIE_SERDES_RESET 0x4084 | ||
939 | 1012 | ||
940 | /*====EEPROM REGISTERS====*/ | 1013 | /*====EEPROM REGISTERS====*/ |
941 | 1014 | ||
@@ -977,98 +1050,6 @@ | |||
977 | #define AR5K_EEPROM_BASE 0x6000 | 1050 | #define AR5K_EEPROM_BASE 0x6000 |
978 | 1051 | ||
979 | /* | 1052 | /* |
980 | * Common ar5xxx EEPROM data offsets (set these on AR5K_EEPROM_BASE) | ||
981 | */ | ||
982 | #define AR5K_EEPROM_MAGIC 0x003d /* EEPROM Magic number */ | ||
983 | #define AR5K_EEPROM_MAGIC_VALUE 0x5aa5 /* Default - found on EEPROM */ | ||
984 | #define AR5K_EEPROM_MAGIC_5212 0x0000145c /* 5212 */ | ||
985 | #define AR5K_EEPROM_MAGIC_5211 0x0000145b /* 5211 */ | ||
986 | #define AR5K_EEPROM_MAGIC_5210 0x0000145a /* 5210 */ | ||
987 | |||
988 | #define AR5K_EEPROM_PROTECT 0x003f /* EEPROM protect status */ | ||
989 | #define AR5K_EEPROM_PROTECT_RD_0_31 0x0001 /* Read protection bit for offsets 0x0 - 0x1f */ | ||
990 | #define AR5K_EEPROM_PROTECT_WR_0_31 0x0002 /* Write protection bit for offsets 0x0 - 0x1f */ | ||
991 | #define AR5K_EEPROM_PROTECT_RD_32_63 0x0004 /* 0x20 - 0x3f */ | ||
992 | #define AR5K_EEPROM_PROTECT_WR_32_63 0x0008 | ||
993 | #define AR5K_EEPROM_PROTECT_RD_64_127 0x0010 /* 0x40 - 0x7f */ | ||
994 | #define AR5K_EEPROM_PROTECT_WR_64_127 0x0020 | ||
995 | #define AR5K_EEPROM_PROTECT_RD_128_191 0x0040 /* 0x80 - 0xbf (regdom) */ | ||
996 | #define AR5K_EEPROM_PROTECT_WR_128_191 0x0080 | ||
997 | #define AR5K_EEPROM_PROTECT_RD_192_207 0x0100 /* 0xc0 - 0xcf */ | ||
998 | #define AR5K_EEPROM_PROTECT_WR_192_207 0x0200 | ||
999 | #define AR5K_EEPROM_PROTECT_RD_208_223 0x0400 /* 0xd0 - 0xdf */ | ||
1000 | #define AR5K_EEPROM_PROTECT_WR_208_223 0x0800 | ||
1001 | #define AR5K_EEPROM_PROTECT_RD_224_239 0x1000 /* 0xe0 - 0xef */ | ||
1002 | #define AR5K_EEPROM_PROTECT_WR_224_239 0x2000 | ||
1003 | #define AR5K_EEPROM_PROTECT_RD_240_255 0x4000 /* 0xf0 - 0xff */ | ||
1004 | #define AR5K_EEPROM_PROTECT_WR_240_255 0x8000 | ||
1005 | #define AR5K_EEPROM_REG_DOMAIN 0x00bf /* EEPROM regdom */ | ||
1006 | #define AR5K_EEPROM_INFO_BASE 0x00c0 /* EEPROM header */ | ||
1007 | #define AR5K_EEPROM_INFO_MAX (0x400 - AR5K_EEPROM_INFO_BASE) | ||
1008 | #define AR5K_EEPROM_INFO_CKSUM 0xffff | ||
1009 | #define AR5K_EEPROM_INFO(_n) (AR5K_EEPROM_INFO_BASE + (_n)) | ||
1010 | |||
1011 | #define AR5K_EEPROM_VERSION AR5K_EEPROM_INFO(1) /* EEPROM Version */ | ||
1012 | #define AR5K_EEPROM_VERSION_3_0 0x3000 /* No idea what's going on before this version */ | ||
1013 | #define AR5K_EEPROM_VERSION_3_1 0x3001 /* ob/db values for 2Ghz (ar5211_rfregs) */ | ||
1014 | #define AR5K_EEPROM_VERSION_3_2 0x3002 /* different frequency representation (eeprom_bin2freq) */ | ||
1015 | #define AR5K_EEPROM_VERSION_3_3 0x3003 /* offsets changed, has 32 CTLs (see below) and ee_false_detect (eeprom_read_modes) */ | ||
1016 | #define AR5K_EEPROM_VERSION_3_4 0x3004 /* has ee_i_gain ee_cck_ofdm_power_delta (eeprom_read_modes) */ | ||
1017 | #define AR5K_EEPROM_VERSION_4_0 0x4000 /* has ee_misc*, ee_cal_pier, ee_turbo_max_power and ee_xr_power (eeprom_init) */ | ||
1018 | #define AR5K_EEPROM_VERSION_4_1 0x4001 /* has ee_margin_tx_rx (eeprom_init) */ | ||
1019 | #define AR5K_EEPROM_VERSION_4_2 0x4002 /* has ee_cck_ofdm_gain_delta (eeprom_init) */ | ||
1020 | #define AR5K_EEPROM_VERSION_4_3 0x4003 | ||
1021 | #define AR5K_EEPROM_VERSION_4_4 0x4004 | ||
1022 | #define AR5K_EEPROM_VERSION_4_5 0x4005 | ||
1023 | #define AR5K_EEPROM_VERSION_4_6 0x4006 /* has ee_scaled_cck_delta */ | ||
1024 | #define AR5K_EEPROM_VERSION_4_7 0x4007 | ||
1025 | |||
1026 | #define AR5K_EEPROM_MODE_11A 0 | ||
1027 | #define AR5K_EEPROM_MODE_11B 1 | ||
1028 | #define AR5K_EEPROM_MODE_11G 2 | ||
1029 | |||
1030 | #define AR5K_EEPROM_HDR AR5K_EEPROM_INFO(2) /* Header that contains the device caps */ | ||
1031 | #define AR5K_EEPROM_HDR_11A(_v) (((_v) >> AR5K_EEPROM_MODE_11A) & 0x1) | ||
1032 | #define AR5K_EEPROM_HDR_11B(_v) (((_v) >> AR5K_EEPROM_MODE_11B) & 0x1) | ||
1033 | #define AR5K_EEPROM_HDR_11G(_v) (((_v) >> AR5K_EEPROM_MODE_11G) & 0x1) | ||
1034 | #define AR5K_EEPROM_HDR_T_2GHZ_DIS(_v) (((_v) >> 3) & 0x1) /* Disable turbo for 2Ghz (?) */ | ||
1035 | #define AR5K_EEPROM_HDR_T_5GHZ_DBM(_v) (((_v) >> 4) & 0x7f) /* Max turbo power for a/XR mode (eeprom_init) */ | ||
1036 | #define AR5K_EEPROM_HDR_DEVICE(_v) (((_v) >> 11) & 0x7) | ||
1037 | #define AR5K_EEPROM_HDR_T_5GHZ_DIS(_v) (((_v) >> 15) & 0x1) /* Disable turbo for 5Ghz (?) */ | ||
1038 | #define AR5K_EEPROM_HDR_RFKILL(_v) (((_v) >> 14) & 0x1) /* Device has RFKill support */ | ||
1039 | |||
1040 | #define AR5K_EEPROM_RFKILL_GPIO_SEL 0x0000001c | ||
1041 | #define AR5K_EEPROM_RFKILL_GPIO_SEL_S 2 | ||
1042 | #define AR5K_EEPROM_RFKILL_POLARITY 0x00000002 | ||
1043 | #define AR5K_EEPROM_RFKILL_POLARITY_S 1 | ||
1044 | |||
1045 | /* Newer EEPROMs are using a different offset */ | ||
1046 | #define AR5K_EEPROM_OFF(_v, _v3_0, _v3_3) \ | ||
1047 | (((_v) >= AR5K_EEPROM_VERSION_3_3) ? _v3_3 : _v3_0) | ||
1048 | |||
1049 | #define AR5K_EEPROM_ANT_GAIN(_v) AR5K_EEPROM_OFF(_v, 0x00c4, 0x00c3) | ||
1050 | #define AR5K_EEPROM_ANT_GAIN_5GHZ(_v) ((int8_t)(((_v) >> 8) & 0xff)) | ||
1051 | #define AR5K_EEPROM_ANT_GAIN_2GHZ(_v) ((int8_t)((_v) & 0xff)) | ||
1052 | |||
1053 | /* calibration settings */ | ||
1054 | #define AR5K_EEPROM_MODES_11A(_v) AR5K_EEPROM_OFF(_v, 0x00c5, 0x00d4) | ||
1055 | #define AR5K_EEPROM_MODES_11B(_v) AR5K_EEPROM_OFF(_v, 0x00d0, 0x00f2) | ||
1056 | #define AR5K_EEPROM_MODES_11G(_v) AR5K_EEPROM_OFF(_v, 0x00da, 0x010d) | ||
1057 | #define AR5K_EEPROM_CTL(_v) AR5K_EEPROM_OFF(_v, 0x00e4, 0x0128) /* Conformance test limits */ | ||
1058 | |||
1059 | /* [3.1 - 3.3] */ | ||
1060 | #define AR5K_EEPROM_OBDB0_2GHZ 0x00ec | ||
1061 | #define AR5K_EEPROM_OBDB1_2GHZ 0x00ed | ||
1062 | |||
1063 | /* Misc values available since EEPROM 4.0 */ | ||
1064 | #define AR5K_EEPROM_MISC0 0x00c4 | ||
1065 | #define AR5K_EEPROM_EARSTART(_v) ((_v) & 0xfff) | ||
1066 | #define AR5K_EEPROM_EEMAP(_v) (((_v) >> 14) & 0x3) | ||
1067 | #define AR5K_EEPROM_MISC1 0x00c5 | ||
1068 | #define AR5K_EEPROM_TARGET_PWRSTART(_v) ((_v) & 0xfff) | ||
1069 | #define AR5K_EEPROM_HAS32KHZCRYSTAL(_v) (((_v) >> 14) & 0x1) | ||
1070 | |||
1071 | /* | ||
1072 | * EEPROM data register | 1053 | * EEPROM data register |
1073 | */ | 1054 | */ |
1074 | #define AR5K_EEPROM_DATA_5211 0x6004 | 1055 | #define AR5K_EEPROM_DATA_5211 0x6004 |
@@ -1100,14 +1081,28 @@ | |||
1100 | * EEPROM config register | 1081 | * EEPROM config register |
1101 | */ | 1082 | */ |
1102 | #define AR5K_EEPROM_CFG 0x6010 /* Register Addres */ | 1083 | #define AR5K_EEPROM_CFG 0x6010 /* Register Addres */ |
1103 | #define AR5K_EEPROM_CFG_SIZE_OVR 0x00000001 | 1084 | #define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */ |
1085 | #define AR5K_EEPROM_CFG_SIZE_AUTO 0 | ||
1086 | #define AR5K_EEPROM_CFG_SIZE_4KBIT 1 | ||
1087 | #define AR5K_EEPROM_CFG_SIZE_8KBIT 2 | ||
1088 | #define AR5K_EEPROM_CFG_SIZE_16KBIT 3 | ||
1104 | #define AR5K_EEPROM_CFG_WR_WAIT_DIS 0x00000004 /* Disable write wait */ | 1089 | #define AR5K_EEPROM_CFG_WR_WAIT_DIS 0x00000004 /* Disable write wait */ |
1105 | #define AR5K_EEPROM_CFG_CLK_RATE 0x00000018 /* Clock rate */ | 1090 | #define AR5K_EEPROM_CFG_CLK_RATE 0x00000018 /* Clock rate */ |
1106 | #define AR5K_EEPROM_CFG_PROT_KEY 0x00ffff00 /* Protectio key */ | 1091 | #define AR5K_EEPROM_CFG_CLK_RATE_S 3 |
1092 | #define AR5K_EEPROM_CFG_CLK_RATE_156KHZ 0 | ||
1093 | #define AR5K_EEPROM_CFG_CLK_RATE_312KHZ 1 | ||
1094 | #define AR5K_EEPROM_CFG_CLK_RATE_625KHZ 2 | ||
1095 | #define AR5K_EEPROM_CFG_PROT_KEY 0x00ffff00 /* Protection key */ | ||
1096 | #define AR5K_EEPROM_CFG_PROT_KEY_S 8 | ||
1107 | #define AR5K_EEPROM_CFG_LIND_EN 0x01000000 /* Enable length indicator (?) */ | 1097 | #define AR5K_EEPROM_CFG_LIND_EN 0x01000000 /* Enable length indicator (?) */ |
1108 | 1098 | ||
1109 | 1099 | ||
1110 | /* | 1100 | /* |
1101 | * TODO: Wake On Wireless registers | ||
1102 | * Range 0x7000 - 0x7ce0 | ||
1103 | */ | ||
1104 | |||
1105 | /* | ||
1111 | * Protocol Control Unit (PCU) registers | 1106 | * Protocol Control Unit (PCU) registers |
1112 | */ | 1107 | */ |
1113 | /* | 1108 | /* |
@@ -1139,11 +1134,13 @@ | |||
1139 | #define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */ | 1134 | #define AR5K_STA_ID1_DESC_ANTENNA 0x00400000 /* Update antenna from descriptor */ |
1140 | #define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */ | 1135 | #define AR5K_STA_ID1_RTS_DEF_ANTENNA 0x00800000 /* Use default antenna for RTS */ |
1141 | #define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Use 6Mbit/s for ACK/CTS */ | 1136 | #define AR5K_STA_ID1_ACKCTS_6MB 0x01000000 /* Use 6Mbit/s for ACK/CTS */ |
1142 | #define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate (for ACK/CTS ?) [5211+] */ | 1137 | #define AR5K_STA_ID1_BASE_RATE_11B 0x02000000 /* Use 11b base rate for ACK/CTS [5211+] */ |
1143 | #define AR5K_STA_ID1_SELF_GEN_SECTORE 0x04000000 /* Self generate sectore (?) */ | 1138 | #define AR5K_STA_ID1_SELFGEN_DEF_ANT 0x04000000 /* Use def. antenna for self generated frames */ |
1144 | #define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */ | 1139 | #define AR5K_STA_ID1_CRYPT_MIC_EN 0x08000000 /* Enable MIC */ |
1145 | #define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Keysearch mode (?) */ | 1140 | #define AR5K_STA_ID1_KEYSRCH_MODE 0x10000000 /* Look up key when key id != 0 */ |
1146 | #define AR5K_STA_ID1_PRESERVE_SEQ_NUM 0x20000000 /* Preserve sequence number */ | 1141 | #define AR5K_STA_ID1_PRESERVE_SEQ_NUM 0x20000000 /* Preserve sequence number */ |
1142 | #define AR5K_STA_ID1_CBCIV_ENDIAN 0x40000000 /* ??? */ | ||
1143 | #define AR5K_STA_ID1_KEYSRCH_MCAST 0x80000000 /* Do key cache search for mcast frames */ | ||
1147 | 1144 | ||
1148 | /* | 1145 | /* |
1149 | * First BSSID register (MAC address, lower 32bits) | 1146 | * First BSSID register (MAC address, lower 32bits) |
@@ -1402,16 +1399,16 @@ | |||
1402 | #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 | 1399 | #define AR5K_DIAG_SW_LOOP_BACK_5211 0x00000040 |
1403 | #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ | 1400 | #define AR5K_DIAG_SW_LOOP_BACK (ah->ah_version == AR5K_AR5210 ? \ |
1404 | AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) | 1401 | AR5K_DIAG_SW_LOOP_BACK_5210 : AR5K_DIAG_SW_LOOP_BACK_5211) |
1405 | #define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 | 1402 | #define AR5K_DIAG_SW_CORR_FCS_5210 0x00000100 /* Corrupted FCS */ |
1406 | #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 | 1403 | #define AR5K_DIAG_SW_CORR_FCS_5211 0x00000080 |
1407 | #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ | 1404 | #define AR5K_DIAG_SW_CORR_FCS (ah->ah_version == AR5K_AR5210 ? \ |
1408 | AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) | 1405 | AR5K_DIAG_SW_CORR_FCS_5210 : AR5K_DIAG_SW_CORR_FCS_5211) |
1409 | #define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 | 1406 | #define AR5K_DIAG_SW_CHAN_INFO_5210 0x00000200 /* Dump channel info */ |
1410 | #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 | 1407 | #define AR5K_DIAG_SW_CHAN_INFO_5211 0x00000100 |
1411 | #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ | 1408 | #define AR5K_DIAG_SW_CHAN_INFO (ah->ah_version == AR5K_AR5210 ? \ |
1412 | AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) | 1409 | AR5K_DIAG_SW_CHAN_INFO_5210 : AR5K_DIAG_SW_CHAN_INFO_5211) |
1413 | #define AR5K_DIAG_SW_EN_SCRAM_SEED_5211 0x00000200 /* Enable scrambler seed */ | 1410 | #define AR5K_DIAG_SW_EN_SCRAM_SEED_5210 0x00000400 /* Enable fixed scrambler seed */ |
1414 | #define AR5K_DIAG_SW_EN_SCRAM_SEED_5210 0x00000400 | 1411 | #define AR5K_DIAG_SW_EN_SCRAM_SEED_5211 0x00000200 |
1415 | #define AR5K_DIAG_SW_EN_SCRAM_SEED (ah->ah_version == AR5K_AR5210 ? \ | 1412 | #define AR5K_DIAG_SW_EN_SCRAM_SEED (ah->ah_version == AR5K_AR5210 ? \ |
1416 | AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211) | 1413 | AR5K_DIAG_SW_EN_SCRAM_SEED_5210 : AR5K_DIAG_SW_EN_SCRAM_SEED_5211) |
1417 | #define AR5K_DIAG_SW_ECO_ENABLE 0x00000400 /* [5211+] */ | 1414 | #define AR5K_DIAG_SW_ECO_ENABLE 0x00000400 /* [5211+] */ |
@@ -1420,12 +1417,15 @@ | |||
1420 | #define AR5K_DIAG_SW_SCRAM_SEED_S 10 | 1417 | #define AR5K_DIAG_SW_SCRAM_SEED_S 10 |
1421 | #define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */ | 1418 | #define AR5K_DIAG_SW_DIS_SEQ_INC 0x00040000 /* Disable seqnum increment (?)[5210] */ |
1422 | #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 | 1419 | #define AR5K_DIAG_SW_FRAME_NV0_5210 0x00080000 |
1423 | #define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 | 1420 | #define AR5K_DIAG_SW_FRAME_NV0_5211 0x00020000 /* Accept frames of non-zero protocol number */ |
1424 | #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ | 1421 | #define AR5K_DIAG_SW_FRAME_NV0 (ah->ah_version == AR5K_AR5210 ? \ |
1425 | AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) | 1422 | AR5K_DIAG_SW_FRAME_NV0_5210 : AR5K_DIAG_SW_FRAME_NV0_5211) |
1426 | #define AR5K_DIAG_SW_OBSPT_M 0x000c0000 | 1423 | #define AR5K_DIAG_SW_OBSPT_M 0x000c0000 /* Observation point select (?) */ |
1427 | #define AR5K_DIAG_SW_OBSPT_S 18 | 1424 | #define AR5K_DIAG_SW_OBSPT_S 18 |
1428 | /* more bits */ | 1425 | #define AR5K_DIAG_SW_RX_CLEAR_HIGH 0x0010000 /* Force RX Clear high */ |
1426 | #define AR5K_DIAG_SW_IGNORE_CARR_SENSE 0x0020000 /* Ignore virtual carrier sense */ | ||
1427 | #define AR5K_DIAG_SW_CHANEL_IDLE_HIGH 0x0040000 /* Force channel idle high */ | ||
1428 | #define AR5K_DIAG_SW_PHEAR_ME 0x0080000 /* ??? */ | ||
1429 | 1429 | ||
1430 | /* | 1430 | /* |
1431 | * TSF (clock) register (lower 32 bits) | 1431 | * TSF (clock) register (lower 32 bits) |
@@ -1636,16 +1636,16 @@ | |||
1636 | * | 1636 | * |
1637 | * XXX: PCDAC steps (0.5dbm) or DBM ? | 1637 | * XXX: PCDAC steps (0.5dbm) or DBM ? |
1638 | * | 1638 | * |
1639 | * XXX: Mask changes for newer chips to 7f | ||
1640 | * like tx power table ? | ||
1641 | */ | 1639 | */ |
1642 | #define AR5K_TXPC 0x80e8 /* Register Address */ | 1640 | #define AR5K_TXPC 0x80e8 /* Register Address */ |
1643 | #define AR5K_TXPC_ACK_M 0x0000003f /* Mask for ACK tx power */ | 1641 | #define AR5K_TXPC_ACK_M 0x0000003f /* ACK tx power */ |
1644 | #define AR5K_TXPC_ACK_S 0 | 1642 | #define AR5K_TXPC_ACK_S 0 |
1645 | #define AR5K_TXPC_CTS_M 0x00003f00 /* Mask for CTS tx power */ | 1643 | #define AR5K_TXPC_CTS_M 0x00003f00 /* CTS tx power */ |
1646 | #define AR5K_TXPC_CTS_S 8 | 1644 | #define AR5K_TXPC_CTS_S 8 |
1647 | #define AR5K_TXPC_CHIRP_M 0x003f0000 /* Mask for CHIRP tx power */ | 1645 | #define AR5K_TXPC_CHIRP_M 0x003f0000 /* CHIRP tx power */ |
1648 | #define AR5K_TXPC_CHIRP_S 22 | 1646 | #define AR5K_TXPC_CHIRP_S 16 |
1647 | #define AR5K_TXPC_DOPPLER 0x0f000000 /* Doppler chirp span (?) */ | ||
1648 | #define AR5K_TXPC_DOPPLER_S 24 | ||
1649 | 1649 | ||
1650 | /* | 1650 | /* |
1651 | * Profile count registers | 1651 | * Profile count registers |
@@ -1656,14 +1656,19 @@ | |||
1656 | #define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */ | 1656 | #define AR5K_PROFCNT_CYCLE 0x80f8 /* Cycle count (?) */ |
1657 | 1657 | ||
1658 | /* | 1658 | /* |
1659 | * Quiet (period) control registers (?) | 1659 | * Quiet period control registers |
1660 | */ | 1660 | */ |
1661 | #define AR5K_QUIET_CTL1 0x80fc /* Register Address */ | 1661 | #define AR5K_QUIET_CTL1 0x80fc /* Register Address */ |
1662 | #define AR5K_QUIET_CTL1_NEXT_QT 0x0000ffff /* Mask for next quiet (period?) (?) */ | 1662 | #define AR5K_QUIET_CTL1_NEXT_QT_TSF 0x0000ffff /* Next quiet period TSF (TU) */ |
1663 | #define AR5K_QUIET_CTL1_QT_EN 0x00010000 /* Enable quiet (period?) */ | 1663 | #define AR5K_QUIET_CTL1_NEXT_QT_TSF_S 0 |
1664 | #define AR5K_QUIET_CTL1_QT_EN 0x00010000 /* Enable quiet period */ | ||
1665 | #define AR5K_QUIET_CTL1_ACK_CTS_EN 0x00020000 /* Send ACK/CTS during quiet period */ | ||
1666 | |||
1664 | #define AR5K_QUIET_CTL2 0x8100 /* Register Address */ | 1667 | #define AR5K_QUIET_CTL2 0x8100 /* Register Address */ |
1665 | #define AR5K_QUIET_CTL2_QT_PER 0x0000ffff /* Mask for quiet period (?) */ | 1668 | #define AR5K_QUIET_CTL2_QT_PER 0x0000ffff /* Mask for quiet period periodicity */ |
1666 | #define AR5K_QUIET_CTL2_QT_DUR 0xffff0000 /* Mask for quiet duration (?) */ | 1669 | #define AR5K_QUIET_CTL2_QT_PER_S 0 |
1670 | #define AR5K_QUIET_CTL2_QT_DUR 0xffff0000 /* Mask for quiet period duration */ | ||
1671 | #define AR5K_QUIET_CTL2_QT_DUR_S 16 | ||
1667 | 1672 | ||
1668 | /* | 1673 | /* |
1669 | * TSF parameter register | 1674 | * TSF parameter register |
@@ -1673,12 +1678,15 @@ | |||
1673 | #define AR5K_TSF_PARM_INC_S 0 | 1678 | #define AR5K_TSF_PARM_INC_S 0 |
1674 | 1679 | ||
1675 | /* | 1680 | /* |
1676 | * QoS register (?) | 1681 | * QoS NOACK policy |
1677 | */ | 1682 | */ |
1678 | #define AR5K_QOS 0x8108 /* Register Address */ | 1683 | #define AR5K_QOS_NOACK 0x8108 /* Register Address */ |
1679 | #define AR5K_QOS_NOACK_2BIT_VALUES 0x00000000 /* (field) */ | 1684 | #define AR5K_QOS_NOACK_2BIT_VALUES 0x0000000f /* ??? */ |
1680 | #define AR5K_QOS_NOACK_BIT_OFFSET 0x00000020 /* (field) */ | 1685 | #define AR5K_QOS_NOACK_2BIT_VALUES_S 0 |
1681 | #define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000080 /* (field) */ | 1686 | #define AR5K_QOS_NOACK_BIT_OFFSET 0x00000070 /* ??? */ |
1687 | #define AR5K_QOS_NOACK_BIT_OFFSET_S 4 | ||
1688 | #define AR5K_QOS_NOACK_BYTE_OFFSET 0x00000180 /* ??? */ | ||
1689 | #define AR5K_QOS_NOACK_BYTE_OFFSET_S 8 | ||
1682 | 1690 | ||
1683 | /* | 1691 | /* |
1684 | * PHY error filter register | 1692 | * PHY error filter register |
@@ -1702,29 +1710,15 @@ | |||
1702 | /* | 1710 | /* |
1703 | * MIC QoS control register (?) | 1711 | * MIC QoS control register (?) |
1704 | */ | 1712 | */ |
1705 | #define AR5K_MIC_QOS_CTL 0x8118 /* Register Address */ | 1713 | #define AR5K_MIC_QOS_CTL 0x8118 /* Register Address */ |
1706 | #define AR5K_MIC_QOS_CTL_0 0x00000001 /* MIC QoS control 0 (?) */ | 1714 | #define AR5K_MIC_QOS_CTL_OFF(_n) (1 << (_n * 2)) |
1707 | #define AR5K_MIC_QOS_CTL_1 0x00000004 /* MIC QoS control 1 (?) */ | 1715 | #define AR5K_MIC_QOS_CTL_MQ_EN 0x00010000 /* Enable MIC QoS */ |
1708 | #define AR5K_MIC_QOS_CTL_2 0x00000010 /* MIC QoS control 2 (?) */ | ||
1709 | #define AR5K_MIC_QOS_CTL_3 0x00000040 /* MIC QoS control 3 (?) */ | ||
1710 | #define AR5K_MIC_QOS_CTL_4 0x00000100 /* MIC QoS control 4 (?) */ | ||
1711 | #define AR5K_MIC_QOS_CTL_5 0x00000400 /* MIC QoS control 5 (?) */ | ||
1712 | #define AR5K_MIC_QOS_CTL_6 0x00001000 /* MIC QoS control 6 (?) */ | ||
1713 | #define AR5K_MIC_QOS_CTL_7 0x00004000 /* MIC QoS control 7 (?) */ | ||
1714 | #define AR5K_MIC_QOS_CTL_MQ_EN 0x00010000 /* Enable MIC QoS */ | ||
1715 | 1716 | ||
1716 | /* | 1717 | /* |
1717 | * MIC QoS select register (?) | 1718 | * MIC QoS select register (?) |
1718 | */ | 1719 | */ |
1719 | #define AR5K_MIC_QOS_SEL 0x811c | 1720 | #define AR5K_MIC_QOS_SEL 0x811c |
1720 | #define AR5K_MIC_QOS_SEL_0 0x00000001 | 1721 | #define AR5K_MIC_QOS_SEL_OFF(_n) (1 << (_n * 4)) |
1721 | #define AR5K_MIC_QOS_SEL_1 0x00000010 | ||
1722 | #define AR5K_MIC_QOS_SEL_2 0x00000100 | ||
1723 | #define AR5K_MIC_QOS_SEL_3 0x00001000 | ||
1724 | #define AR5K_MIC_QOS_SEL_4 0x00010000 | ||
1725 | #define AR5K_MIC_QOS_SEL_5 0x00100000 | ||
1726 | #define AR5K_MIC_QOS_SEL_6 0x01000000 | ||
1727 | #define AR5K_MIC_QOS_SEL_7 0x10000000 | ||
1728 | 1722 | ||
1729 | /* | 1723 | /* |
1730 | * Misc mode control register (?) | 1724 | * Misc mode control register (?) |
@@ -1759,6 +1753,11 @@ | |||
1759 | #define AR5K_TSF_THRES 0x813c | 1753 | #define AR5K_TSF_THRES 0x813c |
1760 | 1754 | ||
1761 | /* | 1755 | /* |
1756 | * TODO: Wake On Wireless registers | ||
1757 | * Range: 0x8147 - 0x818c | ||
1758 | */ | ||
1759 | |||
1760 | /* | ||
1762 | * Rate -> ACK SIFS mapping table (32 entries) | 1761 | * Rate -> ACK SIFS mapping table (32 entries) |
1763 | */ | 1762 | */ |
1764 | #define AR5K_RATE_ACKSIFS_BASE 0x8680 /* Register Address */ | 1763 | #define AR5K_RATE_ACKSIFS_BASE 0x8680 /* Register Address */ |
@@ -1873,7 +1872,8 @@ | |||
1873 | */ | 1872 | */ |
1874 | #define AR5K_PHY_TURBO 0x9804 /* Register Address */ | 1873 | #define AR5K_PHY_TURBO 0x9804 /* Register Address */ |
1875 | #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ | 1874 | #define AR5K_PHY_TURBO_MODE 0x00000001 /* Enable turbo mode */ |
1876 | #define AR5K_PHY_TURBO_SHORT 0x00000002 /* Short mode (20Mhz channels) (?) */ | 1875 | #define AR5K_PHY_TURBO_SHORT 0x00000002 /* Set short symbols to turbo mode */ |
1876 | #define AR5K_PHY_TURBO_MIMO 0x00000004 /* Set turbo for mimo mimo */ | ||
1877 | 1877 | ||
1878 | /* | 1878 | /* |
1879 | * PHY agility command register | 1879 | * PHY agility command register |
@@ -1883,6 +1883,11 @@ | |||
1883 | #define AR5K_PHY_TST1 0x9808 | 1883 | #define AR5K_PHY_TST1 0x9808 |
1884 | #define AR5K_PHY_AGC_DISABLE 0x08000000 /* Disable AGC to A2 (?)*/ | 1884 | #define AR5K_PHY_AGC_DISABLE 0x08000000 /* Disable AGC to A2 (?)*/ |
1885 | #define AR5K_PHY_TST1_TXHOLD 0x00003800 /* Set tx hold (?) */ | 1885 | #define AR5K_PHY_TST1_TXHOLD 0x00003800 /* Set tx hold (?) */ |
1886 | #define AR5K_PHY_TST1_TXSRC_SRC 0x00000002 /* Used with bit 7 (?) */ | ||
1887 | #define AR5K_PHY_TST1_TXSRC_SRC_S 1 | ||
1888 | #define AR5K_PHY_TST1_TXSRC_ALT 0x00000080 /* Set input to tsdac (?) */ | ||
1889 | #define AR5K_PHY_TST1_TXSRC_ALT_S 7 | ||
1890 | |||
1886 | 1891 | ||
1887 | /* | 1892 | /* |
1888 | * PHY timing register 3 [5112+] | 1893 | * PHY timing register 3 [5112+] |
@@ -1907,15 +1912,23 @@ | |||
1907 | 1912 | ||
1908 | /* | 1913 | /* |
1909 | * PHY RF control registers | 1914 | * PHY RF control registers |
1910 | * (i think these are delay times, | ||
1911 | * these calibration values exist | ||
1912 | * in EEPROM) | ||
1913 | */ | 1915 | */ |
1914 | #define AR5K_PHY_RF_CTL2 0x9824 /* Register Address */ | 1916 | #define AR5K_PHY_RF_CTL2 0x9824 /* Register Address */ |
1915 | #define AR5K_PHY_RF_CTL2_TXF2TXD_START 0x0000000f /* Mask for TX frame to TX d(esc?) start */ | 1917 | #define AR5K_PHY_RF_CTL2_TXF2TXD_START 0x0000000f /* TX frame to TX data start */ |
1918 | #define AR5K_PHY_RF_CTL2_TXF2TXD_START_S 0 | ||
1916 | 1919 | ||
1917 | #define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */ | 1920 | #define AR5K_PHY_RF_CTL3 0x9828 /* Register Address */ |
1918 | #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000000f /* Mask for TX end to XLNA on */ | 1921 | #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON 0x0000000f /* TX end to XLNA on */ |
1922 | #define AR5K_PHY_RF_CTL3_TXE2XLNA_ON_S 0 | ||
1923 | |||
1924 | #define AR5K_PHY_ADC_CTL 0x982c | ||
1925 | #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF 0x00000003 | ||
1926 | #define AR5K_PHY_ADC_CTL_INBUFGAIN_OFF_S 0 | ||
1927 | #define AR5K_PHY_ADC_CTL_PWD_DAC_OFF 0x00002000 | ||
1928 | #define AR5K_PHY_ADC_CTL_PWD_BAND_GAP_OFF 0x00004000 | ||
1929 | #define AR5K_PHY_ADC_CTL_PWD_ADC_OFF 0x00008000 | ||
1930 | #define AR5K_PHY_ADC_CTL_INBUFGAIN_ON 0x00030000 | ||
1931 | #define AR5K_PHY_ADC_CTL_INBUFGAIN_ON_S 16 | ||
1919 | 1932 | ||
1920 | #define AR5K_PHY_RF_CTL4 0x9834 /* Register Address */ | 1933 | #define AR5K_PHY_RF_CTL4 0x9834 /* Register Address */ |
1921 | #define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON 0x00000001 /* TX frame to XPA A on (field) */ | 1934 | #define AR5K_PHY_RF_CTL4_TXF2XPA_A_ON 0x00000001 /* TX frame to XPA A on (field) */ |
@@ -1937,35 +1950,43 @@ | |||
1937 | * PHY settling register | 1950 | * PHY settling register |
1938 | */ | 1951 | */ |
1939 | #define AR5K_PHY_SETTLING 0x9844 /* Register Address */ | 1952 | #define AR5K_PHY_SETTLING 0x9844 /* Register Address */ |
1940 | #define AR5K_PHY_SETTLING_AGC 0x0000007f /* Mask for AGC settling time */ | 1953 | #define AR5K_PHY_SETTLING_AGC 0x0000007f /* AGC settling time */ |
1941 | #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Mask for Switch settlig time */ | 1954 | #define AR5K_PHY_SETTLING_AGC_S 0 |
1955 | #define AR5K_PHY_SETTLING_SWITCH 0x00003f80 /* Switch settlig time */ | ||
1956 | #define AR5K_PHY_SETTLINK_SWITCH_S 7 | ||
1942 | 1957 | ||
1943 | /* | 1958 | /* |
1944 | * PHY Gain registers | 1959 | * PHY Gain registers |
1945 | */ | 1960 | */ |
1946 | #define AR5K_PHY_GAIN 0x9848 /* Register Address */ | 1961 | #define AR5K_PHY_GAIN 0x9848 /* Register Address */ |
1947 | #define AR5K_PHY_GAIN_TXRX_ATTEN 0x0003f000 /* Mask for TX-RX Attenuation */ | 1962 | #define AR5K_PHY_GAIN_TXRX_ATTEN 0x0003f000 /* TX-RX Attenuation */ |
1963 | #define AR5K_PHY_GAIN_TXRX_ATTEN_S 12 | ||
1964 | #define AR5K_PHY_GAIN_TXRX_RF_MAX 0x007c0000 | ||
1965 | #define AR5K_PHY_GAIN_TXRX_RF_MAX_S 18 | ||
1948 | 1966 | ||
1949 | #define AR5K_PHY_GAIN_OFFSET 0x984c /* Register Address */ | 1967 | #define AR5K_PHY_GAIN_OFFSET 0x984c /* Register Address */ |
1950 | #define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */ | 1968 | #define AR5K_PHY_GAIN_OFFSET_RXTX_FLAG 0x00020000 /* RX-TX flag (?) */ |
1951 | 1969 | ||
1952 | /* | 1970 | /* |
1953 | * Desired size register | 1971 | * Desired ADC/PGA size register |
1954 | * (for more infos read ANI patent) | 1972 | * (for more infos read ANI patent) |
1955 | */ | 1973 | */ |
1956 | #define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */ | 1974 | #define AR5K_PHY_DESIRED_SIZE 0x9850 /* Register Address */ |
1957 | #define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* Mask for ADC desired size */ | 1975 | #define AR5K_PHY_DESIRED_SIZE_ADC 0x000000ff /* ADC desired size */ |
1958 | #define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* Mask for PGA desired size */ | 1976 | #define AR5K_PHY_DESIRED_SIZE_ADC_S 0 |
1959 | #define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Mask for Total desired size (?) */ | 1977 | #define AR5K_PHY_DESIRED_SIZE_PGA 0x0000ff00 /* PGA desired size */ |
1978 | #define AR5K_PHY_DESIRED_SIZE_PGA_S 8 | ||
1979 | #define AR5K_PHY_DESIRED_SIZE_TOT 0x0ff00000 /* Total desired size */ | ||
1980 | #define AR5K_PHY_DESIRED_SIZE_TOT_S 20 | ||
1960 | 1981 | ||
1961 | /* | 1982 | /* |
1962 | * PHY signal register | 1983 | * PHY signal register |
1963 | * (for more infos read ANI patent) | 1984 | * (for more infos read ANI patent) |
1964 | */ | 1985 | */ |
1965 | #define AR5K_PHY_SIG 0x9858 /* Register Address */ | 1986 | #define AR5K_PHY_SIG 0x9858 /* Register Address */ |
1966 | #define AR5K_PHY_SIG_FIRSTEP 0x0003f000 /* Mask for FIRSTEP */ | 1987 | #define AR5K_PHY_SIG_FIRSTEP 0x0003f000 /* FIRSTEP */ |
1967 | #define AR5K_PHY_SIG_FIRSTEP_S 12 | 1988 | #define AR5K_PHY_SIG_FIRSTEP_S 12 |
1968 | #define AR5K_PHY_SIG_FIRPWR 0x03fc0000 /* Mask for FIPWR */ | 1989 | #define AR5K_PHY_SIG_FIRPWR 0x03fc0000 /* FIPWR */ |
1969 | #define AR5K_PHY_SIG_FIRPWR_S 18 | 1990 | #define AR5K_PHY_SIG_FIRPWR_S 18 |
1970 | 1991 | ||
1971 | /* | 1992 | /* |
@@ -1973,9 +1994,9 @@ | |||
1973 | * (for more infos read ANI patent) | 1994 | * (for more infos read ANI patent) |
1974 | */ | 1995 | */ |
1975 | #define AR5K_PHY_AGCCOARSE 0x985c /* Register Address */ | 1996 | #define AR5K_PHY_AGCCOARSE 0x985c /* Register Address */ |
1976 | #define AR5K_PHY_AGCCOARSE_LO 0x00007f80 /* Mask for AGC Coarse low */ | 1997 | #define AR5K_PHY_AGCCOARSE_LO 0x00007f80 /* AGC Coarse low */ |
1977 | #define AR5K_PHY_AGCCOARSE_LO_S 7 | 1998 | #define AR5K_PHY_AGCCOARSE_LO_S 7 |
1978 | #define AR5K_PHY_AGCCOARSE_HI 0x003f8000 /* Mask for AGC Coarse high */ | 1999 | #define AR5K_PHY_AGCCOARSE_HI 0x003f8000 /* AGC Coarse high */ |
1979 | #define AR5K_PHY_AGCCOARSE_HI_S 15 | 2000 | #define AR5K_PHY_AGCCOARSE_HI_S 15 |
1980 | 2001 | ||
1981 | /* | 2002 | /* |
@@ -1984,6 +2005,8 @@ | |||
1984 | #define AR5K_PHY_AGCCTL 0x9860 /* Register address */ | 2005 | #define AR5K_PHY_AGCCTL 0x9860 /* Register address */ |
1985 | #define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */ | 2006 | #define AR5K_PHY_AGCCTL_CAL 0x00000001 /* Enable PHY calibration */ |
1986 | #define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */ | 2007 | #define AR5K_PHY_AGCCTL_NF 0x00000002 /* Enable Noise Floor calibration */ |
2008 | #define AR5K_PHY_AGCCTL_NF_EN 0x00008000 /* Enable nf calibration to happen (?) */ | ||
2009 | #define AR5K_PHY_AGCCTL_NF_NOUPDATE 0x00020000 /* Don't update nf automaticaly */ | ||
1987 | 2010 | ||
1988 | /* | 2011 | /* |
1989 | * PHY noise floor status register | 2012 | * PHY noise floor status register |
@@ -1994,7 +2017,10 @@ | |||
1994 | #define AR5K_PHY_NF_RVAL(_n) (((_n) >> 19) & AR5K_PHY_NF_M) | 2017 | #define AR5K_PHY_NF_RVAL(_n) (((_n) >> 19) & AR5K_PHY_NF_M) |
1995 | #define AR5K_PHY_NF_AVAL(_n) (-((_n) ^ AR5K_PHY_NF_M) + 1) | 2018 | #define AR5K_PHY_NF_AVAL(_n) (-((_n) ^ AR5K_PHY_NF_M) + 1) |
1996 | #define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9)) | 2019 | #define AR5K_PHY_NF_SVAL(_n) (((_n) & AR5K_PHY_NF_M) | (1 << 9)) |
1997 | #define AR5K_PHY_NF_THRESH62 0x00001000 /* Thresh62 -check ANI patent- (field) */ | 2020 | #define AR5K_PHY_NF_THRESH62 0x0007f000 /* Thresh62 -check ANI patent- (field) */ |
2021 | #define AR5K_PHY_NF_THRESH62_S 12 | ||
2022 | #define AR5K_PHY_NF_MINCCA_PWR 0x0ff80000 /* ??? */ | ||
2023 | #define AR5K_PHY_NF_MINCCA_PWR_S 19 | ||
1998 | 2024 | ||
1999 | /* | 2025 | /* |
2000 | * PHY ADC saturation register [5110] | 2026 | * PHY ADC saturation register [5110] |
@@ -2034,24 +2060,31 @@ | |||
2034 | */ | 2060 | */ |
2035 | #define AR5K_PHY_SCR 0x9870 | 2061 | #define AR5K_PHY_SCR 0x9870 |
2036 | #define AR5K_PHY_SCR_32MHZ 0x0000001f | 2062 | #define AR5K_PHY_SCR_32MHZ 0x0000001f |
2063 | |||
2037 | #define AR5K_PHY_SLMT 0x9874 | 2064 | #define AR5K_PHY_SLMT 0x9874 |
2038 | #define AR5K_PHY_SLMT_32MHZ 0x0000007f | 2065 | #define AR5K_PHY_SLMT_32MHZ 0x0000007f |
2066 | |||
2039 | #define AR5K_PHY_SCAL 0x9878 | 2067 | #define AR5K_PHY_SCAL 0x9878 |
2040 | #define AR5K_PHY_SCAL_32MHZ 0x0000000e | 2068 | #define AR5K_PHY_SCAL_32MHZ 0x0000000e |
2041 | 2069 | ||
2070 | |||
2042 | /* | 2071 | /* |
2043 | * PHY PLL (Phase Locked Loop) control register | 2072 | * PHY PLL (Phase Locked Loop) control register |
2044 | */ | 2073 | */ |
2045 | #define AR5K_PHY_PLL 0x987c | 2074 | #define AR5K_PHY_PLL 0x987c |
2046 | #define AR5K_PHY_PLL_20MHZ 0x13 /* For half rate (?) [5111+] */ | 2075 | #define AR5K_PHY_PLL_20MHZ 0x00000013 /* For half rate (?) */ |
2047 | #define AR5K_PHY_PLL_40MHZ_5211 0x18 /* For 802.11a */ | 2076 | /* 40MHz -> 5GHz band */ |
2077 | #define AR5K_PHY_PLL_40MHZ_5211 0x00000018 | ||
2048 | #define AR5K_PHY_PLL_40MHZ_5212 0x000000aa | 2078 | #define AR5K_PHY_PLL_40MHZ_5212 0x000000aa |
2079 | #define AR5K_PHY_PLL_40MHZ_5413 0x00000004 | ||
2049 | #define AR5K_PHY_PLL_40MHZ (ah->ah_version == AR5K_AR5211 ? \ | 2080 | #define AR5K_PHY_PLL_40MHZ (ah->ah_version == AR5K_AR5211 ? \ |
2050 | AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212) | 2081 | AR5K_PHY_PLL_40MHZ_5211 : AR5K_PHY_PLL_40MHZ_5212) |
2051 | #define AR5K_PHY_PLL_44MHZ_5211 0x19 /* For 802.11b/g */ | 2082 | /* 44MHz -> 2.4GHz band */ |
2083 | #define AR5K_PHY_PLL_44MHZ_5211 0x00000019 | ||
2052 | #define AR5K_PHY_PLL_44MHZ_5212 0x000000ab | 2084 | #define AR5K_PHY_PLL_44MHZ_5212 0x000000ab |
2053 | #define AR5K_PHY_PLL_44MHZ (ah->ah_version == AR5K_AR5211 ? \ | 2085 | #define AR5K_PHY_PLL_44MHZ (ah->ah_version == AR5K_AR5211 ? \ |
2054 | AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212) | 2086 | AR5K_PHY_PLL_44MHZ_5211 : AR5K_PHY_PLL_44MHZ_5212) |
2087 | |||
2055 | #define AR5K_PHY_PLL_RF5111 0x00000000 | 2088 | #define AR5K_PHY_PLL_RF5111 0x00000000 |
2056 | #define AR5K_PHY_PLL_RF5112 0x00000040 | 2089 | #define AR5K_PHY_PLL_RF5112 0x00000040 |
2057 | #define AR5K_PHY_PLL_HALF_RATE 0x00000100 | 2090 | #define AR5K_PHY_PLL_HALF_RATE 0x00000100 |
@@ -2118,6 +2151,19 @@ | |||
2118 | #define AR5K_PHY_RFSTG_DISABLE 0x00000021 | 2151 | #define AR5K_PHY_RFSTG_DISABLE 0x00000021 |
2119 | 2152 | ||
2120 | /* | 2153 | /* |
2154 | * BIN masks (?) | ||
2155 | */ | ||
2156 | #define AR5K_PHY_BIN_MASK_1 0x9900 | ||
2157 | #define AR5K_PHY_BIN_MASK_2 0x9904 | ||
2158 | #define AR5K_PHY_BIN_MASK_3 0x9908 | ||
2159 | |||
2160 | #define AR5K_PHY_BIN_MASK_CTL 0x990c | ||
2161 | #define AR5K_PHY_BIN_MASK_CTL_MASK_4 0x00003fff | ||
2162 | #define AR5K_PHY_BIN_MASK_CTL_MASK_4_S 0 | ||
2163 | #define AR5K_PHY_BIN_MASK_CTL_RATE 0xff000000 | ||
2164 | #define AR5K_PHY_BIN_MASK_CTL_RATE_S 24 | ||
2165 | |||
2166 | /* | ||
2121 | * PHY Antenna control register | 2167 | * PHY Antenna control register |
2122 | */ | 2168 | */ |
2123 | #define AR5K_PHY_ANT_CTL 0x9910 /* Register Address */ | 2169 | #define AR5K_PHY_ANT_CTL 0x9910 /* Register Address */ |
@@ -2164,6 +2210,7 @@ | |||
2164 | #define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */ | 2210 | #define AR5K_PHY_OFDM_SELFCORR 0x9924 /* Register Address */ |
2165 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */ | 2211 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_EN 0x00000001 /* Enable cyclic RSSI thr 1 */ |
2166 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */ | 2212 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1 0x000000fe /* Mask for Cyclic RSSI threshold 1 */ |
2213 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1_S 0 | ||
2167 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */ | 2214 | #define AR5K_PHY_OFDM_SELFCORR_CYPWR_THR3 0x00000100 /* Cyclic RSSI threshold 3 (field) (?) */ |
2168 | #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */ | 2215 | #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR_EN 0x00008000 /* Enable 1A RSSI threshold (?) */ |
2169 | #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */ | 2216 | #define AR5K_PHY_OFDM_SELFCORR_RSSI_1ATHR 0x00010000 /* 1A RSSI threshold (field) (?) */ |
@@ -2210,7 +2257,6 @@ | |||
2210 | #define AR5K_PHY_PAPD_PROBE_INI_5111 0x00004883 /* [5212+] */ | 2257 | #define AR5K_PHY_PAPD_PROBE_INI_5111 0x00004883 /* [5212+] */ |
2211 | #define AR5K_PHY_PAPD_PROBE_INI_5112 0x00004882 /* [5212+] */ | 2258 | #define AR5K_PHY_PAPD_PROBE_INI_5112 0x00004882 /* [5212+] */ |
2212 | 2259 | ||
2213 | |||
2214 | /* | 2260 | /* |
2215 | * PHY TX rate power registers [5112+] | 2261 | * PHY TX rate power registers [5112+] |
2216 | */ | 2262 | */ |
@@ -2232,6 +2278,8 @@ | |||
2232 | #define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */ | 2278 | #define AR5K_PHY_FRAME_CTL_TX_CLIP 0x00000038 /* Mask for tx clip (?) */ |
2233 | #define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3 | 2279 | #define AR5K_PHY_FRAME_CTL_TX_CLIP_S 3 |
2234 | #define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */ | 2280 | #define AR5K_PHY_FRAME_CTL_PREP_CHINFO 0x00010000 /* Prepend chan info */ |
2281 | #define AR5K_PHY_FRAME_CTL_EMU 0x80000000 | ||
2282 | #define AR5K_PHY_FRAME_CTL_EMU_S 31 | ||
2235 | /*---[5110/5111]---*/ | 2283 | /*---[5110/5111]---*/ |
2236 | #define AR5K_PHY_FRAME_CTL_TIMING_ERR 0x01000000 /* PHY timing error */ | 2284 | #define AR5K_PHY_FRAME_CTL_TIMING_ERR 0x01000000 /* PHY timing error */ |
2237 | #define AR5K_PHY_FRAME_CTL_PARITY_ERR 0x02000000 /* Parity error */ | 2285 | #define AR5K_PHY_FRAME_CTL_PARITY_ERR 0x02000000 /* Parity error */ |
@@ -2250,48 +2298,36 @@ | |||
2250 | * PHY radar detection register [5111+] | 2298 | * PHY radar detection register [5111+] |
2251 | */ | 2299 | */ |
2252 | #define AR5K_PHY_RADAR 0x9954 | 2300 | #define AR5K_PHY_RADAR 0x9954 |
2253 | |||
2254 | /* Radar enable ........ ........ ........ .......1 */ | ||
2255 | #define AR5K_PHY_RADAR_ENABLE 0x00000001 | 2301 | #define AR5K_PHY_RADAR_ENABLE 0x00000001 |
2256 | #define AR5K_PHY_RADAR_DISABLE 0x00000000 | 2302 | #define AR5K_PHY_RADAR_DISABLE 0x00000000 |
2257 | #define AR5K_PHY_RADAR_ENABLE_S 0 | 2303 | #define AR5K_PHY_RADAR_INBANDTHR 0x0000003e /* Inband threshold |
2258 | 2304 | 5-bits, units unknown {0..31} | |
2259 | /* This is the value found on the card .1.111.1 .1.1.... 111....1 1...1... | 2305 | (? MHz ?) */ |
2260 | at power on. */ | ||
2261 | #define AR5K_PHY_RADAR_PWONDEF_AR5213 0x5d50e188 | ||
2262 | |||
2263 | /* This is the value found on the card .1.1.111 ..11...1 .1...1.1 1...11.1 | ||
2264 | after DFS is enabled */ | ||
2265 | #define AR5K_PHY_RADAR_ENABLED_AR5213 0x5731458d | ||
2266 | |||
2267 | /* Finite Impulse Response (FIR) filter .1111111 ........ ........ ........ | ||
2268 | * power out threshold. | ||
2269 | * 7-bits, standard power range {0..127} in 1/2 dBm units. */ | ||
2270 | #define AR5K_PHY_RADAR_FIRPWROUTTHR 0x7f000000 | ||
2271 | #define AR5K_PHY_RADAR_FIRPWROUTTHR_S 24 | ||
2272 | |||
2273 | /* Radar RSSI/SNR threshold. ........ 111111.. ........ ........ | ||
2274 | * 6-bits, dBm range {0..63} in dBm units. */ | ||
2275 | #define AR5K_PHY_RADAR_RADARRSSITHR 0x00fc0000 | ||
2276 | #define AR5K_PHY_RADAR_RADARRSSITHR_S 18 | ||
2277 | |||
2278 | /* Pulse height threshold ........ ......11 1111.... ........ | ||
2279 | * 6-bits, dBm range {0..63} in dBm units. */ | ||
2280 | #define AR5K_PHY_RADAR_PULSEHEIGHTTHR 0x0003f000 | ||
2281 | #define AR5K_PHY_RADAR_PULSEHEIGHTTHR_S 12 | ||
2282 | |||
2283 | /* Pulse RSSI/SNR threshold ........ ........ ....1111 11...... | ||
2284 | * 6-bits, dBm range {0..63} in dBm units. */ | ||
2285 | #define AR5K_PHY_RADAR_PULSERSSITHR 0x00000fc0 | ||
2286 | #define AR5K_PHY_RADAR_PULSERSSITHR_S 6 | ||
2287 | |||
2288 | /* Inband threshold ........ ........ ........ ..11111. | ||
2289 | * 5-bits, units unknown {0..31} (? MHz ?) */ | ||
2290 | #define AR5K_PHY_RADAR_INBANDTHR 0x0000003e | ||
2291 | #define AR5K_PHY_RADAR_INBANDTHR_S 1 | 2306 | #define AR5K_PHY_RADAR_INBANDTHR_S 1 |
2292 | 2307 | ||
2308 | #define AR5K_PHY_RADAR_PRSSI_THR 0x00000fc0 /* Pulse RSSI/SNR threshold | ||
2309 | 6-bits, dBm range {0..63} | ||
2310 | in dBm units. */ | ||
2311 | #define AR5K_PHY_RADAR_PRSSI_THR_S 6 | ||
2312 | |||
2313 | #define AR5K_PHY_RADAR_PHEIGHT_THR 0x0003f000 /* Pulse height threshold | ||
2314 | 6-bits, dBm range {0..63} | ||
2315 | in dBm units. */ | ||
2316 | #define AR5K_PHY_RADAR_PHEIGHT_THR_S 12 | ||
2317 | |||
2318 | #define AR5K_PHY_RADAR_RSSI_THR 0x00fc0000 /* Radar RSSI/SNR threshold. | ||
2319 | 6-bits, dBm range {0..63} | ||
2320 | in dBm units. */ | ||
2321 | #define AR5K_PHY_RADAR_RSSI_THR_S 18 | ||
2322 | |||
2323 | #define AR5K_PHY_RADAR_FIRPWR_THR 0x7f000000 /* Finite Impulse Response | ||
2324 | filter power out threshold. | ||
2325 | 7-bits, standard power range | ||
2326 | {0..127} in 1/2 dBm units. */ | ||
2327 | #define AR5K_PHY_RADAR_FIRPWR_THRS 24 | ||
2328 | |||
2293 | /* | 2329 | /* |
2294 | * PHY antenna switch table registers [5110] | 2330 | * PHY antenna switch table registers |
2295 | */ | 2331 | */ |
2296 | #define AR5K_PHY_ANT_SWITCH_TABLE_0 0x9960 | 2332 | #define AR5K_PHY_ANT_SWITCH_TABLE_0 0x9960 |
2297 | #define AR5K_PHY_ANT_SWITCH_TABLE_1 0x9964 | 2333 | #define AR5K_PHY_ANT_SWITCH_TABLE_1 0x9964 |
@@ -2302,25 +2338,65 @@ after DFS is enabled */ | |||
2302 | #define AR5K_PHY_NFTHRES 0x9968 | 2338 | #define AR5K_PHY_NFTHRES 0x9968 |
2303 | 2339 | ||
2304 | /* | 2340 | /* |
2305 | * PHY clock sleep registers [5112+] | 2341 | * Sigma Delta register (?) [5213] |
2306 | */ | 2342 | */ |
2307 | #define AR5K_PHY_SCLOCK 0x99f0 | 2343 | #define AR5K_PHY_SIGMA_DELTA 0x996C |
2308 | #define AR5K_PHY_SCLOCK_32MHZ 0x0000000c | 2344 | #define AR5K_PHY_SIGMA_DELTA_ADC_SEL 0x00000003 |
2309 | #define AR5K_PHY_SDELAY 0x99f4 | 2345 | #define AR5K_PHY_SIGMA_DELTA_ADC_SEL_S 0 |
2310 | #define AR5K_PHY_SDELAY_32MHZ 0x000000ff | 2346 | #define AR5K_PHY_SIGMA_DELTA_FILT2 0x000000f8 |
2311 | #define AR5K_PHY_SPENDING 0x99f8 | 2347 | #define AR5K_PHY_SIGMA_DELTA_FILT2_S 3 |
2312 | #define AR5K_PHY_SPENDING_14 0x00000014 | 2348 | #define AR5K_PHY_SIGMA_DELTA_FILT1 0x00001f00 |
2313 | #define AR5K_PHY_SPENDING_18 0x00000018 | 2349 | #define AR5K_PHY_SIGMA_DELTA_FILT1_S 8 |
2314 | #define AR5K_PHY_SPENDING_RF5111 0x00000018 | 2350 | #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP 0x01ff3000 |
2315 | #define AR5K_PHY_SPENDING_RF5112 0x00000014 | 2351 | #define AR5K_PHY_SIGMA_DELTA_ADC_CLIP_S 13 |
2316 | /* #define AR5K_PHY_SPENDING_RF5112A 0x0000000e */ | 2352 | |
2317 | /* #define AR5K_PHY_SPENDING_RF5424 0x00000012 */ | 2353 | /* |
2318 | #define AR5K_PHY_SPENDING_RF5413 0x00000014 | 2354 | * RF restart register [5112+] (?) |
2319 | #define AR5K_PHY_SPENDING_RF2413 0x00000014 | 2355 | */ |
2320 | #define AR5K_PHY_SPENDING_RF2425 0x00000018 | 2356 | #define AR5K_PHY_RESTART 0x9970 /* restart */ |
2357 | #define AR5K_PHY_RESTART_DIV_GC 0x001c0000 /* Fast diversity gc_limit (?) */ | ||
2358 | #define AR5K_PHY_RESTART_DIV_GC_S 18 | ||
2359 | |||
2360 | /* | ||
2361 | * RF Bus access request register (for synth-oly channel switching) | ||
2362 | */ | ||
2363 | #define AR5K_PHY_RFBUS_REQ 0x997C | ||
2364 | #define AR5K_PHY_RFBUS_REQ_REQUEST 0x00000001 | ||
2365 | |||
2366 | /* | ||
2367 | * Spur mitigation masks (?) | ||
2368 | */ | ||
2369 | #define AR5K_PHY_TIMING_7 0x9980 | ||
2370 | #define AR5K_PHY_TIMING_8 0x9984 | ||
2371 | #define AR5K_PHY_TIMING_8_PILOT_MASK_2 0x000fffff | ||
2372 | #define AR5K_PHY_TIMING_8_PILOT_MASK_2_S 0 | ||
2373 | |||
2374 | #define AR5K_PHY_BIN_MASK2_1 0x9988 | ||
2375 | #define AR5K_PHY_BIN_MASK2_2 0x998c | ||
2376 | #define AR5K_PHY_BIN_MASK2_3 0x9990 | ||
2377 | |||
2378 | #define AR5K_PHY_BIN_MASK2_4 0x9994 | ||
2379 | #define AR5K_PHY_BIN_MASK2_4_MASK_4 0x00003fff | ||
2380 | #define AR5K_PHY_BIN_MASK2_4_MASK_4_S 0 | ||
2381 | |||
2382 | #define AR_PHY_TIMING_9 0x9998 | ||
2383 | #define AR_PHY_TIMING_10 0x999c | ||
2384 | #define AR_PHY_TIMING_10_PILOT_MASK_2 0x000fffff | ||
2385 | #define AR_PHY_TIMING_10_PILOT_MASK_2_S 0 | ||
2386 | |||
2387 | /* | ||
2388 | * Spur mitigation control | ||
2389 | */ | ||
2390 | #define AR_PHY_TIMING_11 0x99a0 /* Register address */ | ||
2391 | #define AR_PHY_TIMING_11_SPUR_DELTA_PHASE 0x000fffff /* Spur delta phase */ | ||
2392 | #define AR_PHY_TIMING_11_SPUR_DELTA_PHASE_S 0 | ||
2393 | #define AR_PHY_TIMING_11_SPUR_FREQ_SD 0x3ff00000 /* Freq sigma delta */ | ||
2394 | #define AR_PHY_TIMING_11_SPUR_FREQ_SD_S 20 | ||
2395 | #define AR_PHY_TIMING_11_USE_SPUR_IN_AGC 0x40000000 /* Spur filter in AGC detector */ | ||
2396 | #define AR_PHY_TIMING_11_USE_SPUR_IN_SELFCOR 0x80000000 /* Spur filter in OFDM self correlator */ | ||
2321 | 2397 | ||
2322 | /* | 2398 | /* |
2323 | * Misc PHY/radio registers [5110 - 5111] | 2399 | * Gain tables |
2324 | */ | 2400 | */ |
2325 | #define AR5K_BB_GAIN_BASE 0x9b00 /* BaseBand Amplifier Gain table base address */ | 2401 | #define AR5K_BB_GAIN_BASE 0x9b00 /* BaseBand Amplifier Gain table base address */ |
2326 | #define AR5K_BB_GAIN(_n) (AR5K_BB_GAIN_BASE + ((_n) << 2)) | 2402 | #define AR5K_BB_GAIN(_n) (AR5K_BB_GAIN_BASE + ((_n) << 2)) |
@@ -2340,9 +2416,10 @@ after DFS is enabled */ | |||
2340 | #define AR5K_PHY_CURRENT_RSSI 0x9c1c | 2416 | #define AR5K_PHY_CURRENT_RSSI 0x9c1c |
2341 | 2417 | ||
2342 | /* | 2418 | /* |
2343 | * PHY RF Bus grant register (?) | 2419 | * PHY RF Bus grant register |
2344 | */ | 2420 | */ |
2345 | #define AR5K_PHY_RFBUS_GRANT 0x9c20 | 2421 | #define AR5K_PHY_RFBUS_GRANT 0x9c20 |
2422 | #define AR5K_PHY_RFBUS_GRANT_OK 0x00000001 | ||
2346 | 2423 | ||
2347 | /* | 2424 | /* |
2348 | * PHY ADC test register | 2425 | * PHY ADC test register |
@@ -2386,6 +2463,31 @@ after DFS is enabled */ | |||
2386 | #define AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008 | 2463 | #define AR5K_PHY_CHAN_STATUS_RX_CLR_PAP 0x00000008 |
2387 | 2464 | ||
2388 | /* | 2465 | /* |
2466 | * Heavy clip enable register | ||
2467 | */ | ||
2468 | #define AR5K_PHY_HEAVY_CLIP_ENABLE 0x99e0 | ||
2469 | |||
2470 | /* | ||
2471 | * PHY clock sleep registers [5112+] | ||
2472 | */ | ||
2473 | #define AR5K_PHY_SCLOCK 0x99f0 | ||
2474 | #define AR5K_PHY_SCLOCK_32MHZ 0x0000000c | ||
2475 | #define AR5K_PHY_SDELAY 0x99f4 | ||
2476 | #define AR5K_PHY_SDELAY_32MHZ 0x000000ff | ||
2477 | #define AR5K_PHY_SPENDING 0x99f8 | ||
2478 | #define AR5K_PHY_SPENDING_14 0x00000014 | ||
2479 | #define AR5K_PHY_SPENDING_18 0x00000018 | ||
2480 | #define AR5K_PHY_SPENDING_RF5111 0x00000018 | ||
2481 | #define AR5K_PHY_SPENDING_RF5112 0x00000014 | ||
2482 | /* #define AR5K_PHY_SPENDING_RF5112A 0x0000000e */ | ||
2483 | /* #define AR5K_PHY_SPENDING_RF5424 0x00000012 */ | ||
2484 | #define AR5K_PHY_SPENDING_RF5413 0x00000018 | ||
2485 | #define AR5K_PHY_SPENDING_RF2413 0x00000018 | ||
2486 | #define AR5K_PHY_SPENDING_RF2316 0x00000018 | ||
2487 | #define AR5K_PHY_SPENDING_RF2317 0x00000018 | ||
2488 | #define AR5K_PHY_SPENDING_RF2425 0x00000014 | ||
2489 | |||
2490 | /* | ||
2389 | * PHY PAPD I (power?) table (?) | 2491 | * PHY PAPD I (power?) table (?) |
2390 | * (92! entries) | 2492 | * (92! entries) |
2391 | */ | 2493 | */ |
@@ -2436,10 +2538,47 @@ after DFS is enabled */ | |||
2436 | #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000000f | 2538 | #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR 0x0000000f |
2437 | #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0 | 2539 | #define AR5K_PHY_CCK_CROSSCORR_WEAK_SIG_THR_S 0 |
2438 | 2540 | ||
2541 | /* Same address is used for antenna diversity activation */ | ||
2542 | #define AR5K_PHY_FAST_ANT_DIV 0xa208 | ||
2543 | #define AR5K_PHY_FAST_ANT_DIV_EN 0x00002000 | ||
2544 | |||
2439 | /* | 2545 | /* |
2440 | * PHY 2GHz gain register [5111+] | 2546 | * PHY 2GHz gain register [5111+] |
2441 | */ | 2547 | */ |
2442 | #define AR5K_PHY_GAIN_2GHZ 0xa20c | 2548 | #define AR5K_PHY_GAIN_2GHZ 0xa20c |
2443 | #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000 | 2549 | #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX 0x00fc0000 |
2444 | #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18 | 2550 | #define AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX_S 18 |
2445 | #define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c | 2551 | #define AR5K_PHY_GAIN_2GHZ_INI_5111 0x6480416c |
2552 | |||
2553 | #define AR5K_PHY_CCK_RX_CTL_4 0xa21c | ||
2554 | #define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT 0x01f80000 | ||
2555 | #define AR5K_PHY_CCK_RX_CTL_4_FREQ_EST_SHORT_S 19 | ||
2556 | |||
2557 | #define AR5K_PHY_DAG_CCK_CTL 0xa228 | ||
2558 | #define AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR 0x00000200 | ||
2559 | #define AR5K_PHY_DAG_CCK_CTL_RSSI_THR 0x0001fc00 | ||
2560 | #define AR5K_PHY_DAG_CCK_CTL_RSSI_THR_S 10 | ||
2561 | |||
2562 | #define AR5K_PHY_FAST_ADC 0xa24c | ||
2563 | |||
2564 | #define AR5K_PHY_BLUETOOTH 0xa254 | ||
2565 | |||
2566 | /* | ||
2567 | * Transmit Power Control register | ||
2568 | * [2413+] | ||
2569 | */ | ||
2570 | #define AR5K_PHY_TPC_RG1 0xa258 | ||
2571 | #define AR5K_PHY_TPC_RG1_NUM_PD_GAIN 0x0000c000 | ||
2572 | #define AR5K_PHY_TPC_RG1_NUM_PD_GAIN_S 14 | ||
2573 | |||
2574 | #define AR5K_PHY_TPC_RG5 0xa26C | ||
2575 | #define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP 0x0000000F | ||
2576 | #define AR5K_PHY_TPC_RG5_PD_GAIN_OVERLAP_S 0 | ||
2577 | #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1 0x000003F0 | ||
2578 | #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_1_S 4 | ||
2579 | #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2 0x0000FC00 | ||
2580 | #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_2_S 10 | ||
2581 | #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3 0x003F0000 | ||
2582 | #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_3_S 16 | ||
2583 | #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4 0x0FC00000 | ||
2584 | #define AR5K_PHY_TPC_RG5_PD_GAIN_BOUNDARY_4_S 22 | ||
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c new file mode 100644 index 000000000000..8f1886834e61 --- /dev/null +++ b/drivers/net/wireless/ath5k/reset.c | |||
@@ -0,0 +1,931 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu> | ||
5 | * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org> | ||
6 | * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> | ||
7 | * | ||
8 | * Permission to use, copy, modify, and distribute this software for any | ||
9 | * purpose with or without fee is hereby granted, provided that the above | ||
10 | * copyright notice and this permission notice appear in all copies. | ||
11 | * | ||
12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #define _ATH5K_RESET | ||
23 | |||
24 | /*****************************\ | ||
25 | Reset functions and helpers | ||
26 | \*****************************/ | ||
27 | |||
28 | #include <linux/pci.h> | ||
29 | #include "ath5k.h" | ||
30 | #include "reg.h" | ||
31 | #include "base.h" | ||
32 | #include "debug.h" | ||
33 | |||
34 | /** | ||
35 | * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 | ||
36 | * | ||
37 | * @ah: the &struct ath5k_hw | ||
38 | * @channel: the currently set channel upon reset | ||
39 | * | ||
40 | * Write the OFDM timings for the AR5212 upon reset. This is a helper for | ||
41 | * ath5k_hw_reset(). This seems to tune the PLL a specified frequency | ||
42 | * depending on the bandwidth of the channel. | ||
43 | * | ||
44 | */ | ||
45 | static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | ||
46 | struct ieee80211_channel *channel) | ||
47 | { | ||
48 | /* Get exponent and mantissa and set it */ | ||
49 | u32 coef_scaled, coef_exp, coef_man, | ||
50 | ds_coef_exp, ds_coef_man, clock; | ||
51 | |||
52 | if (!(ah->ah_version == AR5K_AR5212) || | ||
53 | !(channel->hw_value & CHANNEL_OFDM)) | ||
54 | BUG(); | ||
55 | |||
56 | /* Seems there are two PLLs, one for baseband sampling and one | ||
57 | * for tuning. Tuning basebands are 40 MHz or 80MHz when in | ||
58 | * turbo. */ | ||
59 | clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40; | ||
60 | coef_scaled = ((5 * (clock << 24)) / 2) / | ||
61 | channel->center_freq; | ||
62 | |||
63 | for (coef_exp = 31; coef_exp > 0; coef_exp--) | ||
64 | if ((coef_scaled >> coef_exp) & 0x1) | ||
65 | break; | ||
66 | |||
67 | if (!coef_exp) | ||
68 | return -EINVAL; | ||
69 | |||
70 | coef_exp = 14 - (coef_exp - 24); | ||
71 | coef_man = coef_scaled + | ||
72 | (1 << (24 - coef_exp - 1)); | ||
73 | ds_coef_man = coef_man >> (24 - coef_exp); | ||
74 | ds_coef_exp = coef_exp - 16; | ||
75 | |||
76 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, | ||
77 | AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man); | ||
78 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, | ||
79 | AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp); | ||
80 | |||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | |||
85 | /* | ||
86 | * index into rates for control rates, we can set it up like this because | ||
87 | * this is only used for AR5212 and we know it supports G mode | ||
88 | */ | ||
89 | static int control_rates[] = | ||
90 | { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; | ||
91 | |||
92 | /** | ||
93 | * ath5k_hw_write_rate_duration - set rate duration during hw resets | ||
94 | * | ||
95 | * @ah: the &struct ath5k_hw | ||
96 | * @mode: one of enum ath5k_driver_mode | ||
97 | * | ||
98 | * Write the rate duration table upon hw reset. This is a helper for | ||
99 | * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for | ||
100 | * the hardware for the current mode for each rate. The rates which are capable | ||
101 | * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another | ||
102 | * register for the short preamble ACK timeout calculation. | ||
103 | */ | ||
104 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | ||
105 | unsigned int mode) | ||
106 | { | ||
107 | struct ath5k_softc *sc = ah->ah_sc; | ||
108 | struct ieee80211_rate *rate; | ||
109 | unsigned int i; | ||
110 | |||
111 | /* Write rate duration table */ | ||
112 | for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) { | ||
113 | u32 reg; | ||
114 | u16 tx_time; | ||
115 | |||
116 | rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]]; | ||
117 | |||
118 | /* Set ACK timeout */ | ||
119 | reg = AR5K_RATE_DUR(rate->hw_value); | ||
120 | |||
121 | /* An ACK frame consists of 10 bytes. If you add the FCS, | ||
122 | * which ieee80211_generic_frame_duration() adds, | ||
123 | * its 14 bytes. Note we use the control rate and not the | ||
124 | * actual rate for this rate. See mac80211 tx.c | ||
125 | * ieee80211_duration() for a brief description of | ||
126 | * what rate we should choose to TX ACKs. */ | ||
127 | tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, | ||
128 | sc->vif, 10, rate)); | ||
129 | |||
130 | ath5k_hw_reg_write(ah, tx_time, reg); | ||
131 | |||
132 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) | ||
133 | continue; | ||
134 | |||
135 | /* | ||
136 | * We're not distinguishing short preamble here, | ||
137 | * This is true, all we'll get is a longer value here | ||
138 | * which is not necessarilly bad. We could use | ||
139 | * export ieee80211_frame_duration() but that needs to be | ||
140 | * fixed first to be properly used by mac802111 drivers: | ||
141 | * | ||
142 | * - remove erp stuff and let the routine figure ofdm | ||
143 | * erp rates | ||
144 | * - remove passing argument ieee80211_local as | ||
145 | * drivers don't have access to it | ||
146 | * - move drivers using ieee80211_generic_frame_duration() | ||
147 | * to this | ||
148 | */ | ||
149 | ath5k_hw_reg_write(ah, tx_time, | ||
150 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); | ||
151 | } | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * Reset chipset | ||
156 | */ | ||
157 | static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) | ||
158 | { | ||
159 | int ret; | ||
160 | u32 mask = val ? val : ~0U; | ||
161 | |||
162 | ATH5K_TRACE(ah->ah_sc); | ||
163 | |||
164 | /* Read-and-clear RX Descriptor Pointer*/ | ||
165 | ath5k_hw_reg_read(ah, AR5K_RXDP); | ||
166 | |||
167 | /* | ||
168 | * Reset the device and wait until success | ||
169 | */ | ||
170 | ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL); | ||
171 | |||
172 | /* Wait at least 128 PCI clocks */ | ||
173 | udelay(15); | ||
174 | |||
175 | if (ah->ah_version == AR5K_AR5210) { | ||
176 | val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | ||
177 | | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; | ||
178 | mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | ||
179 | | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; | ||
180 | } else { | ||
181 | val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; | ||
182 | mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; | ||
183 | } | ||
184 | |||
185 | ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false); | ||
186 | |||
187 | /* | ||
188 | * Reset configuration register (for hw byte-swap). Note that this | ||
189 | * is only set for big endian. We do the necessary magic in | ||
190 | * AR5K_INIT_CFG. | ||
191 | */ | ||
192 | if ((val & AR5K_RESET_CTL_PCU) == 0) | ||
193 | ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG); | ||
194 | |||
195 | return ret; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Sleep control | ||
200 | */ | ||
201 | int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, | ||
202 | bool set_chip, u16 sleep_duration) | ||
203 | { | ||
204 | unsigned int i; | ||
205 | u32 staid, data; | ||
206 | |||
207 | ATH5K_TRACE(ah->ah_sc); | ||
208 | staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); | ||
209 | |||
210 | switch (mode) { | ||
211 | case AR5K_PM_AUTO: | ||
212 | staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA; | ||
213 | /* fallthrough */ | ||
214 | case AR5K_PM_NETWORK_SLEEP: | ||
215 | if (set_chip) | ||
216 | ath5k_hw_reg_write(ah, | ||
217 | AR5K_SLEEP_CTL_SLE_ALLOW | | ||
218 | sleep_duration, | ||
219 | AR5K_SLEEP_CTL); | ||
220 | |||
221 | staid |= AR5K_STA_ID1_PWR_SV; | ||
222 | break; | ||
223 | |||
224 | case AR5K_PM_FULL_SLEEP: | ||
225 | if (set_chip) | ||
226 | ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP, | ||
227 | AR5K_SLEEP_CTL); | ||
228 | |||
229 | staid |= AR5K_STA_ID1_PWR_SV; | ||
230 | break; | ||
231 | |||
232 | case AR5K_PM_AWAKE: | ||
233 | |||
234 | staid &= ~AR5K_STA_ID1_PWR_SV; | ||
235 | |||
236 | if (!set_chip) | ||
237 | goto commit; | ||
238 | |||
239 | /* Preserve sleep duration */ | ||
240 | data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL); | ||
241 | if (data & 0xffc00000) | ||
242 | data = 0; | ||
243 | else | ||
244 | data = data & 0xfffcffff; | ||
245 | |||
246 | ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); | ||
247 | udelay(15); | ||
248 | |||
249 | for (i = 50; i > 0; i--) { | ||
250 | /* Check if the chip did wake up */ | ||
251 | if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) & | ||
252 | AR5K_PCICFG_SPWR_DN) == 0) | ||
253 | break; | ||
254 | |||
255 | /* Wait a bit and retry */ | ||
256 | udelay(200); | ||
257 | ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); | ||
258 | } | ||
259 | |||
260 | /* Fail if the chip didn't wake up */ | ||
261 | if (i <= 0) | ||
262 | return -EIO; | ||
263 | |||
264 | break; | ||
265 | |||
266 | default: | ||
267 | return -EINVAL; | ||
268 | } | ||
269 | |||
270 | commit: | ||
271 | ah->ah_power_mode = mode; | ||
272 | ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1); | ||
273 | |||
274 | return 0; | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * Bring up MAC + PHY Chips | ||
279 | */ | ||
280 | int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) | ||
281 | { | ||
282 | struct pci_dev *pdev = ah->ah_sc->pdev; | ||
283 | u32 turbo, mode, clock, bus_flags; | ||
284 | int ret; | ||
285 | |||
286 | turbo = 0; | ||
287 | mode = 0; | ||
288 | clock = 0; | ||
289 | |||
290 | ATH5K_TRACE(ah->ah_sc); | ||
291 | |||
292 | /* Wakeup the device */ | ||
293 | ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); | ||
294 | if (ret) { | ||
295 | ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n"); | ||
296 | return ret; | ||
297 | } | ||
298 | |||
299 | if (ah->ah_version != AR5K_AR5210) { | ||
300 | /* | ||
301 | * Get channel mode flags | ||
302 | */ | ||
303 | |||
304 | if (ah->ah_radio >= AR5K_RF5112) { | ||
305 | mode = AR5K_PHY_MODE_RAD_RF5112; | ||
306 | clock = AR5K_PHY_PLL_RF5112; | ||
307 | } else { | ||
308 | mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/ | ||
309 | clock = AR5K_PHY_PLL_RF5111; /*Zero*/ | ||
310 | } | ||
311 | |||
312 | if (flags & CHANNEL_2GHZ) { | ||
313 | mode |= AR5K_PHY_MODE_FREQ_2GHZ; | ||
314 | clock |= AR5K_PHY_PLL_44MHZ; | ||
315 | |||
316 | if (flags & CHANNEL_CCK) { | ||
317 | mode |= AR5K_PHY_MODE_MOD_CCK; | ||
318 | } else if (flags & CHANNEL_OFDM) { | ||
319 | /* XXX Dynamic OFDM/CCK is not supported by the | ||
320 | * AR5211 so we set MOD_OFDM for plain g (no | ||
321 | * CCK headers) operation. We need to test | ||
322 | * this, 5211 might support ofdm-only g after | ||
323 | * all, there are also initial register values | ||
324 | * in the code for g mode (see initvals.c). */ | ||
325 | if (ah->ah_version == AR5K_AR5211) | ||
326 | mode |= AR5K_PHY_MODE_MOD_OFDM; | ||
327 | else | ||
328 | mode |= AR5K_PHY_MODE_MOD_DYN; | ||
329 | } else { | ||
330 | ATH5K_ERR(ah->ah_sc, | ||
331 | "invalid radio modulation mode\n"); | ||
332 | return -EINVAL; | ||
333 | } | ||
334 | } else if (flags & CHANNEL_5GHZ) { | ||
335 | mode |= AR5K_PHY_MODE_FREQ_5GHZ; | ||
336 | clock |= AR5K_PHY_PLL_40MHZ; | ||
337 | |||
338 | if (flags & CHANNEL_OFDM) | ||
339 | mode |= AR5K_PHY_MODE_MOD_OFDM; | ||
340 | else { | ||
341 | ATH5K_ERR(ah->ah_sc, | ||
342 | "invalid radio modulation mode\n"); | ||
343 | return -EINVAL; | ||
344 | } | ||
345 | } else { | ||
346 | ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n"); | ||
347 | return -EINVAL; | ||
348 | } | ||
349 | |||
350 | if (flags & CHANNEL_TURBO) | ||
351 | turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT; | ||
352 | } else { /* Reset the device */ | ||
353 | |||
354 | /* ...enable Atheros turbo mode if requested */ | ||
355 | if (flags & CHANNEL_TURBO) | ||
356 | ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE, | ||
357 | AR5K_PHY_TURBO); | ||
358 | } | ||
359 | |||
360 | /* reseting PCI on PCI-E cards results card to hang | ||
361 | * and always return 0xffff... so we ingore that flag | ||
362 | * for PCI-E cards */ | ||
363 | bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; | ||
364 | |||
365 | /* Reset chipset */ | ||
366 | if (ah->ah_version == AR5K_AR5210) { | ||
367 | ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | | ||
368 | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA | | ||
369 | AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI); | ||
370 | mdelay(2); | ||
371 | } else { | ||
372 | ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | | ||
373 | AR5K_RESET_CTL_BASEBAND | bus_flags); | ||
374 | } | ||
375 | if (ret) { | ||
376 | ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n"); | ||
377 | return -EIO; | ||
378 | } | ||
379 | |||
380 | /* ...wakeup again!*/ | ||
381 | ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); | ||
382 | if (ret) { | ||
383 | ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n"); | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | /* ...final warm reset */ | ||
388 | if (ath5k_hw_nic_reset(ah, 0)) { | ||
389 | ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n"); | ||
390 | return -EIO; | ||
391 | } | ||
392 | |||
393 | if (ah->ah_version != AR5K_AR5210) { | ||
394 | /* ...set the PHY operating mode */ | ||
395 | ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL); | ||
396 | udelay(300); | ||
397 | |||
398 | ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE); | ||
399 | ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO); | ||
400 | } | ||
401 | |||
402 | return 0; | ||
403 | } | ||
404 | |||
405 | /* | ||
406 | * Main reset function | ||
407 | */ | ||
408 | int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | ||
409 | struct ieee80211_channel *channel, bool change_channel) | ||
410 | { | ||
411 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
412 | struct pci_dev *pdev = ah->ah_sc->pdev; | ||
413 | u32 data, s_seq, s_ant, s_led[3], dma_size; | ||
414 | unsigned int i, mode, freq, ee_mode, ant[2]; | ||
415 | int ret; | ||
416 | |||
417 | ATH5K_TRACE(ah->ah_sc); | ||
418 | |||
419 | s_seq = 0; | ||
420 | s_ant = 0; | ||
421 | ee_mode = 0; | ||
422 | freq = 0; | ||
423 | mode = 0; | ||
424 | |||
425 | /* | ||
426 | * Save some registers before a reset | ||
427 | */ | ||
428 | /*DCU/Antenna selection not available on 5210*/ | ||
429 | if (ah->ah_version != AR5K_AR5210) { | ||
430 | if (change_channel) { | ||
431 | /* Seq number for queue 0 -do this for all queues ? */ | ||
432 | s_seq = ath5k_hw_reg_read(ah, | ||
433 | AR5K_QUEUE_DFS_SEQNUM(0)); | ||
434 | /*Default antenna*/ | ||
435 | s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); | ||
436 | } | ||
437 | } | ||
438 | |||
439 | /*GPIOs*/ | ||
440 | s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE; | ||
441 | s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); | ||
442 | s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); | ||
443 | |||
444 | if (change_channel && ah->ah_rf_banks != NULL) | ||
445 | ath5k_hw_get_rf_gain(ah); | ||
446 | |||
447 | |||
448 | /*Wakeup the device*/ | ||
449 | ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); | ||
450 | if (ret) | ||
451 | return ret; | ||
452 | |||
453 | /* | ||
454 | * Initialize operating mode | ||
455 | */ | ||
456 | ah->ah_op_mode = op_mode; | ||
457 | |||
458 | /* | ||
459 | * 5111/5112 Settings | ||
460 | * 5210 only comes with RF5110 | ||
461 | */ | ||
462 | if (ah->ah_version != AR5K_AR5210) { | ||
463 | if (ah->ah_radio != AR5K_RF5111 && | ||
464 | ah->ah_radio != AR5K_RF5112 && | ||
465 | ah->ah_radio != AR5K_RF5413 && | ||
466 | ah->ah_radio != AR5K_RF2413 && | ||
467 | ah->ah_radio != AR5K_RF2425) { | ||
468 | ATH5K_ERR(ah->ah_sc, | ||
469 | "invalid phy radio: %u\n", ah->ah_radio); | ||
470 | return -EINVAL; | ||
471 | } | ||
472 | |||
473 | switch (channel->hw_value & CHANNEL_MODES) { | ||
474 | case CHANNEL_A: | ||
475 | mode = AR5K_MODE_11A; | ||
476 | freq = AR5K_INI_RFGAIN_5GHZ; | ||
477 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
478 | break; | ||
479 | case CHANNEL_G: | ||
480 | mode = AR5K_MODE_11G; | ||
481 | freq = AR5K_INI_RFGAIN_2GHZ; | ||
482 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
483 | break; | ||
484 | case CHANNEL_B: | ||
485 | mode = AR5K_MODE_11B; | ||
486 | freq = AR5K_INI_RFGAIN_2GHZ; | ||
487 | ee_mode = AR5K_EEPROM_MODE_11B; | ||
488 | break; | ||
489 | case CHANNEL_T: | ||
490 | mode = AR5K_MODE_11A_TURBO; | ||
491 | freq = AR5K_INI_RFGAIN_5GHZ; | ||
492 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
493 | break; | ||
494 | /*Is this ok on 5211 too ?*/ | ||
495 | case CHANNEL_TG: | ||
496 | mode = AR5K_MODE_11G_TURBO; | ||
497 | freq = AR5K_INI_RFGAIN_2GHZ; | ||
498 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
499 | break; | ||
500 | case CHANNEL_XR: | ||
501 | if (ah->ah_version == AR5K_AR5211) { | ||
502 | ATH5K_ERR(ah->ah_sc, | ||
503 | "XR mode not available on 5211"); | ||
504 | return -EINVAL; | ||
505 | } | ||
506 | mode = AR5K_MODE_XR; | ||
507 | freq = AR5K_INI_RFGAIN_5GHZ; | ||
508 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
509 | break; | ||
510 | default: | ||
511 | ATH5K_ERR(ah->ah_sc, | ||
512 | "invalid channel: %d\n", channel->center_freq); | ||
513 | return -EINVAL; | ||
514 | } | ||
515 | |||
516 | /* PHY access enable */ | ||
517 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | ||
518 | |||
519 | } | ||
520 | |||
521 | ret = ath5k_hw_write_initvals(ah, mode, change_channel); | ||
522 | if (ret) | ||
523 | return ret; | ||
524 | |||
525 | /* | ||
526 | * 5211/5212 Specific | ||
527 | */ | ||
528 | if (ah->ah_version != AR5K_AR5210) { | ||
529 | /* | ||
530 | * Write initial RF gain settings | ||
531 | * This should work for both 5111/5112 | ||
532 | */ | ||
533 | ret = ath5k_hw_rfgain(ah, freq); | ||
534 | if (ret) | ||
535 | return ret; | ||
536 | |||
537 | mdelay(1); | ||
538 | |||
539 | /* | ||
540 | * Write some more initial register settings | ||
541 | */ | ||
542 | if (ah->ah_version == AR5K_AR5212) { | ||
543 | ath5k_hw_reg_write(ah, 0x0002a002, 0x982c); | ||
544 | |||
545 | if (channel->hw_value == CHANNEL_G) | ||
546 | if (ah->ah_mac_srev < AR5K_SREV_AR2413) | ||
547 | ath5k_hw_reg_write(ah, 0x00f80d80, | ||
548 | 0x994c); | ||
549 | else if (ah->ah_mac_srev < AR5K_SREV_AR5424) | ||
550 | ath5k_hw_reg_write(ah, 0x00380140, | ||
551 | 0x994c); | ||
552 | else if (ah->ah_mac_srev < AR5K_SREV_AR2425) | ||
553 | ath5k_hw_reg_write(ah, 0x00fc0ec0, | ||
554 | 0x994c); | ||
555 | else /* 2425 */ | ||
556 | ath5k_hw_reg_write(ah, 0x00fc0fc0, | ||
557 | 0x994c); | ||
558 | else | ||
559 | ath5k_hw_reg_write(ah, 0x00000000, 0x994c); | ||
560 | |||
561 | /* Some bits are disabled here, we know nothing about | ||
562 | * register 0xa228 yet, most of the times this ends up | ||
563 | * with a value 0x9b5 -haven't seen any dump with | ||
564 | * a different value- */ | ||
565 | /* Got this from decompiling binary HAL */ | ||
566 | data = ath5k_hw_reg_read(ah, 0xa228); | ||
567 | data &= 0xfffffdff; | ||
568 | ath5k_hw_reg_write(ah, data, 0xa228); | ||
569 | |||
570 | data = ath5k_hw_reg_read(ah, 0xa228); | ||
571 | data &= 0xfffe03ff; | ||
572 | ath5k_hw_reg_write(ah, data, 0xa228); | ||
573 | data = 0; | ||
574 | |||
575 | /* Just write 0x9b5 ? */ | ||
576 | /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */ | ||
577 | ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK); | ||
578 | ath5k_hw_reg_write(ah, 0x00000000, 0xa254); | ||
579 | ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL); | ||
580 | } | ||
581 | |||
582 | /* Fix for first revision of the RF5112 RF chipset */ | ||
583 | if (ah->ah_radio >= AR5K_RF5112 && | ||
584 | ah->ah_radio_5ghz_revision < | ||
585 | AR5K_SREV_RAD_5112A) { | ||
586 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, | ||
587 | AR5K_PHY_CCKTXCTL); | ||
588 | if (channel->hw_value & CHANNEL_5GHZ) | ||
589 | data = 0xffb81020; | ||
590 | else | ||
591 | data = 0xffb80d20; | ||
592 | ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); | ||
593 | data = 0; | ||
594 | } | ||
595 | |||
596 | /* | ||
597 | * Set TX power (FIXME) | ||
598 | */ | ||
599 | ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER); | ||
600 | if (ret) | ||
601 | return ret; | ||
602 | |||
603 | /* Write rate duration table only on AR5212 and if | ||
604 | * virtual interface has already been brought up | ||
605 | * XXX: rethink this after new mode changes to | ||
606 | * mac80211 are integrated */ | ||
607 | if (ah->ah_version == AR5K_AR5212 && | ||
608 | ah->ah_sc->vif != NULL) | ||
609 | ath5k_hw_write_rate_duration(ah, mode); | ||
610 | |||
611 | /* | ||
612 | * Write RF registers | ||
613 | */ | ||
614 | ret = ath5k_hw_rfregs(ah, channel, mode); | ||
615 | if (ret) | ||
616 | return ret; | ||
617 | |||
618 | /* | ||
619 | * Configure additional registers | ||
620 | */ | ||
621 | |||
622 | /* Write OFDM timings on 5212*/ | ||
623 | if (ah->ah_version == AR5K_AR5212 && | ||
624 | channel->hw_value & CHANNEL_OFDM) { | ||
625 | ret = ath5k_hw_write_ofdm_timings(ah, channel); | ||
626 | if (ret) | ||
627 | return ret; | ||
628 | } | ||
629 | |||
630 | /*Enable/disable 802.11b mode on 5111 | ||
631 | (enable 2111 frequency converter + CCK)*/ | ||
632 | if (ah->ah_radio == AR5K_RF5111) { | ||
633 | if (mode == AR5K_MODE_11B) | ||
634 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, | ||
635 | AR5K_TXCFG_B_MODE); | ||
636 | else | ||
637 | AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, | ||
638 | AR5K_TXCFG_B_MODE); | ||
639 | } | ||
640 | |||
641 | /* | ||
642 | * Set channel and calibrate the PHY | ||
643 | */ | ||
644 | ret = ath5k_hw_channel(ah, channel); | ||
645 | if (ret) | ||
646 | return ret; | ||
647 | |||
648 | /* Set antenna mode */ | ||
649 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL, | ||
650 | ah->ah_antenna[ee_mode][0], 0xfffffc06); | ||
651 | |||
652 | /* | ||
653 | * In case a fixed antenna was set as default | ||
654 | * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE | ||
655 | * registers. | ||
656 | */ | ||
657 | if (s_ant != 0) { | ||
658 | if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */ | ||
659 | ant[0] = ant[1] = AR5K_ANT_FIXED_A; | ||
660 | else /* 2 - Aux */ | ||
661 | ant[0] = ant[1] = AR5K_ANT_FIXED_B; | ||
662 | } else { | ||
663 | ant[0] = AR5K_ANT_FIXED_A; | ||
664 | ant[1] = AR5K_ANT_FIXED_B; | ||
665 | } | ||
666 | |||
667 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]], | ||
668 | AR5K_PHY_ANT_SWITCH_TABLE_0); | ||
669 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]], | ||
670 | AR5K_PHY_ANT_SWITCH_TABLE_1); | ||
671 | |||
672 | /* Commit values from EEPROM */ | ||
673 | if (ah->ah_radio == AR5K_RF5111) | ||
674 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL, | ||
675 | AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip); | ||
676 | |||
677 | ath5k_hw_reg_write(ah, | ||
678 | AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), | ||
679 | AR5K_PHY_NFTHRES); | ||
680 | |||
681 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING, | ||
682 | (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80, | ||
683 | 0xffffc07f); | ||
684 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN, | ||
685 | (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000, | ||
686 | 0xfffc0fff); | ||
687 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
688 | (ee->ee_adc_desired_size[ee_mode] & 0x00ff) | | ||
689 | ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00), | ||
690 | 0xffff0000); | ||
691 | |||
692 | ath5k_hw_reg_write(ah, | ||
693 | (ee->ee_tx_end2xpa_disable[ee_mode] << 24) | | ||
694 | (ee->ee_tx_end2xpa_disable[ee_mode] << 16) | | ||
695 | (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) | | ||
696 | (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4); | ||
697 | |||
698 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3, | ||
699 | ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff); | ||
700 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF, | ||
701 | (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff); | ||
702 | AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01); | ||
703 | |||
704 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
705 | AR5K_PHY_IQ_CORR_ENABLE | | ||
706 | (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | | ||
707 | ee->ee_q_cal[ee_mode]); | ||
708 | |||
709 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
710 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, | ||
711 | AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, | ||
712 | ee->ee_margin_tx_rx[ee_mode]); | ||
713 | |||
714 | } else { | ||
715 | mdelay(1); | ||
716 | /* Disable phy and wait */ | ||
717 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); | ||
718 | mdelay(1); | ||
719 | } | ||
720 | |||
721 | /* | ||
722 | * Restore saved values | ||
723 | */ | ||
724 | /*DCU/Antenna selection not available on 5210*/ | ||
725 | if (ah->ah_version != AR5K_AR5210) { | ||
726 | ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0)); | ||
727 | ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA); | ||
728 | } | ||
729 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]); | ||
730 | ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); | ||
731 | ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); | ||
732 | |||
733 | /* | ||
734 | * Misc | ||
735 | */ | ||
736 | /* XXX: add ah->aid once mac80211 gives this to us */ | ||
737 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); | ||
738 | |||
739 | ath5k_hw_set_opmode(ah); | ||
740 | /*PISR/SISR Not available on 5210*/ | ||
741 | if (ah->ah_version != AR5K_AR5210) { | ||
742 | ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); | ||
743 | /* If we later allow tuning for this, store into sc structure */ | ||
744 | data = AR5K_TUNE_RSSI_THRES | | ||
745 | AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S; | ||
746 | ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR); | ||
747 | } | ||
748 | |||
749 | /* | ||
750 | * Set Rx/Tx DMA Configuration | ||
751 | * | ||
752 | * Set maximum DMA size (512) except for PCI-E cards since | ||
753 | * it causes rx overruns and tx errors (tested on 5424 but since | ||
754 | * rx overruns also occur on 5416/5418 with madwifi we set 128 | ||
755 | * for all PCI-E cards to be safe). | ||
756 | * | ||
757 | * In dumps this is 128 for allchips. | ||
758 | * | ||
759 | * XXX: need to check 5210 for this | ||
760 | * TODO: Check out tx triger level, it's always 64 on dumps but I | ||
761 | * guess we can tweak it and see how it goes ;-) | ||
762 | */ | ||
763 | dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B; | ||
764 | if (ah->ah_version != AR5K_AR5210) { | ||
765 | AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, | ||
766 | AR5K_TXCFG_SDMAMR, dma_size); | ||
767 | AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, | ||
768 | AR5K_RXCFG_SDMAMW, dma_size); | ||
769 | } | ||
770 | |||
771 | /* | ||
772 | * Enable the PHY and wait until completion | ||
773 | */ | ||
774 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); | ||
775 | |||
776 | /* | ||
777 | * On 5211+ read activation -> rx delay | ||
778 | * and use it. | ||
779 | */ | ||
780 | if (ah->ah_version != AR5K_AR5210) { | ||
781 | data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | ||
782 | AR5K_PHY_RX_DELAY_M; | ||
783 | data = (channel->hw_value & CHANNEL_CCK) ? | ||
784 | ((data << 2) / 22) : (data / 10); | ||
785 | |||
786 | udelay(100 + (2 * data)); | ||
787 | data = 0; | ||
788 | } else { | ||
789 | mdelay(1); | ||
790 | } | ||
791 | |||
792 | /* | ||
793 | * Perform ADC test (?) | ||
794 | */ | ||
795 | data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); | ||
796 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); | ||
797 | for (i = 0; i <= 20; i++) { | ||
798 | if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) | ||
799 | break; | ||
800 | udelay(200); | ||
801 | } | ||
802 | ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1); | ||
803 | data = 0; | ||
804 | |||
805 | /* | ||
806 | * Start automatic gain calibration | ||
807 | * | ||
808 | * During AGC calibration RX path is re-routed to | ||
809 | * a signal detector so we don't receive anything. | ||
810 | * | ||
811 | * This method is used to calibrate some static offsets | ||
812 | * used together with on-the fly I/Q calibration (the | ||
813 | * one performed via ath5k_hw_phy_calibrate), that doesn't | ||
814 | * interrupt rx path. | ||
815 | * | ||
816 | * If we are in a noisy environment AGC calibration may time | ||
817 | * out. | ||
818 | */ | ||
819 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | ||
820 | AR5K_PHY_AGCCTL_CAL); | ||
821 | |||
822 | /* At the same time start I/Q calibration for QAM constellation | ||
823 | * -no need for CCK- */ | ||
824 | ah->ah_calibration = false; | ||
825 | if (!(mode == AR5K_MODE_11B)) { | ||
826 | ah->ah_calibration = true; | ||
827 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, | ||
828 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); | ||
829 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
830 | AR5K_PHY_IQ_RUN); | ||
831 | } | ||
832 | |||
833 | /* Wait for gain calibration to finish (we check for I/Q calibration | ||
834 | * during ath5k_phy_calibrate) */ | ||
835 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | ||
836 | AR5K_PHY_AGCCTL_CAL, 0, false)) { | ||
837 | ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", | ||
838 | channel->center_freq); | ||
839 | return -EAGAIN; | ||
840 | } | ||
841 | |||
842 | /* | ||
843 | * Start noise floor calibration | ||
844 | * | ||
845 | * If we run NF calibration before AGC, it always times out. | ||
846 | * Binary HAL starts NF and AGC calibration at the same time | ||
847 | * and only waits for AGC to finish. I believe that's wrong because | ||
848 | * during NF calibration, rx path is also routed to a detector, so if | ||
849 | * it doesn't finish we won't have RX. | ||
850 | * | ||
851 | * XXX: Find an interval that's OK for all cards... | ||
852 | */ | ||
853 | ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq); | ||
854 | if (ret) | ||
855 | return ret; | ||
856 | |||
857 | /* | ||
858 | * Reset queues and start beacon timers at the end of the reset routine | ||
859 | */ | ||
860 | for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { | ||
861 | /*No QCU on 5210*/ | ||
862 | if (ah->ah_version != AR5K_AR5210) | ||
863 | AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i); | ||
864 | |||
865 | ret = ath5k_hw_reset_tx_queue(ah, i); | ||
866 | if (ret) { | ||
867 | ATH5K_ERR(ah->ah_sc, | ||
868 | "failed to reset TX queue #%d\n", i); | ||
869 | return ret; | ||
870 | } | ||
871 | } | ||
872 | |||
873 | /* Pre-enable interrupts on 5211/5212*/ | ||
874 | if (ah->ah_version != AR5K_AR5210) | ||
875 | ath5k_hw_set_imr(ah, AR5K_INT_RX | AR5K_INT_TX | | ||
876 | AR5K_INT_FATAL); | ||
877 | |||
878 | /* | ||
879 | * Set RF kill flags if supported by the device (read from the EEPROM) | ||
880 | * Disable gpio_intr for now since it results system hang. | ||
881 | * TODO: Handle this in ath5k_intr | ||
882 | */ | ||
883 | #if 0 | ||
884 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { | ||
885 | ath5k_hw_set_gpio_input(ah, 0); | ||
886 | ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0); | ||
887 | if (ah->ah_gpio[0] == 0) | ||
888 | ath5k_hw_set_gpio_intr(ah, 0, 1); | ||
889 | else | ||
890 | ath5k_hw_set_gpio_intr(ah, 0, 0); | ||
891 | } | ||
892 | #endif | ||
893 | |||
894 | /* | ||
895 | * Set the 32MHz reference clock on 5212 phy clock sleep register | ||
896 | * | ||
897 | * TODO: Find out how to switch to external 32Khz clock to save power | ||
898 | */ | ||
899 | if (ah->ah_version == AR5K_AR5212) { | ||
900 | ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR); | ||
901 | ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT); | ||
902 | ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL); | ||
903 | ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); | ||
904 | ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); | ||
905 | ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING); | ||
906 | |||
907 | data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ; | ||
908 | data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ? | ||
909 | 0x00000f80 : 0x00001380 ; | ||
910 | ath5k_hw_reg_write(ah, data, AR5K_USEC_5211); | ||
911 | data = 0; | ||
912 | } | ||
913 | |||
914 | if (ah->ah_version == AR5K_AR5212) { | ||
915 | ath5k_hw_reg_write(ah, 0x000100aa, 0x8118); | ||
916 | ath5k_hw_reg_write(ah, 0x00003210, 0x811c); | ||
917 | ath5k_hw_reg_write(ah, 0x00000052, 0x8108); | ||
918 | if (ah->ah_mac_srev >= AR5K_SREV_AR2413) | ||
919 | ath5k_hw_reg_write(ah, 0x00000004, 0x8120); | ||
920 | } | ||
921 | |||
922 | /* | ||
923 | * Disable beacons and reset the register | ||
924 | */ | ||
925 | AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | | ||
926 | AR5K_BEACON_RESET_TSF); | ||
927 | |||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | #undef _ATH5K_RESET | ||