From f522b85f3e95c053521cdb969e0d0cdf8de69613 Mon Sep 17 00:00:00 2001 From: avishad verma Date: Fri, 5 Jan 2024 06:45:59 -0600 Subject: [PATCH 275/296] brcmfmac: fix CERT-11N: Traffic Differentiation in Single BSS with 802.11n STA Increased PSQ Size from 256 to 256*8. Increased Low and High Watermark accordingly. Added Module param to use the old config if required. Issue:While running muliple streams of 2-BE and 1-VO, It has been observed the PSQ LOW Watermark is reached. Reason for reaching Low Mark is VO is borrowing all credits from BE and BK, causing BE packets to accumulate in PSQ. Netif queue is stopped once the PSQ Low watermark is reached. During this queue stop period, PSQ will not be having any VO packets, causing a drop in VO traffic and WMM test failure. PSQ size is increased to avoid Netif queue stop. Signed-off-by: avishad verma --- .../broadcom/brcm80211/brcmfmac/common.c | 7 ++++ .../broadcom/brcm80211/brcmfmac/common.h | 1 + .../broadcom/brcm80211/brcmfmac/fwsignal.c | 41 ++++++++++++++----- 3 files changed, 38 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 8ef5837d3da0..b7480c7817f5 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -142,6 +142,10 @@ static int brcmf_idle_time_zero; module_param_named(idle_time_zero, brcmf_idle_time_zero, int, 0644); MODULE_PARM_DESC(idle_time_zero, "Set idle interval to zero"); +static int brcmf_short_psq; +module_param_named(short_psq, brcmf_short_psq, int, 0); +MODULE_PARM_DESC(short_psq, "Use shorter PS Queue"); + static struct brcmfmac_platform_data *brcmfmac_pdata; struct brcmf_mp_global_t brcmf_mp_global; @@ -783,6 +787,7 @@ int brcmf_debugfs_param_read(struct seq_file *s, void *data) seq_printf(s, "%-20s: %d\n", "txglomsz", brcmf_sdiod_txglomsz); seq_printf(s, "%-20s: %d\n", "bt_over_sdio", !!brcmf_bt_over_sdio); seq_printf(s, "%-20s: %d\n", "idle_time_zero", !!brcmf_idle_time_zero); + seq_printf(s, "%-20s: %d\n", "short_psq", !!brcmf_short_psq); return 0; } @@ -846,6 +851,8 @@ struct brcmf_mp_device *brcmf_get_module_param(struct device *dev, settings->bt_over_sdio = !!brcmf_bt_over_sdio; brcmf_dbg(INFO, "bt_over_sdio: %d\n", settings->bt_over_sdio); + settings->short_psq = !!brcmf_short_psq; + brcmf_dbg(INFO, "brcmf_short_psq: %d\n", settings->short_psq); settings->idleclk_disable = brcmf_sdio_idleclk_disable; brcmf_dbg(INFO, "idleclk_disable: %d\n", settings->idleclk_disable); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h index 422fe83793f4..f2fb78d7dddf 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h @@ -85,6 +85,7 @@ struct brcmf_mp_device { unsigned int offload_prof; unsigned int offload_feat; bool bt_over_sdio; + bool short_psq; struct brcmfmac_pd_cc *country_codes; const char *board_type; unsigned char mac[ETH_ALEN]; diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c index b4a812543712..8b7cf9c1127a 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c @@ -149,11 +149,14 @@ static const char *brcmf_fws_get_tlv_name(enum brcmf_fws_tlv_type id) #define BRCMF_FWS_HOSTIF_FLOWSTATE_OFF 0 #define BRCMF_FWS_HOSTIF_FLOWSTATE_ON 1 -#define BRCMF_FWS_FLOWCONTROL_HIWATER 128 -#define BRCMF_FWS_FLOWCONTROL_LOWATER 64 +#define BRCMF_FWS_FLOWCONTROL_HIWATER ((256 * 8) - 256) +#define BRCMF_FWS_FLOWCONTROL_LOWATER 256 +#define BRCMF_FWS_FLOWCONTROL_SHQUEUE_HIWATER 128 +#define BRCMF_FWS_FLOWCONTROL_SHQUEUE_LOWATER 64 #define BRCMF_FWS_PSQ_PREC_COUNT ((BRCMF_FWS_FIFO_COUNT + 1) * 2) -#define BRCMF_FWS_PSQ_LEN 256 +#define BRCMF_FWS_PSQ_LEN (256 * 8) +#define BRCMF_FWS_SHQUEUE_PSQ_LEN 256 #define BRCMF_FWS_HTOD_FLAG_PKTFROMHOST 0x01 #define BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED 0x02 @@ -505,6 +508,9 @@ struct brcmf_fws_info { #if (KERNEL_VERSION(4, 16, 0) > LINUX_VERSION_CODE) int fifo_init_credit[BRCMF_FWS_FIFO_COUNT]; #endif + int fws_psq_len; + int fws_psq_hi_water; + int fws_psq_low_water; }; #define BRCMF_FWS_TLV_DEF(name, id, len) \ @@ -964,11 +970,11 @@ brcmf_fws_flow_control_check(struct brcmf_fws_info *fws, struct pktq *pq, return; if ((ifp->netif_stop & BRCMF_NETIF_STOP_REASON_FWS_FC) && - pq->len <= BRCMF_FWS_FLOWCONTROL_LOWATER) + pq->len <= fws->fws_psq_low_water) brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FWS_FC, false); if (!(ifp->netif_stop & BRCMF_NETIF_STOP_REASON_FWS_FC) && - pq->len >= BRCMF_FWS_FLOWCONTROL_HIWATER) { + pq->len >= fws->fws_psq_hi_water) { fws->stats.fws_flow_block++; brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FWS_FC, true); } @@ -1014,8 +1020,9 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) entry->mac_handle = mac_handle; brcmf_fws_macdesc_init(entry, addr, ifidx); brcmf_fws_macdesc_set_name(fws, entry); - brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT, - BRCMF_FWS_PSQ_LEN); + brcmu_pktq_init(&entry->psq, + BRCMF_FWS_PSQ_PREC_COUNT, + fws->fws_psq_len); brcmf_fws_unlock(fws); brcmf_dbg(TRACE, "add %s mac %pM\n", entry->name, addr); } else { @@ -2177,8 +2184,9 @@ void brcmf_fws_add_interface(struct brcmf_if *ifp) ifp->fws_desc = entry; brcmf_fws_macdesc_init(entry, ifp->mac_addr, ifp->ifidx); brcmf_fws_macdesc_set_name(fws, entry); - brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT, - BRCMF_FWS_PSQ_LEN); + brcmu_pktq_init(&entry->psq, + BRCMF_FWS_PSQ_PREC_COUNT, + fws->fws_psq_len); brcmf_dbg(TRACE, "added %s\n", entry->name); } @@ -2401,6 +2409,16 @@ struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr) fws->drvr = drvr; fws->fcmode = drvr->settings->fcmode; + if (drvr->settings->short_psq) { + fws->fws_psq_len = BRCMF_FWS_SHQUEUE_PSQ_LEN; + fws->fws_psq_hi_water = BRCMF_FWS_FLOWCONTROL_SHQUEUE_HIWATER; + fws->fws_psq_low_water = BRCMF_FWS_FLOWCONTROL_SHQUEUE_LOWATER; + } else { + fws->fws_psq_len = BRCMF_FWS_PSQ_LEN; + fws->fws_psq_hi_water = BRCMF_FWS_FLOWCONTROL_HIWATER; + fws->fws_psq_low_water = BRCMF_FWS_FLOWCONTROL_LOWATER; + } + if (!drvr->bus_if->always_use_fws_queue && (fws->fcmode == BRCMF_FWS_FCMODE_NONE)) { fws->avoid_queueing = true; @@ -2468,8 +2486,9 @@ struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr) brcmf_fws_macdesc_init(&fws->desc.other, NULL, 0); brcmf_fws_macdesc_set_name(fws, &fws->desc.other); brcmf_dbg(INFO, "added %s\n", fws->desc.other.name); - brcmu_pktq_init(&fws->desc.other.psq, BRCMF_FWS_PSQ_PREC_COUNT, - BRCMF_FWS_PSQ_LEN); + brcmu_pktq_init(&fws->desc.other.psq, + BRCMF_FWS_PSQ_PREC_COUNT, + fws->fws_psq_len); brcmf_dbg(INFO, "%s bdcv2 tlv signaling [%x]\n", fws->fw_signals ? "enabled" : "disabled", tlv); -- 2.25.1