From: Rafał Miłecki <rafal@milecki.pl>
Date: Thu, 19 Dec 2019 08:16:59 +0000 (+0100)
Subject: mac80211: brcm: add support for BCM4359 SDIO chipset
X-Git-Url: http://git.cdn.openwrt.org/?a=commitdiff_plain;h=17e2246eca901fec79fbac5b7a90f68f60785c4e;p=openwrt%2Fstaging%2Fdedeckeh.git

mac80211: brcm: add support for BCM4359 SDIO chipset

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---

diff --git a/package/kernel/mac80211/patches/brcm/114-v5.6-0001-brcmfmac-reset-two-D11-cores-if-chip-has-two-D11-cor.patch b/package/kernel/mac80211/patches/brcm/114-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/114-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 <wright.feng@cypress.com>
+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 <wright.feng@cypress.com>
+Signed-off-by: Soeren Moch <smoch@web.de>
+Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../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/114-v5.6-0002-brcmfmac-set-F2-blocksize-and-watermark-for-4359.patch b/package/kernel/mac80211/patches/brcm/114-v5.6-0002-brcmfmac-set-F2-blocksize-and-watermark-for-4359.patch
new file mode 100644
index 0000000000..bdfe2ae85f
--- /dev/null
+++ b/package/kernel/mac80211/patches/brcm/114-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 <stanley.hsu@cypress.com>
+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 <stanley.hsu@cypress.com>
+[slightly adapted for rebase on mainline linux]
+Signed-off-by: Soeren Moch <smoch@web.de>
+Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../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
+ 
+@@ -903,6 +904,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);
+ 
+@@ -912,7 +914,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
+ 
+@@ -4206,6 +4208,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/114-v5.6-0003-brcmfmac-fix-rambase-for-4359-9.patch b/package/kernel/mac80211/patches/brcm/114-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/114-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 <smoch@web.de>
+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 <smoch@web.de>
+Acked-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ 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/114-v5.6-0004-brcmfmac-make-errors-when-setting-roaming-parameters.patch b/package/kernel/mac80211/patches/brcm/114-v5.6-0004-brcmfmac-make-errors-when-setting-roaming-parameters.patch
new file mode 100644
index 0000000000..cd7ccb0439
--- /dev/null
+++ b/package/kernel/mac80211/patches/brcm/114-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 <smoch@web.de>
+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 <smoch@web.de>
+Acked-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../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
+@@ -5944,19 +5944,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/114-v5.6-0005-brcmfmac-add-support-for-BCM4359-SDIO-chipset.patch b/package/kernel/mac80211/patches/brcm/114-v5.6-0005-brcmfmac-add-support-for-BCM4359-SDIO-chipset.patch
new file mode 100644
index 0000000000..0001fb17a7
--- /dev/null
+++ b/package/kernel/mac80211/patches/brcm/114-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 <smoch@web.de>
+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 <wright.feng@cypress.com>
+
+Signed-off-by: Soeren Moch <smoch@web.de>
+Acked-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
+Acked-by: Ulf Hansson <ulf.hansson@linaro.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ 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
+@@ -973,8 +973,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/114-v5.6-0006-brcmfmac-add-RSDB-condition-when-setting-interface-c.patch b/package/kernel/mac80211/patches/brcm/114-v5.6-0006-brcmfmac-add-RSDB-condition-when-setting-interface-c.patch
new file mode 100644
index 0000000000..d00c59c07c
--- /dev/null
+++ b/package/kernel/mac80211/patches/brcm/114-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 <wright.feng@cypress.com>
+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 <wright.feng@cypress.com>
+Signed-off-by: Soeren Moch <smoch@web.de>
+Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../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
+@@ -6452,6 +6452,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
+@@ -6463,6 +6466,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)
+ {
+@@ -6470,13 +6477,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;
+@@ -6487,16 +6495,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);
+@@ -6505,16 +6533,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/114-v5.6-0007-brcmfmac-not-set-mbss-in-vif-if-firmware-does-not-su.patch b/package/kernel/mac80211/patches/brcm/114-v5.6-0007-brcmfmac-not-set-mbss-in-vif-if-firmware-does-not-su.patch
new file mode 100644
index 0000000000..9c211a68d0
--- /dev/null
+++ b/package/kernel/mac80211/patches/brcm/114-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 <wright.feng@cypress.com>
+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 <wright.feng@cypress.com>
+Signed-off-by: Soeren Moch <smoch@web.de>
+Reviewed-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ 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
+@@ -5301,6 +5301,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));
+@@ -5313,7 +5314,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) {