Commit 2c5a744d authored by Sujith's avatar Sujith Committed by John W. Linville

ath9k: Use helpers

Break down huge functions, use helper functions or
macros instead.
Signed-off-by: default avatarSujith <Sujith.Manoharan@atheros.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 46d14a58
...@@ -153,11 +153,6 @@ static struct ath_rate_table ar5416_11na_ratetable = { ...@@ -153,11 +153,6 @@ static struct ath_rate_table ar5416_11na_ratetable = {
WLAN_RC_HT_FLAG, /* Phy rates allowed initially */ WLAN_RC_HT_FLAG, /* Phy rates allowed initially */
}; };
/* VALID_ALL - valid for 20/40/Legacy,
* VALID - Legacy only,
* VALID_20 - HT 20 only,
* VALID_40 - HT 40 only */
/* 4ms frame limit not used for NG mode. The values filled /* 4ms frame limit not used for NG mode. The values filled
* for HT are the 64K max aggregate limit */ * for HT are the 64K max aggregate limit */
...@@ -471,11 +466,10 @@ static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv, ...@@ -471,11 +466,10 @@ static inline int ath_rc_isvalid_txmask(struct ath_rate_priv *ath_rc_priv,
return ath_rc_priv->valid_rate_index[index]; return ath_rc_priv->valid_rate_index[index];
} }
static inline int static inline int ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table, struct ath_rate_priv *ath_rc_priv,
struct ath_rate_priv *ath_rc_priv, u8 cur_valid_txrate,
u8 cur_valid_txrate, u8 *next_idx)
u8 *next_idx)
{ {
u8 i; u8 i;
...@@ -488,6 +482,7 @@ ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table, ...@@ -488,6 +482,7 @@ ath_rc_get_nextvalid_txrate(struct ath_rate_table *rate_table,
/* No more valid rates */ /* No more valid rates */
*next_idx = 0; *next_idx = 0;
return 0; return 0;
} }
...@@ -522,13 +517,13 @@ ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table, ...@@ -522,13 +517,13 @@ ath_rc_get_nextlowervalid_txrate(struct ath_rate_table *rate_table,
return 1; return 1;
} }
} }
return 0; return 0;
} }
static u8 static u8 ath_rc_init_validrates(struct ath_rate_priv *ath_rc_priv,
ath_rc_sib_init_validrates(struct ath_rate_priv *ath_rc_priv, struct ath_rate_table *rate_table,
struct ath_rate_table *rate_table, u32 capflag)
u32 capflag)
{ {
u8 i, hi = 0; u8 i, hi = 0;
u32 valid; u32 valid;
...@@ -552,14 +547,14 @@ ath_rc_sib_init_validrates(struct ath_rate_priv *ath_rc_priv, ...@@ -552,14 +547,14 @@ ath_rc_sib_init_validrates(struct ath_rate_priv *ath_rc_priv,
hi = A_MAX(hi, i); hi = A_MAX(hi, i);
} }
} }
return hi; return hi;
} }
static u8 static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
ath_rc_sib_setvalid_rates(struct ath_rate_priv *ath_rc_priv, struct ath_rate_table *rate_table,
struct ath_rate_table *rate_table, struct ath_rateset *rateset,
struct ath_rateset *rateset, u32 capflag)
u32 capflag)
{ {
u8 i, j, hi = 0; u8 i, j, hi = 0;
...@@ -570,17 +565,17 @@ ath_rc_sib_setvalid_rates(struct ath_rate_priv *ath_rc_priv, ...@@ -570,17 +565,17 @@ ath_rc_sib_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
u32 valid = (ath_rc_priv->single_stream ? u32 valid = (ath_rc_priv->single_stream ?
rate_table->info[j].valid_single_stream : rate_table->info[j].valid_single_stream :
rate_table->info[j].valid); rate_table->info[j].valid);
u8 rate = rateset->rs_rates[i];
u8 dot11rate = rate_table->info[j].dot11rate;
/* We allow a rate only if its valid and the /* We allow a rate only if its valid and the
* capflag matches one of the validity * capflag matches one of the validity
* (VALID/VALID_20/VALID_40) flags */ * (VALID/VALID_20/VALID_40) flags */
if (((rateset->rs_rates[i] & 0x7F) == if (((rate & 0x7F) == (dot11rate & 0x7F)) &&
(rate_table->info[j].dot11rate & 0x7F)) && ((valid & WLAN_RC_CAP_MODE(capflag)) ==
((valid & WLAN_RC_CAP_MODE(capflag)) == WLAN_RC_CAP_MODE(capflag)) &&
WLAN_RC_CAP_MODE(capflag)) && !WLAN_RC_PHY_HT(phy)) {
!WLAN_RC_PHY_HT(phy)) {
u8 valid_rate_count = 0; u8 valid_rate_count = 0;
if (!ath_rc_valid_phyrate(phy, capflag, 0)) if (!ath_rc_valid_phyrate(phy, capflag, 0))
...@@ -597,27 +592,29 @@ ath_rc_sib_setvalid_rates(struct ath_rate_priv *ath_rc_priv, ...@@ -597,27 +592,29 @@ ath_rc_sib_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
} }
} }
} }
return hi; return hi;
} }
static u8 static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
ath_rc_sib_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, struct ath_rate_table *rate_table,
struct ath_rate_table *rate_table, u8 *mcs_set, u32 capflag)
u8 *mcs_set, u32 capflag)
{ {
struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
u8 i, j, hi = 0; u8 i, j, hi = 0;
/* Use intersection of working rates and valid rates */ /* Use intersection of working rates and valid rates */
for (i = 0; i < ((struct ath_rateset *)mcs_set)->rs_nrates; i++) { for (i = 0; i < rateset->rs_nrates; i++) {
for (j = 0; j < rate_table->rate_cnt; j++) { for (j = 0; j < rate_table->rate_cnt; j++) {
u32 phy = rate_table->info[j].phy; u32 phy = rate_table->info[j].phy;
u32 valid = (ath_rc_priv->single_stream ? u32 valid = (ath_rc_priv->single_stream ?
rate_table->info[j].valid_single_stream : rate_table->info[j].valid_single_stream :
rate_table->info[j].valid); rate_table->info[j].valid);
u8 rate = rateset->rs_rates[i];
u8 dot11rate = rate_table->info[j].dot11rate;
if (((((struct ath_rateset *) if (((rate & 0x7F) != (dot11rate & 0x7F)) ||
mcs_set)->rs_rates[i] & 0x7F) !=
(rate_table->info[j].dot11rate & 0x7F)) ||
!WLAN_RC_PHY_HT(phy) || !WLAN_RC_PHY_HT(phy) ||
!WLAN_RC_PHY_HT_VALID(valid, capflag)) !WLAN_RC_PHY_HT_VALID(valid, capflag))
continue; continue;
...@@ -632,26 +629,8 @@ ath_rc_sib_setvalid_htrates(struct ath_rate_priv *ath_rc_priv, ...@@ -632,26 +629,8 @@ ath_rc_sib_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
hi = A_MAX(hi, j); hi = A_MAX(hi, j);
} }
} }
return hi;
}
u8 ath_rate_findrateix(struct ath_softc *sc,
u8 dot11rate)
{
struct ath_rate_table *ratetable;
int i;
ratetable = sc->hw_rate_table[sc->sc_curmode];
if (WARN_ON(!ratetable))
return 0;
for (i = 0; i < ratetable->rate_cnt; i++) {
if ((ratetable->info[i].dot11rate & 0x7f) == (dot11rate & 0x7f))
return i;
}
return 0; return hi;
} }
static u8 ath_rc_ratefind_ht(struct ath_softc *sc, static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
...@@ -784,9 +763,7 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc, ...@@ -784,9 +763,7 @@ static u8 ath_rc_ratefind_ht(struct ath_softc *sc,
static void ath_rc_rate_set_series(struct ath_rate_table *rate_table , static void ath_rc_rate_set_series(struct ath_rate_table *rate_table ,
struct ieee80211_tx_rate *rate, struct ieee80211_tx_rate *rate,
u8 tries, u8 tries, u8 rix, int rtsctsenable)
u8 rix,
int rtsctsenable)
{ {
rate->count = tries; rate->count = tries;
rate->idx = rix; rate->idx = rix;
...@@ -911,15 +888,16 @@ static void ath_rc_ratefind(struct ath_softc *sc, ...@@ -911,15 +888,16 @@ static void ath_rc_ratefind(struct ath_softc *sc,
} }
} }
static void ath_rc_update_ht(struct ath_softc *sc, static bool ath_rc_update_per(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv, struct ath_rate_table *rate_table,
struct ath_tx_info_priv *tx_info_priv, struct ath_rate_priv *ath_rc_priv,
int tx_rate, int xretries, int retries) struct ath_tx_info_priv *tx_info_priv,
int tx_rate, int xretries, int retries,
u32 now_msec)
{ {
u32 now_msec = jiffies_to_msecs(jiffies); bool state_change = false;
int state_change = 0, rate, count; int count;
u8 last_per; u8 last_per;
struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
static u32 nretry_to_per_lookup[10] = { static u32 nretry_to_per_lookup[10] = {
100 * 0 / 1, 100 * 0 / 1,
100 * 1 / 4, 100 * 1 / 4,
...@@ -933,24 +911,9 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -933,24 +911,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
100 * 9 / 10 100 * 9 / 10
}; };
if (!ath_rc_priv)
return;
ASSERT(tx_rate >= 0);
if (tx_rate < 0)
return;
/* To compensate for some imbalance between ctrl and ext. channel */
if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
tx_info_priv->tx.ts_rssi =
tx_info_priv->tx.ts_rssi < 3 ? 0 :
tx_info_priv->tx.ts_rssi - 3;
last_per = ath_rc_priv->state[tx_rate].per; last_per = ath_rc_priv->state[tx_rate].per;
if (xretries) { if (xretries) {
/* Update the PER. */
if (xretries == 1) { if (xretries == 1) {
ath_rc_priv->state[tx_rate].per += 30; ath_rc_priv->state[tx_rate].per += 30;
if (ath_rc_priv->state[tx_rate].per > 100) if (ath_rc_priv->state[tx_rate].per > 100)
...@@ -960,11 +923,10 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -960,11 +923,10 @@ static void ath_rc_update_ht(struct ath_softc *sc,
count = ARRAY_SIZE(nretry_to_per_lookup); count = ARRAY_SIZE(nretry_to_per_lookup);
if (retries >= count) if (retries >= count)
retries = count - 1; retries = count - 1;
/* new_PER = 7/8*old_PER + 1/8*(currentPER) */ /* new_PER = 7/8*old_PER + 1/8*(currentPER) */
ath_rc_priv->state[tx_rate].per = ath_rc_priv->state[tx_rate].per =
(u8)(ath_rc_priv->state[tx_rate].per - (u8)(last_per - (last_per >> 3) + (100 >> 3));
(ath_rc_priv->state[tx_rate].per >> 3) +
((100) >> 3));
} }
/* xretries == 1 or 2 */ /* xretries == 1 or 2 */
...@@ -972,12 +934,11 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -972,12 +934,11 @@ static void ath_rc_update_ht(struct ath_softc *sc,
if (ath_rc_priv->probe_rate == tx_rate) if (ath_rc_priv->probe_rate == tx_rate)
ath_rc_priv->probe_rate = 0; ath_rc_priv->probe_rate = 0;
} else { /* xretries == 0 */ } else { /* xretries == 0 */
/* Update the PER. */
/* Make sure it doesn't index out of array's bounds. */
count = ARRAY_SIZE(nretry_to_per_lookup); count = ARRAY_SIZE(nretry_to_per_lookup);
if (retries >= count) if (retries >= count)
retries = count - 1; retries = count - 1;
if (tx_info_priv->n_bad_frames) { if (tx_info_priv->n_bad_frames) {
/* new_PER = 7/8*old_PER + 1/8*(currentPER) /* new_PER = 7/8*old_PER + 1/8*(currentPER)
* Assuming that n_frames is not 0. The current PER * Assuming that n_frames is not 0. The current PER
...@@ -991,22 +952,21 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -991,22 +952,21 @@ static void ath_rc_update_ht(struct ath_softc *sc,
* the above PER. The expression below is a * the above PER. The expression below is a
* simplified version of the sum of these two terms. * simplified version of the sum of these two terms.
*/ */
if (tx_info_priv->n_frames > 0) if (tx_info_priv->n_frames > 0) {
ath_rc_priv->state[tx_rate].per int n_frames, n_bad_frames;
= (u8) u8 cur_per, new_per;
(ath_rc_priv->state[tx_rate].per -
(ath_rc_priv->state[tx_rate].per >> 3) + n_bad_frames = retries * tx_info_priv->n_frames +
((100*(retries*tx_info_priv->n_frames + tx_info_priv->n_bad_frames;
tx_info_priv->n_bad_frames) / n_frames = tx_info_priv->n_frames * (retries + 1);
(tx_info_priv->n_frames * cur_per = (100 * n_bad_frames / n_frames) >> 3;
(retries+1))) >> 3)); new_per = (u8)(last_per - (last_per >> 3) + cur_per);
ath_rc_priv->state[tx_rate].per = new_per;
}
} else { } else {
/* new_PER = 7/8*old_PER + 1/8*(currentPER) */ ath_rc_priv->state[tx_rate].per =
(u8)(last_per - (last_per >> 3) +
ath_rc_priv->state[tx_rate].per = (u8) (nretry_to_per_lookup[retries] >> 3));
(ath_rc_priv->state[tx_rate].per -
(ath_rc_priv->state[tx_rate].per >> 3) +
(nretry_to_per_lookup[retries] >> 3));
} }
ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev; ath_rc_priv->rssi_last_prev2 = ath_rc_priv->rssi_last_prev;
...@@ -1018,7 +978,6 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1018,7 +978,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
* If we got at most one retry then increase the max rate if * If we got at most one retry then increase the max rate if
* this was a probe. Otherwise, ignore the probe. * this was a probe. Otherwise, ignore the probe.
*/ */
if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) { if (ath_rc_priv->probe_rate && ath_rc_priv->probe_rate == tx_rate) {
if (retries > 0 || 2 * tx_info_priv->n_bad_frames > if (retries > 0 || 2 * tx_info_priv->n_bad_frames >
tx_info_priv->n_frames) { tx_info_priv->n_frames) {
...@@ -1033,7 +992,8 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1033,7 +992,8 @@ static void ath_rc_update_ht(struct ath_softc *sc,
} else { } else {
u8 probe_rate = 0; u8 probe_rate = 0;
ath_rc_priv->rate_max_phy = ath_rc_priv->probe_rate; ath_rc_priv->rate_max_phy =
ath_rc_priv->probe_rate;
probe_rate = ath_rc_priv->probe_rate; probe_rate = ath_rc_priv->probe_rate;
if (ath_rc_priv->state[probe_rate].per > 30) if (ath_rc_priv->state[probe_rate].per > 30)
...@@ -1047,8 +1007,8 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1047,8 +1007,8 @@ static void ath_rc_update_ht(struct ath_softc *sc,
* to move up faster if the probes are * to move up faster if the probes are
* succesful. * succesful.
*/ */
ath_rc_priv->probe_time = now_msec - ath_rc_priv->probe_time =
rate_table->probe_interval / 2; now_msec - rate_table->probe_interval / 2;
} }
} }
...@@ -1064,6 +1024,10 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1064,6 +1024,10 @@ static void ath_rc_update_ht(struct ath_softc *sc,
*/ */
ath_rc_priv->hw_maxretry_pktcnt = 0; ath_rc_priv->hw_maxretry_pktcnt = 0;
} else { } else {
int32_t rssi_ackAvg;
int8_t rssi_thres;
int8_t rssi_ack_vmin;
/* /*
* It worked with no retries. First ignore bogus (small) * It worked with no retries. First ignore bogus (small)
* rssi_ack values. * rssi_ack values.
...@@ -1073,46 +1037,82 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1073,46 +1037,82 @@ static void ath_rc_update_ht(struct ath_softc *sc,
ath_rc_priv->hw_maxretry_pktcnt++; ath_rc_priv->hw_maxretry_pktcnt++;
} }
if (tx_info_priv->tx.ts_rssi >= if (tx_info_priv->tx.ts_rssi <
rate_table->info[tx_rate].rssi_ack_validmin) { rate_table->info[tx_rate].rssi_ack_validmin)
/* Average the rssi */ goto exit;
if (tx_rate != ath_rc_priv->rssi_sum_rate) {
ath_rc_priv->rssi_sum_rate = tx_rate;
ath_rc_priv->rssi_sum =
ath_rc_priv->rssi_sum_cnt = 0;
}
ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi; /* Average the rssi */
ath_rc_priv->rssi_sum_cnt++; if (tx_rate != ath_rc_priv->rssi_sum_rate) {
ath_rc_priv->rssi_sum_rate = tx_rate;
if (ath_rc_priv->rssi_sum_cnt > 4) { ath_rc_priv->rssi_sum =
int32_t rssi_ackAvg = ath_rc_priv->rssi_sum_cnt = 0;
(ath_rc_priv->rssi_sum + 2) / 4; }
int8_t rssi_thres =
ath_rc_priv->state[tx_rate]. ath_rc_priv->rssi_sum += tx_info_priv->tx.ts_rssi;
rssi_thres; ath_rc_priv->rssi_sum_cnt++;
int8_t rssi_ack_vmin =
rate_table->info[tx_rate]. if (ath_rc_priv->rssi_sum_cnt < 4)
rssi_ack_validmin; goto exit;
ath_rc_priv->rssi_sum = rssi_ackAvg =
ath_rc_priv->rssi_sum_cnt = 0; (ath_rc_priv->rssi_sum + 2) / 4;
rssi_thres =
/* Now reduce the current ath_rc_priv->state[tx_rate].rssi_thres;
* rssi threshold. */ rssi_ack_vmin =
if ((rssi_ackAvg < rssi_thres + 2) && rate_table->info[tx_rate].rssi_ack_validmin;
(rssi_thres > rssi_ack_vmin)) {
ath_rc_priv->state[tx_rate]. ath_rc_priv->rssi_sum =
rssi_thres--; ath_rc_priv->rssi_sum_cnt = 0;
}
/* Now reduce the current rssi threshold */
state_change = 1; if ((rssi_ackAvg < rssi_thres + 2) &&
} (rssi_thres > rssi_ack_vmin)) {
ath_rc_priv->state[tx_rate].rssi_thres--;
} }
state_change = true;
} }
} }
exit:
return state_change;
}
/* Update PER, RSSI and whatever else that the code thinks it is doing.
If you can make sense of all this, you really need to go out more. */
/* For all cases */ static void ath_rc_update_ht(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
struct ath_tx_info_priv *tx_info_priv,
int tx_rate, int xretries, int retries)
{
#define CHK_RSSI(rate) \
((ath_rc_priv->state[(rate)].rssi_thres + \
rate_table->info[(rate)].rssi_ack_deltamin) > \
ath_rc_priv->state[(rate)+1].rssi_thres)
u32 now_msec = jiffies_to_msecs(jiffies);
int rate;
u8 last_per;
bool state_change = false;
struct ath_rate_table *rate_table = sc->hw_rate_table[sc->sc_curmode];
int size = ath_rc_priv->rate_table_size;
if ((tx_rate < 0) || (tx_rate > rate_table->rate_cnt))
return;
/* To compensate for some imbalance between ctrl and ext. channel */
if (WLAN_RC_PHY_40(rate_table->info[tx_rate].phy))
tx_info_priv->tx.ts_rssi =
tx_info_priv->tx.ts_rssi < 3 ? 0 :
tx_info_priv->tx.ts_rssi - 3;
last_per = ath_rc_priv->state[tx_rate].per;
/* Update PER first */
state_change = ath_rc_update_per(sc, rate_table, ath_rc_priv,
tx_info_priv, tx_rate, xretries,
retries, now_msec);
/* /*
* If this rate looks bad (high PER) then stop using it for * If this rate looks bad (high PER) then stop using it for
...@@ -1122,7 +1122,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1122,7 +1122,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
rate_table->info[tx_rate].ratekbps <= rate_table->info[tx_rate].ratekbps <=
rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) { rate_table->info[ath_rc_priv->rate_max_phy].ratekbps) {
ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv, ath_rc_get_nextlowervalid_txrate(rate_table, ath_rc_priv,
(u8) tx_rate, &ath_rc_priv->rate_max_phy); (u8)tx_rate, &ath_rc_priv->rate_max_phy);
/* Don't probe for a little while. */ /* Don't probe for a little while. */
ath_rc_priv->probe_time = now_msec; ath_rc_priv->probe_time = now_msec;
...@@ -1136,20 +1136,15 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1136,20 +1136,15 @@ static void ath_rc_update_ht(struct ath_softc *sc,
* made to keep the rssi thresholds monotonically * made to keep the rssi thresholds monotonically
* increasing between the CCK and OFDM rates.) * increasing between the CCK and OFDM rates.)
*/ */
for (rate = tx_rate; rate < for (rate = tx_rate; rate < size - 1; rate++) {
ath_rc_priv->rate_table_size - 1; rate++) {
if (rate_table->info[rate+1].phy != if (rate_table->info[rate+1].phy !=
rate_table->info[tx_rate].phy) rate_table->info[tx_rate].phy)
break; break;
if (ath_rc_priv->state[rate].rssi_thres + if (CHK_RSSI(rate)) {
rate_table->info[rate].rssi_ack_deltamin >
ath_rc_priv->state[rate+1].rssi_thres) {
ath_rc_priv->state[rate+1].rssi_thres = ath_rc_priv->state[rate+1].rssi_thres =
ath_rc_priv->state[rate]. ath_rc_priv->state[rate].rssi_thres +
rssi_thres + rate_table->info[rate].rssi_ack_deltamin;
rate_table->info[rate].
rssi_ack_deltamin;
} }
} }
...@@ -1159,27 +1154,20 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1159,27 +1154,20 @@ static void ath_rc_update_ht(struct ath_softc *sc,
rate_table->info[tx_rate].phy) rate_table->info[tx_rate].phy)
break; break;
if (ath_rc_priv->state[rate].rssi_thres + if (CHK_RSSI(rate)) {
rate_table->info[rate].rssi_ack_deltamin >
ath_rc_priv->state[rate+1].rssi_thres) {
if (ath_rc_priv->state[rate+1].rssi_thres < if (ath_rc_priv->state[rate+1].rssi_thres <
rate_table->info[rate]. rate_table->info[rate].rssi_ack_deltamin)
rssi_ack_deltamin)
ath_rc_priv->state[rate].rssi_thres = 0; ath_rc_priv->state[rate].rssi_thres = 0;
else { else {
ath_rc_priv->state[rate].rssi_thres = ath_rc_priv->state[rate].rssi_thres =
ath_rc_priv->state[rate+1]. ath_rc_priv->state[rate+1].rssi_thres -
rssi_thres - rate_table->info[rate].rssi_ack_deltamin;
rate_table->info[rate].
rssi_ack_deltamin;
} }
if (ath_rc_priv->state[rate].rssi_thres < if (ath_rc_priv->state[rate].rssi_thres <
rate_table->info[rate]. rate_table->info[rate].rssi_ack_validmin) {
rssi_ack_validmin) {
ath_rc_priv->state[rate].rssi_thres = ath_rc_priv->state[rate].rssi_thres =
rate_table->info[rate]. rate_table->info[rate].rssi_ack_validmin;
rssi_ack_validmin;
} }
} }
} }
...@@ -1202,8 +1190,9 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1202,8 +1190,9 @@ static void ath_rc_update_ht(struct ath_softc *sc,
} }
/* Maintain monotonicity for rates above the current rate */ /* Maintain monotonicity for rates above the current rate */
for (rate = tx_rate; rate < ath_rc_priv->rate_table_size - 1; rate++) { for (rate = tx_rate; rate < size - 1; rate++) {
if (ath_rc_priv->state[rate+1].per < ath_rc_priv->state[rate].per) if (ath_rc_priv->state[rate+1].per <
ath_rc_priv->state[rate].per)
ath_rc_priv->state[rate+1].per = ath_rc_priv->state[rate+1].per =
ath_rc_priv->state[rate].per; ath_rc_priv->state[rate].per;
} }
...@@ -1213,7 +1202,7 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1213,7 +1202,7 @@ static void ath_rc_update_ht(struct ath_softc *sc,
if (now_msec - ath_rc_priv->rssi_down_time >= if (now_msec - ath_rc_priv->rssi_down_time >=
rate_table->rssi_reduce_interval) { rate_table->rssi_reduce_interval) {
for (rate = 0; rate < ath_rc_priv->rate_table_size; rate++) { for (rate = 0; rate < size; rate++) {
if (ath_rc_priv->state[rate].rssi_thres > if (ath_rc_priv->state[rate].rssi_thres >
rate_table->info[rate].rssi_ack_validmin) rate_table->info[rate].rssi_ack_validmin)
ath_rc_priv->state[rate].rssi_thres -= 1; ath_rc_priv->state[rate].rssi_thres -= 1;
...@@ -1225,13 +1214,33 @@ static void ath_rc_update_ht(struct ath_softc *sc, ...@@ -1225,13 +1214,33 @@ static void ath_rc_update_ht(struct ath_softc *sc,
* and PER (different for CCK and OFDM). */ * and PER (different for CCK and OFDM). */
if (now_msec - ath_rc_priv->per_down_time >= if (now_msec - ath_rc_priv->per_down_time >=
rate_table->rssi_reduce_interval) { rate_table->rssi_reduce_interval) {
for (rate = 0; rate < ath_rc_priv->rate_table_size; rate++) { for (rate = 0; rate < size; rate++) {
ath_rc_priv->state[rate].per = ath_rc_priv->state[rate].per =
7 * ath_rc_priv->state[rate].per / 8; 7 * ath_rc_priv->state[rate].per / 8;
} }
ath_rc_priv->per_down_time = now_msec; ath_rc_priv->per_down_time = now_msec;
} }
#undef CHK_RSSI
}
static int ath_rc_get_rateindex(struct ath_rate_table *rate_table,
struct ieee80211_tx_rate *rate)
{
int rix;
if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
(rate->flags & IEEE80211_TX_RC_SHORT_GI))
rix = rate_table->info[rate->idx].ht_index;
else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
rix = rate_table->info[rate->idx].sgi_index;
else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
rix = rate_table->info[rate->idx].cw40index;
else
rix = rate_table->info[rate->idx].base_index;
return rix;
} }
static void ath_rc_tx_status(struct ath_softc *sc, static void ath_rc_tx_status(struct ath_softc *sc,
...@@ -1243,7 +1252,7 @@ static void ath_rc_tx_status(struct ath_softc *sc, ...@@ -1243,7 +1252,7 @@ static void ath_rc_tx_status(struct ath_softc *sc,
struct ath_rate_table *rate_table; struct ath_rate_table *rate_table;
struct ieee80211_tx_rate *rates = tx_info->status.rates; struct ieee80211_tx_rate *rates = tx_info->status.rates;
u8 flags; u8 flags;
u32 series = 0, rix; u32 i = 0, rix;
rate_table = sc->hw_rate_table[sc->sc_curmode]; rate_table = sc->hw_rate_table[sc->sc_curmode];
...@@ -1253,32 +1262,22 @@ static void ath_rc_tx_status(struct ath_softc *sc, ...@@ -1253,32 +1262,22 @@ static void ath_rc_tx_status(struct ath_softc *sc,
*/ */
if (final_ts_idx != 0) { if (final_ts_idx != 0) {
/* Process intermediate rates that failed.*/ /* Process intermediate rates that failed.*/
for (series = 0; series < final_ts_idx ; series++) { for (i = 0; i < final_ts_idx ; i++) {
if (rates[series].count != 0 && (rates[series].idx >= 0)) { if (rates[i].count != 0 && (rates[i].idx >= 0)) {
flags = rates[series].flags; flags = rates[i].flags;
/* If HT40 and we have switched mode from /* If HT40 and we have switched mode from
* 40 to 20 => don't update */ * 40 to 20 => don't update */
if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
(ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG))
return; return;
if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && rix = ath_rc_get_rateindex(rate_table, &rates[i]);
(flags & IEEE80211_TX_RC_SHORT_GI))
rix = rate_table->info[
rates[series].idx].ht_index;
else if (flags & IEEE80211_TX_RC_SHORT_GI)
rix = rate_table->info[
rates[series].idx].sgi_index;
else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
rix = rate_table->info[
rates[series].idx].cw40index;
else
rix = rate_table->info[
rates[series].idx].base_index;
ath_rc_update_ht(sc, ath_rc_priv, ath_rc_update_ht(sc, ath_rc_priv,
tx_info_priv, rix, tx_info_priv, rix,
xretries ? 1 : 2, xretries ? 1 : 2,
rates[series].count); rates[i].count);
} }
} }
} else { } else {
...@@ -1292,24 +1291,17 @@ static void ath_rc_tx_status(struct ath_softc *sc, ...@@ -1292,24 +1291,17 @@ static void ath_rc_tx_status(struct ath_softc *sc,
xretries = 2; xretries = 2;
} }
flags = rates[series].flags; flags = rates[i].flags;
/* If HT40 and we have switched mode from 40 to 20 => don't update */ /* If HT40 and we have switched mode from 40 to 20 => don't update */
if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
(ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) { (ath_rc_priv->rc_phy_mode != WLAN_RC_40_FLAG)) {
return; return;
} }
if ((flags & IEEE80211_TX_RC_40_MHZ_WIDTH) && (flags & IEEE80211_TX_RC_SHORT_GI)) rix = ath_rc_get_rateindex(rate_table, &rates[i]);
rix = rate_table->info[rates[series].idx].ht_index;
else if (flags & IEEE80211_TX_RC_SHORT_GI)
rix = rate_table->info[rates[series].idx].sgi_index;
else if (flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
rix = rate_table->info[rates[series].idx].cw40index;
else
rix = rate_table->info[rates[series].idx].base_index;
ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix, ath_rc_update_ht(sc, ath_rc_priv, tx_info_priv, rix,
xretries, long_retry); xretries, long_retry);
} }
static void ath_rc_init(struct ath_softc *sc, static void ath_rc_init(struct ath_softc *sc,
...@@ -1362,14 +1354,14 @@ static void ath_rc_init(struct ath_softc *sc, ...@@ -1362,14 +1354,14 @@ static void ath_rc_init(struct ath_softc *sc,
if (!rateset->rs_nrates) { if (!rateset->rs_nrates) {
/* No working rate, just initialize valid rates */ /* No working rate, just initialize valid rates */
hi = ath_rc_sib_init_validrates(ath_rc_priv, rate_table, hi = ath_rc_init_validrates(ath_rc_priv, rate_table,
ath_rc_priv->ht_cap); ath_rc_priv->ht_cap);
} else { } else {
/* Use intersection of working rates and valid rates */ /* Use intersection of working rates and valid rates */
hi = ath_rc_sib_setvalid_rates(ath_rc_priv, rate_table, hi = ath_rc_setvalid_rates(ath_rc_priv, rate_table,
rateset, ath_rc_priv->ht_cap); rateset, ath_rc_priv->ht_cap);
if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) { if (ath_rc_priv->ht_cap & WLAN_RC_HT_FLAG) {
hthi = ath_rc_sib_setvalid_htrates(ath_rc_priv, hthi = ath_rc_setvalid_htrates(ath_rc_priv,
rate_table, rate_table,
ht_mcs, ht_mcs,
ath_rc_priv->ht_cap); ath_rc_priv->ht_cap);
......
...@@ -27,6 +27,11 @@ struct ath_softc; ...@@ -27,6 +27,11 @@ struct ath_softc;
#define RATE_TABLE_SIZE 64 #define RATE_TABLE_SIZE 64
#define MAX_TX_RATE_PHY 48 #define MAX_TX_RATE_PHY 48
/* VALID_ALL - valid for 20/40/Legacy,
* VALID - Legacy only,
* VALID_20 - HT 20 only,
* VALID_40 - HT 40 only */
#define INVALID 0x0 #define INVALID 0x0
#define VALID 0x1 #define VALID 0x1
#define VALID_20 0x2 #define VALID_20 0x2
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment