--- /dev/null
+From fd3ed33f51c2a586412d35b4f64803f019ab589f Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Fri, 15 Jul 2016 12:39:13 +0200
+Subject: [PATCH] brcmfmac: defer DPC processing during probe
+
+The sdio dpc starts processing when in SDIOD_STATE_DATA. This state was
+entered right after firmware download. This patch moves that transition
+just before enabling sdio interrupt handling thus avoiding watchdog
+expiry which would put the bus to sleep while probing.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -3304,10 +3304,6 @@ static int brcmf_sdio_download_firmware(
+ goto err;
+ }
+
+- /* Allow full data communication using DPC from now on. */
+- brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
+- bcmerror = 0;
+-
+ err:
+ brcmf_sdio_clkctl(bus, CLK_SDONLY, false);
+ sdio_release_host(bus->sdiodev->func[1]);
+@@ -4045,6 +4041,9 @@ static void brcmf_sdio_firmware_callback
+ }
+
+ if (err == 0) {
++ /* Allow full data communication using DPC from now on. */
++ brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
++
+ err = brcmf_sdiod_intr_register(sdiodev);
+ if (err != 0)
+ brcmf_err("intr register failed:%d\n", err);
--- /dev/null
+From 3bdae810721b33061d2e541bd78a70f86ca42af3 Mon Sep 17 00:00:00 2001
+From: Florian Fainelli <f.fainelli@gmail.com>
+Date: Mon, 18 Jul 2016 16:24:34 -0700
+Subject: [PATCH] brcmfmac: Fix glob_skb leak in brcmf_sdiod_recv_chain
+
+In case brcmf_sdiod_recv_chain() cannot complete a succeful call to
+brcmf_sdiod_buffrw, we would be leaking glom_skb and not free it as we
+should, fix this.
+
+Reported-by: coverity (CID 1164856)
+Fixes: a413e39a38573 ("brcmfmac: fix brcmf_sdcard_recv_chain() for host without sg support")
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -722,8 +722,10 @@ int brcmf_sdiod_recv_chain(struct brcmf_
+ return -ENOMEM;
+ err = brcmf_sdiod_buffrw(sdiodev, SDIO_FUNC_2, false, addr,
+ glom_skb);
+- if (err)
++ if (err) {
++ brcmu_pkt_buf_free_skb(glom_skb);
+ goto done;
++ }
+
+ skb_queue_walk(pktq, skb) {
+ memcpy(skb->data, glom_skb->data, skb->len);
--- /dev/null
+From 938f89e50a41c2d56710805fb019ad7618cef84b Mon Sep 17 00:00:00 2001
+From: Wolfram Sang <wsa-dev@sang-engineering.com>
+Date: Thu, 11 Aug 2016 23:05:31 +0200
+Subject: [PATCH] net: wireless: broadcom: brcm80211: brcmfmac: usb: don't
+ print error when allocating urb fails
+
+kmalloc will print enough information in case of failure.
+
+Signed-off-by: Wolfram Sang <wsa-dev@sang-engineering.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 8 ++------
+ 1 file changed, 2 insertions(+), 6 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+@@ -1099,15 +1099,11 @@ struct brcmf_usbdev *brcmf_usb_attach(st
+ devinfo->tx_freecount = ntxq;
+
+ devinfo->ctl_urb = usb_alloc_urb(0, GFP_ATOMIC);
+- if (!devinfo->ctl_urb) {
+- brcmf_err("usb_alloc_urb (ctl) failed\n");
++ if (!devinfo->ctl_urb)
+ goto error;
+- }
+ devinfo->bulk_urb = usb_alloc_urb(0, GFP_ATOMIC);
+- if (!devinfo->bulk_urb) {
+- brcmf_err("usb_alloc_urb (bulk) failed\n");
++ if (!devinfo->bulk_urb)
+ goto error;
+- }
+
+ return &devinfo->bus_pub;
+
--- /dev/null
+From 15dacf880e49ce3ecee05eb1a0c6b8e363dbacdc Mon Sep 17 00:00:00 2001
+From: "mhiramat@kernel.org" <mhiramat@kernel.org>
+Date: Mon, 15 Aug 2016 18:40:57 +0900
+Subject: [PATCH] brcmfmac: Check rtnl_lock is locked when removing interface
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Check rtnl_lock is locked in brcmf_p2p_ifp_removed() by passing
+rtnl_locked flag. Actually the caller brcmf_del_if() checks whether
+the rtnl_lock is locked, but doesn't pass it to brcmf_p2p_ifp_removed().
+
+Without this fix, wpa_supplicant goes softlockup with rtnl_lock
+holding (this means all other process using netlink are locked up too)
+
+e.g.
+[ 4495.876627] INFO: task wpa_supplicant:7307 blocked for more than 10 seconds.
+[ 4495.876632] Tainted: G W 4.8.0-rc1+ #8
+[ 4495.876635] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
+[ 4495.876638] wpa_supplicant D ffff974c647b39a0 0 7307 1 0x00000000
+[ 4495.876644] ffff974c647b39a0 0000000000000000 ffff974c00000000 ffff974c7dc59c58
+[ 4495.876651] ffff974c6b7417c0 ffff974c645017c0 ffff974c647b4000 ffffffff86f16c08
+[ 4495.876657] ffff974c645017c0 0000000000000246 00000000ffffffff ffff974c647b39b8
+[ 4495.876664] Call Trace:
+[ 4495.876671] [<ffffffff868aeccc>] schedule+0x3c/0x90
+[ 4495.876676] [<ffffffff868af065>] schedule_preempt_disabled+0x15/0x20
+[ 4495.876682] [<ffffffff868b0996>] mutex_lock_nested+0x176/0x3b0
+[ 4495.876686] [<ffffffff867a2067>] ? rtnl_lock+0x17/0x20
+[ 4495.876690] [<ffffffff867a2067>] rtnl_lock+0x17/0x20
+[ 4495.876720] [<ffffffffc0ae9a5d>] brcmf_p2p_ifp_removed+0x4d/0x70 [brcmfmac]
+[ 4495.876741] [<ffffffffc0aebde6>] brcmf_remove_interface+0x196/0x1b0 [brcmfmac]
+[ 4495.876760] [<ffffffffc0ae9901>] brcmf_p2p_del_vif+0x111/0x220 [brcmfmac]
+[ 4495.876777] [<ffffffffc0adefab>] brcmf_cfg80211_del_iface+0x21b/0x270 [brcmfmac]
+[ 4495.876820] [<ffffffffc097b39e>] nl80211_del_interface+0xfe/0x3a0 [cfg80211]
+[ 4495.876825] [<ffffffff867ca335>] genl_family_rcv_msg+0x1b5/0x370
+[ 4495.876832] [<ffffffff860e5d8d>] ? trace_hardirqs_on+0xd/0x10
+[ 4495.876836] [<ffffffff867ca56d>] genl_rcv_msg+0x7d/0xb0
+[ 4495.876839] [<ffffffff867ca4f0>] ? genl_family_rcv_msg+0x370/0x370
+[ 4495.876846] [<ffffffff867c9a47>] netlink_rcv_skb+0x97/0xb0
+[ 4495.876849] [<ffffffff867ca168>] genl_rcv+0x28/0x40
+[ 4495.876854] [<ffffffff867c93c3>] netlink_unicast+0x1d3/0x2f0
+[ 4495.876860] [<ffffffff867c933b>] ? netlink_unicast+0x14b/0x2f0
+[ 4495.876866] [<ffffffff867c97cb>] netlink_sendmsg+0x2eb/0x3a0
+[ 4495.876870] [<ffffffff8676dad8>] sock_sendmsg+0x38/0x50
+[ 4495.876874] [<ffffffff8676e4df>] ___sys_sendmsg+0x27f/0x290
+[ 4495.876882] [<ffffffff8628b935>] ? mntput_no_expire+0x5/0x3f0
+[ 4495.876888] [<ffffffff8628b9be>] ? mntput_no_expire+0x8e/0x3f0
+[ 4495.876894] [<ffffffff8628b935>] ? mntput_no_expire+0x5/0x3f0
+[ 4495.876899] [<ffffffff8628bd44>] ? mntput+0x24/0x40
+[ 4495.876904] [<ffffffff86267830>] ? __fput+0x190/0x200
+[ 4495.876909] [<ffffffff8676f125>] __sys_sendmsg+0x45/0x80
+[ 4495.876914] [<ffffffff8676f172>] SyS_sendmsg+0x12/0x20
+[ 4495.876918] [<ffffffff868b5680>] entry_SYSCALL_64_fastpath+0x23/0xc1
+[ 4495.876924] [<ffffffff860e2b8f>] ? trace_hardirqs_off_caller+0x1f/0xc0
+
+Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
+Acked-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 2 +-
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 8 +++++---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h | 2 +-
+ 3 files changed, 7 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -743,7 +743,7 @@ static void brcmf_del_if(struct brcmf_pu
+ * serious troublesome side effects. The p2p module will clean
+ * up the ifp if needed.
+ */
+- brcmf_p2p_ifp_removed(ifp);
++ brcmf_p2p_ifp_removed(ifp, rtnl_locked);
+ kfree(ifp);
+ }
+ }
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c
+@@ -2299,7 +2299,7 @@ int brcmf_p2p_del_vif(struct wiphy *wiph
+ return err;
+ }
+
+-void brcmf_p2p_ifp_removed(struct brcmf_if *ifp)
++void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked)
+ {
+ struct brcmf_cfg80211_info *cfg;
+ struct brcmf_cfg80211_vif *vif;
+@@ -2308,9 +2308,11 @@ void brcmf_p2p_ifp_removed(struct brcmf_
+ vif = ifp->vif;
+ cfg = wdev_to_cfg(&vif->wdev);
+ cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
+- rtnl_lock();
++ if (!rtnl_locked)
++ rtnl_lock();
+ cfg80211_unregister_wdev(&vif->wdev);
+- rtnl_unlock();
++ if (!rtnl_locked)
++ rtnl_unlock();
+ brcmf_free_vif(vif);
+ }
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h
+@@ -155,7 +155,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);
++void brcmf_p2p_ifp_removed(struct brcmf_if *ifp, bool rtnl_locked);
+ 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,
--- /dev/null
+From b64abcb7dae6060c67ab0e548da3ef923c49641d Mon Sep 17 00:00:00 2001
+From: "mhiramat@kernel.org" <mhiramat@kernel.org>
+Date: Mon, 15 Aug 2016 18:41:12 +0900
+Subject: [PATCH] brcmfmac: Change vif_event_lock to spinlock
+
+Change vif_event_lock to spinlock from mutex, since this lock is
+used in wait_event_timeout() via vif_event_equals(). This caused
+a warning report as below.
+
+As far as I can see, this lock protects regions where updating
+structure members, not function calls. Also, since those
+regions are not called from interrupt handlers (of course, it
+was a mutex), spin_lock is used instead of spin_lock_irqsave.
+
+[ 186.678550] ------------[ cut here ]------------
+[ 186.678556] WARNING: CPU: 2 PID: 7140 at /home/mhiramat/ksrc/linux/kernel/sched/core.c:7545 __might_sleep+0x7c/0x80
+[ 186.678560] do not call blocking ops when !TASK_RUNNING; state=2 set at [<ffffffff980d9090>] prepare_to_wait_event+0x60/0x100
+[ 186.678560] Modules linked in: brcmfmac xt_CHECKSUM rfcomm ipt_MASQUERADE nf_nat_masquerade_ipv4 xt_addrtype br_netfilter xt_tcpudp ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ip_set nfnetlink ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_raw ip6table_security ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_filter ip6_tables iptable_raw iptable_security iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_filter ip_tables x_tables bnep nls_iso8859_1 i2c_designware_platform i2c_designware_core snd_hda_codec_hdmi snd_hda_codec_realtek dcdbas snd_hda_codec_generic snd_hda_intel snd_hda_codec intel_rapl snd_hda_core x86_pkg_temp_thermal intel_powerclamp coretemp
+[ 186.678594] snd_pcm crct10dif_pclmul crc32_pclmul aesni_intel aes_x86_64 joydev glue_helper snd_hwdep lrw gf128mul uvcvideo ablk_helper snd_seq_midi cryptd snd_seq_midi_event snd_rawmidi videobuf2_vmalloc videobuf2_memops snd_seq input_leds videobuf2_v4l2 cfg80211 videobuf2_core snd_timer videodev serio_raw btusb snd_seq_device media btrtl rtsx_pci_ms snd mei_me memstick hid_multitouch mei soundcore brcmutil idma64 virt_dma intel_lpss_pci processor_thermal_device intel_soc_dts_iosf hci_uart btbcm btqca btintel bluetooth int3403_thermal dell_smo8800 intel_lpss_acpi intel_lpss int3402_thermal int340x_thermal_zone intel_hid mac_hid int3400_thermal shpchp sparse_keymap acpi_pad acpi_thermal_rel acpi_als kfifo_buf industrialio kvm_intel kvm irqbypass parport_pc ppdev lp parport autofs4 btrfs xor raid6_pq
+[ 186.678631] usbhid nouveau ttm i915 rtsx_pci_sdmmc mxm_wmi i2c_algo_bit drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops psmouse drm ahci rtsx_pci nvme nvme_core libahci i2c_hid hid pinctrl_sunrisepoint video wmi pinctrl_intel fjes [last unloaded: brcmfmac]
+[ 186.678646] CPU: 2 PID: 7140 Comm: wpa_supplicant Not tainted 4.8.0-rc1+ #8
+[ 186.678647] Hardware name: Dell Inc. XPS 15 9550/0N7TVV, BIOS 01.02.00 04/07/2016
+[ 186.678648] 0000000000000000 ffff9d8c64b5b900 ffffffff98442f23 ffff9d8c64b5b950
+[ 186.678651] 0000000000000000 ffff9d8c64b5b940 ffffffff9808b22b 00001d790000000d
+[ 186.678653] ffffffff98c75e78 000000000000026c 0000000000000000 ffff9d8c2706d058
+[ 186.678655] Call Trace:
+[ 186.678659] [<ffffffff98442f23>] dump_stack+0x85/0xc2
+[ 186.678666] [<ffffffff9808b22b>] __warn+0xcb/0xf0
+[ 186.678668] [<ffffffff9808b29f>] warn_slowpath_fmt+0x4f/0x60
+[ 186.678671] [<ffffffff980d9090>] ? prepare_to_wait_event+0x60/0x100
+[ 186.678672] [<ffffffff980d9090>] ? prepare_to_wait_event+0x60/0x100
+[ 186.678674] [<ffffffff980b922c>] __might_sleep+0x7c/0x80
+[ 186.678680] [<ffffffff988b0853>] mutex_lock_nested+0x33/0x3b0
+[ 186.678682] [<ffffffff980e5d8d>] ? trace_hardirqs_on+0xd/0x10
+[ 186.678689] [<ffffffffc0c57d2d>] brcmf_cfg80211_wait_vif_event+0xcd/0x130 [brcmfmac]
+[ 186.678691] [<ffffffff980d9190>] ? wake_atomic_t_function+0x60/0x60
+[ 186.678697] [<ffffffffc0c628e9>] brcmf_p2p_del_vif+0xf9/0x220 [brcmfmac]
+[ 186.678702] [<ffffffffc0c57fab>] brcmf_cfg80211_del_iface+0x21b/0x270 [brcmfmac]
+[ 186.678716] [<ffffffffc0b0539e>] nl80211_del_interface+0xfe/0x3a0 [cfg80211]
+[ 186.678718] [<ffffffff987ca335>] genl_family_rcv_msg+0x1b5/0x370
+[ 186.678720] [<ffffffff980e5d8d>] ? trace_hardirqs_on+0xd/0x10
+[ 186.678721] [<ffffffff987ca56d>] genl_rcv_msg+0x7d/0xb0
+[ 186.678722] [<ffffffff987ca4f0>] ? genl_family_rcv_msg+0x370/0x370
+[ 186.678724] [<ffffffff987c9a47>] netlink_rcv_skb+0x97/0xb0
+[ 186.678726] [<ffffffff987ca168>] genl_rcv+0x28/0x40
+[ 186.678727] [<ffffffff987c93c3>] netlink_unicast+0x1d3/0x2f0
+[ 186.678729] [<ffffffff987c933b>] ? netlink_unicast+0x14b/0x2f0
+[ 186.678731] [<ffffffff987c97cb>] netlink_sendmsg+0x2eb/0x3a0
+[ 186.678733] [<ffffffff9876dad8>] sock_sendmsg+0x38/0x50
+[ 186.678734] [<ffffffff9876e4df>] ___sys_sendmsg+0x27f/0x290
+[ 186.678737] [<ffffffff9828b935>] ? mntput_no_expire+0x5/0x3f0
+[ 186.678739] [<ffffffff9828b9be>] ? mntput_no_expire+0x8e/0x3f0
+[ 186.678741] [<ffffffff9828b935>] ? mntput_no_expire+0x5/0x3f0
+[ 186.678743] [<ffffffff9828bd44>] ? mntput+0x24/0x40
+[ 186.678744] [<ffffffff98267830>] ? __fput+0x190/0x200
+[ 186.678746] [<ffffffff9876f125>] __sys_sendmsg+0x45/0x80
+[ 186.678748] [<ffffffff9876f172>] SyS_sendmsg+0x12/0x20
+[ 186.678749] [<ffffffff988b5680>] entry_SYSCALL_64_fastpath+0x23/0xc1
+[ 186.678751] [<ffffffff980e2b8f>] ? trace_hardirqs_off_caller+0x1f/0xc0
+[ 186.678752] ---[ end trace e224d66c5d8408b5 ]---
+
+Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c | 26 +++++++++++-----------
+ .../broadcom/brcm80211/brcmfmac/cfg80211.h | 2 +-
+ 2 files changed, 14 insertions(+), 14 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -5555,7 +5555,7 @@ static s32 brcmf_notify_vif_event(struct
+ ifevent->action, ifevent->flags, ifevent->ifidx,
+ ifevent->bsscfgidx);
+
+- mutex_lock(&event->vif_event_lock);
++ spin_lock(&event->vif_event_lock);
+ event->action = ifevent->action;
+ vif = event->vif;
+
+@@ -5563,7 +5563,7 @@ static s32 brcmf_notify_vif_event(struct
+ case BRCMF_E_IF_ADD:
+ /* waiting process may have timed out */
+ if (!cfg->vif_event.vif) {
+- mutex_unlock(&event->vif_event_lock);
++ spin_unlock(&event->vif_event_lock);
+ return -EBADF;
+ }
+
+@@ -5574,24 +5574,24 @@ static s32 brcmf_notify_vif_event(struct
+ ifp->ndev->ieee80211_ptr = &vif->wdev;
+ SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
+ }
+- mutex_unlock(&event->vif_event_lock);
++ spin_unlock(&event->vif_event_lock);
+ wake_up(&event->vif_wq);
+ return 0;
+
+ case BRCMF_E_IF_DEL:
+- mutex_unlock(&event->vif_event_lock);
++ spin_unlock(&event->vif_event_lock);
+ /* event may not be upon user request */
+ if (brcmf_cfg80211_vif_event_armed(cfg))
+ wake_up(&event->vif_wq);
+ return 0;
+
+ case BRCMF_E_IF_CHANGE:
+- mutex_unlock(&event->vif_event_lock);
++ spin_unlock(&event->vif_event_lock);
+ wake_up(&event->vif_wq);
+ return 0;
+
+ default:
+- mutex_unlock(&event->vif_event_lock);
++ spin_unlock(&event->vif_event_lock);
+ break;
+ }
+ return -EINVAL;
+@@ -5712,7 +5712,7 @@ static void wl_deinit_priv(struct brcmf_
+ static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
+ {
+ init_waitqueue_head(&event->vif_wq);
+- mutex_init(&event->vif_event_lock);
++ spin_lock_init(&event->vif_event_lock);
+ }
+
+ static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
+@@ -6607,9 +6607,9 @@ static inline bool vif_event_equals(stru
+ {
+ u8 evt_action;
+
+- mutex_lock(&event->vif_event_lock);
++ spin_lock(&event->vif_event_lock);
+ evt_action = event->action;
+- mutex_unlock(&event->vif_event_lock);
++ spin_unlock(&event->vif_event_lock);
+ return evt_action == action;
+ }
+
+@@ -6618,10 +6618,10 @@ void brcmf_cfg80211_arm_vif_event(struct
+ {
+ struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
+
+- mutex_lock(&event->vif_event_lock);
++ spin_lock(&event->vif_event_lock);
+ event->vif = vif;
+ event->action = 0;
+- mutex_unlock(&event->vif_event_lock);
++ spin_unlock(&event->vif_event_lock);
+ }
+
+ bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
+@@ -6629,9 +6629,9 @@ bool brcmf_cfg80211_vif_event_armed(stru
+ struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
+ bool armed;
+
+- mutex_lock(&event->vif_event_lock);
++ spin_lock(&event->vif_event_lock);
+ armed = event->vif != NULL;
+- mutex_unlock(&event->vif_event_lock);
++ spin_unlock(&event->vif_event_lock);
+
+ return armed;
+ }
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h
+@@ -227,7 +227,7 @@ struct escan_info {
+ */
+ struct brcmf_cfg80211_vif_event {
+ wait_queue_head_t vif_wq;
+- struct mutex vif_event_lock;
++ spinlock_t vif_event_lock;
+ u8 action;
+ struct brcmf_cfg80211_vif *vif;
+ };
--- /dev/null
+From 8af92af3f2d55db143417a5d401696f4b642009a Mon Sep 17 00:00:00 2001
+From: Baoyou Xie <baoyou.xie@linaro.org>
+Date: Mon, 29 Aug 2016 20:39:35 +0800
+Subject: [PATCH] brcmfmac: add missing header dependencies
+
+We get 1 warning when building kernel with W=1:
+
+drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c:23:6: warning: no previous prototype for '__brcmf_err' [-Wmissing-prototypes]
+
+In fact, this function is declared in brcmfmac/debug.h, so this patch
+adds missing header dependencies.
+
+Signed-off-by: Baoyou Xie <baoyou.xie@linaro.org>
+Acked-by: Arnd Bergmann <arnd@arndb.de>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c
+@@ -19,6 +19,7 @@
+ #ifndef __CHECKER__
+ #define CREATE_TRACE_POINTS
+ #include "tracepoint.h"
++#include "debug.h"
+
+ void __brcmf_err(const char *func, const char *fmt, ...)
+ {
--- /dev/null
+From bccf3ffc8c6d8e0251a15541bb4d12b423c4f729 Mon Sep 17 00:00:00 2001
+From: Ismael Luceno <ismael@iodev.co.uk>
+Date: Mon, 22 Aug 2016 19:40:07 -0300
+Subject: [PATCH] brcmfmac: Add USB ID for Cisco Linksys AE1200
+
+The AE1200 comes with different revisions of the BCM43235 chipset,
+but all have the same USB ID. Only revision 3 can be supported.
+
+Signed-off-by: Ismael Luceno <ismael@iodev.co.uk>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 4 ++++
+ drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 2 ++
+ 2 files changed, 6 insertions(+)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+@@ -1456,11 +1456,15 @@ static int brcmf_usb_reset_resume(struct
+ #define BRCMF_USB_DEVICE(dev_id) \
+ { USB_DEVICE(BRCM_USB_VENDOR_ID_BROADCOM, dev_id) }
+
++#define LINKSYS_USB_DEVICE(dev_id) \
++ { USB_DEVICE(BRCM_USB_VENDOR_ID_LINKSYS, dev_id) }
++
+ static struct usb_device_id brcmf_usb_devid_table[] = {
+ BRCMF_USB_DEVICE(BRCM_USB_43143_DEVICE_ID),
+ BRCMF_USB_DEVICE(BRCM_USB_43236_DEVICE_ID),
+ BRCMF_USB_DEVICE(BRCM_USB_43242_DEVICE_ID),
+ BRCMF_USB_DEVICE(BRCM_USB_43569_DEVICE_ID),
++ LINKSYS_USB_DEVICE(BRCM_USB_43235_LINKSYS_DEVICE_ID),
+ { USB_DEVICE(BRCM_USB_VENDOR_ID_LG, BRCM_USB_43242_LG_DEVICE_ID) },
+ /* special entry for device with firmware loaded and running */
+ BRCMF_USB_DEVICE(BRCM_USB_BCMFW_DEVICE_ID),
+--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
++++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+@@ -22,6 +22,7 @@
+
+ #define BRCM_USB_VENDOR_ID_BROADCOM 0x0a5c
+ #define BRCM_USB_VENDOR_ID_LG 0x043e
++#define BRCM_USB_VENDOR_ID_LINKSYS 0x13b1
+ #define BRCM_PCIE_VENDOR_ID_BROADCOM PCI_VENDOR_ID_BROADCOM
+
+ /* Chipcommon Core Chip IDs */
+@@ -56,6 +57,7 @@
+
+ /* USB Device IDs */
+ #define BRCM_USB_43143_DEVICE_ID 0xbd1e
++#define BRCM_USB_43235_LINKSYS_DEVICE_ID 0x0039
+ #define BRCM_USB_43236_DEVICE_ID 0xbd17
+ #define BRCM_USB_43242_DEVICE_ID 0xbd1f
+ #define BRCM_USB_43242_LG_DEVICE_ID 0x3101
--- /dev/null
+From 7703773ef1d85b40433902a8da20167331597e4a Mon Sep 17 00:00:00 2001
+From: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
+Date: Tue, 23 Aug 2016 11:37:17 +0200
+Subject: [PATCH] brcmfmac: fix pmksa->bssid usage
+
+The struct cfg80211_pmksa defines its bssid field as:
+
+ const u8 *bssid;
+
+contrary to struct brcmf_pmksa, which uses:
+
+ u8 bssid[ETH_ALEN];
+
+Therefore in brcmf_cfg80211_del_pmksa(), &pmksa->bssid takes the address
+of this field (of type u8**), not the one of its content (which would be
+u8*). Remove the & operator to make brcmf_dbg("%pM") and memcmp()
+behave as expected.
+
+This bug have been found using a custom static checker (which checks the
+usage of %p... attributes at build time). It has been introduced in
+commit 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code"),
+which replaced pmksa->bssid by &pmksa->bssid while refactoring the code,
+without modifying struct cfg80211_pmksa definition.
+
+Replace &pmk[i].bssid with pmk[i].bssid too to make the code clearer,
+this change does not affect the semantic.
+
+Fixes: 6c404f34f2bd ("brcmfmac: Cleanup pmksa cache handling code")
+Cc: stable@vger.kernel.org
+Signed-off-by: Nicolas Iooss <nicolas.iooss_linux@m4x.org>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3804,11 +3804,11 @@ brcmf_cfg80211_del_pmksa(struct wiphy *w
+ if (!check_vif_up(ifp->vif))
+ return -EIO;
+
+- brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", &pmksa->bssid);
++ brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
+
+ npmk = le32_to_cpu(cfg->pmk_list.npmk);
+ for (i = 0; i < npmk; i++)
+- if (!memcmp(&pmksa->bssid, &pmk[i].bssid, ETH_ALEN))
++ if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
+ break;
+
+ if ((npmk > 0) && (i < npmk)) {
--- /dev/null
+From ded89912156b1a47d940a0c954c43afbabd0c42c Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 5 Sep 2016 10:45:47 +0100
+Subject: [PATCH] brcmfmac: avoid potential stack overflow in
+ brcmf_cfg80211_start_ap()
+
+User-space can choose to omit NL80211_ATTR_SSID and only provide raw
+IE TLV data. When doing so it can provide SSID IE with length exceeding
+the allowed size. The driver further processes this IE copying it
+into a local variable without checking the length. Hence stack can be
+corrupted and used as exploit.
+
+Cc: stable@vger.kernel.org # v4.7
+Reported-by: Daxing Guo <freener.gdx@gmail.com>
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -4447,7 +4447,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
+ (u8 *)&settings->beacon.head[ie_offset],
+ settings->beacon.head_len - ie_offset,
+ WLAN_EID_SSID);
+- if (!ssid_ie)
++ if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
+ return -EINVAL;
+
+ memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
--- /dev/null
+From 634faf3686900ccdee87b77e2c56df8b2159912b Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 5 Sep 2016 11:42:12 +0100
+Subject: [PATCH] brcmfmac: add support for bcm4339 chip with modalias
+ sdio:c00v02D0d4339
+
+The driver already supports the bcm4339 chipset but only for the variant
+that shares the same modalias as the bcm4335, ie. sdio:c00v02D0d4335.
+It turns out that there are also bcm4339 devices out there that have a
+more distiguishable modalias sdio:c00v02D0d4339.
+
+Reported-by: Steve deRosier <derosier@gmail.com>
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 +
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 ++-
+ include/linux/mmc/sdio_ids.h | 1 +
+ 3 files changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -1097,6 +1097,7 @@ static const struct sdio_device_id brcmf
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
++ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4339),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -3756,7 +3756,8 @@ static u32 brcmf_sdio_buscore_read32(voi
+ u32 val, rev;
+
+ val = brcmf_sdiod_regrl(sdiodev, addr, NULL);
+- if (sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 &&
++ if ((sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4335_4339 ||
++ sdiodev->func[0]->device == SDIO_DEVICE_ID_BROADCOM_4339) &&
+ addr == CORE_CC_REG(SI_ENUM_BASE, chipid)) {
+ rev = (val & CID_REV_MASK) >> CID_REV_SHIFT;
+ if (rev >= 2) {
+--- a/include/linux/mmc/sdio_ids.h
++++ b/include/linux/mmc/sdio_ids.h
+@@ -32,6 +32,7 @@
+ #define SDIO_DEVICE_ID_BROADCOM_43340 0xa94c
+ #define SDIO_DEVICE_ID_BROADCOM_43341 0xa94d
+ #define SDIO_DEVICE_ID_BROADCOM_4335_4339 0x4335
++#define SDIO_DEVICE_ID_BROADCOM_4339 0x4339
+ #define SDIO_DEVICE_ID_BROADCOM_43362 0xa962
+ #define SDIO_DEVICE_ID_BROADCOM_43430 0xa9a6
+ #define SDIO_DEVICE_ID_BROADCOM_4345 0x4345
--- /dev/null
+From 5251b6be8bb5c5675bdf12347c7b83937a5c91e5 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 5 Sep 2016 11:42:13 +0100
+Subject: [PATCH] brcmfmac: sdio: shorten retry loop in
+ brcmf_sdio_kso_control()
+
+In brcmf_sdio_kso_control() there is a retry loop as hardware may take
+time to settle. However, when the call to brcmf_sdiod_regrb() returns
+an error it is due to SDIO access failure and it makes no sense to wait
+for hardware to settle. This patch aborts the loop after a number of
+subsequent access errors.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 11 +++++++++--
+ 1 file changed, 9 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+@@ -313,6 +313,7 @@ struct rte_console {
+
+ #define KSO_WAIT_US 50
+ #define MAX_KSO_ATTEMPTS (PMU_MAX_TRANSITION_DLY/KSO_WAIT_US)
++#define BRCMF_SDIO_MAX_ACCESS_ERRORS 5
+
+ /*
+ * Conversion of 802.1D priority to precedence level
+@@ -675,6 +676,7 @@ brcmf_sdio_kso_control(struct brcmf_sdio
+ {
+ u8 wr_val = 0, rd_val, cmp_val, bmask;
+ int err = 0;
++ int err_cnt = 0;
+ int try_cnt = 0;
+
+ brcmf_dbg(TRACE, "Enter: on=%d\n", on);
+@@ -710,9 +712,14 @@ brcmf_sdio_kso_control(struct brcmf_sdio
+ */
+ rd_val = brcmf_sdiod_regrb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
+ &err);
+- if (((rd_val & bmask) == cmp_val) && !err)
++ if (!err) {
++ if ((rd_val & bmask) == cmp_val)
++ break;
++ err_cnt = 0;
++ }
++ /* bail out upon subsequent access errors */
++ if (err && (err_cnt++ > BRCMF_SDIO_MAX_ACCESS_ERRORS))
+ break;
+-
+ udelay(KSO_WAIT_US);
+ brcmf_sdiod_regwb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR,
+ wr_val, &err);
--- /dev/null
+From b3589dfe02123a0d0ea82076a9f8ef84a46852c0 Mon Sep 17 00:00:00 2001
+From: Hante Meuleman <hante.meuleman@broadcom.com>
+Date: Mon, 19 Sep 2016 12:09:51 +0100
+Subject: [PATCH] brcmfmac: ignore 11d configuration errors
+
+802.11d is not always supported by firmware anymore. Currently the
+AP configuration of 11d will cause an abort if the ioctl set is
+failing. This behavior is not correct and the error should be
+ignored.
+
+Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../broadcom/brcm80211/brcmfmac/cfg80211.c | 27 ++++++++++++----------
+ 1 file changed, 15 insertions(+), 12 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -4422,6 +4422,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
+ u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
+ bool mbss;
+ int is_11d;
++ bool supports_11d;
+
+ brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
+ settings->chandef.chan->hw_value,
+@@ -4434,11 +4435,16 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
+ mbss = ifp->vif->mbss;
+
+ /* store current 11d setting */
+- brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
+- country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
+- settings->beacon.tail_len,
+- WLAN_EID_COUNTRY);
+- is_11d = country_ie ? 1 : 0;
++ if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY,
++ &ifp->vif->is_11d)) {
++ supports_11d = false;
++ } else {
++ country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
++ settings->beacon.tail_len,
++ WLAN_EID_COUNTRY);
++ is_11d = country_ie ? 1 : 0;
++ supports_11d = true;
++ }
+
+ memset(&ssid_le, 0, sizeof(ssid_le));
+ if (settings->ssid == NULL || settings->ssid_len == 0) {
+@@ -4497,7 +4503,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
+
+ /* Parameters shared by all radio interfaces */
+ if (!mbss) {
+- if (is_11d != ifp->vif->is_11d) {
++ if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
+ is_11d);
+ if (err < 0) {
+@@ -4539,7 +4545,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
+ brcmf_err("SET INFRA error %d\n", err);
+ goto exit;
+ }
+- } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
++ } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) {
+ /* Multiple-BSS should use same 11d configuration */
+ err = -EINVAL;
+ goto exit;
+@@ -4673,11 +4679,8 @@ static int brcmf_cfg80211_stop_ap(struct
+ brcmf_err("setting INFRA mode failed %d\n", err);
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
+ brcmf_fil_iovar_int_set(ifp, "mbss", 0);
+- err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
+- ifp->vif->is_11d);
+- if (err < 0)
+- brcmf_err("restoring REGULATORY setting failed %d\n",
+- err);
++ brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
++ ifp->vif->is_11d);
+ /* Bring device back up so it can be used again */
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
+ if (err < 0)
--- /dev/null
+From 704d1c6b56f4ee2ad6a5f012a72a278d17c1a223 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 19 Sep 2016 12:09:52 +0100
+Subject: [PATCH] brcmfmac: rework pointer trickery in
+ brcmf_proto_bcdc_query_dcmd()
+
+The variable info is assigned to point to bcdc->msg[1], which is the
+same as pointing to bcdc->buf. As that is what we want to access
+make it clear by fixing the assignment. This also avoid out-of-bounds
+errors from static analyzers are bcdc->msg[1] is not in the structure
+definition.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c
+@@ -194,7 +194,7 @@ retry:
+ }
+
+ /* Check info buffer */
+- info = (void *)&msg[1];
++ info = (void *)&bcdc->buf[0];
+
+ /* Copy info buffer */
+ if (buf) {
--- /dev/null
+From bc981641360183990de59da17f9f560f9150b801 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 19 Sep 2016 12:09:53 +0100
+Subject: [PATCH] brcmfmac: fix memory leak in brcmf_flowring_add_tdls_peer()
+
+In the error paths in brcmf_flowring_add_tdls_peer() the allocated
+resource should be freed.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
+@@ -495,14 +495,18 @@ void brcmf_flowring_add_tdls_peer(struct
+ } else {
+ search = flow->tdls_entry;
+ if (memcmp(search->mac, peer, ETH_ALEN) == 0)
+- return;
++ goto free_entry;
+ while (search->next) {
+ search = search->next;
+ if (memcmp(search->mac, peer, ETH_ALEN) == 0)
+- return;
++ goto free_entry;
+ }
+ search->next = tdls_entry;
+ }
+
+ flow->tdls_active = true;
++ return;
++
++free_entry:
++ kfree(tdls_entry);
+ }
--- /dev/null
+From 26305d3d7298d1ddf8fd4ce95a382aa90534f0a3 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 19 Sep 2016 12:09:54 +0100
+Subject: [PATCH] brcmfmac: initialize variable in brcmf_sdiod_regrl()
+
+In case of an error the variable returned is uninitialized. The caller
+will probably check the error code before using it, but better assure
+it is set to zero.
+
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+@@ -416,7 +416,7 @@ u8 brcmf_sdiod_regrb(struct brcmf_sdio_d
+
+ u32 brcmf_sdiod_regrl(struct brcmf_sdio_dev *sdiodev, u32 addr, int *ret)
+ {
+- u32 data;
++ u32 data = 0;
+ int retval;
+
+ brcmf_dbg(SDIO, "addr:0x%08x\n", addr);
--- /dev/null
+From 8fa5fdec09cd379c9ecb8972f344f8f308e0ccf3 Mon Sep 17 00:00:00 2001
+From: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Date: Mon, 19 Sep 2016 12:09:55 +0100
+Subject: [PATCH] brcmfmac: remove worker from .ndo_set_mac_address() callback
+
+As it turns out there is no need to use a worker for the callback
+because it is not called from atomic context.
+
+Reported-by: Dan Williams <dcbw@redhat.com>
+Reviewed-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ .../wireless/broadcom/brcm80211/brcmfmac/core.c | 39 ++++++++--------------
+ .../wireless/broadcom/brcm80211/brcmfmac/core.h | 2 --
+ 2 files changed, 13 insertions(+), 28 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -136,27 +136,6 @@ static void _brcmf_set_multicast_list(st
+ err);
+ }
+
+-static void
+-_brcmf_set_mac_address(struct work_struct *work)
+-{
+- struct brcmf_if *ifp;
+- s32 err;
+-
+- ifp = container_of(work, struct brcmf_if, setmacaddr_work);
+-
+- brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
+-
+- err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", ifp->mac_addr,
+- ETH_ALEN);
+- if (err < 0) {
+- brcmf_err("Setting cur_etheraddr failed, %d\n", err);
+- } else {
+- brcmf_dbg(TRACE, "MAC address updated to %pM\n",
+- ifp->mac_addr);
+- memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
+- }
+-}
+-
+ #if IS_ENABLED(CONFIG_IPV6)
+ static void _brcmf_update_ndtable(struct work_struct *work)
+ {
+@@ -190,10 +169,20 @@ static int brcmf_netdev_set_mac_address(
+ {
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct sockaddr *sa = (struct sockaddr *)addr;
++ int err;
+
+- memcpy(&ifp->mac_addr, sa->sa_data, ETH_ALEN);
+- schedule_work(&ifp->setmacaddr_work);
+- return 0;
++ brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx);
++
++ err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", sa->sa_data,
++ ETH_ALEN);
++ if (err < 0) {
++ brcmf_err("Setting cur_etheraddr failed, %d\n", err);
++ } else {
++ brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data);
++ memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN);
++ memcpy(ifp->ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
++ }
++ return err;
+ }
+
+ static void brcmf_netdev_set_multicast_list(struct net_device *ndev)
+@@ -525,7 +514,6 @@ int brcmf_net_attach(struct brcmf_if *if
+ /* set the mac address */
+ memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
+
+- INIT_WORK(&ifp->setmacaddr_work, _brcmf_set_mac_address);
+ INIT_WORK(&ifp->multicast_work, _brcmf_set_multicast_list);
+ INIT_WORK(&ifp->ndoffload_work, _brcmf_update_ndtable);
+
+@@ -730,7 +718,6 @@ static void brcmf_del_if(struct brcmf_pu
+ }
+
+ if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
+- cancel_work_sync(&ifp->setmacaddr_work);
+ cancel_work_sync(&ifp->multicast_work);
+ cancel_work_sync(&ifp->ndoffload_work);
+ }
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+@@ -176,7 +176,6 @@ enum brcmf_netif_stop_reason {
+ * @vif: points to cfg80211 specific interface information.
+ * @ndev: associated network device.
+ * @stats: interface specific network statistics.
+- * @setmacaddr_work: worker object for setting mac address.
+ * @multicast_work: worker object for multicast provisioning.
+ * @ndoffload_work: worker object for neighbor discovery offload configuration.
+ * @fws_desc: interface specific firmware-signalling descriptor.
+@@ -193,7 +192,6 @@ struct brcmf_if {
+ struct brcmf_cfg80211_vif *vif;
+ struct net_device *ndev;
+ struct net_device_stats stats;
+- struct work_struct setmacaddr_work;
+ struct work_struct multicast_work;
+ struct work_struct ndoffload_work;
+ struct brcmf_fws_mac_descriptor *fws_desc;
--- /dev/null
+From 835680b82f029818c813324aed3073cdcf63241f Mon Sep 17 00:00:00 2001
+From: Hante Meuleman <hante.meuleman@broadcom.com>
+Date: Mon, 19 Sep 2016 12:09:56 +0100
+Subject: [PATCH] brcmfmac: remove unnecessary null pointer check
+
+in the function brcmf_bus_start() in the exception handling a
+check is made to dermine whether ifp is null, though this is not
+possible. Removing the unnessary check.
+
+Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -1048,8 +1048,7 @@ fail:
+ brcmf_fws_del_interface(ifp);
+ brcmf_fws_deinit(drvr);
+ }
+- if (ifp)
+- brcmf_net_detach(ifp->ndev, false);
++ brcmf_net_detach(ifp->ndev, false);
+ if (p2p_ifp)
+ brcmf_net_detach(p2p_ifp->ndev, false);
+ drvr->iflist[0] = NULL;
--- /dev/null
+From 2b7425f3629b38c438f890c20c5faeca64b144ff Mon Sep 17 00:00:00 2001
+From: Hante Meuleman <hante.meuleman@broadcom.com>
+Date: Mon, 19 Sep 2016 12:09:57 +0100
+Subject: [PATCH] brcmfmac: fix clearing entry IPv6 address
+
+When IPv6 address is to be cleared there is a possible out of
+bound access. But also the clearing of the last entry and the
+adjustment of total number of stored IPv6 addresses is not
+updated. This patch fixes that bug. Bug was found using coverity.
+
+Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 7 +++++--
+ 1 file changed, 5 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -873,9 +873,12 @@ static int brcmf_inet6addr_changed(struc
+ }
+ break;
+ case NETDEV_DOWN:
+- if (i < NDOL_MAX_ENTRIES)
+- for (; i < ifp->ipv6addr_idx; i++)
++ if (i < NDOL_MAX_ENTRIES) {
++ for (; i < ifp->ipv6addr_idx - 1; i++)
+ table[i] = table[i + 1];
++ memset(&table[i], 0, sizeof(table[i]));
++ ifp->ipv6addr_idx--;
++ }
+ break;
+ default:
+ break;
--- /dev/null
+From a7ed7828ecda0c2b5e0d7f55dedd4230afd4b583 Mon Sep 17 00:00:00 2001
+From: Hante Meuleman <hante.meuleman@broadcom.com>
+Date: Mon, 19 Sep 2016 12:09:58 +0100
+Subject: [PATCH] brcmfmac: fix out of bound access on clearing wowl wake
+ indicator
+
+Clearing the wowl wakeindicator happens with a rather odd
+construction where the string "clear" is used to set the iovar
+wowl_wakeind. This was implemented incorrectly as it caused an
+out of bound access. Use an intermediate variable of correct
+length and copy string in that. Problem was found using coverity.
+
+Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -3623,6 +3623,7 @@ static void brcmf_configure_wowl(struct
+ struct cfg80211_wowlan *wowl)
+ {
+ u32 wowl_config;
++ struct brcmf_wowl_wakeind_le wowl_wakeind;
+ u32 i;
+
+ brcmf_dbg(TRACE, "Suspend, wowl config.\n");
+@@ -3664,8 +3665,9 @@ static void brcmf_configure_wowl(struct
+ if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
+ wowl_config |= BRCMF_WOWL_UNASSOC;
+
+- brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear",
+- sizeof(struct brcmf_wowl_wakeind_le));
++ memcpy(&wowl_wakeind, "clear", 6);
++ brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind,
++ sizeof(wowl_wakeind));
+ brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
+ brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
+ brcmf_bus_wowl_config(cfg->pub->bus_if, true);
--- /dev/null
+From 92c313604711a0976def79dabb9e8da3cc2cc780 Mon Sep 17 00:00:00 2001
+From: Hante Meuleman <hante.meuleman@broadcom.com>
+Date: Mon, 19 Sep 2016 12:09:59 +0100
+Subject: [PATCH] brcmfmac: simplify mapping of auth type
+
+The 802.11 standard only has four valid auth type configurations of which
+our firmware only supports two, ie. Open System and Shared Key. Simplify
+the mapping falling back to automatic for other types specified by
+user-space.
+
+Reviewed-by: Arend Van Spriel <arend.vanspriel@broadcom.com>
+Reviewed-by: Franky Lin <franky.lin@broadcom.com>
+Reviewed-by: Pieter-Paul Giesberts <pieter-paul.giesberts@broadcom.com>
+Signed-off-by: Hante Meuleman <hante.meuleman@broadcom.com>
+Signed-off-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -1577,15 +1577,9 @@ static s32 brcmf_set_auth_type(struct ne
+ val = 1;
+ brcmf_dbg(CONN, "shared key\n");
+ break;
+- case NL80211_AUTHTYPE_AUTOMATIC:
+- val = 2;
+- brcmf_dbg(CONN, "automatic\n");
+- break;
+- case NL80211_AUTHTYPE_NETWORK_EAP:
+- brcmf_dbg(CONN, "network eap\n");
+ default:
+ val = 2;
+- brcmf_err("invalid auth type (%d)\n", sme->auth_type);
++ brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
+ break;
+ }
+
--- /dev/null
+From 23e9c128adb2038c27a424a5f91136e7fa3e0dc6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Wed, 21 Sep 2016 08:23:24 +0200
+Subject: [PATCH] brcmfmac: fix memory leak in brcmf_fill_bss_param
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This function is called from get_station callback which means that every
+time user space was getting/dumping station(s) we were leaking 2 KiB.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Fixes: 1f0dc59a6de ("brcmfmac: rework .get_station() callback")
+Cc: stable@vger.kernel.org # 4.2+
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+@@ -2463,7 +2463,7 @@ static void brcmf_fill_bss_param(struct
+ WL_BSS_INFO_MAX);
+ if (err) {
+ brcmf_err("Failed to get bss info (%d)\n", err);
+- return;
++ goto out_kfree;
+ }
+ si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
+ si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
+@@ -2475,6 +2475,9 @@ static void brcmf_fill_bss_param(struct
+ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
+ if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
+ si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
++
++out_kfree:
++ kfree(buf);
+ }
+
+ static s32
--- /dev/null
+From 2df86ad959c9d1cdbeb2f23a0801857731156692 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Fri, 23 Sep 2016 15:27:46 +0200
+Subject: [PATCH] brcmfmac: drop unused fields from struct brcmf_pub
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+They seem to be there from the first day. We calculate these values but
+never use them.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 4 ----
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 2 --
+ 3 files changed, 9 deletions(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -508,9 +508,6 @@ int brcmf_net_attach(struct brcmf_if *if
+ ndev->hard_header_len += drvr->hdrlen;
+ ndev->ethtool_ops = &brcmf_ethtool_ops;
+
+- drvr->rxsz = ndev->mtu + ndev->hard_header_len +
+- drvr->hdrlen;
+-
+ /* set the mac address */
+ memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN);
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+@@ -112,15 +112,11 @@ struct brcmf_pub {
+
+ /* Internal brcmf items */
+ uint hdrlen; /* Total BRCMF header length (proto + bus) */
+- uint rxsz; /* Rx buffer size bus module should use */
+
+ /* Dongle media info */
+ char fwver[BRCMF_DRIVER_FIRMWARE_VERSION_LEN];
+ u8 mac[ETH_ALEN]; /* MAC address obtained from dongle */
+
+- /* Multicast data packets sent to dongle */
+- unsigned long tx_multicast;
+-
+ struct mac_address addresses[BRCMF_MAX_IFS];
+
+ struct brcmf_if *iflist[BRCMF_MAX_IFS];
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+@@ -2104,8 +2104,6 @@ int brcmf_fws_process_skb(struct brcmf_i
+ if (!skb->priority)
+ skb->priority = cfg80211_classify8021d(skb, NULL);
+
+- drvr->tx_multicast += !!multicast;
+-
+ if (fws->avoid_queueing) {
+ rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
+ if (rc < 0)
--- /dev/null
+From 2f0e56fa37cce60a5ac5d451bcadec51cd711436 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Tue, 27 Sep 2016 12:12:24 +0200
+Subject: [PATCH] brcmfmac: replace WARNING on timeout with a simple error
+ message
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Even with timeout increased to 950 ms we get WARNINGs from time to time.
+It mostly happens on A-MPDU stalls (e.g. when station goes out of
+range). It may take up to 5-10 secods for the firmware to recover and
+for that time it doesn't process packets.
+
+It's still useful to have a message on time out as it may indicate some
+firmware problem and incorrect key update. Raising a WARNING however
+wasn't really that necessary, it doesn't point to any driver bug anymore
+and backtrace wasn't much useful.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+@@ -1155,7 +1155,8 @@ int brcmf_netdev_wait_pend8021x(struct b
+ !brcmf_get_pend_8021x_cnt(ifp),
+ MAX_WAIT_FOR_8021X_TX);
+
+- WARN_ON(!err);
++ if (!err)
++ brcmf_err("Timed out waiting for no pending 802.1x packets\n");
+
+ return !err;
+ }
--- /dev/null
+From 7f00ee2bbc630900ba16fc2690473f3e2db0e264 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
+Date: Tue, 27 Sep 2016 14:11:04 +0200
+Subject: [PATCH] brcmfmac: use correct skb freeing helper when deleting
+ flowring
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Flowrings contain skbs waiting for transmission that were passed to us
+by netif. It means we checked every one of them looking for 802.1x
+Ethernet type. When deleting flowring we have to use freeing function
+that will check for 802.1x type as well.
+
+Freeing skbs without a proper check was leading to counter not being
+properly decreased. This was triggering a WARNING every time
+brcmf_netdev_wait_pend8021x was called.
+
+Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
+Acked-by: Arend van Spriel <arend@broadcom.com>
+Cc: stable@vger.kernel.org # 4.5+
+Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
+---
+ drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/flowring.c
+@@ -234,13 +234,20 @@ static void brcmf_flowring_block(struct
+
+ void brcmf_flowring_delete(struct brcmf_flowring *flow, u16 flowid)
+ {
++ struct brcmf_bus *bus_if = dev_get_drvdata(flow->dev);
+ struct brcmf_flowring_ring *ring;
++ struct brcmf_if *ifp;
+ u16 hash_idx;
++ u8 ifidx;
+ struct sk_buff *skb;
+
+ ring = flow->rings[flowid];
+ if (!ring)
+ return;
++
++ ifidx = brcmf_flowring_ifidx_get(flow, flowid);
++ ifp = brcmf_get_ifp(bus_if->drvr, ifidx);
++
+ brcmf_flowring_block(flow, flowid, false);
+ hash_idx = ring->hash_id;
+ flow->hash[hash_idx].ifidx = BRCMF_FLOWRING_INVALID_IFIDX;
+@@ -249,7 +256,7 @@ void brcmf_flowring_delete(struct brcmf_
+
+ skb = skb_dequeue(&ring->skblist);
+ while (skb) {
+- brcmu_pkt_buf_free_skb(skb);
++ brcmf_txfinalize(ifp, skb, false);
+ skb = skb_dequeue(&ring->skblist);
+ }
+
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
-@@ -1213,6 +1213,7 @@ int __init brcmf_core_init(void)
+@@ -1200,6 +1200,7 @@ int __init brcmf_core_init(void)
{
if (!schedule_work(&brcmf_driver_work))
return -EBUSY;