ath9k: Revamp wireless mode usage
[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__);
2893                 return -ENODEV;
2894         }
2895
2896         ecode = ath9k_hw_rf_claim(ah);
2897         if (ecode != 0)
2898                 return ecode;
2899
2900         ecode = ath9k_hw_eeprom_attach(ah);
2901         if (ecode != 0)
2902                 return ecode;
2903         ecode = ath9k_hw_rfattach(ah);
2904         if (ecode != 0)
2905                 return ecode;
2906
2907         if (!AR_SREV_9100(ah)) {
2908                 ath9k_hw_ani_setup(ah);
2909                 ath9k_hw_ani_attach(ah);
2910         }
2911         return 0;
2912 }
2913
2914 static u32 ath9k_hw_ini_fixup(struct ath_hal *ah,
2915                                     struct ar5416_eeprom *pEepData,
2916                                     u32 reg, u32 value)
2917 {
2918         struct base_eep_header *pBase = &(pEepData->baseEepHeader);
2919
2920         switch (ah->ah_devid) {
2921         case AR9280_DEVID_PCI:
2922                 if (reg == 0x7894) {
2923                         DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2924                                  "ini VAL: %x  EEPROM: %x\n", value,
2925                                  (pBase->version & 0xff));
2926
2927                         if ((pBase->version & 0xff) > 0x0a) {
2928                                 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2929                                          "PWDCLKIND: %d\n",
2930                                          pBase->pwdclkind);
2931                                 value &= ~AR_AN_TOP2_PWDCLKIND;
2932                                 value |= AR_AN_TOP2_PWDCLKIND & (pBase->
2933                                          pwdclkind << AR_AN_TOP2_PWDCLKIND_S);
2934                         } else {
2935                                 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2936                                          "PWDCLKIND Earlier Rev\n");
2937                         }
2938
2939                         DPRINTF(ah->ah_sc, ATH_DBG_ANY,
2940                                  "final ini VAL: %x\n", value);
2941                 }
2942                 break;
2943         }
2944         return value;
2945 }
2946
2947 static bool ath9k_hw_fill_cap_info(struct ath_hal *ah)
2948 {
2949         struct ath_hal_5416 *ahp = AH5416(ah);
2950         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
2951         u16 capField = 0, eeval;
2952
2953         eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_0);
2954
2955         ah->ah_currentRD = eeval;
2956
2957         eeval = ath9k_hw_get_eeprom(ahp, EEP_REG_1);
2958         ah->ah_currentRDExt = eeval;
2959
2960         capField = ath9k_hw_get_eeprom(ahp, EEP_OP_CAP);
2961
2962         if (ah->ah_opmode != ATH9K_M_HOSTAP &&
2963             ah->ah_subvendorid == AR_SUBVENDOR_ID_NEW_A) {
2964                 if (ah->ah_currentRD == 0x64 || ah->ah_currentRD == 0x65)
2965                         ah->ah_currentRD += 5;
2966                 else if (ah->ah_currentRD == 0x41)
2967                         ah->ah_currentRD = 0x43;
2968                 DPRINTF(ah->ah_sc, ATH_DBG_REGULATORY,
2969                          "%s: regdomain mapped to 0x%x\n", __func__,
2970                          ah->ah_currentRD);
2971         }
2972
2973         eeval = ath9k_hw_get_eeprom(ahp, EEP_OP_MODE);
2974         bitmap_zero(pCap->wireless_modes, ATH9K_MODE_MAX);
2975
2976         if (eeval & AR5416_OPFLAGS_11A) {
2977                 set_bit(ATH9K_MODE_11A, pCap->wireless_modes);
2978                 if (ah->ah_config.ht_enable) {
2979                         if (!(eeval & AR5416_OPFLAGS_N_5G_HT20))
2980                                 set_bit(ATH9K_MODE_11NA_HT20,
2981                                         pCap->wireless_modes);
2982                         if (!(eeval & AR5416_OPFLAGS_N_5G_HT40)) {
2983                                 set_bit(ATH9K_MODE_11NA_HT40PLUS,
2984                                         pCap->wireless_modes);
2985                                 set_bit(ATH9K_MODE_11NA_HT40MINUS,
2986                                         pCap->wireless_modes);
2987                         }
2988                 }
2989         }
2990
2991         if (eeval & AR5416_OPFLAGS_11G) {
2992                 set_bit(ATH9K_MODE_11B, pCap->wireless_modes);
2993                 set_bit(ATH9K_MODE_11G, pCap->wireless_modes);
2994                 if (ah->ah_config.ht_enable) {
2995                         if (!(eeval & AR5416_OPFLAGS_N_2G_HT20))
2996                                 set_bit(ATH9K_MODE_11NG_HT20,
2997                                         pCap->wireless_modes);
2998                         if (!(eeval & AR5416_OPFLAGS_N_2G_HT40)) {
2999                                 set_bit(ATH9K_MODE_11NG_HT40PLUS,
3000                                         pCap->wireless_modes);
3001                                 set_bit(ATH9K_MODE_11NG_HT40MINUS,
3002                                         pCap->wireless_modes);
3003                         }
3004                 }
3005         }
3006
3007         pCap->tx_chainmask = ath9k_hw_get_eeprom(ahp, EEP_TX_MASK);
3008         if ((ah->ah_isPciExpress)
3009             || (eeval & AR5416_OPFLAGS_11A)) {
3010                 pCap->rx_chainmask =
3011                         ath9k_hw_get_eeprom(ahp, EEP_RX_MASK);
3012         } else {
3013                 pCap->rx_chainmask =
3014                         (ath9k_hw_gpio_get(ah, 0)) ? 0x5 : 0x7;
3015         }
3016
3017         if (!(AR_SREV_9280(ah) && (ah->ah_macRev == 0)))
3018                 ahp->ah_miscMode |= AR_PCU_MIC_NEW_LOC_ENA;
3019
3020         pCap->low_2ghz_chan = 2312;
3021         pCap->high_2ghz_chan = 2732;
3022
3023         pCap->low_5ghz_chan = 4920;
3024         pCap->high_5ghz_chan = 6100;
3025
3026         pCap->hw_caps &= ~ATH9K_HW_CAP_CIPHER_CKIP;
3027         pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_TKIP;
3028         pCap->hw_caps |= ATH9K_HW_CAP_CIPHER_AESCCM;
3029
3030         pCap->hw_caps &= ~ATH9K_HW_CAP_MIC_CKIP;
3031         pCap->hw_caps |= ATH9K_HW_CAP_MIC_TKIP;
3032         pCap->hw_caps |= ATH9K_HW_CAP_MIC_AESCCM;
3033
3034         pCap->hw_caps |= ATH9K_HW_CAP_CHAN_SPREAD;
3035
3036         if (ah->ah_config.ht_enable)
3037                 pCap->hw_caps |= ATH9K_HW_CAP_HT;
3038         else
3039                 pCap->hw_caps &= ~ATH9K_HW_CAP_HT;
3040
3041         pCap->hw_caps |= ATH9K_HW_CAP_GTT;
3042         pCap->hw_caps |= ATH9K_HW_CAP_VEOL;
3043         pCap->hw_caps |= ATH9K_HW_CAP_BSSIDMASK;
3044         pCap->hw_caps &= ~ATH9K_HW_CAP_MCAST_KEYSEARCH;
3045
3046         if (capField & AR_EEPROM_EEPCAP_MAXQCU)
3047                 pCap->total_queues =
3048                         MS(capField, AR_EEPROM_EEPCAP_MAXQCU);
3049         else
3050                 pCap->total_queues = ATH9K_NUM_TX_QUEUES;
3051
3052         if (capField & AR_EEPROM_EEPCAP_KC_ENTRIES)
3053                 pCap->keycache_size =
3054                         1 << MS(capField, AR_EEPROM_EEPCAP_KC_ENTRIES);
3055         else
3056                 pCap->keycache_size = AR_KEYTABLE_SIZE;
3057
3058         pCap->hw_caps |= ATH9K_HW_CAP_FASTCC;
3059         pCap->num_mr_retries = 4;
3060         pCap->tx_triglevel_max = MAX_TX_FIFO_THRESHOLD;
3061
3062         if (AR_SREV_9280_10_OR_LATER(ah))
3063                 pCap->num_gpio_pins = AR928X_NUM_GPIO;
3064         else
3065                 pCap->num_gpio_pins = AR_NUM_GPIO;
3066
3067         if (AR_SREV_9280_10_OR_LATER(ah)) {
3068                 pCap->hw_caps |= ATH9K_HW_CAP_WOW;
3069                 pCap->hw_caps |= ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
3070         } else {
3071                 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW;
3072                 pCap->hw_caps &= ~ATH9K_HW_CAP_WOW_MATCHPATTERN_EXACT;
3073         }
3074
3075         if (AR_SREV_9160_10_OR_LATER(ah) || AR_SREV_9100(ah)) {
3076                 pCap->hw_caps |= ATH9K_HW_CAP_CST;
3077                 pCap->rts_aggr_limit = ATH_AMPDU_LIMIT_MAX;
3078         } else {
3079                 pCap->rts_aggr_limit = (8 * 1024);
3080         }
3081
3082         pCap->hw_caps |= ATH9K_HW_CAP_ENHANCEDPM;
3083
3084         ah->ah_rfsilent = ath9k_hw_get_eeprom(ahp, EEP_RF_SILENT);
3085         if (ah->ah_rfsilent & EEP_RFSILENT_ENABLED) {
3086                 ahp->ah_gpioSelect =
3087                         MS(ah->ah_rfsilent, EEP_RFSILENT_GPIO_SEL);
3088                 ahp->ah_polarity =
3089                         MS(ah->ah_rfsilent, EEP_RFSILENT_POLARITY);
3090
3091                 ath9k_hw_setcapability(ah, ATH9K_CAP_RFSILENT, 1, true,
3092                                        NULL);
3093                 pCap->hw_caps |= ATH9K_HW_CAP_RFSILENT;
3094         }
3095
3096         if ((ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) ||
3097             (ah->ah_macVersion == AR_SREV_VERSION_5416_PCIE) ||
3098             (ah->ah_macVersion == AR_SREV_VERSION_9160) ||
3099             (ah->ah_macVersion == AR_SREV_VERSION_9100) ||
3100             (ah->ah_macVersion == AR_SREV_VERSION_9280))
3101                 pCap->hw_caps &= ~ATH9K_HW_CAP_AUTOSLEEP;
3102         else
3103                 pCap->hw_caps |= ATH9K_HW_CAP_AUTOSLEEP;
3104
3105         if (AR_SREV_9280(ah))
3106                 pCap->hw_caps &= ~ATH9K_HW_CAP_4KB_SPLITTRANS;
3107         else
3108                 pCap->hw_caps |= ATH9K_HW_CAP_4KB_SPLITTRANS;
3109
3110         if (ah->ah_currentRDExt & (1 << REG_EXT_JAPAN_MIDBAND)) {
3111                 pCap->reg_cap =
3112                         AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3113                         AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN |
3114                         AR_EEPROM_EEREGCAP_EN_KK_U2 |
3115                         AR_EEPROM_EEREGCAP_EN_KK_MIDBAND;
3116         } else {
3117                 pCap->reg_cap =
3118                         AR_EEPROM_EEREGCAP_EN_KK_NEW_11A |
3119                         AR_EEPROM_EEREGCAP_EN_KK_U1_EVEN;
3120         }
3121
3122         pCap->reg_cap |= AR_EEPROM_EEREGCAP_EN_FCC_MIDBAND;
3123
3124         pCap->num_antcfg_5ghz =
3125                 ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_5GHZ);
3126         pCap->num_antcfg_2ghz =
3127                 ath9k_hw_get_num_ant_config(ahp, IEEE80211_BAND_2GHZ);
3128
3129         return true;
3130 }
3131
3132 static void ar5416DisablePciePhy(struct ath_hal *ah)
3133 {
3134         if (!AR_SREV_9100(ah))
3135                 return;
3136
3137         REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3138         REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3139         REG_WRITE(ah, AR_PCIE_SERDES, 0x28000029);
3140         REG_WRITE(ah, AR_PCIE_SERDES, 0x57160824);
3141         REG_WRITE(ah, AR_PCIE_SERDES, 0x25980579);
3142         REG_WRITE(ah, AR_PCIE_SERDES, 0x00000000);
3143         REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3144         REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3145         REG_WRITE(ah, AR_PCIE_SERDES, 0x000e1007);
3146
3147         REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3148 }
3149
3150 static void ath9k_set_power_sleep(struct ath_hal *ah, int setChip)
3151 {
3152         REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3153         if (setChip) {
3154                 REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3155                             AR_RTC_FORCE_WAKE_EN);
3156                 if (!AR_SREV_9100(ah))
3157                         REG_WRITE(ah, AR_RC, AR_RC_AHB | AR_RC_HOSTIF);
3158
3159                 REG_CLR_BIT(ah, (u16) (AR_RTC_RESET),
3160                             AR_RTC_RESET_EN);
3161         }
3162 }
3163
3164 static void ath9k_set_power_network_sleep(struct ath_hal *ah, int setChip)
3165 {
3166         REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3167         if (setChip) {
3168                 struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3169
3170                 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
3171                         REG_WRITE(ah, AR_RTC_FORCE_WAKE,
3172                                   AR_RTC_FORCE_WAKE_ON_INT);
3173                 } else {
3174                         REG_CLR_BIT(ah, AR_RTC_FORCE_WAKE,
3175                                     AR_RTC_FORCE_WAKE_EN);
3176                 }
3177         }
3178 }
3179
3180 static bool ath9k_hw_set_power_awake(struct ath_hal *ah,
3181                                      int setChip)
3182 {
3183         u32 val;
3184         int i;
3185
3186         if (setChip) {
3187                 if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
3188                     AR_RTC_STATUS_SHUTDOWN) {
3189                         if (ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)
3190                             != true) {
3191                                 return false;
3192                         }
3193                 }
3194                 if (AR_SREV_9100(ah))
3195                         REG_SET_BIT(ah, AR_RTC_RESET,
3196                                        AR_RTC_RESET_EN);
3197
3198                 REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3199                             AR_RTC_FORCE_WAKE_EN);
3200                 udelay(50);
3201
3202                 for (i = POWER_UP_TIME / 50; i > 0; i--) {
3203                         val = REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M;
3204                         if (val == AR_RTC_STATUS_ON)
3205                                 break;
3206                         udelay(50);
3207                         REG_SET_BIT(ah, AR_RTC_FORCE_WAKE,
3208                                        AR_RTC_FORCE_WAKE_EN);
3209                 }
3210                 if (i == 0) {
3211                         DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3212                                  "%s: Failed to wakeup in %uus\n",
3213                                  __func__, POWER_UP_TIME / 20);
3214                         return false;
3215                 }
3216         }
3217
3218         REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_PWR_SAV);
3219         return true;
3220 }
3221
3222 bool ath9k_hw_setpower(struct ath_hal *ah,
3223                        enum ath9k_power_mode mode)
3224 {
3225         struct ath_hal_5416 *ahp = AH5416(ah);
3226         static const char *modes[] = {
3227                 "AWAKE",
3228                 "FULL-SLEEP",
3229                 "NETWORK SLEEP",
3230                 "UNDEFINED"
3231         };
3232         int status = true, setChip = true;
3233
3234         DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT, "%s: %s -> %s (%s)\n", __func__,
3235                  modes[ahp->ah_powerMode], modes[mode],
3236                  setChip ? "set chip " : "");
3237
3238         switch (mode) {
3239         case ATH9K_PM_AWAKE:
3240                 status = ath9k_hw_set_power_awake(ah, setChip);
3241                 break;
3242         case ATH9K_PM_FULL_SLEEP:
3243                 ath9k_set_power_sleep(ah, setChip);
3244                 ahp->ah_chipFullSleep = true;
3245                 break;
3246         case ATH9K_PM_NETWORK_SLEEP:
3247                 ath9k_set_power_network_sleep(ah, setChip);
3248                 break;
3249         default:
3250                 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
3251                          "%s: unknown power mode %u\n", __func__, mode);
3252                 return false;
3253         }
3254         ahp->ah_powerMode = mode;
3255         return status;
3256 }
3257
3258 static struct ath_hal *ath9k_hw_do_attach(u16 devid,
3259                                           struct ath_softc *sc,
3260                                           void __iomem *mem,
3261                                           int *status)
3262 {
3263         struct ath_hal_5416 *ahp;
3264         struct ath_hal *ah;
3265         int ecode;
3266 #ifndef CONFIG_SLOW_ANT_DIV
3267         u32 i;
3268         u32 j;
3269 #endif
3270
3271         ahp = ath9k_hw_newstate(devid, sc, mem, status);
3272         if (ahp == NULL)
3273                 return NULL;
3274
3275         ah = &ahp->ah;
3276
3277         ath9k_hw_set_defaults(ah);
3278
3279         if (ah->ah_config.intr_mitigation != 0)
3280                 ahp->ah_intrMitigation = true;
3281
3282         if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_POWER_ON)) {
3283                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't reset chip\n",
3284                          __func__);
3285                 ecode = -EIO;
3286                 goto bad;
3287         }
3288
3289         if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE)) {
3290                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: couldn't wakeup chip\n",
3291                          __func__);
3292                 ecode = -EIO;
3293                 goto bad;
3294         }
3295
3296         if (ah->ah_config.serialize_regmode == SER_REG_MODE_AUTO) {
3297                 if (ah->ah_macVersion == AR_SREV_VERSION_5416_PCI) {
3298                         ah->ah_config.serialize_regmode =
3299                                 SER_REG_MODE_ON;
3300                 } else {
3301                         ah->ah_config.serialize_regmode =
3302                                 SER_REG_MODE_OFF;
3303                 }
3304         }
3305         DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3306                 "%s: serialize_regmode is %d\n",
3307                 __func__, ah->ah_config.serialize_regmode);
3308
3309         if ((ah->ah_macVersion != AR_SREV_VERSION_5416_PCI) &&
3310             (ah->ah_macVersion != AR_SREV_VERSION_5416_PCIE) &&
3311             (ah->ah_macVersion != AR_SREV_VERSION_9160) &&
3312             (!AR_SREV_9100(ah)) && (!AR_SREV_9280(ah))) {
3313                 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3314                          "%s: Mac Chip Rev 0x%02x.%x is not supported by "
3315                          "this driver\n", __func__,
3316                          ah->ah_macVersion, ah->ah_macRev);
3317                 ecode = -EOPNOTSUPP;
3318                 goto bad;
3319         }
3320
3321         if (AR_SREV_9100(ah)) {
3322                 ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3323                 ahp->ah_suppCals = IQ_MISMATCH_CAL;
3324                 ah->ah_isPciExpress = false;
3325         }
3326         ah->ah_phyRev = REG_READ(ah, AR_PHY_CHIP_ID);
3327
3328         if (AR_SREV_9160_10_OR_LATER(ah)) {
3329                 if (AR_SREV_9280_10_OR_LATER(ah)) {
3330                         ahp->ah_iqCalData.calData = &iq_cal_single_sample;
3331                         ahp->ah_adcGainCalData.calData =
3332                                 &adc_gain_cal_single_sample;
3333                         ahp->ah_adcDcCalData.calData =
3334                                 &adc_dc_cal_single_sample;
3335                         ahp->ah_adcDcCalInitData.calData =
3336                                 &adc_init_dc_cal;
3337                 } else {
3338                         ahp->ah_iqCalData.calData = &iq_cal_multi_sample;
3339                         ahp->ah_adcGainCalData.calData =
3340                                 &adc_gain_cal_multi_sample;
3341                         ahp->ah_adcDcCalData.calData =
3342                                 &adc_dc_cal_multi_sample;
3343                         ahp->ah_adcDcCalInitData.calData =
3344                                 &adc_init_dc_cal;
3345                 }
3346                 ahp->ah_suppCals =
3347                         ADC_GAIN_CAL | ADC_DC_CAL | IQ_MISMATCH_CAL;
3348         }
3349
3350         if (AR_SREV_9160(ah)) {
3351                 ah->ah_config.enable_ani = 1;
3352                 ahp->ah_ani_function = (ATH9K_ANI_SPUR_IMMUNITY_LEVEL |
3353                                         ATH9K_ANI_FIRSTEP_LEVEL);
3354         } else {
3355                 ahp->ah_ani_function = ATH9K_ANI_ALL;
3356                 if (AR_SREV_9280_10_OR_LATER(ah)) {
3357                         ahp->ah_ani_function &=
3358                                 ~ATH9K_ANI_NOISE_IMMUNITY_LEVEL;
3359                 }
3360         }
3361
3362         DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3363                  "%s: This Mac Chip Rev 0x%02x.%x is \n", __func__,
3364                  ah->ah_macVersion, ah->ah_macRev);
3365
3366         if (AR_SREV_9280_20_OR_LATER(ah)) {
3367                 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280_2,
3368                                ARRAY_SIZE(ar9280Modes_9280_2), 6);
3369                 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280_2,
3370                                ARRAY_SIZE(ar9280Common_9280_2), 2);
3371
3372                 if (ah->ah_config.pcie_clock_req) {
3373                         INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3374                                        ar9280PciePhy_clkreq_off_L1_9280,
3375                                        ARRAY_SIZE
3376                                        (ar9280PciePhy_clkreq_off_L1_9280),
3377                                        2);
3378                 } else {
3379                         INIT_INI_ARRAY(&ahp->ah_iniPcieSerdes,
3380                                        ar9280PciePhy_clkreq_always_on_L1_9280,
3381                                        ARRAY_SIZE
3382                                        (ar9280PciePhy_clkreq_always_on_L1_9280),
3383                                        2);
3384                 }
3385                 INIT_INI_ARRAY(&ahp->ah_iniModesAdditional,
3386                                ar9280Modes_fast_clock_9280_2,
3387                                ARRAY_SIZE(ar9280Modes_fast_clock_9280_2),
3388                                3);
3389         } else if (AR_SREV_9280_10_OR_LATER(ah)) {
3390                 INIT_INI_ARRAY(&ahp->ah_iniModes, ar9280Modes_9280,
3391                                ARRAY_SIZE(ar9280Modes_9280), 6);
3392                 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar9280Common_9280,
3393                                ARRAY_SIZE(ar9280Common_9280), 2);
3394         } else if (AR_SREV_9160_10_OR_LATER(ah)) {
3395                 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9160,
3396                                ARRAY_SIZE(ar5416Modes_9160), 6);
3397                 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9160,
3398                                ARRAY_SIZE(ar5416Common_9160), 2);
3399                 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9160,
3400                                ARRAY_SIZE(ar5416Bank0_9160), 2);
3401                 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9160,
3402                                ARRAY_SIZE(ar5416BB_RfGain_9160), 3);
3403                 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9160,
3404                                ARRAY_SIZE(ar5416Bank1_9160), 2);
3405                 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9160,
3406                                ARRAY_SIZE(ar5416Bank2_9160), 2);
3407                 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9160,
3408                                ARRAY_SIZE(ar5416Bank3_9160), 3);
3409                 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9160,
3410                                ARRAY_SIZE(ar5416Bank6_9160), 3);
3411                 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9160,
3412                                ARRAY_SIZE(ar5416Bank6TPC_9160), 3);
3413                 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9160,
3414                                ARRAY_SIZE(ar5416Bank7_9160), 2);
3415                 if (AR_SREV_9160_11(ah)) {
3416                         INIT_INI_ARRAY(&ahp->ah_iniAddac,
3417                                        ar5416Addac_91601_1,
3418                                        ARRAY_SIZE(ar5416Addac_91601_1), 2);
3419                 } else {
3420                         INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9160,
3421                                        ARRAY_SIZE(ar5416Addac_9160), 2);
3422                 }
3423         } else if (AR_SREV_9100_OR_LATER(ah)) {
3424                 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes_9100,
3425                                ARRAY_SIZE(ar5416Modes_9100), 6);
3426                 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common_9100,
3427                                ARRAY_SIZE(ar5416Common_9100), 2);
3428                 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0_9100,
3429                                ARRAY_SIZE(ar5416Bank0_9100), 2);
3430                 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain_9100,
3431                                ARRAY_SIZE(ar5416BB_RfGain_9100), 3);
3432                 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1_9100,
3433                                ARRAY_SIZE(ar5416Bank1_9100), 2);
3434                 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2_9100,
3435                                ARRAY_SIZE(ar5416Bank2_9100), 2);
3436                 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3_9100,
3437                                ARRAY_SIZE(ar5416Bank3_9100), 3);
3438                 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6_9100,
3439                                ARRAY_SIZE(ar5416Bank6_9100), 3);
3440                 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC_9100,
3441                                ARRAY_SIZE(ar5416Bank6TPC_9100), 3);
3442                 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7_9100,
3443                                ARRAY_SIZE(ar5416Bank7_9100), 2);
3444                 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac_9100,
3445                                ARRAY_SIZE(ar5416Addac_9100), 2);
3446         } else {
3447                 INIT_INI_ARRAY(&ahp->ah_iniModes, ar5416Modes,
3448                                ARRAY_SIZE(ar5416Modes), 6);
3449                 INIT_INI_ARRAY(&ahp->ah_iniCommon, ar5416Common,
3450                                ARRAY_SIZE(ar5416Common), 2);
3451                 INIT_INI_ARRAY(&ahp->ah_iniBank0, ar5416Bank0,
3452                                ARRAY_SIZE(ar5416Bank0), 2);
3453                 INIT_INI_ARRAY(&ahp->ah_iniBB_RfGain, ar5416BB_RfGain,
3454                                ARRAY_SIZE(ar5416BB_RfGain), 3);
3455                 INIT_INI_ARRAY(&ahp->ah_iniBank1, ar5416Bank1,
3456                                ARRAY_SIZE(ar5416Bank1), 2);
3457                 INIT_INI_ARRAY(&ahp->ah_iniBank2, ar5416Bank2,
3458                                ARRAY_SIZE(ar5416Bank2), 2);
3459                 INIT_INI_ARRAY(&ahp->ah_iniBank3, ar5416Bank3,
3460                                ARRAY_SIZE(ar5416Bank3), 3);
3461                 INIT_INI_ARRAY(&ahp->ah_iniBank6, ar5416Bank6,
3462                                ARRAY_SIZE(ar5416Bank6), 3);
3463                 INIT_INI_ARRAY(&ahp->ah_iniBank6TPC, ar5416Bank6TPC,
3464                                ARRAY_SIZE(ar5416Bank6TPC), 3);
3465                 INIT_INI_ARRAY(&ahp->ah_iniBank7, ar5416Bank7,
3466                                ARRAY_SIZE(ar5416Bank7), 2);
3467                 INIT_INI_ARRAY(&ahp->ah_iniAddac, ar5416Addac,
3468                                ARRAY_SIZE(ar5416Addac), 2);
3469         }
3470
3471         if (ah->ah_isPciExpress)
3472                 ath9k_hw_configpcipowersave(ah, 0);
3473         else
3474                 ar5416DisablePciePhy(ah);
3475
3476         ecode = ath9k_hw_post_attach(ah);
3477         if (ecode != 0)
3478                 goto bad;
3479
3480 #ifndef CONFIG_SLOW_ANT_DIV
3481         if (ah->ah_devid == AR9280_DEVID_PCI) {
3482                 for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
3483                         u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
3484
3485                         for (j = 1; j < ahp->ah_iniModes.ia_columns; j++) {
3486                                 u32 val = INI_RA(&ahp->ah_iniModes, i, j);
3487
3488                                 INI_RA(&ahp->ah_iniModes, i, j) =
3489                                         ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom,
3490                                                            reg, val);
3491                         }
3492                 }
3493         }
3494 #endif
3495
3496         if (!ath9k_hw_fill_cap_info(ah)) {
3497                 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3498                          "%s:failed ath9k_hw_fill_cap_info\n", __func__);
3499                 ecode = -EINVAL;
3500                 goto bad;
3501         }
3502
3503         ecode = ath9k_hw_init_macaddr(ah);
3504         if (ecode != 0) {
3505                 DPRINTF(ah->ah_sc, ATH_DBG_RESET,
3506                          "%s: failed initializing mac address\n",
3507                          __func__);
3508                 goto bad;
3509         }
3510
3511         if (AR_SREV_9285(ah))
3512                 ah->ah_txTrigLevel = (AR_FTRIG_256B >> AR_FTRIG_S);
3513         else
3514                 ah->ah_txTrigLevel = (AR_FTRIG_512B >> AR_FTRIG_S);
3515
3516 #ifndef ATH_NF_PER_CHAN
3517
3518         ath9k_init_nfcal_hist_buffer(ah);
3519 #endif
3520
3521         return ah;
3522
3523 bad:
3524         if (ahp)
3525                 ath9k_hw_detach((struct ath_hal *) ahp);
3526         if (status)
3527                 *status = ecode;
3528         return NULL;
3529 }
3530
3531 void ath9k_hw_detach(struct ath_hal *ah)
3532 {
3533         if (!AR_SREV_9100(ah))
3534                 ath9k_hw_ani_detach(ah);
3535         ath9k_hw_rfdetach(ah);
3536
3537         ath9k_hw_setpower(ah, ATH9K_PM_FULL_SLEEP);
3538         kfree(ah);
3539 }
3540
3541 bool ath9k_get_channel_edges(struct ath_hal *ah,
3542                              u16 flags, u16 *low,
3543                              u16 *high)
3544 {
3545         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
3546
3547         if (flags & CHANNEL_5GHZ) {
3548                 *low = pCap->low_5ghz_chan;
3549                 *high = pCap->high_5ghz_chan;
3550                 return true;
3551         }
3552         if ((flags & CHANNEL_2GHZ)) {
3553                 *low = pCap->low_2ghz_chan;
3554                 *high = pCap->high_2ghz_chan;
3555
3556                 return true;
3557         }
3558         return false;
3559 }
3560
3561 static inline bool ath9k_hw_fill_vpd_table(u8 pwrMin,
3562                                            u8 pwrMax,
3563                                            u8 *pPwrList,
3564                                            u8 *pVpdList,
3565                                            u16
3566                                            numIntercepts,
3567                                            u8 *pRetVpdList)
3568 {
3569         u16 i, k;
3570         u8 currPwr = pwrMin;
3571         u16 idxL = 0, idxR = 0;
3572
3573         for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
3574                 ath9k_hw_get_lower_upper_index(currPwr, pPwrList,
3575                                                numIntercepts, &(idxL),
3576                                                &(idxR));
3577                 if (idxR < 1)
3578                         idxR = 1;
3579                 if (idxL == numIntercepts - 1)
3580                         idxL = (u16) (numIntercepts - 2);
3581                 if (pPwrList[idxL] == pPwrList[idxR])
3582                         k = pVpdList[idxL];
3583                 else
3584                         k = (u16) (((currPwr -
3585                                            pPwrList[idxL]) *
3586                                           pVpdList[idxR] +
3587                                           (pPwrList[idxR] -
3588                                            currPwr) * pVpdList[idxL]) /
3589                                          (pPwrList[idxR] -
3590                                           pPwrList[idxL]));
3591                 pRetVpdList[i] = (u8) k;
3592                 currPwr += 2;
3593         }
3594
3595         return true;
3596 }
3597
3598 static inline void
3599 ath9k_hw_get_gain_boundaries_pdadcs(struct ath_hal *ah,
3600                                     struct ath9k_channel *chan,
3601                                     struct cal_data_per_freq *pRawDataSet,
3602                                     u8 *bChans,
3603                                     u16 availPiers,
3604                                     u16 tPdGainOverlap,
3605                                     int16_t *pMinCalPower,
3606                                     u16 *pPdGainBoundaries,
3607                                     u8 *pPDADCValues,
3608                                     u16 numXpdGains)
3609 {
3610         int i, j, k;
3611         int16_t ss;
3612         u16 idxL = 0, idxR = 0, numPiers;
3613         static u8 vpdTableL[AR5416_NUM_PD_GAINS]
3614                 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3615         static u8 vpdTableR[AR5416_NUM_PD_GAINS]
3616                 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3617         static u8 vpdTableI[AR5416_NUM_PD_GAINS]
3618                 [AR5416_MAX_PWR_RANGE_IN_HALF_DB];
3619
3620         u8 *pVpdL, *pVpdR, *pPwrL, *pPwrR;
3621         u8 minPwrT4[AR5416_NUM_PD_GAINS];
3622         u8 maxPwrT4[AR5416_NUM_PD_GAINS];
3623         int16_t vpdStep;
3624         int16_t tmpVal;
3625         u16 sizeCurrVpdTable, maxIndex, tgtIndex;
3626         bool match;
3627         int16_t minDelta = 0;
3628         struct chan_centers centers;
3629
3630         ath9k_hw_get_channel_centers(ah, chan, &centers);
3631
3632         for (numPiers = 0; numPiers < availPiers; numPiers++) {
3633                 if (bChans[numPiers] == AR5416_BCHAN_UNUSED)
3634                         break;
3635         }
3636
3637         match = ath9k_hw_get_lower_upper_index((u8)
3638                                                FREQ2FBIN(centers.
3639                                                          synth_center,
3640                                                          IS_CHAN_2GHZ
3641                                                          (chan)), bChans,
3642                                                numPiers, &idxL, &idxR);
3643
3644         if (match) {
3645                 for (i = 0; i < numXpdGains; i++) {
3646                         minPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][0];
3647                         maxPwrT4[i] = pRawDataSet[idxL].pwrPdg[i][4];
3648                         ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3649                                                 pRawDataSet[idxL].
3650                                                 pwrPdg[i],
3651                                                 pRawDataSet[idxL].
3652                                                 vpdPdg[i],
3653                                                 AR5416_PD_GAIN_ICEPTS,
3654                                                 vpdTableI[i]);
3655                 }
3656         } else {
3657                 for (i = 0; i < numXpdGains; i++) {
3658                         pVpdL = pRawDataSet[idxL].vpdPdg[i];
3659                         pPwrL = pRawDataSet[idxL].pwrPdg[i];
3660                         pVpdR = pRawDataSet[idxR].vpdPdg[i];
3661                         pPwrR = pRawDataSet[idxR].pwrPdg[i];
3662
3663                         minPwrT4[i] = max(pPwrL[0], pPwrR[0]);
3664
3665                         maxPwrT4[i] =
3666                                 min(pPwrL[AR5416_PD_GAIN_ICEPTS - 1],
3667                                     pPwrR[AR5416_PD_GAIN_ICEPTS - 1]);
3668
3669
3670                         ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3671                                                 pPwrL, pVpdL,
3672                                                 AR5416_PD_GAIN_ICEPTS,
3673                                                 vpdTableL[i]);
3674                         ath9k_hw_fill_vpd_table(minPwrT4[i], maxPwrT4[i],
3675                                                 pPwrR, pVpdR,
3676                                                 AR5416_PD_GAIN_ICEPTS,
3677                                                 vpdTableR[i]);
3678
3679                         for (j = 0; j <= (maxPwrT4[i] - minPwrT4[i]) / 2; j++) {
3680                                 vpdTableI[i][j] =
3681                                         (u8) (ath9k_hw_interpolate
3682                                                     ((u16)
3683                                                      FREQ2FBIN(centers.
3684                                                                synth_center,
3685                                                                IS_CHAN_2GHZ
3686                                                                (chan)),
3687                                                      bChans[idxL],
3688                                                      bChans[idxR], vpdTableL[i]
3689                                                      [j], vpdTableR[i]
3690                                                      [j]));
3691                         }
3692                 }
3693         }
3694
3695         *pMinCalPower = (int16_t) (minPwrT4[0] / 2);
3696
3697         k = 0;
3698         for (i = 0; i < numXpdGains; i++) {
3699                 if (i == (numXpdGains - 1))
3700                         pPdGainBoundaries[i] =
3701                                 (u16) (maxPwrT4[i] / 2);
3702                 else
3703                         pPdGainBoundaries[i] =
3704                                 (u16) ((maxPwrT4[i] +
3705                                               minPwrT4[i + 1]) / 4);
3706
3707                 pPdGainBoundaries[i] =
3708                         min((u16) AR5416_MAX_RATE_POWER,
3709                             pPdGainBoundaries[i]);
3710
3711                 if ((i == 0) && !AR_SREV_5416_V20_OR_LATER(ah)) {
3712                         minDelta = pPdGainBoundaries[0] - 23;
3713                         pPdGainBoundaries[0] = 23;
3714                 } else {
3715                         minDelta = 0;
3716                 }
3717
3718                 if (i == 0) {
3719                         if (AR_SREV_9280_10_OR_LATER(ah))
3720                                 ss = (int16_t) (0 - (minPwrT4[i] / 2));
3721                         else
3722                                 ss = 0;
3723                 } else {
3724                         ss = (int16_t) ((pPdGainBoundaries[i - 1] -
3725                                          (minPwrT4[i] / 2)) -
3726                                         tPdGainOverlap + 1 + minDelta);
3727                 }
3728                 vpdStep = (int16_t) (vpdTableI[i][1] - vpdTableI[i][0]);
3729                 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3730
3731                 while ((ss < 0) && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3732                         tmpVal = (int16_t) (vpdTableI[i][0] + ss * vpdStep);
3733                         pPDADCValues[k++] =
3734                                 (u8) ((tmpVal < 0) ? 0 : tmpVal);
3735                         ss++;
3736                 }
3737
3738                 sizeCurrVpdTable =
3739                         (u8) ((maxPwrT4[i] - minPwrT4[i]) / 2 + 1);
3740                 tgtIndex = (u8) (pPdGainBoundaries[i] + tPdGainOverlap -
3741                                        (minPwrT4[i] / 2));
3742                 maxIndex = (tgtIndex <
3743                             sizeCurrVpdTable) ? tgtIndex : sizeCurrVpdTable;
3744
3745                 while ((ss < maxIndex)
3746                        && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3747                         pPDADCValues[k++] = vpdTableI[i][ss++];
3748                 }
3749
3750                 vpdStep = (int16_t) (vpdTableI[i][sizeCurrVpdTable - 1] -
3751                                      vpdTableI[i][sizeCurrVpdTable - 2]);
3752                 vpdStep = (int16_t) ((vpdStep < 1) ? 1 : vpdStep);
3753
3754                 if (tgtIndex > maxIndex) {
3755                         while ((ss <= tgtIndex)
3756                                && (k < (AR5416_NUM_PDADC_VALUES - 1))) {
3757                                 tmpVal = (int16_t) ((vpdTableI[i]
3758                                                      [sizeCurrVpdTable -
3759                                                       1] + (ss - maxIndex +
3760                                                             1) * vpdStep));
3761                                 pPDADCValues[k++] = (u8) ((tmpVal >
3762                                                  255) ? 255 : tmpVal);
3763                                 ss++;
3764                         }
3765                 }
3766         }
3767
3768         while (i < AR5416_PD_GAINS_IN_MASK) {
3769                 pPdGainBoundaries[i] = pPdGainBoundaries[i - 1];
3770                 i++;
3771         }
3772
3773         while (k < AR5416_NUM_PDADC_VALUES) {
3774                 pPDADCValues[k] = pPDADCValues[k - 1];
3775                 k++;
3776         }
3777         return;
3778 }
3779
3780 static inline bool
3781 ath9k_hw_set_power_cal_table(struct ath_hal *ah,
3782                              struct ar5416_eeprom *pEepData,
3783                              struct ath9k_channel *chan,
3784                              int16_t *pTxPowerIndexOffset)
3785 {
3786         struct cal_data_per_freq *pRawDataset;
3787         u8 *pCalBChans = NULL;
3788         u16 pdGainOverlap_t2;
3789         static u8 pdadcValues[AR5416_NUM_PDADC_VALUES];
3790         u16 gainBoundaries[AR5416_PD_GAINS_IN_MASK];
3791         u16 numPiers, i, j;
3792         int16_t tMinCalPower;
3793         u16 numXpdGain, xpdMask;
3794         u16 xpdGainValues[AR5416_NUM_PD_GAINS] = { 0, 0, 0, 0 };
3795         u32 reg32, regOffset, regChainOffset;
3796         int16_t modalIdx;
3797         struct ath_hal_5416 *ahp = AH5416(ah);
3798
3799         modalIdx = IS_CHAN_2GHZ(chan) ? 1 : 0;
3800         xpdMask = pEepData->modalHeader[modalIdx].xpdGain;
3801
3802         if ((pEepData->baseEepHeader.
3803              version & AR5416_EEP_VER_MINOR_MASK) >=
3804             AR5416_EEP_MINOR_VER_2) {
3805                 pdGainOverlap_t2 =
3806                         pEepData->modalHeader[modalIdx].pdGainOverlap;
3807         } else {
3808                 pdGainOverlap_t2 =
3809                         (u16) (MS
3810                                      (REG_READ(ah, AR_PHY_TPCRG5),
3811                                       AR_PHY_TPCRG5_PD_GAIN_OVERLAP));
3812         }
3813
3814         if (IS_CHAN_2GHZ(chan)) {
3815                 pCalBChans = pEepData->calFreqPier2G;
3816                 numPiers = AR5416_NUM_2G_CAL_PIERS;
3817         } else {
3818                 pCalBChans = pEepData->calFreqPier5G;
3819                 numPiers = AR5416_NUM_5G_CAL_PIERS;
3820         }
3821
3822         numXpdGain = 0;
3823
3824         for (i = 1; i <= AR5416_PD_GAINS_IN_MASK; i++) {
3825                 if ((xpdMask >> (AR5416_PD_GAINS_IN_MASK - i)) & 1) {
3826                         if (numXpdGain >= AR5416_NUM_PD_GAINS)
3827                                 break;
3828                         xpdGainValues[numXpdGain] =
3829                                 (u16) (AR5416_PD_GAINS_IN_MASK - i);
3830                         numXpdGain++;
3831                 }
3832         }
3833
3834         REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
3835                       (numXpdGain - 1) & 0x3);
3836         REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
3837                       xpdGainValues[0]);
3838         REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
3839                       xpdGainValues[1]);
3840         REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3,
3841                       xpdGainValues[2]);
3842
3843         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
3844                 if (AR_SREV_5416_V20_OR_LATER(ah) &&
3845                     (ahp->ah_rxchainmask == 5 || ahp->ah_txchainmask == 5)
3846                     && (i != 0)) {
3847                         regChainOffset = (i == 1) ? 0x2000 : 0x1000;
3848                 } else
3849                         regChainOffset = i * 0x1000;
3850                 if (pEepData->baseEepHeader.txMask & (1 << i)) {
3851                         if (IS_CHAN_2GHZ(chan))
3852                                 pRawDataset = pEepData->calPierData2G[i];
3853                         else
3854                                 pRawDataset = pEepData->calPierData5G[i];
3855
3856                         ath9k_hw_get_gain_boundaries_pdadcs(ah, chan,
3857                                                             pRawDataset,
3858                                                             pCalBChans,
3859                                                             numPiers,
3860                                                             pdGainOverlap_t2,
3861                                                             &tMinCalPower,
3862                                                             gainBoundaries,
3863                                                             pdadcValues,
3864                                                             numXpdGain);
3865
3866                         if ((i == 0) || AR_SREV_5416_V20_OR_LATER(ah)) {
3867
3868                                 REG_WRITE(ah,
3869                                           AR_PHY_TPCRG5 + regChainOffset,
3870                                           SM(pdGainOverlap_t2,
3871                                              AR_PHY_TPCRG5_PD_GAIN_OVERLAP)
3872                                           | SM(gainBoundaries[0],
3873                                                AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_1)
3874                                           | SM(gainBoundaries[1],
3875                                                AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_2)
3876                                           | SM(gainBoundaries[2],
3877                                                AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_3)
3878                                           | SM(gainBoundaries[3],
3879                                        AR_PHY_TPCRG5_PD_GAIN_BOUNDARY_4));
3880                         }
3881
3882                         regOffset =
3883                                 AR_PHY_BASE + (672 << 2) + regChainOffset;
3884                         for (j = 0; j < 32; j++) {
3885                                 reg32 =
3886                                         ((pdadcValues[4 * j + 0] & 0xFF) << 0)
3887                                         | ((pdadcValues[4 * j + 1] & 0xFF) <<
3888                                            8) | ((pdadcValues[4 * j + 2] &
3889                                                   0xFF) << 16) |
3890                                         ((pdadcValues[4 * j + 3] & 0xFF) <<
3891                                          24);
3892                                 REG_WRITE(ah, regOffset, reg32);
3893
3894                                 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3895                                          "PDADC (%d,%4x): %4.4x %8.8x\n",
3896                                          i, regChainOffset, regOffset,
3897                                          reg32);
3898                                 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
3899                                 "PDADC: Chain %d | PDADC %3d Value %3d | "
3900                                 "PDADC %3d Value %3d | PDADC %3d Value %3d | "
3901                                 "PDADC %3d Value %3d |\n",
3902                                          i, 4 * j, pdadcValues[4 * j],
3903                                          4 * j + 1, pdadcValues[4 * j + 1],
3904                                          4 * j + 2, pdadcValues[4 * j + 2],
3905                                          4 * j + 3,
3906                                          pdadcValues[4 * j + 3]);
3907
3908                                 regOffset += 4;
3909                         }
3910                 }
3911         }
3912         *pTxPowerIndexOffset = 0;
3913
3914         return true;
3915 }
3916
3917 void ath9k_hw_configpcipowersave(struct ath_hal *ah, int restore)
3918 {
3919         struct ath_hal_5416 *ahp = AH5416(ah);
3920         u8 i;
3921
3922         if (ah->ah_isPciExpress != true)
3923                 return;
3924
3925         if (ah->ah_config.pcie_powersave_enable == 2)
3926                 return;
3927
3928         if (restore)
3929                 return;
3930
3931         if (AR_SREV_9280_20_OR_LATER(ah)) {
3932                 for (i = 0; i < ahp->ah_iniPcieSerdes.ia_rows; i++) {
3933                         REG_WRITE(ah, INI_RA(&ahp->ah_iniPcieSerdes, i, 0),
3934                                   INI_RA(&ahp->ah_iniPcieSerdes, i, 1));
3935                 }
3936                 udelay(1000);
3937         } else if (AR_SREV_9280(ah)
3938                    && (ah->ah_macRev == AR_SREV_REVISION_9280_10)) {
3939                 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fd00);
3940                 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3941
3942                 REG_WRITE(ah, AR_PCIE_SERDES, 0xa8000019);
3943                 REG_WRITE(ah, AR_PCIE_SERDES, 0x13160820);
3944                 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980560);
3945
3946                 if (ah->ah_config.pcie_clock_req)
3947                         REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffc);
3948                 else
3949                         REG_WRITE(ah, AR_PCIE_SERDES, 0x401deffd);
3950
3951                 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3952                 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3953                 REG_WRITE(ah, AR_PCIE_SERDES, 0x00043007);
3954
3955                 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3956
3957                 udelay(1000);
3958         } else {
3959                 REG_WRITE(ah, AR_PCIE_SERDES, 0x9248fc00);
3960                 REG_WRITE(ah, AR_PCIE_SERDES, 0x24924924);
3961                 REG_WRITE(ah, AR_PCIE_SERDES, 0x28000039);
3962                 REG_WRITE(ah, AR_PCIE_SERDES, 0x53160824);
3963                 REG_WRITE(ah, AR_PCIE_SERDES, 0xe5980579);
3964                 REG_WRITE(ah, AR_PCIE_SERDES, 0x001defff);
3965                 REG_WRITE(ah, AR_PCIE_SERDES, 0x1aaabe40);
3966                 REG_WRITE(ah, AR_PCIE_SERDES, 0xbe105554);
3967                 REG_WRITE(ah, AR_PCIE_SERDES, 0x000e3007);
3968                 REG_WRITE(ah, AR_PCIE_SERDES2, 0x00000000);
3969         }
3970
3971         REG_SET_BIT(ah, AR_PCIE_PM_CTRL, AR_PCIE_PM_CTRL_ENA);
3972
3973         if (ah->ah_config.pcie_waen) {
3974                 REG_WRITE(ah, AR_WA, ah->ah_config.pcie_waen);
3975         } else {
3976                 if (AR_SREV_9280(ah))
3977                         REG_WRITE(ah, AR_WA, 0x0040073f);
3978                 else
3979                         REG_WRITE(ah, AR_WA, 0x0000073f);
3980         }
3981 }
3982
3983 static inline void
3984 ath9k_hw_get_legacy_target_powers(struct ath_hal *ah,
3985                                   struct ath9k_channel *chan,
3986                                   struct cal_target_power_leg *powInfo,
3987                                   u16 numChannels,
3988                                   struct cal_target_power_leg *pNewPower,
3989                                   u16 numRates,
3990                                   bool isExtTarget)
3991 {
3992         u16 clo, chi;
3993         int i;
3994         int matchIndex = -1, lowIndex = -1;
3995         u16 freq;
3996         struct chan_centers centers;
3997
3998         ath9k_hw_get_channel_centers(ah, chan, &centers);
3999         freq = (isExtTarget) ? centers.ext_center : centers.ctl_center;
4000
4001         if (freq <= ath9k_hw_fbin2freq(powInfo[0].bChannel,
4002                 IS_CHAN_2GHZ(chan))) {
4003                 matchIndex = 0;
4004         } else {
4005                 for (i = 0; (i < numChannels)
4006                      && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4007                         if (freq ==
4008                             ath9k_hw_fbin2freq(powInfo[i].bChannel,
4009                                                IS_CHAN_2GHZ(chan))) {
4010                                 matchIndex = i;
4011                                 break;
4012                         } else if ((freq <
4013                                     ath9k_hw_fbin2freq(powInfo[i].bChannel,
4014                                                        IS_CHAN_2GHZ(chan)))
4015                                    && (freq >
4016                                        ath9k_hw_fbin2freq(powInfo[i - 1].
4017                                                           bChannel,
4018                                                           IS_CHAN_2GHZ
4019                                                           (chan)))) {
4020                                 lowIndex = i - 1;
4021                                 break;
4022                         }
4023                 }
4024                 if ((matchIndex == -1) && (lowIndex == -1))
4025                         matchIndex = i - 1;
4026         }
4027
4028         if (matchIndex != -1) {
4029                 *pNewPower = powInfo[matchIndex];
4030         } else {
4031                 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4032                                          IS_CHAN_2GHZ(chan));
4033                 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4034                                          IS_CHAN_2GHZ(chan));
4035
4036                 for (i = 0; i < numRates; i++) {
4037                         pNewPower->tPow2x[i] =
4038                                 (u8) ath9k_hw_interpolate(freq, clo, chi,
4039                                                                 powInfo
4040                                                                 [lowIndex].
4041                                                                 tPow2x[i],
4042                                                                 powInfo
4043                                                                 [lowIndex +
4044                                                                  1].tPow2x[i]);
4045                 }
4046         }
4047 }
4048
4049 static inline void
4050 ath9k_hw_get_target_powers(struct ath_hal *ah,
4051                            struct ath9k_channel *chan,
4052                            struct cal_target_power_ht *powInfo,
4053                            u16 numChannels,
4054                            struct cal_target_power_ht *pNewPower,
4055                            u16 numRates,
4056                            bool isHt40Target)
4057 {
4058         u16 clo, chi;
4059         int i;
4060         int matchIndex = -1, lowIndex = -1;
4061         u16 freq;
4062         struct chan_centers centers;
4063
4064         ath9k_hw_get_channel_centers(ah, chan, &centers);
4065         freq = isHt40Target ? centers.synth_center : centers.ctl_center;
4066
4067         if (freq <=
4068                 ath9k_hw_fbin2freq(powInfo[0].bChannel, IS_CHAN_2GHZ(chan))) {
4069                 matchIndex = 0;
4070         } else {
4071                 for (i = 0; (i < numChannels)
4072                      && (powInfo[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4073                         if (freq ==
4074                             ath9k_hw_fbin2freq(powInfo[i].bChannel,
4075                                                IS_CHAN_2GHZ(chan))) {
4076                                 matchIndex = i;
4077                                 break;
4078                         } else
4079                                 if ((freq <
4080                                      ath9k_hw_fbin2freq(powInfo[i].bChannel,
4081                                                         IS_CHAN_2GHZ(chan)))
4082                                     && (freq >
4083                                         ath9k_hw_fbin2freq(powInfo[i - 1].
4084                                                            bChannel,
4085                                                            IS_CHAN_2GHZ
4086                                                            (chan)))) {
4087                                         lowIndex = i - 1;
4088                                         break;
4089                                 }
4090                 }
4091                 if ((matchIndex == -1) && (lowIndex == -1))
4092                         matchIndex = i - 1;
4093         }
4094
4095         if (matchIndex != -1) {
4096                 *pNewPower = powInfo[matchIndex];
4097         } else {
4098                 clo = ath9k_hw_fbin2freq(powInfo[lowIndex].bChannel,
4099                                          IS_CHAN_2GHZ(chan));
4100                 chi = ath9k_hw_fbin2freq(powInfo[lowIndex + 1].bChannel,
4101                                          IS_CHAN_2GHZ(chan));
4102
4103                 for (i = 0; i < numRates; i++) {
4104                         pNewPower->tPow2x[i] =
4105                                 (u8) ath9k_hw_interpolate(freq, clo, chi,
4106                                                                 powInfo
4107                                                                 [lowIndex].
4108                                                                 tPow2x[i],
4109                                                                 powInfo
4110                                                                 [lowIndex +
4111                                                                  1].tPow2x[i]);
4112                 }
4113         }
4114 }
4115
4116 static inline u16
4117 ath9k_hw_get_max_edge_power(u16 freq,
4118                             struct cal_ctl_edges *pRdEdgesPower,
4119                             bool is2GHz)
4120 {
4121         u16 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4122         int i;
4123
4124         for (i = 0; (i < AR5416_NUM_BAND_EDGES)
4125              && (pRdEdgesPower[i].bChannel != AR5416_BCHAN_UNUSED); i++) {
4126                 if (freq == ath9k_hw_fbin2freq(pRdEdgesPower[i].bChannel,
4127                                                is2GHz)) {
4128                         twiceMaxEdgePower = pRdEdgesPower[i].tPower;
4129                         break;
4130                 } else if ((i > 0)
4131                            && (freq <
4132                                ath9k_hw_fbin2freq(pRdEdgesPower[i].
4133                                                   bChannel, is2GHz))) {
4134                         if (ath9k_hw_fbin2freq
4135                             (pRdEdgesPower[i - 1].bChannel, is2GHz) < freq
4136                             && pRdEdgesPower[i - 1].flag) {
4137                                 twiceMaxEdgePower =
4138                                         pRdEdgesPower[i - 1].tPower;
4139                         }
4140                         break;
4141                 }
4142         }
4143         return twiceMaxEdgePower;
4144 }
4145
4146 static inline bool
4147 ath9k_hw_set_power_per_rate_table(struct ath_hal *ah,
4148                                   struct ar5416_eeprom *pEepData,
4149                                   struct ath9k_channel *chan,
4150                                   int16_t *ratesArray,
4151                                   u16 cfgCtl,
4152                                   u8 AntennaReduction,
4153                                   u8 twiceMaxRegulatoryPower,
4154                                   u8 powerLimit)
4155 {
4156         u8 twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4157         static const u16 tpScaleReductionTable[5] =
4158                 { 0, 3, 6, 9, AR5416_MAX_RATE_POWER };
4159
4160         int i;
4161         int8_t twiceLargestAntenna;
4162         struct cal_ctl_data *rep;
4163         struct cal_target_power_leg targetPowerOfdm, targetPowerCck = {
4164                 0, { 0, 0, 0, 0}
4165         };
4166         struct cal_target_power_leg targetPowerOfdmExt = {
4167                 0, { 0, 0, 0, 0} }, targetPowerCckExt = {
4168                 0, { 0, 0, 0, 0 }
4169         };
4170         struct cal_target_power_ht targetPowerHt20, targetPowerHt40 = {
4171                 0, {0, 0, 0, 0}
4172         };
4173         u8 scaledPower = 0, minCtlPower, maxRegAllowedPower;
4174         u16 ctlModesFor11a[] =
4175                 { CTL_11A, CTL_5GHT20, CTL_11A_EXT, CTL_5GHT40 };
4176         u16 ctlModesFor11g[] =
4177                 { CTL_11B, CTL_11G, CTL_2GHT20, CTL_11B_EXT, CTL_11G_EXT,
4178                   CTL_2GHT40
4179                 };
4180         u16 numCtlModes, *pCtlMode, ctlMode, freq;
4181         struct chan_centers centers;
4182         int tx_chainmask;
4183         u8 twiceMinEdgePower;
4184         struct ath_hal_5416 *ahp = AH5416(ah);
4185
4186         tx_chainmask = ahp->ah_txchainmask;
4187
4188         ath9k_hw_get_channel_centers(ah, chan, &centers);
4189
4190         twiceLargestAntenna = max(
4191                 pEepData->modalHeader
4192                         [IS_CHAN_2GHZ(chan)].antennaGainCh[0],
4193                 pEepData->modalHeader
4194                         [IS_CHAN_2GHZ(chan)].antennaGainCh[1]);
4195
4196         twiceLargestAntenna = max((u8) twiceLargestAntenna,
4197                 pEepData->modalHeader
4198                         [IS_CHAN_2GHZ(chan)].antennaGainCh[2]);
4199
4200         twiceLargestAntenna =
4201                 (int8_t) min(AntennaReduction - twiceLargestAntenna, 0);
4202
4203         maxRegAllowedPower = twiceMaxRegulatoryPower + twiceLargestAntenna;
4204
4205         if (ah->ah_tpScale != ATH9K_TP_SCALE_MAX) {
4206                 maxRegAllowedPower -=
4207                         (tpScaleReductionTable[(ah->ah_tpScale)] * 2);
4208         }
4209
4210         scaledPower = min(powerLimit, maxRegAllowedPower);
4211
4212         switch (ar5416_get_ntxchains(tx_chainmask)) {
4213         case 1:
4214                 break;
4215         case 2:
4216                 scaledPower -=
4217                         pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4218                         pwrDecreaseFor2Chain;
4219                 break;
4220         case 3:
4221                 scaledPower -=
4222                         pEepData->modalHeader[IS_CHAN_2GHZ(chan)].
4223                         pwrDecreaseFor3Chain;
4224                 break;
4225         }
4226
4227         scaledPower = max(0, (int32_t) scaledPower);
4228
4229         if (IS_CHAN_2GHZ(chan)) {
4230                 numCtlModes =
4231                         ARRAY_SIZE(ctlModesFor11g) -
4232                         SUB_NUM_CTL_MODES_AT_2G_40;
4233                 pCtlMode = ctlModesFor11g;
4234
4235                 ath9k_hw_get_legacy_target_powers(ah, chan,
4236                         pEepData->
4237                         calTargetPowerCck,
4238                         AR5416_NUM_2G_CCK_TARGET_POWERS,
4239                         &targetPowerCck, 4,
4240                         false);
4241                 ath9k_hw_get_legacy_target_powers(ah, chan,
4242                         pEepData->
4243                         calTargetPower2G,
4244                         AR5416_NUM_2G_20_TARGET_POWERS,
4245                         &targetPowerOfdm, 4,
4246                         false);
4247                 ath9k_hw_get_target_powers(ah, chan,
4248                         pEepData->calTargetPower2GHT20,
4249                         AR5416_NUM_2G_20_TARGET_POWERS,
4250                         &targetPowerHt20, 8, false);
4251
4252                 if (IS_CHAN_HT40(chan)) {
4253                         numCtlModes = ARRAY_SIZE(ctlModesFor11g);
4254                         ath9k_hw_get_target_powers(ah, chan,
4255                                 pEepData->
4256                                 calTargetPower2GHT40,
4257                                 AR5416_NUM_2G_40_TARGET_POWERS,
4258                                 &targetPowerHt40, 8,
4259                                 true);
4260                         ath9k_hw_get_legacy_target_powers(ah, chan,
4261                                 pEepData->
4262                                 calTargetPowerCck,
4263                                 AR5416_NUM_2G_CCK_TARGET_POWERS,
4264                                 &targetPowerCckExt,
4265                                 4, true);
4266                         ath9k_hw_get_legacy_target_powers(ah, chan,
4267                                 pEepData->
4268                                 calTargetPower2G,
4269                                 AR5416_NUM_2G_20_TARGET_POWERS,
4270                                 &targetPowerOfdmExt,
4271                                 4, true);
4272                 }
4273         } else {
4274
4275                 numCtlModes =
4276                         ARRAY_SIZE(ctlModesFor11a) -
4277                         SUB_NUM_CTL_MODES_AT_5G_40;
4278                 pCtlMode = ctlModesFor11a;
4279
4280                 ath9k_hw_get_legacy_target_powers(ah, chan,
4281                         pEepData->
4282                         calTargetPower5G,
4283                         AR5416_NUM_5G_20_TARGET_POWERS,
4284                         &targetPowerOfdm, 4,
4285                         false);
4286                 ath9k_hw_get_target_powers(ah, chan,
4287                         pEepData->calTargetPower5GHT20,
4288                         AR5416_NUM_5G_20_TARGET_POWERS,
4289                         &targetPowerHt20, 8, false);
4290
4291                 if (IS_CHAN_HT40(chan)) {
4292                         numCtlModes = ARRAY_SIZE(ctlModesFor11a);
4293                         ath9k_hw_get_target_powers(ah, chan,
4294                                 pEepData->
4295                                 calTargetPower5GHT40,
4296                                 AR5416_NUM_5G_40_TARGET_POWERS,
4297                                 &targetPowerHt40, 8,
4298                                 true);
4299                         ath9k_hw_get_legacy_target_powers(ah, chan,
4300                                 pEepData->
4301                                 calTargetPower5G,
4302                                 AR5416_NUM_5G_20_TARGET_POWERS,
4303                                 &targetPowerOfdmExt,
4304                                 4, true);
4305                 }
4306         }
4307
4308         for (ctlMode = 0; ctlMode < numCtlModes; ctlMode++) {
4309                 bool isHt40CtlMode =
4310                         (pCtlMode[ctlMode] == CTL_5GHT40)
4311                         || (pCtlMode[ctlMode] == CTL_2GHT40);
4312                 if (isHt40CtlMode)
4313                         freq = centers.synth_center;
4314                 else if (pCtlMode[ctlMode] & EXT_ADDITIVE)
4315                         freq = centers.ext_center;
4316                 else
4317                         freq = centers.ctl_center;
4318
4319                 if (ar5416_get_eep_ver(ahp) == 14
4320                     && ar5416_get_eep_rev(ahp) <= 2)
4321                         twiceMaxEdgePower = AR5416_MAX_RATE_POWER;
4322
4323                 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4324                         "LOOP-Mode ctlMode %d < %d, isHt40CtlMode %d, "
4325                         "EXT_ADDITIVE %d\n",
4326                          ctlMode, numCtlModes, isHt40CtlMode,
4327                          (pCtlMode[ctlMode] & EXT_ADDITIVE));
4328
4329                 for (i = 0; (i < AR5416_NUM_CTLS) && pEepData->ctlIndex[i];
4330                      i++) {
4331                         DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4332                                 "  LOOP-Ctlidx %d: cfgCtl 0x%2.2x "
4333                                 "pCtlMode 0x%2.2x ctlIndex 0x%2.2x "
4334                                 "chan %d\n",
4335                                 i, cfgCtl, pCtlMode[ctlMode],
4336                                 pEepData->ctlIndex[i], chan->channel);
4337
4338                         if ((((cfgCtl & ~CTL_MODE_M) |
4339                               (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4340                              pEepData->ctlIndex[i])
4341                             ||
4342                             (((cfgCtl & ~CTL_MODE_M) |
4343                               (pCtlMode[ctlMode] & CTL_MODE_M)) ==
4344                              ((pEepData->
4345                                ctlIndex[i] & CTL_MODE_M) | SD_NO_CTL))) {
4346                                 rep = &(pEepData->ctlData[i]);
4347
4348                                 twiceMinEdgePower =
4349                                         ath9k_hw_get_max_edge_power(freq,
4350                                                 rep->
4351                                                 ctlEdges
4352                                                 [ar5416_get_ntxchains
4353                                                 (tx_chainmask)
4354                                                 - 1],
4355                                                 IS_CHAN_2GHZ
4356                                                 (chan));
4357
4358                                 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4359                                         "    MATCH-EE_IDX %d: ch %d is2 %d "
4360                                         "2xMinEdge %d chainmask %d chains %d\n",
4361                                          i, freq, IS_CHAN_2GHZ(chan),
4362                                          twiceMinEdgePower, tx_chainmask,
4363                                          ar5416_get_ntxchains
4364                                          (tx_chainmask));
4365                                 if ((cfgCtl & ~CTL_MODE_M) == SD_NO_CTL) {
4366                                         twiceMaxEdgePower =
4367                                                 min(twiceMaxEdgePower,
4368                                                     twiceMinEdgePower);
4369                                 } else {
4370                                         twiceMaxEdgePower =
4371                                                 twiceMinEdgePower;
4372                                         break;
4373                                 }
4374                         }
4375                 }
4376
4377                 minCtlPower = min(twiceMaxEdgePower, scaledPower);
4378
4379                 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
4380                                 "    SEL-Min ctlMode %d pCtlMode %d "
4381                                 "2xMaxEdge %d sP %d minCtlPwr %d\n",
4382                          ctlMode, pCtlMode[ctlMode], twiceMaxEdgePower,
4383                          scaledPower, minCtlPower);
4384
4385                 switch (pCtlMode[ctlMode]) {
4386                 case CTL_11B:
4387                         for (i = 0; i < ARRAY_SIZE(targetPowerCck.tPow2x);
4388                              i++) {
4389                                 targetPowerCck.tPow2x[i] =
4390                                         min(targetPowerCck.tPow2x[i],
4391                                             minCtlPower);
4392                         }
4393                         break;
4394                 case CTL_11A:
4395                 case CTL_11G:
4396                         for (i = 0; i < ARRAY_SIZE(targetPowerOfdm.tPow2x);
4397                              i++) {
4398                                 targetPowerOfdm.tPow2x[i] =
4399                                         min(targetPowerOfdm.tPow2x[i],
4400                                             minCtlPower);
4401                         }
4402                         break;
4403                 case CTL_5GHT20:
4404                 case CTL_2GHT20:
4405                         for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x);
4406                              i++) {
4407                                 targetPowerHt20.tPow2x[i] =
4408                                         min(targetPowerHt20.tPow2x[i],
4409                                             minCtlPower);
4410                         }
4411                         break;
4412                 case CTL_11B_EXT:
4413                         targetPowerCckExt.tPow2x[0] =
4414                                 min(targetPowerCckExt.tPow2x[0], minCtlPower);
4415                         break;
4416                 case CTL_11A_EXT:
4417                 case CTL_11G_EXT:
4418                         targetPowerOfdmExt.tPow2x[0] =
4419                                 min(targetPowerOfdmExt.tPow2x[0], minCtlPower);
4420                         break;
4421                 case CTL_5GHT40:
4422                 case CTL_2GHT40:
4423                         for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x);
4424                              i++) {
4425                                 targetPowerHt40.tPow2x[i] =
4426                                         min(targetPowerHt40.tPow2x[i],
4427                                             minCtlPower);
4428                         }
4429                         break;
4430                 default:
4431                         break;
4432                 }
4433         }
4434
4435         ratesArray[rate6mb] = ratesArray[rate9mb] = ratesArray[rate12mb] =
4436                 ratesArray[rate18mb] = ratesArray[rate24mb] =
4437                 targetPowerOfdm.tPow2x[0];
4438         ratesArray[rate36mb] = targetPowerOfdm.tPow2x[1];
4439         ratesArray[rate48mb] = targetPowerOfdm.tPow2x[2];
4440         ratesArray[rate54mb] = targetPowerOfdm.tPow2x[3];
4441         ratesArray[rateXr] = targetPowerOfdm.tPow2x[0];
4442
4443         for (i = 0; i < ARRAY_SIZE(targetPowerHt20.tPow2x); i++)
4444                 ratesArray[rateHt20_0 + i] = targetPowerHt20.tPow2x[i];
4445
4446         if (IS_CHAN_2GHZ(chan)) {
4447                 ratesArray[rate1l] = targetPowerCck.tPow2x[0];
4448                 ratesArray[rate2s] = ratesArray[rate2l] =
4449                         targetPowerCck.tPow2x[1];
4450                 ratesArray[rate5_5s] = ratesArray[rate5_5l] =
4451                         targetPowerCck.tPow2x[2];
4452                 ;
4453                 ratesArray[rate11s] = ratesArray[rate11l] =
4454                         targetPowerCck.tPow2x[3];
4455                 ;
4456         }
4457         if (IS_CHAN_HT40(chan)) {
4458                 for (i = 0; i < ARRAY_SIZE(targetPowerHt40.tPow2x); i++) {
4459                         ratesArray[rateHt40_0 + i] =
4460                                 targetPowerHt40.tPow2x[i];
4461                 }
4462                 ratesArray[rateDupOfdm] = targetPowerHt40.tPow2x[0];
4463                 ratesArray[rateDupCck] = targetPowerHt40.tPow2x[0];
4464                 ratesArray[rateExtOfdm] = targetPowerOfdmExt.tPow2x[0];
4465                 if (IS_CHAN_2GHZ(chan)) {
4466                         ratesArray[rateExtCck] =
4467                                 targetPowerCckExt.tPow2x[0];
4468                 }
4469         }
4470         return true;
4471 }
4472
4473 static int
4474 ath9k_hw_set_txpower(struct ath_hal *ah,
4475                      struct ar5416_eeprom *pEepData,
4476                      struct ath9k_channel *chan,
4477                      u16 cfgCtl,
4478                      u8 twiceAntennaReduction,
4479                      u8 twiceMaxRegulatoryPower,
4480                      u8 powerLimit)
4481 {
4482         struct modal_eep_header *pModal =
4483                 &(pEepData->modalHeader[IS_CHAN_2GHZ(chan)]);
4484         int16_t ratesArray[Ar5416RateSize];
4485         int16_t txPowerIndexOffset = 0;
4486         u8 ht40PowerIncForPdadc = 2;
4487         int i;
4488
4489         memset(ratesArray, 0, sizeof(ratesArray));
4490
4491         if ((pEepData->baseEepHeader.
4492              version & AR5416_EEP_VER_MINOR_MASK) >=
4493             AR5416_EEP_MINOR_VER_2) {
4494                 ht40PowerIncForPdadc = pModal->ht40PowerIncForPdadc;
4495         }
4496
4497         if (!ath9k_hw_set_power_per_rate_table(ah, pEepData, chan,
4498                                                &ratesArray[0], cfgCtl,
4499                                                twiceAntennaReduction,
4500                                                twiceMaxRegulatoryPower,
4501                                                powerLimit)) {
4502                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4503                         "ath9k_hw_set_txpower: unable to set "
4504                         "tx power per rate table\n");
4505                 return -EIO;
4506         }
4507
4508         if (!ath9k_hw_set_power_cal_table
4509             (ah, pEepData, chan, &txPowerIndexOffset)) {
4510                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
4511                          "ath9k_hw_set_txpower: unable to set power table\n");
4512                 return -EIO;
4513         }
4514
4515         for (i = 0; i < ARRAY_SIZE(ratesArray); i++) {
4516                 ratesArray[i] =
4517                         (int16_t) (txPowerIndexOffset + ratesArray[i]);
4518                 if (ratesArray[i] > AR5416_MAX_RATE_POWER)
4519                         ratesArray[i] = AR5416_MAX_RATE_POWER;
4520         }
4521
4522         if (AR_SREV_9280_10_OR_LATER(ah)) {
4523                 for (i = 0; i < Ar5416RateSize; i++)
4524                         ratesArray[i] -= AR5416_PWR_TABLE_OFFSET * 2;
4525         }
4526
4527         REG_WRITE(ah, AR_PHY_POWER_TX_RATE1,
4528                   ATH9K_POW_SM(ratesArray[rate18mb], 24)
4529                   | ATH9K_POW_SM(ratesArray[rate12mb], 16)
4530                   | ATH9K_POW_SM(ratesArray[rate9mb], 8)
4531                   | ATH9K_POW_SM(ratesArray[rate6mb], 0)
4532                 );
4533         REG_WRITE(ah, AR_PHY_POWER_TX_RATE2,
4534                   ATH9K_POW_SM(ratesArray[rate54mb], 24)
4535                   | ATH9K_POW_SM(ratesArray[rate48mb], 16)
4536                   | ATH9K_POW_SM(ratesArray[rate36mb], 8)
4537                   | ATH9K_POW_SM(ratesArray[rate24mb], 0)
4538                 );
4539
4540         if (IS_CHAN_2GHZ(chan)) {
4541                 REG_WRITE(ah, AR_PHY_POWER_TX_RATE3,
4542                           ATH9K_POW_SM(ratesArray[rate2s], 24)
4543                           | ATH9K_POW_SM(ratesArray[rate2l], 16)
4544                           | ATH9K_POW_SM(ratesArray[rateXr], 8)
4545                           | ATH9K_POW_SM(ratesArray[rate1l], 0)
4546                         );
4547                 REG_WRITE(ah, AR_PHY_POWER_TX_RATE4,
4548                           ATH9K_POW_SM(ratesArray[rate11s], 24)
4549                           | ATH9K_POW_SM(ratesArray[rate11l], 16)
4550                           | ATH9K_POW_SM(ratesArray[rate5_5s], 8)
4551                           | ATH9K_POW_SM(ratesArray[rate5_5l], 0)
4552                         );
4553         }
4554
4555         REG_WRITE(ah, AR_PHY_POWER_TX_RATE5,
4556                   ATH9K_POW_SM(ratesArray[rateHt20_3], 24)
4557                   | ATH9K_POW_SM(ratesArray[rateHt20_2], 16)
4558                   | ATH9K_POW_SM(ratesArray[rateHt20_1], 8)
4559                   | ATH9K_POW_SM(ratesArray[rateHt20_0], 0)
4560                 );
4561         REG_WRITE(ah, AR_PHY_POWER_TX_RATE6,
4562                   ATH9K_POW_SM(ratesArray[rateHt20_7], 24)
4563                   | ATH9K_POW_SM(ratesArray[rateHt20_6], 16)
4564                   | ATH9K_POW_SM(ratesArray[rateHt20_5], 8)
4565                   | ATH9K_POW_SM(ratesArray[rateHt20_4], 0)
4566                 );
4567
4568         if (IS_CHAN_HT40(chan)) {
4569                 REG_WRITE(ah, AR_PHY_POWER_TX_RATE7,
4570                           ATH9K_POW_SM(ratesArray[rateHt40_3] +
4571                                        ht40PowerIncForPdadc, 24)
4572                           | ATH9K_POW_SM(ratesArray[rateHt40_2] +
4573                                          ht40PowerIncForPdadc, 16)
4574                           | ATH9K_POW_SM(ratesArray[rateHt40_1] +
4575                                          ht40PowerIncForPdadc, 8)
4576                           | ATH9K_POW_SM(ratesArray[rateHt40_0] +
4577                                          ht40PowerIncForPdadc, 0)
4578                         );
4579                 REG_WRITE(ah, AR_PHY_POWER_TX_RATE8,
4580                           ATH9K_POW_SM(ratesArray[rateHt40_7] +
4581                                        ht40PowerIncForPdadc, 24)
4582                           | ATH9K_POW_SM(ratesArray[rateHt40_6] +
4583                                          ht40PowerIncForPdadc, 16)
4584                           | ATH9K_POW_SM(ratesArray[rateHt40_5] +
4585                                          ht40PowerIncForPdadc, 8)
4586                           | ATH9K_POW_SM(ratesArray[rateHt40_4] +
4587                                          ht40PowerIncForPdadc, 0)
4588                         );
4589
4590                 REG_WRITE(ah, AR_PHY_POWER_TX_RATE9,
4591                           ATH9K_POW_SM(ratesArray[rateExtOfdm], 24)
4592                           | ATH9K_POW_SM(ratesArray[rateExtCck], 16)
4593                           | ATH9K_POW_SM(ratesArray[rateDupOfdm], 8)
4594                           | ATH9K_POW_SM(ratesArray[rateDupCck], 0)
4595                         );
4596         }
4597
4598         REG_WRITE(ah, AR_PHY_POWER_TX_SUB,
4599                   ATH9K_POW_SM(pModal->pwrDecreaseFor3Chain, 6)
4600                   | ATH9K_POW_SM(pModal->pwrDecreaseFor2Chain, 0)
4601                 );
4602
4603         i = rate6mb;
4604         if (IS_CHAN_HT40(chan))
4605                 i = rateHt40_0;
4606         else if (IS_CHAN_HT20(chan))
4607                 i = rateHt20_0;
4608
4609         if (AR_SREV_9280_10_OR_LATER(ah))
4610                 ah->ah_maxPowerLevel =
4611                         ratesArray[i] + AR5416_PWR_TABLE_OFFSET * 2;
4612         else
4613                 ah->ah_maxPowerLevel = ratesArray[i];
4614
4615         return 0;
4616 }
4617
4618 static inline void ath9k_hw_get_delta_slope_vals(struct ath_hal *ah,
4619                                                  u32 coef_scaled,
4620                                                  u32 *coef_mantissa,
4621                                                  u32 *coef_exponent)
4622 {
4623         u32 coef_exp, coef_man;
4624
4625         for (coef_exp = 31; coef_exp > 0; coef_exp--)
4626                 if ((coef_scaled >> coef_exp) & 0x1)
4627                         break;
4628
4629         coef_exp = 14 - (coef_exp - COEF_SCALE_S);
4630
4631         coef_man = coef_scaled + (1 << (COEF_SCALE_S - coef_exp - 1));
4632
4633         *coef_mantissa = coef_man >> (COEF_SCALE_S - coef_exp);
4634         *coef_exponent = coef_exp - 16;
4635 }
4636
4637 static void
4638 ath9k_hw_set_delta_slope(struct ath_hal *ah,
4639                          struct ath9k_channel *chan)
4640 {
4641         u32 coef_scaled, ds_coef_exp, ds_coef_man;
4642         u32 clockMhzScaled = 0x64000000;
4643         struct chan_centers centers;
4644
4645         if (IS_CHAN_HALF_RATE(chan))
4646                 clockMhzScaled = clockMhzScaled >> 1;
4647         else if (IS_CHAN_QUARTER_RATE(chan))
4648                 clockMhzScaled = clockMhzScaled >> 2;
4649
4650         ath9k_hw_get_channel_centers(ah, chan, &centers);
4651         coef_scaled = clockMhzScaled / centers.synth_center;
4652
4653         ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4654                                       &ds_coef_exp);
4655
4656         REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4657                       AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
4658         REG_RMW_FIELD(ah, AR_PHY_TIMING3,
4659                       AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
4660
4661         coef_scaled = (9 * coef_scaled) / 10;
4662
4663         ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
4664                                       &ds_coef_exp);
4665
4666         REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4667                       AR_PHY_HALFGI_DSC_MAN, ds_coef_man);
4668         REG_RMW_FIELD(ah, AR_PHY_HALFGI,
4669                       AR_PHY_HALFGI_DSC_EXP, ds_coef_exp);
4670 }
4671
4672 static void ath9k_hw_9280_spur_mitigate(struct ath_hal *ah,
4673                                         struct ath9k_channel *chan)
4674 {
4675         int bb_spur = AR_NO_SPUR;
4676         int freq;
4677         int bin, cur_bin;
4678         int bb_spur_off, spur_subchannel_sd;
4679         int spur_freq_sd;
4680         int spur_delta_phase;
4681         int denominator;
4682         int upper, lower, cur_vit_mask;
4683         int tmp, newVal;
4684         int i;
4685         int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4686                           AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4687         };
4688         int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4689                          AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4690         };
4691         int inc[4] = { 0, 100, 0, 0 };
4692         struct chan_centers centers;
4693
4694         int8_t mask_m[123];
4695         int8_t mask_p[123];
4696         int8_t mask_amt;
4697         int tmp_mask;
4698         int cur_bb_spur;
4699         bool is2GHz = IS_CHAN_2GHZ(chan);
4700
4701         memset(&mask_m, 0, sizeof(int8_t) * 123);
4702         memset(&mask_p, 0, sizeof(int8_t) * 123);
4703
4704         ath9k_hw_get_channel_centers(ah, chan, &centers);
4705         freq = centers.synth_center;
4706
4707         ah->ah_config.spurmode = SPUR_ENABLE_EEPROM;
4708         for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4709                 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4710
4711                 if (is2GHz)
4712                         cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_2GHZ;
4713                 else
4714                         cur_bb_spur = (cur_bb_spur / 10) + AR_BASE_FREQ_5GHZ;
4715
4716                 if (AR_NO_SPUR == cur_bb_spur)
4717                         break;
4718                 cur_bb_spur = cur_bb_spur - freq;
4719
4720                 if (IS_CHAN_HT40(chan)) {
4721                         if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT40) &&
4722                             (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT40)) {
4723                                 bb_spur = cur_bb_spur;
4724                                 break;
4725                         }
4726                 } else if ((cur_bb_spur > -AR_SPUR_FEEQ_BOUND_HT20) &&
4727                            (cur_bb_spur < AR_SPUR_FEEQ_BOUND_HT20)) {
4728                         bb_spur = cur_bb_spur;
4729                         break;
4730                 }
4731         }
4732
4733         if (AR_NO_SPUR == bb_spur) {
4734                 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4735                             AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4736                 return;
4737         } else {
4738                 REG_CLR_BIT(ah, AR_PHY_FORCE_CLKEN_CCK,
4739                             AR_PHY_FORCE_CLKEN_CCK_MRC_MUX);
4740         }
4741
4742         bin = bb_spur * 320;
4743
4744         tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4745
4746         newVal = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4747                         AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4748                         AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4749                         AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4750         REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), newVal);
4751
4752         newVal = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4753                   AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4754                   AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4755                   AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4756                   SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4757         REG_WRITE(ah, AR_PHY_SPUR_REG, newVal);
4758
4759         if (IS_CHAN_HT40(chan)) {
4760                 if (bb_spur < 0) {
4761                         spur_subchannel_sd = 1;
4762                         bb_spur_off = bb_spur + 10;
4763                 } else {
4764                         spur_subchannel_sd = 0;
4765                         bb_spur_off = bb_spur - 10;
4766                 }
4767         } else {
4768                 spur_subchannel_sd = 0;
4769                 bb_spur_off = bb_spur;
4770         }
4771
4772         if (IS_CHAN_HT40(chan))
4773                 spur_delta_phase =
4774                         ((bb_spur * 262144) /
4775                          10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4776         else
4777                 spur_delta_phase =
4778                         ((bb_spur * 524288) /
4779                          10) & AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4780
4781         denominator = IS_CHAN_2GHZ(chan) ? 44 : 40;
4782         spur_freq_sd = ((bb_spur_off * 2048) / denominator) & 0x3ff;
4783
4784         newVal = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4785                   SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4786                   SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4787         REG_WRITE(ah, AR_PHY_TIMING11, newVal);
4788
4789         newVal = spur_subchannel_sd << AR_PHY_SFCORR_SPUR_SUBCHNL_SD_S;
4790         REG_WRITE(ah, AR_PHY_SFCORR_EXT, newVal);
4791
4792         cur_bin = -6000;
4793         upper = bin + 100;
4794         lower = bin - 100;
4795
4796         for (i = 0; i < 4; i++) {
4797                 int pilot_mask = 0;
4798                 int chan_mask = 0;
4799                 int bp = 0;
4800                 for (bp = 0; bp < 30; bp++) {
4801                         if ((cur_bin > lower) && (cur_bin < upper)) {
4802                                 pilot_mask = pilot_mask | 0x1 << bp;
4803                                 chan_mask = chan_mask | 0x1 << bp;
4804                         }
4805                         cur_bin += 100;
4806                 }
4807                 cur_bin += inc[i];
4808                 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
4809                 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
4810         }
4811
4812         cur_vit_mask = 6100;
4813         upper = bin + 120;
4814         lower = bin - 120;
4815
4816         for (i = 0; i < 123; i++) {
4817                 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
4818
4819                         /* workaround for gcc bug #37014 */
4820                         volatile int tmp = abs(cur_vit_mask - bin);
4821
4822                         if (tmp < 75)
4823                                 mask_amt = 1;
4824                         else
4825                                 mask_amt = 0;
4826                         if (cur_vit_mask < 0)
4827                                 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
4828                         else
4829                                 mask_p[cur_vit_mask / 100] = mask_amt;
4830                 }
4831                 cur_vit_mask -= 100;
4832         }
4833
4834         tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
4835                 | (mask_m[48] << 26) | (mask_m[49] << 24)
4836                 | (mask_m[50] << 22) | (mask_m[51] << 20)
4837                 | (mask_m[52] << 18) | (mask_m[53] << 16)
4838                 | (mask_m[54] << 14) | (mask_m[55] << 12)
4839                 | (mask_m[56] << 10) | (mask_m[57] << 8)
4840                 | (mask_m[58] << 6) | (mask_m[59] << 4)
4841                 | (mask_m[60] << 2) | (mask_m[61] << 0);
4842         REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
4843         REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
4844
4845         tmp_mask = (mask_m[31] << 28)
4846                 | (mask_m[32] << 26) | (mask_m[33] << 24)
4847                 | (mask_m[34] << 22) | (mask_m[35] << 20)
4848                 | (mask_m[36] << 18) | (mask_m[37] << 16)
4849                 | (mask_m[48] << 14) | (mask_m[39] << 12)
4850                 | (mask_m[40] << 10) | (mask_m[41] << 8)
4851                 | (mask_m[42] << 6) | (mask_m[43] << 4)
4852                 | (mask_m[44] << 2) | (mask_m[45] << 0);
4853         REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
4854         REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
4855
4856         tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
4857                 | (mask_m[18] << 26) | (mask_m[18] << 24)
4858                 | (mask_m[20] << 22) | (mask_m[20] << 20)
4859                 | (mask_m[22] << 18) | (mask_m[22] << 16)
4860                 | (mask_m[24] << 14) | (mask_m[24] << 12)
4861                 | (mask_m[25] << 10) | (mask_m[26] << 8)
4862                 | (mask_m[27] << 6) | (mask_m[28] << 4)
4863                 | (mask_m[29] << 2) | (mask_m[30] << 0);
4864         REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
4865         REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
4866
4867         tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
4868                 | (mask_m[2] << 26) | (mask_m[3] << 24)
4869                 | (mask_m[4] << 22) | (mask_m[5] << 20)
4870                 | (mask_m[6] << 18) | (mask_m[7] << 16)
4871                 | (mask_m[8] << 14) | (mask_m[9] << 12)
4872                 | (mask_m[10] << 10) | (mask_m[11] << 8)
4873                 | (mask_m[12] << 6) | (mask_m[13] << 4)
4874                 | (mask_m[14] << 2) | (mask_m[15] << 0);
4875         REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
4876         REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
4877
4878         tmp_mask = (mask_p[15] << 28)
4879                 | (mask_p[14] << 26) | (mask_p[13] << 24)
4880                 | (mask_p[12] << 22) | (mask_p[11] << 20)
4881                 | (mask_p[10] << 18) | (mask_p[9] << 16)
4882                 | (mask_p[8] << 14) | (mask_p[7] << 12)
4883                 | (mask_p[6] << 10) | (mask_p[5] << 8)
4884                 | (mask_p[4] << 6) | (mask_p[3] << 4)
4885                 | (mask_p[2] << 2) | (mask_p[1] << 0);
4886         REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
4887         REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
4888
4889         tmp_mask = (mask_p[30] << 28)
4890                 | (mask_p[29] << 26) | (mask_p[28] << 24)
4891                 | (mask_p[27] << 22) | (mask_p[26] << 20)
4892                 | (mask_p[25] << 18) | (mask_p[24] << 16)
4893                 | (mask_p[23] << 14) | (mask_p[22] << 12)
4894                 | (mask_p[21] << 10) | (mask_p[20] << 8)
4895                 | (mask_p[19] << 6) | (mask_p[18] << 4)
4896                 | (mask_p[17] << 2) | (mask_p[16] << 0);
4897         REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
4898         REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
4899
4900         tmp_mask = (mask_p[45] << 28)
4901                 | (mask_p[44] << 26) | (mask_p[43] << 24)
4902                 | (mask_p[42] << 22) | (mask_p[41] << 20)
4903                 | (mask_p[40] << 18) | (mask_p[39] << 16)
4904                 | (mask_p[38] << 14) | (mask_p[37] << 12)
4905                 | (mask_p[36] << 10) | (mask_p[35] << 8)
4906                 | (mask_p[34] << 6) | (mask_p[33] << 4)
4907                 | (mask_p[32] << 2) | (mask_p[31] << 0);
4908         REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
4909         REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
4910
4911         tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
4912                 | (mask_p[59] << 26) | (mask_p[58] << 24)
4913                 | (mask_p[57] << 22) | (mask_p[56] << 20)
4914                 | (mask_p[55] << 18) | (mask_p[54] << 16)
4915                 | (mask_p[53] << 14) | (mask_p[52] << 12)
4916                 | (mask_p[51] << 10) | (mask_p[50] << 8)
4917                 | (mask_p[49] << 6) | (mask_p[48] << 4)
4918                 | (mask_p[47] << 2) | (mask_p[46] << 0);
4919         REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
4920         REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
4921 }
4922
4923 static void ath9k_hw_spur_mitigate(struct ath_hal *ah,
4924                                    struct ath9k_channel *chan)
4925 {
4926         int bb_spur = AR_NO_SPUR;
4927         int bin, cur_bin;
4928         int spur_freq_sd;
4929         int spur_delta_phase;
4930         int denominator;
4931         int upper, lower, cur_vit_mask;
4932         int tmp, new;
4933         int i;
4934         int pilot_mask_reg[4] = { AR_PHY_TIMING7, AR_PHY_TIMING8,
4935                           AR_PHY_PILOT_MASK_01_30, AR_PHY_PILOT_MASK_31_60
4936         };
4937         int chan_mask_reg[4] = { AR_PHY_TIMING9, AR_PHY_TIMING10,
4938                          AR_PHY_CHANNEL_MASK_01_30, AR_PHY_CHANNEL_MASK_31_60
4939         };
4940         int inc[4] = { 0, 100, 0, 0 };
4941
4942         int8_t mask_m[123];
4943         int8_t mask_p[123];
4944         int8_t mask_amt;
4945         int tmp_mask;
4946         int cur_bb_spur;
4947         bool is2GHz = IS_CHAN_2GHZ(chan);
4948
4949         memset(&mask_m, 0, sizeof(int8_t) * 123);
4950         memset(&mask_p, 0, sizeof(int8_t) * 123);
4951
4952         for (i = 0; i < AR_EEPROM_MODAL_SPURS; i++) {
4953                 cur_bb_spur = ath9k_hw_eeprom_get_spur_chan(ah, i, is2GHz);
4954                 if (AR_NO_SPUR == cur_bb_spur)
4955                         break;
4956                 cur_bb_spur = cur_bb_spur - (chan->channel * 10);
4957                 if ((cur_bb_spur > -95) && (cur_bb_spur < 95)) {
4958                         bb_spur = cur_bb_spur;
4959                         break;
4960                 }
4961         }
4962
4963         if (AR_NO_SPUR == bb_spur)
4964                 return;
4965
4966         bin = bb_spur * 32;
4967
4968         tmp = REG_READ(ah, AR_PHY_TIMING_CTRL4(0));
4969         new = tmp | (AR_PHY_TIMING_CTRL4_ENABLE_SPUR_RSSI |
4970                      AR_PHY_TIMING_CTRL4_ENABLE_SPUR_FILTER |
4971                      AR_PHY_TIMING_CTRL4_ENABLE_CHAN_MASK |
4972                      AR_PHY_TIMING_CTRL4_ENABLE_PILOT_MASK);
4973
4974         REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), new);
4975
4976         new = (AR_PHY_SPUR_REG_MASK_RATE_CNTL |
4977                AR_PHY_SPUR_REG_ENABLE_MASK_PPM |
4978                AR_PHY_SPUR_REG_MASK_RATE_SELECT |
4979                AR_PHY_SPUR_REG_ENABLE_VIT_SPUR_RSSI |
4980                SM(SPUR_RSSI_THRESH, AR_PHY_SPUR_REG_SPUR_RSSI_THRESH));
4981         REG_WRITE(ah, AR_PHY_SPUR_REG, new);
4982
4983         spur_delta_phase = ((bb_spur * 524288) / 100) &
4984                 AR_PHY_TIMING11_SPUR_DELTA_PHASE;
4985
4986         denominator = IS_CHAN_2GHZ(chan) ? 440 : 400;
4987         spur_freq_sd = ((bb_spur * 2048) / denominator) & 0x3ff;
4988
4989         new = (AR_PHY_TIMING11_USE_SPUR_IN_AGC |
4990                SM(spur_freq_sd, AR_PHY_TIMING11_SPUR_FREQ_SD) |
4991                SM(spur_delta_phase, AR_PHY_TIMING11_SPUR_DELTA_PHASE));
4992         REG_WRITE(ah, AR_PHY_TIMING11, new);
4993
4994         cur_bin = -6000;
4995         upper = bin + 100;
4996         lower = bin - 100;
4997
4998         for (i = 0; i < 4; i++) {
4999                 int pilot_mask = 0;
5000                 int chan_mask = 0;
5001                 int bp = 0;
5002                 for (bp = 0; bp < 30; bp++) {
5003                         if ((cur_bin > lower) && (cur_bin < upper)) {
5004                                 pilot_mask = pilot_mask | 0x1 << bp;
5005                                 chan_mask = chan_mask | 0x1 << bp;
5006                         }
5007                         cur_bin += 100;
5008                 }
5009                 cur_bin += inc[i];
5010                 REG_WRITE(ah, pilot_mask_reg[i], pilot_mask);
5011                 REG_WRITE(ah, chan_mask_reg[i], chan_mask);
5012         }
5013
5014         cur_vit_mask = 6100;
5015         upper = bin + 120;
5016         lower = bin - 120;
5017
5018         for (i = 0; i < 123; i++) {
5019                 if ((cur_vit_mask > lower) && (cur_vit_mask < upper)) {
5020                         if ((abs(cur_vit_mask - bin)) < 75)
5021                                 mask_amt = 1;
5022                         else
5023                                 mask_amt = 0;
5024                         if (cur_vit_mask < 0)
5025                                 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5026                         else
5027                                 mask_p[cur_vit_mask / 100] = mask_amt;
5028                 }
5029                 cur_vit_mask -= 100;
5030         }
5031
5032         tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5033                 | (mask_m[48] << 26) | (mask_m[49] << 24)
5034                 | (mask_m[50] << 22) | (mask_m[51] << 20)
5035                 | (mask_m[52] << 18) | (mask_m[53] << 16)
5036                 | (mask_m[54] << 14) | (mask_m[55] << 12)
5037                 | (mask_m[56] << 10) | (mask_m[57] << 8)
5038                 | (mask_m[58] << 6) | (mask_m[59] << 4)
5039                 | (mask_m[60] << 2) | (mask_m[61] << 0);
5040         REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5041         REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5042
5043         tmp_mask = (mask_m[31] << 28)
5044                 | (mask_m[32] << 26) | (mask_m[33] << 24)
5045                 | (mask_m[34] << 22) | (mask_m[35] << 20)
5046                 | (mask_m[36] << 18) | (mask_m[37] << 16)
5047                 | (mask_m[48] << 14) | (mask_m[39] << 12)
5048                 | (mask_m[40] << 10) | (mask_m[41] << 8)
5049                 | (mask_m[42] << 6) | (mask_m[43] << 4)
5050                 | (mask_m[44] << 2) | (mask_m[45] << 0);
5051         REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5052         REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5053
5054         tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5055                 | (mask_m[18] << 26) | (mask_m[18] << 24)
5056                 | (mask_m[20] << 22) | (mask_m[20] << 20)
5057                 | (mask_m[22] << 18) | (mask_m[22] << 16)
5058                 | (mask_m[24] << 14) | (mask_m[24] << 12)
5059                 | (mask_m[25] << 10) | (mask_m[26] << 8)
5060                 | (mask_m[27] << 6) | (mask_m[28] << 4)
5061                 | (mask_m[29] << 2) | (mask_m[30] << 0);
5062         REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5063         REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5064
5065         tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5066                 | (mask_m[2] << 26) | (mask_m[3] << 24)
5067                 | (mask_m[4] << 22) | (mask_m[5] << 20)
5068                 | (mask_m[6] << 18) | (mask_m[7] << 16)
5069                 | (mask_m[8] << 14) | (mask_m[9] << 12)
5070                 | (mask_m[10] << 10) | (mask_m[11] << 8)
5071                 | (mask_m[12] << 6) | (mask_m[13] << 4)
5072                 | (mask_m[14] << 2) | (mask_m[15] << 0);
5073         REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5074         REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5075
5076         tmp_mask = (mask_p[15] << 28)
5077                 | (mask_p[14] << 26) | (mask_p[13] << 24)
5078                 | (mask_p[12] << 22) | (mask_p[11] << 20)
5079                 | (mask_p[10] << 18) | (mask_p[9] << 16)
5080                 | (mask_p[8] << 14) | (mask_p[7] << 12)
5081                 | (mask_p[6] << 10) | (mask_p[5] << 8)
5082                 | (mask_p[4] << 6) | (mask_p[3] << 4)
5083                 | (mask_p[2] << 2) | (mask_p[1] << 0);
5084         REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5085         REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5086
5087         tmp_mask = (mask_p[30] << 28)
5088                 | (mask_p[29] << 26) | (mask_p[28] << 24)
5089                 | (mask_p[27] << 22) | (mask_p[26] << 20)
5090                 | (mask_p[25] << 18) | (mask_p[24] << 16)
5091                 | (mask_p[23] << 14) | (mask_p[22] << 12)
5092                 | (mask_p[21] << 10) | (mask_p[20] << 8)
5093                 | (mask_p[19] << 6) | (mask_p[18] << 4)
5094                 | (mask_p[17] << 2) | (mask_p[16] << 0);
5095         REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5096         REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5097
5098         tmp_mask = (mask_p[45] << 28)
5099                 | (mask_p[44] << 26) | (mask_p[43] << 24)
5100                 | (mask_p[42] << 22) | (mask_p[41] << 20)
5101                 | (mask_p[40] << 18) | (mask_p[39] << 16)
5102                 | (mask_p[38] << 14) | (mask_p[37] << 12)
5103                 | (mask_p[36] << 10) | (mask_p[35] << 8)
5104                 | (mask_p[34] << 6) | (mask_p[33] << 4)
5105                 | (mask_p[32] << 2) | (mask_p[31] << 0);
5106         REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5107         REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5108
5109         tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5110                 | (mask_p[59] << 26) | (mask_p[58] << 24)
5111                 | (mask_p[57] << 22) | (mask_p[56] << 20)
5112                 | (mask_p[55] << 18) | (mask_p[54] << 16)
5113                 | (mask_p[53] << 14) | (mask_p[52] << 12)
5114                 | (mask_p[51] << 10) | (mask_p[50] << 8)
5115                 | (mask_p[49] << 6) | (mask_p[48] << 4)
5116                 | (mask_p[47] << 2) | (mask_p[46] << 0);
5117         REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5118         REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5119 }
5120
5121 static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5122 {
5123         struct ath_hal_5416 *ahp = AH5416(ah);
5124         int rx_chainmask, tx_chainmask;
5125
5126         rx_chainmask = ahp->ah_rxchainmask;
5127         tx_chainmask = ahp->ah_txchainmask;
5128
5129         switch (rx_chainmask) {
5130         case 0x5:
5131                 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5132                             AR_PHY_SWAP_ALT_CHAIN);
5133         case 0x3:
5134                 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5135                         REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5136                         REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5137                         break;
5138                 }
5139         case 0x1:
5140         case 0x2:
5141                 if (!AR_SREV_9280(ah))
5142                         break;
5143         case 0x7:
5144                 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5145                 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5146                 break;
5147         default:
5148                 break;
5149         }
5150
5151         REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5152         if (tx_chainmask == 0x5) {
5153                 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5154                             AR_PHY_SWAP_ALT_CHAIN);
5155         }
5156         if (AR_SREV_9100(ah))
5157                 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5158                           REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5159 }
5160
5161 static void ath9k_hw_set_addac(struct ath_hal *ah,
5162                                struct ath9k_channel *chan)
5163 {
5164         struct modal_eep_header *pModal;
5165         struct ath_hal_5416 *ahp = AH5416(ah);
5166         struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5167         u8 biaslevel;
5168
5169         if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5170                 return;
5171
5172         if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5173                 return;
5174
5175         pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5176
5177         if (pModal->xpaBiasLvl != 0xff) {
5178                 biaslevel = pModal->xpaBiasLvl;
5179         } else {
5180
5181                 u16 resetFreqBin, freqBin, freqCount = 0;
5182                 struct chan_centers centers;
5183
5184                 ath9k_hw_get_channel_centers(ah, chan, &centers);
5185
5186                 resetFreqBin =
5187                         FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5188                 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5189                 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5190
5191                 freqCount++;
5192
5193                 while (freqCount < 3) {
5194                         if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5195                                 break;
5196
5197                         freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5198                         if (resetFreqBin >= freqBin) {
5199                                 biaslevel =
5200                                         (u8) (pModal->
5201                                                     xpaBiasLvlFreq[freqCount]
5202                                                     >> 14);
5203                         } else {
5204                                 break;
5205                         }
5206                         freqCount++;
5207                 }
5208         }
5209
5210         if (IS_CHAN_2GHZ(chan)) {
5211                 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5212                         (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5213                         << 3;
5214         } else {
5215                 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5216                         (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5217                         << 6;
5218         }
5219 }
5220
5221 static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5222 {
5223         if (ah->ah_curchan != NULL)
5224                 return clks /
5225                 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5226         else
5227                 return clks / CLOCK_RATE[ATH9K_MODE_11B];
5228 }
5229
5230 static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5231 {
5232         struct ath9k_channel *chan = ah->ah_curchan;
5233
5234         if (chan && IS_CHAN_HT40(chan))
5235                 return ath9k_hw_mac_usec(ah, clks) / 2;
5236         else
5237                 return ath9k_hw_mac_usec(ah, clks);
5238 }
5239
5240 static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5241 {
5242         if (ah->ah_curchan != NULL)
5243                 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5244                         ah->ah_curchan)];
5245         else
5246                 return usecs * CLOCK_RATE[ATH9K_MODE_11B];
5247 }
5248
5249 static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5250 {
5251         struct ath9k_channel *chan = ah->ah_curchan;
5252
5253         if (chan && IS_CHAN_HT40(chan))
5254                 return ath9k_hw_mac_clks(ah, usecs) * 2;
5255         else
5256                 return ath9k_hw_mac_clks(ah, usecs);
5257 }
5258
5259 static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5260 {
5261         struct ath_hal_5416 *ahp = AH5416(ah);
5262
5263         if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5264                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5265                          __func__, us);
5266                 ahp->ah_acktimeout = (u32) -1;
5267                 return false;
5268         } else {
5269                 REG_RMW_FIELD(ah, AR_TIME_OUT,
5270                               AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5271                 ahp->ah_acktimeout = us;
5272                 return true;
5273         }
5274 }
5275
5276 static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5277 {
5278         struct ath_hal_5416 *ahp = AH5416(ah);
5279
5280         if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5281                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5282                          __func__, us);
5283                 ahp->ah_ctstimeout = (u32) -1;
5284                 return false;
5285         } else {
5286                 REG_RMW_FIELD(ah, AR_TIME_OUT,
5287                               AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5288                 ahp->ah_ctstimeout = us;
5289                 return true;
5290         }
5291 }
5292 static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5293                                           u32 tu)
5294 {
5295         struct ath_hal_5416 *ahp = AH5416(ah);
5296
5297         if (tu > 0xFFFF) {
5298                 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5299                         "%s: bad global tx timeout %u\n", __func__, tu);
5300                 ahp->ah_globaltxtimeout = (u32) -1;
5301                 return false;
5302         } else {
5303                 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5304                 ahp->ah_globaltxtimeout = tu;
5305                 return true;
5306         }
5307 }
5308
5309 bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5310 {
5311         struct ath_hal_5416 *ahp = AH5416(ah);
5312
5313         if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5314                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5315                          __func__, us);
5316                 ahp->ah_slottime = (u32) -1;
5317                 return false;
5318         } else {
5319                 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5320                 ahp->ah_slottime = us;
5321                 return true;
5322         }
5323 }
5324
5325 static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5326 {
5327         struct ath_hal_5416 *ahp = AH5416(ah);
5328
5329         DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5330                  __func__, ahp->ah_miscMode);
5331         if (ahp->ah_miscMode != 0)
5332                 REG_WRITE(ah, AR_PCU_MISC,
5333                           REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5334         if (ahp->ah_slottime != (u32) -1)
5335                 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5336         if (ahp->ah_acktimeout != (u32) -1)
5337                 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5338         if (ahp->ah_ctstimeout != (u32) -1)
5339                 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5340         if (ahp->ah_globaltxtimeout != (u32) -1)
5341                 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5342 }
5343
5344 static inline int
5345 ath9k_hw_process_ini(struct ath_hal *ah,
5346                      struct ath9k_channel *chan,
5347                      enum ath9k_ht_macmode macmode)
5348 {
5349         int i, regWrites = 0;
5350         struct ath_hal_5416 *ahp = AH5416(ah);
5351         u32 modesIndex, freqIndex;
5352         int status;
5353
5354         switch (chan->chanmode) {
5355         case CHANNEL_A:
5356         case CHANNEL_A_HT20:
5357                 modesIndex = 1;
5358                 freqIndex = 1;
5359                 break;
5360         case CHANNEL_A_HT40PLUS:
5361         case CHANNEL_A_HT40MINUS:
5362                 modesIndex = 2;
5363                 freqIndex = 1;
5364                 break;
5365         case CHANNEL_G:
5366         case CHANNEL_G_HT20:
5367         case CHANNEL_B:
5368                 modesIndex = 4;
5369                 freqIndex = 2;
5370                 break;
5371         case CHANNEL_G_HT40PLUS:
5372         case CHANNEL_G_HT40MINUS:
5373                 modesIndex = 3;
5374                 freqIndex = 2;
5375                 break;
5376
5377         default:
5378                 return -EINVAL;
5379         }
5380
5381         REG_WRITE(ah, AR_PHY(0), 0x00000007);
5382
5383         REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5384
5385         ath9k_hw_set_addac(ah, chan);
5386
5387         if (AR_SREV_5416_V22_OR_LATER(ah)) {
5388                 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5389         } else {
5390                 struct ar5416IniArray temp;
5391                 u32 addacSize =
5392                         sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5393                         ahp->ah_iniAddac.ia_columns;
5394
5395                 memcpy(ahp->ah_addac5416_21,
5396                        ahp->ah_iniAddac.ia_array, addacSize);
5397
5398                 (ahp->ah_addac5416_21)[31 *
5399                                        ahp->ah_iniAddac.ia_columns + 1] = 0;
5400
5401                 temp.ia_array = ahp->ah_addac5416_21;
5402                 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5403                 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5404                 REG_WRITE_ARRAY(&temp, 1, regWrites);
5405         }
5406         REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5407
5408         for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5409                 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5410                 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5411
5412 #ifdef CONFIG_SLOW_ANT_DIV
5413                 if (ah->ah_devid == AR9280_DEVID_PCI)
5414                         val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5415                                                  val);
5416 #endif
5417
5418                 REG_WRITE(ah, reg, val);
5419
5420                 if (reg >= 0x7800 && reg < 0x78a0
5421                     && ah->ah_config.analog_shiftreg) {
5422                         udelay(100);
5423                 }
5424
5425                 DO_DELAY(regWrites);
5426         }
5427
5428         for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5429                 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5430                 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5431
5432                 REG_WRITE(ah, reg, val);
5433
5434                 if (reg >= 0x7800 && reg < 0x78a0
5435                     && ah->ah_config.analog_shiftreg) {
5436                         udelay(100);
5437                 }
5438
5439                 DO_DELAY(regWrites);
5440         }
5441
5442         ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5443
5444         if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5445                 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5446                                 regWrites);
5447         }
5448
5449         ath9k_hw_override_ini(ah, chan);
5450         ath9k_hw_set_regs(ah, chan, macmode);
5451         ath9k_hw_init_chain_masks(ah);
5452
5453         status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5454                                       ath9k_regd_get_ctl(ah, chan),
5455                                       ath9k_regd_get_antenna_allowed(ah,
5456                                                                      chan),
5457                                       chan->maxRegTxPower * 2,
5458                                       min((u32) MAX_RATE_POWER,
5459                                           (u32) ah->ah_powerLimit));
5460         if (status != 0) {
5461                 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5462                          "%s: error init'ing transmit power\n", __func__);
5463                 return -EIO;
5464         }
5465
5466         if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5467                 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5468                          "%s: ar5416SetRfRegs failed\n", __func__);
5469                 return -EIO;
5470         }
5471
5472         return 0;
5473 }
5474
5475 static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5476                                               struct hal_cal_list *currCal)
5477 {
5478         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5479                       AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5480                       currCal->calData->calCountMax);
5481
5482         switch (currCal->calData->calType) {
5483         case IQ_MISMATCH_CAL:
5484                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5485                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5486                          "%s: starting IQ Mismatch Calibration\n",
5487                          __func__);
5488                 break;
5489         case ADC_GAIN_CAL:
5490                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5491                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5492                          "%s: starting ADC Gain Calibration\n", __func__);
5493                 break;
5494         case ADC_DC_CAL:
5495                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5496                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5497                          "%s: starting ADC DC Calibration\n", __func__);
5498                 break;
5499         case ADC_DC_INIT_CAL:
5500                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5501                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5502                          "%s: starting Init ADC DC Calibration\n",
5503                          __func__);
5504                 break;
5505         }
5506
5507         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5508                     AR_PHY_TIMING_CTRL4_DO_CAL);
5509 }
5510
5511 static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5512                                               struct hal_cal_list *currCal)
5513 {
5514         struct ath_hal_5416 *ahp = AH5416(ah);
5515         int i;
5516
5517         ath9k_hw_setup_calibration(ah, currCal);
5518
5519         currCal->calState = CAL_RUNNING;
5520
5521         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5522                 ahp->ah_Meas0.sign[i] = 0;
5523                 ahp->ah_Meas1.sign[i] = 0;
5524                 ahp->ah_Meas2.sign[i] = 0;
5525                 ahp->ah_Meas3.sign[i] = 0;
5526         }
5527
5528         ahp->ah_CalSamples = 0;
5529 }
5530
5531 static inline void
5532 ath9k_hw_per_calibration(struct ath_hal *ah,
5533                          struct ath9k_channel *ichan,
5534                          u8 rxchainmask,
5535                          struct hal_cal_list *currCal,
5536                          bool *isCalDone)
5537 {
5538         struct ath_hal_5416 *ahp = AH5416(ah);
5539
5540         *isCalDone = false;
5541
5542         if (currCal->calState == CAL_RUNNING) {
5543                 if (!(REG_READ(ah,
5544                                AR_PHY_TIMING_CTRL4(0)) &
5545                       AR_PHY_TIMING_CTRL4_DO_CAL)) {
5546
5547                         currCal->calData->calCollect(ah);
5548
5549                         ahp->ah_CalSamples++;
5550
5551                         if (ahp->ah_CalSamples >=
5552                             currCal->calData->calNumSamples) {
5553                                 int i, numChains = 0;
5554                                 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5555                                         if (rxchainmask & (1 << i))
5556                                                 numChains++;
5557                                 }
5558
5559                                 currCal->calData->calPostProc(ah,
5560                                                               numChains);
5561
5562                                 ichan->CalValid |=
5563                                         currCal->calData->calType;
5564                                 currCal->calState = CAL_DONE;
5565                                 *isCalDone = true;
5566                         } else {
5567                                 ath9k_hw_setup_calibration(ah, currCal);
5568                         }
5569                 }
5570         } else if (!(ichan->CalValid & currCal->calData->calType)) {
5571                 ath9k_hw_reset_calibration(ah, currCal);
5572         }
5573 }
5574
5575 static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5576                                           int init_cal_count)
5577 {
5578         struct ath_hal_5416 *ahp = AH5416(ah);
5579         struct ath9k_channel ichan;
5580         bool isCalDone;
5581         struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5582         const struct hal_percal_data *calData = currCal->calData;
5583         int i;
5584
5585         if (currCal == NULL)
5586                 return false;
5587
5588         ichan.CalValid = 0;
5589
5590         for (i = 0; i < init_cal_count; i++) {
5591                 ath9k_hw_reset_calibration(ah, currCal);
5592
5593                 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5594                                    AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5595                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5596                                  "%s: Cal %d failed to complete in 100ms.\n",
5597                                  __func__, calData->calType);
5598
5599                         ahp->ah_cal_list = ahp->ah_cal_list_last =
5600                                 ahp->ah_cal_list_curr = NULL;
5601                         return false;
5602                 }
5603
5604                 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5605                                          currCal, &isCalDone);
5606                 if (!isCalDone) {
5607                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5608                                  "%s: Not able to run Init Cal %d.\n",
5609                                  __func__, calData->calType);
5610                 }
5611                 if (currCal->calNext) {
5612                         currCal = currCal->calNext;
5613                         calData = currCal->calData;
5614                 }
5615         }
5616
5617         ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5618         return true;
5619 }
5620
5621 static inline bool
5622 ath9k_hw_channel_change(struct ath_hal *ah,
5623                         struct ath9k_channel *chan,
5624                         enum ath9k_ht_macmode macmode)
5625 {
5626         u32 synthDelay, qnum;
5627         struct ath_hal_5416 *ahp = AH5416(ah);
5628
5629         for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5630                 if (ath9k_hw_numtxpending(ah, qnum)) {
5631                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5632                                  "%s: Transmit frames pending on queue %d\n",
5633                                  __func__, qnum);
5634                         return false;
5635                 }
5636         }
5637
5638         REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5639         if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5640                            AR_PHY_RFBUS_GRANT_EN)) {
5641                 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5642                          "%s: Could not kill baseband RX\n", __func__);
5643                 return false;
5644         }
5645
5646         ath9k_hw_set_regs(ah, chan, macmode);
5647
5648         if (AR_SREV_9280_10_OR_LATER(ah)) {
5649                 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5650                         DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5651                                  "%s: failed to set channel\n", __func__);
5652                         return false;
5653                 }
5654         } else {
5655                 if (!(ath9k_hw_set_channel(ah, chan))) {
5656                         DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5657                                  "%s: failed to set channel\n", __func__);
5658                         return false;
5659                 }
5660         }
5661
5662         if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5663                                  ath9k_regd_get_ctl(ah, chan),
5664                                  ath9k_regd_get_antenna_allowed(ah, chan),
5665                                  chan->maxRegTxPower * 2,
5666                                  min((u32) MAX_RATE_POWER,
5667                                      (u32) ah->ah_powerLimit)) != 0) {
5668                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5669                          "%s: error init'ing transmit power\n", __func__);
5670                 return false;
5671         }
5672
5673         synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5674         if (IS_CHAN_CCK(chan))
5675                 synthDelay = (4 * synthDelay) / 22;
5676         else
5677                 synthDelay /= 10;
5678
5679         udelay(synthDelay + BASE_ACTIVATE_DELAY);
5680
5681         REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5682
5683         if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5684                 ath9k_hw_set_delta_slope(ah, chan);
5685
5686         if (AR_SREV_9280_10_OR_LATER(ah))
5687                 ath9k_hw_9280_spur_mitigate(ah, chan);
5688         else
5689                 ath9k_hw_spur_mitigate(ah, chan);
5690
5691         if (!chan->oneTimeCalsDone)
5692                 chan->oneTimeCalsDone = true;
5693
5694         return true;
5695 }
5696
5697 static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5698                                 struct ath9k_channel *chan)
5699 {
5700         struct ath_hal_5416 *ahp = AH5416(ah);
5701
5702         if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5703                 return false;
5704
5705         if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5706                 return false;
5707
5708         ahp->ah_chipFullSleep = false;
5709
5710         ath9k_hw_init_pll(ah, chan);
5711
5712         ath9k_hw_set_rfmode(ah, chan);
5713
5714         return true;
5715 }
5716
5717 static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5718 {
5719         u32 regval;
5720
5721         regval = REG_READ(ah, AR_AHB_MODE);
5722         REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5723
5724         regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5725         REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5726
5727         REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5728
5729         regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5730         REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5731
5732         REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5733
5734         if (AR_SREV_9285(ah)) {
5735                 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5736                           AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5737         } else {
5738                 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5739                           AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5740         }
5741 }
5742
5743 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5744 {
5745         REG_WRITE(ah, AR_CR, AR_CR_RXD);
5746         if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5747                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5748                         "%s: dma failed to stop in 10ms\n"
5749                         "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5750                         __func__,
5751                         REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5752                 return false;
5753         } else {
5754                 return true;
5755         }
5756 }
5757
5758 void ath9k_hw_startpcureceive(struct ath_hal *ah)
5759 {
5760         REG_CLR_BIT(ah, AR_DIAG_SW,
5761                     (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5762
5763         ath9k_enable_mib_counters(ah);
5764
5765         ath9k_ani_reset(ah);
5766 }
5767
5768 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5769 {
5770         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5771
5772         ath9k_hw_disable_mib_counters(ah);
5773 }
5774
5775 static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5776                                      struct ath9k_channel *chan,
5777                                      enum hal_cal_types calType)
5778 {
5779         struct ath_hal_5416 *ahp = AH5416(ah);
5780         bool retval = false;
5781
5782         switch (calType & ahp->ah_suppCals) {
5783         case IQ_MISMATCH_CAL:
5784                 if (!IS_CHAN_B(chan))
5785                         retval = true;
5786                 break;
5787         case ADC_GAIN_CAL:
5788         case ADC_DC_CAL:
5789                 if (!IS_CHAN_B(chan)
5790                     && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5791                         retval = true;
5792                 break;
5793         }
5794
5795         return retval;
5796 }
5797
5798 static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5799                                      struct ath9k_channel *chan)
5800 {
5801         struct ath_hal_5416 *ahp = AH5416(ah);
5802         struct ath9k_channel *ichan =
5803                 ath9k_regd_check_channel(ah, chan);
5804
5805         REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5806                   REG_READ(ah, AR_PHY_AGC_CONTROL) |
5807                   AR_PHY_AGC_CONTROL_CAL);
5808
5809         if (!ath9k_hw_wait
5810             (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5811                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5812                          "%s: offset calibration failed to complete in 1ms; "
5813                          "noisy environment?\n", __func__);
5814                 return false;
5815         }
5816
5817         REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5818                   REG_READ(ah, AR_PHY_AGC_CONTROL) |
5819                   AR_PHY_AGC_CONTROL_NF);
5820
5821         ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5822                 NULL;
5823
5824         if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5825                 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5826                         INIT_CAL(&ahp->ah_adcGainCalData);
5827                         INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5828                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5829                                  "%s: enabling ADC Gain Calibration.\n",
5830                                  __func__);
5831                 }
5832                 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5833                         INIT_CAL(&ahp->ah_adcDcCalData);
5834                         INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5835                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5836                                  "%s: enabling ADC DC Calibration.\n",
5837                                  __func__);
5838                 }
5839                 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5840                         INIT_CAL(&ahp->ah_iqCalData);
5841                         INSERT_CAL(ahp, &ahp->ah_iqCalData);
5842                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5843                                  "%s: enabling IQ Calibration.\n",
5844                                  __func__);
5845                 }
5846
5847                 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5848
5849                 if (ahp->ah_cal_list_curr)
5850                         ath9k_hw_reset_calibration(ah,
5851                                                    ahp->ah_cal_list_curr);
5852         }
5853
5854         ichan->CalValid = 0;
5855
5856         return true;
5857 }
5858
5859
5860 bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5861                     struct ath9k_channel *chan,
5862                     enum ath9k_ht_macmode macmode,
5863                     u8 txchainmask, u8 rxchainmask,
5864                     enum ath9k_ht_extprotspacing extprotspacing,
5865                     bool bChannelChange,
5866                     int *status)
5867 {
5868 #define FAIL(_code)     do { ecode = _code; goto bad; } while (0)
5869         u32 saveLedState;
5870         struct ath_hal_5416 *ahp = AH5416(ah);
5871         struct ath9k_channel *curchan = ah->ah_curchan;
5872         u32 saveDefAntenna;
5873         u32 macStaId1;
5874         int ecode;
5875         int i, rx_chainmask;
5876
5877         ahp->ah_extprotspacing = extprotspacing;
5878         ahp->ah_txchainmask = txchainmask;
5879         ahp->ah_rxchainmask = rxchainmask;
5880
5881         if (AR_SREV_9280(ah)) {
5882                 ahp->ah_txchainmask &= 0x3;
5883                 ahp->ah_rxchainmask &= 0x3;
5884         }
5885
5886         if (ath9k_hw_check_chan(ah, chan) == NULL) {
5887                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5888                          "%s: invalid channel %u/0x%x; no mapping\n",
5889                          __func__, chan->channel, chan->channelFlags);
5890                 FAIL(-EINVAL);
5891         }
5892
5893         if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5894                 return false;
5895
5896         if (curchan)
5897                 ath9k_hw_getnf(ah, curchan);
5898
5899         if (bChannelChange &&
5900             (ahp->ah_chipFullSleep != true) &&
5901             (ah->ah_curchan != NULL) &&
5902             (chan->channel != ah->ah_curchan->channel) &&
5903             ((chan->channelFlags & CHANNEL_ALL) ==
5904              (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5905             (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5906                                    !IS_CHAN_A_5MHZ_SPACED(ah->
5907                                                           ah_curchan)))) {
5908
5909                 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5910                         ath9k_hw_loadnf(ah, ah->ah_curchan);
5911                         ath9k_hw_start_nfcal(ah);
5912                         return true;
5913                 }
5914         }
5915
5916         saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5917         if (saveDefAntenna == 0)
5918                 saveDefAntenna = 1;
5919
5920         macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5921
5922         saveLedState = REG_READ(ah, AR_CFG_LED) &
5923                 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5924                  AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5925
5926         ath9k_hw_mark_phy_inactive(ah);
5927
5928         if (!ath9k_hw_chip_reset(ah, chan)) {
5929                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5930                          __func__);
5931                 FAIL(-EIO);
5932         }
5933
5934         if (AR_SREV_9280(ah)) {
5935                 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5936                             AR_GPIO_JTAG_DISABLE);
5937
5938                 if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
5939                         if (IS_CHAN_5GHZ(chan))
5940                                 ath9k_hw_set_gpio(ah, 9, 0);
5941                         else
5942                                 ath9k_hw_set_gpio(ah, 9, 1);
5943                 }
5944                 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5945         }
5946
5947         ecode = ath9k_hw_process_ini(ah, chan, macmode);
5948         if (ecode != 0)
5949                 goto bad;
5950
5951         if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5952                 ath9k_hw_set_delta_slope(ah, chan);
5953
5954         if (AR_SREV_9280_10_OR_LATER(ah))
5955                 ath9k_hw_9280_spur_mitigate(ah, chan);
5956         else
5957                 ath9k_hw_spur_mitigate(ah, chan);
5958
5959         if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5960                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5961                          "%s: error setting board options\n", __func__);
5962                 FAIL(-EIO);
5963         }
5964
5965         ath9k_hw_decrease_chain_power(ah, chan);
5966
5967         REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5968         REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5969                   | macStaId1
5970                   | AR_STA_ID1_RTS_USE_DEF
5971                   | (ah->ah_config.
5972                      ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
5973                   | ahp->ah_staId1Defaults);
5974         ath9k_hw_set_operating_mode(ah, opmode);
5975
5976         REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5977         REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5978
5979         REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5980
5981         REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5982         REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5983                   ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5984
5985         REG_WRITE(ah, AR_ISR, ~0);
5986
5987         REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5988
5989         if (AR_SREV_9280_10_OR_LATER(ah)) {
5990                 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5991                         FAIL(-EIO);
5992         } else {
5993                 if (!(ath9k_hw_set_channel(ah, chan)))
5994                         FAIL(-EIO);
5995         }
5996
5997         for (i = 0; i < AR_NUM_DCU; i++)
5998                 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
5999
6000         ahp->ah_intrTxqs = 0;
6001         for (i = 0; i < ah->ah_caps.total_queues; i++)
6002                 ath9k_hw_resettxqueue(ah, i);
6003
6004         ath9k_hw_init_interrupt_masks(ah, opmode);
6005         ath9k_hw_init_qos(ah);
6006
6007         ath9k_hw_init_user_settings(ah);
6008
6009         ah->ah_opmode = opmode;
6010
6011         REG_WRITE(ah, AR_STA_ID1,
6012                   REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6013
6014         ath9k_hw_set_dma(ah);
6015
6016         REG_WRITE(ah, AR_OBS, 8);
6017
6018         if (ahp->ah_intrMitigation) {
6019
6020                 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6021                 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6022         }
6023
6024         ath9k_hw_init_bb(ah, chan);
6025
6026         if (!ath9k_hw_init_cal(ah, chan))
6027                 FAIL(-ENODEV);
6028
6029         rx_chainmask = ahp->ah_rxchainmask;
6030         if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6031                 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6032                 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6033         }
6034
6035         REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6036
6037         if (AR_SREV_9100(ah)) {
6038                 u32 mask;
6039                 mask = REG_READ(ah, AR_CFG);
6040                 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6041                         DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6042                                  "%s CFG Byte Swap Set 0x%x\n", __func__,
6043                                  mask);
6044                 } else {
6045                         mask =
6046                                 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6047                         REG_WRITE(ah, AR_CFG, mask);
6048                         DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6049                                  "%s Setting CFG 0x%x\n", __func__,
6050                                  REG_READ(ah, AR_CFG));
6051                 }
6052         } else {
6053 #ifdef __BIG_ENDIAN
6054                 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6055 #endif
6056         }
6057
6058         return true;
6059 bad:
6060         if (status)
6061                 *status = ecode;
6062         return false;
6063 #undef FAIL
6064 }
6065
6066 bool ath9k_hw_phy_disable(struct ath_hal *ah)
6067 {
6068         return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6069 }
6070
6071 bool ath9k_hw_disable(struct ath_hal *ah)
6072 {
6073         if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6074                 return false;
6075
6076         return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6077 }
6078
6079 bool
6080 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6081                    u8 rxchainmask, bool longcal,
6082                    bool *isCalDone)
6083 {
6084         struct ath_hal_5416 *ahp = AH5416(ah);
6085         struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6086         struct ath9k_channel *ichan =
6087                 ath9k_regd_check_channel(ah, chan);
6088
6089         *isCalDone = true;
6090
6091         if (ichan == NULL) {
6092                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6093                          "%s: invalid channel %u/0x%x; no mapping\n",
6094                          __func__, chan->channel, chan->channelFlags);
6095                 return false;
6096         }
6097
6098         if (currCal &&
6099             (currCal->calState == CAL_RUNNING ||
6100              currCal->calState == CAL_WAITING)) {
6101                 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6102                                          isCalDone);
6103                 if (*isCalDone) {
6104                         ahp->ah_cal_list_curr = currCal = currCal->calNext;
6105
6106                         if (currCal->calState == CAL_WAITING) {
6107                                 *isCalDone = false;
6108                                 ath9k_hw_reset_calibration(ah, currCal);
6109                         }
6110                 }
6111         }
6112
6113         if (longcal) {
6114                 ath9k_hw_getnf(ah, ichan);
6115                 ath9k_hw_loadnf(ah, ah->ah_curchan);
6116                 ath9k_hw_start_nfcal(ah);
6117
6118                 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6119
6120                         chan->channelFlags |= CHANNEL_CW_INT;
6121                         ichan->channelFlags &= ~CHANNEL_CW_INT;
6122                 }
6123         }
6124
6125         return true;
6126 }
6127
6128 static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6129 {
6130         struct ath_hal_5416 *ahp = AH5416(ah);
6131         int i;
6132
6133         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6134                 ahp->ah_totalPowerMeasI[i] +=
6135                         REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6136                 ahp->ah_totalPowerMeasQ[i] +=
6137                         REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6138                 ahp->ah_totalIqCorrMeas[i] +=
6139                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6140                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6141                          "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6142                          ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6143                          ahp->ah_totalPowerMeasQ[i],
6144                          ahp->ah_totalIqCorrMeas[i]);
6145         }
6146 }
6147
6148 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6149 {
6150         struct ath_hal_5416 *ahp = AH5416(ah);
6151         int i;
6152
6153         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6154                 ahp->ah_totalAdcIOddPhase[i] +=
6155                         REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6156                 ahp->ah_totalAdcIEvenPhase[i] +=
6157                         REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6158                 ahp->ah_totalAdcQOddPhase[i] +=
6159                         REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6160                 ahp->ah_totalAdcQEvenPhase[i] +=
6161                         REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6162
6163                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6164                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6165                         "oddq=0x%08x; evenq=0x%08x;\n",
6166                          ahp->ah_CalSamples, i,
6167                          ahp->ah_totalAdcIOddPhase[i],
6168                          ahp->ah_totalAdcIEvenPhase[i],
6169                          ahp->ah_totalAdcQOddPhase[i],
6170                          ahp->ah_totalAdcQEvenPhase[i]);
6171         }
6172 }
6173
6174 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6175 {
6176         struct ath_hal_5416 *ahp = AH5416(ah);
6177         int i;
6178
6179         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6180                 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6181                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6182                 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6183                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6184                 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6185                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6186                 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6187                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6188
6189                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6190                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6191                         "oddq=0x%08x; evenq=0x%08x;\n",
6192                          ahp->ah_CalSamples, i,
6193                          ahp->ah_totalAdcDcOffsetIOddPhase[i],
6194                          ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6195                          ahp->ah_totalAdcDcOffsetQOddPhase[i],
6196                          ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6197         }
6198 }
6199
6200 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6201 {
6202         struct ath_hal_5416 *ahp = AH5416(ah);
6203         u32 powerMeasQ, powerMeasI, iqCorrMeas;
6204         u32 qCoffDenom, iCoffDenom;
6205         int32_t qCoff, iCoff;
6206         int iqCorrNeg, i;
6207
6208         for (i = 0; i < numChains; i++) {
6209                 powerMeasI = ahp->ah_totalPowerMeasI[i];
6210                 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6211                 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6212
6213                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6214                          "Starting IQ Cal and Correction for Chain %d\n",
6215                          i);
6216
6217                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6218                          "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6219                          i, ahp->ah_totalIqCorrMeas[i]);
6220
6221                 iqCorrNeg = 0;
6222
6223
6224                 if (iqCorrMeas > 0x80000000) {
6225                         iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6226                         iqCorrNeg = 1;
6227                 }
6228
6229                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6230                          "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6231                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6232                          "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6233                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6234                          iqCorrNeg);
6235
6236                 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6237                 qCoffDenom = powerMeasQ / 64;
6238
6239                 if (powerMeasQ != 0) {
6240
6241                         iCoff = iqCorrMeas / iCoffDenom;
6242                         qCoff = powerMeasI / qCoffDenom - 64;
6243                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6244                                  "Chn %d iCoff = 0x%08x\n", i, iCoff);
6245                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6246                                  "Chn %d qCoff = 0x%08x\n", i, qCoff);
6247
6248
6249                         iCoff = iCoff & 0x3f;
6250                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6251                                  "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6252                         if (iqCorrNeg == 0x0)
6253                                 iCoff = 0x40 - iCoff;
6254
6255                         if (qCoff > 15)
6256                                 qCoff = 15;
6257                         else if (qCoff <= -16)
6258                                 qCoff = 16;
6259
6260                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6261                                  "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
6262                                 i, iCoff, qCoff);
6263
6264                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6265                                       AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6266                                       iCoff);
6267                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6268                                       AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6269                                       qCoff);
6270                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6271                                 "IQ Cal and Correction done for Chain %d\n",
6272                                 i);
6273                 }
6274         }
6275
6276         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6277                     AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6278 }
6279
6280 static void
6281 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6282 {
6283         struct ath_hal_5416 *ahp = AH5416(ah);
6284         u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6285                 qEvenMeasOffset;
6286         u32 qGainMismatch, iGainMismatch, val, i;
6287
6288         for (i = 0; i < numChains; i++) {
6289                 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6290                 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6291                 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6292                 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6293
6294                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6295                          "Starting ADC Gain Cal for Chain %d\n", i);
6296
6297                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6298                          "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6299                          iOddMeasOffset);
6300                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6301                          "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6302                          iEvenMeasOffset);
6303                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6304                          "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6305                          qOddMeasOffset);
6306                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6307                          "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6308                          qEvenMeasOffset);
6309
6310                 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6311                         iGainMismatch =
6312                                 ((iEvenMeasOffset * 32) /
6313                                  iOddMeasOffset) & 0x3f;
6314                         qGainMismatch =
6315                                 ((qOddMeasOffset * 32) /
6316                                  qEvenMeasOffset) & 0x3f;
6317
6318                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6319                                  "Chn %d gain_mismatch_i = 0x%08x\n", i,
6320                                  iGainMismatch);
6321                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6322                                  "Chn %d gain_mismatch_q = 0x%08x\n", i,
6323                                  qGainMismatch);
6324
6325                         val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6326                         val &= 0xfffff000;
6327                         val |= (qGainMismatch) | (iGainMismatch << 6);
6328                         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6329
6330                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6331                                  "ADC Gain Cal done for Chain %d\n", i);
6332                 }
6333         }
6334
6335         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6336                   REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6337                   AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6338 }
6339
6340 static void
6341 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6342 {
6343         struct ath_hal_5416 *ahp = AH5416(ah);
6344         u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6345         int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6346         const struct hal_percal_data *calData =
6347                 ahp->ah_cal_list_curr->calData;
6348         u32 numSamples =
6349                 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6350
6351         for (i = 0; i < numChains; i++) {
6352                 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6353                 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6354                 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6355                 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6356
6357                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6358                          "Starting ADC DC Offset Cal for Chain %d\n", i);
6359
6360                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6361                          "Chn %d pwr_meas_odd_i = %d\n", i,
6362                          iOddMeasOffset);
6363                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6364                          "Chn %d pwr_meas_even_i = %d\n", i,
6365                          iEvenMeasOffset);
6366                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6367                          "Chn %d pwr_meas_odd_q = %d\n", i,
6368                          qOddMeasOffset);
6369                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6370                          "Chn %d pwr_meas_even_q = %d\n", i,
6371                          qEvenMeasOffset);
6372
6373                 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6374                                numSamples) & 0x1ff;
6375                 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6376                                numSamples) & 0x1ff;
6377
6378                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6379                          "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6380                          iDcMismatch);
6381                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6382                          "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6383                          qDcMismatch);
6384
6385                 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6386                 val &= 0xc0000fff;
6387                 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6388                 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6389
6390                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6391                          "ADC DC Offset Cal done for Chain %d\n", i);
6392         }
6393
6394         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6395                   REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6396                   AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6397 }
6398
6399 bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6400 {
6401         struct ath_hal_5416 *ahp = AH5416(ah);
6402         struct ath9k_channel *chan = ah->ah_curchan;
6403
6404         ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6405
6406         if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6407                                  ath9k_regd_get_ctl(ah, chan),
6408                                  ath9k_regd_get_antenna_allowed(ah,
6409                                                                 chan),
6410                                  chan->maxRegTxPower * 2,
6411                                  min((u32) MAX_RATE_POWER,
6412                                      (u32) ah->ah_powerLimit)) != 0)
6413                 return false;
6414
6415         return true;
6416 }
6417
6418 void
6419 ath9k_hw_get_channel_centers(struct ath_hal *ah,
6420                              struct ath9k_channel *chan,
6421                              struct chan_centers *centers)
6422 {
6423         int8_t extoff;
6424         struct ath_hal_5416 *ahp = AH5416(ah);
6425
6426         if (!IS_CHAN_HT40(chan)) {
6427                 centers->ctl_center = centers->ext_center =
6428                         centers->synth_center = chan->channel;
6429                 return;
6430         }
6431
6432         if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6433             (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6434                 centers->synth_center =
6435                         chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6436                 extoff = 1;
6437         } else {
6438                 centers->synth_center =
6439                         chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6440                 extoff = -1;
6441         }
6442
6443         centers->ctl_center = centers->synth_center - (extoff *
6444                 HT40_CHANNEL_CENTER_SHIFT);
6445         centers->ext_center = centers->synth_center + (extoff *
6446                 ((ahp->
6447                 ah_extprotspacing
6448                 ==
6449                 ATH9K_HT_EXTPROTSPACING_20)
6450                 ?
6451                 HT40_CHANNEL_CENTER_SHIFT
6452                 : 15));
6453
6454 }
6455
6456 void
6457 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6458                         bool *isCalDone)
6459 {
6460         struct ath_hal_5416 *ahp = AH5416(ah);
6461         struct ath9k_channel *ichan =
6462                 ath9k_regd_check_channel(ah, chan);
6463         struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6464
6465         *isCalDone = true;
6466
6467         if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6468                 return;
6469
6470         if (currCal == NULL)
6471                 return;
6472
6473         if (ichan == NULL) {
6474                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6475                          "%s: invalid channel %u/0x%x; no mapping\n",
6476                          __func__, chan->channel, chan->channelFlags);
6477                 return;
6478         }
6479
6480
6481         if (currCal->calState != CAL_DONE) {
6482                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6483                          "%s: Calibration state incorrect, %d\n",
6484                          __func__, currCal->calState);
6485                 return;
6486         }
6487
6488
6489         if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6490                 return;
6491
6492         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6493                  "%s: Resetting Cal %d state for channel %u/0x%x\n",
6494                  __func__, currCal->calData->calType, chan->channel,
6495                  chan->channelFlags);
6496
6497         ichan->CalValid &= ~currCal->calData->calType;
6498         currCal->calState = CAL_WAITING;
6499
6500         *isCalDone = false;
6501 }
6502
6503 void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6504 {
6505         struct ath_hal_5416 *ahp = AH5416(ah);
6506
6507         memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6508 }
6509
6510 bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6511 {
6512         struct ath_hal_5416 *ahp = AH5416(ah);
6513
6514         memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6515         return true;
6516 }
6517
6518 void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6519 {
6520         struct ath_hal_5416 *ahp = AH5416(ah);
6521
6522         memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6523 }
6524
6525 bool
6526 ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6527 {
6528         struct ath_hal_5416 *ahp = AH5416(ah);
6529
6530         memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6531
6532         REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6533         REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6534
6535         return true;
6536 }
6537
6538 #ifdef CONFIG_ATH9K_RFKILL
6539 static void ath9k_enable_rfkill(struct ath_hal *ah)
6540 {
6541         struct ath_hal_5416 *ahp = AH5416(ah);
6542
6543         REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6544                     AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6545
6546         REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6547                     AR_GPIO_INPUT_MUX2_RFSILENT);
6548
6549         ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6550         REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6551
6552         if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6553
6554                 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6555                                        !ahp->ah_gpioBit);
6556         } else {
6557                 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6558                                        ahp->ah_gpioBit);
6559         }
6560 }
6561 #endif
6562
6563 void
6564 ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6565                        u16 assocId)
6566 {
6567         struct ath_hal_5416 *ahp = AH5416(ah);
6568
6569         memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6570         ahp->ah_assocId = assocId;
6571
6572         REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6573         REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6574                   ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6575 }
6576
6577 u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6578 {
6579         u64 tsf;
6580
6581         tsf = REG_READ(ah, AR_TSF_U32);
6582         tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6583         return tsf;
6584 }
6585
6586 void ath9k_hw_reset_tsf(struct ath_hal *ah)
6587 {
6588         int count;
6589
6590         count = 0;
6591         while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6592                 count++;
6593                 if (count > 10) {
6594                         DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6595                          "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6596                                  __func__);
6597                         break;
6598                 }
6599                 udelay(10);
6600         }
6601         REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6602 }
6603
6604 u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6605 {
6606         return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6607 }
6608
6609 void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6610 {
6611         REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6612 }
6613
6614 bool
6615 ath9k_hw_setantennaswitch(struct ath_hal *ah,
6616                           enum ath9k_ant_setting settings,
6617                           struct ath9k_channel *chan,
6618                           u8 *tx_chainmask,
6619                           u8 *rx_chainmask,
6620                           u8 *antenna_cfgd)
6621 {
6622         struct ath_hal_5416 *ahp = AH5416(ah);
6623         static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6624
6625         if (AR_SREV_9280(ah)) {
6626                 if (!tx_chainmask_cfg) {
6627
6628                         tx_chainmask_cfg = *tx_chainmask;
6629                         rx_chainmask_cfg = *rx_chainmask;
6630                 }
6631
6632                 switch (settings) {
6633                 case ATH9K_ANT_FIXED_A:
6634                         *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6635                         *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6636                         *antenna_cfgd = true;
6637                         break;
6638                 case ATH9K_ANT_FIXED_B:
6639                         if (ah->ah_caps.tx_chainmask >
6640                             ATH9K_ANTENNA1_CHAINMASK) {
6641                                 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6642                         }
6643                         *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6644                         *antenna_cfgd = true;
6645                         break;
6646                 case ATH9K_ANT_VARIABLE:
6647                         *tx_chainmask = tx_chainmask_cfg;
6648                         *rx_chainmask = rx_chainmask_cfg;
6649                         *antenna_cfgd = true;
6650                         break;
6651                 default:
6652                         break;
6653                 }
6654         } else {
6655                 ahp->ah_diversityControl = settings;
6656         }
6657
6658         return true;
6659 }
6660
6661 void ath9k_hw_setopmode(struct ath_hal *ah)
6662 {
6663         ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6664 }
6665
6666 bool
6667 ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
6668                        u32 capability, u32 *result)
6669 {
6670         struct ath_hal_5416 *ahp = AH5416(ah);
6671         const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6672
6673         switch (type) {
6674         case ATH9K_CAP_CIPHER:
6675                 switch (capability) {
6676                 case ATH9K_CIPHER_AES_CCM:
6677                 case ATH9K_CIPHER_AES_OCB:
6678                 case ATH9K_CIPHER_TKIP:
6679                 case ATH9K_CIPHER_WEP:
6680                 case ATH9K_CIPHER_MIC:
6681                 case ATH9K_CIPHER_CLR:
6682                         return true;
6683                 default:
6684                         return false;
6685                 }
6686         case ATH9K_CAP_TKIP_MIC:
6687                 switch (capability) {
6688                 case 0:
6689                         return true;
6690                 case 1:
6691                         return (ahp->ah_staId1Defaults &
6692                                 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6693                         false;
6694                 }
6695         case ATH9K_CAP_TKIP_SPLIT:
6696                 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6697                         false : true;
6698         case ATH9K_CAP_WME_TKIPMIC:
6699                 return 0;
6700         case ATH9K_CAP_PHYCOUNTERS:
6701                 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6702         case ATH9K_CAP_DIVERSITY:
6703                 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6704                         AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6705                         true : false;
6706         case ATH9K_CAP_PHYDIAG:
6707                 return true;
6708         case ATH9K_CAP_MCAST_KEYSRCH:
6709                 switch (capability) {
6710                 case 0:
6711                         return true;
6712                 case 1:
6713                         if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6714                                 return false;
6715                         } else {
6716                                 return (ahp->ah_staId1Defaults &
6717                                         AR_STA_ID1_MCAST_KSRCH) ? true :
6718                                         false;
6719                         }
6720                 }
6721                 return false;
6722         case ATH9K_CAP_TSF_ADJUST:
6723                 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6724                         true : false;
6725         case ATH9K_CAP_RFSILENT:
6726                 if (capability == 3)
6727                         return false;
6728         case ATH9K_CAP_ANT_CFG_2GHZ:
6729                 *result = pCap->num_antcfg_2ghz;
6730                 return true;
6731         case ATH9K_CAP_ANT_CFG_5GHZ:
6732                 *result = pCap->num_antcfg_5ghz;
6733                 return true;
6734         case ATH9K_CAP_TXPOW:
6735                 switch (capability) {
6736                 case 0:
6737                         return 0;
6738                 case 1:
6739                         *result = ah->ah_powerLimit;
6740                         return 0;
6741                 case 2:
6742                         *result = ah->ah_maxPowerLevel;
6743                         return 0;
6744                 case 3:
6745                         *result = ah->ah_tpScale;
6746                         return 0;
6747                 }
6748                 return false;
6749         default:
6750                 return false;
6751         }
6752 }
6753
6754 int
6755 ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6756 {
6757         struct ath_hal_5416 *ahp = AH5416(ah);
6758         struct ath9k_channel *chan = ah->ah_curchan;
6759         const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6760         u16 ant_config;
6761         u32 halNumAntConfig;
6762
6763         halNumAntConfig =
6764                 IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
6765                 num_antcfg_5ghz;
6766
6767         if (cfg < halNumAntConfig) {
6768                 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6769                                                      cfg, &ant_config)) {
6770                         REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6771                         return 0;
6772                 }
6773         }
6774
6775         return -EINVAL;
6776 }
6777
6778 bool ath9k_hw_intrpend(struct ath_hal *ah)
6779 {
6780         u32 host_isr;
6781
6782         if (AR_SREV_9100(ah))
6783                 return true;
6784
6785         host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6786         if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6787                 return true;
6788
6789         host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6790         if ((host_isr & AR_INTR_SYNC_DEFAULT)
6791             && (host_isr != AR_INTR_SPURIOUS))
6792                 return true;
6793
6794         return false;
6795 }
6796
6797 bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6798 {
6799         u32 isr = 0;
6800         u32 mask2 = 0;
6801         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6802         u32 sync_cause = 0;
6803         bool fatal_int = false;
6804
6805         if (!AR_SREV_9100(ah)) {
6806                 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6807                         if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6808                             == AR_RTC_STATUS_ON) {
6809                                 isr = REG_READ(ah, AR_ISR);
6810                         }
6811                 }
6812
6813                 sync_cause =
6814                         REG_READ(ah,
6815                                  AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6816
6817                 *masked = 0;
6818
6819                 if (!isr && !sync_cause)
6820                         return false;
6821         } else {
6822                 *masked = 0;
6823                 isr = REG_READ(ah, AR_ISR);
6824         }
6825
6826         if (isr) {
6827                 struct ath_hal_5416 *ahp = AH5416(ah);
6828
6829                 if (isr & AR_ISR_BCNMISC) {
6830                         u32 isr2;
6831                         isr2 = REG_READ(ah, AR_ISR_S2);
6832                         if (isr2 & AR_ISR_S2_TIM)
6833                                 mask2 |= ATH9K_INT_TIM;
6834                         if (isr2 & AR_ISR_S2_DTIM)
6835                                 mask2 |= ATH9K_INT_DTIM;
6836                         if (isr2 & AR_ISR_S2_DTIMSYNC)
6837                                 mask2 |= ATH9K_INT_DTIMSYNC;
6838                         if (isr2 & (AR_ISR_S2_CABEND))
6839                                 mask2 |= ATH9K_INT_CABEND;
6840                         if (isr2 & AR_ISR_S2_GTT)
6841                                 mask2 |= ATH9K_INT_GTT;
6842                         if (isr2 & AR_ISR_S2_CST)
6843                                 mask2 |= ATH9K_INT_CST;
6844                 }
6845
6846                 isr = REG_READ(ah, AR_ISR_RAC);
6847                 if (isr == 0xffffffff) {
6848                         *masked = 0;
6849                         return false;
6850                 }
6851
6852                 *masked = isr & ATH9K_INT_COMMON;
6853
6854                 if (ahp->ah_intrMitigation) {
6855
6856                         if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6857                                 *masked |= ATH9K_INT_RX;
6858                 }
6859
6860                 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6861                         *masked |= ATH9K_INT_RX;
6862                 if (isr &
6863                     (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6864                      AR_ISR_TXEOL)) {
6865                         u32 s0_s, s1_s;
6866
6867                         *masked |= ATH9K_INT_TX;
6868
6869                         s0_s = REG_READ(ah, AR_ISR_S0_S);
6870                         ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6871                         ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6872
6873                         s1_s = REG_READ(ah, AR_ISR_S1_S);
6874                         ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6875                         ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6876                 }
6877
6878                 if (isr & AR_ISR_RXORN) {
6879                         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6880                                  "%s: receive FIFO overrun interrupt\n",
6881                                  __func__);
6882                 }
6883
6884                 if (!AR_SREV_9100(ah)) {
6885                         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
6886                                 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6887                                 if (isr5 & AR_ISR_S5_TIM_TIMER)
6888                                         *masked |= ATH9K_INT_TIM_TIMER;
6889                         }
6890                 }
6891
6892                 *masked |= mask2;
6893         }
6894         if (AR_SREV_9100(ah))
6895                 return true;
6896         if (sync_cause) {
6897                 fatal_int =
6898                         (sync_cause &
6899                          (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6900                         ? true : false;
6901
6902                 if (fatal_int) {
6903                         if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6904                                 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6905                                          "%s: received PCI FATAL interrupt\n",
6906                                          __func__);
6907                         }
6908                         if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6909                                 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6910                                          "%s: received PCI PERR interrupt\n",
6911                                          __func__);
6912                         }
6913                 }
6914                 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6915                         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6916                                  "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6917                                  __func__);
6918                         REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6919                         REG_WRITE(ah, AR_RC, 0);
6920                         *masked |= ATH9K_INT_FATAL;
6921                 }
6922                 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6923                         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6924                                  "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6925                                  __func__);
6926                 }
6927
6928                 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6929                 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6930         }
6931         return true;
6932 }
6933
6934 enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6935 {
6936         return AH5416(ah)->ah_maskReg;
6937 }
6938
6939 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6940 {
6941         struct ath_hal_5416 *ahp = AH5416(ah);
6942         u32 omask = ahp->ah_maskReg;
6943         u32 mask, mask2;
6944         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6945
6946         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6947                  omask, ints);
6948
6949         if (omask & ATH9K_INT_GLOBAL) {
6950                 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6951                          __func__);
6952                 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6953                 (void) REG_READ(ah, AR_IER);
6954                 if (!AR_SREV_9100(ah)) {
6955                         REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6956                         (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6957
6958                         REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6959                         (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6960                 }
6961         }
6962
6963         mask = ints & ATH9K_INT_COMMON;
6964         mask2 = 0;
6965
6966         if (ints & ATH9K_INT_TX) {
6967                 if (ahp->ah_txOkInterruptMask)
6968                         mask |= AR_IMR_TXOK;
6969                 if (ahp->ah_txDescInterruptMask)
6970                         mask |= AR_IMR_TXDESC;
6971                 if (ahp->ah_txErrInterruptMask)
6972                         mask |= AR_IMR_TXERR;
6973                 if (ahp->ah_txEolInterruptMask)
6974                         mask |= AR_IMR_TXEOL;
6975         }
6976         if (ints & ATH9K_INT_RX) {
6977                 mask |= AR_IMR_RXERR;
6978                 if (ahp->ah_intrMitigation)
6979                         mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6980                 else
6981                         mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6982                 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
6983                         mask |= AR_IMR_GENTMR;
6984         }
6985
6986         if (ints & (ATH9K_INT_BMISC)) {
6987                 mask |= AR_IMR_BCNMISC;
6988                 if (ints & ATH9K_INT_TIM)
6989                         mask2 |= AR_IMR_S2_TIM;
6990                 if (ints & ATH9K_INT_DTIM)
6991                         mask2 |= AR_IMR_S2_DTIM;
6992                 if (ints & ATH9K_INT_DTIMSYNC)
6993                         mask2 |= AR_IMR_S2_DTIMSYNC;
6994                 if (ints & ATH9K_INT_CABEND)
6995                         mask2 |= (AR_IMR_S2_CABEND);
6996         }
6997
6998         if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
6999                 mask |= AR_IMR_BCNMISC;
7000                 if (ints & ATH9K_INT_GTT)
7001                         mask2 |= AR_IMR_S2_GTT;
7002                 if (ints & ATH9K_INT_CST)
7003                         mask2 |= AR_IMR_S2_CST;
7004         }
7005
7006         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
7007                  mask);
7008         REG_WRITE(ah, AR_IMR, mask);
7009         mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
7010                                            AR_IMR_S2_DTIM |
7011                                            AR_IMR_S2_DTIMSYNC |
7012                                            AR_IMR_S2_CABEND |
7013                                            AR_IMR_S2_CABTO |
7014                                            AR_IMR_S2_TSFOOR |
7015                                            AR_IMR_S2_GTT | AR_IMR_S2_CST);
7016         REG_WRITE(ah, AR_IMR_S2, mask | mask2);
7017         ahp->ah_maskReg = ints;
7018
7019         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
7020                 if (ints & ATH9K_INT_TIM_TIMER)
7021                         REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7022                 else
7023                         REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7024         }
7025
7026         if (ints & ATH9K_INT_GLOBAL) {
7027                 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7028                          __func__);
7029                 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7030                 if (!AR_SREV_9100(ah)) {
7031                         REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7032                                   AR_INTR_MAC_IRQ);
7033                         REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7034
7035
7036                         REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7037                                   AR_INTR_SYNC_DEFAULT);
7038                         REG_WRITE(ah, AR_INTR_SYNC_MASK,
7039                                   AR_INTR_SYNC_DEFAULT);
7040                 }
7041                 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7042                          REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7043         }
7044
7045         return omask;
7046 }
7047
7048 void
7049 ath9k_hw_beaconinit(struct ath_hal *ah,
7050                     u32 next_beacon, u32 beacon_period)
7051 {
7052         struct ath_hal_5416 *ahp = AH5416(ah);
7053         int flags = 0;
7054
7055         ahp->ah_beaconInterval = beacon_period;
7056
7057         switch (ah->ah_opmode) {
7058         case ATH9K_M_STA:
7059         case ATH9K_M_MONITOR:
7060                 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7061                 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7062                 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7063                 flags |= AR_TBTT_TIMER_EN;
7064                 break;
7065         case ATH9K_M_IBSS:
7066                 REG_SET_BIT(ah, AR_TXCFG,
7067                             AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7068                 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7069                           TU_TO_USEC(next_beacon +
7070                                      (ahp->ah_atimWindow ? ahp->
7071                                       ah_atimWindow : 1)));
7072                 flags |= AR_NDP_TIMER_EN;
7073         case ATH9K_M_HOSTAP:
7074                 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7075                 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7076                           TU_TO_USEC(next_beacon -
7077                                      ah->ah_config.
7078                                      dma_beacon_response_time));
7079                 REG_WRITE(ah, AR_NEXT_SWBA,
7080                           TU_TO_USEC(next_beacon -
7081                                      ah->ah_config.
7082                                      sw_beacon_response_time));
7083                 flags |=
7084                         AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7085                 break;
7086         }
7087
7088         REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7089         REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7090         REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7091         REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7092
7093         beacon_period &= ~ATH9K_BEACON_ENA;
7094         if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7095                 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7096                 ath9k_hw_reset_tsf(ah);
7097         }
7098
7099         REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7100 }
7101
7102 void
7103 ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7104                                const struct ath9k_beacon_state *bs)
7105 {
7106         u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7107         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7108
7109         REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7110
7111         REG_WRITE(ah, AR_BEACON_PERIOD,
7112                   TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7113         REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7114                   TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7115
7116         REG_RMW_FIELD(ah, AR_RSSI_THR,
7117                       AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7118
7119         beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7120
7121         if (bs->bs_sleepduration > beaconintval)
7122                 beaconintval = bs->bs_sleepduration;
7123
7124         dtimperiod = bs->bs_dtimperiod;
7125         if (bs->bs_sleepduration > dtimperiod)
7126                 dtimperiod = bs->bs_sleepduration;
7127
7128         if (beaconintval == dtimperiod)
7129                 nextTbtt = bs->bs_nextdtim;
7130         else
7131                 nextTbtt = bs->bs_nexttbtt;
7132
7133         DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7134                  bs->bs_nextdtim);
7135         DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7136                  nextTbtt);
7137         DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7138                  beaconintval);
7139         DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7140                  dtimperiod);
7141
7142         REG_WRITE(ah, AR_NEXT_DTIM,
7143                   TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7144         REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7145
7146         REG_WRITE(ah, AR_SLEEP1,
7147                   SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7148                   | AR_SLEEP1_ASSUME_DTIM);
7149
7150         if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
7151                 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7152         else
7153                 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7154
7155         REG_WRITE(ah, AR_SLEEP2,
7156                   SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7157
7158         REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7159         REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7160
7161         REG_SET_BIT(ah, AR_TIMER_MODE,
7162                     AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7163                     AR_DTIM_TIMER_EN);
7164
7165 }
7166
7167 bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7168 {
7169         if (entry < ah->ah_caps.keycache_size) {
7170                 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7171                 if (val & AR_KEYTABLE_VALID)
7172                         return true;
7173         }
7174         return false;
7175 }
7176
7177 bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7178 {
7179         u32 keyType;
7180
7181         if (entry >= ah->ah_caps.keycache_size) {
7182                 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7183                          "%s: entry %u out of range\n", __func__, entry);
7184                 return false;
7185         }
7186         keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7187
7188         REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7189         REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7190         REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7191         REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7192         REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7193         REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7194         REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7195         REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7196
7197         if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7198                 u16 micentry = entry + 64;
7199
7200                 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7201                 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7202                 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7203                 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7204
7205         }
7206
7207         if (ah->ah_curchan == NULL)
7208                 return true;
7209
7210         return true;
7211 }
7212
7213 bool
7214 ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7215                    const u8 *mac)
7216 {
7217         u32 macHi, macLo;
7218
7219         if (entry >= ah->ah_caps.keycache_size) {
7220                 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7221                          "%s: entry %u out of range\n", __func__, entry);
7222                 return false;
7223         }
7224
7225         if (mac != NULL) {
7226                 macHi = (mac[5] << 8) | mac[4];
7227                 macLo = (mac[3] << 24) | (mac[2] << 16)
7228                         | (mac[1] << 8) | mac[0];
7229                 macLo >>= 1;
7230                 macLo |= (macHi & 1) << 31;
7231                 macHi >>= 1;
7232         } else {
7233                 macLo = macHi = 0;
7234         }
7235         REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7236         REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7237
7238         return true;
7239 }
7240
7241 bool
7242 ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7243                             const struct ath9k_keyval *k,
7244                             const u8 *mac, int xorKey)
7245 {
7246         const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7247         u32 key0, key1, key2, key3, key4;
7248         u32 keyType;
7249         u32 xorMask = xorKey ?
7250                 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7251                  | ATH9K_KEY_XOR) : 0;
7252         struct ath_hal_5416 *ahp = AH5416(ah);
7253
7254         if (entry >= pCap->keycache_size) {
7255                 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7256                          "%s: entry %u out of range\n", __func__, entry);
7257                 return false;
7258         }
7259         switch (k->kv_type) {
7260         case ATH9K_CIPHER_AES_OCB:
7261                 keyType = AR_KEYTABLE_TYPE_AES;
7262                 break;
7263         case ATH9K_CIPHER_AES_CCM:
7264                 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
7265                         DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7266                                  "%s: AES-CCM not supported by "
7267                                  "mac rev 0x%x\n", __func__,
7268                                  ah->ah_macRev);
7269                         return false;
7270                 }
7271                 keyType = AR_KEYTABLE_TYPE_CCM;
7272                 break;
7273         case ATH9K_CIPHER_TKIP:
7274                 keyType = AR_KEYTABLE_TYPE_TKIP;
7275                 if (ATH9K_IS_MIC_ENABLED(ah)
7276                     && entry + 64 >= pCap->keycache_size) {
7277                         DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7278                                  "%s: entry %u inappropriate for TKIP\n",
7279                                  __func__, entry);
7280                         return false;
7281                 }
7282                 break;
7283         case ATH9K_CIPHER_WEP:
7284                 if (k->kv_len < 40 / NBBY) {
7285                         DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7286                                  "%s: WEP key length %u too small\n",
7287                                  __func__, k->kv_len);
7288                         return false;
7289                 }
7290                 if (k->kv_len <= 40 / NBBY)
7291                         keyType = AR_KEYTABLE_TYPE_40;
7292                 else if (k->kv_len <= 104 / NBBY)
7293                         keyType = AR_KEYTABLE_TYPE_104;
7294                 else
7295                         keyType = AR_KEYTABLE_TYPE_128;
7296                 break;
7297         case ATH9K_CIPHER_CLR:
7298                 keyType = AR_KEYTABLE_TYPE_CLR;
7299                 break;
7300         default:
7301                 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7302                          "%s: cipher %u not supported\n", __func__,
7303                          k->kv_type);
7304                 return false;
7305         }
7306
7307         key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7308         key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7309         key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7310         key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7311         key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7312         if (k->kv_len <= 104 / NBBY)
7313                 key4 &= 0xff;
7314
7315         if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7316                 u16 micentry = entry + 64;
7317
7318                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7319                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7320                 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7321                 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7322                 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7323                 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7324                 (void) ath9k_hw_keysetmac(ah, entry, mac);
7325
7326                 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7327                         u32 mic0, mic1, mic2, mic3, mic4;
7328
7329                         mic0 = get_unaligned_le32(k->kv_mic + 0);
7330                         mic2 = get_unaligned_le32(k->kv_mic + 4);
7331                         mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7332                         mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7333                         mic4 = get_unaligned_le32(k->kv_txmic + 4);
7334                         REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7335                         REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7336                         REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7337                         REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7338                         REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7339                         REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7340                                   AR_KEYTABLE_TYPE_CLR);
7341
7342                 } else {
7343                         u32 mic0, mic2;
7344
7345                         mic0 = get_unaligned_le32(k->kv_mic + 0);
7346                         mic2 = get_unaligned_le32(k->kv_mic + 4);
7347                         REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7348                         REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7349                         REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7350                         REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7351                         REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7352                         REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7353                                   AR_KEYTABLE_TYPE_CLR);
7354                 }
7355                 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7356                 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7357                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7358                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7359         } else {
7360                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7361                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7362                 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7363                 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7364                 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7365                 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7366
7367                 (void) ath9k_hw_keysetmac(ah, entry, mac);
7368         }
7369
7370         if (ah->ah_curchan == NULL)
7371                 return true;
7372
7373         return true;
7374 }
7375
7376 bool
7377 ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7378 {
7379         struct ath_hal_5416 *ahp = AH5416(ah);
7380         u32 txcfg, curLevel, newLevel;
7381         enum ath9k_int omask;
7382
7383         if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7384                 return false;
7385
7386         omask = ath9k_hw_set_interrupts(ah,
7387                                         ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7388
7389         txcfg = REG_READ(ah, AR_TXCFG);
7390         curLevel = MS(txcfg, AR_FTRIG);
7391         newLevel = curLevel;
7392         if (bIncTrigLevel) {
7393                 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7394                         newLevel++;
7395         } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7396                 newLevel--;
7397         if (newLevel != curLevel)
7398                 REG_WRITE(ah, AR_TXCFG,
7399                           (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7400
7401         ath9k_hw_set_interrupts(ah, omask);
7402
7403         ah->ah_txTrigLevel = newLevel;
7404
7405         return newLevel != curLevel;
7406 }
7407
7408 bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
7409                             const struct ath9k_tx_queue_info *qinfo)
7410 {
7411         u32 cw;
7412         struct ath_hal_5416 *ahp = AH5416(ah);
7413         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7414         struct ath9k_tx_queue_info *qi;
7415
7416         if (q >= pCap->total_queues) {
7417                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7418                          __func__, q);
7419                 return false;
7420         }
7421
7422         qi = &ahp->ah_txq[q];
7423         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7424                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7425                          __func__);
7426                 return false;
7427         }
7428
7429         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7430
7431         qi->tqi_ver = qinfo->tqi_ver;
7432         qi->tqi_subtype = qinfo->tqi_subtype;
7433         qi->tqi_qflags = qinfo->tqi_qflags;
7434         qi->tqi_priority = qinfo->tqi_priority;
7435         if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7436                 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
7437         else
7438                 qi->tqi_aifs = INIT_AIFS;
7439         if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7440                 cw = min(qinfo->tqi_cwmin, 1024U);
7441                 qi->tqi_cwmin = 1;
7442                 while (qi->tqi_cwmin < cw)
7443                         qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7444         } else
7445                 qi->tqi_cwmin = qinfo->tqi_cwmin;
7446         if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7447                 cw = min(qinfo->tqi_cwmax, 1024U);
7448                 qi->tqi_cwmax = 1;
7449                 while (qi->tqi_cwmax < cw)
7450                         qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7451         } else
7452                 qi->tqi_cwmax = INIT_CWMAX;
7453
7454         if (qinfo->tqi_shretry != 0)
7455                 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
7456         else
7457                 qi->tqi_shretry = INIT_SH_RETRY;
7458         if (qinfo->tqi_lgretry != 0)
7459                 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
7460         else
7461                 qi->tqi_lgretry = INIT_LG_RETRY;
7462         qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
7463         qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
7464         qi->tqi_burstTime = qinfo->tqi_burstTime;
7465         qi->tqi_readyTime = qinfo->tqi_readyTime;
7466
7467         switch (qinfo->tqi_subtype) {
7468         case ATH9K_WME_UPSD:
7469                 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7470                         qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7471                 break;
7472         default:
7473                 break;
7474         }
7475         return true;
7476 }
7477
7478 bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
7479                             struct ath9k_tx_queue_info *qinfo)
7480 {
7481         struct ath_hal_5416 *ahp = AH5416(ah);
7482         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7483         struct ath9k_tx_queue_info *qi;
7484
7485         if (q >= pCap->total_queues) {
7486                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7487                          __func__, q);
7488                 return false;
7489         }
7490
7491         qi = &ahp->ah_txq[q];
7492         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7493                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7494                          __func__);
7495                 return false;
7496         }
7497
7498         qinfo->tqi_qflags = qi->tqi_qflags;
7499         qinfo->tqi_ver = qi->tqi_ver;
7500         qinfo->tqi_subtype = qi->tqi_subtype;
7501         qinfo->tqi_qflags = qi->tqi_qflags;
7502         qinfo->tqi_priority = qi->tqi_priority;
7503         qinfo->tqi_aifs = qi->tqi_aifs;
7504         qinfo->tqi_cwmin = qi->tqi_cwmin;
7505         qinfo->tqi_cwmax = qi->tqi_cwmax;
7506         qinfo->tqi_shretry = qi->tqi_shretry;
7507         qinfo->tqi_lgretry = qi->tqi_lgretry;
7508         qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7509         qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7510         qinfo->tqi_burstTime = qi->tqi_burstTime;
7511         qinfo->tqi_readyTime = qi->tqi_readyTime;
7512
7513         return true;
7514 }
7515
7516 int
7517 ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7518                       const struct ath9k_tx_queue_info *qinfo)
7519 {
7520         struct ath_hal_5416 *ahp = AH5416(ah);
7521         struct ath9k_tx_queue_info *qi;
7522         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7523         int q;
7524
7525         switch (type) {
7526         case ATH9K_TX_QUEUE_BEACON:
7527                 q = pCap->total_queues - 1;
7528                 break;
7529         case ATH9K_TX_QUEUE_CAB:
7530                 q = pCap->total_queues - 2;
7531                 break;
7532         case ATH9K_TX_QUEUE_PSPOLL:
7533                 q = 1;
7534                 break;
7535         case ATH9K_TX_QUEUE_UAPSD:
7536                 q = pCap->total_queues - 3;
7537                 break;
7538         case ATH9K_TX_QUEUE_DATA:
7539                 for (q = 0; q < pCap->total_queues; q++)
7540                         if (ahp->ah_txq[q].tqi_type ==
7541                             ATH9K_TX_QUEUE_INACTIVE)
7542                                 break;
7543                 if (q == pCap->total_queues) {
7544                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7545                                  "%s: no available tx queue\n", __func__);
7546                         return -1;
7547                 }
7548                 break;
7549         default:
7550                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7551                          __func__, type);
7552                 return -1;
7553         }
7554
7555         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7556
7557         qi = &ahp->ah_txq[q];
7558         if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7559                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7560                          "%s: tx queue %u already active\n", __func__, q);
7561                 return -1;
7562         }
7563         memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7564         qi->tqi_type = type;
7565         if (qinfo == NULL) {
7566                 qi->tqi_qflags =
7567                         TXQ_FLAG_TXOKINT_ENABLE
7568                         | TXQ_FLAG_TXERRINT_ENABLE
7569                         | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7570                 qi->tqi_aifs = INIT_AIFS;
7571                 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7572                 qi->tqi_cwmax = INIT_CWMAX;
7573                 qi->tqi_shretry = INIT_SH_RETRY;
7574                 qi->tqi_lgretry = INIT_LG_RETRY;
7575                 qi->tqi_physCompBuf = 0;
7576         } else {
7577                 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
7578                 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
7579         }
7580
7581         return q;
7582 }
7583
7584 static void
7585 ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7586                             struct ath9k_tx_queue_info *qi)
7587 {
7588         struct ath_hal_5416 *ahp = AH5416(ah);
7589
7590         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7591                  "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7592                  __func__, ahp->ah_txOkInterruptMask,
7593                  ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7594                  ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7595
7596         REG_WRITE(ah, AR_IMR_S0,
7597                   SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7598                   | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7599         REG_WRITE(ah, AR_IMR_S1,
7600                   SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7601                   | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7602         REG_RMW_FIELD(ah, AR_IMR_S2,
7603                       AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7604 }
7605
7606 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7607 {
7608         struct ath_hal_5416 *ahp = AH5416(ah);
7609         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7610         struct ath9k_tx_queue_info *qi;
7611
7612         if (q >= pCap->total_queues) {
7613                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7614                          __func__, q);
7615                 return false;
7616         }
7617         qi = &ahp->ah_txq[q];
7618         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7619                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7620                          __func__, q);
7621                 return false;
7622         }
7623
7624         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7625                 __func__, q);
7626
7627         qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7628         ahp->ah_txOkInterruptMask &= ~(1 << q);
7629         ahp->ah_txErrInterruptMask &= ~(1 << q);
7630         ahp->ah_txDescInterruptMask &= ~(1 << q);
7631         ahp->ah_txEolInterruptMask &= ~(1 << q);
7632         ahp->ah_txUrnInterruptMask &= ~(1 << q);
7633         ath9k_hw_set_txq_interrupts(ah, qi);
7634
7635         return true;
7636 }
7637
7638 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7639 {
7640         struct ath_hal_5416 *ahp = AH5416(ah);
7641         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7642         struct ath9k_channel *chan = ah->ah_curchan;
7643         struct ath9k_tx_queue_info *qi;
7644         u32 cwMin, chanCwMin, value;
7645
7646         if (q >= pCap->total_queues) {
7647                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7648                          __func__, q);
7649                 return false;
7650         }
7651         qi = &ahp->ah_txq[q];
7652         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7653                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7654                          __func__, q);
7655                 return true;
7656         }
7657
7658         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7659
7660         if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7661                 if (chan && IS_CHAN_B(chan))
7662                         chanCwMin = INIT_CWMIN_11B;
7663                 else
7664                         chanCwMin = INIT_CWMIN;
7665
7666                 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7667         } else
7668                 cwMin = qi->tqi_cwmin;
7669
7670         REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7671                   | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7672                   | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7673
7674         REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7675                   SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7676                   | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7677                   | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7678                 );
7679
7680         REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7681         REG_WRITE(ah, AR_DMISC(q),
7682                   AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7683
7684         if (qi->tqi_cbrPeriod) {
7685                 REG_WRITE(ah, AR_QCBRCFG(q),
7686                           SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7687                           | SM(qi->tqi_cbrOverflowLimit,
7688                                AR_Q_CBRCFG_OVF_THRESH));
7689                 REG_WRITE(ah, AR_QMISC(q),
7690                           REG_READ(ah,
7691                                    AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7692                                         tqi_cbrOverflowLimit
7693                                         ?
7694                                         AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7695                                         :
7696                                         0));
7697         }
7698         if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7699                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7700                           SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7701                           AR_Q_RDYTIMECFG_EN);
7702         }
7703
7704         REG_WRITE(ah, AR_DCHNTIME(q),
7705                   SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7706                   (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7707
7708         if (qi->tqi_burstTime
7709             && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7710                 REG_WRITE(ah, AR_QMISC(q),
7711                           REG_READ(ah,
7712                                    AR_QMISC(q)) |
7713                           AR_Q_MISC_RDYTIME_EXP_POLICY);
7714
7715         }
7716
7717         if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7718                 REG_WRITE(ah, AR_DMISC(q),
7719                           REG_READ(ah, AR_DMISC(q)) |
7720                           AR_D_MISC_POST_FR_BKOFF_DIS);
7721         }
7722         if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7723                 REG_WRITE(ah, AR_DMISC(q),
7724                           REG_READ(ah, AR_DMISC(q)) |
7725                           AR_D_MISC_FRAG_BKOFF_EN);
7726         }
7727         switch (qi->tqi_type) {
7728         case ATH9K_TX_QUEUE_BEACON:
7729                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7730                           | AR_Q_MISC_FSP_DBA_GATED
7731                           | AR_Q_MISC_BEACON_USE
7732                           | AR_Q_MISC_CBR_INCR_DIS1);
7733
7734                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7735                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7736                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7737                           | AR_D_MISC_BEACON_USE
7738                           | AR_D_MISC_POST_FR_BKOFF_DIS);
7739                 break;
7740         case ATH9K_TX_QUEUE_CAB:
7741                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7742                           | AR_Q_MISC_FSP_DBA_GATED
7743                           | AR_Q_MISC_CBR_INCR_DIS1
7744                           | AR_Q_MISC_CBR_INCR_DIS0);
7745                 value = (qi->tqi_readyTime
7746                          - (ah->ah_config.sw_beacon_response_time -
7747                             ah->ah_config.dma_beacon_response_time)
7748                          -
7749                          ah->ah_config.additional_swba_backoff) *
7750                         1024;
7751                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7752                           value | AR_Q_RDYTIMECFG_EN);
7753                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7754                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7755                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7756                 break;
7757         case ATH9K_TX_QUEUE_PSPOLL:
7758                 REG_WRITE(ah, AR_QMISC(q),
7759                           REG_READ(ah,
7760                                    AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7761                 break;
7762         case ATH9K_TX_QUEUE_UAPSD:
7763                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7764                           | AR_D_MISC_POST_FR_BKOFF_DIS);
7765                 break;
7766         default:
7767                 break;
7768         }
7769
7770         if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7771                 REG_WRITE(ah, AR_DMISC(q),
7772                           REG_READ(ah, AR_DMISC(q)) |
7773                           SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7774                              AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7775                           AR_D_MISC_POST_FR_BKOFF_DIS);
7776         }
7777
7778         if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7779                 ahp->ah_txOkInterruptMask |= 1 << q;
7780         else
7781                 ahp->ah_txOkInterruptMask &= ~(1 << q);
7782         if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7783                 ahp->ah_txErrInterruptMask |= 1 << q;
7784         else
7785                 ahp->ah_txErrInterruptMask &= ~(1 << q);
7786         if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7787                 ahp->ah_txDescInterruptMask |= 1 << q;
7788         else
7789                 ahp->ah_txDescInterruptMask &= ~(1 << q);
7790         if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7791                 ahp->ah_txEolInterruptMask |= 1 << q;
7792         else
7793                 ahp->ah_txEolInterruptMask &= ~(1 << q);
7794         if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7795                 ahp->ah_txUrnInterruptMask |= 1 << q;
7796         else
7797                 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7798         ath9k_hw_set_txq_interrupts(ah, qi);
7799
7800         return true;
7801 }
7802
7803 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7804 {
7805         struct ath_hal_5416 *ahp = AH5416(ah);
7806         *txqs &= ahp->ah_intrTxqs;
7807         ahp->ah_intrTxqs &= ~(*txqs);
7808 }
7809
7810 bool
7811 ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7812                     u32 segLen, bool firstSeg,
7813                     bool lastSeg, const struct ath_desc *ds0)
7814 {
7815         struct ar5416_desc *ads = AR5416DESC(ds);
7816
7817         if (firstSeg) {
7818                 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7819         } else if (lastSeg) {
7820                 ads->ds_ctl0 = 0;
7821                 ads->ds_ctl1 = segLen;
7822                 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7823                 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7824         } else {
7825                 ads->ds_ctl0 = 0;
7826                 ads->ds_ctl1 = segLen | AR_TxMore;
7827                 ads->ds_ctl2 = 0;
7828                 ads->ds_ctl3 = 0;
7829         }
7830         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7831         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7832         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7833         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7834         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7835         return true;
7836 }
7837
7838 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7839 {
7840         struct ar5416_desc *ads = AR5416DESC(ds);
7841
7842         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7843         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7844         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7845         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7846         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7847 }
7848
7849 int
7850 ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7851 {
7852         struct ar5416_desc *ads = AR5416DESC(ds);
7853
7854         if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7855                 return -EINPROGRESS;
7856
7857         ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7858         ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7859         ds->ds_txstat.ts_status = 0;
7860         ds->ds_txstat.ts_flags = 0;
7861
7862         if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7863                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7864         if (ads->ds_txstatus1 & AR_Filtered)
7865                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7866         if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7867                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7868         if (ads->ds_txstatus9 & AR_TxOpExceeded)
7869                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7870         if (ads->ds_txstatus1 & AR_TxTimerExpired)
7871                 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7872
7873         if (ads->ds_txstatus1 & AR_DescCfgErr)
7874                 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7875         if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7876                 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7877                 ath9k_hw_updatetxtriglevel(ah, true);
7878         }
7879         if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7880                 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7881                 ath9k_hw_updatetxtriglevel(ah, true);
7882         }
7883         if (ads->ds_txstatus0 & AR_TxBaStatus) {
7884                 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7885                 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7886                 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7887         }
7888
7889         ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7890         switch (ds->ds_txstat.ts_rateindex) {
7891         case 0:
7892                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7893                 break;
7894         case 1:
7895                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7896                 break;
7897         case 2:
7898                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7899                 break;
7900         case 3:
7901                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7902                 break;
7903         }
7904
7905         ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7906         ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7907         ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7908         ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7909         ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7910         ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7911         ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7912         ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7913         ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7914         ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7915         ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7916         ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7917         ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7918         ds->ds_txstat.ts_antenna = 1;
7919
7920         return 0;
7921 }
7922
7923 void
7924 ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7925                        u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7926                        u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7927 {
7928         struct ar5416_desc *ads = AR5416DESC(ds);
7929         struct ath_hal_5416 *ahp = AH5416(ah);
7930
7931         txPower += ahp->ah_txPowerIndexOffset;
7932         if (txPower > 63)
7933                 txPower = 63;
7934
7935         ads->ds_ctl0 = (pktLen & AR_FrameLen)
7936                 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7937                 | SM(txPower, AR_XmitPower)
7938                 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7939                 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7940                 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7941                 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7942
7943         ads->ds_ctl1 =
7944                 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7945                 | SM(type, AR_FrameType)
7946                 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7947                 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7948                 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7949
7950         ads->ds_ctl6 = SM(keyType, AR_EncrType);
7951
7952         if (AR_SREV_9285(ah)) {
7953
7954                 ads->ds_ctl8 = 0;
7955                 ads->ds_ctl9 = 0;
7956                 ads->ds_ctl10 = 0;
7957                 ads->ds_ctl11 = 0;
7958         }
7959 }
7960
7961 void
7962 ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7963                              struct ath_desc *lastds,
7964                              u32 durUpdateEn, u32 rtsctsRate,
7965                              u32 rtsctsDuration,
7966                              struct ath9k_11n_rate_series series[],
7967                              u32 nseries, u32 flags)
7968 {
7969         struct ar5416_desc *ads = AR5416DESC(ds);
7970         struct ar5416_desc *last_ads = AR5416DESC(lastds);
7971         u32 ds_ctl0;
7972
7973         (void) nseries;
7974         (void) rtsctsDuration;
7975
7976         if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7977                 ds_ctl0 = ads->ds_ctl0;
7978
7979                 if (flags & ATH9K_TXDESC_RTSENA) {
7980                         ds_ctl0 &= ~AR_CTSEnable;
7981                         ds_ctl0 |= AR_RTSEnable;
7982                 } else {
7983                         ds_ctl0 &= ~AR_RTSEnable;
7984                         ds_ctl0 |= AR_CTSEnable;
7985                 }
7986
7987                 ads->ds_ctl0 = ds_ctl0;
7988         } else {
7989                 ads->ds_ctl0 =
7990                         (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7991         }
7992
7993         ads->ds_ctl2 = set11nTries(series, 0)
7994                 | set11nTries(series, 1)
7995                 | set11nTries(series, 2)
7996                 | set11nTries(series, 3)
7997                 | (durUpdateEn ? AR_DurUpdateEna : 0)
7998                 | SM(0, AR_BurstDur);
7999
8000         ads->ds_ctl3 = set11nRate(series, 0)
8001                 | set11nRate(series, 1)
8002                 | set11nRate(series, 2)
8003                 | set11nRate(series, 3);
8004
8005         ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
8006                 | set11nPktDurRTSCTS(series, 1);
8007
8008         ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8009                 | set11nPktDurRTSCTS(series, 3);
8010
8011         ads->ds_ctl7 = set11nRateFlags(series, 0)
8012                 | set11nRateFlags(series, 1)
8013                 | set11nRateFlags(series, 2)
8014                 | set11nRateFlags(series, 3)
8015                 | SM(rtsctsRate, AR_RTSCTSRate);
8016         last_ads->ds_ctl2 = ads->ds_ctl2;
8017         last_ads->ds_ctl3 = ads->ds_ctl3;
8018 }
8019
8020 void
8021 ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8022                            u32 aggrLen)
8023 {
8024         struct ar5416_desc *ads = AR5416DESC(ds);
8025
8026         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8027
8028         ads->ds_ctl6 &= ~AR_AggrLen;
8029         ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8030 }
8031
8032 void
8033 ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8034                             u32 numDelims)
8035 {
8036         struct ar5416_desc *ads = AR5416DESC(ds);
8037         unsigned int ctl6;
8038
8039         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8040
8041         ctl6 = ads->ds_ctl6;
8042         ctl6 &= ~AR_PadDelim;
8043         ctl6 |= SM(numDelims, AR_PadDelim);
8044         ads->ds_ctl6 = ctl6;
8045 }
8046
8047 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8048 {
8049         struct ar5416_desc *ads = AR5416DESC(ds);
8050
8051         ads->ds_ctl1 |= AR_IsAggr;
8052         ads->ds_ctl1 &= ~AR_MoreAggr;
8053         ads->ds_ctl6 &= ~AR_PadDelim;
8054 }
8055
8056 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8057 {
8058         struct ar5416_desc *ads = AR5416DESC(ds);
8059
8060         ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8061 }
8062
8063 void
8064 ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8065                               u32 burstDuration)
8066 {
8067         struct ar5416_desc *ads = AR5416DESC(ds);
8068
8069         ads->ds_ctl2 &= ~AR_BurstDur;
8070         ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8071 }
8072
8073 void
8074 ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8075                                 u32 vmf)
8076 {
8077         struct ar5416_desc *ads = AR5416DESC(ds);
8078
8079         if (vmf)
8080                 ads->ds_ctl0 |= AR_VirtMoreFrag;
8081         else
8082                 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8083 }
8084
8085 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8086 {
8087         REG_WRITE(ah, AR_RXDP, rxdp);
8088 }
8089
8090 void ath9k_hw_rxena(struct ath_hal *ah)
8091 {
8092         REG_WRITE(ah, AR_CR, AR_CR_RXE);
8093 }
8094
8095 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8096 {
8097         if (set) {
8098
8099                 REG_SET_BIT(ah, AR_DIAG_SW,
8100                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8101
8102                 if (!ath9k_hw_wait
8103                     (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8104                         u32 reg;
8105
8106                         REG_CLR_BIT(ah, AR_DIAG_SW,
8107                                     (AR_DIAG_RX_DIS |
8108                                      AR_DIAG_RX_ABORT));
8109
8110                         reg = REG_READ(ah, AR_OBS_BUS_1);
8111                         DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8112                                 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8113                                 __func__, reg);
8114
8115                         return false;
8116                 }
8117         } else {
8118                 REG_CLR_BIT(ah, AR_DIAG_SW,
8119                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8120         }
8121
8122         return true;
8123 }
8124
8125 void
8126 ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8127                         u32 filter1)
8128 {
8129         REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8130         REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8131 }
8132
8133 bool
8134 ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8135                      u32 size, u32 flags)
8136 {
8137         struct ar5416_desc *ads = AR5416DESC(ds);
8138         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
8139
8140         ads->ds_ctl1 = size & AR_BufLen;
8141         if (flags & ATH9K_RXDESC_INTREQ)
8142                 ads->ds_ctl1 |= AR_RxIntrReq;
8143
8144         ads->ds_rxstatus8 &= ~AR_RxDone;
8145         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
8146                 memset(&(ads->u), 0, sizeof(ads->u));
8147         return true;
8148 }
8149
8150 int
8151 ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8152                     u32 pa, struct ath_desc *nds, u64 tsf)
8153 {
8154         struct ar5416_desc ads;
8155         struct ar5416_desc *adsp = AR5416DESC(ds);
8156
8157         if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8158                 return -EINPROGRESS;
8159
8160         ads.u.rx = adsp->u.rx;
8161
8162         ds->ds_rxstat.rs_status = 0;
8163         ds->ds_rxstat.rs_flags = 0;
8164
8165         ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8166         ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8167
8168         ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8169         ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8170         ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8171         ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8172         ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8173         ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8174         ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8175         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8176                 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8177         else
8178                 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8179
8180         ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8181         ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8182
8183         ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8184         ds->ds_rxstat.rs_moreaggr =
8185                 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8186         ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8187         ds->ds_rxstat.rs_flags =
8188                 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8189         ds->ds_rxstat.rs_flags |=
8190                 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8191
8192         if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8193                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8194         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8195                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8196         if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8197                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8198
8199         if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8200
8201                 if (ads.ds_rxstatus8 & AR_CRCErr)
8202                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8203                 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8204                         u32 phyerr;
8205
8206                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8207                         phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8208                         ds->ds_rxstat.rs_phyerr = phyerr;
8209                 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8210                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8211                 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8212                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8213         }
8214
8215         return 0;
8216 }
8217
8218 static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8219                                       struct ath9k_rate_table *rt)
8220 {
8221         int i;
8222
8223         if (rt->rateCodeToIndex[0] != 0)
8224                 return;
8225         for (i = 0; i < 256; i++)
8226                 rt->rateCodeToIndex[i] = (u8) -1;
8227         for (i = 0; i < rt->rateCount; i++) {
8228                 u8 code = rt->info[i].rateCode;
8229                 u8 cix = rt->info[i].controlRate;
8230
8231                 rt->rateCodeToIndex[code] = i;
8232                 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8233
8234                 rt->info[i].lpAckDuration =
8235                         ath9k_hw_computetxtime(ah, rt,
8236                                                WLAN_CTRL_FRAME_SIZE,
8237                                                cix,
8238                                                false);
8239                 rt->info[i].spAckDuration =
8240                         ath9k_hw_computetxtime(ah, rt,
8241                                                WLAN_CTRL_FRAME_SIZE,
8242                                                cix,
8243                                                true);
8244         }
8245 }
8246
8247 const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8248                                                    u32 mode)
8249 {
8250         struct ath9k_rate_table *rt;
8251         switch (mode) {
8252         case ATH9K_MODE_11A:
8253                 rt = &ar5416_11a_table;
8254                 break;
8255         case ATH9K_MODE_11B:
8256                 rt = &ar5416_11b_table;
8257                 break;
8258         case ATH9K_MODE_11G:
8259                 rt = &ar5416_11g_table;
8260                 break;
8261         case ATH9K_MODE_11NG_HT20:
8262         case ATH9K_MODE_11NG_HT40PLUS:
8263         case ATH9K_MODE_11NG_HT40MINUS:
8264                 rt = &ar5416_11ng_table;
8265                 break;
8266         case ATH9K_MODE_11NA_HT20:
8267         case ATH9K_MODE_11NA_HT40PLUS:
8268         case ATH9K_MODE_11NA_HT40MINUS:
8269                 rt = &ar5416_11na_table;
8270                 break;
8271         default:
8272                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8273                          __func__, mode);
8274                 return NULL;
8275         }
8276         ath9k_hw_setup_rate_table(ah, rt);
8277         return rt;
8278 }
8279
8280 static const char *ath9k_hw_devname(u16 devid)
8281 {
8282         switch (devid) {
8283         case AR5416_DEVID_PCI:
8284         case AR5416_DEVID_PCIE:
8285                 return "Atheros 5416";
8286         case AR9160_DEVID_PCI:
8287                 return "Atheros 9160";
8288         case AR9280_DEVID_PCI:
8289         case AR9280_DEVID_PCIE:
8290                 return "Atheros 9280";
8291         }
8292         return NULL;
8293 }
8294
8295 const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8296 {
8297         return vendorid == ATHEROS_VENDOR_ID ?
8298                 ath9k_hw_devname(devid) : NULL;
8299 }
8300
8301 struct ath_hal *ath9k_hw_attach(u16 devid,
8302                                 struct ath_softc *sc,
8303                                 void __iomem *mem,
8304                                 int *error)
8305 {
8306         struct ath_hal *ah = NULL;
8307
8308         switch (devid) {
8309         case AR5416_DEVID_PCI:
8310         case AR5416_DEVID_PCIE:
8311         case AR9160_DEVID_PCI:
8312         case AR9280_DEVID_PCI:
8313         case AR9280_DEVID_PCIE:
8314                 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8315                 break;
8316         default:
8317                 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8318                          "devid=0x%x not supported.\n", devid);
8319                 ah = NULL;
8320                 *error = -ENXIO;
8321                 break;
8322         }
8323         if (ah != NULL) {
8324                 ah->ah_devid = ah->ah_devid;
8325                 ah->ah_subvendorid = ah->ah_subvendorid;
8326                 ah->ah_macVersion = ah->ah_macVersion;
8327                 ah->ah_macRev = ah->ah_macRev;
8328                 ah->ah_phyRev = ah->ah_phyRev;
8329                 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8330                 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8331         }
8332         return ah;
8333 }
8334
8335 u16
8336 ath9k_hw_computetxtime(struct ath_hal *ah,
8337                        const struct ath9k_rate_table *rates,
8338                        u32 frameLen, u16 rateix,
8339                        bool shortPreamble)
8340 {
8341         u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8342         u32 kbps;
8343
8344         kbps = rates->info[rateix].rateKbps;
8345
8346         if (kbps == 0)
8347                 return 0;
8348         switch (rates->info[rateix].phy) {
8349
8350         case PHY_CCK:
8351                 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8352                 if (shortPreamble && rates->info[rateix].shortPreamble)
8353                         phyTime >>= 1;
8354                 numBits = frameLen << 3;
8355                 txTime = CCK_SIFS_TIME + phyTime
8356                         + ((numBits * 1000) / kbps);
8357                 break;
8358         case PHY_OFDM:
8359                 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8360                         bitsPerSymbol =
8361                                 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8362
8363                         numBits = OFDM_PLCP_BITS + (frameLen << 3);
8364                         numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8365                         txTime = OFDM_SIFS_TIME_QUARTER
8366                                 + OFDM_PREAMBLE_TIME_QUARTER
8367                                 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8368                 } else if (ah->ah_curchan &&
8369                            IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8370                         bitsPerSymbol =
8371                                 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8372
8373                         numBits = OFDM_PLCP_BITS + (frameLen << 3);
8374                         numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8375                         txTime = OFDM_SIFS_TIME_HALF +
8376                                 OFDM_PREAMBLE_TIME_HALF
8377                                 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8378                 } else {
8379                         bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8380
8381                         numBits = OFDM_PLCP_BITS + (frameLen << 3);
8382                         numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8383                         txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8384                                 + (numSymbols * OFDM_SYMBOL_TIME);
8385                 }
8386                 break;
8387
8388         default:
8389                 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8390                          "%s: unknown phy %u (rate ix %u)\n", __func__,
8391                          rates->info[rateix].phy, rateix);
8392                 txTime = 0;
8393                 break;
8394         }
8395         return txTime;
8396 }
8397
8398 u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8399 {
8400         if (flags & CHANNEL_2GHZ) {
8401                 if (freq == 2484)
8402                         return 14;
8403                 if (freq < 2484)
8404                         return (freq - 2407) / 5;
8405                 else
8406                         return 15 + ((freq - 2512) / 20);
8407         } else if (flags & CHANNEL_5GHZ) {
8408                 if (ath9k_regd_is_public_safety_sku(ah) &&
8409                     IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8410                         return ((freq * 10) +
8411                                 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8412                 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8413                         return (freq - 4000) / 5;
8414                 } else {
8415                         return (freq - 5000) / 5;
8416                 }
8417         } else {
8418                 if (freq == 2484)
8419                         return 14;
8420                 if (freq < 2484)
8421                         return (freq - 2407) / 5;
8422                 if (freq < 5000) {
8423                         if (ath9k_regd_is_public_safety_sku(ah)
8424                             && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8425                                 return ((freq * 10) +
8426                                         (((freq % 5) ==
8427                                           2) ? 5 : 0) - 49400) / 5;
8428                         } else if (freq > 4900) {
8429                                 return (freq - 4000) / 5;
8430                         } else {
8431                                 return 15 + ((freq - 2512) / 20);
8432                         }
8433                 }
8434                 return (freq - 5000) / 5;
8435         }
8436 }
8437
8438 int16_t
8439 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8440 {
8441         struct ath9k_channel *ichan;
8442
8443         ichan = ath9k_regd_check_channel(ah, chan);
8444         if (ichan == NULL) {
8445                 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8446                          "%s: invalid channel %u/0x%x; no mapping\n",
8447                          __func__, chan->channel, chan->channelFlags);
8448                 return 0;
8449         }
8450         if (ichan->rawNoiseFloor == 0) {
8451                 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8452                 return NOISE_FLOOR[mode];
8453         } else
8454                 return ichan->rawNoiseFloor;
8455 }
8456
8457 bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8458 {
8459         struct ath_hal_5416 *ahp = AH5416(ah);
8460
8461         if (setting)
8462                 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8463         else
8464                 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8465         return true;
8466 }
8467
8468 bool ath9k_hw_phycounters(struct ath_hal *ah)
8469 {
8470         struct ath_hal_5416 *ahp = AH5416(ah);
8471
8472         return ahp->ah_hasHwPhyCounters ? true : false;
8473 }
8474
8475 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8476 {
8477         return REG_READ(ah, AR_QTXDP(q));
8478 }
8479
8480 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8481                        u32 txdp)
8482 {
8483         REG_WRITE(ah, AR_QTXDP(q), txdp);
8484
8485         return true;
8486 }
8487
8488 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8489 {
8490         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8491
8492         REG_WRITE(ah, AR_Q_TXE, 1 << q);
8493
8494         return true;
8495 }
8496
8497 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8498 {
8499         u32 npend;
8500
8501         npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8502         if (npend == 0) {
8503
8504                 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8505                         npend = 1;
8506         }
8507         return npend;
8508 }
8509
8510 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8511 {
8512         u32 wait;
8513
8514         REG_WRITE(ah, AR_Q_TXD, 1 << q);
8515
8516         for (wait = 1000; wait != 0; wait--) {
8517                 if (ath9k_hw_numtxpending(ah, q) == 0)
8518                         break;
8519                 udelay(100);
8520         }
8521
8522         if (ath9k_hw_numtxpending(ah, q)) {
8523                 u32 tsfLow, j;
8524
8525                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8526                          "%s: Num of pending TX Frames %d on Q %d\n",
8527                          __func__, ath9k_hw_numtxpending(ah, q), q);
8528
8529                 for (j = 0; j < 2; j++) {
8530                         tsfLow = REG_READ(ah, AR_TSF_L32);
8531                         REG_WRITE(ah, AR_QUIET2,
8532                                   SM(10, AR_QUIET2_QUIET_DUR));
8533                         REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8534                         REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8535                         REG_SET_BIT(ah, AR_TIMER_MODE,
8536                                        AR_QUIET_TIMER_EN);
8537
8538                         if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8539                             (tsfLow >> 10)) {
8540                                 break;
8541                         }
8542                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8543                                 "%s: TSF have moved while trying to set "
8544                                 "quiet time TSF: 0x%08x\n",
8545                                 __func__, tsfLow);
8546                 }
8547
8548                 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8549
8550                 udelay(200);
8551                 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8552
8553                 wait = 1000;
8554
8555                 while (ath9k_hw_numtxpending(ah, q)) {
8556                         if ((--wait) == 0) {
8557                                 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8558                                         "%s: Failed to stop Tx DMA in 100 "
8559                                         "msec after killing last frame\n",
8560                                         __func__);
8561                                 break;
8562                         }
8563                         udelay(100);
8564                 }
8565
8566                 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8567         }
8568
8569         REG_WRITE(ah, AR_Q_TXD, 0);
8570         return wait != 0;
8571 }