aboutsummaryrefslogtreecommitdiffstats
path: root/package
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2015-04-24 10:45:33 +0000
committerRafał Miłecki <zajec5@gmail.com>2015-04-24 10:45:33 +0000
commitc1a7e135873d5def34db3b9393e18241a8cf3231 (patch)
treebb70f57269d74d2950c773774a931b202d361684 /package
parent33e597b2417e2bc12559333f1c5374778935a8e1 (diff)
downloadupstream-c1a7e135873d5def34db3b9393e18241a8cf3231.tar.gz
upstream-c1a7e135873d5def34db3b9393e18241a8cf3231.tar.bz2
upstream-c1a7e135873d5def34db3b9393e18241a8cf3231.zip
mac80211: update brcmfmac to the wireless-drivers-next-for-davem-2015-04-09
Signed-off-by: Rafał Miłecki <zajec5@gmail.com> SVN-Revision: 45576
Diffstat (limited to 'package')
-rw-r--r--package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch44
-rw-r--r--package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch157
-rw-r--r--package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch83
-rw-r--r--package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch86
-rw-r--r--package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch48
-rw-r--r--package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch74
-rw-r--r--package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch240
-rw-r--r--package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch61
-rw-r--r--package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch367
-rw-r--r--package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch96
-rw-r--r--package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch59
-rw-r--r--package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch44
-rw-r--r--package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch171
-rw-r--r--package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch26
-rw-r--r--package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch26
-rw-r--r--package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch138
-rw-r--r--package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch50
-rw-r--r--package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch52
-rw-r--r--package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch28
19 files changed, 1850 insertions, 0 deletions
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
index 0000000000..5e63a803b0
--- /dev/null
+++ b/package/kernel/mac80211/patches/335-brcmfmac-Fix-oops-when-SDIO-device-is-removed.patch
@@ -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
index 0000000000..201da75bfc
--- /dev/null
+++ b/package/kernel/mac80211/patches/336-brcmfmac-Simplify-watchdog-sleep.patch
@@ -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
index 0000000000..3a2de7a944
--- /dev/null
+++ b/package/kernel/mac80211/patches/337-brcmfmac-Fix-possible-race-condition.patch
@@ -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
index 0000000000..c9eb9008a6
--- /dev/null
+++ b/package/kernel/mac80211/patches/338-brcmfmac-Add-support-for-BCM4345-SDIO-chipset.patch
@@ -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
index 0000000000..7a688c4be6
--- /dev/null
+++ b/package/kernel/mac80211/patches/339-brcmfmac-remove-duplication-of-ramsize-info.patch
@@ -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
index 0000000000..e2a2074247
--- /dev/null
+++ b/package/kernel/mac80211/patches/340-brcmfmac-always-perform-cores-checks.patch
@@ -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
index 0000000000..a272800577
--- /dev/null
+++ b/package/kernel/mac80211/patches/341-brcmfmac-rename-chip-download-functions.patch
@@ -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
index 0000000000..6b1dd8144f
--- /dev/null
+++ b/package/kernel/mac80211/patches/342-brcmfmac-assure-device-is-ready-for-download-after-b.patch
@@ -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
index 0000000000..bcc2ed4868
--- /dev/null
+++ b/package/kernel/mac80211/patches/343-brcmfmac-extract-ram-size-info-from-internal-memory-.patch
@@ -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
index 0000000000..69618a7aa7
--- /dev/null
+++ b/package/kernel/mac80211/patches/344-brcmfmac-take-save-restore-memory-into-account-for-S.patch
@@ -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
index 0000000000..1b10dbb800
--- /dev/null
+++ b/package/kernel/mac80211/patches/345-brcmfmac-fix-watchdog-timer-regression.patch
@@ -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
index 0000000000..af76f13ecd
--- /dev/null
+++ b/package/kernel/mac80211/patches/346-brcmfmac-avoid-runtime-pm-for-sdio-host-controller.patch
@@ -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
index 0000000000..c419cc68f5
--- /dev/null
+++ b/package/kernel/mac80211/patches/347-brcmfmac-Add-necessary-memory-barriers-for-SDIO.patch
@@ -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
index 0000000000..1bc98a053e
--- /dev/null
+++ b/package/kernel/mac80211/patches/348-brcmfmac-Remove-unnecessary-new-line-in-pcie-console.patch
@@ -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
index 0000000000..fcf0bf34f0
--- /dev/null
+++ b/package/kernel/mac80211/patches/349-brcmfmac-add-MODULE_FIRMWARE-macros-for-bcm4356-PCIe.patch
@@ -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
index 0000000000..b3e9bc9a07
--- /dev/null
+++ b/package/kernel/mac80211/patches/350-brcmfmac-add-support-for-BCM43430-SDIO-chipset.patch
@@ -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
index 0000000000..c3d7bc2cbf
--- /dev/null
+++ b/package/kernel/mac80211/patches/351-brcmfmac-only-support-the-BCM43455-7-device.patch
@@ -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
index 0000000000..a62cfdfc4c
--- /dev/null
+++ b/package/kernel/mac80211/patches/352-brcmfmac-remove-support-for-unreleased-BCM4354-PCIe.patch
@@ -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
index 0000000000..366ff85d03
--- /dev/null
+++ b/package/kernel/mac80211/patches/353-brcmfmac-disable-MBSS-feature-for-BCM43362.patch
@@ -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) {