aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2010-08-27 11:53:46 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-08-27 11:53:46 -0400
commita194e3249baf954dc34c67cdad5b8bed36f49e72 (patch)
tree2010fbba8fdae3179a1439f2038e30694a85124f /drivers/net/wireless
parent751ca305d0e37f0d44b6a261e7db31aa6b60fbf4 (diff)
iwlwifi: contextify broadcast station
The broadcast station ID is per context, so add a variable for the ID in the context and use it everywhere we previously hardcoded it. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-1000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945-rs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c11
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-5000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-6000.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-core.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c89
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.h29
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c20
15 files changed, 142 insertions, 93 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-1000.c b/drivers/net/wireless/iwlwifi/iwl-1000.c
index 3bf5a30828b..674fb93ae17 100644
--- a/drivers/net/wireless/iwlwifi/iwl-1000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-1000.c
@@ -130,7 +130,7 @@ static int iwl1000_hw_set_hw_params(struct iwl_priv *priv)
130 sizeof(struct iwlagn_scd_bc_tbl); 130 sizeof(struct iwlagn_scd_bc_tbl);
131 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 131 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
132 priv->hw_params.max_stations = IWLAGN_STATION_COUNT; 132 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
133 priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; 133 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
134 134
135 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 135 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
136 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 136 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -217,7 +217,7 @@ static struct iwl_lib_ops iwl1000_lib = {
217 .set_ct_kill = iwl1000_set_ct_threshold, 217 .set_ct_kill = iwl1000_set_ct_threshold,
218 }, 218 },
219 .manage_ibss_station = iwlagn_manage_ibss_station, 219 .manage_ibss_station = iwlagn_manage_ibss_station,
220 .update_bcast_station = iwl_update_bcast_station, 220 .update_bcast_stations = iwl_update_bcast_stations,
221 .debugfs_ops = { 221 .debugfs_ops = {
222 .rx_stats_read = iwl_ucode_rx_stats_read, 222 .rx_stats_read = iwl_ucode_rx_stats_read,
223 .tx_stats_read = iwl_ucode_tx_stats_read, 223 .tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
index 08f53f869c1..0cfc7a605e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945-rs.c
@@ -343,7 +343,7 @@ void iwl3945_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 s
343 int i; 343 int i;
344 344
345 IWL_DEBUG_INFO(priv, "enter\n"); 345 IWL_DEBUG_INFO(priv, "enter\n");
346 if (sta_id == priv->hw_params.bcast_sta_id) 346 if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id)
347 goto out; 347 goto out;
348 348
349 psta = (struct iwl3945_sta_priv *) sta->drv_priv; 349 psta = (struct iwl3945_sta_priv *) sta->drv_priv;
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index f059b1dd4d4..905575c840c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -2305,8 +2305,10 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
2305 int ret; 2305 int ret;
2306 2306
2307 if (add) { 2307 if (add) {
2308 ret = iwl_add_bssid_station(priv, vif->bss_conf.bssid, false, 2308 ret = iwl_add_bssid_station(
2309 &vif_priv->ibss_bssid_sta_id); 2309 priv, &priv->contexts[IWL_RXON_CTX_BSS],
2310 vif->bss_conf.bssid, false,
2311 &vif_priv->ibss_bssid_sta_id);
2310 if (ret) 2312 if (ret)
2311 return ret; 2313 return ret;
2312 2314
@@ -2424,7 +2426,7 @@ int iwl3945_hw_set_hw_params(struct iwl_priv *priv)
2424 priv->hw_params.max_rxq_size = RX_QUEUE_SIZE; 2426 priv->hw_params.max_rxq_size = RX_QUEUE_SIZE;
2425 priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG; 2427 priv->hw_params.max_rxq_log = RX_QUEUE_SIZE_LOG;
2426 priv->hw_params.max_stations = IWL3945_STATION_COUNT; 2428 priv->hw_params.max_stations = IWL3945_STATION_COUNT;
2427 priv->hw_params.bcast_sta_id = IWL3945_BROADCAST_ID; 2429 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL3945_BROADCAST_ID;
2428 2430
2429 priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR; 2431 priv->hw_params.rx_wrt_ptr_reg = FH39_RSCSR_CHNL0_WPTR;
2430 priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL; 2432 priv->hw_params.max_beacon_itrvl = IWL39_MAX_UCODE_BEACON_INTERVAL;
@@ -2442,7 +2444,8 @@ unsigned int iwl3945_hw_get_beacon_cmd(struct iwl_priv *priv,
2442 tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u; 2444 tx_beacon_cmd = (struct iwl3945_tx_beacon_cmd *)&frame->u;
2443 memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd)); 2445 memset(tx_beacon_cmd, 0, sizeof(*tx_beacon_cmd));
2444 2446
2445 tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; 2447 tx_beacon_cmd->tx.sta_id =
2448 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
2446 tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 2449 tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
2447 2450
2448 frame_size = iwl3945_fill_beacon_frame(priv, 2451 frame_size = iwl3945_fill_beacon_frame(priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index cda389c3b02..c155816f811 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -657,7 +657,7 @@ static int iwl4965_hw_set_hw_params(struct iwl_priv *priv)
657 sizeof(struct iwl4965_scd_bc_tbl); 657 sizeof(struct iwl4965_scd_bc_tbl);
658 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 658 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
659 priv->hw_params.max_stations = IWL4965_STATION_COUNT; 659 priv->hw_params.max_stations = IWL4965_STATION_COUNT;
660 priv->hw_params.bcast_sta_id = IWL4965_BROADCAST_ID; 660 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWL4965_BROADCAST_ID;
661 priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE; 661 priv->hw_params.max_data_size = IWL49_RTC_DATA_SIZE;
662 priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE; 662 priv->hw_params.max_inst_size = IWL49_RTC_INST_SIZE;
663 priv->hw_params.max_bsm_size = BSM_SRAM_SIZE; 663 priv->hw_params.max_bsm_size = BSM_SRAM_SIZE;
@@ -2010,7 +2010,7 @@ static u8 iwl_find_station(struct iwl_priv *priv, const u8 *addr)
2010 start = IWL_STA_ID; 2010 start = IWL_STA_ID;
2011 2011
2012 if (is_broadcast_ether_addr(addr)) 2012 if (is_broadcast_ether_addr(addr))
2013 return priv->hw_params.bcast_sta_id; 2013 return priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
2014 2014
2015 spin_lock_irqsave(&priv->sta_lock, flags); 2015 spin_lock_irqsave(&priv->sta_lock, flags);
2016 for (i = start; i < priv->hw_params.max_stations; i++) 2016 for (i = start; i < priv->hw_params.max_stations; i++)
@@ -2283,7 +2283,7 @@ static struct iwl_lib_ops iwl4965_lib = {
2283 .set_ct_kill = iwl4965_set_ct_threshold, 2283 .set_ct_kill = iwl4965_set_ct_threshold,
2284 }, 2284 },
2285 .manage_ibss_station = iwlagn_manage_ibss_station, 2285 .manage_ibss_station = iwlagn_manage_ibss_station,
2286 .update_bcast_station = iwl_update_bcast_station, 2286 .update_bcast_stations = iwl_update_bcast_stations,
2287 .debugfs_ops = { 2287 .debugfs_ops = {
2288 .rx_stats_read = iwl_ucode_rx_stats_read, 2288 .rx_stats_read = iwl_ucode_rx_stats_read,
2289 .tx_stats_read = iwl_ucode_tx_stats_read, 2289 .tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-5000.c b/drivers/net/wireless/iwlwifi/iwl-5000.c
index 8536f19d7dc..d67031f080c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-5000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-5000.c
@@ -180,7 +180,7 @@ static int iwl5000_hw_set_hw_params(struct iwl_priv *priv)
180 sizeof(struct iwlagn_scd_bc_tbl); 180 sizeof(struct iwlagn_scd_bc_tbl);
181 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 181 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
182 priv->hw_params.max_stations = IWLAGN_STATION_COUNT; 182 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
183 priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; 183 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
184 184
185 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 185 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
186 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 186 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -227,7 +227,7 @@ static int iwl5150_hw_set_hw_params(struct iwl_priv *priv)
227 sizeof(struct iwlagn_scd_bc_tbl); 227 sizeof(struct iwlagn_scd_bc_tbl);
228 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 228 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
229 priv->hw_params.max_stations = IWLAGN_STATION_COUNT; 229 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
230 priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; 230 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
231 231
232 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE; 232 priv->hw_params.max_data_size = IWLAGN_RTC_DATA_SIZE;
233 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE; 233 priv->hw_params.max_inst_size = IWLAGN_RTC_INST_SIZE;
@@ -398,7 +398,7 @@ static struct iwl_lib_ops iwl5000_lib = {
398 .set_ct_kill = iwl5000_set_ct_threshold, 398 .set_ct_kill = iwl5000_set_ct_threshold,
399 }, 399 },
400 .manage_ibss_station = iwlagn_manage_ibss_station, 400 .manage_ibss_station = iwlagn_manage_ibss_station,
401 .update_bcast_station = iwl_update_bcast_station, 401 .update_bcast_stations = iwl_update_bcast_stations,
402 .debugfs_ops = { 402 .debugfs_ops = {
403 .rx_stats_read = iwl_ucode_rx_stats_read, 403 .rx_stats_read = iwl_ucode_rx_stats_read,
404 .tx_stats_read = iwl_ucode_tx_stats_read, 404 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -469,7 +469,7 @@ static struct iwl_lib_ops iwl5150_lib = {
469 .set_ct_kill = iwl5150_set_ct_threshold, 469 .set_ct_kill = iwl5150_set_ct_threshold,
470 }, 470 },
471 .manage_ibss_station = iwlagn_manage_ibss_station, 471 .manage_ibss_station = iwlagn_manage_ibss_station,
472 .update_bcast_station = iwl_update_bcast_station, 472 .update_bcast_stations = iwl_update_bcast_stations,
473 .debugfs_ops = { 473 .debugfs_ops = {
474 .rx_stats_read = iwl_ucode_rx_stats_read, 474 .rx_stats_read = iwl_ucode_rx_stats_read,
475 .tx_stats_read = iwl_ucode_tx_stats_read, 475 .tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-6000.c b/drivers/net/wireless/iwlwifi/iwl-6000.c
index bf1fe25fae7..8c4a98b82e3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-6000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-6000.c
@@ -161,7 +161,7 @@ static int iwl6000_hw_set_hw_params(struct iwl_priv *priv)
161 sizeof(struct iwlagn_scd_bc_tbl); 161 sizeof(struct iwlagn_scd_bc_tbl);
162 priv->hw_params.tfd_size = sizeof(struct iwl_tfd); 162 priv->hw_params.tfd_size = sizeof(struct iwl_tfd);
163 priv->hw_params.max_stations = IWLAGN_STATION_COUNT; 163 priv->hw_params.max_stations = IWLAGN_STATION_COUNT;
164 priv->hw_params.bcast_sta_id = IWLAGN_BROADCAST_ID; 164 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id = IWLAGN_BROADCAST_ID;
165 165
166 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE; 166 priv->hw_params.max_data_size = IWL60_RTC_DATA_SIZE;
167 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE; 167 priv->hw_params.max_inst_size = IWL60_RTC_INST_SIZE;
@@ -323,7 +323,7 @@ static struct iwl_lib_ops iwl6000_lib = {
323 .set_calib_version = iwl6000_set_calib_version, 323 .set_calib_version = iwl6000_set_calib_version,
324 }, 324 },
325 .manage_ibss_station = iwlagn_manage_ibss_station, 325 .manage_ibss_station = iwlagn_manage_ibss_station,
326 .update_bcast_station = iwl_update_bcast_station, 326 .update_bcast_stations = iwl_update_bcast_stations,
327 .debugfs_ops = { 327 .debugfs_ops = {
328 .rx_stats_read = iwl_ucode_rx_stats_read, 328 .rx_stats_read = iwl_ucode_rx_stats_read,
329 .tx_stats_read = iwl_ucode_tx_stats_read, 329 .tx_stats_read = iwl_ucode_tx_stats_read,
@@ -398,7 +398,7 @@ static struct iwl_lib_ops iwl6000g2b_lib = {
398 .set_calib_version = iwl6000_set_calib_version, 398 .set_calib_version = iwl6000_set_calib_version,
399 }, 399 },
400 .manage_ibss_station = iwlagn_manage_ibss_station, 400 .manage_ibss_station = iwlagn_manage_ibss_station,
401 .update_bcast_station = iwl_update_bcast_station, 401 .update_bcast_stations = iwl_update_bcast_stations,
402 .debugfs_ops = { 402 .debugfs_ops = {
403 .rx_stats_read = iwl_ucode_rx_stats_read, 403 .rx_stats_read = iwl_ucode_rx_stats_read,
404 .tx_stats_read = iwl_ucode_tx_stats_read, 404 .tx_stats_read = iwl_ucode_tx_stats_read,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index f919977d563..cb3c173e7c8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -1163,6 +1163,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1163 }; 1163 };
1164 struct iwl_scan_cmd *scan; 1164 struct iwl_scan_cmd *scan;
1165 struct ieee80211_conf *conf = NULL; 1165 struct ieee80211_conf *conf = NULL;
1166 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
1166 u32 rate_flags = 0; 1167 u32 rate_flags = 0;
1167 u16 cmd_len; 1168 u16 cmd_len;
1168 u16 rx_chain = 0; 1169 u16 rx_chain = 0;
@@ -1175,6 +1176,9 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1175 u8 active_chains; 1176 u8 active_chains;
1176 u8 scan_tx_antennas = priv->hw_params.valid_tx_ant; 1177 u8 scan_tx_antennas = priv->hw_params.valid_tx_ant;
1177 1178
1179 if (vif)
1180 ctx = iwl_rxon_ctx_from_vif(vif);
1181
1178 conf = ieee80211_get_hw_conf(priv->hw); 1182 conf = ieee80211_get_hw_conf(priv->hw);
1179 1183
1180 cancel_delayed_work(&priv->scan_check); 1184 cancel_delayed_work(&priv->scan_check);
@@ -1283,7 +1287,7 @@ void iwlagn_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
1283 IWL_DEBUG_SCAN(priv, "Start passive scan.\n"); 1287 IWL_DEBUG_SCAN(priv, "Start passive scan.\n");
1284 1288
1285 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; 1289 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
1286 scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; 1290 scan->tx_cmd.sta_id = ctx->bcast_sta_id;
1287 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 1291 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
1288 1292
1289 switch (priv->scan_band) { 1293 switch (priv->scan_band) {
@@ -1446,7 +1450,8 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
1446 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv; 1450 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
1447 1451
1448 if (add) 1452 if (add)
1449 return iwl_add_bssid_station(priv, vif->bss_conf.bssid, true, 1453 return iwl_add_bssid_station(priv, vif_priv->ctx,
1454 vif->bss_conf.bssid, true,
1450 &vif_priv->ibss_bssid_sta_id); 1455 &vif_priv->ibss_bssid_sta_id);
1451 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id, 1456 return iwl_remove_station(priv, vif_priv->ibss_bssid_sta_id,
1452 vif->bss_conf.bssid); 1457 vif->bss_conf.bssid);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 88b7bbfb1f9..a2e4ca0eb7c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -531,6 +531,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
531 struct iwl_device_cmd *out_cmd; 531 struct iwl_device_cmd *out_cmd;
532 struct iwl_cmd_meta *out_meta; 532 struct iwl_cmd_meta *out_meta;
533 struct iwl_tx_cmd *tx_cmd; 533 struct iwl_tx_cmd *tx_cmd;
534 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
534 int swq_id, txq_id; 535 int swq_id, txq_id;
535 dma_addr_t phys_addr; 536 dma_addr_t phys_addr;
536 dma_addr_t txcmd_phys; 537 dma_addr_t txcmd_phys;
@@ -545,6 +546,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
545 u8 *qc = NULL; 546 u8 *qc = NULL;
546 unsigned long flags; 547 unsigned long flags;
547 548
549 if (info->control.vif)
550 ctx = iwl_rxon_ctx_from_vif(info->control.vif);
551
548 spin_lock_irqsave(&priv->lock, flags); 552 spin_lock_irqsave(&priv->lock, flags);
549 if (iwl_is_rfkill(priv)) { 553 if (iwl_is_rfkill(priv)) {
550 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); 554 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
@@ -565,7 +569,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
565 hdr_len = ieee80211_hdrlen(fc); 569 hdr_len = ieee80211_hdrlen(fc);
566 570
567 /* Find index into station table for destination station */ 571 /* Find index into station table for destination station */
568 sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); 572 sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta);
569 if (sta_id == IWL_INVALID_STATION) { 573 if (sta_id == IWL_INVALID_STATION) {
570 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 574 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
571 hdr->addr1); 575 hdr->addr1);
@@ -577,8 +581,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
577 if (sta) 581 if (sta)
578 sta_priv = (void *)sta->drv_priv; 582 sta_priv = (void *)sta->drv_priv;
579 583
580 if (sta_priv && sta_id != priv->hw_params.bcast_sta_id && 584 if (sta_priv && sta_priv->asleep) {
581 sta_priv->asleep) {
582 WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)); 585 WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
583 /* 586 /*
584 * This sends an asynchronous command to the device, 587 * This sends an asynchronous command to the device,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 5f67955c76c..d2222782f46 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -357,7 +357,9 @@ static unsigned int iwl_hw_get_beacon_cmd(struct iwl_priv *priv,
357 357
358 /* Set up TX command fields */ 358 /* Set up TX command fields */
359 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size); 359 tx_beacon_cmd->tx.len = cpu_to_le16((u16)frame_size);
360 tx_beacon_cmd->tx.sta_id = priv->hw_params.bcast_sta_id; 360#warning "Use proper STA ID"
361 tx_beacon_cmd->tx.sta_id =
362 priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
361 tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 363 tx_beacon_cmd->tx.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
362 tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK | 364 tx_beacon_cmd->tx.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK |
363 TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK; 365 TX_CMD_FLG_TSF_MSK | TX_CMD_FLG_STA_RATE_MSK;
@@ -2829,7 +2831,7 @@ static void __iwl_down(struct iwl_priv *priv)
2829 del_timer_sync(&priv->monitor_recover); 2831 del_timer_sync(&priv->monitor_recover);
2830 2832
2831 iwl_clear_ucode_stations(priv); 2833 iwl_clear_ucode_stations(priv);
2832 iwl_dealloc_bcast_station(priv); 2834 iwl_dealloc_bcast_stations(priv);
2833 iwl_clear_driver_stations(priv); 2835 iwl_clear_driver_stations(priv);
2834 2836
2835 /* reset BT coex data */ 2837 /* reset BT coex data */
@@ -2971,6 +2973,7 @@ static int iwl_prepare_card_hw(struct iwl_priv *priv)
2971 2973
2972static int __iwl_up(struct iwl_priv *priv) 2974static int __iwl_up(struct iwl_priv *priv)
2973{ 2975{
2976 struct iwl_rxon_context *ctx;
2974 int i; 2977 int i;
2975 int ret; 2978 int ret;
2976 2979
@@ -2984,9 +2987,13 @@ static int __iwl_up(struct iwl_priv *priv)
2984 return -EIO; 2987 return -EIO;
2985 } 2988 }
2986 2989
2987 ret = iwl_alloc_bcast_station(priv, true); 2990 for_each_context(priv, ctx) {
2988 if (ret) 2991 ret = iwl_alloc_bcast_station(priv, ctx, true);
2989 return ret; 2992 if (ret) {
2993 iwl_dealloc_bcast_stations(priv);
2994 return ret;
2995 }
2996 }
2990 2997
2991 iwl_prepare_card_hw(priv); 2998 iwl_prepare_card_hw(priv);
2992 2999
@@ -3520,9 +3527,11 @@ static void iwl_mac_update_tkip_key(struct ieee80211_hw *hw,
3520{ 3527{
3521 3528
3522 struct iwl_priv *priv = hw->priv; 3529 struct iwl_priv *priv = hw->priv;
3530 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
3531
3523 IWL_DEBUG_MAC80211(priv, "enter\n"); 3532 IWL_DEBUG_MAC80211(priv, "enter\n");
3524 3533
3525 iwl_update_tkip_key(priv, keyconf, sta, 3534 iwl_update_tkip_key(priv, vif_priv->ctx, keyconf, sta,
3526 iv32, phase1key); 3535 iv32, phase1key);
3527 3536
3528 IWL_DEBUG_MAC80211(priv, "leave\n"); 3537 IWL_DEBUG_MAC80211(priv, "leave\n");
@@ -3534,6 +3543,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3534 struct ieee80211_key_conf *key) 3543 struct ieee80211_key_conf *key)
3535{ 3544{
3536 struct iwl_priv *priv = hw->priv; 3545 struct iwl_priv *priv = hw->priv;
3546 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
3537 int ret; 3547 int ret;
3538 u8 sta_id; 3548 u8 sta_id;
3539 bool is_default_wep_key = false; 3549 bool is_default_wep_key = false;
@@ -3545,7 +3555,7 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3545 return -EOPNOTSUPP; 3555 return -EOPNOTSUPP;
3546 } 3556 }
3547 3557
3548 sta_id = iwl_sta_id_or_broadcast(priv, sta); 3558 sta_id = iwl_sta_id_or_broadcast(priv, vif_priv->ctx, sta);
3549 if (sta_id == IWL_INVALID_STATION) 3559 if (sta_id == IWL_INVALID_STATION)
3550 return -EINVAL; 3560 return -EINVAL;
3551 3561
@@ -3573,7 +3583,8 @@ static int iwl_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3573 if (is_default_wep_key) 3583 if (is_default_wep_key)
3574 ret = iwl_set_default_wep_key(priv, key); 3584 ret = iwl_set_default_wep_key(priv, key);
3575 else 3585 else
3576 ret = iwl_set_dynamic_key(priv, key, sta_id); 3586 ret = iwl_set_dynamic_key(priv, vif_priv->ctx,
3587 key, sta_id);
3577 3588
3578 IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n"); 3589 IWL_DEBUG_MAC80211(priv, "enable hwcrypto key\n");
3579 break; 3590 break;
@@ -3713,6 +3724,7 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3713{ 3724{
3714 struct iwl_priv *priv = hw->priv; 3725 struct iwl_priv *priv = hw->priv;
3715 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 3726 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
3727 struct iwl_vif_priv *vif_priv = (void *)vif->drv_priv;
3716 bool is_ap = vif->type == NL80211_IFTYPE_STATION; 3728 bool is_ap = vif->type == NL80211_IFTYPE_STATION;
3717 int ret; 3729 int ret;
3718 u8 sta_id; 3730 u8 sta_id;
@@ -3728,8 +3740,8 @@ static int iwlagn_mac_sta_add(struct ieee80211_hw *hw,
3728 if (vif->type == NL80211_IFTYPE_AP) 3740 if (vif->type == NL80211_IFTYPE_AP)
3729 sta_priv->client = true; 3741 sta_priv->client = true;
3730 3742
3731 ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, 3743 ret = iwl_add_station_common(priv, vif_priv->ctx, sta->addr,
3732 &sta_id); 3744 is_ap, &sta->ht_cap, &sta_id);
3733 if (ret) { 3745 if (ret) {
3734 IWL_ERR(priv, "Unable to add station %pM (%d)\n", 3746 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
3735 sta->addr, ret); 3747 sta->addr, ret);
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index f6aa5ce478b..f7bfe59c0ca 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -2113,8 +2113,8 @@ int iwl_mac_config(struct ieee80211_hw *hw, u32 changed)
2113 2113
2114 spin_unlock_irqrestore(&priv->lock, flags); 2114 spin_unlock_irqrestore(&priv->lock, flags);
2115 2115
2116 if (priv->cfg->ops->lib->update_bcast_station) 2116 if (priv->cfg->ops->lib->update_bcast_stations)
2117 ret = priv->cfg->ops->lib->update_bcast_station(priv); 2117 ret = priv->cfg->ops->lib->update_bcast_stations(priv);
2118 2118
2119 set_ch_out: 2119 set_ch_out:
2120 /* The list of supported rates and rate mask can be different 2120 /* The list of supported rates and rate mask can be different
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.h b/drivers/net/wireless/iwlwifi/iwl-core.h
index 80c256246e4..7aa9c6c5c43 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.h
+++ b/drivers/net/wireless/iwlwifi/iwl-core.h
@@ -206,7 +206,7 @@ struct iwl_lib_ops {
206 /* station management */ 206 /* station management */
207 int (*manage_ibss_station)(struct iwl_priv *priv, 207 int (*manage_ibss_station)(struct iwl_priv *priv,
208 struct ieee80211_vif *vif, bool add); 208 struct ieee80211_vif *vif, bool add);
209 int (*update_bcast_station)(struct iwl_priv *priv); 209 int (*update_bcast_stations)(struct iwl_priv *priv);
210 /* recover from tx queue stall */ 210 /* recover from tx queue stall */
211 void (*recover_from_tx_stall)(unsigned long data); 211 void (*recover_from_tx_stall)(unsigned long data);
212 /* check for plcp health */ 212 /* check for plcp health */
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 8ec377d514f..f51c07c078c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -681,7 +681,6 @@ struct iwl_sensitivity_ranges {
681 * @rx_page_order: Rx buffer page order 681 * @rx_page_order: Rx buffer page order
682 * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR 682 * @rx_wrt_ptr_reg: FH{39}_RSCSR_CHNL0_WPTR
683 * @max_stations: 683 * @max_stations:
684 * @bcast_sta_id:
685 * @ht40_channel: is 40MHz width possible in band 2.4 684 * @ht40_channel: is 40MHz width possible in band 2.4
686 * BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ) 685 * BIT(IEEE80211_BAND_5GHZ) BIT(IEEE80211_BAND_5GHZ)
687 * @sw_crypto: 0 for hw, 1 for sw 686 * @sw_crypto: 0 for hw, 1 for sw
@@ -705,7 +704,6 @@ struct iwl_hw_params {
705 u32 rx_page_order; 704 u32 rx_page_order;
706 u32 rx_wrt_ptr_reg; 705 u32 rx_wrt_ptr_reg;
707 u8 max_stations; 706 u8 max_stations;
708 u8 bcast_sta_id;
709 u8 ht40_channel; 707 u8 ht40_channel;
710 u8 max_beacon_itrvl; /* in 1024 ms */ 708 u8 max_beacon_itrvl; /* in 1024 ms */
711 u32 max_inst_size; 709 u32 max_inst_size;
@@ -1126,6 +1124,8 @@ struct iwl_rxon_context {
1126 struct iwl_rxon_cmd staging; 1124 struct iwl_rxon_cmd staging;
1127 1125
1128 struct iwl_rxon_time_cmd timing; 1126 struct iwl_rxon_time_cmd timing;
1127
1128 u8 bcast_sta_id;
1129}; 1129};
1130 1130
1131struct iwl_priv { 1131struct iwl_priv {
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 43afb8fb36c..b1275e34520 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -226,8 +226,8 @@ static void iwl_set_ht_add_station(struct iwl_priv *priv, u8 index,
226 * 226 *
227 * should be called with sta_lock held 227 * should be called with sta_lock held
228 */ 228 */
229static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr, 229static u8 iwl_prep_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
230 bool is_ap, 230 const u8 *addr, bool is_ap,
231 struct ieee80211_sta_ht_cap *ht_info) 231 struct ieee80211_sta_ht_cap *ht_info)
232{ 232{
233 struct iwl_station_entry *station; 233 struct iwl_station_entry *station;
@@ -238,7 +238,7 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
238 if (is_ap) 238 if (is_ap)
239 sta_id = IWL_AP_ID; 239 sta_id = IWL_AP_ID;
240 else if (is_broadcast_ether_addr(addr)) 240 else if (is_broadcast_ether_addr(addr))
241 sta_id = priv->hw_params.bcast_sta_id; 241 sta_id = ctx->bcast_sta_id;
242 else 242 else
243 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) { 243 for (i = IWL_STA_ID; i < priv->hw_params.max_stations; i++) {
244 if (!compare_ether_addr(priv->stations[i].sta.sta.addr, 244 if (!compare_ether_addr(priv->stations[i].sta.sta.addr,
@@ -313,10 +313,9 @@ static u8 iwl_prep_station(struct iwl_priv *priv, const u8 *addr,
313/** 313/**
314 * iwl_add_station_common - 314 * iwl_add_station_common -
315 */ 315 */
316int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, 316int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
317 bool is_ap, 317 const u8 *addr, bool is_ap,
318 struct ieee80211_sta_ht_cap *ht_info, 318 struct ieee80211_sta_ht_cap *ht_info, u8 *sta_id_r)
319 u8 *sta_id_r)
320{ 319{
321 unsigned long flags_spin; 320 unsigned long flags_spin;
322 int ret = 0; 321 int ret = 0;
@@ -325,7 +324,7 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
325 324
326 *sta_id_r = 0; 325 *sta_id_r = 0;
327 spin_lock_irqsave(&priv->sta_lock, flags_spin); 326 spin_lock_irqsave(&priv->sta_lock, flags_spin);
328 sta_id = iwl_prep_station(priv, addr, is_ap, ht_info); 327 sta_id = iwl_prep_station(priv, ctx, addr, is_ap, ht_info);
329 if (sta_id == IWL_INVALID_STATION) { 328 if (sta_id == IWL_INVALID_STATION) {
330 IWL_ERR(priv, "Unable to prepare station %pM for addition\n", 329 IWL_ERR(priv, "Unable to prepare station %pM for addition\n",
331 addr); 330 addr);
@@ -431,8 +430,8 @@ static struct iwl_link_quality_cmd *iwl_sta_alloc_lq(struct iwl_priv *priv,
431 * 430 *
432 * Function sleeps. 431 * Function sleeps.
433 */ 432 */
434int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs, 433int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
435 u8 *sta_id_r) 434 const u8 *addr, bool init_rs, u8 *sta_id_r)
436{ 435{
437 int ret; 436 int ret;
438 u8 sta_id; 437 u8 sta_id;
@@ -442,7 +441,7 @@ int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs,
442 if (sta_id_r) 441 if (sta_id_r)
443 *sta_id_r = IWL_INVALID_STATION; 442 *sta_id_r = IWL_INVALID_STATION;
444 443
445 ret = iwl_add_station_common(priv, addr, 0, NULL, &sta_id); 444 ret = iwl_add_station_common(priv, ctx, addr, 0, NULL, &sta_id);
446 if (ret) { 445 if (ret) {
447 IWL_ERR(priv, "Unable to add station %pM\n", addr); 446 IWL_ERR(priv, "Unable to add station %pM\n", addr);
448 return ret; 447 return ret;
@@ -833,8 +832,9 @@ int iwl_set_default_wep_key(struct iwl_priv *priv,
833EXPORT_SYMBOL(iwl_set_default_wep_key); 832EXPORT_SYMBOL(iwl_set_default_wep_key);
834 833
835static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv, 834static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
836 struct ieee80211_key_conf *keyconf, 835 struct iwl_rxon_context *ctx,
837 u8 sta_id) 836 struct ieee80211_key_conf *keyconf,
837 u8 sta_id)
838{ 838{
839 unsigned long flags; 839 unsigned long flags;
840 __le16 key_flags = 0; 840 __le16 key_flags = 0;
@@ -851,7 +851,7 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
851 if (keyconf->keylen == WEP_KEY_LEN_128) 851 if (keyconf->keylen == WEP_KEY_LEN_128)
852 key_flags |= STA_KEY_FLG_KEY_SIZE_MSK; 852 key_flags |= STA_KEY_FLG_KEY_SIZE_MSK;
853 853
854 if (sta_id == priv->hw_params.bcast_sta_id) 854 if (sta_id == ctx->bcast_sta_id)
855 key_flags |= STA_KEY_MULTICAST_MSK; 855 key_flags |= STA_KEY_MULTICAST_MSK;
856 856
857 spin_lock_irqsave(&priv->sta_lock, flags); 857 spin_lock_irqsave(&priv->sta_lock, flags);
@@ -887,8 +887,9 @@ static int iwl_set_wep_dynamic_key_info(struct iwl_priv *priv,
887} 887}
888 888
889static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv, 889static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
890 struct ieee80211_key_conf *keyconf, 890 struct iwl_rxon_context *ctx,
891 u8 sta_id) 891 struct ieee80211_key_conf *keyconf,
892 u8 sta_id)
892{ 893{
893 unsigned long flags; 894 unsigned long flags;
894 __le16 key_flags = 0; 895 __le16 key_flags = 0;
@@ -900,7 +901,7 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
900 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); 901 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
901 key_flags &= ~STA_KEY_FLG_INVALID; 902 key_flags &= ~STA_KEY_FLG_INVALID;
902 903
903 if (sta_id == priv->hw_params.bcast_sta_id) 904 if (sta_id == ctx->bcast_sta_id)
904 key_flags |= STA_KEY_MULTICAST_MSK; 905 key_flags |= STA_KEY_MULTICAST_MSK;
905 906
906 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 907 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -936,8 +937,9 @@ static int iwl_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
936} 937}
937 938
938static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv, 939static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
939 struct ieee80211_key_conf *keyconf, 940 struct iwl_rxon_context *ctx,
940 u8 sta_id) 941 struct ieee80211_key_conf *keyconf,
942 u8 sta_id)
941{ 943{
942 unsigned long flags; 944 unsigned long flags;
943 int ret = 0; 945 int ret = 0;
@@ -947,7 +949,7 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
947 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); 949 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
948 key_flags &= ~STA_KEY_FLG_INVALID; 950 key_flags &= ~STA_KEY_FLG_INVALID;
949 951
950 if (sta_id == priv->hw_params.bcast_sta_id) 952 if (sta_id == ctx->bcast_sta_id)
951 key_flags |= STA_KEY_MULTICAST_MSK; 953 key_flags |= STA_KEY_MULTICAST_MSK;
952 954
953 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 955 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -982,8 +984,9 @@ static int iwl_set_tkip_dynamic_key_info(struct iwl_priv *priv,
982} 984}
983 985
984void iwl_update_tkip_key(struct iwl_priv *priv, 986void iwl_update_tkip_key(struct iwl_priv *priv,
985 struct ieee80211_key_conf *keyconf, 987 struct iwl_rxon_context *ctx,
986 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key) 988 struct ieee80211_key_conf *keyconf,
989 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key)
987{ 990{
988 u8 sta_id; 991 u8 sta_id;
989 unsigned long flags; 992 unsigned long flags;
@@ -995,7 +998,7 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
995 return; 998 return;
996 } 999 }
997 1000
998 sta_id = iwl_sta_id_or_broadcast(priv, sta); 1001 sta_id = iwl_sta_id_or_broadcast(priv, ctx, sta);
999 if (sta_id == IWL_INVALID_STATION) 1002 if (sta_id == IWL_INVALID_STATION)
1000 return; 1003 return;
1001 1004
@@ -1080,8 +1083,8 @@ int iwl_remove_dynamic_key(struct iwl_priv *priv,
1080} 1083}
1081EXPORT_SYMBOL(iwl_remove_dynamic_key); 1084EXPORT_SYMBOL(iwl_remove_dynamic_key);
1082 1085
1083int iwl_set_dynamic_key(struct iwl_priv *priv, 1086int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
1084 struct ieee80211_key_conf *keyconf, u8 sta_id) 1087 struct ieee80211_key_conf *keyconf, u8 sta_id)
1085{ 1088{
1086 int ret; 1089 int ret;
1087 1090
@@ -1092,14 +1095,14 @@ int iwl_set_dynamic_key(struct iwl_priv *priv,
1092 1095
1093 switch (keyconf->cipher) { 1096 switch (keyconf->cipher) {
1094 case WLAN_CIPHER_SUITE_CCMP: 1097 case WLAN_CIPHER_SUITE_CCMP:
1095 ret = iwl_set_ccmp_dynamic_key_info(priv, keyconf, sta_id); 1098 ret = iwl_set_ccmp_dynamic_key_info(priv, ctx, keyconf, sta_id);
1096 break; 1099 break;
1097 case WLAN_CIPHER_SUITE_TKIP: 1100 case WLAN_CIPHER_SUITE_TKIP:
1098 ret = iwl_set_tkip_dynamic_key_info(priv, keyconf, sta_id); 1101 ret = iwl_set_tkip_dynamic_key_info(priv, ctx, keyconf, sta_id);
1099 break; 1102 break;
1100 case WLAN_CIPHER_SUITE_WEP40: 1103 case WLAN_CIPHER_SUITE_WEP40:
1101 case WLAN_CIPHER_SUITE_WEP104: 1104 case WLAN_CIPHER_SUITE_WEP104:
1102 ret = iwl_set_wep_dynamic_key_info(priv, keyconf, sta_id); 1105 ret = iwl_set_wep_dynamic_key_info(priv, ctx, keyconf, sta_id);
1103 break; 1106 break;
1104 default: 1107 default:
1105 IWL_ERR(priv, 1108 IWL_ERR(priv,
@@ -1229,14 +1232,15 @@ EXPORT_SYMBOL(iwl_send_lq_cmd);
1229 * and marks it driver active, so that it will be restored to the 1232 * and marks it driver active, so that it will be restored to the
1230 * device at the next best time. 1233 * device at the next best time.
1231 */ 1234 */
1232int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq) 1235int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
1236 bool init_lq)
1233{ 1237{
1234 struct iwl_link_quality_cmd *link_cmd; 1238 struct iwl_link_quality_cmd *link_cmd;
1235 unsigned long flags; 1239 unsigned long flags;
1236 u8 sta_id; 1240 u8 sta_id;
1237 1241
1238 spin_lock_irqsave(&priv->sta_lock, flags); 1242 spin_lock_irqsave(&priv->sta_lock, flags);
1239 sta_id = iwl_prep_station(priv, iwl_bcast_addr, false, NULL); 1243 sta_id = iwl_prep_station(priv, ctx, iwl_bcast_addr, false, NULL);
1240 if (sta_id == IWL_INVALID_STATION) { 1244 if (sta_id == IWL_INVALID_STATION) {
1241 IWL_ERR(priv, "Unable to prepare broadcast station\n"); 1245 IWL_ERR(priv, "Unable to prepare broadcast station\n");
1242 spin_unlock_irqrestore(&priv->sta_lock, flags); 1246 spin_unlock_irqrestore(&priv->sta_lock, flags);
@@ -1271,11 +1275,12 @@ EXPORT_SYMBOL_GPL(iwl_alloc_bcast_station);
1271 * Only used by iwlagn. Placed here to have all bcast station management 1275 * Only used by iwlagn. Placed here to have all bcast station management
1272 * code together. 1276 * code together.
1273 */ 1277 */
1274int iwl_update_bcast_station(struct iwl_priv *priv) 1278static int iwl_update_bcast_station(struct iwl_priv *priv,
1279 struct iwl_rxon_context *ctx)
1275{ 1280{
1276 unsigned long flags; 1281 unsigned long flags;
1277 struct iwl_link_quality_cmd *link_cmd; 1282 struct iwl_link_quality_cmd *link_cmd;
1278 u8 sta_id = priv->hw_params.bcast_sta_id; 1283 u8 sta_id = ctx->bcast_sta_id;
1279 1284
1280 link_cmd = iwl_sta_alloc_lq(priv, sta_id); 1285 link_cmd = iwl_sta_alloc_lq(priv, sta_id);
1281 if (!link_cmd) { 1286 if (!link_cmd) {
@@ -1293,9 +1298,23 @@ int iwl_update_bcast_station(struct iwl_priv *priv)
1293 1298
1294 return 0; 1299 return 0;
1295} 1300}
1296EXPORT_SYMBOL_GPL(iwl_update_bcast_station);
1297 1301
1298void iwl_dealloc_bcast_station(struct iwl_priv *priv) 1302int iwl_update_bcast_stations(struct iwl_priv *priv)
1303{
1304 struct iwl_rxon_context *ctx;
1305 int ret = 0;
1306
1307 for_each_context(priv, ctx) {
1308 ret = iwl_update_bcast_station(priv, ctx);
1309 if (ret)
1310 break;
1311 }
1312
1313 return ret;
1314}
1315EXPORT_SYMBOL_GPL(iwl_update_bcast_stations);
1316
1317void iwl_dealloc_bcast_stations(struct iwl_priv *priv)
1299{ 1318{
1300 unsigned long flags; 1319 unsigned long flags;
1301 int i; 1320 int i;
@@ -1313,7 +1332,7 @@ void iwl_dealloc_bcast_station(struct iwl_priv *priv)
1313 } 1332 }
1314 spin_unlock_irqrestore(&priv->sta_lock, flags); 1333 spin_unlock_irqrestore(&priv->sta_lock, flags);
1315} 1334}
1316EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_station); 1335EXPORT_SYMBOL_GPL(iwl_dealloc_bcast_stations);
1317 1336
1318/** 1337/**
1319 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table 1338 * iwl_sta_tx_modify_enable_tid - Enable Tx for this TID in station table
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.h b/drivers/net/wireless/iwlwifi/iwl-sta.h
index d38a350ba0b..8a978c6e105 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.h
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.h
@@ -48,28 +48,29 @@ int iwl_remove_default_wep_key(struct iwl_priv *priv,
48int iwl_set_default_wep_key(struct iwl_priv *priv, 48int iwl_set_default_wep_key(struct iwl_priv *priv,
49 struct ieee80211_key_conf *key); 49 struct ieee80211_key_conf *key);
50int iwl_restore_default_wep_keys(struct iwl_priv *priv); 50int iwl_restore_default_wep_keys(struct iwl_priv *priv);
51int iwl_set_dynamic_key(struct iwl_priv *priv, 51int iwl_set_dynamic_key(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
52 struct ieee80211_key_conf *key, u8 sta_id); 52 struct ieee80211_key_conf *key, u8 sta_id);
53int iwl_remove_dynamic_key(struct iwl_priv *priv, 53int iwl_remove_dynamic_key(struct iwl_priv *priv,
54 struct ieee80211_key_conf *key, u8 sta_id); 54 struct ieee80211_key_conf *key, u8 sta_id);
55void iwl_update_tkip_key(struct iwl_priv *priv, 55void iwl_update_tkip_key(struct iwl_priv *priv,
56 struct ieee80211_key_conf *keyconf, 56 struct iwl_rxon_context *ctx,
57 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key); 57 struct ieee80211_key_conf *keyconf,
58 struct ieee80211_sta *sta, u32 iv32, u16 *phase1key);
58 59
59void iwl_restore_stations(struct iwl_priv *priv); 60void iwl_restore_stations(struct iwl_priv *priv);
60void iwl_clear_ucode_stations(struct iwl_priv *priv); 61void iwl_clear_ucode_stations(struct iwl_priv *priv);
61int iwl_alloc_bcast_station(struct iwl_priv *priv, bool init_lq); 62int iwl_alloc_bcast_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
62void iwl_dealloc_bcast_station(struct iwl_priv *priv); 63 bool init_lq);
63int iwl_update_bcast_station(struct iwl_priv *priv); 64void iwl_dealloc_bcast_stations(struct iwl_priv *priv);
65int iwl_update_bcast_stations(struct iwl_priv *priv);
64int iwl_get_free_ucode_key_index(struct iwl_priv *priv); 66int iwl_get_free_ucode_key_index(struct iwl_priv *priv);
65int iwl_send_add_sta(struct iwl_priv *priv, 67int iwl_send_add_sta(struct iwl_priv *priv,
66 struct iwl_addsta_cmd *sta, u8 flags); 68 struct iwl_addsta_cmd *sta, u8 flags);
67int iwl_add_bssid_station(struct iwl_priv *priv, const u8 *addr, bool init_rs, 69int iwl_add_bssid_station(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
68 u8 *sta_id_r); 70 const u8 *addr, bool init_rs, u8 *sta_id_r);
69int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr, 71int iwl_add_station_common(struct iwl_priv *priv, struct iwl_rxon_context *ctx,
70 bool is_ap, 72 const u8 *addr, bool is_ap,
71 struct ieee80211_sta_ht_cap *ht_info, 73 struct ieee80211_sta_ht_cap *ht_info, u8 *sta_id_r);
72 u8 *sta_id_r);
73int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, 74int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
74 const u8 *addr); 75 const u8 *addr);
75int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 76int iwl_mac_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
@@ -123,6 +124,7 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
123/** 124/**
124 * iwl_sta_id_or_broadcast - return sta_id or broadcast sta 125 * iwl_sta_id_or_broadcast - return sta_id or broadcast sta
125 * @priv: iwl priv 126 * @priv: iwl priv
127 * @context: the current context
126 * @sta: mac80211 station 128 * @sta: mac80211 station
127 * 129 *
128 * In certain circumstances mac80211 passes a station pointer 130 * In certain circumstances mac80211 passes a station pointer
@@ -131,12 +133,13 @@ static inline int iwl_sta_id(struct ieee80211_sta *sta)
131 * inline wraps that pattern. 133 * inline wraps that pattern.
132 */ 134 */
133static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv, 135static inline int iwl_sta_id_or_broadcast(struct iwl_priv *priv,
136 struct iwl_rxon_context *context,
134 struct ieee80211_sta *sta) 137 struct ieee80211_sta *sta)
135{ 138{
136 int sta_id; 139 int sta_id;
137 140
138 if (!sta) 141 if (!sta)
139 return priv->hw_params.bcast_sta_id; 142 return context->bcast_sta_id;
140 143
141 sta_id = iwl_sta_id(sta); 144 sta_id = iwl_sta_id(sta);
142 145
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 02e0a9bbad1..8b076326414 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -144,7 +144,7 @@ static int iwl3945_set_ccmp_dynamic_key_info(struct iwl_priv *priv,
144 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK); 144 key_flags |= (STA_KEY_FLG_CCMP | STA_KEY_FLG_MAP_KEY_MSK);
145 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS); 145 key_flags |= cpu_to_le16(keyconf->keyidx << STA_KEY_FLG_KEYID_POS);
146 146
147 if (sta_id == priv->hw_params.bcast_sta_id) 147 if (sta_id == priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id)
148 key_flags |= STA_KEY_MULTICAST_MSK; 148 key_flags |= STA_KEY_MULTICAST_MSK;
149 149
150 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; 150 keyconf->flags |= IEEE80211_KEY_FLAG_GENERATE_IV;
@@ -512,7 +512,9 @@ static int iwl3945_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
512 hdr_len = ieee80211_hdrlen(fc); 512 hdr_len = ieee80211_hdrlen(fc);
513 513
514 /* Find index into station table for destination station */ 514 /* Find index into station table for destination station */
515 sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); 515 sta_id = iwl_sta_id_or_broadcast(
516 priv, &priv->contexts[IWL_RXON_CTX_BSS],
517 info->control.sta);
516 if (sta_id == IWL_INVALID_STATION) { 518 if (sta_id == IWL_INVALID_STATION) {
517 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 519 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
518 hdr->addr1); 520 hdr->addr1);
@@ -2580,7 +2582,7 @@ static void __iwl3945_down(struct iwl_priv *priv)
2580 2582
2581 /* Station information will now be cleared in device */ 2583 /* Station information will now be cleared in device */
2582 iwl_clear_ucode_stations(priv); 2584 iwl_clear_ucode_stations(priv);
2583 iwl_dealloc_bcast_station(priv); 2585 iwl_dealloc_bcast_stations(priv);
2584 iwl_clear_driver_stations(priv); 2586 iwl_clear_driver_stations(priv);
2585 2587
2586 /* Unblock any waiting calls */ 2588 /* Unblock any waiting calls */
@@ -2662,7 +2664,8 @@ static int __iwl3945_up(struct iwl_priv *priv)
2662{ 2664{
2663 int rc, i; 2665 int rc, i;
2664 2666
2665 rc = iwl_alloc_bcast_station(priv, false); 2667 rc = iwl_alloc_bcast_station(priv, &priv->contexts[IWL_RXON_CTX_BSS],
2668 false);
2666 if (rc) 2669 if (rc)
2667 return rc; 2670 return rc;
2668 2671
@@ -2946,7 +2949,7 @@ void iwl3945_request_scan(struct iwl_priv *priv, struct ieee80211_vif *vif)
2946 /* We don't build a direct scan probe request; the uCode will do 2949 /* We don't build a direct scan probe request; the uCode will do
2947 * that based on the direct_mask added to each channel entry */ 2950 * that based on the direct_mask added to each channel entry */
2948 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK; 2951 scan->tx_cmd.tx_flags = TX_CMD_FLG_SEQ_CTL_MSK;
2949 scan->tx_cmd.sta_id = priv->hw_params.bcast_sta_id; 2952 scan->tx_cmd.sta_id = priv->contexts[IWL_RXON_CTX_BSS].bcast_sta_id;
2950 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE; 2953 scan->tx_cmd.stop_time.life_time = TX_CMD_LIFE_TIME_INFINITE;
2951 2954
2952 /* flags + rate selection */ 2955 /* flags + rate selection */
@@ -3330,7 +3333,8 @@ static int iwl3945_mac_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd,
3330 static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS); 3333 static_key = !iwl_is_associated(priv, IWL_RXON_CTX_BSS);
3331 3334
3332 if (!static_key) { 3335 if (!static_key) {
3333 sta_id = iwl_sta_id_or_broadcast(priv, sta); 3336 sta_id = iwl_sta_id_or_broadcast(
3337 priv, &priv->contexts[IWL_RXON_CTX_BSS], sta);
3334 if (sta_id == IWL_INVALID_STATION) 3338 if (sta_id == IWL_INVALID_STATION)
3335 return -EINVAL; 3339 return -EINVAL;
3336 } 3340 }
@@ -3381,8 +3385,8 @@ static int iwl3945_mac_sta_add(struct ieee80211_hw *hw,
3381 sta_priv->common.sta_id = IWL_INVALID_STATION; 3385 sta_priv->common.sta_id = IWL_INVALID_STATION;
3382 3386
3383 3387
3384 ret = iwl_add_station_common(priv, sta->addr, is_ap, &sta->ht_cap, 3388 ret = iwl_add_station_common(priv, &priv->contexts[IWL_RXON_CTX_BSS],
3385 &sta_id); 3389 sta->addr, is_ap, &sta->ht_cap, &sta_id);
3386 if (ret) { 3390 if (ret) {
3387 IWL_ERR(priv, "Unable to add station %pM (%d)\n", 3391 IWL_ERR(priv, "Unable to add station %pM (%d)\n",
3388 sta->addr, ret); 3392 sta->addr, ret);