{
        struct sk_buff *skb = NULL;
 
-       if (skb_queue_len(&p_aggr->free_q) < (AGGR_NUM_OF_FREE_NETBUFS >> 2))
-               ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+       if (skb_queue_len(&p_aggr->rx_amsdu_freeq) <
+           (AGGR_NUM_OF_FREE_NETBUFS >> 2))
+               ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq,
+                                    AGGR_NUM_OF_FREE_NETBUFS);
 
-       skb = skb_dequeue(&p_aggr->free_q);
+       skb = skb_dequeue(&p_aggr->rx_amsdu_freeq);
 
        return skb;
 }
        struct skb_hold_q *node;
        u16 idx, idx_end, seq_end;
        struct rxtid_stats *stats;
+       struct aggr_info_conn *agg_conn;
 
-       if (!p_aggr)
+       if (!p_aggr || !p_aggr->aggr_conn)
                return;
 
-       rxtid = &p_aggr->rx_tid[tid];
-       stats = &p_aggr->stat[tid];
+       agg_conn = p_aggr->aggr_conn;
+       rxtid = &agg_conn->rx_tid[tid];
+       stats = &agg_conn->stat[tid];
 
        idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
 
        stats->num_delivered += skb_queue_len(&rxtid->q);
 
        while ((skb = skb_dequeue(&rxtid->q)))
-               ath6kl_deliver_frames_to_nw_stack(p_aggr->dev, skb);
+               ath6kl_deliver_frames_to_nw_stack(agg_conn->dev, skb);
 }
 
 static bool aggr_process_recv_frm(struct aggr_info *agg_info, u8 tid,
        u16 idx, st, cur, end;
        bool is_queued = false;
        u16 extended_end;
+       struct aggr_info_conn *agg_conn = agg_info->aggr_conn;
 
-       rxtid = &agg_info->rx_tid[tid];
-       stats = &agg_info->stat[tid];
+       rxtid = &agg_conn->rx_tid[tid];
+       stats = &agg_conn->stat[tid];
 
        stats->num_into_aggr++;
 
                        is_queued = true;
                        stats->num_amsdu++;
                        while ((skb = skb_dequeue(&rxtid->q)))
-                               ath6kl_deliver_frames_to_nw_stack(agg_info->dev,
+                               ath6kl_deliver_frames_to_nw_stack(agg_conn->dev,
                                                                  skb);
                }
                return is_queued;
 
        aggr_deque_frms(agg_info, tid, 0, 1);
 
-       if (agg_info->timer_scheduled)
+       if (agg_conn->timer_scheduled)
                rxtid->progress = true;
        else
                for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
                                 * the frame doesn't remain stuck
                                 * forever.
                                 */
-                               agg_info->timer_scheduled = true;
-                               mod_timer(&agg_info->timer,
+                               agg_conn->timer_scheduled = true;
+                               mod_timer(&agg_conn->timer,
                                          (jiffies +
                                           HZ * (AGGR_RX_TIMEOUT) / 1000));
                                rxtid->progress = false;
 static void aggr_timeout(unsigned long arg)
 {
        u8 i, j;
-       struct aggr_info *p_aggr = (struct aggr_info *) arg;
+       struct aggr_info_conn *aggr_conn = (struct aggr_info_conn *) arg;
        struct rxtid *rxtid;
        struct rxtid_stats *stats;
 
        for (i = 0; i < NUM_OF_TIDS; i++) {
-               rxtid = &p_aggr->rx_tid[i];
-               stats = &p_aggr->stat[i];
+               rxtid = &aggr_conn->rx_tid[i];
+               stats = &aggr_conn->stat[i];
 
                if (!rxtid->aggr || !rxtid->timer_mon || rxtid->progress)
                        continue;
                           rxtid->seq_next,
                           ((rxtid->seq_next + rxtid->hold_q_sz-1) &
                            ATH6KL_MAX_SEQ_NO));
-               aggr_deque_frms(p_aggr, i, 0, 0);
+               aggr_deque_frms(aggr_conn->aggr_info, i, 0, 0);
        }
 
-       p_aggr->timer_scheduled = false;
+       aggr_conn->timer_scheduled = false;
 
        for (i = 0; i < NUM_OF_TIDS; i++) {
-               rxtid = &p_aggr->rx_tid[i];
+               rxtid = &aggr_conn->rx_tid[i];
 
                if (rxtid->aggr && rxtid->hold_q) {
                        for (j = 0; j < rxtid->hold_q_sz; j++) {
                                if (rxtid->hold_q[j].skb) {
-                                       p_aggr->timer_scheduled = true;
+                                       aggr_conn->timer_scheduled = true;
                                        rxtid->timer_mon = true;
                                        rxtid->progress = false;
                                        break;
                }
        }
 
-       if (p_aggr->timer_scheduled)
-               mod_timer(&p_aggr->timer,
+       if (aggr_conn->timer_scheduled)
+               mod_timer(&aggr_conn->timer,
                          jiffies + msecs_to_jiffies(AGGR_RX_TIMEOUT));
 }
 
-static void aggr_delete_tid_state(struct aggr_info *p_aggr, u8 tid)
+static void aggr_delete_tid_state(struct aggr_info_conn *aggr_conn, u8 tid)
 {
        struct rxtid *rxtid;
        struct rxtid_stats *stats;
 
-       if (!p_aggr || tid >= NUM_OF_TIDS)
+       if (!aggr_conn || tid >= NUM_OF_TIDS)
                return;
 
-       rxtid = &p_aggr->rx_tid[tid];
-       stats = &p_aggr->stat[tid];
+       rxtid = &aggr_conn->rx_tid[tid];
+       stats = &aggr_conn->stat[tid];
 
        if (rxtid->aggr)
-               aggr_deque_frms(p_aggr, tid, 0, 0);
+               aggr_deque_frms(aggr_conn->aggr_info, tid, 0, 0);
 
        rxtid->aggr = false;
        rxtid->progress = false;
                             u8 win_sz)
 {
        struct aggr_info *p_aggr = vif->aggr_cntxt;
+       struct aggr_info_conn *aggr_conn;
        struct rxtid *rxtid;
        struct rxtid_stats *stats;
        u16 hold_q_size;
 
-       if (!p_aggr)
+       if (!p_aggr || !p_aggr->aggr_conn)
                return;
 
-       rxtid = &p_aggr->rx_tid[tid];
-       stats = &p_aggr->stat[tid];
+       aggr_conn = p_aggr->aggr_conn;
+
+       rxtid = &aggr_conn->rx_tid[tid];
+       stats = &aggr_conn->stat[tid];
 
        if (win_sz < AGGR_WIN_SZ_MIN || win_sz > AGGR_WIN_SZ_MAX)
                ath6kl_dbg(ATH6KL_DBG_WLAN_RX, "%s: win_sz %d, tid %d\n",
                           __func__, win_sz, tid);
 
        if (rxtid->aggr)
-               aggr_delete_tid_state(p_aggr, tid);
+               aggr_delete_tid_state(aggr_conn, tid);
 
        rxtid->seq_next = seq_no;
        hold_q_size = TID_WINDOW_SZ(win_sz) * sizeof(struct skb_hold_q);
        rxtid->aggr = true;
 }
 
-struct aggr_info *aggr_init(struct net_device *dev)
+static void aggr_conn_init(struct ath6kl_vif *vif,
+                          struct aggr_info_conn *aggr_conn)
 {
-       struct aggr_info *p_aggr = NULL;
        struct rxtid *rxtid;
        u8 i;
 
-       p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
-       if (!p_aggr) {
-               ath6kl_err("failed to alloc memory for aggr_node\n");
-               return NULL;
-       }
-
-       p_aggr->aggr_sz = AGGR_SZ_DEFAULT;
-       p_aggr->dev = dev;
-       init_timer(&p_aggr->timer);
-       p_aggr->timer.function = aggr_timeout;
-       p_aggr->timer.data = (unsigned long) p_aggr;
-
-       p_aggr->timer_scheduled = false;
-       skb_queue_head_init(&p_aggr->free_q);
+       aggr_conn->aggr_sz = AGGR_SZ_DEFAULT;
+       aggr_conn->dev = vif->ndev;
+       init_timer(&aggr_conn->timer);
+       aggr_conn->timer.function = aggr_timeout;
+       aggr_conn->timer.data = (unsigned long) aggr_conn;
+       aggr_conn->aggr_info = vif->aggr_cntxt;
 
-       ath6kl_alloc_netbufs(&p_aggr->free_q, AGGR_NUM_OF_FREE_NETBUFS);
+       aggr_conn->timer_scheduled = false;
 
        for (i = 0; i < NUM_OF_TIDS; i++) {
-               rxtid = &p_aggr->rx_tid[i];
+               rxtid = &aggr_conn->rx_tid[i];
                rxtid->aggr = false;
                rxtid->progress = false;
                rxtid->timer_mon = false;
                spin_lock_init(&rxtid->lock);
        }
 
+}
+
+struct aggr_info *aggr_init(struct ath6kl_vif *vif)
+{
+       struct aggr_info *p_aggr = NULL;
+
+       p_aggr = kzalloc(sizeof(struct aggr_info), GFP_KERNEL);
+       if (!p_aggr) {
+               ath6kl_err("failed to alloc memory for aggr_node\n");
+               return NULL;
+       }
+
+       p_aggr->aggr_conn = kzalloc(sizeof(struct aggr_info_conn), GFP_KERNEL);
+       if (!p_aggr->aggr_conn) {
+               ath6kl_err("failed to alloc memory for connection specific aggr info\n");
+               kfree(p_aggr);
+               return NULL;
+       }
+
+       aggr_conn_init(vif, p_aggr->aggr_conn);
+
+       skb_queue_head_init(&p_aggr->rx_amsdu_freeq);
+       ath6kl_alloc_netbufs(&p_aggr->rx_amsdu_freeq, AGGR_NUM_OF_FREE_NETBUFS);
+
        return p_aggr;
 }
 
 {
        struct aggr_info *p_aggr = vif->aggr_cntxt;
        struct rxtid *rxtid;
+       struct aggr_info_conn *aggr_conn;
 
-       if (!p_aggr)
+       if (!p_aggr || !p_aggr->aggr_conn)
                return;
 
-       rxtid = &p_aggr->rx_tid[tid];
+       aggr_conn = p_aggr->aggr_conn;
+       rxtid = &aggr_conn->rx_tid[tid];
 
        if (rxtid->aggr)
-               aggr_delete_tid_state(p_aggr, tid);
+               aggr_delete_tid_state(aggr_conn, tid);
 }
 
 void aggr_reset_state(struct aggr_info *aggr_info)
 {
        u8 tid;
 
-       if (aggr_info->timer_scheduled) {
-               del_timer(&aggr_info->timer);
-               aggr_info->timer_scheduled = false;
+       if (!aggr_info || !aggr_info->aggr_conn)
+               return;
+
+       if (aggr_info->aggr_conn->timer_scheduled) {
+               del_timer(&aggr_info->aggr_conn->timer);
+               aggr_info->aggr_conn->timer_scheduled = false;
        }
 
        for (tid = 0; tid < NUM_OF_TIDS; tid++)
-               aggr_delete_tid_state(aggr_info, tid);
+               aggr_delete_tid_state(aggr_info->aggr_conn, tid);
 }
 
 /* clean up our amsdu buffer list */
 
 void aggr_module_destroy(struct aggr_info *aggr_info)
 {
-       struct rxtid *rxtid;
-       u8 i, k;
-
-       if (!aggr_info)
+       if (!aggr_info || !aggr_info->aggr_conn)
                return;
 
-       if (aggr_info->timer_scheduled) {
-               del_timer(&aggr_info->timer);
-               aggr_info->timer_scheduled = false;
-       }
-
-       for (i = 0; i < NUM_OF_TIDS; i++) {
-               rxtid = &aggr_info->rx_tid[i];
-               if (rxtid->hold_q) {
-                       for (k = 0; k < rxtid->hold_q_sz; k++)
-                               dev_kfree_skb(rxtid->hold_q[k].skb);
-                       kfree(rxtid->hold_q);
-               }
-
-               skb_queue_purge(&rxtid->q);
-       }
-
-       skb_queue_purge(&aggr_info->free_q);
+       aggr_reset_state(aggr_info);
+       skb_queue_purge(&aggr_info->rx_amsdu_freeq);
+       kfree(aggr_info->aggr_conn);
        kfree(aggr_info);
 }