Commit 3110bef7 authored by Guy Cohen's avatar Guy Cohen Committed by John W. Linville

iwlwifi: Added support for 3 antennas

Added support for 3 antennas for Legacy, SISO and MIMO2.
MIMO3 is still not supported yet.
Signed-off-by: default avatarGuy Cohen <guy.cohen@intel.com>
Signed-off-by: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarZhu Yi <yi.zhu@intel.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 90d7795e
...@@ -1282,15 +1282,23 @@ static int rs_move_legacy_other(struct iwl_priv *priv, ...@@ -1282,15 +1282,23 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
u8 start_action = tbl->action; u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret = 0; int ret = 0;
for (; ;) { for (; ;) {
switch (tbl->action) { switch (tbl->action) {
case IWL_LEGACY_SWITCH_ANTENNA: case IWL_LEGACY_SWITCH_ANTENNA1:
case IWL_LEGACY_SWITCH_ANTENNA2:
IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n"); IWL_DEBUG_RATE("LQ: Legacy toggle Antenna\n");
lq_sta->action_counter++; lq_sta->action_counter++;
if ((tbl->action == IWL_LEGACY_SWITCH_ANTENNA1 &&
tx_chains_num <= 1) ||
(tbl->action == IWL_LEGACY_SWITCH_ANTENNA2 &&
tx_chains_num <= 2))
break;
/* Don't change antenna if success has been great */ /* Don't change antenna if success has been great */
if (window->success_ratio >= IWL_RS_GOOD_RATIO) if (window->success_ratio >= IWL_RS_GOOD_RATIO)
break; break;
...@@ -1300,7 +1308,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv, ...@@ -1300,7 +1308,7 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
if (rs_toggle_antenna(valid_tx_ant, if (rs_toggle_antenna(valid_tx_ant,
&search_tbl->current_rate, search_tbl)) { &search_tbl->current_rate, search_tbl)) {
lq_sta->search_better_tbl = 1; rs_set_expected_tpt_table(lq_sta, search_tbl);
goto out; goto out;
} }
break; break;
...@@ -1313,43 +1321,54 @@ static int rs_move_legacy_other(struct iwl_priv *priv, ...@@ -1313,43 +1321,54 @@ static int rs_move_legacy_other(struct iwl_priv *priv,
ret = rs_switch_to_siso(priv, lq_sta, conf, sta, ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
search_tbl, index); search_tbl, index);
if (!ret) { if (!ret) {
lq_sta->search_better_tbl = 1;
lq_sta->action_counter = 0; lq_sta->action_counter = 0;
goto out; goto out;
} }
break; break;
case IWL_LEGACY_SWITCH_MIMO2: case IWL_LEGACY_SWITCH_MIMO2_AB:
case IWL_LEGACY_SWITCH_MIMO2_AC:
case IWL_LEGACY_SWITCH_MIMO2_BC:
IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n"); IWL_DEBUG_RATE("LQ: Legacy switch to MIMO2\n");
/* Set up search table to try MIMO */ /* Set up search table to try MIMO */
memcpy(search_tbl, tbl, sz); memcpy(search_tbl, tbl, sz);
search_tbl->is_SGI = 0; search_tbl->is_SGI = 0;
search_tbl->ant_type = ANT_AB;/*FIXME:RS*/
/*FIXME:RS:need to check ant validity*/ if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AB)
search_tbl->ant_type = ANT_AB;
else if (tbl->action == IWL_LEGACY_SWITCH_MIMO2_AC)
search_tbl->ant_type = ANT_AC;
else
search_tbl->ant_type = ANT_BC;
if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
break;
ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
search_tbl, index); search_tbl, index);
if (!ret) { if (!ret) {
lq_sta->search_better_tbl = 1;
lq_sta->action_counter = 0; lq_sta->action_counter = 0;
goto out; goto out;
} }
break; break;
} }
tbl->action++; tbl->action++;
if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA; tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
if (tbl->action == start_action) if (tbl->action == start_action)
break; break;
} }
search_tbl->lq_type = LQ_NONE;
return 0; return 0;
out: out:
lq_sta->search_better_tbl = 1;
tbl->action++; tbl->action++;
if (tbl->action > IWL_LEGACY_SWITCH_MIMO2) if (tbl->action > IWL_LEGACY_SWITCH_MIMO2_BC)
tbl->action = IWL_LEGACY_SWITCH_ANTENNA; tbl->action = IWL_LEGACY_SWITCH_ANTENNA1;
return 0; return 0;
} }
...@@ -1371,34 +1390,51 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, ...@@ -1371,34 +1390,51 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
u8 start_action = tbl->action; u8 start_action = tbl->action;
u8 valid_tx_ant = priv->hw_params.valid_tx_ant; u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret; int ret;
for (;;) { for (;;) {
lq_sta->action_counter++; lq_sta->action_counter++;
switch (tbl->action) { switch (tbl->action) {
case IWL_SISO_SWITCH_ANTENNA: case IWL_SISO_SWITCH_ANTENNA1:
case IWL_SISO_SWITCH_ANTENNA2:
IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n"); IWL_DEBUG_RATE("LQ: SISO toggle Antenna\n");
if ((tbl->action == IWL_SISO_SWITCH_ANTENNA1 &&
tx_chains_num <= 1) ||
(tbl->action == IWL_SISO_SWITCH_ANTENNA2 &&
tx_chains_num <= 2))
break;
if (window->success_ratio >= IWL_RS_GOOD_RATIO) if (window->success_ratio >= IWL_RS_GOOD_RATIO)
break; break;
memcpy(search_tbl, tbl, sz); memcpy(search_tbl, tbl, sz);
if (rs_toggle_antenna(valid_tx_ant, if (rs_toggle_antenna(valid_tx_ant,
&search_tbl->current_rate, search_tbl)) { &search_tbl->current_rate, search_tbl))
lq_sta->search_better_tbl = 1;
goto out; goto out;
}
break; break;
case IWL_SISO_SWITCH_MIMO2: case IWL_SISO_SWITCH_MIMO2_AB:
case IWL_SISO_SWITCH_MIMO2_AC:
case IWL_SISO_SWITCH_MIMO2_BC:
IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n"); IWL_DEBUG_RATE("LQ: SISO switch to MIMO2\n");
memcpy(search_tbl, tbl, sz); memcpy(search_tbl, tbl, sz);
search_tbl->is_SGI = 0; search_tbl->is_SGI = 0;
search_tbl->ant_type = ANT_AB; /*FIXME:RS*/
if (tbl->action == IWL_SISO_SWITCH_MIMO2_AB)
search_tbl->ant_type = ANT_AB;
else if (tbl->action == IWL_SISO_SWITCH_MIMO2_AC)
search_tbl->ant_type = ANT_AC;
else
search_tbl->ant_type = ANT_BC;
if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
break;
ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta, ret = rs_switch_to_mimo2(priv, lq_sta, conf, sta,
search_tbl, index); search_tbl, index);
if (!ret) { if (!ret)
lq_sta->search_better_tbl = 1;
goto out; goto out;
}
break; break;
case IWL_SISO_SWITCH_GI: case IWL_SISO_SWITCH_GI:
if (!tbl->is_fat && if (!tbl->is_fat &&
...@@ -1428,22 +1464,23 @@ static int rs_move_siso_to_other(struct iwl_priv *priv, ...@@ -1428,22 +1464,23 @@ static int rs_move_siso_to_other(struct iwl_priv *priv,
} }
search_tbl->current_rate = rate_n_flags_from_tbl( search_tbl->current_rate = rate_n_flags_from_tbl(
search_tbl, index, is_green); search_tbl, index, is_green);
lq_sta->search_better_tbl = 1;
goto out; goto out;
} }
tbl->action++; tbl->action++;
if (tbl->action > IWL_SISO_SWITCH_GI) if (tbl->action > IWL_SISO_SWITCH_GI)
tbl->action = IWL_SISO_SWITCH_ANTENNA; tbl->action = IWL_SISO_SWITCH_ANTENNA1;
if (tbl->action == start_action) if (tbl->action == start_action)
break; break;
} }
search_tbl->lq_type = LQ_NONE;
return 0; return 0;
out: out:
lq_sta->search_better_tbl = 1;
tbl->action++; tbl->action++;
if (tbl->action > IWL_SISO_SWITCH_GI) if (tbl->action > IWL_SISO_SWITCH_GI)
tbl->action = IWL_SISO_SWITCH_ANTENNA; tbl->action = IWL_SISO_SWITCH_ANTENNA1;
return 0; return 0;
} }
...@@ -1459,37 +1496,58 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, ...@@ -1459,37 +1496,58 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]); struct iwl_scale_tbl_info *tbl = &(lq_sta->lq_info[lq_sta->active_tbl]);
struct iwl_scale_tbl_info *search_tbl = struct iwl_scale_tbl_info *search_tbl =
&(lq_sta->lq_info[(1 - lq_sta->active_tbl)]); &(lq_sta->lq_info[(1 - lq_sta->active_tbl)]);
struct iwl_rate_scale_data *window = &(tbl->win[index]);
u32 sz = (sizeof(struct iwl_scale_tbl_info) - u32 sz = (sizeof(struct iwl_scale_tbl_info) -
(sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
u8 start_action = tbl->action; u8 start_action = tbl->action;
/*u8 valid_tx_ant = priv->hw_params.valid_tx_ant;*/ u8 valid_tx_ant = priv->hw_params.valid_tx_ant;
u8 tx_chains_num = priv->hw_params.tx_chains_num;
int ret; int ret;
for (;;) { for (;;) {
lq_sta->action_counter++; lq_sta->action_counter++;
switch (tbl->action) { switch (tbl->action) {
case IWL_MIMO_SWITCH_ANTENNA_A: case IWL_MIMO2_SWITCH_ANTENNA1:
case IWL_MIMO_SWITCH_ANTENNA_B: case IWL_MIMO2_SWITCH_ANTENNA2:
IWL_DEBUG_RATE("LQ: MIMO toggle Antennas\n");
if (tx_chains_num <= 2)
break;
if (window->success_ratio >= IWL_RS_GOOD_RATIO)
break;
memcpy(search_tbl, tbl, sz);
if (rs_toggle_antenna(valid_tx_ant,
&search_tbl->current_rate, search_tbl))
goto out;
break;
case IWL_MIMO2_SWITCH_SISO_A:
case IWL_MIMO2_SWITCH_SISO_B:
case IWL_MIMO2_SWITCH_SISO_C:
IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n"); IWL_DEBUG_RATE("LQ: MIMO2 switch to SISO\n");
/* Set up new search table for SISO */ /* Set up new search table for SISO */
memcpy(search_tbl, tbl, sz); memcpy(search_tbl, tbl, sz);
/*FIXME:RS:need to check ant validity + C*/ if (tbl->action == IWL_MIMO2_SWITCH_SISO_A)
if (tbl->action == IWL_MIMO_SWITCH_ANTENNA_A)
search_tbl->ant_type = ANT_A; search_tbl->ant_type = ANT_A;
else else if (tbl->action == IWL_MIMO2_SWITCH_SISO_B)
search_tbl->ant_type = ANT_B; search_tbl->ant_type = ANT_B;
else
search_tbl->ant_type = ANT_C;
if (!rs_is_valid_ant(valid_tx_ant, search_tbl->ant_type))
break;
ret = rs_switch_to_siso(priv, lq_sta, conf, sta, ret = rs_switch_to_siso(priv, lq_sta, conf, sta,
search_tbl, index); search_tbl, index);
if (!ret) { if (!ret)
lq_sta->search_better_tbl = 1;
goto out; goto out;
}
break; break;
case IWL_MIMO_SWITCH_GI: case IWL_MIMO2_SWITCH_GI:
if (!tbl->is_fat && if (!tbl->is_fat &&
!(priv->current_ht_config.sgf & !(priv->current_ht_config.sgf &
HT_SHORT_GI_20MHZ)) HT_SHORT_GI_20MHZ))
...@@ -1518,23 +1576,23 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv, ...@@ -1518,23 +1576,23 @@ static int rs_move_mimo_to_other(struct iwl_priv *priv,
} }
search_tbl->current_rate = rate_n_flags_from_tbl( search_tbl->current_rate = rate_n_flags_from_tbl(
search_tbl, index, is_green); search_tbl, index, is_green);
lq_sta->search_better_tbl = 1;
goto out; goto out;
} }
tbl->action++; tbl->action++;
if (tbl->action > IWL_MIMO_SWITCH_GI) if (tbl->action > IWL_MIMO2_SWITCH_GI)
tbl->action = IWL_MIMO_SWITCH_ANTENNA_A; tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
if (tbl->action == start_action) if (tbl->action == start_action)
break; break;
} }
search_tbl->lq_type = LQ_NONE;
return 0; return 0;
out: out:
lq_sta->search_better_tbl = 1;
tbl->action++; tbl->action++;
if (tbl->action > IWL_MIMO_SWITCH_GI) if (tbl->action > IWL_MIMO2_SWITCH_GI)
tbl->action = IWL_MIMO_SWITCH_ANTENNA_A; tbl->action = IWL_MIMO2_SWITCH_ANTENNA1;
return 0; return 0;
} }
...@@ -1749,19 +1807,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -1749,19 +1807,13 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
rs_stay_in_table(lq_sta); rs_stay_in_table(lq_sta);
goto out; goto out;
}
/* Else we have enough samples; calculate estimate of /* Else we have enough samples; calculate estimate of
* actual average throughput */ * actual average throughput */
} else {
/*FIXME:RS remove this else if we don't get this error*/ BUG_ON(window->average_tpt != ((window->success_ratio *
if (window->average_tpt != ((window->success_ratio * tbl->expected_tpt[index] + 64) / 128));
tbl->expected_tpt[index] + 64) / 128)) {
IWL_ERROR("expected_tpt should have been calculated"
" by now\n");
window->average_tpt = ((window->success_ratio *
tbl->expected_tpt[index] + 64) / 128);
}
}
/* If we are searching for better modulation mode, check success. */ /* If we are searching for better modulation mode, check success. */
if (lq_sta->search_better_tbl) { if (lq_sta->search_better_tbl) {
...@@ -1771,7 +1823,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv, ...@@ -1771,7 +1823,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
* continuing to use the setup that we've been trying. */ * continuing to use the setup that we've been trying. */
if (window->average_tpt > lq_sta->last_tpt) { if (window->average_tpt > lq_sta->last_tpt) {
IWL_DEBUG_RATE("LQ: SWITCHING TO CURRENT TABLE " IWL_DEBUG_RATE("LQ: SWITCHING TO NEW TABLE "
"suc=%d cur-tpt=%d old-tpt=%d\n", "suc=%d cur-tpt=%d old-tpt=%d\n",
window->success_ratio, window->success_ratio,
window->average_tpt, window->average_tpt,
...@@ -2184,7 +2236,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta, ...@@ -2184,7 +2236,7 @@ static void rs_rate_init(void *priv_rate, void *priv_sta,
for (i = 0; i < IWL_RATE_COUNT; i++) for (i = 0; i < IWL_RATE_COUNT; i++)
rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]); rs_rate_scale_clear_window(&lq_sta->lq_info[j].win[i]);
IWL_DEBUG_RATE("LQ: *** rate scale global init ***\n"); IWL_DEBUG_RATE("LQ: *** rate scale station global init ***\n");
/* TODO: what is a good starting rate for STA? About middle? Maybe not /* TODO: what is a good starting rate for STA? About middle? Maybe not
* the lowest or the highest rate.. Could consider using RSSI from * the lowest or the highest rate.. Could consider using RSSI from
* previous packets? Need to have IEEE 802.1X auth succeed immediately * previous packets? Need to have IEEE 802.1X auth succeed immediately
......
...@@ -206,21 +206,28 @@ enum { ...@@ -206,21 +206,28 @@ enum {
#define IWL_RATE_DECREASE_TH 1920 /* 15% */ #define IWL_RATE_DECREASE_TH 1920 /* 15% */
/* possible actions when in legacy mode */ /* possible actions when in legacy mode */
#define IWL_LEGACY_SWITCH_ANTENNA 0 #define IWL_LEGACY_SWITCH_ANTENNA1 0
#define IWL_LEGACY_SWITCH_SISO 1 #define IWL_LEGACY_SWITCH_ANTENNA2 1
#define IWL_LEGACY_SWITCH_MIMO2 2 #define IWL_LEGACY_SWITCH_SISO 2
#define IWL_LEGACY_SWITCH_MIMO2_AB 3
#define IWL_LEGACY_SWITCH_MIMO2_AC 4
#define IWL_LEGACY_SWITCH_MIMO2_BC 5
/* possible actions when in siso mode */ /* possible actions when in siso mode */
#define IWL_SISO_SWITCH_ANTENNA 0 #define IWL_SISO_SWITCH_ANTENNA1 0
#define IWL_SISO_SWITCH_MIMO2 1 #define IWL_SISO_SWITCH_ANTENNA2 1
#define IWL_SISO_SWITCH_GI 2 #define IWL_SISO_SWITCH_MIMO2_AB 2
#define IWL_SISO_SWITCH_MIMO2_AC 3
#define IWL_SISO_SWITCH_MIMO2_BC 4
#define IWL_SISO_SWITCH_GI 5
/* possible actions when in mimo mode */ /* possible actions when in mimo mode */
#define IWL_MIMO_SWITCH_ANTENNA_A 0 #define IWL_MIMO2_SWITCH_ANTENNA1 0
#define IWL_MIMO_SWITCH_ANTENNA_B 1 #define IWL_MIMO2_SWITCH_ANTENNA2 1
#define IWL_MIMO_SWITCH_GI 2 #define IWL_MIMO2_SWITCH_SISO_A 2
#define IWL_MIMO2_SWITCH_SISO_B 3
/*FIXME:RS:separate MIMO2/3 transitions*/ #define IWL_MIMO2_SWITCH_SISO_C 4
#define IWL_MIMO2_SWITCH_GI 5
/*FIXME:RS:add posible acctions for MIMO3*/ /*FIXME:RS:add posible acctions for MIMO3*/
......
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