aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2011-08-26 02:11:18 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-08-29 15:30:31 -0400
commit5f85a7890cbfd2be8f4c6620b2a6774d6b5ac647 (patch)
tree66eaa03491a20c343b1000e7ad4de4f5f282e0de
parent1603dd495f87ae97763870d57237744d90bc2bab (diff)
iwlagn: iwl_tid_data moves to iwl-shared
The rate scaling and the transport need to access the data in iwl_tid_data, hence the move. Note that the only component in the upper layer that needs this data is the rate scaling. Refactoring the rate scaling may help to move iwl_tid_data from the shared area to the transport area. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-rs.c18
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-tx.c47
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-commands.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debugfs.c25
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h39
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-shared.h32
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.c2
9 files changed, 83 insertions, 87 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
index 3870b723c8c2..356762f21d2f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c
@@ -297,10 +297,10 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
297 u8 *qc = ieee80211_get_qos_ctl(hdr); 297 u8 *qc = ieee80211_get_qos_ctl(hdr);
298 tid = qc[0] & 0xf; 298 tid = qc[0] & 0xf;
299 } else 299 } else
300 return MAX_TID_COUNT; 300 return IWL_MAX_TID_COUNT;
301 301
302 if (unlikely(tid >= TID_MAX_LOAD_COUNT)) 302 if (unlikely(tid >= TID_MAX_LOAD_COUNT))
303 return MAX_TID_COUNT; 303 return IWL_MAX_TID_COUNT;
304 304
305 tl = &lq_data->load[tid]; 305 tl = &lq_data->load[tid];
306 306
@@ -313,7 +313,7 @@ static u8 rs_tl_add_packet(struct iwl_lq_sta *lq_data,
313 tl->queue_count = 1; 313 tl->queue_count = 1;
314 tl->head = 0; 314 tl->head = 0;
315 tl->packet_count[0] = 1; 315 tl->packet_count[0] = 1;
316 return MAX_TID_COUNT; 316 return IWL_MAX_TID_COUNT;
317 } 317 }
318 318
319 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time); 319 time_diff = TIME_WRAP_AROUND(tl->time_stamp, curr_time);
@@ -2261,7 +2261,7 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2261 u8 done_search = 0; 2261 u8 done_search = 0;
2262 u16 high_low; 2262 u16 high_low;
2263 s32 sr; 2263 s32 sr;
2264 u8 tid = MAX_TID_COUNT; 2264 u8 tid = IWL_MAX_TID_COUNT;
2265 struct iwl_tid_data *tid_data; 2265 struct iwl_tid_data *tid_data;
2266 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; 2266 struct iwl_station_priv *sta_priv = (void *)sta->drv_priv;
2267 struct iwl_rxon_context *ctx = sta_priv->common.ctx; 2267 struct iwl_rxon_context *ctx = sta_priv->common.ctx;
@@ -2280,8 +2280,9 @@ static void rs_rate_scale_perform(struct iwl_priv *priv,
2280 lq_sta->supp_rates = sta->supp_rates[lq_sta->band]; 2280 lq_sta->supp_rates = sta->supp_rates[lq_sta->band];
2281 2281
2282 tid = rs_tl_add_packet(lq_sta, hdr); 2282 tid = rs_tl_add_packet(lq_sta, hdr);
2283 if ((tid != MAX_TID_COUNT) && (lq_sta->tx_agg_tid_en & (1 << tid))) { 2283 if ((tid != IWL_MAX_TID_COUNT) &&
2284 tid_data = &priv->stations[lq_sta->lq.sta_id].tid[tid]; 2284 (lq_sta->tx_agg_tid_en & (1 << tid))) {
2285 tid_data = &priv->shrd->tid_data[lq_sta->lq.sta_id][tid];
2285 if (tid_data->agg.state == IWL_AGG_OFF) 2286 if (tid_data->agg.state == IWL_AGG_OFF)
2286 lq_sta->is_agg = 0; 2287 lq_sta->is_agg = 0;
2287 else 2288 else
@@ -2651,9 +2652,10 @@ lq_update:
2651 iwl_ht_enabled(priv)) { 2652 iwl_ht_enabled(priv)) {
2652 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) && 2653 if ((lq_sta->last_tpt > IWL_AGG_TPT_THREHOLD) &&
2653 (lq_sta->tx_agg_tid_en & (1 << tid)) && 2654 (lq_sta->tx_agg_tid_en & (1 << tid)) &&
2654 (tid != MAX_TID_COUNT)) { 2655 (tid != IWL_MAX_TID_COUNT)) {
2656 u8 sta_id = lq_sta->lq.sta_id;
2655 tid_data = 2657 tid_data =
2656 &priv->stations[lq_sta->lq.sta_id].tid[tid]; 2658 &priv->shrd->tid_data[sta_id][tid];
2657 if (tid_data->agg.state == IWL_AGG_OFF) { 2659 if (tid_data->agg.state == IWL_AGG_OFF) {
2658 IWL_DEBUG_RATE(priv, 2660 IWL_DEBUG_RATE(priv,
2659 "try to aggregate tid %d\n", 2661 "try to aggregate tid %d\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
index 97d03a85d579..bb6605b51956 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-tx.c
@@ -410,13 +410,15 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
410 410
411 if (ieee80211_is_data_qos(fc)) { 411 if (ieee80211_is_data_qos(fc)) {
412 u8 *qc = NULL; 412 u8 *qc = NULL;
413 struct iwl_tid_data *tid_data;
413 qc = ieee80211_get_qos_ctl(hdr); 414 qc = ieee80211_get_qos_ctl(hdr);
414 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK; 415 tid = qc[0] & IEEE80211_QOS_CTL_TID_MASK;
416 tid_data = &priv->shrd->tid_data[sta_id][tid];
415 417
416 if (WARN_ON_ONCE(tid >= MAX_TID_COUNT)) 418 if (WARN_ON_ONCE(tid >= IWL_MAX_TID_COUNT))
417 goto drop_unlock_sta; 419 goto drop_unlock_sta;
418 420
419 seq_number = priv->stations[sta_id].tid[tid].seq_number; 421 seq_number = tid_data->seq_number;
420 seq_number &= IEEE80211_SCTL_SEQ; 422 seq_number &= IEEE80211_SCTL_SEQ;
421 hdr->seq_ctrl = hdr->seq_ctrl & 423 hdr->seq_ctrl = hdr->seq_ctrl &
422 cpu_to_le16(IEEE80211_SCTL_FRAG); 424 cpu_to_le16(IEEE80211_SCTL_FRAG);
@@ -424,8 +426,8 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
424 seq_number += 0x10; 426 seq_number += 0x10;
425 /* aggregation is on for this <sta,tid> */ 427 /* aggregation is on for this <sta,tid> */
426 if (info->flags & IEEE80211_TX_CTL_AMPDU && 428 if (info->flags & IEEE80211_TX_CTL_AMPDU &&
427 priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) { 429 tid_data->agg.state == IWL_AGG_ON) {
428 txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; 430 txq_id = tid_data->agg.txq_id;
429 is_agg = true; 431 is_agg = true;
430 } 432 }
431 } 433 }
@@ -456,9 +458,10 @@ int iwlagn_tx_skb(struct iwl_priv *priv, struct sk_buff *skb)
456 goto drop_unlock_sta; 458 goto drop_unlock_sta;
457 459
458 if (ieee80211_is_data_qos(fc)) { 460 if (ieee80211_is_data_qos(fc)) {
459 priv->stations[sta_id].tid[tid].tfds_in_queue++; 461 priv->shrd->tid_data[sta_id][tid].tfds_in_queue++;
460 if (!ieee80211_has_morefrags(fc)) 462 if (!ieee80211_has_morefrags(fc))
461 priv->stations[sta_id].tid[tid].seq_number = seq_number; 463 priv->shrd->tid_data[sta_id][tid].seq_number =
464 seq_number;
462 } 465 }
463 466
464 spin_unlock(&priv->shrd->sta_lock); 467 spin_unlock(&priv->shrd->sta_lock);
@@ -521,10 +524,10 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
521 IWL_ERR(priv, "Start AGG on invalid station\n"); 524 IWL_ERR(priv, "Start AGG on invalid station\n");
522 return -ENXIO; 525 return -ENXIO;
523 } 526 }
524 if (unlikely(tid >= MAX_TID_COUNT)) 527 if (unlikely(tid >= IWL_MAX_TID_COUNT))
525 return -EINVAL; 528 return -EINVAL;
526 529
527 if (priv->stations[sta_id].tid[tid].agg.state != IWL_AGG_OFF) { 530 if (priv->shrd->tid_data[sta_id][tid].agg.state != IWL_AGG_OFF) {
528 IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n"); 531 IWL_ERR(priv, "Start AGG when state is not IWL_AGG_OFF !\n");
529 return -ENXIO; 532 return -ENXIO;
530 } 533 }
@@ -536,7 +539,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
536 } 539 }
537 540
538 spin_lock_irqsave(&priv->shrd->sta_lock, flags); 541 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
539 tid_data = &priv->stations[sta_id].tid[tid]; 542 tid_data = &priv->shrd->tid_data[sta_id][tid];
540 *ssn = SEQ_TO_SN(tid_data->seq_number); 543 *ssn = SEQ_TO_SN(tid_data->seq_number);
541 tid_data->agg.txq_id = txq_id; 544 tid_data->agg.txq_id = txq_id;
542 tid_data->agg.tx_fifo = tx_fifo; 545 tid_data->agg.tx_fifo = tx_fifo;
@@ -548,7 +551,7 @@ int iwlagn_tx_agg_start(struct iwl_priv *priv, struct ieee80211_vif *vif,
548 return ret; 551 return ret;
549 552
550 spin_lock_irqsave(&priv->shrd->sta_lock, flags); 553 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
551 tid_data = &priv->stations[sta_id].tid[tid]; 554 tid_data = &priv->shrd->tid_data[sta_id][tid];
552 if (tid_data->tfds_in_queue == 0) { 555 if (tid_data->tfds_in_queue == 0) {
553 IWL_DEBUG_HT(priv, "HW queue is empty\n"); 556 IWL_DEBUG_HT(priv, "HW queue is empty\n");
554 tid_data->agg.state = IWL_AGG_ON; 557 tid_data->agg.state = IWL_AGG_ON;
@@ -583,11 +586,11 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
583 586
584 spin_lock_irqsave(&priv->shrd->sta_lock, flags); 587 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
585 588
586 tid_data = &priv->stations[sta_id].tid[tid]; 589 tid_data = &priv->shrd->tid_data[sta_id][tid];
587 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4; 590 ssn = (tid_data->seq_number & IEEE80211_SCTL_SEQ) >> 4;
588 txq_id = tid_data->agg.txq_id; 591 txq_id = tid_data->agg.txq_id;
589 592
590 switch (priv->stations[sta_id].tid[tid].agg.state) { 593 switch (priv->shrd->tid_data[sta_id][tid].agg.state) {
591 case IWL_EMPTYING_HW_QUEUE_ADDBA: 594 case IWL_EMPTYING_HW_QUEUE_ADDBA:
592 /* 595 /*
593 * This can happen if the peer stops aggregation 596 * This can happen if the peer stops aggregation
@@ -609,7 +612,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
609 /* The queue is not empty */ 612 /* The queue is not empty */
610 if (write_ptr != read_ptr) { 613 if (write_ptr != read_ptr) {
611 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n"); 614 IWL_DEBUG_HT(priv, "Stopping a non empty AGG HW QUEUE\n");
612 priv->stations[sta_id].tid[tid].agg.state = 615 priv->shrd->tid_data[sta_id][tid].agg.state =
613 IWL_EMPTYING_HW_QUEUE_DELBA; 616 IWL_EMPTYING_HW_QUEUE_DELBA;
614 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags); 617 spin_unlock_irqrestore(&priv->shrd->sta_lock, flags);
615 return 0; 618 return 0;
@@ -617,7 +620,7 @@ int iwlagn_tx_agg_stop(struct iwl_priv *priv, struct ieee80211_vif *vif,
617 620
618 IWL_DEBUG_HT(priv, "HW queue is empty\n"); 621 IWL_DEBUG_HT(priv, "HW queue is empty\n");
619 turn_off: 622 turn_off:
620 priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; 623 priv->shrd->tid_data[sta_id][tid].agg.state = IWL_AGG_OFF;
621 624
622 /* do not restore/save irqs */ 625 /* do not restore/save irqs */
623 spin_unlock(&priv->shrd->sta_lock); 626 spin_unlock(&priv->shrd->sta_lock);
@@ -643,14 +646,14 @@ static int iwlagn_txq_check_empty(struct iwl_priv *priv,
643{ 646{
644 struct iwl_queue *q = &priv->txq[txq_id].q; 647 struct iwl_queue *q = &priv->txq[txq_id].q;
645 u8 *addr = priv->stations[sta_id].sta.sta.addr; 648 u8 *addr = priv->stations[sta_id].sta.sta.addr;
646 struct iwl_tid_data *tid_data = &priv->stations[sta_id].tid[tid]; 649 struct iwl_tid_data *tid_data = &priv->shrd->tid_data[sta_id][tid];
647 struct iwl_rxon_context *ctx; 650 struct iwl_rxon_context *ctx;
648 651
649 ctx = &priv->contexts[priv->stations[sta_id].ctxid]; 652 ctx = &priv->contexts[priv->stations[sta_id].ctxid];
650 653
651 lockdep_assert_held(&priv->shrd->sta_lock); 654 lockdep_assert_held(&priv->shrd->sta_lock);
652 655
653 switch (priv->stations[sta_id].tid[tid].agg.state) { 656 switch (priv->shrd->tid_data[sta_id][tid].agg.state) {
654 case IWL_EMPTYING_HW_QUEUE_DELBA: 657 case IWL_EMPTYING_HW_QUEUE_DELBA:
655 /* We are reclaiming the last packet of the */ 658 /* We are reclaiming the last packet of the */
656 /* aggregated HW queue */ 659 /* aggregated HW queue */
@@ -815,7 +818,7 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv,
815 IWLAGN_TX_RES_TID_POS; 818 IWLAGN_TX_RES_TID_POS;
816 int sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >> 819 int sta_id = (tx_resp->ra_tid & IWLAGN_TX_RES_RA_MSK) >>
817 IWLAGN_TX_RES_RA_POS; 820 IWLAGN_TX_RES_RA_POS;
818 struct iwl_ht_agg *agg = &priv->stations[sta_id].tid[tid].agg; 821 struct iwl_ht_agg *agg = &priv->shrd->tid_data[sta_id][tid].agg;
819 u32 status = le16_to_cpu(tx_resp->status.status); 822 u32 status = le16_to_cpu(tx_resp->status.status);
820 int i; 823 int i;
821 824
@@ -893,13 +896,13 @@ static void iwl_free_tfds_in_queue(struct iwl_priv *priv,
893{ 896{
894 lockdep_assert_held(&priv->shrd->sta_lock); 897 lockdep_assert_held(&priv->shrd->sta_lock);
895 898
896 if (priv->stations[sta_id].tid[tid].tfds_in_queue >= freed) 899 if (priv->shrd->tid_data[sta_id][tid].tfds_in_queue >= freed)
897 priv->stations[sta_id].tid[tid].tfds_in_queue -= freed; 900 priv->shrd->tid_data[sta_id][tid].tfds_in_queue -= freed;
898 else { 901 else {
899 IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n", 902 IWL_DEBUG_TX(priv, "free more than tfds_in_queue (%u:%d)\n",
900 priv->stations[sta_id].tid[tid].tfds_in_queue, 903 priv->shrd->tid_data[sta_id][tid].tfds_in_queue,
901 freed); 904 freed);
902 priv->stations[sta_id].tid[tid].tfds_in_queue = 0; 905 priv->shrd->tid_data[sta_id][tid].tfds_in_queue = 0;
903 } 906 }
904} 907}
905 908
@@ -1149,7 +1152,7 @@ void iwlagn_rx_reply_compressed_ba(struct iwl_priv *priv,
1149 txq = &priv->txq[scd_flow]; 1152 txq = &priv->txq[scd_flow];
1150 sta_id = ba_resp->sta_id; 1153 sta_id = ba_resp->sta_id;
1151 tid = ba_resp->tid; 1154 tid = ba_resp->tid;
1152 agg = &priv->stations[sta_id].tid[tid].agg; 1155 agg = &priv->shrd->tid_data[sta_id][tid].agg;
1153 1156
1154 /* Find index of block-ack window */ 1157 /* Find index of block-ack window */
1155 index = ba_resp_scd_ssn & (txq->q.n_bd - 1); 1158 index = ba_resp_scd_ssn & (txq->q.n_bd - 1);
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 37d2043fb7e9..1cf36783c1c3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2203,7 +2203,7 @@ static int iwlagn_mac_suspend(struct ieee80211_hw *hw,
2203 * since the uCode will add 0x10 before using the value. 2203 * since the uCode will add 0x10 before using the value.
2204 */ 2204 */
2205 for (i = 0; i < 8; i++) { 2205 for (i = 0; i < 8; i++) {
2206 seq = priv->stations[IWL_AP_ID].tid[i].seq_number; 2206 seq = priv->shrd->tid_data[IWL_AP_ID][i].seq_number;
2207 seq -= 0x10; 2207 seq -= 0x10;
2208 wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq); 2208 wakeup_filter_cmd.qos_seq[i] = cpu_to_le16(seq);
2209 } 2209 }
diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h
index 56252897ab3e..cb06196e0e80 100644
--- a/drivers/net/wireless/iwlwifi/iwl-commands.h
+++ b/drivers/net/wireless/iwlwifi/iwl-commands.h
@@ -808,6 +808,7 @@ struct iwl_qosparam_cmd {
808#define IWLAGN_STATION_COUNT 16 808#define IWLAGN_STATION_COUNT 16
809 809
810#define IWL_INVALID_STATION 255 810#define IWL_INVALID_STATION 255
811#define IWL_MAX_TID_COUNT 9
811 812
812#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2) 813#define STA_FLG_TX_RATE_MSK cpu_to_le32(1 << 2)
813#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8) 814#define STA_FLG_PWR_SAVE_MSK cpu_to_le32(1 << 8)
diff --git a/drivers/net/wireless/iwlwifi/iwl-debugfs.c b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
index a01beb31d994..e320cc10167e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debugfs.c
+++ b/drivers/net/wireless/iwlwifi/iwl-debugfs.c
@@ -340,6 +340,7 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
340{ 340{
341 struct iwl_priv *priv = file->private_data; 341 struct iwl_priv *priv = file->private_data;
342 struct iwl_station_entry *station; 342 struct iwl_station_entry *station;
343 struct iwl_tid_data *tid_data;
343 int max_sta = hw_params(priv).max_stations; 344 int max_sta = hw_params(priv).max_stations;
344 char *buf; 345 char *buf;
345 int i, j, pos = 0; 346 int i, j, pos = 0;
@@ -363,22 +364,18 @@ static ssize_t iwl_dbgfs_stations_read(struct file *file, char __user *user_buf,
363 i, station->sta.sta.addr, 364 i, station->sta.sta.addr,
364 station->sta.station_flags_msk); 365 station->sta.station_flags_msk);
365 pos += scnprintf(buf + pos, bufsz - pos, 366 pos += scnprintf(buf + pos, bufsz - pos,
366 "TID\tseq_num\ttxq_id\tframes\ttfds\t"); 367 "TID\tseq_num\ttxq_id\ttfds\trate_n_flags\n");
367 pos += scnprintf(buf + pos, bufsz - pos,
368 "start_idx\tbitmap\t\t\trate_n_flags\n");
369 368
370 for (j = 0; j < MAX_TID_COUNT; j++) { 369 for (j = 0; j < IWL_MAX_TID_COUNT; j++) {
370 tid_data = &priv->shrd->tid_data[i][j];
371 pos += scnprintf(buf + pos, bufsz - pos, 371 pos += scnprintf(buf + pos, bufsz - pos,
372 "%d:\t%#x\t%#x\t%u\t%u\t%u\t\t%#.16llx\t%#x", 372 "%d:\t%#x\t%#x\t%u\t%#x",
373 j, station->tid[j].seq_number, 373 j, tid_data->seq_number,
374 station->tid[j].agg.txq_id, 374 tid_data->agg.txq_id,
375 station->tid[j].agg.frame_count, 375 tid_data->tfds_in_queue,
376 station->tid[j].tfds_in_queue, 376 tid_data->agg.rate_n_flags);
377 station->tid[j].agg.start_idx, 377
378 station->tid[j].agg.bitmap, 378 if (tid_data->agg.wait_for_ba)
379 station->tid[j].agg.rate_n_flags);
380
381 if (station->tid[j].agg.wait_for_ba)
382 pos += scnprintf(buf + pos, bufsz - pos, 379 pos += scnprintf(buf + pos, bufsz - pos,
383 " - waitforba"); 380 " - waitforba");
384 pos += scnprintf(buf + pos, bufsz - pos, "\n"); 381 pos += scnprintf(buf + pos, bufsz - pos, "\n");
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index eb98df6e883b..6a6aba052782 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -331,47 +331,9 @@ struct iwl_host_cmd {
331 331
332#define IWL_SUPPORTED_RATES_IE_LEN 8 332#define IWL_SUPPORTED_RATES_IE_LEN 8
333 333
334#define MAX_TID_COUNT 9
335
336#define IWL_INVALID_RATE 0xFF 334#define IWL_INVALID_RATE 0xFF
337#define IWL_INVALID_VALUE -1 335#define IWL_INVALID_VALUE -1
338 336
339/**
340 * struct iwl_ht_agg -- aggregation status while waiting for block-ack
341 * @txq_id: Tx queue used for Tx attempt
342 * @frame_count: # frames attempted by Tx command
343 * @wait_for_ba: Expect block-ack before next Tx reply
344 * @start_idx: Index of 1st Transmit Frame Descriptor (TFD) in Tx window
345 * @bitmap0: Low order bitmap, one bit for each frame pending ACK in Tx window
346 * @bitmap1: High order, one bit for each frame pending ACK in Tx window
347 * @rate_n_flags: Rate at which Tx was attempted
348 *
349 * If REPLY_TX indicates that aggregation was attempted, driver must wait
350 * for block ack (REPLY_COMPRESSED_BA). This struct stores tx reply info
351 * until block ack arrives.
352 */
353struct iwl_ht_agg {
354 u16 txq_id;
355 u16 frame_count;
356 u16 wait_for_ba;
357 u16 start_idx;
358 u64 bitmap;
359 u32 rate_n_flags;
360#define IWL_AGG_OFF 0
361#define IWL_AGG_ON 1
362#define IWL_EMPTYING_HW_QUEUE_ADDBA 2
363#define IWL_EMPTYING_HW_QUEUE_DELBA 3
364 u8 state;
365 u8 tx_fifo;
366};
367
368
369struct iwl_tid_data {
370 u16 seq_number; /* agn only */
371 u16 tfds_in_queue;
372 struct iwl_ht_agg agg;
373};
374
375union iwl_ht_rate_supp { 337union iwl_ht_rate_supp {
376 u16 rates; 338 u16 rates;
377 struct { 339 struct {
@@ -422,7 +384,6 @@ struct iwl_qos_info {
422 */ 384 */
423struct iwl_station_entry { 385struct iwl_station_entry {
424 struct iwl_addsta_cmd sta; 386 struct iwl_addsta_cmd sta;
425 struct iwl_tid_data tid[MAX_TID_COUNT];
426 u8 used, ctxid; 387 u8 used, ctxid;
427 struct iwl_link_quality_cmd *lq; 388 struct iwl_link_quality_cmd *lq;
428}; 389};
diff --git a/drivers/net/wireless/iwlwifi/iwl-shared.h b/drivers/net/wireless/iwlwifi/iwl-shared.h
index 27aee528ce3a..bb61c13d4998 100644
--- a/drivers/net/wireless/iwlwifi/iwl-shared.h
+++ b/drivers/net/wireless/iwlwifi/iwl-shared.h
@@ -68,6 +68,8 @@
68#include <linux/mutex.h> 68#include <linux/mutex.h>
69#include <linux/gfp.h> 69#include <linux/gfp.h>
70 70
71#include "iwl-commands.h"
72
71/*This files includes all the types / functions that are exported by the 73/*This files includes all the types / functions that are exported by the
72 * upper layer to the bus and transport layer */ 74 * upper layer to the bus and transport layer */
73 75
@@ -167,6 +169,34 @@ struct iwl_hw_params {
167}; 169};
168 170
169/** 171/**
172 * struct iwl_ht_agg - aggregation status while waiting for block-ack
173 * @txq_id: Tx queue used for Tx attempt
174 * @wait_for_ba: Expect block-ack before next Tx reply
175 * @rate_n_flags: Rate at which Tx was attempted
176 *
177 * If REPLY_TX indicates that aggregation was attempted, driver must wait
178 * for block ack (REPLY_COMPRESSED_BA). This struct stores tx reply info
179 * until block ack arrives.
180 */
181struct iwl_ht_agg {
182 u16 txq_id;
183 u16 wait_for_ba;
184 u32 rate_n_flags;
185#define IWL_AGG_OFF 0
186#define IWL_AGG_ON 1
187#define IWL_EMPTYING_HW_QUEUE_ADDBA 2
188#define IWL_EMPTYING_HW_QUEUE_DELBA 3
189 u8 state;
190 u8 tx_fifo;
191};
192
193struct iwl_tid_data {
194 u16 seq_number; /* agn only */
195 u16 tfds_in_queue;
196 struct iwl_ht_agg agg;
197};
198
199/**
170 * struct iwl_shared - shared fields for all the layers of the driver 200 * struct iwl_shared - shared fields for all the layers of the driver
171 * 201 *
172 * @dbg_level_dev: dbg level set per device. Prevails on 202 * @dbg_level_dev: dbg level set per device. Prevails on
@@ -200,6 +230,8 @@ struct iwl_shared {
200 spinlock_t lock; 230 spinlock_t lock;
201 spinlock_t sta_lock; 231 spinlock_t sta_lock;
202 struct mutex mutex; 232 struct mutex mutex;
233
234 struct iwl_tid_data tid_data[IWLAGN_STATION_COUNT][IWL_MAX_TID_COUNT];
203}; 235};
204 236
205/*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */ 237/*Whatever _m is (iwl_trans, iwl_priv, iwl_bus, these macros will work */
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
index 3105409bd3cc..9f4ffebfa56d 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-tx-pcie.c
@@ -438,11 +438,11 @@ void iwl_trans_pcie_txq_agg_setup(struct iwl_priv *priv, int sta_id, int tid,
438 438
439 if (WARN_ON(sta_id == IWL_INVALID_STATION)) 439 if (WARN_ON(sta_id == IWL_INVALID_STATION))
440 return; 440 return;
441 if (WARN_ON(tid >= MAX_TID_COUNT)) 441 if (WARN_ON(tid >= IWL_MAX_TID_COUNT))
442 return; 442 return;
443 443
444 spin_lock_irqsave(&priv->shrd->sta_lock, flags); 444 spin_lock_irqsave(&priv->shrd->sta_lock, flags);
445 tid_data = &priv->stations[sta_id].tid[tid]; 445 tid_data = &priv->shrd->tid_data[sta_id][tid];
446 ssn_idx = SEQ_TO_SN(tid_data->seq_number); 446 ssn_idx = SEQ_TO_SN(tid_data->seq_number);
447 txq_id = tid_data->agg.txq_id; 447 txq_id = tid_data->agg.txq_id;
448 tx_fifo = tid_data->agg.tx_fifo; 448 tx_fifo = tid_data->agg.tx_fifo;
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.c b/drivers/net/wireless/iwlwifi/iwl-trans.c
index b95e71389b7c..a18ed425c24c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.c
@@ -1193,7 +1193,7 @@ static void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id,
1193 1193
1194 if (txq->sched_retry) { 1194 if (txq->sched_retry) {
1195 agg_state = 1195 agg_state =
1196 priv->stations[txq->sta_id].tid[txq->tid].agg.state; 1196 priv->shrd->tid_data[txq->sta_id][txq->tid].agg.state;
1197 cond = (agg_state != IWL_EMPTYING_HW_QUEUE_DELBA); 1197 cond = (agg_state != IWL_EMPTYING_HW_QUEUE_DELBA);
1198 } else { 1198 } else {
1199 cond = (status != TX_STATUS_FAIL_PASSIVE_NO_RX); 1199 cond = (status != TX_STATUS_FAIL_PASSIVE_NO_RX);