diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 175 |
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 | ||
3256 | void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) | 3272 | void 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 | ||
3541 | static ssize_t store_flags(struct device *d, | 3561 | static 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 | ||
3576 | static ssize_t store_filter_flags(struct device *d, | 3598 | static 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 | ||
3818 | static struct attribute *iwl3945_sysfs_entries[] = { | 3840 | static 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 | ||
3967 | static int iwl3945_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 3988 | static 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); |