aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-04-29 07:43:06 -0400
committerReinette Chatre <reinette.chatre@intel.com>2010-05-10 18:08:58 -0400
commit1dda6d28377bec52f96767e8d4a59aa95102b9dd (patch)
tree583e26326f5d7d59c34c4f584b29b674c24f0e29 /drivers/net/wireless
parent3474ad635db371b0d8d0ee40086f15d223d5b6a4 (diff)
iwlwifi: push virtual interface through
Rather than keeping every bit of information around in priv and the virtual interface, add a virtual interface to many functions and use the information directly from it. This removes beacon_int, assoc_capability and assoc_id from struct iwl_priv. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c52
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c54
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-scan.c13
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c63
9 files changed, 118 insertions, 122 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.h b/drivers/net/wireless/iwlwifi/iwl-3945.h
index cea824c15bc5..8fe24eee1c56 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.h
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.h
@@ -261,8 +261,10 @@ void iwl3945_reply_statistics(struct iwl_priv *priv,
261 struct iwl_rx_mem_buffer *rxb); 261 struct iwl_rx_mem_buffer *rxb);
262extern void iwl3945_disable_events(struct iwl_priv *priv); 262extern void iwl3945_disable_events(struct iwl_priv *priv);
263extern int iwl4965_get_temperature(const struct iwl_priv *priv); 263extern int iwl4965_get_temperature(const struct iwl_priv *priv);
264extern void iwl3945_post_associate(struct iwl_priv *priv); 264extern void iwl3945_post_associate(struct iwl_priv *priv,
265extern void iwl3945_config_ap(struct iwl_priv *priv); 265 struct ieee80211_vif *vif);
266extern void iwl3945_config_ap(struct iwl_priv *priv,
267 struct ieee80211_vif *vif);
266 268
267/** 269/**
268 * iwl3945_hw_find_station - Find station id for a given BSSID 270 * iwl3945_hw_find_station - Find station id for a given BSSID
@@ -288,7 +290,7 @@ extern const struct iwl_channel_info *iwl3945_get_channel_info(
288extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate); 290extern int iwl3945_rs_next_rate(struct iwl_priv *priv, int rate);
289 291
290/* scanning */ 292/* scanning */
291void iwl3945_request_scan(struct iwl_priv *priv); 293void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
292 294
293/* Requires full declaration of iwl_priv before including */ 295/* Requires full declaration of iwl_priv before including */
294#include "iwl-io.h" 296#include "iwl-io.h"
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 50ff313c549c..f05e6002a04e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1114,8 +1114,9 @@ void iwlagn_rx_reply_rx_phy(struct iwl_priv *priv,
1114} 1114}
1115 1115
1116static int iwl_get_single_channel_for_scan(struct iwl_priv *priv, 1116static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
1117 enum ieee80211_band band, 1117 struct ieee80211_vif *vif,
1118 struct iwl_scan_channel *scan_ch) 1118 enum ieee80211_band band,
1119 struct iwl_scan_channel *scan_ch)
1119{ 1120{
1120 const struct ieee80211_supported_band *sband; 1121 const struct ieee80211_supported_band *sband;
1121 const struct iwl_channel_info *ch_info; 1122 const struct iwl_channel_info *ch_info;
@@ -1131,7 +1132,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
1131 } 1132 }
1132 1133
1133 active_dwell = iwl_get_active_dwell_time(priv, band, 0); 1134 active_dwell = iwl_get_active_dwell_time(priv, band, 0);
1134 passive_dwell = iwl_get_passive_dwell_time(priv, band); 1135 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
1135 1136
1136 if (passive_dwell <= active_dwell) 1137 if (passive_dwell <= active_dwell)
1137 passive_dwell = active_dwell + 1; 1138 passive_dwell = active_dwell + 1;
@@ -1180,6 +1181,7 @@ static int iwl_get_single_channel_for_scan(struct iwl_priv *priv,
1180} 1181}
1181 1182
1182static int iwl_get_channels_for_scan(struct iwl_priv *priv, 1183static int iwl_get_channels_for_scan(struct iwl_priv *priv,
1184 struct ieee80211_vif *vif,
1183 enum ieee80211_band band, 1185 enum ieee80211_band band,
1184 u8 is_active, u8 n_probes, 1186 u8 is_active, u8 n_probes,
1185 struct iwl_scan_channel *scan_ch) 1187 struct iwl_scan_channel *scan_ch)
@@ -1197,7 +1199,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
1197 return 0; 1199 return 0;
1198 1200
1199 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); 1201 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
1200 passive_dwell = iwl_get_passive_dwell_time(priv, band); 1202 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
1201 1203
1202 if (passive_dwell <= active_dwell) 1204 if (passive_dwell <= active_dwell)
1203 passive_dwell = active_dwell + 1; 1205 passive_dwell = active_dwell + 1;
@@ -1257,7 +1259,7 @@ static int iwl_get_channels_for_scan(struct iwl_priv *priv,
1257 return added; 1259 return added;
1258} 1260}
1259 1261
1260void iwlagn_request_scan(struct iwl_priv *priv) 1262void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1261{ 1263{
1262 struct iwl_host_cmd cmd = { 1264 struct iwl_host_cmd cmd = {
1263 .id = REPLY_SCAN_CMD, 1265 .id = REPLY_SCAN_CMD,
@@ -1343,7 +1345,7 @@ void iwlagn_request_scan(struct iwl_priv *priv)
1343 1345
1344 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 1346 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
1345 spin_lock_irqsave(&priv->lock, flags); 1347 spin_lock_irqsave(&priv->lock, flags);
1346 interval = priv->beacon_int; 1348 interval = vif ? vif->bss_conf.beacon_int : 0;
1347 spin_unlock_irqrestore(&priv->lock, flags); 1349 spin_unlock_irqrestore(&priv->lock, flags);
1348 1350
1349 scan->suspend_time = 0; 1351 scan->suspend_time = 0;
@@ -1474,12 +1476,12 @@ void iwlagn_request_scan(struct iwl_priv *priv)
1474 1476
1475 if (priv->is_internal_short_scan) { 1477 if (priv->is_internal_short_scan) {
1476 scan->channel_count = 1478 scan->channel_count =
1477 iwl_get_single_channel_for_scan(priv, band, 1479 iwl_get_single_channel_for_scan(priv, vif, band,
1478 (void *)&scan->data[le16_to_cpu( 1480 (void *)&scan->data[le16_to_cpu(
1479 scan->tx_cmd.len)]); 1481 scan->tx_cmd.len)]);
1480 } else { 1482 } else {
1481 scan->channel_count = 1483 scan->channel_count =
1482 iwl_get_channels_for_scan(priv, band, 1484 iwl_get_channels_for_scan(priv, vif, band,
1483 is_active, n_probes, 1485 is_active, n_probes,
1484 (void *)&scan->data[le16_to_cpu( 1486 (void *)&scan->data[le16_to_cpu(
1485 scan->tx_cmd.len)]); 1487 scan->tx_cmd.len)]);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 7c3363ab561a..270635edb63c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2356,7 +2356,7 @@ static void iwl_alive_start(struct iwl_priv *priv)
2356 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2356 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2357 } else { 2357 } else {
2358 /* Initialize our rx_config data */ 2358 /* Initialize our rx_config data */
2359 iwl_connection_init_rx_config(priv, priv->iw_mode); 2359 iwl_connection_init_rx_config(priv, NULL);
2360 2360
2361 if (priv->cfg->ops->hcmd->set_rxon_chain) 2361 if (priv->cfg->ops->hcmd->set_rxon_chain)
2362 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2362 priv->cfg->ops->hcmd->set_rxon_chain(priv);
@@ -2729,12 +2729,15 @@ static void iwl_bg_rx_replenish(struct work_struct *data)
2729 2729
2730#define IWL_DELAY_NEXT_SCAN (HZ*2) 2730#define IWL_DELAY_NEXT_SCAN (HZ*2)
2731 2731
2732void iwl_post_associate(struct iwl_priv *priv) 2732void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
2733{ 2733{
2734 struct ieee80211_conf *conf = NULL; 2734 struct ieee80211_conf *conf = NULL;
2735 int ret = 0; 2735 int ret = 0;
2736 2736
2737 if (priv->iw_mode == NL80211_IFTYPE_AP) { 2737 if (!vif || !priv->is_open)
2738 return;
2739
2740 if (vif->type == NL80211_IFTYPE_AP) {
2738 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 2741 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
2739 return; 2742 return;
2740 } 2743 }
@@ -2742,10 +2745,6 @@ void iwl_post_associate(struct iwl_priv *priv)
2742 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 2745 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
2743 return; 2746 return;
2744 2747
2745
2746 if (!priv->vif || !priv->is_open)
2747 return;
2748
2749 iwl_scan_cancel_timeout(priv, 200); 2748 iwl_scan_cancel_timeout(priv, 200);
2750 2749
2751 conf = ieee80211_get_hw_conf(priv->hw); 2750 conf = ieee80211_get_hw_conf(priv->hw);
@@ -2753,7 +2752,7 @@ void iwl_post_associate(struct iwl_priv *priv)
2753 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2752 priv->staging_rxon.filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2754 iwlcore_commit_rxon(priv); 2753 iwlcore_commit_rxon(priv);
2755 2754
2756 iwl_setup_rxon_timing(priv); 2755 iwl_setup_rxon_timing(priv, vif);
2757 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 2756 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
2758 sizeof(priv->rxon_timing), &priv->rxon_timing); 2757 sizeof(priv->rxon_timing), &priv->rxon_timing);
2759 if (ret) 2758 if (ret)
@@ -2767,43 +2766,41 @@ void iwl_post_associate(struct iwl_priv *priv)
2767 if (priv->cfg->ops->hcmd->set_rxon_chain) 2766 if (priv->cfg->ops->hcmd->set_rxon_chain)
2768 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2767 priv->cfg->ops->hcmd->set_rxon_chain(priv);
2769 2768
2770 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 2769 priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);
2771 2770
2772 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 2771 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
2773 priv->assoc_id, priv->beacon_int); 2772 vif->bss_conf.aid, vif->bss_conf.beacon_int);
2774 2773
2775 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 2774 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2776 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 2775 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
2777 else 2776 else
2778 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 2777 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
2779 2778
2780 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 2779 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
2781 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 2780 if (vif->bss_conf.assoc_capability &
2781 WLAN_CAPABILITY_SHORT_SLOT_TIME)
2782 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 2782 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
2783 else 2783 else
2784 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 2784 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2785 2785
2786 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 2786 if (vif->type == NL80211_IFTYPE_ADHOC)
2787 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 2787 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
2788
2789 } 2788 }
2790 2789
2791 iwlcore_commit_rxon(priv); 2790 iwlcore_commit_rxon(priv);
2792 2791
2793 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 2792 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
2794 priv->assoc_id, priv->active_rxon.bssid_addr); 2793 vif->bss_conf.aid, priv->active_rxon.bssid_addr);
2795 2794
2796 switch (priv->iw_mode) { 2795 switch (vif->type) {
2797 case NL80211_IFTYPE_STATION: 2796 case NL80211_IFTYPE_STATION:
2798 break; 2797 break;
2799 case NL80211_IFTYPE_ADHOC: 2798 case NL80211_IFTYPE_ADHOC:
2800 /* assume default assoc id */
2801 priv->assoc_id = 1;
2802 iwl_send_beacon_cmd(priv); 2799 iwl_send_beacon_cmd(priv);
2803 break; 2800 break;
2804 default: 2801 default:
2805 IWL_ERR(priv, "%s Should not be called in %d mode\n", 2802 IWL_ERR(priv, "%s Should not be called in %d mode\n",
2806 __func__, priv->iw_mode); 2803 __func__, vif->type);
2807 break; 2804 break;
2808 } 2805 }
2809 2806
@@ -2980,7 +2977,7 @@ static int iwl_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
2980 return NETDEV_TX_OK; 2977 return NETDEV_TX_OK;
2981} 2978}
2982 2979
2983void iwl_config_ap(struct iwl_priv *priv) 2980void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
2984{ 2981{
2985 int ret = 0; 2982 int ret = 0;
2986 2983
@@ -2995,7 +2992,7 @@ void iwl_config_ap(struct iwl_priv *priv)
2995 iwlcore_commit_rxon(priv); 2992 iwlcore_commit_rxon(priv);
2996 2993
2997 /* RXON Timing */ 2994 /* RXON Timing */
2998 iwl_setup_rxon_timing(priv); 2995 iwl_setup_rxon_timing(priv, vif);
2999 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 2996 ret = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
3000 sizeof(priv->rxon_timing), &priv->rxon_timing); 2997 sizeof(priv->rxon_timing), &priv->rxon_timing);
3001 if (ret) 2998 if (ret)
@@ -3009,9 +3006,10 @@ void iwl_config_ap(struct iwl_priv *priv)
3009 if (priv->cfg->ops->hcmd->set_rxon_chain) 3006 if (priv->cfg->ops->hcmd->set_rxon_chain)
3010 priv->cfg->ops->hcmd->set_rxon_chain(priv); 3007 priv->cfg->ops->hcmd->set_rxon_chain(priv);
3011 3008
3012 /* FIXME: what should be the assoc_id for AP? */ 3009 priv->staging_rxon.assoc_id = 0;
3013 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 3010
3014 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3011 if (vif->bss_conf.assoc_capability &
3012 WLAN_CAPABILITY_SHORT_PREAMBLE)
3015 priv->staging_rxon.flags |= 3013 priv->staging_rxon.flags |=
3016 RXON_FLG_SHORT_PREAMBLE_MSK; 3014 RXON_FLG_SHORT_PREAMBLE_MSK;
3017 else 3015 else
@@ -3019,15 +3017,15 @@ void iwl_config_ap(struct iwl_priv *priv)
3019 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3017 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3020 3018
3021 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3019 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3022 if (priv->assoc_capability & 3020 if (vif->bss_conf.assoc_capability &
3023 WLAN_CAPABILITY_SHORT_SLOT_TIME) 3021 WLAN_CAPABILITY_SHORT_SLOT_TIME)
3024 priv->staging_rxon.flags |= 3022 priv->staging_rxon.flags |=
3025 RXON_FLG_SHORT_SLOT_MSK; 3023 RXON_FLG_SHORT_SLOT_MSK;
3026 else 3024 else
3027 priv->staging_rxon.flags &= 3025 priv->staging_rxon.flags &=
3028 ~RXON_FLG_SHORT_SLOT_MSK; 3026 ~RXON_FLG_SHORT_SLOT_MSK;
3029 3027
3030 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 3028 if (vif->type == NL80211_IFTYPE_ADHOC)
3031 priv->staging_rxon.flags &= 3029 priv->staging_rxon.flags &=
3032 ~RXON_FLG_SHORT_SLOT_MSK; 3030 ~RXON_FLG_SHORT_SLOT_MSK;
3033 } 3031 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.h b/drivers/net/wireless/iwlwifi/iwl-agn.h
index 4a1e7b2b7a8e..f52bedb8c8b3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.h
@@ -171,7 +171,7 @@ static inline bool iwl_is_tx_success(u32 status)
171} 171}
172 172
173/* scan */ 173/* scan */
174void iwlagn_request_scan(struct iwl_priv *priv); 174void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif);
175 175
176/* station mgmt */ 176/* station mgmt */
177int iwlagn_manage_ibss_station(struct iwl_priv *priv, 177int iwlagn_manage_ibss_station(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index 246538a27fc6..68c3693a296e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -480,7 +480,7 @@ static u16 iwl_adjust_beacon_interval(u16 beacon_val, u16 max_beacon_val)
480 return new_val; 480 return new_val;
481} 481}
482 482
483void iwl_setup_rxon_timing(struct iwl_priv *priv) 483void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif)
484{ 484{
485 u64 tsf; 485 u64 tsf;
486 s32 interval_tm, rem; 486 s32 interval_tm, rem;
@@ -494,15 +494,14 @@ void iwl_setup_rxon_timing(struct iwl_priv *priv)
494 priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp); 494 priv->rxon_timing.timestamp = cpu_to_le64(priv->timestamp);
495 priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval); 495 priv->rxon_timing.listen_interval = cpu_to_le16(conf->listen_interval);
496 496
497 if (priv->iw_mode == NL80211_IFTYPE_STATION) { 497 beacon_int = vif->bss_conf.beacon_int;
498 beacon_int = priv->beacon_int;
499 priv->rxon_timing.atim_window = 0;
500 } else {
501 beacon_int = priv->vif->bss_conf.beacon_int;
502 498
499 if (vif->type == NL80211_IFTYPE_ADHOC) {
503 /* TODO: we need to get atim_window from upper stack 500 /* TODO: we need to get atim_window from upper stack
504 * for now we set to 0 */ 501 * for now we set to 0 */
505 priv->rxon_timing.atim_window = 0; 502 priv->rxon_timing.atim_window = 0;
503 } else {
504 priv->rxon_timing.atim_window = 0;
506 } 505 }
507 506
508 beacon_int = iwl_adjust_beacon_interval(beacon_int, 507 beacon_int = iwl_adjust_beacon_interval(beacon_int,
@@ -894,8 +893,9 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch)
894} 893}
895EXPORT_SYMBOL(iwl_set_rxon_channel); 894EXPORT_SYMBOL(iwl_set_rxon_channel);
896 895
897void iwl_set_flags_for_band(struct iwl_priv *priv, 896static void iwl_set_flags_for_band(struct iwl_priv *priv,
898 enum ieee80211_band band) 897 enum ieee80211_band band,
898 struct ieee80211_vif *vif)
899{ 899{
900 if (band == IEEE80211_BAND_5GHZ) { 900 if (band == IEEE80211_BAND_5GHZ) {
901 priv->staging_rxon.flags &= 901 priv->staging_rxon.flags &=
@@ -904,12 +904,12 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
904 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 904 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
905 } else { 905 } else {
906 /* Copied from iwl_post_associate() */ 906 /* Copied from iwl_post_associate() */
907 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 907 if (vif && vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
908 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 908 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
909 else 909 else
910 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 910 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
911 911
912 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 912 if (vif && vif->type == NL80211_IFTYPE_ADHOC)
913 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 913 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
914 914
915 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK; 915 priv->staging_rxon.flags |= RXON_FLG_BAND_24G_MSK;
@@ -921,13 +921,18 @@ void iwl_set_flags_for_band(struct iwl_priv *priv,
921/* 921/*
922 * initialize rxon structure with default values from eeprom 922 * initialize rxon structure with default values from eeprom
923 */ 923 */
924void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode) 924void iwl_connection_init_rx_config(struct iwl_priv *priv,
925 struct ieee80211_vif *vif)
925{ 926{
926 const struct iwl_channel_info *ch_info; 927 const struct iwl_channel_info *ch_info;
928 enum nl80211_iftype type = NL80211_IFTYPE_STATION;
929
930 if (vif)
931 type = vif->type;
927 932
928 memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon)); 933 memset(&priv->staging_rxon, 0, sizeof(priv->staging_rxon));
929 934
930 switch (mode) { 935 switch (type) {
931 case NL80211_IFTYPE_AP: 936 case NL80211_IFTYPE_AP:
932 priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP; 937 priv->staging_rxon.dev_type = RXON_DEV_TYPE_AP;
933 break; 938 break;
@@ -945,7 +950,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
945 break; 950 break;
946 951
947 default: 952 default:
948 IWL_ERR(priv, "Unsupported interface type %d\n", mode); 953 IWL_ERR(priv, "Unsupported interface type %d\n", type);
949 break; 954 break;
950 } 955 }
951 956
@@ -967,7 +972,7 @@ void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode)
967 priv->staging_rxon.channel = cpu_to_le16(ch_info->channel); 972 priv->staging_rxon.channel = cpu_to_le16(ch_info->channel);
968 priv->band = ch_info->band; 973 priv->band = ch_info->band;
969 974
970 iwl_set_flags_for_band(priv, priv->band); 975 iwl_set_flags_for_band(priv, priv->band, vif);
971 976
972 priv->staging_rxon.ofdm_basic_rates = 977 priv->staging_rxon.ofdm_basic_rates =
973 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF; 978 (IWL_OFDM_RATES_MASK >> IWL_FIRST_OFDM_RATE) & 0xFF;
@@ -1793,7 +1798,6 @@ static void iwl_ht_conf(struct iwl_priv *priv,
1793 1798
1794static inline void iwl_set_no_assoc(struct iwl_priv *priv) 1799static inline void iwl_set_no_assoc(struct iwl_priv *priv)
1795{ 1800{
1796 priv->assoc_id = 0;
1797 iwl_led_disassociate(priv); 1801 iwl_led_disassociate(priv);
1798 /* 1802 /*
1799 * inform the ucode that there is no longer an 1803 * inform the ucode that there is no longer an
@@ -1827,7 +1831,6 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1827 } 1831 }
1828 1832
1829 if (changes & BSS_CHANGED_BEACON_INT) { 1833 if (changes & BSS_CHANGED_BEACON_INT) {
1830 priv->beacon_int = bss_conf->beacon_int;
1831 /* TODO: in AP mode, do something to make this take effect */ 1834 /* TODO: in AP mode, do something to make this take effect */
1832 } 1835 }
1833 1836
@@ -1917,20 +1920,17 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1917 if (changes & BSS_CHANGED_ASSOC) { 1920 if (changes & BSS_CHANGED_ASSOC) {
1918 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc); 1921 IWL_DEBUG_MAC80211(priv, "ASSOC %d\n", bss_conf->assoc);
1919 if (bss_conf->assoc) { 1922 if (bss_conf->assoc) {
1920 priv->assoc_id = bss_conf->aid;
1921 priv->beacon_int = bss_conf->beacon_int;
1922 priv->timestamp = bss_conf->timestamp; 1923 priv->timestamp = bss_conf->timestamp;
1923 priv->assoc_capability = bss_conf->assoc_capability;
1924 1924
1925 iwl_led_associate(priv); 1925 iwl_led_associate(priv);
1926 1926
1927 if (!iwl_is_rfkill(priv)) 1927 if (!iwl_is_rfkill(priv))
1928 priv->cfg->ops->lib->post_associate(priv); 1928 priv->cfg->ops->lib->post_associate(priv, vif);
1929 } else 1929 } else
1930 iwl_set_no_assoc(priv); 1930 iwl_set_no_assoc(priv);
1931 } 1931 }
1932 1932
1933 if (changes && iwl_is_associated(priv) && priv->assoc_id) { 1933 if (changes && iwl_is_associated(priv) && bss_conf->aid) {
1934 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n", 1934 IWL_DEBUG_MAC80211(priv, "Changes (%#x) while associated\n",
1935 changes); 1935 changes);
1936 ret = iwl_send_rxon_assoc(priv); 1936 ret = iwl_send_rxon_assoc(priv);
@@ -1947,7 +1947,7 @@ void iwl_bss_info_changed(struct ieee80211_hw *hw,
1947 memcpy(priv->staging_rxon.bssid_addr, 1947 memcpy(priv->staging_rxon.bssid_addr,
1948 bss_conf->bssid, ETH_ALEN); 1948 bss_conf->bssid, ETH_ALEN);
1949 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN); 1949 memcpy(priv->bssid, bss_conf->bssid, ETH_ALEN);
1950 iwlcore_config_ap(priv); 1950 iwlcore_config_ap(priv, vif);
1951 } else 1951 } else
1952 iwl_set_no_assoc(priv); 1952 iwl_set_no_assoc(priv);
1953 } 1953 }
@@ -1987,14 +1987,13 @@ int iwl_mac_beacon_update(struct ieee80211_hw *hw, struct sk_buff *skb)
1987 1987
1988 priv->ibss_beacon = skb; 1988 priv->ibss_beacon = skb;
1989 1989
1990 priv->assoc_id = 0;
1991 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp; 1990 timestamp = ((struct ieee80211_mgmt *)skb->data)->u.beacon.timestamp;
1992 priv->timestamp = le64_to_cpu(timestamp); 1991 priv->timestamp = le64_to_cpu(timestamp);
1993 1992
1994 IWL_DEBUG_MAC80211(priv, "leave\n"); 1993 IWL_DEBUG_MAC80211(priv, "leave\n");
1995 spin_unlock_irqrestore(&priv->lock, flags); 1994 spin_unlock_irqrestore(&priv->lock, flags);
1996 1995
1997 priv->cfg->ops->lib->post_associate(priv); 1996 priv->cfg->ops->lib->post_associate(priv, priv->vif);
1998 1997
1999 return 0; 1998 return 0;
2000} 1999}
@@ -2002,7 +2001,7 @@ EXPORT_SYMBOL(iwl_mac_beacon_update);
2002 2001
2003static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif) 2002static int iwl_set_mode(struct iwl_priv *priv, struct ieee80211_vif *vif)
2004{ 2003{
2005 iwl_connection_init_rx_config(priv, vif->type); 2004 iwl_connection_init_rx_config(priv, vif);
2006 2005
2007 if (priv->cfg->ops->hcmd->set_rxon_chain) 2006 if (priv->cfg->ops->hcmd->set_rxon_chain)
2008 priv->cfg->ops->hcmd->set_rxon_chain(priv); 2007 priv->cfg->ops->hcmd->set_rxon_chain(priv);
@@ -2176,7 +2175,7 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2176 iwl_set_rxon_channel(priv, conf->channel); 2175 iwl_set_rxon_channel(priv, conf->channel);
2177 iwl_set_rxon_ht(priv, ht_conf); 2176 iwl_set_rxon_ht(priv, ht_conf);
2178 2177
2179 iwl_set_flags_for_band(priv, conf->channel->band); 2178 iwl_set_flags_for_band(priv, conf->channel->band, priv->vif);
2180 spin_unlock_irqrestore(&priv->lock, flags); 2179 spin_unlock_irqrestore(&priv->lock, flags);
2181 if (iwl_is_associated(priv) && 2180 if (iwl_is_associated(priv) &&
2182 (le16_to_cpu(priv->active_rxon.channel) != ch) && 2181 (le16_to_cpu(priv->active_rxon.channel) != ch) &&
@@ -2259,8 +2258,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2259 spin_unlock_irqrestore(&priv->lock, flags); 2258 spin_unlock_irqrestore(&priv->lock, flags);
2260 2259
2261 spin_lock_irqsave(&priv->lock, flags); 2260 spin_lock_irqsave(&priv->lock, flags);
2262 priv->assoc_id = 0;
2263 priv->assoc_capability = 0;
2264 2261
2265 /* new association get rid of ibss beacon skb */ 2262 /* new association get rid of ibss beacon skb */
2266 if (priv->ibss_beacon) 2263 if (priv->ibss_beacon)
@@ -2268,7 +2265,6 @@ void iwl_mac_reset_tsf(struct ieee80211_hw *hw)
2268 2265
2269 priv->ibss_beacon = NULL; 2266 priv->ibss_beacon = NULL;
2270 2267
2271 priv->beacon_int = priv->vif->bss_conf.beacon_int;
2272 priv->timestamp = 0; 2268 priv->timestamp = 0;
2273 2269
2274 spin_unlock_irqrestore(&priv->lock, flags); 2270 spin_unlock_irqrestore(&priv->lock, flags);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 7a3f94926c25..1774ce9186eb 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -106,7 +106,7 @@ struct iwl_hcmd_utils_ops {
106 __le32 *tx_flags); 106 __le32 *tx_flags);
107 int (*calc_rssi)(struct iwl_priv *priv, 107 int (*calc_rssi)(struct iwl_priv *priv,
108 struct iwl_rx_phy_res *rx_resp); 108 struct iwl_rx_phy_res *rx_resp);
109 void (*request_scan)(struct iwl_priv *priv); 109 void (*request_scan)(struct iwl_priv *priv, struct ieee80211_vif *vif);
110}; 110};
111 111
112struct iwl_apm_ops { 112struct iwl_apm_ops {
@@ -180,8 +180,9 @@ struct iwl_lib_ops {
180 /* power */ 180 /* power */
181 int (*send_tx_power) (struct iwl_priv *priv); 181 int (*send_tx_power) (struct iwl_priv *priv);
182 void (*update_chain_flags)(struct iwl_priv *priv); 182 void (*update_chain_flags)(struct iwl_priv *priv);
183 void (*post_associate) (struct iwl_priv *priv); 183 void (*post_associate)(struct iwl_priv *priv,
184 void (*config_ap) (struct iwl_priv *priv); 184 struct ieee80211_vif *vif);
185 void (*config_ap)(struct iwl_priv *priv, struct ieee80211_vif *vif);
185 irqreturn_t (*isr) (int irq, void *data); 186 irqreturn_t (*isr) (int irq, void *data);
186 187
187 /* eeprom operations (as defined in iwl-eeprom.h) */ 188 /* eeprom operations (as defined in iwl-eeprom.h) */
@@ -334,8 +335,8 @@ int iwl_set_rxon_channel(struct iwl_priv *priv, struct ieee80211_channel *ch);
334void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf); 335void iwl_set_rxon_ht(struct iwl_priv *priv, struct iwl_ht_config *ht_conf);
335u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv, 336u8 iwl_is_ht40_tx_allowed(struct iwl_priv *priv,
336 struct ieee80211_sta_ht_cap *sta_ht_inf); 337 struct ieee80211_sta_ht_cap *sta_ht_inf);
337void iwl_set_flags_for_band(struct iwl_priv *priv, enum ieee80211_band band); 338void iwl_connection_init_rx_config(struct iwl_priv *priv,
338void iwl_connection_init_rx_config(struct iwl_priv *priv, int mode); 339 struct ieee80211_vif *vif);
339int iwl_set_decrypted_flag(struct iwl_priv *priv, 340int iwl_set_decrypted_flag(struct iwl_priv *priv,
340 struct ieee80211_hdr *hdr, 341 struct ieee80211_hdr *hdr,
341 u32 decrypt_res, 342 u32 decrypt_res,
@@ -345,7 +346,7 @@ void iwl_configure_filter(struct ieee80211_hw *hw,
345 unsigned int changed_flags, 346 unsigned int changed_flags,
346 unsigned int *total_flags, u64 multicast); 347 unsigned int *total_flags, u64 multicast);
347int iwl_set_hw_params(struct iwl_priv *priv); 348int iwl_set_hw_params(struct iwl_priv *priv);
348void iwl_post_associate(struct iwl_priv *priv); 349void iwl_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif);
349void iwl_bss_info_changed(struct ieee80211_hw *hw, 350void iwl_bss_info_changed(struct ieee80211_hw *hw,
350 struct ieee80211_vif *vif, 351 struct ieee80211_vif *vif,
351 struct ieee80211_bss_conf *bss_conf, 352 struct ieee80211_bss_conf *bss_conf,
@@ -357,7 +358,7 @@ int iwl_mac_add_interface(struct ieee80211_hw *hw,
357void iwl_mac_remove_interface(struct ieee80211_hw *hw, 358void iwl_mac_remove_interface(struct ieee80211_hw *hw,
358 struct ieee80211_vif *vif); 359 struct ieee80211_vif *vif);
359int iwl_mac_config(struct ieee80211_hw *hw, u32 changed); 360int iwl_mac_config(struct ieee80211_hw *hw, u32 changed);
360void iwl_config_ap(struct iwl_priv *priv); 361void iwl_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif);
361void iwl_mac_reset_tsf(struct ieee80211_hw *hw); 362void iwl_mac_reset_tsf(struct ieee80211_hw *hw);
362int iwl_alloc_txq_mem(struct iwl_priv *priv); 363int iwl_alloc_txq_mem(struct iwl_priv *priv);
363void iwl_free_txq_mem(struct iwl_priv *priv); 364void iwl_free_txq_mem(struct iwl_priv *priv);
@@ -520,7 +521,8 @@ u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
520 enum ieee80211_band band, 521 enum ieee80211_band band,
521 u8 n_probes); 522 u8 n_probes);
522u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, 523u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
523 enum ieee80211_band band); 524 enum ieee80211_band band,
525 struct ieee80211_vif *vif);
524void iwl_bg_scan_check(struct work_struct *data); 526void iwl_bg_scan_check(struct work_struct *data);
525void iwl_bg_abort_scan(struct work_struct *work); 527void iwl_bg_abort_scan(struct work_struct *work);
526void iwl_bg_scan_completed(struct work_struct *work); 528void iwl_bg_scan_completed(struct work_struct *work);
@@ -684,7 +686,7 @@ extern int iwl_send_lq_cmd(struct iwl_priv *priv,
684void iwl_apm_stop(struct iwl_priv *priv); 686void iwl_apm_stop(struct iwl_priv *priv);
685int iwl_apm_init(struct iwl_priv *priv); 687int iwl_apm_init(struct iwl_priv *priv);
686 688
687void iwl_setup_rxon_timing(struct iwl_priv *priv); 689void iwl_setup_rxon_timing(struct iwl_priv *priv, struct ieee80211_vif *vif);
688static inline int iwl_send_rxon_assoc(struct iwl_priv *priv) 690static inline int iwl_send_rxon_assoc(struct iwl_priv *priv)
689{ 691{
690 return priv->cfg->ops->hcmd->rxon_assoc(priv); 692 return priv->cfg->ops->hcmd->rxon_assoc(priv);
@@ -693,9 +695,10 @@ static inline int iwlcore_commit_rxon(struct iwl_priv *priv)
693{ 695{
694 return priv->cfg->ops->hcmd->commit_rxon(priv); 696 return priv->cfg->ops->hcmd->commit_rxon(priv);
695} 697}
696static inline void iwlcore_config_ap(struct iwl_priv *priv) 698static inline void iwlcore_config_ap(struct iwl_priv *priv,
699 struct ieee80211_vif *vif)
697{ 700{
698 priv->cfg->ops->lib->config_ap(priv); 701 priv->cfg->ops->lib->config_ap(priv, vif);
699} 702}
700static inline const struct ieee80211_supported_band *iwl_get_hw_mode( 703static inline const struct ieee80211_supported_band *iwl_get_hw_mode(
701 struct iwl_priv *priv, enum ieee80211_band band) 704 struct iwl_priv *priv, enum ieee80211_band band)
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index d09c8bc20d17..bcdb663ec923 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1243,7 +1243,6 @@ struct iwl_priv {
1243 1243
1244 /* Last Rx'd beacon timestamp */ 1244 /* Last Rx'd beacon timestamp */
1245 u64 timestamp; 1245 u64 timestamp;
1246 u16 beacon_int;
1247 struct ieee80211_vif *vif; 1246 struct ieee80211_vif *vif;
1248 1247
1249 union { 1248 union {
@@ -1305,10 +1304,6 @@ struct iwl_priv {
1305 struct iwl_hw_params hw_params; 1304 struct iwl_hw_params hw_params;
1306 1305
1307 u32 inta_mask; 1306 u32 inta_mask;
1308 /* Current association information needed to configure the
1309 * hardware */
1310 u16 assoc_id;
1311 u16 assoc_capability;
1312 1307
1313 struct iwl_qos_info qos_data; 1308 struct iwl_qos_info qos_data;
1314 1309
diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c
index 28e2d86ee055..32ca848e9262 100644
--- a/drivers/net/wireless/iwlwifi/iwl-scan.c
+++ b/drivers/net/wireless/iwlwifi/iwl-scan.c
@@ -264,7 +264,8 @@ inline u16 iwl_get_active_dwell_time(struct iwl_priv *priv,
264EXPORT_SYMBOL(iwl_get_active_dwell_time); 264EXPORT_SYMBOL(iwl_get_active_dwell_time);
265 265
266u16 iwl_get_passive_dwell_time(struct iwl_priv *priv, 266u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
267 enum ieee80211_band band) 267 enum ieee80211_band band,
268 struct ieee80211_vif *vif)
268{ 269{
269 u16 passive = (band == IEEE80211_BAND_2GHZ) ? 270 u16 passive = (band == IEEE80211_BAND_2GHZ) ?
270 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 : 271 IWL_PASSIVE_DWELL_BASE + IWL_PASSIVE_DWELL_TIME_24 :
@@ -274,7 +275,7 @@ u16 iwl_get_passive_dwell_time(struct iwl_priv *priv,
274 /* If we're associated, we clamp the maximum passive 275 /* If we're associated, we clamp the maximum passive
275 * dwell time to be 98% of the beacon interval (minus 276 * dwell time to be 98% of the beacon interval (minus
276 * 2 * channel tune time) */ 277 * 2 * channel tune time) */
277 passive = priv->beacon_int; 278 passive = vif ? vif->bss_conf.beacon_int : 0;
278 if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive) 279 if ((passive > IWL_PASSIVE_DWELL_BASE) || !passive)
279 passive = IWL_PASSIVE_DWELL_BASE; 280 passive = IWL_PASSIVE_DWELL_BASE;
280 passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2; 281 passive = (passive * 98) / 100 - IWL_CHANNEL_TUNE_TIME * 2;
@@ -294,7 +295,7 @@ void iwl_init_scan_params(struct iwl_priv *priv)
294} 295}
295EXPORT_SYMBOL(iwl_init_scan_params); 296EXPORT_SYMBOL(iwl_init_scan_params);
296 297
297static int iwl_scan_initiate(struct iwl_priv *priv) 298static int iwl_scan_initiate(struct iwl_priv *priv, struct ieee80211_vif *vif)
298{ 299{
299 WARN_ON(!mutex_is_locked(&priv->mutex)); 300 WARN_ON(!mutex_is_locked(&priv->mutex));
300 301
@@ -306,7 +307,7 @@ static int iwl_scan_initiate(struct iwl_priv *priv)
306 if (WARN_ON(!priv->cfg->ops->utils->request_scan)) 307 if (WARN_ON(!priv->cfg->ops->utils->request_scan))
307 return -EOPNOTSUPP; 308 return -EOPNOTSUPP;
308 309
309 priv->cfg->ops->utils->request_scan(priv); 310 priv->cfg->ops->utils->request_scan(priv, vif);
310 311
311 return 0; 312 return 0;
312} 313}
@@ -347,7 +348,7 @@ int iwl_mac_hw_scan(struct ieee80211_hw *hw,
347 priv->scan_band = req->channels[0]->band; 348 priv->scan_band = req->channels[0]->band;
348 priv->scan_request = req; 349 priv->scan_request = req;
349 350
350 ret = iwl_scan_initiate(priv); 351 ret = iwl_scan_initiate(priv, vif);
351 352
352 IWL_DEBUG_MAC80211(priv, "leave\n"); 353 IWL_DEBUG_MAC80211(priv, "leave\n");
353 354
@@ -398,7 +399,7 @@ void iwl_bg_start_internal_scan(struct work_struct *work)
398 if (WARN_ON(!priv->cfg->ops->utils->request_scan)) 399 if (WARN_ON(!priv->cfg->ops->utils->request_scan))
399 goto unlock; 400 goto unlock;
400 401
401 priv->cfg->ops->utils->request_scan(priv); 402 priv->cfg->ops->utils->request_scan(priv, NULL);
402 unlock: 403 unlock:
403 mutex_unlock(&priv->mutex); 404 mutex_unlock(&priv->mutex);
404} 405}
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 77ab00b98778..85a46ad667de 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -1847,7 +1847,8 @@ static void iwl3945_irq_tasklet(struct iwl_priv *priv)
1847static int iwl3945_get_channels_for_scan(struct iwl_priv *priv, 1847static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1848 enum ieee80211_band band, 1848 enum ieee80211_band band,
1849 u8 is_active, u8 n_probes, 1849 u8 is_active, u8 n_probes,
1850 struct iwl3945_scan_channel *scan_ch) 1850 struct iwl3945_scan_channel *scan_ch,
1851 struct ieee80211_vif *vif)
1851{ 1852{
1852 struct ieee80211_channel *chan; 1853 struct ieee80211_channel *chan;
1853 const struct ieee80211_supported_band *sband; 1854 const struct ieee80211_supported_band *sband;
@@ -1861,7 +1862,7 @@ static int iwl3945_get_channels_for_scan(struct iwl_priv *priv,
1861 return 0; 1862 return 0;
1862 1863
1863 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes); 1864 active_dwell = iwl_get_active_dwell_time(priv, band, n_probes);
1864 passive_dwell = iwl_get_passive_dwell_time(priv, band); 1865 passive_dwell = iwl_get_passive_dwell_time(priv, band, vif);
1865 1866
1866 if (passive_dwell <= active_dwell) 1867 if (passive_dwell <= active_dwell)
1867 passive_dwell = active_dwell + 1; 1868 passive_dwell = active_dwell + 1;
@@ -2543,7 +2544,7 @@ static void iwl3945_alive_start(struct iwl_priv *priv)
2543 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK; 2544 active_rxon->filter_flags &= ~RXON_FILTER_ASSOC_MSK;
2544 } else { 2545 } else {
2545 /* Initialize our rx_config data */ 2546 /* Initialize our rx_config data */
2546 iwl_connection_init_rx_config(priv, priv->iw_mode); 2547 iwl_connection_init_rx_config(priv, NULL);
2547 } 2548 }
2548 2549
2549 /* Configure Bluetooth device coexistence support */ 2550 /* Configure Bluetooth device coexistence support */
@@ -2811,7 +2812,7 @@ static void iwl3945_rfkill_poll(struct work_struct *data)
2811 2812
2812} 2813}
2813 2814
2814void iwl3945_request_scan(struct iwl_priv *priv) 2815void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2815{ 2816{
2816 struct iwl_host_cmd cmd = { 2817 struct iwl_host_cmd cmd = {
2817 .id = REPLY_SCAN_CMD, 2818 .id = REPLY_SCAN_CMD,
@@ -2892,7 +2893,7 @@ void iwl3945_request_scan(struct iwl_priv *priv)
2892 IWL_DEBUG_INFO(priv, "Scanning while associated...\n"); 2893 IWL_DEBUG_INFO(priv, "Scanning while associated...\n");
2893 2894
2894 spin_lock_irqsave(&priv->lock, flags); 2895 spin_lock_irqsave(&priv->lock, flags);
2895 interval = priv->beacon_int; 2896 interval = vif ? vif->bss_conf.beacon_int : 0;
2896 spin_unlock_irqrestore(&priv->lock, flags); 2897 spin_unlock_irqrestore(&priv->lock, flags);
2897 2898
2898 scan->suspend_time = 0; 2899 scan->suspend_time = 0;
@@ -2987,7 +2988,7 @@ void iwl3945_request_scan(struct iwl_priv *priv)
2987 2988
2988 scan->channel_count = 2989 scan->channel_count =
2989 iwl3945_get_channels_for_scan(priv, band, is_active, n_probes, 2990 iwl3945_get_channels_for_scan(priv, band, is_active, n_probes,
2990 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)]); 2991 (void *)&scan->data[le16_to_cpu(scan->tx_cmd.len)], vif);
2991 2992
2992 if (scan->channel_count == 0) { 2993 if (scan->channel_count == 0) {
2993 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count); 2994 IWL_DEBUG_SCAN(priv, "channel count %d\n", scan->channel_count);
@@ -3060,26 +3061,25 @@ static void iwl3945_bg_rx_replenish(struct work_struct *data)
3060 mutex_unlock(&priv->mutex); 3061 mutex_unlock(&priv->mutex);
3061} 3062}
3062 3063
3063void iwl3945_post_associate(struct iwl_priv *priv) 3064void iwl3945_post_associate(struct iwl_priv *priv, struct ieee80211_vif *vif)
3064{ 3065{
3065 int rc = 0; 3066 int rc = 0;
3066 struct ieee80211_conf *conf = NULL; 3067 struct ieee80211_conf *conf = NULL;
3067 3068
3068 if (priv->iw_mode == NL80211_IFTYPE_AP) { 3069 if (!vif || !priv->is_open)
3070 return;
3071
3072 if (vif->type == NL80211_IFTYPE_AP) {
3069 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__); 3073 IWL_ERR(priv, "%s Should not be called in AP mode\n", __func__);
3070 return; 3074 return;
3071 } 3075 }
3072 3076
3073
3074 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n", 3077 IWL_DEBUG_ASSOC(priv, "Associated as %d to: %pM\n",
3075 priv->assoc_id, priv->active_rxon.bssid_addr); 3078 vif->bss_conf.aid, priv->active_rxon.bssid_addr);
3076 3079
3077 if (test_bit(STATUS_EXIT_PENDING, &priv->status)) 3080 if (test_bit(STATUS_EXIT_PENDING, &priv->status))
3078 return; 3081 return;
3079 3082
3080 if (!priv->vif || !priv->is_open)
3081 return;
3082
3083 iwl_scan_cancel_timeout(priv, 200); 3083 iwl_scan_cancel_timeout(priv, 200);
3084 3084
3085 conf = ieee80211_get_hw_conf(priv->hw); 3085 conf = ieee80211_get_hw_conf(priv->hw);
@@ -3088,7 +3088,7 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3088 iwlcore_commit_rxon(priv); 3088 iwlcore_commit_rxon(priv);
3089 3089
3090 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); 3090 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
3091 iwl_setup_rxon_timing(priv); 3091 iwl_setup_rxon_timing(priv, vif);
3092 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 3092 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
3093 sizeof(priv->rxon_timing), &priv->rxon_timing); 3093 sizeof(priv->rxon_timing), &priv->rxon_timing);
3094 if (rc) 3094 if (rc)
@@ -3097,40 +3097,38 @@ void iwl3945_post_associate(struct iwl_priv *priv)
3097 3097
3098 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK; 3098 priv->staging_rxon.filter_flags |= RXON_FILTER_ASSOC_MSK;
3099 3099
3100 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 3100 priv->staging_rxon.assoc_id = cpu_to_le16(vif->bss_conf.aid);
3101 3101
3102 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n", 3102 IWL_DEBUG_ASSOC(priv, "assoc id %d beacon interval %d\n",
3103 priv->assoc_id, priv->beacon_int); 3103 vif->bss_conf.aid, vif->bss_conf.beacon_int);
3104 3104
3105 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3105 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
3106 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK; 3106 priv->staging_rxon.flags |= RXON_FLG_SHORT_PREAMBLE_MSK;
3107 else 3107 else
3108 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK; 3108 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_PREAMBLE_MSK;
3109 3109
3110 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3110 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3111 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME) 3111 if (vif->bss_conf.assoc_capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
3112 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK; 3112 priv->staging_rxon.flags |= RXON_FLG_SHORT_SLOT_MSK;
3113 else 3113 else
3114 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3114 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3115 3115
3116 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 3116 if (vif->type == NL80211_IFTYPE_ADHOC)
3117 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK; 3117 priv->staging_rxon.flags &= ~RXON_FLG_SHORT_SLOT_MSK;
3118
3119 } 3118 }
3120 3119
3121 iwlcore_commit_rxon(priv); 3120 iwlcore_commit_rxon(priv);
3122 3121
3123 switch (priv->iw_mode) { 3122 switch (vif->type) {
3124 case NL80211_IFTYPE_STATION: 3123 case NL80211_IFTYPE_STATION:
3125 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID); 3124 iwl3945_rate_scale_init(priv->hw, IWL_AP_ID);
3126 break; 3125 break;
3127 case NL80211_IFTYPE_ADHOC: 3126 case NL80211_IFTYPE_ADHOC:
3128 priv->assoc_id = 1;
3129 iwl3945_send_beacon_cmd(priv); 3127 iwl3945_send_beacon_cmd(priv);
3130 break; 3128 break;
3131 default: 3129 default:
3132 IWL_ERR(priv, "%s Should not be called in %d mode\n", 3130 IWL_ERR(priv, "%s Should not be called in %d mode\n",
3133 __func__, priv->iw_mode); 3131 __func__, vif->type);
3134 break; 3132 break;
3135 } 3133 }
3136} 3134}
@@ -3254,7 +3252,7 @@ static int iwl3945_mac_tx(struct ieee80211_hw *hw, struct sk_buff *skb)
3254 return NETDEV_TX_OK; 3252 return NETDEV_TX_OK;
3255} 3253}
3256 3254
3257void iwl3945_config_ap(struct iwl_priv *priv) 3255void iwl3945_config_ap(struct iwl_priv *priv, struct ieee80211_vif *vif)
3258{ 3256{
3259 int rc = 0; 3257 int rc = 0;
3260 3258
@@ -3270,7 +3268,7 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3270 3268
3271 /* RXON Timing */ 3269 /* RXON Timing */
3272 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd)); 3270 memset(&priv->rxon_timing, 0, sizeof(struct iwl_rxon_time_cmd));
3273 iwl_setup_rxon_timing(priv); 3271 iwl_setup_rxon_timing(priv, vif);
3274 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING, 3272 rc = iwl_send_cmd_pdu(priv, REPLY_RXON_TIMING,
3275 sizeof(priv->rxon_timing), 3273 sizeof(priv->rxon_timing),
3276 &priv->rxon_timing); 3274 &priv->rxon_timing);
@@ -3278,9 +3276,10 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3278 IWL_WARN(priv, "REPLY_RXON_TIMING failed - " 3276 IWL_WARN(priv, "REPLY_RXON_TIMING failed - "
3279 "Attempting to continue.\n"); 3277 "Attempting to continue.\n");
3280 3278
3281 /* FIXME: what should be the assoc_id for AP? */ 3279 priv->staging_rxon.assoc_id = 0;
3282 priv->staging_rxon.assoc_id = cpu_to_le16(priv->assoc_id); 3280
3283 if (priv->assoc_capability & WLAN_CAPABILITY_SHORT_PREAMBLE) 3281 if (vif->bss_conf.assoc_capability &
3282 WLAN_CAPABILITY_SHORT_PREAMBLE)
3284 priv->staging_rxon.flags |= 3283 priv->staging_rxon.flags |=
3285 RXON_FLG_SHORT_PREAMBLE_MSK; 3284 RXON_FLG_SHORT_PREAMBLE_MSK;
3286 else 3285 else
@@ -3288,15 +3287,15 @@ void iwl3945_config_ap(struct iwl_priv *priv)
3288 ~RXON_FLG_SHORT_PREAMBLE_MSK; 3287 ~RXON_FLG_SHORT_PREAMBLE_MSK;
3289 3288
3290 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) { 3289 if (priv->staging_rxon.flags & RXON_FLG_BAND_24G_MSK) {
3291 if (priv->assoc_capability & 3290 if (vif->bss_conf.assoc_capability &
3292 WLAN_CAPABILITY_SHORT_SLOT_TIME) 3291 WLAN_CAPABILITY_SHORT_SLOT_TIME)
3293 priv->staging_rxon.flags |= 3292 priv->staging_rxon.flags |=
3294 RXON_FLG_SHORT_SLOT_MSK; 3293 RXON_FLG_SHORT_SLOT_MSK;
3295 else 3294 else
3296 priv->staging_rxon.flags &= 3295 priv->staging_rxon.flags &=
3297 ~RXON_FLG_SHORT_SLOT_MSK; 3296 ~RXON_FLG_SHORT_SLOT_MSK;
3298 3297
3299 if (priv->iw_mode == NL80211_IFTYPE_ADHOC) 3298 if (vif->type == NL80211_IFTYPE_ADHOC)
3300 priv->staging_rxon.flags &= 3299 priv->staging_rxon.flags &=
3301 ~RXON_FLG_SHORT_SLOT_MSK; 3300 ~RXON_FLG_SHORT_SLOT_MSK;
3302 } 3301 }