diff options
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 97 |
1 files changed, 65 insertions, 32 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 43db5f38e3e6..8f8c4b73f8b9 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -317,15 +317,15 @@ 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, IWL_RXON_CTX_BSS) || !priv->ibss_beacon) | 320 | if (!iwl_is_associated(priv, IWL_RXON_CTX_BSS) || !priv->beacon_skb) |
321 | return 0; | 321 | return 0; |
322 | 322 | ||
323 | if (priv->ibss_beacon->len > left) | 323 | if (priv->beacon_skb->len > left) |
324 | return 0; | 324 | return 0; |
325 | 325 | ||
326 | memcpy(hdr, priv->ibss_beacon->data, priv->ibss_beacon->len); | 326 | memcpy(hdr, priv->beacon_skb->data, priv->beacon_skb->len); |
327 | 327 | ||
328 | return priv->ibss_beacon->len; | 328 | return priv->beacon_skb->len; |
329 | } | 329 | } |
330 | 330 | ||
331 | static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) | 331 | static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) |
@@ -813,10 +813,10 @@ static void iwl3945_bg_beacon_update(struct work_struct *work) | |||
813 | 813 | ||
814 | mutex_lock(&priv->mutex); | 814 | mutex_lock(&priv->mutex); |
815 | /* new beacon skb is allocated every time; dispose previous.*/ | 815 | /* new beacon skb is allocated every time; dispose previous.*/ |
816 | if (priv->ibss_beacon) | 816 | if (priv->beacon_skb) |
817 | dev_kfree_skb(priv->ibss_beacon); | 817 | dev_kfree_skb(priv->beacon_skb); |
818 | 818 | ||
819 | priv->ibss_beacon = beacon; | 819 | priv->beacon_skb = beacon; |
820 | mutex_unlock(&priv->mutex); | 820 | mutex_unlock(&priv->mutex); |
821 | 821 | ||
822 | iwl3945_send_beacon_cmd(priv); | 822 | iwl3945_send_beacon_cmd(priv); |
@@ -2547,7 +2547,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv) | |||
2547 | priv->cfg->ops->hcmd->send_bt_config(priv); | 2547 | priv->cfg->ops->hcmd->send_bt_config(priv); |
2548 | 2548 | ||
2549 | /* Configure the adapter for unassociated operation */ | 2549 | /* Configure the adapter for unassociated operation */ |
2550 | iwlcore_commit_rxon(priv, ctx); | 2550 | iwl3945_commit_rxon(priv, ctx); |
2551 | 2551 | ||
2552 | iwl3945_reg_txpower_periodic(priv); | 2552 | iwl3945_reg_txpower_periodic(priv); |
2553 | 2553 | ||
@@ -2637,14 +2637,14 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2637 | udelay(5); | 2637 | udelay(5); |
2638 | 2638 | ||
2639 | /* Stop the device, and put it in low power state */ | 2639 | /* Stop the device, and put it in low power state */ |
2640 | priv->cfg->ops->lib->apm_ops.stop(priv); | 2640 | iwl_apm_stop(priv); |
2641 | 2641 | ||
2642 | exit: | 2642 | exit: |
2643 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); | 2643 | memset(&priv->card_alive, 0, sizeof(struct iwl_alive_resp)); |
2644 | 2644 | ||
2645 | if (priv->ibss_beacon) | 2645 | if (priv->beacon_skb) |
2646 | dev_kfree_skb(priv->ibss_beacon); | 2646 | dev_kfree_skb(priv->beacon_skb); |
2647 | priv->ibss_beacon = NULL; | 2647 | priv->beacon_skb = NULL; |
2648 | 2648 | ||
2649 | /* clear out any free frames */ | 2649 | /* clear out any free frames */ |
2650 | iwl3945_clear_free_frames(priv); | 2650 | iwl3945_clear_free_frames(priv); |
@@ -2661,12 +2661,33 @@ static void iwl3945_down(struct iwl_priv *priv) | |||
2661 | 2661 | ||
2662 | #define MAX_HW_RESTARTS 5 | 2662 | #define MAX_HW_RESTARTS 5 |
2663 | 2663 | ||
2664 | static int iwl3945_alloc_bcast_station(struct iwl_priv *priv) | ||
2665 | { | ||
2666 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
2667 | unsigned long flags; | ||
2668 | u8 sta_id; | ||
2669 | |||
2670 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
2671 | sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL); | ||
2672 | if (sta_id == IWL_INVALID_STATION) { | ||
2673 | IWL_ERR(priv, "Unable to prepare broadcast station\n"); | ||
2674 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
2675 | |||
2676 | return -EINVAL; | ||
2677 | } | ||
2678 | |||
2679 | priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; | ||
2680 | priv->stations[sta_id].used |= IWL_STA_BCAST; | ||
2681 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
2682 | |||
2683 | return 0; | ||
2684 | } | ||
2685 | |||
2664 | static int __iwl3945_up(struct iwl_priv *priv) | 2686 | static int __iwl3945_up(struct iwl_priv *priv) |
2665 | { | 2687 | { |
2666 | int rc, i; | 2688 | int rc, i; |
2667 | 2689 | ||
2668 | rc = iwl_alloc_bcast_station(priv, &priv->contexts[IWL_RXON_CTX_BSS], | 2690 | rc = iwl3945_alloc_bcast_station(priv); |
2669 | false); | ||
2670 | if (rc) | 2691 | if (rc) |
2671 | return rc; | 2692 | return rc; |
2672 | 2693 | ||
@@ -2917,18 +2938,10 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
2917 | case IEEE80211_BAND_2GHZ: | 2938 | case IEEE80211_BAND_2GHZ: |
2918 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; | 2939 | scan->flags = RXON_FLG_BAND_24G_MSK | RXON_FLG_AUTO_DETECT_MSK; |
2919 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; | 2940 | scan->tx_cmd.rate = IWL_RATE_1M_PLCP; |
2920 | scan->good_CRC_th = 0; | ||
2921 | band = IEEE80211_BAND_2GHZ; | 2941 | band = IEEE80211_BAND_2GHZ; |
2922 | break; | 2942 | break; |
2923 | case IEEE80211_BAND_5GHZ: | 2943 | case IEEE80211_BAND_5GHZ: |
2924 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; | 2944 | scan->tx_cmd.rate = IWL_RATE_6M_PLCP; |
2925 | /* | ||
2926 | * If active scaning is requested but a certain channel | ||
2927 | * is marked passive, we can do active scanning if we | ||
2928 | * detect transmissions. | ||
2929 | */ | ||
2930 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : | ||
2931 | IWL_GOOD_CRC_TH_DISABLED; | ||
2932 | band = IEEE80211_BAND_5GHZ; | 2945 | band = IEEE80211_BAND_5GHZ; |
2933 | break; | 2946 | break; |
2934 | default: | 2947 | default: |
@@ -2936,6 +2949,14 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
2936 | return -EIO; | 2949 | return -EIO; |
2937 | } | 2950 | } |
2938 | 2951 | ||
2952 | /* | ||
2953 | * If active scaning is requested but a certain channel | ||
2954 | * is marked passive, we can do active scanning if we | ||
2955 | * detect transmissions. | ||
2956 | */ | ||
2957 | scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : | ||
2958 | IWL_GOOD_CRC_TH_DISABLED; | ||
2959 | |||
2939 | if (!priv->is_internal_short_scan) { | 2960 | if (!priv->is_internal_short_scan) { |
2940 | scan->tx_cmd.len = cpu_to_le16( | 2961 | scan->tx_cmd.len = cpu_to_le16( |
2941 | iwl_fill_probe_req(priv, | 2962 | iwl_fill_probe_req(priv, |
@@ -2983,6 +3004,18 @@ int iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
2983 | return ret; | 3004 | return ret; |
2984 | } | 3005 | } |
2985 | 3006 | ||
3007 | void iwl3945_post_scan(struct iwl_priv *priv) | ||
3008 | { | ||
3009 | struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS]; | ||
3010 | |||
3011 | /* | ||
3012 | * Since setting the RXON may have been deferred while | ||
3013 | * performing the scan, fire one off if needed | ||
3014 | */ | ||
3015 | if (memcmp(&ctx->staging, &ctx->active, sizeof(ctx->staging))) | ||
3016 | iwl3945_commit_rxon(priv, ctx); | ||
3017 | } | ||
3018 | |||
2986 | static void iwl3945_bg_restart(struct work_struct *data) | 3019 | static void iwl3945_bg_restart(struct work_struct *data) |
2987 | { | 3020 | { |
2988 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); | 3021 | struct iwl_priv *priv = container_of(data, struct iwl_priv, restart); |
@@ -3049,7 +3082,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3049 | conf = ieee80211_get_hw_conf(priv->hw); | 3082 | conf = ieee80211_get_hw_conf(priv->hw); |
3050 | 3083 | ||
3051 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3084 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
3052 | iwlcore_commit_rxon(priv, ctx); | 3085 | iwl3945_commit_rxon(priv, ctx); |
3053 | 3086 | ||
3054 | rc = iwl_send_rxon_timing(priv, ctx); | 3087 | rc = iwl_send_rxon_timing(priv, ctx); |
3055 | if (rc) | 3088 | if (rc) |
@@ -3075,7 +3108,7 @@ void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3075 | ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; | 3108 | ctx->staging.flags &= ~RXON_FLG_SHORT_SLOT_MSK; |
3076 | } | 3109 | } |
3077 | 3110 | ||
3078 | iwlcore_commit_rxon(priv, ctx); | 3111 | iwl3945_commit_rxon(priv, ctx); |
3079 | 3112 | ||
3080 | switch (vif->type) { | 3113 | switch (vif->type) { |
3081 | case NL80211_IFTYPE_STATION: | 3114 | case NL80211_IFTYPE_STATION: |
@@ -3214,7 +3247,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3214 | 3247 | ||
3215 | /* RXON - unassoc (to set timing command) */ | 3248 | /* RXON - unassoc (to set timing command) */ |
3216 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 3249 | ctx->staging.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
3217 | iwlcore_commit_rxon(priv, ctx); | 3250 | iwl3945_commit_rxon(priv, ctx); |
3218 | 3251 | ||
3219 | /* RXON Timing */ | 3252 | /* RXON Timing */ |
3220 | rc = iwl_send_rxon_timing(priv, ctx); | 3253 | rc = iwl_send_rxon_timing(priv, ctx); |
@@ -3241,7 +3274,7 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3241 | } | 3274 | } |
3242 | /* restore RXON assoc */ | 3275 | /* restore RXON assoc */ |
3243 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; | 3276 | ctx->staging.filter_flags |= RXON_FILTER_ASSOC_MSK; |
3244 | iwlcore_commit_rxon(priv, ctx); | 3277 | iwl3945_commit_rxon(priv, ctx); |
3245 | } | 3278 | } |
3246 | iwl3945_send_beacon_cmd(priv); | 3279 | iwl3945_send_beacon_cmd(priv); |
3247 | 3280 | ||
@@ -3507,7 +3540,7 @@ static ssize_t store_flags(struct device *d, | |||
3507 | IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", | 3540 | IWL_DEBUG_INFO(priv, "Committing rxon.flags = 0x%04X\n", |
3508 | flags); | 3541 | flags); |
3509 | ctx->staging.flags = cpu_to_le32(flags); | 3542 | ctx->staging.flags = cpu_to_le32(flags); |
3510 | iwlcore_commit_rxon(priv, ctx); | 3543 | iwl3945_commit_rxon(priv, ctx); |
3511 | } | 3544 | } |
3512 | } | 3545 | } |
3513 | mutex_unlock(&priv->mutex); | 3546 | mutex_unlock(&priv->mutex); |
@@ -3545,7 +3578,7 @@ static ssize_t store_filter_flags(struct device *d, | |||
3545 | "0x%04X\n", filter_flags); | 3578 | "0x%04X\n", filter_flags); |
3546 | ctx->staging.filter_flags = | 3579 | ctx->staging.filter_flags = |
3547 | cpu_to_le32(filter_flags); | 3580 | cpu_to_le32(filter_flags); |
3548 | iwlcore_commit_rxon(priv, ctx); | 3581 | iwl3945_commit_rxon(priv, ctx); |
3549 | } | 3582 | } |
3550 | } | 3583 | } |
3551 | mutex_unlock(&priv->mutex); | 3584 | mutex_unlock(&priv->mutex); |
@@ -3815,7 +3848,7 @@ static int iwl3945_init_drv(struct iwl_priv *priv) | |||
3815 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; | 3848 | struct iwl3945_eeprom *eeprom = (struct iwl3945_eeprom *)priv->eeprom; |
3816 | 3849 | ||
3817 | priv->retry_rate = 1; | 3850 | priv->retry_rate = 1; |
3818 | priv->ibss_beacon = NULL; | 3851 | priv->beacon_skb = NULL; |
3819 | 3852 | ||
3820 | spin_lock_init(&priv->sta_lock); | 3853 | spin_lock_init(&priv->sta_lock); |
3821 | spin_lock_init(&priv->hcmd_lock); | 3854 | spin_lock_init(&priv->hcmd_lock); |
@@ -4179,7 +4212,7 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4179 | * paths to avoid running iwl_down() at all before leaving driver. | 4212 | * paths to avoid running iwl_down() at all before leaving driver. |
4180 | * This (inexpensive) call *makes sure* device is reset. | 4213 | * This (inexpensive) call *makes sure* device is reset. |
4181 | */ | 4214 | */ |
4182 | priv->cfg->ops->lib->apm_ops.stop(priv); | 4215 | iwl_apm_stop(priv); |
4183 | 4216 | ||
4184 | /* make sure we flush any pending irq or | 4217 | /* make sure we flush any pending irq or |
4185 | * tasklet for the driver | 4218 | * tasklet for the driver |
@@ -4223,8 +4256,8 @@ static void __devexit iwl3945_pci_remove(struct pci_dev *pdev) | |||
4223 | iwl_free_channel_map(priv); | 4256 | iwl_free_channel_map(priv); |
4224 | iwlcore_free_geos(priv); | 4257 | iwlcore_free_geos(priv); |
4225 | kfree(priv->scan_cmd); | 4258 | kfree(priv->scan_cmd); |
4226 | if (priv->ibss_beacon) | 4259 | if (priv->beacon_skb) |
4227 | dev_kfree_skb(priv->ibss_beacon); | 4260 | dev_kfree_skb(priv->beacon_skb); |
4228 | 4261 | ||
4229 | ieee80211_free_hw(priv->hw); | 4262 | ieee80211_free_hw(priv->hw); |
4230 | } | 4263 | } |