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:39:11 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-04-16 15:43:35 -0400
commitdf23acaa5d3239745805650e2f27a4252182c063 (patch)
tree045e59bc9d7bd70ddbf4e2b9c0f8e623157a5f41 /drivers/net/wireless/ath/ath9k/ar9003_phy.c
parent4b01931e3a3ca5ec49604e2b279b8b9dd42fbe4c (diff)
ath9k_hw: complete AR9003 calibration
This goes with some new shiny TX IQ calibration that AR9003 hardware family supports. Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: Vasanthakumar Thiagarajan <vasanth@atheros.com> Signed-off-by: Felix Fietkau <nbd@openwrt.org> 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.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index 67b3b651843..fee07fd7a59 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -814,6 +814,105 @@ void ar9003_hw_set_nf_limits(struct ath_hw *ah)
814 ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ; 814 ah->nf_5g_min = AR_PHY_CCA_MIN_GOOD_VAL_9300_5GHZ;
815} 815}
816 816
817/*
818 * Find out which of the RX chains are enabled
819 */
820static u32 ar9003_hw_get_rx_chainmask(struct ath_hw *ah)
821{
822 u32 chain = REG_READ(ah, AR_PHY_RX_CHAINMASK);
823 /*
824 * The bits [2:0] indicate the rx chain mask and are to be
825 * interpreted as follows:
826 * 00x => Only chain 0 is enabled
827 * 01x => Chain 1 and 0 enabled
828 * 1xx => Chain 2,1 and 0 enabled
829 */
830 return chain & 0x7;
831}
832
833static void ar9003_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
834{
835 struct ath9k_nfcal_hist *h;
836 unsigned i, j;
837 int32_t val;
838 const u32 ar9300_cca_regs[6] = {
839 AR_PHY_CCA_0,
840 AR_PHY_CCA_1,
841 AR_PHY_CCA_2,
842 AR_PHY_EXT_CCA,
843 AR_PHY_EXT_CCA_1,
844 AR_PHY_EXT_CCA_2,
845 };
846 u8 chainmask, rx_chain_status;
847 struct ath_common *common = ath9k_hw_common(ah);
848
849 rx_chain_status = ar9003_hw_get_rx_chainmask(ah);
850
851 chainmask = 0x3F;
852 h = ah->nfCalHist;
853
854 for (i = 0; i < NUM_NF_READINGS; i++) {
855 if (chainmask & (1 << i)) {
856 val = REG_READ(ah, ar9300_cca_regs[i]);
857 val &= 0xFFFFFE00;
858 val |= (((u32) (h[i].privNF) << 1) & 0x1ff);
859 REG_WRITE(ah, ar9300_cca_regs[i], val);
860 }
861 }
862
863 /*
864 * Load software filtered NF value into baseband internal minCCApwr
865 * variable.
866 */
867 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
868 AR_PHY_AGC_CONTROL_ENABLE_NF);
869 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
870 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
871 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
872
873 /*
874 * Wait for load to complete, should be fast, a few 10s of us.
875 * The max delay was changed from an original 250us to 10000us
876 * since 250us often results in NF load timeout and causes deaf
877 * condition during stress testing 12/12/2009
878 */
879 for (j = 0; j < 1000; j++) {
880 if ((REG_READ(ah, AR_PHY_AGC_CONTROL) &
881 AR_PHY_AGC_CONTROL_NF) == 0)
882 break;
883 udelay(10);
884 }
885
886 /*
887 * We timed out waiting for the noisefloor to load, probably due to an
888 * in-progress rx. Simply return here and allow the load plenty of time
889 * to complete before the next calibration interval. We need to avoid
890 * trying to load -50 (which happens below) while the previous load is
891 * still in progress as this can cause rx deafness. Instead by returning
892 * here, the baseband nf cal will just be capped by our present
893 * noisefloor until the next calibration timer.
894 */
895 if (j == 1000) {
896 ath_print(common, ATH_DBG_ANY, "Timeout while waiting for nf "
897 "to load: AR_PHY_AGC_CONTROL=0x%x\n",
898 REG_READ(ah, AR_PHY_AGC_CONTROL));
899 }
900
901 /*
902 * Restore maxCCAPower register parameter again so that we're not capped
903 * by the median we just loaded. This will be initial (and max) value
904 * of next noise floor calibration the baseband does.
905 */
906 for (i = 0; i < NUM_NF_READINGS; i++) {
907 if (chainmask & (1 << i)) {
908 val = REG_READ(ah, ar9300_cca_regs[i]);
909 val &= 0xFFFFFE00;
910 val |= (((u32) (-50) << 1) & 0x1ff);
911 REG_WRITE(ah, ar9300_cca_regs[i], val);
912 }
913 }
914}
915
817void ar9003_hw_attach_phy_ops(struct ath_hw *ah) 916void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
818{ 917{
819 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); 918 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -833,4 +932,5 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
833 priv_ops->set_diversity = ar9003_hw_set_diversity; 932 priv_ops->set_diversity = ar9003_hw_set_diversity;
834 priv_ops->ani_control = ar9003_hw_ani_control; 933 priv_ops->ani_control = ar9003_hw_ani_control;
835 priv_ops->do_getnf = ar9003_hw_do_getnf; 934 priv_ops->do_getnf = ar9003_hw_do_getnf;
935 priv_ops->loadnf = ar9003_hw_loadnf;
836} 936}