mirror of
https://github.com/hak5/wifipineapple-openwrt.git
synced 2025-10-29 16:57:19 +00:00
mac80211: brcmfmac: support dumping stations
It allows user-space fetch associated STAs and e.g. iwinfo/luci display them. git-svn-id: svn://svn.openwrt.org/openwrt/branches/chaos_calmer@48167 3c298f89-4303-0410-b956-a3cf2f4a3e73
This commit is contained in:
parent
615ff23d4f
commit
acad802bce
@ -0,0 +1,23 @@
|
||||
From: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
Date: Sat, 19 Sep 2015 12:47:20 +0200
|
||||
Subject: [PATCH] brcmfmac: include linux/atomic.h
|
||||
|
||||
brcmfmac uses atomic_or() and other atomic_* functions, but does not
|
||||
include linux/atomic.h. This file gets included by some other header
|
||||
file so this normally does not cause problems.
|
||||
|
||||
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
|
||||
Acked-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
|
||||
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/types.h>
|
||||
+#include <linux/atomic.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/printk.h>
|
||||
@ -0,0 +1,347 @@
|
||||
From: Arend van Spriel <arend@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:11 +0200
|
||||
Subject: [PATCH] brcmfmac: expose device memory to devcoredump subsystem
|
||||
|
||||
Upon PSM watchdog event received from firmware the driver will obtain
|
||||
a memory snapshot of the device and expose it to user-space through
|
||||
the devcoredump framework. This will trigger a uevent.
|
||||
|
||||
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/Kconfig
|
||||
+++ b/drivers/net/wireless/brcm80211/Kconfig
|
||||
@@ -85,5 +85,6 @@ config BRCM_TRACING
|
||||
config BRCMDBG
|
||||
bool "Broadcom driver debug functions"
|
||||
depends on BRCMSMAC || BRCMFMAC
|
||||
+ select WANT_DEV_COREDUMP
|
||||
---help---
|
||||
Selecting this enables additional code for debug purposes.
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/bus.h
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bus.h
|
||||
@@ -65,6 +65,8 @@ struct brcmf_bus_dcmd {
|
||||
* @rxctl: receive a control response message from dongle.
|
||||
* @gettxq: obtain a reference of bus transmit queue (optional).
|
||||
* @wowl_config: specify if dongle is configured for wowl when going to suspend
|
||||
+ * @get_ramsize: obtain size of device memory.
|
||||
+ * @get_memdump: obtain device memory dump in provided buffer.
|
||||
*
|
||||
* This structure provides an abstract interface towards the
|
||||
* bus specific driver. For control messages to common driver
|
||||
@@ -79,6 +81,8 @@ struct brcmf_bus_ops {
|
||||
int (*rxctl)(struct device *dev, unsigned char *msg, uint len);
|
||||
struct pktq * (*gettxq)(struct device *dev);
|
||||
void (*wowl_config)(struct device *dev, bool enabled);
|
||||
+ size_t (*get_ramsize)(struct device *dev);
|
||||
+ int (*get_memdump)(struct device *dev, void *data, size_t len);
|
||||
};
|
||||
|
||||
|
||||
@@ -185,6 +189,23 @@ void brcmf_bus_wowl_config(struct brcmf_
|
||||
bus->ops->wowl_config(bus->dev, enabled);
|
||||
}
|
||||
|
||||
+static inline size_t brcmf_bus_get_ramsize(struct brcmf_bus *bus)
|
||||
+{
|
||||
+ if (!bus->ops->get_ramsize)
|
||||
+ return 0;
|
||||
+
|
||||
+ return bus->ops->get_ramsize(bus->dev);
|
||||
+}
|
||||
+
|
||||
+static inline
|
||||
+int brcmf_bus_get_memdump(struct brcmf_bus *bus, void *data, size_t len)
|
||||
+{
|
||||
+ if (!bus->ops->get_memdump)
|
||||
+ return -EOPNOTSUPP;
|
||||
+
|
||||
+ return bus->ops->get_memdump(bus->dev, data, len);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* interface functions from common layer
|
||||
*/
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
@@ -957,8 +957,8 @@ int brcmf_attach(struct device *dev)
|
||||
drvr->bus_if = dev_get_drvdata(dev);
|
||||
drvr->bus_if->drvr = drvr;
|
||||
|
||||
- /* create device debugfs folder */
|
||||
- brcmf_debugfs_attach(drvr);
|
||||
+ /* attach debug facilities */
|
||||
+ brcmf_debug_attach(drvr);
|
||||
|
||||
/* Attach and link in the protocol */
|
||||
ret = brcmf_proto_attach(drvr);
|
||||
@@ -1155,7 +1155,7 @@ void brcmf_detach(struct device *dev)
|
||||
|
||||
brcmf_proto_detach(drvr);
|
||||
|
||||
- brcmf_debugfs_detach(drvr);
|
||||
+ brcmf_debug_detach(drvr);
|
||||
bus_if->drvr = NULL;
|
||||
kfree(drvr);
|
||||
}
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.c
|
||||
@@ -16,15 +16,45 @@
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/netdevice.h>
|
||||
#include <linux/module.h>
|
||||
+#include <linux/devcoredump.h>
|
||||
|
||||
#include <brcmu_wifi.h>
|
||||
#include <brcmu_utils.h>
|
||||
#include "core.h"
|
||||
#include "bus.h"
|
||||
+#include "fweh.h"
|
||||
#include "debug.h"
|
||||
|
||||
static struct dentry *root_folder;
|
||||
|
||||
+static int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data,
|
||||
+ size_t len)
|
||||
+{
|
||||
+ void *dump;
|
||||
+ size_t ramsize;
|
||||
+
|
||||
+ ramsize = brcmf_bus_get_ramsize(bus);
|
||||
+ if (ramsize) {
|
||||
+ dump = vzalloc(len + ramsize);
|
||||
+ if (!dump)
|
||||
+ return -ENOMEM;
|
||||
+ memcpy(dump, data, len);
|
||||
+ brcmf_bus_get_memdump(bus, dump + len, ramsize);
|
||||
+ dev_coredumpv(bus->dev, dump, len + ramsize, GFP_KERNEL);
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_debug_psm_watchdog_notify(struct brcmf_if *ifp,
|
||||
+ const struct brcmf_event_msg *evtmsg,
|
||||
+ void *data)
|
||||
+{
|
||||
+ brcmf_dbg(TRACE, "enter: idx=%d\n", ifp->bssidx);
|
||||
+
|
||||
+ return brcmf_debug_create_memdump(ifp->drvr->bus_if, data,
|
||||
+ evtmsg->datalen);
|
||||
+}
|
||||
+
|
||||
void brcmf_debugfs_init(void)
|
||||
{
|
||||
root_folder = debugfs_create_dir(KBUILD_MODNAME, NULL);
|
||||
@@ -41,7 +71,7 @@ void brcmf_debugfs_exit(void)
|
||||
root_folder = NULL;
|
||||
}
|
||||
|
||||
-int brcmf_debugfs_attach(struct brcmf_pub *drvr)
|
||||
+int brcmf_debug_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
struct device *dev = drvr->bus_if->dev;
|
||||
|
||||
@@ -49,12 +79,18 @@ int brcmf_debugfs_attach(struct brcmf_pu
|
||||
return -ENODEV;
|
||||
|
||||
drvr->dbgfs_dir = debugfs_create_dir(dev_name(dev), root_folder);
|
||||
+ if (IS_ERR(drvr->dbgfs_dir))
|
||||
+ return PTR_ERR(drvr->dbgfs_dir);
|
||||
|
||||
- return PTR_ERR_OR_ZERO(drvr->dbgfs_dir);
|
||||
+
|
||||
+ return brcmf_fweh_register(drvr, BRCMF_E_PSM_WATCHDOG,
|
||||
+ brcmf_debug_psm_watchdog_notify);
|
||||
}
|
||||
|
||||
-void brcmf_debugfs_detach(struct brcmf_pub *drvr)
|
||||
+void brcmf_debug_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
+ brcmf_fweh_unregister(drvr, BRCMF_E_PSM_WATCHDOG);
|
||||
+
|
||||
if (!IS_ERR_OR_NULL(drvr->dbgfs_dir))
|
||||
debugfs_remove_recursive(drvr->dbgfs_dir);
|
||||
}
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.h
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h
|
||||
@@ -109,8 +109,8 @@ struct brcmf_pub;
|
||||
#ifdef DEBUG
|
||||
void brcmf_debugfs_init(void);
|
||||
void brcmf_debugfs_exit(void);
|
||||
-int brcmf_debugfs_attach(struct brcmf_pub *drvr);
|
||||
-void brcmf_debugfs_detach(struct brcmf_pub *drvr);
|
||||
+int brcmf_debug_attach(struct brcmf_pub *drvr);
|
||||
+void brcmf_debug_detach(struct brcmf_pub *drvr);
|
||||
struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr);
|
||||
int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn,
|
||||
int (*read_fn)(struct seq_file *seq, void *data));
|
||||
@@ -121,11 +121,11 @@ static inline void brcmf_debugfs_init(vo
|
||||
static inline void brcmf_debugfs_exit(void)
|
||||
{
|
||||
}
|
||||
-static inline int brcmf_debugfs_attach(struct brcmf_pub *drvr)
|
||||
+static inline int brcmf_debug_attach(struct brcmf_pub *drvr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
-static inline void brcmf_debugfs_detach(struct brcmf_pub *drvr)
|
||||
+static inline void brcmf_debug_detach(struct brcmf_pub *drvr)
|
||||
{
|
||||
}
|
||||
static inline
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
|
||||
@@ -448,6 +448,47 @@ brcmf_pcie_copy_mem_todev(struct brcmf_p
|
||||
}
|
||||
|
||||
|
||||
+static void
|
||||
+brcmf_pcie_copy_dev_tomem(struct brcmf_pciedev_info *devinfo, u32 mem_offset,
|
||||
+ void *dstaddr, u32 len)
|
||||
+{
|
||||
+ void __iomem *address = devinfo->tcm + mem_offset;
|
||||
+ __le32 *dst32;
|
||||
+ __le16 *dst16;
|
||||
+ u8 *dst8;
|
||||
+
|
||||
+ if (((ulong)address & 4) || ((ulong)dstaddr & 4) || (len & 4)) {
|
||||
+ if (((ulong)address & 2) || ((ulong)dstaddr & 2) || (len & 2)) {
|
||||
+ dst8 = (u8 *)dstaddr;
|
||||
+ while (len) {
|
||||
+ *dst8 = ioread8(address);
|
||||
+ address++;
|
||||
+ dst8++;
|
||||
+ len--;
|
||||
+ }
|
||||
+ } else {
|
||||
+ len = len / 2;
|
||||
+ dst16 = (__le16 *)dstaddr;
|
||||
+ while (len) {
|
||||
+ *dst16 = cpu_to_le16(ioread16(address));
|
||||
+ address += 2;
|
||||
+ dst16++;
|
||||
+ len--;
|
||||
+ }
|
||||
+ }
|
||||
+ } else {
|
||||
+ len = len / 4;
|
||||
+ dst32 = (__le32 *)dstaddr;
|
||||
+ while (len) {
|
||||
+ *dst32 = cpu_to_le32(ioread32(address));
|
||||
+ address += 4;
|
||||
+ dst32++;
|
||||
+ len--;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+
|
||||
#define WRITECC32(devinfo, reg, value) brcmf_pcie_write_reg32(devinfo, \
|
||||
CHIPCREGOFFS(reg), value)
|
||||
|
||||
@@ -1352,12 +1393,36 @@ static void brcmf_pcie_wowl_config(struc
|
||||
}
|
||||
|
||||
|
||||
+static size_t brcmf_pcie_get_ramsize(struct device *dev)
|
||||
+{
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
|
||||
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
|
||||
+
|
||||
+ return devinfo->ci->ramsize - devinfo->ci->srsize;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int brcmf_pcie_get_memdump(struct device *dev, void *data, size_t len)
|
||||
+{
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie;
|
||||
+ struct brcmf_pciedev_info *devinfo = buspub->devinfo;
|
||||
+
|
||||
+ brcmf_dbg(PCIE, "dump at 0x%08X: len=%zu\n", devinfo->ci->rambase, len);
|
||||
+ brcmf_pcie_copy_dev_tomem(devinfo, devinfo->ci->rambase, data, len);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static struct brcmf_bus_ops brcmf_pcie_bus_ops = {
|
||||
.txdata = brcmf_pcie_tx,
|
||||
.stop = brcmf_pcie_down,
|
||||
.txctl = brcmf_pcie_tx_ctlpkt,
|
||||
.rxctl = brcmf_pcie_rx_ctlpkt,
|
||||
.wowl_config = brcmf_pcie_wowl_config,
|
||||
+ .get_ramsize = brcmf_pcie_get_ramsize,
|
||||
+ .get_memdump = brcmf_pcie_get_memdump,
|
||||
};
|
||||
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
|
||||
@@ -3539,6 +3539,51 @@ done:
|
||||
return err;
|
||||
}
|
||||
|
||||
+static size_t brcmf_sdio_bus_get_ramsize(struct device *dev)
|
||||
+{
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
+ struct brcmf_sdio *bus = sdiodev->bus;
|
||||
+
|
||||
+ return bus->ci->ramsize - bus->ci->srsize;
|
||||
+}
|
||||
+
|
||||
+static int brcmf_sdio_bus_get_memdump(struct device *dev, void *data,
|
||||
+ size_t mem_size)
|
||||
+{
|
||||
+ struct brcmf_bus *bus_if = dev_get_drvdata(dev);
|
||||
+ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
|
||||
+ struct brcmf_sdio *bus = sdiodev->bus;
|
||||
+ int err;
|
||||
+ int address;
|
||||
+ int offset;
|
||||
+ int len;
|
||||
+
|
||||
+ brcmf_dbg(INFO, "dump at 0x%08x: size=%zu\n", bus->ci->rambase,
|
||||
+ mem_size);
|
||||
+
|
||||
+ address = bus->ci->rambase;
|
||||
+ offset = err = 0;
|
||||
+ sdio_claim_host(sdiodev->func[1]);
|
||||
+ while (offset < mem_size) {
|
||||
+ len = ((offset + MEMBLOCK) < mem_size) ? MEMBLOCK :
|
||||
+ mem_size - offset;
|
||||
+ err = brcmf_sdiod_ramrw(sdiodev, false, address, data, len);
|
||||
+ if (err) {
|
||||
+ brcmf_err("error %d on reading %d membytes at 0x%08x\n",
|
||||
+ err, len, address);
|
||||
+ goto done;
|
||||
+ }
|
||||
+ data += len;
|
||||
+ offset += len;
|
||||
+ address += len;
|
||||
+ }
|
||||
+
|
||||
+done:
|
||||
+ sdio_release_host(sdiodev->func[1]);
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus)
|
||||
{
|
||||
if (!bus->dpc_triggered) {
|
||||
@@ -3987,7 +4032,9 @@ static struct brcmf_bus_ops brcmf_sdio_b
|
||||
.txctl = brcmf_sdio_bus_txctl,
|
||||
.rxctl = brcmf_sdio_bus_rxctl,
|
||||
.gettxq = brcmf_sdio_bus_gettxq,
|
||||
- .wowl_config = brcmf_sdio_wowl_config
|
||||
+ .wowl_config = brcmf_sdio_wowl_config,
|
||||
+ .get_ramsize = brcmf_sdio_bus_get_ramsize,
|
||||
+ .get_memdump = brcmf_sdio_bus_get_memdump,
|
||||
};
|
||||
|
||||
static void brcmf_sdio_firmware_callback(struct device *dev,
|
||||
@ -0,0 +1,108 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:12 +0200
|
||||
Subject: [PATCH] brcmfmac: Fix race condition between USB probe/load and
|
||||
disconnect.
|
||||
|
||||
When a USB device gets disconnected due to for example removal
|
||||
then it is possible that it is still in the loading phase due to
|
||||
the asynchronous load routines. These routines can then possible
|
||||
access memory which has been freed. Fix this by mutex locking the
|
||||
device init phase.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
|
||||
@@ -144,6 +144,7 @@ struct brcmf_usbdev_info {
|
||||
|
||||
struct usb_device *usbdev;
|
||||
struct device *dev;
|
||||
+ struct mutex dev_init_lock;
|
||||
|
||||
int ctl_in_pipe, ctl_out_pipe;
|
||||
struct urb *ctl_urb; /* URB for control endpoint */
|
||||
@@ -1204,6 +1205,8 @@ static void brcmf_usb_probe_phase2(struc
|
||||
int ret;
|
||||
|
||||
brcmf_dbg(USB, "Start fw downloading\n");
|
||||
+
|
||||
+ devinfo = bus->bus_priv.usb->devinfo;
|
||||
ret = check_file(fw->data);
|
||||
if (ret < 0) {
|
||||
brcmf_err("invalid firmware\n");
|
||||
@@ -1211,7 +1214,6 @@ static void brcmf_usb_probe_phase2(struc
|
||||
goto error;
|
||||
}
|
||||
|
||||
- devinfo = bus->bus_priv.usb->devinfo;
|
||||
devinfo->image = fw->data;
|
||||
devinfo->image_len = fw->size;
|
||||
|
||||
@@ -1224,9 +1226,11 @@ static void brcmf_usb_probe_phase2(struc
|
||||
if (ret)
|
||||
goto error;
|
||||
|
||||
+ mutex_unlock(&devinfo->dev_init_lock);
|
||||
return;
|
||||
error:
|
||||
brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret);
|
||||
+ mutex_unlock(&devinfo->dev_init_lock);
|
||||
device_release_driver(dev);
|
||||
}
|
||||
|
||||
@@ -1264,6 +1268,7 @@ static int brcmf_usb_probe_cb(struct brc
|
||||
if (ret)
|
||||
goto fail;
|
||||
/* we are done */
|
||||
+ mutex_unlock(&devinfo->dev_init_lock);
|
||||
return 0;
|
||||
}
|
||||
bus->chip = bus_pub->devid;
|
||||
@@ -1317,6 +1322,12 @@ brcmf_usb_probe(struct usb_interface *in
|
||||
|
||||
devinfo->usbdev = usb;
|
||||
devinfo->dev = &usb->dev;
|
||||
+ /* Take an init lock, to protect for disconnect while still loading.
|
||||
+ * Necessary because of the asynchronous firmware load construction
|
||||
+ */
|
||||
+ mutex_init(&devinfo->dev_init_lock);
|
||||
+ mutex_lock(&devinfo->dev_init_lock);
|
||||
+
|
||||
usb_set_intfdata(intf, devinfo);
|
||||
|
||||
/* Check that the device supports only one configuration */
|
||||
@@ -1391,6 +1402,7 @@ brcmf_usb_probe(struct usb_interface *in
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
+ mutex_unlock(&devinfo->dev_init_lock);
|
||||
kfree(devinfo);
|
||||
usb_set_intfdata(intf, NULL);
|
||||
return ret;
|
||||
@@ -1403,8 +1415,19 @@ brcmf_usb_disconnect(struct usb_interfac
|
||||
|
||||
brcmf_dbg(USB, "Enter\n");
|
||||
devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf);
|
||||
- brcmf_usb_disconnect_cb(devinfo);
|
||||
- kfree(devinfo);
|
||||
+
|
||||
+ if (devinfo) {
|
||||
+ mutex_lock(&devinfo->dev_init_lock);
|
||||
+ /* Make sure that devinfo still exists. Firmware probe routines
|
||||
+ * may have released the device and cleared the intfdata.
|
||||
+ */
|
||||
+ if (!usb_get_intfdata(intf))
|
||||
+ goto done;
|
||||
+
|
||||
+ brcmf_usb_disconnect_cb(devinfo);
|
||||
+ kfree(devinfo);
|
||||
+ }
|
||||
+done:
|
||||
brcmf_dbg(USB, "Exit\n");
|
||||
}
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
From: Franky Lin <frankyl@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:13 +0200
|
||||
Subject: [PATCH] brcmfmac: rename firmware_path to alternative_fw_path
|
||||
|
||||
In brcmfmac the module parameter "firmware_path" is used as an
|
||||
alternative relative path under the search path used by firmware_class
|
||||
or ueventhelper. Rename the parameter to alternative_fw_path to avoid
|
||||
confusion.
|
||||
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Franky Lin <frankyl@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
|
||||
@@ -28,7 +28,7 @@
|
||||
#define BRCMF_FW_NVRAM_PCIEDEV_LEN 10 /* pcie/1/4/ + \0 */
|
||||
|
||||
char brcmf_firmware_path[BRCMF_FW_PATH_LEN];
|
||||
-module_param_string(firmware_path, brcmf_firmware_path,
|
||||
+module_param_string(alternative_fw_path, brcmf_firmware_path,
|
||||
BRCMF_FW_PATH_LEN, 0440);
|
||||
|
||||
enum nvram_parser_state {
|
||||
@ -0,0 +1,25 @@
|
||||
From: Arend van Spriel <arend@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:14 +0200
|
||||
Subject: [PATCH] brcmfmac: remove conversational comment
|
||||
|
||||
Removing a comment that was only useful during the review of
|
||||
the change that introduced it and which should never have been
|
||||
submitted.
|
||||
|
||||
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
|
||||
@@ -873,9 +873,6 @@ brcmf_msgbuf_process_txstatus(struct brc
|
||||
commonring = msgbuf->flowrings[flowid];
|
||||
atomic_dec(&commonring->outstanding_tx);
|
||||
|
||||
- /* Hante: i believe this was a bug as tx_status->msg.ifidx was used
|
||||
- * in brcmf_txfinalize as index in drvr->iflist. Can you confirm/deny?
|
||||
- */
|
||||
brcmf_txfinalize(brcmf_get_ifp(msgbuf->drvr, tx_status->msg.ifidx),
|
||||
skb, true);
|
||||
}
|
||||
@ -0,0 +1,226 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:15 +0200
|
||||
Subject: [PATCH] brcmfmac: Rework p2p attach, use single method for p2p dev
|
||||
creation.
|
||||
|
||||
When module param p2pon is used a p2p device is created at init.
|
||||
This patch reworks how this is done by using the same method as
|
||||
for a dynamically (by user space) created p2p device.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -6237,6 +6237,17 @@ struct brcmf_cfg80211_info *brcmf_cfg802
|
||||
else
|
||||
*cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
|
||||
}
|
||||
+ /* p2p might require that "if-events" get processed by fweh. So
|
||||
+ * activate the already registered event handlers now and activate
|
||||
+ * the rest when initialization has completed. drvr->config needs to
|
||||
+ * be assigned before activating events.
|
||||
+ */
|
||||
+ drvr->config = cfg;
|
||||
+ err = brcmf_fweh_activate_events(ifp);
|
||||
+ if (err) {
|
||||
+ brcmf_err("FWEH activation failed (%d)\n", err);
|
||||
+ goto wiphy_unreg_out;
|
||||
+ }
|
||||
|
||||
err = brcmf_p2p_attach(cfg, p2pdev_forced);
|
||||
if (err) {
|
||||
@@ -6259,6 +6270,13 @@ struct brcmf_cfg80211_info *brcmf_cfg802
|
||||
brcmf_notify_tdls_peer_event);
|
||||
}
|
||||
|
||||
+ /* (re-) activate FWEH event handling */
|
||||
+ err = brcmf_fweh_activate_events(ifp);
|
||||
+ if (err) {
|
||||
+ brcmf_err("FWEH activation failed (%d)\n", err);
|
||||
+ goto wiphy_unreg_out;
|
||||
+ }
|
||||
+
|
||||
return cfg;
|
||||
|
||||
wiphy_unreg_out:
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
@@ -828,8 +828,8 @@ struct brcmf_if *brcmf_add_if(struct brc
|
||||
} else {
|
||||
brcmf_dbg(INFO, "allocate netdev interface\n");
|
||||
/* Allocate netdev, including space for private structure */
|
||||
- ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN,
|
||||
- ether_setup);
|
||||
+ ndev = alloc_netdev(sizeof(*ifp), is_p2pdev ? "p2p%d" : name,
|
||||
+ NET_NAME_UNKNOWN, ether_setup);
|
||||
if (!ndev)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@@ -1021,12 +1021,7 @@ int brcmf_bus_start(struct device *dev)
|
||||
if (IS_ERR(ifp))
|
||||
return PTR_ERR(ifp);
|
||||
|
||||
- if (brcmf_p2p_enable)
|
||||
- p2p_ifp = brcmf_add_if(drvr, 1, 0, false, "p2p%d", NULL);
|
||||
- else
|
||||
- p2p_ifp = NULL;
|
||||
- if (IS_ERR(p2p_ifp))
|
||||
- p2p_ifp = NULL;
|
||||
+ p2p_ifp = NULL;
|
||||
|
||||
/* signal bus ready */
|
||||
brcmf_bus_change_state(bus_if, BRCMF_BUS_UP);
|
||||
@@ -1060,11 +1055,13 @@ int brcmf_bus_start(struct device *dev)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
- ret = brcmf_fweh_activate_events(ifp);
|
||||
- if (ret < 0)
|
||||
- goto fail;
|
||||
-
|
||||
ret = brcmf_net_attach(ifp, false);
|
||||
+
|
||||
+ if ((!ret) && (brcmf_p2p_enable)) {
|
||||
+ p2p_ifp = drvr->iflist[1];
|
||||
+ if (p2p_ifp)
|
||||
+ ret = brcmf_net_p2p_attach(p2p_ifp);
|
||||
+ }
|
||||
fail:
|
||||
if (ret < 0) {
|
||||
brcmf_err("failed: %d\n", ret);
|
||||
@@ -1076,20 +1073,12 @@ fail:
|
||||
brcmf_fws_del_interface(ifp);
|
||||
brcmf_fws_deinit(drvr);
|
||||
}
|
||||
- if (drvr->iflist[0]) {
|
||||
+ if (ifp)
|
||||
brcmf_net_detach(ifp->ndev);
|
||||
- drvr->iflist[0] = NULL;
|
||||
- }
|
||||
- if (p2p_ifp) {
|
||||
+ if (p2p_ifp)
|
||||
brcmf_net_detach(p2p_ifp->ndev);
|
||||
- drvr->iflist[1] = NULL;
|
||||
- }
|
||||
return ret;
|
||||
}
|
||||
- if ((brcmf_p2p_enable) && (p2p_ifp))
|
||||
- if (brcmf_net_p2p_attach(p2p_ifp) < 0)
|
||||
- brcmf_p2p_enable = 0;
|
||||
-
|
||||
return 0;
|
||||
}
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
|
||||
@@ -213,7 +213,8 @@ static void brcmf_fweh_handle_if_event(s
|
||||
is_p2pdev, emsg->ifname, emsg->addr);
|
||||
if (IS_ERR(ifp))
|
||||
return;
|
||||
- brcmf_fws_add_interface(ifp);
|
||||
+ if (!is_p2pdev)
|
||||
+ brcmf_fws_add_interface(ifp);
|
||||
if (!drvr->fweh.evt_handler[BRCMF_E_IF])
|
||||
if (brcmf_net_attach(ifp, false) < 0)
|
||||
return;
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
|
||||
@@ -2350,83 +2350,30 @@ void brcmf_p2p_stop_device(struct wiphy
|
||||
* brcmf_p2p_attach() - attach for P2P.
|
||||
*
|
||||
* @cfg: driver private data for cfg80211 interface.
|
||||
+ * @p2pdev_forced: create p2p device interface at attach.
|
||||
*/
|
||||
s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced)
|
||||
{
|
||||
- struct brcmf_if *pri_ifp;
|
||||
- struct brcmf_if *p2p_ifp;
|
||||
- struct brcmf_cfg80211_vif *p2p_vif;
|
||||
struct brcmf_p2p_info *p2p;
|
||||
- struct brcmf_pub *drvr;
|
||||
- s32 bssidx;
|
||||
+ struct brcmf_if *pri_ifp;
|
||||
s32 err = 0;
|
||||
+ void *err_ptr;
|
||||
|
||||
p2p = &cfg->p2p;
|
||||
p2p->cfg = cfg;
|
||||
|
||||
- drvr = cfg->pub;
|
||||
-
|
||||
- pri_ifp = brcmf_get_ifp(drvr, 0);
|
||||
+ pri_ifp = brcmf_get_ifp(cfg->pub, 0);
|
||||
p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif = pri_ifp->vif;
|
||||
|
||||
if (p2pdev_forced) {
|
||||
- p2p_ifp = drvr->iflist[1];
|
||||
+ err_ptr = brcmf_p2p_create_p2pdev(p2p, NULL, NULL);
|
||||
+ if (IS_ERR(err_ptr)) {
|
||||
+ brcmf_err("P2P device creation failed.\n");
|
||||
+ err = PTR_ERR(err_ptr);
|
||||
+ }
|
||||
} else {
|
||||
- p2p_ifp = NULL;
|
||||
p2p->p2pdev_dynamically = true;
|
||||
}
|
||||
- if (p2p_ifp) {
|
||||
- p2p_vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_P2P_DEVICE,
|
||||
- false);
|
||||
- if (IS_ERR(p2p_vif)) {
|
||||
- brcmf_err("could not create discovery vif\n");
|
||||
- err = -ENOMEM;
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
- p2p_vif->ifp = p2p_ifp;
|
||||
- p2p_ifp->vif = p2p_vif;
|
||||
- p2p_vif->wdev.netdev = p2p_ifp->ndev;
|
||||
- p2p_ifp->ndev->ieee80211_ptr = &p2p_vif->wdev;
|
||||
- SET_NETDEV_DEV(p2p_ifp->ndev, wiphy_dev(cfg->wiphy));
|
||||
-
|
||||
- p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = p2p_vif;
|
||||
-
|
||||
- brcmf_p2p_generate_bss_mac(p2p, NULL);
|
||||
- memcpy(p2p_ifp->mac_addr, p2p->dev_addr, ETH_ALEN);
|
||||
- brcmf_p2p_set_firmware(pri_ifp, p2p->dev_addr);
|
||||
-
|
||||
- brcmf_fweh_p2pdev_setup(pri_ifp, true);
|
||||
-
|
||||
- /* Initialize P2P Discovery in the firmware */
|
||||
- err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1);
|
||||
- if (err < 0) {
|
||||
- brcmf_err("set p2p_disc error\n");
|
||||
- brcmf_free_vif(p2p_vif);
|
||||
- goto exit;
|
||||
- }
|
||||
- /* obtain bsscfg index for P2P discovery */
|
||||
- err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bssidx);
|
||||
- if (err < 0) {
|
||||
- brcmf_err("retrieving discover bsscfg index failed\n");
|
||||
- brcmf_free_vif(p2p_vif);
|
||||
- goto exit;
|
||||
- }
|
||||
- /* Verify that firmware uses same bssidx as driver !! */
|
||||
- if (p2p_ifp->bssidx != bssidx) {
|
||||
- brcmf_err("Incorrect bssidx=%d, compared to p2p_ifp->bssidx=%d\n",
|
||||
- bssidx, p2p_ifp->bssidx);
|
||||
- brcmf_free_vif(p2p_vif);
|
||||
- goto exit;
|
||||
- }
|
||||
-
|
||||
- init_completion(&p2p->send_af_done);
|
||||
- INIT_WORK(&p2p->afx_hdl.afx_work, brcmf_p2p_afx_handler);
|
||||
- init_completion(&p2p->afx_hdl.act_frm_scan);
|
||||
- init_completion(&p2p->wait_next_af);
|
||||
-exit:
|
||||
- brcmf_fweh_p2pdev_setup(pri_ifp, false);
|
||||
- }
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:16 +0200
|
||||
Subject: [PATCH] brcmfmac: Fix station info rate information.
|
||||
|
||||
Txrate and rxrate in get_station got assigned first with value
|
||||
in kbps and then divided by 100 to get it in 100kbps unit. The
|
||||
problem with that is that type of rate is u16 which resulted
|
||||
in incorrect values for high data rate values.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2477,13 +2477,13 @@ brcmf_cfg80211_get_station(struct wiphy
|
||||
sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
|
||||
if (sinfo->tx_packets) {
|
||||
sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
|
||||
- sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate);
|
||||
- sinfo->txrate.legacy /= 100;
|
||||
+ sinfo->txrate.legacy =
|
||||
+ le32_to_cpu(sta_info_le.tx_rate) / 100;
|
||||
}
|
||||
if (sinfo->rx_packets) {
|
||||
sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
|
||||
- sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate);
|
||||
- sinfo->rxrate.legacy /= 100;
|
||||
+ sinfo->rxrate.legacy =
|
||||
+ le32_to_cpu(sta_info_le.rx_rate) / 100;
|
||||
}
|
||||
if (le16_to_cpu(sta_info_le.ver) >= 4) {
|
||||
sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
|
||||
@ -0,0 +1,50 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:17 +0200
|
||||
Subject: [PATCH] brcmfmac: Add RSSI information to get_station.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2431,6 +2431,9 @@ brcmf_cfg80211_get_station(struct wiphy
|
||||
struct brcmf_sta_info_le sta_info_le;
|
||||
u32 sta_flags;
|
||||
u32 is_tdls_peer;
|
||||
+ s32 total_rssi;
|
||||
+ s32 count_rssi;
|
||||
+ u32 i;
|
||||
|
||||
brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
|
||||
if (!check_vif_up(ifp->vif))
|
||||
@@ -2491,6 +2494,26 @@ brcmf_cfg80211_get_station(struct wiphy
|
||||
sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
|
||||
sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
|
||||
}
|
||||
+ total_rssi = 0;
|
||||
+ count_rssi = 0;
|
||||
+ for (i = 0; i < BRCMF_ANT_MAX; i++) {
|
||||
+ if (sta_info_le.rssi[i]) {
|
||||
+ sinfo->chain_signal_avg[count_rssi] =
|
||||
+ sta_info_le.rssi[i];
|
||||
+ sinfo->chain_signal[count_rssi] =
|
||||
+ sta_info_le.rssi[i];
|
||||
+ total_rssi += sta_info_le.rssi[i];
|
||||
+ count_rssi++;
|
||||
+ }
|
||||
+ }
|
||||
+ if (count_rssi) {
|
||||
+ sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL);
|
||||
+ sinfo->chains = count_rssi;
|
||||
+
|
||||
+ sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
|
||||
+ total_rssi /= count_rssi;
|
||||
+ sinfo->signal = total_rssi;
|
||||
+ }
|
||||
}
|
||||
done:
|
||||
brcmf_dbg(TRACE, "Exit\n");
|
||||
@ -0,0 +1,107 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:18 +0200
|
||||
Subject: [PATCH] brcmfmac: Add dump_station support to cfg80221 ops.
|
||||
|
||||
With this feature it becomes possible to request a station
|
||||
assoc list.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -2520,6 +2520,35 @@ done:
|
||||
return err;
|
||||
}
|
||||
|
||||
+static int
|
||||
+brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
|
||||
+ int idx, u8 *mac, struct station_info *sinfo)
|
||||
+{
|
||||
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
|
||||
+ struct brcmf_if *ifp = netdev_priv(ndev);
|
||||
+ s32 err;
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
|
||||
+
|
||||
+ if (idx == 0) {
|
||||
+ cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
|
||||
+ err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
|
||||
+ &cfg->assoclist,
|
||||
+ sizeof(cfg->assoclist));
|
||||
+ if (err) {
|
||||
+ brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
|
||||
+ err);
|
||||
+ cfg->assoclist.count = 0;
|
||||
+ return -EOPNOTSUPP;
|
||||
+ }
|
||||
+ }
|
||||
+ if (idx < le32_to_cpu(cfg->assoclist.count)) {
|
||||
+ memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
|
||||
+ return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
|
||||
+ }
|
||||
+ return -ENOENT;
|
||||
+}
|
||||
+
|
||||
static s32
|
||||
brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
|
||||
bool enabled, s32 timeout)
|
||||
@@ -4619,6 +4648,7 @@ static struct cfg80211_ops wl_cfg80211_o
|
||||
.join_ibss = brcmf_cfg80211_join_ibss,
|
||||
.leave_ibss = brcmf_cfg80211_leave_ibss,
|
||||
.get_station = brcmf_cfg80211_get_station,
|
||||
+ .dump_station = brcmf_cfg80211_dump_station,
|
||||
.set_tx_power = brcmf_cfg80211_set_tx_power,
|
||||
.get_tx_power = brcmf_cfg80211_get_tx_power,
|
||||
.add_key = brcmf_cfg80211_add_key,
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -407,6 +407,7 @@ struct brcmf_cfg80211_info {
|
||||
struct brcmu_d11inf d11inf;
|
||||
bool wowl_enabled;
|
||||
u32 pre_wowl_pmmode;
|
||||
+ struct brcmf_assoclist_le assoclist;
|
||||
};
|
||||
|
||||
/**
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil.h
|
||||
@@ -72,6 +72,7 @@
|
||||
#define BRCMF_C_GET_BSS_INFO 136
|
||||
#define BRCMF_C_GET_BANDLIST 140
|
||||
#define BRCMF_C_SET_SCB_TIMEOUT 158
|
||||
+#define BRCMF_C_GET_ASSOCLIST 159
|
||||
#define BRCMF_C_GET_PHYLIST 180
|
||||
#define BRCMF_C_SET_SCAN_CHANNEL_TIME 185
|
||||
#define BRCMF_C_SET_SCAN_UNASSOC_TIME 187
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
|
||||
@@ -119,6 +119,8 @@
|
||||
#define BRCMF_COUNTRY_BUF_SZ 4
|
||||
#define BRCMF_ANT_MAX 4
|
||||
|
||||
+#define BRCMF_MAX_ASSOCLIST 128
|
||||
+
|
||||
/* join preference types for join_pref iovar */
|
||||
enum brcmf_join_pref_types {
|
||||
BRCMF_JOIN_PREF_RSSI = 1,
|
||||
@@ -621,4 +623,15 @@ struct brcmf_rev_info_le {
|
||||
__le32 nvramrev;
|
||||
};
|
||||
|
||||
+/**
|
||||
+ * struct brcmf_assoclist_le - request assoc list.
|
||||
+ *
|
||||
+ * @count: indicates number of stations.
|
||||
+ * @mac: MAC addresses of stations.
|
||||
+ */
|
||||
+struct brcmf_assoclist_le {
|
||||
+ __le32 count;
|
||||
+ u8 mac[BRCMF_MAX_ASSOCLIST][ETH_ALEN];
|
||||
+};
|
||||
+
|
||||
#endif /* FWIL_TYPES_H_ */
|
||||
@ -0,0 +1,42 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:19 +0200
|
||||
Subject: [PATCH] brcmfmac: Move brcmf_c_preinit_dcmds prototype to correct
|
||||
file.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/common.h
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/common.h
|
||||
@@ -17,4 +17,7 @@
|
||||
|
||||
extern const u8 ALLFFMAC[ETH_ALEN];
|
||||
|
||||
+/* Sets dongle media info (drv_version, mac address). */
|
||||
+int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
|
||||
+
|
||||
#endif /* BRCMFMAC_COMMON_H */
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
@@ -33,6 +33,7 @@
|
||||
#include "feature.h"
|
||||
#include "proto.h"
|
||||
#include "pcie.h"
|
||||
+#include "common.h"
|
||||
|
||||
MODULE_AUTHOR("Broadcom Corporation");
|
||||
MODULE_DESCRIPTION("Broadcom 802.11 wireless LAN fullmac driver.");
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
|
||||
@@ -214,7 +214,4 @@ 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);
|
||||
|
||||
-/* Sets dongle media info (drv_version, mac address). */
|
||||
-int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
|
||||
-
|
||||
#endif /* BRCMFMAC_CORE_H */
|
||||
@ -0,0 +1,55 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:20 +0200
|
||||
Subject: [PATCH] brcmfmac: Remove unused state AP creating.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -839,7 +839,6 @@ brcmf_cfg80211_change_iface(struct wiphy
|
||||
err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
|
||||
}
|
||||
if (!err) {
|
||||
- set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
|
||||
brcmf_dbg(INFO, "IF Type = AP\n");
|
||||
}
|
||||
} else {
|
||||
@@ -4250,7 +4249,6 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
|
||||
brcmf_dbg(TRACE, "GO mode configuration complete\n");
|
||||
}
|
||||
- clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
|
||||
set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||
|
||||
exit:
|
||||
@@ -4315,7 +4313,6 @@ static int brcmf_cfg80211_stop_ap(struct
|
||||
}
|
||||
brcmf_set_mpc(ifp, 1);
|
||||
brcmf_configure_arp_offload(ifp, true);
|
||||
- set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
|
||||
clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||
|
||||
return err;
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.h
|
||||
@@ -143,7 +143,6 @@ struct brcmf_cfg80211_profile {
|
||||
* @BRCMF_VIF_STATUS_CONNECTING: connect/join in progress.
|
||||
* @BRCMF_VIF_STATUS_CONNECTED: connected/joined succesfully.
|
||||
* @BRCMF_VIF_STATUS_DISCONNECTING: disconnect/disable in progress.
|
||||
- * @BRCMF_VIF_STATUS_AP_CREATING: interface configured for AP operation.
|
||||
* @BRCMF_VIF_STATUS_AP_CREATED: AP operation started.
|
||||
*/
|
||||
enum brcmf_vif_status {
|
||||
@@ -151,7 +150,6 @@ enum brcmf_vif_status {
|
||||
BRCMF_VIF_STATUS_CONNECTING,
|
||||
BRCMF_VIF_STATUS_CONNECTED,
|
||||
BRCMF_VIF_STATUS_DISCONNECTING,
|
||||
- BRCMF_VIF_STATUS_AP_CREATING,
|
||||
BRCMF_VIF_STATUS_AP_CREATED
|
||||
};
|
||||
|
||||
@ -0,0 +1,122 @@
|
||||
From: Hante Meuleman <meuleman@broadcom.com>
|
||||
Date: Thu, 8 Oct 2015 20:33:21 +0200
|
||||
Subject: [PATCH] brcmfmac: Properly set carrier state of netdev.
|
||||
|
||||
Use the netif_carrier api to correctly set carrier state on the
|
||||
different modes.
|
||||
|
||||
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
|
||||
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
|
||||
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
|
||||
Signed-off-by: Hante Meuleman <meuleman@broadcom.com>
|
||||
Signed-off-by: Arend van Spriel <arend@broadcom.com>
|
||||
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
|
||||
---
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
|
||||
@@ -4250,6 +4250,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi
|
||||
brcmf_dbg(TRACE, "GO mode configuration complete\n");
|
||||
}
|
||||
set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||
+ brcmf_net_setcarrier(ifp, true);
|
||||
|
||||
exit:
|
||||
if ((err) && (!mbss)) {
|
||||
@@ -4314,6 +4315,7 @@ static int brcmf_cfg80211_stop_ap(struct
|
||||
brcmf_set_mpc(ifp, 1);
|
||||
brcmf_configure_arp_offload(ifp, true);
|
||||
clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
|
||||
+ brcmf_net_setcarrier(ifp, false);
|
||||
|
||||
return err;
|
||||
}
|
||||
@@ -5023,6 +5025,7 @@ brcmf_notify_connect_status(struct brcmf
|
||||
&ifp->vif->sme_state);
|
||||
} else
|
||||
brcmf_bss_connect_done(cfg, ndev, e, true);
|
||||
+ brcmf_net_setcarrier(ifp, true);
|
||||
} else if (brcmf_is_linkdown(e)) {
|
||||
brcmf_dbg(CONN, "Linkdown\n");
|
||||
if (!brcmf_is_ibssmode(ifp->vif)) {
|
||||
@@ -5032,6 +5035,7 @@ brcmf_notify_connect_status(struct brcmf
|
||||
brcmf_init_prof(ndev_to_prof(ndev));
|
||||
if (ndev != cfg_to_ndev(cfg))
|
||||
complete(&cfg->vif_disabled);
|
||||
+ brcmf_net_setcarrier(ifp, false);
|
||||
} else if (brcmf_is_nonetwork(cfg, e)) {
|
||||
if (brcmf_is_ibssmode(ifp->vif))
|
||||
clear_bit(BRCMF_VIF_STATUS_CONNECTING,
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
@@ -635,8 +635,7 @@ static int brcmf_netdev_stop(struct net_
|
||||
|
||||
brcmf_cfg80211_down(ndev);
|
||||
|
||||
- /* Set state and stop OS transmissions */
|
||||
- netif_stop_queue(ndev);
|
||||
+ brcmf_net_setcarrier(ifp, false);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -670,8 +669,8 @@ static int brcmf_netdev_open(struct net_
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
- /* Allow transmit calls */
|
||||
- netif_start_queue(ndev);
|
||||
+ /* Clear, carrier, set when connected or AP mode. */
|
||||
+ netif_carrier_off(ndev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -736,6 +735,24 @@ static void brcmf_net_detach(struct net_
|
||||
brcmf_cfg80211_free_netdev(ndev);
|
||||
}
|
||||
|
||||
+void brcmf_net_setcarrier(struct brcmf_if *ifp, bool on)
|
||||
+{
|
||||
+ struct net_device *ndev;
|
||||
+
|
||||
+ brcmf_dbg(TRACE, "Enter, idx=%d carrier=%d\n", ifp->bssidx, on);
|
||||
+
|
||||
+ ndev = ifp->ndev;
|
||||
+ brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_DISCONNECTED, !on);
|
||||
+ if (on) {
|
||||
+ if (!netif_carrier_ok(ndev))
|
||||
+ netif_carrier_on(ndev);
|
||||
+
|
||||
+ } else {
|
||||
+ if (netif_carrier_ok(ndev))
|
||||
+ netif_carrier_off(ndev);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int brcmf_net_p2p_open(struct net_device *ndev)
|
||||
{
|
||||
brcmf_dbg(TRACE, "Enter\n");
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
|
||||
@@ -154,10 +154,13 @@ struct brcmf_fws_mac_descriptor;
|
||||
* netif stopped due to firmware signalling flow control.
|
||||
* @BRCMF_NETIF_STOP_REASON_FLOW:
|
||||
* netif stopped due to flowring full.
|
||||
+ * @BRCMF_NETIF_STOP_REASON_DISCONNECTED:
|
||||
+ * netif stopped due to not being connected (STA mode).
|
||||
*/
|
||||
enum brcmf_netif_stop_reason {
|
||||
- BRCMF_NETIF_STOP_REASON_FWS_FC = 1,
|
||||
- BRCMF_NETIF_STOP_REASON_FLOW = 2
|
||||
+ BRCMF_NETIF_STOP_REASON_FWS_FC = BIT(0),
|
||||
+ BRCMF_NETIF_STOP_REASON_FLOW = BIT(1),
|
||||
+ BRCMF_NETIF_STOP_REASON_DISCONNECTED = BIT(2)
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -213,5 +216,6 @@ void brcmf_txflowblock_if(struct brcmf_i
|
||||
enum brcmf_netif_stop_reason reason, bool state);
|
||||
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_net_setcarrier(struct brcmf_if *ifp, bool on);
|
||||
|
||||
#endif /* BRCMFMAC_CORE_H */
|
||||
@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
|
||||
|
||||
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
|
||||
@@ -1229,6 +1229,7 @@ static int __init brcmfmac_module_init(v
|
||||
@@ -1236,6 +1236,7 @@ static int __init brcmfmac_module_init(v
|
||||
#endif
|
||||
if (!schedule_work(&brcmf_driver_work))
|
||||
return -EBUSY;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user