aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafał Miłecki <zajec5@gmail.com>2016-01-10 00:19:09 +0000
committerRafał Miłecki <zajec5@gmail.com>2016-01-10 00:19:09 +0000
commit615ff23d4f635cfefaf2960cd9233e540b1eaab5 (patch)
tree8e7d919264803bbeb0435dfa5e65974bb0b49739
parent8e2500205b6c8aa1332baa5db4a5194c911c1334 (diff)
downloadupstream-615ff23d4f635cfefaf2960cd9233e540b1eaab5.tar.gz
upstream-615ff23d4f635cfefaf2960cd9233e540b1eaab5.tar.bz2
upstream-615ff23d4f635cfefaf2960cd9233e540b1eaab5.zip
mac80211: brcmfmac: fix getting/setting TX power
This patches also adds BCM4366 support which may be found on some new routers based on BCM47094 or BCM4709C0. Unfortunately firmware is still missing for this chipset. git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@48166 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r--package/kernel/mac80211/patches/370-0001-brcmfmac-Fix-exception-handling.patch24
-rw-r--r--package/kernel/mac80211/patches/370-0002-brcmfmac-Add-support-for-the-BCM4350-PCIE-device.patch81
-rw-r--r--package/kernel/mac80211/patches/370-0003-brcmfmac-Fix-set-and-get-tx-power-functions.patch218
-rw-r--r--package/kernel/mac80211/patches/370-0004-brcmfmac-Only-assign-primary-netdev-to-if2bss-array.patch73
-rw-r--r--package/kernel/mac80211/patches/370-0005-brcmfmac-Inform-p2p-module-about-p2pon-through-API.patch113
-rw-r--r--package/kernel/mac80211/patches/370-0006-brcmfmac-Fix-bug-in-flowring-management.patch26
-rw-r--r--package/kernel/mac80211/patches/370-0007-brcmfmac-Make-p2pon-module-param-always-available.patch29
-rw-r--r--package/kernel/mac80211/patches/370-0008-brcmfmac-Workaround-in-change-vif-for-wpa_supplicant.patch76
-rw-r--r--package/kernel/mac80211/patches/370-0009-brcmfmac-Deleting-of-p2p-device-is-leaking-memory.patch124
-rw-r--r--package/kernel/mac80211/patches/370-0010-brcmfmac-Only-handle-p2p_stop_device-if-vif-is-valid.patch40
-rw-r--r--package/kernel/mac80211/patches/370-0011-brcmfmac-Fix-p2p-bug-for-older-firmwares.patch35
-rw-r--r--package/kernel/mac80211/patches/370-0012-brcmfmac-Add-module-parameter-to-disable-features.patch54
-rw-r--r--package/kernel/mac80211/patches/370-0013-brcmfmac-Fix-race-condition-bug-when-deleting-p2p-in.patch80
-rw-r--r--package/kernel/mac80211/patches/370-0014-brcmfmac-Add-support-for-the-BCM4365-and-BCM4366-PCI.patch277
-rw-r--r--package/kernel/mac80211/patches/370-0015-brcmfmac-Fix-TDLS-setup-by-properly-handling-p2p-noi.patch120
-rw-r--r--package/kernel/mac80211/patches/370-0016-brcmfmac-Accept-events-when-TDLS-is-used-in-combinat.patch29
-rw-r--r--package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch2
-rw-r--r--package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch2
18 files changed, 1401 insertions, 2 deletions
diff --git a/package/kernel/mac80211/patches/370-0001-brcmfmac-Fix-exception-handling.patch b/package/kernel/mac80211/patches/370-0001-brcmfmac-Fix-exception-handling.patch
new file mode 100644
index 0000000000..bcd10314d9
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0001-brcmfmac-Fix-exception-handling.patch
@@ -0,0 +1,24 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:04 +0200
+Subject: [PATCH] brcmfmac: Fix exception handling.
+
+In some exception situations the ifp->vif was not properly assigned
+which could result in crash.
+
+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/cfg80211.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+@@ -6331,6 +6331,7 @@ wiphy_unreg_out:
+ priv_out:
+ wl_deinit_priv(cfg);
+ brcmf_free_vif(vif);
++ ifp->vif = NULL;
+ wiphy_out:
+ brcmf_free_wiphy(wiphy);
+ return NULL;
diff --git a/package/kernel/mac80211/patches/370-0002-brcmfmac-Add-support-for-the-BCM4350-PCIE-device.patch b/package/kernel/mac80211/patches/370-0002-brcmfmac-Add-support-for-the-BCM4350-PCIE-device.patch
new file mode 100644
index 0000000000..f4ab77b599
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0002-brcmfmac-Add-support-for-the-BCM4350-PCIE-device.patch
@@ -0,0 +1,81 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:05 +0200
+Subject: [PATCH] brcmfmac: Add support for the BCM4350 PCIE device.
+
+This patch adds support fo the BRCM4350 2x2 11ac PCIE device.
+
+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@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/chip.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+@@ -647,6 +647,7 @@ static u32 brcmf_chip_tcm_rambase(struct
+ return 0x198000;
+ case BRCM_CC_4335_CHIP_ID:
+ case BRCM_CC_4339_CHIP_ID:
++ case BRCM_CC_4350_CHIP_ID:
+ case BRCM_CC_4354_CHIP_ID:
+ case BRCM_CC_4356_CHIP_ID:
+ case BRCM_CC_43567_CHIP_ID:
+--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+@@ -47,6 +47,8 @@ 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_4350_FW_NAME "brcm/brcmfmac4350-pcie.bin"
++#define BRCMF_PCIE_4350_NVRAM_NAME "brcm/brcmfmac4350-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"
+@@ -194,6 +196,8 @@ enum brcmf_pcie_state {
+
+ MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME);
++MODULE_FIRMWARE(BRCMF_PCIE_4350_FW_NAME);
++MODULE_FIRMWARE(BRCMF_PCIE_4350_NVRAM_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
+@@ -1418,6 +1422,10 @@ 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_4350_CHIP_ID:
++ fw_name = BRCMF_PCIE_4350_FW_NAME;
++ nvram_name = BRCMF_PCIE_4350_NVRAM_NAME;
++ break;
+ case BRCM_CC_4356_CHIP_ID:
+ fw_name = BRCMF_PCIE_4356_FW_NAME;
+ nvram_name = BRCMF_PCIE_4356_NVRAM_NAME;
+@@ -1956,6 +1964,7 @@ 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_4350_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),
+--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+@@ -39,6 +39,7 @@
+ #define BRCM_CC_4339_CHIP_ID 0x4339
+ #define BRCM_CC_43430_CHIP_ID 43430
+ #define BRCM_CC_4345_CHIP_ID 0x4345
++#define BRCM_CC_4350_CHIP_ID 0x4350
+ #define BRCM_CC_4354_CHIP_ID 0x4354
+ #define BRCM_CC_4356_CHIP_ID 0x4356
+ #define BRCM_CC_43566_CHIP_ID 43566
+@@ -56,6 +57,7 @@
+ #define BRCM_USB_BCMFW_DEVICE_ID 0x0bdc
+
+ /* PCIE Device IDs */
++#define BRCM_PCIE_4350_DEVICE_ID 0x43a3
+ #define BRCM_PCIE_4354_DEVICE_ID 0x43df
+ #define BRCM_PCIE_4356_DEVICE_ID 0x43ec
+ #define BRCM_PCIE_43567_DEVICE_ID 0x43d3
diff --git a/package/kernel/mac80211/patches/370-0003-brcmfmac-Fix-set-and-get-tx-power-functions.patch b/package/kernel/mac80211/patches/370-0003-brcmfmac-Fix-set-and-get-tx-power-functions.patch
new file mode 100644
index 0000000000..62fdd8d745
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0003-brcmfmac-Fix-set-and-get-tx-power-functions.patch
@@ -0,0 +1,218 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:06 +0200
+Subject: [PATCH] brcmfmac: Fix set and get tx-power functions.
+
+Implementation of tx-power (get and set) related functions are
+still assuming mW interface. This is wrong as functions use dbm
+(or mbm) nowadays. As a result a tx power configuration could
+result in wrong power configuration.
+
+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@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/cfg80211.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+@@ -236,89 +236,6 @@ static int brcmf_roamoff;
+ module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
+ MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
+
+-/* Quarter dBm units to mW
+- * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
+- * Table is offset so the last entry is largest mW value that fits in
+- * a u16.
+- */
+-
+-#define QDBM_OFFSET 153 /* Offset for first entry */
+-#define QDBM_TABLE_LEN 40 /* Table size */
+-
+-/* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
+- * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
+- */
+-#define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
+-
+-/* Largest mW value that will round down to the last table entry,
+- * QDBM_OFFSET + QDBM_TABLE_LEN-1.
+- * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
+- * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
+- */
+-#define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
+-
+-static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
+-/* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
+-/* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
+-/* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
+-/* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
+-/* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
+-/* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
+-};
+-
+-static u16 brcmf_qdbm_to_mw(u8 qdbm)
+-{
+- uint factor = 1;
+- int idx = qdbm - QDBM_OFFSET;
+-
+- if (idx >= QDBM_TABLE_LEN)
+- /* clamp to max u16 mW value */
+- return 0xFFFF;
+-
+- /* scale the qdBm index up to the range of the table 0-40
+- * where an offset of 40 qdBm equals a factor of 10 mW.
+- */
+- while (idx < 0) {
+- idx += 40;
+- factor *= 10;
+- }
+-
+- /* return the mW value scaled down to the correct factor of 10,
+- * adding in factor/2 to get proper rounding.
+- */
+- return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
+-}
+-
+-static u8 brcmf_mw_to_qdbm(u16 mw)
+-{
+- u8 qdbm;
+- int offset;
+- uint mw_uint = mw;
+- uint boundary;
+-
+- /* handle boundary case */
+- if (mw_uint <= 1)
+- return 0;
+-
+- offset = QDBM_OFFSET;
+-
+- /* move mw into the range of the table */
+- while (mw_uint < QDBM_TABLE_LOW_BOUND) {
+- mw_uint *= 10;
+- offset -= 40;
+- }
+-
+- for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
+- boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
+- nqdBm_to_mW_map[qdbm]) / 2;
+- if (mw_uint < boundary)
+- break;
+- }
+-
+- qdbm += (u8) offset;
+-
+- return qdbm;
+-}
+
+ static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
+ struct cfg80211_chan_def *ch)
+@@ -2016,16 +1933,14 @@ static s32
+ brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
+ enum nl80211_tx_power_setting type, s32 mbm)
+ {
+-
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct net_device *ndev = cfg_to_ndev(cfg);
+ struct brcmf_if *ifp = netdev_priv(ndev);
+- u16 txpwrmw;
+- s32 err = 0;
+- s32 disable = 0;
+- s32 dbm = MBM_TO_DBM(mbm);
++ s32 err;
++ s32 disable;
++ u32 qdbm = 127;
+
+- brcmf_dbg(TRACE, "Enter\n");
++ brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
+ if (!check_vif_up(ifp->vif))
+ return -EIO;
+
+@@ -2034,12 +1949,20 @@ brcmf_cfg80211_set_tx_power(struct wiphy
+ break;
+ case NL80211_TX_POWER_LIMITED:
+ case NL80211_TX_POWER_FIXED:
+- if (dbm < 0) {
++ if (mbm < 0) {
+ brcmf_err("TX_POWER_FIXED - dbm is negative\n");
+ err = -EINVAL;
+ goto done;
+ }
++ qdbm = MBM_TO_DBM(4 * mbm);
++ if (qdbm > 127)
++ qdbm = 127;
++ qdbm |= WL_TXPWR_OVERRIDE;
+ break;
++ default:
++ brcmf_err("Unsupported type %d\n", type);
++ err = -EINVAL;
++ goto done;
+ }
+ /* Make sure radio is off or on as far as software is concerned */
+ disable = WL_RADIO_SW_DISABLE << 16;
+@@ -2047,52 +1970,44 @@ brcmf_cfg80211_set_tx_power(struct wiphy
+ if (err)
+ brcmf_err("WLC_SET_RADIO error (%d)\n", err);
+
+- if (dbm > 0xffff)
+- txpwrmw = 0xffff;
+- else
+- txpwrmw = (u16) dbm;
+- err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
+- (s32)brcmf_mw_to_qdbm(txpwrmw));
++ err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
+ if (err)
+ brcmf_err("qtxpower error (%d)\n", err);
+- cfg->conf->tx_power = dbm;
+
+ done:
+- brcmf_dbg(TRACE, "Exit\n");
++ brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
+ return err;
+ }
+
+-static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
+- struct wireless_dev *wdev,
+- s32 *dbm)
++static s32
++brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
++ s32 *dbm)
+ {
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+- struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
+- s32 txpwrdbm;
+- u8 result;
+- s32 err = 0;
++ struct net_device *ndev = cfg_to_ndev(cfg);
++ struct brcmf_if *ifp = netdev_priv(ndev);
++ s32 qdbm = 0;
++ s32 err;
+
+ brcmf_dbg(TRACE, "Enter\n");
+ if (!check_vif_up(ifp->vif))
+ return -EIO;
+
+- err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
++ err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
+ if (err) {
+ brcmf_err("error (%d)\n", err);
+ goto done;
+ }
+-
+- result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
+- *dbm = (s32) brcmf_qdbm_to_mw(result);
++ *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
+
+ done:
+- brcmf_dbg(TRACE, "Exit\n");
++ brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
+ return err;
+ }
+
+ static s32
+ brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
+- u8 key_idx, bool unicast, bool multicast)
++ u8 key_idx, bool unicast, bool multicast)
+ {
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ u32 index;
diff --git a/package/kernel/mac80211/patches/370-0004-brcmfmac-Only-assign-primary-netdev-to-if2bss-array.patch b/package/kernel/mac80211/patches/370-0004-brcmfmac-Only-assign-primary-netdev-to-if2bss-array.patch
new file mode 100644
index 0000000000..c51365fe29
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0004-brcmfmac-Only-assign-primary-netdev-to-if2bss-array.patch
@@ -0,0 +1,73 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:07 +0200
+Subject: [PATCH] brcmfmac: Only assign primary netdev to if2bss array.
+
+The if2bss allows for translation of ifidx to bssidx which has a 1:n
+relation. Therefor only the first (primary) netdev should be
+assigned in this array. This fixes the p2pon=1 module param usage.
+
+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/core.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
+@@ -53,6 +53,8 @@ MODULE_LICENSE("Dual BSD/GPL");
+ #define BRCMF_RXREORDER_EXPIDX_VALID 0x08
+ #define BRCMF_RXREORDER_NEW_HOLE 0x10
+
++#define BRCMF_BSSIDX_INVALID -1
++
+ /* Error bits */
+ int brcmf_msg_level;
+ module_param_named(debug, brcmf_msg_level, int, S_IRUSR | S_IWUSR);
+@@ -837,7 +839,8 @@ struct brcmf_if *brcmf_add_if(struct brc
+ ifp = netdev_priv(ndev);
+ ifp->ndev = ndev;
+ /* store mapping ifidx to bssidx */
+- drvr->if2bss[ifidx] = bssidx;
++ if (drvr->if2bss[ifidx] == BRCMF_BSSIDX_INVALID)
++ drvr->if2bss[ifidx] = bssidx;
+ }
+
+ ifp->drvr = drvr;
+@@ -862,15 +865,15 @@ static void brcmf_del_if(struct brcmf_pu
+ struct brcmf_if *ifp;
+
+ ifp = drvr->iflist[bssidx];
+- drvr->if2bss[ifp->ifidx] = -1;
+ drvr->iflist[bssidx] = NULL;
+ if (!ifp) {
+ brcmf_err("Null interface, idx=%d\n", bssidx);
+ return;
+ }
+ brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
++ if (drvr->if2bss[ifp->ifidx] == bssidx)
++ drvr->if2bss[ifp->ifidx] = BRCMF_BSSIDX_INVALID;
+ if (ifp->ndev) {
+- drvr->if2bss[ifp->ifidx] = -1;
+ if (bssidx == 0) {
+ if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
+ rtnl_lock();
+@@ -926,6 +929,7 @@ int brcmf_attach(struct device *dev)
+ {
+ struct brcmf_pub *drvr = NULL;
+ int ret = 0;
++ int i;
+
+ brcmf_dbg(TRACE, "Enter\n");
+
+@@ -934,7 +938,9 @@ int brcmf_attach(struct device *dev)
+ if (!drvr)
+ return -ENOMEM;
+
+- memset(drvr->if2bss, 0xFF, sizeof(drvr->if2bss));
++ for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++)
++ drvr->if2bss[i] = BRCMF_BSSIDX_INVALID;
++
+ mutex_init(&drvr->proto_block);
+
+ /* Link to bus module */
diff --git a/package/kernel/mac80211/patches/370-0005-brcmfmac-Inform-p2p-module-about-p2pon-through-API.patch b/package/kernel/mac80211/patches/370-0005-brcmfmac-Inform-p2p-module-about-p2pon-through-API.patch
new file mode 100644
index 0000000000..3c1058d0ad
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0005-brcmfmac-Inform-p2p-module-about-p2pon-through-API.patch
@@ -0,0 +1,113 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:08 +0200
+Subject: [PATCH] brcmfmac: Inform p2p module about p2pon through API
+
+When the p2pon module param is used then p2p attach will initialize
+p2p device iface in the firmware, but it is doing that by checking
+data. It is cleaner to pass the p2pon information to p2p by API.
+This information is also needed for other patch.
+
+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/cfg80211.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+@@ -6126,7 +6126,8 @@ static void brcmf_free_wiphy(struct wiph
+ }
+
+ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
+- struct device *busdev)
++ struct device *busdev,
++ bool p2pdev_forced)
+ {
+ struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
+ struct brcmf_cfg80211_info *cfg;
+@@ -6218,7 +6219,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802
+ *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+ }
+
+- err = brcmf_p2p_attach(cfg);
++ err = brcmf_p2p_attach(cfg, p2pdev_forced);
+ if (err) {
+ brcmf_err("P2P initilisation failed (%d)\n", err);
+ goto wiphy_unreg_out;
+--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
+@@ -469,7 +469,8 @@ brcmf_cfg80211_connect_info *cfg_to_conn
+ }
+
+ struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
+- struct device *busdev);
++ struct device *busdev,
++ bool p2pdev_forced);
+ void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg);
+ s32 brcmf_cfg80211_up(struct net_device *ndev);
+ s32 brcmf_cfg80211_down(struct net_device *ndev);
+--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
+@@ -1044,7 +1044,8 @@ int brcmf_bus_start(struct device *dev)
+
+ brcmf_fws_add_interface(ifp);
+
+- drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev);
++ drvr->config = brcmf_cfg80211_attach(drvr, bus_if->dev,
++ brcmf_p2p_enable);
+ if (drvr->config == NULL) {
+ ret = -ENOMEM;
+ goto fail;
+--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+@@ -2333,7 +2333,7 @@ void brcmf_p2p_stop_device(struct wiphy
+ *
+ * @cfg: driver private data for cfg80211 interface.
+ */
+-s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg)
++s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced)
+ {
+ struct brcmf_if *pri_ifp;
+ struct brcmf_if *p2p_ifp;
+@@ -2348,11 +2348,15 @@ s32 brcmf_p2p_attach(struct brcmf_cfg802
+
+ drvr = cfg->pub;
+
+- pri_ifp = drvr->iflist[0];
+- p2p_ifp = drvr->iflist[1];
+-
++ pri_ifp = brcmf_get_ifp(drvr, 0);
+ p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
+
++ if (p2pdev_forced) {
++ p2p_ifp = drvr->iflist[1];
++ } else {
++ p2p_ifp = NULL;
++ p2p->p2pdev_dynamically = true;
++ }
+ if (p2p_ifp) {
+ p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE,
+ false);
+--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
+@@ -124,6 +124,7 @@ struct afx_hdl {
+ * @wait_next_af: thread synchronizing struct.
+ * @gon_req_action: about to send go negotiation requets frame.
+ * @block_gon_req_tx: drop tx go negotiation requets frame.
++ * @p2pdev_dynamically: is p2p device if created by module param or supplicant.
+ */
+ struct brcmf_p2p_info {
+ struct brcmf_cfg80211_info *cfg;
+@@ -144,9 +145,10 @@ struct brcmf_p2p_info {
+ struct completion wait_next_af;
+ bool gon_req_action;
+ bool block_gon_req_tx;
++ bool p2pdev_dynamically;
+ };
+
+-s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg);
++s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced);
+ void brcmf_p2p_detach(struct brcmf_p2p_info *p2p);
+ struct wireless_dev *brcmf_p2p_add_vif(struct wiphy *wiphy, const char *name,
+ enum nl80211_iftype type, u32 *flags,
diff --git a/package/kernel/mac80211/patches/370-0006-brcmfmac-Fix-bug-in-flowring-management.patch b/package/kernel/mac80211/patches/370-0006-brcmfmac-Fix-bug-in-flowring-management.patch
new file mode 100644
index 0000000000..66b2117693
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0006-brcmfmac-Fix-bug-in-flowring-management.patch
@@ -0,0 +1,26 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:09 +0200
+Subject: [PATCH] brcmfmac: Fix bug in flowring management.
+
+The hash index stored in the flowrings is of type u16 but gets
+stored in u8. This can result in incorrect indexing and possibly
+result in crashes. This patch fixes the type.
+
+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/flowring.h
++++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.h
+@@ -34,7 +34,7 @@ enum ring_status {
+ };
+
+ struct brcmf_flowring_ring {
+- u8 hash_id;
++ u16 hash_id;
+ bool blocked;
+ enum ring_status status;
+ struct sk_buff_head skblist;
diff --git a/package/kernel/mac80211/patches/370-0007-brcmfmac-Make-p2pon-module-param-always-available.patch b/package/kernel/mac80211/patches/370-0007-brcmfmac-Make-p2pon-module-param-always-available.patch
new file mode 100644
index 0000000000..c143c3ba75
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0007-brcmfmac-Make-p2pon-module-param-always-available.patch
@@ -0,0 +1,29 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:10 +0200
+Subject: [PATCH] brcmfmac: Make p2pon module param always available.
+
+p2pon module param is currently under define BRCMDBG. Though it is
+a needed option for older versions of the wpa_supplicant which do not
+support the P2P_DEVICE interface.
+
+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/core.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
+@@ -62,10 +62,8 @@ MODULE_PARM_DESC(debug, "level of debug
+
+ /* P2P0 enable */
+ static int brcmf_p2p_enable;
+-#ifdef CPTCFG_BRCMDBG
+ module_param_named(p2pon, brcmf_p2p_enable, int, 0);
+-MODULE_PARM_DESC(p2pon, "enable p2p management functionality");
+-#endif
++MODULE_PARM_DESC(p2pon, "enable legacy p2p management functionality");
+
+ char *brcmf_ifname(struct brcmf_pub *drvr, int ifidx)
+ {
diff --git a/package/kernel/mac80211/patches/370-0008-brcmfmac-Workaround-in-change-vif-for-wpa_supplicant.patch b/package/kernel/mac80211/patches/370-0008-brcmfmac-Workaround-in-change-vif-for-wpa_supplicant.patch
new file mode 100644
index 0000000000..15ac2d900a
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0008-brcmfmac-Workaround-in-change-vif-for-wpa_supplicant.patch
@@ -0,0 +1,76 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:11 +0200
+Subject: [PATCH] brcmfmac: Workaround in change vif for wpa_supplicant
+ support.
+
+Different wpa_supplicants have different behavior and expectations
+regarding the change_virtual_intf behavior. This patch implements
+a workaround for the different versions and possible brcmfmac
+configuration.
+
+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/cfg80211.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+@@ -776,6 +776,37 @@ brcmf_cfg80211_change_iface(struct wiphy
+ s32 err = 0;
+
+ brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type);
++
++ /* WAR: There are a number of p2p interface related problems which
++ * need to be handled initially (before doing the validate).
++ * wpa_supplicant tends to do iface changes on p2p device/client/go
++ * which are not always possible/allowed. However we need to return
++ * OK otherwise the wpa_supplicant wont start. The situation differs
++ * on configuration and setup (p2pon=1 module param). The first check
++ * is to see if the request is a change to station for p2p iface.
++ */
++ if ((type == NL80211_IFTYPE_STATION) &&
++ ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
++ (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
++ (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
++ brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
++ /* Now depending on whether module param p2pon=1 was used the
++ * response needs to be either 0 or EOPNOTSUPP. The reason is
++ * that if p2pon=1 is used, but a newer supplicant is used then
++ * we should return an error, as this combination wont work.
++ * In other situations 0 is returned and supplicant will start
++ * normally. It will give a trace in cfg80211, but it is the
++ * only way to get it working. Unfortunately this will result
++ * in situation where we wont support new supplicant in
++ * combination with module param p2pon=1, but that is the way
++ * it is. If the user tries this then unloading of driver might
++ * fail/lock.
++ */
++ if (cfg->p2p.p2pdev_dynamically)
++ return -EOPNOTSUPP;
++ else
++ return 0;
++ }
+ err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
+ if (err) {
+ brcmf_err("iface validation failed: err=%d\n", err);
+@@ -791,18 +822,6 @@ brcmf_cfg80211_change_iface(struct wiphy
+ infra = 0;
+ break;
+ case NL80211_IFTYPE_STATION:
+- /* Ignore change for p2p IF. Unclear why supplicant does this */
+- if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
+- (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
+- brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
+- /* WAR: It is unexpected to get a change of VIF for P2P
+- * IF, but it happens. The request can not be handled
+- * but returning EPERM causes a crash. Returning 0
+- * without setting ieee80211_ptr->iftype causes trace
+- * (WARN_ON) but it works with wpa_supplicant
+- */
+- return 0;
+- }
+ infra = 1;
+ break;
+ case NL80211_IFTYPE_AP:
diff --git a/package/kernel/mac80211/patches/370-0009-brcmfmac-Deleting-of-p2p-device-is-leaking-memory.patch b/package/kernel/mac80211/patches/370-0009-brcmfmac-Deleting-of-p2p-device-is-leaking-memory.patch
new file mode 100644
index 0000000000..1988b5cb6b
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0009-brcmfmac-Deleting-of-p2p-device-is-leaking-memory.patch
@@ -0,0 +1,124 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:12 +0200
+Subject: [PATCH] brcmfmac: Deleting of p2p device is leaking memory.
+
+When a p2p device gets deleted, the memory for the vif is not being
+released. This is solved by reorganizing the cleanup path and
+properly freeing the memory.
+
+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/core.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
+@@ -887,6 +887,16 @@ static void brcmf_del_if(struct brcmf_pu
+ cancel_work_sync(&ifp->multicast_work);
+ }
+ brcmf_net_detach(ifp->ndev);
++ } else {
++ /* Only p2p device interfaces which get dynamically created
++ * end up here. In this case the p2p module should be informed
++ * about the removal of the interface within the firmware. If
++ * not then p2p commands towards the firmware will cause some
++ * serious troublesome side effects. The p2p module will clean
++ * up the ifp if needed.
++ */
++ brcmf_p2p_ifp_removed(ifp);
++ kfree(ifp);
+ }
+ }
+
+@@ -894,7 +904,8 @@ void brcmf_remove_interface(struct brcmf
+ {
+ if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bssidx] != ifp))
+ return;
+-
++ brcmf_dbg(TRACE, "Enter, bssidx=%d, ifidx=%d\n", ifp->bssidx,
++ ifp->ifidx);
+ brcmf_fws_del_interface(ifp);
+ brcmf_del_if(ifp->drvr, ifp->bssidx);
+ }
+--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+@@ -2131,20 +2131,6 @@ fail:
+ }
+
+ /**
+- * brcmf_p2p_delete_p2pdev() - delete P2P_DEVICE virtual interface.
+- *
+- * @vif: virtual interface object to delete.
+- */
+-static void brcmf_p2p_delete_p2pdev(struct brcmf_p2p_info *p2p,
+- struct brcmf_cfg80211_vif *vif)
+-{
+- cfg80211_unregister_wdev(&vif->wdev);
+- p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
+- brcmf_remove_interface(vif->ifp);
+- brcmf_free_vif(vif);
+-}
+-
+-/**
+ * brcmf_p2p_add_vif() - create a new P2P virtual interface.
+ *
+ * @wiphy: wiphy device of new interface.
+@@ -2264,9 +2250,11 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
+ break;
+
+ case NL80211_IFTYPE_P2P_DEVICE:
++ if (!p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
++ return 0;
+ brcmf_p2p_cancel_remain_on_channel(vif->ifp);
+ brcmf_p2p_deinit_discovery(p2p);
+- brcmf_p2p_delete_p2pdev(p2p, vif);
++ brcmf_remove_interface(vif->ifp);
+ return 0;
+ default:
+ return -ENOTSUPP;
+@@ -2298,6 +2286,21 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
+ return err;
+ }
+
++void brcmf_p2p_ifp_removed(struct brcmf_if *ifp)
++{
++ struct brcmf_cfg80211_info *cfg;
++ struct brcmf_cfg80211_vif *vif;
++
++ brcmf_dbg(INFO, "P2P: device interface removed\n");
++ vif = ifp->vif;
++ cfg = wdev_to_cfg(&vif->wdev);
++ cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
++ rtnl_lock();
++ cfg80211_unregister_wdev(&vif->wdev);
++ rtnl_unlock();
++ brcmf_free_vif(vif);
++}
++
+ int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev)
+ {
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+@@ -2422,10 +2425,7 @@ void brcmf_p2p_detach(struct brcmf_p2p_i
+ if (vif != NULL) {
+ brcmf_p2p_cancel_remain_on_channel(vif->ifp);
+ brcmf_p2p_deinit_discovery(p2p);
+- /* remove discovery interface */
+- rtnl_lock();
+- brcmf_p2p_delete_p2pdev(p2p, vif);
+- rtnl_unlock();
++ brcmf_remove_interface(vif->ifp);
+ }
+ /* just set it all to zero */
+ memset(p2p, 0, sizeof(*p2p));
+--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.h
+@@ -156,6 +156,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s
+ int brcmf_p2p_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev);
+ int brcmf_p2p_ifchange(struct brcmf_cfg80211_info *cfg,
+ enum brcmf_fil_p2p_if_types if_type);
++void brcmf_p2p_ifp_removed(struct brcmf_if *ifp);
+ int brcmf_p2p_start_device(struct wiphy *wiphy, struct wireless_dev *wdev);
+ void brcmf_p2p_stop_device(struct wiphy *wiphy, struct wireless_dev *wdev);
+ int brcmf_p2p_scan_prep(struct wiphy *wiphy,
diff --git a/package/kernel/mac80211/patches/370-0010-brcmfmac-Only-handle-p2p_stop_device-if-vif-is-valid.patch b/package/kernel/mac80211/patches/370-0010-brcmfmac-Only-handle-p2p_stop_device-if-vif-is-valid.patch
new file mode 100644
index 0000000000..5225c9e5bc
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0010-brcmfmac-Only-handle-p2p_stop_device-if-vif-is-valid.patch
@@ -0,0 +1,40 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:13 +0200
+Subject: [PATCH] brcmfmac: Only handle p2p_stop_device if vif is valid
+
+In some situations it is possible that vif has been removed while
+cfg80211 invokes the p2p_stop_device handler. This will result in
+crash.
+
+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/p2p.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+@@ -2324,11 +2324,17 @@ void brcmf_p2p_stop_device(struct wiphy
+ struct brcmf_cfg80211_vif *vif;
+
+ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
+- mutex_lock(&cfg->usr_sync);
+- (void)brcmf_p2p_deinit_discovery(p2p);
+- brcmf_abort_scanning(cfg);
+- clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state);
+- mutex_unlock(&cfg->usr_sync);
++ /* This call can be result of the unregister_wdev call. In that case
++ * we dont want to do anything anymore. Just return. The config vif
++ * will have been cleared at this point.
++ */
++ if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == vif) {
++ mutex_lock(&cfg->usr_sync);
++ (void)brcmf_p2p_deinit_discovery(p2p);
++ brcmf_abort_scanning(cfg);
++ clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state);
++ mutex_unlock(&cfg->usr_sync);
++ }
+ }
+
+ /**
diff --git a/package/kernel/mac80211/patches/370-0011-brcmfmac-Fix-p2p-bug-for-older-firmwares.patch b/package/kernel/mac80211/patches/370-0011-brcmfmac-Fix-p2p-bug-for-older-firmwares.patch
new file mode 100644
index 0000000000..e2f24e866b
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0011-brcmfmac-Fix-p2p-bug-for-older-firmwares.patch
@@ -0,0 +1,35 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:14 +0200
+Subject: [PATCH] brcmfmac: Fix p2p bug for older firmwares.
+
+Some devices with older firmwares are reporting new p2p device
+interface with the wrong type. Accept this type to get p2p
+working for these devices.
+
+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/fweh.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+@@ -186,11 +186,13 @@ static void brcmf_fweh_handle_if_event(s
+ ifevent->action, ifevent->ifidx, ifevent->bssidx,
+ ifevent->flags, ifevent->role);
+
+- /* The P2P Device interface event must not be ignored
+- * contrary to what firmware tells us.
++ /* The P2P Device interface event must not be ignored contrary to what
++ * firmware tells us. Older firmware uses p2p noif, with sta role.
++ * This should be accepted.
+ */
+- is_p2pdev = (ifevent->flags & BRCMF_E_IF_FLAG_NOIF) &&
+- ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT;
++ is_p2pdev = ((ifevent->flags & BRCMF_E_IF_FLAG_NOIF) &&
++ (ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT ||
++ ifevent->role == BRCMF_E_IF_ROLE_STA));
+ if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) {
+ brcmf_dbg(EVENT, "event can be ignored\n");
+ return;
diff --git a/package/kernel/mac80211/patches/370-0012-brcmfmac-Add-module-parameter-to-disable-features.patch b/package/kernel/mac80211/patches/370-0012-brcmfmac-Add-module-parameter-to-disable-features.patch
new file mode 100644
index 0000000000..52c787ff61
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0012-brcmfmac-Add-module-parameter-to-disable-features.patch
@@ -0,0 +1,54 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:15 +0200
+Subject: [PATCH] brcmfmac: Add module parameter to disable features.
+
+For debugging purpose it is very handy to be able to disable
+features. It has happened a few times that new features turned
+out not always being properly detected for all devices/firmwares.
+Making it possible to disable the feature with a module parameter
+will make testing/debugging easier.
+
+Reviewed-by: Arend Van Spriel <arend@broadcom.com>
+Reviewed-by: Franky (Zhenhui) Lin <frankyl@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/feature.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
+@@ -15,6 +15,7 @@
+ */
+
+ #include <linux/netdevice.h>
++#include <linux/module.h>
+
+ #include <brcm_hw_ids.h>
+ #include "core.h"
+@@ -23,6 +24,12 @@
+ #include "fwil.h"
+ #include "feature.h"
+
++
++/* Module param feature_disable (global for all devices) */
++static int brcmf_feature_disable;
++module_param_named(feature_disable, brcmf_feature_disable, int, 0);
++MODULE_PARM_DESC(feature_disable, "Disable features");
++
+ /*
+ * expand feature list to array of feature strings.
+ */
+@@ -131,6 +138,12 @@ void brcmf_feat_attach(struct brcmf_pub
+ brcmf_feat_iovar_int_set(ifp, BRCMF_FEAT_MBSS, "mbss", 0);
+ brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_P2P, "p2p");
+
++ if (brcmf_feature_disable) {
++ brcmf_dbg(INFO, "Features: 0x%02x, disable: 0x%02x\n",
++ ifp->drvr->feat_flags, brcmf_feature_disable);
++ ifp->drvr->feat_flags &= ~brcmf_feature_disable;
++ }
++
+ /* set chip related quirks */
+ switch (drvr->bus_if->chip) {
+ case BRCM_CC_43236_CHIP_ID:
diff --git a/package/kernel/mac80211/patches/370-0013-brcmfmac-Fix-race-condition-bug-when-deleting-p2p-in.patch b/package/kernel/mac80211/patches/370-0013-brcmfmac-Fix-race-condition-bug-when-deleting-p2p-in.patch
new file mode 100644
index 0000000000..58a638aa08
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0013-brcmfmac-Fix-race-condition-bug-when-deleting-p2p-in.patch
@@ -0,0 +1,80 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:16 +0200
+Subject: [PATCH] brcmfmac: Fix race condition bug when deleting p2p interface.
+
+When p2p device interface gets deleted by deinitialising discovery
+it will result in an event which removes the interface, but that is
+also done by delete p2p interface code. This results in race
+condition which sometimes results in lockup/crash. With this patch
+the delete device interface will wait for the event (with timeout)
+removing the possible race condition. Also on the stop device call
+from cfg80211 the deinitialisation of the discovery device should
+be avoided as it can result in a similar situation.
+
+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/p2p.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+@@ -2238,6 +2238,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
+ brcmf_dbg(TRACE, "delete P2P vif\n");
+ vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
+
++ brcmf_cfg80211_arm_vif_event(cfg, vif);
+ switch (vif->wdev.iftype) {
+ case NL80211_IFTYPE_P2P_CLIENT:
+ if (test_bit(BRCMF_VIF_STATUS_DISCONNECTING, &vif->sme_state))
+@@ -2254,8 +2255,6 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
+ return 0;
+ brcmf_p2p_cancel_remain_on_channel(vif->ifp);
+ brcmf_p2p_deinit_discovery(p2p);
+- brcmf_remove_interface(vif->ifp);
+- return 0;
+ default:
+ return -ENOTSUPP;
+ }
+@@ -2267,10 +2266,11 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
+ wait_for_completion_timeout(&cfg->vif_disabled,
+ msecs_to_jiffies(500));
+
+- brcmf_vif_clear_mgmt_ies(vif);
+-
+- brcmf_cfg80211_arm_vif_event(cfg, vif);
+- err = brcmf_p2p_release_p2p_if(vif);
++ err = 0;
++ if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE) {
++ brcmf_vif_clear_mgmt_ies(vif);
++ err = brcmf_p2p_release_p2p_if(vif);
++ }
+ if (!err) {
+ /* wait for firmware event */
+ err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_DEL,
+@@ -2280,8 +2280,12 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
+ else
+ err = 0;
+ }
++ if (err)
++ brcmf_remove_interface(vif->ifp);
++
+ brcmf_cfg80211_arm_vif_event(cfg, NULL);
+- p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
++ if (vif->wdev.iftype != NL80211_IFTYPE_P2P_DEVICE)
++ p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif = NULL;
+
+ return err;
+ }
+@@ -2330,7 +2334,9 @@ void brcmf_p2p_stop_device(struct wiphy
+ */
+ if (p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif == vif) {
+ mutex_lock(&cfg->usr_sync);
+- (void)brcmf_p2p_deinit_discovery(p2p);
++ /* Set the discovery state to SCAN */
++ (void)brcmf_p2p_set_discover_state(vif->ifp,
++ WL_P2P_DISC_ST_SCAN, 0, 0);
+ brcmf_abort_scanning(cfg);
+ clear_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state);
+ mutex_unlock(&cfg->usr_sync);
diff --git a/package/kernel/mac80211/patches/370-0014-brcmfmac-Add-support-for-the-BCM4365-and-BCM4366-PCI.patch b/package/kernel/mac80211/patches/370-0014-brcmfmac-Add-support-for-the-BCM4365-and-BCM4366-PCI.patch
new file mode 100644
index 0000000000..d0bbf2a878
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0014-brcmfmac-Add-support-for-the-BCM4365-and-BCM4366-PCI.patch
@@ -0,0 +1,277 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:17 +0200
+Subject: [PATCH] brcmfmac: Add support for the BCM4365 and BCM4366 PCIE
+ devices.
+
+This patch adds support for the BCM4365 and BCM4366 11ac Wave2
+PCIE devices.
+
+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/chip.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+@@ -208,6 +208,7 @@ struct sbsocramregs {
+ };
+
+ #define SOCRAMREGOFFS(_f) offsetof(struct sbsocramregs, _f)
++#define SYSMEMREGOFFS(_f) offsetof(struct sbsocramregs, _f)
+
+ #define ARMCR4_CAP (0x04)
+ #define ARMCR4_BANKIDX (0x40)
+@@ -516,6 +517,9 @@ static int brcmf_chip_cores_check(struct
+ case BCMA_CORE_ARM_CR4:
+ cpu_found = true;
+ break;
++ case BCMA_CORE_ARM_CA7:
++ cpu_found = true;
++ break;
+ default:
+ break;
+ }
+@@ -614,6 +618,29 @@ static void brcmf_chip_socram_ramsize(st
+ }
+ }
+
++/** Return the SYS MEM size */
++static u32 brcmf_chip_sysmem_ramsize(struct brcmf_core_priv *sysmem)
++{
++ u32 memsize = 0;
++ u32 coreinfo;
++ u32 idx;
++ u32 nb;
++ u32 banksize;
++
++ if (!brcmf_chip_iscoreup(&sysmem->pub))
++ brcmf_chip_resetcore(&sysmem->pub, 0, 0, 0);
++
++ coreinfo = brcmf_chip_core_read32(sysmem, SYSMEMREGOFFS(coreinfo));
++ nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
++
++ for (idx = 0; idx < nb; idx++) {
++ brcmf_chip_socram_banksize(sysmem, idx, &banksize);
++ memsize += banksize;
++ }
++
++ return memsize;
++}
++
+ /** Return the TCM-RAM size of the ARMCR4 core. */
+ static u32 brcmf_chip_tcm_ramsize(struct brcmf_core_priv *cr4)
+ {
+@@ -656,6 +683,9 @@ static u32 brcmf_chip_tcm_rambase(struct
+ case BRCM_CC_4358_CHIP_ID:
+ case BRCM_CC_43602_CHIP_ID:
+ return 0x180000;
++ case BRCM_CC_4365_CHIP_ID:
++ case BRCM_CC_4366_CHIP_ID:
++ return 0x200000;
+ default:
+ brcmf_err("unknown chip: %s\n", ci->pub.name);
+ break;
+@@ -678,10 +708,28 @@ static int brcmf_chip_get_raminfo(struct
+ 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);
++ mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_SYS_MEM);
++ if (mem) {
++ mem_core = container_of(mem, struct brcmf_core_priv,
++ pub);
++ ci->pub.ramsize = brcmf_chip_sysmem_ramsize(mem_core);
++ ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
++ if (!ci->pub.rambase) {
++ brcmf_err("RAM base not provided with ARM CA7 core\n");
++ return -EINVAL;
++ }
++ } else {
++ mem = brcmf_chip_get_core(&ci->pub,
++ BCMA_CORE_INTERNAL_MEM);
++ if (!mem) {
++ brcmf_err("No memory cores found\n");
++ return -ENOMEM;
++ }
++ 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,
+@@ -924,7 +972,7 @@ static int brcmf_chip_recognition(struct
+ static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
+ {
+ struct brcmf_core *core;
+- struct brcmf_core_priv *cr4;
++ struct brcmf_core_priv *cpu;
+ u32 val;
+
+
+@@ -937,10 +985,11 @@ static void brcmf_chip_disable_arm(struc
+ brcmf_chip_coredisable(core, 0, 0);
+ break;
+ case BCMA_CORE_ARM_CR4:
+- cr4 = container_of(core, struct brcmf_core_priv, pub);
++ case BCMA_CORE_ARM_CA7:
++ cpu = container_of(core, struct brcmf_core_priv, pub);
+
+ /* clear all IOCTL bits except HALT bit */
+- val = chip->ops->read32(chip->ctx, cr4->wrapbase + BCMA_IOCTL);
++ val = chip->ops->read32(chip->ctx, cpu->wrapbase + BCMA_IOCTL);
+ val &= ARMCR4_BCMA_IOCTL_CPUHALT;
+ brcmf_chip_resetcore(core, val, ARMCR4_BCMA_IOCTL_CPUHALT,
+ ARMCR4_BCMA_IOCTL_CPUHALT);
+@@ -1162,6 +1211,33 @@ static bool brcmf_chip_cr4_set_active(st
+ return true;
+ }
+
++static inline void
++brcmf_chip_ca7_set_passive(struct brcmf_chip_priv *chip)
++{
++ struct brcmf_core *core;
++
++ brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CA7);
++
++ core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
++ brcmf_chip_resetcore(core, D11_BCMA_IOCTL_PHYRESET |
++ D11_BCMA_IOCTL_PHYCLOCKEN,
++ D11_BCMA_IOCTL_PHYCLOCKEN,
++ D11_BCMA_IOCTL_PHYCLOCKEN);
++}
++
++static bool brcmf_chip_ca7_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
++{
++ struct brcmf_core *core;
++
++ chip->ops->activate(chip->ctx, &chip->pub, rstvec);
++
++ /* restore ARM */
++ core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CA7);
++ brcmf_chip_resetcore(core, ARMCR4_BCMA_IOCTL_CPUHALT, 0, 0);
++
++ return true;
++}
++
+ void brcmf_chip_set_passive(struct brcmf_chip *pub)
+ {
+ struct brcmf_chip_priv *chip;
+@@ -1175,8 +1251,16 @@ void brcmf_chip_set_passive(struct brcmf
+ brcmf_chip_cr4_set_passive(chip);
+ return;
+ }
+-
+- brcmf_chip_cm3_set_passive(chip);
++ arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CA7);
++ if (arm) {
++ brcmf_chip_ca7_set_passive(chip);
++ return;
++ }
++ arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CM3);
++ if (arm) {
++ brcmf_chip_cm3_set_passive(chip);
++ return;
++ }
+ }
+
+ bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec)
+@@ -1190,8 +1274,14 @@ bool brcmf_chip_set_active(struct brcmf_
+ arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
+ if (arm)
+ return brcmf_chip_cr4_set_active(chip, rstvec);
++ arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CA7);
++ if (arm)
++ return brcmf_chip_ca7_set_active(chip, rstvec);
++ arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CM3);
++ if (arm)
++ return brcmf_chip_cm3_set_active(chip);
+
+- return brcmf_chip_cm3_set_active(chip);
++ return false;
+ }
+
+ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
+--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+@@ -55,6 +55,10 @@ enum brcmf_pcie_state {
+ #define BRCMF_PCIE_43570_NVRAM_NAME "brcm/brcmfmac43570-pcie.txt"
+ #define BRCMF_PCIE_4358_FW_NAME "brcm/brcmfmac4358-pcie.bin"
+ #define BRCMF_PCIE_4358_NVRAM_NAME "brcm/brcmfmac4358-pcie.txt"
++#define BRCMF_PCIE_4365_FW_NAME "brcm/brcmfmac4365b-pcie.bin"
++#define BRCMF_PCIE_4365_NVRAM_NAME "brcm/brcmfmac4365b-pcie.txt"
++#define BRCMF_PCIE_4366_FW_NAME "brcm/brcmfmac4366b-pcie.bin"
++#define BRCMF_PCIE_4366_NVRAM_NAME "brcm/brcmfmac4366b-pcie.txt"
+
+ #define BRCMF_PCIE_FW_UP_TIMEOUT 2000 /* msec */
+
+@@ -204,6 +208,10 @@ MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME
+ MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_4358_FW_NAME);
+ MODULE_FIRMWARE(BRCMF_PCIE_4358_NVRAM_NAME);
++MODULE_FIRMWARE(BRCMF_PCIE_4365_FW_NAME);
++MODULE_FIRMWARE(BRCMF_PCIE_4365_NVRAM_NAME);
++MODULE_FIRMWARE(BRCMF_PCIE_4366_FW_NAME);
++MODULE_FIRMWARE(BRCMF_PCIE_4366_NVRAM_NAME);
+
+
+ struct brcmf_pcie_console {
+@@ -1440,6 +1448,14 @@ static int brcmf_pcie_get_fwnames(struct
+ fw_name = BRCMF_PCIE_4358_FW_NAME;
+ nvram_name = BRCMF_PCIE_4358_NVRAM_NAME;
+ break;
++ case BRCM_CC_4365_CHIP_ID:
++ fw_name = BRCMF_PCIE_4365_FW_NAME;
++ nvram_name = BRCMF_PCIE_4365_NVRAM_NAME;
++ break;
++ case BRCM_CC_4366_CHIP_ID:
++ fw_name = BRCMF_PCIE_4366_FW_NAME;
++ nvram_name = BRCMF_PCIE_4366_NVRAM_NAME;
++ break;
+ default:
+ brcmf_err("Unsupported chip 0x%04x\n", devinfo->ci->chip);
+ return -ENODEV;
+@@ -1973,6 +1989,12 @@ static struct pci_device_id brcmf_pcie_d
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_2G_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_5G_DEVICE_ID),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_43602_RAW_DEVICE_ID),
++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_DEVICE_ID),
++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_2G_DEVICE_ID),
++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4365_5G_DEVICE_ID),
++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_DEVICE_ID),
++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_2G_DEVICE_ID),
++ BRCMF_PCIE_DEVICE(BRCM_PCIE_4366_5G_DEVICE_ID),
+ { /* end: all zeroes */ }
+ };
+
+--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
++++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+@@ -48,6 +48,8 @@
+ #define BRCM_CC_43570_CHIP_ID 43570
+ #define BRCM_CC_4358_CHIP_ID 0x4358
+ #define BRCM_CC_43602_CHIP_ID 43602
++#define BRCM_CC_4365_CHIP_ID 0x4365
++#define BRCM_CC_4366_CHIP_ID 0x4366
+
+ /* USB Device IDs */
+ #define BRCM_USB_43143_DEVICE_ID 0xbd1e
+@@ -67,6 +69,13 @@
+ #define BRCM_PCIE_43602_2G_DEVICE_ID 0x43bb
+ #define BRCM_PCIE_43602_5G_DEVICE_ID 0x43bc
+ #define BRCM_PCIE_43602_RAW_DEVICE_ID 43602
++#define BRCM_PCIE_4365_DEVICE_ID 0x43ca
++#define BRCM_PCIE_4365_2G_DEVICE_ID 0x43cb
++#define BRCM_PCIE_4365_5G_DEVICE_ID 0x43cc
++#define BRCM_PCIE_4366_DEVICE_ID 0x43c3
++#define BRCM_PCIE_4366_2G_DEVICE_ID 0x43c4
++#define BRCM_PCIE_4366_5G_DEVICE_ID 0x43c5
++
+
+ /* brcmsmac IDs */
+ #define BCM4313_D11N2G_ID 0x4727 /* 4313 802.11n 2.4G device */
diff --git a/package/kernel/mac80211/patches/370-0015-brcmfmac-Fix-TDLS-setup-by-properly-handling-p2p-noi.patch b/package/kernel/mac80211/patches/370-0015-brcmfmac-Fix-TDLS-setup-by-properly-handling-p2p-noi.patch
new file mode 100644
index 0000000000..d33c803ab5
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0015-brcmfmac-Fix-TDLS-setup-by-properly-handling-p2p-noi.patch
@@ -0,0 +1,120 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:18 +0200
+Subject: [PATCH] brcmfmac: Fix TDLS setup by properly handling p2p noif.
+
+There is a workaround needed for p2p device setup which breaks tdls
+functionality. This patch fixes that by properly signalling fweh that
+p2p device setup is ongoing.
+
+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/fweh.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+@@ -188,11 +188,13 @@ static void brcmf_fweh_handle_if_event(s
+
+ /* The P2P Device interface event must not be ignored contrary to what
+ * firmware tells us. Older firmware uses p2p noif, with sta role.
+- * This should be accepted.
++ * This should be accepted when p2pdev_setup is ongoing. TDLS setup will
++ * use the same ifevent and should be ignored.
+ */
+ is_p2pdev = ((ifevent->flags & BRCMF_E_IF_FLAG_NOIF) &&
+ (ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT ||
+- ifevent->role == BRCMF_E_IF_ROLE_STA));
++ ((ifevent->role == BRCMF_E_IF_ROLE_STA) &&
++ (drvr->fweh.p2pdev_setup_ongoing))));
+ if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) {
+ brcmf_dbg(EVENT, "event can be ignored\n");
+ return;
+@@ -316,6 +318,17 @@ event_free:
+ }
+
+ /**
++ * brcmf_fweh_p2pdev_setup() - P2P device setup ongoing (or not).
++ *
++ * @ifp: ifp on which setup is taking place or finished.
++ * @ongoing: p2p device setup in progress (or not).
++ */
++void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing)
++{
++ ifp->drvr->fweh.p2pdev_setup_ongoing = ongoing;
++}
++
++/**
+ * brcmf_fweh_attach() - initialize firmware event handling.
+ *
+ * @drvr: driver information object.
+--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
+@@ -230,12 +230,14 @@ typedef int (*brcmf_fweh_handler_t)(stru
+ /**
+ * struct brcmf_fweh_info - firmware event handling information.
+ *
++ * @p2pdev_setup_ongoing: P2P device creation in progress.
+ * @event_work: event worker.
+ * @evt_q_lock: lock for event queue protection.
+ * @event_q: event queue.
+ * @evt_handler: registered event handlers.
+ */
+ struct brcmf_fweh_info {
++ bool p2pdev_setup_ongoing;
+ struct work_struct event_work;
+ spinlock_t evt_q_lock;
+ struct list_head event_q;
+@@ -255,6 +257,7 @@ void brcmf_fweh_unregister(struct brcmf_
+ int brcmf_fweh_activate_events(struct brcmf_if *ifp);
+ void brcmf_fweh_process_event(struct brcmf_pub *drvr,
+ struct brcmf_event *event_packet);
++void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing);
+
+ static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr,
+ struct sk_buff *skb)
+--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+@@ -2084,11 +2084,13 @@ static struct wireless_dev *brcmf_p2p_cr
+ brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
+
+ brcmf_cfg80211_arm_vif_event(p2p->cfg, p2p_vif);
++ brcmf_fweh_p2pdev_setup(pri_ifp, true);
+
+ /* Initialize P2P Discovery in the firmware */
+ err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
+ if (err < 0) {
+ brcmf_err("set p2p_disc error\n");
++ brcmf_fweh_p2pdev_setup(pri_ifp, false);
+ brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
+ goto fail;
+ }
+@@ -2097,6 +2099,7 @@ static struct wireless_dev *brcmf_p2p_cr
+ err = brcmf_cfg80211_wait_vif_event_timeout(p2p->cfg, BRCMF_E_IF_ADD,
+ msecs_to_jiffies(1500));
+ brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL);
++ brcmf_fweh_p2pdev_setup(pri_ifp, false);
+ if (!err) {
+ brcmf_err("timeout occurred\n");
+ err = -EIO;
+@@ -2393,6 +2396,8 @@ s32 brcmf_p2p_attach(struct brcmf_cfg802
+ memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
+ brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
+
++ brcmf_fweh_p2pdev_setup(pri_ifp, true);
++
+ /* Initialize P2P Discovery in the firmware */
+ err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
+ if (err < 0) {
+@@ -2419,8 +2424,9 @@ s32 brcmf_p2p_attach(struct brcmf_cfg802
+ INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
+ init_completion(&p2p->afx_hdl.act_frm_scan);
+ init_completion(&p2p->wait_next_af);
+- }
+ exit:
++ brcmf_fweh_p2pdev_setup(pri_ifp, false);
++ }
+ return err;
+ }
+
diff --git a/package/kernel/mac80211/patches/370-0016-brcmfmac-Accept-events-when-TDLS-is-used-in-combinat.patch b/package/kernel/mac80211/patches/370-0016-brcmfmac-Accept-events-when-TDLS-is-used-in-combinat.patch
new file mode 100644
index 0000000000..b880078835
--- /dev/null
+++ b/package/kernel/mac80211/patches/370-0016-brcmfmac-Accept-events-when-TDLS-is-used-in-combinat.patch
@@ -0,0 +1,29 @@
+From: Hante Meuleman <meuleman@broadcom.com>
+Date: Fri, 18 Sep 2015 22:08:19 +0200
+Subject: [PATCH] brcmfmac: Accept events when TDLS is used in combination with
+ p2p.
+
+TDLS events are mapped back to primary interface but when p2p is in
+use then this fails because the check was incorrect by checking
+bsscfg number. Which can be different when a p2p device has been
+created.
+
+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/fweh.c
++++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+@@ -300,8 +300,7 @@ static void brcmf_fweh_event_worker(stru
+ goto event_free;
+ }
+
+- if ((event->code == BRCMF_E_TDLS_PEER_EVENT) &&
+- (emsg.bsscfgidx == 1))
++ if (event->code == BRCMF_E_TDLS_PEER_EVENT)
+ ifp = drvr->iflist[0];
+ else
+ ifp = drvr->iflist[emsg.bsscfgidx];
diff --git a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch
index 685a5f90c2..ed37fb6d0e 100644
--- a/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch
+++ b/package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch
@@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
-@@ -1213,6 +1213,7 @@ static int __init brcmfmac_module_init(v
+@@ -1229,6 +1229,7 @@ static int __init brcmfmac_module_init(v
#endif
if (!schedule_work(&brcmf_driver_work))
return -EBUSY;
diff --git a/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
index 1cba2b39e8..32c4a6f9e7 100644
--- a/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
+++ b/package/kernel/mac80211/patches/862-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch
@@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
-@@ -691,9 +691,37 @@ static struct wireless_dev *brcmf_cfg802
+@@ -608,9 +608,37 @@ static struct wireless_dev *brcmf_cfg802
u32 *flags,
struct vif_params *params)
{