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.c163
1 files changed, 93 insertions, 70 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index c7e1d7d09e02..935e64311d39 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -509,11 +509,11 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
509 509
510 hdr_len = ieee80211_hdrlen(fc); 510 hdr_len = ieee80211_hdrlen(fc);
511 511
512 /* Find (or create) index into station table for destination station */ 512 /* Find index into station table for destination station */
513 if (info->flags & IEEE80211_TX_CTL_INJECTED) 513 if (!info->control.sta)
514 sta_id = priv->hw_params.bcast_sta_id; 514 sta_id = priv->hw_params.bcast_sta_id;
515 else 515 else
516 sta_id = iwl_get_sta_id(priv, hdr); 516 sta_id = iwl_sta_id(info->control.sta);
517 if (sta_id == IWL_INVALID_STATION) { 517 if (sta_id == IWL_INVALID_STATION) {
518 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 518 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
519 hdr->addr1); 519 hdr->addr1);
@@ -1848,7 +1848,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1848static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, 1848static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1849 enum ieee80211_band band, 1849 enum ieee80211_band band,
1850 u8 is_active, u8 n_probes, 1850 u8 is_active, u8 n_probes,
1851 struct iwl3945_scan_channel *scan_ch) 1851 struct iwl3945_scan_channel *scan_ch,
1852 struct ieee80211_vif *vif)
1852{ 1853{
1853 struct ieee80211_channel *chan; 1854 struct ieee80211_channel *chan;
1854 const struct ieee80211_supported_band *sband; 1855 const struct ieee80211_supported_band *sband;
@@ -1862,7 +1863,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1862 return 0; 1863 return 0;
1863 1864
1864 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); 1865 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
1865 passive_dwell = iwl_get_passive_dwell_time(priv, band); 1866 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
1866 1867
1867 if (passive_dwell <= active_dwell) 1868 if (passive_dwell <= active_dwell)
1868 passive_dwell = active_dwell + 1; 1869 passive_dwell = active_dwell + 1;
@@ -2110,6 +2111,28 @@ static void iwl3945_nic_start(struct iwl_priv *priv)
2110 iwl_write32(priv, CSR_RESET, 0); 2111 iwl_write32(priv, CSR_RESET, 0);
2111} 2112}
2112 2113
2114#define IWL3945_UCODE_GET(item) \
2115static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode)\
2116{ \
2117 return le32_to_cpu(ucode->u.v1.item); \
2118}
2119
2120static u32 iwl3945_ucode_get_header_size(u32 api_ver)
2121{
2122 return 24;
2123}
2124
2125static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode)
2126{
2127 return (u8 *) ucode->u.v1.data;
2128}
2129
2130IWL3945_UCODE_GET(inst_size);
2131IWL3945_UCODE_GET(data_size);
2132IWL3945_UCODE_GET(init_size);
2133IWL3945_UCODE_GET(init_data_size);
2134IWL3945_UCODE_GET(boot_size);
2135
2113/** 2136/**
2114 * iwl3945_read_ucode - Read uCode images from disk file. 2137 * iwl3945_read_ucode - Read uCode images from disk file.
2115 * 2138 *
@@ -2158,7 +2181,7 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
2158 goto error; 2181 goto error;
2159 2182
2160 /* Make sure that we got at least our header! */ 2183 /* Make sure that we got at least our header! */
2161 if (ucode_raw->size < priv->cfg->ops->ucode->get_header_size(1)) { 2184 if (ucode_raw->size < iwl3945_ucode_get_header_size(1)) {
2162 IWL_ERR(priv, "File size way too small!\n"); 2185 IWL_ERR(priv, "File size way too small!\n");
2163 ret = -EINVAL; 2186 ret = -EINVAL;
2164 goto err_release; 2187 goto err_release;
@@ -2169,13 +2192,12 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
2169 2192
2170 priv->ucode_ver = le32_to_cpu(ucode->ver); 2193 priv->ucode_ver = le32_to_cpu(ucode->ver);
2171 api_ver = IWL_UCODE_API(priv->ucode_ver); 2194 api_ver = IWL_UCODE_API(priv->ucode_ver);
2172 inst_size = priv->cfg->ops->ucode->get_inst_size(ucode, api_ver); 2195 inst_size = iwl3945_ucode_get_inst_size(ucode);
2173 data_size = priv->cfg->ops->ucode->get_data_size(ucode, api_ver); 2196 data_size = iwl3945_ucode_get_data_size(ucode);
2174 init_size = priv->cfg->ops->ucode->get_init_size(ucode, api_ver); 2197 init_size = iwl3945_ucode_get_init_size(ucode);
2175 init_data_size = 2198 init_data_size = iwl3945_ucode_get_init_data_size(ucode);
2176 priv->cfg->ops->ucode->get_init_data_size(ucode, api_ver); 2199 boot_size = iwl3945_ucode_get_boot_size(ucode);
2177 boot_size = priv->cfg->ops->ucode->get_boot_size(ucode, api_ver); 2200 src = iwl3945_ucode_get_data(ucode);
2178 src = priv->cfg->ops->ucode->get_data(ucode, api_ver);
2179 2201
2180 /* api_ver should match the api version forming part of the 2202 /* api_ver should match the api version forming part of the
2181 * firmware filename ... but we don't check for that and only rely 2203 * firmware filename ... but we don't check for that and only rely
@@ -2224,7 +2246,7 @@ static int iwl3945_read_ucode(struct iwl_priv *priv)
2224 2246
2225 2247
2226 /* Verify size of file vs. image size info in file's header */ 2248 /* Verify size of file vs. image size info in file's header */
2227 if (ucode_raw->size != priv->cfg->ops->ucode->get_header_size(api_ver) + 2249 if (ucode_raw->size != iwl3945_ucode_get_header_size(api_ver) +
2228 inst_size + data_size + init_size + 2250 inst_size + data_size + init_size +
2229 init_data_size + boot_size) { 2251 init_data_size + boot_size) {
2230 2252
@@ -2523,7 +2545,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2523 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2545 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2524 } else { 2546 } else {
2525 /* Initialize our rx_config data */ 2547 /* Initialize our rx_config data */
2526 iwl_connection_init_rx_config(priv, priv->iw_mode); 2548 iwl_connection_init_rx_config(priv, NULL);
2527 } 2549 }
2528 2550
2529 /* Configure Bluetooth device coexistence support */ 2551 /* Configure Bluetooth device coexistence support */
@@ -2562,7 +2584,9 @@ static void __iwl3945_down(struct iwl_priv *priv)
2562 set_bit(STATUS_EXIT_PENDING, &priv->status); 2584 set_bit(STATUS_EXIT_PENDING, &priv->status);
2563 2585
2564 /* Station information will now be cleared in device */ 2586 /* Station information will now be cleared in device */
2565 iwl_clear_ucode_stations(priv, true); 2587 iwl_clear_ucode_stations(priv);
2588 iwl_dealloc_bcast_station(priv);
2589 iwl_clear_driver_stations(priv);
2566 2590
2567 /* Unblock any waiting calls */ 2591 /* Unblock any waiting calls */
2568 wake_up_interruptible_all(&priv->wait_command_queue); 2592 wake_up_interruptible_all(&priv->wait_command_queue);
@@ -2643,6 +2667,10 @@ static int __iwl3945_up(struct iwl_priv *priv)
2643{ 2667{
2644 int rc, i; 2668 int rc, i;
2645 2669
2670 rc = iwl_alloc_bcast_station(priv, false);
2671 if (rc)
2672 return rc;
2673
2646 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { 2674 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) {
2647 IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); 2675 IWL_WARN(priv, "Exit pending; will not bring the NIC up\n");
2648 return -EIO; 2676 return -EIO;
@@ -2791,7 +2819,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
2791 2819
2792} 2820}
2793 2821
2794void iwl3945_request_scan(struct iwl_priv *priv) 2822void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2795{ 2823{
2796 struct iwl_host_cmd cmd = { 2824 struct iwl_host_cmd cmd = {
2797 .id = REPLY_SCAN_CMD, 2825 .id = REPLY_SCAN_CMD,
@@ -2872,7 +2900,7 @@ void iwl3945_request_scan(struct iwl_priv *priv)
2872 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 2900 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
2873 2901
2874 spin_lock_irqsave(&priv->lock, flags); 2902 spin_lock_irqsave(&priv->lock, flags);
2875 interval = priv->beacon_int; 2903 interval = vif ? vif->bss_conf.beacon_int : 0;
2876 spin_unlock_irqrestore(&priv->lock, flags); 2904 spin_unlock_irqrestore(&priv->lock, flags);
2877 2905
2878 scan->suspend_time = 0; 2906 scan->suspend_time = 0;
@@ -2967,7 +2995,7 @@ void iwl3945_request_scan(struct iwl_priv *priv)
2967 2995
2968 scan->channel_count = 2996 scan->channel_count =
2969 iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, 2997 iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
2970 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); 2998 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif);
2971 2999
2972 if (scan->channel_count == 0) { 3000 if (scan->channel_count == 0) {
2973 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); 3001 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
@@ -3040,26 +3068,25 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
3040 mutex_unlock(&priv->mutex); 3068 mutex_unlock(&priv->mutex);
3041} 3069}
3042 3070
3043void iwl3945_post_associate(struct iwl_priv *priv) 3071void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3044{ 3072{
3045 int rc = 0; 3073 int rc = 0;
3046 struct ieee80211_conf *conf = NULL; 3074 struct ieee80211_conf *conf = NULL;
3047 3075
3048 if (priv->iw_mode == NL80211_IFTYPE_AP) { 3076 if (!vif || !priv->is_open)
3077 return;
3078
3079 if (vif->type == NL80211_IFTYPE_AP) {
3049 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 3080 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
3050 return; 3081 return;
3051 } 3082 }
3052 3083
3053
3054 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 3084 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3055 priv->assoc_id, priv->active_rxon.bssid_addr); 3085 vif->bss_conf.aid, priv->active_rxon.bssid_addr);
3056 3086
3057 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3087 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3058 return; 3088 return;
3059 3089
3060 if (!priv->vif || !priv->is_open)
3061 return;
3062
3063 iwl_scan_cancel_timeout(priv, 200); 3090 iwl_scan_cancel_timeout(priv, 200);
3064 3091
3065 conf = ieee80211_get_hw_conf(priv->hw); 3092 conf = ieee80211_get_hw_conf(priv->hw);
@@ -3068,7 +3095,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3068 iwlcore_commit_rxon(priv); 3095 iwlcore_commit_rxon(priv);
3069 3096
3070 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); 3097 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
3071 iwl_setup_rxon_timing(priv); 3098 iwl_setup_rxon_timing(priv, vif);
3072 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 3099 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
3073 sizeof(priv->rxon_timing), &priv->rxon_timing); 3100 sizeof(priv->rxon_timing), &priv->rxon_timing);
3074 if (rc) 3101 if (rc)
@@ -3077,51 +3104,38 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3077 3104
3078 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3105 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3079 3106
3080 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 3107 priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);
3081 3108
3082 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3109 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3083 priv->assoc_id, priv->beacon_int); 3110 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3084 3111
3085 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3112 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
3086 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3113 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3087 else 3114 else
3088 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3115 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3089 3116
3090 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3117 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3091 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 3118 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
3092 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3119 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
3093 else 3120 else
3094 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3121 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3095 3122
3096 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 3123 if (vif->type == NL80211_IFTYPE_ADHOC)
3097 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3124 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3098
3099 } 3125 }
3100 3126
3101 iwlcore_commit_rxon(priv); 3127 iwlcore_commit_rxon(priv);
3102 3128
3103 switch (priv->iw_mode) { 3129 switch (vif->type) {
3104 case NL80211_IFTYPE_STATION: 3130 case NL80211_IFTYPE_STATION:
3105 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); 3131 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
3106 break; 3132 break;
3107
3108 case NL80211_IFTYPE_ADHOC: 3133 case NL80211_IFTYPE_ADHOC:
3109
3110 priv->assoc_id = 1;
3111 iwl_add_local_station(priv, priv->bssid, false);
3112 iwl3945_sync_sta(priv, IWL_STA_ID,
3113 (priv->band == IEEE80211_BAND_5GHZ) ?
3114 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP,
3115 CMD_ASYNC);
3116 iwl3945_rate_scale_init(priv->hw, IWL_STA_ID);
3117
3118 iwl3945_send_beacon_cmd(priv); 3134 iwl3945_send_beacon_cmd(priv);
3119
3120 break; 3135 break;
3121
3122 default: 3136 default:
3123 IWL_ERR(priv, "%s Should not be called in %d mode\n", 3137 IWL_ERR(priv, "%s Should not be called in %d mode\n",
3124 __func__, priv->iw_mode); 3138 __func__, vif->type);
3125 break; 3139 break;
3126 } 3140 }
3127} 3141}
@@ -3245,7 +3259,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3245 return NETDEV_TX_OK; 3259 return NETDEV_TX_OK;
3246} 3260}
3247 3261
3248void iwl3945_config_ap(struct iwl_priv *priv) 3262void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3249{ 3263{
3250 int rc = 0; 3264 int rc = 0;
3251 3265
@@ -3261,7 +3275,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3261 3275
3262 /* RXON Timing */ 3276 /* RXON Timing */
3263 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); 3277 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
3264 iwl_setup_rxon_timing(priv); 3278 iwl_setup_rxon_timing(priv, vif);
3265 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 3279 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
3266 sizeof(priv->rxon_timing), 3280 sizeof(priv->rxon_timing),
3267 &priv->rxon_timing); 3281 &priv->rxon_timing);
@@ -3269,9 +3283,10 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3269 IWL_WARN(priv, "REPLY_RXON_TIMING failed - " 3283 IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
3270 "Attempting to continue.\n"); 3284 "Attempting to continue.\n");
3271 3285
3272 /* FIXME: what should be the assoc_id for AP? */ 3286 priv->staging_rxon.assoc_id = 0;
3273 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 3287
3274 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3288 if (vif->bss_conf.assoc_capability &
3289 WLAN_CAPABILITY_SHORT_PREAMBLE)
3275 priv->staging_rxon.flags |= 3290 priv->staging_rxon.flags |=
3276 RXON_FLG_SHORT_PREAMBLE_MSK; 3291 RXON_FLG_SHORT_PREAMBLE_MSK;
3277 else 3292 else
@@ -3279,22 +3294,21 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3279 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3294 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3280 3295
3281 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3296 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3282 if (priv->assoc_capability & 3297 if (vif->bss_conf.assoc_capability &
3283 WLAN_CAPABILITY_SHORT_SLOT_TIME) 3298 WLAN_CAPABILITY_SHORT_SLOT_TIME)
3284 priv->staging_rxon.flags |= 3299 priv->staging_rxon.flags |=
3285 RXON_FLG_SHORT_SLOT_MSK; 3300 RXON_FLG_SHORT_SLOT_MSK;
3286 else 3301 else
3287 priv->staging_rxon.flags &= 3302 priv->staging_rxon.flags &=
3288 ~RXON_FLG_SHORT_SLOT_MSK; 3303 ~RXON_FLG_SHORT_SLOT_MSK;
3289 3304
3290 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 3305 if (vif->type == NL80211_IFTYPE_ADHOC)
3291 priv->staging_rxon.flags &= 3306 priv->staging_rxon.flags &=
3292 ~RXON_FLG_SHORT_SLOT_MSK; 3307 ~RXON_FLG_SHORT_SLOT_MSK;
3293 } 3308 }
3294 /* restore RXON assoc */ 3309 /* restore RXON assoc */
3295 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3310 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3296 iwlcore_commit_rxon(priv); 3311 iwlcore_commit_rxon(priv);
3297 iwl_add_local_station(priv, iwl_bcast_addr, false);
3298 } 3312 }
3299 iwl3945_send_beacon_cmd(priv); 3313 iwl3945_send_beacon_cmd(priv);
3300 3314
@@ -3309,7 +3323,6 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3309 struct ieee80211_key_conf *key) 3323 struct ieee80211_key_conf *key)
3310{ 3324{
3311 struct iwl_priv *priv = hw->priv; 3325 struct iwl_priv *priv = hw->priv;
3312 const u8 *addr;
3313 int ret = 0; 3326 int ret = 0;
3314 u8 sta_id = IWL_INVALID_STATION; 3327 u8 sta_id = IWL_INVALID_STATION;
3315 u8 static_key; 3328 u8 static_key;
@@ -3321,15 +3334,19 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3321 return -EOPNOTSUPP; 3334 return -EOPNOTSUPP;
3322 } 3335 }
3323 3336
3324 addr = sta ? sta->addr : iwl_bcast_addr;
3325 static_key = !iwl_is_associated(priv); 3337 static_key = !iwl_is_associated(priv);
3326 3338
3327 if (!static_key) { 3339 if (!static_key) {
3328 sta_id = iwl_find_station(priv, addr); 3340 if (!sta) {
3329 if (sta_id == IWL_INVALID_STATION) { 3341 sta_id = priv->hw_params.bcast_sta_id;
3330 IWL_DEBUG_MAC80211(priv, "leave - %pM not in station map.\n", 3342 } else {
3331 addr); 3343 sta_id = iwl_sta_id(sta);
3332 return -EINVAL; 3344 if (sta_id == IWL_INVALID_STATION) {
3345 IWL_DEBUG_MAC80211(priv,
3346 "leave - %pM not in station map.\n",
3347 sta->addr);
3348 return -EINVAL;
3349 }
3333 } 3350 }
3334 } 3351 }
3335 3352
@@ -3366,10 +3383,13 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
3366 struct ieee80211_sta *sta) 3383 struct ieee80211_sta *sta)
3367{ 3384{
3368 struct iwl_priv *priv = hw->priv; 3385 struct iwl_priv *priv = hw->priv;
3386 struct iwl3945_sta_priv *sta_priv = (void *)sta->drv_priv;
3369 int ret; 3387 int ret;
3370 bool is_ap = priv->iw_mode == NL80211_IFTYPE_STATION; 3388 bool is_ap = vif->type == NL80211_IFTYPE_STATION;
3371 u8 sta_id; 3389 u8 sta_id;
3372 3390
3391 sta_priv->common.sta_id = IWL_INVALID_STATION;
3392
3373 IWL_DEBUG_INFO(priv, "received request to add station %pM\n", 3393 IWL_DEBUG_INFO(priv, "received request to add station %pM\n",
3374 sta->addr); 3394 sta->addr);
3375 3395
@@ -3382,16 +3402,14 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
3382 return ret; 3402 return ret;
3383 } 3403 }
3384 3404
3405 sta_priv->common.sta_id = sta_id;
3406
3385 /* Initialize rate scaling */ 3407 /* Initialize rate scaling */
3386 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n", 3408 IWL_DEBUG_INFO(priv, "Initializing rate scaling for station %pM\n",
3387 sta->addr); 3409 sta->addr);
3388 iwl3945_rs_rate_init(priv, sta, sta_id); 3410 iwl3945_rs_rate_init(priv, sta, sta_id);
3389 3411
3390 return 0; 3412 return 0;
3391
3392
3393
3394 return ret;
3395} 3413}
3396/***************************************************************************** 3414/*****************************************************************************
3397 * 3415 *
@@ -3740,6 +3758,7 @@ static void iwl3945_setup_deferred_work(struct iwl_priv *priv)
3740 INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll); 3758 INIT_DELAYED_WORK(&priv->_3945.rfkill_poll, iwl3945_rfkill_poll);
3741 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed); 3759 INIT_WORK(&priv->scan_completed, iwl_bg_scan_completed);
3742 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan); 3760 INIT_WORK(&priv->abort_scan, iwl_bg_abort_scan);
3761 INIT_WORK(&priv->start_internal_scan, iwl_bg_start_internal_scan);
3743 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check); 3762 INIT_DELAYED_WORK(&priv->scan_check, iwl_bg_scan_check);
3744 3763
3745 iwl3945_hw_setup_deferred_work(priv); 3764 iwl3945_hw_setup_deferred_work(priv);
@@ -3762,6 +3781,7 @@ static void iwl3945_cancel_deferred_work(struct iwl_priv *priv)
3762 cancel_delayed_work_sync(&priv->init_alive_start); 3781 cancel_delayed_work_sync(&priv->init_alive_start);
3763 cancel_delayed_work(&priv->scan_check); 3782 cancel_delayed_work(&priv->scan_check);
3764 cancel_delayed_work(&priv->alive_start); 3783 cancel_delayed_work(&priv->alive_start);
3784 cancel_work_sync(&priv->start_internal_scan);
3765 cancel_work_sync(&priv->beacon_update); 3785 cancel_work_sync(&priv->beacon_update);
3766 if (priv->cfg->ops->lib->recover_from_tx_stall) 3786 if (priv->cfg->ops->lib->recover_from_tx_stall)
3767 del_timer_sync(&priv->monitor_recover); 3787 del_timer_sync(&priv->monitor_recover);
@@ -3864,6 +3884,8 @@ err:
3864 return ret; 3884 return ret;
3865} 3885}
3866 3886
3887#define IWL3945_MAX_PROBE_REQUEST 200
3888
3867static int iwl3945_setup_mac(struct iwl_priv *priv) 3889static int iwl3945_setup_mac(struct iwl_priv *priv)
3868{ 3890{
3869 int ret; 3891 int ret;
@@ -3871,6 +3893,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3871 3893
3872 hw->rate_control_algorithm = "iwl-3945-rs"; 3894 hw->rate_control_algorithm = "iwl-3945-rs";
3873 hw->sta_data_size = sizeof(struct iwl3945_sta_priv); 3895 hw->sta_data_size = sizeof(struct iwl3945_sta_priv);
3896 hw->vif_data_size = sizeof(struct iwl_vif_priv);
3874 3897
3875 /* Tell mac80211 our characteristics */ 3898 /* Tell mac80211 our characteristics */
3876 hw->flags = IEEE80211_HW_SIGNAL_DBM | 3899 hw->flags = IEEE80211_HW_SIGNAL_DBM |
@@ -3889,7 +3912,7 @@ static int iwl3945_setup_mac(struct iwl_priv *priv)
3889 3912
3890 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945; 3913 hw->wiphy->max_scan_ssids = PROBE_OPTION_MAX_3945;
3891 /* we create the 802.11 header and a zero-length SSID element */ 3914 /* we create the 802.11 header and a zero-length SSID element */
3892 hw->wiphy->max_scan_ie_len = IWL_MAX_PROBE_REQUEST - 24 - 2; 3915 hw->wiphy->max_scan_ie_len = IWL3945_MAX_PROBE_REQUEST - 24 - 2;
3893 3916
3894 /* Default value; 4 EDCA QOS priorities */ 3917 /* Default value; 4 EDCA QOS priorities */
3895 hw->queues = 4; 3918 hw->queues = 4;