25 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28 #include <linux/slab.h>
29 #include <asm/unaligned.h>
107 ath5k_hw_reg_write(ah, 0x00001c16,
AR5K_PHY(0x34));
109 for (i = 0; i < 8; i++)
110 ath5k_hw_reg_write(ah, 0x00010000,
AR5K_PHY(0x20));
113 srev = ath5k_hw_reg_read(ah,
AR5K_PHY(256) >> 28) & 0xf;
114 ret = (
u16)ath5k_hw_bitswap(srev, 4) + 1;
116 srev = (ath5k_hw_reg_read(ah,
AR5K_PHY(0x100)) >> 24) & 0xff;
117 ret = (
u16)ath5k_hw_bitswap(((srev & 0xf0) >> 4) |
118 ((srev & 0x0f) << 4), 8);
143 (freq <= ah->ah_capabilities.cap_range.range_2ghz_max))
147 (freq <= ah->ah_capabilities.cap_range.range_5ghz_max))
208 if (rf_regs[i].
index == reg_id) {
221 num_bits = rfreg->
field.len;
222 first_bit = rfreg->
field.pos;
223 col = rfreg->
field.col;
232 if (!(col <= 3 && num_bits <= 32 && first_bit + num_bits <= 319)) {
237 entry = ((first_bit - 1) / 8) +
offset;
238 position = (first_bit - 1) % 8;
241 data = ath5k_hw_bitswap(val, num_bits);
243 for (bits_shifted = 0, bits_left = num_bits; bits_left > 0;
244 position = 0, entry++) {
246 last_bit = (position + bits_left > 8) ? 8 :
247 position + bits_left;
249 mask = (((1 << last_bit) - 1) ^ ((1 << position) - 1)) <<
254 rfb[
entry] |= ((data << position) << (col * 8)) & mask;
255 data >>= (8 - position);
257 data |= (((rfb[
entry] &
mask) >> (col * 8)) >> position)
259 bits_shifted += last_bit - position;
262 bits_left -= 8 - position;
265 data =
set ? 1 : ath5k_hw_bitswap(data, num_bits);
285 ath5k_hw_write_ofdm_timings(
struct ath5k_hw *ah,
289 u32 coef_scaled, coef_exp, coef_man,
290 ds_coef_exp, ds_coef_man,
clock;
313 coef_scaled = ((5 * (clock << 24)) / 2) / channel->
center_freq;
317 coef_exp =
ilog2(coef_scaled);
320 if (!coef_scaled || !coef_exp)
324 coef_exp = 14 - (coef_exp - 24);
329 coef_man = coef_scaled +
330 (1 << (24 - coef_exp - 1));
334 ds_coef_man = coef_man >> (24 - coef_exp);
335 ds_coef_exp = coef_exp - 16;
363 ath5k_hw_wait_for_synth(
struct ath5k_hw *ah,
375 ((delay << 2) / 22) : (delay / 10);
425 ah->
ah_gain.g_step_idx = rfgain_opt_5111.go_default;
431 ah->
ah_gain.g_step_idx = rfgain_opt_5112.go_default;
457 ath5k_hw_request_rfgain_probe(
struct ath5k_hw *ah)
483 ath5k_hw_rf_gainf_corr(
struct ath5k_hw *ah)
496 go = &rfgain_opt_5112;
497 rf_regs = rf_regs_5112a;
520 ah->
ah_gain.g_f_corr = step * 2;
523 ah->
ah_gain.g_f_corr = (step - 5) * 2;
548 ath5k_hw_rf_check_gainf_readback(
struct ath5k_hw *ah)
561 rf_regs = rf_regs_5111;
568 level[1] = (step == 63) ? 50 : step + 4;
569 level[2] = (step != 63) ? 64 : level[0];
570 level[3] = level[2] + 50;
572 ah->
ah_gain.g_high = level[3] -
578 rf_regs = rf_regs_5112;
584 level[0] = level[2] = 0;
587 level[1] = level[3] = 83;
589 level[1] = level[3] = 107;
594 return (ah->
ah_gain.g_current >= level[0] &&
595 ah->
ah_gain.g_current <= level[1]) ||
596 (ah->
ah_gain.g_current >= level[2] &&
597 ah->
ah_gain.g_current <= level[3]);
608 ath5k_hw_rf_gainf_adjust(
struct ath5k_hw *ah)
616 go = &rfgain_opt_5111;
619 go = &rfgain_opt_5112;
630 if (ah->
ah_gain.g_step_idx == 0)
665 "ret %d, gain step %u, current gain %u, target gain %u\n",
720 ath5k_hw_rf_gainf_corr(ah);
730 if (ath5k_hw_rf_check_gainf_readback(ah) &&
732 ath5k_hw_rf_gainf_adjust(ah)) {
761 ath5k_rfg = rfgain_5111;
765 ath5k_rfg = rfgain_5112;
769 ath5k_rfg = rfgain_2413;
773 ath5k_rfg = rfgain_2316;
777 ath5k_rfg = rfgain_5413;
782 ath5k_rfg = rfgain_2425;
791 for (i = 0; i <
size; i++) {
793 ath5k_hw_reg_write(ah, ath5k_rfg[i].
rfg_value[index],
815 ath5k_hw_rfregs_init(
struct ath5k_hw *ah,
826 int i, obdb = -1, bank = -1;
830 rf_regs = rf_regs_5111;
834 go = &rfgain_opt_5111;
838 rf_regs = rf_regs_5112a;
843 rf_regs = rf_regs_5112;
848 go = &rfgain_opt_5112;
851 rf_regs = rf_regs_2413;
857 rf_regs = rf_regs_2316;
863 rf_regs = rf_regs_5413;
869 rf_regs = rf_regs_2425;
875 rf_regs = rf_regs_2425;
911 if (bank != ini_rfb[i].rfb_bank) {
940 ath5k_hw_rfb_op(ah, rf_regs, ee->
ee_ob[ee_mode][obdb],
943 ath5k_hw_rfb_op(ah, rf_regs, ee->
ee_db[ee_mode][obdb],
961 ath5k_hw_rfb_op(ah, rf_regs, ee->
ee_ob[ee_mode][obdb],
964 ath5k_hw_rfb_op(ah, rf_regs, ee->
ee_db[ee_mode][obdb],
985 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[1],
988 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[2],
991 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[3],
1002 ath5k_hw_rfb_op(ah, rf_regs, !ee->
ee_xpd[ee_mode],
1005 ath5k_hw_rfb_op(ah, rf_regs, ee->
ee_x_gain[ee_mode],
1008 ath5k_hw_rfb_op(ah, rf_regs, ee->
ee_i_gain[ee_mode],
1011 ath5k_hw_rfb_op(ah, rf_regs, ee->
ee_xpd[ee_mode],
1019 ath5k_hw_rfb_op(ah, rf_regs, 0x1f,
1025 ath5k_hw_rfb_op(ah, rf_regs, wait_i,
1027 ath5k_hw_rfb_op(ah, rf_regs, 3,
1038 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[0],
1041 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[1],
1044 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[2],
1047 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[3],
1050 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[4],
1053 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[5],
1056 ath5k_hw_rfb_op(ah, rf_regs, g_step->
gos_param[6],
1066 ath5k_hw_rfb_op(ah, rf_regs, ee->
ee_xpd[ee_mode],
1071 ath5k_hw_rfb_op(ah, rf_regs,
1078 ath5k_hw_rfb_op(ah, rf_regs,
1079 pdg_curve_to_idx[0],
1081 ath5k_hw_rfb_op(ah, rf_regs,
1082 pdg_curve_to_idx[1],
1085 ath5k_hw_rfb_op(ah, rf_regs,
1086 pdg_curve_to_idx[0],
1088 ath5k_hw_rfb_op(ah, rf_regs,
1089 pdg_curve_to_idx[0],
1096 ath5k_hw_rfb_op(ah, rf_regs, 2,
1099 ath5k_hw_rfb_op(ah, rf_regs, 2,
1102 ath5k_hw_rfb_op(ah, rf_regs, 2,
1105 ath5k_hw_rfb_op(ah, rf_regs, 2,
1111 ath5k_hw_rfb_op(ah, rf_regs, 1,
1114 ath5k_hw_rfb_op(ah, rf_regs, 1,
1117 ath5k_hw_rfb_op(ah, rf_regs, 1,
1120 ath5k_hw_rfb_op(ah, rf_regs, 1,
1123 ath5k_hw_rfb_op(ah, rf_regs, 1,
1128 ath5k_hw_rfb_op(ah, rf_regs, ee->
ee_i_gain[ee_mode],
1139 ath5k_hw_rfb_op(ah, rf_regs, pd_delay,
1141 ath5k_hw_rfb_op(ah, rf_regs, 0xf,
1156 ath5k_hw_rfb_op(ah, rf_regs, ath5k_hw_bitswap(6, 3),
1164 ath5k_hw_reg_write(ah, rfb[i], ini_rfb[i].rfb_ctrl_register);
1187 athchan = (ath5k_hw_bitswap(
1190 << 1) | (1 << 6) | 0x1;
1200 ath5k_hw_rf5110_channel(
struct ath5k_hw *ah,
1208 data = ath5k_hw_rf5110_chan2athchan(channel);
1227 ath5k_hw_rf5111_chan2athchan(
unsigned int ieee,
1233 channel = (
int)ieee;
1238 if (channel <= 13) {
1241 }
else if (channel == 14) {
1244 }
else if (channel >= 15 && channel <= 26) {
1245 athchan->
a2_athchan = ((channel - 14) * 4) + 132;
1259 ath5k_hw_rf5111_channel(
struct ath5k_hw *ah,
1263 unsigned int ath5k_channel =
1275 ret = ath5k_hw_rf5111_chan2athchan(
1277 &ath5k_channel_2ghz);
1281 ath5k_channel = ath5k_channel_2ghz.a2_athchan;
1282 data0 = ((ath5k_hw_bitswap(ath5k_channel_2ghz.a2_flags, 8) & 0xff)
1286 if (ath5k_channel < 145 || !(ath5k_channel & 1)) {
1288 data1 = ((ath5k_hw_bitswap(ath5k_channel - 24, 8) & 0xff) << 2) |
1289 (clock << 1) | (1 << 10) | 1;
1292 data1 = ((ath5k_hw_bitswap((ath5k_channel - 24) / 2, 8) & 0xff)
1293 << 2) | (clock << 1) | (1 << 10) | 1;
1296 ath5k_hw_reg_write(ah, (data1 & 0xff) | ((data0 & 0xff) << 8),
1298 ath5k_hw_reg_write(ah, ((data1 >> 8) & 0xff) | (data0 & 0xff00),
1317 ath5k_hw_rf5112_channel(
struct ath5k_hw *ah,
1323 data = data0 = data1 = data2 = 0;
1334 if (!((c - 2224) % 5)) {
1336 data0 = ((2 * (c - 704)) - 3040) / 10;
1340 }
else if (!((c - 2192) % 5)) {
1342 data0 = ((2 * (c - 672)) - 3040) / 10;
1347 data0 = ath5k_hw_bitswap((data0 << 2) & 0xff, 8);
1357 }
else if ((c % 5) != 2 || c > 5435) {
1358 if (!(c % 20) && c >= 5120) {
1359 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1360 data2 = ath5k_hw_bitswap(3, 2);
1361 }
else if (!(c % 10)) {
1362 data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1363 data2 = ath5k_hw_bitswap(2, 2);
1364 }
else if (!(c % 5)) {
1365 data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
1366 data2 = ath5k_hw_bitswap(1, 2);
1370 data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8);
1371 data2 = ath5k_hw_bitswap(0, 2);
1374 data = (data0 << 4) | (data1 << 1) | (data2 << 2) | 0x1001;
1391 ath5k_hw_rf2425_channel(
struct ath5k_hw *ah,
1397 data = data0 = data2 = 0;
1401 data0 = ath5k_hw_bitswap((c - 2272), 8);
1404 }
else if ((c % 5) != 2 || c > 5435) {
1405 if (!(c % 20) && c < 5120)
1406 data0 = ath5k_hw_bitswap(((c - 4800) / 20 << 2), 8);
1408 data0 = ath5k_hw_bitswap(((c - 4800) / 10 << 1), 8);
1410 data0 = ath5k_hw_bitswap((c - 4800) / 5, 8);
1413 data2 = ath5k_hw_bitswap(1, 2);
1415 data0 = ath5k_hw_bitswap((10 * (c - 2 - 4800)) / 25 + 1, 8);
1416 data2 = ath5k_hw_bitswap(0, 2);
1419 data = (data0 << 4) | data2 << 2 | 0x1001;
1436 ath5k_hw_channel(
struct ath5k_hw *ah,
1446 "channel frequency (%u MHz) out of supported "
1457 ret = ath5k_hw_rf5110_channel(ah, channel);
1460 ret = ath5k_hw_rf5111_channel(ah, channel);
1464 ret = ath5k_hw_rf2425_channel(ah, channel);
1467 ret = ath5k_hw_rf5112_channel(ah, channel);
1527 ath5k_hw_read_measured_noise_floor(
struct ath5k_hw *ah)
1554 static void ath5k_hw_update_nfcal_hist(
struct ath5k_hw *ah,
s16 noise_floor)
1566 ath5k_hw_get_median_noise_floor(
struct ath5k_hw *ah)
1574 for (j = 1; j < ATH5K_NF_CAL_HIST_MAX -
i; j++) {
1575 if (sort[j] > sort[j - 1]) {
1577 sort[
j] = sort[j - 1];
1584 "cal %d:%d\n", i, sort[i]);
1586 return sort[(ATH5K_NF_CAL_HIST_MAX - 1) / 2];
1608 "NF did not complete in calibration window\n");
1618 nf = ath5k_hw_read_measured_noise_floor(ah);
1621 if (nf > threshold) {
1623 "noise floor failure detected; "
1624 "read %d, threshold %d\n",
1630 ath5k_hw_update_nfcal_hist(ah, nf);
1631 nf = ath5k_hw_get_median_noise_floor(ah);
1655 AR5K_PHY_AGCCTL_NF);
1662 "noise floor calibrated: %d\n", nf);
1673 ath5k_hw_rf5110_calibrate(
struct ath5k_hw *ah,
1697 ret = ath5k_hw_channel(ah, channel);
1756 ATH5K_ERR(ah,
"calibration timeout (%uMHz)\n",
1776 ath5k_hw_rf511x_iq_calibrate(
struct ath5k_hw *ah)
1779 s32 iq_corr, i_coff, i_coffd, q_coff, q_coffd;
1787 "I/Q calibration still running");
1795 for (i = 0; i <= 10; i++) {
1800 "iq_corr:%x i_pwr:%x q_pwr:%x", iq_corr, i_pwr, q_pwr);
1805 i_coffd = ((i_pwr >> 1) + (q_pwr >> 1)) >> 7;
1808 q_coffd = q_pwr >> 6;
1810 q_coffd = q_pwr >> 7;
1815 if (i_coffd == 0 || q_coffd < 2)
1820 i_coff = (-iq_corr) / i_coffd;
1821 i_coff =
clamp(i_coff, -32, 31);
1824 q_coff = (i_pwr / q_coffd) - 64;
1826 q_coff = (i_pwr / q_coffd) - 128;
1827 q_coff =
clamp(q_coff, -16, 15);
1830 "new I:%d Q:%d (i_coffd:%x q_coffd:%x)",
1831 i_coff, q_coff, i_coffd, q_coffd);
1863 return ath5k_hw_rf5110_calibrate(ah, channel);
1865 ret = ath5k_hw_rf511x_iq_calibrate(ah);
1868 "No I/Q correction performed (%uMHz)\n",
1882 ath5k_hw_request_rfgain_probe(ah);
1907 ath5k_hw_set_spur_mitigation_filter(
struct ath5k_hw *ah,
1911 u32 mag_mask[4] = {0, 0, 0, 0};
1912 u32 pilot_mask[2] = {0, 0};
1914 u16 spur_chan_fbin, chan_fbin, symbol_width, spur_detection_window;
1915 s32 spur_delta_phase, spur_freq_sigma_delta;
1916 s32 spur_offset, num_symbols_x16;
1917 u8 num_symbol_offsets,
i, freq_band;
1936 spur_detection_window *= 2;
1948 if ((chan_fbin - spur_detection_window <=
1950 (chan_fbin + spur_detection_window >=
1951 (spur_chan_fbin & AR5K_EEPROM_SPUR_CHAN_MASK))) {
1958 if (spur_chan_fbin) {
1959 spur_offset = spur_chan_fbin - chan_fbin;
1969 spur_delta_phase = (spur_offset << 16) / 25;
1970 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1975 spur_delta_phase = (spur_offset << 18) / 25;
1976 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1981 spur_delta_phase = (spur_offset << 19) / 25;
1982 spur_freq_sigma_delta = (spur_delta_phase >> 10);
1988 spur_delta_phase = (spur_offset << 17) / 25;
1989 spur_freq_sigma_delta =
1990 (spur_delta_phase >> 10);
1996 spur_delta_phase = (spur_offset << 17) / 25;
1997 spur_freq_sigma_delta =
1998 (spur_offset << 8) / 55;
2010 num_symbols_x16 = ((spur_offset * 1000) << 4) / symbol_width;
2013 if (!(num_symbols_x16 & 0xF))
2015 num_symbol_offsets = 3;
2018 num_symbol_offsets = 4;
2020 for (i = 0; i < num_symbol_offsets; i++) {
2024 (num_symbols_x16 / 16) + i + 25;
2032 (i == 0 || i == (num_symbol_offsets - 1))
2035 if (curr_sym_off >= 0 && curr_sym_off <= 32) {
2036 if (curr_sym_off <= 25)
2037 pilot_mask[0] |= 1 << curr_sym_off;
2038 else if (curr_sym_off >= 27)
2039 pilot_mask[0] |= 1 << (curr_sym_off - 1);
2040 }
else if (curr_sym_off >= 33 && curr_sym_off <= 52)
2041 pilot_mask[1] |= 1 << (curr_sym_off - 33);
2044 if (curr_sym_off >= -1 && curr_sym_off <= 14)
2046 plt_mag_map << (curr_sym_off + 1) * 2;
2047 else if (curr_sym_off >= 15 && curr_sym_off <= 30)
2049 plt_mag_map << (curr_sym_off - 15) * 2;
2050 else if (curr_sym_off >= 31 && curr_sym_off <= 46)
2052 plt_mag_map << (curr_sym_off - 31) * 2;
2053 else if (curr_sym_off >= 47 && curr_sym_off <= 53)
2055 plt_mag_map << (curr_sym_off - 47) * 2;
2069 ath5k_hw_reg_write(ah,
2111 AR5K_PHY_IQ_SPUR_FILT_EN);
2203 ath5k_hw_set_def_antenna(
struct ath5k_hw *ah,
u8 ant)
2286 ath5k_hw_reg_write(ah, ah->
ah_ant_ctl[ee_mode][ant0],
2288 ath5k_hw_reg_write(ah, ah->
ah_ant_ctl[ee_mode][ant1],
2301 bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div;
2302 bool use_def_for_sg;
2309 if (channel ==
NULL) {
2326 use_def_for_tx =
false;
2327 update_def_on_tx =
false;
2328 use_def_for_rts =
false;
2329 use_def_for_sg =
false;
2335 use_def_for_tx =
true;
2336 update_def_on_tx =
false;
2337 use_def_for_rts =
true;
2338 use_def_for_sg =
true;
2344 use_def_for_tx =
true;
2345 update_def_on_tx =
false;
2346 use_def_for_rts =
true;
2347 use_def_for_sg =
true;
2353 use_def_for_tx =
true;
2354 update_def_on_tx =
true;
2355 use_def_for_rts =
true;
2356 use_def_for_sg =
true;
2361 use_def_for_tx =
false;
2362 update_def_on_tx =
false;
2363 use_def_for_rts =
true;
2364 use_def_for_sg =
false;
2369 use_def_for_tx =
true;
2370 update_def_on_tx =
false;
2371 use_def_for_rts =
true;
2372 use_def_for_sg =
false;
2378 use_def_for_tx =
false;
2379 update_def_on_tx =
false;
2380 use_def_for_rts =
false;
2381 use_def_for_sg =
false;
2405 ath5k_hw_set_fast_div(ah, ee_mode, fast_div);
2406 ath5k_hw_set_def_antenna(ah, def_ant);
2434 if ((x_left == x_right) || (y_left == y_right))
2443 ratio = ((100 * y_right - 100 * y_left) / (x_right - x_left));
2446 result = y_left + (ratio * (target - x_left) / 100);
2465 ath5k_get_linear_pcdac_min(
const u8 *stepL,
const u8 *stepR,
2466 const s16 *pwrL,
const s16 *pwrR)
2469 s16 min_pwrL, min_pwrR;
2473 if (stepL[0] == stepL[1] || stepR[0] == stepR[1])
2474 return max(pwrL[0], pwrR[0]);
2476 if (pwrL[0] == pwrL[1])
2482 tmp = (
s8) ath5k_get_interpolated_value(pwr_i,
2484 stepL[0], stepL[1]);
2490 if (pwrR[0] == pwrR[1])
2496 tmp = (
s8) ath5k_get_interpolated_value(pwr_i,
2498 stepR[0], stepR[1]);
2505 return max(min_pwrL, min_pwrR);
2530 ath5k_create_power_curve(
s16 pmin,
s16 pmax,
2535 u8 idx[2] = { 0, 1 };
2536 s16 pwr_i = 2 * pmin;
2554 for (i = 0; (i <= (
u16) (pmax - pmin)) &&
2560 if ((pwr_i > pwr[idx[1]]) && (idx[1] < num_points - 1)) {
2565 vpd_table[
i] = (
u8) ath5k_get_interpolated_value(pwr_i,
2566 pwr[idx[0]], pwr[idx[1]],
2567 vpd[idx[0]], vpd[idx[1]]);
2589 ath5k_get_chan_pcal_surrounding_piers(
struct ath5k_hw *ah,
2623 if (target < pcinfo[0].
freq) {
2631 if (target > pcinfo[max].freq) {
2632 idx_l = idx_r =
max;
2640 for (i = 0; i <=
max; i++) {
2645 if (pcinfo[i].freq == target) {
2653 if (target < pcinfo[i].freq) {
2661 *pcinfo_l = &pcinfo[idx_l];
2662 *pcinfo_r = &pcinfo[idx_r];
2678 ath5k_get_rate_pcal_data(
struct ath5k_hw *ah,
2710 if (target < rpinfo[0].freq) {
2715 if (target > rpinfo[max].freq) {
2716 idx_l = idx_r =
max;
2720 for (i = 0; i <=
max; i++) {
2722 if (rpinfo[i].freq == target) {
2727 if (target < rpinfo[i].freq) {
2739 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2742 rpinfo[idx_r].target_power_6to24);
2745 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2748 rpinfo[idx_r].target_power_36);
2751 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2754 rpinfo[idx_r].target_power_48);
2757 ath5k_get_interpolated_value(target, rpinfo[idx_l].freq,
2760 rpinfo[idx_r].target_power_54);
2773 ath5k_get_max_ctl_power(
struct ath5k_hw *ah,
2809 for (i = 0; i < ee->
ee_ctls; i++) {
2810 if (ctl_val[i] == ctl_mode) {
2818 if (ctl_idx == 0xFF)
2834 if (target <= rep[rep_idx].freq)
2835 edge_pwr = (
s16) rep[rep_idx].
edge;
2839 ah->
ah_txpower.txp_max_pwr = 4 *
min(edge_pwr, max_chan_pwr);
2886 ath5k_fill_pwr_to_pcdac_table(
struct ath5k_hw *ah,
s16* table_min,
2891 u8 pcdac_0, pcdac_n, pcdac_i, pwr_idx,
i;
2892 s16 min_pwr, max_pwr;
2895 min_pwr = table_min[0];
2896 pcdac_0 = pcdac_tmp[0];
2898 max_pwr = table_max[0];
2899 pcdac_n = pcdac_tmp[table_max[0] - table_min[0]];
2903 for (i = 0; i < min_pwr; i++)
2904 pcdac_out[pcdac_i++] = pcdac_0;
2908 for (i = 0; pwr_idx <= max_pwr &&
2910 pcdac_out[pcdac_i++] = pcdac_tmp[
i];
2915 while (pcdac_i < AR5K_EEPROM_POWER_TABLE_SIZE)
2916 pcdac_out[pcdac_i++] = pcdac_n;
2936 ath5k_combine_linear_pcdac_curves(
struct ath5k_hw *ah,
s16* table_min,
2937 s16 *table_max,
u8 pdcurves)
2946 s16 mid_pwr_idx = 0;
2963 mid_pwr_idx = table_max[1] - table_min[1] - 1;
2964 max_pwr_idx = (table_max[0] - table_min[0]) / 2;
2969 if (table_max[0] - table_min[1] > 126)
2970 min_pwr_idx = table_max[0] - 126;
2972 min_pwr_idx = table_min[1];
2976 pcdac_tmp = pcdac_high_pwr;
2982 min_pwr_idx = table_min[0];
2983 max_pwr_idx = (table_max[0] - table_min[0]) / 2;
2984 pcdac_tmp = pcdac_high_pwr;
2989 ah->
ah_txpower.txp_min_idx = min_pwr_idx / 2;
2993 for (i = 63; i >= 0; i--) {
2997 if (edge_flag == 0x40 &&
2998 (2 * pwr <= (table_max[1] - table_min[0]) || pwr == 0)) {
3000 pcdac_tmp = pcdac_low_pwr;
3001 pwr = mid_pwr_idx / 2;
3008 if (pcdac_tmp[pwr] < 1 && (edge_flag == 0x00)) {
3010 pcdac_out[
i] = pcdac_out[i + 1];
3016 pcdac_out[
i] = pcdac_tmp[pwr] | edge_flag;
3021 if (pcdac_out[i] > 126)
3034 ath5k_write_pcdac_table(
struct ath5k_hw *ah)
3042 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
3043 ath5k_hw_reg_write(ah,
3044 (((pcdac_out[2 * i + 0] << 8 | 0xff) & 0xffff) << 0) |
3045 (((pcdac_out[2 * i + 1] << 8 | 0xff) & 0xffff) << 16),
3086 ath5k_combine_pwr_to_pdadc_curves(
struct ath5k_hw *ah,
3087 s16 *pwr_min,
s16 *pwr_max,
u8 pdcurves)
3093 u8 pdadc_i, pdadc_n, pwr_step, pdg,
max_idx, table_size;
3103 for (pdg = 0, pdadc_i = 0; pdg < pdcurves; pdg++) {
3106 if (pdg == pdcurves - 1)
3109 gain_boundaries[pdg] = pwr_max[pdg] + 4;
3113 gain_boundaries[pdg] =
3114 (pwr_max[pdg] + pwr_min[pdg + 1]) / 2;
3127 pdadc_0 = (gain_boundaries[pdg - 1] - pwr_min[pdg]) -
3131 if ((pdadc_tmp[1] - pdadc_tmp[0]) > 1)
3132 pwr_step = pdadc_tmp[1] - pdadc_tmp[0];
3138 while ((pdadc_0 < 0) && (pdadc_i < 128)) {
3139 s16 tmp = pdadc_tmp[0] + pdadc_0 * pwr_step;
3140 pdadc_out[pdadc_i++] = (tmp < 0) ? 0 : (
u8)
tmp;
3145 pdadc_n = gain_boundaries[pdg] + pd_gain_overlap - pwr_min[pdg];
3147 table_size = pwr_max[pdg] - pwr_min[pdg];
3148 max_idx = (pdadc_n < table_size) ? pdadc_n : table_size;
3151 while (pdadc_0 < max_idx && pdadc_i < 128)
3152 pdadc_out[pdadc_i++] = pdadc_tmp[pdadc_0++];
3155 if (pdadc_n <= max_idx)
3159 if ((pdadc_tmp[table_size - 1] - pdadc_tmp[table_size - 2]) > 1)
3160 pwr_step = pdadc_tmp[table_size - 1] -
3161 pdadc_tmp[table_size - 2];
3166 while ((pdadc_0 < (
s16) pdadc_n) &&
3167 (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2)) {
3168 s16 tmp = pdadc_tmp[table_size - 1] +
3169 (pdadc_0 -
max_idx) * pwr_step;
3170 pdadc_out[pdadc_i++] = (tmp > 127) ? 127 : (
u8)
tmp;
3176 gain_boundaries[pdg] = gain_boundaries[pdg - 1];
3180 while (pdadc_i < AR5K_EEPROM_POWER_TABLE_SIZE * 2) {
3181 pdadc_out[pdadc_i] = pdadc_out[pdadc_i - 1];
3186 ath5k_hw_reg_write(ah,
3210 ath5k_write_pwr_to_pdadc_table(
struct ath5k_hw *ah,
u8 ee_mode)
3254 for (i = 0; i < (AR5K_EEPROM_POWER_TABLE_SIZE / 2); i++) {
3279 ath5k_setup_channel_powertable(
struct ath5k_hw *ah,
3281 u8 ee_mode,
u8 type)
3296 ath5k_get_chan_pcal_surrounding_piers(ah, channel,
3302 for (pdg = 0; pdg < ee->
ee_pd_gains[ee_mode]; pdg++) {
3308 u8 idx = pdg_curve_to_idx[pdg];
3349 if (!(ee->
ee_pd_gains[ee_mode] > 1 && pdg == 0)) {
3352 ath5k_get_linear_pcdac_min(pdg_L->
pd_step,
3361 if (table_max[pdg] - table_min[pdg] > 126)
3362 table_min[pdg] = table_max[pdg] - 126;
3369 ath5k_create_power_curve(table_min[pdg],
3378 if (pcinfo_L == pcinfo_R)
3381 ath5k_create_power_curve(table_min[pdg],
3396 for (i = 0; (i < (
u16) (table_max[pdg] - table_min[pdg])) &&
3397 (i < AR5K_EEPROM_POWER_TABLE_SIZE); i++) {
3398 tmpL[
i] = (
u8) ath5k_get_interpolated_value(target,
3417 ah->
ah_txpower.txp_min_pwr = ath5k_get_interpolated_value(target,
3422 ah->
ah_txpower.txp_max_pwr = ath5k_get_interpolated_value(target,
3433 ath5k_combine_linear_pcdac_curves(ah, table_min, table_max,
3439 ah->
ah_txpower.txp_offset = 64 - (table_max[0] / 2);
3444 ath5k_fill_pwr_to_pcdac_table(ah, table_min, table_max);
3453 ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
3476 ath5k_write_channel_powertable(
struct ath5k_hw *ah,
u8 ee_mode,
u8 type)
3479 ath5k_write_pwr_to_pdadc_table(ah, ee_mode);
3481 ath5k_write_pcdac_table(ah);
3515 ath5k_setup_rate_powertable(
struct ath5k_hw *ah,
u16 max_pwr,
3521 s16 rate_idx_scaled = 0;
3529 rates = ah->
ah_txpower.txp_rates_power_table;
3532 for (i = 0; i < 5; i++)
3565 for (i = 8; i <= 15; i++)
3566 rates[i] -= ah->
ah_txpower.txp_cck_ofdm_gainf_delta;
3585 for (i = 0; i < 16; i++) {
3586 rate_idx_scaled = rates[
i] + ah->
ah_txpower.txp_offset;
3588 if (rate_idx_scaled > 63)
3589 rate_idx_scaled = 63;
3590 if (rate_idx_scaled < 0)
3591 rate_idx_scaled = 0;
3592 rates[
i] = rate_idx_scaled;
3617 ATH5K_ERR(ah,
"invalid tx power: %u\n", txpower);
3659 int requested_txpower = ah->
ah_txpower.txp_requested;
3666 ah->
ah_txpower.txp_requested = requested_txpower;
3669 ret = ath5k_setup_channel_powertable(ah, channel,
3676 ath5k_write_channel_powertable(ah, ee_mode, type);
3679 ath5k_get_max_ctl_power(ah, channel);
3689 ath5k_get_rate_pcal_data(ah, channel, &rate_info);
3692 ath5k_setup_rate_powertable(ah, txpower, &rate_info, ee_mode);
3716 ath5k_hw_reg_write(ah,
3741 "changing txpower to %d\n", txpower);
3790 for (i = 0; i < 100; i++) {
3800 ret = ath5k_hw_channel(ah, channel);
3804 ath5k_hw_wait_for_synth(ah, channel);
3814 ret = ath5k_hw_txpower(ah, channel, ah->
ah_txpower.txp_requested ?
3824 ret = ath5k_hw_write_ofdm_timings(ah, channel);
3832 ath5k_hw_set_spur_mitigation_filter(ah,
3872 ret = ath5k_hw_rfgain_init(ah, channel->
band);
3881 ret = ath5k_hw_rfregs_init(ah, channel, mode);
3904 ret = ath5k_hw_channel(ah, channel);
3915 ath5k_hw_wait_for_synth(ah, channel);
3923 for (i = 0; i <= 20; i++) {
3967 ATH5K_ERR(ah,
"gain calibration timeout (%uMHz)\n",