aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k/phy.c
diff options
context:
space:
mode:
authorNick Kossifidis <mick@madwifi-project.org>2009-02-08 23:03:41 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-13 13:44:43 -0500
commit6f3b414aca060a847e243f676b8601731938eb48 (patch)
tree51345c9930dbb9281d2f3dd0ebf0268870caa357 /drivers/net/wireless/ath5k/phy.c
parent33a31826b4fe9f26d6b383bad19b7ae522fda006 (diff)
ath5k: Update gain_F calibration code and add documentation
* Update and cleanup rf gain optimization code * Add comments and refferences to docs and use sane function names * Use only step index on ath5k_gain, no need to have a pointer to the current step since we can determine te step from it's index, this also allows us to put all other structs on rfgain.h and cleanup ath5k.h a little * No need for ah_rfgain variable, we use ah_gain.g_state for everything * Tested on RF2112B chip but gain_F calibration is not yet done (we will finish this on the next patch where we'll rewrite rf-buffer handling) * Use initial rf gain settings for 2316 and 2317 SoCs introduced on a previous patch It seems big but it's mostly cleanup, very few functional changes have been made on phy.c Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k/phy.c')
-rw-r--r--drivers/net/wireless/ath5k/phy.c403
1 files changed, 264 insertions, 139 deletions
diff --git a/drivers/net/wireless/ath5k/phy.c b/drivers/net/wireless/ath5k/phy.c
index 5021749a439e..2543a718fe3f 100644
--- a/drivers/net/wireless/ath5k/phy.c
+++ b/drivers/net/wireless/ath5k/phy.c
@@ -78,10 +78,104 @@ static unsigned int ath5k_hw_rfregs_op(u32 *rf, u32 offset, u32 reg, u32 bits,
78 return data; 78 return data;
79} 79}
80 80
81static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah) 81/**********************\
82* RF Gain optimization *
83\**********************/
84
85/*
86 * This code is used to optimize rf gain on different environments
87 * (temprature mostly) based on feedback from a power detector.
88 *
89 * It's only used on RF5111 and RF5112, later RF chips seem to have
90 * auto adjustment on hw -notice they have a much smaller BANK 7 and
91 * no gain optimization ladder-.
92 *
93 * For more infos check out this patent doc
94 * http://www.freepatentsonline.com/7400691.html
95 *
96 * This paper describes power drops as seen on the receiver due to
97 * probe packets
98 * http://www.cnri.dit.ie/publications/ICT08%20-%20Practical%20Issues
99 * %20of%20Power%20Control.pdf
100 *
101 * And this is the MadWiFi bug entry related to the above
102 * http://madwifi-project.org/ticket/1659
103 * with various measurements and diagrams
104 *
105 * TODO: Deal with power drops due to probes by setting an apropriate
106 * tx power on the probe packets ! Make this part of the calibration process.
107 */
108
109/* Initialize ah_gain durring attach */
110int ath5k_hw_rfgain_opt_init(struct ath5k_hw *ah)
111{
112 /* Initialize the gain optimization values */
113 switch (ah->ah_radio) {
114 case AR5K_RF5111:
115 ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
116 ah->ah_gain.g_low = 20;
117 ah->ah_gain.g_high = 35;
118 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
119 break;
120 case AR5K_RF5112:
121 ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
122 ah->ah_gain.g_low = 20;
123 ah->ah_gain.g_high = 85;
124 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
125 break;
126 default:
127 return -EINVAL;
128 }
129
130 return 0;
131}
132
133/* Schedule a gain probe check on the next transmited packet.
134 * That means our next packet is going to be sent with lower
135 * tx power and a Peak to Average Power Detector (PAPD) will try
136 * to measure the gain.
137 *
138 * TODO: Use propper tx power setting for the probe packet so
139 * that we don't observe a serious power drop on the receiver
140 *
141 * XXX: How about forcing a tx packet (bypassing PCU arbitrator etc)
142 * just after we enable the probe so that we don't mess with
143 * standard traffic ? Maybe it's time to use sw interrupts and
144 * a probe tasklet !!!
145 */
146static void ath5k_hw_request_rfgain_probe(struct ath5k_hw *ah)
147{
148
149 /* Skip if gain calibration is inactive or
150 * we already handle a probe request */
151 if (ah->ah_gain.g_state != AR5K_RFGAIN_ACTIVE)
152 return;
153
154 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
155 AR5K_PHY_PAPD_PROBE_TXPOWER) |
156 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
157
158 ah->ah_gain.g_state = AR5K_RFGAIN_READ_REQUESTED;
159
160}
161
162/* Calculate gain_F measurement correction
163 * based on the current step for RF5112 rev. 2 */
164static u32 ath5k_hw_rf_gainf_corr(struct ath5k_hw *ah)
82{ 165{
83 u32 mix, step; 166 u32 mix, step;
84 u32 *rf; 167 u32 *rf;
168 const struct ath5k_gain_opt *go;
169 const struct ath5k_gain_opt_step *g_step;
170
171 /* Only RF5112 Rev. 2 supports it */
172 if ((ah->ah_radio != AR5K_RF5112) ||
173 (ah->ah_radio_5ghz_revision <= AR5K_SREV_RAD_5112A))
174 return 0;
175
176 go = &rfgain_opt_5112;
177
178 g_step = &go->go_step[ah->ah_gain.g_step_idx];
85 179
86 if (ah->ah_rf_banks == NULL) 180 if (ah->ah_rf_banks == NULL)
87 return 0; 181 return 0;
@@ -89,11 +183,15 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
89 rf = ah->ah_rf_banks; 183 rf = ah->ah_rf_banks;
90 ah->ah_gain.g_f_corr = 0; 184 ah->ah_gain.g_f_corr = 0;
91 185
186 /* No VGA (Variable Gain Amplifier) override, skip */
92 if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1) 187 if (ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, false) != 1)
93 return 0; 188 return 0;
94 189
190 /* Mix gain stepping */
95 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false); 191 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 4, 32, 0, false);
96 mix = ah->ah_gain.g_step->gos_param[0]; 192
193 /* Mix gain override */
194 mix = g_step->gos_param[0];
97 195
98 switch (mix) { 196 switch (mix) {
99 case 3: 197 case 3:
@@ -113,9 +211,13 @@ static u32 ath5k_hw_rfregs_gainf_corr(struct ath5k_hw *ah)
113 return ah->ah_gain.g_f_corr; 211 return ah->ah_gain.g_f_corr;
114} 212}
115 213
116static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah) 214/* Check if current gain_F measurement is in the range of our
215 * power detector windows. If we get a measurement outside range
216 * we know it's not accurate (detectors can't measure anything outside
217 * their detection window) so we must ignore it */
218static bool ath5k_hw_rf_check_gainf_readback(struct ath5k_hw *ah)
117{ 219{
118 u32 step, mix, level[4]; 220 u32 step, mix_ovr, level[4];
119 u32 *rf; 221 u32 *rf;
120 222
121 if (ah->ah_rf_banks == NULL) 223 if (ah->ah_rf_banks == NULL)
@@ -127,20 +229,20 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
127 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0, 229 step = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 6, 37, 0,
128 false); 230 false);
129 level[0] = 0; 231 level[0] = 0;
130 level[1] = (step == 0x3f) ? 0x32 : step + 4; 232 level[1] = (step == 63) ? 50 : step + 4;
131 level[2] = (step != 0x3f) ? 0x40 : level[0]; 233 level[2] = (step != 63) ? 64 : level[0];
132 level[3] = level[2] + 0x32; 234 level[3] = level[2] + 50 ;
133 235
134 ah->ah_gain.g_high = level[3] - 236 ah->ah_gain.g_high = level[3] -
135 (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5); 237 (step == 63 ? AR5K_GAIN_DYN_ADJUST_HI_MARGIN : -5);
136 ah->ah_gain.g_low = level[0] + 238 ah->ah_gain.g_low = level[0] +
137 (step == 0x3f ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0); 239 (step == 63 ? AR5K_GAIN_DYN_ADJUST_LO_MARGIN : 0);
138 } else { 240 } else {
139 mix = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0, 241 mix_ovr = ath5k_hw_rfregs_op(rf, ah->ah_offset[7], 0, 1, 36, 0,
140 false); 242 false);
141 level[0] = level[2] = 0; 243 level[0] = level[2] = 0;
142 244
143 if (mix == 1) { 245 if (mix_ovr == 1) {
144 level[1] = level[3] = 83; 246 level[1] = level[3] = 83;
145 } else { 247 } else {
146 level[1] = level[3] = 107; 248 level[1] = level[3] = 107;
@@ -154,9 +256,12 @@ static bool ath5k_hw_rfregs_gain_readback(struct ath5k_hw *ah)
154 ah->ah_gain.g_current <= level[3]); 256 ah->ah_gain.g_current <= level[3]);
155} 257}
156 258
157static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah) 259/* Perform gain_F adjustment by choosing the right set
260 * of parameters from rf gain optimization ladder */
261static s8 ath5k_hw_rf_gainf_adjust(struct ath5k_hw *ah)
158{ 262{
159 const struct ath5k_gain_opt *go; 263 const struct ath5k_gain_opt *go;
264 const struct ath5k_gain_opt_step *g_step;
160 int ret = 0; 265 int ret = 0;
161 266
162 switch (ah->ah_radio) { 267 switch (ah->ah_radio) {
@@ -170,35 +275,39 @@ static s32 ath5k_hw_rfregs_gain_adjust(struct ath5k_hw *ah)
170 return 0; 275 return 0;
171 } 276 }
172 277
173 ah->ah_gain.g_step = &go->go_step[ah->ah_gain.g_step_idx]; 278 g_step = &go->go_step[ah->ah_gain.g_step_idx];
174 279
175 if (ah->ah_gain.g_current >= ah->ah_gain.g_high) { 280 if (ah->ah_gain.g_current >= ah->ah_gain.g_high) {
281
282 /* Reached maximum */
176 if (ah->ah_gain.g_step_idx == 0) 283 if (ah->ah_gain.g_step_idx == 0)
177 return -1; 284 return -1;
285
178 for (ah->ah_gain.g_target = ah->ah_gain.g_current; 286 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
179 ah->ah_gain.g_target >= ah->ah_gain.g_high && 287 ah->ah_gain.g_target >= ah->ah_gain.g_high &&
180 ah->ah_gain.g_step_idx > 0; 288 ah->ah_gain.g_step_idx > 0;
181 ah->ah_gain.g_step = 289 g_step = &go->go_step[ah->ah_gain.g_step_idx])
182 &go->go_step[ah->ah_gain.g_step_idx])
183 ah->ah_gain.g_target -= 2 * 290 ah->ah_gain.g_target -= 2 *
184 (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain - 291 (go->go_step[--(ah->ah_gain.g_step_idx)].gos_gain -
185 ah->ah_gain.g_step->gos_gain); 292 g_step->gos_gain);
186 293
187 ret = 1; 294 ret = 1;
188 goto done; 295 goto done;
189 } 296 }
190 297
191 if (ah->ah_gain.g_current <= ah->ah_gain.g_low) { 298 if (ah->ah_gain.g_current <= ah->ah_gain.g_low) {
299
300 /* Reached minimum */
192 if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1)) 301 if (ah->ah_gain.g_step_idx == (go->go_steps_count - 1))
193 return -2; 302 return -2;
303
194 for (ah->ah_gain.g_target = ah->ah_gain.g_current; 304 for (ah->ah_gain.g_target = ah->ah_gain.g_current;
195 ah->ah_gain.g_target <= ah->ah_gain.g_low && 305 ah->ah_gain.g_target <= ah->ah_gain.g_low &&
196 ah->ah_gain.g_step_idx < go->go_steps_count-1; 306 ah->ah_gain.g_step_idx < go->go_steps_count-1;
197 ah->ah_gain.g_step = 307 g_step = &go->go_step[ah->ah_gain.g_step_idx])
198 &go->go_step[ah->ah_gain.g_step_idx])
199 ah->ah_gain.g_target -= 2 * 308 ah->ah_gain.g_target -= 2 *
200 (go->go_step[++ah->ah_gain.g_step_idx].gos_gain - 309 (go->go_step[++ah->ah_gain.g_step_idx].gos_gain -
201 ah->ah_gain.g_step->gos_gain); 310 g_step->gos_gain);
202 311
203 ret = 2; 312 ret = 2;
204 goto done; 313 goto done;
@@ -213,6 +322,135 @@ done:
213 return ret; 322 return ret;
214} 323}
215 324
325/* Main callback for thermal rf gain calibration engine
326 * Check for a new gain reading and schedule an adjustment
327 * if needed.
328 *
329 * TODO: Use sw interrupt to schedule reset if gain_F needs
330 * adjustment */
331enum ath5k_rfgain ath5k_hw_gainf_calibrate(struct ath5k_hw *ah)
332{
333 u32 data, type;
334 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
335
336 ATH5K_TRACE(ah->ah_sc);
337
338 if (ah->ah_rf_banks == NULL ||
339 ah->ah_gain.g_state == AR5K_RFGAIN_INACTIVE)
340 return AR5K_RFGAIN_INACTIVE;
341
342 /* No check requested, either engine is inactive
343 * or an adjustment is already requested */
344 if (ah->ah_gain.g_state != AR5K_RFGAIN_READ_REQUESTED)
345 goto done;
346
347 /* Read the PAPD (Peak to Average Power Detector)
348 * register */
349 data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
350
351 /* No probe is scheduled, read gain_F measurement */
352 if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
353 ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
354 type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
355
356 /* If tx packet is CCK correct the gain_F measurement
357 * by cck ofdm gain delta */
358 if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK) {
359 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A)
360 ah->ah_gain.g_current +=
361 ee->ee_cck_ofdm_gain_delta;
362 else
363 ah->ah_gain.g_current +=
364 AR5K_GAIN_CCK_PROBE_CORR;
365 }
366
367 /* Further correct gain_F measurement for
368 * RF5112A radios */
369 if (ah->ah_radio_5ghz_revision >= AR5K_SREV_RAD_5112A) {
370 ath5k_hw_rf_gainf_corr(ah);
371 ah->ah_gain.g_current =
372 ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
373 (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
374 0;
375 }
376
377 /* Check if measurement is ok and if we need
378 * to adjust gain, schedule a gain adjustment,
379 * else switch back to the acive state */
380 if (ath5k_hw_rf_check_gainf_readback(ah) &&
381 AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
382 ath5k_hw_rf_gainf_adjust(ah)) {
383 ah->ah_gain.g_state = AR5K_RFGAIN_NEED_CHANGE;
384 } else {
385 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
386 }
387 }
388
389done:
390 return ah->ah_gain.g_state;
391}
392
393/* Write initial rf gain table to set the RF sensitivity
394 * this one works on all RF chips and has nothing to do
395 * with gain_F calibration */
396int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
397{
398 const struct ath5k_ini_rfgain *ath5k_rfg;
399 unsigned int i, size;
400
401 switch (ah->ah_radio) {
402 case AR5K_RF5111:
403 ath5k_rfg = rfgain_5111;
404 size = ARRAY_SIZE(rfgain_5111);
405 break;
406 case AR5K_RF5112:
407 ath5k_rfg = rfgain_5112;
408 size = ARRAY_SIZE(rfgain_5112);
409 break;
410 case AR5K_RF2413:
411 ath5k_rfg = rfgain_2413;
412 size = ARRAY_SIZE(rfgain_2413);
413 break;
414 case AR5K_RF2316:
415 ath5k_rfg = rfgain_2316;
416 size = ARRAY_SIZE(rfgain_2316);
417 break;
418 case AR5K_RF5413:
419 ath5k_rfg = rfgain_5413;
420 size = ARRAY_SIZE(rfgain_5413);
421 break;
422 case AR5K_RF2317:
423 case AR5K_RF2425:
424 ath5k_rfg = rfgain_2425;
425 size = ARRAY_SIZE(rfgain_2425);
426 break;
427 default:
428 return -EINVAL;
429 }
430
431 switch (freq) {
432 case AR5K_INI_RFGAIN_2GHZ:
433 case AR5K_INI_RFGAIN_5GHZ:
434 break;
435 default:
436 return -EINVAL;
437 }
438
439 for (i = 0; i < size; i++) {
440 AR5K_REG_WAIT(i);
441 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
442 (u32)ath5k_rfg[i].rfg_register);
443 }
444
445 return 0;
446}
447
448
449
450/********************\
451* RF Registers setup *
452\********************/
453
216/* 454/*
217 * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111 455 * Read EEPROM Calibration data, modify RF Banks and Initialize RF5111
218 */ 456 */
@@ -311,6 +549,8 @@ static int ath5k_hw_rf5111_rfregs(struct ath5k_hw *ah,
311 ath5k_hw_reg_write(ah, rf[i], rfb_5111[i].rfb_ctrl_register); 549 ath5k_hw_reg_write(ah, rf[i], rfb_5111[i].rfb_ctrl_register);
312 } 550 }
313 551
552 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
553
314 return 0; 554 return 0;
315} 555}
316 556
@@ -407,6 +647,9 @@ static int ath5k_hw_rf5112_rfregs(struct ath5k_hw *ah,
407 for (i = 0; i < rf_size; i++) 647 for (i = 0; i < rf_size; i++)
408 ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rfb_ctrl_register); 648 ath5k_hw_reg_write(ah, rf[i], rf_ini[i].rfb_ctrl_register);
409 649
650
651 ah->ah_gain.g_state = AR5K_RFGAIN_ACTIVE;
652
410 return 0; 653 return 0;
411} 654}
412 655
@@ -536,125 +779,12 @@ int ath5k_hw_rfregs(struct ath5k_hw *ah, struct ieee80211_channel *channel,
536 } 779 }
537 780
538 ret = func(ah, channel, mode); 781 ret = func(ah, channel, mode);
539 if (!ret)
540 ah->ah_rf_gain = AR5K_RFGAIN_INACTIVE;
541 782
542 return ret; 783 return ret;
543} 784}
544 785
545int ath5k_hw_rfgain(struct ath5k_hw *ah, unsigned int freq)
546{
547 const struct ath5k_ini_rfgain *ath5k_rfg;
548 unsigned int i, size;
549 786
550 switch (ah->ah_radio) {
551 case AR5K_RF5111:
552 ath5k_rfg = rfgain_5111;
553 size = ARRAY_SIZE(rfgain_5111);
554 break;
555 case AR5K_RF5112:
556 ath5k_rfg = rfgain_5112;
557 size = ARRAY_SIZE(rfgain_5112);
558 break;
559 case AR5K_RF5413:
560 ath5k_rfg = rfgain_5413;
561 size = ARRAY_SIZE(rfgain_5413);
562 break;
563 case AR5K_RF2413:
564 ath5k_rfg = rfgain_2413;
565 size = ARRAY_SIZE(rfgain_2413);
566 break;
567 case AR5K_RF2425:
568 ath5k_rfg = rfgain_2425;
569 size = ARRAY_SIZE(rfgain_2425);
570 break;
571 default:
572 return -EINVAL;
573 }
574 787
575 switch (freq) {
576 case AR5K_INI_RFGAIN_2GHZ:
577 case AR5K_INI_RFGAIN_5GHZ:
578 break;
579 default:
580 return -EINVAL;
581 }
582
583 for (i = 0; i < size; i++) {
584 AR5K_REG_WAIT(i);
585 ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
586 (u32)ath5k_rfg[i].rfg_register);
587 }
588
589 return 0;
590}
591
592enum ath5k_rfgain ath5k_hw_get_rf_gain(struct ath5k_hw *ah)
593{
594 u32 data, type;
595
596 ATH5K_TRACE(ah->ah_sc);
597
598 if (ah->ah_rf_banks == NULL || !ah->ah_gain.g_active ||
599 ah->ah_version <= AR5K_AR5211)
600 return AR5K_RFGAIN_INACTIVE;
601
602 if (ah->ah_rf_gain != AR5K_RFGAIN_READ_REQUESTED)
603 goto done;
604
605 data = ath5k_hw_reg_read(ah, AR5K_PHY_PAPD_PROBE);
606
607 if (!(data & AR5K_PHY_PAPD_PROBE_TX_NEXT)) {
608 ah->ah_gain.g_current = data >> AR5K_PHY_PAPD_PROBE_GAINF_S;
609 type = AR5K_REG_MS(data, AR5K_PHY_PAPD_PROBE_TYPE);
610
611 if (type == AR5K_PHY_PAPD_PROBE_TYPE_CCK)
612 ah->ah_gain.g_current += AR5K_GAIN_CCK_PROBE_CORR;
613
614 if (ah->ah_radio >= AR5K_RF5112) {
615 ath5k_hw_rfregs_gainf_corr(ah);
616 ah->ah_gain.g_current =
617 ah->ah_gain.g_current >= ah->ah_gain.g_f_corr ?
618 (ah->ah_gain.g_current-ah->ah_gain.g_f_corr) :
619 0;
620 }
621
622 if (ath5k_hw_rfregs_gain_readback(ah) &&
623 AR5K_GAIN_CHECK_ADJUST(&ah->ah_gain) &&
624 ath5k_hw_rfregs_gain_adjust(ah))
625 ah->ah_rf_gain = AR5K_RFGAIN_NEED_CHANGE;
626 }
627
628done:
629 return ah->ah_rf_gain;
630}
631
632int ath5k_hw_set_rfgain_opt(struct ath5k_hw *ah)
633{
634 /* Initialize the gain optimization values */
635 switch (ah->ah_radio) {
636 case AR5K_RF5111:
637 ah->ah_gain.g_step_idx = rfgain_opt_5111.go_default;
638 ah->ah_gain.g_step =
639 &rfgain_opt_5111.go_step[ah->ah_gain.g_step_idx];
640 ah->ah_gain.g_low = 20;
641 ah->ah_gain.g_high = 35;
642 ah->ah_gain.g_active = 1;
643 break;
644 case AR5K_RF5112:
645 ah->ah_gain.g_step_idx = rfgain_opt_5112.go_default;
646 ah->ah_gain.g_step =
647 &rfgain_opt_5112.go_step[ah->ah_gain.g_step_idx];
648 ah->ah_gain.g_low = 20;
649 ah->ah_gain.g_high = 85;
650 ah->ah_gain.g_active = 1;
651 break;
652 default:
653 return -EINVAL;
654 }
655
656 return 0;
657}
658 788
659/**************************\ 789/**************************\
660 PHY/RF channel functions 790 PHY/RF channel functions
@@ -1176,13 +1306,8 @@ done:
1176 * as often as I/Q calibration.*/ 1306 * as often as I/Q calibration.*/
1177 ath5k_hw_noise_floor_calibration(ah, channel->center_freq); 1307 ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
1178 1308
1179 /* Request RF gain */ 1309 /* Initiate a gain_F calibration */
1180 if (channel->hw_value & CHANNEL_5GHZ) { 1310 ath5k_hw_request_rfgain_probe(ah);
1181 ath5k_hw_reg_write(ah, AR5K_REG_SM(ah->ah_txpower.txp_max,
1182 AR5K_PHY_PAPD_PROBE_TXPOWER) |
1183 AR5K_PHY_PAPD_PROBE_TX_NEXT, AR5K_PHY_PAPD_PROBE);
1184 ah->ah_rf_gain = AR5K_RFGAIN_READ_REQUESTED;
1185 }
1186 1311
1187 return 0; 1312 return 0;
1188} 1313}