 d48a8ed40d
			
		
	
	d48a8ed40d
	
	
	
		
			
			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);
 | |
|  }
 | |
|  
 |