aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k/rc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ath/ath9k/rc.c')
-rw-r--r--drivers/net/wireless/ath/ath9k/rc.c138
1 files changed, 71 insertions, 67 deletions
diff --git a/drivers/net/wireless/ath/ath9k/rc.c b/drivers/net/wireless/ath/ath9k/rc.c
index 9d965e37b00..08bb4553270 100644
--- a/drivers/net/wireless/ath/ath9k/rc.c
+++ b/drivers/net/wireless/ath/ath9k/rc.c
@@ -16,6 +16,7 @@
*/
#include <linux/slab.h>
+#include <linux/export.h>
#include "ath9k.h"
@@ -379,7 +380,30 @@ static const struct ath_rate_table ar5416_11g_ratetable = {
};
static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
- struct ieee80211_tx_rate *rate);
+ struct ieee80211_tx_rate *rate)
+{
+ int rix = 0, i = 0;
+ static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
+
+ if (!(rate->flags & IEEE80211_TX_RC_MCS))
+ return rate->idx;
+
+ while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) {
+ rix++; i++;
+ }
+
+ rix += rate->idx + rate_table->mcs_start;
+
+ if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
+ (rate->flags & IEEE80211_TX_RC_SHORT_GI))
+ rix = rate_table->info[rix].ht_index;
+ else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
+ rix = rate_table->info[rix].sgi_index;
+ else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
+ rix = rate_table->info[rix].cw40index;
+
+ return rix;
+}
static void ath_rc_sort_validrates(const struct ath_rate_table *rate_table,
struct ath_rate_priv *ath_rc_priv)
@@ -533,7 +557,7 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
[valid_rate_count] = j;
ath_rc_priv->valid_phy_ratecnt[phy] += 1;
ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1);
- hi = A_MAX(hi, j);
+ hi = max(hi, j);
}
}
}
@@ -543,10 +567,8 @@ static u8 ath_rc_setvalid_rates(struct ath_rate_priv *ath_rc_priv,
static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
const struct ath_rate_table *rate_table,
- u8 *mcs_set, u32 capflag)
+ struct ath_rateset *rateset, u32 capflag)
{
- struct ath_rateset *rateset = (struct ath_rateset *)mcs_set;
-
u8 i, j, hi = 0;
/* Use intersection of working rates and valid rates */
@@ -569,7 +591,7 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
[ath_rc_priv->valid_phy_ratecnt[phy]] = j;
ath_rc_priv->valid_phy_ratecnt[phy] += 1;
ath_rc_set_valid_rate_idx(ath_rc_priv, j, 1);
- hi = A_MAX(hi, j);
+ hi = max(hi, j);
}
}
@@ -580,7 +602,8 @@ static u8 ath_rc_setvalid_htrates(struct ath_rate_priv *ath_rc_priv,
static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
const struct ath_rate_table *rate_table,
- int *is_probing)
+ int *is_probing,
+ bool legacy)
{
u32 best_thruput, this_thruput, now_msec;
u8 rate, next_rate, best_rate, maxindex, minindex;
@@ -601,6 +624,8 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
u8 per_thres;
rate = ath_rc_priv->valid_rate_index[index];
+ if (legacy && !(rate_table->info[rate].rate_flags & RC_LEGACY))
+ continue;
if (rate > ath_rc_priv->rate_max_phy)
continue;
@@ -667,7 +692,7 @@ static u8 ath_rc_get_highest_rix(struct ath_softc *sc,
return rate;
/* This should not happen */
- WARN_ON(1);
+ WARN_ON_ONCE(1);
rate = ath_rc_priv->valid_rate_index[0];
@@ -723,7 +748,8 @@ static void ath_rc_rate_set_rtscts(struct ath_softc *sc,
* If 802.11g protection is enabled, determine whether to use RTS/CTS or
* just CTS. Note that this is only done for OFDM/HT unicast frames.
*/
- if ((sc->sc_flags & SC_OP_PROTECT_ENABLE) &&
+ if ((tx_info->control.vif &&
+ tx_info->control.vif->bss_conf.use_cts_prot) &&
(rate_table->info[rix].phy == WLAN_RC_PHY_OFDM ||
WLAN_RC_PHY_HT(rate_table->info[rix].phy))) {
rates[0].flags |= IEEE80211_TX_RC_USE_CTS_PROTECT;
@@ -744,7 +770,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
struct ieee80211_tx_rate *rates = tx_info->control.rates;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
__le16 fc = hdr->frame_control;
- u8 try_per_rate, i = 0, rix;
+ u8 try_per_rate, i = 0, rix, high_rix;
int is_probe = 0;
if (rate_control_send_low(sta, priv_sta, txrc))
@@ -763,7 +789,9 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
try_per_rate = 4;
rate_table = ath_rc_priv->rate_table;
- rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table, &is_probe);
+ rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table,
+ &is_probe, false);
+ high_rix = rix;
/*
* If we're in HT mode and both us and our peer supports LDPC.
@@ -799,10 +827,7 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
}
/* Fill in the other rates for multirate retry */
- for ( ; i < 4; i++) {
- /* Use twice the number of tries for the last MRR segment. */
- if (i + 1 == 4)
- try_per_rate = 8;
+ for ( ; i < 3; i++) {
ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
/* All other rates in the series have RTS enabled */
@@ -810,6 +835,24 @@ static void ath_get_rate(void *priv, struct ieee80211_sta *sta, void *priv_sta,
try_per_rate, rix, 1);
}
+ /* Use twice the number of tries for the last MRR segment. */
+ try_per_rate = 8;
+
+ /*
+ * Use a legacy rate as last retry to ensure that the frame
+ * is tried in both MCS and legacy rates.
+ */
+ if ((rates[2].flags & IEEE80211_TX_RC_MCS) &&
+ (!(tx_info->flags & IEEE80211_TX_CTL_AMPDU) ||
+ (ath_rc_priv->per[high_rix] > 45)))
+ rix = ath_rc_get_highest_rix(sc, ath_rc_priv, rate_table,
+ &is_probe, true);
+ else
+ ath_rc_get_lower_rix(rate_table, ath_rc_priv, rix, &rix);
+
+ /* All other rates in the series have RTS enabled */
+ ath_rc_rate_set_series(rate_table, &rates[i], txrc,
+ try_per_rate, rix, 1);
/*
* NB:Change rate series to enable aggregation when operating
* at lower MCS rates. When first rate in series is MCS2
@@ -1080,31 +1123,6 @@ static void ath_rc_update_ht(struct ath_softc *sc,
}
-static int ath_rc_get_rateindex(const struct ath_rate_table *rate_table,
- struct ieee80211_tx_rate *rate)
-{
- int rix = 0, i = 0;
- static const int mcs_rix_off[] = { 7, 15, 20, 21, 22, 23 };
-
- if (!(rate->flags & IEEE80211_TX_RC_MCS))
- return rate->idx;
-
- while (i < ARRAY_SIZE(mcs_rix_off) && rate->idx > mcs_rix_off[i]) {
- rix++; i++;
- }
-
- rix += rate->idx + rate_table->mcs_start;
-
- if ((rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH) &&
- (rate->flags & IEEE80211_TX_RC_SHORT_GI))
- rix = rate_table->info[rix].ht_index;
- else if (rate->flags & IEEE80211_TX_RC_SHORT_GI)
- rix = rate_table->info[rix].sgi_index;
- else if (rate->flags & IEEE80211_TX_RC_40_MHZ_WIDTH)
- rix = rate_table->info[rix].cw40index;
-
- return rix;
-}
static void ath_rc_tx_status(struct ath_softc *sc,
struct ath_rate_priv *ath_rc_priv,
@@ -1180,7 +1198,7 @@ struct ath_rate_table *ath_choose_rate_table(struct ath_softc *sc,
return &ar5416_11na_ratetable;
return &ar5416_11a_ratetable;
default:
- ath_dbg(common, ATH_DBG_CONFIG, "Invalid band\n");
+ ath_dbg(common, CONFIG, "Invalid band\n");
return NULL;
}
}
@@ -1193,7 +1211,7 @@ static void ath_rc_init(struct ath_softc *sc,
{
struct ath_rateset *rateset = &ath_rc_priv->neg_rates;
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- u8 *ht_mcs = (u8 *)&ath_rc_priv->neg_ht_rates;
+ struct ath_rateset *ht_mcs = &ath_rc_priv->neg_ht_rates;
u8 i, j, k, hi = 0, hthi = 0;
/* Initial rate table size. Will change depending
@@ -1209,7 +1227,7 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_init_valid_rate_idx(ath_rc_priv);
for (i = 0; i < WLAN_RC_PHY_MAX; i++) {
- for (j = 0; j < MAX_TX_RATE_PHY; j++)
+ for (j = 0; j < RATE_TABLE_SIZE; j++)
ath_rc_priv->valid_phy_rateidx[i][j] = 0;
ath_rc_priv->valid_phy_ratecnt[i] = 0;
}
@@ -1228,7 +1246,7 @@ static void ath_rc_init(struct ath_softc *sc,
ht_mcs,
ath_rc_priv->ht_cap);
}
- hi = A_MAX(hi, hthi);
+ hi = max(hi, hthi);
}
ath_rc_priv->rate_table_size = hi + 1;
@@ -1257,8 +1275,7 @@ static void ath_rc_init(struct ath_softc *sc,
ath_rc_priv->valid_rate_index[k-1];
ath_rc_priv->rate_table = rate_table;
- ath_dbg(common, ATH_DBG_CONFIG,
- "RC Initialized with capabilities: 0x%x\n",
+ ath_dbg(common, CONFIG, "RC Initialized with capabilities: 0x%x\n",
ath_rc_priv->ht_cap);
}
@@ -1282,12 +1299,13 @@ static u8 ath_rc_build_ht_caps(struct ath_softc *sc, struct ieee80211_sta *sta,
return caps;
}
-static bool ath_tx_aggr_check(struct ath_softc *sc, struct ath_node *an,
+static bool ath_tx_aggr_check(struct ath_softc *sc, struct ieee80211_sta *sta,
u8 tidno)
{
+ struct ath_node *an = (struct ath_node *)sta->drv_priv;
struct ath_atx_tid *txtid;
- if (!(sc->sc_flags & SC_OP_TXAGGR))
+ if (!sta->ht_cap.ht_supported)
return false;
txtid = ATH_AN_2_TID(an, tidno);
@@ -1346,12 +1364,6 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
if (tx_info->flags & IEEE80211_TX_STAT_TX_FILTERED)
return;
- if (!(tx_info->flags & IEEE80211_TX_STAT_AMPDU)) {
- tx_info->status.ampdu_ack_len =
- (tx_info->flags & IEEE80211_TX_STAT_ACK ? 1 : 0);
- tx_info->status.ampdu_len = 1;
- }
-
if (!(tx_info->flags & IEEE80211_TX_STAT_ACK))
tx_status = 1;
@@ -1364,13 +1376,11 @@ static void ath_tx_status(void *priv, struct ieee80211_supported_band *sband,
if (ieee80211_is_data_qos(fc) &&
skb_get_queue_mapping(skb) != IEEE80211_AC_VO) {
u8 *qc, tid;
- struct ath_node *an;
qc = ieee80211_get_qos_ctl(hdr);
tid = qc[0] & 0xf;
- an = (struct ath_node *)sta->drv_priv;
- if(ath_tx_aggr_check(sc, an, tid))
+ if(ath_tx_aggr_check(sc, sta, tid))
ieee80211_start_tx_ba_session(sta, tid, 0);
}
}
@@ -1461,7 +1471,7 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
oper_cw40, oper_sgi);
ath_rc_init(sc, priv_sta, sband, sta, rate_table);
- ath_dbg(ath9k_hw_common(sc->sc_ah), ATH_DBG_CONFIG,
+ ath_dbg(ath9k_hw_common(sc->sc_ah), CONFIG,
"Operating HT Bandwidth changed to: %d\n",
sc->hw->conf.channel_type);
}
@@ -1470,12 +1480,6 @@ static void ath_rate_update(void *priv, struct ieee80211_supported_band *sband,
#ifdef CONFIG_ATH9K_DEBUGFS
-static int ath9k_debugfs_open(struct inode *inode, struct file *file)
-{
- file->private_data = inode->i_private;
- return 0;
-}
-
static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
size_t count, loff_t *ppos)
{
@@ -1488,7 +1492,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
if (rc->rate_table == NULL)
return 0;
- max = 80 + rc->rate_table->rate_cnt * 1024 + 1;
+ max = 80 + rc->rate_table_size * 1024 + 1;
buf = kmalloc(max, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
@@ -1498,7 +1502,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
"HT", "MCS", "Rate",
"Success", "Retries", "XRetries", "PER");
- for (i = 0; i < rc->rate_table->rate_cnt; i++) {
+ for (i = 0; i < rc->rate_table_size; i++) {
u32 ratekbps = rc->rate_table->info[i].ratekbps;
struct ath_rc_stats *stats = &rc->rcstats[i];
char mcs[5];
@@ -1543,7 +1547,7 @@ static ssize_t read_file_rcstat(struct file *file, char __user *user_buf,
static const struct file_operations fops_rcstat = {
.read = read_file_rcstat,
- .open = ath9k_debugfs_open,
+ .open = simple_open,
.owner = THIS_MODULE
};