mac80211: update to wireless-testing 2015-03-09

Based on patch by Bryan Forbes <bryan@reigndropsfall.net>

Also update mt76 to update for API changes

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

SVN-Revision: 44655
This commit is contained in:
Felix Fietkau 2015-03-11 15:02:47 +00:00
parent ee1e8c2f2d
commit 1e5b7c17b0
113 changed files with 2768 additions and 2977 deletions

View file

@ -10,11 +10,11 @@ include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mac80211
PKG_VERSION:=2014-11-04
PKG_VERSION:=2015-03-09
PKG_RELEASE:=1
PKG_SOURCE_URL:=http://mirror2.openwrt.org/sources
PKG_BACKPORT_VERSION:=
PKG_MD5SUM:=d0b64853fb78cfd1d6cb639327811e2a
PKG_MD5SUM:=6d4b04e4ce8a1f54dabfb04f4709453c
PKG_SOURCE:=compat-wireless-$(PKG_VERSION)$(PKG_BACKPORT_VERSION).tar.bz2
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/compat-wireless-$(PKG_VERSION)

View file

@ -1,16 +1,14 @@
--- a/kconf/Makefile
+++ b/kconf/Makefile
@@ -1,10 +1,10 @@
@@ -1,9 +1,9 @@
-CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer
+CFLAGS=-Wall -Wmissing-prototypes -Wstrict-prototypes -O2 -fomit-frame-pointer -DKBUILD_NO_NLS
LXDIALOG := lxdialog/checklist.o lxdialog/inputbox.o lxdialog/menubox.o lxdialog/textbox.o lxdialog/util.o lxdialog/yesno.o
conf: conf.o zconf.tab.o
-mconf: LDFLAGS = -Wl,--add-needed $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
-mconf: CFLAGS += -DCURSES_LOC="<ncurses.h>" -DLOCALE
+mconf: LDFLAGS = $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
+mconf: CFLAGS += -DCURSES_LOC="<ncurses.h>"
mconf: mconf.o zconf.tab.o $(LXDIALOG)
-mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags) -DLOCALE
+mconf_CFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ccflags)
mconf_LDFLAGS := $(shell ./lxdialog/check-lxdialog.sh -ldflags $(CC))
mconf: CFLAGS += $(mconf_CFLAGS)
.PHONY: clean

View file

@ -6,7 +6,7 @@
MAKEFLAGS += --no-print-directory
-SHELL := /bin/bash
+SHELL := /usr/bin/env bash
BACKPORT_PWD := $(shell pwd)
BACKPORT_DIR := $(shell pwd)
KMODDIR ?= updates
@@ -19,6 +19,7 @@ KLIB_BUILD ?= $(KLIB)/build/
@ -15,7 +15,7 @@
CONFIG_MD5 := $(shell md5sum $(KERNEL_CONFIG) 2>/dev/null | sed 's/\s.*//')
+STAMP_KERNEL_CONFIG := .kernel_config_md5_$(CONFIG_MD5)
export KLIB KLIB_BUILD BACKPORT_PWD KMODDIR KMODPATH_ARG
export KLIB KLIB_BUILD BACKPORT_DIR KMODDIR KMODPATH_ARG
@@ -36,7 +37,8 @@ mrproper:
@rm -f .kernel_config_md5 Kconfig.versions Kconfig.kernel
@ -64,7 +64,7 @@
- print=0 ;\
- for v in $$kvers ; do \
- if [ "$$print" = "1" ] ; then \
- echo config BACKPORT_KERNEL_$$(echo $$v | tr . _) ;\
- echo config KERNEL_$$(echo $$v | tr . _) ;\
- echo " def_bool y" ;\
- fi ;\
- if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\
@ -119,7 +119,7 @@
+ print=0 ;\
+ for v in $$kvers ; do \
+ if [ "$$print" = "1" ] ; then \
+ echo config BACKPORT_KERNEL_$$(echo $$v | tr . _) ;\
+ echo config KERNEL_$$(echo $$v | tr . _) ;\
+ echo " def_bool y" ;\
+ fi ;\
+ if [ "$$v" = "$$kver" ] ; then print=1 ; fi ;\

View file

@ -1,14 +1,14 @@
--- a/compat/main.c
+++ b/compat/main.c
@@ -20,31 +20,6 @@ MODULE_LICENSE("GPL");
#error "You need a BACKPORTS_VERSION"
#error "You need a CPTCFG_VERSION"
#endif
-static char *backported_kernel_name = BACKPORTED_KERNEL_NAME;
-static char *backported_kernel_name = CPTCFG_KERNEL_NAME;
-
-module_param(backported_kernel_name, charp, 0400);
-MODULE_PARM_DESC(backported_kernel_name,
- "The kernel tree name that was used for this backport (" BACKPORTED_KERNEL_NAME ")");
- "The kernel tree name that was used for this backport (" CPTCFG_KERNEL_NAME ")");
-
-#ifdef BACKPORTS_GIT_TRACKED
-static char *backports_tracker_id = BACKPORTS_GIT_TRACKED;
@ -16,16 +16,16 @@
-MODULE_PARM_DESC(backports_tracker_id,
- "The version of the tree containing this backport (" BACKPORTS_GIT_TRACKED ")");
-#else
-static char *backported_kernel_version = BACKPORTED_KERNEL_VERSION;
-static char *backports_version = BACKPORTS_VERSION;
-static char *backported_kernel_version = CPTCFG_KERNEL_VERSION;
-static char *backports_version = CPTCFG_VERSION;
-
-module_param(backported_kernel_version, charp, 0400);
-MODULE_PARM_DESC(backported_kernel_version,
- "The kernel version that was used for this backport (" BACKPORTED_KERNEL_VERSION ")");
- "The kernel version that was used for this backport (" CPTCFG_KERNEL_VERSION ")");
-
-module_param(backports_version, charp, 0400);
-MODULE_PARM_DESC(backports_version,
- "The git version of the backports tree used to generate this backport (" BACKPORTS_VERSION ")");
- "The git version of the backports tree used to generate this backport (" CPTCFG_VERSION ")");
-
-#endif
-

View file

@ -0,0 +1,10 @@
--- a/backport-include/linux/debugfs.h
+++ b/backport-include/linux/debugfs.h
@@ -3,6 +3,7 @@
#include_next <linux/debugfs.h>
#include <linux/version.h>
#include <generated/utsrelease.h>
+#include <linux/device.h>
#if defined(CONFIG_DEBUG_FS)
struct dentry *debugfs_create_devm_seqfile(struct device *dev, const char *name,

View file

@ -1,6 +1,6 @@
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1859,6 +1859,13 @@ void ieee80211_remove_interfaces(struct
@@ -1858,6 +1858,13 @@ void ieee80211_remove_interfaces(struct
}
mutex_unlock(&local->iflist_mtx);
unregister_netdevice_many(&unreg_list);

View file

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

View file

@ -1,7 +1,7 @@
--- a/net/wireless/Kconfig
+++ b/net/wireless/Kconfig
@@ -166,7 +166,7 @@ config CFG80211_WEXT
extensions with cfg80211-based drivers.
@@ -174,7 +174,7 @@ config CFG80211_WEXT_EXPORT
wext compatibility symbols to be exported.
config LIB80211
- tristate
@ -9,7 +9,7 @@
depends on m
default n
help
@@ -176,15 +176,15 @@ config LIB80211
@@ -184,15 +184,15 @@ config LIB80211
Drivers should select this themselves if needed.
config LIB80211_CRYPT_WEP

View file

@ -1,6 +1,6 @@
--- a/.local-symbols
+++ b/.local-symbols
@@ -423,42 +423,6 @@ USB_CDC_PHONET=
@@ -344,40 +344,3 @@ USB_CDC_PHONET=
USB_IPHETH=
USB_SIERRA_NET=
USB_VL600=
@ -34,41 +34,27 @@
-BCMA_HOST_PCI=
-BCMA_DRIVER_PCI_HOSTMODE=
-BCMA_HOST_SOC=
-BCMA_DRIVER_PCI=
-BCMA_DRIVER_MIPS=
-BCMA_SFLASH=
-BCMA_NFLASH=
-BCMA_DRIVER_GMAC_CMN=
-BCMA_DRIVER_GPIO=
-BCMA_DEBUG=
NFC=
NFC_DIGITAL=
NFC_NCI=
--- a/Kconfig
+++ b/Kconfig
@@ -33,9 +33,6 @@ source drivers/net/wireless/Kconfig
source drivers/net/ethernet/Kconfig
source drivers/net/usb/Kconfig
-source drivers/ssb/Kconfig
-source drivers/bcma/Kconfig
-
source net/nfc/Kconfig
source drivers/media/Kconfig
--- a/Makefile.kernel
+++ b/Makefile.kernel
@@ -25,8 +25,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
@@ -38,8 +38,6 @@ obj-$(CPTCFG_MAC80211) += net/mac80211/
obj-$(CPTCFG_WLAN) += drivers/net/wireless/
obj-$(CPTCFG_BT) += net/bluetooth/
obj-$(CPTCFG_BT) += drivers/bluetooth/
#obj-$(CPTCFG_BT) += net/bluetooth/
#obj-$(CPTCFG_BT) += drivers/bluetooth/
-obj-$(CPTCFG_SSB) += drivers/ssb/
-obj-$(CPTCFG_BCMA) += drivers/bcma/
obj-$(CPTCFG_ETHERNET) += drivers/net/ethernet/
#obj-$(CPTCFG_ETHERNET) += drivers/net/ethernet/
obj-$(CPTCFG_USB_NET_RNDIS_WLAN) += drivers/net/usb/
obj-$(CPTCFG_NFC) += net/nfc/
#obj-$(CPTCFG_NFC) += net/nfc/
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2828,7 +2828,7 @@ static struct ssb_device *b43_ssb_gpio_d
@@ -2866,7 +2866,7 @@ static struct ssb_device *b43_ssb_gpio_d
{
struct ssb_bus *bus = dev->dev->sdev->bus;
@ -77,7 +63,7 @@
return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev);
#else
return bus->chipco.dev;
@@ -4858,7 +4858,7 @@ static int b43_wireless_core_init(struct
@@ -4907,7 +4907,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. */
@ -127,3 +113,15 @@
void brcms_led_unregister(struct brcms_info *wl);
int brcms_led_register(struct brcms_info *wl);
#else
--- a/Kconfig.sources
+++ b/Kconfig.sources
@@ -9,9 +9,6 @@ source "$BACKPORT_DIR/drivers/net/wirele
#source "$BACKPORT_DIR/drivers/net/ethernet/Kconfig"
source "$BACKPORT_DIR/drivers/net/usb/Kconfig"
-source "$BACKPORT_DIR/drivers/ssb/Kconfig"
-source "$BACKPORT_DIR/drivers/bcma/Kconfig"
-
#source "$BACKPORT_DIR/net/nfc/Kconfig"
#source "$BACKPORT_DIR/drivers/media/Kconfig"

View file

@ -1,9 +1,9 @@
--- a/backport-include/linux/device.h
+++ b/backport-include/linux/device.h
@@ -177,4 +177,20 @@ static inline void *devm_kmalloc_array(s
}
@@ -200,4 +200,20 @@ static inline void *devm_kmemdup(struct
#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(3,15,0)
+#define devm_kmemdup LINUX_BACKPORT(devm_kmemdup)
+static inline void *devm_kmemdup(struct device *dev, const void *src,

View file

@ -1,8 +1,8 @@
--- a/backport-include/linux/list.h
+++ b/backport-include/linux/list.h
@@ -73,4 +73,17 @@
list_entry((pos)->member.next, typeof(*(pos)), member)
#endif /* list_next_entry */
@@ -88,4 +88,17 @@
list_entry((ptr)->prev, type, member)
#endif
+#ifndef list_last_entry
+/**

View file

@ -1,318 +0,0 @@
--- a/drivers/bcma/bcma_private.h
+++ b/drivers/bcma/bcma_private.h
@@ -41,6 +41,7 @@ int __init bcma_bus_scan_early(struct bc
struct bcma_device_id *match,
struct bcma_device *core);
void bcma_init_bus(struct bcma_bus *bus);
+void bcma_unregister_cores(struct bcma_bus *bus);
/* sprom.c */
int bcma_sprom_get(struct bcma_bus *bus);
@@ -105,6 +106,11 @@ static inline void __exit bcma_host_soc_
/* driver_pci.c */
u32 bcma_pcie_read(struct bcma_drv_pci *pc, u32 address);
+void bcma_core_pci_up(struct bcma_drv_pci *pc);
+void bcma_core_pci_down(struct bcma_drv_pci *pc);
+
+/* driver_pcie2.c */
+void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2);
extern int bcma_chipco_watchdog_register(struct bcma_drv_cc *cc);
--- a/drivers/bcma/driver_gpio.c
+++ b/drivers/bcma/driver_gpio.c
@@ -76,7 +76,7 @@ static void bcma_gpio_free(struct gpio_c
bcma_chipco_gpio_pullup(cc, 1 << gpio, 0);
}
-#if IS_BUILTIN(CONFIG_BCM47XX)
+#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X)
static int bcma_gpio_to_irq(struct gpio_chip *chip, unsigned gpio)
{
struct bcma_drv_cc *cc = bcma_gpio_get_cc(chip);
@@ -215,7 +215,7 @@ int bcma_gpio_init(struct bcma_drv_cc *c
chip->set = bcma_gpio_set_value;
chip->direction_input = bcma_gpio_direction_input;
chip->direction_output = bcma_gpio_direction_output;
-#if IS_BUILTIN(CONFIG_BCM47XX)
+#if IS_BUILTIN(CONFIG_BCM47XX) || IS_BUILTIN(CONFIG_ARCH_BCM_5301X)
chip->to_irq = bcma_gpio_to_irq;
#endif
#if IS_BUILTIN(CONFIG_OF)
--- a/drivers/bcma/driver_pci.c
+++ b/drivers/bcma/driver_pci.c
@@ -262,21 +262,21 @@ void bcma_core_pci_power_save(struct bcm
}
EXPORT_SYMBOL_GPL(bcma_core_pci_power_save);
-int bcma_core_pci_irq_ctl(struct bcma_drv_pci *pc, struct bcma_device *core,
+int bcma_core_pci_irq_ctl(struct bcma_bus *bus, struct bcma_device *core,
bool enable)
{
struct pci_dev *pdev;
u32 coremask, tmp;
int err = 0;
- if (!pc || core->bus->hosttype != BCMA_HOSTTYPE_PCI) {
+ if (bus->hosttype != BCMA_HOSTTYPE_PCI) {
/* This bcma device is not on a PCI host-bus. So the IRQs are
* not routed through the PCI core.
* So we must not enable routing through the PCI core. */
goto out;
}
- pdev = pc->core->bus->host_pci;
+ pdev = bus->host_pci;
err = pci_read_config_dword(pdev, BCMA_PCI_IRQMASK, &tmp);
if (err)
@@ -308,28 +308,12 @@ static void bcma_core_pci_extend_L1timer
bcma_pcie_read(pc, BCMA_CORE_PCI_DLLP_PMTHRESHREG);
}
-void bcma_core_pci_up(struct bcma_bus *bus)
+void bcma_core_pci_up(struct bcma_drv_pci *pc)
{
- struct bcma_drv_pci *pc;
-
- if (bus->hosttype != BCMA_HOSTTYPE_PCI)
- return;
-
- pc = &bus->drv_pci[0];
-
bcma_core_pci_extend_L1timer(pc, true);
}
-EXPORT_SYMBOL_GPL(bcma_core_pci_up);
-void bcma_core_pci_down(struct bcma_bus *bus)
+void bcma_core_pci_down(struct bcma_drv_pci *pc)
{
- struct bcma_drv_pci *pc;
-
- if (bus->hosttype != BCMA_HOSTTYPE_PCI)
- return;
-
- pc = &bus->drv_pci[0];
-
bcma_core_pci_extend_L1timer(pc, false);
}
-EXPORT_SYMBOL_GPL(bcma_core_pci_down);
--- a/drivers/bcma/driver_pci_host.c
+++ b/drivers/bcma/driver_pci_host.c
@@ -11,6 +11,7 @@
#include "bcma_private.h"
#include <linux/pci.h>
+#include <linux/slab.h>
#include <linux/export.h>
#include <linux/bcma/bcma.h>
#include <asm/paccess.h>
--- a/drivers/bcma/driver_pcie2.c
+++ b/drivers/bcma/driver_pcie2.c
@@ -10,6 +10,7 @@
#include "bcma_private.h"
#include <linux/bcma/bcma.h>
+#include <linux/pci.h>
/**************************************************
* R/W ops.
@@ -156,14 +157,23 @@ static void pciedev_reg_pm_clk_period(st
void bcma_core_pcie2_init(struct bcma_drv_pcie2 *pcie2)
{
- struct bcma_chipinfo *ci = &pcie2->core->bus->chipinfo;
+ struct bcma_bus *bus = pcie2->core->bus;
+ struct bcma_chipinfo *ci = &bus->chipinfo;
u32 tmp;
tmp = pcie2_read32(pcie2, BCMA_CORE_PCIE2_SPROM(54));
if ((tmp & 0xe) >> 1 == 2)
bcma_core_pcie2_cfg_write(pcie2, 0x4e0, 0x17);
- /* TODO: Do we need pcie_reqsize? */
+ switch (bus->chipinfo.id) {
+ case BCMA_CHIP_ID_BCM4360:
+ case BCMA_CHIP_ID_BCM4352:
+ pcie2->reqsize = 1024;
+ break;
+ default:
+ pcie2->reqsize = 128;
+ break;
+ }
if (ci->id == BCMA_CHIP_ID_BCM4360 && ci->rev > 3)
bcma_core_pcie2_war_delay_perst_enab(pcie2, true);
@@ -173,3 +183,18 @@ void bcma_core_pcie2_init(struct bcma_dr
pciedev_crwlpciegen2_180(pcie2);
pciedev_crwlpciegen2_182(pcie2);
}
+
+/**************************************************
+ * Runtime ops.
+ **************************************************/
+
+void bcma_core_pcie2_up(struct bcma_drv_pcie2 *pcie2)
+{
+ struct bcma_bus *bus = pcie2->core->bus;
+ struct pci_dev *dev = bus->host_pci;
+ int err;
+
+ err = pcie_set_readrq(dev, pcie2->reqsize);
+ if (err)
+ bcma_err(bus, "Error setting PCI_EXP_DEVCTL_READRQ: %d\n", err);
+}
--- a/drivers/bcma/host_pci.c
+++ b/drivers/bcma/host_pci.c
@@ -211,16 +211,26 @@ static int bcma_host_pci_probe(struct pc
/* Initialize struct, detect chip */
bcma_init_bus(bus);
+ /* Scan bus to find out generation of PCIe core */
+ err = bcma_bus_scan(bus);
+ if (err)
+ goto err_pci_unmap_mmio;
+
+ if (bcma_find_core(bus, BCMA_CORE_PCIE2))
+ bus->host_is_pcie2 = true;
+
/* Register */
err = bcma_bus_register(bus);
if (err)
- goto err_pci_unmap_mmio;
+ goto err_unregister_cores;
pci_set_drvdata(dev, bus);
out:
return err;
+err_unregister_cores:
+ bcma_unregister_cores(bus);
err_pci_unmap_mmio:
pci_iounmap(dev, bus->mmio);
err_pci_release_regions:
@@ -281,9 +291,12 @@ static const struct pci_device_id bcma_p
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4357) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4358) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4359) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4360) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4365) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a0) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43a9) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43aa) },
+ { PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x43b1) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 0x4727) },
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43227) }, /* 0xa8db, BCM43217 (sic!) */
{ PCI_DEVICE(PCI_VENDOR_ID_BROADCOM, 43228) }, /* 0xa8dc */
@@ -308,3 +321,31 @@ void __exit bcma_host_pci_exit(void)
{
pci_unregister_driver(&bcma_pci_bridge_driver);
}
+
+/**************************************************
+ * Runtime ops for drivers.
+ **************************************************/
+
+/* See also pcicore_up */
+void bcma_host_pci_up(struct bcma_bus *bus)
+{
+ if (bus->hosttype != BCMA_HOSTTYPE_PCI)
+ return;
+
+ if (bus->host_is_pcie2)
+ bcma_core_pcie2_up(&bus->drv_pcie2);
+ else
+ bcma_core_pci_up(&bus->drv_pci[0]);
+}
+EXPORT_SYMBOL_GPL(bcma_host_pci_up);
+
+/* See also pcicore_down */
+void bcma_host_pci_down(struct bcma_bus *bus)
+{
+ if (bus->hosttype != BCMA_HOSTTYPE_PCI)
+ return;
+
+ if (!bus->host_is_pcie2)
+ bcma_core_pci_down(&bus->drv_pci[0]);
+}
+EXPORT_SYMBOL_GPL(bcma_host_pci_down);
--- a/drivers/bcma/main.c
+++ b/drivers/bcma/main.c
@@ -288,7 +288,7 @@ static int bcma_register_devices(struct
return 0;
}
-static void bcma_unregister_cores(struct bcma_bus *bus)
+void bcma_unregister_cores(struct bcma_bus *bus)
{
struct bcma_device *core, *tmp;
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4770,7 +4770,7 @@ static void b43_wireless_core_exit(struc
switch (dev->dev->bus_type) {
#ifdef CPTCFG_B43_BCMA
case B43_BUS_BCMA:
- bcma_core_pci_down(dev->dev->bdev->bus);
+ bcma_host_pci_down(dev->dev->bdev->bus);
break;
#endif
#ifdef CPTCFG_B43_SSB
@@ -4817,9 +4817,9 @@ static int b43_wireless_core_init(struct
switch (dev->dev->bus_type) {
#ifdef CPTCFG_B43_BCMA
case B43_BUS_BCMA:
- bcma_core_pci_irq_ctl(&dev->dev->bdev->bus->drv_pci[0],
+ bcma_core_pci_irq_ctl(dev->dev->bdev->bus,
dev->dev->bdev, true);
- bcma_core_pci_up(dev->dev->bdev->bus);
+ bcma_host_pci_up(dev->dev->bdev->bus);
break;
#endif
#ifdef CPTCFG_B43_SSB
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4669,7 +4669,7 @@ static int brcms_b_attach(struct brcms_c
brcms_c_coredisable(wlc_hw);
/* Match driver "down" state */
- bcma_core_pci_down(wlc_hw->d11core->bus);
+ bcma_host_pci_down(wlc_hw->d11core->bus);
/* turn off pll and xtal to match driver "down" state */
brcms_b_xtal(wlc_hw, OFF);
@@ -4960,7 +4960,7 @@ static int brcms_b_up_prep(struct brcms_
* Configure pci/pcmcia here instead of in brcms_c_attach()
* to allow mfg hotswap: down, hotswap (chip power cycle), up.
*/
- bcma_core_pci_irq_ctl(&wlc_hw->d11core->bus->drv_pci[0], wlc_hw->d11core,
+ bcma_core_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core,
true);
/*
@@ -4970,12 +4970,12 @@ static int brcms_b_up_prep(struct brcms_
*/
if (brcms_b_radio_read_hwdisabled(wlc_hw)) {
/* put SB PCI in down state again */
- bcma_core_pci_down(wlc_hw->d11core->bus);
+ bcma_host_pci_down(wlc_hw->d11core->bus);
brcms_b_xtal(wlc_hw, OFF);
return -ENOMEDIUM;
}
- bcma_core_pci_up(wlc_hw->d11core->bus);
+ bcma_host_pci_up(wlc_hw->d11core->bus);
/* reset the d11 core */
brcms_b_corereset(wlc_hw, BRCMS_USE_COREFLAGS);
@@ -5172,7 +5172,7 @@ static int brcms_b_down_finish(struct br
/* turn off primary xtal and pll */
if (!wlc_hw->noreset) {
- bcma_core_pci_down(wlc_hw->d11core->bus);
+ bcma_host_pci_down(wlc_hw->d11core->bus);
brcms_b_xtal(wlc_hw, OFF);
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,347 +0,0 @@
--- a/net/mac80211/Kconfig
+++ b/net/mac80211/Kconfig
@@ -5,7 +5,6 @@ config MAC80211
depends on CRYPTO
depends on CRYPTO_ARC4
depends on CRYPTO_AES
- select BACKPORT_CRYPTO_CCM
depends on CRC32
select BACKPORT_AVERAGE
---help---
--- a/net/mac80211/aes_ccm.c
+++ b/net/mac80211/aes_ccm.c
@@ -2,8 +2,6 @@
* Copyright 2003-2004, Instant802 Networks, Inc.
* Copyright 2005-2006, Devicescape Software, Inc.
*
- * Rewrite: Copyright (C) 2013 Linaro Ltd <ard.biesheuvel@linaro.org>
- *
* 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.
@@ -19,76 +17,134 @@
#include "key.h"
#include "aes_ccm.h"
-void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic)
+static void aes_ccm_prepare(struct crypto_cipher *tfm, u8 *scratch, u8 *a)
+{
+ int i;
+ u8 *b_0, *aad, *b, *s_0;
+
+ b_0 = scratch + 3 * AES_BLOCK_SIZE;
+ aad = scratch + 4 * AES_BLOCK_SIZE;
+ b = scratch;
+ s_0 = scratch + AES_BLOCK_SIZE;
+
+ crypto_cipher_encrypt_one(tfm, b, b_0);
+
+ /* Extra Authenticate-only data (always two AES blocks) */
+ for (i = 0; i < AES_BLOCK_SIZE; i++)
+ aad[i] ^= b[i];
+ crypto_cipher_encrypt_one(tfm, b, aad);
+
+ aad += AES_BLOCK_SIZE;
+
+ for (i = 0; i < AES_BLOCK_SIZE; i++)
+ aad[i] ^= b[i];
+ crypto_cipher_encrypt_one(tfm, a, aad);
+
+ /* Mask out bits from auth-only-b_0 */
+ b_0[0] &= 0x07;
+
+ /* S_0 is used to encrypt T (= MIC) */
+ b_0[14] = 0;
+ b_0[15] = 0;
+ crypto_cipher_encrypt_one(tfm, s_0, b_0);
+}
+
+
+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
+ u8 *data, size_t data_len,
+ u8 *cdata, u8 *mic)
{
- struct scatterlist assoc, pt, ct[2];
+ int i, j, last_len, num_blocks;
+ u8 *pos, *cpos, *b, *s_0, *e, *b_0;
- char aead_req_data[sizeof(struct aead_request) +
- crypto_aead_reqsize(tfm)]
- __aligned(__alignof__(struct aead_request));
- struct aead_request *aead_req = (void *) aead_req_data;
-
- memset(aead_req, 0, sizeof(aead_req_data));
-
- sg_init_one(&pt, data, data_len);
- sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
- sg_init_table(ct, 2);
- sg_set_buf(&ct[0], data, data_len);
- sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
-
- aead_request_set_tfm(aead_req, tfm);
- aead_request_set_assoc(aead_req, &assoc, assoc.length);
- aead_request_set_crypt(aead_req, &pt, ct, data_len, b_0);
+ b = scratch;
+ s_0 = scratch + AES_BLOCK_SIZE;
+ e = scratch + 2 * AES_BLOCK_SIZE;
+ b_0 = scratch + 3 * AES_BLOCK_SIZE;
+
+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
+ last_len = data_len % AES_BLOCK_SIZE;
+ aes_ccm_prepare(tfm, scratch, b);
+
+ /* Process payload blocks */
+ pos = data;
+ cpos = cdata;
+ for (j = 1; j <= num_blocks; j++) {
+ int blen = (j == num_blocks && last_len) ?
+ last_len : AES_BLOCK_SIZE;
+
+ /* Authentication followed by encryption */
+ for (i = 0; i < blen; i++)
+ b[i] ^= pos[i];
+ crypto_cipher_encrypt_one(tfm, b, b);
+
+ b_0[14] = (j >> 8) & 0xff;
+ b_0[15] = j & 0xff;
+ crypto_cipher_encrypt_one(tfm, e, b_0);
+ for (i = 0; i < blen; i++)
+ *cpos++ = *pos++ ^ e[i];
+ }
- crypto_aead_encrypt(aead_req);
+ for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++)
+ mic[i] = b[i] ^ s_0[i];
}
-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic)
+
+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
+ u8 *cdata, size_t data_len, u8 *mic, u8 *data)
{
- struct scatterlist assoc, pt, ct[2];
- char aead_req_data[sizeof(struct aead_request) +
- crypto_aead_reqsize(tfm)]
- __aligned(__alignof__(struct aead_request));
- struct aead_request *aead_req = (void *) aead_req_data;
-
- memset(aead_req, 0, sizeof(aead_req_data));
-
- sg_init_one(&pt, data, data_len);
- sg_init_one(&assoc, &aad[2], be16_to_cpup((__be16 *)aad));
- sg_init_table(ct, 2);
- sg_set_buf(&ct[0], data, data_len);
- sg_set_buf(&ct[1], mic, IEEE80211_CCMP_MIC_LEN);
-
- aead_request_set_tfm(aead_req, tfm);
- aead_request_set_assoc(aead_req, &assoc, assoc.length);
- aead_request_set_crypt(aead_req, ct, &pt,
- data_len + IEEE80211_CCMP_MIC_LEN, b_0);
+ int i, j, last_len, num_blocks;
+ u8 *pos, *cpos, *b, *s_0, *a, *b_0;
+
+ b = scratch;
+ s_0 = scratch + AES_BLOCK_SIZE;
+ a = scratch + 2 * AES_BLOCK_SIZE;
+ b_0 = scratch + 3 * AES_BLOCK_SIZE;
+
+ num_blocks = DIV_ROUND_UP(data_len, AES_BLOCK_SIZE);
+ last_len = data_len % AES_BLOCK_SIZE;
+ aes_ccm_prepare(tfm, scratch, a);
+
+ /* Process payload blocks */
+ cpos = cdata;
+ pos = data;
+ for (j = 1; j <= num_blocks; j++) {
+ int blen = (j == num_blocks && last_len) ?
+ last_len : AES_BLOCK_SIZE;
+
+ /* Decryption followed by authentication */
+ b_0[14] = (j >> 8) & 0xff;
+ b_0[15] = j & 0xff;
+ crypto_cipher_encrypt_one(tfm, b, b_0);
+ for (i = 0; i < blen; i++) {
+ *pos = *cpos++ ^ b[i];
+ a[i] ^= *pos++;
+ }
+ crypto_cipher_encrypt_one(tfm, a, a);
+ }
+
+ for (i = 0; i < IEEE80211_CCMP_MIC_LEN; i++) {
+ if ((mic[i] ^ s_0[i]) != a[i])
+ return -1;
+ }
- return crypto_aead_decrypt(aead_req);
+ return 0;
}
-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[])
+
+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[])
{
- struct crypto_aead *tfm;
- int err;
+ struct crypto_cipher *tfm;
- tfm = crypto_alloc_aead("ccm(aes)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(tfm))
- return tfm;
-
- err = crypto_aead_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
- if (!err)
- err = crypto_aead_setauthsize(tfm, IEEE80211_CCMP_MIC_LEN);
- if (!err)
- return tfm;
+ tfm = crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
+ if (!IS_ERR(tfm))
+ crypto_cipher_setkey(tfm, key, WLAN_KEY_LEN_CCMP);
- crypto_free_aead(tfm);
- return ERR_PTR(err);
+ return tfm;
}
-void ieee80211_aes_key_free(struct crypto_aead *tfm)
+
+void ieee80211_aes_key_free(struct crypto_cipher *tfm)
{
- crypto_free_aead(tfm);
+ crypto_free_cipher(tfm);
}
--- a/net/mac80211/aes_ccm.h
+++ b/net/mac80211/aes_ccm.h
@@ -12,11 +12,13 @@
#include <linux/crypto.h>
-struct crypto_aead *ieee80211_aes_key_setup_encrypt(const u8 key[]);
-void ieee80211_aes_ccm_encrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic);
-int ieee80211_aes_ccm_decrypt(struct crypto_aead *tfm, u8 *b_0, u8 *aad,
- u8 *data, size_t data_len, u8 *mic);
-void ieee80211_aes_key_free(struct crypto_aead *tfm);
+struct crypto_cipher *ieee80211_aes_key_setup_encrypt(const u8 key[]);
+void ieee80211_aes_ccm_encrypt(struct crypto_cipher *tfm, u8 *scratch,
+ u8 *data, size_t data_len,
+ u8 *cdata, u8 *mic);
+int ieee80211_aes_ccm_decrypt(struct crypto_cipher *tfm, u8 *scratch,
+ u8 *cdata, size_t data_len,
+ u8 *mic, u8 *data);
+void ieee80211_aes_key_free(struct crypto_cipher *tfm);
#endif /* AES_CCM_H */
--- a/net/mac80211/key.h
+++ b/net/mac80211/key.h
@@ -84,7 +84,7 @@ struct ieee80211_key {
* Management frames.
*/
u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN];
- struct crypto_aead *tfm;
+ struct crypto_cipher *tfm;
u32 replays; /* dot11RSNAStatsCCMPReplays */
} ccmp;
struct {
--- a/net/mac80211/wpa.c
+++ b/net/mac80211/wpa.c
@@ -302,15 +302,22 @@ ieee80211_crypto_tkip_decrypt(struct iee
}
-static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *b_0, u8 *aad)
+static void ccmp_special_blocks(struct sk_buff *skb, u8 *pn, u8 *scratch,
+ int encrypted)
{
__le16 mask_fc;
int a4_included, mgmt;
u8 qos_tid;
- u16 len_a;
+ u8 *b_0, *aad;
+ u16 data_len, len_a;
unsigned int hdrlen;
struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+ memset(scratch, 0, 6 * AES_BLOCK_SIZE);
+
+ b_0 = scratch + 3 * AES_BLOCK_SIZE;
+ aad = scratch + 4 * AES_BLOCK_SIZE;
+
/*
* Mask FC: zero subtype b4 b5 b6 (if not mgmt)
* Retry, PwrMgt, MoreData; set Protected
@@ -332,21 +339,20 @@ static void ccmp_special_blocks(struct s
else
qos_tid = 0;
- /* In CCM, the initial vectors (IV) used for CTR mode encryption and CBC
- * mode authentication are not allowed to collide, yet both are derived
- * from this vector b_0. We only set L := 1 here to indicate that the
- * data size can be represented in (L+1) bytes. The CCM layer will take
- * care of storing the data length in the top (L+1) bytes and setting
- * and clearing the other bits as is required to derive the two IVs.
- */
- b_0[0] = 0x1;
+ data_len = skb->len - hdrlen - IEEE80211_CCMP_HDR_LEN;
+ if (encrypted)
+ data_len -= IEEE80211_CCMP_MIC_LEN;
+ /* First block, b_0 */
+ b_0[0] = 0x59; /* flags: Adata: 1, M: 011, L: 001 */
/* Nonce: Nonce Flags | A2 | PN
* Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7)
*/
b_0[1] = qos_tid | (mgmt << 4);
memcpy(&b_0[2], hdr->addr2, ETH_ALEN);
memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN);
+ /* l(m) */
+ put_unaligned_be16(data_len, &b_0[14]);
/* AAD (extra authenticate-only data) / masked 802.11 header
* FC | A1 | A2 | A3 | SC | [A4] | [QC] */
@@ -402,8 +408,7 @@ static int ccmp_encrypt_skb(struct ieee8
u8 *pos;
u8 pn[6];
u64 pn64;
- u8 aad[2 * AES_BLOCK_SIZE];
- u8 b_0[AES_BLOCK_SIZE];
+ u8 scratch[6 * AES_BLOCK_SIZE];
if (info->control.hw_key &&
!(info->control.hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) &&
@@ -457,9 +462,9 @@ static int ccmp_encrypt_skb(struct ieee8
return 0;
pos += IEEE80211_CCMP_HDR_LEN;
- ccmp_special_blocks(skb, pn, b_0, aad);
- ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, b_0, aad, pos, len,
- skb_put(skb, IEEE80211_CCMP_MIC_LEN));
+ ccmp_special_blocks(skb, pn, scratch, 0);
+ ieee80211_aes_ccm_encrypt(key->u.ccmp.tfm, scratch, pos, len,
+ pos, skb_put(skb, IEEE80211_CCMP_MIC_LEN));
return 0;
}
@@ -522,16 +527,16 @@ ieee80211_crypto_ccmp_decrypt(struct iee
}
if (!(status->flag & RX_FLAG_DECRYPTED)) {
- u8 aad[2 * AES_BLOCK_SIZE];
- u8 b_0[AES_BLOCK_SIZE];
+ u8 scratch[6 * AES_BLOCK_SIZE];
/* hardware didn't decrypt/verify MIC */
- ccmp_special_blocks(skb, pn, b_0, aad);
+ ccmp_special_blocks(skb, pn, scratch, 1);
if (ieee80211_aes_ccm_decrypt(
- key->u.ccmp.tfm, b_0, aad,
+ key->u.ccmp.tfm, scratch,
skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN,
data_len,
- skb->data + skb->len - IEEE80211_CCMP_MIC_LEN))
+ skb->data + skb->len - IEEE80211_CCMP_MIC_LEN,
+ skb->data + hdrlen + IEEE80211_CCMP_HDR_LEN))
return RX_DROP_UNUSABLE;
}

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
@@ -848,7 +848,6 @@ static int ieee80211_stop_ap(struct wiph
@@ -856,7 +856,6 @@ static int ieee80211_stop_ap(struct wiph
sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF;
__sta_info_flush(sdata, true);

View file

@ -18,9 +18,9 @@
static int ieee80211_ifa6_changed(struct notifier_block *nb,
unsigned long data, void *arg)
{
@@ -1044,14 +1044,14 @@ int ieee80211_register_hw(struct ieee802
@@ -1057,14 +1057,14 @@ int ieee80211_register_hw(struct ieee802
if (result)
goto fail_pm_qos;
}
-#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)
@@ -1060,13 +1060,13 @@ int ieee80211_register_hw(struct ieee802
@@ -1073,13 +1073,13 @@ int ieee80211_register_hw(struct ieee802
return 0;
@ -52,7 +52,7 @@
fail_ifa:
pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
&local->network_latency_notifier);
@@ -1111,10 +1111,10 @@ void ieee80211_unregister_hw(struct ieee
@@ -1124,10 +1124,10 @@ void ieee80211_unregister_hw(struct ieee
pm_qos_remove_notifier(PM_QOS_NETWORK_LATENCY,
&local->network_latency_notifier);

View file

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

View file

@ -1,395 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 27 Sep 2014 15:57:09 +0200
Subject: [PATCH] Revert "ath5k: Remove AHB bus support"
This reverts commit 093ec3c5337434f40d77c1af06c139da3e5ba6dc.
---
create mode 100644 drivers/net/wireless/ath/ath5k/ahb.c
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -1,13 +1,14 @@
config ATH5K
tristate "Atheros 5xxx wireless cards support"
depends on m
- depends on PCI && MAC80211
+ depends on (PCI || ATHEROS_AR231X) && MAC80211
select ATH_COMMON
select MAC80211_LEDS
select BACKPORT_LEDS_CLASS
select BACKPORT_NEW_LEDS
select BACKPORT_AVERAGE
- select ATH5K_PCI
+ select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
+ select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
---help---
This module adds support for wireless adapters based on
Atheros 5xxx chipset.
@@ -52,9 +53,16 @@ config ATH5K_TRACER
If unsure, say N.
+config ATH5K_AHB
+ bool "Atheros 5xxx AHB bus support"
+ depends on (ATHEROS_AR231X && !PCI)
+ ---help---
+ This adds support for WiSoC type chipsets of the 5xxx Atheros
+ family.
+
config ATH5K_PCI
bool "Atheros 5xxx PCI bus support"
- depends on PCI
+ depends on (!ATHEROS_AR231X && PCI)
---help---
This adds support for PCI type chipsets of the 5xxx Atheros
family.
--- a/drivers/net/wireless/ath/ath5k/Makefile
+++ b/drivers/net/wireless/ath/ath5k/Makefile
@@ -17,5 +17,6 @@ ath5k-y += ani.o
ath5k-y += sysfs.o
ath5k-y += mac80211-ops.o
ath5k-$(CPTCFG_ATH5K_DEBUG) += debug.o
+ath5k-$(CPTCFG_ATH5K_AHB) += ahb.o
ath5k-$(CPTCFG_ATH5K_PCI) += pci.o
obj-$(CPTCFG_ATH5K) += ath5k.o
--- /dev/null
+++ b/drivers/net/wireless/ath/ath5k/ahb.c
@@ -0,0 +1,234 @@
+/*
+ * Copyright (c) 2008-2009 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <linux/nl80211.h>
+#include <linux/platform_device.h>
+#include <linux/etherdevice.h>
+#include <linux/export.h>
+#include <ar231x_platform.h>
+#include "ath5k.h"
+#include "debug.h"
+#include "base.h"
+#include "reg.h"
+
+/* return bus cachesize in 4B word units */
+static void ath5k_ahb_read_cachesize(struct ath_common *common, int *csz)
+{
+ *csz = L1_CACHE_BYTES >> 2;
+}
+
+static bool
+ath5k_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
+{
+ struct ath5k_hw *ah = common->priv;
+ struct platform_device *pdev = to_platform_device(ah->dev);
+ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
+ u16 *eeprom, *eeprom_end;
+
+ eeprom = (u16 *) bcfg->radio;
+ eeprom_end = ((void *) bcfg->config) + BOARD_CONFIG_BUFSZ;
+
+ eeprom += off;
+ if (eeprom > eeprom_end)
+ return false;
+
+ *data = *eeprom;
+ return true;
+}
+
+int ath5k_hw_read_srev(struct ath5k_hw *ah)
+{
+ struct platform_device *pdev = to_platform_device(ah->dev);
+ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
+ ah->ah_mac_srev = bcfg->devid;
+ return 0;
+}
+
+static int ath5k_ahb_eeprom_read_mac(struct ath5k_hw *ah, u8 *mac)
+{
+ struct platform_device *pdev = to_platform_device(ah->dev);
+ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
+ u8 *cfg_mac;
+
+ if (to_platform_device(ah->dev)->id == 0)
+ cfg_mac = bcfg->config->wlan0_mac;
+ else
+ cfg_mac = bcfg->config->wlan1_mac;
+
+ memcpy(mac, cfg_mac, ETH_ALEN);
+ return 0;
+}
+
+static const struct ath_bus_ops ath_ahb_bus_ops = {
+ .ath_bus_type = ATH_AHB,
+ .read_cachesize = ath5k_ahb_read_cachesize,
+ .eeprom_read = ath5k_ahb_eeprom_read,
+ .eeprom_read_mac = ath5k_ahb_eeprom_read_mac,
+};
+
+/*Initialization*/
+static int ath_ahb_probe(struct platform_device *pdev)
+{
+ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
+ struct ath5k_hw *ah;
+ struct ieee80211_hw *hw;
+ struct resource *res;
+ void __iomem *mem;
+ int irq;
+ int ret = 0;
+ u32 reg;
+
+ if (!dev_get_platdata(&pdev->dev)) {
+ dev_err(&pdev->dev, "no platform data specified\n");
+ ret = -EINVAL;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no memory resource found\n");
+ ret = -ENXIO;
+ goto err_out;
+ }
+
+ mem = ioremap_nocache(res->start, resource_size(res));
+ if (mem == NULL) {
+ dev_err(&pdev->dev, "ioremap failed\n");
+ ret = -ENOMEM;
+ goto err_out;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (res == NULL) {
+ dev_err(&pdev->dev, "no IRQ resource found\n");
+ ret = -ENXIO;
+ goto err_iounmap;
+ }
+
+ irq = res->start;
+
+ hw = ieee80211_alloc_hw(sizeof(struct ath5k_hw), &ath5k_hw_ops);
+ if (hw == NULL) {
+ dev_err(&pdev->dev, "no memory for ieee80211_hw\n");
+ ret = -ENOMEM;
+ goto err_iounmap;
+ }
+
+ ah = hw->priv;
+ ah->hw = hw;
+ ah->dev = &pdev->dev;
+ ah->iobase = mem;
+ ah->irq = irq;
+ ah->devid = bcfg->devid;
+
+ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
+ /* Enable WMAC AHB arbitration */
+ reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+ reg |= AR5K_AR2315_AHB_ARB_CTL_WLAN;
+ iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+
+ /* Enable global WMAC swapping */
+ reg = ioread32((void __iomem *) AR5K_AR2315_BYTESWAP);
+ reg |= AR5K_AR2315_BYTESWAP_WMAC;
+ iowrite32(reg, (void __iomem *) AR5K_AR2315_BYTESWAP);
+ } else {
+ /* Enable WMAC DMA access (assuming 5312 or 231x*/
+ /* TODO: check other platforms */
+ reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
+ if (to_platform_device(ah->dev)->id == 0)
+ reg |= AR5K_AR5312_ENABLE_WLAN0;
+ else
+ reg |= AR5K_AR5312_ENABLE_WLAN1;
+ iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+
+ /*
+ * On a dual-band AR5312, the multiband radio is only
+ * used as pass-through. Disable 2 GHz support in the
+ * driver for it
+ */
+ if (to_platform_device(ah->dev)->id == 0 &&
+ (bcfg->config->flags & (BD_WLAN0 | BD_WLAN1)) ==
+ (BD_WLAN1 | BD_WLAN0))
+ ah->ah_capabilities.cap_needs_2GHz_ovr = true;
+ else
+ ah->ah_capabilities.cap_needs_2GHz_ovr = false;
+ }
+
+ ret = ath5k_init_ah(ah, &ath_ahb_bus_ops);
+ if (ret != 0) {
+ dev_err(&pdev->dev, "failed to attach device, err=%d\n", ret);
+ ret = -ENODEV;
+ goto err_free_hw;
+ }
+
+ platform_set_drvdata(pdev, hw);
+
+ return 0;
+
+ err_free_hw:
+ ieee80211_free_hw(hw);
+ err_iounmap:
+ iounmap(mem);
+ err_out:
+ return ret;
+}
+
+static int ath_ahb_remove(struct platform_device *pdev)
+{
+ struct ar231x_board_config *bcfg = dev_get_platdata(&pdev->dev);
+ struct ieee80211_hw *hw = platform_get_drvdata(pdev);
+ struct ath5k_hw *ah;
+ u32 reg;
+
+ if (!hw)
+ return 0;
+
+ ah = hw->priv;
+
+ if (bcfg->devid >= AR5K_SREV_AR2315_R6) {
+ /* Disable WMAC AHB arbitration */
+ reg = ioread32((void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+ reg &= ~AR5K_AR2315_AHB_ARB_CTL_WLAN;
+ iowrite32(reg, (void __iomem *) AR5K_AR2315_AHB_ARB_CTL);
+ } else {
+ /*Stop DMA access */
+ reg = ioread32((void __iomem *) AR5K_AR5312_ENABLE);
+ if (to_platform_device(ah->dev)->id == 0)
+ reg &= ~AR5K_AR5312_ENABLE_WLAN0;
+ else
+ reg &= ~AR5K_AR5312_ENABLE_WLAN1;
+ iowrite32(reg, (void __iomem *) AR5K_AR5312_ENABLE);
+ }
+
+ ath5k_deinit_ah(ah);
+ iounmap(ah->iobase);
+ ieee80211_free_hw(hw);
+
+ return 0;
+}
+
+static struct platform_driver ath_ahb_driver = {
+ .probe = ath_ahb_probe,
+ .remove = ath_ahb_remove,
+ .driver = {
+ .name = "ar231x-wmac",
+ .owner = THIS_MODULE,
+ },
+};
+
+module_platform_driver(ath_ahb_driver);
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1647,6 +1647,32 @@ static inline struct ath_regulatory *ath
return &(ath5k_hw_common(ah)->regulatory);
}
+#ifdef CONFIG_ATHEROS_AR231X
+#define AR5K_AR2315_PCI_BASE ((void __iomem *)0xb0100000)
+
+static inline void __iomem *ath5k_ahb_reg(struct ath5k_hw *ah, u16 reg)
+{
+ /* On AR2315 and AR2317 the PCI clock domain registers
+ * are outside of the WMAC register space */
+ if (unlikely((reg >= 0x4000) && (reg < 0x5000) &&
+ (ah->ah_mac_srev >= AR5K_SREV_AR2315_R6)))
+ return AR5K_AR2315_PCI_BASE + reg;
+
+ return ah->iobase + reg;
+}
+
+static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
+{
+ return ioread32(ath5k_ahb_reg(ah, reg));
+}
+
+static inline void ath5k_hw_reg_write(struct ath5k_hw *ah, u32 val, u16 reg)
+{
+ iowrite32(val, ath5k_ahb_reg(ah, reg));
+}
+
+#else
+
static inline u32 ath5k_hw_reg_read(struct ath5k_hw *ah, u16 reg)
{
return ioread32(ah->iobase + reg);
@@ -1657,6 +1683,8 @@ static inline void ath5k_hw_reg_write(st
iowrite32(val, ah->iobase + reg);
}
+#endif
+
static inline enum ath_bus_type ath5k_get_bus_type(struct ath5k_hw *ah)
{
return ath5k_hw_common(ah)->bus_ops->ath_bus_type;
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -99,6 +99,15 @@ static int ath5k_reset(struct ath5k_hw *
/* Known SREVs */
static const struct ath5k_srev_name srev_names[] = {
+#ifdef CONFIG_ATHEROS_AR231X
+ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R2 },
+ { "5312", AR5K_VERSION_MAC, AR5K_SREV_AR5312_R7 },
+ { "2313", AR5K_VERSION_MAC, AR5K_SREV_AR2313_R8 },
+ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R6 },
+ { "2315", AR5K_VERSION_MAC, AR5K_SREV_AR2315_R7 },
+ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R1 },
+ { "2317", AR5K_VERSION_MAC, AR5K_SREV_AR2317_R2 },
+#else
{ "5210", AR5K_VERSION_MAC, AR5K_SREV_AR5210 },
{ "5311", AR5K_VERSION_MAC, AR5K_SREV_AR5311 },
{ "5311A", AR5K_VERSION_MAC, AR5K_SREV_AR5311A },
@@ -117,6 +126,7 @@ static const struct ath5k_srev_name srev
{ "5418", AR5K_VERSION_MAC, AR5K_SREV_AR5418 },
{ "2425", AR5K_VERSION_MAC, AR5K_SREV_AR2425 },
{ "2417", AR5K_VERSION_MAC, AR5K_SREV_AR2417 },
+#endif
{ "xxxxx", AR5K_VERSION_MAC, AR5K_SREV_UNKNOWN },
{ "5110", AR5K_VERSION_RAD, AR5K_SREV_RAD_5110 },
{ "5111", AR5K_VERSION_RAD, AR5K_SREV_RAD_5111 },
@@ -132,6 +142,10 @@ static const struct ath5k_srev_name srev
{ "5413", AR5K_VERSION_RAD, AR5K_SREV_RAD_5413 },
{ "5424", AR5K_VERSION_RAD, AR5K_SREV_RAD_5424 },
{ "5133", AR5K_VERSION_RAD, AR5K_SREV_RAD_5133 },
+#ifdef CONFIG_ATHEROS_AR231X
+ { "2316", AR5K_VERSION_RAD, AR5K_SREV_RAD_2316 },
+ { "2317", AR5K_VERSION_RAD, AR5K_SREV_RAD_2317 },
+#endif
{ "xxxxx", AR5K_VERSION_RAD, AR5K_SREV_UNKNOWN },
};
--- a/drivers/net/wireless/ath/ath5k/led.c
+++ b/drivers/net/wireless/ath/ath5k/led.c
@@ -163,14 +163,20 @@ int ath5k_init_leds(struct ath5k_hw *ah)
{
int ret = 0;
struct ieee80211_hw *hw = ah->hw;
+#ifndef CONFIG_ATHEROS_AR231X
struct pci_dev *pdev = ah->pdev;
+#endif
char name[ATH5K_LED_MAX_NAME_LEN + 1];
const struct pci_device_id *match;
if (!ah->pdev)
return 0;
+#ifdef CONFIG_ATHEROS_AR231X
+ match = NULL;
+#else
match = pci_match_id(&ath5k_led_devices[0], pdev);
+#endif
if (match) {
__set_bit(ATH_STAT_LEDSOFT, ah->status);
ah->led_pin = ATH_PIN(match->driver_data);

View file

@ -19,7 +19,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -1192,6 +1192,8 @@ struct ieee80211_vif {
@@ -1257,6 +1257,8 @@ struct ieee80211_vif {
u8 cab_queue;
u8 hw_queue[IEEE80211_NUM_ACS];
@ -28,16 +28,16 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
struct ieee80211_chanctx_conf __rcu *chanctx_conf;
u32 driver_flags;
@@ -1448,6 +1450,8 @@ struct ieee80211_sta {
bool tdls;
@@ -1519,6 +1521,8 @@ struct ieee80211_sta {
bool tdls_initiator;
bool mfp;
+ struct ieee80211_txq *txq[IEEE80211_NUM_TIDS];
+
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
@@ -1476,6 +1480,27 @@ struct ieee80211_tx_control {
@@ -1547,6 +1551,27 @@ struct ieee80211_tx_control {
};
/**
@ -65,7 +65,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
* enum ieee80211_hw_flags - hardware flags
*
* These flags are used to indicate hardware capabilities to
@@ -1698,6 +1723,8 @@ enum ieee80211_hw_flags {
@@ -1770,6 +1795,8 @@ enum ieee80211_hw_flags {
* within &struct ieee80211_sta.
* @chanctx_data_size: size (in bytes) of the drv_priv data area
* within &struct ieee80211_chanctx_conf.
@ -74,7 +74,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
*
* @max_rates: maximum number of alternate rate retry stages the hw
* can handle.
@@ -1746,6 +1773,9 @@ enum ieee80211_hw_flags {
@@ -1818,6 +1845,9 @@ enum ieee80211_hw_flags {
* @n_cipher_schemes: a size of an array of cipher schemes definitions.
* @cipher_schemes: a pointer to an array of cipher scheme definitions
* supported by HW.
@ -84,7 +84,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
*/
struct ieee80211_hw {
struct ieee80211_conf conf;
@@ -1758,6 +1788,7 @@ struct ieee80211_hw {
@@ -1830,6 +1860,7 @@ struct ieee80211_hw {
int vif_data_size;
int sta_data_size;
int chanctx_data_size;
@ -92,7 +92,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
u16 queues;
u16 max_listen_interval;
s8 max_signal;
@@ -1774,6 +1805,7 @@ struct ieee80211_hw {
@@ -1846,6 +1877,7 @@ struct ieee80211_hw {
u8 uapsd_max_sp_len;
u8 n_cipher_schemes;
const struct ieee80211_cipher_scheme *cipher_schemes;
@ -100,26 +100,26 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
};
/**
@@ -2881,6 +2913,8 @@ enum ieee80211_reconfig_type {
*
* @get_txpower: get current maximum tx power (in dBm) based on configuration
* and hardware limits.
@@ -3007,6 +3039,8 @@ enum ieee80211_reconfig_type {
* response template is provided, together with the location of the
* switch-timing IE within the template. The skb can only be used within
* the function call.
+ *
+ * @wake_tx_queue: Called when new packets have been added to the queue.
*/
struct ieee80211_ops {
void (*tx)(struct ieee80211_hw *hw,
@@ -3095,6 +3129,9 @@ struct ieee80211_ops {
u32 (*get_expected_throughput)(struct ieee80211_sta *sta);
int (*get_txpower)(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
int *dbm);
@@ -3238,6 +3272,9 @@ struct ieee80211_ops {
void (*tdls_recv_channel_switch)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif,
struct ieee80211_tdls_ch_sw_params *params);
+
+ void (*wake_tx_queue)(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq);
};
/**
@@ -5038,4 +5075,17 @@ void ieee80211_tdls_oper_request(struct
@@ -5249,4 +5286,17 @@ void ieee80211_unreserve_tid(struct ieee
*/
size_t ieee80211_ie_split(const u8 *ies, size_t ielen,
const u8 *ids, int n_ids, size_t offset);
@ -130,17 +130,17 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ * @hw: pointer as obtained from ieee80211_alloc_hw()
+ * @txq: pointer obtained from .add_tx_queue() call
+ *
+ * Returns 0 if successful, -EAGAIN if no frame was available.
+ * Returns the sjb if successful, ERR_PTR(-EAGAIN) if no frame was available.
+ */
+int ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *txq,
+ struct sk_buff **skb);
+struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq);
+
+
#endif /* MAC80211_H */
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -1311,4 +1311,21 @@ static inline int drv_get_txpower(struct
return ret;
@@ -1367,4 +1367,21 @@ drv_tdls_recv_channel_switch(struct ieee
trace_drv_return_void(local);
}
+static inline void drv_wake_tx_queue(struct ieee80211_local *local,
@ -163,7 +163,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
#endif /* __MAC80211_DRIVER_OPS */
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -793,6 +793,13 @@ struct mac80211_qos_map {
@@ -809,6 +809,13 @@ struct mac80211_qos_map {
struct rcu_head rcu_head;
};
@ -177,30 +177,30 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
struct ieee80211_sub_if_data {
struct list_head list;
@@ -837,6 +844,8 @@ struct ieee80211_sub_if_data {
@@ -853,6 +860,7 @@ struct ieee80211_sub_if_data {
bool control_port_no_encrypt;
int encrypt_headroom;
+ struct txq_info *txq;
+ atomic_t txq_len[IEEE80211_NUM_ACS];
+ atomic_t txqs_len[IEEE80211_NUM_ACS];
struct ieee80211_tx_queue_params tx_conf[IEEE80211_NUM_ACS];
struct mac80211_qos_map __rcu *qos_map;
@@ -1868,6 +1877,11 @@ void ieee80211_add_pending_skbs(struct i
struct sk_buff_head *skbs);
void ieee80211_flush_queues(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata);
@@ -1905,6 +1913,12 @@ static inline bool ieee80211_can_run_wor
return true;
}
+void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
+ struct sta_info *sta,
+ struct txq_info *txq, int tid);
+void ieee80211_flush_tx_queue(struct ieee80211_local *local,
+ struct ieee80211_txq *txq);
+
void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata,
u16 transaction, u16 auth_alg, u16 status,
const u8 *extra, size_t extra_len, const u8 *bssid,
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -967,6 +967,9 @@ static void ieee80211_do_stop(struct iee
@@ -969,6 +969,9 @@ static void ieee80211_do_stop(struct iee
}
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
@ -210,23 +210,74 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
if (local->open_count == 0)
ieee80211_clear_tx_pending(local);
@@ -1773,6 +1776,13 @@ int ieee80211_if_add(struct ieee80211_lo
/* setup type-dependent data */
@@ -1773,6 +1776,15 @@ int ieee80211_if_add(struct ieee80211_lo
ieee80211_setup_sdata(sdata, type);
+ if (local->ops->wake_tx_queue) {
+ sdata->txq = kzalloc(sizeof(*sdata->txq) +
+ local->hw.txq_data_size, GFP_KERNEL);
+ if (sdata->txq)
+ ieee80211_init_tx_queue(sdata, NULL, sdata->txq, 0);
+ }
+
if (ndev) {
+ struct txq_info *txqi = NULL;
+
+ if (local->ops->wake_tx_queue) {
+ txqi = kzalloc(sizeof(*txqi) +
+ local->hw.txq_data_size, GFP_KERNEL);
+ if (txqi)
+ ieee80211_init_tx_queue(sdata, NULL, txqi, 0);
+ }
+
if (params) {
ndev->ieee80211_ptr->use_4addr = params->use_4addr;
if (type == NL80211_IFTYPE_STATION)
@@ -1785,6 +1797,7 @@ int ieee80211_if_add(struct ieee80211_lo
ret = register_netdevice(ndev);
if (ret) {
+ kfree(txqi);
free_netdev(ndev);
return ret;
}
@@ -1802,6 +1815,7 @@ int ieee80211_if_add(struct ieee80211_lo
void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
{
+ struct txq_info *txqi;
ASSERT_RTNL();
mutex_lock(&sdata->local->iflist_mtx);
@@ -1810,6 +1824,11 @@ void ieee80211_if_remove(struct ieee8021
synchronize_rcu();
+ if (sdata->vif.txq) {
+ txqi = container_of(sdata->vif.txq, struct txq_info, txq);
+ kfree(txqi);
+ }
+
if (sdata->dev) {
unregister_netdevice(sdata->dev);
} else {
@@ -1833,6 +1852,7 @@ void ieee80211_sdata_stop(struct ieee802
void ieee80211_remove_interfaces(struct ieee80211_local *local)
{
struct ieee80211_sub_if_data *sdata, *tmp;
+ struct txq_info *txqi;
LIST_HEAD(unreg_list);
LIST_HEAD(wdev_list);
@@ -1851,6 +1871,12 @@ void ieee80211_remove_interfaces(struct
list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
list_del(&sdata->list);
+ if (sdata->vif.txq) {
+ txqi = container_of(sdata->vif.txq, struct txq_info,
+ txq);
+ kfree(txqi);
+ }
+
if (sdata->dev)
unregister_netdevice_queue(sdata->dev, &unreg_list);
else
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -1004,6 +1004,9 @@ int ieee80211_register_hw(struct ieee802
@@ -1019,6 +1019,9 @@ int ieee80211_register_hw(struct ieee802
local->dynamic_ps_forced_timeout = -1;
@ -238,8 +289,8 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n",
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -119,6 +119,11 @@ static void __cleanup_single_sta(struct
sta_info_recalc_tim(sta);
@@ -118,6 +118,11 @@ static void __cleanup_single_sta(struct
atomic_dec(&ps->num_sta_ps);
}
+ if (sta->txq) {
@ -250,23 +301,21 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
local->total_ps_buffered -= skb_queue_len(&sta->ps_tx_buf[ac]);
ieee80211_purge_tx_queue(&local->hw, &sta->ps_tx_buf[ac]);
@@ -241,6 +246,8 @@ void sta_info_free(struct ieee80211_loca
kfree(sta->tx_lat);
}
@@ -234,6 +239,7 @@ void sta_info_free(struct ieee80211_loca
+ kfree(sta->txq);
+
sta_dbg(sta->sdata, "Destroyed STA %pM\n", sta->sta.addr);
+ kfree(sta->txq);
kfree(rcu_dereference_raw(sta->sta.rates));
@@ -294,12 +301,13 @@ struct sta_info *sta_info_alloc(struct i
kfree(sta);
}
@@ -285,11 +291,12 @@ struct sta_info *sta_info_alloc(struct i
const u8 *addr, gfp_t gfp)
{
struct ieee80211_local *local = sdata->local;
+ struct ieee80211_hw *hw = &local->hw;
struct sta_info *sta;
struct timespec uptime;
struct ieee80211_tx_latency_bin_ranges *tx_latency;
int i;
- sta = kzalloc(sizeof(*sta) + local->hw.sta_data_size, gfp);
@ -274,10 +323,13 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
if (!sta)
return NULL;
@@ -357,6 +365,20 @@ struct sta_info *sta_info_alloc(struct i
@@ -321,11 +328,23 @@ struct sta_info *sta_info_alloc(struct i
for (i = 0; i < ARRAY_SIZE(sta->chain_signal_avg); i++)
ewma_init(&sta->chain_signal_avg[i], 1024, 8);
- if (sta_prepare_rate_control(local, sta, gfp)) {
- kfree(sta);
- return NULL;
+ if (local->ops->wake_tx_queue) {
+ int size = sizeof(struct txq_info) +
+ ALIGN(hw->txq_data_size, sizeof(void *));
@ -290,12 +342,15 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ struct txq_info *txq = sta->txq + i * size;
+ ieee80211_init_tx_queue(sdata, sta, txq, i);
+ }
+ }
+
if (sta_prepare_rate_control(local, sta, gfp))
goto free;
}
@@ -380,7 +402,7 @@ struct sta_info *sta_info_alloc(struct i
+ if (sta_prepare_rate_control(local, sta, gfp))
+ goto free_txq;
+
for (i = 0; i < IEEE80211_NUM_TIDS; i++) {
/*
* timer_to_tid must be initialized with identity mapping
@@ -346,7 +365,7 @@ struct sta_info *sta_info_alloc(struct i
if (sdata->vif.type == NL80211_IFTYPE_AP ||
sdata->vif.type == NL80211_IFTYPE_AP_VLAN) {
struct ieee80211_supported_band *sband =
@ -304,19 +359,32 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
u8 smps = (sband->ht_cap.cap & IEEE80211_HT_CAP_SM_PS) >>
IEEE80211_HT_CAP_SM_PS_SHIFT;
/*
@@ -371,6 +390,12 @@ struct sta_info *sta_info_alloc(struct i
sta_dbg(sdata, "Allocated STA %pM\n", sta->sta.addr);
return sta;
+
+free_txq:
+ kfree(sta->txq);
+free:
+ kfree(sta);
+ return NULL;
}
static int sta_info_insert_check(struct sta_info *sta)
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -371,6 +371,7 @@ struct sta_info {
@@ -368,6 +368,7 @@ struct sta_info {
struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
unsigned long driver_buffered_tids;
+ void *txq;
+ struct txq_info *txq;
/* Updated from RX path only, no locking requirements */
unsigned long rx_packets;
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -2201,6 +2201,40 @@ TRACE_EVENT(drv_get_txpower,
@@ -2312,6 +2312,40 @@ TRACE_EVENT(drv_tdls_recv_channel_switch
)
);
@ -354,12 +422,12 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ )
+);
+
#ifdef CPTCFG_MAC80211_MESSAGE_TRACING
#undef TRACE_SYSTEM
#define TRACE_SYSTEM mac80211_msg
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1198,13 +1198,75 @@ ieee80211_tx_prepare(struct ieee80211_su
@@ -1201,13 +1201,76 @@ ieee80211_tx_prepare(struct ieee80211_su
return TX_CONTINUE;
}
@ -373,8 +441,8 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ struct ieee80211_tx_control control = {
+ .sta = pubsta
+ };
+ struct ieee80211_txq *pubtxq = NULL;
+ struct txq_info *txq;
+ struct ieee80211_txq *txq = NULL;
+ struct txq_info *txqi;
+ u8 ac;
+
+ if (ieee80211_is_mgmt(hdr->frame_control) ||
@ -383,22 +451,22 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+
+ if (pubsta) {
+ u8 tid = skb->priority & IEEE80211_QOS_CTL_TID_MASK;
+ pubtxq = pubsta->txq[tid];
+ txq = pubsta->txq[tid];
+ } else if (vif) {
+ pubtxq = vif->txq;
+ txq = vif->txq;
+ }
+
+ if (!pubtxq)
+ if (!txq)
+ goto tx_normal;
+
+ ac = pubtxq->ac;
+ txq = container_of(pubtxq, struct txq_info, txq);
+ atomic_inc(&sdata->txq_len[ac]);
+ if (atomic_read(&sdata->txq_len[ac]) >= local->hw.txq_ac_max_pending)
+ ac = txq->ac;
+ txqi = container_of(txq, struct txq_info, txq);
+ atomic_inc(&sdata->txqs_len[ac]);
+ if (atomic_read(&sdata->txqs_len[ac]) >= local->hw.txq_ac_max_pending)
+ netif_stop_subqueue(sdata->dev, ac);
+
+ skb_queue_tail(&txq->queue, skb);
+ drv_wake_tx_queue(local, txq);
+ skb_queue_tail(&txqi->queue, skb);
+ drv_wake_tx_queue(local, txqi);
+
+ return;
+
@ -406,23 +474,24 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
+ drv_tx(local, &control, skb);
+}
+
+int ieee80211_tx_dequeue(struct ieee80211_hw *hw, struct ieee80211_txq *pubtxq,
+ struct sk_buff **dest)
+struct sk_buff *ieee80211_tx_dequeue(struct ieee80211_hw *hw,
+ struct ieee80211_txq *txq)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(pubtxq->vif);
+ struct txq_info *txq = container_of(pubtxq, struct txq_info, txq);
+ u8 ac = pubtxq->ac;
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
+ struct txq_info *txqi = container_of(txq, struct txq_info, txq);
+ struct sk_buff *skb;
+ u8 ac = txq->ac;
+
+ *dest = skb_dequeue(&txq->queue);
+ if (!*dest)
+ return -EAGAIN;
+ skb = skb_dequeue(&txqi->queue);
+ if (!skb)
+ return ERR_PTR(-EAGAIN);
+
+ atomic_dec(&sdata->txq_len[ac]);
+ atomic_dec(&sdata->txqs_len[ac]);
+ if (__netif_subqueue_stopped(sdata->dev, ac))
+ ieee80211_propagate_queue_wake(local, sdata->vif.hw_queue[ac]);
+
+ return 0;
+ return skb;
+}
+EXPORT_SYMBOL(ieee80211_tx_dequeue);
+
@ -436,7 +505,7 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
struct sk_buff *skb, *tmp;
unsigned long flags;
@@ -1262,10 +1324,9 @@ static bool ieee80211_tx_frags(struct ie
@@ -1265,10 +1328,9 @@ static bool ieee80211_tx_frags(struct ie
spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags);
info->control.vif = vif;
@ -455,44 +524,47 @@ Signed-off-by: Felix Fietkau <nbd@openwrt.org>
int ac_queue = sdata->vif.hw_queue[ac];
+ if (local->ops->wake_tx_queue &&
+ (atomic_read(&sdata->txq_len[ac]) >
+ (atomic_read(&sdata->txqs_len[ac]) >
+ local->hw.txq_ac_max_pending))
+ continue;
+
if (ac_queue == queue ||
(sdata->vif.cab_queue == queue &&
local->queue_stop_reasons[ac_queue] == 0 &&
@@ -3182,3 +3187,33 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u
@@ -3307,3 +3312,36 @@ u8 *ieee80211_add_wmm_info_ie(u8 *buf, u
return buf;
}
+
+void ieee80211_init_tx_queue(struct ieee80211_sub_if_data *sdata,
+ struct sta_info *sta,
+ struct txq_info *txq, int tid)
+ struct txq_info *txqi, int tid)
+{
+ skb_queue_head_init(&txq->queue);
+ txq->txq.vif = &sdata->vif;
+ skb_queue_head_init(&txqi->queue);
+ txqi->txq.vif = &sdata->vif;
+
+ if (sta) {
+ txq->txq.sta = &sta->sta;
+ sta->sta.txq[tid] = &txq->txq;
+ txq->txq.ac = ieee802_1d_to_ac[tid & 7];
+ txqi->txq.sta = &sta->sta;
+ sta->sta.txq[tid] = &txqi->txq;
+ txqi->txq.ac = ieee802_1d_to_ac[tid & 7];
+ } else {
+ sdata->vif.txq = &txq->txq;
+ txq->txq.ac = IEEE80211_AC_BE;
+ sdata->vif.txq = &txqi->txq;
+ txqi->txq.ac = IEEE80211_AC_BE;
+ }
+}
+
+void ieee80211_flush_tx_queue(struct ieee80211_local *local,
+ struct ieee80211_txq *pubtxq)
+ struct ieee80211_txq *txq)
+{
+ struct txq_info *txq = container_of(pubtxq, struct txq_info, txq);
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(pubtxq->vif);
+ struct txq_info *txqi = container_of(txq, struct txq_info, txq);
+ struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->vif);
+ struct sk_buff *skb;
+ int n = 0;
+
+ while ((skb = skb_dequeue(&txq->queue)) != NULL) {
+ atomic_dec(&sdata->txq_len[pubtxq->ac]);
+ while ((skb = skb_dequeue(&txqi->queue)) != NULL) {
+ n++;
+ ieee80211_free_txskb(&local->hw, skb);
+ }
+
+ atomic_sub(n, &sdata->txqs_len[txq->ac]);
+}

View file

@ -1,37 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 27 Sep 2014 15:58:51 +0200
Subject: [PATCH] ath5k: fix AHB kconfig dependency
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath5k/Kconfig
+++ b/drivers/net/wireless/ath/ath5k/Kconfig
@@ -7,8 +7,8 @@ config ATH5K
select BACKPORT_LEDS_CLASS
select BACKPORT_NEW_LEDS
select BACKPORT_AVERAGE
- select ATH5K_AHB if (ATHEROS_AR231X && !PCI)
- select ATH5K_PCI if (!ATHEROS_AR231X && PCI)
+ select ATH5K_AHB if ATHEROS_AR231X
+ select ATH5K_PCI if !ATHEROS_AR231X
---help---
This module adds support for wireless adapters based on
Atheros 5xxx chipset.
@@ -55,14 +55,14 @@ config ATH5K_TRACER
config ATH5K_AHB
bool "Atheros 5xxx AHB bus support"
- depends on (ATHEROS_AR231X && !PCI)
+ depends on ATHEROS_AR231X
---help---
This adds support for WiSoC type chipsets of the 5xxx Atheros
family.
config ATH5K_PCI
bool "Atheros 5xxx PCI bus support"
- depends on (!ATHEROS_AR231X && PCI)
+ depends on !ATHEROS_AR231X
---help---
This adds support for PCI type chipsets of the 5xxx Atheros
family.

View file

@ -0,0 +1,125 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Wed, 11 Mar 2015 09:14:15 +0100
Subject: [PATCH] mac80211: lock rate control
Both minstrel (reported by Sven Eckelmann) and the iwlwifi rate
control aren't properly taking concurrency into account. It's
likely that the same is true for other rate control algorithms.
In the case of minstrel this manifests itself in crashes when an
update and other data access are run concurrently, for example
when the stations change bandwidth or similar. In iwlwifi, this
can cause firmware crashes.
Since fixing all rate control algorithms will be very difficult,
just provide locking for invocations. This protects the internal
data structures the algorithms maintain.
I've manipulated hostapd to test this, by having it change its
advertised bandwidth roughly ever 150ms. At the same time, I'm
running a flood ping between the client and the AP, which causes
this race of update vs. get_rate/status to easily happen on the
client. With this change, the system survives this test.
Reported-by: Sven Eckelmann <sven@open-mesh.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -683,7 +683,13 @@ void rate_control_get_rate(struct ieee80
if (sdata->local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
return;
- ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
+ if (ista) {
+ spin_lock_bh(&sta->rate_ctrl_lock);
+ ref->ops->get_rate(ref->priv, ista, priv_sta, txrc);
+ spin_unlock_bh(&sta->rate_ctrl_lock);
+ } else {
+ ref->ops->get_rate(ref->priv, NULL, NULL, txrc);
+ }
if (sdata->local->hw.flags & IEEE80211_HW_SUPPORTS_RC_TABLE)
return;
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -42,10 +42,12 @@ static inline void rate_control_tx_statu
if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
return;
+ spin_lock_bh(&sta->rate_ctrl_lock);
if (ref->ops->tx_status)
ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
else
ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
+ spin_unlock_bh(&sta->rate_ctrl_lock);
}
static inline void
@@ -64,7 +66,9 @@ rate_control_tx_status_noskb(struct ieee
if (WARN_ON_ONCE(!ref->ops->tx_status_noskb))
return;
+ spin_lock_bh(&sta->rate_ctrl_lock);
ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
+ spin_unlock_bh(&sta->rate_ctrl_lock);
}
static inline void rate_control_rate_init(struct sta_info *sta)
@@ -91,8 +95,10 @@ static inline void rate_control_rate_ini
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);
}
@@ -115,18 +121,20 @@ static inline void rate_control_rate_upd
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);
}
static inline void *rate_control_alloc_sta(struct rate_control_ref *ref,
- struct ieee80211_sta *sta,
- gfp_t gfp)
+ struct sta_info *sta, gfp_t gfp)
{
- return ref->ops->alloc_sta(ref->priv, sta, gfp);
+ spin_lock_init(&sta->rate_ctrl_lock);
+ return ref->ops->alloc_sta(ref->priv, &sta->sta, gfp);
}
static inline void rate_control_free_sta(struct sta_info *sta)
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -280,7 +280,7 @@ static int sta_prepare_rate_control(stru
sta->rate_ctrl = local->rate_ctrl;
sta->rate_ctrl_priv = rate_control_alloc_sta(sta->rate_ctrl,
- &sta->sta, gfp);
+ sta, gfp);
if (!sta->rate_ctrl_priv)
return -ENOMEM;
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -348,6 +348,7 @@ struct sta_info {
u8 ptk_idx;
struct rate_control_ref *rate_ctrl;
void *rate_ctrl_priv;
+ spinlock_t rate_ctrl_lock;
spinlock_t lock;
struct work_struct drv_deliver_wk;

View file

@ -1,118 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Wed, 22 Oct 2014 18:18:04 +0200
Subject: [PATCH] ath9k: add support for reporting tx power to mac80211
Track it per channel context instead of in the softc
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -347,6 +347,7 @@ struct ath_chanctx {
int flush_timeout;
u16 txpower;
+ u16 cur_txpower;
bool offchannel;
bool stopped;
bool active;
@@ -987,7 +988,6 @@ struct ath_softc {
u8 gtt_cnt;
u32 intrstatus;
u16 ps_flags; /* PS_* */
- u16 curtxpow;
bool ps_enabled;
bool ps_idle;
short nbcnvifs;
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -172,17 +172,20 @@ static void ath9k_reg_notifier(struct wi
ath_reg_notifier_apply(wiphy, request, reg);
/* Set tx power */
- if (ah->curchan) {
- sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
- ath9k_ps_wakeup(sc);
- ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
- sc->curtxpow = ath9k_hw_regulatory(ah)->power_limit;
- /* synchronize DFS detector if regulatory domain changed */
- if (sc->dfs_detector != NULL)
- sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
- request->dfs_region);
- ath9k_ps_restore(sc);
- }
+ if (!ah->curchan)
+ return;
+
+ sc->cur_chan->txpower = 2 * ah->curchan->chan->max_power;
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_set_txpowerlimit(ah, sc->cur_chan->txpower, false);
+ ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
+ sc->cur_chan->txpower,
+ &sc->cur_chan->cur_txpower);
+ /* synchronize DFS detector if regulatory domain changed */
+ if (sc->dfs_detector != NULL)
+ sc->dfs_detector->set_dfs_domain(sc->dfs_detector,
+ request->dfs_region);
+ ath9k_ps_restore(sc);
}
/*
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -233,8 +233,9 @@ static bool ath_complete_reset(struct at
ath9k_calculate_summary_state(sc, sc->cur_chan);
ath_startrecv(sc);
- ath9k_cmn_update_txpow(ah, sc->curtxpow,
- sc->cur_chan->txpower, &sc->curtxpow);
+ ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
+ sc->cur_chan->txpower,
+ &sc->cur_chan->cur_txpower);
clear_bit(ATH_OP_HW_RESET, &common->op_flags);
if (!sc->cur_chan->offchannel && start) {
@@ -1471,8 +1472,9 @@ static int ath9k_config(struct ieee80211
if (changed & IEEE80211_CONF_CHANGE_POWER) {
ath_dbg(common, CONFIG, "Set power: %d\n", conf->power_level);
sc->cur_chan->txpower = 2 * conf->power_level;
- ath9k_cmn_update_txpow(ah, sc->curtxpow,
- sc->cur_chan->txpower, &sc->curtxpow);
+ ath9k_cmn_update_txpow(ah, sc->cur_chan->cur_txpower,
+ sc->cur_chan->txpower,
+ &sc->cur_chan->cur_txpower);
}
mutex_unlock(&sc->mutex);
@@ -2594,6 +2596,24 @@ void ath9k_fill_chanctx_ops(void)
#endif
+static int ath9k_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ int *dbm)
+{
+ struct ath_softc *sc = hw->priv;
+ struct ath_vif *avp = (void *)vif->drv_priv;
+
+ mutex_lock(&sc->mutex);
+ if (avp->chanctx)
+ *dbm = avp->chanctx->cur_txpower;
+ else
+ *dbm = sc->cur_chan->cur_txpower;
+ mutex_unlock(&sc->mutex);
+
+ *dbm /= 2;
+
+ return 0;
+}
+
struct ieee80211_ops ath9k_ops = {
.tx = ath9k_tx,
.start = ath9k_start,
@@ -2640,4 +2660,5 @@ struct ieee80211_ops ath9k_ops = {
#endif
.sw_scan_start = ath9k_sw_scan_start,
.sw_scan_complete = ath9k_sw_scan_complete,
+ .get_txpower = ath9k_get_txpower,
};

View file

@ -0,0 +1,21 @@
From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
Date: Tue, 10 Mar 2015 17:49:29 +0100
Subject: [PATCH] ath9k: restart only triggering DFS detector line
To support HT40 DFS mode, a triggering detector must
reset only itself but not other detector lines.
Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
---
--- a/drivers/net/wireless/ath/dfs_pattern_detector.c
+++ b/drivers/net/wireless/ath/dfs_pattern_detector.c
@@ -289,7 +289,7 @@ dpd_add_pulse(struct dfs_pattern_detecto
"count=%d, count_false=%d\n",
event->freq, pd->rs->type_id,
ps->pri, ps->count, ps->count_falses);
- channel_detector_reset(dpd, cd);
+ pd->reset(pd, dpd->last_pulse_ts);
return true;
}
}

View file

@ -1,20 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Wed, 22 Oct 2014 18:44:03 +0200
Subject: [PATCH] ath10k: add SURVEY_INFO_IN_USE for current channel on
survey
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4044,6 +4044,9 @@ static int ath10k_get_survey(struct ieee
survey->channel = &sband->channels[idx];
+ if (ar->rx_channel == survey->channel)
+ survey->filled |= SURVEY_INFO_IN_USE;
+
exit:
mutex_unlock(&ar->conf_mutex);
return ret;

View file

@ -0,0 +1,76 @@
From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
Date: Tue, 10 Mar 2015 17:49:30 +0100
Subject: [PATCH] ath9k: add DFS support for extension channel
In HT40 modes, pulse events on primary and extension
channel are processed individually. If valid, a pulse
event will be fed into the detector
* for primary frequency, or
* for extension frequency (+/-20MHz based on HT40-mode)
* or both
With that, a 40MHz radar will result in two individual
radar events.
Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
---
--- a/drivers/net/wireless/ath/ath9k/dfs.c
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
@@ -126,8 +126,19 @@ ath9k_postprocess_radar_event(struct ath
DFS_STAT_INC(sc, pulses_detected);
return true;
}
-#undef PRI_CH_RADAR_FOUND
-#undef EXT_CH_RADAR_FOUND
+
+static void
+ath9k_dfs_process_radar_pulse(struct ath_softc *sc, struct pulse_event *pe)
+{
+ struct dfs_pattern_detector *pd = sc->dfs_detector;
+ DFS_STAT_INC(sc, pulses_processed);
+ if (pd == NULL)
+ return;
+ if (!pd->add_pulse(pd, pe))
+ return;
+ DFS_STAT_INC(sc, radar_detected);
+ ieee80211_radar_detected(sc->hw);
+}
/*
* DFS: check PHY-error for radar pulse and feed the detector
@@ -176,18 +187,21 @@ void ath9k_dfs_process_phyerr(struct ath
ard.pulse_length_pri = vdata_end[-3];
pe.freq = ah->curchan->channel;
pe.ts = mactime;
- if (ath9k_postprocess_radar_event(sc, &ard, &pe)) {
- struct dfs_pattern_detector *pd = sc->dfs_detector;
- ath_dbg(common, DFS,
- "ath9k_dfs_process_phyerr: channel=%d, ts=%llu, "
- "width=%d, rssi=%d, delta_ts=%llu\n",
- pe.freq, pe.ts, pe.width, pe.rssi,
- pe.ts - sc->dfs_prev_pulse_ts);
- sc->dfs_prev_pulse_ts = pe.ts;
- DFS_STAT_INC(sc, pulses_processed);
- if (pd != NULL && pd->add_pulse(pd, &pe)) {
- DFS_STAT_INC(sc, radar_detected);
- ieee80211_radar_detected(sc->hw);
- }
+ if (!ath9k_postprocess_radar_event(sc, &ard, &pe))
+ return;
+
+ ath_dbg(common, DFS,
+ "ath9k_dfs_process_phyerr: type=%d, freq=%d, ts=%llu, "
+ "width=%d, rssi=%d, delta_ts=%llu\n",
+ ard.pulse_bw_info, pe.freq, pe.ts, pe.width, pe.rssi,
+ pe.ts - sc->dfs_prev_pulse_ts);
+ sc->dfs_prev_pulse_ts = pe.ts;
+ if (ard.pulse_bw_info & PRI_CH_RADAR_FOUND)
+ ath9k_dfs_process_radar_pulse(sc, &pe);
+ if (ard.pulse_bw_info & EXT_CH_RADAR_FOUND) {
+ pe.freq += IS_CHAN_HT40PLUS(ah->curchan) ? 20 : -20;
+ ath9k_dfs_process_radar_pulse(sc, &pe);
}
}
+#undef PRI_CH_RADAR_FOUND
+#undef EXT_CH_RADAR_FOUND

View file

@ -1,61 +0,0 @@
From: Miaoqing Pan <miaoqing@qca.qualcomm.com>
Date: Thu, 6 Nov 2014 10:52:23 +0530
Subject: [PATCH] ath9k: Fix RTC_DERIVED_CLK usage
Based on the reference clock, which could be 25MHz or 40MHz,
AR_RTC_DERIVED_CLK is programmed differently for AR9340 and AR9550.
But, when a chip reset is done, processing the initvals
sets the register back to the default value.
Fix this by moving the code in ath9k_hw_init_pll() to
ar9003_hw_override_ini(). Also, do this override for AR9531.
Cc: stable@vger.kernel.org
Signed-off-by: Miaoqing Pan <miaoqing@qca.qualcomm.com>
Signed-off-by: Sujith Manoharan <c_manoha@qca.qualcomm.com>
---
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -664,6 +664,19 @@ static void ar9003_hw_override_ini(struc
ah->enabled_cals |= TX_CL_CAL;
else
ah->enabled_cals &= ~TX_CL_CAL;
+
+ if (AR_SREV_9340(ah) || AR_SREV_9531(ah) || AR_SREV_9550(ah)) {
+ if (ah->is_clk_25mhz) {
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
+ } else {
+ REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
+ REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
+ REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
+ }
+ udelay(100);
+ }
}
static void ar9003_hw_prog_ini(struct ath_hw *ah,
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -870,19 +870,6 @@ static void ath9k_hw_init_pll(struct ath
udelay(RTC_PLL_SETTLE_DELAY);
REG_WRITE(ah, AR_RTC_SLEEP_CLK, AR_RTC_FORCE_DERIVED_CLK);
-
- if (AR_SREV_9340(ah) || AR_SREV_9550(ah)) {
- if (ah->is_clk_25mhz) {
- REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x17c << 1);
- REG_WRITE(ah, AR_SLP32_MODE, 0x0010f3d7);
- REG_WRITE(ah, AR_SLP32_INC, 0x0001e7ae);
- } else {
- REG_WRITE(ah, AR_RTC_DERIVED_CLK, 0x261 << 1);
- REG_WRITE(ah, AR_SLP32_MODE, 0x0010f400);
- REG_WRITE(ah, AR_SLP32_INC, 0x0001e800);
- }
- udelay(100);
- }
}
static void ath9k_hw_init_interrupt_masks(struct ath_hw *ah,

View file

@ -0,0 +1,19 @@
From: Zefir Kurtisi <zefir.kurtisi@neratec.com>
Date: Tue, 10 Mar 2015 17:49:31 +0100
Subject: [PATCH] ath9k: allow 40MHz radar detection width
Signed-off-by: Zefir Kurtisi <zefir.kurtisi@neratec.com>
---
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -763,7 +763,8 @@ static const struct ieee80211_iface_comb
.num_different_channels = 1,
.beacon_int_infra_match = true,
.radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
- BIT(NL80211_CHAN_WIDTH_20),
+ BIT(NL80211_CHAN_WIDTH_20) |
+ BIT(NL80211_CHAN_WIDTH_40),
}
#endif
};

View file

@ -1,6 +1,5 @@
From a5d37f41d298a2a202296909892dd01e2bf071c7 Mon Sep 17 00:00:00 2001
From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
Date: Wed, 4 Mar 2015 00:44:37 +0300
Date: Wed, 4 Mar 2015 05:12:10 +0300
Subject: [PATCH] ath5k: channel change fix
ath5k updates the channel pointer and after that it stops the Rx logic
@ -59,15 +58,10 @@ Tested-by: Christophe Prevotaux <cprevotaux@nltinc.com>
Tested-by: Eric Bree <ebree@nltinc.com>
Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
---
drivers/net/wireless/ath/ath5k/base.c | 24 +++++++++++++++++++++---
drivers/net/wireless/ath/ath5k/reset.c | 24 ------------------------
2 files changed, 21 insertions(+), 27 deletions(-)
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index bc9cb35..34b2f15 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -2858,7 +2858,7 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
@@ -2858,7 +2858,7 @@ ath5k_reset(struct ath5k_hw *ah, struct
{
struct ath_common *common = ath5k_hw_common(ah);
int ret, ani_mode;
@ -76,7 +70,7 @@ index bc9cb35..34b2f15 100644
ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
@@ -2876,11 +2876,29 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
@@ -2876,11 +2876,29 @@ ath5k_reset(struct ath5k_hw *ah, struct
* so we should also free any remaining
* tx buffers */
ath5k_drain_tx_buffs(ah);
@ -108,11 +102,9 @@ index bc9cb35..34b2f15 100644
ret = ath5k_hw_reset(ah, ah->opmode, ah->curchan, fast, skip_pcu);
if (ret) {
ATH5K_ERR(ah, "can't reset hardware (%d)\n", ret);
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index b9b651e..99e62f9 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1169,30 +1169,6 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
@@ -1169,30 +1169,6 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
if (ah->ah_version == AR5K_AR5212)
ath5k_hw_set_sleep_clock(ah, false);

View file

@ -1,38 +0,0 @@
From: Hauke Mehrtens <hauke@hauke-m.de>
Date: Wed, 5 Nov 2014 23:31:07 +0100
Subject: [PATCH] b43: fix NULL pointer dereference in b43_phy_copy()
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
phy_read and phy_write are not set for every phy any more sine this:
commit d342b95dd735014a590f9051b1ba227eb54ca8f6
Author: RafaÅ MiÅecki <zajec5@gmail.com>
Date: Thu Jul 31 21:59:43 2014 +0200
b43: don't duplicate common PHY read/write ops
b43_phy_copy() accesses phy_read and phy_write directly and will fail
with some phys. This patch fixes the regression by using the
b43_phy_read() and b43_phy_write() functions which should be used for
read and write access.
This should fix this bug report:
https://bugzilla.kernel.org/show_bug.cgi?id=87731
Reported-by: Volker Kempter <v.kempter@pe.tu-clausthal.de>
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
---
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -301,8 +301,7 @@ void b43_phy_write(struct b43_wldev *dev
void b43_phy_copy(struct b43_wldev *dev, u16 destreg, u16 srcreg)
{
assert_mac_suspended(dev);
- dev->phy.ops->phy_write(dev, destreg,
- dev->phy.ops->phy_read(dev, srcreg));
+ b43_phy_write(dev, destreg, b43_phy_read(dev, srcreg));
}
void b43_phy_mask(struct b43_wldev *dev, u16 offset, u16 mask)

View file

@ -1,6 +1,5 @@
From d8d4050dff457b79ad7e9356103cad557c338532 Mon Sep 17 00:00:00 2001
From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
Date: Wed, 4 Mar 2015 03:16:34 +0300
Date: Wed, 4 Mar 2015 05:12:11 +0300
Subject: [PATCH] ath5k: fix reset race
To prepare for reset ath5k should finish all asynchronous tasks. At
@ -54,12 +53,7 @@ Tested-by: Christophe Prevotaux <cprevotaux@nltinc.com>
Tested-by: Eric Bree <ebree@nltinc.com>
Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
---
drivers/net/wireless/ath/ath5k/ath5k.h | 1 +
drivers/net/wireless/ath/ath5k/base.c | 7 +++++++
2 files changed, 8 insertions(+)
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 1ed7a88..7ca0d6f 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1283,6 +1283,7 @@ struct ath5k_hw {
@ -70,11 +64,9 @@ index 1ed7a88..7ca0d6f 100644
unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
unsigned int fif_filter_flags; /* Current FIF_* filter flags */
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 34b2f15..41848e1 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1523,6 +1523,9 @@ ath5k_set_current_imask(struct ath5k_hw *ah)
@@ -1523,6 +1523,9 @@ ath5k_set_current_imask(struct ath5k_hw
enum ath5k_int imask;
unsigned long flags;
@ -84,7 +76,7 @@ index 34b2f15..41848e1 100644
spin_lock_irqsave(&ah->irqlock, flags);
imask = ah->imask;
if (ah->rx_pending)
@@ -2862,6 +2865,8 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
@@ -2862,6 +2865,8 @@ ath5k_reset(struct ath5k_hw *ah, struct
ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
@ -93,7 +85,7 @@ index 34b2f15..41848e1 100644
ath5k_hw_set_imr(ah, 0);
synchronize_irq(ah->irq);
ath5k_stop_tasklets(ah);
@@ -2952,6 +2957,8 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
@@ -2952,6 +2957,8 @@ ath5k_reset(struct ath5k_hw *ah, struct
*/
/* ath5k_chan_change(ah, c); */

View file

@ -1,33 +0,0 @@
From: Ben Greear <greearb@candelatech.com>
Date: Tue, 4 Nov 2014 15:22:49 -0800
Subject: [PATCH] ath9k: fix misc debugfs when not using chan context
When channel-context is not enabled, all vifs belong to
the first context, but it is not configured as 'assigned'.
Fix misc debugfs file to print out info for non-assigned
contexts, and also print whether ctx is assigned or not.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -828,13 +828,14 @@ static ssize_t read_file_misc(struct fil
i = 0;
ath_for_each_chanctx(sc, ctx) {
- if (!ctx->assigned || list_empty(&ctx->vifs))
+ if (list_empty(&ctx->vifs))
continue;
ath9k_calculate_iter_data(sc, ctx, &iter_data);
len += scnprintf(buf + len, sizeof(buf) - len,
- "VIF-COUNTS: CTX %i AP: %i STA: %i MESH: %i WDS: %i",
- i++, iter_data.naps, iter_data.nstations,
+ "VIFS: CTX %i(%i) AP: %i STA: %i MESH: %i WDS: %i",
+ i++, (int)(ctx->assigned), iter_data.naps,
+ iter_data.nstations,
iter_data.nmeshes, iter_data.nwds);
len += scnprintf(buf + len, sizeof(buf) - len,
" ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",

View file

@ -1,70 +0,0 @@
From: Ben Greear <greearb@candelatech.com>
Date: Tue, 4 Nov 2014 15:22:50 -0800
Subject: [PATCH] ath9k: fix regression in bssidmask calculation
The commit that went into 3.17:
ath9k: Summarize hw state per channel context
Group and set hw state (opmode, primary_sta, beacon conf) per
channel context instead of whole list of vifs. This would allow
each channel context to run in different mode (STA/AP).
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
Signed-off-by: Rajkumar Manoharan <rmanohar@qti.qualcomm.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
broke multi-vif configuration due to not properly calculating
the bssid mask.
The test case that caught this was:
create wlan0 and sta0-4 (6 total), not sure how much that matters.
associate all 6 (works fine)
disconnect 5 of them, leaving sta0 up
Start trying to bring up the other 5 one at a time. It will
fail, with iw events looking like this (in these logs, several
sta are trying to come up, but symptom is the same with just one)
The patch causing the regression made quite a few changes, but
the part I think caused this particular problem was not
recalculating the bssid mask when adding and removing interfaces.
Re-adding those calls fixes my test case. Fix bad comment
as well.
Signed-off-by: Ben Greear <greearb@candelatech.com>
---
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -994,9 +994,8 @@ void ath9k_calculate_iter_data(struct at
struct ath_vif *avp;
/*
- * Pick the MAC address of the first interface as the new hardware
- * MAC address. The hardware will use it together with the BSSID mask
- * when matching addresses.
+ * The hardware will use primary station addr together with the
+ * BSSID mask when matching addresses.
*/
memset(iter_data, 0, sizeof(*iter_data));
memset(&iter_data->mask, 0xff, ETH_ALEN);
@@ -1225,6 +1224,8 @@ static int ath9k_add_interface(struct ie
list_add_tail(&avp->list, &avp->chanctx->vifs);
}
+ ath9k_calculate_summary_state(sc, avp->chanctx);
+
ath9k_assign_hw_queues(hw, vif);
an->sc = sc;
@@ -1294,6 +1295,8 @@ static void ath9k_remove_interface(struc
ath_tx_node_cleanup(sc, &avp->mcast_node);
+ ath9k_calculate_summary_state(sc, avp->chanctx);
+
mutex_unlock(&sc->mutex);
}

View file

@ -1,95 +0,0 @@
From: Stanislaw Gruszka <sgruszka@redhat.com>
Date: Sun, 2 Nov 2014 13:38:47 +0100
Subject: [PATCH] rt2x00: do not align payload on modern H/W
RT2800 and newer hardware require padding between header and payload if
header length is not multiple of 4.
For historical reasons we also align payload to to 4 bytes boundary, but
such alignment is not needed on modern H/W.
Patch improve performance on embedded CPUs and _possibly_ fixes
skb_under_panic problems reported from time to time:
https://bugzilla.kernel.org/show_bug.cgi?id=84911
https://bugzilla.kernel.org/show_bug.cgi?id=72471
http://marc.info/?l=linux-wireless&m=139108549530402&w=2
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/1087591
But we can not explain or otherwise confirm the patch fixes this panic
issue for sure.
Originally-From: Helmut Schaa <helmut.schaa@googlemail.com>
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -158,55 +158,29 @@ void rt2x00queue_align_frame(struct sk_b
skb_trim(skb, frame_length);
}
-void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int header_length)
+/*
+ * H/W needs L2 padding between the header and the paylod if header size
+ * is not 4 bytes aligned.
+ */
+void rt2x00queue_insert_l2pad(struct sk_buff *skb, unsigned int hdr_len)
{
- unsigned int payload_length = skb->len - header_length;
- unsigned int header_align = ALIGN_SIZE(skb, 0);
- unsigned int payload_align = ALIGN_SIZE(skb, header_length);
- unsigned int l2pad = payload_length ? L2PAD_SIZE(header_length) : 0;
+ unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
- /*
- * Adjust the header alignment if the payload needs to be moved more
- * than the header.
- */
- if (payload_align > header_align)
- header_align += 4;
-
- /* There is nothing to do if no alignment is needed */
- if (!header_align)
+ if (!l2pad)
return;
- /* Reserve the amount of space needed in front of the frame */
- skb_push(skb, header_align);
-
- /*
- * Move the header.
- */
- memmove(skb->data, skb->data + header_align, header_length);
-
- /* Move the payload, if present and if required */
- if (payload_length && payload_align)
- memmove(skb->data + header_length + l2pad,
- skb->data + header_length + l2pad + payload_align,
- payload_length);
-
- /* Trim the skb to the correct size */
- skb_trim(skb, header_length + l2pad + payload_length);
+ skb_push(skb, l2pad);
+ memmove(skb->data, skb->data + l2pad, hdr_len);
}
-void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int header_length)
+void rt2x00queue_remove_l2pad(struct sk_buff *skb, unsigned int hdr_len)
{
- /*
- * L2 padding is only present if the skb contains more than just the
- * IEEE 802.11 header.
- */
- unsigned int l2pad = (skb->len > header_length) ?
- L2PAD_SIZE(header_length) : 0;
+ unsigned int l2pad = (skb->len > hdr_len) ? L2PAD_SIZE(hdr_len) : 0;
if (!l2pad)
return;
- memmove(skb->data + l2pad, skb->data, header_length);
+ memmove(skb->data + l2pad, skb->data, hdr_len);
skb_pull(skb, l2pad);
}

View file

@ -1,38 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 13 Nov 2014 18:27:47 +0100
Subject: [PATCH] ath9k: prevent early IRQs from accessing hardware
IRQs are suppressed if ah == NULL and ATH_OP_INVALID being set in
common->op_flags. Close a short time window between those two.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -513,10 +513,14 @@ static int ath9k_init_softc(u16 devid, s
ah->reg_ops.read = ath9k_ioread32;
ah->reg_ops.write = ath9k_iowrite32;
ah->reg_ops.rmw = ath9k_reg_rmw;
- sc->sc_ah = ah;
pCap = &ah->caps;
common = ath9k_hw_common(ah);
+
+ /* Will be cleared in ath9k_start() */
+ set_bit(ATH_OP_INVALID, &common->op_flags);
+
+ sc->sc_ah = ah;
sc->dfs_detector = dfs_pattern_detector_init(common, NL80211_DFS_UNSET);
sc->tx99_power = MAX_RATE_POWER + 1;
init_waitqueue_head(&sc->tx_wait);
@@ -876,9 +880,6 @@ int ath9k_init_device(u16 devid, struct
common = ath9k_hw_common(ah);
ath9k_set_hw_capab(sc, hw);
- /* Will be cleared in ath9k_start() */
- set_bit(ATH_OP_INVALID, &common->op_flags);
-
/* Initialize regulatory */
error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
ath9k_reg_notifier);

View file

@ -1,29 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 13 Nov 2014 18:29:00 +0100
Subject: [PATCH] ath9k: set ATH_OP_INVALID before disabling hardware
Closes another small IRQ handler race
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -885,6 +885,9 @@ static void ath9k_stop(struct ieee80211_
&sc->cur_chan->chandef);
ath9k_hw_reset(ah, ah->curchan, ah->caldata, false);
+
+ set_bit(ATH_OP_INVALID, &common->op_flags);
+
ath9k_hw_phy_disable(ah);
ath9k_hw_configpcipowersave(ah, true);
@@ -893,7 +896,6 @@ static void ath9k_stop(struct ieee80211_
ath9k_ps_restore(sc);
- set_bit(ATH_OP_INVALID, &common->op_flags);
sc->ps_idle = prev_idle;
mutex_unlock(&sc->mutex);

View file

@ -1,61 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Thu, 13 Nov 2014 18:29:26 +0100
Subject: [PATCH] ath9k: do not access hardware on IRQs during reset
Instead of killing interrupts during reset when the first one happens,
kill them before issuing the reset.
This fixes an easy to reproduce crash with multiple cards sharing the
same IRQ.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -512,16 +512,13 @@ irqreturn_t ath_isr(int irq, void *dev)
if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags))
return IRQ_NONE;
- /* shared irq, not for us */
+ if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
+ return IRQ_NONE;
+ /* shared irq, not for us */
if (!ath9k_hw_intrpend(ah))
return IRQ_NONE;
- if (test_bit(ATH_OP_HW_RESET, &common->op_flags)) {
- ath9k_hw_kill_interrupts(ah);
- return IRQ_HANDLED;
- }
-
/*
* Figure out the reason(s) for the interrupt. Note
* that the hal returns a pseudo-ISR that may include
@@ -532,6 +529,9 @@ irqreturn_t ath_isr(int irq, void *dev)
ath9k_debug_sync_cause(sc, sync_cause);
status &= ah->imask; /* discard unasked-for bits */
+ if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
+ return IRQ_HANDLED;
+
/*
* If there are no status bits set, then this interrupt was not
* for me (should have been caught above).
@@ -613,6 +613,7 @@ int ath_reset(struct ath_softc *sc, stru
struct ath_common *common = ath9k_hw_common(sc->sc_ah);
int r;
+ ath9k_hw_kill_interrupts(sc->sc_ah);
set_bit(ATH_OP_HW_RESET, &common->op_flags);
ath9k_ps_wakeup(sc);
@@ -633,6 +634,7 @@ void ath9k_queue_reset(struct ath_softc
#ifdef CPTCFG_ATH9K_DEBUGFS
RESET_STAT_INC(sc, type);
#endif
+ ath9k_hw_kill_interrupts(sc->sc_ah);
set_bit(ATH_OP_HW_RESET, &common->op_flags);
ieee80211_queue_work(sc->hw, &sc->hw_reset_work);
}

View file

@ -1,22 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 15 Nov 2014 03:45:56 +0100
Subject: [PATCH] mac80211: skip legacy rate mask handling for VHT rates
The rate mask code currently assumes that a rate is legacy if
IEEE80211_TX_RC_MCS is not set. This might be the cause of bogus VHT
rates being reported with minstrel_ht.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -385,7 +385,7 @@ static void rate_idx_match_mask(struct i
*rate = alt_rate;
return;
}
- } else {
+ } else if (!(rate->flags & IEEE80211_TX_RC_VHT_MCS)) {
/* handle legacy rates */
if (rate_idx_match_legacy_mask(rate, sband->n_bitrates, mask))
return;

View file

@ -1,33 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 15 Nov 2014 22:13:38 +0100
Subject: [PATCH] mac80211: minstrel_ht: add a small optimization to
minstrel_aggr_check
Check the queue mapping earlier, skb->queue_mapping is more likely than
skb->data to still be in d-cache.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -690,6 +690,9 @@ minstrel_aggr_check(struct ieee80211_sta
struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
u16 tid;
+ if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
+ return;
+
if (unlikely(!ieee80211_is_data_qos(hdr->frame_control)))
return;
@@ -700,9 +703,6 @@ minstrel_aggr_check(struct ieee80211_sta
if (likely(sta->ampdu_mlme.tid_tx[tid]))
return;
- if (skb_get_queue_mapping(skb) == IEEE80211_AC_VO)
- return;
-
ieee80211_start_tx_ba_session(pubsta, tid, 5000);
}

View file

@ -1,33 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 15 Nov 2014 22:16:36 +0100
Subject: [PATCH] mac80211: minstrel_ht: move aggregation check to
.get_rate()
Preparation for adding a no-skb tx status path
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -782,9 +782,6 @@ minstrel_ht_tx_status(void *priv, struct
if (time_after(jiffies, mi->stats_update + (mp->update_interval / 2 * HZ) / 1000)) {
update = true;
minstrel_ht_update_stats(mp, mi);
- if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
- mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP)
- minstrel_aggr_check(sta, skb);
}
if (update)
@@ -1026,6 +1023,10 @@ minstrel_ht_get_rate(void *priv, struct
if (!msp->is_ht)
return mac80211_minstrel.get_rate(priv, sta, &msp->legacy, txrc);
+ if (!(info->flags & IEEE80211_TX_CTL_AMPDU) &&
+ mi->max_prob_rate / MCS_GROUP_RATES != MINSTREL_CCK_GROUP)
+ minstrel_aggr_check(sta, txrc->skb);
+
info->flags |= mi->tx_flags;
minstrel_ht_check_cck_shortpreamble(mp, mi, txrc->short_preamble);

View file

@ -1,43 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 15 Nov 2014 22:23:44 +0100
Subject: [PATCH] mac80211: add tx_status_noskb to rate_control_ops
This op works like .tx_status, except it does not need access to the
skb. This will be used by drivers that cannot match tx status
information to specific packets.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -4727,6 +4727,10 @@ struct rate_control_ops {
void (*free_sta)(void *priv, struct ieee80211_sta *sta,
void *priv_sta);
+ void (*tx_status_noskb)(void *priv,
+ struct ieee80211_supported_band *sband,
+ struct ieee80211_sta *sta, void *priv_sta,
+ struct ieee80211_tx_info *info);
void (*tx_status)(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
struct sk_buff *skb);
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -37,11 +37,15 @@ static inline void rate_control_tx_statu
struct rate_control_ref *ref = local->rate_ctrl;
struct ieee80211_sta *ista = &sta->sta;
void *priv_sta = sta->rate_ctrl_priv;
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
return;
- ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
+ if (ref->ops->tx_status)
+ ref->ops->tx_status(ref->priv, sband, ista, priv_sta, skb);
+ else
+ ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
}

View file

@ -1,31 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 15 Nov 2014 22:38:07 +0100
Subject: [PATCH] mac80211: minstrel: switch to .tx_status_noskb
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/rc80211_minstrel.c
+++ b/net/mac80211/rc80211_minstrel.c
@@ -223,11 +223,10 @@ minstrel_update_stats(struct minstrel_pr
static void
minstrel_tx_status(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
- struct sk_buff *skb)
+ struct ieee80211_tx_info *info)
{
struct minstrel_priv *mp = priv;
struct minstrel_sta_info *mi = priv_sta;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *ar = info->status.rates;
int i, ndx;
int success;
@@ -674,7 +673,7 @@ static u32 minstrel_get_expected_through
const struct rate_control_ops mac80211_minstrel = {
.name = "minstrel",
- .tx_status = minstrel_tx_status,
+ .tx_status_noskb = minstrel_tx_status,
.get_rate = minstrel_get_rate,
.rate_init = minstrel_rate_init,
.alloc = minstrel_alloc,

View file

@ -1,41 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 15 Nov 2014 22:38:21 +0100
Subject: [PATCH] mac80211: minstrel_ht: switch to .tx_status_noskb
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -709,11 +709,10 @@ minstrel_aggr_check(struct ieee80211_sta
static void
minstrel_ht_tx_status(void *priv, struct ieee80211_supported_band *sband,
struct ieee80211_sta *sta, void *priv_sta,
- struct sk_buff *skb)
+ struct ieee80211_tx_info *info)
{
struct minstrel_ht_sta_priv *msp = priv_sta;
struct minstrel_ht_sta *mi = &msp->ht;
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
struct ieee80211_tx_rate *ar = info->status.rates;
struct minstrel_rate_stats *rate, *rate2;
struct minstrel_priv *mp = priv;
@@ -721,7 +720,8 @@ minstrel_ht_tx_status(void *priv, struct
int i;
if (!msp->is_ht)
- return mac80211_minstrel.tx_status(priv, sband, sta, &msp->legacy, skb);
+ return mac80211_minstrel.tx_status_noskb(priv, sband, sta,
+ &msp->legacy, info);
/* This packet was aggregated but doesn't carry status info */
if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
@@ -1343,7 +1343,7 @@ static u32 minstrel_ht_get_expected_thro
static const struct rate_control_ops mac80211_minstrel_ht = {
.name = "minstrel_ht",
- .tx_status = minstrel_ht_tx_status,
+ .tx_status_noskb = minstrel_ht_tx_status,
.get_rate = minstrel_ht_get_rate,
.rate_init = minstrel_ht_rate_init,
.rate_update = minstrel_ht_rate_update,

View file

@ -1,219 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sat, 15 Nov 2014 23:50:27 +0100
Subject: [PATCH] mac80211: add ieee80211_tx_status_noskb
This can be used by drivers that cannot reliably map tx status
information onto specific skbs.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3517,6 +3517,28 @@ void ieee80211_tx_status(struct ieee8021
struct sk_buff *skb);
/**
+ * ieee80211_tx_status_noskb - transmit status callback without skb
+ *
+ * This function can be used as a replacement for ieee80211_tx_status
+ * in drivers that cannot reliably map tx status information back to
+ * specific skbs.
+ *
+ * This function may not be called in IRQ context. Calls to this function
+ * for a single hardware must be synchronized against each other. Calls
+ * to this function, ieee80211_tx_status_ni() and ieee80211_tx_status_irqsafe()
+ * may not be mixed for a single hardware. Must not run concurrently with
+ * ieee80211_rx() or ieee80211_rx_ni().
+ *
+ * @hw: the hardware the frame was transmitted by
+ * @sta: the receiver station to which this packet is sent
+ * (NULL for multicast packets)
+ * @info: tx status information
+ */
+void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct ieee80211_tx_info *info);
+
+/**
* ieee80211_tx_status_ni - transmit status callback (in process context)
*
* Like ieee80211_tx_status() but can be called in process context.
--- a/net/mac80211/rate.h
+++ b/net/mac80211/rate.h
@@ -49,6 +49,23 @@ static inline void rate_control_tx_statu
}
+static inline void
+rate_control_tx_status_noskb(struct ieee80211_local *local,
+ struct ieee80211_supported_band *sband,
+ struct sta_info *sta,
+ struct ieee80211_tx_info *info)
+{
+ struct rate_control_ref *ref = local->rate_ctrl;
+ struct ieee80211_sta *ista = &sta->sta;
+ void *priv_sta = sta->rate_ctrl_priv;
+
+ if (!ref || !test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
+ return;
+
+ ref->ops->tx_status_noskb(ref->priv, sband, ista, priv_sta, info);
+}
+
+
static inline void rate_control_rate_init(struct sta_info *sta)
{
struct ieee80211_local *local = sta->sdata->local;
--- a/net/mac80211/status.c
+++ b/net/mac80211/status.c
@@ -541,10 +541,9 @@ static void ieee80211_tx_latency_end_msr
#define STA_LOST_TDLS_PKT_THRESHOLD 10
#define STA_LOST_TDLS_PKT_TIME (10*HZ) /* 10secs since last ACK */
-static void ieee80211_lost_packet(struct sta_info *sta, struct sk_buff *skb)
+static void ieee80211_lost_packet(struct sta_info *sta,
+ struct ieee80211_tx_info *info)
{
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
-
/* This packet was aggregated but doesn't carry status info */
if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
!(info->flags & IEEE80211_TX_STAT_AMPDU))
@@ -571,24 +570,13 @@ static void ieee80211_lost_packet(struct
sta->lost_packets = 0;
}
-void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+static int ieee80211_tx_get_rates(struct ieee80211_hw *hw,
+ struct ieee80211_tx_info *info,
+ int *retry_count)
{
- struct sk_buff *skb2;
- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
- struct ieee80211_local *local = hw_to_local(hw);
- struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
- __le16 fc;
- struct ieee80211_supported_band *sband;
- struct ieee80211_sub_if_data *sdata;
- struct net_device *prev_dev = NULL;
- struct sta_info *sta, *tmp;
- int retry_count = -1, i;
int rates_idx = -1;
- bool send_to_cooked;
- bool acked;
- struct ieee80211_bar *bar;
- int rtap_len;
- int shift = 0;
+ int count = -1;
+ int i;
for (i = 0; i < IEEE80211_TX_MAX_RATES; i++) {
if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
@@ -606,12 +594,94 @@ void ieee80211_tx_status(struct ieee8021
break;
}
- retry_count += info->status.rates[i].count;
+ count += info->status.rates[i].count;
}
rates_idx = i - 1;
- if (retry_count < 0)
- retry_count = 0;
+ if (count < 0)
+ count = 0;
+
+ *retry_count = count;
+ return rates_idx;
+}
+
+void ieee80211_tx_status_noskb(struct ieee80211_hw *hw,
+ struct ieee80211_sta *pubsta,
+ struct ieee80211_tx_info *info)
+{
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_supported_band *sband;
+ int retry_count;
+ int rates_idx;
+ bool acked;
+
+ rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
+
+ sband = hw->wiphy->bands[info->band];
+
+ acked = !!(info->flags & IEEE80211_TX_STAT_ACK);
+ if (pubsta) {
+ struct sta_info *sta;
+
+ sta = container_of(pubsta, struct sta_info, sta);
+
+ if (info->flags & IEEE80211_TX_STATUS_EOSP)
+ clear_sta_flag(sta, WLAN_STA_SP);
+
+ if (!acked)
+ sta->tx_retry_failed++;
+ sta->tx_retry_count += retry_count;
+
+ if (acked) {
+ sta->last_rx = jiffies;
+
+ if (sta->lost_packets)
+ sta->lost_packets = 0;
+
+ /* Track when last TDLS packet was ACKed */
+ if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
+ sta->last_tdls_pkt_time = jiffies;
+ } else {
+ ieee80211_lost_packet(sta, info);
+ }
+
+ rate_control_tx_status_noskb(local, sband, sta, info);
+ }
+
+ if (acked) {
+ local->dot11TransmittedFrameCount++;
+ if (!pubsta)
+ local->dot11MulticastTransmittedFrameCount++;
+ if (retry_count > 0)
+ local->dot11RetryCount++;
+ if (retry_count > 1)
+ local->dot11MultipleRetryCount++;
+ } else {
+ local->dot11FailedCount++;
+ }
+}
+EXPORT_SYMBOL(ieee80211_tx_status_noskb);
+
+void ieee80211_tx_status(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct sk_buff *skb2;
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+ struct ieee80211_local *local = hw_to_local(hw);
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ __le16 fc;
+ struct ieee80211_supported_band *sband;
+ struct ieee80211_sub_if_data *sdata;
+ struct net_device *prev_dev = NULL;
+ struct sta_info *sta, *tmp;
+ int retry_count;
+ int rates_idx;
+ bool send_to_cooked;
+ bool acked;
+ struct ieee80211_bar *bar;
+ int rtap_len;
+ int shift = 0;
+
+ rates_idx = ieee80211_tx_get_rates(hw, info, &retry_count);
rcu_read_lock();
@@ -716,7 +786,7 @@ void ieee80211_tx_status(struct ieee8021
if (test_sta_flag(sta, WLAN_STA_TDLS_PEER_AUTH))
sta->last_tdls_pkt_time = jiffies;
} else {
- ieee80211_lost_packet(sta, skb);
+ ieee80211_lost_packet(sta, info);
}
}

View file

@ -1,47 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Tue, 18 Nov 2014 21:43:25 +0100
Subject: [PATCH] mac80211: minstrel_ht: fix a crash in rate sorting
The commit 5935839ad73583781b8bbe8d91412f6826e218a4
"mac80211: improve minstrel_ht rate sorting by throughput & probability"
introduced a crash on rate sorting that occurs when the rate added to
the sorting array is faster than all the previous rates. Due to an
off-by-one error, it reads the rate index from tp_list[-1], which
contains uninitialized stack garbage, and then uses the resulting index
for accessing the group rate stats, leading to a crash if the garbage
value is big enough.
Cc: Thomas Huehn <thomas@net.t-labs.tu-berlin.de>
Reported-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/rc80211_minstrel_ht.c
+++ b/net/mac80211/rc80211_minstrel_ht.c
@@ -394,19 +394,16 @@ minstrel_ht_sort_best_tp_rates(struct mi
cur_thr = mi->groups[cur_group].rates[cur_idx].cur_tp;
cur_prob = mi->groups[cur_group].rates[cur_idx].probability;
- tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
- tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
- tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
-
- while (j > 0 && (cur_thr > tmp_thr ||
- (cur_thr == tmp_thr && cur_prob > tmp_prob))) {
- j--;
+ do {
tmp_group = tp_list[j - 1] / MCS_GROUP_RATES;
tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES;
tmp_thr = mi->groups[tmp_group].rates[tmp_idx].cur_tp;
tmp_prob = mi->groups[tmp_group].rates[tmp_idx].probability;
- }
+ if (cur_thr < tmp_thr ||
+ (cur_thr == tmp_thr && cur_prob <= tmp_prob))
+ break;
+ j--;
+ } while (j > 0);
if (j < MAX_THR_RATES - 1) {
memmove(&tp_list[j + 1], &tp_list[j], (sizeof(*tp_list) *

View file

@ -1,92 +0,0 @@
From: Johannes Berg <johannes.berg@intel.com>
Date: Tue, 18 Nov 2014 23:26:40 +0100
Subject: [PATCH] mac80211: notify drivers on sta rate table changes
This allows drivers with a firmware or chip-based rate lookup table to
use the most recent default rate selection without having to get it from
per-packet data or explicit ieee80211_get_tx_rate calls
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -2631,6 +2631,9 @@ enum ieee80211_reconfig_type {
* uses hardware rate control (%IEEE80211_HW_HAS_RATE_CONTROL) since
* otherwise the rate control algorithm is notified directly.
* Must be atomic.
+ * @sta_rate_tbl_update: Notifies the driver that the rate table changed. This
+ * is only used if the configured rate control algorithm actually uses
+ * the new rate table API, and is therefore optional. Must be atomic.
*
* @conf_tx: Configure TX queue parameters (EDCF (aifs, cw_min, cw_max),
* bursting) for a hardware TX queue.
@@ -2972,6 +2975,9 @@ struct ieee80211_ops {
struct ieee80211_vif *vif,
struct ieee80211_sta *sta,
u32 changed);
+ void (*sta_rate_tbl_update)(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta);
int (*conf_tx)(struct ieee80211_hw *hw,
struct ieee80211_vif *vif, u16 ac,
const struct ieee80211_tx_queue_params *params);
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -621,6 +621,21 @@ static inline void drv_sta_rc_update(str
trace_drv_return_void(local);
}
+static inline void drv_sta_rate_tbl_update(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta *sta)
+{
+ sdata = get_bss_sdata(sdata);
+ if (!check_sdata_in_driver(sdata))
+ return;
+
+ trace_drv_sta_rate_tbl_update(local, sdata, sta);
+ if (local->ops->sta_rate_tbl_update)
+ local->ops->sta_rate_tbl_update(&local->hw, &sdata->vif, sta);
+
+ trace_drv_return_void(local);
+}
+
static inline int drv_conf_tx(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata, u16 ac,
const struct ieee80211_tx_queue_params *params)
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -696,6 +696,7 @@ int rate_control_set_rates(struct ieee80
struct ieee80211_sta *pubsta,
struct ieee80211_sta_rates *rates)
{
+ struct sta_info *sta = container_of(pubsta, struct sta_info, sta);
struct ieee80211_sta_rates *old;
/*
@@ -709,6 +710,8 @@ int rate_control_set_rates(struct ieee80
if (old)
kfree_rcu(old, rcu_head);
+ drv_sta_rate_tbl_update(hw_to_local(hw), sta->sdata, pubsta);
+
return 0;
}
EXPORT_SYMBOL(rate_control_set_rates);
--- a/net/mac80211/trace.h
+++ b/net/mac80211/trace.h
@@ -826,6 +826,13 @@ DEFINE_EVENT(sta_event, drv_sta_pre_rcu_
TP_ARGS(local, sdata, sta)
);
+DEFINE_EVENT(sta_event, drv_sta_rate_tbl_update,
+ TP_PROTO(struct ieee80211_local *local,
+ struct ieee80211_sub_if_data *sdata,
+ struct ieee80211_sta *sta),
+ TP_ARGS(local, sdata, sta)
+);
+
TRACE_EVENT(drv_conf_tx,
TP_PROTO(struct ieee80211_local *local,
struct ieee80211_sub_if_data *sdata,

View file

@ -1,34 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Fri, 21 Nov 2014 23:27:33 +0100
Subject: [PATCH] mac80211: add more missing checks for VHT tx rates
Fixes a crash on attempting to calculate the frame duration for a VHT
packet (which needs to be handled by hw/driver instead).
Reported-by: Jouni Malinen <j@w1.fi>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/rate.c
+++ b/net/mac80211/rate.c
@@ -446,7 +446,8 @@ static void rate_fixup_ratelist(struct i
*
* XXX: Should this check all retry rates?
*/
- if (!(rates[0].flags & IEEE80211_TX_RC_MCS)) {
+ if (!(rates[0].flags &
+ (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))) {
u32 basic_rates = vif->bss_conf.basic_rates;
s8 baserate = basic_rates ? ffs(basic_rates) - 1 : 0;
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -60,7 +60,7 @@ static __le16 ieee80211_duration(struct
rcu_read_unlock();
/* assume HW handles this */
- if (tx->rate.flags & IEEE80211_TX_RC_MCS)
+ if (tx->rate.flags & (IEEE80211_TX_RC_MCS | IEEE80211_TX_RC_VHT_MCS))
return 0;
/* uh huh? */

View file

@ -1,82 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Mon, 24 Nov 2014 18:09:03 +0100
Subject: [PATCH] mac80211: copy chandef from AP vif to VLANs
Fixes a crash in nl80211_send_chandef, introduced in
commit c12bc4885f4b3bab0ed779c69d5d7e3223fa5003
"mac80211: return the vif's chandef in ieee80211_cfg_get_channel()"
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -932,6 +932,21 @@ ieee80211_vif_chanctx_reservation_comple
}
}
+static void
+ieee80211_vif_update_chandef(struct ieee80211_sub_if_data *sdata,
+ const struct cfg80211_chan_def *chandef)
+{
+ struct ieee80211_sub_if_data *vlan;
+
+ sdata->vif.bss_conf.chandef = *chandef;
+
+ if (sdata->vif.type != NL80211_IFTYPE_AP)
+ return;
+
+ list_for_each_entry(vlan, &sdata->u.ap.vlans, u.vlan.list)
+ vlan->vif.bss_conf.chandef = *chandef;
+}
+
static int
ieee80211_vif_use_reserved_reassign(struct ieee80211_sub_if_data *sdata)
{
@@ -994,7 +1009,7 @@ ieee80211_vif_use_reserved_reassign(stru
if (sdata->vif.bss_conf.chandef.width != sdata->reserved_chandef.width)
changed = BSS_CHANGED_BANDWIDTH;
- sdata->vif.bss_conf.chandef = sdata->reserved_chandef;
+ ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
if (changed)
ieee80211_bss_info_change_notify(sdata, changed);
@@ -1336,7 +1351,7 @@ static int ieee80211_vif_use_reserved_sw
sdata->reserved_chandef.width)
changed = BSS_CHANGED_BANDWIDTH;
- sdata->vif.bss_conf.chandef = sdata->reserved_chandef;
+ ieee80211_vif_update_chandef(sdata, &sdata->reserved_chandef);
if (changed)
ieee80211_bss_info_change_notify(sdata,
changed);
@@ -1507,7 +1522,7 @@ int ieee80211_vif_use_channel(struct iee
goto out;
}
- sdata->vif.bss_conf.chandef = *chandef;
+ ieee80211_vif_update_chandef(sdata, chandef);
ret = ieee80211_assign_vif_chanctx(sdata, ctx);
if (ret) {
@@ -1649,7 +1664,7 @@ int ieee80211_vif_change_bandwidth(struc
break;
}
- sdata->vif.bss_conf.chandef = *chandef;
+ ieee80211_vif_update_chandef(sdata, chandef);
ieee80211_recalc_chanctx_chantype(local, ctx);
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -520,6 +520,7 @@ int ieee80211_do_open(struct wireless_de
sdata->vif.cab_queue = master->vif.cab_queue;
memcpy(sdata->vif.hw_queue, master->vif.hw_queue,
sizeof(sdata->vif.hw_queue));
+ sdata->vif.bss_conf.chandef = master->vif.bss_conf.chandef;
break;
}
case NL80211_IFTYPE_AP:

View file

@ -1,31 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 30 Nov 2014 20:30:46 +0100
Subject: [PATCH] ath9k_hw: fix hardware queue allocation
The driver passes the desired hardware queue index for a WMM data queue
in qinfo->tqi_subtype. This was ignored in ath9k_hw_setuptxqueue, which
instead relied on the order in which the function is called.
Cc: stable@vger.kernel.org
Reported-by: Hubert Feurstein <h.feurstein@gmail.com>
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -311,14 +311,7 @@ int ath9k_hw_setuptxqueue(struct ath_hw
q = ATH9K_NUM_TX_QUEUES - 3;
break;
case ATH9K_TX_QUEUE_DATA:
- for (q = 0; q < ATH9K_NUM_TX_QUEUES; q++)
- if (ah->txq[q].tqi_type ==
- ATH9K_TX_QUEUE_INACTIVE)
- break;
- if (q == ATH9K_NUM_TX_QUEUES) {
- ath_err(common, "No available TX queue\n");
- return -1;
- }
+ q = qinfo->tqi_subtype;
break;
default:
ath_err(common, "Invalid TX queue type: %u\n", type);

View file

@ -1,24 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 30 Nov 2014 20:34:16 +0100
Subject: [PATCH] ath9k: fix BE/BK queue order
Hardware queues are ordered by priority. Use queue index 0 for BK, which
has lower priority than BE.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -217,8 +217,8 @@
#define AH_WOW_BEACON_MISS BIT(3)
enum ath_hw_txq_subtype {
- ATH_TXQ_AC_BE = 0,
- ATH_TXQ_AC_BK = 1,
+ ATH_TXQ_AC_BK = 0,
+ ATH_TXQ_AC_BE = 1,
ATH_TXQ_AC_VI = 2,
ATH_TXQ_AC_VO = 3,
};

View file

@ -1,29 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 30 Nov 2014 21:51:12 +0100
Subject: [PATCH] ath5k: fix hardware queue index assignment
Like with ath9k, ath5k queues also need to be ordered by priority.
queue_info->tqi_subtype already contains the correct index, so use it
instead of relying on the order of ath5k_hw_setup_tx_queue calls.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath5k/qcu.c
+++ b/drivers/net/wireless/ath/ath5k/qcu.c
@@ -225,13 +225,7 @@ ath5k_hw_setup_tx_queue(struct ath5k_hw
} else {
switch (queue_type) {
case AR5K_TX_QUEUE_DATA:
- for (queue = AR5K_TX_QUEUE_ID_DATA_MIN;
- ah->ah_txq[queue].tqi_type !=
- AR5K_TX_QUEUE_INACTIVE; queue++) {
-
- if (queue > AR5K_TX_QUEUE_ID_DATA_MAX)
- return -EINVAL;
- }
+ queue = queue_info->tqi_subtype;
break;
case AR5K_TX_QUEUE_UAPSD:
queue = AR5K_TX_QUEUE_ID_UAPSD;

View file

@ -1,30 +0,0 @@
From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Date: Tue, 16 Dec 2014 09:52:59 +0100
Subject: [PATCH] ath10k: fix low TX rates when IBSS and HT
This fix TX problem when IBSS used in HT mode.
Before we used 6Mbps all the time for TX direction.
Reported-by: Yeoh Chun-Yeow <yeohchunyeow@gmail.com>
Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
---
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1375,9 +1375,16 @@ static void ath10k_peer_assoc_h_qos(stru
if (vif->bss_conf.qos)
arg->peer_flags |= WMI_PEER_QOS;
break;
+ case WMI_VDEV_TYPE_IBSS:
+ if (sta->wme)
+ arg->peer_flags |= WMI_PEER_QOS;
+ break;
default:
break;
}
+
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac peer %pM qos %d\n",
+ sta->addr, !!(arg->peer_flags & WMI_PEER_QOS));
}
static void ath10k_peer_assoc_h_phymode(struct ath10k *ar,

View file

@ -1,26 +0,0 @@
From: Janusz Dziedzic <janusz.dziedzic@tieto.com>
Date: Tue, 16 Dec 2014 09:53:00 +0100
Subject: [PATCH] ath10k: send (re)assoc peer command when NSS changed
Assoc peer command contain information about NSS.
When we will get IEEE80211_RC_NSS_CHANGED we should
also send (re) assoc peer command to be sure firmware
will know about it and RC will work correctly.
Signed-off-by: Janusz Dziedzic <janusz.dziedzic@tieto.com>
---
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3497,8 +3497,9 @@ static void ath10k_sta_rc_update_wk(stru
sta->addr, smps, err);
}
- if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) {
- ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates\n",
+ if (changed & IEEE80211_RC_SUPP_RATES_CHANGED ||
+ changed & IEEE80211_RC_NSS_CHANGED) {
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac update sta %pM supp rates/nss\n",
sta->addr);
err = ath10k_station_assoc(ar, arvif->vif, sta, true);

View file

@ -1,53 +0,0 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Wed, 14 Jan 2015 14:13:15 +0100
Subject: [PATCH] ath9k: fix race condition in irq processing during hardware
reset
To fix invalid hardware accesses, the commit
"ath9k: do not access hardware on IRQs during reset" made the irq
handler ignore interrupts emitted after queueing a hardware reset (which
disables the IRQ). This left a small time window for the IRQ to get
re-enabled by the tasklet, which caused IRQ storms.
Instead of returning IRQ_NONE when ATH_OP_HW_RESET is set, disable the
IRQ entirely for the duration of the reset.
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
---
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -285,6 +285,7 @@ static int ath_reset_internal(struct ath
__ath_cancel_work(sc);
+ disable_irq(sc->irq);
tasklet_disable(&sc->intr_tq);
tasklet_disable(&sc->bcon_tasklet);
spin_lock_bh(&sc->sc_pcu_lock);
@@ -331,6 +332,7 @@ static int ath_reset_internal(struct ath
r = -EIO;
out:
+ enable_irq(sc->irq);
spin_unlock_bh(&sc->sc_pcu_lock);
tasklet_enable(&sc->bcon_tasklet);
tasklet_enable(&sc->intr_tq);
@@ -512,9 +514,6 @@ irqreturn_t ath_isr(int irq, void *dev)
if (!ah || test_bit(ATH_OP_INVALID, &common->op_flags))
return IRQ_NONE;
- if (!AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
- return IRQ_NONE;
-
/* shared irq, not for us */
if (!ath9k_hw_intrpend(ah))
return IRQ_NONE;
@@ -529,7 +528,7 @@ irqreturn_t ath_isr(int irq, void *dev)
ath9k_debug_sync_cause(sc, sync_cause);
status &= ah->imask; /* discard unasked-for bits */
- if (AR_SREV_9100(ah) && test_bit(ATH_OP_HW_RESET, &common->op_flags))
+ if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
return IRQ_HANDLED;
/*

View file

@ -1,45 +0,0 @@
From: Sergey Ryazanov <ryazanov.s.a@gmail.com>
Date: Tue, 3 Feb 2015 22:37:26 +0300
Subject: [PATCH] ath5k: fix spontaneus AR5312 freezes
Sometimes while CPU have some load and ath5k doing the wireless
interface reset the whole WiSoC completely freezes. Set of tests shows
that using atomic delay function while we wait interface reset helps to
avoid such freezes.
The easiest way to reproduce this issue: create a station interface,
start continous scan with wpa_supplicant and load CPU by something. Or
just create multiple station interfaces and put them all in continous
scan.
This patch partially reverts the commit 1846ac3dbec0 ("ath5k: Use
usleep_range where possible"), which replaces initial udelay()
by usleep_range().
I do not know actual source of this issue, but all looks like that HW
freeze is caused by transaction on internal SoC bus, while wireless
block is in reset state.
Also I should note that I do not know how many chips are affected, but I
did not see this issue with chips, other than AR5312.
CC: Jiri Slaby <jirislaby@gmail.com>
CC: Nick Kossifidis <mickflemm@gmail.com>
CC: Luis R. Rodriguez <mcgrof@do-not-panic.com>
Fixes: 1846ac3dbec0 ("ath5k: Use usleep_range where possible")
Reported-by: Christophe Prevotaux <c.prevotaux@rural-networks.com>
Tested-by: Christophe Prevotaux <c.prevotaux@rural-networks.com>
Tested-by: Eric Bree <ebree@nltinc.com>
Signed-off-by: Sergey Ryazanov <ryazanov.s.a@gmail.com>
---
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -478,7 +478,7 @@ ath5k_hw_wisoc_reset(struct ath5k_hw *ah
regval = ioread32(reg);
iowrite32(regval | val, reg);
regval = ioread32(reg);
- usleep_range(100, 150);
+ udelay(100); /* NB: should be atomic */
/* Bring BB/MAC out of reset */
iowrite32(regval & ~val, reg);

View file

@ -14,7 +14,7 @@
ccflags-y += -D__CHECK_ENDIAN__
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -301,13 +301,6 @@ void _ath_dbg(struct ath_common *common,
@@ -313,13 +313,6 @@ void _ath_dbg(struct ath_common *common,
#endif /* CPTCFG_ATH_DEBUG */
/** Returns string describing opmode, or NULL if unknown mode. */

View file

@ -4,8 +4,8 @@
module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
-int led_blink;
+int led_blink = 1;
module_param_named(blink, led_blink, int, 0444);
-int ath9k_led_blink;
+int ath9k_led_blink = 1;
module_param_named(blink, ath9k_led_blink, int, 0444);
MODULE_PARM_DESC(blink, "Enable LED blink on activity");

View file

@ -59,7 +59,7 @@
---help---
--- a/.local-symbols
+++ b/.local-symbols
@@ -116,6 +116,7 @@ RTL8187_LEDS=
@@ -89,6 +89,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
@@ -2112,6 +2112,8 @@ void regulatory_hint_country_ie(struct w
@@ -2368,6 +2368,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;
@@ -2308,6 +2310,7 @@ static void restore_regulatory_settings(
@@ -2571,6 +2573,7 @@ static void restore_regulatory_settings(
void regulatory_hint_disconnect(void)
{

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -684,6 +684,7 @@ static const struct ieee80211_iface_limi
@@ -704,6 +704,7 @@ static const struct ieee80211_iface_limi
BIT(NL80211_IFTYPE_AP) },
{ .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) },

View file

@ -18,7 +18,7 @@
goto end;
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1962,7 +1962,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
@@ -1965,7 +1965,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
}
if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
@ -27,7 +27,7 @@
ah->opmode == NL80211_IFTYPE_MESH_POINT) {
u64 tsf = ath5k_hw_get_tsf64(ah);
u32 tsftu = TSF_TO_TU(tsf);
@@ -2048,7 +2048,7 @@ ath5k_beacon_update_timers(struct ath5k_
@@ -2051,7 +2051,7 @@ ath5k_beacon_update_timers(struct ath5k_
intval = ah->bintval & AR5K_BEACON_PERIOD;
if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs
@ -36,7 +36,7 @@
intval /= ATH_BCBUF; /* staggered multi-bss beacons */
if (intval < 15)
ATH5K_WARN(ah, "intval %u is too low, min 15\n",
@@ -2515,6 +2515,7 @@ static const struct ieee80211_iface_limi
@@ -2518,6 +2518,7 @@ static const struct ieee80211_iface_limi
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_AP) },

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 {
@@ -1371,6 +1371,7 @@ struct ath5k_hw {
u8 ah_coverage_class;
bool ah_ack_bitrate_high;
u8 ah_bwmode;

View file

@ -1,7 +1,7 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1314,6 +1314,53 @@ void ath9k_deinit_debug(struct ath_softc
ath9k_spectral_deinit_debug(sc);
@@ -1299,6 +1299,53 @@ void ath9k_deinit_debug(struct ath_softc
ath9k_cmn_spectral_deinit_debug(&sc->spec_priv);
}
+static ssize_t read_file_eeprom(struct file *file, char __user *user_buf,
@ -54,12 +54,12 @@
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -1333,6 +1380,8 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1318,6 +1365,8 @@ int ath9k_init_debug(struct ath_hw *ah)
ath9k_tx99_init_debug(sc);
ath9k_spectral_init_debug(sc);
ath9k_cmn_spectral_init_debug(&sc->spec_priv, sc->debug.debugfs_phy);
+ debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
+ &fops_eeprom);
debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_dma);
debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
read_file_dma);
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,

View file

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

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -356,13 +356,8 @@ static void ath9k_hw_init_config(struct
@@ -358,13 +358,8 @@ static void ath9k_hw_init_config(struct
ah->config.rx_intr_mitigation = true;

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/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1361,6 +1361,52 @@ static const struct file_operations fops
@@ -1346,6 +1346,52 @@ static const struct file_operations fops
.owner = THIS_MODULE
};
@ -53,18 +53,18 @@
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -1382,6 +1428,8 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1367,6 +1413,8 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_file("eeprom", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_eeprom);
+ debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_chanbw);
debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_dma);
debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
read_file_dma);
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -142,6 +142,7 @@ struct ath_common {
@@ -148,6 +148,7 @@ struct ath_common {
int debug_mask;
enum ath_device_state state;
unsigned long op_flags;

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -611,6 +611,7 @@ int ath9k_hw_init(struct ath_hw *ah)
@@ -616,6 +616,7 @@ int ath9k_hw_init(struct ath_hw *ah)
/* These are all the AR5008/AR9001/AR9002/AR9003 hardware family of chipsets */
switch (ah->hw_version.devid) {
@ -10,7 +10,7 @@
case AR5416_AR9100_DEVID:
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -35,6 +35,7 @@
@@ -36,6 +36,7 @@
#define ATHEROS_VENDOR_ID 0x168c
@ -20,7 +20,7 @@
#define AR9160_DEVID_PCI 0x0027
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -664,6 +664,7 @@ static const struct pci_device_id ath_pc
@@ -751,6 +751,7 @@ static const struct pci_device_id ath_pc
.driver_data = ATH9K_PCI_BT_ANT_DIV },
#endif

View file

@ -1,6 +1,6 @@
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -2245,6 +2245,7 @@ struct cfg80211_qos_map {
@@ -2320,6 +2320,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
*
@@ -2495,6 +2496,7 @@ struct cfg80211_ops {
@@ -2576,6 +2577,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
@@ -1078,6 +1078,7 @@ enum ieee80211_smps_mode {
@@ -1138,6 +1138,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,7 +26,7 @@
*
* @chandef: the channel definition to tune to
* @radar_enabled: whether radar detection is enabled
@@ -1099,6 +1100,7 @@ struct ieee80211_conf {
@@ -1159,6 +1160,7 @@ struct ieee80211_conf {
u32 flags;
int power_level, dynamic_ps_timeout;
int max_sleep_period;
@ -36,19 +36,19 @@
u8 ps_dtim_period;
--- a/include/uapi/linux/nl80211.h
+++ b/include/uapi/linux/nl80211.h
@@ -1656,6 +1656,9 @@ enum nl80211_commands {
* @NL80211_ATTR_SMPS_MODE: SMPS mode to use (ap mode). see
* &enum nl80211_smps_mode.
@@ -1760,6 +1760,9 @@ enum nl80211_commands {
* @NL80211_ATTR_REG_INDOOR: flag attribute, if set indicates that the device
* is operating in an indoor environment.
*
+ * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce
+ * transmit power to stay within regulatory limits. u32, dBi.
+ *
* @NUM_NL80211_ATTR: total number of nl80211_attrs available
* @NL80211_ATTR_MAX: highest attribute number currently defined
* @__NL80211_ATTR_AFTER_LAST: internal use
*/
@@ -2008,6 +2011,8 @@ enum nl80211_attrs {
@@ -2129,6 +2132,8 @@ enum nl80211_attrs {
NL80211_ATTR_SMPS_MODE,
NL80211_ATTR_REG_INDOOR,
+ NL80211_ATTR_WIPHY_ANTENNA_GAIN,
+
@ -57,7 +57,7 @@
__NL80211_ATTR_AFTER_LAST,
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -2155,6 +2155,19 @@ static int ieee80211_get_tx_power(struct
@@ -2208,6 +2208,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)
{
@@ -3723,6 +3736,7 @@ const struct cfg80211_ops mac80211_confi
@@ -3771,6 +3784,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
@@ -1339,6 +1339,7 @@ struct ieee80211_local {
@@ -1330,6 +1330,7 @@ struct ieee80211_local {
int dynamic_ps_forced_timeout;
int user_power_level; /* in dBm, for all interfaces */
@ -129,15 +129,15 @@
local->user_power_level = IEEE80211_UNSET_POWER_LEVEL;
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -395,6 +395,7 @@ static const struct nla_policy nl80211_p
[NL80211_ATTR_USER_PRIO] = { .type = NLA_U8 },
[NL80211_ATTR_ADMITTED_TIME] = { .type = NLA_U16 },
[NL80211_ATTR_SMPS_MODE] = { .type = NLA_U8 },
@@ -400,6 +400,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 },
+ [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 },
};
/* policy for the key attributes */
@@ -2184,6 +2185,20 @@ static int nl80211_set_wiphy(struct sk_b
@@ -2207,6 +2208,20 @@ static int nl80211_set_wiphy(struct sk_b
return result;
}

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -812,6 +812,9 @@ static inline int ath9k_dump_btcoex(stru
@@ -814,6 +814,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)
{
@@ -952,6 +955,13 @@ void ath_ant_comb_scan(struct ath_softc
@@ -953,6 +956,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;
@@ -1003,9 +1013,8 @@ struct ath_softc {
@@ -1004,9 +1014,8 @@ struct ath_softc {
spinlock_t chan_lock;
#ifdef CPTCFG_MAC80211_LEDS
@ -38,15 +38,17 @@
#ifdef CPTCFG_ATH9K_DEBUGFS
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -24,40 +24,102 @@
@@ -24,45 +24,102 @@
static void ath_led_brightness(struct led_classdev *led_cdev,
enum led_brightness brightness)
{
- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, (brightness == LED_OFF));
- u32 val = (brightness == LED_OFF);
+ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev);
+ struct ath_softc *sc = led->sc;
+
- if (sc->sc_ah->config.led_active_high)
- val = !val;
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio,
+ (brightness != LED_OFF) ^ led->gpio->active_low);
@ -78,7 +80,8 @@
+
+ return 0;
+}
+
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val);
+int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name,
+ const char *trigger, bool active_low)
+{
@ -136,7 +139,7 @@
if (AR_SREV_9100(sc->sc_ah))
return;
- if (!led_blink)
- if (!ath9k_led_blink)
- sc->led_cdev.default_trigger =
- ieee80211_get_radio_led_name(sc->hw);
-
@ -150,7 +153,7 @@
- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
- if (ret < 0)
- return;
+ if (led_blink)
+ if (ath9k_led_blink)
+ trigger = sc->led_default_trigger;
+ else
+ trigger = ieee80211_get_radio_led_name(sc->hw);
@ -162,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
@@ -903,7 +903,7 @@ int ath9k_init_device(u16 devid, struct
@@ -924,7 +924,7 @@ int ath9k_init_device(u16 devid, struct
#ifdef CPTCFG_MAC80211_LEDS
/* must be initialized before ieee80211_register_hw */
@ -173,7 +176,7 @@
#endif
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1406,6 +1406,61 @@ static const struct file_operations fops
@@ -1391,6 +1391,61 @@ static const struct file_operations fops
.llseek = default_llseek,
};
@ -235,7 +238,7 @@
int ath9k_init_debug(struct ath_hw *ah)
{
@@ -1430,6 +1485,10 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1415,6 +1470,10 @@ int ath9k_init_debug(struct ath_hw *ah)
&fops_eeprom);
debugfs_create_file("chanbw", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
sc, &fops_chanbw);
@ -243,6 +246,6 @@
+ debugfs_create_file("gpio_led", S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_gpio_led);
+#endif
debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_dma);
debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
read_file_dma);
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1462,6 +1462,50 @@ static const struct file_operations fops
@@ -1447,6 +1447,50 @@ static const struct file_operations fops
#endif
@ -51,18 +51,18 @@
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -1489,6 +1533,8 @@ int ath9k_init_debug(struct ath_hw *ah)
@@ -1474,6 +1518,8 @@ int ath9k_init_debug(struct ath_hw *ah)
debugfs_create_file("gpio_led", S_IWUSR,
sc->debug.debugfs_phy, sc, &fops_gpio_led);
#endif
+ debugfs_create_file("diag", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
+ sc, &fops_diag);
debugfs_create_file("dma", S_IRUSR, sc->debug.debugfs_phy, sc,
&fops_dma);
debugfs_create_file("interrupt", S_IRUSR, sc->debug.debugfs_phy, sc,
debugfs_create_devm_seqfile(sc->dev, "dma", sc->debug.debugfs_phy,
read_file_dma);
debugfs_create_devm_seqfile(sc->dev, "interrupt", sc->debug.debugfs_phy,
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -490,6 +490,12 @@ enum {
@@ -499,6 +499,12 @@ enum {
ATH9K_RESET_COLD,
};
@ -75,7 +75,7 @@
struct ath9k_hw_version {
u32 magic;
u16 devid;
@@ -769,6 +775,8 @@ struct ath_hw {
@@ -780,6 +786,8 @@ struct ath_hw {
u32 rfkill_polarity;
u32 ah_flags;
@ -84,7 +84,7 @@
bool reset_power_on;
bool htc_reset_init;
@@ -1025,6 +1033,7 @@ void ath9k_hw_check_nav(struct ath_hw *a
@@ -1040,6 +1048,7 @@ void ath9k_hw_check_nav(struct ath_hw *a
bool ath9k_hw_check_alive(struct ath_hw *ah);
bool ath9k_hw_setpower(struct ath_hw *ah, enum ath9k_power_mode mode);
@ -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
@@ -1753,6 +1753,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
@@ -1771,6 +1771,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)
{
@@ -1957,6 +1971,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
@@ -1977,6 +1991,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
ar9003_hw_disable_phy_restart(ah);
ath9k_hw_apply_gpio_override(ah);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -686,6 +686,7 @@ struct ath_spec_scan {
@@ -696,6 +696,7 @@ struct ath_spec_scan {
* @config_pci_powersave:
* @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
*
@ -8,7 +8,7 @@
* @spectral_scan_config: set parameters for spectral scan and enable/disable it
* @spectral_scan_trigger: trigger a spectral scan run
* @spectral_scan_wait: wait for a spectral scan run to finish
@@ -708,6 +709,7 @@ struct ath_hw_ops {
@@ -718,6 +719,7 @@ struct ath_hw_ops {
struct ath_hw_antcomb_conf *antconf);
void (*antdiv_comb_conf_set)(struct ath_hw *ah,
struct ath_hw_antcomb_conf *antconf);
@ -18,8 +18,8 @@
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
@@ -1799,6 +1799,26 @@ static void ar9003_hw_tx99_set_txpower(s
ATH9K_POW_SM(p_pwr_array[ALL_TARGET_HT40_14], 0));
@@ -1999,6 +1999,26 @@ void ar9003_hw_init_rate_txpower(struct
}
}
+static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
@ -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);
@@ -1834,6 +1854,7 @@ void ar9003_hw_attach_phy_ops(struct ath
@@ -2035,6 +2055,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;
@ -55,7 +55,7 @@
ops->spectral_scan_config = ar9003_hw_spectral_scan_config;
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -672,7 +672,8 @@ static void ath9k_init_txpower_limits(st
@@ -692,7 +692,8 @@ static void ath9k_init_txpower_limits(st
if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
ath9k_init_band_txpower(sc, IEEE80211_BAND_5GHZ);
@ -65,7 +65,7 @@
}
static const struct ieee80211_iface_limit if_limits[] = {
@@ -863,6 +864,18 @@ static void ath9k_set_hw_capab(struct at
@@ -884,6 +885,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)
{
@@ -908,6 +921,8 @@ int ath9k_init_device(u16 devid, struct
@@ -929,6 +942,8 @@ int ath9k_init_device(u16 devid, struct
ARRAY_SIZE(ath9k_tpt_blink));
#endif
@ -110,8 +110,8 @@
static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -1235,9 +1235,30 @@ static void ar5008_hw_set_radar_conf(str
conf->radar_inband = 8;
@@ -1315,9 +1315,30 @@ void ar5008_hw_init_rate_txpower(struct
}
}
+static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
@ -141,7 +141,7 @@
static const u32 ar5416_cca_regs[6] = {
AR_PHY_CCA,
AR_PHY_CH1_CCA,
@@ -1252,6 +1273,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
@@ -1332,6 +1353,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
if (ret)
return ret;

View file

@ -20,7 +20,7 @@
/******************/
/* Chip Revisions */
/******************/
@@ -1338,6 +1351,9 @@ static bool ath9k_hw_set_reset(struct at
@@ -1349,6 +1362,9 @@ static bool ath9k_hw_set_reset(struct at
if (AR_SREV_9100(ah))
udelay(50);
@ -30,7 +30,7 @@
return true;
}
@@ -1437,6 +1453,9 @@ static bool ath9k_hw_chip_reset(struct a
@@ -1448,6 +1464,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;
}
@@ -1731,8 +1750,14 @@ static int ath9k_hw_do_fastcc(struct ath
@@ -1749,8 +1768,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;
}
@@ -1982,6 +2007,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
@@ -2002,6 +2027,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
ath9k_hw_set_radar_params(ah);
}

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -929,55 +929,6 @@ static bool ar5008_hw_ani_control_new(st
@@ -944,55 +944,6 @@ static bool ar5008_hw_ani_control_new(st
* on == 0 means more noise imm
*/
u32 on = param ? 1 : 0;
@ -58,7 +58,7 @@
REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -26,20 +26,6 @@ static const int cycpwrThr1_table[] =
@@ -41,20 +41,6 @@ static const int cycpwrThr1_table[] =
/* level: 0 1 2 3 4 5 6 7 8 */
{ -6, -4, -2, 0, 2, 4, 6, 8 }; /* lvl 0-7, default 3 */
@ -76,10 +76,10 @@
-static const int m1ThreshExt_off = 127;
-static const int m2ThreshExt_off = 127;
-
/**
* ar9003_hw_set_channel - set channel on single-chip device
* @ah: atheros hardware structure
@@ -984,11 +970,6 @@ static bool ar9003_hw_ani_control(struct
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
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) {
@@ -1002,61 +983,6 @@ static bool ar9003_hw_ani_control(struct
@@ -1108,61 +1089,6 @@ static bool ar9003_hw_ani_control(struct
*/
u32 on = param ? 1 : 0;

View file

@ -24,7 +24,7 @@ Changes since v1:
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7740,6 +7740,7 @@ static int rt2800_probe_rt(struct rt2x00
@@ -7747,6 +7747,7 @@ static int rt2800_probe_rt(struct rt2x00
int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
{
@ -32,7 +32,7 @@ Changes since v1:
int retval;
u32 reg;
@@ -7747,6 +7748,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
@@ -7754,6 +7755,9 @@ int rt2800_probe_hw(struct rt2x00_dev *r
if (retval)
return retval;

View file

@ -187,7 +187,7 @@ Changes since v1: ---
}
/*
@@ -4901,14 +4934,19 @@ static int rt2800_init_registers(struct
@@ -4908,14 +4941,19 @@ static int rt2800_init_registers(struct
/*
* ASIC will keep garbage value after boot, clear encryption keys.
*/
@ -207,7 +207,7 @@ Changes since v1: ---
}
/*
@@ -5034,8 +5072,10 @@ static int rt2800_wait_bbp_ready(struct
@@ -5041,8 +5079,10 @@ static int rt2800_wait_bbp_ready(struct
* BBP was enabled after firmware was loaded,
* but we need to reactivate it now.
*/
@ -218,7 +218,7 @@ Changes since v1: ---
msleep(1);
for (i = 0; i < REGISTER_BUSY_COUNT; i++) {
@@ -6731,11 +6771,19 @@ int rt2800_enable_radio(struct rt2x00_de
@@ -6738,11 +6778,19 @@ int rt2800_enable_radio(struct rt2x00_de
/*
* Send signal during boot time to initialize firmware.
*/
@ -239,7 +239,7 @@ Changes since v1: ---
msleep(1);
/*
@@ -7744,6 +7792,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
@@ -7751,6 +7799,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
int retval;
u32 reg;
@ -248,7 +248,7 @@ Changes since v1: ---
retval = rt2800_probe_rt(rt2x00dev);
if (retval)
return retval;
@@ -7823,8 +7873,11 @@ void rt2800_get_tkip_seq(struct ieee8021
@@ -7830,8 +7880,11 @@ void rt2800_get_tkip_seq(struct ieee8021
u32 offset;
offset = MAC_IVEIV_ENTRY(hw_key_idx);

View file

@ -24,7 +24,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4631,6 +4631,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
@@ -4638,6 +4638,7 @@ EXPORT_SYMBOL_GPL(rt2800_link_tuner);
*/
static int rt2800_init_registers(struct rt2x00_dev *rt2x00dev)
{
@ -32,7 +32,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
u32 reg;
u16 eeprom;
unsigned int i;
@@ -4996,7 +4997,7 @@ static int rt2800_init_registers(struct
@@ -5003,7 +5004,7 @@ static int rt2800_init_registers(struct
/*
* Clear all beacons
*/
@ -41,7 +41,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
rt2800_clear_beacon_register(rt2x00dev, i);
if (rt2x00_is_usb(rt2x00dev)) {
@@ -7845,6 +7846,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
@@ -7852,6 +7853,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
if (rt2x00_rt(rt2x00dev, RT3593))
__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);

View file

@ -34,7 +34,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
*/
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4643,6 +4643,30 @@ static int rt2800_init_registers(struct
@@ -4650,6 +4650,30 @@ static int rt2800_init_registers(struct
if (ret)
return ret;

View file

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7870,7 +7870,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r
@@ -7877,7 +7877,10 @@ int rt2800_probe_hw(struct rt2x00_dev *r
if (rt2x00_rt(rt2x00dev, RT3593))
__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);

View file

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7840,6 +7840,7 @@ static int rt2800_probe_rt(struct rt2x00
@@ -7847,6 +7847,7 @@ static int rt2800_probe_rt(struct rt2x00
case RT3390:
case RT3572:
case RT3593:

View file

@ -31,7 +31,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
#define RF5370 0x5370
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7458,6 +7458,66 @@ static const struct rf_channel rf_vals_3
@@ -7465,6 +7465,66 @@ static const struct rf_channel rf_vals_3
{173, 0x61, 0, 9},
};
@ -98,7 +98,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
static const struct rf_channel rf_vals_5592_xtal20[] = {
/* Channel, N, K, mod, R */
{1, 482, 4, 10, 3},
@@ -7687,6 +7747,11 @@ static int rt2800_probe_hw_mode(struct r
@@ -7694,6 +7754,11 @@ static int rt2800_probe_hw_mode(struct r
spec->channels = rf_vals_3x;
break;

View file

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4395,6 +4395,7 @@ void rt2800_vco_calibration(struct rt2x0
@@ -4402,6 +4402,7 @@ void rt2800_vco_calibration(struct rt2x0
case RF3053:
case RF3070:
case RF3290:
@ -18,7 +18,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
case RF5360:
case RF5362:
case RF5370:
@@ -7866,6 +7867,7 @@ static int rt2800_probe_hw_mode(struct r
@@ -7873,6 +7874,7 @@ static int rt2800_probe_hw_mode(struct r
case RF3053:
case RF3070:
case RF3290:

View file

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7423,6 +7423,7 @@ static int rt2800_init_eeprom(struct rt2
@@ -7430,6 +7430,7 @@ static int rt2800_init_eeprom(struct rt2
case RF3290:
case RF3320:
case RF3322:

View file

@ -35,7 +35,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
#define RX_FILTER_CFG 0x1400
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4998,6 +4998,12 @@ static int rt2800_init_registers(struct
@@ -5005,6 +5005,12 @@ static int rt2800_init_registers(struct
rt2800_register_write(rt2x00dev, TX_SW_CFG2,
0x00000000);
}
@ -48,7 +48,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
} else if (rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392) ||
rt2x00_rt(rt2x00dev, RT5592)) {
@@ -5028,9 +5034,11 @@ static int rt2800_init_registers(struct
@@ -5035,9 +5041,11 @@ static int rt2800_init_registers(struct
rt2800_register_read(rt2x00dev, MAX_LEN_CFG, &reg);
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_MPDU, AGGREGATION_SIZE);
@ -63,7 +63,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 2);
else
rt2x00_set_field32(&reg, MAX_LEN_CFG_MAX_PSDU, 1);
@@ -5183,6 +5191,11 @@ static int rt2800_init_registers(struct
@@ -5190,6 +5198,11 @@ static int rt2800_init_registers(struct
reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002;
rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg);

View file

@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -5801,6 +5801,47 @@ static void rt2800_init_bbp_3593(struct
@@ -5808,6 +5808,47 @@ static void rt2800_init_bbp_3593(struct
rt2800_bbp_write(rt2x00dev, 103, 0xc0);
}
@ -59,7 +59,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev)
{
int ant, div_mode;
@@ -6019,6 +6060,9 @@ static void rt2800_init_bbp(struct rt2x0
@@ -6026,6 +6067,9 @@ static void rt2800_init_bbp(struct rt2x0
case RT3593:
rt2800_init_bbp_3593(rt2x00dev);
return;

View file

@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
/*
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -6836,6 +6836,144 @@ static void rt2800_init_rfcsr_3593(struc
@@ -6843,6 +6843,144 @@ static void rt2800_init_rfcsr_3593(struc
/* TODO: enable stream mode support */
}
@ -166,7 +166,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
{
rt2800_rf_init_calibration(rt2x00dev, 2);
@@ -7067,6 +7205,9 @@ static void rt2800_init_rfcsr(struct rt2
@@ -7074,6 +7212,9 @@ static void rt2800_init_rfcsr(struct rt2
case RT3390:
rt2800_init_rfcsr_3390(rt2x00dev);
break;

View file

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7604,6 +7604,8 @@ static int rt2800_init_eeprom(struct rt2
@@ -7611,6 +7611,8 @@ static int rt2800_init_eeprom(struct rt2
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);

View file

@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4628,7 +4628,8 @@ static void rt2800_config_txpower(struct
@@ -4635,7 +4635,8 @@ static void rt2800_config_txpower(struct
struct ieee80211_channel *chan,
int power_level)
{

View file

@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7486,7 +7486,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
@@ -7493,7 +7493,8 @@ static u8 rt2800_get_txmixer_gain_24g(st
{
u16 word;
@ -21,7 +21,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
return 0;
rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG, &word);
@@ -7500,7 +7501,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
@@ -7507,7 +7508,8 @@ static u8 rt2800_get_txmixer_gain_5g(str
{
u16 word;

View file

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -8421,7 +8421,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
@@ -8428,7 +8428,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
if (rt2x00_rt(rt2x00dev, RT3593))
__set_bit(RT2800_HAS_HIGH_SHARED_MEM, &drv_data->rt2800_flags);

View file

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -4828,7 +4828,8 @@ static u8 rt2800_get_default_vgc(struct
@@ -4835,7 +4835,8 @@ static u8 rt2800_get_default_vgc(struct
else
vgc = 0x2e + rt2x00dev->lna_gain;
} else { /* 5GHZ band */
@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3;
else if (rt2x00_rt(rt2x00dev, RT5592))
vgc = 0x24 + (2 * rt2x00dev->lna_gain);
@@ -4848,7 +4849,8 @@ static inline void rt2800_set_vgc(struct
@@ -4855,7 +4856,8 @@ static inline void rt2800_set_vgc(struct
{
if (qual->vgc_level != vgc_level) {
if (rt2x00_rt(rt2x00dev, RT3572) ||
@ -30,7 +30,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
rt2800_bbp_write_with_rx_chain(rt2x00dev, 66,
vgc_level);
} else if (rt2x00_rt(rt2x00dev, RT5592)) {
@@ -4895,6 +4897,11 @@ void rt2800_link_tuner(struct rt2x00_dev
@@ -4902,6 +4904,11 @@ void rt2800_link_tuner(struct rt2x00_dev
}
break;

View file

@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -7623,7 +7623,8 @@ static int rt2800_validate_eeprom(struct
@@ -7630,7 +7630,8 @@ static int rt2800_validate_eeprom(struct
rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0);
@ -20,7 +20,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 ||
rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff)
rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1,
@@ -7643,7 +7644,8 @@ static int rt2800_validate_eeprom(struct
@@ -7650,7 +7651,8 @@ static int rt2800_validate_eeprom(struct
rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2, &word);
if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10)
rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0);
@ -30,7 +30,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 ||
rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff)
rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2,
@@ -7651,7 +7653,8 @@ static int rt2800_validate_eeprom(struct
@@ -7658,7 +7660,8 @@ static int rt2800_validate_eeprom(struct
}
rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word);

View file

@ -11,7 +11,7 @@ Signed-off-by: Gabor Juhos <juhosg@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -8434,7 +8434,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
@@ -8441,7 +8441,8 @@ int rt2800_probe_hw(struct rt2x00_dev *r
if (retval)
return retval;

View file

@ -1,6 +1,6 @@
--- a/.local-symbols
+++ b/.local-symbols
@@ -289,6 +289,7 @@ RT2X00_LIB_FIRMWARE=
@@ -263,6 +263,7 @@ RT2X00_LIB_FIRMWARE=
RT2X00_LIB_CRYPTO=
RT2X00_LIB_LEDS=
RT2X00_LIB_DEBUGFS=
@ -28,13 +28,13 @@
---help---
@@ -266,6 +268,9 @@ config RT2X00_LIB_FIRMWARE
config RT2X00_LIB_CRYPTO
boolean
bool
+config RT2X00_LIB_EEPROM
+ boolean
+
config RT2X00_LIB_LEDS
boolean
bool
default y if (RT2X00_LIB=y && LEDS_CLASS=y) || (RT2X00_LIB=m && LEDS_CLASS!=n)
--- a/drivers/net/wireless/rt2x00/Makefile
+++ b/drivers/net/wireless/rt2x00/Makefile

View file

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

View file

@ -19,7 +19,7 @@
} else if (rt2x00_rt(rt2x00dev, RT3593)) {
if (rf->channel > 14) {
/* Disable CCK Packet detection on 5GHz */
@@ -6611,6 +6618,12 @@ static void rt2800_init_rfcsr_3290(struc
@@ -6618,6 +6625,12 @@ static void rt2800_init_rfcsr_3290(struc
static void rt2800_init_rfcsr_3352(struct rt2x00_dev *rt2x00dev)
{
@ -32,7 +32,7 @@
rt2800_rf_init_calibration(rt2x00dev, 30);
rt2800_rfcsr_write(rt2x00dev, 0, 0xf0);
@@ -6646,15 +6659,30 @@ static void rt2800_init_rfcsr_3352(struc
@@ -6653,15 +6666,30 @@ static void rt2800_init_rfcsr_3352(struc
rt2800_rfcsr_write(rt2x00dev, 31, 0x80);
rt2800_rfcsr_write(rt2x00dev, 32, 0x80);
rt2800_rfcsr_write(rt2x00dev, 33, 0x00);
@ -66,7 +66,7 @@
rt2800_rfcsr_write(rt2x00dev, 43, 0xdb);
rt2800_rfcsr_write(rt2x00dev, 44, 0xdb);
rt2800_rfcsr_write(rt2x00dev, 45, 0xdb);
@@ -6662,15 +6690,20 @@ static void rt2800_init_rfcsr_3352(struc
@@ -6669,15 +6697,20 @@ static void rt2800_init_rfcsr_3352(struc
rt2800_rfcsr_write(rt2x00dev, 47, 0x0d);
rt2800_rfcsr_write(rt2x00dev, 48, 0x14);
rt2800_rfcsr_write(rt2x00dev, 49, 0x00);
@ -96,7 +96,7 @@
rt2800_rfcsr_write(rt2x00dev, 59, 0x00);
rt2800_rfcsr_write(rt2x00dev, 60, 0x00);
rt2800_rfcsr_write(rt2x00dev, 61, 0x00);
@@ -7691,6 +7724,7 @@ static int rt2800_init_eeprom(struct rt2
@@ -7698,6 +7731,7 @@ static int rt2800_init_eeprom(struct rt2
* RT53xx: defined in "EEPROM_CHIP_ID" field
*/
if (rt2x00_rt(rt2x00dev, RT3290) ||
@ -104,7 +104,7 @@
rt2x00_rt(rt2x00dev, RT5390) ||
rt2x00_rt(rt2x00dev, RT5392))
rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
@@ -7786,7 +7820,8 @@ static int rt2800_init_eeprom(struct rt2
@@ -7793,7 +7827,8 @@ static int rt2800_init_eeprom(struct rt2
/*
* Detect if this device has Bluetooth co-existence.
*/
@ -114,7 +114,7 @@
__set_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags);
/*
@@ -7815,6 +7850,22 @@ static int rt2800_init_eeprom(struct rt2
@@ -7822,6 +7857,22 @@ static int rt2800_init_eeprom(struct rt2
EIRP_MAX_TX_POWER_LIMIT)
__set_bit(CAPABILITY_POWER_LIMIT, &rt2x00dev->cap_flags);

View file

@ -1,6 +1,6 @@
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -8202,6 +8202,27 @@ static const struct rf_channel rf_vals_5
@@ -8209,6 +8209,27 @@ static const struct rf_channel rf_vals_5
{196, 83, 0, 12, 1},
};
@ -28,7 +28,7 @@
static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
{
struct hw_mode_spec *spec = &rt2x00dev->spec;
@@ -8290,7 +8311,10 @@ static int rt2800_probe_hw_mode(struct r
@@ -8297,7 +8318,10 @@ static int rt2800_probe_hw_mode(struct r
case RF5390:
case RF5392:
spec->num_channels = 14;
@ -40,7 +40,7 @@
break;
case RF3052:
@@ -8474,6 +8498,19 @@ static int rt2800_probe_rt(struct rt2x00
@@ -8481,6 +8505,19 @@ static int rt2800_probe_rt(struct rt2x00
return 0;
}
@ -60,7 +60,7 @@
int rt2800_probe_hw(struct rt2x00_dev *rt2x00dev)
{
struct rt2800_drv_data *drv_data = rt2x00dev->drv_data;
@@ -8516,6 +8553,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
@@ -8523,6 +8560,15 @@ int rt2800_probe_hw(struct rt2x00_dev *r
rt2800_register_write(rt2x00dev, GPIO_CTRL, reg);
/*

View file

@ -13,7 +13,7 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
--- a/drivers/net/wireless/rt2x00/rt2800soc.c
+++ b/drivers/net/wireless/rt2x00/rt2800soc.c
@@ -237,11 +237,18 @@ static int rt2800soc_probe(struct platfo
@@ -237,10 +237,17 @@ static int rt2800soc_probe(struct platfo
return rt2x00soc_probe(pdev, &rt2800soc_ops);
}
@ -26,7 +26,6 @@ Signed-off-by: John Crispin <blogic@openwrt.org>
static struct platform_driver rt2800soc_driver = {
.driver = {
.name = "rt2800_wmac",
.owner = THIS_MODULE,
.mod_name = KBUILD_MODNAME,
+ .of_match_table = rt2880_wmac_match,
},

View file

@ -8,7 +8,7 @@
#include "rt2x00.h"
#include "rt2800lib.h"
@@ -8500,13 +8501,14 @@ static int rt2800_probe_rt(struct rt2x00
@@ -8507,13 +8508,14 @@ static int rt2800_probe_rt(struct rt2x00
int rt2800_probe_clk(struct rt2x00_dev *rt2x00dev)
{

View file

@ -50,7 +50,7 @@
rt2800_bbp_read(rt2x00dev, 49, &bbp);
rt2x00_set_field8(&bbp, BBP49_UPDATE_FLAG, 0);
rt2800_bbp_write(rt2x00dev, 49, bbp);
@@ -4691,6 +4701,7 @@ void rt2800_vco_calibration(struct rt2x0
@@ -4698,6 +4708,7 @@ void rt2800_vco_calibration(struct rt2x0
case RF3070:
case RF3290:
case RF3853:
@ -58,7 +58,7 @@
case RF5360:
case RF5362:
case RF5370:
@@ -5104,6 +5115,8 @@ static int rt2800_init_registers(struct
@@ -5111,6 +5122,8 @@ static int rt2800_init_registers(struct
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000404);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000);
@ -67,7 +67,7 @@
} else {
rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000000);
rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00080606);
@@ -5759,9 +5772,13 @@ static void rt2800_init_bbp_3352(struct
@@ -5766,9 +5779,13 @@ static void rt2800_init_bbp_3352(struct
rt2800_bbp_write(rt2x00dev, 82, 0x62);
@ -84,7 +84,7 @@
rt2800_bbp_write(rt2x00dev, 86, 0x38);
@@ -5775,9 +5792,13 @@ static void rt2800_init_bbp_3352(struct
@@ -5782,9 +5799,13 @@ static void rt2800_init_bbp_3352(struct
rt2800_bbp_write(rt2x00dev, 104, 0x92);
@ -101,7 +101,7 @@
rt2800_bbp_write(rt2x00dev, 120, 0x50);
@@ -5802,6 +5823,13 @@ static void rt2800_init_bbp_3352(struct
@@ -5809,6 +5830,13 @@ static void rt2800_init_bbp_3352(struct
rt2800_bbp_write(rt2x00dev, 143, 0xa2);
rt2800_bbp_write(rt2x00dev, 148, 0xc8);
@ -115,7 +115,7 @@
}
static void rt2800_init_bbp_3390(struct rt2x00_dev *rt2x00dev)
@@ -6143,6 +6171,7 @@ static void rt2800_init_bbp(struct rt2x0
@@ -6150,6 +6178,7 @@ static void rt2800_init_bbp(struct rt2x0
rt2800_init_bbp_3290(rt2x00dev);
break;
case RT3352:
@ -123,7 +123,7 @@
rt2800_init_bbp_3352(rt2x00dev);
break;
case RT3390:
@@ -7094,6 +7123,76 @@ static void rt2800_init_rfcsr_3883(struc
@@ -7101,6 +7130,76 @@ static void rt2800_init_rfcsr_3883(struc
rt2800_rfcsr_write(rt2x00dev, 20, rfcsr);
}
@ -200,7 +200,7 @@
static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev)
{
rt2800_rf_init_calibration(rt2x00dev, 2);
@@ -7334,6 +7433,9 @@ static void rt2800_init_rfcsr(struct rt2
@@ -7341,6 +7440,9 @@ static void rt2800_init_rfcsr(struct rt2
case RT3593:
rt2800_init_rfcsr_3593(rt2x00dev);
break;
@ -210,7 +210,7 @@
case RT5390:
rt2800_init_rfcsr_5390(rt2x00dev);
break;
@@ -7593,6 +7695,12 @@ static int rt2800_validate_eeprom(struct
@@ -7600,6 +7702,12 @@ static int rt2800_validate_eeprom(struct
rt2x00_set_field16(&word, EEPROM_NIC_CONF0_RF_TYPE, RF2820);
rt2800_eeprom_write(rt2x00dev, EEPROM_NIC_CONF0, word);
rt2x00_eeprom_dbg(rt2x00dev, "Antenna: 0x%04x\n", word);
@ -223,7 +223,7 @@
} else if (rt2x00_rt(rt2x00dev, RT2860) ||
rt2x00_rt(rt2x00dev, RT2872)) {
/*
@@ -7731,6 +7839,8 @@ static int rt2800_init_eeprom(struct rt2
@@ -7738,6 +7846,8 @@ static int rt2800_init_eeprom(struct rt2
rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID, &rf);
else if (rt2x00_rt(rt2x00dev, RT3883))
rf = RF3853;
@ -232,7 +232,7 @@
else
rf = rt2x00_get_field16(eeprom, EEPROM_NIC_CONF0_RF_TYPE);
@@ -7750,6 +7860,7 @@ static int rt2800_init_eeprom(struct rt2
@@ -7757,6 +7867,7 @@ static int rt2800_init_eeprom(struct rt2
case RF3320:
case RF3322:
case RF3853:
@ -240,7 +240,7 @@
case RF5360:
case RF5362:
case RF5370:
@@ -8305,6 +8416,7 @@ static int rt2800_probe_hw_mode(struct r
@@ -8312,6 +8423,7 @@ static int rt2800_probe_hw_mode(struct r
case RF3290:
case RF3320:
case RF3322:
@ -248,7 +248,7 @@
case RF5360:
case RF5362:
case RF5370:
@@ -8444,6 +8556,7 @@ static int rt2800_probe_hw_mode(struct r
@@ -8451,6 +8563,7 @@ static int rt2800_probe_hw_mode(struct r
case RF3070:
case RF3290:
case RF3853:
@ -256,7 +256,7 @@
case RF5360:
case RF5362:
case RF5370:
@@ -8484,6 +8597,7 @@ static int rt2800_probe_rt(struct rt2x00
@@ -8491,6 +8604,7 @@ static int rt2800_probe_rt(struct rt2x00
case RT3572:
case RT3593:
case RT3883:

View file

@ -8,7 +8,7 @@
#include "rt2x00.h"
#include "rt2800lib.h"
@@ -7950,6 +7951,17 @@ static int rt2800_init_eeprom(struct rt2
@@ -7957,6 +7958,17 @@ static int rt2800_init_eeprom(struct rt2
rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC);
rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY);

Some files were not shown because too many files have changed in this diff Show more