mac80211: brcm: backport remaining 5.6 kernel patches
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
This commit is contained in:
parent
71de48bd37
commit
aca274091a
|
@ -0,0 +1,26 @@
|
||||||
|
From 4282dc057d750c6a7dd92953564b15c26b54c22c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Navid Emamdoost <navid.emamdoost@gmail.com>
|
||||||
|
Date: Sat, 14 Dec 2019 19:51:14 -0600
|
||||||
|
Subject: [PATCH] brcmfmac: Fix memory leak in brcmf_usbdev_qinit
|
||||||
|
|
||||||
|
In the implementation of brcmf_usbdev_qinit() the allocated memory for
|
||||||
|
reqs is leaking if usb_alloc_urb() fails. Release reqs in the error
|
||||||
|
handling path.
|
||||||
|
|
||||||
|
Fixes: 71bb244ba2fd ("brcm80211: fmac: add USB support for bcm43235/6/8 chipsets")
|
||||||
|
Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
|
||||||
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||||
|
---
|
||||||
|
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 1 +
|
||||||
|
1 file changed, 1 insertion(+)
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
|
||||||
|
@@ -430,6 +430,7 @@ fail:
|
||||||
|
usb_free_urb(req->urb);
|
||||||
|
list_del(q->next);
|
||||||
|
}
|
||||||
|
+ kfree(reqs);
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
From a32de68edab7b73ded850bcf76cdf6858e92a7e5 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Dmitry Osipenko <digetx@gmail.com>
|
||||||
|
Date: Sun, 15 Dec 2019 21:42:24 +0300
|
||||||
|
Subject: [PATCH] brcmfmac: Keep OOB wake-interrupt disabled when it shouldn't
|
||||||
|
be enabled
|
||||||
|
|
||||||
|
NVIDIA Tegra SoCs do not like when OOB wake is enabled and WiFi interface
|
||||||
|
is in DOWN state during suspend. This results in a CPU hang on programming
|
||||||
|
OOB wake-up state of the GPIO controller during of system's suspend.
|
||||||
|
|
||||||
|
The solution is trivial: don't enable wake for the OOB interrupt when it
|
||||||
|
should be disabled.
|
||||||
|
|
||||||
|
This fixes hang on Tegra20 (Acer A500) and Tegra30 (Nexus 7) devices which
|
||||||
|
are using BCM4329 and BCM4330 WiFi chips respectively.
|
||||||
|
|
||||||
|
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
|
||||||
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||||
|
---
|
||||||
|
.../net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 10 +++++-----
|
||||||
|
.../net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 1 -
|
||||||
|
2 files changed, 5 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
|
||||||
|
@@ -120,7 +120,7 @@ int brcmf_sdiod_intr_register(struct brc
|
||||||
|
brcmf_err("enable_irq_wake failed %d\n", ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
- sdiodev->irq_wake = true;
|
||||||
|
+ disable_irq_wake(pdata->oob_irq_nr);
|
||||||
|
|
||||||
|
sdio_claim_host(sdiodev->func1);
|
||||||
|
|
||||||
|
@@ -179,10 +179,6 @@ void brcmf_sdiod_intr_unregister(struct
|
||||||
|
sdio_release_host(sdiodev->func1);
|
||||||
|
|
||||||
|
sdiodev->oob_irq_requested = false;
|
||||||
|
- if (sdiodev->irq_wake) {
|
||||||
|
- disable_irq_wake(pdata->oob_irq_nr);
|
||||||
|
- sdiodev->irq_wake = false;
|
||||||
|
- }
|
||||||
|
free_irq(pdata->oob_irq_nr, &sdiodev->func1->dev);
|
||||||
|
sdiodev->irq_en = false;
|
||||||
|
sdiodev->oob_irq_requested = false;
|
||||||
|
@@ -1173,6 +1169,10 @@ static int brcmf_ops_sdio_resume(struct
|
||||||
|
if (ret)
|
||||||
|
brcmf_err("Failed to probe device on resume\n");
|
||||||
|
} else {
|
||||||
|
+ if (sdiodev->wowl_enabled &&
|
||||||
|
+ sdiodev->settings->bus.sdio.oob_irq_supported)
|
||||||
|
+ disable_irq_wake(sdiodev->settings->bus.sdio.oob_irq_nr);
|
||||||
|
+
|
||||||
|
brcmf_sdiod_freezer_off(sdiodev);
|
||||||
|
}
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h
|
||||||
|
@@ -178,7 +178,6 @@ struct brcmf_sdio_dev {
|
||||||
|
bool sd_irq_requested;
|
||||||
|
bool irq_en; /* irq enable flags */
|
||||||
|
spinlock_t irq_en_lock;
|
||||||
|
- bool irq_wake; /* irq wake enable flags */
|
||||||
|
bool sg_support;
|
||||||
|
uint max_request_size;
|
||||||
|
ushort max_segment_count;
|
|
@ -0,0 +1,27 @@
|
||||||
|
From b92c017deda819e45a0f054f6df6b53e645d7fe4 Mon Sep 17 00:00:00 2001
|
||||||
|
From: zhengbin <zhengbin13@huawei.com>
|
||||||
|
Date: Tue, 24 Dec 2019 22:16:06 +0800
|
||||||
|
Subject: [PATCH] brcmfmac: use true,false for bool variable
|
||||||
|
|
||||||
|
Fixes coccicheck warning:
|
||||||
|
|
||||||
|
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c:911:2-24: WARNING: Assignment of 0/1 to bool variable
|
||||||
|
|
||||||
|
Reported-by: Hulk Robot <hulkci@huawei.com>
|
||||||
|
Signed-off-by: zhengbin <zhengbin13@huawei.com>
|
||||||
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||||
|
---
|
||||||
|
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
|
||||||
|
@@ -908,7 +908,7 @@ static u8 brcmf_fws_hdrpush(struct brcmf
|
||||||
|
wlh += wlh[1] + 2;
|
||||||
|
|
||||||
|
if (entry->send_tim_signal) {
|
||||||
|
- entry->send_tim_signal = 0;
|
||||||
|
+ entry->send_tim_signal = false;
|
||||||
|
wlh[0] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP;
|
||||||
|
wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
|
||||||
|
wlh[2] = entry->mac_handle;
|
|
@ -0,0 +1,57 @@
|
||||||
|
From 8c8e60fb86a90a30721bbd797f58f96b3980dcc1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jean-Philippe Brucker <jean-philippe@linaro.org>
|
||||||
|
Date: Thu, 26 Dec 2019 10:20:33 +0100
|
||||||
|
Subject: [PATCH] brcmfmac: sdio: Fix OOB interrupt initialization on brcm43362
|
||||||
|
|
||||||
|
Commit 262f2b53f679 ("brcmfmac: call brcmf_attach() just before calling
|
||||||
|
brcmf_bus_started()") changed the initialization order of the brcmfmac
|
||||||
|
SDIO driver. Unfortunately since brcmf_sdiod_intr_register() is now
|
||||||
|
called before the sdiodev->bus_if initialization, it reads the wrong
|
||||||
|
chip ID and fails to initialize the GPIO on brcm43362. Thus the chip
|
||||||
|
cannot send interrupts and fails to probe:
|
||||||
|
|
||||||
|
[ 12.517023] brcmfmac: brcmf_sdio_bus_rxctl: resumed on timeout
|
||||||
|
[ 12.531214] ieee80211 phy0: brcmf_bus_started: failed: -110
|
||||||
|
[ 12.536976] ieee80211 phy0: brcmf_attach: dongle is not responding: err=-110
|
||||||
|
[ 12.566467] brcmfmac: brcmf_sdio_firmware_callback: brcmf_attach failed
|
||||||
|
|
||||||
|
Initialize the bus interface earlier to ensure that
|
||||||
|
brcmf_sdiod_intr_register() properly sets up the OOB interrupt.
|
||||||
|
|
||||||
|
BugLink: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=908438
|
||||||
|
Fixes: 262f2b53f679 ("brcmfmac: call brcmf_attach() just before calling brcmf_bus_started()")
|
||||||
|
Signed-off-by: Jean-Philippe Brucker <jean-philippe@linaro.org>
|
||||||
|
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
|
||||||
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||||
|
---
|
||||||
|
.../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 12 ++++++------
|
||||||
|
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
|
||||||
|
@@ -4243,6 +4243,12 @@ static void brcmf_sdio_firmware_callback
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err == 0) {
|
||||||
|
+ /* Assign bus interface call back */
|
||||||
|
+ sdiod->bus_if->dev = sdiod->dev;
|
||||||
|
+ sdiod->bus_if->ops = &brcmf_sdio_bus_ops;
|
||||||
|
+ sdiod->bus_if->chip = bus->ci->chip;
|
||||||
|
+ sdiod->bus_if->chiprev = bus->ci->chiprev;
|
||||||
|
+
|
||||||
|
/* Allow full data communication using DPC from now on. */
|
||||||
|
brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DATA);
|
||||||
|
|
||||||
|
@@ -4259,12 +4265,6 @@ static void brcmf_sdio_firmware_callback
|
||||||
|
|
||||||
|
sdio_release_host(sdiod->func1);
|
||||||
|
|
||||||
|
- /* Assign bus interface call back */
|
||||||
|
- sdiod->bus_if->dev = sdiod->dev;
|
||||||
|
- sdiod->bus_if->ops = &brcmf_sdio_bus_ops;
|
||||||
|
- sdiod->bus_if->chip = bus->ci->chip;
|
||||||
|
- sdiod->bus_if->chiprev = bus->ci->chiprev;
|
||||||
|
-
|
||||||
|
err = brcmf_alloc(sdiod->dev, sdiod->settings);
|
||||||
|
if (err) {
|
||||||
|
brcmf_err("brcmf_alloc failed\n");
|
|
@ -0,0 +1,103 @@
|
||||||
|
From 24332f8068ff6df7f16aefee45d514de1de4de80 Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||||
|
Date: Thu, 26 Dec 2019 14:30:49 +0100
|
||||||
|
Subject: [PATCH] brcmfmac: simplify building interface combinations
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Move similar/duplicated code out of combination specific code blocks.
|
||||||
|
This simplifies code a bit and allows adding more combinations later.
|
||||||
|
A list of combinations remains unchanged.
|
||||||
|
|
||||||
|
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||||
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||||
|
---
|
||||||
|
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 43 ++++++-------------
|
||||||
|
1 file changed, 14 insertions(+), 29 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||||
|
@@ -6479,12 +6479,13 @@ static int brcmf_setup_ifmodes(struct wi
|
||||||
|
struct ieee80211_iface_limit *c0_limits = NULL;
|
||||||
|
struct ieee80211_iface_limit *p2p_limits = NULL;
|
||||||
|
struct ieee80211_iface_limit *mbss_limits = NULL;
|
||||||
|
- bool mbss, p2p, rsdb;
|
||||||
|
+ bool mbss, p2p, rsdb, mchan;
|
||||||
|
int i, c, n_combos;
|
||||||
|
|
||||||
|
mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
|
||||||
|
p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
|
||||||
|
rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
|
||||||
|
+ mchan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN);
|
||||||
|
|
||||||
|
n_combos = 1 + !!(p2p && !rsdb) + !!mbss;
|
||||||
|
combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
|
||||||
|
@@ -6494,6 +6495,10 @@ static int brcmf_setup_ifmodes(struct wi
|
||||||
|
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||||
|
BIT(NL80211_IFTYPE_ADHOC) |
|
||||||
|
BIT(NL80211_IFTYPE_AP);
|
||||||
|
+ if (p2p)
|
||||||
|
+ wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
|
+ BIT(NL80211_IFTYPE_P2P_GO) |
|
||||||
|
+ BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||||
|
|
||||||
|
c = 0;
|
||||||
|
i = 0;
|
||||||
|
@@ -6505,48 +6510,28 @@ static int brcmf_setup_ifmodes(struct wi
|
||||||
|
c0_limits = kcalloc(2, sizeof(*c0_limits), GFP_KERNEL);
|
||||||
|
if (!c0_limits)
|
||||||
|
goto err;
|
||||||
|
- if (p2p && rsdb) {
|
||||||
|
- combo[c].num_different_channels = 2;
|
||||||
|
- wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
|
- BIT(NL80211_IFTYPE_P2P_GO) |
|
||||||
|
- BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||||
|
- c0_limits[i].max = 2;
|
||||||
|
- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||||
|
+
|
||||||
|
+ combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
|
||||||
|
+ c0_limits[i].max = 1 + rsdb;
|
||||||
|
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||||
|
+ if (p2p) {
|
||||||
|
c0_limits[i].max = 1;
|
||||||
|
c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||||
|
- c0_limits[i].max = 2;
|
||||||
|
+ c0_limits[i].max = 1 + rsdb;
|
||||||
|
c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
|
BIT(NL80211_IFTYPE_P2P_GO);
|
||||||
|
+ }
|
||||||
|
+ if (p2p && rsdb) {
|
||||||
|
c0_limits[i].max = 2;
|
||||||
|
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||||
|
combo[c].max_interfaces = 5;
|
||||||
|
} else if (p2p) {
|
||||||
|
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
|
||||||
|
- combo[c].num_different_channels = 2;
|
||||||
|
- else
|
||||||
|
- combo[c].num_different_channels = 1;
|
||||||
|
- c0_limits[i].max = 1;
|
||||||
|
- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||||
|
- wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
|
- BIT(NL80211_IFTYPE_P2P_GO) |
|
||||||
|
- BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||||
|
- c0_limits[i].max = 1;
|
||||||
|
- c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||||
|
- c0_limits[i].max = 1;
|
||||||
|
- c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
|
- BIT(NL80211_IFTYPE_P2P_GO);
|
||||||
|
combo[c].max_interfaces = i;
|
||||||
|
} else if (rsdb) {
|
||||||
|
- combo[c].num_different_channels = 2;
|
||||||
|
- c0_limits[i].max = 2;
|
||||||
|
- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||||
|
c0_limits[i].max = 2;
|
||||||
|
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||||
|
combo[c].max_interfaces = 3;
|
||||||
|
} else {
|
||||||
|
- combo[c].num_different_channels = 1;
|
||||||
|
- c0_limits[i].max = 1;
|
||||||
|
- c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||||
|
c0_limits[i].max = 1;
|
||||||
|
c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||||
|
combo[c].max_interfaces = i;
|
|
@ -0,0 +1,345 @@
|
||||||
|
From 20f2c5fa3af060401c72e444999470a4cab641cf Mon Sep 17 00:00:00 2001
|
||||||
|
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
|
||||||
|
Date: Thu, 26 Dec 2019 14:30:50 +0100
|
||||||
|
Subject: [PATCH] brcmfmac: add initial support for monitor mode
|
||||||
|
MIME-Version: 1.0
|
||||||
|
Content-Type: text/plain; charset=UTF-8
|
||||||
|
Content-Transfer-Encoding: 8bit
|
||||||
|
|
||||||
|
Report monitor interface availability using cfg80211 and support it in
|
||||||
|
the add_virtual_intf() and del_virtual_intf() callbacks. This new
|
||||||
|
feature is conditional and depends on firmware flagging monitor packets.
|
||||||
|
Receiving monitor frames is already handled by the brcmf_netif_mon_rx().
|
||||||
|
|
||||||
|
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
|
||||||
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||||
|
---
|
||||||
|
.../broadcom/brcm80211/brcmfmac/cfg80211.c | 112 ++++++++++++++++--
|
||||||
|
.../broadcom/brcm80211/brcmfmac/core.c | 68 ++++++++++-
|
||||||
|
.../broadcom/brcm80211/brcmfmac/core.h | 2 +
|
||||||
|
.../broadcom/brcm80211/brcmfmac/feature.c | 1 +
|
||||||
|
.../broadcom/brcm80211/brcmfmac/feature.h | 2 +
|
||||||
|
.../broadcom/brcm80211/brcmfmac/fwil.h | 2 +
|
||||||
|
6 files changed, 174 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||||
|
@@ -11,6 +11,7 @@
|
||||||
|
#include <linux/vmalloc.h>
|
||||||
|
#include <net/cfg80211.h>
|
||||||
|
#include <net/netlink.h>
|
||||||
|
+#include <uapi/linux/if_arp.h>
|
||||||
|
|
||||||
|
#include <brcmu_utils.h>
|
||||||
|
#include <defs.h>
|
||||||
|
@@ -619,6 +620,82 @@ static bool brcmf_is_ibssmode(struct brc
|
||||||
|
return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/**
|
||||||
|
+ * brcmf_mon_add_vif() - create monitor mode virtual interface
|
||||||
|
+ *
|
||||||
|
+ * @wiphy: wiphy device of new interface.
|
||||||
|
+ * @name: name of the new interface.
|
||||||
|
+ */
|
||||||
|
+static struct wireless_dev *brcmf_mon_add_vif(struct wiphy *wiphy,
|
||||||
|
+ const char *name)
|
||||||
|
+{
|
||||||
|
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||||
|
+ struct brcmf_cfg80211_vif *vif;
|
||||||
|
+ struct net_device *ndev;
|
||||||
|
+ struct brcmf_if *ifp;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ if (cfg->pub->mon_if) {
|
||||||
|
+ err = -EEXIST;
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_MONITOR);
|
||||||
|
+ if (IS_ERR(vif)) {
|
||||||
|
+ err = PTR_ERR(vif);
|
||||||
|
+ goto err_out;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN, ether_setup);
|
||||||
|
+ if (!ndev) {
|
||||||
|
+ err = -ENOMEM;
|
||||||
|
+ goto err_free_vif;
|
||||||
|
+ }
|
||||||
|
+ ndev->type = ARPHRD_IEEE80211_RADIOTAP;
|
||||||
|
+ ndev->ieee80211_ptr = &vif->wdev;
|
||||||
|
+ ndev->needs_free_netdev = true;
|
||||||
|
+ ndev->priv_destructor = brcmf_cfg80211_free_netdev;
|
||||||
|
+ SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
|
||||||
|
+
|
||||||
|
+ ifp = netdev_priv(ndev);
|
||||||
|
+ ifp->vif = vif;
|
||||||
|
+ ifp->ndev = ndev;
|
||||||
|
+ ifp->drvr = cfg->pub;
|
||||||
|
+
|
||||||
|
+ vif->ifp = ifp;
|
||||||
|
+ vif->wdev.netdev = ndev;
|
||||||
|
+
|
||||||
|
+ err = brcmf_net_mon_attach(ifp);
|
||||||
|
+ if (err) {
|
||||||
|
+ brcmf_err("Failed to attach %s device\n", ndev->name);
|
||||||
|
+ free_netdev(ndev);
|
||||||
|
+ goto err_free_vif;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ cfg->pub->mon_if = ifp;
|
||||||
|
+
|
||||||
|
+ return &vif->wdev;
|
||||||
|
+
|
||||||
|
+err_free_vif:
|
||||||
|
+ brcmf_free_vif(vif);
|
||||||
|
+err_out:
|
||||||
|
+ return ERR_PTR(err);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int brcmf_mon_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
|
||||||
|
+{
|
||||||
|
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||||
|
+ struct net_device *ndev = wdev->netdev;
|
||||||
|
+
|
||||||
|
+ ndev->netdev_ops->ndo_stop(ndev);
|
||||||
|
+
|
||||||
|
+ brcmf_net_detach(ndev, true);
|
||||||
|
+
|
||||||
|
+ cfg->pub->mon_if = NULL;
|
||||||
|
+
|
||||||
|
+ return 0;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
|
||||||
|
const char *name,
|
||||||
|
unsigned char name_assign_type,
|
||||||
|
@@ -641,9 +718,10 @@ static struct wireless_dev *brcmf_cfg802
|
||||||
|
case NL80211_IFTYPE_STATION:
|
||||||
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
case NL80211_IFTYPE_WDS:
|
||||||
|
- case NL80211_IFTYPE_MONITOR:
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
return ERR_PTR(-EOPNOTSUPP);
|
||||||
|
+ case NL80211_IFTYPE_MONITOR:
|
||||||
|
+ return brcmf_mon_add_vif(wiphy, name);
|
||||||
|
case NL80211_IFTYPE_AP:
|
||||||
|
wdev = brcmf_ap_add_vif(wiphy, name, params);
|
||||||
|
break;
|
||||||
|
@@ -826,9 +904,10 @@ int brcmf_cfg80211_del_iface(struct wiph
|
||||||
|
case NL80211_IFTYPE_STATION:
|
||||||
|
case NL80211_IFTYPE_AP_VLAN:
|
||||||
|
case NL80211_IFTYPE_WDS:
|
||||||
|
- case NL80211_IFTYPE_MONITOR:
|
||||||
|
case NL80211_IFTYPE_MESH_POINT:
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
+ case NL80211_IFTYPE_MONITOR:
|
||||||
|
+ return brcmf_mon_del_vif(wiphy, wdev);
|
||||||
|
case NL80211_IFTYPE_AP:
|
||||||
|
return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
|
||||||
|
case NL80211_IFTYPE_P2P_CLIENT:
|
||||||
|
@@ -6479,9 +6558,10 @@ static int brcmf_setup_ifmodes(struct wi
|
||||||
|
struct ieee80211_iface_limit *c0_limits = NULL;
|
||||||
|
struct ieee80211_iface_limit *p2p_limits = NULL;
|
||||||
|
struct ieee80211_iface_limit *mbss_limits = NULL;
|
||||||
|
- bool mbss, p2p, rsdb, mchan;
|
||||||
|
- int i, c, n_combos;
|
||||||
|
+ bool mon_flag, mbss, p2p, rsdb, mchan;
|
||||||
|
+ int i, c, n_combos, n_limits;
|
||||||
|
|
||||||
|
+ mon_flag = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FLAG);
|
||||||
|
mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
|
||||||
|
p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
|
||||||
|
rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
|
||||||
|
@@ -6495,6 +6575,8 @@ static int brcmf_setup_ifmodes(struct wi
|
||||||
|
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
|
||||||
|
BIT(NL80211_IFTYPE_ADHOC) |
|
||||||
|
BIT(NL80211_IFTYPE_AP);
|
||||||
|
+ if (mon_flag)
|
||||||
|
+ wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
|
||||||
|
if (p2p)
|
||||||
|
wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
|
||||||
|
BIT(NL80211_IFTYPE_P2P_GO) |
|
||||||
|
@@ -6502,18 +6584,18 @@ static int brcmf_setup_ifmodes(struct wi
|
||||||
|
|
||||||
|
c = 0;
|
||||||
|
i = 0;
|
||||||
|
- if (p2p && rsdb)
|
||||||
|
- c0_limits = kcalloc(4, sizeof(*c0_limits), GFP_KERNEL);
|
||||||
|
- else if (p2p)
|
||||||
|
- c0_limits = kcalloc(3, sizeof(*c0_limits), GFP_KERNEL);
|
||||||
|
- else
|
||||||
|
- c0_limits = kcalloc(2, sizeof(*c0_limits), GFP_KERNEL);
|
||||||
|
+ n_limits = 1 + mon_flag + (p2p ? 2 : 0) + (rsdb || !p2p);
|
||||||
|
+ c0_limits = kcalloc(n_limits, sizeof(*c0_limits), GFP_KERNEL);
|
||||||
|
if (!c0_limits)
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
|
||||||
|
c0_limits[i].max = 1 + rsdb;
|
||||||
|
c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
|
||||||
|
+ if (mon_flag) {
|
||||||
|
+ c0_limits[i].max = 1;
|
||||||
|
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
|
||||||
|
+ }
|
||||||
|
if (p2p) {
|
||||||
|
c0_limits[i].max = 1;
|
||||||
|
c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
|
||||||
|
@@ -6562,14 +6644,20 @@ static int brcmf_setup_ifmodes(struct wi
|
||||||
|
if (mbss) {
|
||||||
|
c++;
|
||||||
|
i = 0;
|
||||||
|
- mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
|
||||||
|
+ n_limits = 1 + mon_flag;
|
||||||
|
+ mbss_limits = kcalloc(n_limits, sizeof(*mbss_limits),
|
||||||
|
+ GFP_KERNEL);
|
||||||
|
if (!mbss_limits)
|
||||||
|
goto err;
|
||||||
|
mbss_limits[i].max = 4;
|
||||||
|
mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
|
||||||
|
+ if (mon_flag) {
|
||||||
|
+ mbss_limits[i].max = 1;
|
||||||
|
+ mbss_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
|
||||||
|
+ }
|
||||||
|
combo[c].beacon_int_infra_match = true;
|
||||||
|
combo[c].num_different_channels = 1;
|
||||||
|
- combo[c].max_interfaces = 4;
|
||||||
|
+ combo[c].max_interfaces = 4 + mon_flag;
|
||||||
|
combo[c].n_limits = i;
|
||||||
|
combo[c].limits = mbss_limits;
|
||||||
|
}
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||||
|
@@ -690,7 +690,7 @@ fail:
|
||||||
|
return -EBADE;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
|
||||||
|
+void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked)
|
||||||
|
{
|
||||||
|
if (ndev->reg_state == NETREG_REGISTERED) {
|
||||||
|
if (rtnl_locked)
|
||||||
|
@@ -703,6 +703,72 @@ static void brcmf_net_detach(struct net_
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int brcmf_net_mon_open(struct net_device *ndev)
|
||||||
|
+{
|
||||||
|
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
||||||
|
+ struct brcmf_pub *drvr = ifp->drvr;
|
||||||
|
+ u32 monitor;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ brcmf_dbg(TRACE, "Enter\n");
|
||||||
|
+
|
||||||
|
+ err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_MONITOR, &monitor);
|
||||||
|
+ if (err) {
|
||||||
|
+ bphy_err(drvr, "BRCMF_C_GET_MONITOR error (%d)\n", err);
|
||||||
|
+ return err;
|
||||||
|
+ } else if (monitor) {
|
||||||
|
+ bphy_err(drvr, "Monitor mode is already enabled\n");
|
||||||
|
+ return -EEXIST;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ monitor = 3;
|
||||||
|
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);
|
||||||
|
+ if (err)
|
||||||
|
+ bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int brcmf_net_mon_stop(struct net_device *ndev)
|
||||||
|
+{
|
||||||
|
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
||||||
|
+ struct brcmf_pub *drvr = ifp->drvr;
|
||||||
|
+ u32 monitor;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ brcmf_dbg(TRACE, "Enter\n");
|
||||||
|
+
|
||||||
|
+ monitor = 0;
|
||||||
|
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_MONITOR, monitor);
|
||||||
|
+ if (err)
|
||||||
|
+ bphy_err(drvr, "BRCMF_C_SET_MONITOR error (%d)\n", err);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static const struct net_device_ops brcmf_netdev_ops_mon = {
|
||||||
|
+ .ndo_open = brcmf_net_mon_open,
|
||||||
|
+ .ndo_stop = brcmf_net_mon_stop,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+int brcmf_net_mon_attach(struct brcmf_if *ifp)
|
||||||
|
+{
|
||||||
|
+ struct brcmf_pub *drvr = ifp->drvr;
|
||||||
|
+ struct net_device *ndev;
|
||||||
|
+ int err;
|
||||||
|
+
|
||||||
|
+ brcmf_dbg(TRACE, "Enter\n");
|
||||||
|
+
|
||||||
|
+ ndev = ifp->ndev;
|
||||||
|
+ ndev->netdev_ops = &brcmf_netdev_ops_mon;
|
||||||
|
+
|
||||||
|
+ err = register_netdevice(ndev);
|
||||||
|
+ if (err)
|
||||||
|
+ bphy_err(drvr, "Failed to register %s device\n", ndev->name);
|
||||||
|
+
|
||||||
|
+ return err;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
|
||||||
|
{
|
||||||
|
struct net_device *ndev;
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
|
||||||
|
@@ -210,6 +210,8 @@ void brcmf_txflowblock_if(struct brcmf_i
|
||||||
|
void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success);
|
||||||
|
void brcmf_netif_rx(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||||
|
void brcmf_netif_mon_rx(struct brcmf_if *ifp, struct sk_buff *skb);
|
||||||
|
+void brcmf_net_detach(struct net_device *ndev, bool rtnl_locked);
|
||||||
|
+int brcmf_net_mon_attach(struct brcmf_if *ifp);
|
||||||
|
void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on);
|
||||||
|
int __init brcmf_core_init(void);
|
||||||
|
void __exit brcmf_core_exit(void);
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c
|
||||||
|
@@ -38,6 +38,7 @@ static const struct brcmf_feat_fwcap brc
|
||||||
|
{ BRCMF_FEAT_MCHAN, "mchan" },
|
||||||
|
{ BRCMF_FEAT_P2P, "p2p" },
|
||||||
|
{ BRCMF_FEAT_MONITOR, "monitor" },
|
||||||
|
+ { BRCMF_FEAT_MONITOR_FLAG, "rtap" },
|
||||||
|
{ BRCMF_FEAT_MONITOR_FMT_RADIOTAP, "rtap" },
|
||||||
|
{ BRCMF_FEAT_DOT11H, "802.11h" }
|
||||||
|
};
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h
|
||||||
|
@@ -23,6 +23,7 @@
|
||||||
|
* GSCAN: enhanced scan offload feature.
|
||||||
|
* FWSUP: Firmware supplicant.
|
||||||
|
* MONITOR: firmware can pass monitor packets to host.
|
||||||
|
+ * MONITOR_FLAG: firmware flags monitor packets.
|
||||||
|
* MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header
|
||||||
|
* MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header
|
||||||
|
* DOT11H: firmware supports 802.11h
|
||||||
|
@@ -43,6 +44,7 @@
|
||||||
|
BRCMF_FEAT_DEF(GSCAN) \
|
||||||
|
BRCMF_FEAT_DEF(FWSUP) \
|
||||||
|
BRCMF_FEAT_DEF(MONITOR) \
|
||||||
|
+ BRCMF_FEAT_DEF(MONITOR_FLAG) \
|
||||||
|
BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \
|
||||||
|
BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) \
|
||||||
|
BRCMF_FEAT_DEF(DOT11H)
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
|
||||||
|
@@ -49,6 +49,8 @@
|
||||||
|
#define BRCMF_C_GET_PM 85
|
||||||
|
#define BRCMF_C_SET_PM 86
|
||||||
|
#define BRCMF_C_GET_REVINFO 98
|
||||||
|
+#define BRCMF_C_GET_MONITOR 107
|
||||||
|
+#define BRCMF_C_SET_MONITOR 108
|
||||||
|
#define BRCMF_C_GET_CURR_RATESET 114
|
||||||
|
#define BRCMF_C_GET_AP 117
|
||||||
|
#define BRCMF_C_SET_AP 118
|
|
@ -0,0 +1,24 @@
|
||||||
|
From 627b0d094240c38393b2f2d40626c33a8fff6103 Mon Sep 17 00:00:00 2001
|
||||||
|
From: yuehaibing <yuehaibing@huawei.com>
|
||||||
|
Date: Wed, 8 Jan 2020 21:57:48 +0800
|
||||||
|
Subject: [PATCH] brcmfmac: Remove always false 'idx < 0' statement
|
||||||
|
|
||||||
|
idx is declared as u32, it will never less than 0.
|
||||||
|
|
||||||
|
Signed-off-by: yuehaibing <yuehaibing@huawei.com>
|
||||||
|
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||||
|
---
|
||||||
|
drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +-
|
||||||
|
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||||
|
|
||||||
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||||
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c
|
||||||
|
@@ -365,7 +365,7 @@ brcmf_msgbuf_get_pktid(struct device *de
|
||||||
|
struct brcmf_msgbuf_pktid *pktid;
|
||||||
|
struct sk_buff *skb;
|
||||||
|
|
||||||
|
- if (idx < 0 || idx >= pktids->array_size) {
|
||||||
|
+ if (idx >= pktids->array_size) {
|
||||||
|
brcmf_err("Invalid packet id %d (max %d)\n", idx,
|
||||||
|
pktids->array_size);
|
||||||
|
return NULL;
|
|
@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||||
|
|
||||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
|
||||||
@@ -1479,6 +1479,7 @@ int __init brcmf_core_init(void)
|
@@ -1545,6 +1545,7 @@ int __init brcmf_core_init(void)
|
||||||
{
|
{
|
||||||
if (!schedule_work(&brcmf_driver_work))
|
if (!schedule_work(&brcmf_driver_work))
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
|
|
|
@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||||
|
|
||||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||||
@@ -628,8 +628,36 @@ static struct wireless_dev *brcmf_cfg802
|
@@ -705,8 +705,36 @@ static struct wireless_dev *brcmf_cfg802
|
||||||
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||||
struct brcmf_pub *drvr = cfg->pub;
|
struct brcmf_pub *drvr = cfg->pub;
|
||||||
struct wireless_dev *wdev;
|
struct wireless_dev *wdev;
|
||||||
|
|
|
@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
|
||||||
|
|
||||||
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||||
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
|
||||||
@@ -2795,6 +2795,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
|
@@ -2874,6 +2874,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
|
||||||
* preference in cfg struct to apply this to
|
* preference in cfg struct to apply this to
|
||||||
* FW later while initializing the dongle
|
* FW later while initializing the dongle
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in New Issue
Block a user