diff options
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/phy.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/phy.c | 152 |
1 files changed, 49 insertions, 103 deletions
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c index f84afb420bd8..78c26fdccad1 100644 --- a/drivers/net/wireless/ath/ath5k/phy.c +++ b/drivers/net/wireless/ath/ath5k/phy.c | |||
@@ -609,10 +609,10 @@ done: | |||
609 | /* Write initial RF gain table to set the RF sensitivity | 609 | /* Write initial RF gain table to set the RF sensitivity |
610 | * this one works on all RF chips and has nothing to do | 610 | * this one works on all RF chips and has nothing to do |
611 | * with gain_F calibration */ | 611 | * with gain_F calibration */ |
612 | static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) | 612 | static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band) |
613 | { | 613 | { |
614 | const struct ath5k_ini_rfgain *ath5k_rfg; | 614 | const struct ath5k_ini_rfgain *ath5k_rfg; |
615 | unsigned int i, size; | 615 | unsigned int i, size, index; |
616 | 616 | ||
617 | switch (ah->ah_radio) { | 617 | switch (ah->ah_radio) { |
618 | case AR5K_RF5111: | 618 | case AR5K_RF5111: |
@@ -644,17 +644,11 @@ static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq) | |||
644 | return -EINVAL; | 644 | return -EINVAL; |
645 | } | 645 | } |
646 | 646 | ||
647 | switch (freq) { | 647 | index = (band == IEEE80211_BAND_2GHZ) ? 1 : 0; |
648 | case AR5K_INI_RFGAIN_2GHZ: | ||
649 | case AR5K_INI_RFGAIN_5GHZ: | ||
650 | break; | ||
651 | default: | ||
652 | return -EINVAL; | ||
653 | } | ||
654 | 648 | ||
655 | for (i = 0; i < size; i++) { | 649 | for (i = 0; i < size; i++) { |
656 | AR5K_REG_WAIT(i); | 650 | AR5K_REG_WAIT(i); |
657 | ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq], | 651 | ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index], |
658 | (u32)ath5k_rfg[i].rfg_register); | 652 | (u32)ath5k_rfg[i].rfg_register); |
659 | } | 653 | } |
660 | 654 | ||
@@ -1361,20 +1355,7 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah) | |||
1361 | return; | 1355 | return; |
1362 | } | 1356 | } |
1363 | 1357 | ||
1364 | switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) { | 1358 | ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel); |
1365 | case CHANNEL_A: | ||
1366 | case CHANNEL_XR: | ||
1367 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
1368 | break; | ||
1369 | case CHANNEL_G: | ||
1370 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
1371 | break; | ||
1372 | default: | ||
1373 | case CHANNEL_B: | ||
1374 | ee_mode = AR5K_EEPROM_MODE_11B; | ||
1375 | break; | ||
1376 | } | ||
1377 | |||
1378 | 1359 | ||
1379 | /* completed NF calibration, test threshold */ | 1360 | /* completed NF calibration, test threshold */ |
1380 | nf = ath5k_hw_read_measured_noise_floor(ah); | 1361 | nf = ath5k_hw_read_measured_noise_floor(ah); |
@@ -1935,7 +1916,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) | |||
1935 | struct ieee80211_channel *channel = ah->ah_current_channel; | 1916 | struct ieee80211_channel *channel = ah->ah_current_channel; |
1936 | bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div; | 1917 | bool use_def_for_tx, update_def_on_tx, use_def_for_rts, fast_div; |
1937 | bool use_def_for_sg; | 1918 | bool use_def_for_sg; |
1938 | u8 def_ant, tx_ant, ee_mode; | 1919 | int ee_mode; |
1920 | u8 def_ant, tx_ant; | ||
1939 | u32 sta_id1 = 0; | 1921 | u32 sta_id1 = 0; |
1940 | 1922 | ||
1941 | /* if channel is not initialized yet we can't set the antennas | 1923 | /* if channel is not initialized yet we can't set the antennas |
@@ -1947,18 +1929,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode) | |||
1947 | 1929 | ||
1948 | def_ant = ah->ah_def_ant; | 1930 | def_ant = ah->ah_def_ant; |
1949 | 1931 | ||
1950 | switch (channel->hw_value & CHANNEL_MODES) { | 1932 | ee_mode = ath5k_eeprom_mode_from_channel(channel); |
1951 | case CHANNEL_A: | 1933 | if (ee_mode < 0) { |
1952 | case CHANNEL_XR: | ||
1953 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
1954 | break; | ||
1955 | case CHANNEL_G: | ||
1956 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
1957 | break; | ||
1958 | case CHANNEL_B: | ||
1959 | ee_mode = AR5K_EEPROM_MODE_11B; | ||
1960 | break; | ||
1961 | default: | ||
1962 | ATH5K_ERR(ah->ah_sc, | 1934 | ATH5K_ERR(ah->ah_sc, |
1963 | "invalid channel: %d\n", channel->center_freq); | 1935 | "invalid channel: %d\n", channel->center_freq); |
1964 | return; | 1936 | return; |
@@ -2593,7 +2565,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min, | |||
2593 | 2565 | ||
2594 | /* Write PCDAC values on hw */ | 2566 | /* Write PCDAC values on hw */ |
2595 | static void | 2567 | static void |
2596 | ath5k_setup_pcdac_table(struct ath5k_hw *ah) | 2568 | ath5k_write_pcdac_table(struct ath5k_hw *ah) |
2597 | { | 2569 | { |
2598 | u8 *pcdac_out = ah->ah_txpower.txp_pd_table; | 2570 | u8 *pcdac_out = ah->ah_txpower.txp_pd_table; |
2599 | int i; | 2571 | int i; |
@@ -2742,7 +2714,7 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah, | |||
2742 | 2714 | ||
2743 | /* Write PDADC values on hw */ | 2715 | /* Write PDADC values on hw */ |
2744 | static void | 2716 | static void |
2745 | ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode) | 2717 | ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode) |
2746 | { | 2718 | { |
2747 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | 2719 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; |
2748 | u8 *pdadc_out = ah->ah_txpower.txp_pd_table; | 2720 | u8 *pdadc_out = ah->ah_txpower.txp_pd_table; |
@@ -2957,8 +2929,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, | |||
2957 | (s16) pcinfo_R->freq, | 2929 | (s16) pcinfo_R->freq, |
2958 | pcinfo_L->max_pwr, pcinfo_R->max_pwr); | 2930 | pcinfo_L->max_pwr, pcinfo_R->max_pwr); |
2959 | 2931 | ||
2960 | /* We are ready to go, fill PCDAC/PDADC | 2932 | /* Fill PCDAC/PDADC table */ |
2961 | * table and write settings on hardware */ | ||
2962 | switch (type) { | 2933 | switch (type) { |
2963 | case AR5K_PWRTABLE_LINEAR_PCDAC: | 2934 | case AR5K_PWRTABLE_LINEAR_PCDAC: |
2964 | /* For RF5112 we can have one or two curves | 2935 | /* For RF5112 we can have one or two curves |
@@ -2971,9 +2942,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, | |||
2971 | * match max power value with max | 2942 | * match max power value with max |
2972 | * table index */ | 2943 | * table index */ |
2973 | ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2); | 2944 | ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2); |
2974 | |||
2975 | /* Write settings on hw */ | ||
2976 | ath5k_setup_pcdac_table(ah); | ||
2977 | break; | 2945 | break; |
2978 | case AR5K_PWRTABLE_PWR_TO_PCDAC: | 2946 | case AR5K_PWRTABLE_PWR_TO_PCDAC: |
2979 | /* We are done for RF5111 since it has only | 2947 | /* We are done for RF5111 since it has only |
@@ -2983,9 +2951,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, | |||
2983 | /* No rate powertable adjustment for RF5111 */ | 2951 | /* No rate powertable adjustment for RF5111 */ |
2984 | ah->ah_txpower.txp_min_idx = 0; | 2952 | ah->ah_txpower.txp_min_idx = 0; |
2985 | ah->ah_txpower.txp_offset = 0; | 2953 | ah->ah_txpower.txp_offset = 0; |
2986 | |||
2987 | /* Write settings on hw */ | ||
2988 | ath5k_setup_pcdac_table(ah); | ||
2989 | break; | 2954 | break; |
2990 | case AR5K_PWRTABLE_PWR_TO_PDADC: | 2955 | case AR5K_PWRTABLE_PWR_TO_PDADC: |
2991 | /* Set PDADC boundaries and fill | 2956 | /* Set PDADC boundaries and fill |
@@ -2993,9 +2958,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, | |||
2993 | ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max, | 2958 | ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max, |
2994 | ee->ee_pd_gains[ee_mode]); | 2959 | ee->ee_pd_gains[ee_mode]); |
2995 | 2960 | ||
2996 | /* Write settings on hw */ | ||
2997 | ath5k_setup_pwr_to_pdadc_table(ah, ee_mode); | ||
2998 | |||
2999 | /* Set txp.offset, note that table_min | 2961 | /* Set txp.offset, note that table_min |
3000 | * can be negative */ | 2962 | * can be negative */ |
3001 | ah->ah_txpower.txp_offset = table_min[0]; | 2963 | ah->ah_txpower.txp_offset = table_min[0]; |
@@ -3004,9 +2966,20 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah, | |||
3004 | return -EINVAL; | 2966 | return -EINVAL; |
3005 | } | 2967 | } |
3006 | 2968 | ||
2969 | ah->ah_txpower.txp_setup = true; | ||
2970 | |||
3007 | return 0; | 2971 | return 0; |
3008 | } | 2972 | } |
3009 | 2973 | ||
2974 | /* Write power table for current channel to hw */ | ||
2975 | static void | ||
2976 | ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type) | ||
2977 | { | ||
2978 | if (type == AR5K_PWRTABLE_PWR_TO_PDADC) | ||
2979 | ath5k_write_pwr_to_pdadc_table(ah, ee_mode); | ||
2980 | else | ||
2981 | ath5k_write_pcdac_table(ah); | ||
2982 | } | ||
3010 | 2983 | ||
3011 | /* | 2984 | /* |
3012 | * Per-rate tx power setting | 2985 | * Per-rate tx power setting |
@@ -3095,7 +3068,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, | |||
3095 | 3068 | ||
3096 | /* Min/max in 0.25dB units */ | 3069 | /* Min/max in 0.25dB units */ |
3097 | ah->ah_txpower.txp_min_pwr = 2 * rates[7]; | 3070 | ah->ah_txpower.txp_min_pwr = 2 * rates[7]; |
3098 | ah->ah_txpower.txp_max_pwr = 2 * rates[0]; | 3071 | ah->ah_txpower.txp_cur_pwr = 2 * rates[0]; |
3099 | ah->ah_txpower.txp_ofdm = rates[7]; | 3072 | ah->ah_txpower.txp_ofdm = rates[7]; |
3100 | } | 3073 | } |
3101 | 3074 | ||
@@ -3105,9 +3078,11 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr, | |||
3105 | */ | 3078 | */ |
3106 | static int | 3079 | static int |
3107 | ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | 3080 | ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, |
3108 | u8 ee_mode, u8 txpower, bool fast) | 3081 | u8 txpower) |
3109 | { | 3082 | { |
3110 | struct ath5k_rate_pcal_info rate_info; | 3083 | struct ath5k_rate_pcal_info rate_info; |
3084 | struct ieee80211_channel *curr_channel = ah->ah_current_channel; | ||
3085 | int ee_mode; | ||
3111 | u8 type; | 3086 | u8 type; |
3112 | int ret; | 3087 | int ret; |
3113 | 3088 | ||
@@ -3116,6 +3091,13 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
3116 | return -EINVAL; | 3091 | return -EINVAL; |
3117 | } | 3092 | } |
3118 | 3093 | ||
3094 | ee_mode = ath5k_eeprom_mode_from_channel(channel); | ||
3095 | if (ee_mode < 0) { | ||
3096 | ATH5K_ERR(ah->ah_sc, | ||
3097 | "invalid channel: %d\n", channel->center_freq); | ||
3098 | return -EINVAL; | ||
3099 | } | ||
3100 | |||
3119 | /* Initialize TX power table */ | 3101 | /* Initialize TX power table */ |
3120 | switch (ah->ah_radio) { | 3102 | switch (ah->ah_radio) { |
3121 | case AR5K_RF5110: | 3103 | case AR5K_RF5110: |
@@ -3138,28 +3120,26 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
3138 | return -EINVAL; | 3120 | return -EINVAL; |
3139 | } | 3121 | } |
3140 | 3122 | ||
3141 | /* If fast is set it means we are on the same channel/mode | 3123 | /* |
3142 | * so there is no need to recalculate the powertable, we 'll | 3124 | * If we don't change channel/mode skip tx powertable calculation |
3143 | * just use the cached one */ | 3125 | * and use the cached one. |
3144 | if (!fast) { | 3126 | */ |
3127 | if (!ah->ah_txpower.txp_setup || | ||
3128 | (channel->hw_value != curr_channel->hw_value) || | ||
3129 | (channel->center_freq != curr_channel->center_freq)) { | ||
3145 | /* Reset TX power values */ | 3130 | /* Reset TX power values */ |
3146 | memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); | 3131 | memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower)); |
3147 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; | 3132 | ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER; |
3148 | ah->ah_txpower.txp_min_pwr = 0; | ||
3149 | ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER; | ||
3150 | 3133 | ||
3151 | /* Calculate the powertable */ | 3134 | /* Calculate the powertable */ |
3152 | ret = ath5k_setup_channel_powertable(ah, channel, | 3135 | ret = ath5k_setup_channel_powertable(ah, channel, |
3153 | ee_mode, type); | 3136 | ee_mode, type); |
3154 | if (ret) | 3137 | if (ret) |
3155 | return ret; | 3138 | return ret; |
3156 | /* Write cached table on hw */ | 3139 | } |
3157 | } else if (type == AR5K_PWRTABLE_PWR_TO_PDADC) | ||
3158 | ath5k_setup_pwr_to_pdadc_table(ah, ee_mode); | ||
3159 | else | ||
3160 | ath5k_setup_pcdac_table(ah); | ||
3161 | |||
3162 | 3140 | ||
3141 | /* Write table on hw */ | ||
3142 | ath5k_write_channel_powertable(ah, ee_mode, type); | ||
3163 | 3143 | ||
3164 | /* Limit max power if we have a CTL available */ | 3144 | /* Limit max power if we have a CTL available */ |
3165 | ath5k_get_max_ctl_power(ah, channel); | 3145 | ath5k_get_max_ctl_power(ah, channel); |
@@ -3214,31 +3194,10 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
3214 | 3194 | ||
3215 | int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) | 3195 | int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) |
3216 | { | 3196 | { |
3217 | /*Just a try M.F.*/ | ||
3218 | struct ieee80211_channel *channel = ah->ah_current_channel; | ||
3219 | u8 ee_mode; | ||
3220 | |||
3221 | switch (channel->hw_value & CHANNEL_MODES) { | ||
3222 | case CHANNEL_A: | ||
3223 | case CHANNEL_XR: | ||
3224 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
3225 | break; | ||
3226 | case CHANNEL_G: | ||
3227 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
3228 | break; | ||
3229 | case CHANNEL_B: | ||
3230 | ee_mode = AR5K_EEPROM_MODE_11B; | ||
3231 | break; | ||
3232 | default: | ||
3233 | ATH5K_ERR(ah->ah_sc, | ||
3234 | "invalid channel: %d\n", channel->center_freq); | ||
3235 | return -EINVAL; | ||
3236 | } | ||
3237 | |||
3238 | ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, | 3197 | ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER, |
3239 | "changing txpower to %d\n", txpower); | 3198 | "changing txpower to %d\n", txpower); |
3240 | 3199 | ||
3241 | return ath5k_hw_txpower(ah, channel, ee_mode, txpower, true); | 3200 | return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower); |
3242 | } | 3201 | } |
3243 | 3202 | ||
3244 | /*************\ | 3203 | /*************\ |
@@ -3246,12 +3205,11 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower) | |||
3246 | \*************/ | 3205 | \*************/ |
3247 | 3206 | ||
3248 | int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | 3207 | int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, |
3249 | u8 mode, u8 ee_mode, u8 freq, bool fast) | 3208 | u8 mode, bool fast) |
3250 | { | 3209 | { |
3251 | struct ieee80211_channel *curr_channel; | 3210 | struct ieee80211_channel *curr_channel; |
3252 | int ret, i; | 3211 | int ret, i; |
3253 | u32 phy_tst1; | 3212 | u32 phy_tst1; |
3254 | bool fast_txp; | ||
3255 | ret = 0; | 3213 | ret = 0; |
3256 | 3214 | ||
3257 | /* | 3215 | /* |
@@ -3282,26 +3240,14 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
3282 | } | 3240 | } |
3283 | 3241 | ||
3284 | /* | 3242 | /* |
3285 | * If we don't change channel/mode skip | ||
3286 | * tx powertable calculation and use the | ||
3287 | * cached one. | ||
3288 | */ | ||
3289 | if ((channel->hw_value == curr_channel->hw_value) && | ||
3290 | (channel->center_freq == curr_channel->center_freq)) | ||
3291 | fast_txp = true; | ||
3292 | else | ||
3293 | fast_txp = false; | ||
3294 | |||
3295 | /* | ||
3296 | * Set TX power | 3243 | * Set TX power |
3297 | * | 3244 | * |
3298 | * Note: We need to do that before we set | 3245 | * Note: We need to do that before we set |
3299 | * RF buffer settings on 5211/5212+ so that we | 3246 | * RF buffer settings on 5211/5212+ so that we |
3300 | * properly set curve indices. | 3247 | * properly set curve indices. |
3301 | */ | 3248 | */ |
3302 | ret = ath5k_hw_txpower(ah, channel, ee_mode, | 3249 | ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_cur_pwr ? |
3303 | ah->ah_txpower.txp_max_pwr / 2, | 3250 | ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER); |
3304 | fast_txp); | ||
3305 | if (ret) | 3251 | if (ret) |
3306 | return ret; | 3252 | return ret; |
3307 | 3253 | ||
@@ -3317,7 +3263,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel, | |||
3317 | * Write initial RF gain settings | 3263 | * Write initial RF gain settings |
3318 | * This should work for both 5111/5112 | 3264 | * This should work for both 5111/5112 |
3319 | */ | 3265 | */ |
3320 | ret = ath5k_hw_rfgain_init(ah, freq); | 3266 | ret = ath5k_hw_rfgain_init(ah, channel->band); |
3321 | if (ret) | 3267 | if (ret) |
3322 | return ret; | 3268 | return ret; |
3323 | 3269 | ||