mac80211: Stop BA session event from device
authorShahar Levi <shahar_levi@ti.com>
Sun, 22 May 2011 13:10:21 +0000 (16:10 +0300)
committerJohn W. Linville <linville@tuxdriver.com>
Tue, 7 Jun 2011 18:41:36 +0000 (14:41 -0400)
Some devices support BT/WLAN co-existence algorigthms.
In order not to harm the system performance and user experience, the device
requests not to allow any RX BA session and tear down existing RX BA sessions
based on system constraints such as periodic BT activity that needs to limit
WLAN activity (eg.SCO or A2DP).
In such cases, the intention is to limit the duration of the RX PPDU and
therefore prevent the peer device to use A-MPDU aggregation.

Adding ieee80211_stop_rx_ba_session() callback
that can be used by the driver to stop existing BA sessions.

Signed-off-by: Shahar Levi <shahar_levi@ti.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
include/net/mac80211.h
net/mac80211/agg-rx.c
net/mac80211/ht.c
net/mac80211/sta_info.h

index b250c6303d6fc8d05c5ebca50e78222bd19b76ef..3b31ec95dd8e938df43f4478cdd0e455eba09776 100644 (file)
@@ -2969,6 +2969,23 @@ void ieee80211_ready_on_channel(struct ieee80211_hw *hw);
  */
 void ieee80211_remain_on_channel_expired(struct ieee80211_hw *hw);
 
+/**
+ * ieee80211_stop_rx_ba_session - callback to stop existing BA sessions
+ *
+ * in order not to harm the system performance and user experience, the device
+ * may request not to allow any rx ba session and tear down existing rx ba
+ * sessions based on system constraints such as periodic BT activity that needs
+ * to limit wlan activity (eg.sco or a2dp)."
+ * in such cases, the intention is to limit the duration of the rx ppdu and
+ * therefore prevent the peer device to use a-mpdu aggregation.
+ *
+ * @vif: &struct ieee80211_vif pointer from the add_interface callback.
+ * @ba_rx_bitmap: Bit map of open rx ba per tid
+ * @addr: & to bssid mac address
+ */
+void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
+                                 const u8 *addr);
+
 /* Rate control API */
 
 /**
index 9c0d76cdca920ed3b322c4b70ed86f044b4a404b..89b0b2ca6db673978057ae8754e3a6f0af10963b 100644 (file)
@@ -100,6 +100,21 @@ void __ieee80211_stop_rx_ba_session(struct sta_info *sta, u16 tid,
        mutex_unlock(&sta->ampdu_mlme.mtx);
 }
 
+void ieee80211_stop_rx_ba_session(struct ieee80211_vif *vif, u16 ba_rx_bitmap,
+                                 const u8 *addr)
+{
+       struct ieee80211_sub_if_data *sdata = vif_to_sdata(vif);
+       struct sta_info *sta = sta_info_get(sdata, addr);
+       int i;
+
+       for (i = 0; i < STA_TID_NUM; i++)
+               if (ba_rx_bitmap & BIT(i))
+                       set_bit(i, sta->ampdu_mlme.tid_rx_stop_requested);
+
+       ieee80211_queue_work(&sta->local->hw, &sta->ampdu_mlme.work);
+}
+EXPORT_SYMBOL(ieee80211_stop_rx_ba_session);
+
 /*
  * After accepting the AddBA Request we activated a timer,
  * resetting it after each frame that arrives from the originator.
index 591add22bcc07e178fe3ffe6215aa2cf84fcf7cc..7cfc286946c07db43e5b41b0705f827f9551f59b 100644 (file)
@@ -140,6 +140,12 @@ void ieee80211_ba_session_work(struct work_struct *work)
                                sta, tid, WLAN_BACK_RECIPIENT,
                                WLAN_REASON_QSTA_TIMEOUT, true);
 
+               if (test_and_clear_bit(tid,
+                                      sta->ampdu_mlme.tid_rx_stop_requested))
+                       ___ieee80211_stop_rx_ba_session(
+                               sta, tid, WLAN_BACK_RECIPIENT,
+                               WLAN_REASON_UNSPECIFIED, true);
+
                tid_tx = sta->ampdu_mlme.tid_start_tx[tid];
                if (tid_tx) {
                        /*
index c6ae8718bd571f5d37ab7687d5894056d1b35837..a06d64ebc1776bba755454d58a33e255eb5ebb56 100644 (file)
@@ -158,6 +158,8 @@ struct tid_ampdu_rx {
  * @work: work struct for starting/stopping aggregation
  * @tid_rx_timer_expired: bitmap indicating on which TIDs the
  *     RX timer expired until the work for it runs
+ * @tid_rx_stop_requested:  bitmap indicating which BA sessions per TID the
+ *     driver requested to close until the work for it runs
  * @mtx: mutex to protect all TX data (except non-NULL assignments
  *     to tid_tx[idx], which are protected by the sta spinlock)
  */
@@ -166,6 +168,7 @@ struct sta_ampdu_mlme {
        /* rx */
        struct tid_ampdu_rx __rcu *tid_rx[STA_TID_NUM];
        unsigned long tid_rx_timer_expired[BITS_TO_LONGS(STA_TID_NUM)];
+       unsigned long tid_rx_stop_requested[BITS_TO_LONGS(STA_TID_NUM)];
        /* tx */
        struct work_struct work;
        struct tid_ampdu_tx __rcu *tid_tx[STA_TID_NUM];