wl12xx: Stop BA session event from device
Shahar Levi [Sun, 22 May 2011 13:10:22 +0000 (16:10 +0300)]
Adding new event that close RX BA session in case of periodic BT activity
limiting WLAN activity.

Signed-off-by: Shahar Levi <shahar_levi@ti.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>

drivers/net/wireless/wl12xx/boot.c
drivers/net/wireless/wl12xx/event.c
drivers/net/wireless/wl12xx/event.h
drivers/net/wireless/wl12xx/init.c
drivers/net/wireless/wl12xx/main.c
drivers/net/wireless/wl12xx/wl12xx.h

index b07f8b7..7ccec07 100644 (file)
@@ -485,7 +485,8 @@ static int wl1271_boot_run_firmware(struct wl1271 *wl)
        if (wl->bss_type == BSS_TYPE_AP_BSS)
                wl->event_mask |= STA_REMOVE_COMPLETE_EVENT_ID;
        else
-               wl->event_mask |= DUMMY_PACKET_EVENT_ID;
+               wl->event_mask |= DUMMY_PACKET_EVENT_ID |
+                       BA_SESSION_RX_CONSTRAINT_EVENT_ID;
 
        ret = wl1271_event_unmask(wl);
        if (ret < 0) {
index c3c554c..94bbd00 100644 (file)
@@ -168,6 +168,21 @@ static void wl1271_event_rssi_trigger(struct wl1271 *wl,
        wl->last_rssi_event = event;
 }
 
+static void wl1271_stop_ba_event(struct wl1271 *wl, u8 ba_allowed)
+{
+       /* Convert the value to bool */
+       wl->ba_allowed = !!ba_allowed;
+
+       /*
+        * Return in case:
+        * there are not BA open or the event indication is to allowed BA
+        */
+       if ((!wl->ba_rx_bitmap) || (wl->ba_allowed))
+               return;
+
+       ieee80211_stop_rx_ba_session(wl->vif, wl->ba_rx_bitmap, wl->bssid);
+}
+
 static void wl1271_event_mbox_dump(struct event_mailbox *mbox)
 {
        wl1271_debug(DEBUG_EVENT, "MBOX DUMP:");
@@ -252,6 +267,14 @@ static int wl1271_event_process(struct wl1271 *wl, struct event_mailbox *mbox)
                        wl1271_event_rssi_trigger(wl, mbox);
        }
 
+       if ((vector & BA_SESSION_RX_CONSTRAINT_EVENT_ID) && !is_ap) {
+               wl1271_debug(DEBUG_EVENT, "BA_SESSION_RX_CONSTRAINT_EVENT_ID. "
+                            "ba_allowed = 0x%x", mbox->ba_allowed);
+
+               if (wl->vif)
+                       wl1271_stop_ba_event(wl, mbox->ba_allowed);
+       }
+
        if ((vector & DUMMY_PACKET_EVENT_ID) && !is_ap) {
                wl1271_debug(DEBUG_EVENT, "DUMMY_PACKET_ID_EVENT_ID");
                if (wl->vif)
index b6cf06e..ce99adf 100644 (file)
@@ -71,7 +71,7 @@ enum {
        HEALTH_CHECK_REPLY_EVENT_ID              = BIT(27),
        PERIODIC_SCAN_COMPLETE_EVENT_ID          = BIT(28),
        PERIODIC_SCAN_REPORT_EVENT_ID            = BIT(29),
-       BA_SESSION_TEAR_DOWN_EVENT_ID            = BIT(30),
+       BA_SESSION_RX_CONSTRAINT_EVENT_ID        = BIT(30),
        EVENT_MBOX_ALL_EVENT_ID                  = 0x7fffffff,
 };
 
@@ -122,7 +122,20 @@ struct event_mailbox {
        __le16 sta_aging_status;
        __le16 sta_tx_retry_exceeded;
 
-       u8 reserved_5[24];
+       /*
+        * Bitmap, Each bit set represents the Role ID for which this constraint
+        * is set. Range: 0 - FF, FF means ANY role
+        */
+       u8 ba_role_id;
+       /*
+        * Bitmap, Each bit set represents the Link ID for which this constraint
+        * is set. Not applicable if ba_role_id is set to ANY role (FF).
+        * Range: 0 - FFFF, FFFF means ANY link in that role
+        */
+       u8 ba_link_id;
+       u8 ba_allowed;
+
+       u8 reserved_5[21];
 } __packed;
 
 int wl1271_event_unmask(struct wl1271 *wl);
index a8f4f15..f5c2c9e 100644 (file)
@@ -541,6 +541,7 @@ static int wl1271_set_ba_policies(struct wl1271 *wl)
 
        /* Reset the BA RX indicators */
        wl->ba_rx_bitmap = 0;
+       wl->ba_allowed = true;
 
        /* validate that FW support BA */
        wl1271_check_ba_support(wl);
index e6497dc..f37f0b8 100644 (file)
@@ -3354,9 +3354,12 @@ static int wl1271_op_ampdu_action(struct ieee80211_hw *hw,
        if (ret < 0)
                goto out;
 
+       wl1271_debug(DEBUG_MAC80211, "mac80211 ampdu: Rx tid %d action %d",
+                    tid, action);
+
        switch (action) {
        case IEEE80211_AMPDU_RX_START:
-               if (wl->ba_support) {
+               if ((wl->ba_support) && (wl->ba_allowed)) {
                        ret = wl1271_acx_set_ba_receiver_session(wl, tid, *ssn,
                                                                 true);
                        if (!ret)
index fbe8f46..3bc794a 100644 (file)
@@ -564,6 +564,7 @@ struct wl1271 {
        /* RX BA constraint value */
        bool ba_support;
        u8 ba_rx_bitmap;
+       bool ba_allowed;
 
        int tcxo_clock;