diff options
author | John W. Linville <linville@tuxdriver.com> | 2010-05-17 13:57:43 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2010-05-17 13:57:43 -0400 |
commit | 6fe70aae0d128339febfabc073ba4c4a03de4f45 (patch) | |
tree | 711dff90df5ca4e07b5bddf11b2819e5cf2b7a93 /drivers/net/wireless/iwlwifi/iwl3945-base.c | |
parent | 278554bd6579206921f5d8a523649a7a57f8850d (diff) | |
parent | 0c348d7c1422d59a86d6fb37b53d75788043e50b (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next-2.6 into for-davem
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl3945-base.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 163 |
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) | |||
1848 | static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, | 1848 | static 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) \ | ||
2115 | static u32 iwl3945_ucode_get_##item(const struct iwl_ucode_header *ucode)\ | ||
2116 | { \ | ||
2117 | return le32_to_cpu(ucode->u.v1.item); \ | ||
2118 | } | ||
2119 | |||
2120 | static u32 iwl3945_ucode_get_header_size(u32 api_ver) | ||
2121 | { | ||
2122 | return 24; | ||
2123 | } | ||
2124 | |||
2125 | static u8 *iwl3945_ucode_get_data(const struct iwl_ucode_header *ucode) | ||
2126 | { | ||
2127 | return (u8 *) ucode->u.v1.data; | ||
2128 | } | ||
2129 | |||
2130 | IWL3945_UCODE_GET(inst_size); | ||
2131 | IWL3945_UCODE_GET(data_size); | ||
2132 | IWL3945_UCODE_GET(init_size); | ||
2133 | IWL3945_UCODE_GET(init_data_size); | ||
2134 | IWL3945_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 | ||
2794 | void iwl3945_request_scan(struct iwl_priv *priv) | 2822 | void 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 | ||
3043 | void iwl3945_post_associate(struct iwl_priv *priv) | 3071 | void 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 | ||
3248 | void iwl3945_config_ap(struct iwl_priv *priv) | 3262 | void 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 | |||
3867 | static int iwl3945_setup_mac(struct iwl_priv *priv) | 3889 | static 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; |