mac80211: brcmfmac: backport changes from 2016-09-27 chaos_calmer
authorRafał Miłecki <zajec5@gmail.com>
Tue, 27 Sep 2016 22:02:13 +0000 (22:02 +0000)
committerRafał Miłecki <zajec5@gmail.com>
Tue, 27 Sep 2016 22:02:13 +0000 (22:02 +0000)
This fixes memory leaks, some possible crashes and bug that could cause
WARNING on every add_key/del_key call. It also replaces WARNING with
a simple message. They may still occur e.g. on station going out of
range and A-MPDU stall in the firmware.

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
SVN-Revision: 49407

25 files changed:
package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch [new file with mode: 0644]
package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch [new file with mode: 0644]
package/kernel/mac80211/patches/861-brcmfmac-register-wiphy-s-during-module_init.patch

diff --git a/package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch b/package/kernel/mac80211/patches/351-0028-brcmfmac-defer-DPC-processing-during-probe.patch
new file mode 100644 (file)
index 0000000..a24c07f
--- /dev/null
@@ -0,0 +1,42 @@
+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);
diff --git a/package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch b/package/kernel/mac80211/patches/351-0029-brcmfmac-Fix-glob_skb-leak-in-brcmf_sdiod_recv_chain.patch
new file mode 100644 (file)
index 0000000..ba9a349
--- /dev/null
@@ -0,0 +1,32 @@
+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);
diff --git a/package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch b/package/kernel/mac80211/patches/351-0030-net-wireless-broadcom-brcm80211-brcmfmac-usb-don-t-p.patch
new file mode 100644 (file)
index 0000000..540b7f0
--- /dev/null
@@ -0,0 +1,34 @@
+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;
diff --git a/package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch b/package/kernel/mac80211/patches/351-0031-brcmfmac-Check-rtnl_lock-is-locked-when-removing-int.patch
new file mode 100644 (file)
index 0000000..6105e6e
--- /dev/null
@@ -0,0 +1,111 @@
+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,
diff --git a/package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch b/package/kernel/mac80211/patches/351-0032-brcmfmac-Change-vif_event_lock-to-spinlock.patch
new file mode 100644 (file)
index 0000000..30ca258
--- /dev/null
@@ -0,0 +1,175 @@
+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;
+ };
diff --git a/package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch b/package/kernel/mac80211/patches/351-0033-brcmfmac-add-missing-header-dependencies.patch
new file mode 100644 (file)
index 0000000..1a7947b
--- /dev/null
@@ -0,0 +1,29 @@
+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, ...)
+ {
diff --git a/package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch b/package/kernel/mac80211/patches/351-0034-brcmfmac-Add-USB-ID-for-Cisco-Linksys-AE1200.patch
new file mode 100644 (file)
index 0000000..24cd92a
--- /dev/null
@@ -0,0 +1,51 @@
+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
diff --git a/package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch b/package/kernel/mac80211/patches/351-0035-brcmfmac-fix-pmksa-bssid-usage.patch
new file mode 100644 (file)
index 0000000..b58a266
--- /dev/null
@@ -0,0 +1,51 @@
+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)) {
diff --git a/package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch b/package/kernel/mac80211/patches/351-0036-brcmfmac-avoid-potential-stack-overflow-in-brcmf_cfg.patch
new file mode 100644 (file)
index 0000000..760b6da
--- /dev/null
@@ -0,0 +1,34 @@
+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);
diff --git a/package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch b/package/kernel/mac80211/patches/351-0037-brcmfmac-add-support-for-bcm4339-chip-with-modalias-.patch
new file mode 100644 (file)
index 0000000..1285b30
--- /dev/null
@@ -0,0 +1,55 @@
+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
diff --git a/package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch b/package/kernel/mac80211/patches/351-0038-brcmfmac-sdio-shorten-retry-loop-in-brcmf_sdio_kso_c.patch
new file mode 100644 (file)
index 0000000..1d5667e
--- /dev/null
@@ -0,0 +1,56 @@
+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);
diff --git a/package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch b/package/kernel/mac80211/patches/351-0039-brcmfmac-ignore-11d-configuration-errors.patch
new file mode 100644 (file)
index 0000000..1620e00
--- /dev/null
@@ -0,0 +1,84 @@
+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)
diff --git a/package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch b/package/kernel/mac80211/patches/351-0040-brcmfmac-rework-pointer-trickery-in-brcmf_proto_bcdc.patch
new file mode 100644 (file)
index 0000000..9461164
--- /dev/null
@@ -0,0 +1,32 @@
+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) {
diff --git a/package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch b/package/kernel/mac80211/patches/351-0041-brcmfmac-fix-memory-leak-in-brcmf_flowring_add_tdls_.patch
new file mode 100644 (file)
index 0000000..2ececdf
--- /dev/null
@@ -0,0 +1,39 @@
+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);
+ }
diff --git a/package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch b/package/kernel/mac80211/patches/351-0042-brcmfmac-initialize-variable-in-brcmf_sdiod_regrl.patch
new file mode 100644 (file)
index 0000000..529cc8d
--- /dev/null
@@ -0,0 +1,28 @@
+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);
diff --git a/package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch b/package/kernel/mac80211/patches/351-0043-brcmfmac-remove-worker-from-.ndo_set_mac_address-cal.patch
new file mode 100644 (file)
index 0000000..67af30e
--- /dev/null
@@ -0,0 +1,107 @@
+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;
diff --git a/package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch b/package/kernel/mac80211/patches/351-0044-brcmfmac-remove-unnecessary-null-pointer-check.patch
new file mode 100644 (file)
index 0000000..5a08479
--- /dev/null
@@ -0,0 +1,31 @@
+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;
diff --git a/package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch b/package/kernel/mac80211/patches/351-0045-brcmfmac-fix-clearing-entry-IPv6-address.patch
new file mode 100644 (file)
index 0000000..0b3a23e
--- /dev/null
@@ -0,0 +1,37 @@
+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;
diff --git a/package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch b/package/kernel/mac80211/patches/351-0046-brcmfmac-fix-out-of-bound-access-on-clearing-wowl-wa.patch
new file mode 100644 (file)
index 0000000..a47cb32
--- /dev/null
@@ -0,0 +1,44 @@
+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);
diff --git a/package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch b/package/kernel/mac80211/patches/351-0047-brcmfmac-simplify-mapping-of-auth-type.patch
new file mode 100644 (file)
index 0000000..a652ae6
--- /dev/null
@@ -0,0 +1,39 @@
+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;
+       }
diff --git a/package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch b/package/kernel/mac80211/patches/351-0048-brcmfmac-fix-memory-leak-in-brcmf_fill_bss_param.patch
new file mode 100644 (file)
index 0000000..623bd77
--- /dev/null
@@ -0,0 +1,41 @@
+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
diff --git a/package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch b/package/kernel/mac80211/patches/351-0049-brcmfmac-drop-unused-fields-from-struct-brcmf_pub.patch
new file mode 100644 (file)
index 0000000..64b0c1e
--- /dev/null
@@ -0,0 +1,60 @@
+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)
diff --git a/package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch b/package/kernel/mac80211/patches/351-0050-brcmfmac-replace-WARNING-on-timeout-with-a-simple-er.patch
new file mode 100644 (file)
index 0000000..1a48f1b
--- /dev/null
@@ -0,0 +1,38 @@
+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;
+ }
diff --git a/package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch b/package/kernel/mac80211/patches/351-0051-brcmfmac-use-correct-skb-freeing-helper-when-deletin.patch
new file mode 100644 (file)
index 0000000..91c5dd5
--- /dev/null
@@ -0,0 +1,58 @@
+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);
+       }
index ae571c99ab151245355d0080a6475bcabbb9a2fb..f7f44f513f5e80f18f26c49073f916a435c6c534 100644 (file)
@@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
 
 --- 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;