diff options
author | Johannes Berg <johannes.berg@intel.com> | 2010-08-23 04:46:32 -0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-08-27 11:26:47 -0400 |
commit | 246ed355221076884d225f9d8a4c30a048be8162 (patch) | |
tree | 64bba3b115c6f0d7ba245c44b81c38e46adec6c8 /drivers/net/wireless/iwlwifi | |
parent | 903786a5626e7214d97b232bece88ee75e37d021 (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')
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 | ||
1713 | static int iwl3945_send_rxon_assoc(struct iwl_priv *priv) | 1714 | static 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 | */ |
1764 | static int iwl3945_commit_rxon(struct iwl_priv *priv) | 1766 | static 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 | ||
1409 | static int iwl4965_send_rxon_assoc(struct iwl_priv *priv) | 1409 | static 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) | |||
1448 | static int iwl4965_hw_channel_switch(struct iwl_priv *priv, | 1449 | static 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) | |||
275 | static int iwl5000_hw_channel_switch(struct iwl_priv *priv, | 275 | static 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) | |||
198 | static int iwl6000_hw_channel_switch(struct iwl_priv *priv, | 198 | static 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 | ||
40 | int iwlagn_send_rxon_assoc(struct iwl_priv *priv) | 40 | int 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 | */ |
101 | int iwl_commit_rxon(struct iwl_priv *priv) | 101 | int 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 | ||
235 | void iwl_update_chain_flags(struct iwl_priv *priv) | 235 | void 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 | ||
243 | static void iwl_clear_free_frames(struct iwl_priv *priv) | 247 | static 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) | |||
2710 | static void iwl_alive_start(struct iwl_priv *priv) | 2719 | static 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 | ||
3196 | void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) | 3206 | void 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 | ||
3440 | void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) | 3453 | void 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 | ||
4119 | static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 4145 | static 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 */ |
227 | int iwlagn_send_rxon_assoc(struct iwl_priv *priv); | 227 | int iwlagn_send_rxon_assoc(struct iwl_priv *priv, |
228 | struct iwl_rxon_context *ctx); | ||
228 | int iwlagn_send_tx_ant_config(struct iwl_priv *priv, u8 valid_tx_ant); | 229 | int 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 | } |
487 | EXPORT_SYMBOL(iwl_is_ht40_tx_allowed); | 490 | EXPORT_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 | } |
547 | EXPORT_SYMBOL(iwl_send_rxon_timing); | 551 | EXPORT_SYMBOL(iwl_send_rxon_timing); |
548 | 552 | ||
549 | void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt) | 553 | void 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 | */ |
568 | int iwl_check_rxon_cmd(struct iwl_priv *priv) | 573 | int 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 | */ |
644 | int iwl_full_rxon_required(struct iwl_priv *priv) | 649 | int 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 | ||
686 | u8 iwl_rate_get_lowest_plcp(struct iwl_priv *priv) | 705 | u8 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 | } |
697 | EXPORT_SYMBOL(iwl_rate_get_lowest_plcp); | 719 | EXPORT_SYMBOL(iwl_rate_get_lowest_plcp); |
698 | 720 | ||
699 | void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf) | 721 | static 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 | |||
789 | void 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 | } | ||
764 | EXPORT_SYMBOL(iwl_set_rxon_ht); | 796 | EXPORT_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 | */ |
835 | void iwl_set_rxon_chain(struct iwl_priv *priv) | 867 | void 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 | } |
895 | EXPORT_SYMBOL(iwl_set_rxon_chain); | 927 | EXPORT_SYMBOL(iwl_set_rxon_chain); |
896 | 928 | ||
897 | /* Return valid channel */ | 929 | /* Return valid, unused, channel for a passive scan to reset the RF */ |
898 | u8 iwl_get_single_channel_number(struct iwl_priv *priv, | 930 | u8 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 | */ |
945 | int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch) | 977 | int 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) | |||
966 | EXPORT_SYMBOL(iwl_set_rxon_channel); | 999 | EXPORT_SYMBOL(iwl_set_rxon_channel); |
967 | 1000 | ||
968 | void iwl_set_flags_for_band(struct iwl_priv *priv, | 1001 | void 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 | } |
989 | EXPORT_SYMBOL(iwl_set_flags_for_band); | 1023 | EXPORT_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 | } |
1063 | EXPORT_SYMBOL(iwl_connection_init_rx_config); | 1099 | EXPORT_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 | } |
1093 | EXPORT_SYMBOL(iwl_set_rate); | 1132 | EXPORT_SYMBOL(iwl_set_rate); |
1094 | 1133 | ||
@@ -1109,14 +1148,17 @@ EXPORT_SYMBOL(iwl_chswitch_done); | |||
1109 | void iwl_rx_csa(struct iwl_priv *priv, struct iwl_rx_mem_buffer *rxb) | 1148 | void 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) | |||
1130 | EXPORT_SYMBOL(iwl_rx_csa); | 1172 | EXPORT_SYMBOL(iwl_rx_csa); |
1131 | 1173 | ||
1132 | #ifdef CONFIG_IWLWIFI_DEBUG | 1174 | #ifdef CONFIG_IWLWIFI_DEBUG |
1133 | void iwl_print_rx_config_cmd(struct iwl_priv *priv) | 1175 | void 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 | ||
1643 | static inline void iwl_set_no_assoc(struct iwl_priv *priv) | 1687 | static 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 | ||
1657 | static int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb) | 1703 | static 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 | ||
1858 | static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) | 1905 | static 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 | ||
1868 | int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | 1917 | int 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 | ||
2093 | out: | 2156 | out: |
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 | ||
90 | struct iwl_hcmd_ops { | 90 | struct 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); | |||
374 | int iwl_mac_conf_tx(struct ieee80211_hw *hw, u16 queue, | 375 | int 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); |
376 | int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); | 377 | int iwl_mac_tx_last_beacon(struct ieee80211_hw *hw); |
377 | void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, int hw_decrypt); | 378 | void iwl_set_rxon_hwcrypto(struct iwl_priv *priv, struct iwl_rxon_context *ctx, |
378 | int iwl_check_rxon_cmd(struct iwl_priv *priv); | 379 | int hw_decrypt); |
379 | int iwl_full_rxon_required(struct iwl_priv *priv); | 380 | int iwl_check_rxon_cmd(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
380 | void iwl_set_rxon_chain(struct iwl_priv *priv); | 381 | int iwl_full_rxon_required(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
381 | int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch); | 382 | void iwl_set_rxon_chain(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
383 | int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch, | ||
384 | struct iwl_rxon_context *ctx); | ||
382 | void iwl_set_flags_for_band(struct iwl_priv *priv, | 385 | void 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); |
385 | u8 iwl_get_single_channel_number(struct iwl_priv *priv, | 389 | u8 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); |
403 | int iwl_commit_rxon(struct iwl_priv *priv); | 407 | int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx); |
404 | int iwl_mac_add_interface(struct ieee80211_hw *hw, | 408 | int iwl_mac_add_interface(struct ieee80211_hw *hw, |
405 | struct ieee80211_vif *vif); | 409 | struct ieee80211_vif *vif); |
406 | void iwl_mac_remove_interface(struct ieee80211_hw *hw, | 410 | void iwl_mac_remove_interface(struct ieee80211_hw *hw, |
@@ -632,9 +636,11 @@ int iwl_dump_nic_event_log(struct iwl_priv *priv, | |||
632 | void iwl_dump_csr(struct iwl_priv *priv); | 636 | void iwl_dump_csr(struct iwl_priv *priv); |
633 | int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); | 637 | int iwl_dump_fh(struct iwl_priv *priv, char **buf, bool display); |
634 | #ifdef CONFIG_IWLWIFI_DEBUG | 638 | #ifdef CONFIG_IWLWIFI_DEBUG |
635 | void iwl_print_rx_config_cmd(struct iwl_priv *priv); | 639 | void iwl_print_rx_config_cmd(struct iwl_priv *priv, |
640 | struct iwl_rxon_context *ctx); | ||
636 | #else | 641 | #else |
637 | static inline void iwl_print_rx_config_cmd(struct iwl_priv *priv) | 642 | static 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); | |||
720 | int iwl_apm_init(struct iwl_priv *priv); | 726 | int iwl_apm_init(struct iwl_priv *priv); |
721 | 727 | ||
722 | int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif); | 728 | int iwl_send_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif); |
723 | static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) | 729 | static 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 | } |
727 | static inline int iwlcore_commit_rxon(struct iwl_priv *priv) | 734 | static 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 | } |
731 | static inline void iwlcore_config_ap(struct iwl_priv *priv, | 739 | static 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 | */ |
521 | struct iwl_vif_priv { | 521 | struct 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 | ||
1101 | enum iwl_rxon_context_id { | ||
1102 | IWL_RXON_CTX_BSS, | ||
1103 | |||
1104 | NUM_IWL_RXON_CTX | ||
1105 | }; | ||
1106 | |||
1107 | struct 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 | |||
1100 | struct iwl_priv { | 1121 | struct 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 | ||
1509 | static inline struct iwl_rxon_context * | ||
1510 | iwl_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 | |||
1522 | static 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 | |||
1529 | static inline int iwl_is_any_associated(struct iwl_priv *priv) | ||
1530 | { | ||
1531 | return iwl_is_associated(priv, IWL_RXON_CTX_BSS); | ||
1532 | } | ||
1493 | 1533 | ||
1494 | static inline int iwl_is_associated(struct iwl_priv *priv) | 1534 | static 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 | ||
1499 | static inline int is_channel_valid(const struct iwl_channel_info *ch_info) | 1539 | static 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 | ||
3261 | void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) | 3264 | void 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 | ||
3546 | static ssize_t store_flags(struct device *d, | 3552 | static 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 | ||
3581 | static ssize_t store_filter_flags(struct device *d, | 3589 | static 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 | ||
3970 | static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 3980 | static 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); |