Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+104 −52
Original line number Original line Diff line number Diff line
@@ -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,


			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,
			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,
		  (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,
			}
			}
			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,
	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,
			}
			}
			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,
		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,
		 * 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,
		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
+18 −11
Original line number Original line Diff line number Diff line
@@ -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*/