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.c97
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
331static int iwl3945_send_beacon_cmd(struct iwl_priv *priv) 331static 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
2664static 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
2664static int __iwl3945_up(struct iwl_priv *priv) 2686static 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
3007void 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
2986static void iwl3945_bg_restart(struct work_struct *data) 3019static 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}