Search Linux Wireless

[PATCH 08/16] wil6210: fix BACK status processing

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

 



When FW notifies about BACK status change, it provides ring ID.
Process BA status for requested connection only. As for now, FW
don't report Rx BACK status, it reports Tx one instead.
As per current algorithm used in the firmware, imply Rx BACK
state is in sync with Tx one

Signed-off-by: Vladimir Kondratiev <qca_vkondrat@xxxxxxxxxxxxxxxx>
---
 drivers/net/wireless/ath/wil6210/wmi.c | 47 ++++++++++++++++++++++------------
 1 file changed, 31 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index dfbc239..635aa32 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -563,27 +563,42 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
 			      int len)
 {
 	struct wmi_vring_ba_status_event *evt = d;
-	uint cid, i;
+	struct wil_sta_info *sta;
+	uint i, cid;
+
+	/* TODO: use Rx BA status, not Tx one */
 
 	wil_dbg_wmi(wil, "BACK[%d] %s {%d} timeout %d\n",
-		    evt->ringid, evt->status == WMI_BA_AGREED ? "OK" : "N/A",
+		    evt->ringid,
+		    evt->status == WMI_BA_AGREED ? "OK" : "N/A",
 		    evt->agg_wsize, __le16_to_cpu(evt->ba_timeout));
-	for (cid = 0; cid < WIL6210_MAX_CID; cid++) {
-		struct wil_sta_info *sta = &wil->sta[cid];
-
-		if (sta->status == wil_sta_unused)
-			continue;
-		wil_dbg_wmi(wil, "Init BACK for CID %d %pM\n", cid, sta->addr);
-		for (i = 0; i < WIL_STA_TID_NUM; i++) {
-			struct wil_tid_ampdu_rx *r = sta->tid_rx[i];
-			sta->tid_rx[i] = NULL;
-			wil_tid_ampdu_rx_free(wil, r);
-			if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize)
-				sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil,
-							evt->agg_wsize, 0);
-		}
+
+	if (evt->ringid >= WIL6210_MAX_TX_RINGS) {
+		wil_err(wil, "invalid ring id %d\n", evt->ringid);
+		return;
 	}
 
+	cid = wil->vring2cid_tid[evt->ringid][0];
+	if (cid >= WIL6210_MAX_CID) {
+		wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid);
+		return;
+	}
+
+	sta = &wil->sta[cid];
+	if (sta->status == wil_sta_unused) {
+		wil_err(wil, "CID %d unused\n", cid);
+		return;
+	}
+
+	wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr);
+	for (i = 0; i < WIL_STA_TID_NUM; i++) {
+		struct wil_tid_ampdu_rx *r = sta->tid_rx[i];
+		sta->tid_rx[i] = NULL;
+		wil_tid_ampdu_rx_free(wil, r);
+		if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize)
+			sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil,
+						evt->agg_wsize, 0);
+	}
 }
 
 static const struct {
-- 
1.8.3.2

--
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 Wireless Personal Area Network]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Linux Kernel]     [IDE]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite Hiking]     [MIPS Linux]     [ARM Linux]     [Linux RAID]

  Powered by Linux