ath9k: Incorrect key used when group and pairwise ciphers are different.
[pandora-kernel.git] / drivers / net / wireless / ath9k / hw.c
1 /*
2  * Copyright (c) 2008 Atheros Communications Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include <linux/io.h>
18 #include <asm/unaligned.h>
19
20 #include "core.h"
21 #include "hw.h"
22 #include "reg.h"
23 #include "phy.h"
24 #include "initvals.h"
25
26 static void ath9k_hw_iqcal_collect(struct ath_hal *ah);
27 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains);
28 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah);
29 static void ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah,
30                                            u8 numChains);
31 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah);
32 static void ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah,
33                                          u8 numChains);
34
35 static const u8 CLOCK_RATE[] = { 40, 80, 22, 44, 88, 40 };
36 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93, -96 };
37
38 static const struct hal_percal_data iq_cal_multi_sample = {
39         IQ_MISMATCH_CAL,
40         MAX_CAL_SAMPLES,
41         PER_MIN_LOG_COUNT,
42         ath9k_hw_iqcal_collect,
43         ath9k_hw_iqcalibrate
44 };
45 static const struct hal_percal_data iq_cal_single_sample = {
46         IQ_MISMATCH_CAL,
47         MIN_CAL_SAMPLES,
48         PER_MAX_LOG_COUNT,
49         ath9k_hw_iqcal_collect,
50         ath9k_hw_iqcalibrate
51 };
52 static const struct hal_percal_data adc_gain_cal_multi_sample = {
53         ADC_GAIN_CAL,
54         MAX_CAL_SAMPLES,
55         PER_MIN_LOG_COUNT,
56         ath9k_hw_adc_gaincal_collect,
57         ath9k_hw_adc_gaincal_calibrate
58 };
59 static const struct hal_percal_data adc_gain_cal_single_sample = {
60         ADC_GAIN_CAL,
61         MIN_CAL_SAMPLES,
62         PER_MAX_LOG_COUNT,
63         ath9k_hw_adc_gaincal_collect,
64         ath9k_hw_adc_gaincal_calibrate
65 };
66 static const struct hal_percal_data adc_dc_cal_multi_sample = {
67         ADC_DC_CAL,
68         MAX_CAL_SAMPLES,
69         PER_MIN_LOG_COUNT,
70         ath9k_hw_adc_dccal_collect,
71         ath9k_hw_adc_dccal_calibrate
72 };
73 static const struct hal_percal_data adc_dc_cal_single_sample = {
74         ADC_DC_CAL,
75         MIN_CAL_SAMPLES,
76         PER_MAX_LOG_COUNT,
77         ath9k_hw_adc_dccal_collect,
78         ath9k_hw_adc_dccal_calibrate
79 };
80 static const struct hal_percal_data adc_init_dc_cal = {
81         ADC_DC_INIT_CAL,
82         MIN_CAL_SAMPLES,
83         INIT_LOG_COUNT,
84         ath9k_hw_adc_dccal_collect,
85         ath9k_hw_adc_dccal_calibrate
86 };
87
88 static const struct ath_hal ar5416hal = {
89         AR5416_MAGIC,
90         0,
91         0,
92         NULL,
93         NULL,
94         CTRY_DEFAULT,
95         0,
96         0,
97         0,
98         0,
99         0,
100         {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
101          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
102          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
103          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
104          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
105          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
106          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
107          0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
108         },
109 };
110
111 static struct ath9k_rate_table ar5416_11a_table = {
112         8,
113         {0},
114         {
115                 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
116                 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
117                 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
118                 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
119                 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
120                 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
121                 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
122                 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4}
123         },
124 };
125
126 static struct ath9k_rate_table ar5416_11b_table = {
127         4,
128         {0},
129         {
130                 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
131                 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
132                 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 1},
133                 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 1}
134         },
135 };
136
137 static struct ath9k_rate_table ar5416_11g_table = {
138         12,
139         {0},
140         {
141                 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
142                 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
143                 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
144                 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
145
146                 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
147                 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
148                 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
149                 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
150                 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
151                 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
152                 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
153                 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8}
154         },
155 };
156
157 static struct ath9k_rate_table ar5416_11ng_table = {
158         28,
159         {0},
160         {
161                 {true, PHY_CCK, 1000, 0x1b, 0x00, (0x80 | 2), 0},
162                 {true, PHY_CCK, 2000, 0x1a, 0x04, (0x80 | 4), 1},
163                 {true, PHY_CCK, 5500, 0x19, 0x04, (0x80 | 11), 2},
164                 {true, PHY_CCK, 11000, 0x18, 0x04, (0x80 | 22), 3},
165
166                 {false, PHY_OFDM, 6000, 0x0b, 0x00, 12, 4},
167                 {false, PHY_OFDM, 9000, 0x0f, 0x00, 18, 4},
168                 {true, PHY_OFDM, 12000, 0x0a, 0x00, 24, 6},
169                 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 6},
170                 {true, PHY_OFDM, 24000, 0x09, 0x00, 48, 8},
171                 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 8},
172                 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 8},
173                 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 8},
174                 {true, PHY_HT, 6500, 0x80, 0x00, 0, 4},
175                 {true, PHY_HT, 13000, 0x81, 0x00, 1, 6},
176                 {true, PHY_HT, 19500, 0x82, 0x00, 2, 6},
177                 {true, PHY_HT, 26000, 0x83, 0x00, 3, 8},
178                 {true, PHY_HT, 39000, 0x84, 0x00, 4, 8},
179                 {true, PHY_HT, 52000, 0x85, 0x00, 5, 8},
180                 {true, PHY_HT, 58500, 0x86, 0x00, 6, 8},
181                 {true, PHY_HT, 65000, 0x87, 0x00, 7, 8},
182                 {true, PHY_HT, 13000, 0x88, 0x00, 8, 4},
183                 {true, PHY_HT, 26000, 0x89, 0x00, 9, 6},
184                 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 6},
185                 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 8},
186                 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 8},
187                 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 8},
188                 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 8},
189                 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 8},
190         },
191 };
192
193 static struct ath9k_rate_table ar5416_11na_table = {
194         24,
195         {0},
196         {
197                 {true, PHY_OFDM, 6000, 0x0b, 0x00, (0x80 | 12), 0},
198                 {true, PHY_OFDM, 9000, 0x0f, 0x00, 18, 0},
199                 {true, PHY_OFDM, 12000, 0x0a, 0x00, (0x80 | 24), 2},
200                 {true, PHY_OFDM, 18000, 0x0e, 0x00, 36, 2},
201                 {true, PHY_OFDM, 24000, 0x09, 0x00, (0x80 | 48), 4},
202                 {true, PHY_OFDM, 36000, 0x0d, 0x00, 72, 4},
203                 {true, PHY_OFDM, 48000, 0x08, 0x00, 96, 4},
204                 {true, PHY_OFDM, 54000, 0x0c, 0x00, 108, 4},
205                 {true, PHY_HT, 6500, 0x80, 0x00, 0, 0},
206                 {true, PHY_HT, 13000, 0x81, 0x00, 1, 2},
207                 {true, PHY_HT, 19500, 0x82, 0x00, 2, 2},
208                 {true, PHY_HT, 26000, 0x83, 0x00, 3, 4},
209                 {true, PHY_HT, 39000, 0x84, 0x00, 4, 4},
210                 {true, PHY_HT, 52000, 0x85, 0x00, 5, 4},
211                 {true, PHY_HT, 58500, 0x86, 0x00, 6, 4},
212                 {true, PHY_HT, 65000, 0x87, 0x00, 7, 4},
213                 {true, PHY_HT, 13000, 0x88, 0x00, 8, 0},
214                 {true, PHY_HT, 26000, 0x89, 0x00, 9, 2},
215                 {true, PHY_HT, 39000, 0x8a, 0x00, 10, 2},
216                 {true, PHY_HT, 52000, 0x8b, 0x00, 11, 4},
217                 {true, PHY_HT, 78000, 0x8c, 0x00, 12, 4},
218                 {true, PHY_HT, 104000, 0x8d, 0x00, 13, 4},
219                 {true, PHY_HT, 117000, 0x8e, 0x00, 14, 4},
220                 {true, PHY_HT, 130000, 0x8f, 0x00, 15, 4},
221         },
222 };
223
224 static enum wireless_mode ath9k_hw_chan2wmode(struct ath_hal *ah,
225                                        const struct ath9k_channel *chan)
226 {
227         if (IS_CHAN_CCK(chan))
228                 return ATH9K_MODE_11A;
229         if (IS_CHAN_G(chan))
230                 return ATH9K_MODE_11G;
231         return ATH9K_MODE_11A;
232 }
233
234 static bool ath9k_hw_wait(struct ath_hal *ah,
235                           u32 reg,
236                           u32 mask,
237                           u32 val)
238 {
239         int i;
240
241         for (i = 0; i < (AH_TIMEOUT / AH_TIME_QUANTUM); i++) {
242                 if ((REG_READ(ah, reg) & mask) == val)
243                         return true;
244
245                 udelay(AH_TIME_QUANTUM);
246         }
247         DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
248                  "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
249                  __func__, reg, REG_READ(ah, reg), mask, val);
250         return false;
251 }
252
253 static bool ath9k_hw_eeprom_read(struct ath_hal *ah, u32 off,
254                                  u16 *data)
255 {
256         (void) REG_READ(ah, AR5416_EEPROM_OFFSET + (off << AR5416_EEPROM_S));
257
258         if (!ath9k_hw_wait(ah,
259                            AR_EEPROM_STATUS_DATA,
260                            AR_EEPROM_STATUS_DATA_BUSY |
261                            AR_EEPROM_STATUS_DATA_PROT_ACCESS, 0)) {
262                 return false;
263         }
264
265         *data = MS(REG_READ(ah, AR_EEPROM_STATUS_DATA),
266                    AR_EEPROM_STATUS_DATA_VAL);
267
268         return true;
269 }
270
271 static int ath9k_hw_flash_map(struct ath_hal *ah)
272 {
273         struct ath_hal_5416 *ahp = AH5416(ah);
274
275         ahp->ah_cal_mem = ioremap(AR5416_EEPROM_START_ADDR, AR5416_EEPROM_MAX);
276
277         if (!ahp->ah_cal_mem) {
278                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
279                          "%s: cannot remap eeprom region \n", __func__);
280                 return -EIO;
281         }
282
283         return 0;
284 }
285
286 static bool ath9k_hw_flash_read(struct ath_hal *ah, u32 off,
287                                 u16 *data)
288 {
289         struct ath_hal_5416 *ahp = AH5416(ah);
290
291         *data = ioread16(ahp->ah_cal_mem + off);
292         return true;
293 }
294
295 static void ath9k_hw_read_revisions(struct ath_hal *ah)
296 {
297         u32 val;
298
299         val = REG_READ(ah, AR_SREV) & AR_SREV_ID;
300
301         if (val == 0xFF) {
302                 val = REG_READ(ah, AR_SREV);
303
304                 ah->ah_macVersion =
305                         (val & AR_SREV_VERSION2) >> AR_SREV_TYPE2_S;
306
307                 ah->ah_macRev = MS(val, AR_SREV_REVISION2);
308                 ah->ah_isPciExpress =
309                         (val & AR_SREV_TYPE2_HOST_MODE) ? 0 : 1;
310
311         } else {
312                 if (!AR_SREV_9100(ah))
313                         ah->ah_macVersion = MS(val, AR_SREV_VERSION);
314
315                 ah->ah_macRev = val & AR_SREV_REVISION;
316
317                 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE)
318                         ah->ah_isPciExpress = true;
319         }
320 }
321
322 u32 ath9k_hw_reverse_bits(u32 val, u32 n)
323 {
324         u32 retval;
325         int i;
326
327         for (i = 0, retval = 0; i < n; i++) {
328                 retval = (retval << 1) | (val & 1);
329                 val >>= 1;
330         }
331         return retval;
332 }
333
334 static void ath9k_hw_set_defaults(struct ath_hal *ah)
335 {
336         int i;
337
338         ah->ah_config.dma_beacon_response_time = 2;
339         ah->ah_config.sw_beacon_response_time = 10;
340         ah->ah_config.additional_swba_backoff = 0;
341         ah->ah_config.ack_6mb = 0x0;
342         ah->ah_config.cwm_ignore_extcca = 0;
343         ah->ah_config.pcie_powersave_enable = 0;
344         ah->ah_config.pcie_l1skp_enable = 0;
345         ah->ah_config.pcie_clock_req = 0;
346         ah->ah_config.pcie_power_reset = 0x100;
347         ah->ah_config.pcie_restore = 0;
348         ah->ah_config.pcie_waen = 0;
349         ah->ah_config.analog_shiftreg = 1;
350         ah->ah_config.ht_enable = 1;
351         ah->ah_config.ofdm_trig_low = 200;
352         ah->ah_config.ofdm_trig_high = 500;
353         ah->ah_config.cck_trig_high = 200;
354         ah->ah_config.cck_trig_low = 100;
355         ah->ah_config.enable_ani = 0;
356         ah->ah_config.noise_immunity_level = 4;
357         ah->ah_config.ofdm_weaksignal_det = 1;
358         ah->ah_config.cck_weaksignal_thr = 0;
359         ah->ah_config.spur_immunity_level = 2;
360         ah->ah_config.firstep_level = 0;
361         ah->ah_config.rssi_thr_high = 40;
362         ah->ah_config.rssi_thr_low = 7;
363         ah->ah_config.diversity_control = 0;
364         ah->ah_config.antenna_switch_swap = 0;
365
366         for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
367                 ah->ah_config.spurchans[i][0] = AR_NO_SPUR;
368                 ah->ah_config.spurchans[i][1] = AR_NO_SPUR;
369         }
370
371         ah->ah_config.intr_mitigation = 0;
372 }
373
374 static inline void ath9k_hw_override_ini(struct ath_hal *ah,
375                                          struct ath9k_channel *chan)
376 {
377         if (!AR_SREV_5416_V20_OR_LATER(ah)
378             || AR_SREV_9280_10_OR_LATER(ah))
379                 return;
380
381         REG_WRITE(ah, 0x9800 + (651 << 2), 0x11);
382 }
383
384 static inline void ath9k_hw_init_bb(struct ath_hal *ah,
385                                     struct ath9k_channel *chan)
386 {
387         u32 synthDelay;
388
389         synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
390         if (IS_CHAN_CCK(chan))
391                 synthDelay = (4 * synthDelay) / 22;
392         else
393                 synthDelay /= 10;
394
395         REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
396
397         udelay(synthDelay + BASE_ACTIVATE_DELAY);
398 }
399
400 static inline void ath9k_hw_init_interrupt_masks(struct ath_hal *ah,
401                                                  enum ath9k_opmode opmode)
402 {
403         struct ath_hal_5416 *ahp = AH5416(ah);
404
405         ahp->ah_maskReg = AR_IMR_TXERR |
406                 AR_IMR_TXURN |
407                 AR_IMR_RXERR |
408                 AR_IMR_RXORN |
409                 AR_IMR_BCNMISC;
410
411         if (ahp->ah_intrMitigation)
412                 ahp->ah_maskReg |= AR_IMR_RXINTM | AR_IMR_RXMINTR;
413         else
414                 ahp->ah_maskReg |= AR_IMR_RXOK;
415
416         ahp->ah_maskReg |= AR_IMR_TXOK;
417
418         if (opmode == ATH9K_M_HOSTAP)
419                 ahp->ah_maskReg |= AR_IMR_MIB;
420
421         REG_WRITE(ah, AR_IMR, ahp->ah_maskReg);
422         REG_WRITE(ah, AR_IMR_S2, REG_READ(ah, AR_IMR_S2) | AR_IMR_S2_GTT);
423
424         if (!AR_SREV_9100(ah)) {
425                 REG_WRITE(ah, AR_INTR_SYNC_CAUSE, 0xFFFFFFFF);
426                 REG_WRITE(ah, AR_INTR_SYNC_ENABLE, AR_INTR_SYNC_DEFAULT);
427                 REG_WRITE(ah, AR_INTR_SYNC_MASK, 0);
428         }
429 }
430
431 static inline void ath9k_hw_init_qos(struct ath_hal *ah)
432 {
433         REG_WRITE(ah, AR_MIC_QOS_CONTROL, 0x100aa);
434         REG_WRITE(ah, AR_MIC_QOS_SELECT, 0x3210);
435
436         REG_WRITE(ah, AR_QOS_NO_ACK,
437                   SM(2, AR_QOS_NO_ACK_TWO_BIT) |
438                   SM(5, AR_QOS_NO_ACK_BIT_OFF) |
439                   SM(0, AR_QOS_NO_ACK_BYTE_OFF));
440
441         REG_WRITE(ah, AR_TXOP_X, AR_TXOP_X_VAL);
442         REG_WRITE(ah, AR_TXOP_0_3, 0xFFFFFFFF);
443         REG_WRITE(ah, AR_TXOP_4_7, 0xFFFFFFFF);
444         REG_WRITE(ah, AR_TXOP_8_11, 0xFFFFFFFF);
445         REG_WRITE(ah, AR_TXOP_12_15, 0xFFFFFFFF);
446 }
447
448 static void ath9k_hw_analog_shift_rmw(struct ath_hal *ah,
449                                       u32 reg,
450                                       u32 mask,
451                                       u32 shift,
452                                       u32 val)
453 {
454         u32 regVal;
455
456         regVal = REG_READ(ah, reg) & ~mask;
457         regVal |= (val << shift) & mask;
458
459         REG_WRITE(ah, reg, regVal);
460
461         if (ah->ah_config.analog_shiftreg)
462                 udelay(100);
463
464         return;
465 }
466
467 static u8 ath9k_hw_get_num_ant_config(struct ath_hal_5416 *ahp,
468                                       enum ieee80211_band freq_band)
469 {
470         struct ar5416_eeprom *eep = &ahp->ah_eeprom;
471         struct modal_eep_header *pModal =
472                 &(eep->modalHeader[IEEE80211_BAND_5GHZ == freq_band]);
473         struct base_eep_header *pBase = &eep->baseEepHeader;
474         u8 num_ant_config;
475
476         num_ant_config = 1;
477
478         if (pBase->version >= 0x0E0D)
479                 if (pModal->useAnt1)
480                         num_ant_config += 1;
481
482         return num_ant_config;
483 }
484
485 static int
486 ath9k_hw_get_eeprom_antenna_cfg(struct ath_hal_5416 *ahp,
487                                 struct ath9k_channel *chan,
488                                 u8 index,
489                                 u16 *config)
490 {
491         struct ar5416_eeprom *eep = &ahp->ah_eeprom;
492         struct modal_eep_header *pModal =
493                 &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
494         struct base_eep_header *pBase = &eep->baseEepHeader;
495
496         switch (index) {
497         case 0:
498                 *config = pModal->antCtrlCommon & 0xFFFF;
499                 return 0;
500         case 1:
501                 if (pBase->version >= 0x0E0D) {
502                         if (pModal->useAnt1) {
503                                 *config =
504                                 ((pModal->antCtrlCommon & 0xFFFF0000) >> 16);
505                                 return 0;
506                         }
507                 }
508                 break;
509         default:
510                 break;
511         }
512
513         return -EINVAL;
514 }
515
516 static inline bool ath9k_hw_nvram_read(struct ath_hal *ah,
517                                        u32 off,
518                                        u16 *data)
519 {
520         if (ath9k_hw_use_flash(ah))
521                 return ath9k_hw_flash_read(ah, off, data);
522         else
523                 return ath9k_hw_eeprom_read(ah, off, data);
524 }
525
526 static inline bool ath9k_hw_fill_eeprom(struct ath_hal *ah)
527 {
528         struct ath_hal_5416 *ahp = AH5416(ah);
529         struct ar5416_eeprom *eep = &ahp->ah_eeprom;
530         u16 *eep_data;
531         int addr, ar5416_eep_start_loc = 0;
532
533         if (!ath9k_hw_use_flash(ah)) {
534                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
535                          "%s: Reading from EEPROM, not flash\n", __func__);
536                 ar5416_eep_start_loc = 256;
537         }
538         if (AR_SREV_9100(ah))
539                 ar5416_eep_start_loc = 256;
540
541         eep_data = (u16 *) eep;
542         for (addr = 0;
543              addr < sizeof(struct ar5416_eeprom) / sizeof(u16);
544              addr++) {
545                 if (!ath9k_hw_nvram_read(ah, addr + ar5416_eep_start_loc,
546                                          eep_data)) {
547                         DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
548                                  "%s: Unable to read eeprom region \n",
549                                  __func__);
550                         return false;
551                 }
552                 eep_data++;
553         }
554         return true;
555 }
556
557 /* XXX: Clean me up, make me more legible */
558 static bool
559 ath9k_hw_eeprom_set_board_values(struct ath_hal *ah,
560                                  struct ath9k_channel *chan)
561 {
562         struct modal_eep_header *pModal;
563         int i, regChainOffset;
564         struct ath_hal_5416 *ahp = AH5416(ah);
565         struct ar5416_eeprom *eep = &ahp->ah_eeprom;
566         u8 txRxAttenLocal;
567         u16 ant_config;
568
569         pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
570
571         txRxAttenLocal = IS_CHAN_2GHZ(chan) ? 23 : 44;
572
573         ath9k_hw_get_eeprom_antenna_cfg(ahp, chan, 1, &ant_config);
574         REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
575
576         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
577                 if (AR_SREV_9280(ah)) {
578                         if (i >= 2)
579                                 break;
580                 }
581
582                 if (AR_SREV_5416_V20_OR_LATER(ah) &&
583                     (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
584                     && (i != 0))
585                         regChainOffset = (i == 1) ? 0x2000 : 0x1000;
586                 else
587                         regChainOffset = i * 0x1000;
588
589                 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0 + regChainOffset,
590                           pModal->antCtrlChain[i]);
591
592                 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0) + regChainOffset,
593                           (REG_READ(ah,
594                                     AR_PHY_TIMING_CTRL4(0) +
595                                     regChainOffset) &
596                            ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF |
597                              AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) |
598                           SM(pModal->iqCalICh[i],
599                              AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
600                           SM(pModal->iqCalQCh[i],
601                              AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
602
603                 if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
604                         if ((eep->baseEepHeader.version &
605                              AR5416_EEP_VER_MINOR_MASK) >=
606                             AR5416_EEP_MINOR_VER_3) {
607                                 txRxAttenLocal = pModal->txRxAttenCh[i];
608                                 if (AR_SREV_9280_10_OR_LATER(ah)) {
609                                         REG_RMW_FIELD(ah,
610                                                 AR_PHY_GAIN_2GHZ +
611                                                 regChainOffset,
612                                                 AR_PHY_GAIN_2GHZ_XATTEN1_MARGIN,
613                                                 pModal->
614                                                 bswMargin[i]);
615                                         REG_RMW_FIELD(ah,
616                                                 AR_PHY_GAIN_2GHZ +
617                                                 regChainOffset,
618                                                 AR_PHY_GAIN_2GHZ_XATTEN1_DB,
619                                                 pModal->
620                                                 bswAtten[i]);
621                                         REG_RMW_FIELD(ah,
622                                                 AR_PHY_GAIN_2GHZ +
623                                                 regChainOffset,
624                                                 AR_PHY_GAIN_2GHZ_XATTEN2_MARGIN,
625                                                 pModal->
626                                                 xatten2Margin[i]);
627                                         REG_RMW_FIELD(ah,
628                                                 AR_PHY_GAIN_2GHZ +
629                                                 regChainOffset,
630                                                 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
631                                                 pModal->
632                                                 xatten2Db[i]);
633                                 } else {
634                                         REG_WRITE(ah,
635                                                   AR_PHY_GAIN_2GHZ +
636                                                   regChainOffset,
637                                                   (REG_READ(ah,
638                                                             AR_PHY_GAIN_2GHZ +
639                                                             regChainOffset) &
640                                                    ~AR_PHY_GAIN_2GHZ_BSW_MARGIN)
641                                                   | SM(pModal->
642                                                   bswMargin[i],
643                                                   AR_PHY_GAIN_2GHZ_BSW_MARGIN));
644                                         REG_WRITE(ah,
645                                                   AR_PHY_GAIN_2GHZ +
646                                                   regChainOffset,
647                                                   (REG_READ(ah,
648                                                             AR_PHY_GAIN_2GHZ +
649                                                             regChainOffset) &
650                                                    ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
651                                                   | SM(pModal->bswAtten[i],
652                                                   AR_PHY_GAIN_2GHZ_BSW_ATTEN));
653                                 }
654                         }
655                         if (AR_SREV_9280_10_OR_LATER(ah)) {
656                                 REG_RMW_FIELD(ah,
657                                               AR_PHY_RXGAIN +
658                                               regChainOffset,
659                                               AR9280_PHY_RXGAIN_TXRX_ATTEN,
660                                               txRxAttenLocal);
661                                 REG_RMW_FIELD(ah,
662                                               AR_PHY_RXGAIN +
663                                               regChainOffset,
664                                               AR9280_PHY_RXGAIN_TXRX_MARGIN,
665                                               pModal->rxTxMarginCh[i]);
666                         } else {
667                                 REG_WRITE(ah,
668                                           AR_PHY_RXGAIN + regChainOffset,
669                                           (REG_READ(ah,
670                                                     AR_PHY_RXGAIN +
671                                                     regChainOffset) &
672                                            ~AR_PHY_RXGAIN_TXRX_ATTEN) |
673                                           SM(txRxAttenLocal,
674                                              AR_PHY_RXGAIN_TXRX_ATTEN));
675                                 REG_WRITE(ah,
676                                           AR_PHY_GAIN_2GHZ +
677                                           regChainOffset,
678                                           (REG_READ(ah,
679                                                     AR_PHY_GAIN_2GHZ +
680                                                     regChainOffset) &
681                                            ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
682                                           SM(pModal->rxTxMarginCh[i],
683                                              AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
684                         }
685                 }
686         }
687
688         if (AR_SREV_9280_10_OR_LATER(ah)) {
689                 if (IS_CHAN_2GHZ(chan)) {
690                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
691                                                   AR_AN_RF2G1_CH0_OB,
692                                                   AR_AN_RF2G1_CH0_OB_S,
693                                                   pModal->ob);
694                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH0,
695                                                   AR_AN_RF2G1_CH0_DB,
696                                                   AR_AN_RF2G1_CH0_DB_S,
697                                                   pModal->db);
698                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
699                                                   AR_AN_RF2G1_CH1_OB,
700                                                   AR_AN_RF2G1_CH1_OB_S,
701                                                   pModal->ob_ch1);
702                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF2G1_CH1,
703                                                   AR_AN_RF2G1_CH1_DB,
704                                                   AR_AN_RF2G1_CH1_DB_S,
705                                                   pModal->db_ch1);
706                 } else {
707                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
708                                                   AR_AN_RF5G1_CH0_OB5,
709                                                   AR_AN_RF5G1_CH0_OB5_S,
710                                                   pModal->ob);
711                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH0,
712                                                   AR_AN_RF5G1_CH0_DB5,
713                                                   AR_AN_RF5G1_CH0_DB5_S,
714                                                   pModal->db);
715                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
716                                                   AR_AN_RF5G1_CH1_OB5,
717                                                   AR_AN_RF5G1_CH1_OB5_S,
718                                                   pModal->ob_ch1);
719                         ath9k_hw_analog_shift_rmw(ah, AR_AN_RF5G1_CH1,
720                                                   AR_AN_RF5G1_CH1_DB5,
721                                                   AR_AN_RF5G1_CH1_DB5_S,
722                                                   pModal->db_ch1);
723                 }
724                 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
725                                           AR_AN_TOP2_XPABIAS_LVL,
726                                           AR_AN_TOP2_XPABIAS_LVL_S,
727                                           pModal->xpaBiasLvl);
728                 ath9k_hw_analog_shift_rmw(ah, AR_AN_TOP2,
729                                           AR_AN_TOP2_LOCALBIAS,
730                                           AR_AN_TOP2_LOCALBIAS_S,
731                                           pModal->local_bias);
732                 DPRINTF(ah->ah_sc, ATH_DBG_ANY, "ForceXPAon: %d\n",
733                         pModal->force_xpaon);
734                 REG_RMW_FIELD(ah, AR_PHY_XPA_CFG, AR_PHY_FORCE_XPA_CFG,
735                               pModal->force_xpaon);
736         }
737
738         REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
739                       pModal->switchSettling);
740         REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
741                       pModal->adcDesiredSize);
742
743         if (!AR_SREV_9280_10_OR_LATER(ah))
744                 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
745                               AR_PHY_DESIRED_SZ_PGA,
746                               pModal->pgaDesiredSize);
747
748         REG_WRITE(ah, AR_PHY_RF_CTL4,
749                   SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF)
750                   | SM(pModal->txEndToXpaOff,
751                        AR_PHY_RF_CTL4_TX_END_XPAB_OFF)
752                   | SM(pModal->txFrameToXpaOn,
753                        AR_PHY_RF_CTL4_FRAME_XPAA_ON)
754                   | SM(pModal->txFrameToXpaOn,
755                        AR_PHY_RF_CTL4_FRAME_XPAB_ON));
756
757         REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
758                       pModal->txEndToRxOn);
759         if (AR_SREV_9280_10_OR_LATER(ah)) {
760                 REG_RMW_FIELD(ah, AR_PHY_CCA, AR9280_PHY_CCA_THRESH62,
761                               pModal->thresh62);
762                 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA0,
763                               AR_PHY_EXT_CCA0_THRESH62,
764                               pModal->thresh62);
765         } else {
766                 REG_RMW_FIELD(ah, AR_PHY_CCA, AR_PHY_CCA_THRESH62,
767                               pModal->thresh62);
768                 REG_RMW_FIELD(ah, AR_PHY_EXT_CCA,
769                               AR_PHY_EXT_CCA_THRESH62,
770                               pModal->thresh62);
771         }
772
773         if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
774             AR5416_EEP_MINOR_VER_2) {
775                 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2,
776                               AR_PHY_TX_END_DATA_START,
777                               pModal->txFrameToDataStart);
778                 REG_RMW_FIELD(ah, AR_PHY_RF_CTL2, AR_PHY_TX_END_PA_ON,
779                               pModal->txFrameToPaOn);
780         }
781
782         if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
783             AR5416_EEP_MINOR_VER_3) {
784                 if (IS_CHAN_HT40(chan))
785                         REG_RMW_FIELD(ah, AR_PHY_SETTLING,
786                                       AR_PHY_SETTLING_SWITCH,
787                                       pModal->swSettleHt40);
788         }
789
790         return true;
791 }
792
793 static inline int ath9k_hw_check_eeprom(struct ath_hal *ah)
794 {
795         u32 sum = 0, el;
796         u16 *eepdata;
797         int i;
798         struct ath_hal_5416 *ahp = AH5416(ah);
799         bool need_swap = false;
800         struct ar5416_eeprom *eep =
801                 (struct ar5416_eeprom *) &ahp->ah_eeprom;
802
803         if (!ath9k_hw_use_flash(ah)) {
804                 u16 magic, magic2;
805                 int addr;
806
807                 if (!ath9k_hw_nvram_read(ah, AR5416_EEPROM_MAGIC_OFFSET,
808                                         &magic)) {
809                         DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
810                                  "%s: Reading Magic # failed\n", __func__);
811                         return false;
812                 }
813                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "%s: Read Magic = 0x%04X\n",
814                          __func__, magic);
815
816                 if (magic != AR5416_EEPROM_MAGIC) {
817                         magic2 = swab16(magic);
818
819                         if (magic2 == AR5416_EEPROM_MAGIC) {
820                                 need_swap = true;
821                                 eepdata = (u16 *) (&ahp->ah_eeprom);
822
823                                 for (addr = 0;
824                                      addr <
825                                              sizeof(struct ar5416_eeprom) /
826                                              sizeof(u16); addr++) {
827                                         u16 temp;
828
829                                         temp = swab16(*eepdata);
830                                         *eepdata = temp;
831                                         eepdata++;
832
833                                         DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
834                                                  "0x%04X  ", *eepdata);
835                                         if (((addr + 1) % 6) == 0)
836                                                 DPRINTF(ah->ah_sc,
837                                                          ATH_DBG_EEPROM,
838                                                          "\n");
839                                 }
840                         } else {
841                                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
842                                          "Invalid EEPROM Magic. "
843                                         "endianness missmatch.\n");
844                                 return -EINVAL;
845                         }
846                 }
847         }
848         DPRINTF(ah->ah_sc, ATH_DBG_EEPROM, "need_swap = %s.\n",
849                  need_swap ? "True" : "False");
850
851         if (need_swap)
852                 el = swab16(ahp->ah_eeprom.baseEepHeader.length);
853         else
854                 el = ahp->ah_eeprom.baseEepHeader.length;
855
856         if (el > sizeof(struct ar5416_eeprom))
857                 el = sizeof(struct ar5416_eeprom) / sizeof(u16);
858         else
859                 el = el / sizeof(u16);
860
861         eepdata = (u16 *) (&ahp->ah_eeprom);
862
863         for (i = 0; i < el; i++)
864                 sum ^= *eepdata++;
865
866         if (need_swap) {
867                 u32 integer, j;
868                 u16 word;
869
870                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
871                          "EEPROM Endianness is not native.. Changing \n");
872
873                 word = swab16(eep->baseEepHeader.length);
874                 eep->baseEepHeader.length = word;
875
876                 word = swab16(eep->baseEepHeader.checksum);
877                 eep->baseEepHeader.checksum = word;
878
879                 word = swab16(eep->baseEepHeader.version);
880                 eep->baseEepHeader.version = word;
881
882                 word = swab16(eep->baseEepHeader.regDmn[0]);
883                 eep->baseEepHeader.regDmn[0] = word;
884
885                 word = swab16(eep->baseEepHeader.regDmn[1]);
886                 eep->baseEepHeader.regDmn[1] = word;
887
888                 word = swab16(eep->baseEepHeader.rfSilent);
889                 eep->baseEepHeader.rfSilent = word;
890
891                 word = swab16(eep->baseEepHeader.blueToothOptions);
892                 eep->baseEepHeader.blueToothOptions = word;
893
894                 word = swab16(eep->baseEepHeader.deviceCap);
895                 eep->baseEepHeader.deviceCap = word;
896
897                 for (j = 0; j < ARRAY_SIZE(eep->modalHeader); j++) {
898                         struct modal_eep_header *pModal =
899                                 &eep->modalHeader[j];
900                         integer = swab32(pModal->antCtrlCommon);
901                         pModal->antCtrlCommon = integer;
902
903                         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
904                                 integer = swab32(pModal->antCtrlChain[i]);
905                                 pModal->antCtrlChain[i] = integer;
906                         }
907
908                         for (i = 0; i < AR5416_EEPROM_MODAL_SPURS; i++) {
909                                 word = swab16(pModal->spurChans[i].spurChan);
910                                 pModal->spurChans[i].spurChan = word;
911                         }
912                 }
913         }
914
915         if (sum != 0xffff || ar5416_get_eep_ver(ahp) != AR5416_EEP_VER ||
916             ar5416_get_eep_rev(ahp) < AR5416_EEP_NO_BACK_VER) {
917                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
918                          "Bad EEPROM checksum 0x%x or revision 0x%04x\n",
919                          sum, ar5416_get_eep_ver(ahp));
920                 return -EINVAL;
921         }
922
923         return 0;
924 }
925
926 static bool ath9k_hw_chip_test(struct ath_hal *ah)
927 {
928         u32 regAddr[2] = { AR_STA_ID0, AR_PHY_BASE + (8 << 2) };
929         u32 regHold[2];
930         u32 patternData[4] = { 0x55555555,
931                                      0xaaaaaaaa,
932                                      0x66666666,
933                                      0x99999999 };
934         int i, j;
935
936         for (i = 0; i < 2; i++) {
937                 u32 addr = regAddr[i];
938                 u32 wrData, rdData;
939
940                 regHold[i] = REG_READ(ah, addr);
941                 for (j = 0; j < 0x100; j++) {
942                         wrData = (j << 16) | j;
943                         REG_WRITE(ah, addr, wrData);
944                         rdData = REG_READ(ah, addr);
945                         if (rdData != wrData) {
946                                 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
947                                  "%s: address test failed "
948                                 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
949                                  __func__, addr, wrData, rdData);
950                                 return false;
951                         }
952                 }
953                 for (j = 0; j < 4; j++) {
954                         wrData = patternData[j];
955                         REG_WRITE(ah, addr, wrData);
956                         rdData = REG_READ(ah, addr);
957                         if (wrData != rdData) {
958                                 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
959                                  "%s: address test failed "
960                                 "addr: 0x%08x - wr:0x%08x != rd:0x%08x\n",
961                                  __func__, addr, wrData, rdData);
962                                 return false;
963                         }
964                 }
965                 REG_WRITE(ah, regAddr[i], regHold[i]);
966         }
967         udelay(100);
968         return true;
969 }
970
971 u32 ath9k_hw_getrxfilter(struct ath_hal *ah)
972 {
973         u32 bits = REG_READ(ah, AR_RX_FILTER);
974         u32 phybits = REG_READ(ah, AR_PHY_ERR);
975
976         if (phybits & AR_PHY_ERR_RADAR)
977                 bits |= ATH9K_RX_FILTER_PHYRADAR;
978         if (phybits & (AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING))
979                 bits |= ATH9K_RX_FILTER_PHYERR;
980         return bits;
981 }
982
983 void ath9k_hw_setrxfilter(struct ath_hal *ah, u32 bits)
984 {
985         u32 phybits;
986
987         REG_WRITE(ah, AR_RX_FILTER, (bits & 0xffff) | AR_RX_COMPR_BAR);
988         phybits = 0;
989         if (bits & ATH9K_RX_FILTER_PHYRADAR)
990                 phybits |= AR_PHY_ERR_RADAR;
991         if (bits & ATH9K_RX_FILTER_PHYERR)
992                 phybits |= AR_PHY_ERR_OFDM_TIMING | AR_PHY_ERR_CCK_TIMING;
993         REG_WRITE(ah, AR_PHY_ERR, phybits);
994
995         if (phybits)
996                 REG_WRITE(ah, AR_RXCFG,
997                           REG_READ(ah, AR_RXCFG) | AR_RXCFG_ZLFDMA);
998         else
999                 REG_WRITE(ah, AR_RXCFG,
1000                           REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_ZLFDMA);
1001 }
1002
1003 bool ath9k_hw_setcapability(struct ath_hal *ah,
1004                             enum ath9k_capability_type type,
1005                             u32 capability,
1006                             u32 setting,
1007                             int *status)
1008 {
1009         struct ath_hal_5416 *ahp = AH5416(ah);
1010         u32 v;
1011
1012         switch (type) {
1013         case ATH9K_CAP_TKIP_MIC:
1014                 if (setting)
1015                         ahp->ah_staId1Defaults |=
1016                                 AR_STA_ID1_CRPT_MIC_ENABLE;
1017                 else
1018                         ahp->ah_staId1Defaults &=
1019                                 ~AR_STA_ID1_CRPT_MIC_ENABLE;
1020                 return true;
1021         case ATH9K_CAP_DIVERSITY:
1022                 v = REG_READ(ah, AR_PHY_CCK_DETECT);
1023                 if (setting)
1024                         v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1025                 else
1026                         v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
1027                 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
1028                 return true;
1029         case ATH9K_CAP_MCAST_KEYSRCH:
1030                 if (setting)
1031                         ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
1032                 else
1033                         ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
1034                 return true;
1035         case ATH9K_CAP_TSF_ADJUST:
1036                 if (setting)
1037                         ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
1038                 else
1039                         ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
1040                 return true;
1041         default:
1042                 return false;
1043         }
1044 }
1045
1046 void ath9k_hw_dmaRegDump(struct ath_hal *ah)
1047 {
1048         u32 val[ATH9K_NUM_DMA_DEBUG_REGS];
1049         int qcuOffset = 0, dcuOffset = 0;
1050         u32 *qcuBase = &val[0], *dcuBase = &val[4];
1051         int i;
1052
1053         REG_WRITE(ah, AR_MACMISC,
1054                   ((AR_MACMISC_DMA_OBS_LINE_8 << AR_MACMISC_DMA_OBS_S) |
1055                    (AR_MACMISC_MISC_OBS_BUS_1 <<
1056                     AR_MACMISC_MISC_OBS_BUS_MSB_S)));
1057
1058         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "Raw DMA Debug values:\n");
1059         for (i = 0; i < ATH9K_NUM_DMA_DEBUG_REGS; i++) {
1060                 if (i % 4 == 0)
1061                         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1062
1063                 val[i] = REG_READ(ah, AR_DMADBG_0 + (i * sizeof(u32)));
1064                 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "%d: %08x ", i, val[i]);
1065         }
1066
1067         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n\n");
1068         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1069                  "Num QCU: chain_st fsp_ok fsp_st DCU: chain_st\n");
1070
1071         for (i = 0; i < ATH9K_NUM_QUEUES;
1072              i++, qcuOffset += 4, dcuOffset += 5) {
1073                 if (i == 8) {
1074                         qcuOffset = 0;
1075                         qcuBase++;
1076                 }
1077
1078                 if (i == 6) {
1079                         dcuOffset = 0;
1080                         dcuBase++;
1081                 }
1082
1083                 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1084                          "%2d          %2x      %1x     %2x           %2x\n",
1085                          i, (*qcuBase & (0x7 << qcuOffset)) >> qcuOffset,
1086                          (*qcuBase & (0x8 << qcuOffset)) >> (qcuOffset +
1087                                                              3),
1088                          val[2] & (0x7 << (i * 3)) >> (i * 3),
1089                          (*dcuBase & (0x1f << dcuOffset)) >> dcuOffset);
1090         }
1091
1092         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "\n");
1093         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1094                  "qcu_stitch state:   %2x    qcu_fetch state:        %2x\n",
1095                  (val[3] & 0x003c0000) >> 18, (val[3] & 0x03c00000) >> 22);
1096         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1097                  "qcu_complete state: %2x    dcu_complete state:     %2x\n",
1098                  (val[3] & 0x1c000000) >> 26, (val[6] & 0x3));
1099         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1100                  "dcu_arb state:      %2x    dcu_fp state:           %2x\n",
1101                  (val[5] & 0x06000000) >> 25, (val[5] & 0x38000000) >> 27);
1102         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1103                  "chan_idle_dur:     %3d    chan_idle_dur_valid:     %1d\n",
1104                  (val[6] & 0x000003fc) >> 2, (val[6] & 0x00000400) >> 10);
1105         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1106                  "txfifo_valid_0:      %1d    txfifo_valid_1:          %1d\n",
1107                  (val[6] & 0x00000800) >> 11, (val[6] & 0x00001000) >> 12);
1108         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1109                  "txfifo_dcu_num_0:   %2d    txfifo_dcu_num_1:       %2d\n",
1110                  (val[6] & 0x0001e000) >> 13, (val[6] & 0x001e0000) >> 17);
1111
1112         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO, "pcu observe 0x%x \n",
1113                 REG_READ(ah, AR_OBS_BUS_1));
1114         DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
1115                 "AR_CR 0x%x \n", REG_READ(ah, AR_CR));
1116 }
1117
1118 u32 ath9k_hw_GetMibCycleCountsPct(struct ath_hal *ah,
1119                                         u32 *rxc_pcnt,
1120                                         u32 *rxf_pcnt,
1121                                         u32 *txf_pcnt)
1122 {
1123         static u32 cycles, rx_clear, rx_frame, tx_frame;
1124         u32 good = 1;
1125
1126         u32 rc = REG_READ(ah, AR_RCCNT);
1127         u32 rf = REG_READ(ah, AR_RFCNT);
1128         u32 tf = REG_READ(ah, AR_TFCNT);
1129         u32 cc = REG_READ(ah, AR_CCCNT);
1130
1131         if (cycles == 0 || cycles > cc) {
1132                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1133                          "%s: cycle counter wrap. ExtBusy = 0\n",
1134                          __func__);
1135                 good = 0;
1136         } else {
1137                 u32 cc_d = cc - cycles;
1138                 u32 rc_d = rc - rx_clear;
1139                 u32 rf_d = rf - rx_frame;
1140                 u32 tf_d = tf - tx_frame;
1141
1142                 if (cc_d != 0) {
1143                         *rxc_pcnt = rc_d * 100 / cc_d;
1144                         *rxf_pcnt = rf_d * 100 / cc_d;
1145                         *txf_pcnt = tf_d * 100 / cc_d;
1146                 } else {
1147                         good = 0;
1148                 }
1149         }
1150
1151         cycles = cc;
1152         rx_frame = rf;
1153         rx_clear = rc;
1154         tx_frame = tf;
1155
1156         return good;
1157 }
1158
1159 void ath9k_hw_set11nmac2040(struct ath_hal *ah, enum ath9k_ht_macmode mode)
1160 {
1161         u32 macmode;
1162
1163         if (mode == ATH9K_HT_MACMODE_2040 &&
1164             !ah->ah_config.cwm_ignore_extcca)
1165                 macmode = AR_2040_JOINED_RX_CLEAR;
1166         else
1167                 macmode = 0;
1168
1169         REG_WRITE(ah, AR_2040_MODE, macmode);
1170 }
1171
1172 static void ath9k_hw_mark_phy_inactive(struct ath_hal *ah)
1173 {
1174         REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
1175 }
1176
1177
1178 static struct ath_hal_5416 *ath9k_hw_newstate(u16 devid,
1179                                               struct ath_softc *sc,
1180                                               void __iomem *mem,
1181                                               int *status)
1182 {
1183         static const u8 defbssidmask[ETH_ALEN] =
1184                 { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
1185         struct ath_hal_5416 *ahp;
1186         struct ath_hal *ah;
1187
1188         ahp = kzalloc(sizeof(struct ath_hal_5416), GFP_KERNEL);
1189         if (ahp == NULL) {
1190                 DPRINTF(sc, ATH_DBG_FATAL,
1191                          "%s: cannot allocate memory for state block\n",
1192                          __func__);
1193                 *status = -ENOMEM;
1194                 return NULL;
1195         }
1196
1197         ah = &ahp->ah;
1198
1199         memcpy(&ahp->ah, &ar5416hal, sizeof(struct ath_hal));
1200
1201         ah->ah_sc = sc;
1202         ah->ah_sh = mem;
1203
1204         ah->ah_devid = devid;
1205         ah->ah_subvendorid = 0;
1206
1207         ah->ah_flags = 0;
1208         if ((devid == AR5416_AR9100_DEVID))
1209                 ah->ah_macVersion = AR_SREV_VERSION_9100;
1210         if (!AR_SREV_9100(ah))
1211                 ah->ah_flags = AH_USE_EEPROM;
1212
1213         ah->ah_powerLimit = MAX_RATE_POWER;
1214         ah->ah_tpScale = ATH9K_TP_SCALE_MAX;
1215
1216         ahp->ah_atimWindow = 0;
1217         ahp->ah_diversityControl = ah->ah_config.diversity_control;
1218         ahp->ah_antennaSwitchSwap =
1219                 ah->ah_config.antenna_switch_swap;
1220
1221         ahp->ah_staId1Defaults = AR_STA_ID1_CRPT_MIC_ENABLE;
1222         ahp->ah_beaconInterval = 100;
1223         ahp->ah_enable32kHzClock = DONT_USE_32KHZ;
1224         ahp->ah_slottime = (u32) -1;
1225         ahp->ah_acktimeout = (u32) -1;
1226         ahp->ah_ctstimeout = (u32) -1;
1227         ahp->ah_globaltxtimeout = (u32) -1;
1228         memcpy(&ahp->ah_bssidmask, defbssidmask, ETH_ALEN);
1229
1230         ahp->ah_gBeaconRate = 0;
1231
1232         return ahp;
1233 }
1234
1235 static int ath9k_hw_eeprom_attach(struct ath_hal *ah)
1236 {
1237         int status;
1238
1239         if (ath9k_hw_use_flash(ah))
1240                 ath9k_hw_flash_map(ah);
1241
1242         if (!ath9k_hw_fill_eeprom(ah))
1243                 return -EIO;
1244
1245         status = ath9k_hw_check_eeprom(ah);
1246
1247         return status;
1248 }
1249
1250 u32 ath9k_hw_get_eeprom(struct ath_hal_5416 *ahp,
1251                               enum eeprom_param param)
1252 {
1253         struct ar5416_eeprom *eep = &ahp->ah_eeprom;
1254         struct modal_eep_header *pModal = eep->modalHeader;
1255         struct base_eep_header *pBase = &eep->baseEepHeader;
1256
1257         switch (param) {
1258         case EEP_NFTHRESH_5:
1259                 return -pModal[0].noiseFloorThreshCh[0];
1260         case EEP_NFTHRESH_2:
1261                 return -pModal[1].noiseFloorThreshCh[0];
1262         case AR_EEPROM_MAC(0):
1263                 return pBase->macAddr[0] << 8 | pBase->macAddr[1];
1264         case AR_EEPROM_MAC(1):
1265                 return pBase->macAddr[2] << 8 | pBase->macAddr[3];
1266         case AR_EEPROM_MAC(2):
1267                 return pBase->macAddr[4] << 8 | pBase->macAddr[5];
1268         case EEP_REG_0:
1269                 return pBase->regDmn[0];
1270         case EEP_REG_1:
1271                 return pBase->regDmn[1];
1272         case EEP_OP_CAP:
1273                 return pBase->deviceCap;
1274         case EEP_OP_MODE:
1275                 return pBase->opCapFlags;
1276         case EEP_RF_SILENT:
1277                 return pBase->rfSilent;
1278         case EEP_OB_5:
1279                 return pModal[0].ob;
1280         case EEP_DB_5:
1281                 return pModal[0].db;
1282         case EEP_OB_2:
1283                 return pModal[1].ob;
1284         case EEP_DB_2:
1285                 return pModal[1].db;
1286         case EEP_MINOR_REV:
1287                 return pBase->version & AR5416_EEP_VER_MINOR_MASK;
1288         case EEP_TX_MASK:
1289                 return pBase->txMask;
1290         case EEP_RX_MASK:
1291                 return pBase->rxMask;
1292         default:
1293                 return 0;
1294         }
1295 }
1296
1297 static inline int ath9k_hw_get_radiorev(struct ath_hal *ah)
1298 {
1299         u32 val;
1300         int i;
1301
1302         REG_WRITE(ah, AR_PHY(0x36), 0x00007058);
1303         for (i = 0; i < 8; i++)
1304                 REG_WRITE(ah, AR_PHY(0x20), 0x00010000);
1305         val = (REG_READ(ah, AR_PHY(256)) >> 24) & 0xff;
1306         val = ((val & 0xf0) >> 4) | ((val & 0x0f) << 4);
1307         return ath9k_hw_reverse_bits(val, 8);
1308 }
1309
1310 static inline int ath9k_hw_init_macaddr(struct ath_hal *ah)
1311 {
1312         u32 sum;
1313         int i;
1314         u16 eeval;
1315         struct ath_hal_5416 *ahp = AH5416(ah);
1316         DECLARE_MAC_BUF(mac);
1317
1318         sum = 0;
1319         for (i = 0; i < 3; i++) {
1320                 eeval = ath9k_hw_get_eeprom(ahp, AR_EEPROM_MAC(i));
1321                 sum += eeval;
1322                 ahp->ah_macaddr[2 * i] = eeval >> 8;
1323                 ahp->ah_macaddr[2 * i + 1] = eeval & 0xff;
1324         }
1325         if (sum == 0 || sum == 0xffff * 3) {
1326                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
1327                          "%s: mac address read failed: %s\n", __func__,
1328                          print_mac(mac, ahp->ah_macaddr));
1329                 return -EADDRNOTAVAIL;
1330         }
1331
1332         return 0;
1333 }
1334
1335 static inline int16_t ath9k_hw_interpolate(u16 target,
1336                                            u16 srcLeft,
1337                                            u16 srcRight,
1338                                            int16_t targetLeft,
1339                                            int16_t targetRight)
1340 {
1341         int16_t rv;
1342
1343         if (srcRight == srcLeft) {
1344                 rv = targetLeft;
1345         } else {
1346                 rv = (int16_t) (((target - srcLeft) * targetRight +
1347                                  (srcRight - target) * targetLeft) /
1348                                 (srcRight - srcLeft));
1349         }
1350         return rv;
1351 }
1352
1353 static inline u16 ath9k_hw_fbin2freq(u8 fbin,
1354                                            bool is2GHz)
1355 {
1356
1357         if (fbin == AR5416_BCHAN_UNUSED)
1358                 return fbin;
1359
1360         return (u16) ((is2GHz) ? (2300 + fbin) : (4800 + 5 * fbin));
1361 }
1362
1363 static u16 ath9k_hw_eeprom_get_spur_chan(struct ath_hal *ah,
1364                                                u16 i,
1365                                                bool is2GHz)
1366 {
1367         struct ath_hal_5416 *ahp = AH5416(ah);
1368         struct ar5416_eeprom *eep =
1369                 (struct ar5416_eeprom *) &ahp->ah_eeprom;
1370         u16 spur_val = AR_NO_SPUR;
1371
1372         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1373                  "Getting spur idx %d is2Ghz. %d val %x\n",
1374                  i, is2GHz, ah->ah_config.spurchans[i][is2GHz]);
1375
1376         switch (ah->ah_config.spurmode) {
1377         case SPUR_DISABLE:
1378                 break;
1379         case SPUR_ENABLE_IOCTL:
1380                 spur_val = ah->ah_config.spurchans[i][is2GHz];
1381                 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
1382                          "Getting spur val from new loc. %d\n", spur_val);
1383                 break;
1384         case SPUR_ENABLE_EEPROM:
1385                 spur_val = eep->modalHeader[is2GHz].spurChans[i].spurChan;
1386                 break;
1387
1388         }
1389         return spur_val;
1390 }
1391
1392 static inline int ath9k_hw_rfattach(struct ath_hal *ah)
1393 {
1394         bool rfStatus = false;
1395         int ecode = 0;
1396
1397         rfStatus = ath9k_hw_init_rf(ah, &ecode);
1398         if (!rfStatus) {
1399                 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1400                          "%s: RF setup failed, status %u\n", __func__,
1401                          ecode);
1402                 return ecode;
1403         }
1404
1405         return 0;
1406 }
1407
1408 static int ath9k_hw_rf_claim(struct ath_hal *ah)
1409 {
1410         u32 val;
1411
1412         REG_WRITE(ah, AR_PHY(0), 0x00000007);
1413
1414         val = ath9k_hw_get_radiorev(ah);
1415         switch (val & AR_RADIO_SREV_MAJOR) {
1416         case 0:
1417                 val = AR_RAD5133_SREV_MAJOR;
1418                 break;
1419         case AR_RAD5133_SREV_MAJOR:
1420         case AR_RAD5122_SREV_MAJOR:
1421         case AR_RAD2133_SREV_MAJOR:
1422         case AR_RAD2122_SREV_MAJOR:
1423                 break;
1424         default:
1425                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1426                          "%s: 5G Radio Chip Rev 0x%02X is not "
1427                         "supported by this driver\n",
1428                          __func__, ah->ah_analog5GhzRev);
1429                 return -EOPNOTSUPP;
1430         }
1431
1432         ah->ah_analog5GhzRev = val;
1433
1434         return 0;
1435 }
1436
1437 static inline void ath9k_hw_init_pll(struct ath_hal *ah,
1438                                      struct ath9k_channel *chan)
1439 {
1440         u32 pll;
1441
1442         if (AR_SREV_9100(ah)) {
1443                 if (chan && IS_CHAN_5GHZ(chan))
1444                         pll = 0x1450;
1445                 else
1446                         pll = 0x1458;
1447         } else {
1448                 if (AR_SREV_9280_10_OR_LATER(ah)) {
1449                         pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1450
1451                         if (chan && IS_CHAN_HALF_RATE(chan))
1452                                 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1453                         else if (chan && IS_CHAN_QUARTER_RATE(chan))
1454                                 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1455
1456                         if (chan && IS_CHAN_5GHZ(chan)) {
1457                                 pll |= SM(0x28, AR_RTC_9160_PLL_DIV);
1458
1459
1460                                 if (AR_SREV_9280_20(ah)) {
1461                                         if (((chan->channel % 20) == 0)
1462                                             || ((chan->channel % 10) == 0))
1463                                                 pll = 0x2850;
1464                                         else
1465                                                 pll = 0x142c;
1466                                 }
1467                         } else {
1468                                 pll |= SM(0x2c, AR_RTC_9160_PLL_DIV);
1469                         }
1470
1471                 } else if (AR_SREV_9160_10_OR_LATER(ah)) {
1472
1473                         pll = SM(0x5, AR_RTC_9160_PLL_REFDIV);
1474
1475                         if (chan && IS_CHAN_HALF_RATE(chan))
1476                                 pll |= SM(0x1, AR_RTC_9160_PLL_CLKSEL);
1477                         else if (chan && IS_CHAN_QUARTER_RATE(chan))
1478                                 pll |= SM(0x2, AR_RTC_9160_PLL_CLKSEL);
1479
1480                         if (chan && IS_CHAN_5GHZ(chan))
1481                                 pll |= SM(0x50, AR_RTC_9160_PLL_DIV);
1482                         else
1483                                 pll |= SM(0x58, AR_RTC_9160_PLL_DIV);
1484                 } else {
1485                         pll = AR_RTC_PLL_REFDIV_5 | AR_RTC_PLL_DIV2;
1486
1487                         if (chan && IS_CHAN_HALF_RATE(chan))
1488                                 pll |= SM(0x1, AR_RTC_PLL_CLKSEL);
1489                         else if (chan && IS_CHAN_QUARTER_RATE(chan))
1490                                 pll |= SM(0x2, AR_RTC_PLL_CLKSEL);
1491
1492                         if (chan && IS_CHAN_5GHZ(chan))
1493                                 pll |= SM(0xa, AR_RTC_PLL_DIV);
1494                         else
1495                                 pll |= SM(0xb, AR_RTC_PLL_DIV);
1496                 }
1497         }
1498         REG_WRITE(ah, (u16) (AR_RTC_PLL_CONTROL), pll);
1499
1500         udelay(RTC_PLL_SETTLE_DELAY);
1501
1502         REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
1503 }
1504
1505 static void ath9k_hw_set_regs(struct ath_hal *ah, struct ath9k_channel *chan,
1506                               enum ath9k_ht_macmode macmode)
1507 {
1508         u32 phymode;
1509         struct ath_hal_5416 *ahp = AH5416(ah);
1510
1511         phymode = AR_PHY_FC_HT_EN | AR_PHY_FC_SHORT_GI_40
1512                 | AR_PHY_FC_SINGLE_HT_LTF1 | AR_PHY_FC_WALSH;
1513
1514         if (IS_CHAN_HT40(chan)) {
1515                 phymode |= AR_PHY_FC_DYN2040_EN;
1516
1517                 if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
1518                     (chan->chanmode == CHANNEL_G_HT40PLUS))
1519                         phymode |= AR_PHY_FC_DYN2040_PRI_CH;
1520
1521                 if (ahp->ah_extprotspacing == ATH9K_HT_EXTPROTSPACING_25)
1522                         phymode |= AR_PHY_FC_DYN2040_EXT_CH;
1523         }
1524         REG_WRITE(ah, AR_PHY_TURBO, phymode);
1525
1526         ath9k_hw_set11nmac2040(ah, macmode);
1527
1528         REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
1529         REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
1530 }
1531
1532 static void ath9k_hw_set_operating_mode(struct ath_hal *ah, int opmode)
1533 {
1534         u32 val;
1535
1536         val = REG_READ(ah, AR_STA_ID1);
1537         val &= ~(AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC);
1538         switch (opmode) {
1539         case ATH9K_M_HOSTAP:
1540                 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_STA_AP
1541                           | AR_STA_ID1_KSRCH_MODE);
1542                 REG_CLR_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1543                 break;
1544         case ATH9K_M_IBSS:
1545                 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_ADHOC
1546                           | AR_STA_ID1_KSRCH_MODE);
1547                 REG_SET_BIT(ah, AR_CFG, AR_CFG_AP_ADHOC_INDICATION);
1548                 break;
1549         case ATH9K_M_STA:
1550         case ATH9K_M_MONITOR:
1551                 REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_KSRCH_MODE);
1552                 break;
1553         }
1554 }
1555
1556 static inline void
1557 ath9k_hw_set_rfmode(struct ath_hal *ah, struct ath9k_channel *chan)
1558 {
1559         u32 rfMode = 0;
1560
1561         if (chan == NULL)
1562                 return;
1563
1564         rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
1565                 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
1566
1567         if (!AR_SREV_9280_10_OR_LATER(ah))
1568                 rfMode |= (IS_CHAN_5GHZ(chan)) ? AR_PHY_MODE_RF5GHZ :
1569                         AR_PHY_MODE_RF2GHZ;
1570
1571         if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan))
1572                 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
1573
1574         REG_WRITE(ah, AR_PHY_MODE, rfMode);
1575 }
1576
1577 static bool ath9k_hw_set_reset(struct ath_hal *ah, int type)
1578 {
1579         u32 rst_flags;
1580         u32 tmpReg;
1581
1582         REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1583                   AR_RTC_FORCE_WAKE_ON_INT);
1584
1585         if (AR_SREV_9100(ah)) {
1586                 rst_flags = AR_RTC_RC_MAC_WARM | AR_RTC_RC_MAC_COLD |
1587                         AR_RTC_RC_COLD_RESET | AR_RTC_RC_WARM_RESET;
1588         } else {
1589                 tmpReg = REG_READ(ah, AR_INTR_SYNC_CAUSE);
1590                 if (tmpReg &
1591                     (AR_INTR_SYNC_LOCAL_TIMEOUT |
1592                      AR_INTR_SYNC_RADM_CPL_TIMEOUT)) {
1593                         REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
1594                         REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
1595                 } else {
1596                         REG_WRITE(ah, AR_RC, AR_RC_AHB);
1597                 }
1598
1599                 rst_flags = AR_RTC_RC_MAC_WARM;
1600                 if (type == ATH9K_RESET_COLD)
1601                         rst_flags |= AR_RTC_RC_MAC_COLD;
1602         }
1603
1604         REG_WRITE(ah, (u16) (AR_RTC_RC), rst_flags);
1605         udelay(50);
1606
1607         REG_WRITE(ah, (u16) (AR_RTC_RC), 0);
1608         if (!ath9k_hw_wait(ah, (u16) (AR_RTC_RC), AR_RTC_RC_M, 0)) {
1609                 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
1610                         "%s: RTC stuck in MAC reset\n",
1611                         __func__);
1612                 return false;
1613         }
1614
1615         if (!AR_SREV_9100(ah))
1616                 REG_WRITE(ah, AR_RC, 0);
1617
1618         ath9k_hw_init_pll(ah, NULL);
1619
1620         if (AR_SREV_9100(ah))
1621                 udelay(50);
1622
1623         return true;
1624 }
1625
1626 static inline bool ath9k_hw_set_reset_power_on(struct ath_hal *ah)
1627 {
1628         REG_WRITE(ah, AR_RTC_FORCE_WAKE, AR_RTC_FORCE_WAKE_EN |
1629                   AR_RTC_FORCE_WAKE_ON_INT);
1630
1631         REG_WRITE(ah, (u16) (AR_RTC_RESET), 0);
1632         REG_WRITE(ah, (u16) (AR_RTC_RESET), 1);
1633
1634         if (!ath9k_hw_wait(ah,
1635                            AR_RTC_STATUS,
1636                            AR_RTC_STATUS_M,
1637                            AR_RTC_STATUS_ON)) {
1638                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: RTC not waking up\n",
1639                          __func__);
1640                 return false;
1641         }
1642
1643         ath9k_hw_read_revisions(ah);
1644
1645         return ath9k_hw_set_reset(ah, ATH9K_RESET_WARM);
1646 }
1647
1648 static bool ath9k_hw_set_reset_reg(struct ath_hal *ah,
1649                                    u32 type)
1650 {
1651         REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1652                   AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1653
1654         switch (type) {
1655         case ATH9K_RESET_POWER_ON:
1656                 return ath9k_hw_set_reset_power_on(ah);
1657                 break;
1658         case ATH9K_RESET_WARM:
1659         case ATH9K_RESET_COLD:
1660                 return ath9k_hw_set_reset(ah, type);
1661                 break;
1662         default:
1663                 return false;
1664         }
1665 }
1666
1667 static inline
1668 struct ath9k_channel *ath9k_hw_check_chan(struct ath_hal *ah,
1669                                           struct ath9k_channel *chan)
1670 {
1671         if (!(IS_CHAN_2GHZ(chan) ^ IS_CHAN_5GHZ(chan))) {
1672                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1673                          "%s: invalid channel %u/0x%x; not marked as "
1674                          "2GHz or 5GHz\n", __func__, chan->channel,
1675                          chan->channelFlags);
1676                 return NULL;
1677         }
1678
1679         if (!IS_CHAN_OFDM(chan) &&
1680               !IS_CHAN_CCK(chan) &&
1681               !IS_CHAN_HT20(chan) &&
1682               !IS_CHAN_HT40(chan)) {
1683                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1684                         "%s: invalid channel %u/0x%x; not marked as "
1685                         "OFDM or CCK or HT20 or HT40PLUS or HT40MINUS\n",
1686                         __func__, chan->channel, chan->channelFlags);
1687                 return NULL;
1688         }
1689
1690         return ath9k_regd_check_channel(ah, chan);
1691 }
1692
1693 static inline bool
1694 ath9k_hw_get_lower_upper_index(u8 target,
1695                                u8 *pList,
1696                                u16 listSize,
1697                                u16 *indexL,
1698                                u16 *indexR)
1699 {
1700         u16 i;
1701
1702         if (target <= pList[0]) {
1703                 *indexL = *indexR = 0;
1704                 return true;
1705         }
1706         if (target >= pList[listSize - 1]) {
1707                 *indexL = *indexR = (u16) (listSize - 1);
1708                 return true;
1709         }
1710
1711         for (i = 0; i < listSize - 1; i++) {
1712                 if (pList[i] == target) {
1713                         *indexL = *indexR = i;
1714                         return true;
1715                 }
1716                 if (target < pList[i + 1]) {
1717                         *indexL = i;
1718                         *indexR = (u16) (i + 1);
1719                         return false;
1720                 }
1721         }
1722         return false;
1723 }
1724
1725 static int16_t ath9k_hw_get_nf_hist_mid(int16_t *nfCalBuffer)
1726 {
1727         int16_t nfval;
1728         int16_t sort[ATH9K_NF_CAL_HIST_MAX];
1729         int i, j;
1730
1731         for (i = 0; i < ATH9K_NF_CAL_HIST_MAX; i++)
1732                 sort[i] = nfCalBuffer[i];
1733
1734         for (i = 0; i < ATH9K_NF_CAL_HIST_MAX - 1; i++) {
1735                 for (j = 1; j < ATH9K_NF_CAL_HIST_MAX - i; j++) {
1736                         if (sort[j] > sort[j - 1]) {
1737                                 nfval = sort[j];
1738                                 sort[j] = sort[j - 1];
1739                                 sort[j - 1] = nfval;
1740                         }
1741                 }
1742         }
1743         nfval = sort[(ATH9K_NF_CAL_HIST_MAX - 1) >> 1];
1744
1745         return nfval;
1746 }
1747
1748 static void ath9k_hw_update_nfcal_hist_buffer(struct ath9k_nfcal_hist *h,
1749                                               int16_t *nfarray)
1750 {
1751         int i;
1752
1753         for (i = 0; i < NUM_NF_READINGS; i++) {
1754                 h[i].nfCalBuffer[h[i].currIndex] = nfarray[i];
1755
1756                 if (++h[i].currIndex >= ATH9K_NF_CAL_HIST_MAX)
1757                         h[i].currIndex = 0;
1758
1759                 if (h[i].invalidNFcount > 0) {
1760                         if (nfarray[i] < AR_PHY_CCA_MIN_BAD_VALUE
1761                             || nfarray[i] > AR_PHY_CCA_MAX_HIGH_VALUE) {
1762                                 h[i].invalidNFcount = ATH9K_NF_CAL_HIST_MAX;
1763                         } else {
1764                                 h[i].invalidNFcount--;
1765                                 h[i].privNF = nfarray[i];
1766                         }
1767                 } else {
1768                         h[i].privNF =
1769                                 ath9k_hw_get_nf_hist_mid(h[i].nfCalBuffer);
1770                 }
1771         }
1772         return;
1773 }
1774
1775 static void ar5416GetNoiseFloor(struct ath_hal *ah,
1776                                 int16_t nfarray[NUM_NF_READINGS])
1777 {
1778         int16_t nf;
1779
1780         if (AR_SREV_9280_10_OR_LATER(ah))
1781                 nf = MS(REG_READ(ah, AR_PHY_CCA), AR9280_PHY_MINCCA_PWR);
1782         else
1783                 nf = MS(REG_READ(ah, AR_PHY_CCA), AR_PHY_MINCCA_PWR);
1784
1785         if (nf & 0x100)
1786                 nf = 0 - ((nf ^ 0x1ff) + 1);
1787         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1788                  "NF calibrated [ctl] [chain 0] is %d\n", nf);
1789         nfarray[0] = nf;
1790
1791         if (AR_SREV_9280_10_OR_LATER(ah))
1792                 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1793                         AR9280_PHY_CH1_MINCCA_PWR);
1794         else
1795                 nf = MS(REG_READ(ah, AR_PHY_CH1_CCA),
1796                         AR_PHY_CH1_MINCCA_PWR);
1797
1798         if (nf & 0x100)
1799                 nf = 0 - ((nf ^ 0x1ff) + 1);
1800         DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1801                  "NF calibrated [ctl] [chain 1] is %d\n", nf);
1802         nfarray[1] = nf;
1803
1804         if (!AR_SREV_9280(ah)) {
1805                 nf = MS(REG_READ(ah, AR_PHY_CH2_CCA),
1806                         AR_PHY_CH2_MINCCA_PWR);
1807                 if (nf & 0x100)
1808                         nf = 0 - ((nf ^ 0x1ff) + 1);
1809                 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1810                          "NF calibrated [ctl] [chain 2] is %d\n", nf);
1811                 nfarray[2] = nf;
1812         }
1813
1814         if (AR_SREV_9280_10_OR_LATER(ah))
1815                 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1816                         AR9280_PHY_EXT_MINCCA_PWR);
1817         else
1818                 nf = MS(REG_READ(ah, AR_PHY_EXT_CCA),
1819                         AR_PHY_EXT_MINCCA_PWR);
1820
1821         if (nf & 0x100)
1822                 nf = 0 - ((nf ^ 0x1ff) + 1);
1823         DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1824                  "NF calibrated [ext] [chain 0] is %d\n", nf);
1825         nfarray[3] = nf;
1826
1827         if (AR_SREV_9280_10_OR_LATER(ah))
1828                 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1829                         AR9280_PHY_CH1_EXT_MINCCA_PWR);
1830         else
1831                 nf = MS(REG_READ(ah, AR_PHY_CH1_EXT_CCA),
1832                         AR_PHY_CH1_EXT_MINCCA_PWR);
1833
1834         if (nf & 0x100)
1835                 nf = 0 - ((nf ^ 0x1ff) + 1);
1836         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1837                  "NF calibrated [ext] [chain 1] is %d\n", nf);
1838         nfarray[4] = nf;
1839
1840         if (!AR_SREV_9280(ah)) {
1841                 nf = MS(REG_READ(ah, AR_PHY_CH2_EXT_CCA),
1842                         AR_PHY_CH2_EXT_MINCCA_PWR);
1843                 if (nf & 0x100)
1844                         nf = 0 - ((nf ^ 0x1ff) + 1);
1845                 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
1846                          "NF calibrated [ext] [chain 2] is %d\n", nf);
1847                 nfarray[5] = nf;
1848         }
1849 }
1850
1851 static bool
1852 getNoiseFloorThresh(struct ath_hal *ah,
1853                     const struct ath9k_channel *chan,
1854                     int16_t *nft)
1855 {
1856         struct ath_hal_5416 *ahp = AH5416(ah);
1857
1858         switch (chan->chanmode) {
1859         case CHANNEL_A:
1860         case CHANNEL_A_HT20:
1861         case CHANNEL_A_HT40PLUS:
1862         case CHANNEL_A_HT40MINUS:
1863                 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_5);
1864                 break;
1865         case CHANNEL_B:
1866         case CHANNEL_G:
1867         case CHANNEL_G_HT20:
1868         case CHANNEL_G_HT40PLUS:
1869         case CHANNEL_G_HT40MINUS:
1870                 *nft = (int16_t) ath9k_hw_get_eeprom(ahp, EEP_NFTHRESH_2);
1871                 break;
1872         default:
1873                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
1874                          "%s: invalid channel flags 0x%x\n", __func__,
1875                          chan->channelFlags);
1876                 return false;
1877         }
1878         return true;
1879 }
1880
1881 static void ath9k_hw_start_nfcal(struct ath_hal *ah)
1882 {
1883         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1884                     AR_PHY_AGC_CONTROL_ENABLE_NF);
1885         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL,
1886                     AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1887         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1888 }
1889
1890 static void
1891 ath9k_hw_loadnf(struct ath_hal *ah, struct ath9k_channel *chan)
1892 {
1893         struct ath9k_nfcal_hist *h;
1894         int i, j;
1895         int32_t val;
1896         const u32 ar5416_cca_regs[6] = {
1897                 AR_PHY_CCA,
1898                 AR_PHY_CH1_CCA,
1899                 AR_PHY_CH2_CCA,
1900                 AR_PHY_EXT_CCA,
1901                 AR_PHY_CH1_EXT_CCA,
1902                 AR_PHY_CH2_EXT_CCA
1903         };
1904         u8 chainmask;
1905
1906         if (AR_SREV_9280(ah))
1907                 chainmask = 0x1B;
1908         else
1909                 chainmask = 0x3F;
1910
1911 #ifdef ATH_NF_PER_CHAN
1912         h = chan->nfCalHist;
1913 #else
1914         h = ah->nfCalHist;
1915 #endif
1916
1917         for (i = 0; i < NUM_NF_READINGS; i++) {
1918                 if (chainmask & (1 << i)) {
1919                         val = REG_READ(ah, ar5416_cca_regs[i]);
1920                         val &= 0xFFFFFE00;
1921                         val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
1922                         REG_WRITE(ah, ar5416_cca_regs[i], val);
1923                 }
1924         }
1925
1926         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1927                     AR_PHY_AGC_CONTROL_ENABLE_NF);
1928         REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
1929                     AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
1930         REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
1931
1932         for (j = 0; j < 1000; j++) {
1933                 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
1934                      AR_PHY_AGC_CONTROL_NF) == 0)
1935                         break;
1936                 udelay(10);
1937         }
1938
1939         for (i = 0; i < NUM_NF_READINGS; i++) {
1940                 if (chainmask & (1 << i)) {
1941                         val = REG_READ(ah, ar5416_cca_regs[i]);
1942                         val &= 0xFFFFFE00;
1943                         val |= (((u32) (-50) << 1) & 0x1ff);
1944                         REG_WRITE(ah, ar5416_cca_regs[i], val);
1945                 }
1946         }
1947 }
1948
1949 static int16_t ath9k_hw_getnf(struct ath_hal *ah,
1950                               struct ath9k_channel *chan)
1951 {
1952         int16_t nf, nfThresh;
1953         int16_t nfarray[NUM_NF_READINGS] = { 0 };
1954         struct ath9k_nfcal_hist *h;
1955         u8 chainmask;
1956
1957         if (AR_SREV_9280(ah))
1958                 chainmask = 0x1B;
1959         else
1960                 chainmask = 0x3F;
1961
1962         chan->channelFlags &= (~CHANNEL_CW_INT);
1963         if (REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF) {
1964                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1965                          "%s: NF did not complete in calibration window\n",
1966                          __func__);
1967                 nf = 0;
1968                 chan->rawNoiseFloor = nf;
1969                 return chan->rawNoiseFloor;
1970         } else {
1971                 ar5416GetNoiseFloor(ah, nfarray);
1972                 nf = nfarray[0];
1973                 if (getNoiseFloorThresh(ah, chan, &nfThresh)
1974                     && nf > nfThresh) {
1975                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
1976                                  "%s: noise floor failed detected; "
1977                                  "detected %d, threshold %d\n", __func__,
1978                                  nf, nfThresh);
1979                         chan->channelFlags |= CHANNEL_CW_INT;
1980                 }
1981         }
1982
1983 #ifdef ATH_NF_PER_CHAN
1984         h = chan->nfCalHist;
1985 #else
1986         h = ah->nfCalHist;
1987 #endif
1988
1989         ath9k_hw_update_nfcal_hist_buffer(h, nfarray);
1990         chan->rawNoiseFloor = h[0].privNF;
1991
1992         return chan->rawNoiseFloor;
1993 }
1994
1995 static void ath9k_hw_update_mibstats(struct ath_hal *ah,
1996                               struct ath9k_mib_stats *stats)
1997 {
1998         stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL);
1999         stats->rts_bad += REG_READ(ah, AR_RTS_FAIL);
2000         stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL);
2001         stats->rts_good += REG_READ(ah, AR_RTS_OK);
2002         stats->beacons += REG_READ(ah, AR_BEACON_CNT);
2003 }
2004
2005 static void ath9k_enable_mib_counters(struct ath_hal *ah)
2006 {
2007         struct ath_hal_5416 *ahp = AH5416(ah);
2008
2009         DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Enable mib counters\n");
2010
2011         ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2012
2013         REG_WRITE(ah, AR_FILT_OFDM, 0);
2014         REG_WRITE(ah, AR_FILT_CCK, 0);
2015         REG_WRITE(ah, AR_MIBC,
2016                   ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS)
2017                   & 0x0f);
2018         REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2019         REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2020 }
2021
2022 static void ath9k_hw_disable_mib_counters(struct ath_hal *ah)
2023 {
2024         struct ath_hal_5416 *ahp = AH5416(ah);
2025
2026         DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Disabling MIB counters\n");
2027
2028         REG_WRITE(ah, AR_MIBC, AR_MIBC_FMC | AR_MIBC_CMC);
2029
2030         ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2031
2032         REG_WRITE(ah, AR_FILT_OFDM, 0);
2033         REG_WRITE(ah, AR_FILT_CCK, 0);
2034 }
2035
2036 static int ath9k_hw_get_ani_channel_idx(struct ath_hal *ah,
2037                                         struct ath9k_channel *chan)
2038 {
2039         struct ath_hal_5416 *ahp = AH5416(ah);
2040         int i;
2041
2042         for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2043                 if (ahp->ah_ani[i].c.channel == chan->channel)
2044                         return i;
2045                 if (ahp->ah_ani[i].c.channel == 0) {
2046                         ahp->ah_ani[i].c.channel = chan->channel;
2047                         ahp->ah_ani[i].c.channelFlags = chan->channelFlags;
2048                         return i;
2049                 }
2050         }
2051
2052         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2053                  "No more channel states left. Using channel 0\n");
2054         return 0;
2055 }
2056
2057 static void ath9k_hw_ani_attach(struct ath_hal *ah)
2058 {
2059         struct ath_hal_5416 *ahp = AH5416(ah);
2060         int i;
2061
2062         ahp->ah_hasHwPhyCounters = 1;
2063
2064         memset(ahp->ah_ani, 0, sizeof(ahp->ah_ani));
2065         for (i = 0; i < ARRAY_SIZE(ahp->ah_ani); i++) {
2066                 ahp->ah_ani[i].ofdmTrigHigh = ATH9K_ANI_OFDM_TRIG_HIGH;
2067                 ahp->ah_ani[i].ofdmTrigLow = ATH9K_ANI_OFDM_TRIG_LOW;
2068                 ahp->ah_ani[i].cckTrigHigh = ATH9K_ANI_CCK_TRIG_HIGH;
2069                 ahp->ah_ani[i].cckTrigLow = ATH9K_ANI_CCK_TRIG_LOW;
2070                 ahp->ah_ani[i].rssiThrHigh = ATH9K_ANI_RSSI_THR_HIGH;
2071                 ahp->ah_ani[i].rssiThrLow = ATH9K_ANI_RSSI_THR_LOW;
2072                 ahp->ah_ani[i].ofdmWeakSigDetectOff =
2073                         !ATH9K_ANI_USE_OFDM_WEAK_SIG;
2074                 ahp->ah_ani[i].cckWeakSigThreshold =
2075                         ATH9K_ANI_CCK_WEAK_SIG_THR;
2076                 ahp->ah_ani[i].spurImmunityLevel = ATH9K_ANI_SPUR_IMMUNE_LVL;
2077                 ahp->ah_ani[i].firstepLevel = ATH9K_ANI_FIRSTEP_LVL;
2078                 if (ahp->ah_hasHwPhyCounters) {
2079                         ahp->ah_ani[i].ofdmPhyErrBase =
2080                                 AR_PHY_COUNTMAX - ATH9K_ANI_OFDM_TRIG_HIGH;
2081                         ahp->ah_ani[i].cckPhyErrBase =
2082                                 AR_PHY_COUNTMAX - ATH9K_ANI_CCK_TRIG_HIGH;
2083                 }
2084         }
2085         if (ahp->ah_hasHwPhyCounters) {
2086                 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2087                         "Setting OfdmErrBase = 0x%08x\n",
2088                         ahp->ah_ani[0].ofdmPhyErrBase);
2089                 DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Setting cckErrBase = 0x%08x\n",
2090                         ahp->ah_ani[0].cckPhyErrBase);
2091
2092                 REG_WRITE(ah, AR_PHY_ERR_1, ahp->ah_ani[0].ofdmPhyErrBase);
2093                 REG_WRITE(ah, AR_PHY_ERR_2, ahp->ah_ani[0].cckPhyErrBase);
2094                 ath9k_enable_mib_counters(ah);
2095         }
2096         ahp->ah_aniPeriod = ATH9K_ANI_PERIOD;
2097         if (ah->ah_config.enable_ani)
2098                 ahp->ah_procPhyErr |= HAL_PROCESS_ANI;
2099 }
2100
2101 static inline void ath9k_hw_ani_setup(struct ath_hal *ah)
2102 {
2103         struct ath_hal_5416 *ahp = AH5416(ah);
2104         int i;
2105
2106         const int totalSizeDesired[] = { -55, -55, -55, -55, -62 };
2107         const int coarseHigh[] = { -14, -14, -14, -14, -12 };
2108         const int coarseLow[] = { -64, -64, -64, -64, -70 };
2109         const int firpwr[] = { -78, -78, -78, -78, -80 };
2110
2111         for (i = 0; i < 5; i++) {
2112                 ahp->ah_totalSizeDesired[i] = totalSizeDesired[i];
2113                 ahp->ah_coarseHigh[i] = coarseHigh[i];
2114                 ahp->ah_coarseLow[i] = coarseLow[i];
2115                 ahp->ah_firpwr[i] = firpwr[i];
2116         }
2117 }
2118
2119 static void ath9k_hw_ani_detach(struct ath_hal *ah)
2120 {
2121         struct ath_hal_5416 *ahp = AH5416(ah);
2122
2123         DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Detaching Ani\n");
2124         if (ahp->ah_hasHwPhyCounters) {
2125                 ath9k_hw_disable_mib_counters(ah);
2126                 REG_WRITE(ah, AR_PHY_ERR_1, 0);
2127                 REG_WRITE(ah, AR_PHY_ERR_2, 0);
2128         }
2129 }
2130
2131
2132 static bool ath9k_hw_ani_control(struct ath_hal *ah,
2133                                  enum ath9k_ani_cmd cmd, int param)
2134 {
2135         struct ath_hal_5416 *ahp = AH5416(ah);
2136         struct ar5416AniState *aniState = ahp->ah_curani;
2137
2138         switch (cmd & ahp->ah_ani_function) {
2139         case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
2140                 u32 level = param;
2141
2142                 if (level >= ARRAY_SIZE(ahp->ah_totalSizeDesired)) {
2143                         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2144                                  "%s: level out of range (%u > %u)\n",
2145                                  __func__, level,
2146                                  (unsigned) ARRAY_SIZE(ahp->
2147                                                        ah_totalSizeDesired));
2148                         return false;
2149                 }
2150
2151                 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
2152                               AR_PHY_DESIRED_SZ_TOT_DES,
2153                               ahp->ah_totalSizeDesired[level]);
2154                 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2155                               AR_PHY_AGC_CTL1_COARSE_LOW,
2156                               ahp->ah_coarseLow[level]);
2157                 REG_RMW_FIELD(ah, AR_PHY_AGC_CTL1,
2158                               AR_PHY_AGC_CTL1_COARSE_HIGH,
2159                               ahp->ah_coarseHigh[level]);
2160                 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2161                               AR_PHY_FIND_SIG_FIRPWR,
2162                               ahp->ah_firpwr[level]);
2163
2164                 if (level > aniState->noiseImmunityLevel)
2165                         ahp->ah_stats.ast_ani_niup++;
2166                 else if (level < aniState->noiseImmunityLevel)
2167                         ahp->ah_stats.ast_ani_nidown++;
2168                 aniState->noiseImmunityLevel = level;
2169                 break;
2170         }
2171         case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
2172                 const int m1ThreshLow[] = { 127, 50 };
2173                 const int m2ThreshLow[] = { 127, 40 };
2174                 const int m1Thresh[] = { 127, 0x4d };
2175                 const int m2Thresh[] = { 127, 0x40 };
2176                 const int m2CountThr[] = { 31, 16 };
2177                 const int m2CountThrLow[] = { 63, 48 };
2178                 u32 on = param ? 1 : 0;
2179
2180                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2181                               AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
2182                               m1ThreshLow[on]);
2183                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2184                               AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
2185                               m2ThreshLow[on]);
2186                 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2187                               AR_PHY_SFCORR_M1_THRESH,
2188                               m1Thresh[on]);
2189                 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2190                               AR_PHY_SFCORR_M2_THRESH,
2191                               m2Thresh[on]);
2192                 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
2193                               AR_PHY_SFCORR_M2COUNT_THR,
2194                               m2CountThr[on]);
2195                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
2196                               AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
2197                               m2CountThrLow[on]);
2198
2199                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2200                               AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
2201                               m1ThreshLow[on]);
2202                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2203                               AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
2204                               m2ThreshLow[on]);
2205                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2206                               AR_PHY_SFCORR_EXT_M1_THRESH,
2207                               m1Thresh[on]);
2208                 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
2209                               AR_PHY_SFCORR_EXT_M2_THRESH,
2210                               m2Thresh[on]);
2211
2212                 if (on)
2213                         REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
2214                                     AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2215                 else
2216                         REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
2217                                     AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
2218
2219                 if (!on != aniState->ofdmWeakSigDetectOff) {
2220                         if (on)
2221                                 ahp->ah_stats.ast_ani_ofdmon++;
2222                         else
2223                                 ahp->ah_stats.ast_ani_ofdmoff++;
2224                         aniState->ofdmWeakSigDetectOff = !on;
2225                 }
2226                 break;
2227         }
2228         case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
2229                 const int weakSigThrCck[] = { 8, 6 };
2230                 u32 high = param ? 1 : 0;
2231
2232                 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
2233                               AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
2234                               weakSigThrCck[high]);
2235                 if (high != aniState->cckWeakSigThreshold) {
2236                         if (high)
2237                                 ahp->ah_stats.ast_ani_cckhigh++;
2238                         else
2239                                 ahp->ah_stats.ast_ani_ccklow++;
2240                         aniState->cckWeakSigThreshold = high;
2241                 }
2242                 break;
2243         }
2244         case ATH9K_ANI_FIRSTEP_LEVEL:{
2245                 const int firstep[] = { 0, 4, 8 };
2246                 u32 level = param;
2247
2248                 if (level >= ARRAY_SIZE(firstep)) {
2249                         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2250                                  "%s: level out of range (%u > %u)\n",
2251                                  __func__, level,
2252                                 (unsigned) ARRAY_SIZE(firstep));
2253                         return false;
2254                 }
2255                 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
2256                               AR_PHY_FIND_SIG_FIRSTEP,
2257                               firstep[level]);
2258                 if (level > aniState->firstepLevel)
2259                         ahp->ah_stats.ast_ani_stepup++;
2260                 else if (level < aniState->firstepLevel)
2261                         ahp->ah_stats.ast_ani_stepdown++;
2262                 aniState->firstepLevel = level;
2263                 break;
2264         }
2265         case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
2266                 const int cycpwrThr1[] =
2267                         { 2, 4, 6, 8, 10, 12, 14, 16 };
2268                 u32 level = param;
2269
2270                 if (level >= ARRAY_SIZE(cycpwrThr1)) {
2271                         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2272                                  "%s: level out of range (%u > %u)\n",
2273                                  __func__, level,
2274                                  (unsigned)
2275                                 ARRAY_SIZE(cycpwrThr1));
2276                         return false;
2277                 }
2278                 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
2279                               AR_PHY_TIMING5_CYCPWR_THR1,
2280                               cycpwrThr1[level]);
2281                 if (level > aniState->spurImmunityLevel)
2282                         ahp->ah_stats.ast_ani_spurup++;
2283                 else if (level < aniState->spurImmunityLevel)
2284                         ahp->ah_stats.ast_ani_spurdown++;
2285                 aniState->spurImmunityLevel = level;
2286                 break;
2287         }
2288         case ATH9K_ANI_PRESENT:
2289                 break;
2290         default:
2291                 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2292                         "%s: invalid cmd %u\n", __func__, cmd);
2293                 return false;
2294         }
2295
2296         DPRINTF(ah->ah_sc, ATH_DBG_ANI, "%s: ANI parameters:\n", __func__);
2297         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2298                 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
2299                 "ofdmWeakSigDetectOff=%d\n",
2300                  aniState->noiseImmunityLevel, aniState->spurImmunityLevel,
2301                  !aniState->ofdmWeakSigDetectOff);
2302         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2303                 "cckWeakSigThreshold=%d, "
2304                 "firstepLevel=%d, listenTime=%d\n",
2305                  aniState->cckWeakSigThreshold, aniState->firstepLevel,
2306                  aniState->listenTime);
2307         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2308                  "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
2309                  aniState->cycleCount, aniState->ofdmPhyErrCount,
2310                  aniState->cckPhyErrCount);
2311         return true;
2312 }
2313
2314 static void ath9k_ani_restart(struct ath_hal *ah)
2315 {
2316         struct ath_hal_5416 *ahp = AH5416(ah);
2317         struct ar5416AniState *aniState;
2318
2319         if (!DO_ANI(ah))
2320                 return;
2321
2322         aniState = ahp->ah_curani;
2323
2324         aniState->listenTime = 0;
2325         if (ahp->ah_hasHwPhyCounters) {
2326                 if (aniState->ofdmTrigHigh > AR_PHY_COUNTMAX) {
2327                         aniState->ofdmPhyErrBase = 0;
2328                         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2329                                  "OFDM Trigger is too high for hw counters\n");
2330                 } else {
2331                         aniState->ofdmPhyErrBase =
2332                                 AR_PHY_COUNTMAX - aniState->ofdmTrigHigh;
2333                 }
2334                 if (aniState->cckTrigHigh > AR_PHY_COUNTMAX) {
2335                         aniState->cckPhyErrBase = 0;
2336                         DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2337                                  "CCK Trigger is too high for hw counters\n");
2338                 } else {
2339                         aniState->cckPhyErrBase =
2340                                 AR_PHY_COUNTMAX - aniState->cckTrigHigh;
2341                 }
2342                 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2343                          "%s: Writing ofdmbase=%u   cckbase=%u\n",
2344                          __func__, aniState->ofdmPhyErrBase,
2345                          aniState->cckPhyErrBase);
2346                 REG_WRITE(ah, AR_PHY_ERR_1, aniState->ofdmPhyErrBase);
2347                 REG_WRITE(ah, AR_PHY_ERR_2, aniState->cckPhyErrBase);
2348                 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2349                 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2350
2351                 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2352         }
2353         aniState->ofdmPhyErrCount = 0;
2354         aniState->cckPhyErrCount = 0;
2355 }
2356
2357 static void ath9k_hw_ani_ofdm_err_trigger(struct ath_hal *ah)
2358 {
2359         struct ath_hal_5416 *ahp = AH5416(ah);
2360         struct ath9k_channel *chan = ah->ah_curchan;
2361         struct ar5416AniState *aniState;
2362         enum wireless_mode mode;
2363         int32_t rssi;
2364
2365         if (!DO_ANI(ah))
2366                 return;
2367
2368         aniState = ahp->ah_curani;
2369
2370         if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2371                 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2372                                          aniState->noiseImmunityLevel + 1)) {
2373                         return;
2374                 }
2375         }
2376
2377         if (aniState->spurImmunityLevel < HAL_SPUR_IMMUNE_MAX) {
2378                 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2379                                          aniState->spurImmunityLevel + 1)) {
2380                         return;
2381                 }
2382         }
2383
2384         if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2385                 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2386                         ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2387                                              aniState->firstepLevel + 1);
2388                 }
2389                 return;
2390         }
2391         rssi = BEACON_RSSI(ahp);
2392         if (rssi > aniState->rssiThrHigh) {
2393                 if (!aniState->ofdmWeakSigDetectOff) {
2394                         if (ath9k_hw_ani_control(ah,
2395                                          ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2396                                          false)) {
2397                                 ath9k_hw_ani_control(ah,
2398                                         ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2399                                         0);
2400                                 return;
2401                         }
2402                 }
2403                 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2404                         ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2405                                              aniState->firstepLevel + 1);
2406                         return;
2407                 }
2408         } else if (rssi > aniState->rssiThrLow) {
2409                 if (aniState->ofdmWeakSigDetectOff)
2410                         ath9k_hw_ani_control(ah,
2411                                      ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2412                                      true);
2413                 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2414                         ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2415                                              aniState->firstepLevel + 1);
2416                 return;
2417         } else {
2418                 mode = ath9k_hw_chan2wmode(ah, chan);
2419                 if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
2420                         if (!aniState->ofdmWeakSigDetectOff)
2421                                 ath9k_hw_ani_control(ah,
2422                                      ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2423                                      false);
2424                         if (aniState->firstepLevel > 0)
2425                                 ath9k_hw_ani_control(ah,
2426                                                      ATH9K_ANI_FIRSTEP_LEVEL,
2427                                                      0);
2428                         return;
2429                 }
2430         }
2431 }
2432
2433 static void ath9k_hw_ani_cck_err_trigger(struct ath_hal *ah)
2434 {
2435         struct ath_hal_5416 *ahp = AH5416(ah);
2436         struct ath9k_channel *chan = ah->ah_curchan;
2437         struct ar5416AniState *aniState;
2438         enum wireless_mode mode;
2439         int32_t rssi;
2440
2441         if (!DO_ANI(ah))
2442                 return;
2443
2444         aniState = ahp->ah_curani;
2445         if (aniState->noiseImmunityLevel < HAL_NOISE_IMMUNE_MAX) {
2446                 if (ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2447                                          aniState->noiseImmunityLevel + 1)) {
2448                         return;
2449                 }
2450         }
2451         if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2452                 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX) {
2453                         ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2454                                              aniState->firstepLevel + 1);
2455                 }
2456                 return;
2457         }
2458         rssi = BEACON_RSSI(ahp);
2459         if (rssi > aniState->rssiThrLow) {
2460                 if (aniState->firstepLevel < HAL_FIRST_STEP_MAX)
2461                         ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2462                                              aniState->firstepLevel + 1);
2463         } else {
2464                 mode = ath9k_hw_chan2wmode(ah, chan);
2465                 if (mode == ATH9K_MODE_11G || mode == ATH9K_MODE_11B) {
2466                         if (aniState->firstepLevel > 0)
2467                                 ath9k_hw_ani_control(ah,
2468                                                      ATH9K_ANI_FIRSTEP_LEVEL,
2469                                                      0);
2470                 }
2471         }
2472 }
2473
2474 static void ath9k_ani_reset(struct ath_hal *ah)
2475 {
2476         struct ath_hal_5416 *ahp = AH5416(ah);
2477         struct ar5416AniState *aniState;
2478         struct ath9k_channel *chan = ah->ah_curchan;
2479         int index;
2480
2481         if (!DO_ANI(ah))
2482                 return;
2483
2484         index = ath9k_hw_get_ani_channel_idx(ah, chan);
2485         aniState = &ahp->ah_ani[index];
2486         ahp->ah_curani = aniState;
2487
2488         if (DO_ANI(ah) && ah->ah_opmode != ATH9K_M_STA
2489             && ah->ah_opmode != ATH9K_M_IBSS) {
2490                 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2491                          "%s: Reset ANI state opmode %u\n", __func__,
2492                          ah->ah_opmode);
2493                 ahp->ah_stats.ast_ani_reset++;
2494                 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL, 0);
2495                 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL, 0);
2496                 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL, 0);
2497                 ath9k_hw_ani_control(ah,
2498                                      ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2499                                      !ATH9K_ANI_USE_OFDM_WEAK_SIG);
2500                 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2501                                      ATH9K_ANI_CCK_WEAK_SIG_THR);
2502                 ath9k_hw_setrxfilter(ah,
2503                                      ath9k_hw_getrxfilter(ah) |
2504                                      ATH9K_RX_FILTER_PHYERR);
2505                 if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2506                         ahp->ah_curani->ofdmTrigHigh =
2507                                 ah->ah_config.ofdm_trig_high;
2508                         ahp->ah_curani->ofdmTrigLow =
2509                                 ah->ah_config.ofdm_trig_low;
2510                         ahp->ah_curani->cckTrigHigh =
2511                                 ah->ah_config.cck_trig_high;
2512                         ahp->ah_curani->cckTrigLow =
2513                                 ah->ah_config.cck_trig_low;
2514                 }
2515                 ath9k_ani_restart(ah);
2516                 return;
2517         }
2518
2519         if (aniState->noiseImmunityLevel != 0)
2520                 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2521                                      aniState->noiseImmunityLevel);
2522         if (aniState->spurImmunityLevel != 0)
2523                 ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2524                                      aniState->spurImmunityLevel);
2525         if (aniState->ofdmWeakSigDetectOff)
2526                 ath9k_hw_ani_control(ah,
2527                                      ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2528                                      !aniState->ofdmWeakSigDetectOff);
2529         if (aniState->cckWeakSigThreshold)
2530                 ath9k_hw_ani_control(ah, ATH9K_ANI_CCK_WEAK_SIGNAL_THR,
2531                                      aniState->cckWeakSigThreshold);
2532         if (aniState->firstepLevel != 0)
2533                 ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2534                                      aniState->firstepLevel);
2535         if (ahp->ah_hasHwPhyCounters) {
2536                 ath9k_hw_setrxfilter(ah,
2537                                      ath9k_hw_getrxfilter(ah) &
2538                                      ~ATH9K_RX_FILTER_PHYERR);
2539                 ath9k_ani_restart(ah);
2540                 REG_WRITE(ah, AR_PHY_ERR_MASK_1, AR_PHY_ERR_OFDM_TIMING);
2541                 REG_WRITE(ah, AR_PHY_ERR_MASK_2, AR_PHY_ERR_CCK_TIMING);
2542
2543         } else {
2544                 ath9k_ani_restart(ah);
2545                 ath9k_hw_setrxfilter(ah,
2546                                      ath9k_hw_getrxfilter(ah) |
2547                                      ATH9K_RX_FILTER_PHYERR);
2548         }
2549 }
2550
2551 void ath9k_hw_procmibevent(struct ath_hal *ah,
2552                            const struct ath9k_node_stats *stats)
2553 {
2554         struct ath_hal_5416 *ahp = AH5416(ah);
2555         u32 phyCnt1, phyCnt2;
2556
2557         DPRINTF(ah->ah_sc, ATH_DBG_ANI, "Processing Mib Intr\n");
2558
2559         REG_WRITE(ah, AR_FILT_OFDM, 0);
2560         REG_WRITE(ah, AR_FILT_CCK, 0);
2561         if (!(REG_READ(ah, AR_SLP_MIB_CTRL) & AR_SLP_MIB_PENDING))
2562                 REG_WRITE(ah, AR_SLP_MIB_CTRL, AR_SLP_MIB_CLEAR);
2563
2564         ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2565         ahp->ah_stats.ast_nodestats = *stats;
2566
2567         if (!DO_ANI(ah))
2568                 return;
2569
2570         phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2571         phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2572         if (((phyCnt1 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK) ||
2573             ((phyCnt2 & AR_MIBCNT_INTRMASK) == AR_MIBCNT_INTRMASK)) {
2574                 struct ar5416AniState *aniState = ahp->ah_curani;
2575                 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2576
2577                 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2578                 ahp->ah_stats.ast_ani_ofdmerrs +=
2579                         ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2580                 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2581
2582                 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2583                 ahp->ah_stats.ast_ani_cckerrs +=
2584                         cckPhyErrCnt - aniState->cckPhyErrCount;
2585                 aniState->cckPhyErrCount = cckPhyErrCnt;
2586
2587                 if (aniState->ofdmPhyErrCount > aniState->ofdmTrigHigh)
2588                         ath9k_hw_ani_ofdm_err_trigger(ah);
2589                 if (aniState->cckPhyErrCount > aniState->cckTrigHigh)
2590                         ath9k_hw_ani_cck_err_trigger(ah);
2591
2592                 ath9k_ani_restart(ah);
2593         }
2594 }
2595
2596 static void ath9k_hw_ani_lower_immunity(struct ath_hal *ah)
2597 {
2598         struct ath_hal_5416 *ahp = AH5416(ah);
2599         struct ar5416AniState *aniState;
2600         int32_t rssi;
2601
2602         aniState = ahp->ah_curani;
2603
2604         if (ah->ah_opmode == ATH9K_M_HOSTAP) {
2605                 if (aniState->firstepLevel > 0) {
2606                         if (ath9k_hw_ani_control(ah, ATH9K_ANI_FIRSTEP_LEVEL,
2607                                                  aniState->firstepLevel - 1)) {
2608                                 return;
2609                         }
2610                 }
2611         } else {
2612                 rssi = BEACON_RSSI(ahp);
2613                 if (rssi > aniState->rssiThrHigh) {
2614                         /* XXX: Handle me */
2615                 } else if (rssi > aniState->rssiThrLow) {
2616                         if (aniState->ofdmWeakSigDetectOff) {
2617                                 if (ath9k_hw_ani_control(ah,
2618                                          ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION,
2619                                          true) ==
2620                                     true) {
2621                                         return;
2622                                 }
2623                         }
2624                         if (aniState->firstepLevel > 0) {
2625                                 if (ath9k_hw_ani_control
2626                                     (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2627                                      aniState->firstepLevel - 1) ==
2628                                     true) {
2629                                         return;
2630                                 }
2631                         }
2632                 } else {
2633                         if (aniState->firstepLevel > 0) {
2634                                 if (ath9k_hw_ani_control
2635                                     (ah, ATH9K_ANI_FIRSTEP_LEVEL,
2636                                      aniState->firstepLevel - 1) ==
2637                                     true) {
2638                                         return;
2639                                 }
2640                         }
2641                 }
2642         }
2643
2644         if (aniState->spurImmunityLevel > 0) {
2645                 if (ath9k_hw_ani_control(ah, ATH9K_ANI_SPUR_IMMUNITY_LEVEL,
2646                                          aniState->spurImmunityLevel - 1)) {
2647                         return;
2648                 }
2649         }
2650
2651         if (aniState->noiseImmunityLevel > 0) {
2652                 ath9k_hw_ani_control(ah, ATH9K_ANI_NOISE_IMMUNITY_LEVEL,
2653                                      aniState->noiseImmunityLevel - 1);
2654                 return;
2655         }
2656 }
2657
2658 static int32_t ath9k_hw_ani_get_listen_time(struct ath_hal *ah)
2659 {
2660         struct ath_hal_5416 *ahp = AH5416(ah);
2661         struct ar5416AniState *aniState;
2662         u32 txFrameCount, rxFrameCount, cycleCount;
2663         int32_t listenTime;
2664
2665         txFrameCount = REG_READ(ah, AR_TFCNT);
2666         rxFrameCount = REG_READ(ah, AR_RFCNT);
2667         cycleCount = REG_READ(ah, AR_CCCNT);
2668
2669         aniState = ahp->ah_curani;
2670         if (aniState->cycleCount == 0 || aniState->cycleCount > cycleCount) {
2671
2672                 listenTime = 0;
2673                 ahp->ah_stats.ast_ani_lzero++;
2674         } else {
2675                 int32_t ccdelta = cycleCount - aniState->cycleCount;
2676                 int32_t rfdelta = rxFrameCount - aniState->rxFrameCount;
2677                 int32_t tfdelta = txFrameCount - aniState->txFrameCount;
2678                 listenTime = (ccdelta - rfdelta - tfdelta) / 44000;
2679         }
2680         aniState->cycleCount = cycleCount;
2681         aniState->txFrameCount = txFrameCount;
2682         aniState->rxFrameCount = rxFrameCount;
2683
2684         return listenTime;
2685 }
2686
2687 void ath9k_hw_ani_monitor(struct ath_hal *ah,
2688                           const struct ath9k_node_stats *stats,
2689                           struct ath9k_channel *chan)
2690 {
2691         struct ath_hal_5416 *ahp = AH5416(ah);
2692         struct ar5416AniState *aniState;
2693         int32_t listenTime;
2694
2695         aniState = ahp->ah_curani;
2696         ahp->ah_stats.ast_nodestats = *stats;
2697
2698         listenTime = ath9k_hw_ani_get_listen_time(ah);
2699         if (listenTime < 0) {
2700                 ahp->ah_stats.ast_ani_lneg++;
2701                 ath9k_ani_restart(ah);
2702                 return;
2703         }
2704
2705         aniState->listenTime += listenTime;
2706
2707         if (ahp->ah_hasHwPhyCounters) {
2708                 u32 phyCnt1, phyCnt2;
2709                 u32 ofdmPhyErrCnt, cckPhyErrCnt;
2710
2711                 ath9k_hw_update_mibstats(ah, &ahp->ah_mibStats);
2712
2713                 phyCnt1 = REG_READ(ah, AR_PHY_ERR_1);
2714                 phyCnt2 = REG_READ(ah, AR_PHY_ERR_2);
2715
2716                 if (phyCnt1 < aniState->ofdmPhyErrBase ||
2717                     phyCnt2 < aniState->cckPhyErrBase) {
2718                         if (phyCnt1 < aniState->ofdmPhyErrBase) {
2719                                 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2720                                          "%s: phyCnt1 0x%x, resetting "
2721                                          "counter value to 0x%x\n",
2722                                          __func__, phyCnt1,
2723                                          aniState->ofdmPhyErrBase);
2724                                 REG_WRITE(ah, AR_PHY_ERR_1,
2725                                           aniState->ofdmPhyErrBase);
2726                                 REG_WRITE(ah, AR_PHY_ERR_MASK_1,
2727                                           AR_PHY_ERR_OFDM_TIMING);
2728                         }
2729                         if (phyCnt2 < aniState->cckPhyErrBase) {
2730                                 DPRINTF(ah->ah_sc, ATH_DBG_ANI,
2731                                          "%s: phyCnt2 0x%x, resetting "
2732                                          "counter value to 0x%x\n",
2733                                          __func__, phyCnt2,
2734                                          aniState->cckPhyErrBase);
2735                                 REG_WRITE(ah, AR_PHY_ERR_2,
2736                                           aniState->cckPhyErrBase);
2737                                 REG_WRITE(ah, AR_PHY_ERR_MASK_2,
2738                                           AR_PHY_ERR_CCK_TIMING);
2739                         }
2740                         return;
2741                 }
2742
2743                 ofdmPhyErrCnt = phyCnt1 - aniState->ofdmPhyErrBase;
2744                 ahp->ah_stats.ast_ani_ofdmerrs +=
2745                         ofdmPhyErrCnt - aniState->ofdmPhyErrCount;
2746                 aniState->ofdmPhyErrCount = ofdmPhyErrCnt;
2747
2748                 cckPhyErrCnt = phyCnt2 - aniState->cckPhyErrBase;
2749                 ahp->ah_stats.ast_ani_cckerrs +=
2750                         cckPhyErrCnt - aniState->cckPhyErrCount;
2751                 aniState->cckPhyErrCount = cckPhyErrCnt;
2752         }
2753
2754         if (!DO_ANI(ah))
2755                 return;
2756
2757         if (aniState->listenTime > 5 * ahp->ah_aniPeriod) {
2758                 if (aniState->ofdmPhyErrCount <= aniState->listenTime *
2759                     aniState->ofdmTrigLow / 1000 &&
2760                     aniState->cckPhyErrCount <= aniState->listenTime *
2761                     aniState->cckTrigLow / 1000)
2762                         ath9k_hw_ani_lower_immunity(ah);
2763                 ath9k_ani_restart(ah);
2764         } else if (aniState->listenTime > ahp->ah_aniPeriod) {
2765                 if (aniState->ofdmPhyErrCount > aniState->listenTime *
2766                     aniState->ofdmTrigHigh / 1000) {
2767                         ath9k_hw_ani_ofdm_err_trigger(ah);
2768                         ath9k_ani_restart(ah);
2769                 } else if (aniState->cckPhyErrCount >
2770                            aniState->listenTime * aniState->cckTrigHigh /
2771                            1000) {
2772                         ath9k_hw_ani_cck_err_trigger(ah);
2773                         ath9k_ani_restart(ah);
2774                 }
2775         }
2776 }
2777
2778 #ifndef ATH_NF_PER_CHAN
2779 static void ath9k_init_nfcal_hist_buffer(struct ath_hal *ah)
2780 {
2781         int i, j;
2782
2783         for (i = 0; i < NUM_NF_READINGS; i++) {
2784                 ah->nfCalHist[i].currIndex = 0;
2785                 ah->nfCalHist[i].privNF = AR_PHY_CCA_MAX_GOOD_VALUE;
2786                 ah->nfCalHist[i].invalidNFcount =
2787                         AR_PHY_CCA_FILTERWINDOW_LENGTH;
2788                 for (j = 0; j < ATH9K_NF_CAL_HIST_MAX; j++) {
2789                         ah->nfCalHist[i].nfCalBuffer[j] =
2790                                 AR_PHY_CCA_MAX_GOOD_VALUE;
2791                 }
2792         }
2793         return;
2794 }
2795 #endif
2796
2797 static void ath9k_hw_gpio_cfg_output_mux(struct ath_hal *ah,
2798                                          u32 gpio, u32 type)
2799 {
2800         int addr;
2801         u32 gpio_shift, tmp;
2802
2803         if (gpio > 11)
2804                 addr = AR_GPIO_OUTPUT_MUX3;
2805         else if (gpio > 5)
2806                 addr = AR_GPIO_OUTPUT_MUX2;
2807         else
2808                 addr = AR_GPIO_OUTPUT_MUX1;
2809
2810         gpio_shift = (gpio % 6) * 5;
2811
2812         if (AR_SREV_9280_20_OR_LATER(ah)
2813             || (addr != AR_GPIO_OUTPUT_MUX1)) {
2814                 REG_RMW(ah, addr, (type << gpio_shift),
2815                         (0x1f << gpio_shift));
2816         } else {
2817                 tmp = REG_READ(ah, addr);
2818                 tmp = ((tmp & 0x1F0) << 1) | (tmp & ~0x1F0);
2819                 tmp &= ~(0x1f << gpio_shift);
2820                 tmp |= (type << gpio_shift);
2821                 REG_WRITE(ah, addr, tmp);
2822         }
2823 }
2824
2825 static bool ath9k_hw_cfg_output(struct ath_hal *ah, u32 gpio,
2826                                 enum ath9k_gpio_output_mux_type
2827                                 halSignalType)
2828 {
2829         u32 ah_signal_type;
2830         u32 gpio_shift;
2831
2832         static u32 MuxSignalConversionTable[] = {
2833
2834                 AR_GPIO_OUTPUT_MUX_AS_OUTPUT,
2835
2836                 AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED,
2837
2838                 AR_GPIO_OUTPUT_MUX_AS_PCIE_POWER_LED,
2839
2840                 AR_GPIO_OUTPUT_MUX_AS_MAC_NETWORK_LED,
2841
2842                 AR_GPIO_OUTPUT_MUX_AS_MAC_POWER_LED,
2843         };
2844
2845         if ((halSignalType >= 0)
2846             && (halSignalType < ARRAY_SIZE(MuxSignalConversionTable)))
2847                 ah_signal_type = MuxSignalConversionTable[halSignalType];
2848         else
2849                 return false;
2850
2851         ath9k_hw_gpio_cfg_output_mux(ah, gpio, ah_signal_type);
2852
2853         gpio_shift = 2 * gpio;
2854
2855         REG_RMW(ah,
2856                 AR_GPIO_OE_OUT,
2857                 (AR_GPIO_OE_OUT_DRV_ALL << gpio_shift),
2858                 (AR_GPIO_OE_OUT_DRV << gpio_shift));
2859
2860         return true;
2861 }
2862
2863 static bool ath9k_hw_set_gpio(struct ath_hal *ah, u32 gpio,
2864                               u32 val)
2865 {
2866         REG_RMW(ah, AR_GPIO_IN_OUT, ((val & 1) << gpio),
2867                 AR_GPIO_BIT(gpio));
2868         return true;
2869 }
2870
2871 static u32 ath9k_hw_gpio_get(struct ath_hal *ah, u32 gpio)
2872 {
2873         if (gpio >= ah->ah_caps.num_gpio_pins)
2874                 return 0xffffffff;
2875
2876         if (AR_SREV_9280_10_OR_LATER(ah)) {
2877                 return (MS
2878                         (REG_READ(ah, AR_GPIO_IN_OUT),
2879                          AR928X_GPIO_IN_VAL) & AR_GPIO_BIT(gpio)) != 0;
2880         } else {
2881                 return (MS(REG_READ(ah, AR_GPIO_IN_OUT), AR_GPIO_IN_VAL) &
2882                         AR_GPIO_BIT(gpio)) != 0;
2883         }
2884 }
2885
2886 static inline int ath9k_hw_post_attach(struct ath_hal *ah)
2887 {
2888         int ecode;
2889
2890         if (!ath9k_hw_chip_test(ah)) {
2891                 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
2892                          "%s: hardware self-test failed\n", __func__