aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-23 04:46:32 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-08-27 11:26:47 -0400
commit246ed355221076884d225f9d8a4c30a048be8162 (patch)
tree64bba3b115c6f0d7ba245c44b81c38e46adec6c8 /drivers/net/wireless/iwlwifi/iwl-agn.c
parent903786a5626e7214d97b232bece88ee75e37d021 (diff)
iwlwifi: initial contextification
In order to support multiple interfaces, we must move a lot of data into per-context structures so we can use the contexts the device offers. To start with, this makes a lot of code context-aware, more changes will move more things into the context structure. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c172
1 files changed, 104 insertions, 68 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 5e0d0d527bf0..e073069a44c2 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -98,21 +98,21 @@ static bool iwlagn_bt_ch_announce = 1;
98 * function correctly transitions out of the RXON_ASSOC_MSK state if 98 * function correctly transitions out of the RXON_ASSOC_MSK state if
99 * a HW tune is required based on the RXON structure changes. 99 * a HW tune is required based on the RXON structure changes.
100 */ 100 */
101int iwl_commit_rxon(struct iwl_priv *priv) 101int iwl_commit_rxon(struct iwl_priv *priv, struct iwl_rxon_context *ctx)
102{ 102{
103 /* cast away the const for active_rxon in this function */ 103 /* cast away the const for active_rxon in this function */
104 struct iwl_rxon_cmd *active_rxon = (void *)&priv->active_rxon; 104 struct iwl_rxon_cmd *active_rxon = (void *)&ctx->active;
105 int ret; 105 int ret;
106 bool new_assoc = 106 bool new_assoc =
107 !!(priv->staging_rxon.filter_flags & RXON_FILTER_ASSOC_MSK); 107 !!(ctx->staging.filter_flags & RXON_FILTER_ASSOC_MSK);
108 108
109 if (!iwl_is_alive(priv)) 109 if (!iwl_is_alive(priv))
110 return -EBUSY; 110 return -EBUSY;
111 111
112 /* always get timestamp with Rx frame */ 112 /* always get timestamp with Rx frame */
113 priv->staging_rxon.flags |= RXON_FLG_TSF2HOST_MSK; 113 ctx->staging.flags |= RXON_FLG_TSF2HOST_MSK;
114 114
115 ret = iwl_check_rxon_cmd(priv); 115 ret = iwl_check_rxon_cmd(priv, ctx);
116 if (ret) { 116 if (ret) {
117 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n"); 117 IWL_ERR(priv, "Invalid RXON configuration. Not committing.\n");
118 return -EINVAL; 118 return -EINVAL;
@@ -123,7 +123,7 @@ int iwl_commit_rxon(struct iwl_priv *priv)
123 * abort any previous channel switch if still in process 123 * abort any previous channel switch if still in process
124 */ 124 */
125 if (priv->switch_rxon.switch_in_progress && 125 if (priv->switch_rxon.switch_in_progress &&
126 (priv->switch_rxon.channel != priv->staging_rxon.channel)) { 126 (priv->switch_rxon.channel != ctx->staging.channel)) {
127 IWL_DEBUG_11H(priv, "abort channel switch on %d\n", 127 IWL_DEBUG_11H(priv, "abort channel switch on %d\n",
128 le16_to_cpu(priv->switch_rxon.channel)); 128 le16_to_cpu(priv->switch_rxon.channel));
129 iwl_chswitch_done(priv, false); 129 iwl_chswitch_done(priv, false);
@@ -132,15 +132,15 @@ int iwl_commit_rxon(struct iwl_priv *priv)
132 /* If we don't need to send a full RXON, we can use 132 /* If we don't need to send a full RXON, we can use
133 * iwl_rxon_assoc_cmd which is used to reconfigure filter 133 * iwl_rxon_assoc_cmd which is used to reconfigure filter
134 * and other flags for the current radio configuration. */ 134 * and other flags for the current radio configuration. */
135 if (!iwl_full_rxon_required(priv)) { 135 if (!iwl_full_rxon_required(priv, ctx)) {
136 ret = iwl_send_rxon_assoc(priv); 136 ret = iwl_send_rxon_assoc(priv, ctx);
137 if (ret) { 137 if (ret) {
138 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret); 138 IWL_ERR(priv, "Error setting RXON_ASSOC (%d)\n", ret);
139 return ret; 139 return ret;
140 } 140 }
141 141
142 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 142 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
143 iwl_print_rx_config_cmd(priv); 143 iwl_print_rx_config_cmd(priv, ctx);
144 return 0; 144 return 0;
145 } 145 }
146 146
@@ -148,13 +148,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
148 * an RXON_ASSOC and the new config wants the associated mask enabled, 148 * an RXON_ASSOC and the new config wants the associated mask enabled,
149 * we must clear the associated from the active configuration 149 * we must clear the associated from the active configuration
150 * before we apply the new config */ 150 * before we apply the new config */
151 if (iwl_is_associated(priv) && new_assoc) { 151 if (iwl_is_associated_ctx(ctx) && new_assoc) {
152 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n"); 152 IWL_DEBUG_INFO(priv, "Toggling associated bit on current RXON\n");
153 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 153 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
154 154
155 ret = iwl_send_cmd_pdu(priv, REPLY_RXON, 155 ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
156 sizeof(struct iwl_rxon_cmd), 156 sizeof(struct iwl_rxon_cmd),
157 &priv->active_rxon); 157 active_rxon);
158 158
159 /* If the mask clearing failed then we set 159 /* If the mask clearing failed then we set
160 * active_rxon back to what it was previously */ 160 * active_rxon back to what it was previously */
@@ -177,10 +177,10 @@ int iwl_commit_rxon(struct iwl_priv *priv)
177 "* channel = %d\n" 177 "* channel = %d\n"
178 "* bssid = %pM\n", 178 "* bssid = %pM\n",
179 (new_assoc ? "" : "out"), 179 (new_assoc ? "" : "out"),
180 le16_to_cpu(priv->staging_rxon.channel), 180 le16_to_cpu(ctx->staging.channel),
181 priv->staging_rxon.bssid_addr); 181 ctx->staging.bssid_addr);
182 182
183 iwl_set_rxon_hwcrypto(priv, !priv->cfg->mod_params->sw_crypto); 183 iwl_set_rxon_hwcrypto(priv, ctx, !priv->cfg->mod_params->sw_crypto);
184 184
185 /* Apply the new configuration 185 /* Apply the new configuration
186 * RXON unassoc clears the station table in uCode so restoration of 186 * RXON unassoc clears the station table in uCode so restoration of
@@ -188,13 +188,13 @@ int iwl_commit_rxon(struct iwl_priv *priv)
188 */ 188 */
189 if (!new_assoc) { 189 if (!new_assoc) {
190 ret = iwl_send_cmd_pdu(priv, REPLY_RXON, 190 ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
191 sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); 191 sizeof(struct iwl_rxon_cmd), &ctx->staging);
192 if (ret) { 192 if (ret) {
193 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); 193 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
194 return ret; 194 return ret;
195 } 195 }
196 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); 196 IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n");
197 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 197 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
198 iwl_clear_ucode_stations(priv); 198 iwl_clear_ucode_stations(priv);
199 iwl_restore_stations(priv); 199 iwl_restore_stations(priv);
200 ret = iwl_restore_default_wep_keys(priv); 200 ret = iwl_restore_default_wep_keys(priv);
@@ -210,14 +210,14 @@ int iwl_commit_rxon(struct iwl_priv *priv)
210 * RXON assoc doesn't clear the station table in uCode, 210 * RXON assoc doesn't clear the station table in uCode,
211 */ 211 */
212 ret = iwl_send_cmd_pdu(priv, REPLY_RXON, 212 ret = iwl_send_cmd_pdu(priv, REPLY_RXON,
213 sizeof(struct iwl_rxon_cmd), &priv->staging_rxon); 213 sizeof(struct iwl_rxon_cmd), &ctx->staging);
214 if (ret) { 214 if (ret) {
215 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret); 215 IWL_ERR(priv, "Error setting new RXON (%d)\n", ret);
216 return ret; 216 return ret;
217 } 217 }
218 memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); 218 memcpy(active_rxon, &ctx->staging, sizeof(*active_rxon));
219 } 219 }
220 iwl_print_rx_config_cmd(priv); 220 iwl_print_rx_config_cmd(priv, ctx);
221 221
222 iwl_init_sensitivity(priv); 222 iwl_init_sensitivity(priv);
223 223
@@ -234,10 +234,14 @@ int iwl_commit_rxon(struct iwl_priv *priv)
234 234
235void iwl_update_chain_flags(struct iwl_priv *priv) 235void iwl_update_chain_flags(struct iwl_priv *priv)
236{ 236{
237 struct iwl_rxon_context *ctx;
237 238
238 if (priv->cfg->ops->hcmd->set_rxon_chain) 239 if (priv->cfg->ops->hcmd->set_rxon_chain) {
239 priv->cfg->ops->hcmd->set_rxon_chain(priv); 240 for_each_context(priv, ctx) {
240 iwlcore_commit_rxon(priv); 241 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
242 iwlcore_commit_rxon(priv, ctx);
243 }
244 }
241} 245}
242 246
243static void iwl_clear_free_frames(struct iwl_priv *priv) 247static void iwl_clear_free_frames(struct iwl_priv *priv)
@@ -633,6 +637,7 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
633{ 637{
634 struct iwl_priv *priv = 638 struct iwl_priv *priv =
635 container_of(work, struct iwl_priv, bt_full_concurrency); 639 container_of(work, struct iwl_priv, bt_full_concurrency);
640 struct iwl_rxon_context *ctx;
636 641
637 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 642 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
638 return; 643 return;
@@ -649,9 +654,13 @@ static void iwl_bg_bt_full_concurrency(struct work_struct *work)
649 * LQ & RXON updated cmds must be sent before BT Config cmd 654 * LQ & RXON updated cmds must be sent before BT Config cmd
650 * to avoid 3-wire collisions 655 * to avoid 3-wire collisions
651 */ 656 */
652 if (priv->cfg->ops->hcmd->set_rxon_chain) 657 mutex_lock(&priv->mutex);
653 priv->cfg->ops->hcmd->set_rxon_chain(priv); 658 for_each_context(priv, ctx) {
654 iwlcore_commit_rxon(priv); 659 if (priv->cfg->ops->hcmd->set_rxon_chain)
660 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
661 iwlcore_commit_rxon(priv, ctx);
662 }
663 mutex_unlock(&priv->mutex);
655 664
656 priv->cfg->ops->hcmd->send_bt_config(priv); 665 priv->cfg->ops->hcmd->send_bt_config(priv);
657} 666}
@@ -2710,6 +2719,7 @@ static void iwl_rf_kill_ct_config(struct iwl_priv *priv)
2710static void iwl_alive_start(struct iwl_priv *priv) 2719static void iwl_alive_start(struct iwl_priv *priv)
2711{ 2720{
2712 int ret = 0; 2721 int ret = 0;
2722 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2713 2723
2714 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); 2724 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
2715 2725
@@ -2758,18 +2768,18 @@ static void iwl_alive_start(struct iwl_priv *priv)
2758 if (priv->cfg->ops->hcmd->set_tx_ant) 2768 if (priv->cfg->ops->hcmd->set_tx_ant)
2759 priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant); 2769 priv->cfg->ops->hcmd->set_tx_ant(priv, priv->cfg->valid_tx_ant);
2760 2770
2761 if (iwl_is_associated(priv)) { 2771 if (iwl_is_associated_ctx(ctx)) {
2762 struct iwl_rxon_cmd *active_rxon = 2772 struct iwl_rxon_cmd *active_rxon =
2763 (struct iwl_rxon_cmd *)&priv->active_rxon; 2773 (struct iwl_rxon_cmd *)&ctx->active;
2764 /* apply any changes in staging */ 2774 /* apply any changes in staging */
2765 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 2775 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2766 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2776 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2767 } else { 2777 } else {
2768 /* Initialize our rx_config data */ 2778 /* Initialize our rx_config data */
2769 iwl_connection_init_rx_config(priv, NULL); 2779 iwl_connection_init_rx_config(priv, NULL);
2770 2780
2771 if (priv->cfg->ops->hcmd->set_rxon_chain) 2781 if (priv->cfg->ops->hcmd->set_rxon_chain)
2772 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2782 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
2773 } 2783 }
2774 2784
2775 if (!priv->cfg->advanced_bt_coexist) { 2785 if (!priv->cfg->advanced_bt_coexist) {
@@ -2780,7 +2790,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
2780 iwl_reset_run_time_calib(priv); 2790 iwl_reset_run_time_calib(priv);
2781 2791
2782 /* Configure the adapter for unassociated operation */ 2792 /* Configure the adapter for unassociated operation */
2783 iwlcore_commit_rxon(priv); 2793 iwlcore_commit_rxon(priv, ctx);
2784 2794
2785 /* At this point, the NIC is initialized and operational */ 2795 /* At this point, the NIC is initialized and operational */
2786 iwl_rf_kill_ct_config(priv); 2796 iwl_rf_kill_ct_config(priv);
@@ -3195,12 +3205,15 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
3195 3205
3196void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) 3206void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3197{ 3207{
3208 struct iwl_rxon_context *ctx;
3198 struct ieee80211_conf *conf = NULL; 3209 struct ieee80211_conf *conf = NULL;
3199 int ret = 0; 3210 int ret = 0;
3200 3211
3201 if (!vif || !priv->is_open) 3212 if (!vif || !priv->is_open)
3202 return; 3213 return;
3203 3214
3215 ctx = iwl_rxon_ctx_from_vif(vif);
3216
3204 if (vif->type == NL80211_IFTYPE_AP) { 3217 if (vif->type == NL80211_IFTYPE_AP) {
3205 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 3218 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
3206 return; 3219 return;
@@ -3213,42 +3226,42 @@ void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3213 3226
3214 conf = ieee80211_get_hw_conf(priv->hw); 3227 conf = ieee80211_get_hw_conf(priv->hw);
3215 3228
3216 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3229 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3217 iwlcore_commit_rxon(priv); 3230 iwlcore_commit_rxon(priv, ctx);
3218 3231
3219 ret = iwl_send_rxon_timing(priv, vif); 3232 ret = iwl_send_rxon_timing(priv, vif);
3220 if (ret) 3233 if (ret)
3221 IWL_WARN(priv, "REPLY_RXON_TIMING failed - " 3234 IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
3222 "Attempting to continue.\n"); 3235 "Attempting to continue.\n");
3223 3236
3224 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3237 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3225 3238
3226 iwl_set_rxon_ht(priv, &priv->current_ht_config); 3239 iwl_set_rxon_ht(priv, &priv->current_ht_config);
3227 3240
3228 if (priv->cfg->ops->hcmd->set_rxon_chain) 3241 if (priv->cfg->ops->hcmd->set_rxon_chain)
3229 priv->cfg->ops->hcmd->set_rxon_chain(priv); 3242 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
3230 3243
3231 priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid); 3244 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
3232 3245
3233 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3246 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3234 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3247 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3235 3248
3236 if (vif->bss_conf.use_short_preamble) 3249 if (vif->bss_conf.use_short_preamble)
3237 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3250 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3238 else 3251 else
3239 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3252 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3240 3253
3241 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3254 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3242 if (vif->bss_conf.use_short_slot) 3255 if (vif->bss_conf.use_short_slot)
3243 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3256 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
3244 else 3257 else
3245 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3258 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3246 } 3259 }
3247 3260
3248 iwlcore_commit_rxon(priv); 3261 iwlcore_commit_rxon(priv, ctx);
3249 3262
3250 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 3263 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3251 vif->bss_conf.aid, priv->active_rxon.bssid_addr); 3264 vif->bss_conf.aid, ctx->active.bssid_addr);
3252 3265
3253 switch (vif->type) { 3266 switch (vif->type) {
3254 case NL80211_IFTYPE_STATION: 3267 case NL80211_IFTYPE_STATION:
@@ -3439,17 +3452,18 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3439 3452
3440void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) 3453void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3441{ 3454{
3455 struct iwl_rxon_context *ctx = iwl_rxon_ctx_from_vif(vif);
3442 int ret = 0; 3456 int ret = 0;
3443 3457
3444 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3458 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3445 return; 3459 return;
3446 3460
3447 /* The following should be done only at AP bring up */ 3461 /* The following should be done only at AP bring up */
3448 if (!iwl_is_associated(priv)) { 3462 if (!iwl_is_associated_ctx(ctx)) {
3449 3463
3450 /* RXON - unassoc (to set timing command) */ 3464 /* RXON - unassoc (to set timing command) */
3451 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3465 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3452 iwlcore_commit_rxon(priv); 3466 iwlcore_commit_rxon(priv, ctx);
3453 3467
3454 /* RXON Timing */ 3468 /* RXON Timing */
3455 ret = iwl_send_rxon_timing(priv, vif); 3469 ret = iwl_send_rxon_timing(priv, vif);
@@ -3462,28 +3476,28 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3462 priv->hw_params.valid_rx_ant; 3476 priv->hw_params.valid_rx_ant;
3463 iwl_set_rxon_ht(priv, &priv->current_ht_config); 3477 iwl_set_rxon_ht(priv, &priv->current_ht_config);
3464 if (priv->cfg->ops->hcmd->set_rxon_chain) 3478 if (priv->cfg->ops->hcmd->set_rxon_chain)
3465 priv->cfg->ops->hcmd->set_rxon_chain(priv); 3479 priv->cfg->ops->hcmd->set_rxon_chain(priv, ctx);
3466 3480
3467 priv->staging_rxon.assoc_id = 0; 3481 ctx->staging.assoc_id = 0;
3468 3482
3469 if (vif->bss_conf.use_short_preamble) 3483 if (vif->bss_conf.use_short_preamble)
3470 priv->staging_rxon.flags |= 3484 ctx->staging.flags |=
3471 RXON_FLG_SHORT_PREAMBLE_MSK; 3485 RXON_FLG_SHORT_PREAMBLE_MSK;
3472 else 3486 else
3473 priv->staging_rxon.flags &= 3487 ctx->staging.flags &=
3474 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3488 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3475 3489
3476 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3490 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3477 if (vif->bss_conf.use_short_slot) 3491 if (vif->bss_conf.use_short_slot)
3478 priv->staging_rxon.flags |= 3492 ctx->staging.flags |=
3479 RXON_FLG_SHORT_SLOT_MSK; 3493 RXON_FLG_SHORT_SLOT_MSK;
3480 else 3494 else
3481 priv->staging_rxon.flags &= 3495 ctx->staging.flags &=
3482 ~RXON_FLG_SHORT_SLOT_MSK; 3496 ~RXON_FLG_SHORT_SLOT_MSK;
3483 } 3497 }
3484 /* restore RXON assoc */ 3498 /* restore RXON assoc */
3485 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3499 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3486 iwlcore_commit_rxon(priv); 3500 iwlcore_commit_rxon(priv, ctx);
3487 } 3501 }
3488 iwl_send_beacon_cmd(priv); 3502 iwl_send_beacon_cmd(priv);
3489 3503
@@ -3737,6 +3751,15 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
3737 struct ieee80211_conf *conf = &hw->conf; 3751 struct ieee80211_conf *conf = &hw->conf;
3738 struct ieee80211_channel *channel = ch_switch->channel; 3752 struct ieee80211_channel *channel = ch_switch->channel;
3739 struct iwl_ht_config *ht_conf = &priv->current_ht_config; 3753 struct iwl_ht_config *ht_conf = &priv->current_ht_config;
3754 /*
3755 * MULTI-FIXME
3756 * When we add support for multiple interfaces, we need to
3757 * revisit this. The channel switch command in the device
3758 * only affects the BSS context, but what does that really
3759 * mean? And what if we get a CSA on the second interface?
3760 * This needs a lot of work.
3761 */
3762 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3740 u16 ch; 3763 u16 ch;
3741 unsigned long flags = 0; 3764 unsigned long flags = 0;
3742 3765
@@ -3749,7 +3772,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
3749 test_bit(STATUS_SCANNING, &priv->status)) 3772 test_bit(STATUS_SCANNING, &priv->status))
3750 goto out_exit; 3773 goto out_exit;
3751 3774
3752 if (!iwl_is_associated(priv)) 3775 if (!iwl_is_associated_ctx(ctx))
3753 goto out_exit; 3776 goto out_exit;
3754 3777
3755 /* channel switch in progress */ 3778 /* channel switch in progress */
@@ -3760,7 +3783,7 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
3760 if (priv->cfg->ops->lib->set_channel_switch) { 3783 if (priv->cfg->ops->lib->set_channel_switch) {
3761 3784
3762 ch = channel->hw_value; 3785 ch = channel->hw_value;
3763 if (le16_to_cpu(priv->active_rxon.channel) != ch) { 3786 if (le16_to_cpu(ctx->active.channel) != ch) {
3764 ch_info = iwl_get_channel_info(priv, 3787 ch_info = iwl_get_channel_info(priv,
3765 channel->band, 3788 channel->band,
3766 ch); 3789 ch);
@@ -3791,12 +3814,12 @@ static void iwl_mac_channel_switch(struct ieee80211_hw *hw,
3791 } else 3814 } else
3792 ht_conf->is_40mhz = false; 3815 ht_conf->is_40mhz = false;
3793 3816
3794 if (le16_to_cpu(priv->staging_rxon.channel) != ch) 3817 if ((le16_to_cpu(ctx->staging.channel) != ch))
3795 priv->staging_rxon.flags = 0; 3818 ctx->staging.flags = 0;
3796 3819
3797 iwl_set_rxon_channel(priv, channel); 3820 iwl_set_rxon_channel(priv, channel, ctx);
3798 iwl_set_rxon_ht(priv, ht_conf); 3821 iwl_set_rxon_ht(priv, ht_conf);
3799 iwl_set_flags_for_band(priv, channel->band, 3822 iwl_set_flags_for_band(priv, ctx, channel->band,
3800 priv->vif); 3823 priv->vif);
3801 spin_unlock_irqrestore(&priv->lock, flags); 3824 spin_unlock_irqrestore(&priv->lock, flags);
3802 3825
@@ -3825,6 +3848,7 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
3825{ 3848{
3826 struct iwl_priv *priv = hw->priv; 3849 struct iwl_priv *priv = hw->priv;
3827 __le32 filter_or = 0, filter_nand = 0; 3850 __le32 filter_or = 0, filter_nand = 0;
3851 struct iwl_rxon_context *ctx;
3828 3852
3829#define CHK(test, flag) do { \ 3853#define CHK(test, flag) do { \
3830 if (*total_flags & (test)) \ 3854 if (*total_flags & (test)) \
@@ -3844,10 +3868,11 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
3844 3868
3845 mutex_lock(&priv->mutex); 3869 mutex_lock(&priv->mutex);
3846 3870
3847 priv->staging_rxon.filter_flags &= ~filter_nand; 3871 for_each_context(priv, ctx) {
3848 priv->staging_rxon.filter_flags |= filter_or; 3872 ctx->staging.filter_flags &= ~filter_nand;
3849 3873 ctx->staging.filter_flags |= filter_or;
3850 iwlcore_commit_rxon(priv); 3874 iwlcore_commit_rxon(priv, ctx);
3875 }
3851 3876
3852 mutex_unlock(&priv->mutex); 3877 mutex_unlock(&priv->mutex);
3853 3878
@@ -4018,7 +4043,8 @@ static int iwl_init_drv(struct iwl_priv *priv)
4018 4043
4019 /* Choose which receivers/antennas to use */ 4044 /* Choose which receivers/antennas to use */
4020 if (priv->cfg->ops->hcmd->set_rxon_chain) 4045 if (priv->cfg->ops->hcmd->set_rxon_chain)
4021 priv->cfg->ops->hcmd->set_rxon_chain(priv); 4046 priv->cfg->ops->hcmd->set_rxon_chain(priv,
4047 &priv->contexts[IWL_RXON_CTX_BSS]);
4022 4048
4023 iwl_init_scan_params(priv); 4049 iwl_init_scan_params(priv);
4024 4050
@@ -4118,7 +4144,7 @@ static int iwl_set_hw_params(struct iwl_priv *priv)
4118 4144
4119static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 4145static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4120{ 4146{
4121 int err = 0; 4147 int err = 0, i;
4122 struct iwl_priv *priv; 4148 struct iwl_priv *priv;
4123 struct ieee80211_hw *hw; 4149 struct ieee80211_hw *hw;
4124 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); 4150 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
@@ -4146,6 +4172,16 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
4146 priv = hw->priv; 4172 priv = hw->priv;
4147 /* At this point both hw and priv are allocated. */ 4173 /* At this point both hw and priv are allocated. */
4148 4174
4175 /*
4176 * The default context is always valid,
4177 * more may be discovered when firmware
4178 * is loaded.
4179 */
4180 priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
4181
4182 for (i = 0; i < NUM_IWL_RXON_CTX; i++)
4183 priv->contexts[i].ctxid = i;
4184
4149 SET_IEEE80211_DEV(hw, &pdev->dev); 4185 SET_IEEE80211_DEV(hw, &pdev->dev);
4150 4186
4151 IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n"); 4187 IWL_DEBUG_INFO(priv, "*** LOAD DRIVER ***\n");