aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-sta.c
diff options
context:
space:
mode:
authorJohn W. Linville <linville@tuxdriver.com>2010-06-02 15:36:51 -0400
committerJohn W. Linville <linville@tuxdriver.com>2010-06-02 15:36:51 -0400
commit1c62c72b1a3c4478fb9069503d20c41b1f385ca1 (patch)
tree939634bedbabfcd389ab7ad96ab7e161e25b2061 /drivers/net/wireless/iwlwifi/iwl-sta.c
parentda1fdb02d9200ff28b6f3a380d21930335fe5429 (diff)
parent9f6e1bafac4f3c58c8a670496adcc4d313d3c7f7 (diff)
Merge branch 'wireless-next-2.6' of git://git.kernel.org/pub/scm/linux/kernel/git/iwlwifi/iwlwifi-2.6
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-sta.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c72
1 files changed, 36 insertions, 36 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 83a26361a9b5..c7127132c298 100644
--- a/drivers/net/wireless/iwlwifi/iwl-sta.c
+++ b/drivers/net/wireless/iwlwifi/iwl-sta.c
@@ -311,10 +311,10 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
311 struct ieee80211_sta_ht_cap *ht_info, 311 struct ieee80211_sta_ht_cap *ht_info,
312 u8 *sta_id_r) 312 u8 *sta_id_r)
313{ 313{
314 struct iwl_station_entry *station;
315 unsigned long flags_spin; 314 unsigned long flags_spin;
316 int ret = 0; 315 int ret = 0;
317 u8 sta_id; 316 u8 sta_id;
317 struct iwl_addsta_cmd sta_cmd;
318 318
319 *sta_id_r = 0; 319 *sta_id_r = 0;
320 spin_lock_irqsave(&priv->sta_lock, flags_spin); 320 spin_lock_irqsave(&priv->sta_lock, flags_spin);
@@ -347,14 +347,15 @@ int iwl_add_station_common(struct iwl_priv *priv, const u8 *addr,
347 } 347 }
348 348
349 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS; 349 priv->stations[sta_id].used |= IWL_STA_UCODE_INPROGRESS;
350 station = &priv->stations[sta_id]; 350 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
351 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 351 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
352 352
353 /* Add station to device's station table */ 353 /* Add station to device's station table */
354 ret = iwl_send_add_sta(priv, &station->sta, CMD_SYNC); 354 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
355 if (ret) { 355 if (ret) {
356 IWL_ERR(priv, "Adding station %pM failed.\n", station->sta.sta.addr);
357 spin_lock_irqsave(&priv->sta_lock, flags_spin); 356 spin_lock_irqsave(&priv->sta_lock, flags_spin);
357 IWL_ERR(priv, "Adding station %pM failed.\n",
358 priv->stations[sta_id].sta.sta.addr);
358 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE; 359 priv->stations[sta_id].used &= ~IWL_STA_DRIVER_ACTIVE;
359 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS; 360 priv->stations[sta_id].used &= ~IWL_STA_UCODE_INPROGRESS;
360 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 361 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
@@ -488,7 +489,7 @@ static void iwl_sta_ucode_deactivate(struct iwl_priv *priv, u8 sta_id)
488} 489}
489 490
490static int iwl_send_remove_station(struct iwl_priv *priv, 491static int iwl_send_remove_station(struct iwl_priv *priv,
491 struct iwl_station_entry *station) 492 const u8 *addr, int sta_id)
492{ 493{
493 struct iwl_rx_packet *pkt; 494 struct iwl_rx_packet *pkt;
494 int ret; 495 int ret;
@@ -505,7 +506,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
505 506
506 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd)); 507 memset(&rm_sta_cmd, 0, sizeof(rm_sta_cmd));
507 rm_sta_cmd.num_sta = 1; 508 rm_sta_cmd.num_sta = 1;
508 memcpy(&rm_sta_cmd.addr, &station->sta.sta.addr , ETH_ALEN); 509 memcpy(&rm_sta_cmd.addr, addr, ETH_ALEN);
509 510
510 cmd.flags |= CMD_WANT_SKB; 511 cmd.flags |= CMD_WANT_SKB;
511 512
@@ -525,7 +526,7 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
525 switch (pkt->u.rem_sta.status) { 526 switch (pkt->u.rem_sta.status) {
526 case REM_STA_SUCCESS_MSK: 527 case REM_STA_SUCCESS_MSK:
527 spin_lock_irqsave(&priv->sta_lock, flags_spin); 528 spin_lock_irqsave(&priv->sta_lock, flags_spin);
528 iwl_sta_ucode_deactivate(priv, station->sta.sta.sta_id); 529 iwl_sta_ucode_deactivate(priv, sta_id);
529 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 530 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
530 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n"); 531 IWL_DEBUG_ASSOC(priv, "REPLY_REMOVE_STA PASSED\n");
531 break; 532 break;
@@ -546,7 +547,6 @@ static int iwl_send_remove_station(struct iwl_priv *priv,
546int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id, 547int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
547 const u8 *addr) 548 const u8 *addr)
548{ 549{
549 struct iwl_station_entry *station;
550 unsigned long flags; 550 unsigned long flags;
551 551
552 if (!iwl_is_ready(priv)) { 552 if (!iwl_is_ready(priv)) {
@@ -592,10 +592,9 @@ int iwl_remove_station(struct iwl_priv *priv, const u8 sta_id,
592 592
593 BUG_ON(priv->num_stations < 0); 593 BUG_ON(priv->num_stations < 0);
594 594
595 station = &priv->stations[sta_id];
596 spin_unlock_irqrestore(&priv->sta_lock, flags); 595 spin_unlock_irqrestore(&priv->sta_lock, flags);
597 596
598 return iwl_send_remove_station(priv, station); 597 return iwl_send_remove_station(priv, addr, sta_id);
599out_err: 598out_err:
600 spin_unlock_irqrestore(&priv->sta_lock, flags); 599 spin_unlock_irqrestore(&priv->sta_lock, flags);
601 return -EINVAL; 600 return -EINVAL;
@@ -643,11 +642,13 @@ EXPORT_SYMBOL(iwl_clear_ucode_stations);
643 */ 642 */
644void iwl_restore_stations(struct iwl_priv *priv) 643void iwl_restore_stations(struct iwl_priv *priv)
645{ 644{
646 struct iwl_station_entry *station; 645 struct iwl_addsta_cmd sta_cmd;
646 struct iwl_link_quality_cmd lq;
647 unsigned long flags_spin; 647 unsigned long flags_spin;
648 int i; 648 int i;
649 bool found = false; 649 bool found = false;
650 int ret; 650 int ret;
651 bool send_lq;
651 652
652 if (!iwl_is_ready(priv)) { 653 if (!iwl_is_ready(priv)) {
653 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n"); 654 IWL_DEBUG_INFO(priv, "Not ready yet, not restoring any stations.\n");
@@ -669,13 +670,20 @@ void iwl_restore_stations(struct iwl_priv *priv)
669 670
670 for (i = 0; i < priv->hw_params.max_stations; i++) { 671 for (i = 0; i < priv->hw_params.max_stations; i++) {
671 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) { 672 if ((priv->stations[i].used & IWL_STA_UCODE_INPROGRESS)) {
673 memcpy(&sta_cmd, &priv->stations[i].sta,
674 sizeof(struct iwl_addsta_cmd));
675 send_lq = false;
676 if (priv->stations[i].lq) {
677 memcpy(&lq, priv->stations[i].lq,
678 sizeof(struct iwl_link_quality_cmd));
679 send_lq = true;
680 }
672 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 681 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
673 station = &priv->stations[i]; 682 ret = iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
674 ret = iwl_send_add_sta(priv, &priv->stations[i].sta, CMD_SYNC);
675 if (ret) { 683 if (ret) {
676 IWL_ERR(priv, "Adding station %pM failed.\n",
677 station->sta.sta.addr);
678 spin_lock_irqsave(&priv->sta_lock, flags_spin); 684 spin_lock_irqsave(&priv->sta_lock, flags_spin);
685 IWL_ERR(priv, "Adding station %pM failed.\n",
686 priv->stations[i].sta.sta.addr);
679 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE; 687 priv->stations[i].used &= ~IWL_STA_DRIVER_ACTIVE;
680 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; 688 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
681 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 689 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
@@ -684,8 +692,8 @@ void iwl_restore_stations(struct iwl_priv *priv)
684 * Rate scaling has already been initialized, send 692 * Rate scaling has already been initialized, send
685 * current LQ command 693 * current LQ command
686 */ 694 */
687 if (station->lq) 695 if (send_lq)
688 iwl_send_lq_cmd(priv, station->lq, CMD_SYNC, true); 696 iwl_send_lq_cmd(priv, &lq, CMD_SYNC, true);
689 spin_lock_irqsave(&priv->sta_lock, flags_spin); 697 spin_lock_irqsave(&priv->sta_lock, flags_spin);
690 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS; 698 priv->stations[i].used &= ~IWL_STA_UCODE_INPROGRESS;
691 } 699 }
@@ -972,24 +980,16 @@ void iwl_update_tkip_key(struct iwl_priv *priv,
972 unsigned long flags; 980 unsigned long flags;
973 int i; 981 int i;
974 982
975 if (sta) {
976 sta_id = iwl_sta_id(sta);
977
978 if (sta_id == IWL_INVALID_STATION) {
979 IWL_DEBUG_MAC80211(priv, "leave - %pM not initialised.\n",
980 sta->addr);
981 return;
982 }
983 } else
984 sta_id = priv->hw_params.bcast_sta_id;
985
986
987 if (iwl_scan_cancel(priv)) { 983 if (iwl_scan_cancel(priv)) {
988 /* cancel scan failed, just live w/ bad key and rely 984 /* cancel scan failed, just live w/ bad key and rely
989 briefly on SW decryption */ 985 briefly on SW decryption */
990 return; 986 return;
991 } 987 }
992 988
989 sta_id = iwl_sta_id_or_broadcast(priv, sta);
990 if (sta_id == IWL_INVALID_STATION)
991 return;
992
993 spin_lock_irqsave(&priv->sta_lock, flags); 993 spin_lock_irqsave(&priv->sta_lock, flags);
994 994
995 priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32; 995 priv->stations[sta_id].sta.key.tkip_rx_tsc_byte2 = (u8) iv32;
@@ -1277,9 +1277,8 @@ void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
1277 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX; 1277 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_TID_DISABLE_TX;
1278 priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid)); 1278 priv->stations[sta_id].sta.tid_disable_tx &= cpu_to_le16(~(1 << tid));
1279 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1279 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1280 spin_unlock_irqrestore(&priv->sta_lock, flags);
1281
1282 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC); 1280 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1281 spin_unlock_irqrestore(&priv->sta_lock, flags);
1283} 1282}
1284EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); 1283EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
1285 1284
@@ -1310,7 +1309,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1310 int tid) 1309 int tid)
1311{ 1310{
1312 unsigned long flags; 1311 unsigned long flags;
1313 int sta_id; 1312 int sta_id, ret;
1314 1313
1315 sta_id = iwl_sta_id(sta); 1314 sta_id = iwl_sta_id(sta);
1316 if (sta_id == IWL_INVALID_STATION) { 1315 if (sta_id == IWL_INVALID_STATION) {
@@ -1323,10 +1322,11 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1323 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK; 1322 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_DELBA_TID_MSK;
1324 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; 1323 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
1325 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1324 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1325 ret = iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1326 spin_unlock_irqrestore(&priv->sta_lock, flags); 1326 spin_unlock_irqrestore(&priv->sta_lock, flags);
1327 1327
1328 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 1328 return ret;
1329 CMD_ASYNC); 1329
1330} 1330}
1331EXPORT_SYMBOL(iwl_sta_rx_agg_stop); 1331EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
1332 1332
@@ -1340,9 +1340,9 @@ void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1340 priv->stations[sta_id].sta.sta.modify_mask = 0; 1340 priv->stations[sta_id].sta.sta.modify_mask = 0;
1341 priv->stations[sta_id].sta.sleep_tx_count = 0; 1341 priv->stations[sta_id].sta.sleep_tx_count = 0;
1342 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1342 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1343 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1343 spin_unlock_irqrestore(&priv->sta_lock, flags); 1344 spin_unlock_irqrestore(&priv->sta_lock, flags);
1344 1345
1345 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1346} 1346}
1347EXPORT_SYMBOL(iwl_sta_modify_ps_wake); 1347EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
1348 1348
@@ -1357,9 +1357,9 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1357 STA_MODIFY_SLEEP_TX_COUNT_MSK; 1357 STA_MODIFY_SLEEP_TX_COUNT_MSK;
1358 priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt); 1358 priv->stations[sta_id].sta.sleep_tx_count = cpu_to_le16(cnt);
1359 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1359 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1360 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1360 spin_unlock_irqrestore(&priv->sta_lock, flags); 1361 spin_unlock_irqrestore(&priv->sta_lock, flags);
1361 1362
1362 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1363} 1363}
1364EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); 1364EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
1365 1365