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 0000000000000000000000000000000000000000..5e63a803b0e817e70ec22e25d3b3c020a3e8cc87
--- /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 0000000000000000000000000000000000000000..201da75bfcfe1942c5d0fd3d71291ecc2186a9f3
--- /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 0000000000000000000000000000000000000000..3a2de7a94431cc6b64b96c3d152cf60af49660c9
--- /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 0000000000000000000000000000000000000000..c9eb9008a6e12b3cafbfd5e2683707bec8aefb21
--- /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 0000000000000000000000000000000000000000..7a688c4be615320a65bd629d03c30e35e9c74b5b
--- /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 0000000000000000000000000000000000000000..e2a20742474c854ad5ead155f26d43ac0450415f
--- /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 0000000000000000000000000000000000000000..a27280057799a012e9062ded954ba63bfb614546
--- /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 0000000000000000000000000000000000000000..6b1dd8144f1347d78285d09af51224217c07a0b2
--- /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 0000000000000000000000000000000000000000..bcc2ed4868265efcef40d2583146da783c7493f4
--- /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 0000000000000000000000000000000000000000..69618a7aa7a4d059d2ffccb57d88556eb294b9b8
--- /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 0000000000000000000000000000000000000000..1b10dbb800aa89411eeb23847a68f441582092ce
--- /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 0000000000000000000000000000000000000000..af76f13ecdc3da223484c08b9929d2efd34666ef
--- /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 0000000000000000000000000000000000000000..c419cc68f5d5d494f36a4c05541169c41949f402
--- /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 0000000000000000000000000000000000000000..1bc98a053ea09c0932670d553146addf95f82b17
--- /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 0000000000000000000000000000000000000000..fcf0bf34f008c9d42ece3f38e9ad93b7264aae17
--- /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 0000000000000000000000000000000000000000..b3e9bc9a072658b27e67f1443346fa83ccafe9d2
--- /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 0000000000000000000000000000000000000000..c3d7bc2cbf6912813642fdc90342360b1fe0d663
--- /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 0000000000000000000000000000000000000000..a62cfdfc4cd4d67628543d38fc8f3cba76b8117c
--- /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 0000000000000000000000000000000000000000..366ff85d035baf33c476be093caa602e44edded6
--- /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) {