|
@@ -351,20 +351,12 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
|
|
|
struct sk_buff *skb,
|
|
|
struct ieee80211_sta *sta,
|
|
|
struct iwl_lq_sta *lq_sta);
|
|
|
-static void rs_fill_link_cmd(struct iwl_mvm *mvm,
|
|
|
- struct ieee80211_sta *sta,
|
|
|
- struct iwl_lq_sta *lq_sta, u32 rate_n_flags);
|
|
|
+static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
|
|
|
+ struct ieee80211_sta *sta,
|
|
|
+ struct iwl_lq_sta *lq_sta,
|
|
|
+ const struct rs_rate *initial_rate);
|
|
|
static void rs_stay_in_table(struct iwl_lq_sta *lq_sta, bool force_search);
|
|
|
|
|
|
-#ifdef CONFIG_MAC80211_DEBUGFS
|
|
|
-static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
|
|
- u32 *rate_n_flags);
|
|
|
-#else
|
|
|
-static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
|
|
- u32 *rate_n_flags)
|
|
|
-{}
|
|
|
-#endif
|
|
|
-
|
|
|
/**
|
|
|
* The following tables contain the expected throughput metrics for all rates
|
|
|
*
|
|
@@ -634,7 +626,7 @@ static int rs_collect_tx_data(struct iwl_scale_tbl_info *tbl,
|
|
|
|
|
|
/* Convert rs_rate object into ucode rate bitmask */
|
|
|
static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
|
|
|
- struct rs_rate *rate)
|
|
|
+ struct rs_rate *rate)
|
|
|
{
|
|
|
u32 ucode_rate = 0;
|
|
|
int index = rate->index;
|
|
@@ -761,8 +753,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
|
|
|
|
|
|
/* switch to another antenna/antennas and return 1 */
|
|
|
/* if no other valid antenna found, return 0 */
|
|
|
-static int rs_toggle_antenna(u32 valid_ant, u32 *ucode_rate,
|
|
|
- struct rs_rate *rate)
|
|
|
+static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate)
|
|
|
{
|
|
|
u8 new_ant_type;
|
|
|
|
|
@@ -783,9 +774,6 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *ucode_rate,
|
|
|
|
|
|
rate->ant = new_ant_type;
|
|
|
|
|
|
- /* TODO: get rid of ucode_rate here. This should handle only rs_rate */
|
|
|
- *ucode_rate &= ~RATE_MCS_ANT_ABC_MSK;
|
|
|
- *ucode_rate |= new_ant_type << RATE_MCS_ANT_POS;
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
@@ -859,9 +847,9 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
|
|
|
return (high << 8) | low;
|
|
|
}
|
|
|
|
|
|
-static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
|
|
|
- struct rs_rate *rate,
|
|
|
- u8 scale_index, u8 ht_possible)
|
|
|
+static void rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
|
|
|
+ struct rs_rate *rate,
|
|
|
+ u8 scale_index, u8 ht_possible)
|
|
|
{
|
|
|
s32 low;
|
|
|
u16 rate_mask;
|
|
@@ -917,7 +905,6 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
|
|
|
|
|
|
out:
|
|
|
rate->index = low;
|
|
|
- return ucode_rate_from_rs_rate(lq_sta->drv, rate);
|
|
|
}
|
|
|
|
|
|
/* Simple function to compare two rate scale table types */
|
|
@@ -1447,10 +1434,7 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm,
|
|
|
struct iwl_lq_sta *lq_sta,
|
|
|
struct rs_rate *rate)
|
|
|
{
|
|
|
- u32 ucode_rate;
|
|
|
-
|
|
|
- ucode_rate = ucode_rate_from_rs_rate(mvm, rate);
|
|
|
- rs_fill_link_cmd(mvm, sta, lq_sta, ucode_rate);
|
|
|
+ rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
|
|
|
iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
|
|
|
}
|
|
|
|
|
@@ -1610,10 +1594,6 @@ static int rs_switch_to_column(struct iwl_mvm *mvm,
|
|
|
rate->index = rate_idx;
|
|
|
}
|
|
|
|
|
|
- /* TODO: remove current_rate and keep using rs_rate all the way until
|
|
|
- * we need to fill in the rs_table in the LQ command
|
|
|
- */
|
|
|
- search_tbl->current_rate = ucode_rate_from_rs_rate(mvm, rate);
|
|
|
IWL_DEBUG_RATE(mvm, "Switched to column %d: Index %d\n",
|
|
|
col_id, rate->index);
|
|
|
|
|
@@ -1730,9 +1710,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
|
|
|
rate->type = LQ_NONE;
|
|
|
lq_sta->search_better_tbl = 0;
|
|
|
tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
|
|
|
- /* get "active" rate info */
|
|
|
- index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
|
|
|
- tbl->rate.index = index;
|
|
|
rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
|
|
|
}
|
|
|
return;
|
|
@@ -1823,7 +1800,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
|
|
|
tbl = &(lq_sta->lq_info[active_tbl]);
|
|
|
|
|
|
/* Revert to "active" rate and throughput info */
|
|
|
- index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
|
|
|
+ index = tbl->rate.index;
|
|
|
current_tpt = lq_sta->last_tpt;
|
|
|
|
|
|
/* Need to set up a new rate table in uCode */
|
|
@@ -2029,11 +2006,11 @@ lq_update:
|
|
|
rs_rate_scale_clear_window(&(tbl->win[i]));
|
|
|
|
|
|
/* Use new "search" start rate */
|
|
|
- index = iwl_hwrate_to_plcp_idx(tbl->current_rate);
|
|
|
+ index = tbl->rate.index;
|
|
|
|
|
|
rs_dump_rate(mvm, &tbl->rate,
|
|
|
"Switch to SEARCH TABLE:");
|
|
|
- rs_fill_link_cmd(mvm, sta, lq_sta, tbl->current_rate);
|
|
|
+ rs_fill_lq_cmd(mvm, sta, lq_sta, &tbl->rate);
|
|
|
iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
|
|
|
} else {
|
|
|
done_search = 1;
|
|
@@ -2071,8 +2048,6 @@ lq_update:
|
|
|
}
|
|
|
|
|
|
out:
|
|
|
- tbl->rate.index = index;
|
|
|
- tbl->current_rate = ucode_rate_from_rs_rate(mvm, &tbl->rate);
|
|
|
lq_sta->last_txrate_idx = index;
|
|
|
}
|
|
|
|
|
@@ -2099,7 +2074,6 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
|
|
|
struct iwl_scale_tbl_info *tbl;
|
|
|
struct rs_rate *rate;
|
|
|
int i;
|
|
|
- u32 ucode_rate;
|
|
|
u8 active_tbl = 0;
|
|
|
u8 valid_tx_ant;
|
|
|
|
|
@@ -2130,9 +2104,6 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
|
|
|
else
|
|
|
rate->type = LQ_LEGACY_G;
|
|
|
|
|
|
- ucode_rate = ucode_rate_from_rs_rate(mvm, rate);
|
|
|
- tbl->current_rate = ucode_rate;
|
|
|
-
|
|
|
WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B);
|
|
|
if (rate->ant == ANT_A)
|
|
|
tbl->column = RS_COLUMN_LEGACY_ANT_A;
|
|
@@ -2140,7 +2111,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
|
|
|
tbl->column = RS_COLUMN_LEGACY_ANT_B;
|
|
|
|
|
|
rs_set_expected_tpt_table(lq_sta, tbl);
|
|
|
- rs_fill_link_cmd(NULL, NULL, lq_sta, ucode_rate);
|
|
|
+ rs_fill_lq_cmd(NULL, NULL, lq_sta, rate);
|
|
|
/* TODO restore station should remember the lq cmd */
|
|
|
iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init);
|
|
|
}
|
|
@@ -2371,9 +2342,32 @@ static void rs_rate_update(void *mvm_r,
|
|
|
iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
|
|
|
}
|
|
|
|
|
|
-static void rs_fill_link_cmd(struct iwl_mvm *mvm,
|
|
|
- struct ieee80211_sta *sta,
|
|
|
- struct iwl_lq_sta *lq_sta, u32 new_rate)
|
|
|
+#ifdef CONFIG_MAC80211_DEBUGFS
|
|
|
+static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
|
|
|
+ struct iwl_lq_cmd *lq_cmd,
|
|
|
+ enum ieee80211_band band,
|
|
|
+ u32 ucode_rate)
|
|
|
+{
|
|
|
+ struct rs_rate rate;
|
|
|
+ int i;
|
|
|
+ int num_rates = ARRAY_SIZE(lq_cmd->rs_table);
|
|
|
+ __le32 ucode_rate_le32 = cpu_to_le32(ucode_rate);
|
|
|
+
|
|
|
+ for (i = 0; i < num_rates; i++)
|
|
|
+ lq_cmd->rs_table[i] = ucode_rate_le32;
|
|
|
+
|
|
|
+ rs_rate_from_ucode_rate(ucode_rate, band, &rate);
|
|
|
+
|
|
|
+ if (is_mimo(&rate))
|
|
|
+ lq_cmd->mimo_delim = num_rates - 1;
|
|
|
+ else
|
|
|
+ lq_cmd->mimo_delim = 0;
|
|
|
+}
|
|
|
+#endif /* CONFIG_MAC80211_DEBUGFS */
|
|
|
+
|
|
|
+static void rs_build_rates_table(struct iwl_mvm *mvm,
|
|
|
+ struct iwl_lq_sta *lq_sta,
|
|
|
+ const struct rs_rate *initial_rate)
|
|
|
{
|
|
|
struct rs_rate rate;
|
|
|
int index = 0;
|
|
@@ -2383,10 +2377,13 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
|
|
|
u8 valid_tx_ant = 0;
|
|
|
struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
|
|
|
|
|
|
- /* Override starting rate (index 0) if needed for debug purposes */
|
|
|
- rs_dbgfs_set_mcs(lq_sta, &new_rate);
|
|
|
+ memcpy(&rate, initial_rate, sizeof(struct rs_rate));
|
|
|
+
|
|
|
+ lq_cmd->mimo_delim = is_mimo(&rate) ? 1 : 0;
|
|
|
|
|
|
- rs_rate_from_ucode_rate(new_rate, lq_sta->band, &rate);
|
|
|
+ /* Fill 1st table entry (index 0) */
|
|
|
+ lq_cmd->rs_table[index] = cpu_to_le32(
|
|
|
+ ucode_rate_from_rs_rate(mvm, &rate));
|
|
|
|
|
|
/* How many times should we repeat the initial rate? */
|
|
|
if (is_legacy(&rate)) {
|
|
@@ -2397,15 +2394,6 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
|
|
|
LINK_QUAL_AGG_DISABLE_START_DEF - 1);
|
|
|
}
|
|
|
|
|
|
- lq_cmd->mimo_delim = is_mimo(&rate) ? 1 : 0;
|
|
|
-
|
|
|
- /* Fill 1st table entry (index 0) */
|
|
|
- lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
|
|
|
-
|
|
|
- if (num_of_ant(rate.ant) == 1)
|
|
|
- lq_cmd->single_stream_ant_msk = rate.ant;
|
|
|
- /* otherwise we don't modify the existing value */
|
|
|
-
|
|
|
index++;
|
|
|
repeat_rate--;
|
|
|
if (mvm)
|
|
@@ -2421,23 +2409,17 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
|
|
|
if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
|
|
|
ant_toggle_cnt++;
|
|
|
else if (mvm &&
|
|
|
- rs_toggle_antenna(valid_tx_ant,
|
|
|
- &new_rate, &rate))
|
|
|
+ rs_toggle_antenna(valid_tx_ant, &rate))
|
|
|
ant_toggle_cnt = 1;
|
|
|
}
|
|
|
|
|
|
- /* Override next rate if needed for debug purposes */
|
|
|
- rs_dbgfs_set_mcs(lq_sta, &new_rate);
|
|
|
-
|
|
|
/* Fill next table entry */
|
|
|
- lq_cmd->rs_table[index] =
|
|
|
- cpu_to_le32(new_rate);
|
|
|
+ lq_cmd->rs_table[index] = cpu_to_le32(
|
|
|
+ ucode_rate_from_rs_rate(mvm, &rate));
|
|
|
repeat_rate--;
|
|
|
index++;
|
|
|
}
|
|
|
|
|
|
- rs_rate_from_ucode_rate(new_rate, lq_sta->band, &rate);
|
|
|
-
|
|
|
/* Indicate to uCode which entries might be MIMO.
|
|
|
* If initial rate was MIMO, this will finally end up
|
|
|
* as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */
|
|
@@ -2445,16 +2427,14 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
|
|
|
lq_cmd->mimo_delim = index;
|
|
|
|
|
|
/* Get next rate */
|
|
|
- new_rate = rs_get_lower_rate(lq_sta, &rate, rate.index,
|
|
|
- use_ht_possible);
|
|
|
+ rs_get_lower_rate(lq_sta, &rate, rate.index, use_ht_possible);
|
|
|
|
|
|
/* How many times should we repeat the next rate? */
|
|
|
if (is_legacy(&rate)) {
|
|
|
if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
|
|
|
ant_toggle_cnt++;
|
|
|
else if (mvm &&
|
|
|
- rs_toggle_antenna(valid_tx_ant,
|
|
|
- &new_rate, &rate))
|
|
|
+ rs_toggle_antenna(valid_tx_ant, &rate))
|
|
|
ant_toggle_cnt = 1;
|
|
|
|
|
|
repeat_rate = IWL_NUMBER_TRY;
|
|
@@ -2468,15 +2448,36 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
|
|
|
*/
|
|
|
use_ht_possible = 0;
|
|
|
|
|
|
- /* Override next rate if needed for debug purposes */
|
|
|
- rs_dbgfs_set_mcs(lq_sta, &new_rate);
|
|
|
-
|
|
|
/* Fill next table entry */
|
|
|
- lq_cmd->rs_table[index] = cpu_to_le32(new_rate);
|
|
|
+ lq_cmd->rs_table[index] = cpu_to_le32(
|
|
|
+ ucode_rate_from_rs_rate(mvm, &rate));
|
|
|
|
|
|
index++;
|
|
|
repeat_rate--;
|
|
|
}
|
|
|
+}
|
|
|
+
|
|
|
+static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
|
|
|
+ struct ieee80211_sta *sta,
|
|
|
+ struct iwl_lq_sta *lq_sta,
|
|
|
+ const struct rs_rate *initial_rate)
|
|
|
+{
|
|
|
+ struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
|
|
|
+ u8 ant = initial_rate->ant;
|
|
|
+
|
|
|
+#ifdef CONFIG_MAC80211_DEBUGFS
|
|
|
+ if (lq_sta->dbg_fixed_rate) {
|
|
|
+ rs_build_rates_table_from_fixed(mvm, lq_cmd,
|
|
|
+ lq_sta->band,
|
|
|
+ lq_sta->dbg_fixed_rate);
|
|
|
+ ant = (lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK) >>
|
|
|
+ RATE_MCS_ANT_POS;
|
|
|
+ } else
|
|
|
+#endif
|
|
|
+ rs_build_rates_table(mvm, lq_sta, initial_rate);
|
|
|
+
|
|
|
+ if (num_of_ant(ant) == 1)
|
|
|
+ lq_cmd->single_stream_ant_msk = ant;
|
|
|
|
|
|
lq_cmd->agg_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
|
|
|
lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_DEF;
|
|
@@ -2510,31 +2511,6 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta,
|
|
|
}
|
|
|
|
|
|
#ifdef CONFIG_MAC80211_DEBUGFS
|
|
|
-static void rs_dbgfs_set_mcs(struct iwl_lq_sta *lq_sta,
|
|
|
- u32 *rate_n_flags)
|
|
|
-{
|
|
|
- struct iwl_mvm *mvm;
|
|
|
- u8 valid_tx_ant;
|
|
|
- u8 ant_sel_tx;
|
|
|
-
|
|
|
- mvm = lq_sta->drv;
|
|
|
- valid_tx_ant = iwl_fw_valid_tx_ant(mvm->fw);
|
|
|
- if (lq_sta->dbg_fixed_rate) {
|
|
|
- ant_sel_tx =
|
|
|
- ((lq_sta->dbg_fixed_rate & RATE_MCS_ANT_ABC_MSK)
|
|
|
- >> RATE_MCS_ANT_POS);
|
|
|
- if ((valid_tx_ant & ant_sel_tx) == ant_sel_tx) {
|
|
|
- *rate_n_flags = lq_sta->dbg_fixed_rate;
|
|
|
- } else {
|
|
|
- lq_sta->dbg_fixed_rate = 0;
|
|
|
- IWL_ERR(mvm,
|
|
|
- "Invalid antenna selection 0x%X, Valid is 0x%X\n",
|
|
|
- ant_sel_tx, valid_tx_ant);
|
|
|
- IWL_DEBUG_RATE(mvm, "Fixed rate OFF\n");
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
static int rs_pretty_print_rate(char *buf, const u32 rate)
|
|
|
{
|
|
|
|
|
@@ -2605,7 +2581,10 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
|
|
|
lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
|
|
|
|
|
|
if (lq_sta->dbg_fixed_rate) {
|
|
|
- rs_fill_link_cmd(NULL, NULL, lq_sta, lq_sta->dbg_fixed_rate);
|
|
|
+ struct rs_rate rate;
|
|
|
+ rs_rate_from_ucode_rate(lq_sta->dbg_fixed_rate,
|
|
|
+ lq_sta->band, &rate);
|
|
|
+ rs_fill_lq_cmd(NULL, NULL, lq_sta, &rate);
|
|
|
iwl_mvm_send_lq_cmd(lq_sta->drv, &lq_sta->lq, false);
|
|
|
}
|
|
|
}
|
|
@@ -2739,14 +2718,14 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
|
|
|
rate = &tbl->rate;
|
|
|
desc += sprintf(buff+desc,
|
|
|
"%s type=%d SGI=%d BW=%s DUP=0\n"
|
|
|
- "rate=0x%X\n",
|
|
|
+ "index=%d\n",
|
|
|
lq_sta->active_tbl == i ? "*" : "x",
|
|
|
rate->type,
|
|
|
rate->sgi,
|
|
|
is_ht20(rate) ? "20Mhz" :
|
|
|
is_ht40(rate) ? "40Mhz" :
|
|
|
is_ht80(rate) ? "80Mhz" : "ERR",
|
|
|
- tbl->current_rate);
|
|
|
+ rate->index);
|
|
|
for (j = 0; j < IWL_RATE_COUNT; j++) {
|
|
|
desc += sprintf(buff+desc,
|
|
|
"counter=%d success=%d %%=%d\n",
|