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

Commit 246ed355 authored by Johannes Berg's avatar Johannes Berg Committed by Wey-Yi Guy
Browse files

iwlwifi: initial contextification



In order to support multiple interfaces, we must move
a lot of data into per-context structures so we can
use the contexts the device offers. To start with,
this makes a lot of code context-aware, more changes
will move more things into the context structure.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarWey-Yi Guy <wey-yi.w.guy@intel.com>
parent 903786a5
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -949,7 +949,8 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
	switch (priv->band) {
	case IEEE80211_BAND_2GHZ:
		/* TODO: this always does G, not a regression */
		if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) {
		if (priv->contexts[IWL_RXON_CTX_BSS].active.flags &
						RXON_FLG_TGG_PROTECT_MSK) {
			rs_sta->tgg = 1;
			rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot;
		} else
+28 −25
Original line number Diff line number Diff line
@@ -245,7 +245,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
		break;
	case IEEE80211_BAND_2GHZ:
		if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
		    iwl_is_associated(priv)) {
		    iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
			if (rate == IWL_RATE_11M_INDEX)
				next_rate = IWL_RATE_5M_INDEX;
		}
@@ -1439,17 +1439,18 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
	int rate_idx, i;
	const struct iwl_channel_info *ch_info = NULL;
	struct iwl3945_txpowertable_cmd txpower = {
		.channel = priv->active_rxon.channel,
		.channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel,
	};
	u16 chan;

	chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel);

	txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
	ch_info = iwl_get_channel_info(priv,
				       priv->band,
				       le16_to_cpu(priv->active_rxon.channel));
	ch_info = iwl_get_channel_info(priv, priv->band, chan);
	if (!ch_info) {
		IWL_ERR(priv,
			"Failed to get channel info for channel %d [%d]\n",
			le16_to_cpu(priv->active_rxon.channel), priv->band);
			chan, priv->band);
		return -EINVAL;
	}

@@ -1710,7 +1711,8 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
	return 0;
}

static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
				   struct iwl_rxon_context *ctx)
{
	int rc = 0;
	struct iwl_rx_packet *pkt;
@@ -1721,8 +1723,8 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
		.flags = CMD_WANT_SKB,
		.data = &rxon_assoc,
	};
	const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
	const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
	const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
	const struct iwl_rxon_cmd *rxon2 = &ctx->active;

	if ((rxon1->flags == rxon2->flags) &&
	    (rxon1->filter_flags == rxon2->filter_flags) &&
@@ -1732,10 +1734,10 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
		return 0;
	}

	rxon_assoc.flags = priv->staging_rxon.flags;
	rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
	rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
	rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
	rxon_assoc.flags = ctx->staging.flags;
	rxon_assoc.filter_flags = ctx->staging.filter_flags;
	rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
	rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
	rxon_assoc.reserved = 0;

	rc = iwl_send_cmd_sync(priv, &cmd);
@@ -1761,14 +1763,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
 * function correctly transitions out of the RXON_ASSOC_MSK state if
 * a HW tune is required based on the RXON structure changes.
 */
static int iwl3945_commit_rxon(struct iwl_priv *priv)
static int iwl3945_commit_rxon(struct iwl_priv *priv,
			       struct iwl_rxon_context *ctx)
{
	/* cast away the const for active_rxon in this function */
	struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
	struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon;
	struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active;
	struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging;
	int rc = 0;
	bool new_assoc =
		!!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
	bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);

	if (!iwl_is_alive(priv))
		return -1;
@@ -1781,7 +1783,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
	    ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
	staging_rxon->flags |= iwl3945_get_antenna_flags(priv);

	rc = iwl_check_rxon_cmd(priv);
	rc = iwl_check_rxon_cmd(priv, ctx);
	if (rc) {
		IWL_ERR(priv, "Invalid RXON configuration.  Not committing.\n");
		return -EINVAL;
@@ -1790,8 +1792,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
	/* If we don't need to send a full RXON, we can use
	 * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
	 * and other flags for the current radio configuration. */
	if (!iwl_full_rxon_required(priv)) {
		rc = iwl_send_rxon_assoc(priv);
	if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) {
		rc = iwl_send_rxon_assoc(priv,
					 &priv->contexts[IWL_RXON_CTX_BSS]);
		if (rc) {
			IWL_ERR(priv, "Error setting RXON_ASSOC "
				  "configuration (%d).\n", rc);
@@ -1807,7 +1810,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
	 * an RXON_ASSOC and the new config wants the associated mask enabled,
	 * we must clear the associated from the active configuration
	 * before we apply the new config */
	if (iwl_is_associated(priv) && new_assoc) {
	if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) {
		IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
		active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;

@@ -1819,7 +1822,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
		active_rxon->reserved5 = 0;
		rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
				      sizeof(struct iwl3945_rxon_cmd),
				      &priv->active_rxon);
				      &priv->contexts[IWL_RXON_CTX_BSS].active);

		/* If the mask clearing failed then we set
		 * active_rxon back to what it was previously */
@@ -1848,7 +1851,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
	staging_rxon->reserved4 = 0;
	staging_rxon->reserved5 = 0;

	iwl_set_rxon_hwcrypto(priv, !iwl3945_mod_params.sw_crypto);
	iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto);

	/* Apply the new configuration */
	rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -2366,7 +2369,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
		 * 1M CCK rates */

		if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
		    iwl_is_associated(priv)) {
		    iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {

			index = IWL_FIRST_CCK_RATE;
			for (i = IWL_RATE_6M_INDEX_TABLE;
+24 −22
Original line number Diff line number Diff line
@@ -347,7 +347,7 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
	struct iwl_chain_noise_data *data = &(priv->chain_noise_data);

	if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
	     iwl_is_associated(priv)) {
	    iwl_is_any_associated(priv)) {
		struct iwl_calib_diff_gain_cmd cmd;

		/* clear data for chain noise calibration algorithm */
@@ -1374,6 +1374,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
	u8 band = 0;
	bool is_ht40 = false;
	u8 ctrl_chan_high = 0;
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];

	if (test_bit(STATUS_SCANNING, &priv->status)) {
		/* If this gets hit a lot, switch it to a BUG() and catch
@@ -1385,17 +1386,16 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)

	band = priv->band == IEEE80211_BAND_2GHZ;

	is_ht40 =  is_ht40_channel(priv->active_rxon.flags);
	is_ht40 = is_ht40_channel(ctx->active.flags);

	if (is_ht40 &&
	    (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
	if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
		ctrl_chan_high = 1;

	cmd.band = band;
	cmd.channel = priv->active_rxon.channel;
	cmd.channel = ctx->active.channel;

	ret = iwl4965_fill_txpower_tbl(priv, band,
				le16_to_cpu(priv->active_rxon.channel),
				le16_to_cpu(ctx->active.channel),
				is_ht40, ctrl_chan_high, &cmd.tx_power);
	if (ret)
		goto out;
@@ -1406,12 +1406,13 @@ out:
	return ret;
}

static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
				   struct iwl_rxon_context *ctx)
{
	int ret = 0;
	struct iwl4965_rxon_assoc_cmd rxon_assoc;
	const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon;
	const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon;
	const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
	const struct iwl_rxon_cmd *rxon2 = &ctx->active;

	if ((rxon1->flags == rxon2->flags) &&
	    (rxon1->filter_flags == rxon2->filter_flags) &&
@@ -1426,16 +1427,16 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
		return 0;
	}

	rxon_assoc.flags = priv->staging_rxon.flags;
	rxon_assoc.filter_flags = priv->staging_rxon.filter_flags;
	rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates;
	rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates;
	rxon_assoc.flags = ctx->staging.flags;
	rxon_assoc.filter_flags = ctx->staging.filter_flags;
	rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
	rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
	rxon_assoc.reserved = 0;
	rxon_assoc.ofdm_ht_single_stream_basic_rates =
	    priv->staging_rxon.ofdm_ht_single_stream_basic_rates;
	    ctx->staging.ofdm_ht_single_stream_basic_rates;
	rxon_assoc.ofdm_ht_dual_stream_basic_rates =
	    priv->staging_rxon.ofdm_ht_dual_stream_basic_rates;
	rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain;
	    ctx->staging.ofdm_ht_dual_stream_basic_rates;
	rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;

	ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
				     sizeof(rxon_assoc), &rxon_assoc, NULL);
@@ -1448,6 +1449,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
				     struct ieee80211_channel_switch *ch_switch)
{
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
	int rc;
	u8 band = 0;
	bool is_ht40 = false;
@@ -1458,22 +1460,22 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
	u16 ch;
	u32 tsf_low;
	u8 switch_count;
	u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
	u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
	struct ieee80211_vif *vif = priv->vif;
	band = priv->band == IEEE80211_BAND_2GHZ;

	is_ht40 = is_ht40_channel(priv->staging_rxon.flags);
	is_ht40 = is_ht40_channel(ctx->staging.flags);

	if (is_ht40 &&
	    (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
	    (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
		ctrl_chan_high = 1;

	cmd.band = band;
	cmd.expect_beacon = 0;
	ch = ch_switch->channel->hw_value;
	cmd.channel = cpu_to_le16(ch);
	cmd.rxon_flags = priv->staging_rxon.flags;
	cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
	cmd.rxon_flags = ctx->staging.flags;
	cmd.rxon_filter_flags = ctx->staging.filter_flags;
	switch_count = ch_switch->count;
	tsf_low = ch_switch->timestamp & 0x0ffffffff;
	/*
@@ -1508,7 +1510,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
		cmd.expect_beacon = is_channel_radar(ch_info);
	else {
		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
			priv->active_rxon.channel, ch);
			ctx->active.channel, ch);
		return -EFAULT;
	}

+10 −5
Original line number Diff line number Diff line
@@ -275,13 +275,18 @@ static void iwl5150_temperature(struct iwl_priv *priv)
static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
				     struct ieee80211_channel_switch *ch_switch)
{
	/*
	 * MULTI-FIXME
	 * See iwl_mac_channel_switch.
	 */
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
	struct iwl5000_channel_switch_cmd cmd;
	const struct iwl_channel_info *ch_info;
	u32 switch_time_in_usec, ucode_switch_time;
	u16 ch;
	u32 tsf_low;
	u8 switch_count;
	u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
	u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
	struct ieee80211_vif *vif = priv->vif;
	struct iwl_host_cmd hcmd = {
		.id = REPLY_CHANNEL_SWITCH,
@@ -293,10 +298,10 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
	ch = ch_switch->channel->hw_value;
	IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
		priv->active_rxon.channel, ch);
		      ctx->active.channel, ch);
	cmd.channel = cpu_to_le16(ch);
	cmd.rxon_flags = priv->staging_rxon.flags;
	cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
	cmd.rxon_flags = ctx->staging.flags;
	cmd.rxon_filter_flags = ctx->staging.filter_flags;
	switch_count = ch_switch->count;
	tsf_low = ch_switch->timestamp & 0x0ffffffff;
	/*
@@ -331,7 +336,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
		cmd.expect_beacon = is_channel_radar(ch_info);
	else {
		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
			priv->active_rxon.channel, ch);
			ctx->active.channel, ch);
		return -EFAULT;
	}
	priv->switch_rxon.channel = cmd.channel;
+10 −5
Original line number Diff line number Diff line
@@ -198,13 +198,18 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
				     struct ieee80211_channel_switch *ch_switch)
{
	/*
	 * MULTI-FIXME
	 * See iwl_mac_channel_switch.
	 */
	struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
	struct iwl6000_channel_switch_cmd cmd;
	const struct iwl_channel_info *ch_info;
	u32 switch_time_in_usec, ucode_switch_time;
	u16 ch;
	u32 tsf_low;
	u8 switch_count;
	u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval);
	u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
	struct ieee80211_vif *vif = priv->vif;
	struct iwl_host_cmd hcmd = {
		.id = REPLY_CHANNEL_SWITCH,
@@ -216,10 +221,10 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
	cmd.band = priv->band == IEEE80211_BAND_2GHZ;
	ch = ch_switch->channel->hw_value;
	IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
		      priv->active_rxon.channel, ch);
		      ctx->active.channel, ch);
	cmd.channel = cpu_to_le16(ch);
	cmd.rxon_flags = priv->staging_rxon.flags;
	cmd.rxon_filter_flags = priv->staging_rxon.filter_flags;
	cmd.rxon_flags = ctx->staging.flags;
	cmd.rxon_filter_flags = ctx->staging.filter_flags;
	switch_count = ch_switch->count;
	tsf_low = ch_switch->timestamp & 0x0ffffffff;
	/*
@@ -254,7 +259,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
		cmd.expect_beacon = is_channel_radar(ch_info);
	else {
		IWL_ERR(priv, "invalid channel switch from %u to %u\n",
			priv->active_rxon.channel, ch);
			ctx->active.channel, ch);
		return -EFAULT;
	}
	priv->switch_rxon.channel = cmd.channel;
Loading