struct sk_buff_head q;
 
        /*
-        * FIXME: No clue what this should protect. Apparently it should
-        * protect some of the fields above but they are also accessed
-        * without taking the lock.
+        * lock mainly protects seq_next and hold_q. Movement of seq_next
+        * needs to be protected between aggr_timeout() and
+        * aggr_process_recv_frm(). hold_q will be holding the pending
+        * reorder frames and it's access should also be protected.
+        * Some of the other fields like hold_q_sz, win_sz and aggr are
+        * initialized/reset when receiving addba/delba req, also while
+        * deleting aggr state all the pending buffers are flushed before
+        * resetting these fields, so there should not be any race in accessing
+        * these fields.
         */
        spinlock_t lock;
 };
 
        rxtid = &agg_conn->rx_tid[tid];
        stats = &agg_conn->stat[tid];
 
+       spin_lock_bh(&rxtid->lock);
        idx = AGGR_WIN_IDX(rxtid->seq_next, rxtid->hold_q_sz);
 
        /*
        seq_end = seq_no ? seq_no : rxtid->seq_next;
        idx_end = AGGR_WIN_IDX(seq_end, rxtid->hold_q_sz);
 
-       spin_lock_bh(&rxtid->lock);
-
        do {
                node = &rxtid->hold_q[idx];
                if ((order == 1) && (!node->skb))
                    ((end > extended_end) && (cur > extended_end) &&
                     (cur < end))) {
                        aggr_deque_frms(agg_conn, tid, 0, 0);
+                       spin_lock_bh(&rxtid->lock);
                        if (cur >= rxtid->hold_q_sz - 1)
                                rxtid->seq_next = cur - (rxtid->hold_q_sz - 1);
                        else
                                rxtid->seq_next = ATH6KL_MAX_SEQ_NO -
                                                  (rxtid->hold_q_sz - 2 - cur);
+                       spin_unlock_bh(&rxtid->lock);
                } else {
                        /*
                         * Dequeue only those frames that are outside the
 
        if (agg_conn->timer_scheduled)
                rxtid->progress = true;
-       else
+       else {
+               spin_lock_bh(&rxtid->lock);
                for (idx = 0 ; idx < rxtid->hold_q_sz; idx++) {
                        if (rxtid->hold_q[idx].skb) {
                                /*
                                break;
                        }
                }
+               spin_unlock_bh(&rxtid->lock);
+       }
 
        return is_queued;
 }
                rxtid = &aggr_conn->rx_tid[i];
 
                if (rxtid->aggr && rxtid->hold_q) {
+                       spin_lock_bh(&rxtid->lock);
                        for (j = 0; j < rxtid->hold_q_sz; j++) {
                                if (rxtid->hold_q[j].skb) {
                                        aggr_conn->timer_scheduled = true;
                                        break;
                                }
                        }
+                       spin_unlock_bh(&rxtid->lock);
 
                        if (j >= rxtid->hold_q_sz)
                                rxtid->timer_mon = false;