Initial commit

This commit is contained in:
domenico
2025-06-24 13:14:22 +02:00
commit 4002f145fc
9002 changed files with 1731834 additions and 0 deletions

View File

@@ -0,0 +1,10 @@
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
@@ -1,6 +1,6 @@
# SPDX-License-Identifier: GPL-2.0-only
config BRCMUTIL
- tristate
+ tristate "Broadcom 802.11 driver utility functions"
depends on m
config BRCMSMAC

View File

@@ -0,0 +1,37 @@
--- a/drivers/net/wireless/broadcom/b43/b43.h
+++ b/drivers/net/wireless/broadcom/b43/b43.h
@@ -840,6 +840,7 @@ struct b43_wldev {
bool qos_enabled; /* TRUE, if QoS is used. */
bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */
bool use_pio; /* TRUE if next init should use PIO */
+ int gpiomask; /* GPIO LED mask as a module parameter */
/* PHY/Radio device. */
struct b43_phy phy;
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -72,6 +72,11 @@ MODULE_FIRMWARE("b43/ucode40.fw");
MODULE_FIRMWARE("b43/ucode42.fw");
MODULE_FIRMWARE("b43/ucode9.fw");
+static int modparam_gpiomask = 0x000F;
+module_param_named(gpiomask, modparam_gpiomask, int, 0444);
+MODULE_PARM_DESC(gpiomask,
+ "GPIO mask for LED control (default 0x000F)");
+
static int modparam_bad_frames_preempt;
module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
MODULE_PARM_DESC(bad_frames_preempt,
@@ -2869,10 +2874,10 @@ static int b43_gpio_init(struct b43_wlde
u32 mask, set;
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
- b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, 0xF);
+ b43_maskset16(dev, B43_MMIO_GPIO_MASK, ~0, modparam_gpiomask);
mask = 0x0000001F;
- set = 0x0000000F;
+ set = modparam_gpiomask;
if (dev->dev->chip_id == 0x4301) {
mask |= 0x0060;
set |= 0x0060;

View File

@@ -0,0 +1,86 @@
--- a/drivers/net/wireless/broadcom/b43/Makefile
+++ b/drivers/net/wireless/broadcom/b43/Makefile
@@ -18,7 +18,7 @@ b43-$(CPTCFG_B43_PHY_AC) += phy_ac.o
b43-y += sysfs.o
b43-y += xmit.o
b43-y += dma.o
-b43-y += pio.o
+b43-$(CPTCFG_B43_PIO) += pio.o
b43-y += rfkill.o
b43-y += ppr.o
b43-$(CPTCFG_B43_LEDS) += leds.o
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -2001,10 +2001,12 @@ static void b43_do_interrupt_thread(stru
dma_reason[0], dma_reason[1],
dma_reason[2], dma_reason[3],
dma_reason[4], dma_reason[5]);
+#ifdef CPTCFG_B43_PIO
b43err(dev->wl, "This device does not support DMA "
"on your system. It will now be switched to PIO.\n");
/* Fall back to PIO transfers if we get fatal DMA errors! */
dev->use_pio = true;
+#endif
b43_controller_restart(dev, "DMA error");
return;
}
--- a/drivers/net/wireless/broadcom/b43/pio.h
+++ b/drivers/net/wireless/broadcom/b43/pio.h
@@ -151,7 +151,7 @@ static inline void b43_piorx_write32(str
b43_write32(q->dev, q->mmio_base + offset, value);
}
-
+#ifdef CPTCFG_B43_PIO
int b43_pio_init(struct b43_wldev *dev);
void b43_pio_free(struct b43_wldev *dev);
@@ -162,5 +162,37 @@ void b43_pio_rx(struct b43_pio_rxqueue *
void b43_pio_tx_suspend(struct b43_wldev *dev);
void b43_pio_tx_resume(struct b43_wldev *dev);
+#else
+static inline int b43_pio_init(struct b43_wldev *dev)
+{
+ return 0;
+}
+
+static inline void b43_pio_free(struct b43_wldev *dev)
+{
+}
+
+static inline int b43_pio_tx(struct b43_wldev *dev, struct sk_buff *skb)
+{
+ return 0;
+}
+
+static inline void b43_pio_handle_txstatus(struct b43_wldev *dev,
+ const struct b43_txstatus *status)
+{
+}
+
+static inline void b43_pio_rx(struct b43_pio_rxqueue *q)
+{
+}
+
+static inline void b43_pio_tx_suspend(struct b43_wldev *dev)
+{
+}
+
+static inline void b43_pio_tx_resume(struct b43_wldev *dev)
+{
+}
+#endif /* CPTCFG_B43_PIO */
#endif /* B43_PIO_H_ */
--- a/drivers/net/wireless/broadcom/b43/Kconfig
+++ b/drivers/net/wireless/broadcom/b43/Kconfig
@@ -100,7 +100,7 @@ config B43_BCMA_PIO
default y
config B43_PIO
- bool
+ bool "Broadcom 43xx PIO support"
depends on B43 && B43_SSB
depends on SSB_BLOCKIO
default y

View File

@@ -0,0 +1,131 @@
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -1643,7 +1643,7 @@ static void b43_write_beacon_template(st
len, ram_offset, shm_size_offset, rate);
/* Write the PHY TX control parameters. */
- antenna = B43_ANTENNA_DEFAULT;
+ antenna = dev->tx_antenna;
antenna = b43_antenna_to_phyctl(antenna);
ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL);
/* We can't send beacons with short preamble. Would get PHY errors. */
@@ -3284,8 +3284,8 @@ static int b43_chip_init(struct b43_wlde
/* Select the antennae */
if (phy->ops->set_rx_antenna)
- phy->ops->set_rx_antenna(dev, B43_ANTENNA_DEFAULT);
- b43_mgmtframe_txantenna(dev, B43_ANTENNA_DEFAULT);
+ phy->ops->set_rx_antenna(dev, dev->rx_antenna);
+ b43_mgmtframe_txantenna(dev, dev->tx_antenna);
if (phy->type == B43_PHYTYPE_B) {
value16 = b43_read16(dev, 0x005E);
@@ -3985,7 +3985,6 @@ static int b43_op_config(struct ieee8021
struct b43_wldev *dev = wl->current_dev;
struct b43_phy *phy = &dev->phy;
struct ieee80211_conf *conf = &hw->conf;
- int antenna;
int err = 0;
mutex_lock(&wl->mutex);
@@ -4028,11 +4027,9 @@ static int b43_op_config(struct ieee8021
}
/* Antennas for RX and management frame TX. */
- antenna = B43_ANTENNA_DEFAULT;
- b43_mgmtframe_txantenna(dev, antenna);
- antenna = B43_ANTENNA_DEFAULT;
+ b43_mgmtframe_txantenna(dev, dev->tx_antenna);
if (phy->ops->set_rx_antenna)
- phy->ops->set_rx_antenna(dev, antenna);
+ phy->ops->set_rx_antenna(dev, dev->rx_antenna);
if (wl->radio_enabled != phy->radio_on) {
if (wl->radio_enabled) {
@@ -5176,6 +5173,47 @@ static int b43_op_get_survey(struct ieee
return 0;
}
+static int b43_op_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev = wl->current_dev;
+
+ if (tx_ant == 1 && rx_ant == 1) {
+ dev->tx_antenna = B43_ANTENNA0;
+ dev->rx_antenna = B43_ANTENNA0;
+ }
+ else if (tx_ant == 2 && rx_ant == 2) {
+ dev->tx_antenna = B43_ANTENNA1;
+ dev->rx_antenna = B43_ANTENNA1;
+ }
+ else if ((tx_ant & 3) == 3 && (rx_ant & 3) == 3) {
+ dev->tx_antenna = B43_ANTENNA_DEFAULT;
+ dev->rx_antenna = B43_ANTENNA_DEFAULT;
+ }
+ else {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+static int b43_op_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant)
+{
+ struct b43_wl *wl = hw_to_b43_wl(hw);
+ struct b43_wldev *dev = wl->current_dev;
+
+ switch (dev->tx_antenna) {
+ case B43_ANTENNA0:
+ *tx_ant = 1; *rx_ant = 1; break;
+ case B43_ANTENNA1:
+ *tx_ant = 2; *rx_ant = 2; break;
+ case B43_ANTENNA_DEFAULT:
+ *tx_ant = 3; *rx_ant = 3; break;
+ }
+ return 0;
+}
+
static const struct ieee80211_ops b43_hw_ops = {
.tx = b43_op_tx,
.conf_tx = b43_op_conf_tx,
@@ -5197,6 +5235,8 @@ static const struct ieee80211_ops b43_hw
.sw_scan_complete = b43_op_sw_scan_complete_notifier,
.get_survey = b43_op_get_survey,
.rfkill_poll = b43_rfkill_poll,
+ .set_antenna = b43_op_set_antenna,
+ .get_antenna = b43_op_get_antenna,
};
/* Hard-reset the chip. Do not call this directly.
@@ -5498,6 +5538,8 @@ static int b43_one_core_attach(struct b4
if (!wldev)
goto out;
+ wldev->rx_antenna = B43_ANTENNA_DEFAULT;
+ wldev->tx_antenna = B43_ANTENNA_DEFAULT;
wldev->use_pio = b43_modparam_pio;
wldev->dev = dev;
wldev->wl = wl;
@@ -5592,6 +5634,9 @@ static struct b43_wl *b43_wireless_init(
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
+ hw->wiphy->available_antennas_rx = 0x3;
+ hw->wiphy->available_antennas_tx = 0x3;
+
wl->hw_registered = false;
hw->max_rates = 2;
SET_IEEE80211_DEV(hw, dev->dev);
--- a/drivers/net/wireless/broadcom/b43/b43.h
+++ b/drivers/net/wireless/broadcom/b43/b43.h
@@ -841,6 +841,8 @@ struct b43_wldev {
bool hwcrypto_enabled; /* TRUE, if HW crypto acceleration is enabled. */
bool use_pio; /* TRUE if next init should use PIO */
int gpiomask; /* GPIO LED mask as a module parameter */
+ int rx_antenna; /* Used RX antenna (B43_ANTENNAxxx) */
+ int tx_antenna; /* Used TX antenna (B43_ANTENNAxxx) */
/* PHY/Radio device. */
struct b43_phy phy;

View File

@@ -0,0 +1,11 @@
--- a/drivers/net/wireless/broadcom/b43/dma.h
+++ b/drivers/net/wireless/broadcom/b43/dma.h
@@ -170,7 +170,7 @@ struct b43_dmadesc_generic {
/* DMA engine tuning knobs */
#define B43_TXRING_SLOTS 256
-#define B43_RXRING_SLOTS 256
+#define B43_RXRING_SLOTS 32
#define B43_DMA0_RX_FW598_BUFSIZE (B43_DMA0_RX_FW598_FO + IEEE80211_MAX_FRAME_LEN)
#define B43_DMA0_RX_FW351_BUFSIZE (B43_DMA0_RX_FW351_FO + IEEE80211_MAX_FRAME_LEN)

View File

@@ -0,0 +1,17 @@
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -2886,6 +2886,14 @@ static int b43_gpio_init(struct b43_wlde
} else if (dev->dev->chip_id == 0x5354) {
/* Don't allow overtaking buttons GPIOs */
set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */
+ } else if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 ||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM47162 ||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM5356 ||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM5357 ||
+ dev->dev->chip_id == BCMA_CHIP_ID_BCM53572) {
+ /* just use gpio 0 and 1 for 2.4 GHz wifi led */
+ set &= 0x3;
+ mask &= 0x3;
}
if (0 /* FIXME: conditional unknown */ ) {

View File

@@ -0,0 +1,11 @@
--- a/drivers/net/wireless/broadcom/b43/main.c
+++ b/drivers/net/wireless/broadcom/b43/main.c
@@ -114,7 +114,7 @@ static int b43_modparam_pio = 0;
module_param_named(pio, b43_modparam_pio, int, 0644);
MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
-static int modparam_allhwsupport = !IS_ENABLED(CPTCFG_BRCMSMAC);
+static int modparam_allhwsupport = 1;
module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");

View File

@@ -0,0 +1,27 @@
--- a/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmsmac/channel.c
@@ -58,19 +58,12 @@
(((c) < 149) ? 3 : 4))))
#define BRCM_2GHZ_2412_2462 REG_RULE(2412-10, 2462+10, 40, 0, 19, 0)
-#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, \
- NL80211_RRF_NO_IR)
+#define BRCM_2GHZ_2467_2472 REG_RULE(2467-10, 2472+10, 20, 0, 19, 0)
-#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, \
- NL80211_RRF_NO_IR)
-#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, \
- NL80211_RRF_DFS | \
- NL80211_RRF_NO_IR)
-#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, \
- NL80211_RRF_DFS | \
- NL80211_RRF_NO_IR)
-#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, \
- NL80211_RRF_NO_IR)
+#define BRCM_5GHZ_5180_5240 REG_RULE(5180-10, 5240+10, 40, 0, 21, 0)
+#define BRCM_5GHZ_5260_5320 REG_RULE(5260-10, 5320+10, 40, 0, 21, 0)
+#define BRCM_5GHZ_5500_5700 REG_RULE(5500-10, 5700+10, 40, 0, 21, 0)
+#define BRCM_5GHZ_5745_5825 REG_RULE(5745-10, 5825+10, 40, 0, 21, 0)
static const struct ieee80211_regdomain brcms_regdom_x2 = {
.n_reg_rules = 6,

View File

@@ -0,0 +1,64 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Mon, 8 Jun 2015 16:11:40 +0200
Subject: [PATCH] brcmfmac: register wiphy(s) during module_init
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This is needed by OpenWrt which expects all PHYs to be created after
module loads successfully.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -431,6 +431,7 @@ struct brcmf_fw {
struct brcmf_fw_request *req;
u32 curpos;
void (*done)(struct device *dev, int err, struct brcmf_fw_request *req);
+ struct completion *completion;
};
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
@@ -638,6 +639,8 @@ static void brcmf_fw_request_done(const
fwctx->req = NULL;
}
fwctx->done(fwctx->dev, ret, fwctx->req);
+ if (fwctx->completion)
+ complete(fwctx->completion);
kfree(fwctx);
}
@@ -662,6 +665,8 @@ int brcmf_fw_get_firmwares(struct device
{
struct brcmf_fw_item *first = &req->items[0];
struct brcmf_fw *fwctx;
+ struct completion completion;
+ unsigned long time_left;
int ret;
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
@@ -678,6 +683,9 @@ int brcmf_fw_get_firmwares(struct device
fwctx->dev = dev;
fwctx->req = req;
fwctx->done = fw_cb;
+
+ init_completion(&completion);
+ fwctx->completion = &completion;
ret = request_firmware_nowait(THIS_MODULE, true, first->path,
fwctx->dev, GFP_KERNEL, fwctx,
@@ -685,6 +693,12 @@ int brcmf_fw_get_firmwares(struct device
if (ret < 0)
brcmf_fw_request_done(NULL, fwctx);
+
+ time_left = wait_for_completion_timeout(&completion,
+ msecs_to_jiffies(5000));
+ if (!time_left && fwctx)
+ fwctx->completion = NULL;
+
return 0;
}

View File

@@ -0,0 +1,49 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Thu, 9 Jul 2015 00:07:59 +0200
Subject: [PATCH] brcmfmac: workaround bug with some inconsistent BSSes state
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
---
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -715,8 +715,36 @@ static struct wireless_dev *brcmf_cfg802
struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
struct brcmf_pub *drvr = cfg->pub;
struct wireless_dev *wdev;
+ struct net_device *dev;
int err;
+ /*
+ * There is a bug with in-firmware BSS management. When adding virtual
+ * interface brcmfmac first tells firmware to create new BSS and then
+ * it creates new struct net_device.
+ *
+ * If creating/registering netdev(ice) fails, BSS remains in some bugged
+ * state. It conflicts with existing BSSes by overtaking their auth
+ * requests.
+ *
+ * It results in one BSS (addresss X) sending beacons and another BSS
+ * (address Y) replying to authentication requests. This makes interface
+ * unusable as AP.
+ *
+ * To workaround this bug we may try to guess if register_netdev(ice)
+ * will fail. The most obvious case is using interface name that already
+ * exists. This is actually quite likely with brcmfmac & some user space
+ * scripts as brcmfmac doesn't allow deleting virtual interfaces.
+ * So this bug can be triggered even by something trivial like:
+ * iw dev wlan0 delete
+ * iw phy phy0 interface add wlan0 type __ap
+ */
+ dev = dev_get_by_name(&init_net, name);
+ if (dev) {
+ dev_put(dev);
+ return ERR_PTR(-ENFILE);
+ }
+
brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
if (err) {

View File

@@ -0,0 +1,27 @@
From 66ae1b1750720a33e29792a177b1e696f4f005fb Mon Sep 17 00:00:00 2001
From: Phil Elwell <phil@raspberrypi.org>
Date: Wed, 9 Mar 2016 17:25:59 +0000
Subject: [PATCH] brcmfmac: Disable power management
Disable wireless power saving in the brcmfmac WLAN driver. This is a
temporary measure until the connectivity loss resulting from power
saving is resolved.
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
---
drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2961,6 +2961,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip
* preference in cfg struct to apply this to
* FW later while initializing the dongle
*/
+#if defined(CONFIG_ARCH_BCM2835)
+ brcmf_dbg(INFO, "power management disabled\n");
+ enabled = false;
+#endif
cfg->pwr_save = enabled;
if (!check_vif_up(ifp->vif)) {

View File

@@ -0,0 +1,60 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Subject: [PATCH] brcmfmac: add in-driver tables with country codes
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This adds early support for changing region. Ideally this data should
be stored in DT as all these mappings are devices specific.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
---
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -12,6 +12,36 @@
#include "common.h"
#include "of.h"
+/* TODO: FIXME: Use DT */
+static void brcmf_of_probe_cc(struct device *dev,
+ struct brcmf_mp_device *settings)
+{
+ static struct brcmfmac_pd_cc_entry netgear_r8000_cc_ent[] = {
+ { "JP", "JP", 78 },
+ { "US", "Q2", 86 },
+ };
+ struct brcmfmac_pd_cc_entry *cc_ent = NULL;
+ int table_size = 0;
+
+ if (of_machine_is_compatible("netgear,r8000")) {
+ cc_ent = netgear_r8000_cc_ent;
+ table_size = ARRAY_SIZE(netgear_r8000_cc_ent);
+ }
+
+ if (cc_ent && table_size) {
+ struct brcmfmac_pd_cc *cc;
+ size_t memsize;
+
+ memsize = table_size * sizeof(struct brcmfmac_pd_cc_entry);
+ cc = devm_kzalloc(dev, sizeof(*cc) + memsize, GFP_KERNEL);
+ if (!cc)
+ return;
+ cc->table_size = table_size;
+ memcpy(cc->table, cc_ent, memsize);
+ settings->country_codes = cc;
+ }
+}
+
void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
struct brcmf_mp_device *settings)
{
@@ -43,6 +73,8 @@ void brcmf_of_probe(struct device *dev,
of_node_put(root);
}
+ brcmf_of_probe_cc(dev, settings);
+
if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
!of_device_is_compatible(np, "brcm,bcm4329-fmac"))
return;

View File

@@ -0,0 +1,23 @@
brcmfmac: do not use internal roaming engine by default
Some evidence of curing disconnects with this disabled, so make it a default.
Can be overridden with module parameter roamoff=0
See: http://projectable.me/optimize-my-pi-wi-fi/
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
---
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -59,7 +59,11 @@ static int brcmf_fcmode;
module_param_named(fcmode, brcmf_fcmode, int, 0);
MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control");
+#if defined(CONFIG_ARCH_BCM2835)
+static int brcmf_roamoff = 1;
+#else
static int brcmf_roamoff;
+#endif
module_param_named(roamoff, brcmf_roamoff, int, 0400);
MODULE_PARM_DESC(roamoff, "Do not use internal roaming engine");

View File

@@ -0,0 +1,148 @@
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -2913,6 +2913,63 @@ done:
}
static int
+brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
+ int idx, struct survey_info *survey)
+{
+ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
+ struct brcmf_if *ifp = netdev_priv(ndev);
+ struct brcmu_chan ch;
+ enum nl80211_band band = 0;
+ s32 err = 0;
+ int noise;
+ u32 freq;
+ u32 chanspec;
+
+ memset(survey, 0, sizeof(struct survey_info));
+ if (idx != 0) {
+ if (idx >= cfg->pub->num_chan_stats || cfg->pub->chan_stats == NULL)
+ return -ENOENT;
+ if (cfg->pub->chan_stats[idx].freq == 0)
+ return -ENOENT;
+ survey->filled = SURVEY_INFO_NOISE_DBM;
+ survey->channel = ieee80211_get_channel(wiphy, cfg->pub->chan_stats[idx].freq);
+ survey->noise = cfg->pub->chan_stats[idx].noise;
+ return 0;
+ }
+
+ err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec);
+ if (err) {
+ brcmf_err("chanspec failed (%d)\n", err);
+ return err;
+ }
+
+ ch.chspec = chanspec;
+ cfg->d11inf.decchspec(&ch);
+
+ switch (ch.band) {
+ case BRCMU_CHAN_BAND_2G:
+ band = NL80211_BAND_2GHZ;
+ break;
+ case BRCMU_CHAN_BAND_5G:
+ band = NL80211_BAND_5GHZ;
+ break;
+ }
+
+ freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
+ survey->channel = ieee80211_get_channel(wiphy, freq);
+
+ err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PHY_NOISE, &noise);
+ if (err) {
+ brcmf_err("Could not get noise (%d)\n", err);
+ return err;
+ }
+
+ survey->filled = SURVEY_INFO_NOISE_DBM | SURVEY_INFO_IN_USE;
+ survey->noise = le32_to_cpu(noise);
+ return 0;
+}
+
+static int
brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
int idx, u8 *mac, struct station_info *sinfo)
{
@@ -3008,6 +3065,7 @@ static s32 brcmf_inform_single_bss(struc
struct brcmu_chan ch;
u16 channel;
u32 freq;
+ int i;
u16 notify_capability;
u16 notify_interval;
u8 *notify_ie;
@@ -3032,6 +3090,17 @@ static s32 brcmf_inform_single_bss(struc
band = NL80211_BAND_5GHZ;
freq = ieee80211_channel_to_frequency(channel, band);
+ for (i = 0;i < cfg->pub->num_chan_stats;i++) {
+ if (freq == cfg->pub->chan_stats[i].freq)
+ break;
+ if (cfg->pub->chan_stats[i].freq == 0)
+ break;
+ }
+ if (i < cfg->pub->num_chan_stats) {
+ cfg->pub->chan_stats[i].freq = freq;
+ cfg->pub->chan_stats[i].noise = bi->phy_noise;
+ }
+
bss_data.chan = ieee80211_get_channel(wiphy, freq);
bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20;
bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
@@ -5518,6 +5587,7 @@ static struct cfg80211_ops brcmf_cfg8021
.leave_ibss = brcmf_cfg80211_leave_ibss,
.get_station = brcmf_cfg80211_get_station,
.dump_station = brcmf_cfg80211_dump_station,
+ .dump_survey = brcmf_cfg80211_dump_survey,
.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/broadcom/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c
@@ -1356,6 +1356,8 @@ int brcmf_attach(struct device *dev)
/* Link to bus module */
drvr->hdrlen = 0;
+ drvr->chan_stats = vzalloc(256 * sizeof(struct brcmf_chan_stats));
+ drvr->num_chan_stats = 256;
/* Attach and link in the protocol */
ret = brcmf_proto_attach(drvr);
@@ -1438,6 +1440,12 @@ void brcmf_detach(struct device *dev)
if (drvr == NULL)
return;
+ drvr->num_chan_stats = 0;
+ if (drvr->chan_stats) {
+ vfree(drvr->chan_stats);
+ drvr->chan_stats = NULL;
+ }
+
#ifdef CONFIG_INET
unregister_inetaddr_notifier(&drvr->inetaddr_notifier);
#endif
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h
@@ -91,6 +91,11 @@ struct brcmf_rev_info {
u32 nvramrev;
};
+struct brcmf_chan_stats {
+ u32 freq;
+ int noise;
+};
+
/* Common structure for module and instance linkage */
struct brcmf_pub {
/* Linkage ponters */
@@ -100,6 +105,9 @@ struct brcmf_pub {
struct cfg80211_ops *ops;
struct brcmf_cfg80211_info *config;
+ int num_chan_stats;
+ struct brcmf_chan_stats *chan_stats;
+
/* Internal brcmf items */
uint hdrlen; /* Total BRCMF header length (proto + bus) */