DECLARE_MAC_BUF(mac);
 
        spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
-       state = sta->ampdu_mlme.tid_tx[tid].state;
+       state = sta->ampdu_mlme.tid_state_tx[tid];
        spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
 
        if (state == HT_AGG_STATE_IDLE &&
 
        p += scnprintf(p, sizeof(buf)+buf-p, "\n RX  :");
        for (i = 0; i < STA_TID_NUM; i++)
                p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-       sta->ampdu_mlme.tid_rx[i].state);
+                       sta->ampdu_mlme.tid_state_rx[i]);
 
        p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
        for (i = 0; i < STA_TID_NUM; i++)
                p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-                       sta->ampdu_mlme.tid_rx[i].dialog_token);
+                       sta->ampdu_mlme.tid_state_rx[i]?
+                       sta->ampdu_mlme.tid_rx[i]->dialog_token : 0);
 
        p += scnprintf(p, sizeof(buf)+buf-p, "\n TX  :");
        for (i = 0; i < STA_TID_NUM; i++)
                p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-                       sta->ampdu_mlme.tid_tx[i].state);
+                       sta->ampdu_mlme.tid_state_tx[i]);
 
        p += scnprintf(p, sizeof(buf)+buf-p, "\n DTKN:");
        for (i = 0; i < STA_TID_NUM; i++)
                p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-                       sta->ampdu_mlme.tid_tx[i].dialog_token);
+                       sta->ampdu_mlme.tid_state_tx[i]?
+                       sta->ampdu_mlme.tid_tx[i]->dialog_token : 0);
 
        p += scnprintf(p, sizeof(buf)+buf-p, "\n SSN :");
        for (i = 0; i < STA_TID_NUM; i++)
                p += scnprintf(p, sizeof(buf)+buf-p, "%5d",
-                       sta->ampdu_mlme.tid_tx[i].ssn);
+                       sta->ampdu_mlme.tid_state_tx[i]?
+                       sta->ampdu_mlme.tid_tx[i]->ssn : 0);
 
        p += scnprintf(p, sizeof(buf)+buf-p, "\n");
 
                        strcpy(state, "off ");
                        ieee80211_sta_stop_rx_ba_session(dev, da, tid_num, 0,
                                        WLAN_REASON_QSTA_REQUIRE_SETUP);
-                       sta->ampdu_mlme.tid_rx[tid_num].state |=
+                       sta->ampdu_mlme.tid_state_rx[tid_num] |=
                                        HT_AGG_STATE_DEBUGFS_CTL;
                        tid_static_rx[tid_num] = 0;
                } else {
                        strcpy(state, "on ");
-                       sta->ampdu_mlme.tid_rx[tid_num].state &=
+                       sta->ampdu_mlme.tid_state_rx[tid_num] &=
                                        ~HT_AGG_STATE_DEBUGFS_CTL;
                        tid_static_rx[tid_num] = 1;
                }
 
        spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
 
        /* we have tried too many times, receiver does not want A-MPDU */
-       if (sta->ampdu_mlme.tid_tx[tid].addba_req_num > HT_AGG_MAX_RETRIES) {
+       if (sta->ampdu_mlme.addba_req_num[tid] > HT_AGG_MAX_RETRIES) {
                ret = -EBUSY;
                goto start_ba_exit;
        }
 
-       state = &sta->ampdu_mlme.tid_tx[tid].state;
+       state = &sta->ampdu_mlme.tid_state_tx[tid];
        /* check if the TID is not in aggregation flow already */
        if (*state != HT_AGG_STATE_IDLE) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
                goto start_ba_exit;
        }
 
+       /* prepare A-MPDU MLME for Tx aggregation */
+       sta->ampdu_mlme.tid_tx[tid] =
+                       kmalloc(sizeof(struct tid_ampdu_tx), GFP_ATOMIC);
+       if (!sta->ampdu_mlme.tid_tx[tid]) {
+               if (net_ratelimit())
+                       printk(KERN_ERR "allocate tx mlme to tid %d failed\n",
+                                       tid);
+               ret = -ENOMEM;
+               goto start_ba_exit;
+       }
+       /* Tx timer */
+       sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.function =
+                       sta_addba_resp_timer_expired;
+       sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.data =
+                       (unsigned long)&sta->timer_to_tid[tid];
+       init_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
+
        /* ensure that TX flow won't interrupt us
         * until the end of the call to requeue function */
        spin_lock_bh(&local->mdev->queue_lock);
         * don't switch to aggregation */
        if (ret) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
-               printk(KERN_DEBUG "BA request denied - no queue available for"
+               printk(KERN_DEBUG "BA request denied - queue unavailable for"
                                        " tid %d\n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
-               spin_unlock_bh(&local->mdev->queue_lock);
-               goto start_ba_exit;
+               goto start_ba_err;
        }
        sdata = sta->sdata;
 
                 * allocated queue */
                 ieee80211_ht_agg_queue_remove(local, sta, tid, 0);
 #ifdef CONFIG_MAC80211_HT_DEBUG
-               printk(KERN_DEBUG "BA request denied - HW or queue unavailable"
-                               " for tid %d\n", tid);
+               printk(KERN_DEBUG "BA request denied - HW unavailable for"
+                                       " tid %d\n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
-               spin_unlock_bh(&local->mdev->queue_lock);
                *state = HT_AGG_STATE_IDLE;
-               goto start_ba_exit;
+               goto start_ba_err;
        }
 
        /* Will put all the packets in the new SW queue */
        ieee80211_requeue(local, ieee802_1d_to_ac[tid]);
        spin_unlock_bh(&local->mdev->queue_lock);
 
-       /* We have most probably almost emptied the legacy queue */
-       /* ieee80211_wake_queue(local_to_hw(local), ieee802_1d_to_ac[tid]); */
-
        /* send an addBA request */
        sta->ampdu_mlme.dialog_token_allocator++;
-       sta->ampdu_mlme.tid_tx[tid].dialog_token =
+       sta->ampdu_mlme.tid_tx[tid]->dialog_token =
                        sta->ampdu_mlme.dialog_token_allocator;
-       sta->ampdu_mlme.tid_tx[tid].ssn = start_seq_num;
+       sta->ampdu_mlme.tid_tx[tid]->ssn = start_seq_num;
 
        ieee80211_send_addba_request(sta->sdata->dev, ra, tid,
-                        sta->ampdu_mlme.tid_tx[tid].dialog_token,
-                        sta->ampdu_mlme.tid_tx[tid].ssn,
+                        sta->ampdu_mlme.tid_tx[tid]->dialog_token,
+                        sta->ampdu_mlme.tid_tx[tid]->ssn,
                         0x40, 5000);
 
        /* activate the timer for the recipient's addBA response */
-       sta->ampdu_mlme.tid_tx[tid].addba_resp_timer.expires =
+       sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer.expires =
                                jiffies + ADDBA_RESP_INTERVAL;
-       add_timer(&sta->ampdu_mlme.tid_tx[tid].addba_resp_timer);
+       add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
        printk(KERN_DEBUG "activated addBA response timer on tid %d\n", tid);
+       goto start_ba_exit;
 
+start_ba_err:
+       kfree(sta->ampdu_mlme.tid_tx[tid]);
+       sta->ampdu_mlme.tid_tx[tid] = NULL;
+       spin_unlock_bh(&local->mdev->queue_lock);
+       ret = -EBUSY;
 start_ba_exit:
        spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
        rcu_read_unlock();
        }
 
        /* check if the TID is in aggregation */
-       state = &sta->ampdu_mlme.tid_tx[tid].state;
+       state = &sta->ampdu_mlme.tid_state_tx[tid];
        spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
 
        if (*state != HT_AGG_STATE_OPERATIONAL) {
                return;
        }
 
-       state = &sta->ampdu_mlme.tid_tx[tid].state;
+       state = &sta->ampdu_mlme.tid_state_tx[tid];
        spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
 
        if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
                rcu_read_unlock();
                return;
        }
-       state = &sta->ampdu_mlme.tid_tx[tid].state;
+       state = &sta->ampdu_mlme.tid_state_tx[tid];
 
        spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
        if ((*state & HT_AGG_STATE_REQ_STOP_BA_MSK) == 0) {
         * necessarily stopped */
        netif_schedule(local->mdev);
        *state = HT_AGG_STATE_IDLE;
-       sta->ampdu_mlme.tid_tx[tid].addba_req_num = 0;
+       sta->ampdu_mlme.addba_req_num[tid] = 0;
+       kfree(sta->ampdu_mlme.tid_tx[tid]);
+       sta->ampdu_mlme.tid_tx[tid] = NULL;
        spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
 
        rcu_read_unlock();
 
                buf_size = buf_size << sband->ht_info.ampdu_factor;
        }
 
-       tid_agg_rx = &sta->ampdu_mlme.tid_rx[tid];
 
        /* examine state machine */
        spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
 
-       if (tid_agg_rx->state != HT_AGG_STATE_IDLE) {
+       if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_IDLE) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
                if (net_ratelimit())
                        printk(KERN_DEBUG "unexpected AddBA Req from "
                goto end;
        }
 
+       /* prepare A-MPDU MLME for Rx aggregation */
+       sta->ampdu_mlme.tid_rx[tid] =
+                       kmalloc(sizeof(struct tid_ampdu_rx), GFP_ATOMIC);
+       if (!sta->ampdu_mlme.tid_rx[tid]) {
+               if (net_ratelimit())
+                       printk(KERN_ERR "allocate rx mlme to tid %d failed\n",
+                                       tid);
+               goto end;
+       }
+       /* rx timer */
+       sta->ampdu_mlme.tid_rx[tid]->session_timer.function =
+                               sta_rx_agg_session_timer_expired;
+       sta->ampdu_mlme.tid_rx[tid]->session_timer.data =
+                               (unsigned long)&sta->timer_to_tid[tid];
+       init_timer(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
+
+       tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
+
        /* prepare reordering buffer */
        tid_agg_rx->reorder_buf =
                kmalloc(buf_size * sizeof(struct sk_buf *), GFP_ATOMIC);
                if (net_ratelimit())
                        printk(KERN_ERR "can not allocate reordering buffer "
                               "to tid %d\n", tid);
+               kfree(sta->ampdu_mlme.tid_rx[tid]);
                goto end;
        }
        memset(tid_agg_rx->reorder_buf, 0,
 
        if (ret) {
                kfree(tid_agg_rx->reorder_buf);
+               kfree(tid_agg_rx);
+               sta->ampdu_mlme.tid_rx[tid] = NULL;
                goto end;
        }
 
        /* change state and send addba resp */
-       tid_agg_rx->state = HT_AGG_STATE_OPERATIONAL;
+       sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_OPERATIONAL;
        tid_agg_rx->dialog_token = dialog_token;
        tid_agg_rx->ssn = start_seq_num;
        tid_agg_rx->head_seq_num = start_seq_num;
        capab = le16_to_cpu(mgmt->u.action.u.addba_resp.capab);
        tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
 
-       state = &sta->ampdu_mlme.tid_tx[tid].state;
+       state = &sta->ampdu_mlme.tid_state_tx[tid];
 
        spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
 
+       if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
+               spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
+               printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
+                       "%d\n", *state);
+               goto addba_resp_exit;
+       }
+
        if (mgmt->u.action.u.addba_resp.dialog_token !=
-               sta->ampdu_mlme.tid_tx[tid].dialog_token) {
+               sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
                spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
-               rcu_read_unlock();
-               return;
+               goto addba_resp_exit;
        }
 
-       del_timer_sync(&sta->ampdu_mlme.tid_tx[tid].addba_resp_timer);
+       del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
 #ifdef CONFIG_MAC80211_HT_DEBUG
        printk(KERN_DEBUG "switched off addBA timer for tid %d \n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
        if (le16_to_cpu(mgmt->u.action.u.addba_resp.status)
                        == WLAN_STATUS_SUCCESS) {
-               if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
-                       spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
-                       printk(KERN_DEBUG "state not HT_ADDBA_REQUESTED_MSK:"
-                               "%d\n", *state);
-                       rcu_read_unlock();
-                       return;
-               }
-
                if (*state & HT_ADDBA_RECEIVED_MSK)
                        printk(KERN_DEBUG "double addBA response\n");
 
                *state |= HT_ADDBA_RECEIVED_MSK;
-               sta->ampdu_mlme.tid_tx[tid].addba_req_num = 0;
+               sta->ampdu_mlme.addba_req_num[tid] = 0;
 
                if (*state == HT_AGG_STATE_OPERATIONAL) {
                        printk(KERN_DEBUG "Aggregation on for tid %d \n", tid);
        } else {
                printk(KERN_DEBUG "recipient rejected agg: tid %d \n", tid);
 
-               sta->ampdu_mlme.tid_tx[tid].addba_req_num++;
+               sta->ampdu_mlme.addba_req_num[tid]++;
                /* this will allow the state check in stop_BA_session */
                *state = HT_AGG_STATE_OPERATIONAL;
                spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
                ieee80211_stop_tx_ba_session(hw, sta->addr, tid,
                                             WLAN_BACK_INITIATOR);
        }
+
+addba_resp_exit:
        rcu_read_unlock();
 }
 
 
        /* check if TID is in operational state */
        spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
-       if (sta->ampdu_mlme.tid_rx[tid].state
+       if (sta->ampdu_mlme.tid_state_rx[tid]
                                != HT_AGG_STATE_OPERATIONAL) {
                spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
                rcu_read_unlock();
                return;
        }
-       sta->ampdu_mlme.tid_rx[tid].state =
+       sta->ampdu_mlme.tid_state_rx[tid] =
                HT_AGG_STATE_REQ_STOP_BA_MSK |
                (initiator << HT_AGG_STATE_INITIATOR_SHIFT);
                spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
 
        /* shutdown timer has not expired */
        if (initiator != WLAN_BACK_TIMER)
-               del_timer_sync(&sta->ampdu_mlme.tid_rx[tid].
-                                       session_timer);
+               del_timer_sync(&sta->ampdu_mlme.tid_rx[tid]->session_timer);
 
        /* check if this is a self generated aggregation halt */
        if (initiator == WLAN_BACK_RECIPIENT || initiator == WLAN_BACK_TIMER)
                ieee80211_send_delba(dev, ra, tid, 0, reason);
 
        /* free the reordering buffer */
-       for (i = 0; i < sta->ampdu_mlme.tid_rx[tid].buf_size; i++) {
-               if (sta->ampdu_mlme.tid_rx[tid].reorder_buf[i]) {
+       for (i = 0; i < sta->ampdu_mlme.tid_rx[tid]->buf_size; i++) {
+               if (sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]) {
                        /* release the reordered frames */
-                       dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid].reorder_buf[i]);
-                       sta->ampdu_mlme.tid_rx[tid].stored_mpdu_num--;
-                       sta->ampdu_mlme.tid_rx[tid].reorder_buf[i] = NULL;
+                       dev_kfree_skb(sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i]);
+                       sta->ampdu_mlme.tid_rx[tid]->stored_mpdu_num--;
+                       sta->ampdu_mlme.tid_rx[tid]->reorder_buf[i] = NULL;
                }
        }
-       kfree(sta->ampdu_mlme.tid_rx[tid].reorder_buf);
+       /* free resources */
+       kfree(sta->ampdu_mlme.tid_rx[tid]->reorder_buf);
+       kfree(sta->ampdu_mlme.tid_rx[tid]);
+       sta->ampdu_mlme.tid_rx[tid] = NULL;
+       sta->ampdu_mlme.tid_state_rx[tid] = HT_AGG_STATE_IDLE;
 
-       sta->ampdu_mlme.tid_rx[tid].state = HT_AGG_STATE_IDLE;
        rcu_read_unlock();
 }
 
                                                 WLAN_BACK_INITIATOR, 0);
        else { /* WLAN_BACK_RECIPIENT */
                spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
-               sta->ampdu_mlme.tid_tx[tid].state =
+               sta->ampdu_mlme.tid_state_tx[tid] =
                                HT_AGG_STATE_OPERATIONAL;
                spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
                ieee80211_stop_tx_ba_session(&local->hw, sta->addr, tid,
                return;
        }
 
-       state = &sta->ampdu_mlme.tid_tx[tid].state;
+       state = &sta->ampdu_mlme.tid_state_tx[tid];
        /* check if the TID waits for addBA response */
        spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
        if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
 
                if (!rx->sta)
                        return RX_CONTINUE;
                tid = le16_to_cpu(bar->control) >> 12;
-               tid_agg_rx = &(rx->sta->ampdu_mlme.tid_rx[tid]);
-               if (tid_agg_rx->state != HT_AGG_STATE_OPERATIONAL)
+               if (rx->sta->ampdu_mlme.tid_state_rx[tid]
+                                       != HT_AGG_STATE_OPERATIONAL)
                        return RX_CONTINUE;
+               tid_agg_rx = rx->sta->ampdu_mlme.tid_rx[tid];
 
                start_seq_num = le16_to_cpu(bar->start_seq_num) >> 4;
 
 
        qc = skb->data + ieee80211_get_hdrlen(fc) - QOS_CONTROL_LEN;
        tid = qc[0] & QOS_CONTROL_TID_MASK;
-       tid_agg_rx = &(sta->ampdu_mlme.tid_rx[tid]);
 
-       if (tid_agg_rx->state != HT_AGG_STATE_OPERATIONAL)
+       if (sta->ampdu_mlme.tid_state_rx[tid] != HT_AGG_STATE_OPERATIONAL)
                goto end_reorder;
 
+       tid_agg_rx = sta->ampdu_mlme.tid_rx[tid];
+
        /* null data frames are excluded */
        if (unlikely(fc & IEEE80211_STYPE_NULLFUNC))
                goto end_reorder;
 
                dev_kfree_skb_any(skb);
 
        for (i = 0; i <  STA_TID_NUM; i++) {
-               del_timer_sync(&sta->ampdu_mlme.tid_rx[i].session_timer);
-               del_timer_sync(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer);
+               spin_lock_bh(&sta->ampdu_mlme.ampdu_rx);
+               if (sta->ampdu_mlme.tid_rx[i])
+                 del_timer_sync(&sta->ampdu_mlme.tid_rx[i]->session_timer);
+               spin_unlock_bh(&sta->ampdu_mlme.ampdu_rx);
+               spin_lock_bh(&sta->ampdu_mlme.ampdu_tx);
+               if (sta->ampdu_mlme.tid_tx[i])
+                 del_timer_sync(&sta->ampdu_mlme.tid_tx[i]->addba_resp_timer);
+               spin_unlock_bh(&sta->ampdu_mlme.ampdu_tx);
        }
+
        rate_control_free_sta(sta->rate_ctrl, sta->rate_ctrl_priv);
        rate_control_put(sta->rate_ctrl);
 
                sta->timer_to_tid[i] = i;
                /* tid to tx queue: initialize according to HW (0 is valid) */
                sta->tid_to_tx_q[i] = local->hw.queues;
-               /* rx timers */
-               sta->ampdu_mlme.tid_rx[i].session_timer.function =
-                       sta_rx_agg_session_timer_expired;
-               sta->ampdu_mlme.tid_rx[i].session_timer.data =
-                       (unsigned long)&sta->timer_to_tid[i];
-               init_timer(&sta->ampdu_mlme.tid_rx[i].session_timer);
-               /* tx timers */
-               sta->ampdu_mlme.tid_tx[i].addba_resp_timer.function =
-                       sta_addba_resp_timer_expired;
-               sta->ampdu_mlme.tid_tx[i].addba_resp_timer.data =
-                       (unsigned long)&sta->timer_to_tid[i];
-               init_timer(&sta->ampdu_mlme.tid_tx[i].addba_resp_timer);
+               /* rx */
+               sta->ampdu_mlme.tid_state_rx[i] = HT_AGG_STATE_IDLE;
+               sta->ampdu_mlme.tid_rx[i] = NULL;
+               /* tx */
+               sta->ampdu_mlme.tid_state_tx[i] = HT_AGG_STATE_IDLE;
+               sta->ampdu_mlme.tid_tx[i] = NULL;
+               sta->ampdu_mlme.addba_req_num[i] = 0;
        }
        skb_queue_head_init(&sta->ps_tx_buf);
        skb_queue_head_init(&sta->tx_filtered);
 
 /**
  * struct tid_ampdu_tx - TID aggregation information (Tx).
  *
- * @state: TID's state in session state machine.
- * @dialog_token: dialog token for aggregation session
- * @ssn: Starting Sequence Number expected to be aggregated.
  * @addba_resp_timer: timer for peer's response to addba request
- * @addba_req_num: number of times addBA request has been sent.
+ * @ssn: Starting Sequence Number expected to be aggregated.
+ * @dialog_token: dialog token for aggregation session
  */
 struct tid_ampdu_tx {
-       u8 state;
-       u8 dialog_token;
-       u16 ssn;
        struct timer_list addba_resp_timer;
-       u8 addba_req_num;
+       u16 ssn;
+       u8 dialog_token;
 };
 
 /**
  * struct tid_ampdu_rx - TID aggregation information (Rx).
  *
- * @state: TID's state in session state machine.
- * @dialog_token: dialog token for aggregation session
- * @ssn: Starting Sequence Number expected to be aggregated.
- * @buf_size: buffer size for incoming A-MPDUs
- * @timeout: reset timer value.
  * @head_seq_num: head sequence number in reordering buffer.
  * @stored_mpdu_num: number of MPDUs in reordering buffer
  * @reorder_buf: buffer to reorder incoming aggregated MPDUs
  * @session_timer: check if peer keeps Tx-ing on the TID (by timeout value)
+ * @ssn: Starting Sequence Number expected to be aggregated.
+ * @buf_size: buffer size for incoming A-MPDUs
+ * @timeout: reset timer value.
+ * @dialog_token: dialog token for aggregation session
  */
 struct tid_ampdu_rx {
-       u8 state;
-       u8 dialog_token;
-       u16 ssn;
-       u16 buf_size;
-       u16 timeout;
        u16 head_seq_num;
        u16 stored_mpdu_num;
        struct sk_buff **reorder_buf;
        struct timer_list session_timer;
+       u16 ssn;
+       u16 buf_size;
+       u16 timeout;
+       u8 dialog_token;
 };
 
 /**
 /**
  * struct sta_ampdu_mlme - STA aggregation information.
  *
+ * @tid_state_rx: TID's state in Rx session state machine.
  * @tid_rx: aggregation info for Rx per TID
- * @tid_tx: aggregation info for Tx per TID
  * @ampdu_rx: for locking sections in aggregation Rx flow
+ * @tid_state_tx: TID's state in Tx session state machine.
+ * @tid_tx: aggregation info for Tx per TID
+ * @addba_req_num: number of times addBA request has been sent.
  * @ampdu_tx: for locking sectionsi in aggregation Tx flow
  * @dialog_token_allocator: dialog token enumerator for each new session;
  */
 struct sta_ampdu_mlme {
-       struct tid_ampdu_rx tid_rx[STA_TID_NUM];
-       struct tid_ampdu_tx tid_tx[STA_TID_NUM];
+       /* rx */
+       u8 tid_state_rx[STA_TID_NUM];
+       struct tid_ampdu_rx *tid_rx[STA_TID_NUM];
        spinlock_t ampdu_rx;
+       /* tx */
+       u8 tid_state_tx[STA_TID_NUM];
+       struct tid_ampdu_tx *tid_tx[STA_TID_NUM];
+       u8 addba_req_num[STA_TID_NUM];
        spinlock_t ampdu_tx;
        u8 dialog_token_allocator;
 };