Initial commit

This commit is contained in:
domenico
2025-06-24 16:03:39 +02:00
commit f3256cdaf2
6949 changed files with 1441681 additions and 0 deletions

View File

@@ -0,0 +1,561 @@
#
# Copyright (C) 2007-2015 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/kernel.mk
PKG_NAME:=mac80211
PKG_VERSION:=4.19.161-1
PKG_RELEASE:=1
PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v4.19.161/
PKG_HASH:=01a4173ba180eb8ca67c898239d5accb49a3ea9aea51510e17d5c937d6e93f9a
PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz
PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION)
PKG_BUILD_PARALLEL:=1
PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
PKG_DRIVERS = \
adm8211 \
airo \
hermes hermes-pci hermes-pcmcia hermes-plx\
lib80211 \
mac80211-hwsim \
mt7601u \
p54-common p54-pci p54-usb \
rsi91x rsi91x-usb rsi91x-sdio\
wlcore wl12xx wl18xx \
zd1211rw
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_kmod-mac80211 \
CONFIG_PACKAGE_MAC80211_DEBUGFS \
CONFIG_PACKAGE_MAC80211_MESH \
CONFIG_PACKAGE_MAC80211_TRACING \
CONFIG_PACKAGE_IWLWIFI_DEBUG \
CONFIG_PACKAGE_IWLWIFI_DEBUGFS \
CONFIG_PACKAGE_RTLWIFI_DEBUG \
include $(INCLUDE_DIR)/package.mk
WMENU:=Wireless Drivers
define KernelPackage/mac80211/Default
SUBMENU:=$(WMENU)
URL:=https://wireless.wiki.kernel.org/
MAINTAINER:=Felix Fietkau <nbd@nbd.name>
endef
config_package=$(if $(CONFIG_PACKAGE_kmod-$(1)),m)
config-y:= \
WLAN \
NL80211_TESTMODE \
CFG80211_WEXT \
CFG80211_CERTIFICATION_ONUS \
MAC80211_RC_MINSTREL \
MAC80211_RC_MINSTREL_HT \
MAC80211_RC_MINSTREL_VHT \
MAC80211_RC_DEFAULT_MINSTREL \
WLAN_VENDOR_ADMTEK \
WLAN_VENDOR_ATH \
WLAN_VENDOR_ATMEL \
WLAN_VENDOR_BROADCOM \
WLAN_VENDOR_CISCO \
WLAN_VENDOR_INTEL \
WLAN_VENDOR_INTERSIL \
WLAN_VENDOR_MARVELL \
WLAN_VENDOR_MEDIATEK \
WLAN_VENDOR_RALINK \
WLAN_VENDOR_REALTEK \
WLAN_VENDOR_RSI \
WLAN_VENDOR_ST \
WLAN_VENDOR_TI \
WLAN_VENDOR_ZYDAS \
config-$(call config_package,cfg80211) += CFG80211
config-$(call config_package,mac80211) += MAC80211
config-$(CONFIG_PACKAGE_MAC80211_MESH) += MAC80211_MESH
include ath.mk
include broadcom.mk
include intel.mk
include marvell.mk
include ralink.mk
include realtek.mk
PKG_CONFIG_DEPENDS += \
$(patsubst %,CONFIG_PACKAGE_kmod-%,$(PKG_DRIVERS))
define KernelPackage/cfg80211
$(call KernelPackage/mac80211/Default)
TITLE:=cfg80211 - wireless configuration API
DEPENDS+= +iw +wireless-regdb
ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
FILES:= \
$(PKG_BUILD_DIR)/compat/compat.ko \
$(PKG_BUILD_DIR)/net/wireless/cfg80211.ko
endef
define KernelPackage/cfg80211/description
cfg80211 is the Linux wireless LAN (802.11) configuration API.
endef
define KernelPackage/mac80211
$(call KernelPackage/mac80211/Default)
TITLE:=Linux 802.11 Wireless Networking Stack
# +kmod-crypto-cmac is a runtime only dependency of net/mac80211/aes_cmac.c
DEPENDS+= +kmod-cfg80211 +hostapd-common
KCONFIG:=\
CONFIG_AVERAGE=y
FILES:= $(PKG_BUILD_DIR)/net/mac80211/mac80211.ko
ABI_VERSION:=$(PKG_VERSION)-$(PKG_RELEASE)
MENU:=1
endef
define KernelPackage/mac80211/config
if PACKAGE_kmod-mac80211
config PACKAGE_MAC80211_DEBUGFS
bool "Export mac80211 internals in DebugFS"
select KERNEL_DEBUG_FS
default y
help
Select this to see extensive information about
the internal state of mac80211 in debugfs.
config PACKAGE_MAC80211_TRACING
bool "Enable tracing (mac80211 and supported drivers)"
select KERNEL_FTRACE
select KERNEL_ENABLE_DEFAULT_TRACERS
default n
help
Select this to enable tracing of mac80211 and
related wifi drivers (using trace-cmd).
config PACKAGE_MAC80211_MESH
bool "Enable 802.11s mesh support"
default y
endif
endef
define KernelPackage/mac80211/description
Generic IEEE 802.11 Networking Stack (mac80211)
endef
define KernelPackage/adm8211
$(call KernelPackage/mac80211/Default)
TITLE:=ADMTek 8211 support
DEPENDS+=@PCI_SUPPORT +kmod-mac80211 +kmod-eeprom-93cx6
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/admtek/adm8211.ko
AUTOLOAD:=$(call AutoProbe,adm8211)
endef
define KernelPackage/airo
$(call KernelPackage/mac80211/Default)
TITLE:=Cisco Aironet driver
DEPENDS+=@PCI_SUPPORT +@DRIVER_WEXT_SUPPORT +kmod-cfg80211 @TARGET_x86
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/cisco/airo.ko
AUTOLOAD:=$(call AutoProbe,airo)
endef
define KernelPackage/airo/description
Kernel support for Cisco Aironet cards
endef
define KernelPackage/hermes
$(call KernelPackage/mac80211/Default)
TITLE:=Hermes 802.11b chipset support
DEPENDS:=@PCI_SUPPORT||PCMCIA_SUPPORT +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT +kmod-crypto-michael-mic
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco.ko
AUTOLOAD:=$(call AutoProbe,orinoco)
endef
define KernelPackage/hermes/description
Kernel support for Hermes 802.11b chipsets
endef
define KernelPackage/hermes-pci
$(call KernelPackage/mac80211/Default)
TITLE:=Intersil Prism 2.5 PCI support
DEPENDS:=@PCI_SUPPORT +kmod-hermes
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_pci.ko
AUTOLOAD:=$(call AutoProbe,orinoco_pci)
endef
define KernelPackage/hermes-pci/description
Kernel modules for Intersil Prism 2.5 PCI support
endef
define KernelPackage/hermes-plx
$(call KernelPackage/mac80211/Default)
TITLE:=PLX9052 based PCI adaptor
DEPENDS:=@PCI_SUPPORT +kmod-hermes
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_plx.ko
AUTOLOAD:=$(call AutoProbe,orinoco_plx)
endef
define KernelPackage/hermes-plx/description
Kernel modules for Hermes in PLX9052 based PCI adaptors
endef
define KernelPackage/hermes-pcmcia
$(call KernelPackage/mac80211/Default)
TITLE:=Hermes based PCMCIA adaptors
DEPENDS:=@PCMCIA_SUPPORT +kmod-hermes +kmod-pcmcia-core
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/orinoco/orinoco_cs.ko
AUTOLOAD:=$(call AutoProbe,orinoco_cs)
endef
define KernelPackage/hermes-pcmcia/description
Kernel modules for Hermes based PCMCIA adaptors
endef
define KernelPackage/lib80211
$(call KernelPackage/mac80211/Default)
TITLE:=802.11 Networking stack
DEPENDS:=+kmod-cfg80211 +kmod-crypto-hash
FILES:= \
$(PKG_BUILD_DIR)/net/wireless/lib80211.ko \
$(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_wep.ko \
$(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_ccmp.ko \
$(PKG_BUILD_DIR)/net/wireless/lib80211_crypt_tkip.ko
AUTOLOAD:=$(call AutoProbe, \
lib80211 \
lib80211_crypt_wep \
lib80211_crypt_ccmp \
lib80211_crypt_tkip \
)
endef
define KernelPackage/lib80211/description
Kernel modules for 802.11 Networking stack
Includes:
- lib80211
- lib80211_crypt_wep
- lib80211_crypt_tkip
- lib80211_crytp_ccmp
endef
define KernelPackage/mac80211-hwsim
$(call KernelPackage/mac80211/Default)
TITLE:=mac80211 HW simulation device
DEPENDS+= +kmod-mac80211 +@DRIVER_11AC_SUPPORT +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mac80211_hwsim.ko
AUTOLOAD:=$(call AutoProbe,mac80211_hwsim)
endef
define KernelPackage/mt7601u
$(call KernelPackage/mac80211/Default)
TITLE:=MT7601U-based USB dongles Wireless Driver
DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT @USB_SUPPORT +kmod-usb-core +mt7601u-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/mediatek/mt7601u/mt7601u.ko
AUTOLOAD:=$(call AutoProbe,mt7601u)
endef
define KernelPackage/p54/Default
$(call KernelPackage/mac80211/Default)
TITLE:=Prism54 Drivers
endef
define KernelPackage/p54/description
Kernel module for Prism54 chipsets (mac80211)
endef
define KernelPackage/p54-common
$(call KernelPackage/p54/Default)
DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 +kmod-lib-crc-ccitt +@DRIVER_11W_SUPPORT
TITLE+= (COMMON)
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54common.ko
endef
define KernelPackage/p54-pci
$(call KernelPackage/p54/Default)
TITLE+= (PCI)
DEPENDS+= @PCI_SUPPORT +kmod-p54-common +p54-pci-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54pci.ko
AUTOLOAD:=$(call AutoProbe,p54pci)
endef
define KernelPackage/p54-usb
$(call KernelPackage/p54/Default)
TITLE+= (USB)
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-p54-common +p54-usb-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54usb.ko
AUTOLOAD:=$(call AutoProbe,p54usb)
endef
define KernelPackage/rsi91x
$(call KernelPackage/mac80211/Default)
TITLE:=Redpine Signals Inc 91x WLAN driver support
DEPENDS+= +kmod-mac80211 +rs9113-firmware +@DRIVER_11N_SUPPORT
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_91x.ko
endef
define KernelPackage/rsi91x-usb
$(call KernelPackage/mac80211/Default)
TITLE:=Redpine Signals USB bus support
DEPENDS+=@USB_SUPPORT +kmod-usb-core +kmod-mac80211 +kmod-rsi91x +rs9113-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_usb.ko
AUTOLOAD:=$(call AutoProbe,rsi_usb)
endef
define KernelPackage/rsi91x-sdio
$(call KernelPackage/mac80211/Default)
TITLE:=Redpine Signals SDIO bus support
DEPENDS+= +kmod-mac80211 +kmod-mmc +kmod-rsi91x +rs9113-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/rsi/rsi_sdio.ko
AUTOLOAD:=$(call AutoProbe,rsi_sdio)
endef
define KernelPackage/wlcore
$(call KernelPackage/mac80211/Default)
TITLE:=TI common driver part
DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11N_SUPPORT
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wlcore/wlcore_sdio.ko
AUTOLOAD:=$(call AutoProbe,wlcore wlcore_sdio)
endef
define KernelPackage/wlcore/description
This module contains some common parts needed by TI Wireless drivers.
endef
define KernelPackage/wl12xx
$(call KernelPackage/mac80211/Default)
TITLE:=Driver for TI WL12xx
URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl12xx
DEPENDS+= +kmod-wlcore +wl12xx-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl12xx/wl12xx.ko
AUTOLOAD:=$(call AutoProbe,wl12xx)
endef
define KernelPackage/wl12xx/description
Kernel modules for TI WL12xx
endef
define KernelPackage/wl18xx
$(call KernelPackage/mac80211/Default)
TITLE:=Driver for TI WL18xx
URL:=https://wireless.wiki.kernel.org/en/users/drivers/wl18xx
DEPENDS+= +kmod-wlcore +wl18xx-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ti/wl18xx/wl18xx.ko
AUTOLOAD:=$(call AutoProbe,wl18xx)
endef
define KernelPackage/wl18xx/description
Kernel modules for TI WL18xx
endef
ZD1211FW_NAME:=zd1211-firmware
ZD1211FW_VERSION:=1.4
define Download/zd1211rw
FILE:=$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
URL:=@SF/zd1211/
HASH:=866308f6f59f7075f075d4959dff2ede47735c751251fecd1496df1ba4d338e1
endef
$(eval $(call Download,zd1211rw))
define KernelPackage/zd1211rw
$(call KernelPackage/mac80211/Default)
TITLE:=Zydas ZD1211 support
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-mac80211 +@DRIVER_11W_SUPPORT
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/zydas/zd1211rw/zd1211rw.ko
AUTOLOAD:=$(call AutoProbe,zd1211rw)
endef
ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS
config-y += \
CFG80211_DEBUGFS \
MAC80211_DEBUGFS
endif
ifdef CONFIG_PACKAGE_MAC80211_TRACING
config-y += \
IWLWIFI_DEVICE_TRACING
endif
config-$(call config_package,lib80211) += LIB80211 LIB80211_CRYPT_WEP LIB80211_CRYPT_CCMP LIB80211_CRYPT_TKIP
config-$(call config_package,airo) += AIRO
config-$(call config_package,mac80211-hwsim) += MAC80211_HWSIM
config-$(call config_package,mt7601u) += MT7601U
config-y += WL_MEDIATEK
config-$(call config_package,p54-common) += P54_COMMON
config-$(call config_package,p54-pci) += P54_PCI
config-$(call config_package,p54-usb) += P54_USB
config-$(call config_package,hermes) += HERMES
config-$(call config_package,hermes-pci) += PCI_HERMES
config-$(call config_package,hermes-plx) += PLX_HERMES
config-$(call config_package,hermes-pcmcia) += PCMCIA_HERMES
config-y += HERMES_PRISM
config-$(call config_package,adm8211) += ADM8211
config-$(call config_package,wlcore) += WLCORE WLCORE_SDIO
config-$(call config_package,wl12xx) += WL12XX
config-$(call config_package,wl18xx) += WL18XX
config-y += WL_TI WILINK_PLATFORM_DATA
config-$(call config_package,zd1211rw) += ZD1211RW
config-$(call config_package,rsi91x) += RSI_91X
config-$(call config_package,rsi91x-usb) += RSI_USB
config-$(call config_package,rsi91x-sdio) += RSI_SDIO
config-$(CONFIG_LEDS_TRIGGERS) += MAC80211_LEDS
MAKE_OPTS:= -C "$(PKG_BUILD_DIR)" \
$(KERNEL_MAKE_FLAGS) \
EXTRA_CFLAGS="-I$(PKG_BUILD_DIR)/include $(IREMAP_CFLAGS)" \
KLIB_BUILD="$(LINUX_DIR)" \
MODPROBE=true \
KLIB=$(TARGET_MODULES_DIR) \
KERNEL_SUBLEVEL=$(lastword $(subst ., ,$(KERNEL_PATCHVER))) \
KBUILD_LDFLAGS_MODULE_PREREQ=
define ConfigVars
$(subst $(space),,$(foreach opt,$(config-$(1)),CPTCFG_$(opt)=$(1)
))
endef
define mac80211_config
$(call ConfigVars,m)$(call ConfigVars,y)
endef
$(eval $(call shexport,mac80211_config))
define Build/Prepare
rm -rf $(PKG_BUILD_DIR)
mkdir -p $(PKG_BUILD_DIR)
$(PKG_UNPACK)
$(Build/Patch)
$(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2100_NAME)-$(IPW2100_VERSION).tgz
$(TAR) -C $(PKG_BUILD_DIR) -xzf $(DL_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION).tgz
$(TAR) -C $(PKG_BUILD_DIR) -xjf $(DL_DIR)/$(ZD1211FW_NAME)-$(ZD1211FW_VERSION).tar.bz2
rm -rf \
$(PKG_BUILD_DIR)/include/linux/ssb \
$(PKG_BUILD_DIR)/include/linux/bcma \
$(PKG_BUILD_DIR)/include/net/bluetooth
rm -f \
$(PKG_BUILD_DIR)/include/linux/cordic.h \
$(PKG_BUILD_DIR)/include/linux/crc8.h \
$(PKG_BUILD_DIR)/include/linux/eeprom_93cx6.h \
$(PKG_BUILD_DIR)/include/linux/wl12xx.h \
$(PKG_BUILD_DIR)/include/linux/spi/libertas_spi.h \
$(PKG_BUILD_DIR)/include/net/ieee80211.h \
$(PKG_BUILD_DIR)/backport-include/linux/bcm47xx_nvram.h
echo 'compat-wireless-$(PKG_VERSION)-$(PKG_RELEASE)-$(REVISION)' > $(PKG_BUILD_DIR)/compat_version
endef
ifneq ($(CONFIG_PACKAGE_kmod-cfg80211)$(CONFIG_PACKAGE_kmod-lib80211),)
define Build/Compile/kmod
rm -rf $(PKG_BUILD_DIR)/modules
+$(MAKE) $(PKG_JOBS) $(MAKE_OPTS) modules
endef
endif
#do not Build/Configure for EXTERNAL KERNEL
ifeq ($(strip $(CONFIG_EXTERNAL_KERNEL_TREE)),"")
ifeq ($(strip $(CONFIG_KERNEL_GIT_CLONE_URI)),"")
define Build/Configure
cmp $(PKG_BUILD_DIR)/include/linux/ath9k_platform.h $(LINUX_DIR)/include/linux/ath9k_platform.h
cmp $(PKG_BUILD_DIR)/include/linux/ath5k_platform.h $(LINUX_DIR)/include/linux/ath5k_platform.h
cmp $(PKG_BUILD_DIR)/include/linux/rt2x00_platform.h $(LINUX_DIR)/include/linux/rt2x00_platform.h
endef
endif
endif
define Build/Patch
$(if $(QUILT),rm -rf $(PKG_BUILD_DIR)/patches; mkdir -p $(PKG_BUILD_DIR)/patches)
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/)
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/)
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/)
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/)
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/)
$(call PatchDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/)
$(if $(QUILT),touch $(PKG_BUILD_DIR)/.quilt_used)
endef
define Quilt/Refresh/Package
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/build,build/)
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/subsys,subsys/)
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/ath,ath/)
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/rt2x00,rt2x00/)
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/mwl,mwl/)
$(call Quilt/RefreshDir,$(PKG_BUILD_DIR),$(PATCH_DIR)/brcm,brcm/)
endef
define Build/Compile
$(SH_FUNC) var2file "$(call shvar,mac80211_config)" $(PKG_BUILD_DIR)/.config
$(MAKE) $(MAKE_OPTS) allnoconfig
$(call Build/Compile/kmod)
endef
define Build/InstallDev
mkdir -p \
$(1)/usr/include/mac80211 \
$(1)/usr/include/mac80211-backport \
$(1)/usr/include/mac80211/ath \
$(1)/usr/include/net/mac80211
$(CP) $(PKG_BUILD_DIR)/net/mac80211/*.h $(PKG_BUILD_DIR)/include/* $(1)/usr/include/mac80211/
$(CP) $(PKG_BUILD_DIR)/backport-include/* $(1)/usr/include/mac80211-backport/
$(CP) $(PKG_BUILD_DIR)/net/mac80211/rate.h $(1)/usr/include/net/mac80211/
$(CP) $(PKG_BUILD_DIR)/drivers/net/wireless/ath/*.h $(1)/usr/include/mac80211/ath/
rm -f $(1)/usr/include/mac80211-backport/linux/module.h
endef
define KernelPackage/b43/install
rm -rf $(1)/lib/firmware/
ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
tar xzf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
else
tar xjf "$(DL_DIR)/$(PKG_B43_FWV4_SOURCE)" -C "$(PKG_BUILD_DIR)"
endif
$(INSTALL_DIR) $(1)/lib/firmware/
ifeq ($(CONFIG_B43_OPENFIRMWARE),y)
$(MAKE) -C "$(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/"
$(INSTALL_DIR) $(1)/lib/firmware/b43-open/
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/ucode5.fw $(1)/lib/firmware/b43-open/ucode5.fw
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0bsinitvals5.fw $(1)/lib/firmware/b43-open/b0g0bsinitvals5.fw
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)/b0g0initvals5.fw $(1)/lib/firmware/b43-open/b0g0initvals5.fw
else
b43-fwcutter -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_B43_FWV4_OBJECT)
endif
ifneq ($(CONFIG_B43_FW_SQUASH),)
b43-fwsquash.py "$(CONFIG_B43_FW_SQUASH_PHYTYPES)" "$(CONFIG_B43_FW_SQUASH_COREREVS)" "$(1)/lib/firmware/b43"
endif
endef
define KernelPackage/cfg80211/install
$(INSTALL_DIR) $(1)/lib/wifi $(1)/lib/netifd/wireless
$(INSTALL_DATA) ./files/lib/wifi/mac80211.sh $(1)/lib/wifi
$(INSTALL_BIN) ./files/lib/netifd/wireless/mac80211.sh $(1)/lib/netifd/wireless
$(INSTALL_DIR) $(1)/etc/hotplug.d/ieee80211
$(INSTALL_DATA) ./files/mac80211.hotplug $(1)/etc/hotplug.d/ieee80211/10-wifi-detect
endef
define KernelPackage/zd1211rw/install
$(INSTALL_DIR) $(1)/lib/firmware/zd1211
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(ZD1211FW_NAME)/zd1211* $(1)/lib/firmware/zd1211
endef
$(eval $(foreach drv,$(PKG_DRIVERS),$(call KernelPackage,$(drv))))
$(eval $(call KernelPackage,cfg80211))
$(eval $(call KernelPackage,mac80211))

View File

@@ -0,0 +1,276 @@
PKG_DRIVERS += \
ath ath5k ath6kl ath6kl-sdio ath6kl-usb ath9k ath9k-common ath9k-htc ath10k \
carl9170
PKG_CONFIG_DEPENDS += \
CONFIG_PACKAGE_ATH_DEBUG \
CONFIG_PACKAGE_ATH_DFS \
CONFIG_PACKAGE_ATH_SPECTRAL \
CONFIG_PACKAGE_ATH_DYNACK \
CONFIG_ATH9K_SUPPORT_PCOEM \
CONFIG_ATH9K_TX99 \
CONFIG_ATH10K_LEDS \
CONFIG_ATH10K_THERMAL \
CONFIG_ATH_USER_REGD
ifdef CONFIG_PACKAGE_MAC80211_DEBUGFS
config-y += \
ATH9K_DEBUGFS \
ATH9K_HTC_DEBUGFS \
ATH10K_DEBUGFS \
CARL9170_DEBUGFS \
ATH5K_DEBUG \
ATH6KL_DEBUG
endif
ifdef CONFIG_PACKAGE_MAC80211_TRACING
config-y += \
ATH10K_TRACING \
ATH6KL_TRACING \
ATH_TRACEPOINTS \
ATH5K_TRACER
endif
config-$(call config_package,ath) += ATH_CARDS ATH_COMMON ATH_REG_DYNAMIC_USER_REG_HINTS
config-$(CONFIG_PACKAGE_ATH_DEBUG) += ATH_DEBUG ATH10K_DEBUG ATH9K_STATION_STATISTICS
config-$(CONFIG_PACKAGE_ATH_DFS) += ATH9K_DFS_CERTIFIED ATH10K_DFS_CERTIFIED
config-$(CONFIG_PACKAGE_ATH_SPECTRAL) += ATH9K_COMMON_SPECTRAL ATH10K_SPECTRAL
config-$(CONFIG_PACKAGE_ATH_DYNACK) += ATH9K_DYNACK
config-$(call config_package,ath9k) += ATH9K
config-$(call config_package,ath9k-common) += ATH9K_COMMON
config-$(CONFIG_TARGET_ar71xx) += ATH9K_AHB
config-$(CONFIG_TARGET_ath79) += ATH9K_AHB
config-$(CONFIG_TARGET_ipq40xx) += ATH10K_AHB
config-$(CONFIG_PCI) += ATH9K_PCI
config-$(CONFIG_ATH_USER_REGD) += ATH_USER_REGD
config-$(CONFIG_ATH9K_SUPPORT_PCOEM) += ATH9K_PCOEM
config-$(CONFIG_ATH9K_TX99) += ATH9K_TX99
config-$(CONFIG_ATH9K_UBNTHSR) += ATH9K_UBNTHSR
config-$(CONFIG_ATH10K_LEDS) += ATH10K_LEDS
config-$(CONFIG_ATH10K_THERMAL) += ATH10K_THERMAL
config-$(call config_package,ath9k-htc) += ATH9K_HTC
config-$(call config_package,ath10k) += ATH10K ATH10K_PCI
config-$(call config_package,ath5k) += ATH5K
ifdef CONFIG_TARGET_ath25
config-y += ATH5K_AHB
else
config-y += ATH5K_PCI
endif
config-$(call config_package,ath6kl) += ATH6KL
config-$(call config_package,ath6kl-sdio) += ATH6KL_SDIO
config-$(call config_package,ath6kl-usb) += ATH6KL_USB
config-$(call config_package,carl9170) += CARL9170
define KernelPackage/ath/config
if PACKAGE_kmod-ath
config ATH_USER_REGD
bool "Force Atheros drivers to respect the user's regdomain settings"
default y
help
Atheros' idea of regulatory handling is that the EEPROM of the card defines
the regulatory limits and the user is only allowed to restrict the settings
even further, even if the country allows frequencies or power levels that
are forbidden by the EEPROM settings.
Select this option if you want the driver to respect the user's decision about
regulatory settings.
config PACKAGE_ATH_DEBUG
bool "Atheros wireless debugging"
help
Say Y, if you want to debug atheros wireless drivers.
Only ath9k & ath10k make use of this.
config PACKAGE_ATH_DFS
bool "Enable DFS support"
default y
help
Dynamic frequency selection (DFS) is required for most of the 5 GHz band
channels in Europe, US, and Japan.
Select this option if you want to use such channels.
config PACKAGE_ATH_SPECTRAL
bool "Atheros spectral scan support"
depends on PACKAGE_ATH_DEBUG
select KERNEL_RELAY
help
Say Y to enable access to the FFT/spectral data via debugfs.
config PACKAGE_ATH_DYNACK
bool "Enable Dynack support"
depends on PACKAGE_kmod-ath9k-common
help
Enables support for Dynamic ACK estimation, which allows the fastest possible speed
at any distance automatically by increasing/decreasing the max frame ACK time for
the most remote station detected. It can be enabled by using iw (iw phy0 set distance auto),
or by sending the NL80211_ATTR_WIPHY_DYN_ACK flag to mac80211 driver using netlink.
Select this option if you want to enable this feature
endif
endef
define KernelPackage/ath
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros common driver part
DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_ath79||TARGET_ath25 +kmod-mac80211
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath.ko
MENU:=1
endef
define KernelPackage/ath/description
This module contains some common parts needed by Atheros Wireless drivers.
endef
define KernelPackage/ath5k
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 5xxx wireless cards support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath5k
DEPENDS+= @(PCI_SUPPORT||TARGET_ath25) +kmod-ath +@DRIVER_11W_SUPPORT
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath5k/ath5k.ko
AUTOLOAD:=$(call AutoProbe,ath5k)
endef
define KernelPackage/ath5k/description
This module adds support for wireless adapters based on
Atheros 5xxx chipset.
endef
define KernelPackage/ath6kl
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros FullMAC wireless devices (common code for ath6kl_sdio and ath6kl_usb)
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl
HIDDEN:=1
DEPENDS+= +kmod-ath +@DRIVER_11N_SUPPORT
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_core.ko
endef
define KernelPackage/ath6kl-sdio
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11n SDIO wireless cards support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl
DEPENDS+= +kmod-mmc +kmod-ath6kl
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_sdio.ko
AUTOLOAD:=$(call AutoProbe,ath6kl_sdio)
endef
define KernelPackage/ath6kl-sdio/description
This module adds support for wireless adapters based on
Atheros IEEE 802.11n AR6003 and AR6004 family of chipsets.
endef
define KernelPackage/ath6kl-usb
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11n USB wireless cards support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath6kl
DEPENDS+= @USB_SUPPORT +kmod-usb-core +kmod-ath6kl
FILES:= $(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath6kl/ath6kl_usb.ko
AUTOLOAD:=$(call AutoProbe,ath6kl_usb)
endef
define KernelPackage/ath6kl-usb/description
This module adds support for wireless adapters based on the
Atheros IEEE 802.11n AR6004 chipset.
endef
define KernelPackage/ath9k-common
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11n wireless devices (common code for ath9k and ath9k_htc)
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k
HIDDEN:=1
DEPENDS+= @PCI_SUPPORT||USB_SUPPORT||TARGET_ar71xx||TARGET_ath79 +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_common.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_hw.ko
endef
define KernelPackage/ath9k
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11n PCI wireless cards support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k
DEPENDS+= @PCI_SUPPORT||TARGET_ar71xx||TARGET_ath79 +kmod-ath9k-common
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k.ko
AUTOLOAD:=$(call AutoProbe,ath9k)
endef
define KernelPackage/ath9k/description
This module adds support for wireless adapters based on
Atheros IEEE 802.11n AR5008 and AR9001 family of chipsets.
endef
define KernelPackage/ath9k/config
config ATH9K_SUPPORT_PCOEM
bool "Support chips used in PC OEM cards"
depends on PACKAGE_kmod-ath9k
config ATH9K_TX99
bool "Enable TX99 support (WARNING: testing only, breaks normal operation!)"
depends on PACKAGE_kmod-ath9k
config ATH9K_UBNTHSR
bool "Support for Ubiquiti UniFi Outdoor+ access point"
depends on PACKAGE_kmod-ath9k && (TARGET_ar71xx_generic||TARGET_ath79)
default y
endef
define KernelPackage/ath9k-htc
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11n USB device support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath9k
DEPENDS+= @USB_SUPPORT +kmod-ath9k-common +kmod-usb-core +ath9k-htc-firmware
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath9k/ath9k_htc.ko
AUTOLOAD:=$(call AutoProbe,ath9k_htc)
endef
define KernelPackage/ath9k-htc/description
This module adds support for wireless adapters based on
Atheros USB AR9271 and AR7010 family of chipsets.
endef
define KernelPackage/ath10k
$(call KernelPackage/mac80211/Default)
TITLE:=Atheros 802.11ac wireless cards support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/ath10k
DEPENDS+= @PCI_SUPPORT +kmod-ath +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT \
+ATH10K_THERMAL:kmod-hwmon-core +ATH10K_THERMAL:kmod-thermal
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_core.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/ath/ath10k/ath10k_pci.ko
AUTOLOAD:=$(call AutoProbe,ath10k_pci)
endef
define KernelPackage/ath10k/description
This module adds support for wireless adapters based on
Atheros IEEE 802.11ac family of chipsets. For now only
PCI is supported.
endef
define KernelPackage/ath10k/config
config ATH10K_LEDS
bool "Enable LED support"
default y
depends on PACKAGE_kmod-ath10k
config ATH10K_THERMAL
bool "Enable thermal sensors and throttling support"
depends on PACKAGE_kmod-ath10k
endef
define KernelPackage/carl9170
$(call KernelPackage/mac80211/Default)
TITLE:=Driver for Atheros AR9170 USB sticks
DEPENDS:=@USB_SUPPORT +kmod-mac80211 +kmod-ath +kmod-usb-core +kmod-input-core +@DRIVER_11N_SUPPORT +@DRIVER_11W_SUPPORT +carl9170-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/ath/carl9170/carl9170.ko
AUTOLOAD:=$(call AutoProbe,carl9170)
endef

View File

@@ -0,0 +1,487 @@
PKG_DRIVERS += \
b43 b43legacy brcmsmac brcmfmac brcmutil
PKG_CONFIG_DEPENDS += \
CONFIG_PACKAGE_B43_DEBUG \
CONFIG_PACKAGE_B43_PIO \
CONFIG_PACKAGE_B43_PHY_G \
CONFIG_PACKAGE_B43_PHY_N \
CONFIG_PACKAGE_B43_PHY_LP \
CONFIG_PACKAGE_B43_PHY_HT \
CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB \
CONFIG_PACKAGE_B43_BUSES_BCMA \
CONFIG_PACKAGE_B43_BUSES_SSB \
CONFIG_PACKAGE_BRCM80211_DEBUG
config-$(call config_package,b43) += B43
config-$(CONFIG_PACKAGE_B43_BUSES_BCMA_AND_SSB) += B43_BUSES_BCMA_AND_SSB
config-$(CONFIG_PACKAGE_B43_BUSES_BCMA) += B43_BUSES_BCMA
config-$(CONFIG_PACKAGE_B43_BUSES_SSB) += B43_BUSES_SSB
config-$(CONFIG_PACKAGE_B43_PHY_G) += B43_PHY_G
config-$(CONFIG_PACKAGE_B43_PHY_N) += B43_PHY_N
config-$(CONFIG_PACKAGE_B43_PHY_LP) += B43_PHY_LP
config-$(CONFIG_PACKAGE_B43_PHY_HT) += B43_PHY_HT
config-$(CONFIG_PACKAGE_B43_PIO) += B43_PIO
config-$(CONFIG_PACKAGE_B43_DEBUG) += B43_DEBUG
config-$(call config_package,b43legacy) += B43LEGACY
config-y += B43LEGACY_DMA_MODE
config-$(call config_package,brcmutil) += BRCMUTIL
config-$(call config_package,brcmsmac) += BRCMSMAC
config-$(call config_package,brcmfmac) += BRCMFMAC
config-$(CONFIG_BRCMFMAC_SDIO) += BRCMFMAC_SDIO
config-$(CONFIG_BRCMFMAC_USB) += BRCMFMAC_USB
config-$(CONFIG_BRCMFMAC_PCIE) += BRCMFMAC_PCIE
config-$(CONFIG_PACKAGE_BRCM80211_DEBUG) += BRCMDBG
config-$(CONFIG_LEDS_TRIGGERS) += B43_LEDS B43LEGACY_LEDS
#Broadcom firmware
ifneq ($(CONFIG_B43_FW_6_30),)
PKG_B43_FWV4_NAME:=broadcom-wl
PKG_B43_FWV4_VERSION:=6.30.163.46
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).wl_apsta.o
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
PKG_B43_FWV4_HASH:=a07c3b6b277833c7dbe61daa511f908cd66c5e2763eb7a0859abc36cd9335c2d
else
ifneq ($(CONFIG_B43_FW_5_10),)
PKG_B43_FWV4_NAME:=broadcom-wl
PKG_B43_FWV4_VERSION:=5.10.56.27.3
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta/wl_prebuilt.o
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)_mipsel.tar.bz2
PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/
PKG_B43_FWV4_HASH:=26a8c370f48fc129d0731cfd751c36cae1419b0bc8ca35781126744e60eae009
else
ifneq ($(CONFIG_B43_FW_4_178),)
PKG_B43_FWV4_NAME:=broadcom-wl
PKG_B43_FWV4_VERSION:=4.178.10.4
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/
PKG_B43_FWV4_HASH:=32f6ad98facbb9045646fdc8b54bb03086d204153253f9c65d0234a5d90ae53f
else
ifneq ($(CONFIG_B43_FW_5_100_138),)
PKG_B43_FWV4_NAME:=broadcom-wl
PKG_B43_FWV4_VERSION:=5.100.138
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/linux/wl_apsta.o
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
PKG_B43_FWV4_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
PKG_B43_FWV4_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f
else
PKG_B43_FWV4_NAME:=broadcom-wl
PKG_B43_FWV4_VERSION:=4.150.10.5
PKG_B43_FWV4_OBJECT:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION)/driver/wl_apsta_mimo.o
PKG_B43_FWV4_SOURCE:=$(PKG_B43_FWV4_NAME)-$(PKG_B43_FWV4_VERSION).tar.bz2
PKG_B43_FWV4_SOURCE_URL:=http://mirror2.openwrt.org/sources/
PKG_B43_FWV4_HASH:=a9f4e276a4d8d3a1cd0f2eb87080ae89b77f0a7140f06d4e9e2135fc44fdd533
endif
endif
endif
endif
ifneq ($(CONFIG_B43_OPENFIRMWARE),)
PKG_B43_FWV4_NAME:=broadcom-wl
PKG_B43_FWV4_VERSION:=5.2
PKG_B43_FWV4_OBJECT:=openfwwf-$(PKG_B43_FWV4_VERSION)
PKG_B43_FWV4_SOURCE:=openfwwf-$(PKG_B43_FWV4_VERSION).tar.gz
PKG_B43_FWV4_SOURCE_URL:=http://netweb.ing.unibs.it/~openfwwf/firmware
PKG_B43_FWV4_HASH:=9de03320083201080b2e94b81637ac07a159cf4e6f3481383e1a217e627bc0dc
endif
define Download/b43
FILE:=$(PKG_B43_FWV4_SOURCE)
URL:=$(PKG_B43_FWV4_SOURCE_URL)
HASH:=$(PKG_B43_FWV4_HASH)
endef
$(eval $(call Download,b43))
define KernelPackage/b43
$(call KernelPackage/mac80211/Default)
TITLE:=Broadcom 43xx wireless support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43
KCONFIG:= \
CONFIG_HW_RANDOM=y
# Depend on PCI_SUPPORT to make sure we can select kmod-bcma or kmod-ssb
DEPENDS += \
@PCI_SUPPORT +@DRIVER_11W_SUPPORT +kmod-mac80211 \
$(if $(CONFIG_PACKAGE_B43_USE_SSB),+kmod-ssb) \
$(if $(CONFIG_PACKAGE_B43_USE_BCMA),+kmod-bcma)
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43/b43.ko
AUTOLOAD:=$(call AutoProbe,b43)
MENU:=1
endef
define KernelPackage/b43/config
config PACKAGE_B43_USE_SSB
select PACKAGE_kmod-ssb
tristate
depends on !TARGET_brcm47xx && !TARGET_brcm63xx
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_SSB
config PACKAGE_B43_USE_BCMA
select PACKAGE_kmod-bcma
tristate
depends on !TARGET_brcm47xx && !TARGET_bcm53xx
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA_AND_SSB
default PACKAGE_kmod-b43 if PACKAGE_B43_BUSES_BCMA
if PACKAGE_kmod-b43
choice
prompt "b43 firmware version"
default B43_FW_5_100_138
help
This option allows you to select the version of the b43 firmware.
config B43_FW_4_150
bool "Firmware 410.2160 from driver 4.150.10.5 (old stable)"
help
Old stable firmware for BCM43xx devices.
If unsure, select this.
config B43_FW_4_178
bool "Firmware 478.104 from driver 4.178.10.4"
help
Older firmware for BCM43xx devices.
If unsure, select the "stable" firmware.
config B43_FW_5_10
bool "Firmware 508.1084 from driver 5.10.56.27"
help
Older firmware for BCM43xx devices.
If unsure, select the "stable" firmware.
config B43_FW_5_100_138
bool "Firmware 666.2 from driver 5.100.138 (stable)"
help
The currently default firmware for BCM43xx devices.
This firmware currently gets most of the testing and is needed for some N-PHY devices.
If unsure, select the this firmware.
config B43_FW_6_30
bool "Firmware 784.2 from driver 6.30.163.46 (experimental)"
help
Newer experimental firmware for BCM43xx devices.
This firmware is mostly untested.
If unsure, select the "stable" firmware.
config B43_OPENFIRMWARE
bool "Open FirmWare for WiFi networks"
help
Opensource firmware for BCM43xx devices.
Do _not_ select this, unless you know what you are doing.
The Opensource firmware is not suitable for embedded devices, yet.
It does not support QoS, which is bad for AccessPoints.
It does not support hardware crypto acceleration, which is a showstopper
for embedded devices with low CPU resources.
If unsure, select the "stable" firmware.
endchoice
config B43_FW_SQUASH
bool "Remove unnecessary firmware files"
depends on !B43_OPENFIRMWARE
default y
help
This options allows you to remove unnecessary b43 firmware files
from the final rootfs image. This can reduce the rootfs size by
up to 200k.
If unsure, say Y.
config B43_FW_SQUASH_COREREVS
string "Core revisions to include"
depends on B43_FW_SQUASH
default "5,6,7,8,9,10,11,13,15" if TARGET_brcm47xx_legacy
default "16,28,29,30" if TARGET_brcm47xx_mips74k
default "5,6,7,8,9,10,11,13,15,16,28,29,30"
help
This is a comma seperated list of core revision numbers.
Example (keep files for rev5 only):
5
Example (keep files for rev5 and rev11):
5,11
config B43_FW_SQUASH_PHYTYPES
string "PHY types to include"
depends on B43_FW_SQUASH
default "G,N,LP" if TARGET_brcm47xx_legacy
default "N,HT" if TARGET_brcm47xx_mips74k
default "G,N,LP,HT"
help
This is a comma seperated list of PHY types:
A => A-PHY
AG => Dual A-PHY G-PHY
G => G-PHY
LP => LP-PHY
N => N-PHY
HT => HT-PHY
LCN => LCN-PHY
LCN40 => LCN40-PHY
AC => AC-PHY
Example (keep files for G-PHY only):
G
Example (keep files for G-PHY and N-PHY):
G,N
choice
prompt "Supported buses"
default PACKAGE_B43_BUSES_BCMA_AND_SSB
help
This allows choosing buses that b43 should support.
config PACKAGE_B43_BUSES_BCMA_AND_SSB
depends on !TARGET_brcm47xx_legacy && !TARGET_brcm47xx_mips74k && !TARGET_bcm53xx
bool "BCMA and SSB"
config PACKAGE_B43_BUSES_BCMA
depends on !TARGET_brcm47xx_legacy
bool "BCMA only"
config PACKAGE_B43_BUSES_SSB
depends on !TARGET_brcm47xx_mips74k && !TARGET_bcm53xx
bool "SSB only"
endchoice
config PACKAGE_B43_DEBUG
bool "Enable debug output and debugfs for b43"
default n
help
Enable additional debug output and runtime sanity checks for b43
and enables the debugfs interface.
If unsure, say N.
config PACKAGE_B43_PIO
bool "Enable support for PIO transfer mode"
default n
help
Enable support for using PIO instead of DMA. Unless you have DMA
transfer problems you don't need this.
If unsure, say N.
config PACKAGE_B43_PHY_G
bool "Enable support for G-PHYs"
default n if TARGET_brcm47xx_mips74k
default y
help
Enable support for G-PHY. This includes support for the following devices:
PCI: BCM4306, BCM4311, BCM4318
SoC: BCM5352E, BCM4712
If unsure, say Y.
config PACKAGE_B43_PHY_N
bool "Enable support for N-PHYs"
default y
help
Enable support for N-PHY. This includes support for the following devices:
PCI: BCM4321, BCM4322, BCM43222, BCM43224, BCM43225
SoC: BCM4716, BCM4717, BCM4718
Currently only 11g speed is available.
If unsure, say Y.
config PACKAGE_B43_PHY_LP
bool "Enable support for LP-PHYs"
default n if TARGET_brcm47xx_mips74k
default y
help
Enable support for LP-PHY. This includes support for the following devices:
PCI: BCM4312
SoC: BCM5354
If unsure, say Y.
config PACKAGE_B43_PHY_HT
bool "Enable support for HT-PHYs"
default n if TARGET_brcm47xx_legacy
default y
help
Enable support for HT-PHY. This includes support for the following devices:
PCI: BCM4331
Currently only 11g speed is available.
If unsure, say Y.
config PACKAGE_B43_PHY_LCN
bool "Enable support for LCN-PHYs"
depends on BROKEN
default n
help
Currently broken.
If unsure, say N.
endif
endef
define KernelPackage/b43/description
Kernel module for Broadcom 43xx wireless support (mac80211 stack) new
endef
define KernelPackage/b43legacy
$(call KernelPackage/mac80211/Default)
TITLE:=Broadcom 43xx-legacy wireless support
URL:=https://wireless.wiki.kernel.org/en/users/drivers/b43
KCONFIG:= \
CONFIG_HW_RANDOM=y
DEPENDS+= +kmod-mac80211 +!(TARGET_brcm47xx||TARGET_brcm63xx):kmod-ssb @!TARGET_brcm47xx_mips74k +b43legacy-firmware +@DRIVER_11W_SUPPORT
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43legacy/b43legacy.ko
AUTOLOAD:=$(call AutoProbe,b43legacy)
MENU:=1
endef
define KernelPackage/b43legacy/description
Kernel module for Broadcom 43xx-legacy wireless support (mac80211 stack) new
endef
define KernelPackage/brcmutil
$(call KernelPackage/mac80211/Default)
TITLE:=Broadcom IEEE802.11n common driver parts
URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
DEPENDS+=@PCI_SUPPORT||USB_SUPPORT
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmutil/brcmutil.ko
AUTOLOAD:=$(call AutoProbe,brcmutil)
MENU:=1
endef
define KernelPackage/brcmutil/description
This module contains some common parts needed by Broadcom Wireless drivers brcmsmac and brcmfmac.
endef
define KernelPackage/brcmutil/config
if PACKAGE_kmod-brcmutil
config PACKAGE_BRCM80211_DEBUG
bool "Broadcom wireless driver debugging"
help
Say Y, if you want to debug brcmsmac and brcmfmac wireless driver.
endif
endef
PKG_BRCMSMAC_FW_NAME:=broadcom-wl
PKG_BRCMSMAC_FW_VERSION:=5.100.138
PKG_BRCMSMAC_FW_OBJECT:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION)/linux/wl_apsta.o
PKG_BRCMSMAC_FW_SOURCE:=$(PKG_BRCMSMAC_FW_NAME)-$(PKG_BRCMSMAC_FW_VERSION).tar.bz2
PKG_BRCMSMAC_FW_SOURCE_URL:=http://www.lwfinger.com/b43-firmware/
PKG_BRCMSMAC_FW_HASH:=f1e7067aac5b62b67b8b6e4c517990277804339ac16065eb13c731ff909ae46f
define Download/brcmsmac
FILE:=$(PKG_BRCMSMAC_FW_SOURCE)
URL:=$(PKG_BRCMSMAC_FW_SOURCE_URL)
HASH:=$(PKG_BRCMSMAC_FW_HASH)
endef
$(eval $(call Download,brcmsmac))
define KernelPackage/brcmsmac
$(call KernelPackage/mac80211/Default)
TITLE:=Broadcom IEEE802.11n PCIe SoftMAC WLAN driver
URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
DEPENDS+= +kmod-mac80211 +@DRIVER_11N_SUPPORT +!TARGET_brcm47xx:kmod-bcma +kmod-lib-cordic +kmod-lib-crc8 +kmod-brcmutil +!BRCMSMAC_USE_FW_FROM_WL:brcmsmac-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmsmac/brcmsmac.ko
AUTOLOAD:=$(call AutoProbe,brcmsmac)
MENU:=1
endef
define KernelPackage/brcmsmac/description
Kernel module for Broadcom IEEE802.11n PCIe Wireless cards
endef
define KernelPackage/brcmsmac/config
if PACKAGE_kmod-brcmsmac
config BRCMSMAC_USE_FW_FROM_WL
bool "Use firmware extracted from broadcom proprietary driver"
default y
help
Instead of using the official brcmsmac firmware a firmware
version 666.2 extracted from the proprietary Broadcom driver
is used. This is needed to get core rev 17 used in bcm4716
to work.
If unsure, say Y.
endif
endef
define KernelPackage/brcmfmac
$(call KernelPackage/mac80211/Default)
TITLE:=Broadcom IEEE802.11n USB FullMAC WLAN driver
URL:=https://wireless.wiki.kernel.org/en/users/drivers/brcm80211
DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT \
+kmod-brcmutil +BRCMFMAC_SDIO:kmod-mmc @!TARGET_uml \
+BRCMFMAC_USB:kmod-usb-core +BRCMFMAC_USB:brcmfmac-firmware-usb
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/brcm80211/brcmfmac/brcmfmac.ko
AUTOLOAD:=$(call AutoProbe,brcmfmac)
endef
define KernelPackage/brcmfmac/description
Kernel module for Broadcom IEEE802.11n USB Wireless cards
endef
define KernelPackage/brcmfmac/config
if PACKAGE_kmod-brcmfmac
config BRCMFMAC_SDIO
bool "Enable SDIO bus interface support"
default y if TARGET_brcm2708
default y if TARGET_sunxi
default n
help
Enable support for cards attached to an SDIO bus.
Select this option only if you are sure that your
board has a Broadcom wireless chip atacched to
that bus.
config BRCMFMAC_USB
bool "Enable USB bus interface support"
depends on USB_SUPPORT
default y
help
Supported USB connected chipsets:
BCM43235, BCM43236, BCM43238 (all in revision 3 only)
BCM43143, BCM43242, BCM43566, BCM43569
config BRCMFMAC_PCIE
bool "Enable PCIE bus interface support"
depends on PCI_SUPPORT
default y
help
Supported PCIe connected chipsets:
BCM4354, BCM4356, BCM43567, BCM43570, BCM43602
endif
endef
define KernelPackage/brcmsmac/install
$(INSTALL_DIR) $(1)/lib/firmware/brcm
ifeq ($(CONFIG_BRCMSMAC_USE_FW_FROM_WL),y)
tar xjf "$(DL_DIR)/$(PKG_BRCMSMAC_FW_SOURCE)" -C "$(PKG_BUILD_DIR)"
b43-fwcutter --brcmsmac -w $(1)/lib/firmware/ $(PKG_BUILD_DIR)/$(PKG_BRCMSMAC_FW_OBJECT)
endif
endef

View File

@@ -0,0 +1,825 @@
#!/bin/sh
. /lib/netifd/netifd-wireless.sh
. /lib/netifd/hostapd.sh
init_wireless_driver "$@"
MP_CONFIG_INT="mesh_retry_timeout mesh_confirm_timeout mesh_holding_timeout mesh_max_peer_links
mesh_max_retries mesh_ttl mesh_element_ttl mesh_hwmp_max_preq_retries
mesh_path_refresh_time mesh_min_discovery_timeout mesh_hwmp_active_path_timeout
mesh_hwmp_preq_min_interval mesh_hwmp_net_diameter_traversal_time mesh_hwmp_rootmode
mesh_hwmp_rann_interval mesh_gate_announcements mesh_sync_offset_max_neighor
mesh_rssi_threshold mesh_hwmp_active_path_to_root_timeout mesh_hwmp_root_interval
mesh_hwmp_confirmation_interval mesh_awake_window mesh_plink_timeout"
MP_CONFIG_BOOL="mesh_auto_open_plinks mesh_fwding"
MP_CONFIG_STRING="mesh_power_mode"
iw() {
command iw $@ || logger -t mac80211 "Failed command: iw $@"
}
drv_mac80211_init_device_config() {
hostapd_common_add_device_config
config_add_string path phy 'macaddr:macaddr'
config_add_string hwmode
config_add_string tx_burst
config_add_int beacon_int chanbw frag rts
config_add_int rxantenna txantenna antenna_gain txpower distance
config_add_boolean noscan ht_coex
config_add_array ht_capab
config_add_array channels
config_add_boolean \
rxldpc \
short_gi_80 \
short_gi_160 \
tx_stbc_2by1 \
su_beamformer \
su_beamformee \
mu_beamformer \
mu_beamformee \
vht_txop_ps \
htc_vht \
rx_antenna_pattern \
tx_antenna_pattern
config_add_int vht_max_a_mpdu_len_exp vht_max_mpdu vht_link_adapt vht160 rx_stbc tx_stbc
config_add_boolean \
ldpc \
greenfield \
short_gi_20 \
short_gi_40 \
max_amsdu \
dsss_cck_40
}
drv_mac80211_init_iface_config() {
hostapd_common_add_bss_config
config_add_string 'macaddr:macaddr' ifname
config_add_boolean wds powersave
config_add_int maxassoc
config_add_int max_listen_int
config_add_int dtim_period
config_add_int start_disabled
# mesh
config_add_string mesh_id
config_add_int $MP_CONFIG_INT
config_add_boolean $MP_CONFIG_BOOL
config_add_string $MP_CONFIG_STRING
}
mac80211_add_capabilities() {
local __var="$1"; shift
local __mask="$1"; shift
local __out= oifs
oifs="$IFS"
IFS=:
for capab in "$@"; do
set -- $capab
[ "$(($4))" -gt 0 ] || continue
[ "$(($__mask & $2))" -eq "$((${3:-$2}))" ] || continue
__out="$__out[$1]"
done
IFS="$oifs"
export -n -- "$__var=$__out"
}
mac80211_hostapd_setup_base() {
local phy="$1"
json_select config
[ "$auto_channel" -gt 0 ] && channel=acs_survey
[ "$auto_channel" -gt 0 ] && json_get_values channel_list channels
json_get_vars noscan ht_coex
json_get_values ht_capab_list ht_capab tx_burst
set_default noscan 0
[ "$noscan" -gt 0 ] && hostapd_noscan=1
[ "$tx_burst" = 0 ] && tx_burst=
ieee80211n=1
ht_capab=
case "$htmode" in
VHT20|HT20) ;;
HT40*|VHT40|VHT80|VHT160)
case "$hwmode" in
a)
case "$(( ($channel / 4) % 2 ))" in
1) ht_capab="[HT40+]";;
0) ht_capab="[HT40-]";;
esac
;;
*)
case "$htmode" in
HT40+) ht_capab="[HT40+]";;
HT40-) ht_capab="[HT40-]";;
*)
if [ "$channel" -lt 7 ]; then
ht_capab="[HT40+]"
else
ht_capab="[HT40-]"
fi
;;
esac
;;
esac
[ "$auto_channel" -gt 0 ] && ht_capab="[HT40+]"
;;
*) ieee80211n= ;;
esac
[ -n "$ieee80211n" ] && {
append base_cfg "ieee80211n=1" "$N"
set_default ht_coex 0
append base_cfg "ht_coex=$ht_coex" "$N"
json_get_vars \
ldpc:1 \
greenfield:0 \
short_gi_20:1 \
short_gi_40:1 \
tx_stbc:1 \
rx_stbc:3 \
max_amsdu:1 \
dsss_cck_40:1
ht_cap_mask=0
for cap in $(iw phy "$phy" info | grep 'Capabilities:' | cut -d: -f2); do
ht_cap_mask="$(($ht_cap_mask | $cap))"
done
cap_rx_stbc=$((($ht_cap_mask >> 8) & 3))
[ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
ht_cap_mask="$(( ($ht_cap_mask & ~(0x300)) | ($cap_rx_stbc << 8) ))"
mac80211_add_capabilities ht_capab_flags $ht_cap_mask \
LDPC:0x1::$ldpc \
GF:0x10::$greenfield \
SHORT-GI-20:0x20::$short_gi_20 \
SHORT-GI-40:0x40::$short_gi_40 \
TX-STBC:0x80::$tx_stbc \
RX-STBC1:0x300:0x100:1 \
RX-STBC12:0x300:0x200:1 \
RX-STBC123:0x300:0x300:1 \
MAX-AMSDU-7935:0x800::$max_amsdu \
DSSS_CCK-40:0x1000::$dsss_cck_40
ht_capab="$ht_capab$ht_capab_flags"
[ -n "$ht_capab" ] && append base_cfg "ht_capab=$ht_capab" "$N"
}
# 802.11ac
enable_ac=0
idx="$channel"
case "$htmode" in
VHT20) enable_ac=1;;
VHT40)
case "$(( ($channel / 4) % 2 ))" in
1) idx=$(($channel + 2));;
0) idx=$(($channel - 2));;
esac
enable_ac=1
append base_cfg "vht_oper_chwidth=0" "$N"
append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N"
;;
VHT80)
case "$(( ($channel / 4) % 4 ))" in
1) idx=$(($channel + 6));;
2) idx=$(($channel + 2));;
3) idx=$(($channel - 2));;
0) idx=$(($channel - 6));;
esac
enable_ac=1
append base_cfg "vht_oper_chwidth=1" "$N"
append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N"
;;
VHT160)
case "$channel" in
36|40|44|48|52|56|60|64) idx=50;;
100|104|108|112|116|120|124|128) idx=114;;
esac
enable_ac=1
append base_cfg "vht_oper_chwidth=2" "$N"
append base_cfg "vht_oper_centr_freq_seg0_idx=$idx" "$N"
;;
esac
if [ "$enable_ac" != "0" ]; then
json_get_vars \
rxldpc:1 \
short_gi_80:1 \
short_gi_160:1 \
tx_stbc_2by1:1 \
su_beamformer:1 \
su_beamformee:1 \
mu_beamformer:1 \
mu_beamformee:1 \
vht_txop_ps:1 \
htc_vht:1 \
rx_antenna_pattern:1 \
tx_antenna_pattern:1 \
vht_max_a_mpdu_len_exp:7 \
vht_max_mpdu:11454 \
rx_stbc:4 \
vht_link_adapt:3 \
vht160:2
set_default tx_burst 2.0
append base_cfg "ieee80211ac=1" "$N"
vht_cap=0
for cap in $(iw phy "$phy" info | awk -F "[()]" '/VHT Capabilities/ { print $2 }'); do
vht_cap="$(($vht_cap | $cap))"
done
cap_rx_stbc=$((($vht_cap >> 8) & 7))
[ "$rx_stbc" -lt "$cap_rx_stbc" ] && cap_rx_stbc="$rx_stbc"
vht_cap="$(( ($vht_cap & ~(0x700)) | ($cap_rx_stbc << 8) ))"
mac80211_add_capabilities vht_capab $vht_cap \
RXLDPC:0x10::$rxldpc \
SHORT-GI-80:0x20::$short_gi_80 \
SHORT-GI-160:0x40::$short_gi_160 \
TX-STBC-2BY1:0x80::$tx_stbc_2by1 \
SU-BEAMFORMER:0x800::$su_beamformer \
SU-BEAMFORMEE:0x1000::$su_beamformee \
MU-BEAMFORMER:0x80000::$mu_beamformer \
MU-BEAMFORMEE:0x100000::$mu_beamformee \
VHT-TXOP-PS:0x200000::$vht_txop_ps \
HTC-VHT:0x400000::$htc_vht \
RX-ANTENNA-PATTERN:0x10000000::$rx_antenna_pattern \
TX-ANTENNA-PATTERN:0x20000000::$tx_antenna_pattern \
RX-STBC-1:0x700:0x100:1 \
RX-STBC-12:0x700:0x200:1 \
RX-STBC-123:0x700:0x300:1 \
RX-STBC-1234:0x700:0x400:1 \
# supported Channel widths
vht160_hw=0
[ "$(($vht_cap & 12))" -eq 4 -a 1 -le "$vht160" ] && \
vht160_hw=1
[ "$(($vht_cap & 12))" -eq 8 -a 2 -le "$vht160" ] && \
vht160_hw=2
[ "$vht160_hw" = 1 ] && vht_capab="$vht_capab[VHT160]"
[ "$vht160_hw" = 2 ] && vht_capab="$vht_capab[VHT160-80PLUS80]"
# maximum MPDU length
vht_max_mpdu_hw=3895
[ "$(($vht_cap & 3))" -ge 1 -a 7991 -le "$vht_max_mpdu" ] && \
vht_max_mpdu_hw=7991
[ "$(($vht_cap & 3))" -ge 2 -a 11454 -le "$vht_max_mpdu" ] && \
vht_max_mpdu_hw=11454
[ "$vht_max_mpdu_hw" != 3895 ] && \
vht_capab="$vht_capab[MAX-MPDU-$vht_max_mpdu_hw]"
# maximum A-MPDU length exponent
vht_max_a_mpdu_len_exp_hw=0
[ "$(($vht_cap & 58720256))" -ge 8388608 -a 1 -le "$vht_max_a_mpdu_len_exp" ] && \
vht_max_a_mpdu_len_exp_hw=1
[ "$(($vht_cap & 58720256))" -ge 16777216 -a 2 -le "$vht_max_a_mpdu_len_exp" ] && \
vht_max_a_mpdu_len_exp_hw=2
[ "$(($vht_cap & 58720256))" -ge 25165824 -a 3 -le "$vht_max_a_mpdu_len_exp" ] && \
vht_max_a_mpdu_len_exp_hw=3
[ "$(($vht_cap & 58720256))" -ge 33554432 -a 4 -le "$vht_max_a_mpdu_len_exp" ] && \
vht_max_a_mpdu_len_exp_hw=4
[ "$(($vht_cap & 58720256))" -ge 41943040 -a 5 -le "$vht_max_a_mpdu_len_exp" ] && \
vht_max_a_mpdu_len_exp_hw=5
[ "$(($vht_cap & 58720256))" -ge 50331648 -a 6 -le "$vht_max_a_mpdu_len_exp" ] && \
vht_max_a_mpdu_len_exp_hw=6
[ "$(($vht_cap & 58720256))" -ge 58720256 -a 7 -le "$vht_max_a_mpdu_len_exp" ] && \
vht_max_a_mpdu_len_exp_hw=7
vht_capab="$vht_capab[MAX-A-MPDU-LEN-EXP$vht_max_a_mpdu_len_exp_hw]"
# whether or not the STA supports link adaptation using VHT variant
vht_link_adapt_hw=0
[ "$(($vht_cap & 201326592))" -ge 134217728 -a 2 -le "$vht_link_adapt" ] && \
vht_link_adapt_hw=2
[ "$(($vht_cap & 201326592))" -ge 201326592 -a 3 -le "$vht_link_adapt" ] && \
vht_link_adapt_hw=3
[ "$vht_link_adapt_hw" != 0 ] && \
vht_capab="$vht_capab[VHT-LINK-ADAPT-$vht_link_adapt_hw]"
[ -n "$vht_capab" ] && append base_cfg "vht_capab=$vht_capab" "$N"
fi
hostapd_prepare_device_config "$hostapd_conf_file" nl80211
cat >> "$hostapd_conf_file" <<EOF
${channel:+channel=$channel}
${channel_list:+chanlist=$channel_list}
${hostapd_noscan:+noscan=1}
${tx_burst:+tx_queue_data2_burst=$tx_burst}
$base_cfg
EOF
json_select ..
}
mac80211_hostapd_setup_bss() {
local phy="$1"
local ifname="$2"
local macaddr="$3"
local type="$4"
hostapd_cfg=
append hostapd_cfg "$type=$ifname" "$N"
hostapd_set_bss_options hostapd_cfg "$vif" || return 1
json_get_vars wds dtim_period max_listen_int start_disabled
set_default wds 0
set_default start_disabled 0
[ "$wds" -gt 0 ] && append hostapd_cfg "wds_sta=1" "$N"
[ "$staidx" -gt 0 -o "$start_disabled" -eq 1 ] && append hostapd_cfg "start_disabled=1" "$N"
cat >> /var/run/hostapd-$phy.conf <<EOF
$hostapd_cfg
bssid=$macaddr
${dtim_period:+dtim_period=$dtim_period}
${max_listen_int:+max_listen_interval=$max_listen_int}
EOF
}
mac80211_get_addr() {
local phy="$1"
local idx="$(($2 + 1))"
head -n $idx /sys/class/ieee80211/${phy}/addresses | tail -n1
}
mac80211_generate_mac() {
local phy="$1"
local id="${macidx:-0}"
local ref="$(cat /sys/class/ieee80211/${phy}/macaddress)"
local mask="$(cat /sys/class/ieee80211/${phy}/address_mask)"
[ "$mask" = "00:00:00:00:00:00" ] && {
mask="ff:ff:ff:ff:ff:ff";
[ "$(wc -l < /sys/class/ieee80211/${phy}/addresses)" -gt 1 ] && {
addr="$(mac80211_get_addr "$phy" "$id")"
[ -n "$addr" ] && {
echo "$addr"
return
}
}
}
local oIFS="$IFS"; IFS=":"; set -- $mask; IFS="$oIFS"
local mask1=$1
local mask6=$6
local oIFS="$IFS"; IFS=":"; set -- $ref; IFS="$oIFS"
macidx=$(($id + 1))
[ "$((0x$mask1))" -gt 0 ] && {
b1="0x$1"
[ "$id" -gt 0 ] && \
b1=$(($b1 ^ ((($id - 1) << 2) | 0x2)))
printf "%02x:%s:%s:%s:%s:%s" $b1 $2 $3 $4 $5 $6
return
}
[ "$((0x$mask6))" -lt 255 ] && {
printf "%s:%s:%s:%s:%s:%02x" $1 $2 $3 $4 $5 $(( 0x$6 ^ $id ))
return
}
off2=$(( (0x$6 + $id) / 0x100 ))
printf "%s:%s:%s:%s:%02x:%02x" \
$1 $2 $3 $4 \
$(( (0x$5 + $off2) % 0x100 )) \
$(( (0x$6 + $id) % 0x100 ))
}
find_phy() {
[ -n "$phy" -a -d /sys/class/ieee80211/$phy ] && return 0
[ -n "$path" ] && {
for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
case "$(readlink -f /sys/class/ieee80211/$phy/device)" in
*$path) return 0;;
esac
done
}
[ -n "$macaddr" ] && {
for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
grep -i -q "$macaddr" "/sys/class/ieee80211/${phy}/macaddress" && return 0
done
}
return 1
}
mac80211_check_ap() {
has_ap=1
}
mac80211_iw_interface_add() {
local phy="$1"
local ifname="$2"
local type="$3"
local wdsflag="$4"
local rc
iw phy "$phy" interface add "$ifname" type "$type" $wdsflag
rc="$?"
[ "$rc" = 233 ] && {
# Device might have just been deleted, give the kernel some time to finish cleaning it up
sleep 1
iw phy "$phy" interface add "$ifname" type "$type" $wdsflag
rc="$?"
}
[ "$rc" = 233 ] && {
# Device might not support virtual interfaces, so the interface never got deleted in the first place.
# Check if the interface already exists, and avoid failing in this case.
ip link show dev "$ifname" >/dev/null 2>/dev/null && rc=0
}
[ "$rc" != 0 ] && wireless_setup_failed INTERFACE_CREATION_FAILED
return $rc
}
mac80211_prepare_vif() {
json_select config
json_get_vars ifname mode ssid wds powersave macaddr
[ -n "$ifname" ] || ifname="wlan${phy#phy}${if_idx:+-$if_idx}"
if_idx=$((${if_idx:-0} + 1))
set_default wds 0
set_default powersave 0
json_select ..
[ -n "$macaddr" ] || {
macaddr="$(mac80211_generate_mac $phy)"
macidx="$(($macidx + 1))"
}
json_add_object data
json_add_string ifname "$ifname"
json_close_object
json_select config
# It is far easier to delete and create the desired interface
case "$mode" in
adhoc)
mac80211_iw_interface_add "$phy" "$ifname" adhoc || return
;;
ap)
# Hostapd will handle recreating the interface and
# subsequent virtual APs belonging to the same PHY
if [ -n "$hostapd_ctrl" ]; then
type=bss
else
type=interface
fi
mac80211_hostapd_setup_bss "$phy" "$ifname" "$macaddr" "$type" || return
[ -n "$hostapd_ctrl" ] || {
mac80211_iw_interface_add "$phy" "$ifname" __ap || return
hostapd_ctrl="${hostapd_ctrl:-/var/run/hostapd/$ifname}"
}
;;
mesh)
mac80211_iw_interface_add "$phy" "$ifname" mp || return
;;
monitor)
mac80211_iw_interface_add "$phy" "$ifname" monitor || return
;;
sta)
local wdsflag=
staidx="$(($staidx + 1))"
[ "$wds" -gt 0 ] && wdsflag="4addr on"
mac80211_iw_interface_add "$phy" "$ifname" managed "$wdsflag" || return
[ "$powersave" -gt 0 ] && powersave="on" || powersave="off"
iw "$ifname" set power_save "$powersave"
;;
esac
case "$mode" in
monitor|mesh)
[ "$auto_channel" -gt 0 ] || iw dev "$ifname" set channel "$channel" $iw_htmode
;;
esac
if [ "$mode" != "ap" ]; then
# ALL ap functionality will be passed to hostapd
# All interfaces must have unique mac addresses
# which can either be explicitly set in the device
# section, or automatically generated
ip link set dev "$ifname" address "$macaddr"
fi
json_select ..
}
mac80211_setup_supplicant() {
wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1
if [ "$mode" = "sta" ]; then
wpa_supplicant_add_network "$ifname"
else
wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan"
fi
wpa_supplicant_run "$ifname" ${hostapd_ctrl:+-H $hostapd_ctrl}
}
mac80211_setup_supplicant_noctl() {
wpa_supplicant_prepare_interface "$ifname" nl80211 || return 1
wpa_supplicant_add_network "$ifname" "$freq" "$htmode" "$noscan"
wpa_supplicant_run "$ifname"
}
mac80211_prepare_iw_htmode() {
case "$htmode" in
VHT20|HT20) iw_htmode=HT20;;
HT40*|VHT40|VHT160)
case "$hwmode" in
a)
case "$(( ($channel / 4) % 2 ))" in
1) iw_htmode="HT40+" ;;
0) iw_htmode="HT40-";;
esac
;;
*)
case "$htmode" in
HT40+) iw_htmode="HT40+";;
HT40-) iw_htmode="HT40-";;
*)
if [ "$channel" -lt 7 ]; then
iw_htmode="HT40+"
else
iw_htmode="HT40-"
fi
;;
esac
;;
esac
[ "$auto_channel" -gt 0 ] && iw_htmode="HT40+"
;;
VHT80)
iw_htmode="80MHZ"
;;
NONE|NOHT)
iw_htmode="NOHT"
;;
*) iw_htmode="" ;;
esac
}
mac80211_setup_adhoc() {
json_get_vars bssid ssid key mcast_rate
keyspec=
[ "$auth_type" = "wep" ] && {
set_default key 1
case "$key" in
[1234])
local idx
for idx in 1 2 3 4; do
json_get_var ikey "key$idx"
[ -n "$ikey" ] && {
ikey="$(($idx - 1)):$(prepare_key_wep "$ikey")"
[ $idx -eq $key ] && ikey="d:$ikey"
append keyspec "$ikey"
}
done
;;
*)
append keyspec "d:0:$(prepare_key_wep "$key")"
;;
esac
}
brstr=
for br in $basic_rate_list; do
wpa_supplicant_add_rate brstr "$br"
done
mcval=
[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
iw dev "$ifname" ibss join "$ssid" $freq $iw_htmode fixed-freq $bssid \
beacon-interval $beacon_int \
${brstr:+basic-rates $brstr} \
${mcval:+mcast-rate $mcval} \
${keyspec:+keys $keyspec}
}
mac80211_setup_mesh() {
json_get_vars ssid mesh_id mcast_rate
mcval=
[ -n "$mcast_rate" ] && wpa_supplicant_add_rate mcval "$mcast_rate"
[ -n "$mesh_id" ] && ssid="$mesh_id"
iw dev "$ifname" mesh join "$ssid" freq $freq $iw_htmode \
${mcval:+mcast-rate $mcval} \
beacon-interval $beacon_int
}
mac80211_setup_vif() {
local name="$1"
local failed
json_select data
json_get_vars ifname
json_select ..
json_select config
json_get_vars mode
json_get_var vif_txpower txpower
ip link set dev "$ifname" up || {
wireless_setup_vif_failed IFUP_ERROR
json_select ..
return
}
set_default vif_txpower "$txpower"
[ -z "$vif_txpower" ] || iw dev "$ifname" set txpower fixed "${vif_txpower%%.*}00"
case "$mode" in
mesh)
wireless_vif_parse_encryption
freq="$(get_freq "$phy" "$channel")"
if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ] || chan_is_dfs "$phy" "$channel"; then
mac80211_setup_supplicant || failed=1
else
mac80211_setup_mesh
fi
for var in $MP_CONFIG_INT $MP_CONFIG_BOOL $MP_CONFIG_STRING; do
json_get_var mp_val "$var"
[ -n "$mp_val" ] && iw dev "$ifname" set mesh_param "$var" "$mp_val"
done
;;
adhoc)
wireless_vif_parse_encryption
if [ "$wpa" -gt 0 -o "$auto_channel" -gt 0 ]; then
freq="$(get_freq "$phy" "$channel")"
mac80211_setup_supplicant_noctl || failed=1
else
mac80211_setup_adhoc
fi
;;
sta)
mac80211_setup_supplicant || failed=1
;;
esac
json_select ..
[ -n "$failed" ] || wireless_add_vif "$name" "$ifname"
}
get_freq() {
local phy="$1"
local chan="$2"
iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep MHz | awk '{print $2}'
}
chan_is_dfs() {
local phy="$1"
local chan="$2"
iw "$phy" info | grep -E -m1 "(\* ${chan:-....} MHz${chan:+|\\[$chan\\]})" | grep -q "MHz.*radar detection"
return $!
}
mac80211_interface_cleanup() {
local phy="$1"
for wdev in $(list_phy_interfaces "$phy"); do
ip link set dev "$wdev" down 2>/dev/null
iw dev "$wdev" del
done
}
mac80211_set_noscan() {
hostapd_noscan=1
}
drv_mac80211_cleanup() {
hostapd_common_cleanup
}
drv_mac80211_setup() {
json_select config
json_get_vars \
phy macaddr path \
country chanbw distance \
txpower antenna_gain \
rxantenna txantenna \
frag rts beacon_int:100 htmode
json_get_values basic_rate_list basic_rate
json_select ..
find_phy || {
echo "Could not find PHY for device '$1'"
wireless_set_retry 0
return 1
}
wireless_set_data phy="$phy"
mac80211_interface_cleanup "$phy"
# convert channel to frequency
[ "$auto_channel" -gt 0 ] || freq="$(get_freq "$phy" "$channel")"
[ -n "$country" ] && {
iw reg get | grep -q "^country $country:" || {
iw reg set "$country"
sleep 1
}
}
hostapd_conf_file="/var/run/hostapd-$phy.conf"
no_ap=1
macidx=0
staidx=0
[ -n "$chanbw" ] && {
for file in /sys/kernel/debug/ieee80211/$phy/ath9k/chanbw /sys/kernel/debug/ieee80211/$phy/ath5k/bwmode; do
[ -f "$file" ] && echo "$chanbw" > "$file"
done
}
set_default rxantenna 0xffffffff
set_default txantenna 0xffffffff
set_default distance 0
set_default antenna_gain 0
[ "$txantenna" = "all" ] && txantenna=0xffffffff
[ "$rxantenna" = "all" ] && rxantenna=0xffffffff
iw phy "$phy" set antenna $txantenna $rxantenna >/dev/null 2>&1
iw phy "$phy" set antenna_gain $antenna_gain
iw phy "$phy" set distance "$distance"
[ -n "$frag" ] && iw phy "$phy" set frag "${frag%%.*}"
[ -n "$rts" ] && iw phy "$phy" set rts "${rts%%.*}"
has_ap=
hostapd_ctrl=
hostapd_noscan=
for_each_interface "ap" mac80211_check_ap
rm -f "$hostapd_conf_file"
for_each_interface "sta adhoc mesh" mac80211_set_noscan
[ -n "$has_ap" ] && mac80211_hostapd_setup_base "$phy"
mac80211_prepare_iw_htmode
for_each_interface "sta adhoc mesh monitor" mac80211_prepare_vif
for_each_interface "ap" mac80211_prepare_vif
[ -n "$hostapd_ctrl" ] && {
/usr/sbin/hostapd -s -P /var/run/wifi-$phy.pid -B "$hostapd_conf_file"
ret="$?"
wireless_add_process "$(cat /var/run/wifi-$phy.pid)" "/usr/sbin/hostapd" 1
[ "$ret" != 0 ] && {
wireless_setup_failed HOSTAPD_START_FAILED
return
}
}
for_each_interface "ap sta adhoc mesh monitor" mac80211_setup_vif
wireless_set_up
}
list_phy_interfaces() {
local phy="$1"
if [ -d "/sys/class/ieee80211/${phy}/device/net" ]; then
ls "/sys/class/ieee80211/${phy}/device/net" 2>/dev/null;
else
ls "/sys/class/ieee80211/${phy}/device" 2>/dev/null | grep net: | sed -e 's,net:,,g'
fi
}
drv_mac80211_teardown() {
wireless_process_kill_all
json_select data
json_get_vars phy
json_select ..
mac80211_interface_cleanup "$phy"
}
add_driver mac80211

View File

@@ -0,0 +1,129 @@
#!/bin/sh
append DRIVERS "mac80211"
lookup_phy() {
[ -n "$phy" ] && {
[ -d /sys/class/ieee80211/$phy ] && return
}
local devpath
config_get devpath "$device" path
[ -n "$devpath" ] && {
for phy in $(ls /sys/class/ieee80211 2>/dev/null); do
case "$(readlink -f /sys/class/ieee80211/$phy/device)" in
*$devpath) return;;
esac
done
}
local macaddr="$(config_get "$device" macaddr | tr 'A-Z' 'a-z')"
[ -n "$macaddr" ] && {
for _phy in /sys/class/ieee80211/*; do
[ -e "$_phy" ] || continue
[ "$macaddr" = "$(cat ${_phy}/macaddress)" ] || continue
phy="${_phy##*/}"
return
done
}
phy=
return
}
find_mac80211_phy() {
local device="$1"
config_get phy "$device" phy
lookup_phy
[ -n "$phy" -a -d "/sys/class/ieee80211/$phy" ] || {
echo "PHY for wifi device $1 not found"
return 1
}
config_set "$device" phy "$phy"
config_get macaddr "$device" macaddr
[ -z "$macaddr" ] && {
config_set "$device" macaddr "$(cat /sys/class/ieee80211/${phy}/macaddress)"
}
return 0
}
check_mac80211_device() {
config_get phy "$1" phy
[ -z "$phy" ] && {
find_mac80211_phy "$1" >/dev/null || return 0
config_get phy "$1" phy
}
[ "$phy" = "$dev" ] && found=1
}
detect_mac80211() {
devidx=0
config_load wireless
while :; do
config_get type "radio$devidx" type
[ -n "$type" ] || break
devidx=$(($devidx + 1))
done
for _dev in /sys/class/ieee80211/*; do
[ -e "$_dev" ] || continue
dev="${_dev##*/}"
found=0
config_foreach check_mac80211_device wifi-device
[ "$found" -gt 0 ] && continue
mode_band="g"
channel="11"
htmode=""
ht_capab=""
iw phy "$dev" info | grep -q 'Capabilities:' && htmode=HT20
iw phy "$dev" info | grep -q '5180 MHz' && {
mode_band="a"
channel="36"
iw phy "$dev" info | grep -q 'VHT Capabilities' && htmode="VHT80"
}
[ -n "$htmode" ] && ht_capab="set wireless.radio${devidx}.htmode=$htmode"
if [ -x /usr/bin/readlink -a -h /sys/class/ieee80211/${dev} ]; then
path="$(readlink -f /sys/class/ieee80211/${dev}/device)"
else
path=""
fi
if [ -n "$path" ]; then
path="${path##/sys/devices/}"
case "$path" in
platform*/pci*) path="${path##platform/}";;
esac
dev_id="set wireless.radio${devidx}.path='$path'"
else
dev_id="set wireless.radio${devidx}.macaddr=$(cat /sys/class/ieee80211/${dev}/macaddress)"
fi
uci -q batch <<-EOF
set wireless.radio${devidx}=wifi-device
set wireless.radio${devidx}.type=mac80211
set wireless.radio${devidx}.channel=${channel}
set wireless.radio${devidx}.hwmode=11${mode_band}
${dev_id}
${ht_capab}
set wireless.radio${devidx}.disabled=1
set wireless.default_radio${devidx}=wifi-iface
set wireless.default_radio${devidx}.device=radio${devidx}
set wireless.default_radio${devidx}.network=lan
set wireless.default_radio${devidx}.mode=ap
set wireless.default_radio${devidx}.ssid=OpenWrt
set wireless.default_radio${devidx}.encryption=none
EOF
uci -q commit wireless
devidx=$(($devidx + 1))
done
}

View File

@@ -0,0 +1,5 @@
#!/bin/sh
[ "${ACTION}" = "add" ] && {
/sbin/wifi config
}

View File

@@ -0,0 +1,200 @@
PKG_DRIVERS += \
iwl-legacy iwl3945 iwl4965 iwlwifi \
libipw ipw2100 ipw2200 \
config-$(call config_package,iwl-legacy) += IWLEGACY
config-$(call config_package,iwl3945) += IWL3945
config-$(call config_package,iwl4965) += IWL4965
config-$(call config_package,iwlwifi) += IWLWIFI IWLDVM IWLMVM
config-$(CONFIG_PACKAGE_IWLWIFI_DEBUG)+= IWLWIFI_DEBUG
config-$(CONFIG_PACKAGE_IWLWIFI_DEBUGFS)+= IWLWIFI_DEBUGFS
config-$(call config_package,libipw) += LIBIPW
config-$(call config_package,ipw2100) += IPW2100
config-$(call config_package,ipw2200) += IPW2200
define KernelPackage/iwlwifi
$(call KernelPackage/mac80211/Default)
DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT
TITLE:=Intel AGN Wireless support
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/dvm/iwldvm.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/mvm/iwlmvm.ko
AUTOLOAD:=$(call AutoProbe,iwlwifi iwldvm iwlmvm)
MENU:=1
endef
define KernelPackage/iwlwifi/description
iwlwifi kernel module for
Intel Wireless WiFi Link 6250AGN Adapter
Intel 6000 Series Wi-Fi Adapters (6200AGN and 6300AGN)
Intel WiFi Link 1000BGN
Intel Wireless WiFi 5150AGN
Intel Wireless WiFi 5100AGN, 5300AGN, and 5350AGN
Intel 6005 Series Wi-Fi Adapters
Intel 6030 Series Wi-Fi Adapters
Intel Wireless WiFi Link 6150BGN 2 Adapter
Intel 100 Series Wi-Fi Adapters (100BGN and 130BGN)
Intel 2000 Series Wi-Fi Adapters
Intel 7260 Wi-Fi Adapter
Intel 3160 Wi-Fi Adapter
Intel 7265 Wi-Fi Adapter
Intel 8260 Wi-Fi Adapter
Intel 3165 Wi-Fi Adapter
endef
define KernelPackage/iwlwifi/config
if PACKAGE_kmod-iwlwifi
config PACKAGE_IWLWIFI_DEBUG
bool "Enable full debugging output in the iwlwifi driver"
default n
help
This option will enable debug tracing output for the iwlwifi drivers
This will result in the kernel module being ~100k larger. You can
control which debug output is sent to the kernel log by setting the
value in
/sys/module/iwlwifi/parameters/debug
This entry will only exist if this option is enabled.
To set a value, simply echo an 8-byte hex value to the same file:
% echo 0x43fff > /sys/module/iwlwifi/parameters/debug
You can find the list of debug mask values in:
drivers/net/wireless/intel/iwlwifi/iwl-debug.h
If this is your first time using this driver, you should say Y here
as the debug information can assist others in helping you resolve
any problems you may encounter.
config PACKAGE_IWLWIFI_DEBUGFS
bool "iwlwifi debugfs support"
depends on PACKAGE_MAC80211_DEBUGFS
default n
help
Enable creation of debugfs files for the iwlwifi drivers. This
is a low-impact option that allows getting insight into the
driver's state at runtime.
endif
endef
define KernelPackage/iwl-legacy
$(call KernelPackage/mac80211/Default)
DEPENDS:= +kmod-mac80211 @PCI_SUPPORT
TITLE:=Intel legacy Wireless support
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlegacy/iwlegacy.ko
AUTOLOAD:=$(call AutoProbe,iwlegacy)
endef
define KernelPackage/iwl-legacy/description
iwl-legacy kernel module for legacy Intel wireless support
endef
define KernelPackage/iwl3945
$(call KernelPackage/mac80211/Default)
DEPENDS:= +kmod-mac80211 +kmod-iwl-legacy +iwl3945-firmware
TITLE:=Intel iwl3945 Wireless support
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlegacy/iwl3945.ko
AUTOLOAD:=$(call AutoProbe,iwl3945)
endef
define KernelPackage/iwl3945/description
iwl3945 kernel module for Intel 3945 support
endef
define KernelPackage/iwl4965
$(call KernelPackage/mac80211/Default)
DEPENDS:= +kmod-mac80211 +kmod-iwl-legacy +@DRIVER_11N_SUPPORT +iwl4965-firmware
TITLE:=Intel iwl4965 Wireless support
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlegacy/iwl4965.ko
AUTOLOAD:=$(call AutoProbe,iwl4965)
endef
define KernelPackage/iwl4965/description
iwl4965 kernel module for Intel 4965 support
endef
define KernelPackage/libipw
$(call KernelPackage/mac80211/Default)
TITLE:=libipw for ipw2100 and ipw2200
DEPENDS:=@PCI_SUPPORT +kmod-crypto-michael-mic +kmod-crypto-ecb +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/libipw.ko
AUTOLOAD:=$(call AutoProbe,libipw)
endef
define KernelPackage/libipw/description
Hardware independent IEEE 802.11 networking stack for ipw2100 and ipw2200.
endef
IPW2100_NAME:=ipw2100-fw
IPW2100_VERSION:=1.3
define Download/ipw2100
URL:= \
https://src.fedoraproject.org/repo/pkgs/ipw2100-firmware/ipw2100-fw-1.3.tgz/46aa75bcda1a00efa841f9707bbbd113/ \
https://archlinux.mirror.pkern.at/other/packages/ipw2100-fw/ \
http://mirror.ox.ac.uk/sites/ftp.openbsd.org/pub/OpenBSD/distfiles/firmware/ \
http://firmware.openbsd.org/firmware-dist/
FILE:=$(IPW2100_NAME)-$(IPW2100_VERSION).tgz
HASH:=e1107c455e48d324a616b47a622593bc8413dcce72026f72731c0b03dae3a7a2
endef
$(eval $(call Download,ipw2100))
define KernelPackage/ipw2100
$(call KernelPackage/mac80211/Default)
TITLE:=Intel IPW2100 driver
DEPENDS:=@PCI_SUPPORT +kmod-libipw
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/ipw2100.ko
AUTOLOAD:=$(call AutoProbe,ipw2100)
endef
define KernelPackage/ipw2100/description
Kernel support for Intel IPW2100
Includes:
- ipw2100
endef
IPW2200_NAME:=ipw2200-fw
IPW2200_VERSION:=3.1
define Download/ipw2200
URL:= \
https://src.fedoraproject.org/repo/pkgs/ipw2200-firmware/ipw2200-fw-3.1.tgz/eaba788643c7cc7483dd67ace70f6e99/ \
https://archlinux.mirror.pkern.at/other/packages/ipw2200-fw/ \
http://mirror.ox.ac.uk/sites/ftp.openbsd.org/pub/OpenBSD/distfiles/firmware/ \
http://firmware.openbsd.org/firmware-dist/
FILE:=$(IPW2200_NAME)-$(IPW2200_VERSION).tgz
HASH:=c6818c11c18cc030d55ff83f64b2bad8feef485e7742f84f94a61d811a6258bd
endef
$(eval $(call Download,ipw2200))
define KernelPackage/ipw2200
$(call KernelPackage/mac80211/Default)
TITLE:=Intel IPW2200 driver
DEPENDS:=@PCI_SUPPORT +kmod-libipw
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/ipw2200.ko
AUTOLOAD:=$(call AutoProbe,ipw2200)
endef
define KernelPackage/ipw2200/description
Kernel support for Intel IPW2200
Includes:
- ipw2200
endef
define KernelPackage/ipw2100/install
$(INSTALL_DIR) $(1)/lib/firmware
$(INSTALL_DATA) $(PKG_BUILD_DIR)/ipw2100-$(IPW2100_VERSION)*.fw $(1)/lib/firmware
endef
define KernelPackage/ipw2200/install
$(INSTALL_DIR) $(1)/lib/firmware
$(INSTALL_DATA) $(PKG_BUILD_DIR)/$(IPW2200_NAME)-$(IPW2200_VERSION)/ipw2200*.fw $(1)/lib/firmware
endef

View File

@@ -0,0 +1,90 @@
PKG_DRIVERS += \
libertas-sdio libertas-usb libertas-spi \
mwl8k mwifiex-pcie mwifiex-sdio
config-$(call config_package,libertas-sdio) += LIBERTAS LIBERTAS_SDIO
config-$(call config_package,libertas-usb) += LIBERTAS LIBERTAS_USB
config-$(call config_package,libertas-spi) += LIBERTAS LIBERTAS_SPI
config-$(call config_package,mwl8k) += MWL8K
config-$(call config_package,mwifiex-pcie) += MWIFIEX MWIFIEX_PCIE
config-$(call config_package,mwifiex-sdio) += MWIFIEX MWIFIEX_SDIO
define KernelPackage/libertas-usb
$(call KernelPackage/mac80211/Default)
DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +kmod-usb-core +kmod-lib80211 +@DRIVER_WEXT_SUPPORT +libertas-usb-firmware
TITLE:=Marvell 88W8015 Wireless Driver
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/usb8xxx.ko
AUTOLOAD:=$(call AutoProbe,libertas usb8xxx)
endef
define KernelPackage/libertas-sdio
$(call KernelPackage/mac80211/Default)
DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-sdio-firmware
TITLE:=Marvell 88W8686 Wireless Driver
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_sdio.ko
AUTOLOAD:=$(call AutoProbe,libertas libertas_sdio)
endef
define KernelPackage/libertas-spi
$(call KernelPackage/mac80211/Default)
SUBMENU:=Wireless Drivers
DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-spi-firmware
KCONFIG := \
CONFIG_SPI=y \
CONFIG_SPI_MASTER=y
TITLE:=Marvell 88W8686 SPI Wireless Driver
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas_spi.ko
AUTOLOAD:=$(call AutoProbe,libertas libertas_spi)
endef
define KernelPackage/mwl8k
$(call KernelPackage/mac80211/Default)
TITLE:=Driver for Marvell TOPDOG 802.11 Wireless cards
URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwl8k
DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT +mwl8k-firmware
FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwl8k.ko
AUTOLOAD:=$(call AutoProbe,mwl8k)
endef
define KernelPackage/mwl8k/description
Kernel modules for Marvell TOPDOG 802.11 Wireless cards
endef
define KernelPackage/mwifiex-pcie
$(call KernelPackage/mac80211/Default)
TITLE:=Driver for Marvell 802.11n/802.11ac PCIe Wireless cards
URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex
DEPENDS+= @PCI_SUPPORT +kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +mwifiex-pcie-firmware
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_pcie.ko
AUTOLOAD:=$(call AutoProbe,mwifiex_pcie)
endef
define KernelPackage/mwifiex-pcie/description
Kernel modules for Marvell 802.11n/802.11ac PCIe Wireless cards
endef
define KernelPackage/mwifiex-sdio
$(call KernelPackage/mac80211/Default)
TITLE:=Driver for Marvell 802.11n/802.11ac SDIO Wireless cards
URL:=https://wireless.wiki.kernel.org/en/users/drivers/mwifiex
DEPENDS+= +kmod-mmc +kmod-mac80211 +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +mwifiex-sdio-firmware
FILES:= \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex.ko \
$(PKG_BUILD_DIR)/drivers/net/wireless/marvell/mwifiex/mwifiex_sdio.ko
AUTOLOAD:=$(call AutoProbe,mwifiex_sdio)
endef
define KernelPackage/mwifiex-sdio/description
Kernel modules for Marvell 802.11n/802.11ac SDIO Wireless cards
endef

View File

@@ -0,0 +1,9 @@
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -1,5 +1,5 @@
config ATH_COMMON
- tristate
+ tristate "ath.ko"
depends on m
config WLAN_VENDOR_ATH

View File

@@ -0,0 +1,47 @@
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -85,6 +85,12 @@ config ATH10K_TRACING
---help---
Select this to ath10k use tracing infrastructure.
+config ATH10K_THERMAL
+ bool "Atheros ath10k thermal monitoring support"
+ depends on THERMAL
+ ---help---
+ Select this to ath10k use hwmon for thermal measurement.
+
config ATH10K_DFS_CERTIFIED
bool "Atheros DFS support for certified platforms"
depends on ATH10K && CFG80211_CERTIFICATION_ONUS
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -18,7 +18,7 @@ ath10k_core-y += mac.o \
ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) += spectral.o
ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
-ath10k_core-$(CONFIG_THERMAL) += thermal.o
+ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o
ath10k_core-$(CONFIG_PM) += wow.o
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
--- a/drivers/net/wireless/ath/ath10k/thermal.h
+++ b/drivers/net/wireless/ath/ath10k/thermal.h
@@ -36,7 +36,7 @@ struct ath10k_thermal {
int temperature;
};
-#if IS_REACHABLE(CONFIG_THERMAL)
+#if IS_REACHABLE(CPTCFG_ATH10K_THERMAL)
int ath10k_thermal_register(struct ath10k *ar);
void ath10k_thermal_unregister(struct ath10k *ar);
void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature);
--- a/local-symbols
+++ b/local-symbols
@@ -139,6 +139,7 @@ ATH10K_SNOC=
ATH10K_DEBUG=
ATH10K_DEBUGFS=
ATH10K_SPECTRAL=
+ATH10K_THERMAL=
ATH10K_TRACING=
ATH10K_DFS_CERTIFIED=
WCN36XX=

View File

@@ -0,0 +1,38 @@
--- a/drivers/net/wireless/ath/ath5k/initvals.c
+++ b/drivers/net/wireless/ath/ath5k/initvals.c
@@ -62,8 +62,14 @@ static const struct ath5k_ini ar5210_ini
{ AR5K_IMR, 0 },
{ AR5K_IER, AR5K_IER_DISABLE },
{ AR5K_BSR, 0, AR5K_INI_READ },
+#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79)
{ AR5K_TXCFG, AR5K_DMASIZE_128B },
{ AR5K_RXCFG, AR5K_DMASIZE_128B },
+#else
+ /* WAR for AR71xx PCI bug */
+ { AR5K_TXCFG, AR5K_DMASIZE_128B },
+ { AR5K_RXCFG, AR5K_DMASIZE_4B },
+#endif
{ AR5K_CFG, AR5K_INIT_CFG },
{ AR5K_TOPS, 8 },
{ AR5K_RXNOFRM, 8 },
--- a/drivers/net/wireless/ath/ath5k/dma.c
+++ b/drivers/net/wireless/ath/ath5k/dma.c
@@ -869,10 +869,18 @@ ath5k_hw_dma_init(struct ath5k_hw *ah)
* guess we can tweak it and see how it goes ;-)
*/
if (ah->ah_version != AR5K_AR5210) {
+#if !defined(CONFIG_ATHEROS_AR71XX) && !defined(CONFIG_ATH79)
AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B);
+#else
+ /* WAR for AR71xx PCI bug */
+ AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
+ AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B);
+ AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
+ AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_4B);
+#endif
}
/* Pre-enable interrupts on 5211/5212*/

View File

@@ -0,0 +1,25 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Sat, 9 Jul 2016 15:25:24 +0200
Subject: [PATCH] ath9k_hw: reset AHB-WMAC interface on AR91xx
Should fix a few stability issues
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1435,8 +1435,12 @@ static bool ath9k_hw_set_reset(struct at
if (!AR_SREV_9100(ah))
REG_WRITE(ah, AR_RC, 0);
- if (AR_SREV_9100(ah))
+ if (AR_SREV_9100(ah)) {
+ /* Reset the AHB-WMAC interface */
+ if (ah->external_reset)
+ ah->external_reset();
udelay(50);
+ }
return true;
}

View File

@@ -0,0 +1,129 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Sat, 9 Jul 2016 15:26:44 +0200
Subject: [PATCH] ath9k_hw: issue external reset for QCA955x
The RTC interface on the SoC needs to be reset along with the rest of
the WMAC.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1312,39 +1312,56 @@ void ath9k_hw_get_delta_slope_vals(struc
*coef_exponent = coef_exp - 16;
}
-/* AR9330 WAR:
- * call external reset function to reset WMAC if:
- * - doing a cold reset
- * - we have pending frames in the TX queues.
- */
-static bool ath9k_hw_ar9330_reset_war(struct ath_hw *ah, int type)
+static bool ath9k_hw_need_external_reset(struct ath_hw *ah, int type)
{
- int i, npend = 0;
+ int i;
- for (i = 0; i < AR_NUM_QCU; i++) {
- npend = ath9k_hw_numtxpending(ah, i);
- if (npend)
- break;
- }
-
- if (ah->external_reset &&
- (npend || type == ATH9K_RESET_COLD)) {
- int reset_err = 0;
-
- ath_dbg(ath9k_hw_common(ah), RESET,
- "reset MAC via external reset\n");
-
- reset_err = ah->external_reset();
- if (reset_err) {
- ath_err(ath9k_hw_common(ah),
- "External reset failed, err=%d\n",
- reset_err);
- return false;
+ if (type == ATH9K_RESET_COLD)
+ return true;
+
+ if (AR_SREV_9550(ah))
+ return true;
+
+ /* AR9330 WAR:
+ * call external reset function to reset WMAC if:
+ * - doing a cold reset
+ * - we have pending frames in the TX queues.
+ */
+ if (AR_SREV_9330(ah)) {
+ for (i = 0; i < AR_NUM_QCU; i++) {
+ if (ath9k_hw_numtxpending(ah, i))
+ return true;
}
+ }
+
+ return false;
+}
+
+static bool ath9k_hw_external_reset(struct ath_hw *ah, int type)
+{
+ int err;
+
+ if (!ah->external_reset || !ath9k_hw_need_external_reset(ah, type))
+ return true;
+
+ ath_dbg(ath9k_hw_common(ah), RESET,
+ "reset MAC via external reset\n");
- REG_WRITE(ah, AR_RTC_RESET, 1);
+ err = ah->external_reset();
+ if (err) {
+ ath_err(ath9k_hw_common(ah),
+ "External reset failed, err=%d\n", err);
+ return false;
}
+ if (AR_SREV_9550(ah)) {
+ REG_WRITE(ah, AR_RTC_RESET, 0);
+ udelay(10);
+ }
+
+ REG_WRITE(ah, AR_RTC_RESET, 1);
+ udelay(10);
+
return true;
}
@@ -1397,24 +1414,24 @@ static bool ath9k_hw_set_reset(struct at
rst_flags |= AR_RTC_RC_MAC_COLD;
}
- if (AR_SREV_9330(ah)) {
- if (!ath9k_hw_ar9330_reset_war(ah, type))
- return false;
- }
-
if (ath9k_hw_mci_is_enabled(ah))
ar9003_mci_check_gpm_offset(ah);
/* DMA HALT added to resolve ar9300 and ar9580 bus error during
- * RTC_RC reg read
+ * RTC_RC reg read. Also needed for AR9550 external reset
*/
- if (AR_SREV_9300(ah) || AR_SREV_9580(ah)) {
+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah) || AR_SREV_9550(ah)) {
REG_SET_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
ath9k_hw_wait(ah, AR_CFG, AR_CFG_HALT_ACK, AR_CFG_HALT_ACK,
20 * AH_WAIT_TIMEOUT);
- REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
}
+ if (!AR_SREV_9100(ah))
+ ath9k_hw_external_reset(ah, type);
+
+ if (AR_SREV_9300(ah) || AR_SREV_9580(ah))
+ REG_CLR_BIT(ah, AR_CFG, AR_CFG_HALT_REQ);
+
REG_WRITE(ah, AR_RTC_RC, rst_flags);
REGWRITE_BUFFER_FLUSH(ah);

View File

@@ -0,0 +1,35 @@
From: Felix Fietkau <nbd@openwrt.org>
Date: Sun, 7 Jun 2015 13:53:35 +0200
Subject: [PATCH] ath9k: force rx_clear when disabling rx
This makes stopping Rx more reliable and should reduce the frequency of
Rx related DMA stop warnings. Don't use rx_clear in TX99 mode.
Cc: stable@vger.kernel.org
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Helmut Schaa <helmut.schaa@googlemail.com>
---
--- a/drivers/net/wireless/ath/ath9k/mac.c
+++ b/drivers/net/wireless/ath/ath9k/mac.c
@@ -678,13 +678,18 @@ void ath9k_hw_startpcureceive(struct ath
ath9k_ani_reset(ah, is_scanning);
- REG_CLR_BIT(ah, AR_DIAG_SW, (AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT));
+ REG_CLR_BIT(ah, AR_DIAG_SW,
+ AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT | AR_DIAG_FORCE_RX_CLEAR);
}
EXPORT_SYMBOL(ath9k_hw_startpcureceive);
void ath9k_hw_abortpcurecv(struct ath_hw *ah)
{
- REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_ABORT | AR_DIAG_RX_DIS);
+ u32 reg = AR_DIAG_RX_DIS | AR_DIAG_RX_ABORT;
+
+ if (!IS_ENABLED(CPTCFG_ATH9K_TX99))
+ reg |= AR_DIAG_FORCE_RX_CLEAR;
+ REG_SET_BIT(ah, AR_DIAG_SW, reg);
ath9k_hw_disable_mib_counters(ah);
}

View File

@@ -0,0 +1,36 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Sat, 14 May 2016 14:51:02 +0200
Subject: [PATCH] Revert "ath9k: interpret requested txpower in EIRP
domain"
This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411.
---
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2976,7 +2976,8 @@ void ath9k_hw_apply_txpower(struct ath_h
{
struct ath_regulatory *reg = ath9k_hw_regulatory(ah);
struct ieee80211_channel *channel;
- int chan_pwr, new_pwr;
+ int chan_pwr, new_pwr, max_gain;
+ int ant_gain, ant_reduction = 0;
u16 ctl = NO_CTL;
if (!chan)
@@ -2988,9 +2989,14 @@ void ath9k_hw_apply_txpower(struct ath_h
channel = chan->chan;
chan_pwr = min_t(int, channel->max_power * 2, MAX_RATE_POWER);
new_pwr = min_t(int, chan_pwr, reg->power_limit);
+ max_gain = chan_pwr - new_pwr + channel->max_antenna_gain * 2;
+
+ ant_gain = get_antenna_gain(ah, chan);
+ if (ant_gain > max_gain)
+ ant_reduction = ant_gain - max_gain;
ah->eep_ops->set_txpower(ah, chan, ctl,
- get_antenna_gain(ah, chan), new_pwr, test);
+ ant_reduction, new_pwr, test);
}
void ath9k_hw_set_txpowerlimit(struct ath_hw *ah, u32 limit, bool test)

View File

@@ -0,0 +1,24 @@
From: Felix Fietkau <nbd@nbd.name>
Date: Wed, 19 Jul 2017 08:49:31 +0200
Subject: [PATCH] ath9k: adjust tx power reduction for US regulatory
domain
FCC regulatory rules allow for up to 6 dBi antenna gain. Account for
this in the EEPROM based tx power reduction code.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2995,6 +2995,10 @@ void ath9k_hw_apply_txpower(struct ath_h
if (ant_gain > max_gain)
ant_reduction = ant_gain - max_gain;
+ /* FCC allows maximum antenna gain of 6 dBi */
+ if (reg->region == NL80211_DFS_FCC)
+ ant_reduction = max_t(int, ant_reduction - 12, 0);
+
ah->eep_ops->set_txpower(ah, chan, ctl,
ant_reduction, new_pwr, test);
}

View File

@@ -0,0 +1,31 @@
--- a/drivers/net/wireless/ath/Makefile
+++ b/drivers/net/wireless/ath/Makefile
@@ -14,10 +14,10 @@ ath-objs := main.o \
regd.o \
hw.o \
key.o \
+ debug.o \
dfs_pattern_detector.o \
dfs_pri_detector.o
-ath-$(CPTCFG_ATH_DEBUG) += debug.o
ath-$(CPTCFG_ATH_TRACEPOINTS) += trace.o
CFLAGS_trace.o := -I$(src)
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -316,14 +316,7 @@ void _ath_dbg(struct ath_common *common,
#endif /* CPTCFG_ATH_DEBUG */
/** Returns string describing opmode, or NULL if unknown mode. */
-#ifdef CPTCFG_ATH_DEBUG
const char *ath_opmode_to_string(enum nl80211_iftype opmode);
-#else
-static inline const char *ath_opmode_to_string(enum nl80211_iftype opmode)
-{
- return "UNKNOWN";
-}
-#endif
extern const char *ath_bus_type_strings[];
static inline const char *ath_bus_type_to_string(enum ath_bus_type bustype)

View File

@@ -0,0 +1,11 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -48,7 +48,7 @@ int ath9k_modparam_nohwcrypt;
module_param_named(nohwcrypt, ath9k_modparam_nohwcrypt, int, 0444);
MODULE_PARM_DESC(nohwcrypt, "Disable hardware encryption");
-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

@@ -0,0 +1,92 @@
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -24,6 +24,7 @@
#include "regd_common.h"
static int __ath_regd_init(struct ath_regulatory *reg);
+static struct reg_dmn_pair_mapping *ath_get_regpair(int regdmn);
/*
* This is a set of common rules used by our world regulatory domains.
@@ -116,6 +117,9 @@ static const struct ieee80211_regdomain
static bool dynamic_country_user_possible(struct ath_regulatory *reg)
{
+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+ return true;
+
if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
return true;
@@ -188,6 +192,8 @@ static bool dynamic_country_user_possibl
static bool ath_reg_dyn_country_user_allow(struct ath_regulatory *reg)
{
+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+ return true;
if (!IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_REG_HINTS))
return false;
if (!dynamic_country_user_possible(reg))
@@ -345,6 +351,9 @@ ath_reg_apply_beaconing_flags(struct wip
struct ieee80211_channel *ch;
unsigned int i;
+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+ return;
+
for (band = 0; band < NUM_NL80211_BANDS; band++) {
if (!wiphy->bands[band])
continue;
@@ -378,6 +387,9 @@ ath_reg_apply_ir_flags(struct wiphy *wip
{
struct ieee80211_supported_band *sband;
+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+ return;
+
sband = wiphy->bands[NL80211_BAND_2GHZ];
if (!sband)
return;
@@ -407,6 +419,9 @@ static void ath_reg_apply_radar_flags(st
struct ieee80211_channel *ch;
unsigned int i;
+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+ return;
+
if (!wiphy->bands[NL80211_BAND_5GHZ])
return;
@@ -639,6 +654,10 @@ ath_regd_init_wiphy(struct ath_regulator
const struct ieee80211_regdomain *regd;
wiphy->reg_notifier = reg_notifier;
+
+ if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
+ return 0;
+
wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
REGULATORY_CUSTOM_REG;
--- a/drivers/net/wireless/ath/Kconfig
+++ b/drivers/net/wireless/ath/Kconfig
@@ -23,6 +23,9 @@ config WLAN_VENDOR_ATH
if WLAN_VENDOR_ATH
+config ATH_USER_REGD
+ bool "Do not enforce EEPROM regulatory restrictions"
+
config ATH_DEBUG
bool "Atheros wireless debugging"
---help---
--- a/local-symbols
+++ b/local-symbols
@@ -83,6 +83,7 @@ ADM8211=
ATH_COMMON=
WLAN_VENDOR_ATH=
ATH_DEBUG=
+ATH_USER_REGD=
ATH_TRACEPOINTS=
ATH_REG_DYNAMIC_USER_REG_HINTS=
ATH_REG_DYNAMIC_USER_CERT_TESTING=

View File

@@ -0,0 +1,84 @@
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -44,7 +44,8 @@ static struct reg_dmn_pair_mapping *ath_
NL80211_RRF_NO_OFDM)
/* We allow IBSS on these on a case by case basis by regulatory domain */
-#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5350+10, 80, 0, 30,\
+#define ATH9K_5GHZ_5150_5350 REG_RULE(5150-10, 5240+10, 80, 0, 30, 0),\
+ REG_RULE(5260-10, 5350+10, 80, 0, 30,\
NL80211_RRF_NO_IR)
#define ATH9K_5GHZ_5470_5850 REG_RULE(5470-10, 5850+10, 80, 0, 30,\
NL80211_RRF_NO_IR)
@@ -62,57 +63,56 @@ static struct reg_dmn_pair_mapping *ath_
#define ATH9K_5GHZ_NO_MIDBAND ATH9K_5GHZ_5150_5350, \
ATH9K_5GHZ_5725_5850
+#define REGD_RULES(...) \
+ .reg_rules = { __VA_ARGS__ }, \
+ .n_reg_rules = ARRAY_SIZE(((struct ieee80211_reg_rule[]) { __VA_ARGS__ }))
+
/* Can be used for:
* 0x60, 0x61, 0x62 */
static const struct ieee80211_regdomain ath_world_regdom_60_61_62 = {
- .n_reg_rules = 5,
.alpha2 = "99",
- .reg_rules = {
+ REGD_RULES(
ATH9K_2GHZ_ALL,
ATH9K_5GHZ_ALL,
- }
+ )
};
/* Can be used by 0x63 and 0x65 */
static const struct ieee80211_regdomain ath_world_regdom_63_65 = {
- .n_reg_rules = 4,
.alpha2 = "99",
- .reg_rules = {
+ REGD_RULES(
ATH9K_2GHZ_CH01_11,
ATH9K_2GHZ_CH12_13,
ATH9K_5GHZ_NO_MIDBAND,
- }
+ )
};
/* Can be used by 0x64 only */
static const struct ieee80211_regdomain ath_world_regdom_64 = {
- .n_reg_rules = 3,
.alpha2 = "99",
- .reg_rules = {
+ REGD_RULES(
ATH9K_2GHZ_CH01_11,
ATH9K_5GHZ_NO_MIDBAND,
- }
+ )
};
/* Can be used by 0x66 and 0x69 */
static const struct ieee80211_regdomain ath_world_regdom_66_69 = {
- .n_reg_rules = 3,
.alpha2 = "99",
- .reg_rules = {
+ REGD_RULES(
ATH9K_2GHZ_CH01_11,
ATH9K_5GHZ_ALL,
- }
+ )
};
/* Can be used by 0x67, 0x68, 0x6A and 0x6C */
static const struct ieee80211_regdomain ath_world_regdom_67_68_6A_6C = {
- .n_reg_rules = 4,
.alpha2 = "99",
- .reg_rules = {
+ REGD_RULES(
ATH9K_2GHZ_CH01_11,
ATH9K_2GHZ_CH12_13,
ATH9K_5GHZ_ALL,
- }
+ )
};
static bool dynamic_country_user_possible(struct ath_regulatory *reg)

View File

@@ -0,0 +1,19 @@
--- a/net/wireless/reg.c
+++ b/net/wireless/reg.c
@@ -3037,6 +3037,8 @@ void regulatory_hint_country_ie(struct w
enum environment_cap env = ENVIRON_ANY;
struct regulatory_request *request = NULL, *lr;
+ return;
+
/* IE len must be evenly divisible by 2 */
if (country_ie_len & 0x01)
return;
@@ -3262,6 +3264,7 @@ static bool is_wiphy_all_set_reg_flag(en
void regulatory_hint_disconnect(void)
{
+ return;
/* Restore of regulatory settings is not required when wiphy(s)
* ignore IE from connected access point but clearance of beacon hints
* is required when wiphy(s) supports beacon hints.

View File

@@ -0,0 +1,26 @@
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -32,6 +32,7 @@ enum EnumRd {
FCC2_WORLD = 0x21,
FCC2_ETSIC = 0x22,
FCC6_WORLD = 0x23,
+ FCC3_FCCA_2 = 0x2A,
FRANCE_RES = 0x31,
FCC3_FCCA = 0x3A,
FCC3_WORLD = 0x3B,
@@ -172,6 +173,7 @@ static struct reg_dmn_pair_mapping regDo
{FCC2_WORLD, CTL_FCC, CTL_ETSI},
{FCC2_ETSIC, CTL_FCC, CTL_ETSI},
{FCC3_FCCA, CTL_FCC, CTL_FCC},
+ {FCC3_FCCA_2, CTL_FCC, CTL_FCC},
{FCC3_WORLD, CTL_FCC, CTL_ETSI},
{FCC3_ETSIC, CTL_FCC, CTL_ETSI},
{FCC4_FCCA, CTL_FCC, CTL_FCC},
@@ -483,6 +485,7 @@ static struct country_code_to_enum_rd al
{CTRY_UAE, NULL1_WORLD, "AE"},
{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
{CTRY_UNITED_STATES, FCC3_FCCA, "US"},
+ {CTRY_UNITED_STATES, FCC3_FCCA_2, "US"},
/* This "PS" is for US public safety actually... to support this we
* would need to assign new special alpha2 to CRDA db as with the world
* regdomain and use another alpha2 */

View File

@@ -0,0 +1,51 @@
--- a/drivers/net/wireless/ath/regd.c
+++ b/drivers/net/wireless/ath/regd.c
@@ -115,6 +115,16 @@ static const struct ieee80211_regdomain
)
};
+static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
+{
+ return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
+}
+
+static bool is_default_regd(struct ath_regulatory *reg)
+{
+ return ath_regd_get_eepromRD(reg) == CTRY_DEFAULT;
+}
+
static bool dynamic_country_user_possible(struct ath_regulatory *reg)
{
if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
@@ -123,6 +133,9 @@ static bool dynamic_country_user_possibl
if (IS_ENABLED(CPTCFG_ATH_REG_DYNAMIC_USER_CERT_TESTING))
return true;
+ if (is_default_regd(reg))
+ return true;
+
switch (reg->country_code) {
case CTRY_UNITED_STATES:
case CTRY_JAPAN1:
@@ -208,11 +221,6 @@ static inline bool is_wwr_sku(u16 regd)
(regd == WORLD));
}
-static u16 ath_regd_get_eepromRD(struct ath_regulatory *reg)
-{
- return reg->current_rd & ~WORLDWIDE_ROAMING_FLAG;
-}
-
bool ath_is_world_regd(struct ath_regulatory *reg)
{
return is_wwr_sku(ath_regd_get_eepromRD(reg));
@@ -658,6 +666,9 @@ ath_regd_init_wiphy(struct ath_regulator
if (IS_ENABLED(CPTCFG_ATH_USER_REGD))
return 0;
+ if (is_default_regd(reg))
+ return 0;
+
wiphy->regulatory_flags |= REGULATORY_STRICT_REG |
REGULATORY_CUSTOM_REG;

View File

@@ -0,0 +1,35 @@
From: Oever Gonzalez <notengobattery@gmail.com>
Date: Mon, 7 Jan 2019 01:07:12 +0200
Subject: [PATCH] ath: regd: add extra coutry codes
This patch adds several country codes to the regd.h and regd_common.h
files in order to support devices whose country codes are not present in
the original list. Without this patch, all devices whose manufacturer
programmed any of these code in their EEPROM will not work.
Signed-off-by: Oever Gonzalez <notengobattery@gmail.com>
---
--- a/drivers/net/wireless/ath/regd.h
+++ b/drivers/net/wireless/ath/regd.h
@@ -185,7 +185,9 @@ enum CountryCode {
CTRY_UKRAINE = 804,
CTRY_UNITED_KINGDOM = 826,
CTRY_UNITED_STATES = 840,
+ CTRY_UNITED_STATES2 = 841,
CTRY_UNITED_STATES_FCC49 = 842,
+ CTRY_UNITED_STATES3 = 843,
CTRY_URUGUAY = 858,
CTRY_UZBEKISTAN = 860,
CTRY_VENEZUELA = 862,
--- a/drivers/net/wireless/ath/regd_common.h
+++ b/drivers/net/wireless/ath/regd_common.h
@@ -486,6 +486,8 @@ static struct country_code_to_enum_rd al
{CTRY_UNITED_KINGDOM, ETSI1_WORLD, "GB"},
{CTRY_UNITED_STATES, FCC3_FCCA, "US"},
{CTRY_UNITED_STATES, FCC3_FCCA_2, "US"},
+ {CTRY_UNITED_STATES2, FCC3_FCCA, "US"},
+ {CTRY_UNITED_STATES3, FCC3_FCCA, "US"},
/* This "PS" is for US public safety actually... to support this we
* would need to assign new special alpha2 to CRDA db as with the world
* regdomain and use another alpha2 */

View File

@@ -0,0 +1,10 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -833,6 +833,7 @@ static const struct ieee80211_iface_limi
BIT(NL80211_IFTYPE_AP) },
{ .max = 1, .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
BIT(NL80211_IFTYPE_P2P_GO) },
+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
};
#ifdef CPTCFG_WIRELESS_WDS

View File

@@ -0,0 +1,46 @@
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -86,13 +86,8 @@ ath5k_add_interface(struct ieee80211_hw
goto end;
}
- /* Don't allow other interfaces if one ad-hoc is configured.
- * TODO: Fix the problems with ad-hoc and multiple other interfaces.
- * We would need to operate the HW in ad-hoc mode to allow TSF updates
- * for the IBSS, but this breaks with additional AP or STA interfaces
- * at the moment. */
- if (ah->num_adhoc_vifs ||
- (ah->nvifs && vif->type == NL80211_IFTYPE_ADHOC)) {
+ /* Don't allow more than one ad-hoc interface */
+ if (ah->num_adhoc_vifs && vif->type == NL80211_IFTYPE_ADHOC) {
ATH5K_ERR(ah, "Only one single ad-hoc interface is allowed.\n");
ret = -ELNRNG;
goto end;
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1965,7 +1965,7 @@ ath5k_beacon_send(struct ath5k_hw *ah)
}
if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs +
- ah->num_mesh_vifs > 1) ||
+ ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) ||
ah->opmode == NL80211_IFTYPE_MESH_POINT) {
u64 tsf = ath5k_hw_get_tsf64(ah);
u32 tsftu = TSF_TO_TU(tsf);
@@ -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
- + ah->num_mesh_vifs > 1) {
+ + ah->num_adhoc_vifs + ah->num_mesh_vifs > 1) {
intval /= ATH_BCBUF; /* staggered multi-bss beacons */
if (intval < 15)
ATH5K_WARN(ah, "intval %u is too low, min 15\n",
@@ -2518,6 +2518,7 @@ static const struct ieee80211_iface_limi
BIT(NL80211_IFTYPE_MESH_POINT) |
#endif
BIT(NL80211_IFTYPE_AP) },
+ { .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
};
static const struct ieee80211_iface_combination if_comb = {

View File

@@ -0,0 +1,18 @@
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1154,6 +1154,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
tsf_lo = 0;
mode = 0;
+#if 0
/*
* Sanity check for fast flag
* Fast channel change only available
@@ -1161,6 +1162,7 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum
*/
if (fast && (ah->ah_radio != AR5K_RF2413) &&
(ah->ah_radio != AR5K_RF5413))
+#endif
fast = false;
/* Disable sleep clock operation

View File

@@ -0,0 +1,33 @@
--- /dev/null
+++ b/include/linux/ath5k_platform.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2008 Atheros Communications Inc.
+ * Copyright (c) 2009 Gabor Juhos <juhosg@openwrt.org>
+ * Copyright (c) 2009 Imre Kaloz <kaloz@openwrt.org>
+ * Copyright (c) 2010 Daniel Golle <daniel.golle@gmail.com>
+ *
+ * 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.
+ */
+
+#ifndef _LINUX_ATH5K_PLATFORM_H
+#define _LINUX_ATH5K_PLATFORM_H
+
+#define ATH5K_PLAT_EEP_MAX_WORDS 2048
+
+struct ath5k_platform_data {
+ u16 *eeprom_data;
+ u8 *macaddr;
+};
+
+#endif /* _LINUX_ATH5K_PLATFORM_H */

View File

@@ -0,0 +1,56 @@
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -21,6 +21,7 @@
#include <linux/pci-aspm.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
+#include <linux/ath5k_platform.h>
#include "../ath.h"
#include "ath5k.h"
#include "debug.h"
@@ -72,7 +73,7 @@ static void ath5k_pci_read_cachesize(str
}
/*
- * Read from eeprom
+ * Read from eeprom or platform_data
*/
static bool
ath5k_pci_eeprom_read(struct ath_common *common, u32 offset, u16 *data)
@@ -80,6 +81,19 @@ ath5k_pci_eeprom_read(struct ath_common
struct ath5k_hw *ah = (struct ath5k_hw *) common->ah;
u32 status, timeout;
+ struct ath5k_platform_data *pdata = NULL;
+
+ if (ah->pdev)
+ pdata = ah->pdev->dev.platform_data;
+
+ if (pdata && pdata->eeprom_data && pdata->eeprom_data[61] == AR5K_EEPROM_MAGIC_VALUE) {
+ if (offset >= ATH5K_PLAT_EEP_MAX_WORDS)
+ return false;
+
+ *data = pdata->eeprom_data[offset];
+ return true;
+ }
+
/*
* Initialize EEPROM access
*/
@@ -123,6 +137,16 @@ static int ath5k_pci_eeprom_read_mac(str
u16 data;
int octet;
+ struct ath5k_platform_data *pdata = NULL;
+
+ if (ah->pdev)
+ pdata = ah->pdev->dev.platform_data;
+
+ if (pdata && pdata->macaddr) {
+ memcpy(mac, pdata->macaddr, ETH_ALEN);
+ return 0;
+ }
+
AR5K_EEPROM_READ(0x20, data);
for (offset = 0x1f, octet = 0, total = 0; offset >= 0x1d; offset--) {

View File

@@ -0,0 +1,11 @@
--- a/drivers/net/wireless/ath/ath5k/pci.c
+++ b/drivers/net/wireless/ath/ath5k/pci.c
@@ -48,6 +48,8 @@ static const struct pci_device_id ath5k_
{ PCI_VDEVICE(ATHEROS, 0x001b) }, /* 5413 Eagle */
{ PCI_VDEVICE(ATHEROS, 0x001c) }, /* PCI-E cards */
{ PCI_VDEVICE(ATHEROS, 0x001d) }, /* 2417 Nala */
+ { PCI_VDEVICE(ATHEROS, 0xff16) }, /* 2413,2414 sx76x on lantiq_danube */
+ { PCI_VDEVICE(ATHEROS, 0xff1a) }, /* 2417 arv45xx on lantiq_danube */
{ PCI_VDEVICE(ATHEROS, 0xff1b) }, /* AR5BXB63 */
{ 0 }
};

View File

@@ -0,0 +1,142 @@
This adds a bwmode debugfs file which can be used to set alternate
channel operating bandwidths. Only tested with AR5413 and only at
5 and 20 mhz channels.
Signed-off-by: Pat Erley <pat-lkml at erley.org>
---
Other devices will need to be added to the switch in write_file_bwmode
drivers/net/wireless/ath/ath5k/debug.c | 86 ++++++++++++++++++++++++++++++++
1 files changed, 86 insertions(+), 0 deletions(-)
--- a/drivers/net/wireless/ath/ath5k/debug.c
+++ b/drivers/net/wireless/ath/ath5k/debug.c
@@ -822,6 +822,97 @@ static const struct file_operations fops
.llseek = default_llseek,
};
+/* debugfs: bwmode */
+
+static ssize_t read_file_bwmode(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath5k_hw *ah = file->private_data;
+ char buf[15];
+ unsigned int len = 0;
+
+ int cur_ah_bwmode = ah->ah_bwmode_debug;
+
+#define print_selected(MODE, LABEL) \
+ if (cur_ah_bwmode == MODE) \
+ len += snprintf(buf+len, sizeof(buf)-len, "[%s]", LABEL); \
+ else \
+ len += snprintf(buf+len, sizeof(buf)-len, "%s", LABEL); \
+ len += snprintf(buf+len, sizeof(buf)-len, " ");
+
+ print_selected(AR5K_BWMODE_5MHZ, "5");
+ print_selected(AR5K_BWMODE_10MHZ, "10");
+ print_selected(AR5K_BWMODE_DEFAULT, "20");
+ print_selected(AR5K_BWMODE_40MHZ, "40");
+#undef print_selected
+
+ len += snprintf(buf+len, sizeof(buf)-len, "\n");
+
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_bwmode(struct file *file,
+ const char __user *userbuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath5k_hw *ah = file->private_data;
+ char buf[3];
+ int bw = 20;
+ int tobwmode = AR5K_BWMODE_DEFAULT;
+
+ if (copy_from_user(buf, userbuf, min(count, sizeof(buf))))
+ return -EFAULT;
+
+ /* TODO: Add check for active interface */
+
+ if(strncmp(buf, "5", 1) == 0 ) {
+ tobwmode = AR5K_BWMODE_5MHZ;
+ bw = 5;
+ } else if ( strncmp(buf, "10", 2) == 0 ) {
+ tobwmode = AR5K_BWMODE_10MHZ;
+ bw = 10;
+ } else if ( strncmp(buf, "20", 2) == 0 ) {
+ tobwmode = AR5K_BWMODE_DEFAULT;
+ bw = 20;
+ } else if ( strncmp(buf, "40", 2) == 0 ) {
+ tobwmode = AR5K_BWMODE_40MHZ;
+ bw = 40;
+ } else
+ return -EINVAL;
+
+ ATH5K_INFO(ah, "Changing to %imhz channel width[%i]\n",
+ bw, tobwmode);
+
+ switch (ah->ah_radio) {
+ /* TODO: only define radios that actually support 5/10mhz channels */
+ case AR5K_RF5413:
+ case AR5K_RF5110:
+ case AR5K_RF5111:
+ case AR5K_RF5112:
+ case AR5K_RF2413:
+ case AR5K_RF2316:
+ case AR5K_RF2317:
+ case AR5K_RF2425:
+ if(ah->ah_bwmode_debug != tobwmode) {
+ mutex_lock(&ah->lock);
+ ah->ah_bwmode = tobwmode;
+ ah->ah_bwmode_debug = tobwmode;
+ mutex_unlock(&ah->lock);
+ }
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+ return count;
+}
+
+static const struct file_operations fops_bwmode = {
+ .read = read_file_bwmode,
+ .write = write_file_bwmode,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
/* debugfs: queues etc */
@@ -1016,6 +1107,8 @@ ath5k_debug_init_device(struct ath5k_hw
debugfs_create_file("queue", 0600, phydir, ah, &fops_queue);
debugfs_create_bool("32khz_clock", 0600, phydir,
&ah->ah_use_32khz_clock);
+ debugfs_create_file("bwmode", S_IWUSR | S_IRUSR, phydir, ah,
+ &fops_bwmode);
}
/* functions used in other places */
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1372,6 +1372,7 @@ struct ath5k_hw {
u8 ah_coverage_class;
bool ah_ack_bitrate_high;
u8 ah_bwmode;
+ u8 ah_bwmode_debug;
bool ah_short_slot;
/* Antenna Control */
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -466,6 +466,9 @@ ath5k_chan_set(struct ath5k_hw *ah, stru
return -EINVAL;
}
+ if (ah->ah_bwmode_debug != AR5K_BWMODE_DEFAULT)
+ ah->ah_bwmode = ah->ah_bwmode_debug;
+
/*
* To switch channels clear any pending DMA operations;
* wait long enough for the RX fifo to drain, reset the

View File

@@ -0,0 +1,65 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1374,6 +1374,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,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ struct ath_hw *ah = sc->sc_ah;
+ struct ath_common *common = ath9k_hw_common(ah);
+ int bytes = 0;
+ int pos = *ppos;
+ int size = 4096;
+ u16 val;
+ int i;
+
+ if (AR_SREV_9300_20_OR_LATER(ah))
+ size = 16384;
+
+ if (*ppos < 0)
+ return -EINVAL;
+
+ if (count > size - *ppos)
+ count = size - *ppos;
+
+ for (i = *ppos / 2; count > 0; count -= bytes, *ppos += bytes, i++) {
+ void *from = &val;
+
+ if (!common->bus_ops->eeprom_read(common, i, &val))
+ val = 0xffff;
+
+ if (*ppos % 2) {
+ from++;
+ bytes = 1;
+ } else if (count == 1) {
+ bytes = 1;
+ } else {
+ bytes = 2;
+ }
+ copy_to_user(user_buf, from, bytes);
+ user_buf += bytes;
+ }
+ return *ppos - pos;
+}
+
+static const struct file_operations fops_eeprom = {
+ .read = read_file_eeprom,
+ .open = simple_open,
+ .owner = THIS_MODULE
+};
+
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -1393,6 +1440,8 @@ int ath9k_init_debug(struct ath_hw *ah)
ath9k_tx99_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_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

@@ -0,0 +1,34 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -1144,25 +1144,25 @@ static int __init ath9k_init(void)
{
int error;
- error = ath_pci_init();
+ error = ath_ahb_init();
if (error < 0) {
- pr_err("No PCI devices found, driver not installed\n");
error = -ENODEV;
goto err_out;
}
- error = ath_ahb_init();
+ error = ath_pci_init();
if (error < 0) {
+ pr_err("No PCI devices found, driver not installed\n");
error = -ENODEV;
- goto err_pci_exit;
+ goto err_ahb_exit;
}
dmi_check_system(ath9k_quirks);
return 0;
- err_pci_exit:
- ath_pci_exit();
+ err_ahb_exit:
+ ath_ahb_exit();
err_out:
return error;
}

View File

@@ -0,0 +1,18 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -403,13 +403,8 @@ static void ath9k_hw_init_config(struct
ah->config.rx_intr_mitigation = true;
- if (AR_SREV_9300_20_OR_LATER(ah)) {
- ah->config.rimt_last = 500;
- ah->config.rimt_first = 2000;
- } else {
- ah->config.rimt_last = 250;
- ah->config.rimt_first = 700;
- }
+ ah->config.rimt_last = 250;
+ ah->config.rimt_first = 500;
if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
ah->config.pll_pwrsave = 7;

View File

@@ -0,0 +1,11 @@
--- 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 *
(_l) &= ((_sz) - 1); \
} while (0)
-#define ATH_RXBUF 512
+#define ATH_RXBUF 256
#define ATH_TXBUF 512
#define ATH_TXBUF_RESERVE 5
#define ATH_TXMAXTRY 13

View File

@@ -0,0 +1,125 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1421,6 +1421,52 @@ static const struct file_operations fops
.owner = THIS_MODULE
};
+
+static ssize_t read_file_chan_bw(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ char buf[32];
+ unsigned int len;
+
+ len = sprintf(buf, "0x%08x\n", common->chan_bw);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_chan_bw(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ struct ath_common *common = ath9k_hw_common(sc->sc_ah);
+ unsigned long chan_bw;
+ char buf[32];
+ ssize_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ if (kstrtoul(buf, 0, &chan_bw))
+ return -EINVAL;
+
+ common->chan_bw = chan_bw;
+ if (!test_bit(ATH_OP_INVALID, &common->op_flags))
+ ath9k_ops.config(sc->hw, IEEE80211_CONF_CHANGE_CHANNEL);
+
+ return count;
+}
+
+static const struct file_operations fops_chanbw = {
+ .read = read_file_chan_bw,
+ .write = write_file_chan_bw,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -1442,6 +1488,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_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
@@ -149,6 +149,7 @@ struct ath_common {
int debug_mask;
enum ath_device_state state;
unsigned long op_flags;
+ u32 chan_bw;
struct ath_ani ani;
--- a/drivers/net/wireless/ath/ath9k/common.c
+++ b/drivers/net/wireless/ath/ath9k/common.c
@@ -297,11 +297,13 @@ EXPORT_SYMBOL(ath9k_cmn_get_hw_crypto_ke
/*
* Update internal channel flags.
*/
-static void ath9k_cmn_update_ichannel(struct ath9k_channel *ichan,
+static void ath9k_cmn_update_ichannel(struct ath_common *common,
+ struct ath9k_channel *ichan,
struct cfg80211_chan_def *chandef)
{
struct ieee80211_channel *chan = chandef->chan;
u16 flags = 0;
+ int width;
ichan->channel = chan->center_freq;
ichan->chan = chan;
@@ -309,7 +311,19 @@ static void ath9k_cmn_update_ichannel(st
if (chan->band == NL80211_BAND_5GHZ)
flags |= CHANNEL_5GHZ;
- switch (chandef->width) {
+ switch (common->chan_bw) {
+ case 5:
+ width = NL80211_CHAN_WIDTH_5;
+ break;
+ case 10:
+ width = NL80211_CHAN_WIDTH_10;
+ break;
+ default:
+ width = chandef->width;
+ break;
+ }
+
+ switch (width) {
case NL80211_CHAN_WIDTH_5:
flags |= CHANNEL_QUARTER;
break;
@@ -342,10 +356,11 @@ struct ath9k_channel *ath9k_cmn_get_chan
struct cfg80211_chan_def *chandef)
{
struct ieee80211_channel *curchan = chandef->chan;
+ struct ath_common *common = ath9k_hw_common(ah);
struct ath9k_channel *channel;
channel = &ah->channels[curchan->hw_value];
- ath9k_cmn_update_ichannel(channel, chandef);
+ ath9k_cmn_update_ichannel(common, channel, chandef);
return channel;
}

View File

@@ -0,0 +1,30 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -663,6 +663,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) {
+ case AR9300_DEVID_INVALID:
case AR5416_DEVID_PCI:
case AR5416_DEVID_PCIE:
case AR5416_AR9100_DEVID:
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -36,6 +36,7 @@
#define ATHEROS_VENDOR_ID 0x168c
+#define AR9300_DEVID_INVALID 0xabcd
#define AR5416_DEVID_PCI 0x0023
#define AR5416_DEVID_PCIE 0x0024
#define AR9160_DEVID_PCI 0x0027
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -774,6 +774,7 @@ static const struct pci_device_id ath_pc
.driver_data = ATH9K_PCI_BT_ANT_DIV },
#endif
+ { PCI_VDEVICE(ATHEROS, 0xabcd) }, /* PCI-E internal chip default ID */
{ 0 }
};

View File

@@ -0,0 +1,267 @@
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -850,6 +850,9 @@ static inline int ath9k_dump_btcoex(stru
#ifdef CPTCFG_MAC80211_LEDS
void ath_init_leds(struct ath_softc *sc);
void ath_deinit_leds(struct ath_softc *sc);
+int ath_create_gpio_led(struct ath_softc *sc, int gpio, const char *name,
+ const char *trigger, bool active_low);
+
#else
static inline void ath_init_leds(struct ath_softc *sc)
{
@@ -991,6 +994,13 @@ void ath_ant_comb_scan(struct ath_softc
#define AIRTIME_USE_NEW_QUEUES BIT(2)
#define AIRTIME_ACTIVE(flags) (!!(flags & (AIRTIME_USE_TX|AIRTIME_USE_RX)))
+struct ath_led {
+ struct list_head list;
+ struct ath_softc *sc;
+ const struct gpio_led *gpio;
+ struct led_classdev cdev;
+};
+
struct ath_softc {
struct ieee80211_hw *hw;
struct device *dev;
@@ -1046,9 +1056,8 @@ struct ath_softc {
spinlock_t chan_lock;
#ifdef CPTCFG_MAC80211_LEDS
- bool led_registered;
- char led_name[32];
- struct led_classdev led_cdev;
+ const char *led_default_trigger;
+ struct list_head leds;
#endif
#ifdef CPTCFG_ATH9K_DEBUGFS
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -39,61 +39,111 @@ static void ath_fill_led_pin(struct ath_
else
ah->led_pin = ATH_LED_PIN_DEF;
}
+}
+
+static void ath_led_brightness(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct ath_led *led = container_of(led_cdev, struct ath_led, cdev);
+ struct ath_softc *sc = led->sc;
+
+ ath9k_ps_wakeup(sc);
+ ath9k_hw_set_gpio(sc->sc_ah, led->gpio->gpio,
+ (brightness != LED_OFF) ^ led->gpio->active_low);
+ ath9k_ps_restore(sc);
+}
+
+static int ath_add_led(struct ath_softc *sc, struct ath_led *led)
+{
+ const struct gpio_led *gpio = led->gpio;
+ int ret;
+
+ led->cdev.name = gpio->name;
+ led->cdev.default_trigger = gpio->default_trigger;
+ led->cdev.brightness_set = ath_led_brightness;
+
+ ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &led->cdev);
+ if (ret < 0)
+ return ret;
+
+ led->sc = sc;
+ list_add(&led->list, &sc->leds);
/* Configure gpio for output */
- ath9k_hw_gpio_request_out(ah, ah->led_pin, "ath9k-led",
+ ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name,
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- /* LED off, active low */
- ath9k_hw_set_gpio(ah, ah->led_pin, ah->config.led_active_high ? 0 : 1);
+ /* LED off */
+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
+
+ return 0;
}
-static void ath_led_brightness(struct led_classdev *led_cdev,
- enum led_brightness brightness)
+int ath_create_gpio_led(struct ath_softc *sc, int gpio_num, const char *name,
+ const char *trigger, bool active_low)
{
- struct ath_softc *sc = container_of(led_cdev, struct ath_softc, led_cdev);
- u32 val = (brightness == LED_OFF);
+ struct ath_led *led;
+ struct gpio_led *gpio;
+ char *_name;
+ int ret;
- if (sc->sc_ah->config.led_active_high)
- val = !val;
+ led = kzalloc(sizeof(*led) + sizeof(*gpio) + strlen(name) + 1,
+ GFP_KERNEL);
+ if (!led)
+ return -ENOMEM;
+
+ led->gpio = gpio = (struct gpio_led *) (led + 1);
+ _name = (char *) (led->gpio + 1);
+
+ strcpy(_name, name);
+ gpio->name = _name;
+ gpio->gpio = gpio_num;
+ gpio->active_low = active_low;
+ gpio->default_trigger = trigger;
+
+ ret = ath_add_led(sc, led);
+ if (unlikely(ret < 0))
+ kfree(led);
- ath9k_hw_set_gpio(sc->sc_ah, sc->sc_ah->led_pin, val);
+ return ret;
}
void ath_deinit_leds(struct ath_softc *sc)
{
- if (!sc->led_registered)
- return;
+ struct ath_led *led;
- ath_led_brightness(&sc->led_cdev, LED_OFF);
- led_classdev_unregister(&sc->led_cdev);
-
- ath9k_hw_gpio_free(sc->sc_ah, sc->sc_ah->led_pin);
+ while (!list_empty(&sc->leds)) {
+ led = list_first_entry(&sc->leds, struct ath_led, list);
+ list_del(&led->list);
+ ath_led_brightness(&led->cdev, LED_OFF);
+ led_classdev_unregister(&led->cdev);
+ ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio);
+ kfree(led);
+ }
}
void ath_init_leds(struct ath_softc *sc)
{
- int ret;
+ char led_name[32];
+ const char *trigger;
+
+ INIT_LIST_HEAD(&sc->leds);
if (AR_SREV_9100(sc->sc_ah))
return;
ath_fill_led_pin(sc);
- if (!ath9k_led_blink)
- sc->led_cdev.default_trigger =
- ieee80211_get_radio_led_name(sc->hw);
-
- snprintf(sc->led_name, sizeof(sc->led_name),
- "ath9k-%s", wiphy_name(sc->hw->wiphy));
- sc->led_cdev.name = sc->led_name;
- sc->led_cdev.brightness_set = ath_led_brightness;
+ snprintf(led_name, sizeof(led_name), "ath9k-%s",
+ wiphy_name(sc->hw->wiphy));
- ret = led_classdev_register(wiphy_dev(sc->hw->wiphy), &sc->led_cdev);
- if (ret < 0)
- return;
+ if (ath9k_led_blink)
+ trigger = sc->led_default_trigger;
+ else
+ trigger = ieee80211_get_radio_led_name(sc->hw);
- sc->led_registered = true;
+ ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger,
+ !sc->sc_ah->config.led_active_high);
}
#endif
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -1056,7 +1056,7 @@ int ath9k_init_device(u16 devid, struct
#ifdef CPTCFG_MAC80211_LEDS
/* must be initialized before ieee80211_register_hw */
- sc->led_cdev.default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
+ sc->led_default_trigger = ieee80211_create_tpt_led_trigger(sc->hw,
IEEE80211_TPT_LEDTRIG_FL_RADIO, ath9k_tpt_blink,
ARRAY_SIZE(ath9k_tpt_blink));
#endif
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1466,6 +1466,61 @@ static const struct file_operations fops
.llseek = default_llseek,
};
+#ifdef CONFIG_MAC80211_LEDS
+
+static ssize_t write_file_gpio_led(struct file *file, const char __user *ubuf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ char buf[32], *str, *name, *c;
+ ssize_t len;
+ unsigned int gpio;
+ bool active_low = false;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, ubuf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ name = strchr(buf, ',');
+ if (!name)
+ return -EINVAL;
+
+ *(name++) = 0;
+ if (!*name)
+ return -EINVAL;
+
+ c = strchr(name, '\n');
+ if (c)
+ *c = 0;
+
+ str = buf;
+ if (*str == '!') {
+ str++;
+ active_low = true;
+ }
+
+ if (kstrtouint(str, 0, &gpio) < 0)
+ return -EINVAL;
+
+ if (gpio >= sc->sc_ah->caps.num_gpio_pins)
+ return -EINVAL;
+
+ if (ath_create_gpio_led(sc, gpio, name, NULL, active_low) < 0)
+ return -EINVAL;
+
+ return count;
+}
+
+static const struct file_operations fops_gpio_led = {
+ .write = write_file_gpio_led,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+#endif
+
int ath9k_init_debug(struct ath_hw *ah)
{
@@ -1490,6 +1545,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);
+#ifdef CONFIG_MAC80211_LEDS
+ debugfs_create_file("gpio_led", S_IWUSR,
+ sc->debug.debugfs_phy, sc, &fops_gpio_led);
+#endif
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

@@ -0,0 +1,76 @@
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -46,6 +46,9 @@ struct ath9k_platform_data {
int (*external_reset)(void);
bool use_eeprom;
+
+ int num_leds;
+ const struct gpio_led *leds;
};
#endif /* _LINUX_ATH9K_PLATFORM_H */
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -15,6 +15,7 @@
*/
#include "ath9k.h"
+#include <linux/ath9k_platform.h>
/********************************/
/* LED functions */
@@ -108,6 +109,24 @@ int ath_create_gpio_led(struct ath_softc
return ret;
}
+static int ath_create_platform_led(struct ath_softc *sc,
+ const struct gpio_led *gpio)
+{
+ struct ath_led *led;
+ int ret;
+
+ led = kzalloc(sizeof(*led), GFP_KERNEL);
+ if (!led)
+ return -ENOMEM;
+
+ led->gpio = gpio;
+ ret = ath_add_led(sc, led);
+ if (ret < 0)
+ kfree(led);
+
+ return ret;
+}
+
void ath_deinit_leds(struct ath_softc *sc)
{
struct ath_led *led;
@@ -124,8 +143,10 @@ void ath_deinit_leds(struct ath_softc *s
void ath_init_leds(struct ath_softc *sc)
{
+ struct ath9k_platform_data *pdata = sc->dev->platform_data;
char led_name[32];
const char *trigger;
+ int i;
INIT_LIST_HEAD(&sc->leds);
@@ -134,6 +155,17 @@ void ath_init_leds(struct ath_softc *sc)
ath_fill_led_pin(sc);
+ if (pdata && pdata->leds && pdata->num_leds)
+ for (i = 0; i < pdata->num_leds; i++) {
+ if (pdata->leds[i].gpio == sc->sc_ah->led_pin)
+ sc->sc_ah->led_pin = -1;
+
+ ath_create_platform_led(sc, &pdata->leds[i]);
+ }
+
+ if (sc->sc_ah->led_pin < 0)
+ return;
+
snprintf(led_name, sizeof(led_name), "ath9k-%s",
wiphy_name(sc->hw->wiphy));

View File

@@ -0,0 +1,11 @@
--- a/drivers/net/wireless/ath/ath9k/ani.h
+++ b/drivers/net/wireless/ath/ath9k/ani.h
@@ -42,7 +42,7 @@
#define ATH9K_ANI_PERIOD 300
/* in ms */
-#define ATH9K_ANI_POLLINTERVAL 1000
+#define ATH9K_ANI_POLLINTERVAL 300
#define ATH9K_SIG_FIRSTEP_SETTING_MIN 0
#define ATH9K_SIG_FIRSTEP_SETTING_MAX 20

View File

@@ -0,0 +1,139 @@
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -1522,6 +1522,50 @@ static const struct file_operations fops
#endif
+static ssize_t read_file_diag(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ struct ath_hw *ah = sc->sc_ah;
+ char buf[32];
+ unsigned int len;
+
+ len = sprintf(buf, "0x%08lx\n", ah->diag);
+ return simple_read_from_buffer(user_buf, count, ppos, buf, len);
+}
+
+static ssize_t write_file_diag(struct file *file, const char __user *user_buf,
+ size_t count, loff_t *ppos)
+{
+ struct ath_softc *sc = file->private_data;
+ struct ath_hw *ah = sc->sc_ah;
+ unsigned long diag;
+ char buf[32];
+ ssize_t len;
+
+ len = min(count, sizeof(buf) - 1);
+ if (copy_from_user(buf, user_buf, len))
+ return -EFAULT;
+
+ buf[len] = '\0';
+ if (kstrtoul(buf, 0, &diag))
+ return -EINVAL;
+
+ ah->diag = diag;
+ ath9k_hw_update_diag(ah);
+
+ return count;
+}
+
+static const struct file_operations fops_diag = {
+ .read = read_file_diag,
+ .write = write_file_diag,
+ .open = simple_open,
+ .owner = THIS_MODULE,
+ .llseek = default_llseek,
+};
+
+
int ath9k_init_debug(struct ath_hw *ah)
{
struct ath_common *common = ath9k_hw_common(ah);
@@ -1549,6 +1593,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_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
@@ -520,6 +520,12 @@ enum {
ATH9K_RESET_COLD,
};
+enum {
+ ATH_DIAG_DISABLE_RX,
+ ATH_DIAG_DISABLE_TX,
+ ATH_DIAG_TRIGGER_ERROR,
+};
+
struct ath9k_hw_version {
u32 magic;
u16 devid;
@@ -808,6 +814,8 @@ struct ath_hw {
u32 ah_flags;
s16 nf_override;
+ unsigned long diag;
+
bool reset_power_on;
bool htc_reset_init;
@@ -1073,6 +1081,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);
+void ath9k_hw_update_diag(struct ath_hw *ah);
/* Generic hw timer primitives */
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
@@ -1883,6 +1883,20 @@ u32 ath9k_hw_get_tsf_offset(struct times
}
EXPORT_SYMBOL(ath9k_hw_get_tsf_offset);
+void ath9k_hw_update_diag(struct ath_hw *ah)
+{
+ if (test_bit(ATH_DIAG_DISABLE_RX, &ah->diag))
+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
+ else
+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_RX_DIS);
+
+ if (test_bit(ATH_DIAG_DISABLE_TX, &ah->diag))
+ REG_SET_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
+ else
+ REG_CLR_BIT(ah, AR_DIAG_SW, AR_DIAG_LOOP_BACK);
+}
+EXPORT_SYMBOL(ath9k_hw_update_diag);
+
int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
struct ath9k_hw_cal_data *caldata, bool fastcc)
{
@@ -2091,6 +2105,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st
ar9003_hw_disable_phy_restart(ah);
ath9k_hw_apply_gpio_override(ah);
+ ath9k_hw_update_diag(ah);
if (AR_SREV_9565(ah) && common->bt_ant_diversity)
REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -528,6 +528,11 @@ irqreturn_t ath_isr(int irq, void *dev)
if (test_bit(ATH_OP_HW_RESET, &common->op_flags))
return IRQ_HANDLED;
+ if (test_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag)) {
+ status |= ATH9K_INT_FATAL;
+ clear_bit(ATH_DIAG_TRIGGER_ERROR, &ah->diag);
+ }
+
/*
* If there are no status bits set, then this interrupt was not
* for me (should have been caught above).

View File

@@ -0,0 +1,186 @@
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -721,6 +721,7 @@ struct ath_spec_scan {
* @config_pci_powersave:
* @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC
*
+ * @get_adc_entropy: get entropy from the raw ADC I/Q output
* @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
@@ -743,6 +744,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);
+ void (*get_adc_entropy)(struct ath_hw *ah, u8 *buf, size_t len);
void (*spectral_scan_config)(struct ath_hw *ah,
struct ath_spec_scan *param);
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
@@ -1945,6 +1945,26 @@ void ar9003_hw_init_rate_txpower(struct
}
}
+static void ar9003_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
+{
+ int i, j;
+
+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
+ REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, AR_PHY_TEST_CTL_RX_OBS_SEL, 0);
+
+ memset(buf, 0, len);
+ for (i = 0; i < len; i++) {
+ for (j = 0; j < 4; j++) {
+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC);
+
+ buf[i] <<= 2;
+ buf[i] |= (regval & 1) | ((regval & BIT(10)) >> 9);
+ udelay(1);
+ }
+ }
+}
+
void ar9003_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
@@ -1981,6 +2001,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;
+ ops->get_adc_entropy = ar9003_hw_get_adc_entropy;
ops->antdiv_comb_conf_get = ar9003_hw_antdiv_comb_conf_get;
ops->antdiv_comb_conf_set = ar9003_hw_antdiv_comb_conf_set;
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
@@ -821,7 +821,8 @@ static void ath9k_init_txpower_limits(st
if (ah->caps.hw_caps & ATH9K_HW_CAP_5GHZ)
ath9k_init_band_txpower(sc, NL80211_BAND_5GHZ);
- ah->curchan = curchan;
+ if (curchan)
+ ah->curchan = curchan;
}
static const struct ieee80211_iface_limit if_limits[] = {
@@ -1016,6 +1017,18 @@ static void ath9k_set_hw_capab(struct at
wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
}
+static void ath_get_initial_entropy(struct ath_softc *sc)
+{
+ struct ath_hw *ah = sc->sc_ah;
+ char buf[256];
+
+ /* reuse last channel initialized by the tx power test */
+ ath9k_hw_reset(ah, ah->curchan, NULL, false);
+
+ ath9k_hw_get_adc_entropy(ah, buf, sizeof(buf));
+ add_device_randomness(buf, sizeof(buf));
+}
+
int ath9k_init_device(u16 devid, struct ath_softc *sc,
const struct ath_bus_ops *bus_ops)
{
@@ -1061,6 +1074,8 @@ int ath9k_init_device(u16 devid, struct
ARRAY_SIZE(ath9k_tpt_blink));
#endif
+ ath_get_initial_entropy(sc);
+
/* Register with mac80211 */
error = ieee80211_register_hw(hw);
if (error)
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -100,6 +100,12 @@ static inline void ath9k_hw_tx99_set_txp
ath9k_hw_ops(ah)->tx99_set_txpower(ah, power);
}
+static inline void ath9k_hw_get_adc_entropy(struct ath_hw *ah,
+ u8 *buf, size_t len)
+{
+ ath9k_hw_ops(ah)->get_adc_entropy(ah, buf, len);
+}
+
#ifdef CPTCFG_ATH9K_BTCOEX_SUPPORT
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
@@ -1324,9 +1324,30 @@ void ar5008_hw_init_rate_txpower(struct
}
}
+static void ar5008_hw_get_adc_entropy(struct ath_hw *ah, u8 *buf, size_t len)
+{
+ int i, j;
+
+ REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 1);
+ REG_CLR_BIT(ah, AR_PHY_TEST, AR_PHY_TEST_RX_OBS_SEL_BIT5);
+ REG_RMW_FIELD(ah, AR_PHY_TEST2, AR_PHY_TEST2_RX_OBS_SEL, 0);
+
+ memset(buf, 0, len);
+ for (i = 0; i < len; i++) {
+ for (j = 0; j < 4; j++) {
+ u32 regval = REG_READ(ah, AR_PHY_TST_ADC);
+
+ buf[i] <<= 2;
+ buf[i] |= (regval & 1) | ((regval & BIT(9)) >> 8);
+ udelay(1);
+ }
+ }
+}
+
int ar5008_hw_attach_phy_ops(struct ath_hw *ah)
{
struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
+ struct ath_hw_ops *ops = ath9k_hw_ops(ah);
static const u32 ar5416_cca_regs[6] = {
AR_PHY_CCA,
AR_PHY_CH1_CCA,
@@ -1341,6 +1362,8 @@ int ar5008_hw_attach_phy_ops(struct ath_
if (ret)
return ret;
+ ops->get_adc_entropy = ar5008_hw_get_adc_entropy;
+
priv_ops->rf_set_freq = ar5008_hw_set_channel;
priv_ops->spur_mitigate_freq = ar5008_hw_spur_mitigate;
--- a/drivers/net/wireless/ath/ath9k/ar9002_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9002_phy.h
@@ -20,6 +20,12 @@
#define PHY_AGC_CLR 0x10000000
#define RFSILENT_BB 0x00002000
+#define AR_PHY_TEST_BBB_OBS_SEL 0x780000
+#define AR_PHY_TEST_BBB_OBS_SEL_S 19
+
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5_S 23
+#define AR_PHY_TEST_RX_OBS_SEL_BIT5 (1 << AR_PHY_TEST_RX_OBS_SEL_BIT5_S)
+
#define AR_PHY_TURBO 0x9804
#define AR_PHY_FC_TURBO_MODE 0x00000001
#define AR_PHY_FC_TURBO_SHORT 0x00000002
@@ -36,6 +42,9 @@
#define AR_PHY_TEST2 0x9808
+#define AR_PHY_TEST2_RX_OBS_SEL 0x3C00
+#define AR_PHY_TEST2_RX_OBS_SEL_S 10
+
#define AR_PHY_TIMING2 0x9810
#define AR_PHY_TIMING3 0x9814
#define AR_PHY_TIMING3_DSC_MAN 0xFFFE0000
@@ -393,6 +402,8 @@
#define AR_PHY_RFBUS_GRANT 0x9C20
#define AR_PHY_RFBUS_GRANT_EN 0x00000001
+#define AR_PHY_TST_ADC 0x9C24
+
#define AR_PHY_CHAN_INFO_GAIN_DIFF 0x9CF4
#define AR_PHY_CHAN_INFO_GAIN_DIFF_UPPER_LIMIT 320

View File

@@ -0,0 +1,79 @@
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -248,6 +248,19 @@ void ath9k_hw_get_channel_centers(struct
centers->synth_center + (extoff * HT40_CHANNEL_CENTER_SHIFT);
}
+static inline void ath9k_hw_disable_pll_lock_detect(struct ath_hw *ah)
+{
+ /* On AR9330 and AR9340 devices, some PHY registers must be
+ * tuned to gain better stability/performance. These registers
+ * might be changed while doing wlan reset so the registers must
+ * be reprogrammed after each reset.
+ */
+ REG_CLR_BIT(ah, AR_PHY_USB_CTRL1, BIT(20));
+ REG_RMW(ah, AR_PHY_USB_CTRL2,
+ (1 << 21) | (0xf << 22),
+ (1 << 21) | (0x3 << 22));
+}
+
/******************/
/* Chip Revisions */
/******************/
@@ -1455,6 +1468,9 @@ static bool ath9k_hw_set_reset(struct at
udelay(50);
}
+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
+ ath9k_hw_disable_pll_lock_detect(ah);
+
return true;
}
@@ -1554,6 +1570,9 @@ static bool ath9k_hw_chip_reset(struct a
ar9003_hw_internal_regulator_apply(ah);
ath9k_hw_init_pll(ah, chan);
+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
+ ath9k_hw_disable_pll_lock_detect(ah);
+
return true;
}
@@ -1861,8 +1880,14 @@ static int ath9k_hw_do_fastcc(struct ath
if (AR_SREV_9271(ah))
ar9002_hw_load_ani_reg(ah, chan);
+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
+ ath9k_hw_disable_pll_lock_detect(ah);
+
return 0;
fail:
+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
+ ath9k_hw_disable_pll_lock_detect(ah);
+
return -EINVAL;
}
@@ -2116,6 +2141,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st
ath9k_hw_set_radar_params(ah);
}
+ if (AR_SREV_9330(ah) || AR_SREV_9340(ah))
+ ath9k_hw_disable_pll_lock_detect(ah);
+
return 0;
}
EXPORT_SYMBOL(ath9k_hw_reset);
--- a/drivers/net/wireless/ath/ath9k/phy.h
+++ b/drivers/net/wireless/ath/ath9k/phy.h
@@ -48,6 +48,9 @@
#define AR_PHY_PLL_CONTROL 0x16180
#define AR_PHY_PLL_MODE 0x16184
+#define AR_PHY_USB_CTRL1 0x16c84
+#define AR_PHY_USB_CTRL2 0x16c88
+
enum ath9k_ant_div_comb_lna_conf {
ATH_ANT_DIV_COMB_LNA1_MINUS_LNA2,
ATH_ANT_DIV_COMB_LNA2,

View File

@@ -0,0 +1,155 @@
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -953,55 +953,6 @@ static bool ar5008_hw_ani_control_new(st
* on == 0 means more noise imm
*/
u32 on = param ? 1 : 0;
- /*
- * make register setting for default
- * (weak sig detect ON) come from INI file
- */
- int m1ThreshLow = on ?
- aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
- int m2ThreshLow = on ?
- aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
- int m1Thresh = on ?
- aniState->iniDef.m1Thresh : m1Thresh_off;
- int m2Thresh = on ?
- aniState->iniDef.m2Thresh : m2Thresh_off;
- int m2CountThr = on ?
- aniState->iniDef.m2CountThr : m2CountThr_off;
- int m2CountThrLow = on ?
- aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
- int m1ThreshLowExt = on ?
- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
- int m2ThreshLowExt = on ?
- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
- int m1ThreshExt = on ?
- aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
- int m2ThreshExt = on ?
- aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
-
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
- AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
- m1ThreshLow);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
- AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
- m2ThreshLow);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
- AR_PHY_SFCORR_M1_THRESH, m1Thresh);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
- AR_PHY_SFCORR_M2_THRESH, m2Thresh);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
- AR_PHY_SFCORR_M2COUNT_THR, m2CountThr);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
- m2CountThrLow);
-
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
- AR_PHY_SFCORR_EXT_M1_THRESH_LOW, m1ThreshLowExt);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
- AR_PHY_SFCORR_EXT_M2_THRESH_LOW, m2ThreshLowExt);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
- AR_PHY_SFCORR_EXT_M1_THRESH, m1ThreshExt);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
- AR_PHY_SFCORR_EXT_M2_THRESH, m2ThreshExt);
if (on)
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
@@ -42,20 +42,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 */
-/*
- * register values to turn OFDM weak signal detection OFF
- */
-static const int m1ThreshLow_off = 127;
-static const int m2ThreshLow_off = 127;
-static const int m1Thresh_off = 127;
-static const int m2Thresh_off = 127;
-static const int m2CountThr_off = 31;
-static const int m2CountThrLow_off = 63;
-static const int m1ThreshLowExt_off = 127;
-static const int m2ThreshLowExt_off = 127;
-static const int m1ThreshExt_off = 127;
-static const int m2ThreshExt_off = 127;
-
static const u8 ofdm2pwr[] = {
ALL_TARGET_LEGACY_6_24,
ALL_TARGET_LEGACY_6_24,
@@ -1095,11 +1081,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;
- int m1ThreshLow, m2ThreshLow;
- int m1Thresh, m2Thresh;
- int m2CountThr, m2CountThrLow;
- int m1ThreshLowExt, m2ThreshLowExt;
- int m1ThreshExt, m2ThreshExt;
s32 value, value2;
switch (cmd & ah->ani_function) {
@@ -1113,61 +1094,6 @@ static bool ar9003_hw_ani_control(struct
*/
u32 on = param ? 1 : 0;
- if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
- goto skip_ws_det;
-
- m1ThreshLow = on ?
- aniState->iniDef.m1ThreshLow : m1ThreshLow_off;
- m2ThreshLow = on ?
- aniState->iniDef.m2ThreshLow : m2ThreshLow_off;
- m1Thresh = on ?
- aniState->iniDef.m1Thresh : m1Thresh_off;
- m2Thresh = on ?
- aniState->iniDef.m2Thresh : m2Thresh_off;
- m2CountThr = on ?
- aniState->iniDef.m2CountThr : m2CountThr_off;
- m2CountThrLow = on ?
- aniState->iniDef.m2CountThrLow : m2CountThrLow_off;
- m1ThreshLowExt = on ?
- aniState->iniDef.m1ThreshLowExt : m1ThreshLowExt_off;
- m2ThreshLowExt = on ?
- aniState->iniDef.m2ThreshLowExt : m2ThreshLowExt_off;
- m1ThreshExt = on ?
- aniState->iniDef.m1ThreshExt : m1ThreshExt_off;
- m2ThreshExt = on ?
- aniState->iniDef.m2ThreshExt : m2ThreshExt_off;
-
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
- AR_PHY_SFCORR_LOW_M1_THRESH_LOW,
- m1ThreshLow);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
- AR_PHY_SFCORR_LOW_M2_THRESH_LOW,
- m2ThreshLow);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
- AR_PHY_SFCORR_M1_THRESH,
- m1Thresh);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
- AR_PHY_SFCORR_M2_THRESH,
- m2Thresh);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR,
- AR_PHY_SFCORR_M2COUNT_THR,
- m2CountThr);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_LOW,
- AR_PHY_SFCORR_LOW_M2COUNT_THR_LOW,
- m2CountThrLow);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
- AR_PHY_SFCORR_EXT_M1_THRESH_LOW,
- m1ThreshLowExt);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
- AR_PHY_SFCORR_EXT_M2_THRESH_LOW,
- m2ThreshLowExt);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
- AR_PHY_SFCORR_EXT_M1_THRESH,
- m1ThreshExt);
- REG_RMW_FIELD(ah, AR_PHY_SFCORR_EXT,
- AR_PHY_SFCORR_EXT_M2_THRESH,
- m2ThreshExt);
-skip_ws_det:
if (on)
REG_SET_BIT(ah, AR_PHY_SFCORR_LOW,
AR_PHY_SFCORR_LOW_USE_SELF_CORR_LOW);

View File

@@ -0,0 +1,29 @@
From: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
Date: Sun, 31 Jan 2016 20:48:49 +0100
Subject: [PATCH v4 2/8] mac80211: ath9k: set default state for platform LEDs
Support default state for platform LEDs connected to ath9k device.
Now LEDs are correctly set on or off at ath9k module initialization.
Very useful if power LED is connected to wireless chip.
Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
---
gpio.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -74,8 +74,11 @@ static int ath_add_led(struct ath_softc
ath9k_hw_gpio_request_out(sc->sc_ah, gpio->gpio, gpio->name,
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
- /* LED off */
- ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
+ /* Set default LED state */
+ if (gpio->default_state == LEDS_GPIO_DEFSTATE_ON)
+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, !gpio->active_low);
+ else
+ ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
return 0;
}

View File

@@ -0,0 +1,251 @@
From: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
Date: Sun, 31 Jan 2016 21:01:31 +0100
Subject: [PATCH v4 4/8] mac80211: ath9k: enable access to GPIO
Enable access to GPIO chip and its pins for Atheros AR92xx
wireless devices. For now AR9285 and AR9287 are supported.
Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -24,6 +24,7 @@
#include <linux/completion.h>
#include <linux/time.h>
#include <linux/hw_random.h>
+#include <linux/gpio/driver.h>
#include "common.h"
#include "debug.h"
@@ -1001,6 +1002,14 @@ struct ath_led {
struct led_classdev cdev;
};
+#ifdef CONFIG_GPIOLIB
+struct ath9k_gpio_chip {
+ struct ath_softc *sc;
+ char label[32];
+ struct gpio_chip gchip;
+};
+#endif
+
struct ath_softc {
struct ieee80211_hw *hw;
struct device *dev;
@@ -1058,6 +1067,9 @@ struct ath_softc {
#ifdef CPTCFG_MAC80211_LEDS
const char *led_default_trigger;
struct list_head leds;
+#ifdef CONFIG_GPIOLIB
+ struct ath9k_gpio_chip *gpiochip;
+#endif
#endif
#ifdef CPTCFG_ATH9K_DEBUGFS
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -16,13 +16,139 @@
#include "ath9k.h"
#include <linux/ath9k_platform.h>
+#include <linux/gpio.h>
+
+#ifdef CPTCFG_MAC80211_LEDS
+
+#ifdef CONFIG_GPIOLIB
+
+/***************/
+/* GPIO Chip */
+/***************/
+
+/* gpio_chip handler : set GPIO to input */
+static int ath9k_gpio_pin_cfg_input(struct gpio_chip *chip, unsigned offset)
+{
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
+ gchip);
+
+ ath9k_hw_gpio_request_in(gc->sc->sc_ah, offset, "ath9k-gpio");
+
+ return 0;
+}
+
+/* gpio_chip handler : set GPIO to output */
+static int ath9k_gpio_pin_cfg_output(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
+ gchip);
+
+ ath9k_hw_gpio_request_out(gc->sc->sc_ah, offset, "ath9k-gpio",
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value);
+
+ return 0;
+}
+
+/* gpio_chip handler : query GPIO direction (0=out, 1=in) */
+static int ath9k_gpio_pin_get_dir(struct gpio_chip *chip, unsigned offset)
+{
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
+ gchip);
+ struct ath_hw *ah = gc->sc->sc_ah;
+
+ return !((REG_READ(ah, AR_GPIO_OE_OUT) >> (offset * 2)) & 3);
+}
+
+/* gpio_chip handler : get GPIO pin value */
+static int ath9k_gpio_pin_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
+ gchip);
+
+ return ath9k_hw_gpio_get(gc->sc->sc_ah, offset);
+}
+
+/* gpio_chip handler : set GPIO pin to value */
+static void ath9k_gpio_pin_set(struct gpio_chip *chip, unsigned offset,
+ int value)
+{
+ struct ath9k_gpio_chip *gc = container_of(chip, struct ath9k_gpio_chip,
+ gchip);
+
+ ath9k_hw_set_gpio(gc->sc->sc_ah, offset, value);
+}
+
+/* register GPIO chip */
+static void ath9k_register_gpio_chip(struct ath_softc *sc)
+{
+ struct ath9k_gpio_chip *gc;
+ struct ath_hw *ah = sc->sc_ah;
+
+ gc = kzalloc(sizeof(struct ath9k_gpio_chip), GFP_KERNEL);
+ if (!gc)
+ return;
+
+ gc->sc = sc;
+ snprintf(gc->label, sizeof(gc->label), "ath9k-%s",
+ wiphy_name(sc->hw->wiphy));
+#ifdef CONFIG_OF
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,5,0)
+ gc->gchip.parent = sc->dev;
+#else
+ gc->gchip.dev = sc->dev;
+#endif
+#endif
+ gc->gchip.label = gc->label;
+ gc->gchip.base = -1; /* determine base automatically */
+ gc->gchip.ngpio = ah->caps.num_gpio_pins;
+ gc->gchip.direction_input = ath9k_gpio_pin_cfg_input;
+ gc->gchip.direction_output = ath9k_gpio_pin_cfg_output;
+ gc->gchip.get_direction = ath9k_gpio_pin_get_dir;
+ gc->gchip.get = ath9k_gpio_pin_get;
+ gc->gchip.set = ath9k_gpio_pin_set;
+
+ if (gpiochip_add(&gc->gchip)) {
+ kfree(gc);
+ return;
+ }
+
+#ifdef CONFIG_OF
+ gc->gchip.owner = NULL;
+#endif
+ sc->gpiochip = gc;
+}
+
+/* remove GPIO chip */
+static void ath9k_unregister_gpio_chip(struct ath_softc *sc)
+{
+ struct ath9k_gpio_chip *gc = sc->gpiochip;
+
+ if (!gc)
+ return;
+
+ gpiochip_remove(&gc->gchip);
+ kfree(gc);
+ sc->gpiochip = NULL;
+}
+
+#else /* CONFIG_GPIOLIB */
+
+static inline void ath9k_register_gpio_chip(struct ath_softc *sc)
+{
+}
+
+static inline void ath9k_unregister_gpio_chip(struct ath_softc *sc)
+{
+}
+
+#endif /* CONFIG_GPIOLIB */
/********************************/
/* LED functions */
/********************************/
-#ifdef CPTCFG_MAC80211_LEDS
-
static void ath_fill_led_pin(struct ath_softc *sc)
{
struct ath_hw *ah = sc->sc_ah;
@@ -80,6 +206,12 @@ static int ath_add_led(struct ath_softc
else
ath9k_hw_set_gpio(sc->sc_ah, gpio->gpio, gpio->active_low);
+#ifdef CONFIG_GPIOLIB
+ /* If there is GPIO chip configured, reserve LED pin */
+ if (sc->gpiochip)
+ gpio_request(sc->gpiochip->gchip.base + gpio->gpio, gpio->name);
+#endif
+
return 0;
}
@@ -136,17 +268,24 @@ void ath_deinit_leds(struct ath_softc *s
while (!list_empty(&sc->leds)) {
led = list_first_entry(&sc->leds, struct ath_led, list);
+#ifdef CONFIG_GPIOLIB
+ /* If there is GPIO chip configured, free LED pin */
+ if (sc->gpiochip)
+ gpio_free(sc->gpiochip->gchip.base + led->gpio->gpio);
+#endif
list_del(&led->list);
ath_led_brightness(&led->cdev, LED_OFF);
led_classdev_unregister(&led->cdev);
ath9k_hw_gpio_free(sc->sc_ah, led->gpio->gpio);
kfree(led);
}
+ ath9k_unregister_gpio_chip(sc);
}
void ath_init_leds(struct ath_softc *sc)
{
struct ath9k_platform_data *pdata = sc->dev->platform_data;
+ struct device_node *np = sc->dev->of_node;
char led_name[32];
const char *trigger;
int i;
@@ -156,6 +295,15 @@ void ath_init_leds(struct ath_softc *sc)
if (AR_SREV_9100(sc->sc_ah))
return;
+ if (!np)
+ ath9k_register_gpio_chip(sc);
+
+ /* setup gpio controller only if requested and skip the led_pin setup */
+ if (of_property_read_bool(np, "gpio-controller")) {
+ ath9k_register_gpio_chip(sc);
+ return;
+ }
+
ath_fill_led_pin(sc);
if (pdata && pdata->leds && pdata->num_leds)
@@ -180,6 +328,7 @@ void ath_init_leds(struct ath_softc *sc)
ath_create_gpio_led(sc, sc->sc_ah->led_pin, led_name, trigger,
!sc->sc_ah->config.led_active_high);
}
+
#endif
/*******************/

View File

@@ -0,0 +1,143 @@
From: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
Subject: [PATCH v5 5/8] mac80211: ath9k: enable GPIO buttons
Enable platform-defined GPIO button support for ath9k device.
Key poller is activated for attached platform buttons.
Requires ath9k GPIO chip access.
Signed-off-by: Michal Cieslakiewicz <michal.cieslakiewicz@wp.pl>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -1069,6 +1069,7 @@ struct ath_softc {
struct list_head leds;
#ifdef CONFIG_GPIOLIB
struct ath9k_gpio_chip *gpiochip;
+ struct platform_device *btnpdev; /* gpio-keys-polled */
#endif
#endif
--- a/drivers/net/wireless/ath/ath9k/gpio.c
+++ b/drivers/net/wireless/ath/ath9k/gpio.c
@@ -17,6 +17,8 @@
#include "ath9k.h"
#include <linux/ath9k_platform.h>
#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/gpio_keys.h>
#ifdef CPTCFG_MAC80211_LEDS
@@ -133,6 +135,67 @@ static void ath9k_unregister_gpio_chip(s
sc->gpiochip = NULL;
}
+/******************/
+/* GPIO Buttons */
+/******************/
+
+/* add GPIO buttons */
+static void ath9k_init_buttons(struct ath_softc *sc)
+{
+ struct ath9k_platform_data *pdata = sc->dev->platform_data;
+ struct platform_device *pdev;
+ struct gpio_keys_platform_data gkpdata;
+ struct gpio_keys_button *bt;
+ int i;
+
+ if (!sc->gpiochip)
+ return;
+
+ if (!pdata || !pdata->btns || !pdata->num_btns)
+ return;
+
+ bt = devm_kmemdup(sc->dev, pdata->btns,
+ pdata->num_btns * sizeof(struct gpio_keys_button),
+ GFP_KERNEL);
+ if (!bt)
+ return;
+
+ for (i = 0; i < pdata->num_btns; i++) {
+ if (pdata->btns[i].gpio == sc->sc_ah->led_pin)
+ sc->sc_ah->led_pin = -1;
+
+ ath9k_hw_gpio_request_in(sc->sc_ah, pdata->btns[i].gpio,
+ "ath9k-gpio");
+ bt[i].gpio = sc->gpiochip->gchip.base + pdata->btns[i].gpio;
+ }
+
+ memset(&gkpdata, 0, sizeof(struct gpio_keys_platform_data));
+ gkpdata.buttons = bt;
+ gkpdata.nbuttons = pdata->num_btns;
+ gkpdata.poll_interval = pdata->btn_poll_interval;
+
+ pdev = platform_device_register_data(sc->dev, "gpio-keys-polled",
+ PLATFORM_DEVID_AUTO, &gkpdata,
+ sizeof(gkpdata));
+ if (!IS_ERR_OR_NULL(pdev))
+ sc->btnpdev = pdev;
+ else {
+ sc->btnpdev = NULL;
+ devm_kfree(sc->dev, bt);
+ }
+}
+
+/* remove GPIO buttons */
+static void ath9k_deinit_buttons(struct ath_softc *sc)
+{
+ if (!sc->gpiochip || !sc->btnpdev)
+ return;
+
+ platform_device_unregister(sc->btnpdev);
+
+ sc->btnpdev = NULL;
+}
+
#else /* CONFIG_GPIOLIB */
static inline void ath9k_register_gpio_chip(struct ath_softc *sc)
@@ -143,6 +206,14 @@ static inline void ath9k_unregister_gpio
{
}
+static inline void ath9k_init_buttons(struct ath_softc *sc)
+{
+}
+
+static inline void ath9k_deinit_buttons(struct ath_softc *sc)
+{
+}
+
#endif /* CONFIG_GPIOLIB */
/********************************/
@@ -266,6 +337,7 @@ void ath_deinit_leds(struct ath_softc *s
{
struct ath_led *led;
+ ath9k_deinit_buttons(sc);
while (!list_empty(&sc->leds)) {
led = list_first_entry(&sc->leds, struct ath_led, list);
#ifdef CONFIG_GPIOLIB
@@ -305,6 +377,7 @@ void ath_init_leds(struct ath_softc *sc)
}
ath_fill_led_pin(sc);
+ ath9k_init_buttons(sc);
if (pdata && pdata->leds && pdata->num_leds)
for (i = 0; i < pdata->num_leds; i++) {
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -49,6 +49,10 @@ struct ath9k_platform_data {
int num_leds;
const struct gpio_led *leds;
+
+ unsigned num_btns;
+ const struct gpio_keys_button *btns;
+ unsigned btn_poll_interval;
};
#endif /* _LINUX_ATH9K_PLATFORM_H */

View File

@@ -0,0 +1,15 @@
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -627,6 +627,12 @@ static int ath9k_of_init(struct ath_soft
ath_dbg(common, CONFIG, "parsing configuration from OF node\n");
+ if (of_property_read_bool(np, "qca,disable-2ghz"))
+ ah->disable_2ghz = true;
+
+ if (of_property_read_bool(np, "qca,disable-5ghz"))
+ ah->disable_5ghz = true;
+
if (of_property_read_bool(np, "qca,no-eeprom")) {
/* ath9k-eeprom-<bus>-<id>.bin */
scnprintf(eeprom_name, sizeof(eeprom_name),

View File

@@ -0,0 +1,418 @@
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -15,6 +15,8 @@
*/
#include "ath9k.h"
+#include <linux/ath9k_platform.h>
+#include "hsr.h"
/* Set/change channels. If the channel is really being changed, it's done
* by reseting the chip. To accomplish this we must first cleanup any pending
@@ -22,6 +24,7 @@
*/
static int ath_set_channel(struct ath_softc *sc)
{
+ struct ath9k_platform_data *pdata = sc->dev->platform_data;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_hw *hw = sc->hw;
@@ -42,6 +45,11 @@ static int ath_set_channel(struct ath_so
ath_dbg(common, CONFIG, "Set channel: %d MHz width: %d\n",
chan->center_freq, chandef->width);
+ if (pdata && pdata->ubnt_hsr) {
+ ath9k_hsr_enable(ah, chandef->width, chan->center_freq);
+ ath9k_hsr_status(ah);
+ }
+
/* update survey stats for the old channel before switching */
spin_lock_irqsave(&common->cc_lock, flags);
ath_update_survey_stats(sc);
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hsr.c
@@ -0,0 +1,247 @@
+/*
+ *
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Kirill Berezin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ *
+ */
+
+#include <linux/io.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/time.h>
+#include <linux/bitops.h>
+#include <linux/etherdevice.h>
+#include <linux/rtnetlink.h>
+#include <asm/unaligned.h>
+
+#include "hw.h"
+#include "ath9k.h"
+
+#define HSR_GPIO_CSN 8
+#define HSR_GPIO_CLK 6
+#define HSR_GPIO_DOUT 7
+#define HSR_GPIO_DIN 5
+
+/* delays are in useconds */
+#define HSR_DELAY_HALF_TICK 100
+#define HSR_DELAY_PRE_WRITE 75
+#define HSR_DELAY_FINAL 20000
+#define HSR_DELAY_TRAILING 200
+
+void ath9k_hsr_init(struct ath_hw *ah)
+{
+ ath9k_hw_gpio_request_in(ah, HSR_GPIO_DIN, NULL);
+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CSN, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_CLK, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+ ath9k_hw_gpio_request_out(ah, HSR_GPIO_DOUT, NULL,
+ AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
+
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1);
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0);
+ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, 0);
+
+ udelay(HSR_DELAY_TRAILING);
+}
+
+static u32 ath9k_hsr_write_byte(struct ath_hw *ah, int delay, u32 value)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ int i;
+ u32 rval = 0;
+
+ udelay(delay);
+
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0);
+ udelay(HSR_DELAY_HALF_TICK);
+
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 0);
+ udelay(HSR_DELAY_HALF_TICK);
+
+ for (i = 0; i < 8; ++i) {
+ rval = rval << 1;
+
+ /* pattern is left to right, that is 7-th bit runs first */
+ ath9k_hw_set_gpio(ah, HSR_GPIO_DOUT, (value >> (7 - i)) & 0x1);
+ udelay(HSR_DELAY_HALF_TICK);
+
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 1);
+ udelay(HSR_DELAY_HALF_TICK);
+
+ rval |= ath9k_hw_gpio_get(ah, HSR_GPIO_DIN);
+
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CLK, 0);
+ udelay(HSR_DELAY_HALF_TICK);
+ }
+
+ ath9k_hw_set_gpio(ah, HSR_GPIO_CSN, 1);
+ udelay(HSR_DELAY_HALF_TICK);
+
+ ath_dbg(common, CONFIG, "ath9k_hsr_write_byte: write byte %d return value is %d %c\n",
+ value, rval, rval > 32 ? rval : '-');
+
+ return rval & 0xff;
+}
+
+static int ath9k_hsr_write_a_chain(struct ath_hw *ah, char *chain, int items)
+{
+ int status = 0;
+ int i = 0;
+ int err;
+
+ /* a preamble */
+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
+ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
+
+ /* clear HSR's reply buffer */
+ if (status) {
+ int loop = 0;
+
+ for (loop = 0; (loop < 42) && status; ++loop)
+ status = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE,
+ 0);
+
+ if (loop >= 42) {
+ ATH_DBG_WARN(1,
+ "ath9k_hsr_write_a_chain: can't clear an output buffer after a 42 cycles.\n");
+ return -1;
+ }
+ }
+
+ for (i = 0; (i < items) && (chain[i] != 0); ++i)
+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, (u32)chain[i]);
+
+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
+ mdelay(HSR_DELAY_FINAL / 1000);
+
+ /* reply */
+ memset(chain, 0, items);
+
+ ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
+ udelay(HSR_DELAY_TRAILING);
+
+ for (i = 0; i < (items - 1); ++i) {
+ u32 ret;
+
+ ret = ath9k_hsr_write_byte(ah, HSR_DELAY_PRE_WRITE, 0);
+ if (ret != 0)
+ chain[i] = (char)ret;
+ else
+ break;
+
+ udelay(HSR_DELAY_TRAILING);
+ }
+
+ if (i <= 1)
+ return 0;
+
+ err = kstrtoint(chain + 1, 10, &i);
+ if (err)
+ return err;
+
+ return i;
+}
+
+int ath9k_hsr_disable(struct ath_hw *ah)
+{
+ char cmd[10] = {'b', '4', '0', 0, 0, 0, 0, 0, 0, 0};
+ int ret;
+
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
+ if ((ret > 0) && (*cmd == 'B'))
+ return 0;
+
+ return -1;
+}
+
+int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq)
+{
+ char cmd[10];
+ int ret;
+
+ /* Bandwidth argument is 0 sometimes. Assume default 802.11bgn
+ * 20MHz on invalid values
+ */
+ if ((bw != 5) && (bw != 10) && (bw != 20) && (bw != 40))
+ bw = 20;
+
+ memset(cmd, 0, sizeof(cmd));
+ *cmd = 'b';
+ snprintf(cmd + 1, 3, "%02d", bw);
+
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
+ if ((*cmd != 'B') || (ret != bw)) {
+ ATH_DBG_WARN(1,
+ "ath9k_hsr_enable: failed changing bandwidth -> set (%d,%d) reply (%d, %d)\n",
+ 'b', bw, *cmd, ret);
+ return -1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+ *cmd = 'x';
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
+ if (*cmd != 'X') {
+ ATH_DBG_WARN(1,
+ "ath9k_hsr_enable: failed 'x' command -> reply (%d, %d)\n",
+ *cmd, ret);
+ return -1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+ *cmd = 'm';
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
+ if (*cmd != 'M') {
+ ATH_DBG_WARN(1,
+ "ath9k_hsr_enable: failed 'm' command -> reply (%d, %d)\n",
+ *cmd, ret);
+ return -1;
+ }
+
+ memset(cmd, 0, sizeof(cmd));
+ *cmd = 'f';
+ snprintf(cmd + 1, 6, "%05d", fq);
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
+ if ((*cmd != 'F') && (ret != fq)) {
+ ATH_DBG_WARN(1,
+ "ath9k_hsr_enable: failed set frequency -> reply (%d, %d)\n",
+ *cmd, ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+int ath9k_hsr_status(struct ath_hw *ah)
+{
+ char cmd[10] = {'s', 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ int ret;
+
+ ret = ath9k_hsr_write_a_chain(ah, cmd, sizeof(cmd));
+ if (*cmd != 'S') {
+ ATH_DBG_WARN(1, "ath9k_hsr_status: returned %d,%d\n", *cmd,
+ ret);
+ return -1;
+ }
+
+ return 0;
+}
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/hsr.h
@@ -0,0 +1,48 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2015 Kirill Berezin
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef HSR_H
+#define HSR_H
+
+#ifdef CPTCFG_ATH9K_UBNTHSR
+
+void ath9k_hsr_init(struct ath_hw *ah);
+int ath9k_hsr_disable(struct ath_hw *ah);
+int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq);
+int ath9k_hsr_status(struct ath_hw *ah);
+
+#else
+static inline void ath9k_hsr_init(struct ath_hw *ah) {}
+
+static inline int ath9k_hsr_enable(struct ath_hw *ah, int bw, int fq)
+{
+ return 0;
+}
+
+static inline int ath9k_hsr_disable(struct ath_hw *ah) { return 0; }
+static inline int ath9k_hsr_status(struct ath_hw *ah) { return 0; }
+
+#endif
+
+#endif /* HSR_H */
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -16,8 +16,10 @@
#include <linux/nl80211.h>
#include <linux/delay.h>
+#include <linux/ath9k_platform.h>
#include "ath9k.h"
#include "btcoex.h"
+#include "hsr.h"
u8 ath9k_parse_mpdudensity(u8 mpdudensity)
{
@@ -649,6 +651,7 @@ void ath_reset_work(struct work_struct *
static int ath9k_start(struct ieee80211_hw *hw)
{
struct ath_softc *sc = hw->priv;
+ struct ath9k_platform_data *pdata = sc->dev->platform_data;
struct ath_hw *ah = sc->sc_ah;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_channel *curchan = sc->cur_chan->chandef.chan;
@@ -727,6 +730,11 @@ static int ath9k_start(struct ieee80211_
AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
}
+ if (pdata && pdata->ubnt_hsr) {
+ ath9k_hsr_init(ah);
+ ath9k_hsr_disable(ah);
+ }
+
/*
* Reset key cache to sane defaults (all entries cleared) instead of
* semi-random values after suspend/resume.
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -17,6 +17,7 @@ ath9k-$(CPTCFG_ATH9K_DFS_CERTIFIED) += d
ath9k-$(CPTCFG_ATH9K_TX99) += tx99.o
ath9k-$(CPTCFG_ATH9K_WOW) += wow.o
ath9k-$(CPTCFG_ATH9K_HWRNG) += rng.o
+ath9k-$(CPTCFG_ATH9K_UBNTHSR) += hsr.o
ath9k-$(CPTCFG_ATH9K_DEBUGFS) += debug.o
--- a/include/linux/ath9k_platform.h
+++ b/include/linux/ath9k_platform.h
@@ -53,6 +53,8 @@ struct ath9k_platform_data {
unsigned num_btns;
const struct gpio_keys_button *btns;
unsigned btn_poll_interval;
+
+ bool ubnt_hsr;
};
#endif /* _LINUX_ATH9K_PLATFORM_H */
--- a/local-symbols
+++ b/local-symbols
@@ -110,6 +110,7 @@ ATH9K_WOW=
ATH9K_RFKILL=
ATH9K_CHANNEL_CONTEXT=
ATH9K_PCOEM=
+ATH9K_UBNTHSR=
ATH9K_HTC=
ATH9K_HTC_DEBUGFS=
ATH9K_HWRNG=
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -59,6 +59,19 @@ config ATH9K_AHB
Say Y, if you have a SoC with a compatible built-in
wireless MAC. Say N if unsure.
+config ATH9K_UBNTHSR
+ bool "Ubiquiti UniFi Outdoor Plus HSR support"
+ depends on ATH9K
+ ---help---
+ This options enables code to control the HSR RF
+ filter in the receive path of the Ubiquiti UniFi
+ Outdoor Plus access point.
+
+ Say Y if you want to use the access point. The
+ code will only be used if the device is detected,
+ so it does not harm other setup other than occupying
+ a bit of memory.
+
config ATH9K_DEBUGFS
bool "Atheros ath9k debugging"
depends on ATH9K && DEBUG_FS

View File

@@ -0,0 +1,337 @@
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -20,7 +20,15 @@
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
+#include <linux/of_device.h>
#include "ath9k.h"
+#include <linux/ath9k_platform.h>
+
+#ifdef CONFIG_OF
+#include <asm/mach-ath79/ath79.h>
+#include <asm/mach-ath79/ar71xx_regs.h>
+#include <linux/mtd/mtd.h>
+#endif
static const struct platform_device_id ath9k_platform_id_table[] = {
{
@@ -69,6 +77,242 @@ static const struct ath_bus_ops ath_ahb_
.eeprom_read = ath_ahb_eeprom_read,
};
+#ifdef CONFIG_OF
+
+#define QCA955X_DDR_CTL_CONFIG 0x108
+#define QCA955X_DDR_CTL_CONFIG_ACT_WMAC BIT(23)
+
+static int of_get_wifi_cal(struct device_node *np, struct ath9k_platform_data *pdata)
+{
+#ifdef CONFIG_MTD
+ struct device_node *mtd_np = NULL;
+ size_t retlen;
+ int size, ret;
+ struct mtd_info *mtd;
+ const char *part;
+ const __be32 *list;
+ phandle phandle;
+
+ list = of_get_property(np, "mtd-cal-data", &size);
+ if (!list)
+ return 0;
+
+ if (size != (2 * sizeof(*list)))
+ return 1;
+
+ phandle = be32_to_cpup(list++);
+ if (phandle)
+ mtd_np = of_find_node_by_phandle(phandle);
+
+ if (!mtd_np)
+ return 1;
+
+ part = of_get_property(mtd_np, "label", NULL);
+ if (!part)
+ part = mtd_np->name;
+
+ mtd = get_mtd_device_nm(part);
+ if (IS_ERR(mtd))
+ return 1;
+
+ ret = mtd_read(mtd, be32_to_cpup(list), sizeof(pdata->eeprom_data),
+ &retlen, (u8*)pdata->eeprom_data);
+ put_mtd_device(mtd);
+
+#endif
+ return 0;
+}
+
+static int ar913x_wmac_reset(void)
+{
+ ath79_device_reset_set(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ ath79_device_reset_clear(AR913X_RESET_AMBA2WMAC);
+ mdelay(10);
+
+ return 0;
+}
+
+static int ar933x_wmac_reset(void)
+{
+ int retries = 20;
+
+ ath79_device_reset_set(AR933X_RESET_WMAC);
+ ath79_device_reset_clear(AR933X_RESET_WMAC);
+
+ while (1) {
+ u32 bootstrap;
+
+ bootstrap = ath79_reset_rr(AR933X_RESET_REG_BOOTSTRAP);
+ if ((bootstrap & AR933X_BOOTSTRAP_EEPBUSY) == 0)
+ return 0;
+
+ if (retries-- == 0)
+ break;
+
+ udelay(10000);
+ }
+
+ pr_err("ar933x: WMAC reset timed out");
+ return -ETIMEDOUT;
+}
+
+static int qca955x_wmac_reset(void)
+{
+ int i;
+
+ /* Try to wait for WMAC DDR activity to stop */
+ for (i = 0; i < 10; i++) {
+ if (!(__raw_readl(ath79_ddr_base + QCA955X_DDR_CTL_CONFIG) &
+ QCA955X_DDR_CTL_CONFIG_ACT_WMAC))
+ break;
+
+ udelay(10);
+ }
+
+ ath79_device_reset_set(QCA955X_RESET_RTC);
+ udelay(10);
+ ath79_device_reset_clear(QCA955X_RESET_RTC);
+ udelay(10);
+
+ return 0;
+}
+
+enum {
+ AR913X_WMAC = 0,
+ AR933X_WMAC,
+ AR934X_WMAC,
+ QCA953X_WMAC,
+ QCA955X_WMAC,
+ QCA956X_WMAC,
+};
+
+static int ar9330_get_soc_revision(void)
+{
+ if (ath79_soc_rev == 1)
+ return ath79_soc_rev;
+
+ return 0;
+}
+
+static int ath79_get_soc_revision(void)
+{
+ return ath79_soc_rev;
+}
+
+static const struct of_ath_ahb_data {
+ u16 dev_id;
+ u32 bootstrap_reg;
+ u32 bootstrap_ref;
+
+ int (*soc_revision)(void);
+ int (*wmac_reset)(void);
+} of_ath_ahb_data[] = {
+ [AR913X_WMAC] = {
+ .dev_id = AR5416_AR9100_DEVID,
+ .wmac_reset = ar913x_wmac_reset,
+
+ },
+ [AR933X_WMAC] = {
+ .dev_id = AR9300_DEVID_AR9330,
+ .bootstrap_reg = AR933X_RESET_REG_BOOTSTRAP,
+ .bootstrap_ref = AR933X_BOOTSTRAP_REF_CLK_40,
+ .soc_revision = ar9330_get_soc_revision,
+ .wmac_reset = ar933x_wmac_reset,
+ },
+ [AR934X_WMAC] = {
+ .dev_id = AR9300_DEVID_AR9340,
+ .bootstrap_reg = AR934X_RESET_REG_BOOTSTRAP,
+ .bootstrap_ref = AR934X_BOOTSTRAP_REF_CLK_40,
+ .soc_revision = ath79_get_soc_revision,
+ },
+ [QCA953X_WMAC] = {
+ .dev_id = AR9300_DEVID_AR953X,
+ .bootstrap_reg = QCA953X_RESET_REG_BOOTSTRAP,
+ .bootstrap_ref = QCA953X_BOOTSTRAP_REF_CLK_40,
+ .soc_revision = ath79_get_soc_revision,
+ },
+ [QCA955X_WMAC] = {
+ .dev_id = AR9300_DEVID_QCA955X,
+ .bootstrap_reg = QCA955X_RESET_REG_BOOTSTRAP,
+ .bootstrap_ref = QCA955X_BOOTSTRAP_REF_CLK_40,
+ .wmac_reset = qca955x_wmac_reset,
+ },
+ [QCA956X_WMAC] = {
+ .dev_id = AR9300_DEVID_QCA956X,
+ .bootstrap_reg = QCA956X_RESET_REG_BOOTSTRAP,
+ .bootstrap_ref = QCA956X_BOOTSTRAP_REF_CLK_40,
+ .soc_revision = ath79_get_soc_revision,
+ },
+};
+
+const struct of_device_id of_ath_ahb_match[] = {
+ { .compatible = "qca,ar9130-wmac", .data = &of_ath_ahb_data[AR913X_WMAC] },
+ { .compatible = "qca,ar9330-wmac", .data = &of_ath_ahb_data[AR933X_WMAC] },
+ { .compatible = "qca,ar9340-wmac", .data = &of_ath_ahb_data[AR934X_WMAC] },
+ { .compatible = "qca,qca9530-wmac", .data = &of_ath_ahb_data[QCA953X_WMAC] },
+ { .compatible = "qca,qca9550-wmac", .data = &of_ath_ahb_data[QCA955X_WMAC] },
+ { .compatible = "qca,qca9560-wmac", .data = &of_ath_ahb_data[QCA956X_WMAC] },
+ {},
+};
+MODULE_DEVICE_TABLE(of, of_ath_ahb_match);
+
+static int of_ath_ahb_probe(struct platform_device *pdev)
+{
+ struct ath9k_platform_data *pdata;
+ const struct of_device_id *match;
+ const struct of_ath_ahb_data *data;
+ u8 led_pin;
+
+ match = of_match_device(of_ath_ahb_match, &pdev->dev);
+ data = (const struct of_ath_ahb_data *)match->data;
+
+ pdata = dev_get_platdata(&pdev->dev);
+
+ if (!of_property_read_u8(pdev->dev.of_node, "qca,led-pin", &led_pin))
+ pdata->led_pin = led_pin;
+ else
+ pdata->led_pin = -1;
+
+ if (of_property_read_bool(pdev->dev.of_node, "qca,disable-2ghz"))
+ pdata->disable_2ghz = true;
+
+ if (of_property_read_bool(pdev->dev.of_node, "qca,disable-5ghz"))
+ pdata->disable_5ghz = true;
+
+ if (of_property_read_bool(pdev->dev.of_node, "qca,tx-gain-buffalo"))
+ pdata->tx_gain_buffalo = true;
+
+ if (data->wmac_reset) {
+ data->wmac_reset();
+ pdata->external_reset = data->wmac_reset;
+ }
+
+ if (data->dev_id == AR9300_DEVID_AR953X) {
+ /*
+ * QCA953x only supports 25MHz refclk.
+ * Some vendors have an invalid bootstrap option
+ * set, which would break the WMAC here.
+ */
+ pdata->is_clk_25mhz = true;
+ } else if (data->bootstrap_reg && data->bootstrap_ref) {
+ u32 t = ath79_reset_rr(data->bootstrap_reg);
+ if (t & data->bootstrap_ref)
+ pdata->is_clk_25mhz = false;
+ else
+ pdata->is_clk_25mhz = true;
+ }
+
+ pdata->get_mac_revision = data->soc_revision;
+
+ if (of_get_wifi_cal(pdev->dev.of_node, pdata))
+ dev_err(&pdev->dev, "failed to load calibration data from mtd device\n");
+
+ return data->dev_id;
+}
+#endif
+
static int ath_ahb_probe(struct platform_device *pdev)
{
void __iomem *mem;
@@ -80,6 +324,17 @@ static int ath_ahb_probe(struct platform
int ret = 0;
struct ath_hw *ah;
char hw_name[64];
+ u16 dev_id;
+
+ if (id)
+ dev_id = id->driver_data;
+
+#ifdef CONFIG_OF
+ if (pdev->dev.of_node)
+ pdev->dev.platform_data = devm_kzalloc(&pdev->dev,
+ sizeof(struct ath9k_platform_data),
+ GFP_KERNEL);
+#endif
if (!dev_get_platdata(&pdev->dev)) {
dev_err(&pdev->dev, "no platform data specified\n");
@@ -122,13 +377,16 @@ static int ath_ahb_probe(struct platform
sc->mem = mem;
sc->irq = irq;
+#ifdef CONFIG_OF
+ dev_id = of_ath_ahb_probe(pdev);
+#endif
ret = request_irq(irq, ath_isr, IRQF_SHARED, "ath9k", sc);
if (ret) {
dev_err(&pdev->dev, "request_irq failed\n");
goto err_free_hw;
}
- ret = ath9k_init_device(id->driver_data, sc, &ath_ahb_bus_ops);
+ ret = ath9k_init_device(dev_id, sc, &ath_ahb_bus_ops);
if (ret) {
dev_err(&pdev->dev, "failed to initialize device\n");
goto err_irq;
@@ -159,6 +417,9 @@ static int ath_ahb_remove(struct platfor
free_irq(sc->irq, sc);
ieee80211_free_hw(sc->hw);
}
+#ifdef CONFIG_OF
+ pdev->dev.platform_data = NULL;
+#endif
return 0;
}
@@ -168,6 +429,9 @@ static struct platform_driver ath_ahb_dr
.remove = ath_ahb_remove,
.driver = {
.name = "ath9k",
+#ifdef CONFIG_OF
+ .of_match_table = of_ath_ahb_match,
+#endif
},
.id_table = ath9k_platform_id_table,
};
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -25,6 +25,7 @@
#include <linux/time.h>
#include <linux/hw_random.h>
#include <linux/gpio/driver.h>
+#include <linux/reset.h>
#include "common.h"
#include "debug.h"
@@ -1023,6 +1024,9 @@ struct ath_softc {
struct ath_hw *sc_ah;
void __iomem *mem;
int irq;
+#ifdef CONFIG_OF
+ struct reset_control *reset;
+#endif
spinlock_t sc_serial_rw;
spinlock_t sc_pm_lock;
spinlock_t sc_pcu_lock;

View File

@@ -0,0 +1,88 @@
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Date: Fri, 2 Nov 2018 21:49:56 +0100
Subject: [PATCH] ath9k: dynack: move debug log after buffer increments
Move debug log in ath_dynack_sample_tx_ts and ath_dynack_sample_ack_ts
after timestamp buffer head/tail increments in order to make debugging
more user friendly
Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -178,11 +178,12 @@ void ath_dynack_sample_tx_ts(struct ath_
struct ath_tx_status *ts,
struct ieee80211_sta *sta)
{
- u8 ridx;
struct ieee80211_hdr *hdr;
struct ath_dynack *da = &ah->dynack;
struct ath_common *common = ath9k_hw_common(ah);
struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ u32 dur = ts->duration;
+ u8 ridx;
if (!da->enabled || (info->flags & IEEE80211_TX_CTL_NO_ACK))
return;
@@ -217,14 +218,13 @@ void ath_dynack_sample_tx_ts(struct ath_
ridx = ts->ts_rateindex;
da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp;
- da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration;
ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1);
ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2);
if (!(info->status.rates[ridx].flags & IEEE80211_TX_RC_MCS)) {
- u32 phy, sifs;
const struct ieee80211_rate *rate;
struct ieee80211_tx_rate *rates = info->status.rates;
+ u32 phy;
rate = &common->sbands[info->band].bitrates[rates[ridx].idx];
if (info->band == NL80211_BAND_2GHZ &&
@@ -233,19 +233,18 @@ void ath_dynack_sample_tx_ts(struct ath_
else
phy = WLAN_RC_PHY_OFDM;
- sifs = ath_dynack_get_sifs(ah, phy);
- da->st_rbf.ts[da->st_rbf.t_rb].dur -= sifs;
+ dur -= ath_dynack_get_sifs(ah, phy);
}
-
- ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n",
- hdr->addr1, da->st_rbf.ts[da->st_rbf.t_rb].tstamp,
- da->st_rbf.ts[da->st_rbf.t_rb].dur, da->st_rbf.h_rb,
- (da->st_rbf.t_rb + 1) % ATH_DYN_BUF);
+ da->st_rbf.ts[da->st_rbf.t_rb].dur = dur;
INCR(da->st_rbf.t_rb, ATH_DYN_BUF);
if (da->st_rbf.t_rb == da->st_rbf.h_rb)
INCR(da->st_rbf.h_rb, ATH_DYN_BUF);
+ ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n",
+ hdr->addr1, ts->ts_tstamp, dur, da->st_rbf.h_rb,
+ da->st_rbf.t_rb);
+
ath_dynack_compute_to(ah);
spin_unlock_bh(&da->qlock);
@@ -272,14 +271,13 @@ void ath_dynack_sample_ack_ts(struct ath
spin_lock_bh(&da->qlock);
da->ack_rbf.tstamp[da->ack_rbf.t_rb] = ts;
- ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n",
- da->ack_rbf.tstamp[da->ack_rbf.t_rb],
- da->ack_rbf.h_rb, (da->ack_rbf.t_rb + 1) % ATH_DYN_BUF);
-
INCR(da->ack_rbf.t_rb, ATH_DYN_BUF);
if (da->ack_rbf.t_rb == da->ack_rbf.h_rb)
INCR(da->ack_rbf.h_rb, ATH_DYN_BUF);
+ ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n",
+ ts, da->ack_rbf.h_rb, da->ack_rbf.t_rb);
+
ath_dynack_compute_to(ah);
spin_unlock_bh(&da->qlock);

View File

@@ -0,0 +1,22 @@
From: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
Date: Fri, 2 Nov 2018 21:49:59 +0100
Subject: [PATCH] ath9k: dynack: remove 'experimental' tag
Remove experimental tag from dynack Kconfig entry since it has
been tested on outdoor 25Km links
Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@redhat.com>
---
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -132,7 +132,7 @@ config ATH9K_DFS_CERTIFIED
except increase code size.
config ATH9K_DYNACK
- bool "Atheros ath9k ACK timeout estimation algorithm (EXPERIMENTAL)"
+ bool "Atheros ath9k ACK timeout estimation algorithm"
depends on ATH9K
default n
---help---

View File

@@ -0,0 +1,89 @@
From 4420866ef1b602682b009e0186fbb8aefd2125be Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 20 Aug 2019 18:20:19 +0200
Subject: [PATCH 1/4] ath9k: dynack: introduce ath_dynack_set_timeout routine
Introduce ath_dynack_set_timeout routine to configure slottime/ack/cts
timeouts and remove duplicated code
Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/ath/ath9k/dynack.c | 37 ++++++++++++++-----------
1 file changed, 21 insertions(+), 16 deletions(-)
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -79,6 +79,24 @@ static inline bool ath_dynack_bssidmask(
}
/**
+ * ath_dynack_set_timeout - configure timeouts/slottime registers
+ * @ah: ath hw
+ * @to: timeout value
+ *
+ */
+static void ath_dynack_set_timeout(struct ath_hw *ah, int to)
+{
+ struct ath_common *common = ath9k_hw_common(ah);
+ int slottime = (to - 3) / 2;
+
+ ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n",
+ to, slottime);
+ ath9k_hw_setslottime(ah, slottime);
+ ath9k_hw_set_ack_timeout(ah, to);
+ ath9k_hw_set_cts_timeout(ah, to);
+}
+
+/**
* ath_dynack_compute_ackto - compute ACK timeout as the maximum STA timeout
* @ah: ath hw
*
@@ -86,7 +104,6 @@ static inline bool ath_dynack_bssidmask(
*/
static void ath_dynack_compute_ackto(struct ath_hw *ah)
{
- struct ath_common *common = ath9k_hw_common(ah);
struct ath_dynack *da = &ah->dynack;
struct ath_node *an;
int to = 0;
@@ -96,15 +113,8 @@ static void ath_dynack_compute_ackto(str
to = an->ackto;
if (to && da->ackto != to) {
- u32 slottime;
-
- slottime = (to - 3) / 2;
+ ath_dynack_set_timeout(ah, to);
da->ackto = to;
- ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n",
- da->ackto, slottime);
- ath9k_hw_setslottime(ah, slottime);
- ath9k_hw_set_ack_timeout(ah, da->ackto);
- ath9k_hw_set_cts_timeout(ah, da->ackto);
}
}
@@ -198,10 +208,7 @@ void ath_dynack_sample_tx_ts(struct ath_
ieee80211_is_assoc_resp(hdr->frame_control) ||
ieee80211_is_auth(hdr->frame_control)) {
ath_dbg(common, DYNACK, "late ack\n");
-
- ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2);
- ath9k_hw_set_ack_timeout(ah, LATEACK_TO);
- ath9k_hw_set_cts_timeout(ah, LATEACK_TO);
+ ath_dynack_set_timeout(ah, LATEACK_TO);
if (sta) {
struct ath_node *an;
@@ -340,9 +347,7 @@ void ath_dynack_reset(struct ath_hw *ah)
da->ack_rbf.h_rb = 0;
/* init acktimeout */
- ath9k_hw_setslottime(ah, (ackto - 3) / 2);
- ath9k_hw_set_ack_timeout(ah, ackto);
- ath9k_hw_set_cts_timeout(ah, ackto);
+ ath_dynack_set_timeout(ah, ackto);
}
EXPORT_SYMBOL(ath_dynack_reset);

View File

@@ -0,0 +1,27 @@
From e5b56ce50eab31d24df6a70cf025db3acc4aa3ac Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 20 Aug 2019 18:20:20 +0200
Subject: [PATCH 2/4] ath9k: dynack: properly set last timeout timestamp in
ath_dynack_reset
Add compute timeout to last computation timestamp in
ath_dynack_reset in order to not run ath_dynack_compute_ackto
immediately
Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/ath/ath9k/dynack.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -338,7 +338,7 @@ void ath_dynack_reset(struct ath_hw *ah)
u32 ackto = 9 + 16 + 64;
struct ath_dynack *da = &ah->dynack;
- da->lto = jiffies;
+ da->lto = jiffies + COMPUTE_TO;
da->ackto = ackto;
da->st_rbf.t_rb = 0;

View File

@@ -0,0 +1,92 @@
From 3f737abb7d53cc80d619a3b4a30b6fa63cdc8df7 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 20 Aug 2019 18:20:21 +0200
Subject: [PATCH 3/4] ath9k: dynack: set max timeout according to channel width
Compute maximum configurable ackimeout/ctstimeout according to channel
width (clockrate)
Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/ath/ath9k/dynack.c | 38 +++++++++++++++++++------
1 file changed, 30 insertions(+), 8 deletions(-)
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -20,12 +20,31 @@
#define COMPUTE_TO (5 * HZ)
#define LATEACK_DELAY (10 * HZ)
-#define LATEACK_TO 256
-#define MAX_DELAY 300
#define EWMA_LEVEL 96
#define EWMA_DIV 128
/**
+ * ath_dynack_get_max_to - set max timeout according to channel width
+ * @ah: ath hw
+ *
+ */
+static u32 ath_dynack_get_max_to(struct ath_hw *ah)
+{
+ const struct ath9k_channel *chan = ah->curchan;
+
+ if (!chan)
+ return 300;
+
+ if (IS_CHAN_HT40(chan))
+ return 300;
+ if (IS_CHAN_HALF_RATE(chan))
+ return 750;
+ if (IS_CHAN_QUARTER_RATE(chan))
+ return 1500;
+ return 600;
+}
+
+/**
* ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation
*
*/
@@ -126,15 +145,16 @@ static void ath_dynack_compute_ackto(str
*/
static void ath_dynack_compute_to(struct ath_hw *ah)
{
- u32 ackto, ack_ts;
- u8 *dst, *src;
+ struct ath_dynack *da = &ah->dynack;
+ u32 ackto, ack_ts, max_to;
struct ieee80211_sta *sta;
- struct ath_node *an;
struct ts_info *st_ts;
- struct ath_dynack *da = &ah->dynack;
+ struct ath_node *an;
+ u8 *dst, *src;
rcu_read_lock();
+ max_to = ath_dynack_get_max_to(ah);
while (da->st_rbf.h_rb != da->st_rbf.t_rb &&
da->ack_rbf.h_rb != da->ack_rbf.t_rb) {
ack_ts = da->ack_rbf.tstamp[da->ack_rbf.h_rb];
@@ -150,7 +170,7 @@ static void ath_dynack_compute_to(struct
if (ack_ts > st_ts->tstamp + st_ts->dur) {
ackto = ack_ts - st_ts->tstamp - st_ts->dur;
- if (ackto < MAX_DELAY) {
+ if (ackto < max_to) {
sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst,
src);
if (sta) {
@@ -207,8 +227,10 @@ void ath_dynack_sample_tx_ts(struct ath_
if (ieee80211_is_assoc_req(hdr->frame_control) ||
ieee80211_is_assoc_resp(hdr->frame_control) ||
ieee80211_is_auth(hdr->frame_control)) {
+ u32 max_to = ath_dynack_get_max_to(ah);
+
ath_dbg(common, DYNACK, "late ack\n");
- ath_dynack_set_timeout(ah, LATEACK_TO);
+ ath_dynack_set_timeout(ah, max_to);
if (sta) {
struct ath_node *an;

View File

@@ -0,0 +1,73 @@
From cc783bfa67e87d2e6206f7626b7bbb74d5c5f269 Mon Sep 17 00:00:00 2001
From: Lorenzo Bianconi <lorenzo@kernel.org>
Date: Tue, 20 Aug 2019 18:20:22 +0200
Subject: [PATCH 4/4] ath9k: dynack: set ackto to max timeout in
ath_dynack_reset
Initialize acktimeout to the maximum configurable value in
ath_dynack_reset in order to not disconnect long distance static links
enabling dynack and even to take care of possible errors configuring
a static timeout. Moreover initialize station timeout value to the current
acktimeout value
Tested-by: Koen Vandeputte <koen.vandeputte@ncentric.com>
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
---
drivers/net/wireless/ath/ath9k/dynack.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
--- a/drivers/net/wireless/ath/ath9k/dynack.c
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -321,11 +321,9 @@ EXPORT_SYMBOL(ath_dynack_sample_ack_ts);
*/
void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an)
{
- /* ackto = slottime + sifs + air delay */
- u32 ackto = 9 + 16 + 64;
struct ath_dynack *da = &ah->dynack;
- an->ackto = ackto;
+ an->ackto = da->ackto;
spin_lock_bh(&da->qlock);
list_add_tail(&an->list, &da->nodes);
@@ -356,20 +354,26 @@ EXPORT_SYMBOL(ath_dynack_node_deinit);
*/
void ath_dynack_reset(struct ath_hw *ah)
{
- /* ackto = slottime + sifs + air delay */
- u32 ackto = 9 + 16 + 64;
struct ath_dynack *da = &ah->dynack;
+ struct ath_node *an;
+
+ spin_lock_bh(&da->qlock);
da->lto = jiffies + COMPUTE_TO;
- da->ackto = ackto;
da->st_rbf.t_rb = 0;
da->st_rbf.h_rb = 0;
da->ack_rbf.t_rb = 0;
da->ack_rbf.h_rb = 0;
+ da->ackto = ath_dynack_get_max_to(ah);
+ list_for_each_entry(an, &da->nodes, list)
+ an->ackto = da->ackto;
+
/* init acktimeout */
- ath_dynack_set_timeout(ah, ackto);
+ ath_dynack_set_timeout(ah, da->ackto);
+
+ spin_unlock_bh(&da->qlock);
}
EXPORT_SYMBOL(ath_dynack_reset);
@@ -386,6 +390,8 @@ void ath_dynack_init(struct ath_hw *ah)
spin_lock_init(&da->qlock);
INIT_LIST_HEAD(&da->nodes);
+ /* ackto = slottime + sifs + air delay */
+ da->ackto = 9 + 16 + 64;
ah->hw->wiphy->features |= NL80211_FEATURE_ACKTO_ESTIMATION;
}

View File

@@ -0,0 +1,33 @@
From: Sven Eckelmann <sven@open-mesh.com>
Date: Tue, 18 Nov 2014 12:29:28 +0100
Subject: [PATCH] ath10k: Don't initialize devices asynchronously
OpenWrt requires all PHYs to be initialized to create the configuration files
during bootup. ath10k violates this because it delays the creation of the PHY
to a not well defined point in the future.
Forcing the work to be done immediately works around this problem but may also
delay the boot when firmware images cannot be found.
Signed-off-by: Sven Eckelmann <sven@open-mesh.com>
---
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -2735,6 +2735,16 @@ int ath10k_core_register(struct ath10k *
ar->chip_id = chip_id;
queue_work(ar->workqueue, &ar->register_work);
+ /* OpenWrt requires all PHYs to be initialized to create the
+ * configuration files during bootup. ath10k violates this
+ * because it delays the creation of the PHY to a not well defined
+ * point in the future.
+ *
+ * Forcing the work to be done immediately works around this problem
+ * but may also delay the boot when firmware images cannot be found.
+ */
+ flush_workqueue(ar->workqueue);
+
return 0;
}
EXPORT_SYMBOL(ath10k_core_register);

View File

@@ -0,0 +1,37 @@
From: Linus Lüssing <ll@simonwunderlich.de>
Date: Wed, 5 Feb 2020 20:10:43 +0100
Subject: ath10k: increase rx buffer size to 2048
Before, only frames with a maximum size of 1528 bytes could be
transmitted between two 802.11s nodes.
For batman-adv for instance, which adds its own header to each frame,
we typically need an MTU of at least 1532 bytes to be able to transmit
without fragmentation.
This patch now increases the maxmimum frame size from 1528 to 1656
bytes.
Tested with two ath10k devices in 802.11s mode, as well as with
batman-adv on top of 802.11s with forwarding disabled.
Fix originally found and developed by Ben Greear.
Link: https://github.com/greearb/ath10k-ct/issues/89
Link: https://github.com/greearb/ath10k-ct/commit/9e5ab25027e0971fa24ccf93373324c08c4e992d
Cc: Ben Greear <greearb@candelatech.com>
Signed-off-by: Linus Lüssing <ll@simonwunderlich.de>
Forwarded: https://patchwork.kernel.org/patch/11367055/
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -2004,7 +2004,7 @@ struct htt_rx_desc {
* Should be: sizeof(struct htt_host_rx_desc) + max rx MSDU size,
* rounded up to a cache line size.
*/
-#define HTT_RX_BUF_SIZE 1920
+#define HTT_RX_BUF_SIZE 2048
#define HTT_RX_MSDU_SIZE (HTT_RX_BUF_SIZE - (int)sizeof(struct htt_rx_desc))
/* Refill a bunch of RX buffers for each refill round so that FW/HW can handle

View File

@@ -0,0 +1,37 @@
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -8300,6 +8300,21 @@ static int ath10k_mac_init_rd(struct ath
return 0;
}
+#ifdef CPTCFG_MAC80211_LEDS
+static const struct ieee80211_tpt_blink ath10k_tpt_blink[] = {
+ { .throughput = 0 * 1024, .blink_time = 334 },
+ { .throughput = 1 * 1024, .blink_time = 260 },
+ { .throughput = 2 * 1024, .blink_time = 220 },
+ { .throughput = 5 * 1024, .blink_time = 190 },
+ { .throughput = 10 * 1024, .blink_time = 170 },
+ { .throughput = 25 * 1024, .blink_time = 150 },
+ { .throughput = 54 * 1024, .blink_time = 130 },
+ { .throughput = 120 * 1024, .blink_time = 110 },
+ { .throughput = 265 * 1024, .blink_time = 80 },
+ { .throughput = 586 * 1024, .blink_time = 50 },
+};
+#endif
+
int ath10k_mac_register(struct ath10k *ar)
{
static const u32 cipher_suites[] = {
@@ -8584,6 +8599,12 @@ int ath10k_mac_register(struct ath10k *a
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
+#ifdef CPTCFG_MAC80211_LEDS
+ ieee80211_create_tpt_led_trigger(ar->hw,
+ IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
+ ARRAY_SIZE(ath10k_tpt_blink));
+#endif
+
ret = ieee80211_register_hw(ar->hw);
if (ret) {
ath10k_err(ar, "failed to register ieee80211: %d\n", ret);

View File

@@ -0,0 +1,11 @@
--- a/drivers/net/wireless/ath/ath10k/htt.h
+++ b/drivers/net/wireless/ath/ath10k/htt.h
@@ -238,7 +238,7 @@ enum htt_rx_ring_flags {
};
#define HTT_RX_RING_SIZE_MIN 128
-#define HTT_RX_RING_SIZE_MAX 2048
+#define HTT_RX_RING_SIZE_MAX 512
#define HTT_RX_RING_SIZE HTT_RX_RING_SIZE_MAX
#define HTT_RX_RING_FILL_LEVEL (((HTT_RX_RING_SIZE) / 2) - 1)
#define HTT_RX_RING_FILL_LEVEL_DUAL_MAC (HTT_RX_RING_SIZE - 1)

View File

@@ -0,0 +1,38 @@
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -142,7 +142,7 @@ static struct ce_attr host_ce_config_wla
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
- .dest_nentries = 512,
+ .dest_nentries = 128,
.recv_cb = ath10k_pci_htt_htc_rx_cb,
},
@@ -151,7 +151,7 @@ static struct ce_attr host_ce_config_wla
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
- .dest_nentries = 128,
+ .dest_nentries = 64,
.recv_cb = ath10k_pci_htc_rx_cb,
},
@@ -178,7 +178,7 @@ static struct ce_attr host_ce_config_wla
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 512,
- .dest_nentries = 512,
+ .dest_nentries = 128,
.recv_cb = ath10k_pci_htt_rx_cb,
},
@@ -203,7 +203,7 @@ static struct ce_attr host_ce_config_wla
.flags = CE_ATTR_FLAGS,
.src_nentries = 0,
.src_sz_max = 2048,
- .dest_nentries = 128,
+ .dest_nentries = 96,
.recv_cb = ath10k_pci_pktlog_rx_cb,
},

View File

@@ -0,0 +1,144 @@
From: Sebastian Gottschall <s.gottschall@dd-wrt.com>
current handling of peer_bw_rxnss_override parameter is based on guessing the VHT160/8080 capability by rx rate. this is wrong and may lead
to a non initialized peer_bw_rxnss_override parameter which is required since VHT160 operation mode only supports 2x2 chainmasks in addition the original code
initialized the parameter with wrong masked values.
This patch uses the peer phymode and peer nss information for correct initialisation of the peer_bw_rxnss_override parameter.
if this peer information is not available, we initialize the parameter by minimum nss which is suggested by QCA as temporary workaround according
to the QCA sourcecodes.
Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
v2: remove debug messages
v3: apply some cosmetics, update documentation
v4: fix compile warning and truncate nss to maximum of 2x2 since current chipsets only support 2x2 at vht160
v5: handle maximum nss for chipsets supportig vht160 with 1x1 only
v7: use more simple code variant and take care about hw/sw chainmask configuration
v8: fix some code style issues
v9: use SM/MS macros from code.h to simplify shift/mask handling
---
drivers/net/wireless/ath/ath10k/mac.c | 54 +++++++++++++++++++--------
drivers/net/wireless/ath/ath10k/wmi.c | 7 +---
drivers/net/wireless/ath/ath10k/wmi.h | 14 ++++++-
3 files changed, 52 insertions(+), 23 deletions(-)
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -2474,7 +2474,7 @@ static void ath10k_peer_assoc_h_vht(stru
const u16 *vht_mcs_mask;
u8 ampdu_factor;
u8 max_nss, vht_mcs;
- int i;
+ int i, nss160;
if (WARN_ON(ath10k_mac_vif_chan(vif, &def)))
return;
@@ -2534,23 +2534,45 @@ static void ath10k_peer_assoc_h_vht(stru
__le16_to_cpu(vht_cap->vht_mcs.tx_highest);
arg->peer_vht_rates.tx_mcs_set = ath10k_peer_assoc_h_vht_limit(
__le16_to_cpu(vht_cap->vht_mcs.tx_mcs_map), vht_mcs_mask);
+ arg->peer_bw_rxnss_override = 0;
+ nss160 = 1; /* 1x1 default config for VHT160 */
- ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x\n",
- sta->addr, arg->peer_max_mpdu, arg->peer_flags);
+ /* only local 4x4 configuration do support 2x2 for VHT160,
+ * everything else must use 1x1
+ */
- if (arg->peer_vht_rates.rx_max_rate &&
- (sta->vht_cap.cap & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK)) {
- switch (arg->peer_vht_rates.rx_max_rate) {
- case 1560:
- /* Must be 2x2 at 160Mhz is all it can do. */
- arg->peer_bw_rxnss_override = 2;
- break;
- case 780:
- /* Can only do 1x1 at 160Mhz (Long Guard Interval) */
- arg->peer_bw_rxnss_override = 1;
- break;
- }
+ if (ar->cfg_rx_chainmask == 15)
+ nss160 = arg->peer_num_spatial_streams <= 2 ? 1 : 2;
+
+ /* if peer provides 1x1 nss160 information using max rate
+ * vht information, we reduce local nss160 to 1x1.
+ * consider that it has been observed that some client
+ * devices provide zero here, no matter which transmission
+ * rate is possible. in that case the local nss configuration
+ * will be used at maxmimum configuration possible. (see above)
+ */
+
+ if (arg->peer_vht_rates.rx_max_rate == 780)
+ nss160 = 1;
+
+ /* in case if peer is connected with vht160 or vht80+80,
+ * we need to properly adjust rxnss parameters otherwise
+ * firmware will raise a assert
+ */
+ switch (arg->peer_phymode) {
+ case MODE_11AC_VHT80_80:
+ arg->peer_bw_rxnss_override = BW_NSS_FWCONF_80_80(nss160);
+ /* fall through */
+ case MODE_11AC_VHT160:
+ arg->peer_bw_rxnss_override |= BW_NSS_FWCONF_160(nss160);
+ break;
+ default:
+ break;
}
+
+ ath10k_dbg(ar, ATH10K_DBG_MAC, "mac vht peer %pM max_mpdu %d flags 0x%x peer_bw_rxnss_override 0x%x\n",
+ sta->addr, arg->peer_max_mpdu, arg->peer_flags,
+ arg->peer_bw_rxnss_override);
}
static void ath10k_peer_assoc_h_qos(struct ath10k *ar,
@@ -2702,9 +2724,9 @@ static int ath10k_peer_assoc_prepare(str
ath10k_peer_assoc_h_crypto(ar, vif, sta, arg);
ath10k_peer_assoc_h_rates(ar, vif, sta, arg);
ath10k_peer_assoc_h_ht(ar, vif, sta, arg);
+ ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
ath10k_peer_assoc_h_vht(ar, vif, sta, arg);
ath10k_peer_assoc_h_qos(ar, vif, sta, arg);
- ath10k_peer_assoc_h_phymode(ar, vif, sta, arg);
return 0;
}
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -7391,12 +7391,7 @@ ath10k_wmi_peer_assoc_fill_10_4(struct a
struct wmi_10_4_peer_assoc_complete_cmd *cmd = buf;
ath10k_wmi_peer_assoc_fill_10_2(ar, buf, arg);
- if (arg->peer_bw_rxnss_override)
- cmd->peer_bw_rxnss_override =
- __cpu_to_le32((arg->peer_bw_rxnss_override - 1) |
- BIT(PEER_BW_RXNSS_OVERRIDE_OFFSET));
- else
- cmd->peer_bw_rxnss_override = 0;
+ cmd->peer_bw_rxnss_override = __cpu_to_le32(arg->peer_bw_rxnss_override);
}
static int
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -6357,7 +6357,19 @@ struct wmi_10_2_peer_assoc_complete_cmd
__le32 info0; /* WMI_PEER_ASSOC_INFO0_ */
} __packed;
-#define PEER_BW_RXNSS_OVERRIDE_OFFSET 31
+#define BW_NSS_FWCONF_MAP_ENABLE BIT(31)
+#define BW_NSS_FWCONF_MAP_160MHZ_LSB (0)
+#define BW_NSS_FWCONF_MAP_160MHZ_MASK (0x00000007)
+#define BW_NSS_FWCONF_MAP_80_80MHZ_LSB (3)
+#define BW_NSS_FWCONF_MAP_80_80MHZ_MASK (0x00000038)
+#define BW_NSS_FWCONF_MAP_MASK (0x0000003F)
+
+#define GET_BW_NSS_FWCONF_160(x) (MS(x, BW_NSS_FWCONF_MAP_160MHZ) + 1)
+#define GET_BW_NSS_FWCONF_80_80(x) (MS(x, BW_NSS_FWCONF_MAP_80_80MHZ) + 1)
+
+/* Values defined to set 160 MHz Bandwidth NSS Mapping into FW*/
+#define BW_NSS_FWCONF_160(x) (BW_NSS_FWCONF_MAP_ENABLE | SM(x - 1, BW_NSS_FWCONF_MAP_160MHZ))
+#define BW_NSS_FWCONF_80_80(x) (BW_NSS_FWCONF_MAP_ENABLE | SM(x - 1, BW_NSS_FWCONF_MAP_80_80MHZ))
struct wmi_10_4_peer_assoc_complete_cmd {
struct wmi_10_2_peer_assoc_complete_cmd cmd;

View File

@@ -0,0 +1,53 @@
From: Sebastian Gottschall <s.gottschall@dd-wrt.com>
starting with firmware 10.4.3.4.x series QCA changed the handling of the channel property band_center_freq1 and band_center_freq2 in vht160 operation mode
likelly for backward compatiblity with vht80 only capable clients.
this patch adjusts the handling to get vht160 to work again with official qca firmwares newer than 3.3
consider that this patch will not work with older firmwares anymore. to avoid undefined behaviour this we disable vht160 capability for outdated firmwares
Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
v2: fix trailing whitespace issue and fix some typos within the commit note
---
drivers/net/wireless/ath/ath10k/mac.c | 7 -------
drivers/net/wireless/ath/ath10k/wmi.c | 11 ++++++++---
2 files changed, 8 insertions(+), 10 deletions(-)
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4483,13 +4483,6 @@ static struct ieee80211_sta_vht_cap ath1
vht_cap.cap |= val;
}
- /* Currently the firmware seems to be buggy, don't enable 80+80
- * mode until that's resolved.
- */
- if ((ar->vht_cap_info & IEEE80211_VHT_CAP_SHORT_GI_160) &&
- (ar->vht_cap_info & IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_MASK) == 0)
- vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
-
mcs_map = 0;
for (i = 0; i < 8; i++) {
if ((i < ar->num_rf_chains) && (ar->cfg_tx_chainmask & BIT(i)))
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -1677,13 +1677,18 @@ void ath10k_wmi_put_wmi_channel(struct w
flags |= WMI_CHAN_FLAG_HT40_PLUS;
if (arg->chan_radar)
flags |= WMI_CHAN_FLAG_DFS;
-
+ ch->band_center_freq2 = 0;
ch->mhz = __cpu_to_le32(arg->freq);
ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1);
if (arg->mode == MODE_11AC_VHT80_80)
ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq2);
- else
- ch->band_center_freq2 = 0;
+ if (arg->mode == MODE_11AC_VHT160) {
+ if (arg->freq < arg->band_center_freq1)
+ ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1 - 40);
+ else
+ ch->band_center_freq1 = __cpu_to_le32(arg->band_center_freq1 + 40);
+ ch->band_center_freq2 = __cpu_to_le32(arg->band_center_freq1);
+ }
ch->min_power = arg->min_power;
ch->max_power = arg->max_power;
ch->reg_power = arg->max_reg_power;

View File

@@ -0,0 +1,617 @@
From: Sebastian Gottschall <s.gottschall@newmedia-net.de>
Adds LED and GPIO Control support for 988x, 9887, 9888, 99x0, 9984 based
chipsets with on chipset connected led's using WMI Firmware API. The LED
device will get available named as "ath10k-phyX" at sysfs and can be controlled
with various triggers. adds also debugfs interface for gpio control.
This patch is specific for OpenWRt base, as is use old backported package
with old wireless source. Support for QCA9984 is removed and a simbol
is added to local-simbol file to export the actually compile the code
with the ATH10K_LEDS simbol.
Signed-off-by: Sebastian Gottschall <s.gottschall@dd-wrt.com>
Reviewed-by: Steve deRosier <derosier@cal-sierra.com>
[kvalo: major reorg and cleanup]
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Signed-off-by: Ansuel Smith <ansuelsmth@gmail.com>
---
v13:
* only compile tested!
* fix all checkpatch warnings
* fix commit log
* sizeof(struct ath10k_gpiocontrol) -> sizeof(*gpio)
* unsigned -> unsigned int
* remove GPIOLIB code, that should be added in a separate patch
* rename gpio.c to leds.c
* add leds.h
* rename some functions:
ath10k_attach_led() -> ath10k_leds_register()
ath10k_unregister_led() -> ath10k_leds_unregister()
ath10k_reset_led_pin() -> ath10k_leds_start()
* call ath10k_leds_unregister() before ath10k_thermal_unregister() to preserve ordering
* call ath10k_leds_start() only from ath10k_core_start() and not from mac.c
* rename struct ath10k_gpiocontrol as anonymous function under struct
ath10k::leds, no need for memory allocation
* merge ath10k_add_led() to ath10k_attach_led(), which is it's only caller
* remove #if IS_ENABLED() checks from most of places, memory savings from those were not worth it
* Kconfig help text improvement and move it lower in the menu, also don't enable it by default
* switch to set_brightness_blocking() so that the callback can sleep,
then no need to use ath10k_wmi_cmd_send_nowait() and can take mutex
to access ar->state
* don't touch ath10k_wmi_pdev_get_temperature()
* as QCA6174/QCA9377 are not (yet) supported don't add the command to WMI-TLV interface
* remove debugfs interface, that should be added in another patch
* cleanup includes
drivers/net/wireless/ath/ath10k/Kconfig | 10 +++
drivers/net/wireless/ath/ath10k/Makefile | 1 +
drivers/net/wireless/ath/ath10k/core.c | 22 +++++++
drivers/net/wireless/ath/ath10k/core.h | 9 ++-
drivers/net/wireless/ath/ath10k/hw.h | 1 +
drivers/net/wireless/ath/ath10k/leds.c | 103 ++++++++++++++++++++++++++++++
drivers/net/wireless/ath/ath10k/leds.h | 45 +++++++++++++
drivers/net/wireless/ath/ath10k/mac.c | 1 +
drivers/net/wireless/ath/ath10k/wmi-ops.h | 32 ++++++++++
drivers/net/wireless/ath/ath10k/wmi-tlv.c | 2 +
drivers/net/wireless/ath/ath10k/wmi.c | 54 ++++++++++++++++
drivers/net/wireless/ath/ath10k/wmi.h | 35 ++++++++++
12 files changed, 314 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/wireless/ath/ath10k/leds.c
create mode 100644 drivers/net/wireless/ath/ath10k/leds.h
--- a/drivers/net/wireless/ath/ath10k/Kconfig
+++ b/drivers/net/wireless/ath/ath10k/Kconfig
@@ -69,6 +69,16 @@ config ATH10K_DEBUGFS
If unsure, say Y to make it easier to debug problems.
+config ATH10K_LEDS
+ bool "Atheros ath10k LED support"
+ depends on ATH10K
+ select MAC80211_LEDS
+ select LEDS_CLASS
+ select NEW_LEDS
+ default y
+ ---help---
+ This option is necessary, if you want LED support for chipset connected led pins. If unsure, say N.
+
config ATH10K_SPECTRAL
bool "Atheros ath10k spectral scan support"
depends on ATH10K_DEBUGFS
--- a/drivers/net/wireless/ath/ath10k/Makefile
+++ b/drivers/net/wireless/ath/ath10k/Makefile
@@ -19,6 +19,7 @@ ath10k_core-$(CPTCFG_ATH10K_SPECTRAL) +=
ath10k_core-$(CPTCFG_NL80211_TESTMODE) += testmode.o
ath10k_core-$(CPTCFG_ATH10K_TRACING) += trace.o
ath10k_core-$(CPTCFG_ATH10K_THERMAL) += thermal.o
+ath10k_core-$(CPTCFG_ATH10K_LEDS) += leds.o
ath10k_core-$(CPTCFG_MAC80211_DEBUGFS) += debugfs_sta.o
ath10k_core-$(CONFIG_PM) += wow.o
ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o
--- a/local-symbols
+++ b/local-symbols
@@ -142,6 +142,7 @@ ATH10K_DEBUG=
ATH10K_DEBUGFS=
ATH10K_SPECTRAL=
ATH10K_THERMAL=
+ATH10K_LEDS=
ATH10K_TRACING=
ATH10K_DFS_CERTIFIED=
WCN36XX=
--- a/drivers/net/wireless/ath/ath10k/core.c
+++ b/drivers/net/wireless/ath/ath10k/core.c
@@ -34,6 +34,7 @@
#include "testmode.h"
#include "wmi-ops.h"
#include "coredump.h"
+#include "leds.h"
unsigned int ath10k_debug_mask;
static unsigned int ath10k_cryptmode_param;
@@ -64,6 +65,7 @@ static const struct ath10k_hw_params ath
.id = QCA988X_HW_2_0_VERSION,
.dev_id = QCA988X_2_0_DEVICE_ID,
.name = "qca988x hw2.0",
+ .led_pin = 1,
.patch_load_addr = QCA988X_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
@@ -131,6 +133,7 @@ static const struct ath10k_hw_params ath
.id = QCA9887_HW_1_0_VERSION,
.dev_id = QCA9887_1_0_DEVICE_ID,
.name = "qca9887 hw1.0",
+ .led_pin = 1,
.patch_load_addr = QCA9887_HW_1_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_ALL,
@@ -300,6 +303,7 @@ static const struct ath10k_hw_params ath
.id = QCA99X0_HW_2_0_DEV_VERSION,
.dev_id = QCA99X0_2_0_DEVICE_ID,
.name = "qca99x0 hw2.0",
+ .led_pin = 17,
.patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.otp_exe_param = 0x00000700,
@@ -339,6 +343,7 @@ static const struct ath10k_hw_params ath
.id = QCA9984_HW_1_0_DEV_VERSION,
.dev_id = QCA9984_1_0_DEVICE_ID,
.name = "qca9984/qca9994 hw1.0",
+ .led_pin = 17,
.patch_load_addr = QCA9984_HW_1_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
@@ -383,6 +388,7 @@ static const struct ath10k_hw_params ath
.id = QCA9888_HW_2_0_DEV_VERSION,
.dev_id = QCA9888_2_0_DEVICE_ID,
.name = "qca9888 hw2.0",
+ .led_pin = 17,
.patch_load_addr = QCA9888_HW_2_0_PATCH_LOAD_ADDR,
.uart_pin = 7,
.cc_wraparound_type = ATH10K_HW_CC_WRAP_SHIFTED_EACH,
@@ -2456,6 +2462,10 @@ int ath10k_core_start(struct ath10k *ar,
if (status)
goto err_hif_stop;
+ status = ath10k_leds_start(ar);
+ if (status)
+ goto err_hif_stop;
+
return 0;
err_hif_stop:
@@ -2710,9 +2720,18 @@ static void ath10k_core_register_work(st
goto err_spectral_destroy;
}
+ status = ath10k_leds_register(ar);
+ if (status) {
+ ath10k_err(ar, "could not register leds: %d\n",
+ status);
+ goto err_thermal_unregister;
+ }
+
set_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags);
return;
+err_thermal_unregister:
+ ath10k_thermal_unregister(ar);
err_spectral_destroy:
ath10k_spectral_destroy(ar);
err_debug_destroy:
@@ -2756,6 +2775,8 @@ void ath10k_core_unregister(struct ath10
if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags))
return;
+ ath10k_leds_unregister(ar);
+
ath10k_thermal_unregister(ar);
/* Stop spectral before unregistering from mac80211 to remove the
* relayfs debugfs file cleanly. Otherwise the parent debugfs tree
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -25,6 +25,7 @@
#include <linux/pci.h>
#include <linux/uuid.h>
#include <linux/time.h>
+#include <linux/leds.h>
#include "htt.h"
#include "htc.h"
@@ -908,7 +909,6 @@ struct ath10k {
u32 low_5ghz_chan;
u32 high_5ghz_chan;
bool ani_enabled;
-
bool p2p;
struct {
@@ -1100,6 +1100,13 @@ struct ath10k {
} testmode;
struct {
+ struct gpio_led wifi_led;
+ struct led_classdev cdev;
+ char label[48];
+ u32 gpio_state_pin;
+ } leds;
+
+ struct {
/* protected by data_lock */
u32 fw_crash_counter;
u32 fw_warm_reset_counter;
--- a/drivers/net/wireless/ath/ath10k/hw.h
+++ b/drivers/net/wireless/ath/ath10k/hw.h
@@ -504,6 +504,7 @@ struct ath10k_hw_params {
const char *name;
u32 patch_load_addr;
int uart_pin;
+ int led_pin;
u32 otp_exe_param;
/* Type of hw cycle counter wraparound logic, for more info
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/leds.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2005-2011 Atheros Communications Inc.
+ * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
+ * Copyright (c) 2018 Sebastian Gottschall <s.gottschall@dd-wrt.com>
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * 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/leds.h>
+
+#include "core.h"
+#include "wmi.h"
+#include "wmi-ops.h"
+
+#include "leds.h"
+
+static int ath10k_leds_set_brightness_blocking(struct led_classdev *led_cdev,
+ enum led_brightness brightness)
+{
+ struct ath10k *ar = container_of(led_cdev, struct ath10k,
+ leds.cdev);
+ struct gpio_led *led = &ar->leds.wifi_led;
+
+ mutex_lock(&ar->conf_mutex);
+
+ if (ar->state != ATH10K_STATE_ON)
+ goto out;
+
+ ar->leds.gpio_state_pin = (brightness != LED_OFF) ^ led->active_low;
+ ath10k_wmi_gpio_output(ar, led->gpio, ar->leds.gpio_state_pin);
+
+out:
+ mutex_unlock(&ar->conf_mutex);
+
+ return 0;
+}
+
+int ath10k_leds_start(struct ath10k *ar)
+{
+ if (ar->hw_params.led_pin == 0)
+ /* leds not supported */
+ return 0;
+
+ /* under some circumstances, the gpio pin gets reconfigured
+ * to default state by the firmware, so we need to
+ * reconfigure it this behaviour has only ben seen on
+ * QCA9984 and QCA99XX devices so far
+ */
+ ath10k_wmi_gpio_config(ar, ar->hw_params.led_pin, 0,
+ WMI_GPIO_PULL_NONE, WMI_GPIO_INTTYPE_DISABLE);
+ ath10k_wmi_gpio_output(ar, ar->hw_params.led_pin, 1);
+
+ return 0;
+}
+
+int ath10k_leds_register(struct ath10k *ar)
+{
+ int ret;
+
+ if (ar->hw_params.led_pin == 0)
+ /* leds not supported */
+ return 0;
+
+ snprintf(ar->leds.label, sizeof(ar->leds.label), "ath10k-%s",
+ wiphy_name(ar->hw->wiphy));
+ ar->leds.wifi_led.active_low = 1;
+ ar->leds.wifi_led.gpio = ar->hw_params.led_pin;
+ ar->leds.wifi_led.name = ar->leds.label;
+ ar->leds.wifi_led.default_state = LEDS_GPIO_DEFSTATE_KEEP;
+
+ ar->leds.cdev.name = ar->leds.label;
+ ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking;
+
+ /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */
+ ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger;
+
+ ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+void ath10k_leds_unregister(struct ath10k *ar)
+{
+ if (ar->hw_params.led_pin == 0)
+ /* leds not supported */
+ return;
+
+ led_classdev_unregister(&ar->leds.cdev);
+}
+
--- /dev/null
+++ b/drivers/net/wireless/ath/ath10k/leds.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2018, The Linux Foundation. All rights reserved.
+ *
+ * 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.
+ */
+#ifndef _LEDS_H_
+#define _LEDS_H_
+
+#include "core.h"
+
+#ifdef CPTCFG_ATH10K_LEDS
+void ath10k_leds_unregister(struct ath10k *ar);
+int ath10k_leds_start(struct ath10k *ar);
+int ath10k_leds_register(struct ath10k *ar);
+#else
+static inline void ath10k_leds_unregister(struct ath10k *ar)
+{
+}
+
+static inline int ath10k_leds_start(struct ath10k *ar)
+{
+ return 0;
+}
+
+static inline int ath10k_leds_register(struct ath10k *ar)
+{
+ return 0;
+}
+
+#endif
+#endif /* _LEDS_H_ */
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -34,6 +34,7 @@
#include "wmi-tlv.h"
#include "wmi-ops.h"
#include "wow.h"
+#include "leds.h"
/*********/
/* Rates */
--- a/drivers/net/wireless/ath/ath10k/wmi-ops.h
+++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h
@@ -217,7 +217,10 @@ struct wmi_ops {
struct sk_buff *(*gen_echo)(struct ath10k *ar, u32 value);
struct sk_buff *(*gen_pdev_get_tpc_table_cmdid)(struct ath10k *ar,
u32 param);
+ struct sk_buff *(*gen_gpio_config)(struct ath10k *ar, u32 gpio_num,
+ u32 input, u32 pull_type, u32 intr_mode);
+ struct sk_buff *(*gen_gpio_output)(struct ath10k *ar, u32 gpio_num, u32 set);
};
int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1064,6 +1067,35 @@ ath10k_wmi_force_fw_hang(struct ath10k *
return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid);
}
+static inline int ath10k_wmi_gpio_config(struct ath10k *ar, u32 gpio_num,
+ u32 input, u32 pull_type, u32 intr_mode)
+{
+ struct sk_buff *skb;
+
+ if (!ar->wmi.ops->gen_gpio_config)
+ return -EOPNOTSUPP;
+
+ skb = ar->wmi.ops->gen_gpio_config(ar, gpio_num, input, pull_type, intr_mode);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_config_cmdid);
+}
+
+static inline int ath10k_wmi_gpio_output(struct ath10k *ar, u32 gpio_num, u32 set)
+{
+ struct sk_buff *skb;
+
+ if (!ar->wmi.ops->gen_gpio_config)
+ return -EOPNOTSUPP;
+
+ skb = ar->wmi.ops->gen_gpio_output(ar, gpio_num, set);
+ if (IS_ERR(skb))
+ return PTR_ERR(skb);
+
+ return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->gpio_output_cmdid);
+}
+
static inline int
ath10k_wmi_dbglog_cfg(struct ath10k *ar, u64 module_enable, u32 log_level)
{
--- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c
+++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c
@@ -3991,6 +3991,8 @@ static const struct wmi_ops wmi_tlv_ops
.gen_echo = ath10k_wmi_tlv_op_gen_echo,
.gen_vdev_spectral_conf = ath10k_wmi_tlv_op_gen_vdev_spectral_conf,
.gen_vdev_spectral_enable = ath10k_wmi_tlv_op_gen_vdev_spectral_enable,
+ /* .gen_gpio_config not implemented */
+ /* .gen_gpio_output not implemented */
};
static const struct wmi_peer_flags_map wmi_tlv_peer_flags_map = {
--- a/drivers/net/wireless/ath/ath10k/wmi.c
+++ b/drivers/net/wireless/ath/ath10k/wmi.c
@@ -7211,6 +7211,49 @@ ath10k_wmi_op_gen_peer_set_param(struct
return skb;
}
+static struct sk_buff *ath10k_wmi_op_gen_gpio_config(struct ath10k *ar,
+ u32 gpio_num, u32 input,
+ u32 pull_type, u32 intr_mode)
+{
+ struct wmi_gpio_config_cmd *cmd;
+ struct sk_buff *skb;
+
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
+ if (!skb)
+ return ERR_PTR(-ENOMEM);
+
+ cmd = (struct wmi_gpio_config_cmd *)skb->data;
+ cmd->pull_type = __cpu_to_le32(pull_type);
+ cmd->gpio_num = __cpu_to_le32(gpio_num);
+ cmd->input = __cpu_to_le32(input);
+ cmd->intr_mode = __cpu_to_le32(intr_mode);
+
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_config gpio_num 0x%08x input 0x%08x pull_type 0x%08x intr_mode 0x%08x\n",
+ gpio_num, input, pull_type, intr_mode);
+
+ return skb;
+}
+
+static struct sk_buff *ath10k_wmi_op_gen_gpio_output(struct ath10k *ar,
+ u32 gpio_num, u32 set)
+{
+ struct wmi_gpio_output_cmd *cmd;
+ struct sk_buff *skb;
+
+ skb = ath10k_wmi_alloc_skb(ar, sizeof(*cmd));
+ if (!skb)
+ return ERR_PTR(-ENOMEM);
+
+ cmd = (struct wmi_gpio_output_cmd *)skb->data;
+ cmd->gpio_num = __cpu_to_le32(gpio_num);
+ cmd->set = __cpu_to_le32(set);
+
+ ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi gpio_output gpio_num 0x%08x set 0x%08x\n",
+ gpio_num, set);
+
+ return skb;
+}
+
static struct sk_buff *
ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id,
enum wmi_sta_ps_mode psmode)
@@ -8822,6 +8865,9 @@ static const struct wmi_ops wmi_ops = {
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
.gen_echo = ath10k_wmi_op_gen_echo,
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
+
/* .gen_bcn_tmpl not implemented */
/* .gen_prb_tmpl not implemented */
/* .gen_p2p_go_bcn_ie not implemented */
@@ -8892,6 +8938,8 @@ static const struct wmi_ops wmi_10_1_ops
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
.gen_echo = ath10k_wmi_op_gen_echo,
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
/* .gen_bcn_tmpl not implemented */
/* .gen_prb_tmpl not implemented */
/* .gen_p2p_go_bcn_ie not implemented */
@@ -8963,6 +9011,8 @@ static const struct wmi_ops wmi_10_2_ops
.gen_delba_send = ath10k_wmi_op_gen_delba_send,
.fw_stats_fill = ath10k_wmi_10x_op_fw_stats_fill,
.get_vdev_subtype = ath10k_wmi_op_get_vdev_subtype,
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
/* .gen_pdev_enable_adaptive_cca not implemented */
};
@@ -9033,6 +9083,8 @@ static const struct wmi_ops wmi_10_2_4_o
.gen_pdev_enable_adaptive_cca =
ath10k_wmi_op_gen_pdev_enable_adaptive_cca,
.get_vdev_subtype = ath10k_wmi_10_2_4_op_get_vdev_subtype,
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
/* .gen_bcn_tmpl not implemented */
/* .gen_prb_tmpl not implemented */
/* .gen_p2p_go_bcn_ie not implemented */
@@ -9112,6 +9164,8 @@ static const struct wmi_ops wmi_10_4_ops
.gen_pdev_bss_chan_info_req = ath10k_wmi_10_2_op_gen_pdev_bss_chan_info,
.gen_echo = ath10k_wmi_op_gen_echo,
.gen_pdev_get_tpc_config = ath10k_wmi_10_2_4_op_gen_pdev_get_tpc_config,
+ .gen_gpio_config = ath10k_wmi_op_gen_gpio_config,
+ .gen_gpio_output = ath10k_wmi_op_gen_gpio_output,
};
int ath10k_wmi_attach(struct ath10k *ar)
--- a/drivers/net/wireless/ath/ath10k/wmi.h
+++ b/drivers/net/wireless/ath/ath10k/wmi.h
@@ -2942,6 +2942,41 @@ enum wmi_10_4_feature_mask {
};
+/* WMI_GPIO_CONFIG_CMDID */
+enum {
+ WMI_GPIO_PULL_NONE,
+ WMI_GPIO_PULL_UP,
+ WMI_GPIO_PULL_DOWN,
+};
+
+enum {
+ WMI_GPIO_INTTYPE_DISABLE,
+ WMI_GPIO_INTTYPE_RISING_EDGE,
+ WMI_GPIO_INTTYPE_FALLING_EDGE,
+ WMI_GPIO_INTTYPE_BOTH_EDGE,
+ WMI_GPIO_INTTYPE_LEVEL_LOW,
+ WMI_GPIO_INTTYPE_LEVEL_HIGH
+};
+
+/* WMI_GPIO_CONFIG_CMDID */
+struct wmi_gpio_config_cmd {
+ __le32 gpio_num; /* GPIO number to be setup */
+ __le32 input; /* 0 - Output/ 1 - Input */
+ __le32 pull_type; /* Pull type defined above */
+ __le32 intr_mode; /* Interrupt mode defined above (Input) */
+} __packed;
+
+/* WMI_GPIO_OUTPUT_CMDID */
+struct wmi_gpio_output_cmd {
+ __le32 gpio_num; /* GPIO number to be setup */
+ __le32 set; /* Set the GPIO pin*/
+} __packed;
+
+/* WMI_GPIO_INPUT_EVENTID */
+struct wmi_gpio_input_event {
+ __le32 gpio_num; /* GPIO number which changed state */
+} __packed;
+
struct wmi_ext_resource_config_10_4_cmd {
/* contains enum wmi_host_platform_type */
__le32 host_platform_config;

View File

@@ -0,0 +1,53 @@
From 79c9d7aabae1d1da9eea97d83b61e1517a8a2221 Mon Sep 17 00:00:00 2001
From: Mathias Kresin <dev@kresin.me>
Date: Fri, 22 Jun 2018 18:59:44 +0200
Subject: [PATCH] ath10k: use tpt LED trigger by default
Use the tpt LED trigger for each created phy led. Ths way LEDs attached
to the ath10k GPIO pins are indicating the phy status and blink on
traffic.
Signed-off-by: Mathias Kresin <dev@kresin.me>
---
drivers/net/wireless/ath/ath10k/core.h | 4 ++++
drivers/net/wireless/ath/ath10k/leds.c | 4 +---
drivers/net/wireless/ath/ath10k/mac.c | 2 +-
3 files changed, 6 insertions(+), 4 deletions(-)
--- a/drivers/net/wireless/ath/ath10k/core.h
+++ b/drivers/net/wireless/ath/ath10k/core.h
@@ -1145,6 +1145,10 @@ struct ath10k {
struct ath10k_radar_found_info last_radar_info;
struct work_struct radar_confirmation_work;
+#ifdef CPTCFG_MAC80211_LEDS
+ const char *led_default_trigger;
+#endif
+
/* must be last */
u8 drv_priv[0] __aligned(sizeof(void *));
};
--- a/drivers/net/wireless/ath/ath10k/leds.c
+++ b/drivers/net/wireless/ath/ath10k/leds.c
@@ -81,9 +81,7 @@ int ath10k_leds_register(struct ath10k *
ar->leds.cdev.name = ar->leds.label;
ar->leds.cdev.brightness_set_blocking = ath10k_leds_set_brightness_blocking;
-
- /* FIXME: this assignment doesn't make sense as it's NULL, remove it? */
- ar->leds.cdev.default_trigger = ar->leds.wifi_led.default_trigger;
+ ar->leds.cdev.default_trigger = ar->led_default_trigger;
ret = led_classdev_register(wiphy_dev(ar->hw->wiphy), &ar->leds.cdev);
if (ret)
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -8616,7 +8616,7 @@ int ath10k_mac_register(struct ath10k *a
wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
#ifdef CPTCFG_MAC80211_LEDS
- ieee80211_create_tpt_led_trigger(ar->hw,
+ ar->led_default_trigger = ieee80211_create_tpt_led_trigger(ar->hw,
IEEE80211_TPT_LEDTRIG_FL_RADIO, ath10k_tpt_blink,
ARRAY_SIZE(ath10k_tpt_blink));
#endif

View File

@@ -0,0 +1,89 @@
From: Sriram R <srirrama@codeaurora.org>
Date: Mon, 10 Sep 2018 11:09:40 +0530
Subject: [PATCH] ath10k: add support for configuring management packet rate
By default the firmware uses 1Mbps and 6Mbps rate for management packets
in 2G and 5G bands respectively. But when the user selects different
basic rates from the userspace, we need to send the management
packets at the lowest basic rate selected by the user.
This change makes use of WMI_VDEV_PARAM_MGMT_RATE param for configuring the
management packets rate to the firmware.
Chipsets Tested : QCA988X, QCA9887, QCA9984
FW Tested : 10.2.4-1.0-41, 10.4-3.6.104
Signed-off-by: Sriram R <srirrama@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=f279294e9ee22a8f306fdc8e4181cf555e6f0f70
---
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -158,6 +158,22 @@ u8 ath10k_mac_bitrate_to_idx(const struc
return 0;
}
+static int ath10k_mac_get_rate_hw_value(int bitrate)
+{
+ int i;
+ u8 hw_value_prefix = 0;
+
+ if (ath10k_mac_bitrate_is_cck(bitrate))
+ hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
+
+ for (i = 0; i < sizeof(ath10k_rates); i++) {
+ if (ath10k_rates[i].bitrate == bitrate)
+ return hw_value_prefix | ath10k_rates[i].hw_value;
+ }
+
+ return -EINVAL;
+}
+
static int ath10k_mac_get_max_vht_mcs_map(u16 mcs_map, int nss)
{
switch ((mcs_map >> (2 * nss)) & 0x3) {
@@ -5485,9 +5501,10 @@ static void ath10k_bss_info_changed(stru
struct cfg80211_chan_def def;
u32 vdev_param, pdev_param, slottime, preamble;
u16 bitrate, hw_value;
- u8 rate;
- int rateidx, ret = 0;
+ u8 rate, basic_rate_idx;
+ int rateidx, ret = 0, hw_rate_code;
enum nl80211_band band;
+ const struct ieee80211_supported_band *sband;
mutex_lock(&ar->conf_mutex);
@@ -5693,6 +5710,30 @@ static void ath10k_bss_info_changed(stru
arvif->vdev_id, ret);
}
+ if (changed & BSS_CHANGED_BASIC_RATES) {
+ if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) {
+ mutex_unlock(&ar->conf_mutex);
+ return;
+ }
+
+ sband = ar->hw->wiphy->bands[def.chan->band];
+ basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
+ bitrate = sband->bitrates[basic_rate_idx].bitrate;
+
+ hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
+ if (hw_rate_code < 0) {
+ ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
+ mutex_unlock(&ar->conf_mutex);
+ return;
+ }
+
+ vdev_param = ar->wmi.vdev_param->mgmt_rate;
+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
+ hw_rate_code);
+ if (ret)
+ ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
+ }
+
mutex_unlock(&ar->conf_mutex);
}

View File

@@ -0,0 +1,66 @@
From: Sriram R <srirrama@codeaurora.org>
Date: Wed, 3 Oct 2018 08:43:50 +0530
Subject: [PATCH] ath10k: fix possible out of bound access of ath10k_rates array
While using 'ath10k_mac_get_rate_hw_value()' to obtain the hw value
from the passed bitrate, there is a chance of out of bound array access
when wrong bitrate is passed. This is fixed by comparing the bitrates
within the correct size of the ath10k_rates array.
Fixes commit f279294e9ee2 ("ath10k: add support for configuring management
packet rate"). Also correction made to some indents used in the above commit.
Signed-off-by: Sriram R <srirrama@codeaurora.org>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
Origin: backport, https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=34e141eea7dd8525dd1ef7a925459e455b4d307f
---
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -166,7 +166,7 @@ static int ath10k_mac_get_rate_hw_value(
if (ath10k_mac_bitrate_is_cck(bitrate))
hw_value_prefix = WMI_RATE_PREAMBLE_CCK << 6;
- for (i = 0; i < sizeof(ath10k_rates); i++) {
+ for (i = 0; i < ARRAY_SIZE(ath10k_rates); i++) {
if (ath10k_rates[i].bitrate == bitrate)
return hw_value_prefix | ath10k_rates[i].hw_value;
}
@@ -5716,22 +5716,22 @@ static void ath10k_bss_info_changed(stru
return;
}
- sband = ar->hw->wiphy->bands[def.chan->band];
- basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
- bitrate = sband->bitrates[basic_rate_idx].bitrate;
-
- hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
- if (hw_rate_code < 0) {
- ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
- mutex_unlock(&ar->conf_mutex);
- return;
- }
+ sband = ar->hw->wiphy->bands[def.chan->band];
+ basic_rate_idx = ffs(vif->bss_conf.basic_rates) - 1;
+ bitrate = sband->bitrates[basic_rate_idx].bitrate;
+
+ hw_rate_code = ath10k_mac_get_rate_hw_value(bitrate);
+ if (hw_rate_code < 0) {
+ ath10k_warn(ar, "bitrate not supported %d\n", bitrate);
+ mutex_unlock(&ar->conf_mutex);
+ return;
+ }
- vdev_param = ar->wmi.vdev_param->mgmt_rate;
- ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
- hw_rate_code);
- if (ret)
- ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
+ vdev_param = ar->wmi.vdev_param->mgmt_rate;
+ ret = ath10k_wmi_vdev_set_param(ar, arvif->vdev_id, vdev_param,
+ hw_rate_code);
+ if (ret)
+ ath10k_warn(ar, "failed to set mgmt tx rate %d\n", ret);
}
mutex_unlock(&ar->conf_mutex);

View File

@@ -0,0 +1,43 @@
From: Pradeep kumar Chitrapu <pradeepc@codeaurora.org>
Date: Mon, 10 Dec 2018 20:56:11 -0800
Subject: ath10k: fix incorrect multicast/broadcast rate setting
Invalid rate code is sent to firmware when multicast rate value of 0 is
sent to driver indicating disabled case, causing broken mesh path.
so fix that.
Tested on QCA9984 with firmware 10.4-3.6.1-00827
Fixes: cd93b83ad92 ("ath10k: support for multicast rate control")
Co-developed-by: Zhi Chen <zhichen@codeaurora.org>
Signed-off-by: Zhi Chen <zhichen@codeaurora.org>
Signed-off-by: Pradeep Kumar Chitrapu <pradeepc@codeaurora.org>
Origin: other, https://patchwork.kernel.org/patch/10723033/
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -5501,8 +5501,8 @@ static void ath10k_bss_info_changed(stru
struct cfg80211_chan_def def;
u32 vdev_param, pdev_param, slottime, preamble;
u16 bitrate, hw_value;
- u8 rate, basic_rate_idx;
- int rateidx, ret = 0, hw_rate_code;
+ u8 rate, basic_rate_idx, rateidx;
+ int ret = 0, hw_rate_code, mcast_rate;
enum nl80211_band band;
const struct ieee80211_supported_band *sband;
@@ -5675,7 +5675,11 @@ static void ath10k_bss_info_changed(stru
if (changed & BSS_CHANGED_MCAST_RATE &&
!ath10k_mac_vif_chan(arvif->vif, &def)) {
band = def.chan->band;
- rateidx = vif->bss_conf.mcast_rate[band] - 1;
+ mcast_rate = vif->bss_conf.mcast_rate[band];
+ if (mcast_rate > 0)
+ rateidx = mcast_rate - 1;
+ else
+ rateidx = ffs(vif->bss_conf.basic_rates) - 1;
if (ar->phy_capability & WHAL_WLAN_11A_CAPABILITY)
rateidx += ATH10K_MAC_FIRST_OFDM_RATE_IDX;

View File

@@ -0,0 +1,49 @@
From: Sven Eckelmann <seckelmann@datto.com>
Date: Tue, 11 Jun 2019 13:58:35 +0200
Subject: ath10k: fix max antenna gain unit
Most of the txpower for the ath10k firmware is stored as twicepower (0.5 dB
steps). This isn't the case for max_antenna_gain - which is still expected
by the firmware as dB.
The firmware is converting it from dB to the internal (twicepower)
representation when it calculates the limits of a channel. This can be seen
in tpc_stats when configuring "12" as max_antenna_gain. Instead of the
expected 12 (6 dB), the tpc_stats shows 24 (12 dB).
Tested on QCA9888 and IPQ4019 with firmware 10.4-3.5.3-00057.
Fixes: 02256930d9b8 ("ath10k: use proper tx power unit")
Signed-off-by: Sven Eckelmann <seckelmann@datto.com>
Forwarded: https://patchwork.kernel.org/patch/10986723/
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -1020,7 +1020,7 @@ static int ath10k_monitor_vdev_start(str
arg.channel.min_power = 0;
arg.channel.max_power = channel->max_power * 2;
arg.channel.max_reg_power = channel->max_reg_power * 2;
- arg.channel.max_antenna_gain = channel->max_antenna_gain * 2;
+ arg.channel.max_antenna_gain = channel->max_antenna_gain;
reinit_completion(&ar->vdev_setup_done);
@@ -1462,7 +1462,7 @@ static int ath10k_vdev_start_restart(str
arg.channel.min_power = 0;
arg.channel.max_power = chandef->chan->max_power * 2;
arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
- arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain * 2;
+ arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
arg.ssid = arvif->u.ap.ssid;
@@ -3143,7 +3143,7 @@ static int ath10k_update_channel_list(st
ch->min_power = 0;
ch->max_power = channel->max_power * 2;
ch->max_reg_power = channel->max_reg_power * 2;
- ch->max_antenna_gain = channel->max_antenna_gain * 2;
+ ch->max_antenna_gain = channel->max_antenna_gain;
ch->reg_class_id = 0; /* FIXME */
/* FIXME: why use only legacy modes, why not any

View File

@@ -0,0 +1,101 @@
From: Sven Eckelmann <seckelmann@datto.com>
Date: Wed, 28 Nov 2018 16:16:27 +0100
Subject: ath10k: adjust tx power reduction for US regulatory domain
FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4):
> (4) The conducted output power limit
> specified in paragraph (b) of this section
> is based on the use of antennas
> with directional gains that do not exceed
> 6 dBi. Except as shown in paragraph
> (c) of this section, if transmitting
> antennas of directional gain greater
> than 6 dBi are used, the conducted
> output power from the intentional radiator
> shall be reduced below the stated
> values in paragraphs (b)(1), (b)(2),
> and (b)(3) of this section, as appropriate,
> by the amount in dB that the
> directional gain of the antenna exceeds
> 6 dBi.
https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf
Signed-off-by: Sven Eckelmann <seckelmann@datto.com>
Forwarded: no
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -988,6 +988,40 @@ static inline int ath10k_vdev_setup_sync
return ar->last_wmi_vdev_start_status;
}
+static u32 ath10k_get_max_antenna_gain(struct ath10k *ar,
+ u32 ch_max_antenna_gain)
+{
+ u32 max_antenna_gain;
+
+ if (ar->dfs_detector && ar->dfs_detector->region == NL80211_DFS_FCC) {
+ /* FCC allows maximum antenna gain of 6 dBi. 15.247(b)(4):
+ *
+ * > (4) The conducted output power limit
+ * > specified in paragraph (b) of this section
+ * > is based on the use of antennas
+ * > with directional gains that do not exceed
+ * > 6 dBi. Except as shown in paragraph
+ * > (c) of this section, if transmitting
+ * > antennas of directional gain greater
+ * > than 6 dBi are used, the conducted
+ * > output power from the intentional radiator
+ * > shall be reduced below the stated
+ * > values in paragraphs (b)(1), (b)(2),
+ * > and (b)(3) of this section, as appropriate,
+ * > by the amount in dB that the
+ * > directional gain of the antenna exceeds
+ * > 6 dBi.
+ *
+ * https://www.gpo.gov/fdsys/pkg/CFR-2013-title47-vol1/pdf/CFR-2013-title47-vol1-sec15-247.pdf
+ */
+ max_antenna_gain = 6;
+ } else {
+ max_antenna_gain = 0;
+ }
+
+ return max(ch_max_antenna_gain, max_antenna_gain);
+}
+
static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id)
{
struct cfg80211_chan_def *chandef = NULL;
@@ -1020,7 +1054,8 @@ static int ath10k_monitor_vdev_start(str
arg.channel.min_power = 0;
arg.channel.max_power = channel->max_power * 2;
arg.channel.max_reg_power = channel->max_reg_power * 2;
- arg.channel.max_antenna_gain = channel->max_antenna_gain;
+ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
+ channel->max_antenna_gain);
reinit_completion(&ar->vdev_setup_done);
@@ -1462,7 +1497,8 @@ static int ath10k_vdev_start_restart(str
arg.channel.min_power = 0;
arg.channel.max_power = chandef->chan->max_power * 2;
arg.channel.max_reg_power = chandef->chan->max_reg_power * 2;
- arg.channel.max_antenna_gain = chandef->chan->max_antenna_gain;
+ arg.channel.max_antenna_gain = ath10k_get_max_antenna_gain(ar,
+ chandef->chan->max_antenna_gain);
if (arvif->vdev_type == WMI_VDEV_TYPE_AP) {
arg.ssid = arvif->u.ap.ssid;
@@ -3143,7 +3179,8 @@ static int ath10k_update_channel_list(st
ch->min_power = 0;
ch->max_power = channel->max_power * 2;
ch->max_reg_power = channel->max_reg_power * 2;
- ch->max_antenna_gain = channel->max_antenna_gain;
+ ch->max_antenna_gain = ath10k_get_max_antenna_gain(ar,
+ channel->max_antenna_gain);
ch->reg_class_id = 0; /* FIXME */
/* FIXME: why use only legacy modes, why not any

View File

@@ -0,0 +1,9 @@
--- a/drivers/net/wireless/broadcom/brcm80211/Kconfig
+++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig
@@ -1,5 +1,5 @@
config BRCMUTIL
- tristate
+ tristate "Broadcom 802.11 driver utility functions"
depends on m
config BRCMSMAC

View File

@@ -0,0 +1,25 @@
From 2fef681a4cf7994c882190fd2417b95f30510afb Mon Sep 17 00:00:00 2001
From: Jia-Shyr Chuang <saint.chuang@cypress.com>
Date: Wed, 15 Aug 2018 04:23:09 -0500
Subject: [PATCH] brcmfmac: add CYW89342 mini-PCIe device
CYW89342 is a 2x2 MIMO, 802.11a/b/g/n/ac for WLAN. It is a member of
4355/4359 family.
Signed-off-by: Jia-Shyr Chuang <saint.chuang@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -2017,6 +2017,7 @@ static const struct dev_pm_ops brcmf_pci
static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID),
+ BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),

View File

@@ -0,0 +1,57 @@
From a8254fa4ba60b85829b6e5ede6564f81cd70d59f Mon Sep 17 00:00:00 2001
From: YueHaibing <yuehaibing@huawei.com>
Date: Tue, 11 Sep 2018 11:24:04 +0800
Subject: [PATCH] brcmfmac: remove set but not used variables 'sfdoff' and
'pad_size'
Fixes gcc '-Wunused-but-set-variable' warning:
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c: In function 'brcmf_sdio_rxglom':
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:1466:11: warning:
variable 'sfdoff' set but not used [-Wunused-but-set-variable]
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c: In function 'brcmf_sdio_bus_preinit':
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:3408:7: warning:
variable 'pad_size' set but not used [-Wunused-but-set-variable]
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -1480,7 +1480,7 @@ static u8 brcmf_sdio_rxglom(struct brcmf
struct sk_buff *pfirst, *pnext;
int errcode;
- u8 doff, sfdoff;
+ u8 doff;
struct brcmf_sdio_hdrinfo rd_new;
@@ -1614,7 +1614,6 @@ static u8 brcmf_sdio_rxglom(struct brcmf
/* Remove superframe header, remember offset */
skb_pull(pfirst, rd_new.dat_offset);
- sfdoff = rd_new.dat_offset;
num = 0;
/* Validate all the subframe headers */
@@ -3428,7 +3427,6 @@ static int brcmf_sdio_bus_preinit(struct
struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio;
struct brcmf_sdio *bus = sdiodev->bus;
struct brcmf_core *core = bus->sdio_core;
- uint pad_size;
u32 value;
int err;
@@ -3469,7 +3467,6 @@ static int brcmf_sdio_bus_preinit(struct
if (sdiodev->sg_support) {
bus->txglom = false;
value = 1;
- pad_size = bus->sdiodev->func2->cur_blksize << 1;
err = brcmf_iovar_data_set(bus->sdiodev->dev, "bus:rxglom",
&value, sizeof(u32));
if (err < 0) {

View File

@@ -0,0 +1,102 @@
From a1a3b762163868ad07a4499a73df324f40d5ab0b Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 10 Oct 2018 13:00:58 +0200
Subject: [PATCH] brcmfmac: Remove firmware-loading code duplication
brcmf_fw_request_next_item and brcmf_fw_request_done both have identical
code to complete the fw-request depending on the item-type.
This commit adds a new brcmf_fw_complete_request helper removing this code
duplication.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 62 +++++++++++-----------
1 file changed, 31 insertions(+), 31 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -504,6 +504,34 @@ fail:
return -ENOENT;
}
+static int brcmf_fw_complete_request(const struct firmware *fw,
+ struct brcmf_fw *fwctx)
+{
+ struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos];
+ int ret = 0;
+
+ brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path, fw ? "" : "not ");
+
+ switch (cur->type) {
+ case BRCMF_FW_TYPE_NVRAM:
+ ret = brcmf_fw_request_nvram_done(fw, fwctx);
+ break;
+ case BRCMF_FW_TYPE_BINARY:
+ if (fw)
+ cur->binary = fw;
+ else
+ ret = -ENOENT;
+ break;
+ default:
+ /* something fishy here so bail out early */
+ brcmf_err("unknown fw type: %d\n", cur->type);
+ release_firmware(fw);
+ ret = -EINVAL;
+ }
+
+ return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret;
+}
+
static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
{
struct brcmf_fw_item *cur;
@@ -525,15 +553,7 @@ static int brcmf_fw_request_next_item(st
if (ret < 0) {
brcmf_fw_request_done(NULL, fwctx);
} else if (!async && fw) {
- brcmf_dbg(TRACE, "firmware %s %sfound\n", cur->path,
- fw ? "" : "not ");
- if (cur->type == BRCMF_FW_TYPE_BINARY)
- cur->binary = fw;
- else if (cur->type == BRCMF_FW_TYPE_NVRAM)
- brcmf_fw_request_nvram_done(fw, fwctx);
- else
- release_firmware(fw);
-
+ brcmf_fw_complete_request(fw, fwctx);
return -EAGAIN;
}
return 0;
@@ -547,28 +567,8 @@ static void brcmf_fw_request_done(const
cur = &fwctx->req->items[fwctx->curpos];
- brcmf_dbg(TRACE, "enter: firmware %s %sfound\n", cur->path,
- fw ? "" : "not ");
-
- if (!fw)
- ret = -ENOENT;
-
- switch (cur->type) {
- case BRCMF_FW_TYPE_NVRAM:
- ret = brcmf_fw_request_nvram_done(fw, fwctx);
- break;
- case BRCMF_FW_TYPE_BINARY:
- cur->binary = fw;
- break;
- default:
- /* something fishy here so bail out early */
- brcmf_err("unknown fw type: %d\n", cur->type);
- release_firmware(fw);
- ret = -EINVAL;
- goto fail;
- }
-
- if (ret < 0 && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
+ ret = brcmf_fw_complete_request(fw, fwctx);
+ if (ret < 0)
goto fail;
do {

View File

@@ -0,0 +1,127 @@
From 5b587496dc63595b71265d986ce69728c2724370 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 10 Oct 2018 13:00:59 +0200
Subject: [PATCH] brcmfmac: Remove recursion from firmware load error handling
Before this commit brcmf_fw_request_done would call
brcmf_fw_request_next_item to load the next item, which on an error would
call brcmf_fw_request_done, which if the error is recoverable (*) will
then continue calling brcmf_fw_request_next_item for the next item again
which on an error will call brcmf_fw_request_done again...
This does not blow up because we only have a limited number of items so
we never recurse too deep. But the recursion is still quite ugly and
frankly is giving me a headache, so lets fix this.
This commit fixes this by removing brcmf_fw_request_next_item and by
making brcmf_fw_get_firmwares and brcmf_fw_request_done directly call
firmware_request_nowait resp. firmware_request themselves.
*) brcmf_fw_request_nvram_done fallback path succeeds or
BRCMF_FW_REQF_OPTIONAL is set
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 65 +++++++---------------
1 file changed, 19 insertions(+), 46 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -532,33 +532,6 @@ static int brcmf_fw_complete_request(con
return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret;
}
-static int brcmf_fw_request_next_item(struct brcmf_fw *fwctx, bool async)
-{
- struct brcmf_fw_item *cur;
- const struct firmware *fw = NULL;
- int ret;
-
- cur = &fwctx->req->items[fwctx->curpos];
-
- brcmf_dbg(TRACE, "%srequest for %s\n", async ? "async " : "",
- cur->path);
-
- if (async)
- ret = request_firmware_nowait(THIS_MODULE, true, cur->path,
- fwctx->dev, GFP_KERNEL, fwctx,
- brcmf_fw_request_done);
- else
- ret = request_firmware(&fw, cur->path, fwctx->dev);
-
- if (ret < 0) {
- brcmf_fw_request_done(NULL, fwctx);
- } else if (!async && fw) {
- brcmf_fw_complete_request(fw, fwctx);
- return -EAGAIN;
- }
- return 0;
-}
-
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
{
struct brcmf_fw *fwctx = ctx;
@@ -568,26 +541,19 @@ static void brcmf_fw_request_done(const
cur = &fwctx->req->items[fwctx->curpos];
ret = brcmf_fw_complete_request(fw, fwctx);
- if (ret < 0)
- goto fail;
- do {
- if (++fwctx->curpos == fwctx->req->n_items) {
- ret = 0;
- goto done;
- }
-
- ret = brcmf_fw_request_next_item(fwctx, false);
- } while (ret == -EAGAIN);
-
- return;
-
-fail:
- brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
- dev_name(fwctx->dev), cur->path);
- brcmf_fw_free_request(fwctx->req);
- fwctx->req = NULL;
-done:
+ while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) {
+ cur = &fwctx->req->items[fwctx->curpos];
+ request_firmware(&fw, cur->path, fwctx->dev);
+ ret = brcmf_fw_complete_request(fw, ctx);
+ }
+
+ if (ret) {
+ brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
+ dev_name(fwctx->dev), cur->path);
+ brcmf_fw_free_request(fwctx->req);
+ fwctx->req = NULL;
+ }
fwctx->done(fwctx->dev, ret, fwctx->req);
kfree(fwctx);
}
@@ -611,7 +577,9 @@ int brcmf_fw_get_firmwares(struct device
void (*fw_cb)(struct device *dev, int err,
struct brcmf_fw_request *req))
{
+ struct brcmf_fw_item *first = &req->items[0];
struct brcmf_fw *fwctx;
+ int ret;
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev));
if (!fw_cb)
@@ -628,7 +596,12 @@ int brcmf_fw_get_firmwares(struct device
fwctx->req = req;
fwctx->done = fw_cb;
- brcmf_fw_request_next_item(fwctx, true);
+ ret = request_firmware_nowait(THIS_MODULE, true, first->path,
+ fwctx->dev, GFP_KERNEL, fwctx,
+ brcmf_fw_request_done);
+ if (ret < 0)
+ brcmf_fw_request_done(NULL, fwctx);
+
return 0;
}

View File

@@ -0,0 +1,77 @@
From eae8e50669e15002b195177212a6e25afbe7cf4d Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 10 Oct 2018 13:01:00 +0200
Subject: [PATCH] brcmfmac: Add support for first trying to get a board
specific nvram file
The nvram files which some brcmfmac chips need are board-specific. To be
able to distribute these as part of linux-firmware, so that devices with
such a wifi chip will work OOTB, multiple (one per board) versions must
co-exist under /lib/firmware.
This commit adds support for callers of the brcmfmac/firmware.c code to
pass in a board_type parameter through the request structure.
If that parameter is set then the code will first try to load
chipmodel.board_type.txt before falling back to the old chipmodel.txt name.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 27 +++++++++++++++++++++-
.../broadcom/brcm80211/brcmfmac/firmware.h | 1 +
2 files changed, 27 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -532,6 +532,31 @@ static int brcmf_fw_complete_request(con
return (cur->flags & BRCMF_FW_REQF_OPTIONAL) ? 0 : ret;
}
+static int brcmf_fw_request_firmware(const struct firmware **fw,
+ struct brcmf_fw *fwctx)
+{
+ struct brcmf_fw_item *cur = &fwctx->req->items[fwctx->curpos];
+ int ret;
+
+ /* nvram files are board-specific, first try a board-specific path */
+ if (cur->type == BRCMF_FW_TYPE_NVRAM && fwctx->req->board_type) {
+ char alt_path[BRCMF_FW_NAME_LEN];
+
+ strlcpy(alt_path, cur->path, BRCMF_FW_NAME_LEN);
+ /* strip .txt at the end */
+ alt_path[strlen(alt_path) - 4] = 0;
+ strlcat(alt_path, ".", BRCMF_FW_NAME_LEN);
+ strlcat(alt_path, fwctx->req->board_type, BRCMF_FW_NAME_LEN);
+ strlcat(alt_path, ".txt", BRCMF_FW_NAME_LEN);
+
+ ret = request_firmware(fw, alt_path, fwctx->dev);
+ if (ret == 0)
+ return ret;
+ }
+
+ return request_firmware(fw, cur->path, fwctx->dev);
+}
+
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
{
struct brcmf_fw *fwctx = ctx;
@@ -544,7 +569,7 @@ static void brcmf_fw_request_done(const
while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) {
cur = &fwctx->req->items[fwctx->curpos];
- request_firmware(&fw, cur->path, fwctx->dev);
+ brcmf_fw_request_firmware(&fw, fwctx);
ret = brcmf_fw_complete_request(fw, ctx);
}
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.h
@@ -70,6 +70,7 @@ struct brcmf_fw_request {
u16 domain_nr;
u16 bus_nr;
u32 n_items;
+ const char *board_type;
struct brcmf_fw_item items[0];
};

View File

@@ -0,0 +1,77 @@
From 0ad4b55b2f29784f93875e6231bf57cd233624a2 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 10 Oct 2018 13:01:01 +0200
Subject: [PATCH] brcmfmac: Set board_type used for nvram file selection to
machine-compatible
For of/devicetree using machines, set the board_type used for nvram file
selection to the first string listed in the top-level's node compatible
string, aka the machine-compatible as used by of_machine_is_compatible().
The board_type setting is used to load the board-specific nvram file with
a board-specific name so that we can ship files for each supported board
in linux-firmware.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h | 1 +
drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c | 11 ++++++++++-
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 +
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 1 +
4 files changed, 13 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -59,6 +59,7 @@ struct brcmf_mp_device {
bool iapp;
bool ignore_probe_fail;
struct brcmfmac_pd_cc *country_codes;
+ const char *board_type;
union {
struct brcmfmac_sdio_pd sdio;
} bus;
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c
@@ -27,11 +27,20 @@ void brcmf_of_probe(struct device *dev,
struct brcmf_mp_device *settings)
{
struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
- struct device_node *np = dev->of_node;
+ struct device_node *root, *np = dev->of_node;
+ struct property *prop;
int irq;
u32 irqf;
u32 val;
+ /* Set board-type to the first string of the machine compatible prop */
+ root = of_find_node_by_path("/");
+ if (root) {
+ prop = of_find_property(root, "compatible", NULL);
+ settings->board_type = of_prop_next_string(prop, NULL);
+ of_node_put(root);
+ }
+
if (!np || bus_type != BRCMF_BUSTYPE_SDIO ||
!of_device_is_compatible(np, "brcm,bcm4329-fmac"))
return;
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -1785,6 +1785,7 @@ brcmf_pcie_prepare_fw_request(struct brc
fwreq->items[BRCMF_PCIE_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
fwreq->items[BRCMF_PCIE_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
fwreq->items[BRCMF_PCIE_FW_NVRAM].flags = BRCMF_FW_REQF_OPTIONAL;
+ fwreq->board_type = devinfo->settings->board_type;
/* NVRAM reserves PCI domain 0 for Broadcom's SDK faked bus */
fwreq->domain_nr = pci_domain_nr(devinfo->pdev->bus) + 1;
fwreq->bus_nr = devinfo->pdev->bus->number;
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -4219,6 +4219,7 @@ brcmf_sdio_prepare_fw_request(struct brc
fwreq->items[BRCMF_SDIO_FW_CODE].type = BRCMF_FW_TYPE_BINARY;
fwreq->items[BRCMF_SDIO_FW_NVRAM].type = BRCMF_FW_TYPE_NVRAM;
+ fwreq->board_type = bus->sdiodev->settings->board_type;
return fwreq;
}

View File

@@ -0,0 +1,179 @@
From bd1e82bb420adf4ad7cd468d8a482cde622dd69d Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 10 Oct 2018 13:01:02 +0200
Subject: [PATCH] brcmfmac: Set board_type from DMI on x86 based machines
For x86 based machines, set the board_type used for nvram file selection
based on the DMI sys-vendor and product-name strings.
Since on some models these strings are too generic, this commit also adds
a quirk table overriding the strings for models listed in that table.
The board_type setting is used to load the board-specific nvram file with
a board-specific name so that we can ship files for each supported board
in linux-firmware.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../wireless/broadcom/brcm80211/brcmfmac/Makefile | 2 +
.../wireless/broadcom/brcm80211/brcmfmac/common.c | 3 +-
.../wireless/broadcom/brcm80211/brcmfmac/common.h | 7 ++
.../net/wireless/broadcom/brcm80211/brcmfmac/dmi.c | 116 +++++++++++++++++++++
4 files changed, 127 insertions(+), 1 deletion(-)
create mode 100644 drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/Makefile
@@ -54,3 +54,5 @@ brcmfmac-$(CPTCFG_BRCM_TRACING) += \
tracepoint.o
brcmfmac-$(CONFIG_OF) += \
of.o
+brcmfmac-$(CONFIG_DMI) += \
+ dmi.o
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -448,8 +448,9 @@ struct brcmf_mp_device *brcmf_get_module
}
}
if (!found) {
- /* No platform data for this device, try OF (Open Firwmare) */
+ /* No platform data for this device, try OF and DMI data */
brcmf_of_probe(dev, bus_type, settings);
+ brcmf_dmi_probe(settings, chip, chiprev);
}
return settings;
}
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.h
@@ -75,4 +75,11 @@ void brcmf_release_module_param(struct b
/* Sets dongle media info (drv_version, mac address). */
int brcmf_c_preinit_dcmds(struct brcmf_if *ifp);
+#ifdef CONFIG_DMI
+void brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev);
+#else
+static inline void
+brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev) {}
+#endif
+
#endif /* BRCMFMAC_COMMON_H */
--- /dev/null
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2018 Hans de Goede <hdegoede@redhat.com>
+ *
+ * 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/dmi.h>
+#include <linux/mod_devicetable.h>
+#include "core.h"
+#include "common.h"
+#include "brcm_hw_ids.h"
+
+/* The DMI data never changes so we can use a static buf for this */
+static char dmi_board_type[128];
+
+struct brcmf_dmi_data {
+ u32 chip;
+ u32 chiprev;
+ const char *board_type;
+};
+
+/* NOTE: Please keep all entries sorted alphabetically */
+
+static const struct brcmf_dmi_data gpd_win_pocket_data = {
+ BRCM_CC_4356_CHIP_ID, 2, "gpd-win-pocket"
+};
+
+static const struct brcmf_dmi_data jumper_ezpad_mini3_data = {
+ BRCM_CC_43430_CHIP_ID, 0, "jumper-ezpad-mini3"
+};
+
+static const struct brcmf_dmi_data meegopad_t08_data = {
+ BRCM_CC_43340_CHIP_ID, 2, "meegopad-t08"
+};
+
+static const struct dmi_system_id dmi_platform_data[] = {
+ {
+ /* Match for the GPDwin which unfortunately uses somewhat
+ * generic dmi strings, which is why we test for 4 strings.
+ * Comparing against 23 other byt/cht boards, board_vendor
+ * and board_name are unique to the GPDwin, where as only one
+ * other board has the same board_serial and 3 others have
+ * the same default product_name. Also the GPDwin is the
+ * only device to have both board_ and product_name not set.
+ */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"),
+ DMI_MATCH(DMI_BOARD_NAME, "Default string"),
+ DMI_MATCH(DMI_BOARD_SERIAL, "Default string"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
+ },
+ .driver_data = (void *)&gpd_win_pocket_data,
+ },
+ {
+ /* Jumper EZpad mini3 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Insyde"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "CherryTrail"),
+ /* jumperx.T87.KFBNEEA02 with the version-nr dropped */
+ DMI_MATCH(DMI_BIOS_VERSION, "jumperx.T87.KFBNEEA"),
+ },
+ .driver_data = (void *)&jumper_ezpad_mini3_data,
+ },
+ {
+ /* Meegopad T08 */
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Default string"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"),
+ DMI_MATCH(DMI_BOARD_NAME, "T3 MRD"),
+ DMI_MATCH(DMI_BOARD_VERSION, "V1.1"),
+ },
+ .driver_data = (void *)&meegopad_t08_data,
+ },
+ {}
+};
+
+void brcmf_dmi_probe(struct brcmf_mp_device *settings, u32 chip, u32 chiprev)
+{
+ const struct dmi_system_id *match;
+ const struct brcmf_dmi_data *data;
+ const char *sys_vendor;
+ const char *product_name;
+
+ /* Some models have DMI strings which are too generic, e.g.
+ * "Default string", we use a quirk table for these.
+ */
+ for (match = dmi_first_match(dmi_platform_data);
+ match;
+ match = dmi_first_match(match + 1)) {
+ data = match->driver_data;
+
+ if (data->chip == chip && data->chiprev == chiprev) {
+ settings->board_type = data->board_type;
+ return;
+ }
+ }
+
+ /* Not found in the quirk-table, use sys_vendor-product_name */
+ sys_vendor = dmi_get_system_info(DMI_SYS_VENDOR);
+ product_name = dmi_get_system_info(DMI_PRODUCT_NAME);
+ if (sys_vendor && product_name) {
+ snprintf(dmi_board_type, sizeof(dmi_board_type), "%s-%s",
+ sys_vendor, product_name);
+ settings->board_type = dmi_board_type;
+ }
+}

View File

@@ -0,0 +1,41 @@
From 55e491edbf14b2da5419c2a319ea3b1d6368d9a2 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Wed, 10 Oct 2018 13:01:03 +0200
Subject: [PATCH] brcmfmac: Cleanup brcmf_fw_request_done()
The "cur" variable is now only used for a debug print and we already
print the same info from brcmf_fw_complete_request(), so the debug print
does not provide any extra info and we can remove it.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -560,22 +560,16 @@ static int brcmf_fw_request_firmware(con
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx)
{
struct brcmf_fw *fwctx = ctx;
- struct brcmf_fw_item *cur;
- int ret = 0;
-
- cur = &fwctx->req->items[fwctx->curpos];
+ int ret;
ret = brcmf_fw_complete_request(fw, fwctx);
while (ret == 0 && ++fwctx->curpos < fwctx->req->n_items) {
- cur = &fwctx->req->items[fwctx->curpos];
brcmf_fw_request_firmware(&fw, fwctx);
ret = brcmf_fw_complete_request(fw, ctx);
}
if (ret) {
- brcmf_dbg(TRACE, "failed err=%d: dev=%s, fw=%s\n", ret,
- dev_name(fwctx->dev), cur->path);
brcmf_fw_free_request(fwctx->req);
fwctx->req = NULL;
}

View File

@@ -0,0 +1,132 @@
From ce2e6db554fad444fa0b3904fc3015336e0ef765 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 11 Oct 2018 11:51:06 +0200
Subject: [PATCH] brcmfmac: Add support for getting nvram contents from EFI
variables
Various X86 laptops with a SDIO attached brcmfmac wifi chip, store the
nvram contents in a special EFI variable. This commit adds support for
getting nvram directly from this EFI variable, without the user needing
to manually copy it.
This makes Wifi / Bluetooth work out of the box on these devices instead of
requiring manual setup.
This has been tested on the following models: Acer Iconia Tab8 w1-810,
Acer One 10, Asus T100CHI, Asus T100HA, Asus T100TA, Asus T200TA and a
Lenovo Mixx 2 8.
Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 63 +++++++++++++++++++---
1 file changed, 57 insertions(+), 6 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -14,6 +14,7 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/efi.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/device.h>
@@ -445,6 +446,51 @@ struct brcmf_fw {
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
+#ifdef CONFIG_EFI
+static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret)
+{
+ const u16 name[] = { 'n', 'v', 'r', 'a', 'm', 0 };
+ struct efivar_entry *nvram_efivar;
+ unsigned long data_len = 0;
+ u8 *data = NULL;
+ int err;
+
+ nvram_efivar = kzalloc(sizeof(*nvram_efivar), GFP_KERNEL);
+ if (!nvram_efivar)
+ return NULL;
+
+ memcpy(&nvram_efivar->var.VariableName, name, sizeof(name));
+ nvram_efivar->var.VendorGuid = EFI_GUID(0x74b00bd9, 0x805a, 0x4d61,
+ 0xb5, 0x1f, 0x43, 0x26,
+ 0x81, 0x23, 0xd1, 0x13);
+
+ err = efivar_entry_size(nvram_efivar, &data_len);
+ if (err)
+ goto fail;
+
+ data = kmalloc(data_len, GFP_KERNEL);
+ if (!data)
+ goto fail;
+
+ err = efivar_entry_get(nvram_efivar, NULL, &data_len, data);
+ if (err)
+ goto fail;
+
+ brcmf_info("Using nvram EFI variable\n");
+
+ kfree(nvram_efivar);
+ *data_len_ret = data_len;
+ return data;
+
+fail:
+ kfree(data);
+ kfree(nvram_efivar);
+ return NULL;
+}
+#else
+static u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
+#endif
+
static void brcmf_fw_free_request(struct brcmf_fw_request *req)
{
struct brcmf_fw_item *item;
@@ -463,11 +509,12 @@ static int brcmf_fw_request_nvram_done(c
{
struct brcmf_fw *fwctx = ctx;
struct brcmf_fw_item *cur;
+ bool free_bcm47xx_nvram = false;
+ bool kfree_nvram = false;
u32 nvram_length = 0;
void *nvram = NULL;
u8 *data = NULL;
size_t data_len;
- bool raw_nvram;
brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(fwctx->dev));
@@ -476,12 +523,13 @@ static int brcmf_fw_request_nvram_done(c
if (fw && fw->data) {
data = (u8 *)fw->data;
data_len = fw->size;
- raw_nvram = false;
} else {
- data = bcm47xx_nvram_get_contents(&data_len);
- if (!data && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
+ if ((data = bcm47xx_nvram_get_contents(&data_len)))
+ free_bcm47xx_nvram = true;
+ else if ((data = brcmf_fw_nvram_from_efi(&data_len)))
+ kfree_nvram = true;
+ else if (!(cur->flags & BRCMF_FW_REQF_OPTIONAL))
goto fail;
- raw_nvram = true;
}
if (data)
@@ -489,8 +537,11 @@ static int brcmf_fw_request_nvram_done(c
fwctx->req->domain_nr,
fwctx->req->bus_nr);
- if (raw_nvram)
+ if (free_bcm47xx_nvram)
bcm47xx_nvram_release_contents(data);
+ if (kfree_nvram)
+ kfree(data);
+
release_firmware(fw);
if (!nvram && !(cur->flags & BRCMF_FW_REQF_OPTIONAL))
goto fail;

View File

@@ -0,0 +1,97 @@
From 29ec3394f0bd85c22674ab6693d92da5e2324610 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 11 Oct 2018 11:51:07 +0200
Subject: [PATCH] brcmfmac: Fix ccode from EFI nvram when necessary
In some cases the EFI-var stored nvram contains "ccode=ALL" or "ccode=XV"
to specify "worldwide" compatible settings, but these 2 ccode-s do not work
properly.
I've tested the different known "worldwide" ccode-s used in various nvram
sources with the latest firmwares from linux-firmware for various brcmfmac
models, here is a simplified (*) table with what each setting results in:
ALL: 12-14 disab, U-NII-1, U-NII-2 no-IR/radar, U-NII-3
XV: 12-14 no-IR, disables all 5G channels
XY: 12-13 enab, 14 disab, U-NII-1 enab, U-NII-2 no-IR/radar, U-NII-3 disab
X2: 12-13 no-IR, 14 dis, U-NII-1 no-IR, U-NII-2 no-IR/radar, U-NII-3 no-IR
Where 12,13,14 are 2.4G channels 12-14 and U-NII-1/2/3 are the 3 different
5G channel groups. no-IR is no-Initiate-Radiation, we will never send on
these channels without first having received valid wifi traffic there.
This immediately shows that both ALL and XV are not as worldwide as we want
them to be. ALL causes channels 12 and 13 to not be available and XV causes
all 5GHz channels to not be available. Also ALL unconditionally enables the
U-NII-1 and U-NII-3 5G groups, while we really should be using no-IR for
these.
This commit replace XV and ALL with X2, which allows usage of chan 12-13
and 5G channels, but only after receiving valid wifi traffic there first.
Note that this configure the firmware's channel limits, the kernels own
regulatory restrictions based on e.g. regulatory info received from the
access-point, will be applied on top of this.
This fixes channels 12+13 not working on the Asus T200TA and the Lenovo
Mixx 2 8 and 5G channels not working on the Asus T100HA.
This has been tested on the following models: Acer Iconia Tab8 w1-810,
Acer One 10, Asus T100CHI, Asus T100HA, Asus T100TA, Asus T200TA and a
Lenovo Mixx 2 8.
*) There are some exceptions to this table:
1) On really old firmware e.g. linux-firmware's 2011 brcmfmac4330-sdio.bin
ALL really means all, unconditionally enabling everything
2) The exact meaning might be influenced by setting the regrev nvram var.
Specifically using ccode=XV + regrev=1 on brcmfmac43241b4 leads to:
12-14 no-ir, U-NII-1 no-ir, U-NII-2 no-ir/radar, U-NII-3 no-ir
But only on the brcmfmac43241b4 and not on e.g. the brcmfmac43340
Tested-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/firmware.c | 24 ++++++++++++++++++++++
1 file changed, 24 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -447,6 +447,29 @@ struct brcmf_fw {
static void brcmf_fw_request_done(const struct firmware *fw, void *ctx);
#ifdef CONFIG_EFI
+/* In some cases the EFI-var stored nvram contains "ccode=ALL" or "ccode=XV"
+ * to specify "worldwide" compatible settings, but these 2 ccode-s do not work
+ * properly. "ccode=ALL" causes channels 12 and 13 to not be available,
+ * "ccode=XV" causes all 5GHz channels to not be available. So we replace both
+ * with "ccode=X2" which allows channels 12+13 and 5Ghz channels in
+ * no-Initiate-Radiation mode. This means that we will never send on these
+ * channels without first having received valid wifi traffic on the channel.
+ */
+static void brcmf_fw_fix_efi_nvram_ccode(char *data, unsigned long data_len)
+{
+ char *ccode;
+
+ ccode = strnstr((char *)data, "ccode=ALL", data_len);
+ if (!ccode)
+ ccode = strnstr((char *)data, "ccode=XV\r", data_len);
+ if (!ccode)
+ return;
+
+ ccode[6] = 'X';
+ ccode[7] = '2';
+ ccode[8] = '\r';
+}
+
static u8 *brcmf_fw_nvram_from_efi(size_t *data_len_ret)
{
const u16 name[] = { 'n', 'v', 'r', 'a', 'm', 0 };
@@ -476,6 +499,7 @@ static u8 *brcmf_fw_nvram_from_efi(size_
if (err)
goto fail;
+ brcmf_fw_fix_efi_nvram_ccode(data, data_len);
brcmf_info("Using nvram EFI variable\n");
kfree(nvram_efivar);

View File

@@ -0,0 +1,34 @@
From e966a79c2f761a696dec9cfb0e2d4aa977bf78cb Mon Sep 17 00:00:00 2001
From: Colin Ian King <colin.king@canonical.com>
Date: Tue, 16 Oct 2018 18:43:42 +0100
Subject: [PATCH] brcmfmac: fix spelling mistake "Retreiving" -> "Retrieving"
Trivial fix to spelling mistake in brcmf_err error message.
Signed-off-by: Colin Ian King <colin.king@canonical.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -214,7 +214,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
err = brcmf_fil_iovar_data_get(ifp, "cur_etheraddr", ifp->mac_addr,
sizeof(ifp->mac_addr));
if (err < 0) {
- brcmf_err("Retreiving cur_etheraddr failed, %d\n", err);
+ brcmf_err("Retrieving cur_etheraddr failed, %d\n", err);
goto done;
}
memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN);
@@ -269,7 +269,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i
strcpy(buf, "ver");
err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf));
if (err < 0) {
- brcmf_err("Retreiving version information failed, %d\n",
+ brcmf_err("Retrieving version information failed, %d\n",
err);
goto done;
}

View File

@@ -0,0 +1,83 @@
From ae5848cb4511bbbfe0306fcdbe5d9a95cd9546a9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Fri, 26 Oct 2018 13:22:32 +0200
Subject: [PATCH] brcmutil: print invalid chanspec when WARN-ing
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
On one of my devices I got WARNINGs when brcmfmac tried to decode
chanspec. I couldn't tell if it was some unsupported format or just a
malformed value passed by a firmware.
Print chanspec value so it's possible to debug a possible problem.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmutil/d11.c
@@ -128,7 +128,7 @@ static void brcmu_d11n_decchspec(struct
}
break;
default:
- WARN_ON_ONCE(1);
+ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
break;
}
@@ -140,7 +140,7 @@ static void brcmu_d11n_decchspec(struct
ch->band = BRCMU_CHAN_BAND_2G;
break;
default:
- WARN_ON_ONCE(1);
+ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
break;
}
}
@@ -167,7 +167,7 @@ static void brcmu_d11ac_decchspec(struct
ch->sb = BRCMU_CHAN_SB_U;
ch->control_ch_num += CH_10MHZ_APART;
} else {
- WARN_ON_ONCE(1);
+ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
}
break;
case BRCMU_CHSPEC_D11AC_BW_80:
@@ -188,7 +188,7 @@ static void brcmu_d11ac_decchspec(struct
ch->control_ch_num += CH_30MHZ_APART;
break;
default:
- WARN_ON_ONCE(1);
+ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
break;
}
break;
@@ -222,13 +222,13 @@ static void brcmu_d11ac_decchspec(struct
ch->control_ch_num += CH_70MHZ_APART;
break;
default:
- WARN_ON_ONCE(1);
+ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
break;
}
break;
case BRCMU_CHSPEC_D11AC_BW_8080:
default:
- WARN_ON_ONCE(1);
+ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
break;
}
@@ -240,7 +240,7 @@ static void brcmu_d11ac_decchspec(struct
ch->band = BRCMU_CHAN_BAND_2G;
break;
default:
- WARN_ON_ONCE(1);
+ WARN_ONCE(1, "Invalid chanspec 0x%04x\n", ch->chspec);
break;
}
}

View File

@@ -0,0 +1,80 @@
From 4282ff17e557d319e1b988fa4f582792cfaf6fff Mon Sep 17 00:00:00 2001
From: Dan Haab <riproute@gmail.com>
Date: Fri, 9 Nov 2018 09:38:55 -0700
Subject: [PATCH] brcmfmac: support STA info struct v7
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The newest firmwares provide STA info using v7 of the struct. As v7
isn't backward compatible, a union is needed.
Even though brcmfmac does not use any of the new info it's important to
provide the proper struct buffer. Without this change new firmwares will
fallback to the very limited v3 instead of something in between such as
v4.
Signed-off-by: Dan Haab <dan.haab@luxul.com>
Reviewed-by: Rafał Miłecki <rafal@milecki.pl>
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/fwil_types.h | 40 +++++++++++++++----
1 file changed, 33 insertions(+), 7 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil_types.h
@@ -176,6 +176,8 @@
#define BRCMF_VHT_CAP_MCS_MAP_NSS_MAX 8
+#define BRCMF_HE_CAP_MCS_MAP_NSS_MAX 8
+
/* MAX_CHUNK_LEN is the maximum length for data passing to firmware in each
* ioctl. It is relatively small because firmware has small maximum size input
* playload restriction for ioctls.
@@ -601,13 +603,37 @@ struct brcmf_sta_info_le {
__le32 rx_pkts_retried; /* # rx with retry bit set */
__le32 tx_rate_fallback; /* lowest fallback TX rate */
- /* Fields valid for ver >= 5 */
- struct {
- __le32 count; /* # rates in this set */
- u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */
- u8 mcs[BRCMF_MCSSET_LEN]; /* supported mcs index bit map */
- __le16 vht_mcs[BRCMF_VHT_CAP_MCS_MAP_NSS_MAX]; /* supported mcs index bit map per nss */
- } rateset_adv;
+ union {
+ struct {
+ struct {
+ __le32 count; /* # rates in this set */
+ u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */
+ u8 mcs[BRCMF_MCSSET_LEN]; /* supported mcs index bit map */
+ __le16 vht_mcs[BRCMF_VHT_CAP_MCS_MAP_NSS_MAX]; /* supported mcs index bit map per nss */
+ } rateset_adv;
+ } v5;
+
+ struct {
+ __le32 rx_dur_total; /* total user RX duration (estimated) */
+ __le16 chanspec; /** chanspec this sta is on */
+ __le16 pad_1;
+ struct {
+ __le16 version; /* version */
+ __le16 len; /* length */
+ __le32 count; /* # rates in this set */
+ u8 rates[BRCMF_MAXRATES_IN_SET]; /* rates in 500kbps units w/hi bit set if basic */
+ u8 mcs[BRCMF_MCSSET_LEN]; /* supported mcs index bit map */
+ __le16 vht_mcs[BRCMF_VHT_CAP_MCS_MAP_NSS_MAX]; /* supported mcs index bit map per nss */
+ __le16 he_mcs[BRCMF_HE_CAP_MCS_MAP_NSS_MAX]; /* supported he mcs index bit map per nss */
+ } rateset_adv; /* rateset along with mcs index bitmap */
+ __le16 wpauth; /* authentication type */
+ u8 algo; /* crypto algorithm */
+ u8 pad_2;
+ __le32 tx_rspec; /* Rate of last successful tx frame */
+ __le32 rx_rspec; /* Rate of last successful rx frame */
+ __le32 wnm_cap; /* wnm capabilities */
+ } v7;
+ };
};
struct brcmf_chanspec_list {

View File

@@ -0,0 +1,39 @@
From 554da3868eb1d7174710c18b4ddd6ff01f6d612c Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Fri, 23 Nov 2018 10:11:48 +0100
Subject: [PATCH] brcmfmac: Call brcmf_dmi_probe before brcmf_of_probe
ARM systems with UEFI may have both devicetree (of) and DMI data in this
case we end up setting brcmf_mp_device.board_type twice.
In this case we should prefer the devicetree data, because:
1) The devicerree data is more reliable
2) Some ARM systems (e.g. the Raspberry Pi 3 models) support both UEFI and
classic uboot booting, the devicetree data is always there, so using it
makes sure we ask for the same nvram file independent of how we booted.
This commit moves the brcmf_dmi_probe call to before the brcmf_of_probe
call, so that the latter can override the value of the first if both are
set.
Fixes: bd1e82bb420a ("brcmfmac: Set board_type from DMI on x86 based ...")
Cc: Peter Robinson <pbrobinson@gmail.com>
Tested-and-reported-by: Peter Robinson <pbrobinson@gmail.com>
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -449,8 +449,8 @@ struct brcmf_mp_device *brcmf_get_module
}
if (!found) {
/* No platform data for this device, try OF and DMI data */
- brcmf_of_probe(dev, bus_type, settings);
brcmf_dmi_probe(settings, chip, chiprev);
+ brcmf_of_probe(dev, bus_type, settings);
}
return settings;
}

View File

@@ -0,0 +1,95 @@
From 153e22c0ff1260035cd7fe72c8aeead1f5fac757 Mon Sep 17 00:00:00 2001
From: Wright Feng <Wright.Feng@cypress.com>
Date: Mon, 5 Nov 2018 05:51:54 +0000
Subject: [PATCH] brcmfmac: add credit numbers updating support
The credit numbers are static and tunable per chip in firmware side.
However the credit number may be changed that is based on packet pool
length and will send BRCMF_E_FIFO_CREDIT_MAP event to notify host driver
updates the credit numbers during interface up.
The purpose of this patch is making host driver has ability of updating
the credit numbers when receiving the BRCMF_E_FIFO_CREDIT_MAP event.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/fwsignal.c | 23 ++++++++++++-------
1 file changed, 15 insertions(+), 8 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -511,6 +511,7 @@ struct brcmf_fws_info {
struct work_struct fws_dequeue_work;
u32 fifo_enqpkt[BRCMF_FWS_FIFO_COUNT];
int fifo_credit[BRCMF_FWS_FIFO_COUNT];
+ int init_fifo_credit[BRCMF_FWS_FIFO_COUNT];
int credits_borrowed[BRCMF_FWS_FIFO_AC_VO + 1];
int deq_node_pos[BRCMF_FWS_FIFO_COUNT];
u32 fifo_credit_map;
@@ -1245,6 +1246,9 @@ static void brcmf_fws_return_credits(str
}
fws->fifo_credit[fifo] += credits;
+ if (fws->fifo_credit[fifo] > fws->init_fifo_credit[fifo])
+ fws->fifo_credit[fifo] = fws->init_fifo_credit[fifo];
+
}
static void brcmf_fws_schedule_deq(struct brcmf_fws_info *fws)
@@ -1603,19 +1607,21 @@ static int brcmf_fws_notify_credit_map(s
brcmf_err("event payload too small (%d)\n", e->datalen);
return -EINVAL;
}
- if (fws->creditmap_received)
- return 0;
fws->creditmap_received = true;
brcmf_dbg(TRACE, "enter: credits %pM\n", credits);
brcmf_fws_lock(fws);
for (i = 0; i < ARRAY_SIZE(fws->fifo_credit); i++) {
- if (*credits)
+ fws->fifo_credit[i] += credits[i] - fws->init_fifo_credit[i];
+ fws->init_fifo_credit[i] = credits[i];
+ if (fws->fifo_credit[i] > 0)
fws->fifo_credit_map |= 1 << i;
else
fws->fifo_credit_map &= ~(1 << i);
- fws->fifo_credit[i] = *credits++;
+ WARN_ONCE(fws->fifo_credit[i] < 0,
+ "fifo_credit[%d] is negative(%d)\n", i,
+ fws->fifo_credit[i]);
}
brcmf_fws_schedule_deq(fws);
brcmf_fws_unlock(fws);
@@ -2021,7 +2027,7 @@ static int brcmf_fws_borrow_credit(struc
}
for (lender_ac = 0; lender_ac <= BRCMF_FWS_FIFO_AC_VO; lender_ac++) {
- if (fws->fifo_credit[lender_ac]) {
+ if (fws->fifo_credit[lender_ac] > 0) {
fws->credits_borrowed[lender_ac]++;
fws->fifo_credit[lender_ac]--;
if (fws->fifo_credit[lender_ac] == 0)
@@ -2220,8 +2226,9 @@ static void brcmf_fws_dequeue_worker(str
}
continue;
}
- while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) &&
- (fifo == BRCMF_FWS_FIFO_BCMC))) {
+ while ((fws->fifo_credit[fifo] > 0) ||
+ ((!fws->bcmc_credit_check) &&
+ (fifo == BRCMF_FWS_FIFO_BCMC))) {
skb = brcmf_fws_deq(fws, fifo);
if (!skb)
break;
@@ -2232,7 +2239,7 @@ static void brcmf_fws_dequeue_worker(str
break;
}
if ((fifo == BRCMF_FWS_FIFO_AC_BE) &&
- (fws->fifo_credit[fifo] == 0) &&
+ (fws->fifo_credit[fifo] <= 0) &&
(!fws->bus_flow_blocked)) {
while (brcmf_fws_borrow_credit(fws) == 0) {
skb = brcmf_fws_deq(fws, fifo);

View File

@@ -0,0 +1,42 @@
From a3bdc6deb60bf6be4405058ca49a686c4db08c39 Mon Sep 17 00:00:00 2001
From: Wright Feng <Wright.Feng@cypress.com>
Date: Mon, 5 Nov 2018 05:51:59 +0000
Subject: [PATCH] brcmfmac: enable frameburst mode in default firmware setting
The frameburst feature can enable per-packet framebursting in firmware
side and get higher TX throughput in High Throughput(HT) mode. To enhance
TX throughput, we enable frameburst mode in default firmware setting.
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 6 ++++++
drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h | 1 +
2 files changed, 7 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c
@@ -6654,6 +6654,12 @@ static s32 brcmf_config_dongle(struct br
brcmf_configure_arp_nd_offload(ifp, true);
+ err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1);
+ if (err) {
+ brcmf_err("failed to set frameburst mode\n");
+ goto default_conf_out;
+ }
+
cfg->dongle_up = true;
default_conf_out:
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.h
@@ -80,6 +80,7 @@
#define BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON 201
#define BRCMF_C_SET_ASSOC_PREFER 205
#define BRCMF_C_GET_VALID_CHANNELS 217
+#define BRCMF_C_SET_FAKEFRAG 219
#define BRCMF_C_GET_KEY_PRIMARY 235
#define BRCMF_C_SET_KEY_PRIMARY 236
#define BRCMF_C_SET_SCAN_PASSIVE_TIME 258

View File

@@ -0,0 +1,229 @@
From e4af3ffb43d50f070134aa1b40d5c3573f57deb1 Mon Sep 17 00:00:00 2001
From: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Date: Mon, 5 Nov 2018 05:52:05 +0000
Subject: [PATCH] brcmfmac: handle compressed tx status signal
Firmware inform the driver about tx status by normal tx status signal
or compressed tx status signal. This patch adds support to handle the
compressed tx status signal.
Signed-off-by: Chung-Hsien Hsu <stanley.hsu@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/fwsignal.c | 121 ++++++++++--------
1 file changed, 71 insertions(+), 50 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c
@@ -1463,9 +1463,10 @@ static int brcmf_fws_txstatus_suppressed
static int
brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
- u32 genbit, u16 seq)
+ u32 genbit, u16 seq, u8 compcnt)
{
u32 fifo;
+ u8 cnt = 0;
int ret;
bool remove_from_hanger = true;
struct sk_buff *skb;
@@ -1476,60 +1477,71 @@ brcmf_fws_txs_process(struct brcmf_fws_i
brcmf_dbg(DATA, "flags %d\n", flags);
if (flags == BRCMF_FWS_TXSTATUS_DISCARD)
- fws->stats.txs_discard++;
+ fws->stats.txs_discard += compcnt;
else if (flags == BRCMF_FWS_TXSTATUS_CORE_SUPPRESS) {
- fws->stats.txs_supp_core++;
+ fws->stats.txs_supp_core += compcnt;
remove_from_hanger = false;
} else if (flags == BRCMF_FWS_TXSTATUS_FW_PS_SUPPRESS) {
- fws->stats.txs_supp_ps++;
+ fws->stats.txs_supp_ps += compcnt;
remove_from_hanger = false;
} else if (flags == BRCMF_FWS_TXSTATUS_FW_TOSSED)
- fws->stats.txs_tossed++;
+ fws->stats.txs_tossed += compcnt;
else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)
- fws->stats.txs_host_tossed++;
+ fws->stats.txs_host_tossed += compcnt;
else
brcmf_err("unexpected txstatus\n");
- ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
- remove_from_hanger);
- if (ret != 0) {
- brcmf_err("no packet in hanger slot: hslot=%d\n", hslot);
- return ret;
- }
+ while (cnt < compcnt) {
+ ret = brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb,
+ remove_from_hanger);
+ if (ret != 0) {
+ brcmf_err("no packet in hanger slot: hslot=%d\n",
+ hslot);
+ goto cont;
+ }
- skcb = brcmf_skbcb(skb);
- entry = skcb->mac;
- if (WARN_ON(!entry)) {
- brcmu_pkt_buf_free_skb(skb);
- return -EINVAL;
- }
- entry->transit_count--;
- if (entry->suppressed && entry->suppr_transit_count)
- entry->suppr_transit_count--;
-
- brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name, flags,
- skcb->htod, seq);
-
- /* pick up the implicit credit from this packet */
- fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
- if ((fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT) ||
- (brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
- (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED)) {
- brcmf_fws_return_credits(fws, fifo, 1);
- brcmf_fws_schedule_deq(fws);
- }
- brcmf_fws_macdesc_return_req_credit(skb);
+ skcb = brcmf_skbcb(skb);
+ entry = skcb->mac;
+ if (WARN_ON(!entry)) {
+ brcmu_pkt_buf_free_skb(skb);
+ goto cont;
+ }
+ entry->transit_count--;
+ if (entry->suppressed && entry->suppr_transit_count)
+ entry->suppr_transit_count--;
- ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
- if (ret) {
- brcmu_pkt_buf_free_skb(skb);
- return -EINVAL;
+ brcmf_dbg(DATA, "%s flags %d htod %X seq %X\n", entry->name,
+ flags, skcb->htod, seq);
+
+ /* pick up the implicit credit from this packet */
+ fifo = brcmf_skb_htod_tag_get_field(skb, FIFO);
+ if (fws->fcmode == BRCMF_FWS_FCMODE_IMPLIED_CREDIT ||
+ (brcmf_skb_if_flags_get_field(skb, REQ_CREDIT)) ||
+ flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED) {
+ brcmf_fws_return_credits(fws, fifo, 1);
+ brcmf_fws_schedule_deq(fws);
+ }
+ brcmf_fws_macdesc_return_req_credit(skb);
+
+ ret = brcmf_proto_hdrpull(fws->drvr, false, skb, &ifp);
+ if (ret) {
+ brcmu_pkt_buf_free_skb(skb);
+ goto cont;
+ }
+ if (!remove_from_hanger)
+ ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
+ genbit, seq);
+ if (remove_from_hanger || ret)
+ brcmf_txfinalize(ifp, skb, true);
+
+cont:
+ hslot = (hslot + 1) & (BRCMF_FWS_TXSTAT_HSLOT_MASK >>
+ BRCMF_FWS_TXSTAT_HSLOT_SHIFT);
+ if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode))
+ seq = (seq + 1) & BRCMF_SKB_HTOD_SEQ_NR_MASK;
+
+ cnt++;
}
- if (!remove_from_hanger)
- ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb,
- genbit, seq);
- if (remove_from_hanger || ret)
- brcmf_txfinalize(ifp, skb, true);
return 0;
}
@@ -1555,7 +1567,8 @@ static int brcmf_fws_fifocreditback_indi
return BRCMF_FWS_RET_OK_SCHEDULE;
}
-static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
+static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 type,
+ u8 *data)
{
__le32 status_le;
__le16 seq_le;
@@ -1564,23 +1577,31 @@ static int brcmf_fws_txstatus_indicate(s
u32 genbit;
u8 flags;
u16 seq;
+ u8 compcnt;
+ u8 compcnt_offset = BRCMF_FWS_TYPE_TXSTATUS_LEN;
- fws->stats.txs_indicate++;
memcpy(&status_le, data, sizeof(status_le));
status = le32_to_cpu(status_le);
flags = brcmf_txstatus_get_field(status, FLAGS);
hslot = brcmf_txstatus_get_field(status, HSLOT);
genbit = brcmf_txstatus_get_field(status, GENERATION);
if (BRCMF_FWS_MODE_GET_REUSESEQ(fws->mode)) {
- memcpy(&seq_le, &data[BRCMF_FWS_TYPE_PKTTAG_LEN],
+ memcpy(&seq_le, &data[BRCMF_FWS_TYPE_TXSTATUS_LEN],
sizeof(seq_le));
seq = le16_to_cpu(seq_le);
+ compcnt_offset += BRCMF_FWS_TYPE_SEQ_LEN;
} else {
seq = 0;
}
+ if (type == BRCMF_FWS_TYPE_COMP_TXSTATUS)
+ compcnt = data[compcnt_offset];
+ else
+ compcnt = 1;
+ fws->stats.txs_indicate += compcnt;
+
brcmf_fws_lock(fws);
- brcmf_fws_txs_process(fws, flags, hslot, genbit, seq);
+ brcmf_fws_txs_process(fws, flags, hslot, genbit, seq, compcnt);
brcmf_fws_unlock(fws);
return BRCMF_FWS_RET_OK_NOSCHEDULE;
}
@@ -1896,8 +1917,6 @@ void brcmf_fws_hdrpull(struct brcmf_if *
err = BRCMF_FWS_RET_OK_NOSCHEDULE;
switch (type) {
- case BRCMF_FWS_TYPE_COMP_TXSTATUS:
- break;
case BRCMF_FWS_TYPE_HOST_REORDER_RXPKTS:
rd = (struct brcmf_skb_reorder_data *)skb->cb;
rd->reorder = data;
@@ -1920,7 +1939,8 @@ void brcmf_fws_hdrpull(struct brcmf_if *
err = brcmf_fws_request_indicate(fws, type, data);
break;
case BRCMF_FWS_TYPE_TXSTATUS:
- brcmf_fws_txstatus_indicate(fws, data);
+ case BRCMF_FWS_TYPE_COMP_TXSTATUS:
+ brcmf_fws_txstatus_indicate(fws, type, data);
break;
case BRCMF_FWS_TYPE_FIFO_CREDITBACK:
err = brcmf_fws_fifocreditback_indicate(fws, data);
@@ -2009,7 +2029,7 @@ static void brcmf_fws_rollback_toq(struc
fws->stats.rollback_failed++;
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
- hslot, 0, 0);
+ hslot, 0, 0, 1);
} else {
fws->stats.rollback_success++;
brcmf_fws_return_credits(fws, fifo, 1);
@@ -2480,7 +2500,8 @@ void brcmf_fws_bustxfail(struct brcmf_fw
}
brcmf_fws_lock(fws);
hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
- brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0);
+ brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, hslot, 0, 0,
+ 1);
brcmf_fws_unlock(fws);
}

View File

@@ -0,0 +1,36 @@
From eb6b33bfb8f56859df7264dccc2ca8ab7c57342a Mon Sep 17 00:00:00 2001
From: Winnie Chang <winnie.chang@cypress.com>
Date: Wed, 21 Nov 2018 07:53:42 +0000
Subject: [PATCH] brcmfmac: add 4354 raw pcie device id
Add the raw 4354 PCIe device ID for unprogrammed Cypress boards.
Reviewed-by: Arend Van Spriel <arend@broadcom.com>
Signed-off-by: Winnie Chang <winnie.chang@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 1 +
drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h | 1 +
2 files changed, 2 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -2019,6 +2019,7 @@ static const struct dev_pm_ops brcmf_pci
static const struct pci_device_id brcmf_pcie_devid_table[] = {
BRCMF_PCIE_DEVICE(BRCM_PCIE_4350_DEVICE_ID),
BRCMF_PCIE_DEVICE_SUB(0x4355, BRCM_PCIE_VENDOR_ID_BROADCOM, 0x4355),
+ BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_RAW_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -74,6 +74,7 @@
/* PCIE Device IDs */
#define BRCM_PCIE_4350_DEVICE_ID 0x43a3
#define BRCM_PCIE_4354_DEVICE_ID 0x43df
+#define BRCM_PCIE_4354_RAW_DEVICE_ID 0x4354
#define BRCM_PCIE_4356_DEVICE_ID 0x43ec
#define BRCM_PCIE_43567_DEVICE_ID 0x43d3
#define BRCM_PCIE_43570_DEVICE_ID 0x43d9

View File

@@ -0,0 +1,253 @@
From 35cb51b2162a1a7c5cd977f92595e60ab14d3b22 Mon Sep 17 00:00:00 2001
From: Chi-Hsien Lin <Chi-Hsien.Lin@cypress.com>
Date: Wed, 21 Nov 2018 07:53:47 +0000
Subject: [PATCH] brcmfmac: add support for CYW43012 SDIO chipset
CYW43012 is a 1x1 802.11a/b/g/n Dual-Band HT20, 256-QAM/Turbo QAM. It
is an Ultra Low Power WLAN+BT combo chip.
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Praveen Babu C <praveen.chandran@cypress.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/bcmsdh.c | 1 +
.../broadcom/brcm80211/brcmfmac/chip.c | 14 +++-
.../broadcom/brcm80211/brcmfmac/sdio.c | 74 ++++++++++++++++---
.../broadcom/brcm80211/include/brcm_hw_ids.h | 1 +
include/linux/mmc/sdio_ids.h | 1 +
5 files changed, 78 insertions(+), 13 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c
@@ -970,6 +970,7 @@ static const struct sdio_device_id brcmf
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4356),
BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_4373),
+ BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_CYPRESS_43012),
{ /* end: all zeroes */ }
};
MODULE_DEVICE_TABLE(sdio, brcmf_sdmmc_ids);
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -165,6 +165,7 @@ struct sbconfig {
#define SRCI_LSS_MASK 0x00f00000
#define SRCI_LSS_SHIFT 20
#define SRCI_SRNB_MASK 0xf0
+#define SRCI_SRNB_MASK_EXT 0x100
#define SRCI_SRNB_SHIFT 4
#define SRCI_SRBSZ_MASK 0xf
#define SRCI_SRBSZ_SHIFT 0
@@ -592,7 +593,13 @@ static void brcmf_chip_socram_ramsize(st
if (lss != 0)
*ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
} else {
- nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ /* length of SRAM Banks increased for corerev greater than 23 */
+ if (sr->pub.rev >= 23) {
+ nb = (coreinfo & (SRCI_SRNB_MASK | SRCI_SRNB_MASK_EXT))
+ >> SRCI_SRNB_SHIFT;
+ } else {
+ nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
+ }
for (i = 0; i < nb; i++) {
retent = brcmf_chip_socram_banksize(sr, i, &banksize);
*ramsize += banksize;
@@ -1356,6 +1363,11 @@ bool brcmf_chip_sr_capable(struct brcmf_
addr = CORE_CC_REG(base, sr_control1);
reg = chip->ops->read32(chip->ctx, addr);
return reg != 0;
+ case CY_CC_43012_CHIP_ID:
+ addr = CORE_CC_REG(pmu->base, retention_ctl);
+ reg = chip->ops->read32(chip->ctx, addr);
+ return (reg & (PMU_RCTL_MACPHY_DISABLE_MASK |
+ PMU_RCTL_LOGIC_DISABLE_MASK)) == 0;
default:
addr = CORE_CC_REG(pmu->base, pmucapabilities_ext);
reg = chip->ops->read32(chip->ctx, addr);
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -624,6 +624,7 @@ BRCMF_FW_DEF(43455, "brcmfmac43455-sdio"
BRCMF_FW_DEF(4354, "brcmfmac4354-sdio");
BRCMF_FW_DEF(4356, "brcmfmac4356-sdio");
BRCMF_FW_DEF(4373, "brcmfmac4373-sdio");
+BRCMF_FW_DEF(43012, "brcmfmac43012-sdio");
static const struct brcmf_firmware_mapping brcmf_sdio_fwnames[] = {
BRCMF_FW_ENTRY(BRCM_CC_43143_CHIP_ID, 0xFFFFFFFF, 43143),
@@ -643,7 +644,8 @@ static const struct brcmf_firmware_mappi
BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455),
BRCMF_FW_ENTRY(BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, 4354),
BRCMF_FW_ENTRY(BRCM_CC_4356_CHIP_ID, 0xFFFFFFFF, 4356),
- BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373)
+ BRCMF_FW_ENTRY(CY_CC_4373_CHIP_ID, 0xFFFFFFFF, 4373),
+ BRCMF_FW_ENTRY(CY_CC_43012_CHIP_ID, 0xFFFFFFFF, 43012)
};
static void pkt_align(struct sk_buff *p, int len, int align)
@@ -683,6 +685,14 @@ brcmf_sdio_kso_control(struct brcmf_sdio
/* 1st KSO write goes to AOS wake up core if device is asleep */
brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_SLEEPCSR, wr_val, &err);
+ /* In case of 43012 chip, the chip could go down immediately after
+ * KSO bit is cleared. So the further reads of KSO register could
+ * fail. Thereby just bailing out immediately after clearing KSO
+ * bit, to avoid polling of KSO bit.
+ */
+ if (!on && bus->ci->chip == CY_CC_43012_CHIP_ID)
+ return err;
+
if (on) {
/* device WAKEUP through KSO:
* write bit 0 & read back until
@@ -2416,6 +2426,14 @@ static int brcmf_sdio_tx_ctrlframe(struc
return ret;
}
+static bool brcmf_chip_is_ulp(struct brcmf_chip *ci)
+{
+ if (ci->chip == CY_CC_43012_CHIP_ID)
+ return true;
+ else
+ return false;
+}
+
static void brcmf_sdio_bus_stop(struct device *dev)
{
struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -2423,7 +2441,7 @@ static void brcmf_sdio_bus_stop(struct d
struct brcmf_sdio *bus = sdiodev->bus;
struct brcmf_core *core = bus->sdio_core;
u32 local_hostintmask;
- u8 saveclk;
+ u8 saveclk, bpreq;
int err;
brcmf_dbg(TRACE, "Enter\n");
@@ -2450,9 +2468,14 @@ static void brcmf_sdio_bus_stop(struct d
/* Force backplane clocks to assure F2 interrupt propagates */
saveclk = brcmf_sdiod_readb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
&err);
- if (!err)
- brcmf_sdiod_writeb(sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
- (saveclk | SBSDIO_FORCE_HT), &err);
+ if (!err) {
+ bpreq = saveclk;
+ bpreq |= brcmf_chip_is_ulp(bus->ci) ?
+ SBSDIO_HT_AVAIL_REQ : SBSDIO_FORCE_HT;
+ brcmf_sdiod_writeb(sdiodev,
+ SBSDIO_FUNC1_CHIPCLKCSR,
+ bpreq, &err);
+ }
if (err)
brcmf_err("Failed to force clock for F2: err %d\n",
err);
@@ -3345,20 +3368,45 @@ err:
return bcmerror;
}
+static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
+{
+ if (bus->ci->chip == CY_CC_43012_CHIP_ID)
+ return true;
+ else
+ return false;
+}
+
static void brcmf_sdio_sr_init(struct brcmf_sdio *bus)
{
int err = 0;
u8 val;
+ u8 wakeupctrl;
+ u8 cardcap;
+ u8 chipclkcsr;
brcmf_dbg(TRACE, "Enter\n");
+ if (brcmf_chip_is_ulp(bus->ci)) {
+ wakeupctrl = SBSDIO_FUNC1_WCTRL_ALPWAIT_SHIFT;
+ chipclkcsr = SBSDIO_HT_AVAIL_REQ;
+ } else {
+ wakeupctrl = SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
+ chipclkcsr = SBSDIO_FORCE_HT;
+ }
+
+ if (brcmf_sdio_aos_no_decode(bus)) {
+ cardcap = SDIO_CCCR_BRCM_CARDCAP_CMD_NODEC;
+ } else {
+ cardcap = (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
+ SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT);
+ }
+
val = brcmf_sdiod_readb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, &err);
if (err) {
brcmf_err("error reading SBSDIO_FUNC1_WAKEUPCTRL\n");
return;
}
-
- val |= 1 << SBSDIO_FUNC1_WCTRL_HTWAIT_SHIFT;
+ val |= 1 << wakeupctrl;
brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_WAKEUPCTRL, val, &err);
if (err) {
brcmf_err("error writing SBSDIO_FUNC1_WAKEUPCTRL\n");
@@ -3367,8 +3415,7 @@ static void brcmf_sdio_sr_init(struct br
/* Add CMD14 Support */
brcmf_sdiod_func0_wb(bus->sdiodev, SDIO_CCCR_BRCM_CARDCAP,
- (SDIO_CCCR_BRCM_CARDCAP_CMD14_SUPPORT |
- SDIO_CCCR_BRCM_CARDCAP_CMD14_EXT),
+ cardcap,
&err);
if (err) {
brcmf_err("error writing SDIO_CCCR_BRCM_CARDCAP\n");
@@ -3376,7 +3423,7 @@ static void brcmf_sdio_sr_init(struct br
}
brcmf_sdiod_writeb(bus->sdiodev, SBSDIO_FUNC1_CHIPCLKCSR,
- SBSDIO_FORCE_HT, &err);
+ chipclkcsr, &err);
if (err) {
brcmf_err("error writing SBSDIO_FUNC1_CHIPCLKCSR\n");
return;
@@ -4071,7 +4118,7 @@ static void brcmf_sdio_firmware_callback
const struct firmware *code;
void *nvram;
u32 nvram_len;
- u8 saveclk;
+ u8 saveclk, bpreq;
u8 devctl;
brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err);
@@ -4105,8 +4152,11 @@ static void brcmf_sdio_firmware_callback
/* Force clocks on backplane to be sure F2 interrupt propagates */
saveclk = brcmf_sdiod_readb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR, &err);
if (!err) {
+ bpreq = saveclk;
+ bpreq |= brcmf_chip_is_ulp(bus->ci) ?
+ SBSDIO_HT_AVAIL_REQ : SBSDIO_FORCE_HT;
brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_CHIPCLKCSR,
- (saveclk | SBSDIO_FORCE_HT), &err);
+ bpreq, &err);
}
if (err) {
brcmf_err("Failed to force clock for F2: err %d\n", err);
--- a/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/brcm_hw_ids.h
@@ -60,6 +60,7 @@
#define BRCM_CC_43664_CHIP_ID 43664
#define BRCM_CC_4371_CHIP_ID 0x4371
#define CY_CC_4373_CHIP_ID 0x4373
+#define CY_CC_43012_CHIP_ID 43012
/* USB Device IDs */
#define BRCM_USB_43143_DEVICE_ID 0xbd1e
--- a/include/linux/mmc/sdio_ids.h
+++ b/include/linux/mmc/sdio_ids.h
@@ -42,6 +42,7 @@
#define SDIO_DEVICE_ID_BROADCOM_4354 0x4354
#define SDIO_DEVICE_ID_BROADCOM_4356 0x4356
#define SDIO_DEVICE_ID_CYPRESS_4373 0x4373
+#define SDIO_DEVICE_ID_CYPRESS_43012 43012
#define SDIO_VENDOR_ID_INTEL 0x0089
#define SDIO_DEVICE_ID_INTEL_IWMC3200WIMAX 0x1402

View File

@@ -0,0 +1,60 @@
From b021a6bc1175442609af0b66d64f850883e155fb Mon Sep 17 00:00:00 2001
From: Chi-Hsien Lin <Chi-Hsien.Lin@cypress.com>
Date: Wed, 21 Nov 2018 07:53:48 +0000
Subject: [PATCH] brcmfmac: allow GCI core enumuration
GCI core is needed for ULP operation. Allow GCI core enumuration with
below changes:
- Allow GCI to be added to core list even when it doesn't have a wrapper.
- Allow 8K address space size.
- Don't overwrite the address value when an additional size descriptor
is in place.
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../wireless/broadcom/brcm80211/brcmfmac/chip.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -786,7 +786,7 @@ static int brcmf_chip_dmp_get_regaddr(st
u32 *regbase, u32 *wrapbase)
{
u8 desc;
- u32 val;
+ u32 val, szdesc;
u8 mpnum = 0;
u8 stype, sztype, wraptype;
@@ -832,14 +832,15 @@ static int brcmf_chip_dmp_get_regaddr(st
/* next size descriptor can be skipped */
if (sztype == DMP_SLAVE_SIZE_DESC) {
- val = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
+ szdesc = brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
/* skip upper size descriptor if present */
- if (val & DMP_DESC_ADDRSIZE_GT32)
+ if (szdesc & DMP_DESC_ADDRSIZE_GT32)
brcmf_chip_dmp_get_desc(ci, eromaddr, NULL);
}
- /* only look for 4K register regions */
- if (sztype != DMP_SLAVE_SIZE_4K)
+ /* look for 4K or 8K register regions */
+ if (sztype != DMP_SLAVE_SIZE_4K &&
+ sztype != DMP_SLAVE_SIZE_8K)
continue;
stype = (val & DMP_SLAVE_TYPE) >> DMP_SLAVE_TYPE_S;
@@ -896,7 +897,8 @@ int brcmf_chip_dmp_erom_scan(struct brcm
/* need core with ports */
if (nmw + nsw == 0 &&
- id != BCMA_CORE_PMU)
+ id != BCMA_CORE_PMU &&
+ id != BCMA_CORE_GCI)
continue;
/* try to obtain register address info */

View File

@@ -0,0 +1,49 @@
From f95a8d9c6aca196f1ace5b2e53a3dd3bc491b1b3 Mon Sep 17 00:00:00 2001
From: Naveen Gupta <naveen.gupta@cypress.com>
Date: Wed, 21 Nov 2018 07:53:49 +0000
Subject: [PATCH] brcmfmac: update 43012 F2 watermark setting to fix DMA Error
during UDP RX Traffic
The number of words that the read FIFO has to contain except
the end of frame before sends data back to the host.
Max watermark = (512B - 2* (BurstLength))/4 =
(512 - 128)/4 = 384/4 = 0x60
so if burst length (i.e. BurstLength = 64) is increased,
watermark has to be reduced. This is the optimal setting for this chip.
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Naveen Gupta <naveen.gupta@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -52,6 +52,7 @@
/* watermark expressed in number of words */
#define DEFAULT_F2_WATERMARK 0x8
#define CY_4373_F2_WATERMARK 0x40
+#define CY_43012_F2_WATERMARK 0x60
#ifdef DEBUG
@@ -4193,6 +4194,17 @@ static void brcmf_sdio_firmware_callback
CY_4373_F2_WATERMARK |
SBSDIO_MESBUSYCTRL_ENAB, &err);
break;
+ case SDIO_DEVICE_ID_CYPRESS_43012:
+ brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n",
+ CY_43012_F2_WATERMARK);
+ brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK,
+ CY_43012_F2_WATERMARK, &err);
+ devctl = brcmf_sdiod_readb(sdiod, SBSDIO_DEVICE_CTL,
+ &err);
+ devctl |= SBSDIO_DEVCTL_F2WM_ENAB;
+ brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl,
+ &err);
+ break;
default:
brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK,
DEFAULT_F2_WATERMARK, &err);

View File

@@ -0,0 +1,57 @@
From 2f2d389efda4caa4c1b69cb4fa2ab217f0fe6d6f Mon Sep 17 00:00:00 2001
From: Chi-Hsien Lin <Chi-Hsien.Lin@cypress.com>
Date: Wed, 21 Nov 2018 07:53:50 +0000
Subject: [PATCH] brcmfmac: 4373 save-restore support
Use chipcommon sr_control0 register to check 4373 sr support.
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/chip.c | 5 +++++
.../broadcom/brcm80211/include/chipcommon.h | 19 +++++++++++++++++++
2 files changed, 24 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c
@@ -1365,6 +1365,11 @@ bool brcmf_chip_sr_capable(struct brcmf_
addr = CORE_CC_REG(base, sr_control1);
reg = chip->ops->read32(chip->ctx, addr);
return reg != 0;
+ case CY_CC_4373_CHIP_ID:
+ /* explicitly check SR engine enable bit */
+ addr = CORE_CC_REG(base, sr_control0);
+ reg = chip->ops->read32(chip->ctx, addr);
+ return (reg & CC_SR_CTL0_ENABLE_MASK) != 0;
case CY_CC_43012_CHIP_ID:
addr = CORE_CC_REG(pmu->base, retention_ctl);
reg = chip->ops->read32(chip->ctx, addr);
--- a/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
+++ b/drivers/net/wireless/broadcom/brcm80211/include/chipcommon.h
@@ -269,6 +269,25 @@ struct chipcregs {
/* GSIO (spi/i2c) present, rev >= 37 */
#define CC_CAP2_GSIO 0x00000002
+/* sr_control0, rev >= 48 */
+#define CC_SR_CTL0_ENABLE_MASK BIT(0)
+#define CC_SR_CTL0_ENABLE_SHIFT 0
+#define CC_SR_CTL0_EN_SR_ENG_CLK_SHIFT 1 /* sr_clk to sr_memory enable */
+#define CC_SR_CTL0_RSRC_TRIGGER_SHIFT 2 /* Rising edge resource trigger 0 to
+ * sr_engine
+ */
+#define CC_SR_CTL0_MIN_DIV_SHIFT 6 /* Min division value for fast clk
+ * in sr_engine
+ */
+#define CC_SR_CTL0_EN_SBC_STBY_SHIFT 16
+#define CC_SR_CTL0_EN_SR_ALP_CLK_MASK_SHIFT 18
+#define CC_SR_CTL0_EN_SR_HT_CLK_SHIFT 19
+#define CC_SR_CTL0_ALLOW_PIC_SHIFT 20 /* Allow pic to separate power
+ * domains
+ */
+#define CC_SR_CTL0_MAX_SR_LQ_CLK_CNT_SHIFT 25
+#define CC_SR_CTL0_EN_MEM_DISABLE_FOR_SLEEP 30
+
/* pmucapabilities */
#define PCAP_REV_MASK 0x000000ff
#define PCAP_RC_MASK 0x00001f00

View File

@@ -0,0 +1,45 @@
From 29f6589140a10ece8c1d73f58043ea5b3473ab3e Mon Sep 17 00:00:00 2001
From: Wright Feng <wright.feng@cypress.com>
Date: Wed, 21 Nov 2018 07:53:52 +0000
Subject: [PATCH] brcmfmac: disable command decode in sdio_aos
AOS is a part of the SDIOD core that becomes active when the rest of
SDIOD is sleeping to keep SDIO bus alive responding to reduced set of
commands.
Transaction between AOS and SDIOD is not protected, and if cmd 52 is
received in AOS and in the middle of response state changed from AOS to
SDIOD, response is corrupted and it causes to SDIO Host controller to
hang.
Command decode for below chips are disabled in this commit:
- 4339
- 4345
- 4354
- 4373
Reviewed-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Wright Feng <wright.feng@cypress.com>
Signed-off-by: Double Lo <double.lo@cypress.com>
Signed-off-by: Madhan Mohan R <madhanmohan.r@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c
@@ -3371,7 +3371,11 @@ err:
static bool brcmf_sdio_aos_no_decode(struct brcmf_sdio *bus)
{
- if (bus->ci->chip == CY_CC_43012_CHIP_ID)
+ if (bus->ci->chip == CY_CC_43012_CHIP_ID ||
+ bus->ci->chip == CY_CC_4373_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4339_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4345_CHIP_ID ||
+ bus->ci->chip == BRCM_CC_4354_CHIP_ID)
return true;
else
return false;

View File

@@ -0,0 +1,34 @@
From 412dd15c8177d93abe0c8787b83b31c5eb061405 Mon Sep 17 00:00:00 2001
From: Arnd Bergmann <arnd@arndb.de>
Date: Mon, 10 Dec 2018 21:55:37 +0100
Subject: [PATCH] brcmfmac: fix false-positive -Wmaybe-unintialized warning
When CONFIG_NO_AUTO_INLINE is set, we get a false-postive warning
for the brcmf_fw_request_nvram_done() function, after gcc figures
out that brcmf_fw_nvram_from_efi() might not set the 'data_len'
variable, but fails to notice that it always returns NULL:
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c: In function 'brcmf_fw_request_nvram_done':
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c:560:11: error: 'data_len' may be used uninitialized in this function [-Werror=maybe-uninitialized]
Mark it 'inline' to force gcc to understand this.
Fixes: ce2e6db554fa ("brcmfmac: Add support for getting nvram contents from EFI variables")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c
@@ -512,7 +512,7 @@ fail:
return NULL;
}
#else
-static u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
+static inline u8 *brcmf_fw_nvram_from_efi(size_t *data_len) { return NULL; }
#endif
static void brcmf_fw_free_request(struct brcmf_fw_request *req)

View File

@@ -0,0 +1,51 @@
From 4d95f99c59b8b814bcf09ba86020d937ec7caa86 Mon Sep 17 00:00:00 2001
From: Hans de Goede <hdegoede@redhat.com>
Date: Thu, 20 Dec 2018 17:40:58 +0100
Subject: [PATCH] brcmfmac: Add DMI nvram filename quirk for PoV TAB-P1006W-232
tablet
The Point of View TAB-P1006W-232 tablet contains quite generic names in
the sys_vendor and product_name DMI strings, without this patch brcmfmac
will try to load: brcmfmac43340-sdio.Insyde-BayTrail.txt as nvram file
which is a bit too generic.
Add a DMI quirk so that a unique and clearly identifiable nvram file
name is used on the PoV TAB-P1006W-232 tablet.
Signed-off-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../wireless/broadcom/brcm80211/brcmfmac/dmi.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/dmi.c
@@ -43,6 +43,10 @@ static const struct brcmf_dmi_data meego
BRCM_CC_43340_CHIP_ID, 2, "meegopad-t08"
};
+static const struct brcmf_dmi_data pov_tab_p1006w_data = {
+ BRCM_CC_43340_CHIP_ID, 2, "pov-tab-p1006w-data"
+};
+
static const struct dmi_system_id dmi_platform_data[] = {
{
/* Match for the GPDwin which unfortunately uses somewhat
@@ -81,6 +85,17 @@ static const struct dmi_system_id dmi_pl
},
.driver_data = (void *)&meegopad_t08_data,
},
+ {
+ /* Point of View TAB-P1006W-232 */
+ .matches = {
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "Insyde"),
+ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "BayTrail"),
+ /* Note 105b is Foxcon's USB/PCI vendor id */
+ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "105B"),
+ DMI_EXACT_MATCH(DMI_BOARD_NAME, "0E57"),
+ },
+ .driver_data = (void *)&pov_tab_p1006w_data,
+ },
{}
};

View File

@@ -0,0 +1,28 @@
From 42daad3343be4a4e1ee03e30a5f5cc731dadfef5 Mon Sep 17 00:00:00 2001
From: Kangjie Lu <kjlu@umn.edu>
Date: Tue, 25 Dec 2018 19:22:24 -0600
Subject: [PATCH] brcmfmac: add a check for the status of usb_register
usb_register() may fail, so let's check its status and issue an error
message if it fails.
Signed-off-by: Kangjie Lu <kjlu@umn.edu>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c
@@ -1558,6 +1558,10 @@ void brcmf_usb_exit(void)
void brcmf_usb_register(void)
{
+ int ret;
+
brcmf_dbg(USB, "Enter\n");
- usb_register(&brcmf_usbdrvr);
+ ret = usb_register(&brcmf_usbdrvr);
+ if (ret)
+ brcmf_err("usb_register failed %d\n", ret);
}

View File

@@ -0,0 +1,33 @@
From 3a33bd840523aaa06f4429fbfd38922bf0dc2e8d Mon Sep 17 00:00:00 2001
From: Lo-Hsiang Lo <double.lo@cypress.com>
Date: Mon, 7 Jan 2019 08:46:16 +0000
Subject: [PATCH] brcmfmac: fix system warning message during wowl suspend
There is a system warning message, warn_slowpath-fmt, during suspend
while using supplicant join AP and enable wowl feature by IW command.
It's caused by brcmf_pno_remove_request path can't find the reqid.
This fix will not go to remove pno request function if there is no
pno scan.
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Lo-Hsiang Lo <double.lo@cypress.com>
Signed-off-by: Chi-Hsien Lin <chi-hsien.lin@cypress.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c
@@ -496,6 +496,11 @@ int brcmf_pno_stop_sched_scan(struct brc
brcmf_dbg(TRACE, "reqid=%llu\n", reqid);
pi = ifp_to_pno(ifp);
+
+ /* No PNO request */
+ if (!pi->n_reqs)
+ return 0;
+
err = brcmf_pno_remove_request(pi, reqid);
if (err)
return err;

View File

@@ -0,0 +1,104 @@
From 5cc898fbcb352b764f8d51c16e10e2eb0056173d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Wed, 6 Feb 2019 12:28:15 +0100
Subject: [PATCH] brcmfmac: modify __brcmf_err() to take bus as a parameter
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
So far __brcmf_err() was using pr_err() which didn't allow identifying
device that was affected by an error. It's crucial for systems with more
than 1 device supported by brcmfmac (a common case for home routers).
This change allows passing struct brcmf_bus to the __brcmf_err(). That
struct has been agreed to be the most common one. It allows accessing
struct device easily & using dev_err() printing helper.
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Acked-by: Arend van Spriel <arend.vanspriel@broadcom.com>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../net/wireless/broadcom/brcm80211/brcmfmac/common.c | 7 +++++--
drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 8 +++++---
.../wireless/broadcom/brcm80211/brcmfmac/tracepoint.c | 9 +++++++--
3 files changed, 17 insertions(+), 7 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c
@@ -350,7 +350,7 @@ done:
}
#ifndef CPTCFG_BRCM_TRACING
-void __brcmf_err(const char *func, const char *fmt, ...)
+void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
@@ -359,7 +359,10 @@ void __brcmf_err(const char *func, const
vaf.fmt = fmt;
vaf.va = &args;
- pr_err("%s: %pV", func, &vaf);
+ if (bus)
+ dev_err(bus->dev, "%s: %pV", func, &vaf);
+ else
+ pr_err("%s: %pV", func, &vaf);
va_end(args);
}
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
@@ -45,8 +45,10 @@
#undef pr_fmt
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-__printf(2, 3)
-void __brcmf_err(const char *func, const char *fmt, ...);
+struct brcmf_bus;
+
+__printf(3, 4)
+void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...);
/* Macro for error messages. When debugging / tracing the driver all error
* messages are important to us.
*/
@@ -55,7 +57,7 @@ void __brcmf_err(const char *func, const
if (IS_ENABLED(CPTCFG_BRCMDBG) || \
IS_ENABLED(CPTCFG_BRCM_TRACING) || \
net_ratelimit()) \
- __brcmf_err(__func__, fmt, ##__VA_ARGS__); \
+ __brcmf_err(NULL, __func__, fmt, ##__VA_ARGS__);\
} while (0)
#if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/tracepoint.c
@@ -14,14 +14,16 @@
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
+#include <linux/device.h>
#include <linux/module.h> /* bug in tracepoint.h, it should include this */
#ifndef __CHECKER__
#define CREATE_TRACE_POINTS
+#include "bus.h"
#include "tracepoint.h"
#include "debug.h"
-void __brcmf_err(const char *func, const char *fmt, ...)
+void __brcmf_err(struct brcmf_bus *bus, const char *func, const char *fmt, ...)
{
struct va_format vaf = {
.fmt = fmt,
@@ -30,7 +32,10 @@ void __brcmf_err(const char *func, const
va_start(args, fmt);
vaf.va = &args;
- pr_err("%s: %pV", func, &vaf);
+ if (bus)
+ dev_err(bus->dev, "%s: %pV", func, &vaf);
+ else
+ pr_err("%s: %pV", func, &vaf);
trace_brcmf_err(func, &vaf);
va_end(args);
}

View File

@@ -0,0 +1,266 @@
From 8602e62441aba276cafd68034b72162fbc5ca0a6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl>
Date: Wed, 6 Feb 2019 12:28:16 +0100
Subject: [PATCH] brcmfmac: pass bus to the __brcmf_err() in pcie.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This enables dev_err() usage (instead of pr_err()) in the __brcmf_err().
It makes error messages more meaningful and is important for debugging
errors/bugs on systems with multiple brcmfmac supported devices.
All bus files should follow & get updated similarly (soon).
Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Signed-off-by: Kalle Valo <kvalo@codeaurora.org>
---
.../broadcom/brcm80211/brcmfmac/debug.h | 2 +
.../broadcom/brcm80211/brcmfmac/pcie.c | 59 +++++++++++--------
2 files changed, 38 insertions(+), 23 deletions(-)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h
@@ -52,6 +52,7 @@ void __brcmf_err(struct brcmf_bus *bus,
/* Macro for error messages. When debugging / tracing the driver all error
* messages are important to us.
*/
+#ifndef brcmf_err
#define brcmf_err(fmt, ...) \
do { \
if (IS_ENABLED(CPTCFG_BRCMDBG) || \
@@ -59,6 +60,7 @@ void __brcmf_err(struct brcmf_bus *bus,
net_ratelimit()) \
__brcmf_err(NULL, __func__, fmt, ##__VA_ARGS__);\
} while (0)
+#endif
#if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING)
--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c
@@ -30,6 +30,15 @@
#include <brcmu_wifi.h>
#include <brcm_hw_ids.h>
+/* Custom brcmf_err() that takes bus arg and passes it further */
+#define brcmf_err(bus, fmt, ...) \
+ do { \
+ if (IS_ENABLED(CPTCFG_BRCMDBG) || \
+ IS_ENABLED(CPTCFG_BRCM_TRACING) || \
+ net_ratelimit()) \
+ __brcmf_err(bus, __func__, fmt, ##__VA_ARGS__); \
+ } while (0)
+
#include "debug.h"
#include "bus.h"
#include "commonring.h"
@@ -531,6 +540,7 @@ static void
brcmf_pcie_select_core(struct brcmf_pciedev_info *devinfo, u16 coreid)
{
const struct pci_dev *pdev = devinfo->pdev;
+ struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
struct brcmf_core *core;
u32 bar0_win;
@@ -548,7 +558,7 @@ brcmf_pcie_select_core(struct brcmf_pcie
}
}
} else {
- brcmf_err("Unsupported core selected %x\n", coreid);
+ brcmf_err(bus, "Unsupported core selected %x\n", coreid);
}
}
@@ -848,9 +858,8 @@ static irqreturn_t brcmf_pcie_isr_thread
static int brcmf_pcie_request_irq(struct brcmf_pciedev_info *devinfo)
{
- struct pci_dev *pdev;
-
- pdev = devinfo->pdev;
+ struct pci_dev *pdev = devinfo->pdev;
+ struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
brcmf_pcie_intr_disable(devinfo);
@@ -861,7 +870,7 @@ static int brcmf_pcie_request_irq(struct
brcmf_pcie_isr_thread, IRQF_SHARED,
"brcmf_pcie_intr", devinfo)) {
pci_disable_msi(pdev);
- brcmf_err("Failed to request IRQ %d\n", pdev->irq);
+ brcmf_err(bus, "Failed to request IRQ %d\n", pdev->irq);
return -EIO;
}
devinfo->irq_allocated = true;
@@ -871,15 +880,14 @@ static int brcmf_pcie_request_irq(struct
static void brcmf_pcie_release_irq(struct brcmf_pciedev_info *devinfo)
{
- struct pci_dev *pdev;
+ struct pci_dev *pdev = devinfo->pdev;
+ struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
u32 status;
u32 count;
if (!devinfo->irq_allocated)
return;
- pdev = devinfo->pdev;
-
brcmf_pcie_intr_disable(devinfo);
free_irq(pdev->irq, devinfo);
pci_disable_msi(pdev);
@@ -891,7 +899,7 @@ static void brcmf_pcie_release_irq(struc
count++;
}
if (devinfo->in_irq)
- brcmf_err("Still in IRQ (processing) !!!\n");
+ brcmf_err(bus, "Still in IRQ (processing) !!!\n");
status = brcmf_pcie_read_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT);
brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_PCIE2REG_MAILBOXINT, status);
@@ -1102,6 +1110,7 @@ static void brcmf_pcie_release_ringbuffe
static int brcmf_pcie_init_ringbuffers(struct brcmf_pciedev_info *devinfo)
{
+ struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
struct brcmf_pcie_ringbuf *ring;
struct brcmf_pcie_ringbuf *rings;
u32 d2h_w_idx_ptr;
@@ -1254,7 +1263,7 @@ static int brcmf_pcie_init_ringbuffers(s
return 0;
fail:
- brcmf_err("Allocating ring buffers failed\n");
+ brcmf_err(bus, "Allocating ring buffers failed\n");
brcmf_pcie_release_ringbuffers(devinfo);
return -ENOMEM;
}
@@ -1277,6 +1286,7 @@ brcmf_pcie_release_scratchbuffers(struct
static int brcmf_pcie_init_scratchbuffers(struct brcmf_pciedev_info *devinfo)
{
+ struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
u64 address;
u32 addr;
@@ -1316,7 +1326,7 @@ static int brcmf_pcie_init_scratchbuffer
return 0;
fail:
- brcmf_err("Allocating scratch buffers failed\n");
+ brcmf_err(bus, "Allocating scratch buffers failed\n");
brcmf_pcie_release_scratchbuffers(devinfo);
return -ENOMEM;
}
@@ -1437,6 +1447,7 @@ static int
brcmf_pcie_init_share_ram_info(struct brcmf_pciedev_info *devinfo,
u32 sharedram_addr)
{
+ struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
struct brcmf_pcie_shared_info *shared;
u32 addr;
@@ -1448,7 +1459,8 @@ brcmf_pcie_init_share_ram_info(struct br
brcmf_dbg(PCIE, "PCIe protocol version %d\n", shared->version);
if ((shared->version > BRCMF_PCIE_MAX_SHARED_VERSION) ||
(shared->version < BRCMF_PCIE_MIN_SHARED_VERSION)) {
- brcmf_err("Unsupported PCIE version %d\n", shared->version);
+ brcmf_err(bus, "Unsupported PCIE version %d\n",
+ shared->version);
return -EINVAL;
}
@@ -1490,6 +1502,7 @@ static int brcmf_pcie_download_fw_nvram(
const struct firmware *fw, void *nvram,
u32 nvram_len)
{
+ struct brcmf_bus *bus = dev_get_drvdata(&devinfo->pdev->dev);
u32 sharedram_addr;
u32 sharedram_addr_written;
u32 loop_counter;
@@ -1544,7 +1557,7 @@ static int brcmf_pcie_download_fw_nvram(
loop_counter--;
}
if (sharedram_addr == sharedram_addr_written) {
- brcmf_err("FW failed to initialize\n");
+ brcmf_err(bus, "FW failed to initialize\n");
return -ENODEV;
}
brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr);
@@ -1555,16 +1568,15 @@ static int brcmf_pcie_download_fw_nvram(
static int brcmf_pcie_get_resource(struct brcmf_pciedev_info *devinfo)
{
- struct pci_dev *pdev;
+ struct pci_dev *pdev = devinfo->pdev;
+ struct brcmf_bus *bus = dev_get_drvdata(&pdev->dev);
int err;
phys_addr_t bar0_addr, bar1_addr;
ulong bar1_size;
- pdev = devinfo->pdev;
-
err = pci_enable_device(pdev);
if (err) {
- brcmf_err("pci_enable_device failed err=%d\n", err);
+ brcmf_err(bus, "pci_enable_device failed err=%d\n", err);
return err;
}
@@ -1577,7 +1589,7 @@ static int brcmf_pcie_get_resource(struc
/* read Bar-1 mapped memory range */
bar1_size = pci_resource_len(pdev, 2);
if ((bar1_size == 0) || (bar1_addr == 0)) {
- brcmf_err("BAR1 Not enabled, device size=%ld, addr=%#016llx\n",
+ brcmf_err(bus, "BAR1 Not enabled, device size=%ld, addr=%#016llx\n",
bar1_size, (unsigned long long)bar1_addr);
return -EINVAL;
}
@@ -1586,7 +1598,7 @@ static int brcmf_pcie_get_resource(struc
devinfo->tcm = ioremap_nocache(bar1_addr, bar1_size);
if (!devinfo->regs || !devinfo->tcm) {
- brcmf_err("ioremap() failed (%p,%p)\n", devinfo->regs,
+ brcmf_err(bus, "ioremap() failed (%p,%p)\n", devinfo->regs,
devinfo->tcm);
return -EINVAL;
}
@@ -1873,7 +1885,7 @@ fail_bus:
kfree(bus->msgbuf);
kfree(bus);
fail:
- brcmf_err("failed %x:%x\n", pdev->vendor, pdev->device);
+ brcmf_err(NULL, "failed %x:%x\n", pdev->vendor, pdev->device);
brcmf_pcie_release_resource(devinfo);
if (devinfo->ci)
brcmf_chip_detach(devinfo->ci);
@@ -1947,7 +1959,7 @@ static int brcmf_pcie_pm_enter_D3(struct
wait_event_timeout(devinfo->mbdata_resp_wait, devinfo->mbdata_completed,
BRCMF_PCIE_MBDATA_TIMEOUT);
if (!devinfo->mbdata_completed) {
- brcmf_err("Timeout on response for entering D3 substate\n");
+ brcmf_err(bus, "Timeout on response for entering D3 substate\n");
brcmf_bus_change_state(bus, BRCMF_BUS_UP);
return -EIO;
}
@@ -1993,7 +2005,7 @@ cleanup:
err = brcmf_pcie_probe(pdev, NULL);
if (err)
- brcmf_err("probe after resume failed, err=%d\n", err);
+ brcmf_err(bus, "probe after resume failed, err=%d\n", err);
return err;
}
@@ -2066,7 +2078,8 @@ void brcmf_pcie_register(void)
brcmf_dbg(PCIE, "Enter\n");
err = pci_register_driver(&brcmf_pciedrvr);
if (err)
- brcmf_err("PCIE driver registration failed, err=%d\n", err);
+ brcmf_err(NULL, "PCIE driver registration failed, err=%d\n",
+ err);
}

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