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
......@@ -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
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
......
......@@ -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;
......
......@@ -625,7 +625,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
data = &(priv->sensitivity_data);
if (!iwl_is_associated(priv)) {
if (!iwl_is_any_associated(priv)) {
IWL_DEBUG_CALIB(priv, "<< - not associated\n");
return;
}
......@@ -763,6 +763,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
unsigned long flags;
struct statistics_rx_non_phy *rx_info;
u8 first_chain;
/*
* MULTI-FIXME:
* When we support multiple interfaces on different channels,
* this must be modified/fixed.
*/
struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
if (priv->disable_chain_noise_cal)
return;
......@@ -793,8 +799,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
return;
}
rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK);
rxon_chnum = le16_to_cpu(priv->staging_rxon.channel);
rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
rxon_chnum = le16_to_cpu(ctx->staging.channel);
if (priv->cfg->bt_statistics) {
stat_band24 = !!(((struct iwl_bt_notif_statistics *)
stat_resp)->flag &
......
......@@ -37,12 +37,13 @@
#include "iwl-io.h"
#include "iwl-agn.h"
int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
struct iwl_rxon_context *ctx)
{
int ret = 0;
struct iwl5000_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) &&
......@@ -60,21 +61,21 @@ int iwlagn_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.reserved1 = 0;
rxon_assoc.reserved2 = 0;
rxon_assoc.reserved3 = 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;
rxon_assoc.ofdm_ht_triple_stream_basic_rates =
priv->staging_rxon.ofdm_ht_triple_stream_basic_rates;
rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data;
ctx->staging.ofdm_ht_triple_stream_basic_rates;
rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
sizeof(rxon_assoc), &rxon_assoc, NULL);
......@@ -184,7 +185,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
int ret;
if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
iwl_is_associated(priv)) {
iwl_is_any_associated(priv)) {
struct iwl_calib_chain_noise_reset_cmd cmd;
/* clear data for chain noise calibration algorithm */
......
......@@ -1232,7 +1232,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
if (iwl_is_associated(priv)) {
if (iwl_is_any_associated(priv)) {
u16 interval = 0;
u32 extra;
u32 suspend_time = 100;
......@@ -1289,7 +1289,9 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
switch (priv->scan_band) {
case IEEE80211_BAND_2GHZ:
scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK)
chan_mod = le32_to_cpu(
priv->contexts[IWL_RXON_CTX_BSS].active.flags &
RXON_FLG_CHANNEL_MODE_MSK)
>> RXON_FLG_CHANNEL_MODE_POS;
if (chan_mod == CHANNEL_MODE_PURE_40) {
rate = IWL_RATE_6M_PLCP;
......
......@@ -416,18 +416,26 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
/* stop ct_kill_waiting_tm timer */
del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
if (changed) {
struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
if (tt->state >= IWL_TI_1) {
/* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
tt->tt_power_mode = IWL_POWER_INDEX_5;
if (!iwl_ht_enabled(priv))
/* disable HT */
rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
RXON_FLG_HT40_PROT_MSK |
RXON_FLG_HT_PROT_MSK);
else {
if (!iwl_ht_enabled(priv)) {
struct iwl_rxon_context *ctx;
for_each_context(priv, ctx) {
struct iwl_rxon_cmd *rxon;
rxon = &ctx->staging;
/* disable HT */
rxon->flags &= ~(
RXON_FLG_CHANNEL_MODE_MSK |
RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
RXON_FLG_HT40_PROT_MSK |
RXON_FLG_HT_PROT_MSK);
}
} else {
/* check HT capability and set
* according to the system HT capability
* in case get disabled before */
......
......@@ -98,21 +98,21 @@ static bool iwlagn_bt_ch_announce = 1;
* function correctly transitions out of the RXON_ASSOC_MSK state if
* a HW tune is required based on the RXON structure changes.
*/
int iwl_commit_rxon(struct iwl_priv *priv)
int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
{
/* cast away the const for active_rxon in this function */
struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon;
struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
int ret;
bool new_assoc =
!!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
!!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
if (!iwl_is_alive(priv))
return -EBUSY;
/* always get timestamp with Rx frame */
priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK;
ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
ret = iwl_check_rxon_cmd(priv);
ret = iwl_check_rxon_cmd(priv, ctx);
if (ret) {
IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
return -EINVAL;
......@@ -123,7 +123,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
* abort any previous channel switch if still in process
*/
if (priv->switch_rxon.switch_in_progress &&
(priv->switch_rxon.channel != priv->staging_rxon.channel)) {
(priv->switch_rxon.channel != ctx->staging.channel)) {
IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
le16_to_cpu(priv->switch_rxon.channel));
iwl_chswitch_done(priv, false);
......@@ -132,15 +132,15 @@ int iwl_commit_rxon(struct iwl_priv *priv)
/* If we don't need to send a full RXON, we can use
* iwl_rxon_assoc_cmd which is used to reconfigure filter
* and other flags for the current radio configuration. */
if (!iwl_full_rxon_required(priv)) {
ret = iwl_send_rxon_assoc(priv);
if (!iwl_full_rxon_required(priv, ctx)) {
ret = iwl_send_rxon_assoc(priv, ctx);
if (ret) {
IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
return ret;
}
memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon));
iwl_print_rx_config_cmd(priv);
memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
iwl_print_rx_config_cmd(priv, ctx);
return 0;
}
......@@ -148,13 +148,13 @@ int iwl_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_ctx(ctx) && new_assoc) {
IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
sizeof(struct iwl_rxon_cmd),
&priv->active_rxon);
sizeof(struct iwl_rxon_cmd),
active_rxon);
/* If the mask clearing failed then we set
* active_rxon back to what it was previously */
......@@ -177,10 +177,10 @@ int iwl_commit_rxon(struct iwl_priv *priv)
"* channel = %d\n"
"* bssid = %pM\n",
(new_assoc ? "" : "out"),
le16_to_cpu(priv->staging_rxon.channel),
priv->staging_rxon.bssid_addr);
le16_to_cpu(ctx->staging.channel),
ctx->staging.bssid_addr);
iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto);
iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);