aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-23 04:46:32 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-08-27 11:26:47 -0400
commit246ed355221076884d225f9d8a4c30a048be8162 (patch)
tree64bba3b115c6f0d7ba245c44b81c38e46adec6c8 /drivers/net/wireless/iwlwifi
parent903786a5626e7214d97b232bece88ee75e37d021 (diff)
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: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c53
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-calib.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tt.c26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c172
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c391
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h38
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h62
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-rx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c111
19 files changed, 611 insertions, 400 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 8e84a08ff951..08f53f869c18 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -949,7 +949,8 @@ void iwl3945_rate_scale_init(struct ieee80211_hw *hw, s32 sta_id)
949 switch (priv->band) { 949 switch (priv->band) {
950 case IEEE80211_BAND_2GHZ: 950 case IEEE80211_BAND_2GHZ:
951 /* TODO: this always does G, not a regression */ 951 /* TODO: this always does G, not a regression */
952 if (priv->active_rxon.flags & RXON_FLG_TGG_PROTECT_MSK) { 952 if (priv->contexts[IWL_RXON_CTX_BSS].active.flags &
953 RXON_FLG_TGG_PROTECT_MSK) {
953 rs_sta->tgg = 1; 954 rs_sta->tgg = 1;
954 rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot; 955 rs_sta->expected_tpt = iwl3945_expected_tpt_g_prot;
955 } else 956 } else
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 8ccfcd08218d..f4aa229986ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -245,7 +245,7 @@ int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate)
245 break; 245 break;
246 case IEEE80211_BAND_2GHZ: 246 case IEEE80211_BAND_2GHZ:
247 if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && 247 if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
248 iwl_is_associated(priv)) { 248 iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
249 if (rate == IWL_RATE_11M_INDEX) 249 if (rate == IWL_RATE_11M_INDEX)
250 next_rate = IWL_RATE_5M_INDEX; 250 next_rate = IWL_RATE_5M_INDEX;
251 } 251 }
@@ -1439,17 +1439,18 @@ static int iwl3945_send_tx_power(struct iwl_priv *priv)
1439 int rate_idx, i; 1439 int rate_idx, i;
1440 const struct iwl_channel_info *ch_info = NULL; 1440 const struct iwl_channel_info *ch_info = NULL;
1441 struct iwl3945_txpowertable_cmd txpower = { 1441 struct iwl3945_txpowertable_cmd txpower = {
1442 .channel = priv->active_rxon.channel, 1442 .channel = priv->contexts[IWL_RXON_CTX_BSS].active.channel,
1443 }; 1443 };
1444 u16 chan;
1445
1446 chan = le16_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.channel);
1444 1447
1445 txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1; 1448 txpower.band = (priv->band == IEEE80211_BAND_5GHZ) ? 0 : 1;
1446 ch_info = iwl_get_channel_info(priv, 1449 ch_info = iwl_get_channel_info(priv, priv->band, chan);
1447 priv->band,
1448 le16_to_cpu(priv->active_rxon.channel));
1449 if (!ch_info) { 1450 if (!ch_info) {
1450 IWL_ERR(priv, 1451 IWL_ERR(priv,
1451 "Failed to get channel info for channel %d [%d]\n", 1452 "Failed to get channel info for channel %d [%d]\n",
1452 le16_to_cpu(priv->active_rxon.channel), priv->band); 1453 chan, priv->band);
1453 return -EINVAL; 1454 return -EINVAL;
1454 } 1455 }
1455 1456
@@ -1710,7 +1711,8 @@ int iwl3945_hw_reg_set_txpower(struct iwl_priv *priv, s8 power)
1710 return 0; 1711 return 0;
1711} 1712}
1712 1713
1713static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) 1714static int iwl3945_send_rxon_assoc(struct iwl_priv *priv,
1715 struct iwl_rxon_context *ctx)
1714{ 1716{
1715 int rc = 0; 1717 int rc = 0;
1716 struct iwl_rx_packet *pkt; 1718 struct iwl_rx_packet *pkt;
@@ -1721,8 +1723,8 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
1721 .flags = CMD_WANT_SKB, 1723 .flags = CMD_WANT_SKB,
1722 .data = &rxon_assoc, 1724 .data = &rxon_assoc,
1723 }; 1725 };
1724 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; 1726 const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
1725 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; 1727 const struct iwl_rxon_cmd *rxon2 = &ctx->active;
1726 1728
1727 if ((rxon1->flags == rxon2->flags) && 1729 if ((rxon1->flags == rxon2->flags) &&
1728 (rxon1->filter_flags == rxon2->filter_flags) && 1730 (rxon1->filter_flags == rxon2->filter_flags) &&
@@ -1732,10 +1734,10 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
1732 return 0; 1734 return 0;
1733 } 1735 }
1734 1736
1735 rxon_assoc.flags = priv->staging_rxon.flags; 1737 rxon_assoc.flags = ctx->staging.flags;
1736 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; 1738 rxon_assoc.filter_flags = ctx->staging.filter_flags;
1737 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; 1739 rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
1738 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; 1740 rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
1739 rxon_assoc.reserved = 0; 1741 rxon_assoc.reserved = 0;
1740 1742
1741 rc = iwl_send_cmd_sync(priv, &cmd); 1743 rc = iwl_send_cmd_sync(priv, &cmd);
@@ -1761,14 +1763,14 @@ static int iwl3945_send_rxon_assoc(struct iwl_priv *priv)
1761 * function correctly transitions out of the RXON_ASSOC_MSK state if 1763 * function correctly transitions out of the RXON_ASSOC_MSK state if
1762 * a HW tune is required based on the RXON structure changes. 1764 * a HW tune is required based on the RXON structure changes.
1763 */ 1765 */
1764static int iwl3945_commit_rxon(struct iwl_priv *priv) 1766static int iwl3945_commit_rxon(struct iwl_priv *priv,
1767 struct iwl_rxon_context *ctx)
1765{ 1768{
1766 /* cast away the const for active_rxon in this function */ 1769 /* cast away the const for active_rxon in this function */
1767 struct iwl3945_rxon_cmd *active_rxon = (void *)&priv->active_rxon; 1770 struct iwl3945_rxon_cmd *active_rxon = (void *)&ctx->active;
1768 struct iwl3945_rxon_cmd *staging_rxon = (void *)&priv->staging_rxon; 1771 struct iwl3945_rxon_cmd *staging_rxon = (void *)&ctx->staging;
1769 int rc = 0; 1772 int rc = 0;
1770 bool new_assoc = 1773 bool new_assoc = !!(staging_rxon->filter_flags & RXON_FILTER_ASSOC_MSK);
1771 !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK);
1772 1774
1773 if (!iwl_is_alive(priv)) 1775 if (!iwl_is_alive(priv))
1774 return -1; 1776 return -1;
@@ -1781,7 +1783,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1781 ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK); 1783 ~(RXON_FLG_DIS_DIV_MSK | RXON_FLG_ANT_SEL_MSK);
1782 staging_rxon->flags |= iwl3945_get_antenna_flags(priv); 1784 staging_rxon->flags |= iwl3945_get_antenna_flags(priv);
1783 1785
1784 rc = iwl_check_rxon_cmd(priv); 1786 rc = iwl_check_rxon_cmd(priv, ctx);
1785 if (rc) { 1787 if (rc) {
1786 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); 1788 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
1787 return -EINVAL; 1789 return -EINVAL;
@@ -1790,8 +1792,9 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1790 /* If we don't need to send a full RXON, we can use 1792 /* If we don't need to send a full RXON, we can use
1791 * iwl3945_rxon_assoc_cmd which is used to reconfigure filter 1793 * iwl3945_rxon_assoc_cmd which is used to reconfigure filter
1792 * and other flags for the current radio configuration. */ 1794 * and other flags for the current radio configuration. */
1793 if (!iwl_full_rxon_required(priv)) { 1795 if (!iwl_full_rxon_required(priv, &priv->contexts[IWL_RXON_CTX_BSS])) {
1794 rc = iwl_send_rxon_assoc(priv); 1796 rc = iwl_send_rxon_assoc(priv,
1797 &priv->contexts[IWL_RXON_CTX_BSS]);
1795 if (rc) { 1798 if (rc) {
1796 IWL_ERR(priv, "Error setting RXON_ASSOC " 1799 IWL_ERR(priv, "Error setting RXON_ASSOC "
1797 "configuration (%d).\n", rc); 1800 "configuration (%d).\n", rc);
@@ -1807,7 +1810,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1807 * an RXON_ASSOC and the new config wants the associated mask enabled, 1810 * an RXON_ASSOC and the new config wants the associated mask enabled,
1808 * we must clear the associated from the active configuration 1811 * we must clear the associated from the active configuration
1809 * before we apply the new config */ 1812 * before we apply the new config */
1810 if (iwl_is_associated(priv) && new_assoc) { 1813 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS) && new_assoc) {
1811 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); 1814 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
1812 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1815 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1813 1816
@@ -1819,7 +1822,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1819 active_rxon->reserved5 = 0; 1822 active_rxon->reserved5 = 0;
1820 rc = iwl_send_cmd_pdu(priv, REPLY_RXON, 1823 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
1821 sizeof(struct iwl3945_rxon_cmd), 1824 sizeof(struct iwl3945_rxon_cmd),
1822 &priv->active_rxon); 1825 &priv->contexts[IWL_RXON_CTX_BSS].active);
1823 1826
1824 /* If the mask clearing failed then we set 1827 /* If the mask clearing failed then we set
1825 * active_rxon back to what it was previously */ 1828 * active_rxon back to what it was previously */
@@ -1848,7 +1851,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv)
1848 staging_rxon->reserved4 = 0; 1851 staging_rxon->reserved4 = 0;
1849 staging_rxon->reserved5 = 0; 1852 staging_rxon->reserved5 = 0;
1850 1853
1851 iwl_set_rxon_hwcrypto(priv, !iwl3945_mod_params.sw_crypto); 1854 iwl_set_rxon_hwcrypto(priv, ctx, !iwl3945_mod_params.sw_crypto);
1852 1855
1853 /* Apply the new configuration */ 1856 /* Apply the new configuration */
1854 rc = iwl_send_cmd_pdu(priv, REPLY_RXON, 1857 rc = iwl_send_cmd_pdu(priv, REPLY_RXON,
@@ -2366,7 +2369,7 @@ int iwl3945_init_hw_rate_table(struct iwl_priv *priv)
2366 * 1M CCK rates */ 2369 * 1M CCK rates */
2367 2370
2368 if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) && 2371 if (!(priv->_3945.sta_supp_rates & IWL_OFDM_RATES_MASK) &&
2369 iwl_is_associated(priv)) { 2372 iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
2370 2373
2371 index = IWL_FIRST_CCK_RATE; 2374 index = IWL_FIRST_CCK_RATE;
2372 for (i = IWL_RATE_6M_INDEX_TABLE; 2375 for (i = IWL_RATE_6M_INDEX_TABLE;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index f0a47f42d4b8..82f32305f50e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -347,7 +347,7 @@ static void iwl4965_chain_noise_reset(struct iwl_priv *priv)
347 struct iwl_chain_noise_data *data = &(priv->chain_noise_data); 347 struct iwl_chain_noise_data *data = &(priv->chain_noise_data);
348 348
349 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && 349 if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
350 iwl_is_associated(priv)) { 350 iwl_is_any_associated(priv)) {
351 struct iwl_calib_diff_gain_cmd cmd; 351 struct iwl_calib_diff_gain_cmd cmd;
352 352
353 /* clear data for chain noise calibration algorithm */ 353 /* clear data for chain noise calibration algorithm */
@@ -1374,6 +1374,7 @@ static int iwl4965_send_tx_power(struct iwl_priv *priv)
1374 u8 band = 0; 1374 u8 band = 0;
1375 bool is_ht40 = false; 1375 bool is_ht40 = false;
1376 u8 ctrl_chan_high = 0; 1376 u8 ctrl_chan_high = 0;
1377 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1377 1378
1378 if (test_bit(STATUS_SCANNING, &priv->status)) { 1379 if (test_bit(STATUS_SCANNING, &priv->status)) {
1379 /* If this gets hit a lot, switch it to a BUG() and catch 1380 /* 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)
1385 1386
1386 band = priv->band == IEEE80211_BAND_2GHZ; 1387 band = priv->band == IEEE80211_BAND_2GHZ;
1387 1388
1388 is_ht40 = is_ht40_channel(priv->active_rxon.flags); 1389 is_ht40 = is_ht40_channel(ctx->active.flags);
1389 1390
1390 if (is_ht40 && 1391 if (is_ht40 && (ctx->active.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
1391 (priv->active_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
1392 ctrl_chan_high = 1; 1392 ctrl_chan_high = 1;
1393 1393
1394 cmd.band = band; 1394 cmd.band = band;
1395 cmd.channel = priv->active_rxon.channel; 1395 cmd.channel = ctx->active.channel;
1396 1396
1397 ret = iwl4965_fill_txpower_tbl(priv, band, 1397 ret = iwl4965_fill_txpower_tbl(priv, band,
1398 le16_to_cpu(priv->active_rxon.channel), 1398 le16_to_cpu(ctx->active.channel),
1399 is_ht40, ctrl_chan_high, &cmd.tx_power); 1399 is_ht40, ctrl_chan_high, &cmd.tx_power);
1400 if (ret) 1400 if (ret)
1401 goto out; 1401 goto out;
@@ -1406,12 +1406,13 @@ out:
1406 return ret; 1406 return ret;
1407} 1407}
1408 1408
1409static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) 1409static int iwl4965_send_rxon_assoc(struct iwl_priv *priv,
1410 struct iwl_rxon_context *ctx)
1410{ 1411{
1411 int ret = 0; 1412 int ret = 0;
1412 struct iwl4965_rxon_assoc_cmd rxon_assoc; 1413 struct iwl4965_rxon_assoc_cmd rxon_assoc;
1413 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; 1414 const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
1414 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; 1415 const struct iwl_rxon_cmd *rxon2 = &ctx->active;
1415 1416
1416 if ((rxon1->flags == rxon2->flags) && 1417 if ((rxon1->flags == rxon2->flags) &&
1417 (rxon1->filter_flags == rxon2->filter_flags) && 1418 (rxon1->filter_flags == rxon2->filter_flags) &&
@@ -1426,16 +1427,16 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
1426 return 0; 1427 return 0;
1427 } 1428 }
1428 1429
1429 rxon_assoc.flags = priv->staging_rxon.flags; 1430 rxon_assoc.flags = ctx->staging.flags;
1430 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; 1431 rxon_assoc.filter_flags = ctx->staging.filter_flags;
1431 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; 1432 rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
1432 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; 1433 rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
1433 rxon_assoc.reserved = 0; 1434 rxon_assoc.reserved = 0;
1434 rxon_assoc.ofdm_ht_single_stream_basic_rates = 1435 rxon_assoc.ofdm_ht_single_stream_basic_rates =
1435 priv->staging_rxon.ofdm_ht_single_stream_basic_rates; 1436 ctx->staging.ofdm_ht_single_stream_basic_rates;
1436 rxon_assoc.ofdm_ht_dual_stream_basic_rates = 1437 rxon_assoc.ofdm_ht_dual_stream_basic_rates =
1437 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; 1438 ctx->staging.ofdm_ht_dual_stream_basic_rates;
1438 rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; 1439 rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
1439 1440
1440 ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, 1441 ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
1441 sizeof(rxon_assoc), &rxon_assoc, NULL); 1442 sizeof(rxon_assoc), &rxon_assoc, NULL);
@@ -1448,6 +1449,7 @@ static int iwl4965_send_rxon_assoc(struct iwl_priv *priv)
1448static int iwl4965_hw_channel_switch(struct iwl_priv *priv, 1449static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
1449 struct ieee80211_channel_switch *ch_switch) 1450 struct ieee80211_channel_switch *ch_switch)
1450{ 1451{
1452 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1451 int rc; 1453 int rc;
1452 u8 band = 0; 1454 u8 band = 0;
1453 bool is_ht40 = false; 1455 bool is_ht40 = false;
@@ -1458,22 +1460,22 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
1458 u16 ch; 1460 u16 ch;
1459 u32 tsf_low; 1461 u32 tsf_low;
1460 u8 switch_count; 1462 u8 switch_count;
1461 u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); 1463 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
1462 struct ieee80211_vif *vif = priv->vif; 1464 struct ieee80211_vif *vif = priv->vif;
1463 band = priv->band == IEEE80211_BAND_2GHZ; 1465 band = priv->band == IEEE80211_BAND_2GHZ;
1464 1466
1465 is_ht40 = is_ht40_channel(priv->staging_rxon.flags); 1467 is_ht40 = is_ht40_channel(ctx->staging.flags);
1466 1468
1467 if (is_ht40 && 1469 if (is_ht40 &&
1468 (priv->staging_rxon.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK)) 1470 (ctx->staging.flags & RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK))
1469 ctrl_chan_high = 1; 1471 ctrl_chan_high = 1;
1470 1472
1471 cmd.band = band; 1473 cmd.band = band;
1472 cmd.expect_beacon = 0; 1474 cmd.expect_beacon = 0;
1473 ch = ch_switch->channel->hw_value; 1475 ch = ch_switch->channel->hw_value;
1474 cmd.channel = cpu_to_le16(ch); 1476 cmd.channel = cpu_to_le16(ch);
1475 cmd.rxon_flags = priv->staging_rxon.flags; 1477 cmd.rxon_flags = ctx->staging.flags;
1476 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; 1478 cmd.rxon_filter_flags = ctx->staging.filter_flags;
1477 switch_count = ch_switch->count; 1479 switch_count = ch_switch->count;
1478 tsf_low = ch_switch->timestamp & 0x0ffffffff; 1480 tsf_low = ch_switch->timestamp & 0x0ffffffff;
1479 /* 1481 /*
@@ -1508,7 +1510,7 @@ static int iwl4965_hw_channel_switch(struct iwl_priv *priv,
1508 cmd.expect_beacon = is_channel_radar(ch_info); 1510 cmd.expect_beacon = is_channel_radar(ch_info);
1509 else { 1511 else {
1510 IWL_ERR(priv, "invalid channel switch from %u to %u\n", 1512 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
1511 priv->active_rxon.channel, ch); 1513 ctx->active.channel, ch);
1512 return -EFAULT; 1514 return -EFAULT;
1513 } 1515 }
1514 1516
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 013f3dae69f1..8536f19d7dcc 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -275,13 +275,18 @@ static void iwl5150_temperature(struct iwl_priv *priv)
275static int iwl5000_hw_channel_switch(struct iwl_priv *priv, 275static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
276 struct ieee80211_channel_switch *ch_switch) 276 struct ieee80211_channel_switch *ch_switch)
277{ 277{
278 /*
279 * MULTI-FIXME
280 * See iwl_mac_channel_switch.
281 */
282 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
278 struct iwl5000_channel_switch_cmd cmd; 283 struct iwl5000_channel_switch_cmd cmd;
279 const struct iwl_channel_info *ch_info; 284 const struct iwl_channel_info *ch_info;
280 u32 switch_time_in_usec, ucode_switch_time; 285 u32 switch_time_in_usec, ucode_switch_time;
281 u16 ch; 286 u16 ch;
282 u32 tsf_low; 287 u32 tsf_low;
283 u8 switch_count; 288 u8 switch_count;
284 u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); 289 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
285 struct ieee80211_vif *vif = priv->vif; 290 struct ieee80211_vif *vif = priv->vif;
286 struct iwl_host_cmd hcmd = { 291 struct iwl_host_cmd hcmd = {
287 .id = REPLY_CHANNEL_SWITCH, 292 .id = REPLY_CHANNEL_SWITCH,
@@ -293,10 +298,10 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
293 cmd.band = priv->band == IEEE80211_BAND_2GHZ; 298 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
294 ch = ch_switch->channel->hw_value; 299 ch = ch_switch->channel->hw_value;
295 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n", 300 IWL_DEBUG_11H(priv, "channel switch from %d to %d\n",
296 priv->active_rxon.channel, ch); 301 ctx->active.channel, ch);
297 cmd.channel = cpu_to_le16(ch); 302 cmd.channel = cpu_to_le16(ch);
298 cmd.rxon_flags = priv->staging_rxon.flags; 303 cmd.rxon_flags = ctx->staging.flags;
299 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; 304 cmd.rxon_filter_flags = ctx->staging.filter_flags;
300 switch_count = ch_switch->count; 305 switch_count = ch_switch->count;
301 tsf_low = ch_switch->timestamp & 0x0ffffffff; 306 tsf_low = ch_switch->timestamp & 0x0ffffffff;
302 /* 307 /*
@@ -331,7 +336,7 @@ static int iwl5000_hw_channel_switch(struct iwl_priv *priv,
331 cmd.expect_beacon = is_channel_radar(ch_info); 336 cmd.expect_beacon = is_channel_radar(ch_info);
332 else { 337 else {
333 IWL_ERR(priv, "invalid channel switch from %u to %u\n", 338 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
334 priv->active_rxon.channel, ch); 339 ctx->active.channel, ch);
335 return -EFAULT; 340 return -EFAULT;
336 } 341 }
337 priv->switch_rxon.channel = cmd.channel; 342 priv->switch_rxon.channel = cmd.channel;
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index fc9344b873ba..bf1fe25fae73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -198,13 +198,18 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
198static int iwl6000_hw_channel_switch(struct iwl_priv *priv, 198static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
199 struct ieee80211_channel_switch *ch_switch) 199 struct ieee80211_channel_switch *ch_switch)
200{ 200{
201 /*
202 * MULTI-FIXME
203 * See iwl_mac_channel_switch.
204 */
205 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
201 struct iwl6000_channel_switch_cmd cmd; 206 struct iwl6000_channel_switch_cmd cmd;
202 const struct iwl_channel_info *ch_info; 207 const struct iwl_channel_info *ch_info;
203 u32 switch_time_in_usec, ucode_switch_time; 208 u32 switch_time_in_usec, ucode_switch_time;
204 u16 ch; 209 u16 ch;
205 u32 tsf_low; 210 u32 tsf_low;
206 u8 switch_count; 211 u8 switch_count;
207 u16 beacon_interval = le16_to_cpu(priv->rxon_timing.beacon_interval); 212 u16 beacon_interval = le16_to_cpu(ctx->timing.beacon_interval);
208 struct ieee80211_vif *vif = priv->vif; 213 struct ieee80211_vif *vif = priv->vif;
209 struct iwl_host_cmd hcmd = { 214 struct iwl_host_cmd hcmd = {
210 .id = REPLY_CHANNEL_SWITCH, 215 .id = REPLY_CHANNEL_SWITCH,
@@ -216,10 +221,10 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
216 cmd.band = priv->band == IEEE80211_BAND_2GHZ; 221 cmd.band = priv->band == IEEE80211_BAND_2GHZ;
217 ch = ch_switch->channel->hw_value; 222 ch = ch_switch->channel->hw_value;
218 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n", 223 IWL_DEBUG_11H(priv, "channel switch from %u to %u\n",
219 priv->active_rxon.channel, ch); 224 ctx->active.channel, ch);
220 cmd.channel = cpu_to_le16(ch); 225 cmd.channel = cpu_to_le16(ch);
221 cmd.rxon_flags = priv->staging_rxon.flags; 226 cmd.rxon_flags = ctx->staging.flags;
222 cmd.rxon_filter_flags = priv->staging_rxon.filter_flags; 227 cmd.rxon_filter_flags = ctx->staging.filter_flags;
223 switch_count = ch_switch->count; 228 switch_count = ch_switch->count;
224 tsf_low = ch_switch->timestamp & 0x0ffffffff; 229 tsf_low = ch_switch->timestamp & 0x0ffffffff;
225 /* 230 /*
@@ -254,7 +259,7 @@ static int iwl6000_hw_channel_switch(struct iwl_priv *priv,
254 cmd.expect_beacon = is_channel_radar(ch_info); 259 cmd.expect_beacon = is_channel_radar(ch_info);
255 else { 260 else {
256 IWL_ERR(priv, "invalid channel switch from %u to %u\n", 261 IWL_ERR(priv, "invalid channel switch from %u to %u\n",
257 priv->active_rxon.channel, ch); 262 ctx->active.channel, ch);
258 return -EFAULT; 263 return -EFAULT;
259 } 264 }
260 priv->switch_rxon.channel = cmd.channel; 265 priv->switch_rxon.channel = cmd.channel;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
index 156b125dba71..84ad62958535 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-calib.c
@@ -625,7 +625,7 @@ void iwl_sensitivity_calibration(struct iwl_priv *priv, void *resp)
625 625
626 data = &(priv->sensitivity_data); 626 data = &(priv->sensitivity_data);
627 627
628 if (!iwl_is_associated(priv)) { 628 if (!iwl_is_any_associated(priv)) {
629 IWL_DEBUG_CALIB(priv, "<< - not associated\n"); 629 IWL_DEBUG_CALIB(priv, "<< - not associated\n");
630 return; 630 return;
631 } 631 }
@@ -763,6 +763,12 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
763 unsigned long flags; 763 unsigned long flags;
764 struct statistics_rx_non_phy *rx_info; 764 struct statistics_rx_non_phy *rx_info;
765 u8 first_chain; 765 u8 first_chain;
766 /*
767 * MULTI-FIXME:
768 * When we support multiple interfaces on different channels,
769 * this must be modified/fixed.
770 */
771 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
766 772
767 if (priv->disable_chain_noise_cal) 773 if (priv->disable_chain_noise_cal)
768 return; 774 return;
@@ -793,8 +799,8 @@ void iwl_chain_noise_calibration(struct iwl_priv *priv, void *stat_resp)
793 return; 799 return;
794 } 800 }
795 801
796 rxon_band24 = !!(priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK); 802 rxon_band24 = !!(ctx->staging.flags & RXON_FLG_BAND_24G_MSK);
797 rxon_chnum = le16_to_cpu(priv->staging_rxon.channel); 803 rxon_chnum = le16_to_cpu(ctx->staging.channel);
798 if (priv->cfg->bt_statistics) { 804 if (priv->cfg->bt_statistics) {
799 stat_band24 = !!(((struct iwl_bt_notif_statistics *) 805 stat_band24 = !!(((struct iwl_bt_notif_statistics *)
800 stat_resp)->flag & 806 stat_resp)->flag &
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
index 84fe06adcef4..3e5069943dde 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hcmd.c
@@ -37,12 +37,13 @@
37#include "iwl-io.h" 37#include "iwl-io.h"
38#include "iwl-agn.h" 38#include "iwl-agn.h"
39 39
40int iwlagn_send_rxon_assoc(struct iwl_priv *priv) 40int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
41 struct iwl_rxon_context *ctx)
41{ 42{
42 int ret = 0; 43 int ret = 0;
43 struct iwl5000_rxon_assoc_cmd rxon_assoc; 44 struct iwl5000_rxon_assoc_cmd rxon_assoc;
44 const struct iwl_rxon_cmd *rxon1 = &priv->staging_rxon; 45 const struct iwl_rxon_cmd *rxon1 = &ctx->staging;
45 const struct iwl_rxon_cmd *rxon2 = &priv->active_rxon; 46 const struct iwl_rxon_cmd *rxon2 = &ctx->active;
46 47
47 if ((rxon1->flags == rxon2->flags) && 48 if ((rxon1->flags == rxon2->flags) &&
48 (rxon1->filter_flags == rxon2->filter_flags) && 49 (rxon1->filter_flags == rxon2->filter_flags) &&
@@ -60,21 +61,21 @@ int iwlagn_send_rxon_assoc(struct iwl_priv *priv)
60 return 0; 61 return 0;
61 } 62 }
62 63
63 rxon_assoc.flags = priv->staging_rxon.flags; 64 rxon_assoc.flags = ctx->staging.flags;
64 rxon_assoc.filter_flags = priv->staging_rxon.filter_flags; 65 rxon_assoc.filter_flags = ctx->staging.filter_flags;
65 rxon_assoc.ofdm_basic_rates = priv->staging_rxon.ofdm_basic_rates; 66 rxon_assoc.ofdm_basic_rates = ctx->staging.ofdm_basic_rates;
66 rxon_assoc.cck_basic_rates = priv->staging_rxon.cck_basic_rates; 67 rxon_assoc.cck_basic_rates = ctx->staging.cck_basic_rates;
67 rxon_assoc.reserved1 = 0; 68 rxon_assoc.reserved1 = 0;
68 rxon_assoc.reserved2 = 0; 69 rxon_assoc.reserved2 = 0;
69 rxon_assoc.reserved3 = 0; 70 rxon_assoc.reserved3 = 0;
70 rxon_assoc.ofdm_ht_single_stream_basic_rates = 71 rxon_assoc.ofdm_ht_single_stream_basic_rates =
71 priv->staging_rxon.ofdm_ht_single_stream_basic_rates; 72 ctx->staging.ofdm_ht_single_stream_basic_rates;
72 rxon_assoc.ofdm_ht_dual_stream_basic_rates = 73 rxon_assoc.ofdm_ht_dual_stream_basic_rates =
73 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates; 74 ctx->staging.ofdm_ht_dual_stream_basic_rates;
74 rxon_assoc.rx_chain_select_flags = priv->staging_rxon.rx_chain; 75 rxon_assoc.rx_chain_select_flags = ctx->staging.rx_chain;
75 rxon_assoc.ofdm_ht_triple_stream_basic_rates = 76 rxon_assoc.ofdm_ht_triple_stream_basic_rates =
76 priv->staging_rxon.ofdm_ht_triple_stream_basic_rates; 77 ctx->staging.ofdm_ht_triple_stream_basic_rates;
77 rxon_assoc.acquisition_data = priv->staging_rxon.acquisition_data; 78 rxon_assoc.acquisition_data = ctx->staging.acquisition_data;
78 79
79 ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC, 80 ret = iwl_send_cmd_pdu_async(priv, REPLY_RXON_ASSOC,
80 sizeof(rxon_assoc), &rxon_assoc, NULL); 81 sizeof(rxon_assoc), &rxon_assoc, NULL);
@@ -184,7 +185,7 @@ static void iwlagn_chain_noise_reset(struct iwl_priv *priv)
184 int ret; 185 int ret;
185 186
186 if ((data->state == IWL_CHAIN_NOISE_ALIVE) && 187 if ((data->state == IWL_CHAIN_NOISE_ALIVE) &&
187 iwl_is_associated(priv)) { 188 iwl_is_any_associated(priv)) {
188 struct iwl_calib_chain_noise_reset_cmd cmd; 189 struct iwl_calib_chain_noise_reset_cmd cmd;
189 190
190 /* clear data for chain noise calibration algorithm */ 191 /* clear data for chain noise calibration algorithm */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index a9e69a6213f4..531a7dc3dc72 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1232,7 +1232,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1232 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; 1232 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
1233 scan->quiet_time = IWL_ACTIVE_QUIET_TIME; 1233 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
1234 1234
1235 if (iwl_is_associated(priv)) { 1235 if (iwl_is_any_associated(priv)) {
1236 u16 interval = 0; 1236 u16 interval = 0;
1237 u32 extra; 1237 u32 extra;
1238 u32 suspend_time = 100; 1238 u32 suspend_time = 100;
@@ -1289,7 +1289,9 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1289 switch (priv->scan_band) { 1289 switch (priv->scan_band) {
1290 case IEEE80211_BAND_2GHZ: 1290 case IEEE80211_BAND_2GHZ:
1291 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; 1291 scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK;
1292 chan_mod = le32_to_cpu(priv->active_rxon.flags & RXON_FLG_CHANNEL_MODE_MSK) 1292 chan_mod = le32_to_cpu(
1293 priv->contexts[IWL_RXON_CTX_BSS].active.flags &
1294 RXON_FLG_CHANNEL_MODE_MSK)
1293 >> RXON_FLG_CHANNEL_MODE_POS; 1295 >> RXON_FLG_CHANNEL_MODE_POS;
1294 if (chan_mod == CHANNEL_MODE_PURE_40) { 1296 if (chan_mod == CHANNEL_MODE_PURE_40) {
1295 rate = IWL_RATE_6M_PLCP; 1297 rate = IWL_RATE_6M_PLCP;
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
index 30298ea56a24..07b2c6cadf51 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tt.c
@@ -416,18 +416,26 @@ static void iwl_advance_tt_handler(struct iwl_priv *priv, s32 temp, bool force)
416 /* stop ct_kill_waiting_tm timer */ 416 /* stop ct_kill_waiting_tm timer */
417 del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm); 417 del_timer_sync(&priv->thermal_throttle.ct_kill_waiting_tm);
418 if (changed) { 418 if (changed) {
419 struct iwl_rxon_cmd *rxon = &priv->staging_rxon;
420
421 if (tt->state >= IWL_TI_1) { 419 if (tt->state >= IWL_TI_1) {
422 /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */ 420 /* force PI = IWL_POWER_INDEX_5 in the case of TI > 0 */
423 tt->tt_power_mode = IWL_POWER_INDEX_5; 421 tt->tt_power_mode = IWL_POWER_INDEX_5;
424 if (!iwl_ht_enabled(priv)) 422
425 /* disable HT */ 423 if (!iwl_ht_enabled(priv)) {
426 rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | 424 struct iwl_rxon_context *ctx;
427 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK | 425
428 RXON_FLG_HT40_PROT_MSK | 426 for_each_context(priv, ctx) {
429 RXON_FLG_HT_PROT_MSK); 427 struct iwl_rxon_cmd *rxon;
430 else { 428
429 rxon = &ctx->staging;
430
431 /* disable HT */
432 rxon->flags &= ~(
433 RXON_FLG_CHANNEL_MODE_MSK |
434 RXON_FLG_CTRL_CHANNEL_LOC_HI_MSK |
435 RXON_FLG_HT40_PROT_MSK |
436 RXON_FLG_HT_PROT_MSK);
437 }
438 } else {
431 /* check HT capability and set 439 /* check HT capability and set
432 * according to the system HT capability 440 * according to the system HT capability
433 * in case get disabled before */ 441 * in case get disabled before */
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 5e0d0d527bf0..e073069a44c2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -98,21 +98,21 @@ static bool iwlagn_bt_ch_announce = 1;
98 * function correctly transitions out of the RXON_ASSOC_MSK state if 98 * function correctly transitions out of the RXON_ASSOC_MSK state if
99 * a HW tune is required based on the RXON structure changes. 99 * a HW tune is required based on the RXON structure changes.
100 */ 100 */
101int iwl_commit_rxon(struct iwl_priv *priv) 101int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
102{ 102{
103 /* cast away the const for active_rxon in this function */ 103 /* cast away the const for active_rxon in this function */
104 struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; 104 struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
105 int ret; 105 int ret;
106 bool new_assoc = 106 bool new_assoc =
107 !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); 107 !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
108 108
109 if (!iwl_is_alive(priv)) 109 if (!iwl_is_alive(priv))
110 return -EBUSY; 110 return -EBUSY;
111 111
112 /* always get timestamp with Rx frame */ 112 /* always get timestamp with Rx frame */
113 priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; 113 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
114 114
115 ret = iwl_check_rxon_cmd(priv); 115 ret = iwl_check_rxon_cmd(priv, ctx);
116 if (ret) { 116 if (ret) {
117 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); 117 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
118 return -EINVAL; 118 return -EINVAL;
@@ -123,7 +123,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
123 * abort any previous channel switch if still in process 123 * abort any previous channel switch if still in process
124 */ 124 */
125 if (priv->switch_rxon.switch_in_progress && 125 if (priv->switch_rxon.switch_in_progress &&
126 (priv->switch_rxon.channel != priv->staging_rxon.channel)) { 126 (priv->switch_rxon.channel != ctx->staging.channel)) {
127 IWL_DEBUG_11H(priv, "abort channel switch on %d\n", 127 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
128 le16_to_cpu(priv->switch_rxon.channel)); 128 le16_to_cpu(priv->switch_rxon.channel));
129 iwl_chswitch_done(priv, false); 129 iwl_chswitch_done(priv, false);
@@ -132,15 +132,15 @@ int iwl_commit_rxon(struct iwl_priv *priv)
132 /* If we don't need to send a full RXON, we can use 132 /* If we don't need to send a full RXON, we can use
133 * iwl_rxon_assoc_cmd which is used to reconfigure filter 133 * iwl_rxon_assoc_cmd which is used to reconfigure filter
134 * and other flags for the current radio configuration. */ 134 * and other flags for the current radio configuration. */
135 if (!iwl_full_rxon_required(priv)) { 135 if (!iwl_full_rxon_required(priv, ctx)) {
136 ret = iwl_send_rxon_assoc(priv); 136 ret = iwl_send_rxon_assoc(priv, ctx);
137 if (ret) { 137 if (ret) {
138 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); 138 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
139 return ret; 139 return ret;
140 } 140 }
141 141
142 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 142 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
143 iwl_print_rx_config_cmd(priv); 143 iwl_print_rx_config_cmd(priv, ctx);
144 return 0; 144 return 0;
145 } 145 }
146 146
@@ -148,13 +148,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
148 * an RXON_ASSOC and the new config wants the associated mask enabled, 148 * an RXON_ASSOC and the new config wants the associated mask enabled,
149 * we must clear the associated from the active configuration 149 * we must clear the associated from the active configuration
150 * before we apply the new config */ 150 * before we apply the new config */
151 if (iwl_is_associated(priv) && new_assoc) { 151 if (iwl_is_associated_ctx(ctx) && new_assoc) {
152 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); 152 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
153 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 153 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
154 154
155 ret = iwl_send_cmd_pdu(priv, REPLY_RXON, 155 ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
156 sizeof(struct iwl_rxon_cmd), 156 sizeof(struct iwl_rxon_cmd),
157 &priv->active_rxon); 157 active_rxon);
158 158
159 /* If the mask clearing failed then we set 159 /* If the mask clearing failed then we set
160 * active_rxon back to what it was previously */ 160 * active_rxon back to what it was previously */
@@ -177,10 +177,10 @@ int iwl_commit_rxon(struct iwl_priv *priv)
177 "* channel = %d\n" 177 "* channel = %d\n"
178 "* bssid = %pM\n", 178 "* bssid = %pM\n",
179 (new_assoc ? "" : "out"), 179 (new_assoc ? "" : "out"),
180 le16_to_cpu(priv->staging_rxon.channel), 180 le16_to_cpu(ctx->staging.channel),
181 priv->staging_rxon.bssid_addr); 181 ctx->staging.bssid_addr);
182 182
183 iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); 183 iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
184 184
185 /* Apply the new configuration 185 /* Apply the new configuration
186 * RXON unassoc clears the station table in uCode so restoration of 186 * RXON unassoc clears the station table in uCode so restoration of
@@ -188,13 +188,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
188 */ 188 */
189 if (!new_assoc) { 189 if (!new_assoc) {
190 ret = iwl_send_cmd_pdu(priv, REPLY_RXON, 190 ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
191 sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); 191 sizeof(struct iwl_rxon_cmd), &ctx->staging);
192 if (ret) { 192 if (ret) {
193 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); 193 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
194 return ret; 194 return ret;
195 } 195 }
196 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); 196 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
197 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 197 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
198 iwl_clear_ucode_stations(priv); 198 iwl_clear_ucode_stations(priv);
199 iwl_restore_stations(priv); 199 iwl_restore_stations(priv);
200 ret = iwl_restore_default_wep_keys(priv); 200 ret = iwl_restore_default_wep_keys(priv);
@@ -210,14 +210,14 @@ int iwl_commit_rxon(struct iwl_priv *priv)
210 * RXON assoc doesn't clear the station table in uCode, 210 * RXON assoc doesn't clear the station table in uCode,
211 */ 211 */
212 ret = iwl_send_cmd_pdu(priv, REPLY_RXON, 212 ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
213 sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); 213 sizeof(struct iwl_rxon_cmd), &ctx->staging);
214 if (ret) { 214 if (ret) {
215 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); 215 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
216 return ret; 216 return ret;
217 } 217 }
218 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 218 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
219 } 219 }
220 iwl_print_rx_config_cmd(priv); 220 iwl_print_rx_config_cmd(priv, ctx);
221 221
222 iwl_init_sensitivity(priv); 222 iwl_init_sensitivity(priv);
223 223
@@ -234,10 +234,14 @@ int iwl_commit_rxon(struct iwl_priv *priv)
234 234
235void iwl_update_chain_flags(struct iwl_priv *priv) 235void iwl_update_chain_flags(struct iwl_priv *priv)
236{ 236{
237 struct iwl_rxon_context *ctx;
237 238
238 if (priv->cfg->ops->hcmd->set_rxon_chain) 239 if (priv->cfg->ops->hcmd->set_rxon_chain) {
239 priv->cfg->ops->hcmd->set_rxon_chain(priv); 240 for_each_context(priv, ctx) {
240 iwlcore_commit_rxon(priv); 241 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
242 iwlcore_commit_rxon(priv, ctx);
243 }
244 }
241} 245}
242 246
243static void iwl_clear_free_frames(struct iwl_priv *priv) 247static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -633,6 +637,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
633{ 637{
634 struct iwl_priv *priv = 638 struct iwl_priv *priv =
635 container_of(work, struct iwl_priv, bt_full_concurrency); 639 container_of(work, struct iwl_priv, bt_full_concurrency);
640 struct iwl_rxon_context *ctx;
636 641
637 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 642 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
638 return; 643 return;
@@ -649,9 +654,13 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
649 * LQ & RXON updated cmds must be sent before BT Config cmd 654 * LQ & RXON updated cmds must be sent before BT Config cmd
650 * to avoid 3-wire collisions 655 * to avoid 3-wire collisions
651 */ 656 */
652 if (priv->cfg->ops->hcmd->set_rxon_chain) 657 mutex_lock(&priv->mutex);
653 priv->cfg->ops->hcmd->set_rxon_chain(priv); 658 for_each_context(priv, ctx) {
654 iwlcore_commit_rxon(priv); 659 if (priv->cfg->ops->hcmd->set_rxon_chain)
660 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
661 iwlcore_commit_rxon(priv, ctx);
662 }
663 mutex_unlock(&priv->mutex);
655 664
656 priv->cfg->ops->hcmd->send_bt_config(priv); 665 priv->cfg->ops->hcmd->send_bt_config(priv);
657} 666}
@@ -2710,6 +2719,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
2710static void iwl_alive_start(struct iwl_priv *priv) 2719static void iwl_alive_start(struct iwl_priv *priv)
2711{ 2720{
2712 int ret = 0; 2721 int ret = 0;
2722 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2713 2723
2714 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); 2724 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
2715 2725
@@ -2758,18 +2768,18 @@ static void iwl_alive_start(struct iwl_priv *priv)
2758 if (priv->cfg->ops->hcmd->set_tx_ant) 2768 if (priv->cfg->ops->hcmd->set_tx_ant)
2759 priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant); 2769 priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant);
2760 2770
2761 if (iwl_is_associated(priv)) { 2771 if (iwl_is_associated_ctx(ctx)) {
2762 struct iwl_rxon_cmd *active_rxon = 2772 struct iwl_rxon_cmd *active_rxon =
2763 (struct iwl_rxon_cmd *)&priv->active_rxon; 2773 (struct iwl_rxon_cmd *)&ctx->active;
2764 /* apply any changes in staging */ 2774 /* apply any changes in staging */
2765 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 2775 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2766 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2776 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2767 } else { 2777 } else {
2768 /* Initialize our rx_config data */ 2778 /* Initialize our rx_config data */
2769 iwl_connection_init_rx_config(priv, NULL); 2779 iwl_connection_init_rx_config(priv, NULL);
2770 2780
2771 if (priv->cfg->ops->hcmd->set_rxon_chain) 2781 if (priv->cfg->ops->hcmd->set_rxon_chain)
2772 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2782 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2773 } 2783 }
2774 2784
2775 if (!priv->cfg->advanced_bt_coexist) { 2785 if (!priv->cfg->advanced_bt_coexist) {
@@ -2780,7 +2790,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
2780 iwl_reset_run_time_calib(priv); 2790 iwl_reset_run_time_calib(priv);
2781 2791
2782 /* Configure the adapter for unassociated operation */ 2792 /* Configure the adapter for unassociated operation */
2783 iwlcore_commit_rxon(priv); 2793 iwlcore_commit_rxon(priv, ctx);
2784 2794
2785 /* At this point, the NIC is initialized and operational */ 2795 /* At this point, the NIC is initialized and operational */
2786 iwl_rf_kill_ct_config(priv); 2796 iwl_rf_kill_ct_config(priv);
@@ -3195,12 +3205,15 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
3195 3205
3196void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) 3206void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3197{ 3207{
3208 struct iwl_rxon_context *ctx;
3198 struct ieee80211_conf *conf = NULL; 3209 struct ieee80211_conf *conf = NULL;
3199 int ret = 0; 3210 int ret = 0;
3200 3211
3201 if (!vif || !priv->is_open) 3212 if (!vif || !priv->is_open)
3202 return; 3213 return;
3203 3214
3215 ctx = iwl_rxon_ctx_from_vif(vif);
3216
3204 if (vif->type == NL80211_IFTYPE_AP) { 3217 if (vif->type == NL80211_IFTYPE_AP) {
3205 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 3218 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
3206 return; 3219 return;
@@ -3213,42 +3226,42 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3213 3226
3214 conf = ieee80211_get_hw_conf(priv->hw); 3227 conf = ieee80211_get_hw_conf(priv->hw);
3215 3228
3216 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3229 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3217 iwlcore_commit_rxon(priv); 3230 iwlcore_commit_rxon(priv, ctx);
3218 3231
3219 ret = iwl_send_rxon_timing(priv, vif); 3232 ret = iwl_send_rxon_timing(priv, vif);
3220 if (ret) 3233 if (ret)
3221 IWL_WARN(priv, "REPLY_RXON_TIMING failed - " 3234 IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
3222 "Attempting to continue.\n"); 3235 "Attempting to continue.\n");
3223 3236
3224 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3237 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3225 3238
3226 iwl_set_rxon_ht(priv, &priv->current_ht_config); 3239 iwl_set_rxon_ht(priv, &priv->current_ht_config);
3227 3240
3228 if (priv->cfg->ops->hcmd->set_rxon_chain) 3241 if (priv->cfg->ops->hcmd->set_rxon_chain)
3229 priv->cfg->ops->hcmd->set_rxon_chain(priv); 3242 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
3230 3243
3231 priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid); 3244 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
3232 3245
3233 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3246 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3234 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3247 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3235 3248
3236 if (vif->bss_conf.use_short_preamble) 3249 if (vif->bss_conf.use_short_preamble)
3237 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3250 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3238 else 3251 else
3239 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3252 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3240 3253
3241 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3254 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3242 if (vif->bss_conf.use_short_slot) 3255 if (vif->bss_conf.use_short_slot)
3243 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3256 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
3244 else 3257 else
3245 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3258 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3246 } 3259 }
3247 3260
3248 iwlcore_commit_rxon(priv); 3261 iwlcore_commit_rxon(priv, ctx);
3249 3262
3250 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 3263 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3251 vif->bss_conf.aid, priv->active_rxon.bssid_addr); 3264 vif->bss_conf.aid, ctx->active.bssid_addr);
3252 3265
3253 switch (vif->type) { 3266 switch (vif->type) {
3254 case NL80211_IFTYPE_STATION: 3267 case NL80211_IFTYPE_STATION:
@@ -3439,17 +3452,18 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3439 3452
3440void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) 3453void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3441{ 3454{
3455 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
3442 int ret = 0; 3456 int ret = 0;
3443 3457
3444 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3458 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3445 return; 3459 return;
3446 3460
3447 /* The following should be done only at AP bring up */ 3461 /* The following should be done only at AP bring up */
3448 if (!iwl_is_associated(priv)) { 3462 if (!iwl_is_associated_ctx(ctx)) {
3449 3463
3450 /* RXON - unassoc (to set timing command) */ 3464 /* RXON - unassoc (to set timing command) */
3451 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3465 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3452 iwlcore_commit_rxon(priv); 3466 iwlcore_commit_rxon(priv, ctx);
3453 3467
3454 /* RXON Timing */ 3468 /* RXON Timing */
3455 ret = iwl_send_rxon_timing(priv, vif); 3469 ret = iwl_send_rxon_timing(priv, vif);
@@ -3462,28 +3476,28 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3462 priv->hw_params.valid_rx_ant; 3476 priv->hw_params.valid_rx_ant;
3463 iwl_set_rxon_ht(priv, &priv->current_ht_config); 3477 iwl_set_rxon_ht(priv, &priv->current_ht_config);
3464 if (priv->cfg->ops->hcmd->set_rxon_chain) 3478 if (priv->cfg->ops->hcmd->set_rxon_chain)
3465 priv->cfg->ops->hcmd->set_rxon_chain(priv); 3479 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
3466 3480
3467 priv->staging_rxon.assoc_id = 0; 3481 ctx->staging.assoc_id = 0;
3468 3482
3469 if (vif->bss_conf.use_short_preamble) 3483 if (vif->bss_conf.use_short_preamble)
3470 priv->staging_rxon.flags |= 3484 ctx->staging.flags |=
3471 RXON_FLG_SHORT_PREAMBLE_MSK; 3485 RXON_FLG_SHORT_PREAMBLE_MSK;
3472 else 3486 else
3473 priv->staging_rxon.flags &= 3487 ctx->staging.flags &=
3474 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3488 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3475 3489
3476 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3490 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3477 if (vif->bss_conf.use_short_slot) 3491 if (vif->bss_conf.use_short_slot)
3478 priv->staging_rxon.flags |= 3492 ctx->staging.flags |=
3479 RXON_FLG_SHORT_SLOT_MSK; 3493 RXON_FLG_SHORT_SLOT_MSK;
3480 else 3494 else
3481 priv->staging_rxon.flags &= 3495 ctx->staging.flags &=
3482 ~RXON_FLG_SHORT_SLOT_MSK; 3496 ~RXON_FLG_SHORT_SLOT_MSK;
3483 } 3497 }
3484 /* restore RXON assoc */ 3498 /* restore RXON assoc */
3485 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3499 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3486 iwlcore_commit_rxon(priv); 3500 iwlcore_commit_rxon(priv, ctx);
3487 } 3501 }
3488 iwl_send_beacon_cmd(priv); 3502 iwl_send_beacon_cmd(priv);
3489 3503
@@ -3737,6 +3751,15 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
3737 struct ieee80211_conf *conf = &hw->conf; 3751 struct ieee80211_conf *conf = &hw->conf;
3738 struct ieee80211_channel *channel = ch_switch->channel; 3752 struct ieee80211_channel *channel = ch_switch->channel;
3739 struct iwl_ht_config *ht_conf = &priv->current_ht_config; 3753 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
3754 /*
3755 * MULTI-FIXME
3756 * When we add support for multiple interfaces, we need to
3757 * revisit this. The channel switch command in the device
3758 * only affects the BSS context, but what does that really
3759 * mean? And what if we get a CSA on the second interface?
3760 * This needs a lot of work.
3761 */
3762 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3740 u16 ch; 3763 u16 ch;
3741 unsigned long flags = 0; 3764 unsigned long flags = 0;
3742 3765
@@ -3749,7 +3772,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
3749 test_bit(STATUS_SCANNING, &priv->status)) 3772 test_bit(STATUS_SCANNING, &priv->status))
3750 goto out_exit; 3773 goto out_exit;
3751 3774
3752 if (!iwl_is_associated(priv)) 3775 if (!iwl_is_associated_ctx(ctx))
3753 goto out_exit; 3776 goto out_exit;
3754 3777
3755 /* channel switch in progress */ 3778 /* channel switch in progress */
@@ -3760,7 +3783,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
3760 if (priv->cfg->ops->lib->set_channel_switch) { 3783 if (priv->cfg->ops->lib->set_channel_switch) {
3761 3784
3762 ch = channel->hw_value; 3785 ch = channel->hw_value;
3763 if (le16_to_cpu(priv->active_rxon.channel) != ch) { 3786 if (le16_to_cpu(ctx->active.channel) != ch) {
3764 ch_info = iwl_get_channel_info(priv, 3787 ch_info = iwl_get_channel_info(priv,
3765 channel->band, 3788 channel->band,
3766 ch); 3789 ch);
@@ -3791,12 +3814,12 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
3791 } else 3814 } else
3792 ht_conf->is_40mhz = false; 3815 ht_conf->is_40mhz = false;
3793 3816
3794 if (le16_to_cpu(priv->staging_rxon.channel) != ch) 3817 if ((le16_to_cpu(ctx->staging.channel) != ch))
3795 priv->staging_rxon.flags = 0; 3818 ctx->staging.flags = 0;
3796 3819
3797 iwl_set_rxon_channel(priv, channel); 3820 iwl_set_rxon_channel(priv, channel, ctx);
3798 iwl_set_rxon_ht(priv, ht_conf); 3821 iwl_set_rxon_ht(priv, ht_conf);
3799 iwl_set_flags_for_band(priv, channel->band, 3822 iwl_set_flags_for_band(priv, ctx, channel->band,
3800 priv->vif); 3823 priv->vif);
3801 spin_unlock_irqrestore(&priv->lock, flags); 3824 spin_unlock_irqrestore(&priv->lock, flags);
3802 3825
@@ -3825,6 +3848,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
3825{ 3848{
3826 struct iwl_priv *priv = hw->priv; 3849 struct iwl_priv *priv = hw->priv;
3827 __le32 filter_or = 0, filter_nand = 0; 3850 __le32 filter_or = 0, filter_nand = 0;
3851 struct iwl_rxon_context *ctx;
3828 3852
3829#define CHK(test, flag) do { \ 3853#define CHK(test, flag) do { \
3830 if (*total_flags & (test)) \ 3854 if (*total_flags & (test)) \
@@ -3844,10 +3868,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
3844 3868
3845 mutex_lock(&priv->mutex); 3869 mutex_lock(&priv->mutex);
3846 3870
3847 priv->staging_rxon.filter_flags &= ~filter_nand; 3871 for_each_context(priv, ctx) {
3848 priv->staging_rxon.filter_flags |= filter_or; 3872 ctx->staging.filter_flags &= ~filter_nand;
3849 3873 ctx->staging.filter_flags |= filter_or;
3850 iwlcore_commit_rxon(priv); 3874 iwlcore_commit_rxon(priv, ctx);
3875 }
3851 3876
3852 mutex_unlock(&priv->mutex); 3877 mutex_unlock(&priv->mutex);
3853 3878
@@ -4018,7 +4043,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
4018 4043
4019 /* Choose which receivers/antennas to use */ 4044 /* Choose which receivers/antennas to use */
4020 if (priv->cfg->ops->hcmd->set_rxon_chain) 4045 if (priv->cfg->ops->hcmd->set_rxon_chain)
4021 priv->cfg->ops->hcmd->set_rxon_chain(priv); 4046 priv->cfg->ops->hcmd->set_rxon_chain(priv,
4047 &priv->contexts[IWL_RXON_CTX_BSS]);
4022 4048
4023 iwl_init_scan_params(priv); 4049 iwl_init_scan_params(priv);
4024 4050
@@ -4118,7 +4144,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
4118 4144
4119static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 4145static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4120{ 4146{
4121 int err = 0; 4147 int err = 0, i;
4122 struct iwl_priv *priv; 4148 struct iwl_priv *priv;
4123 struct ieee80211_hw *hw; 4149 struct ieee80211_hw *hw;
4124 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); 4150 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
@@ -4146,6 +4172,16 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4146 priv = hw->priv; 4172 priv = hw->priv;
4147 /* At this point both hw and priv are allocated. */ 4173 /* At this point both hw and priv are allocated. */
4148 4174
4175 /*
4176 * The default context is always valid,
4177 * more may be discovered when firmware
4178 * is loaded.
4179 */
4180 priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
4181
4182 for (i = 0; i < NUM_IWL_RXON_CTX; i++)
4183 priv->contexts[i].ctxid = i;
4184
4149 SET_IEEE80211_DEV(hw, &pdev->dev); 4185 SET_IEEE80211_DEV(hw, &pdev->dev);
4150 4186
4151 IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); 4187 IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 1a7f70f293a0..7c542a8c8f81 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -224,7 +224,8 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
224 struct ieee80211_vif *vif, bool add); 224 struct ieee80211_vif *vif, bool add);
225 225
226/* hcmd */ 226/* hcmd */
227int iwlagn_send_rxon_assoc(struct iwl_priv *priv); 227int iwlagn_send_rxon_assoc(struct iwl_priv *priv,
228 struct iwl_rxon_context *ctx);
228int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); 229int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant);
229 230
230/* bt coex */ 231/* bt coex */
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index c43124c997cc..cc88401960e4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -465,6 +465,9 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
465 struct ieee80211_sta_ht_cap *sta_ht_inf) 465 struct ieee80211_sta_ht_cap *sta_ht_inf)
466{ 466{
467 struct iwl_ht_config *ht_conf = &priv->current_ht_config; 467 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
468#if !TODO
469 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
470#endif
468 471
469 if (!ht_conf->is_ht || !ht_conf->is_40mhz) 472 if (!ht_conf->is_ht || !ht_conf->is_40mhz)
470 return 0; 473 return 0;
@@ -481,7 +484,7 @@ u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
481 return 0; 484 return 0;
482#endif 485#endif
483 return iwl_is_channel_extension(priv, priv->band, 486 return iwl_is_channel_extension(priv, priv->band,
484 le16_to_cpu(priv->staging_rxon.channel), 487 le16_to_cpu(ctx->staging.channel),
485 ht_conf->extension_chan_offset); 488 ht_conf->extension_chan_offset);
486} 489}
487EXPORT_SYMBOL(iwl_is_ht40_tx_allowed); 490EXPORT_SYMBOL(iwl_is_ht40_tx_allowed);
@@ -506,49 +509,51 @@ int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif)
506 s32 interval_tm, rem; 509 s32 interval_tm, rem;
507 struct ieee80211_conf *conf = NULL; 510 struct ieee80211_conf *conf = NULL;
508 u16 beacon_int; 511 u16 beacon_int;
512 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
509 513
510 conf = ieee80211_get_hw_conf(priv->hw); 514 conf = ieee80211_get_hw_conf(priv->hw);
511 515
512 lockdep_assert_held(&priv->mutex); 516 lockdep_assert_held(&priv->mutex);
513 517
514 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); 518 memset(&ctx->timing, 0, sizeof(struct iwl_rxon_time_cmd));
515 519
516 priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp); 520 ctx->timing.timestamp = cpu_to_le64(priv->timestamp);
517 priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval); 521 ctx->timing.listen_interval = cpu_to_le16(conf->listen_interval);
518 522
519 beacon_int = vif->bss_conf.beacon_int; 523 beacon_int = vif->bss_conf.beacon_int;
520 524
521 if (vif->type == NL80211_IFTYPE_ADHOC) { 525 if (vif->type == NL80211_IFTYPE_ADHOC) {
522 /* TODO: we need to get atim_window from upper stack 526 /* TODO: we need to get atim_window from upper stack
523 * for now we set to 0 */ 527 * for now we set to 0 */
524 priv->rxon_timing.atim_window = 0; 528 ctx->timing.atim_window = 0;
525 } else { 529 } else {
526 priv->rxon_timing.atim_window = 0; 530 ctx->timing.atim_window = 0;
527 } 531 }
528 532
529 beacon_int = iwl_adjust_beacon_interval(beacon_int, 533 beacon_int = iwl_adjust_beacon_interval(beacon_int,
530 priv->hw_params.max_beacon_itrvl * TIME_UNIT); 534 priv->hw_params.max_beacon_itrvl * TIME_UNIT);
531 priv->rxon_timing.beacon_interval = cpu_to_le16(beacon_int); 535 ctx->timing.beacon_interval = cpu_to_le16(beacon_int);
532 536
533 tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */ 537 tsf = priv->timestamp; /* tsf is modifed by do_div: copy it */
534 interval_tm = beacon_int * TIME_UNIT; 538 interval_tm = beacon_int * TIME_UNIT;
535 rem = do_div(tsf, interval_tm); 539 rem = do_div(tsf, interval_tm);
536 priv->rxon_timing.beacon_init_val = cpu_to_le32(interval_tm - rem); 540 ctx->timing.beacon_init_val = cpu_to_le32(interval_tm - rem);
537 541
538 IWL_DEBUG_ASSOC(priv, 542 IWL_DEBUG_ASSOC(priv,
539 "beacon interval %d beacon timer %d beacon tim %d\n", 543 "beacon interval %d beacon timer %d beacon tim %d\n",
540 le16_to_cpu(priv->rxon_timing.beacon_interval), 544 le16_to_cpu(ctx->timing.beacon_interval),
541 le32_to_cpu(priv->rxon_timing.beacon_init_val), 545 le32_to_cpu(ctx->timing.beacon_init_val),
542 le16_to_cpu(priv->rxon_timing.atim_window)); 546 le16_to_cpu(ctx->timing.atim_window));
543 547
544 return iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 548 return iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
545 sizeof(priv->rxon_timing), &priv->rxon_timing); 549 sizeof(ctx->timing), &ctx->timing);
546} 550}
547EXPORT_SYMBOL(iwl_send_rxon_timing); 551EXPORT_SYMBOL(iwl_send_rxon_timing);
548 552
549void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) 553void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
554 int hw_decrypt)
550{ 555{
551 struct iwl_rxon_cmd *rxon = &priv->staging_rxon; 556 struct iwl_rxon_cmd *rxon = &ctx->staging;
552 557
553 if (hw_decrypt) 558 if (hw_decrypt)
554 rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK; 559 rxon->filter_flags &= ~RXON_FILTER_DIS_DECRYPT_MSK;
@@ -565,11 +570,11 @@ EXPORT_SYMBOL(iwl_set_rxon_hwcrypto);
565 * be #ifdef'd out once the driver is stable and folks aren't actively 570 * be #ifdef'd out once the driver is stable and folks aren't actively
566 * making changes 571 * making changes
567 */ 572 */
568int iwl_check_rxon_cmd(struct iwl_priv *priv) 573int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
569{ 574{
570 int error = 0; 575 int error = 0;
571 int counter = 1; 576 int counter = 1;
572 struct iwl_rxon_cmd *rxon = &priv->staging_rxon; 577 struct iwl_rxon_cmd *rxon = &ctx->staging;
573 578
574 if (rxon->flags & RXON_FLG_BAND_24G_MSK) { 579 if (rxon->flags & RXON_FLG_BAND_24G_MSK) {
575 error |= le32_to_cpu(rxon->flags & 580 error |= le32_to_cpu(rxon->flags &
@@ -641,43 +646,57 @@ EXPORT_SYMBOL(iwl_check_rxon_cmd);
641 * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that 646 * or is clearing the RXON_FILTER_ASSOC_MSK, then return 1 to indicate that
642 * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required. 647 * a new tune (full RXON command, rather than RXON_ASSOC cmd) is required.
643 */ 648 */
644int iwl_full_rxon_required(struct iwl_priv *priv) 649int iwl_full_rxon_required(struct iwl_priv *priv,
650 struct iwl_rxon_context *ctx)
645{ 651{
652 const struct iwl_rxon_cmd *staging = &ctx->staging;
653 const struct iwl_rxon_cmd *active = &ctx->active;
654
655#define CHK(cond) \
656 if ((cond)) { \
657 IWL_DEBUG_INFO(priv, "need full RXON - " #cond "\n"); \
658 return 1; \
659 }
660
661#define CHK_NEQ(c1, c2) \
662 if ((c1) != (c2)) { \
663 IWL_DEBUG_INFO(priv, "need full RXON - " \
664 #c1 " != " #c2 " - %d != %d\n", \
665 (c1), (c2)); \
666 return 1; \
667 }
646 668
647 /* These items are only settable from the full RXON command */ 669 /* These items are only settable from the full RXON command */
648 if (!(iwl_is_associated(priv)) || 670 CHK(!iwl_is_associated_ctx(ctx));
649 compare_ether_addr(priv->staging_rxon.bssid_addr, 671 CHK(compare_ether_addr(staging->bssid_addr, active->bssid_addr));
650 priv->active_rxon.bssid_addr) || 672 CHK(compare_ether_addr(staging->node_addr, active->node_addr));
651 compare_ether_addr(priv->staging_rxon.node_addr, 673 CHK(compare_ether_addr(staging->wlap_bssid_addr,
652 priv->active_rxon.node_addr) || 674 active->wlap_bssid_addr));
653 compare_ether_addr(priv->staging_rxon.wlap_bssid_addr, 675 CHK_NEQ(staging->dev_type, active->dev_type);
654 priv->active_rxon.wlap_bssid_addr) || 676 CHK_NEQ(staging->channel, active->channel);
655 (priv->staging_rxon.dev_type != priv->active_rxon.dev_type) || 677 CHK_NEQ(staging->air_propagation, active->air_propagation);
656 (priv->staging_rxon.channel != priv->active_rxon.channel) || 678 CHK_NEQ(staging->ofdm_ht_single_stream_basic_rates,
657 (priv->staging_rxon.air_propagation != 679 active->ofdm_ht_single_stream_basic_rates);
658 priv->active_rxon.air_propagation) || 680 CHK_NEQ(staging->ofdm_ht_dual_stream_basic_rates,
659 (priv->staging_rxon.ofdm_ht_single_stream_basic_rates != 681 active->ofdm_ht_dual_stream_basic_rates);
660 priv->active_rxon.ofdm_ht_single_stream_basic_rates) || 682 CHK_NEQ(staging->ofdm_ht_triple_stream_basic_rates,
661 (priv->staging_rxon.ofdm_ht_dual_stream_basic_rates != 683 active->ofdm_ht_triple_stream_basic_rates);
662 priv->active_rxon.ofdm_ht_dual_stream_basic_rates) || 684 CHK_NEQ(staging->assoc_id, active->assoc_id);
663 (priv->staging_rxon.ofdm_ht_triple_stream_basic_rates !=
664 priv->active_rxon.ofdm_ht_triple_stream_basic_rates) ||
665 (priv->staging_rxon.assoc_id != priv->active_rxon.assoc_id))
666 return 1;
667 685
668 /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can 686 /* flags, filter_flags, ofdm_basic_rates, and cck_basic_rates can
669 * be updated with the RXON_ASSOC command -- however only some 687 * be updated with the RXON_ASSOC command -- however only some
670 * flag transitions are allowed using RXON_ASSOC */ 688 * flag transitions are allowed using RXON_ASSOC */
671 689
672 /* Check if we are not switching bands */ 690 /* Check if we are not switching bands */
673 if ((priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) != 691 CHK_NEQ(staging->flags & RXON_FLG_BAND_24G_MSK,
674 (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK)) 692 active->flags & RXON_FLG_BAND_24G_MSK);
675 return 1;
676 693
677 /* Check if we are switching association toggle */ 694 /* Check if we are switching association toggle */
678 if ((priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) != 695 CHK_NEQ(staging->filter_flags & RXON_FILTER_ASSOC_MSK,
679 (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK)) 696 active->filter_flags & RXON_FILTER_ASSOC_MSK);
680 return 1; 697
698#undef CHK
699#undef CHK_NEQ
681 700
682 return 0; 701 return 0;
683} 702}
@@ -685,20 +704,25 @@ EXPORT_SYMBOL(iwl_full_rxon_required);
685 704
686u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) 705u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv)
687{ 706{
707#if !TODO
708 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
709#endif
688 /* 710 /*
689 * Assign the lowest rate -- should really get this from 711 * Assign the lowest rate -- should really get this from
690 * the beacon skb from mac80211. 712 * the beacon skb from mac80211.
691 */ 713 */
692 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) 714 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK)
693 return IWL_RATE_1M_PLCP; 715 return IWL_RATE_1M_PLCP;
694 else 716 else
695 return IWL_RATE_6M_PLCP; 717 return IWL_RATE_6M_PLCP;
696} 718}
697EXPORT_SYMBOL(iwl_rate_get_lowest_plcp); 719EXPORT_SYMBOL(iwl_rate_get_lowest_plcp);
698 720
699void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) 721static void _iwl_set_rxon_ht(struct iwl_priv *priv,
722 struct iwl_ht_config *ht_conf,
723 struct iwl_rxon_context *ctx)
700{ 724{
701 struct iwl_rxon_cmd *rxon = &priv->staging_rxon; 725 struct iwl_rxon_cmd *rxon = &ctx->staging;
702 726
703 if (!ht_conf->is_ht) { 727 if (!ht_conf->is_ht) {
704 rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK | 728 rxon->flags &= ~(RXON_FLG_CHANNEL_MODE_MSK |
@@ -754,13 +778,21 @@ void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
754 } 778 }
755 779
756 if (priv->cfg->ops->hcmd->set_rxon_chain) 780 if (priv->cfg->ops->hcmd->set_rxon_chain)
757 priv->cfg->ops->hcmd->set_rxon_chain(priv); 781 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
758 782
759 IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X " 783 IWL_DEBUG_ASSOC(priv, "rxon flags 0x%X operation mode :0x%X "
760 "extension channel offset 0x%x\n", 784 "extension channel offset 0x%x\n",
761 le32_to_cpu(rxon->flags), ht_conf->ht_protection, 785 le32_to_cpu(rxon->flags), ht_conf->ht_protection,
762 ht_conf->extension_chan_offset); 786 ht_conf->extension_chan_offset);
763} 787}
788
789void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf)
790{
791 struct iwl_rxon_context *ctx;
792
793 for_each_context(priv, ctx)
794 _iwl_set_rxon_ht(priv, ht_conf, ctx);
795}
764EXPORT_SYMBOL(iwl_set_rxon_ht); 796EXPORT_SYMBOL(iwl_set_rxon_ht);
765 797
766#define IWL_NUM_RX_CHAINS_MULTIPLE 3 798#define IWL_NUM_RX_CHAINS_MULTIPLE 3
@@ -832,7 +864,7 @@ static u8 iwl_count_chain_bitmap(u32 chain_bitmap)
832 * Selects how many and which Rx receivers/antennas/chains to use. 864 * Selects how many and which Rx receivers/antennas/chains to use.
833 * This should not be used for scan command ... it puts data in wrong place. 865 * This should not be used for scan command ... it puts data in wrong place.
834 */ 866 */
835void iwl_set_rxon_chain(struct iwl_priv *priv) 867void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
836{ 868{
837 bool is_single = is_single_rx_stream(priv); 869 bool is_single = is_single_rx_stream(priv);
838 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status); 870 bool is_cam = !test_bit(STATUS_POWER_PMI, &priv->status);
@@ -878,15 +910,15 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
878 rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS; 910 rx_chain |= active_rx_cnt << RXON_RX_CHAIN_MIMO_CNT_POS;
879 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS; 911 rx_chain |= idle_rx_cnt << RXON_RX_CHAIN_CNT_POS;
880 912
881 priv->staging_rxon.rx_chain = cpu_to_le16(rx_chain); 913 ctx->staging.rx_chain = cpu_to_le16(rx_chain);
882 914
883 if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam) 915 if (!is_single && (active_rx_cnt >= IWL_NUM_RX_CHAINS_SINGLE) && is_cam)
884 priv->staging_rxon.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK; 916 ctx->staging.rx_chain |= RXON_RX_CHAIN_MIMO_FORCE_MSK;
885 else 917 else
886 priv->staging_rxon.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK; 918 ctx->staging.rx_chain &= ~RXON_RX_CHAIN_MIMO_FORCE_MSK;
887 919
888 IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n", 920 IWL_DEBUG_ASSOC(priv, "rx_chain=0x%X active=%d idle=%d\n",
889 priv->staging_rxon.rx_chain, 921 ctx->staging.rx_chain,
890 active_rx_cnt, idle_rx_cnt); 922 active_rx_cnt, idle_rx_cnt);
891 923
892 WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 || 924 WARN_ON(active_rx_cnt == 0 || idle_rx_cnt == 0 ||
@@ -894,39 +926,41 @@ void iwl_set_rxon_chain(struct iwl_priv *priv)
894} 926}
895EXPORT_SYMBOL(iwl_set_rxon_chain); 927EXPORT_SYMBOL(iwl_set_rxon_chain);
896 928
897/* Return valid channel */ 929/* Return valid, unused, channel for a passive scan to reset the RF */
898u8 iwl_get_single_channel_number(struct iwl_priv *priv, 930u8 iwl_get_single_channel_number(struct iwl_priv *priv,
899 enum ieee80211_band band) 931 enum ieee80211_band band)
900{ 932{
901 const struct iwl_channel_info *ch_info; 933 const struct iwl_channel_info *ch_info;
902 int i; 934 int i;
903 u8 channel = 0; 935 u8 channel = 0;
936 u8 min, max;
937 struct iwl_rxon_context *ctx;
904 938
905 /* only scan single channel, good enough to reset the RF */
906 /* pick the first valid not in-use channel */
907 if (band == IEEE80211_BAND_5GHZ) { 939 if (band == IEEE80211_BAND_5GHZ) {
908 for (i = 14; i < priv->channel_count; i++) { 940 min = 14;
909 if (priv->channel_info[i].channel != 941 max = priv->channel_count;
910 le16_to_cpu(priv->staging_rxon.channel)) {
911 channel = priv->channel_info[i].channel;
912 ch_info = iwl_get_channel_info(priv,
913 band, channel);
914 if (is_channel_valid(ch_info))
915 break;
916 }
917 }
918 } else { 942 } else {
919 for (i = 0; i < 14; i++) { 943 min = 0;
920 if (priv->channel_info[i].channel != 944 max = 14;
921 le16_to_cpu(priv->staging_rxon.channel)) { 945 }
922 channel = 946
923 priv->channel_info[i].channel; 947 for (i = min; i < max; i++) {
924 ch_info = iwl_get_channel_info(priv, 948 bool busy = false;
925 band, channel); 949
926 if (is_channel_valid(ch_info)) 950 for_each_context(priv, ctx) {
927 break; 951 busy = priv->channel_info[i].channel ==
928 } 952 le16_to_cpu(ctx->staging.channel);
953 if (busy)
954 break;
929 } 955 }
956
957 if (busy)
958 continue;
959
960 channel = priv->channel_info[i].channel;
961 ch_info = iwl_get_channel_info(priv, band, channel);
962 if (is_channel_valid(ch_info))
963 break;
930 } 964 }
931 965
932 return channel; 966 return channel;
@@ -937,25 +971,24 @@ EXPORT_SYMBOL(iwl_get_single_channel_number);
937 * iwl_set_rxon_channel - Set the band and channel values in staging RXON 971 * iwl_set_rxon_channel - Set the band and channel values in staging RXON
938 * @ch: requested channel as a pointer to struct ieee80211_channel 972 * @ch: requested channel as a pointer to struct ieee80211_channel
939 973
940 * In addition to setting the staging RXON, priv->band is also set.
941 *
942 * NOTE: Does not commit to the hardware; it sets appropriate bit fields 974 * NOTE: Does not commit to the hardware; it sets appropriate bit fields
943 * in the staging RXON flag structure based on the ch->band 975 * in the staging RXON flag structure based on the ch->band
944 */ 976 */
945int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) 977int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
978 struct iwl_rxon_context *ctx)
946{ 979{
947 enum ieee80211_band band = ch->band; 980 enum ieee80211_band band = ch->band;
948 u16 channel = ch->hw_value; 981 u16 channel = ch->hw_value;
949 982
950 if ((le16_to_cpu(priv->staging_rxon.channel) == channel) && 983 if ((le16_to_cpu(ctx->staging.channel) == channel) &&
951 (priv->band == band)) 984 (priv->band == band))
952 return 0; 985 return 0;
953 986
954 priv->staging_rxon.channel = cpu_to_le16(channel); 987 ctx->staging.channel = cpu_to_le16(channel);
955 if (band == IEEE80211_BAND_5GHZ) 988 if (band == IEEE80211_BAND_5GHZ)
956 priv->staging_rxon.flags &= ~RXON_FLG_BAND_24G_MSK; 989 ctx->staging.flags &= ~RXON_FLG_BAND_24G_MSK;
957 else 990 else
958 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; 991 ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
959 992
960 priv->band = band; 993 priv->band = band;
961 994
@@ -966,24 +999,25 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
966EXPORT_SYMBOL(iwl_set_rxon_channel); 999EXPORT_SYMBOL(iwl_set_rxon_channel);
967 1000
968void iwl_set_flags_for_band(struct iwl_priv *priv, 1001void iwl_set_flags_for_band(struct iwl_priv *priv,
1002 struct iwl_rxon_context *ctx,
969 enum ieee80211_band band, 1003 enum ieee80211_band band,
970 struct ieee80211_vif *vif) 1004 struct ieee80211_vif *vif)
971{ 1005{
972 if (band == IEEE80211_BAND_5GHZ) { 1006 if (band == IEEE80211_BAND_5GHZ) {
973 priv->staging_rxon.flags &= 1007 ctx->staging.flags &=
974 ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK 1008 ~(RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK
975 | RXON_FLG_CCK_MSK); 1009 | RXON_FLG_CCK_MSK);
976 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 1010 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
977 } else { 1011 } else {
978 /* Copied from iwl_post_associate() */ 1012 /* Copied from iwl_post_associate() */
979 if (vif && vif->bss_conf.use_short_slot) 1013 if (vif && vif->bss_conf.use_short_slot)
980 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 1014 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
981 else 1015 else
982 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 1016 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
983 1017
984 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; 1018 ctx->staging.flags |= RXON_FLG_BAND_24G_MSK;
985 priv->staging_rxon.flags |= RXON_FLG_AUTO_DETECT_MSK; 1019 ctx->staging.flags |= RXON_FLG_AUTO_DETECT_MSK;
986 priv->staging_rxon.flags &= ~RXON_FLG_CCK_MSK; 1020 ctx->staging.flags &= ~RXON_FLG_CCK_MSK;
987 } 1021 }
988} 1022}
989EXPORT_SYMBOL(iwl_set_flags_for_band); 1023EXPORT_SYMBOL(iwl_set_flags_for_band);
@@ -996,26 +1030,29 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
996{ 1030{
997 const struct iwl_channel_info *ch_info; 1031 const struct iwl_channel_info *ch_info;
998 enum nl80211_iftype type = NL80211_IFTYPE_STATION; 1032 enum nl80211_iftype type = NL80211_IFTYPE_STATION;
1033 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
999 1034
1000 if (vif) 1035 if (vif) {
1001 type = vif->type; 1036 type = vif->type;
1037 ctx = iwl_rxon_ctx_from_vif(vif);
1038 }
1002 1039
1003 memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); 1040 memset(&ctx->staging, 0, sizeof(ctx->staging));
1004 1041
1005 switch (type) { 1042 switch (type) {
1006 case NL80211_IFTYPE_AP: 1043 case NL80211_IFTYPE_AP:
1007 priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; 1044 ctx->staging.dev_type = RXON_DEV_TYPE_AP;
1008 break; 1045 break;
1009 1046
1010 case NL80211_IFTYPE_STATION: 1047 case NL80211_IFTYPE_STATION:
1011 priv->staging_rxon.dev_type = RXON_DEV_TYPE_ESS; 1048 ctx->staging.dev_type = RXON_DEV_TYPE_ESS;
1012 priv->staging_rxon.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK; 1049 ctx->staging.filter_flags = RXON_FILTER_ACCEPT_GRP_MSK;
1013 break; 1050 break;
1014 1051
1015 case NL80211_IFTYPE_ADHOC: 1052 case NL80211_IFTYPE_ADHOC:
1016 priv->staging_rxon.dev_type = RXON_DEV_TYPE_IBSS; 1053 ctx->staging.dev_type = RXON_DEV_TYPE_IBSS;
1017 priv->staging_rxon.flags = RXON_FLG_SHORT_PREAMBLE_MSK; 1054 ctx->staging.flags = RXON_FLG_SHORT_PREAMBLE_MSK;
1018 priv->staging_rxon.filter_flags = RXON_FILTER_BCON_AWARE_MSK | 1055 ctx->staging.filter_flags = RXON_FILTER_BCON_AWARE_MSK |
1019 RXON_FILTER_ACCEPT_GRP_MSK; 1056 RXON_FILTER_ACCEPT_GRP_MSK;
1020 break; 1057 break;
1021 1058
@@ -1028,37 +1065,36 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv,
1028 /* TODO: Figure out when short_preamble would be set and cache from 1065 /* TODO: Figure out when short_preamble would be set and cache from
1029 * that */ 1066 * that */
1030 if (!hw_to_local(priv->hw)->short_preamble) 1067 if (!hw_to_local(priv->hw)->short_preamble)
1031 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 1068 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
1032 else 1069 else
1033 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 1070 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
1034#endif 1071#endif
1035 1072
1036 ch_info = iwl_get_channel_info(priv, priv->band, 1073 ch_info = iwl_get_channel_info(priv, priv->band,
1037 le16_to_cpu(priv->active_rxon.channel)); 1074 le16_to_cpu(ctx->active.channel));
1038 1075
1039 if (!ch_info) 1076 if (!ch_info)
1040 ch_info = &priv->channel_info[0]; 1077 ch_info = &priv->channel_info[0];
1041 1078
1042 priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); 1079 ctx->staging.channel = cpu_to_le16(ch_info->channel);
1043 priv->band = ch_info->band; 1080 priv->band = ch_info->band;
1044 1081
1045 iwl_set_flags_for_band(priv, priv->band, vif); 1082 iwl_set_flags_for_band(priv, ctx, priv->band, vif);
1046 1083
1047 priv->staging_rxon.ofdm_basic_rates = 1084 ctx->staging.ofdm_basic_rates =
1048 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 1085 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
1049 priv->staging_rxon.cck_basic_rates = 1086 ctx->staging.cck_basic_rates =
1050 (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; 1087 (IWL_CCK_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
1051 1088
1052 /* clear both MIX and PURE40 mode flag */ 1089 /* clear both MIX and PURE40 mode flag */
1053 priv->staging_rxon.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED | 1090 ctx->staging.flags &= ~(RXON_FLG_CHANNEL_MODE_MIXED |
1054 RXON_FLG_CHANNEL_MODE_PURE_40); 1091 RXON_FLG_CHANNEL_MODE_PURE_40);
1055
1056 if (vif) 1092 if (vif)
1057 memcpy(priv->staging_rxon.node_addr, vif->addr, ETH_ALEN); 1093 memcpy(ctx->staging.node_addr, vif->addr, ETH_ALEN);
1058 1094
1059 priv->staging_rxon.ofdm_ht_single_stream_basic_rates = 0xff; 1095 ctx->staging.ofdm_ht_single_stream_basic_rates = 0xff;
1060 priv->staging_rxon.ofdm_ht_dual_stream_basic_rates = 0xff; 1096 ctx->staging.ofdm_ht_dual_stream_basic_rates = 0xff;
1061 priv->staging_rxon.ofdm_ht_triple_stream_basic_rates = 0xff; 1097 ctx->staging.ofdm_ht_triple_stream_basic_rates = 0xff;
1062} 1098}
1063EXPORT_SYMBOL(iwl_connection_init_rx_config); 1099EXPORT_SYMBOL(iwl_connection_init_rx_config);
1064 1100
@@ -1066,6 +1102,7 @@ void iwl_set_rate(struct iwl_priv *priv)
1066{ 1102{
1067 const struct ieee80211_supported_band *hw = NULL; 1103 const struct ieee80211_supported_band *hw = NULL;
1068 struct ieee80211_rate *rate; 1104 struct ieee80211_rate *rate;
1105 struct iwl_rxon_context *ctx;
1069 int i; 1106 int i;
1070 1107
1071 hw = iwl_get_hw_mode(priv, priv->band); 1108 hw = iwl_get_hw_mode(priv, priv->band);
@@ -1084,11 +1121,13 @@ void iwl_set_rate(struct iwl_priv *priv)
1084 1121
1085 IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate); 1122 IWL_DEBUG_RATE(priv, "Set active_rate = %0x\n", priv->active_rate);
1086 1123
1087 priv->staging_rxon.cck_basic_rates = 1124 for_each_context(priv, ctx) {
1088 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF; 1125 ctx->staging.cck_basic_rates =
1126 (IWL_CCK_BASIC_RATES_MASK >> IWL_FIRST_CCK_RATE) & 0xF;
1089 1127
1090 priv->staging_rxon.ofdm_basic_rates = 1128 ctx->staging.ofdm_basic_rates =
1091 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 1129 (IWL_OFDM_BASIC_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
1130 }
1092} 1131}
1093EXPORT_SYMBOL(iwl_set_rate); 1132EXPORT_SYMBOL(iwl_set_rate);
1094 1133
@@ -1109,14 +1148,17 @@ EXPORT_SYMBOL(iwl_chswitch_done);
1109void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) 1148void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1110{ 1149{
1111 struct iwl_rx_packet *pkt = rxb_addr(rxb); 1150 struct iwl_rx_packet *pkt = rxb_addr(rxb);
1112 struct iwl_rxon_cmd *rxon = (void *)&priv->active_rxon;
1113 struct iwl_csa_notification *csa = &(pkt->u.csa_notif); 1151 struct iwl_csa_notification *csa = &(pkt->u.csa_notif);
1152#if !TODO
1153 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1154#endif
1155 struct iwl_rxon_cmd *rxon = (void *)&ctx->active;
1114 1156
1115 if (priv->switch_rxon.switch_in_progress) { 1157 if (priv->switch_rxon.switch_in_progress) {
1116 if (!le32_to_cpu(csa->status) && 1158 if (!le32_to_cpu(csa->status) &&
1117 (csa->channel == priv->switch_rxon.channel)) { 1159 (csa->channel == priv->switch_rxon.channel)) {
1118 rxon->channel = csa->channel; 1160 rxon->channel = csa->channel;
1119 priv->staging_rxon.channel = csa->channel; 1161 ctx->staging.channel = csa->channel;
1120 IWL_DEBUG_11H(priv, "CSA notif: channel %d\n", 1162 IWL_DEBUG_11H(priv, "CSA notif: channel %d\n",
1121 le16_to_cpu(csa->channel)); 1163 le16_to_cpu(csa->channel));
1122 iwl_chswitch_done(priv, true); 1164 iwl_chswitch_done(priv, true);
@@ -1130,9 +1172,10 @@ void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb)
1130EXPORT_SYMBOL(iwl_rx_csa); 1172EXPORT_SYMBOL(iwl_rx_csa);
1131 1173
1132#ifdef CONFIG_IWLWIFI_DEBUG 1174#ifdef CONFIG_IWLWIFI_DEBUG
1133void iwl_print_rx_config_cmd(struct iwl_priv *priv) 1175void iwl_print_rx_config_cmd(struct iwl_priv *priv,
1176 struct iwl_rxon_context *ctx)
1134{ 1177{
1135 struct iwl_rxon_cmd *rxon = &priv->staging_rxon; 1178 struct iwl_rxon_cmd *rxon = &ctx->staging;
1136 1179
1137 IWL_DEBUG_RADIO(priv, "RX CONFIG:\n"); 1180 IWL_DEBUG_RADIO(priv, "RX CONFIG:\n");
1138 iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon)); 1181 iwl_print_hex_dump(priv, IWL_DL_RADIO, (u8 *) rxon, sizeof(*rxon));
@@ -1172,7 +1215,8 @@ void iwl_irq_handle_error(struct iwl_priv *priv)
1172 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false); 1215 priv->cfg->ops->lib->dump_nic_event_log(priv, false, NULL, false);
1173#ifdef CONFIG_IWLWIFI_DEBUG 1216#ifdef CONFIG_IWLWIFI_DEBUG
1174 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS) 1217 if (iwl_get_debug_level(priv) & IWL_DL_FW_ERRORS)
1175 iwl_print_rx_config_cmd(priv); 1218 iwl_print_rx_config_cmd(priv,
1219 &priv->contexts[IWL_RXON_CTX_BSS]);
1176#endif 1220#endif
1177 1221
1178 wake_up_interruptible(&priv->wait_command_queue); 1222 wake_up_interruptible(&priv->wait_command_queue);
@@ -1640,18 +1684,20 @@ static void iwl_ht_conf(struct iwl_priv *priv,
1640 IWL_DEBUG_MAC80211(priv, "leave\n"); 1684 IWL_DEBUG_MAC80211(priv, "leave\n");
1641} 1685}
1642 1686
1643static inline void iwl_set_no_assoc(struct iwl_priv *priv) 1687static inline void iwl_set_no_assoc(struct iwl_priv *priv,
1688 struct ieee80211_vif *vif)
1644{ 1689{
1690 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1691
1645 iwl_led_disassociate(priv); 1692 iwl_led_disassociate(priv);
1646 /* 1693 /*
1647 * inform the ucode that there is no longer an 1694 * inform the ucode that there is no longer an
1648 * association and that no more packets should be 1695 * association and that no more packets should be
1649 * sent 1696 * sent
1650 */ 1697 */
1651 priv->staging_rxon.filter_flags &= 1698 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1652 ~RXON_FILTER_ASSOC_MSK; 1699 ctx->staging.assoc_id = 0;
1653 priv->staging_rxon.assoc_id = 0; 1700 iwlcore_commit_rxon(priv, ctx);
1654 iwlcore_commit_rxon(priv);
1655} 1701}
1656 1702
1657static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) 1703static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
@@ -1691,6 +1737,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1691 u32 changes) 1737 u32 changes)
1692{ 1738{
1693 struct iwl_priv *priv = hw->priv; 1739 struct iwl_priv *priv = hw->priv;
1740 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1694 int ret; 1741 int ret;
1695 1742
1696 IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes); 1743 IWL_DEBUG_MAC80211(priv, "changes = 0x%X\n", changes);
@@ -1735,13 +1782,13 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1735 1782
1736 /* mac80211 only sets assoc when in STATION mode */ 1783 /* mac80211 only sets assoc when in STATION mode */
1737 if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) { 1784 if (vif->type == NL80211_IFTYPE_ADHOC || bss_conf->assoc) {
1738 memcpy(priv->staging_rxon.bssid_addr, 1785 memcpy(ctx->staging.bssid_addr,
1739 bss_conf->bssid, ETH_ALEN); 1786 bss_conf->bssid, ETH_ALEN);
1740 1787
1741 /* currently needed in a few places */ 1788 /* currently needed in a few places */
1742 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); 1789 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1743 } else { 1790 } else {
1744 priv->staging_rxon.filter_flags &= 1791 ctx->staging.filter_flags &=
1745 ~RXON_FILTER_ASSOC_MSK; 1792 ~RXON_FILTER_ASSOC_MSK;
1746 } 1793 }
1747 1794
@@ -1764,21 +1811,21 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1764 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n", 1811 IWL_DEBUG_MAC80211(priv, "ERP_PREAMBLE %d\n",
1765 bss_conf->use_short_preamble); 1812 bss_conf->use_short_preamble);
1766 if (bss_conf->use_short_preamble) 1813 if (bss_conf->use_short_preamble)
1767 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 1814 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
1768 else 1815 else
1769 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 1816 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
1770 } 1817 }
1771 1818
1772 if (changes & BSS_CHANGED_ERP_CTS_PROT) { 1819 if (changes & BSS_CHANGED_ERP_CTS_PROT) {
1773 IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot); 1820 IWL_DEBUG_MAC80211(priv, "ERP_CTS %d\n", bss_conf->use_cts_prot);
1774 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ)) 1821 if (bss_conf->use_cts_prot && (priv->band != IEEE80211_BAND_5GHZ))
1775 priv->staging_rxon.flags |= RXON_FLG_TGG_PROTECT_MSK; 1822 ctx->staging.flags |= RXON_FLG_TGG_PROTECT_MSK;
1776 else 1823 else
1777 priv->staging_rxon.flags &= ~RXON_FLG_TGG_PROTECT_MSK; 1824 ctx->staging.flags &= ~RXON_FLG_TGG_PROTECT_MSK;
1778 if (bss_conf->use_cts_prot) 1825 if (bss_conf->use_cts_prot)
1779 priv->staging_rxon.flags |= RXON_FLG_SELF_CTS_EN; 1826 ctx->staging.flags |= RXON_FLG_SELF_CTS_EN;
1780 else 1827 else
1781 priv->staging_rxon.flags &= ~RXON_FLG_SELF_CTS_EN; 1828 ctx->staging.flags &= ~RXON_FLG_SELF_CTS_EN;
1782 } 1829 }
1783 1830
1784 if (changes & BSS_CHANGED_BASIC_RATES) { 1831 if (changes & BSS_CHANGED_BASIC_RATES) {
@@ -1788,12 +1835,12 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1788 * like this here: 1835 * like this here:
1789 * 1836 *
1790 if (A-band) 1837 if (A-band)
1791 priv->staging_rxon.ofdm_basic_rates = 1838 ctx->staging.ofdm_basic_rates =
1792 bss_conf->basic_rates; 1839 bss_conf->basic_rates;
1793 else 1840 else
1794 priv->staging_rxon.ofdm_basic_rates = 1841 ctx->staging.ofdm_basic_rates =
1795 bss_conf->basic_rates >> 4; 1842 bss_conf->basic_rates >> 4;
1796 priv->staging_rxon.cck_basic_rates = 1843 ctx->staging.cck_basic_rates =
1797 bss_conf->basic_rates & 0xF; 1844 bss_conf->basic_rates & 0xF;
1798 */ 1845 */
1799 } 1846 }
@@ -1802,7 +1849,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1802 iwl_ht_conf(priv, vif); 1849 iwl_ht_conf(priv, vif);
1803 1850
1804 if (priv->cfg->ops->hcmd->set_rxon_chain) 1851 if (priv->cfg->ops->hcmd->set_rxon_chain)
1805 priv->cfg->ops->hcmd->set_rxon_chain(priv); 1852 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1806 } 1853 }
1807 1854
1808 if (changes & BSS_CHANGED_ASSOC) { 1855 if (changes & BSS_CHANGED_ASSOC) {
@@ -1815,29 +1862,29 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1815 if (!iwl_is_rfkill(priv)) 1862 if (!iwl_is_rfkill(priv))
1816 priv->cfg->ops->lib->post_associate(priv, vif); 1863 priv->cfg->ops->lib->post_associate(priv, vif);
1817 } else 1864 } else
1818 iwl_set_no_assoc(priv); 1865 iwl_set_no_assoc(priv, vif);
1819 } 1866 }
1820 1867
1821 if (changes && iwl_is_associated(priv) && bss_conf->aid) { 1868 if (changes && iwl_is_associated_ctx(ctx) && bss_conf->aid) {
1822 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", 1869 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
1823 changes); 1870 changes);
1824 ret = iwl_send_rxon_assoc(priv); 1871 ret = iwl_send_rxon_assoc(priv, ctx);
1825 if (!ret) { 1872 if (!ret) {
1826 /* Sync active_rxon with latest change. */ 1873 /* Sync active_rxon with latest change. */
1827 memcpy((void *)&priv->active_rxon, 1874 memcpy((void *)&ctx->active,
1828 &priv->staging_rxon, 1875 &ctx->staging,
1829 sizeof(struct iwl_rxon_cmd)); 1876 sizeof(struct iwl_rxon_cmd));
1830 } 1877 }
1831 } 1878 }
1832 1879
1833 if (changes & BSS_CHANGED_BEACON_ENABLED) { 1880 if (changes & BSS_CHANGED_BEACON_ENABLED) {
1834 if (vif->bss_conf.enable_beacon) { 1881 if (vif->bss_conf.enable_beacon) {
1835 memcpy(priv->staging_rxon.bssid_addr, 1882 memcpy(ctx->staging.bssid_addr,
1836 bss_conf->bssid, ETH_ALEN); 1883 bss_conf->bssid, ETH_ALEN);
1837 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); 1884 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1838 iwlcore_config_ap(priv, vif); 1885 iwlcore_config_ap(priv, vif);
1839 } else 1886 } else
1840 iwl_set_no_assoc(priv); 1887 iwl_set_no_assoc(priv, vif);
1841 } 1888 }
1842 1889
1843 if (changes & BSS_CHANGED_IBSS) { 1890 if (changes & BSS_CHANGED_IBSS) {
@@ -1857,17 +1904,20 @@ EXPORT_SYMBOL(iwl_bss_info_changed);
1857 1904
1858static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) 1905static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
1859{ 1906{
1907 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1908
1860 iwl_connection_init_rx_config(priv, vif); 1909 iwl_connection_init_rx_config(priv, vif);
1861 1910
1862 if (priv->cfg->ops->hcmd->set_rxon_chain) 1911 if (priv->cfg->ops->hcmd->set_rxon_chain)
1863 priv->cfg->ops->hcmd->set_rxon_chain(priv); 1912 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
1864 1913
1865 return iwlcore_commit_rxon(priv); 1914 return iwlcore_commit_rxon(priv, ctx);
1866} 1915}
1867 1916
1868int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) 1917int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1869{ 1918{
1870 struct iwl_priv *priv = hw->priv; 1919 struct iwl_priv *priv = hw->priv;
1920 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1871 int err = 0; 1921 int err = 0;
1872 1922
1873 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n", 1923 IWL_DEBUG_MAC80211(priv, "enter: type %d, addr %pM\n",
@@ -1875,6 +1925,8 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1875 1925
1876 mutex_lock(&priv->mutex); 1926 mutex_lock(&priv->mutex);
1877 1927
1928 vif_priv->ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1929
1878 if (WARN_ON(!iwl_is_ready_rf(priv))) { 1930 if (WARN_ON(!iwl_is_ready_rf(priv))) {
1879 err = -EINVAL; 1931 err = -EINVAL;
1880 goto out; 1932 goto out;
@@ -1920,6 +1972,7 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
1920 struct ieee80211_vif *vif) 1972 struct ieee80211_vif *vif)
1921{ 1973{
1922 struct iwl_priv *priv = hw->priv; 1974 struct iwl_priv *priv = hw->priv;
1975 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
1923 bool scan_completed = false; 1976 bool scan_completed = false;
1924 1977
1925 IWL_DEBUG_MAC80211(priv, "enter\n"); 1978 IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -1928,8 +1981,8 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw,
1928 1981
1929 if (iwl_is_ready_rf(priv)) { 1982 if (iwl_is_ready_rf(priv)) {
1930 iwl_scan_cancel_timeout(priv, 100); 1983 iwl_scan_cancel_timeout(priv, 100);
1931 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 1984 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
1932 iwlcore_commit_rxon(priv); 1985 iwlcore_commit_rxon(priv, ctx);
1933 } 1986 }
1934 if (priv->vif == vif) { 1987 if (priv->vif == vif) {
1935 priv->vif = NULL; 1988 priv->vif = NULL;
@@ -1971,6 +2024,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
1971 struct ieee80211_conf *conf = &hw->conf; 2024 struct ieee80211_conf *conf = &hw->conf;
1972 struct ieee80211_channel *channel = conf->channel; 2025 struct ieee80211_channel *channel = conf->channel;
1973 struct iwl_ht_config *ht_conf = &priv->current_ht_config; 2026 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
2027 struct iwl_rxon_context *ctx;
1974 unsigned long flags = 0; 2028 unsigned long flags = 0;
1975 int ret = 0; 2029 int ret = 0;
1976 u16 ch; 2030 u16 ch;
@@ -2000,7 +2054,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2000 * configured. 2054 * configured.
2001 */ 2055 */
2002 if (priv->cfg->ops->hcmd->set_rxon_chain) 2056 if (priv->cfg->ops->hcmd->set_rxon_chain)
2003 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2057 for_each_context(priv, ctx)
2058 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2004 } 2059 }
2005 2060
2006 /* during scanning mac80211 will delay channel setting until 2061 /* during scanning mac80211 will delay channel setting until
@@ -2042,13 +2097,20 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2042 * from BSS config in iwl_ht_conf */ 2097 * from BSS config in iwl_ht_conf */
2043 ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE; 2098 ht_conf->ht_protection = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
2044 2099
2045 if ((le16_to_cpu(priv->staging_rxon.channel) != ch)) 2100 for_each_context(priv, ctx) {
2046 priv->staging_rxon.flags = 0; 2101 /* if we are switching from ht to 2.4 clear flags
2102 * from any ht related info since 2.4 does not
2103 * support ht */
2104 if ((le16_to_cpu(ctx->staging.channel) != ch))
2105 ctx->staging.flags = 0;
2047 2106
2048 iwl_set_rxon_channel(priv, channel); 2107 iwl_set_rxon_channel(priv, channel, ctx);
2049 iwl_set_rxon_ht(priv, ht_conf); 2108 iwl_set_rxon_ht(priv, ht_conf);
2109
2110 iwl_set_flags_for_band(priv, ctx, channel->band,
2111 priv->vif);
2112 }
2050 2113
2051 iwl_set_flags_for_band(priv, channel->band, priv->vif);
2052 spin_unlock_irqrestore(&priv->lock, flags); 2114 spin_unlock_irqrestore(&priv->lock, flags);
2053 2115
2054 if (priv->cfg->ops->lib->update_bcast_station) 2116 if (priv->cfg->ops->lib->update_bcast_station)
@@ -2083,12 +2145,13 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2083 if (scan_active) 2145 if (scan_active)
2084 goto out; 2146 goto out;
2085 2147
2086 if (memcmp(&priv->active_rxon, 2148 for_each_context(priv, ctx) {
2087 &priv->staging_rxon, sizeof(priv->staging_rxon))) 2149 if (memcmp(&ctx->active, &ctx->staging, sizeof(ctx->staging)))
2088 iwlcore_commit_rxon(priv); 2150 iwlcore_commit_rxon(priv, ctx);
2089 else 2151 else
2090 IWL_DEBUG_INFO(priv, "Not re-sending same RXON configuration.\n"); 2152 IWL_DEBUG_INFO(priv,
2091 2153 "Not re-sending same RXON configuration.\n");
2154 }
2092 2155
2093out: 2156out:
2094 IWL_DEBUG_MAC80211(priv, "leave\n"); 2157 IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -2101,6 +2164,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2101{ 2164{
2102 struct iwl_priv *priv = hw->priv; 2165 struct iwl_priv *priv = hw->priv;
2103 unsigned long flags; 2166 unsigned long flags;
2167 /* IBSS can only be the IWL_RXON_CTX_BSS context */
2168 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2104 2169
2105 mutex_lock(&priv->mutex); 2170 mutex_lock(&priv->mutex);
2106 IWL_DEBUG_MAC80211(priv, "enter\n"); 2171 IWL_DEBUG_MAC80211(priv, "enter\n");
@@ -2131,8 +2196,8 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2131 * clear RXON_FILTER_ASSOC_MSK bit 2196 * clear RXON_FILTER_ASSOC_MSK bit
2132 */ 2197 */
2133 iwl_scan_cancel_timeout(priv, 100); 2198 iwl_scan_cancel_timeout(priv, 100);
2134 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2199 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2135 iwlcore_commit_rxon(priv); 2200 iwlcore_commit_rxon(priv, ctx);
2136 2201
2137 iwl_set_rate(priv); 2202 iwl_set_rate(priv);
2138 2203
@@ -2541,7 +2606,7 @@ static void iwl_force_rf_reset(struct iwl_priv *priv)
2541 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2606 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2542 return; 2607 return;
2543 2608
2544 if (!iwl_is_associated(priv)) { 2609 if (!iwl_is_any_associated(priv)) {
2545 IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n"); 2610 IWL_DEBUG_SCAN(priv, "force reset rejected: not associated\n");
2546 return; 2611 return;
2547 } 2612 }
@@ -2696,7 +2761,7 @@ void iwl_bg_monitor_recover(unsigned long data)
2696 return; 2761 return;
2697 2762
2698 /* monitor and check for other stuck queues */ 2763 /* monitor and check for other stuck queues */
2699 if (iwl_is_associated(priv)) { 2764 if (iwl_is_any_associated(priv)) {
2700 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) { 2765 for (cnt = 0; cnt < priv->hw_params.max_txq_num; cnt++) {
2701 /* skip as we already checked the command queue */ 2766 /* skip as we already checked the command queue */
2702 if (cnt == IWL_CMD_QUEUE_NUM) 2767 if (cnt == IWL_CMD_QUEUE_NUM)
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index de2e39f36c25..80c256246e4d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -88,9 +88,10 @@ struct iwl_cmd;
88#define IWL_CMD(x) case x: return #x 88#define IWL_CMD(x) case x: return #x
89 89
90struct iwl_hcmd_ops { 90struct iwl_hcmd_ops {
91 int (*rxon_assoc)(struct iwl_priv *priv); 91 int (*rxon_assoc)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
92 int (*commit_rxon)(struct iwl_priv *priv); 92 int (*commit_rxon)(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
93 void (*set_rxon_chain)(struct iwl_priv *priv); 93 void (*set_rxon_chain)(struct iwl_priv *priv,
94 struct iwl_rxon_context *ctx);
94 int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant); 95 int (*set_tx_ant)(struct iwl_priv *priv, u8 valid_tx_ant);
95 void (*send_bt_config)(struct iwl_priv *priv); 96 void (*send_bt_config)(struct iwl_priv *priv);
96}; 97};
@@ -374,12 +375,15 @@ void iwl_activate_qos(struct iwl_priv *priv);
374int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, 375int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue,
375 const struct ieee80211_tx_queue_params *params); 376 const struct ieee80211_tx_queue_params *params);
376int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); 377int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw);
377void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt); 378void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
378int iwl_check_rxon_cmd(struct iwl_priv *priv); 379 int hw_decrypt);
379int iwl_full_rxon_required(struct iwl_priv *priv); 380int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
380void iwl_set_rxon_chain(struct iwl_priv *priv); 381int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
381int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); 382void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
383int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch,
384 struct iwl_rxon_context *ctx);
382void iwl_set_flags_for_band(struct iwl_priv *priv, 385void iwl_set_flags_for_band(struct iwl_priv *priv,
386 struct iwl_rxon_context *ctx,
383 enum ieee80211_band band, 387 enum ieee80211_band band,
384 struct ieee80211_vif *vif); 388 struct ieee80211_vif *vif);
385u8 iwl_get_single_channel_number(struct iwl_priv *priv, 389u8 iwl_get_single_channel_number(struct iwl_priv *priv,
@@ -400,7 +404,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
400 struct ieee80211_vif *vif, 404 struct ieee80211_vif *vif,
401 struct ieee80211_bss_conf *bss_conf, 405 struct ieee80211_bss_conf *bss_conf,
402 u32 changes); 406 u32 changes);
403int iwl_commit_rxon(struct iwl_priv *priv); 407int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx);
404int iwl_mac_add_interface(struct ieee80211_hw *hw, 408int iwl_mac_add_interface(struct ieee80211_hw *hw,
405 struct ieee80211_vif *vif); 409 struct ieee80211_vif *vif);
406void iwl_mac_remove_interface(struct ieee80211_hw *hw, 410void iwl_mac_remove_interface(struct ieee80211_hw *hw,
@@ -632,9 +636,11 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv,
632void iwl_dump_csr(struct iwl_priv *priv); 636void iwl_dump_csr(struct iwl_priv *priv);
633int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); 637int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display);
634#ifdef CONFIG_IWLWIFI_DEBUG 638#ifdef CONFIG_IWLWIFI_DEBUG
635void iwl_print_rx_config_cmd(struct iwl_priv *priv); 639void iwl_print_rx_config_cmd(struct iwl_priv *priv,
640 struct iwl_rxon_context *ctx);
636#else 641#else
637static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv) 642static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv,
643 struct iwl_rxon_context *ctx)
638{ 644{
639} 645}
640#endif 646#endif
@@ -720,13 +726,15 @@ void iwl_apm_stop(struct iwl_priv *priv);
720int iwl_apm_init(struct iwl_priv *priv); 726int iwl_apm_init(struct iwl_priv *priv);
721 727
722int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif); 728int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif);
723static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) 729static inline int iwl_send_rxon_assoc(struct iwl_priv *priv,
730 struct iwl_rxon_context *ctx)
724{ 731{
725 return priv->cfg->ops->hcmd->rxon_assoc(priv); 732 return priv->cfg->ops->hcmd->rxon_assoc(priv, ctx);
726} 733}
727static inline int iwlcore_commit_rxon(struct iwl_priv *priv) 734static inline int iwlcore_commit_rxon(struct iwl_priv *priv,
735 struct iwl_rxon_context *ctx)
728{ 736{
729 return priv->cfg->ops->hcmd->commit_rxon(priv); 737 return priv->cfg->ops->hcmd->commit_rxon(priv, ctx);
730} 738}
731static inline void iwlcore_config_ap(struct iwl_priv *priv, 739static inline void iwlcore_config_ap(struct iwl_priv *priv,
732 struct ieee80211_vif *vif) 740 struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index ef787905f51c..d36418c3a6b5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -730,7 +730,7 @@ static ssize_t iwl_dbgfs_disable_ht40_write(struct file *file,
730 return -EFAULT; 730 return -EFAULT;
731 if (sscanf(buf, "%d", &ht40) != 1) 731 if (sscanf(buf, "%d", &ht40) != 1)
732 return -EFAULT; 732 return -EFAULT;
733 if (!iwl_is_associated(priv)) 733 if (!iwl_is_any_associated(priv))
734 priv->disable_ht40 = ht40 ? true : false; 734 priv->disable_ht40 = ht40 ? true : false;
735 else { 735 else {
736 IWL_ERR(priv, "Sta associated with AP - " 736 IWL_ERR(priv, "Sta associated with AP - "
@@ -1319,7 +1319,8 @@ static ssize_t iwl_dbgfs_rxon_flags_read(struct file *file,
1319 int len = 0; 1319 int len = 0;
1320 char buf[20]; 1320 char buf[20];
1321 1321
1322 len = sprintf(buf, "0x%04X\n", le32_to_cpu(priv->active_rxon.flags)); 1322 len = sprintf(buf, "0x%04X\n",
1323 le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.flags));
1323 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1324 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1324} 1325}
1325 1326
@@ -1332,7 +1333,7 @@ static ssize_t iwl_dbgfs_rxon_filter_flags_read(struct file *file,
1332 char buf[20]; 1333 char buf[20];
1333 1334
1334 len = sprintf(buf, "0x%04X\n", 1335 len = sprintf(buf, "0x%04X\n",
1335 le32_to_cpu(priv->active_rxon.filter_flags)); 1336 le32_to_cpu(priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags));
1336 return simple_read_from_buffer(user_buf, count, ppos, buf, len); 1337 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1337} 1338}
1338 1339
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 8d5201ac80f9..6b188926014b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -519,6 +519,7 @@ struct iwl_station_priv {
519 * space for us to put data into. 519 * space for us to put data into.
520 */ 520 */
521struct iwl_vif_priv { 521struct iwl_vif_priv {
522 struct iwl_rxon_context *ctx;
522 u8 ibss_bssid_sta_id; 523 u8 ibss_bssid_sta_id;
523}; 524};
524 525
@@ -1097,6 +1098,26 @@ struct iwl_force_reset {
1097 */ 1098 */
1098#define IWLAGN_EXT_BEACON_TIME_POS 22 1099#define IWLAGN_EXT_BEACON_TIME_POS 22
1099 1100
1101enum iwl_rxon_context_id {
1102 IWL_RXON_CTX_BSS,
1103
1104 NUM_IWL_RXON_CTX
1105};
1106
1107struct iwl_rxon_context {
1108 enum iwl_rxon_context_id ctxid;
1109 /*
1110 * We declare this const so it can only be
1111 * changed via explicit cast within the
1112 * routines that actually update the physical
1113 * hardware.
1114 */
1115 const struct iwl_rxon_cmd active;
1116 struct iwl_rxon_cmd staging;
1117
1118 struct iwl_rxon_time_cmd timing;
1119};
1120
1100struct iwl_priv { 1121struct iwl_priv {
1101 1122
1102 /* ieee device used by generic ieee processing code */ 1123 /* ieee device used by generic ieee processing code */
@@ -1173,6 +1194,9 @@ struct iwl_priv {
1173 u32 hw_wa_rev; 1194 u32 hw_wa_rev;
1174 u8 rev_id; 1195 u8 rev_id;
1175 1196
1197 /* microcode/device supports multiple contexts */
1198 u8 valid_contexts;
1199
1176 /* EEPROM MAC addresses */ 1200 /* EEPROM MAC addresses */
1177 struct mac_address addresses[2]; 1201 struct mac_address addresses[2];
1178 1202
@@ -1190,15 +1214,7 @@ struct iwl_priv {
1190 u8 ucode_write_complete; /* the image write is complete */ 1214 u8 ucode_write_complete; /* the image write is complete */
1191 char firmware_name[25]; 1215 char firmware_name[25];
1192 1216
1193 1217 struct iwl_rxon_context contexts[NUM_IWL_RXON_CTX];
1194 struct iwl_rxon_time_cmd rxon_timing;
1195
1196 /* We declare this const so it can only be
1197 * changed via explicit cast within the
1198 * routines that actually update the physical
1199 * hardware */
1200 const struct iwl_rxon_cmd active_rxon;
1201 struct iwl_rxon_cmd staging_rxon;
1202 1218
1203 struct iwl_switch_rxon switch_rxon; 1219 struct iwl_switch_rxon switch_rxon;
1204 1220
@@ -1490,10 +1506,34 @@ static inline struct ieee80211_hdr *iwl_tx_queue_get_hdr(struct iwl_priv *priv,
1490 return NULL; 1506 return NULL;
1491} 1507}
1492 1508
1509static inline struct iwl_rxon_context *
1510iwl_rxon_ctx_from_vif(struct ieee80211_vif *vif)
1511{
1512 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1513
1514 return vif_priv->ctx;
1515}
1516
1517#define for_each_context(priv, ctx) \
1518 for (ctx = &priv->contexts[IWL_RXON_CTX_BSS]; \
1519 ctx < &priv->contexts[NUM_IWL_RXON_CTX]; ctx++) \
1520 if (priv->valid_contexts & BIT(ctx->ctxid))
1521
1522static inline int iwl_is_associated(struct iwl_priv *priv,
1523 enum iwl_rxon_context_id ctxid)
1524{
1525 return (priv->contexts[ctxid].active.filter_flags &
1526 RXON_FILTER_ASSOC_MSK) ? 1 : 0;
1527}
1528
1529static inline int iwl_is_any_associated(struct iwl_priv *priv)
1530{
1531 return iwl_is_associated(priv, IWL_RXON_CTX_BSS);
1532}
1493 1533
1494static inline int iwl_is_associated(struct iwl_priv *priv) 1534static inline int iwl_is_associated_ctx(struct iwl_rxon_context *ctx)
1495{ 1535{
1496 return (priv->active_rxon.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0; 1536 return (ctx->active.filter_flags & RXON_FILTER_ASSOC_MSK) ? 1 : 0;
1497} 1537}
1498 1538
1499static inline int is_channel_valid(const struct iwl_channel_info *ch_info) 1539static inline int is_channel_valid(const struct iwl_channel_info *ch_info)
diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
index 79773e353baa..10be197b0f22 100644
--- a/drivers/net/wireless/iwlwifi/iwl-rx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
@@ -228,7 +228,7 @@ void iwl_recover_from_statistics(struct iwl_priv *priv,
228{ 228{
229 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 229 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
230 return; 230 return;
231 if (iwl_is_associated(priv)) { 231 if (iwl_is_any_associated(priv)) {
232 if (priv->cfg->ops->lib->check_ack_health) { 232 if (priv->cfg->ops->lib->check_ack_health) {
233 if (!priv->cfg->ops->lib->check_ack_health( 233 if (!priv->cfg->ops->lib->check_ack_health(
234 priv, pkt)) { 234 priv, pkt)) {
@@ -266,7 +266,12 @@ int iwl_set_decrypted_flag(struct iwl_priv *priv,
266{ 266{
267 u16 fc = le16_to_cpu(hdr->frame_control); 267 u16 fc = le16_to_cpu(hdr->frame_control);
268 268
269 if (priv->active_rxon.filter_flags & RXON_FILTER_DIS_DECRYPT_MSK) 269 /*
270 * All contexts have the same setting here due to it being
271 * a module parameter, so OK to check any context.
272 */
273 if (priv->contexts[IWL_RXON_CTX_BSS].active.filter_flags &
274 RXON_FILTER_DIS_DECRYPT_MSK)
270 return 0; 275 return 0;
271 276
272 if (!(fc & IEEE80211_FCTL_PROTECTED)) 277 if (!(fc & IEEE80211_FCTL_PROTECTED))
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 2939699a1200..fe4cb57c3a1c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -290,7 +290,8 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
290 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : 290 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
291 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52; 291 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_52;
292 292
293 if (iwl_is_associated(priv)) { 293 if (iwl_is_any_associated(priv)) {
294 /* TODO: should use minimum of all contexts */
294 /* If we're associated, we clamp the maximum passive 295 /* If we're associated, we clamp the maximum passive
295 * dwell time to be 98% of the beacon interval (minus 296 * dwell time to be 98% of the beacon interval (minus
296 * 2 * channel tune time) */ 297 * 2 * channel tune time) */
@@ -527,6 +528,7 @@ static void iwl_bg_scan_completed(struct work_struct *work)
527 container_of(work, struct iwl_priv, scan_completed); 528 container_of(work, struct iwl_priv, scan_completed);
528 bool internal = false; 529 bool internal = false;
529 bool scan_completed = false; 530 bool scan_completed = false;
531 struct iwl_rxon_context *ctx;
530 532
531 IWL_DEBUG_SCAN(priv, "SCAN complete scan\n"); 533 IWL_DEBUG_SCAN(priv, "SCAN complete scan\n");
532 534
@@ -557,9 +559,8 @@ static void iwl_bg_scan_completed(struct work_struct *work)
557 * Since setting the RXON may have been deferred while 559 * Since setting the RXON may have been deferred while
558 * performing the scan, fire one off if needed 560 * performing the scan, fire one off if needed
559 */ 561 */
560 if (memcmp(&priv->active_rxon, 562 for_each_context(priv, ctx)
561 &priv->staging_rxon, sizeof(priv->staging_rxon))) 563 iwlcore_commit_rxon(priv, ctx);
562 iwlcore_commit_rxon(priv);
563 564
564 out: 565 out:
565 mutex_unlock(&priv->mutex); 566 mutex_unlock(&priv->mutex);
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index d5e8db37b86e..43afb8fb36c3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -1153,12 +1153,16 @@ static bool is_lq_table_valid(struct iwl_priv *priv,
1153{ 1153{
1154 int i; 1154 int i;
1155 struct iwl_ht_config *ht_conf = &priv->current_ht_config; 1155 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
1156#if !TODO
1157 struct iwl_rxon_context *ctx =
1158 &priv->contexts[IWL_RXON_CTX_BSS];
1159#endif
1156 1160
1157 if (ht_conf->is_ht) 1161 if (ht_conf->is_ht)
1158 return true; 1162 return true;
1159 1163
1160 IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n", 1164 IWL_DEBUG_INFO(priv, "Channel %u is not an HT channel\n",
1161 priv->active_rxon.channel); 1165 ctx->active.channel);
1162 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) { 1166 for (i = 0; i < LINK_QUAL_MAX_RETRY_NUM; i++) {
1163 if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) { 1167 if (le32_to_cpu(lq->rs_table[i].rate_n_flags) & RATE_MCS_HT_MSK) {
1164 IWL_DEBUG_INFO(priv, 1168 IWL_DEBUG_INFO(priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 53e6cbb3aaaa..234d6b430fcf 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -317,7 +317,7 @@ unsigned int iwl3945_fill_beacon_frame(struct iwl_priv *priv,
317 int left) 317 int left)
318{ 318{
319 319
320 if (!iwl_is_associated(priv) || !priv->ibss_beacon) 320 if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->ibss_beacon)
321 return 0; 321 return 0;
322 322
323 if (priv->ibss_beacon->len > left) 323 if (priv->ibss_beacon->len > left)
@@ -683,11 +683,12 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
683 int rc; 683 int rc;
684 int spectrum_resp_status; 684 int spectrum_resp_status;
685 int duration = le16_to_cpu(params->duration); 685 int duration = le16_to_cpu(params->duration);
686 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
686 687
687 if (iwl_is_associated(priv)) 688 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS))
688 add_time = iwl_usecs_to_beacons(priv, 689 add_time = iwl_usecs_to_beacons(priv,
689 le64_to_cpu(params->start_time) - priv->_3945.last_tsf, 690 le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
690 le16_to_cpu(priv->rxon_timing.beacon_interval)); 691 le16_to_cpu(ctx->timing.beacon_interval));
691 692
692 memset(&spectrum, 0, sizeof(spectrum)); 693 memset(&spectrum, 0, sizeof(spectrum));
693 694
@@ -698,18 +699,18 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
698 cmd.len = sizeof(spectrum); 699 cmd.len = sizeof(spectrum);
699 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len)); 700 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
700 701
701 if (iwl_is_associated(priv)) 702 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS))
702 spectrum.start_time = 703 spectrum.start_time =
703 iwl_add_beacon_time(priv, 704 iwl_add_beacon_time(priv,
704 priv->_3945.last_beacon_time, add_time, 705 priv->_3945.last_beacon_time, add_time,
705 le16_to_cpu(priv->rxon_timing.beacon_interval)); 706 le16_to_cpu(ctx->timing.beacon_interval));
706 else 707 else
707 spectrum.start_time = 0; 708 spectrum.start_time = 0;
708 709
709 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); 710 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
710 spectrum.channels[0].channel = params->channel; 711 spectrum.channels[0].channel = params->channel;
711 spectrum.channels[0].type = type; 712 spectrum.channels[0].type = type;
712 if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK) 713 if (ctx->active.flags & RXON_FLG_BAND_24G_MSK)
713 spectrum.flags |= RXON_FLG_BAND_24G_MSK | 714 spectrum.flags |= RXON_FLG_BAND_24G_MSK |
714 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; 715 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
715 716
@@ -2468,6 +2469,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2468{ 2469{
2469 int thermal_spin = 0; 2470 int thermal_spin = 0;
2470 u32 rfkill; 2471 u32 rfkill;
2472 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2471 2473
2472 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); 2474 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
2473 2475
@@ -2525,11 +2527,11 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2525 2527
2526 iwl_power_update_mode(priv, true); 2528 iwl_power_update_mode(priv, true);
2527 2529
2528 if (iwl_is_associated(priv)) { 2530 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
2529 struct iwl3945_rxon_cmd *active_rxon = 2531 struct iwl3945_rxon_cmd *active_rxon =
2530 (struct iwl3945_rxon_cmd *)(&priv->active_rxon); 2532 (struct iwl3945_rxon_cmd *)(&ctx->active);
2531 2533
2532 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 2534 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2533 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2535 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2534 } else { 2536 } else {
2535 /* Initialize our rx_config data */ 2537 /* Initialize our rx_config data */
@@ -2540,7 +2542,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2540 priv->cfg->ops->hcmd->send_bt_config(priv); 2542 priv->cfg->ops->hcmd->send_bt_config(priv);
2541 2543
2542 /* Configure the adapter for unassociated operation */ 2544 /* Configure the adapter for unassociated operation */
2543 iwlcore_commit_rxon(priv); 2545 iwlcore_commit_rxon(priv, ctx);
2544 2546
2545 iwl3945_reg_txpower_periodic(priv); 2547 iwl3945_reg_txpower_periodic(priv);
2546 2548
@@ -2883,7 +2885,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2883 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; 2885 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
2884 scan->quiet_time = IWL_ACTIVE_QUIET_TIME; 2886 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
2885 2887
2886 if (iwl_is_associated(priv)) { 2888 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
2887 u16 interval = 0; 2889 u16 interval = 0;
2888 u32 extra; 2890 u32 extra;
2889 u32 suspend_time = 100; 2891 u32 suspend_time = 100;
@@ -3077,6 +3079,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3077{ 3079{
3078 int rc = 0; 3080 int rc = 0;
3079 struct ieee80211_conf *conf = NULL; 3081 struct ieee80211_conf *conf = NULL;
3082 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3080 3083
3081 if (!vif || !priv->is_open) 3084 if (!vif || !priv->is_open)
3082 return; 3085 return;
@@ -3087,7 +3090,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3087 } 3090 }
3088 3091
3089 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 3092 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3090 vif->bss_conf.aid, priv->active_rxon.bssid_addr); 3093 vif->bss_conf.aid, ctx->active.bssid_addr);
3091 3094
3092 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3095 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3093 return; 3096 return;
@@ -3096,34 +3099,34 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3096 3099
3097 conf = ieee80211_get_hw_conf(priv->hw); 3100 conf = ieee80211_get_hw_conf(priv->hw);
3098 3101
3099 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3102 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3100 iwlcore_commit_rxon(priv); 3103 iwlcore_commit_rxon(priv, ctx);
3101 3104
3102 rc = iwl_send_rxon_timing(priv, vif); 3105 rc = iwl_send_rxon_timing(priv, vif);
3103 if (rc) 3106 if (rc)
3104 IWL_WARN(priv, "REPLY_RXON_TIMING failed - " 3107 IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
3105 "Attempting to continue.\n"); 3108 "Attempting to continue.\n");
3106 3109
3107 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3110 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3108 3111
3109 priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid); 3112 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
3110 3113
3111 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3114 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3112 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3115 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3113 3116
3114 if (vif->bss_conf.use_short_preamble) 3117 if (vif->bss_conf.use_short_preamble)
3115 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3118 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3116 else 3119 else
3117 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3120 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3118 3121
3119 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3122 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3120 if (vif->bss_conf.use_short_slot) 3123 if (vif->bss_conf.use_short_slot)
3121 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3124 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
3122 else 3125 else
3123 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3126 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3124 } 3127 }
3125 3128
3126 iwlcore_commit_rxon(priv); 3129 iwlcore_commit_rxon(priv, ctx);
3127 3130
3128 switch (vif->type) { 3131 switch (vif->type) {
3129 case NL80211_IFTYPE_STATION: 3132 case NL80211_IFTYPE_STATION:
@@ -3260,17 +3263,18 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3260 3263
3261void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) 3264void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3262{ 3265{
3266 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3263 int rc = 0; 3267 int rc = 0;
3264 3268
3265 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3269 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3266 return; 3270 return;
3267 3271
3268 /* The following should be done only at AP bring up */ 3272 /* The following should be done only at AP bring up */
3269 if (!(iwl_is_associated(priv))) { 3273 if (!(iwl_is_associated(priv, IWL_RXON_CTX_BSS))) {
3270 3274
3271 /* RXON - unassoc (to set timing command) */ 3275 /* RXON - unassoc (to set timing command) */
3272 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3276 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3273 iwlcore_commit_rxon(priv); 3277 iwlcore_commit_rxon(priv, ctx);
3274 3278
3275 /* RXON Timing */ 3279 /* RXON Timing */
3276 rc = iwl_send_rxon_timing(priv, vif); 3280 rc = iwl_send_rxon_timing(priv, vif);
@@ -3278,26 +3282,26 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3278 IWL_WARN(priv, "REPLY_RXON_TIMING failed - " 3282 IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
3279 "Attempting to continue.\n"); 3283 "Attempting to continue.\n");
3280 3284
3281 priv->staging_rxon.assoc_id = 0; 3285 ctx->staging.assoc_id = 0;
3282 3286
3283 if (vif->bss_conf.use_short_preamble) 3287 if (vif->bss_conf.use_short_preamble)
3284 priv->staging_rxon.flags |= 3288 ctx->staging.flags |=
3285 RXON_FLG_SHORT_PREAMBLE_MSK; 3289 RXON_FLG_SHORT_PREAMBLE_MSK;
3286 else 3290 else
3287 priv->staging_rxon.flags &= 3291 ctx->staging.flags &=
3288 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3292 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3289 3293
3290 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3294 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3291 if (vif->bss_conf.use_short_slot) 3295 if (vif->bss_conf.use_short_slot)
3292 priv->staging_rxon.flags |= 3296 ctx->staging.flags |=
3293 RXON_FLG_SHORT_SLOT_MSK; 3297 RXON_FLG_SHORT_SLOT_MSK;
3294 else 3298 else
3295 priv->staging_rxon.flags &= 3299 ctx->staging.flags &=
3296 ~RXON_FLG_SHORT_SLOT_MSK; 3300 ~RXON_FLG_SHORT_SLOT_MSK;
3297 } 3301 }
3298 /* restore RXON assoc */ 3302 /* restore RXON assoc */
3299 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3303 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3300 iwlcore_commit_rxon(priv); 3304 iwlcore_commit_rxon(priv, ctx);
3301 } 3305 }
3302 iwl3945_send_beacon_cmd(priv); 3306 iwl3945_send_beacon_cmd(priv);
3303 3307
@@ -3323,7 +3327,7 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3323 return -EOPNOTSUPP; 3327 return -EOPNOTSUPP;
3324 } 3328 }
3325 3329
3326 static_key = !iwl_is_associated(priv); 3330 static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS);
3327 3331
3328 if (!static_key) { 3332 if (!static_key) {
3329 sta_id = iwl_sta_id_or_broadcast(priv, sta); 3333 sta_id = iwl_sta_id_or_broadcast(priv, sta);
@@ -3405,6 +3409,7 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
3405{ 3409{
3406 struct iwl_priv *priv = hw->priv; 3410 struct iwl_priv *priv = hw->priv;
3407 __le32 filter_or = 0, filter_nand = 0; 3411 __le32 filter_or = 0, filter_nand = 0;
3412 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3408 3413
3409#define CHK(test, flag) do { \ 3414#define CHK(test, flag) do { \
3410 if (*total_flags & (test)) \ 3415 if (*total_flags & (test)) \
@@ -3424,8 +3429,8 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
3424 3429
3425 mutex_lock(&priv->mutex); 3430 mutex_lock(&priv->mutex);
3426 3431
3427 priv->staging_rxon.filter_flags &= ~filter_nand; 3432 ctx->staging.filter_flags &= ~filter_nand;
3428 priv->staging_rxon.filter_flags |= filter_or; 3433 ctx->staging.filter_flags |= filter_or;
3429 3434
3430 /* 3435 /*
3431 * Committing directly here breaks for some reason, 3436 * Committing directly here breaks for some reason,
@@ -3539,8 +3544,9 @@ static ssize_t show_flags(struct device *d,
3539 struct device_attribute *attr, char *buf) 3544 struct device_attribute *attr, char *buf)
3540{ 3545{
3541 struct iwl_priv *priv = dev_get_drvdata(d); 3546 struct iwl_priv *priv = dev_get_drvdata(d);
3547 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3542 3548
3543 return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); 3549 return sprintf(buf, "0x%04X\n", ctx->active.flags);
3544} 3550}
3545 3551
3546static ssize_t store_flags(struct device *d, 3552static ssize_t store_flags(struct device *d,
@@ -3549,17 +3555,18 @@ static ssize_t store_flags(struct device *d,
3549{ 3555{
3550 struct iwl_priv *priv = dev_get_drvdata(d); 3556 struct iwl_priv *priv = dev_get_drvdata(d);
3551 u32 flags = simple_strtoul(buf, NULL, 0); 3557 u32 flags = simple_strtoul(buf, NULL, 0);
3558 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3552 3559
3553 mutex_lock(&priv->mutex); 3560 mutex_lock(&priv->mutex);
3554 if (le32_to_cpu(priv->staging_rxon.flags) != flags) { 3561 if (le32_to_cpu(ctx->staging.flags) != flags) {
3555 /* Cancel any currently running scans... */ 3562 /* Cancel any currently running scans... */
3556 if (iwl_scan_cancel_timeout(priv, 100)) 3563 if (iwl_scan_cancel_timeout(priv, 100))
3557 IWL_WARN(priv, "Could not cancel scan.\n"); 3564 IWL_WARN(priv, "Could not cancel scan.\n");
3558 else { 3565 else {
3559 IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", 3566 IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
3560 flags); 3567 flags);
3561 priv->staging_rxon.flags = cpu_to_le32(flags); 3568 ctx->staging.flags = cpu_to_le32(flags);
3562 iwlcore_commit_rxon(priv); 3569 iwlcore_commit_rxon(priv, ctx);
3563 } 3570 }
3564 } 3571 }
3565 mutex_unlock(&priv->mutex); 3572 mutex_unlock(&priv->mutex);
@@ -3573,9 +3580,10 @@ static ssize_t show_filter_flags(struct device *d,
3573 struct device_attribute *attr, char *buf) 3580 struct device_attribute *attr, char *buf)
3574{ 3581{
3575 struct iwl_priv *priv = dev_get_drvdata(d); 3582 struct iwl_priv *priv = dev_get_drvdata(d);
3583 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3576 3584
3577 return sprintf(buf, "0x%04X\n", 3585 return sprintf(buf, "0x%04X\n",
3578 le32_to_cpu(priv->active_rxon.filter_flags)); 3586 le32_to_cpu(ctx->active.filter_flags));
3579} 3587}
3580 3588
3581static ssize_t store_filter_flags(struct device *d, 3589static ssize_t store_filter_flags(struct device *d,
@@ -3583,19 +3591,20 @@ static ssize_t store_filter_flags(struct device *d,
3583 const char *buf, size_t count) 3591 const char *buf, size_t count)
3584{ 3592{
3585 struct iwl_priv *priv = dev_get_drvdata(d); 3593 struct iwl_priv *priv = dev_get_drvdata(d);
3594 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3586 u32 filter_flags = simple_strtoul(buf, NULL, 0); 3595 u32 filter_flags = simple_strtoul(buf, NULL, 0);
3587 3596
3588 mutex_lock(&priv->mutex); 3597 mutex_lock(&priv->mutex);
3589 if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { 3598 if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) {
3590 /* Cancel any currently running scans... */ 3599 /* Cancel any currently running scans... */
3591 if (iwl_scan_cancel_timeout(priv, 100)) 3600 if (iwl_scan_cancel_timeout(priv, 100))
3592 IWL_WARN(priv, "Could not cancel scan.\n"); 3601 IWL_WARN(priv, "Could not cancel scan.\n");
3593 else { 3602 else {
3594 IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = " 3603 IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
3595 "0x%04X\n", filter_flags); 3604 "0x%04X\n", filter_flags);
3596 priv->staging_rxon.filter_flags = 3605 ctx->staging.filter_flags =
3597 cpu_to_le32(filter_flags); 3606 cpu_to_le32(filter_flags);
3598 iwlcore_commit_rxon(priv); 3607 iwlcore_commit_rxon(priv, ctx);
3599 } 3608 }
3600 } 3609 }
3601 mutex_unlock(&priv->mutex); 3610 mutex_unlock(&priv->mutex);
@@ -3643,8 +3652,9 @@ static ssize_t store_measurement(struct device *d,
3643 const char *buf, size_t count) 3652 const char *buf, size_t count)
3644{ 3653{
3645 struct iwl_priv *priv = dev_get_drvdata(d); 3654 struct iwl_priv *priv = dev_get_drvdata(d);
3655 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3646 struct ieee80211_measurement_params params = { 3656 struct ieee80211_measurement_params params = {
3647 .channel = le16_to_cpu(priv->active_rxon.channel), 3657 .channel = le16_to_cpu(ctx->active.channel),
3648 .start_time = cpu_to_le64(priv->_3945.last_tsf), 3658 .start_time = cpu_to_le64(priv->_3945.last_tsf),
3649 .duration = cpu_to_le16(1), 3659 .duration = cpu_to_le16(1),
3650 }; 3660 };
@@ -3969,7 +3979,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3969 3979
3970static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3980static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3971{ 3981{
3972 int err = 0; 3982 int err = 0, i;
3973 struct iwl_priv *priv; 3983 struct iwl_priv *priv;
3974 struct ieee80211_hw *hw; 3984 struct ieee80211_hw *hw;
3975 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); 3985 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
@@ -3991,6 +4001,12 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
3991 priv = hw->priv; 4001 priv = hw->priv;
3992 SET_IEEE80211_DEV(hw, &pdev->dev); 4002 SET_IEEE80211_DEV(hw, &pdev->dev);
3993 4003
4004 /* 3945 has only one valid context */
4005 priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
4006
4007 for (i = 0; i < NUM_IWL_RXON_CTX; i++)
4008 priv->contexts[i].ctxid = i;
4009
3994 /* 4010 /*
3995 * Disabling hardware scan means that mac80211 will perform scans 4011 * Disabling hardware scan means that mac80211 will perform scans
3996 * "the hard way", rather than using device's scan. 4012 * "the hard way", rather than using device's scan.
@@ -4126,7 +4142,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4126 } 4142 }
4127 4143
4128 iwl_set_rxon_channel(priv, 4144 iwl_set_rxon_channel(priv,
4129 &priv->bands[IEEE80211_BAND_2GHZ].channels[5]); 4145 &priv->bands[IEEE80211_BAND_2GHZ].channels[5],
4146 &priv->contexts[IWL_RXON_CTX_BSS]);
4130 iwl3945_setup_deferred_work(priv); 4147 iwl3945_setup_deferred_work(priv);
4131 iwl3945_setup_rx_handlers(priv); 4148 iwl3945_setup_rx_handlers(priv);
4132 iwl_power_initialize(priv); 4149 iwl_power_initialize(priv);