aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-tx.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c137
1 files changed, 79 insertions, 58 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 3fc982e87921..5950184d9860 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -71,18 +71,6 @@ static const u8 tid_to_ac[] = {
71 2, 3, 3, 2, 1, 1, 0, 0 71 2, 3, 3, 2, 1, 1, 0, 0
72}; 72};
73 73
74static const u8 ac_to_fifo[] = {
75 IWL_TX_FIFO_VO,
76 IWL_TX_FIFO_VI,
77 IWL_TX_FIFO_BE,
78 IWL_TX_FIFO_BK,
79};
80
81static inline int get_fifo_from_ac(u8 ac)
82{
83 return ac_to_fifo[ac];
84}
85
86static inline int get_ac_from_tid(u16 tid) 74static inline int get_ac_from_tid(u16 tid)
87{ 75{
88 if (likely(tid < ARRAY_SIZE(tid_to_ac))) 76 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
@@ -92,10 +80,10 @@ static inline int get_ac_from_tid(u16 tid)
92 return -EINVAL; 80 return -EINVAL;
93} 81}
94 82
95static inline int get_fifo_from_tid(u16 tid) 83static inline int get_fifo_from_tid(struct iwl_rxon_context *ctx, u16 tid)
96{ 84{
97 if (likely(tid < ARRAY_SIZE(tid_to_ac))) 85 if (likely(tid < ARRAY_SIZE(tid_to_ac)))
98 return get_fifo_from_ac(tid_to_ac[tid]); 86 return ctx->ac_to_fifo[tid_to_ac[tid]];
99 87
100 /* no support for TIDs 8-15 yet */ 88 /* no support for TIDs 8-15 yet */
101 return -EINVAL; 89 return -EINVAL;
@@ -118,7 +106,7 @@ void iwlagn_txq_update_byte_cnt_tbl(struct iwl_priv *priv,
118 106
119 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX); 107 WARN_ON(len > 0xFFF || write_ptr >= TFD_QUEUE_SIZE_MAX);
120 108
121 if (txq_id != IWL_CMD_QUEUE_NUM) { 109 if (txq_id != priv->cmd_queue) {
122 sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id; 110 sta_id = txq->cmd[txq->q.write_ptr]->cmd.tx.sta_id;
123 sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl; 111 sec_ctl = txq->cmd[txq->q.write_ptr]->cmd.tx.sec_ctl;
124 112
@@ -155,7 +143,7 @@ void iwlagn_txq_inval_byte_cnt_tbl(struct iwl_priv *priv,
155 143
156 WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX); 144 WARN_ON(read_ptr >= TFD_QUEUE_SIZE_MAX);
157 145
158 if (txq_id != IWL_CMD_QUEUE_NUM) 146 if (txq_id != priv->cmd_queue)
159 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id; 147 sta_id = txq->cmd[read_ptr]->cmd.tx.sta_id;
160 148
161 bc_ent = cpu_to_le16(1 | (sta_id << 12)); 149 bc_ent = cpu_to_le16(1 | (sta_id << 12));
@@ -333,19 +321,15 @@ void iwlagn_txq_set_sched(struct iwl_priv *priv, u32 mask)
333 iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask); 321 iwl_write_prph(priv, IWLAGN_SCD_TXFACT, mask);
334} 322}
335 323
336static inline int get_queue_from_ac(u16 ac)
337{
338 return ac;
339}
340
341/* 324/*
342 * handle build REPLY_TX command notification. 325 * handle build REPLY_TX command notification.
343 */ 326 */
344static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv, 327static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
345 struct iwl_tx_cmd *tx_cmd, 328 struct sk_buff *skb,
346 struct ieee80211_tx_info *info, 329 struct iwl_tx_cmd *tx_cmd,
347 struct ieee80211_hdr *hdr, 330 struct ieee80211_tx_info *info,
348 u8 std_id) 331 struct ieee80211_hdr *hdr,
332 u8 std_id)
349{ 333{
350 __le16 fc = hdr->frame_control; 334 __le16 fc = hdr->frame_control;
351 __le32 tx_flags = tx_cmd->tx_flags; 335 __le32 tx_flags = tx_cmd->tx_flags;
@@ -365,6 +349,12 @@ static void iwlagn_tx_cmd_build_basic(struct iwl_priv *priv,
365 349
366 if (ieee80211_is_back_req(fc)) 350 if (ieee80211_is_back_req(fc))
367 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK; 351 tx_flags |= TX_CMD_FLG_ACK_MSK | TX_CMD_FLG_IMM_BA_RSP_MASK;
352 else if (info->band == IEEE80211_BAND_2GHZ &&
353 priv->cfg->advanced_bt_coexist &&
354 (ieee80211_is_auth(fc) || ieee80211_is_assoc_req(fc) ||
355 ieee80211_is_reassoc_req(fc) ||
356 skb->protocol == cpu_to_be16(ETH_P_PAE)))
357 tx_flags |= TX_CMD_FLG_IGNORE_BT;
368 358
369 359
370 tx_cmd->sta_id = std_id; 360 tx_cmd->sta_id = std_id;
@@ -454,7 +444,12 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
454 rate_flags |= RATE_MCS_CCK_MSK; 444 rate_flags |= RATE_MCS_CCK_MSK;
455 445
456 /* Set up antennas */ 446 /* Set up antennas */
457 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 447 if (priv->cfg->advanced_bt_coexist && priv->bt_full_concurrent) {
448 /* operated as 1x1 in full concurrency mode */
449 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
450 first_antenna(priv->hw_params.valid_tx_ant));
451 } else
452 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
458 priv->hw_params.valid_tx_ant); 453 priv->hw_params.valid_tx_ant);
459 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant); 454 rate_flags |= iwl_ant_idx_to_flags(priv->mgmt_tx_ant);
460 455
@@ -519,6 +514,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
519 struct iwl_device_cmd *out_cmd; 514 struct iwl_device_cmd *out_cmd;
520 struct iwl_cmd_meta *out_meta; 515 struct iwl_cmd_meta *out_meta;
521 struct iwl_tx_cmd *tx_cmd; 516 struct iwl_tx_cmd *tx_cmd;
517 struct iwl_rxon_context *ctx = &priv->contexts[IWL_RXON_CTX_BSS];
522 int swq_id, txq_id; 518 int swq_id, txq_id;
523 dma_addr_t phys_addr; 519 dma_addr_t phys_addr;
524 dma_addr_t txcmd_phys; 520 dma_addr_t txcmd_phys;
@@ -533,6 +529,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
533 u8 *qc = NULL; 529 u8 *qc = NULL;
534 unsigned long flags; 530 unsigned long flags;
535 531
532 if (info->control.vif)
533 ctx = iwl_rxon_ctx_from_vif(info->control.vif);
534
536 spin_lock_irqsave(&priv->lock, flags); 535 spin_lock_irqsave(&priv->lock, flags);
537 if (iwl_is_rfkill(priv)) { 536 if (iwl_is_rfkill(priv)) {
538 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n"); 537 IWL_DEBUG_DROP(priv, "Dropping - RF KILL\n");
@@ -553,7 +552,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
553 hdr_len = ieee80211_hdrlen(fc); 552 hdr_len = ieee80211_hdrlen(fc);
554 553
555 /* Find index into station table for destination station */ 554 /* Find index into station table for destination station */
556 sta_id = iwl_sta_id_or_broadcast(priv, info->control.sta); 555 sta_id = iwl_sta_id_or_broadcast(priv, ctx, info->control.sta);
557 if (sta_id == IWL_INVALID_STATION) { 556 if (sta_id == IWL_INVALID_STATION) {
558 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n", 557 IWL_DEBUG_DROP(priv, "Dropping - INVALID STATION: %pM\n",
559 hdr->addr1); 558 hdr->addr1);
@@ -565,8 +564,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
565 if (sta) 564 if (sta)
566 sta_priv = (void *)sta->drv_priv; 565 sta_priv = (void *)sta->drv_priv;
567 566
568 if (sta_priv && sta_id != priv->hw_params.bcast_sta_id && 567 if (sta_priv && sta_priv->asleep) {
569 sta_priv->asleep) {
570 WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE)); 568 WARN_ON(!(info->flags & IEEE80211_TX_CTL_PSPOLL_RESPONSE));
571 /* 569 /*
572 * This sends an asynchronous command to the device, 570 * This sends an asynchronous command to the device,
@@ -580,7 +578,20 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
580 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1); 578 iwl_sta_modify_sleep_tx_count(priv, sta_id, 1);
581 } 579 }
582 580
583 txq_id = get_queue_from_ac(skb_get_queue_mapping(skb)); 581 /*
582 * Send this frame after DTIM -- there's a special queue
583 * reserved for this for contexts that support AP mode.
584 */
585 if (info->flags & IEEE80211_TX_CTL_SEND_AFTER_DTIM) {
586 txq_id = ctx->mcast_queue;
587 /*
588 * The microcode will clear the more data
589 * bit in the last frame it transmits.
590 */
591 hdr->frame_control |=
592 cpu_to_le16(IEEE80211_FCTL_MOREDATA);
593 } else
594 txq_id = ctx->ac_to_queue[skb_get_queue_mapping(skb)];
584 595
585 /* irqs already disabled/saved above when locking priv->lock */ 596 /* irqs already disabled/saved above when locking priv->lock */
586 spin_lock(&priv->sta_lock); 597 spin_lock(&priv->sta_lock);
@@ -625,6 +636,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
625 /* Set up driver data for this TFD */ 636 /* Set up driver data for this TFD */
626 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info)); 637 memset(&(txq->txb[q->write_ptr]), 0, sizeof(struct iwl_tx_info));
627 txq->txb[q->write_ptr].skb = skb; 638 txq->txb[q->write_ptr].skb = skb;
639 txq->txb[q->write_ptr].ctx = ctx;
628 640
629 /* Set up first empty entry in queue's array of Tx/cmd buffers */ 641 /* Set up first empty entry in queue's array of Tx/cmd buffers */
630 out_cmd = txq->cmd[q->write_ptr]; 642 out_cmd = txq->cmd[q->write_ptr];
@@ -655,7 +667,7 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
655 iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id); 667 iwlagn_tx_cmd_build_hwcrypto(priv, info, tx_cmd, skb, sta_id);
656 668
657 /* TODO need this for burst mode later on */ 669 /* TODO need this for burst mode later on */
658 iwlagn_tx_cmd_build_basic(priv, tx_cmd, info, hdr, sta_id); 670 iwlagn_tx_cmd_build_basic(priv, skb, tx_cmd, info, hdr, sta_id);
659 iwl_dbg_log_tx_data_frame(priv, len, hdr); 671 iwl_dbg_log_tx_data_frame(priv, len, hdr);
660 672
661 iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc); 673 iwlagn_tx_cmd_build_rate(priv, tx_cmd, info, fc);
@@ -813,7 +825,7 @@ void iwlagn_hw_txq_ctx_free(struct iwl_priv *priv)
813 /* Tx queues */ 825 /* Tx queues */
814 if (priv->txq) { 826 if (priv->txq) {
815 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) 827 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++)
816 if (txq_id == IWL_CMD_QUEUE_NUM) 828 if (txq_id == priv->cmd_queue)
817 iwl_cmd_queue_free(priv); 829 iwl_cmd_queue_free(priv);
818 else 830 else
819 iwl_tx_queue_free(priv, txq_id); 831 iwl_tx_queue_free(priv, txq_id);
@@ -870,9 +882,9 @@ int iwlagn_txq_ctx_alloc(struct iwl_priv *priv)
870 882
871 spin_unlock_irqrestore(&priv->lock, flags); 883 spin_unlock_irqrestore(&priv->lock, flags);
872 884
873 /* Alloc and init all Tx queues, including the command queue (#4) */ 885 /* Alloc and init all Tx queues, including the command queue (#4/#9) */
874 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { 886 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
875 slots_num = (txq_id == IWL_CMD_QUEUE_NUM) ? 887 slots_num = (txq_id == priv->cmd_queue) ?
876 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; 888 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
877 ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num, 889 ret = iwl_tx_queue_init(priv, &priv->txq[txq_id], slots_num,
878 txq_id); 890 txq_id);
@@ -910,7 +922,7 @@ void iwlagn_txq_ctx_reset(struct iwl_priv *priv)
910 922
911 /* Alloc and init all Tx queues, including the command queue (#4) */ 923 /* Alloc and init all Tx queues, including the command queue (#4) */
912 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) { 924 for (txq_id = 0; txq_id < priv->hw_params.max_txq_num; txq_id++) {
913 slots_num = txq_id == IWL_CMD_QUEUE_NUM ? 925 slots_num = txq_id == priv->cmd_queue ?
914 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS; 926 TFD_CMD_SLOTS : TFD_TX_CMD_SLOTS;
915 iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id); 927 iwl_tx_queue_reset(priv, &priv->txq[txq_id], slots_num, txq_id);
916 } 928 }
@@ -968,7 +980,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
968 unsigned long flags; 980 unsigned long flags;
969 struct iwl_tid_data *tid_data; 981 struct iwl_tid_data *tid_data;
970 982
971 tx_fifo = get_fifo_from_tid(tid); 983 tx_fifo = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
972 if (unlikely(tx_fifo < 0)) 984 if (unlikely(tx_fifo < 0))
973 return tx_fifo; 985 return tx_fifo;
974 986
@@ -1024,12 +1036,12 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
1024int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif, 1036int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1025 struct ieee80211_sta *sta, u16 tid) 1037 struct ieee80211_sta *sta, u16 tid)
1026{ 1038{
1027 int tx_fifo_id, txq_id, sta_id, ssn = -1; 1039 int tx_fifo_id, txq_id, sta_id, ssn;
1028 struct iwl_tid_data *tid_data; 1040 struct iwl_tid_data *tid_data;
1029 int write_ptr, read_ptr; 1041 int write_ptr, read_ptr;
1030 unsigned long flags; 1042 unsigned long flags;
1031 1043
1032 tx_fifo_id = get_fifo_from_tid(tid); 1044 tx_fifo_id = get_fifo_from_tid(iwl_rxon_ctx_from_vif(vif), tid);
1033 if (unlikely(tx_fifo_id < 0)) 1045 if (unlikely(tx_fifo_id < 0))
1034 return tx_fifo_id; 1046 return tx_fifo_id;
1035 1047
@@ -1042,21 +1054,26 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1042 1054
1043 spin_lock_irqsave(&priv->sta_lock, flags); 1055 spin_lock_irqsave(&priv->sta_lock, flags);
1044 1056
1045 if (priv->stations[sta_id].tid[tid].agg.state ==
1046 IWL_EMPTYING_HW_QUEUE_ADDBA) {
1047 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
1048 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
1049 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1050 spin_unlock_irqrestore(&priv->sta_lock, flags);
1051 return 0;
1052 }
1053
1054 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_ON)
1055 IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
1056
1057 tid_data = &priv->stations[sta_id].tid[tid]; 1057 tid_data = &priv->stations[sta_id].tid[tid];
1058 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; 1058 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
1059 txq_id = tid_data->agg.txq_id; 1059 txq_id = tid_data->agg.txq_id;
1060
1061 switch (priv->stations[sta_id].tid[tid].agg.state) {
1062 case IWL_EMPTYING_HW_QUEUE_ADDBA:
1063 /*
1064 * This can happen if the peer stops aggregation
1065 * again before we've had a chance to drain the
1066 * queue we selected previously, i.e. before the
1067 * session was really started completely.
1068 */
1069 IWL_DEBUG_HT(priv, "AGG stop before setup done\n");
1070 goto turn_off;
1071 case IWL_AGG_ON:
1072 break;
1073 default:
1074 IWL_WARN(priv, "Stopping AGG while state not ON or starting\n");
1075 }
1076
1060 write_ptr = priv->txq[txq_id].q.write_ptr; 1077 write_ptr = priv->txq[txq_id].q.write_ptr;
1061 read_ptr = priv->txq[txq_id].q.read_ptr; 1078 read_ptr = priv->txq[txq_id].q.read_ptr;
1062 1079
@@ -1070,6 +1087,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
1070 } 1087 }
1071 1088
1072 IWL_DEBUG_HT(priv, "HW queue is empty\n"); 1089 IWL_DEBUG_HT(priv, "HW queue is empty\n");
1090 turn_off:
1073 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 1091 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF;
1074 1092
1075 /* do not restore/save irqs */ 1093 /* do not restore/save irqs */
@@ -1098,6 +1116,9 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1098 struct iwl_queue *q = &priv->txq[txq_id].q; 1116 struct iwl_queue *q = &priv->txq[txq_id].q;
1099 u8 *addr = priv->stations[sta_id].sta.sta.addr; 1117 u8 *addr = priv->stations[sta_id].sta.sta.addr;
1100 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; 1118 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid];
1119 struct iwl_rxon_context *ctx;
1120
1121 ctx = &priv->contexts[priv->stations[sta_id].ctxid];
1101 1122
1102 lockdep_assert_held(&priv->sta_lock); 1123 lockdep_assert_held(&priv->sta_lock);
1103 1124
@@ -1108,12 +1129,12 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1108 if ((txq_id == tid_data->agg.txq_id) && 1129 if ((txq_id == tid_data->agg.txq_id) &&
1109 (q->read_ptr == q->write_ptr)) { 1130 (q->read_ptr == q->write_ptr)) {
1110 u16 ssn = SEQ_TO_SN(tid_data->seq_number); 1131 u16 ssn = SEQ_TO_SN(tid_data->seq_number);
1111 int tx_fifo = get_fifo_from_tid(tid); 1132 int tx_fifo = get_fifo_from_tid(ctx, tid);
1112 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n"); 1133 IWL_DEBUG_HT(priv, "HW queue empty: continue DELBA flow\n");
1113 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, 1134 priv->cfg->ops->lib->txq_agg_disable(priv, txq_id,
1114 ssn, tx_fifo); 1135 ssn, tx_fifo);
1115 tid_data->agg.state = IWL_AGG_OFF; 1136 tid_data->agg.state = IWL_AGG_OFF;
1116 ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, addr, tid); 1137 ieee80211_stop_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
1117 } 1138 }
1118 break; 1139 break;
1119 case IWL_EMPTYING_HW_QUEUE_ADDBA: 1140 case IWL_EMPTYING_HW_QUEUE_ADDBA:
@@ -1121,7 +1142,7 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1121 if (tid_data->tfds_in_queue == 0) { 1142 if (tid_data->tfds_in_queue == 0) {
1122 IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n"); 1143 IWL_DEBUG_HT(priv, "HW queue empty: continue ADDBA flow\n");
1123 tid_data->agg.state = IWL_AGG_ON; 1144 tid_data->agg.state = IWL_AGG_ON;
1124 ieee80211_start_tx_ba_cb_irqsafe(priv->vif, addr, tid); 1145 ieee80211_start_tx_ba_cb_irqsafe(ctx->vif, addr, tid);
1125 } 1146 }
1126 break; 1147 break;
1127 } 1148 }
@@ -1129,14 +1150,14 @@ int iwlagn_txq_check_empty(struct iwl_priv *priv,
1129 return 0; 1150 return 0;
1130} 1151}
1131 1152
1132static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb) 1153static void iwlagn_tx_status(struct iwl_priv *priv, struct iwl_tx_info *tx_info)
1133{ 1154{
1134 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; 1155 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) tx_info->skb->data;
1135 struct ieee80211_sta *sta; 1156 struct ieee80211_sta *sta;
1136 struct iwl_station_priv *sta_priv; 1157 struct iwl_station_priv *sta_priv;
1137 1158
1138 rcu_read_lock(); 1159 rcu_read_lock();
1139 sta = ieee80211_find_sta(priv->vif, hdr->addr1); 1160 sta = ieee80211_find_sta(tx_info->ctx->vif, hdr->addr1);
1140 if (sta) { 1161 if (sta) {
1141 sta_priv = (void *)sta->drv_priv; 1162 sta_priv = (void *)sta->drv_priv;
1142 /* avoid atomic ops if this isn't a client */ 1163 /* avoid atomic ops if this isn't a client */
@@ -1146,7 +1167,7 @@ static void iwlagn_tx_status(struct iwl_priv *priv, struct sk_buff *skb)
1146 } 1167 }
1147 rcu_read_unlock(); 1168 rcu_read_unlock();
1148 1169
1149 ieee80211_tx_status_irqsafe(priv->hw, skb); 1170 ieee80211_tx_status_irqsafe(priv->hw, tx_info->skb);
1150} 1171}
1151 1172
1152int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index) 1173int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
@@ -1169,7 +1190,7 @@ int iwlagn_tx_queue_reclaim(struct iwl_priv *priv, int txq_id, int index)
1169 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { 1190 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) {
1170 1191
1171 tx_info = &txq->txb[txq->q.read_ptr]; 1192 tx_info = &txq->txb[txq->q.read_ptr];
1172 iwlagn_tx_status(priv, tx_info->skb); 1193 iwlagn_tx_status(priv, tx_info);
1173 1194
1174 hdr = (struct ieee80211_hdr *)tx_info->skb->data; 1195 hdr = (struct ieee80211_hdr *)tx_info->skb->data;
1175 if (hdr && ieee80211_is_data_qos(hdr->frame_control)) 1196 if (hdr && ieee80211_is_data_qos(hdr->frame_control))