aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/ar9003_phy.c
diff options
context:
space:
mode:
authorLuis R. Rodriguez <lrodriguez@atheros.com>2010-04-15 17:38:40 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-16 15:43:25 -0400
commitaf914a9ffd60a841054e9fd248f12630df0698c5 (patch)
tree460379e2c7f959865b796e3e608be84666767f14 /drivers/net/wireless/ath/ath9k/ar9003_phy.c
parentc16fcb49b3849b4dceec9e4bbeb013b0713c7b38 (diff)
ath9k_hw: add all the AR9003 PHY callbacks
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/ar9003_phy.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c300
1 files changed, 289 insertions, 11 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 356e03db9cf1..c938b85c174e 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -225,7 +225,30 @@ static void ar9003_hw_set_channel_regs(struct ath_hw *ah,
225static void ar9003_hw_init_bb(struct ath_hw *ah, 225static void ar9003_hw_init_bb(struct ath_hw *ah,
226 struct ath9k_channel *chan) 226 struct ath9k_channel *chan)
227{ 227{
228 /* TODO */ 228 u32 synthDelay;
229
230 /*
231 * Wait for the frequency synth to settle (synth goes on
232 * via AR_PHY_ACTIVE_EN). Read the phy active delay register.
233 * Value is in 100ns increments.
234 */
235 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
236 if (IS_CHAN_B(chan))
237 synthDelay = (4 * synthDelay) / 22;
238 else
239 synthDelay /= 10;
240
241 /* Activate the PHY (includes baseband activate + synthesizer on) */
242 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_EN);
243
244 /*
245 * There is an issue if the AP starts the calibration before
246 * the base band timeout completes. This could result in the
247 * rx_clear false triggering. As a workaround we add delay an
248 * extra BASE_ACTIVATE_DELAY usecs to ensure this condition
249 * does not happen.
250 */
251 udelay(synthDelay + BASE_ACTIVATE_DELAY);
229} 252}
230 253
231void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx) 254void ar9003_hw_set_chain_masks(struct ath_hw *ah, u8 rx, u8 tx)
@@ -385,46 +408,301 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
385static void ar9003_hw_set_rfmode(struct ath_hw *ah, 408static void ar9003_hw_set_rfmode(struct ath_hw *ah,
386 struct ath9k_channel *chan) 409 struct ath9k_channel *chan)
387{ 410{
388 /* TODO */ 411 u32 rfMode = 0;
412
413 if (chan == NULL)
414 return;
415
416 rfMode |= (IS_CHAN_B(chan) || IS_CHAN_G(chan))
417 ? AR_PHY_MODE_DYNAMIC : AR_PHY_MODE_OFDM;
418
419 if (IS_CHAN_A_5MHZ_SPACED(chan))
420 rfMode |= (AR_PHY_MODE_DYNAMIC | AR_PHY_MODE_DYN_CCK_DISABLE);
421
422 REG_WRITE(ah, AR_PHY_MODE, rfMode);
389} 423}
390 424
391static void ar9003_hw_mark_phy_inactive(struct ath_hw *ah) 425static void ar9003_hw_mark_phy_inactive(struct ath_hw *ah)
392{ 426{
393 /* TODO */ 427 REG_WRITE(ah, AR_PHY_ACTIVE, AR_PHY_ACTIVE_DIS);
394} 428}
395 429
396static void ar9003_hw_set_delta_slope(struct ath_hw *ah, 430static void ar9003_hw_set_delta_slope(struct ath_hw *ah,
397 struct ath9k_channel *chan) 431 struct ath9k_channel *chan)
398{ 432{
399 /* TODO */ 433 u32 coef_scaled, ds_coef_exp, ds_coef_man;
434 u32 clockMhzScaled = 0x64000000;
435 struct chan_centers centers;
436
437 /*
438 * half and quarter rate can divide the scaled clock by 2 or 4
439 * scale for selected channel bandwidth
440 */
441 if (IS_CHAN_HALF_RATE(chan))
442 clockMhzScaled = clockMhzScaled >> 1;
443 else if (IS_CHAN_QUARTER_RATE(chan))
444 clockMhzScaled = clockMhzScaled >> 2;
445
446 /*
447 * ALGO -> coef = 1e8/fcarrier*fclock/40;
448 * scaled coef to provide precision for this floating calculation
449 */
450 ath9k_hw_get_channel_centers(ah, chan, &centers);
451 coef_scaled = clockMhzScaled / centers.synth_center;
452
453 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
454 &ds_coef_exp);
455
456 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
457 AR_PHY_TIMING3_DSC_MAN, ds_coef_man);
458 REG_RMW_FIELD(ah, AR_PHY_TIMING3,
459 AR_PHY_TIMING3_DSC_EXP, ds_coef_exp);
460
461 /*
462 * For Short GI,
463 * scaled coeff is 9/10 that of normal coeff
464 */
465 coef_scaled = (9 * coef_scaled) / 10;
466
467 ath9k_hw_get_delta_slope_vals(ah, coef_scaled, &ds_coef_man,
468 &ds_coef_exp);
469
470 /* for short gi */
471 REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
472 AR_PHY_SGI_DSC_MAN, ds_coef_man);
473 REG_RMW_FIELD(ah, AR_PHY_SGI_DELTA,
474 AR_PHY_SGI_DSC_EXP, ds_coef_exp);
400} 475}
401 476
402static bool ar9003_hw_rfbus_req(struct ath_hw *ah) 477static bool ar9003_hw_rfbus_req(struct ath_hw *ah)
403{ 478{
404 /* TODO */ 479 REG_WRITE(ah, AR_PHY_RFBUS_REQ, AR_PHY_RFBUS_REQ_EN);
405 return false; 480 return ath9k_hw_wait(ah, AR_PHY_RFBUS_GRANT, AR_PHY_RFBUS_GRANT_EN,
481 AR_PHY_RFBUS_GRANT_EN, AH_WAIT_TIMEOUT);
406} 482}
407 483
484/*
485 * Wait for the frequency synth to settle (synth goes on via PHY_ACTIVE_EN).
486 * Read the phy active delay register. Value is in 100ns increments.
487 */
408static void ar9003_hw_rfbus_done(struct ath_hw *ah) 488static void ar9003_hw_rfbus_done(struct ath_hw *ah)
409{ 489{
410 /* TODO */ 490 u32 synthDelay = REG_READ(ah, AR_PHY_RX_DELAY) & AR_PHY_RX_DELAY_DELAY;
491 if (IS_CHAN_B(ah->curchan))
492 synthDelay = (4 * synthDelay) / 22;
493 else
494 synthDelay /= 10;
495
496 udelay(synthDelay + BASE_ACTIVATE_DELAY);
497
498 REG_WRITE(ah, AR_PHY_RFBUS_REQ, 0);
411} 499}
412 500
501/*
502 * Set the interrupt and GPIO values so the ISR can disable RF
503 * on a switch signal. Assumes GPIO port and interrupt polarity
504 * are set prior to call.
505 */
413static void ar9003_hw_enable_rfkill(struct ath_hw *ah) 506static void ar9003_hw_enable_rfkill(struct ath_hw *ah)
414{ 507{
415 /* TODO */ 508 /* Connect rfsilent_bb_l to baseband */
509 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL,
510 AR_GPIO_INPUT_EN_VAL_RFSILENT_BB);
511 /* Set input mux for rfsilent_bb_l to GPIO #0 */
512 REG_CLR_BIT(ah, AR_GPIO_INPUT_MUX2,
513 AR_GPIO_INPUT_MUX2_RFSILENT);
514
515 /*
516 * Configure the desired GPIO port for input and
517 * enable baseband rf silence.
518 */
519 ath9k_hw_cfg_gpio_input(ah, ah->rfkill_gpio);
520 REG_SET_BIT(ah, AR_PHY_TEST, RFSILENT_BB);
416} 521}
417 522
418static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value) 523static void ar9003_hw_set_diversity(struct ath_hw *ah, bool value)
419{ 524{
420 /* TODO */ 525 u32 v = REG_READ(ah, AR_PHY_CCK_DETECT);
526 if (value)
527 v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
528 else
529 v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
530 REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
421} 531}
422 532
423static bool ar9003_hw_ani_control(struct ath_hw *ah, 533static bool ar9003_hw_ani_control(struct ath_hw *ah,
424 enum ath9k_ani_cmd cmd, int param) 534 enum ath9k_ani_cmd cmd, int param)
425{ 535{
426 /* TODO */ 536 struct ar5416AniState *aniState = ah->curani;
427 return false; 537 struct ath_common *common = ath9k_hw_common(ah);
538
539 switch (cmd & ah->ani_function) {
540 case ATH9K_ANI_NOISE_IMMUNITY_LEVEL:{
541 u32 level = param;
542
543 if (level >= ARRAY_SIZE(ah->totalSizeDesired)) {
544 ath_print(common, ATH_DBG_ANI,
545 "level out of range (%u > %u)\n",
546 level,
547 (unsigned)ARRAY_SIZE(ah->totalSizeDesired));
548 return false;
549 }
550
551 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ,
552 AR_PHY_DESIRED_SZ_TOT_DES,
553 ah->totalSizeDesired[level]);
554 REG_RMW_FIELD(ah, AR_PHY_AGC,
555 AR_PHY_AGC_COARSE_LOW,
556 ah->coarse_low[level]);
557 REG_RMW_FIELD(ah, AR_PHY_AGC,
558 AR_PHY_AGC_COARSE_HIGH,
559 ah->coarse_high[level]);
560 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
561 AR_PHY_FIND_SIG_FIRPWR, ah->firpwr[level]);
562
563 if (level > aniState->noiseImmunityLevel)
564 ah->stats.ast_ani_niup++;
565 else if (level < aniState->noiseImmunityLevel)
566 ah->stats.ast_ani_nidown++;
567 aniState->noiseImmunityLevel = level;
568 break;
569 }
570 case ATH9K_ANI_OFDM_WEAK_SIGNAL_DETECTION:{
571 const int m1ThreshLow[] = { 127, 50 };
572 const int m2ThreshLow[] = { 127, 40 };
573 const int m1Thresh[] = { 127, 0x4d };
574 const int m2Thresh[] = { 127, 0x40 };
575 const int m2CountThr[] = { 31, 16 };
576 const int m2CountThrLow[] = { 63, 48 };
577 u32 on = param ? 1 : 0;
578
579 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
580 AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
581 m1ThreshLow[on]);
582 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
583 AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
584 m2ThreshLow[on]);
585 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
586 AR_PHY_SFCORR_M1_THRESH, m1Thresh[on]);
587 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
588 AR_PHY_SFCORR_M2_THRESH, m2Thresh[on]);
589 REG_RMW_FIELD(ah, AR_PHY_SFCORR,
590 AR_PHY_SFCORR_M2COUNT_THR, m2CountThr[on]);
591 REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
592 AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
593 m2CountThrLow[on]);
594
595 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
596 AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLow[on]);
597 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
598 AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLow[on]);
599 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
600 AR_PHY_SFCORR_EXT_M1_THRESH, m1Thresh[on]);
601 REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
602 AR_PHY_SFCORR_EXT_M2_THRESH, m2Thresh[on]);
603
604 if (on)
605 REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
606 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
607 else
608 REG_CLR_BIT(ah, AR_PHY_SFCORR_LOW,
609 AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);
610
611 if (!on != aniState->ofdmWeakSigDetectOff) {
612 if (on)
613 ah->stats.ast_ani_ofdmon++;
614 else
615 ah->stats.ast_ani_ofdmoff++;
616 aniState->ofdmWeakSigDetectOff = !on;
617 }
618 break;
619 }
620 case ATH9K_ANI_CCK_WEAK_SIGNAL_THR:{
621 const int weakSigThrCck[] = { 8, 6 };
622 u32 high = param ? 1 : 0;
623
624 REG_RMW_FIELD(ah, AR_PHY_CCK_DETECT,
625 AR_PHY_CCK_DETECT_WEAK_SIG_THR_CCK,
626 weakSigThrCck[high]);
627 if (high != aniState->cckWeakSigThreshold) {
628 if (high)
629 ah->stats.ast_ani_cckhigh++;
630 else
631 ah->stats.ast_ani_ccklow++;
632 aniState->cckWeakSigThreshold = high;
633 }
634 break;
635 }
636 case ATH9K_ANI_FIRSTEP_LEVEL:{
637 const int firstep[] = { 0, 4, 8 };
638 u32 level = param;
639
640 if (level >= ARRAY_SIZE(firstep)) {
641 ath_print(common, ATH_DBG_ANI,
642 "level out of range (%u > %u)\n",
643 level,
644 (unsigned) ARRAY_SIZE(firstep));
645 return false;
646 }
647 REG_RMW_FIELD(ah, AR_PHY_FIND_SIG,
648 AR_PHY_FIND_SIG_FIRSTEP,
649 firstep[level]);
650 if (level > aniState->firstepLevel)
651 ah->stats.ast_ani_stepup++;
652 else if (level < aniState->firstepLevel)
653 ah->stats.ast_ani_stepdown++;
654 aniState->firstepLevel = level;
655 break;
656 }
657 case ATH9K_ANI_SPUR_IMMUNITY_LEVEL:{
658 const int cycpwrThr1[] = { 2, 4, 6, 8, 10, 12, 14, 16 };
659 u32 level = param;
660
661 if (level >= ARRAY_SIZE(cycpwrThr1)) {
662 ath_print(common, ATH_DBG_ANI,
663 "level out of range (%u > %u)\n",
664 level,
665 (unsigned) ARRAY_SIZE(cycpwrThr1));
666 return false;
667 }
668 REG_RMW_FIELD(ah, AR_PHY_TIMING5,
669 AR_PHY_TIMING5_CYCPWR_THR1,
670 cycpwrThr1[level]);
671 if (level > aniState->spurImmunityLevel)
672 ah->stats.ast_ani_spurup++;
673 else if (level < aniState->spurImmunityLevel)
674 ah->stats.ast_ani_spurdown++;
675 aniState->spurImmunityLevel = level;
676 break;
677 }
678 case ATH9K_ANI_PRESENT:
679 break;
680 default:
681 ath_print(common, ATH_DBG_ANI,
682 "invalid cmd %u\n", cmd);
683 return false;
684 }
685
686 ath_print(common, ATH_DBG_ANI, "ANI parameters:\n");
687 ath_print(common, ATH_DBG_ANI,
688 "noiseImmunityLevel=%d, spurImmunityLevel=%d, "
689 "ofdmWeakSigDetectOff=%d\n",
690 aniState->noiseImmunityLevel,
691 aniState->spurImmunityLevel,
692 !aniState->ofdmWeakSigDetectOff);
693 ath_print(common, ATH_DBG_ANI,
694 "cckWeakSigThreshold=%d, "
695 "firstepLevel=%d, listenTime=%d\n",
696 aniState->cckWeakSigThreshold,
697 aniState->firstepLevel,
698 aniState->listenTime);
699 ath_print(common, ATH_DBG_ANI,
700 "cycleCount=%d, ofdmPhyErrCount=%d, cckPhyErrCount=%d\n\n",
701 aniState->cycleCount,
702 aniState->ofdmPhyErrCount,
703 aniState->cckPhyErrCount);
704
705 return true;
428} 706}
429 707
430void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 708void ar9003_hw_attach_phy_ops(struct ath_hw *ah)