From: Rafał Miłecki Date: Thu, 19 Dec 2019 08:16:59 +0000 (+0100) Subject: mac80211: brcm: add support for BCM4359 SDIO chipset X-Git-Tag: v19.07.0~57 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=2c16044ccf3925caba4c8bb474536d971b67858c;p=oweals%2Fopenwrt.git mac80211: brcm: add support for BCM4359 SDIO chipset Signed-off-by: Rafał Miłecki (cherry picked from commit 17e2246eca901fec79fbac5b7a90f68f60785c4e) --- diff --git a/package/kernel/mac80211/patches/brcm/414-v5.6-0001-brcmfmac-reset-two-D11-cores-if-chip-has-two-D11-cor.patch b/package/kernel/mac80211/patches/brcm/414-v5.6-0001-brcmfmac-reset-two-D11-cores-if-chip-has-two-D11-cor.patch new file mode 100644 index 0000000000..19bf41ad9b --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/414-v5.6-0001-brcmfmac-reset-two-D11-cores-if-chip-has-two-D11-cor.patch @@ -0,0 +1,121 @@ +From 1b8d2e0a9e4221b99eea375c079507ce8ef655f5 Mon Sep 17 00:00:00 2001 +From: Wright Feng +Date: Thu, 12 Dec 2019 00:52:45 +0100 +Subject: [PATCH 1/7] brcmfmac: reset two D11 cores if chip has two D11 cores + +There are two D11 cores in RSDB chips like 4359. We have to reset two +D11 cores simutaneously before firmware download, or the firmware may +not be initialized correctly and cause "fw initialized failed" error. + +Signed-off-by: Wright Feng +Signed-off-by: Soeren Moch +Reviewed-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/chip.c | 50 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/chip.h | 1 + + .../broadcom/brcm80211/brcmfmac/pcie.c | 2 +- + 3 files changed, 52 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -433,11 +433,25 @@ static void brcmf_chip_ai_resetcore(stru + { + struct brcmf_chip_priv *ci; + int count; ++ struct brcmf_core *d11core2 = NULL; ++ struct brcmf_core_priv *d11priv2 = NULL; + + ci = core->chip; + ++ /* special handle two D11 cores reset */ ++ if (core->pub.id == BCMA_CORE_80211) { ++ d11core2 = brcmf_chip_get_d11core(&ci->pub, 1); ++ if (d11core2) { ++ brcmf_dbg(INFO, "found two d11 cores, reset both\n"); ++ d11priv2 = container_of(d11core2, ++ struct brcmf_core_priv, pub); ++ } ++ } ++ + /* must disable first to work for arbitrary current core state */ + brcmf_chip_ai_coredisable(core, prereset, reset); ++ if (d11priv2) ++ brcmf_chip_ai_coredisable(d11priv2, prereset, reset); + + count = 0; + while (ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) & +@@ -449,9 +463,30 @@ static void brcmf_chip_ai_resetcore(stru + usleep_range(40, 60); + } + ++ if (d11priv2) { ++ count = 0; ++ while (ci->ops->read32(ci->ctx, ++ d11priv2->wrapbase + BCMA_RESET_CTL) & ++ BCMA_RESET_CTL_RESET) { ++ ci->ops->write32(ci->ctx, ++ d11priv2->wrapbase + BCMA_RESET_CTL, ++ 0); ++ count++; ++ if (count > 50) ++ break; ++ usleep_range(40, 60); ++ } ++ } ++ + ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL, + postreset | BCMA_IOCTL_CLK); + ci->ops->read32(ci->ctx, core->wrapbase + BCMA_IOCTL); ++ ++ if (d11priv2) { ++ ci->ops->write32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL, ++ postreset | BCMA_IOCTL_CLK); ++ ci->ops->read32(ci->ctx, d11priv2->wrapbase + BCMA_IOCTL); ++ } + } + + char *brcmf_chip_name(u32 id, u32 rev, char *buf, uint len) +@@ -1109,6 +1144,21 @@ void brcmf_chip_detach(struct brcmf_chip + kfree(chip); + } + ++struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit) ++{ ++ struct brcmf_chip_priv *chip; ++ struct brcmf_core_priv *core; ++ ++ chip = container_of(pub, struct brcmf_chip_priv, pub); ++ list_for_each_entry(core, &chip->cores, list) { ++ if (core->pub.id == BCMA_CORE_80211) { ++ if (unit-- == 0) ++ return &core->pub; ++ } ++ } ++ return NULL; ++} ++ + struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *pub, u16 coreid) + { + struct brcmf_chip_priv *chip; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +@@ -74,6 +74,7 @@ struct brcmf_chip *brcmf_chip_attach(voi + const struct brcmf_buscore_ops *ops); + void brcmf_chip_detach(struct brcmf_chip *chip); + struct brcmf_core *brcmf_chip_get_core(struct brcmf_chip *chip, u16 coreid); ++struct brcmf_core *brcmf_chip_get_d11core(struct brcmf_chip *pub, u8 unit); + struct brcmf_core *brcmf_chip_get_chipcommon(struct brcmf_chip *chip); + struct brcmf_core *brcmf_chip_get_pmu(struct brcmf_chip *pub); + bool brcmf_chip_iscoreup(struct brcmf_core *core); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -78,7 +78,7 @@ static const struct brcmf_firmware_mappi + BRCMF_FW_ENTRY(BRCM_CC_4371_CHIP_ID, 0xFFFFFFFF, 4371), + }; + +-#define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */ ++#define BRCMF_PCIE_FW_UP_TIMEOUT 5000 /* msec */ + + #define BRCMF_PCIE_REG_MAP_SIZE (32 * 1024) + diff --git a/package/kernel/mac80211/patches/brcm/414-v5.6-0002-brcmfmac-set-F2-blocksize-and-watermark-for-4359.patch b/package/kernel/mac80211/patches/brcm/414-v5.6-0002-brcmfmac-set-F2-blocksize-and-watermark-for-4359.patch new file mode 100644 index 0000000000..34f597482b --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/414-v5.6-0002-brcmfmac-set-F2-blocksize-and-watermark-for-4359.patch @@ -0,0 +1,79 @@ +From 172f6854551d48d1c9530f84513b421db944e714 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Thu, 12 Dec 2019 00:52:46 +0100 +Subject: [PATCH 2/7] brcmfmac: set F2 blocksize and watermark for 4359 + +Set F2 blocksize to 256 bytes and watermark to 0x40 for 4359. Also +enable and configure F1 MesBusyCtrl. It fixes DMA error while having +UDP bi-directional traffic. + +Signed-off-by: Chung-Hsien Hsu +[slightly adapted for rebase on mainline linux] +Signed-off-by: Soeren Moch +Reviewed-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 6 +++++- + .../wireless/broadcom/brcm80211/brcmfmac/sdio.c | 15 +++++++++++++++ + 2 files changed, 20 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -43,6 +43,7 @@ + + #define SDIO_FUNC1_BLOCKSIZE 64 + #define SDIO_FUNC2_BLOCKSIZE 512 ++#define SDIO_4359_FUNC2_BLOCKSIZE 256 + /* Maximum milliseconds to wait for F2 to come up */ + #define SDIO_WAIT_F2RDY 3000 + +@@ -892,6 +893,7 @@ static void brcmf_sdiod_host_fixup(struc + static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev) + { + int ret = 0; ++ unsigned int f2_blksz = SDIO_FUNC2_BLOCKSIZE; + + sdio_claim_host(sdiodev->func1); + +@@ -901,7 +903,9 @@ static int brcmf_sdiod_probe(struct brcm + sdio_release_host(sdiodev->func1); + goto out; + } +- ret = sdio_set_block_size(sdiodev->func2, SDIO_FUNC2_BLOCKSIZE); ++ if (sdiodev->func2->device == SDIO_DEVICE_ID_BROADCOM_4359) ++ f2_blksz = SDIO_4359_FUNC2_BLOCKSIZE; ++ ret = sdio_set_block_size(sdiodev->func2, f2_blksz); + if (ret) { + brcmf_err("Failed to set F2 blocksize\n"); + sdio_release_host(sdiodev->func1); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -42,6 +42,8 @@ + #define DEFAULT_F2_WATERMARK 0x8 + #define CY_4373_F2_WATERMARK 0x40 + #define CY_43012_F2_WATERMARK 0x60 ++#define CY_4359_F2_WATERMARK 0x40 ++#define CY_4359_F1_MESBUSYCTRL (CY_4359_F2_WATERMARK | SBSDIO_MESBUSYCTRL_ENAB) + + #ifdef DEBUG + +@@ -4210,6 +4212,19 @@ static void brcmf_sdio_firmware_callback + brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl, + &err); + break; ++ case SDIO_DEVICE_ID_BROADCOM_4359: ++ brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n", ++ CY_4359_F2_WATERMARK); ++ brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, ++ CY_4359_F2_WATERMARK, &err); ++ devctl = brcmf_sdiod_readb(sdiod, SBSDIO_DEVICE_CTL, ++ &err); ++ devctl |= SBSDIO_DEVCTL_F2WM_ENAB; ++ brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl, ++ &err); ++ brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_MESBUSYCTRL, ++ CY_4359_F1_MESBUSYCTRL, &err); ++ break; + default: + brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, + DEFAULT_F2_WATERMARK, &err); diff --git a/package/kernel/mac80211/patches/brcm/414-v5.6-0003-brcmfmac-fix-rambase-for-4359-9.patch b/package/kernel/mac80211/patches/brcm/414-v5.6-0003-brcmfmac-fix-rambase-for-4359-9.patch new file mode 100644 index 0000000000..7e4e32ffdd --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/414-v5.6-0003-brcmfmac-fix-rambase-for-4359-9.patch @@ -0,0 +1,34 @@ +From 6647274ed995a172369cb04754eb5f8b85f68f6d Mon Sep 17 00:00:00 2001 +From: Soeren Moch +Date: Thu, 12 Dec 2019 00:52:47 +0100 +Subject: [PATCH 3/7] brcmfmac: fix rambase for 4359/9 + +Newer 4359 chip revisions need a different rambase address. +This fixes firmware download on such devices which fails otherwise. + +Signed-off-by: Soeren Moch +Acked-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -712,7 +712,6 @@ static u32 brcmf_chip_tcm_rambase(struct + case BRCM_CC_43569_CHIP_ID: + case BRCM_CC_43570_CHIP_ID: + case BRCM_CC_4358_CHIP_ID: +- case BRCM_CC_4359_CHIP_ID: + case BRCM_CC_43602_CHIP_ID: + case BRCM_CC_4371_CHIP_ID: + return 0x180000; +@@ -722,6 +721,8 @@ static u32 brcmf_chip_tcm_rambase(struct + case BRCM_CC_4366_CHIP_ID: + case BRCM_CC_43664_CHIP_ID: + return 0x200000; ++ case BRCM_CC_4359_CHIP_ID: ++ return (ci->pub.chiprev < 9) ? 0x180000 : 0x160000; + case CY_CC_4373_CHIP_ID: + return 0x160000; + default: diff --git a/package/kernel/mac80211/patches/brcm/414-v5.6-0004-brcmfmac-make-errors-when-setting-roaming-parameters.patch b/package/kernel/mac80211/patches/brcm/414-v5.6-0004-brcmfmac-make-errors-when-setting-roaming-parameters.patch new file mode 100644 index 0000000000..b15907217e --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/414-v5.6-0004-brcmfmac-make-errors-when-setting-roaming-parameters.patch @@ -0,0 +1,42 @@ +From c12c8913d79c49ceccb38f42714d25b783833758 Mon Sep 17 00:00:00 2001 +From: Soeren Moch +Date: Thu, 12 Dec 2019 00:52:48 +0100 +Subject: [PATCH 4/7] brcmfmac: make errors when setting roaming parameters + non-fatal + +4359 dongles do not support setting roaming parameters (error -52). +Do not fail the 80211 configuration in this case. + +Signed-off-by: Soeren Moch +Acked-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5936,19 +5936,17 @@ static s32 brcmf_dongle_roam(struct brcm + roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL); + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER, + (void *)roamtrigger, sizeof(roamtrigger)); +- if (err) { ++ if (err) + bphy_err(drvr, "WLC_SET_ROAM_TRIGGER error (%d)\n", err); +- goto roam_setup_done; +- } + + roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA); + roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL); + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA, + (void *)roam_delta, sizeof(roam_delta)); +- if (err) { ++ if (err) + bphy_err(drvr, "WLC_SET_ROAM_DELTA error (%d)\n", err); +- goto roam_setup_done; +- } ++ ++ return 0; + + roam_setup_done: + return err; diff --git a/package/kernel/mac80211/patches/brcm/414-v5.6-0005-brcmfmac-add-support-for-BCM4359-SDIO-chipset.patch b/package/kernel/mac80211/patches/brcm/414-v5.6-0005-brcmfmac-add-support-for-BCM4359-SDIO-chipset.patch new file mode 100644 index 0000000000..266c32246f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/414-v5.6-0005-brcmfmac-add-support-for-BCM4359-SDIO-chipset.patch @@ -0,0 +1,75 @@ +From d4aef159394d5940bd7158ab789969dab82f7c76 Mon Sep 17 00:00:00 2001 +From: Soeren Moch +Date: Thu, 12 Dec 2019 00:52:49 +0100 +Subject: [PATCH 5/7] brcmfmac: add support for BCM4359 SDIO chipset + +BCM4359 is a 2x2 802.11 abgn+ac Dual-Band HT80 combo chip and it +supports Real Simultaneous Dual Band feature. + +Based on a similar patch by: Wright Feng + +Signed-off-by: Soeren Moch +Acked-by: Chi-Hsien Lin +Acked-by: Ulf Hansson +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 ++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 1 + + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 2 ++ + include/linux/mmc/sdio_ids.h | 2 ++ + 4 files changed, 7 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -962,8 +962,10 @@ static const struct sdio_device_id brcmf + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43455), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356), ++ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4359), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_4373), + BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_43012), ++ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_89359), + { /* end: all zeroes */ } + }; + MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +@@ -1408,6 +1408,7 @@ bool brcmf_chip_sr_capable(struct brcmf_ + addr = CORE_CC_REG(base, sr_control0); + reg = chip->ops->read32(chip->ctx, addr); + return (reg & CC_SR_CTL0_ENABLE_MASK) != 0; ++ case BRCM_CC_4359_CHIP_ID: + case CY_CC_43012_CHIP_ID: + addr = CORE_CC_REG(pmu->base, retention_ctl); + reg = chip->ops->read32(chip->ctx, addr); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -616,6 +616,7 @@ BRCMF_FW_DEF(43455, "brcmfmac43455-sdio" + BRCMF_FW_DEF(43456, "brcmfmac43456-sdio"); + BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); + BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); ++BRCMF_FW_DEF(4359, "brcmfmac4359-sdio"); + BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); + BRCMF_FW_DEF(43012, "brcmfmac43012-sdio"); + +@@ -638,6 +639,7 @@ static const struct brcmf_firmware_mappi + BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 43455), + BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354), + BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356), ++ BRCMF_FW_ENTRY(BRCM_CC_4359_CHIP_ID, 0xFFFFFFFF, 4359), + BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373), + BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012) + }; +--- a/include/linux/mmc/sdio_ids.h ++++ b/include/linux/mmc/sdio_ids.h +@@ -41,8 +41,10 @@ + #define SDIO_DEVICE_ID_BROADCOM_43455 0xa9bf + #define SDIO_DEVICE_ID_BROADCOM_4354 0x4354 + #define SDIO_DEVICE_ID_BROADCOM_4356 0x4356 ++#define SDIO_DEVICE_ID_BROADCOM_4359 0x4359 + #define SDIO_DEVICE_ID_CYPRESS_4373 0x4373 + #define SDIO_DEVICE_ID_CYPRESS_43012 43012 ++#define SDIO_DEVICE_ID_CYPRESS_89359 0x4355 + + #define SDIO_VENDOR_ID_INTEL 0x0089 + #define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402 diff --git a/package/kernel/mac80211/patches/brcm/414-v5.6-0006-brcmfmac-add-RSDB-condition-when-setting-interface-c.patch b/package/kernel/mac80211/patches/brcm/414-v5.6-0006-brcmfmac-add-RSDB-condition-when-setting-interface-c.patch new file mode 100644 index 0000000000..c56ae2c248 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/414-v5.6-0006-brcmfmac-add-RSDB-condition-when-setting-interface-c.patch @@ -0,0 +1,130 @@ +From 837482e69a3f0d7cbc73922020012f83635f5ddb Mon Sep 17 00:00:00 2001 +From: Wright Feng +Date: Thu, 12 Dec 2019 00:52:50 +0100 +Subject: [PATCH 6/7] brcmfmac: add RSDB condition when setting interface + combinations + +With firmware RSDB feature +1. The maximum support interface is four. +2. The maximum difference channel is two. +3. The maximum interfaces of {station/p2p client/AP} are two. +4. The maximum interface of p2p device is one. + +Signed-off-by: Wright Feng +Signed-off-by: Soeren Moch +Reviewed-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 54 ++++++++++++++++--- + 1 file changed, 46 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6444,6 +6444,9 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = + * #STA <= 1, #AP <= 1, channels = 1, 2 total + * #AP <= 4, matching BI, channels = 1, 4 total + * ++ * no p2p and rsdb: ++ * #STA <= 2, #AP <= 2, channels = 2, 4 total ++ * + * p2p, no mchan, and mbss: + * + * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total +@@ -6455,6 +6458,10 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = + * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total + * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total + * #AP <= 4, matching BI, channels = 1, 4 total ++ * ++ * p2p, rsdb, and no mbss: ++ * #STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2, ++ * channels = 2, 4 total + */ + static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp) + { +@@ -6462,13 +6469,14 @@ static int brcmf_setup_ifmodes(struct wi + struct ieee80211_iface_limit *c0_limits = NULL; + struct ieee80211_iface_limit *p2p_limits = NULL; + struct ieee80211_iface_limit *mbss_limits = NULL; +- bool mbss, p2p; ++ bool mbss, p2p, rsdb; + int i, c, n_combos; + + mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS); + p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P); ++ rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB); + +- n_combos = 1 + !!p2p + !!mbss; ++ n_combos = 1 + !!(p2p && !rsdb) + !!mbss; + combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL); + if (!combo) + goto err; +@@ -6479,16 +6487,36 @@ static int brcmf_setup_ifmodes(struct wi + + c = 0; + i = 0; +- c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL); ++ if (p2p && rsdb) ++ c0_limits = kcalloc(4, sizeof(*c0_limits), GFP_KERNEL); ++ else if (p2p) ++ c0_limits = kcalloc(3, sizeof(*c0_limits), GFP_KERNEL); ++ else ++ c0_limits = kcalloc(2, sizeof(*c0_limits), GFP_KERNEL); + if (!c0_limits) + goto err; +- c0_limits[i].max = 1; +- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); +- if (p2p) { ++ if (p2p && rsdb) { ++ combo[c].num_different_channels = 2; ++ wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_P2P_GO) | ++ BIT(NL80211_IFTYPE_P2P_DEVICE); ++ c0_limits[i].max = 2; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); ++ c0_limits[i].max = 1; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE); ++ c0_limits[i].max = 2; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | ++ BIT(NL80211_IFTYPE_P2P_GO); ++ c0_limits[i].max = 2; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); ++ combo[c].max_interfaces = 5; ++ } else if (p2p) { + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)) + combo[c].num_different_channels = 2; + else + combo[c].num_different_channels = 1; ++ c0_limits[i].max = 1; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); + wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO) | + BIT(NL80211_IFTYPE_P2P_DEVICE); +@@ -6497,16 +6525,26 @@ static int brcmf_setup_ifmodes(struct wi + c0_limits[i].max = 1; + c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) | + BIT(NL80211_IFTYPE_P2P_GO); ++ combo[c].max_interfaces = i; ++ } else if (rsdb) { ++ combo[c].num_different_channels = 2; ++ c0_limits[i].max = 2; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); ++ c0_limits[i].max = 2; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); ++ combo[c].max_interfaces = 3; + } else { + combo[c].num_different_channels = 1; + c0_limits[i].max = 1; ++ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION); ++ c0_limits[i].max = 1; + c0_limits[i++].types = BIT(NL80211_IFTYPE_AP); ++ combo[c].max_interfaces = i; + } +- combo[c].max_interfaces = i; + combo[c].n_limits = i; + combo[c].limits = c0_limits; + +- if (p2p) { ++ if (p2p && !rsdb) { + c++; + i = 0; + p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL); diff --git a/package/kernel/mac80211/patches/brcm/414-v5.6-0007-brcmfmac-not-set-mbss-in-vif-if-firmware-does-not-su.patch b/package/kernel/mac80211/patches/brcm/414-v5.6-0007-brcmfmac-not-set-mbss-in-vif-if-firmware-does-not-su.patch new file mode 100644 index 0000000000..96df09dfab --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/414-v5.6-0007-brcmfmac-not-set-mbss-in-vif-if-firmware-does-not-su.patch @@ -0,0 +1,38 @@ +From 2635853ce4ab7654a77ab7080fb56de83408606b Mon Sep 17 00:00:00 2001 +From: Wright Feng +Date: Thu, 12 Dec 2019 00:52:51 +0100 +Subject: [PATCH 7/7] brcmfmac: not set mbss in vif if firmware does not + support MBSS + +With RSDB mode, FMAC and firmware are able to create 2 or more AP, +so we should not set mbss in vif structure if firmware does not +support MBSS feature. + +Signed-off-by: Wright Feng +Signed-off-by: Soeren Moch +Reviewed-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5293,6 +5293,7 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v + struct brcmf_cfg80211_vif *vif_walk; + struct brcmf_cfg80211_vif *vif; + bool mbss; ++ struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); + + brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n", + sizeof(*vif)); +@@ -5305,7 +5306,8 @@ struct brcmf_cfg80211_vif *brcmf_alloc_v + + brcmf_init_prof(&vif->profile); + +- if (type == NL80211_IFTYPE_AP) { ++ if (type == NL80211_IFTYPE_AP && ++ brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) { + mbss = false; + list_for_each_entry(vif_walk, &cfg->vif_list, list) { + if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {