aboutsummaryrefslogtreecommitdiffstats
path: root/package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch')
-rw-r--r--package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch227
1 files changed, 227 insertions, 0 deletions
diff --git a/package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch b/package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch
new file mode 100644
index 0000000000..f7e09ecaab
--- /dev/null
+++ b/package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch
@@ -0,0 +1,227 @@
+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--;
++ 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--;
+
+- brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
+- skcb->htod, seq);
++ 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);
++ /* 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);
+- return -EINVAL;
++ 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);
+ }
+