This updates mac80211 to backports version 4.19.23-1 which includes all the stable fixes from kernel 4.19.23. The removed patches are included in this version. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
		
			
				
	
	
		
			230 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			230 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
From e4af3ffb43d50f070134aa1b40d5c3573f57deb1 Mon Sep 17 00:00:00 2001
 | 
						|
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
 | 
						|
Date: Mon, 5 Nov 2018 05:52:05 +0000
 | 
						|
Subject: [PATCH] brcmfmac: handle compressed tx status signal
 | 
						|
 | 
						|
Firmware inform the driver about tx status by normal tx status signal
 | 
						|
or compressed tx status signal. This patch adds support to handle the
 | 
						|
compressed tx status signal.
 | 
						|
 | 
						|
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
 | 
						|
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
 | 
						|
Signed-off-by: Wright Feng <wright.feng@cypress.com>
 | 
						|
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
 | 
						|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
 | 
						|
---
 | 
						|
 .../broadcom/brcm80211/brcmfmac/fwsignal.c    | 121 ++++++++++--------
 | 
						|
 1 file changed, 71 insertions(+), 50 deletions(-)
 | 
						|
 | 
						|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
 | 
						|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
 | 
						|
@@ -1455,9 +1455,10 @@ static int brcmf_fws_txstatus_suppressed
 | 
						|
 
 | 
						|
 static int
 | 
						|
 brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
 | 
						|
-		      u32 genbit, u16 seq)
 | 
						|
+		      u32 genbit, u16 seq, u8 compcnt)
 | 
						|
 {
 | 
						|
 	u32 fifo;
 | 
						|
+	u8 cnt = 0;
 | 
						|
 	int ret;
 | 
						|
 	bool remove_from_hanger = true;
 | 
						|
 	struct sk_buff *skb;
 | 
						|
@@ -1468,60 +1469,71 @@ brcmf_fws_txs_process(struct brcmf_fws_i
 | 
						|
 	brcmf_dbg(DATA, "flags %d\n", flags);
 | 
						|
 
 | 
						|
 	if (flags == BRCMF_FWS_TXSTATUS_DISCARD)
 | 
						|
-		fws->stats.txs_discard++;
 | 
						|
+		fws->stats.txs_discard += compcnt;
 | 
						|
 	else if (flags == BRCMF_FWS_TXSTATUS_CORE_SUPPRESS) {
 | 
						|
-		fws->stats.txs_supp_core++;
 | 
						|
+		fws->stats.txs_supp_core += compcnt;
 | 
						|
 		remove_from_hanger = false;
 | 
						|
 	} else if (flags == BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS) {
 | 
						|
-		fws->stats.txs_supp_ps++;
 | 
						|
+		fws->stats.txs_supp_ps += compcnt;
 | 
						|
 		remove_from_hanger = false;
 | 
						|
 	} else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED)
 | 
						|
-		fws->stats.txs_tossed++;
 | 
						|
+		fws->stats.txs_tossed += compcnt;
 | 
						|
 	else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)
 | 
						|
-		fws->stats.txs_host_tossed++;
 | 
						|
+		fws->stats.txs_host_tossed += compcnt;
 | 
						|
 	else
 | 
						|
 		brcmf_err("unexpected txstatus\n");
 | 
						|
 
 | 
						|
-	ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
 | 
						|
-				      remove_from_hanger);
 | 
						|
-	if (ret != 0) {
 | 
						|
-		brcmf_err("no packet in hanger slot: hslot=%d\n", hslot);
 | 
						|
-		return ret;
 | 
						|
-	}
 | 
						|
+	while (cnt < compcnt) {
 | 
						|
+		ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
 | 
						|
+					      remove_from_hanger);
 | 
						|
+		if (ret != 0) {
 | 
						|
+			brcmf_err("no packet in hanger slot: hslot=%d\n",
 | 
						|
+				  hslot);
 | 
						|
+			goto cont;
 | 
						|
+		}
 | 
						|
 
 | 
						|
-	skcb = brcmf_skbcb(skb);
 | 
						|
-	entry = skcb->mac;
 | 
						|
-	if (WARN_ON(!entry)) {
 | 
						|
-		brcmu_pkt_buf_free_skb(skb);
 | 
						|
-		return -EINVAL;
 | 
						|
-	}
 | 
						|
-	entry->transit_count--;
 | 
						|
-	if (entry->suppressed && entry->suppr_transit_count)
 | 
						|
-		entry->suppr_transit_count--;
 | 
						|
-
 | 
						|
-	brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
 | 
						|
-		  skcb->htod, seq);
 | 
						|
-
 | 
						|
-	/* pick up the implicit credit from this packet */
 | 
						|
-	fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
 | 
						|
-	if ((fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT) ||
 | 
						|
-	    (brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
 | 
						|
-	    (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)) {
 | 
						|
-		brcmf_fws_return_credits(fws, fifo, 1);
 | 
						|
-		brcmf_fws_schedule_deq(fws);
 | 
						|
-	}
 | 
						|
-	brcmf_fws_macdesc_return_req_credit(skb);
 | 
						|
+		skcb = brcmf_skbcb(skb);
 | 
						|
+		entry = skcb->mac;
 | 
						|
+		if (WARN_ON(!entry)) {
 | 
						|
+			brcmu_pkt_buf_free_skb(skb);
 | 
						|
+			goto cont;
 | 
						|
+		}
 | 
						|
+		entry->transit_count--;
 | 
						|
+		if (entry->suppressed && entry->suppr_transit_count)
 | 
						|
+			entry->suppr_transit_count--;
 | 
						|
 
 | 
						|
-	ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
 | 
						|
-	if (ret) {
 | 
						|
-		brcmu_pkt_buf_free_skb(skb);
 | 
						|
-		return -EINVAL;
 | 
						|
+		brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name,
 | 
						|
+			  flags, skcb->htod, seq);
 | 
						|
+
 | 
						|
+		/* pick up the implicit credit from this packet */
 | 
						|
+		fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
 | 
						|
+		if (fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT ||
 | 
						|
+		    (brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
 | 
						|
+		    flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED) {
 | 
						|
+			brcmf_fws_return_credits(fws, fifo, 1);
 | 
						|
+			brcmf_fws_schedule_deq(fws);
 | 
						|
+		}
 | 
						|
+		brcmf_fws_macdesc_return_req_credit(skb);
 | 
						|
+
 | 
						|
+		ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
 | 
						|
+		if (ret) {
 | 
						|
+			brcmu_pkt_buf_free_skb(skb);
 | 
						|
+			goto cont;
 | 
						|
+		}
 | 
						|
+		if (!remove_from_hanger)
 | 
						|
+			ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
 | 
						|
+							    genbit, seq);
 | 
						|
+		if (remove_from_hanger || ret)
 | 
						|
+			brcmf_txfinalize(ifp, skb, true);
 | 
						|
+
 | 
						|
+cont:
 | 
						|
+		hslot = (hslot + 1) & (BRCMF_FWS_TXSTAT_HSLOT_MASK >>
 | 
						|
+				       BRCMF_FWS_TXSTAT_HSLOT_SHIFT);
 | 
						|
+		if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode))
 | 
						|
+			seq = (seq + 1) & BRCMF_SKB_HTOD_SEQ_NR_MASK;
 | 
						|
+
 | 
						|
+		cnt++;
 | 
						|
 	}
 | 
						|
-	if (!remove_from_hanger)
 | 
						|
-		ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
 | 
						|
-						    genbit, seq);
 | 
						|
-	if (remove_from_hanger || ret)
 | 
						|
-		brcmf_txfinalize(ifp, skb, true);
 | 
						|
 
 | 
						|
 	return 0;
 | 
						|
 }
 | 
						|
@@ -1547,7 +1559,8 @@ static int brcmf_fws_fifocreditback_indi
 | 
						|
 	return BRCMF_FWS_RET_OK_SCHEDULE;
 | 
						|
 }
 | 
						|
 
 | 
						|
-static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
 | 
						|
+static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 type,
 | 
						|
+				       u8 *data)
 | 
						|
 {
 | 
						|
 	__le32 status_le;
 | 
						|
 	__le16 seq_le;
 | 
						|
@@ -1556,23 +1569,31 @@ static int brcmf_fws_txstatus_indicate(s
 | 
						|
 	u32 genbit;
 | 
						|
 	u8 flags;
 | 
						|
 	u16 seq;
 | 
						|
+	u8 compcnt;
 | 
						|
+	u8 compcnt_offset = BRCMF_FWS_TYPE_TXSTATUS_LEN;
 | 
						|
 
 | 
						|
-	fws->stats.txs_indicate++;
 | 
						|
 	memcpy(&status_le, data, sizeof(status_le));
 | 
						|
 	status = le32_to_cpu(status_le);
 | 
						|
 	flags = brcmf_txstatus_get_field(status, FLAGS);
 | 
						|
 	hslot = brcmf_txstatus_get_field(status, HSLOT);
 | 
						|
 	genbit = brcmf_txstatus_get_field(status, GENERATION);
 | 
						|
 	if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
 | 
						|
-		memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN],
 | 
						|
+		memcpy(&seq_le, &data[BRCMF_FWS_TYPE_TXSTATUS_LEN],
 | 
						|
 		       sizeof(seq_le));
 | 
						|
 		seq = le16_to_cpu(seq_le);
 | 
						|
+		compcnt_offset += BRCMF_FWS_TYPE_SEQ_LEN;
 | 
						|
 	} else {
 | 
						|
 		seq = 0;
 | 
						|
 	}
 | 
						|
 
 | 
						|
+	if (type == BRCMF_FWS_TYPE_COMP_TXSTATUS)
 | 
						|
+		compcnt = data[compcnt_offset];
 | 
						|
+	else
 | 
						|
+		compcnt = 1;
 | 
						|
+	fws->stats.txs_indicate += compcnt;
 | 
						|
+
 | 
						|
 	brcmf_fws_lock(fws);
 | 
						|
-	brcmf_fws_txs_process(fws, flags, hslot, genbit, seq);
 | 
						|
+	brcmf_fws_txs_process(fws, flags, hslot, genbit, seq, compcnt);
 | 
						|
 	brcmf_fws_unlock(fws);
 | 
						|
 	return BRCMF_FWS_RET_OK_NOSCHEDULE;
 | 
						|
 }
 | 
						|
@@ -1888,8 +1909,6 @@ void brcmf_fws_hdrpull(struct brcmf_if *
 | 
						|
 
 | 
						|
 		err = BRCMF_FWS_RET_OK_NOSCHEDULE;
 | 
						|
 		switch (type) {
 | 
						|
-		case BRCMF_FWS_TYPE_COMP_TXSTATUS:
 | 
						|
-			break;
 | 
						|
 		case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
 | 
						|
 			rd = (struct brcmf_skb_reorder_data *)skb->cb;
 | 
						|
 			rd->reorder = data;
 | 
						|
@@ -1912,7 +1931,8 @@ void brcmf_fws_hdrpull(struct brcmf_if *
 | 
						|
 			err = brcmf_fws_request_indicate(fws, type, data);
 | 
						|
 			break;
 | 
						|
 		case BRCMF_FWS_TYPE_TXSTATUS:
 | 
						|
-			brcmf_fws_txstatus_indicate(fws, data);
 | 
						|
+		case BRCMF_FWS_TYPE_COMP_TXSTATUS:
 | 
						|
+			brcmf_fws_txstatus_indicate(fws, type, data);
 | 
						|
 			break;
 | 
						|
 		case BRCMF_FWS_TYPE_FIFO_CREDITBACK:
 | 
						|
 			err = brcmf_fws_fifocreditback_indicate(fws, data);
 | 
						|
@@ -2001,7 +2021,7 @@ static void brcmf_fws_rollback_toq(struc
 | 
						|
 		fws->stats.rollback_failed++;
 | 
						|
 		hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
 | 
						|
 		brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
 | 
						|
-				      hslot, 0, 0);
 | 
						|
+				      hslot, 0, 0, 1);
 | 
						|
 	} else {
 | 
						|
 		fws->stats.rollback_success++;
 | 
						|
 		brcmf_fws_return_credits(fws, fifo, 1);
 | 
						|
@@ -2462,7 +2482,8 @@ void brcmf_fws_bustxfail(struct brcmf_fw
 | 
						|
 	}
 | 
						|
 	brcmf_fws_lock(fws);
 | 
						|
 	hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
 | 
						|
-	brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0);
 | 
						|
+	brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0,
 | 
						|
+			      1);
 | 
						|
 	brcmf_fws_unlock(fws);
 | 
						|
 }
 | 
						|
 
 |