diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-1000.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-3945.c | 5 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-4965.c | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-5000.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-6000.c | 2 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn.c | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.c | 7 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-core.h | 1 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.c | 137 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-sta.h | 12 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 8 |
11 files changed, 89 insertions, 99 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c index a2f7cbcc2f7c..6be2992f8f21 100644 --- a/drivers/net/wireless/iwlwifi/iwl-1000.c +++ b/drivers/net/wireless/iwlwifi/iwl-1000.c | |||
@@ -212,7 +212,6 @@ static struct iwl_lib_ops iwl1000_lib = { | |||
212 | .temperature = iwlagn_temperature, | 212 | .temperature = iwlagn_temperature, |
213 | .set_ct_kill = iwl1000_set_ct_threshold, | 213 | .set_ct_kill = iwl1000_set_ct_threshold, |
214 | }, | 214 | }, |
215 | .add_bcast_station = iwl_add_bcast_station, | ||
216 | .manage_ibss_station = iwlagn_manage_ibss_station, | 215 | .manage_ibss_station = iwlagn_manage_ibss_station, |
217 | .debugfs_ops = { | 216 | .debugfs_ops = { |
218 | .rx_stats_read = iwl_ucode_rx_stats_read, | 217 | .rx_stats_read = iwl_ucode_rx_stats_read, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c index 05d808b28777..7fb159565f68 100644 --- a/drivers/net/wireless/iwlwifi/iwl-3945.c +++ b/drivers/net/wireless/iwlwifi/iwl-3945.c | |||
@@ -1992,7 +1992,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) | |||
1992 | "configuration (%d).\n", rc); | 1992 | "configuration (%d).\n", rc); |
1993 | return rc; | 1993 | return rc; |
1994 | } | 1994 | } |
1995 | iwl_clear_ucode_stations(priv, false); | 1995 | iwl_clear_ucode_stations(priv); |
1996 | iwl_restore_stations(priv); | 1996 | iwl_restore_stations(priv); |
1997 | } | 1997 | } |
1998 | 1998 | ||
@@ -2025,7 +2025,7 @@ static int iwl3945_commit_rxon(struct iwl_priv *priv) | |||
2025 | memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); | 2025 | memcpy(active_rxon, staging_rxon, sizeof(*active_rxon)); |
2026 | 2026 | ||
2027 | if (!new_assoc) { | 2027 | if (!new_assoc) { |
2028 | iwl_clear_ucode_stations(priv, false); | 2028 | iwl_clear_ucode_stations(priv); |
2029 | iwl_restore_stations(priv); | 2029 | iwl_restore_stations(priv); |
2030 | } | 2030 | } |
2031 | 2031 | ||
@@ -2853,7 +2853,6 @@ static struct iwl_lib_ops iwl3945_lib = { | |||
2853 | .isr = iwl_isr_legacy, | 2853 | .isr = iwl_isr_legacy, |
2854 | .config_ap = iwl3945_config_ap, | 2854 | .config_ap = iwl3945_config_ap, |
2855 | .manage_ibss_station = iwl3945_manage_ibss_station, | 2855 | .manage_ibss_station = iwl3945_manage_ibss_station, |
2856 | .add_bcast_station = iwl3945_add_bcast_station, | ||
2857 | .check_plcp_health = iwl3945_good_plcp_health, | 2856 | .check_plcp_health = iwl3945_good_plcp_health, |
2858 | 2857 | ||
2859 | .debugfs_ops = { | 2858 | .debugfs_ops = { |
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c index b8bf837af464..93893aec6cc4 100644 --- a/drivers/net/wireless/iwlwifi/iwl-4965.c +++ b/drivers/net/wireless/iwlwifi/iwl-4965.c | |||
@@ -2190,7 +2190,6 @@ static struct iwl_lib_ops iwl4965_lib = { | |||
2190 | .temperature = iwl4965_temperature_calib, | 2190 | .temperature = iwl4965_temperature_calib, |
2191 | .set_ct_kill = iwl4965_set_ct_threshold, | 2191 | .set_ct_kill = iwl4965_set_ct_threshold, |
2192 | }, | 2192 | }, |
2193 | .add_bcast_station = iwl_add_bcast_station, | ||
2194 | .manage_ibss_station = iwlagn_manage_ibss_station, | 2193 | .manage_ibss_station = iwlagn_manage_ibss_station, |
2195 | .debugfs_ops = { | 2194 | .debugfs_ops = { |
2196 | .rx_stats_read = iwl_ucode_rx_stats_read, | 2195 | .rx_stats_read = iwl_ucode_rx_stats_read, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c index efda0e8ccacb..a28af7eb67eb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-5000.c +++ b/drivers/net/wireless/iwlwifi/iwl-5000.c | |||
@@ -351,7 +351,6 @@ static struct iwl_lib_ops iwl5000_lib = { | |||
351 | .temperature = iwlagn_temperature, | 351 | .temperature = iwlagn_temperature, |
352 | .set_ct_kill = iwl5000_set_ct_threshold, | 352 | .set_ct_kill = iwl5000_set_ct_threshold, |
353 | }, | 353 | }, |
354 | .add_bcast_station = iwl_add_bcast_station, | ||
355 | .manage_ibss_station = iwlagn_manage_ibss_station, | 354 | .manage_ibss_station = iwlagn_manage_ibss_station, |
356 | .debugfs_ops = { | 355 | .debugfs_ops = { |
357 | .rx_stats_read = iwl_ucode_rx_stats_read, | 356 | .rx_stats_read = iwl_ucode_rx_stats_read, |
@@ -414,7 +413,6 @@ static struct iwl_lib_ops iwl5150_lib = { | |||
414 | .temperature = iwl5150_temperature, | 413 | .temperature = iwl5150_temperature, |
415 | .set_ct_kill = iwl5150_set_ct_threshold, | 414 | .set_ct_kill = iwl5150_set_ct_threshold, |
416 | }, | 415 | }, |
417 | .add_bcast_station = iwl_add_bcast_station, | ||
418 | .manage_ibss_station = iwlagn_manage_ibss_station, | 416 | .manage_ibss_station = iwlagn_manage_ibss_station, |
419 | .debugfs_ops = { | 417 | .debugfs_ops = { |
420 | .rx_stats_read = iwl_ucode_rx_stats_read, | 418 | .rx_stats_read = iwl_ucode_rx_stats_read, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c index 03c73244703c..9fbf54cd3e1a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-6000.c +++ b/drivers/net/wireless/iwlwifi/iwl-6000.c | |||
@@ -317,7 +317,6 @@ static struct iwl_lib_ops iwl6000_lib = { | |||
317 | .temperature = iwlagn_temperature, | 317 | .temperature = iwlagn_temperature, |
318 | .set_ct_kill = iwl6000_set_ct_threshold, | 318 | .set_ct_kill = iwl6000_set_ct_threshold, |
319 | }, | 319 | }, |
320 | .add_bcast_station = iwl_add_bcast_station, | ||
321 | .manage_ibss_station = iwlagn_manage_ibss_station, | 320 | .manage_ibss_station = iwlagn_manage_ibss_station, |
322 | .debugfs_ops = { | 321 | .debugfs_ops = { |
323 | .rx_stats_read = iwl_ucode_rx_stats_read, | 322 | .rx_stats_read = iwl_ucode_rx_stats_read, |
@@ -390,7 +389,6 @@ static struct iwl_lib_ops iwl6050_lib = { | |||
390 | .set_ct_kill = iwl6000_set_ct_threshold, | 389 | .set_ct_kill = iwl6000_set_ct_threshold, |
391 | .set_calib_version = iwl6050_set_calib_version, | 390 | .set_calib_version = iwl6050_set_calib_version, |
392 | }, | 391 | }, |
393 | .add_bcast_station = iwl_add_bcast_station, | ||
394 | .manage_ibss_station = iwlagn_manage_ibss_station, | 392 | .manage_ibss_station = iwlagn_manage_ibss_station, |
395 | .debugfs_ops = { | 393 | .debugfs_ops = { |
396 | .rx_stats_read = iwl_ucode_rx_stats_read, | 394 | .rx_stats_read = iwl_ucode_rx_stats_read, |
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c index 85e045baf5ae..0c913ea71f1e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn.c | |||
@@ -156,7 +156,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
156 | IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); | 156 | IWL_ERR(priv, "Error clearing ASSOC_MSK (%d)\n", ret); |
157 | return ret; | 157 | return ret; |
158 | } | 158 | } |
159 | iwl_clear_ucode_stations(priv, false); | 159 | iwl_clear_ucode_stations(priv); |
160 | iwl_restore_stations(priv); | 160 | iwl_restore_stations(priv); |
161 | ret = iwl_restore_default_wep_keys(priv); | 161 | ret = iwl_restore_default_wep_keys(priv); |
162 | if (ret) { | 162 | if (ret) { |
@@ -188,7 +188,7 @@ int iwl_commit_rxon(struct iwl_priv *priv) | |||
188 | } | 188 | } |
189 | IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); | 189 | IWL_DEBUG_INFO(priv, "Return from !new_assoc RXON.\n"); |
190 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); | 190 | memcpy(active_rxon, &priv->staging_rxon, sizeof(*active_rxon)); |
191 | iwl_clear_ucode_stations(priv, false); | 191 | iwl_clear_ucode_stations(priv); |
192 | iwl_restore_stations(priv); | 192 | iwl_restore_stations(priv); |
193 | ret = iwl_restore_default_wep_keys(priv); | 193 | ret = iwl_restore_default_wep_keys(priv); |
194 | if (ret) { | 194 | if (ret) { |
@@ -2403,7 +2403,8 @@ static void __iwl_down(struct iwl_priv *priv) | |||
2403 | if (!exit_pending) | 2403 | if (!exit_pending) |
2404 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2404 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
2405 | 2405 | ||
2406 | iwl_clear_ucode_stations(priv, true); | 2406 | iwl_clear_ucode_stations(priv); |
2407 | iwl_dealloc_bcast_station(priv); | ||
2407 | 2408 | ||
2408 | /* Unblock any waiting calls */ | 2409 | /* Unblock any waiting calls */ |
2409 | wake_up_interruptible_all(&priv->wait_command_queue); | 2410 | wake_up_interruptible_all(&priv->wait_command_queue); |
@@ -2550,6 +2551,10 @@ static int __iwl_up(struct iwl_priv *priv) | |||
2550 | return -EIO; | 2551 | return -EIO; |
2551 | } | 2552 | } |
2552 | 2553 | ||
2554 | ret = iwl_alloc_bcast_station(priv, true); | ||
2555 | if (ret) | ||
2556 | return ret; | ||
2557 | |||
2553 | iwl_prepare_card_hw(priv); | 2558 | iwl_prepare_card_hw(priv); |
2554 | 2559 | ||
2555 | if (!priv->hw_ready) { | 2560 | if (!priv->hw_ready) { |
@@ -3032,7 +3037,6 @@ void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3032 | /* restore RXON assoc */ | 3037 | /* restore RXON assoc */ |
3033 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 3038 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
3034 | iwlcore_commit_rxon(priv); | 3039 | iwlcore_commit_rxon(priv); |
3035 | iwl_add_bcast_station(priv); | ||
3036 | } | 3040 | } |
3037 | iwl_send_beacon_cmd(priv); | 3041 | iwl_send_beacon_cmd(priv); |
3038 | 3042 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c index d7a36205f0e1..f007b36ec54e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.c +++ b/drivers/net/wireless/iwlwifi/iwl-core.c | |||
@@ -2042,11 +2042,6 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) | |||
2042 | if (err) | 2042 | if (err) |
2043 | goto out_err; | 2043 | goto out_err; |
2044 | 2044 | ||
2045 | /* Add the broadcast address so we can send broadcast frames */ | ||
2046 | err = priv->cfg->ops->lib->add_bcast_station(priv); | ||
2047 | if (err) | ||
2048 | goto out_err; | ||
2049 | |||
2050 | goto out; | 2045 | goto out; |
2051 | 2046 | ||
2052 | out_err: | 2047 | out_err: |
@@ -2069,8 +2064,6 @@ void iwl_mac_remove_interface(struct ieee80211_hw *hw, | |||
2069 | 2064 | ||
2070 | mutex_lock(&priv->mutex); | 2065 | mutex_lock(&priv->mutex); |
2071 | 2066 | ||
2072 | iwl_clear_ucode_stations(priv, true); | ||
2073 | |||
2074 | if (iwl_is_ready_rf(priv)) { | 2067 | if (iwl_is_ready_rf(priv)) { |
2075 | iwl_scan_cancel_timeout(priv, 100); | 2068 | iwl_scan_cancel_timeout(priv, 100); |
2076 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; | 2069 | priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; |
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h index 1774ce9186eb..d80aa6c8d785 100644 --- a/drivers/net/wireless/iwlwifi/iwl-core.h +++ b/drivers/net/wireless/iwlwifi/iwl-core.h | |||
@@ -191,7 +191,6 @@ struct iwl_lib_ops { | |||
191 | /* temperature */ | 191 | /* temperature */ |
192 | struct iwl_temp_ops temp_ops; | 192 | struct iwl_temp_ops temp_ops; |
193 | /* station management */ | 193 | /* station management */ |
194 | int (*add_bcast_station)(struct iwl_priv *priv); | ||
195 | int (*manage_ibss_station)(struct iwl_priv *priv, | 194 | int (*manage_ibss_station)(struct iwl_priv *priv, |
196 | struct ieee80211_vif *vif, bool add); | 195 | struct ieee80211_vif *vif, bool add); |
197 | /* recover from tx queue stall */ | 196 | /* recover from tx queue stall */ |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 5bf82b9b523b..7e51647cf02d 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c | |||
@@ -656,63 +656,27 @@ out: | |||
656 | EXPORT_SYMBOL_GPL(iwl_remove_station); | 656 | EXPORT_SYMBOL_GPL(iwl_remove_station); |
657 | 657 | ||
658 | /** | 658 | /** |
659 | * iwl_clear_ucode_stations() - clear entire station table driver and/or ucode | 659 | * iwl_clear_ucode_stations - clear ucode station table bits |
660 | * @priv: | 660 | * |
661 | * @force: If set then the uCode station table needs to be cleared here. If | 661 | * This function clears all the bits in the driver indicating |
662 | * not set then the uCode station table has already been cleared, | 662 | * which stations are active in the ucode. Call when something |
663 | * for example after sending it a RXON command without ASSOC bit | 663 | * other than explicit station management would cause this in |
664 | * set, and we just need to change driver state here. | 664 | * the ucode, e.g. unassociated RXON. |
665 | */ | 665 | */ |
666 | void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force) | 666 | void iwl_clear_ucode_stations(struct iwl_priv *priv) |
667 | { | 667 | { |
668 | int i; | 668 | int i; |
669 | unsigned long flags_spin; | 669 | unsigned long flags_spin; |
670 | bool cleared = false; | 670 | bool cleared = false; |
671 | 671 | ||
672 | IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver%s\n", | 672 | IWL_DEBUG_INFO(priv, "Clearing ucode stations in driver\n"); |
673 | force ? " and ucode" : ""); | ||
674 | |||
675 | if (force) { | ||
676 | if (!iwl_is_ready(priv)) { | ||
677 | /* | ||
678 | * If device is not ready at this point the station | ||
679 | * table is likely already empty (uCode not ready | ||
680 | * to receive station requests) or will soon be | ||
681 | * due to interface going down. | ||
682 | */ | ||
683 | IWL_DEBUG_INFO(priv, "Unable to remove stations from device - device not ready\n"); | ||
684 | } else { | ||
685 | iwl_send_cmd_pdu_async(priv, REPLY_REMOVE_ALL_STA, 0, NULL, NULL); | ||
686 | } | ||
687 | } | ||
688 | 673 | ||
689 | spin_lock_irqsave(&priv->sta_lock, flags_spin); | 674 | spin_lock_irqsave(&priv->sta_lock, flags_spin); |
690 | if (force) { | 675 | for (i = 0; i < priv->hw_params.max_stations; i++) { |
691 | IWL_DEBUG_INFO(priv, "Clearing all station information in driver\n"); | 676 | if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) { |
692 | /* | 677 | IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i); |
693 | * The station entry contains a link to the LQ command. For | 678 | priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; |
694 | * all stations managed by mac80211 this memory will be | 679 | cleared = true; |
695 | * managed by it also. For local stations (broadcast and | ||
696 | * bssid station when in adhoc mode) we need to maintain | ||
697 | * this lq command separately. This memory is created when | ||
698 | * these stations are added. | ||
699 | */ | ||
700 | for (i = 0; i < priv->hw_params.max_stations; i++) { | ||
701 | if (priv->stations[i].used & IWL_STA_LOCAL) { | ||
702 | kfree(priv->stations[i].lq); | ||
703 | priv->stations[i].lq = NULL; | ||
704 | } | ||
705 | } | ||
706 | priv->num_stations = 0; | ||
707 | memset(priv->stations, 0, sizeof(priv->stations)); | ||
708 | cleared = true; | ||
709 | } else { | ||
710 | for (i = 0; i < priv->hw_params.max_stations; i++) { | ||
711 | if (priv->stations[i].used & IWL_STA_UCODE_ACTIVE) { | ||
712 | IWL_DEBUG_INFO(priv, "Clearing ucode active for station %d\n", i); | ||
713 | priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; | ||
714 | cleared = true; | ||
715 | } | ||
716 | } | 680 | } |
717 | } | 681 | } |
718 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); | 682 | spin_unlock_irqrestore(&priv->sta_lock, flags_spin); |
@@ -1251,34 +1215,67 @@ int iwl_send_lq_cmd(struct iwl_priv *priv, | |||
1251 | EXPORT_SYMBOL(iwl_send_lq_cmd); | 1215 | EXPORT_SYMBOL(iwl_send_lq_cmd); |
1252 | 1216 | ||
1253 | /** | 1217 | /** |
1254 | * iwl_add_bcast_station - add broadcast station into station table. | 1218 | * iwl_alloc_bcast_station - add broadcast station into driver's station table. |
1219 | * | ||
1220 | * This adds the broadcast station into the driver's station table | ||
1221 | * and marks it driver active, so that it will be restored to the | ||
1222 | * device at the next best time. | ||
1255 | */ | 1223 | */ |
1256 | int iwl_add_bcast_station(struct iwl_priv *priv) | 1224 | int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq) |
1257 | { | 1225 | { |
1258 | IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); | 1226 | struct iwl_link_quality_cmd *link_cmd; |
1259 | return iwl_add_local_station(priv, iwl_bcast_addr, true); | 1227 | unsigned long flags; |
1228 | u8 sta_id; | ||
1229 | |||
1230 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
1231 | sta_id = iwl_prep_station(priv, iwl_bcast_addr, false, NULL); | ||
1232 | if (sta_id == IWL_INVALID_STATION) { | ||
1233 | IWL_ERR(priv, "Unable to prepare broadcast station\n"); | ||
1234 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
1235 | |||
1236 | return -EINVAL; | ||
1237 | } | ||
1238 | |||
1239 | priv->stations[sta_id].used |= IWL_STA_DRIVER_ACTIVE; | ||
1240 | priv->stations[sta_id].used |= IWL_STA_BCAST; | ||
1241 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
1242 | |||
1243 | if (init_lq) { | ||
1244 | link_cmd = iwl_sta_alloc_lq(priv, sta_id); | ||
1245 | if (!link_cmd) { | ||
1246 | IWL_ERR(priv, | ||
1247 | "Unable to initialize rate scaling for bcast station.\n"); | ||
1248 | return -ENOMEM; | ||
1249 | } | ||
1250 | |||
1251 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
1252 | priv->stations[sta_id].lq = link_cmd; | ||
1253 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
1254 | } | ||
1255 | |||
1256 | return 0; | ||
1260 | } | 1257 | } |
1261 | EXPORT_SYMBOL(iwl_add_bcast_station); | 1258 | EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station); |
1262 | 1259 | ||
1263 | /** | 1260 | void iwl_dealloc_bcast_station(struct iwl_priv *priv) |
1264 | * iwl3945_add_bcast_station - add broadcast station into station table. | ||
1265 | */ | ||
1266 | int iwl3945_add_bcast_station(struct iwl_priv *priv) | ||
1267 | { | 1261 | { |
1268 | int ret; | 1262 | unsigned long flags; |
1269 | 1263 | int i; | |
1270 | IWL_DEBUG_INFO(priv, "Adding broadcast station to station table\n"); | ||
1271 | ret = iwl_add_local_station(priv, iwl_bcast_addr, false); | ||
1272 | /* | ||
1273 | * It is assumed that when station is added more initialization | ||
1274 | * needs to be done, but for 3945 it is not the case and we can | ||
1275 | * just release station table access right here. | ||
1276 | */ | ||
1277 | priv->stations[priv->hw_params.bcast_sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; | ||
1278 | return ret; | ||
1279 | 1264 | ||
1265 | spin_lock_irqsave(&priv->sta_lock, flags); | ||
1266 | for (i = 0; i < priv->hw_params.max_stations; i++) { | ||
1267 | if (!(priv->stations[i].used & IWL_STA_BCAST)) | ||
1268 | continue; | ||
1269 | |||
1270 | priv->stations[i].used &= ~IWL_STA_UCODE_ACTIVE; | ||
1271 | priv->num_stations--; | ||
1272 | BUG_ON(priv->num_stations < 0); | ||
1273 | kfree(priv->stations[i].lq); | ||
1274 | priv->stations[i].lq = NULL; | ||
1275 | } | ||
1276 | spin_unlock_irqrestore(&priv->sta_lock, flags); | ||
1280 | } | 1277 | } |
1281 | EXPORT_SYMBOL(iwl3945_add_bcast_station); | 1278 | EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station); |
1282 | 1279 | ||
1283 | /** | 1280 | /** |
1284 | * iwl_get_sta_id - Find station's index within station table | 1281 | * iwl_get_sta_id - Find station's index within station table |
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h index 1a0e590a824d..50c9d5138a4b 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.h +++ b/drivers/net/wireless/iwlwifi/iwl-sta.h | |||
@@ -36,9 +36,9 @@ | |||
36 | #define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */ | 36 | #define IWL_STA_UCODE_ACTIVE BIT(1) /* ucode entry is active */ |
37 | #define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of | 37 | #define IWL_STA_UCODE_INPROGRESS BIT(2) /* ucode entry is in process of |
38 | being activated */ | 38 | being activated */ |
39 | #define IWL_STA_LOCAL BIT(3) /* station state not directed by mac80211 | 39 | #define IWL_STA_LOCAL BIT(3) /* station state not directed by mac80211; |
40 | this is for bcast and bssid (when adhoc) | 40 | (this is for the IBSS BSSID stations) */ |
41 | stations */ | 41 | #define IWL_STA_BCAST BIT(4) /* this station is the special bcast station */ |
42 | 42 | ||
43 | 43 | ||
44 | /** | 44 | /** |
@@ -60,10 +60,10 @@ void iwl_update_tkip_key(struct iwl_priv *priv, | |||
60 | struct ieee80211_key_conf *keyconf, | 60 | struct ieee80211_key_conf *keyconf, |
61 | const u8 *addr, u32 iv32, u16 *phase1key); | 61 | const u8 *addr, u32 iv32, u16 *phase1key); |
62 | 62 | ||
63 | int iwl_add_bcast_station(struct iwl_priv *priv); | ||
64 | int iwl3945_add_bcast_station(struct iwl_priv *priv); | ||
65 | void iwl_restore_stations(struct iwl_priv *priv); | 63 | void iwl_restore_stations(struct iwl_priv *priv); |
66 | void iwl_clear_ucode_stations(struct iwl_priv *priv, bool force); | 64 | void iwl_clear_ucode_stations(struct iwl_priv *priv); |
65 | int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq); | ||
66 | void iwl_dealloc_bcast_station(struct iwl_priv *priv); | ||
67 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv); | 67 | int iwl_get_free_ucode_key_index(struct iwl_priv *priv); |
68 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); | 68 | int iwl_get_sta_id(struct iwl_priv *priv, struct ieee80211_hdr *hdr); |
69 | int iwl_send_add_sta(struct iwl_priv *priv, | 69 | int iwl_send_add_sta(struct iwl_priv *priv, |
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index 85a46ad667de..1a445711e34a 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c | |||
@@ -2583,7 +2583,8 @@ static void __iwl3945_down(struct iwl_priv *priv) | |||
2583 | set_bit(STATUS_EXIT_PENDING, &priv->status); | 2583 | set_bit(STATUS_EXIT_PENDING, &priv->status); |
2584 | 2584 | ||
2585 | /* Station information will now be cleared in device */ | 2585 | /* Station information will now be cleared in device */ |
2586 | iwl_clear_ucode_stations(priv, true); | 2586 | iwl_clear_ucode_stations(priv); |
2587 | iwl_dealloc_bcast_station(priv); | ||
2587 | 2588 | ||
2588 | /* Unblock any waiting calls */ | 2589 | /* Unblock any waiting calls */ |
2589 | wake_up_interruptible_all(&priv->wait_command_queue); | 2590 | wake_up_interruptible_all(&priv->wait_command_queue); |
@@ -2664,6 +2665,10 @@ static int __iwl3945_up(struct iwl_priv *priv) | |||
2664 | { | 2665 | { |
2665 | int rc, i; | 2666 | int rc, i; |
2666 | 2667 | ||
2668 | rc = iwl_alloc_bcast_station(priv, false); | ||
2669 | if (rc) | ||
2670 | return rc; | ||
2671 | |||
2667 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { | 2672 | if (test_bit(STATUS_EXIT_PENDING, &priv->status)) { |
2668 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); | 2673 | IWL_WARN(priv, "Exit pending; will not bring the NIC up\n"); |
2669 | return -EIO; | 2674 | return -EIO; |
@@ -3302,7 +3307,6 @@ void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif) | |||
3302 | /* restore RXON assoc */ | 3307 | /* restore RXON assoc */ |
3303 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; | 3308 | priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; |
3304 | iwlcore_commit_rxon(priv); | 3309 | iwlcore_commit_rxon(priv); |
3305 | iwl3945_add_bcast_station(priv); | ||
3306 | } | 3310 | } |
3307 | iwl3945_send_beacon_cmd(priv); | 3311 | iwl3945_send_beacon_cmd(priv); |
3308 | 3312 | ||