From 0994e65c6a32ea7009d1fe89f7261cb5d106c7a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= Date: Tue, 12 Feb 2019 13:43:06 +0100 Subject: mac80211: brcmfmac: backport remaining patches from the Linux 5.0 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Rafał Miłecki --- ...cmfmac-handle-compressed-tx-status-signal.patch | 227 +++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch (limited to 'package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch') 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 +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 +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Wright Feng +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../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); + } + -- cgit v1.2.3