1 --- a/drivers/net/wireless/ath/ath9k/Makefile
2 +++ b/drivers/net/wireless/ath/ath9k/Makefile
3 @@ -32,7 +32,8 @@ ath9k_hw-y:= \
11 obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
13 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
14 +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
15 @@ -67,6 +67,7 @@ static const struct ar9300_eeprom ar9300
16 * bit2 - enable fastClock - enabled
17 * bit3 - enable doubling - enabled
18 * bit4 - enable internal regulator - disabled
19 + * bit5 - enable pa predistortion - disabled
21 .miscConfiguration = 0, /* bit0 - turn down drivestrength */
22 .eepromWriteEnableGpio = 3,
23 @@ -129,9 +130,11 @@ static const struct ar9300_eeprom ar9300
25 .txFrameToXpaOn = 0xe,
27 - .futureModal = { /* [32] */
28 + .papdRateMaskHt20 = LE32(0x80c080),
29 + .papdRateMaskHt40 = LE32(0x80c080),
31 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
32 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
33 + 0, 0, 0, 0, 0, 0, 0, 0
37 @@ -326,9 +329,11 @@ static const struct ar9300_eeprom ar9300
39 .txFrameToXpaOn = 0xe,
41 + .papdRateMaskHt20 = LE32(0xf0e0e0),
42 + .papdRateMaskHt40 = LE32(0xf0e0e0),
44 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
45 - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
46 + 0, 0, 0, 0, 0, 0, 0, 0
50 @@ -644,6 +649,8 @@ static u32 ath9k_hw_ar9300_get_eeprom(st
51 return (pBase->featureEnable & 0x10) >> 4;
53 return le32_to_cpu(pBase->swreg);
55 + return !!(pBase->featureEnable & BIT(5));
59 --- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
60 +++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.h
61 @@ -234,7 +234,9 @@ struct ar9300_modal_eep_header {
66 + __le32 papdRateMaskHt20;
67 + __le32 papdRateMaskHt40;
71 struct ar9300_cal_data_per_freq_op_loop {
72 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
73 +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
74 @@ -470,6 +470,14 @@ static void ar9003_hw_set11n_virtualmore
75 ads->ctl11 &= ~AR_VirtMoreFrag;
78 +void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains)
80 + struct ar9003_txc *ads = ds;
82 + ads->ctl12 |= SM(chains, AR_PAPRDChainMask);
84 +EXPORT_SYMBOL(ar9003_hw_set_paprd_txdesc);
86 void ar9003_hw_attach_mac_ops(struct ath_hw *hw)
88 struct ath_hw_ops *ops = ath9k_hw_ops(hw);
89 --- a/drivers/net/wireless/ath/ath9k/ar9003_mac.h
90 +++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.h
93 #define AR_Not_Sounding 0x20000000
96 +#define AR_PAPRDChainMask 0x00000e00
97 +#define AR_PAPRDChainMask_S 9
99 #define MAP_ISR_S2_CST 6
100 #define MAP_ISR_S2_GTT 6
101 #define MAP_ISR_S2_TIM 3
103 +++ b/drivers/net/wireless/ath/ath9k/ar9003_paprd.c
106 + * Copyright (c) 2010 Atheros Communications Inc.
108 + * Permission to use, copy, modify, and/or distribute this software for any
109 + * purpose with or without fee is hereby granted, provided that the above
110 + * copyright notice and this permission notice appear in all copies.
112 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
113 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
114 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
115 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
116 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
117 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
118 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
122 +#include "ar9003_phy.h"
124 +void ar9003_paprd_enable(struct ath_hw *ah, bool val)
126 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B0,
127 + AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
128 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B1,
129 + AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
130 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL0_B2,
131 + AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE, !!val);
133 +EXPORT_SYMBOL(ar9003_paprd_enable);
135 +static void ar9003_paprd_setup_single_table(struct ath_hw *ah)
137 + struct ar9300_eeprom *eep = &ah->eeprom.ar9300_eep;
138 + struct ar9300_modal_eep_header *hdr;
139 + const u32 ctrl0[3] = {
140 + AR_PHY_PAPRD_CTRL0_B0,
141 + AR_PHY_PAPRD_CTRL0_B1,
142 + AR_PHY_PAPRD_CTRL0_B2
144 + const u32 ctrl1[3] = {
145 + AR_PHY_PAPRD_CTRL1_B0,
146 + AR_PHY_PAPRD_CTRL1_B1,
147 + AR_PHY_PAPRD_CTRL1_B2
149 + u32 am_mask, ht40_mask;
152 + if (ah->curchan && IS_CHAN_5GHZ(ah->curchan))
153 + hdr = &eep->modalHeader5G;
155 + hdr = &eep->modalHeader2G;
157 + am_mask = le32_to_cpu(hdr->papdRateMaskHt20);
158 + ht40_mask = le32_to_cpu(hdr->papdRateMaskHt40);
160 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2AM, AR_PHY_PAPRD_AM2AM_MASK, am_mask);
161 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_AM2PM, AR_PHY_PAPRD_AM2PM_MASK, am_mask);
162 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_HT40, AR_PHY_PAPRD_HT40_MASK, ht40_mask);
164 + for (i = 0; i < 3; i++) {
165 + REG_RMW_FIELD(ah, ctrl0[i],
166 + AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK, 1);
167 + REG_RMW_FIELD(ah, ctrl1[i],
168 + AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE, 1);
169 + REG_RMW_FIELD(ah, ctrl1[i],
170 + AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE, 1);
171 + REG_RMW_FIELD(ah, ctrl1[i],
172 + AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0);
173 + REG_RMW_FIELD(ah, ctrl1[i],
174 + AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK, 181);
175 + REG_RMW_FIELD(ah, ctrl1[i],
176 + AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT, 361);
177 + REG_RMW_FIELD(ah, ctrl1[i],
178 + AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA, 0);
179 + REG_RMW_FIELD(ah, ctrl0[i],
180 + AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH, 3);
183 + ar9003_paprd_enable(ah, false);
185 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
186 + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP, 0x30);
187 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
188 + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE, 1);
189 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
190 + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE, 1);
191 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
192 + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE, 0);
193 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
194 + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE, 0);
195 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
196 + AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING, 28);
197 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL1,
198 + AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE, 1);
199 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL2,
200 + AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN, 147);
201 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
202 + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN, 4);
203 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
204 + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN, 4);
205 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
206 + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES, 7);
207 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
208 + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL, 1);
209 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
210 + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP, -6);
211 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
212 + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE,
214 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL3,
215 + AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE, 1);
216 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
217 + AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA, 0);
218 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
219 + AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR, 400);
220 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_TRAINER_CNTL4,
221 + AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES,
223 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_0_B0,
224 + AR_PHY_PAPRD_PRE_POST_SCALING, 261376);
225 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_1_B0,
226 + AR_PHY_PAPRD_PRE_POST_SCALING, 248079);
227 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_2_B0,
228 + AR_PHY_PAPRD_PRE_POST_SCALING, 233759);
229 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_3_B0,
230 + AR_PHY_PAPRD_PRE_POST_SCALING, 220464);
231 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_4_B0,
232 + AR_PHY_PAPRD_PRE_POST_SCALING, 208194);
233 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_5_B0,
234 + AR_PHY_PAPRD_PRE_POST_SCALING, 196949);
235 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_6_B0,
236 + AR_PHY_PAPRD_PRE_POST_SCALING, 185706);
237 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_PRE_POST_SCALE_7_B0,
238 + AR_PHY_PAPRD_PRE_POST_SCALING, 175487);
241 +static void ar9003_paprd_get_gain_table(struct ath_hw *ah)
243 + u32 *entry = ah->paprd_gain_table_entries;
244 + u8 *index = ah->paprd_gain_table_index;
245 + u32 reg = AR_PHY_TXGAIN_TABLE;
248 + memset(entry, 0, sizeof(ah->paprd_gain_table_entries));
249 + memset(index, 0, sizeof(ah->paprd_gain_table_index));
251 + for (i = 0; i < 32; i++) {
252 + entry[i] = REG_READ(ah, reg);
253 + index[i] = (entry[i] >> 24) & 0xff;
258 +static unsigned int ar9003_get_desired_gain(struct ath_hw *ah, int chain,
261 + int olpc_gain_delta = 0;
262 + int alpha_therm, alpha_volt;
263 + int therm_cal_value, volt_cal_value;
264 + int therm_value, volt_value;
265 + int thermal_gain_corr, voltage_gain_corr;
266 + int desired_scale, desired_gain = 0;
269 + REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
270 + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
271 + desired_scale = REG_READ_FIELD(ah, AR_PHY_TPC_12,
272 + AR_PHY_TPC_12_DESIRED_SCALE_HT40_5);
273 + alpha_therm = REG_READ_FIELD(ah, AR_PHY_TPC_19,
274 + AR_PHY_TPC_19_ALPHA_THERM);
275 + alpha_volt = REG_READ_FIELD(ah, AR_PHY_TPC_19,
276 + AR_PHY_TPC_19_ALPHA_VOLT);
277 + therm_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18,
278 + AR_PHY_TPC_18_THERM_CAL_VALUE);
279 + volt_cal_value = REG_READ_FIELD(ah, AR_PHY_TPC_18,
280 + AR_PHY_TPC_18_VOLT_CAL_VALUE);
281 + therm_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4,
282 + AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE);
283 + volt_value = REG_READ_FIELD(ah, AR_PHY_BB_THERM_ADC_4,
284 + AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE);
287 + reg = AR_PHY_TPC_11_B0;
288 + else if (chain == 1)
289 + reg = AR_PHY_TPC_11_B1;
291 + reg = AR_PHY_TPC_11_B2;
293 + olpc_gain_delta = REG_READ_FIELD(ah, reg,
294 + AR_PHY_TPC_11_OLPC_GAIN_DELTA);
296 + if (olpc_gain_delta >= 128)
297 + olpc_gain_delta = olpc_gain_delta - 256;
299 + thermal_gain_corr = (alpha_therm * (therm_value - therm_cal_value) +
301 + voltage_gain_corr = (alpha_volt * (volt_value - volt_cal_value) +
303 + desired_gain = target_power - olpc_gain_delta - thermal_gain_corr -
304 + voltage_gain_corr + desired_scale;
306 + return desired_gain;
309 +static void ar9003_tx_force_gain(struct ath_hw *ah, unsigned int gain_index)
311 + int selected_gain_entry, txbb1dbgain, txbb6dbgain, txmxrgain;
312 + int padrvgnA, padrvgnB, padrvgnC, padrvgnD;
313 + u32 *gain_table_entries = ah->paprd_gain_table_entries;
315 + selected_gain_entry = gain_table_entries[gain_index];
316 + txbb1dbgain = selected_gain_entry & 0x7;
317 + txbb6dbgain = (selected_gain_entry >> 3) & 0x3;
318 + txmxrgain = (selected_gain_entry >> 5) & 0xf;
319 + padrvgnA = (selected_gain_entry >> 9) & 0xf;
320 + padrvgnB = (selected_gain_entry >> 13) & 0xf;
321 + padrvgnC = (selected_gain_entry >> 17) & 0xf;
322 + padrvgnD = (selected_gain_entry >> 21) & 0x3;
324 + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
325 + AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN, txbb1dbgain);
326 + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
327 + AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN, txbb6dbgain);
328 + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
329 + AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN, txmxrgain);
330 + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
331 + AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA, padrvgnA);
332 + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
333 + AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB, padrvgnB);
334 + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
335 + AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC, padrvgnC);
336 + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
337 + AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND, padrvgnD);
338 + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
339 + AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL, 0);
340 + REG_RMW_FIELD(ah, AR_PHY_TX_FORCED_GAIN,
341 + AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN, 0);
342 + REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCED_DAC_GAIN, 0);
343 + REG_RMW_FIELD(ah, AR_PHY_TPC_1, AR_PHY_TPC_1_FORCE_DAC_GAIN, 0);
346 +static inline int find_expn(int num)
348 + return fls(num) - 1;
351 +static inline int find_proper_scale(int expn, int N)
353 + return (expn > N) ? expn - 10 : 0;
358 +static bool create_pa_curve(u32 *data_L, u32 *data_U, u32 *pa_table, u16 *gain)
360 + unsigned int thresh_accum_cnt;
361 + int x_est[NUM_BIN + 1], Y[NUM_BIN + 1], theta[NUM_BIN + 1];
362 + int PA_in[NUM_BIN + 1];
363 + int B1_tmp[NUM_BIN + 1], B2_tmp[NUM_BIN + 1];
364 + unsigned int B1_abs_max, B2_abs_max;
365 + int max_index, scale_factor;
366 + int y_est[NUM_BIN + 1];
367 + int x_est_fxp1_nonlin, x_tilde[NUM_BIN + 1];
368 + unsigned int x_tilde_abs;
369 + int G_fxp, Y_intercept, order_x_by_y, M, I, L, sum_y_sqr, sum_y_quad;
370 + int Q_x, Q_B1, Q_B2, beta_raw, alpha_raw, scale_B;
371 + int Q_scale_B, Q_beta, Q_alpha, alpha, beta, order_1, order_2;
372 + int order1_5x, order2_3x, order1_5x_rem, order2_3x_rem;
374 + int theta_low_bin = 0;
377 + /* disregard any bin that contains <= 16 samples */
378 + thresh_accum_cnt = 16;
381 + memset(theta, 0, sizeof(theta));
382 + memset(x_est, 0, sizeof(x_est));
383 + memset(Y, 0, sizeof(Y));
384 + memset(y_est, 0, sizeof(y_est));
385 + memset(x_tilde, 0, sizeof(x_tilde));
387 + for (i = 0; i < NUM_BIN; i++) {
388 + s32 accum_cnt, accum_tx, accum_rx, accum_ang;
390 + /* number of samples */
391 + accum_cnt = data_L[i] & 0xffff;
393 + if (accum_cnt <= thresh_accum_cnt)
396 + /* sum(tx amplitude) */
397 + accum_tx = ((data_L[i] >> 16) & 0xffff) |
398 + ((data_U[i] & 0x7ff) << 16);
400 + /* sum(rx amplitude distance to lower bin edge) */
401 + accum_rx = ((data_U[i] >> 11) & 0x1f) |
402 + ((data_L[i + 23] & 0xffff) << 5);
405 + accum_ang = ((data_L[i + 23] >> 16) & 0xffff) |
406 + ((data_U[i + 23] & 0x7ff) << 16);
408 + accum_tx <<= scale_factor;
409 + accum_rx <<= scale_factor;
410 + x_est[i + 1] = (((accum_tx + accum_cnt) / accum_cnt) + 32) >>
413 + Y[i + 1] = ((((accum_rx + accum_cnt) / accum_cnt) + 32) >>
414 + scale_factor) + (1 << scale_factor) * max_index + 16;
416 + if (accum_ang >= (1 << 26))
417 + accum_ang -= 1 << 27;
419 + theta[i + 1] = ((accum_ang * (1 << scale_factor)) + accum_cnt) /
426 + * Find average theta of first 5 bin and all of those to same value.
427 + * Curve is linear at that range.
429 + for (i = 1; i < 6; i++)
430 + theta_low_bin += theta[i];
432 + theta_low_bin = theta_low_bin / 5;
433 + for (i = 1; i < 6; i++)
434 + theta[i] = theta_low_bin;
436 + /* Set values at origin */
437 + theta[0] = theta_low_bin;
438 + for (i = 0; i <= max_index; i++)
439 + theta[i] -= theta_low_bin;
445 + /* low signal gain */
446 + if (x_est[6] == x_est[3])
450 + (((Y[6] - Y[3]) * 1 << scale_factor) +
451 + (x_est[6] - x_est[3])) / (x_est[6] - x_est[3]);
454 + (G_fxp * (x_est[0] - x_est[3]) +
455 + (1 << scale_factor)) / (1 << scale_factor) + Y[3];
457 + for (i = 0; i <= max_index; i++)
458 + y_est[i] = Y[i] - Y_intercept;
460 + for (i = 0; i <= 3; i++) {
463 + /* prevent division by zero */
467 + x_est[i] = ((y_est[i] * 1 << scale_factor) + G_fxp) / G_fxp;
470 + x_est_fxp1_nonlin =
471 + x_est[max_index] - ((1 << scale_factor) * y_est[max_index] +
475 + (x_est_fxp1_nonlin + y_est[max_index]) / y_est[max_index];
477 + if (order_x_by_y == 0)
479 + else if (order_x_by_y == 1)
484 + I = (max_index > 15) ? 7 : max_index >> 1;
491 + for (i = 0; i <= L; i++) {
492 + unsigned int y_sqr;
493 + unsigned int y_quad;
494 + unsigned int tmp_abs;
496 + /* prevent division by zero */
497 + if (y_est[i + I] == 0)
500 + x_est_fxp1_nonlin =
501 + x_est[i + I] - ((1 << scale_factor) * y_est[i + I] +
505 + (x_est_fxp1_nonlin * (1 << M) + y_est[i + I]) / y_est[i +
508 + (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I];
510 + (x_tilde[i] * (1 << M) + y_est[i + I]) / y_est[i + I];
512 + (y_est[i + I] * y_est[i + I] +
513 + (scale_factor * scale_factor)) / (scale_factor *
515 + tmp_abs = abs(x_tilde[i]);
516 + if (tmp_abs > x_tilde_abs)
517 + x_tilde_abs = tmp_abs;
519 + y_quad = y_sqr * y_sqr;
520 + sum_y_sqr = sum_y_sqr + y_sqr;
521 + sum_y_quad = sum_y_quad + y_quad;
522 + B1_tmp[i] = y_sqr * (L + 1);
528 + for (i = 0; i <= L; i++) {
531 + B1_tmp[i] -= sum_y_sqr;
532 + B2_tmp[i] = sum_y_quad - sum_y_sqr * B2_tmp[i];
534 + abs_val = abs(B1_tmp[i]);
535 + if (abs_val > B1_abs_max)
536 + B1_abs_max = abs_val;
538 + abs_val = abs(B2_tmp[i]);
539 + if (abs_val > B2_abs_max)
540 + B2_abs_max = abs_val;
543 + Q_x = find_proper_scale(find_expn(x_tilde_abs), 10);
544 + Q_B1 = find_proper_scale(find_expn(B1_abs_max), 10);
545 + Q_B2 = find_proper_scale(find_expn(B2_abs_max), 10);
549 + for (i = 0; i <= L; i++) {
550 + x_tilde[i] = x_tilde[i] / (1 << Q_x);
551 + B1_tmp[i] = B1_tmp[i] / (1 << Q_B1);
552 + B2_tmp[i] = B2_tmp[i] / (1 << Q_B2);
553 + beta_raw = beta_raw + B1_tmp[i] * x_tilde[i];
554 + alpha_raw = alpha_raw + B2_tmp[i] * x_tilde[i];
558 + ((sum_y_quad / scale_factor) * (L + 1) -
559 + (sum_y_sqr / scale_factor) * sum_y_sqr) * scale_factor;
561 + Q_scale_B = find_proper_scale(find_expn(abs(scale_B)), 10);
562 + scale_B = scale_B / (1 << Q_scale_B);
563 + Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10);
564 + Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10);
565 + beta_raw = beta_raw / (1 << Q_beta);
566 + alpha_raw = alpha_raw / (1 << Q_alpha);
567 + alpha = (alpha_raw << 10) / scale_B;
568 + beta = (beta_raw << 10) / scale_B;
569 + order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B;
570 + order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B;
571 + order1_5x = order_1 / 5;
572 + order2_3x = order_2 / 3;
573 + order1_5x_rem = order_1 - 5 * order1_5x;
574 + order2_3x_rem = order_2 - 3 * order2_3x;
576 + for (i = 0; i < PAPRD_TABLE_SZ; i++) {
578 + y5 = ((beta * tmp) >> 6) >> order1_5x;
579 + y5 = (y5 * tmp) >> order1_5x;
580 + y5 = (y5 * tmp) >> order1_5x;
581 + y5 = (y5 * tmp) >> order1_5x;
582 + y5 = (y5 * tmp) >> order1_5x;
583 + y5 = y5 >> order1_5x_rem;
584 + y3 = (alpha * tmp) >> order2_3x;
585 + y3 = (y3 * tmp) >> order2_3x;
586 + y3 = (y3 * tmp) >> order2_3x;
587 + y3 = y3 >> order2_3x_rem;
588 + PA_in[i] = y5 + y3 + (256 * tmp) / G_fxp;
591 + tmp = PA_in[i] - PA_in[i - 1];
594 + PA_in[i - 1] + (PA_in[i - 1] -
598 + PA_in[i] = (PA_in[i] < 1400) ? PA_in[i] : 1400;
604 + for (i = 0; i <= L; i++) {
606 + ((theta[i + I] << M) + y_est[i + I]) / y_est[i + I];
608 + ((theta_tilde << M) + y_est[i + I]) / y_est[i + I];
610 + ((theta_tilde << M) + y_est[i + I]) / y_est[i + I];
611 + beta_raw = beta_raw + B1_tmp[i] * theta_tilde;
612 + alpha_raw = alpha_raw + B2_tmp[i] * theta_tilde;
615 + Q_beta = find_proper_scale(find_expn(abs(beta_raw)), 10);
616 + Q_alpha = find_proper_scale(find_expn(abs(alpha_raw)), 10);
617 + beta_raw = beta_raw / (1 << Q_beta);
618 + alpha_raw = alpha_raw / (1 << Q_alpha);
620 + alpha = (alpha_raw << 10) / scale_B;
621 + beta = (beta_raw << 10) / scale_B;
622 + order_1 = 3 * M - Q_x - Q_B1 - Q_beta + 10 + Q_scale_B + 5;
623 + order_2 = 3 * M - Q_x - Q_B2 - Q_alpha + 10 + Q_scale_B + 5;
624 + order1_5x = order_1 / 5;
625 + order2_3x = order_2 / 3;
626 + order1_5x_rem = order_1 - 5 * order1_5x;
627 + order2_3x_rem = order_2 - 3 * order2_3x;
629 + for (i = 0; i < PAPRD_TABLE_SZ; i++) {
632 + /* pa_table[4] is calculated from PA_angle for i=5 */
638 + y5 = (((beta * tmp - 64) >> 6) -
639 + (1 << order1_5x)) / (1 << order1_5x);
641 + y5 = ((((beta * tmp - 64) >> 6) +
642 + (1 << order1_5x)) / (1 << order1_5x));
644 + y5 = (y5 * tmp) / (1 << order1_5x);
645 + y5 = (y5 * tmp) / (1 << order1_5x);
646 + y5 = (y5 * tmp) / (1 << order1_5x);
647 + y5 = (y5 * tmp) / (1 << order1_5x);
648 + y5 = y5 / (1 << order1_5x_rem);
651 + y3 = (alpha * tmp -
652 + (1 << order2_3x)) / (1 << order2_3x);
654 + y3 = (alpha * tmp +
655 + (1 << order2_3x)) / (1 << order2_3x);
656 + y3 = (y3 * tmp) / (1 << order2_3x);
657 + y3 = (y3 * tmp) / (1 << order2_3x);
658 + y3 = y3 / (1 << order2_3x_rem);
663 + PA_angle = y5 + y3;
664 + if (PA_angle < -150)
666 + else if (PA_angle > 150)
670 + pa_table[i] = ((PA_in[i] & 0x7ff) << 11) + (PA_angle & 0x7ff);
672 + PA_angle = (PA_angle + 2) >> 1;
673 + pa_table[i - 1] = ((PA_in[i - 1] & 0x7ff) << 11) +
674 + (PA_angle & 0x7ff);
682 +void ar9003_paprd_populate_single_table(struct ath_hw *ah,
683 + struct ath9k_channel *chan, int chain)
685 + u32 *paprd_table_val = chan->pa_table[chain];
686 + u32 small_signal_gain = chan->small_signal_gain[chain];
687 + u32 training_power;
692 + REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
693 + AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
694 + training_power -= 4;
697 + reg = AR_PHY_PAPRD_MEM_TAB_B0;
698 + else if (chain == 1)
699 + reg = AR_PHY_PAPRD_MEM_TAB_B1;
700 + else if (chain == 2)
701 + reg = AR_PHY_PAPRD_MEM_TAB_B2;
703 + for (i = 0; i < PAPRD_TABLE_SZ; i++) {
704 + REG_WRITE(ah, reg, paprd_table_val[i]);
709 + reg = AR_PHY_PA_GAIN123_B0;
710 + else if (chain == 1)
711 + reg = AR_PHY_PA_GAIN123_B1;
713 + reg = AR_PHY_PA_GAIN123_B2;
715 + REG_RMW_FIELD(ah, reg, AR_PHY_PA_GAIN123_PA_GAIN1, small_signal_gain);
717 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B0,
718 + AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
721 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B1,
722 + AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
725 + REG_RMW_FIELD(ah, AR_PHY_PAPRD_CTRL1_B2,
726 + AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL,
729 +EXPORT_SYMBOL(ar9003_paprd_populate_single_table);
731 +int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain)
734 + unsigned int i, desired_gain, gain_index;
735 + unsigned int train_power;
737 + train_power = REG_READ_FIELD(ah, AR_PHY_POWERTX_RATE5,
738 + AR_PHY_POWERTX_RATE5_POWERTXHT20_0);
740 + train_power = train_power - 4;
742 + desired_gain = ar9003_get_desired_gain(ah, chain, train_power);
745 + for (i = 0; i < 32; i++) {
746 + if (ah->paprd_gain_table_index[i] >= desired_gain)
751 + ar9003_tx_force_gain(ah, gain_index);
753 + REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
754 + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
758 +EXPORT_SYMBOL(ar9003_paprd_setup_gain_table);
760 +int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan,
763 + u16 *small_signal_gain = &chan->small_signal_gain[chain];
764 + u32 *pa_table = chan->pa_table[chain];
765 + u32 *data_L, *data_U;
770 + memset(chan->pa_table[chain], 0, sizeof(chan->pa_table[chain]));
772 + buf = kmalloc(2 * 48 * sizeof(u32), GFP_ATOMIC);
779 + REG_CLR_BIT(ah, AR_PHY_CHAN_INFO_MEMORY,
780 + AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ);
782 + reg = AR_PHY_CHAN_INFO_TAB_0;
783 + for (i = 0; i < 48; i++)
784 + data_L[i] = REG_READ(ah, reg + (i << 2));
786 + REG_SET_BIT(ah, AR_PHY_CHAN_INFO_MEMORY,
787 + AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ);
789 + for (i = 0; i < 48; i++)
790 + data_U[i] = REG_READ(ah, reg + (i << 2));
792 + if (!create_pa_curve(data_L, data_U, pa_table, small_signal_gain))
795 + REG_CLR_BIT(ah, AR_PHY_PAPRD_TRAINER_STAT1,
796 + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
802 +EXPORT_SYMBOL(ar9003_paprd_create_curve);
804 +int ar9003_paprd_init_table(struct ath_hw *ah)
806 + ar9003_paprd_setup_single_table(ah);
807 + ar9003_paprd_get_gain_table(ah);
810 +EXPORT_SYMBOL(ar9003_paprd_init_table);
812 +bool ar9003_paprd_is_done(struct ath_hw *ah)
814 + return !!REG_READ_FIELD(ah, AR_PHY_PAPRD_TRAINER_STAT1,
815 + AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE);
817 +EXPORT_SYMBOL(ar9003_paprd_is_done);
818 --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
819 +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
821 #define AR_PHY_TSTDAC (AR_SM_BASE + 0x168)
823 #define AR_PHY_CHAN_STATUS (AR_SM_BASE + 0x16c)
824 -#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170)
826 +#define AR_PHY_CHAN_INFO_MEMORY (AR_SM_BASE + 0x170)
827 +#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ 0x00000008
828 +#define AR_PHY_CHAN_INFO_MEMORY_CHANINFOMEM_S2_READ_S 3
830 #define AR_PHY_CHNINFO_NOISEPWR (AR_SM_BASE + 0x174)
831 #define AR_PHY_CHNINFO_GAINDIFF (AR_SM_BASE + 0x178)
832 #define AR_PHY_CHNINFO_FINETIM (AR_SM_BASE + 0x17c)
833 @@ -467,17 +471,63 @@
834 #define AR_PHY_PWRTX_MAX (AR_SM_BASE + 0x1f0)
835 #define AR_PHY_POWER_TX_SUB (AR_SM_BASE + 0x1f4)
837 -#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204)
838 -#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208)
839 -#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c)
840 -#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220)
841 -#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c)
842 -#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240)
843 +#define AR_PHY_TPC_1 (AR_SM_BASE + 0x1f8)
844 +#define AR_PHY_TPC_1_FORCED_DAC_GAIN 0x0000003e
845 +#define AR_PHY_TPC_1_FORCED_DAC_GAIN_S 1
846 +#define AR_PHY_TPC_1_FORCE_DAC_GAIN 0x00000001
847 +#define AR_PHY_TPC_1_FORCE_DAC_GAIN_S 0
849 +#define AR_PHY_TPC_4_B0 (AR_SM_BASE + 0x204)
850 +#define AR_PHY_TPC_5_B0 (AR_SM_BASE + 0x208)
851 +#define AR_PHY_TPC_6_B0 (AR_SM_BASE + 0x20c)
853 +#define AR_PHY_TPC_11_B0 (AR_SM_BASE + 0x220)
854 +#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
855 +#define AR_PHY_TPC_11_B2 (AR_SM2_BASE + 0x220)
856 +#define AR_PHY_TPC_11_OLPC_GAIN_DELTA 0x00ff0000
857 +#define AR_PHY_TPC_11_OLPC_GAIN_DELTA_S 16
859 +#define AR_PHY_TPC_12 (AR_SM_BASE + 0x224)
860 +#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5 0x3e000000
861 +#define AR_PHY_TPC_12_DESIRED_SCALE_HT40_5_S 25
863 +#define AR_PHY_TPC_18 (AR_SM_BASE + 0x23c)
864 +#define AR_PHY_TPC_18_THERM_CAL_VALUE 0x000000ff
865 +#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0
866 +#define AR_PHY_TPC_18_VOLT_CAL_VALUE 0x0000ff00
867 +#define AR_PHY_TPC_18_VOLT_CAL_VALUE_S 8
869 +#define AR_PHY_TPC_19 (AR_SM_BASE + 0x240)
870 +#define AR_PHY_TPC_19_ALPHA_VOLT 0x001f0000
871 +#define AR_PHY_TPC_19_ALPHA_VOLT_S 16
872 +#define AR_PHY_TPC_19_ALPHA_THERM 0xff
873 +#define AR_PHY_TPC_19_ALPHA_THERM_S 0
875 +#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258)
876 +#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN 0x00000001
877 +#define AR_PHY_TX_FORCED_GAIN_FORCE_TX_GAIN_S 0
878 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN 0x0000000e
879 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB1DBGAIN_S 1
880 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN 0x00000030
881 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXBB6DBGAIN_S 4
882 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN 0x000003c0
883 +#define AR_PHY_TX_FORCED_GAIN_FORCED_TXMXRGAIN_S 6
884 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA 0x00003c00
885 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNA_S 10
886 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB 0x0003c000
887 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNB_S 14
888 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC 0x003c0000
889 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGNC_S 18
890 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND 0x00c00000
891 +#define AR_PHY_TX_FORCED_GAIN_FORCED_PADRVGND_S 22
892 +#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL 0x01000000
893 +#define AR_PHY_TX_FORCED_GAIN_FORCED_ENABLE_PAL_S 24
895 -#define AR_PHY_TX_FORCED_GAIN (AR_SM_BASE + 0x258)
897 #define AR_PHY_PDADC_TAB_0 (AR_SM_BASE + 0x280)
899 +#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
901 #define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + 0x448)
902 #define AR_PHY_TX_IQCAL_START (AR_SM_BASE + 0x440)
903 #define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + 0x48c)
905 #define AR_PHY_ONLY_WARMRESET (AR_SM_BASE + 0x5d0)
906 #define AR_PHY_ONLY_CTL (AR_SM_BASE + 0x5d4)
907 #define AR_PHY_ECO_CTRL (AR_SM_BASE + 0x5dc)
908 -#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248)
910 +#define AR_PHY_BB_THERM_ADC_1 (AR_SM_BASE + 0x248)
911 +#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff
912 +#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0
914 +#define AR_PHY_BB_THERM_ADC_4 (AR_SM_BASE + 0x254)
915 +#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE 0x000000ff
916 +#define AR_PHY_BB_THERM_ADC_4_LATEST_THERM_VALUE_S 0
917 +#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00
918 +#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8
921 #define AR_PHY_65NM_CH0_SYNTH4 0x1608c
922 #define AR_PHY_SYNTH4_LONG_SHIFT_SELECT 0x00000002
924 #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE 0x00003fff
925 #define AR_PHY_TX_IQCAL_CORR_COEFF_01_COEFF_TABLE_S 0
927 -#define AR_PHY_TPC_18_THERM_CAL_VALUE 0xff
928 -#define AR_PHY_TPC_18_THERM_CAL_VALUE_S 0
929 -#define AR_PHY_TPC_19_ALPHA_THERM 0xff
930 -#define AR_PHY_TPC_19_ALPHA_THERM_S 0
932 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON 0x10000000
933 #define AR_PHY_65NM_CH0_RXTX4_THERM_ON_S 28
935 -#define AR_PHY_BB_THERM_ADC_1_INIT_THERM 0x000000ff
936 -#define AR_PHY_BB_THERM_ADC_1_INIT_THERM_S 0
939 * Channel 1 Register Map
941 @@ -842,6 +894,144 @@
943 #define AR_PHY_WATCHDOG_STATUS_CLR 0x00000008
948 +#define AR_PHY_XPA_TIMING_CTL (AR_SM_BASE + 0x64)
950 +#define AR_PHY_PAPRD_AM2AM (AR_CHAN_BASE + 0xe4)
951 +#define AR_PHY_PAPRD_AM2AM_MASK 0x01ffffff
952 +#define AR_PHY_PAPRD_AM2AM_MASK_S 0
954 +#define AR_PHY_PAPRD_AM2PM (AR_CHAN_BASE + 0xe8)
955 +#define AR_PHY_PAPRD_AM2PM_MASK 0x01ffffff
956 +#define AR_PHY_PAPRD_AM2PM_MASK_S 0
958 +#define AR_PHY_PAPRD_HT40 (AR_CHAN_BASE + 0xec)
959 +#define AR_PHY_PAPRD_HT40_MASK 0x01ffffff
960 +#define AR_PHY_PAPRD_HT40_MASK_S 0
962 +#define AR_PHY_PAPRD_CTRL0_B0 (AR_CHAN_BASE + 0xf0)
963 +#define AR_PHY_PAPRD_CTRL0_B1 (AR_CHAN1_BASE + 0xf0)
964 +#define AR_PHY_PAPRD_CTRL0_B2 (AR_CHAN2_BASE + 0xf0)
965 +#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE 0x00000001
966 +#define AR_PHY_PAPRD_CTRL0_PAPRD_ENABLE_S 0
967 +#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK 0x00000002
968 +#define AR_PHY_PAPRD_CTRL0_USE_SINGLE_TABLE_MASK_S 1
969 +#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH 0xf8000000
970 +#define AR_PHY_PAPRD_CTRL0_PAPRD_MAG_THRSH_S 27
972 +#define AR_PHY_PAPRD_CTRL1_B0 (AR_CHAN_BASE + 0xf4)
973 +#define AR_PHY_PAPRD_CTRL1_B1 (AR_CHAN1_BASE + 0xf4)
974 +#define AR_PHY_PAPRD_CTRL1_B2 (AR_CHAN2_BASE + 0xf4)
975 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA 0x00000001
976 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_SCALING_ENA_S 0
977 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE 0x00000002
978 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2AM_ENABLE_S 1
979 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE 0x00000004
980 +#define AR_PHY_PAPRD_CTRL1_ADAPTIVE_AM2PM_ENABLE_S 2
981 +#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL 0x000001f8
982 +#define AR_PHY_PAPRD_CTRL1_PAPRD_POWER_AT_AM2AM_CAL_S 3
983 +#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK 0x0001fe00
984 +#define AR_PHY_PAPRD_CTRL1_PA_GAIN_SCALE_FACT_MASK_S 9
985 +#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT 0x0ffe0000
986 +#define AR_PHY_PAPRD_CTRL1_PAPRD_MAG_SCALE_FACT_S 17
988 +#define AR_PHY_PAPRD_TRAINER_CNTL1 (AR_SM_BASE + 0x490)
989 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE 0x00000001
990 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_CF_PAPRD_TRAIN_ENABLE_S 0
991 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING 0x0000007e
992 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_AGC2_SETTLING_S 1
993 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE 0x00000100
994 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_IQCORR_ENABLE_S 8
995 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE 0x00000200
996 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_RX_BB_GAIN_FORCE_S 9
997 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE 0x00000400
998 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_TX_GAIN_FORCE_S 10
999 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE 0x00000800
1000 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_ENABLE_S 11
1001 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP 0x0003f000
1002 +#define AR_PHY_PAPRD_TRAINER_CNTL1_CF_PAPRD_LB_SKIP_S 12
1004 +#define AR_PHY_PAPRD_TRAINER_CNTL2 (AR_SM_BASE + 0x494)
1005 +#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN 0xFFFFFFFF
1006 +#define AR_PHY_PAPRD_TRAINER_CNTL2_CF_PAPRD_INIT_RX_BB_GAIN_S 0
1008 +#define AR_PHY_PAPRD_TRAINER_CNTL3 (AR_SM_BASE + 0x498)
1009 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE 0x0000003f
1010 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_ADC_DESIRED_SIZE_S 0
1011 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP 0x00000fc0
1012 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_QUICK_DROP_S 6
1013 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL 0x0001f000
1014 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_MIN_LOOPBACK_DEL_S 12
1015 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES 0x000e0000
1016 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_NUM_CORR_STAGES_S 17
1017 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN 0x00f00000
1018 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_COARSE_CORR_LEN_S 20
1019 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN 0x0f000000
1020 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_FINE_CORR_LEN_S 24
1021 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE 0x20000000
1022 +#define AR_PHY_PAPRD_TRAINER_CNTL3_CF_PAPRD_BBTXMIX_DISABLE_S 29
1024 +#define AR_PHY_PAPRD_TRAINER_CNTL4 (AR_SM_BASE + 0x49c)
1025 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES 0x03ff0000
1026 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_NUM_TRAIN_SAMPLES_S 16
1027 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA 0x0000f000
1028 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_SAFETY_DELTA_S 12
1029 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR 0x00000fff
1030 +#define AR_PHY_PAPRD_TRAINER_CNTL4_CF_PAPRD_MIN_CORR_S 0
1032 +#define AR_PHY_PAPRD_PRE_POST_SCALE_0_B0 (AR_CHAN_BASE + 0x100)
1033 +#define AR_PHY_PAPRD_PRE_POST_SCALE_1_B0 (AR_CHAN_BASE + 0x104)
1034 +#define AR_PHY_PAPRD_PRE_POST_SCALE_2_B0 (AR_CHAN_BASE + 0x108)
1035 +#define AR_PHY_PAPRD_PRE_POST_SCALE_3_B0 (AR_CHAN_BASE + 0x10c)
1036 +#define AR_PHY_PAPRD_PRE_POST_SCALE_4_B0 (AR_CHAN_BASE + 0x110)
1037 +#define AR_PHY_PAPRD_PRE_POST_SCALE_5_B0 (AR_CHAN_BASE + 0x114)
1038 +#define AR_PHY_PAPRD_PRE_POST_SCALE_6_B0 (AR_CHAN_BASE + 0x118)
1039 +#define AR_PHY_PAPRD_PRE_POST_SCALE_7_B0 (AR_CHAN_BASE + 0x11c)
1040 +#define AR_PHY_PAPRD_PRE_POST_SCALING 0x3FFFF
1041 +#define AR_PHY_PAPRD_PRE_POST_SCALING_S 0
1043 +#define AR_PHY_PAPRD_TRAINER_STAT1 (AR_SM_BASE + 0x4a0)
1044 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE 0x00000001
1045 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_DONE_S 0
1046 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE 0x00000002
1047 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_INCOMPLETE_S 1
1048 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR 0x00000004
1049 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_CORR_ERR_S 2
1050 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE 0x00000008
1051 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_TRAIN_ACTIVE_S 3
1052 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX 0x000001f0
1053 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_RX_GAIN_IDX_S 4
1054 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR 0x0001fe00
1055 +#define AR_PHY_PAPRD_TRAINER_STAT1_PAPRD_AGC2_PWR_S 9
1057 +#define AR_PHY_PAPRD_TRAINER_STAT2 (AR_SM_BASE + 0x4a4)
1058 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL 0x0000ffff
1059 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_VAL_S 0
1060 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX 0x001f0000
1061 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_COARSE_IDX_S 16
1062 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX 0x00600000
1063 +#define AR_PHY_PAPRD_TRAINER_STAT2_PAPRD_FINE_IDX_S 21
1065 +#define AR_PHY_PAPRD_TRAINER_STAT3 (AR_SM_BASE + 0x4a8)
1066 +#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT 0x000fffff
1067 +#define AR_PHY_PAPRD_TRAINER_STAT3_PAPRD_TRAIN_SAMPLES_CNT_S 0
1069 +#define AR_PHY_PAPRD_MEM_TAB_B0 (AR_CHAN_BASE + 0x120)
1070 +#define AR_PHY_PAPRD_MEM_TAB_B1 (AR_CHAN1_BASE + 0x120)
1071 +#define AR_PHY_PAPRD_MEM_TAB_B2 (AR_CHAN2_BASE + 0x120)
1073 +#define AR_PHY_PA_GAIN123_B0 (AR_CHAN_BASE + 0xf8)
1074 +#define AR_PHY_PA_GAIN123_B1 (AR_CHAN1_BASE + 0xf8)
1075 +#define AR_PHY_PA_GAIN123_B2 (AR_CHAN2_BASE + 0xf8)
1076 +#define AR_PHY_PA_GAIN123_PA_GAIN1 0x3FF
1077 +#define AR_PHY_PA_GAIN123_PA_GAIN1_S 0
1079 +#define AR_PHY_POWERTX_RATE5 (AR_SM_BASE + 0x1d0)
1080 +#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0 0x3F
1081 +#define AR_PHY_POWERTX_RATE5_POWERTXHT20_0_S 0
1083 void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx);
1085 #endif /* AR9003_PHY_H */
1086 --- a/drivers/net/wireless/ath/ath9k/ath9k.h
1087 +++ b/drivers/net/wireless/ath/ath9k/ath9k.h
1089 #include <linux/etherdevice.h>
1090 #include <linux/device.h>
1091 #include <linux/leds.h>
1092 +#include <linux/completion.h>
1096 @@ -194,6 +195,7 @@ enum ATH_AGGR_STATUS {
1098 #define ATH_TXFIFO_DEPTH 8
1103 struct list_head axq_q;
1104 @@ -206,7 +208,6 @@ struct ath_txq {
1105 struct list_head txq_fifo_pending;
1108 - int pending_frames;
1112 @@ -224,6 +225,7 @@ struct ath_buf_state {
1118 enum ath9k_key_type bfs_keytype;
1120 @@ -244,7 +246,6 @@ struct ath_buf {
1121 struct ath_buf_state bf_state;
1122 dma_addr_t bf_dmacontext;
1123 struct ath_wiphy *aphy;
1124 - struct ath_txq *txq;
1127 struct ath_atx_tid {
1128 @@ -281,6 +282,7 @@ struct ath_tx_control {
1129 struct ath_txq *txq;
1131 enum ath9k_internal_frame_type frame_type;
1135 #define ATH_TX_ERROR 0x01
1136 @@ -290,11 +292,12 @@ struct ath_tx_control {
1140 - int hwq_map[ATH9K_WME_AC_VO+1];
1141 + int hwq_map[WME_NUM_AC];
1142 spinlock_t txbuflock;
1143 struct list_head txbuf;
1144 struct ath_txq txq[ATH9K_NUM_TX_QUEUES];
1145 struct ath_descdma txdma;
1146 + int pending_frames[WME_NUM_AC];
1149 struct ath_rx_edma {
1150 @@ -421,6 +424,7 @@ int ath_beaconq_config(struct ath_softc
1151 #define ATH_LONG_CALINTERVAL 30000 /* 30 seconds */
1152 #define ATH_RESTART_CALINTERVAL 1200000 /* 20 minutes */
1154 +void ath_paprd_calibrate(struct work_struct *work);
1155 void ath_ani_calibrate(unsigned long data);
1158 @@ -553,6 +557,9 @@ struct ath_softc {
1159 spinlock_t sc_serial_rw;
1160 spinlock_t sc_pm_lock;
1162 + struct work_struct paprd_work;
1163 + struct completion paprd_complete;
1167 u32 sc_flags; /* SC_OP_* */
1168 @@ -613,7 +620,6 @@ struct ath_wiphy {
1170 void ath9k_tasklet(unsigned long data);
1171 int ath_reset(struct ath_softc *sc, bool retry_tx);
1172 -int ath_get_hal_qnum(u16 queue, struct ath_softc *sc);
1173 int ath_get_mac80211_qnum(u32 queue, struct ath_softc *sc);
1174 int ath_cabq_update(struct ath_softc *);
1176 @@ -629,8 +635,6 @@ irqreturn_t ath_isr(int irq, void *dev);
1177 int ath9k_init_device(u16 devid, struct ath_softc *sc, u16 subsysid,
1178 const struct ath_bus_ops *bus_ops);
1179 void ath9k_deinit_device(struct ath_softc *sc);
1180 -const char *ath_mac_bb_name(u32 mac_bb_version);
1181 -const char *ath_rf_name(u16 rf_version);
1182 void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw);
1183 void ath9k_update_ichannel(struct ath_softc *sc, struct ieee80211_hw *hw,
1184 struct ath9k_channel *ichan);
1185 @@ -681,8 +685,6 @@ void ath9k_set_wiphy_idle(struct ath_wip
1186 void ath_mac80211_stop_queue(struct ath_softc *sc, u16 skb_queue);
1187 void ath_mac80211_start_queue(struct ath_softc *sc, u16 skb_queue);
1189 -int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype);
1191 void ath_start_rfkill_poll(struct ath_softc *sc);
1192 extern void ath9k_rfkill_poll_state(struct ieee80211_hw *hw);
1194 --- a/drivers/net/wireless/ath/ath9k/eeprom.h
1195 +++ b/drivers/net/wireless/ath/ath9k/eeprom.h
1196 @@ -263,7 +263,8 @@ enum eeprom_param {
1197 EEP_PWR_TABLE_OFFSET,
1199 EEP_INTERNAL_REGULATOR,
1206 --- a/drivers/net/wireless/ath/ath9k/hw.c
1207 +++ b/drivers/net/wireless/ath/ath9k/hw.c
1208 @@ -2246,6 +2246,8 @@ int ath9k_hw_fill_cap_info(struct ath_hw
1209 pCap->rx_status_len = sizeof(struct ar9003_rxs);
1210 pCap->tx_desc_len = sizeof(struct ar9003_txc);
1211 pCap->txs_len = sizeof(struct ar9003_txs);
1212 + if (ah->eep_ops->get_eeprom(ah, EEP_PAPRD))
1213 + pCap->hw_caps |= ATH9K_HW_CAP_PAPRD;
1215 pCap->tx_desc_len = sizeof(struct ath_desc);
1216 if (AR_SREV_9280_20(ah) &&
1217 --- a/drivers/net/wireless/ath/ath9k/hw.h
1218 +++ b/drivers/net/wireless/ath/ath9k/hw.h
1220 #define ATH9K_HW_RX_HP_QDEPTH 16
1221 #define ATH9K_HW_RX_LP_QDEPTH 128
1223 +#define PAPRD_GAIN_TABLE_ENTRIES 32
1224 +#define PAPRD_TABLE_SZ 24
1226 enum ath_ini_subsys {
1229 @@ -200,6 +203,7 @@ enum ath9k_hw_caps {
1230 ATH9K_HW_CAP_LDPC = BIT(19),
1231 ATH9K_HW_CAP_FASTCLOCK = BIT(20),
1232 ATH9K_HW_CAP_SGI_20 = BIT(21),
1233 + ATH9K_HW_CAP_PAPRD = BIT(22),
1236 enum ath9k_capability_type {
1237 @@ -359,6 +363,9 @@ struct ath9k_channel {
1240 int16_t rawNoiseFloor;
1242 + u16 small_signal_gain[AR9300_MAX_CHAINS];
1243 + u32 pa_table[AR9300_MAX_CHAINS][PAPRD_TABLE_SZ];
1246 #define IS_CHAN_G(_c) ((((_c)->channelFlags & (CHANNEL_G)) == CHANNEL_G) || \
1247 @@ -793,6 +800,9 @@ struct ath_hw {
1249 u32 bb_watchdog_last_status;
1250 u32 bb_watchdog_timeout_ms; /* in ms, 0 to disable */
1252 + u32 paprd_gain_table_entries[PAPRD_GAIN_TABLE_ENTRIES];
1253 + u8 paprd_gain_table_index[PAPRD_GAIN_TABLE_ENTRIES];
1256 static inline struct ath_common *ath9k_hw_common(struct ath_hw *ah)
1257 @@ -922,6 +932,15 @@ void ar9003_hw_set_nf_limits(struct ath_
1258 void ar9003_hw_bb_watchdog_config(struct ath_hw *ah);
1259 void ar9003_hw_bb_watchdog_read(struct ath_hw *ah);
1260 void ar9003_hw_bb_watchdog_dbg_info(struct ath_hw *ah);
1261 +void ar9003_paprd_enable(struct ath_hw *ah, bool val);
1262 +void ar9003_paprd_populate_single_table(struct ath_hw *ah,
1263 + struct ath9k_channel *chan, int chain);
1264 +int ar9003_paprd_create_curve(struct ath_hw *ah, struct ath9k_channel *chan,
1266 +int ar9003_paprd_setup_gain_table(struct ath_hw *ah, int chain);
1267 +int ar9003_paprd_init_table(struct ath_hw *ah);
1268 +bool ar9003_paprd_is_done(struct ath_hw *ah);
1269 +void ar9003_hw_set_paprd_txdesc(struct ath_hw *ah, void *ds, u8 chains);
1271 /* Hardware family op attach helpers */
1272 void ar5008_hw_attach_phy_ops(struct ath_hw *ah);
1273 --- a/drivers/net/wireless/ath/ath9k/init.c
1274 +++ b/drivers/net/wireless/ath/ath9k/init.c
1275 @@ -427,7 +427,7 @@ static int ath9k_init_btcoex(struct ath_
1276 r = ath_init_btcoex_timer(sc);
1279 - qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
1280 + qnum = sc->tx.hwq_map[WME_AC_BE];
1281 ath9k_hw_init_btcoex_hw(sc->sc_ah, qnum);
1282 sc->btcoex.bt_stomp_type = ATH_BTCOEX_STOMP_LOW;
1284 @@ -464,23 +464,23 @@ static int ath9k_init_queues(struct ath_
1285 sc->config.cabqReadytime = ATH_CABQ_READY_TIME;
1286 ath_cabq_update(sc);
1288 - if (!ath_tx_setup(sc, ATH9K_WME_AC_BK)) {
1289 + if (!ath_tx_setup(sc, WME_AC_BK)) {
1290 ath_print(common, ATH_DBG_FATAL,
1291 "Unable to setup xmit queue for BK traffic\n");
1295 - if (!ath_tx_setup(sc, ATH9K_WME_AC_BE)) {
1296 + if (!ath_tx_setup(sc, WME_AC_BE)) {
1297 ath_print(common, ATH_DBG_FATAL,
1298 "Unable to setup xmit queue for BE traffic\n");
1301 - if (!ath_tx_setup(sc, ATH9K_WME_AC_VI)) {
1302 + if (!ath_tx_setup(sc, WME_AC_VI)) {
1303 ath_print(common, ATH_DBG_FATAL,
1304 "Unable to setup xmit queue for VI traffic\n");
1307 - if (!ath_tx_setup(sc, ATH9K_WME_AC_VO)) {
1308 + if (!ath_tx_setup(sc, WME_AC_VO)) {
1309 ath_print(common, ATH_DBG_FATAL,
1310 "Unable to setup xmit queue for VO traffic\n");
1312 @@ -769,6 +769,7 @@ int ath9k_init_device(u16 devid, struct
1316 + INIT_WORK(&sc->paprd_work, ath_paprd_calibrate);
1317 INIT_WORK(&sc->chan_work, ath9k_wiphy_chan_work);
1318 INIT_DELAYED_WORK(&sc->wiphy_work, ath9k_wiphy_work);
1319 sc->wiphy_scheduler_int = msecs_to_jiffies(500);
1320 --- a/drivers/net/wireless/ath/ath9k/main.c
1321 +++ b/drivers/net/wireless/ath/ath9k/main.c
1322 @@ -233,6 +233,104 @@ int ath_set_channel(struct ath_softc *sc
1326 +static void ath_paprd_activate(struct ath_softc *sc)
1328 + struct ath_hw *ah = sc->sc_ah;
1331 + if (!ah->curchan->paprd_done)
1334 + ath9k_ps_wakeup(sc);
1335 + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
1336 + if (!(ah->caps.tx_chainmask & BIT(chain)))
1339 + ar9003_paprd_populate_single_table(ah, ah->curchan, chain);
1342 + ar9003_paprd_enable(ah, true);
1343 + ath9k_ps_restore(sc);
1346 +void ath_paprd_calibrate(struct work_struct *work)
1348 + struct ath_softc *sc = container_of(work, struct ath_softc, paprd_work);
1349 + struct ieee80211_hw *hw = sc->hw;
1350 + struct ath_hw *ah = sc->sc_ah;
1351 + struct ieee80211_hdr *hdr;
1352 + struct sk_buff *skb = NULL;
1353 + struct ieee80211_tx_info *tx_info;
1354 + int band = hw->conf.channel->band;
1355 + struct ieee80211_supported_band *sband = &sc->sbands[band];
1356 + struct ath_tx_control txctl;
1363 + ath9k_ps_wakeup(sc);
1364 + skb = alloc_skb(len, GFP_KERNEL);
1368 + tx_info = IEEE80211_SKB_CB(skb);
1370 + skb_put(skb, len);
1371 + memset(skb->data, 0, len);
1372 + hdr = (struct ieee80211_hdr *)skb->data;
1373 + ftype = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_NULLFUNC;
1374 + hdr->frame_control = cpu_to_le16(ftype);
1375 + hdr->duration_id = 10;
1376 + memcpy(hdr->addr1, hw->wiphy->perm_addr, ETH_ALEN);
1377 + memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN);
1378 + memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN);
1380 + memset(&txctl, 0, sizeof(txctl));
1381 + qnum = sc->tx.hwq_map[WME_AC_BE];
1382 + txctl.txq = &sc->tx.txq[qnum];
1384 + ar9003_paprd_init_table(ah);
1385 + for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
1386 + if (!(ah->caps.tx_chainmask & BIT(chain)))
1390 + memset(tx_info, 0, sizeof(*tx_info));
1391 + tx_info->band = band;
1393 + for (i = 0; i < 4; i++) {
1394 + tx_info->control.rates[i].idx = sband->n_bitrates - 1;
1395 + tx_info->control.rates[i].count = 6;
1398 + init_completion(&sc->paprd_complete);
1399 + ar9003_paprd_setup_gain_table(ah, chain);
1400 + txctl.paprd = BIT(chain);
1401 + if (ath_tx_start(hw, skb, &txctl) != 0)
1404 + wait_for_completion(&sc->paprd_complete);
1406 + if (!ar9003_paprd_is_done(ah))
1409 + if (ar9003_paprd_create_curve(ah, ah->curchan, chain) != 0)
1417 + ah->curchan->paprd_done = true;
1418 + ath_paprd_activate(sc);
1421 + ath9k_ps_restore(sc);
1425 * This routine performs the periodic noise floor calibration function
1426 * that is used to adjust and optimize the chip performance. This
1427 @@ -332,6 +430,13 @@ set_timer:
1428 cal_interval = min(cal_interval, (u32)short_cal_interval);
1430 mod_timer(&common->ani.timer, jiffies + msecs_to_jiffies(cal_interval));
1431 + if ((sc->sc_ah->caps.hw_caps & ATH9K_HW_CAP_PAPRD) &&
1432 + !(sc->sc_flags & SC_OP_SCANNING)) {
1433 + if (!sc->sc_ah->curchan->paprd_done)
1434 + ieee80211_queue_work(sc->hw, &sc->paprd_work);
1436 + ath_paprd_activate(sc);
1440 static void ath_start_ani(struct ath_common *common)
1441 @@ -805,25 +910,25 @@ int ath_reset(struct ath_softc *sc, bool
1445 -int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
1446 +static int ath_get_hal_qnum(u16 queue, struct ath_softc *sc)
1452 - qnum = sc->tx.hwq_map[ATH9K_WME_AC_VO];
1453 + qnum = sc->tx.hwq_map[WME_AC_VO];
1456 - qnum = sc->tx.hwq_map[ATH9K_WME_AC_VI];
1457 + qnum = sc->tx.hwq_map[WME_AC_VI];
1460 - qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
1461 + qnum = sc->tx.hwq_map[WME_AC_BE];
1464 - qnum = sc->tx.hwq_map[ATH9K_WME_AC_BK];
1465 + qnum = sc->tx.hwq_map[WME_AC_BK];
1468 - qnum = sc->tx.hwq_map[ATH9K_WME_AC_BE];
1469 + qnum = sc->tx.hwq_map[WME_AC_BE];
1473 @@ -835,16 +940,16 @@ int ath_get_mac80211_qnum(u32 queue, str
1477 - case ATH9K_WME_AC_VO:
1481 - case ATH9K_WME_AC_VI:
1485 - case ATH9K_WME_AC_BE:
1489 - case ATH9K_WME_AC_BK:
1494 @@ -1128,6 +1233,7 @@ static void ath9k_stop(struct ieee80211_
1496 cancel_delayed_work_sync(&sc->ath_led_blink_work);
1497 cancel_delayed_work_sync(&sc->tx_complete_work);
1498 + cancel_work_sync(&sc->paprd_work);
1500 if (!sc->num_sec_wiphy) {
1501 cancel_delayed_work_sync(&sc->wiphy_work);
1502 @@ -1556,7 +1662,7 @@ static int ath9k_conf_tx(struct ieee8021
1503 ath_print(common, ATH_DBG_FATAL, "TXQ Update failed\n");
1505 if (sc->sc_ah->opmode == NL80211_IFTYPE_ADHOC)
1506 - if ((qnum == sc->tx.hwq_map[ATH9K_WME_AC_BE]) && !ret)
1507 + if ((qnum == sc->tx.hwq_map[WME_AC_BE]) && !ret)
1508 ath_beaconq_config(sc);
1510 mutex_unlock(&sc->mutex);
1511 @@ -1843,6 +1949,7 @@ static void ath9k_sw_scan_start(struct i
1512 ath9k_wiphy_pause_all_forced(sc, aphy);
1513 sc->sc_flags |= SC_OP_SCANNING;
1514 del_timer_sync(&common->ani.timer);
1515 + cancel_work_sync(&sc->paprd_work);
1516 cancel_delayed_work_sync(&sc->tx_complete_work);
1517 mutex_unlock(&sc->mutex);
1519 --- a/drivers/net/wireless/ath/ath9k/xmit.c
1520 +++ b/drivers/net/wireless/ath/ath9k/xmit.c
1521 @@ -941,6 +941,7 @@ struct ath_txq *ath_txq_setup(struct ath
1522 if (!ATH_TXQ_SETUP(sc, qnum)) {
1523 struct ath_txq *txq = &sc->tx.txq[qnum];
1525 + txq->axq_class = subtype;
1526 txq->axq_qnum = qnum;
1527 txq->axq_link = NULL;
1528 INIT_LIST_HEAD(&txq->axq_q);
1529 @@ -958,32 +959,6 @@ struct ath_txq *ath_txq_setup(struct ath
1530 return &sc->tx.txq[qnum];
1533 -int ath_tx_get_qnum(struct ath_softc *sc, int qtype, int haltype)
1538 - case ATH9K_TX_QUEUE_DATA:
1539 - if (haltype >= ARRAY_SIZE(sc->tx.hwq_map)) {
1540 - ath_print(ath9k_hw_common(sc->sc_ah), ATH_DBG_FATAL,
1541 - "HAL AC %u out of range, max %zu!\n",
1542 - haltype, ARRAY_SIZE(sc->tx.hwq_map));
1545 - qnum = sc->tx.hwq_map[haltype];
1547 - case ATH9K_TX_QUEUE_BEACON:
1548 - qnum = sc->beacon.beaconq;
1550 - case ATH9K_TX_QUEUE_CAB:
1551 - qnum = sc->beacon.cabq->axq_qnum;
1559 int ath_txq_update(struct ath_softc *sc, int qnum,
1560 struct ath9k_tx_queue_info *qinfo)
1562 @@ -1662,12 +1637,13 @@ static int ath_tx_setup_buffer(struct ie
1563 bf->bf_frmlen -= padsize;
1566 - if (conf_is_ht(&hw->conf)) {
1567 + if (!txctl->paprd && conf_is_ht(&hw->conf)) {
1568 bf->bf_state.bf_type |= BUF_HT;
1569 if (tx_info->flags & IEEE80211_TX_CTL_LDPC)
1573 + bf->bf_state.bfs_paprd = txctl->paprd;
1574 bf->bf_flags = setup_tx_flags(skb, use_ldpc);
1576 bf->bf_keytype = get_hw_crypto_keytype(skb);
1577 @@ -1742,6 +1718,9 @@ static void ath_tx_start_dma(struct ath_
1579 txctl->txq->axq_qnum);
1581 + if (bf->bf_state.bfs_paprd)
1582 + ar9003_hw_set_paprd_txdesc(ah, ds, bf->bf_state.bfs_paprd);
1584 spin_lock_bh(&txctl->txq->axq_lock);
1586 if (bf_isht(bf) && (sc->sc_flags & SC_OP_TXAGGR) &&
1587 @@ -1785,7 +1764,7 @@ int ath_tx_start(struct ieee80211_hw *hw
1588 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1589 struct ath_txq *txq = txctl->txq;
1594 bf = ath_tx_get_buffer(sc);
1596 @@ -1793,14 +1772,6 @@ int ath_tx_start(struct ieee80211_hw *hw
1600 - bf->txq = txctl->txq;
1601 - spin_lock_bh(&bf->txq->axq_lock);
1602 - if (++bf->txq->pending_frames > ATH_MAX_QDEPTH && !txq->stopped) {
1603 - ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
1606 - spin_unlock_bh(&bf->txq->axq_lock);
1608 r = ath_tx_setup_buffer(hw, bf, skb, txctl);
1610 ath_print(common, ATH_DBG_FATAL, "TX mem alloc failure\n");
1611 @@ -1821,6 +1792,17 @@ int ath_tx_start(struct ieee80211_hw *hw
1615 + q = skb_get_queue_mapping(skb);
1619 + spin_lock_bh(&txq->axq_lock);
1620 + if (++sc->tx.pending_frames[q] > ATH_MAX_QDEPTH && !txq->stopped) {
1621 + ath_mac80211_stop_queue(sc, skb_get_queue_mapping(skb));
1624 + spin_unlock_bh(&txq->axq_lock);
1626 ath_tx_start_dma(sc, bf, txctl);
1629 @@ -1890,7 +1872,7 @@ static void ath_tx_complete(struct ath_s
1630 struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
1631 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1632 struct ieee80211_hdr * hdr = (struct ieee80211_hdr *)skb->data;
1633 - int padpos, padsize;
1634 + int q, padpos, padsize;
1636 ath_print(common, ATH_DBG_XMIT, "TX complete: skb: %p\n", skb);
1638 @@ -1929,8 +1911,16 @@ static void ath_tx_complete(struct ath_s
1640 if (unlikely(tx_info->pad[0] & ATH_TX_INFO_FRAME_TYPE_INTERNAL))
1641 ath9k_tx_status(hw, skb);
1644 + q = skb_get_queue_mapping(skb);
1648 + if (--sc->tx.pending_frames[q] < 0)
1649 + sc->tx.pending_frames[q] = 0;
1651 ieee80211_tx_status(hw, skb);
1655 static void ath_tx_complete_buf(struct ath_softc *sc, struct ath_buf *bf,
1656 @@ -1951,16 +1941,15 @@ static void ath_tx_complete_buf(struct a
1657 tx_flags |= ATH_TX_XRETRY;
1661 - spin_lock_bh(&bf->txq->axq_lock);
1662 - bf->txq->pending_frames--;
1663 - spin_unlock_bh(&bf->txq->axq_lock);
1667 dma_unmap_single(sc->dev, bf->bf_dmacontext, skb->len, DMA_TO_DEVICE);
1668 - ath_tx_complete(sc, skb, bf->aphy, tx_flags);
1669 - ath_debug_stat_tx(sc, txq, bf, ts);
1671 + if (bf->bf_state.bfs_paprd) {
1672 + sc->paprd_txok = txok;
1673 + complete(&sc->paprd_complete);
1675 + ath_tx_complete(sc, skb, bf->aphy, tx_flags);
1676 + ath_debug_stat_tx(sc, txq, bf, ts);
1680 * Return the list of ath_buf of this mpdu to free queue
1681 @@ -2045,13 +2034,14 @@ static void ath_wake_mac80211_queue(stru
1685 + qnum = ath_get_mac80211_qnum(txq->axq_class, sc);
1689 spin_lock_bh(&txq->axq_lock);
1690 - if (txq->stopped && txq->pending_frames < ATH_MAX_QDEPTH) {
1691 - qnum = ath_get_mac80211_qnum(txq->axq_qnum, sc);
1693 - ath_mac80211_start_queue(sc, qnum);
1696 + if (txq->stopped && sc->tx.pending_frames[qnum] < ATH_MAX_QDEPTH) {
1697 + ath_mac80211_start_queue(sc, qnum);
1700 spin_unlock_bh(&txq->axq_lock);
1702 @@ -2422,26 +2412,8 @@ void ath_tx_node_init(struct ath_softc *
1703 for (acno = 0, ac = &an->ac[acno];
1704 acno < WME_NUM_AC; acno++, ac++) {
1706 + ac->qnum = sc->tx.hwq_map[acno];
1707 INIT_LIST_HEAD(&ac->tid_q);
1711 - ac->qnum = ath_tx_get_qnum(sc,
1712 - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BE);
1715 - ac->qnum = ath_tx_get_qnum(sc,
1716 - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_BK);
1719 - ac->qnum = ath_tx_get_qnum(sc,
1720 - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VI);
1723 - ac->qnum = ath_tx_get_qnum(sc,
1724 - ATH9K_TX_QUEUE_DATA, ATH9K_WME_AC_VO);
1730 --- a/drivers/net/wireless/ath/ath9k/beacon.c
1731 +++ b/drivers/net/wireless/ath/ath9k/beacon.c
1732 @@ -38,8 +38,7 @@ int ath_beaconq_config(struct ath_softc
1735 /* Adhoc mode; important thing is to use 2x cwmin. */
1736 - qnum = ath_tx_get_qnum(sc, ATH9K_TX_QUEUE_DATA,
1738 + qnum = sc->tx.hwq_map[WME_AC_BE];
1739 ath9k_hw_get_txq_props(ah, qnum, &qi_be);
1740 qi.tqi_aifs = qi_be.tqi_aifs;
1741 qi.tqi_cwmin = 4*qi_be.tqi_cwmin;
1742 --- a/drivers/net/wireless/ath/ath9k/debug.c
1743 +++ b/drivers/net/wireless/ath/ath9k/debug.c
1744 @@ -630,10 +630,10 @@ static const struct file_operations fops
1746 len += snprintf(buf + len, size - len, \
1747 "%s%13u%11u%10u%10u\n", str, \
1748 - sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BE]].elem, \
1749 - sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_BK]].elem, \
1750 - sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VI]].elem, \
1751 - sc->debug.stats.txstats[sc->tx.hwq_map[ATH9K_WME_AC_VO]].elem); \
1752 + sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BE]].elem, \
1753 + sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_BK]].elem, \
1754 + sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VI]].elem, \
1755 + sc->debug.stats.txstats[sc->tx.hwq_map[WME_AC_VO]].elem); \
1758 static ssize_t read_file_xmit(struct file *file, char __user *user_buf,
1759 @@ -956,6 +956,10 @@ int ath9k_init_debug(struct ath_hw *ah)
1760 sc->debug.debugfs_phy, sc, &fops_regval))
1763 + if (!debugfs_create_bool("ignore_extcca", S_IRUSR | S_IWUSR,
1764 + sc->debug.debugfs_phy, &ah->config.cwm_ignore_extcca))
1767 sc->debug.regidx = 0;
1770 --- a/drivers/net/wireless/ath/ath9k/htc.h
1771 +++ b/drivers/net/wireless/ath/ath9k/htc.h
1772 @@ -398,7 +398,7 @@ struct ath9k_htc_priv {
1776 - int hwq_map[ATH9K_WME_AC_VO+1];
1777 + int hwq_map[WME_NUM_AC];
1779 #ifdef CONFIG_ATH9K_HTC_DEBUGFS
1780 struct ath9k_debug debug;
1781 --- a/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
1782 +++ b/drivers/net/wireless/ath/ath9k/htc_drv_beacon.c
1783 @@ -227,7 +227,7 @@ void ath9k_htc_beaconq_config(struct ath
1785 struct ath_hw *ah = priv->ah;
1786 struct ath9k_tx_queue_info qi, qi_be;
1787 - int qnum = priv->hwq_map[ATH9K_WME_AC_BE];
1788 + int qnum = priv->hwq_map[WME_AC_BE];
1790 memset(&qi, 0, sizeof(struct ath9k_tx_queue_info));
1791 memset(&qi_be, 0, sizeof(struct ath9k_tx_queue_info));
1792 --- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
1793 +++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
1794 @@ -521,23 +521,23 @@ static int ath9k_init_queues(struct ath9
1798 - if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BE)) {
1799 + if (!ath9k_htc_txq_setup(priv, WME_AC_BE)) {
1800 ath_print(common, ATH_DBG_FATAL,
1801 "Unable to setup xmit queue for BE traffic\n");
1805 - if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_BK)) {
1806 + if (!ath9k_htc_txq_setup(priv, WME_AC_BK)) {
1807 ath_print(common, ATH_DBG_FATAL,
1808 "Unable to setup xmit queue for BK traffic\n");
1811 - if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VI)) {
1812 + if (!ath9k_htc_txq_setup(priv, WME_AC_VI)) {
1813 ath_print(common, ATH_DBG_FATAL,
1814 "Unable to setup xmit queue for VI traffic\n");
1817 - if (!ath9k_htc_txq_setup(priv, ATH9K_WME_AC_VO)) {
1818 + if (!ath9k_htc_txq_setup(priv, WME_AC_VO)) {
1819 ath_print(common, ATH_DBG_FATAL,
1820 "Unable to setup xmit queue for VO traffic\n");
1822 --- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
1823 +++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
1824 @@ -1590,7 +1590,7 @@ static int ath9k_htc_conf_tx(struct ieee
1827 if ((priv->ah->opmode == NL80211_IFTYPE_ADHOC) &&
1828 - (qnum == priv->hwq_map[ATH9K_WME_AC_BE]))
1829 + (qnum == priv->hwq_map[WME_AC_BE]))
1830 ath9k_htc_beaconq_config(priv);
1832 ath9k_htc_ps_restore(priv);
1833 --- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
1834 +++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
1835 @@ -34,15 +34,15 @@ int get_hw_qnum(u16 queue, int *hwq_map)
1839 - return hwq_map[ATH9K_WME_AC_VO];
1840 + return hwq_map[WME_AC_VO];
1842 - return hwq_map[ATH9K_WME_AC_VI];
1843 + return hwq_map[WME_AC_VI];
1845 - return hwq_map[ATH9K_WME_AC_BE];
1846 + return hwq_map[WME_AC_BE];
1848 - return hwq_map[ATH9K_WME_AC_BK];
1849 + return hwq_map[WME_AC_BK];
1851 - return hwq_map[ATH9K_WME_AC_BE];
1852 + return hwq_map[WME_AC_BE];
1856 --- a/drivers/net/wireless/ath/ath9k/mac.h
1857 +++ b/drivers/net/wireless/ath/ath9k/mac.h
1858 @@ -577,13 +577,8 @@ enum ath9k_tx_queue {
1860 #define ATH9K_NUM_TX_QUEUES 10
1862 -enum ath9k_tx_queue_subtype {
1863 - ATH9K_WME_AC_BK = 0,
1869 +/* Used as a queue subtype instead of a WMM AC */
1870 +#define ATH9K_WME_UPSD 4
1872 enum ath9k_tx_queue_flags {
1873 TXQ_FLAG_TXOKINT_ENABLE = 0x0001,
1874 @@ -617,7 +612,7 @@ enum ath9k_pkt_type {
1875 struct ath9k_tx_queue_info {
1877 enum ath9k_tx_queue tqi_type;
1878 - enum ath9k_tx_queue_subtype tqi_subtype;
1880 enum ath9k_tx_queue_flags tqi_qflags;
1883 --- a/drivers/net/wireless/ath/ath9k/virtual.c
1884 +++ b/drivers/net/wireless/ath/ath9k/virtual.c
1885 @@ -219,7 +219,7 @@ static int ath9k_send_nullfunc(struct at
1886 info->control.rates[1].idx = -1;
1888 memset(&txctl, 0, sizeof(struct ath_tx_control));
1889 - txctl.txq = &sc->tx.txq[sc->tx.hwq_map[ATH9K_WME_AC_VO]];
1890 + txctl.txq = &sc->tx.txq[sc->tx.hwq_map[WME_AC_VO]];
1891 txctl.frame_type = ps ? ATH9K_IFT_PAUSE : ATH9K_IFT_UNPAUSE;
1893 if (ath_tx_start(aphy->hw, skb, &txctl) != 0)