[source] mac80211: brcmfmac: backport scheduled scan cleanup and chip support

LEDE Commits lede-commits at lists.infradead.org
Thu Feb 2 02:13:57 PST 2017


rmilecki pushed a commit to source.git, branch master:
https://git.lede-project.org/863a06b0a4ed3939d81fb49d3b8a88db9e807d41

commit 863a06b0a4ed3939d81fb49d3b8a88db9e807d41
Author: Rafał Miłecki <rafal at milecki.pl>
AuthorDate: Thu Feb 2 09:27:20 2017 +0100

    mac80211: brcmfmac: backport scheduled scan cleanup and chip support
    
    Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
---
 ...d-pcie-host-dongle-interface-rev6-support.patch | 490 +++++++++++++++++++++
 ...-0002-brcmfmac-add-support-for-43341-chip.patch |  39 ++
 ...ve-pno-helper-functions-in-separate-sourc.patch | 319 ++++++++++++++
 ...x-handling-ssids-in-.sched_scan_start-cal.patch | 221 ++++++++++
 ...mfmac-change-prototype-for-brcmf_do_escan.patch |  58 +++
 ...brcmfmac-make-internal-escan-more-generic.patch | 306 +++++++++++++
 ...cmfmac-split-up-brcmf_pno_config-function.patch | 176 ++++++++
 ...ve-scheduled-scan-activation-to-pno-sourc.patch | 292 ++++++++++++
 ...-use-provided-channels-for-scheduled-scan.patch | 111 +++++
 ...move-restriction-from-.sched_scan_start-c.patch |  34 ++
 ...e-requested-scan-interval-in-scheduled-sc.patch |  67 +++
 ...x-scheduled-scan-result-handling-for-newe.patch |  76 ++++
 ...oid-writing-channel-out-of-allocated-arra.patch |   6 +-
 ...mac-don-t-preset-all-channels-as-disabled.patch |   4 +-
 ...tup-wiphy-bands-after-registering-it-firs.patch |   4 +-
 ...41-brcmfmac-use-wiphy_read_of_freq_limits.patch |   4 +-
 ...rkaround-bug-with-some-inconsistent-BSSes.patch |   2 +-
 .../862-brcmfmac-Disable-power-management.patch    |   2 +-
 18 files changed, 2200 insertions(+), 11 deletions(-)

diff --git a/package/kernel/mac80211/patches/357-0001-brcmfmac-add-pcie-host-dongle-interface-rev6-support.patch b/package/kernel/mac80211/patches/357-0001-brcmfmac-add-pcie-host-dongle-interface-rev6-support.patch
new file mode 100644
index 0000000..e093913
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0001-brcmfmac-add-pcie-host-dongle-interface-rev6-support.patch
@@ -0,0 +1,490 @@
+From be4b092cab84b2ecc01ee7f4da6a044279430b6f Mon Sep 17 00:00:00 2001
+From: Franky Lin <franky.lin at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:20 +0000
+Subject: [PATCH] brcmfmac: add pcie host dongle interface rev6 support
+
+In rev6 of pcie host dongle interface protocol, host needs to maximum
+supported ring number from dongle shared memory and set up ring buffer
+and ring indices offset accordingly.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h |  10 +-
+ .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.c  |  38 +++--
+ .../wireless/broadcom/brcm80211/brcmfmac/msgbuf.h  |   4 +
+ .../wireless/broadcom/brcm80211/brcmfmac/pcie.c    | 171 ++++++++++++---------
+ 4 files changed, 132 insertions(+), 91 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h
+@@ -22,10 +22,12 @@
+ /* IDs of the 6 default common rings of msgbuf protocol */
+ #define BRCMF_H2D_MSGRING_CONTROL_SUBMIT	0
+ #define BRCMF_H2D_MSGRING_RXPOST_SUBMIT		1
++#define BRCMF_H2D_MSGRING_FLOWRING_IDSTART	2
+ #define BRCMF_D2H_MSGRING_CONTROL_COMPLETE	2
+ #define BRCMF_D2H_MSGRING_TX_COMPLETE		3
+ #define BRCMF_D2H_MSGRING_RX_COMPLETE		4
+ 
++
+ #define BRCMF_NROF_H2D_COMMON_MSGRINGS		2
+ #define BRCMF_NROF_D2H_COMMON_MSGRINGS		3
+ #define BRCMF_NROF_COMMON_MSGRINGS	(BRCMF_NROF_H2D_COMMON_MSGRINGS + \
+@@ -95,14 +97,18 @@ struct brcmf_bus_ops {
+  * @flowrings: commonrings which are dynamically created and destroyed for data.
+  * @rx_dataoffset: if set then all rx data has this this offset.
+  * @max_rxbufpost: maximum number of buffers to post for rx.
+- * @nrof_flowrings: number of flowrings.
++ * @max_flowrings: maximum number of tx flow rings supported.
++ * @max_submissionrings: maximum number of submission rings(h2d) supported.
++ * @max_completionrings: maximum number of completion rings(d2h) supported.
+  */
+ struct brcmf_bus_msgbuf {
+ 	struct brcmf_commonring *commonrings[BRCMF_NROF_COMMON_MSGRINGS];
+ 	struct brcmf_commonring **flowrings;
+ 	u32 rx_dataoffset;
+ 	u32 max_rxbufpost;
+-	u32 nrof_flowrings;
++	u16 max_flowrings;
++	u16 max_submissionrings;
++	u16 max_completionrings;
+ };
+ 
+ 
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
+@@ -87,11 +87,6 @@ struct msgbuf_common_hdr {
+ 	__le32				request_id;
+ };
+ 
+-struct msgbuf_buf_addr {
+-	__le32				low_addr;
+-	__le32				high_addr;
+-};
+-
+ struct msgbuf_ioctl_req_hdr {
+ 	struct msgbuf_common_hdr	msg;
+ 	__le32				cmd;
+@@ -227,7 +222,10 @@ struct brcmf_msgbuf {
+ 	struct brcmf_commonring **commonrings;
+ 	struct brcmf_commonring **flowrings;
+ 	dma_addr_t *flowring_dma_handle;
+-	u16 nrof_flowrings;
++
++	u16 max_flowrings;
++	u16 max_submissionrings;
++	u16 max_completionrings;
+ 
+ 	u16 rx_dataoffset;
+ 	u32 max_rxbufpost;
+@@ -610,7 +608,7 @@ brcmf_msgbuf_flowring_create_worker(stru
+ 	create->msg.request_id = 0;
+ 	create->tid = brcmf_flowring_tid(msgbuf->flow, flowid);
+ 	create->flow_ring_id = cpu_to_le16(flowid +
+-					   BRCMF_NROF_H2D_COMMON_MSGRINGS);
++					   BRCMF_H2D_MSGRING_FLOWRING_IDSTART);
+ 	memcpy(create->sa, work->sa, ETH_ALEN);
+ 	memcpy(create->da, work->da, ETH_ALEN);
+ 	address = (u64)msgbuf->flowring_dma_handle[flowid];
+@@ -760,7 +758,7 @@ static void brcmf_msgbuf_txflow_worker(s
+ 	u32 flowid;
+ 
+ 	msgbuf = container_of(worker, struct brcmf_msgbuf, txflow_work);
+-	for_each_set_bit(flowid, msgbuf->flow_map, msgbuf->nrof_flowrings) {
++	for_each_set_bit(flowid, msgbuf->flow_map, msgbuf->max_flowrings) {
+ 		clear_bit(flowid, msgbuf->flow_map);
+ 		brcmf_msgbuf_txflow(msgbuf, flowid);
+ 	}
+@@ -866,7 +864,7 @@ brcmf_msgbuf_process_txstatus(struct brc
+ 	tx_status = (struct msgbuf_tx_status *)buf;
+ 	idx = le32_to_cpu(tx_status->msg.request_id);
+ 	flowid = le16_to_cpu(tx_status->compl_hdr.flow_ring_id);
+-	flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS;
++	flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
+ 	skb = brcmf_msgbuf_get_pktid(msgbuf->drvr->bus_if->dev,
+ 				     msgbuf->tx_pktids, idx);
+ 	if (!skb)
+@@ -1174,7 +1172,7 @@ brcmf_msgbuf_process_flow_ring_create_re
+ 	flowring_create_resp = (struct msgbuf_flowring_create_resp *)buf;
+ 
+ 	flowid = le16_to_cpu(flowring_create_resp->compl_hdr.flow_ring_id);
+-	flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS;
++	flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
+ 	status =  le16_to_cpu(flowring_create_resp->compl_hdr.status);
+ 
+ 	if (status) {
+@@ -1202,7 +1200,7 @@ brcmf_msgbuf_process_flow_ring_delete_re
+ 	flowring_delete_resp = (struct msgbuf_flowring_delete_resp *)buf;
+ 
+ 	flowid = le16_to_cpu(flowring_delete_resp->compl_hdr.flow_ring_id);
+-	flowid -= BRCMF_NROF_H2D_COMMON_MSGRINGS;
++	flowid -= BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
+ 	status =  le16_to_cpu(flowring_delete_resp->compl_hdr.status);
+ 
+ 	if (status) {
+@@ -1307,7 +1305,7 @@ int brcmf_proto_msgbuf_rx_trigger(struct
+ 	brcmf_msgbuf_process_rx(msgbuf, buf);
+ 
+ 	for_each_set_bit(flowid, msgbuf->txstatus_done_map,
+-			 msgbuf->nrof_flowrings) {
++			 msgbuf->max_flowrings) {
+ 		clear_bit(flowid, msgbuf->txstatus_done_map);
+ 		commonring = msgbuf->flowrings[flowid];
+ 		qlen = brcmf_flowring_qlen(msgbuf->flow, flowid);
+@@ -1349,7 +1347,7 @@ void brcmf_msgbuf_delete_flowring(struct
+ 	delete->msg.request_id = 0;
+ 
+ 	delete->flow_ring_id = cpu_to_le16(flowid +
+-					   BRCMF_NROF_H2D_COMMON_MSGRINGS);
++					   BRCMF_H2D_MSGRING_FLOWRING_IDSTART);
+ 	delete->reason = 0;
+ 
+ 	brcmf_dbg(MSGBUF, "Send Flow Delete Req flow ID %d, ifindex %d\n",
+@@ -1427,10 +1425,10 @@ int brcmf_proto_msgbuf_attach(struct brc
+ 
+ 	if_msgbuf = drvr->bus_if->msgbuf;
+ 
+-	if (if_msgbuf->nrof_flowrings >= BRCMF_FLOWRING_HASHSIZE) {
++	if (if_msgbuf->max_flowrings >= BRCMF_FLOWRING_HASHSIZE) {
+ 		brcmf_err("driver not configured for this many flowrings %d\n",
+-			  if_msgbuf->nrof_flowrings);
+-		if_msgbuf->nrof_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
++			  if_msgbuf->max_flowrings);
++		if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1;
+ 	}
+ 
+ 	msgbuf = kzalloc(sizeof(*msgbuf), GFP_KERNEL);
+@@ -1443,7 +1441,7 @@ int brcmf_proto_msgbuf_attach(struct brc
+ 		goto fail;
+ 	}
+ 	INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker);
+-	count = BITS_TO_LONGS(if_msgbuf->nrof_flowrings);
++	count = BITS_TO_LONGS(if_msgbuf->max_flowrings);
+ 	count = count * sizeof(unsigned long);
+ 	msgbuf->flow_map = kzalloc(count, GFP_KERNEL);
+ 	if (!msgbuf->flow_map)
+@@ -1479,8 +1477,8 @@ int brcmf_proto_msgbuf_attach(struct brc
+ 	msgbuf->commonrings =
+ 		(struct brcmf_commonring **)if_msgbuf->commonrings;
+ 	msgbuf->flowrings = (struct brcmf_commonring **)if_msgbuf->flowrings;
+-	msgbuf->nrof_flowrings = if_msgbuf->nrof_flowrings;
+-	msgbuf->flowring_dma_handle = kzalloc(msgbuf->nrof_flowrings *
++	msgbuf->max_flowrings = if_msgbuf->max_flowrings;
++	msgbuf->flowring_dma_handle = kzalloc(msgbuf->max_flowrings *
+ 		sizeof(*msgbuf->flowring_dma_handle), GFP_KERNEL);
+ 	if (!msgbuf->flowring_dma_handle)
+ 		goto fail;
+@@ -1501,7 +1499,7 @@ int brcmf_proto_msgbuf_attach(struct brc
+ 		goto fail;
+ 
+ 	msgbuf->flow = brcmf_flowring_attach(drvr->bus_if->dev,
+-					     if_msgbuf->nrof_flowrings);
++					     if_msgbuf->max_flowrings);
+ 	if (!msgbuf->flow)
+ 		goto fail;
+ 
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.h
+@@ -31,6 +31,10 @@
+ #define BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE		32
+ #define BRCMF_H2D_TXFLOWRING_ITEMSIZE			48
+ 
++struct msgbuf_buf_addr {
++	__le32		low_addr;
++	__le32		high_addr;
++};
+ 
+ int brcmf_proto_msgbuf_rx_trigger(struct device *dev);
+ void brcmf_msgbuf_delete_flowring(struct brcmf_pub *drvr, u16 flowid);
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+@@ -135,7 +135,7 @@ static struct brcmf_firmware_mapping brc
+ 						 BRCMF_PCIE_MB_INT_D2H3_DB1)
+ 
+ #define BRCMF_PCIE_MIN_SHARED_VERSION		5
+-#define BRCMF_PCIE_MAX_SHARED_VERSION		5
++#define BRCMF_PCIE_MAX_SHARED_VERSION		6
+ #define BRCMF_PCIE_SHARED_VERSION_MASK		0x00FF
+ #define BRCMF_PCIE_SHARED_DMA_INDEX		0x10000
+ #define BRCMF_PCIE_SHARED_DMA_2B_IDX		0x100000
+@@ -166,17 +166,6 @@ static struct brcmf_firmware_mapping brc
+ #define BRCMF_RING_MEM_SZ			16
+ #define BRCMF_RING_STATE_SZ			8
+ 
+-#define BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET	4
+-#define BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET	8
+-#define BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET	12
+-#define BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET	16
+-#define BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET	20
+-#define BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET	28
+-#define BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET	36
+-#define BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET	44
+-#define BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET	0
+-#define BRCMF_SHARED_RING_MAX_SUB_QUEUES	52
+-
+ #define BRCMF_DEF_MAX_RXBUFPOST			255
+ 
+ #define BRCMF_CONSOLE_BUFADDR_OFFSET		8
+@@ -231,7 +220,9 @@ struct brcmf_pcie_shared_info {
+ 	struct brcmf_pcie_ringbuf *commonrings[BRCMF_NROF_COMMON_MSGRINGS];
+ 	struct brcmf_pcie_ringbuf *flowrings;
+ 	u16 max_rxbufpost;
+-	u32 nrof_flowrings;
++	u16 max_flowrings;
++	u16 max_submissionrings;
++	u16 max_completionrings;
+ 	u32 rx_dataoffset;
+ 	u32 htod_mb_data_addr;
+ 	u32 dtoh_mb_data_addr;
+@@ -241,6 +232,7 @@ struct brcmf_pcie_shared_info {
+ 	dma_addr_t scratch_dmahandle;
+ 	void *ringupd;
+ 	dma_addr_t ringupd_dmahandle;
++	u8 version;
+ };
+ 
+ struct brcmf_pcie_core_info {
+@@ -284,6 +276,36 @@ struct brcmf_pcie_ringbuf {
+ 	u8 id;
+ };
+ 
++/**
++ * struct brcmf_pcie_dhi_ringinfo - dongle/host interface shared ring info
++ *
++ * @ringmem: dongle memory pointer to ring memory location
++ * @h2d_w_idx_ptr: h2d ring write indices dongle memory pointers
++ * @h2d_r_idx_ptr: h2d ring read indices dongle memory pointers
++ * @d2h_w_idx_ptr: d2h ring write indices dongle memory pointers
++ * @d2h_r_idx_ptr: d2h ring read indices dongle memory pointers
++ * @h2d_w_idx_hostaddr: h2d ring write indices host memory pointers
++ * @h2d_r_idx_hostaddr: h2d ring read indices host memory pointers
++ * @d2h_w_idx_hostaddr: d2h ring write indices host memory pointers
++ * @d2h_r_idx_hostaddr: d2h ring reaD indices host memory pointers
++ * @max_flowrings: maximum number of tx flow rings supported.
++ * @max_submissionrings: maximum number of submission rings(h2d) supported.
++ * @max_completionrings: maximum number of completion rings(d2h) supported.
++ */
++struct brcmf_pcie_dhi_ringinfo {
++	__le32			ringmem;
++	__le32			h2d_w_idx_ptr;
++	__le32			h2d_r_idx_ptr;
++	__le32			d2h_w_idx_ptr;
++	__le32			d2h_r_idx_ptr;
++	struct msgbuf_buf_addr	h2d_w_idx_hostaddr;
++	struct msgbuf_buf_addr	h2d_r_idx_hostaddr;
++	struct msgbuf_buf_addr	d2h_w_idx_hostaddr;
++	struct msgbuf_buf_addr	d2h_r_idx_hostaddr;
++	__le16			max_flowrings;
++	__le16			max_submissionrings;
++	__le16			max_completionrings;
++};
+ 
+ static const u32 brcmf_ring_max_item[BRCMF_NROF_COMMON_MSGRINGS] = {
+ 	BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM,
+@@ -1054,26 +1076,35 @@ static int brcmf_pcie_init_ringbuffers(s
+ {
+ 	struct brcmf_pcie_ringbuf *ring;
+ 	struct brcmf_pcie_ringbuf *rings;
+-	u32 ring_addr;
+ 	u32 d2h_w_idx_ptr;
+ 	u32 d2h_r_idx_ptr;
+ 	u32 h2d_w_idx_ptr;
+ 	u32 h2d_r_idx_ptr;
+-	u32 addr;
+ 	u32 ring_mem_ptr;
+ 	u32 i;
+ 	u64 address;
+ 	u32 bufsz;
+-	u16 max_sub_queues;
+ 	u8 idx_offset;
+-
+-	ring_addr = devinfo->shared.ring_info_addr;
+-	brcmf_dbg(PCIE, "Base ring addr = 0x%08x\n", ring_addr);
+-	addr = ring_addr + BRCMF_SHARED_RING_MAX_SUB_QUEUES;
+-	max_sub_queues = brcmf_pcie_read_tcm16(devinfo, addr);
++	struct brcmf_pcie_dhi_ringinfo ringinfo;
++	u16 max_flowrings;
++	u16 max_submissionrings;
++	u16 max_completionrings;
++
++	memcpy_fromio(&ringinfo, devinfo->tcm + devinfo->shared.ring_info_addr,
++		      sizeof(ringinfo));
++	if (devinfo->shared.version >= 6) {
++		max_submissionrings = le16_to_cpu(ringinfo.max_submissionrings);
++		max_flowrings = le16_to_cpu(ringinfo.max_flowrings);
++		max_completionrings = le16_to_cpu(ringinfo.max_completionrings);
++	} else {
++		max_submissionrings = le16_to_cpu(ringinfo.max_flowrings);
++		max_flowrings = max_submissionrings -
++				BRCMF_NROF_H2D_COMMON_MSGRINGS;
++		max_completionrings = BRCMF_NROF_D2H_COMMON_MSGRINGS;
++	}
+ 
+ 	if (devinfo->dma_idx_sz != 0) {
+-		bufsz = (BRCMF_NROF_D2H_COMMON_MSGRINGS + max_sub_queues) *
++		bufsz = (max_submissionrings + max_completionrings) *
+ 			devinfo->dma_idx_sz * 2;
+ 		devinfo->idxbuf = dma_alloc_coherent(&devinfo->pdev->dev, bufsz,
+ 						     &devinfo->idxbuf_dmahandle,
+@@ -1083,14 +1114,10 @@ static int brcmf_pcie_init_ringbuffers(s
+ 	}
+ 
+ 	if (devinfo->dma_idx_sz == 0) {
+-		addr = ring_addr + BRCMF_SHARED_RING_D2H_W_IDX_PTR_OFFSET;
+-		d2h_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
+-		addr = ring_addr + BRCMF_SHARED_RING_D2H_R_IDX_PTR_OFFSET;
+-		d2h_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
+-		addr = ring_addr + BRCMF_SHARED_RING_H2D_W_IDX_PTR_OFFSET;
+-		h2d_w_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
+-		addr = ring_addr + BRCMF_SHARED_RING_H2D_R_IDX_PTR_OFFSET;
+-		h2d_r_idx_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
++		d2h_w_idx_ptr = le32_to_cpu(ringinfo.d2h_w_idx_ptr);
++		d2h_r_idx_ptr = le32_to_cpu(ringinfo.d2h_r_idx_ptr);
++		h2d_w_idx_ptr = le32_to_cpu(ringinfo.h2d_w_idx_ptr);
++		h2d_r_idx_ptr = le32_to_cpu(ringinfo.h2d_r_idx_ptr);
+ 		idx_offset = sizeof(u32);
+ 		devinfo->write_ptr = brcmf_pcie_write_tcm16;
+ 		devinfo->read_ptr = brcmf_pcie_read_tcm16;
+@@ -1103,34 +1130,42 @@ static int brcmf_pcie_init_ringbuffers(s
+ 		devinfo->read_ptr = brcmf_pcie_read_idx;
+ 
+ 		h2d_w_idx_ptr = 0;
+-		addr = ring_addr + BRCMF_SHARED_RING_H2D_WP_HADDR_OFFSET;
+ 		address = (u64)devinfo->idxbuf_dmahandle;
+-		brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
+-		brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
+-
+-		h2d_r_idx_ptr = h2d_w_idx_ptr + max_sub_queues * idx_offset;
+-		addr = ring_addr + BRCMF_SHARED_RING_H2D_RP_HADDR_OFFSET;
+-		address += max_sub_queues * idx_offset;
+-		brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
+-		brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
+-
+-		d2h_w_idx_ptr = h2d_r_idx_ptr + max_sub_queues * idx_offset;
+-		addr = ring_addr + BRCMF_SHARED_RING_D2H_WP_HADDR_OFFSET;
+-		address += max_sub_queues * idx_offset;
+-		brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
+-		brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
++		ringinfo.h2d_w_idx_hostaddr.low_addr =
++			cpu_to_le32(address & 0xffffffff);
++		ringinfo.h2d_w_idx_hostaddr.high_addr =
++			cpu_to_le32(address >> 32);
++
++		h2d_r_idx_ptr = h2d_w_idx_ptr +
++				max_submissionrings * idx_offset;
++		address += max_submissionrings * idx_offset;
++		ringinfo.h2d_r_idx_hostaddr.low_addr =
++			cpu_to_le32(address & 0xffffffff);
++		ringinfo.h2d_r_idx_hostaddr.high_addr =
++			cpu_to_le32(address >> 32);
++
++		d2h_w_idx_ptr = h2d_r_idx_ptr +
++				max_submissionrings * idx_offset;
++		address += max_submissionrings * idx_offset;
++		ringinfo.d2h_w_idx_hostaddr.low_addr =
++			cpu_to_le32(address & 0xffffffff);
++		ringinfo.d2h_w_idx_hostaddr.high_addr =
++			cpu_to_le32(address >> 32);
+ 
+ 		d2h_r_idx_ptr = d2h_w_idx_ptr +
+-				BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset;
+-		addr = ring_addr + BRCMF_SHARED_RING_D2H_RP_HADDR_OFFSET;
+-		address += BRCMF_NROF_D2H_COMMON_MSGRINGS * idx_offset;
+-		brcmf_pcie_write_tcm32(devinfo, addr, address & 0xffffffff);
+-		brcmf_pcie_write_tcm32(devinfo, addr + 4, address >> 32);
++				max_completionrings * idx_offset;
++		address += max_completionrings * idx_offset;
++		ringinfo.d2h_r_idx_hostaddr.low_addr =
++			cpu_to_le32(address & 0xffffffff);
++		ringinfo.d2h_r_idx_hostaddr.high_addr =
++			cpu_to_le32(address >> 32);
++
++		memcpy_toio(devinfo->tcm + devinfo->shared.ring_info_addr,
++			    &ringinfo, sizeof(ringinfo));
+ 		brcmf_dbg(PCIE, "Using host memory indices\n");
+ 	}
+ 
+-	addr = ring_addr + BRCMF_SHARED_RING_TCM_MEMLOC_OFFSET;
+-	ring_mem_ptr = brcmf_pcie_read_tcm32(devinfo, addr);
++	ring_mem_ptr = le32_to_cpu(ringinfo.ringmem);
+ 
+ 	for (i = 0; i < BRCMF_NROF_H2D_COMMON_MSGRINGS; i++) {
+ 		ring = brcmf_pcie_alloc_dma_and_ring(devinfo, i, ring_mem_ptr);
+@@ -1161,20 +1196,19 @@ static int brcmf_pcie_init_ringbuffers(s
+ 		ring_mem_ptr += BRCMF_RING_MEM_SZ;
+ 	}
+ 
+-	devinfo->shared.nrof_flowrings =
+-			max_sub_queues - BRCMF_NROF_H2D_COMMON_MSGRINGS;
+-	rings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*ring),
+-			GFP_KERNEL);
++	devinfo->shared.max_flowrings = max_flowrings;
++	devinfo->shared.max_submissionrings = max_submissionrings;
++	devinfo->shared.max_completionrings = max_completionrings;
++	rings = kcalloc(max_flowrings, sizeof(*ring), GFP_KERNEL);
+ 	if (!rings)
+ 		goto fail;
+ 
+-	brcmf_dbg(PCIE, "Nr of flowrings is %d\n",
+-		  devinfo->shared.nrof_flowrings);
++	brcmf_dbg(PCIE, "Nr of flowrings is %d\n", max_flowrings);
+ 
+-	for (i = 0; i < devinfo->shared.nrof_flowrings; i++) {
++	for (i = 0; i < max_flowrings; i++) {
+ 		ring = &rings[i];
+ 		ring->devinfo = devinfo;
+-		ring->id = i + BRCMF_NROF_COMMON_MSGRINGS;
++		ring->id = i + BRCMF_H2D_MSGRING_FLOWRING_IDSTART;
+ 		brcmf_commonring_register_cb(&ring->commonring,
+ 					     brcmf_pcie_ring_mb_ring_bell,
+ 					     brcmf_pcie_ring_mb_update_rptr,
+@@ -1357,17 +1391,16 @@ brcmf_pcie_init_share_ram_info(struct br
+ {
+ 	struct brcmf_pcie_shared_info *shared;
+ 	u32 addr;
+-	u32 version;
+ 
+ 	shared = &devinfo->shared;
+ 	shared->tcm_base_address = sharedram_addr;
+ 
+ 	shared->flags = brcmf_pcie_read_tcm32(devinfo, sharedram_addr);
+-	version = shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK;
+-	brcmf_dbg(PCIE, "PCIe protocol version %d\n", version);
+-	if ((version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
+-	    (version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
+-		brcmf_err("Unsupported PCIE version %d\n", version);
++	shared->version = (u8)(shared->flags & BRCMF_PCIE_SHARED_VERSION_MASK);
++	brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version);
++	if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
++	    (shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
++		brcmf_err("Unsupported PCIE version %d\n", shared->version);
+ 		return -EINVAL;
+ 	}
+ 
+@@ -1661,18 +1694,18 @@ static void brcmf_pcie_setup(struct devi
+ 		bus->msgbuf->commonrings[i] =
+ 				&devinfo->shared.commonrings[i]->commonring;
+ 
+-	flowrings = kcalloc(devinfo->shared.nrof_flowrings, sizeof(*flowrings),
++	flowrings = kcalloc(devinfo->shared.max_flowrings, sizeof(*flowrings),
+ 			    GFP_KERNEL);
+ 	if (!flowrings)
+ 		goto fail;
+ 
+-	for (i = 0; i < devinfo->shared.nrof_flowrings; i++)
++	for (i = 0; i < devinfo->shared.max_flowrings; i++)
+ 		flowrings[i] = &devinfo->shared.flowrings[i].commonring;
+ 	bus->msgbuf->flowrings = flowrings;
+ 
+ 	bus->msgbuf->rx_dataoffset = devinfo->shared.rx_dataoffset;
+ 	bus->msgbuf->max_rxbufpost = devinfo->shared.max_rxbufpost;
+-	bus->msgbuf->nrof_flowrings = devinfo->shared.nrof_flowrings;
++	bus->msgbuf->max_flowrings = devinfo->shared.max_flowrings;
+ 
+ 	init_waitqueue_head(&devinfo->mbdata_resp_wait);
+ 
diff --git a/package/kernel/mac80211/patches/357-0002-brcmfmac-add-support-for-43341-chip.patch b/package/kernel/mac80211/patches/357-0002-brcmfmac-add-support-for-43341-chip.patch
new file mode 100644
index 0000000..edd7de3
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0002-brcmfmac-add-support-for-43341-chip.patch
@@ -0,0 +1,39 @@
+From dc630dc5c753ccba97ce174f9c2894f802f9bd93 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:21 +0000
+Subject: [PATCH] brcmfmac: add support for 43341 chip
+
+This chip was already supported, but seems a device came up giving
+a different chip identifier. So adding that effectively mapping to
+the same firmware file as for 43340 chip.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c       | 1 +
+ drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 +
+ 2 files changed, 2 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -621,6 +621,7 @@ static struct brcmf_firmware_mapping brc
+ 	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4330_CHIP_ID, 0xFFFFFFFF, 4330),
+ 	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4334_CHIP_ID, 0xFFFFFFFF, 4334),
+ 	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43340_CHIP_ID, 0xFFFFFFFF, 43340),
++	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43341_CHIP_ID, 0xFFFFFFFF, 43340),
+ 	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, 4335),
+ 	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, 43362),
+ 	BRCMF_FW_NVRAM_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339),
+--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+@@ -36,6 +36,7 @@
+ #define BRCM_CC_4330_CHIP_ID		0x4330
+ #define BRCM_CC_4334_CHIP_ID		0x4334
+ #define BRCM_CC_43340_CHIP_ID		43340
++#define BRCM_CC_43341_CHIP_ID		43341
+ #define BRCM_CC_43362_CHIP_ID		43362
+ #define BRCM_CC_4335_CHIP_ID		0x4335
+ #define BRCM_CC_4339_CHIP_ID		0x4339
diff --git a/package/kernel/mac80211/patches/357-0003-brcmfmac-move-pno-helper-functions-in-separate-sourc.patch b/package/kernel/mac80211/patches/357-0003-brcmfmac-move-pno-helper-functions-in-separate-sourc.patch
new file mode 100644
index 0000000..94f2e6b
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0003-brcmfmac-move-pno-helper-functions-in-separate-sourc.patch
@@ -0,0 +1,319 @@
+From ac55136f43d3336c7b40238b779c404008229929 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:22 +0000
+Subject: [PATCH] brcmfmac: move pno helper functions in separate source file
+
+Introducing new source file for pno related functionality. Moving
+existing pno functions.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/Makefile  |   3 +-
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c         |  93 ++-----------------
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 100 +++++++++++++++++++++
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h |  40 +++++++++
+ 4 files changed, 150 insertions(+), 86 deletions(-)
+ create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+ create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
+@@ -35,7 +35,8 @@ brcmfmac-objs += \
+ 		firmware.o \
+ 		feature.o \
+ 		btcoex.o \
+-		vendor.o
++		vendor.o \
++		pno.o
+ brcmfmac-$(CPTCFG_BRCMFMAC_PROTO_BCDC) += \
+ 		bcdc.o
+ brcmfmac-$(CPTCFG_BRCMFMAC_PROTO_MSGBUF) += \
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -32,6 +32,7 @@
+ #include "fwil_types.h"
+ #include "p2p.h"
+ #include "btcoex.h"
++#include "pno.h"
+ #include "cfg80211.h"
+ #include "feature.h"
+ #include "fwil.h"
+@@ -41,16 +42,6 @@
+ #include "common.h"
+ 
+ #define BRCMF_SCAN_IE_LEN_MAX		2048
+-#define BRCMF_PNO_VERSION		2
+-#define BRCMF_PNO_TIME			30
+-#define BRCMF_PNO_REPEAT		4
+-#define BRCMF_PNO_FREQ_EXPO_MAX		3
+-#define BRCMF_PNO_MAX_PFN_COUNT		16
+-#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT	6
+-#define BRCMF_PNO_HIDDEN_BIT		2
+-#define BRCMF_PNO_WPA_AUTH_ANY		0xFFFFFFFF
+-#define BRCMF_PNO_SCAN_COMPLETE		1
+-#define BRCMF_PNO_SCAN_INCOMPLETE	0
+ 
+ #define WPA_OUI				"\x00\x50\xF2"	/* WPA OUI */
+ #define WPA_OUI_TYPE			1
+@@ -3323,76 +3314,6 @@ out_err:
+ 	return err;
+ }
+ 
+-static int brcmf_dev_pno_clean(struct net_device *ndev)
+-{
+-	int ret;
+-
+-	/* Disable pfn */
+-	ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
+-	if (ret == 0) {
+-		/* clear pfn */
+-		ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
+-					       NULL, 0);
+-	}
+-	if (ret < 0)
+-		brcmf_err("failed code %d\n", ret);
+-
+-	return ret;
+-}
+-
+-static int brcmf_dev_pno_config(struct brcmf_if *ifp,
+-				struct cfg80211_sched_scan_request *request)
+-{
+-	struct brcmf_pno_param_le pfn_param;
+-	struct brcmf_pno_macaddr_le pfn_mac;
+-	s32 err;
+-	u8 *mac_mask;
+-	int i;
+-
+-	memset(&pfn_param, 0, sizeof(pfn_param));
+-	pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
+-
+-	/* set extra pno params */
+-	pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
+-	pfn_param.repeat = BRCMF_PNO_REPEAT;
+-	pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
+-
+-	/* set up pno scan fr */
+-	pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
+-
+-	err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
+-				       sizeof(pfn_param));
+-	if (err) {
+-		brcmf_err("pfn_set failed, err=%d\n", err);
+-		return err;
+-	}
+-
+-	/* Find out if mac randomization should be turned on */
+-	if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
+-		return 0;
+-
+-	pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
+-	pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
+-
+-	memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
+-	mac_mask = request->mac_addr_mask;
+-	for (i = 0; i < ETH_ALEN; i++) {
+-		pfn_mac.mac[i] &= mac_mask[i];
+-		pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
+-	}
+-	/* Clear multi bit */
+-	pfn_mac.mac[0] &= 0xFE;
+-	/* Set locally administered */
+-	pfn_mac.mac[0] |= 0x02;
+-
+-	err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
+-				       sizeof(pfn_mac));
+-	if (err)
+-		brcmf_err("pfn_macaddr failed, err=%d\n", err);
+-
+-	return err;
+-}
+-
+ static int
+ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
+ 				struct net_device *ndev,
+@@ -3436,15 +3357,16 @@ brcmf_cfg80211_sched_scan_start(struct w
+ 
+ 	if (request->n_match_sets > 0) {
+ 		/* clean up everything */
+-		ret = brcmf_dev_pno_clean(ndev);
++		ret = brcmf_pno_clean(ifp);
+ 		if  (ret < 0) {
+ 			brcmf_err("failed error=%d\n", ret);
+ 			return ret;
+ 		}
+ 
+ 		/* configure pno */
+-		if (brcmf_dev_pno_config(ifp, request))
+-			return -EINVAL;
++		ret = brcmf_pno_config(ifp, request);
++		if (ret < 0)
++			return ret;
+ 
+ 		/* configure each match set */
+ 		for (i = 0; i < request->n_match_sets; i++) {
+@@ -3486,11 +3408,12 @@ static int brcmf_cfg80211_sched_scan_sto
+ 					  struct net_device *ndev)
+ {
+ 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
++	struct brcmf_if *ifp = netdev_priv(ndev);
+ 
+ 	brcmf_dbg(SCAN, "enter\n");
+-	brcmf_dev_pno_clean(ndev);
++	brcmf_pno_clean(ifp);
+ 	if (cfg->sched_escan)
+-		brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
++		brcmf_notify_escan_complete(cfg, ifp, true, true);
+ 	return 0;
+ }
+ 
+--- /dev/null
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+@@ -0,0 +1,100 @@
++/*
++ * Copyright (c) 2016 Broadcom
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#include <linux/netdevice.h>
++#include <net/cfg80211.h>
++
++#include "core.h"
++#include "debug.h"
++#include "pno.h"
++#include "fwil.h"
++#include "fwil_types.h"
++
++#define BRCMF_PNO_VERSION		2
++#define BRCMF_PNO_TIME			30
++#define BRCMF_PNO_REPEAT		4
++#define BRCMF_PNO_FREQ_EXPO_MAX		3
++#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT	6
++#define BRCMF_PNO_SCAN_INCOMPLETE	0
++
++int brcmf_pno_clean(struct brcmf_if *ifp)
++{
++	int ret;
++
++	/* Disable pfn */
++	ret = brcmf_fil_iovar_int_set(ifp, "pfn", 0);
++	if (ret == 0) {
++		/* clear pfn */
++		ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0);
++	}
++	if (ret < 0)
++		brcmf_err("failed code %d\n", ret);
++
++	return ret;
++}
++
++int brcmf_pno_config(struct brcmf_if *ifp,
++		     struct cfg80211_sched_scan_request *request)
++{
++	struct brcmf_pno_param_le pfn_param;
++	struct brcmf_pno_macaddr_le pfn_mac;
++	s32 err;
++	u8 *mac_mask;
++	int i;
++
++	memset(&pfn_param, 0, sizeof(pfn_param));
++	pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
++
++	/* set extra pno params */
++	pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
++	pfn_param.repeat = BRCMF_PNO_REPEAT;
++	pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
++
++	/* set up pno scan fr */
++	pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
++
++	err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
++				       sizeof(pfn_param));
++	if (err) {
++		brcmf_err("pfn_set failed, err=%d\n", err);
++		return err;
++	}
++
++	/* Find out if mac randomization should be turned on */
++	if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
++		return 0;
++
++	pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
++	pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
++
++	memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
++	mac_mask = request->mac_addr_mask;
++	for (i = 0; i < ETH_ALEN; i++) {
++		pfn_mac.mac[i] &= mac_mask[i];
++		pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
++	}
++	/* Clear multi bit */
++	pfn_mac.mac[0] &= 0xFE;
++	/* Set locally administered */
++	pfn_mac.mac[0] |= 0x02;
++
++	err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
++				       sizeof(pfn_mac));
++	if (err)
++		brcmf_err("pfn_macaddr failed, err=%d\n", err);
++
++	return err;
++}
++
+--- /dev/null
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
+@@ -0,0 +1,40 @@
++/*
++ * Copyright (c) 2016 Broadcom
++ *
++ * Permission to use, copy, modify, and/or distribute this software for any
++ * purpose with or without fee is hereby granted, provided that the above
++ * copyright notice and this permission notice appear in all copies.
++ *
++ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
++ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
++ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
++ * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
++ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
++ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
++ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
++ */
++#ifndef _BRCMF_PNO_H
++#define _BRCMF_PNO_H
++
++#define BRCMF_PNO_SCAN_COMPLETE		1
++#define BRCMF_PNO_WPA_AUTH_ANY		0xFFFFFFFF
++#define BRCMF_PNO_HIDDEN_BIT		2
++#define BRCMF_PNO_MAX_PFN_COUNT		16
++
++/**
++ * brcmf_pno_clean - disable and clear pno in firmware.
++ *
++ * @ifp: interface object used.
++ */
++int brcmf_pno_clean(struct brcmf_if *ifp);
++
++/**
++ * brcmf_pno_config - configure pno parameters.
++ *
++ * @ifp: interface object used.
++ * @request: scheduled scan parameters.
++ */
++int brcmf_pno_config(struct brcmf_if *ifp,
++		     struct cfg80211_sched_scan_request *request);
++
++#endif /* _BRCMF_PNO_H */
diff --git a/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch b/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch
new file mode 100644
index 0000000..f1934af
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0004-brcmfmac-fix-handling-ssids-in-.sched_scan_start-cal.patch
@@ -0,0 +1,221 @@
+From 3e2e86ab19c2a43953de30089c5411c580ddb5f7 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:23 +0000
+Subject: [PATCH] brcmfmac: fix handling ssids in .sched_scan_start() callback
+
+The ssids list in the scheduled scan request were not properly taken
+into account when configuring in firmware. The hidden bit was set for
+any ssid resulting in active scanning for all. Only set it for ssids
+that are in the ssids list.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 103 ++++++++++-----------
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c |  18 ++++
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h |  12 ++-
+ 3 files changed, 76 insertions(+), 57 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3314,19 +3314,37 @@ out_err:
+ 	return err;
+ }
+ 
++static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid,
++				 struct cfg80211_sched_scan_request *req)
++{
++	int i;
++
++	if (!ssid || !req->ssids || !req->n_ssids)
++		return false;
++
++	for (i = 0; i < req->n_ssids; i++) {
++		if (ssid->ssid_len == req->ssids[i].ssid_len) {
++			if (!strncmp(ssid->ssid, req->ssids[i].ssid,
++				     ssid->ssid_len))
++				return true;
++		}
++	}
++	return false;
++}
++
+ static int
+ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
+ 				struct net_device *ndev,
+-				struct cfg80211_sched_scan_request *request)
++				struct cfg80211_sched_scan_request *req)
+ {
+ 	struct brcmf_if *ifp = netdev_priv(ndev);
+ 	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
+-	struct brcmf_pno_net_param_le pfn;
++	struct cfg80211_ssid *ssid;
+ 	int i;
+ 	int ret = 0;
+ 
+ 	brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
+-		  request->n_match_sets, request->n_ssids);
++		  req->n_match_sets, req->n_ssids);
+ 	if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
+ 		brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
+ 		return -EAGAIN;
+@@ -3337,71 +3355,46 @@ brcmf_cfg80211_sched_scan_start(struct w
+ 		return -EAGAIN;
+ 	}
+ 
+-	if (!request->n_ssids || !request->n_match_sets) {
+-		brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
+-			  request->n_ssids);
++	if (req->n_match_sets <= 0) {
++		brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
++			  req->n_match_sets);
+ 		return -EINVAL;
+ 	}
+ 
+-	if (request->n_ssids > 0) {
+-		for (i = 0; i < request->n_ssids; i++) {
+-			/* Active scan req for ssids */
+-			brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
+-				  request->ssids[i].ssid);
+-
+-			/* match_set ssids is a supert set of n_ssid list,
+-			 * so we need not add these set separately.
+-			 */
+-		}
++	/* clean up everything */
++	ret = brcmf_pno_clean(ifp);
++	if  (ret < 0) {
++		brcmf_err("failed error=%d\n", ret);
++		return ret;
+ 	}
+ 
+-	if (request->n_match_sets > 0) {
+-		/* clean up everything */
+-		ret = brcmf_pno_clean(ifp);
+-		if  (ret < 0) {
+-			brcmf_err("failed error=%d\n", ret);
+-			return ret;
++	/* configure pno */
++	ret = brcmf_pno_config(ifp, req);
++	if (ret < 0)
++		return ret;
++
++	/* configure each match set */
++	for (i = 0; i < req->n_match_sets; i++) {
++
++		ssid = &req->match_sets[i].ssid;
++
++		if (!ssid->ssid_len) {
++			brcmf_err("skip broadcast ssid\n");
++			continue;
+ 		}
+ 
+-		/* configure pno */
+-		ret = brcmf_pno_config(ifp, request);
++		ret = brcmf_pno_add_ssid(ifp, ssid,
++					 brcmf_is_ssid_active(ssid, req));
+ 		if (ret < 0)
+-			return ret;
+-
+-		/* configure each match set */
+-		for (i = 0; i < request->n_match_sets; i++) {
+-			struct cfg80211_ssid *ssid;
+-			u32 ssid_len;
+-
+-			ssid = &request->match_sets[i].ssid;
+-			ssid_len = ssid->ssid_len;
+-
+-			if (!ssid_len) {
+-				brcmf_err("skip broadcast ssid\n");
+-				continue;
+-			}
+-			pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
+-			pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
+-			pfn.wsec = cpu_to_le32(0);
+-			pfn.infra = cpu_to_le32(1);
+-			pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
+-			pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
+-			memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
+-			ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
+-						       sizeof(pfn));
+ 			brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
+ 				  ret == 0 ? "set" : "failed", ssid->ssid);
+-		}
+-		/* Enable the PNO */
+-		if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
+-			brcmf_err("PNO enable failed!! ret=%d\n", ret);
+-			return -EINVAL;
+-		}
+-	} else {
+-		return -EINVAL;
+ 	}
++	/* Enable the PNO */
++	ret = brcmf_fil_iovar_int_set(ifp, "pfn", 1);
++	if (ret < 0)
++		brcmf_err("PNO enable failed!! ret=%d\n", ret);
+ 
+-	return 0;
++	return ret;
+ }
+ 
+ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+@@ -28,6 +28,8 @@
+ #define BRCMF_PNO_FREQ_EXPO_MAX		3
+ #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT	6
+ #define BRCMF_PNO_SCAN_INCOMPLETE	0
++#define BRCMF_PNO_WPA_AUTH_ANY		0xFFFFFFFF
++#define BRCMF_PNO_HIDDEN_BIT		2
+ 
+ int brcmf_pno_clean(struct brcmf_if *ifp)
+ {
+@@ -98,3 +100,19 @@ int brcmf_pno_config(struct brcmf_if *if
+ 	return err;
+ }
+ 
++int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
++		       bool active)
++{
++	struct brcmf_pno_net_param_le pfn;
++
++	pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
++	pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
++	pfn.wsec = cpu_to_le32(0);
++	pfn.infra = cpu_to_le32(1);
++	if (active)
++		pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
++	pfn.ssid.SSID_len = cpu_to_le32(ssid->ssid_len);
++	memcpy(pfn.ssid.SSID, ssid->ssid, ssid->ssid_len);
++	return brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn));
++}
++
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
+@@ -17,8 +17,6 @@
+ #define _BRCMF_PNO_H
+ 
+ #define BRCMF_PNO_SCAN_COMPLETE		1
+-#define BRCMF_PNO_WPA_AUTH_ANY		0xFFFFFFFF
+-#define BRCMF_PNO_HIDDEN_BIT		2
+ #define BRCMF_PNO_MAX_PFN_COUNT		16
+ 
+ /**
+@@ -37,4 +35,14 @@ int brcmf_pno_clean(struct brcmf_if *ifp
+ int brcmf_pno_config(struct brcmf_if *ifp,
+ 		     struct cfg80211_sched_scan_request *request);
+ 
++/**
++ * brcmf_pno_add_ssid - add ssid for pno in firmware.
++ *
++ * @ifp: interface object used.
++ * @ssid: ssid information.
++ * @active: indicate this ssid needs to be actively probed.
++ */
++int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
++		       bool active);
++
+ #endif /* _BRCMF_PNO_H */
diff --git a/package/kernel/mac80211/patches/357-0005-brcmfmac-change-prototype-for-brcmf_do_escan.patch b/package/kernel/mac80211/patches/357-0005-brcmfmac-change-prototype-for-brcmf_do_escan.patch
new file mode 100644
index 0000000..07b353b
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0005-brcmfmac-change-prototype-for-brcmf_do_escan.patch
@@ -0,0 +1,58 @@
+From ab5981c830339b945ddbedc314567a9e5f506d72 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:24 +0000
+Subject: [PATCH] brcmfmac: change prototype for brcmf_do_escan()
+
+Reduce the number of parameters as the removed ones can be obtained
+through struct brcmf_if parameter.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -1080,9 +1080,9 @@ exit:
+ }
+ 
+ static s32
+-brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
+-	       struct brcmf_if *ifp, struct cfg80211_scan_request *request)
++brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
+ {
++	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ 	s32 err;
+ 	u32 passive_scan;
+ 	struct brcmf_scan_results *results;
+@@ -1090,7 +1090,7 @@ brcmf_do_escan(struct brcmf_cfg80211_inf
+ 
+ 	brcmf_dbg(SCAN, "Enter\n");
+ 	escan->ifp = ifp;
+-	escan->wiphy = wiphy;
++	escan->wiphy = cfg->wiphy;
+ 	escan->escan_state = WL_ESCAN_STATE_SCANNING;
+ 	passive_scan = cfg->active_scan ? 0 : 1;
+ 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
+@@ -1170,7 +1170,7 @@ brcmf_cfg80211_escan(struct wiphy *wiphy
+ 		if (err)
+ 			goto scan_out;
+ 
+-		err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
++		err = brcmf_do_escan(vif->ifp, request);
+ 		if (err)
+ 			goto scan_out;
+ 	} else {
+@@ -3289,7 +3289,7 @@ brcmf_notify_sched_scan_results(struct b
+ 
+ 		set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
+ 		cfg->escan_info.run = brcmf_run_escan;
+-		err = brcmf_do_escan(cfg, wiphy, ifp, request);
++		err = brcmf_do_escan(ifp, request);
+ 		if (err) {
+ 			clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
+ 			goto out_err;
diff --git a/package/kernel/mac80211/patches/357-0006-brcmfmac-make-internal-escan-more-generic.patch b/package/kernel/mac80211/patches/357-0006-brcmfmac-make-internal-escan-more-generic.patch
new file mode 100644
index 0000000..84a69f0
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0006-brcmfmac-make-internal-escan-more-generic.patch
@@ -0,0 +1,306 @@
+From fa85b30a908455ff25def3a5f319aad272ef4862 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:25 +0000
+Subject: [PATCH] brcmfmac: make internal escan more generic
+
+For scheduled scan we initiate an escan in firmware to obtain more
+info missing from the scheduled scan notification we get from firmware.
+For upcoming functionality this is also required so make it a bit
+more generic.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 187 ++++++++++++---------
+ .../broadcom/brcm80211/brcmfmac/cfg80211.h         |   4 +-
+ 2 files changed, 109 insertions(+), 82 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -757,12 +757,12 @@ s32 brcmf_notify_escan_complete(struct b
+ 	brcmf_scan_config_mpc(ifp, 1);
+ 
+ 	/*
+-	 * e-scan can be initiated by scheduled scan
++	 * e-scan can be initiated internally
+ 	 * which takes precedence.
+ 	 */
+-	if (cfg->sched_escan) {
++	if (cfg->internal_escan) {
+ 		brcmf_dbg(SCAN, "scheduled scan completed\n");
+-		cfg->sched_escan = false;
++		cfg->internal_escan = false;
+ 		if (!aborted)
+ 			cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
+ 	} else if (scan_request) {
+@@ -3013,7 +3013,7 @@ void brcmf_abort_scanning(struct brcmf_c
+ 	struct escan_info *escan = &cfg->escan_info;
+ 
+ 	set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
+-	if (cfg->scan_request) {
++	if (cfg->internal_escan || cfg->scan_request) {
+ 		escan->escan_state = WL_ESCAN_STATE_IDLE;
+ 		brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
+ 	}
+@@ -3036,7 +3036,7 @@ static void brcmf_escan_timeout(unsigned
+ 	struct brcmf_cfg80211_info *cfg =
+ 			(struct brcmf_cfg80211_info *)data;
+ 
+-	if (cfg->scan_request) {
++	if (cfg->internal_escan || cfg->scan_request) {
+ 		brcmf_err("timer expired\n");
+ 		schedule_work(&cfg->escan_timeout_work);
+ 	}
+@@ -3119,7 +3119,7 @@ brcmf_cfg80211_escan_handler(struct brcm
+ 		if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
+ 			goto exit;
+ 
+-		if (!cfg->scan_request) {
++		if (!cfg->internal_escan && !cfg->scan_request) {
+ 			brcmf_dbg(SCAN, "result without cfg80211 request\n");
+ 			goto exit;
+ 		}
+@@ -3165,7 +3165,7 @@ brcmf_cfg80211_escan_handler(struct brcm
+ 		cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
+ 		if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
+ 			goto exit;
+-		if (cfg->scan_request) {
++		if (cfg->internal_escan || cfg->scan_request) {
+ 			brcmf_inform_bss(cfg);
+ 			aborted = status != BRCMF_E_STATUS_SUCCESS;
+ 			brcmf_notify_escan_complete(cfg, ifp, aborted, false);
+@@ -3190,6 +3190,73 @@ static void brcmf_init_escan(struct brcm
+ 		  brcmf_cfg80211_escan_timeout_worker);
+ }
+ 
++static struct cfg80211_scan_request *
++brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
++	struct cfg80211_scan_request *req;
++	size_t req_size;
++
++	req_size = sizeof(*req) +
++		   n_netinfo * sizeof(req->channels[0]) +
++		   n_netinfo * sizeof(*req->ssids);
++
++	req = kzalloc(req_size, GFP_KERNEL);
++	if (req) {
++		req->wiphy = wiphy;
++		req->ssids = (void *)(&req->channels[0]) +
++			     n_netinfo * sizeof(req->channels[0]);
++	}
++	return req;
++}
++
++static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req,
++					 u8 *ssid, u8 ssid_len, u8 channel)
++{
++	struct ieee80211_channel *chan;
++	enum nl80211_band band;
++	int freq;
++
++	if (channel <= CH_MAX_2G_CHANNEL)
++		band = NL80211_BAND_2GHZ;
++	else
++		band = NL80211_BAND_5GHZ;
++
++	freq = ieee80211_channel_to_frequency(channel, band);
++	if (!freq)
++		return -EINVAL;
++
++	chan = ieee80211_get_channel(req->wiphy, freq);
++	if (!chan)
++		return -EINVAL;
++
++	req->channels[req->n_channels++] = chan;
++	memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
++	req->ssids[req->n_ssids++].ssid_len = ssid_len;
++
++	return 0;
++}
++
++static int brcmf_start_internal_escan(struct brcmf_if *ifp,
++				      struct cfg80211_scan_request *request)
++{
++	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
++	int err;
++
++	if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
++		/* Abort any on-going scan */
++		brcmf_abort_scanning(cfg);
++	}
++
++	set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
++	cfg->escan_info.run = brcmf_run_escan;
++	err = brcmf_do_escan(ifp, request);
++	if (err) {
++		clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
++		return err;
++	}
++	cfg->internal_escan = true;
++	return 0;
++}
++
+ /* PFN result doesn't have all the info which are required by the supplicant
+  * (For e.g IEs) Do a target Escan so that sched scan results are reported
+  * via wl_inform_single_bss in the required format. Escan does require the
+@@ -3203,12 +3270,8 @@ brcmf_notify_sched_scan_results(struct b
+ 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
+ 	struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
+ 	struct cfg80211_scan_request *request = NULL;
+-	struct cfg80211_ssid *ssid = NULL;
+-	struct ieee80211_channel *channel = NULL;
+ 	struct wiphy *wiphy = cfg_to_wiphy(cfg);
+-	int err = 0;
+-	int channel_req = 0;
+-	int band = 0;
++	int i, err = 0;
+ 	struct brcmf_pno_scanresults_le *pfn_result;
+ 	u32 result_count;
+ 	u32 status;
+@@ -3234,83 +3297,47 @@ brcmf_notify_sched_scan_results(struct b
+ 	 */
+ 	WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
+ 	brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
+-	if (result_count > 0) {
+-		int i;
+-
+-		request = kzalloc(sizeof(*request), GFP_KERNEL);
+-		ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
+-		channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
+-		if (!request || !ssid || !channel) {
+-			err = -ENOMEM;
+-			goto out_err;
+-		}
++	if (!result_count) {
++		brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
++		goto out_err;
++	}
++	request = brcmf_alloc_internal_escan_request(wiphy,
++						     result_count);
++	if (!request) {
++		err = -ENOMEM;
++		goto out_err;
++	}
+ 
+-		request->wiphy = wiphy;
+-		data += sizeof(struct brcmf_pno_scanresults_le);
+-		netinfo_start = (struct brcmf_pno_net_info_le *)data;
+-
+-		for (i = 0; i < result_count; i++) {
+-			netinfo = &netinfo_start[i];
+-			if (!netinfo) {
+-				brcmf_err("Invalid netinfo ptr. index: %d\n",
+-					  i);
+-				err = -EINVAL;
+-				goto out_err;
+-			}
++	data += sizeof(struct brcmf_pno_scanresults_le);
++	netinfo_start = (struct brcmf_pno_net_info_le *)data;
+ 
+-			brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
+-				  netinfo->SSID, netinfo->channel);
+-			memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
+-			ssid[i].ssid_len = netinfo->SSID_len;
+-			request->n_ssids++;
+-
+-			channel_req = netinfo->channel;
+-			if (channel_req <= CH_MAX_2G_CHANNEL)
+-				band = NL80211_BAND_2GHZ;
+-			else
+-				band = NL80211_BAND_5GHZ;
+-			channel[i].center_freq =
+-				ieee80211_channel_to_frequency(channel_req,
+-							       band);
+-			channel[i].band = band;
+-			channel[i].flags |= IEEE80211_CHAN_NO_HT40;
+-			request->channels[i] = &channel[i];
+-			request->n_channels++;
+-		}
+-
+-		/* assign parsed ssid array */
+-		if (request->n_ssids)
+-			request->ssids = &ssid[0];
+-
+-		if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
+-			/* Abort any on-going scan */
+-			brcmf_abort_scanning(cfg);
++	for (i = 0; i < result_count; i++) {
++		netinfo = &netinfo_start[i];
++		if (!netinfo) {
++			brcmf_err("Invalid netinfo ptr. index: %d\n",
++				  i);
++			err = -EINVAL;
++			goto out_err;
+ 		}
+ 
+-		set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
+-		cfg->escan_info.run = brcmf_run_escan;
+-		err = brcmf_do_escan(ifp, request);
+-		if (err) {
+-			clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
++		brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
++			  netinfo->SSID, netinfo->channel);
++		err = brcmf_internal_escan_add_info(request,
++						    netinfo->SSID,
++						    netinfo->SSID_len,
++						    netinfo->channel);
++		if (err)
+ 			goto out_err;
+-		}
+-		cfg->sched_escan = true;
+-		cfg->scan_request = request;
+-	} else {
+-		brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
+-		goto out_err;
+ 	}
+ 
+-	kfree(ssid);
+-	kfree(channel);
+-	kfree(request);
+-	return 0;
++	err = brcmf_start_internal_escan(ifp, request);
++	if (!err)
++		goto free_req;
+ 
+ out_err:
+-	kfree(ssid);
+-	kfree(channel);
+-	kfree(request);
+ 	cfg80211_sched_scan_stopped(wiphy);
++free_req:
++	kfree(request);
+ 	return err;
+ }
+ 
+@@ -3405,7 +3432,7 @@ static int brcmf_cfg80211_sched_scan_sto
+ 
+ 	brcmf_dbg(SCAN, "enter\n");
+ 	brcmf_pno_clean(ifp);
+-	if (cfg->sched_escan)
++	if (cfg->internal_escan)
+ 		brcmf_notify_escan_complete(cfg, ifp, true, true);
+ 	return 0;
+ }
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+@@ -271,7 +271,7 @@ struct brcmf_cfg80211_wowl {
+  * @pub: common driver information.
+  * @channel: current channel.
+  * @active_scan: current scan mode.
+- * @sched_escan: e-scan for scheduled scan support running.
++ * @internal_escan: indicates internally initiated e-scan is running.
+  * @ibss_starter: indicates this sta is ibss starter.
+  * @pwr_save: indicate whether dongle to support power save mode.
+  * @dongle_up: indicate whether dongle up or not.
+@@ -303,7 +303,7 @@ struct brcmf_cfg80211_info {
+ 	struct brcmf_pub *pub;
+ 	u32 channel;
+ 	bool active_scan;
+-	bool sched_escan;
++	bool internal_escan;
+ 	bool ibss_starter;
+ 	bool pwr_save;
+ 	bool dongle_up;
diff --git a/package/kernel/mac80211/patches/357-0007-brcmfmac-split-up-brcmf_pno_config-function.patch b/package/kernel/mac80211/patches/357-0007-brcmfmac-split-up-brcmf_pno_config-function.patch
new file mode 100644
index 0000000..f81523a
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0007-brcmfmac-split-up-brcmf_pno_config-function.patch
@@ -0,0 +1,176 @@
+From fca6cb2f059e51dec3fcf3589a5abbbcce5b4043 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:26 +0000
+Subject: [PATCH] brcmfmac: split up brcmf_pno_config() function
+
+The brcmf_pno_config() function handles two configurations in
+firmware. Split it and have caller sort out what is needed.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 11 +++-
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 60 ++++++++++++++++------
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h | 17 ++++--
+ 3 files changed, 68 insertions(+), 20 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -42,6 +42,7 @@
+ #include "common.h"
+ 
+ #define BRCMF_SCAN_IE_LEN_MAX		2048
++#define BRCMF_SCHED_SCAN_PERIOD		30
+ 
+ #define WPA_OUI				"\x00\x50\xF2"	/* WPA OUI */
+ #define WPA_OUI_TYPE			1
+@@ -3396,10 +3397,18 @@ brcmf_cfg80211_sched_scan_start(struct w
+ 	}
+ 
+ 	/* configure pno */
+-	ret = brcmf_pno_config(ifp, req);
++	ret = brcmf_pno_config(ifp, BRCMF_SCHED_SCAN_PERIOD, 0, 0);
+ 	if (ret < 0)
+ 		return ret;
+ 
++	/* configure random mac */
++	if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
++		ret = brcmf_pno_set_random(ifp, req->mac_addr,
++					   req->mac_addr_mask);
++		if (ret < 0)
++			return ret;
++	}
++
+ 	/* configure each match set */
+ 	for (i = 0; i < req->n_match_sets; i++) {
+ 
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+@@ -23,10 +23,12 @@
+ #include "fwil_types.h"
+ 
+ #define BRCMF_PNO_VERSION		2
+-#define BRCMF_PNO_TIME			30
+ #define BRCMF_PNO_REPEAT		4
+ #define BRCMF_PNO_FREQ_EXPO_MAX		3
++#define BRCMF_PNO_IMMEDIATE_SCAN_BIT	3
++#define BRCMF_PNO_ENABLE_BD_SCAN_BIT	5
+ #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT	6
++#define BRCMF_PNO_REPORT_SEPARATELY_BIT	11
+ #define BRCMF_PNO_SCAN_INCOMPLETE	0
+ #define BRCMF_PNO_WPA_AUTH_ANY		0xFFFFFFFF
+ #define BRCMF_PNO_HIDDEN_BIT		2
+@@ -47,42 +49,68 @@ int brcmf_pno_clean(struct brcmf_if *ifp
+ 	return ret;
+ }
+ 
+-int brcmf_pno_config(struct brcmf_if *ifp,
+-		     struct cfg80211_sched_scan_request *request)
++int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
++		     u32 mscan, u32 bestn)
+ {
+ 	struct brcmf_pno_param_le pfn_param;
+-	struct brcmf_pno_macaddr_le pfn_mac;
++	u16 flags;
++	u32 pfnmem;
+ 	s32 err;
+-	u8 *mac_mask;
+-	int i;
+ 
+ 	memset(&pfn_param, 0, sizeof(pfn_param));
+ 	pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
+ 
+ 	/* set extra pno params */
+-	pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
++	flags = BIT(BRCMF_PNO_IMMEDIATE_SCAN_BIT) |
++		BIT(BRCMF_PNO_REPORT_SEPARATELY_BIT) |
++		BIT(BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
+ 	pfn_param.repeat = BRCMF_PNO_REPEAT;
+ 	pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
+ 
+ 	/* set up pno scan fr */
+-	pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
++	pfn_param.scan_freq = cpu_to_le32(scan_freq);
++
++	if (mscan) {
++		pfnmem = bestn;
+ 
++		/* set bestn in firmware */
++		err = brcmf_fil_iovar_int_set(ifp, "pfnmem", pfnmem);
++		if (err < 0) {
++			brcmf_err("failed to set pfnmem\n");
++			goto exit;
++		}
++		/* get max mscan which the firmware supports */
++		err = brcmf_fil_iovar_int_get(ifp, "pfnmem", &pfnmem);
++		if (err < 0) {
++			brcmf_err("failed to get pfnmem\n");
++			goto exit;
++		}
++		mscan = min_t(u32, mscan, pfnmem);
++		pfn_param.mscan = mscan;
++		pfn_param.bestn = bestn;
++		flags |= BIT(BRCMF_PNO_ENABLE_BD_SCAN_BIT);
++		brcmf_dbg(INFO, "mscan=%d, bestn=%d\n", mscan, bestn);
++	}
++
++	pfn_param.flags = cpu_to_le16(flags);
+ 	err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
+ 				       sizeof(pfn_param));
+-	if (err) {
++	if (err)
+ 		brcmf_err("pfn_set failed, err=%d\n", err);
+-		return err;
+-	}
+ 
+-	/* Find out if mac randomization should be turned on */
+-	if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
+-		return 0;
++exit:
++	return err;
++}
++
++int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask)
++{
++	struct brcmf_pno_macaddr_le pfn_mac;
++	int err, i;
+ 
+ 	pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
+ 	pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
+ 
+-	memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
+-	mac_mask = request->mac_addr_mask;
++	memcpy(pfn_mac.mac, mac_addr, ETH_ALEN);
+ 	for (i = 0; i < ETH_ALEN; i++) {
+ 		pfn_mac.mac[i] &= mac_mask[i];
+ 		pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
+@@ -30,10 +30,21 @@ int brcmf_pno_clean(struct brcmf_if *ifp
+  * brcmf_pno_config - configure pno parameters.
+  *
+  * @ifp: interface object used.
+- * @request: scheduled scan parameters.
++ * @scan_freq: scan frequency period in seconds.
++ * @mscan: maximum number of scans stored in firmware.
++ * @bestn: maximum number of APs per scan stored in firmware.
+  */
+-int brcmf_pno_config(struct brcmf_if *ifp,
+-		     struct cfg80211_sched_scan_request *request);
++int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
++		     u32 mscan, u32 bestn);
++
++/**
++ * brcmf_pno_set_random - setup randomisation mac address for pno.
++ *
++ * @ifp: interface object used.
++ * @mac_addr: MAC address used with randomisation.
++ * @mac_mask: MAC address mask used for randomisation.
++ */
++int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask);
+ 
+ /**
+  * brcmf_pno_add_ssid - add ssid for pno in firmware.
diff --git a/package/kernel/mac80211/patches/357-0008-brcmfmac-move-scheduled-scan-activation-to-pno-sourc.patch b/package/kernel/mac80211/patches/357-0008-brcmfmac-move-scheduled-scan-activation-to-pno-sourc.patch
new file mode 100644
index 0000000..6dcea28
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0008-brcmfmac-move-scheduled-scan-activation-to-pno-sourc.patch
@@ -0,0 +1,292 @@
+From 3e48611d31dd333be01576902f2dc11adefc9a06 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:27 +0000
+Subject: [PATCH] brcmfmac: move scheduled scan activation to pno source file
+
+Rework .sched_scan_start() callback moving actual configuration of
+the device in pno source file.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c         |  65 +-----------
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 110 +++++++++++++++++----
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.h |  29 +-----
+ 3 files changed, 94 insertions(+), 110 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -42,7 +42,6 @@
+ #include "common.h"
+ 
+ #define BRCMF_SCAN_IE_LEN_MAX		2048
+-#define BRCMF_SCHED_SCAN_PERIOD		30
+ 
+ #define WPA_OUI				"\x00\x50\xF2"	/* WPA OUI */
+ #define WPA_OUI_TYPE			1
+@@ -3342,24 +3341,6 @@ free_req:
+ 	return err;
+ }
+ 
+-static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid,
+-				 struct cfg80211_sched_scan_request *req)
+-{
+-	int i;
+-
+-	if (!ssid || !req->ssids || !req->n_ssids)
+-		return false;
+-
+-	for (i = 0; i < req->n_ssids; i++) {
+-		if (ssid->ssid_len == req->ssids[i].ssid_len) {
+-			if (!strncmp(ssid->ssid, req->ssids[i].ssid,
+-				     ssid->ssid_len))
+-				return true;
+-		}
+-	}
+-	return false;
+-}
+-
+ static int
+ brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
+ 				struct net_device *ndev,
+@@ -3367,9 +3348,6 @@ brcmf_cfg80211_sched_scan_start(struct w
+ {
+ 	struct brcmf_if *ifp = netdev_priv(ndev);
+ 	struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
+-	struct cfg80211_ssid *ssid;
+-	int i;
+-	int ret = 0;
+ 
+ 	brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
+ 		  req->n_match_sets, req->n_ssids);
+@@ -3389,48 +3367,7 @@ brcmf_cfg80211_sched_scan_start(struct w
+ 		return -EINVAL;
+ 	}
+ 
+-	/* clean up everything */
+-	ret = brcmf_pno_clean(ifp);
+-	if  (ret < 0) {
+-		brcmf_err("failed error=%d\n", ret);
+-		return ret;
+-	}
+-
+-	/* configure pno */
+-	ret = brcmf_pno_config(ifp, BRCMF_SCHED_SCAN_PERIOD, 0, 0);
+-	if (ret < 0)
+-		return ret;
+-
+-	/* configure random mac */
+-	if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
+-		ret = brcmf_pno_set_random(ifp, req->mac_addr,
+-					   req->mac_addr_mask);
+-		if (ret < 0)
+-			return ret;
+-	}
+-
+-	/* configure each match set */
+-	for (i = 0; i < req->n_match_sets; i++) {
+-
+-		ssid = &req->match_sets[i].ssid;
+-
+-		if (!ssid->ssid_len) {
+-			brcmf_err("skip broadcast ssid\n");
+-			continue;
+-		}
+-
+-		ret = brcmf_pno_add_ssid(ifp, ssid,
+-					 brcmf_is_ssid_active(ssid, req));
+-		if (ret < 0)
+-			brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
+-				  ret == 0 ? "set" : "failed", ssid->ssid);
+-	}
+-	/* Enable the PNO */
+-	ret = brcmf_fil_iovar_int_set(ifp, "pfn", 1);
+-	if (ret < 0)
+-		brcmf_err("PNO enable failed!! ret=%d\n", ret);
+-
+-	return ret;
++	return brcmf_pno_start_sched_scan(ifp, req);
+ }
+ 
+ static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+@@ -32,25 +32,10 @@
+ #define BRCMF_PNO_SCAN_INCOMPLETE	0
+ #define BRCMF_PNO_WPA_AUTH_ANY		0xFFFFFFFF
+ #define BRCMF_PNO_HIDDEN_BIT		2
++#define BRCMF_PNO_SCHED_SCAN_PERIOD	30
+ 
+-int brcmf_pno_clean(struct brcmf_if *ifp)
+-{
+-	int ret;
+-
+-	/* Disable pfn */
+-	ret = brcmf_fil_iovar_int_set(ifp, "pfn", 0);
+-	if (ret == 0) {
+-		/* clear pfn */
+-		ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0);
+-	}
+-	if (ret < 0)
+-		brcmf_err("failed code %d\n", ret);
+-
+-	return ret;
+-}
+-
+-int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
+-		     u32 mscan, u32 bestn)
++static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
++			    u32 mscan, u32 bestn)
+ {
+ 	struct brcmf_pno_param_le pfn_param;
+ 	u16 flags;
+@@ -102,7 +87,8 @@ exit:
+ 	return err;
+ }
+ 
+-int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask)
++static int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr,
++				u8 *mac_mask)
+ {
+ 	struct brcmf_pno_macaddr_le pfn_mac;
+ 	int err, i;
+@@ -128,8 +114,8 @@ int brcmf_pno_set_random(struct brcmf_if
+ 	return err;
+ }
+ 
+-int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
+-		       bool active)
++static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
++			      bool active)
+ {
+ 	struct brcmf_pno_net_param_le pfn;
+ 
+@@ -144,3 +130,85 @@ int brcmf_pno_add_ssid(struct brcmf_if *
+ 	return brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn));
+ }
+ 
++static bool brcmf_is_ssid_active(struct cfg80211_ssid *ssid,
++				 struct cfg80211_sched_scan_request *req)
++{
++	int i;
++
++	if (!ssid || !req->ssids || !req->n_ssids)
++		return false;
++
++	for (i = 0; i < req->n_ssids; i++) {
++		if (ssid->ssid_len == req->ssids[i].ssid_len) {
++			if (!strncmp(ssid->ssid, req->ssids[i].ssid,
++				     ssid->ssid_len))
++				return true;
++		}
++	}
++	return false;
++}
++
++int brcmf_pno_clean(struct brcmf_if *ifp)
++{
++	int ret;
++
++	/* Disable pfn */
++	ret = brcmf_fil_iovar_int_set(ifp, "pfn", 0);
++	if (ret == 0) {
++		/* clear pfn */
++		ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0);
++	}
++	if (ret < 0)
++		brcmf_err("failed code %d\n", ret);
++
++	return ret;
++}
++
++int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
++			       struct cfg80211_sched_scan_request *req)
++{
++	struct cfg80211_ssid *ssid;
++	int i, ret;
++
++	/* clean up everything */
++	ret = brcmf_pno_clean(ifp);
++	if  (ret < 0) {
++		brcmf_err("failed error=%d\n", ret);
++		return ret;
++	}
++
++	/* configure pno */
++	ret = brcmf_pno_config(ifp, BRCMF_PNO_SCHED_SCAN_PERIOD, 0, 0);
++	if (ret < 0)
++		return ret;
++
++	/* configure random mac */
++	if (req->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
++		ret = brcmf_pno_set_random(ifp, req->mac_addr,
++					   req->mac_addr_mask);
++		if (ret < 0)
++			return ret;
++	}
++
++	/* configure each match set */
++	for (i = 0; i < req->n_match_sets; i++) {
++		ssid = &req->match_sets[i].ssid;
++		if (!ssid->ssid_len) {
++			brcmf_err("skip broadcast ssid\n");
++			continue;
++		}
++
++		ret = brcmf_pno_add_ssid(ifp, ssid,
++					 brcmf_is_ssid_active(ssid, req));
++		if (ret < 0)
++			brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
++				  ret == 0 ? "set" : "failed", ssid->ssid);
++	}
++	/* Enable the PNO */
++	ret = brcmf_fil_iovar_int_set(ifp, "pfn", 1);
++	if (ret < 0)
++		brcmf_err("PNO enable failed!! ret=%d\n", ret);
++
++	return ret;
++}
++
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
+@@ -27,33 +27,12 @@
+ int brcmf_pno_clean(struct brcmf_if *ifp);
+ 
+ /**
+- * brcmf_pno_config - configure pno parameters.
++ * brcmf_pno_start_sched_scan - initiate scheduled scan on device.
+  *
+  * @ifp: interface object used.
+- * @scan_freq: scan frequency period in seconds.
+- * @mscan: maximum number of scans stored in firmware.
+- * @bestn: maximum number of APs per scan stored in firmware.
++ * @req: configuration parameters for scheduled scan.
+  */
+-int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
+-		     u32 mscan, u32 bestn);
+-
+-/**
+- * brcmf_pno_set_random - setup randomisation mac address for pno.
+- *
+- * @ifp: interface object used.
+- * @mac_addr: MAC address used with randomisation.
+- * @mac_mask: MAC address mask used for randomisation.
+- */
+-int brcmf_pno_set_random(struct brcmf_if *ifp, u8 *mac_addr, u8 *mac_mask);
+-
+-/**
+- * brcmf_pno_add_ssid - add ssid for pno in firmware.
+- *
+- * @ifp: interface object used.
+- * @ssid: ssid information.
+- * @active: indicate this ssid needs to be actively probed.
+- */
+-int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid,
+-		       bool active);
++int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
++			       struct cfg80211_sched_scan_request *req);
+ 
+ #endif /* _BRCMF_PNO_H */
diff --git a/package/kernel/mac80211/patches/357-0009-brcmfmac-use-provided-channels-for-scheduled-scan.patch b/package/kernel/mac80211/patches/357-0009-brcmfmac-use-provided-channels-for-scheduled-scan.patch
new file mode 100644
index 0000000..fae844c
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0009-brcmfmac-use-provided-channels-for-scheduled-scan.patch
@@ -0,0 +1,111 @@
+From 331e789443618ca9cc3ed48ada4e670225cca036 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:28 +0000
+Subject: [PATCH] brcmfmac: use provided channels for scheduled scan
+
+User-space can provide list of channels in the schedule scan request.
+This was ignored so all channels supported and allowed by the device
+were used. This patch configures the device to use the channels as
+listed in the request.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/fwil_types.h       | 16 +++++++++++++
+ .../net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 26 +++++++++++++++++++++-
+ 2 files changed, 41 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+@@ -131,6 +131,7 @@
+ #define BRCMF_TXBF_MU_BFR_CAP		BIT(1)
+ 
+ #define	BRCMF_MAXPMKID			16	/* max # PMKID cache entries */
++#define BRCMF_NUMCHANNELS		64
+ 
+ #define BRCMF_PFN_MACADDR_CFG_VER	1
+ #define BRCMF_PFN_MAC_OUI_ONLY		BIT(0)
+@@ -719,6 +720,21 @@ struct brcmf_pno_param_le {
+ };
+ 
+ /**
++ * struct brcmf_pno_config_le - PNO channel configuration.
++ *
++ * @reporttype: determines what is reported.
++ * @channel_num: number of channels specified in @channel_list.
++ * @channel_list: channels to use in PNO scan.
++ * @flags: reserved.
++ */
++struct brcmf_pno_config_le {
++	__le32  reporttype;
++	__le32  channel_num;
++	__le16  channel_list[BRCMF_NUMCHANNELS];
++	__le32  flags;
++};
++
++/**
+  * struct brcmf_pno_net_param_le - scan parameters per preferred network.
+  *
+  * @ssid: ssid name and its length.
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+@@ -18,9 +18,10 @@
+ 
+ #include "core.h"
+ #include "debug.h"
+-#include "pno.h"
+ #include "fwil.h"
+ #include "fwil_types.h"
++#include "cfg80211.h"
++#include "pno.h"
+ 
+ #define BRCMF_PNO_VERSION		2
+ #define BRCMF_PNO_REPEAT		4
+@@ -34,6 +35,15 @@
+ #define BRCMF_PNO_HIDDEN_BIT		2
+ #define BRCMF_PNO_SCHED_SCAN_PERIOD	30
+ 
++static int brcmf_pno_channel_config(struct brcmf_if *ifp,
++				    struct brcmf_pno_config_le *cfg)
++{
++	cfg->reporttype = 0;
++	cfg->flags = 0;
++
++	return brcmf_fil_iovar_data_set(ifp, "pfn_cfg", cfg, sizeof(*cfg));
++}
++
+ static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq,
+ 			    u32 mscan, u32 bestn)
+ {
+@@ -167,7 +177,10 @@ int brcmf_pno_clean(struct brcmf_if *ifp
+ int brcmf_pno_start_sched_scan(struct brcmf_if *ifp,
+ 			       struct cfg80211_sched_scan_request *req)
+ {
++	struct brcmu_d11inf *d11inf;
++	struct brcmf_pno_config_le pno_cfg;
+ 	struct cfg80211_ssid *ssid;
++	u16 chan;
+ 	int i, ret;
+ 
+ 	/* clean up everything */
+@@ -190,6 +203,17 @@ int brcmf_pno_start_sched_scan(struct br
+ 			return ret;
+ 	}
+ 
++	/* configure channels to use */
++	d11inf = &ifp->drvr->config->d11inf;
++	for (i = 0; i < req->n_channels; i++) {
++		chan = req->channels[i]->hw_value;
++		pno_cfg.channel_list[i] = cpu_to_le16(chan);
++	}
++	if (req->n_channels) {
++		pno_cfg.channel_num = cpu_to_le32(req->n_channels);
++		brcmf_pno_channel_config(ifp, &pno_cfg);
++	}
++
+ 	/* configure each match set */
+ 	for (i = 0; i < req->n_match_sets; i++) {
+ 		ssid = &req->match_sets[i].ssid;
diff --git a/package/kernel/mac80211/patches/357-0010-brcmfmac-remove-restriction-from-.sched_scan_start-c.patch b/package/kernel/mac80211/patches/357-0010-brcmfmac-remove-restriction-from-.sched_scan_start-c.patch
new file mode 100644
index 0000000..d14a60a
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0010-brcmfmac-remove-restriction-from-.sched_scan_start-c.patch
@@ -0,0 +1,34 @@
+From dfe5b0d52d5880bd9d4b427e1a53c9e9e4c3c820 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:29 +0000
+Subject: [PATCH] brcmfmac: remove restriction from .sched_scan_start()
+ callback
+
+In the .sched_scan_start() callback a condition was checked whether a
+normal scan was ongoing. However, there is no need for this check as
+it is ok to start the scheduled scan irrespective whether or not a
+normal scan is ongoing.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3351,10 +3351,7 @@ brcmf_cfg80211_sched_scan_start(struct w
+ 
+ 	brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
+ 		  req->n_match_sets, req->n_ssids);
+-	if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
+-		brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
+-		return -EAGAIN;
+-	}
++
+ 	if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
+ 		brcmf_err("Scanning suppressed: status (%lu)\n",
+ 			  cfg->scan_status);
diff --git a/package/kernel/mac80211/patches/357-0011-brcmfmac-use-requested-scan-interval-in-scheduled-sc.patch b/package/kernel/mac80211/patches/357-0011-brcmfmac-use-requested-scan-interval-in-scheduled-sc.patch
new file mode 100644
index 0000000..eb1d5d3
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0011-brcmfmac-use-requested-scan-interval-in-scheduled-sc.patch
@@ -0,0 +1,67 @@
+From c6989fd55ceb633d2f18c12ffae01b9123125c89 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:30 +0000
+Subject: [PATCH] brcmfmac: use requested scan interval in scheduled scan
+
+User-space can specify the interval for the scheduled scan. This
+interval is found in scheduled scan plan. The driver supports only
+one plan, which is legacy behaviour.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 1 +
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c      | 6 +++++-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h      | 6 ++++--
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -6312,6 +6312,7 @@ static void brcmf_wiphy_pno_params(struc
+ 	wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
+ 	wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
+ 	wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
++	wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD;
+ 	wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
+ }
+ 
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+@@ -63,6 +63,10 @@ static int brcmf_pno_config(struct brcmf
+ 	pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
+ 
+ 	/* set up pno scan fr */
++	if (scan_freq < BRCMF_PNO_SCHED_SCAN_MIN_PERIOD) {
++		brcmf_dbg(SCAN, "scan period too small, using minimum\n");
++		scan_freq = BRCMF_PNO_SCHED_SCAN_MIN_PERIOD;
++	}
+ 	pfn_param.scan_freq = cpu_to_le32(scan_freq);
+ 
+ 	if (mscan) {
+@@ -191,7 +195,7 @@ int brcmf_pno_start_sched_scan(struct br
+ 	}
+ 
+ 	/* configure pno */
+-	ret = brcmf_pno_config(ifp, BRCMF_PNO_SCHED_SCAN_PERIOD, 0, 0);
++	ret = brcmf_pno_config(ifp, req->scan_plans[0].interval, 0, 0);
+ 	if (ret < 0)
+ 		return ret;
+ 
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.h
+@@ -16,8 +16,10 @@
+ #ifndef _BRCMF_PNO_H
+ #define _BRCMF_PNO_H
+ 
+-#define BRCMF_PNO_SCAN_COMPLETE		1
+-#define BRCMF_PNO_MAX_PFN_COUNT		16
++#define BRCMF_PNO_SCAN_COMPLETE			1
++#define BRCMF_PNO_MAX_PFN_COUNT			16
++#define BRCMF_PNO_SCHED_SCAN_MIN_PERIOD	10
++#define BRCMF_PNO_SCHED_SCAN_MAX_PERIOD	508
+ 
+ /**
+  * brcmf_pno_clean - disable and clear pno in firmware.
diff --git a/package/kernel/mac80211/patches/357-0012-brcmfmac-fix-scheduled-scan-result-handling-for-newe.patch b/package/kernel/mac80211/patches/357-0012-brcmfmac-fix-scheduled-scan-result-handling-for-newe.patch
new file mode 100644
index 0000000..bbd8774
--- /dev/null
+++ b/package/kernel/mac80211/patches/357-0012-brcmfmac-fix-scheduled-scan-result-handling-for-newe.patch
@@ -0,0 +1,76 @@
+From 53e3a80d80c80bf50ab64cf6c44fb0fa41aa22d8 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel at broadcom.com>
+Date: Wed, 23 Nov 2016 10:25:31 +0000
+Subject: [PATCH] brcmfmac: fix scheduled scan result handling for newer chips
+
+The scan results for scheduled scan as retrieved from the device
+have changed. A field has been added which is not needed. However,
+the appended info is. Luckily they are versioned so check that to
+find out the location of the appended data.
+
+Reviewed-by: Hante Meuleman <hante.meuleman at broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts at broadcom.com>
+Reviewed-by: Franky Lin <franky.lin at broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel at broadcom.com>
+Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c         | 24 +++++++++++++++++++++-
+ .../broadcom/brcm80211/brcmfmac/fwil_types.h       |  7 +++++++
+ 2 files changed, 30 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3257,6 +3257,28 @@ static int brcmf_start_internal_escan(st
+ 	return 0;
+ }
+ 
++static struct brcmf_pno_net_info_le *
++brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1)
++{
++	struct brcmf_pno_scanresults_v2_le *pfn_v2;
++	struct brcmf_pno_net_info_le *netinfo;
++
++	switch (pfn_v1->version) {
++	default:
++		WARN_ON(1);
++		/* fall-thru */
++	case cpu_to_le32(1):
++		netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1);
++		break;
++	case cpu_to_le32(2):
++		pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1;
++		netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1);
++		break;
++	}
++
++	return netinfo;
++}
++
+ /* PFN result doesn't have all the info which are required by the supplicant
+  * (For e.g IEs) Do a target Escan so that sched scan results are reported
+  * via wl_inform_single_bss in the required format. Escan does require the
+@@ -3309,7 +3331,7 @@ brcmf_notify_sched_scan_results(struct b
+ 	}
+ 
+ 	data += sizeof(struct brcmf_pno_scanresults_le);
+-	netinfo_start = (struct brcmf_pno_net_info_le *)data;
++	netinfo_start = brcmf_get_netinfo_array(pfn_result);
+ 
+ 	for (i = 0; i < result_count; i++) {
+ 		netinfo = &netinfo_start[i];
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+@@ -785,6 +785,13 @@ struct brcmf_pno_scanresults_le {
+ 	__le32 count;
+ };
+ 
++struct brcmf_pno_scanresults_v2_le {
++	__le32 version;
++	__le32 status;
++	__le32 count;
++	__le32 scan_ch_bucket;
++};
++
+ /**
+  * struct brcmf_pno_macaddr_le - to configure PNO macaddr randomization.
+  *
diff --git a/package/kernel/mac80211/patches/360-0001-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch b/package/kernel/mac80211/patches/360-0001-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch
index 58af4d9..c2ea368 100644
--- a/package/kernel/mac80211/patches/360-0001-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch
+++ b/package/kernel/mac80211/patches/360-0001-brcmfmac-avoid-writing-channel-out-of-allocated-arra.patch
@@ -28,7 +28,7 @@ Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -5915,7 +5915,6 @@ static int brcmf_construct_chaninfo(stru
+@@ -5823,7 +5823,6 @@ static int brcmf_construct_chaninfo(stru
  	u32 i, j;
  	u32 total;
  	u32 chaninfo;
@@ -36,7 +36,7 @@ Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
  
  	pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
  
-@@ -5963,33 +5962,36 @@ static int brcmf_construct_chaninfo(stru
+@@ -5871,33 +5870,36 @@ static int brcmf_construct_chaninfo(stru
  		    ch.bw == BRCMU_CHAN_BW_80)
  			continue;
  
@@ -85,7 +85,7 @@ Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
  			ch.bw = BRCMU_CHAN_BW_20;
  			cfg->d11inf.encchspec(&ch);
  			chaninfo = ch.chspec;
-@@ -5997,11 +5999,11 @@ static int brcmf_construct_chaninfo(stru
+@@ -5905,11 +5907,11 @@ static int brcmf_construct_chaninfo(stru
  						       &chaninfo);
  			if (!err) {
  				if (chaninfo & WL_CHAN_RADAR)
diff --git a/package/kernel/mac80211/patches/360-0002-brcmfmac-don-t-preset-all-channels-as-disabled.patch b/package/kernel/mac80211/patches/360-0002-brcmfmac-don-t-preset-all-channels-as-disabled.patch
index dbe4564..5a66a35 100644
--- a/package/kernel/mac80211/patches/360-0002-brcmfmac-don-t-preset-all-channels-as-disabled.patch
+++ b/package/kernel/mac80211/patches/360-0002-brcmfmac-don-t-preset-all-channels-as-disabled.patch
@@ -17,7 +17,7 @@ Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -147,7 +147,6 @@ static struct ieee80211_rate __wl_rates[
+@@ -138,7 +138,6 @@ static struct ieee80211_rate __wl_rates[
  	.band			= NL80211_BAND_2GHZ,		\
  	.center_freq		= (_freq),			\
  	.hw_value		= (_channel),			\
@@ -25,7 +25,7 @@ Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
  	.max_antenna_gain	= 0,				\
  	.max_power		= 30,				\
  }
-@@ -156,7 +155,6 @@ static struct ieee80211_rate __wl_rates[
+@@ -147,7 +146,6 @@ static struct ieee80211_rate __wl_rates[
  	.band			= NL80211_BAND_5GHZ,		\
  	.center_freq		= 5000 + (5 * (_channel)),	\
  	.hw_value		= (_channel),			\
diff --git a/package/kernel/mac80211/patches/360-0003-brcmfmac-setup-wiphy-bands-after-registering-it-firs.patch b/package/kernel/mac80211/patches/360-0003-brcmfmac-setup-wiphy-bands-after-registering-it-firs.patch
index 9c773bd..29ebad7 100644
--- a/package/kernel/mac80211/patches/360-0003-brcmfmac-setup-wiphy-bands-after-registering-it-firs.patch
+++ b/package/kernel/mac80211/patches/360-0003-brcmfmac-setup-wiphy-bands-after-registering-it-firs.patch
@@ -25,7 +25,7 @@ Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -6566,8 +6566,7 @@ static int brcmf_setup_wiphy(struct wiph
+@@ -6475,8 +6475,7 @@ static int brcmf_setup_wiphy(struct wiph
  			wiphy->bands[NL80211_BAND_5GHZ] = band;
  		}
  	}
@@ -35,7 +35,7 @@ Signed-off-by: Kalle Valo <kvalo at codeaurora.org>
  }
  
  static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
-@@ -6932,6 +6931,12 @@ struct brcmf_cfg80211_info *brcmf_cfg802
+@@ -6841,6 +6840,12 @@ struct brcmf_cfg80211_info *brcmf_cfg802
  		goto priv_out;
  	}
  
diff --git a/package/kernel/mac80211/patches/841-brcmfmac-use-wiphy_read_of_freq_limits.patch b/package/kernel/mac80211/patches/841-brcmfmac-use-wiphy_read_of_freq_limits.patch
index 9f26a49..c23d4c0 100644
--- a/package/kernel/mac80211/patches/841-brcmfmac-use-wiphy_read_of_freq_limits.patch
+++ b/package/kernel/mac80211/patches/841-brcmfmac-use-wiphy_read_of_freq_limits.patch
@@ -9,7 +9,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -5976,6 +5976,9 @@ static int brcmf_construct_chaninfo(stru
+@@ -5884,6 +5884,9 @@ static int brcmf_construct_chaninfo(stru
  			continue;
  		}
  
@@ -19,7 +19,7 @@ Signed-off-by: Rafał Miłecki <rafal at milecki.pl>
  		/* assuming the chanspecs order is HT20,
  		 * HT40 upper, HT40 lower, and VHT80.
  		 */
-@@ -6566,6 +6569,9 @@ static int brcmf_setup_wiphy(struct wiph
+@@ -6475,6 +6478,9 @@ static int brcmf_setup_wiphy(struct wiph
  			wiphy->bands[NL80211_BAND_5GHZ] = band;
  		}
  	}
diff --git a/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
index 7551b7d..c7b1389 100644
--- a/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
+++ b/package/kernel/mac80211/patches/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
@@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5 at gmail.com>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -663,9 +663,37 @@ static struct wireless_dev *brcmf_cfg802
+@@ -654,9 +654,37 @@ static struct wireless_dev *brcmf_cfg802
  						     u32 *flags,
  						     struct vif_params *params)
  {
diff --git a/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch
index 70b8844..83bc7fe 100644
--- a/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch
+++ b/package/kernel/mac80211/patches/862-brcmfmac-Disable-power-management.patch
@@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil at raspberrypi.org>
 
 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
 +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
-@@ -2782,6 +2782,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
+@@ -2773,6 +2773,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
  	 * preference in cfg struct to apply this to
  	 * FW later while initializing the dongle
  	 */



More information about the lede-commits mailing list