mac80211: brcm: add support for BCM4359 SDIO chipset
authorRafał Miłecki <rafal@milecki.pl>
Thu, 19 Dec 2019 08:16:59 +0000 (09:16 +0100)
committerRafał Miłecki <rafal@milecki.pl>
Thu, 19 Dec 2019 08:17:22 +0000 (09:17 +0100)
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
package/kernel/mac80211/patches/brcm/114-v5.6-0001-brcmfmac-reset-two-D11-cores-if-chip-has-two-D11-cor.patch [new file with mode: 0644]
package/kernel/mac80211/patches/brcm/114-v5.6-0002-brcmfmac-set-F2-blocksize-and-watermark-for-4359.patch [new file with mode: 0644]
package/kernel/mac80211/patches/brcm/114-v5.6-0003-brcmfmac-fix-rambase-for-4359-9.patch [new file with mode: 0644]
package/kernel/mac80211/patches/brcm/114-v5.6-0004-brcmfmac-make-errors-when-setting-roaming-parameters.patch [new file with mode: 0644]
package/kernel/mac80211/patches/brcm/114-v5.6-0005-brcmfmac-add-support-for-BCM4359-SDIO-chipset.patch [new file with mode: 0644]
package/kernel/mac80211/patches/brcm/114-v5.6-0006-brcmfmac-add-RSDB-condition-when-setting-interface-c.patch [new file with mode: 0644]
package/kernel/mac80211/patches/brcm/114-v5.6-0007-brcmfmac-not-set-mbss-in-vif-if-firmware-does-not-su.patch [new file with mode: 0644]

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 (file)
index 0000000..19bf41a
--- /dev/null
@@ -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 (file)
index 0000000..bdfe2ae
--- /dev/null
@@ -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 (file)
index 0000000..7e4e32f
--- /dev/null
@@ -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 (file)
index 0000000..cd7ccb0
--- /dev/null
@@ -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 (file)
index 0000000..0001fb1
--- /dev/null
@@ -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 (file)
index 0000000..d00c59c
--- /dev/null
@@ -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 (file)
index 0000000..9c211a6
--- /dev/null
@@ -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) {