Commit 8fc7c58c authored by Eyal Shapira's avatar Eyal Shapira Committed by Emmanuel Grumbach

iwlwifi: mvm: rs: refactor building the LQ command

Simplify the code a bit more by extracting the rates table
building logic into a separate function and handle setting
a fixed rate for debug in a separate flow.
Also avoid using and saving ucode rate format in different
places. Instead use rs_rate struct and convert to ucode format
only when filling the rates table in the LQ command.
Signed-off-by: default avatarEyal Shapira <eyal@wizery.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
parent 75209672
...@@ -351,20 +351,12 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, ...@@ -351,20 +351,12 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
struct sk_buff *skb, struct sk_buff *skb,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta); struct iwl_lq_sta *lq_sta);
static void rs_fill_link_cmd(struct iwl_mvm *mvm, static void rs_fill_lq_cmd(struct iwl_mvm *mvm,
struct ieee80211_sta *sta, struct ieee80211_sta *sta,
struct iwl_lq_sta *lq_sta, u32 rate_n_flags); 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); 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 * The following tables contain the expected throughput metrics for all rates
* *
...@@ -761,8 +753,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate, ...@@ -761,8 +753,7 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
/* switch to another antenna/antennas and return 1 */ /* switch to another antenna/antennas and return 1 */
/* if no other valid antenna found, return 0 */ /* if no other valid antenna found, return 0 */
static int rs_toggle_antenna(u32 valid_ant, u32 *ucode_rate, static int rs_toggle_antenna(u32 valid_ant, struct rs_rate *rate)
struct rs_rate *rate)
{ {
u8 new_ant_type; u8 new_ant_type;
...@@ -783,9 +774,6 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *ucode_rate, ...@@ -783,9 +774,6 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *ucode_rate,
rate->ant = new_ant_type; 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; return 1;
} }
...@@ -859,7 +847,7 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask, ...@@ -859,7 +847,7 @@ static u16 rs_get_adjacent_rate(struct iwl_mvm *mvm, u8 index, u16 rate_mask,
return (high << 8) | low; return (high << 8) | low;
} }
static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, static void rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
struct rs_rate *rate, struct rs_rate *rate,
u8 scale_index, u8 ht_possible) u8 scale_index, u8 ht_possible)
{ {
...@@ -917,7 +905,6 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta, ...@@ -917,7 +905,6 @@ static u32 rs_get_lower_rate(struct iwl_lq_sta *lq_sta,
out: out:
rate->index = low; rate->index = low;
return ucode_rate_from_rs_rate(lq_sta->drv, rate);
} }
/* Simple function to compare two rate scale table types */ /* Simple function to compare two rate scale table types */
...@@ -1447,10 +1434,7 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm, ...@@ -1447,10 +1434,7 @@ static void rs_update_rate_tbl(struct iwl_mvm *mvm,
struct iwl_lq_sta *lq_sta, struct iwl_lq_sta *lq_sta,
struct rs_rate *rate) struct rs_rate *rate)
{ {
u32 ucode_rate; rs_fill_lq_cmd(mvm, sta, lq_sta, rate);
ucode_rate = ucode_rate_from_rs_rate(mvm, rate);
rs_fill_link_cmd(mvm, sta, lq_sta, ucode_rate);
iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false); iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
} }
...@@ -1610,10 +1594,6 @@ static int rs_switch_to_column(struct iwl_mvm *mvm, ...@@ -1610,10 +1594,6 @@ static int rs_switch_to_column(struct iwl_mvm *mvm,
rate->index = rate_idx; 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", IWL_DEBUG_RATE(mvm, "Switched to column %d: Index %d\n",
col_id, rate->index); col_id, rate->index);
...@@ -1730,9 +1710,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, ...@@ -1730,9 +1710,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
rate->type = LQ_NONE; rate->type = LQ_NONE;
lq_sta->search_better_tbl = 0; lq_sta->search_better_tbl = 0;
tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); 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); rs_update_rate_tbl(mvm, sta, lq_sta, &tbl->rate);
} }
return; return;
...@@ -1823,7 +1800,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, ...@@ -1823,7 +1800,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
tbl = &(lq_sta->lq_info[active_tbl]); tbl = &(lq_sta->lq_info[active_tbl]);
/* Revert to "active" rate and throughput info */ /* 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; current_tpt = lq_sta->last_tpt;
/* Need to set up a new rate table in uCode */ /* Need to set up a new rate table in uCode */
...@@ -2029,11 +2006,11 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, ...@@ -2029,11 +2006,11 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
rs_rate_scale_clear_window(&(tbl->win[i])); rs_rate_scale_clear_window(&(tbl->win[i]));
/* Use new "search" start rate */ /* Use new "search" start rate */
index = iwl_hwrate_to_plcp_idx(tbl->current_rate); index = tbl->rate.index;
rs_dump_rate(mvm, &tbl->rate, rs_dump_rate(mvm, &tbl->rate,
"Switch to SEARCH TABLE:"); "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); iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, false);
} else { } else {
done_search = 1; done_search = 1;
...@@ -2071,8 +2048,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm, ...@@ -2071,8 +2048,6 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
} }
out: out:
tbl->rate.index = index;
tbl->current_rate = ucode_rate_from_rs_rate(mvm, &tbl->rate);
lq_sta->last_txrate_idx = index; lq_sta->last_txrate_idx = index;
} }
...@@ -2099,7 +2074,6 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, ...@@ -2099,7 +2074,6 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
struct iwl_scale_tbl_info *tbl; struct iwl_scale_tbl_info *tbl;
struct rs_rate *rate; struct rs_rate *rate;
int i; int i;
u32 ucode_rate;
u8 active_tbl = 0; u8 active_tbl = 0;
u8 valid_tx_ant; u8 valid_tx_ant;
...@@ -2130,9 +2104,6 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, ...@@ -2130,9 +2104,6 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
else else
rate->type = LQ_LEGACY_G; 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); WARN_ON_ONCE(rate->ant != ANT_A && rate->ant != ANT_B);
if (rate->ant == ANT_A) if (rate->ant == ANT_A)
tbl->column = RS_COLUMN_LEGACY_ANT_A; tbl->column = RS_COLUMN_LEGACY_ANT_A;
...@@ -2140,7 +2111,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm, ...@@ -2140,7 +2111,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
tbl->column = RS_COLUMN_LEGACY_ANT_B; tbl->column = RS_COLUMN_LEGACY_ANT_B;
rs_set_expected_tpt_table(lq_sta, tbl); 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 */ /* TODO restore station should remember the lq cmd */
iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init); iwl_mvm_send_lq_cmd(mvm, &lq_sta->lq, init);
} }
...@@ -2371,9 +2342,32 @@ static void rs_rate_update(void *mvm_r, ...@@ -2371,9 +2342,32 @@ static void rs_rate_update(void *mvm_r,
iwl_mvm_rs_rate_init(mvm, sta, sband->band, false); iwl_mvm_rs_rate_init(mvm, sta, sband->band, false);
} }
static void rs_fill_link_cmd(struct iwl_mvm *mvm, #ifdef CONFIG_MAC80211_DEBUGFS
struct ieee80211_sta *sta, static void rs_build_rates_table_from_fixed(struct iwl_mvm *mvm,
struct iwl_lq_sta *lq_sta, u32 new_rate) 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; struct rs_rate rate;
int index = 0; int index = 0;
...@@ -2383,10 +2377,13 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, ...@@ -2383,10 +2377,13 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
u8 valid_tx_ant = 0; u8 valid_tx_ant = 0;
struct iwl_lq_cmd *lq_cmd = &lq_sta->lq; struct iwl_lq_cmd *lq_cmd = &lq_sta->lq;
/* Override starting rate (index 0) if needed for debug purposes */ memcpy(&rate, initial_rate, sizeof(struct rs_rate));
rs_dbgfs_set_mcs(lq_sta, &new_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? */ /* How many times should we repeat the initial rate? */
if (is_legacy(&rate)) { if (is_legacy(&rate)) {
...@@ -2397,15 +2394,6 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, ...@@ -2397,15 +2394,6 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
LINK_QUAL_AGG_DISABLE_START_DEF - 1); 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++; index++;
repeat_rate--; repeat_rate--;
if (mvm) if (mvm)
...@@ -2421,23 +2409,17 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, ...@@ -2421,23 +2409,17 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
ant_toggle_cnt++; ant_toggle_cnt++;
else if (mvm && else if (mvm &&
rs_toggle_antenna(valid_tx_ant, rs_toggle_antenna(valid_tx_ant, &rate))
&new_rate, &rate))
ant_toggle_cnt = 1; ant_toggle_cnt = 1;
} }
/* Override next rate if needed for debug purposes */
rs_dbgfs_set_mcs(lq_sta, &new_rate);
/* Fill next table entry */ /* Fill next table entry */
lq_cmd->rs_table[index] = lq_cmd->rs_table[index] = cpu_to_le32(
cpu_to_le32(new_rate); ucode_rate_from_rs_rate(mvm, &rate));
repeat_rate--; repeat_rate--;
index++; index++;
} }
rs_rate_from_ucode_rate(new_rate, lq_sta->band, &rate);
/* Indicate to uCode which entries might be MIMO. /* Indicate to uCode which entries might be MIMO.
* If initial rate was MIMO, this will finally end up * If initial rate was MIMO, this will finally end up
* as (IWL_HT_NUMBER_TRY * 2), after 2nd pass, otherwise 0. */ * 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, ...@@ -2445,16 +2427,14 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
lq_cmd->mimo_delim = index; lq_cmd->mimo_delim = index;
/* Get next rate */ /* Get next rate */
new_rate = rs_get_lower_rate(lq_sta, &rate, rate.index, rs_get_lower_rate(lq_sta, &rate, rate.index, use_ht_possible);
use_ht_possible);
/* How many times should we repeat the next rate? */ /* How many times should we repeat the next rate? */
if (is_legacy(&rate)) { if (is_legacy(&rate)) {
if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE) if (ant_toggle_cnt < NUM_TRY_BEFORE_ANT_TOGGLE)
ant_toggle_cnt++; ant_toggle_cnt++;
else if (mvm && else if (mvm &&
rs_toggle_antenna(valid_tx_ant, rs_toggle_antenna(valid_tx_ant, &rate))
&new_rate, &rate))
ant_toggle_cnt = 1; ant_toggle_cnt = 1;
repeat_rate = IWL_NUMBER_TRY; repeat_rate = IWL_NUMBER_TRY;
...@@ -2468,15 +2448,36 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm, ...@@ -2468,15 +2448,36 @@ static void rs_fill_link_cmd(struct iwl_mvm *mvm,
*/ */
use_ht_possible = 0; use_ht_possible = 0;
/* Override next rate if needed for debug purposes */
rs_dbgfs_set_mcs(lq_sta, &new_rate);
/* Fill next table entry */ /* 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++; index++;
repeat_rate--; 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_frame_cnt_limit = LINK_QUAL_AGG_FRAME_LIMIT_DEF;
lq_cmd->agg_disable_start_th = LINK_QUAL_AGG_DISABLE_START_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, ...@@ -2510,31 +2511,6 @@ static void rs_free_sta(void *mvm_r, struct ieee80211_sta *sta,
} }
#ifdef CONFIG_MAC80211_DEBUGFS #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) 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, ...@@ -2605,7 +2581,10 @@ static void rs_program_fix_rate(struct iwl_mvm *mvm,
lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
if (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); 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, ...@@ -2739,14 +2718,14 @@ static ssize_t rs_sta_dbgfs_stats_table_read(struct file *file,
rate = &tbl->rate; rate = &tbl->rate;
desc += sprintf(buff+desc, desc += sprintf(buff+desc,
"%s type=%d SGI=%d BW=%s DUP=0\n" "%s type=%d SGI=%d BW=%s DUP=0\n"
"rate=0x%X\n", "index=%d\n",
lq_sta->active_tbl == i ? "*" : "x", lq_sta->active_tbl == i ? "*" : "x",
rate->type, rate->type,
rate->sgi, rate->sgi,
is_ht20(rate) ? "20Mhz" : is_ht20(rate) ? "20Mhz" :
is_ht40(rate) ? "40Mhz" : is_ht40(rate) ? "40Mhz" :
is_ht80(rate) ? "80Mhz" : "ERR", is_ht80(rate) ? "80Mhz" : "ERR",
tbl->current_rate); rate->index);
for (j = 0; j < IWL_RATE_COUNT; j++) { for (j = 0; j < IWL_RATE_COUNT; j++) {
desc += sprintf(buff+desc, desc += sprintf(buff+desc,
"counter=%d success=%d %%=%d\n", "counter=%d success=%d %%=%d\n",
......
...@@ -278,7 +278,6 @@ struct iwl_scale_tbl_info { ...@@ -278,7 +278,6 @@ struct iwl_scale_tbl_info {
struct rs_rate rate; struct rs_rate rate;
enum rs_column column; enum rs_column column;
s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */ s32 *expected_tpt; /* throughput metrics; expected_tpt_G, etc. */
u32 current_rate; /* rate_n_flags, uCode API format */
struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */ struct iwl_rate_scale_data win[IWL_RATE_COUNT]; /* rate histories */
}; };
......
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