2010-12-21 08:30:20

by Bruno Randolf

[permalink] [raw]
Subject: [PATCH 1/5] ath5k: Simplify powertable recalculation

Let ath5k_hw_txpower() decide if it can re-use the powertable or if it has to
be recalculated instead of passing a 'fast' flag from the outside.

Signed-off-by: Bruno Randolf <[email protected]>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 1 +
drivers/net/wireless/ath/ath5k/phy.c | 35 ++++++++++++--------------------
2 files changed, 14 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index d6e7440..e6491bf 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1113,6 +1113,7 @@ struct ath5k_hw {
s16 txp_cck_ofdm_gainf_delta;
/* Value in dB units */
s16 txp_cck_ofdm_pwr_delta;
+ bool txp_setup;
} ah_txpower;

struct {
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index f84afb4..7c6d7dc 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -3004,6 +3004,8 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
return -EINVAL;
}

+ ah->ah_txpower.txp_setup = true;
+
return 0;
}

@@ -3105,9 +3107,10 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
*/
static int
ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 ee_mode, u8 txpower, bool fast)
+ u8 ee_mode, u8 txpower)
{
struct ath5k_rate_pcal_info rate_info;
+ struct ieee80211_channel *curr_channel = ah->ah_current_channel;
u8 type;
int ret;

@@ -3138,10 +3141,13 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return -EINVAL;
}

- /* If fast is set it means we are on the same channel/mode
- * so there is no need to recalculate the powertable, we 'll
- * just use the cached one */
- if (!fast) {
+ /*
+ * If we don't change channel/mode skip tx powertable calculation
+ * and use the cached one.
+ */
+ if (!ah->ah_txpower.txp_setup ||
+ (channel->hw_value != curr_channel->hw_value) ||
+ (channel->center_freq != curr_channel->center_freq)) {
/* Reset TX power values */
memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
@@ -3159,8 +3165,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
else
ath5k_setup_pcdac_table(ah);

-
-
/* Limit max power if we have a CTL available */
ath5k_get_max_ctl_power(ah, channel);

@@ -3238,7 +3242,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
"changing txpower to %d\n", txpower);

- return ath5k_hw_txpower(ah, channel, ee_mode, txpower, true);
+ return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
}

/*************\
@@ -3251,7 +3255,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
struct ieee80211_channel *curr_channel;
int ret, i;
u32 phy_tst1;
- bool fast_txp;
ret = 0;

/*
@@ -3282,17 +3285,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
}

/*
- * If we don't change channel/mode skip
- * tx powertable calculation and use the
- * cached one.
- */
- if ((channel->hw_value == curr_channel->hw_value) &&
- (channel->center_freq == curr_channel->center_freq))
- fast_txp = true;
- else
- fast_txp = false;
-
- /*
* Set TX power
*
* Note: We need to do that before we set
@@ -3300,8 +3292,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
* properly set curve indices.
*/
ret = ath5k_hw_txpower(ah, channel, ee_mode,
- ah->ah_txpower.txp_max_pwr / 2,
- fast_txp);
+ ah->ah_txpower.txp_max_pwr / 2);
if (ret)
return ret;




2010-12-21 14:48:29

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 2/5] ath5k: Separate powertable setup and writing

2010/12/21 Bruno Randolf <[email protected]>:
> And rename functions which write the powertable to make it clearer.
>
> Signed-off-by: Bruno Randolf <[email protected]>
> ---
>  drivers/net/wireless/ath/ath5k/phy.c |   34 ++++++++++++++++------------------
>  1 files changed, 16 insertions(+), 18 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
> index 7c6d7dc..6f0cf3a 100644
> --- a/drivers/net/wireless/ath/ath5k/phy.c
> +++ b/drivers/net/wireless/ath/ath5k/phy.c
> @@ -2593,7 +2593,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,
>
>  /* Write PCDAC values on hw */
>  static void
> -ath5k_setup_pcdac_table(struct ath5k_hw *ah)
> +ath5k_write_pcdac_table(struct ath5k_hw *ah)
>  {
>        u8      *pcdac_out = ah->ah_txpower.txp_pd_table;
>        int     i;
> @@ -2742,7 +2742,7 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,
>
>  /* Write PDADC values on hw */
>  static void
> -ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
> +ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
>  {
>        struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
>        u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
> @@ -2957,8 +2957,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
>                                        (s16) pcinfo_R->freq,
>                                        pcinfo_L->max_pwr, pcinfo_R->max_pwr);
>
> -       /* We are ready to go, fill PCDAC/PDADC
> -        * table and write settings on hardware */
> +       /* Fill PCDAC/PDADC table */
>        switch (type) {
>        case AR5K_PWRTABLE_LINEAR_PCDAC:
>                /* For RF5112 we can have one or two curves
> @@ -2971,9 +2970,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
>                 * match max power value with max
>                 * table index */
>                ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
> -
> -               /* Write settings on hw */
> -               ath5k_setup_pcdac_table(ah);
>                break;
>        case AR5K_PWRTABLE_PWR_TO_PCDAC:
>                /* We are done for RF5111 since it has only
> @@ -2983,9 +2979,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
>                /* No rate powertable adjustment for RF5111 */
>                ah->ah_txpower.txp_min_idx = 0;
>                ah->ah_txpower.txp_offset = 0;
> -
> -               /* Write settings on hw */
> -               ath5k_setup_pcdac_table(ah);
>                break;
>        case AR5K_PWRTABLE_PWR_TO_PDADC:
>                /* Set PDADC boundaries and fill
> @@ -2993,9 +2986,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
>                ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
>                                                ee->ee_pd_gains[ee_mode]);
>
> -               /* Write settings on hw */
> -               ath5k_setup_pwr_to_pdadc_table(ah, ee_mode);
> -
>                /* Set txp.offset, note that table_min
>                 * can be negative */
>                ah->ah_txpower.txp_offset = table_min[0];
> @@ -3009,6 +2999,15 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
>        return 0;
>  }
>
> +/* Write power table for current channel to hw */
> +static void
> +ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type)
> +{
> +       if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
> +               ath5k_write_pwr_to_pdadc_table(ah, ee_mode);
> +       else
> +               ath5k_write_pcdac_table(ah);
> +}
>
>  /*
>  * Per-rate tx power setting
> @@ -3159,11 +3158,10 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>                                                        ee_mode, type);
>                if (ret)
>                        return ret;
> -       /* Write cached table on hw */
> -       } else if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
> -               ath5k_setup_pwr_to_pdadc_table(ah, ee_mode);
> -       else
> -               ath5k_setup_pcdac_table(ah);
> +       }
> +
> +       /* Write table on hw */
> +       ath5k_write_channel_powertable(ah, ee_mode, type);
>
>        /* Limit max power if we have a CTL available */
>        ath5k_get_max_ctl_power(ah, channel);
>
>

Acked-by: Nick Kossifidis <[email protected]>

--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2010-12-21 08:30:42

by Bruno Randolf

[permalink] [raw]
Subject: [PATCH 5/5] ath5k: Use helper function to get eeprom mode from channel

Introduce a helper function to get the EEPROM mode from channel and remove
multiple similar switch statements. Also since it's now easy to get the EEPROM
mode from the channel, use them inside the functions which need it, instead of
passing a redundant ee_mode parameter.

Signed-off-by: Bruno Randolf <[email protected]>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 2 -
drivers/net/wireless/ath/ath5k/eeprom.c | 16 +++++++
drivers/net/wireless/ath/ath5k/eeprom.h | 2 +
drivers/net/wireless/ath/ath5k/phy.c | 68 +++++++------------------------
drivers/net/wireless/ath/ath5k/reset.c | 19 ++++-----
5 files changed, 42 insertions(+), 65 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 5de8520..407e39c 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1318,7 +1318,7 @@ void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
/* Init function */
int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 mode, u8 ee_mode, bool fast);
+ u8 mode, bool fast);

/*
* Functions used internaly
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
index 97eaa9a..80e6256 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.c
+++ b/drivers/net/wireless/ath/ath5k/eeprom.c
@@ -1802,3 +1802,19 @@ ath5k_eeprom_detach(struct ath5k_hw *ah)
for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
ath5k_eeprom_free_pcal_info(ah, mode);
}
+
+int
+ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
+{
+ switch (channel->hw_value & CHANNEL_MODES) {
+ case CHANNEL_A:
+ case CHANNEL_XR:
+ return AR5K_EEPROM_MODE_11A;
+ case CHANNEL_G:
+ return AR5K_EEPROM_MODE_11G;
+ case CHANNEL_B:
+ return AR5K_EEPROM_MODE_11B;
+ default:
+ return -1;
+ }
+}
diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
index 0017006..7c09e15 100644
--- a/drivers/net/wireless/ath/ath5k/eeprom.h
+++ b/drivers/net/wireless/ath/ath5k/eeprom.h
@@ -517,3 +517,5 @@ struct ath5k_eeprom_info {
u32 ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
};

+int
+ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel);
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index b6e9621..9306d5f 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -1355,20 +1355,7 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
return;
}

- switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
- case CHANNEL_XR:
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_G:
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- default:
- case CHANNEL_B:
- ee_mode = AR5K_EEPROM_MODE_11B;
- break;
- }
-
+ ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel);

/* completed NF calibration, test threshold */
nf = ath5k_hw_read_measured_noise_floor(ah);
@@ -1941,18 +1928,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)

def_ant = ah->ah_def_ant;

- switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
- case CHANNEL_XR:
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_G:
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- case CHANNEL_B:
- ee_mode = AR5K_EEPROM_MODE_11B;
- break;
- default:
+ ee_mode = ath5k_eeprom_mode_from_channel(channel);
+ if (ee_mode < 0) {
ATH5K_ERR(ah->ah_sc,
"invalid channel: %d\n", channel->center_freq);
return;
@@ -3100,11 +3077,11 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
*/
static int
ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 ee_mode, u8 txpower)
+ u8 txpower)
{
struct ath5k_rate_pcal_info rate_info;
struct ieee80211_channel *curr_channel = ah->ah_current_channel;
- u8 type;
+ u8 type, ee_mode;
int ret;

if (txpower > AR5K_TUNE_MAX_TXPOWER) {
@@ -3112,6 +3089,13 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
return -EINVAL;
}

+ ee_mode = ath5k_eeprom_mode_from_channel(channel);
+ if (ee_mode < 0) {
+ ATH5K_ERR(ah->ah_sc,
+ "invalid channel: %d\n", channel->center_freq);
+ return -EINVAL;
+ }
+
/* Initialize TX power table */
switch (ah->ah_radio) {
case AR5K_RF5110:
@@ -3208,31 +3192,10 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,

int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
{
- /*Just a try M.F.*/
- struct ieee80211_channel *channel = ah->ah_current_channel;
- u8 ee_mode;
-
- switch (channel->hw_value & CHANNEL_MODES) {
- case CHANNEL_A:
- case CHANNEL_XR:
- ee_mode = AR5K_EEPROM_MODE_11A;
- break;
- case CHANNEL_G:
- ee_mode = AR5K_EEPROM_MODE_11G;
- break;
- case CHANNEL_B:
- ee_mode = AR5K_EEPROM_MODE_11B;
- break;
- default:
- ATH5K_ERR(ah->ah_sc,
- "invalid channel: %d\n", channel->center_freq);
- return -EINVAL;
- }
-
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
"changing txpower to %d\n", txpower);

- return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
+ return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower);
}

/*************\
@@ -3240,7 +3203,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
\*************/

int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 mode, u8 ee_mode, bool fast)
+ u8 mode, bool fast)
{
struct ieee80211_channel *curr_channel;
int ret, i;
@@ -3281,8 +3244,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
* RF buffer settings on 5211/5212+ so that we
* properly set curve indices.
*/
- ret = ath5k_hw_txpower(ah, channel, ee_mode,
- ah->ah_txpower.txp_cur_pwr ?
+ ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_cur_pwr ?
ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER);
if (ret)
return ret;
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index 4b8b987..3c962f7 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -866,15 +866,18 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
}

static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
- struct ieee80211_channel *channel, u8 ee_mode)
+ struct ieee80211_channel *channel)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
s16 cck_ofdm_pwr_delta;
+ u8 ee_mode;

/* TODO: Add support for AR5210 EEPROM */
if (ah->ah_version == AR5K_AR5210)
return;

+ ee_mode = ath5k_eeprom_mode_from_channel(channel);
+
/* Adjust power delta for channel 14 */
if (channel->center_freq == 2484)
cck_ofdm_pwr_delta =
@@ -1020,10 +1023,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
struct ieee80211_channel *channel, bool fast, bool skip_pcu)
{
u32 s_seq[10], s_led[3], tsf_up, tsf_lo;
- u8 mode, ee_mode;
+ u8 mode;
int i, ret;

- ee_mode = 0;
tsf_up = 0;
tsf_lo = 0;
mode = 0;
@@ -1070,7 +1072,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
mode = AR5K_MODE_11A;
- ee_mode = AR5K_EEPROM_MODE_11A;
break;
case CHANNEL_G:

@@ -1081,7 +1082,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}

mode = AR5K_MODE_11G;
- ee_mode = AR5K_EEPROM_MODE_11G;
break;
case CHANNEL_B:

@@ -1092,7 +1092,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}

mode = AR5K_MODE_11B;
- ee_mode = AR5K_EEPROM_MODE_11B;
break;
case CHANNEL_XR:
if (ah->ah_version == AR5K_AR5211) {
@@ -1101,7 +1100,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
return -EINVAL;
}
mode = AR5K_MODE_XR;
- ee_mode = AR5K_EEPROM_MODE_11A;
break;
default:
ATH5K_ERR(ah->ah_sc,
@@ -1114,8 +1112,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
* go on. If it fails continue with a normal reset.
*/
if (fast) {
- ret = ath5k_hw_phy_init(ah, channel, mode,
- ee_mode, true);
+ ret = ath5k_hw_phy_init(ah, channel, mode, true);
if (ret) {
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
"fast chan change failed, falling back to normal reset\n");
@@ -1212,7 +1209,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
ath5k_hw_tweak_initval_settings(ah, channel);

/* Commit values from EEPROM */
- ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);
+ ath5k_hw_commit_eeprom_settings(ah, channel);


/*
@@ -1251,7 +1248,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/*
* Initialize PHY
*/
- ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, false);
+ ret = ath5k_hw_phy_init(ah, channel, mode, false);
if (ret) {
ATH5K_ERR(ah->ah_sc,
"failed to initialize PHY (%i) !\n", ret);


2010-12-21 14:49:05

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 4/5] ath5k: Remove ATH5K_INI_RFGAIN defines, use band instead

2010/12/21 Bruno Randolf <[email protected]>:
> Remove redundant defines.
>
> Signed-off-by: Bruno Randolf <[email protected]>
> ---
>  drivers/net/wireless/ath/ath5k/ath5k.h |    6 +-----
>  drivers/net/wireless/ath/ath5k/phy.c   |   18 ++++++------------
>  drivers/net/wireless/ath/ath5k/reset.c |   11 +++--------
>  3 files changed, 10 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
> index 342da28..5de8520 100644
> --- a/drivers/net/wireless/ath/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
> @@ -154,10 +154,6 @@
>                udelay(1);                                              \
>  } while (0)
>
> -/* Register dumps are done per operation mode */
> -#define AR5K_INI_RFGAIN_5GHZ           0
> -#define AR5K_INI_RFGAIN_2GHZ           1
> -
>  /*
>  * Some tuneable values (these should be changeable by the user)
>  * TODO: Make use of them and add more options OR use debug/configfs
> @@ -1322,7 +1318,7 @@ void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
>  int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
>  /* Init function */
>  int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
> -                               u8 mode, u8 ee_mode, u8 freq, bool fast);
> +                               u8 mode, u8 ee_mode, bool fast);
>
>  /*
>  * Functions used internaly
> diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
> index 18c58cd..b6e9621 100644
> --- a/drivers/net/wireless/ath/ath5k/phy.c
> +++ b/drivers/net/wireless/ath/ath5k/phy.c
> @@ -609,10 +609,10 @@ done:
>  /* Write initial RF gain table to set the RF sensitivity
>  * this one works on all RF chips and has nothing to do
>  * with gain_F calibration */
> -static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
> +static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band)
>  {
>        const struct ath5k_ini_rfgain *ath5k_rfg;
> -       unsigned int i, size;
> +       unsigned int i, size, index;
>
>        switch (ah->ah_radio) {
>        case AR5K_RF5111:
> @@ -644,17 +644,11 @@ static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
>                return -EINVAL;
>        }
>
> -       switch (freq) {
> -       case AR5K_INI_RFGAIN_2GHZ:
> -       case AR5K_INI_RFGAIN_5GHZ:
> -               break;
> -       default:
> -               return -EINVAL;
> -       }
> +       index = (band == IEEE80211_BAND_2GHZ) ? 1 : 0;
>
>        for (i = 0; i < size; i++) {
>                AR5K_REG_WAIT(i);
> -               ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
> +               ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index],
>                        (u32)ath5k_rfg[i].rfg_register);
>        }
>
> @@ -3246,7 +3240,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
>  \*************/
>
>  int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
> -                               u8 mode, u8 ee_mode, u8 freq, bool fast)
> +                               u8 mode, u8 ee_mode, bool fast)
>  {
>        struct ieee80211_channel *curr_channel;
>        int ret, i;
> @@ -3305,7 +3299,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>                 * Write initial RF gain settings
>                 * This should work for both 5111/5112
>                 */
> -               ret = ath5k_hw_rfgain_init(ah, freq);
> +               ret = ath5k_hw_rfgain_init(ah, channel->band);
>                if (ret)
>                        return ret;
>
> diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
> index bc84aaa..4b8b987 100644
> --- a/drivers/net/wireless/ath/ath5k/reset.c
> +++ b/drivers/net/wireless/ath/ath5k/reset.c
> @@ -1020,13 +1020,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>                struct ieee80211_channel *channel, bool fast, bool skip_pcu)
>  {
>        u32 s_seq[10], s_led[3], tsf_up, tsf_lo;
> -       u8 mode, freq, ee_mode;
> +       u8 mode, ee_mode;
>        int i, ret;
>
>        ee_mode = 0;
>        tsf_up = 0;
>        tsf_lo = 0;
> -       freq = 0;
>        mode = 0;
>
>        /*
> @@ -1071,7 +1070,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>        switch (channel->hw_value & CHANNEL_MODES) {
>        case CHANNEL_A:
>                mode = AR5K_MODE_11A;
> -               freq = AR5K_INI_RFGAIN_5GHZ;
>                ee_mode = AR5K_EEPROM_MODE_11A;
>                break;
>        case CHANNEL_G:
> @@ -1083,7 +1081,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>                }
>
>                mode = AR5K_MODE_11G;
> -               freq = AR5K_INI_RFGAIN_2GHZ;
>                ee_mode = AR5K_EEPROM_MODE_11G;
>                break;
>        case CHANNEL_B:
> @@ -1095,7 +1092,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>                }
>
>                mode = AR5K_MODE_11B;
> -               freq = AR5K_INI_RFGAIN_2GHZ;
>                ee_mode = AR5K_EEPROM_MODE_11B;
>                break;
>        case CHANNEL_XR:
> @@ -1105,7 +1101,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>                        return -EINVAL;
>                }
>                mode = AR5K_MODE_XR;
> -               freq = AR5K_INI_RFGAIN_5GHZ;
>                ee_mode = AR5K_EEPROM_MODE_11A;
>                break;
>        default:
> @@ -1120,7 +1115,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>         */
>        if (fast) {
>                ret = ath5k_hw_phy_init(ah, channel, mode,
> -                                       ee_mode, freq, true);
> +                                       ee_mode, true);
>                if (ret) {
>                        ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
>                                "fast chan change failed, falling back to normal reset\n");
> @@ -1256,7 +1251,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>        /*
>         * Initialize PHY
>         */
> -       ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq, false);
> +       ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, false);
>        if (ret) {
>                ATH5K_ERR(ah->ah_sc,
>                        "failed to initialize PHY (%i) !\n", ret);
>
>

Acked-by: Nick Kossifidis <[email protected]>


--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2010-12-21 14:48:45

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 3/5] ath5k: Track current TX power separately from max TX power

2010/12/21 Bruno Randolf <[email protected]>:
> Add a new variable to keep track of the currently configured tx power. Before
> max_pwr was re-used for keeping the maximum allowed power as well as the
> current configuration. Doing a min() on it allows you to lower the txpower, but
> how would you be able to make it higher again?
>
> This patch fixes that by adding a new variable ah_cur_pwr which is used instead
> of txp_max_pwr to keep the current configuration. txp_max_pwr is used to check
> if we are within the limits.
>
> Another problem fixed by this patch is that it avoids setting a zero txpower
> when things are initialized first and the current power is not yet set.
>
> Signed-off-by: Bruno Randolf <[email protected]>
> ---
>  drivers/net/wireless/ath/ath5k/ath5k.h |    1 +
>  drivers/net/wireless/ath/ath5k/phy.c   |    7 +++----
>  2 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
> index e6491bf..342da28 100644
> --- a/drivers/net/wireless/ath/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
> @@ -1107,6 +1107,7 @@ struct ath5k_hw {
>                /* Values in 0.25dB units */
>                s16             txp_min_pwr;
>                s16             txp_max_pwr;
> +               s16             txp_cur_pwr;
>                /* Values in 0.5dB units */
>                s16             txp_offset;
>                s16             txp_ofdm;
> diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
> index 6f0cf3a..18c58cd 100644
> --- a/drivers/net/wireless/ath/ath5k/phy.c
> +++ b/drivers/net/wireless/ath/ath5k/phy.c
> @@ -3096,7 +3096,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
>
>        /* Min/max in 0.25dB units */
>        ah->ah_txpower.txp_min_pwr = 2 * rates[7];
> -       ah->ah_txpower.txp_max_pwr = 2 * rates[0];
> +       ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
>        ah->ah_txpower.txp_ofdm = rates[7];
>  }
>
> @@ -3150,8 +3150,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>                /* Reset TX power values */
>                memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
>                ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
> -               ah->ah_txpower.txp_min_pwr = 0;
> -               ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;
>
>                /* Calculate the powertable */
>                ret = ath5k_setup_channel_powertable(ah, channel,
> @@ -3290,7 +3288,8 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>         * properly set curve indices.
>         */
>        ret = ath5k_hw_txpower(ah, channel, ee_mode,
> -                               ah->ah_txpower.txp_max_pwr / 2);
> +               ah->ah_txpower.txp_cur_pwr ?
> +                       ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER);
>        if (ret)
>                return ret;
>
>
>

Acked-by: Nick Kossifidis <[email protected]>


--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2010-12-21 08:30:27

by Bruno Randolf

[permalink] [raw]
Subject: [PATCH 2/5] ath5k: Separate powertable setup and writing

And rename functions which write the powertable to make it clearer.

Signed-off-by: Bruno Randolf <[email protected]>
---
drivers/net/wireless/ath/ath5k/phy.c | 34 ++++++++++++++++------------------
1 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 7c6d7dc..6f0cf3a 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -2593,7 +2593,7 @@ ath5k_combine_linear_pcdac_curves(struct ath5k_hw *ah, s16* table_min,

/* Write PCDAC values on hw */
static void
-ath5k_setup_pcdac_table(struct ath5k_hw *ah)
+ath5k_write_pcdac_table(struct ath5k_hw *ah)
{
u8 *pcdac_out = ah->ah_txpower.txp_pd_table;
int i;
@@ -2742,7 +2742,7 @@ ath5k_combine_pwr_to_pdadc_curves(struct ath5k_hw *ah,

/* Write PDADC values on hw */
static void
-ath5k_setup_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
+ath5k_write_pwr_to_pdadc_table(struct ath5k_hw *ah, u8 ee_mode)
{
struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
u8 *pdadc_out = ah->ah_txpower.txp_pd_table;
@@ -2957,8 +2957,7 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
(s16) pcinfo_R->freq,
pcinfo_L->max_pwr, pcinfo_R->max_pwr);

- /* We are ready to go, fill PCDAC/PDADC
- * table and write settings on hardware */
+ /* Fill PCDAC/PDADC table */
switch (type) {
case AR5K_PWRTABLE_LINEAR_PCDAC:
/* For RF5112 we can have one or two curves
@@ -2971,9 +2970,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
* match max power value with max
* table index */
ah->ah_txpower.txp_offset = 64 - (table_max[0] / 2);
-
- /* Write settings on hw */
- ath5k_setup_pcdac_table(ah);
break;
case AR5K_PWRTABLE_PWR_TO_PCDAC:
/* We are done for RF5111 since it has only
@@ -2983,9 +2979,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
/* No rate powertable adjustment for RF5111 */
ah->ah_txpower.txp_min_idx = 0;
ah->ah_txpower.txp_offset = 0;
-
- /* Write settings on hw */
- ath5k_setup_pcdac_table(ah);
break;
case AR5K_PWRTABLE_PWR_TO_PDADC:
/* Set PDADC boundaries and fill
@@ -2993,9 +2986,6 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
ath5k_combine_pwr_to_pdadc_curves(ah, table_min, table_max,
ee->ee_pd_gains[ee_mode]);

- /* Write settings on hw */
- ath5k_setup_pwr_to_pdadc_table(ah, ee_mode);
-
/* Set txp.offset, note that table_min
* can be negative */
ah->ah_txpower.txp_offset = table_min[0];
@@ -3009,6 +2999,15 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
return 0;
}

+/* Write power table for current channel to hw */
+static void
+ath5k_write_channel_powertable(struct ath5k_hw *ah, u8 ee_mode, u8 type)
+{
+ if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
+ ath5k_write_pwr_to_pdadc_table(ah, ee_mode);
+ else
+ ath5k_write_pcdac_table(ah);
+}

/*
* Per-rate tx power setting
@@ -3159,11 +3158,10 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
ee_mode, type);
if (ret)
return ret;
- /* Write cached table on hw */
- } else if (type == AR5K_PWRTABLE_PWR_TO_PDADC)
- ath5k_setup_pwr_to_pdadc_table(ah, ee_mode);
- else
- ath5k_setup_pcdac_table(ah);
+ }
+
+ /* Write table on hw */
+ ath5k_write_channel_powertable(ah, ee_mode, type);

/* Limit max power if we have a CTL available */
ath5k_get_max_ctl_power(ah, channel);


2010-12-21 14:49:32

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 5/5] ath5k: Use helper function to get eeprom mode from channel

2010/12/21 Bruno Randolf <[email protected]>:
> Introduce a helper function to get the EEPROM mode from channel and remove
> multiple similar switch statements. Also since it's now easy to get the EEPROM
> mode from the channel, use them inside the functions which need it, instead of
> passing a redundant ee_mode parameter.
>
> Signed-off-by: Bruno Randolf <[email protected]>
> ---
>  drivers/net/wireless/ath/ath5k/ath5k.h  |    2 -
>  drivers/net/wireless/ath/ath5k/eeprom.c |   16 +++++++
>  drivers/net/wireless/ath/ath5k/eeprom.h |    2 +
>  drivers/net/wireless/ath/ath5k/phy.c    |   68 +++++++------------------------
>  drivers/net/wireless/ath/ath5k/reset.c  |   19 ++++-----
>  5 files changed, 42 insertions(+), 65 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
> index 5de8520..407e39c 100644
> --- a/drivers/net/wireless/ath/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
> @@ -1318,7 +1318,7 @@ void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
>  int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
>  /* Init function */
>  int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
> -                               u8 mode, u8 ee_mode, bool fast);
> +                               u8 mode, bool fast);
>
>  /*
>  * Functions used internaly
> diff --git a/drivers/net/wireless/ath/ath5k/eeprom.c b/drivers/net/wireless/ath/ath5k/eeprom.c
> index 97eaa9a..80e6256 100644
> --- a/drivers/net/wireless/ath/ath5k/eeprom.c
> +++ b/drivers/net/wireless/ath/ath5k/eeprom.c
> @@ -1802,3 +1802,19 @@ ath5k_eeprom_detach(struct ath5k_hw *ah)
>        for (mode = AR5K_EEPROM_MODE_11A; mode <= AR5K_EEPROM_MODE_11G; mode++)
>                ath5k_eeprom_free_pcal_info(ah, mode);
>  }
> +
> +int
> +ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel)
> +{
> +       switch (channel->hw_value & CHANNEL_MODES) {
> +       case CHANNEL_A:
> +       case CHANNEL_XR:
> +               return AR5K_EEPROM_MODE_11A;
> +       case CHANNEL_G:
> +               return AR5K_EEPROM_MODE_11G;
> +       case CHANNEL_B:
> +               return AR5K_EEPROM_MODE_11B;
> +       default:
> +               return -1;
> +       }
> +}
> diff --git a/drivers/net/wireless/ath/ath5k/eeprom.h b/drivers/net/wireless/ath/ath5k/eeprom.h
> index 0017006..7c09e15 100644
> --- a/drivers/net/wireless/ath/ath5k/eeprom.h
> +++ b/drivers/net/wireless/ath/ath5k/eeprom.h
> @@ -517,3 +517,5 @@ struct ath5k_eeprom_info {
>        u32     ee_antenna[AR5K_EEPROM_N_MODES][AR5K_ANT_MAX];
>  };
>
> +int
> +ath5k_eeprom_mode_from_channel(struct ieee80211_channel *channel);
> diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
> index b6e9621..9306d5f 100644
> --- a/drivers/net/wireless/ath/ath5k/phy.c
> +++ b/drivers/net/wireless/ath/ath5k/phy.c
> @@ -1355,20 +1355,7 @@ void ath5k_hw_update_noise_floor(struct ath5k_hw *ah)
>                return;
>        }
>
> -       switch (ah->ah_current_channel->hw_value & CHANNEL_MODES) {
> -       case CHANNEL_A:
> -       case CHANNEL_XR:
> -               ee_mode = AR5K_EEPROM_MODE_11A;
> -               break;
> -       case CHANNEL_G:
> -               ee_mode = AR5K_EEPROM_MODE_11G;
> -               break;
> -       default:
> -       case CHANNEL_B:
> -               ee_mode = AR5K_EEPROM_MODE_11B;
> -               break;
> -       }
> -
> +       ee_mode = ath5k_eeprom_mode_from_channel(ah->ah_current_channel);
>
>        /* completed NF calibration, test threshold */
>        nf = ath5k_hw_read_measured_noise_floor(ah);
> @@ -1941,18 +1928,8 @@ ath5k_hw_set_antenna_mode(struct ath5k_hw *ah, u8 ant_mode)
>
>        def_ant = ah->ah_def_ant;
>
> -       switch (channel->hw_value & CHANNEL_MODES) {
> -       case CHANNEL_A:
> -       case CHANNEL_XR:
> -               ee_mode = AR5K_EEPROM_MODE_11A;
> -               break;
> -       case CHANNEL_G:
> -               ee_mode = AR5K_EEPROM_MODE_11G;
> -               break;
> -       case CHANNEL_B:
> -               ee_mode = AR5K_EEPROM_MODE_11B;
> -               break;
> -       default:
> +       ee_mode = ath5k_eeprom_mode_from_channel(channel);
> +       if (ee_mode < 0) {
>                ATH5K_ERR(ah->ah_sc,
>                        "invalid channel: %d\n", channel->center_freq);
>                return;
> @@ -3100,11 +3077,11 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
>  */
>  static int
>  ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
> -               u8 ee_mode, u8 txpower)
> +                u8 txpower)
>  {
>        struct ath5k_rate_pcal_info rate_info;
>        struct ieee80211_channel *curr_channel = ah->ah_current_channel;
> -       u8 type;
> +       u8 type, ee_mode;
>        int ret;
>
>        if (txpower > AR5K_TUNE_MAX_TXPOWER) {
> @@ -3112,6 +3089,13 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>                return -EINVAL;
>        }
>
> +       ee_mode = ath5k_eeprom_mode_from_channel(channel);
> +       if (ee_mode < 0) {
> +               ATH5K_ERR(ah->ah_sc,
> +                       "invalid channel: %d\n", channel->center_freq);
> +               return -EINVAL;
> +       }
> +
>        /* Initialize TX power table */
>        switch (ah->ah_radio) {
>        case AR5K_RF5110:
> @@ -3208,31 +3192,10 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>
>  int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
>  {
> -       /*Just a try M.F.*/
> -       struct ieee80211_channel *channel = ah->ah_current_channel;
> -       u8 ee_mode;
> -
> -       switch (channel->hw_value & CHANNEL_MODES) {
> -       case CHANNEL_A:
> -       case CHANNEL_XR:
> -               ee_mode = AR5K_EEPROM_MODE_11A;
> -               break;
> -       case CHANNEL_G:
> -               ee_mode = AR5K_EEPROM_MODE_11G;
> -               break;
> -       case CHANNEL_B:
> -               ee_mode = AR5K_EEPROM_MODE_11B;
> -               break;
> -       default:
> -               ATH5K_ERR(ah->ah_sc,
> -                       "invalid channel: %d\n", channel->center_freq);
> -               return -EINVAL;
> -       }
> -
>        ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
>                "changing txpower to %d\n", txpower);
>
> -       return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
> +       return ath5k_hw_txpower(ah, ah->ah_current_channel, txpower);
>  }
>
>  /*************\
> @@ -3240,7 +3203,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
>  \*************/
>
>  int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
> -                               u8 mode, u8 ee_mode, bool fast)
> +                     u8 mode, bool fast)
>  {
>        struct ieee80211_channel *curr_channel;
>        int ret, i;
> @@ -3281,8 +3244,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>         * RF buffer settings on 5211/5212+ so that we
>         * properly set curve indices.
>         */
> -       ret = ath5k_hw_txpower(ah, channel, ee_mode,
> -               ah->ah_txpower.txp_cur_pwr ?
> +       ret = ath5k_hw_txpower(ah, channel, ah->ah_txpower.txp_cur_pwr ?
>                        ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER);
>        if (ret)
>                return ret;
> diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
> index 4b8b987..3c962f7 100644
> --- a/drivers/net/wireless/ath/ath5k/reset.c
> +++ b/drivers/net/wireless/ath/ath5k/reset.c
> @@ -866,15 +866,18 @@ static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah,
>  }
>
>  static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah,
> -               struct ieee80211_channel *channel, u8 ee_mode)
> +               struct ieee80211_channel *channel)
>  {
>        struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
>        s16 cck_ofdm_pwr_delta;
> +       u8 ee_mode;
>
>        /* TODO: Add support for AR5210 EEPROM */
>        if (ah->ah_version == AR5K_AR5210)
>                return;
>
> +       ee_mode = ath5k_eeprom_mode_from_channel(channel);
> +
>        /* Adjust power delta for channel 14 */
>        if (channel->center_freq == 2484)
>                cck_ofdm_pwr_delta =
> @@ -1020,10 +1023,9 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>                struct ieee80211_channel *channel, bool fast, bool skip_pcu)
>  {
>        u32 s_seq[10], s_led[3], tsf_up, tsf_lo;
> -       u8 mode, ee_mode;
> +       u8 mode;
>        int i, ret;
>
> -       ee_mode = 0;
>        tsf_up = 0;
>        tsf_lo = 0;
>        mode = 0;
> @@ -1070,7 +1072,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>        switch (channel->hw_value & CHANNEL_MODES) {
>        case CHANNEL_A:
>                mode = AR5K_MODE_11A;
> -               ee_mode = AR5K_EEPROM_MODE_11A;
>                break;
>        case CHANNEL_G:
>
> @@ -1081,7 +1082,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>                }
>
>                mode = AR5K_MODE_11G;
> -               ee_mode = AR5K_EEPROM_MODE_11G;
>                break;
>        case CHANNEL_B:
>
> @@ -1092,7 +1092,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>                }
>
>                mode = AR5K_MODE_11B;
> -               ee_mode = AR5K_EEPROM_MODE_11B;
>                break;
>        case CHANNEL_XR:
>                if (ah->ah_version == AR5K_AR5211) {
> @@ -1101,7 +1100,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>                        return -EINVAL;
>                }
>                mode = AR5K_MODE_XR;
> -               ee_mode = AR5K_EEPROM_MODE_11A;
>                break;
>        default:
>                ATH5K_ERR(ah->ah_sc,
> @@ -1114,8 +1112,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>         * go on. If it fails continue with a normal reset.
>         */
>        if (fast) {
> -               ret = ath5k_hw_phy_init(ah, channel, mode,
> -                                       ee_mode, true);
> +               ret = ath5k_hw_phy_init(ah, channel, mode, true);
>                if (ret) {
>                        ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
>                                "fast chan change failed, falling back to normal reset\n");
> @@ -1212,7 +1209,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>        ath5k_hw_tweak_initval_settings(ah, channel);
>
>        /* Commit values from EEPROM */
> -       ath5k_hw_commit_eeprom_settings(ah, channel, ee_mode);
> +       ath5k_hw_commit_eeprom_settings(ah, channel);
>
>
>        /*
> @@ -1251,7 +1248,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
>        /*
>         * Initialize PHY
>         */
> -       ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, false);
> +       ret = ath5k_hw_phy_init(ah, channel, mode, false);
>        if (ret) {
>                ATH5K_ERR(ah->ah_sc,
>                        "failed to initialize PHY (%i) !\n", ret);
>
>

Acked-by: Nick Kossifidis <[email protected]>


--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2010-12-21 08:30:37

by Bruno Randolf

[permalink] [raw]
Subject: [PATCH 4/5] ath5k: Remove ATH5K_INI_RFGAIN defines, use band instead

Remove redundant defines.

Signed-off-by: Bruno Randolf <[email protected]>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 6 +-----
drivers/net/wireless/ath/ath5k/phy.c | 18 ++++++------------
drivers/net/wireless/ath/ath5k/reset.c | 11 +++--------
3 files changed, 10 insertions(+), 25 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 342da28..5de8520 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -154,10 +154,6 @@
udelay(1); \
} while (0)

-/* Register dumps are done per operation mode */
-#define AR5K_INI_RFGAIN_5GHZ 0
-#define AR5K_INI_RFGAIN_2GHZ 1
-
/*
* Some tuneable values (these should be changeable by the user)
* TODO: Make use of them and add more options OR use debug/configfs
@@ -1322,7 +1318,7 @@ void ath5k_hw_set_antenna_switch(struct ath5k_hw *ah, u8 ee_mode);
int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower);
/* Init function */
int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 mode, u8 ee_mode, u8 freq, bool fast);
+ u8 mode, u8 ee_mode, bool fast);

/*
* Functions used internaly
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 18c58cd..b6e9621 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -609,10 +609,10 @@ done:
/* Write initial RF gain table to set the RF sensitivity
* this one works on all RF chips and has nothing to do
* with gain_F calibration */
-static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
+static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, enum ieee80211_band band)
{
const struct ath5k_ini_rfgain *ath5k_rfg;
- unsigned int i, size;
+ unsigned int i, size, index;

switch (ah->ah_radio) {
case AR5K_RF5111:
@@ -644,17 +644,11 @@ static int ath5k_hw_rfgain_init(struct ath5k_hw *ah, unsigned int freq)
return -EINVAL;
}

- switch (freq) {
- case AR5K_INI_RFGAIN_2GHZ:
- case AR5K_INI_RFGAIN_5GHZ:
- break;
- default:
- return -EINVAL;
- }
+ index = (band == IEEE80211_BAND_2GHZ) ? 1 : 0;

for (i = 0; i < size; i++) {
AR5K_REG_WAIT(i);
- ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[freq],
+ ath5k_hw_reg_write(ah, ath5k_rfg[i].rfg_value[index],
(u32)ath5k_rfg[i].rfg_register);
}

@@ -3246,7 +3240,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
\*************/

int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
- u8 mode, u8 ee_mode, u8 freq, bool fast)
+ u8 mode, u8 ee_mode, bool fast)
{
struct ieee80211_channel *curr_channel;
int ret, i;
@@ -3305,7 +3299,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
* Write initial RF gain settings
* This should work for both 5111/5112
*/
- ret = ath5k_hw_rfgain_init(ah, freq);
+ ret = ath5k_hw_rfgain_init(ah, channel->band);
if (ret)
return ret;

diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index bc84aaa..4b8b987 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1020,13 +1020,12 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
struct ieee80211_channel *channel, bool fast, bool skip_pcu)
{
u32 s_seq[10], s_led[3], tsf_up, tsf_lo;
- u8 mode, freq, ee_mode;
+ u8 mode, ee_mode;
int i, ret;

ee_mode = 0;
tsf_up = 0;
tsf_lo = 0;
- freq = 0;
mode = 0;

/*
@@ -1071,7 +1070,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
switch (channel->hw_value & CHANNEL_MODES) {
case CHANNEL_A:
mode = AR5K_MODE_11A;
- freq = AR5K_INI_RFGAIN_5GHZ;
ee_mode = AR5K_EEPROM_MODE_11A;
break;
case CHANNEL_G:
@@ -1083,7 +1081,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}

mode = AR5K_MODE_11G;
- freq = AR5K_INI_RFGAIN_2GHZ;
ee_mode = AR5K_EEPROM_MODE_11G;
break;
case CHANNEL_B:
@@ -1095,7 +1092,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
}

mode = AR5K_MODE_11B;
- freq = AR5K_INI_RFGAIN_2GHZ;
ee_mode = AR5K_EEPROM_MODE_11B;
break;
case CHANNEL_XR:
@@ -1105,7 +1101,6 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
return -EINVAL;
}
mode = AR5K_MODE_XR;
- freq = AR5K_INI_RFGAIN_5GHZ;
ee_mode = AR5K_EEPROM_MODE_11A;
break;
default:
@@ -1120,7 +1115,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
*/
if (fast) {
ret = ath5k_hw_phy_init(ah, channel, mode,
- ee_mode, freq, true);
+ ee_mode, true);
if (ret) {
ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_RESET,
"fast chan change failed, falling back to normal reset\n");
@@ -1256,7 +1251,7 @@ int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
/*
* Initialize PHY
*/
- ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, freq, false);
+ ret = ath5k_hw_phy_init(ah, channel, mode, ee_mode, false);
if (ret) {
ATH5K_ERR(ah->ah_sc,
"failed to initialize PHY (%i) !\n", ret);


2010-12-21 14:48:01

by Nick Kossifidis

[permalink] [raw]
Subject: Re: [PATCH 1/5] ath5k: Simplify powertable recalculation

2010/12/21 Bruno Randolf <[email protected]>:
> Let ath5k_hw_txpower() decide if it can re-use the powertable or if it has to
> be recalculated instead of passing a 'fast' flag from the outside.
>
> Signed-off-by: Bruno Randolf <[email protected]>
> ---
>  drivers/net/wireless/ath/ath5k/ath5k.h |    1 +
>  drivers/net/wireless/ath/ath5k/phy.c   |   35 ++++++++++++--------------------
>  2 files changed, 14 insertions(+), 22 deletions(-)
>
> diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
> index d6e7440..e6491bf 100644
> --- a/drivers/net/wireless/ath/ath5k/ath5k.h
> +++ b/drivers/net/wireless/ath/ath5k/ath5k.h
> @@ -1113,6 +1113,7 @@ struct ath5k_hw {
>                s16             txp_cck_ofdm_gainf_delta;
>                /* Value in dB units */
>                s16             txp_cck_ofdm_pwr_delta;
> +               bool            txp_setup;
>        } ah_txpower;
>
>        struct {
> diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
> index f84afb4..7c6d7dc 100644
> --- a/drivers/net/wireless/ath/ath5k/phy.c
> +++ b/drivers/net/wireless/ath/ath5k/phy.c
> @@ -3004,6 +3004,8 @@ ath5k_setup_channel_powertable(struct ath5k_hw *ah,
>                return -EINVAL;
>        }
>
> +       ah->ah_txpower.txp_setup = true;
> +
>        return 0;
>  }
>
> @@ -3105,9 +3107,10 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,
>  */
>  static int
>  ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
> -               u8 ee_mode, u8 txpower, bool fast)
> +               u8 ee_mode, u8 txpower)
>  {
>        struct ath5k_rate_pcal_info rate_info;
> +       struct ieee80211_channel *curr_channel = ah->ah_current_channel;
>        u8 type;
>        int ret;
>
> @@ -3138,10 +3141,13 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>                return -EINVAL;
>        }
>
> -       /* If fast is set it means we are on the same channel/mode
> -        * so there is no need to recalculate the powertable, we 'll
> -        * just use the cached one */
> -       if (!fast) {
> +       /*
> +        * If we don't change channel/mode skip tx powertable calculation
> +        * and use the cached one.
> +        */
> +       if (!ah->ah_txpower.txp_setup ||
> +           (channel->hw_value != curr_channel->hw_value) ||
> +           (channel->center_freq != curr_channel->center_freq)) {
>                /* Reset TX power values */
>                memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
>                ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
> @@ -3159,8 +3165,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>        else
>                ath5k_setup_pcdac_table(ah);
>
> -
> -
>        /* Limit max power if we have a CTL available */
>        ath5k_get_max_ctl_power(ah, channel);
>
> @@ -3238,7 +3242,7 @@ int ath5k_hw_set_txpower_limit(struct ath5k_hw *ah, u8 txpower)
>        ATH5K_DBG(ah->ah_sc, ATH5K_DEBUG_TXPOWER,
>                "changing txpower to %d\n", txpower);
>
> -       return ath5k_hw_txpower(ah, channel, ee_mode, txpower, true);
> +       return ath5k_hw_txpower(ah, channel, ee_mode, txpower);
>  }
>
>  /*************\
> @@ -3251,7 +3255,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>        struct ieee80211_channel *curr_channel;
>        int ret, i;
>        u32 phy_tst1;
> -       bool fast_txp;
>        ret = 0;
>
>        /*
> @@ -3282,17 +3285,6 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>        }
>
>        /*
> -        * If we don't change channel/mode skip
> -        * tx powertable calculation and use the
> -        * cached one.
> -        */
> -       if ((channel->hw_value == curr_channel->hw_value) &&
> -       (channel->center_freq == curr_channel->center_freq))
> -               fast_txp = true;
> -       else
> -               fast_txp = false;
> -
> -       /*
>         * Set TX power
>         *
>         * Note: We need to do that before we set
> @@ -3300,8 +3292,7 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
>         * properly set curve indices.
>         */
>        ret = ath5k_hw_txpower(ah, channel, ee_mode,
> -                               ah->ah_txpower.txp_max_pwr / 2,
> -                               fast_txp);
> +                               ah->ah_txpower.txp_max_pwr / 2);
>        if (ret)
>                return ret;
>
>
>

Acked-by: Nick Kossifidis <[email protected]>


--
GPG ID: 0xD21DB2DB
As you read this post global entropy rises. Have Fun ;-)
Nick

2010-12-21 08:30:30

by Bruno Randolf

[permalink] [raw]
Subject: [PATCH 3/5] ath5k: Track current TX power separately from max TX power

Add a new variable to keep track of the currently configured tx power. Before
max_pwr was re-used for keeping the maximum allowed power as well as the
current configuration. Doing a min() on it allows you to lower the txpower, but
how would you be able to make it higher again?

This patch fixes that by adding a new variable ah_cur_pwr which is used instead
of txp_max_pwr to keep the current configuration. txp_max_pwr is used to check
if we are within the limits.

Another problem fixed by this patch is that it avoids setting a zero txpower
when things are initialized first and the current power is not yet set.

Signed-off-by: Bruno Randolf <[email protected]>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 1 +
drivers/net/wireless/ath/ath5k/phy.c | 7 +++----
2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index e6491bf..342da28 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1107,6 +1107,7 @@ struct ath5k_hw {
/* Values in 0.25dB units */
s16 txp_min_pwr;
s16 txp_max_pwr;
+ s16 txp_cur_pwr;
/* Values in 0.5dB units */
s16 txp_offset;
s16 txp_ofdm;
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 6f0cf3a..18c58cd 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -3096,7 +3096,7 @@ ath5k_setup_rate_powertable(struct ath5k_hw *ah, u16 max_pwr,

/* Min/max in 0.25dB units */
ah->ah_txpower.txp_min_pwr = 2 * rates[7];
- ah->ah_txpower.txp_max_pwr = 2 * rates[0];
+ ah->ah_txpower.txp_cur_pwr = 2 * rates[0];
ah->ah_txpower.txp_ofdm = rates[7];
}

@@ -3150,8 +3150,6 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
/* Reset TX power values */
memset(&ah->ah_txpower, 0, sizeof(ah->ah_txpower));
ah->ah_txpower.txp_tpc = AR5K_TUNE_TPC_TXPOWER;
- ah->ah_txpower.txp_min_pwr = 0;
- ah->ah_txpower.txp_max_pwr = AR5K_TUNE_MAX_TXPOWER;

/* Calculate the powertable */
ret = ath5k_setup_channel_powertable(ah, channel,
@@ -3290,7 +3288,8 @@ int ath5k_hw_phy_init(struct ath5k_hw *ah, struct ieee80211_channel *channel,
* properly set curve indices.
*/
ret = ath5k_hw_txpower(ah, channel, ee_mode,
- ah->ah_txpower.txp_max_pwr / 2);
+ ah->ah_txpower.txp_cur_pwr ?
+ ah->ah_txpower.txp_cur_pwr / 2 : AR5K_TUNE_MAX_TXPOWER);
if (ret)
return ret;