Merge git://git.kernel.org/pub/scm/linux/kernel/git/steve/gfs2-2.6-nmw
[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
5021                         /* workaround for gcc bug #37014 */
5022                         volatile int tmp = abs(cur_vit_mask - bin);
5023
5024                         if (tmp < 75)
5025                                 mask_amt = 1;
5026                         else
5027                                 mask_amt = 0;
5028                         if (cur_vit_mask < 0)
5029                                 mask_m[abs(cur_vit_mask / 100)] = mask_amt;
5030                         else
5031                                 mask_p[cur_vit_mask / 100] = mask_amt;
5032                 }
5033                 cur_vit_mask -= 100;
5034         }
5035
5036         tmp_mask = (mask_m[46] << 30) | (mask_m[47] << 28)
5037                 | (mask_m[48] << 26) | (mask_m[49] << 24)
5038                 | (mask_m[50] << 22) | (mask_m[51] << 20)
5039                 | (mask_m[52] << 18) | (mask_m[53] << 16)
5040                 | (mask_m[54] << 14) | (mask_m[55] << 12)
5041                 | (mask_m[56] << 10) | (mask_m[57] << 8)
5042                 | (mask_m[58] << 6) | (mask_m[59] << 4)
5043                 | (mask_m[60] << 2) | (mask_m[61] << 0);
5044         REG_WRITE(ah, AR_PHY_BIN_MASK_1, tmp_mask);
5045         REG_WRITE(ah, AR_PHY_VIT_MASK2_M_46_61, tmp_mask);
5046
5047         tmp_mask = (mask_m[31] << 28)
5048                 | (mask_m[32] << 26) | (mask_m[33] << 24)
5049                 | (mask_m[34] << 22) | (mask_m[35] << 20)
5050                 | (mask_m[36] << 18) | (mask_m[37] << 16)
5051                 | (mask_m[48] << 14) | (mask_m[39] << 12)
5052                 | (mask_m[40] << 10) | (mask_m[41] << 8)
5053                 | (mask_m[42] << 6) | (mask_m[43] << 4)
5054                 | (mask_m[44] << 2) | (mask_m[45] << 0);
5055         REG_WRITE(ah, AR_PHY_BIN_MASK_2, tmp_mask);
5056         REG_WRITE(ah, AR_PHY_MASK2_M_31_45, tmp_mask);
5057
5058         tmp_mask = (mask_m[16] << 30) | (mask_m[16] << 28)
5059                 | (mask_m[18] << 26) | (mask_m[18] << 24)
5060                 | (mask_m[20] << 22) | (mask_m[20] << 20)
5061                 | (mask_m[22] << 18) | (mask_m[22] << 16)
5062                 | (mask_m[24] << 14) | (mask_m[24] << 12)
5063                 | (mask_m[25] << 10) | (mask_m[26] << 8)
5064                 | (mask_m[27] << 6) | (mask_m[28] << 4)
5065                 | (mask_m[29] << 2) | (mask_m[30] << 0);
5066         REG_WRITE(ah, AR_PHY_BIN_MASK_3, tmp_mask);
5067         REG_WRITE(ah, AR_PHY_MASK2_M_16_30, tmp_mask);
5068
5069         tmp_mask = (mask_m[0] << 30) | (mask_m[1] << 28)
5070                 | (mask_m[2] << 26) | (mask_m[3] << 24)
5071                 | (mask_m[4] << 22) | (mask_m[5] << 20)
5072                 | (mask_m[6] << 18) | (mask_m[7] << 16)
5073                 | (mask_m[8] << 14) | (mask_m[9] << 12)
5074                 | (mask_m[10] << 10) | (mask_m[11] << 8)
5075                 | (mask_m[12] << 6) | (mask_m[13] << 4)
5076                 | (mask_m[14] << 2) | (mask_m[15] << 0);
5077         REG_WRITE(ah, AR_PHY_MASK_CTL, tmp_mask);
5078         REG_WRITE(ah, AR_PHY_MASK2_M_00_15, tmp_mask);
5079
5080         tmp_mask = (mask_p[15] << 28)
5081                 | (mask_p[14] << 26) | (mask_p[13] << 24)
5082                 | (mask_p[12] << 22) | (mask_p[11] << 20)
5083                 | (mask_p[10] << 18) | (mask_p[9] << 16)
5084                 | (mask_p[8] << 14) | (mask_p[7] << 12)
5085                 | (mask_p[6] << 10) | (mask_p[5] << 8)
5086                 | (mask_p[4] << 6) | (mask_p[3] << 4)
5087                 | (mask_p[2] << 2) | (mask_p[1] << 0);
5088         REG_WRITE(ah, AR_PHY_BIN_MASK2_1, tmp_mask);
5089         REG_WRITE(ah, AR_PHY_MASK2_P_15_01, tmp_mask);
5090
5091         tmp_mask = (mask_p[30] << 28)
5092                 | (mask_p[29] << 26) | (mask_p[28] << 24)
5093                 | (mask_p[27] << 22) | (mask_p[26] << 20)
5094                 | (mask_p[25] << 18) | (mask_p[24] << 16)
5095                 | (mask_p[23] << 14) | (mask_p[22] << 12)
5096                 | (mask_p[21] << 10) | (mask_p[20] << 8)
5097                 | (mask_p[19] << 6) | (mask_p[18] << 4)
5098                 | (mask_p[17] << 2) | (mask_p[16] << 0);
5099         REG_WRITE(ah, AR_PHY_BIN_MASK2_2, tmp_mask);
5100         REG_WRITE(ah, AR_PHY_MASK2_P_30_16, tmp_mask);
5101
5102         tmp_mask = (mask_p[45] << 28)
5103                 | (mask_p[44] << 26) | (mask_p[43] << 24)
5104                 | (mask_p[42] << 22) | (mask_p[41] << 20)
5105                 | (mask_p[40] << 18) | (mask_p[39] << 16)
5106                 | (mask_p[38] << 14) | (mask_p[37] << 12)
5107                 | (mask_p[36] << 10) | (mask_p[35] << 8)
5108                 | (mask_p[34] << 6) | (mask_p[33] << 4)
5109                 | (mask_p[32] << 2) | (mask_p[31] << 0);
5110         REG_WRITE(ah, AR_PHY_BIN_MASK2_3, tmp_mask);
5111         REG_WRITE(ah, AR_PHY_MASK2_P_45_31, tmp_mask);
5112
5113         tmp_mask = (mask_p[61] << 30) | (mask_p[60] << 28)
5114                 | (mask_p[59] << 26) | (mask_p[58] << 24)
5115                 | (mask_p[57] << 22) | (mask_p[56] << 20)
5116                 | (mask_p[55] << 18) | (mask_p[54] << 16)
5117                 | (mask_p[53] << 14) | (mask_p[52] << 12)
5118                 | (mask_p[51] << 10) | (mask_p[50] << 8)
5119                 | (mask_p[49] << 6) | (mask_p[48] << 4)
5120                 | (mask_p[47] << 2) | (mask_p[46] << 0);
5121         REG_WRITE(ah, AR_PHY_BIN_MASK2_4, tmp_mask);
5122         REG_WRITE(ah, AR_PHY_MASK2_P_61_45, tmp_mask);
5123 }
5124
5125 static inline void ath9k_hw_init_chain_masks(struct ath_hal *ah)
5126 {
5127         struct ath_hal_5416 *ahp = AH5416(ah);
5128         int rx_chainmask, tx_chainmask;
5129
5130         rx_chainmask = ahp->ah_rxchainmask;
5131         tx_chainmask = ahp->ah_txchainmask;
5132
5133         switch (rx_chainmask) {
5134         case 0x5:
5135                 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5136                             AR_PHY_SWAP_ALT_CHAIN);
5137         case 0x3:
5138                 if (((ah)->ah_macVersion <= AR_SREV_VERSION_9160)) {
5139                         REG_WRITE(ah, AR_PHY_RX_CHAINMASK, 0x7);
5140                         REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, 0x7);
5141                         break;
5142                 }
5143         case 0x1:
5144         case 0x2:
5145                 if (!AR_SREV_9280(ah))
5146                         break;
5147         case 0x7:
5148                 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
5149                 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
5150                 break;
5151         default:
5152                 break;
5153         }
5154
5155         REG_WRITE(ah, AR_SELFGEN_MASK, tx_chainmask);
5156         if (tx_chainmask == 0x5) {
5157                 REG_SET_BIT(ah, AR_PHY_ANALOG_SWAP,
5158                             AR_PHY_SWAP_ALT_CHAIN);
5159         }
5160         if (AR_SREV_9100(ah))
5161                 REG_WRITE(ah, AR_PHY_ANALOG_SWAP,
5162                           REG_READ(ah, AR_PHY_ANALOG_SWAP) | 0x00000001);
5163 }
5164
5165 static void ath9k_hw_set_addac(struct ath_hal *ah,
5166                                struct ath9k_channel *chan)
5167 {
5168         struct modal_eep_header *pModal;
5169         struct ath_hal_5416 *ahp = AH5416(ah);
5170         struct ar5416_eeprom *eep = &ahp->ah_eeprom;
5171         u8 biaslevel;
5172
5173         if (ah->ah_macVersion != AR_SREV_VERSION_9160)
5174                 return;
5175
5176         if (ar5416_get_eep_rev(ahp) < AR5416_EEP_MINOR_VER_7)
5177                 return;
5178
5179         pModal = &(eep->modalHeader[IS_CHAN_2GHZ(chan)]);
5180
5181         if (pModal->xpaBiasLvl != 0xff) {
5182                 biaslevel = pModal->xpaBiasLvl;
5183         } else {
5184
5185                 u16 resetFreqBin, freqBin, freqCount = 0;
5186                 struct chan_centers centers;
5187
5188                 ath9k_hw_get_channel_centers(ah, chan, &centers);
5189
5190                 resetFreqBin =
5191                         FREQ2FBIN(centers.synth_center, IS_CHAN_2GHZ(chan));
5192                 freqBin = pModal->xpaBiasLvlFreq[0] & 0xff;
5193                 biaslevel = (u8) (pModal->xpaBiasLvlFreq[0] >> 14);
5194
5195                 freqCount++;
5196
5197                 while (freqCount < 3) {
5198                         if (pModal->xpaBiasLvlFreq[freqCount] == 0x0)
5199                                 break;
5200
5201                         freqBin = pModal->xpaBiasLvlFreq[freqCount] & 0xff;
5202                         if (resetFreqBin >= freqBin) {
5203                                 biaslevel =
5204                                         (u8) (pModal->
5205                                                     xpaBiasLvlFreq[freqCount]
5206                                                     >> 14);
5207                         } else {
5208                                 break;
5209                         }
5210                         freqCount++;
5211                 }
5212         }
5213
5214         if (IS_CHAN_2GHZ(chan)) {
5215                 INI_RA(&ahp->ah_iniAddac, 7, 1) =
5216                         (INI_RA(&ahp->ah_iniAddac, 7, 1) & (~0x18)) | biaslevel
5217                         << 3;
5218         } else {
5219                 INI_RA(&ahp->ah_iniAddac, 6, 1) =
5220                         (INI_RA(&ahp->ah_iniAddac, 6, 1) & (~0xc0)) | biaslevel
5221                         << 6;
5222         }
5223 }
5224
5225 static u32 ath9k_hw_mac_usec(struct ath_hal *ah, u32 clks)
5226 {
5227         if (ah->ah_curchan != NULL)
5228                 return clks /
5229                 CLOCK_RATE[ath9k_hw_chan2wmode(ah, ah->ah_curchan)];
5230         else
5231                 return clks / CLOCK_RATE[ATH9K_MODE_11B];
5232 }
5233
5234 static u32 ath9k_hw_mac_to_usec(struct ath_hal *ah, u32 clks)
5235 {
5236         struct ath9k_channel *chan = ah->ah_curchan;
5237
5238         if (chan && IS_CHAN_HT40(chan))
5239                 return ath9k_hw_mac_usec(ah, clks) / 2;
5240         else
5241                 return ath9k_hw_mac_usec(ah, clks);
5242 }
5243
5244 static u32 ath9k_hw_mac_clks(struct ath_hal *ah, u32 usecs)
5245 {
5246         if (ah->ah_curchan != NULL)
5247                 return usecs * CLOCK_RATE[ath9k_hw_chan2wmode(ah,
5248                         ah->ah_curchan)];
5249         else
5250                 return usecs * CLOCK_RATE[ATH9K_MODE_11B];
5251 }
5252
5253 static u32 ath9k_hw_mac_to_clks(struct ath_hal *ah, u32 usecs)
5254 {
5255         struct ath9k_channel *chan = ah->ah_curchan;
5256
5257         if (chan && IS_CHAN_HT40(chan))
5258                 return ath9k_hw_mac_clks(ah, usecs) * 2;
5259         else
5260                 return ath9k_hw_mac_clks(ah, usecs);
5261 }
5262
5263 static bool ath9k_hw_set_ack_timeout(struct ath_hal *ah, u32 us)
5264 {
5265         struct ath_hal_5416 *ahp = AH5416(ah);
5266
5267         if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
5268                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad ack timeout %u\n",
5269                          __func__, us);
5270                 ahp->ah_acktimeout = (u32) -1;
5271                 return false;
5272         } else {
5273                 REG_RMW_FIELD(ah, AR_TIME_OUT,
5274                               AR_TIME_OUT_ACK, ath9k_hw_mac_to_clks(ah, us));
5275                 ahp->ah_acktimeout = us;
5276                 return true;
5277         }
5278 }
5279
5280 static bool ath9k_hw_set_cts_timeout(struct ath_hal *ah, u32 us)
5281 {
5282         struct ath_hal_5416 *ahp = AH5416(ah);
5283
5284         if (us > ath9k_hw_mac_to_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
5285                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad cts timeout %u\n",
5286                          __func__, us);
5287                 ahp->ah_ctstimeout = (u32) -1;
5288                 return false;
5289         } else {
5290                 REG_RMW_FIELD(ah, AR_TIME_OUT,
5291                               AR_TIME_OUT_CTS, ath9k_hw_mac_to_clks(ah, us));
5292                 ahp->ah_ctstimeout = us;
5293                 return true;
5294         }
5295 }
5296 static bool ath9k_hw_set_global_txtimeout(struct ath_hal *ah,
5297                                           u32 tu)
5298 {
5299         struct ath_hal_5416 *ahp = AH5416(ah);
5300
5301         if (tu > 0xFFFF) {
5302                 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
5303                         "%s: bad global tx timeout %u\n", __func__, tu);
5304                 ahp->ah_globaltxtimeout = (u32) -1;
5305                 return false;
5306         } else {
5307                 REG_RMW_FIELD(ah, AR_GTXTO, AR_GTXTO_TIMEOUT_LIMIT, tu);
5308                 ahp->ah_globaltxtimeout = tu;
5309                 return true;
5310         }
5311 }
5312
5313 bool ath9k_hw_setslottime(struct ath_hal *ah, u32 us)
5314 {
5315         struct ath_hal_5416 *ahp = AH5416(ah);
5316
5317         if (us < ATH9K_SLOT_TIME_9 || us > ath9k_hw_mac_to_usec(ah, 0xffff)) {
5318                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: bad slot time %u\n",
5319                          __func__, us);
5320                 ahp->ah_slottime = (u32) -1;
5321                 return false;
5322         } else {
5323                 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath9k_hw_mac_to_clks(ah, us));
5324                 ahp->ah_slottime = us;
5325                 return true;
5326         }
5327 }
5328
5329 static inline void ath9k_hw_init_user_settings(struct ath_hal *ah)
5330 {
5331         struct ath_hal_5416 *ahp = AH5416(ah);
5332
5333         DPRINTF(ah->ah_sc, ATH_DBG_RESET, "--AP %s ahp->ah_miscMode 0x%x\n",
5334                  __func__, ahp->ah_miscMode);
5335         if (ahp->ah_miscMode != 0)
5336                 REG_WRITE(ah, AR_PCU_MISC,
5337                           REG_READ(ah, AR_PCU_MISC) | ahp->ah_miscMode);
5338         if (ahp->ah_slottime != (u32) -1)
5339                 ath9k_hw_setslottime(ah, ahp->ah_slottime);
5340         if (ahp->ah_acktimeout != (u32) -1)
5341                 ath9k_hw_set_ack_timeout(ah, ahp->ah_acktimeout);
5342         if (ahp->ah_ctstimeout != (u32) -1)
5343                 ath9k_hw_set_cts_timeout(ah, ahp->ah_ctstimeout);
5344         if (ahp->ah_globaltxtimeout != (u32) -1)
5345                 ath9k_hw_set_global_txtimeout(ah, ahp->ah_globaltxtimeout);
5346 }
5347
5348 static inline int
5349 ath9k_hw_process_ini(struct ath_hal *ah,
5350                      struct ath9k_channel *chan,
5351                      enum ath9k_ht_macmode macmode)
5352 {
5353         int i, regWrites = 0;
5354         struct ath_hal_5416 *ahp = AH5416(ah);
5355         u32 modesIndex, freqIndex;
5356         int status;
5357
5358         switch (chan->chanmode) {
5359         case CHANNEL_A:
5360         case CHANNEL_A_HT20:
5361                 modesIndex = 1;
5362                 freqIndex = 1;
5363                 break;
5364         case CHANNEL_A_HT40PLUS:
5365         case CHANNEL_A_HT40MINUS:
5366                 modesIndex = 2;
5367                 freqIndex = 1;
5368                 break;
5369         case CHANNEL_G:
5370         case CHANNEL_G_HT20:
5371         case CHANNEL_B:
5372                 modesIndex = 4;
5373                 freqIndex = 2;
5374                 break;
5375         case CHANNEL_G_HT40PLUS:
5376         case CHANNEL_G_HT40MINUS:
5377                 modesIndex = 3;
5378                 freqIndex = 2;
5379                 break;
5380
5381         default:
5382                 return -EINVAL;
5383         }
5384
5385         REG_WRITE(ah, AR_PHY(0), 0x00000007);
5386
5387         REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_EXTERNAL_RADIO);
5388
5389         ath9k_hw_set_addac(ah, chan);
5390
5391         if (AR_SREV_5416_V22_OR_LATER(ah)) {
5392                 REG_WRITE_ARRAY(&ahp->ah_iniAddac, 1, regWrites);
5393         } else {
5394                 struct ar5416IniArray temp;
5395                 u32 addacSize =
5396                         sizeof(u32) * ahp->ah_iniAddac.ia_rows *
5397                         ahp->ah_iniAddac.ia_columns;
5398
5399                 memcpy(ahp->ah_addac5416_21,
5400                        ahp->ah_iniAddac.ia_array, addacSize);
5401
5402                 (ahp->ah_addac5416_21)[31 *
5403                                        ahp->ah_iniAddac.ia_columns + 1] = 0;
5404
5405                 temp.ia_array = ahp->ah_addac5416_21;
5406                 temp.ia_columns = ahp->ah_iniAddac.ia_columns;
5407                 temp.ia_rows = ahp->ah_iniAddac.ia_rows;
5408                 REG_WRITE_ARRAY(&temp, 1, regWrites);
5409         }
5410         REG_WRITE(ah, AR_PHY_ADC_SERIAL_CTL, AR_PHY_SEL_INTERNAL_ADDAC);
5411
5412         for (i = 0; i < ahp->ah_iniModes.ia_rows; i++) {
5413                 u32 reg = INI_RA(&ahp->ah_iniModes, i, 0);
5414                 u32 val = INI_RA(&ahp->ah_iniModes, i, modesIndex);
5415
5416 #ifdef CONFIG_SLOW_ANT_DIV
5417                 if (ah->ah_devid == AR9280_DEVID_PCI)
5418                         val = ath9k_hw_ini_fixup(ah, &ahp->ah_eeprom, reg,
5419                                                  val);
5420 #endif
5421
5422                 REG_WRITE(ah, reg, val);
5423
5424                 if (reg >= 0x7800 && reg < 0x78a0
5425                     && ah->ah_config.analog_shiftreg) {
5426                         udelay(100);
5427                 }
5428
5429                 DO_DELAY(regWrites);
5430         }
5431
5432         for (i = 0; i < ahp->ah_iniCommon.ia_rows; i++) {
5433                 u32 reg = INI_RA(&ahp->ah_iniCommon, i, 0);
5434                 u32 val = INI_RA(&ahp->ah_iniCommon, i, 1);
5435
5436                 REG_WRITE(ah, reg, val);
5437
5438                 if (reg >= 0x7800 && reg < 0x78a0
5439                     && ah->ah_config.analog_shiftreg) {
5440                         udelay(100);
5441                 }
5442
5443                 DO_DELAY(regWrites);
5444         }
5445
5446         ath9k_hw_write_regs(ah, modesIndex, freqIndex, regWrites);
5447
5448         if (AR_SREV_9280_20(ah) && IS_CHAN_A_5MHZ_SPACED(chan)) {
5449                 REG_WRITE_ARRAY(&ahp->ah_iniModesAdditional, modesIndex,
5450                                 regWrites);
5451         }
5452
5453         ath9k_hw_override_ini(ah, chan);
5454         ath9k_hw_set_regs(ah, chan, macmode);
5455         ath9k_hw_init_chain_masks(ah);
5456
5457         status = ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5458                                       ath9k_regd_get_ctl(ah, chan),
5459                                       ath9k_regd_get_antenna_allowed(ah,
5460                                                                      chan),
5461                                       chan->maxRegTxPower * 2,
5462                                       min((u32) MAX_RATE_POWER,
5463                                           (u32) ah->ah_powerLimit));
5464         if (status != 0) {
5465                 DPRINTF(ah->ah_sc, ATH_DBG_POWER_MGMT,
5466                          "%s: error init'ing transmit power\n", __func__);
5467                 return -EIO;
5468         }
5469
5470         if (!ath9k_hw_set_rf_regs(ah, chan, freqIndex)) {
5471                 DPRINTF(ah->ah_sc, ATH_DBG_REG_IO,
5472                          "%s: ar5416SetRfRegs failed\n", __func__);
5473                 return -EIO;
5474         }
5475
5476         return 0;
5477 }
5478
5479 static inline void ath9k_hw_setup_calibration(struct ath_hal *ah,
5480                                               struct hal_cal_list *currCal)
5481 {
5482         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(0),
5483                       AR_PHY_TIMING_CTRL4_IQCAL_LOG_COUNT_MAX,
5484                       currCal->calData->calCountMax);
5485
5486         switch (currCal->calData->calType) {
5487         case IQ_MISMATCH_CAL:
5488                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_IQ);
5489                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5490                          "%s: starting IQ Mismatch Calibration\n",
5491                          __func__);
5492                 break;
5493         case ADC_GAIN_CAL:
5494                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_GAIN);
5495                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5496                          "%s: starting ADC Gain Calibration\n", __func__);
5497                 break;
5498         case ADC_DC_CAL:
5499                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_PER);
5500                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5501                          "%s: starting ADC DC Calibration\n", __func__);
5502                 break;
5503         case ADC_DC_INIT_CAL:
5504                 REG_WRITE(ah, AR_PHY_CALMODE, AR_PHY_CALMODE_ADC_DC_INIT);
5505                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5506                          "%s: starting Init ADC DC Calibration\n",
5507                          __func__);
5508                 break;
5509         }
5510
5511         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
5512                     AR_PHY_TIMING_CTRL4_DO_CAL);
5513 }
5514
5515 static inline void ath9k_hw_reset_calibration(struct ath_hal *ah,
5516                                               struct hal_cal_list *currCal)
5517 {
5518         struct ath_hal_5416 *ahp = AH5416(ah);
5519         int i;
5520
5521         ath9k_hw_setup_calibration(ah, currCal);
5522
5523         currCal->calState = CAL_RUNNING;
5524
5525         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5526                 ahp->ah_Meas0.sign[i] = 0;
5527                 ahp->ah_Meas1.sign[i] = 0;
5528                 ahp->ah_Meas2.sign[i] = 0;
5529                 ahp->ah_Meas3.sign[i] = 0;
5530         }
5531
5532         ahp->ah_CalSamples = 0;
5533 }
5534
5535 static inline void
5536 ath9k_hw_per_calibration(struct ath_hal *ah,
5537                          struct ath9k_channel *ichan,
5538                          u8 rxchainmask,
5539                          struct hal_cal_list *currCal,
5540                          bool *isCalDone)
5541 {
5542         struct ath_hal_5416 *ahp = AH5416(ah);
5543
5544         *isCalDone = false;
5545
5546         if (currCal->calState == CAL_RUNNING) {
5547                 if (!(REG_READ(ah,
5548                                AR_PHY_TIMING_CTRL4(0)) &
5549                       AR_PHY_TIMING_CTRL4_DO_CAL)) {
5550
5551                         currCal->calData->calCollect(ah);
5552
5553                         ahp->ah_CalSamples++;
5554
5555                         if (ahp->ah_CalSamples >=
5556                             currCal->calData->calNumSamples) {
5557                                 int i, numChains = 0;
5558                                 for (i = 0; i < AR5416_MAX_CHAINS; i++) {
5559                                         if (rxchainmask & (1 << i))
5560                                                 numChains++;
5561                                 }
5562
5563                                 currCal->calData->calPostProc(ah,
5564                                                               numChains);
5565
5566                                 ichan->CalValid |=
5567                                         currCal->calData->calType;
5568                                 currCal->calState = CAL_DONE;
5569                                 *isCalDone = true;
5570                         } else {
5571                                 ath9k_hw_setup_calibration(ah, currCal);
5572                         }
5573                 }
5574         } else if (!(ichan->CalValid & currCal->calData->calType)) {
5575                 ath9k_hw_reset_calibration(ah, currCal);
5576         }
5577 }
5578
5579 static inline bool ath9k_hw_run_init_cals(struct ath_hal *ah,
5580                                           int init_cal_count)
5581 {
5582         struct ath_hal_5416 *ahp = AH5416(ah);
5583         struct ath9k_channel ichan;
5584         bool isCalDone;
5585         struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
5586         const struct hal_percal_data *calData = currCal->calData;
5587         int i;
5588
5589         if (currCal == NULL)
5590                 return false;
5591
5592         ichan.CalValid = 0;
5593
5594         for (i = 0; i < init_cal_count; i++) {
5595                 ath9k_hw_reset_calibration(ah, currCal);
5596
5597                 if (!ath9k_hw_wait(ah, AR_PHY_TIMING_CTRL4(0),
5598                                    AR_PHY_TIMING_CTRL4_DO_CAL, 0)) {
5599                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5600                                  "%s: Cal %d failed to complete in 100ms.\n",
5601                                  __func__, calData->calType);
5602
5603                         ahp->ah_cal_list = ahp->ah_cal_list_last =
5604                                 ahp->ah_cal_list_curr = NULL;
5605                         return false;
5606                 }
5607
5608                 ath9k_hw_per_calibration(ah, &ichan, ahp->ah_rxchainmask,
5609                                          currCal, &isCalDone);
5610                 if (!isCalDone) {
5611                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5612                                  "%s: Not able to run Init Cal %d.\n",
5613                                  __func__, calData->calType);
5614                 }
5615                 if (currCal->calNext) {
5616                         currCal = currCal->calNext;
5617                         calData = currCal->calData;
5618                 }
5619         }
5620
5621         ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr = NULL;
5622         return true;
5623 }
5624
5625 static inline bool
5626 ath9k_hw_channel_change(struct ath_hal *ah,
5627                         struct ath9k_channel *chan,
5628                         enum ath9k_ht_macmode macmode)
5629 {
5630         u32 synthDelay, qnum;
5631         struct ath_hal_5416 *ahp = AH5416(ah);
5632
5633         for (qnum = 0; qnum < AR_NUM_QCU; qnum++) {
5634                 if (ath9k_hw_numtxpending(ah, qnum)) {
5635                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5636                                  "%s: Transmit frames pending on queue %d\n",
5637                                  __func__, qnum);
5638                         return false;
5639                 }
5640         }
5641
5642         REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
5643         if (!ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
5644                            AR_PHY_RFBUS_GRANT_EN)) {
5645                 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
5646                          "%s: Could not kill baseband RX\n", __func__);
5647                 return false;
5648         }
5649
5650         ath9k_hw_set_regs(ah, chan, macmode);
5651
5652         if (AR_SREV_9280_10_OR_LATER(ah)) {
5653                 if (!(ath9k_hw_ar9280_set_channel(ah, chan))) {
5654                         DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5655                                  "%s: failed to set channel\n", __func__);
5656                         return false;
5657                 }
5658         } else {
5659                 if (!(ath9k_hw_set_channel(ah, chan))) {
5660                         DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5661                                  "%s: failed to set channel\n", __func__);
5662                         return false;
5663                 }
5664         }
5665
5666         if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
5667                                  ath9k_regd_get_ctl(ah, chan),
5668                                  ath9k_regd_get_antenna_allowed(ah, chan),
5669                                  chan->maxRegTxPower * 2,
5670                                  min((u32) MAX_RATE_POWER,
5671                                      (u32) ah->ah_powerLimit)) != 0) {
5672                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5673                          "%s: error init'ing transmit power\n", __func__);
5674                 return false;
5675         }
5676
5677         synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
5678         if (IS_CHAN_CCK(chan))
5679                 synthDelay = (4 * synthDelay) / 22;
5680         else
5681                 synthDelay /= 10;
5682
5683         udelay(synthDelay + BASE_ACTIVATE_DELAY);
5684
5685         REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
5686
5687         if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5688                 ath9k_hw_set_delta_slope(ah, chan);
5689
5690         if (AR_SREV_9280_10_OR_LATER(ah))
5691                 ath9k_hw_9280_spur_mitigate(ah, chan);
5692         else
5693                 ath9k_hw_spur_mitigate(ah, chan);
5694
5695         if (!chan->oneTimeCalsDone)
5696                 chan->oneTimeCalsDone = true;
5697
5698         return true;
5699 }
5700
5701 static bool ath9k_hw_chip_reset(struct ath_hal *ah,
5702                                 struct ath9k_channel *chan)
5703 {
5704         struct ath_hal_5416 *ahp = AH5416(ah);
5705
5706         if (!ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM))
5707                 return false;
5708
5709         if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5710                 return false;
5711
5712         ahp->ah_chipFullSleep = false;
5713
5714         ath9k_hw_init_pll(ah, chan);
5715
5716         ath9k_hw_set_rfmode(ah, chan);
5717
5718         return true;
5719 }
5720
5721 static inline void ath9k_hw_set_dma(struct ath_hal *ah)
5722 {
5723         u32 regval;
5724
5725         regval = REG_READ(ah, AR_AHB_MODE);
5726         REG_WRITE(ah, AR_AHB_MODE, regval | AR_AHB_PREFETCH_RD_EN);
5727
5728         regval = REG_READ(ah, AR_TXCFG) & ~AR_TXCFG_DMASZ_MASK;
5729         REG_WRITE(ah, AR_TXCFG, regval | AR_TXCFG_DMASZ_128B);
5730
5731         REG_RMW_FIELD(ah, AR_TXCFG, AR_FTRIG, ah->ah_txTrigLevel);
5732
5733         regval = REG_READ(ah, AR_RXCFG) & ~AR_RXCFG_DMASZ_MASK;
5734         REG_WRITE(ah, AR_RXCFG, regval | AR_RXCFG_DMASZ_128B);
5735
5736         REG_WRITE(ah, AR_RXFIFO_CFG, 0x200);
5737
5738         if (AR_SREV_9285(ah)) {
5739                 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5740                           AR_9285_PCU_TXBUF_CTRL_USABLE_SIZE);
5741         } else {
5742                 REG_WRITE(ah, AR_PCU_TXBUF_CTRL,
5743                           AR_PCU_TXBUF_CTRL_USABLE_SIZE);
5744         }
5745 }
5746
5747 bool ath9k_hw_stopdmarecv(struct ath_hal *ah)
5748 {
5749         REG_WRITE(ah, AR_CR, AR_CR_RXD);
5750         if (!ath9k_hw_wait(ah, AR_CR, AR_CR_RXE, 0)) {
5751                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
5752                         "%s: dma failed to stop in 10ms\n"
5753                         "AR_CR=0x%08x\nAR_DIAG_SW=0x%08x\n",
5754                         __func__,
5755                         REG_READ(ah, AR_CR), REG_READ(ah, AR_DIAG_SW));
5756                 return false;
5757         } else {
5758                 return true;
5759         }
5760 }
5761
5762 void ath9k_hw_startpcureceive(struct ath_hal *ah)
5763 {
5764         REG_CLR_BIT(ah, AR_DIAG_SW,
5765                     (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
5766
5767         ath9k_enable_mib_counters(ah);
5768
5769         ath9k_ani_reset(ah);
5770 }
5771
5772 void ath9k_hw_stoppcurecv(struct ath_hal *ah)
5773 {
5774         REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
5775
5776         ath9k_hw_disable_mib_counters(ah);
5777 }
5778
5779 static bool ath9k_hw_iscal_supported(struct ath_hal *ah,
5780                                      struct ath9k_channel *chan,
5781                                      enum hal_cal_types calType)
5782 {
5783         struct ath_hal_5416 *ahp = AH5416(ah);
5784         bool retval = false;
5785
5786         switch (calType & ahp->ah_suppCals) {
5787         case IQ_MISMATCH_CAL:
5788                 if (!IS_CHAN_B(chan))
5789                         retval = true;
5790                 break;
5791         case ADC_GAIN_CAL:
5792         case ADC_DC_CAL:
5793                 if (!IS_CHAN_B(chan)
5794                     && !(IS_CHAN_2GHZ(chan) && IS_CHAN_HT20(chan)))
5795                         retval = true;
5796                 break;
5797         }
5798
5799         return retval;
5800 }
5801
5802 static inline bool ath9k_hw_init_cal(struct ath_hal *ah,
5803                                      struct ath9k_channel *chan)
5804 {
5805         struct ath_hal_5416 *ahp = AH5416(ah);
5806         struct ath9k_channel *ichan =
5807                 ath9k_regd_check_channel(ah, chan);
5808
5809         REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5810                   REG_READ(ah, AR_PHY_AGC_CONTROL) |
5811                   AR_PHY_AGC_CONTROL_CAL);
5812
5813         if (!ath9k_hw_wait
5814             (ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_CAL, 0)) {
5815                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5816                          "%s: offset calibration failed to complete in 1ms; "
5817                          "noisy environment?\n", __func__);
5818                 return false;
5819         }
5820
5821         REG_WRITE(ah, AR_PHY_AGC_CONTROL,
5822                   REG_READ(ah, AR_PHY_AGC_CONTROL) |
5823                   AR_PHY_AGC_CONTROL_NF);
5824
5825         ahp->ah_cal_list = ahp->ah_cal_list_last = ahp->ah_cal_list_curr =
5826                 NULL;
5827
5828         if (AR_SREV_9100(ah) || AR_SREV_9160_10_OR_LATER(ah)) {
5829                 if (ath9k_hw_iscal_supported(ah, chan, ADC_GAIN_CAL)) {
5830                         INIT_CAL(&ahp->ah_adcGainCalData);
5831                         INSERT_CAL(ahp, &ahp->ah_adcGainCalData);
5832                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5833                                  "%s: enabling ADC Gain Calibration.\n",
5834                                  __func__);
5835                 }
5836                 if (ath9k_hw_iscal_supported(ah, chan, ADC_DC_CAL)) {
5837                         INIT_CAL(&ahp->ah_adcDcCalData);
5838                         INSERT_CAL(ahp, &ahp->ah_adcDcCalData);
5839                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5840                                  "%s: enabling ADC DC Calibration.\n",
5841                                  __func__);
5842                 }
5843                 if (ath9k_hw_iscal_supported(ah, chan, IQ_MISMATCH_CAL)) {
5844                         INIT_CAL(&ahp->ah_iqCalData);
5845                         INSERT_CAL(ahp, &ahp->ah_iqCalData);
5846                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
5847                                  "%s: enabling IQ Calibration.\n",
5848                                  __func__);
5849                 }
5850
5851                 ahp->ah_cal_list_curr = ahp->ah_cal_list;
5852
5853                 if (ahp->ah_cal_list_curr)
5854                         ath9k_hw_reset_calibration(ah,
5855                                                    ahp->ah_cal_list_curr);
5856         }
5857
5858         ichan->CalValid = 0;
5859
5860         return true;
5861 }
5862
5863
5864 bool ath9k_hw_reset(struct ath_hal *ah, enum ath9k_opmode opmode,
5865                     struct ath9k_channel *chan,
5866                     enum ath9k_ht_macmode macmode,
5867                     u8 txchainmask, u8 rxchainmask,
5868                     enum ath9k_ht_extprotspacing extprotspacing,
5869                     bool bChannelChange,
5870                     int *status)
5871 {
5872 #define FAIL(_code)     do { ecode = _code; goto bad; } while (0)
5873         u32 saveLedState;
5874         struct ath_hal_5416 *ahp = AH5416(ah);
5875         struct ath9k_channel *curchan = ah->ah_curchan;
5876         u32 saveDefAntenna;
5877         u32 macStaId1;
5878         int ecode;
5879         int i, rx_chainmask;
5880
5881         ahp->ah_extprotspacing = extprotspacing;
5882         ahp->ah_txchainmask = txchainmask;
5883         ahp->ah_rxchainmask = rxchainmask;
5884
5885         if (AR_SREV_9280(ah)) {
5886                 ahp->ah_txchainmask &= 0x3;
5887                 ahp->ah_rxchainmask &= 0x3;
5888         }
5889
5890         if (ath9k_hw_check_chan(ah, chan) == NULL) {
5891                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
5892                          "%s: invalid channel %u/0x%x; no mapping\n",
5893                          __func__, chan->channel, chan->channelFlags);
5894                 FAIL(-EINVAL);
5895         }
5896
5897         if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
5898                 return false;
5899
5900         if (curchan)
5901                 ath9k_hw_getnf(ah, curchan);
5902
5903         if (bChannelChange &&
5904             (ahp->ah_chipFullSleep != true) &&
5905             (ah->ah_curchan != NULL) &&
5906             (chan->channel != ah->ah_curchan->channel) &&
5907             ((chan->channelFlags & CHANNEL_ALL) ==
5908              (ah->ah_curchan->channelFlags & CHANNEL_ALL)) &&
5909             (!AR_SREV_9280(ah) || (!IS_CHAN_A_5MHZ_SPACED(chan) &&
5910                                    !IS_CHAN_A_5MHZ_SPACED(ah->
5911                                                           ah_curchan)))) {
5912
5913                 if (ath9k_hw_channel_change(ah, chan, macmode)) {
5914                         ath9k_hw_loadnf(ah, ah->ah_curchan);
5915                         ath9k_hw_start_nfcal(ah);
5916                         return true;
5917                 }
5918         }
5919
5920         saveDefAntenna = REG_READ(ah, AR_DEF_ANTENNA);
5921         if (saveDefAntenna == 0)
5922                 saveDefAntenna = 1;
5923
5924         macStaId1 = REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_BASE_RATE_11B;
5925
5926         saveLedState = REG_READ(ah, AR_CFG_LED) &
5927                 (AR_CFG_LED_ASSOC_CTL | AR_CFG_LED_MODE_SEL |
5928                  AR_CFG_LED_BLINK_THRESH_SEL | AR_CFG_LED_BLINK_SLOW);
5929
5930         ath9k_hw_mark_phy_inactive(ah);
5931
5932         if (!ath9k_hw_chip_reset(ah, chan)) {
5933                 DPRINTF(ah->ah_sc, ATH_DBG_RESET, "%s: chip reset failed\n",
5934                          __func__);
5935                 FAIL(-EIO);
5936         }
5937
5938         if (AR_SREV_9280(ah)) {
5939                 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
5940                             AR_GPIO_JTAG_DISABLE);
5941
5942                 if (test_bit(ATH9K_MODE_11A, ah->ah_caps.wireless_modes)) {
5943                         if (IS_CHAN_5GHZ(chan))
5944                                 ath9k_hw_set_gpio(ah, 9, 0);
5945                         else
5946                                 ath9k_hw_set_gpio(ah, 9, 1);
5947                 }
5948                 ath9k_hw_cfg_output(ah, 9, ATH9K_GPIO_OUTPUT_MUX_AS_OUTPUT);
5949         }
5950
5951         ecode = ath9k_hw_process_ini(ah, chan, macmode);
5952         if (ecode != 0)
5953                 goto bad;
5954
5955         if (IS_CHAN_OFDM(chan) || IS_CHAN_HT(chan))
5956                 ath9k_hw_set_delta_slope(ah, chan);
5957
5958         if (AR_SREV_9280_10_OR_LATER(ah))
5959                 ath9k_hw_9280_spur_mitigate(ah, chan);
5960         else
5961                 ath9k_hw_spur_mitigate(ah, chan);
5962
5963         if (!ath9k_hw_eeprom_set_board_values(ah, chan)) {
5964                 DPRINTF(ah->ah_sc, ATH_DBG_EEPROM,
5965                          "%s: error setting board options\n", __func__);
5966                 FAIL(-EIO);
5967         }
5968
5969         ath9k_hw_decrease_chain_power(ah, chan);
5970
5971         REG_WRITE(ah, AR_STA_ID0, get_unaligned_le32(ahp->ah_macaddr));
5972         REG_WRITE(ah, AR_STA_ID1, get_unaligned_le16(ahp->ah_macaddr + 4)
5973                   | macStaId1
5974                   | AR_STA_ID1_RTS_USE_DEF
5975                   | (ah->ah_config.
5976                      ack_6mb ? AR_STA_ID1_ACKCTS_6MB : 0)
5977                   | ahp->ah_staId1Defaults);
5978         ath9k_hw_set_operating_mode(ah, opmode);
5979
5980         REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
5981         REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
5982
5983         REG_WRITE(ah, AR_DEF_ANTENNA, saveDefAntenna);
5984
5985         REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
5986         REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
5987                   ((ahp->ah_assocId & 0x3fff) << AR_BSS_ID1_AID_S));
5988
5989         REG_WRITE(ah, AR_ISR, ~0);
5990
5991         REG_WRITE(ah, AR_RSSI_THR, INIT_RSSI_THR);
5992
5993         if (AR_SREV_9280_10_OR_LATER(ah)) {
5994                 if (!(ath9k_hw_ar9280_set_channel(ah, chan)))
5995                         FAIL(-EIO);
5996         } else {
5997                 if (!(ath9k_hw_set_channel(ah, chan)))
5998                         FAIL(-EIO);
5999         }
6000
6001         for (i = 0; i < AR_NUM_DCU; i++)
6002                 REG_WRITE(ah, AR_DQCUMASK(i), 1 << i);
6003
6004         ahp->ah_intrTxqs = 0;
6005         for (i = 0; i < ah->ah_caps.total_queues; i++)
6006                 ath9k_hw_resettxqueue(ah, i);
6007
6008         ath9k_hw_init_interrupt_masks(ah, opmode);
6009         ath9k_hw_init_qos(ah);
6010
6011         ath9k_hw_init_user_settings(ah);
6012
6013         ah->ah_opmode = opmode;
6014
6015         REG_WRITE(ah, AR_STA_ID1,
6016                   REG_READ(ah, AR_STA_ID1) | AR_STA_ID1_PRESERVE_SEQNUM);
6017
6018         ath9k_hw_set_dma(ah);
6019
6020         REG_WRITE(ah, AR_OBS, 8);
6021
6022         if (ahp->ah_intrMitigation) {
6023
6024                 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, 500);
6025                 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, 2000);
6026         }
6027
6028         ath9k_hw_init_bb(ah, chan);
6029
6030         if (!ath9k_hw_init_cal(ah, chan))
6031                 FAIL(-ENODEV);
6032
6033         rx_chainmask = ahp->ah_rxchainmask;
6034         if ((rx_chainmask == 0x5) || (rx_chainmask == 0x3)) {
6035                 REG_WRITE(ah, AR_PHY_RX_CHAINMASK, rx_chainmask);
6036                 REG_WRITE(ah, AR_PHY_CAL_CHAINMASK, rx_chainmask);
6037         }
6038
6039         REG_WRITE(ah, AR_CFG_LED, saveLedState | AR_CFG_SCLK_32KHZ);
6040
6041         if (AR_SREV_9100(ah)) {
6042                 u32 mask;
6043                 mask = REG_READ(ah, AR_CFG);
6044                 if (mask & (AR_CFG_SWRB | AR_CFG_SWTB | AR_CFG_SWRG)) {
6045                         DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6046                                  "%s CFG Byte Swap Set 0x%x\n", __func__,
6047                                  mask);
6048                 } else {
6049                         mask =
6050                                 INIT_CONFIG_STATUS | AR_CFG_SWRB | AR_CFG_SWTB;
6051                         REG_WRITE(ah, AR_CFG, mask);
6052                         DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6053                                  "%s Setting CFG 0x%x\n", __func__,
6054                                  REG_READ(ah, AR_CFG));
6055                 }
6056         } else {
6057 #ifdef __BIG_ENDIAN
6058                 REG_WRITE(ah, AR_CFG, AR_CFG_SWTD | AR_CFG_SWRD);
6059 #endif
6060         }
6061
6062         return true;
6063 bad:
6064         if (status)
6065                 *status = ecode;
6066         return false;
6067 #undef FAIL
6068 }
6069
6070 bool ath9k_hw_phy_disable(struct ath_hal *ah)
6071 {
6072         return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_WARM);
6073 }
6074
6075 bool ath9k_hw_disable(struct ath_hal *ah)
6076 {
6077         if (!ath9k_hw_setpower(ah, ATH9K_PM_AWAKE))
6078                 return false;
6079
6080         return ath9k_hw_set_reset_reg(ah, ATH9K_RESET_COLD);
6081 }
6082
6083 bool
6084 ath9k_hw_calibrate(struct ath_hal *ah, struct ath9k_channel *chan,
6085                    u8 rxchainmask, bool longcal,
6086                    bool *isCalDone)
6087 {
6088         struct ath_hal_5416 *ahp = AH5416(ah);
6089         struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6090         struct ath9k_channel *ichan =
6091                 ath9k_regd_check_channel(ah, chan);
6092
6093         *isCalDone = true;
6094
6095         if (ichan == NULL) {
6096                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL,
6097                          "%s: invalid channel %u/0x%x; no mapping\n",
6098                          __func__, chan->channel, chan->channelFlags);
6099                 return false;
6100         }
6101
6102         if (currCal &&
6103             (currCal->calState == CAL_RUNNING ||
6104              currCal->calState == CAL_WAITING)) {
6105                 ath9k_hw_per_calibration(ah, ichan, rxchainmask, currCal,
6106                                          isCalDone);
6107                 if (*isCalDone) {
6108                         ahp->ah_cal_list_curr = currCal = currCal->calNext;
6109
6110                         if (currCal->calState == CAL_WAITING) {
6111                                 *isCalDone = false;
6112                                 ath9k_hw_reset_calibration(ah, currCal);
6113                         }
6114                 }
6115         }
6116
6117         if (longcal) {
6118                 ath9k_hw_getnf(ah, ichan);
6119                 ath9k_hw_loadnf(ah, ah->ah_curchan);
6120                 ath9k_hw_start_nfcal(ah);
6121
6122                 if ((ichan->channelFlags & CHANNEL_CW_INT) != 0) {
6123
6124                         chan->channelFlags |= CHANNEL_CW_INT;
6125                         ichan->channelFlags &= ~CHANNEL_CW_INT;
6126                 }
6127         }
6128
6129         return true;
6130 }
6131
6132 static void ath9k_hw_iqcal_collect(struct ath_hal *ah)
6133 {
6134         struct ath_hal_5416 *ahp = AH5416(ah);
6135         int i;
6136
6137         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6138                 ahp->ah_totalPowerMeasI[i] +=
6139                         REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6140                 ahp->ah_totalPowerMeasQ[i] +=
6141                         REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6142                 ahp->ah_totalIqCorrMeas[i] +=
6143                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6144                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6145                          "%d: Chn %d pmi=0x%08x;pmq=0x%08x;iqcm=0x%08x;\n",
6146                          ahp->ah_CalSamples, i, ahp->ah_totalPowerMeasI[i],
6147                          ahp->ah_totalPowerMeasQ[i],
6148                          ahp->ah_totalIqCorrMeas[i]);
6149         }
6150 }
6151
6152 static void ath9k_hw_adc_gaincal_collect(struct ath_hal *ah)
6153 {
6154         struct ath_hal_5416 *ahp = AH5416(ah);
6155         int i;
6156
6157         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6158                 ahp->ah_totalAdcIOddPhase[i] +=
6159                         REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6160                 ahp->ah_totalAdcIEvenPhase[i] +=
6161                         REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6162                 ahp->ah_totalAdcQOddPhase[i] +=
6163                         REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6164                 ahp->ah_totalAdcQEvenPhase[i] +=
6165                         REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6166
6167                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6168                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6169                         "oddq=0x%08x; evenq=0x%08x;\n",
6170                          ahp->ah_CalSamples, i,
6171                          ahp->ah_totalAdcIOddPhase[i],
6172                          ahp->ah_totalAdcIEvenPhase[i],
6173                          ahp->ah_totalAdcQOddPhase[i],
6174                          ahp->ah_totalAdcQEvenPhase[i]);
6175         }
6176 }
6177
6178 static void ath9k_hw_adc_dccal_collect(struct ath_hal *ah)
6179 {
6180         struct ath_hal_5416 *ahp = AH5416(ah);
6181         int i;
6182
6183         for (i = 0; i < AR5416_MAX_CHAINS; i++) {
6184                 ahp->ah_totalAdcDcOffsetIOddPhase[i] +=
6185                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_0(i));
6186                 ahp->ah_totalAdcDcOffsetIEvenPhase[i] +=
6187                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_1(i));
6188                 ahp->ah_totalAdcDcOffsetQOddPhase[i] +=
6189                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_2(i));
6190                 ahp->ah_totalAdcDcOffsetQEvenPhase[i] +=
6191                         (int32_t) REG_READ(ah, AR_PHY_CAL_MEAS_3(i));
6192
6193                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6194                         "%d: Chn %d oddi=0x%08x; eveni=0x%08x; "
6195                         "oddq=0x%08x; evenq=0x%08x;\n",
6196                          ahp->ah_CalSamples, i,
6197                          ahp->ah_totalAdcDcOffsetIOddPhase[i],
6198                          ahp->ah_totalAdcDcOffsetIEvenPhase[i],
6199                          ahp->ah_totalAdcDcOffsetQOddPhase[i],
6200                          ahp->ah_totalAdcDcOffsetQEvenPhase[i]);
6201         }
6202 }
6203
6204 static void ath9k_hw_iqcalibrate(struct ath_hal *ah, u8 numChains)
6205 {
6206         struct ath_hal_5416 *ahp = AH5416(ah);
6207         u32 powerMeasQ, powerMeasI, iqCorrMeas;
6208         u32 qCoffDenom, iCoffDenom;
6209         int32_t qCoff, iCoff;
6210         int iqCorrNeg, i;
6211
6212         for (i = 0; i < numChains; i++) {
6213                 powerMeasI = ahp->ah_totalPowerMeasI[i];
6214                 powerMeasQ = ahp->ah_totalPowerMeasQ[i];
6215                 iqCorrMeas = ahp->ah_totalIqCorrMeas[i];
6216
6217                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6218                          "Starting IQ Cal and Correction for Chain %d\n",
6219                          i);
6220
6221                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6222                          "Orignal: Chn %diq_corr_meas = 0x%08x\n",
6223                          i, ahp->ah_totalIqCorrMeas[i]);
6224
6225                 iqCorrNeg = 0;
6226
6227
6228                 if (iqCorrMeas > 0x80000000) {
6229                         iqCorrMeas = (0xffffffff - iqCorrMeas) + 1;
6230                         iqCorrNeg = 1;
6231                 }
6232
6233                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6234                          "Chn %d pwr_meas_i = 0x%08x\n", i, powerMeasI);
6235                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6236                          "Chn %d pwr_meas_q = 0x%08x\n", i, powerMeasQ);
6237                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE, "iqCorrNeg is 0x%08x\n",
6238                          iqCorrNeg);
6239
6240                 iCoffDenom = (powerMeasI / 2 + powerMeasQ / 2) / 128;
6241                 qCoffDenom = powerMeasQ / 64;
6242
6243                 if (powerMeasQ != 0) {
6244
6245                         iCoff = iqCorrMeas / iCoffDenom;
6246                         qCoff = powerMeasI / qCoffDenom - 64;
6247                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6248                                  "Chn %d iCoff = 0x%08x\n", i, iCoff);
6249                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6250                                  "Chn %d qCoff = 0x%08x\n", i, qCoff);
6251
6252
6253                         iCoff = iCoff & 0x3f;
6254                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6255                                  "New: Chn %d iCoff = 0x%08x\n", i, iCoff);
6256                         if (iqCorrNeg == 0x0)
6257                                 iCoff = 0x40 - iCoff;
6258
6259                         if (qCoff > 15)
6260                                 qCoff = 15;
6261                         else if (qCoff <= -16)
6262                                 qCoff = 16;
6263
6264                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6265                                  "Chn %d : iCoff = 0x%x  qCoff = 0x%x\n",
6266                                 i, iCoff, qCoff);
6267
6268                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6269                                       AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF,
6270                                       iCoff);
6271                         REG_RMW_FIELD(ah, AR_PHY_TIMING_CTRL4(i),
6272                                       AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF,
6273                                       qCoff);
6274                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6275                                 "IQ Cal and Correction done for Chain %d\n",
6276                                 i);
6277                 }
6278         }
6279
6280         REG_SET_BIT(ah, AR_PHY_TIMING_CTRL4(0),
6281                     AR_PHY_TIMING_CTRL4_IQCORR_ENABLE);
6282 }
6283
6284 static void
6285 ath9k_hw_adc_gaincal_calibrate(struct ath_hal *ah, u8 numChains)
6286 {
6287         struct ath_hal_5416 *ahp = AH5416(ah);
6288         u32 iOddMeasOffset, iEvenMeasOffset, qOddMeasOffset,
6289                 qEvenMeasOffset;
6290         u32 qGainMismatch, iGainMismatch, val, i;
6291
6292         for (i = 0; i < numChains; i++) {
6293                 iOddMeasOffset = ahp->ah_totalAdcIOddPhase[i];
6294                 iEvenMeasOffset = ahp->ah_totalAdcIEvenPhase[i];
6295                 qOddMeasOffset = ahp->ah_totalAdcQOddPhase[i];
6296                 qEvenMeasOffset = ahp->ah_totalAdcQEvenPhase[i];
6297
6298                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6299                          "Starting ADC Gain Cal for Chain %d\n", i);
6300
6301                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6302                          "Chn %d pwr_meas_odd_i = 0x%08x\n", i,
6303                          iOddMeasOffset);
6304                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6305                          "Chn %d pwr_meas_even_i = 0x%08x\n", i,
6306                          iEvenMeasOffset);
6307                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6308                          "Chn %d pwr_meas_odd_q = 0x%08x\n", i,
6309                          qOddMeasOffset);
6310                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6311                          "Chn %d pwr_meas_even_q = 0x%08x\n", i,
6312                          qEvenMeasOffset);
6313
6314                 if (iOddMeasOffset != 0 && qEvenMeasOffset != 0) {
6315                         iGainMismatch =
6316                                 ((iEvenMeasOffset * 32) /
6317                                  iOddMeasOffset) & 0x3f;
6318                         qGainMismatch =
6319                                 ((qOddMeasOffset * 32) /
6320                                  qEvenMeasOffset) & 0x3f;
6321
6322                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6323                                  "Chn %d gain_mismatch_i = 0x%08x\n", i,
6324                                  iGainMismatch);
6325                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6326                                  "Chn %d gain_mismatch_q = 0x%08x\n", i,
6327                                  qGainMismatch);
6328
6329                         val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6330                         val &= 0xfffff000;
6331                         val |= (qGainMismatch) | (iGainMismatch << 6);
6332                         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6333
6334                         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6335                                  "ADC Gain Cal done for Chain %d\n", i);
6336                 }
6337         }
6338
6339         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6340                   REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6341                   AR_PHY_NEW_ADC_GAIN_CORR_ENABLE);
6342 }
6343
6344 static void
6345 ath9k_hw_adc_dccal_calibrate(struct ath_hal *ah, u8 numChains)
6346 {
6347         struct ath_hal_5416 *ahp = AH5416(ah);
6348         u32 iOddMeasOffset, iEvenMeasOffset, val, i;
6349         int32_t qOddMeasOffset, qEvenMeasOffset, qDcMismatch, iDcMismatch;
6350         const struct hal_percal_data *calData =
6351                 ahp->ah_cal_list_curr->calData;
6352         u32 numSamples =
6353                 (1 << (calData->calCountMax + 5)) * calData->calNumSamples;
6354
6355         for (i = 0; i < numChains; i++) {
6356                 iOddMeasOffset = ahp->ah_totalAdcDcOffsetIOddPhase[i];
6357                 iEvenMeasOffset = ahp->ah_totalAdcDcOffsetIEvenPhase[i];
6358                 qOddMeasOffset = ahp->ah_totalAdcDcOffsetQOddPhase[i];
6359                 qEvenMeasOffset = ahp->ah_totalAdcDcOffsetQEvenPhase[i];
6360
6361                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6362                          "Starting ADC DC Offset Cal for Chain %d\n", i);
6363
6364                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6365                          "Chn %d pwr_meas_odd_i = %d\n", i,
6366                          iOddMeasOffset);
6367                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6368                          "Chn %d pwr_meas_even_i = %d\n", i,
6369                          iEvenMeasOffset);
6370                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6371                          "Chn %d pwr_meas_odd_q = %d\n", i,
6372                          qOddMeasOffset);
6373                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6374                          "Chn %d pwr_meas_even_q = %d\n", i,
6375                          qEvenMeasOffset);
6376
6377                 iDcMismatch = (((iEvenMeasOffset - iOddMeasOffset) * 2) /
6378                                numSamples) & 0x1ff;
6379                 qDcMismatch = (((qOddMeasOffset - qEvenMeasOffset) * 2) /
6380                                numSamples) & 0x1ff;
6381
6382                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6383                          "Chn %d dc_offset_mismatch_i = 0x%08x\n", i,
6384                          iDcMismatch);
6385                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6386                          "Chn %d dc_offset_mismatch_q = 0x%08x\n", i,
6387                          qDcMismatch);
6388
6389                 val = REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i));
6390                 val &= 0xc0000fff;
6391                 val |= (qDcMismatch << 12) | (iDcMismatch << 21);
6392                 REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(i), val);
6393
6394                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6395                          "ADC DC Offset Cal done for Chain %d\n", i);
6396         }
6397
6398         REG_WRITE(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0),
6399                   REG_READ(ah, AR_PHY_NEW_ADC_DC_GAIN_CORR(0)) |
6400                   AR_PHY_NEW_ADC_DC_OFFSET_CORR_ENABLE);
6401 }
6402
6403 bool ath9k_hw_set_txpowerlimit(struct ath_hal *ah, u32 limit)
6404 {
6405         struct ath_hal_5416 *ahp = AH5416(ah);
6406         struct ath9k_channel *chan = ah->ah_curchan;
6407
6408         ah->ah_powerLimit = min(limit, (u32) MAX_RATE_POWER);
6409
6410         if (ath9k_hw_set_txpower(ah, &ahp->ah_eeprom, chan,
6411                                  ath9k_regd_get_ctl(ah, chan),
6412                                  ath9k_regd_get_antenna_allowed(ah,
6413                                                                 chan),
6414                                  chan->maxRegTxPower * 2,
6415                                  min((u32) MAX_RATE_POWER,
6416                                      (u32) ah->ah_powerLimit)) != 0)
6417                 return false;
6418
6419         return true;
6420 }
6421
6422 void
6423 ath9k_hw_get_channel_centers(struct ath_hal *ah,
6424                              struct ath9k_channel *chan,
6425                              struct chan_centers *centers)
6426 {
6427         int8_t extoff;
6428         struct ath_hal_5416 *ahp = AH5416(ah);
6429
6430         if (!IS_CHAN_HT40(chan)) {
6431                 centers->ctl_center = centers->ext_center =
6432                         centers->synth_center = chan->channel;
6433                 return;
6434         }
6435
6436         if ((chan->chanmode == CHANNEL_A_HT40PLUS) ||
6437             (chan->chanmode == CHANNEL_G_HT40PLUS)) {
6438                 centers->synth_center =
6439                         chan->channel + HT40_CHANNEL_CENTER_SHIFT;
6440                 extoff = 1;
6441         } else {
6442                 centers->synth_center =
6443                         chan->channel - HT40_CHANNEL_CENTER_SHIFT;
6444                 extoff = -1;
6445         }
6446
6447         centers->ctl_center = centers->synth_center - (extoff *
6448                 HT40_CHANNEL_CENTER_SHIFT);
6449         centers->ext_center = centers->synth_center + (extoff *
6450                 ((ahp->
6451                 ah_extprotspacing
6452                 ==
6453                 ATH9K_HT_EXTPROTSPACING_20)
6454                 ?
6455                 HT40_CHANNEL_CENTER_SHIFT
6456                 : 15));
6457
6458 }
6459
6460 void
6461 ath9k_hw_reset_calvalid(struct ath_hal *ah, struct ath9k_channel *chan,
6462                         bool *isCalDone)
6463 {
6464         struct ath_hal_5416 *ahp = AH5416(ah);
6465         struct ath9k_channel *ichan =
6466                 ath9k_regd_check_channel(ah, chan);
6467         struct hal_cal_list *currCal = ahp->ah_cal_list_curr;
6468
6469         *isCalDone = true;
6470
6471         if (!AR_SREV_9100(ah) && !AR_SREV_9160_10_OR_LATER(ah))
6472                 return;
6473
6474         if (currCal == NULL)
6475                 return;
6476
6477         if (ichan == NULL) {
6478                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6479                          "%s: invalid channel %u/0x%x; no mapping\n",
6480                          __func__, chan->channel, chan->channelFlags);
6481                 return;
6482         }
6483
6484
6485         if (currCal->calState != CAL_DONE) {
6486                 DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6487                          "%s: Calibration state incorrect, %d\n",
6488                          __func__, currCal->calState);
6489                 return;
6490         }
6491
6492
6493         if (!ath9k_hw_iscal_supported(ah, chan, currCal->calData->calType))
6494                 return;
6495
6496         DPRINTF(ah->ah_sc, ATH_DBG_CALIBRATE,
6497                  "%s: Resetting Cal %d state for channel %u/0x%x\n",
6498                  __func__, currCal->calData->calType, chan->channel,
6499                  chan->channelFlags);
6500
6501         ichan->CalValid &= ~currCal->calData->calType;
6502         currCal->calState = CAL_WAITING;
6503
6504         *isCalDone = false;
6505 }
6506
6507 void ath9k_hw_getmac(struct ath_hal *ah, u8 *mac)
6508 {
6509         struct ath_hal_5416 *ahp = AH5416(ah);
6510
6511         memcpy(mac, ahp->ah_macaddr, ETH_ALEN);
6512 }
6513
6514 bool ath9k_hw_setmac(struct ath_hal *ah, const u8 *mac)
6515 {
6516         struct ath_hal_5416 *ahp = AH5416(ah);
6517
6518         memcpy(ahp->ah_macaddr, mac, ETH_ALEN);
6519         return true;
6520 }
6521
6522 void ath9k_hw_getbssidmask(struct ath_hal *ah, u8 *mask)
6523 {
6524         struct ath_hal_5416 *ahp = AH5416(ah);
6525
6526         memcpy(mask, ahp->ah_bssidmask, ETH_ALEN);
6527 }
6528
6529 bool
6530 ath9k_hw_setbssidmask(struct ath_hal *ah, const u8 *mask)
6531 {
6532         struct ath_hal_5416 *ahp = AH5416(ah);
6533
6534         memcpy(ahp->ah_bssidmask, mask, ETH_ALEN);
6535
6536         REG_WRITE(ah, AR_BSSMSKL, get_unaligned_le32(ahp->ah_bssidmask));
6537         REG_WRITE(ah, AR_BSSMSKU, get_unaligned_le16(ahp->ah_bssidmask + 4));
6538
6539         return true;
6540 }
6541
6542 #ifdef CONFIG_ATH9K_RFKILL
6543 static void ath9k_enable_rfkill(struct ath_hal *ah)
6544 {
6545         struct ath_hal_5416 *ahp = AH5416(ah);
6546
6547         REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
6548                     AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
6549
6550         REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
6551                     AR_GPIO_INPUT_MUX2_RFSILENT);
6552
6553         ath9k_hw_cfg_gpio_input(ah, ahp->ah_gpioSelect);
6554         REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
6555
6556         if (ahp->ah_gpioBit == ath9k_hw_gpio_get(ah, ahp->ah_gpioSelect)) {
6557
6558                 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6559                                        !ahp->ah_gpioBit);
6560         } else {
6561                 ath9k_hw_set_gpio_intr(ah, ahp->ah_gpioSelect,
6562                                        ahp->ah_gpioBit);
6563         }
6564 }
6565 #endif
6566
6567 void
6568 ath9k_hw_write_associd(struct ath_hal *ah, const u8 *bssid,
6569                        u16 assocId)
6570 {
6571         struct ath_hal_5416 *ahp = AH5416(ah);
6572
6573         memcpy(ahp->ah_bssid, bssid, ETH_ALEN);
6574         ahp->ah_assocId = assocId;
6575
6576         REG_WRITE(ah, AR_BSS_ID0, get_unaligned_le32(ahp->ah_bssid));
6577         REG_WRITE(ah, AR_BSS_ID1, get_unaligned_le16(ahp->ah_bssid + 4) |
6578                   ((assocId & 0x3fff) << AR_BSS_ID1_AID_S));
6579 }
6580
6581 u64 ath9k_hw_gettsf64(struct ath_hal *ah)
6582 {
6583         u64 tsf;
6584
6585         tsf = REG_READ(ah, AR_TSF_U32);
6586         tsf = (tsf << 32) | REG_READ(ah, AR_TSF_L32);
6587         return tsf;
6588 }
6589
6590 void ath9k_hw_reset_tsf(struct ath_hal *ah)
6591 {
6592         int count;
6593
6594         count = 0;
6595         while (REG_READ(ah, AR_SLP32_MODE) & AR_SLP32_TSF_WRITE_STATUS) {
6596                 count++;
6597                 if (count > 10) {
6598                         DPRINTF(ah->ah_sc, ATH_DBG_RESET,
6599                          "%s: AR_SLP32_TSF_WRITE_STATUS limit exceeded\n",
6600                                  __func__);
6601                         break;
6602                 }
6603                 udelay(10);
6604         }
6605         REG_WRITE(ah, AR_RESET_TSF, AR_RESET_TSF_ONCE);
6606 }
6607
6608 u32 ath9k_hw_getdefantenna(struct ath_hal *ah)
6609 {
6610         return REG_READ(ah, AR_DEF_ANTENNA) & 0x7;
6611 }
6612
6613 void ath9k_hw_setantenna(struct ath_hal *ah, u32 antenna)
6614 {
6615         REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
6616 }
6617
6618 bool
6619 ath9k_hw_setantennaswitch(struct ath_hal *ah,
6620                           enum ath9k_ant_setting settings,
6621                           struct ath9k_channel *chan,
6622                           u8 *tx_chainmask,
6623                           u8 *rx_chainmask,
6624                           u8 *antenna_cfgd)
6625 {
6626         struct ath_hal_5416 *ahp = AH5416(ah);
6627         static u8 tx_chainmask_cfg, rx_chainmask_cfg;
6628
6629         if (AR_SREV_9280(ah)) {
6630                 if (!tx_chainmask_cfg) {
6631
6632                         tx_chainmask_cfg = *tx_chainmask;
6633                         rx_chainmask_cfg = *rx_chainmask;
6634                 }
6635
6636                 switch (settings) {
6637                 case ATH9K_ANT_FIXED_A:
6638                         *tx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6639                         *rx_chainmask = ATH9K_ANTENNA0_CHAINMASK;
6640                         *antenna_cfgd = true;
6641                         break;
6642                 case ATH9K_ANT_FIXED_B:
6643                         if (ah->ah_caps.tx_chainmask >
6644                             ATH9K_ANTENNA1_CHAINMASK) {
6645                                 *tx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6646                         }
6647                         *rx_chainmask = ATH9K_ANTENNA1_CHAINMASK;
6648                         *antenna_cfgd = true;
6649                         break;
6650                 case ATH9K_ANT_VARIABLE:
6651                         *tx_chainmask = tx_chainmask_cfg;
6652                         *rx_chainmask = rx_chainmask_cfg;
6653                         *antenna_cfgd = true;
6654                         break;
6655                 default:
6656                         break;
6657                 }
6658         } else {
6659                 ahp->ah_diversityControl = settings;
6660         }
6661
6662         return true;
6663 }
6664
6665 void ath9k_hw_setopmode(struct ath_hal *ah)
6666 {
6667         ath9k_hw_set_operating_mode(ah, ah->ah_opmode);
6668 }
6669
6670 bool
6671 ath9k_hw_getcapability(struct ath_hal *ah, enum ath9k_capability_type type,
6672                        u32 capability, u32 *result)
6673 {
6674         struct ath_hal_5416 *ahp = AH5416(ah);
6675         const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6676
6677         switch (type) {
6678         case ATH9K_CAP_CIPHER:
6679                 switch (capability) {
6680                 case ATH9K_CIPHER_AES_CCM:
6681                 case ATH9K_CIPHER_AES_OCB:
6682                 case ATH9K_CIPHER_TKIP:
6683                 case ATH9K_CIPHER_WEP:
6684                 case ATH9K_CIPHER_MIC:
6685                 case ATH9K_CIPHER_CLR:
6686                         return true;
6687                 default:
6688                         return false;
6689                 }
6690         case ATH9K_CAP_TKIP_MIC:
6691                 switch (capability) {
6692                 case 0:
6693                         return true;
6694                 case 1:
6695                         return (ahp->ah_staId1Defaults &
6696                                 AR_STA_ID1_CRPT_MIC_ENABLE) ? true :
6697                         false;
6698                 }
6699         case ATH9K_CAP_TKIP_SPLIT:
6700                 return (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) ?
6701                         false : true;
6702         case ATH9K_CAP_WME_TKIPMIC:
6703                 return 0;
6704         case ATH9K_CAP_PHYCOUNTERS:
6705                 return ahp->ah_hasHwPhyCounters ? 0 : -ENXIO;
6706         case ATH9K_CAP_DIVERSITY:
6707                 return (REG_READ(ah, AR_PHY_CCK_DETECT) &
6708                         AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV) ?
6709                         true : false;
6710         case ATH9K_CAP_PHYDIAG:
6711                 return true;
6712         case ATH9K_CAP_MCAST_KEYSRCH:
6713                 switch (capability) {
6714                 case 0:
6715                         return true;
6716                 case 1:
6717                         if (REG_READ(ah, AR_STA_ID1) & AR_STA_ID1_ADHOC) {
6718                                 return false;
6719                         } else {
6720                                 return (ahp->ah_staId1Defaults &
6721                                         AR_STA_ID1_MCAST_KSRCH) ? true :
6722                                         false;
6723                         }
6724                 }
6725                 return false;
6726         case ATH9K_CAP_TSF_ADJUST:
6727                 return (ahp->ah_miscMode & AR_PCU_TX_ADD_TSF) ?
6728                         true : false;
6729         case ATH9K_CAP_RFSILENT:
6730                 if (capability == 3)
6731                         return false;
6732         case ATH9K_CAP_ANT_CFG_2GHZ:
6733                 *result = pCap->num_antcfg_2ghz;
6734                 return true;
6735         case ATH9K_CAP_ANT_CFG_5GHZ:
6736                 *result = pCap->num_antcfg_5ghz;
6737                 return true;
6738         case ATH9K_CAP_TXPOW:
6739                 switch (capability) {
6740                 case 0:
6741                         return 0;
6742                 case 1:
6743                         *result = ah->ah_powerLimit;
6744                         return 0;
6745                 case 2:
6746                         *result = ah->ah_maxPowerLevel;
6747                         return 0;
6748                 case 3:
6749                         *result = ah->ah_tpScale;
6750                         return 0;
6751                 }
6752                 return false;
6753         default:
6754                 return false;
6755         }
6756 }
6757
6758 int
6759 ath9k_hw_select_antconfig(struct ath_hal *ah, u32 cfg)
6760 {
6761         struct ath_hal_5416 *ahp = AH5416(ah);
6762         struct ath9k_channel *chan = ah->ah_curchan;
6763         const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6764         u16 ant_config;
6765         u32 halNumAntConfig;
6766
6767         halNumAntConfig =
6768                 IS_CHAN_2GHZ(chan) ? pCap->num_antcfg_2ghz : pCap->
6769                 num_antcfg_5ghz;
6770
6771         if (cfg < halNumAntConfig) {
6772                 if (!ath9k_hw_get_eeprom_antenna_cfg(ahp, chan,
6773                                                      cfg, &ant_config)) {
6774                         REG_WRITE(ah, AR_PHY_SWITCH_COM, ant_config);
6775                         return 0;
6776                 }
6777         }
6778
6779         return -EINVAL;
6780 }
6781
6782 bool ath9k_hw_intrpend(struct ath_hal *ah)
6783 {
6784         u32 host_isr;
6785
6786         if (AR_SREV_9100(ah))
6787                 return true;
6788
6789         host_isr = REG_READ(ah, AR_INTR_ASYNC_CAUSE);
6790         if ((host_isr & AR_INTR_MAC_IRQ) && (host_isr != AR_INTR_SPURIOUS))
6791                 return true;
6792
6793         host_isr = REG_READ(ah, AR_INTR_SYNC_CAUSE);
6794         if ((host_isr & AR_INTR_SYNC_DEFAULT)
6795             && (host_isr != AR_INTR_SPURIOUS))
6796                 return true;
6797
6798         return false;
6799 }
6800
6801 bool ath9k_hw_getisr(struct ath_hal *ah, enum ath9k_int *masked)
6802 {
6803         u32 isr = 0;
6804         u32 mask2 = 0;
6805         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6806         u32 sync_cause = 0;
6807         bool fatal_int = false;
6808
6809         if (!AR_SREV_9100(ah)) {
6810                 if (REG_READ(ah, AR_INTR_ASYNC_CAUSE) & AR_INTR_MAC_IRQ) {
6811                         if ((REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M)
6812                             == AR_RTC_STATUS_ON) {
6813                                 isr = REG_READ(ah, AR_ISR);
6814                         }
6815                 }
6816
6817                 sync_cause =
6818                         REG_READ(ah,
6819                                  AR_INTR_SYNC_CAUSE) & AR_INTR_SYNC_DEFAULT;
6820
6821                 *masked = 0;
6822
6823                 if (!isr && !sync_cause)
6824                         return false;
6825         } else {
6826                 *masked = 0;
6827                 isr = REG_READ(ah, AR_ISR);
6828         }
6829
6830         if (isr) {
6831                 struct ath_hal_5416 *ahp = AH5416(ah);
6832
6833                 if (isr & AR_ISR_BCNMISC) {
6834                         u32 isr2;
6835                         isr2 = REG_READ(ah, AR_ISR_S2);
6836                         if (isr2 & AR_ISR_S2_TIM)
6837                                 mask2 |= ATH9K_INT_TIM;
6838                         if (isr2 & AR_ISR_S2_DTIM)
6839                                 mask2 |= ATH9K_INT_DTIM;
6840                         if (isr2 & AR_ISR_S2_DTIMSYNC)
6841                                 mask2 |= ATH9K_INT_DTIMSYNC;
6842                         if (isr2 & (AR_ISR_S2_CABEND))
6843                                 mask2 |= ATH9K_INT_CABEND;
6844                         if (isr2 & AR_ISR_S2_GTT)
6845                                 mask2 |= ATH9K_INT_GTT;
6846                         if (isr2 & AR_ISR_S2_CST)
6847                                 mask2 |= ATH9K_INT_CST;
6848                 }
6849
6850                 isr = REG_READ(ah, AR_ISR_RAC);
6851                 if (isr == 0xffffffff) {
6852                         *masked = 0;
6853                         return false;
6854                 }
6855
6856                 *masked = isr & ATH9K_INT_COMMON;
6857
6858                 if (ahp->ah_intrMitigation) {
6859
6860                         if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM))
6861                                 *masked |= ATH9K_INT_RX;
6862                 }
6863
6864                 if (isr & (AR_ISR_RXOK | AR_ISR_RXERR))
6865                         *masked |= ATH9K_INT_RX;
6866                 if (isr &
6867                     (AR_ISR_TXOK | AR_ISR_TXDESC | AR_ISR_TXERR |
6868                      AR_ISR_TXEOL)) {
6869                         u32 s0_s, s1_s;
6870
6871                         *masked |= ATH9K_INT_TX;
6872
6873                         s0_s = REG_READ(ah, AR_ISR_S0_S);
6874                         ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXOK);
6875                         ahp->ah_intrTxqs |= MS(s0_s, AR_ISR_S0_QCU_TXDESC);
6876
6877                         s1_s = REG_READ(ah, AR_ISR_S1_S);
6878                         ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXERR);
6879                         ahp->ah_intrTxqs |= MS(s1_s, AR_ISR_S1_QCU_TXEOL);
6880                 }
6881
6882                 if (isr & AR_ISR_RXORN) {
6883                         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6884                                  "%s: receive FIFO overrun interrupt\n",
6885                                  __func__);
6886                 }
6887
6888                 if (!AR_SREV_9100(ah)) {
6889                         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
6890                                 u32 isr5 = REG_READ(ah, AR_ISR_S5_S);
6891                                 if (isr5 & AR_ISR_S5_TIM_TIMER)
6892                                         *masked |= ATH9K_INT_TIM_TIMER;
6893                         }
6894                 }
6895
6896                 *masked |= mask2;
6897         }
6898         if (AR_SREV_9100(ah))
6899                 return true;
6900         if (sync_cause) {
6901                 fatal_int =
6902                         (sync_cause &
6903                          (AR_INTR_SYNC_HOST1_FATAL | AR_INTR_SYNC_HOST1_PERR))
6904                         ? true : false;
6905
6906                 if (fatal_int) {
6907                         if (sync_cause & AR_INTR_SYNC_HOST1_FATAL) {
6908                                 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6909                                          "%s: received PCI FATAL interrupt\n",
6910                                          __func__);
6911                         }
6912                         if (sync_cause & AR_INTR_SYNC_HOST1_PERR) {
6913                                 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
6914                                          "%s: received PCI PERR interrupt\n",
6915                                          __func__);
6916                         }
6917                 }
6918                 if (sync_cause & AR_INTR_SYNC_RADM_CPL_TIMEOUT) {
6919                         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6920                                  "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
6921                                  __func__);
6922                         REG_WRITE(ah, AR_RC, AR_RC_HOSTIF);
6923                         REG_WRITE(ah, AR_RC, 0);
6924                         *masked |= ATH9K_INT_FATAL;
6925                 }
6926                 if (sync_cause & AR_INTR_SYNC_LOCAL_TIMEOUT) {
6927                         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
6928                                  "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
6929                                  __func__);
6930                 }
6931
6932                 REG_WRITE(ah, AR_INTR_SYNC_CAUSE_CLR, sync_cause);
6933                 (void) REG_READ(ah, AR_INTR_SYNC_CAUSE_CLR);
6934         }
6935         return true;
6936 }
6937
6938 enum ath9k_int ath9k_hw_intrget(struct ath_hal *ah)
6939 {
6940         return AH5416(ah)->ah_maskReg;
6941 }
6942
6943 enum ath9k_int ath9k_hw_set_interrupts(struct ath_hal *ah, enum ath9k_int ints)
6944 {
6945         struct ath_hal_5416 *ahp = AH5416(ah);
6946         u32 omask = ahp->ah_maskReg;
6947         u32 mask, mask2;
6948         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
6949
6950         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: 0x%x => 0x%x\n", __func__,
6951                  omask, ints);
6952
6953         if (omask & ATH9K_INT_GLOBAL) {
6954                 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: disable IER\n",
6955                          __func__);
6956                 REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
6957                 (void) REG_READ(ah, AR_IER);
6958                 if (!AR_SREV_9100(ah)) {
6959                         REG_WRITE(ah, AR_INTR_ASYNC_ENABLE, 0);
6960                         (void) REG_READ(ah, AR_INTR_ASYNC_ENABLE);
6961
6962                         REG_WRITE(ah, AR_INTR_SYNC_ENABLE, 0);
6963                         (void) REG_READ(ah, AR_INTR_SYNC_ENABLE);
6964                 }
6965         }
6966
6967         mask = ints & ATH9K_INT_COMMON;
6968         mask2 = 0;
6969
6970         if (ints & ATH9K_INT_TX) {
6971                 if (ahp->ah_txOkInterruptMask)
6972                         mask |= AR_IMR_TXOK;
6973                 if (ahp->ah_txDescInterruptMask)
6974                         mask |= AR_IMR_TXDESC;
6975                 if (ahp->ah_txErrInterruptMask)
6976                         mask |= AR_IMR_TXERR;
6977                 if (ahp->ah_txEolInterruptMask)
6978                         mask |= AR_IMR_TXEOL;
6979         }
6980         if (ints & ATH9K_INT_RX) {
6981                 mask |= AR_IMR_RXERR;
6982                 if (ahp->ah_intrMitigation)
6983                         mask |= AR_IMR_RXMINTR | AR_IMR_RXINTM;
6984                 else
6985                         mask |= AR_IMR_RXOK | AR_IMR_RXDESC;
6986                 if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
6987                         mask |= AR_IMR_GENTMR;
6988         }
6989
6990         if (ints & (ATH9K_INT_BMISC)) {
6991                 mask |= AR_IMR_BCNMISC;
6992                 if (ints & ATH9K_INT_TIM)
6993                         mask2 |= AR_IMR_S2_TIM;
6994                 if (ints & ATH9K_INT_DTIM)
6995                         mask2 |= AR_IMR_S2_DTIM;
6996                 if (ints & ATH9K_INT_DTIMSYNC)
6997                         mask2 |= AR_IMR_S2_DTIMSYNC;
6998                 if (ints & ATH9K_INT_CABEND)
6999                         mask2 |= (AR_IMR_S2_CABEND);
7000         }
7001
7002         if (ints & (ATH9K_INT_GTT | ATH9K_INT_CST)) {
7003                 mask |= AR_IMR_BCNMISC;
7004                 if (ints & ATH9K_INT_GTT)
7005                         mask2 |= AR_IMR_S2_GTT;
7006                 if (ints & ATH9K_INT_CST)
7007                         mask2 |= AR_IMR_S2_CST;
7008         }
7009
7010         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: new IMR 0x%x\n", __func__,
7011                  mask);
7012         REG_WRITE(ah, AR_IMR, mask);
7013         mask = REG_READ(ah, AR_IMR_S2) & ~(AR_IMR_S2_TIM |
7014                                            AR_IMR_S2_DTIM |
7015                                            AR_IMR_S2_DTIMSYNC |
7016                                            AR_IMR_S2_CABEND |
7017                                            AR_IMR_S2_CABTO |
7018                                            AR_IMR_S2_TSFOOR |
7019                                            AR_IMR_S2_GTT | AR_IMR_S2_CST);
7020         REG_WRITE(ah, AR_IMR_S2, mask | mask2);
7021         ahp->ah_maskReg = ints;
7022
7023         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)) {
7024                 if (ints & ATH9K_INT_TIM_TIMER)
7025                         REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7026                 else
7027                         REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
7028         }
7029
7030         if (ints & ATH9K_INT_GLOBAL) {
7031                 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "%s: enable IER\n",
7032                          __func__);
7033                 REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
7034                 if (!AR_SREV_9100(ah)) {
7035                         REG_WRITE(ah, AR_INTR_ASYNC_ENABLE,
7036                                   AR_INTR_MAC_IRQ);
7037                         REG_WRITE(ah, AR_INTR_ASYNC_MASK, AR_INTR_MAC_IRQ);
7038
7039
7040                         REG_WRITE(ah, AR_INTR_SYNC_ENABLE,
7041                                   AR_INTR_SYNC_DEFAULT);
7042                         REG_WRITE(ah, AR_INTR_SYNC_MASK,
7043                                   AR_INTR_SYNC_DEFAULT);
7044                 }
7045                 DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT, "AR_IMR 0x%x IER 0x%x\n",
7046                          REG_READ(ah, AR_IMR), REG_READ(ah, AR_IER));
7047         }
7048
7049         return omask;
7050 }
7051
7052 void
7053 ath9k_hw_beaconinit(struct ath_hal *ah,
7054                     u32 next_beacon, u32 beacon_period)
7055 {
7056         struct ath_hal_5416 *ahp = AH5416(ah);
7057         int flags = 0;
7058
7059         ahp->ah_beaconInterval = beacon_period;
7060
7061         switch (ah->ah_opmode) {
7062         case ATH9K_M_STA:
7063         case ATH9K_M_MONITOR:
7064                 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7065                 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT, 0xffff);
7066                 REG_WRITE(ah, AR_NEXT_SWBA, 0x7ffff);
7067                 flags |= AR_TBTT_TIMER_EN;
7068                 break;
7069         case ATH9K_M_IBSS:
7070                 REG_SET_BIT(ah, AR_TXCFG,
7071                             AR_TXCFG_ADHOC_BEACON_ATIM_TX_POLICY);
7072                 REG_WRITE(ah, AR_NEXT_NDP_TIMER,
7073                           TU_TO_USEC(next_beacon +
7074                                      (ahp->ah_atimWindow ? ahp->
7075                                       ah_atimWindow : 1)));
7076                 flags |= AR_NDP_TIMER_EN;
7077         case ATH9K_M_HOSTAP:
7078                 REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(next_beacon));
7079                 REG_WRITE(ah, AR_NEXT_DMA_BEACON_ALERT,
7080                           TU_TO_USEC(next_beacon -
7081                                      ah->ah_config.
7082                                      dma_beacon_response_time));
7083                 REG_WRITE(ah, AR_NEXT_SWBA,
7084                           TU_TO_USEC(next_beacon -
7085                                      ah->ah_config.
7086                                      sw_beacon_response_time));
7087                 flags |=
7088                         AR_TBTT_TIMER_EN | AR_DBA_TIMER_EN | AR_SWBA_TIMER_EN;
7089                 break;
7090         }
7091
7092         REG_WRITE(ah, AR_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7093         REG_WRITE(ah, AR_DMA_BEACON_PERIOD, TU_TO_USEC(beacon_period));
7094         REG_WRITE(ah, AR_SWBA_PERIOD, TU_TO_USEC(beacon_period));
7095         REG_WRITE(ah, AR_NDP_PERIOD, TU_TO_USEC(beacon_period));
7096
7097         beacon_period &= ~ATH9K_BEACON_ENA;
7098         if (beacon_period & ATH9K_BEACON_RESET_TSF) {
7099                 beacon_period &= ~ATH9K_BEACON_RESET_TSF;
7100                 ath9k_hw_reset_tsf(ah);
7101         }
7102
7103         REG_SET_BIT(ah, AR_TIMER_MODE, flags);
7104 }
7105
7106 void
7107 ath9k_hw_set_sta_beacon_timers(struct ath_hal *ah,
7108                                const struct ath9k_beacon_state *bs)
7109 {
7110         u32 nextTbtt, beaconintval, dtimperiod, beacontimeout;
7111         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7112
7113         REG_WRITE(ah, AR_NEXT_TBTT_TIMER, TU_TO_USEC(bs->bs_nexttbtt));
7114
7115         REG_WRITE(ah, AR_BEACON_PERIOD,
7116                   TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7117         REG_WRITE(ah, AR_DMA_BEACON_PERIOD,
7118                   TU_TO_USEC(bs->bs_intval & ATH9K_BEACON_PERIOD));
7119
7120         REG_RMW_FIELD(ah, AR_RSSI_THR,
7121                       AR_RSSI_THR_BM_THR, bs->bs_bmissthreshold);
7122
7123         beaconintval = bs->bs_intval & ATH9K_BEACON_PERIOD;
7124
7125         if (bs->bs_sleepduration > beaconintval)
7126                 beaconintval = bs->bs_sleepduration;
7127
7128         dtimperiod = bs->bs_dtimperiod;
7129         if (bs->bs_sleepduration > dtimperiod)
7130                 dtimperiod = bs->bs_sleepduration;
7131
7132         if (beaconintval == dtimperiod)
7133                 nextTbtt = bs->bs_nextdtim;
7134         else
7135                 nextTbtt = bs->bs_nexttbtt;
7136
7137         DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next DTIM %d\n", __func__,
7138                  bs->bs_nextdtim);
7139         DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: next beacon %d\n", __func__,
7140                  nextTbtt);
7141         DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: beacon period %d\n", __func__,
7142                  beaconintval);
7143         DPRINTF(ah->ah_sc, ATH_DBG_BEACON, "%s: DTIM period %d\n", __func__,
7144                  dtimperiod);
7145
7146         REG_WRITE(ah, AR_NEXT_DTIM,
7147                   TU_TO_USEC(bs->bs_nextdtim - SLEEP_SLOP));
7148         REG_WRITE(ah, AR_NEXT_TIM, TU_TO_USEC(nextTbtt - SLEEP_SLOP));
7149
7150         REG_WRITE(ah, AR_SLEEP1,
7151                   SM((CAB_TIMEOUT_VAL << 3), AR_SLEEP1_CAB_TIMEOUT)
7152                   | AR_SLEEP1_ASSUME_DTIM);
7153
7154         if (pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP)
7155                 beacontimeout = (BEACON_TIMEOUT_VAL << 3);
7156         else
7157                 beacontimeout = MIN_BEACON_TIMEOUT_VAL;
7158
7159         REG_WRITE(ah, AR_SLEEP2,
7160                   SM(beacontimeout, AR_SLEEP2_BEACON_TIMEOUT));
7161
7162         REG_WRITE(ah, AR_TIM_PERIOD, TU_TO_USEC(beaconintval));
7163         REG_WRITE(ah, AR_DTIM_PERIOD, TU_TO_USEC(dtimperiod));
7164
7165         REG_SET_BIT(ah, AR_TIMER_MODE,
7166                     AR_TBTT_TIMER_EN | AR_TIM_TIMER_EN |
7167                     AR_DTIM_TIMER_EN);
7168
7169 }
7170
7171 bool ath9k_hw_keyisvalid(struct ath_hal *ah, u16 entry)
7172 {
7173         if (entry < ah->ah_caps.keycache_size) {
7174                 u32 val = REG_READ(ah, AR_KEYTABLE_MAC1(entry));
7175                 if (val & AR_KEYTABLE_VALID)
7176                         return true;
7177         }
7178         return false;
7179 }
7180
7181 bool ath9k_hw_keyreset(struct ath_hal *ah, u16 entry)
7182 {
7183         u32 keyType;
7184
7185         if (entry >= ah->ah_caps.keycache_size) {
7186                 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7187                          "%s: entry %u out of range\n", __func__, entry);
7188                 return false;
7189         }
7190         keyType = REG_READ(ah, AR_KEYTABLE_TYPE(entry));
7191
7192         REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), 0);
7193         REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), 0);
7194         REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), 0);
7195         REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), 0);
7196         REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), 0);
7197         REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), AR_KEYTABLE_TYPE_CLR);
7198         REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), 0);
7199         REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), 0);
7200
7201         if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7202                 u16 micentry = entry + 64;
7203
7204                 REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), 0);
7205                 REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7206                 REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), 0);
7207                 REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7208
7209         }
7210
7211         if (ah->ah_curchan == NULL)
7212                 return true;
7213
7214         return true;
7215 }
7216
7217 bool
7218 ath9k_hw_keysetmac(struct ath_hal *ah, u16 entry,
7219                    const u8 *mac)
7220 {
7221         u32 macHi, macLo;
7222
7223         if (entry >= ah->ah_caps.keycache_size) {
7224                 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7225                          "%s: entry %u out of range\n", __func__, entry);
7226                 return false;
7227         }
7228
7229         if (mac != NULL) {
7230                 macHi = (mac[5] << 8) | mac[4];
7231                 macLo = (mac[3] << 24) | (mac[2] << 16)
7232                         | (mac[1] << 8) | mac[0];
7233                 macLo >>= 1;
7234                 macLo |= (macHi & 1) << 31;
7235                 macHi >>= 1;
7236         } else {
7237                 macLo = macHi = 0;
7238         }
7239         REG_WRITE(ah, AR_KEYTABLE_MAC0(entry), macLo);
7240         REG_WRITE(ah, AR_KEYTABLE_MAC1(entry), macHi | AR_KEYTABLE_VALID);
7241
7242         return true;
7243 }
7244
7245 bool
7246 ath9k_hw_set_keycache_entry(struct ath_hal *ah, u16 entry,
7247                             const struct ath9k_keyval *k,
7248                             const u8 *mac, int xorKey)
7249 {
7250         const struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7251         u32 key0, key1, key2, key3, key4;
7252         u32 keyType;
7253         u32 xorMask = xorKey ?
7254                 (ATH9K_KEY_XOR << 24 | ATH9K_KEY_XOR << 16 | ATH9K_KEY_XOR << 8
7255                  | ATH9K_KEY_XOR) : 0;
7256         struct ath_hal_5416 *ahp = AH5416(ah);
7257
7258         if (entry >= pCap->keycache_size) {
7259                 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7260                          "%s: entry %u out of range\n", __func__, entry);
7261                 return false;
7262         }
7263         switch (k->kv_type) {
7264         case ATH9K_CIPHER_AES_OCB:
7265                 keyType = AR_KEYTABLE_TYPE_AES;
7266                 break;
7267         case ATH9K_CIPHER_AES_CCM:
7268                 if (!(pCap->hw_caps & ATH9K_HW_CAP_CIPHER_AESCCM)) {
7269                         DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7270                                  "%s: AES-CCM not supported by "
7271                                  "mac rev 0x%x\n", __func__,
7272                                  ah->ah_macRev);
7273                         return false;
7274                 }
7275                 keyType = AR_KEYTABLE_TYPE_CCM;
7276                 break;
7277         case ATH9K_CIPHER_TKIP:
7278                 keyType = AR_KEYTABLE_TYPE_TKIP;
7279                 if (ATH9K_IS_MIC_ENABLED(ah)
7280                     && entry + 64 >= pCap->keycache_size) {
7281                         DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7282                                  "%s: entry %u inappropriate for TKIP\n",
7283                                  __func__, entry);
7284                         return false;
7285                 }
7286                 break;
7287         case ATH9K_CIPHER_WEP:
7288                 if (k->kv_len < LEN_WEP40) {
7289                         DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7290                                  "%s: WEP key length %u too small\n",
7291                                  __func__, k->kv_len);
7292                         return false;
7293                 }
7294                 if (k->kv_len <= LEN_WEP40)
7295                         keyType = AR_KEYTABLE_TYPE_40;
7296                 else if (k->kv_len <= LEN_WEP104)
7297                         keyType = AR_KEYTABLE_TYPE_104;
7298                 else
7299                         keyType = AR_KEYTABLE_TYPE_128;
7300                 break;
7301         case ATH9K_CIPHER_CLR:
7302                 keyType = AR_KEYTABLE_TYPE_CLR;
7303                 break;
7304         default:
7305                 DPRINTF(ah->ah_sc, ATH_DBG_KEYCACHE,
7306                          "%s: cipher %u not supported\n", __func__,
7307                          k->kv_type);
7308                 return false;
7309         }
7310
7311         key0 = get_unaligned_le32(k->kv_val + 0) ^ xorMask;
7312         key1 = (get_unaligned_le16(k->kv_val + 4) ^ xorMask) & 0xffff;
7313         key2 = get_unaligned_le32(k->kv_val + 6) ^ xorMask;
7314         key3 = (get_unaligned_le16(k->kv_val + 10) ^ xorMask) & 0xffff;
7315         key4 = get_unaligned_le32(k->kv_val + 12) ^ xorMask;
7316         if (k->kv_len <= LEN_WEP104)
7317                 key4 &= 0xff;
7318
7319         if (keyType == AR_KEYTABLE_TYPE_TKIP && ATH9K_IS_MIC_ENABLED(ah)) {
7320                 u16 micentry = entry + 64;
7321
7322                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), ~key0);
7323                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), ~key1);
7324                 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7325                 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7326                 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7327                 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7328                 (void) ath9k_hw_keysetmac(ah, entry, mac);
7329
7330                 if (ahp->ah_miscMode & AR_PCU_MIC_NEW_LOC_ENA) {
7331                         u32 mic0, mic1, mic2, mic3, mic4;
7332
7333                         mic0 = get_unaligned_le32(k->kv_mic + 0);
7334                         mic2 = get_unaligned_le32(k->kv_mic + 4);
7335                         mic1 = get_unaligned_le16(k->kv_txmic + 2) & 0xffff;
7336                         mic3 = get_unaligned_le16(k->kv_txmic + 0) & 0xffff;
7337                         mic4 = get_unaligned_le32(k->kv_txmic + 4);
7338                         REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7339                         REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), mic1);
7340                         REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7341                         REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), mic3);
7342                         REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), mic4);
7343                         REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7344                                   AR_KEYTABLE_TYPE_CLR);
7345
7346                 } else {
7347                         u32 mic0, mic2;
7348
7349                         mic0 = get_unaligned_le32(k->kv_mic + 0);
7350                         mic2 = get_unaligned_le32(k->kv_mic + 4);
7351                         REG_WRITE(ah, AR_KEYTABLE_KEY0(micentry), mic0);
7352                         REG_WRITE(ah, AR_KEYTABLE_KEY1(micentry), 0);
7353                         REG_WRITE(ah, AR_KEYTABLE_KEY2(micentry), mic2);
7354                         REG_WRITE(ah, AR_KEYTABLE_KEY3(micentry), 0);
7355                         REG_WRITE(ah, AR_KEYTABLE_KEY4(micentry), 0);
7356                         REG_WRITE(ah, AR_KEYTABLE_TYPE(micentry),
7357                                   AR_KEYTABLE_TYPE_CLR);
7358                 }
7359                 REG_WRITE(ah, AR_KEYTABLE_MAC0(micentry), 0);
7360                 REG_WRITE(ah, AR_KEYTABLE_MAC1(micentry), 0);
7361                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7362                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7363         } else {
7364                 REG_WRITE(ah, AR_KEYTABLE_KEY0(entry), key0);
7365                 REG_WRITE(ah, AR_KEYTABLE_KEY1(entry), key1);
7366                 REG_WRITE(ah, AR_KEYTABLE_KEY2(entry), key2);
7367                 REG_WRITE(ah, AR_KEYTABLE_KEY3(entry), key3);
7368                 REG_WRITE(ah, AR_KEYTABLE_KEY4(entry), key4);
7369                 REG_WRITE(ah, AR_KEYTABLE_TYPE(entry), keyType);
7370
7371                 (void) ath9k_hw_keysetmac(ah, entry, mac);
7372         }
7373
7374         if (ah->ah_curchan == NULL)
7375                 return true;
7376
7377         return true;
7378 }
7379
7380 bool
7381 ath9k_hw_updatetxtriglevel(struct ath_hal *ah, bool bIncTrigLevel)
7382 {
7383         struct ath_hal_5416 *ahp = AH5416(ah);
7384         u32 txcfg, curLevel, newLevel;
7385         enum ath9k_int omask;
7386
7387         if (ah->ah_txTrigLevel >= MAX_TX_FIFO_THRESHOLD)
7388                 return false;
7389
7390         omask = ath9k_hw_set_interrupts(ah,
7391                                         ahp->ah_maskReg & ~ATH9K_INT_GLOBAL);
7392
7393         txcfg = REG_READ(ah, AR_TXCFG);
7394         curLevel = MS(txcfg, AR_FTRIG);
7395         newLevel = curLevel;
7396         if (bIncTrigLevel) {
7397                 if (curLevel < MAX_TX_FIFO_THRESHOLD)
7398                         newLevel++;
7399         } else if (curLevel > MIN_TX_FIFO_THRESHOLD)
7400                 newLevel--;
7401         if (newLevel != curLevel)
7402                 REG_WRITE(ah, AR_TXCFG,
7403                           (txcfg & ~AR_FTRIG) | SM(newLevel, AR_FTRIG));
7404
7405         ath9k_hw_set_interrupts(ah, omask);
7406
7407         ah->ah_txTrigLevel = newLevel;
7408
7409         return newLevel != curLevel;
7410 }
7411
7412 bool ath9k_hw_set_txq_props(struct ath_hal *ah, int q,
7413                             const struct ath9k_tx_queue_info *qinfo)
7414 {
7415         u32 cw;
7416         struct ath_hal_5416 *ahp = AH5416(ah);
7417         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7418         struct ath9k_tx_queue_info *qi;
7419
7420         if (q >= pCap->total_queues) {
7421                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7422                          __func__, q);
7423                 return false;
7424         }
7425
7426         qi = &ahp->ah_txq[q];
7427         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7428                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7429                          __func__);
7430                 return false;
7431         }
7432
7433         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %p\n", __func__, qi);
7434
7435         qi->tqi_ver = qinfo->tqi_ver;
7436         qi->tqi_subtype = qinfo->tqi_subtype;
7437         qi->tqi_qflags = qinfo->tqi_qflags;
7438         qi->tqi_priority = qinfo->tqi_priority;
7439         if (qinfo->tqi_aifs != ATH9K_TXQ_USEDEFAULT)
7440                 qi->tqi_aifs = min(qinfo->tqi_aifs, 255U);
7441         else
7442                 qi->tqi_aifs = INIT_AIFS;
7443         if (qinfo->tqi_cwmin != ATH9K_TXQ_USEDEFAULT) {
7444                 cw = min(qinfo->tqi_cwmin, 1024U);
7445                 qi->tqi_cwmin = 1;
7446                 while (qi->tqi_cwmin < cw)
7447                         qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
7448         } else
7449                 qi->tqi_cwmin = qinfo->tqi_cwmin;
7450         if (qinfo->tqi_cwmax != ATH9K_TXQ_USEDEFAULT) {
7451                 cw = min(qinfo->tqi_cwmax, 1024U);
7452                 qi->tqi_cwmax = 1;
7453                 while (qi->tqi_cwmax < cw)
7454                         qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
7455         } else
7456                 qi->tqi_cwmax = INIT_CWMAX;
7457
7458         if (qinfo->tqi_shretry != 0)
7459                 qi->tqi_shretry = min((u32) qinfo->tqi_shretry, 15U);
7460         else
7461                 qi->tqi_shretry = INIT_SH_RETRY;
7462         if (qinfo->tqi_lgretry != 0)
7463                 qi->tqi_lgretry = min((u32) qinfo->tqi_lgretry, 15U);
7464         else
7465                 qi->tqi_lgretry = INIT_LG_RETRY;
7466         qi->tqi_cbrPeriod = qinfo->tqi_cbrPeriod;
7467         qi->tqi_cbrOverflowLimit = qinfo->tqi_cbrOverflowLimit;
7468         qi->tqi_burstTime = qinfo->tqi_burstTime;
7469         qi->tqi_readyTime = qinfo->tqi_readyTime;
7470
7471         switch (qinfo->tqi_subtype) {
7472         case ATH9K_WME_UPSD:
7473                 if (qi->tqi_type == ATH9K_TX_QUEUE_DATA)
7474                         qi->tqi_intFlags = ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS;
7475                 break;
7476         default:
7477                 break;
7478         }
7479         return true;
7480 }
7481
7482 bool ath9k_hw_get_txq_props(struct ath_hal *ah, int q,
7483                             struct ath9k_tx_queue_info *qinfo)
7484 {
7485         struct ath_hal_5416 *ahp = AH5416(ah);
7486         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7487         struct ath9k_tx_queue_info *qi;
7488
7489         if (q >= pCap->total_queues) {
7490                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7491                          __func__, q);
7492                 return false;
7493         }
7494
7495         qi = &ahp->ah_txq[q];
7496         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7497                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue\n",
7498                          __func__);
7499                 return false;
7500         }
7501
7502         qinfo->tqi_qflags = qi->tqi_qflags;
7503         qinfo->tqi_ver = qi->tqi_ver;
7504         qinfo->tqi_subtype = qi->tqi_subtype;
7505         qinfo->tqi_qflags = qi->tqi_qflags;
7506         qinfo->tqi_priority = qi->tqi_priority;
7507         qinfo->tqi_aifs = qi->tqi_aifs;
7508         qinfo->tqi_cwmin = qi->tqi_cwmin;
7509         qinfo->tqi_cwmax = qi->tqi_cwmax;
7510         qinfo->tqi_shretry = qi->tqi_shretry;
7511         qinfo->tqi_lgretry = qi->tqi_lgretry;
7512         qinfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
7513         qinfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
7514         qinfo->tqi_burstTime = qi->tqi_burstTime;
7515         qinfo->tqi_readyTime = qi->tqi_readyTime;
7516
7517         return true;
7518 }
7519
7520 int
7521 ath9k_hw_setuptxqueue(struct ath_hal *ah, enum ath9k_tx_queue type,
7522                       const struct ath9k_tx_queue_info *qinfo)
7523 {
7524         struct ath_hal_5416 *ahp = AH5416(ah);
7525         struct ath9k_tx_queue_info *qi;
7526         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7527         int q;
7528
7529         switch (type) {
7530         case ATH9K_TX_QUEUE_BEACON:
7531                 q = pCap->total_queues - 1;
7532                 break;
7533         case ATH9K_TX_QUEUE_CAB:
7534                 q = pCap->total_queues - 2;
7535                 break;
7536         case ATH9K_TX_QUEUE_PSPOLL:
7537                 q = 1;
7538                 break;
7539         case ATH9K_TX_QUEUE_UAPSD:
7540                 q = pCap->total_queues - 3;
7541                 break;
7542         case ATH9K_TX_QUEUE_DATA:
7543                 for (q = 0; q < pCap->total_queues; q++)
7544                         if (ahp->ah_txq[q].tqi_type ==
7545                             ATH9K_TX_QUEUE_INACTIVE)
7546                                 break;
7547                 if (q == pCap->total_queues) {
7548                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7549                                  "%s: no available tx queue\n", __func__);
7550                         return -1;
7551                 }
7552                 break;
7553         default:
7554                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: bad tx queue type %u\n",
7555                          __func__, type);
7556                 return -1;
7557         }
7558
7559         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
7560
7561         qi = &ahp->ah_txq[q];
7562         if (qi->tqi_type != ATH9K_TX_QUEUE_INACTIVE) {
7563                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
7564                          "%s: tx queue %u already active\n", __func__, q);
7565                 return -1;
7566         }
7567         memset(qi, 0, sizeof(struct ath9k_tx_queue_info));
7568         qi->tqi_type = type;
7569         if (qinfo == NULL) {
7570                 qi->tqi_qflags =
7571                         TXQ_FLAG_TXOKINT_ENABLE
7572                         | TXQ_FLAG_TXERRINT_ENABLE
7573                         | TXQ_FLAG_TXDESCINT_ENABLE | TXQ_FLAG_TXURNINT_ENABLE;
7574                 qi->tqi_aifs = INIT_AIFS;
7575                 qi->tqi_cwmin = ATH9K_TXQ_USEDEFAULT;
7576                 qi->tqi_cwmax = INIT_CWMAX;
7577                 qi->tqi_shretry = INIT_SH_RETRY;
7578                 qi->tqi_lgretry = INIT_LG_RETRY;
7579                 qi->tqi_physCompBuf = 0;
7580         } else {
7581                 qi->tqi_physCompBuf = qinfo->tqi_physCompBuf;
7582                 (void) ath9k_hw_set_txq_props(ah, q, qinfo);
7583         }
7584
7585         return q;
7586 }
7587
7588 static void
7589 ath9k_hw_set_txq_interrupts(struct ath_hal *ah,
7590                             struct ath9k_tx_queue_info *qi)
7591 {
7592         struct ath_hal_5416 *ahp = AH5416(ah);
7593
7594         DPRINTF(ah->ah_sc, ATH_DBG_INTERRUPT,
7595                  "%s: tx ok 0x%x err 0x%x desc 0x%x eol 0x%x urn 0x%x\n",
7596                  __func__, ahp->ah_txOkInterruptMask,
7597                  ahp->ah_txErrInterruptMask, ahp->ah_txDescInterruptMask,
7598                  ahp->ah_txEolInterruptMask, ahp->ah_txUrnInterruptMask);
7599
7600         REG_WRITE(ah, AR_IMR_S0,
7601                   SM(ahp->ah_txOkInterruptMask, AR_IMR_S0_QCU_TXOK)
7602                   | SM(ahp->ah_txDescInterruptMask, AR_IMR_S0_QCU_TXDESC));
7603         REG_WRITE(ah, AR_IMR_S1,
7604                   SM(ahp->ah_txErrInterruptMask, AR_IMR_S1_QCU_TXERR)
7605                   | SM(ahp->ah_txEolInterruptMask, AR_IMR_S1_QCU_TXEOL));
7606         REG_RMW_FIELD(ah, AR_IMR_S2,
7607                       AR_IMR_S2_QCU_TXURN, ahp->ah_txUrnInterruptMask);
7608 }
7609
7610 bool ath9k_hw_releasetxqueue(struct ath_hal *ah, u32 q)
7611 {
7612         struct ath_hal_5416 *ahp = AH5416(ah);
7613         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7614         struct ath9k_tx_queue_info *qi;
7615
7616         if (q >= pCap->total_queues) {
7617                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7618                          __func__, q);
7619                 return false;
7620         }
7621         qi = &ahp->ah_txq[q];
7622         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7623                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7624                          __func__, q);
7625                 return false;
7626         }
7627
7628         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: release queue %u\n",
7629                 __func__, q);
7630
7631         qi->tqi_type = ATH9K_TX_QUEUE_INACTIVE;
7632         ahp->ah_txOkInterruptMask &= ~(1 << q);
7633         ahp->ah_txErrInterruptMask &= ~(1 << q);
7634         ahp->ah_txDescInterruptMask &= ~(1 << q);
7635         ahp->ah_txEolInterruptMask &= ~(1 << q);
7636         ahp->ah_txUrnInterruptMask &= ~(1 << q);
7637         ath9k_hw_set_txq_interrupts(ah, qi);
7638
7639         return true;
7640 }
7641
7642 bool ath9k_hw_resettxqueue(struct ath_hal *ah, u32 q)
7643 {
7644         struct ath_hal_5416 *ahp = AH5416(ah);
7645         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
7646         struct ath9k_channel *chan = ah->ah_curchan;
7647         struct ath9k_tx_queue_info *qi;
7648         u32 cwMin, chanCwMin, value;
7649
7650         if (q >= pCap->total_queues) {
7651                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: invalid queue num %u\n",
7652                          __func__, q);
7653                 return false;
7654         }
7655         qi = &ahp->ah_txq[q];
7656         if (qi->tqi_type == ATH9K_TX_QUEUE_INACTIVE) {
7657                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: inactive queue %u\n",
7658                          __func__, q);
7659                 return true;
7660         }
7661
7662         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: reset queue %u\n", __func__, q);
7663
7664         if (qi->tqi_cwmin == ATH9K_TXQ_USEDEFAULT) {
7665                 if (chan && IS_CHAN_B(chan))
7666                         chanCwMin = INIT_CWMIN_11B;
7667                 else
7668                         chanCwMin = INIT_CWMIN;
7669
7670                 for (cwMin = 1; cwMin < chanCwMin; cwMin = (cwMin << 1) | 1);
7671         } else
7672                 cwMin = qi->tqi_cwmin;
7673
7674         REG_WRITE(ah, AR_DLCL_IFS(q), SM(cwMin, AR_D_LCL_IFS_CWMIN)
7675                   | SM(qi->tqi_cwmax, AR_D_LCL_IFS_CWMAX)
7676                   | SM(qi->tqi_aifs, AR_D_LCL_IFS_AIFS));
7677
7678         REG_WRITE(ah, AR_DRETRY_LIMIT(q),
7679                   SM(INIT_SSH_RETRY, AR_D_RETRY_LIMIT_STA_SH)
7680                   | SM(INIT_SLG_RETRY, AR_D_RETRY_LIMIT_STA_LG)
7681                   | SM(qi->tqi_shretry, AR_D_RETRY_LIMIT_FR_SH)
7682                 );
7683
7684         REG_WRITE(ah, AR_QMISC(q), AR_Q_MISC_DCU_EARLY_TERM_REQ);
7685         REG_WRITE(ah, AR_DMISC(q),
7686                   AR_D_MISC_CW_BKOFF_EN | AR_D_MISC_FRAG_WAIT_EN | 0x2);
7687
7688         if (qi->tqi_cbrPeriod) {
7689                 REG_WRITE(ah, AR_QCBRCFG(q),
7690                           SM(qi->tqi_cbrPeriod, AR_Q_CBRCFG_INTERVAL)
7691                           | SM(qi->tqi_cbrOverflowLimit,
7692                                AR_Q_CBRCFG_OVF_THRESH));
7693                 REG_WRITE(ah, AR_QMISC(q),
7694                           REG_READ(ah,
7695                                    AR_QMISC(q)) | AR_Q_MISC_FSP_CBR | (qi->
7696                                         tqi_cbrOverflowLimit
7697                                         ?
7698                                         AR_Q_MISC_CBR_EXP_CNTR_LIMIT_EN
7699                                         :
7700                                         0));
7701         }
7702         if (qi->tqi_readyTime && (qi->tqi_type != ATH9K_TX_QUEUE_CAB)) {
7703                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7704                           SM(qi->tqi_readyTime, AR_Q_RDYTIMECFG_DURATION) |
7705                           AR_Q_RDYTIMECFG_EN);
7706         }
7707
7708         REG_WRITE(ah, AR_DCHNTIME(q),
7709                   SM(qi->tqi_burstTime, AR_D_CHNTIME_DUR) |
7710                   (qi->tqi_burstTime ? AR_D_CHNTIME_EN : 0));
7711
7712         if (qi->tqi_burstTime
7713             && (qi->tqi_qflags & TXQ_FLAG_RDYTIME_EXP_POLICY_ENABLE)) {
7714                 REG_WRITE(ah, AR_QMISC(q),
7715                           REG_READ(ah,
7716                                    AR_QMISC(q)) |
7717                           AR_Q_MISC_RDYTIME_EXP_POLICY);
7718
7719         }
7720
7721         if (qi->tqi_qflags & TXQ_FLAG_BACKOFF_DISABLE) {
7722                 REG_WRITE(ah, AR_DMISC(q),
7723                           REG_READ(ah, AR_DMISC(q)) |
7724                           AR_D_MISC_POST_FR_BKOFF_DIS);
7725         }
7726         if (qi->tqi_qflags & TXQ_FLAG_FRAG_BURST_BACKOFF_ENABLE) {
7727                 REG_WRITE(ah, AR_DMISC(q),
7728                           REG_READ(ah, AR_DMISC(q)) |
7729                           AR_D_MISC_FRAG_BKOFF_EN);
7730         }
7731         switch (qi->tqi_type) {
7732         case ATH9K_TX_QUEUE_BEACON:
7733                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7734                           | AR_Q_MISC_FSP_DBA_GATED
7735                           | AR_Q_MISC_BEACON_USE
7736                           | AR_Q_MISC_CBR_INCR_DIS1);
7737
7738                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7739                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7740                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S)
7741                           | AR_D_MISC_BEACON_USE
7742                           | AR_D_MISC_POST_FR_BKOFF_DIS);
7743                 break;
7744         case ATH9K_TX_QUEUE_CAB:
7745                 REG_WRITE(ah, AR_QMISC(q), REG_READ(ah, AR_QMISC(q))
7746                           | AR_Q_MISC_FSP_DBA_GATED
7747                           | AR_Q_MISC_CBR_INCR_DIS1
7748                           | AR_Q_MISC_CBR_INCR_DIS0);
7749                 value = (qi->tqi_readyTime
7750                          - (ah->ah_config.sw_beacon_response_time -
7751                             ah->ah_config.dma_beacon_response_time)
7752                          -
7753                          ah->ah_config.additional_swba_backoff) *
7754                         1024;
7755                 REG_WRITE(ah, AR_QRDYTIMECFG(q),
7756                           value | AR_Q_RDYTIMECFG_EN);
7757                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7758                           | (AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL <<
7759                              AR_D_MISC_ARB_LOCKOUT_CNTRL_S));
7760                 break;
7761         case ATH9K_TX_QUEUE_PSPOLL:
7762                 REG_WRITE(ah, AR_QMISC(q),
7763                           REG_READ(ah,
7764                                    AR_QMISC(q)) | AR_Q_MISC_CBR_INCR_DIS1);
7765                 break;
7766         case ATH9K_TX_QUEUE_UAPSD:
7767                 REG_WRITE(ah, AR_DMISC(q), REG_READ(ah, AR_DMISC(q))
7768                           | AR_D_MISC_POST_FR_BKOFF_DIS);
7769                 break;
7770         default:
7771                 break;
7772         }
7773
7774         if (qi->tqi_intFlags & ATH9K_TXQ_USE_LOCKOUT_BKOFF_DIS) {
7775                 REG_WRITE(ah, AR_DMISC(q),
7776                           REG_READ(ah, AR_DMISC(q)) |
7777                           SM(AR_D_MISC_ARB_LOCKOUT_CNTRL_GLOBAL,
7778                              AR_D_MISC_ARB_LOCKOUT_CNTRL) |
7779                           AR_D_MISC_POST_FR_BKOFF_DIS);
7780         }
7781
7782         if (qi->tqi_qflags & TXQ_FLAG_TXOKINT_ENABLE)
7783                 ahp->ah_txOkInterruptMask |= 1 << q;
7784         else
7785                 ahp->ah_txOkInterruptMask &= ~(1 << q);
7786         if (qi->tqi_qflags & TXQ_FLAG_TXERRINT_ENABLE)
7787                 ahp->ah_txErrInterruptMask |= 1 << q;
7788         else
7789                 ahp->ah_txErrInterruptMask &= ~(1 << q);
7790         if (qi->tqi_qflags & TXQ_FLAG_TXDESCINT_ENABLE)
7791                 ahp->ah_txDescInterruptMask |= 1 << q;
7792         else
7793                 ahp->ah_txDescInterruptMask &= ~(1 << q);
7794         if (qi->tqi_qflags & TXQ_FLAG_TXEOLINT_ENABLE)
7795                 ahp->ah_txEolInterruptMask |= 1 << q;
7796         else
7797                 ahp->ah_txEolInterruptMask &= ~(1 << q);
7798         if (qi->tqi_qflags & TXQ_FLAG_TXURNINT_ENABLE)
7799                 ahp->ah_txUrnInterruptMask |= 1 << q;
7800         else
7801                 ahp->ah_txUrnInterruptMask &= ~(1 << q);
7802         ath9k_hw_set_txq_interrupts(ah, qi);
7803
7804         return true;
7805 }
7806
7807 void ath9k_hw_gettxintrtxqs(struct ath_hal *ah, u32 *txqs)
7808 {
7809         struct ath_hal_5416 *ahp = AH5416(ah);
7810         *txqs &= ahp->ah_intrTxqs;
7811         ahp->ah_intrTxqs &= ~(*txqs);
7812 }
7813
7814 bool
7815 ath9k_hw_filltxdesc(struct ath_hal *ah, struct ath_desc *ds,
7816                     u32 segLen, bool firstSeg,
7817                     bool lastSeg, const struct ath_desc *ds0)
7818 {
7819         struct ar5416_desc *ads = AR5416DESC(ds);
7820
7821         if (firstSeg) {
7822                 ads->ds_ctl1 |= segLen | (lastSeg ? 0 : AR_TxMore);
7823         } else if (lastSeg) {
7824                 ads->ds_ctl0 = 0;
7825                 ads->ds_ctl1 = segLen;
7826                 ads->ds_ctl2 = AR5416DESC_CONST(ds0)->ds_ctl2;
7827                 ads->ds_ctl3 = AR5416DESC_CONST(ds0)->ds_ctl3;
7828         } else {
7829                 ads->ds_ctl0 = 0;
7830                 ads->ds_ctl1 = segLen | AR_TxMore;
7831                 ads->ds_ctl2 = 0;
7832                 ads->ds_ctl3 = 0;
7833         }
7834         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7835         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7836         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7837         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7838         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7839         return true;
7840 }
7841
7842 void ath9k_hw_cleartxdesc(struct ath_hal *ah, struct ath_desc *ds)
7843 {
7844         struct ar5416_desc *ads = AR5416DESC(ds);
7845
7846         ads->ds_txstatus0 = ads->ds_txstatus1 = 0;
7847         ads->ds_txstatus2 = ads->ds_txstatus3 = 0;
7848         ads->ds_txstatus4 = ads->ds_txstatus5 = 0;
7849         ads->ds_txstatus6 = ads->ds_txstatus7 = 0;
7850         ads->ds_txstatus8 = ads->ds_txstatus9 = 0;
7851 }
7852
7853 int
7854 ath9k_hw_txprocdesc(struct ath_hal *ah, struct ath_desc *ds)
7855 {
7856         struct ar5416_desc *ads = AR5416DESC(ds);
7857
7858         if ((ads->ds_txstatus9 & AR_TxDone) == 0)
7859                 return -EINPROGRESS;
7860
7861         ds->ds_txstat.ts_seqnum = MS(ads->ds_txstatus9, AR_SeqNum);
7862         ds->ds_txstat.ts_tstamp = ads->AR_SendTimestamp;
7863         ds->ds_txstat.ts_status = 0;
7864         ds->ds_txstat.ts_flags = 0;
7865
7866         if (ads->ds_txstatus1 & AR_ExcessiveRetries)
7867                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XRETRY;
7868         if (ads->ds_txstatus1 & AR_Filtered)
7869                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FILT;
7870         if (ads->ds_txstatus1 & AR_FIFOUnderrun)
7871                 ds->ds_txstat.ts_status |= ATH9K_TXERR_FIFO;
7872         if (ads->ds_txstatus9 & AR_TxOpExceeded)
7873                 ds->ds_txstat.ts_status |= ATH9K_TXERR_XTXOP;
7874         if (ads->ds_txstatus1 & AR_TxTimerExpired)
7875                 ds->ds_txstat.ts_status |= ATH9K_TXERR_TIMER_EXPIRED;
7876
7877         if (ads->ds_txstatus1 & AR_DescCfgErr)
7878                 ds->ds_txstat.ts_flags |= ATH9K_TX_DESC_CFG_ERR;
7879         if (ads->ds_txstatus1 & AR_TxDataUnderrun) {
7880                 ds->ds_txstat.ts_flags |= ATH9K_TX_DATA_UNDERRUN;
7881                 ath9k_hw_updatetxtriglevel(ah, true);
7882         }
7883         if (ads->ds_txstatus1 & AR_TxDelimUnderrun) {
7884                 ds->ds_txstat.ts_flags |= ATH9K_TX_DELIM_UNDERRUN;
7885                 ath9k_hw_updatetxtriglevel(ah, true);
7886         }
7887         if (ads->ds_txstatus0 & AR_TxBaStatus) {
7888                 ds->ds_txstat.ts_flags |= ATH9K_TX_BA;
7889                 ds->ds_txstat.ba_low = ads->AR_BaBitmapLow;
7890                 ds->ds_txstat.ba_high = ads->AR_BaBitmapHigh;
7891         }
7892
7893         ds->ds_txstat.ts_rateindex = MS(ads->ds_txstatus9, AR_FinalTxIdx);
7894         switch (ds->ds_txstat.ts_rateindex) {
7895         case 0:
7896                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate0);
7897                 break;
7898         case 1:
7899                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate1);
7900                 break;
7901         case 2:
7902                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate2);
7903                 break;
7904         case 3:
7905                 ds->ds_txstat.ts_ratecode = MS(ads->ds_ctl3, AR_XmitRate3);
7906                 break;
7907         }
7908
7909         ds->ds_txstat.ts_rssi = MS(ads->ds_txstatus5, AR_TxRSSICombined);
7910         ds->ds_txstat.ts_rssi_ctl0 = MS(ads->ds_txstatus0, AR_TxRSSIAnt00);
7911         ds->ds_txstat.ts_rssi_ctl1 = MS(ads->ds_txstatus0, AR_TxRSSIAnt01);
7912         ds->ds_txstat.ts_rssi_ctl2 = MS(ads->ds_txstatus0, AR_TxRSSIAnt02);
7913         ds->ds_txstat.ts_rssi_ext0 = MS(ads->ds_txstatus5, AR_TxRSSIAnt10);
7914         ds->ds_txstat.ts_rssi_ext1 = MS(ads->ds_txstatus5, AR_TxRSSIAnt11);
7915         ds->ds_txstat.ts_rssi_ext2 = MS(ads->ds_txstatus5, AR_TxRSSIAnt12);
7916         ds->ds_txstat.evm0 = ads->AR_TxEVM0;
7917         ds->ds_txstat.evm1 = ads->AR_TxEVM1;
7918         ds->ds_txstat.evm2 = ads->AR_TxEVM2;
7919         ds->ds_txstat.ts_shortretry = MS(ads->ds_txstatus1, AR_RTSFailCnt);
7920         ds->ds_txstat.ts_longretry = MS(ads->ds_txstatus1, AR_DataFailCnt);
7921         ds->ds_txstat.ts_virtcol = MS(ads->ds_txstatus1, AR_VirtRetryCnt);
7922         ds->ds_txstat.ts_antenna = 1;
7923
7924         return 0;
7925 }
7926
7927 void
7928 ath9k_hw_set11n_txdesc(struct ath_hal *ah, struct ath_desc *ds,
7929                        u32 pktLen, enum ath9k_pkt_type type, u32 txPower,
7930                        u32 keyIx, enum ath9k_key_type keyType, u32 flags)
7931 {
7932         struct ar5416_desc *ads = AR5416DESC(ds);
7933         struct ath_hal_5416 *ahp = AH5416(ah);
7934
7935         txPower += ahp->ah_txPowerIndexOffset;
7936         if (txPower > 63)
7937                 txPower = 63;
7938
7939         ads->ds_ctl0 = (pktLen & AR_FrameLen)
7940                 | (flags & ATH9K_TXDESC_VMF ? AR_VirtMoreFrag : 0)
7941                 | SM(txPower, AR_XmitPower)
7942                 | (flags & ATH9K_TXDESC_VEOL ? AR_VEOL : 0)
7943                 | (flags & ATH9K_TXDESC_CLRDMASK ? AR_ClrDestMask : 0)
7944                 | (flags & ATH9K_TXDESC_INTREQ ? AR_TxIntrReq : 0)
7945                 | (keyIx != ATH9K_TXKEYIX_INVALID ? AR_DestIdxValid : 0);
7946
7947         ads->ds_ctl1 =
7948                 (keyIx != ATH9K_TXKEYIX_INVALID ? SM(keyIx, AR_DestIdx) : 0)
7949                 | SM(type, AR_FrameType)
7950                 | (flags & ATH9K_TXDESC_NOACK ? AR_NoAck : 0)
7951                 | (flags & ATH9K_TXDESC_EXT_ONLY ? AR_ExtOnly : 0)
7952                 | (flags & ATH9K_TXDESC_EXT_AND_CTL ? AR_ExtAndCtl : 0);
7953
7954         ads->ds_ctl6 = SM(keyType, AR_EncrType);
7955
7956         if (AR_SREV_9285(ah)) {
7957
7958                 ads->ds_ctl8 = 0;
7959                 ads->ds_ctl9 = 0;
7960                 ads->ds_ctl10 = 0;
7961                 ads->ds_ctl11 = 0;
7962         }
7963 }
7964
7965 void
7966 ath9k_hw_set11n_ratescenario(struct ath_hal *ah, struct ath_desc *ds,
7967                              struct ath_desc *lastds,
7968                              u32 durUpdateEn, u32 rtsctsRate,
7969                              u32 rtsctsDuration,
7970                              struct ath9k_11n_rate_series series[],
7971                              u32 nseries, u32 flags)
7972 {
7973         struct ar5416_desc *ads = AR5416DESC(ds);
7974         struct ar5416_desc *last_ads = AR5416DESC(lastds);
7975         u32 ds_ctl0;
7976
7977         (void) nseries;
7978         (void) rtsctsDuration;
7979
7980         if (flags & (ATH9K_TXDESC_RTSENA | ATH9K_TXDESC_CTSENA)) {
7981                 ds_ctl0 = ads->ds_ctl0;
7982
7983                 if (flags & ATH9K_TXDESC_RTSENA) {
7984                         ds_ctl0 &= ~AR_CTSEnable;
7985                         ds_ctl0 |= AR_RTSEnable;
7986                 } else {
7987                         ds_ctl0 &= ~AR_RTSEnable;
7988                         ds_ctl0 |= AR_CTSEnable;
7989                 }
7990
7991                 ads->ds_ctl0 = ds_ctl0;
7992         } else {
7993                 ads->ds_ctl0 =
7994                         (ads->ds_ctl0 & ~(AR_RTSEnable | AR_CTSEnable));
7995         }
7996
7997         ads->ds_ctl2 = set11nTries(series, 0)
7998                 | set11nTries(series, 1)
7999                 | set11nTries(series, 2)
8000                 | set11nTries(series, 3)
8001                 | (durUpdateEn ? AR_DurUpdateEna : 0)
8002                 | SM(0, AR_BurstDur);
8003
8004         ads->ds_ctl3 = set11nRate(series, 0)
8005                 | set11nRate(series, 1)
8006                 | set11nRate(series, 2)
8007                 | set11nRate(series, 3);
8008
8009         ads->ds_ctl4 = set11nPktDurRTSCTS(series, 0)
8010                 | set11nPktDurRTSCTS(series, 1);
8011
8012         ads->ds_ctl5 = set11nPktDurRTSCTS(series, 2)
8013                 | set11nPktDurRTSCTS(series, 3);
8014
8015         ads->ds_ctl7 = set11nRateFlags(series, 0)
8016                 | set11nRateFlags(series, 1)
8017                 | set11nRateFlags(series, 2)
8018                 | set11nRateFlags(series, 3)
8019                 | SM(rtsctsRate, AR_RTSCTSRate);
8020         last_ads->ds_ctl2 = ads->ds_ctl2;
8021         last_ads->ds_ctl3 = ads->ds_ctl3;
8022 }
8023
8024 void
8025 ath9k_hw_set11n_aggr_first(struct ath_hal *ah, struct ath_desc *ds,
8026                            u32 aggrLen)
8027 {
8028         struct ar5416_desc *ads = AR5416DESC(ds);
8029
8030         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8031
8032         ads->ds_ctl6 &= ~AR_AggrLen;
8033         ads->ds_ctl6 |= SM(aggrLen, AR_AggrLen);
8034 }
8035
8036 void
8037 ath9k_hw_set11n_aggr_middle(struct ath_hal *ah, struct ath_desc *ds,
8038                             u32 numDelims)
8039 {
8040         struct ar5416_desc *ads = AR5416DESC(ds);
8041         unsigned int ctl6;
8042
8043         ads->ds_ctl1 |= (AR_IsAggr | AR_MoreAggr);
8044
8045         ctl6 = ads->ds_ctl6;
8046         ctl6 &= ~AR_PadDelim;
8047         ctl6 |= SM(numDelims, AR_PadDelim);
8048         ads->ds_ctl6 = ctl6;
8049 }
8050
8051 void ath9k_hw_set11n_aggr_last(struct ath_hal *ah, struct ath_desc *ds)
8052 {
8053         struct ar5416_desc *ads = AR5416DESC(ds);
8054
8055         ads->ds_ctl1 |= AR_IsAggr;
8056         ads->ds_ctl1 &= ~AR_MoreAggr;
8057         ads->ds_ctl6 &= ~AR_PadDelim;
8058 }
8059
8060 void ath9k_hw_clr11n_aggr(struct ath_hal *ah, struct ath_desc *ds)
8061 {
8062         struct ar5416_desc *ads = AR5416DESC(ds);
8063
8064         ads->ds_ctl1 &= (~AR_IsAggr & ~AR_MoreAggr);
8065 }
8066
8067 void
8068 ath9k_hw_set11n_burstduration(struct ath_hal *ah, struct ath_desc *ds,
8069                               u32 burstDuration)
8070 {
8071         struct ar5416_desc *ads = AR5416DESC(ds);
8072
8073         ads->ds_ctl2 &= ~AR_BurstDur;
8074         ads->ds_ctl2 |= SM(burstDuration, AR_BurstDur);
8075 }
8076
8077 void
8078 ath9k_hw_set11n_virtualmorefrag(struct ath_hal *ah, struct ath_desc *ds,
8079                                 u32 vmf)
8080 {
8081         struct ar5416_desc *ads = AR5416DESC(ds);
8082
8083         if (vmf)
8084                 ads->ds_ctl0 |= AR_VirtMoreFrag;
8085         else
8086                 ads->ds_ctl0 &= ~AR_VirtMoreFrag;
8087 }
8088
8089 void ath9k_hw_putrxbuf(struct ath_hal *ah, u32 rxdp)
8090 {
8091         REG_WRITE(ah, AR_RXDP, rxdp);
8092 }
8093
8094 void ath9k_hw_rxena(struct ath_hal *ah)
8095 {
8096         REG_WRITE(ah, AR_CR, AR_CR_RXE);
8097 }
8098
8099 bool ath9k_hw_setrxabort(struct ath_hal *ah, bool set)
8100 {
8101         if (set) {
8102
8103                 REG_SET_BIT(ah, AR_DIAG_SW,
8104                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8105
8106                 if (!ath9k_hw_wait
8107                     (ah, AR_OBS_BUS_1, AR_OBS_BUS_1_RX_STATE, 0)) {
8108                         u32 reg;
8109
8110                         REG_CLR_BIT(ah, AR_DIAG_SW,
8111                                     (AR_DIAG_RX_DIS |
8112                                      AR_DIAG_RX_ABORT));
8113
8114                         reg = REG_READ(ah, AR_OBS_BUS_1);
8115                         DPRINTF(ah->ah_sc, ATH_DBG_FATAL,
8116                                 "%s: rx failed to go idle in 10 ms RXSM=0x%x\n",
8117                                 __func__, reg);
8118
8119                         return false;
8120                 }
8121         } else {
8122                 REG_CLR_BIT(ah, AR_DIAG_SW,
8123                             (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
8124         }
8125
8126         return true;
8127 }
8128
8129 void
8130 ath9k_hw_setmcastfilter(struct ath_hal *ah, u32 filter0,
8131                         u32 filter1)
8132 {
8133         REG_WRITE(ah, AR_MCAST_FIL0, filter0);
8134         REG_WRITE(ah, AR_MCAST_FIL1, filter1);
8135 }
8136
8137 bool
8138 ath9k_hw_setuprxdesc(struct ath_hal *ah, struct ath_desc *ds,
8139                      u32 size, u32 flags)
8140 {
8141         struct ar5416_desc *ads = AR5416DESC(ds);
8142         struct ath9k_hw_capabilities *pCap = &ah->ah_caps;
8143
8144         ads->ds_ctl1 = size & AR_BufLen;
8145         if (flags & ATH9K_RXDESC_INTREQ)
8146                 ads->ds_ctl1 |= AR_RxIntrReq;
8147
8148         ads->ds_rxstatus8 &= ~AR_RxDone;
8149         if (!(pCap->hw_caps & ATH9K_HW_CAP_AUTOSLEEP))
8150                 memset(&(ads->u), 0, sizeof(ads->u));
8151         return true;
8152 }
8153
8154 int
8155 ath9k_hw_rxprocdesc(struct ath_hal *ah, struct ath_desc *ds,
8156                     u32 pa, struct ath_desc *nds, u64 tsf)
8157 {
8158         struct ar5416_desc ads;
8159         struct ar5416_desc *adsp = AR5416DESC(ds);
8160
8161         if ((adsp->ds_rxstatus8 & AR_RxDone) == 0)
8162                 return -EINPROGRESS;
8163
8164         ads.u.rx = adsp->u.rx;
8165
8166         ds->ds_rxstat.rs_status = 0;
8167         ds->ds_rxstat.rs_flags = 0;
8168
8169         ds->ds_rxstat.rs_datalen = ads.ds_rxstatus1 & AR_DataLen;
8170         ds->ds_rxstat.rs_tstamp = ads.AR_RcvTimestamp;
8171
8172         ds->ds_rxstat.rs_rssi = MS(ads.ds_rxstatus4, AR_RxRSSICombined);
8173         ds->ds_rxstat.rs_rssi_ctl0 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt00);
8174         ds->ds_rxstat.rs_rssi_ctl1 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt01);
8175         ds->ds_rxstat.rs_rssi_ctl2 = MS(ads.ds_rxstatus0, AR_RxRSSIAnt02);
8176         ds->ds_rxstat.rs_rssi_ext0 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt10);
8177         ds->ds_rxstat.rs_rssi_ext1 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt11);
8178         ds->ds_rxstat.rs_rssi_ext2 = MS(ads.ds_rxstatus4, AR_RxRSSIAnt12);
8179         if (ads.ds_rxstatus8 & AR_RxKeyIdxValid)
8180                 ds->ds_rxstat.rs_keyix = MS(ads.ds_rxstatus8, AR_KeyIdx);
8181         else
8182                 ds->ds_rxstat.rs_keyix = ATH9K_RXKEYIX_INVALID;
8183
8184         ds->ds_rxstat.rs_rate = RXSTATUS_RATE(ah, (&ads));
8185         ds->ds_rxstat.rs_more = (ads.ds_rxstatus1 & AR_RxMore) ? 1 : 0;
8186
8187         ds->ds_rxstat.rs_isaggr = (ads.ds_rxstatus8 & AR_RxAggr) ? 1 : 0;
8188         ds->ds_rxstat.rs_moreaggr =
8189                 (ads.ds_rxstatus8 & AR_RxMoreAggr) ? 1 : 0;
8190         ds->ds_rxstat.rs_antenna = MS(ads.ds_rxstatus3, AR_RxAntenna);
8191         ds->ds_rxstat.rs_flags =
8192                 (ads.ds_rxstatus3 & AR_GI) ? ATH9K_RX_GI : 0;
8193         ds->ds_rxstat.rs_flags |=
8194                 (ads.ds_rxstatus3 & AR_2040) ? ATH9K_RX_2040 : 0;
8195
8196         if (ads.ds_rxstatus8 & AR_PreDelimCRCErr)
8197                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_PRE;
8198         if (ads.ds_rxstatus8 & AR_PostDelimCRCErr)
8199                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DELIM_CRC_POST;
8200         if (ads.ds_rxstatus8 & AR_DecryptBusyErr)
8201                 ds->ds_rxstat.rs_flags |= ATH9K_RX_DECRYPT_BUSY;
8202
8203         if ((ads.ds_rxstatus8 & AR_RxFrameOK) == 0) {
8204
8205                 if (ads.ds_rxstatus8 & AR_CRCErr)
8206                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_CRC;
8207                 else if (ads.ds_rxstatus8 & AR_PHYErr) {
8208                         u32 phyerr;
8209
8210                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_PHY;
8211                         phyerr = MS(ads.ds_rxstatus8, AR_PHYErrCode);
8212                         ds->ds_rxstat.rs_phyerr = phyerr;
8213                 } else if (ads.ds_rxstatus8 & AR_DecryptCRCErr)
8214                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_DECRYPT;
8215                 else if (ads.ds_rxstatus8 & AR_MichaelErr)
8216                         ds->ds_rxstat.rs_status |= ATH9K_RXERR_MIC;
8217         }
8218
8219         return 0;
8220 }
8221
8222 static void ath9k_hw_setup_rate_table(struct ath_hal *ah,
8223                                       struct ath9k_rate_table *rt)
8224 {
8225         int i;
8226
8227         if (rt->rateCodeToIndex[0] != 0)
8228                 return;
8229         for (i = 0; i < 256; i++)
8230                 rt->rateCodeToIndex[i] = (u8) -1;
8231         for (i = 0; i < rt->rateCount; i++) {
8232                 u8 code = rt->info[i].rateCode;
8233                 u8 cix = rt->info[i].controlRate;
8234
8235                 rt->rateCodeToIndex[code] = i;
8236                 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
8237
8238                 rt->info[i].lpAckDuration =
8239                         ath9k_hw_computetxtime(ah, rt,
8240                                                WLAN_CTRL_FRAME_SIZE,
8241                                                cix,
8242                                                false);
8243                 rt->info[i].spAckDuration =
8244                         ath9k_hw_computetxtime(ah, rt,
8245                                                WLAN_CTRL_FRAME_SIZE,
8246                                                cix,
8247                                                true);
8248         }
8249 }
8250
8251 const struct ath9k_rate_table *ath9k_hw_getratetable(struct ath_hal *ah,
8252                                                    u32 mode)
8253 {
8254         struct ath9k_rate_table *rt;
8255         switch (mode) {
8256         case ATH9K_MODE_11A:
8257                 rt = &ar5416_11a_table;
8258                 break;
8259         case ATH9K_MODE_11B:
8260                 rt = &ar5416_11b_table;
8261                 break;
8262         case ATH9K_MODE_11G:
8263                 rt = &ar5416_11g_table;
8264                 break;
8265         case ATH9K_MODE_11NG_HT20:
8266         case ATH9K_MODE_11NG_HT40PLUS:
8267         case ATH9K_MODE_11NG_HT40MINUS:
8268                 rt = &ar5416_11ng_table;
8269                 break;
8270         case ATH9K_MODE_11NA_HT20:
8271         case ATH9K_MODE_11NA_HT40PLUS:
8272         case ATH9K_MODE_11NA_HT40MINUS:
8273                 rt = &ar5416_11na_table;
8274                 break;
8275         default:
8276                 DPRINTF(ah->ah_sc, ATH_DBG_CHANNEL, "%s: invalid mode 0x%x\n",
8277                          __func__, mode);
8278                 return NULL;
8279         }
8280         ath9k_hw_setup_rate_table(ah, rt);
8281         return rt;
8282 }
8283
8284 static const char *ath9k_hw_devname(u16 devid)
8285 {
8286         switch (devid) {
8287         case AR5416_DEVID_PCI:
8288         case AR5416_DEVID_PCIE:
8289                 return "Atheros 5416";
8290         case AR9160_DEVID_PCI:
8291                 return "Atheros 9160";
8292         case AR9280_DEVID_PCI:
8293         case AR9280_DEVID_PCIE:
8294                 return "Atheros 9280";
8295         }
8296         return NULL;
8297 }
8298
8299 const char *ath9k_hw_probe(u16 vendorid, u16 devid)
8300 {
8301         return vendorid == ATHEROS_VENDOR_ID ?
8302                 ath9k_hw_devname(devid) : NULL;
8303 }
8304
8305 struct ath_hal *ath9k_hw_attach(u16 devid,
8306                                 struct ath_softc *sc,
8307                                 void __iomem *mem,
8308                                 int *error)
8309 {
8310         struct ath_hal *ah = NULL;
8311
8312         switch (devid) {
8313         case AR5416_DEVID_PCI:
8314         case AR5416_DEVID_PCIE:
8315         case AR9160_DEVID_PCI:
8316         case AR9280_DEVID_PCI:
8317         case AR9280_DEVID_PCIE:
8318                 ah = ath9k_hw_do_attach(devid, sc, mem, error);
8319                 break;
8320         default:
8321                 DPRINTF(ah->ah_sc, ATH_DBG_ANY,
8322                          "devid=0x%x not supported.\n", devid);
8323                 ah = NULL;
8324                 *error = -ENXIO;
8325                 break;
8326         }
8327         if (ah != NULL) {
8328                 ah->ah_devid = ah->ah_devid;
8329                 ah->ah_subvendorid = ah->ah_subvendorid;
8330                 ah->ah_macVersion = ah->ah_macVersion;
8331                 ah->ah_macRev = ah->ah_macRev;
8332                 ah->ah_phyRev = ah->ah_phyRev;
8333                 ah->ah_analog5GhzRev = ah->ah_analog5GhzRev;
8334                 ah->ah_analog2GhzRev = ah->ah_analog2GhzRev;
8335         }
8336         return ah;
8337 }
8338
8339 u16
8340 ath9k_hw_computetxtime(struct ath_hal *ah,
8341                        const struct ath9k_rate_table *rates,
8342                        u32 frameLen, u16 rateix,
8343                        bool shortPreamble)
8344 {
8345         u32 bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
8346         u32 kbps;
8347
8348         kbps = rates->info[rateix].rateKbps;
8349
8350         if (kbps == 0)
8351                 return 0;
8352         switch (rates->info[rateix].phy) {
8353
8354         case PHY_CCK:
8355                 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
8356                 if (shortPreamble && rates->info[rateix].shortPreamble)
8357                         phyTime >>= 1;
8358                 numBits = frameLen << 3;
8359                 txTime = CCK_SIFS_TIME + phyTime
8360                         + ((numBits * 1000) / kbps);
8361                 break;
8362         case PHY_OFDM:
8363                 if (ah->ah_curchan && IS_CHAN_QUARTER_RATE(ah->ah_curchan)) {
8364                         bitsPerSymbol =
8365                                 (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
8366
8367                         numBits = OFDM_PLCP_BITS + (frameLen << 3);
8368                         numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8369                         txTime = OFDM_SIFS_TIME_QUARTER
8370                                 + OFDM_PREAMBLE_TIME_QUARTER
8371                                 + (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
8372                 } else if (ah->ah_curchan &&
8373                            IS_CHAN_HALF_RATE(ah->ah_curchan)) {
8374                         bitsPerSymbol =
8375                                 (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
8376
8377                         numBits = OFDM_PLCP_BITS + (frameLen << 3);
8378                         numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8379                         txTime = OFDM_SIFS_TIME_HALF +
8380                                 OFDM_PREAMBLE_TIME_HALF
8381                                 + (numSymbols * OFDM_SYMBOL_TIME_HALF);
8382                 } else {
8383                         bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
8384
8385                         numBits = OFDM_PLCP_BITS + (frameLen << 3);
8386                         numSymbols = DIV_ROUND_UP(numBits, bitsPerSymbol);
8387                         txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
8388                                 + (numSymbols * OFDM_SYMBOL_TIME);
8389                 }
8390                 break;
8391
8392         default:
8393                 DPRINTF(ah->ah_sc, ATH_DBG_PHY_IO,
8394                          "%s: unknown phy %u (rate ix %u)\n", __func__,
8395                          rates->info[rateix].phy, rateix);
8396                 txTime = 0;
8397                 break;
8398         }
8399         return txTime;
8400 }
8401
8402 u32 ath9k_hw_mhz2ieee(struct ath_hal *ah, u32 freq, u32 flags)
8403 {
8404         if (flags & CHANNEL_2GHZ) {
8405                 if (freq == 2484)
8406                         return 14;
8407                 if (freq < 2484)
8408                         return (freq - 2407) / 5;
8409                 else
8410                         return 15 + ((freq - 2512) / 20);
8411         } else if (flags & CHANNEL_5GHZ) {
8412                 if (ath9k_regd_is_public_safety_sku(ah) &&
8413                     IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8414                         return ((freq * 10) +
8415                                 (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
8416                 } else if ((flags & CHANNEL_A) && (freq <= 5000)) {
8417                         return (freq - 4000) / 5;
8418                 } else {
8419                         return (freq - 5000) / 5;
8420                 }
8421         } else {
8422                 if (freq == 2484)
8423                         return 14;
8424                 if (freq < 2484)
8425                         return (freq - 2407) / 5;
8426                 if (freq < 5000) {
8427                         if (ath9k_regd_is_public_safety_sku(ah)
8428                             && IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
8429                                 return ((freq * 10) +
8430                                         (((freq % 5) ==
8431                                           2) ? 5 : 0) - 49400) / 5;
8432                         } else if (freq > 4900) {
8433                                 return (freq - 4000) / 5;
8434                         } else {
8435                                 return 15 + ((freq - 2512) / 20);
8436                         }
8437                 }
8438                 return (freq - 5000) / 5;
8439         }
8440 }
8441
8442 int16_t
8443 ath9k_hw_getchan_noise(struct ath_hal *ah, struct ath9k_channel *chan)
8444 {
8445         struct ath9k_channel *ichan;
8446
8447         ichan = ath9k_regd_check_channel(ah, chan);
8448         if (ichan == NULL) {
8449                 DPRINTF(ah->ah_sc, ATH_DBG_NF_CAL,
8450                          "%s: invalid channel %u/0x%x; no mapping\n",
8451                          __func__, chan->channel, chan->channelFlags);
8452                 return 0;
8453         }
8454         if (ichan->rawNoiseFloor == 0) {
8455                 enum wireless_mode mode = ath9k_hw_chan2wmode(ah, chan);
8456                 return NOISE_FLOOR[mode];
8457         } else
8458                 return ichan->rawNoiseFloor;
8459 }
8460
8461 bool ath9k_hw_set_tsfadjust(struct ath_hal *ah, u32 setting)
8462 {
8463         struct ath_hal_5416 *ahp = AH5416(ah);
8464
8465         if (setting)
8466                 ahp->ah_miscMode |= AR_PCU_TX_ADD_TSF;
8467         else
8468                 ahp->ah_miscMode &= ~AR_PCU_TX_ADD_TSF;
8469         return true;
8470 }
8471
8472 bool ath9k_hw_phycounters(struct ath_hal *ah)
8473 {
8474         struct ath_hal_5416 *ahp = AH5416(ah);
8475
8476         return ahp->ah_hasHwPhyCounters ? true : false;
8477 }
8478
8479 u32 ath9k_hw_gettxbuf(struct ath_hal *ah, u32 q)
8480 {
8481         return REG_READ(ah, AR_QTXDP(q));
8482 }
8483
8484 bool ath9k_hw_puttxbuf(struct ath_hal *ah, u32 q,
8485                        u32 txdp)
8486 {
8487         REG_WRITE(ah, AR_QTXDP(q), txdp);
8488
8489         return true;
8490 }
8491
8492 bool ath9k_hw_txstart(struct ath_hal *ah, u32 q)
8493 {
8494         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE, "%s: queue %u\n", __func__, q);
8495
8496         REG_WRITE(ah, AR_Q_TXE, 1 << q);
8497
8498         return true;
8499 }
8500
8501 u32 ath9k_hw_numtxpending(struct ath_hal *ah, u32 q)
8502 {
8503         u32 npend;
8504
8505         npend = REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT;
8506         if (npend == 0) {
8507
8508                 if (REG_READ(ah, AR_Q_TXE) & (1 << q))
8509                         npend = 1;
8510         }
8511         return npend;
8512 }
8513
8514 bool ath9k_hw_stoptxdma(struct ath_hal *ah, u32 q)
8515 {
8516         u32 wait;
8517
8518         REG_WRITE(ah, AR_Q_TXD, 1 << q);
8519
8520         for (wait = 1000; wait != 0; wait--) {
8521                 if (ath9k_hw_numtxpending(ah, q) == 0)
8522                         break;
8523                 udelay(100);
8524         }
8525
8526         if (ath9k_hw_numtxpending(ah, q)) {
8527                 u32 tsfLow, j;
8528
8529                 DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8530                          "%s: Num of pending TX Frames %d on Q %d\n",
8531                          __func__, ath9k_hw_numtxpending(ah, q), q);
8532
8533                 for (j = 0; j < 2; j++) {
8534                         tsfLow = REG_READ(ah, AR_TSF_L32);
8535                         REG_WRITE(ah, AR_QUIET2,
8536                                   SM(10, AR_QUIET2_QUIET_DUR));
8537                         REG_WRITE(ah, AR_QUIET_PERIOD, 100);
8538                         REG_WRITE(ah, AR_NEXT_QUIET_TIMER, tsfLow >> 10);
8539                         REG_SET_BIT(ah, AR_TIMER_MODE,
8540                                        AR_QUIET_TIMER_EN);
8541
8542                         if ((REG_READ(ah, AR_TSF_L32) >> 10) ==
8543                             (tsfLow >> 10)) {
8544                                 break;
8545                         }
8546                         DPRINTF(ah->ah_sc, ATH_DBG_QUEUE,
8547                                 "%s: TSF have moved while trying to set "
8548                                 "quiet time TSF: 0x%08x\n",
8549                                 __func__, tsfLow);
8550                 }
8551
8552                 REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8553
8554                 udelay(200);
8555                 REG_CLR_BIT(ah, AR_TIMER_MODE, AR_QUIET_TIMER_EN);
8556
8557                 wait = 1000;
8558
8559                 while (ath9k_hw_numtxpending(ah, q)) {
8560                         if ((--wait) == 0) {
8561                                 DPRINTF(ah->ah_sc, ATH_DBG_XMIT,
8562                                         "%s: Failed to stop Tx DMA in 100 "
8563                                         "msec after killing last frame\n",
8564                                         __func__);
8565                                 break;
8566                         }
8567                         udelay(100);
8568                 }
8569
8570                 REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_FORCE_CH_IDLE_HIGH);
8571         }
8572
8573         REG_WRITE(ah, AR_Q_TXD, 0);
8574         return wait != 0;
8575 }