Search Linux Wireless

[PATCH v2 2/2] wl12xx: Stop BA session event from device

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Adding new event that close RX BA session in case of periodic BT activity
limiting WLAN activity.

Signed-off-by: Shahar Levi <shahar_levi@xxxxxx>
---
Changes from v1:
- Work queue implementation in mac80211
- wl1271_event_ba() to wl1271_stop_ba_event()
- Align 'struct event_mailbox'
- Mask events in Ap mode
- wl->ba_allowed type from u8 to bool
- Add debug to wl1271_op_ampdu_action()

 drivers/net/wireless/wl12xx/boot.c   |    3 ++-
 drivers/net/wireless/wl12xx/event.c  |   23 +++++++++++++++++++++++
 drivers/net/wireless/wl12xx/event.h  |   17 +++++++++++++++--
 drivers/net/wireless/wl12xx/init.c   |    1 +
 drivers/net/wireless/wl12xx/main.c   |    5 ++++-
 drivers/net/wireless/wl12xx/wl12xx.h |    1 +
 6 files changed, 46 insertions(+), 4 deletions(-)

diff --git a/drivers/net/wireless/wl12xx/boot.c b/drivers/net/wireless/wl12xx/boot.c
index b07f8b7..7ccec07 100644
--- a/drivers/net/wireless/wl12xx/boot.c
+++ b/drivers/net/wireless/wl12xx/boot.c
@@ -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) {
diff --git a/drivers/net/wireless/wl12xx/event.c b/drivers/net/wireless/wl12xx/event.c
index 9102443..0b68f13 100644
--- a/drivers/net/wireless/wl12xx/event.c
+++ b/drivers/net/wireless/wl12xx/event.c
@@ -186,6 +186,21 @@ static void wl12xx_event_soft_gemini_sense(struct wl1271 *wl,
 
 }
 
+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:");
@@ -266,6 +281,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)
diff --git a/drivers/net/wireless/wl12xx/event.h b/drivers/net/wireless/wl12xx/event.h
index b6cf06e..ce99adf 100644
--- a/drivers/net/wireless/wl12xx/event.h
+++ b/drivers/net/wireless/wl12xx/event.h
@@ -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);
diff --git a/drivers/net/wireless/wl12xx/init.c b/drivers/net/wireless/wl12xx/init.c
index b85edcc..741d7a4 100644
--- a/drivers/net/wireless/wl12xx/init.c
+++ b/drivers/net/wireless/wl12xx/init.c
@@ -546,6 +546,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);
diff --git a/drivers/net/wireless/wl12xx/main.c b/drivers/net/wireless/wl12xx/main.c
index fb0f764..94036bb 100644
--- a/drivers/net/wireless/wl12xx/main.c
+++ b/drivers/net/wireless/wl12xx/main.c
@@ -3471,9 +3471,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)
diff --git a/drivers/net/wireless/wl12xx/wl12xx.h b/drivers/net/wireless/wl12xx/wl12xx.h
index 1cafb08..4bc22d8 100644
--- a/drivers/net/wireless/wl12xx/wl12xx.h
+++ b/drivers/net/wireless/wl12xx/wl12xx.h
@@ -571,6 +571,7 @@ struct wl1271 {
 	/* RX BA constraint value */
 	bool ba_support;
 	u8 ba_rx_bitmap;
+	bool ba_allowed;
 
 	int tcxo_clock;
 
-- 
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Host AP]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]
  Powered by Linux