mac80211: update to wireless-testing 2015-10-26

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

SVN-Revision: 47286
This commit is contained in:
Felix Fietkau 2015-10-30 15:17:56 +00:00
parent f79bae2fc0
commit ec3ee0969e
79 changed files with 134 additions and 3603 deletions

View file

@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mac80211
PKG_VERSION:=2015-07-21
PKG_VERSION:=2015-10-26
PKG_RELEASE:=1
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
PKG_BACKPORT_VERSION:=
PKG_MD5SUM:=ec529acfb9c942daf8116e5cff47c999
PKG_MD5SUM:=3b07569065a18c6a69a340ea50235b7d
PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)
@ -1435,7 +1435,7 @@ define KernelPackage/rtl8180
$(call KernelPackage/rtl818x/Default)
DEPENDS+= @PCI_SUPPORT
TITLE+= (RTL8180 PCI)
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8180/rtl818x_pci.ko
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl818x/rtl8180/rtl818x_pci.ko
AUTOLOAD:=$(call AutoProbe,rtl818x_pci)
endef
@ -1443,7 +1443,7 @@ define KernelPackage/rtl8187
$(call KernelPackage/rtl818x/Default)
DEPENDS+= @USB_SUPPORT +kmod-usb-core
TITLE+= (RTL8187 USB)
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtl818x/rtl8187/rtl8187.ko
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtl818x/rtl8187/rtl8187.ko
AUTOLOAD:=$(call AutoProbe,rtl8187)
endef
@ -1460,7 +1460,7 @@ define KernelPackage/rtlwifi
$(call KernelPackage/mac80211/Default)
TITLE:=Realtek common driver part
DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 +@DRIVER_11N_SUPPORT
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtlwifi/rtlwifi.ko
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtlwifi.ko
HIDDEN:=1
endef
@ -1468,7 +1468,7 @@ define KernelPackage/rtlwifi-pci
$(call KernelPackage/mac80211/Default)
TITLE:=Realtek common driver part (PCI support)
DEPENDS+= @PCI_SUPPORT +kmod-rtlwifi
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtlwifi/rtl_pci.ko
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_pci.ko
AUTOLOAD:=$(call AutoProbe,rtl_pci)
HIDDEN:=1
endef
@ -1477,7 +1477,7 @@ define KernelPackage/rtlwifi-usb
$(call KernelPackage/mac80211/Default)
TITLE:=Realtek common driver part (USB support)
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-rtlwifi
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtlwifi/rtl_usb.ko
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl_usb.ko
AUTOLOAD:=$(call AutoProbe,rtl_usb)
HIDDEN:=1
endef
@ -1486,7 +1486,7 @@ define KernelPackage/rtl8192c-common
$(call KernelPackage/mac80211/Default)
TITLE:=Realtek RTL8192CE/RTL8192CU common support module
DEPENDS+= +kmod-rtlwifi
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/rtlwifi/rtl8192c/rtl8192c-common.ko
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192c/rtl8192c-common.ko
HIDDEN:=1
endef
@ -1494,7 +1494,7 @@ define KernelPackage/rtl8192ce
$(call KernelPackage/mac80211/Default)
TITLE:=Realtek RTL8192CE/RTL8188CE support
DEPENDS+= +kmod-rtlwifi-pci +kmod-rtl8192c-common
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/rtlwifi/rtl8192ce/rtl8192ce.ko
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192ce/rtl8192ce.ko
AUTOLOAD:=$(call AutoProbe,rtl8192ce)
endef
@ -1509,7 +1509,7 @@ define KernelPackage/rtl8192se
$(call KernelPackage/mac80211/Default)
TITLE:=Realtek RTL8192SE/RTL8191SE support
DEPENDS+= +kmod-rtlwifi-pci
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rtlwifi/rtl8192se/rtl8192se.ko
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192se/rtl8192se.ko
AUTOLOAD:=$(call AutoProbe,rtl8192se)
endef
@ -1522,7 +1522,7 @@ define KernelPackage/rtl8192de
$(call KernelPackage/mac80211/Default)
TITLE:=Realtek RTL8192DE/RTL8188DE support
DEPENDS+= +kmod-rtlwifi-pci
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/rtlwifi/rtl8192de/rtl8192de.ko
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rtl8192de.ko
AUTOLOAD:=$(call AutoProbe,rtl8192de)
endef
@ -1535,7 +1535,7 @@ define KernelPackage/rtl8192cu
$(call KernelPackage/mac80211/Default)
TITLE:=Realtek RTL8192CU/RTL8188CU support
DEPENDS+= +kmod-rtlwifi-usb +kmod-rtl8192c-common
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/rtlwifi/rtl8192cu/rtl8192cu.ko
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/rtl8192cu.ko
AUTOLOAD:=$(call AutoProbe,rtl8192cu)
endef

View file

@ -1,6 +1,6 @@
--- a/kconf/conf.c
+++ b/kconf/conf.c
@@ -578,40 +578,12 @@ int main(int ac, char **av)
@@ -593,40 +593,12 @@ int main(int ac, char **av)
case oldconfig:
case listnewconfig:
case olddefconfig:

View file

@ -1,33 +0,0 @@
From e15e9231e7a9f81f5264d294fd3fd96a20d92516 Mon Sep 17 00:00:00 2001
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Sat, 25 Jul 2015 15:19:17 +0200
Subject: [PATCH 3/3] backports: do not add debugfs_create_devm_seqfile() on
recent kernel versions
An #ifdef for the kernel version was missing around the header of
debugfs_create_devm_seqfile() and the LINUX_BACKPORT() was also not
done.
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
backport/backport-include/linux/debugfs.h | 3 +++
1 file changed, 3 insertions(+)
--- a/backport-include/linux/debugfs.h
+++ b/backport-include/linux/debugfs.h
@@ -5,6 +5,8 @@
#include <linux/device.h>
#include <generated/utsrelease.h>
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0)
+#define debugfs_create_devm_seqfile LINUX_BACKPORT(debugfs_create_devm_seqfile)
#if defined(CONFIG_DEBUG_FS)
struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,
struct dentry *parent,
@@ -20,5 +22,6 @@ static inline struct dentry *debugfs_cre
return ERR_PTR(-ENODEV);
}
#endif /* CONFIG_DEBUG_FS */
+#endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3,19,0) */
#endif /* __BACKPORT_DEBUGFS_H_ */

View file

@ -43,5 +43,5 @@
- tristate
+ tristate "RT2x00 support"
depends on m
select BPAUTO_AVERAGE
config RT2X00_LIB_FIRMWARE

View file

@ -1,6 +1,6 @@
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -174,7 +174,7 @@ config CFG80211_WEXT_EXPORT
@@ -184,7 +184,7 @@ config CFG80211_WEXT_EXPORT
wext compatibility symbols to be exported.
config LIB80211
@ -9,7 +9,7 @@
depends on m
default n
help
@@ -184,15 +184,15 @@ config LIB80211
@@ -194,15 +194,15 @@ config LIB80211
Drivers should select this themselves if needed.
config LIB80211_CRYPT_WEP

View file

@ -1,9 +1,9 @@
--- a/.local-symbols
+++ b/.local-symbols
@@ -449,43 +449,6 @@ USB_CDC_PHONET=
USB_IPHETH=
@@ -454,43 +454,6 @@ USB_IPHETH=
USB_SIERRA_NET=
USB_VL600=
USB_NET_CH9200=
-SSB_POSSIBLE=
-SSB=
-SSB_SPROM=
@ -46,7 +46,7 @@
NFC_NCI=
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2866,7 +2866,7 @@ static struct ssb_device *b43_ssb_gpio_d
@@ -2867,7 +2867,7 @@ static struct ssb_device *b43_ssb_gpio_d
{
struct ssb_bus *bus = dev->dev->sdev->bus;
@ -55,7 +55,7 @@
return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
#else
return bus->chipco.dev;
@@ -4903,7 +4903,7 @@ static int b43_wireless_core_init(struct
@@ -4904,7 +4904,7 @@ static int b43_wireless_core_init(struct
}
if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
@ -120,7 +120,7 @@
--- a/Makefile.kernel
+++ b/Makefile.kernel
@@ -38,8 +38,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
obj-$(CPTCFG_WLAN) += drivers/net/wireless/
#obj-$(CPTCFG_WLAN += drivers/net/wireless/
obj-$(CPTCFG_BT) += net/bluetooth/
obj-$(CPTCFG_BT) += drivers/bluetooth/
-obj-$(CPTCFG_SSB) += drivers/ssb/

View file

@ -7,11 +7,11 @@
- select BPAUTO_CRYPTO_CCM
- depends on CRYPTO_GCM
depends on CRC32
select BPAUTO_AVERAGE
---help---
This option enables the hardware independent IEEE 802.11
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -15,9 +15,7 @@ mac80211-y := \
@@ -16,9 +16,7 @@ mac80211-y := \
michael.o \
tkip.o \
aes_ccm.o \
@ -320,7 +320,7 @@
struct {
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -304,7 +304,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
@@ -307,7 +307,8 @@ ieee80211_crypto_tkip_decrypt(struct iee
}
@ -330,7 +330,7 @@
{
__le16 mask_fc;
int a4_included, mgmt;
@@ -334,14 +335,8 @@ static void ccmp_special_blocks(struct s
@@ -337,14 +338,8 @@ static void ccmp_special_blocks(struct s
else
qos_tid = 0;
@ -347,7 +347,7 @@
/* Nonce: Nonce Flags | A2 | PN
* Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
@@ -349,6 +344,8 @@ static void ccmp_special_blocks(struct s
@@ -352,6 +347,8 @@ static void ccmp_special_blocks(struct s
b_0[1] = qos_tid | (mgmt << 4);
memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
@ -356,7 +356,7 @@
/* AAD (extra authenticate-only data) / masked 802.11 header
* FC | A1 | A2 | A3 | SC | [A4] | [QC] */
@@ -460,7 +457,7 @@ static int ccmp_encrypt_skb(struct ieee8
@@ -463,7 +460,7 @@ static int ccmp_encrypt_skb(struct ieee8
return 0;
pos += IEEE80211_CCMP_HDR_LEN;
@ -365,7 +365,7 @@
ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
skb_put(skb, mic_len), mic_len);
@@ -531,7 +528,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
@@ -534,7 +531,7 @@ ieee80211_crypto_ccmp_decrypt(struct iee
u8 aad[2 * AES_BLOCK_SIZE];
u8 b_0[AES_BLOCK_SIZE];
/* hardware didn't decrypt/verify MIC */

View file

@ -2,7 +2,7 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -886,7 +886,6 @@ static int ieee80211_stop_ap(struct wiph
@@ -846,7 +846,6 @@ static int ieee80211_stop_ap(struct wiph
sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
__sta_info_flush(sdata, true);

View file

@ -1,6 +1,6 @@
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -287,7 +287,7 @@ void ieee80211_restart_hw(struct ieee802
@@ -285,7 +285,7 @@ void ieee80211_restart_hw(struct ieee802
}
EXPORT_SYMBOL(ieee80211_restart_hw);
@ -9,7 +9,7 @@
static int ieee80211_ifa_changed(struct notifier_block *nb,
unsigned long data, void *arg)
{
@@ -346,7 +346,7 @@ static int ieee80211_ifa_changed(struct
@@ -344,7 +344,7 @@ static int ieee80211_ifa_changed(struct
}
#endif
@ -18,9 +18,9 @@
static int ieee80211_ifa6_changed(struct notifier_block *nb,
unsigned long data, void *arg)
{
@@ -1086,14 +1086,14 @@ int ieee80211_register_hw(struct ieee802
if (result)
goto fail_pm_qos;
@@ -1081,14 +1081,14 @@ int ieee80211_register_hw(struct ieee802
rtnl_unlock();
-#ifdef CONFIG_INET
+#ifdef __disabled__CONFIG_INET
@ -35,7 +35,7 @@
local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed;
result = register_inet6addr_notifier(&local->ifa6_notifier);
if (result)
@@ -1102,13 +1102,13 @@ int ieee80211_register_hw(struct ieee802
@@ -1097,13 +1097,13 @@ int ieee80211_register_hw(struct ieee802
return 0;
@ -50,12 +50,12 @@
-#if defined(CONFIG_INET) || defined(CONFIG_IPV6)
+#if defined(__disabled__CONFIG_INET) || defined(__disabled__CONFIG_IPV6)
fail_ifa:
pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
&local->network_latency_notifier);
@@ -1141,10 +1141,10 @@ void ieee80211_unregister_hw(struct ieee
#endif
rtnl_lock();
@@ -1131,10 +1131,10 @@ void ieee80211_unregister_hw(struct ieee
tasklet_kill(&local->tx_pending_tasklet);
tasklet_kill(&local->tasklet);
pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
&local->network_latency_notifier);
-#ifdef CONFIG_INET
+#ifdef __disabled__CONFIG_INET
unregister_inetaddr_notifier(&local->ifa_notifier);

View file

@ -1,6 +1,6 @@
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2008,7 +2008,7 @@ static int ieee80211_scan(struct wiphy *
@@ -1981,7 +1981,7 @@ static int ieee80211_scan(struct wiphy *
* the frames sent while scanning on other channel will be
* lost)
*/

View file

@ -1,31 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 7 Jun 2015 13:53:35 +0200
Subject: [PATCH] ath9k: force rx_clear when disabling rx
This makes stopping Rx more reliable and should reduce the frequency of
Rx related DMA stop warnings
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -677,13 +677,15 @@ void ath9k_hw_startpcureceive(struct ath
ath9k_ani_reset(ah, is_scanning);
- REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+ REG_CLR_BIT(ah, AR_DIAG_SW,
+ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
}
EXPORT_SYMBOL(ath9k_hw_startpcureceive);
void ath9k_hw_abortpcurecv(struct ath_hw *ah)
{
- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
+ REG_SET_BIT(ah, AR_DIAG_SW,
+ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
ath9k_hw_disable_mib_counters(ah);
}

View file

@ -1,121 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 2 Jul 2015 15:20:56 +0200
Subject: [PATCH] ath9k: limit retries for powersave response frames
In some cases, the channel might be busy enough that an ath9k AP's
response to PS-Poll frames might be too slow and the station has already
gone to sleep. To avoid wasting too much airtime on this, limit the
number of retries on such frames and ensure that no sample rate gets
used.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -147,10 +147,25 @@ static void ath_send_bar(struct ath_atx_
}
static void ath_set_rates(struct ieee80211_vif *vif, struct ieee80211_sta *sta,
- struct ath_buf *bf)
+ struct ath_buf *bf, bool ps)
{
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(bf->bf_mpdu);
+
+ if (ps) {
+ /* Clear the first rate to avoid using a sample rate for PS frames */
+ info->control.rates[0].idx = -1;
+ info->control.rates[0].count = 0;
+ }
+
ieee80211_get_tx_rates(vif, sta, bf->bf_mpdu, bf->rates,
ARRAY_SIZE(bf->rates));
+ if (!ps)
+ return;
+
+ if (bf->rates[0].count > 2)
+ bf->rates[0].count = 2;
+
+ bf->rates[1].idx = -1;
}
static void ath_txq_skb_done(struct ath_softc *sc, struct ath_txq *txq,
@@ -1430,7 +1445,7 @@ ath_tx_form_burst(struct ath_softc *sc,
if (tx_info->flags & IEEE80211_TX_CTL_AMPDU)
break;
- ath_set_rates(tid->an->vif, tid->an->sta, bf);
+ ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
} while (1);
}
@@ -1461,7 +1476,7 @@ static bool ath_tx_sched_aggr(struct ath
return false;
}
- ath_set_rates(tid->an->vif, tid->an->sta, bf);
+ ath_set_rates(tid->an->vif, tid->an->sta, bf, false);
if (aggr)
last = ath_tx_form_aggr(sc, txq, tid, &bf_q, bf,
tid_q, &aggr_len);
@@ -1653,7 +1668,7 @@ void ath9k_release_buffered_frames(struc
__skb_unlink(bf->bf_mpdu, tid_q);
list_add_tail(&bf->list, &bf_q);
- ath_set_rates(tid->an->vif, tid->an->sta, bf);
+ ath_set_rates(tid->an->vif, tid->an->sta, bf, true);
if (bf_isampdu(bf)) {
ath_tx_addto_baw(sc, tid, bf);
bf->bf_state.bf_type &= ~BUF_AGGR;
@@ -2318,7 +2333,7 @@ int ath_tx_start(struct ieee80211_hw *hw
struct ath_txq *txq = txctl->txq;
struct ath_atx_tid *tid = NULL;
struct ath_buf *bf;
- bool queue, skip_uapsd = false, ps_resp;
+ bool queue, ps_resp;
int q, ret;
if (vif)
@@ -2365,13 +2380,13 @@ int ath_tx_start(struct ieee80211_hw *hw
if (!txctl->an)
txctl->an = &avp->mcast_node;
queue = true;
- skip_uapsd = true;
+ ps_resp = false;
}
if (txctl->an && queue)
tid = ath_get_skb_tid(sc, txctl->an, skb);
- if (!skip_uapsd && ps_resp) {
+ if (ps_resp) {
ath_txq_unlock(sc, txq);
txq = sc->tx.uapsdq;
ath_txq_lock(sc, txq);
@@ -2409,7 +2424,7 @@ int ath_tx_start(struct ieee80211_hw *hw
if (txctl->paprd)
bf->bf_state.bfs_paprd_timestamp = jiffies;
- ath_set_rates(vif, sta, bf);
+ ath_set_rates(vif, sta, bf, ps_resp);
ath_tx_send_normal(sc, txq, tid, skb);
out:
@@ -2448,7 +2463,7 @@ void ath_tx_cabq(struct ieee80211_hw *hw
break;
bf->bf_lastbf = bf;
- ath_set_rates(vif, NULL, bf);
+ ath_set_rates(vif, NULL, bf, false);
ath_buf_set_rate(sc, bf, &info, fi->framelen, false);
duration += info.rates[0].PktDuration;
if (bf_tail)
@@ -2968,7 +2983,7 @@ int ath9k_tx99_send(struct ath_softc *sc
return -EINVAL;
}
- ath_set_rates(sc->tx99_vif, NULL, bf);
+ ath_set_rates(sc->tx99_vif, NULL, bf, false);
ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr);
ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum);

View file

@ -1,56 +0,0 @@
From: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
Date: Fri, 3 Jul 2015 11:45:42 +0530
Subject: [PATCH] ath10k: Delay device access after cold reset
It is observed that during cold reset pcie access right
after a write operation to SOC_GLOBAL_RESET_ADDRESS causes
Data Bus Error and system hard lockup. The reason
for bus error is that pcie needs some time to get
back to stable state for any transaction during cold reset. Add
delay of 20 msecs after write of SOC_GLOBAL_RESET_ADDRESS
to fix this issue.
Signed-off-by: Vasanthakumar Thiagarajan <vthiagar@qti.qualcomm.com>
---
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -2761,7 +2761,6 @@ static int ath10k_pci_wait_for_target_in
static int ath10k_pci_cold_reset(struct ath10k *ar)
{
- int i;
u32 val;
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset\n");
@@ -2777,23 +2776,18 @@ static int ath10k_pci_cold_reset(struct
val |= 1;
ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
- for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
- if (ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
- RTC_STATE_COLD_RESET_MASK)
- break;
- msleep(1);
- }
+ /* After writing into SOC_GLOBAL_RESET to put device into
+ * reset and pulling out of reset pcie may not be stable
+ * for any immediate pcie register access and cause bus error,
+ * add delay before any pcie access request to fix this issue.
+ */
+ msleep(20);
/* Pull Target, including PCIe, out of RESET. */
val &= ~1;
ath10k_pci_reg_write32(ar, SOC_GLOBAL_RESET_ADDRESS, val);
- for (i = 0; i < ATH_PCI_RESET_WAIT_MAX; i++) {
- if (!(ath10k_pci_reg_read32(ar, RTC_STATE_ADDRESS) &
- RTC_STATE_COLD_RESET_MASK))
- break;
- msleep(1);
- }
+ msleep(20);
ath10k_dbg(ar, ATH10K_DBG_BOOT, "boot cold reset complete\n");

View file

@ -1,17 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Mon, 11 May 2015 18:35:20 +0200
Subject: [PATCH] ath9k: add fast-xmit support
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -826,6 +826,7 @@ static void ath9k_set_hw_capab(struct at
ieee80211_hw_set(hw, SIGNAL_DBM);
ieee80211_hw_set(hw, RX_INCLUDES_FCS);
ieee80211_hw_set(hw, HOST_BROADCAST_PS_BUFFERING);
+ ieee80211_hw_set(hw, SUPPORT_FAST_XMIT);
if (ath9k_ps_enable)
ieee80211_hw_set(hw, SUPPORTS_PS);

View file

@ -1,385 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 4 Apr 2015 18:39:06 +0200
Subject: [PATCH] ath9k: remove struct ath_atx_ac
struct ath_atx_ac contains a list of active TIDs belonging to one WMM AC.
This patch changes the code to track active station TIDs in the txq directly.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -173,14 +173,6 @@ struct ath_txq {
struct sk_buff_head complete_q;
};
-struct ath_atx_ac {
- struct ath_txq *txq;
- struct list_head list;
- struct list_head tid_q;
- bool clear_ps_filter;
- bool sched;
-};
-
struct ath_frame_info {
struct ath_buf *bf;
u16 framelen;
@@ -243,7 +235,7 @@ struct ath_atx_tid {
struct sk_buff_head buf_q;
struct sk_buff_head retry_q;
struct ath_node *an;
- struct ath_atx_ac *ac;
+ struct ath_txq *txq;
unsigned long tx_buf[BITS_TO_LONGS(ATH_TID_MAX_BUFS)];
u16 seq_start;
u16 seq_next;
@@ -255,6 +247,7 @@ struct ath_atx_tid {
s8 bar_index;
bool sched;
bool active;
+ bool clear_ps_filter;
};
struct ath_node {
@@ -262,7 +255,6 @@ struct ath_node {
struct ieee80211_sta *sta; /* station struct we're part of */
struct ieee80211_vif *vif; /* interface with which we're associated */
struct ath_atx_tid tid[IEEE80211_NUM_TIDS];
- struct ath_atx_ac ac[IEEE80211_NUM_ACS];
u16 maxampdu;
u8 mpdudensity;
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -106,7 +106,6 @@ void ath_txq_unlock_complete(struct ath_
static void ath_tx_queue_tid(struct ath_softc *sc, struct ath_txq *txq,
struct ath_atx_tid *tid)
{
- struct ath_atx_ac *ac = tid->ac;
struct list_head *list;
struct ath_vif *avp = (struct ath_vif *) tid->an->vif->drv_priv;
struct ath_chanctx *ctx = avp->chanctx;
@@ -118,15 +117,8 @@ static void ath_tx_queue_tid(struct ath_
return;
tid->sched = true;
- list_add_tail(&tid->list, &ac->tid_q);
-
- if (ac->sched)
- return;
-
- ac->sched = true;
-
list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
- list_add_tail(&ac->list, list);
+ list_add_tail(&tid->list, list);
}
static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
@@ -223,7 +215,7 @@ static struct sk_buff *ath_tid_dequeue(s
static void
ath_tx_tid_change_state(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_txq *txq = tid->ac->txq;
+ struct ath_txq *txq = tid->txq;
struct ieee80211_tx_info *tx_info;
struct sk_buff *skb, *tskb;
struct ath_buf *bf;
@@ -252,7 +244,7 @@ ath_tx_tid_change_state(struct ath_softc
static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
{
- struct ath_txq *txq = tid->ac->txq;
+ struct ath_txq *txq = tid->txq;
struct sk_buff *skb;
struct ath_buf *bf;
struct list_head bf_head;
@@ -659,7 +651,7 @@ static void ath_tx_complete_aggr(struct
ath_tx_queue_tid(sc, txq, tid);
if (ts->ts_status & (ATH9K_TXERR_FILT | ATH9K_TXERR_XRETRY))
- tid->ac->clear_ps_filter = true;
+ tid->clear_ps_filter = true;
}
}
@@ -749,7 +741,7 @@ static u32 ath_lookup_rate(struct ath_so
struct ieee80211_tx_rate *rates;
u32 max_4ms_framelen, frmlen;
u16 aggr_limit, bt_aggr_limit, legacy = 0;
- int q = tid->ac->txq->mac80211_qnum;
+ int q = tid->txq->mac80211_qnum;
int i;
skb = bf->bf_mpdu;
@@ -1486,8 +1478,8 @@ static bool ath_tx_sched_aggr(struct ath
if (list_empty(&bf_q))
return false;
- if (tid->ac->clear_ps_filter || tid->an->no_ps_filter) {
- tid->ac->clear_ps_filter = false;
+ if (tid->clear_ps_filter || tid->an->no_ps_filter) {
+ tid->clear_ps_filter = false;
tx_info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
}
@@ -1506,7 +1498,7 @@ int ath_tx_aggr_start(struct ath_softc *
an = (struct ath_node *)sta->drv_priv;
txtid = ATH_AN_2_TID(an, tid);
- txq = txtid->ac->txq;
+ txq = txtid->txq;
ath_txq_lock(sc, txq);
@@ -1540,7 +1532,7 @@ void ath_tx_aggr_stop(struct ath_softc *
{
struct ath_node *an = (struct ath_node *)sta->drv_priv;
struct ath_atx_tid *txtid = ATH_AN_2_TID(an, tid);
- struct ath_txq *txq = txtid->ac->txq;
+ struct ath_txq *txq = txtid->txq;
ath_txq_lock(sc, txq);
txtid->active = false;
@@ -1553,7 +1545,6 @@ void ath_tx_aggr_sleep(struct ieee80211_
struct ath_node *an)
{
struct ath_atx_tid *tid;
- struct ath_atx_ac *ac;
struct ath_txq *txq;
bool buffered;
int tidno;
@@ -1561,8 +1552,7 @@ void ath_tx_aggr_sleep(struct ieee80211_
for (tidno = 0, tid = &an->tid[tidno];
tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
- ac = tid->ac;
- txq = ac->txq;
+ txq = tid->txq;
ath_txq_lock(sc, txq);
@@ -1576,11 +1566,6 @@ void ath_tx_aggr_sleep(struct ieee80211_
tid->sched = false;
list_del(&tid->list);
- if (ac->sched) {
- ac->sched = false;
- list_del(&ac->list);
- }
-
ath_txq_unlock(sc, txq);
ieee80211_sta_set_buffered(sta, tidno, buffered);
@@ -1590,18 +1575,16 @@ void ath_tx_aggr_sleep(struct ieee80211_
void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
{
struct ath_atx_tid *tid;
- struct ath_atx_ac *ac;
struct ath_txq *txq;
int tidno;
for (tidno = 0, tid = &an->tid[tidno];
tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
- ac = tid->ac;
- txq = ac->txq;
+ txq = tid->txq;
ath_txq_lock(sc, txq);
- ac->clear_ps_filter = true;
+ tid->clear_ps_filter = true;
if (ath_tid_has_buffered(tid)) {
ath_tx_queue_tid(sc, txq, tid);
@@ -1621,7 +1604,7 @@ void ath_tx_aggr_resume(struct ath_softc
an = (struct ath_node *)sta->drv_priv;
tid = ATH_AN_2_TID(an, tidno);
- txq = tid->ac->txq;
+ txq = tid->txq;
ath_txq_lock(sc, txq);
@@ -1660,7 +1643,7 @@ void ath9k_release_buffered_frames(struc
tid = ATH_AN_2_TID(an, i);
- ath_txq_lock(sc, tid->ac->txq);
+ ath_txq_lock(sc, tid->txq);
while (nframes > 0) {
bf = ath_tx_get_tid_subframe(sc, sc->tx.uapsdq, tid, &tid_q);
if (!bf)
@@ -1684,7 +1667,7 @@ void ath9k_release_buffered_frames(struc
if (an->sta && !ath_tid_has_buffered(tid))
ieee80211_sta_set_buffered(an->sta, i, false);
}
- ath_txq_unlock_complete(sc, tid->ac->txq);
+ ath_txq_unlock_complete(sc, tid->txq);
}
if (list_empty(&bf_q))
@@ -1933,9 +1916,8 @@ void ath_tx_cleanupq(struct ath_softc *s
void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
{
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
- struct ath_atx_ac *ac, *last_ac;
struct ath_atx_tid *tid, *last_tid;
- struct list_head *ac_list;
+ struct list_head *tid_list;
bool sent = false;
if (txq->mac80211_qnum < 0)
@@ -1945,63 +1927,46 @@ void ath_txq_schedule(struct ath_softc *
return;
spin_lock_bh(&sc->chan_lock);
- ac_list = &sc->cur_chan->acq[txq->mac80211_qnum];
+ tid_list = &sc->cur_chan->acq[txq->mac80211_qnum];
- if (list_empty(ac_list)) {
+ if (list_empty(tid_list)) {
spin_unlock_bh(&sc->chan_lock);
return;
}
rcu_read_lock();
- last_ac = list_entry(ac_list->prev, struct ath_atx_ac, list);
- while (!list_empty(ac_list)) {
+ last_tid = list_entry(tid_list->prev, struct ath_atx_tid, list);
+ while (!list_empty(tid_list)) {
bool stop = false;
if (sc->cur_chan->stopped)
break;
- ac = list_first_entry(ac_list, struct ath_atx_ac, list);
- last_tid = list_entry(ac->tid_q.prev, struct ath_atx_tid, list);
- list_del(&ac->list);
- ac->sched = false;
-
- while (!list_empty(&ac->tid_q)) {
-
- tid = list_first_entry(&ac->tid_q, struct ath_atx_tid,
- list);
- list_del(&tid->list);
- tid->sched = false;
-
- if (ath_tx_sched_aggr(sc, txq, tid, &stop))
- sent = true;
-
- /*
- * add tid to round-robin queue if more frames
- * are pending for the tid
- */
- if (ath_tid_has_buffered(tid))
- ath_tx_queue_tid(sc, txq, tid);
+ tid = list_first_entry(tid_list, struct ath_atx_tid, list);
+ list_del(&tid->list);
+ tid->sched = false;
- if (stop || tid == last_tid)
- break;
- }
+ if (ath_tx_sched_aggr(sc, txq, tid, &stop))
+ sent = true;
- if (!list_empty(&ac->tid_q) && !ac->sched) {
- ac->sched = true;
- list_add_tail(&ac->list, ac_list);
- }
+ /*
+ * add tid to round-robin queue if more frames
+ * are pending for the tid
+ */
+ if (ath_tid_has_buffered(tid))
+ ath_tx_queue_tid(sc, txq, tid);
if (stop)
break;
- if (ac == last_ac) {
+ if (tid == last_tid) {
if (!sent)
break;
sent = false;
- last_ac = list_entry(ac_list->prev,
- struct ath_atx_ac, list);
+ last_tid = list_entry(tid_list->prev,
+ struct ath_atx_tid, list);
}
}
@@ -2391,10 +2356,10 @@ int ath_tx_start(struct ieee80211_hw *hw
txq = sc->tx.uapsdq;
ath_txq_lock(sc, txq);
} else if (txctl->an && queue) {
- WARN_ON(tid->ac->txq != txctl->txq);
+ WARN_ON(tid->txq != txctl->txq);
if (info->flags & IEEE80211_TX_CTL_CLEAR_PS_FILT)
- tid->ac->clear_ps_filter = true;
+ tid->clear_ps_filter = true;
/*
* Add this frame to software queue for scheduling later
@@ -2888,7 +2853,6 @@ int ath_tx_init(struct ath_softc *sc, in
void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
{
struct ath_atx_tid *tid;
- struct ath_atx_ac *ac;
int tidno, acno;
for (tidno = 0, tid = &an->tid[tidno];
@@ -2901,24 +2865,16 @@ void ath_tx_node_init(struct ath_softc *
tid->baw_head = tid->baw_tail = 0;
tid->sched = false;
tid->active = false;
+ tid->clear_ps_filter = true;
__skb_queue_head_init(&tid->buf_q);
__skb_queue_head_init(&tid->retry_q);
acno = TID_TO_WME_AC(tidno);
- tid->ac = &an->ac[acno];
- }
-
- for (acno = 0, ac = &an->ac[acno];
- acno < IEEE80211_NUM_ACS; acno++, ac++) {
- ac->sched = false;
- ac->clear_ps_filter = true;
- ac->txq = sc->tx.txq_map[acno];
- INIT_LIST_HEAD(&ac->tid_q);
+ tid->txq = sc->tx.txq_map[acno];
}
}
void ath_tx_node_cleanup(struct ath_softc *sc, struct ath_node *an)
{
- struct ath_atx_ac *ac;
struct ath_atx_tid *tid;
struct ath_txq *txq;
int tidno;
@@ -2926,8 +2882,7 @@ void ath_tx_node_cleanup(struct ath_soft
for (tidno = 0, tid = &an->tid[tidno];
tidno < IEEE80211_NUM_TIDS; tidno++, tid++) {
- ac = tid->ac;
- txq = ac->txq;
+ txq = tid->txq;
ath_txq_lock(sc, txq);
@@ -2936,11 +2891,6 @@ void ath_tx_node_cleanup(struct ath_soft
tid->sched = false;
}
- if (ac->sched) {
- list_del(&ac->list);
- tid->ac->sched = false;
- }
-
ath_tid_drain(sc, txq, tid);
tid->active = false;

View file

@ -1,90 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 4 Apr 2015 18:42:33 +0200
Subject: [PATCH] ath9k: remove the sched field in struct ath_atx_tid
Use list_empty(&tid->list) instead
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -245,7 +245,6 @@ struct ath_atx_tid {
int baw_tail; /* next unused tx buffer slot */
s8 bar_index;
- bool sched;
bool active;
bool clear_ps_filter;
};
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -113,12 +113,9 @@ static void ath_tx_queue_tid(struct ath_
if (!ctx)
return;
- if (tid->sched)
- return;
-
- tid->sched = true;
list = &ctx->acq[TID_TO_WME_AC(tid->tidno)];
- list_add_tail(&tid->list, list);
+ if (list_empty(&tid->list))
+ list_add_tail(&tid->list, list);
}
static struct ath_frame_info *get_frame_info(struct sk_buff *skb)
@@ -1556,15 +1553,14 @@ void ath_tx_aggr_sleep(struct ieee80211_
ath_txq_lock(sc, txq);
- if (!tid->sched) {
+ if (list_empty(&tid->list)) {
ath_txq_unlock(sc, txq);
continue;
}
buffered = ath_tid_has_buffered(tid);
- tid->sched = false;
- list_del(&tid->list);
+ list_del_init(&tid->list);
ath_txq_unlock(sc, txq);
@@ -1944,8 +1940,7 @@ void ath_txq_schedule(struct ath_softc *
break;
tid = list_first_entry(tid_list, struct ath_atx_tid, list);
- list_del(&tid->list);
- tid->sched = false;
+ list_del_init(&tid->list);
if (ath_tx_sched_aggr(sc, txq, tid, &stop))
sent = true;
@@ -2863,11 +2858,11 @@ void ath_tx_node_init(struct ath_softc *
tid->seq_start = tid->seq_next = 0;
tid->baw_size = WME_MAX_BA;
tid->baw_head = tid->baw_tail = 0;
- tid->sched = false;
tid->active = false;
tid->clear_ps_filter = true;
__skb_queue_head_init(&tid->buf_q);
__skb_queue_head_init(&tid->retry_q);
+ INIT_LIST_HEAD(&tid->list);
acno = TID_TO_WME_AC(tidno);
tid->txq = sc->tx.txq_map[acno];
}
@@ -2886,10 +2881,8 @@ void ath_tx_node_cleanup(struct ath_soft
ath_txq_lock(sc, txq);
- if (tid->sched) {
- list_del(&tid->list);
- tid->sched = false;
- }
+ if (!list_empty(&tid->list))
+ list_del_init(&tid->list);
ath_tid_drain(sc, txq, tid);
tid->active = false;

View file

@ -1,161 +0,0 @@
From: Denys Vlasenko <dvlasenk@redhat.com>
Date: Wed, 15 Jul 2015 14:56:06 +0200
Subject: [PATCH] mac80211: Deinline rate_control_rate_init,
rate_control_rate_update
With this .config: http://busybox.net/~vda/kernel_config,
after deinlining these functions have sizes and callsite counts
as follows:
rate_control_rate_init: 554 bytes, 8 calls
rate_control_rate_update: 1596 bytes, 5 calls
Total size reduction: about 11 kbytes.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
CC: John Linville <linville@tuxdriver.com>
CC: Michal Kazior <michal.kazior@tieto.com>
CC: Johannes Berg <johannes.berg@intel.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
CC: linux-kernel@vger.kernel.org
---
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -29,6 +29,65 @@ module_param(ieee80211_default_rc_algo,
MODULE_PARM_DESC(ieee80211_default_rc_algo,
"Default rate control algorithm for mac80211 to use");
+void rate_control_rate_init(struct sta_info *sta)
+{
+ struct ieee80211_local *local = sta->sdata->local;
+ struct rate_control_ref *ref = sta->rate_ctrl;
+ struct ieee80211_sta *ista = &sta->sta;
+ void *priv_sta = sta->rate_ctrl_priv;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+
+ ieee80211_sta_set_rx_nss(sta);
+
+ if (!ref)
+ return;
+
+ rcu_read_lock();
+
+ chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
+ if (WARN_ON(!chanctx_conf)) {
+ rcu_read_unlock();
+ return;
+ }
+
+ sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
+
+ spin_lock_bh(&sta->rate_ctrl_lock);
+ ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
+ priv_sta);
+ spin_unlock_bh(&sta->rate_ctrl_lock);
+ rcu_read_unlock();
+ set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
+}
+
+void rate_control_rate_update(struct ieee80211_local *local,
+ struct ieee80211_supported_band *sband,
+ struct sta_info *sta, u32 changed)
+{
+ struct rate_control_ref *ref = local->rate_ctrl;
+ struct ieee80211_sta *ista = &sta->sta;
+ void *priv_sta = sta->rate_ctrl_priv;
+ struct ieee80211_chanctx_conf *chanctx_conf;
+
+ if (ref && ref->ops->rate_update) {
+ rcu_read_lock();
+
+ chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
+ if (WARN_ON(!chanctx_conf)) {
+ rcu_read_unlock();
+ return;
+ }
+
+ spin_lock_bh(&sta->rate_ctrl_lock);
+ ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
+ ista, priv_sta, changed);
+ spin_unlock_bh(&sta->rate_ctrl_lock);
+ rcu_read_unlock();
+ }
+ drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
+}
+
int ieee80211_rate_control_register(const struct rate_control_ops *ops)
{
struct rate_control_alg *alg;
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -71,64 +71,10 @@ rate_control_tx_status_noskb(struct ieee
spin_unlock_bh(&sta->rate_ctrl_lock);
}
-static inline void rate_control_rate_init(struct sta_info *sta)
-{
- struct ieee80211_local *local = sta->sdata->local;
- struct rate_control_ref *ref = sta->rate_ctrl;
- struct ieee80211_sta *ista = &sta->sta;
- void *priv_sta = sta->rate_ctrl_priv;
- struct ieee80211_supported_band *sband;
- struct ieee80211_chanctx_conf *chanctx_conf;
-
- ieee80211_sta_set_rx_nss(sta);
-
- if (!ref)
- return;
-
- rcu_read_lock();
-
- chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
- if (WARN_ON(!chanctx_conf)) {
- rcu_read_unlock();
- return;
- }
-
- sband = local->hw.wiphy->bands[chanctx_conf->def.chan->band];
-
- spin_lock_bh(&sta->rate_ctrl_lock);
- ref->ops->rate_init(ref->priv, sband, &chanctx_conf->def, ista,
- priv_sta);
- spin_unlock_bh(&sta->rate_ctrl_lock);
- rcu_read_unlock();
- set_sta_flag(sta, WLAN_STA_RATE_CONTROL);
-}
-
-static inline void rate_control_rate_update(struct ieee80211_local *local,
+void rate_control_rate_init(struct sta_info *sta);
+void rate_control_rate_update(struct ieee80211_local *local,
struct ieee80211_supported_band *sband,
- struct sta_info *sta, u32 changed)
-{
- struct rate_control_ref *ref = local->rate_ctrl;
- struct ieee80211_sta *ista = &sta->sta;
- void *priv_sta = sta->rate_ctrl_priv;
- struct ieee80211_chanctx_conf *chanctx_conf;
-
- if (ref && ref->ops->rate_update) {
- rcu_read_lock();
-
- chanctx_conf = rcu_dereference(sta->sdata->vif.chanctx_conf);
- if (WARN_ON(!chanctx_conf)) {
- rcu_read_unlock();
- return;
- }
-
- spin_lock_bh(&sta->rate_ctrl_lock);
- ref->ops->rate_update(ref->priv, sband, &chanctx_conf->def,
- ista, priv_sta, changed);
- spin_unlock_bh(&sta->rate_ctrl_lock);
- rcu_read_unlock();
- }
- drv_sta_rc_update(local, sta->sdata, &sta->sta, changed);
-}
+ struct sta_info *sta, u32 changed);
static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
struct sta_info *sta, gfp_t gfp)

View file

@ -1,116 +0,0 @@
From: Denys Vlasenko <dvlasenk@redhat.com>
Date: Wed, 15 Jul 2015 14:56:05 +0200
Subject: [PATCH] mac80211: Deinline drv_sta_state
With this .config: http://busybox.net/~vda/kernel_config,
after deinlining the function size is 3132 bytes and there are
7 callsites.
Total size reduction: about 20 kbytes.
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
CC: John Linville <linville@tuxdriver.com>
CC: Michal Kazior <michal.kazior@tieto.com>
Cc: Johannes Berg <johannes.berg@intel.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
CC: linux-kernel@vger.kernel.org
---
create mode 100644 net/mac80211/driver-ops.c
--- a/net/mac80211/Makefile
+++ b/net/mac80211/Makefile
@@ -3,6 +3,7 @@ obj-$(CPTCFG_MAC80211) += mac80211.o
# mac80211 objects
mac80211-y := \
main.o status.o \
+ driver-ops.o \
sta_info.o \
wep.o \
wpa.o \
--- /dev/null
+++ b/net/mac80211/driver-ops.c
@@ -0,0 +1,41 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <net/mac80211.h>
+#include "ieee80211_i.h"
+#include "trace.h"
+#include "driver-ops.h"
+
+__must_check
+int drv_sta_state(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct sta_info *sta,
+ enum ieee80211_sta_state old_state,
+ enum ieee80211_sta_state new_state)
+{
+ int ret = 0;
+
+ might_sleep();
+
+ sdata = get_bss_sdata(sdata);
+ if (!check_sdata_in_driver(sdata))
+ return -EIO;
+
+ trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
+ if (local->ops->sta_state) {
+ ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
+ old_state, new_state);
+ } else if (old_state == IEEE80211_STA_AUTH &&
+ new_state == IEEE80211_STA_ASSOC) {
+ ret = drv_sta_add(local, sdata, &sta->sta);
+ if (ret == 0)
+ sta->uploaded = true;
+ } else if (old_state == IEEE80211_STA_ASSOC &&
+ new_state == IEEE80211_STA_AUTH) {
+ drv_sta_remove(local, sdata, &sta->sta);
+ }
+ trace_drv_return_int(local, ret);
+ return ret;
+}
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -573,37 +573,12 @@ static inline void drv_sta_pre_rcu_remov
trace_drv_return_void(local);
}
-static inline __must_check
+__must_check
int drv_sta_state(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,
struct sta_info *sta,
enum ieee80211_sta_state old_state,
- enum ieee80211_sta_state new_state)
-{
- int ret = 0;
-
- might_sleep();
-
- sdata = get_bss_sdata(sdata);
- if (!check_sdata_in_driver(sdata))
- return -EIO;
-
- trace_drv_sta_state(local, sdata, &sta->sta, old_state, new_state);
- if (local->ops->sta_state) {
- ret = local->ops->sta_state(&local->hw, &sdata->vif, &sta->sta,
- old_state, new_state);
- } else if (old_state == IEEE80211_STA_AUTH &&
- new_state == IEEE80211_STA_ASSOC) {
- ret = drv_sta_add(local, sdata, &sta->sta);
- if (ret == 0)
- sta->uploaded = true;
- } else if (old_state == IEEE80211_STA_ASSOC &&
- new_state == IEEE80211_STA_AUTH) {
- drv_sta_remove(local, sdata, &sta->sta);
- }
- trace_drv_return_int(local, ret);
- return ret;
-}
+ enum ieee80211_sta_state new_state);
static inline void drv_sta_rc_update(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,

View file

@ -1,30 +0,0 @@
From: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
Date: Wed, 22 Jul 2015 10:42:43 +0200
Subject: [PATCH] ath9k: Fix NF CCA limits for AR9287 and AR9227
The FreeBSD driver [0] uses the same 2G values as for the AR9280 chips.
Using the same values in ath9k results in much better throughput for me.
Before this patch I had a huge amount of packet loss (sometimes up to
40%) and the max transfer speed was somewhere around 5Mbit/s. With this
patch applied I have zero packet loss and ten times the throughput.
My device uses a AR9227 which is the PCI variant of the AR9287.
[0] http://bxr.su/FreeBSD/sys/dev/ath/ath_hal/ar9002/ar9287.h
Signed-off-by: Martin Blumenstingl <martin.blumenstingl@googlemail.com>
---
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -610,8 +610,8 @@
#define AR_PHY_CCA_MIN_GOOD_VAL_9271_2GHZ -127
#define AR_PHY_CCA_MAX_GOOD_VAL_9271_2GHZ -116
-#define AR_PHY_CCA_NOM_VAL_9287_2GHZ -120
+#define AR_PHY_CCA_NOM_VAL_9287_2GHZ -112
#define AR_PHY_CCA_MIN_GOOD_VAL_9287_2GHZ -127
-#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ -110
+#define AR_PHY_CCA_MAX_GOOD_VAL_9287_2GHZ -97
#endif

View file

@ -1,20 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 30 Jul 2015 14:12:25 +0200
Subject: [PATCH] mac80211: make local->tx_headroom a multiple of 4
This ensures that mac80211 generated management frames and beacons are
aligned before being passed to the driver
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1031,6 +1031,7 @@ int ieee80211_register_hw(struct ieee802
*/
local->tx_headroom = max_t(unsigned int , local->hw.extra_tx_headroom,
IEEE80211_TX_STATUS_HEADROOM);
+ local->tx_headroom = ALIGN(local->tx_headroom, 4);
debugfs_hw_add(local);

View file

@ -1,34 +0,0 @@
From: Adrien Schildknecht <adrien+dev@schischi.me>
Date: Tue, 28 Jul 2015 10:30:16 +0200
Subject: [PATCH] mac80211: fix invalid read in minstrel_sort_best_tp_rates()
At the last iteration of the loop, j may equal zero and thus
tp_list[j - 1] causes an invalid read.
Changed the logic of the loop so that j - 1 is always >= 0.
Signed-off-by: Adrien Schildknecht <adrien+dev@schischi.me>
---
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -92,14 +92,15 @@ int minstrel_get_tp_avg(struct minstrel_
static inline void
minstrel_sort_best_tp_rates(struct minstrel_sta_info *mi, int i, u8 *tp_list)
{
- int j = MAX_THR_RATES;
- struct minstrel_rate_stats *tmp_mrs = &mi->r[j - 1].stats;
+ int j;
+ struct minstrel_rate_stats *tmp_mrs;
struct minstrel_rate_stats *cur_mrs = &mi->r[i].stats;
- while (j > 0 && (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_ewma) >
- minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_ewma))) {
- j--;
+ for (j = MAX_THR_RATES; j > 0; --j) {
tmp_mrs = &mi->r[tp_list[j - 1]].stats;
+ if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_ewma) <=
+ minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_ewma))
+ break;
}
if (j < MAX_THR_RATES - 1)

View file

@ -1,45 +0,0 @@
From: Vineet Gupta <Vineet.Gupta1@synopsys.com>
Date: Thu, 9 Jul 2015 13:43:18 +0530
Subject: [PATCH] brcmfmac: dhd_sdio.c: use existing atomic_or primitive
There's already a generic implementation so use that instead.
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -2564,15 +2564,6 @@ static inline void brcmf_sdio_clrintr(st
}
}
-static void atomic_orr(int val, atomic_t *v)
-{
- int old_val;
-
- old_val = atomic_read(v);
- while (atomic_cmpxchg(v, old_val, val | old_val) != old_val)
- old_val = atomic_read(v);
-}
-
static int brcmf_sdio_intr_rstatus(struct brcmf_sdio *bus)
{
struct brcmf_core *buscore;
@@ -2595,7 +2586,7 @@ static int brcmf_sdio_intr_rstatus(struc
if (val) {
brcmf_sdiod_regwl(bus->sdiodev, addr, val, &ret);
bus->sdcnt.f1regdata++;
- atomic_orr(val, &bus->intstatus);
+ atomic_or(val, &bus->intstatus);
}
return ret;
@@ -2712,7 +2703,7 @@ static void brcmf_sdio_dpc(struct brcmf_
/* Keep still-pending events for next scheduling */
if (intstatus)
- atomic_orr(intstatus, &bus->intstatus);
+ atomic_or(intstatus, &bus->intstatus);
brcmf_sdio_clrintr(bus);

View file

@ -1,46 +0,0 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Thu, 20 Aug 2015 00:16:42 +0200
Subject: [PATCH] brcmfmac: check all combinations when setting wiphy's
addresses
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Broadcom is working on better reflection of interface combinations. With
upcoming patches we may have 1st combination supporting less interfaces
than others.
To don't run out of addresses check all combinations to find the one
with the greatest max_interfaces value.
Signed-off-by: Rafał Miłecki <zajec5@gmail.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
@@ -5786,7 +5786,9 @@ static void brcmf_wiphy_wowl_params(stru
static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
{
struct brcmf_pub *drvr = ifp->drvr;
+ const struct ieee80211_iface_combination *combo;
struct ieee80211_supported_band *band;
+ u16 max_interfaces = 0;
__le32 bandlist[3];
u32 n_bands;
int err, i;
@@ -5799,8 +5801,13 @@ static int brcmf_setup_wiphy(struct wiph
if (err)
return err;
- for (i = 0; i < wiphy->iface_combinations->max_interfaces &&
- i < ARRAY_SIZE(drvr->addresses); i++) {
+ for (i = 0, combo = wiphy->iface_combinations;
+ i < wiphy->n_iface_combinations; i++, combo++) {
+ max_interfaces = max(max_interfaces, combo->max_interfaces);
+ }
+
+ for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
+ i++) {
u8 *addr = drvr->addresses[i].addr;
memcpy(addr, drvr->mac, ETH_ALEN);

View file

@ -1,204 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Thu, 20 Aug 2015 22:06:03 +0200
Subject: [PATCH] brcmfmac: correct interface combination info
The interface combination provided by brcmfmac did not truly reflect
the combinations supported by driver and/or firmware.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Pontus Fuchs <pontusf@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
@@ -5695,63 +5695,132 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] =
}
};
+/**
+ * brcmf_setup_ifmodes() - determine interface modes and combinations.
+ *
+ * @wiphy: wiphy object.
+ * @ifp: interface object needed for feat module api.
+ *
+ * The interface modes and combinations are determined dynamically here
+ * based on firmware functionality.
+ *
+ * no p2p and no mbss:
+ *
+ * #STA <= 1, #AP <= 1, channels = 1, 2 total
+ *
+ * no p2p and mbss:
+ *
+ * #STA <= 1, #AP <= 1, channels = 1, 2 total
+ * #AP <= 4, matching BI, channels = 1, 4 total
+ *
+ * p2p, no mchan, and mbss:
+ *
+ * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
+ * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
+ * #AP <= 4, matching BI, channels = 1, 4 total
+ *
+ * p2p, mchan, and mbss:
+ *
+ * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
+ * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
+ * #AP <= 4, matching BI, channels = 1, 4 total
+ */
static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
{
struct ieee80211_iface_combination *combo = NULL;
- struct ieee80211_iface_limit *limits = NULL;
- int i = 0, max_iface_cnt;
+ struct ieee80211_iface_limit *c0_limits = NULL;
+ struct ieee80211_iface_limit *p2p_limits = NULL;
+ struct ieee80211_iface_limit *mbss_limits = NULL;
+ bool mbss, p2p;
+ int i, c, n_combos;
- combo = kzalloc(sizeof(*combo), GFP_KERNEL);
+ mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
+ p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
+
+ n_combos = 1 + !!p2p + !!mbss;
+ combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
if (!combo)
goto err;
- limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL);
- if (!limits)
+ c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
+ if (!c0_limits)
goto err;
+ if (p2p) {
+ p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
+ if (!p2p_limits)
+ goto err;
+ }
+
+ if (mbss) {
+ mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
+ if (!mbss_limits)
+ goto err;
+ }
+
wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
BIT(NL80211_IFTYPE_ADHOC) |
BIT(NL80211_IFTYPE_AP);
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
- combo->num_different_channels = 2;
- else
- combo->num_different_channels = 1;
-
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
- limits[i].max = 1;
- limits[i++].types = BIT(NL80211_IFTYPE_STATION);
- limits[i].max = 4;
- limits[i++].types = BIT(NL80211_IFTYPE_AP);
- max_iface_cnt = 5;
- } else {
- limits[i].max = 2;
- limits[i++].types = BIT(NL80211_IFTYPE_STATION) |
- BIT(NL80211_IFTYPE_AP);
- max_iface_cnt = 2;
- }
-
- if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) {
+ c = 0;
+ i = 0;
+ combo[c].num_different_channels = 1;
+ c0_limits[i].max = 1;
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
+ if (p2p) {
+ if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
+ combo[c].num_different_channels = 2;
wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) |
BIT(NL80211_IFTYPE_P2P_DEVICE);
- limits[i].max = 1;
- limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
- BIT(NL80211_IFTYPE_P2P_GO);
- limits[i].max = 1;
- limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
- max_iface_cnt += 2;
- }
- combo->max_interfaces = max_iface_cnt;
- combo->limits = limits;
- combo->n_limits = i;
+ 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);
+ } else {
+ c0_limits[i].max = 1;
+ c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
+ }
+ combo[c].max_interfaces = i;
+ combo[c].n_limits = i;
+ combo[c].limits = c0_limits;
+
+ if (p2p) {
+ c++;
+ i = 0;
+ combo[c].num_different_channels = 1;
+ p2p_limits[i].max = 1;
+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
+ p2p_limits[i].max = 1;
+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
+ p2p_limits[i].max = 1;
+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
+ p2p_limits[i].max = 1;
+ p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
+ combo[c].max_interfaces = i;
+ combo[c].n_limits = i;
+ combo[c].limits = p2p_limits;
+ }
+ if (mbss) {
+ c++;
+ combo[c].beacon_int_infra_match = true;
+ combo[c].num_different_channels = 1;
+ mbss_limits[0].max = 4;
+ mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
+ combo[c].max_interfaces = 4;
+ combo[c].n_limits = 1;
+ combo[c].limits = mbss_limits;
+ }
+ wiphy->n_iface_combinations = n_combos;
wiphy->iface_combinations = combo;
- wiphy->n_iface_combinations = 1;
return 0;
err:
- kfree(limits);
+ kfree(c0_limits);
+ kfree(p2p_limits);
+ kfree(mbss_limits);
kfree(combo);
return -ENOMEM;
}
@@ -6080,11 +6149,15 @@ static void brcmf_cfg80211_reg_notifier(
static void brcmf_free_wiphy(struct wiphy *wiphy)
{
+ int i;
+
if (!wiphy)
return;
- if (wiphy->iface_combinations)
- kfree(wiphy->iface_combinations->limits);
+ if (wiphy->iface_combinations) {
+ for (i = 0; i < wiphy->n_iface_combinations; i++)
+ kfree(wiphy->iface_combinations[i].limits);
+ }
kfree(wiphy->iface_combinations);
if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);

View file

@ -1,87 +0,0 @@
From: Franky Lin <frankyl@broadcom.com>
Date: Thu, 20 Aug 2015 22:06:04 +0200
Subject: [PATCH] brcmfmac: add debugfs entry for msgbuf statistics
Expose ring buffer read/write pointers and other useful statistics
through debugfs.
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@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/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -1360,6 +1360,60 @@ void brcmf_msgbuf_delete_flowring(struct
}
}
+#ifdef DEBUG
+static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)
+{
+ struct brcmf_bus *bus_if = dev_get_drvdata(seq->private);
+ struct brcmf_pub *drvr = bus_if->drvr;
+ struct brcmf_msgbuf *msgbuf = (struct brcmf_msgbuf *)drvr->proto->pd;
+ struct brcmf_commonring *commonring;
+ u16 i;
+ struct brcmf_flowring_ring *ring;
+ struct brcmf_flowring_hash *hash;
+
+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT];
+ seq_printf(seq, "h2d_ctl_submit: rp %4u, wp %4u, depth %4u\n",
+ commonring->r_ptr, commonring->w_ptr, commonring->depth);
+ commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_RXPOST_SUBMIT];
+ seq_printf(seq, "h2d_rx_submit: rp %4u, wp %4u, depth %4u\n",
+ commonring->r_ptr, commonring->w_ptr, commonring->depth);
+ commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_CONTROL_COMPLETE];
+ seq_printf(seq, "d2h_ctl_cmplt: rp %4u, wp %4u, depth %4u\n",
+ commonring->r_ptr, commonring->w_ptr, commonring->depth);
+ commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_TX_COMPLETE];
+ seq_printf(seq, "d2h_tx_cmplt: rp %4u, wp %4u, depth %4u\n",
+ commonring->r_ptr, commonring->w_ptr, commonring->depth);
+ commonring = msgbuf->commonrings[BRCMF_D2H_MSGRING_RX_COMPLETE];
+ seq_printf(seq, "d2h_rx_cmplt: rp %4u, wp %4u, depth %4u\n",
+ commonring->r_ptr, commonring->w_ptr, commonring->depth);
+
+ seq_printf(seq, "\nh2d_flowrings: depth %u\n",
+ BRCMF_H2D_TXFLOWRING_MAX_ITEM);
+ seq_puts(seq, "Active flowrings:\n");
+ hash = msgbuf->flow->hash;
+ for (i = 0; i < msgbuf->flow->nrofrings; i++) {
+ if (!msgbuf->flow->rings[i])
+ continue;
+ ring = msgbuf->flow->rings[i];
+ if (ring->status != RING_OPEN)
+ continue;
+ commonring = msgbuf->flowrings[i];
+ hash = &msgbuf->flow->hash[ring->hash_id];
+ seq_printf(seq, "id %3u: rp %4u, wp %4u, qlen %4u, blocked %u\n"
+ " ifidx %u, fifo %u, da %pM\n",
+ i, commonring->r_ptr, commonring->w_ptr,
+ skb_queue_len(&ring->skblist), ring->blocked,
+ hash->ifidx, hash->fifo, hash->mac);
+ }
+
+ return 0;
+}
+#else
+static int brcmf_msgbuf_stats_read(struct seq_file *seq, void *data)
+{
+ return 0;
+}
+#endif
int brcmf_proto_msgbuf_attach(struct brcmf_pub *drvr)
{
@@ -1460,6 +1514,8 @@ int brcmf_proto_msgbuf_attach(struct brc
spin_lock_init(&msgbuf->flowring_work_lock);
INIT_LIST_HEAD(&msgbuf->work_queue);
+ brcmf_debugfs_add_entry(drvr, "msgbuf_stats", brcmf_msgbuf_stats_read);
+
return 0;
fail:

View file

@ -1,83 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Thu, 20 Aug 2015 22:06:05 +0200
Subject: [PATCH] brcmfmac: make use of cfg80211_check_combinations()
Use cfg80211_check_combinations() so we can bail out early when an
interface add or change results in an invalid combination.
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/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -469,6 +469,36 @@ brcmf_find_wpsie(const u8 *parse, u32 le
return NULL;
}
+static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
+ struct brcmf_cfg80211_vif *vif,
+ enum nl80211_iftype new_type)
+{
+ int iftype_num[NUM_NL80211_IFTYPES];
+ struct brcmf_cfg80211_vif *pos;
+
+ memset(&iftype_num[0], 0, sizeof(iftype_num));
+ list_for_each_entry(pos, &cfg->vif_list, list)
+ if (pos == vif)
+ iftype_num[new_type]++;
+ else
+ iftype_num[pos->wdev.iftype]++;
+
+ return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
+}
+
+static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
+ enum nl80211_iftype new_type)
+{
+ int iftype_num[NUM_NL80211_IFTYPES];
+ struct brcmf_cfg80211_vif *pos;
+
+ memset(&iftype_num[0], 0, sizeof(iftype_num));
+ list_for_each_entry(pos, &cfg->vif_list, list)
+ iftype_num[pos->wdev.iftype]++;
+
+ iftype_num[new_type]++;
+ return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
+}
static void convert_key_from_CPU(struct brcmf_wsec_key *key,
struct brcmf_wsec_key_le *key_le)
@@ -663,8 +693,14 @@ static struct wireless_dev *brcmf_cfg802
struct vif_params *params)
{
struct wireless_dev *wdev;
+ int err;
brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
+ err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
+ if (err) {
+ brcmf_err("iface validation failed: err=%d\n", err);
+ return ERR_PTR(err);
+ }
switch (type) {
case NL80211_IFTYPE_ADHOC:
case NL80211_IFTYPE_STATION:
@@ -823,8 +859,12 @@ brcmf_cfg80211_change_iface(struct wiphy
s32 ap = 0;
s32 err = 0;
- brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
-
+ brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type);
+ err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
+ if (err) {
+ brcmf_err("iface validation failed: err=%d\n", err);
+ return err;
+ }
switch (type) {
case NL80211_IFTYPE_MONITOR:
case NL80211_IFTYPE_WDS:

View file

@ -1,48 +0,0 @@
From: Franky Lin <frankyl@broadcom.com>
Date: Thu, 20 Aug 2015 22:06:06 +0200
Subject: [PATCH] brcmfmac: block the correct flowring when backup queue
overflow
brcmf_flowring_block blocks the last active flowring under the same
interface instead of the one provided by caller. This could lead to a
dead lock of netif stop if there are more than one flowring under the
interface and the traffic is high enough so brcmf_flowring_enqueue can
not unblock the ring right away.
Reviewed-by: Pieter-Paul Giesberts <pieterpg@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/flowring.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
@@ -194,11 +194,15 @@ static void brcmf_flowring_block(struct
spin_lock_irqsave(&flow->block_lock, flags);
ring = flow->rings[flowid];
+ if (ring->blocked == blocked) {
+ spin_unlock_irqrestore(&flow->block_lock, flags);
+ return;
+ }
ifidx = brcmf_flowring_ifidx_get(flow, flowid);
currently_blocked = false;
for (i = 0; i < flow->nrofrings; i++) {
- if (flow->rings[i]) {
+ if ((flow->rings[i]) && (i != flowid)) {
ring = flow->rings[i];
if ((ring->status == RING_OPEN) &&
(brcmf_flowring_ifidx_get(flow, i) == ifidx)) {
@@ -209,8 +213,8 @@ static void brcmf_flowring_block(struct
}
}
}
- ring->blocked = blocked;
- if (currently_blocked == blocked) {
+ flow->rings[flowid]->blocked = blocked;
+ if (currently_blocked) {
spin_unlock_irqrestore(&flow->block_lock, flags);
return;
}

View file

@ -1,52 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Thu, 20 Aug 2015 22:06:07 +0200
Subject: [PATCH] brcmfmac: bump highest event number for 4339 firmware
The event mask length is determined by the highest event number
that is specified in the driver. When this length is shorter than
firmware expects setting event mask will fail and device becomes
pretty useless. This issue was reported with bcm4339 firmware that
was recently released.
Reported-by: Pontus Fuchs <pontusf@broadcom.com>
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Pontus Fuchs <pontusf@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/fweh.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.h
@@ -85,7 +85,6 @@ struct brcmf_event;
BRCMF_ENUM_DEF(IF, 54) \
BRCMF_ENUM_DEF(P2P_DISC_LISTEN_COMPLETE, 55) \
BRCMF_ENUM_DEF(RSSI, 56) \
- BRCMF_ENUM_DEF(PFN_SCAN_COMPLETE, 57) \
BRCMF_ENUM_DEF(EXTLOG_MSG, 58) \
BRCMF_ENUM_DEF(ACTION_FRAME, 59) \
BRCMF_ENUM_DEF(ACTION_FRAME_COMPLETE, 60) \
@@ -103,8 +102,7 @@ struct brcmf_event;
BRCMF_ENUM_DEF(FIFO_CREDIT_MAP, 74) \
BRCMF_ENUM_DEF(ACTION_FRAME_RX, 75) \
BRCMF_ENUM_DEF(TDLS_PEER_EVENT, 92) \
- BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127) \
- BRCMF_ENUM_DEF(PSTA_PRIMARY_INTF_IND, 128)
+ BRCMF_ENUM_DEF(BCMC_CREDIT_SUPPORT, 127)
#define BRCMF_ENUM_DEF(id, val) \
BRCMF_E_##id = (val),
@@ -112,7 +110,11 @@ struct brcmf_event;
/* firmware event codes sent by the dongle */
enum brcmf_fweh_event_code {
BRCMF_FWEH_EVENT_ENUM_DEFLIST
- BRCMF_E_LAST
+ /* this determines event mask length which must match
+ * minimum length check in device firmware so it is
+ * hard-coded here.
+ */
+ BRCMF_E_LAST = 139
};
#undef BRCMF_ENUM_DEF

View file

@ -1,138 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:14:53 +0200
Subject: [PATCH] brcmfmac: consolidate ifp lookup in driver core
In rx path the firmware provide an interface index which is used to
map to a struct brcmf_if instance. However, this involves some trick
that is done in two places. This is changed by having driver core
providing brcmf_get_ifp() function.
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -276,6 +276,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
struct sk_buff *pktbuf)
{
struct brcmf_proto_bcdc_header *h;
+ struct brcmf_if *ifp;
brcmf_dbg(BCDC, "Enter\n");
@@ -289,30 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
trace_brcmf_bcdchdr(pktbuf->data);
h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
- *ifidx = BCDC_GET_IF_IDX(h);
- if (*ifidx >= BRCMF_MAX_IFS) {
- brcmf_err("rx data ifnum out of range (%d)\n", *ifidx);
+ ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
+ if (IS_ERR_OR_NULL(ifp)) {
+ brcmf_dbg(INFO, "no matching ifp found\n");
return -EBADE;
}
- /* The ifidx is the idx to map to matching netdev/ifp. When receiving
- * events this is easy because it contains the bssidx which maps
- * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
- * bssidx 1 is used for p2p0 and no data can be received or
- * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
- */
- if (*ifidx)
- (*ifidx)++;
-
if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
BCDC_PROTO_VER) {
brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
- brcmf_ifname(drvr, *ifidx), h->flags);
+ brcmf_ifname(drvr, ifp->ifidx), h->flags);
return -EBADE;
}
if (h->flags & BCDC_FLAG_SUM_GOOD) {
brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
- brcmf_ifname(drvr, *ifidx), h->flags);
+ brcmf_ifname(drvr, ifp->ifidx), h->flags);
pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
}
@@ -320,12 +312,15 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
skb_pull(pktbuf, BCDC_HEADER_LEN);
if (do_fws)
- brcmf_fws_hdrpull(drvr, *ifidx, h->data_offset << 2, pktbuf);
+ brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2,
+ pktbuf);
else
skb_pull(pktbuf, h->data_offset << 2);
if (pktbuf->len == 0)
return -ENODATA;
+
+ *ifidx = ifp->ifidx;
return 0;
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -83,6 +83,25 @@ char *brcmf_ifname(struct brcmf_pub *drv
return "<if_none>";
}
+struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
+{
+ if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
+ brcmf_err("ifidx %d out of range\n", ifidx);
+ return ERR_PTR(-ERANGE);
+ }
+
+ /* The ifidx is the idx to map to matching netdev/ifp. When receiving
+ * events this is easy because it contains the bssidx which maps
+ * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
+ * bssidx 1 is used for p2p0 and no data can be received or
+ * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
+ */
+ if (ifidx)
+ ifidx++;
+
+ return drvr->iflist[ifidx];
+}
+
static void _brcmf_set_multicast_list(struct work_struct *work)
{
struct brcmf_if *ifp;
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
@@ -202,7 +202,7 @@ int brcmf_netdev_wait_pend8021x(struct b
/* Return pointer to interface name */
char *brcmf_ifname(struct brcmf_pub *drvr, int idx);
-
+struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
char *name, u8 *mac_addr);
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -1081,16 +1081,8 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf
{
struct brcmf_if *ifp;
- /* The ifidx is the idx to map to matching netdev/ifp. When receiving
- * events this is easy because it contains the bssidx which maps
- * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
- * bssidx 1 is used for p2p0 and no data can be received or
- * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
- */
- if (ifidx)
- (ifidx)++;
- ifp = msgbuf->drvr->iflist[ifidx];
- if (!ifp || !ifp->ndev) {
+ ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
+ if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) {
brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
brcmu_pkt_buf_free_skb(skb);
return;

View file

@ -1,222 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:14:54 +0200
Subject: [PATCH] brcmfmac: make brcmf_proto_hdrpull() return struct
brcmf_if instance
Avoid spreading the ifidx in the driver, but have it return the
struct brcmf_if instance.
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -272,11 +272,11 @@ brcmf_proto_bcdc_hdrpush(struct brcmf_pu
}
static int
-brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
- struct sk_buff *pktbuf)
+brcmf_proto_bcdc_hdrpull(struct brcmf_pub *drvr, bool do_fws,
+ struct sk_buff *pktbuf, struct brcmf_if **ifp)
{
struct brcmf_proto_bcdc_header *h;
- struct brcmf_if *ifp;
+ struct brcmf_if *tmp_if;
brcmf_dbg(BCDC, "Enter\n");
@@ -290,21 +290,21 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
trace_brcmf_bcdchdr(pktbuf->data);
h = (struct brcmf_proto_bcdc_header *)(pktbuf->data);
- ifp = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
- if (IS_ERR_OR_NULL(ifp)) {
+ tmp_if = brcmf_get_ifp(drvr, BCDC_GET_IF_IDX(h));
+ if (!tmp_if) {
brcmf_dbg(INFO, "no matching ifp found\n");
return -EBADE;
}
if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) !=
BCDC_PROTO_VER) {
brcmf_err("%s: non-BCDC packet received, flags 0x%x\n",
- brcmf_ifname(drvr, ifp->ifidx), h->flags);
+ brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
return -EBADE;
}
if (h->flags & BCDC_FLAG_SUM_GOOD) {
brcmf_dbg(BCDC, "%s: BDC rcv, good checksum, flags 0x%x\n",
- brcmf_ifname(drvr, ifp->ifidx), h->flags);
+ brcmf_ifname(drvr, tmp_if->ifidx), h->flags);
pktbuf->ip_summed = CHECKSUM_UNNECESSARY;
}
@@ -312,7 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
skb_pull(pktbuf, BCDC_HEADER_LEN);
if (do_fws)
- brcmf_fws_hdrpull(drvr, ifp->ifidx, h->data_offset << 2,
+ brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2,
pktbuf);
else
skb_pull(pktbuf, h->data_offset << 2);
@@ -320,7 +320,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
if (pktbuf->len == 0)
return -ENODATA;
- *ifidx = ifp->ifidx;
+ *ifp = tmp_if;
return 0;
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -87,7 +87,7 @@ struct brcmf_if *brcmf_get_ifp(struct br
{
if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
brcmf_err("ifidx %d out of range\n", ifidx);
- return ERR_PTR(-ERANGE);
+ return NULL;
}
/* The ifidx is the idx to map to matching netdev/ifp. When receiving
@@ -539,17 +539,15 @@ void brcmf_rx_frame(struct device *dev,
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
struct brcmf_skb_reorder_data *rd;
- u8 ifidx;
int ret;
brcmf_dbg(DATA, "Enter: %s: rxp=%p\n", dev_name(dev), skb);
/* process and remove protocol-specific header */
- ret = brcmf_proto_hdrpull(drvr, true, &ifidx, skb);
- ifp = drvr->iflist[ifidx];
+ ret = brcmf_proto_hdrpull(drvr, true, skb, &ifp);
if (ret || !ifp || !ifp->ndev) {
- if ((ret != -ENODATA) && ifp)
+ if (ret != -ENODATA && ifp)
ifp->stats.rx_errors++;
brcmu_pkt_buf_free_skb(skb);
return;
@@ -592,17 +590,17 @@ void brcmf_txcomplete(struct device *dev
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
struct brcmf_pub *drvr = bus_if->drvr;
- u8 ifidx;
+ struct brcmf_if *ifp;
/* await txstatus signal for firmware if active */
if (brcmf_fws_fc_active(drvr->fws)) {
if (!success)
brcmf_fws_bustxfail(drvr->fws, txp);
} else {
- if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp))
+ if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
brcmu_pkt_buf_free_skb(txp);
else
- brcmf_txfinalize(drvr, txp, ifidx, success);
+ brcmf_txfinalize(drvr, txp, ifp->ifidx, success);
}
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1448,7 +1448,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
struct sk_buff *skb;
struct brcmf_skbuff_cb *skcb;
struct brcmf_fws_mac_descriptor *entry = NULL;
- u8 ifidx;
+ struct brcmf_if *ifp;
brcmf_dbg(DATA, "flags %d\n", flags);
@@ -1497,15 +1497,16 @@ brcmf_fws_txs_process(struct brcmf_fws_i
}
brcmf_fws_macdesc_return_req_credit(skb);
- if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) {
+ ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
+ if (ret) {
brcmu_pkt_buf_free_skb(skb);
return -EINVAL;
}
if (!remove_from_hanger)
- ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx,
+ ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
genbit, seq);
if (remove_from_hanger || ret)
- brcmf_txfinalize(fws->drvr, skb, ifidx, true);
+ brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true);
return 0;
}
@@ -1848,7 +1849,7 @@ static int brcmf_fws_commit_skb(struct b
entry->transit_count--;
if (entry->suppressed)
entry->suppr_transit_count--;
- brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
+ (void)brcmf_proto_hdrpull(fws->drvr, false, skb, NULL);
goto rollback;
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -522,7 +522,7 @@ static int brcmf_msgbuf_set_dcmd(struct
static int brcmf_msgbuf_hdrpull(struct brcmf_pub *drvr, bool do_fws,
- u8 *ifidx, struct sk_buff *skb)
+ struct sk_buff *skb, struct brcmf_if **ifp)
{
return -ENODEV;
}
@@ -1082,7 +1082,7 @@ brcmf_msgbuf_rx_skb(struct brcmf_msgbuf
struct brcmf_if *ifp;
ifp = brcmf_get_ifp(msgbuf->drvr, ifidx);
- if (IS_ERR_OR_NULL(ifp) || !ifp->ndev) {
+ if (!ifp || !ifp->ndev) {
brcmf_err("Received pkt for invalid ifidx %d\n", ifidx);
brcmu_pkt_buf_free_skb(skb);
return;
--- a/drivers/net/wireless/brcm80211/brcmfmac/proto.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/proto.h
@@ -24,8 +24,8 @@ enum proto_addr_mode {
struct brcmf_proto {
- int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws, u8 *ifidx,
- struct sk_buff *skb);
+ int (*hdrpull)(struct brcmf_pub *drvr, bool do_fws,
+ struct sk_buff *skb, struct brcmf_if **ifp);
int (*query_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd,
void *buf, uint len);
int (*set_dcmd)(struct brcmf_pub *drvr, int ifidx, uint cmd, void *buf,
@@ -46,9 +46,19 @@ int brcmf_proto_attach(struct brcmf_pub
void brcmf_proto_detach(struct brcmf_pub *drvr);
static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws,
- u8 *ifidx, struct sk_buff *skb)
+ struct sk_buff *skb,
+ struct brcmf_if **ifp)
{
- return drvr->proto->hdrpull(drvr, do_fws, ifidx, skb);
+ struct brcmf_if *tmp = NULL;
+
+ /* assure protocol is always called with
+ * non-null initialized pointer.
+ */
+ if (ifp)
+ *ifp = NULL;
+ else
+ ifp = &tmp;
+ return drvr->proto->hdrpull(drvr, do_fws, skb, ifp);
}
static inline int brcmf_proto_query_dcmd(struct brcmf_pub *drvr, int ifidx,
uint cmd, void *buf, uint len)

View file

@ -1,87 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:14:55 +0200
Subject: [PATCH] brcmfmac: change parameters for
brcmf_remove_interface()
Just pass the interface to be removed, ie. the struct brcmf_if instance.
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -4983,7 +4983,7 @@ brcmf_notify_connect_status_ap(struct br
brcmf_dbg(CONN, "AP mode link down\n");
complete(&cfg->vif_disabled);
if (ifp->vif->mbss)
- brcmf_remove_interface(ifp->drvr, ifp->bssidx);
+ brcmf_remove_interface(ifp);
return 0;
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -887,12 +887,13 @@ static void brcmf_del_if(struct brcmf_pu
}
}
-void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx)
+void brcmf_remove_interface(struct brcmf_if *ifp)
{
- if (drvr->iflist[bssidx]) {
- brcmf_fws_del_interface(drvr->iflist[bssidx]);
- brcmf_del_if(drvr, bssidx);
- }
+ if (!ifp || WARN_ON(ifp->drvr->iflist[ifp->bssidx] != ifp))
+ return;
+
+ brcmf_fws_del_interface(ifp);
+ brcmf_del_if(ifp->drvr, ifp->bssidx);
}
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr)
@@ -1122,7 +1123,7 @@ void brcmf_detach(struct device *dev)
/* make sure primary interface removed last */
for (i = BRCMF_MAX_IFS-1; i > -1; i--)
- brcmf_remove_interface(drvr, i);
+ brcmf_remove_interface(drvr->iflist[i]);
brcmf_cfg80211_detach(drvr->config);
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
@@ -206,7 +206,7 @@ struct brcmf_if *brcmf_get_ifp(struct br
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
char *name, u8 *mac_addr);
-void brcmf_remove_interface(struct brcmf_pub *drvr, u32 bssidx);
+void brcmf_remove_interface(struct brcmf_if *ifp);
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
void brcmf_txflowblock_if(struct brcmf_if *ifp,
enum brcmf_netif_stop_reason reason, bool state);
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -222,7 +222,7 @@ static void brcmf_fweh_handle_if_event(s
err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data);
if (ifp && ifevent->action == BRCMF_E_IF_DEL)
- brcmf_remove_interface(drvr, ifevent->bssidx);
+ brcmf_remove_interface(ifp);
}
/**
--- a/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/p2p.c
@@ -2140,7 +2140,7 @@ static void brcmf_p2p_delete_p2pdev(stru
{
cfg80211_unregister_wdev(&vif->wdev);
p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif = NULL;
- brcmf_remove_interface(vif->ifp->drvr, vif->ifp->bssidx);
+ brcmf_remove_interface(vif->ifp);
brcmf_free_vif(vif);
}

View file

@ -1,92 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:14:56 +0200
Subject: [PATCH] brcmfmac: only call brcmf_cfg80211_detach() when attach
was successful
In brcmf_bus_start() the function brcmf_cfg80211_attach() is called which
may fail. If this happens we should not call brcmf_cfg80211_detach() in
the failure path as it will result in NULL pointer dereference:
brcmf_fweh_activate_events: Set event_msgs error (-5)
brcmf_bus_start: failed: -5
brcmf_sdio_firmware_callback: dongle is not responding
BUG: unable to handle kernel NULL pointer dereference at 0000000000000068
IP: [<ffffffff811e8f08>] kernfs_find_ns+0x18/0xd0
PGD 0
Oops: 0000 [#1] SMP
Modules linked in: brcmfmac(O) brcmutil(O) cfg80211 auth_rpcgss
CPU: 1 PID: 45 Comm: kworker/1:1 Tainted: G O
Hardware name: Dell Inc. Latitude E6410/07XJP9, BIOS A07 02/15/2011
Workqueue: events request_firmware_work_func
task: ffff880036c09ac0 ti: ffff880036dd4000 task.ti: ffff880036dd4000
RIP: 0010:[<ffffffff811e8f08>] [<ffffffff811e8f08>] kernfs_find_ns+0x18/0xd0
RSP: 0018:ffff880036dd7a28 EFLAGS: 00010246
RAX: ffff880036c09ac0 RBX: 0000000000000000 RCX: 000000007fffffff
RDX: 0000000000000000 RSI: ffffffff816578b9 RDI: 0000000000000000
RBP: ffff880036dd7a48 R08: 0000000000000000 R09: ffff880036c0b340
R10: 00000000000002ec R11: ffff880036dd7b08 R12: ffffffff816578b9
R13: 0000000000000000 R14: ffffffff816578b9 R15: ffff8800c6c87000
FS: 0000000000000000(0000) GS:ffff88012bc40000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000068 CR3: 0000000001a0b000 CR4: 00000000000006e0
Stack:
0000000000000000 ffffffff816578b9 0000000000000000 ffff8800c0d003c8
ffff880036dd7a78 ffffffff811e8ff5 0000000ffffffff1 ffffffff81a9b060
ffff8800c789f880 ffff8800c0d00000 ffff880036dd7a98 ffffffff811ebe0d
Call Trace:
[<ffffffff811e8ff5>] kernfs_find_and_get_ns+0x35/0x60
[<ffffffff811ebe0d>] sysfs_unmerge_group+0x1d/0x60
[<ffffffff81404ef2>] dpm_sysfs_remove+0x22/0x60
[<ffffffff813f9db9>] device_del+0x49/0x240
[<ffffffff815da768>] rfkill_unregister+0x58/0xc0
[<ffffffffa06bd91b>] wiphy_unregister+0xab/0x2f0 [cfg80211]
[<ffffffffa0742fe3>] brcmf_cfg80211_detach+0x23/0x50 [brcmfmac]
[<ffffffffa074d986>] brcmf_detach+0x86/0xe0 [brcmfmac]
[<ffffffffa0757de8>] brcmf_sdio_remove+0x48/0x120 [brcmfmac]
[<ffffffffa0758ed9>] brcmf_sdiod_remove+0x29/0xd0 [brcmfmac]
[<ffffffffa0759031>] brcmf_ops_sdio_remove+0xb1/0x110 [brcmfmac]
[<ffffffffa001c267>] sdio_bus_remove+0x37/0x100 [mmc_core]
[<ffffffff813fe026>] __device_release_driver+0x96/0x130
[<ffffffff813fe0e3>] device_release_driver+0x23/0x30
[<ffffffffa0754bc8>] brcmf_sdio_firmware_callback+0x2a8/0x5d0 [brcmfmac]
[<ffffffffa074deaf>] brcmf_fw_request_nvram_done+0x15f/0x5e0 [brcmfmac]
[<ffffffff8140142f>] ? devres_add+0x3f/0x50
[<ffffffff810642b5>] ? usermodehelper_read_unlock+0x15/0x20
[<ffffffff81400000>] ? platform_match+0x70/0xa0
[<ffffffff8140f400>] request_firmware_work_func+0x30/0x60
[<ffffffff8106828c>] process_one_work+0x14c/0x3d0
[<ffffffff8106862a>] worker_thread+0x11a/0x450
[<ffffffff81068510>] ? process_one_work+0x3d0/0x3d0
[<ffffffff8106d692>] kthread+0xd2/0xf0
[<ffffffff8106d5c0>] ? kthread_create_on_node+0x180/0x180
[<ffffffff815ed35f>] ret_from_fork+0x3f/0x70
[<ffffffff8106d5c0>] ? kthread_create_on_node+0x180/0x180
Code: e9 40 fe ff ff 48 89 d8 eb 87 66 0f 1f 84 00 00 00 00 00 66 66 66 66
90 55 48 89 e5 41 56 49 89 f6 41 55 49 89 d5 31 d2 41 54 53 <0f> b7
47 68 48 8b 5f 48 66 c1 e8 05 83 e0 01 4d 85 ed 0f b6 c8
RIP [<ffffffff811e8f08>] kernfs_find_ns+0x18/0xd0
RSP <ffff880036dd7a28>
CR2: 0000000000000068
---[ end trace 87d6ec0d3fe46740 ]---
Reported-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -1049,7 +1049,10 @@ int brcmf_bus_start(struct device *dev)
fail:
if (ret < 0) {
brcmf_err("failed: %d\n", ret);
- brcmf_cfg80211_detach(drvr->config);
+ if (drvr->config) {
+ brcmf_cfg80211_detach(drvr->config);
+ drvr->config = NULL;
+ }
if (drvr->fws) {
brcmf_fws_del_interface(ifp);
brcmf_fws_deinit(drvr);

View file

@ -1,105 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:14:57 +0200
Subject: [PATCH] brcmfmac: correct detection of p2pdev interface event
The p2pdev interface is setup in firmware resulting in a interface
event. This event has role and no-if flag. When role is p2p client
and no-if flag is set it indicates that this is the p2pdev interface.
This info is used in handling the event and adding interface in the
driver.
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -795,7 +795,7 @@ fail:
}
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
- char *name, u8 *mac_addr)
+ bool is_p2pdev, char *name, u8 *mac_addr)
{
struct brcmf_if *ifp;
struct net_device *ndev;
@@ -821,7 +821,7 @@ struct brcmf_if *brcmf_add_if(struct brc
}
}
- if (!brcmf_p2p_enable && bssidx == 1) {
+ if (!brcmf_p2p_enable && is_p2pdev) {
/* this is P2P_DEVICE interface */
brcmf_dbg(INFO, "allocate non-netdev interface\n");
ifp = kzalloc(sizeof(*ifp), GFP_KERNEL);
@@ -999,12 +999,12 @@ int brcmf_bus_start(struct device *dev)
brcmf_dbg(TRACE, "\n");
/* add primary networking interface */
- ifp = brcmf_add_if(drvr, 0, 0, "wlan%d", NULL);
+ ifp = brcmf_add_if(drvr, 0, 0, false, "wlan%d", NULL);
if (IS_ERR(ifp))
return PTR_ERR(ifp);
if (brcmf_p2p_enable)
- p2p_ifp = brcmf_add_if(drvr, 1, 0, "p2p%d", NULL);
+ p2p_ifp = brcmf_add_if(drvr, 1, 0, false, "p2p%d", NULL);
else
p2p_ifp = NULL;
if (IS_ERR(p2p_ifp))
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
@@ -205,7 +205,7 @@ char *brcmf_ifname(struct brcmf_pub *drv
struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx);
int brcmf_net_attach(struct brcmf_if *ifp, bool rtnl_locked);
struct brcmf_if *brcmf_add_if(struct brcmf_pub *drvr, s32 bssidx, s32 ifidx,
- char *name, u8 *mac_addr);
+ bool is_p2pdev, char *name, u8 *mac_addr);
void brcmf_remove_interface(struct brcmf_if *ifp);
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
void brcmf_txflowblock_if(struct brcmf_if *ifp,
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -179,6 +179,7 @@ static void brcmf_fweh_handle_if_event(s
{
struct brcmf_if_event *ifevent = data;
struct brcmf_if *ifp;
+ bool is_p2pdev;
int err = 0;
brcmf_dbg(EVENT, "action: %u idx: %u bsscfg: %u flags: %u role: %u\n",
@@ -186,18 +187,16 @@ static void brcmf_fweh_handle_if_event(s
ifevent->flags, ifevent->role);
/* The P2P Device interface event must not be ignored
- * contrary to what firmware tells us. The only way to
- * distinguish the P2P Device is by looking at the ifidx
- * and bssidx received.
+ * contrary to what firmware tells us.
*/
- if (!(ifevent->ifidx == 0 && ifevent->bssidx == 1) &&
- (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) {
+ is_p2pdev = (ifevent->flags & BRCMF_E_IF_FLAG_NOIF) &&
+ ifevent->role == BRCMF_E_IF_ROLE_P2P_CLIENT;
+ if (!is_p2pdev && (ifevent->flags & BRCMF_E_IF_FLAG_NOIF)) {
brcmf_dbg(EVENT, "event can be ignored\n");
return;
}
if (ifevent->ifidx >= BRCMF_MAX_IFS) {
- brcmf_err("invalid interface index: %u\n",
- ifevent->ifidx);
+ brcmf_err("invalid interface index: %u\n", ifevent->ifidx);
return;
}
@@ -207,7 +206,7 @@ static void brcmf_fweh_handle_if_event(s
brcmf_dbg(EVENT, "adding %s (%pM)\n", emsg->ifname,
emsg->addr);
ifp = brcmf_add_if(drvr, ifevent->bssidx, ifevent->ifidx,
- emsg->ifname, emsg->addr);
+ is_p2pdev, emsg->ifname, emsg->addr);
if (IS_ERR(ifp))
return;
brcmf_fws_add_interface(ifp);

View file

@ -1,126 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:14:58 +0200
Subject: [PATCH] brcmfmac: use brcmf_get_ifp() to map ifidx to struct
brcmf_if instance
The knowledge on how to map the interface index to a struct brcmf_if
instance is in brcmf_get_ifp() so use that function when only the
interface index is known instead of accessing brcmf_pub::iflist
directly.
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/btcoex.c
@@ -149,7 +149,7 @@ static s32 brcmf_btcoex_params_read(stru
static void brcmf_btcoex_boost_wifi(struct brcmf_btcoex_info *btci,
bool trump_sco)
{
- struct brcmf_if *ifp = btci->cfg->pub->iflist[0];
+ struct brcmf_if *ifp = brcmf_get_ifp(btci->cfg->pub, 0);
if (trump_sco && !btci->saved_regs_part2) {
/* this should reduce eSCO agressive
@@ -468,7 +468,7 @@ int brcmf_btcoex_set_mode(struct brcmf_c
{
struct brcmf_cfg80211_info *cfg = wiphy_priv(vif->wdev.wiphy);
struct brcmf_btcoex_info *btci = cfg->btcoex;
- struct brcmf_if *ifp = cfg->pub->iflist[0];
+ struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
switch (mode) {
case BRCMF_BTCOEX_DISABLED:
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -6213,7 +6213,7 @@ static void brcmf_free_wiphy(struct wiph
struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
struct device *busdev)
{
- struct net_device *ndev = drvr->iflist[0]->ndev;
+ struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
struct brcmf_cfg80211_info *cfg;
struct wiphy *wiphy;
struct brcmf_cfg80211_vif *vif;
--- a/drivers/net/wireless/brcm80211/brcmfmac/feature.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/feature.c
@@ -121,7 +121,7 @@ static void brcmf_feat_iovar_int_set(str
void brcmf_feat_attach(struct brcmf_pub *drvr)
{
- struct brcmf_if *ifp = drvr->iflist[0];
+ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MCHAN, "mchan");
brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_PNO, "pfn");
--- a/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/flowring.c
@@ -221,7 +221,7 @@ static void brcmf_flowring_block(struct
bus_if = dev_get_drvdata(flow->dev);
drvr = bus_if->drvr;
- ifp = drvr->iflist[ifidx];
+ ifp = brcmf_get_ifp(drvr, ifidx);
brcmf_txflowblock_if(ifp, BRCMF_NETIF_STOP_REASON_FLOW, blocked);
spin_unlock_irqrestore(&flow->block_lock, flags);
--- a/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fweh.c
@@ -334,7 +334,7 @@ void brcmf_fweh_attach(struct brcmf_pub
void brcmf_fweh_detach(struct brcmf_pub *drvr)
{
struct brcmf_fweh_info *fweh = &drvr->fweh;
- struct brcmf_if *ifp = drvr->iflist[0];
+ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
s8 eventmask[BRCMF_EVENTING_MASK_LEN];
if (ifp) {
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -972,7 +972,7 @@ static void
brcmf_fws_flow_control_check(struct brcmf_fws_info *fws, struct pktq *pq,
u8 if_id)
{
- struct brcmf_if *ifp = fws->drvr->iflist[!if_id ? 0 : if_id + 1];
+ struct brcmf_if *ifp = brcmf_get_ifp(fws->drvr, if_id);
if (WARN_ON(!ifp))
return;
@@ -2118,6 +2118,7 @@ static int brcmf_debugfs_fws_stats_read(
int brcmf_fws_init(struct brcmf_pub *drvr)
{
struct brcmf_fws_info *fws;
+ struct brcmf_if *ifp;
u32 tlv = BRCMF_FWS_FLAGS_RSSI_SIGNALS;
int rc;
u32 mode;
@@ -2177,21 +2178,22 @@ int brcmf_fws_init(struct brcmf_pub *drv
* continue. Set mode back to none indicating not enabled.
*/
fws->fw_signals = true;
- if (brcmf_fil_iovar_int_set(drvr->iflist[0], "tlv", tlv)) {
+ ifp = brcmf_get_ifp(drvr, 0);
+ if (brcmf_fil_iovar_int_set(ifp, "tlv", tlv)) {
brcmf_err("failed to set bdcv2 tlv signaling\n");
fws->fcmode = BRCMF_FWS_FCMODE_NONE;
fws->fw_signals = false;
}
- if (brcmf_fil_iovar_int_set(drvr->iflist[0], "ampdu_hostreorder", 1))
+ if (brcmf_fil_iovar_int_set(ifp, "ampdu_hostreorder", 1))
brcmf_dbg(INFO, "enabling AMPDU host-reorder failed\n");
/* Enable seq number reuse, if supported */
- if (brcmf_fil_iovar_int_get(drvr->iflist[0], "wlfc_mode", &mode) == 0) {
+ if (brcmf_fil_iovar_int_get(ifp, "wlfc_mode", &mode) == 0) {
if (BRCMF_FWS_MODE_GET_REUSESEQ(mode)) {
mode = 0;
BRCMF_FWS_MODE_SET_REUSESEQ(mode, 1);
- if (brcmf_fil_iovar_int_set(drvr->iflist[0],
+ if (brcmf_fil_iovar_int_set(ifp,
"wlfc_mode", mode) == 0) {
BRCMF_FWS_MODE_SET_REUSESEQ(fws->mode, 1);
}

View file

@ -1,122 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:14:59 +0200
Subject: [PATCH] brcmfmac: pass struct brcmf_if instance in
brcmf_txfinalize()
Most call sites of brcmf_txfinalize already have struct brcmf_if
instance so pass that to brcmf_txfinalize() as the function
needs it anyway.
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -560,17 +560,11 @@ void brcmf_rx_frame(struct device *dev,
brcmf_netif_rx(ifp, skb);
}
-void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
- bool success)
+void brcmf_txfinalize(struct brcmf_if *ifp, struct sk_buff *txp, bool success)
{
- struct brcmf_if *ifp;
struct ethhdr *eh;
u16 type;
- ifp = drvr->iflist[ifidx];
- if (!ifp)
- goto done;
-
eh = (struct ethhdr *)(txp->data);
type = ntohs(eh->h_proto);
@@ -582,7 +576,7 @@ void brcmf_txfinalize(struct brcmf_pub *
if (!success)
ifp->stats.tx_errors++;
-done:
+
brcmu_pkt_buf_free_skb(txp);
}
@@ -600,7 +594,7 @@ void brcmf_txcomplete(struct device *dev
if (brcmf_proto_hdrpull(drvr, false, txp, &ifp))
brcmu_pkt_buf_free_skb(txp);
else
- brcmf_txfinalize(drvr, txp, ifp->ifidx, success);
+ brcmf_txfinalize(ifp, txp, success);
}
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
@@ -210,8 +210,7 @@ void brcmf_remove_interface(struct brcmf
int brcmf_get_next_free_bsscfgidx(struct brcmf_pub *drvr);
void brcmf_txflowblock_if(struct brcmf_if *ifp,
enum brcmf_netif_stop_reason reason, bool state);
-void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
- bool success);
+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). */
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1506,7 +1506,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
genbit, seq);
if (remove_from_hanger || ret)
- brcmf_txfinalize(fws->drvr, skb, ifp->ifidx, true);
+ brcmf_txfinalize(ifp, skb, true);
return 0;
}
@@ -1905,7 +1905,7 @@ int brcmf_fws_process_skb(struct brcmf_i
if (fws->avoid_queueing) {
rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
if (rc < 0)
- brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
+ brcmf_txfinalize(ifp, skb, false);
return rc;
}
@@ -1929,7 +1929,7 @@ int brcmf_fws_process_skb(struct brcmf_i
brcmf_fws_schedule_deq(fws);
} else {
brcmf_err("drop skb: no hanger slot\n");
- brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
+ brcmf_txfinalize(ifp, skb, false);
rc = -ENOMEM;
}
brcmf_fws_unlock(fws);
@@ -2009,8 +2009,9 @@ static void brcmf_fws_dequeue_worker(str
ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
brcmf_fws_lock(fws);
if (ret < 0)
- brcmf_txfinalize(drvr, skb, ifidx,
- false);
+ brcmf_txfinalize(brcmf_get_ifp(drvr,
+ ifidx),
+ skb, false);
if (fws->bus_flow_blocked)
break;
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -873,7 +873,11 @@ brcmf_msgbuf_process_txstatus(struct brc
commonring = msgbuf->flowrings[flowid];
atomic_dec(&commonring->outstanding_tx);
- brcmf_txfinalize(msgbuf->drvr, skb, tx_status->msg.ifidx, true);
+ /* 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);
}

View file

@ -1,92 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:15:00 +0200
Subject: [PATCH] brcmfmac: add mapping for interface index to bsscfg
index
Because the P2P Device interface in firmware uses the same interface
index as the primary interface we use the bsscfg index as index in the
struct brcmf_pub::iflist. However, in the data path we get the interface
index and not the bsscfg index. So we need a mapping of interface index
to bsscfg index, which can be determined upon handle adding the interface.
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -85,21 +85,20 @@ char *brcmf_ifname(struct brcmf_pub *drv
struct brcmf_if *brcmf_get_ifp(struct brcmf_pub *drvr, int ifidx)
{
+ struct brcmf_if *ifp;
+ s32 bssidx;
+
if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) {
brcmf_err("ifidx %d out of range\n", ifidx);
return NULL;
}
- /* The ifidx is the idx to map to matching netdev/ifp. When receiving
- * events this is easy because it contains the bssidx which maps
- * 1-on-1 to the netdev/ifp. But for data frames the ifidx is rcvd.
- * bssidx 1 is used for p2p0 and no data can be received or
- * transmitted on it. Therefor bssidx is ifidx + 1 if ifidx > 0
- */
- if (ifidx)
- ifidx++;
+ ifp = NULL;
+ bssidx = drvr->if2bss[ifidx];
+ if (bssidx >= 0)
+ ifp = drvr->iflist[bssidx];
- return drvr->iflist[ifidx];
+ return ifp;
}
static void _brcmf_set_multicast_list(struct work_struct *work)
@@ -831,6 +830,8 @@ struct brcmf_if *brcmf_add_if(struct brc
ifp = netdev_priv(ndev);
ifp->ndev = ndev;
+ /* store mapping ifidx to bssidx */
+ drvr->if2bss[ifidx] = bssidx;
}
ifp->drvr = drvr;
@@ -855,6 +856,7 @@ static void brcmf_del_if(struct brcmf_pu
struct brcmf_if *ifp;
ifp = drvr->iflist[bssidx];
+ drvr->if2bss[ifp->ifidx] = -1;
drvr->iflist[bssidx] = NULL;
if (!ifp) {
brcmf_err("Null interface, idx=%d\n", bssidx);
@@ -862,6 +864,7 @@ static void brcmf_del_if(struct brcmf_pu
}
brcmf_dbg(TRACE, "Enter, idx=%d, ifidx=%d\n", bssidx, ifp->ifidx);
if (ifp->ndev) {
+ drvr->if2bss[ifp->ifidx] = -1;
if (bssidx == 0) {
if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) {
rtnl_lock();
@@ -926,6 +929,7 @@ int brcmf_attach(struct device *dev)
if (!drvr)
return -ENOMEM;
+ memset(drvr->if2bss, 0xFF, sizeof(drvr->if2bss));
mutex_init(&drvr->proto_block);
/* Link to bus module */
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.h
@@ -122,6 +122,7 @@ struct brcmf_pub {
struct mac_address addresses[BRCMF_MAX_IFS];
struct brcmf_if *iflist[BRCMF_MAX_IFS];
+ s32 if2bss[BRCMF_MAX_IFS];
struct mutex proto_block;
unsigned char proto_buf[BRCMF_DCMD_MAXLEN];

View file

@ -1,103 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:15:01 +0200
Subject: [PATCH] brcmfmac: add dedicated debug level for firmware
console logging
Both PCIe and SDIO devices have the possibility to log the firmware
console output in kernel log. For PCIe it is logged when PCIE debug
level is enabled. For SDIO it is logged when user specifies a non-zero
console interval through debugfs. This patch tries to make it a
bit more consistent. The firmware console output is only logged when
FWCON debug level is enabled.
Reviewed-by: Hante Meuleman <meuleman@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@broadcom.com>
Reviewed-by: Pieter-Paul Giesberts <pieterpg@broadcom.com>
Reviewed-by: Pontus Fuchs <pontusf@broadcom.com>
Signed-off-by: Arend van Spriel <arend@broadcom.com>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h
@@ -37,6 +37,7 @@
#define BRCMF_SDIO_VAL 0x00020000
#define BRCMF_MSGBUF_VAL 0x00040000
#define BRCMF_PCIE_VAL 0x00080000
+#define BRCMF_FWCON_VAL 0x00100000
/* set default print format */
#undef pr_fmt
@@ -78,6 +79,7 @@ do { \
#define BRCMF_GLOM_ON() (brcmf_msg_level & BRCMF_GLOM_VAL)
#define BRCMF_EVENT_ON() (brcmf_msg_level & BRCMF_EVENT_VAL)
#define BRCMF_FIL_ON() (brcmf_msg_level & BRCMF_FIL_VAL)
+#define BRCMF_FWCON_ON() (brcmf_msg_level & BRCMF_FWCON_VAL)
#else /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */
@@ -90,6 +92,7 @@ do { \
#define BRCMF_GLOM_ON() 0
#define BRCMF_EVENT_ON() 0
#define BRCMF_FIL_ON() 0
+#define BRCMF_FWCON_ON() 0
#endif /* defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) */
--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
@@ -644,7 +644,7 @@ static void brcmf_pcie_bus_console_init(
addr = console->base_addr + BRCMF_CONSOLE_BUFSIZE_OFFSET;
console->bufsize = brcmf_pcie_read_tcm32(devinfo, addr);
- brcmf_dbg(PCIE, "Console: base %x, buf %x, size %d\n",
+ brcmf_dbg(FWCON, "Console: base %x, buf %x, size %d\n",
console->base_addr, console->buf_addr, console->bufsize);
}
@@ -656,6 +656,9 @@ static void brcmf_pcie_bus_console_read(
u8 ch;
u32 newidx;
+ if (!BRCMF_FWCON_ON())
+ return;
+
console = &devinfo->shared.console;
addr = console->base_addr + BRCMF_CONSOLE_WRITEIDX_OFFSET;
newidx = brcmf_pcie_read_tcm32(devinfo, addr);
@@ -677,7 +680,7 @@ static void brcmf_pcie_bus_console_read(
}
if (ch == '\n') {
console->log_str[console->log_idx] = 0;
- brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str);
+ pr_debug("CONSOLE: %s", console->log_str);
console->log_idx = 0;
}
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -123,6 +123,7 @@ struct rte_console {
#define BRCMF_FIRSTREAD (1 << 6)
+#define BRCMF_CONSOLE 10 /* watchdog interval to poll console */
/* SBSDIO_DEVICE_CTL */
@@ -3204,6 +3205,8 @@ static void brcmf_sdio_debugfs_create(st
if (IS_ERR_OR_NULL(dentry))
return;
+ bus->console_interval = BRCMF_CONSOLE;
+
brcmf_debugfs_add_entry(drvr, "forensics", brcmf_sdio_forensic_read);
brcmf_debugfs_add_entry(drvr, "counters",
brcmf_debugfs_sdio_count_read);
@@ -3613,7 +3616,7 @@ static void brcmf_sdio_bus_watchdog(stru
}
#ifdef DEBUG
/* Poll for console output periodically */
- if (bus->sdiodev->state == BRCMF_SDIOD_DATA &&
+ if (bus->sdiodev->state == BRCMF_SDIOD_DATA && BRCMF_FWCON_ON() &&
bus->console_interval != 0) {
bus->console.count += BRCMF_WD_POLL_MS;
if (bus->console.count >= bus->console_interval) {

View file

@ -1,34 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:15:02 +0200
Subject: [PATCH] brcmfmac: remove ifidx parameter from
brcmf_fws_txstatus_suppressed()
The brcmf_fws_txstatus_suppressed() function prototype specifies an
ifidx parameter which is not used within the function implementation.
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1398,7 +1398,7 @@ done:
}
static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
- struct sk_buff *skb, u8 ifidx,
+ struct sk_buff *skb,
u32 genbit, u16 seq)
{
struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
@@ -1503,7 +1503,7 @@ brcmf_fws_txs_process(struct brcmf_fws_i
return -EINVAL;
}
if (!remove_from_hanger)
- ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifp->ifidx,
+ ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
genbit, seq);
if (remove_from_hanger || ret)
brcmf_txfinalize(ifp, skb, true);

View file

@ -1,97 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:15:03 +0200
Subject: [PATCH] brcmfmac: change prototype for brcmf_fws_hdrpull()
Instead of passing ifidx and drvr just pass struct brcmf_if pointer
which holds both parameters.
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcdc.c
@@ -312,8 +312,7 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu
skb_pull(pktbuf, BCDC_HEADER_LEN);
if (do_fws)
- brcmf_fws_hdrpull(drvr, tmp_if->ifidx, h->data_offset << 2,
- pktbuf);
+ brcmf_fws_hdrpull(tmp_if, h->data_offset << 2, pktbuf);
else
skb_pull(pktbuf, h->data_offset << 2);
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -1616,11 +1616,10 @@ static int brcmf_fws_notify_bcmc_credit_
return 0;
}
-int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
- struct sk_buff *skb)
+void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb)
{
struct brcmf_skb_reorder_data *rd;
- struct brcmf_fws_info *fws = drvr->fws;
+ struct brcmf_fws_info *fws = ifp->drvr->fws;
u8 *signal_data;
s16 data_len;
u8 type;
@@ -1630,20 +1629,20 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
s32 err;
brcmf_dbg(HDRS, "enter: ifidx %d, skblen %u, sig %d\n",
- ifidx, skb->len, signal_len);
+ ifp->ifidx, skb->len, siglen);
- WARN_ON(signal_len > skb->len);
+ WARN_ON(siglen > skb->len);
- if (!signal_len)
- return 0;
+ if (!siglen)
+ return;
/* if flow control disabled, skip to packet data and leave */
if ((!fws) || (!fws->fw_signals)) {
- skb_pull(skb, signal_len);
- return 0;
+ skb_pull(skb, siglen);
+ return;
}
fws->stats.header_pulls++;
- data_len = signal_len;
+ data_len = siglen;
signal_data = skb->data;
status = BRCMF_FWS_RET_OK_NOSCHEDULE;
@@ -1731,14 +1730,12 @@ int brcmf_fws_hdrpull(struct brcmf_pub *
/* signalling processing result does
* not affect the actual ethernet packet.
*/
- skb_pull(skb, signal_len);
+ skb_pull(skb, siglen);
/* this may be a signal-only packet
*/
if (skb->len == 0)
fws->stats.header_only_pkt++;
-
- return 0;
}
static u8 brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.h
@@ -21,8 +21,7 @@
int brcmf_fws_init(struct brcmf_pub *drvr);
void brcmf_fws_deinit(struct brcmf_pub *drvr);
bool brcmf_fws_fc_active(struct brcmf_fws_info *fws);
-int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
- struct sk_buff *skb);
+void brcmf_fws_hdrpull(struct brcmf_if *ifp, s16 siglen, struct sk_buff *skb);
int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb);
void brcmf_fws_reset_interface(struct brcmf_if *ifp);

View file

@ -1,99 +0,0 @@
From: Arend van Spriel <arend@broadcom.com>
Date: Wed, 26 Aug 2015 22:15:04 +0200
Subject: [PATCH] brcmfmac: introduce brcmf_net_detach() function
In case of error during brcmf_bus_start() the network interfaces were
freed using free_netdev(). However, the interfaces may have additional
memory allocated which is not freed. The netdev has destructor set to
brcmf_cfg80211_free_netdev() which frees the additional memory if
allocated and call free_netdev(). The brcmf_net_detach() either calls
brcmf_cfg80211_free_netdev() directly or uses unregister_netdev() when
struct net_device::reg_state indicates the netdev was registered.
Reported-by: Daniel (Deognyoun) Kim <dekim@broadcom.com>
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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -4747,7 +4747,8 @@ void brcmf_cfg80211_free_netdev(struct n
ifp = netdev_priv(ndev);
vif = ifp->vif;
- brcmf_free_vif(vif);
+ if (vif)
+ brcmf_free_vif(vif);
free_netdev(ndev);
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/core.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/core.c
@@ -718,8 +718,6 @@ int brcmf_net_attach(struct brcmf_if *if
}
brcmf_dbg(INFO, "%s: Broadcom Dongle Host Driver\n", ndev->name);
-
- ndev->destructor = brcmf_cfg80211_free_netdev;
return 0;
fail:
@@ -729,6 +727,14 @@ fail:
return -EBADE;
}
+static void brcmf_net_detach(struct net_device *ndev)
+{
+ if (ndev->reg_state == NETREG_REGISTERED)
+ unregister_netdev(ndev);
+ else
+ brcmf_cfg80211_free_netdev(ndev);
+}
+
static int brcmf_net_p2p_open(struct net_device *ndev)
{
brcmf_dbg(TRACE, "Enter\n");
@@ -805,8 +811,7 @@ struct brcmf_if *brcmf_add_if(struct brc
ifp->ndev->name);
if (ifidx) {
netif_stop_queue(ifp->ndev);
- unregister_netdev(ifp->ndev);
- free_netdev(ifp->ndev);
+ brcmf_net_detach(ifp->ndev);
drvr->iflist[bssidx] = NULL;
} else {
brcmf_err("ignore IF event\n");
@@ -828,6 +833,7 @@ struct brcmf_if *brcmf_add_if(struct brc
if (!ndev)
return ERR_PTR(-ENOMEM);
+ ndev->destructor = brcmf_cfg80211_free_netdev;
ifp = netdev_priv(ndev);
ifp->ndev = ndev;
/* store mapping ifidx to bssidx */
@@ -879,8 +885,7 @@ static void brcmf_del_if(struct brcmf_pu
cancel_work_sync(&ifp->setmacaddr_work);
cancel_work_sync(&ifp->multicast_work);
}
- /* unregister will take care of freeing it */
- unregister_netdev(ifp->ndev);
+ brcmf_net_detach(ifp->ndev);
}
}
@@ -1056,11 +1061,11 @@ fail:
brcmf_fws_deinit(drvr);
}
if (drvr->iflist[0]) {
- free_netdev(ifp->ndev);
+ brcmf_net_detach(ifp->ndev);
drvr->iflist[0] = NULL;
}
if (p2p_ifp) {
- free_netdev(p2p_ifp->ndev);
+ brcmf_net_detach(p2p_ifp->ndev);
drvr->iflist[1] = NULL;
}
return ret;

View file

@ -1,193 +0,0 @@
From: Hante Meuleman <meuleman@broadcom.com>
Date: Thu, 27 Aug 2015 16:14:06 +0200
Subject: [PATCH] brcmfmac: Reset PCIE devices after recognition.
When PCIE type devices are being FW reloaded without being properly
reset then the device ends up in a locked state, requiring the
device to be completely powered down. This patch adds a reset
through watchdog at the moment the device (cores) has been
recognized. This will solve warm reboot issues.
Cc: Rafal Milecki <zajec5@gmail.com>
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Reviewed-by: Franky (Zhenhui) Lin <frankyl@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>
---
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -101,6 +101,9 @@
/* ARM Cortex M3 core, ID 0x82a */
#define BCM4329_CORE_ARM_BASE 0x18002000
+/* Max possibly supported memory size (limited by IO mapped memory) */
+#define BRCMF_CHIP_MAX_MEMSIZE (4 * 1024 * 1024)
+
#define CORE_SB(base, field) \
(base + SBCONFIGOFF + offsetof(struct sbconfig, field))
#define SBCOREREV(sbidh) \
@@ -687,6 +690,12 @@ static int brcmf_chip_get_raminfo(struct
brcmf_err("RAM size is undetermined\n");
return -ENOMEM;
}
+
+ if (ci->pub.ramsize > BRCMF_CHIP_MAX_MEMSIZE) {
+ brcmf_err("RAM size is incorrect\n");
+ return -ENOMEM;
+ }
+
return 0;
}
@@ -899,6 +908,15 @@ static int brcmf_chip_recognition(struct
/* assure chip is passive for core access */
brcmf_chip_set_passive(&ci->pub);
+
+ /* Call bus specific reset function now. Cores have been determined
+ * but further access may require a chip specific reset at this point.
+ */
+ if (ci->ops->reset) {
+ ci->ops->reset(ci->ctx, &ci->pub);
+ brcmf_chip_set_passive(&ci->pub);
+ }
+
return brcmf_chip_get_raminfo(ci);
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
@@ -73,6 +73,7 @@ struct brcmf_buscore_ops {
u32 (*read32)(void *ctx, u32 addr);
void (*write32)(void *ctx, u32 addr, u32 value);
int (*prepare)(void *ctx);
+ int (*reset)(void *ctx, struct brcmf_chip *chip);
int (*setup)(void *ctx, struct brcmf_chip *chip);
void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
};
--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
@@ -74,6 +74,8 @@ enum brcmf_pcie_state {
#define BRCMF_PCIE_REG_INTMASK 0x94
#define BRCMF_PCIE_REG_SBMBX 0x98
+#define BRCMF_PCIE_REG_LINK_STATUS_CTRL 0xBC
+
#define BRCMF_PCIE_PCIE2REG_INTMASK 0x24
#define BRCMF_PCIE_PCIE2REG_MAILBOXINT 0x48
#define BRCMF_PCIE_PCIE2REG_MAILBOXMASK 0x4C
@@ -466,6 +468,7 @@ brcmf_pcie_select_core(struct brcmf_pcie
static void brcmf_pcie_reset_device(struct brcmf_pciedev_info *devinfo)
{
+ struct brcmf_core *core;
u16 cfg_offset[] = { BRCMF_PCIE_CFGREG_STATUS_CMD,
BRCMF_PCIE_CFGREG_PM_CSR,
BRCMF_PCIE_CFGREG_MSI_CAP,
@@ -484,32 +487,38 @@ static void brcmf_pcie_reset_device(stru
if (!devinfo->ci)
return;
+ /* Disable ASPM */
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
- BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL);
- lsc = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA);
+ pci_read_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL,
+ &lsc);
val = lsc & (~BRCMF_PCIE_LINK_STATUS_CTRL_ASPM_ENAB);
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, val);
+ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL,
+ val);
+ /* Watchdog reset */
brcmf_pcie_select_core(devinfo, BCMA_CORE_CHIPCOMMON);
WRITECC32(devinfo, watchdog, 4);
msleep(100);
+ /* Restore ASPM */
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
- BRCMF_PCIE_CFGREG_LINK_STATUS_CTRL);
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA, lsc);
+ pci_write_config_dword(devinfo->pdev, BRCMF_PCIE_REG_LINK_STATUS_CTRL,
+ lsc);
- brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
- for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) {
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR,
- cfg_offset[i]);
- val = brcmf_pcie_read_reg32(devinfo,
- BRCMF_PCIE_PCIE2REG_CONFIGDATA);
- brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n",
- cfg_offset[i], val);
- brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGDATA,
- val);
+ core = brcmf_chip_get_core(devinfo->ci, BCMA_CORE_PCIE2);
+ if (core->rev <= 13) {
+ for (i = 0; i < ARRAY_SIZE(cfg_offset); i++) {
+ brcmf_pcie_write_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_CONFIGADDR,
+ cfg_offset[i]);
+ val = brcmf_pcie_read_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_CONFIGDATA);
+ brcmf_dbg(PCIE, "config offset 0x%04x, value 0x%04x\n",
+ cfg_offset[i], val);
+ brcmf_pcie_write_reg32(devinfo,
+ BRCMF_PCIE_PCIE2REG_CONFIGDATA,
+ val);
+ }
}
}
@@ -519,8 +528,6 @@ static void brcmf_pcie_attach(struct brc
u32 config;
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
- if (brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_INTMASK) != 0)
- brcmf_pcie_reset_device(devinfo);
/* BAR1 window may not be sized properly */
brcmf_pcie_select_core(devinfo, BCMA_CORE_PCIE2);
brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_CONFIGADDR, 0x4e0);
@@ -1636,6 +1643,23 @@ static int brcmf_pcie_buscoreprep(void *
}
+static int brcmf_pcie_buscore_reset(void *ctx, struct brcmf_chip *chip)
+{
+ struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
+ u32 val;
+
+ devinfo->ci = chip;
+ brcmf_pcie_reset_device(devinfo);
+
+ val = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
+ if (val != 0xffffffff)
+ brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT,
+ val);
+
+ return 0;
+}
+
+
static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip,
u32 rstvec)
{
@@ -1647,6 +1671,7 @@ static void brcmf_pcie_buscore_activate(
static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
.prepare = brcmf_pcie_buscoreprep,
+ .reset = brcmf_pcie_buscore_reset,
.activate = brcmf_pcie_buscore_activate,
.read32 = brcmf_pcie_buscore_read32,
.write32 = brcmf_pcie_buscore_write32,
@@ -1814,7 +1839,6 @@ brcmf_pcie_remove(struct pci_dev *pdev)
brcmf_pcie_intr_disable(devinfo);
brcmf_detach(&pdev->dev);
- brcmf_pcie_reset_device(devinfo);
kfree(bus->bus_priv.pcie);
kfree(bus->msgbuf->flowrings);

View file

@ -1,33 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 13 Sep 2015 22:26:10 +0200
Subject: [PATCH] ath10k: fix DMA related firmware crashes on multiple devices
Some platforms really don't like DMA bursts of 256 bytes, and this
causes the firmware to crash when sending beacons.
Also, changing this based on the firmware version does not seem to make
much sense, so use 128 bytes for all versions.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -340,7 +340,7 @@ enum ath10k_hw_rate_cck {
#define TARGET_10X_MAX_FRAG_ENTRIES 0
/* 10.2 parameters */
-#define TARGET_10_2_DMA_BURST_SIZE 1
+#define TARGET_10_2_DMA_BURST_SIZE 0
/* Target specific defines for WMI-TLV firmware */
#define TARGET_TLV_NUM_VDEVS 4
@@ -397,7 +397,7 @@ enum ath10k_hw_rate_cck {
#define TARGET_10_4_TX_DBG_LOG_SIZE 1024
#define TARGET_10_4_NUM_WDS_ENTRIES 32
-#define TARGET_10_4_DMA_BURST_SIZE 1
+#define TARGET_10_4_DMA_BURST_SIZE 0
#define TARGET_10_4_MAC_AGGR_DELIM 0
#define TARGET_10_4_RX_SKIP_DEFRAG_TIMEOUT_DUP_DETECTION_CHECK 1
#define TARGET_10_4_VOW_CONFIG 0

View file

@ -1,33 +0,0 @@
From: Miaoqing Pan <miaoqing@qca.qualcomm.com>
Date: Tue, 1 Sep 2015 10:56:09 +0800
Subject: [PATCH] ath9k: enable hw manual peak calibration for QCA9561
This patch fix https://lists.openwrt.org/pipermail/openwrt-devel/
2015-August/034979.html. As the peak detect calibration is set
incorrectly.
Signed-off-by: Miaoqing Pan <miaoqing@qca.qualcomm.com>
---
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -1249,7 +1249,8 @@ static void ar9003_hw_manual_peak_cal(st
REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
AR_PHY_65NM_RXRF_AGC_AGC2G_CALDAC_OVR, 0x0);
- if (AR_SREV_9003_PCOEM(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah)) {
+ if (AR_SREV_9003_PCOEM(ah) || AR_SREV_9550(ah) || AR_SREV_9531(ah) ||
+ AR_SREV_9561(ah)) {
if (is_2g)
REG_RMW_FIELD(ah, AR_PHY_65NM_RXRF_AGC(chain),
AR_PHY_65NM_RXRF_AGC_AGC2G_DBDAC_OVR,
@@ -1640,7 +1641,8 @@ static bool ar9003_hw_init_cal_soc(struc
skip_tx_iqcal:
if (run_agc_cal || !(ah->ah_flags & AH_FASTCC)) {
- if (AR_SREV_9330_11(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah)) {
+ if (AR_SREV_9330_11(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah) ||
+ AR_SREV_9561(ah)) {
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
if (!(ah->rxchainmask & (1 << i)))
continue;

View file

@ -1,23 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 24 Sep 2015 14:10:07 +0200
Subject: [PATCH] mac80211: fix tx sequence number assignment with software
queue + fast-xmit
When using software queueing, tx sequence number assignment happens at
ieee80211_tx_dequeue time, so the fast-xmit codepath must not do that.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -2766,7 +2766,8 @@ static bool ieee80211_xmit_fast(struct i
if (hdr->frame_control & cpu_to_le16(IEEE80211_STYPE_QOS_DATA)) {
*ieee80211_get_qos_ctl(hdr) = tid;
- hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
+ if (!sta->sta.txq[0])
+ hdr->seq_ctrl = ieee80211_tx_next_seq(sta, tid);
} else {
info->flags |= IEEE80211_TX_CTL_ASSIGN_SEQ;
hdr->seq_ctrl = cpu_to_le16(sdata->sequence_number);

View file

@ -1,45 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 24 Sep 2015 14:11:40 +0200
Subject: [PATCH] mac80211: fix handling of PS filtering with fast-xmit
Fixes dropped packets in the tx path in case a non-PS station triggers
the tx filter.
Cc: stable@vger.kernel.org # 4.2
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -101,6 +101,7 @@ static void ieee80211_handle_filtered_fr
* when it wakes up for the next time.
*/
set_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT);
+ ieee80211_clear_fast_xmit(sta);
/*
* This code races in the following way:
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1217,8 +1217,10 @@ ieee80211_tx_prepare(struct ieee80211_su
if (!tx->sta)
info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
- else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT))
+ else if (test_and_clear_sta_flag(tx->sta, WLAN_STA_CLEAR_PS_FILT)) {
info->flags |= IEEE80211_TX_CTL_CLEAR_PS_FILT;
+ ieee80211_check_fast_xmit(tx->sta);
+ }
info->flags |= IEEE80211_TX_CTL_FIRST_FRAGMENT;
@@ -2450,7 +2452,8 @@ void ieee80211_check_fast_xmit(struct st
if (test_sta_flag(sta, WLAN_STA_PS_STA) ||
test_sta_flag(sta, WLAN_STA_PS_DRIVER) ||
- test_sta_flag(sta, WLAN_STA_PS_DELIVER))
+ test_sta_flag(sta, WLAN_STA_PS_DELIVER) ||
+ test_sta_flag(sta, WLAN_STA_CLEAR_PS_FILT))
goto out;
if (sdata->noack_map)

View file

@ -1,22 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 24 Sep 2015 16:57:37 +0200
Subject: [PATCH] ath9k: declare required extra tx headroom
ath9k inserts padding between the 802.11 header and the data area (to
align it). Since it didn't declare this extra required headroom, this
led to some nasty issues like randomly dropped packets in some setups.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -875,6 +875,7 @@ static void ath9k_set_hw_capab(struct at
hw->max_rate_tries = 10;
hw->sta_data_size = sizeof(struct ath_node);
hw->vif_data_size = sizeof(struct ath_vif);
+ hw->extra_tx_headroom = 4;
hw->wiphy->available_antennas_rx = BIT(ah->caps.max_rxchains) - 1;
hw->wiphy->available_antennas_tx = BIT(ah->caps.max_txchains) - 1;

View file

@ -1,37 +0,0 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Mon, 31 Aug 2015 22:59:38 +0200
Subject: [PATCH] nl80211: put current TX power in interface info
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Many drivers implement reading current TX power (using either cfg80211
or ieee80211 op) but userspace can't get it using nl80211. Right now the
only way to access it is to call some wext ioctl.
Let's put TX power in interface info reply (callback is wdev specific)
just like we do with current channel.
To be consistent (e.g. NL80211_CMD_SET_WIPHY) let's use mBm as na unit.
Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -2406,6 +2406,16 @@ static int nl80211_send_iface(struct sk_
}
}
+ if (rdev->ops->get_tx_power) {
+ int dbm, ret;
+
+ ret = rdev_get_tx_power(rdev, wdev, &dbm);
+ if (ret == 0 &&
+ nla_put_u32(msg, NL80211_ATTR_WIPHY_TX_POWER_LEVEL,
+ DBM_TO_MBM(dbm)))
+ goto nla_put_failure;
+ }
+
if (wdev->ssid_len) {
if (nla_put(msg, NL80211_ATTR_SSID, wdev->ssid_len, wdev->ssid))
goto nla_put_failure;

View file

@ -1,21 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Mon, 5 Oct 2015 17:41:25 +0200
Subject: [PATCH] mac80211: initialize tid field in struct ieee80211_txq
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -3288,9 +3288,11 @@ void ieee80211_init_tx_queue(struct ieee
if (sta) {
txqi->txq.sta = &sta->sta;
sta->sta.txq[tid] = &txqi->txq;
+ txqi->txq.tid = tid;
txqi->txq.ac = ieee802_1d_to_ac[tid & 7];
} else {
sdata->vif.txq = &txqi->txq;
+ txqi->txq.tid = 0;
txqi->txq.ac = IEEE80211_AC_BE;
}
}

View file

@ -59,7 +59,7 @@
---help---
--- a/.local-symbols
+++ b/.local-symbols
@@ -137,6 +137,7 @@ RTL8187_LEDS=
@@ -140,6 +140,7 @@ RTL8187_LEDS=
ATH_COMMON=
ATH_CARDS=
ATH_DEBUG=

View file

@ -1,6 +1,6 @@
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -2390,6 +2390,8 @@ void regulatory_hint_country_ie(struct w
@@ -2480,6 +2480,8 @@ void regulatory_hint_country_ie(struct w
enum environment_cap env = ENVIRON_ANY;
struct regulatory_request *request = NULL, *lr;
@ -9,7 +9,7 @@
/* IE len must be evenly divisible by 2 */
if (country_ie_len & 0x01)
return;
@@ -2596,6 +2598,7 @@ static void restore_regulatory_settings(
@@ -2686,6 +2688,7 @@ static void restore_regulatory_settings(
void regulatory_hint_disconnect(void)
{

View file

@ -121,7 +121,7 @@ drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++
debugfs_create_file("antenna", S_IWUSR | S_IRUSR, phydir, ah,
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1370,6 +1370,7 @@ struct ath5k_hw {
@@ -1372,6 +1372,7 @@ struct ath5k_hw {
u8 ah_coverage_class;
bool ah_ack_bitrate_high;
u8 ah_bwmode;

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -1032,23 +1032,23 @@ static int __init ath9k_init(void)
@@ -1038,23 +1038,23 @@ static int __init ath9k_init(void)
{
int error;

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -88,7 +88,7 @@ int ath_descdma_setup(struct ath_softc *
@@ -87,7 +87,7 @@ int ath_descdma_setup(struct ath_softc *
(_l) &= ((_sz) - 1); \
} while (0)

View file

@ -1,6 +1,6 @@
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2320,6 +2320,7 @@ struct cfg80211_qos_map {
@@ -2361,6 +2361,7 @@ struct cfg80211_qos_map {
* (as advertised by the nl80211 feature flag.)
* @get_tx_power: store the current TX power into the dbm variable;
* return 0 if successful
@ -8,7 +8,7 @@
*
* @set_wds_peer: set the WDS peer for a WDS interface
*
@@ -2576,6 +2577,7 @@ struct cfg80211_ops {
@@ -2617,6 +2618,7 @@ struct cfg80211_ops {
enum nl80211_tx_power_setting type, int mbm);
int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev,
int *dbm);
@ -18,7 +18,7 @@
const u8 *addr);
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1252,6 +1252,7 @@ enum ieee80211_smps_mode {
@@ -1250,6 +1250,7 @@ enum ieee80211_smps_mode {
*
* @power_level: requested transmit power (in dBm), backward compatibility
* value only that is set to the minimum of all interfaces
@ -26,19 +26,19 @@
*
* @chandef: the channel definition to tune to
* @radar_enabled: whether radar detection is enabled
@@ -1273,6 +1274,7 @@ struct ieee80211_conf {
@@ -1270,6 +1271,7 @@ enum ieee80211_smps_mode {
struct ieee80211_conf {
u32 flags;
int power_level, dynamic_ps_timeout;
int max_sleep_period;
+ int max_antenna_gain;
u16 listen_interval;
u8 ps_dtim_period;
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1761,6 +1761,9 @@ enum nl80211_commands {
* @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
* is operating in an indoor environment.
@@ -1783,6 +1783,9 @@ enum nl80211_commands {
* between scans. The scan plans are executed sequentially.
* Each scan plan is a nested attribute of &enum nl80211_sched_scan_plan.
*
+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
+ * transmit power to stay within regulatory limits. u32, dBi.
@ -46,9 +46,9 @@
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
@@ -2130,6 +2133,8 @@ enum nl80211_attrs {
NL80211_ATTR_REG_INDOOR,
@@ -2157,6 +2160,8 @@ enum nl80211_attrs {
NL80211_ATTR_MAX_SCAN_PLAN_ITERATIONS,
NL80211_ATTR_SCHED_SCAN_PLANS,
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
+
@ -57,7 +57,7 @@
__NL80211_ATTR_AFTER_LAST,
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2233,6 +2233,19 @@ static int ieee80211_get_tx_power(struct
@@ -2206,6 +2206,19 @@ static int ieee80211_get_tx_power(struct
return 0;
}
@ -77,7 +77,7 @@
static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev,
const u8 *addr)
{
@@ -3845,6 +3858,7 @@ const struct cfg80211_ops mac80211_confi
@@ -3849,6 +3862,7 @@ const struct cfg80211_ops mac80211_confi
.set_wiphy_params = ieee80211_set_wiphy_params,
.set_tx_power = ieee80211_set_tx_power,
.get_tx_power = ieee80211_get_tx_power,
@ -87,7 +87,7 @@
CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd)
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1318,6 +1318,7 @@ struct ieee80211_local {
@@ -1321,6 +1321,7 @@ struct ieee80211_local {
int dynamic_ps_forced_timeout;
int user_power_level; /* in dBm, for all interfaces */
@ -97,7 +97,7 @@
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -95,7 +95,7 @@ static u32 ieee80211_hw_conf_chan(struct
@@ -93,7 +93,7 @@ static u32 ieee80211_hw_conf_chan(struct
struct ieee80211_sub_if_data *sdata;
struct cfg80211_chan_def chandef = {};
u32 changed = 0;
@ -106,7 +106,7 @@
u32 offchannel_flag;
offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL;
@@ -152,6 +152,12 @@ static u32 ieee80211_hw_conf_chan(struct
@@ -150,6 +150,12 @@ static u32 ieee80211_hw_conf_chan(struct
}
rcu_read_unlock();
@ -119,7 +119,7 @@
if (local->hw.conf.power_level != power) {
changed |= IEEE80211_CONF_CHANGE_POWER;
local->hw.conf.power_level = power;
@@ -581,6 +587,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
@@ -580,6 +586,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_
IEEE80211_RADIOTAP_MCS_HAVE_BW;
local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI |
IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH;
@ -129,7 +129,7 @@
local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -402,6 +402,7 @@ static const struct nla_policy nl80211_p
@@ -403,6 +403,7 @@ static const struct nla_policy nl80211_p
[NL80211_ATTR_NETNS_FD] = { .type = NLA_U32 },
[NL80211_ATTR_SCHED_SCAN_DELAY] = { .type = NLA_U32 },
[NL80211_ATTR_REG_INDOOR] = { .type = NLA_FLAG },
@ -137,7 +137,7 @@
};
/* policy for the key attributes */
@@ -2207,6 +2208,20 @@ static int nl80211_set_wiphy(struct sk_b
@@ -2220,6 +2221,20 @@ static int nl80211_set_wiphy(struct sk_b
if (result)
return result;
}

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -806,6 +806,9 @@ static inline int ath9k_dump_btcoex(stru
@@ -813,6 +813,9 @@ static inline int ath9k_dump_btcoex(stru
void ath_init_leds(struct ath_softc *sc);
void ath_deinit_leds(struct ath_softc *sc);
void ath_fill_led_pin(struct ath_softc *sc);
@ -10,7 +10,7 @@
#else
static inline void ath_init_leds(struct ath_softc *sc)
{
@@ -945,6 +948,13 @@ void ath_ant_comb_scan(struct ath_softc
@@ -952,6 +955,13 @@ void ath_ant_comb_scan(struct ath_softc
#define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */
@ -24,7 +24,7 @@
struct ath_softc {
struct ieee80211_hw *hw;
struct device *dev;
@@ -996,9 +1006,8 @@ struct ath_softc {
@@ -1003,9 +1013,8 @@ struct ath_softc {
spinlock_t chan_lock;
#ifdef CPTCFG_MAC80211_LEDS
@ -165,7 +165,7 @@
void ath_fill_led_pin(struct ath_softc *sc)
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -944,7 +944,7 @@ int ath9k_init_device(u16 devid, struct
@@ -950,7 +950,7 @@ int ath9k_init_device(u16 devid, struct
#ifdef CPTCFG_MAC80211_LEDS
/* must be initialized before ieee80211_register_hw */

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -695,7 +695,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
@@ -693,7 +693,7 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
{
#define AH_RX_STOP_DMA_TIMEOUT 10000 /* usec */
struct ath_common *common = ath9k_hw_common(ah);
@ -9,7 +9,7 @@
int i;
/* Enable access to the DMA observation bus */
@@ -725,6 +725,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
@@ -723,6 +723,16 @@ bool ath9k_hw_stopdmarecv(struct ath_hw
}
if (i == 0) {

View file

@ -94,7 +94,7 @@
struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah,
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1808,6 +1808,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
@@ -1809,6 +1809,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
}
EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
@ -115,7 +115,7 @@
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata, bool fastcc)
{
@@ -2016,6 +2030,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
@@ -2017,6 +2031,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
ar9003_hw_disable_phy_restart(ah);
ath9k_hw_apply_gpio_override(ah);

View file

@ -18,7 +18,7 @@
void (*spectral_scan_trigger)(struct ath_hw *ah);
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -1999,6 +1999,26 @@ void ar9003_hw_init_rate_txpower(struct
@@ -1998,6 +1998,26 @@ void ar9003_hw_init_rate_txpower(struct
}
}
@ -45,7 +45,7 @@
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -2035,6 +2055,7 @@ void ar9003_hw_attach_phy_ops(struct ath
@@ -2034,6 +2054,7 @@ void ar9003_hw_attach_phy_ops(struct ath
priv_ops->set_radar_params = ar9003_hw_set_radar_params;
priv_ops->fast_chan_change = ar9003_hw_fast_chan_change;
@ -65,7 +65,7 @@
}
static const struct ieee80211_iface_limit if_limits[] = {
@@ -904,6 +905,18 @@ static void ath9k_set_hw_capab(struct at
@@ -910,6 +911,18 @@ static void ath9k_set_hw_capab(struct at
SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
}
@ -84,7 +84,7 @@
int ath9k_init_device(u16 devid, struct ath_softc *sc,
const struct ath_bus_ops *bus_ops)
{
@@ -949,6 +962,8 @@ int ath9k_init_device(u16 devid, struct
@@ -955,6 +968,8 @@ int ath9k_init_device(u16 devid, struct
ARRAY_SIZE(ath9k_tpt_blink));
#endif

View file

@ -20,7 +20,7 @@
/******************/
/* Chip Revisions */
/******************/
@@ -1386,6 +1399,9 @@ static bool ath9k_hw_set_reset(struct at
@@ -1387,6 +1400,9 @@ static bool ath9k_hw_set_reset(struct at
if (AR_SREV_9100(ah))
udelay(50);
@ -30,7 +30,7 @@
return true;
}
@@ -1485,6 +1501,9 @@ static bool ath9k_hw_chip_reset(struct a
@@ -1486,6 +1502,9 @@ static bool ath9k_hw_chip_reset(struct a
ar9003_hw_internal_regulator_apply(ah);
ath9k_hw_init_pll(ah, chan);
@ -40,7 +40,7 @@
return true;
}
@@ -1786,8 +1805,14 @@ static int ath9k_hw_do_fastcc(struct ath
@@ -1787,8 +1806,14 @@ static int ath9k_hw_do_fastcc(struct ath
if (AR_SREV_9271(ah))
ar9002_hw_load_ani_reg(ah, chan);
@ -55,7 +55,7 @@
return -EINVAL;
}
@@ -2041,6 +2066,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
@@ -2042,6 +2067,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
ath9k_hw_set_radar_params(ah);
}

View file

@ -79,7 +79,7 @@
static const u8 ofdm2pwr[] = {
ALL_TARGET_LEGACY_6_24,
ALL_TARGET_LEGACY_6_24,
@@ -1090,11 +1076,6 @@ static bool ar9003_hw_ani_control(struct
@@ -1089,11 +1075,6 @@ static bool ar9003_hw_ani_control(struct
struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *chan = ah->curchan;
struct ar5416AniState *aniState = &ah->ani;
@ -91,7 +91,7 @@
s32 value, value2;
switch (cmd & ah->ani_function) {
@@ -1108,61 +1089,6 @@ static bool ar9003_hw_ani_control(struct
@@ -1107,61 +1088,6 @@ static bool ar9003_hw_ani_control(struct
*/
u32 on = param ? 1 : 0;

View file

@ -122,7 +122,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
*/
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -987,6 +987,11 @@ struct rt2x00_dev {
@@ -989,6 +989,11 @@ struct rt2x00_dev {
int rf_channel;
/*

View file

@ -1,6 +1,6 @@
--- a/.local-symbols
+++ b/.local-symbols
@@ -312,6 +312,7 @@ RT2X00_LIB_FIRMWARE=
@@ -314,6 +314,7 @@ RT2X00_LIB_FIRMWARE=
RT2X00_LIB_CRYPTO=
RT2X00_LIB_LEDS=
RT2X00_LIB_DEBUGFS=
@ -26,7 +26,7 @@
select RT2800_LIB
select RT2800_LIB_MMIO
---help---
@@ -266,6 +268,9 @@ config RT2X00_LIB_FIRMWARE
@@ -265,6 +267,9 @@ config RT2X00_LIB_FIRMWARE
config RT2X00_LIB_CRYPTO
bool
@ -105,7 +105,7 @@
.drv_init_registers = rt2800mmio_init_registers,
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -695,6 +695,7 @@ enum rt2x00_capability_flags {
@@ -697,6 +697,7 @@ enum rt2x00_capability_flags {
REQUIRE_HT_TX_DESC,
REQUIRE_PS_AUTOWAKE,
REQUIRE_DELAYED_RFKILL,
@ -113,7 +113,7 @@
/*
* Capabilities
@@ -964,6 +965,11 @@ struct rt2x00_dev {
@@ -966,6 +967,11 @@ struct rt2x00_dev {
const struct firmware *fw;
/*

View file

@ -37,7 +37,7 @@
num_rates += 4;
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -403,6 +403,7 @@ struct hw_mode_spec {
@@ -405,6 +405,7 @@ struct hw_mode_spec {
unsigned int supported_bands;
#define SUPPORT_BAND_2GHZ 0x00000001
#define SUPPORT_BAND_5GHZ 0x00000002

View file

@ -31,7 +31,7 @@
{
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1410,6 +1410,7 @@ static inline void rt2x00debug_dump_fram
@@ -1412,6 +1412,7 @@ static inline void rt2x00debug_dump_fram
*/
u32 rt2x00lib_get_bssidx(struct rt2x00_dev *rt2x00dev,
struct ieee80211_vif *vif);

View file

@ -200,7 +200,7 @@
* EEPROM frequency
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -715,6 +715,8 @@ enum rt2x00_capability_flags {
@@ -717,6 +717,8 @@ enum rt2x00_capability_flags {
CAPABILITY_DOUBLE_ANTENNA,
CAPABILITY_BT_COEXIST,
CAPABILITY_VCO_RECALIBRATION,

View file

@ -78,7 +78,7 @@
retval = rt2800_probe_hw_mode(rt2x00dev);
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -398,6 +398,7 @@ static inline struct rt2x00_intf* vif_to
@@ -400,6 +400,7 @@ static inline struct rt2x00_intf* vif_to
* @channels: Device/chipset specific channel values (See &struct rf_channel).
* @channels_info: Additional information for channels (See &struct channel_info).
* @ht: Driver HT Capabilities (See &ieee80211_sta_ht_cap).
@ -86,7 +86,7 @@
*/
struct hw_mode_spec {
unsigned int supported_bands;
@@ -414,6 +415,7 @@ struct hw_mode_spec {
@@ -416,6 +417,7 @@ struct hw_mode_spec {
const struct channel_info *channels_info;
struct ieee80211_sta_ht_cap ht;

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -5678,6 +5678,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
@@ -5679,6 +5679,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw")
MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API));
static const struct pci_device_id mwl8k_pci_id_table[] = {

View file

@ -22,7 +22,7 @@
static int modparam_bad_frames_preempt;
module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444);
MODULE_PARM_DESC(bad_frames_preempt,
@@ -2882,10 +2887,10 @@ static int b43_gpio_init(struct b43_wlde
@@ -2883,10 +2888,10 @@ static int b43_gpio_init(struct b43_wlde
u32 mask, set;
b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);

View file

@ -11,7 +11,7 @@
b43-$(CPTCFG_B43_LEDS) += leds.o
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2008,10 +2008,12 @@ static void b43_do_interrupt_thread(stru
@@ -2009,10 +2009,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]);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1648,7 +1648,7 @@ static void b43_write_beacon_template(st
@@ -1649,7 +1649,7 @@ static void b43_write_beacon_template(st
len, ram_offset, shm_size_offset, rate);
/* Write the PHY TX control parameters. */
@ -9,7 +9,7 @@
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. */
@@ -3300,8 +3300,8 @@ static int b43_chip_init(struct b43_wlde
@@ -3301,8 +3301,8 @@ static int b43_chip_init(struct b43_wlde
/* Select the antennae */
if (phy->ops->set_rx_antenna)
@ -20,7 +20,7 @@
if (phy->type == B43_PHYTYPE_B) {
value16 = b43_read16(dev, 0x005E);
@@ -4001,7 +4001,6 @@ static int b43_op_config(struct ieee8021
@@ -4002,7 +4002,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;
@ -28,7 +28,7 @@
int err = 0;
mutex_lock(&wl->mutex);
@@ -4044,11 +4043,9 @@ static int b43_op_config(struct ieee8021
@@ -4045,11 +4044,9 @@ static int b43_op_config(struct ieee8021
}
/* Antennas for RX and management frame TX. */
@ -42,7 +42,7 @@
if (wl->radio_enabled != phy->radio_on) {
if (wl->radio_enabled) {
@@ -5209,6 +5206,47 @@ static int b43_op_get_survey(struct ieee
@@ -5210,6 +5207,47 @@ static int b43_op_get_survey(struct ieee
return 0;
}
@ -90,7 +90,7 @@
static const struct ieee80211_ops b43_hw_ops = {
.tx = b43_op_tx,
.conf_tx = b43_op_conf_tx,
@@ -5230,6 +5268,8 @@ static const struct ieee80211_ops b43_hw
@@ -5231,6 +5269,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,
@ -99,7 +99,7 @@
};
/* Hard-reset the chip. Do not call this directly.
@@ -5538,6 +5578,8 @@ static int b43_one_core_attach(struct b4
@@ -5539,6 +5579,8 @@ static int b43_one_core_attach(struct b4
if (!wldev)
goto out;
@ -108,7 +108,7 @@
wldev->use_pio = b43_modparam_pio;
wldev->dev = dev;
wldev->wl = wl;
@@ -5628,6 +5670,9 @@ static struct b43_wl *b43_wireless_init(
@@ -5629,6 +5671,9 @@ static struct b43_wl *b43_wireless_init(
hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2899,6 +2899,14 @@ static int b43_gpio_init(struct b43_wlde
@@ -2900,6 +2900,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 */

View file

@ -1,80 +0,0 @@
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <zajec5@gmail.com>
Date: Mon, 8 Jun 2015 16:59:31 +0200
Subject: [PATCH] brcmfmac: use bcm47xx platform NVRAM as fallback
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/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -19,6 +19,9 @@
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/module.h>
+#if IS_ENABLED(CONFIG_BCM47XX_NVRAM)
+#include <linux/bcm47xx_nvram.h>
+#endif
#include "debug.h"
#include "firmware.h"
@@ -424,17 +427,42 @@ struct brcmf_fw {
static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
{
struct brcmf_fw *fwctx = ctx;
+#if IS_ENABLED(CONFIG_BCM47XX_NVRAM)
+ const u8 *bcm47xx_nvram = NULL;
+ size_t bcm47xx_nvram_len;
+#endif
+ const u8 *data = NULL;
+ size_t data_len;
u32 nvram_length = 0;
void *nvram = NULL;
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
- if (!fw && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
+ if (fw) {
+ data = fw->data;
+ data_len = fw->size;
+ }
+#if IS_ENABLED(CONFIG_BCM47XX_NVRAM)
+ else {
+ bcm47xx_nvram = bcm47xx_nvram_get_contents(&bcm47xx_nvram_len);
+ if (bcm47xx_nvram) {
+ data = bcm47xx_nvram;
+ data_len = bcm47xx_nvram_len;
+ brcmf_err("Found platform NVRAM (%zu B)\n", data_len);
+ }
+ }
+#endif
+ if (!data && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
goto fail;
- if (fw) {
- nvram = brcmf_fw_nvram_strip(fw->data, fw->size, &nvram_length,
+ if (data) {
+ nvram = brcmf_fw_nvram_strip(data, data_len, &nvram_length,
fwctx->domain_nr, fwctx->bus_nr);
- release_firmware(fw);
+ if (fw)
+ release_firmware(fw);
+#if IS_ENABLED(CONFIG_BCM47XX_NVRAM)
+ if (bcm47xx_nvram)
+ bcm47xx_nvram_release_contents(bcm47xx_nvram);
+#endif
if (!nvram && !(fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL))
goto fail;
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/debug.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/debug.h
@@ -17,6 +17,8 @@
#ifndef BRCMFMAC_DEBUG_H
#define BRCMFMAC_DEBUG_H
+#include <linux/net.h>
+
/* message levels */
#define BRCMF_TRACE_VAL 0x00000002
#define BRCMF_INFO_VAL 0x00000004

View file

@ -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
@@ -1213,6 +1213,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;
@ -23,7 +23,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
}
--- a/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/firmware.c
@@ -422,13 +422,14 @@ struct brcmf_fw {
@@ -420,6 +420,7 @@ struct brcmf_fw {
u16 bus_nr;
void (*done)(struct device *dev, const struct firmware *fw,
void *nvram_image, u32 nvram_len);
@ -31,16 +31,8 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
};
static void brcmf_fw_request_nvram_done(const struct firmware *fw, void *ctx)
{
struct brcmf_fw *fwctx = ctx;
#if IS_ENABLED(CONFIG_BCM47XX_NVRAM)
- const u8 *bcm47xx_nvram = NULL;
+ u8 *bcm47xx_nvram = NULL;
size_t bcm47xx_nvram_len;
#endif
const u8 *data = NULL;
@@ -468,6 +469,8 @@ static void brcmf_fw_request_nvram_done(
}
@@ -455,6 +456,8 @@ static void brcmf_fw_request_nvram_done(
goto fail;
fwctx->done(fwctx->dev, fwctx->code, nvram, nvram_length);
+ if (fwctx->completion)
@ -48,7 +40,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
kfree(fwctx);
return;
@@ -475,6 +478,8 @@ fail:
@@ -462,6 +465,8 @@ fail:
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
release_firmware(fwctx->code);
device_release_driver(fwctx->dev);
@ -57,7 +49,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
kfree(fwctx);
}
@@ -490,6 +495,8 @@ static void brcmf_fw_request_code_done(c
@@ -477,6 +482,8 @@ static void brcmf_fw_request_code_done(c
/* only requested code so done here */
if (!(fwctx->flags & BRCMF_FW_REQUEST_NVRAM)) {
fwctx->done(fwctx->dev, fw, NULL, 0);
@ -66,16 +58,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
kfree(fwctx);
return;
}
@@ -504,6 +511,8 @@ static void brcmf_fw_request_code_done(c
/* when nvram is optional call .done() callback here */
if (fwctx->flags & BRCMF_FW_REQ_NV_OPTIONAL) {
fwctx->done(fwctx->dev, fw, NULL, 0);
+ if (fwctx->completion)
+ complete(fwctx->completion);
kfree(fwctx);
return;
}
@@ -513,6 +522,8 @@ static void brcmf_fw_request_code_done(c
@@ -494,6 +501,8 @@ static void brcmf_fw_request_code_done(c
fail:
brcmf_dbg(TRACE, "failed: dev=%s\n", dev_name(fwctx->dev));
device_release_driver(fwctx->dev);
@ -84,7 +67,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
kfree(fwctx);
}
@@ -524,6 +535,8 @@ int brcmf_fw_get_firmwares_pcie(struct d
@@ -505,6 +514,8 @@ int brcmf_fw_get_firmwares_pcie(struct d
u16 domain_nr, u16 bus_nr)
{
struct brcmf_fw *fwctx;
@ -93,7 +76,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
if (!fw_cb || !code)
@@ -544,9 +557,17 @@ int brcmf_fw_get_firmwares_pcie(struct d
@@ -525,9 +536,17 @@ int brcmf_fw_get_firmwares_pcie(struct d
fwctx->domain_nr = domain_nr;
fwctx->bus_nr = bus_nr;

View file

@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki <zajec5@gmail.com>
--- a/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/cfg80211.c
@@ -692,9 +692,37 @@ static struct wireless_dev *brcmf_cfg802
@@ -609,9 +609,37 @@ static struct wireless_dev *brcmf_cfg802
u32 *flags,
struct vif_params *params)
{

View file

@ -14,7 +14,7 @@ Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -1520,6 +1520,16 @@ int ath10k_core_register(struct ath10k *
@@ -1843,6 +1843,16 @@ int ath10k_core_register(struct ath10k *
ar->chip_id = chip_id;
queue_work(ar->workqueue, &ar->register_work);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -6804,6 +6804,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
@@ -7085,6 +7085,21 @@ struct ath10k_vif *ath10k_get_arvif(stru
return arvif_iter.arvif;
}
@ -22,7 +22,7 @@
int ath10k_mac_register(struct ath10k *ar)
{
static const u32 cipher_suites[] = {
@@ -7025,6 +7040,12 @@ int ath10k_mac_register(struct ath10k *a
@@ -7310,6 +7325,12 @@ int ath10k_mac_register(struct ath10k *a
ar->hw->wiphy->cipher_suites = cipher_suites;
ar->hw->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/mwl8k.c
+++ b/drivers/net/wireless/mwl8k.c
@@ -6261,6 +6261,8 @@ static int mwl8k_probe(struct pci_dev *p
@@ -6262,6 +6262,8 @@ static int mwl8k_probe(struct pci_dev *p
priv->running_bsses = 0;
@ -9,7 +9,7 @@
return rc;
err_stop_firmware:
@@ -6294,8 +6296,6 @@ static void mwl8k_remove(struct pci_dev
@@ -6295,8 +6297,6 @@ static void mwl8k_remove(struct pci_dev
return;
priv = hw->priv;

View file

@ -1,7 +1,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=mt76
PKG_VERSION:=2015-10-12
PKG_VERSION:=2015-10-30
PKG_RELEASE=1
PKG_LICENSE:=GPLv2
@ -10,7 +10,7 @@ PKG_LICENSE_FILES:=
PKG_SOURCE_URL:=https://github.com/openwrt/mt76
PKG_SOURCE_PROTO:=git
PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION)
PKG_SOURCE_VERSION:=2f31d1e329dc43074a05782624195860c45b099a
PKG_SOURCE_VERSION:=a3ba5b080d1a4bcbf8dc891ba835ed742603382f
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.xz
PKG_MAINTAINER:=Felix Fietkau <nbd@openwrt.org>

View file

@ -0,0 +1,11 @@
--- a/mac80211.c
+++ b/mac80211.c
@@ -574,7 +574,7 @@ static int mwl_mac80211_ampdu_action(str
struct ieee80211_vif *vif,
enum ieee80211_ampdu_mlme_action action,
struct ieee80211_sta *sta,
- u16 tid, u16 *ssn, u8 buf_size)
+ u16 tid, u16 *ssn, u8 buf_size, bool amsdu)
{
int rc = 0;
struct mwl_priv *priv = hw->priv;