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/iwl-agn.c | |
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/iwl-agn.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 172 |
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 | */ |
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"); |