Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
[safe/jmp/linux-2.6] / net / mac80211 / agg-tx.c
index 6ddd114..5e3a7ec 100644 (file)
@@ -91,7 +91,7 @@ static void ieee80211_send_addba_request(struct ieee80211_sub_if_data *sdata,
        mgmt->u.action.u.addba_req.start_seq_num =
                                        cpu_to_le16(start_seq_num << 4);
 
-       ieee80211_tx_skb(sdata, skb, 1);
+       ieee80211_tx_skb(sdata, skb);
 }
 
 void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u16 ssn)
@@ -120,16 +120,22 @@ void ieee80211_send_bar(struct ieee80211_sub_if_data *sdata, u8 *ra, u16 tid, u1
        bar->control = cpu_to_le16(bar_control);
        bar->start_seq_num = cpu_to_le16(ssn);
 
-       ieee80211_tx_skb(sdata, skb, 0);
+       IEEE80211_SKB_CB(skb)->flags |= IEEE80211_TX_INTFL_DONT_ENCRYPT;
+       ieee80211_tx_skb(sdata, skb);
 }
 
-static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
-                                          enum ieee80211_back_parties initiator)
+int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
+                                   enum ieee80211_back_parties initiator)
 {
        struct ieee80211_local *local = sta->local;
        int ret;
        u8 *state;
 
+#ifdef CONFIG_MAC80211_HT_DEBUG
+       printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
+              sta->sta.addr, tid);
+#endif /* CONFIG_MAC80211_HT_DEBUG */
+
        state = &sta->ampdu_mlme.tid_state_tx[tid];
 
        if (*state == HT_AGG_STATE_OPERATIONAL)
@@ -144,7 +150,6 @@ static int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
 
        /* HW shall not deny going back to legacy */
        if (WARN_ON(ret)) {
-               *state = HT_AGG_STATE_OPERATIONAL;
                /*
                 * We may have pending packets get stuck in this case...
                 * Not bothering with a workaround for now.
@@ -174,12 +179,14 @@ static void sta_addba_resp_timer_expired(unsigned long data)
 
        /* check if the TID waits for addBA response */
        spin_lock_bh(&sta->lock);
-       if (!(*state & HT_ADDBA_REQUESTED_MSK)) {
+       if ((*state & (HT_ADDBA_REQUESTED_MSK | HT_ADDBA_RECEIVED_MSK)) !=
+                                               HT_ADDBA_REQUESTED_MSK) {
                spin_unlock_bh(&sta->lock);
                *state = HT_AGG_STATE_IDLE;
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "timer expired on tid %d but we are not "
-                               "expecting addBA response there", tid);
+                               "(or no longer) expecting addBA response there",
+                       tid);
 #endif
                return;
        }
@@ -489,6 +496,7 @@ void ieee80211_start_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
        ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
        memcpy(&ra_tid->ra, ra, ETH_ALEN);
        ra_tid->tid = tid;
+       ra_tid->vif = vif;
 
        skb->pkt_type = IEEE80211_ADDBA_MSG;
        skb_queue_tail(&local->skb_queue, skb);
@@ -511,11 +519,6 @@ int __ieee80211_stop_tx_ba_session(struct sta_info *sta, u16 tid,
                goto unlock;
        }
 
-#ifdef CONFIG_MAC80211_HT_DEBUG
-       printk(KERN_DEBUG "Tx BA session stop requested for %pM tid %u\n",
-              sta->sta.addr, tid);
-#endif /* CONFIG_MAC80211_HT_DEBUG */
-
        ret = ___ieee80211_stop_tx_ba_session(sta, tid, initiator);
 
  unlock:
@@ -530,7 +533,7 @@ int ieee80211_stop_tx_ba_session(struct ieee80211_sta *pubsta, u16 tid,
        struct ieee80211_sub_if_data *sdata = sta->sdata;
        struct ieee80211_local *local = sdata->local;
 
-       if (WARN_ON(!local->ops->ampdu_action))
+       if (!local->ops->ampdu_action)
                return -EINVAL;
 
        if (tid >= STA_TID_NUM)
@@ -625,6 +628,7 @@ void ieee80211_stop_tx_ba_cb_irqsafe(struct ieee80211_vif *vif,
        ra_tid = (struct ieee80211_ra_tid *) &skb->cb;
        memcpy(&ra_tid->ra, ra, ETH_ALEN);
        ra_tid->tid = tid;
+       ra_tid->vif = vif;
 
        skb->pkt_type = IEEE80211_DELBA_MSG;
        skb_queue_tail(&local->skb_queue, skb);
@@ -646,21 +650,21 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
 
        state = &sta->ampdu_mlme.tid_state_tx[tid];
 
-       del_timer_sync(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
-
        spin_lock_bh(&sta->lock);
 
        if (!(*state & HT_ADDBA_REQUESTED_MSK))
-               goto timer_still_needed;
+               goto out;
 
        if (mgmt->u.action.u.addba_resp.dialog_token !=
                sta->ampdu_mlme.tid_tx[tid]->dialog_token) {
 #ifdef CONFIG_MAC80211_HT_DEBUG
                printk(KERN_DEBUG "wrong addBA response token, tid %d\n", tid);
 #endif /* CONFIG_MAC80211_HT_DEBUG */
-               goto timer_still_needed;
+               goto out;
        }
 
+       del_timer(&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 */
@@ -679,10 +683,6 @@ void ieee80211_process_addba_resp(struct ieee80211_local *local,
                ___ieee80211_stop_tx_ba_session(sta, tid, WLAN_BACK_INITIATOR);
        }
 
-       goto out;
-
- timer_still_needed:
-       add_timer(&sta->ampdu_mlme.tid_tx[tid]->addba_resp_timer);
  out:
        spin_unlock_bh(&sta->lock);
 }