From edbe0e75f5ed8eb006cc6c187f6ddd0f6f9dd86a Mon Sep 17 00:00:00 2001 From: JasonHuang Date: Mon, 29 Jan 2024 23:38:13 -0600 Subject: [PATCH 242/296] non-upstream: check and set default fcmode of the chip This request came from Amazon facing some t-put issue. Default set fcmode=2 and then clear fcmode if chip not support proptxstatus. We can read current fcmode from /sys/kernel/debug/ieee80211/phy0/parameter Signed-off-by: JasonHuang --- .../wireless/broadcom/brcm80211/brcmfmac/bus.h | 10 ++++++++++ .../broadcom/brcm80211/brcmfmac/common.c | 7 +++++-- .../wireless/broadcom/brcm80211/brcmfmac/core.c | 5 +++++ .../broadcom/brcm80211/brcmfmac/feature.c | 1 + .../broadcom/brcm80211/brcmfmac/feature.h | 3 ++- .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 16 ++++++++++++++++ 6 files changed, 39 insertions(+), 3 deletions(-) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h index 1c336fde2d48..8c4e58d6f922 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h @@ -108,6 +108,7 @@ struct brcmf_bus_ops { void (*debugfs_create)(struct device *dev); int (*reset)(struct device *dev); void (*remove)(struct device *dev); + int (*set_fcmode)(struct device *dev); }; @@ -312,6 +313,15 @@ static inline void brcmf_bus_remove(struct brcmf_bus *bus) bus->ops->remove(bus->dev); } +static inline +int brcmf_bus_set_fcmode(struct brcmf_bus *bus) +{ + if (!bus->ops->set_fcmode) + return -EOPNOTSUPP; + + return bus->ops->set_fcmode(bus->dev); +} + /* * interface functions from common layer */ diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c index 7225978788f3..b813217044d9 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c @@ -26,6 +26,7 @@ #include #include #include "pcie.h" +#include "sdio.h" MODULE_AUTHOR("Broadcom Corporation"); MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver."); @@ -61,7 +62,7 @@ module_param_string(alternative_fw_path, brcmf_firmware_path, BRCMF_FW_ALTPATH_LEN, 0400); MODULE_PARM_DESC(alternative_fw_path, "Alternative firmware path"); -static int brcmf_fcmode; +static int brcmf_fcmode = 2; module_param_named(fcmode, brcmf_fcmode, int, 0); MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); @@ -736,12 +737,14 @@ static void brcmf_mp_attach(void) int brcmf_debugfs_param_read(struct seq_file *s, void *data) { + struct brcmf_bus *bus_if = dev_get_drvdata(s->private); + seq_printf(s, "%-20s: %s\n", "Name", "Value"); seq_printf(s, "%-20s: 0x%x\n", "debug", brcmf_msg_level); seq_printf(s, "%-20s: %s\n", "alternative_fw_path", brcmf_firmware_path); seq_printf(s, "%-20s: %d\n", "p2pon", !!brcmf_p2p_enable); seq_printf(s, "%-20s: %d\n", "feature_disable", brcmf_feature_disable); - seq_printf(s, "%-20s: %d\n", "fcmode", brcmf_fcmode); + seq_printf(s, "%-20s: %d\n", "fcmode", bus_if->drvr->settings->fcmode); seq_printf(s, "%-20s: %d\n", "roamoff", !!brcmf_roamoff); seq_printf(s, "%-20s: %d\n", "iapp", !!brcmf_iapp_enable); seq_printf(s, "%-20s: %d\n", "eap_restrict", !!brcmf_eap_restrict); diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c index 96a444438006..ad18635d6eb6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c @@ -33,6 +33,7 @@ #include "common.h" #include "twt.h" #include "bt_shared_sdio_ifx.h" +#include "sdio.h" #define MAX_WAIT_FOR_8021X_TX msecs_to_jiffies(950) @@ -1594,6 +1595,10 @@ static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) goto fail; brcmf_feat_attach(drvr); + ret = brcmf_bus_set_fcmode(bus_if); + /* Set fcmode = 0 for PCIe/USB */ + if (ret < 0) + drvr->settings->fcmode = 0; ret = brcmf_proto_init_done(drvr); if (ret < 0) diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c index 5832bf158737..7bf3f8f05eb6 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c @@ -50,6 +50,7 @@ static const struct brcmf_feat_fwcap brcmf_fwcap_map[] = { { BRCMF_FEAT_GCMP, "gcmp" }, { BRCMF_FEAT_OFFLOADS, "offloads" }, { BRCMF_FEAT_ULP, "ulp" }, + { BRCMF_FEAT_PROPTXSTATUS, "proptxstatus" }, }; #ifdef DEBUG diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h index 8ebe078193a4..112e035f9258 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h @@ -74,7 +74,8 @@ BRCMF_FEAT_DEF(GCMP) \ BRCMF_FEAT_DEF(TWT) \ BRCMF_FEAT_DEF(OFFLOADS) \ - BRCMF_FEAT_DEF(ULP) + BRCMF_FEAT_DEF(ULP) \ + BRCMF_FEAT_DEF(PROPTXSTATUS) /* * Quirks: diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c index 11c60a1435d6..acc546f5554c 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c @@ -5218,6 +5218,7 @@ static int brcmf_sdio_bus_reset(struct device *dev) return 0; } + static void brcmf_sdio_bus_remove(struct device *dev) { struct brcmf_bus *bus_if = dev_get_drvdata(dev); @@ -5227,6 +5228,20 @@ static void brcmf_sdio_bus_remove(struct device *dev) device_release_driver(&sdiod->func1->dev); } +static int brcmf_sdio_bus_set_fcmode(struct device *dev) +{ + struct brcmf_bus *bus_if = dev_get_drvdata(dev); + struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; + + if (!brcmf_feat_is_enabled(bus_if->drvr->iflist[0], BRCMF_FEAT_PROPTXSTATUS)) { + bus_if->drvr->settings->fcmode = 0; + sdiodev->settings->fcmode = bus_if->drvr->settings->fcmode; + brcmf_dbg(INFO, "Set fcmode = %d\n", sdiodev->settings->fcmode); + } + + return sdiodev->settings->fcmode; +} + static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { .stop = brcmf_sdio_bus_stop, .preinit = brcmf_sdio_bus_preinit, @@ -5241,6 +5256,7 @@ static const struct brcmf_bus_ops brcmf_sdio_bus_ops = { .debugfs_create = brcmf_sdio_debugfs_create, .reset = brcmf_sdio_bus_reset, .remove = brcmf_sdio_bus_remove, + .set_fcmode = brcmf_sdio_bus_set_fcmode }; #define BRCMF_SDIO_FW_CODE 0 -- 2.25.1