aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl3945-base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c175
1 files changed, 109 insertions, 66 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 94d7e6e1323d..68e624afb987 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -144,7 +144,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
144 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); 144 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
145 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); 145 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
146 146
147 if (sta_id == priv->hw_params.bcast_sta_id) 147 if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id)
148 key_flags |= STA_KEY_MULTICAST_MSK; 148 key_flags |= STA_KEY_MULTICAST_MSK;
149 149
150 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 150 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -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)
@@ -343,7 +343,8 @@ static int iwl3945_send_beacon_cmd(struct iwl_priv *priv)
343 return -ENOMEM; 343 return -ENOMEM;
344 } 344 }
345 345
346 rate = iwl_rate_get_lowest_plcp(priv); 346 rate = iwl_rate_get_lowest_plcp(priv,
347 &priv->contexts[IWL_RXON_CTX_BSS]);
347 348
348 frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate); 349 frame_size = iwl3945_hw_get_beacon_cmd(priv, frame, rate);
349 350
@@ -512,7 +513,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
512 hdr_len = ieee80211_hdrlen(fc); 513 hdr_len = ieee80211_hdrlen(fc);
513 514
514 /* Find index into station table for destination station */ 515 /* Find index into station table for destination station */
515 sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); 516 sta_id = iwl_sta_id_or_broadcast(
517 priv, &priv->contexts[IWL_RXON_CTX_BSS],
518 info->control.sta);
516 if (sta_id == IWL_INVALID_STATION) { 519 if (sta_id == IWL_INVALID_STATION) {
517 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 520 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
518 hdr->addr1); 521 hdr->addr1);
@@ -542,6 +545,7 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
542 /* Set up driver data for this TFD */ 545 /* Set up driver data for this TFD */
543 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); 546 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
544 txq->txb[q->write_ptr].skb = skb; 547 txq->txb[q->write_ptr].skb = skb;
548 txq->txb[q->write_ptr].ctx = &priv->contexts[IWL_RXON_CTX_BSS];
545 549
546 /* Init first empty entry in queue's array of Tx/cmd buffers */ 550 /* Init first empty entry in queue's array of Tx/cmd buffers */
547 out_cmd = txq->cmd[idx]; 551 out_cmd = txq->cmd[idx];
@@ -683,11 +687,12 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
683 int rc; 687 int rc;
684 int spectrum_resp_status; 688 int spectrum_resp_status;
685 int duration = le16_to_cpu(params->duration); 689 int duration = le16_to_cpu(params->duration);
690 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
686 691
687 if (iwl_is_associated(priv)) 692 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS))
688 add_time = iwl_usecs_to_beacons(priv, 693 add_time = iwl_usecs_to_beacons(priv,
689 le64_to_cpu(params->start_time) - priv->_3945.last_tsf, 694 le64_to_cpu(params->start_time) - priv->_3945.last_tsf,
690 le16_to_cpu(priv->rxon_timing.beacon_interval)); 695 le16_to_cpu(ctx->timing.beacon_interval));
691 696
692 memset(&spectrum, 0, sizeof(spectrum)); 697 memset(&spectrum, 0, sizeof(spectrum));
693 698
@@ -698,18 +703,18 @@ static int iwl3945_get_measurement(struct iwl_priv *priv,
698 cmd.len = sizeof(spectrum); 703 cmd.len = sizeof(spectrum);
699 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len)); 704 spectrum.len = cpu_to_le16(cmd.len - sizeof(spectrum.len));
700 705
701 if (iwl_is_associated(priv)) 706 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS))
702 spectrum.start_time = 707 spectrum.start_time =
703 iwl_add_beacon_time(priv, 708 iwl_add_beacon_time(priv,
704 priv->_3945.last_beacon_time, add_time, 709 priv->_3945.last_beacon_time, add_time,
705 le16_to_cpu(priv->rxon_timing.beacon_interval)); 710 le16_to_cpu(ctx->timing.beacon_interval));
706 else 711 else
707 spectrum.start_time = 0; 712 spectrum.start_time = 0;
708 713
709 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT); 714 spectrum.channels[0].duration = cpu_to_le32(duration * TIME_UNIT);
710 spectrum.channels[0].channel = params->channel; 715 spectrum.channels[0].channel = params->channel;
711 spectrum.channels[0].type = type; 716 spectrum.channels[0].type = type;
712 if (priv->active_rxon.flags & RXON_FLG_BAND_24G_MSK) 717 if (ctx->active.flags & RXON_FLG_BAND_24G_MSK)
713 spectrum.flags |= RXON_FLG_BAND_24G_MSK | 718 spectrum.flags |= RXON_FLG_BAND_24G_MSK |
714 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK; 719 RXON_FLG_AUTO_DETECT_MSK | RXON_FLG_TGG_PROTECT_MSK;
715 720
@@ -798,7 +803,8 @@ static void iwl3945_bg_beacon_update(struct work_struct *work)
798 struct sk_buff *beacon; 803 struct sk_buff *beacon;
799 804
800 /* Pull updated AP beacon from mac80211. will fail if not in AP mode */ 805 /* Pull updated AP beacon from mac80211. will fail if not in AP mode */
801 beacon = ieee80211_beacon_get(priv->hw, priv->vif); 806 beacon = ieee80211_beacon_get(priv->hw,
807 priv->contexts[IWL_RXON_CTX_BSS].vif);
802 808
803 if (!beacon) { 809 if (!beacon) {
804 IWL_ERR(priv, "update beacon failed\n"); 810 IWL_ERR(priv, "update beacon failed\n");
@@ -2468,6 +2474,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2468{ 2474{
2469 int thermal_spin = 0; 2475 int thermal_spin = 0;
2470 u32 rfkill; 2476 u32 rfkill;
2477 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
2471 2478
2472 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n"); 2479 IWL_DEBUG_INFO(priv, "Runtime Alive received.\n");
2473 2480
@@ -2525,22 +2532,22 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2525 2532
2526 iwl_power_update_mode(priv, true); 2533 iwl_power_update_mode(priv, true);
2527 2534
2528 if (iwl_is_associated(priv)) { 2535 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
2529 struct iwl3945_rxon_cmd *active_rxon = 2536 struct iwl3945_rxon_cmd *active_rxon =
2530 (struct iwl3945_rxon_cmd *)(&priv->active_rxon); 2537 (struct iwl3945_rxon_cmd *)(&ctx->active);
2531 2538
2532 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 2539 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
2533 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2540 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2534 } else { 2541 } else {
2535 /* Initialize our rx_config data */ 2542 /* Initialize our rx_config data */
2536 iwl_connection_init_rx_config(priv, NULL); 2543 iwl_connection_init_rx_config(priv, ctx);
2537 } 2544 }
2538 2545
2539 /* Configure Bluetooth device coexistence support */ 2546 /* Configure Bluetooth device coexistence support */
2540 priv->cfg->ops->hcmd->send_bt_config(priv); 2547 priv->cfg->ops->hcmd->send_bt_config(priv);
2541 2548
2542 /* Configure the adapter for unassociated operation */ 2549 /* Configure the adapter for unassociated operation */
2543 iwlcore_commit_rxon(priv); 2550 iwlcore_commit_rxon(priv, ctx);
2544 2551
2545 iwl3945_reg_txpower_periodic(priv); 2552 iwl3945_reg_txpower_periodic(priv);
2546 2553
@@ -2571,9 +2578,14 @@ static void __iwl3945_down(struct iwl_priv *priv)
2571 if (!exit_pending) 2578 if (!exit_pending)
2572 set_bit(STATUS_EXIT_PENDING, &priv->status); 2579 set_bit(STATUS_EXIT_PENDING, &priv->status);
2573 2580
2581 /* Stop TX queues watchdog. We need to have STATUS_EXIT_PENDING bit set
2582 * to prevent rearm timer */
2583 if (priv->cfg->ops->lib->recover_from_tx_stall)
2584 del_timer_sync(&priv->monitor_recover);
2585
2574 /* Station information will now be cleared in device */ 2586 /* Station information will now be cleared in device */
2575 iwl_clear_ucode_stations(priv); 2587 iwl_clear_ucode_stations(priv, NULL);
2576 iwl_dealloc_bcast_station(priv); 2588 iwl_dealloc_bcast_stations(priv);
2577 iwl_clear_driver_stations(priv); 2589 iwl_clear_driver_stations(priv);
2578 2590
2579 /* Unblock any waiting calls */ 2591 /* Unblock any waiting calls */
@@ -2655,7 +2667,8 @@ static int __iwl3945_up(struct iwl_priv *priv)
2655{ 2667{
2656 int rc, i; 2668 int rc, i;
2657 2669
2658 rc = iwl_alloc_bcast_station(priv, false); 2670 rc = iwl_alloc_bcast_station(priv, &priv->contexts[IWL_RXON_CTX_BSS],
2671 false);
2659 if (rc) 2672 if (rc)
2660 return rc; 2673 return rc;
2661 2674
@@ -2878,7 +2891,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2878 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH; 2891 scan->quiet_plcp_th = IWL_PLCP_QUIET_THRESH;
2879 scan->quiet_time = IWL_ACTIVE_QUIET_TIME; 2892 scan->quiet_time = IWL_ACTIVE_QUIET_TIME;
2880 2893
2881 if (iwl_is_associated(priv)) { 2894 if (iwl_is_associated(priv, IWL_RXON_CTX_BSS)) {
2882 u16 interval = 0; 2895 u16 interval = 0;
2883 u32 extra; 2896 u32 extra;
2884 u32 suspend_time = 100; 2897 u32 suspend_time = 100;
@@ -2939,7 +2952,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2939 /* We don't build a direct scan probe request; the uCode will do 2952 /* We don't build a direct scan probe request; the uCode will do
2940 * that based on the direct_mask added to each channel entry */ 2953 * that based on the direct_mask added to each channel entry */
2941 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; 2954 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
2942 scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; 2955 scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
2943 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 2956 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
2944 2957
2945 /* flags + rate selection */ 2958 /* flags + rate selection */
@@ -3037,8 +3050,10 @@ static void iwl3945_bg_restart(struct work_struct *data)
3037 return; 3050 return;
3038 3051
3039 if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) { 3052 if (test_and_clear_bit(STATUS_FW_ERROR, &priv->status)) {
3053 struct iwl_rxon_context *ctx;
3040 mutex_lock(&priv->mutex); 3054 mutex_lock(&priv->mutex);
3041 priv->vif = NULL; 3055 for_each_context(priv, ctx)
3056 ctx->vif = NULL;
3042 priv->is_open = 0; 3057 priv->is_open = 0;
3043 mutex_unlock(&priv->mutex); 3058 mutex_unlock(&priv->mutex);
3044 iwl3945_down(priv); 3059 iwl3945_down(priv);
@@ -3072,6 +3087,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3072{ 3087{
3073 int rc = 0; 3088 int rc = 0;
3074 struct ieee80211_conf *conf = NULL; 3089 struct ieee80211_conf *conf = NULL;
3090 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3075 3091
3076 if (!vif || !priv->is_open) 3092 if (!vif || !priv->is_open)
3077 return; 3093 return;
@@ -3082,7 +3098,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3082 } 3098 }
3083 3099
3084 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 3100 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3085 vif->bss_conf.aid, priv->active_rxon.bssid_addr); 3101 vif->bss_conf.aid, ctx->active.bssid_addr);
3086 3102
3087 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3103 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3088 return; 3104 return;
@@ -3091,34 +3107,34 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3091 3107
3092 conf = ieee80211_get_hw_conf(priv->hw); 3108 conf = ieee80211_get_hw_conf(priv->hw);
3093 3109
3094 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3110 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3095 iwlcore_commit_rxon(priv); 3111 iwlcore_commit_rxon(priv, ctx);
3096 3112
3097 rc = iwl_send_rxon_timing(priv, vif); 3113 rc = iwl_send_rxon_timing(priv, ctx);
3098 if (rc) 3114 if (rc)
3099 IWL_WARN(priv, "REPLY_RXON_TIMING failed - " 3115 IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
3100 "Attempting to continue.\n"); 3116 "Attempting to continue.\n");
3101 3117
3102 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3118 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3103 3119
3104 priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid); 3120 ctx->staging.assoc_id = cpu_to_le16(vif->bss_conf.aid);
3105 3121
3106 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3122 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3107 vif->bss_conf.aid, vif->bss_conf.beacon_int); 3123 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3108 3124
3109 if (vif->bss_conf.use_short_preamble) 3125 if (vif->bss_conf.use_short_preamble)
3110 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3126 ctx->staging.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3111 else 3127 else
3112 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3128 ctx->staging.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3113 3129
3114 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3130 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3115 if (vif->bss_conf.use_short_slot) 3131 if (vif->bss_conf.use_short_slot)
3116 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3132 ctx->staging.flags |= RXON_FLG_SHORT_SLOT_MSK;
3117 else 3133 else
3118 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3134 ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3119 } 3135 }
3120 3136
3121 iwlcore_commit_rxon(priv); 3137 iwlcore_commit_rxon(priv, ctx);
3122 3138
3123 switch (vif->type) { 3139 switch (vif->type) {
3124 case NL80211_IFTYPE_STATION: 3140 case NL80211_IFTYPE_STATION:
@@ -3255,44 +3271,45 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3255 3271
3256void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) 3272void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3257{ 3273{
3274 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3258 int rc = 0; 3275 int rc = 0;
3259 3276
3260 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3277 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3261 return; 3278 return;
3262 3279
3263 /* The following should be done only at AP bring up */ 3280 /* The following should be done only at AP bring up */
3264 if (!(iwl_is_associated(priv))) { 3281 if (!(iwl_is_associated(priv, IWL_RXON_CTX_BSS))) {
3265 3282
3266 /* RXON - unassoc (to set timing command) */ 3283 /* RXON - unassoc (to set timing command) */
3267 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 3284 ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
3268 iwlcore_commit_rxon(priv); 3285 iwlcore_commit_rxon(priv, ctx);
3269 3286
3270 /* RXON Timing */ 3287 /* RXON Timing */
3271 rc = iwl_send_rxon_timing(priv, vif); 3288 rc = iwl_send_rxon_timing(priv, ctx);
3272 if (rc) 3289 if (rc)
3273 IWL_WARN(priv, "REPLY_RXON_TIMING failed - " 3290 IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
3274 "Attempting to continue.\n"); 3291 "Attempting to continue.\n");
3275 3292
3276 priv->staging_rxon.assoc_id = 0; 3293 ctx->staging.assoc_id = 0;
3277 3294
3278 if (vif->bss_conf.use_short_preamble) 3295 if (vif->bss_conf.use_short_preamble)
3279 priv->staging_rxon.flags |= 3296 ctx->staging.flags |=
3280 RXON_FLG_SHORT_PREAMBLE_MSK; 3297 RXON_FLG_SHORT_PREAMBLE_MSK;
3281 else 3298 else
3282 priv->staging_rxon.flags &= 3299 ctx->staging.flags &=
3283 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3300 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3284 3301
3285 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3302 if (ctx->staging.flags & RXON_FLG_BAND_24G_MSK) {
3286 if (vif->bss_conf.use_short_slot) 3303 if (vif->bss_conf.use_short_slot)
3287 priv->staging_rxon.flags |= 3304 ctx->staging.flags |=
3288 RXON_FLG_SHORT_SLOT_MSK; 3305 RXON_FLG_SHORT_SLOT_MSK;
3289 else 3306 else
3290 priv->staging_rxon.flags &= 3307 ctx->staging.flags &=
3291 ~RXON_FLG_SHORT_SLOT_MSK; 3308 ~RXON_FLG_SHORT_SLOT_MSK;
3292 } 3309 }
3293 /* restore RXON assoc */ 3310 /* restore RXON assoc */
3294 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3311 ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK;
3295 iwlcore_commit_rxon(priv); 3312 iwlcore_commit_rxon(priv, ctx);
3296 } 3313 }
3297 iwl3945_send_beacon_cmd(priv); 3314 iwl3945_send_beacon_cmd(priv);
3298 3315
@@ -3318,10 +3335,11 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3318 return -EOPNOTSUPP; 3335 return -EOPNOTSUPP;
3319 } 3336 }
3320 3337
3321 static_key = !iwl_is_associated(priv); 3338 static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS);
3322 3339
3323 if (!static_key) { 3340 if (!static_key) {
3324 sta_id = iwl_sta_id_or_broadcast(priv, sta); 3341 sta_id = iwl_sta_id_or_broadcast(
3342 priv, &priv->contexts[IWL_RXON_CTX_BSS], sta);
3325 if (sta_id == IWL_INVALID_STATION) 3343 if (sta_id == IWL_INVALID_STATION)
3326 return -EINVAL; 3344 return -EINVAL;
3327 } 3345 }
@@ -3372,8 +3390,8 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
3372 sta_priv->common.sta_id = IWL_INVALID_STATION; 3390 sta_priv->common.sta_id = IWL_INVALID_STATION;
3373 3391
3374 3392
3375 ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, 3393 ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS],
3376 &sta_id); 3394 sta->addr, is_ap, sta, &sta_id);
3377 if (ret) { 3395 if (ret) {
3378 IWL_ERR(priv, "Unable to add station %pM (%d)\n", 3396 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
3379 sta->addr, ret); 3397 sta->addr, ret);
@@ -3400,6 +3418,7 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
3400{ 3418{
3401 struct iwl_priv *priv = hw->priv; 3419 struct iwl_priv *priv = hw->priv;
3402 __le32 filter_or = 0, filter_nand = 0; 3420 __le32 filter_or = 0, filter_nand = 0;
3421 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3403 3422
3404#define CHK(test, flag) do { \ 3423#define CHK(test, flag) do { \
3405 if (*total_flags & (test)) \ 3424 if (*total_flags & (test)) \
@@ -3419,8 +3438,8 @@ static void iwl3945_configure_filter(struct ieee80211_hw *hw,
3419 3438
3420 mutex_lock(&priv->mutex); 3439 mutex_lock(&priv->mutex);
3421 3440
3422 priv->staging_rxon.filter_flags &= ~filter_nand; 3441 ctx->staging.filter_flags &= ~filter_nand;
3423 priv->staging_rxon.filter_flags |= filter_or; 3442 ctx->staging.filter_flags |= filter_or;
3424 3443
3425 /* 3444 /*
3426 * Committing directly here breaks for some reason, 3445 * Committing directly here breaks for some reason,
@@ -3534,8 +3553,9 @@ static ssize_t show_flags(struct device *d,
3534 struct device_attribute *attr, char *buf) 3553 struct device_attribute *attr, char *buf)
3535{ 3554{
3536 struct iwl_priv *priv = dev_get_drvdata(d); 3555 struct iwl_priv *priv = dev_get_drvdata(d);
3556 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3537 3557
3538 return sprintf(buf, "0x%04X\n", priv->active_rxon.flags); 3558 return sprintf(buf, "0x%04X\n", ctx->active.flags);
3539} 3559}
3540 3560
3541static ssize_t store_flags(struct device *d, 3561static ssize_t store_flags(struct device *d,
@@ -3544,17 +3564,18 @@ static ssize_t store_flags(struct device *d,
3544{ 3564{
3545 struct iwl_priv *priv = dev_get_drvdata(d); 3565 struct iwl_priv *priv = dev_get_drvdata(d);
3546 u32 flags = simple_strtoul(buf, NULL, 0); 3566 u32 flags = simple_strtoul(buf, NULL, 0);
3567 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3547 3568
3548 mutex_lock(&priv->mutex); 3569 mutex_lock(&priv->mutex);
3549 if (le32_to_cpu(priv->staging_rxon.flags) != flags) { 3570 if (le32_to_cpu(ctx->staging.flags) != flags) {
3550 /* Cancel any currently running scans... */ 3571 /* Cancel any currently running scans... */
3551 if (iwl_scan_cancel_timeout(priv, 100)) 3572 if (iwl_scan_cancel_timeout(priv, 100))
3552 IWL_WARN(priv, "Could not cancel scan.\n"); 3573 IWL_WARN(priv, "Could not cancel scan.\n");
3553 else { 3574 else {
3554 IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", 3575 IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n",
3555 flags); 3576 flags);
3556 priv->staging_rxon.flags = cpu_to_le32(flags); 3577 ctx->staging.flags = cpu_to_le32(flags);
3557 iwlcore_commit_rxon(priv); 3578 iwlcore_commit_rxon(priv, ctx);
3558 } 3579 }
3559 } 3580 }
3560 mutex_unlock(&priv->mutex); 3581 mutex_unlock(&priv->mutex);
@@ -3568,9 +3589,10 @@ static ssize_t show_filter_flags(struct device *d,
3568 struct device_attribute *attr, char *buf) 3589 struct device_attribute *attr, char *buf)
3569{ 3590{
3570 struct iwl_priv *priv = dev_get_drvdata(d); 3591 struct iwl_priv *priv = dev_get_drvdata(d);
3592 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3571 3593
3572 return sprintf(buf, "0x%04X\n", 3594 return sprintf(buf, "0x%04X\n",
3573 le32_to_cpu(priv->active_rxon.filter_flags)); 3595 le32_to_cpu(ctx->active.filter_flags));
3574} 3596}
3575 3597
3576static ssize_t store_filter_flags(struct device *d, 3598static ssize_t store_filter_flags(struct device *d,
@@ -3578,19 +3600,20 @@ static ssize_t store_filter_flags(struct device *d,
3578 const char *buf, size_t count) 3600 const char *buf, size_t count)
3579{ 3601{
3580 struct iwl_priv *priv = dev_get_drvdata(d); 3602 struct iwl_priv *priv = dev_get_drvdata(d);
3603 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3581 u32 filter_flags = simple_strtoul(buf, NULL, 0); 3604 u32 filter_flags = simple_strtoul(buf, NULL, 0);
3582 3605
3583 mutex_lock(&priv->mutex); 3606 mutex_lock(&priv->mutex);
3584 if (le32_to_cpu(priv->staging_rxon.filter_flags) != filter_flags) { 3607 if (le32_to_cpu(ctx->staging.filter_flags) != filter_flags) {
3585 /* Cancel any currently running scans... */ 3608 /* Cancel any currently running scans... */
3586 if (iwl_scan_cancel_timeout(priv, 100)) 3609 if (iwl_scan_cancel_timeout(priv, 100))
3587 IWL_WARN(priv, "Could not cancel scan.\n"); 3610 IWL_WARN(priv, "Could not cancel scan.\n");
3588 else { 3611 else {
3589 IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = " 3612 IWL_DEBUG_INFO(priv, "Committing rxon.filter_flags = "
3590 "0x%04X\n", filter_flags); 3613 "0x%04X\n", filter_flags);
3591 priv->staging_rxon.filter_flags = 3614 ctx->staging.filter_flags =
3592 cpu_to_le32(filter_flags); 3615 cpu_to_le32(filter_flags);
3593 iwlcore_commit_rxon(priv); 3616 iwlcore_commit_rxon(priv, ctx);
3594 } 3617 }
3595 } 3618 }
3596 mutex_unlock(&priv->mutex); 3619 mutex_unlock(&priv->mutex);
@@ -3638,8 +3661,9 @@ static ssize_t store_measurement(struct device *d,
3638 const char *buf, size_t count) 3661 const char *buf, size_t count)
3639{ 3662{
3640 struct iwl_priv *priv = dev_get_drvdata(d); 3663 struct iwl_priv *priv = dev_get_drvdata(d);
3664 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
3641 struct ieee80211_measurement_params params = { 3665 struct ieee80211_measurement_params params = {
3642 .channel = le16_to_cpu(priv->active_rxon.channel), 3666 .channel = le16_to_cpu(ctx->active.channel),
3643 .start_time = cpu_to_le64(priv->_3945.last_tsf), 3667 .start_time = cpu_to_le64(priv->_3945.last_tsf),
3644 .duration = cpu_to_le16(1), 3668 .duration = cpu_to_le16(1),
3645 }; 3669 };
@@ -3811,8 +3835,6 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
3811 cancel_delayed_work(&priv->alive_start); 3835 cancel_delayed_work(&priv->alive_start);
3812 cancel_work_sync(&priv->start_internal_scan); 3836 cancel_work_sync(&priv->start_internal_scan);
3813 cancel_work_sync(&priv->beacon_update); 3837 cancel_work_sync(&priv->beacon_update);
3814 if (priv->cfg->ops->lib->recover_from_tx_stall)
3815 del_timer_sync(&priv->monitor_recover);
3816} 3838}
3817 3839
3818static struct attribute *iwl3945_sysfs_entries[] = { 3840static struct attribute *iwl3945_sysfs_entries[] = {
@@ -3933,8 +3955,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3933 IEEE80211_HW_SUPPORTS_DYNAMIC_PS; 3955 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
3934 3956
3935 hw->wiphy->interface_modes = 3957 hw->wiphy->interface_modes =
3936 BIT(NL80211_IFTYPE_STATION) | 3958 priv->contexts[IWL_RXON_CTX_BSS].interface_modes;
3937 BIT(NL80211_IFTYPE_ADHOC);
3938 3959
3939 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY | 3960 hw->wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY |
3940 WIPHY_FLAG_DISABLE_BEACON_HINTS; 3961 WIPHY_FLAG_DISABLE_BEACON_HINTS;
@@ -3966,7 +3987,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3966 3987
3967static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 3988static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
3968{ 3989{
3969 int err = 0; 3990 int err = 0, i;
3970 struct iwl_priv *priv; 3991 struct iwl_priv *priv;
3971 struct ieee80211_hw *hw; 3992 struct ieee80211_hw *hw;
3972 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data); 3993 struct iwl_cfg *cfg = (struct iwl_cfg *)(ent->driver_data);
@@ -3988,6 +4009,27 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
3988 priv = hw->priv; 4009 priv = hw->priv;
3989 SET_IEEE80211_DEV(hw, &pdev->dev); 4010 SET_IEEE80211_DEV(hw, &pdev->dev);
3990 4011
4012 priv->cmd_queue = IWL39_CMD_QUEUE_NUM;
4013
4014 /* 3945 has only one valid context */
4015 priv->valid_contexts = BIT(IWL_RXON_CTX_BSS);
4016
4017 for (i = 0; i < NUM_IWL_RXON_CTX; i++)
4018 priv->contexts[i].ctxid = i;
4019
4020 priv->contexts[IWL_RXON_CTX_BSS].rxon_cmd = REPLY_RXON;
4021 priv->contexts[IWL_RXON_CTX_BSS].rxon_timing_cmd = REPLY_RXON_TIMING;
4022 priv->contexts[IWL_RXON_CTX_BSS].rxon_assoc_cmd = REPLY_RXON_ASSOC;
4023 priv->contexts[IWL_RXON_CTX_BSS].qos_cmd = REPLY_QOS_PARAM;
4024 priv->contexts[IWL_RXON_CTX_BSS].ap_sta_id = IWL_AP_ID;
4025 priv->contexts[IWL_RXON_CTX_BSS].wep_key_cmd = REPLY_WEPKEY;
4026 priv->contexts[IWL_RXON_CTX_BSS].interface_modes =
4027 BIT(NL80211_IFTYPE_STATION) |
4028 BIT(NL80211_IFTYPE_ADHOC);
4029 priv->contexts[IWL_RXON_CTX_BSS].ibss_devtype = RXON_DEV_TYPE_IBSS;
4030 priv->contexts[IWL_RXON_CTX_BSS].station_devtype = RXON_DEV_TYPE_ESS;
4031 priv->contexts[IWL_RXON_CTX_BSS].unused_devtype = RXON_DEV_TYPE_ESS;
4032
3991 /* 4033 /*
3992 * Disabling hardware scan means that mac80211 will perform scans 4034 * Disabling hardware scan means that mac80211 will perform scans
3993 * "the hard way", rather than using device's scan. 4035 * "the hard way", rather than using device's scan.
@@ -4123,7 +4165,8 @@ static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *e
4123 } 4165 }
4124 4166
4125 iwl_set_rxon_channel(priv, 4167 iwl_set_rxon_channel(priv,
4126 &priv->bands[IEEE80211_BAND_2GHZ].channels[5]); 4168 &priv->bands[IEEE80211_BAND_2GHZ].channels[5],
4169 &priv->contexts[IWL_RXON_CTX_BSS]);
4127 iwl3945_setup_deferred_work(priv); 4170 iwl3945_setup_deferred_work(priv);
4128 iwl3945_setup_rx_handlers(priv); 4171 iwl3945_setup_rx_handlers(priv);
4129 iwl_power_initialize(priv); 4172 iwl_power_initialize(priv);