aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-3945.c9
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-4965.c5
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c7
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c41
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-sta.c56
-rw-r--r--drivers/net/wireless/iwlwifi/iwl3945-base.c5
7 files changed, 85 insertions, 42 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-3945.c b/drivers/net/wireless/iwlwifi/iwl-3945.c
index 0eb0faa9d3cf..5ffbce8f4563 100644
--- a/drivers/net/wireless/iwlwifi/iwl-3945.c
+++ b/drivers/net/wireless/iwlwifi/iwl-3945.c
@@ -946,8 +946,7 @@ void iwl3945_hw_build_tx_cmd_rate(struct iwl_priv *priv,
946 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]); 946 tx_cmd->supp_rates[1], tx_cmd->supp_rates[0]);
947} 947}
948 948
949static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, 949static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id, u16 tx_rate)
950 u16 tx_rate, u8 flags)
951{ 950{
952 unsigned long flags_spin; 951 unsigned long flags_spin;
953 struct iwl_station_entry *station; 952 struct iwl_station_entry *station;
@@ -961,10 +960,9 @@ static u8 iwl3945_sync_sta(struct iwl_priv *priv, int sta_id,
961 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK; 960 station->sta.sta.modify_mask = STA_MODIFY_TX_RATE_MSK;
962 station->sta.rate_n_flags = cpu_to_le16(tx_rate); 961 station->sta.rate_n_flags = cpu_to_le16(tx_rate);
963 station->sta.mode = STA_CONTROL_MODIFY_MSK; 962 station->sta.mode = STA_CONTROL_MODIFY_MSK;
964 963 iwl_send_add_sta(priv, &station->sta, CMD_ASYNC);
965 spin_unlock_irqrestore(&priv->sta_lock, flags_spin); 964 spin_unlock_irqrestore(&priv->sta_lock, flags_spin);
966 965
967 iwl_send_add_sta(priv, &station->sta, flags);
968 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n", 966 IWL_DEBUG_RATE(priv, "SCALE sync station %d to rate %d\n",
969 sta_id, tx_rate); 967 sta_id, tx_rate);
970 return sta_id; 968 return sta_id;
@@ -2472,8 +2470,7 @@ static int iwl3945_manage_ibss_station(struct iwl_priv *priv,
2472 2470
2473 iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id, 2471 iwl3945_sync_sta(priv, vif_priv->ibss_bssid_sta_id,
2474 (priv->band == IEEE80211_BAND_5GHZ) ? 2472 (priv->band == IEEE80211_BAND_5GHZ) ?
2475 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP, 2473 IWL_RATE_6M_PLCP : IWL_RATE_1M_PLCP);
2476 CMD_ASYNC);
2477 iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id); 2474 iwl3945_rate_scale_init(priv->hw, vif_priv->ibss_bssid_sta_id);
2478 2475
2479 return 0; 2476 return 0;
diff --git a/drivers/net/wireless/iwlwifi/iwl-4965.c b/drivers/net/wireless/iwlwifi/iwl-4965.c
index 03b066c7aa3c..ad4d7d11c3b8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-4965.c
+++ b/drivers/net/wireless/iwlwifi/iwl-4965.c
@@ -2026,6 +2026,7 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2026 int sta_id; 2026 int sta_id;
2027 int freed; 2027 int freed;
2028 u8 *qc = NULL; 2028 u8 *qc = NULL;
2029 unsigned long flags;
2029 2030
2030 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 2031 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
2031 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " 2032 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
@@ -2050,10 +2051,10 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2050 return; 2051 return;
2051 } 2052 }
2052 2053
2054 spin_lock_irqsave(&priv->sta_lock, flags);
2053 if (txq->sched_retry) { 2055 if (txq->sched_retry) {
2054 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp); 2056 const u32 scd_ssn = iwl4965_get_scd_ssn(tx_resp);
2055 struct iwl_ht_agg *agg = NULL; 2057 struct iwl_ht_agg *agg = NULL;
2056
2057 WARN_ON(!qc); 2058 WARN_ON(!qc);
2058 2059
2059 agg = &priv->stations[sta_id].tid[tid].agg; 2060 agg = &priv->stations[sta_id].tid[tid].agg;
@@ -2110,6 +2111,8 @@ static void iwl4965_rx_reply_tx(struct iwl_priv *priv,
2110 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); 2111 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
2111 2112
2112 iwl_check_abort_status(priv, tx_resp->frame_count, status); 2113 iwl_check_abort_status(priv, tx_resp->frame_count, status);
2114
2115 spin_unlock_irqrestore(&priv->sta_lock, flags);
2113} 2116}
2114 2117
2115static int iwl4965_calc_rssi(struct iwl_priv *priv, 2118static int iwl4965_calc_rssi(struct iwl_priv *priv,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
index 5f07bc2e14e9..4857b5f62481 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c
@@ -184,6 +184,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
184 int tid; 184 int tid;
185 int sta_id; 185 int sta_id;
186 int freed; 186 int freed;
187 unsigned long flags;
187 188
188 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) { 189 if ((index >= txq->q.n_bd) || (iwl_queue_used(&txq->q, index) == 0)) {
189 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d " 190 IWL_ERR(priv, "Read index for DMA queue txq_id (%d) index %d "
@@ -199,9 +200,10 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
199 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS; 200 tid = (tx_resp->ra_tid & IWL50_TX_RES_TID_MSK) >> IWL50_TX_RES_TID_POS;
200 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS; 201 sta_id = (tx_resp->ra_tid & IWL50_TX_RES_RA_MSK) >> IWL50_TX_RES_RA_POS;
201 202
203 spin_lock_irqsave(&priv->sta_lock, flags);
202 if (txq->sched_retry) { 204 if (txq->sched_retry) {
203 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp); 205 const u32 scd_ssn = iwlagn_get_scd_ssn(tx_resp);
204 struct iwl_ht_agg *agg = NULL; 206 struct iwl_ht_agg *agg;
205 207
206 agg = &priv->stations[sta_id].tid[tid].agg; 208 agg = &priv->stations[sta_id].tid[tid].agg;
207 209
@@ -256,6 +258,7 @@ static void iwlagn_rx_reply_tx(struct iwl_priv *priv,
256 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id); 258 iwlagn_txq_check_empty(priv, sta_id, tid, txq_id);
257 259
258 iwl_check_abort_status(priv, tx_resp->frame_count, status); 260 iwl_check_abort_status(priv, tx_resp->frame_count, status);
261 spin_unlock_irqrestore(&priv->sta_lock, flags);
259} 262}
260 263
261void iwlagn_rx_handler_setup(struct iwl_priv *priv) 264void iwlagn_rx_handler_setup(struct iwl_priv *priv)
@@ -1533,6 +1536,8 @@ int iwlagn_manage_ibss_station(struct iwl_priv *priv,
1533void iwl_free_tfds_in_queue(struct iwl_priv *priv, 1536void iwl_free_tfds_in_queue(struct iwl_priv *priv,
1534 int sta_id, int tid, int freed) 1537 int sta_id, int tid, int freed)
1535{ 1538{
1539 WARN_ON(!spin_is_locked(&priv->sta_lock));
1540
1536 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) 1541 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed)
1537 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 1542 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed;
1538 else { 1543 else {
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 18b15466fce1..52bec1040467 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -595,11 +595,17 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
595 } 595 }
596 596
597 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); 597 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb));
598
599 /* irqs already disabled/saved above when locking priv->lock */
600 spin_lock(&priv->sta_lock);
601
598 if (ieee80211_is_data_qos(fc)) { 602 if (ieee80211_is_data_qos(fc)) {
599 qc = ieee80211_get_qos_ctl(hdr); 603 qc = ieee80211_get_qos_ctl(hdr);
600 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 604 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
601 if (unlikely(tid >= MAX_TID_COUNT)) 605 if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) {
606 spin_unlock(&priv->sta_lock);
602 goto drop_unlock; 607 goto drop_unlock;
608 }
603 seq_number = priv->stations[sta_id].tid[tid].seq_number; 609 seq_number = priv->stations[sta_id].tid[tid].seq_number;
604 seq_number &= IEEE80211_SCTL_SEQ; 610 seq_number &= IEEE80211_SCTL_SEQ;
605 hdr->seq_ctrl = hdr->seq_ctrl & 611 hdr->seq_ctrl = hdr->seq_ctrl &
@@ -617,11 +623,18 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
617 swq_id = txq->swq_id; 623 swq_id = txq->swq_id;
618 q = &txq->q; 624 q = &txq->q;
619 625
620 if (unlikely(iwl_queue_space(q) < q->high_mark)) 626 if (unlikely(iwl_queue_space(q) < q->high_mark)) {
627 spin_unlock(&priv->sta_lock);
621 goto drop_unlock; 628 goto drop_unlock;
629 }
622 630
623 if (ieee80211_is_data_qos(fc)) 631 if (ieee80211_is_data_qos(fc)) {
624 priv->stations[sta_id].tid[tid].tfds_in_queue++; 632 priv->stations[sta_id].tid[tid].tfds_in_queue++;
633 if (!ieee80211_has_morefrags(fc))
634 priv->stations[sta_id].tid[tid].seq_number = seq_number;
635 }
636
637 spin_unlock(&priv->sta_lock);
625 638
626 /* Set up driver data for this TFD */ 639 /* Set up driver data for this TFD */
627 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); 640 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
@@ -700,8 +713,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
700 713
701 if (!ieee80211_has_morefrags(hdr->frame_control)) { 714 if (!ieee80211_has_morefrags(hdr->frame_control)) {
702 txq->need_update = 1; 715 txq->need_update = 1;
703 if (qc)
704 priv->stations[sta_id].tid[tid].seq_number = seq_number;
705 } else { 716 } else {
706 wait_write_ptr = 1; 717 wait_write_ptr = 1;
707 txq->need_update = 0; 718 txq->need_update = 0;
@@ -1006,6 +1017,8 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
1006 if (ret) 1017 if (ret)
1007 return ret; 1018 return ret;
1008 1019
1020 spin_lock_irqsave(&priv->sta_lock, flags);
1021 tid_data = &priv->stations[sta_id].tid[tid];
1009 if (tid_data->tfds_in_queue == 0) { 1022 if (tid_data->tfds_in_queue == 0) {
1010 IWL_DEBUG_HT(priv, "HW queue is empty\n"); 1023 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1011 tid_data->agg.state = IWL_AGG_ON; 1024 tid_data->agg.state = IWL_AGG_ON;
@@ -1015,6 +1028,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
1015 tid_data->tfds_in_queue); 1028 tid_data->tfds_in_queue);
1016 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA; 1029 tid_data->agg.state = IWL_EMPTYING_HW_QUEUE_ADDBA;
1017 } 1030 }
1031 spin_unlock_irqrestore(&priv->sta_lock, flags);
1018 return ret; 1032 return ret;
1019} 1033}
1020 1034
@@ -1037,11 +1051,14 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1037 return -ENXIO; 1051 return -ENXIO;
1038 } 1052 }
1039 1053
1054 spin_lock_irqsave(&priv->sta_lock, flags);
1055
1040 if (priv->stations[sta_id].tid[tid].agg.state == 1056 if (priv->stations[sta_id].tid[tid].agg.state ==
1041 IWL_EMPTYING_HW_QUEUE_ADDBA) { 1057 IWL_EMPTYING_HW_QUEUE_ADDBA) {
1042 IWL_DEBUG_HT(priv, "AGG stop before setup done\n"); 1058 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
1043 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid); 1059 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1044 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 1060 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1061 spin_unlock_irqrestore(&priv->sta_lock, flags);
1045 return 0; 1062 return 0;
1046 } 1063 }
1047 1064
@@ -1059,13 +1076,17 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1059 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n"); 1076 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
1060 priv->stations[sta_id].tid[tid].agg.state = 1077 priv->stations[sta_id].tid[tid].agg.state =
1061 IWL_EMPTYING_HW_QUEUE_DELBA; 1078 IWL_EMPTYING_HW_QUEUE_DELBA;
1079 spin_unlock_irqrestore(&priv->sta_lock, flags);
1062 return 0; 1080 return 0;
1063 } 1081 }
1064 1082
1065 IWL_DEBUG_HT(priv, "HW queue is empty\n"); 1083 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1066 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 1084 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1067 1085
1068 spin_lock_irqsave(&priv->lock, flags); 1086 /* do not restore/save irqs */
1087 spin_unlock(&priv->sta_lock);
1088 spin_lock(&priv->lock);
1089
1069 /* 1090 /*
1070 * the only reason this call can fail is queue number out of range, 1091 * the only reason this call can fail is queue number out of range,
1071 * which can happen if uCode is reloaded and all the station 1092 * which can happen if uCode is reloaded and all the station
@@ -1089,6 +1110,8 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1089 u8 *addr = priv->stations[sta_id].sta.sta.addr; 1110 u8 *addr = priv->stations[sta_id].sta.sta.addr;
1090 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; 1111 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
1091 1112
1113 WARN_ON(!spin_is_locked(&priv->sta_lock));
1114
1092 switch (priv->stations[sta_id].tid[tid].agg.state) { 1115 switch (priv->stations[sta_id].tid[tid].agg.state) {
1093 case IWL_EMPTYING_HW_QUEUE_DELBA: 1116 case IWL_EMPTYING_HW_QUEUE_DELBA:
1094 /* We are reclaiming the last packet of the */ 1117 /* We are reclaiming the last packet of the */
@@ -1113,6 +1136,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1113 } 1136 }
1114 break; 1137 break;
1115 } 1138 }
1139
1116 return 0; 1140 return 0;
1117} 1141}
1118 1142
@@ -1276,6 +1300,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1276 int index; 1300 int index;
1277 int sta_id; 1301 int sta_id;
1278 int tid; 1302 int tid;
1303 unsigned long flags;
1279 1304
1280 /* "flow" corresponds to Tx queue */ 1305 /* "flow" corresponds to Tx queue */
1281 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow); 1306 u16 scd_flow = le16_to_cpu(ba_resp->scd_flow);
@@ -1298,7 +1323,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1298 /* Find index just before block-ack window */ 1323 /* Find index just before block-ack window */
1299 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd); 1324 index = iwl_queue_dec_wrap(ba_resp_scd_ssn & 0xff, txq->q.n_bd);
1300 1325
1301 /* TODO: Need to get this copy more safely - now good for debug */ 1326 spin_lock_irqsave(&priv->sta_lock, flags);
1302 1327
1303 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, " 1328 IWL_DEBUG_TX_REPLY(priv, "REPLY_COMPRESSED_BA [%d] Received from %pM, "
1304 "sta_id = %d\n", 1329 "sta_id = %d\n",
@@ -1334,4 +1359,6 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1334 1359
1335 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow); 1360 iwlagn_txq_check_empty(priv, sta_id, tid, scd_flow);
1336 } 1361 }
1362
1363 spin_unlock_irqrestore(&priv->sta_lock, flags);
1337} 1364}
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 8538af788a73..5ac03f5a4713 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -1224,7 +1224,9 @@ struct iwl_priv {
1224 u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */ 1224 u8 bssid[ETH_ALEN]; /* used only on 3945 but filled by core */
1225 u8 mac_addr[ETH_ALEN]; 1225 u8 mac_addr[ETH_ALEN];
1226 1226
1227 /*station table variables */ 1227 /* station table variables */
1228
1229 /* Note: if lock and sta_lock are needed, lock must be acquired first */
1228 spinlock_t sta_lock; 1230 spinlock_t sta_lock;
1229 int num_stations; 1231 int num_stations;
1230 struct iwl_station_entry stations[IWL_STATION_COUNT]; 1232 struct iwl_station_entry stations[IWL_STATION_COUNT];
diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c
index 2eafba60053b..4d878d8cbbee 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 }
@@ -1269,9 +1277,8 @@ void iwl_sta_tx_modify_enable_tid(struct iwl_priv *priv, int sta_id, int tid)
1269 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;
1270 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));
1271 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 1279 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
1272 spin_unlock_irqrestore(&priv->sta_lock, flags);
1273
1274 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);
1275} 1282}
1276EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid); 1283EXPORT_SYMBOL(iwl_sta_tx_modify_enable_tid);
1277 1284
@@ -1302,7 +1309,7 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1302 int tid) 1309 int tid)
1303{ 1310{
1304 unsigned long flags; 1311 unsigned long flags;
1305 int sta_id; 1312 int sta_id, ret;
1306 1313
1307 sta_id = iwl_sta_id(sta); 1314 sta_id = iwl_sta_id(sta);
1308 if (sta_id == IWL_INVALID_STATION) { 1315 if (sta_id == IWL_INVALID_STATION) {
@@ -1315,10 +1322,11 @@ int iwl_sta_rx_agg_stop(struct iwl_priv *priv, struct ieee80211_sta *sta,
1315 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;
1316 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid; 1323 priv->stations[sta_id].sta.remove_immediate_ba_tid = (u8)tid;
1317 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);
1318 spin_unlock_irqrestore(&priv->sta_lock, flags); 1326 spin_unlock_irqrestore(&priv->sta_lock, flags);
1319 1327
1320 return iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 1328 return ret;
1321 CMD_ASYNC); 1329
1322} 1330}
1323EXPORT_SYMBOL(iwl_sta_rx_agg_stop); 1331EXPORT_SYMBOL(iwl_sta_rx_agg_stop);
1324 1332
@@ -1332,9 +1340,9 @@ void iwl_sta_modify_ps_wake(struct iwl_priv *priv, int sta_id)
1332 priv->stations[sta_id].sta.sta.modify_mask = 0; 1340 priv->stations[sta_id].sta.sta.modify_mask = 0;
1333 priv->stations[sta_id].sta.sleep_tx_count = 0; 1341 priv->stations[sta_id].sta.sleep_tx_count = 0;
1334 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);
1335 spin_unlock_irqrestore(&priv->sta_lock, flags); 1344 spin_unlock_irqrestore(&priv->sta_lock, flags);
1336 1345
1337 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1338} 1346}
1339EXPORT_SYMBOL(iwl_sta_modify_ps_wake); 1347EXPORT_SYMBOL(iwl_sta_modify_ps_wake);
1340 1348
@@ -1349,9 +1357,9 @@ void iwl_sta_modify_sleep_tx_count(struct iwl_priv *priv, int sta_id, int cnt)
1349 STA_MODIFY_SLEEP_TX_COUNT_MSK; 1357 STA_MODIFY_SLEEP_TX_COUNT_MSK;
1350 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);
1351 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);
1352 spin_unlock_irqrestore(&priv->sta_lock, flags); 1361 spin_unlock_irqrestore(&priv->sta_lock, flags);
1353 1362
1354 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, CMD_ASYNC);
1355} 1363}
1356EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count); 1364EXPORT_SYMBOL(iwl_sta_modify_sleep_tx_count);
1357 1365
diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
index 445406406bd0..82beeb5a2af9 100644
--- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
+++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
@@ -196,6 +196,7 @@ static int iwl3945_set_wep_dynamic_key_info(struct iwl_priv *priv,
196static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id) 196static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
197{ 197{
198 unsigned long flags; 198 unsigned long flags;
199 struct iwl_addsta_cmd sta_cmd;
199 200
200 spin_lock_irqsave(&priv->sta_lock, flags); 201 spin_lock_irqsave(&priv->sta_lock, flags);
201 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key)); 202 memset(&priv->stations[sta_id].keyinfo, 0, sizeof(struct iwl_hw_key));
@@ -204,11 +205,11 @@ static int iwl3945_clear_sta_key_info(struct iwl_priv *priv, u8 sta_id)
204 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC; 205 priv->stations[sta_id].sta.key.key_flags = STA_KEY_FLG_NO_ENC;
205 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK; 206 priv->stations[sta_id].sta.sta.modify_mask = STA_MODIFY_KEY_MASK;
206 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK; 207 priv->stations[sta_id].sta.mode = STA_CONTROL_MODIFY_MSK;
208 memcpy(&sta_cmd, &priv->stations[sta_id].sta, sizeof(struct iwl_addsta_cmd));
207 spin_unlock_irqrestore(&priv->sta_lock, flags); 209 spin_unlock_irqrestore(&priv->sta_lock, flags);
208 210
209 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n"); 211 IWL_DEBUG_INFO(priv, "hwcrypto: clear ucode station key info\n");
210 iwl_send_add_sta(priv, &priv->stations[sta_id].sta, 0); 212 return iwl_send_add_sta(priv, &sta_cmd, CMD_SYNC);
211 return 0;
212} 213}
213 214
214static int iwl3945_set_dynamic_key(struct iwl_priv *priv, 215static int iwl3945_set_dynamic_key(struct iwl_priv *priv,