mac80211: update brcmfmac to the wireless-drivers-next-for-davem-2015-04-09
authorRafał Miłecki <zajec5@gmail.com>
Fri, 24 Apr 2015 10:45:33 +0000 (10:45 +0000)
committerRafał Miłecki <zajec5@gmail.com>
Fri, 24 Apr 2015 10:45:33 +0000 (10:45 +0000)
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
SVN-Revision: 45576

19 files changed:
package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch [new file with mode: 0644]
package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch [new file with mode: 0644]
package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch [new file with mode: 0644]
package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch [new file with mode: 0644]
package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch [new file with mode: 0644]
package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch [new file with mode: 0644]
package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch [new file with mode: 0644]
package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch [new file with mode: 0644]
package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch [new file with mode: 0644]
package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch [new file with mode: 0644]
package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch [new file with mode: 0644]
package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch [new file with mode: 0644]
package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch [new file with mode: 0644]
package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch [new file with mode: 0644]
package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch [new file with mode: 0644]
package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch [new file with mode: 0644]
package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch [new file with mode: 0644]
package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch [new file with mode: 0644]

diff --git a/package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch b/package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch
new file mode 100644 (file)
index 0000000..5e63a80
--- /dev/null
@@ -0,0 +1,44 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 6 Mar 2015 18:40:38 +0100
+Subject: [PATCH] brcmfmac: Fix oops when SDIO device is removed.
+
+On removal of SDIO card both functions of card will be getting
+a remove call. When the first is hanging in ctrl frame xmit then
+the second will cause oops. This patch fixes the xmit ctrl
+handling in case of serious errors and also limits the handling
+for remove to function 1 only.
+
+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
+Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+@@ -1194,7 +1194,7 @@ static void brcmf_ops_sdio_remove(struct
+       brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
+       brcmf_dbg(SDIO, "Function: %d\n", func->num);
+-      if (func->num != 1 && func->num != 2)
++      if (func->num != 1)
+               return;
+       bus_if = dev_get_drvdata(&func->dev);
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -2740,6 +2740,11 @@ static void brcmf_sdio_dpc(struct brcmf_
+       if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) {
+               brcmf_err("failed backplane access over SDIO, halting operation\n");
+               atomic_set(&bus->intstatus, 0);
++              if (bus->ctrl_frame_stat) {
++                      bus->ctrl_frame_err = -ENODEV;
++                      bus->ctrl_frame_stat = false;
++                      brcmf_sdio_wait_event_wakeup(bus);
++              }
+       } else if (atomic_read(&bus->intstatus) ||
+                  atomic_read(&bus->ipend) > 0 ||
+                  (!atomic_read(&bus->fcstate) &&
diff --git a/package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch b/package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch
new file mode 100644 (file)
index 0000000..201da75
--- /dev/null
@@ -0,0 +1,157 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 6 Mar 2015 18:40:39 +0100
+Subject: [PATCH] brcmfmac: Simplify watchdog sleep.
+
+The watchdog thread is used to put the SDIO bus to sleep when the
+system is idling. This patch simplifies the way it is determined
+when sleep can be entered.
+
+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
+Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -485,10 +485,9 @@ struct brcmf_sdio {
+ #endif                                /* DEBUG */
+       uint clkstate;          /* State of sd and backplane clock(s) */
+-      bool activity;          /* Activity flag for clock down */
+       s32 idletime;           /* Control for activity timeout */
+-      s32 idlecount;  /* Activity timeout counter */
+-      s32 idleclock;  /* How to set bus driver when idle */
++      s32 idlecount;          /* Activity timeout counter */
++      s32 idleclock;          /* How to set bus driver when idle */
+       bool rxflow_mode;       /* Rx flow control mode */
+       bool rxflow;            /* Is rx flow control on */
+       bool alp_only;          /* Don't use HT clock (ALP only) */
+@@ -511,6 +510,7 @@ struct brcmf_sdio {
+       struct workqueue_struct *brcmf_wq;
+       struct work_struct datawork;
+       atomic_t dpc_tskcnt;
++      atomic_t dpc_running;
+       bool txoff;             /* Transmit flow-controlled */
+       struct brcmf_sdio_count sdcnt;
+@@ -959,13 +959,8 @@ static int brcmf_sdio_clkctl(struct brcm
+       brcmf_dbg(SDIO, "Enter\n");
+       /* Early exit if we're already there */
+-      if (bus->clkstate == target) {
+-              if (target == CLK_AVAIL) {
+-                      brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
+-                      bus->activity = true;
+-              }
++      if (bus->clkstate == target)
+               return 0;
+-      }
+       switch (target) {
+       case CLK_AVAIL:
+@@ -975,7 +970,6 @@ static int brcmf_sdio_clkctl(struct brcm
+               /* Now request HT Avail on the backplane */
+               brcmf_sdio_htclk(bus, true, pendok);
+               brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
+-              bus->activity = true;
+               break;
+       case CLK_SDONLY:
+@@ -1024,17 +1018,6 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *
+               /* Going to sleep */
+               if (sleep) {
+-                      /* Don't sleep if something is pending */
+-                      if (atomic_read(&bus->intstatus) ||
+-                          atomic_read(&bus->ipend) > 0 ||
+-                          bus->ctrl_frame_stat ||
+-                          (!atomic_read(&bus->fcstate) &&
+-                          brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
+-                          data_ok(bus))) {
+-                               err = -EBUSY;
+-                               goto done;
+-                      }
+-
+                       clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
+                                                  SBSDIO_FUNC1_CHIPCLKCSR,
+                                                  &err);
+@@ -1045,11 +1028,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *
+                                                 SBSDIO_ALP_AVAIL_REQ, &err);
+                       }
+                       err = brcmf_sdio_kso_control(bus, false);
+-                      /* disable watchdog */
+-                      if (!err)
+-                              brcmf_sdio_wd_timer(bus, 0);
+               } else {
+-                      bus->idlecount = 0;
+                       err = brcmf_sdio_kso_control(bus, true);
+               }
+               if (err) {
+@@ -3566,7 +3545,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *b
+       queue_work(bus->brcmf_wq, &bus->datawork);
+ }
+-static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
++static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
+ {
+       brcmf_dbg(TIMER, "Enter\n");
+@@ -3627,22 +3606,21 @@ static bool brcmf_sdio_bus_watchdog(stru
+ #endif                                /* DEBUG */
+       /* On idle timeout clear activity flag and/or turn off clock */
+-      if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
+-              if (++bus->idlecount >= bus->idletime) {
++      if ((atomic_read(&bus->dpc_tskcnt) == 0) &&
++          (atomic_read(&bus->dpc_running) == 0) &&
++          (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
++              bus->idlecount++;
++              if (bus->idlecount > bus->idletime) {
++                      brcmf_dbg(SDIO, "idle\n");
++                      sdio_claim_host(bus->sdiodev->func[1]);
++                      brcmf_sdio_wd_timer(bus, 0);
+                       bus->idlecount = 0;
+-                      if (bus->activity) {
+-                              bus->activity = false;
+-                              brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
+-                      } else {
+-                              brcmf_dbg(SDIO, "idle\n");
+-                              sdio_claim_host(bus->sdiodev->func[1]);
+-                              brcmf_sdio_bus_sleep(bus, true, false);
+-                              sdio_release_host(bus->sdiodev->func[1]);
+-                      }
++                      brcmf_sdio_bus_sleep(bus, true, false);
++                      sdio_release_host(bus->sdiodev->func[1]);
+               }
++      } else {
++              bus->idlecount = 0;
+       }
+-
+-      return (atomic_read(&bus->ipend) > 0);
+ }
+ static void brcmf_sdio_dataworker(struct work_struct *work)
+@@ -3651,8 +3629,11 @@ static void brcmf_sdio_dataworker(struct
+                                             datawork);
+       while (atomic_read(&bus->dpc_tskcnt)) {
++              atomic_set(&bus->dpc_running, 1);
+               atomic_set(&bus->dpc_tskcnt, 0);
+               brcmf_sdio_dpc(bus);
++              bus->idlecount = 0;
++              atomic_set(&bus->dpc_running, 0);
+       }
+       if (brcmf_sdiod_freezing(bus->sdiodev)) {
+               brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
+@@ -4154,6 +4135,7 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
+       }
+       /* Initialize DPC thread */
+       atomic_set(&bus->dpc_tskcnt, 0);
++      atomic_set(&bus->dpc_running, 0);
+       /* Assign bus interface call back */
+       bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
diff --git a/package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch b/package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch
new file mode 100644 (file)
index 0000000..3a2de7a
--- /dev/null
@@ -0,0 +1,83 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 6 Mar 2015 18:40:40 +0100
+Subject: [PATCH] brcmfmac: Fix possible race-condition.
+
+SDIO is using a "shared" variable to handoff ctl frames to DPC
+and to see when they are done. In a timeout situation this can
+lead to erroneous situation where DPC started to handle the ctl
+frame while the timeout expired. This patch will fix this by
+adding locking around the shared variable.
+
+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
+Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -2700,11 +2700,13 @@ static void brcmf_sdio_dpc(struct brcmf_
+       if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
+           data_ok(bus)) {
+               sdio_claim_host(bus->sdiodev->func[1]);
+-              err = brcmf_sdio_tx_ctrlframe(bus,  bus->ctrl_frame_buf,
+-                                            bus->ctrl_frame_len);
++              if (bus->ctrl_frame_stat) {
++                      err = brcmf_sdio_tx_ctrlframe(bus,  bus->ctrl_frame_buf,
++                                                    bus->ctrl_frame_len);
++                      bus->ctrl_frame_err = err;
++                      bus->ctrl_frame_stat = false;
++              }
+               sdio_release_host(bus->sdiodev->func[1]);
+-              bus->ctrl_frame_err = err;
+-              bus->ctrl_frame_stat = false;
+               brcmf_sdio_wait_event_wakeup(bus);
+       }
+       /* Send queued frames (limit 1 if rx may still be pending) */
+@@ -2720,9 +2722,13 @@ static void brcmf_sdio_dpc(struct brcmf_
+               brcmf_err("failed backplane access over SDIO, halting operation\n");
+               atomic_set(&bus->intstatus, 0);
+               if (bus->ctrl_frame_stat) {
+-                      bus->ctrl_frame_err = -ENODEV;
+-                      bus->ctrl_frame_stat = false;
+-                      brcmf_sdio_wait_event_wakeup(bus);
++                      sdio_claim_host(bus->sdiodev->func[1]);
++                      if (bus->ctrl_frame_stat) {
++                              bus->ctrl_frame_err = -ENODEV;
++                              bus->ctrl_frame_stat = false;
++                              brcmf_sdio_wait_event_wakeup(bus);
++                      }
++                      sdio_release_host(bus->sdiodev->func[1]);
+               }
+       } else if (atomic_read(&bus->intstatus) ||
+                  atomic_read(&bus->ipend) > 0 ||
+@@ -2930,15 +2936,20 @@ brcmf_sdio_bus_txctl(struct device *dev,
+       brcmf_sdio_trigger_dpc(bus);
+       wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat,
+                                        msecs_to_jiffies(CTL_DONE_TIMEOUT));
+-
+-      if (!bus->ctrl_frame_stat) {
++      ret = 0;
++      if (bus->ctrl_frame_stat) {
++              sdio_claim_host(bus->sdiodev->func[1]);
++              if (bus->ctrl_frame_stat) {
++                      brcmf_dbg(SDIO, "ctrl_frame timeout\n");
++                      bus->ctrl_frame_stat = false;
++                      ret = -ETIMEDOUT;
++              }
++              sdio_release_host(bus->sdiodev->func[1]);
++      }
++      if (!ret) {
+               brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n",
+                         bus->ctrl_frame_err);
+               ret = bus->ctrl_frame_err;
+-      } else {
+-              brcmf_dbg(SDIO, "ctrl_frame timeout\n");
+-              bus->ctrl_frame_stat = false;
+-              ret = -ETIMEDOUT;
+       }
+       if (ret)
diff --git a/package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch b/package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch
new file mode 100644 (file)
index 0000000..c9eb900
--- /dev/null
@@ -0,0 +1,86 @@
+From: Syed Asifful Dayyan <syedd@broadcom.com>
+Date: Fri, 6 Mar 2015 18:40:42 +0100
+Subject: [PATCH] brcmfmac: Add support for BCM4345 SDIO chipset.
+
+These changes add support for BCM4345 SDIO chipset.
+
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
+Signed-off-by: Syed Asifful Dayyan <syedd@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+@@ -1096,6 +1096,7 @@ static const struct sdio_device_id brcmf
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
++      BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
+       { /* end: all zeroes */ }
+ };
+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+@@ -491,6 +491,10 @@ static void brcmf_chip_get_raminfo(struc
+       case BRCM_CC_43362_CHIP_ID:
+               ci->pub.ramsize = 0x3c000;
+               break;
++      case BRCM_CC_4345_CHIP_ID:
++              ci->pub.ramsize = 0xc8000;
++              ci->pub.rambase = 0x198000;
++              break;
+       case BRCM_CC_4339_CHIP_ID:
+       case BRCM_CC_4354_CHIP_ID:
+       case BRCM_CC_4356_CHIP_ID:
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -617,6 +617,8 @@ static const struct sdiod_drive_str sdio
+ #define BCM43362_NVRAM_NAME           "brcm/brcmfmac43362-sdio.txt"
+ #define BCM4339_FIRMWARE_NAME         "brcm/brcmfmac4339-sdio.bin"
+ #define BCM4339_NVRAM_NAME            "brcm/brcmfmac4339-sdio.txt"
++#define BCM4345_FIRMWARE_NAME         "brcm/brcmfmac4345-sdio.bin"
++#define BCM4345_NVRAM_NAME            "brcm/brcmfmac4345-sdio.txt"
+ #define BCM4354_FIRMWARE_NAME         "brcm/brcmfmac4354-sdio.bin"
+ #define BCM4354_NVRAM_NAME            "brcm/brcmfmac4354-sdio.txt"
+@@ -640,6 +642,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);
+ MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
+ MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
+ MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
++MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME);
++MODULE_FIRMWARE(BCM4345_NVRAM_NAME);
+ MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
+ MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
+@@ -669,6 +673,7 @@ static const struct brcmf_firmware_names
+       { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
+       { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
+       { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
++      { BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) },
+       { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
+ };
+--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+@@ -37,6 +37,7 @@
+ #define BRCM_CC_43362_CHIP_ID         43362
+ #define BRCM_CC_4335_CHIP_ID          0x4335
+ #define BRCM_CC_4339_CHIP_ID          0x4339
++#define BRCM_CC_4345_CHIP_ID          0x4345
+ #define BRCM_CC_4354_CHIP_ID          0x4354
+ #define BRCM_CC_4356_CHIP_ID          0x4356
+ #define BRCM_CC_43566_CHIP_ID         43566
+--- a/include/linux/mmc/sdio_ids.h
++++ b/include/linux/mmc/sdio_ids.h
+@@ -33,6 +33,7 @@
+ #define SDIO_DEVICE_ID_BROADCOM_43341         0xa94d
+ #define SDIO_DEVICE_ID_BROADCOM_4335_4339     0x4335
+ #define SDIO_DEVICE_ID_BROADCOM_43362         0xa962
++#define SDIO_DEVICE_ID_BROADCOM_4345          0x4345
+ #define SDIO_DEVICE_ID_BROADCOM_4354          0x4354
+ #define SDIO_VENDOR_ID_INTEL                  0x0089
diff --git a/package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch b/package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch
new file mode 100644 (file)
index 0000000..7a688c4
--- /dev/null
@@ -0,0 +1,48 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 11 Mar 2015 16:11:27 +0100
+Subject: [PATCH] brcmfmac: remove duplication of ramsize info
+
+Removing the ramsize from the brcmf_sdio structure to avoid
+duplication. The information is available in brcmf_chip
+structure.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -432,8 +432,6 @@ struct brcmf_sdio {
+       struct brcmf_sdio_dev *sdiodev; /* sdio device handler */
+       struct brcmf_chip *ci;  /* Chip info struct */
+-      u32 ramsize;            /* Size of RAM in SOCRAM (bytes) */
+-
+       u32 hostintmask;        /* Copy of Host Interrupt Mask */
+       atomic_t intstatus;     /* Intstatus bits (events) pending */
+       atomic_t fcstate;       /* State of dongle flow-control */
+@@ -1075,7 +1073,7 @@ static int brcmf_sdio_readshared(struct
+       struct sdpcm_shared_le sh_le;
+       __le32 addr_le;
+-      shaddr = bus->ci->rambase + bus->ramsize - 4;
++      shaddr = bus->ci->rambase + bus->ci->ramsize - 4;
+       /*
+        * Read last word in socram to determine
+@@ -3871,13 +3869,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdi
+               drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
+       brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
+-      /* Get info on the SOCRAM cores... */
+-      bus->ramsize = bus->ci->ramsize;
+-      if (!(bus->ramsize)) {
+-              brcmf_err("failed to find SOCRAM memory!\n");
+-              goto fail;
+-      }
+-
+       /* Set card control so an SDIO card reset does a WLAN backplane reset */
+       reg_val = brcmf_sdiod_regrb(bus->sdiodev,
+                                   SDIO_CCCR_BRCM_CARDCTRL, &err);
diff --git a/package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch b/package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch
new file mode 100644 (file)
index 0000000..e2a2074
--- /dev/null
@@ -0,0 +1,74 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 11 Mar 2015 16:11:28 +0100
+Subject: [PATCH] brcmfmac: always perform cores checks
+
+Instead of checking the cores in the chip only if CONFIG_BRCMDBG
+is selected perform the check always and extend it with more sanity
+checking.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+@@ -419,13 +419,13 @@ static struct brcmf_core *brcmf_chip_add
+       return &core->pub;
+ }
+-#ifdef DEBUG
+ /* safety check for chipinfo */
+ static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
+ {
+       struct brcmf_core_priv *core;
+       bool need_socram = false;
+       bool has_socram = false;
++      bool cpu_found = false;
+       int idx = 1;
+       list_for_each_entry(core, &ci->cores, list) {
+@@ -435,12 +435,14 @@ static int brcmf_chip_cores_check(struct
+               switch (core->pub.id) {
+               case BCMA_CORE_ARM_CM3:
++                      cpu_found = true;
+                       need_socram = true;
+                       break;
+               case BCMA_CORE_INTERNAL_MEM:
+                       has_socram = true;
+                       break;
+               case BCMA_CORE_ARM_CR4:
++                      cpu_found = true;
+                       if (ci->pub.rambase == 0) {
+                               brcmf_err("RAM base not provided with ARM CR4 core\n");
+                               return -ENOMEM;
+@@ -451,19 +453,21 @@ static int brcmf_chip_cores_check(struct
+               }
+       }
++      if (!cpu_found) {
++              brcmf_err("CPU core not detected\n");
++              return -ENXIO;
++      }
+       /* check RAM core presence for ARM CM3 core */
+       if (need_socram && !has_socram) {
+               brcmf_err("RAM core not provided with ARM CM3 core\n");
+               return -ENODEV;
+       }
++      if (!ci->pub.ramsize) {
++              brcmf_err("RAM size is undetermined\n");
++              return -ENOMEM;
++      }
+       return 0;
+ }
+-#else /* DEBUG */
+-static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
+-{
+-      return 0;
+-}
+-#endif
+ static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
+ {
diff --git a/package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch b/package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch
new file mode 100644 (file)
index 0000000..a272800
--- /dev/null
@@ -0,0 +1,240 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 11 Mar 2015 16:11:29 +0100
+Subject: [PATCH] brcmfmac: rename chip download functions
+
+The functions brcmf_chip_[enter/exit]_download() are not exclusively
+used for firmware download so rename these more appropriate.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+@@ -807,7 +807,7 @@ struct brcmf_chip *brcmf_chip_attach(voi
+               err = -EINVAL;
+       if (WARN_ON(!ops->prepare))
+               err = -EINVAL;
+-      if (WARN_ON(!ops->exit_dl))
++      if (WARN_ON(!ops->activate))
+               err = -EINVAL;
+       if (err < 0)
+               return ERR_PTR(-EINVAL);
+@@ -905,7 +905,7 @@ void brcmf_chip_resetcore(struct brcmf_c
+ }
+ static void
+-brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip)
++brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)
+ {
+       struct brcmf_core *core;
+@@ -919,7 +919,7 @@ brcmf_chip_cm3_enterdl(struct brcmf_chip
+       brcmf_chip_resetcore(core, 0, 0, 0);
+ }
+-static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip)
++static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip)
+ {
+       struct brcmf_core *core;
+@@ -929,7 +929,7 @@ static bool brcmf_chip_cm3_exitdl(struct
+               return false;
+       }
+-      chip->ops->exit_dl(chip->ctx, &chip->pub, 0);
++      chip->ops->activate(chip->ctx, &chip->pub, 0);
+       core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
+       brcmf_chip_resetcore(core, 0, 0, 0);
+@@ -938,7 +938,7 @@ static bool brcmf_chip_cm3_exitdl(struct
+ }
+ static inline void
+-brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip)
++brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip)
+ {
+       struct brcmf_core *core;
+@@ -951,11 +951,11 @@ brcmf_chip_cr4_enterdl(struct brcmf_chip
+                            D11_BCMA_IOCTL_PHYCLOCKEN);
+ }
+-static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec)
++static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
+ {
+       struct brcmf_core *core;
+-      chip->ops->exit_dl(chip->ctx, &chip->pub, rstvec);
++      chip->ops->activate(chip->ctx, &chip->pub, rstvec);
+       /* restore ARM */
+       core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
+@@ -964,7 +964,7 @@ static bool brcmf_chip_cr4_exitdl(struct
+       return true;
+ }
+-void brcmf_chip_enter_download(struct brcmf_chip *pub)
++void brcmf_chip_set_passive(struct brcmf_chip *pub)
+ {
+       struct brcmf_chip_priv *chip;
+       struct brcmf_core *arm;
+@@ -974,14 +974,14 @@ void brcmf_chip_enter_download(struct br
+       chip = container_of(pub, struct brcmf_chip_priv, pub);
+       arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
+       if (arm) {
+-              brcmf_chip_cr4_enterdl(chip);
++              brcmf_chip_cr4_set_passive(chip);
+               return;
+       }
+-      brcmf_chip_cm3_enterdl(chip);
++      brcmf_chip_cm3_set_passive(chip);
+ }
+-bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec)
++bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec)
+ {
+       struct brcmf_chip_priv *chip;
+       struct brcmf_core *arm;
+@@ -991,9 +991,9 @@ bool brcmf_chip_exit_download(struct brc
+       chip = container_of(pub, struct brcmf_chip_priv, pub);
+       arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
+       if (arm)
+-              return brcmf_chip_cr4_exitdl(chip, rstvec);
++              return brcmf_chip_cr4_set_active(chip, rstvec);
+-      return brcmf_chip_cm3_exitdl(chip);
++      return brcmf_chip_cm3_set_active(chip);
+ }
+ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
+@@ -64,7 +64,7 @@ struct brcmf_core {
+  * @write32: write 32-bit value over bus.
+  * @prepare: prepare bus for core configuration.
+  * @setup: bus-specific core setup.
+- * @exit_dl: exit download state.
++ * @active: chip becomes active.
+  *    The callback should use the provided @rstvec when non-zero.
+  */
+ struct brcmf_buscore_ops {
+@@ -72,7 +72,7 @@ struct brcmf_buscore_ops {
+       void (*write32)(void *ctx, u32 addr, u32 value);
+       int (*prepare)(void *ctx);
+       int (*setup)(void *ctx, struct brcmf_chip *chip);
+-      void (*exit_dl)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
++      void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
+ };
+ struct brcmf_chip *brcmf_chip_attach(void *ctx,
+@@ -84,8 +84,8 @@ bool brcmf_chip_iscoreup(struct brcmf_co
+ void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
+ void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
+                         u32 postreset);
+-void brcmf_chip_enter_download(struct brcmf_chip *ci);
+-bool brcmf_chip_exit_download(struct brcmf_chip *ci, u32 rstvec);
++void brcmf_chip_set_passive(struct brcmf_chip *ci);
++bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec);
+ bool brcmf_chip_sr_capable(struct brcmf_chip *pub);
+ #endif /* BRCMF_AXIDMP_H */
+--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+@@ -509,7 +509,7 @@ static void brcmf_pcie_attach(struct brc
+ static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo)
+ {
+-      brcmf_chip_enter_download(devinfo->ci);
++      brcmf_chip_set_passive(devinfo->ci);
+       if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) {
+               brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4);
+@@ -536,7 +536,7 @@ static int brcmf_pcie_exit_download_stat
+               brcmf_chip_resetcore(core, 0, 0, 0);
+       }
+-      return !brcmf_chip_exit_download(devinfo->ci, resetintr);
++      return !brcmf_chip_set_active(devinfo->ci, resetintr);
+ }
+@@ -1566,8 +1566,8 @@ static int brcmf_pcie_buscoreprep(void *
+ }
+-static void brcmf_pcie_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
+-                                    u32 rstvec)
++static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip,
++                                      u32 rstvec)
+ {
+       struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
+@@ -1577,7 +1577,7 @@ static void brcmf_pcie_buscore_exitdl(vo
+ static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
+       .prepare = brcmf_pcie_buscoreprep,
+-      .exit_dl = brcmf_pcie_buscore_exitdl,
++      .activate = brcmf_pcie_buscore_activate,
+       .read32 = brcmf_pcie_buscore_read32,
+       .write32 = brcmf_pcie_buscore_write32,
+ };
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -3357,7 +3357,7 @@ static int brcmf_sdio_download_firmware(
+       brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
+       /* Keep arm in reset */
+-      brcmf_chip_enter_download(bus->ci);
++      brcmf_chip_set_passive(bus->ci);
+       rstvec = get_unaligned_le32(fw->data);
+       brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
+@@ -3378,7 +3378,7 @@ static int brcmf_sdio_download_firmware(
+       }
+       /* Take arm out of reset */
+-      if (!brcmf_chip_exit_download(bus->ci, rstvec)) {
++      if (!brcmf_chip_set_active(bus->ci, rstvec)) {
+               brcmf_err("error getting out of ARM core reset\n");
+               goto err;
+       }
+@@ -3771,8 +3771,8 @@ static int brcmf_sdio_buscoreprep(void *
+       return 0;
+ }
+-static void brcmf_sdio_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
+-                                    u32 rstvec)
++static void brcmf_sdio_buscore_activate(void *ctx, struct brcmf_chip *chip,
++                                      u32 rstvec)
+ {
+       struct brcmf_sdio_dev *sdiodev = ctx;
+       struct brcmf_core *core;
+@@ -3815,7 +3815,7 @@ static void brcmf_sdio_buscore_write32(v
+ static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
+       .prepare = brcmf_sdio_buscoreprep,
+-      .exit_dl = brcmf_sdio_buscore_exitdl,
++      .activate = brcmf_sdio_buscore_activate,
+       .read32 = brcmf_sdio_buscore_read32,
+       .write32 = brcmf_sdio_buscore_write32,
+ };
+@@ -4239,12 +4239,11 @@ void brcmf_sdio_remove(struct brcmf_sdio
+                               sdio_claim_host(bus->sdiodev->func[1]);
+                               brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
+                               /* Leave the device in state where it is
+-                               * 'quiet'. This is done by putting it in
+-                               * download_state which essentially resets
+-                               * all necessary cores.
++                               * 'passive'. This is done by resetting all
++                               * necessary cores.
+                                */
+                               msleep(20);
+-                              brcmf_chip_enter_download(bus->ci);
++                              brcmf_chip_set_passive(bus->ci);
+                               brcmf_sdio_clkctl(bus, CLK_NONE, false);
+                               sdio_release_host(bus->sdiodev->func[1]);
+                       }
diff --git a/package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch b/package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch
new file mode 100644 (file)
index 0000000..6b1dd81
--- /dev/null
@@ -0,0 +1,61 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 11 Mar 2015 16:11:30 +0100
+Subject: [PATCH] brcmfmac: assure device is ready for download after
+ brcmf_chip_attach()
+
+Make the brcmf_chip_attach() function responsible for putting the
+device in a state where it is accessible for firmware download.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+@@ -786,12 +786,6 @@ static int brcmf_chip_setup(struct brcmf
+       if (chip->ops->setup)
+               ret = chip->ops->setup(chip->ctx, pub);
+-      /*
+-       * Make sure any on-chip ARM is off (in case strapping is wrong),
+-       * or downloaded code was already running.
+-       */
+-      brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
+-      brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
+       return ret;
+ }
+@@ -833,6 +827,8 @@ struct brcmf_chip *brcmf_chip_attach(voi
+       if (err < 0)
+               goto fail;
++      /* assure chip is passive for download */
++      brcmf_chip_set_passive(&chip->pub);
+       return &chip->pub;
+ fail:
+--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+@@ -509,8 +509,6 @@ static void brcmf_pcie_attach(struct brc
+ static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo)
+ {
+-      brcmf_chip_set_passive(devinfo->ci);
+-
+       if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) {
+               brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4);
+               brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX,
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -3356,9 +3356,6 @@ static int brcmf_sdio_download_firmware(
+       sdio_claim_host(bus->sdiodev->func[1]);
+       brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
+-      /* Keep arm in reset */
+-      brcmf_chip_set_passive(bus->ci);
+-
+       rstvec = get_unaligned_le32(fw->data);
+       brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
diff --git a/package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch b/package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch
new file mode 100644 (file)
index 0000000..bcc2ed4
--- /dev/null
@@ -0,0 +1,367 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 11 Mar 2015 16:11:31 +0100
+Subject: [PATCH] brcmfmac: extract ram size info from internal memory
+ registers
+
+Instead of hard-coded memory sizes it is possible to obtain that
+information from the internal memory registers.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+@@ -100,9 +100,6 @@
+ #define BCM4329_CORE_SOCRAM_BASE      0x18003000
+ /* ARM Cortex M3 core, ID 0x82a */
+ #define BCM4329_CORE_ARM_BASE         0x18002000
+-#define BCM4329_RAMSIZE                       0x48000
+-/* bcm43143 */
+-#define BCM43143_RAMSIZE              0x70000
+ #define CORE_SB(base, field) \
+               (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
+@@ -150,6 +147,78 @@ struct sbconfig {
+       u32 sbidhigh;   /* identification */
+ };
++/* bankidx and bankinfo reg defines corerev >= 8 */
++#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000
++#define SOCRAM_BANKINFO_SZMASK                0x0000007f
++#define SOCRAM_BANKIDX_ROM_MASK               0x00000100
++
++#define SOCRAM_BANKIDX_MEMTYPE_SHIFT  8
++/* socram bankinfo memtype */
++#define SOCRAM_MEMTYPE_RAM            0
++#define SOCRAM_MEMTYPE_R0M            1
++#define SOCRAM_MEMTYPE_DEVRAM         2
++
++#define SOCRAM_BANKINFO_SZBASE                8192
++#define SRCI_LSS_MASK         0x00f00000
++#define SRCI_LSS_SHIFT                20
++#define       SRCI_SRNB_MASK          0xf0
++#define       SRCI_SRNB_SHIFT         4
++#define       SRCI_SRBSZ_MASK         0xf
++#define       SRCI_SRBSZ_SHIFT        0
++#define SR_BSZ_BASE           14
++
++struct sbsocramregs {
++      u32 coreinfo;
++      u32 bwalloc;
++      u32 extracoreinfo;
++      u32 biststat;
++      u32 bankidx;
++      u32 standbyctrl;
++
++      u32 errlogstatus;       /* rev 6 */
++      u32 errlogaddr; /* rev 6 */
++      /* used for patching rev 3 & 5 */
++      u32 cambankidx;
++      u32 cambankstandbyctrl;
++      u32 cambankpatchctrl;
++      u32 cambankpatchtblbaseaddr;
++      u32 cambankcmdreg;
++      u32 cambankdatareg;
++      u32 cambankmaskreg;
++      u32 PAD[1];
++      u32 bankinfo;   /* corev 8 */
++      u32 bankpda;
++      u32 PAD[14];
++      u32 extmemconfig;
++      u32 extmemparitycsr;
++      u32 extmemparityerrdata;
++      u32 extmemparityerrcnt;
++      u32 extmemwrctrlandsize;
++      u32 PAD[84];
++      u32 workaround;
++      u32 pwrctl;             /* corerev >= 2 */
++      u32 PAD[133];
++      u32 sr_control;     /* corerev >= 15 */
++      u32 sr_status;      /* corerev >= 15 */
++      u32 sr_address;     /* corerev >= 15 */
++      u32 sr_data;        /* corerev >= 15 */
++};
++
++#define SOCRAMREGOFFS(_f)     offsetof(struct sbsocramregs, _f)
++
++#define ARMCR4_CAP            (0x04)
++#define ARMCR4_BANKIDX                (0x40)
++#define ARMCR4_BANKINFO               (0x44)
++#define ARMCR4_BANKPDA                (0x4C)
++
++#define       ARMCR4_TCBBNB_MASK      0xf0
++#define       ARMCR4_TCBBNB_SHIFT     4
++#define       ARMCR4_TCBANB_MASK      0xf
++#define       ARMCR4_TCBANB_SHIFT     0
++
++#define       ARMCR4_BSZ_MASK         0x3f
++#define       ARMCR4_BSZ_MULT         8192
++
+ struct brcmf_core_priv {
+       struct brcmf_core pub;
+       u32 wrapbase;
+@@ -443,10 +512,6 @@ static int brcmf_chip_cores_check(struct
+                       break;
+               case BCMA_CORE_ARM_CR4:
+                       cpu_found = true;
+-                      if (ci->pub.rambase == 0) {
+-                              brcmf_err("RAM base not provided with ARM CR4 core\n");
+-                              return -ENOMEM;
+-                      }
+                       break;
+               default:
+                       break;
+@@ -462,60 +527,160 @@ static int brcmf_chip_cores_check(struct
+               brcmf_err("RAM core not provided with ARM CM3 core\n");
+               return -ENODEV;
+       }
+-      if (!ci->pub.ramsize) {
+-              brcmf_err("RAM size is undetermined\n");
+-              return -ENOMEM;
+-      }
+       return 0;
+ }
+-static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
++static u32 brcmf_chip_core_read32(struct brcmf_core_priv *core, u16 reg)
+ {
+-      switch (ci->pub.chip) {
+-      case BRCM_CC_4329_CHIP_ID:
+-              ci->pub.ramsize = BCM4329_RAMSIZE;
+-              break;
+-      case BRCM_CC_43143_CHIP_ID:
+-              ci->pub.ramsize = BCM43143_RAMSIZE;
+-              break;
+-      case BRCM_CC_43241_CHIP_ID:
+-              ci->pub.ramsize = 0x90000;
+-              break;
+-      case BRCM_CC_4330_CHIP_ID:
+-              ci->pub.ramsize = 0x48000;
+-              break;
++      return core->chip->ops->read32(core->chip->ctx, core->pub.base + reg);
++}
++
++static void brcmf_chip_core_write32(struct brcmf_core_priv *core,
++                                  u16 reg, u32 val)
++{
++      core->chip->ops->write32(core->chip->ctx, core->pub.base + reg, val);
++}
++
++static bool brcmf_chip_socram_banksize(struct brcmf_core_priv *core, u8 idx,
++                                     u32 *banksize)
++{
++      u32 bankinfo;
++      u32 bankidx = (SOCRAM_MEMTYPE_RAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
++
++      bankidx |= idx;
++      brcmf_chip_core_write32(core, SOCRAMREGOFFS(bankidx), bankidx);
++      bankinfo = brcmf_chip_core_read32(core, SOCRAMREGOFFS(bankinfo));
++      *banksize = (bankinfo & SOCRAM_BANKINFO_SZMASK) + 1;
++      *banksize *= SOCRAM_BANKINFO_SZBASE;
++      return !!(bankinfo & SOCRAM_BANKINFO_RETNTRAM_MASK);
++}
++
++static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize,
++                                    u32 *srsize)
++{
++      u32 coreinfo;
++      uint nb, banksize, lss;
++      bool retent;
++      int i;
++
++      *ramsize = 0;
++      *srsize = 0;
++
++      if (WARN_ON(sr->pub.rev < 4))
++              return;
++
++      if (!brcmf_chip_iscoreup(&sr->pub))
++              brcmf_chip_resetcore(&sr->pub, 0, 0, 0);
++
++      /* Get info for determining size */
++      coreinfo = brcmf_chip_core_read32(sr, SOCRAMREGOFFS(coreinfo));
++      nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
++
++      if ((sr->pub.rev <= 7) || (sr->pub.rev == 12)) {
++              banksize = (coreinfo & SRCI_SRBSZ_MASK);
++              lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
++              if (lss != 0)
++                      nb--;
++              *ramsize = nb * (1 << (banksize + SR_BSZ_BASE));
++              if (lss != 0)
++                      *ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
++      } else {
++              nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
++              for (i = 0; i < nb; i++) {
++                      retent = brcmf_chip_socram_banksize(sr, i, &banksize);
++                      *ramsize += banksize;
++                      if (retent)
++                              *srsize += banksize;
++              }
++      }
++
++      /* hardcoded save&restore memory sizes */
++      switch (sr->chip->pub.chip) {
+       case BRCM_CC_4334_CHIP_ID:
+-      case BRCM_CC_43340_CHIP_ID:
+-              ci->pub.ramsize = 0x80000;
++              if (sr->chip->pub.chiprev < 2)
++                      *srsize = (32 * 1024);
+               break;
+-      case BRCM_CC_4335_CHIP_ID:
+-              ci->pub.ramsize = 0xc0000;
+-              ci->pub.rambase = 0x180000;
+-              break;
+-      case BRCM_CC_43362_CHIP_ID:
+-              ci->pub.ramsize = 0x3c000;
++      default:
+               break;
++      }
++}
++
++/** Return the TCM-RAM size of the ARMCR4 core. */
++static u32 brcmf_chip_tcm_ramsize(struct brcmf_core_priv *cr4)
++{
++      u32 corecap;
++      u32 memsize = 0;
++      u32 nab;
++      u32 nbb;
++      u32 totb;
++      u32 bxinfo;
++      u32 idx;
++
++      corecap = brcmf_chip_core_read32(cr4, ARMCR4_CAP);
++
++      nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
++      nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
++      totb = nab + nbb;
++
++      for (idx = 0; idx < totb; idx++) {
++              brcmf_chip_core_write32(cr4, ARMCR4_BANKIDX, idx);
++              bxinfo = brcmf_chip_core_read32(cr4, ARMCR4_BANKINFO);
++              memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT;
++      }
++
++      return memsize;
++}
++
++static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
++{
++      switch (ci->pub.chip) {
+       case BRCM_CC_4345_CHIP_ID:
+-              ci->pub.ramsize = 0xc8000;
+-              ci->pub.rambase = 0x198000;
+-              break;
++              return 0x198000;
++      case BRCM_CC_4335_CHIP_ID:
+       case BRCM_CC_4339_CHIP_ID:
+       case BRCM_CC_4354_CHIP_ID:
+       case BRCM_CC_4356_CHIP_ID:
+       case BRCM_CC_43567_CHIP_ID:
+       case BRCM_CC_43569_CHIP_ID:
+       case BRCM_CC_43570_CHIP_ID:
+-              ci->pub.ramsize = 0xc0000;
+-              ci->pub.rambase = 0x180000;
+-              break;
+       case BRCM_CC_43602_CHIP_ID:
+-              ci->pub.ramsize = 0xf0000;
+-              ci->pub.rambase = 0x180000;
+-              break;
++              return 0x180000;
+       default:
+               brcmf_err("unknown chip: %s\n", ci->pub.name);
+               break;
+       }
++      return 0;
++}
++
++static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
++{
++      struct brcmf_core_priv *mem_core;
++      struct brcmf_core *mem;
++
++      mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4);
++      if (mem) {
++              mem_core = container_of(mem, struct brcmf_core_priv, pub);
++              ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core);
++              ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
++              if (!ci->pub.rambase) {
++                      brcmf_err("RAM base not provided with ARM CR4 core\n");
++                      return -EINVAL;
++              }
++      } else {
++              mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_INTERNAL_MEM);
++              mem_core = container_of(mem, struct brcmf_core_priv, pub);
++              brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize,
++                                        &ci->pub.srsize);
++      }
++      brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n",
++                ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize,
++                ci->pub.srsize, ci->pub.srsize);
++
++      if (!ci->pub.ramsize) {
++              brcmf_err("RAM size is undetermined\n");
++              return -ENOMEM;
++      }
++      return 0;
+ }
+ static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
+@@ -668,6 +833,7 @@ static int brcmf_chip_recognition(struct
+       struct brcmf_core *core;
+       u32 regdata;
+       u32 socitype;
++      int ret;
+       /* Get CC core rev
+        * Chipid is assume to be at offset 0 from SI_ENUM_BASE
+@@ -720,9 +886,13 @@ static int brcmf_chip_recognition(struct
+               return -ENODEV;
+       }
+-      brcmf_chip_get_raminfo(ci);
+-
+-      return brcmf_chip_cores_check(ci);
++      ret = brcmf_chip_cores_check(ci);
++      if (ret)
++              return ret;
++
++      /* assure chip is passive for core access */
++      brcmf_chip_set_passive(&ci->pub);
++      return brcmf_chip_get_raminfo(ci);
+ }
+ static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
+@@ -827,8 +997,6 @@ struct brcmf_chip *brcmf_chip_attach(voi
+       if (err < 0)
+               goto fail;
+-      /* assure chip is passive for download */
+-      brcmf_chip_set_passive(&chip->pub);
+       return &chip->pub;
+ fail:
+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
+@@ -30,7 +30,8 @@
+  * @pmucaps: PMU capabilities.
+  * @pmurev: PMU revision.
+  * @rambase: RAM base address (only applicable for ARM CR4 chips).
+- * @ramsize: amount of RAM on chip.
++ * @ramsize: amount of RAM on chip including retention.
++ * @srsize: amount of retention RAM on chip.
+  * @name: string representation of the chip identifier.
+  */
+ struct brcmf_chip {
+@@ -41,6 +42,7 @@ struct brcmf_chip {
+       u32 pmurev;
+       u32 rambase;
+       u32 ramsize;
++      u32 srsize;
+       char name[8];
+ };
diff --git a/package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch b/package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch
new file mode 100644 (file)
index 0000000..69618a7
--- /dev/null
@@ -0,0 +1,96 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 11 Mar 2015 16:11:32 +0100
+Subject: [PATCH] brcmfmac: take save&restore memory into account for SDIO
+ shared info
+
+The firmware provides pointer to SDIO shared information at end of
+RAM during firmware initialization. End of RAM is obviously determined
+by the actual ram size, but part of that may be used for save&restore
+memory. In that case another location in RAM will hold the pointer.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -1067,44 +1067,47 @@ static inline bool brcmf_sdio_valid_shar
+ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
+                                struct sdpcm_shared *sh)
+ {
+-      u32 addr;
++      u32 addr = 0;
+       int rv;
+       u32 shaddr = 0;
+       struct sdpcm_shared_le sh_le;
+       __le32 addr_le;
+-      shaddr = bus->ci->rambase + bus->ci->ramsize - 4;
++      sdio_claim_host(bus->sdiodev->func[1]);
++      brcmf_sdio_bus_sleep(bus, false, false);
+       /*
+        * Read last word in socram to determine
+        * address of sdpcm_shared structure
+        */
+-      sdio_claim_host(bus->sdiodev->func[1]);
+-      brcmf_sdio_bus_sleep(bus, false, false);
+-      rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4);
+-      sdio_release_host(bus->sdiodev->func[1]);
++      shaddr = bus->ci->rambase + bus->ci->ramsize - 4;
++      if (!bus->ci->rambase && brcmf_chip_sr_capable(bus->ci))
++              shaddr -= bus->ci->srsize;
++      rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr,
++                             (u8 *)&addr_le, 4);
+       if (rv < 0)
+-              return rv;
+-
+-      addr = le32_to_cpu(addr_le);
+-
+-      brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
++              goto fail;
+       /*
+        * Check if addr is valid.
+        * NVRAM length at the end of memory should have been overwritten.
+        */
++      addr = le32_to_cpu(addr_le);
+       if (!brcmf_sdio_valid_shared_address(addr)) {
+-                      brcmf_err("invalid sdpcm_shared address 0x%08X\n",
+-                                addr);
+-                      return -EINVAL;
++              brcmf_err("invalid sdpcm_shared address 0x%08X\n", addr);
++              rv = -EINVAL;
++              goto fail;
+       }
++      brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr);
++
+       /* Read hndrte_shared structure */
+       rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
+                              sizeof(struct sdpcm_shared_le));
+       if (rv < 0)
+-              return rv;
++              goto fail;
++
++      sdio_release_host(bus->sdiodev->func[1]);
+       /* Endianness */
+       sh->flags = le32_to_cpu(sh_le.flags);
+@@ -1121,8 +1124,13 @@ static int brcmf_sdio_readshared(struct
+                         sh->flags & SDPCM_SHARED_VERSION_MASK);
+               return -EPROTO;
+       }
+-
+       return 0;
++
++fail:
++      brcmf_err("unable to obtain sdpcm_shared info: rv=%d (addr=0x%x)\n",
++                rv, addr);
++      sdio_release_host(bus->sdiodev->func[1]);
++      return rv;
+ }
+ static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
diff --git a/package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch b/package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch
new file mode 100644 (file)
index 0000000..1b10dbb
--- /dev/null
@@ -0,0 +1,59 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 11 Mar 2015 16:11:33 +0100
+Subject: [PATCH] brcmfmac: fix watchdog timer regression
+
+The watchdog timer is used to put the device in a low-power mode when
+it is idle for some time. This timer is stopped during that mode and
+should be restarted upon activity. This has been broken by commit
+d4150fced0365 ("brcmfmac: Simplify watchdog sleep."). This patch
+restores the behaviour as it was before that commit.
+
+Reported-by: Pontus Fuchs <pontusf@broadcom.com>
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -972,7 +972,6 @@ static int brcmf_sdio_clkctl(struct brcm
+                       brcmf_sdio_sdclk(bus, true);
+               /* Now request HT Avail on the backplane */
+               brcmf_sdio_htclk(bus, true, pendok);
+-              brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
+               break;
+       case CLK_SDONLY:
+@@ -984,7 +983,6 @@ static int brcmf_sdio_clkctl(struct brcm
+               else
+                       brcmf_err("request for %d -> %d\n",
+                                 bus->clkstate, target);
+-              brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
+               break;
+       case CLK_NONE:
+@@ -993,7 +991,6 @@ static int brcmf_sdio_clkctl(struct brcm
+                       brcmf_sdio_htclk(bus, false, false);
+               /* Now remove the SD clock */
+               brcmf_sdio_sdclk(bus, false);
+-              brcmf_sdio_wd_timer(bus, 0);
+               break;
+       }
+ #ifdef DEBUG
+@@ -1048,6 +1045,7 @@ end:
+                       brcmf_sdio_clkctl(bus, CLK_NONE, pendok);
+       } else {
+               brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
++              brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
+       }
+       bus->sleeping = sleep;
+       brcmf_dbg(SDIO, "new state %s\n",
+@@ -4242,6 +4240,7 @@ void brcmf_sdio_remove(struct brcmf_sdio
+               if (bus->ci) {
+                       if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
+                               sdio_claim_host(bus->sdiodev->func[1]);
++                              brcmf_sdio_wd_timer(bus, 0);
+                               brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
+                               /* Leave the device in state where it is
+                                * 'passive'. This is done by resetting all
diff --git a/package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch b/package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch
new file mode 100644 (file)
index 0000000..af76f13
--- /dev/null
@@ -0,0 +1,44 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 18 Mar 2015 13:25:21 +0100
+Subject: [PATCH] brcmfmac: avoid runtime-pm for sdio host controller
+
+Several host controllers supporting runtime-pm are causing issues
+with our sdio wireless cards because they disable the sdio interrupt
+upon going into runtime suspend. This patch avoids that by doing
+a pm_runtime_forbid() call during the probe. Tested with Sony Vaio
+Duo 13 which uses sdhci-acpi host controller.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+@@ -29,6 +29,7 @@
+ #include <linux/mmc/host.h>
+ #include <linux/platform_device.h>
+ #include <linux/platform_data/brcmfmac-sdio.h>
++#include <linux/pm_runtime.h>
+ #include <linux/suspend.h>
+ #include <linux/errno.h>
+ #include <linux/module.h>
+@@ -1006,6 +1007,7 @@ static int brcmf_sdiod_remove(struct brc
+       sg_free_table(&sdiodev->sgtable);
+       sdiodev->sbwad = 0;
++      pm_runtime_allow(sdiodev->func[1]->card->host->parent);
+       return 0;
+ }
+@@ -1074,7 +1076,7 @@ static int brcmf_sdiod_probe(struct brcm
+               ret = -ENODEV;
+               goto out;
+       }
+-
++      pm_runtime_forbid(host->parent);
+ out:
+       if (ret)
+               brcmf_sdiod_remove(sdiodev);
diff --git a/package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch b/package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch
new file mode 100644 (file)
index 0000000..c419cc6
--- /dev/null
@@ -0,0 +1,171 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Wed, 18 Mar 2015 13:25:22 +0100
+Subject: [PATCH] brcmfmac: Add necessary memory barriers for SDIO.
+
+SDIO uses a thread to handle all communication with the device,
+for this data is exchanged between threads. This data needs proper
+memory barriers to make sure that data "exchange" is going correct.
+
+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
+Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -507,8 +507,8 @@ struct brcmf_sdio {
+       struct workqueue_struct *brcmf_wq;
+       struct work_struct datawork;
+-      atomic_t dpc_tskcnt;
+-      atomic_t dpc_running;
++      bool dpc_triggered;
++      bool dpc_running;
+       bool txoff;             /* Transmit flow-controlled */
+       struct brcmf_sdio_count sdcnt;
+@@ -2713,6 +2713,7 @@ static void brcmf_sdio_dpc(struct brcmf_
+                       err = brcmf_sdio_tx_ctrlframe(bus,  bus->ctrl_frame_buf,
+                                                     bus->ctrl_frame_len);
+                       bus->ctrl_frame_err = err;
++                      wmb();
+                       bus->ctrl_frame_stat = false;
+               }
+               sdio_release_host(bus->sdiodev->func[1]);
+@@ -2734,6 +2735,7 @@ static void brcmf_sdio_dpc(struct brcmf_
+                       sdio_claim_host(bus->sdiodev->func[1]);
+                       if (bus->ctrl_frame_stat) {
+                               bus->ctrl_frame_err = -ENODEV;
++                              wmb();
+                               bus->ctrl_frame_stat = false;
+                               brcmf_sdio_wait_event_wakeup(bus);
+                       }
+@@ -2744,7 +2746,7 @@ static void brcmf_sdio_dpc(struct brcmf_
+                  (!atomic_read(&bus->fcstate) &&
+                   brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
+                   data_ok(bus))) {
+-              atomic_inc(&bus->dpc_tskcnt);
++              bus->dpc_triggered = true;
+       }
+ }
+@@ -2940,6 +2942,7 @@ brcmf_sdio_bus_txctl(struct device *dev,
+       /* Send from dpc */
+       bus->ctrl_frame_buf = msg;
+       bus->ctrl_frame_len = msglen;
++      wmb();
+       bus->ctrl_frame_stat = true;
+       brcmf_sdio_trigger_dpc(bus);
+@@ -2958,6 +2961,7 @@ brcmf_sdio_bus_txctl(struct device *dev,
+       if (!ret) {
+               brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n",
+                         bus->ctrl_frame_err);
++              rmb();
+               ret = bus->ctrl_frame_err;
+       }
+@@ -3526,8 +3530,8 @@ done:
+ void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus)
+ {
+-      if (atomic_read(&bus->dpc_tskcnt) == 0) {
+-              atomic_inc(&bus->dpc_tskcnt);
++      if (!bus->dpc_triggered) {
++              bus->dpc_triggered = true;
+               queue_work(bus->brcmf_wq, &bus->datawork);
+       }
+ }
+@@ -3558,7 +3562,7 @@ void brcmf_sdio_isr(struct brcmf_sdio *b
+       if (!bus->intr)
+               brcmf_err("isr w/o interrupt configured!\n");
+-      atomic_inc(&bus->dpc_tskcnt);
++      bus->dpc_triggered = true;
+       queue_work(bus->brcmf_wq, &bus->datawork);
+ }
+@@ -3578,7 +3582,7 @@ static void brcmf_sdio_bus_watchdog(stru
+               if (!bus->intr ||
+                   (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) {
+-                      if (atomic_read(&bus->dpc_tskcnt) == 0) {
++                      if (!bus->dpc_triggered) {
+                               u8 devpend;
+                               sdio_claim_host(bus->sdiodev->func[1]);
+@@ -3596,7 +3600,7 @@ static void brcmf_sdio_bus_watchdog(stru
+                               bus->sdcnt.pollcnt++;
+                               atomic_set(&bus->ipend, 1);
+-                              atomic_inc(&bus->dpc_tskcnt);
++                              bus->dpc_triggered = true;
+                               queue_work(bus->brcmf_wq, &bus->datawork);
+                       }
+               }
+@@ -3623,17 +3627,21 @@ static void brcmf_sdio_bus_watchdog(stru
+ #endif                                /* DEBUG */
+       /* On idle timeout clear activity flag and/or turn off clock */
+-      if ((atomic_read(&bus->dpc_tskcnt) == 0) &&
+-          (atomic_read(&bus->dpc_running) == 0) &&
+-          (bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) {
+-              bus->idlecount++;
+-              if (bus->idlecount > bus->idletime) {
+-                      brcmf_dbg(SDIO, "idle\n");
+-                      sdio_claim_host(bus->sdiodev->func[1]);
+-                      brcmf_sdio_wd_timer(bus, 0);
++      if (!bus->dpc_triggered) {
++              rmb();
++              if ((!bus->dpc_running) && (bus->idletime > 0) &&
++                  (bus->clkstate == CLK_AVAIL)) {
++                      bus->idlecount++;
++                      if (bus->idlecount > bus->idletime) {
++                              brcmf_dbg(SDIO, "idle\n");
++                              sdio_claim_host(bus->sdiodev->func[1]);
++                              brcmf_sdio_wd_timer(bus, 0);
++                              bus->idlecount = 0;
++                              brcmf_sdio_bus_sleep(bus, true, false);
++                              sdio_release_host(bus->sdiodev->func[1]);
++                      }
++              } else {
+                       bus->idlecount = 0;
+-                      brcmf_sdio_bus_sleep(bus, true, false);
+-                      sdio_release_host(bus->sdiodev->func[1]);
+               }
+       } else {
+               bus->idlecount = 0;
+@@ -3645,13 +3653,14 @@ static void brcmf_sdio_dataworker(struct
+       struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio,
+                                             datawork);
+-      while (atomic_read(&bus->dpc_tskcnt)) {
+-              atomic_set(&bus->dpc_running, 1);
+-              atomic_set(&bus->dpc_tskcnt, 0);
++      bus->dpc_running = true;
++      wmb();
++      while (ACCESS_ONCE(bus->dpc_triggered)) {
++              bus->dpc_triggered = false;
+               brcmf_sdio_dpc(bus);
+               bus->idlecount = 0;
+-              atomic_set(&bus->dpc_running, 0);
+       }
++      bus->dpc_running = false;
+       if (brcmf_sdiod_freezing(bus->sdiodev)) {
+               brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
+               brcmf_sdiod_try_freeze(bus->sdiodev);
+@@ -4144,8 +4153,8 @@ struct brcmf_sdio *brcmf_sdio_probe(stru
+               bus->watchdog_tsk = NULL;
+       }
+       /* Initialize DPC thread */
+-      atomic_set(&bus->dpc_tskcnt, 0);
+-      atomic_set(&bus->dpc_running, 0);
++      bus->dpc_triggered = false;
++      bus->dpc_running = false;
+       /* Assign bus interface call back */
+       bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
diff --git a/package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch b/package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch
new file mode 100644 (file)
index 0000000..1bc98a0
--- /dev/null
@@ -0,0 +1,26 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Wed, 18 Mar 2015 13:25:24 +0100
+Subject: [PATCH] brcmfmac: Remove unnecessary new-line in pcie console
+ logging.
+
+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+@@ -651,10 +651,9 @@ static void brcmf_pcie_bus_console_read(
+                       console->log_str[console->log_idx] = ch;
+                       console->log_idx++;
+               }
+-
+               if (ch == '\n') {
+                       console->log_str[console->log_idx] = 0;
+-                      brcmf_dbg(PCIE, "CONSOLE: %s\n", console->log_str);
++                      brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str);
+                       console->log_idx = 0;
+               }
+       }
diff --git a/package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch b/package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch
new file mode 100644 (file)
index 0000000..fcf0bf3
--- /dev/null
@@ -0,0 +1,26 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 18 Mar 2015 13:25:25 +0100
+Subject: [PATCH] brcmfmac: add MODULE_FIRMWARE() macros for bcm4356 PCIe
+ device
+
+The BCM4356 PCIe wireless device was added recently but overlooked
+the fact that the MODULE_FIRMWARE() macros were missing for the
+firmwares needed by this device.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+@@ -189,6 +189,8 @@ MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME
+ MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME);
++MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME);
++MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME);
diff --git a/package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch b/package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch
new file mode 100644 (file)
index 0000000..b3e9bc9
--- /dev/null
@@ -0,0 +1,138 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 18 Mar 2015 13:25:26 +0100
+Subject: [PATCH] brcmfmac: add support for BCM43430 SDIO chipset
+
+This patch added support for the BCM43430 802.11n SDIO chipset.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+@@ -1098,6 +1098,7 @@ static const struct sdio_device_id brcmf
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
++      BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
+       BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
+       { /* end: all zeroes */ }
+--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+@@ -600,6 +600,12 @@ static void brcmf_chip_socram_ramsize(st
+               if (sr->chip->pub.chiprev < 2)
+                       *srsize = (32 * 1024);
+               break;
++      case BRCM_CC_43430_CHIP_ID:
++              /* assume sr for now as we can not check
++               * firmware sr capability at this point.
++               */
++              *srsize = (64 * 1024);
++              break;
+       default:
+               break;
+       }
+@@ -1072,6 +1078,7 @@ static void
+ brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)
+ {
+       struct brcmf_core *core;
++      struct brcmf_core_priv *sr;
+       brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
+       core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
+@@ -1081,6 +1088,13 @@ brcmf_chip_cm3_set_passive(struct brcmf_
+                            D11_BCMA_IOCTL_PHYCLOCKEN);
+       core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
+       brcmf_chip_resetcore(core, 0, 0, 0);
++
++      /* disable bank #3 remap for this device */
++      if (chip->pub.chip == BRCM_CC_43430_CHIP_ID) {
++              sr = container_of(core, struct brcmf_core_priv, pub);
++              brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3);
++              brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0);
++      }
+ }
+ static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip)
+@@ -1188,6 +1202,10 @@ bool brcmf_chip_sr_capable(struct brcmf_
+               addr = CORE_CC_REG(base, chipcontrol_data);
+               reg = chip->ops->read32(chip->ctx, addr);
+               return (reg & pmu_cc3_mask) != 0;
++      case BRCM_CC_43430_CHIP_ID:
++              addr = CORE_CC_REG(base, sr_control1);
++              reg = chip->ops->read32(chip->ctx, addr);
++              return reg != 0;
+       default:
+               addr = CORE_CC_REG(base, pmucapabilities_ext);
+               reg = chip->ops->read32(chip->ctx, addr);
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -615,6 +615,8 @@ static const struct sdiod_drive_str sdio
+ #define BCM43362_NVRAM_NAME           "brcm/brcmfmac43362-sdio.txt"
+ #define BCM4339_FIRMWARE_NAME         "brcm/brcmfmac4339-sdio.bin"
+ #define BCM4339_NVRAM_NAME            "brcm/brcmfmac4339-sdio.txt"
++#define BCM43430_FIRMWARE_NAME                "brcm/brcmfmac43430-sdio.bin"
++#define BCM43430_NVRAM_NAME           "brcm/brcmfmac43430-sdio.txt"
+ #define BCM4345_FIRMWARE_NAME         "brcm/brcmfmac4345-sdio.bin"
+ #define BCM4345_NVRAM_NAME            "brcm/brcmfmac4345-sdio.txt"
+ #define BCM4354_FIRMWARE_NAME         "brcm/brcmfmac4354-sdio.bin"
+@@ -640,6 +642,8 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);
+ MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
+ MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
+ MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
++MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME);
++MODULE_FIRMWARE(BCM43430_NVRAM_NAME);
+ MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME);
+ MODULE_FIRMWARE(BCM4345_NVRAM_NAME);
+ MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
+@@ -671,6 +675,7 @@ static const struct brcmf_firmware_names
+       { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
+       { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
+       { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
++      { BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) },
+       { BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) },
+       { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
+ };
+--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+@@ -37,6 +37,7 @@
+ #define BRCM_CC_43362_CHIP_ID         43362
+ #define BRCM_CC_4335_CHIP_ID          0x4335
+ #define BRCM_CC_4339_CHIP_ID          0x4339
++#define BRCM_CC_43430_CHIP_ID         43430
+ #define BRCM_CC_4345_CHIP_ID          0x4345
+ #define BRCM_CC_4354_CHIP_ID          0x4354
+ #define BRCM_CC_4356_CHIP_ID          0x4356
+--- a/drivers/net/wireless/brcm80211/include/chipcommon.h
++++ b/drivers/net/wireless/brcm80211/include/chipcommon.h
+@@ -183,7 +183,14 @@ struct chipcregs {
+       u8 uart1lsr;
+       u8 uart1msr;
+       u8 uart1scratch;
+-      u32 PAD[126];
++      u32 PAD[62];
++
++      /* save/restore, corerev >= 48 */
++      u32 sr_capability;          /* 0x500 */
++      u32 sr_control0;            /* 0x504 */
++      u32 sr_control1;            /* 0x508 */
++      u32 gpio_control;           /* 0x50C */
++      u32 PAD[60];
+       /* PMU registers (corerev >= 20) */
+       u32 pmucontrol; /* 0x600 */
+--- a/include/linux/mmc/sdio_ids.h
++++ b/include/linux/mmc/sdio_ids.h
+@@ -33,6 +33,7 @@
+ #define SDIO_DEVICE_ID_BROADCOM_43341         0xa94d
+ #define SDIO_DEVICE_ID_BROADCOM_4335_4339     0x4335
+ #define SDIO_DEVICE_ID_BROADCOM_43362         0xa962
++#define SDIO_DEVICE_ID_BROADCOM_43430         0xa9a6
+ #define SDIO_DEVICE_ID_BROADCOM_4345          0x4345
+ #define SDIO_DEVICE_ID_BROADCOM_4354          0x4354
diff --git a/package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch b/package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch
new file mode 100644 (file)
index 0000000..c3d7bc2
--- /dev/null
@@ -0,0 +1,50 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 18 Mar 2015 13:25:27 +0100
+Subject: [PATCH] brcmfmac: only support the BCM43455/7 device
+
+Recently support was added for the BCM4345 SDIO chipset by
+commit 9c51026509d7 ("brcmfmac: Add support for BCM4345 SDIO chipset")
+however this was verified using a BCM43455 device, which is
+a more recent revision of the chip. This patch assure that
+older revisions are not probed as they would fail.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Syed Asifful Dayyan <syedd@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+@@ -617,8 +617,8 @@ static const struct sdiod_drive_str sdio
+ #define BCM4339_NVRAM_NAME            "brcm/brcmfmac4339-sdio.txt"
+ #define BCM43430_FIRMWARE_NAME                "brcm/brcmfmac43430-sdio.bin"
+ #define BCM43430_NVRAM_NAME           "brcm/brcmfmac43430-sdio.txt"
+-#define BCM4345_FIRMWARE_NAME         "brcm/brcmfmac4345-sdio.bin"
+-#define BCM4345_NVRAM_NAME            "brcm/brcmfmac4345-sdio.txt"
++#define BCM43455_FIRMWARE_NAME                "brcm/brcmfmac43455-sdio.bin"
++#define BCM43455_NVRAM_NAME           "brcm/brcmfmac43455-sdio.txt"
+ #define BCM4354_FIRMWARE_NAME         "brcm/brcmfmac4354-sdio.bin"
+ #define BCM4354_NVRAM_NAME            "brcm/brcmfmac4354-sdio.txt"
+@@ -644,8 +644,8 @@ MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
+ MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
+ MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME);
+ MODULE_FIRMWARE(BCM43430_NVRAM_NAME);
+-MODULE_FIRMWARE(BCM4345_FIRMWARE_NAME);
+-MODULE_FIRMWARE(BCM4345_NVRAM_NAME);
++MODULE_FIRMWARE(BCM43455_FIRMWARE_NAME);
++MODULE_FIRMWARE(BCM43455_NVRAM_NAME);
+ MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
+ MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
+@@ -676,7 +676,7 @@ static const struct brcmf_firmware_names
+       { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
+       { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
+       { BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) },
+-      { BRCM_CC_4345_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4345) },
++      { BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, BRCMF_FIRMWARE_NVRAM(BCM43455) },
+       { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
+ };
diff --git a/package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch b/package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch
new file mode 100644 (file)
index 0000000..a62cfdf
--- /dev/null
@@ -0,0 +1,52 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Wed, 18 Mar 2015 13:25:28 +0100
+Subject: [PATCH] brcmfmac: remove support for unreleased BCM4354 PCIe
+
+There are no known BCM4354 PCIe devices released so removing
+support from the driver until proven otherwise.
+
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+@@ -47,8 +47,6 @@ enum brcmf_pcie_state {
+ #define BRCMF_PCIE_43602_FW_NAME              "brcm/brcmfmac43602-pcie.bin"
+ #define BRCMF_PCIE_43602_NVRAM_NAME           "brcm/brcmfmac43602-pcie.txt"
+-#define BRCMF_PCIE_4354_FW_NAME                       "brcm/brcmfmac4354-pcie.bin"
+-#define BRCMF_PCIE_4354_NVRAM_NAME            "brcm/brcmfmac4354-pcie.txt"
+ #define BRCMF_PCIE_4356_FW_NAME                       "brcm/brcmfmac4356-pcie.bin"
+ #define BRCMF_PCIE_4356_NVRAM_NAME            "brcm/brcmfmac4356-pcie.txt"
+ #define BRCMF_PCIE_43570_FW_NAME              "brcm/brcmfmac43570-pcie.bin"
+@@ -187,8 +185,6 @@ enum brcmf_pcie_state {
+ MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME);
+-MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME);
+-MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
+@@ -1327,10 +1323,6 @@ static int brcmf_pcie_get_fwnames(struct
+               fw_name = BRCMF_PCIE_43602_FW_NAME;
+               nvram_name = BRCMF_PCIE_43602_NVRAM_NAME;
+               break;
+-      case BRCM_CC_4354_CHIP_ID:
+-              fw_name = BRCMF_PCIE_4354_FW_NAME;
+-              nvram_name = BRCMF_PCIE_4354_NVRAM_NAME;
+-              break;
+       case BRCM_CC_4356_CHIP_ID:
+               fw_name = BRCMF_PCIE_4356_FW_NAME;
+               nvram_name = BRCMF_PCIE_4356_NVRAM_NAME;
+@@ -1855,7 +1847,6 @@ cleanup:
+       PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 }
+ static struct pci_device_id brcmf_pcie_devid_table[] = {
+-      BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_DEVICE_ID),
+       BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
+       BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
+       BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
diff --git a/package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch b/package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch
new file mode 100644 (file)
index 0000000..366ff85
--- /dev/null
@@ -0,0 +1,28 @@
+From: Arend van Spriel <arend@broadcom.com>
+Date: Fri, 20 Mar 2015 22:18:17 +0100
+Subject: [PATCH] brcmfmac: disable MBSS feature for BCM43362
+
+The BCM43362 firmware falsely reports it is capable of providing
+MBSS. As a result AP mode no longer works for this device. Therefor
+disable MBSS in the driver for this chipset.
+
+Cc: stable@vger.kernel.org # 3.19.y
+Reported-by: Jorg Krause <jkrause@posteo.de>
+Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
+Signed-off-by: Arend van Spriel <arend@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+
+--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
+@@ -126,7 +126,8 @@ void brcmf_feat_attach(struct brcmf_pub
+       brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
+       if (drvr->bus_if->wowl_supported)
+               brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_WOWL, "wowl");
+-      brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
++      if (drvr->bus_if->chip != BRCM_CC_43362_CHIP_ID)
++              brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
+       /* set chip related quirks */
+       switch (drvr->bus_if->chip) {