diff --git a/config/Config-build.in b/config/Config-build.in index d882abd9d9..21c23de3cb 100644 --- a/config/Config-build.in +++ b/config/Config-build.in @@ -7,6 +7,13 @@ menu "Global build settings" + config JSON_ADD_IMAGE_INFO + bool "Create JSON info files per build image" + default BUILDBOT + help + The JSON info files contain information about the device and + build images, stored next to the firmware images. + config ALL_NONSHARED bool "Select all target specific packages by default" select ALL_KMODS diff --git a/config/Config-images.in b/config/Config-images.in index 7f8dfa941e..c331ad24dc 100644 --- a/config/Config-images.in +++ b/config/Config-images.in @@ -78,7 +78,7 @@ menu "Target Images" menuconfig TARGET_ROOTFS_EXT4FS bool "ext4" - default y if USES_EXT4 + default n help Build an ext4 root filesystem. diff --git a/include/image.mk b/include/image.mk index f0d3379bbc..6fb9cb56fd 100644 --- a/include/image.mk +++ b/include/image.mk @@ -42,6 +42,8 @@ IMG_PREFIX_VERNUM:=$(if $(CONFIG_VERSION_FILENAMES),$(call sanitize,$(VERSION_NU IMG_PREFIX_VERCODE:=$(if $(CONFIG_VERSION_CODE_FILENAMES),$(call sanitize,$(VERSION_CODE))-) IMG_PREFIX:=$(VERSION_DIST_SANITIZED)-$(IMG_PREFIX_VERNUM)$(IMG_PREFIX_VERCODE)$(IMG_PREFIX_EXTRA)$(BOARD)$(if $(SUBTARGET),-$(SUBTARGET)) +IMG_ROOTFS:=$(IMG_PREFIX)-rootfs +IMG_COMBINED:=$(IMG_PREFIX)-combined MKFS_DEVTABLE_OPT := -D $(INCLUDE_DIR)/device_table.txt @@ -104,7 +106,7 @@ define add_jffs2_mark echo -ne '\xde\xad\xc0\xde' >> $(1) endef -PROFILE_SANITIZED := $(call sanitize,$(PROFILE)) +PROFILE_SANITIZED := $(call tolower,$(subst DEVICE_,,$(subst $(space),-,$(PROFILE)))) define split_args $(foreach data, \ @@ -152,6 +154,43 @@ ifdef CONFIG_TARGET_IMAGES_GZIP endef endif + +# Disable noisy checks by default as in upstream +ifeq ($(strip $(call kernel_patchver_ge,4.7.0)),1) + DTC_FLAGS += -Wno-unit_address_vs_reg +endif +ifeq ($(strip $(call kernel_patchver_ge,4.12.0)),1) + DTC_FLAGS += \ + -Wno-unit_address_vs_reg \ + -Wno-simple_bus_reg \ + -Wno-unit_address_format \ + -Wno-pci_bridge \ + -Wno-pci_device_bus_num \ + -Wno-pci_device_reg +endif +ifeq ($(strip $(call kernel_patchver_ge,4.17.0)),1) + DTC_FLAGS += \ + -Wno-avoid_unnecessary_addr_size \ + -Wno-alias_paths +endif +ifeq ($(strip $(call kernel_patchver_ge,4.18.0)),1) + DTC_FLAGS += \ + -Wno-graph_child_address \ + -Wno-graph_port \ + -Wno-unique_unit_address +endif + +define Image/pad-to + dd if=$(1) of=$(1).new bs=$(2) conv=sync + mv $(1).new $(1) +endef + +ROOTFS_PARTSIZE=$(shell echo $$(($(CONFIG_TARGET_ROOTFS_PARTSIZE)*1024*1024))) + +define Image/pad-root-squashfs + $(call Image/pad-to,$(KDIR)/root.squashfs,$(if $(1),$(1),$(ROOTFS_PARTSIZE))) +endef + # $(1) source dts file # $(2) target dtb file # $(3) extra CPP flags @@ -164,7 +203,7 @@ define Image/BuildDTB -undef -D__DTS__ $(3) \ -o $(2).tmp $(1) $(LINUX_DIR)/scripts/dtc/dtc -O dtb \ - -i$(dir $(1)) $(4) \ + -i$(dir $(1)) $(DTC_FLAGS) $(4) \ -o $(2) $(2).tmp $(RM) $(2).tmp endef @@ -203,8 +242,7 @@ define Image/mkfs/squashfs $(STAGING_DIR_HOST)/bin/mksquashfs4 $(call mkfs_target_dir,$(1)) $@ \ -nopad -noappend -root-owned \ -comp $(SQUASHFSCOMP) $(SQUASHFSOPT) \ - -processors 16 \ - $(if $(SOURCE_DATE_EPOCH),-fixed-time $(SOURCE_DATE_EPOCH)) + -processors 16 endef # $(1): board name @@ -248,11 +286,9 @@ define Image/mkfs/ubifs -o $@ -d $(call mkfs_target_dir,$(1)) endef -E2SIZE=$(shell echo $$(($(CONFIG_TARGET_ROOTFS_PARTSIZE)*1024*1024))) - define Image/mkfs/ext4 $(STAGING_DIR_HOST)/bin/make_ext4fs \ - -l $(E2SIZE) -b $(CONFIG_TARGET_EXT4_BLOCKSIZE) \ + -l $(ROOTFS_PARTSIZE) -b $(CONFIG_TARGET_EXT4_BLOCKSIZE) \ $(if $(CONFIG_TARGET_EXT4_RESERVED_PCT),-m $(CONFIG_TARGET_EXT4_RESERVED_PCT)) \ $(if $(CONFIG_TARGET_EXT4_JOURNAL),,-J) \ $(if $(SOURCE_DATE_EPOCH),-T $(SOURCE_DATE_EPOCH)) \ @@ -264,9 +300,26 @@ define Image/Manifest $(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED)).manifest endef +define Image/gzip-ext4-padded-squashfs + + define Image/Build/squashfs + $(call Image/pad-root-squashfs) + endef + + ifneq ($(CONFIG_TARGET_IMAGES_GZIP),) + define Image/Build/gzip/ext4 + $(call Image/Build/gzip,ext4) + endef + define Image/Build/gzip/squashfs + $(call Image/Build/gzip,squashfs) + endef + endif + +endef + ifdef CONFIG_TARGET_ROOTFS_TARGZ define Image/Build/targz - $(TAR) -cp --numeric-owner --owner=0 --group=0 --sort=name \ + $(TAR) -cp --numeric-owner --owner=0 --group=0 --mode=a-s --sort=name \ $(if $(SOURCE_DATE_EPOCH),--mtime="@$(SOURCE_DATE_EPOCH)") \ -C $(TARGET_DIR)/ . | gzip -9n > $(BIN_DIR)/$(IMG_PREFIX)$(if $(PROFILE_SANITIZED),-$(PROFILE_SANITIZED))-rootfs.tar.gz endef @@ -274,13 +327,13 @@ endif ifdef CONFIG_TARGET_ROOTFS_CPIOGZ define Image/Build/cpiogz - ( cd $(TARGET_DIR); find . | cpio -o -H newc -R root:root | gzip -9n >$(BIN_DIR)/$(IMG_PREFIX)-rootfs.cpio.gz ) + ( cd $(TARGET_DIR); find . | cpio -o -H newc -R root:root | gzip -9n >$(BIN_DIR)/$(IMG_ROOTFS).cpio.gz ) endef endif mkfs_packages = $(filter-out @%,$(PACKAGES_$(call param_get,pkg,pkg=$(target_params)))) -mkfs_packages_add = $(filter-out -%,$(mkfs_packages)) -mkfs_packages_remove = $(patsubst -%,%,$(filter -%,$(mkfs_packages))) +mkfs_packages_add = $(foreach pkg,$(filter-out -%,$(mkfs_packages)),$(pkg)$(call GetABISuffix,$(pkg))) +mkfs_packages_remove = $(foreach pkg,$(patsubst -%,%,$(filter -%,$(mkfs_packages))),$(pkg)$(call GetABISuffix,$(pkg))) mkfs_cur_target_dir = $(call mkfs_target_dir,pkg=$(target_params)) opkg_target = \ @@ -308,7 +361,22 @@ $(KDIR)/root.%: kernel_prepare define Device/InitProfile PROFILES := $(PROFILE) - DEVICE_TITLE := + DEVICE_TITLE = $$(DEVICE_VENDOR) $$(DEVICE_MODEL)$$(if $$(DEVICE_VARIANT), $$(DEVICE_VARIANT)) + DEVICE_ALT0_TITLE = $$(DEVICE_ALT0_VENDOR) $$(DEVICE_ALT0_MODEL)$$(if $$(DEVICE_ALT0_VARIANT), $$(DEVICE_ALT0_VARIANT)) + DEVICE_ALT1_TITLE = $$(DEVICE_ALT1_VENDOR) $$(DEVICE_ALT1_MODEL)$$(if $$(DEVICE_ALT1_VARIANT), $$(DEVICE_ALT1_VARIANT)) + DEVICE_ALT2_TITLE = $$(DEVICE_ALT2_VENDOR) $$(DEVICE_ALT2_MODEL)$$(if $$(DEVICE_ALT2_VARIANT), $$(DEVICE_ALT2_VARIANT)) + DEVICE_VENDOR := + DEVICE_MODEL := + DEVICE_VARIANT := + DEVICE_ALT0_VENDOR := + DEVICE_ALT0_MODEL := + DEVICE_ALT0_VARIANT := + DEVICE_ALT1_VENDOR := + DEVICE_ALT1_MODEL := + DEVICE_ALT1_VARIANT := + DEVICE_ALT2_VENDOR := + DEVICE_ALT2_MODEL := + DEVICE_ALT2_VARIANT := DEVICE_PACKAGES := DEVICE_DESCRIPTION = Build firmware images for $$(DEVICE_TITLE) endef @@ -358,15 +426,22 @@ define Device/Init IMAGE_METADATA := FILESYSTEMS := $(TARGET_FILESYSTEMS) + + UBOOT_PATH := $(STAGING_DIR_IMAGE)/uboot-$(1) + + DEFAULT := endef DEFAULT_DEVICE_VARS := \ - DEVICE_NAME KERNEL KERNEL_INITRAMFS KERNEL_SIZE KERNEL_INITRAMFS_IMAGE \ - KERNEL_LOADADDR DEVICE_DTS DEVICE_DTS_CONFIG DEVICE_DTS_DIR BOARD_NAME \ - CMDLINE UBOOTENV_IN_UBI KERNEL_IN_UBI \ - BLOCKSIZE PAGESIZE SUBPAGESIZE VID_HDR_OFFSET \ - UBINIZE_OPTS UIMAGE_NAME UBINIZE_PARTS \ - SUPPORTED_DEVICES IMAGE_METADATA + DEVICE_NAME KERNEL KERNEL_INITRAMFS KERNEL_INITRAMFS_IMAGE KERNEL_SIZE \ + CMDLINE UBOOTENV_IN_UBI KERNEL_IN_UBI BLOCKSIZE PAGESIZE SUBPAGESIZE \ + VID_HDR_OFFSET UBINIZE_OPTS UBINIZE_PARTS MKUBIFS_OPTS DEVICE_DTS \ + DEVICE_DTS_CONFIG DEVICE_DTS_DIR BOARD_NAME UIMAGE_NAME SUPPORTED_DEVICES \ + IMAGE_METADATA KERNEL_ENTRY KERNEL_LOADADDR UBOOT_PATH DEVICE_VENDOR \ + DEVICE_MODEL DEVICE_VARIANT \ + DEVICE_ALT0_VENDOR DEVICE_ALT0_MODEL DEVICE_ALT0_VARIANT \ + DEVICE_ALT1_VENDOR DEVICE_ALT1_MODEL DEVICE_ALT1_VARIANT \ + DEVICE_ALT2_VENDOR DEVICE_ALT2_MODEL DEVICE_ALT2_VARIANT define Device/ExportVar $(1) : $(2):=$$($(2)) @@ -496,11 +571,37 @@ define Device/Build/image $(BIN_DIR)/$(call IMAGE_NAME,$(1),$(2)): $(KDIR)/tmp/$(call IMAGE_NAME,$(1),$(2)) cp $$^ $$@ - + $(if $(CONFIG_JSON_ADD_IMAGE_INFO), \ + DEVICE_ID="$(DEVICE_NAME)" \ + BIN_DIR="$(BIN_DIR)" \ + IMAGE_NAME="$(IMAGE_NAME)" \ + IMAGE_TYPE=$(word 1,$(subst ., ,$(2))) \ + IMAGE_PREFIX="$(IMAGE_PREFIX)" \ + DEVICE_VENDOR="$(DEVICE_VENDOR)" \ + DEVICE_MODEL="$(DEVICE_MODEL)" \ + DEVICE_VARIANT="$(DEVICE_VARIANT)" \ + DEVICE_ALT0_VENDOR="$(DEVICE_ALT0_VENDOR)" \ + DEVICE_ALT0_MODEL="$(DEVICE_ALT0_MODEL)" \ + DEVICE_ALT0_VARIANT="$(DEVICE_ALT0_VARIANT)" \ + DEVICE_ALT1_VENDOR="$(DEVICE_ALT1_VENDOR)" \ + DEVICE_ALT1_MODEL="$(DEVICE_ALT1_MODEL)" \ + DEVICE_ALT1_VARIANT="$(DEVICE_ALT1_VARIANT)" \ + DEVICE_ALT2_VENDOR="$(DEVICE_ALT2_VENDOR)" \ + DEVICE_ALT2_MODEL="$(DEVICE_ALT2_MODEL)" \ + DEVICE_ALT2_VARIANT="$(DEVICE_ALT2_VARIANT)" \ + DEVICE_TITLE="$(DEVICE_TITLE)" \ + TARGET="$(BOARD)" \ + SUBTARGET="$(SUBTARGET)" \ + VERSION_NUMBER="$(VERSION_NUMBER)" \ + VERSION_CODE="$(VERSION_CODE)" \ + SUPPORTED_DEVICES="$(SUPPORTED_DEVICES)" \ + $(TOPDIR)/scripts/json_add_image_info.py \ + ) endef define Device/Build/artifact $$(_TARGET): $(BIN_DIR)/$(IMAGE_PREFIX)-$(1) + $(eval $(call Device/Export,$(KDIR)/tmp/$(IMAGE_PREFIX)-$(1))) $(KDIR)/tmp/$(IMAGE_PREFIX)-$(1): $$(KDIR_KERNEL_IMAGE) @rm -f $$@ $$(call concat_cmd,$(ARTIFACT/$(1))) @@ -513,6 +614,8 @@ define Device/Build/artifact endef define Device/Build + $(shell rm -f $(BIN_DIR)/$(IMG_PREFIX)-$(1).json) + $(if $(CONFIG_TARGET_ROOTFS_INITRAMFS),$(call Device/Build/initramfs,$(1))) $(call Device/Build/kernel,$(1)) @@ -530,15 +633,35 @@ endef define Device/DumpInfo Target-Profile: DEVICE_$(1) -Target-Profile-Name: $(DEVICE_TITLE) +Target-Profile-Name: $(DEVICE_DISPLAY) Target-Profile-Packages: $(DEVICE_PACKAGES) +Target-Profile-hasImageMetadata: $(if $(foreach image,$(IMAGES),$(findstring append-metadata,$(IMAGE/$(image)))),1,0) +Target-Profile-SupportedDevices: $(SUPPORTED_DEVICES) +$(if $(DEFAULT),Target-Profile-Default: $(DEFAULT)) Target-Profile-Description: $(DEVICE_DESCRIPTION) +$(if $(strip $(DEVICE_ALT0_TITLE)),Alternative device titles: +- $(DEVICE_ALT0_TITLE)) +$(if $(strip $(DEVICE_ALT1_TITLE)),- $(DEVICE_ALT1_TITLE)) +$(if $(strip $(DEVICE_ALT2_TITLE)),- $(DEVICE_ALT2_TITLE)) @@ endef define Device/Dump +ifneq ($$(strip $$(DEVICE_ALT0_TITLE)),) +DEVICE_DISPLAY = $$(DEVICE_ALT0_TITLE) ($$(DEVICE_TITLE)) +$$(info $$(call Device/DumpInfo,$(1))) +endif +ifneq ($$(strip $$(DEVICE_ALT1_TITLE)),) +DEVICE_DISPLAY = $$(DEVICE_ALT1_TITLE) ($$(DEVICE_TITLE)) +$$(info $$(call Device/DumpInfo,$(1))) +endif +ifneq ($$(strip $$(DEVICE_ALT2_TITLE)),) +DEVICE_DISPLAY = $$(DEVICE_ALT2_TITLE) ($$(DEVICE_TITLE)) +$$(info $$(call Device/DumpInfo,$(1))) +endif +DEVICE_DISPLAY = $$(DEVICE_TITLE) $$(eval $$(if $$(DEVICE_TITLE),$$(info $$(call Device/DumpInfo,$(1))))) endef @@ -581,7 +704,7 @@ define BuildImage $(call Image/Prepare) legacy-images-prepare-make: image_prepare - $(MAKE) legacy-images-prepare + $(MAKE) legacy-images-prepare BIN_DIR="$(BIN_DIR)" else image_prepare: @@ -605,7 +728,7 @@ define BuildImage legacy-images-make: install-images $(call Image/mkfs/ubifs/legacy) - $(MAKE) legacy-images + $(MAKE) legacy-images BIN_DIR="$(BIN_DIR)" install: install-images $(call Image/Manifest) diff --git a/package/firmware/brcmfmac-board-rpi/Makefile b/package/firmware/brcmfmac-board-rpi/Makefile index 4268d9124c..e622280ba8 100644 --- a/package/firmware/brcmfmac-board-rpi/Makefile +++ b/package/firmware/brcmfmac-board-rpi/Makefile @@ -8,25 +8,8 @@ PKG_FLAGS:=nonshared include $(INCLUDE_DIR)/package.mk BRCMFMAC434XX_SDIO_URL:=@GITHUB/RPi-Distro/firmware-nonfree/$(PKG_RELEASE)/brcm/ -BRCMFMAC43430_SDIO_FILE:=brcmfmac43430-sdio-$(PKG_RELEASE) BRCMFMAC43455_SDIO_FILE:=brcmfmac43455-sdio-$(PKG_RELEASE) -define Download/brcmfmac43430_sdio_txt - FILE:=$(BRCMFMAC43430_SDIO_FILE).txt - URL:=$(BRCMFMAC434XX_SDIO_URL) - URL_FILE:=brcmfmac43430-sdio.txt - HASH:=e4ce7ad5ce72406f958ed758539b65d958d1c0eb3e46e3f8e9f02b510d88e0b0 -endef -$(eval $(call Download,brcmfmac43430_sdio_txt)) - -define Download/brcmfmac43455_sdio_txt - FILE:=$(BRCMFMAC43455_SDIO_FILE).txt - URL:=$(BRCMFMAC434XX_SDIO_URL) - URL_FILE:=brcmfmac43455-sdio.txt - HASH:=15698c62457bcf25e60d063e6c666d6e1b7dacdf2b03e6d14ebbc619de6da6b7 -endef -$(eval $(call Download,brcmfmac43455_sdio_txt)) - define Download/brcmfmac43455_sdio_clm_blob FILE:=$(BRCMFMAC43455_SDIO_FILE).clm_blob URL:=$(BRCMFMAC434XX_SDIO_URL) @@ -43,29 +26,18 @@ define Package/brcmfmac-board-rpi/Default PKGARCH:=all endef -define Package/brcmfmac-board-rpi2 - $(call Package/brcmfmac-board-rpi/Default) - TITLE:=BCM43430 RPi SDIO NVRAM -endef - -define Package/brcmfmac-board-rpi2/description - NVRAM for the Broadcom BCM43430 on RPi boards. -endef - -define Package/brcmfmac-board-rpi3 +define Package/brcmfmac-firmware-43455-clm_blob $(call Package/brcmfmac-board-rpi/Default) - TITLE:=BCM43455 RPi SDIO NVRAM + TITLE:=BCM43455 RPi SDIO Localisation Blob endef -define Package/brcmfmac-board-rpi3/description - NVRAM and localisations blob for the Broadcom BCM43455 on RPi boards. +define Package/brcmfmac-firmware-43455-clm_blob/description + Localisation blob for the Broadcom BCM43455 on RPi boards. endef define Build/Prepare rm -rf $(PKG_BUILD_DIR) mkdir -p $(PKG_BUILD_DIR) - cp $(DL_DIR)/$(BRCMFMAC43430_SDIO_FILE).txt $(PKG_BUILD_DIR)/brcmfmac43430-sdio.txt - cp $(DL_DIR)/$(BRCMFMAC43455_SDIO_FILE).txt $(PKG_BUILD_DIR)/brcmfmac43455-sdio.txt cp $(DL_DIR)/$(BRCMFMAC43455_SDIO_FILE).clm_blob $(PKG_BUILD_DIR)/brcmfmac43455-sdio.clm_blob endef @@ -73,16 +45,9 @@ define Build/Compile true endef -define Package/brcmfmac-board-rpi2/install - $(INSTALL_DIR) $(1)/lib/firmware/brcm/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/brcmfmac43430-sdio.txt $(1)/lib/firmware/brcm/ -endef - -define Package/brcmfmac-board-rpi3/install +define Package/brcmfmac-firmware-43455-clm_blob/install $(INSTALL_DIR) $(1)/lib/firmware/brcm/ - $(INSTALL_DATA) $(PKG_BUILD_DIR)/brcmfmac43455-sdio.txt $(1)/lib/firmware/brcm/ $(INSTALL_DATA) $(PKG_BUILD_DIR)/brcmfmac43455-sdio.clm_blob $(1)/lib/firmware/brcm/ endef -$(eval $(call BuildPackage,brcmfmac-board-rpi2)) -$(eval $(call BuildPackage,brcmfmac-board-rpi3)) +$(eval $(call BuildPackage,brcmfmac-firmware-43455-clm_blob)) diff --git a/package/firmware/linux-firmware/Makefile b/package/firmware/linux-firmware/Makefile index ac4c3d4a63..137ff2bc9d 100644 --- a/package/firmware/linux-firmware/Makefile +++ b/package/firmware/linux-firmware/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=linux-firmware -PKG_VERSION:=20190815 +PKG_VERSION:=20190416 PKG_RELEASE:=1 PKG_SOURCE_URL:=@KERNEL/linux/kernel/firmware PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz -PKG_HASH:=15615d87ac9d93aa5c20939a6c65cca7f3bc656b5e8ffd998b8acb932c854327 +PKG_HASH:=4851120ea69436fd5088fc72674798ad343c5ddb89ac6b4161225357d1eda08c PKG_MAINTAINER:=Felix Fietkau @@ -33,4 +33,4 @@ define Build/Compile endef include $(wildcard ./*.mk) -#$(eval $(call BuildPackage,linux-firmware)) +#$(eval $(call BuildPackage,linux-firmware)) \ No newline at end of file diff --git a/package/firmware/linux-firmware/broadcom.mk b/package/firmware/linux-firmware/broadcom.mk index 4f7492a2d8..0ce94912c5 100644 --- a/package/firmware/linux-firmware/broadcom.mk +++ b/package/firmware/linux-firmware/broadcom.mk @@ -103,7 +103,7 @@ define Package/brcmfmac-firmware-43455-sdio-rpi-4b/install $(INSTALL_DATA) \ $(PKG_BUILD_DIR)/brcm/brcmfmac43455-sdio.raspberrypi,3-model-b-plus.txt \ $(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberrypi,4-model-b.txt - $(SED) 's/boardflags3=.*/boardflags3=0x44200100/g' \ + $(SED) 's/boardflags3=.*/boardflags3=0x44200100/g' \ $(1)/lib/firmware/brcm/brcmfmac43455-sdio.raspberrypi,4-model-b.txt endef $(eval $(call BuildPackage,brcmfmac-firmware-43455-sdio-rpi-4b)) diff --git a/package/firmware/linux-firmware/intel.mk b/package/firmware/linux-firmware/intel.mk index 923701c703..401ab1aa7e 100644 --- a/package/firmware/linux-firmware/intel.mk +++ b/package/firmware/linux-firmware/intel.mk @@ -73,7 +73,7 @@ $(eval $(call BuildPackage,iwlwifi-firmware-iwl3160)) Package/iwlwifi-firmware-iwl3168 = $(call Package/firmware-default,Intel Wireless 3168 firmware) define Package/iwlwifi-firmware-iwl3168/install $(INSTALL_DIR) $(1)/lib/firmware - $(INSTALL_DATA) $(PKG_BUILD_DIR)/iwlwifi-3168-29.ucode $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/iwlwifi-3168-27.ucode $(1)/lib/firmware endef $(eval $(call BuildPackage,iwlwifi-firmware-iwl3168)) @@ -157,14 +157,14 @@ $(eval $(call BuildPackage,iwlwifi-firmware-iwl8265)) Package/iwlwifi-firmware-iwl9000 = $(call Package/firmware-default,Intel Wireless 9000 firmware) define Package/iwlwifi-firmware-iwl9000/install $(INSTALL_DIR) $(1)/lib/firmware - $(INSTALL_DATA) $(PKG_BUILD_DIR)/iwlwifi-9000-pu-b0-jf-b0-46.ucode $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/iwlwifi-9000-pu-b0-jf-b0-38.ucode $(1)/lib/firmware endef $(eval $(call BuildPackage,iwlwifi-firmware-iwl9000)) Package/iwlwifi-firmware-iwl9260 = $(call Package/firmware-default,Intel Wireless 9260 firmware) define Package/iwlwifi-firmware-iwl9260/install $(INSTALL_DIR) $(1)/lib/firmware - $(INSTALL_DATA) $(PKG_BUILD_DIR)/iwlwifi-9260-th-b0-jf-b0-46.ucode $(1)/lib/firmware + $(INSTALL_DATA) $(PKG_BUILD_DIR)/iwlwifi-9260-th-b0-jf-b0-38.ucode $(1)/lib/firmware endef $(eval $(call BuildPackage,iwlwifi-firmware-iwl9260)) diff --git a/package/firmware/linux-firmware/mediatek.mk b/package/firmware/linux-firmware/mediatek.mk index 18677bc748..b258551a00 100644 --- a/package/firmware/linux-firmware/mediatek.mk +++ b/package/firmware/linux-firmware/mediatek.mk @@ -41,12 +41,3 @@ define Package/rt73-usb-firmware/install $(INSTALL_DATA) $(PKG_BUILD_DIR)/rt73.bin $(1)/lib/firmware/ endef $(eval $(call BuildPackage,rt73-usb-firmware)) - -Package/mt7622bt-firmware = $(call Package/firmware-default,mt7622bt firmware) -define Package/mt7622bt-firmware/install - $(INSTALL_DIR) $(1)/lib/firmware/mediatek - $(INSTALL_DATA) \ - $(PKG_BUILD_DIR)/mediatek/mt7622pr2h.bin \ - $(1)/lib/firmware/mediatek -endef -$(eval $(call BuildPackage,mt7622bt-firmware)) diff --git a/package/kernel/mac80211/Makefile b/package/kernel/mac80211/Makefile index 3cc14944fe..5ab42f0a1f 100644 --- a/package/kernel/mac80211/Makefile +++ b/package/kernel/mac80211/Makefile @@ -10,10 +10,10 @@ include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=mac80211 -PKG_VERSION:=5.3-rc4-1 -PKG_RELEASE:=1 -PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v5.3-rc4/ -PKG_HASH:=b159557f1e9e3e88ee2edf60ee786cd9ffd477e386306ea249c4e9085695b932 +PKG_VERSION:=4.19.32-1 +PKG_RELEASE:=2 +PKG_SOURCE_URL:=@KERNEL/linux/kernel/projects/backports/stable/v4.19.32/ +PKG_HASH:=838db1565b54fe4bd1e769c54f30c65c9ea2fb5e99a0cddb7910561794ae317a PKG_SOURCE:=backports-$(PKG_VERSION).tar.xz PKG_BUILD_DIR:=$(KERNEL_BUILD_DIR)/backports-$(PKG_VERSION) @@ -28,7 +28,7 @@ PKG_DRIVERS = \ lib80211 \ mac80211-hwsim \ mt7601u \ - p54-common p54-pci p54-usb \ + p54-common p54-pci p54-spi p54-usb \ rsi91x rsi91x-usb rsi91x-sdio\ wlcore wl12xx wl18xx \ zd1211rw @@ -162,7 +162,7 @@ endef define KernelPackage/airo $(call KernelPackage/mac80211/Default) TITLE:=Cisco Aironet driver - DEPENDS+=@PCI_SUPPORT +@DRIVER_WEXT_SUPPORT +kmod-cfg80211 @TARGET_x86 @BROKEN + 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 @@ -275,7 +275,7 @@ endef define KernelPackage/p54-common $(call KernelPackage/p54/Default) - DEPENDS+= @(PCI_SUPPORT||USB_SUPPORT) +kmod-mac80211 +kmod-lib-crc-ccitt +@DRIVER_11W_SUPPORT + DEPENDS+= @PCI_SUPPORT||@USB_SUPPORT||@TARGET_omap24xx +kmod-mac80211 +kmod-lib-crc-ccitt +@DRIVER_11W_SUPPORT TITLE+= (COMMON) FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54common.ko endef @@ -296,6 +296,14 @@ define KernelPackage/p54-usb AUTOLOAD:=$(call AutoProbe,p54usb) endef +define KernelPackage/p54-spi + $(call KernelPackage/p54/Default) + TITLE+= (SPI) + DEPENDS+= @TARGET_omap24xx +kmod-p54-common +p54-spi-firmware + FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intersil/p54/p54spi.ko + AUTOLOAD:=$(call AutoProbe,p54spi) +endef + define KernelPackage/rsi91x $(call KernelPackage/mac80211/Default) TITLE:=Redpine Signals Inc 91x WLAN driver support @@ -400,6 +408,7 @@ 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,p54-spi) += P54_SPI config-$(call config_package,hermes) += HERMES config-$(call config_package,hermes-pci) += PCI_HERMES diff --git a/package/kernel/mac80211/ath.mk b/package/kernel/mac80211/ath.mk index 64aac41b4d..e4540422a4 100644 --- a/package/kernel/mac80211/ath.mk +++ b/package/kernel/mac80211/ath.mk @@ -131,7 +131,7 @@ 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 + 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 diff --git a/package/kernel/mac80211/broadcom.mk b/package/kernel/mac80211/broadcom.mk index f55f38d55e..4b05c13dba 100644 --- a/package/kernel/mac80211/broadcom.mk +++ b/package/kernel/mac80211/broadcom.mk @@ -105,7 +105,7 @@ define KernelPackage/b43 CONFIG_HW_RANDOM=y # Depend on PCI_SUPPORT to make sure we can select kmod-bcma or kmod-ssb DEPENDS += \ - @PCI_SUPPORT +kmod-mac80211 +kmod-lib-cordic \ + @PCI_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 @@ -347,7 +347,7 @@ define KernelPackage/b43legacy 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 + DEPENDS+= +kmod-mac80211 +!(TARGET_brcm47xx||TARGET_brcm63xx):kmod-ssb +b43legacy-firmware FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/broadcom/b43legacy/b43legacy.ko AUTOLOAD:=$(call AutoProbe,b43legacy) MENU:=1 diff --git a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh index f9d5c0c6d5..6dc4e5bf5f 100644 --- a/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh +++ b/package/kernel/mac80211/files/lib/netifd/wireless/mac80211.sh @@ -26,7 +26,7 @@ drv_mac80211_init_device_config() { 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 acs_exclude_dfs + config_add_boolean noscan ht_coex config_add_array ht_capab config_add_array channels config_add_boolean \ @@ -97,10 +97,6 @@ mac80211_hostapd_setup_base() { [ "$auto_channel" -gt 0 ] && channel=acs_survey [ "$auto_channel" -gt 0 ] && json_get_values channel_list channels - [ "$auto_channel" -gt 0 ] && json_get_vars acs_exclude_dfs - [ -n "$acs_exclude_dfs" ] && [ "$acs_exclude_dfs" -gt 0 ] && - append base_cfg "acs_exclude_dfs=1" "$N" - json_get_vars noscan ht_coex json_get_values ht_capab_list ht_capab tx_burst diff --git a/package/kernel/mac80211/intel.mk b/package/kernel/mac80211/intel.mk index a8ae4ff7c7..71494fe0ce 100644 --- a/package/kernel/mac80211/intel.mk +++ b/package/kernel/mac80211/intel.mk @@ -15,7 +15,7 @@ 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 + DEPENDS:= +kmod-mac80211 @PCI_SUPPORT +@DRIVER_11N_SUPPORT +@DRIVER_11AC_SUPPORT +@DRIVER_11W_SUPPORT @!LINUX_3_18 TITLE:=Intel AGN Wireless support FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/intel/iwlwifi/iwlwifi.ko \ @@ -124,7 +124,7 @@ 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 + DEPENDS:=@PCI_SUPPORT +kmod-crypto-michael-mic +kmod-crypto-ecb +kmod-lib80211 +kmod-cfg80211 +@DRIVER_WEXT_SUPPORT @!BIG_ENDIAN @!LINUX_3_18 FILES:=$(PKG_BUILD_DIR)/drivers/net/wireless/intel/ipw2x00/libipw.ko AUTOLOAD:=$(call AutoProbe,libipw) endef diff --git a/package/kernel/mac80211/marvell.mk b/package/kernel/mac80211/marvell.mk index a0e67091e5..4e2f925b73 100644 --- a/package/kernel/mac80211/marvell.mk +++ b/package/kernel/mac80211/marvell.mk @@ -11,7 +11,7 @@ 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 + DEPENDS+= @USB_SUPPORT +kmod-cfg80211 +kmod-usb-core +kmod-lib80211 +@DRIVER_WEXT_SUPPORT +libertas-usb-firmware @!LINUX_3_18 TITLE:=Marvell 88W8015 Wireless Driver FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \ @@ -21,7 +21,7 @@ endef define KernelPackage/libertas-sdio $(call KernelPackage/mac80211/Default) - DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-sdio-firmware + DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +kmod-mmc +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-sdio-firmware @!LINUX_3_18 TITLE:=Marvell 88W8686 Wireless Driver FILES:= \ $(PKG_BUILD_DIR)/drivers/net/wireless/marvell/libertas/libertas.ko \ @@ -32,7 +32,7 @@ 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 + DEPENDS+= +kmod-cfg80211 +kmod-lib80211 +@DRIVER_WEXT_SUPPORT @!TARGET_uml +libertas-spi-firmware @!LINUX_3_18 KCONFIG := \ CONFIG_SPI=y \ CONFIG_SPI_MASTER=y diff --git a/package/kernel/mac80211/patches/ath/070-ath_common_config.patch b/package/kernel/mac80211/patches/ath/070-ath_common_config.patch index 3d0b4d6b1a..41774fe53e 100644 --- a/package/kernel/mac80211/patches/ath/070-ath_common_config.patch +++ b/package/kernel/mac80211/patches/ath/070-ath_common_config.patch @@ -1,7 +1,6 @@ --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig -@@ -1,6 +1,6 @@ - # SPDX-License-Identifier: ISC +@@ -1,5 +1,5 @@ config ATH_COMMON - tristate + tristate "ath.ko" diff --git a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch b/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch index 231a7cb393..a86cbc6e54 100644 --- a/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch +++ b/package/kernel/mac80211/patches/ath/080-ath10k_thermal_config.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig -@@ -87,6 +87,12 @@ config ATH10K_TRACING +@@ -85,6 +85,12 @@ config ATH10K_TRACING ---help--- Select this to ath10k use tracing infrastructure. @@ -26,7 +26,7 @@ ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o --- a/drivers/net/wireless/ath/ath10k/thermal.h +++ b/drivers/net/wireless/ath/ath10k/thermal.h -@@ -25,7 +25,7 @@ struct ath10k_thermal { +@@ -36,7 +36,7 @@ struct ath10k_thermal { int temperature; }; @@ -37,7 +37,7 @@ void ath10k_thermal_event_temperature(struct ath10k *ar, int temperature); --- a/local-symbols +++ b/local-symbols -@@ -141,6 +141,7 @@ ATH10K_SNOC= +@@ -139,6 +139,7 @@ ATH10K_SNOC= ATH10K_DEBUG= ATH10K_DEBUGFS= ATH10K_SPECTRAL= diff --git a/package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch b/package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch index d648a3a3e5..cadbf6809c 100644 --- a/package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch +++ b/package/kernel/mac80211/patches/ath/350-ath9k_hw-reset-AHB-WMAC-interface-on-AR91xx.patch @@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau --- 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 +@@ -1421,8 +1421,12 @@ static bool ath9k_hw_set_reset(struct at if (!AR_SREV_9100(ah)) REG_WRITE(ah, AR_RC, 0); diff --git a/package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch b/package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch index 5f265b84c2..ac9e112f51 100644 --- a/package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch +++ b/package/kernel/mac80211/patches/ath/351-ath9k_hw-issue-external-reset-for-QCA955x.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- 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 +@@ -1298,39 +1298,56 @@ void ath9k_hw_get_delta_slope_vals(struc *coef_exponent = coef_exp - 16; } @@ -94,7 +94,7 @@ Signed-off-by: Felix Fietkau return true; } -@@ -1397,24 +1414,24 @@ static bool ath9k_hw_set_reset(struct at +@@ -1383,24 +1400,24 @@ static bool ath9k_hw_set_reset(struct at rst_flags |= AR_RTC_RC_MAC_COLD; } diff --git a/package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch b/package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch index 385eea0116..3adcb8b796 100644 --- a/package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch +++ b/package/kernel/mac80211/patches/ath/356-Revert-ath9k-interpret-requested-txpower-in-EIRP-dom.patch @@ -8,7 +8,7 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2977,7 +2977,8 @@ void ath9k_hw_apply_txpower(struct ath_h +@@ -2962,7 +2962,8 @@ void ath9k_hw_apply_txpower(struct ath_h { struct ath_regulatory *reg = ath9k_hw_regulatory(ah); struct ieee80211_channel *channel; @@ -18,9 +18,9 @@ This reverts commit 71f5137bf010c6faffab50c0ec15374c59c4a411. u16 ctl = NO_CTL; if (!chan) -@@ -2989,9 +2990,14 @@ void ath9k_hw_apply_txpower(struct ath_h +@@ -2974,9 +2975,14 @@ void ath9k_hw_apply_txpower(struct ath_h channel = chan->chan; - chan_pwr = min_t(int, channel->max_power * 2, MAX_COMBINED_POWER); + 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; + diff --git a/package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch b/package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch index 0c3edc1260..363e9aa9a3 100644 --- a/package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch +++ b/package/kernel/mac80211/patches/ath/365-ath9k-adjust-tx-power-reduction-for-US-regulatory-do.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -2996,6 +2996,10 @@ void ath9k_hw_apply_txpower(struct ath_h +@@ -2981,6 +2981,10 @@ void ath9k_hw_apply_txpower(struct ath_h if (ant_gain > max_gain) ant_reduction = ant_gain - max_gain; diff --git a/package/kernel/mac80211/patches/ath/381-ath9k-fix-tx99-with-monitor-mode-interface.patch b/package/kernel/mac80211/patches/ath/381-ath9k-fix-tx99-with-monitor-mode-interface.patch new file mode 100644 index 0000000000..d5c37825fd --- /dev/null +++ b/package/kernel/mac80211/patches/ath/381-ath9k-fix-tx99-with-monitor-mode-interface.patch @@ -0,0 +1,92 @@ +From: Felix Fietkau +Date: Mon, 20 Aug 2018 11:35:05 +0200 +Subject: [PATCH] ath9k: fix tx99 with monitor mode interface + +Tx99 is typically configured via a monitor mode interface, which does +not get added to the driver as a vif. Since the code currently expects +a configured virtual interface for tx99, enabling tx99 via debugfs fails. +Since the vif is not needed anyway, remove all checks for it. + +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -1074,7 +1074,6 @@ struct ath_softc { + + struct ath_spec_scan_priv spec_priv; + +- struct ieee80211_vif *tx99_vif; + struct sk_buff *tx99_skb; + bool tx99_state; + s16 tx99_power; +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1251,15 +1251,10 @@ static int ath9k_add_interface(struct ie + struct ath_vif *avp = (void *)vif->drv_priv; + struct ath_node *an = &avp->mcast_node; + +- mutex_lock(&sc->mutex); ++ if (IS_ENABLED(CPTCFG_ATH9K_TX99)) ++ return -EOPNOTSUPP; + +- if (IS_ENABLED(CPTCFG_ATH9K_TX99)) { +- if (sc->cur_chan->nvifs >= 1) { +- mutex_unlock(&sc->mutex); +- return -EOPNOTSUPP; +- } +- sc->tx99_vif = vif; +- } ++ mutex_lock(&sc->mutex); + + ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); + sc->cur_chan->nvifs++; +@@ -1342,7 +1337,6 @@ static void ath9k_remove_interface(struc + ath9k_p2p_remove_vif(sc, vif); + + sc->cur_chan->nvifs--; +- sc->tx99_vif = NULL; + if (!ath9k_is_chanctx_enabled()) + list_del(&avp->list); + +--- a/drivers/net/wireless/ath/ath9k/tx99.c ++++ b/drivers/net/wireless/ath/ath9k/tx99.c +@@ -54,12 +54,6 @@ static struct sk_buff *ath9k_build_tx99_ + struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *tx_info; + struct sk_buff *skb; +- struct ath_vif *avp; +- +- if (!sc->tx99_vif) +- return NULL; +- +- avp = (struct ath_vif *)sc->tx99_vif->drv_priv; + + skb = alloc_skb(len, GFP_KERNEL); + if (!skb) +@@ -77,14 +71,11 @@ static struct sk_buff *ath9k_build_tx99_ + memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); + memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); + +- hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); +- + tx_info = IEEE80211_SKB_CB(skb); + memset(tx_info, 0, sizeof(*tx_info)); + rate = &tx_info->control.rates[0]; + tx_info->band = sc->cur_chan->chandef.chan->band; + tx_info->flags = IEEE80211_TX_CTL_NO_ACK; +- tx_info->control.vif = sc->tx99_vif; + rate->count = 1; + if (ah->curchan && IS_CHAN_HT(ah->curchan)) { + rate->flags |= IEEE80211_TX_RC_MCS; +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -2974,7 +2974,7 @@ int ath9k_tx99_send(struct ath_softc *sc + return -EINVAL; + } + +- ath_set_rates(sc->tx99_vif, NULL, bf); ++ ath_set_rates(NULL, NULL, bf); + + ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr); + ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum); diff --git a/package/kernel/mac80211/patches/ath/395-ath9k-add-back-support-for-using-active-monitor-inte.patch b/package/kernel/mac80211/patches/ath/395-ath9k-add-back-support-for-using-active-monitor-inte.patch new file mode 100644 index 0000000000..7f30de9862 --- /dev/null +++ b/package/kernel/mac80211/patches/ath/395-ath9k-add-back-support-for-using-active-monitor-inte.patch @@ -0,0 +1,96 @@ +From: Felix Fietkau +Date: Sat, 22 Sep 2018 15:20:50 +0200 +Subject: [PATCH] ath9k: add back support for using active monitor interfaces + for tx99 + +Various documented examples on how to set up tx99 with ath9k rely +on setting up a regular monitor interface for setting the channel. +My previous patch "ath9k: fix tx99 with monitor mode interface" made +it possible to set it up this way again. However, it was removing support +for using an active monitor interface, which is required for controlling +the bitrate as well, since the bitrate is not passed down with a regular +monitor interface. + +This patch partially reverts the previous one, but keeps support for using +a regular monitor interface to keep documented steps working in cases +where the bitrate does not matter + +Fixes: d9c52fd17cb48 ("ath9k: fix tx99 with monitor mode interface") +Signed-off-by: Felix Fietkau +--- + +--- a/drivers/net/wireless/ath/ath9k/ath9k.h ++++ b/drivers/net/wireless/ath/ath9k/ath9k.h +@@ -1074,6 +1074,7 @@ struct ath_softc { + + struct ath_spec_scan_priv spec_priv; + ++ struct ieee80211_vif *tx99_vif; + struct sk_buff *tx99_skb; + bool tx99_state; + s16 tx99_power; +--- a/drivers/net/wireless/ath/ath9k/main.c ++++ b/drivers/net/wireless/ath/ath9k/main.c +@@ -1251,8 +1251,13 @@ static int ath9k_add_interface(struct ie + struct ath_vif *avp = (void *)vif->drv_priv; + struct ath_node *an = &avp->mcast_node; + +- if (IS_ENABLED(CPTCFG_ATH9K_TX99)) +- return -EOPNOTSUPP; ++ if (IS_ENABLED(CPTCFG_ATH9K_TX99)) { ++ if (sc->cur_chan->nvifs >= 1) { ++ mutex_unlock(&sc->mutex); ++ return -EOPNOTSUPP; ++ } ++ sc->tx99_vif = vif; ++ } + + mutex_lock(&sc->mutex); + +@@ -1337,6 +1342,7 @@ static void ath9k_remove_interface(struc + ath9k_p2p_remove_vif(sc, vif); + + sc->cur_chan->nvifs--; ++ sc->tx99_vif = NULL; + if (!ath9k_is_chanctx_enabled()) + list_del(&avp->list); + +--- a/drivers/net/wireless/ath/ath9k/tx99.c ++++ b/drivers/net/wireless/ath/ath9k/tx99.c +@@ -54,6 +54,7 @@ static struct sk_buff *ath9k_build_tx99_ + struct ieee80211_hdr *hdr; + struct ieee80211_tx_info *tx_info; + struct sk_buff *skb; ++ struct ath_vif *avp; + + skb = alloc_skb(len, GFP_KERNEL); + if (!skb) +@@ -71,11 +72,17 @@ static struct sk_buff *ath9k_build_tx99_ + memcpy(hdr->addr2, hw->wiphy->perm_addr, ETH_ALEN); + memcpy(hdr->addr3, hw->wiphy->perm_addr, ETH_ALEN); + ++ if (sc->tx99_vif) { ++ avp = (struct ath_vif *) sc->tx99_vif->drv_priv; ++ hdr->seq_ctrl |= cpu_to_le16(avp->seq_no); ++ } ++ + tx_info = IEEE80211_SKB_CB(skb); + memset(tx_info, 0, sizeof(*tx_info)); + rate = &tx_info->control.rates[0]; + tx_info->band = sc->cur_chan->chandef.chan->band; + tx_info->flags = IEEE80211_TX_CTL_NO_ACK; ++ tx_info->control.vif = sc->tx99_vif; + rate->count = 1; + if (ah->curchan && IS_CHAN_HT(ah->curchan)) { + rate->flags |= IEEE80211_TX_RC_MCS; +--- a/drivers/net/wireless/ath/ath9k/xmit.c ++++ b/drivers/net/wireless/ath/ath9k/xmit.c +@@ -2974,7 +2974,7 @@ int ath9k_tx99_send(struct ath_softc *sc + return -EINVAL; + } + +- ath_set_rates(NULL, NULL, bf); ++ ath_set_rates(sc->tx99_vif, NULL, bf); + + ath9k_hw_set_desc_link(sc->sc_ah, bf->bf_desc, bf->bf_daddr); + ath9k_hw_tx99_start(sc->sc_ah, txctl->txq->axq_qnum); diff --git a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch index 7824eab6cb..03c12df1a8 100644 --- a/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch +++ b/package/kernel/mac80211/patches/ath/402-ath_regd_optional.patch @@ -70,7 +70,7 @@ --- a/drivers/net/wireless/ath/Kconfig +++ b/drivers/net/wireless/ath/Kconfig -@@ -24,6 +24,9 @@ config WLAN_VENDOR_ATH +@@ -23,6 +23,9 @@ config WLAN_VENDOR_ATH if WLAN_VENDOR_ATH @@ -82,7 +82,7 @@ ---help--- --- a/local-symbols +++ b/local-symbols -@@ -85,6 +85,7 @@ ADM8211= +@@ -83,6 +83,7 @@ ADM8211= ATH_COMMON= WLAN_VENDOR_ATH= ATH_DEBUG= diff --git a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch index e4d1a6daab..ec95206acb 100644 --- a/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch +++ b/package/kernel/mac80211/patches/ath/404-regd_no_assoc_hints.patch @@ -1,6 +1,6 @@ --- a/net/wireless/reg.c +++ b/net/wireless/reg.c -@@ -3032,6 +3032,8 @@ void regulatory_hint_country_ie(struct w +@@ -2982,6 +2982,8 @@ void regulatory_hint_country_ie(struct w enum environment_cap env = ENVIRON_ANY; struct regulatory_request *request = NULL, *lr; @@ -9,11 +9,11 @@ /* IE len must be evenly divisible by 2 */ if (country_ie_len & 0x01) return; -@@ -3283,6 +3285,7 @@ static bool is_wiphy_all_set_reg_flag(en +@@ -3188,6 +3190,7 @@ static void restore_regulatory_settings( 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. + pr_debug("All devices are disconnected, going to restore regulatory settings\n"); + restore_regulatory_settings(false); + } diff --git a/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch b/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch index 088833199d..8cb7f00ff9 100644 --- a/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch +++ b/package/kernel/mac80211/patches/ath/405-ath_regd_us.patch @@ -21,6 +21,6 @@ {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 */ diff --git a/package/kernel/mac80211/patches/ath/407-regd_add_extra_country_codes.patch b/package/kernel/mac80211/patches/ath/407-regd_add_extra_country_codes.patch new file mode 100644 index 0000000000..8f621002fe --- /dev/null +++ b/package/kernel/mac80211/patches/ath/407-regd_add_extra_country_codes.patch @@ -0,0 +1,35 @@ +From: Oever Gonzalez +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 +--- + +--- 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 */ diff --git a/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch index bdf784968f..25c236b12c 100644 --- a/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch +++ b/package/kernel/mac80211/patches/ath/410-ath9k_allow_adhoc_and_ap.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -831,6 +831,7 @@ static const struct ieee80211_iface_limi +@@ -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) }, diff --git a/package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch b/package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch index 9dbe047c9a..2a5ab3d428 100644 --- a/package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch +++ b/package/kernel/mac80211/patches/ath/411-ath5k_allow_adhoc_and_ap.patch @@ -18,7 +18,7 @@ goto end; --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c -@@ -1964,7 +1964,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) +@@ -1965,7 +1965,7 @@ ath5k_beacon_send(struct ath5k_hw *ah) } if ((ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs + @@ -27,7 +27,7 @@ ah->opmode == NL80211_IFTYPE_MESH_POINT) { u64 tsf = ath5k_hw_get_tsf64(ah); u32 tsftu = TSF_TO_TU(tsf); -@@ -2050,7 +2050,7 @@ ath5k_beacon_update_timers(struct ath5k_ +@@ -2051,7 +2051,7 @@ ath5k_beacon_update_timers(struct ath5k_ intval = ah->bintval & AR5K_BEACON_PERIOD; if (ah->opmode == NL80211_IFTYPE_AP && ah->num_ap_vifs @@ -36,7 +36,7 @@ intval /= ATH_BCBUF; /* staggered multi-bss beacons */ if (intval < 15) ATH5K_WARN(ah, "intval %u is too low, min 15\n", -@@ -2516,6 +2516,7 @@ static const struct ieee80211_iface_limi +@@ -2518,6 +2518,7 @@ static const struct ieee80211_iface_limi BIT(NL80211_IFTYPE_MESH_POINT) | #endif BIT(NL80211_IFTYPE_AP) }, diff --git a/package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch b/package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch index 786a3ed3fb..b6dc45cd96 100644 --- a/package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch +++ b/package/kernel/mac80211/patches/ath/500-ath9k_eeprom_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1361,6 +1361,53 @@ void ath9k_deinit_debug(struct ath_softc +@@ -1374,6 +1374,53 @@ void ath9k_deinit_debug(struct ath_softc ath9k_cmn_spectral_deinit_debug(&sc->spec_priv); } @@ -54,7 +54,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1380,6 +1427,8 @@ int ath9k_init_debug(struct ath_hw *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); diff --git a/package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch b/package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch index b9c784eb25..5fc60dd0ae 100644 --- a/package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch +++ b/package/kernel/mac80211/patches/ath/501-ath9k_ahb_init.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -1143,25 +1143,25 @@ static int __init ath9k_init(void) +@@ -1144,25 +1144,25 @@ static int __init ath9k_init(void) { int error; diff --git a/package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch b/package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch index 75b48b480e..356939a354 100644 --- a/package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch +++ b/package/kernel/mac80211/patches/ath/510-ath9k_intr_mitigation_tweak.patch @@ -1,6 +1,6 @@ --- 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 +@@ -392,13 +392,8 @@ static void ath9k_hw_init_config(struct ah->config.rx_intr_mitigation = true; diff --git a/package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch b/package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch index 80e33182f7..2d4a5688c8 100644 --- a/package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch +++ b/package/kernel/mac80211/patches/ath/512-ath9k_channelbw_debugfs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1408,6 +1408,52 @@ static const struct file_operations fops +@@ -1421,6 +1421,52 @@ static const struct file_operations fops .owner = THIS_MODULE }; @@ -53,7 +53,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1429,6 +1475,8 @@ int ath9k_init_debug(struct ath_hw *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); diff --git a/package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch b/package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch index 113c35625f..e536e60794 100644 --- a/package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch +++ b/package/kernel/mac80211/patches/ath/513-ath9k_add_pci_ids.patch @@ -1,6 +1,6 @@ --- 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) +@@ -649,6 +649,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) { diff --git a/package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch b/package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch index 1f19483064..c13a72cbb0 100644 --- a/package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch +++ b/package/kernel/mac80211/patches/ath/530-ath9k_extra_leds.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -843,6 +843,9 @@ static inline int ath9k_dump_btcoex(stru +@@ -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); @@ -10,9 +10,9 @@ #else static inline void ath_init_leds(struct ath_softc *sc) { -@@ -979,6 +982,13 @@ void ath_ant_comb_scan(struct ath_softc - - #define ATH9K_NUM_CHANCTX 2 /* supports 2 operating channels */ +@@ -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; @@ -24,7 +24,7 @@ struct ath_softc { struct ieee80211_hw *hw; struct device *dev; -@@ -1032,9 +1042,8 @@ struct ath_softc { +@@ -1046,9 +1056,8 @@ struct ath_softc { spinlock_t chan_lock; #ifdef CPTCFG_MAC80211_LEDS @@ -181,7 +181,7 @@ --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -1055,7 +1055,7 @@ int ath9k_init_device(u16 devid, struct +@@ -1056,7 +1056,7 @@ int ath9k_init_device(u16 devid, struct #ifdef CPTCFG_MAC80211_LEDS /* must be initialized before ieee80211_register_hw */ @@ -192,7 +192,7 @@ #endif --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1453,6 +1453,61 @@ static const struct file_operations fops +@@ -1466,6 +1466,61 @@ static const struct file_operations fops .llseek = default_llseek, }; @@ -254,7 +254,7 @@ int ath9k_init_debug(struct ath_hw *ah) { -@@ -1477,6 +1532,10 @@ 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); diff --git a/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch b/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch index 7c60191d48..55896c834b 100644 --- a/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch +++ b/package/kernel/mac80211/patches/ath/542-ath9k_debugfs_diag.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/debug.c +++ b/drivers/net/wireless/ath/ath9k/debug.c -@@ -1509,6 +1509,50 @@ static const struct file_operations fops +@@ -1522,6 +1522,50 @@ static const struct file_operations fops #endif @@ -51,7 +51,7 @@ int ath9k_init_debug(struct ath_hw *ah) { struct ath_common *common = ath9k_hw_common(ah); -@@ -1536,6 +1580,8 @@ int ath9k_init_debug(struct ath_hw *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 @@ -62,7 +62,7 @@ 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 -@@ -521,6 +521,12 @@ enum { +@@ -520,6 +520,12 @@ enum { ATH9K_RESET_COLD, }; @@ -75,7 +75,7 @@ struct ath9k_hw_version { u32 magic; u16 devid; -@@ -809,6 +815,8 @@ struct ath_hw { +@@ -808,6 +814,8 @@ struct ath_hw { u32 ah_flags; s16 nf_override; @@ -84,7 +84,7 @@ bool reset_power_on; bool htc_reset_init; -@@ -1074,6 +1082,7 @@ void ath9k_hw_check_nav(struct ath_hw *a +@@ -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); @@ -94,7 +94,7 @@ struct ath_gen_timer *ath_gen_timer_alloc(struct ath_hw *ah, --- a/drivers/net/wireless/ath/ath9k/hw.c +++ b/drivers/net/wireless/ath/ath9k/hw.c -@@ -1883,6 +1883,20 @@ u32 ath9k_hw_get_tsf_offset(struct times +@@ -1869,6 +1869,20 @@ u32 ath9k_hw_get_tsf_offset(struct times } EXPORT_SYMBOL(ath9k_hw_get_tsf_offset); @@ -115,7 +115,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan, struct ath9k_hw_cal_data *caldata, bool fastcc) { -@@ -2091,6 +2105,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st +@@ -2077,6 +2091,7 @@ int ath9k_hw_reset(struct ath_hw *ah, st ar9003_hw_disable_phy_restart(ah); ath9k_hw_apply_gpio_override(ah); diff --git a/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch b/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch index 64bd6cacfd..b0a027564a 100644 --- a/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch +++ b/package/kernel/mac80211/patches/ath/543-ath9k_entropy_from_adc.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/hw.h +++ b/drivers/net/wireless/ath/ath9k/hw.h -@@ -722,6 +722,7 @@ struct ath_spec_scan { +@@ -721,6 +721,7 @@ struct ath_spec_scan { * @config_pci_powersave: * @calibrate: periodic calibration for NF, ANI, IQ, ADC gain, ADC-DC * @@ -8,7 +8,7 @@ * @spectral_scan_config: set parameters for spectral scan and enable/disable it * @spectral_scan_trigger: trigger a spectral scan run * @spectral_scan_wait: wait for a spectral scan run to finish -@@ -744,6 +745,7 @@ struct ath_hw_ops { +@@ -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); @@ -18,7 +18,7 @@ void (*spectral_scan_trigger)(struct ath_hw *ah); --- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c -@@ -1927,6 +1927,26 @@ void ar9003_hw_init_rate_txpower(struct +@@ -1945,6 +1945,26 @@ void ar9003_hw_init_rate_txpower(struct } } @@ -45,7 +45,7 @@ void ar9003_hw_attach_phy_ops(struct ath_hw *ah) { struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah); -@@ -1963,6 +1983,7 @@ void ar9003_hw_attach_phy_ops(struct ath +@@ -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; @@ -55,7 +55,7 @@ ops->spectral_scan_config = ar9003_hw_spectral_scan_config; --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c -@@ -819,7 +819,8 @@ static void ath9k_init_txpower_limits(st +@@ -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); @@ -65,8 +65,8 @@ } static const struct ieee80211_iface_limit if_limits[] = { -@@ -1015,6 +1016,18 @@ static void ath9k_set_hw_capab(struct at - wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_AIRTIME_FAIRNESS); +@@ -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) @@ -84,7 +84,7 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, const struct ath_bus_ops *bus_ops) { -@@ -1060,6 +1073,8 @@ int ath9k_init_device(u16 devid, struct +@@ -1061,6 +1074,8 @@ int ath9k_init_device(u16 devid, struct ARRAY_SIZE(ath9k_tpt_blink)); #endif @@ -110,7 +110,7 @@ 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 -@@ -1320,9 +1320,30 @@ void ar5008_hw_init_rate_txpower(struct +@@ -1324,9 +1324,30 @@ void ar5008_hw_init_rate_txpower(struct } } @@ -141,7 +141,7 @@ static const u32 ar5416_cca_regs[6] = { AR_PHY_CCA, AR_PHY_CH1_CCA, -@@ -1337,6 +1358,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ +@@ -1341,6 +1362,8 @@ int ar5008_hw_attach_phy_ops(struct ath_ if (ret) return ret; diff --git a/package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch b/package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch index 93eee34b64..ba8f1e5d61 100644 --- a/package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch +++ b/package/kernel/mac80211/patches/ath/544-ath9k-ar933x-usb-hang-workaround.patch @@ -20,7 +20,7 @@ /******************/ /* Chip Revisions */ /******************/ -@@ -1455,6 +1468,9 @@ static bool ath9k_hw_set_reset(struct at +@@ -1441,6 +1454,9 @@ static bool ath9k_hw_set_reset(struct at udelay(50); } @@ -30,7 +30,7 @@ return true; } -@@ -1554,6 +1570,9 @@ static bool ath9k_hw_chip_reset(struct a +@@ -1540,6 +1556,9 @@ static bool ath9k_hw_chip_reset(struct a ar9003_hw_internal_regulator_apply(ah); ath9k_hw_init_pll(ah, chan); @@ -40,7 +40,7 @@ return true; } -@@ -1861,8 +1880,14 @@ static int ath9k_hw_do_fastcc(struct ath +@@ -1847,8 +1866,14 @@ static int ath9k_hw_do_fastcc(struct ath if (AR_SREV_9271(ah)) ar9002_hw_load_ani_reg(ah, chan); @@ -55,7 +55,7 @@ return -EINVAL; } -@@ -2116,6 +2141,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st +@@ -2102,6 +2127,9 @@ int ath9k_hw_reset(struct ath_hw *ah, st ath9k_hw_set_radar_params(ah); } diff --git a/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch b/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch index 48cc171134..3a3f244b9d 100644 --- a/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch +++ b/package/kernel/mac80211/patches/ath/545-ath9k_ani_ws_detect.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c +++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c -@@ -949,55 +949,6 @@ static bool ar5008_hw_ani_control_new(st +@@ -953,55 +953,6 @@ static bool ar5008_hw_ani_control_new(st * on == 0 means more noise imm */ u32 on = param ? 1 : 0; @@ -79,7 +79,7 @@ static const u8 ofdm2pwr[] = { ALL_TARGET_LEGACY_6_24, ALL_TARGET_LEGACY_6_24, -@@ -1077,11 +1063,6 @@ static bool ar9003_hw_ani_control(struct +@@ -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; @@ -91,7 +91,7 @@ s32 value, value2; switch (cmd & ah->ani_function) { -@@ -1095,61 +1076,6 @@ static bool ar9003_hw_ani_control(struct +@@ -1113,61 +1094,6 @@ static bool ar9003_hw_ani_control(struct */ u32 on = param ? 1 : 0; diff --git a/package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch b/package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch index 78206d2860..eb9eb26a74 100644 --- a/package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch +++ b/package/kernel/mac80211/patches/ath/548-ath9k_enable_gpio_chip.patch @@ -18,7 +18,7 @@ Signed-off-by: Felix Fietkau #include "common.h" #include "debug.h" -@@ -989,6 +990,14 @@ struct ath_led { +@@ -1001,6 +1002,14 @@ struct ath_led { struct led_classdev cdev; }; @@ -33,7 +33,7 @@ Signed-off-by: Felix Fietkau struct ath_softc { struct ieee80211_hw *hw; struct device *dev; -@@ -1044,6 +1053,9 @@ struct ath_softc { +@@ -1058,6 +1067,9 @@ struct ath_softc { #ifdef CPTCFG_MAC80211_LEDS const char *led_default_trigger; struct list_head leds; diff --git a/package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch b/package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch index 716e09f351..bd71b75e76 100644 --- a/package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch +++ b/package/kernel/mac80211/patches/ath/549-ath9k_enable_gpio_buttons.patch @@ -10,7 +10,7 @@ Signed-off-by: Felix Fietkau --- --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h -@@ -1055,6 +1055,7 @@ struct ath_softc { +@@ -1069,6 +1069,7 @@ struct ath_softc { struct list_head leds; #ifdef CONFIG_GPIOLIB struct ath9k_gpio_chip *gpiochip; diff --git a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch b/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch index 9c91767587..30eba27137 100644 --- a/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch +++ b/package/kernel/mac80211/patches/ath/551-ath9k_ubnt_uap_plus_hsr.patch @@ -386,7 +386,7 @@ #endif /* _LINUX_ATH9K_PLATFORM_H */ --- a/local-symbols +++ b/local-symbols -@@ -112,6 +112,7 @@ ATH9K_WOW= +@@ -110,6 +110,7 @@ ATH9K_WOW= ATH9K_RFKILL= ATH9K_CHANNEL_CONTEXT= ATH9K_PCOEM= @@ -396,7 +396,7 @@ ATH9K_HWRNG= --- a/drivers/net/wireless/ath/ath9k/Kconfig +++ b/drivers/net/wireless/ath/ath9k/Kconfig -@@ -60,6 +60,19 @@ config ATH9K_AHB +@@ -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. diff --git a/package/kernel/mac80211/patches/ath/552-ahb_of.patch b/package/kernel/mac80211/patches/ath/552-ahb_of.patch index 1170fc64bd..08735d2871 100644 --- a/package/kernel/mac80211/patches/ath/552-ahb_of.patch +++ b/package/kernel/mac80211/patches/ath/552-ahb_of.patch @@ -318,7 +318,7 @@ #include "common.h" #include "debug.h" -@@ -1011,6 +1012,9 @@ struct ath_softc { +@@ -1023,6 +1024,9 @@ struct ath_softc { struct ath_hw *sc_ah; void __iomem *mem; int irq; diff --git a/package/kernel/mac80211/patches/ath/554-ath9k-dynack-move-debug-log-after-buffer-increments.patch b/package/kernel/mac80211/patches/ath/554-ath9k-dynack-move-debug-log-after-buffer-increments.patch new file mode 100644 index 0000000000..607722cc3d --- /dev/null +++ b/package/kernel/mac80211/patches/ath/554-ath9k-dynack-move-debug-log-after-buffer-increments.patch @@ -0,0 +1,88 @@ +From: Lorenzo Bianconi +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 +Signed-off-by: Lorenzo Bianconi +--- + +--- 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); diff --git a/package/kernel/mac80211/patches/ath/557-ath9k-dynack-remove-experimental-tag.patch b/package/kernel/mac80211/patches/ath/557-ath9k-dynack-remove-experimental-tag.patch new file mode 100644 index 0000000000..2e4cffd1fa --- /dev/null +++ b/package/kernel/mac80211/patches/ath/557-ath9k-dynack-remove-experimental-tag.patch @@ -0,0 +1,22 @@ +From: Lorenzo Bianconi +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 +Signed-off-by: Lorenzo Bianconi +--- + +--- 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--- diff --git a/package/kernel/mac80211/patches/ath/558-ath9k-dynack-introduce-ath_dynack_set_timeout-routin.patch b/package/kernel/mac80211/patches/ath/558-ath9k-dynack-introduce-ath_dynack_set_timeout-routin.patch deleted file mode 100644 index e13a15026e..0000000000 --- a/package/kernel/mac80211/patches/ath/558-ath9k-dynack-introduce-ath_dynack_set_timeout-routin.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 4420866ef1b602682b009e0186fbb8aefd2125be Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -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 -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/wireless/ath/ath9k/dynack.c | 37 ++++++++++++++----------- - 1 file changed, 21 insertions(+), 16 deletions(-) - -diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c -index f112fa5b2eac..38dbe25919f7 100644 ---- a/drivers/net/wireless/ath/ath9k/dynack.c -+++ b/drivers/net/wireless/ath/ath9k/dynack.c -@@ -78,6 +78,24 @@ static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac) - return true; - } - -+/** -+ * 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(struct ath_hw *ah, const u8 *mac) - */ - 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(struct ath_hw *ah) - 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_hw *ah, struct sk_buff *skb, - 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); - --- -2.17.1 - diff --git a/package/kernel/mac80211/patches/ath/559-ath9k-dynack-properly-set-last-timeout-timestamp-in-.patch b/package/kernel/mac80211/patches/ath/559-ath9k-dynack-properly-set-last-timeout-timestamp-in-.patch deleted file mode 100644 index 9504af1419..0000000000 --- a/package/kernel/mac80211/patches/ath/559-ath9k-dynack-properly-set-last-timeout-timestamp-in-.patch +++ /dev/null @@ -1,32 +0,0 @@ -From e5b56ce50eab31d24df6a70cf025db3acc4aa3ac Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -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 -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/wireless/ath/ath9k/dynack.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c -index 38dbe25919f7..398ea872751f 100644 ---- 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; --- -2.17.1 - diff --git a/package/kernel/mac80211/patches/ath/560-ath9k-dynack-set-max-timeout-according-to-channel-wi.patch b/package/kernel/mac80211/patches/ath/560-ath9k-dynack-set-max-timeout-according-to-channel-wi.patch deleted file mode 100644 index f40289cca4..0000000000 --- a/package/kernel/mac80211/patches/ath/560-ath9k-dynack-set-max-timeout-according-to-channel-wi.patch +++ /dev/null @@ -1,96 +0,0 @@ -From 3f737abb7d53cc80d619a3b4a30b6fa63cdc8df7 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -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 -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/wireless/ath/ath9k/dynack.c | 38 +++++++++++++++++++------ - 1 file changed, 30 insertions(+), 8 deletions(-) - -diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c -index 398ea872751f..fe9181533de3 100644 ---- a/drivers/net/wireless/ath/ath9k/dynack.c -+++ b/drivers/net/wireless/ath/ath9k/dynack.c -@@ -20,11 +20,30 @@ - - #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(struct ath_hw *ah) - */ - 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 ath_hw *ah) - 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_hw *ah, struct sk_buff *skb, - 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; - --- -2.17.1 - diff --git a/package/kernel/mac80211/patches/ath/561-ath9k-dynack-set-ackto-to-max-timeout-in-ath_dynack_.patch b/package/kernel/mac80211/patches/ath/561-ath9k-dynack-set-ackto-to-max-timeout-in-ath_dynack_.patch deleted file mode 100644 index 5b75096e19..0000000000 --- a/package/kernel/mac80211/patches/ath/561-ath9k-dynack-set-ackto-to-max-timeout-in-ath_dynack_.patch +++ /dev/null @@ -1,78 +0,0 @@ -From cc783bfa67e87d2e6206f7626b7bbb74d5c5f269 Mon Sep 17 00:00:00 2001 -From: Lorenzo Bianconi -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 -Signed-off-by: Lorenzo Bianconi ---- - drivers/net/wireless/ath/ath9k/dynack.c | 20 +++++++++++++------- - 1 file changed, 13 insertions(+), 7 deletions(-) - -diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c -index fe9181533de3..f786be04d0ac 100644 ---- 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(&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; - } --- -2.17.1 - diff --git a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch index 8221d78197..47ecc9c655 100644 --- a/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/ath/921-ath10k_init_devices_synchronously.patch @@ -14,8 +14,8 @@ Signed-off-by: Sven Eckelmann --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -3071,6 +3071,16 @@ int ath10k_core_register(struct ath10k * - +@@ -2720,6 +2720,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 diff --git a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch b/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch index b1172cd17d..3fd6bca819 100644 --- a/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch +++ b/package/kernel/mac80211/patches/ath/930-ath10k_add_tpt_led_trigger.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -8669,6 +8669,21 @@ static int ath10k_mac_init_rd(struct ath +@@ -8282,6 +8282,21 @@ static int ath10k_mac_init_rd(struct ath return 0; } @@ -22,9 +22,9 @@ int ath10k_mac_register(struct ath10k *ar) { static const u32 cipher_suites[] = { -@@ -8995,6 +9010,12 @@ int ath10k_mac_register(struct ath10k *a +@@ -8571,6 +8586,12 @@ int ath10k_mac_register(struct ath10k *a - ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; + wiphy_ext_feature_set(ar->hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); +#ifdef CPTCFG_MAC80211_LEDS + ieee80211_create_tpt_led_trigger(ar->hw, diff --git a/package/kernel/mac80211/patches/ath/960-0010-ath10k-limit-htt-rx-ring-size.patch b/package/kernel/mac80211/patches/ath/960-0010-ath10k-limit-htt-rx-ring-size.patch index 05fce6a168..810e97a783 100644 --- a/package/kernel/mac80211/patches/ath/960-0010-ath10k-limit-htt-rx-ring-size.patch +++ b/package/kernel/mac80211/patches/ath/960-0010-ath10k-limit-htt-rx-ring-size.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/htt.h +++ b/drivers/net/wireless/ath/ath10k/htt.h -@@ -226,7 +226,7 @@ enum htt_rx_ring_flags { +@@ -238,7 +238,7 @@ enum htt_rx_ring_flags { }; #define HTT_RX_RING_SIZE_MIN 128 diff --git a/package/kernel/mac80211/patches/ath/960-0011-ath10k-limit-pci-buffer-size.patch b/package/kernel/mac80211/patches/ath/960-0011-ath10k-limit-pci-buffer-size.patch index 0c25fb3f04..283f4d819f 100644 --- a/package/kernel/mac80211/patches/ath/960-0011-ath10k-limit-pci-buffer-size.patch +++ b/package/kernel/mac80211/patches/ath/960-0011-ath10k-limit-pci-buffer-size.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ath/ath10k/pci.c +++ b/drivers/net/wireless/ath/ath10k/pci.c -@@ -131,7 +131,7 @@ static struct ce_attr host_ce_config_wla +@@ -142,7 +142,7 @@ static struct ce_attr host_ce_config_wla .flags = CE_ATTR_FLAGS, .src_nentries = 0, .src_sz_max = 2048, @@ -9,7 +9,7 @@ .recv_cb = ath10k_pci_htt_htc_rx_cb, }, -@@ -140,7 +140,7 @@ static struct ce_attr host_ce_config_wla +@@ -151,7 +151,7 @@ static struct ce_attr host_ce_config_wla .flags = CE_ATTR_FLAGS, .src_nentries = 0, .src_sz_max = 2048, @@ -18,7 +18,7 @@ .recv_cb = ath10k_pci_htc_rx_cb, }, -@@ -167,7 +167,7 @@ static struct ce_attr host_ce_config_wla +@@ -178,7 +178,7 @@ static struct ce_attr host_ce_config_wla .flags = CE_ATTR_FLAGS, .src_nentries = 0, .src_sz_max = 512, @@ -27,7 +27,7 @@ .recv_cb = ath10k_pci_htt_rx_cb, }, -@@ -192,7 +192,7 @@ static struct ce_attr host_ce_config_wla +@@ -203,7 +203,7 @@ static struct ce_attr host_ce_config_wla .flags = CE_ATTR_FLAGS, .src_nentries = 0, .src_sz_max = 2048, diff --git a/package/kernel/mac80211/patches/ath/972-ath10k_fix-crash-due-to-wrong-handling-of-peer_bw_rxnss_override-parameter.patch b/package/kernel/mac80211/patches/ath/972-ath10k_fix-crash-due-to-wrong-handling-of-peer_bw_rxnss_override-parameter.patch index c99ba55955..d8f6887cd0 100644 --- a/package/kernel/mac80211/patches/ath/972-ath10k_fix-crash-due-to-wrong-handling-of-peer_bw_rxnss_override-parameter.patch +++ b/package/kernel/mac80211/patches/ath/972-ath10k_fix-crash-due-to-wrong-handling-of-peer_bw_rxnss_override-parameter.patch @@ -23,7 +23,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling 3 files changed, 52 insertions(+), 23 deletions(-) --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -2515,7 +2515,7 @@ static void ath10k_peer_assoc_h_vht(stru +@@ -2469,7 +2469,7 @@ static void ath10k_peer_assoc_h_vht(stru const u16 *vht_mcs_mask; u8 ampdu_factor; u8 max_nss, vht_mcs; @@ -32,7 +32,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling if (WARN_ON(ath10k_mac_vif_chan(vif, &def))) return; -@@ -2575,23 +2575,45 @@ static void ath10k_peer_assoc_h_vht(stru +@@ -2529,23 +2529,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); @@ -92,7 +92,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling } static void ath10k_peer_assoc_h_qos(struct ath10k *ar, -@@ -2743,9 +2765,9 @@ static int ath10k_peer_assoc_prepare(str +@@ -2697,9 +2719,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); @@ -105,7 +105,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling } --- a/drivers/net/wireless/ath/ath10k/wmi.c +++ b/drivers/net/wireless/ath/ath10k/wmi.c -@@ -7552,12 +7552,7 @@ ath10k_wmi_peer_assoc_fill_10_4(struct a +@@ -7357,12 +7357,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); @@ -121,7 +121,7 @@ v9: use SM/MS macros from code.h to simplify shift/mask handling static int --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h -@@ -6478,7 +6478,19 @@ struct wmi_10_2_peer_assoc_complete_cmd +@@ -6357,7 +6357,19 @@ struct wmi_10_2_peer_assoc_complete_cmd __le32 info0; /* WMI_PEER_ASSOC_INFO0_ */ } __packed; diff --git a/package/kernel/mac80211/patches/ath/973-ath10k_fix-band_center_freq-handling-for-VHT160-in-recent-firmwares.patch b/package/kernel/mac80211/patches/ath/973-ath10k_fix-band_center_freq-handling-for-VHT160-in-recent-firmwares.patch index 65f42520cb..9a7c749cb1 100644 --- a/package/kernel/mac80211/patches/ath/973-ath10k_fix-band_center_freq-handling-for-VHT160-in-recent-firmwares.patch +++ b/package/kernel/mac80211/patches/ath/973-ath10k_fix-band_center_freq-handling-for-VHT160-in-recent-firmwares.patch @@ -13,7 +13,7 @@ v2: fix trailing whitespace issue and fix some typos within the commit note 2 files changed, 8 insertions(+), 10 deletions(-) --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -4573,13 +4573,6 @@ static struct ieee80211_sta_vht_cap ath1 +@@ -4473,13 +4473,6 @@ static struct ieee80211_sta_vht_cap ath1 vht_cap.cap |= val; } @@ -29,7 +29,7 @@ v2: fix trailing whitespace issue and fix some typos within the commit note 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 -@@ -1700,13 +1700,18 @@ void ath10k_wmi_put_wmi_channel(struct w +@@ -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; diff --git a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch b/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch index 97b7550e34..50ed63b065 100644 --- a/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch +++ b/package/kernel/mac80211/patches/ath/974-ath10k_add-LED-and-GPIO-controlling-support-for-various-chipsets.patch @@ -85,7 +85,7 @@ v13: create mode 100644 drivers/net/wireless/ath/ath10k/leds.h --- a/drivers/net/wireless/ath/ath10k/Kconfig +++ b/drivers/net/wireless/ath/ath10k/Kconfig -@@ -71,6 +71,16 @@ config ATH10K_DEBUGFS +@@ -69,6 +69,16 @@ config ATH10K_DEBUGFS If unsure, say Y to make it easier to debug problems. @@ -114,7 +114,7 @@ v13: ath10k_core-$(CONFIG_DEV_COREDUMP) += coredump.o --- a/local-symbols +++ b/local-symbols -@@ -144,6 +144,7 @@ ATH10K_DEBUG= +@@ -142,6 +142,7 @@ ATH10K_DEBUG= ATH10K_DEBUGFS= ATH10K_SPECTRAL= ATH10K_THERMAL= @@ -124,57 +124,57 @@ v13: WCN36XX= --- a/drivers/net/wireless/ath/ath10k/core.c +++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -24,6 +24,7 @@ +@@ -34,6 +34,7 @@ #include "testmode.h" #include "wmi-ops.h" #include "coredump.h" +#include "leds.h" unsigned int ath10k_debug_mask; - EXPORT_SYMBOL(ath10k_debug_mask); -@@ -60,6 +61,7 @@ static const struct ath10k_hw_params ath + 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, - .bus = ATH10K_BUS_PCI, .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, -@@ -130,6 +132,7 @@ static const struct ath10k_hw_params ath +@@ -129,6 +131,7 @@ static const struct ath10k_hw_params ath + .id = QCA9887_HW_1_0_VERSION, .dev_id = QCA9887_1_0_DEVICE_ID, - .bus = ATH10K_BUS_PCI, .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, -@@ -337,6 +340,7 @@ static const struct ath10k_hw_params ath +@@ -293,6 +296,7 @@ static const struct ath10k_hw_params ath + .id = QCA99X0_HW_2_0_DEV_VERSION, .dev_id = QCA99X0_2_0_DEVICE_ID, - .bus = ATH10K_BUS_PCI, .name = "qca99x0 hw2.0", + .led_pin = 17, .patch_load_addr = QCA99X0_HW_2_0_PATCH_LOAD_ADDR, .uart_pin = 7, .otp_exe_param = 0x00000700, -@@ -378,6 +382,7 @@ static const struct ath10k_hw_params ath +@@ -331,6 +335,7 @@ static const struct ath10k_hw_params ath + .id = QCA9984_HW_1_0_DEV_VERSION, .dev_id = QCA9984_1_0_DEVICE_ID, - .bus = ATH10K_BUS_PCI, .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, -@@ -426,6 +431,7 @@ static const struct ath10k_hw_params ath +@@ -374,6 +379,7 @@ static const struct ath10k_hw_params ath + .id = QCA9888_HW_2_0_DEV_VERSION, .dev_id = QCA9888_2_0_DEVICE_ID, - .bus = ATH10K_BUS_PCI, .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, -@@ -2788,6 +2794,10 @@ int ath10k_core_start(struct ath10k *ar, +@@ -2441,6 +2447,10 @@ int ath10k_core_start(struct ath10k *ar, + if (status) goto err_hif_stop; - } + status = ath10k_leds_start(ar); + if (status) @@ -183,7 +183,7 @@ v13: return 0; err_hif_stop: -@@ -3044,9 +3054,18 @@ static void ath10k_core_register_work(st +@@ -2695,9 +2705,18 @@ static void ath10k_core_register_work(st goto err_spectral_destroy; } @@ -202,7 +202,7 @@ v13: err_spectral_destroy: ath10k_spectral_destroy(ar); err_debug_destroy: -@@ -3092,6 +3111,8 @@ void ath10k_core_unregister(struct ath10 +@@ -2741,6 +2760,8 @@ void ath10k_core_unregister(struct ath10 if (!test_bit(ATH10K_FLAG_CORE_REGISTERED, &ar->dev_flags)) return; @@ -213,7 +213,7 @@ v13: * 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 -@@ -14,6 +14,7 @@ +@@ -25,6 +25,7 @@ #include #include #include @@ -221,7 +221,15 @@ v13: #include "htt.h" #include "htc.h" -@@ -1170,6 +1171,13 @@ struct ath10k { +@@ -908,7 +909,6 @@ struct ath10k { + u32 low_5ghz_chan; + u32 high_5ghz_chan; + bool ani_enabled; +- + bool p2p; + + struct { +@@ -1099,6 +1099,13 @@ struct ath10k { } testmode; struct { @@ -237,7 +245,7 @@ v13: u32 fw_warm_reset_counter; --- a/drivers/net/wireless/ath/ath10k/hw.h +++ b/drivers/net/wireless/ath/ath10k/hw.h -@@ -514,6 +514,7 @@ struct ath10k_hw_params { +@@ -504,6 +504,7 @@ struct ath10k_hw_params { const char *name; u32 patch_load_addr; int uart_pin; @@ -397,7 +405,7 @@ v13: +#endif /* _LEDS_H_ */ --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -23,6 +23,7 @@ +@@ -33,6 +33,7 @@ #include "wmi-tlv.h" #include "wmi-ops.h" #include "wow.h" @@ -408,9 +416,9 @@ v13: --- a/drivers/net/wireless/ath/ath10k/wmi-ops.h +++ b/drivers/net/wireless/ath/ath10k/wmi-ops.h @@ -216,7 +216,10 @@ struct wmi_ops { - struct sk_buff *(*gen_bb_timing) - (struct ath10k *ar, - const struct wmi_bb_timing_cfg_arg *arg); + 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); @@ -418,7 +426,7 @@ v13: }; int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id); -@@ -1080,6 +1083,35 @@ ath10k_wmi_force_fw_hang(struct ath10k * +@@ -1054,6 +1057,35 @@ ath10k_wmi_force_fw_hang(struct ath10k * return ath10k_wmi_cmd_send(ar, skb, ar->wmi.cmd->force_fw_hang_cmdid); } @@ -456,7 +464,7 @@ v13: { --- a/drivers/net/wireless/ath/ath10k/wmi-tlv.c +++ b/drivers/net/wireless/ath/ath10k/wmi-tlv.c -@@ -4364,6 +4364,8 @@ static const struct wmi_ops wmi_tlv_ops +@@ -3976,6 +3976,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, @@ -467,7 +475,7 @@ v13: 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 -@@ -7372,6 +7372,49 @@ ath10k_wmi_op_gen_peer_set_param(struct +@@ -7177,6 +7177,49 @@ ath10k_wmi_op_gen_peer_set_param(struct return skb; } @@ -517,7 +525,7 @@ v13: static struct sk_buff * ath10k_wmi_op_gen_set_psmode(struct ath10k *ar, u32 vdev_id, enum wmi_sta_ps_mode psmode) -@@ -9029,6 +9072,9 @@ static const struct wmi_ops wmi_ops = { +@@ -8788,6 +8831,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, @@ -527,7 +535,7 @@ v13: /* .gen_bcn_tmpl not implemented */ /* .gen_prb_tmpl not implemented */ /* .gen_p2p_go_bcn_ie not implemented */ -@@ -9099,6 +9145,8 @@ static const struct wmi_ops wmi_10_1_ops +@@ -8858,6 +8904,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, @@ -536,7 +544,7 @@ v13: /* .gen_bcn_tmpl not implemented */ /* .gen_prb_tmpl not implemented */ /* .gen_p2p_go_bcn_ie not implemented */ -@@ -9171,6 +9219,8 @@ static const struct wmi_ops wmi_10_2_ops +@@ -8929,6 +8977,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, @@ -545,16 +553,16 @@ v13: /* .gen_pdev_enable_adaptive_cca not implemented */ }; -@@ -9242,6 +9292,8 @@ static const struct wmi_ops wmi_10_2_4_o +@@ -8999,6 +9049,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_bb_timing = ath10k_wmi_10_2_4_op_gen_bb_timing, + .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 */ -@@ -9322,6 +9374,8 @@ static const struct wmi_ops wmi_10_4_ops +@@ -9078,6 +9130,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, @@ -565,7 +573,7 @@ v13: int ath10k_wmi_attach(struct ath10k *ar) --- a/drivers/net/wireless/ath/ath10k/wmi.h +++ b/drivers/net/wireless/ath/ath10k/wmi.h -@@ -3005,6 +3005,41 @@ enum wmi_10_4_feature_mask { +@@ -2942,6 +2942,41 @@ enum wmi_10_4_feature_mask { }; diff --git a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch b/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch index 8922ffed81..dfe2829468 100644 --- a/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch +++ b/package/kernel/mac80211/patches/ath/975-ath10k-use-tpt-trigger-by-default.patch @@ -16,9 +16,9 @@ Signed-off-by: Mathias Kresin --- a/drivers/net/wireless/ath/ath10k/core.h +++ b/drivers/net/wireless/ath/ath10k/core.h -@@ -1219,6 +1219,10 @@ struct ath10k { - struct ath10k_bus_params bus_param; - struct completion peer_delete_done; +@@ -1144,6 +1144,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; @@ -42,8 +42,8 @@ Signed-off-by: Mathias Kresin if (ret) --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -9027,7 +9027,7 @@ int ath10k_mac_register(struct ath10k *a - ar->hw->weight_multiplier = ATH10K_AIRTIME_WEIGHT_MULTIPLIER; +@@ -8603,7 +8603,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, diff --git a/package/kernel/mac80211/patches/ath/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch b/package/kernel/mac80211/patches/ath/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch deleted file mode 100644 index 4f247e29f7..0000000000 --- a/package/kernel/mac80211/patches/ath/976-ath10k-Check-if-station-exists-before-forwarding-tx-.patch +++ /dev/null @@ -1,83 +0,0 @@ -From cc8ec75f5ad4acf9babe5e26a10c9bca10624593 Mon Sep 17 00:00:00 2001 -From: Hauke Mehrtens -Date: Sun, 18 Aug 2019 15:33:51 +0200 -Subject: [PATCH] ath10k: Check if station exists before forwarding tx airtime - report - -It looks like the FW on QCA9984 already reports the tx airtimes before -the station is added to the peer entry. The peer entry is created in -ath10k_peer_map_event() just with the vdev_id and the ethaddr, but -not with a station entry, this is added later in ath10k_peer_create() in -callbacks from mac80211. - -When there is no sta added to the peer entry, this function fails -because it calls ieee80211_sta_register_airtime() with NULL. - -This was reported in OpenWrt some time ago: -https://bugs.openwrt.org/index.php?do=details&task_id=2414 - -This commit should fix this crash: -[ 75.991714] Unable to handle kernel paging request at virtual address fffff9e8 -[ 75.991756] pgd = c0204000 -[ 75.997955] [fffff9e8] *pgd=5fdfd861, *pte=00000000, *ppte=00000000 -[ 76.000537] Internal error: Oops: 37 [#1] SMP ARM -[ 76.006686] Modules linked in: pppoe ppp_async ath10k_pci ath10k_core ath pptp pppox ppp_mppe ppp_generic mac80211 iptable_nat ipt_REJECT ipt_MASQUERADE cfg80211 xt_time xt_tcpudp xt_tcpmss xt_statistic xt_state xt_recent xt_nat xt_multiport xt_mark xt_mac xt_limit xt_length xt_hl xt_helper xt_esp xt_ecn xt_dscp xt_conntrack xt_connmark xt_connlimit xt_connbytes xt_comment xt_TCPMSS xt_REDIRECT xt_LOG xt_HL xt_FLOWOFFLOAD xt_DSCP xt_CT xt_CLASSIFY usbserial slhc nf_reject_ipv4 nf_nat_redirect nf_nat_masquerade_ipv4 nf_conntrack_ipv4 nf_nat_ipv4 nf_log_ipv4 nf_flow_table_hw nf_flow_table nf_defrag_ipv4 nf_conntrack_rtcache nf_conntrack_netlink iptable_raw iptable_mangle iptable_filter ipt_ah ipt_ECN ip_tables crc_ccitt compat chaoskey fuse sch_cake sch_tbf sch_ingress sch_htb sch_hfsc em_u32 cls_u32 -[ 76.059974] cls_tcindex cls_route cls_matchall cls_fw cls_flow cls_basic act_skbedit act_mirred ledtrig_usbport xt_set ip_set_list_set ip_set_hash_netportnet ip_set_hash_netport ip_set_hash_netnet ip_set_hash_netiface ip_set_hash_net ip_set_hash_mac ip_set_hash_ipportnet ip_set_hash_ipportip ip_set_hash_ipport ip_set_hash_ipmark ip_set_hash_ip ip_set_bitmap_port ip_set_bitmap_ipmac ip_set_bitmap_ip ip_set nfnetlink ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6t_NPT ip6t_MASQUERADE nf_nat_masquerade_ipv6 nf_nat nf_conntrack nf_log_ipv6 nf_log_common ip6table_mangle ip6table_filter ip6_tables ip6t_REJECT x_tables nf_reject_ipv6 msdos ip_gre gre ifb sit tunnel4 ip_tunnel tun vfat fat hfsplus cifs nls_utf8 nls_iso8859_15 nls_iso8859_1 nls_cp850 nls_cp437 nls_cp1250 sha1_generic md5 md4 -[ 76.130634] usb_storage leds_gpio xhci_plat_hcd xhci_pci xhci_hcd dwc3 dwc3_of_simple ohci_platform ohci_hcd phy_qcom_dwc3 ahci ehci_platform sd_mod ahci_platform libahci_platform libahci libata scsi_mod ehci_hcd gpio_button_hotplug ext4 mbcache jbd2 exfat crc32c_generic -[ 76.154772] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.14.132 #0 -[ 76.177001] Hardware name: Generic DT based system -[ 76.182990] task: c0b06d80 task.stack: c0b00000 -[ 76.187832] PC is at ieee80211_sta_register_airtime+0x24/0x148 [mac80211] -[ 76.192211] LR is at ath10k_htt_t2h_msg_handler+0x678/0x10f4 [ath10k_core] -[ 76.199052] pc : [] lr : [] psr: a0000113 -[ 76.205820] sp : c0b01d54 ip : 00000002 fp : bf869c0c -[ 76.211981] r10: 0000003c r9 : dbdca138 r8 : 00060002 -[ 76.217192] r7 : 00000000 r6 : dabe1150 r5 : 00000000 r4 : dbdc95c0 -[ 76.222401] r3 : 00000000 r2 : 00060002 r1 : 00000000 r0 : 00000000 -[ 76.229003] Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none -[ 76.235509] Control: 10c5787d Table: 5c94006a DAC: 00000051 -[ 76.242716] Process swapper/0 (pid: 0, stack limit = 0xc0b00210) -[ 76.248446] Stack: (0xc0b01d54 to 0xc0b02000) -[ 76.254532] 1d40: dbdc95c0 00000000 dabe1150 -[ 76.258808] 1d60: 00000001 dabe1150 dbdca138 0000003c bf869c0c bf83e8b0 00000002 c0314b10 -[ 76.266969] 1d80: dbdc9c70 00000001 00000001 dabe114c 00010000 00000000 dbdcd724 bf88f3d8 -[ 76.275126] 1da0: c0310d28 db393c00 dbdc95c0 00000000 c0b01dd0 c07fb4c4 dbdcd724 00000001 -[ 76.283286] 1dc0: 00000022 bf88b09c db393c00 00000022 c0b01dd0 c0b01dd0 00000000 dbdcc5c0 -[ 76.291445] 1de0: bf88f04c dbdcd654 dbdcd71c dbdc95c0 00000014 dbdcd724 dbdcc5c0 00000005 -[ 76.299605] 1e00: 0004b400 bf85c360 00000000 bf87101c c0b01e24 00000006 00000000 dbdc95c0 -[ 76.307764] 1e20: 00000001 00000040 0000012c c0b01e80 1cf51000 bf85c448 dbdcd440 dbdc95c0 -[ 76.315925] 1e40: dbdca440 ffffa880 00000040 bf88cb68 dbdcd440 00000001 00000040 ffffa880 -[ 76.324084] 1e60: c0b02d00 c06d72e0 dd990080 c0a3f080 c0b255dc c0b047e4 c090afac c090e80c -[ 76.332244] 1e80: c0b01e80 c0b01e80 c0b01e88 c0b01e88 dd4cc200 00000000 00000003 c0b0208c -[ 76.340405] 1ea0: c0b02080 40000003 ffffe000 00000100 c0b02080 c03015c8 00000000 00000001 -[ 76.348564] 1ec0: dd408000 c0a38210 c0b2c7c0 0000000a ffffa880 c0b02d00 c07fb764 00200102 -[ 76.356723] 1ee0: dd4cc268 c0a3e414 00000000 00000000 00000001 dd408000 de803000 00000000 -[ 76.364883] 1f00: 00000000 c03247cc c0a3e414 c0368f1c c0b03f60 c0b153cc de80200c de802000 -[ 76.373042] 1f20: c0b01f48 c0301488 c0308630 60000013 ffffffff c0b01f7c 00000000 c0b00000 -[ 76.381204] 1f40: 00000000 c030c08c 00000001 00000000 00000000 c0315180 ffffe000 c0b03cc0 -[ 76.389363] 1f60: c0b03c70 00000000 00000000 c0a2da28 00000000 00000000 c0b01f90 c0b01f98 -[ 76.397522] 1f80: c030862c c0308630 60000013 ffffffff 00000051 00000000 ffffe000 c035dd18 -[ 76.405681] 1fa0: 000000bf c0b03c40 00000000 c0b2c000 dddfce80 c035e060 c0b2c040 c0a00cf4 -[ 76.413842] 1fc0: ffffffff ffffffff 00000000 c0a0067c c0a2da28 00000000 00000000 c0b2c1d4 -[ 76.422001] 1fe0: c0b03c5c c0a2da24 c0b07ee0 4220406a 512f04d0 4220807c 00000000 00000000 -[ 76.430335] [] (ieee80211_sta_register_airtime [mac80211]) from [<00000002>] (0x2) -[ 76.438314] Code: e1cd81f0 e1a08002 e1cda1f8 e58de020 (e5102618) -[ 76.446965] ---[ end trace 227a38ade964d642 ]--- - -Fixes: bb31b7cb106c ("ath10k: report tx airtime provided by fw") -Signed-off-by: Hauke Mehrtens ---- - drivers/net/wireless/ath/ath10k/htt_rx.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/ath/ath10k/htt_rx.c -+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c -@@ -2639,7 +2639,7 @@ static void ath10k_htt_rx_tx_compl_ind(s - spin_lock_bh(&ar->data_lock); - - peer = ath10k_peer_find_by_id(ar, peer_id); -- if (!peer) { -+ if (!peer || !peer->sta) { - spin_unlock_bh(&ar->data_lock); - rcu_read_unlock(); - continue; diff --git a/package/kernel/mac80211/patches/ath/976-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch b/package/kernel/mac80211/patches/ath/976-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch new file mode 100644 index 0000000000..260c0c7867 --- /dev/null +++ b/package/kernel/mac80211/patches/ath/976-ath10k-Limit-available-channels-via-DT-ieee80211-fre.patch @@ -0,0 +1,39 @@ +From bbf0a8af2261bc7ae39b227ff6a1e9f45a008c27 Mon Sep 17 00:00:00 2001 +From: Sven Eckelmann +Date: Mon, 30 Jul 2018 17:31:41 +0200 +Subject: [PATCH] ath10k: Limit available channels via DT ieee80211-freq-limit + +Tri-band devices (1x 2.4GHz + 2x 5GHz) often incorporate special filters in +the RX and TX path. These filtered channel can in theory still be used by +the hardware but the signal strength is reduced so much that it makes no +sense. + +There is already a DT property to limit the available channels but ath10k +has to manually call this functionality to limit the currrently set wiphy +channels further. + +Signed-off-by: Sven Eckelmann + +Forwarded: https://patchwork.kernel.org/patch/10549245/ +--- + drivers/net/wireless/ath/ath10k/mac.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -18,6 +18,7 @@ + + #include "mac.h" + ++#include + #include + #include + #include +@@ -8390,6 +8391,7 @@ int ath10k_mac_register(struct ath10k *a + ar->hw->wiphy->bands[NL80211_BAND_5GHZ] = band; + } + ++ wiphy_read_of_freq_limits(ar->hw->wiphy); + ath10k_mac_setup_ht_vht_cap(ar); + + ar->hw->wiphy->interface_modes = diff --git a/package/kernel/mac80211/patches/ath/977-ath10k-add-support-for-configuring-management-packet.patch b/package/kernel/mac80211/patches/ath/977-ath10k-add-support-for-configuring-management-packet.patch new file mode 100644 index 0000000000..4f2f64a60a --- /dev/null +++ b/package/kernel/mac80211/patches/ath/977-ath10k-add-support-for-configuring-management-packet.patch @@ -0,0 +1,89 @@ +From: Sriram R +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 +Signed-off-by: Kalle Valo + +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) { +@@ -5468,9 +5484,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); + +@@ -5676,6 +5693,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); + } + diff --git a/package/kernel/mac80211/patches/ath/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch b/package/kernel/mac80211/patches/ath/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch new file mode 100644 index 0000000000..b82b16a92b --- /dev/null +++ b/package/kernel/mac80211/patches/ath/978-ath10k-fix-possible-out-of-bound-access-of-ath10k_ra.patch @@ -0,0 +1,66 @@ +From: Sriram R +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 +Signed-off-by: Kalle Valo + +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; + } +@@ -5699,22 +5699,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); diff --git a/package/kernel/mac80211/patches/ath/979-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch b/package/kernel/mac80211/patches/ath/979-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch new file mode 100644 index 0000000000..8695b7e094 --- /dev/null +++ b/package/kernel/mac80211/patches/ath/979-ath10k-fix-incorrect-multicast-broadcast-rate-settin.patch @@ -0,0 +1,43 @@ +From: Pradeep kumar Chitrapu +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 +Signed-off-by: Zhi Chen +Signed-off-by: Pradeep Kumar Chitrapu + +Origin: other, https://patchwork.kernel.org/patch/10723033/ + +--- a/drivers/net/wireless/ath/ath10k/mac.c ++++ b/drivers/net/wireless/ath/ath10k/mac.c +@@ -5484,8 +5484,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; + +@@ -5658,7 +5658,11 @@ static void ath10k_bss_info_changed(stru + if (changed & BSS_CHANGED_MCAST_RATE && + !WARN_ON(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; diff --git a/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch b/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch index f60163f941..9cd23ce1b7 100644 --- a/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch +++ b/package/kernel/mac80211/patches/ath/980-ath10k-fix-max-antenna-gain-unit.patch @@ -20,7 +20,7 @@ Forwarded: https://patchwork.kernel.org/patch/10986723/ --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -1041,7 +1041,7 @@ static int ath10k_monitor_vdev_start(str +@@ -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; @@ -28,8 +28,8 @@ Forwarded: https://patchwork.kernel.org/patch/10986723/ + arg.channel.max_antenna_gain = channel->max_antenna_gain; reinit_completion(&ar->vdev_setup_done); - reinit_completion(&ar->vdev_delete_done); -@@ -1487,7 +1487,7 @@ static int ath10k_vdev_start_restart(str + +@@ -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; @@ -38,7 +38,7 @@ Forwarded: https://patchwork.kernel.org/patch/10986723/ if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { arg.ssid = arvif->u.ap.ssid; -@@ -3168,7 +3168,7 @@ static int ath10k_update_channel_list(st +@@ -3139,7 +3139,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; diff --git a/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch b/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch index 9fbb254127..07247a0577 100644 --- a/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch +++ b/package/kernel/mac80211/patches/ath/981-ath10k-adjust-tx-power-reduction-for-US-regulatory-d.patch @@ -28,8 +28,8 @@ Forwarded: no --- a/drivers/net/wireless/ath/ath10k/mac.c +++ b/drivers/net/wireless/ath/ath10k/mac.c -@@ -1009,6 +1009,40 @@ static inline int ath10k_vdev_setup_sync - return ar->last_wmi_vdev_start_status; +@@ -988,6 +988,40 @@ static inline int ath10k_vdev_setup_sync + return 0; } +static u32 ath10k_get_max_antenna_gain(struct ath10k *ar, @@ -69,7 +69,7 @@ Forwarded: no static int ath10k_monitor_vdev_start(struct ath10k *ar, int vdev_id) { struct cfg80211_chan_def *chandef = NULL; -@@ -1041,7 +1075,8 @@ static int ath10k_monitor_vdev_start(str +@@ -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; @@ -78,8 +78,8 @@ Forwarded: no + channel->max_antenna_gain); reinit_completion(&ar->vdev_setup_done); - reinit_completion(&ar->vdev_delete_done); -@@ -1487,7 +1522,8 @@ static int ath10k_vdev_start_restart(str + +@@ -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; @@ -89,7 +89,7 @@ Forwarded: no if (arvif->vdev_type == WMI_VDEV_TYPE_AP) { arg.ssid = arvif->u.ap.ssid; -@@ -3168,7 +3204,8 @@ static int ath10k_update_channel_list(st +@@ -3139,7 +3175,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; diff --git a/package/kernel/mac80211/patches/ath/982-ath10k-fix-latency-issue-for-QCA988x.patch b/package/kernel/mac80211/patches/ath/982-ath10k-fix-latency-issue-for-QCA988x.patch deleted file mode 100644 index 3702abb412..0000000000 --- a/package/kernel/mac80211/patches/ath/982-ath10k-fix-latency-issue-for-QCA988x.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Miaoqing Pan -Subject: [PATCH] ath10k: fix latency issue for QCA988x -Date: Thu, 29 Aug 2019 10:45:12 +0800 - -Bad latency is found on QCA988x, the issue was introduced by -commit 4504f0e5b571 ("ath10k: sdio: workaround firmware UART -pin configuration bug"). If uart_pin_workaround is false, this -change will set uart pin even if uart_print is false. - -Tested HW: QCA9880 -Tested FW: 10.2.4-1.0-00037 - -Fixes: 4504f0e5b571 ("ath10k: sdio: workaround firmware UART pin configuration bug") -Signed-off-by: Miaoqing Pan ---- - drivers/net/wireless/ath/ath10k/core.c | 15 +++++++++------ - 1 file changed, 9 insertions(+), 6 deletions(-) - ---- a/drivers/net/wireless/ath/ath10k/core.c -+++ b/drivers/net/wireless/ath/ath10k/core.c -@@ -2124,12 +2124,15 @@ static int ath10k_init_uart(struct ath10 - return ret; - } - -- if (!uart_print && ar->hw_params.uart_pin_workaround) { -- ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, -- ar->hw_params.uart_pin); -- if (ret) { -- ath10k_warn(ar, "failed to set UART TX pin: %d", ret); -- return ret; -+ if (!uart_print) { -+ if (ar->hw_params.uart_pin_workaround) { -+ ret = ath10k_bmi_write32(ar, hi_dbg_uart_txpin, -+ ar->hw_params.uart_pin); -+ if (ret) { -+ ath10k_warn(ar, "failed to set UART TX pin: %d", -+ ret); -+ return ret; -+ } - } - - return 0; diff --git a/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch b/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch index 3e8505b5b4..167332d916 100644 --- a/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch +++ b/package/kernel/mac80211/patches/brcm/040-brcmutil_option.patch @@ -1,7 +1,6 @@ --- a/drivers/net/wireless/broadcom/brcm80211/Kconfig +++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig -@@ -1,6 +1,6 @@ - # SPDX-License-Identifier: GPL-2.0-only +@@ -1,5 +1,5 @@ config BRCMUTIL - tristate + tristate "Broadcom 802.11 driver utility functions" diff --git a/package/kernel/mac80211/patches/brcm/103-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch b/package/kernel/mac80211/patches/brcm/103-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch deleted file mode 100644 index 0d38084e90..0000000000 --- a/package/kernel/mac80211/patches/brcm/103-v5.4-0001-brcmfmac-add-160MHz-in-chandef_to_chanspec.patch +++ /dev/null @@ -1,56 +0,0 @@ -From f491645f039420fb7e14283e21b90772571c807c Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 10:45:30 +0200 -Subject: [PATCH] brcmfmac: add 160MHz in chandef_to_chanspec() - -The function chandef_to_chanspec() was not handling 160MHz bandwidth -resulting in wrong encoding of the channel. That resulting in firmware -rejecting the provided channel specification. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 21 ++++++++++++++++++- - 1 file changed, 20 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -276,8 +276,26 @@ static u16 chandef_to_chanspec(struct br - else - ch_inf.sb = BRCMU_CHAN_SB_UU; - break; -- case NL80211_CHAN_WIDTH_80P80: - case NL80211_CHAN_WIDTH_160: -+ ch_inf.bw = BRCMU_CHAN_BW_160; -+ if (primary_offset == -70) -+ ch_inf.sb = BRCMU_CHAN_SB_LLL; -+ else if (primary_offset == -50) -+ ch_inf.sb = BRCMU_CHAN_SB_LLU; -+ else if (primary_offset == -30) -+ ch_inf.sb = BRCMU_CHAN_SB_LUL; -+ else if (primary_offset == -10) -+ ch_inf.sb = BRCMU_CHAN_SB_LUU; -+ else if (primary_offset == 10) -+ ch_inf.sb = BRCMU_CHAN_SB_ULL; -+ else if (primary_offset == 30) -+ ch_inf.sb = BRCMU_CHAN_SB_ULU; -+ else if (primary_offset == 50) -+ ch_inf.sb = BRCMU_CHAN_SB_UUL; -+ else -+ ch_inf.sb = BRCMU_CHAN_SB_UUU; -+ break; -+ case NL80211_CHAN_WIDTH_80P80: - case NL80211_CHAN_WIDTH_5: - case NL80211_CHAN_WIDTH_10: - default: -@@ -296,6 +314,7 @@ static u16 chandef_to_chanspec(struct br - } - d11inf->encchspec(&ch_inf); - -+ brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec); - return ch_inf.chspec; - } - diff --git a/package/kernel/mac80211/patches/brcm/103-v5.4-0002-brcmfmac-enable-DFS_OFFLOAD-extended-feature-if-supp.patch b/package/kernel/mac80211/patches/brcm/103-v5.4-0002-brcmfmac-enable-DFS_OFFLOAD-extended-feature-if-supp.patch deleted file mode 100644 index 6d0756ca78..0000000000 --- a/package/kernel/mac80211/patches/brcm/103-v5.4-0002-brcmfmac-enable-DFS_OFFLOAD-extended-feature-if-supp.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 011a56a3336a5de9c3152c169cd52ff79b8c3f89 Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 10:45:31 +0200 -Subject: [PATCH] brcmfmac: enable DFS_OFFLOAD extended feature if supported - -If the firmware supports 802.11h and the device can operate in 5GHz -band we can enable DFS_OFFLOAD extended feature. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 5 +++++ - drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 1 + - drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h | 4 +++- - 3 files changed, 9 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -6733,6 +6733,11 @@ static int brcmf_setup_wiphy(struct wiph - } - } - -+ if (wiphy->bands[NL80211_BAND_5GHZ] && -+ brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DOT11H)) -+ wiphy_ext_feature_set(wiphy, -+ NL80211_EXT_FEATURE_DFS_OFFLOAD); -+ - wiphy_read_of_freq_limits(wiphy); - - return 0; ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c -@@ -39,6 +39,7 @@ static const struct brcmf_feat_fwcap brc - { BRCMF_FEAT_P2P, "p2p" }, - { BRCMF_FEAT_MONITOR, "monitor" }, - { BRCMF_FEAT_MONITOR_FMT_RADIOTAP, "rtap" }, -+ { BRCMF_FEAT_DOT11H, "802.11h" } - }; - - #ifdef DEBUG ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h -@@ -25,6 +25,7 @@ - * MONITOR: firmware can pass monitor packets to host. - * MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header - * MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header -+ * DOT11H: firmware supports 802.11h - */ - #define BRCMF_FEAT_LIST \ - BRCMF_FEAT_DEF(MBSS) \ -@@ -43,7 +44,8 @@ - BRCMF_FEAT_DEF(FWSUP) \ - BRCMF_FEAT_DEF(MONITOR) \ - BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \ -- BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) -+ BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) \ -+ BRCMF_FEAT_DEF(DOT11H) - - /* - * Quirks: diff --git a/package/kernel/mac80211/patches/brcm/103-v5.4-0003-brcmfmac-allow-160MHz-in-custom-regulatory-rules.patch b/package/kernel/mac80211/patches/brcm/103-v5.4-0003-brcmfmac-allow-160MHz-in-custom-regulatory-rules.patch deleted file mode 100644 index 3df8057ced..0000000000 --- a/package/kernel/mac80211/patches/brcm/103-v5.4-0003-brcmfmac-allow-160MHz-in-custom-regulatory-rules.patch +++ /dev/null @@ -1,34 +0,0 @@ -From fa9050927fa885410055ee03c948c2252693d296 Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 10:45:32 +0200 -Subject: [PATCH] brcmfmac: allow 160MHz in custom regulatory rules - -The driver has custom regulatory rules which had maximum bandwidth -for 5GHz channels set to 80MHz. As a consequence the driver can -not use 160MHz in AP mode even when the device supports it. So -relax the rules allowing 160MHz. After wiphy_register() the channel -flags are updated according what the device actually supports. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -189,9 +189,9 @@ static const struct ieee80211_regdomain - */ - REG_RULE(2484-10, 2484+10, 20, 6, 20, 0), - /* IEEE 802.11a, channel 36..64 */ -- REG_RULE(5150-10, 5350+10, 80, 6, 20, 0), -+ REG_RULE(5150-10, 5350+10, 160, 6, 20, 0), - /* IEEE 802.11a, channel 100..165 */ -- REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), } -+ REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), } - }; - - /* Note: brcmf_cipher_suites is an array of int defining which cipher suites diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch deleted file mode 100644 index 45a9a339fa..0000000000 --- a/package/kernel/mac80211/patches/brcm/104-v5.4-0001-Revert-brcmfmac-fix-NULL-pointer-derefence-during-US.patch +++ /dev/null @@ -1,168 +0,0 @@ -From a84a60ccdd65278485fb495f468a5ab91a75c649 Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 11:05:06 +0200 -Subject: [PATCH] Revert "brcmfmac: fix NULL pointer derefence during USB - disconnect" - -This reverts commit 5cdb0ef6144f47440850553579aa923c20a63f23. Subsequent -changes make rework the driver code fixing the issue differently. - -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 11 ++--------- - .../wireless/broadcom/brcm80211/brcmfmac/bcdc.h | 6 ++---- - .../wireless/broadcom/brcm80211/brcmfmac/core.c | 4 +--- - .../broadcom/brcm80211/brcmfmac/fwsignal.c | 16 ++++------------ - .../broadcom/brcm80211/brcmfmac/fwsignal.h | 3 +-- - .../wireless/broadcom/brcm80211/brcmfmac/proto.c | 10 ++-------- - .../wireless/broadcom/brcm80211/brcmfmac/proto.h | 3 +-- - 7 files changed, 13 insertions(+), 40 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c -@@ -479,18 +479,11 @@ fail: - return -ENOMEM; - } - --void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) --{ -- struct brcmf_bcdc *bcdc = drvr->proto->pd; -- -- brcmf_fws_detach_pre_delif(bcdc->fws); --} -- --void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) -+void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) - { - struct brcmf_bcdc *bcdc = drvr->proto->pd; - - drvr->proto->pd = NULL; -- brcmf_fws_detach_post_delif(bcdc->fws); -+ brcmf_fws_detach(bcdc->fws); - kfree(bcdc); - } ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h -@@ -7,16 +7,14 @@ - - #ifdef CPTCFG_BRCMFMAC_PROTO_BCDC - int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr); --void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr); --void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr); -+void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr); - void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state); - void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp, - bool success); - struct brcmf_fws_info *drvr_to_fws(struct brcmf_pub *drvr); - #else - static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; } --static void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) {}; --static inline void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) {} -+static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {} - #endif - - #endif /* BRCMFMAC_BCDC_H */ ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1335,8 +1335,6 @@ void brcmf_detach(struct device *dev) - - brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); - -- brcmf_proto_detach_pre_delif(drvr); -- - /* make sure primary interface removed last */ - for (i = BRCMF_MAX_IFS-1; i > -1; i--) - brcmf_remove_interface(drvr->iflist[i], false); -@@ -1346,7 +1344,7 @@ void brcmf_detach(struct device *dev) - - brcmf_bus_stop(drvr->bus_if); - -- brcmf_proto_detach_post_delif(drvr); -+ brcmf_proto_detach(drvr); - - bus_if->drvr = NULL; - wiphy_free(drvr->wiphy); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c -@@ -2432,25 +2432,17 @@ struct brcmf_fws_info *brcmf_fws_attach( - return fws; - - fail: -- brcmf_fws_detach_pre_delif(fws); -- brcmf_fws_detach_post_delif(fws); -+ brcmf_fws_detach(fws); - return ERR_PTR(rc); - } - --void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws) -+void brcmf_fws_detach(struct brcmf_fws_info *fws) - { - if (!fws) - return; -- if (fws->fws_wq) { -- destroy_workqueue(fws->fws_wq); -- fws->fws_wq = NULL; -- } --} - --void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws) --{ -- if (!fws) -- return; -+ if (fws->fws_wq) -+ destroy_workqueue(fws->fws_wq); - - /* cleanup */ - brcmf_fws_lock(fws); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h -@@ -7,8 +7,7 @@ - #define FWSIGNAL_H_ - - struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); --void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws); --void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws); -+void brcmf_fws_detach(struct brcmf_fws_info *fws); - void brcmf_fws_debugfs_create(struct brcmf_pub *drvr); - bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); - bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c -@@ -56,22 +56,16 @@ fail: - return -ENOMEM; - } - --void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr) -+void brcmf_proto_detach(struct brcmf_pub *drvr) - { - brcmf_dbg(TRACE, "Enter\n"); - - if (drvr->proto) { - if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) -- brcmf_proto_bcdc_detach_post_delif(drvr); -+ brcmf_proto_bcdc_detach(drvr); - else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF) - brcmf_proto_msgbuf_detach(drvr); - kfree(drvr->proto); - drvr->proto = NULL; - } - } -- --void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr) --{ -- if (drvr->proto && drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) -- brcmf_proto_bcdc_detach_pre_delif(drvr); --} ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h -@@ -43,8 +43,7 @@ struct brcmf_proto { - - - int brcmf_proto_attach(struct brcmf_pub *drvr); --void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr); --void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr); -+void brcmf_proto_detach(struct brcmf_pub *drvr); - - static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, - struct sk_buff *skb, diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch deleted file mode 100644 index d40bf031b8..0000000000 --- a/package/kernel/mac80211/patches/brcm/104-v5.4-0002-brcmfmac-change-the-order-of-things-in-brcmf_detach.patch +++ /dev/null @@ -1,67 +0,0 @@ -From 14fcfd1cc0c05ea58f47dd693fdd13f25dfe995e Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 11:05:07 +0200 -Subject: [PATCH] brcmfmac: change the order of things in brcmf_detach() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -When brcmf_detach() from the bus layer upon rmmod we can no longer -communicate. Hence we will set the bus state to DOWN and cleanup -the event and protocol layer. The network interfaces need to be -deleted before brcmf_cfg80211_detach() because the latter does the -wiphy_unregister() which issues a warning if there are still network -devices linked to the wiphy instance. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Tested-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/core.c | 27 ++++++++++--------- - 1 file changed, 14 insertions(+), 13 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1328,25 +1328,26 @@ void brcmf_detach(struct device *dev) - unregister_inet6addr_notifier(&drvr->inet6addr_notifier); - #endif - -- /* stop firmware event handling */ -- brcmf_fweh_detach(drvr); -- if (drvr->config) -- brcmf_p2p_detach(&drvr->config->p2p); -- - brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); -- -- /* make sure primary interface removed last */ -- for (i = BRCMF_MAX_IFS-1; i > -1; i--) -- brcmf_remove_interface(drvr->iflist[i], false); -- -- brcmf_cfg80211_detach(drvr->config); -- drvr->config = NULL; -- - brcmf_bus_stop(drvr->bus_if); - -+ brcmf_fweh_detach(drvr); - brcmf_proto_detach(drvr); - -+ /* make sure primary interface removed last */ -+ for (i = BRCMF_MAX_IFS - 1; i > -1; i--) { -+ if (drvr->iflist[i]) -+ brcmf_del_if(drvr, drvr->iflist[i]->bsscfgidx, false); -+ } -+ -+ if (drvr->config) { -+ brcmf_p2p_detach(&drvr->config->p2p); -+ brcmf_cfg80211_detach(drvr->config); -+ drvr->config = NULL; -+ } -+ - bus_if->drvr = NULL; -+ - wiphy_free(drvr->wiphy); - } - diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch deleted file mode 100644 index 4c42b2b0c9..0000000000 --- a/package/kernel/mac80211/patches/brcm/104-v5.4-0003-brcmfmac-avoid-firmware-command-in-brcmf_netdev_open.patch +++ /dev/null @@ -1,30 +0,0 @@ -From c613085b74941024194e41b200601b9aa6ee388f Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 11:05:08 +0200 -Subject: [PATCH] brcmfmac: avoid firmware command in brcmf_netdev_open() when - bus is down - -No point in sending a firmware command when bus is down so make it -conditional checking the state. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -579,7 +579,8 @@ static int brcmf_netdev_stop(struct net_ - - brcmf_cfg80211_down(ndev); - -- brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); -+ if (ifp->drvr->bus_if->state == BRCMF_BUS_UP) -+ brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", NULL, 0); - - brcmf_net_setcarrier(ifp, false); - diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch deleted file mode 100644 index d796faa79f..0000000000 --- a/package/kernel/mac80211/patches/brcm/104-v5.4-0004-brcmfmac-clear-events-in-brcmf_fweh_detach-will-alwa.patch +++ /dev/null @@ -1,38 +0,0 @@ -From c33330ac06fe863289643e7a13ecdb6a2502dad7 Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 11:05:09 +0200 -Subject: [PATCH] brcmfmac: clear events in brcmf_fweh_detach() will always - fail - -Clearing firmware events in brcmf_fweh_detach() is always failing -because it is called only upon driver remove and communication -with firmware is no longer possible. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c | 9 --------- - 1 file changed, 9 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c -@@ -303,16 +303,7 @@ void brcmf_fweh_attach(struct brcmf_pub - void brcmf_fweh_detach(struct brcmf_pub *drvr) - { - struct brcmf_fweh_info *fweh = &drvr->fweh; -- struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); -- s8 eventmask[BRCMF_EVENTING_MASK_LEN]; - -- if (ifp) { -- /* clear all events */ -- memset(eventmask, 0, BRCMF_EVENTING_MASK_LEN); -- (void)brcmf_fil_iovar_data_set(ifp, "event_msgs", -- eventmask, -- BRCMF_EVENTING_MASK_LEN); -- } - /* cancel the worker */ - cancel_work_sync(&fweh->event_work); - WARN_ON(!list_empty(&fweh->event_q)); diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch deleted file mode 100644 index 747cf58b7b..0000000000 --- a/package/kernel/mac80211/patches/brcm/104-v5.4-0005-brcmfmac-avoid-firmware-commands-when-bus-is-down.patch +++ /dev/null @@ -1,79 +0,0 @@ -From 1ac11ae949dd883854f4523ef8e3a32aabfd6256 Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 11:05:10 +0200 -Subject: [PATCH] brcmfmac: avoid firmware commands when bus is down - -Upon rmmod a few attempts are made to inform firmware, but there is -no point as the bus is down and these will fail. Avoid them to keep -the logs clean. - -Reported-by: Stefan Wahren -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 23 +++++++++++-------- - 1 file changed, 13 insertions(+), 10 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -1286,17 +1286,21 @@ static void brcmf_link_down(struct brcmf - { - struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); - struct brcmf_pub *drvr = cfg->pub; -+ bool bus_up = drvr->bus_if->state == BRCMF_BUS_UP; - s32 err = 0; - - brcmf_dbg(TRACE, "Enter\n"); - - if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) { -- brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n"); -- err = brcmf_fil_cmd_data_set(vif->ifp, -- BRCMF_C_DISASSOC, NULL, 0); -- if (err) { -- bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", err); -+ if (bus_up) { -+ brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n"); -+ err = brcmf_fil_cmd_data_set(vif->ifp, -+ BRCMF_C_DISASSOC, NULL, 0); -+ if (err) -+ bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", -+ err); - } -+ - if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) || - (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) - cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0, -@@ -1306,7 +1310,8 @@ static void brcmf_link_down(struct brcmf - clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status); - brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0); - if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) { -- brcmf_set_pmk(vif->ifp, NULL, 0); -+ if (bus_up) -+ brcmf_set_pmk(vif->ifp, NULL, 0); - vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE; - } - brcmf_dbg(TRACE, "Exit\n"); -@@ -5004,18 +5009,16 @@ static int brcmf_cfg80211_get_channel(st - struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); - struct net_device *ndev = wdev->netdev; - struct brcmf_pub *drvr = cfg->pub; -- struct brcmf_if *ifp; - struct brcmu_chan ch; - enum nl80211_band band = 0; - enum nl80211_chan_width width = 0; - u32 chanspec; - int freq, err; - -- if (!ndev) -+ if (!ndev || drvr->bus_if->state != BRCMF_BUS_UP) - return -ENODEV; -- ifp = netdev_priv(ndev); - -- err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec); -+ err = brcmf_fil_iovar_int_get(netdev_priv(ndev), "chanspec", &chanspec); - if (err) { - bphy_err(drvr, "chanspec failed (%d)\n", err); - return err; diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch deleted file mode 100644 index 040ab16a6c..0000000000 --- a/package/kernel/mac80211/patches/brcm/104-v5.4-0006-brcmfmac-simply-remove-flowring-if-bus-is-down.patch +++ /dev/null @@ -1,33 +0,0 @@ -From e0bfb9601d4812719167cc4124a0d6db1e2f55e4 Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 11:05:11 +0200 -Subject: [PATCH] brcmfmac: simply remove flowring if bus is down - -When the bus is down, eg. due to rmmod, there is no need to -attempt to inform firmware about it. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 7 +++++++ - 1 file changed, 7 insertions(+) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c -@@ -1398,6 +1398,13 @@ void brcmf_msgbuf_delete_flowring(struct - u8 ifidx; - int err; - -+ /* no need to submit if firmware can not be reached */ -+ if (drvr->bus_if->state != BRCMF_BUS_UP) { -+ brcmf_dbg(MSGBUF, "bus down, flowring will be removed\n"); -+ brcmf_msgbuf_remove_flowring(msgbuf, flowid); -+ return; -+ } -+ - commonring = msgbuf->commonrings[BRCMF_H2D_MSGRING_CONTROL_SUBMIT]; - brcmf_commonring_lock(commonring); - ret_ptr = brcmf_commonring_reserve_for_write(commonring); diff --git a/package/kernel/mac80211/patches/brcm/104-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch b/package/kernel/mac80211/patches/brcm/104-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch deleted file mode 100644 index 444546aaf7..0000000000 --- a/package/kernel/mac80211/patches/brcm/104-v5.4-0007-brcmfmac-remove-unnecessary-strlcpy-upon-obtaining-v.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 4b11c915f00caeef3292ed0429acc579b9da762a Mon Sep 17 00:00:00 2001 -From: Arend van Spriel -Date: Thu, 11 Jul 2019 11:05:12 +0200 -Subject: [PATCH] brcmfmac: remove unnecessary strlcpy() upon obtaining "ver" - iovar - -Recently a strcpy() was replaced by strlcpy(). However, the strcpy() -was not needed in the first place. So removing that line of code. - -Reviewed-by: Hante Meuleman -Reviewed-by: Pieter-Paul Giesberts -Reviewed-by: Franky Lin -Signed-off-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -@@ -258,7 +258,6 @@ int brcmf_c_preinit_dcmds(struct brcmf_i - - /* query for 'ver' to get version info from firmware */ - memset(buf, 0, sizeof(buf)); -- strlcpy(buf, "ver", sizeof(buf)); - err = brcmf_fil_iovar_data_get(ifp, "ver", buf, sizeof(buf)); - if (err < 0) { - bphy_err(drvr, "Retrieving version information failed, %d\n", diff --git a/package/kernel/mac80211/patches/brcm/105-v5.4-brcmfmac-don-t-net_ratelimit-CONSOLE-messages-on-fir.patch b/package/kernel/mac80211/patches/brcm/105-v5.4-brcmfmac-don-t-net_ratelimit-CONSOLE-messages-on-fir.patch deleted file mode 100644 index 60f6e49210..0000000000 --- a/package/kernel/mac80211/patches/brcm/105-v5.4-brcmfmac-don-t-net_ratelimit-CONSOLE-messages-on-fir.patch +++ /dev/null @@ -1,38 +0,0 @@ -From e3b1d879ccda9ffd5332777bb1beeb2cc913faa8 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 21 Jul 2019 21:52:17 +0200 -Subject: [PATCH] brcmfmac: don't net_ratelimit() CONSOLE messages on firmware - crash -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Firmware crash is a pretty rare event and can't happen too frequently as -it has to be followed by a hardware reinitialization and config reload. -It should be safe to don't use net_ratelimit() when it happens. - -For reporting & debugging purposes it's important to provide a complete -log as the last lines are actually the most important. This change -modifies brcmfmac to print all messages in an unlimited way in that -specific case. With this change there should be finally a backtrace of -firmware finally visible after a crash. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 3 ++- - 1 file changed, 2 insertions(+), 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -794,7 +794,8 @@ static void brcmf_pcie_bus_console_read( - if (ch == '\n') { - console->log_str[console->log_idx] = 0; - if (error) -- brcmf_err(bus, "CONSOLE: %s", console->log_str); -+ __brcmf_err(bus, __func__, "CONSOLE: %s", -+ console->log_str); - else - pr_debug("CONSOLE: %s", console->log_str); - console->log_idx = 0; diff --git a/package/kernel/mac80211/patches/brcm/106-v5.4-brcmfmac-remove-set-but-not-used-variable-dtim_perio.patch b/package/kernel/mac80211/patches/brcm/106-v5.4-brcmfmac-remove-set-but-not-used-variable-dtim_perio.patch deleted file mode 100644 index da0d8d5894..0000000000 --- a/package/kernel/mac80211/patches/brcm/106-v5.4-brcmfmac-remove-set-but-not-used-variable-dtim_perio.patch +++ /dev/null @@ -1,54 +0,0 @@ -From cddecd92d1ec2fd05ed1123455e7c6cf6906b5a5 Mon Sep 17 00:00:00 2001 -From: YueHaibing -Date: Wed, 24 Jul 2019 22:12:01 +0800 -Subject: [PATCH] brcmfmac: remove set but not used variable 'dtim_period' - -Fixes gcc '-Wunused-but-set-variable' warning: - -drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c: In function brcmf_update_bss_info: -drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:2962:5: warning: variable dtim_period set but not used [-Wunused-but-set-variable] -drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c: In function brcmf_update_bss_info: -drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:2961:6: warning: variable beacon_interval set but not used [-Wunused-but-set-variable] - -They are never used so can be removed. - -Reported-by: Hulk Robot -Signed-off-by: YueHaibing -Signed-off-by: Kalle Valo ---- - .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 8 +------- - 1 file changed, 1 insertion(+), 7 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -2982,8 +2982,6 @@ static s32 brcmf_update_bss_info(struct - struct brcmf_pub *drvr = cfg->pub; - struct brcmf_bss_info_le *bi; - const struct brcmf_tlv *tim; -- u16 beacon_interval; -- u8 dtim_period; - size_t ie_len; - u8 *ie; - s32 err = 0; -@@ -3007,12 +3005,9 @@ static s32 brcmf_update_bss_info(struct - - ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset); - ie_len = le32_to_cpu(bi->ie_length); -- beacon_interval = le16_to_cpu(bi->beacon_period); - - tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM); -- if (tim) -- dtim_period = tim->data[1]; -- else { -+ if (!tim) { - /* - * active scan was done so we could not get dtim - * information out of probe response. -@@ -3024,7 +3019,6 @@ static s32 brcmf_update_bss_info(struct - bphy_err(drvr, "wl dtim_assoc failed (%d)\n", err); - goto update_bss_info_out; - } -- dtim_period = (u8)var; - } - - update_bss_info_out: diff --git a/package/kernel/mac80211/patches/brcm/107-v5.4-brcmfmac-remove-redundant-assignment-to-pointer-hash.patch b/package/kernel/mac80211/patches/brcm/107-v5.4-brcmfmac-remove-redundant-assignment-to-pointer-hash.patch deleted file mode 100644 index 84573af23e..0000000000 --- a/package/kernel/mac80211/patches/brcm/107-v5.4-brcmfmac-remove-redundant-assignment-to-pointer-hash.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 73c742bb9c9ba30871fdd5c730d5ca8b6712833a Mon Sep 17 00:00:00 2001 -From: Colin Ian King -Date: Fri, 9 Aug 2019 18:22:17 +0100 -Subject: [PATCH] brcmfmac: remove redundant assignment to pointer hash - -The pointer hash is being initialized with a value that is never read -and is being re-assigned a little later on. The assignment is -redundant and hence can be removed. - -Addresses-Coverity: ("Unused value") -Signed-off-by: Colin Ian King -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 1 - - 1 file changed, 1 deletion(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c -@@ -1468,7 +1468,6 @@ static int brcmf_msgbuf_stats_read(struc - seq_printf(seq, "\nh2d_flowrings: depth %u\n", - BRCMF_H2D_TXFLOWRING_MAX_ITEM); - seq_puts(seq, "Active flowrings:\n"); -- hash = msgbuf->flow->hash; - for (i = 0; i < msgbuf->flow->nrofrings; i++) { - if (!msgbuf->flow->rings[i]) - continue; diff --git a/package/kernel/mac80211/patches/brcm/108-v5.4-brcmfmac-replace-strncpy-by-strscpy.patch b/package/kernel/mac80211/patches/brcm/108-v5.4-brcmfmac-replace-strncpy-by-strscpy.patch deleted file mode 100644 index 5efe6a8f14..0000000000 --- a/package/kernel/mac80211/patches/brcm/108-v5.4-brcmfmac-replace-strncpy-by-strscpy.patch +++ /dev/null @@ -1,36 +0,0 @@ -From 5f42b382ead278c1f6c3854765c97eb20491aa2a Mon Sep 17 00:00:00 2001 -From: Xulin Sun -Date: Fri, 23 Aug 2019 15:47:08 +0800 -Subject: [PATCH] brcmfmac: replace strncpy() by strscpy() - -The strncpy() may truncate the copied string, -replace it by the safer strscpy(). - -To avoid below compile warning with gcc 8.2: - -drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:In function 'brcmf_vndr_ie': -drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c:4227:2: -warning: 'strncpy' output truncated before terminating nul copying 3 bytes from a string of the same length [-Wstringop-truncation] - strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1); - ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Signed-off-by: Xulin Sun -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 +--- - 1 file changed, 1 insertion(+), 3 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4244,9 +4244,7 @@ next: - static u32 - brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd) - { -- -- strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1); -- iebuf[VNDR_IE_CMD_LEN - 1] = '\0'; -+ strscpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN); - - put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]); - diff --git a/package/kernel/mac80211/patches/brcm/110-v5.4-0001-brcmfmac-add-stub-version-of-brcmf_debugfs_get_devdi.patch b/package/kernel/mac80211/patches/brcm/110-v5.4-0001-brcmfmac-add-stub-version-of-brcmf_debugfs_get_devdi.patch deleted file mode 100644 index 3fbf0dedd9..0000000000 --- a/package/kernel/mac80211/patches/brcm/110-v5.4-0001-brcmfmac-add-stub-version-of-brcmf_debugfs_get_devdi.patch +++ /dev/null @@ -1,31 +0,0 @@ -From cb34212b1c25f7656a315f956d72696777e88340 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 1 Sep 2019 13:34:35 +0200 -Subject: [PATCH] brcmfmac: add stub version of brcmf_debugfs_get_devdir() -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -In case of compiling driver without DEBUG expose a stub function to make -writing debug code much simpler (no extra conditions). This will allow -e.g. using debugfs_create_file() without any magic if or #ifdef. - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h | 4 ++++ - 1 file changed, 4 insertions(+) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h -@@ -121,6 +121,10 @@ int brcmf_debugfs_add_entry(struct brcmf - int brcmf_debug_create_memdump(struct brcmf_bus *bus, const void *data, - size_t len); - #else -+static inline struct dentry *brcmf_debugfs_get_devdir(struct brcmf_pub *drvr) -+{ -+ return ERR_PTR(-ENOENT); -+} - static inline - int brcmf_debugfs_add_entry(struct brcmf_pub *drvr, const char *fn, - int (*read_fn)(struct seq_file *seq, void *data)) diff --git a/package/kernel/mac80211/patches/brcm/110-v5.4-0002-brcmfmac-add-reset-debugfs-entry-for-testing-reset.patch b/package/kernel/mac80211/patches/brcm/110-v5.4-0002-brcmfmac-add-reset-debugfs-entry-for-testing-reset.patch deleted file mode 100644 index b3d01477a6..0000000000 --- a/package/kernel/mac80211/patches/brcm/110-v5.4-0002-brcmfmac-add-reset-debugfs-entry-for-testing-reset.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 2f8c8e62cd50d72ac68de884a09c6f5a969a269c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Sun, 1 Sep 2019 13:34:36 +0200 -Subject: [PATCH] brcmfmac: add "reset" debugfs entry for testing reset -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This is a trivial debugfs entry for triggering reset just like in case -of firmware crash. It works by writing 1 to it: -echo 1 > reset - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/core.c | 25 +++++++++++++++++++ - 1 file changed, 25 insertions(+) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1107,6 +1107,29 @@ static void brcmf_core_bus_reset(struct - brcmf_bus_reset(drvr->bus_if); - } - -+static ssize_t bus_reset_write(struct file *file, const char __user *user_buf, -+ size_t count, loff_t *ppos) -+{ -+ struct brcmf_pub *drvr = file->private_data; -+ u8 value; -+ -+ if (kstrtou8_from_user(user_buf, count, 0, &value)) -+ return -EINVAL; -+ -+ if (value != 1) -+ return -EINVAL; -+ -+ schedule_work(&drvr->bus_reset); -+ -+ return count; -+} -+ -+static const struct file_operations bus_reset_fops = { -+ .open = simple_open, -+ .llseek = no_llseek, -+ .write = bus_reset_write, -+}; -+ - static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) - { - int ret = -1; -@@ -1182,6 +1205,8 @@ static int brcmf_bus_started(struct brcm - - /* populate debugfs */ - brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); -+ debugfs_create_file("reset", 0600, brcmf_debugfs_get_devdir(drvr), drvr, -+ &bus_reset_fops); - brcmf_feat_debugfs_create(drvr); - brcmf_proto_debugfs_create(drvr); - brcmf_bus_debugfs_create(bus_if); diff --git a/package/kernel/mac80211/patches/brcm/111-v5.4-brcmfmac-use-ph-to-print-small-buffer.patch b/package/kernel/mac80211/patches/brcm/111-v5.4-brcmfmac-use-ph-to-print-small-buffer.patch deleted file mode 100644 index 9576b2b5b2..0000000000 --- a/package/kernel/mac80211/patches/brcm/111-v5.4-brcmfmac-use-ph-to-print-small-buffer.patch +++ /dev/null @@ -1,58 +0,0 @@ -From 0e48b86d9a8f5c695bb02c9c02f6dc7d2ec8f2e2 Mon Sep 17 00:00:00 2001 -From: Andy Shevchenko -Date: Wed, 4 Sep 2019 20:50:52 +0300 -Subject: [PATCH] brcmfmac: use %*ph to print small buffer - -Use %*ph format to print small buffer as hex string. - -Signed-off-by: Andy Shevchenko -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/cfg80211.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -4222,10 +4222,8 @@ brcmf_parse_vndr_ies(const u8 *vndr_ie_b - - vndr_ies->count++; - -- brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n", -- parsed_info->vndrie.oui[0], -- parsed_info->vndrie.oui[1], -- parsed_info->vndrie.oui[2], -+ brcmf_dbg(TRACE, "** OUI %3ph, type 0x%02x\n", -+ parsed_info->vndrie.oui, - parsed_info->vndrie.oui_type); - - if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT) -@@ -4349,12 +4347,10 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c - for (i = 0; i < old_vndr_ies.count; i++) { - vndrie_info = &old_vndr_ies.ie_info[i]; - -- brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n", -+ brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%3ph\n", - vndrie_info->vndrie.id, - vndrie_info->vndrie.len, -- vndrie_info->vndrie.oui[0], -- vndrie_info->vndrie.oui[1], -- vndrie_info->vndrie.oui[2]); -+ vndrie_info->vndrie.oui); - - del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag, - vndrie_info->ie_ptr, -@@ -4386,12 +4382,10 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c - remained_buf_len -= (vndrie_info->ie_len + - VNDR_IE_VSIE_OFFSET); - -- brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n", -+ brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%3ph\n", - vndrie_info->vndrie.id, - vndrie_info->vndrie.len, -- vndrie_info->vndrie.oui[0], -- vndrie_info->vndrie.oui[1], -- vndrie_info->vndrie.oui[2]); -+ vndrie_info->vndrie.oui); - - del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag, - vndrie_info->ie_ptr, diff --git a/package/kernel/mac80211/patches/brcm/112-v5.4-0001-brcmfmac-move-cfg80211_ops-pointer-to-another-struct.patch b/package/kernel/mac80211/patches/brcm/112-v5.4-0001-brcmfmac-move-cfg80211_ops-pointer-to-another-struct.patch deleted file mode 100644 index 653251feff..0000000000 --- a/package/kernel/mac80211/patches/brcm/112-v5.4-0001-brcmfmac-move-cfg80211_ops-pointer-to-another-struct.patch +++ /dev/null @@ -1,95 +0,0 @@ -From ba76ff25ee64d5cfc86209d1fbb3c294b2c04412 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 3 Sep 2019 06:29:26 +0200 -Subject: [PATCH 1/3] brcmfmac: move "cfg80211_ops" pointer to another struct -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -This moves "ops" pointer from "struct brcmf_cfg80211_info" to the -"struct brcmf_pub". This movement makes it possible to allocate wiphy -without attaching cfg80211 (brcmf_cfg80211_attach()). It's required for -later separation of wiphy allocation and driver initialization. - -While at it fix also an unlikely memory leak in the brcmf_attach(). - -Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo ---- - .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 1 - - .../net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h | 1 - - drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c | 9 ++++++--- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 1 + - 4 files changed, 7 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -7202,7 +7202,6 @@ void brcmf_cfg80211_detach(struct brcmf_ - brcmf_pno_detach(cfg); - brcmf_btcoex_detach(cfg); - wiphy_unregister(cfg->wiphy); -- kfree(cfg->ops); - wl_deinit_priv(cfg); - brcmf_free_wiphy(cfg->wiphy); - kfree(cfg); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.h -@@ -292,7 +292,6 @@ struct brcmf_cfg80211_wowl { - */ - struct brcmf_cfg80211_info { - struct wiphy *wiphy; -- struct cfg80211_ops *ops; - struct brcmf_cfg80211_conf *conf; - struct brcmf_p2p_info p2p; - struct brcmf_btcoex_info *btcoex; ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1245,12 +1245,15 @@ int brcmf_attach(struct device *dev, str - return -ENOMEM; - - wiphy = wiphy_new(ops, sizeof(*drvr)); -- if (!wiphy) -+ if (!wiphy) { -+ kfree(ops); - return -ENOMEM; -+ } - - set_wiphy_dev(wiphy, dev); - drvr = wiphy_priv(wiphy); - drvr->wiphy = wiphy; -+ drvr->ops = ops; - - for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) - drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; -@@ -1283,12 +1286,10 @@ int brcmf_attach(struct device *dev, str - goto fail; - } - -- drvr->config->ops = ops; - return 0; - - fail: - brcmf_detach(dev); -- kfree(ops); - - return ret; - } -@@ -1374,6 +1375,8 @@ void brcmf_detach(struct device *dev) - - bus_if->drvr = NULL; - -+ kfree(drvr->ops); -+ - wiphy_free(drvr->wiphy); - } - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h -@@ -97,6 +97,7 @@ struct brcmf_pub { - struct brcmf_bus *bus_if; - struct brcmf_proto *proto; - struct wiphy *wiphy; -+ struct cfg80211_ops *ops; - struct brcmf_cfg80211_info *config; - - /* Internal brcmf items */ diff --git a/package/kernel/mac80211/patches/brcm/112-v5.4-0002-brcmfmac-split-brcmf_attach-and-brcmf_detach-functio.patch b/package/kernel/mac80211/patches/brcm/112-v5.4-0002-brcmfmac-split-brcmf_attach-and-brcmf_detach-functio.patch deleted file mode 100644 index e0b2c7dd21..0000000000 --- a/package/kernel/mac80211/patches/brcm/112-v5.4-0002-brcmfmac-split-brcmf_attach-and-brcmf_detach-functio.patch +++ /dev/null @@ -1,266 +0,0 @@ -From 450914c39f88d1adada26256360dea7050ff4e83 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 3 Sep 2019 06:29:27 +0200 -Subject: [PATCH 2/3] brcmfmac: split brcmf_attach() and brcmf_detach() - functions -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Move code allocating/freeing wiphy out of above functions. This will -allow reinitializing the driver (e.g. on some error) without allocating -a new wiphy. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - .../broadcom/brcm80211/brcmfmac/bus.h | 4 ++- - .../broadcom/brcm80211/brcmfmac/core.c | 33 ++++++++++++++---- - .../broadcom/brcm80211/brcmfmac/pcie.c | 13 +++++-- - .../broadcom/brcm80211/brcmfmac/sdio.c | 15 ++++++-- - .../broadcom/brcm80211/brcmfmac/usb.c | 34 +++++++++++++++---- - 5 files changed, 80 insertions(+), 19 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h -@@ -254,10 +254,12 @@ void brcmf_rx_frame(struct device *dev, - /* Receive async event packet from firmware. Callee disposes of rxp. */ - void brcmf_rx_event(struct device *dev, struct sk_buff *rxp); - -+int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings); - /* Indication from bus module regarding presence/insertion of dongle. */ --int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings); -+int brcmf_attach(struct device *dev); - /* Indication from bus module regarding removal/absence of dongle */ - void brcmf_detach(struct device *dev); -+void brcmf_free(struct device *dev); - /* Indication from bus module that dongle should be reset */ - void brcmf_dev_reset(struct device *dev); - /* Request from bus module to initiate a coredump */ ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1230,13 +1230,11 @@ fail: - return ret; - } - --int brcmf_attach(struct device *dev, struct brcmf_mp_device *settings) -+int brcmf_alloc(struct device *dev, struct brcmf_mp_device *settings) - { - struct wiphy *wiphy; - struct cfg80211_ops *ops; - struct brcmf_pub *drvr = NULL; -- int ret = 0; -- int i; - - brcmf_dbg(TRACE, "Enter\n"); - -@@ -1254,6 +1252,21 @@ int brcmf_attach(struct device *dev, str - drvr = wiphy_priv(wiphy); - drvr->wiphy = wiphy; - drvr->ops = ops; -+ drvr->bus_if = dev_get_drvdata(dev); -+ drvr->bus_if->drvr = drvr; -+ drvr->settings = settings; -+ -+ return 0; -+} -+ -+int brcmf_attach(struct device *dev) -+{ -+ struct brcmf_bus *bus_if = dev_get_drvdata(dev); -+ struct brcmf_pub *drvr = bus_if->drvr; -+ int ret = 0; -+ int i; -+ -+ brcmf_dbg(TRACE, "Enter\n"); - - for (i = 0; i < ARRAY_SIZE(drvr->if2bss); i++) - drvr->if2bss[i] = BRCMF_BSSIDX_INVALID; -@@ -1262,9 +1275,6 @@ int brcmf_attach(struct device *dev, str - - /* Link to bus module */ - drvr->hdrlen = 0; -- drvr->bus_if = dev_get_drvdata(dev); -- drvr->bus_if->drvr = drvr; -- drvr->settings = settings; - - /* Attach and link in the protocol */ - ret = brcmf_proto_attach(drvr); -@@ -1280,7 +1290,7 @@ int brcmf_attach(struct device *dev, str - /* attach firmware event handler */ - brcmf_fweh_attach(drvr); - -- ret = brcmf_bus_started(drvr, ops); -+ ret = brcmf_bus_started(drvr, drvr->ops); - if (ret != 0) { - bphy_err(drvr, "dongle is not responding: err=%d\n", ret); - goto fail; -@@ -1372,6 +1382,15 @@ void brcmf_detach(struct device *dev) - brcmf_cfg80211_detach(drvr->config); - drvr->config = NULL; - } -+} -+ -+void brcmf_free(struct device *dev) -+{ -+ struct brcmf_bus *bus_if = dev_get_drvdata(dev); -+ struct brcmf_pub *drvr = bus_if->drvr; -+ -+ if (!drvr) -+ return; - - bus_if->drvr = NULL; - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -1430,6 +1430,7 @@ static int brcmf_pcie_reset(struct devic - brcmf_pcie_bus_console_read(devinfo, true); - - brcmf_detach(dev); -+ brcmf_free(dev); - - brcmf_pcie_release_irq(devinfo); - brcmf_pcie_release_scratchbuffers(devinfo); -@@ -1824,11 +1825,18 @@ static void brcmf_pcie_setup(struct devi - - brcmf_pcie_intr_enable(devinfo); - brcmf_pcie_hostready(devinfo); -- if (brcmf_attach(&devinfo->pdev->dev, devinfo->settings) == 0) -- return; -+ -+ ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); -+ if (ret) -+ goto fail; -+ ret = brcmf_attach(&devinfo->pdev->dev); -+ if (ret) -+ goto fail; - - brcmf_pcie_bus_console_read(devinfo, false); - -+ return; -+ - fail: - device_release_driver(dev); - } -@@ -1971,6 +1979,7 @@ brcmf_pcie_remove(struct pci_dev *pdev) - brcmf_pcie_intr_disable(devinfo); - - brcmf_detach(&pdev->dev); -+ brcmf_free(&pdev->dev); - - kfree(bus->bus_priv.pcie); - kfree(bus->msgbuf->flowrings); ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c -@@ -4247,17 +4247,26 @@ static void brcmf_sdio_firmware_callback - sdiod->bus_if->chip = bus->ci->chip; - sdiod->bus_if->chiprev = bus->ci->chiprev; - -+ err = brcmf_alloc(sdiod->dev, sdiod->settings); -+ if (err) { -+ brcmf_err("brcmf_alloc failed\n"); -+ goto claim; -+ } -+ - /* Attach to the common layer, reserve hdr space */ -- err = brcmf_attach(sdiod->dev, sdiod->settings); -+ err = brcmf_attach(sdiod->dev); - if (err != 0) { - brcmf_err("brcmf_attach failed\n"); -- sdio_claim_host(sdiod->func1); -- goto checkdied; -+ goto free; - } - - /* ready */ - return; - -+free: -+ brcmf_free(sdiod->dev); -+claim: -+ sdio_claim_host(sdiod->func1); - checkdied: - brcmf_sdio_checkdied(bus); - release: ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c -@@ -1178,8 +1178,12 @@ static void brcmf_usb_probe_phase2(struc - if (ret) - goto error; - -+ ret = brcmf_alloc(devinfo->dev, devinfo->settings); -+ if (ret) -+ goto error; -+ - /* Attach to the common driver interface */ -- ret = brcmf_attach(devinfo->dev, devinfo->settings); -+ ret = brcmf_attach(devinfo->dev); - if (ret) - goto error; - -@@ -1251,7 +1255,10 @@ static int brcmf_usb_probe_cb(struct brc - } - - if (!brcmf_usb_dlneeded(devinfo)) { -- ret = brcmf_attach(devinfo->dev, devinfo->settings); -+ ret = brcmf_alloc(devinfo->dev, devinfo->settings); -+ if (ret) -+ goto fail; -+ ret = brcmf_attach(devinfo->dev); - if (ret) - goto fail; - /* we are done */ -@@ -1279,6 +1286,7 @@ static int brcmf_usb_probe_cb(struct brc - - fail: - /* Release resources in reverse order */ -+ brcmf_free(devinfo->dev); - kfree(bus); - brcmf_usb_detach(devinfo); - return ret; -@@ -1292,6 +1300,7 @@ brcmf_usb_disconnect_cb(struct brcmf_usb - brcmf_dbg(USB, "Enter, bus_pub %p\n", devinfo); - - brcmf_detach(devinfo->dev); -+ brcmf_free(devinfo->dev); - kfree(devinfo->bus_pub.bus); - brcmf_usb_detach(devinfo); - } -@@ -1435,10 +1444,12 @@ static int brcmf_usb_suspend(struct usb_ - - brcmf_dbg(USB, "Enter\n"); - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_SLEEP; -- if (devinfo->wowl_enabled) -+ if (devinfo->wowl_enabled) { - brcmf_cancel_all_urbs(devinfo); -- else -+ } else { - brcmf_detach(&usb->dev); -+ brcmf_free(&usb->dev); -+ } - return 0; - } - -@@ -1451,8 +1462,19 @@ static int brcmf_usb_resume(struct usb_i - struct brcmf_usbdev_info *devinfo = brcmf_usb_get_businfo(&usb->dev); - - brcmf_dbg(USB, "Enter\n"); -- if (!devinfo->wowl_enabled) -- return brcmf_attach(devinfo->dev, devinfo->settings); -+ if (!devinfo->wowl_enabled) { -+ int err; -+ -+ err = brcmf_alloc(&usb->dev, devinfo->settings); -+ if (err) -+ return err; -+ -+ err = brcmf_attach(devinfo->dev); -+ if (err) { -+ brcmf_free(devinfo->dev); -+ return err; -+ } -+ } - - devinfo->bus_pub.state = BRCMFMAC_USB_STATE_UP; - brcmf_usb_rx_fill_all(devinfo); diff --git a/package/kernel/mac80211/patches/brcm/112-v5.4-0003-brcmfmac-don-t-realloc-wiphy-during-PCIe-reset.patch b/package/kernel/mac80211/patches/brcm/112-v5.4-0003-brcmfmac-don-t-realloc-wiphy-during-PCIe-reset.patch deleted file mode 100644 index 511f24dd72..0000000000 --- a/package/kernel/mac80211/patches/brcm/112-v5.4-0003-brcmfmac-don-t-realloc-wiphy-during-PCIe-reset.patch +++ /dev/null @@ -1,51 +0,0 @@ -From a1f5aac1765afbeace9581afa27da34085f68e1d Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Tue, 3 Sep 2019 06:29:28 +0200 -Subject: [PATCH 3/3] brcmfmac: don't realloc wiphy during PCIe reset -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Providing a new wiphy on every PCIe reset was confusing and was causing -configuration problems for some users (supplicant and authenticators). -Sticking to the existing wiphy should make error recovery much simpler -and more reliable. - -Signed-off-by: Rafał Miłecki -Acked-by: Arend van Spriel -Signed-off-by: Kalle Valo ---- - drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - ---- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -+++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -1430,7 +1430,6 @@ static int brcmf_pcie_reset(struct devic - brcmf_pcie_bus_console_read(devinfo, true); - - brcmf_detach(dev); -- brcmf_free(dev); - - brcmf_pcie_release_irq(devinfo); - brcmf_pcie_release_scratchbuffers(devinfo); -@@ -1826,9 +1825,6 @@ static void brcmf_pcie_setup(struct devi - brcmf_pcie_intr_enable(devinfo); - brcmf_pcie_hostready(devinfo); - -- ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); -- if (ret) -- goto fail; - ret = brcmf_attach(&devinfo->pdev->dev); - if (ret) - goto fail; -@@ -1931,6 +1927,10 @@ brcmf_pcie_probe(struct pci_dev *pdev, c - bus->wowl_supported = pci_pme_capable(pdev, PCI_D3hot); - dev_set_drvdata(&pdev->dev, bus); - -+ ret = brcmf_alloc(&devinfo->pdev->dev, devinfo->settings); -+ if (ret) -+ goto fail_bus; -+ - fwreq = brcmf_pcie_prepare_fw_request(devinfo); - if (!fwreq) { - ret = -ENOMEM; diff --git a/package/kernel/mac80211/patches/brcm/300-v4.20-0001-brcmfmac-add-CYW89342-mini-PCIe-device.patch b/package/kernel/mac80211/patches/brcm/300-v4.20-0001-brcmfmac-add-CYW89342-mini-PCIe-device.patch new file mode 100644 index 0000000000..d0d9b20373 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/300-v4.20-0001-brcmfmac-add-CYW89342-mini-PCIe-device.patch @@ -0,0 +1,25 @@ +From 2fef681a4cf7994c882190fd2417b95f30510afb Mon Sep 17 00:00:00 2001 +From: Jia-Shyr Chuang +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 +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + 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), diff --git a/package/kernel/mac80211/patches/brcm/302-v4.20-0001-brcmfmac-fix-wrong-strnchr-usage.patch b/package/kernel/mac80211/patches/brcm/302-v4.20-0001-brcmfmac-fix-wrong-strnchr-usage.patch new file mode 100644 index 0000000000..8267b37864 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/302-v4.20-0001-brcmfmac-fix-wrong-strnchr-usage.patch @@ -0,0 +1,38 @@ +From cb18e2e9ec71d42409a51b83546686c609780dde Mon Sep 17 00:00:00 2001 +From: Rasmus Villemoes +Date: Wed, 22 Aug 2018 15:22:15 +0200 +Subject: [PATCH] brcmfmac: fix wrong strnchr usage + +strnchr takes arguments in the order of its name: string, max bytes to +read, character to search for. Here we're passing '\n' aka 10 as the +buffer size, and searching for sizeof(buf) aka BRCMF_DCMD_SMLEN aka +256 (aka '\0', since it's implicitly converted to char) within those 10 +bytes. + +Just interchanging the last two arguments would still leave a bug, +because if we've been successful once, there are not sizeof(buf) +characters left after the new value of p. + +Since clmver is immediately afterwards passed as a %s argument, I assume +that it is actually a properly nul-terminated string. For that case, we +have strreplace(). + +Signed-off-by: Rasmus Villemoes +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -296,9 +296,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + /* Replace all newline/linefeed characters with space + * character + */ +- ptr = clmver; +- while ((ptr = strnchr(ptr, '\n', sizeof(buf))) != NULL) +- *ptr = ' '; ++ strreplace(clmver, '\n', ' '); + + brcmf_dbg(INFO, "CLM version = %s\n", clmver); + } diff --git a/package/kernel/mac80211/patches/brcm/304-v4.20-0002-brcmfmac-increase-buffer-for-obtaining-firmware-capa.patch b/package/kernel/mac80211/patches/brcm/304-v4.20-0002-brcmfmac-increase-buffer-for-obtaining-firmware-capa.patch new file mode 100644 index 0000000000..11fb4bce45 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/304-v4.20-0002-brcmfmac-increase-buffer-for-obtaining-firmware-capa.patch @@ -0,0 +1,28 @@ +From: Arend van Spriel +Date: Wed, 5 Sep 2018 09:48:59 +0200 +Subject: [PATCH] brcmfmac: increase buffer for obtaining firmware capabilities + +When obtaining the firmware capability a buffer is provided of 512 +bytes. However, if all features in firmware are supported the buffer +needs to be 565 bytes as otherwise truncated information is retrieved +from firmware. Increasing the buffer to 768 bytes on stack. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -178,7 +178,7 @@ static void brcmf_feat_iovar_data_set(st + ifp->fwil_fwerr = false; + } + +-#define MAX_CAPS_BUFFER_SIZE 512 ++#define MAX_CAPS_BUFFER_SIZE 768 + static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp) + { + char caps[MAX_CAPS_BUFFER_SIZE]; diff --git a/package/kernel/mac80211/patches/brcm/305-v4.20-0001-brcmfmac-remove-set-but-not-used-variables-sfdoff-an.patch b/package/kernel/mac80211/patches/brcm/305-v4.20-0001-brcmfmac-remove-set-but-not-used-variables-sfdoff-an.patch new file mode 100644 index 0000000000..192ed1a770 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/305-v4.20-0001-brcmfmac-remove-set-but-not-used-variables-sfdoff-an.patch @@ -0,0 +1,57 @@ +From a8254fa4ba60b85829b6e5ede6564f81cd70d59f Mon Sep 17 00:00:00 2001 +From: YueHaibing +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 +Signed-off-by: Kalle Valo +--- + 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 +@@ -1463,7 +1463,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; + +@@ -1597,7 +1597,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 */ +@@ -3405,7 +3404,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; + +@@ -3448,7 +3446,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) { diff --git a/package/kernel/mac80211/patches/brcm/306-v4.20-0001-brcmfmac-reduce-timeout-for-action-frame-scan.patch b/package/kernel/mac80211/patches/brcm/306-v4.20-0001-brcmfmac-reduce-timeout-for-action-frame-scan.patch new file mode 100644 index 0000000000..a71c1aee03 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/306-v4.20-0001-brcmfmac-reduce-timeout-for-action-frame-scan.patch @@ -0,0 +1,67 @@ +From edb6d6885bef82d1eac432dbeca9fbf4ec349d7e Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Thu, 27 Sep 2018 14:59:44 +0000 +Subject: [PATCH] brcmfmac: reduce timeout for action frame scan + +Finding a common channel to send an action frame out is required for +some action types. Since a loop with several scan retry is used to find +the channel, a short wait time could be considered for each attempt. +This patch reduces the wait time from 1500 to 450 msec for each action +frame scan. + +This patch fixes the WFA p2p certification 5.1.20 failure caused by the +long action frame send time. + +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -74,7 +74,7 @@ + #define P2P_AF_MAX_WAIT_TIME msecs_to_jiffies(2000) + #define P2P_INVALID_CHANNEL -1 + #define P2P_CHANNEL_SYNC_RETRY 5 +-#define P2P_AF_FRM_SCAN_MAX_WAIT msecs_to_jiffies(1500) ++#define P2P_AF_FRM_SCAN_MAX_WAIT msecs_to_jiffies(450) + #define P2P_DEFAULT_SLEEP_TIME_VSDB 200 + + /* WiFi P2P Public Action Frame OUI Subtypes */ +@@ -1134,7 +1134,6 @@ static s32 brcmf_p2p_af_searching_channe + { + struct afx_hdl *afx_hdl = &p2p->afx_hdl; + struct brcmf_cfg80211_vif *pri_vif; +- unsigned long duration; + s32 retry; + + brcmf_dbg(TRACE, "Enter\n"); +@@ -1150,7 +1149,6 @@ static s32 brcmf_p2p_af_searching_channe + * pending action frame tx is cancelled. + */ + retry = 0; +- duration = msecs_to_jiffies(P2P_AF_FRM_SCAN_MAX_WAIT); + while ((retry < P2P_CHANNEL_SYNC_RETRY) && + (afx_hdl->peer_chan == P2P_INVALID_CHANNEL)) { + afx_hdl->is_listen = false; +@@ -1158,7 +1156,8 @@ static s32 brcmf_p2p_af_searching_channe + retry); + /* search peer on peer's listen channel */ + schedule_work(&afx_hdl->afx_work); +- wait_for_completion_timeout(&afx_hdl->act_frm_scan, duration); ++ wait_for_completion_timeout(&afx_hdl->act_frm_scan, ++ P2P_AF_FRM_SCAN_MAX_WAIT); + if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) || + (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, + &p2p->status))) +@@ -1171,7 +1170,7 @@ static s32 brcmf_p2p_af_searching_channe + afx_hdl->is_listen = true; + schedule_work(&afx_hdl->afx_work); + wait_for_completion_timeout(&afx_hdl->act_frm_scan, +- duration); ++ P2P_AF_FRM_SCAN_MAX_WAIT); + } + if ((afx_hdl->peer_chan != P2P_INVALID_CHANNEL) || + (!test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, diff --git a/package/kernel/mac80211/patches/brcm/306-v4.20-0002-brcmfmac-fix-full-timeout-waiting-for-action-frame-o.patch b/package/kernel/mac80211/patches/brcm/306-v4.20-0002-brcmfmac-fix-full-timeout-waiting-for-action-frame-o.patch new file mode 100644 index 0000000000..ef2d0934fc --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/306-v4.20-0002-brcmfmac-fix-full-timeout-waiting-for-action-frame-o.patch @@ -0,0 +1,79 @@ +From fbf07000960d9c8a13fdc17c6de0230d681c7543 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +Date: Thu, 27 Sep 2018 14:59:49 +0000 +Subject: [PATCH] brcmfmac: fix full timeout waiting for action frame + on-channel tx + +The driver sends an action frame down and waits for a completion signal +triggered by the received BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE event +to continue the process. However, the action frame could be transmitted +either on the current channel or on an off channel. For the on-channel +case, only BRCMF_E_ACTION_FRAME_COMPLETE event will be received when +the frame is transmitted, which make the driver always wait a full +timeout duration. This patch has the completion signal be triggered by +receiving the BRCMF_E_ACTION_FRAME_COMPLETE event for the on-channel +case. + +This change fixes WFA p2p certification 5.1.19 failure. + +Signed-off-by: Chung-Hsien Hsu +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c | 17 +++++++++++++++-- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h | 2 ++ + 2 files changed, 17 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -1457,10 +1457,12 @@ int brcmf_p2p_notify_action_tx_complete( + return 0; + + if (e->event_code == BRCMF_E_ACTION_FRAME_COMPLETE) { +- if (e->status == BRCMF_E_STATUS_SUCCESS) ++ if (e->status == BRCMF_E_STATUS_SUCCESS) { + set_bit(BRCMF_P2P_STATUS_ACTION_TX_COMPLETED, + &p2p->status); +- else { ++ if (!p2p->wait_for_offchan_complete) ++ complete(&p2p->send_af_done); ++ } else { + set_bit(BRCMF_P2P_STATUS_ACTION_TX_NOACK, &p2p->status); + /* If there is no ack, we don't need to wait for + * WLC_E_ACTION_FRAME_OFFCHAN_COMPLETE event +@@ -1511,6 +1513,17 @@ static s32 brcmf_p2p_tx_action_frame(str + p2p->af_sent_channel = le32_to_cpu(af_params->channel); + p2p->af_tx_sent_jiffies = jiffies; + ++ if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status) && ++ p2p->af_sent_channel == ++ ieee80211_frequency_to_channel(p2p->remain_on_channel.center_freq)) ++ p2p->wait_for_offchan_complete = false; ++ else ++ p2p->wait_for_offchan_complete = true; ++ ++ brcmf_dbg(TRACE, "Waiting for %s tx completion event\n", ++ (p2p->wait_for_offchan_complete) ? ++ "off-channel" : "on-channel"); ++ + timeout = wait_for_completion_timeout(&p2p->send_af_done, + P2P_AF_MAX_WAIT_TIME); + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.h +@@ -124,6 +124,7 @@ struct afx_hdl { + * @gon_req_action: about to send go negotiation requets frame. + * @block_gon_req_tx: drop tx go negotiation requets frame. + * @p2pdev_dynamically: is p2p device if created by module param or supplicant. ++ * @wait_for_offchan_complete: wait for off-channel tx completion event. + */ + struct brcmf_p2p_info { + struct brcmf_cfg80211_info *cfg; +@@ -144,6 +145,7 @@ struct brcmf_p2p_info { + bool gon_req_action; + bool block_gon_req_tx; + bool p2pdev_dynamically; ++ bool wait_for_offchan_complete; + }; + + s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced); diff --git a/package/kernel/mac80211/patches/brcm/320-v5.0-0001-brcmfmac-Remove-firmware-loading-code-duplication.patch b/package/kernel/mac80211/patches/brcm/320-v5.0-0001-brcmfmac-Remove-firmware-loading-code-duplication.patch new file mode 100644 index 0000000000..eca15a516e --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v5.0-0001-brcmfmac-Remove-firmware-loading-code-duplication.patch @@ -0,0 +1,102 @@ +From a1a3b762163868ad07a4499a73df324f40d5ab0b Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Signed-off-by: Kalle Valo +--- + .../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 { diff --git a/package/kernel/mac80211/patches/brcm/320-v5.0-0002-brcmfmac-Remove-recursion-from-firmware-load-error-h.patch b/package/kernel/mac80211/patches/brcm/320-v5.0-0002-brcmfmac-Remove-recursion-from-firmware-load-error-h.patch new file mode 100644 index 0000000000..1a4a1ec348 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v5.0-0002-brcmfmac-Remove-recursion-from-firmware-load-error-h.patch @@ -0,0 +1,127 @@ +From 5b587496dc63595b71265d986ce69728c2724370 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Signed-off-by: Kalle Valo +--- + .../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; + } + diff --git a/package/kernel/mac80211/patches/brcm/320-v5.0-0003-brcmfmac-Add-support-for-first-trying-to-get-a-board.patch b/package/kernel/mac80211/patches/brcm/320-v5.0-0003-brcmfmac-Add-support-for-first-trying-to-get-a-board.patch new file mode 100644 index 0000000000..727dcbe85a --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v5.0-0003-brcmfmac-Add-support-for-first-trying-to-get-a-board.patch @@ -0,0 +1,77 @@ +From eae8e50669e15002b195177212a6e25afbe7cf4d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Signed-off-by: Kalle Valo +--- + .../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]; + }; + diff --git a/package/kernel/mac80211/patches/brcm/320-v5.0-0004-brcmfmac-Set-board_type-used-for-nvram-file-selectio.patch b/package/kernel/mac80211/patches/brcm/320-v5.0-0004-brcmfmac-Set-board_type-used-for-nvram-file-selectio.patch new file mode 100644 index 0000000000..a33ceaa21e --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v5.0-0004-brcmfmac-Set-board_type-used-for-nvram-file-selectio.patch @@ -0,0 +1,77 @@ +From 0ad4b55b2f29784f93875e6231bf57cd233624a2 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Signed-off-by: Kalle Valo +--- + 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 +@@ -4174,6 +4174,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; + } diff --git a/package/kernel/mac80211/patches/brcm/320-v5.0-0005-brcmfmac-Set-board_type-from-DMI-on-x86-based-machin.patch b/package/kernel/mac80211/patches/brcm/320-v5.0-0005-brcmfmac-Set-board_type-from-DMI-on-x86-based-machin.patch new file mode 100644 index 0000000000..25426e3f10 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v5.0-0005-brcmfmac-Set-board_type-from-DMI-on-x86-based-machin.patch @@ -0,0 +1,179 @@ +From bd1e82bb420adf4ad7cd468d8a482cde622dd69d Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Signed-off-by: Kalle Valo +--- + .../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 ++ * ++ * 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 ++#include ++#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; ++ } ++} diff --git a/package/kernel/mac80211/patches/brcm/320-v5.0-0006-brcmfmac-Cleanup-brcmf_fw_request_done.patch b/package/kernel/mac80211/patches/brcm/320-v5.0-0006-brcmfmac-Cleanup-brcmf_fw_request_done.patch new file mode 100644 index 0000000000..211e9e4a9f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/320-v5.0-0006-brcmfmac-Cleanup-brcmf_fw_request_done.patch @@ -0,0 +1,41 @@ +From 55e491edbf14b2da5419c2a319ea3b1d6368d9a2 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Signed-off-by: Kalle Valo +--- + 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; + } diff --git a/package/kernel/mac80211/patches/brcm/321-v5.0-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch b/package/kernel/mac80211/patches/brcm/321-v5.0-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch new file mode 100644 index 0000000000..88e5c67735 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/321-v5.0-0001-brcmfmac-Add-support-for-getting-nvram-contents-from.patch @@ -0,0 +1,132 @@ +From ce2e6db554fad444fa0b3904fc3015336e0ef765 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + .../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 + #include + #include + #include +@@ -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; diff --git a/package/kernel/mac80211/patches/brcm/321-v5.0-0002-brcmfmac-Fix-ccode-from-EFI-nvram-when-necessary.patch b/package/kernel/mac80211/patches/brcm/321-v5.0-0002-brcmfmac-Fix-ccode-from-EFI-nvram-when-necessary.patch new file mode 100644 index 0000000000..c2fd620d6c --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/321-v5.0-0002-brcmfmac-Fix-ccode-from-EFI-nvram-when-necessary.patch @@ -0,0 +1,97 @@ +From 29ec3394f0bd85c22674ab6693d92da5e2324610 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + .../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); diff --git a/package/kernel/mac80211/patches/brcm/322-v5.0-0001-brcmfmac-fix-spelling-mistake-Retreiving-Retrieving.patch b/package/kernel/mac80211/patches/brcm/322-v5.0-0001-brcmfmac-fix-spelling-mistake-Retreiving-Retrieving.patch new file mode 100644 index 0000000000..c1aea25cba --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/322-v5.0-0001-brcmfmac-fix-spelling-mistake-Retreiving-Retrieving.patch @@ -0,0 +1,34 @@ +From e966a79c2f761a696dec9cfb0e2d4aa977bf78cb Mon Sep 17 00:00:00 2001 +From: Colin Ian King +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 +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + 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; + } diff --git a/package/kernel/mac80211/patches/brcm/323-v5.0-0001-brcmutil-print-invalid-chanspec-when-WARN-ing.patch b/package/kernel/mac80211/patches/brcm/323-v5.0-0001-brcmutil-print-invalid-chanspec-when-WARN-ing.patch new file mode 100644 index 0000000000..566336cbc3 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/323-v5.0-0001-brcmutil-print-invalid-chanspec-when-WARN-ing.patch @@ -0,0 +1,83 @@ +From ae5848cb4511bbbfe0306fcdbe5d9a95cd9546a9 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +Signed-off-by: Kalle Valo +--- + 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; + } + } diff --git a/package/kernel/mac80211/patches/brcm/325-v5.0-brcmfmac-support-STA-info-struct-v7.patch b/package/kernel/mac80211/patches/brcm/325-v5.0-brcmfmac-support-STA-info-struct-v7.patch new file mode 100644 index 0000000000..8ff42462b0 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/325-v5.0-brcmfmac-support-STA-info-struct-v7.patch @@ -0,0 +1,80 @@ +From 4282ff17e557d319e1b988fa4f582792cfaf6fff Mon Sep 17 00:00:00 2001 +From: Dan Haab +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 +Reviewed-by: Rafał Miłecki +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../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 { diff --git a/package/kernel/mac80211/patches/brcm/326-v5.0-brcmfmac-Call-brcmf_dmi_probe-before-brcmf_of_probe.patch b/package/kernel/mac80211/patches/brcm/326-v5.0-brcmfmac-Call-brcmf_dmi_probe-before-brcmf_of_probe.patch new file mode 100644 index 0000000000..01621561c1 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/326-v5.0-brcmfmac-Call-brcmf_dmi_probe-before-brcmf_of_probe.patch @@ -0,0 +1,39 @@ +From 554da3868eb1d7174710c18b4ddd6ff01f6d612c Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Tested-and-reported-by: Peter Robinson +Signed-off-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + 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; + } diff --git a/package/kernel/mac80211/patches/brcm/328-v5.0-0001-brcmfmac-add-credit-numbers-updating-support.patch b/package/kernel/mac80211/patches/brcm/328-v5.0-0001-brcmfmac-add-credit-numbers-updating-support.patch new file mode 100644 index 0000000000..dd40ee2b1f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/328-v5.0-0001-brcmfmac-add-credit-numbers-updating-support.patch @@ -0,0 +1,95 @@ +From 153e22c0ff1260035cd7fe72c8aeead1f5fac757 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../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; +@@ -1237,6 +1238,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) +@@ -1595,19 +1599,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); +@@ -2013,7 +2019,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) +@@ -2210,8 +2216,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; +@@ -2222,7 +2229,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); diff --git a/package/kernel/mac80211/patches/brcm/328-v5.0-0002-brcmfmac-enable-frameburst-mode-in-default-firmware-.patch b/package/kernel/mac80211/patches/brcm/328-v5.0-0002-brcmfmac-enable-frameburst-mode-in-default-firmware-.patch new file mode 100644 index 0000000000..9602792d4f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/328-v5.0-0002-brcmfmac-enable-frameburst-mode-in-default-firmware-.patch @@ -0,0 +1,42 @@ +From a3bdc6deb60bf6be4405058ca49a686c4db08c39 Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + 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 +@@ -6638,6 +6638,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 diff --git a/package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch b/package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch new file mode 100644 index 0000000000..d44c8737ad --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/328-v5.0-0003-brcmfmac-handle-compressed-tx-status-signal.patch @@ -0,0 +1,229 @@ +From e4af3ffb43d50f070134aa1b40d5c3573f57deb1 Mon Sep 17 00:00:00 2001 +From: Chung-Hsien Hsu +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 +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Wright Feng +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../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 +@@ -1455,9 +1455,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; +@@ -1468,60 +1469,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; + } +@@ -1547,7 +1559,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; +@@ -1556,23 +1569,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; + } +@@ -1888,8 +1909,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; +@@ -1912,7 +1931,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); +@@ -2001,7 +2021,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); +@@ -2462,7 +2482,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); + } + diff --git a/package/kernel/mac80211/patches/brcm/329-v5.0-0001-brcmfmac-add-4354-raw-pcie-device-id.patch b/package/kernel/mac80211/patches/brcm/329-v5.0-0001-brcmfmac-add-4354-raw-pcie-device-id.patch new file mode 100644 index 0000000000..ead33db0d5 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/329-v5.0-0001-brcmfmac-add-4354-raw-pcie-device-id.patch @@ -0,0 +1,36 @@ +From eb6b33bfb8f56859df7264dccc2ca8ab7c57342a Mon Sep 17 00:00:00 2001 +From: Winnie Chang +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 +Signed-off-by: Winnie Chang +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + 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 diff --git a/package/kernel/mac80211/patches/brcm/329-v5.0-0002-brcmfmac-set-F2-watermark-to-256-for-4373.patch b/package/kernel/mac80211/patches/brcm/329-v5.0-0002-brcmfmac-set-F2-watermark-to-256-for-4373.patch new file mode 100644 index 0000000000..a915473b8c --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/329-v5.0-0002-brcmfmac-set-F2-watermark-to-256-for-4373.patch @@ -0,0 +1,73 @@ +From e1a08730eeb0bad4d82c3bc40e74854872de618d Mon Sep 17 00:00:00 2001 +From: Wright Feng +Date: Wed, 21 Nov 2018 07:53:44 +0000 +Subject: [PATCH] brcmfmac: set F2 watermark to 256 for 4373 + +We got SDIO_CRC_ERROR with 4373 on SDR104 when doing bi-directional +throughput test. Enable watermark to 256 to guarantee the operation +stability. + +Reviewed-by: Arend van Spriel +Signed-off-by: Wright Feng +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/sdio.c | 26 +++++++++++++++++-- + 1 file changed, 24 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -49,6 +49,10 @@ + #define DCMD_RESP_TIMEOUT msecs_to_jiffies(2500) + #define CTL_DONE_TIMEOUT msecs_to_jiffies(2500) + ++/* watermark expressed in number of words */ ++#define DEFAULT_F2_WATERMARK 0x8 ++#define CY_4373_F2_WATERMARK 0x40 ++ + #ifdef DEBUG + + #define BRCMF_TRAP_INFO_SIZE 80 +@@ -138,6 +142,8 @@ struct rte_console { + /* 1: isolate internal sdio signals, put external pads in tri-state; requires + * sdio bus power cycle to clear (rev 9) */ + #define SBSDIO_DEVCTL_PADS_ISO 0x08 ++/* 1: enable F2 Watermark */ ++#define SBSDIO_DEVCTL_F2WM_ENAB 0x10 + /* Force SD->SB reset mapping (rev 11) */ + #define SBSDIO_DEVCTL_SB_RST_CTL 0x30 + /* Determined by CoreControl bit */ +@@ -4046,6 +4052,7 @@ static void brcmf_sdio_firmware_callback + void *nvram; + u32 nvram_len; + u8 saveclk; ++ u8 devctl; + + brcmf_dbg(TRACE, "Enter: dev=%s, err=%d\n", dev_name(dev), err); + +@@ -4101,8 +4108,23 @@ static void brcmf_sdio_firmware_callback + brcmf_sdiod_writel(sdiod, core->base + SD_REG(hostintmask), + bus->hostintmask, NULL); + +- +- brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, 8, &err); ++ switch (sdiod->func1->device) { ++ case SDIO_DEVICE_ID_CYPRESS_4373: ++ brcmf_dbg(INFO, "set F2 watermark to 0x%x*4 bytes\n", ++ CY_4373_F2_WATERMARK); ++ brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, ++ CY_4373_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); ++ break; ++ } + } else { + /* Disable F2 again */ + sdio_disable_func(sdiod->func2); diff --git a/package/kernel/mac80211/patches/brcm/329-v5.0-0003-brcmfmac-set-SDIO-F1-MesBusyCtrl-for-CYW4373.patch b/package/kernel/mac80211/patches/brcm/329-v5.0-0003-brcmfmac-set-SDIO-F1-MesBusyCtrl-for-CYW4373.patch new file mode 100644 index 0000000000..0e22a1545e --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/329-v5.0-0003-brcmfmac-set-SDIO-F1-MesBusyCtrl-for-CYW4373.patch @@ -0,0 +1,55 @@ +From 58e4bbea0c1d9b5ace11df968c5dc096ce052a73 Mon Sep 17 00:00:00 2001 +From: Madhan Mohan R +Date: Wed, 21 Nov 2018 07:53:45 +0000 +Subject: [PATCH] brcmfmac: set SDIO F1 MesBusyCtrl for CYW4373 + +Along with F2 watermark (existing) configuration, F1 MesBusyCtrl +should be enabled & sdio device RX FIFO watermark should be +configured to avoid overflow errors. + +Reviewed-by: Arend van Spriel +Signed-off-by: Madhan Mohan R +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 3 +++ + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h | 9 ++++++++- + 2 files changed, 11 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -4119,6 +4119,9 @@ static void brcmf_sdio_firmware_callback + devctl |= SBSDIO_DEVCTL_F2WM_ENAB; + brcmf_sdiod_writeb(sdiod, SBSDIO_DEVICE_CTL, devctl, + &err); ++ brcmf_sdiod_writeb(sdiod, SBSDIO_FUNC1_MESBUSYCTRL, ++ CY_4373_F2_WATERMARK | ++ SBSDIO_MESBUSYCTRL_ENAB, &err); + break; + default: + brcmf_sdiod_writeb(sdiod, SBSDIO_WATERMARK, +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.h +@@ -77,7 +77,7 @@ + #define SBSDIO_GPIO_OUT 0x10006 + /* gpio enable */ + #define SBSDIO_GPIO_EN 0x10007 +-/* rev < 7, watermark for sdio device */ ++/* rev < 7, watermark for sdio device TX path */ + #define SBSDIO_WATERMARK 0x10008 + /* control busy signal generation */ + #define SBSDIO_DEVICE_CTL 0x10009 +@@ -104,6 +104,13 @@ + #define SBSDIO_FUNC1_RFRAMEBCHI 0x1001C + /* MesBusyCtl (rev 11) */ + #define SBSDIO_FUNC1_MESBUSYCTRL 0x1001D ++/* Watermark for sdio device RX path */ ++#define SBSDIO_MESBUSY_RXFIFO_WM_MASK 0x7F ++#define SBSDIO_MESBUSY_RXFIFO_WM_SHIFT 0 ++/* Enable busy capability for MES access */ ++#define SBSDIO_MESBUSYCTRL_ENAB 0x80 ++#define SBSDIO_MESBUSYCTRL_ENAB_SHIFT 7 ++ + /* Sdio Core Rev 12 */ + #define SBSDIO_FUNC1_WAKEUPCTRL 0x1001E + #define SBSDIO_FUNC1_WCTRL_ALPWAIT_MASK 0x1 diff --git a/package/kernel/mac80211/patches/brcm/329-v5.0-0004-brcmfmac-add-support-for-CYW43012-SDIO-chipset.patch b/package/kernel/mac80211/patches/brcm/329-v5.0-0004-brcmfmac-add-support-for-CYW43012-SDIO-chipset.patch new file mode 100644 index 0000000000..e53d4bafa0 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/329-v5.0-0004-brcmfmac-add-support-for-CYW43012-SDIO-chipset.patch @@ -0,0 +1,253 @@ +From 35cb51b2162a1a7c5cd977f92595e60ab14d3b22 Mon Sep 17 00:00:00 2001 +From: Chi-Hsien Lin +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 +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Praveen Babu C +Signed-off-by: Kalle Valo +--- + .../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 +@@ -972,6 +972,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) +@@ -677,6 +679,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 +@@ -2402,6 +2412,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); +@@ -2409,7 +2427,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"); +@@ -2436,9 +2454,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); +@@ -3328,20 +3351,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"); +@@ -3350,8 +3398,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"); +@@ -3359,7 +3406,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; +@@ -4051,7 +4098,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); +@@ -4085,8 +4132,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 diff --git a/package/kernel/mac80211/patches/brcm/329-v5.0-0005-brcmfmac-allow-GCI-core-enumuration.patch b/package/kernel/mac80211/patches/brcm/329-v5.0-0005-brcmfmac-allow-GCI-core-enumuration.patch new file mode 100644 index 0000000000..809ee9a516 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/329-v5.0-0005-brcmfmac-allow-GCI-core-enumuration.patch @@ -0,0 +1,60 @@ +From b021a6bc1175442609af0b66d64f850883e155fb Mon Sep 17 00:00:00 2001 +From: Chi-Hsien Lin +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 +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + .../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 */ diff --git a/package/kernel/mac80211/patches/brcm/329-v5.0-0006-brcmfmac-update-43012-F2-watermark-setting-to-fix-DM.patch b/package/kernel/mac80211/patches/brcm/329-v5.0-0006-brcmfmac-update-43012-F2-watermark-setting-to-fix-DM.patch new file mode 100644 index 0000000000..3b44952af4 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/329-v5.0-0006-brcmfmac-update-43012-F2-watermark-setting-to-fix-DM.patch @@ -0,0 +1,49 @@ +From f95a8d9c6aca196f1ace5b2e53a3dd3bc491b1b3 Mon Sep 17 00:00:00 2001 +From: Naveen Gupta +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 +Signed-off-by: Naveen Gupta +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + .../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 + +@@ -4173,6 +4174,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); diff --git a/package/kernel/mac80211/patches/brcm/329-v5.0-0007-brcmfmac-4373-save-restore-support.patch b/package/kernel/mac80211/patches/brcm/329-v5.0-0007-brcmfmac-4373-save-restore-support.patch new file mode 100644 index 0000000000..61c65692de --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/329-v5.0-0007-brcmfmac-4373-save-restore-support.patch @@ -0,0 +1,57 @@ +From 2f2d389efda4caa4c1b69cb4fa2ab217f0fe6d6f Mon Sep 17 00:00:00 2001 +From: Chi-Hsien Lin +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 +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + .../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 diff --git a/package/kernel/mac80211/patches/brcm/329-v5.0-0008-brcmfmac-disable-command-decode-in-sdio_aos.patch b/package/kernel/mac80211/patches/brcm/329-v5.0-0008-brcmfmac-disable-command-decode-in-sdio_aos.patch new file mode 100644 index 0000000000..a1125e588d --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/329-v5.0-0008-brcmfmac-disable-command-decode-in-sdio_aos.patch @@ -0,0 +1,45 @@ +From 29f6589140a10ece8c1d73f58043ea5b3473ab3e Mon Sep 17 00:00:00 2001 +From: Wright Feng +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 +Signed-off-by: Wright Feng +Signed-off-by: Double Lo +Signed-off-by: Madhan Mohan R +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + 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 +@@ -3354,7 +3354,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; diff --git a/package/kernel/mac80211/patches/brcm/330-v5.0-0001-brcmfmac-fix-false-positive-Wmaybe-unintialized-warn.patch b/package/kernel/mac80211/patches/brcm/330-v5.0-0001-brcmfmac-fix-false-positive-Wmaybe-unintialized-warn.patch new file mode 100644 index 0000000000..5d454fd3ee --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/330-v5.0-0001-brcmfmac-fix-false-positive-Wmaybe-unintialized-warn.patch @@ -0,0 +1,34 @@ +From 412dd15c8177d93abe0c8787b83b31c5eb061405 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +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 +Reviewed-by: Hans de Goede +Signed-off-by: Kalle Valo +--- + 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) diff --git a/package/kernel/mac80211/patches/brcm/332-v5.0-0001-brcmfmac-Fix-access-point-mode.patch b/package/kernel/mac80211/patches/brcm/332-v5.0-0001-brcmfmac-Fix-access-point-mode.patch new file mode 100644 index 0000000000..acf587676e --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/332-v5.0-0001-brcmfmac-Fix-access-point-mode.patch @@ -0,0 +1,41 @@ +From 861cb5eb467f5e38dce1aabe4e8db379255bd89b Mon Sep 17 00:00:00 2001 +From: Stefan Wahren +Date: Wed, 12 Dec 2018 20:20:06 +0100 +Subject: [PATCH] brcmfmac: Fix access point mode + +Since commit 1204aa17f3b4 ("brcmfmac: set WIPHY_FLAG_HAVE_AP_SME flag") +the Raspberry Pi 3 A+ (BCM43455) isn't able to operate in AP mode with +hostapd (device_ap_sme=1 use_monitor=0): + +brcmfmac: brcmf_cfg80211_stop_ap: setting AP mode failed -52 + +So add the missing mgmt_stypes for AP mode to fix this. + +Fixes: 1204aa17f3b4 ("brcmfmac: set WIPHY_FLAG_HAVE_AP_SME flag") +Suggested-by: Arend van Spriel +Signed-off-by: Stefan Wahren +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6308,6 +6308,16 @@ brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = + .tx = 0xffff, + .rx = BIT(IEEE80211_STYPE_ACTION >> 4) | + BIT(IEEE80211_STYPE_PROBE_REQ >> 4) ++ }, ++ [NL80211_IFTYPE_AP] = { ++ .tx = 0xffff, ++ .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) | ++ BIT(IEEE80211_STYPE_PROBE_REQ >> 4) | ++ BIT(IEEE80211_STYPE_DISASSOC >> 4) | ++ BIT(IEEE80211_STYPE_AUTH >> 4) | ++ BIT(IEEE80211_STYPE_DEAUTH >> 4) | ++ BIT(IEEE80211_STYPE_ACTION >> 4) + } + }; + diff --git a/package/kernel/mac80211/patches/brcm/340-v5.1-brcmfmac-Add-DMI-nvram-filename-quirk-for-PoV-TAB-P1.patch b/package/kernel/mac80211/patches/brcm/340-v5.1-brcmfmac-Add-DMI-nvram-filename-quirk-for-PoV-TAB-P1.patch new file mode 100644 index 0000000000..4cb3a4243a --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/340-v5.1-brcmfmac-Add-DMI-nvram-filename-quirk-for-PoV-TAB-P1.patch @@ -0,0 +1,51 @@ +From 4d95f99c59b8b814bcf09ba86020d937ec7caa86 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +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 +Signed-off-by: Kalle Valo +--- + .../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, ++ }, + {} + }; + diff --git a/package/kernel/mac80211/patches/brcm/341-v5.1-brcmfmac-add-a-check-for-the-status-of-usb_register.patch b/package/kernel/mac80211/patches/brcm/341-v5.1-brcmfmac-add-a-check-for-the-status-of-usb_register.patch new file mode 100644 index 0000000000..3568910678 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/341-v5.1-brcmfmac-add-a-check-for-the-status-of-usb_register.patch @@ -0,0 +1,28 @@ +From 42daad3343be4a4e1ee03e30a5f5cc731dadfef5 Mon Sep 17 00:00:00 2001 +From: Kangjie Lu +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 +Signed-off-by: Kalle Valo +--- + 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 +@@ -1552,6 +1552,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); + } diff --git a/package/kernel/mac80211/patches/brcm/342-v5.1-brcmfmac-fix-system-warning-message-during-wowl-susp.patch b/package/kernel/mac80211/patches/brcm/342-v5.1-brcmfmac-fix-system-warning-message-during-wowl-susp.patch new file mode 100644 index 0000000000..9115373add --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/342-v5.1-brcmfmac-fix-system-warning-message-during-wowl-susp.patch @@ -0,0 +1,33 @@ +From 3a33bd840523aaa06f4429fbfd38922bf0dc2e8d Mon Sep 17 00:00:00 2001 +From: Lo-Hsiang Lo +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 +Signed-off-by: Lo-Hsiang Lo +Signed-off-by: Chi-Hsien Lin +Signed-off-by: Kalle Valo +--- + 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; diff --git a/package/kernel/mac80211/patches/brcm/344-v5.1-brcmfmac-modify-__brcmf_err-to-take-bus-as-a-paramet.patch b/package/kernel/mac80211/patches/brcm/344-v5.1-brcmfmac-modify-__brcmf_err-to-take-bus-as-a-paramet.patch new file mode 100644 index 0000000000..f83f38f274 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/344-v5.1-brcmfmac-modify-__brcmf_err-to-take-bus-as-a-paramet.patch @@ -0,0 +1,104 @@ +From 5cc898fbcb352b764f8d51c16e10e2eb0056173d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../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 + #include /* 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); + } diff --git a/package/kernel/mac80211/patches/brcm/345-v5.1-brcmfmac-pass-bus-to-the-__brcmf_err-in-pcie.c.patch b/package/kernel/mac80211/patches/brcm/345-v5.1-brcmfmac-pass-bus-to-the-__brcmf_err-in-pcie.c.patch new file mode 100644 index 0000000000..8eceee6859 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/345-v5.1-brcmfmac-pass-bus-to-the-__brcmf_err-in-pcie.c.patch @@ -0,0 +1,266 @@ +From 8602e62441aba276cafd68034b72162fbc5ca0a6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +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 +Signed-off-by: Kalle Valo +--- + .../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 + #include + ++/* 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); + } + + diff --git a/package/kernel/mac80211/patches/brcm/346-v5.1-brcmfmac-add-bphy_err-and-use-it-in-the-cfg80211.c.patch b/package/kernel/mac80211/patches/brcm/346-v5.1-brcmfmac-add-bphy_err-and-use-it-in-the-cfg80211.c.patch new file mode 100644 index 0000000000..efd77d4c00 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/346-v5.1-brcmfmac-add-bphy_err-and-use-it-in-the-cfg80211.c.patch @@ -0,0 +1,2025 @@ +From 3ef005b82e2ad68107fc5814eaa743d171a6c362 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 16 Jan 2019 07:28:54 +0100 +Subject: [PATCH] brcmfmac: add bphy_err() and use it in the cfg80211.c +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This new macro uses wiphy_err() which: +1) Should be the best choice with wiphy already created +2) Uses dev_err() which allows identifying error-affected device + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 497 ++++++++++-------- + .../broadcom/brcm80211/brcmfmac/debug.h | 9 + + 2 files changed, 282 insertions(+), 224 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -457,6 +457,7 @@ static void convert_key_from_CPU(struct + static int + send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + int err; + struct brcmf_wsec_key_le key_le; + +@@ -468,7 +469,7 @@ send_key_to_dongle(struct brcmf_if *ifp, + sizeof(key_le)); + + if (err) +- brcmf_err("wsec_key error (%d)\n", err); ++ bphy_err(wiphy, "wsec_key error (%d)\n", err); + return err; + } + +@@ -508,6 +509,7 @@ static int brcmf_get_first_free_bsscfgid + + static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_mbss_ssid_le mbss_ssid_le; + int bsscfgidx; + int err; +@@ -524,7 +526,7 @@ static int brcmf_cfg80211_request_ap_if( + err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le, + sizeof(mbss_ssid_le)); + if (err < 0) +- brcmf_err("setting ssid failed %d\n", err); ++ bphy_err(wiphy, "setting ssid failed %d\n", err); + + return err; + } +@@ -567,7 +569,7 @@ struct wireless_dev *brcmf_ap_add_vif(st + BRCMF_VIF_EVENT_TIMEOUT); + brcmf_cfg80211_arm_vif_event(cfg, NULL); + if (!err) { +- brcmf_err("timeout occurred\n"); ++ bphy_err(wiphy, "timeout occurred\n"); + err = -EIO; + goto fail; + } +@@ -575,7 +577,7 @@ struct wireless_dev *brcmf_ap_add_vif(st + /* interface created in firmware */ + ifp = vif->ifp; + if (!ifp) { +- brcmf_err("no if pointer provided\n"); ++ bphy_err(wiphy, "no if pointer provided\n"); + err = -ENOENT; + goto fail; + } +@@ -583,7 +585,7 @@ struct wireless_dev *brcmf_ap_add_vif(st + strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1); + err = brcmf_net_attach(ifp, true); + if (err) { +- brcmf_err("Registering netdevice failed\n"); ++ bphy_err(wiphy, "Registering netdevice failed\n"); + free_netdev(ifp->ndev); + goto fail; + } +@@ -620,7 +622,7 @@ static struct wireless_dev *brcmf_cfg802 + brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); + err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type); + if (err) { +- brcmf_err("iface validation failed: err=%d\n", err); ++ bphy_err(wiphy, "iface validation failed: err=%d\n", err); + return ERR_PTR(err); + } + switch (type) { +@@ -645,8 +647,8 @@ static struct wireless_dev *brcmf_cfg802 + } + + if (IS_ERR(wdev)) +- brcmf_err("add iface %s type %d failed: err=%d\n", +- name, type, (int)PTR_ERR(wdev)); ++ bphy_err(wiphy, "add iface %s type %d failed: err=%d\n", name, ++ type, (int)PTR_ERR(wdev)); + else + brcmf_cfg80211_update_proto_addr_mode(wdev); + +@@ -661,12 +663,13 @@ static void brcmf_scan_config_mpc(struct + + void brcmf_set_mpc(struct brcmf_if *ifp, int mpc) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + s32 err = 0; + + if (check_vif_up(ifp->vif)) { + err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc); + if (err) { +- brcmf_err("fail to set mpc\n"); ++ bphy_err(wiphy, "fail to set mpc\n"); + return; + } + brcmf_dbg(INFO, "MPC : %d\n", mpc); +@@ -677,6 +680,7 @@ s32 brcmf_notify_escan_complete(struct b + struct brcmf_if *ifp, bool aborted, + bool fw_abort) + { ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + struct brcmf_scan_params_le params_le; + struct cfg80211_scan_request *scan_request; + u64 reqid; +@@ -711,7 +715,7 @@ s32 brcmf_notify_escan_complete(struct b + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, + ¶ms_le, sizeof(params_le)); + if (err) +- brcmf_err("Scan abort failed\n"); ++ bphy_err(wiphy, "Scan abort failed\n"); + } + + brcmf_scan_config_mpc(ifp, 1); +@@ -763,7 +767,7 @@ static int brcmf_cfg80211_del_ap_iface(s + + err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0); + if (err) { +- brcmf_err("interface_remove failed %d\n", err); ++ bphy_err(wiphy, "interface_remove failed %d\n", err); + goto err_unarm; + } + +@@ -771,7 +775,7 @@ static int brcmf_cfg80211_del_ap_iface(s + ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL, + BRCMF_VIF_EVENT_TIMEOUT); + if (!ret) { +- brcmf_err("timeout occurred\n"); ++ bphy_err(wiphy, "timeout occurred\n"); + err = -EIO; + goto err_unarm; + } +@@ -873,14 +877,14 @@ brcmf_cfg80211_change_iface(struct wiphy + } + err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type); + if (err) { +- brcmf_err("iface validation failed: err=%d\n", err); ++ bphy_err(wiphy, "iface validation failed: err=%d\n", err); + return err; + } + switch (type) { + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_WDS: +- brcmf_err("type (%d) : currently we do not support this type\n", +- type); ++ bphy_err(wiphy, "type (%d) : currently we do not support this type\n", ++ type); + return -EOPNOTSUPP; + case NL80211_IFTYPE_ADHOC: + infra = 0; +@@ -908,7 +912,7 @@ brcmf_cfg80211_change_iface(struct wiphy + } else { + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra); + if (err) { +- brcmf_err("WLC_SET_INFRA error (%d)\n", err); ++ bphy_err(wiphy, "WLC_SET_INFRA error (%d)\n", err); + err = -EAGAIN; + goto done; + } +@@ -999,6 +1003,7 @@ static s32 + brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, + struct cfg80211_scan_request *request) + { ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE + + offsetof(struct brcmf_escan_params_le, params_le); + struct brcmf_escan_params_le *params; +@@ -1030,7 +1035,7 @@ brcmf_run_escan(struct brcmf_cfg80211_in + if (err == -EBUSY) + brcmf_dbg(INFO, "system busy : escan canceled\n"); + else +- brcmf_err("error (%d)\n", err); ++ bphy_err(wiphy, "error (%d)\n", err); + } + + kfree(params); +@@ -1076,21 +1081,22 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, + return -EIO; + + if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { +- brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status); ++ bphy_err(wiphy, "Scanning already: status (%lu)\n", ++ cfg->scan_status); + return -EAGAIN; + } + if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) { +- brcmf_err("Scanning being aborted: status (%lu)\n", +- cfg->scan_status); ++ bphy_err(wiphy, "Scanning being aborted: status (%lu)\n", ++ cfg->scan_status); + return -EAGAIN; + } + if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { +- brcmf_err("Scanning suppressed: status (%lu)\n", +- cfg->scan_status); ++ bphy_err(wiphy, "Scanning suppressed: status (%lu)\n", ++ cfg->scan_status); + return -EAGAIN; + } + if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { +- brcmf_err("Connecting: status (%lu)\n", vif->sme_state); ++ bphy_err(wiphy, "Connecting: status (%lu)\n", vif->sme_state); + return -EAGAIN; + } + +@@ -1124,7 +1130,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, + return 0; + + scan_out: +- brcmf_err("scan error (%d)\n", err); ++ bphy_err(wiphy, "scan error (%d)\n", err); + clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + cfg->scan_request = NULL; + return err; +@@ -1132,36 +1138,41 @@ scan_out: + + static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold) + { ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct wiphy *wiphy = ifp->drvr->wiphy; + s32 err = 0; + +- err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh", +- rts_threshold); ++ err = brcmf_fil_iovar_int_set(ifp, "rtsthresh", rts_threshold); + if (err) +- brcmf_err("Error (%d)\n", err); ++ bphy_err(wiphy, "Error (%d)\n", err); + + return err; + } + + static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold) + { ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct wiphy *wiphy = ifp->drvr->wiphy; + s32 err = 0; + +- err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh", ++ err = brcmf_fil_iovar_int_set(ifp, "fragthresh", + frag_threshold); + if (err) +- brcmf_err("Error (%d)\n", err); ++ bphy_err(wiphy, "Error (%d)\n", err); + + return err; + } + + static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) + { ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct wiphy *wiphy = ifp->drvr->wiphy; + s32 err = 0; + u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL); + +- err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry); ++ err = brcmf_fil_cmd_int_set(ifp, cmd, retry); + if (err) { +- brcmf_err("cmd (%d) , error (%d)\n", cmd, err); ++ bphy_err(wiphy, "cmd (%d) , error (%d)\n", cmd, err); + return err; + } + return err; +@@ -1237,6 +1248,7 @@ static u16 brcmf_map_fw_linkdown_reason( + + static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_wsec_pmk_le pmk; + int i, err; + +@@ -1250,8 +1262,8 @@ static int brcmf_set_pmk(struct brcmf_if + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK, + &pmk, sizeof(pmk)); + if (err < 0) +- brcmf_err("failed to change PSK in firmware (len=%u)\n", +- pmk_len); ++ bphy_err(wiphy, "failed to change PSK in firmware (len=%u)\n", ++ pmk_len); + + return err; + } +@@ -1259,6 +1271,7 @@ static int brcmf_set_pmk(struct brcmf_if + static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason) + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + s32 err = 0; + + brcmf_dbg(TRACE, "Enter\n"); +@@ -1268,7 +1281,7 @@ static void brcmf_link_down(struct brcmf + err = brcmf_fil_cmd_data_set(vif->ifp, + BRCMF_C_DISASSOC, NULL, 0); + if (err) { +- brcmf_err("WLC_DISASSOC failed (%d)\n", err); ++ bphy_err(wiphy, "WLC_DISASSOC failed (%d)\n", err); + } + if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) || + (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) +@@ -1356,7 +1369,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *w + + err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec); + if (err) { +- brcmf_err("wsec failed (%d)\n", err); ++ bphy_err(wiphy, "wsec failed (%d)\n", err); + goto done; + } + +@@ -1368,7 +1381,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *w + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd); + if (err) { +- brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err); ++ bphy_err(wiphy, "WLC_SET_BCNPRD failed (%d)\n", err); + goto done; + } + +@@ -1413,7 +1426,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *w + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL, + target_channel); + if (err) { +- brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err); ++ bphy_err(wiphy, "WLC_SET_CHANNEL failed (%d)\n", err); + goto done; + } + } else +@@ -1425,7 +1438,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *w + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, + &join_params, join_params_size); + if (err) { +- brcmf_err("WLC_SET_SSID failed (%d)\n", err); ++ bphy_err(wiphy, "WLC_SET_SSID failed (%d)\n", err); + goto done; + } + +@@ -1461,6 +1474,8 @@ brcmf_cfg80211_leave_ibss(struct wiphy * + static s32 brcmf_set_wpa_version(struct net_device *ndev, + struct cfg80211_connect_params *sme) + { ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_security *sec; + s32 val = 0; +@@ -1473,9 +1488,9 @@ static s32 brcmf_set_wpa_version(struct + else + val = WPA_AUTH_DISABLED; + brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val); +- err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val); ++ err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val); + if (err) { +- brcmf_err("set wpa_auth failed (%d)\n", err); ++ bphy_err(wiphy, "set wpa_auth failed (%d)\n", err); + return err; + } + sec = &profile->sec; +@@ -1486,6 +1501,8 @@ static s32 brcmf_set_wpa_version(struct + static s32 brcmf_set_auth_type(struct net_device *ndev, + struct cfg80211_connect_params *sme) + { ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_security *sec; + s32 val = 0; +@@ -1506,9 +1523,9 @@ static s32 brcmf_set_auth_type(struct ne + break; + } + +- err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val); ++ err = brcmf_fil_bsscfg_int_set(ifp, "auth", val); + if (err) { +- brcmf_err("set auth failed (%d)\n", err); ++ bphy_err(wiphy, "set auth failed (%d)\n", err); + return err; + } + sec = &profile->sec; +@@ -1520,6 +1537,8 @@ static s32 + brcmf_set_wsec_mode(struct net_device *ndev, + struct cfg80211_connect_params *sme) + { ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_security *sec; + s32 pval = 0; +@@ -1543,8 +1562,8 @@ brcmf_set_wsec_mode(struct net_device *n + pval = AES_ENABLED; + break; + default: +- brcmf_err("invalid cipher pairwise (%d)\n", +- sme->crypto.ciphers_pairwise[0]); ++ bphy_err(wiphy, "invalid cipher pairwise (%d)\n", ++ sme->crypto.ciphers_pairwise[0]); + return -EINVAL; + } + } +@@ -1564,8 +1583,8 @@ brcmf_set_wsec_mode(struct net_device *n + gval = AES_ENABLED; + break; + default: +- brcmf_err("invalid cipher group (%d)\n", +- sme->crypto.cipher_group); ++ bphy_err(wiphy, "invalid cipher group (%d)\n", ++ sme->crypto.cipher_group); + return -EINVAL; + } + } +@@ -1578,9 +1597,9 @@ brcmf_set_wsec_mode(struct net_device *n + pval = AES_ENABLED; + + wsec = pval | gval; +- err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec); ++ err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + if (err) { +- brcmf_err("error (%d)\n", err); ++ bphy_err(wiphy, "error (%d)\n", err); + return err; + } + +@@ -1595,6 +1614,7 @@ static s32 + brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + { + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + s32 val; + s32 err; +@@ -1613,7 +1633,7 @@ brcmf_set_key_mgmt(struct net_device *nd + + err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val); + if (err) { +- brcmf_err("could not get wpa_auth (%d)\n", err); ++ bphy_err(wiphy, "could not get wpa_auth (%d)\n", err); + return err; + } + if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { +@@ -1627,8 +1647,8 @@ brcmf_set_key_mgmt(struct net_device *nd + val = WPA_AUTH_PSK; + break; + default: +- brcmf_err("invalid cipher group (%d)\n", +- sme->crypto.cipher_group); ++ bphy_err(wiphy, "invalid cipher group (%d)\n", ++ sme->crypto.cipher_group); + return -EINVAL; + } + } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { +@@ -1650,8 +1670,8 @@ brcmf_set_key_mgmt(struct net_device *nd + val = WPA2_AUTH_PSK; + break; + default: +- brcmf_err("invalid cipher group (%d)\n", +- sme->crypto.cipher_group); ++ bphy_err(wiphy, "invalid cipher group (%d)\n", ++ sme->crypto.cipher_group); + return -EINVAL; + } + } +@@ -1697,7 +1717,7 @@ skip_mfp_config: + brcmf_dbg(CONN, "setting wpa_auth to %d\n", val); + err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val); + if (err) { +- brcmf_err("could not set wpa_auth (%d)\n", err); ++ bphy_err(wiphy, "could not set wpa_auth (%d)\n", err); + return err; + } + +@@ -1708,6 +1728,8 @@ static s32 + brcmf_set_sharedkey(struct net_device *ndev, + struct cfg80211_connect_params *sme) + { ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_security *sec; + struct brcmf_wsec_key key; +@@ -1734,7 +1756,7 @@ brcmf_set_sharedkey(struct net_device *n + key.len = (u32) sme->key_len; + key.index = (u32) sme->key_idx; + if (key.len > sizeof(key.data)) { +- brcmf_err("Too long key length (%u)\n", key.len); ++ bphy_err(wiphy, "Too long key length (%u)\n", key.len); + return -EINVAL; + } + memcpy(key.data, sme->key, key.len); +@@ -1747,24 +1769,24 @@ brcmf_set_sharedkey(struct net_device *n + key.algo = CRYPTO_ALGO_WEP128; + break; + default: +- brcmf_err("Invalid algorithm (%d)\n", +- sme->crypto.ciphers_pairwise[0]); ++ bphy_err(wiphy, "Invalid algorithm (%d)\n", ++ sme->crypto.ciphers_pairwise[0]); + return -EINVAL; + } + /* Set the new key/index */ + brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n", + key.len, key.index, key.algo); + brcmf_dbg(CONN, "key \"%s\"\n", key.data); +- err = send_key_to_dongle(netdev_priv(ndev), &key); ++ err = send_key_to_dongle(ifp, &key); + if (err) + return err; + + if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) { + brcmf_dbg(CONN, "set auth_type to shared key\n"); + val = WL_AUTH_SHARED_KEY; /* shared key */ +- err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val); ++ err = brcmf_fil_bsscfg_int_set(ifp, "auth", val); + if (err) +- brcmf_err("set auth failed (%d)\n", err); ++ bphy_err(wiphy, "set auth failed (%d)\n", err); + } + return err; + } +@@ -1784,6 +1806,7 @@ enum nl80211_auth_type brcmf_war_auth_ty + static void brcmf_set_join_pref(struct brcmf_if *ifp, + struct cfg80211_bss_selection *bss_select) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_join_pref_params join_pref_params[2]; + enum nl80211_band band; + int err, i = 0; +@@ -1822,7 +1845,7 @@ static void brcmf_set_join_pref(struct b + err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params, + sizeof(join_pref_params)); + if (err) +- brcmf_err("Set join_pref error (%d)\n", err); ++ bphy_err(wiphy, "Set join_pref error (%d)\n", err); + } + + static s32 +@@ -1849,7 +1872,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + return -EIO; + + if (!sme->ssid) { +- brcmf_err("Invalid ssid\n"); ++ bphy_err(wiphy, "Invalid ssid\n"); + return -EOPNOTSUPP; + } + +@@ -1878,7 +1901,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG, + sme->ie, sme->ie_len); + if (err) +- brcmf_err("Set Assoc REQ IE Failed\n"); ++ bphy_err(wiphy, "Set Assoc REQ IE Failed\n"); + else + brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n"); + +@@ -1899,32 +1922,32 @@ brcmf_cfg80211_connect(struct wiphy *wip + + err = brcmf_set_wpa_version(ndev, sme); + if (err) { +- brcmf_err("wl_set_wpa_version failed (%d)\n", err); ++ bphy_err(wiphy, "wl_set_wpa_version failed (%d)\n", err); + goto done; + } + + sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type); + err = brcmf_set_auth_type(ndev, sme); + if (err) { +- brcmf_err("wl_set_auth_type failed (%d)\n", err); ++ bphy_err(wiphy, "wl_set_auth_type failed (%d)\n", err); + goto done; + } + + err = brcmf_set_wsec_mode(ndev, sme); + if (err) { +- brcmf_err("wl_set_set_cipher failed (%d)\n", err); ++ bphy_err(wiphy, "wl_set_set_cipher failed (%d)\n", err); + goto done; + } + + err = brcmf_set_key_mgmt(ndev, sme); + if (err) { +- brcmf_err("wl_set_key_mgmt failed (%d)\n", err); ++ bphy_err(wiphy, "wl_set_key_mgmt failed (%d)\n", err); + goto done; + } + + err = brcmf_set_sharedkey(ndev, sme); + if (err) { +- brcmf_err("brcmf_set_sharedkey failed (%d)\n", err); ++ bphy_err(wiphy, "brcmf_set_sharedkey failed (%d)\n", err); + goto done; + } + +@@ -1941,7 +1964,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + /* enable firmware supplicant for this interface */ + err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1); + if (err < 0) { +- brcmf_err("failed to enable fw supplicant\n"); ++ bphy_err(wiphy, "failed to enable fw supplicant\n"); + goto done; + } + } +@@ -2036,7 +2059,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, + &join_params, join_params_size); + if (err) +- brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err); ++ bphy_err(wiphy, "BRCMF_C_SET_SSID failed (%d)\n", err); + + done: + if (err) +@@ -2067,7 +2090,7 @@ brcmf_cfg80211_disconnect(struct wiphy * + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC, + &scbval, sizeof(scbval)); + if (err) +- brcmf_err("error (%d)\n", err); ++ bphy_err(wiphy, "error (%d)\n", err); + + brcmf_dbg(TRACE, "Exit\n"); + return err; +@@ -2094,7 +2117,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy + case NL80211_TX_POWER_LIMITED: + case NL80211_TX_POWER_FIXED: + if (mbm < 0) { +- brcmf_err("TX_POWER_FIXED - dbm is negative\n"); ++ bphy_err(wiphy, "TX_POWER_FIXED - dbm is negative\n"); + err = -EINVAL; + goto done; + } +@@ -2104,7 +2127,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy + qdbm |= WL_TXPWR_OVERRIDE; + break; + default: +- brcmf_err("Unsupported type %d\n", type); ++ bphy_err(wiphy, "Unsupported type %d\n", type); + err = -EINVAL; + goto done; + } +@@ -2112,11 +2135,11 @@ brcmf_cfg80211_set_tx_power(struct wiphy + disable = WL_RADIO_SW_DISABLE << 16; + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable); + if (err) +- brcmf_err("WLC_SET_RADIO error (%d)\n", err); ++ bphy_err(wiphy, "WLC_SET_RADIO error (%d)\n", err); + + err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm); + if (err) +- brcmf_err("qtxpower error (%d)\n", err); ++ bphy_err(wiphy, "qtxpower error (%d)\n", err); + + done: + brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE); +@@ -2137,7 +2160,7 @@ brcmf_cfg80211_get_tx_power(struct wiphy + + err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm); + if (err) { +- brcmf_err("error (%d)\n", err); ++ bphy_err(wiphy, "error (%d)\n", err); + goto done; + } + *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4; +@@ -2163,7 +2186,7 @@ brcmf_cfg80211_config_default_key(struct + + err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + if (err) { +- brcmf_err("WLC_GET_WSEC error (%d)\n", err); ++ bphy_err(wiphy, "WLC_GET_WSEC error (%d)\n", err); + goto done; + } + +@@ -2173,7 +2196,7 @@ brcmf_cfg80211_config_default_key(struct + err = brcmf_fil_cmd_int_set(ifp, + BRCMF_C_SET_KEY_PRIMARY, index); + if (err) +- brcmf_err("error (%d)\n", err); ++ bphy_err(wiphy, "error (%d)\n", err); + } + done: + brcmf_dbg(TRACE, "Exit\n"); +@@ -2237,7 +2260,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip + + if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) { + /* we ignore this key index in this case */ +- brcmf_err("invalid key index (%d)\n", key_idx); ++ bphy_err(wiphy, "invalid key index (%d)\n", key_idx); + return -EINVAL; + } + +@@ -2246,7 +2269,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip + mac_addr); + + if (params->key_len > sizeof(key->data)) { +- brcmf_err("Too long key length (%u)\n", params->key_len); ++ bphy_err(wiphy, "Too long key length (%u)\n", params->key_len); + return -EINVAL; + } + +@@ -2300,7 +2323,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip + brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n"); + break; + default: +- brcmf_err("Invalid cipher (0x%x)\n", params->cipher); ++ bphy_err(wiphy, "Invalid cipher (0x%x)\n", params->cipher); + err = -EINVAL; + goto done; + } +@@ -2311,13 +2334,13 @@ brcmf_cfg80211_add_key(struct wiphy *wip + + err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + if (err) { +- brcmf_err("get wsec error (%d)\n", err); ++ bphy_err(wiphy, "get wsec error (%d)\n", err); + goto done; + } + wsec |= val; + err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + if (err) { +- brcmf_err("set wsec error (%d)\n", err); ++ bphy_err(wiphy, "set wsec error (%d)\n", err); + goto done; + } + +@@ -2348,7 +2371,7 @@ brcmf_cfg80211_get_key(struct wiphy *wip + + err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + if (err) { +- brcmf_err("WLC_GET_WSEC error (%d)\n", err); ++ bphy_err(wiphy, "WLC_GET_WSEC error (%d)\n", err); + /* Ignore this error, may happen during DISASSOC */ + err = -EAGAIN; + goto done; +@@ -2369,7 +2392,7 @@ brcmf_cfg80211_get_key(struct wiphy *wip + params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; + brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); + } else { +- brcmf_err("Invalid algo (0x%x)\n", wsec); ++ bphy_err(wiphy, "Invalid algo (0x%x)\n", wsec); + err = -EINVAL; + goto done; + } +@@ -2399,6 +2422,7 @@ brcmf_cfg80211_config_default_mgmt_key(s + static void + brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + s32 err; + u8 key_idx; + struct brcmf_wsec_key *key; +@@ -2415,18 +2439,18 @@ brcmf_cfg80211_reconfigure_wep(struct br + + err = send_key_to_dongle(ifp, key); + if (err) { +- brcmf_err("Setting WEP key failed (%d)\n", err); ++ bphy_err(wiphy, "Setting WEP key failed (%d)\n", err); + return; + } + err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + if (err) { +- brcmf_err("get wsec error (%d)\n", err); ++ bphy_err(wiphy, "get wsec error (%d)\n", err); + return; + } + wsec |= WEP_ENABLED; + err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + if (err) +- brcmf_err("set wsec error (%d)\n", err); ++ bphy_err(wiphy, "set wsec error (%d)\n", err); + } + + static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si) +@@ -2452,6 +2476,7 @@ static void brcmf_convert_sta_flags(u32 + + static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct { + __le32 len; + struct brcmf_bss_info_le bss_le; +@@ -2467,7 +2492,7 @@ static void brcmf_fill_bss_param(struct + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf, + WL_BSS_INFO_MAX); + if (err) { +- brcmf_err("Failed to get bss info (%d)\n", err); ++ bphy_err(wiphy, "Failed to get bss info (%d)\n", err); + goto out_kfree; + } + si->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM); +@@ -2489,6 +2514,7 @@ static s32 + brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp, + struct station_info *sinfo) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_scb_val_le scbval; + struct brcmf_pktcnt_le pktcnt; + s32 err; +@@ -2498,7 +2524,7 @@ brcmf_cfg80211_get_station_ibss(struct b + /* Get the current tx rate */ + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); + if (err < 0) { +- brcmf_err("BRCMF_C_GET_RATE error (%d)\n", err); ++ bphy_err(wiphy, "BRCMF_C_GET_RATE error (%d)\n", err); + return err; + } + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); +@@ -2508,7 +2534,7 @@ brcmf_cfg80211_get_station_ibss(struct b + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval, + sizeof(scbval)); + if (err) { +- brcmf_err("BRCMF_C_GET_RSSI error (%d)\n", err); ++ bphy_err(wiphy, "BRCMF_C_GET_RSSI error (%d)\n", err); + return err; + } + rssi = le32_to_cpu(scbval.val); +@@ -2518,7 +2544,7 @@ brcmf_cfg80211_get_station_ibss(struct b + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt, + sizeof(pktcnt)); + if (err) { +- brcmf_err("BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err); ++ bphy_err(wiphy, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err); + return err; + } + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS) | +@@ -2566,7 +2592,7 @@ brcmf_cfg80211_get_station(struct wiphy + &sta_info_le, + sizeof(sta_info_le)); + if (err < 0) { +- brcmf_err("GET STA INFO failed, %d\n", err); ++ bphy_err(wiphy, "GET STA INFO failed, %d\n", err); + goto done; + } + } +@@ -2635,7 +2661,8 @@ brcmf_cfg80211_get_station(struct wiphy + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, + &scb_val, sizeof(scb_val)); + if (err) { +- brcmf_err("Could not get rssi (%d)\n", err); ++ bphy_err(wiphy, "Could not get rssi (%d)\n", ++ err); + goto done; + } else { + rssi = le32_to_cpu(scb_val.val); +@@ -2666,8 +2693,8 @@ brcmf_cfg80211_dump_station(struct wiphy + &cfg->assoclist, + sizeof(cfg->assoclist)); + if (err) { +- brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n", +- err); ++ bphy_err(wiphy, "BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n", ++ err); + cfg->assoclist.count = 0; + return -EOPNOTSUPP; + } +@@ -2715,9 +2742,9 @@ brcmf_cfg80211_set_power_mgmt(struct wip + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm); + if (err) { + if (err == -ENODEV) +- brcmf_err("net_device is not ready yet\n"); ++ bphy_err(wiphy, "net_device is not ready yet\n"); + else +- brcmf_err("error (%d)\n", err); ++ bphy_err(wiphy, "error (%d)\n", err); + } + done: + brcmf_dbg(TRACE, "Exit\n"); +@@ -2740,7 +2767,7 @@ static s32 brcmf_inform_single_bss(struc + struct cfg80211_inform_bss bss_data = {}; + + if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) { +- brcmf_err("Bss info is larger than buffer. Discarding\n"); ++ bphy_err(wiphy, "Bss info is larger than buffer. Discarding\n"); + return 0; + } + +@@ -2799,6 +2826,7 @@ next_bss_le(struct brcmf_scan_results *l + + static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg) + { ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + struct brcmf_scan_results *bss_list; + struct brcmf_bss_info_le *bi = NULL; /* must be initialized */ + s32 err = 0; +@@ -2807,8 +2835,8 @@ static s32 brcmf_inform_bss(struct brcmf + bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; + if (bss_list->count != 0 && + bss_list->version != BRCMF_BSS_INFO_VERSION) { +- brcmf_err("Version %d != WL_BSS_INFO_VERSION\n", +- bss_list->version); ++ bphy_err(wiphy, "Version %d != WL_BSS_INFO_VERSION\n", ++ bss_list->version); + return -EOPNOTSUPP; + } + brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count); +@@ -2852,7 +2880,7 @@ static s32 brcmf_inform_ibss(struct brcm + err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO, + buf, WL_BSS_INFO_MAX); + if (err) { +- brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err); ++ bphy_err(wiphy, "WLC_GET_BSS_INFO failed: %d\n", err); + goto CleanUp; + } + +@@ -2906,6 +2934,7 @@ CleanUp: + static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg, + struct brcmf_if *ifp) + { ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + struct brcmf_bss_info_le *bi; + const struct brcmf_tlv *tim; + u16 beacon_interval; +@@ -2922,7 +2951,7 @@ static s32 brcmf_update_bss_info(struct + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, + cfg->extra_buf, WL_EXTRA_BUF_MAX); + if (err) { +- brcmf_err("Could not get bss info %d\n", err); ++ bphy_err(wiphy, "Could not get bss info %d\n", err); + goto update_bss_info_out; + } + +@@ -2947,7 +2976,7 @@ static s32 brcmf_update_bss_info(struct + u32 var; + err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var); + if (err) { +- brcmf_err("wl dtim_assoc failed (%d)\n", err); ++ bphy_err(wiphy, "wl dtim_assoc failed (%d)\n", err); + goto update_bss_info_out; + } + dtim_period = (u8)var; +@@ -2985,9 +3014,10 @@ static void brcmf_escan_timeout(struct t + { + struct brcmf_cfg80211_info *cfg = + from_timer(cfg, t, escan_timeout); ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + + if (cfg->int_escan_map || cfg->scan_request) { +- brcmf_err("timer expired\n"); ++ bphy_err(wiphy, "timer expired\n"); + schedule_work(&cfg->escan_timeout_work); + } + } +@@ -3036,6 +3066,7 @@ brcmf_cfg80211_escan_handler(struct brcm + const struct brcmf_event_msg *e, void *data) + { + struct brcmf_cfg80211_info *cfg = ifp->drvr->config; ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + s32 status; + struct brcmf_escan_result_le *escan_result_le; + u32 escan_buflen; +@@ -3052,32 +3083,33 @@ brcmf_cfg80211_escan_handler(struct brcm + goto exit; + + if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { +- brcmf_err("scan not ready, bsscfgidx=%d\n", ifp->bsscfgidx); ++ bphy_err(wiphy, "scan not ready, bsscfgidx=%d\n", ++ ifp->bsscfgidx); + return -EPERM; + } + + if (status == BRCMF_E_STATUS_PARTIAL) { + brcmf_dbg(SCAN, "ESCAN Partial result\n"); + if (e->datalen < sizeof(*escan_result_le)) { +- brcmf_err("invalid event data length\n"); ++ bphy_err(wiphy, "invalid event data length\n"); + goto exit; + } + escan_result_le = (struct brcmf_escan_result_le *) data; + if (!escan_result_le) { +- brcmf_err("Invalid escan result (NULL pointer)\n"); ++ bphy_err(wiphy, "Invalid escan result (NULL pointer)\n"); + goto exit; + } + escan_buflen = le32_to_cpu(escan_result_le->buflen); + if (escan_buflen > BRCMF_ESCAN_BUF_SIZE || + escan_buflen > e->datalen || + escan_buflen < sizeof(*escan_result_le)) { +- brcmf_err("Invalid escan buffer length: %d\n", +- escan_buflen); ++ bphy_err(wiphy, "Invalid escan buffer length: %d\n", ++ escan_buflen); + goto exit; + } + if (le16_to_cpu(escan_result_le->bss_count) != 1) { +- brcmf_err("Invalid bss_count %d: ignoring\n", +- escan_result_le->bss_count); ++ bphy_err(wiphy, "Invalid bss_count %d: ignoring\n", ++ escan_result_le->bss_count); + goto exit; + } + bss_info_le = &escan_result_le->bss_info_le; +@@ -3092,8 +3124,8 @@ brcmf_cfg80211_escan_handler(struct brcm + + bi_length = le32_to_cpu(bss_info_le->length); + if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { +- brcmf_err("Ignoring invalid bss_info length: %d\n", +- bi_length); ++ bphy_err(wiphy, "Ignoring invalid bss_info length: %d\n", ++ bi_length); + goto exit; + } + +@@ -3101,7 +3133,7 @@ brcmf_cfg80211_escan_handler(struct brcm + BIT(NL80211_IFTYPE_ADHOC))) { + if (le16_to_cpu(bss_info_le->capability) & + WLAN_CAPABILITY_IBSS) { +- brcmf_err("Ignoring IBSS result\n"); ++ bphy_err(wiphy, "Ignoring IBSS result\n"); + goto exit; + } + } +@@ -3109,7 +3141,7 @@ brcmf_cfg80211_escan_handler(struct brcm + list = (struct brcmf_scan_results *) + cfg->escan_info.escan_buf; + if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) { +- brcmf_err("Buffer is too small: ignoring\n"); ++ bphy_err(wiphy, "Buffer is too small: ignoring\n"); + goto exit; + } + +@@ -3301,14 +3333,14 @@ brcmf_notify_sched_scan_results(struct b + WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE); + brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count); + if (!result_count) { +- brcmf_err("FALSE PNO Event. (pfn_count == 0)\n"); ++ bphy_err(wiphy, "FALSE PNO Event. (pfn_count == 0)\n"); + goto out_err; + } + + netinfo_start = brcmf_get_netinfo_array(pfn_result); + datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result); + if (datalen < result_count * sizeof(*netinfo)) { +- brcmf_err("insufficient event data\n"); ++ bphy_err(wiphy, "insufficient event data\n"); + goto out_err; + } + +@@ -3362,8 +3394,8 @@ brcmf_cfg80211_sched_scan_start(struct w + req->n_match_sets, req->n_ssids); + + if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { +- brcmf_err("Scanning suppressed: status=%lu\n", +- cfg->scan_status); ++ bphy_err(wiphy, "Scanning suppressed: status=%lu\n", ++ cfg->scan_status); + return -EAGAIN; + } + +@@ -3442,6 +3474,7 @@ brcmf_wowl_nd_results(struct brcmf_if *i + void *data) + { + struct brcmf_cfg80211_info *cfg = ifp->drvr->config; ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + struct brcmf_pno_scanresults_le *pfn_result; + struct brcmf_pno_net_info_le *netinfo; + +@@ -3460,8 +3493,8 @@ brcmf_wowl_nd_results(struct brcmf_if *i + } + + if (le32_to_cpu(pfn_result->count) < 1) { +- brcmf_err("Invalid result count, expected 1 (%d)\n", +- le32_to_cpu(pfn_result->count)); ++ bphy_err(wiphy, "Invalid result count, expected 1 (%d)\n", ++ le32_to_cpu(pfn_result->count)); + return -EINVAL; + } + +@@ -3498,7 +3531,7 @@ static void brcmf_report_wowl_wakeind(st + err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le, + sizeof(wake_ind_le)); + if (err) { +- brcmf_err("Get wowl_wakeind failed, err = %d\n", err); ++ bphy_err(wiphy, "Get wowl_wakeind failed, err = %d\n", err); + return; + } + +@@ -3539,7 +3572,7 @@ static void brcmf_report_wowl_wakeind(st + cfg->wowl.nd_data_completed, + BRCMF_ND_INFO_TIMEOUT); + if (!timeout) +- brcmf_err("No result for wowl net detect\n"); ++ bphy_err(wiphy, "No result for wowl net detect\n"); + else + wakeup_data.net_detect = cfg->wowl.nd_info; + } +@@ -3747,7 +3780,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *w + cfg->pmk_list.npmk = cpu_to_le32(npmk); + } + } else { +- brcmf_err("Too many PMKSA entries cached %d\n", npmk); ++ bphy_err(wiphy, "Too many PMKSA entries cached %d\n", npmk); + return -EINVAL; + } + +@@ -3793,7 +3826,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *w + memset(&pmk[i], 0, sizeof(*pmk)); + cfg->pmk_list.npmk = cpu_to_le32(npmk - 1); + } else { +- brcmf_err("Cache entry not found\n"); ++ bphy_err(wiphy, "Cache entry not found\n"); + return -EINVAL; + } + +@@ -3825,19 +3858,20 @@ brcmf_cfg80211_flush_pmksa(struct wiphy + + static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + s32 err; + s32 wpa_val; + + /* set auth */ + err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0); + if (err < 0) { +- brcmf_err("auth error %d\n", err); ++ bphy_err(wiphy, "auth error %d\n", err); + return err; + } + /* set wsec */ + err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0); + if (err < 0) { +- brcmf_err("wsec error %d\n", err); ++ bphy_err(wiphy, "wsec error %d\n", err); + return err; + } + /* set upper-layer auth */ +@@ -3847,7 +3881,7 @@ static s32 brcmf_configure_opensecurity( + wpa_val = WPA_AUTH_DISABLED; + err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_val); + if (err < 0) { +- brcmf_err("wpa_auth error %d\n", err); ++ bphy_err(wiphy, "wpa_auth error %d\n", err); + return err; + } + +@@ -3867,6 +3901,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + const struct brcmf_vs_tlv *wpa_ie, + bool is_rsn_ie) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + u32 auth = 0; /* d11 open authentication */ + u16 count; + s32 err = 0; +@@ -3897,13 +3932,13 @@ brcmf_configure_wpaie(struct brcmf_if *i + /* check for multicast cipher suite */ + if (offset + WPA_IE_MIN_OUI_LEN > len) { + err = -EINVAL; +- brcmf_err("no multicast cipher suite\n"); ++ bphy_err(wiphy, "no multicast cipher suite\n"); + goto exit; + } + + if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { + err = -EINVAL; +- brcmf_err("ivalid OUI\n"); ++ bphy_err(wiphy, "ivalid OUI\n"); + goto exit; + } + offset += TLV_OUI_LEN; +@@ -3925,7 +3960,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + break; + default: + err = -EINVAL; +- brcmf_err("Invalid multi cast cipher info\n"); ++ bphy_err(wiphy, "Invalid multi cast cipher info\n"); + goto exit; + } + +@@ -3936,13 +3971,13 @@ brcmf_configure_wpaie(struct brcmf_if *i + /* Check for unicast suite(s) */ + if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) { + err = -EINVAL; +- brcmf_err("no unicast cipher suite\n"); ++ bphy_err(wiphy, "no unicast cipher suite\n"); + goto exit; + } + for (i = 0; i < count; i++) { + if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { + err = -EINVAL; +- brcmf_err("ivalid OUI\n"); ++ bphy_err(wiphy, "ivalid OUI\n"); + goto exit; + } + offset += TLV_OUI_LEN; +@@ -3960,7 +3995,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + pval |= AES_ENABLED; + break; + default: +- brcmf_err("Invalid unicast security info\n"); ++ bphy_err(wiphy, "Invalid unicast security info\n"); + } + offset++; + } +@@ -3970,13 +4005,13 @@ brcmf_configure_wpaie(struct brcmf_if *i + /* Check for auth key management suite(s) */ + if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) { + err = -EINVAL; +- brcmf_err("no auth key mgmt suite\n"); ++ bphy_err(wiphy, "no auth key mgmt suite\n"); + goto exit; + } + for (i = 0; i < count; i++) { + if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { + err = -EINVAL; +- brcmf_err("ivalid OUI\n"); ++ bphy_err(wiphy, "ivalid OUI\n"); + goto exit; + } + offset += TLV_OUI_LEN; +@@ -4004,7 +4039,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + wpa_auth |= WPA2_AUTH_1X_SHA256; + break; + default: +- brcmf_err("Invalid key mgmt info\n"); ++ bphy_err(wiphy, "Invalid key mgmt info\n"); + } + offset++; + } +@@ -4046,7 +4081,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable", + wme_bss_disable); + if (err < 0) { +- brcmf_err("wme_bss_disable error %d\n", err); ++ bphy_err(wiphy, "wme_bss_disable error %d\n", err); + goto exit; + } + +@@ -4060,7 +4095,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + &data[offset], + WPA_IE_MIN_OUI_LEN); + if (err < 0) { +- brcmf_err("bip error %d\n", err); ++ bphy_err(wiphy, "bip error %d\n", err); + goto exit; + } + } +@@ -4071,13 +4106,13 @@ brcmf_configure_wpaie(struct brcmf_if *i + /* set auth */ + err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth); + if (err < 0) { +- brcmf_err("auth error %d\n", err); ++ bphy_err(wiphy, "auth error %d\n", err); + goto exit; + } + /* set wsec */ + err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + if (err < 0) { +- brcmf_err("wsec error %d\n", err); ++ bphy_err(wiphy, "wsec error %d\n", err); + goto exit; + } + /* Configure MFP, this needs to go after wsec otherwise the wsec command +@@ -4086,14 +4121,14 @@ brcmf_configure_wpaie(struct brcmf_if *i + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) { + err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp); + if (err < 0) { +- brcmf_err("mfp error %d\n", err); ++ bphy_err(wiphy, "mfp error %d\n", err); + goto exit; + } + } + /* set upper-layer auth */ + err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth); + if (err < 0) { +- brcmf_err("wpa_auth error %d\n", err); ++ bphy_err(wiphy, "wpa_auth error %d\n", err); + goto exit; + } + +@@ -4180,6 +4215,7 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + const u8 *vndr_ie_buf, u32 vndr_ie_len) + { + struct brcmf_if *ifp; ++ struct wiphy *wiphy; + struct vif_saved_ie *saved_ie; + s32 err = 0; + u8 *iovar_ie_buf; +@@ -4200,6 +4236,7 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + if (!vif) + return -ENODEV; + ifp = vif->ifp; ++ wiphy = ifp->drvr->wiphy; + saved_ie = &vif->saved_ie; + + brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx, +@@ -4231,13 +4268,13 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + break; + default: + err = -EPERM; +- brcmf_err("not suitable type\n"); ++ bphy_err(wiphy, "not suitable type\n"); + goto exit; + } + + if (vndr_ie_len > mgmt_ie_buf_len) { + err = -ENOMEM; +- brcmf_err("extra IE size too big\n"); ++ bphy_err(wiphy, "extra IE size too big\n"); + goto exit; + } + +@@ -4298,8 +4335,8 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + /* verify remained buf size before copy data */ + if (remained_buf_len < (vndrie_info->vndrie.len + + VNDR_IE_VSIE_OFFSET)) { +- brcmf_err("no space in mgmt_ie_buf: len left %d", +- remained_buf_len); ++ bphy_err(wiphy, "no space in mgmt_ie_buf: len left %d", ++ remained_buf_len); + break; + } + remained_buf_len -= (vndrie_info->ie_len + +@@ -4330,7 +4367,7 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf, + total_ie_buf_len); + if (err) +- brcmf_err("vndr ie set error : %d\n", err); ++ bphy_err(wiphy, "vndr ie set error : %d\n", err); + } + + exit: +@@ -4358,13 +4395,14 @@ static s32 + brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif, + struct cfg80211_beacon_data *beacon) + { ++ struct wiphy *wiphy = vif->ifp->drvr->wiphy; + s32 err; + + /* Set Beacon IEs to FW */ + err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG, + beacon->tail, beacon->tail_len); + if (err) { +- brcmf_err("Set Beacon IE Failed\n"); ++ bphy_err(wiphy, "Set Beacon IE Failed\n"); + return err; + } + brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n"); +@@ -4374,7 +4412,7 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg + beacon->proberesp_ies, + beacon->proberesp_ies_len); + if (err) +- brcmf_err("Set Probe Resp IE Failed\n"); ++ bphy_err(wiphy, "Set Probe Resp IE Failed\n"); + else + brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n"); + +@@ -4483,7 +4521,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, + is_11d); + if (err < 0) { +- brcmf_err("Regulatory Set Error, %d\n", err); ++ bphy_err(wiphy, "Regulatory Set Error, %d\n", ++ err); + goto exit; + } + } +@@ -4491,8 +4530,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, + settings->beacon_interval); + if (err < 0) { +- brcmf_err("Beacon Interval Set Error, %d\n", +- err); ++ bphy_err(wiphy, "Beacon Interval Set Error, %d\n", ++ err); + goto exit; + } + } +@@ -4500,7 +4539,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD, + settings->dtim_period); + if (err < 0) { +- brcmf_err("DTIM Interval Set Error, %d\n", err); ++ bphy_err(wiphy, "DTIM Interval Set Error, %d\n", ++ err); + goto exit; + } + } +@@ -4510,7 +4550,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) { + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); + if (err < 0) { +- brcmf_err("BRCMF_C_DOWN error %d\n", err); ++ bphy_err(wiphy, "BRCMF_C_DOWN error %d\n", ++ err); + goto exit; + } + brcmf_fil_iovar_int_set(ifp, "apsta", 0); +@@ -4518,7 +4559,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1); + if (err < 0) { +- brcmf_err("SET INFRA error %d\n", err); ++ bphy_err(wiphy, "SET INFRA error %d\n", err); + goto exit; + } + } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) { +@@ -4534,7 +4575,8 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1); + if (err < 0) { +- brcmf_err("setting AP mode failed %d\n", err); ++ bphy_err(wiphy, "setting AP mode failed %d\n", ++ err); + goto exit; + } + if (!mbss) { +@@ -4543,14 +4585,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + */ + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); + if (err < 0) { +- brcmf_err("Set Channel failed: chspec=%d, %d\n", +- chanspec, err); ++ bphy_err(wiphy, "Set Channel failed: chspec=%d, %d\n", ++ chanspec, err); + goto exit; + } + } + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); + if (err < 0) { +- brcmf_err("BRCMF_C_UP error (%d)\n", err); ++ bphy_err(wiphy, "BRCMF_C_UP error (%d)\n", err); + goto exit; + } + /* On DOWN the firmware removes the WEP keys, reconfigure +@@ -4565,14 +4607,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, + &join_params, sizeof(join_params)); + if (err < 0) { +- brcmf_err("SET SSID error (%d)\n", err); ++ bphy_err(wiphy, "SET SSID error (%d)\n", err); + goto exit; + } + + if (settings->hidden_ssid) { + err = brcmf_fil_iovar_int_set(ifp, "closednet", 1); + if (err) { +- brcmf_err("closednet error (%d)\n", err); ++ bphy_err(wiphy, "closednet error (%d)\n", err); + goto exit; + } + } +@@ -4581,14 +4623,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + } else if (dev_role == NL80211_IFTYPE_P2P_GO) { + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); + if (err < 0) { +- brcmf_err("Set Channel failed: chspec=%d, %d\n", +- chanspec, err); ++ bphy_err(wiphy, "Set Channel failed: chspec=%d, %d\n", ++ chanspec, err); + goto exit; + } + err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le, + sizeof(ssid_le)); + if (err < 0) { +- brcmf_err("setting ssid failed %d\n", err); ++ bphy_err(wiphy, "setting ssid failed %d\n", err); + goto exit; + } + bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx); +@@ -4596,7 +4638,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable, + sizeof(bss_enable)); + if (err < 0) { +- brcmf_err("bss_enable config failed %d\n", err); ++ bphy_err(wiphy, "bss_enable config failed %d\n", err); + goto exit; + } + +@@ -4644,13 +4686,13 @@ static int brcmf_cfg80211_stop_ap(struct + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, + &join_params, sizeof(join_params)); + if (err < 0) +- brcmf_err("SET SSID error (%d)\n", err); ++ bphy_err(wiphy, "SET SSID error (%d)\n", err); + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); + if (err < 0) +- brcmf_err("BRCMF_C_DOWN error %d\n", err); ++ bphy_err(wiphy, "BRCMF_C_DOWN error %d\n", err); + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0); + if (err < 0) +- brcmf_err("setting AP mode failed %d\n", err); ++ bphy_err(wiphy, "setting AP mode failed %d\n", err); + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) + brcmf_fil_iovar_int_set(ifp, "mbss", 0); + brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, +@@ -4658,7 +4700,7 @@ static int brcmf_cfg80211_stop_ap(struct + /* Bring device back up so it can be used again */ + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); + if (err < 0) +- brcmf_err("BRCMF_C_UP error %d\n", err); ++ bphy_err(wiphy, "BRCMF_C_UP error %d\n", err); + + brcmf_vif_clear_mgmt_ies(ifp->vif); + } else { +@@ -4667,7 +4709,7 @@ static int brcmf_cfg80211_stop_ap(struct + err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable, + sizeof(bss_enable)); + if (err < 0) +- brcmf_err("bss_enable config failed %d\n", err); ++ bphy_err(wiphy, "bss_enable config failed %d\n", err); + } + brcmf_set_mpc(ifp, 1); + brcmf_configure_arp_nd_offload(ifp, true); +@@ -4715,7 +4757,8 @@ brcmf_cfg80211_del_station(struct wiphy + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, + &scbval, sizeof(scbval)); + if (err) +- brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err); ++ bphy_err(wiphy, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", ++ err); + + brcmf_dbg(TRACE, "Exit\n"); + return err; +@@ -4745,7 +4788,7 @@ brcmf_cfg80211_change_station(struct wip + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE, + (void *)mac, ETH_ALEN); + if (err < 0) +- brcmf_err("Setting SCB (de-)authorize failed, %d\n", err); ++ bphy_err(wiphy, "Setting SCB (de-)authorize failed, %d\n", err); + + return err; + } +@@ -4795,7 +4838,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip + mgmt = (const struct ieee80211_mgmt *)buf; + + if (!ieee80211_is_mgmt(mgmt->frame_control)) { +- brcmf_err("Driver only allows MGMT packet type\n"); ++ bphy_err(wiphy, "Driver only allows MGMT packet type\n"); + return -EPERM; + } + +@@ -4826,13 +4869,13 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip + GFP_KERNEL); + } else if (ieee80211_is_action(mgmt->frame_control)) { + if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) { +- brcmf_err("invalid action frame length\n"); ++ bphy_err(wiphy, "invalid action frame length\n"); + err = -EINVAL; + goto exit; + } + af_params = kzalloc(sizeof(*af_params), GFP_KERNEL); + if (af_params == NULL) { +- brcmf_err("unable to allocate frame\n"); ++ bphy_err(wiphy, "unable to allocate frame\n"); + err = -ENOMEM; + goto exit; + } +@@ -4890,7 +4933,7 @@ brcmf_cfg80211_cancel_remain_on_channel( + + vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif; + if (vif == NULL) { +- brcmf_err("No p2p device available for probe response\n"); ++ bphy_err(wiphy, "No p2p device available for probe response\n"); + err = -ENODEV; + goto exit; + } +@@ -4918,7 +4961,7 @@ static int brcmf_cfg80211_get_channel(st + + err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec); + if (err) { +- brcmf_err("chanspec failed (%d)\n", err); ++ bphy_err(wiphy, "chanspec failed (%d)\n", err); + return err; + } + +@@ -5057,7 +5100,7 @@ static int brcmf_cfg80211_tdls_oper(stru + ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint", + &info, sizeof(info)); + if (ret < 0) +- brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret); ++ bphy_err(wiphy, "tdls_endpoint iovar failed: ret=%d\n", ret); + + return ret; + } +@@ -5078,7 +5121,7 @@ brcmf_cfg80211_update_conn_params(struct + err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG, + sme->ie, sme->ie_len); + if (err) +- brcmf_err("Set Assoc REQ IE Failed\n"); ++ bphy_err(wiphy, "Set Assoc REQ IE Failed\n"); + else + brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n"); + +@@ -5104,7 +5147,7 @@ brcmf_cfg80211_set_rekey_data(struct wip + ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", >k_le, + sizeof(gtk_le)); + if (ret < 0) +- brcmf_err("gtk_key_info iovar failed: ret=%d\n", ret); ++ bphy_err(wiphy, "gtk_key_info iovar failed: ret=%d\n", ret); + + return ret; + } +@@ -5336,6 +5379,7 @@ static void brcmf_clear_assoc_ies(struct + static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg, + struct brcmf_if *ifp) + { ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + struct brcmf_cfg80211_assoc_ielen_le *assoc_info; + struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); + u32 req_len; +@@ -5347,7 +5391,7 @@ static s32 brcmf_get_assoc_ies(struct br + err = brcmf_fil_iovar_data_get(ifp, "assoc_info", + cfg->extra_buf, WL_ASSOC_INFO_MAX); + if (err) { +- brcmf_err("could not get assoc info (%d)\n", err); ++ bphy_err(wiphy, "could not get assoc info (%d)\n", err); + return err; + } + assoc_info = +@@ -5359,7 +5403,7 @@ static s32 brcmf_get_assoc_ies(struct br + cfg->extra_buf, + WL_ASSOC_INFO_MAX); + if (err) { +- brcmf_err("could not get assoc req (%d)\n", err); ++ bphy_err(wiphy, "could not get assoc req (%d)\n", err); + return err; + } + conn_info->req_ie_len = req_len; +@@ -5375,7 +5419,7 @@ static s32 brcmf_get_assoc_ies(struct br + cfg->extra_buf, + WL_ASSOC_INFO_MAX); + if (err) { +- brcmf_err("could not get assoc resp (%d)\n", err); ++ bphy_err(wiphy, "could not get assoc resp (%d)\n", err); + return err; + } + conn_info->resp_ie_len = resp_len; +@@ -5502,6 +5546,7 @@ brcmf_notify_connect_status_ap(struct br + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) + { ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + static int generation; + u32 event = e->event_code; + u32 reason = e->reason; +@@ -5519,7 +5564,7 @@ brcmf_notify_connect_status_ap(struct br + if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) && + (reason == BRCMF_E_STATUS_SUCCESS)) { + if (!data) { +- brcmf_err("No IEs present in ASSOC/REASSOC_IND"); ++ bphy_err(wiphy, "No IEs present in ASSOC/REASSOC_IND\n"); + return -EINVAL; + } + +@@ -5811,6 +5856,7 @@ static void init_vif_event(struct brcmf_ + + static s32 brcmf_dongle_roam(struct brcmf_if *ifp) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + s32 err; + u32 bcn_timeout; + __le32 roamtrigger[2]; +@@ -5823,7 +5869,7 @@ static s32 brcmf_dongle_roam(struct brcm + bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON; + err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout); + if (err) { +- brcmf_err("bcn_timeout error (%d)\n", err); ++ bphy_err(wiphy, "bcn_timeout error (%d)\n", err); + goto roam_setup_done; + } + +@@ -5835,7 +5881,7 @@ static s32 brcmf_dongle_roam(struct brcm + err = brcmf_fil_iovar_int_set(ifp, "roam_off", + ifp->drvr->settings->roamoff); + if (err) { +- brcmf_err("roam_off error (%d)\n", err); ++ bphy_err(wiphy, "roam_off error (%d)\n", err); + goto roam_setup_done; + } + +@@ -5844,7 +5890,7 @@ static s32 brcmf_dongle_roam(struct brcm + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER, + (void *)roamtrigger, sizeof(roamtrigger)); + if (err) { +- brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err); ++ bphy_err(wiphy, "WLC_SET_ROAM_TRIGGER error (%d)\n", err); + goto roam_setup_done; + } + +@@ -5853,7 +5899,7 @@ static s32 brcmf_dongle_roam(struct brcm + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA, + (void *)roam_delta, sizeof(roam_delta)); + if (err) { +- brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err); ++ bphy_err(wiphy, "WLC_SET_ROAM_DELTA error (%d)\n", err); + goto roam_setup_done; + } + +@@ -5864,25 +5910,26 @@ roam_setup_done: + static s32 + brcmf_dongle_scantime(struct brcmf_if *ifp) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + s32 err = 0; + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, + BRCMF_SCAN_CHANNEL_TIME); + if (err) { +- brcmf_err("Scan assoc time error (%d)\n", err); ++ bphy_err(wiphy, "Scan assoc time error (%d)\n", err); + goto dongle_scantime_out; + } + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME, + BRCMF_SCAN_UNASSOC_TIME); + if (err) { +- brcmf_err("Scan unassoc time error (%d)\n", err); ++ bphy_err(wiphy, "Scan unassoc time error (%d)\n", err); + goto dongle_scantime_out; + } + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME, + BRCMF_SCAN_PASSIVE_TIME); + if (err) { +- brcmf_err("Scan passive time error (%d)\n", err); ++ bphy_err(wiphy, "Scan passive time error (%d)\n", err); + goto dongle_scantime_out; + } + +@@ -5914,10 +5961,10 @@ static void brcmf_update_bw40_channel_fl + static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg, + u32 bw_cap[]) + { ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); + struct ieee80211_supported_band *band; + struct ieee80211_channel *channel; +- struct wiphy *wiphy; + struct brcmf_chanspec_list *list; + struct brcmu_chan ch; + int err; +@@ -5936,11 +5983,10 @@ static int brcmf_construct_chaninfo(stru + err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf, + BRCMF_DCMD_MEDLEN); + if (err) { +- brcmf_err("get chanspecs error (%d)\n", err); ++ bphy_err(wiphy, "get chanspecs error (%d)\n", err); + goto fail_pbuf; + } + +- wiphy = cfg_to_wiphy(cfg); + band = wiphy->bands[NL80211_BAND_2GHZ]; + if (band) + for (i = 0; i < band->n_channels; i++) +@@ -5960,7 +6006,8 @@ static int brcmf_construct_chaninfo(stru + } else if (ch.band == BRCMU_CHAN_BAND_5G) { + band = wiphy->bands[NL80211_BAND_5GHZ]; + } else { +- brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec); ++ bphy_err(wiphy, "Invalid channel Spec. 0x%x.\n", ++ ch.chspec); + continue; + } + if (!band) +@@ -5983,8 +6030,8 @@ static int brcmf_construct_chaninfo(stru + /* It seems firmware supports some channel we never + * considered. Something new in IEEE standard? + */ +- brcmf_err("Ignoring unexpected firmware channel %d\n", +- ch.control_ch_num); ++ bphy_err(wiphy, "Ignoring unexpected firmware channel %d\n", ++ ch.control_ch_num); + continue; + } + +@@ -6030,6 +6077,7 @@ fail_pbuf: + + static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) + { ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); + struct ieee80211_supported_band *band; + struct brcmf_fil_bwcap_le band_bwcap; +@@ -6076,7 +6124,7 @@ static int brcmf_enable_bw40_2g(struct b + err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf, + BRCMF_DCMD_MEDLEN); + if (err) { +- brcmf_err("get chanspecs error (%d)\n", err); ++ bphy_err(wiphy, "get chanspecs error (%d)\n", err); + kfree(pbuf); + return err; + } +@@ -6107,6 +6155,7 @@ static int brcmf_enable_bw40_2g(struct b + + static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) + { ++ struct wiphy *wiphy = ifp->drvr->wiphy; + u32 band, mimo_bwcap; + int err; + +@@ -6142,7 +6191,7 @@ static void brcmf_get_bwcap(struct brcmf + bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT; + break; + default: +- brcmf_err("invalid mimo_bw_cap value\n"); ++ bphy_err(wiphy, "invalid mimo_bw_cap value\n"); + } + } + +@@ -6218,7 +6267,7 @@ static void brcmf_update_vht_cap(struct + static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + { + struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); +- struct wiphy *wiphy; ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + u32 nmode = 0; + u32 vhtmode = 0; + u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT }; +@@ -6234,7 +6283,7 @@ static int brcmf_setup_wiphybands(struct + (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode); + err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode); + if (err) { +- brcmf_err("nmode error (%d)\n", err); ++ bphy_err(wiphy, "nmode error (%d)\n", err); + } else { + brcmf_get_bwcap(ifp, bw_cap); + } +@@ -6244,7 +6293,7 @@ static int brcmf_setup_wiphybands(struct + + err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain); + if (err) { +- brcmf_err("rxchain error (%d)\n", err); ++ bphy_err(wiphy, "rxchain error (%d)\n", err); + nchain = 1; + } else { + for (nchain = 0; rxchain; nchain++) +@@ -6254,7 +6303,7 @@ static int brcmf_setup_wiphybands(struct + + err = brcmf_construct_chaninfo(cfg, bw_cap); + if (err) { +- brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err); ++ bphy_err(wiphy, "brcmf_construct_chaninfo failed (%d)\n", err); + return err; + } + +@@ -6266,7 +6315,6 @@ static int brcmf_setup_wiphybands(struct + &txbf_bfr_cap); + } + +- wiphy = cfg_to_wiphy(cfg); + for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) { + band = wiphy->bands[i]; + if (band == NULL) +@@ -6467,7 +6515,7 @@ static void brcmf_wiphy_wowl_params(stru + wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support), + GFP_KERNEL); + if (!wowl) { +- brcmf_err("only support basic wowlan features\n"); ++ bphy_err(wiphy, "only support basic wowlan features\n"); + wiphy->wowlan = &brcmf_wowlan_support; + return; + } +@@ -6564,7 +6612,7 @@ static int brcmf_setup_wiphy(struct wiph + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist, + sizeof(bandlist)); + if (err) { +- brcmf_err("could not obtain band info: err=%d\n", err); ++ bphy_err(wiphy, "could not obtain band info: err=%d\n", err); + return err; + } + /* first entry in bandlist is number of bands */ +@@ -6613,6 +6661,7 @@ static int brcmf_setup_wiphy(struct wiph + + static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) + { ++ struct wiphy *wiphy = cfg_to_wiphy(cfg); + struct net_device *ndev; + struct wireless_dev *wdev; + struct brcmf_if *ifp; +@@ -6650,7 +6699,7 @@ static s32 brcmf_config_dongle(struct br + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1); + if (err) { +- brcmf_err("failed to set frameburst mode\n"); ++ bphy_err(wiphy, "failed to set frameburst mode\n"); + goto default_conf_out; + } + +@@ -6842,8 +6891,8 @@ static void brcmf_cfg80211_reg_notifier( + /* ignore non-ISO3166 country codes */ + for (i = 0; i < 2; i++) + if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { +- brcmf_err("not an ISO3166 code (0x%02x 0x%02x)\n", +- req->alpha2[0], req->alpha2[1]); ++ bphy_err(wiphy, "not an ISO3166 code (0x%02x 0x%02x)\n", ++ req->alpha2[0], req->alpha2[1]); + return; + } + +@@ -6852,7 +6901,7 @@ static void brcmf_cfg80211_reg_notifier( + + err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq)); + if (err) { +- brcmf_err("Country code iovar returned err = %d\n", err); ++ bphy_err(wiphy, "Country code iovar returned err = %d\n", err); + return; + } + +@@ -6862,7 +6911,7 @@ static void brcmf_cfg80211_reg_notifier( + + err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq)); + if (err) { +- brcmf_err("Firmware rejected country setting\n"); ++ bphy_err(wiphy, "Firmware rejected country setting\n"); + return; + } + brcmf_setup_wiphybands(cfg); +@@ -6908,13 +6957,13 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + u16 *cap = NULL; + + if (!ndev) { +- brcmf_err("ndev is invalid\n"); ++ bphy_err(wiphy, "ndev is invalid\n"); + return NULL; + } + + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + if (!cfg) { +- brcmf_err("Could not allocate wiphy device\n"); ++ bphy_err(wiphy, "Could not allocate wiphy device\n"); + return NULL; + } + +@@ -6935,7 +6984,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + + err = wl_init_priv(cfg); + if (err) { +- brcmf_err("Failed to init iwm_priv (%d)\n", err); ++ bphy_err(wiphy, "Failed to init iwm_priv (%d)\n", err); + brcmf_free_vif(vif); + goto wiphy_out; + } +@@ -6944,7 +6993,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + /* determine d11 io type before wiphy setup */ + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type); + if (err) { +- brcmf_err("Failed to get D11 version (%d)\n", err); ++ bphy_err(wiphy, "Failed to get D11 version (%d)\n", err); + goto priv_out; + } + cfg->d11inf.io_type = (u8)io_type; +@@ -6978,13 +7027,13 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + #endif + err = wiphy_register(wiphy); + if (err < 0) { +- brcmf_err("Could not register wiphy device (%d)\n", err); ++ bphy_err(wiphy, "Could not register wiphy device (%d)\n", err); + goto priv_out; + } + + err = brcmf_setup_wiphybands(cfg); + if (err) { +- brcmf_err("Setting wiphy bands failed (%d)\n", err); ++ bphy_err(wiphy, "Setting wiphy bands failed (%d)\n", err); + goto wiphy_unreg_out; + } + +@@ -7002,24 +7051,24 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + + err = brcmf_fweh_activate_events(ifp); + if (err) { +- brcmf_err("FWEH activation failed (%d)\n", err); ++ bphy_err(wiphy, "FWEH activation failed (%d)\n", err); + goto wiphy_unreg_out; + } + + err = brcmf_p2p_attach(cfg, p2pdev_forced); + if (err) { +- brcmf_err("P2P initialisation failed (%d)\n", err); ++ bphy_err(wiphy, "P2P initialisation failed (%d)\n", err); + goto wiphy_unreg_out; + } + err = brcmf_btcoex_attach(cfg); + if (err) { +- brcmf_err("BT-coex initialisation failed (%d)\n", err); ++ bphy_err(wiphy, "BT-coex initialisation failed (%d)\n", err); + brcmf_p2p_detach(&cfg->p2p); + goto wiphy_unreg_out; + } + err = brcmf_pno_attach(cfg); + if (err) { +- brcmf_err("PNO initialisation failed (%d)\n", err); ++ bphy_err(wiphy, "PNO initialisation failed (%d)\n", err); + brcmf_btcoex_detach(cfg); + brcmf_p2p_detach(&cfg->p2p); + goto wiphy_unreg_out; +@@ -7039,7 +7088,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + /* (re-) activate FWEH event handling */ + err = brcmf_fweh_activate_events(ifp); + if (err) { +- brcmf_err("FWEH activation failed (%d)\n", err); ++ bphy_err(wiphy, "FWEH activation failed (%d)\n", err); + goto detach; + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h +@@ -62,6 +62,15 @@ void __brcmf_err(struct brcmf_bus *bus, + } while (0) + #endif + ++#define bphy_err(wiphy, fmt, ...) \ ++ do { \ ++ if (IS_ENABLED(CPTCFG_BRCMDBG) || \ ++ IS_ENABLED(CPTCFG_BRCM_TRACING) || \ ++ net_ratelimit()) \ ++ wiphy_err(wiphy, "%s: " fmt, __func__, \ ++ ##__VA_ARGS__); \ ++ } while (0) ++ + #if defined(DEBUG) || defined(CPTCFG_BRCM_TRACING) + + /* For debug/tracing purposes treat info messages as errors */ diff --git a/package/kernel/mac80211/patches/brcm/347-v5.1-brcmfmac-fix-typos.patch b/package/kernel/mac80211/patches/brcm/347-v5.1-brcmfmac-fix-typos.patch new file mode 100644 index 0000000000..e21c1ee60a --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/347-v5.1-brcmfmac-fix-typos.patch @@ -0,0 +1,62 @@ +From 2359dd09f9819c7d57d81e05173541f0f9f820c7 Mon Sep 17 00:00:00 2001 +From: Matteo Croce +Date: Tue, 29 Jan 2019 18:47:17 +0100 +Subject: [PATCH] brcmfmac: fix typos + +Fix spelling mistakes in brcmfmac: "lenght" -> "length". +The typos are also in the special comment blocks which +translates to documentation. + +Signed-off-by: Matteo Croce +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h | 2 +- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 2 +- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h | 2 +- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 2 +- + 4 files changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -36,7 +36,7 @@ + #define BRCMF_DCMD_MEDLEN 1536 + #define BRCMF_DCMD_MAXLEN 8192 + +-/* IOCTL from host to device are limited in lenght. A device can only handle ++/* IOCTL from host to device are limited in length. A device can only handle + * ethernet frame size. This limitation is to be applied by protocol layer. + */ + #define BRCMF_TX_IOCTL_MAX_MSG_SIZE (ETH_FRAME_LEN+ETH_FCS_LEN) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -47,7 +47,7 @@ enum nvram_parser_state { + * @state: current parser state. + * @data: input buffer being parsed. + * @nvram: output buffer with parse result. +- * @nvram_len: lenght of parse result. ++ * @nvram_len: length of parse result. + * @line: current line. + * @column: current column in line. + * @pos: byte offset in input buffer. +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +@@ -266,7 +266,7 @@ struct brcmf_event { + * @status: status information. + * @reason: reason code. + * @auth_type: authentication type. +- * @datalen: lenght of event data buffer. ++ * @datalen: length of event data buffer. + * @addr: ether address. + * @ifname: interface name. + * @ifidx: interface index. +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -508,7 +508,7 @@ static void brcmf_usb_rx_complete(struct + skb = req->skb; + req->skb = NULL; + +- /* zero lenght packets indicate usb "failure". Do not refill */ ++ /* zero length packets indicate usb "failure". Do not refill */ + if (urb->status != 0 || !urb->actual_length) { + brcmu_pkt_buf_free_skb(skb); + brcmf_usb_enq(devinfo, &devinfo->rx_freeq, req, NULL); diff --git a/package/kernel/mac80211/patches/brcm/348-v5.1-brcmfmac-support-monitor-frames-with-the-hardware-uc.patch b/package/kernel/mac80211/patches/brcm/348-v5.1-brcmfmac-support-monitor-frames-with-the-hardware-uc.patch new file mode 100644 index 0000000000..c93bcf0ce9 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/348-v5.1-brcmfmac-support-monitor-frames-with-the-hardware-uc.patch @@ -0,0 +1,143 @@ +From e665988be29ccea3584528967b432a5cfd801ca4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 8 Feb 2019 07:42:30 +0100 +Subject: [PATCH] brcmfmac: support monitor frames with the hardware/ucode + header +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So far there were two monitor frame formats: +1) 802.11 frames (with frame (sub)type & all addresses) +2) 802.11 frames with the radiotap header + +Testing the latest FullMAC firmwares for 4366b1/4366c0 resulted in +discovering a new format being used. It seems (almost?) identical to the +one known from ucode used in SoftMAC devices which is most likely the +same codebase anyway. + +While new firmwares will /announce/ radiotap header support using the +"rtap" fw capability string it seems no string was added for the new +ucode header format. + +All above means that: +1) We need new format support when dealing with a received frame +2) A new feature bit & mapping quirks have to be added manually + +As for now only an empty radiotap is being created. Adding support for +extracting some info (band, channel, signal, etc.) is planned for the +future. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/core.c | 55 +++++++++++++++++++ + .../broadcom/brcm80211/brcmfmac/feature.c | 4 ++ + .../broadcom/brcm80211/brcmfmac/feature.h | 4 +- + 3 files changed, 62 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -43,6 +43,36 @@ + + #define BRCMF_BSSIDX_INVALID -1 + ++#define RXS_PBPRES BIT(2) ++ ++#define D11_PHY_HDR_LEN 6 ++ ++struct d11rxhdr_le { ++ __le16 RxFrameSize; ++ u16 PAD; ++ __le16 PhyRxStatus_0; ++ __le16 PhyRxStatus_1; ++ __le16 PhyRxStatus_2; ++ __le16 PhyRxStatus_3; ++ __le16 PhyRxStatus_4; ++ __le16 PhyRxStatus_5; ++ __le16 RxStatus1; ++ __le16 RxStatus2; ++ __le16 RxTSFTime; ++ __le16 RxChan; ++ u8 unknown[12]; ++} __packed; ++ ++struct wlc_d11rxhdr { ++ struct d11rxhdr_le rxhdr; ++ __le32 tsf_l; ++ s8 rssi; ++ s8 rxpwr0; ++ s8 rxpwr1; ++ s8 do_rssi_ma; ++ s8 rxpwr[4]; ++} __packed; ++ + char *brcmf_ifname(struct brcmf_if *ifp) + { + if (!ifp) +@@ -409,6 +439,31 @@ void brcmf_netif_mon_rx(struct brcmf_if + { + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_RADIOTAP)) { + /* Do nothing */ ++ } else if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR)) { ++ struct wlc_d11rxhdr *wlc_rxhdr = (struct wlc_d11rxhdr *)skb->data; ++ struct ieee80211_radiotap_header *radiotap; ++ unsigned int offset; ++ u16 RxStatus1; ++ ++ RxStatus1 = le16_to_cpu(wlc_rxhdr->rxhdr.RxStatus1); ++ ++ offset = sizeof(struct wlc_d11rxhdr); ++ /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU ++ * subframes ++ */ ++ if (RxStatus1 & RXS_PBPRES) ++ offset += 2; ++ offset += D11_PHY_HDR_LEN; ++ ++ skb_pull(skb, offset); ++ ++ /* TODO: use RX header to fill some radiotap data */ ++ radiotap = skb_push(skb, sizeof(*radiotap)); ++ memset(radiotap, 0, sizeof(*radiotap)); ++ radiotap->it_len = cpu_to_le16(sizeof(*radiotap)); ++ ++ /* TODO: 4 bytes with receive status? */ ++ skb->len -= 4; + } else { + struct ieee80211_radiotap_header *radiotap; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -103,6 +103,10 @@ static const struct brcmf_feat_fwfeat br + { "01-6cb8e269", BIT(BRCMF_FEAT_MONITOR) }, + /* brcmfmac4366b-pcie.bin from linux-firmware.git commit 52442afee990 */ + { "01-c47a91a4", BIT(BRCMF_FEAT_MONITOR) }, ++ /* brcmfmac4366b-pcie.bin from linux-firmware.git commit 211de1679a68 */ ++ { "01-801fb449", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) }, ++ /* brcmfmac4366c-pcie.bin from linux-firmware.git commit 211de1679a68 */ ++ { "01-d2cbb8fd", BIT(BRCMF_FEAT_MONITOR_FMT_HW_RX_HDR) }, + }; + + static void brcmf_feat_firmware_overrides(struct brcmf_pub *drv) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.h +@@ -35,6 +35,7 @@ + * FWSUP: Firmware supplicant. + * MONITOR: firmware can pass monitor packets to host. + * MONITOR_FMT_RADIOTAP: firmware provides monitor packets with radiotap header ++ * MONITOR_FMT_HW_RX_HDR: firmware provides monitor packets with hw/ucode header + */ + #define BRCMF_FEAT_LIST \ + BRCMF_FEAT_DEF(MBSS) \ +@@ -52,7 +53,8 @@ + BRCMF_FEAT_DEF(GSCAN) \ + BRCMF_FEAT_DEF(FWSUP) \ + BRCMF_FEAT_DEF(MONITOR) \ +- BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) ++ BRCMF_FEAT_DEF(MONITOR_FMT_RADIOTAP) \ ++ BRCMF_FEAT_DEF(MONITOR_FMT_HW_RX_HDR) + + /* + * Quirks: diff --git a/package/kernel/mac80211/patches/brcm/349-v5.1-0001-brcmfmac-assure-SSID-length-from-firmware-is-limited.patch b/package/kernel/mac80211/patches/brcm/349-v5.1-0001-brcmfmac-assure-SSID-length-from-firmware-is-limited.patch new file mode 100644 index 0000000000..78db26870b --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/349-v5.1-0001-brcmfmac-assure-SSID-length-from-firmware-is-limited.patch @@ -0,0 +1,28 @@ +From 1b5e2423164b3670e8bc9174e4762d297990deff Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 14 Feb 2019 13:43:47 +0100 +Subject: [PATCH] brcmfmac: assure SSID length from firmware is limited + +The SSID length as received from firmware should not exceed +IEEE80211_MAX_SSID_LEN as that would result in heap overflow. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -3499,6 +3499,8 @@ brcmf_wowl_nd_results(struct brcmf_if *i + } + + netinfo = brcmf_get_netinfo_array(pfn_result); ++ if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN) ++ netinfo->SSID_len = IEEE80211_MAX_SSID_LEN; + memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len); + cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len; + cfg->wowl.nd->n_channels = 1; diff --git a/package/kernel/mac80211/patches/brcm/349-v5.1-0002-brcmfmac-add-subtype-check-for-event-handling-in-dat.patch b/package/kernel/mac80211/patches/brcm/349-v5.1-0002-brcmfmac-add-subtype-check-for-event-handling-in-dat.patch new file mode 100644 index 0000000000..57946dabed --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/349-v5.1-0002-brcmfmac-add-subtype-check-for-event-handling-in-dat.patch @@ -0,0 +1,96 @@ +From a4176ec356c73a46c07c181c6d04039fafa34a9f Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 14 Feb 2019 13:43:48 +0100 +Subject: [PATCH] brcmfmac: add subtype check for event handling in data path + +For USB there is no separate channel being used to pass events +from firmware to the host driver and as such are passed over the +data path. In order to detect mock event messages an additional +check is needed on event subtype. This check is added conditionally +using unlikely() keyword. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 5 +++-- + .../wireless/broadcom/brcm80211/brcmfmac/fweh.h | 16 ++++++++++++---- + .../broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +- + 3 files changed, 16 insertions(+), 7 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -519,7 +519,8 @@ void brcmf_rx_frame(struct device *dev, + } else { + /* Process special event packets */ + if (handle_event) +- brcmf_fweh_process_skb(ifp->drvr, skb); ++ brcmf_fweh_process_skb(ifp->drvr, skb, ++ BCMILCP_SUBTYPE_VENDOR_LONG); + + brcmf_netif_rx(ifp, skb); + } +@@ -536,7 +537,7 @@ void brcmf_rx_event(struct device *dev, + if (brcmf_rx_hdrpull(drvr, skb, &ifp)) + return; + +- brcmf_fweh_process_skb(ifp->drvr, skb); ++ brcmf_fweh_process_skb(ifp->drvr, skb, 0); + brcmu_pkt_buf_free_skb(skb); + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.h +@@ -211,7 +211,7 @@ enum brcmf_fweh_event_code { + */ + #define BRCM_OUI "\x00\x10\x18" + #define BCMILCP_BCM_SUBTYPE_EVENT 1 +- ++#define BCMILCP_SUBTYPE_VENDOR_LONG 32769 + + /** + * struct brcm_ethhdr - broadcom specific ether header. +@@ -334,10 +334,10 @@ void brcmf_fweh_process_event(struct brc + void brcmf_fweh_p2pdev_setup(struct brcmf_if *ifp, bool ongoing); + + static inline void brcmf_fweh_process_skb(struct brcmf_pub *drvr, +- struct sk_buff *skb) ++ struct sk_buff *skb, u16 stype) + { + struct brcmf_event *event_packet; +- u16 usr_stype; ++ u16 subtype, usr_stype; + + /* only process events when protocol matches */ + if (skb->protocol != cpu_to_be16(ETH_P_LINK_CTL)) +@@ -346,8 +346,16 @@ static inline void brcmf_fweh_process_sk + if ((skb->len + ETH_HLEN) < sizeof(*event_packet)) + return; + +- /* check for BRCM oui match */ + event_packet = (struct brcmf_event *)skb_mac_header(skb); ++ ++ /* check subtype if needed */ ++ if (unlikely(stype)) { ++ subtype = get_unaligned_be16(&event_packet->hdr.subtype); ++ if (subtype != stype) ++ return; ++ } ++ ++ /* check for BRCM oui match */ + if (memcmp(BRCM_OUI, &event_packet->hdr.oui[0], + sizeof(event_packet->hdr.oui))) + return; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -1116,7 +1116,7 @@ static void brcmf_msgbuf_process_event(s + + skb->protocol = eth_type_trans(skb, ifp->ndev); + +- brcmf_fweh_process_skb(ifp->drvr, skb); ++ brcmf_fweh_process_skb(ifp->drvr, skb, 0); + + exit: + brcmu_pkt_buf_free_skb(skb); diff --git a/package/kernel/mac80211/patches/brcm/349-v5.1-0003-brcmfmac-create-debugfs-files-for-bus-specific-layer.patch b/package/kernel/mac80211/patches/brcm/349-v5.1-0003-brcmfmac-create-debugfs-files-for-bus-specific-layer.patch new file mode 100644 index 0000000000..b58ec4b7e9 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/349-v5.1-0003-brcmfmac-create-debugfs-files-for-bus-specific-layer.patch @@ -0,0 +1,101 @@ +From aaf6a5e86e36766abbeedf220462bde8031f9a72 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 14 Feb 2019 13:43:49 +0100 +Subject: [PATCH] brcmfmac: create debugfs files for bus-specific layer + +Since we moved the drivers debugfs directory under ieee80211 debugfs the +debugfs entries need to be added after wiphy_register() has been called. +For most part that has been done accordingly, but for the debugfs entries +added by SDIO it was not and failed silently. This patch fixes that by +adding a bus-layer callback for it. + +Fixes: 856d5a011c86 ("brcmfmac: allocate struct brcmf_pub instance using wiphy_new()") +Reported-by: Russel King +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 10 ++++++++++ + .../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 1 + + .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 12 +++++++----- + 3 files changed, 18 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -90,6 +90,7 @@ struct brcmf_bus_ops { + int (*get_memdump)(struct device *dev, void *data, size_t len); + int (*get_fwname)(struct device *dev, const char *ext, + unsigned char *fw_name); ++ void (*debugfs_create)(struct device *dev); + }; + + +@@ -235,6 +236,15 @@ int brcmf_bus_get_fwname(struct brcmf_bu + return bus->ops->get_fwname(bus->dev, ext, fw_name); + } + ++static inline ++void brcmf_bus_debugfs_create(struct brcmf_bus *bus) ++{ ++ if (!bus->ops->debugfs_create) ++ return; ++ ++ return bus->ops->debugfs_create(bus->dev); ++} ++ + /* + * interface functions from common layer + */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1177,6 +1177,7 @@ static int brcmf_bus_started(struct brcm + brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); + brcmf_feat_debugfs_create(drvr); + brcmf_proto_debugfs_create(drvr); ++ brcmf_bus_debugfs_create(bus_if); + + return 0; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -3143,9 +3143,12 @@ static int brcmf_debugfs_sdio_count_read + return 0; + } + +-static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) ++static void brcmf_sdio_debugfs_create(struct device *dev) + { +- struct brcmf_pub *drvr = bus->sdiodev->bus_if->drvr; ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_pub *drvr = bus_if->drvr; ++ struct brcmf_sdio_dev *sdiodev = bus_if->bus_priv.sdio; ++ struct brcmf_sdio *bus = sdiodev->bus; + struct dentry *dentry = brcmf_debugfs_get_devdir(drvr); + + if (IS_ERR_OR_NULL(dentry)) +@@ -3165,7 +3168,7 @@ static int brcmf_sdio_checkdied(struct b + return 0; + } + +-static void brcmf_sdio_debugfs_create(struct brcmf_sdio *bus) ++static void brcmf_sdio_debugfs_create(struct device *dev) + { + } + #endif /* DEBUG */ +@@ -3477,8 +3480,6 @@ static int brcmf_sdio_bus_preinit(struct + if (bus->rxbuf) + bus->rxblen = value; + +- brcmf_sdio_debugfs_create(bus); +- + /* the commands below use the terms tx and rx from + * a device perspective, ie. bus:txglom affects the + * bus transfers from device to host. +@@ -4088,6 +4089,7 @@ static const struct brcmf_bus_ops brcmf_ + .get_ramsize = brcmf_sdio_bus_get_ramsize, + .get_memdump = brcmf_sdio_bus_get_memdump, + .get_fwname = brcmf_sdio_get_fwname, ++ .debugfs_create = brcmf_sdio_debugfs_create + }; + + #define BRCMF_SDIO_FW_CODE 0 diff --git a/package/kernel/mac80211/patches/brcm/349-v5.1-0004-brcmfmac-disable-MBSS-feature-for-bcm4330-device.patch b/package/kernel/mac80211/patches/brcm/349-v5.1-0004-brcmfmac-disable-MBSS-feature-for-bcm4330-device.patch new file mode 100644 index 0000000000..e6602d7900 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/349-v5.1-0004-brcmfmac-disable-MBSS-feature-for-bcm4330-device.patch @@ -0,0 +1,41 @@ +From 92d3b88b1029c46f9bf27302c502dc0e3541805b Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 14 Feb 2019 13:43:50 +0100 +Subject: [PATCH] brcmfmac: disable MBSS feature for bcm4330 device + +The MBSS feature was already disabled for bcm43362 as it resulted in a +beacon with BRCM_TEST_SSID regardless user configuration in hostapd. Now +the same has been reported for bcm4330 so disable the feature for this +device as well. + +Reported-by: Russell King +Tested-by: Christopher Martin +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/feature.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -272,9 +272,15 @@ void brcmf_feat_attach(struct brcmf_pub + BIT(BRCMF_FEAT_WOWL_GTK); + } + } +- /* MBSS does not work for 43362 */ +- if (drvr->bus_if->chip == BRCM_CC_43362_CHIP_ID) ++ /* MBSS does not work for all chips */ ++ switch (drvr->bus_if->chip) { ++ case BRCM_CC_4330_CHIP_ID: ++ case BRCM_CC_43362_CHIP_ID: + ifp->drvr->feat_flags &= ~BIT(BRCMF_FEAT_MBSS); ++ break; ++ default: ++ break; ++ } + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_RSDB, "rsdb_mode"); + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_TDLS, "tdls_enable"); + brcmf_feat_iovar_int_get(ifp, BRCMF_FEAT_MFP, "mfp"); diff --git a/package/kernel/mac80211/patches/brcm/349-v5.1-0005-brcmfmac-check-and-dump-trap-info-during-sdio-probe.patch b/package/kernel/mac80211/patches/brcm/349-v5.1-0005-brcmfmac-check-and-dump-trap-info-during-sdio-probe.patch new file mode 100644 index 0000000000..dce4331585 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/349-v5.1-0005-brcmfmac-check-and-dump-trap-info-during-sdio-probe.patch @@ -0,0 +1,121 @@ +From 4ab2cf03da91785f2c34d79a302e53da06928bc1 Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 14 Feb 2019 13:43:51 +0100 +Subject: [PATCH] brcmfmac: check and dump trap info during sdio probe + +When the firmware crashes during the probe sequence we provide little +information on what really failed. This patch checks the sdpcm shared +location and show the trap information if a firmware trap has happened. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/sdio.c | 59 +++++++++++++------ + 1 file changed, 40 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -2999,21 +2999,35 @@ static int brcmf_sdio_trap_info(struct s + if (error < 0) + return error; + +- seq_printf(seq, +- "dongle trap info: type 0x%x @ epc 0x%08x\n" +- " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" +- " lr 0x%08x pc 0x%08x offset 0x%x\n" +- " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" +- " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", +- le32_to_cpu(tr.type), le32_to_cpu(tr.epc), +- le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), +- le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), +- le32_to_cpu(tr.pc), sh->trap_addr, +- le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), +- le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), +- le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), +- le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); +- ++ if (seq) ++ seq_printf(seq, ++ "dongle trap info: type 0x%x @ epc 0x%08x\n" ++ " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" ++ " lr 0x%08x pc 0x%08x offset 0x%x\n" ++ " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" ++ " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", ++ le32_to_cpu(tr.type), le32_to_cpu(tr.epc), ++ le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), ++ le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), ++ le32_to_cpu(tr.pc), sh->trap_addr, ++ le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), ++ le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), ++ le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), ++ le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); ++ else ++ pr_debug("dongle trap info: type 0x%x @ epc 0x%08x\n" ++ " cpsr 0x%08x spsr 0x%08x sp 0x%08x\n" ++ " lr 0x%08x pc 0x%08x offset 0x%x\n" ++ " r0 0x%08x r1 0x%08x r2 0x%08x r3 0x%08x\n" ++ " r4 0x%08x r5 0x%08x r6 0x%08x r7 0x%08x\n", ++ le32_to_cpu(tr.type), le32_to_cpu(tr.epc), ++ le32_to_cpu(tr.cpsr), le32_to_cpu(tr.spsr), ++ le32_to_cpu(tr.r13), le32_to_cpu(tr.r14), ++ le32_to_cpu(tr.pc), sh->trap_addr, ++ le32_to_cpu(tr.r0), le32_to_cpu(tr.r1), ++ le32_to_cpu(tr.r2), le32_to_cpu(tr.r3), ++ le32_to_cpu(tr.r4), le32_to_cpu(tr.r5), ++ le32_to_cpu(tr.r6), le32_to_cpu(tr.r7)); + return 0; + } + +@@ -3067,8 +3081,10 @@ static int brcmf_sdio_checkdied(struct b + else if (sh.flags & SDPCM_SHARED_ASSERT) + brcmf_err("assertion in dongle\n"); + +- if (sh.flags & SDPCM_SHARED_TRAP) ++ if (sh.flags & SDPCM_SHARED_TRAP) { + brcmf_err("firmware trap in dongle\n"); ++ brcmf_sdio_trap_info(NULL, bus, &sh); ++ } + + return 0; + } +@@ -4199,7 +4215,7 @@ static void brcmf_sdio_firmware_callback + } else { + /* Disable F2 again */ + sdio_disable_func(sdiod->func2); +- goto release; ++ goto checkdied; + } + + if (brcmf_chip_sr_capable(bus->ci)) { +@@ -4220,8 +4236,10 @@ static void brcmf_sdio_firmware_callback + } + + /* If we didn't come up, turn off backplane clock */ +- if (err != 0) ++ if (err != 0) { + brcmf_sdio_clkctl(bus, CLK_NONE, false); ++ goto checkdied; ++ } + + sdio_release_host(sdiod->func1); + +@@ -4235,12 +4253,15 @@ static void brcmf_sdio_firmware_callback + err = brcmf_attach(sdiod->dev, sdiod->settings); + if (err != 0) { + brcmf_err("brcmf_attach failed\n"); +- goto fail; ++ sdio_claim_host(sdiod->func1); ++ goto checkdied; + } + + /* ready */ + return; + ++checkdied: ++ brcmf_sdio_checkdied(bus); + release: + sdio_release_host(sdiod->func1); + fail: diff --git a/package/kernel/mac80211/patches/brcm/349-v5.1-0006-brcmfmac-use-chipname-in-brcmf_fw_alloc_request-for-.patch b/package/kernel/mac80211/patches/brcm/349-v5.1-0006-brcmfmac-use-chipname-in-brcmf_fw_alloc_request-for-.patch new file mode 100644 index 0000000000..23180c7236 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/349-v5.1-0006-brcmfmac-use-chipname-in-brcmf_fw_alloc_request-for-.patch @@ -0,0 +1,42 @@ +From a250c91c1762e85c736e67cb4a9a95ebae72e62d Mon Sep 17 00:00:00 2001 +From: Arend van Spriel +Date: Thu, 14 Feb 2019 13:43:52 +0100 +Subject: [PATCH] brcmfmac: use chipname in brcmf_fw_alloc_request() for error + path as well + +The local variable chipname is string representation of chip id and revision +which is printed in the good flow of brcmf_fw_alloc_request(). Also use it +for the error path, ie. for unknown/unsupported devices. + +Reviewed-by: Hante Meuleman +Reviewed-by: Pieter-Paul Giesberts +Reviewed-by: Franky Lin +Signed-off-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -719,8 +719,10 @@ brcmf_fw_alloc_request(u32 chip, u32 chi + break; + } + ++ brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname)); ++ + if (i == table_size) { +- brcmf_err("Unknown chipid %d [%d]\n", chip, chiprev); ++ brcmf_err("Unknown chip %s\n", chipname); + return NULL; + } + +@@ -729,8 +731,6 @@ brcmf_fw_alloc_request(u32 chip, u32 chi + if (!fwreq) + return NULL; + +- brcmf_chip_name(chip, chiprev, chipname, sizeof(chipname)); +- + brcmf_info("using %s for chip %s\n", + mapping_table[i].fw_base, chipname); + diff --git a/package/kernel/mac80211/patches/brcm/350-v5.1-brcmfmac-print-firmware-reported-ring-status-errors.patch b/package/kernel/mac80211/patches/brcm/350-v5.1-brcmfmac-print-firmware-reported-ring-status-errors.patch new file mode 100644 index 0000000000..b41b9cebf4 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/350-v5.1-brcmfmac-print-firmware-reported-ring-status-errors.patch @@ -0,0 +1,67 @@ +From c988b78244df8216902e20de536434e2f474a37e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 8 Feb 2019 15:24:39 +0100 +Subject: [PATCH] brcmfmac: print firmware reported ring status errors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Firmware is capable of reporting ring status. It's used e.g. to signal +some problem with a specific ring setup. This patch adds support for +printing ring & error number which may be useful for debugging setup +issues. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/msgbuf.c | 25 +++++++++++++++++++ + 1 file changed, 25 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -134,6 +134,14 @@ struct msgbuf_completion_hdr { + __le16 flow_ring_id; + }; + ++/* Data struct for the MSGBUF_TYPE_RING_STATUS */ ++struct msgbuf_ring_status { ++ struct msgbuf_common_hdr msg; ++ struct msgbuf_completion_hdr compl_hdr; ++ __le16 write_idx; ++ __le32 rsvd0[5]; ++}; ++ + struct msgbuf_rx_event { + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; +@@ -1180,6 +1188,19 @@ brcmf_msgbuf_process_rx_complete(struct + brcmf_netif_rx(ifp, skb); + } + ++static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf, ++ void *buf) ++{ ++ struct msgbuf_ring_status *ring_status = buf; ++ int err; ++ ++ err = le16_to_cpu(ring_status->compl_hdr.status); ++ if (err) { ++ int ring = le16_to_cpu(ring_status->compl_hdr.flow_ring_id); ++ ++ brcmf_err("Firmware reported ring %d error: %d\n", ring, err); ++ } ++} + + static void + brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf, +@@ -1241,6 +1262,10 @@ static void brcmf_msgbuf_process_msgtype + + msg = (struct msgbuf_common_hdr *)buf; + switch (msg->msgtype) { ++ case MSGBUF_TYPE_RING_STATUS: ++ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RING_STATUS\n"); ++ brcmf_msgbuf_process_ring_status(msgbuf, buf); ++ break; + case MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT: + brcmf_dbg(MSGBUF, "MSGBUF_TYPE_FLOW_RING_CREATE_CMPLT\n"); + brcmf_msgbuf_process_flow_ring_create_response(msgbuf, buf); diff --git a/package/kernel/mac80211/patches/brcm/351-v5.1-0001-brcmfmac-improve-code-handling-bandwidth-of-firmware.patch b/package/kernel/mac80211/patches/brcm/351-v5.1-0001-brcmfmac-improve-code-handling-bandwidth-of-firmware.patch new file mode 100644 index 0000000000..4e49246554 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/351-v5.1-0001-brcmfmac-improve-code-handling-bandwidth-of-firmware.patch @@ -0,0 +1,42 @@ +From f4e183293b871c96c0220dcc549d5ca4c72628ad Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 11 Feb 2019 23:04:53 +0100 +Subject: [PATCH] brcmfmac: improve code handling bandwidth of firmware + reported channels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +1) Use switch to simplify/improve the code & avoid some duplication +2) Add warning for unsupported values + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6043,11 +6043,18 @@ static int brcmf_construct_chaninfo(stru + /* assuming the chanspecs order is HT20, + * HT40 upper, HT40 lower, and VHT80. + */ +- if (ch.bw == BRCMU_CHAN_BW_80) { ++ switch (ch.bw) { ++ case BRCMU_CHAN_BW_80: + channel->flags &= ~IEEE80211_CHAN_NO_80MHZ; +- } else if (ch.bw == BRCMU_CHAN_BW_40) { ++ break; ++ case BRCMU_CHAN_BW_40: + brcmf_update_bw40_channel_flag(channel, &ch); +- } else { ++ break; ++ default: ++ wiphy_warn(wiphy, "Firmware reported unsupported bandwidth %d\n", ++ ch.bw); ++ /* fall through */ ++ case BRCMU_CHAN_BW_20: + /* enable the channel and disable other bandwidths + * for now as mentioned order assure they are enabled + * for subsequent chanspecs. diff --git a/package/kernel/mac80211/patches/brcm/351-v5.1-0002-brcmfmac-support-firmware-reporting-160-MHz-channels.patch b/package/kernel/mac80211/patches/brcm/351-v5.1-0002-brcmfmac-support-firmware-reporting-160-MHz-channels.patch new file mode 100644 index 0000000000..a809378d13 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/351-v5.1-0002-brcmfmac-support-firmware-reporting-160-MHz-channels.patch @@ -0,0 +1,30 @@ +From 30519cbe339a45bd11a57ca8ece07f4f6a1cda2e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Mon, 11 Feb 2019 23:04:54 +0100 +Subject: [PATCH] brcmfmac: support firmware reporting 160 MHz channels +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +So far 160 MHz channels were treated as 20 MHz ones which was breaking +support for 40/80 MHz due to the brcmf_construct_chaninfo() logic and +its assumptions. + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -6044,6 +6044,9 @@ static int brcmf_construct_chaninfo(stru + * HT40 upper, HT40 lower, and VHT80. + */ + switch (ch.bw) { ++ case BRCMU_CHAN_BW_160: ++ channel->flags &= ~IEEE80211_CHAN_NO_160MHZ; ++ break; + case BRCMU_CHAN_BW_80: + channel->flags &= ~IEEE80211_CHAN_NO_80MHZ; + break; diff --git a/package/kernel/mac80211/patches/brcm/352-v5.1-brcmfmac-rework-bphy_err-to-take-struct-brcmf_pub-ar.patch b/package/kernel/mac80211/patches/brcm/352-v5.1-brcmfmac-rework-bphy_err-to-take-struct-brcmf_pub-ar.patch new file mode 100644 index 0000000000..27931db840 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/352-v5.1-brcmfmac-rework-bphy_err-to-take-struct-brcmf_pub-ar.patch @@ -0,0 +1,2290 @@ +From 16e646768396339b3d354985b99bcd3f1f195a7d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Fri, 15 Feb 2019 15:45:54 +0100 +Subject: [PATCH] brcmfmac: rework bphy_err() to take struct brcmf_pub argument +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This macro will be used in more places not just the cfg80211.c. It makes +sense to pass some common struct to it as "struct wiphy" is mostly +referenced in cfg80211 code only. + +A very common one (used above the bus abstraction layer) is struct +brcmf_pub. Many functions already keep reference to it which will make +using bphy_err() simpler. It should also allow extending that macro's +logic if it's ever needed. + +This improves code recently added in the commit 3ef005b82e2a ("brcmfmac: +add bphy_err() and use it in the cfg80211.c"). + +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/cfg80211.c | 510 ++++++++++-------- + .../broadcom/brcm80211/brcmfmac/debug.h | 4 +- + 2 files changed, 281 insertions(+), 233 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -457,7 +457,7 @@ static void convert_key_from_CPU(struct + static int + send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + int err; + struct brcmf_wsec_key_le key_le; + +@@ -469,7 +469,7 @@ send_key_to_dongle(struct brcmf_if *ifp, + sizeof(key_le)); + + if (err) +- bphy_err(wiphy, "wsec_key error (%d)\n", err); ++ bphy_err(drvr, "wsec_key error (%d)\n", err); + return err; + } + +@@ -509,7 +509,7 @@ static int brcmf_get_first_free_bsscfgid + + static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_mbss_ssid_le mbss_ssid_le; + int bsscfgidx; + int err; +@@ -526,7 +526,7 @@ static int brcmf_cfg80211_request_ap_if( + err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le, + sizeof(mbss_ssid_le)); + if (err < 0) +- bphy_err(wiphy, "setting ssid failed %d\n", err); ++ bphy_err(drvr, "setting ssid failed %d\n", err); + + return err; + } +@@ -544,6 +544,7 @@ struct wireless_dev *brcmf_ap_add_vif(st + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_cfg80211_vif *vif; + int err; + +@@ -569,7 +570,7 @@ struct wireless_dev *brcmf_ap_add_vif(st + BRCMF_VIF_EVENT_TIMEOUT); + brcmf_cfg80211_arm_vif_event(cfg, NULL); + if (!err) { +- bphy_err(wiphy, "timeout occurred\n"); ++ bphy_err(drvr, "timeout occurred\n"); + err = -EIO; + goto fail; + } +@@ -577,7 +578,7 @@ struct wireless_dev *brcmf_ap_add_vif(st + /* interface created in firmware */ + ifp = vif->ifp; + if (!ifp) { +- bphy_err(wiphy, "no if pointer provided\n"); ++ bphy_err(drvr, "no if pointer provided\n"); + err = -ENOENT; + goto fail; + } +@@ -585,7 +586,7 @@ struct wireless_dev *brcmf_ap_add_vif(st + strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1); + err = brcmf_net_attach(ifp, true); + if (err) { +- bphy_err(wiphy, "Registering netdevice failed\n"); ++ bphy_err(drvr, "Registering netdevice failed\n"); + free_netdev(ifp->ndev); + goto fail; + } +@@ -616,13 +617,15 @@ static struct wireless_dev *brcmf_cfg802 + enum nl80211_iftype type, + struct vif_params *params) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct wireless_dev *wdev; + int err; + + brcmf_dbg(TRACE, "enter: %s type %d\n", name, type); + err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type); + if (err) { +- bphy_err(wiphy, "iface validation failed: err=%d\n", err); ++ bphy_err(drvr, "iface validation failed: err=%d\n", err); + return ERR_PTR(err); + } + switch (type) { +@@ -647,7 +650,7 @@ static struct wireless_dev *brcmf_cfg802 + } + + if (IS_ERR(wdev)) +- bphy_err(wiphy, "add iface %s type %d failed: err=%d\n", name, ++ bphy_err(drvr, "add iface %s type %d failed: err=%d\n", name, + type, (int)PTR_ERR(wdev)); + else + brcmf_cfg80211_update_proto_addr_mode(wdev); +@@ -663,13 +666,13 @@ static void brcmf_scan_config_mpc(struct + + void brcmf_set_mpc(struct brcmf_if *ifp, int mpc) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + s32 err = 0; + + if (check_vif_up(ifp->vif)) { + err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc); + if (err) { +- bphy_err(wiphy, "fail to set mpc\n"); ++ bphy_err(drvr, "fail to set mpc\n"); + return; + } + brcmf_dbg(INFO, "MPC : %d\n", mpc); +@@ -680,7 +683,7 @@ s32 brcmf_notify_escan_complete(struct b + struct brcmf_if *ifp, bool aborted, + bool fw_abort) + { +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_scan_params_le params_le; + struct cfg80211_scan_request *scan_request; + u64 reqid; +@@ -715,7 +718,7 @@ s32 brcmf_notify_escan_complete(struct b + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, + ¶ms_le, sizeof(params_le)); + if (err) +- bphy_err(wiphy, "Scan abort failed\n"); ++ bphy_err(drvr, "Scan abort failed\n"); + } + + brcmf_scan_config_mpc(ifp, 1); +@@ -760,6 +763,7 @@ static int brcmf_cfg80211_del_ap_iface(s + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct net_device *ndev = wdev->netdev; + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = cfg->pub; + int ret; + int err; + +@@ -767,7 +771,7 @@ static int brcmf_cfg80211_del_ap_iface(s + + err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0); + if (err) { +- bphy_err(wiphy, "interface_remove failed %d\n", err); ++ bphy_err(drvr, "interface_remove failed %d\n", err); + goto err_unarm; + } + +@@ -775,7 +779,7 @@ static int brcmf_cfg80211_del_ap_iface(s + ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL, + BRCMF_VIF_EVENT_TIMEOUT); + if (!ret) { +- bphy_err(wiphy, "timeout occurred\n"); ++ bphy_err(drvr, "timeout occurred\n"); + err = -EIO; + goto err_unarm; + } +@@ -838,6 +842,7 @@ brcmf_cfg80211_change_iface(struct wiphy + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_vif *vif = ifp->vif; ++ struct brcmf_pub *drvr = cfg->pub; + s32 infra = 0; + s32 ap = 0; + s32 err = 0; +@@ -877,13 +882,13 @@ brcmf_cfg80211_change_iface(struct wiphy + } + err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type); + if (err) { +- bphy_err(wiphy, "iface validation failed: err=%d\n", err); ++ bphy_err(drvr, "iface validation failed: err=%d\n", err); + return err; + } + switch (type) { + case NL80211_IFTYPE_MONITOR: + case NL80211_IFTYPE_WDS: +- bphy_err(wiphy, "type (%d) : currently we do not support this type\n", ++ bphy_err(drvr, "type (%d) : currently we do not support this type\n", + type); + return -EOPNOTSUPP; + case NL80211_IFTYPE_ADHOC: +@@ -912,7 +917,7 @@ brcmf_cfg80211_change_iface(struct wiphy + } else { + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra); + if (err) { +- bphy_err(wiphy, "WLC_SET_INFRA error (%d)\n", err); ++ bphy_err(drvr, "WLC_SET_INFRA error (%d)\n", err); + err = -EAGAIN; + goto done; + } +@@ -1003,7 +1008,7 @@ static s32 + brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp, + struct cfg80211_scan_request *request) + { +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE + + offsetof(struct brcmf_escan_params_le, params_le); + struct brcmf_escan_params_le *params; +@@ -1035,7 +1040,7 @@ brcmf_run_escan(struct brcmf_cfg80211_in + if (err == -EBUSY) + brcmf_dbg(INFO, "system busy : escan canceled\n"); + else +- bphy_err(wiphy, "error (%d)\n", err); ++ bphy_err(drvr, "error (%d)\n", err); + } + + kfree(params); +@@ -1072,6 +1077,7 @@ static s32 + brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request) + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_cfg80211_vif *vif; + s32 err = 0; + +@@ -1081,22 +1087,22 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, + return -EIO; + + if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { +- bphy_err(wiphy, "Scanning already: status (%lu)\n", ++ bphy_err(drvr, "Scanning already: status (%lu)\n", + cfg->scan_status); + return -EAGAIN; + } + if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) { +- bphy_err(wiphy, "Scanning being aborted: status (%lu)\n", ++ bphy_err(drvr, "Scanning being aborted: status (%lu)\n", + cfg->scan_status); + return -EAGAIN; + } + if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { +- bphy_err(wiphy, "Scanning suppressed: status (%lu)\n", ++ bphy_err(drvr, "Scanning suppressed: status (%lu)\n", + cfg->scan_status); + return -EAGAIN; + } + if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) { +- bphy_err(wiphy, "Connecting: status (%lu)\n", vif->sme_state); ++ bphy_err(drvr, "Connecting: status (%lu)\n", vif->sme_state); + return -EAGAIN; + } + +@@ -1130,7 +1136,7 @@ brcmf_cfg80211_scan(struct wiphy *wiphy, + return 0; + + scan_out: +- bphy_err(wiphy, "scan error (%d)\n", err); ++ bphy_err(drvr, "scan error (%d)\n", err); + clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status); + cfg->scan_request = NULL; + return err; +@@ -1139,12 +1145,12 @@ scan_out: + static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + s32 err = 0; + + err = brcmf_fil_iovar_int_set(ifp, "rtsthresh", rts_threshold); + if (err) +- bphy_err(wiphy, "Error (%d)\n", err); ++ bphy_err(drvr, "Error (%d)\n", err); + + return err; + } +@@ -1152,13 +1158,13 @@ static s32 brcmf_set_rts(struct net_devi + static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + s32 err = 0; + + err = brcmf_fil_iovar_int_set(ifp, "fragthresh", + frag_threshold); + if (err) +- bphy_err(wiphy, "Error (%d)\n", err); ++ bphy_err(drvr, "Error (%d)\n", err); + + return err; + } +@@ -1166,13 +1172,13 @@ static s32 brcmf_set_frag(struct net_dev + static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + s32 err = 0; + u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL); + + err = brcmf_fil_cmd_int_set(ifp, cmd, retry); + if (err) { +- bphy_err(wiphy, "cmd (%d) , error (%d)\n", cmd, err); ++ bphy_err(drvr, "cmd (%d) , error (%d)\n", cmd, err); + return err; + } + return err; +@@ -1248,7 +1254,7 @@ static u16 brcmf_map_fw_linkdown_reason( + + static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_wsec_pmk_le pmk; + int i, err; + +@@ -1262,7 +1268,7 @@ static int brcmf_set_pmk(struct brcmf_if + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK, + &pmk, sizeof(pmk)); + if (err < 0) +- bphy_err(wiphy, "failed to change PSK in firmware (len=%u)\n", ++ bphy_err(drvr, "failed to change PSK in firmware (len=%u)\n", + pmk_len); + + return err; +@@ -1271,7 +1277,7 @@ static int brcmf_set_pmk(struct brcmf_if + static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason) + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy); +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + s32 err = 0; + + brcmf_dbg(TRACE, "Enter\n"); +@@ -1281,7 +1287,7 @@ static void brcmf_link_down(struct brcmf + err = brcmf_fil_cmd_data_set(vif->ifp, + BRCMF_C_DISASSOC, NULL, 0); + if (err) { +- bphy_err(wiphy, "WLC_DISASSOC failed (%d)\n", err); ++ bphy_err(drvr, "WLC_DISASSOC failed (%d)\n", err); + } + if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) || + (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)) +@@ -1305,6 +1311,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *w + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_join_params join_params; + size_t join_params_size = 0; + s32 err = 0; +@@ -1369,7 +1376,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *w + + err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec); + if (err) { +- bphy_err(wiphy, "wsec failed (%d)\n", err); ++ bphy_err(drvr, "wsec failed (%d)\n", err); + goto done; + } + +@@ -1381,7 +1388,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *w + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd); + if (err) { +- bphy_err(wiphy, "WLC_SET_BCNPRD failed (%d)\n", err); ++ bphy_err(drvr, "WLC_SET_BCNPRD failed (%d)\n", err); + goto done; + } + +@@ -1426,7 +1433,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *w + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL, + target_channel); + if (err) { +- bphy_err(wiphy, "WLC_SET_CHANNEL failed (%d)\n", err); ++ bphy_err(drvr, "WLC_SET_CHANNEL failed (%d)\n", err); + goto done; + } + } else +@@ -1438,7 +1445,7 @@ brcmf_cfg80211_join_ibss(struct wiphy *w + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, + &join_params, join_params_size); + if (err) { +- bphy_err(wiphy, "WLC_SET_SSID failed (%d)\n", err); ++ bphy_err(drvr, "WLC_SET_SSID failed (%d)\n", err); + goto done; + } + +@@ -1475,8 +1482,8 @@ static s32 brcmf_set_wpa_version(struct + struct cfg80211_connect_params *sme) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_cfg80211_security *sec; + s32 val = 0; + s32 err = 0; +@@ -1490,7 +1497,7 @@ static s32 brcmf_set_wpa_version(struct + brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val); + err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val); + if (err) { +- bphy_err(wiphy, "set wpa_auth failed (%d)\n", err); ++ bphy_err(drvr, "set wpa_auth failed (%d)\n", err); + return err; + } + sec = &profile->sec; +@@ -1502,8 +1509,8 @@ static s32 brcmf_set_auth_type(struct ne + struct cfg80211_connect_params *sme) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_cfg80211_security *sec; + s32 val = 0; + s32 err = 0; +@@ -1525,7 +1532,7 @@ static s32 brcmf_set_auth_type(struct ne + + err = brcmf_fil_bsscfg_int_set(ifp, "auth", val); + if (err) { +- bphy_err(wiphy, "set auth failed (%d)\n", err); ++ bphy_err(drvr, "set auth failed (%d)\n", err); + return err; + } + sec = &profile->sec; +@@ -1538,8 +1545,8 @@ brcmf_set_wsec_mode(struct net_device *n + struct cfg80211_connect_params *sme) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_cfg80211_security *sec; + s32 pval = 0; + s32 gval = 0; +@@ -1562,7 +1569,7 @@ brcmf_set_wsec_mode(struct net_device *n + pval = AES_ENABLED; + break; + default: +- bphy_err(wiphy, "invalid cipher pairwise (%d)\n", ++ bphy_err(drvr, "invalid cipher pairwise (%d)\n", + sme->crypto.ciphers_pairwise[0]); + return -EINVAL; + } +@@ -1583,7 +1590,7 @@ brcmf_set_wsec_mode(struct net_device *n + gval = AES_ENABLED; + break; + default: +- bphy_err(wiphy, "invalid cipher group (%d)\n", ++ bphy_err(drvr, "invalid cipher group (%d)\n", + sme->crypto.cipher_group); + return -EINVAL; + } +@@ -1599,7 +1606,7 @@ brcmf_set_wsec_mode(struct net_device *n + wsec = pval | gval; + err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + if (err) { +- bphy_err(wiphy, "error (%d)\n", err); ++ bphy_err(drvr, "error (%d)\n", err); + return err; + } + +@@ -1614,8 +1621,8 @@ static s32 + brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct wiphy *wiphy = ifp->drvr->wiphy; + struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; ++ struct brcmf_pub *drvr = ifp->drvr; + s32 val; + s32 err; + const struct brcmf_tlv *rsn_ie; +@@ -1633,7 +1640,7 @@ brcmf_set_key_mgmt(struct net_device *nd + + err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val); + if (err) { +- bphy_err(wiphy, "could not get wpa_auth (%d)\n", err); ++ bphy_err(drvr, "could not get wpa_auth (%d)\n", err); + return err; + } + if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { +@@ -1647,7 +1654,7 @@ brcmf_set_key_mgmt(struct net_device *nd + val = WPA_AUTH_PSK; + break; + default: +- bphy_err(wiphy, "invalid cipher group (%d)\n", ++ bphy_err(drvr, "invalid cipher group (%d)\n", + sme->crypto.cipher_group); + return -EINVAL; + } +@@ -1670,7 +1677,7 @@ brcmf_set_key_mgmt(struct net_device *nd + val = WPA2_AUTH_PSK; + break; + default: +- bphy_err(wiphy, "invalid cipher group (%d)\n", ++ bphy_err(drvr, "invalid cipher group (%d)\n", + sme->crypto.cipher_group); + return -EINVAL; + } +@@ -1717,7 +1724,7 @@ skip_mfp_config: + brcmf_dbg(CONN, "setting wpa_auth to %d\n", val); + err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val); + if (err) { +- bphy_err(wiphy, "could not set wpa_auth (%d)\n", err); ++ bphy_err(drvr, "could not set wpa_auth (%d)\n", err); + return err; + } + +@@ -1729,7 +1736,7 @@ brcmf_set_sharedkey(struct net_device *n + struct cfg80211_connect_params *sme) + { + struct brcmf_if *ifp = netdev_priv(ndev); +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev); + struct brcmf_cfg80211_security *sec; + struct brcmf_wsec_key key; +@@ -1756,7 +1763,7 @@ brcmf_set_sharedkey(struct net_device *n + key.len = (u32) sme->key_len; + key.index = (u32) sme->key_idx; + if (key.len > sizeof(key.data)) { +- bphy_err(wiphy, "Too long key length (%u)\n", key.len); ++ bphy_err(drvr, "Too long key length (%u)\n", key.len); + return -EINVAL; + } + memcpy(key.data, sme->key, key.len); +@@ -1769,7 +1776,7 @@ brcmf_set_sharedkey(struct net_device *n + key.algo = CRYPTO_ALGO_WEP128; + break; + default: +- bphy_err(wiphy, "Invalid algorithm (%d)\n", ++ bphy_err(drvr, "Invalid algorithm (%d)\n", + sme->crypto.ciphers_pairwise[0]); + return -EINVAL; + } +@@ -1786,7 +1793,7 @@ brcmf_set_sharedkey(struct net_device *n + val = WL_AUTH_SHARED_KEY; /* shared key */ + err = brcmf_fil_bsscfg_int_set(ifp, "auth", val); + if (err) +- bphy_err(wiphy, "set auth failed (%d)\n", err); ++ bphy_err(drvr, "set auth failed (%d)\n", err); + } + return err; + } +@@ -1806,7 +1813,7 @@ enum nl80211_auth_type brcmf_war_auth_ty + static void brcmf_set_join_pref(struct brcmf_if *ifp, + struct cfg80211_bss_selection *bss_select) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_join_pref_params join_pref_params[2]; + enum nl80211_band band; + int err, i = 0; +@@ -1845,7 +1852,7 @@ static void brcmf_set_join_pref(struct b + err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params, + sizeof(join_pref_params)); + if (err) +- bphy_err(wiphy, "Set join_pref error (%d)\n", err); ++ bphy_err(drvr, "Set join_pref error (%d)\n", err); + } + + static s32 +@@ -1856,6 +1863,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; + struct ieee80211_channel *chan = sme->channel; ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_join_params join_params; + size_t join_params_size; + const struct brcmf_tlv *rsn_ie; +@@ -1872,7 +1880,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + return -EIO; + + if (!sme->ssid) { +- bphy_err(wiphy, "Invalid ssid\n"); ++ bphy_err(drvr, "Invalid ssid\n"); + return -EOPNOTSUPP; + } + +@@ -1901,7 +1909,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG, + sme->ie, sme->ie_len); + if (err) +- bphy_err(wiphy, "Set Assoc REQ IE Failed\n"); ++ bphy_err(drvr, "Set Assoc REQ IE Failed\n"); + else + brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n"); + +@@ -1922,32 +1930,32 @@ brcmf_cfg80211_connect(struct wiphy *wip + + err = brcmf_set_wpa_version(ndev, sme); + if (err) { +- bphy_err(wiphy, "wl_set_wpa_version failed (%d)\n", err); ++ bphy_err(drvr, "wl_set_wpa_version failed (%d)\n", err); + goto done; + } + + sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type); + err = brcmf_set_auth_type(ndev, sme); + if (err) { +- bphy_err(wiphy, "wl_set_auth_type failed (%d)\n", err); ++ bphy_err(drvr, "wl_set_auth_type failed (%d)\n", err); + goto done; + } + + err = brcmf_set_wsec_mode(ndev, sme); + if (err) { +- bphy_err(wiphy, "wl_set_set_cipher failed (%d)\n", err); ++ bphy_err(drvr, "wl_set_set_cipher failed (%d)\n", err); + goto done; + } + + err = brcmf_set_key_mgmt(ndev, sme); + if (err) { +- bphy_err(wiphy, "wl_set_key_mgmt failed (%d)\n", err); ++ bphy_err(drvr, "wl_set_key_mgmt failed (%d)\n", err); + goto done; + } + + err = brcmf_set_sharedkey(ndev, sme); + if (err) { +- bphy_err(wiphy, "brcmf_set_sharedkey failed (%d)\n", err); ++ bphy_err(drvr, "brcmf_set_sharedkey failed (%d)\n", err); + goto done; + } + +@@ -1964,7 +1972,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + /* enable firmware supplicant for this interface */ + err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1); + if (err < 0) { +- bphy_err(wiphy, "failed to enable fw supplicant\n"); ++ bphy_err(drvr, "failed to enable fw supplicant\n"); + goto done; + } + } +@@ -2059,7 +2067,7 @@ brcmf_cfg80211_connect(struct wiphy *wip + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, + &join_params, join_params_size); + if (err) +- bphy_err(wiphy, "BRCMF_C_SET_SSID failed (%d)\n", err); ++ bphy_err(drvr, "BRCMF_C_SET_SSID failed (%d)\n", err); + + done: + if (err) +@@ -2072,8 +2080,10 @@ static s32 + brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev, + u16 reason_code) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_scb_val_le scbval; + s32 err = 0; + +@@ -2090,7 +2100,7 @@ brcmf_cfg80211_disconnect(struct wiphy * + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC, + &scbval, sizeof(scbval)); + if (err) +- bphy_err(wiphy, "error (%d)\n", err); ++ bphy_err(drvr, "error (%d)\n", err); + + brcmf_dbg(TRACE, "Exit\n"); + return err; +@@ -2103,6 +2113,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct net_device *ndev = cfg_to_ndev(cfg); + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = cfg->pub; + s32 err; + s32 disable; + u32 qdbm = 127; +@@ -2117,7 +2128,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy + case NL80211_TX_POWER_LIMITED: + case NL80211_TX_POWER_FIXED: + if (mbm < 0) { +- bphy_err(wiphy, "TX_POWER_FIXED - dbm is negative\n"); ++ bphy_err(drvr, "TX_POWER_FIXED - dbm is negative\n"); + err = -EINVAL; + goto done; + } +@@ -2127,7 +2138,7 @@ brcmf_cfg80211_set_tx_power(struct wiphy + qdbm |= WL_TXPWR_OVERRIDE; + break; + default: +- bphy_err(wiphy, "Unsupported type %d\n", type); ++ bphy_err(drvr, "Unsupported type %d\n", type); + err = -EINVAL; + goto done; + } +@@ -2135,11 +2146,11 @@ brcmf_cfg80211_set_tx_power(struct wiphy + disable = WL_RADIO_SW_DISABLE << 16; + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable); + if (err) +- bphy_err(wiphy, "WLC_SET_RADIO error (%d)\n", err); ++ bphy_err(drvr, "WLC_SET_RADIO error (%d)\n", err); + + err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm); + if (err) +- bphy_err(wiphy, "qtxpower error (%d)\n", err); ++ bphy_err(drvr, "qtxpower error (%d)\n", err); + + done: + brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE); +@@ -2150,7 +2161,9 @@ static s32 + brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev, + s32 *dbm) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev); ++ struct brcmf_pub *drvr = cfg->pub; + s32 qdbm = 0; + s32 err; + +@@ -2160,7 +2173,7 @@ brcmf_cfg80211_get_tx_power(struct wiphy + + err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm); + if (err) { +- bphy_err(wiphy, "error (%d)\n", err); ++ bphy_err(drvr, "error (%d)\n", err); + goto done; + } + *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4; +@@ -2175,6 +2188,7 @@ brcmf_cfg80211_config_default_key(struct + u8 key_idx, bool unicast, bool multicast) + { + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = ifp->drvr; + u32 index; + u32 wsec; + s32 err = 0; +@@ -2186,7 +2200,7 @@ brcmf_cfg80211_config_default_key(struct + + err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + if (err) { +- bphy_err(wiphy, "WLC_GET_WSEC error (%d)\n", err); ++ bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err); + goto done; + } + +@@ -2196,7 +2210,7 @@ brcmf_cfg80211_config_default_key(struct + err = brcmf_fil_cmd_int_set(ifp, + BRCMF_C_SET_KEY_PRIMARY, index); + if (err) +- bphy_err(wiphy, "error (%d)\n", err); ++ bphy_err(drvr, "error (%d)\n", err); + } + done: + brcmf_dbg(TRACE, "Exit\n"); +@@ -2245,7 +2259,9 @@ brcmf_cfg80211_add_key(struct wiphy *wip + u8 key_idx, bool pairwise, const u8 *mac_addr, + struct key_params *params) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_wsec_key *key; + s32 val; + s32 wsec; +@@ -2260,7 +2276,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip + + if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) { + /* we ignore this key index in this case */ +- bphy_err(wiphy, "invalid key index (%d)\n", key_idx); ++ bphy_err(drvr, "invalid key index (%d)\n", key_idx); + return -EINVAL; + } + +@@ -2269,7 +2285,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip + mac_addr); + + if (params->key_len > sizeof(key->data)) { +- bphy_err(wiphy, "Too long key length (%u)\n", params->key_len); ++ bphy_err(drvr, "Too long key length (%u)\n", params->key_len); + return -EINVAL; + } + +@@ -2323,7 +2339,7 @@ brcmf_cfg80211_add_key(struct wiphy *wip + brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n"); + break; + default: +- bphy_err(wiphy, "Invalid cipher (0x%x)\n", params->cipher); ++ bphy_err(drvr, "Invalid cipher (0x%x)\n", params->cipher); + err = -EINVAL; + goto done; + } +@@ -2334,13 +2350,13 @@ brcmf_cfg80211_add_key(struct wiphy *wip + + err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + if (err) { +- bphy_err(wiphy, "get wsec error (%d)\n", err); ++ bphy_err(drvr, "get wsec error (%d)\n", err); + goto done; + } + wsec |= val; + err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + if (err) { +- bphy_err(wiphy, "set wsec error (%d)\n", err); ++ bphy_err(drvr, "set wsec error (%d)\n", err); + goto done; + } + +@@ -2355,9 +2371,11 @@ brcmf_cfg80211_get_key(struct wiphy *wip + void (*callback)(void *cookie, + struct key_params *params)) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct key_params params; + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_cfg80211_security *sec; + s32 wsec; + s32 err = 0; +@@ -2371,7 +2389,7 @@ brcmf_cfg80211_get_key(struct wiphy *wip + + err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + if (err) { +- bphy_err(wiphy, "WLC_GET_WSEC error (%d)\n", err); ++ bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err); + /* Ignore this error, may happen during DISASSOC */ + err = -EAGAIN; + goto done; +@@ -2392,7 +2410,7 @@ brcmf_cfg80211_get_key(struct wiphy *wip + params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; + brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n"); + } else { +- bphy_err(wiphy, "Invalid algo (0x%x)\n", wsec); ++ bphy_err(drvr, "Invalid algo (0x%x)\n", wsec); + err = -EINVAL; + goto done; + } +@@ -2422,7 +2440,7 @@ brcmf_cfg80211_config_default_mgmt_key(s + static void + brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + s32 err; + u8 key_idx; + struct brcmf_wsec_key *key; +@@ -2439,18 +2457,18 @@ brcmf_cfg80211_reconfigure_wep(struct br + + err = send_key_to_dongle(ifp, key); + if (err) { +- bphy_err(wiphy, "Setting WEP key failed (%d)\n", err); ++ bphy_err(drvr, "Setting WEP key failed (%d)\n", err); + return; + } + err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec); + if (err) { +- bphy_err(wiphy, "get wsec error (%d)\n", err); ++ bphy_err(drvr, "get wsec error (%d)\n", err); + return; + } + wsec |= WEP_ENABLED; + err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + if (err) +- bphy_err(wiphy, "set wsec error (%d)\n", err); ++ bphy_err(drvr, "set wsec error (%d)\n", err); + } + + static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si) +@@ -2476,7 +2494,7 @@ static void brcmf_convert_sta_flags(u32 + + static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + struct { + __le32 len; + struct brcmf_bss_info_le bss_le; +@@ -2492,7 +2510,7 @@ static void brcmf_fill_bss_param(struct + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf, + WL_BSS_INFO_MAX); + if (err) { +- bphy_err(wiphy, "Failed to get bss info (%d)\n", err); ++ bphy_err(drvr, "Failed to get bss info (%d)\n", err); + goto out_kfree; + } + si->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM); +@@ -2514,7 +2532,7 @@ static s32 + brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp, + struct station_info *sinfo) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_scb_val_le scbval; + struct brcmf_pktcnt_le pktcnt; + s32 err; +@@ -2524,7 +2542,7 @@ brcmf_cfg80211_get_station_ibss(struct b + /* Get the current tx rate */ + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate); + if (err < 0) { +- bphy_err(wiphy, "BRCMF_C_GET_RATE error (%d)\n", err); ++ bphy_err(drvr, "BRCMF_C_GET_RATE error (%d)\n", err); + return err; + } + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE); +@@ -2534,7 +2552,7 @@ brcmf_cfg80211_get_station_ibss(struct b + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval, + sizeof(scbval)); + if (err) { +- bphy_err(wiphy, "BRCMF_C_GET_RSSI error (%d)\n", err); ++ bphy_err(drvr, "BRCMF_C_GET_RSSI error (%d)\n", err); + return err; + } + rssi = le32_to_cpu(scbval.val); +@@ -2544,7 +2562,7 @@ brcmf_cfg80211_get_station_ibss(struct b + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt, + sizeof(pktcnt)); + if (err) { +- bphy_err(wiphy, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err); ++ bphy_err(drvr, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err); + return err; + } + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS) | +@@ -2563,7 +2581,9 @@ static s32 + brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev, + const u8 *mac, struct station_info *sinfo) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_scb_val_le scb_val; + s32 err = 0; + struct brcmf_sta_info_le sta_info_le; +@@ -2592,7 +2612,7 @@ brcmf_cfg80211_get_station(struct wiphy + &sta_info_le, + sizeof(sta_info_le)); + if (err < 0) { +- bphy_err(wiphy, "GET STA INFO failed, %d\n", err); ++ bphy_err(drvr, "GET STA INFO failed, %d\n", err); + goto done; + } + } +@@ -2661,7 +2681,7 @@ brcmf_cfg80211_get_station(struct wiphy + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, + &scb_val, sizeof(scb_val)); + if (err) { +- bphy_err(wiphy, "Could not get rssi (%d)\n", ++ bphy_err(drvr, "Could not get rssi (%d)\n", + err); + goto done; + } else { +@@ -2683,6 +2703,7 @@ brcmf_cfg80211_dump_station(struct wiphy + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = cfg->pub; + s32 err; + + brcmf_dbg(TRACE, "Enter, idx %d\n", idx); +@@ -2693,7 +2714,7 @@ brcmf_cfg80211_dump_station(struct wiphy + &cfg->assoclist, + sizeof(cfg->assoclist)); + if (err) { +- bphy_err(wiphy, "BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n", ++ bphy_err(drvr, "BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n", + err); + cfg->assoclist.count = 0; + return -EOPNOTSUPP; +@@ -2714,6 +2735,7 @@ brcmf_cfg80211_set_power_mgmt(struct wip + s32 err = 0; + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = cfg->pub; + + brcmf_dbg(TRACE, "Enter\n"); + +@@ -2742,9 +2764,9 @@ brcmf_cfg80211_set_power_mgmt(struct wip + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm); + if (err) { + if (err == -ENODEV) +- bphy_err(wiphy, "net_device is not ready yet\n"); ++ bphy_err(drvr, "net_device is not ready yet\n"); + else +- bphy_err(wiphy, "error (%d)\n", err); ++ bphy_err(drvr, "error (%d)\n", err); + } + done: + brcmf_dbg(TRACE, "Exit\n"); +@@ -2755,6 +2777,7 @@ static s32 brcmf_inform_single_bss(struc + struct brcmf_bss_info_le *bi) + { + struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + struct cfg80211_bss *bss; + enum nl80211_band band; + struct brcmu_chan ch; +@@ -2767,7 +2790,7 @@ static s32 brcmf_inform_single_bss(struc + struct cfg80211_inform_bss bss_data = {}; + + if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) { +- bphy_err(wiphy, "Bss info is larger than buffer. Discarding\n"); ++ bphy_err(drvr, "Bss info is larger than buffer. Discarding\n"); + return 0; + } + +@@ -2826,7 +2849,7 @@ next_bss_le(struct brcmf_scan_results *l + + static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg) + { +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_scan_results *bss_list; + struct brcmf_bss_info_le *bi = NULL; /* must be initialized */ + s32 err = 0; +@@ -2835,7 +2858,7 @@ static s32 brcmf_inform_bss(struct brcmf + bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf; + if (bss_list->count != 0 && + bss_list->version != BRCMF_BSS_INFO_VERSION) { +- bphy_err(wiphy, "Version %d != WL_BSS_INFO_VERSION\n", ++ bphy_err(drvr, "Version %d != WL_BSS_INFO_VERSION\n", + bss_list->version); + return -EOPNOTSUPP; + } +@@ -2853,6 +2876,7 @@ static s32 brcmf_inform_ibss(struct brcm + struct net_device *ndev, const u8 *bssid) + { + struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + struct ieee80211_channel *notify_channel; + struct brcmf_bss_info_le *bi = NULL; + struct ieee80211_supported_band *band; +@@ -2880,7 +2904,7 @@ static s32 brcmf_inform_ibss(struct brcm + err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO, + buf, WL_BSS_INFO_MAX); + if (err) { +- bphy_err(wiphy, "WLC_GET_BSS_INFO failed: %d\n", err); ++ bphy_err(drvr, "WLC_GET_BSS_INFO failed: %d\n", err); + goto CleanUp; + } + +@@ -2934,7 +2958,7 @@ CleanUp: + static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg, + struct brcmf_if *ifp) + { +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_bss_info_le *bi; + const struct brcmf_tlv *tim; + u16 beacon_interval; +@@ -2951,7 +2975,7 @@ static s32 brcmf_update_bss_info(struct + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, + cfg->extra_buf, WL_EXTRA_BUF_MAX); + if (err) { +- bphy_err(wiphy, "Could not get bss info %d\n", err); ++ bphy_err(drvr, "Could not get bss info %d\n", err); + goto update_bss_info_out; + } + +@@ -2976,7 +3000,7 @@ static s32 brcmf_update_bss_info(struct + u32 var; + err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var); + if (err) { +- bphy_err(wiphy, "wl dtim_assoc failed (%d)\n", err); ++ bphy_err(drvr, "wl dtim_assoc failed (%d)\n", err); + goto update_bss_info_out; + } + dtim_period = (u8)var; +@@ -3014,10 +3038,10 @@ static void brcmf_escan_timeout(struct t + { + struct brcmf_cfg80211_info *cfg = + from_timer(cfg, t, escan_timeout); +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + + if (cfg->int_escan_map || cfg->scan_request) { +- bphy_err(wiphy, "timer expired\n"); ++ bphy_err(drvr, "timer expired\n"); + schedule_work(&cfg->escan_timeout_work); + } + } +@@ -3065,8 +3089,8 @@ static s32 + brcmf_cfg80211_escan_handler(struct brcmf_if *ifp, + const struct brcmf_event_msg *e, void *data) + { +- struct brcmf_cfg80211_info *cfg = ifp->drvr->config; +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = ifp->drvr; ++ struct brcmf_cfg80211_info *cfg = drvr->config; + s32 status; + struct brcmf_escan_result_le *escan_result_le; + u32 escan_buflen; +@@ -3083,7 +3107,7 @@ brcmf_cfg80211_escan_handler(struct brcm + goto exit; + + if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) { +- bphy_err(wiphy, "scan not ready, bsscfgidx=%d\n", ++ bphy_err(drvr, "scan not ready, bsscfgidx=%d\n", + ifp->bsscfgidx); + return -EPERM; + } +@@ -3091,24 +3115,24 @@ brcmf_cfg80211_escan_handler(struct brcm + if (status == BRCMF_E_STATUS_PARTIAL) { + brcmf_dbg(SCAN, "ESCAN Partial result\n"); + if (e->datalen < sizeof(*escan_result_le)) { +- bphy_err(wiphy, "invalid event data length\n"); ++ bphy_err(drvr, "invalid event data length\n"); + goto exit; + } + escan_result_le = (struct brcmf_escan_result_le *) data; + if (!escan_result_le) { +- bphy_err(wiphy, "Invalid escan result (NULL pointer)\n"); ++ bphy_err(drvr, "Invalid escan result (NULL pointer)\n"); + goto exit; + } + escan_buflen = le32_to_cpu(escan_result_le->buflen); + if (escan_buflen > BRCMF_ESCAN_BUF_SIZE || + escan_buflen > e->datalen || + escan_buflen < sizeof(*escan_result_le)) { +- bphy_err(wiphy, "Invalid escan buffer length: %d\n", ++ bphy_err(drvr, "Invalid escan buffer length: %d\n", + escan_buflen); + goto exit; + } + if (le16_to_cpu(escan_result_le->bss_count) != 1) { +- bphy_err(wiphy, "Invalid bss_count %d: ignoring\n", ++ bphy_err(drvr, "Invalid bss_count %d: ignoring\n", + escan_result_le->bss_count); + goto exit; + } +@@ -3124,7 +3148,7 @@ brcmf_cfg80211_escan_handler(struct brcm + + bi_length = le32_to_cpu(bss_info_le->length); + if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) { +- bphy_err(wiphy, "Ignoring invalid bss_info length: %d\n", ++ bphy_err(drvr, "Ignoring invalid bss_info length: %d\n", + bi_length); + goto exit; + } +@@ -3133,7 +3157,7 @@ brcmf_cfg80211_escan_handler(struct brcm + BIT(NL80211_IFTYPE_ADHOC))) { + if (le16_to_cpu(bss_info_le->capability) & + WLAN_CAPABILITY_IBSS) { +- bphy_err(wiphy, "Ignoring IBSS result\n"); ++ bphy_err(drvr, "Ignoring IBSS result\n"); + goto exit; + } + } +@@ -3141,7 +3165,7 @@ brcmf_cfg80211_escan_handler(struct brcm + list = (struct brcmf_scan_results *) + cfg->escan_info.escan_buf; + if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) { +- bphy_err(wiphy, "Buffer is too small: ignoring\n"); ++ bphy_err(drvr, "Buffer is too small: ignoring\n"); + goto exit; + } + +@@ -3300,7 +3324,8 @@ static s32 + brcmf_notify_sched_scan_results(struct brcmf_if *ifp, + const struct brcmf_event_msg *e, void *data) + { +- struct brcmf_cfg80211_info *cfg = ifp->drvr->config; ++ struct brcmf_pub *drvr = ifp->drvr; ++ struct brcmf_cfg80211_info *cfg = drvr->config; + struct brcmf_pno_net_info_le *netinfo, *netinfo_start; + struct cfg80211_scan_request *request = NULL; + struct wiphy *wiphy = cfg_to_wiphy(cfg); +@@ -3333,14 +3358,14 @@ brcmf_notify_sched_scan_results(struct b + WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE); + brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count); + if (!result_count) { +- bphy_err(wiphy, "FALSE PNO Event. (pfn_count == 0)\n"); ++ bphy_err(drvr, "FALSE PNO Event. (pfn_count == 0)\n"); + goto out_err; + } + + netinfo_start = brcmf_get_netinfo_array(pfn_result); + datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result); + if (datalen < result_count * sizeof(*netinfo)) { +- bphy_err(wiphy, "insufficient event data\n"); ++ bphy_err(drvr, "insufficient event data\n"); + goto out_err; + } + +@@ -3387,14 +3412,15 @@ brcmf_cfg80211_sched_scan_start(struct w + struct net_device *ndev, + struct cfg80211_sched_scan_request *req) + { +- struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = cfg->pub; + + brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n", + req->n_match_sets, req->n_ssids); + + if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) { +- bphy_err(wiphy, "Scanning suppressed: status=%lu\n", ++ bphy_err(drvr, "Scanning suppressed: status=%lu\n", + cfg->scan_status); + return -EAGAIN; + } +@@ -3473,8 +3499,8 @@ static s32 + brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e, + void *data) + { +- struct brcmf_cfg80211_info *cfg = ifp->drvr->config; +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = ifp->drvr; ++ struct brcmf_cfg80211_info *cfg = drvr->config; + struct brcmf_pno_scanresults_le *pfn_result; + struct brcmf_pno_net_info_le *netinfo; + +@@ -3493,7 +3519,7 @@ brcmf_wowl_nd_results(struct brcmf_if *i + } + + if (le32_to_cpu(pfn_result->count) < 1) { +- bphy_err(wiphy, "Invalid result count, expected 1 (%d)\n", ++ bphy_err(drvr, "Invalid result count, expected 1 (%d)\n", + le32_to_cpu(pfn_result->count)); + return -EINVAL; + } +@@ -3523,6 +3549,7 @@ brcmf_wowl_nd_results(struct brcmf_if *i + static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp) + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_wowl_wakeind_le wake_ind_le; + struct cfg80211_wowlan_wakeup wakeup_data; + struct cfg80211_wowlan_wakeup *wakeup; +@@ -3533,7 +3560,7 @@ static void brcmf_report_wowl_wakeind(st + err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le, + sizeof(wake_ind_le)); + if (err) { +- bphy_err(wiphy, "Get wowl_wakeind failed, err = %d\n", err); ++ bphy_err(drvr, "Get wowl_wakeind failed, err = %d\n", err); + return; + } + +@@ -3574,7 +3601,7 @@ static void brcmf_report_wowl_wakeind(st + cfg->wowl.nd_data_completed, + BRCMF_ND_INFO_TIMEOUT); + if (!timeout) +- bphy_err(wiphy, "No result for wowl net detect\n"); ++ bphy_err(drvr, "No result for wowl net detect\n"); + else + wakeup_data.net_detect = cfg->wowl.nd_info; + } +@@ -3763,6 +3790,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *w + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0]; ++ struct brcmf_pub *drvr = cfg->pub; + s32 err; + u32 npmk, i; + +@@ -3782,7 +3810,7 @@ brcmf_cfg80211_set_pmksa(struct wiphy *w + cfg->pmk_list.npmk = cpu_to_le32(npmk); + } + } else { +- bphy_err(wiphy, "Too many PMKSA entries cached %d\n", npmk); ++ bphy_err(drvr, "Too many PMKSA entries cached %d\n", npmk); + return -EINVAL; + } + +@@ -3805,6 +3833,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *w + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0]; ++ struct brcmf_pub *drvr = cfg->pub; + s32 err; + u32 npmk, i; + +@@ -3828,7 +3857,7 @@ brcmf_cfg80211_del_pmksa(struct wiphy *w + memset(&pmk[i], 0, sizeof(*pmk)); + cfg->pmk_list.npmk = cpu_to_le32(npmk - 1); + } else { +- bphy_err(wiphy, "Cache entry not found\n"); ++ bphy_err(drvr, "Cache entry not found\n"); + return -EINVAL; + } + +@@ -3860,20 +3889,20 @@ brcmf_cfg80211_flush_pmksa(struct wiphy + + static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + s32 err; + s32 wpa_val; + + /* set auth */ + err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0); + if (err < 0) { +- bphy_err(wiphy, "auth error %d\n", err); ++ bphy_err(drvr, "auth error %d\n", err); + return err; + } + /* set wsec */ + err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0); + if (err < 0) { +- bphy_err(wiphy, "wsec error %d\n", err); ++ bphy_err(drvr, "wsec error %d\n", err); + return err; + } + /* set upper-layer auth */ +@@ -3883,7 +3912,7 @@ static s32 brcmf_configure_opensecurity( + wpa_val = WPA_AUTH_DISABLED; + err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_val); + if (err < 0) { +- bphy_err(wiphy, "wpa_auth error %d\n", err); ++ bphy_err(drvr, "wpa_auth error %d\n", err); + return err; + } + +@@ -3903,7 +3932,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + const struct brcmf_vs_tlv *wpa_ie, + bool is_rsn_ie) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + u32 auth = 0; /* d11 open authentication */ + u16 count; + s32 err = 0; +@@ -3934,13 +3963,13 @@ brcmf_configure_wpaie(struct brcmf_if *i + /* check for multicast cipher suite */ + if (offset + WPA_IE_MIN_OUI_LEN > len) { + err = -EINVAL; +- bphy_err(wiphy, "no multicast cipher suite\n"); ++ bphy_err(drvr, "no multicast cipher suite\n"); + goto exit; + } + + if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { + err = -EINVAL; +- bphy_err(wiphy, "ivalid OUI\n"); ++ bphy_err(drvr, "ivalid OUI\n"); + goto exit; + } + offset += TLV_OUI_LEN; +@@ -3962,7 +3991,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + break; + default: + err = -EINVAL; +- bphy_err(wiphy, "Invalid multi cast cipher info\n"); ++ bphy_err(drvr, "Invalid multi cast cipher info\n"); + goto exit; + } + +@@ -3973,13 +4002,13 @@ brcmf_configure_wpaie(struct brcmf_if *i + /* Check for unicast suite(s) */ + if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) { + err = -EINVAL; +- bphy_err(wiphy, "no unicast cipher suite\n"); ++ bphy_err(drvr, "no unicast cipher suite\n"); + goto exit; + } + for (i = 0; i < count; i++) { + if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { + err = -EINVAL; +- bphy_err(wiphy, "ivalid OUI\n"); ++ bphy_err(drvr, "ivalid OUI\n"); + goto exit; + } + offset += TLV_OUI_LEN; +@@ -3997,7 +4026,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + pval |= AES_ENABLED; + break; + default: +- bphy_err(wiphy, "Invalid unicast security info\n"); ++ bphy_err(drvr, "Invalid unicast security info\n"); + } + offset++; + } +@@ -4007,13 +4036,13 @@ brcmf_configure_wpaie(struct brcmf_if *i + /* Check for auth key management suite(s) */ + if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) { + err = -EINVAL; +- bphy_err(wiphy, "no auth key mgmt suite\n"); ++ bphy_err(drvr, "no auth key mgmt suite\n"); + goto exit; + } + for (i = 0; i < count; i++) { + if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) { + err = -EINVAL; +- bphy_err(wiphy, "ivalid OUI\n"); ++ bphy_err(drvr, "ivalid OUI\n"); + goto exit; + } + offset += TLV_OUI_LEN; +@@ -4041,7 +4070,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + wpa_auth |= WPA2_AUTH_1X_SHA256; + break; + default: +- bphy_err(wiphy, "Invalid key mgmt info\n"); ++ bphy_err(drvr, "Invalid key mgmt info\n"); + } + offset++; + } +@@ -4083,7 +4112,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable", + wme_bss_disable); + if (err < 0) { +- bphy_err(wiphy, "wme_bss_disable error %d\n", err); ++ bphy_err(drvr, "wme_bss_disable error %d\n", err); + goto exit; + } + +@@ -4097,7 +4126,7 @@ brcmf_configure_wpaie(struct brcmf_if *i + &data[offset], + WPA_IE_MIN_OUI_LEN); + if (err < 0) { +- bphy_err(wiphy, "bip error %d\n", err); ++ bphy_err(drvr, "bip error %d\n", err); + goto exit; + } + } +@@ -4108,13 +4137,13 @@ brcmf_configure_wpaie(struct brcmf_if *i + /* set auth */ + err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth); + if (err < 0) { +- bphy_err(wiphy, "auth error %d\n", err); ++ bphy_err(drvr, "auth error %d\n", err); + goto exit; + } + /* set wsec */ + err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec); + if (err < 0) { +- bphy_err(wiphy, "wsec error %d\n", err); ++ bphy_err(drvr, "wsec error %d\n", err); + goto exit; + } + /* Configure MFP, this needs to go after wsec otherwise the wsec command +@@ -4123,14 +4152,14 @@ brcmf_configure_wpaie(struct brcmf_if *i + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) { + err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp); + if (err < 0) { +- bphy_err(wiphy, "mfp error %d\n", err); ++ bphy_err(drvr, "mfp error %d\n", err); + goto exit; + } + } + /* set upper-layer auth */ + err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth); + if (err < 0) { +- bphy_err(wiphy, "wpa_auth error %d\n", err); ++ bphy_err(drvr, "wpa_auth error %d\n", err); + goto exit; + } + +@@ -4216,8 +4245,8 @@ brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 + s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag, + const u8 *vndr_ie_buf, u32 vndr_ie_len) + { ++ struct brcmf_pub *drvr; + struct brcmf_if *ifp; +- struct wiphy *wiphy; + struct vif_saved_ie *saved_ie; + s32 err = 0; + u8 *iovar_ie_buf; +@@ -4238,7 +4267,7 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + if (!vif) + return -ENODEV; + ifp = vif->ifp; +- wiphy = ifp->drvr->wiphy; ++ drvr = ifp->drvr; + saved_ie = &vif->saved_ie; + + brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx, +@@ -4270,13 +4299,13 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + break; + default: + err = -EPERM; +- bphy_err(wiphy, "not suitable type\n"); ++ bphy_err(drvr, "not suitable type\n"); + goto exit; + } + + if (vndr_ie_len > mgmt_ie_buf_len) { + err = -ENOMEM; +- bphy_err(wiphy, "extra IE size too big\n"); ++ bphy_err(drvr, "extra IE size too big\n"); + goto exit; + } + +@@ -4337,7 +4366,7 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + /* verify remained buf size before copy data */ + if (remained_buf_len < (vndrie_info->vndrie.len + + VNDR_IE_VSIE_OFFSET)) { +- bphy_err(wiphy, "no space in mgmt_ie_buf: len left %d", ++ bphy_err(drvr, "no space in mgmt_ie_buf: len left %d", + remained_buf_len); + break; + } +@@ -4369,7 +4398,7 @@ s32 brcmf_vif_set_mgmt_ie(struct brcmf_c + err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf, + total_ie_buf_len); + if (err) +- bphy_err(wiphy, "vndr ie set error : %d\n", err); ++ bphy_err(drvr, "vndr ie set error : %d\n", err); + } + + exit: +@@ -4397,14 +4426,14 @@ static s32 + brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif, + struct cfg80211_beacon_data *beacon) + { +- struct wiphy *wiphy = vif->ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = vif->ifp->drvr; + s32 err; + + /* Set Beacon IEs to FW */ + err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG, + beacon->tail, beacon->tail_len); + if (err) { +- bphy_err(wiphy, "Set Beacon IE Failed\n"); ++ bphy_err(drvr, "Set Beacon IE Failed\n"); + return err; + } + brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n"); +@@ -4414,7 +4443,7 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg + beacon->proberesp_ies, + beacon->proberesp_ies_len); + if (err) +- bphy_err(wiphy, "Set Probe Resp IE Failed\n"); ++ bphy_err(drvr, "Set Probe Resp IE Failed\n"); + else + brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n"); + +@@ -4428,6 +4457,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + s32 ie_offset; + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = cfg->pub; + const struct brcmf_tlv *ssid_ie; + const struct brcmf_tlv *country_ie; + struct brcmf_ssid_le ssid_le; +@@ -4523,7 +4553,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, + is_11d); + if (err < 0) { +- bphy_err(wiphy, "Regulatory Set Error, %d\n", ++ bphy_err(drvr, "Regulatory Set Error, %d\n", + err); + goto exit; + } +@@ -4532,7 +4562,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, + settings->beacon_interval); + if (err < 0) { +- bphy_err(wiphy, "Beacon Interval Set Error, %d\n", ++ bphy_err(drvr, "Beacon Interval Set Error, %d\n", + err); + goto exit; + } +@@ -4541,7 +4571,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD, + settings->dtim_period); + if (err < 0) { +- bphy_err(wiphy, "DTIM Interval Set Error, %d\n", ++ bphy_err(drvr, "DTIM Interval Set Error, %d\n", + err); + goto exit; + } +@@ -4552,7 +4582,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) { + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); + if (err < 0) { +- bphy_err(wiphy, "BRCMF_C_DOWN error %d\n", ++ bphy_err(drvr, "BRCMF_C_DOWN error %d\n", + err); + goto exit; + } +@@ -4561,7 +4591,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1); + if (err < 0) { +- bphy_err(wiphy, "SET INFRA error %d\n", err); ++ bphy_err(drvr, "SET INFRA error %d\n", err); + goto exit; + } + } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) { +@@ -4577,7 +4607,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1); + if (err < 0) { +- bphy_err(wiphy, "setting AP mode failed %d\n", ++ bphy_err(drvr, "setting AP mode failed %d\n", + err); + goto exit; + } +@@ -4587,14 +4617,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + */ + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); + if (err < 0) { +- bphy_err(wiphy, "Set Channel failed: chspec=%d, %d\n", ++ bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n", + chanspec, err); + goto exit; + } + } + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); + if (err < 0) { +- bphy_err(wiphy, "BRCMF_C_UP error (%d)\n", err); ++ bphy_err(drvr, "BRCMF_C_UP error (%d)\n", err); + goto exit; + } + /* On DOWN the firmware removes the WEP keys, reconfigure +@@ -4609,14 +4639,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, + &join_params, sizeof(join_params)); + if (err < 0) { +- bphy_err(wiphy, "SET SSID error (%d)\n", err); ++ bphy_err(drvr, "SET SSID error (%d)\n", err); + goto exit; + } + + if (settings->hidden_ssid) { + err = brcmf_fil_iovar_int_set(ifp, "closednet", 1); + if (err) { +- bphy_err(wiphy, "closednet error (%d)\n", err); ++ bphy_err(drvr, "closednet error (%d)\n", err); + goto exit; + } + } +@@ -4625,14 +4655,14 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + } else if (dev_role == NL80211_IFTYPE_P2P_GO) { + err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec); + if (err < 0) { +- bphy_err(wiphy, "Set Channel failed: chspec=%d, %d\n", ++ bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n", + chanspec, err); + goto exit; + } + err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le, + sizeof(ssid_le)); + if (err < 0) { +- bphy_err(wiphy, "setting ssid failed %d\n", err); ++ bphy_err(drvr, "setting ssid failed %d\n", err); + goto exit; + } + bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx); +@@ -4640,7 +4670,7 @@ brcmf_cfg80211_start_ap(struct wiphy *wi + err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable, + sizeof(bss_enable)); + if (err < 0) { +- bphy_err(wiphy, "bss_enable config failed %d\n", err); ++ bphy_err(drvr, "bss_enable config failed %d\n", err); + goto exit; + } + +@@ -4663,7 +4693,9 @@ exit: + + static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(ndev); ++ struct brcmf_pub *drvr = cfg->pub; + s32 err; + struct brcmf_fil_bss_enable_le bss_enable; + struct brcmf_join_params join_params; +@@ -4688,13 +4720,13 @@ static int brcmf_cfg80211_stop_ap(struct + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID, + &join_params, sizeof(join_params)); + if (err < 0) +- bphy_err(wiphy, "SET SSID error (%d)\n", err); ++ bphy_err(drvr, "SET SSID error (%d)\n", err); + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); + if (err < 0) +- bphy_err(wiphy, "BRCMF_C_DOWN error %d\n", err); ++ bphy_err(drvr, "BRCMF_C_DOWN error %d\n", err); + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0); + if (err < 0) +- bphy_err(wiphy, "setting AP mode failed %d\n", err); ++ bphy_err(drvr, "setting AP mode failed %d\n", err); + if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) + brcmf_fil_iovar_int_set(ifp, "mbss", 0); + brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY, +@@ -4702,7 +4734,7 @@ static int brcmf_cfg80211_stop_ap(struct + /* Bring device back up so it can be used again */ + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1); + if (err < 0) +- bphy_err(wiphy, "BRCMF_C_UP error %d\n", err); ++ bphy_err(drvr, "BRCMF_C_UP error %d\n", err); + + brcmf_vif_clear_mgmt_ies(ifp->vif); + } else { +@@ -4711,7 +4743,7 @@ static int brcmf_cfg80211_stop_ap(struct + err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable, + sizeof(bss_enable)); + if (err < 0) +- bphy_err(wiphy, "bss_enable config failed %d\n", err); ++ bphy_err(drvr, "bss_enable config failed %d\n", err); + } + brcmf_set_mpc(ifp, 1); + brcmf_configure_arp_nd_offload(ifp, true); +@@ -4740,6 +4772,7 @@ brcmf_cfg80211_del_station(struct wiphy + struct station_del_parameters *params) + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_scb_val_le scbval; + struct brcmf_if *ifp = netdev_priv(ndev); + s32 err; +@@ -4759,7 +4792,7 @@ brcmf_cfg80211_del_station(struct wiphy + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON, + &scbval, sizeof(scbval)); + if (err) +- bphy_err(wiphy, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", ++ bphy_err(drvr, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", + err); + + brcmf_dbg(TRACE, "Exit\n"); +@@ -4770,6 +4803,8 @@ static int + brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev, + const u8 *mac, struct station_parameters *params) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_if *ifp = netdev_priv(ndev); + s32 err; + +@@ -4790,7 +4825,7 @@ brcmf_cfg80211_change_station(struct wip + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE, + (void *)mac, ETH_ALEN); + if (err < 0) +- bphy_err(wiphy, "Setting SCB (de-)authorize failed, %d\n", err); ++ bphy_err(drvr, "Setting SCB (de-)authorize failed, %d\n", err); + + return err; + } +@@ -4820,6 +4855,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct ieee80211_channel *chan = params->chan; ++ struct brcmf_pub *drvr = cfg->pub; + const u8 *buf = params->buf; + size_t len = params->len; + const struct ieee80211_mgmt *mgmt; +@@ -4840,7 +4876,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip + mgmt = (const struct ieee80211_mgmt *)buf; + + if (!ieee80211_is_mgmt(mgmt->frame_control)) { +- bphy_err(wiphy, "Driver only allows MGMT packet type\n"); ++ bphy_err(drvr, "Driver only allows MGMT packet type\n"); + return -EPERM; + } + +@@ -4871,13 +4907,13 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wip + GFP_KERNEL); + } else if (ieee80211_is_action(mgmt->frame_control)) { + if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) { +- bphy_err(wiphy, "invalid action frame length\n"); ++ bphy_err(drvr, "invalid action frame length\n"); + err = -EINVAL; + goto exit; + } + af_params = kzalloc(sizeof(*af_params), GFP_KERNEL); + if (af_params == NULL) { +- bphy_err(wiphy, "unable to allocate frame\n"); ++ bphy_err(drvr, "unable to allocate frame\n"); + err = -ENOMEM; + goto exit; + } +@@ -4928,6 +4964,7 @@ brcmf_cfg80211_cancel_remain_on_channel( + u64 cookie) + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_cfg80211_vif *vif; + int err = 0; + +@@ -4935,7 +4972,7 @@ brcmf_cfg80211_cancel_remain_on_channel( + + vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif; + if (vif == NULL) { +- bphy_err(wiphy, "No p2p device available for probe response\n"); ++ bphy_err(drvr, "No p2p device available for probe response\n"); + err = -ENODEV; + goto exit; + } +@@ -4950,6 +4987,7 @@ static int brcmf_cfg80211_get_channel(st + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct net_device *ndev = wdev->netdev; ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_if *ifp; + struct brcmu_chan ch; + enum nl80211_band band = 0; +@@ -4963,7 +5001,7 @@ static int brcmf_cfg80211_get_channel(st + + err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec); + if (err) { +- bphy_err(wiphy, "chanspec failed (%d)\n", err); ++ bphy_err(drvr, "chanspec failed (%d)\n", err); + return err; + } + +@@ -5085,6 +5123,8 @@ static int brcmf_cfg80211_tdls_oper(stru + struct net_device *ndev, const u8 *peer, + enum nl80211_tdls_operation oper) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_if *ifp; + struct brcmf_tdls_iovar_le info; + int ret = 0; +@@ -5102,7 +5142,7 @@ static int brcmf_cfg80211_tdls_oper(stru + ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint", + &info, sizeof(info)); + if (ret < 0) +- bphy_err(wiphy, "tdls_endpoint iovar failed: ret=%d\n", ret); ++ bphy_err(drvr, "tdls_endpoint iovar failed: ret=%d\n", ret); + + return ret; + } +@@ -5113,6 +5153,8 @@ brcmf_cfg80211_update_conn_params(struct + struct cfg80211_connect_params *sme, + u32 changed) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_if *ifp; + int err; + +@@ -5123,7 +5165,7 @@ brcmf_cfg80211_update_conn_params(struct + err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG, + sme->ie, sme->ie_len); + if (err) +- bphy_err(wiphy, "Set Assoc REQ IE Failed\n"); ++ bphy_err(drvr, "Set Assoc REQ IE Failed\n"); + else + brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n"); + +@@ -5135,6 +5177,8 @@ static int + brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev, + struct cfg80211_gtk_rekey_data *gtk) + { ++ struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_if *ifp = netdev_priv(ndev); + struct brcmf_gtk_keyinfo_le gtk_le; + int ret; +@@ -5149,7 +5193,7 @@ brcmf_cfg80211_set_rekey_data(struct wip + ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", >k_le, + sizeof(gtk_le)); + if (ret < 0) +- bphy_err(wiphy, "gtk_key_info iovar failed: ret=%d\n", ret); ++ bphy_err(drvr, "gtk_key_info iovar failed: ret=%d\n", ret); + + return ret; + } +@@ -5381,7 +5425,7 @@ static void brcmf_clear_assoc_ies(struct + static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg, + struct brcmf_if *ifp) + { +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_cfg80211_assoc_ielen_le *assoc_info; + struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg); + u32 req_len; +@@ -5393,7 +5437,7 @@ static s32 brcmf_get_assoc_ies(struct br + err = brcmf_fil_iovar_data_get(ifp, "assoc_info", + cfg->extra_buf, WL_ASSOC_INFO_MAX); + if (err) { +- bphy_err(wiphy, "could not get assoc info (%d)\n", err); ++ bphy_err(drvr, "could not get assoc info (%d)\n", err); + return err; + } + assoc_info = +@@ -5405,7 +5449,7 @@ static s32 brcmf_get_assoc_ies(struct br + cfg->extra_buf, + WL_ASSOC_INFO_MAX); + if (err) { +- bphy_err(wiphy, "could not get assoc req (%d)\n", err); ++ bphy_err(drvr, "could not get assoc req (%d)\n", err); + return err; + } + conn_info->req_ie_len = req_len; +@@ -5421,7 +5465,7 @@ static s32 brcmf_get_assoc_ies(struct br + cfg->extra_buf, + WL_ASSOC_INFO_MAX); + if (err) { +- bphy_err(wiphy, "could not get assoc resp (%d)\n", err); ++ bphy_err(drvr, "could not get assoc resp (%d)\n", err); + return err; + } + conn_info->resp_ie_len = resp_len; +@@ -5548,7 +5592,7 @@ brcmf_notify_connect_status_ap(struct br + struct net_device *ndev, + const struct brcmf_event_msg *e, void *data) + { +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + static int generation; + u32 event = e->event_code; + u32 reason = e->reason; +@@ -5566,7 +5610,7 @@ brcmf_notify_connect_status_ap(struct br + if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) && + (reason == BRCMF_E_STATUS_SUCCESS)) { + if (!data) { +- bphy_err(wiphy, "No IEs present in ASSOC/REASSOC_IND\n"); ++ bphy_err(drvr, "No IEs present in ASSOC/REASSOC_IND\n"); + return -EINVAL; + } + +@@ -5858,7 +5902,7 @@ static void init_vif_event(struct brcmf_ + + static s32 brcmf_dongle_roam(struct brcmf_if *ifp) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + s32 err; + u32 bcn_timeout; + __le32 roamtrigger[2]; +@@ -5871,7 +5915,7 @@ static s32 brcmf_dongle_roam(struct brcm + bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON; + err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout); + if (err) { +- bphy_err(wiphy, "bcn_timeout error (%d)\n", err); ++ bphy_err(drvr, "bcn_timeout error (%d)\n", err); + goto roam_setup_done; + } + +@@ -5883,7 +5927,7 @@ static s32 brcmf_dongle_roam(struct brcm + err = brcmf_fil_iovar_int_set(ifp, "roam_off", + ifp->drvr->settings->roamoff); + if (err) { +- bphy_err(wiphy, "roam_off error (%d)\n", err); ++ bphy_err(drvr, "roam_off error (%d)\n", err); + goto roam_setup_done; + } + +@@ -5892,7 +5936,7 @@ static s32 brcmf_dongle_roam(struct brcm + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER, + (void *)roamtrigger, sizeof(roamtrigger)); + if (err) { +- bphy_err(wiphy, "WLC_SET_ROAM_TRIGGER error (%d)\n", err); ++ bphy_err(drvr, "WLC_SET_ROAM_TRIGGER error (%d)\n", err); + goto roam_setup_done; + } + +@@ -5901,7 +5945,7 @@ static s32 brcmf_dongle_roam(struct brcm + err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA, + (void *)roam_delta, sizeof(roam_delta)); + if (err) { +- bphy_err(wiphy, "WLC_SET_ROAM_DELTA error (%d)\n", err); ++ bphy_err(drvr, "WLC_SET_ROAM_DELTA error (%d)\n", err); + goto roam_setup_done; + } + +@@ -5912,26 +5956,26 @@ roam_setup_done: + static s32 + brcmf_dongle_scantime(struct brcmf_if *ifp) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + s32 err = 0; + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, + BRCMF_SCAN_CHANNEL_TIME); + if (err) { +- bphy_err(wiphy, "Scan assoc time error (%d)\n", err); ++ bphy_err(drvr, "Scan assoc time error (%d)\n", err); + goto dongle_scantime_out; + } + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME, + BRCMF_SCAN_UNASSOC_TIME); + if (err) { +- bphy_err(wiphy, "Scan unassoc time error (%d)\n", err); ++ bphy_err(drvr, "Scan unassoc time error (%d)\n", err); + goto dongle_scantime_out; + } + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME, + BRCMF_SCAN_PASSIVE_TIME); + if (err) { +- bphy_err(wiphy, "Scan passive time error (%d)\n", err); ++ bphy_err(drvr, "Scan passive time error (%d)\n", err); + goto dongle_scantime_out; + } + +@@ -5964,7 +6008,8 @@ static int brcmf_construct_chaninfo(stru + u32 bw_cap[]) + { + struct wiphy *wiphy = cfg_to_wiphy(cfg); +- struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); ++ struct brcmf_pub *drvr = cfg->pub; ++ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); + struct ieee80211_supported_band *band; + struct ieee80211_channel *channel; + struct brcmf_chanspec_list *list; +@@ -5985,7 +6030,7 @@ static int brcmf_construct_chaninfo(stru + err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf, + BRCMF_DCMD_MEDLEN); + if (err) { +- bphy_err(wiphy, "get chanspecs error (%d)\n", err); ++ bphy_err(drvr, "get chanspecs error (%d)\n", err); + goto fail_pbuf; + } + +@@ -6008,7 +6053,7 @@ static int brcmf_construct_chaninfo(stru + } else if (ch.band == BRCMU_CHAN_BAND_5G) { + band = wiphy->bands[NL80211_BAND_5GHZ]; + } else { +- bphy_err(wiphy, "Invalid channel Spec. 0x%x.\n", ++ bphy_err(drvr, "Invalid channel Spec. 0x%x.\n", + ch.chspec); + continue; + } +@@ -6032,7 +6077,7 @@ static int brcmf_construct_chaninfo(stru + /* It seems firmware supports some channel we never + * considered. Something new in IEEE standard? + */ +- bphy_err(wiphy, "Ignoring unexpected firmware channel %d\n", ++ bphy_err(drvr, "Ignoring unexpected firmware channel %d\n", + ch.control_ch_num); + continue; + } +@@ -6089,8 +6134,8 @@ fail_pbuf: + + static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg) + { +- struct wiphy *wiphy = cfg_to_wiphy(cfg); +- struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); ++ struct brcmf_pub *drvr = cfg->pub; ++ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); + struct ieee80211_supported_band *band; + struct brcmf_fil_bwcap_le band_bwcap; + struct brcmf_chanspec_list *list; +@@ -6136,7 +6181,7 @@ static int brcmf_enable_bw40_2g(struct b + err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf, + BRCMF_DCMD_MEDLEN); + if (err) { +- bphy_err(wiphy, "get chanspecs error (%d)\n", err); ++ bphy_err(drvr, "get chanspecs error (%d)\n", err); + kfree(pbuf); + return err; + } +@@ -6167,7 +6212,7 @@ static int brcmf_enable_bw40_2g(struct b + + static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[]) + { +- struct wiphy *wiphy = ifp->drvr->wiphy; ++ struct brcmf_pub *drvr = ifp->drvr; + u32 band, mimo_bwcap; + int err; + +@@ -6203,7 +6248,7 @@ static void brcmf_get_bwcap(struct brcmf + bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT; + break; + default: +- bphy_err(wiphy, "invalid mimo_bw_cap value\n"); ++ bphy_err(drvr, "invalid mimo_bw_cap value\n"); + } + } + +@@ -6278,7 +6323,8 @@ static void brcmf_update_vht_cap(struct + + static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg) + { +- struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); ++ struct brcmf_pub *drvr = cfg->pub; ++ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); + struct wiphy *wiphy = cfg_to_wiphy(cfg); + u32 nmode = 0; + u32 vhtmode = 0; +@@ -6295,7 +6341,7 @@ static int brcmf_setup_wiphybands(struct + (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode); + err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode); + if (err) { +- bphy_err(wiphy, "nmode error (%d)\n", err); ++ bphy_err(drvr, "nmode error (%d)\n", err); + } else { + brcmf_get_bwcap(ifp, bw_cap); + } +@@ -6305,7 +6351,7 @@ static int brcmf_setup_wiphybands(struct + + err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain); + if (err) { +- bphy_err(wiphy, "rxchain error (%d)\n", err); ++ bphy_err(drvr, "rxchain error (%d)\n", err); + nchain = 1; + } else { + for (nchain = 0; rxchain; nchain++) +@@ -6315,7 +6361,7 @@ static int brcmf_setup_wiphybands(struct + + err = brcmf_construct_chaninfo(cfg, bw_cap); + if (err) { +- bphy_err(wiphy, "brcmf_construct_chaninfo failed (%d)\n", err); ++ bphy_err(drvr, "brcmf_construct_chaninfo failed (%d)\n", err); + return err; + } + +@@ -6522,12 +6568,13 @@ static void brcmf_wiphy_wowl_params(stru + { + #ifdef CONFIG_PM + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); ++ struct brcmf_pub *drvr = cfg->pub; + struct wiphy_wowlan_support *wowl; + + wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support), + GFP_KERNEL); + if (!wowl) { +- bphy_err(wiphy, "only support basic wowlan features\n"); ++ bphy_err(drvr, "only support basic wowlan features\n"); + wiphy->wowlan = &brcmf_wowlan_support; + return; + } +@@ -6624,7 +6671,7 @@ static int brcmf_setup_wiphy(struct wiph + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist, + sizeof(bandlist)); + if (err) { +- bphy_err(wiphy, "could not obtain band info: err=%d\n", err); ++ bphy_err(drvr, "could not obtain band info: err=%d\n", err); + return err; + } + /* first entry in bandlist is number of bands */ +@@ -6673,7 +6720,7 @@ static int brcmf_setup_wiphy(struct wiph + + static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg) + { +- struct wiphy *wiphy = cfg_to_wiphy(cfg); ++ struct brcmf_pub *drvr = cfg->pub; + struct net_device *ndev; + struct wireless_dev *wdev; + struct brcmf_if *ifp; +@@ -6711,7 +6758,7 @@ static s32 brcmf_config_dongle(struct br + + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1); + if (err) { +- bphy_err(wiphy, "failed to set frameburst mode\n"); ++ bphy_err(drvr, "failed to set frameburst mode\n"); + goto default_conf_out; + } + +@@ -6892,6 +6939,7 @@ static void brcmf_cfg80211_reg_notifier( + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_fil_country_le ccreq; + s32 err; + int i; +@@ -6903,7 +6951,7 @@ static void brcmf_cfg80211_reg_notifier( + /* ignore non-ISO3166 country codes */ + for (i = 0; i < 2; i++) + if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') { +- bphy_err(wiphy, "not an ISO3166 code (0x%02x 0x%02x)\n", ++ bphy_err(drvr, "not an ISO3166 code (0x%02x 0x%02x)\n", + req->alpha2[0], req->alpha2[1]); + return; + } +@@ -6913,7 +6961,7 @@ static void brcmf_cfg80211_reg_notifier( + + err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq)); + if (err) { +- bphy_err(wiphy, "Country code iovar returned err = %d\n", err); ++ bphy_err(drvr, "Country code iovar returned err = %d\n", err); + return; + } + +@@ -6923,7 +6971,7 @@ static void brcmf_cfg80211_reg_notifier( + + err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq)); + if (err) { +- bphy_err(wiphy, "Firmware rejected country setting\n"); ++ bphy_err(drvr, "Firmware rejected country setting\n"); + return; + } + brcmf_setup_wiphybands(cfg); +@@ -6969,13 +7017,13 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + u16 *cap = NULL; + + if (!ndev) { +- bphy_err(wiphy, "ndev is invalid\n"); ++ bphy_err(drvr, "ndev is invalid\n"); + return NULL; + } + + cfg = kzalloc(sizeof(*cfg), GFP_KERNEL); + if (!cfg) { +- bphy_err(wiphy, "Could not allocate wiphy device\n"); ++ bphy_err(drvr, "Could not allocate wiphy device\n"); + return NULL; + } + +@@ -6996,7 +7044,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + + err = wl_init_priv(cfg); + if (err) { +- bphy_err(wiphy, "Failed to init iwm_priv (%d)\n", err); ++ bphy_err(drvr, "Failed to init iwm_priv (%d)\n", err); + brcmf_free_vif(vif); + goto wiphy_out; + } +@@ -7005,7 +7053,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + /* determine d11 io type before wiphy setup */ + err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type); + if (err) { +- bphy_err(wiphy, "Failed to get D11 version (%d)\n", err); ++ bphy_err(drvr, "Failed to get D11 version (%d)\n", err); + goto priv_out; + } + cfg->d11inf.io_type = (u8)io_type; +@@ -7039,13 +7087,13 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + #endif + err = wiphy_register(wiphy); + if (err < 0) { +- bphy_err(wiphy, "Could not register wiphy device (%d)\n", err); ++ bphy_err(drvr, "Could not register wiphy device (%d)\n", err); + goto priv_out; + } + + err = brcmf_setup_wiphybands(cfg); + if (err) { +- bphy_err(wiphy, "Setting wiphy bands failed (%d)\n", err); ++ bphy_err(drvr, "Setting wiphy bands failed (%d)\n", err); + goto wiphy_unreg_out; + } + +@@ -7063,24 +7111,24 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + + err = brcmf_fweh_activate_events(ifp); + if (err) { +- bphy_err(wiphy, "FWEH activation failed (%d)\n", err); ++ bphy_err(drvr, "FWEH activation failed (%d)\n", err); + goto wiphy_unreg_out; + } + + err = brcmf_p2p_attach(cfg, p2pdev_forced); + if (err) { +- bphy_err(wiphy, "P2P initialisation failed (%d)\n", err); ++ bphy_err(drvr, "P2P initialisation failed (%d)\n", err); + goto wiphy_unreg_out; + } + err = brcmf_btcoex_attach(cfg); + if (err) { +- bphy_err(wiphy, "BT-coex initialisation failed (%d)\n", err); ++ bphy_err(drvr, "BT-coex initialisation failed (%d)\n", err); + brcmf_p2p_detach(&cfg->p2p); + goto wiphy_unreg_out; + } + err = brcmf_pno_attach(cfg); + if (err) { +- bphy_err(wiphy, "PNO initialisation failed (%d)\n", err); ++ bphy_err(drvr, "PNO initialisation failed (%d)\n", err); + brcmf_btcoex_detach(cfg); + brcmf_p2p_detach(&cfg->p2p); + goto wiphy_unreg_out; +@@ -7100,7 +7148,7 @@ struct brcmf_cfg80211_info *brcmf_cfg802 + /* (re-) activate FWEH event handling */ + err = brcmf_fweh_activate_events(ifp); + if (err) { +- bphy_err(wiphy, "FWEH activation failed (%d)\n", err); ++ bphy_err(drvr, "FWEH activation failed (%d)\n", err); + goto detach; + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/debug.h +@@ -62,12 +62,12 @@ void __brcmf_err(struct brcmf_bus *bus, + } while (0) + #endif + +-#define bphy_err(wiphy, fmt, ...) \ ++#define bphy_err(drvr, fmt, ...) \ + do { \ + if (IS_ENABLED(CPTCFG_BRCMDBG) || \ + IS_ENABLED(CPTCFG_BRCM_TRACING) || \ + net_ratelimit()) \ +- wiphy_err(wiphy, "%s: " fmt, __func__, \ ++ wiphy_err((drvr)->wiphy, "%s: " fmt, __func__, \ + ##__VA_ARGS__); \ + } while (0) + diff --git a/package/kernel/mac80211/patches/brcm/353-v5.1-brcmfmac-remove-set-but-not-used-variable-old_state.patch b/package/kernel/mac80211/patches/brcm/353-v5.1-brcmfmac-remove-set-but-not-used-variable-old_state.patch new file mode 100644 index 0000000000..2a46378e73 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/353-v5.1-brcmfmac-remove-set-but-not-used-variable-old_state.patch @@ -0,0 +1,38 @@ +From e4d1b2716b8859199c28f2ac5f984bd05a146a6b Mon Sep 17 00:00:00 2001 +From: YueHaibing +Date: Mon, 18 Feb 2019 08:08:46 +0000 +Subject: [PATCH] brcmfmac: remove set but not used variable 'old_state' + +Fixes gcc '-Wunused-but-set-variable' warning: + +drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c: In function 'brcmf_usb_state_change': +drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c:578:6: warning: + variable 'old_state' set but not used [-Wunused-but-set-variable] + +It's never used and can be removed. + +Signed-off-by: YueHaibing +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -575,7 +575,6 @@ static void + brcmf_usb_state_change(struct brcmf_usbdev_info *devinfo, int state) + { + struct brcmf_bus *bcmf_bus = devinfo->bus_pub.bus; +- int old_state; + + brcmf_dbg(USB, "Enter, current state=%d, new state=%d\n", + devinfo->bus_pub.state, state); +@@ -583,7 +582,6 @@ brcmf_usb_state_change(struct brcmf_usbd + if (devinfo->bus_pub.state == state) + return; + +- old_state = devinfo->bus_pub.state; + devinfo->bus_pub.state = state; + + /* update state of upper layer */ diff --git a/package/kernel/mac80211/patches/brcm/354-v5.1-brcmfmac-use-bphy_err-in-all-wiphy-related-code.patch b/package/kernel/mac80211/patches/brcm/354-v5.1-brcmfmac-use-bphy_err-in-all-wiphy-related-code.patch new file mode 100644 index 0000000000..5836f6ab87 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/354-v5.1-brcmfmac-use-bphy_err-in-all-wiphy-related-code.patch @@ -0,0 +1,1707 @@ +From dcb1471bc6d0541d636c7ecd9239573304842884 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 19 Feb 2019 23:42:19 +0100 +Subject: [PATCH] brcmfmac: use bphy_err() in all wiphy-related code +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This recently added macro provides more meaningful error messages thanks +to identifying a specific wiphy. It's especially important on systems +with few cards supported by the same (brcmfmac) driver. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/bcdc.c | 22 ++--- + .../broadcom/brcm80211/brcmfmac/common.c | 39 ++++---- + .../broadcom/brcm80211/brcmfmac/core.c | 74 ++++++++-------- + .../broadcom/brcm80211/brcmfmac/feature.c | 8 +- + .../broadcom/brcm80211/brcmfmac/fweh.c | 25 +++--- + .../broadcom/brcm80211/brcmfmac/fwil.c | 10 +-- + .../broadcom/brcm80211/brcmfmac/fwsignal.c | 38 ++++---- + .../broadcom/brcm80211/brcmfmac/msgbuf.c | 65 ++++++++------ + .../broadcom/brcm80211/brcmfmac/p2p.c | 88 +++++++++++-------- + .../broadcom/brcm80211/brcmfmac/pno.c | 22 +++-- + .../broadcom/brcm80211/brcmfmac/proto.c | 6 +- + 11 files changed, 224 insertions(+), 173 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +@@ -178,8 +178,8 @@ brcmf_proto_bcdc_query_dcmd(struct brcmf + *fwerr = 0; + ret = brcmf_proto_bcdc_msg(drvr, ifidx, cmd, buf, len, false); + if (ret < 0) { +- brcmf_err("brcmf_proto_bcdc_msg failed w/status %d\n", +- ret); ++ bphy_err(drvr, "brcmf_proto_bcdc_msg failed w/status %d\n", ++ ret); + goto done; + } + +@@ -195,9 +195,9 @@ retry: + if ((id < bcdc->reqid) && (++retries < RETRIES)) + goto retry; + if (id != bcdc->reqid) { +- brcmf_err("%s: unexpected request id %d (expected %d)\n", +- brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id, +- bcdc->reqid); ++ bphy_err(drvr, "%s: unexpected request id %d (expected %d)\n", ++ brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id, ++ bcdc->reqid); + ret = -EINVAL; + goto done; + } +@@ -245,9 +245,9 @@ brcmf_proto_bcdc_set_dcmd(struct brcmf_p + id = (flags & BCDC_DCMD_ID_MASK) >> BCDC_DCMD_ID_SHIFT; + + if (id != bcdc->reqid) { +- brcmf_err("%s: unexpected request id %d (expected %d)\n", +- brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id, +- bcdc->reqid); ++ bphy_err(drvr, "%s: unexpected request id %d (expected %d)\n", ++ brcmf_ifname(brcmf_get_ifp(drvr, ifidx)), id, ++ bcdc->reqid); + ret = -EINVAL; + goto done; + } +@@ -312,8 +312,8 @@ brcmf_proto_bcdc_hdrpull(struct brcmf_pu + } + if (((h->flags & BCDC_FLAG_VER_MASK) >> BCDC_FLAG_VER_SHIFT) != + BCDC_PROTO_VER) { +- brcmf_err("%s: non-BCDC packet received, flags 0x%x\n", +- brcmf_ifname(tmp_if), h->flags); ++ bphy_err(drvr, "%s: non-BCDC packet received, flags 0x%x\n", ++ brcmf_ifname(tmp_if), h->flags); + return -EBADE; + } + +@@ -460,7 +460,7 @@ int brcmf_proto_bcdc_attach(struct brcmf + + /* ensure that the msg buf directly follows the cdc msg struct */ + if ((unsigned long)(&bcdc->msg + 1) != (unsigned long)bcdc->buf) { +- brcmf_err("struct brcmf_proto_bcdc is not correctly defined\n"); ++ bphy_err(drvr, "struct brcmf_proto_bcdc is not correctly defined\n"); + goto fail; + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +@@ -90,6 +90,7 @@ struct brcmf_mp_global_t brcmf_mp_global + + void brcmf_c_set_joinpref_default(struct brcmf_if *ifp) + { ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_join_pref_params join_pref_params[2]; + int err; + +@@ -106,7 +107,7 @@ void brcmf_c_set_joinpref_default(struct + err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params, + sizeof(join_pref_params)); + if (err) +- brcmf_err("Set join_pref error (%d)\n", err); ++ bphy_err(drvr, "Set join_pref error (%d)\n", err); + } + + static int brcmf_c_download(struct brcmf_if *ifp, u16 flag, +@@ -129,7 +130,8 @@ static int brcmf_c_download(struct brcmf + + static int brcmf_c_process_clm_blob(struct brcmf_if *ifp) + { +- struct brcmf_bus *bus = ifp->drvr->bus_if; ++ struct brcmf_pub *drvr = ifp->drvr; ++ struct brcmf_bus *bus = drvr->bus_if; + struct brcmf_dload_data_le *chunk_buf; + const struct firmware *clm = NULL; + u8 clm_name[BRCMF_FW_NAME_LEN]; +@@ -145,7 +147,7 @@ static int brcmf_c_process_clm_blob(stru + memset(clm_name, 0, sizeof(clm_name)); + err = brcmf_bus_get_fwname(bus, ".clm_blob", clm_name); + if (err) { +- brcmf_err("get CLM blob file name failed (%d)\n", err); ++ bphy_err(drvr, "get CLM blob file name failed (%d)\n", err); + return err; + } + +@@ -182,12 +184,12 @@ static int brcmf_c_process_clm_blob(stru + } while ((datalen > 0) && (err == 0)); + + if (err) { +- brcmf_err("clmload (%zu byte file) failed (%d); ", +- clm->size, err); ++ bphy_err(drvr, "clmload (%zu byte file) failed (%d)\n", ++ clm->size, err); + /* Retrieve clmload_status and print */ + err = brcmf_fil_iovar_int_get(ifp, "clmload_status", &status); + if (err) +- brcmf_err("get clmload_status failed (%d)\n", err); ++ bphy_err(drvr, "get clmload_status failed (%d)\n", err); + else + brcmf_dbg(INFO, "clmload_status=%d\n", status); + err = -EIO; +@@ -201,6 +203,7 @@ done: + + int brcmf_c_preinit_dcmds(struct brcmf_if *ifp) + { ++ struct brcmf_pub *drvr = ifp->drvr; + s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + u8 buf[BRCMF_DCMD_SMLEN]; + struct brcmf_bus *bus; +@@ -214,7 +217,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("Retrieving cur_etheraddr failed, %d\n", err); ++ bphy_err(drvr, "Retrieving cur_etheraddr failed, %d\n", err); + goto done; + } + memcpy(ifp->drvr->wiphy->perm_addr, ifp->drvr->mac, ETH_ALEN); +@@ -226,7 +229,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_REVINFO, + &revinfo, sizeof(revinfo)); + if (err < 0) { +- brcmf_err("retrieving revision info failed, %d\n", err); ++ bphy_err(drvr, "retrieving revision info failed, %d\n", err); + strlcpy(ri->chipname, "UNKNOWN", sizeof(ri->chipname)); + } else { + ri->vendorid = le32_to_cpu(revinfo.vendorid); +@@ -260,7 +263,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + /* Do any CLM downloading */ + err = brcmf_c_process_clm_blob(ifp); + if (err < 0) { +- brcmf_err("download CLM blob file failed, %d\n", err); ++ bphy_err(drvr, "download CLM blob file failed, %d\n", err); + goto done; + } + +@@ -269,8 +272,8 @@ 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("Retrieving version information failed, %d\n", +- err); ++ bphy_err(drvr, "Retrieving version information failed, %d\n", ++ err); + goto done; + } + ptr = (char *)buf; +@@ -304,7 +307,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + /* set mpc */ + err = brcmf_fil_iovar_int_set(ifp, "mpc", 1); + if (err) { +- brcmf_err("failed setting mpc\n"); ++ bphy_err(drvr, "failed setting mpc\n"); + goto done; + } + +@@ -314,14 +317,14 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask, + BRCMF_EVENTING_MASK_LEN); + if (err) { +- brcmf_err("Get event_msgs error (%d)\n", err); ++ bphy_err(drvr, "Get event_msgs error (%d)\n", err); + goto done; + } + setbit(eventmask, BRCMF_E_IF); + err = brcmf_fil_iovar_data_set(ifp, "event_msgs", eventmask, + BRCMF_EVENTING_MASK_LEN); + if (err) { +- brcmf_err("Set event_msgs error (%d)\n", err); ++ bphy_err(drvr, "Set event_msgs error (%d)\n", err); + goto done; + } + +@@ -329,8 +332,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME, + BRCMF_DEFAULT_SCAN_CHANNEL_TIME); + if (err) { +- brcmf_err("BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n", +- err); ++ bphy_err(drvr, "BRCMF_C_SET_SCAN_CHANNEL_TIME error (%d)\n", ++ err); + goto done; + } + +@@ -338,8 +341,8 @@ int brcmf_c_preinit_dcmds(struct brcmf_i + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME, + BRCMF_DEFAULT_SCAN_UNASSOC_TIME); + if (err) { +- brcmf_err("BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n", +- err); ++ bphy_err(drvr, "BRCMF_C_SET_SCAN_UNASSOC_TIME error (%d)\n", ++ err); + goto done; + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -90,7 +90,7 @@ struct brcmf_if *brcmf_get_ifp(struct br + s32 bsscfgidx; + + if (ifidx < 0 || ifidx >= BRCMF_MAX_IFS) { +- brcmf_err("ifidx %d out of range\n", ifidx); ++ bphy_err(drvr, "ifidx %d out of range\n", ifidx); + return NULL; + } + +@@ -141,7 +141,9 @@ void brcmf_configure_arp_nd_offload(stru + + static void _brcmf_set_multicast_list(struct work_struct *work) + { +- struct brcmf_if *ifp; ++ struct brcmf_if *ifp = container_of(work, struct brcmf_if, ++ multicast_work); ++ struct brcmf_pub *drvr = ifp->drvr; + struct net_device *ndev; + struct netdev_hw_addr *ha; + u32 cmd_value, cnt; +@@ -150,8 +152,6 @@ static void _brcmf_set_multicast_list(st + u32 buflen; + s32 err; + +- ifp = container_of(work, struct brcmf_if, multicast_work); +- + brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); + + ndev = ifp->ndev; +@@ -181,7 +181,7 @@ static void _brcmf_set_multicast_list(st + + err = brcmf_fil_iovar_data_set(ifp, "mcast_list", buf, buflen); + if (err < 0) { +- brcmf_err("Setting mcast_list failed, %d\n", err); ++ bphy_err(drvr, "Setting mcast_list failed, %d\n", err); + cmd_value = cnt ? true : cmd_value; + } + +@@ -194,25 +194,25 @@ static void _brcmf_set_multicast_list(st + */ + err = brcmf_fil_iovar_int_set(ifp, "allmulti", cmd_value); + if (err < 0) +- brcmf_err("Setting allmulti failed, %d\n", err); ++ bphy_err(drvr, "Setting allmulti failed, %d\n", err); + + /*Finally, pick up the PROMISC flag */ + cmd_value = (ndev->flags & IFF_PROMISC) ? true : false; + err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PROMISC, cmd_value); + if (err < 0) +- brcmf_err("Setting BRCMF_C_SET_PROMISC failed, %d\n", +- err); ++ bphy_err(drvr, "Setting BRCMF_C_SET_PROMISC failed, %d\n", ++ err); + brcmf_configure_arp_nd_offload(ifp, !cmd_value); + } + + #if IS_ENABLED(CONFIG_IPV6) + static void _brcmf_update_ndtable(struct work_struct *work) + { +- struct brcmf_if *ifp; ++ struct brcmf_if *ifp = container_of(work, struct brcmf_if, ++ ndoffload_work); ++ struct brcmf_pub *drvr = ifp->drvr; + int i, ret; + +- ifp = container_of(work, struct brcmf_if, ndoffload_work); +- + /* clear the table in firmware */ + ret = brcmf_fil_iovar_data_set(ifp, "nd_hostip_clear", NULL, 0); + if (ret) { +@@ -225,7 +225,7 @@ static void _brcmf_update_ndtable(struct + &ifp->ipv6_addr_tbl[i], + sizeof(struct in6_addr)); + if (ret) +- brcmf_err("add nd ip err %d\n", ret); ++ bphy_err(drvr, "add nd ip err %d\n", ret); + } + } + #else +@@ -238,6 +238,7 @@ static int brcmf_netdev_set_mac_address( + { + struct brcmf_if *ifp = netdev_priv(ndev); + struct sockaddr *sa = (struct sockaddr *)addr; ++ struct brcmf_pub *drvr = ifp->drvr; + int err; + + brcmf_dbg(TRACE, "Enter, bsscfgidx=%d\n", ifp->bsscfgidx); +@@ -245,7 +246,7 @@ static int brcmf_netdev_set_mac_address( + err = brcmf_fil_iovar_data_set(ifp, "cur_etheraddr", sa->sa_data, + ETH_ALEN); + if (err < 0) { +- brcmf_err("Setting cur_etheraddr failed, %d\n", err); ++ bphy_err(drvr, "Setting cur_etheraddr failed, %d\n", err); + } else { + brcmf_dbg(TRACE, "updated to %pM\n", sa->sa_data); + memcpy(ifp->mac_addr, sa->sa_data, ETH_ALEN); +@@ -305,7 +306,7 @@ static netdev_tx_t brcmf_netdev_start_xm + + /* Can the device send data? */ + if (drvr->bus_if->state != BRCMF_BUS_UP) { +- brcmf_err("xmit rejected state=%d\n", drvr->bus_if->state); ++ bphy_err(drvr, "xmit rejected state=%d\n", drvr->bus_if->state); + netif_stop_queue(ndev); + dev_kfree_skb(skb); + ret = -ENODEV; +@@ -339,8 +340,8 @@ static netdev_tx_t brcmf_netdev_start_xm + ret = pskb_expand_head(skb, ALIGN(head_delta, NET_SKB_PAD), 0, + GFP_ATOMIC); + if (ret < 0) { +- brcmf_err("%s: failed to expand headroom\n", +- brcmf_ifname(ifp)); ++ bphy_err(drvr, "%s: failed to expand headroom\n", ++ brcmf_ifname(ifp)); + atomic_inc(&drvr->bus_if->stats.pktcow_failed); + goto done; + } +@@ -607,7 +608,7 @@ static int brcmf_netdev_open(struct net_ + + /* If bus is not ready, can't continue */ + if (bus_if->state != BRCMF_BUS_UP) { +- brcmf_err("failed bus is not ready\n"); ++ bphy_err(drvr, "failed bus is not ready\n"); + return -EAGAIN; + } + +@@ -621,7 +622,7 @@ static int brcmf_netdev_open(struct net_ + ndev->features &= ~NETIF_F_IP_CSUM; + + if (brcmf_cfg80211_up(ndev)) { +- brcmf_err("failed to bring up cfg80211\n"); ++ bphy_err(drvr, "failed to bring up cfg80211\n"); + return -EIO; + } + +@@ -683,7 +684,7 @@ int brcmf_net_attach(struct brcmf_if *if + else + err = register_netdev(ndev); + if (err != 0) { +- brcmf_err("couldn't register the net device\n"); ++ bphy_err(drvr, "couldn't register the net device\n"); + goto fail; + } + +@@ -760,6 +761,7 @@ static const struct net_device_ops brcmf + + static int brcmf_net_p2p_attach(struct brcmf_if *ifp) + { ++ struct brcmf_pub *drvr = ifp->drvr; + struct net_device *ndev; + + brcmf_dbg(TRACE, "Enter, bsscfgidx=%d mac=%pM\n", ifp->bsscfgidx, +@@ -772,7 +774,7 @@ static int brcmf_net_p2p_attach(struct b + memcpy(ndev->dev_addr, ifp->mac_addr, ETH_ALEN); + + if (register_netdev(ndev) != 0) { +- brcmf_err("couldn't register the p2p net device\n"); ++ bphy_err(drvr, "couldn't register the p2p net device\n"); + goto fail; + } + +@@ -801,8 +803,8 @@ struct brcmf_if *brcmf_add_if(struct brc + */ + if (ifp) { + if (ifidx) { +- brcmf_err("ERROR: netdev:%s already exists\n", +- ifp->ndev->name); ++ bphy_err(drvr, "ERROR: netdev:%s already exists\n", ++ ifp->ndev->name); + netif_stop_queue(ifp->ndev); + brcmf_net_detach(ifp->ndev, false); + drvr->iflist[bsscfgidx] = NULL; +@@ -864,7 +866,7 @@ static void brcmf_del_if(struct brcmf_pu + ifp = drvr->iflist[bsscfgidx]; + drvr->iflist[bsscfgidx] = NULL; + if (!ifp) { +- brcmf_err("Null interface, bsscfgidx=%d\n", bsscfgidx); ++ bphy_err(drvr, "Null interface, bsscfgidx=%d\n", bsscfgidx); + return; + } + brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx, +@@ -914,16 +916,17 @@ static int brcmf_psm_watchdog_notify(str + const struct brcmf_event_msg *evtmsg, + void *data) + { ++ struct brcmf_pub *drvr = ifp->drvr; + int err; + + brcmf_dbg(TRACE, "enter: bsscfgidx=%d\n", ifp->bsscfgidx); + +- brcmf_err("PSM's watchdog has fired!\n"); ++ bphy_err(drvr, "PSM's watchdog has fired!\n"); + + err = brcmf_debug_create_memdump(ifp->drvr->bus_if, data, + evtmsg->datalen); + if (err) +- brcmf_err("Failed to get memory dump, %d\n", err); ++ bphy_err(drvr, "Failed to get memory dump, %d\n", err); + + return err; + } +@@ -967,7 +970,7 @@ static int brcmf_inetaddr_changed(struct + ret = brcmf_fil_iovar_data_get(ifp, "arp_hostip", addr_table, + sizeof(addr_table)); + if (ret) { +- brcmf_err("fail to get arp ip table err:%d\n", ret); ++ bphy_err(drvr, "fail to get arp ip table err:%d\n", ret); + return NOTIFY_OK; + } + +@@ -984,7 +987,7 @@ static int brcmf_inetaddr_changed(struct + ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip", + &ifa->ifa_address, sizeof(ifa->ifa_address)); + if (ret) +- brcmf_err("add arp ip err %d\n", ret); ++ bphy_err(drvr, "add arp ip err %d\n", ret); + } + break; + case NETDEV_DOWN: +@@ -996,8 +999,8 @@ static int brcmf_inetaddr_changed(struct + ret = brcmf_fil_iovar_data_set(ifp, "arp_hostip_clear", + NULL, 0); + if (ret) { +- brcmf_err("fail to clear arp ip table err:%d\n", +- ret); ++ bphy_err(drvr, "fail to clear arp ip table err:%d\n", ++ ret); + return NOTIFY_OK; + } + for (i = 0; i < ARPOL_MAX_ENTRIES; i++) { +@@ -1007,8 +1010,8 @@ static int brcmf_inetaddr_changed(struct + &addr_table[i], + sizeof(addr_table[i])); + if (ret) +- brcmf_err("add arp ip err %d\n", +- ret); ++ bphy_err(drvr, "add arp ip err %d\n", ++ ret); + } + } + break; +@@ -1182,7 +1185,7 @@ static int brcmf_bus_started(struct brcm + return 0; + + fail: +- brcmf_err("failed: %d\n", ret); ++ bphy_err(drvr, "failed: %d\n", ret); + if (drvr->config) { + brcmf_cfg80211_detach(drvr->config); + drvr->config = NULL; +@@ -1234,7 +1237,7 @@ int brcmf_attach(struct device *dev, str + /* Attach and link in the protocol */ + ret = brcmf_proto_attach(drvr); + if (ret != 0) { +- brcmf_err("brcmf_prot_attach failed\n"); ++ bphy_err(drvr, "brcmf_prot_attach failed\n"); + goto fail; + } + +@@ -1247,7 +1250,7 @@ int brcmf_attach(struct device *dev, str + + ret = brcmf_bus_started(drvr, ops); + if (ret != 0) { +- brcmf_err("dongle is not responding: err=%d\n", ret); ++ bphy_err(drvr, "dongle is not responding: err=%d\n", ret); + goto fail; + } + +@@ -1347,6 +1350,7 @@ static int brcmf_get_pend_8021x_cnt(stru + + int brcmf_netdev_wait_pend8021x(struct brcmf_if *ifp) + { ++ struct brcmf_pub *drvr = ifp->drvr; + int err; + + err = wait_event_timeout(ifp->pend_8021x_wait, +@@ -1354,7 +1358,7 @@ int brcmf_netdev_wait_pend8021x(struct b + MAX_WAIT_FOR_8021X_TX); + + if (!err) +- brcmf_err("Timed out waiting for no pending 802.1x packets\n"); ++ bphy_err(drvr, "Timed out waiting for no pending 802.1x packets\n"); + + return !err; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/feature.c +@@ -185,13 +185,14 @@ static void brcmf_feat_iovar_data_set(st + #define MAX_CAPS_BUFFER_SIZE 768 + static void brcmf_feat_firmware_capabilities(struct brcmf_if *ifp) + { ++ struct brcmf_pub *drvr = ifp->drvr; + char caps[MAX_CAPS_BUFFER_SIZE]; + enum brcmf_feat_id id; + int i, err; + + err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); + if (err) { +- brcmf_err("could not get firmware cap (%d)\n", err); ++ bphy_err(drvr, "could not get firmware cap (%d)\n", err); + return; + } + +@@ -216,14 +217,15 @@ static void brcmf_feat_firmware_capabili + static int brcmf_feat_fwcap_debugfs_read(struct seq_file *seq, void *data) + { + struct brcmf_bus *bus_if = dev_get_drvdata(seq->private); +- struct brcmf_if *ifp = brcmf_get_ifp(bus_if->drvr, 0); ++ struct brcmf_pub *drvr = bus_if->drvr; ++ struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0); + char caps[MAX_CAPS_BUFFER_SIZE + 1] = { }; + char *tmp; + int err; + + err = brcmf_fil_iovar_data_get(ifp, "cap", caps, sizeof(caps)); + if (err) { +- brcmf_err("could not get firmware cap (%d)\n", err); ++ bphy_err(drvr, "could not get firmware cap (%d)\n", err); + return err; + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fweh.c +@@ -102,7 +102,8 @@ static void brcmf_fweh_queue_event(struc + schedule_work(&fweh->event_work); + } + +-static int brcmf_fweh_call_event_handler(struct brcmf_if *ifp, ++static int brcmf_fweh_call_event_handler(struct brcmf_pub *drvr, ++ struct brcmf_if *ifp, + enum brcmf_fweh_event_code code, + struct brcmf_event_msg *emsg, + void *data) +@@ -117,9 +118,9 @@ static int brcmf_fweh_call_event_handler + if (fweh->evt_handler[code]) + err = fweh->evt_handler[code](ifp, emsg, data); + else +- brcmf_err("unhandled event %d ignored\n", code); ++ bphy_err(drvr, "unhandled event %d ignored\n", code); + } else { +- brcmf_err("no interface object\n"); ++ bphy_err(drvr, "no interface object\n"); + } + return err; + } +@@ -158,7 +159,7 @@ static void brcmf_fweh_handle_if_event(s + return; + } + if (ifevent->ifidx >= BRCMF_MAX_IFS) { +- brcmf_err("invalid interface index: %u\n", ifevent->ifidx); ++ bphy_err(drvr, "invalid interface index: %u\n", ifevent->ifidx); + return; + } + +@@ -181,7 +182,8 @@ static void brcmf_fweh_handle_if_event(s + if (ifp && ifevent->action == BRCMF_E_IF_CHANGE) + brcmf_proto_reset_if(drvr, ifp); + +- err = brcmf_fweh_call_event_handler(ifp, emsg->event_code, emsg, data); ++ err = brcmf_fweh_call_event_handler(drvr, ifp, emsg->event_code, emsg, ++ data); + + if (ifp && ifevent->action == BRCMF_E_IF_DEL) { + bool armed = brcmf_cfg80211_vif_event_armed(drvr->config); +@@ -268,11 +270,11 @@ static void brcmf_fweh_event_worker(stru + ifp = drvr->iflist[0]; + else + ifp = drvr->iflist[emsg.bsscfgidx]; +- err = brcmf_fweh_call_event_handler(ifp, event->code, &emsg, +- event->data); ++ err = brcmf_fweh_call_event_handler(drvr, ifp, event->code, ++ &emsg, event->data); + if (err) { +- brcmf_err("event handler failed (%d)\n", +- event->code); ++ bphy_err(drvr, "event handler failed (%d)\n", ++ event->code); + err = 0; + } + event_free: +@@ -339,7 +341,7 @@ int brcmf_fweh_register(struct brcmf_pub + brcmf_fweh_handler_t handler) + { + if (drvr->fweh.evt_handler[code]) { +- brcmf_err("event code %d already registered\n", code); ++ bphy_err(drvr, "event code %d already registered\n", code); + return -ENOSPC; + } + drvr->fweh.evt_handler[code] = handler; +@@ -369,6 +371,7 @@ void brcmf_fweh_unregister(struct brcmf_ + */ + int brcmf_fweh_activate_events(struct brcmf_if *ifp) + { ++ struct brcmf_pub *drvr = ifp->drvr; + int i, err; + s8 eventmask[BRCMF_EVENTING_MASK_LEN]; + +@@ -388,7 +391,7 @@ int brcmf_fweh_activate_events(struct br + err = brcmf_fil_iovar_data_set(ifp, "event_msgs", + eventmask, BRCMF_EVENTING_MASK_LEN); + if (err) +- brcmf_err("Set event_msgs error (%d)\n", err); ++ bphy_err(drvr, "Set event_msgs error (%d)\n", err); + + return err; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwil.c +@@ -110,7 +110,7 @@ brcmf_fil_cmd_data(struct brcmf_if *ifp, + s32 err, fwerr; + + if (drvr->bus_if->state != BRCMF_BUS_UP) { +- brcmf_err("bus is down. we have nothing to do.\n"); ++ bphy_err(drvr, "bus is down. we have nothing to do.\n"); + return -EIO; + } + +@@ -242,7 +242,7 @@ brcmf_fil_iovar_data_set(struct brcmf_if + buflen, true); + } else { + err = -EPERM; +- brcmf_err("Creating iovar failed\n"); ++ bphy_err(drvr, "Creating iovar failed\n"); + } + + mutex_unlock(&drvr->proto_block); +@@ -268,7 +268,7 @@ brcmf_fil_iovar_data_get(struct brcmf_if + memcpy(data, drvr->proto_buf, len); + } else { + err = -EPERM; +- brcmf_err("Creating iovar failed\n"); ++ bphy_err(drvr, "Creating iovar failed\n"); + } + + brcmf_dbg(FIL, "ifidx=%d, name=%s, len=%d\n", ifp->ifidx, name, len); +@@ -366,7 +366,7 @@ brcmf_fil_bsscfg_data_set(struct brcmf_i + buflen, true); + } else { + err = -EPERM; +- brcmf_err("Creating bsscfg failed\n"); ++ bphy_err(drvr, "Creating bsscfg failed\n"); + } + + mutex_unlock(&drvr->proto_block); +@@ -392,7 +392,7 @@ brcmf_fil_bsscfg_data_get(struct brcmf_i + memcpy(data, drvr->proto_buf, len); + } else { + err = -EPERM; +- brcmf_err("Creating bsscfg failed\n"); ++ bphy_err(drvr, "Creating bsscfg failed\n"); + } + brcmf_dbg(FIL, "ifidx=%d, bsscfgidx=%d, name=%s, len=%d\n", ifp->ifidx, + ifp->bsscfgidx, name, len); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -1255,6 +1255,7 @@ static int brcmf_fws_enq(struct brcmf_fw + enum brcmf_fws_skb_state state, int fifo, + struct sk_buff *p) + { ++ struct brcmf_pub *drvr = fws->drvr; + int prec = 2 * fifo; + u32 *qfull_stat = &fws->stats.delayq_full_error; + struct brcmf_fws_mac_descriptor *entry; +@@ -1267,7 +1268,7 @@ static int brcmf_fws_enq(struct brcmf_fw + + entry = brcmf_skbcb(p)->mac; + if (entry == NULL) { +- brcmf_err("no mac descriptor found for skb %p\n", p); ++ bphy_err(drvr, "no mac descriptor found for skb %p\n", p); + return -ENOENT; + } + +@@ -1457,6 +1458,7 @@ static int + brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot, + u32 genbit, u16 seq, u8 compcnt) + { ++ struct brcmf_pub *drvr = fws->drvr; + u32 fifo; + u8 cnt = 0; + int ret; +@@ -1481,14 +1483,14 @@ brcmf_fws_txs_process(struct brcmf_fws_i + else if (flags == BRCMF_FWS_TXSTATUS_HOST_TOSSED) + fws->stats.txs_host_tossed += compcnt; + else +- brcmf_err("unexpected txstatus\n"); ++ bphy_err(drvr, "unexpected txstatus\n"); + + 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); ++ bphy_err(drvr, "no packet in hanger slot: hslot=%d\n", ++ hslot); + goto cont; + } + +@@ -1612,12 +1614,13 @@ static int brcmf_fws_notify_credit_map(s + const struct brcmf_event_msg *e, + void *data) + { +- struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr); ++ struct brcmf_pub *drvr = ifp->drvr; ++ struct brcmf_fws_info *fws = drvr_to_fws(drvr); + int i; + u8 *credits = data; + + if (e->datalen < BRCMF_FWS_FIFO_COUNT) { +- brcmf_err("event payload too small (%d)\n", e->datalen); ++ bphy_err(drvr, "event payload too small (%d)\n", e->datalen); + return -EINVAL; + } + +@@ -1681,6 +1684,7 @@ static void brcmf_rxreorder_get_skb_list + + void brcmf_fws_rxreorder(struct brcmf_if *ifp, struct sk_buff *pkt) + { ++ struct brcmf_pub *drvr = ifp->drvr; + u8 *reorder_data; + u8 flow_id, max_idx, cur_idx, exp_idx, end_idx; + struct brcmf_ampdu_rx_reorder *rfi; +@@ -1695,7 +1699,7 @@ void brcmf_fws_rxreorder(struct brcmf_if + + /* validate flags and flow id */ + if (flags == 0xFF) { +- brcmf_err("invalid flags...so ignore this packet\n"); ++ bphy_err(drvr, "invalid flags...so ignore this packet\n"); + brcmf_netif_rx(ifp, pkt); + return; + } +@@ -1732,7 +1736,7 @@ void brcmf_fws_rxreorder(struct brcmf_if + flow_id, max_idx); + rfi = kzalloc(buf_size, GFP_ATOMIC); + if (rfi == NULL) { +- brcmf_err("failed to alloc buffer\n"); ++ bphy_err(drvr, "failed to alloc buffer\n"); + brcmf_netif_rx(ifp, pkt); + return; + } +@@ -1996,6 +2000,7 @@ static u8 brcmf_fws_precommit_skb(struct + static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, + struct sk_buff *skb, int fifo) + { ++ struct brcmf_pub *drvr = fws->drvr; + struct brcmf_fws_mac_descriptor *entry; + struct sk_buff *pktout; + int qidx, hslot; +@@ -2009,11 +2014,11 @@ static void brcmf_fws_rollback_toq(struc + + pktout = brcmu_pktq_penq_head(&entry->psq, qidx, skb); + if (pktout == NULL) { +- brcmf_err("%s queue %d full\n", entry->name, qidx); ++ bphy_err(drvr, "%s queue %d full\n", entry->name, qidx); + rc = -ENOSPC; + } + } else { +- brcmf_err("%s entry removed\n", entry->name); ++ bphy_err(drvr, "%s entry removed\n", entry->name); + rc = -ENOENT; + } + +@@ -2118,7 +2123,8 @@ static int brcmf_fws_assign_htod(struct + + int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) + { +- struct brcmf_fws_info *fws = drvr_to_fws(ifp->drvr); ++ struct brcmf_pub *drvr = ifp->drvr; ++ struct brcmf_fws_info *fws = drvr_to_fws(drvr); + struct brcmf_skbuff_cb *skcb = brcmf_skbcb(skb); + struct ethhdr *eh = (struct ethhdr *)(skb->data); + int fifo = BRCMF_FWS_FIFO_BCMC; +@@ -2146,7 +2152,7 @@ int brcmf_fws_process_skb(struct brcmf_i + brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); + brcmf_fws_schedule_deq(fws); + } else { +- brcmf_err("drop skb: no hanger slot\n"); ++ bphy_err(drvr, "drop skb: no hanger slot\n"); + brcmf_txfinalize(ifp, skb, false); + rc = -ENOMEM; + } +@@ -2365,7 +2371,7 @@ struct brcmf_fws_info *brcmf_fws_attach( + + fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq"); + if (fws->fws_wq == NULL) { +- brcmf_err("workqueue creation failed\n"); ++ bphy_err(drvr, "workqueue creation failed\n"); + rc = -EBADF; + goto fail; + } +@@ -2381,13 +2387,13 @@ struct brcmf_fws_info *brcmf_fws_attach( + rc = brcmf_fweh_register(drvr, BRCMF_E_FIFO_CREDIT_MAP, + brcmf_fws_notify_credit_map); + if (rc < 0) { +- brcmf_err("register credit map handler failed\n"); ++ bphy_err(drvr, "register credit map handler failed\n"); + goto fail; + } + rc = brcmf_fweh_register(drvr, BRCMF_E_BCMC_CREDIT_SUPPORT, + brcmf_fws_notify_bcmc_credit_support); + if (rc < 0) { +- brcmf_err("register bcmc credit handler failed\n"); ++ bphy_err(drvr, "register bcmc credit handler failed\n"); + brcmf_fweh_unregister(drvr, BRCMF_E_FIFO_CREDIT_MAP); + goto fail; + } +@@ -2399,7 +2405,7 @@ struct brcmf_fws_info *brcmf_fws_attach( + fws->fw_signals = true; + ifp = brcmf_get_ifp(drvr, 0); + if (brcmf_fil_iovar_int_set(ifp, "tlv", tlv)) { +- brcmf_err("failed to set bdcv2 tlv signaling\n"); ++ bphy_err(drvr, "failed to set bdcv2 tlv signaling\n"); + fws->fcmode = BRCMF_FWS_FCMODE_NONE; + fws->fw_signals = false; + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -439,7 +439,7 @@ static int brcmf_msgbuf_tx_ioctl(struct + brcmf_commonring_lock(commonring); + ret_ptr = brcmf_commonring_reserve_for_write(commonring); + if (!ret_ptr) { +- brcmf_err("Failed to reserve space in commonring\n"); ++ bphy_err(drvr, "Failed to reserve space in commonring\n"); + brcmf_commonring_unlock(commonring); + return -ENOMEM; + } +@@ -503,7 +503,7 @@ static int brcmf_msgbuf_query_dcmd(struc + + timeout = brcmf_msgbuf_ioctl_resp_wait(msgbuf); + if (!timeout) { +- brcmf_err("Timeout on response for query command\n"); ++ bphy_err(drvr, "Timeout on response for query command\n"); + return -EIO; + } + +@@ -580,6 +580,7 @@ static u32 + brcmf_msgbuf_flowring_create_worker(struct brcmf_msgbuf *msgbuf, + struct brcmf_msgbuf_work_item *work) + { ++ struct brcmf_pub *drvr = msgbuf->drvr; + struct msgbuf_tx_flowring_create_req *create; + struct brcmf_commonring *commonring; + void *ret_ptr; +@@ -595,7 +596,7 @@ brcmf_msgbuf_flowring_create_worker(stru + &msgbuf->flowring_dma_handle[flowid], + GFP_KERNEL); + if (!dma_buf) { +- brcmf_err("dma_alloc_coherent failed\n"); ++ bphy_err(drvr, "dma_alloc_coherent failed\n"); + brcmf_flowring_delete(msgbuf->flow, flowid); + return BRCMF_FLOWRING_INVALID_ID; + } +@@ -608,7 +609,7 @@ brcmf_msgbuf_flowring_create_worker(stru + brcmf_commonring_lock(commonring); + ret_ptr = brcmf_commonring_reserve_for_write(commonring); + if (!ret_ptr) { +- brcmf_err("Failed to reserve space in commonring\n"); ++ bphy_err(drvr, "Failed to reserve space in commonring\n"); + brcmf_commonring_unlock(commonring); + brcmf_msgbuf_remove_flowring(msgbuf, flowid); + return BRCMF_FLOWRING_INVALID_ID; +@@ -635,7 +636,7 @@ brcmf_msgbuf_flowring_create_worker(stru + err = brcmf_commonring_write_complete(commonring); + brcmf_commonring_unlock(commonring); + if (err) { +- brcmf_err("Failed to write commonring\n"); ++ bphy_err(drvr, "Failed to write commonring\n"); + brcmf_msgbuf_remove_flowring(msgbuf, flowid); + return BRCMF_FLOWRING_INVALID_ID; + } +@@ -694,6 +695,7 @@ static u32 brcmf_msgbuf_flowring_create( + static void brcmf_msgbuf_txflow(struct brcmf_msgbuf *msgbuf, u16 flowid) + { + struct brcmf_flowring *flow = msgbuf->flow; ++ struct brcmf_pub *drvr = msgbuf->drvr; + struct brcmf_commonring *commonring; + void *ret_ptr; + u32 count; +@@ -713,8 +715,8 @@ static void brcmf_msgbuf_txflow(struct b + while (brcmf_flowring_qlen(flow, flowid)) { + skb = brcmf_flowring_dequeue(flow, flowid); + if (skb == NULL) { +- brcmf_err("No SKB, but qlen %d\n", +- brcmf_flowring_qlen(flow, flowid)); ++ bphy_err(drvr, "No SKB, but qlen %d\n", ++ brcmf_flowring_qlen(flow, flowid)); + break; + } + skb_orphan(skb); +@@ -722,7 +724,7 @@ static void brcmf_msgbuf_txflow(struct b + msgbuf->tx_pktids, skb, ETH_HLEN, + &physaddr, &pktid)) { + brcmf_flowring_reinsert(flow, flowid, skb); +- brcmf_err("No PKTID available !!\n"); ++ bphy_err(drvr, "No PKTID available !!\n"); + break; + } + ret_ptr = brcmf_commonring_reserve_for_write(commonring); +@@ -893,6 +895,7 @@ brcmf_msgbuf_process_txstatus(struct brc + + static u32 brcmf_msgbuf_rxbuf_data_post(struct brcmf_msgbuf *msgbuf, u32 count) + { ++ struct brcmf_pub *drvr = msgbuf->drvr; + struct brcmf_commonring *commonring; + void *ret_ptr; + struct sk_buff *skb; +@@ -920,7 +923,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post( + skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE); + + if (skb == NULL) { +- brcmf_err("Failed to alloc SKB\n"); ++ bphy_err(drvr, "Failed to alloc SKB\n"); + brcmf_commonring_write_cancel(commonring, alloced - i); + break; + } +@@ -930,7 +933,7 @@ static u32 brcmf_msgbuf_rxbuf_data_post( + msgbuf->rx_pktids, skb, 0, + &physaddr, &pktid)) { + dev_kfree_skb_any(skb); +- brcmf_err("No PKTID available !!\n"); ++ bphy_err(drvr, "No PKTID available !!\n"); + brcmf_commonring_write_cancel(commonring, alloced - i); + break; + } +@@ -1000,6 +1003,7 @@ static u32 + brcmf_msgbuf_rxbuf_ctrl_post(struct brcmf_msgbuf *msgbuf, bool event_buf, + u32 count) + { ++ struct brcmf_pub *drvr = msgbuf->drvr; + struct brcmf_commonring *commonring; + void *ret_ptr; + struct sk_buff *skb; +@@ -1017,7 +1021,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcm + count, + &alloced); + if (!ret_ptr) { +- brcmf_err("Failed to reserve space in commonring\n"); ++ bphy_err(drvr, "Failed to reserve space in commonring\n"); + brcmf_commonring_unlock(commonring); + return 0; + } +@@ -1029,7 +1033,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcm + skb = brcmu_pkt_buf_get_skb(BRCMF_MSGBUF_MAX_PKT_SIZE); + + if (skb == NULL) { +- brcmf_err("Failed to alloc SKB\n"); ++ bphy_err(drvr, "Failed to alloc SKB\n"); + brcmf_commonring_write_cancel(commonring, alloced - i); + break; + } +@@ -1039,7 +1043,7 @@ brcmf_msgbuf_rxbuf_ctrl_post(struct brcm + msgbuf->rx_pktids, skb, 0, + &physaddr, &pktid)) { + dev_kfree_skb_any(skb); +- brcmf_err("No PKTID available !!\n"); ++ bphy_err(drvr, "No PKTID available !!\n"); + brcmf_commonring_write_cancel(commonring, alloced - i); + break; + } +@@ -1091,6 +1095,7 @@ static void brcmf_msgbuf_rxbuf_event_pos + + static void brcmf_msgbuf_process_event(struct brcmf_msgbuf *msgbuf, void *buf) + { ++ struct brcmf_pub *drvr = msgbuf->drvr; + struct msgbuf_rx_event *event; + u32 idx; + u16 buflen; +@@ -1117,8 +1122,8 @@ static void brcmf_msgbuf_process_event(s + + ifp = brcmf_get_ifp(msgbuf->drvr, event->msg.ifidx); + if (!ifp || !ifp->ndev) { +- brcmf_err("Received pkt for invalid ifidx %d\n", +- event->msg.ifidx); ++ bphy_err(drvr, "Received pkt for invalid ifidx %d\n", ++ event->msg.ifidx); + goto exit; + } + +@@ -1134,6 +1139,7 @@ exit: + static void + brcmf_msgbuf_process_rx_complete(struct brcmf_msgbuf *msgbuf, void *buf) + { ++ struct brcmf_pub *drvr = msgbuf->drvr; + struct msgbuf_rx_complete *rx_complete; + struct sk_buff *skb; + u16 data_offset; +@@ -1167,7 +1173,7 @@ brcmf_msgbuf_process_rx_complete(struct + ifp = msgbuf->drvr->mon_if; + + if (!ifp) { +- brcmf_err("Received unexpected monitor pkt\n"); ++ bphy_err(drvr, "Received unexpected monitor pkt\n"); + brcmu_pkt_buf_free_skb(skb); + return; + } +@@ -1178,8 +1184,8 @@ brcmf_msgbuf_process_rx_complete(struct + + ifp = brcmf_get_ifp(msgbuf->drvr, rx_complete->msg.ifidx); + if (!ifp || !ifp->ndev) { +- brcmf_err("Received pkt for invalid ifidx %d\n", +- rx_complete->msg.ifidx); ++ bphy_err(drvr, "Received pkt for invalid ifidx %d\n", ++ rx_complete->msg.ifidx); + brcmu_pkt_buf_free_skb(skb); + return; + } +@@ -1192,13 +1198,15 @@ static void brcmf_msgbuf_process_ring_st + void *buf) + { + struct msgbuf_ring_status *ring_status = buf; ++ struct brcmf_pub *drvr = msgbuf->drvr; + int err; + + err = le16_to_cpu(ring_status->compl_hdr.status); + if (err) { + int ring = le16_to_cpu(ring_status->compl_hdr.flow_ring_id); + +- brcmf_err("Firmware reported ring %d error: %d\n", ring, err); ++ bphy_err(drvr, "Firmware reported ring %d error: %d\n", ring, ++ err); + } + } + +@@ -1206,6 +1214,7 @@ static void + brcmf_msgbuf_process_flow_ring_create_response(struct brcmf_msgbuf *msgbuf, + void *buf) + { ++ struct brcmf_pub *drvr = msgbuf->drvr; + struct msgbuf_flowring_create_resp *flowring_create_resp; + u16 status; + u16 flowid; +@@ -1217,7 +1226,7 @@ brcmf_msgbuf_process_flow_ring_create_re + status = le16_to_cpu(flowring_create_resp->compl_hdr.status); + + if (status) { +- brcmf_err("Flowring creation failed, code %d\n", status); ++ bphy_err(drvr, "Flowring creation failed, code %d\n", status); + brcmf_msgbuf_remove_flowring(msgbuf, flowid); + return; + } +@@ -1234,6 +1243,7 @@ static void + brcmf_msgbuf_process_flow_ring_delete_response(struct brcmf_msgbuf *msgbuf, + void *buf) + { ++ struct brcmf_pub *drvr = msgbuf->drvr; + struct msgbuf_flowring_delete_resp *flowring_delete_resp; + u16 status; + u16 flowid; +@@ -1245,7 +1255,7 @@ brcmf_msgbuf_process_flow_ring_delete_re + status = le16_to_cpu(flowring_delete_resp->compl_hdr.status); + + if (status) { +- brcmf_err("Flowring deletion failed, code %d\n", status); ++ bphy_err(drvr, "Flowring deletion failed, code %d\n", status); + brcmf_flowring_delete(msgbuf->flow, flowid); + return; + } +@@ -1258,6 +1268,7 @@ brcmf_msgbuf_process_flow_ring_delete_re + + static void brcmf_msgbuf_process_msgtype(struct brcmf_msgbuf *msgbuf, void *buf) + { ++ struct brcmf_pub *drvr = msgbuf->drvr; + struct msgbuf_common_hdr *msg; + + msg = (struct msgbuf_common_hdr *)buf; +@@ -1294,7 +1305,7 @@ static void brcmf_msgbuf_process_msgtype + brcmf_msgbuf_process_rx_complete(msgbuf, buf); + break; + default: +- brcmf_err("Unsupported msgtype %d\n", msg->msgtype); ++ bphy_err(drvr, "Unsupported msgtype %d\n", msg->msgtype); + break; + } + } +@@ -1377,7 +1388,7 @@ void brcmf_msgbuf_delete_flowring(struct + brcmf_commonring_lock(commonring); + ret_ptr = brcmf_commonring_reserve_for_write(commonring); + if (!ret_ptr) { +- brcmf_err("FW unaware, flowring will be removed !!\n"); ++ bphy_err(drvr, "FW unaware, flowring will be removed !!\n"); + brcmf_commonring_unlock(commonring); + brcmf_msgbuf_remove_flowring(msgbuf, flowid); + return; +@@ -1401,7 +1412,7 @@ void brcmf_msgbuf_delete_flowring(struct + err = brcmf_commonring_write_complete(commonring); + brcmf_commonring_unlock(commonring); + if (err) { +- brcmf_err("Failed to submit RING_DELETE, flowring will be removed\n"); ++ bphy_err(drvr, "Failed to submit RING_DELETE, flowring will be removed\n"); + brcmf_msgbuf_remove_flowring(msgbuf, flowid); + } + } +@@ -1476,8 +1487,8 @@ int brcmf_proto_msgbuf_attach(struct brc + if_msgbuf = drvr->bus_if->msgbuf; + + if (if_msgbuf->max_flowrings >= BRCMF_FLOWRING_HASHSIZE) { +- brcmf_err("driver not configured for this many flowrings %d\n", +- if_msgbuf->max_flowrings); ++ bphy_err(drvr, "driver not configured for this many flowrings %d\n", ++ if_msgbuf->max_flowrings); + if_msgbuf->max_flowrings = BRCMF_FLOWRING_HASHSIZE - 1; + } + +@@ -1487,7 +1498,7 @@ int brcmf_proto_msgbuf_attach(struct brc + + msgbuf->txflow_wq = create_singlethread_workqueue("msgbuf_txflow"); + if (msgbuf->txflow_wq == NULL) { +- brcmf_err("workqueue creation failed\n"); ++ bphy_err(drvr, "workqueue creation failed\n"); + goto fail; + } + INIT_WORK(&msgbuf->txflow_work, brcmf_msgbuf_txflow_worker); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/p2p.c +@@ -434,6 +434,7 @@ static void brcmf_p2p_print_actframe(boo + */ + static int brcmf_p2p_set_firmware(struct brcmf_if *ifp, u8 *p2p_mac) + { ++ struct brcmf_pub *drvr = ifp->drvr; + s32 ret = 0; + + brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1); +@@ -450,7 +451,7 @@ static int brcmf_p2p_set_firmware(struct + ret = brcmf_fil_iovar_data_set(ifp, "p2p_da_override", p2p_mac, + ETH_ALEN); + if (ret) +- brcmf_err("failed to update device address ret %d\n", ret); ++ bphy_err(drvr, "failed to update device address ret %d\n", ret); + + return ret; + } +@@ -570,13 +571,14 @@ static s32 brcmf_p2p_deinit_discovery(st + */ + static int brcmf_p2p_enable_discovery(struct brcmf_p2p_info *p2p) + { ++ struct brcmf_pub *drvr = p2p->cfg->pub; + struct brcmf_cfg80211_vif *vif; + s32 ret = 0; + + brcmf_dbg(TRACE, "enter\n"); + vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; + if (!vif) { +- brcmf_err("P2P config device not available\n"); ++ bphy_err(drvr, "P2P config device not available\n"); + ret = -EPERM; + goto exit; + } +@@ -590,13 +592,13 @@ static int brcmf_p2p_enable_discovery(st + vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; + ret = brcmf_fil_iovar_int_set(vif->ifp, "p2p_disc", 1); + if (ret < 0) { +- brcmf_err("set p2p_disc error\n"); ++ bphy_err(drvr, "set p2p_disc error\n"); + goto exit; + } + vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; + ret = brcmf_p2p_set_discover_state(vif->ifp, WL_P2P_DISC_ST_SCAN, 0, 0); + if (ret < 0) { +- brcmf_err("unable to set WL_P2P_DISC_ST_SCAN\n"); ++ bphy_err(drvr, "unable to set WL_P2P_DISC_ST_SCAN\n"); + goto exit; + } + +@@ -608,7 +610,7 @@ static int brcmf_p2p_enable_discovery(st + */ + ret = brcmf_fil_bsscfg_int_set(vif->ifp, "wsec", AES_ENABLED); + if (ret < 0) { +- brcmf_err("wsec error %d\n", ret); ++ bphy_err(drvr, "wsec error %d\n", ret); + goto exit; + } + +@@ -630,6 +632,7 @@ static s32 brcmf_p2p_escan(struct brcmf_ + u16 chanspecs[], s32 search_state, + enum p2p_bss_type bss_type) + { ++ struct brcmf_pub *drvr = p2p->cfg->pub; + s32 ret = 0; + s32 memsize = offsetof(struct brcmf_p2p_scan_le, + eparams.params_le.channel_list); +@@ -648,7 +651,7 @@ static s32 brcmf_p2p_escan(struct brcmf_ + + vif = p2p->bss_idx[bss_type].vif; + if (vif == NULL) { +- brcmf_err("no vif for bss type %d\n", bss_type); ++ bphy_err(drvr, "no vif for bss type %d\n", bss_type); + ret = -EINVAL; + goto exit; + } +@@ -676,7 +679,7 @@ static s32 brcmf_p2p_escan(struct brcmf_ + BRCMF_P2P_WILDCARD_SSID_LEN); + break; + default: +- brcmf_err(" invalid search state %d\n", search_state); ++ bphy_err(drvr, " invalid search state %d\n", search_state); + ret = -EINVAL; + goto exit; + } +@@ -760,6 +763,7 @@ static s32 brcmf_p2p_run_escan(struct br + struct cfg80211_scan_request *request) + { + struct brcmf_p2p_info *p2p = &cfg->p2p; ++ struct brcmf_pub *drvr = cfg->pub; + s32 err = 0; + s32 search_state = WL_P2P_DISC_ST_SCAN; + struct brcmf_cfg80211_vif *vif; +@@ -822,7 +826,7 @@ static s32 brcmf_p2p_run_escan(struct br + } + exit: + if (err) +- brcmf_err("error (%d)\n", err); ++ bphy_err(drvr, "error (%d)\n", err); + return err; + } + +@@ -917,19 +921,20 @@ int brcmf_p2p_scan_prep(struct wiphy *wi + static s32 + brcmf_p2p_discover_listen(struct brcmf_p2p_info *p2p, u16 channel, u32 duration) + { ++ struct brcmf_pub *drvr = p2p->cfg->pub; + struct brcmf_cfg80211_vif *vif; + struct brcmu_chan ch; + s32 err = 0; + + vif = p2p->bss_idx[P2PAPI_BSSCFG_DEVICE].vif; + if (!vif) { +- brcmf_err("Discovery is not set, so we have nothing to do\n"); ++ bphy_err(drvr, "Discovery is not set, so we have nothing to do\n"); + err = -EPERM; + goto exit; + } + + if (test_bit(BRCMF_P2P_STATUS_DISCOVER_LISTEN, &p2p->status)) { +- brcmf_err("Previous LISTEN is not completed yet\n"); ++ bphy_err(drvr, "Previous LISTEN is not completed yet\n"); + /* WAR: prevent cookie mismatch in wpa_supplicant return OK */ + goto exit; + } +@@ -1046,6 +1051,7 @@ void brcmf_p2p_cancel_remain_on_channel( + */ + static s32 brcmf_p2p_act_frm_search(struct brcmf_p2p_info *p2p, u16 channel) + { ++ struct brcmf_pub *drvr = p2p->cfg->pub; + s32 err; + u32 channel_cnt; + u16 *default_chan_list; +@@ -1061,7 +1067,7 @@ static s32 brcmf_p2p_act_frm_search(stru + default_chan_list = kcalloc(channel_cnt, sizeof(*default_chan_list), + GFP_KERNEL); + if (default_chan_list == NULL) { +- brcmf_err("channel list allocation failed\n"); ++ bphy_err(drvr, "channel list allocation failed\n"); + err = -ENOMEM; + goto exit; + } +@@ -1103,6 +1109,7 @@ static void brcmf_p2p_afx_handler(struct + struct brcmf_p2p_info *p2p = container_of(afx_hdl, + struct brcmf_p2p_info, + afx_hdl); ++ struct brcmf_pub *drvr = p2p->cfg->pub; + s32 err; + + if (!afx_hdl->is_active) +@@ -1116,7 +1123,7 @@ static void brcmf_p2p_afx_handler(struct + err = brcmf_p2p_act_frm_search(p2p, afx_hdl->peer_listen_chan); + + if (err) { +- brcmf_err("ERROR occurred! value is (%d)\n", err); ++ bphy_err(drvr, "ERROR occurred! value is (%d)\n", err); + if (test_bit(BRCMF_P2P_STATUS_FINDING_COMMON_CHANNEL, + &p2p->status)) + complete(&afx_hdl->act_frm_scan); +@@ -1338,7 +1345,8 @@ int brcmf_p2p_notify_action_frame_rx(str + const struct brcmf_event_msg *e, + void *data) + { +- struct brcmf_cfg80211_info *cfg = ifp->drvr->config; ++ struct brcmf_pub *drvr = ifp->drvr; ++ struct brcmf_cfg80211_info *cfg = drvr->config; + struct brcmf_p2p_info *p2p = &cfg->p2p; + struct afx_hdl *afx_hdl = &p2p->afx_hdl; + struct wireless_dev *wdev; +@@ -1409,7 +1417,7 @@ int brcmf_p2p_notify_action_frame_rx(str + mgmt_frame = kzalloc(offsetof(struct ieee80211_mgmt, u) + + mgmt_frame_len, GFP_KERNEL); + if (!mgmt_frame) { +- brcmf_err("No memory available for action frame\n"); ++ bphy_err(drvr, "No memory available for action frame\n"); + return -ENOMEM; + } + memcpy(mgmt_frame->da, ifp->mac_addr, ETH_ALEN); +@@ -1492,6 +1500,7 @@ int brcmf_p2p_notify_action_tx_complete( + static s32 brcmf_p2p_tx_action_frame(struct brcmf_p2p_info *p2p, + struct brcmf_fil_af_params_le *af_params) + { ++ struct brcmf_pub *drvr = p2p->cfg->pub; + struct brcmf_cfg80211_vif *vif; + s32 err = 0; + s32 timeout = 0; +@@ -1506,7 +1515,7 @@ static s32 brcmf_p2p_tx_action_frame(str + err = brcmf_fil_bsscfg_data_set(vif->ifp, "actframe", af_params, + sizeof(*af_params)); + if (err) { +- brcmf_err(" sending action frame has failed\n"); ++ bphy_err(drvr, " sending action frame has failed\n"); + goto exit; + } + +@@ -1556,6 +1565,7 @@ static s32 brcmf_p2p_pub_af_tx(struct br + struct brcmf_config_af_params *config_af_params) + { + struct brcmf_p2p_info *p2p = &cfg->p2p; ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_fil_action_frame_le *action_frame; + struct brcmf_p2p_pub_act_frame *act_frm; + s32 err = 0; +@@ -1634,8 +1644,8 @@ static s32 brcmf_p2p_pub_af_tx(struct br + config_af_params->extra_listen = false; + break; + default: +- brcmf_err("Unknown p2p pub act frame subtype: %d\n", +- act_frm->subtype); ++ bphy_err(drvr, "Unknown p2p pub act frame subtype: %d\n", ++ act_frm->subtype); + err = -EINVAL; + } + return err; +@@ -1657,6 +1667,7 @@ bool brcmf_p2p_send_action_frame(struct + struct brcmf_fil_action_frame_le *action_frame; + struct brcmf_config_af_params config_af_params; + struct afx_hdl *afx_hdl = &p2p->afx_hdl; ++ struct brcmf_pub *drvr = cfg->pub; + u16 action_frame_len; + bool ack = false; + u8 category; +@@ -1692,7 +1703,7 @@ bool brcmf_p2p_send_action_frame(struct + if (brcmf_p2p_pub_af_tx(cfg, af_params, &config_af_params)) { + /* Just send unknown subtype frame with */ + /* default parameters. */ +- brcmf_err("P2P Public action frame, unknown subtype.\n"); ++ bphy_err(drvr, "P2P Public action frame, unknown subtype.\n"); + } + } else if (brcmf_p2p_is_gas_action(action_frame->data, + action_frame_len)) { +@@ -1714,7 +1725,7 @@ bool brcmf_p2p_send_action_frame(struct + af_params->dwell_time = + cpu_to_le32(P2P_AF_MIN_DWELL_TIME); + } else { +- brcmf_err("Unknown action type: %d\n", action); ++ bphy_err(drvr, "Unknown action type: %d\n", action); + goto exit; + } + } else if (brcmf_p2p_is_p2p_action(action_frame->data, +@@ -1722,8 +1733,8 @@ bool brcmf_p2p_send_action_frame(struct + /* do not configure anything. it will be */ + /* sent with a default configuration */ + } else { +- brcmf_err("Unknown Frame: category 0x%x, action 0x%x\n", +- category, action); ++ bphy_err(drvr, "Unknown Frame: category 0x%x, action 0x%x\n", ++ category, action); + return false; + } + +@@ -1761,7 +1772,7 @@ bool brcmf_p2p_send_action_frame(struct + + if (brcmf_p2p_af_searching_channel(p2p) == + P2P_INVALID_CHANNEL) { +- brcmf_err("Couldn't find peer's channel.\n"); ++ bphy_err(drvr, "Couldn't find peer's channel.\n"); + goto exit; + } + +@@ -1783,7 +1794,8 @@ bool brcmf_p2p_send_action_frame(struct + tx_retry++; + } + if (ack == false) { +- brcmf_err("Failed to send Action Frame(retry %d)\n", tx_retry); ++ bphy_err(drvr, "Failed to send Action Frame(retry %d)\n", ++ tx_retry); + clear_bit(BRCMF_P2P_STATUS_GO_NEG_PHASE, &p2p->status); + } + +@@ -1965,6 +1977,7 @@ int brcmf_p2p_ifchange(struct brcmf_cfg8 + enum brcmf_fil_p2p_if_types if_type) + { + struct brcmf_p2p_info *p2p = &cfg->p2p; ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_cfg80211_vif *vif; + struct brcmf_fil_p2p_if_le if_request; + s32 err; +@@ -1974,13 +1987,13 @@ int brcmf_p2p_ifchange(struct brcmf_cfg8 + + vif = p2p->bss_idx[P2PAPI_BSSCFG_PRIMARY].vif; + if (!vif) { +- brcmf_err("vif for P2PAPI_BSSCFG_PRIMARY does not exist\n"); ++ bphy_err(drvr, "vif for P2PAPI_BSSCFG_PRIMARY does not exist\n"); + return -EPERM; + } + brcmf_notify_escan_complete(cfg, vif->ifp, true, true); + vif = p2p->bss_idx[P2PAPI_BSSCFG_CONNECTION].vif; + if (!vif) { +- brcmf_err("vif for P2PAPI_BSSCFG_CONNECTION does not exist\n"); ++ bphy_err(drvr, "vif for P2PAPI_BSSCFG_CONNECTION does not exist\n"); + return -EPERM; + } + brcmf_set_mpc(vif->ifp, 0); +@@ -1998,7 +2011,7 @@ int brcmf_p2p_ifchange(struct brcmf_cfg8 + err = brcmf_fil_iovar_data_set(vif->ifp, "p2p_ifupd", &if_request, + sizeof(if_request)); + if (err) { +- brcmf_err("p2p_ifupd FAILED, err=%d\n", err); ++ bphy_err(drvr, "p2p_ifupd FAILED, err=%d\n", err); + brcmf_cfg80211_arm_vif_event(cfg, NULL); + return err; + } +@@ -2006,7 +2019,7 @@ int brcmf_p2p_ifchange(struct brcmf_cfg8 + BRCMF_VIF_EVENT_TIMEOUT); + brcmf_cfg80211_arm_vif_event(cfg, NULL); + if (!err) { +- brcmf_err("No BRCMF_E_IF_CHANGE event received\n"); ++ bphy_err(drvr, "No BRCMF_E_IF_CHANGE event received\n"); + return -EIO; + } + +@@ -2069,6 +2082,7 @@ static struct wireless_dev *brcmf_p2p_cr + struct wiphy *wiphy, + u8 *addr) + { ++ struct brcmf_pub *drvr = p2p->cfg->pub; + struct brcmf_cfg80211_vif *p2p_vif; + struct brcmf_if *p2p_ifp; + struct brcmf_if *pri_ifp; +@@ -2080,7 +2094,7 @@ static struct wireless_dev *brcmf_p2p_cr + + p2p_vif = brcmf_alloc_vif(p2p->cfg, NL80211_IFTYPE_P2P_DEVICE); + if (IS_ERR(p2p_vif)) { +- brcmf_err("could not create discovery vif\n"); ++ bphy_err(drvr, "could not create discovery vif\n"); + return (struct wireless_dev *)p2p_vif; + } + +@@ -2088,7 +2102,7 @@ static struct wireless_dev *brcmf_p2p_cr + + /* firmware requires unique mac address for p2pdev interface */ + if (addr && ether_addr_equal(addr, pri_ifp->mac_addr)) { +- brcmf_err("discovery vif must be different from primary interface\n"); ++ bphy_err(drvr, "discovery vif must be different from primary interface\n"); + return ERR_PTR(-EINVAL); + } + +@@ -2101,7 +2115,7 @@ static struct wireless_dev *brcmf_p2p_cr + /* Initialize P2P Discovery in the firmware */ + err = brcmf_fil_iovar_int_set(pri_ifp, "p2p_disc", 1); + if (err < 0) { +- brcmf_err("set p2p_disc error\n"); ++ bphy_err(drvr, "set p2p_disc error\n"); + brcmf_fweh_p2pdev_setup(pri_ifp, false); + brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL); + goto fail; +@@ -2113,7 +2127,7 @@ static struct wireless_dev *brcmf_p2p_cr + brcmf_cfg80211_arm_vif_event(p2p->cfg, NULL); + brcmf_fweh_p2pdev_setup(pri_ifp, false); + if (!err) { +- brcmf_err("timeout occurred\n"); ++ bphy_err(drvr, "timeout occurred\n"); + err = -EIO; + goto fail; + } +@@ -2127,7 +2141,7 @@ static struct wireless_dev *brcmf_p2p_cr + /* verify bsscfg index for P2P discovery */ + err = brcmf_fil_iovar_int_get(pri_ifp, "p2p_dev", &bsscfgidx); + if (err < 0) { +- brcmf_err("retrieving discover bsscfg index failed\n"); ++ bphy_err(drvr, "retrieving discover bsscfg index failed\n"); + goto fail; + } + +@@ -2161,6 +2175,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s + { + struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); + struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_cfg80211_vif *vif; + enum brcmf_fil_p2p_if_types iftype; + int err; +@@ -2201,7 +2216,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s + BRCMF_VIF_EVENT_TIMEOUT); + brcmf_cfg80211_arm_vif_event(cfg, NULL); + if (!err) { +- brcmf_err("timeout occurred\n"); ++ bphy_err(drvr, "timeout occurred\n"); + err = -EIO; + goto fail; + } +@@ -2209,7 +2224,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s + /* interface created in firmware */ + ifp = vif->ifp; + if (!ifp) { +- brcmf_err("no if pointer provided\n"); ++ bphy_err(drvr, "no if pointer provided\n"); + err = -ENOENT; + goto fail; + } +@@ -2220,7 +2235,7 @@ struct wireless_dev *brcmf_p2p_add_vif(s + #endif /* >= 3.17.0 */ + err = brcmf_net_attach(ifp, true); + if (err) { +- brcmf_err("Registering netdevice failed\n"); ++ bphy_err(drvr, "Registering netdevice failed\n"); + free_netdev(ifp->ndev); + goto fail; + } +@@ -2375,6 +2390,7 @@ void brcmf_p2p_stop_device(struct wiphy + */ + s32 brcmf_p2p_attach(struct brcmf_cfg80211_info *cfg, bool p2pdev_forced) + { ++ struct brcmf_pub *drvr = cfg->pub; + struct brcmf_p2p_info *p2p; + struct brcmf_if *pri_ifp; + s32 err = 0; +@@ -2389,7 +2405,7 @@ s32 brcmf_p2p_attach(struct brcmf_cfg802 + if (p2pdev_forced) { + err_ptr = brcmf_p2p_create_p2pdev(p2p, NULL, NULL); + if (IS_ERR(err_ptr)) { +- brcmf_err("P2P device creation failed.\n"); ++ bphy_err(drvr, "P2P device creation failed.\n"); + err = PTR_ERR(err_ptr); + } + } else { +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pno.c +@@ -109,6 +109,7 @@ static int brcmf_pno_channel_config(stru + static int brcmf_pno_config(struct brcmf_if *ifp, u32 scan_freq, + u32 mscan, u32 bestn) + { ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_pno_param_le pfn_param; + u16 flags; + u32 pfnmem; +@@ -132,13 +133,13 @@ static int brcmf_pno_config(struct brcmf + /* set bestn in firmware */ + err = brcmf_fil_iovar_int_set(ifp, "pfnmem", pfnmem); + if (err < 0) { +- brcmf_err("failed to set pfnmem\n"); ++ bphy_err(drvr, "failed to set pfnmem\n"); + goto exit; + } + /* get max mscan which the firmware supports */ + err = brcmf_fil_iovar_int_get(ifp, "pfnmem", &pfnmem); + if (err < 0) { +- brcmf_err("failed to get pfnmem\n"); ++ bphy_err(drvr, "failed to get pfnmem\n"); + goto exit; + } + mscan = min_t(u32, mscan, pfnmem); +@@ -152,7 +153,7 @@ static int brcmf_pno_config(struct brcmf + err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param, + sizeof(pfn_param)); + if (err) +- brcmf_err("pfn_set failed, err=%d\n", err); ++ bphy_err(drvr, "pfn_set failed, err=%d\n", err); + + exit: + return err; +@@ -160,6 +161,7 @@ exit: + + static int brcmf_pno_set_random(struct brcmf_if *ifp, struct brcmf_pno_info *pi) + { ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_pno_macaddr_le pfn_mac; + u8 *mac_addr = NULL; + u8 *mac_mask = NULL; +@@ -194,7 +196,7 @@ static int brcmf_pno_set_random(struct b + err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac, + sizeof(pfn_mac)); + if (err) +- brcmf_err("pfn_macaddr failed, err=%d\n", err); ++ bphy_err(drvr, "pfn_macaddr failed, err=%d\n", err); + + return err; + } +@@ -202,6 +204,7 @@ static int brcmf_pno_set_random(struct b + static int brcmf_pno_add_ssid(struct brcmf_if *ifp, struct cfg80211_ssid *ssid, + bool active) + { ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_pno_net_param_le pfn; + int err; + +@@ -218,12 +221,13 @@ static int brcmf_pno_add_ssid(struct brc + brcmf_dbg(SCAN, "adding ssid=%.32s (active=%d)\n", ssid->ssid, active); + err = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn, sizeof(pfn)); + if (err < 0) +- brcmf_err("adding failed: err=%d\n", err); ++ bphy_err(drvr, "adding failed: err=%d\n", err); + return err; + } + + static int brcmf_pno_add_bssid(struct brcmf_if *ifp, const u8 *bssid) + { ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_pno_bssid_le bssid_cfg; + int err; + +@@ -234,7 +238,7 @@ static int brcmf_pno_add_bssid(struct br + err = brcmf_fil_iovar_data_set(ifp, "pfn_add_bssid", &bssid_cfg, + sizeof(bssid_cfg)); + if (err < 0) +- brcmf_err("adding failed: err=%d\n", err); ++ bphy_err(drvr, "adding failed: err=%d\n", err); + return err; + } + +@@ -258,6 +262,7 @@ static bool brcmf_is_ssid_active(struct + + static int brcmf_pno_clean(struct brcmf_if *ifp) + { ++ struct brcmf_pub *drvr = ifp->drvr; + int ret; + + /* Disable pfn */ +@@ -267,7 +272,7 @@ static int brcmf_pno_clean(struct brcmf_ + ret = brcmf_fil_iovar_data_set(ifp, "pfnclear", NULL, 0); + } + if (ret < 0) +- brcmf_err("failed code %d\n", ret); ++ bphy_err(drvr, "failed code %d\n", ret); + + return ret; + } +@@ -392,6 +397,7 @@ static int brcmf_pno_config_networks(str + + static int brcmf_pno_config_sched_scans(struct brcmf_if *ifp) + { ++ struct brcmf_pub *drvr = ifp->drvr; + struct brcmf_pno_info *pi; + struct brcmf_gscan_config *gscan_cfg; + struct brcmf_gscan_bucket_config *buckets; +@@ -416,7 +422,7 @@ static int brcmf_pno_config_sched_scans( + /* clean up everything */ + err = brcmf_pno_clean(ifp); + if (err < 0) { +- brcmf_err("failed error=%d\n", err); ++ bphy_err(drvr, "failed error=%d\n", err); + goto free_gscan; + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c +@@ -47,8 +47,8 @@ int brcmf_proto_attach(struct brcmf_pub + if (brcmf_proto_msgbuf_attach(drvr)) + goto fail; + } else { +- brcmf_err("Unsupported proto type %d\n", +- drvr->bus_if->proto_type); ++ bphy_err(drvr, "Unsupported proto type %d\n", ++ drvr->bus_if->proto_type); + goto fail; + } + if (!proto->tx_queue_data || (proto->hdrpull == NULL) || +@@ -56,7 +56,7 @@ int brcmf_proto_attach(struct brcmf_pub + (proto->configure_addr_mode == NULL) || + (proto->delete_peer == NULL) || (proto->add_tdls_peer == NULL) || + (proto->debugfs_create == NULL)) { +- brcmf_err("Not all proto handlers have been installed\n"); ++ bphy_err(drvr, "Not all proto handlers have been installed\n"); + goto fail; + } + return 0; diff --git a/package/kernel/mac80211/patches/brcm/355-v5.1-brcmfmac-add-basic-validation-of-shared-RAM-address.patch b/package/kernel/mac80211/patches/brcm/355-v5.1-brcmfmac-add-basic-validation-of-shared-RAM-address.patch new file mode 100644 index 0000000000..323e93354c --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/355-v5.1-brcmfmac-add-basic-validation-of-shared-RAM-address.patch @@ -0,0 +1,38 @@ +From e0a8ef4d7b4315bc4c1641fb3f3a7dfdfa6627b8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Wed, 20 Feb 2019 11:30:47 +0100 +Subject: [PATCH] brcmfmac: add basic validation of shared RAM address +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +While experimenting with firmware loading I ended up in a state of +firmware reporting shared RAM address 0x04000001. It was causing: +[ 94.448015] Unable to handle kernel paging request at virtual address cd680001 +due to reading out of the mapped memory. + +This patch adds some basic validation to avoid kernel crashes due to the +unexpected firmware behavior. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -1560,6 +1560,12 @@ static int brcmf_pcie_download_fw_nvram( + brcmf_err(bus, "FW failed to initialize\n"); + return -ENODEV; + } ++ if (sharedram_addr < devinfo->ci->rambase || ++ sharedram_addr >= devinfo->ci->rambase + devinfo->ci->ramsize) { ++ brcmf_err(bus, "Invalid shared RAM address 0x%08x\n", ++ sharedram_addr); ++ return -ENODEV; ++ } + brcmf_dbg(PCIE, "Shared RAM addr: 0x%08x\n", sharedram_addr); + + return (brcmf_pcie_init_share_ram_info(devinfo, sharedram_addr)); diff --git a/package/kernel/mac80211/patches/brcm/356-v5.1-0001-brcmfmac-fix-size-of-the-struct-msgbuf_ring_status.patch b/package/kernel/mac80211/patches/brcm/356-v5.1-0001-brcmfmac-fix-size-of-the-struct-msgbuf_ring_status.patch new file mode 100644 index 0000000000..10834db608 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/356-v5.1-0001-brcmfmac-fix-size-of-the-struct-msgbuf_ring_status.patch @@ -0,0 +1,29 @@ +From 0c7051610c577b60b01b3b5aec14d6765e177b0d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 21 Feb 2019 11:33:24 +0100 +Subject: [PATCH] brcmfmac: fix size of the struct msgbuf_ring_status +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This updates host struct to match the in-firmawre definition. It's a +cosmetic change as it only applies to the reserved struct space. + +Fixes: c988b78244df ("brcmfmac: print firmware reported ring status errors") +Signed-off-by: Rafał Miłecki +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -139,7 +139,7 @@ struct msgbuf_ring_status { + struct msgbuf_common_hdr msg; + struct msgbuf_completion_hdr compl_hdr; + __le16 write_idx; +- __le32 rsvd0[5]; ++ __le16 rsvd0[5]; + }; + + struct msgbuf_rx_event { diff --git a/package/kernel/mac80211/patches/brcm/356-v5.1-0002-brcmfmac-print-firmware-reported-general-status-erro.patch b/package/kernel/mac80211/patches/brcm/356-v5.1-0002-brcmfmac-print-firmware-reported-general-status-erro.patch new file mode 100644 index 0000000000..313d501e82 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/356-v5.1-0002-brcmfmac-print-firmware-reported-general-status-erro.patch @@ -0,0 +1,69 @@ +From c91377495192cda096e52dc09c266b0d05f16d86 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Thu, 21 Feb 2019 11:33:25 +0100 +Subject: [PATCH] brcmfmac: print firmware reported general status errors +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Firmware may report general errors using a special message type. Add +basic support for it by simply decoding & printing an error number. + +A sample situation in which firmware reports a buf error: +CONSOLE: 027084.733 no host response IOCTL buffer available..so fail the request +will now produce a "Firmware reported general error: 9" on the host. + +Signed-off-by: Rafał Miłecki +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/msgbuf.c | 24 +++++++++++++++++++ + 1 file changed, 24 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/msgbuf.c +@@ -134,6 +134,14 @@ struct msgbuf_completion_hdr { + __le16 flow_ring_id; + }; + ++/* Data struct for the MSGBUF_TYPE_GEN_STATUS */ ++struct msgbuf_gen_status { ++ struct msgbuf_common_hdr msg; ++ struct msgbuf_completion_hdr compl_hdr; ++ __le16 write_idx; ++ __le32 rsvd0[3]; ++}; ++ + /* Data struct for the MSGBUF_TYPE_RING_STATUS */ + struct msgbuf_ring_status { + struct msgbuf_common_hdr msg; +@@ -1194,6 +1202,18 @@ brcmf_msgbuf_process_rx_complete(struct + brcmf_netif_rx(ifp, skb); + } + ++static void brcmf_msgbuf_process_gen_status(struct brcmf_msgbuf *msgbuf, ++ void *buf) ++{ ++ struct msgbuf_gen_status *gen_status = buf; ++ struct brcmf_pub *drvr = msgbuf->drvr; ++ int err; ++ ++ err = le16_to_cpu(gen_status->compl_hdr.status); ++ if (err) ++ bphy_err(drvr, "Firmware reported general error: %d\n", err); ++} ++ + static void brcmf_msgbuf_process_ring_status(struct brcmf_msgbuf *msgbuf, + void *buf) + { +@@ -1273,6 +1293,10 @@ static void brcmf_msgbuf_process_msgtype + + msg = (struct msgbuf_common_hdr *)buf; + switch (msg->msgtype) { ++ case MSGBUF_TYPE_GEN_STATUS: ++ brcmf_dbg(MSGBUF, "MSGBUF_TYPE_GEN_STATUS\n"); ++ brcmf_msgbuf_process_gen_status(msgbuf, buf); ++ break; + case MSGBUF_TYPE_RING_STATUS: + brcmf_dbg(MSGBUF, "MSGBUF_TYPE_RING_STATUS\n"); + brcmf_msgbuf_process_ring_status(msgbuf, buf); diff --git a/package/kernel/mac80211/patches/brcm/360-v5.2-0001-brcmfmac-support-repeated-brcmf_fw_alloc_request-cal.patch b/package/kernel/mac80211/patches/brcm/360-v5.2-0001-brcmfmac-support-repeated-brcmf_fw_alloc_request-cal.patch new file mode 100644 index 0000000000..ef694f079f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/360-v5.2-0001-brcmfmac-support-repeated-brcmf_fw_alloc_request-cal.patch @@ -0,0 +1,32 @@ +From c9692820710f57c826b2e43a6fb1e4cd307508b0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 26 Feb 2019 14:11:16 +0100 +Subject: [PATCH] brcmfmac: support repeated brcmf_fw_alloc_request() calls +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +During a normal brcmfmac lifetime brcmf_fw_alloc_request() is called +once only during the probe. It's safe to assume provided array is clear. + +Further brcmfmac improvements may require calling it multiple times +though. This patch allows it by fixing invalid firmware paths like: +brcm/brcmfmac4366c-pcie.binbrcm/brcmfmac4366c-pcie.bin + +Signed-off-by: Rafał Miłecki +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -743,6 +743,7 @@ brcmf_fw_alloc_request(u32 chip, u32 chi + + for (j = 0; j < n_fwnames; j++) { + fwreq->items[j].path = fwnames[j].path; ++ fwnames[j].path[0] = '\0'; + /* check if firmware path is provided by module parameter */ + if (brcmf_mp_global.firmware_path[0] != '\0') { + strlcpy(fwnames[j].path, mp_path, diff --git a/package/kernel/mac80211/patches/brcm/360-v5.2-0002-brcmfmac-add-a-function-designated-for-handling-firm.patch b/package/kernel/mac80211/patches/brcm/360-v5.2-0002-brcmfmac-add-a-function-designated-for-handling-firm.patch new file mode 100644 index 0000000000..595b8948c7 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/360-v5.2-0002-brcmfmac-add-a-function-designated-for-handling-firm.patch @@ -0,0 +1,79 @@ +From a2ec87ddbf1637f854ffcfff9d12d392fa30758b Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 26 Feb 2019 14:11:18 +0100 +Subject: [PATCH] brcmfmac: add a function designated for handling firmware + fails +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This improves handling PCIe firmware halts by printing a clear error +message and replaces a similar code in the SDIO bus support. + +It will also allow further improvements like trying to recover from a +firmware crash. + +Signed-off-by: Rafał Miłecki +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h | 2 ++ + .../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 10 ++++++++++ + .../net/wireless/broadcom/brcm80211/brcmfmac/pcie.c | 2 +- + .../net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 ++-- + 4 files changed, 15 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -262,6 +262,8 @@ void brcmf_detach(struct device *dev); + void brcmf_dev_reset(struct device *dev); + /* Request from bus module to initiate a coredump */ + void brcmf_dev_coredump(struct device *dev); ++/* Indication that firmware has halted or crashed */ ++void brcmf_fw_crashed(struct device *dev); + + /* Configure the "global" bus state used by upper layers */ + void brcmf_bus_change_state(struct brcmf_bus *bus, enum brcmf_bus_state state); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1294,6 +1294,16 @@ void brcmf_dev_coredump(struct device *d + brcmf_dbg(TRACE, "failed to create coredump\n"); + } + ++void brcmf_fw_crashed(struct device *dev) ++{ ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_pub *drvr = bus_if->drvr; ++ ++ bphy_err(drvr, "Firmware has halted or crashed\n"); ++ ++ brcmf_dev_coredump(dev); ++} ++ + void brcmf_detach(struct device *dev) + { + s32 i; +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -730,7 +730,7 @@ static void brcmf_pcie_handle_mb_data(st + } + if (dtoh_mb_data & BRCMF_D2H_DEV_FWHALT) { + brcmf_dbg(PCIE, "D2H_MB_DATA: FW HALT\n"); +- brcmf_dev_coredump(&devinfo->pdev->dev); ++ brcmf_fw_crashed(&devinfo->pdev->dev); + } + } + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -1090,8 +1090,8 @@ static u32 brcmf_sdio_hostmail(struct br + + /* dongle indicates the firmware has halted/crashed */ + if (hmb_data & HMB_DATA_FWHALT) { +- brcmf_err("mailbox indicates firmware halted\n"); +- brcmf_dev_coredump(&sdiod->func1->dev); ++ brcmf_dbg(SDIO, "mailbox indicates firmware halted\n"); ++ brcmf_fw_crashed(&sdiod->func1->dev); + } + + /* Dongle recomposed rx frames, accept them again */ diff --git a/package/kernel/mac80211/patches/brcm/360-v5.2-0003-brcmfmac-reset-PCIe-bus-on-a-firmware-crash.patch b/package/kernel/mac80211/patches/brcm/360-v5.2-0003-brcmfmac-reset-PCIe-bus-on-a-firmware-crash.patch new file mode 100644 index 0000000000..5617d141b3 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/360-v5.2-0003-brcmfmac-reset-PCIe-bus-on-a-firmware-crash.patch @@ -0,0 +1,153 @@ +From 4684997d9eea29380000e062755aa6d368d789a3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= +Date: Tue, 26 Feb 2019 14:11:19 +0100 +Subject: [PATCH] brcmfmac: reset PCIe bus on a firmware crash +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This includes bus reset & reloading a firmware. It should be sufficient +for a user space to (setup and) use a wireless device again. + +Support for reset on USB & SDIO can be added later. + +Signed-off-by: Rafał Miłecki +Reviewed-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/bus.h | 10 ++++++ + .../broadcom/brcm80211/brcmfmac/core.c | 12 +++++++ + .../broadcom/brcm80211/brcmfmac/core.h | 2 ++ + .../broadcom/brcm80211/brcmfmac/pcie.c | 35 +++++++++++++++++++ + 4 files changed, 59 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bus.h +@@ -91,6 +91,7 @@ struct brcmf_bus_ops { + int (*get_fwname)(struct device *dev, const char *ext, + unsigned char *fw_name); + void (*debugfs_create)(struct device *dev); ++ int (*reset)(struct device *dev); + }; + + +@@ -245,6 +246,15 @@ void brcmf_bus_debugfs_create(struct brc + return bus->ops->debugfs_create(bus->dev); + } + ++static inline ++int brcmf_bus_reset(struct brcmf_bus *bus) ++{ ++ if (!bus->ops->reset) ++ return -EOPNOTSUPP; ++ ++ return bus->ops->reset(bus->dev); ++} ++ + /* + * interface functions from common layer + */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1105,6 +1105,14 @@ static int brcmf_revinfo_read(struct seq + return 0; + } + ++static void brcmf_core_bus_reset(struct work_struct *work) ++{ ++ struct brcmf_pub *drvr = container_of(work, struct brcmf_pub, ++ bus_reset); ++ ++ brcmf_bus_reset(drvr->bus_if); ++} ++ + static int brcmf_bus_started(struct brcmf_pub *drvr, struct cfg80211_ops *ops) + { + int ret = -1; +@@ -1176,6 +1184,8 @@ static int brcmf_bus_started(struct brcm + #endif + #endif /* CONFIG_INET */ + ++ INIT_WORK(&drvr->bus_reset, brcmf_core_bus_reset); ++ + /* populate debugfs */ + brcmf_debugfs_add_entry(drvr, "revinfo", brcmf_revinfo_read); + brcmf_feat_debugfs_create(drvr); +@@ -1302,6 +1312,8 @@ void brcmf_fw_crashed(struct device *dev + bphy_err(drvr, "Firmware has halted or crashed\n"); + + brcmf_dev_coredump(dev); ++ ++ schedule_work(&drvr->bus_reset); + } + + void brcmf_detach(struct device *dev) +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.h +@@ -143,6 +143,8 @@ struct brcmf_pub { + struct notifier_block inet6addr_notifier; + struct brcmf_mp_device *settings; + ++ struct work_struct bus_reset; ++ + u8 clmver[BRCMF_DCMD_SMLEN]; + }; + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +@@ -345,6 +345,10 @@ static const u32 brcmf_ring_itemsize[BRC + BRCMF_D2H_MSGRING_RX_COMPLETE_ITEMSIZE + }; + ++static void brcmf_pcie_setup(struct device *dev, int ret, ++ struct brcmf_fw_request *fwreq); ++static struct brcmf_fw_request * ++brcmf_pcie_prepare_fw_request(struct brcmf_pciedev_info *devinfo); + + static u32 + brcmf_pcie_read_reg32(struct brcmf_pciedev_info *devinfo, u32 reg_offset) +@@ -1409,6 +1413,36 @@ int brcmf_pcie_get_fwname(struct device + return 0; + } + ++static int brcmf_pcie_reset(struct device *dev) ++{ ++ struct brcmf_bus *bus_if = dev_get_drvdata(dev); ++ struct brcmf_pciedev *buspub = bus_if->bus_priv.pcie; ++ struct brcmf_pciedev_info *devinfo = buspub->devinfo; ++ struct brcmf_fw_request *fwreq; ++ int err; ++ ++ brcmf_detach(dev); ++ ++ brcmf_pcie_release_irq(devinfo); ++ brcmf_pcie_release_scratchbuffers(devinfo); ++ brcmf_pcie_release_ringbuffers(devinfo); ++ brcmf_pcie_reset_device(devinfo); ++ ++ fwreq = brcmf_pcie_prepare_fw_request(devinfo); ++ if (!fwreq) { ++ dev_err(dev, "Failed to prepare FW request\n"); ++ return -ENOMEM; ++ } ++ ++ err = brcmf_fw_get_firmwares(dev, fwreq, brcmf_pcie_setup); ++ if (err) { ++ dev_err(dev, "Failed to prepare FW request\n"); ++ kfree(fwreq); ++ } ++ ++ return err; ++} ++ + static const struct brcmf_bus_ops brcmf_pcie_bus_ops = { + .txdata = brcmf_pcie_tx, + .stop = brcmf_pcie_down, +@@ -1418,6 +1452,7 @@ static const struct brcmf_bus_ops brcmf_ + .get_ramsize = brcmf_pcie_get_ramsize, + .get_memdump = brcmf_pcie_get_memdump, + .get_fwname = brcmf_pcie_get_fwname, ++ .reset = brcmf_pcie_reset, + }; + + diff --git a/package/kernel/mac80211/patches/brcm/361-v5.2-0001-brcmfmac-fix-WARNING-during-USB-disconnect-in-case-o.patch b/package/kernel/mac80211/patches/brcm/361-v5.2-0001-brcmfmac-fix-WARNING-during-USB-disconnect-in-case-o.patch new file mode 100644 index 0000000000..cb4b5c924f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/361-v5.2-0001-brcmfmac-fix-WARNING-during-USB-disconnect-in-case-o.patch @@ -0,0 +1,124 @@ +From c80d26e81ef1802f30364b4ad1955c1443a592b9 Mon Sep 17 00:00:00 2001 +From: Piotr Figiel +Date: Mon, 4 Mar 2019 15:42:49 +0000 +Subject: [PATCH] brcmfmac: fix WARNING during USB disconnect in case of + unempty psq + +brcmu_pkt_buf_free_skb emits WARNING when attempting to free a sk_buff +which is part of any queue. After USB disconnect this may have happened +when brcmf_fws_hanger_cleanup() is called as per-interface psq was never +cleaned when removing the interface. +Change brcmf_fws_macdesc_cleanup() in a way that it removes the +corresponding packets from hanger table (to avoid double-free when +brcmf_fws_hanger_cleanup() is called) and add a call to clean-up the +interface specific packet queue. + +Below is a WARNING during USB disconnect with Raspberry Pi WiFi dongle +running in AP mode. This was reproducible when the interface was +transmitting during the disconnect and is fixed with this commit. + +------------[ cut here ]------------ +WARNING: CPU: 0 PID: 1171 at drivers/net/wireless/broadcom/brcm80211/brcmutil/utils.c:49 brcmu_pkt_buf_free_skb+0x3c/0x40 +Modules linked in: nf_log_ipv4 nf_log_common xt_LOG xt_limit iptable_mangle xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis u_ether cdc_acm smsc95xx usbnet ci_hdrc_imx ci_hdrc ulpi usbmisc_imx 8250_exar 8250_pci 8250 8250_base libcomposite configfs udc_core +CPU: 0 PID: 1171 Comm: kworker/0:0 Not tainted 4.19.23-00075-gde33ed8 #99 +Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) +Workqueue: usb_hub_wq hub_event +[<8010ff84>] (unwind_backtrace) from [<8010bb64>] (show_stack+0x10/0x14) +[<8010bb64>] (show_stack) from [<80840278>] (dump_stack+0x88/0x9c) +[<80840278>] (dump_stack) from [<8011f5ec>] (__warn+0xfc/0x114) +[<8011f5ec>] (__warn) from [<8011f71c>] (warn_slowpath_null+0x40/0x48) +[<8011f71c>] (warn_slowpath_null) from [<805a476c>] (brcmu_pkt_buf_free_skb+0x3c/0x40) +[<805a476c>] (brcmu_pkt_buf_free_skb) from [<805bb6c4>] (brcmf_fws_cleanup+0x1e4/0x22c) +[<805bb6c4>] (brcmf_fws_cleanup) from [<805bc854>] (brcmf_fws_del_interface+0x58/0x68) +[<805bc854>] (brcmf_fws_del_interface) from [<805b66ac>] (brcmf_remove_interface+0x40/0x150) +[<805b66ac>] (brcmf_remove_interface) from [<805b6870>] (brcmf_detach+0x6c/0xb0) +[<805b6870>] (brcmf_detach) from [<805bdbb8>] (brcmf_usb_disconnect+0x30/0x4c) +[<805bdbb8>] (brcmf_usb_disconnect) from [<805e5d64>] (usb_unbind_interface+0x5c/0x1e0) +[<805e5d64>] (usb_unbind_interface) from [<804aab10>] (device_release_driver_internal+0x154/0x1ec) +[<804aab10>] (device_release_driver_internal) from [<804a97f4>] (bus_remove_device+0xcc/0xf8) +[<804a97f4>] (bus_remove_device) from [<804a6fc0>] (device_del+0x118/0x308) +[<804a6fc0>] (device_del) from [<805e488c>] (usb_disable_device+0xa0/0x1c8) +[<805e488c>] (usb_disable_device) from [<805dcf98>] (usb_disconnect+0x70/0x1d8) +[<805dcf98>] (usb_disconnect) from [<805ddd84>] (hub_event+0x464/0xf50) +[<805ddd84>] (hub_event) from [<80135a70>] (process_one_work+0x138/0x3f8) +[<80135a70>] (process_one_work) from [<80135d5c>] (worker_thread+0x2c/0x554) +[<80135d5c>] (worker_thread) from [<8013b1a0>] (kthread+0x124/0x154) +[<8013b1a0>] (kthread) from [<801010e8>] (ret_from_fork+0x14/0x2c) +Exception stack(0xecf8dfb0 to 0xecf8dff8) +dfa0: 00000000 00000000 00000000 00000000 +dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 +---[ end trace 38d234018e9e2a90 ]--- +------------[ cut here ]------------ + +Signed-off-by: Piotr Figiel +Signed-off-by: Kalle Valo +--- + .../broadcom/brcm80211/brcmfmac/fwsignal.c | 42 +++++++++++-------- + 1 file changed, 24 insertions(+), 18 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -580,24 +580,6 @@ static bool brcmf_fws_ifidx_match(struct + return ifidx == *(int *)arg; + } + +-static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q, +- int ifidx) +-{ +- bool (*matchfn)(struct sk_buff *, void *) = NULL; +- struct sk_buff *skb; +- int prec; +- +- if (ifidx != -1) +- matchfn = brcmf_fws_ifidx_match; +- for (prec = 0; prec < q->num_prec; prec++) { +- skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); +- while (skb) { +- brcmu_pkt_buf_free_skb(skb); +- skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); +- } +- } +-} +- + static void brcmf_fws_hanger_init(struct brcmf_fws_hanger *hanger) + { + int i; +@@ -669,6 +651,28 @@ static inline int brcmf_fws_hanger_poppk + return 0; + } + ++static void brcmf_fws_psq_flush(struct brcmf_fws_info *fws, struct pktq *q, ++ int ifidx) ++{ ++ bool (*matchfn)(struct sk_buff *, void *) = NULL; ++ struct sk_buff *skb; ++ int prec; ++ u32 hslot; ++ ++ if (ifidx != -1) ++ matchfn = brcmf_fws_ifidx_match; ++ for (prec = 0; prec < q->num_prec; prec++) { ++ skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); ++ while (skb) { ++ hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); ++ brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, ++ true); ++ brcmu_pkt_buf_free_skb(skb); ++ skb = brcmu_pktq_pdeq_match(q, prec, matchfn, &ifidx); ++ } ++ } ++} ++ + static int brcmf_fws_hanger_mark_suppressed(struct brcmf_fws_hanger *h, + u32 slot_id) + { +@@ -2200,6 +2204,8 @@ void brcmf_fws_del_interface(struct brcm + brcmf_fws_lock(fws); + ifp->fws_desc = NULL; + brcmf_dbg(TRACE, "deleting %s\n", entry->name); ++ brcmf_fws_macdesc_cleanup(fws, &fws->desc.iface[ifp->ifidx], ++ ifp->ifidx); + brcmf_fws_macdesc_deinit(entry); + brcmf_fws_cleanup(fws, ifp->ifidx); + brcmf_fws_unlock(fws); diff --git a/package/kernel/mac80211/patches/brcm/361-v5.2-0002-brcmfmac-fix-NULL-pointer-derefence-during-USB-disco.patch b/package/kernel/mac80211/patches/brcm/361-v5.2-0002-brcmfmac-fix-NULL-pointer-derefence-during-USB-disco.patch new file mode 100644 index 0000000000..e45288b63b --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/361-v5.2-0002-brcmfmac-fix-NULL-pointer-derefence-during-USB-disco.patch @@ -0,0 +1,217 @@ +From 5cdb0ef6144f47440850553579aa923c20a63f23 Mon Sep 17 00:00:00 2001 +From: Piotr Figiel +Date: Mon, 4 Mar 2019 15:42:52 +0000 +Subject: [PATCH] brcmfmac: fix NULL pointer derefence during USB disconnect + +In case USB disconnect happens at the moment transmitting workqueue is in +progress the underlying interface may be gone causing a NULL pointer +dereference. Add synchronization of the workqueue destruction with the +detach implementation in core so that the transmitting workqueue is stopped +during detach before the interfaces are removed. + +Fix following Oops: + +Unable to handle kernel NULL pointer dereference at virtual address 00000008 +pgd = 9e6a802d +[00000008] *pgd=00000000 +Internal error: Oops: 5 [#1] PREEMPT SMP ARM +Modules linked in: nf_log_ipv4 nf_log_common xt_LOG xt_limit iptable_mangle +xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 +iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis u_ether +usb_serial_simple usbserial cdc_acm brcmfmac brcmutil smsc95xx usbnet +ci_hdrc_imx ci_hdrc ulpi usbmisc_imx 8250_exar 8250_pci 8250 8250_base +libcomposite configfs udc_core +CPU: 0 PID: 7 Comm: kworker/u8:0 Not tainted 4.19.23-00076-g03740aa-dirty #102 +Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) +Workqueue: brcmf_fws_wq brcmf_fws_dequeue_worker [brcmfmac] +PC is at brcmf_txfinalize+0x34/0x90 [brcmfmac] +LR is at brcmf_fws_dequeue_worker+0x218/0x33c [brcmfmac] +pc : [<7f0dee64>] lr : [<7f0e4140>] psr: 60010093 +sp : ee8abef0 ip : 00000000 fp : edf38000 +r10: ffffffed r9 : edf38970 r8 : edf38004 +r7 : edf3e970 r6 : 00000000 r5 : ede69000 r4 : 00000000 +r3 : 00000a97 r2 : 00000000 r1 : 0000888e r0 : ede69000 +Flags: nZCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment none +Control: 10c5387d Table: 7d03c04a DAC: 00000051 +Process kworker/u8:0 (pid: 7, stack limit = 0x24ec3e04) +Stack: (0xee8abef0 to 0xee8ac000) +bee0: ede69000 00000000 ed56c3e0 7f0e4140 +bf00: 00000001 00000000 edf38004 edf3e99c ed56c3e0 80d03d00 edfea43a edf3e970 +bf20: ee809880 ee804200 ee971100 00000000 edf3e974 00000000 ee804200 80135a70 +bf40: 80d03d00 ee804218 ee809880 ee809894 ee804200 80d03d00 ee804218 ee8aa000 +bf60: 00000088 80135d5c 00000000 ee829f00 ee829dc0 00000000 ee809880 80135d30 +bf80: ee829f1c ee873eac 00000000 8013b1a0 ee829dc0 8013b07c 00000000 00000000 +bfa0: 00000000 00000000 00000000 801010e8 00000000 00000000 00000000 00000000 +bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 00000000 00000000 +[<7f0dee64>] (brcmf_txfinalize [brcmfmac]) from [<7f0e4140>] (brcmf_fws_dequeue_worker+0x218/0x33c [brcmfmac]) +[<7f0e4140>] (brcmf_fws_dequeue_worker [brcmfmac]) from [<80135a70>] (process_one_work+0x138/0x3f8) +[<80135a70>] (process_one_work) from [<80135d5c>] (worker_thread+0x2c/0x554) +[<80135d5c>] (worker_thread) from [<8013b1a0>] (kthread+0x124/0x154) +[<8013b1a0>] (kthread) from [<801010e8>] (ret_from_fork+0x14/0x2c) +Exception stack(0xee8abfb0 to 0xee8abff8) +bfa0: 00000000 00000000 00000000 00000000 +bfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +bfe0: 00000000 00000000 00000000 00000000 00000013 00000000 +Code: e1530001 0a000007 e3560000 e1a00005 (05942008) +---[ end trace 079239dd31c86e90 ]--- + +Signed-off-by: Piotr Figiel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/bcdc.c | 11 +++++++++-- + .../wireless/broadcom/brcm80211/brcmfmac/bcdc.h | 6 ++++-- + .../wireless/broadcom/brcm80211/brcmfmac/core.c | 4 +++- + .../broadcom/brcm80211/brcmfmac/fwsignal.c | 16 ++++++++++++---- + .../broadcom/brcm80211/brcmfmac/fwsignal.h | 3 ++- + .../wireless/broadcom/brcm80211/brcmfmac/proto.c | 10 ++++++++-- + .../wireless/broadcom/brcm80211/brcmfmac/proto.h | 3 ++- + 7 files changed, 40 insertions(+), 13 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.c +@@ -490,11 +490,18 @@ fail: + return -ENOMEM; + } + +-void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) ++void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) ++{ ++ struct brcmf_bcdc *bcdc = drvr->proto->pd; ++ ++ brcmf_fws_detach_pre_delif(bcdc->fws); ++} ++ ++void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) + { + struct brcmf_bcdc *bcdc = drvr->proto->pd; + + drvr->proto->pd = NULL; +- brcmf_fws_detach(bcdc->fws); ++ brcmf_fws_detach_post_delif(bcdc->fws); + kfree(bcdc); + } +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcdc.h +@@ -18,14 +18,16 @@ + + #ifdef CPTCFG_BRCMFMAC_PROTO_BCDC + int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr); +-void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr); ++void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr); ++void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr); + void brcmf_proto_bcdc_txflowblock(struct device *dev, bool state); + void brcmf_proto_bcdc_txcomplete(struct device *dev, struct sk_buff *txp, + bool success); + struct brcmf_fws_info *drvr_to_fws(struct brcmf_pub *drvr); + #else + static inline int brcmf_proto_bcdc_attach(struct brcmf_pub *drvr) { return 0; } +-static inline void brcmf_proto_bcdc_detach(struct brcmf_pub *drvr) {} ++static void brcmf_proto_bcdc_detach_pre_delif(struct brcmf_pub *drvr) {}; ++static inline void brcmf_proto_bcdc_detach_post_delif(struct brcmf_pub *drvr) {} + #endif + + #endif /* BRCMFMAC_BCDC_H */ +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -1342,6 +1342,8 @@ void brcmf_detach(struct device *dev) + + brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN); + ++ brcmf_proto_detach_pre_delif(drvr); ++ + /* make sure primary interface removed last */ + for (i = BRCMF_MAX_IFS-1; i > -1; i--) + brcmf_remove_interface(drvr->iflist[i], false); +@@ -1351,7 +1353,7 @@ void brcmf_detach(struct device *dev) + + brcmf_bus_stop(drvr->bus_if); + +- brcmf_proto_detach(drvr); ++ brcmf_proto_detach_post_delif(drvr); + + bus_if->drvr = NULL; + wiphy_free(drvr->wiphy); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.c +@@ -2443,17 +2443,25 @@ struct brcmf_fws_info *brcmf_fws_attach( + return fws; + + fail: +- brcmf_fws_detach(fws); ++ brcmf_fws_detach_pre_delif(fws); ++ brcmf_fws_detach_post_delif(fws); + return ERR_PTR(rc); + } + +-void brcmf_fws_detach(struct brcmf_fws_info *fws) ++void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws) + { + if (!fws) + return; +- +- if (fws->fws_wq) ++ if (fws->fws_wq) { + destroy_workqueue(fws->fws_wq); ++ fws->fws_wq = NULL; ++ } ++} ++ ++void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws) ++{ ++ if (!fws) ++ return; + + /* cleanup */ + brcmf_fws_lock(fws); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/fwsignal.h +@@ -19,7 +19,8 @@ + #define FWSIGNAL_H_ + + struct brcmf_fws_info *brcmf_fws_attach(struct brcmf_pub *drvr); +-void brcmf_fws_detach(struct brcmf_fws_info *fws); ++void brcmf_fws_detach_pre_delif(struct brcmf_fws_info *fws); ++void brcmf_fws_detach_post_delif(struct brcmf_fws_info *fws); + void brcmf_fws_debugfs_create(struct brcmf_pub *drvr); + bool brcmf_fws_queue_skbs(struct brcmf_fws_info *fws); + bool brcmf_fws_fc_active(struct brcmf_fws_info *fws); +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.c +@@ -67,16 +67,22 @@ fail: + return -ENOMEM; + } + +-void brcmf_proto_detach(struct brcmf_pub *drvr) ++void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr) + { + brcmf_dbg(TRACE, "Enter\n"); + + if (drvr->proto) { + if (drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) +- brcmf_proto_bcdc_detach(drvr); ++ brcmf_proto_bcdc_detach_post_delif(drvr); + else if (drvr->bus_if->proto_type == BRCMF_PROTO_MSGBUF) + brcmf_proto_msgbuf_detach(drvr); + kfree(drvr->proto); + drvr->proto = NULL; + } + } ++ ++void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr) ++{ ++ if (drvr->proto && drvr->bus_if->proto_type == BRCMF_PROTO_BCDC) ++ brcmf_proto_bcdc_detach_pre_delif(drvr); ++} +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/proto.h +@@ -54,7 +54,8 @@ struct brcmf_proto { + + + int brcmf_proto_attach(struct brcmf_pub *drvr); +-void brcmf_proto_detach(struct brcmf_pub *drvr); ++void brcmf_proto_detach_pre_delif(struct brcmf_pub *drvr); ++void brcmf_proto_detach_post_delif(struct brcmf_pub *drvr); + + static inline int brcmf_proto_hdrpull(struct brcmf_pub *drvr, bool do_fws, + struct sk_buff *skb, diff --git a/package/kernel/mac80211/patches/brcm/362-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch b/package/kernel/mac80211/patches/brcm/362-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch new file mode 100644 index 0000000000..b6a11d6793 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/362-v5.2-0001-brcmfmac-fix-race-during-disconnect-when-USB-complet.patch @@ -0,0 +1,84 @@ +From db3b9e2e1d58080d0754bdf9293dabf8c6491b67 Mon Sep 17 00:00:00 2001 +From: Piotr Figiel +Date: Fri, 8 Mar 2019 15:25:04 +0000 +Subject: [PATCH] brcmfmac: fix race during disconnect when USB completion is + in progress + +It was observed that rarely during USB disconnect happening shortly after +connect (before full initialization completes) usb_hub_wq would wait +forever for the dev_init_lock to be unlocked. dev_init_lock would remain +locked though because of infinite wait during usb_kill_urb: + +[ 2730.656472] kworker/0:2 D 0 260 2 0x00000000 +[ 2730.660700] Workqueue: events request_firmware_work_func +[ 2730.664807] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac) +[ 2730.670587] [<809dd164>] (schedule) from [<8069af44>] (usb_kill_urb+0xdc/0x114) +[ 2730.676815] [<8069af44>] (usb_kill_urb) from [<7f258b50>] (brcmf_usb_free_q+0x34/0xa8 [brcmfmac]) +[ 2730.684833] [<7f258b50>] (brcmf_usb_free_q [brcmfmac]) from [<7f2517d4>] (brcmf_detach+0xa0/0xb8 [brcmfmac]) +[ 2730.693557] [<7f2517d4>] (brcmf_detach [brcmfmac]) from [<7f251a34>] (brcmf_attach+0xac/0x3d8 [brcmfmac]) +[ 2730.702094] [<7f251a34>] (brcmf_attach [brcmfmac]) from [<7f2587ac>] (brcmf_usb_probe_phase2+0x468/0x4a0 [brcmfmac]) +[ 2730.711601] [<7f2587ac>] (brcmf_usb_probe_phase2 [brcmfmac]) from [<7f252888>] (brcmf_fw_request_done+0x194/0x220 [brcmfmac]) +[ 2730.721795] [<7f252888>] (brcmf_fw_request_done [brcmfmac]) from [<805748e4>] (request_firmware_work_func+0x4c/0x88) +[ 2730.731125] [<805748e4>] (request_firmware_work_func) from [<80141474>] (process_one_work+0x228/0x808) +[ 2730.739223] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) +[ 2730.746105] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) +[ 2730.752227] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) + +[ 2733.099695] kworker/0:3 D 0 1065 2 0x00000000 +[ 2733.103926] Workqueue: usb_hub_wq hub_event +[ 2733.106914] [<809dca20>] (__schedule) from [<809dd164>] (schedule+0x4c/0xac) +[ 2733.112693] [<809dd164>] (schedule) from [<809e2a8c>] (schedule_timeout+0x214/0x3e4) +[ 2733.119621] [<809e2a8c>] (schedule_timeout) from [<809dde2c>] (wait_for_common+0xc4/0x1c0) +[ 2733.126810] [<809dde2c>] (wait_for_common) from [<7f258d00>] (brcmf_usb_disconnect+0x1c/0x4c [brcmfmac]) +[ 2733.135206] [<7f258d00>] (brcmf_usb_disconnect [brcmfmac]) from [<8069e0c8>] (usb_unbind_interface+0x5c/0x1e4) +[ 2733.143943] [<8069e0c8>] (usb_unbind_interface) from [<8056d3e8>] (device_release_driver_internal+0x164/0x1fc) +[ 2733.152769] [<8056d3e8>] (device_release_driver_internal) from [<8056c078>] (bus_remove_device+0xd0/0xfc) +[ 2733.161138] [<8056c078>] (bus_remove_device) from [<8056977c>] (device_del+0x11c/0x310) +[ 2733.167939] [<8056977c>] (device_del) from [<8069cba8>] (usb_disable_device+0xa0/0x1cc) +[ 2733.174743] [<8069cba8>] (usb_disable_device) from [<8069507c>] (usb_disconnect+0x74/0x1dc) +[ 2733.181823] [<8069507c>] (usb_disconnect) from [<80695e88>] (hub_event+0x478/0xf88) +[ 2733.188278] [<80695e88>] (hub_event) from [<80141474>] (process_one_work+0x228/0x808) +[ 2733.194905] [<80141474>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) +[ 2733.201724] [<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) +[ 2733.207913] [<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) + +It was traced down to a case where usb_kill_urb would be called on an URB +structure containing more or less random data, including large number in +its use_count. During the debugging it appeared that in brcmf_usb_free_q() +the traversal over URBs' lists is not synchronized with operations on those +lists in brcmf_usb_rx_complete() leading to handling +brcmf_usbdev_info structure (holding lists' head) as lists' element and in +result causing above problem. + +Fix it by walking through all URBs during brcmf_cancel_all_urbs using the +arrays of requests instead of linked lists. + +Signed-off-by: Piotr Figiel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -682,12 +682,18 @@ static int brcmf_usb_up(struct device *d + + static void brcmf_cancel_all_urbs(struct brcmf_usbdev_info *devinfo) + { ++ int i; ++ + if (devinfo->ctl_urb) + usb_kill_urb(devinfo->ctl_urb); + if (devinfo->bulk_urb) + usb_kill_urb(devinfo->bulk_urb); +- brcmf_usb_free_q(&devinfo->tx_postq, true); +- brcmf_usb_free_q(&devinfo->rx_postq, true); ++ if (devinfo->tx_reqs) ++ for (i = 0; i < devinfo->bus_pub.ntxq; i++) ++ usb_kill_urb(devinfo->tx_reqs[i].urb); ++ if (devinfo->rx_reqs) ++ for (i = 0; i < devinfo->bus_pub.nrxq; i++) ++ usb_kill_urb(devinfo->rx_reqs[i].urb); + } + + static void brcmf_usb_down(struct device *dev) diff --git a/package/kernel/mac80211/patches/brcm/362-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch b/package/kernel/mac80211/patches/brcm/362-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch new file mode 100644 index 0000000000..088e731322 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/362-v5.2-0002-brcmfmac-remove-pending-parameter-from-brcmf_usb_fre.patch @@ -0,0 +1,54 @@ +From 2b78e5f5223666d403d4fdb30af4ad65c8da3cdb Mon Sep 17 00:00:00 2001 +From: Piotr Figiel +Date: Fri, 8 Mar 2019 15:25:06 +0000 +Subject: [PATCH] brcmfmac: remove pending parameter from brcmf_usb_free_q + +brcmf_usb_free_q is no longer called with pending=true thus this boolean +parameter is no longer needed. + +Signed-off-by: Piotr Figiel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/usb.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -445,9 +445,10 @@ fail: + + } + +-static void brcmf_usb_free_q(struct list_head *q, bool pending) ++static void brcmf_usb_free_q(struct list_head *q) + { + struct brcmf_usbreq *req, *next; ++ + int i = 0; + list_for_each_entry_safe(req, next, q, list) { + if (!req->urb) { +@@ -455,12 +456,8 @@ static void brcmf_usb_free_q(struct list + break; + } + i++; +- if (pending) { +- usb_kill_urb(req->urb); +- } else { +- usb_free_urb(req->urb); +- list_del_init(&req->list); +- } ++ usb_free_urb(req->urb); ++ list_del_init(&req->list); + } + } + +@@ -1029,8 +1026,8 @@ static void brcmf_usb_detach(struct brcm + brcmf_dbg(USB, "Enter, devinfo %p\n", devinfo); + + /* free the URBS */ +- brcmf_usb_free_q(&devinfo->rx_freeq, false); +- brcmf_usb_free_q(&devinfo->tx_freeq, false); ++ brcmf_usb_free_q(&devinfo->rx_freeq); ++ brcmf_usb_free_q(&devinfo->tx_freeq); + + usb_free_urb(devinfo->ctl_urb); + usb_free_urb(devinfo->bulk_urb); diff --git a/package/kernel/mac80211/patches/brcm/362-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch b/package/kernel/mac80211/patches/brcm/362-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch new file mode 100644 index 0000000000..4c8d073914 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/362-v5.2-0003-brcmfmac-remove-unused-variable-i-from-brcmf_usb_fre.patch @@ -0,0 +1,29 @@ +From 504f06725d015954a0fcafdf1d90a6795ca8f769 Mon Sep 17 00:00:00 2001 +From: Piotr Figiel +Date: Fri, 8 Mar 2019 15:25:09 +0000 +Subject: [PATCH] brcmfmac: remove unused variable i from brcmf_usb_free_q + +Variable i is not used so remove it. + +Signed-off-by: Piotr Figiel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -449,13 +449,11 @@ static void brcmf_usb_free_q(struct list + { + struct brcmf_usbreq *req, *next; + +- int i = 0; + list_for_each_entry_safe(req, next, q, list) { + if (!req->urb) { + brcmf_err("bad req\n"); + break; + } +- i++; + usb_free_urb(req->urb); + list_del_init(&req->list); + } diff --git a/package/kernel/mac80211/patches/brcm/363-v5.2-brcmfmac-fix-Oops-when-bringing-up-interface-during-.patch b/package/kernel/mac80211/patches/brcm/363-v5.2-brcmfmac-fix-Oops-when-bringing-up-interface-during-.patch new file mode 100644 index 0000000000..01e9bf076d --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/363-v5.2-brcmfmac-fix-Oops-when-bringing-up-interface-during-.patch @@ -0,0 +1,123 @@ +From 24d413a31afaee9bbbf79226052c386b01780ce2 Mon Sep 17 00:00:00 2001 +From: Piotr Figiel +Date: Wed, 13 Mar 2019 09:52:01 +0000 +Subject: [PATCH] brcmfmac: fix Oops when bringing up interface during USB + disconnect + +Fix a race which leads to an Oops with NULL pointer dereference. The +dereference is in brcmf_config_dongle() when cfg_to_ndev() attempts to get +net_device structure of interface with index 0 via if2bss mapping. This +shouldn't fail because of check for bus being ready in brcmf_netdev_open(), +but it's not synchronised with USB disconnect and there is a race: after +the check the bus can be marked down and the mapping for interface 0 may be +gone. + +Solve this by modifying disconnect handling so that the removal of mapping +of ifidx to brcmf_if structure happens after netdev removal (which is +synchronous with brcmf_netdev_open() thanks to rtln being locked in +devinet_ioctl()). This assures brcmf_netdev_open() returns before the +mapping is removed during disconnect. + +Unable to handle kernel NULL pointer dereference at virtual address 00000008 +pgd = bcae2612 +[00000008] *pgd=8be73831 +Internal error: Oops: 17 [#1] PREEMPT SMP ARM +Modules linked in: brcmfmac brcmutil nf_log_ipv4 nf_log_common xt_LOG xt_limit +iptable_mangle xt_connmark xt_tcpudp xt_conntrack nf_conntrack nf_defrag_ipv6 +nf_defrag_ipv4 iptable_filter ip_tables x_tables usb_f_mass_storage usb_f_rndis +u_ether usb_serial_simple usbserial cdc_acm smsc95xx usbnet ci_hdrc_imx ci_hdrc +usbmisc_imx ulpi 8250_exar 8250_pci 8250 8250_base libcomposite configfs +udc_core [last unloaded: brcmutil] +CPU: 2 PID: 24478 Comm: ifconfig Not tainted 4.19.23-00078-ga62866d-dirty #115 +Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) +PC is at brcmf_cfg80211_up+0x94/0x29c [brcmfmac] +LR is at brcmf_cfg80211_up+0x8c/0x29c [brcmfmac] +pc : [<7f26a91c>] lr : [<7f26a914>] psr: a0070013 +sp : eca99d28 ip : 00000000 fp : ee9c6c00 +r10: 00000036 r9 : 00000000 r8 : ece4002c +r7 : edb5b800 r6 : 00000000 r5 : 80f08448 r4 : edb5b968 +r3 : ffffffff r2 : 00000000 r1 : 00000002 r0 : 00000000 +Flags: NzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment none +Control: 10c5387d Table: 7ca0c04a DAC: 00000051 +Process ifconfig (pid: 24478, stack limit = 0xd9e85a0e) +Stack: (0xeca99d28 to 0xeca9a000) +9d20: 00000000 80f873b0 0000000d 80f08448 eca99d68 50d45f32 +9d40: 7f27de94 ece40000 80f08448 80f08448 7f27de94 ece4002c 00000000 00000036 +9d60: ee9c6c00 7f27262c 00001002 50d45f32 ece40000 00000000 80f08448 80772008 +9d80: 00000001 00001043 00001002 ece40000 00000000 50d45f32 ece40000 00000001 +9da0: 80f08448 00001043 00001002 807723d0 00000000 50d45f32 80f08448 eca99e58 +9dc0: 80f87113 50d45f32 80f08448 ece40000 ece40138 00001002 80f08448 00000000 +9de0: 00000000 80772434 edbd5380 eca99e58 edbd5380 80f08448 ee9c6c0c 80805f70 +9e00: 00000000 ede08e00 00008914 ece40000 00000014 ee9c6c0c 600c0013 00001043 +9e20: 0208a8c0 ffffffff 00000000 50d45f32 eca98000 80f08448 7ee9fc38 00008914 +9e40: 80f68e40 00000051 eca98000 00000036 00000003 80808b9c 6e616c77 00000030 +9e60: 00000000 00000000 00001043 0208a8c0 ffffffff 00000000 80f08448 00000000 +9e80: 00000000 816d8b20 600c0013 00000001 ede09320 801763d4 00000000 50d45f32 +9ea0: eca98000 80f08448 7ee9fc38 50d45f32 00008914 80f08448 7ee9fc38 80f68e40 +9ec0: ed531540 8074721c 00000800 00000001 00000000 6e616c77 00000030 00000000 +9ee0: 00000000 00001002 0208a8c0 ffffffff 00000000 50d45f32 80f08448 7ee9fc38 +9f00: ed531560 ec8fc900 80285a6c 80285138 edb910c0 00000000 ecd91008 ede08e00 +9f20: 80f08448 00000000 00000000 816d8b20 600c0013 00000001 ede09320 801763d4 +9f40: 00000000 50d45f32 00021000 edb91118 edb910c0 80f08448 01b29000 edb91118 +9f60: eca99f7c 50d45f32 00021000 ec8fc900 00000003 ec8fc900 00008914 7ee9fc38 +9f80: eca98000 00000036 00000003 80285a6c 00086364 7ee9fe1c 000000c3 00000036 +9fa0: 801011c4 80101000 00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364 +9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003 +9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc 600c0010 00000003 00000000 00000000 +[<7f26a91c>] (brcmf_cfg80211_up [brcmfmac]) from [<7f27262c>] (brcmf_netdev_open+0x74/0xe8 [brcmfmac]) +[<7f27262c>] (brcmf_netdev_open [brcmfmac]) from [<80772008>] (__dev_open+0xcc/0x150) +[<80772008>] (__dev_open) from [<807723d0>] (__dev_change_flags+0x168/0x1b4) +[<807723d0>] (__dev_change_flags) from [<80772434>] (dev_change_flags+0x18/0x48) +[<80772434>] (dev_change_flags) from [<80805f70>] (devinet_ioctl+0x67c/0x79c) +[<80805f70>] (devinet_ioctl) from [<80808b9c>] (inet_ioctl+0x210/0x3d4) +[<80808b9c>] (inet_ioctl) from [<8074721c>] (sock_ioctl+0x350/0x524) +[<8074721c>] (sock_ioctl) from [<80285138>] (do_vfs_ioctl+0xb0/0x9b0) +[<80285138>] (do_vfs_ioctl) from [<80285a6c>] (ksys_ioctl+0x34/0x5c) +[<80285a6c>] (ksys_ioctl) from [<80101000>] (ret_fast_syscall+0x0/0x28) +Exception stack(0xeca99fa8 to 0xeca99ff0) +9fa0: 00086364 7ee9fe1c 00000003 00008914 7ee9fc38 00086364 +9fc0: 00086364 7ee9fe1c 000000c3 00000036 0008630c 7ee9fe1c 7ee9fc38 00000003 +9fe0: 000a42b8 7ee9fbd4 00019914 76e09acc +Code: e5970328 eb002021 e1a02006 e3a01002 (e5909008) +---[ end trace 5cbac2333f3ac5df ]--- + +Signed-off-by: Piotr Figiel +Signed-off-by: Kalle Valo +--- + .../net/wireless/broadcom/brcm80211/brcmfmac/core.c | 10 +++++++--- + 1 file changed, 7 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +@@ -862,17 +862,17 @@ static void brcmf_del_if(struct brcmf_pu + bool rtnl_locked) + { + struct brcmf_if *ifp; ++ int ifidx; + + ifp = drvr->iflist[bsscfgidx]; +- drvr->iflist[bsscfgidx] = NULL; + if (!ifp) { + bphy_err(drvr, "Null interface, bsscfgidx=%d\n", bsscfgidx); + return; + } + brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, ifidx=%d\n", bsscfgidx, + ifp->ifidx); +- if (drvr->if2bss[ifp->ifidx] == bsscfgidx) +- drvr->if2bss[ifp->ifidx] = BRCMF_BSSIDX_INVALID; ++ ifidx = ifp->ifidx; ++ + if (ifp->ndev) { + if (bsscfgidx == 0) { + if (ifp->ndev->netdev_ops == &brcmf_netdev_ops_pri) { +@@ -900,6 +900,10 @@ static void brcmf_del_if(struct brcmf_pu + brcmf_p2p_ifp_removed(ifp, rtnl_locked); + kfree(ifp); + } ++ ++ drvr->iflist[bsscfgidx] = NULL; ++ if (drvr->if2bss[ifidx] == bsscfgidx) ++ drvr->if2bss[ifidx] = BRCMF_BSSIDX_INVALID; + } + + void brcmf_remove_interface(struct brcmf_if *ifp, bool rtnl_locked) diff --git a/package/kernel/mac80211/patches/brcm/364-v5.2-brcmfmac-convert-dev_init_lock-mutex-to-completion.patch b/package/kernel/mac80211/patches/brcm/364-v5.2-brcmfmac-convert-dev_init_lock-mutex-to-completion.patch new file mode 100644 index 0000000000..e6ecd2215f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/364-v5.2-brcmfmac-convert-dev_init_lock-mutex-to-completion.patch @@ -0,0 +1,182 @@ +From a9fd0953fa4a62887306be28641b4b0809f3b2fd Mon Sep 17 00:00:00 2001 +From: Piotr Figiel +Date: Wed, 13 Mar 2019 09:52:42 +0000 +Subject: [PATCH] brcmfmac: convert dev_init_lock mutex to completion + +Leaving dev_init_lock mutex locked in probe causes BUG and a WARNING when +kernel is compiled with CONFIG_PROVE_LOCKING. Convert mutex to completion +which silences those warnings and improves code readability. + +Fix below errors when connecting the USB WiFi dongle: + +brcmfmac: brcmf_fw_alloc_request: using brcm/brcmfmac43143 for chip BCM43143/2 +BUG: workqueue leaked lock or atomic: kworker/0:2/0x00000000/434 + last function: hub_event +1 lock held by kworker/0:2/434: + #0: 18d5dcdf (&devinfo->dev_init_lock){+.+.}, at: brcmf_usb_probe+0x78/0x550 [brcmfmac] +CPU: 0 PID: 434 Comm: kworker/0:2 Not tainted 4.19.23-00084-g454a789-dirty #123 +Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) +Workqueue: usb_hub_wq hub_event +[<8011237c>] (unwind_backtrace) from [<8010d74c>] (show_stack+0x10/0x14) +[<8010d74c>] (show_stack) from [<809c4324>] (dump_stack+0xa8/0xd4) +[<809c4324>] (dump_stack) from [<8014195c>] (process_one_work+0x710/0x808) +[<8014195c>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) +[<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) +[<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) +Exception stack(0xed1d9fb0 to 0xed1d9ff8) +9fa0: 00000000 00000000 00000000 00000000 +9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 + +====================================================== +WARNING: possible circular locking dependency detected +4.19.23-00084-g454a789-dirty #123 Not tainted +------------------------------------------------------ +kworker/0:2/434 is trying to acquire lock: +e29cf799 ((wq_completion)"events"){+.+.}, at: process_one_work+0x174/0x808 + +but task is already holding lock: +18d5dcdf (&devinfo->dev_init_lock){+.+.}, at: brcmf_usb_probe+0x78/0x550 [brcmfmac] + +which lock already depends on the new lock. + +the existing dependency chain (in reverse order) is: + +-> #2 (&devinfo->dev_init_lock){+.+.}: + mutex_lock_nested+0x1c/0x24 + brcmf_usb_probe+0x78/0x550 [brcmfmac] + usb_probe_interface+0xc0/0x1bc + really_probe+0x228/0x2c0 + __driver_attach+0xe4/0xe8 + bus_for_each_dev+0x68/0xb4 + bus_add_driver+0x19c/0x214 + driver_register+0x78/0x110 + usb_register_driver+0x84/0x148 + process_one_work+0x228/0x808 + worker_thread+0x2c/0x564 + kthread+0x13c/0x16c + ret_from_fork+0x14/0x20 + (null) + +-> #1 (brcmf_driver_work){+.+.}: + worker_thread+0x2c/0x564 + kthread+0x13c/0x16c + ret_from_fork+0x14/0x20 + (null) + +-> #0 ((wq_completion)"events"){+.+.}: + process_one_work+0x1b8/0x808 + worker_thread+0x2c/0x564 + kthread+0x13c/0x16c + ret_from_fork+0x14/0x20 + (null) + +other info that might help us debug this: + +Chain exists of: + (wq_completion)"events" --> brcmf_driver_work --> &devinfo->dev_init_lock + + Possible unsafe locking scenario: + + CPU0 CPU1 + ---- ---- + lock(&devinfo->dev_init_lock); + lock(brcmf_driver_work); + lock(&devinfo->dev_init_lock); + lock((wq_completion)"events"); + + *** DEADLOCK *** + +1 lock held by kworker/0:2/434: + #0: 18d5dcdf (&devinfo->dev_init_lock){+.+.}, at: brcmf_usb_probe+0x78/0x550 [brcmfmac] + +stack backtrace: +CPU: 0 PID: 434 Comm: kworker/0:2 Not tainted 4.19.23-00084-g454a789-dirty #123 +Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree) +Workqueue: events request_firmware_work_func +[<8011237c>] (unwind_backtrace) from [<8010d74c>] (show_stack+0x10/0x14) +[<8010d74c>] (show_stack) from [<809c4324>] (dump_stack+0xa8/0xd4) +[<809c4324>] (dump_stack) from [<80172838>] (print_circular_bug+0x210/0x330) +[<80172838>] (print_circular_bug) from [<80175940>] (__lock_acquire+0x160c/0x1a30) +[<80175940>] (__lock_acquire) from [<8017671c>] (lock_acquire+0xe0/0x268) +[<8017671c>] (lock_acquire) from [<80141404>] (process_one_work+0x1b8/0x808) +[<80141404>] (process_one_work) from [<80141a80>] (worker_thread+0x2c/0x564) +[<80141a80>] (worker_thread) from [<80147bcc>] (kthread+0x13c/0x16c) +[<80147bcc>] (kthread) from [<801010b4>] (ret_from_fork+0x14/0x20) +Exception stack(0xed1d9fb0 to 0xed1d9ff8) +9fa0: 00000000 00000000 00000000 00000000 +9fc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 +9fe0: 00000000 00000000 00000000 00000000 00000013 00000000 + +Signed-off-by: Piotr Figiel +Signed-off-by: Kalle Valo +--- + .../wireless/broadcom/brcm80211/brcmfmac/usb.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/usb.c +@@ -160,7 +160,7 @@ struct brcmf_usbdev_info { + + struct usb_device *usbdev; + struct device *dev; +- struct mutex dev_init_lock; ++ struct completion dev_init_done; + + int ctl_in_pipe, ctl_out_pipe; + struct urb *ctl_urb; /* URB for control endpoint */ +@@ -1194,11 +1194,11 @@ static void brcmf_usb_probe_phase2(struc + if (ret) + goto error; + +- mutex_unlock(&devinfo->dev_init_lock); ++ complete(&devinfo->dev_init_done); + return; + error: + brcmf_dbg(TRACE, "failed: dev=%s, err=%d\n", dev_name(dev), ret); +- mutex_unlock(&devinfo->dev_init_lock); ++ complete(&devinfo->dev_init_done); + device_release_driver(dev); + } + +@@ -1266,7 +1266,7 @@ static int brcmf_usb_probe_cb(struct brc + if (ret) + goto fail; + /* we are done */ +- mutex_unlock(&devinfo->dev_init_lock); ++ complete(&devinfo->dev_init_done); + return 0; + } + bus->chip = bus_pub->devid; +@@ -1326,11 +1326,10 @@ brcmf_usb_probe(struct usb_interface *in + + devinfo->usbdev = usb; + devinfo->dev = &usb->dev; +- /* Take an init lock, to protect for disconnect while still loading. ++ /* Init completion, to protect for disconnect while still loading. + * Necessary because of the asynchronous firmware load construction + */ +- mutex_init(&devinfo->dev_init_lock); +- mutex_lock(&devinfo->dev_init_lock); ++ init_completion(&devinfo->dev_init_done); + + usb_set_intfdata(intf, devinfo); + +@@ -1408,7 +1407,7 @@ brcmf_usb_probe(struct usb_interface *in + return 0; + + fail: +- mutex_unlock(&devinfo->dev_init_lock); ++ complete(&devinfo->dev_init_done); + kfree(devinfo); + usb_set_intfdata(intf, NULL); + return ret; +@@ -1423,7 +1422,7 @@ brcmf_usb_disconnect(struct usb_interfac + devinfo = (struct brcmf_usbdev_info *)usb_get_intfdata(intf); + + if (devinfo) { +- mutex_lock(&devinfo->dev_init_lock); ++ wait_for_completion(&devinfo->dev_init_done); + /* Make sure that devinfo still exists. Firmware probe routines + * may have released the device and cleared the intfdata. + */ diff --git a/package/kernel/mac80211/patches/brcm/365-v5.2-brcmfmac-fix-missing-checks-for-kmemdup.patch b/package/kernel/mac80211/patches/brcm/365-v5.2-brcmfmac-fix-missing-checks-for-kmemdup.patch new file mode 100644 index 0000000000..87974dcc6f --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/365-v5.2-brcmfmac-fix-missing-checks-for-kmemdup.patch @@ -0,0 +1,35 @@ +From 46953f97224d56a12ccbe9c6acaa84ca0dab2780 Mon Sep 17 00:00:00 2001 +From: Kangjie Lu +Date: Fri, 15 Mar 2019 12:04:32 -0500 +Subject: [PATCH] brcmfmac: fix missing checks for kmemdup + +In case kmemdup fails, the fix sets conn_info->req_ie_len and +conn_info->resp_ie_len to zero to avoid buffer overflows. + +Signed-off-by: Kangjie Lu +Acked-by: Arend van Spriel +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +@@ -5456,6 +5456,8 @@ static s32 brcmf_get_assoc_ies(struct br + conn_info->req_ie = + kmemdup(cfg->extra_buf, conn_info->req_ie_len, + GFP_KERNEL); ++ if (!conn_info->req_ie) ++ conn_info->req_ie_len = 0; + } else { + conn_info->req_ie_len = 0; + conn_info->req_ie = NULL; +@@ -5472,6 +5474,8 @@ static s32 brcmf_get_assoc_ies(struct br + conn_info->resp_ie = + kmemdup(cfg->extra_buf, conn_info->resp_ie_len, + GFP_KERNEL); ++ if (!conn_info->resp_ie) ++ conn_info->resp_ie_len = 0; + } else { + conn_info->resp_ie_len = 0; + conn_info->resp_ie = NULL; diff --git a/package/kernel/mac80211/patches/brcm/366-v5.2-brcmfmac-Use-struct_size-in-kzalloc.patch b/package/kernel/mac80211/patches/brcm/366-v5.2-brcmfmac-Use-struct_size-in-kzalloc.patch new file mode 100644 index 0000000000..d00a9d7964 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/366-v5.2-brcmfmac-Use-struct_size-in-kzalloc.patch @@ -0,0 +1,53 @@ +From 0cf83903aad03dc7f444a47990def48c4a9d3276 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Wed, 3 Apr 2019 11:46:11 -0500 +Subject: [PATCH] brcmfmac: Use struct_size() in kzalloc() + +One of the more common cases of allocation size calculations is finding +the size of a structure that has a zero-sized array at the end, along +with memory for some number of elements for that array. For example: + +struct foo { + int stuff; + struct boo entry[]; +}; + +size = sizeof(struct foo) + count * sizeof(struct boo); +instance = kzalloc(size, GFP_KERNEL) + +Instead of leaving these open-coded and prone to type mistakes, we can +now use the new struct_size() helper: + +instance = kzalloc(struct_size(instance, entry, count), GFP_KERNEL) + +Notice that, in this case, variable reqsz is not necessary, +hence it is removed. + +This code was detected with the help of Coccinelle. + +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +@@ -711,7 +711,6 @@ brcmf_fw_alloc_request(u32 chip, u32 chi + size_t mp_path_len; + u32 i, j; + char end = '\0'; +- size_t reqsz; + + for (i = 0; i < table_size; i++) { + if (mapping_table[i].chipid == chip && +@@ -726,8 +725,7 @@ brcmf_fw_alloc_request(u32 chip, u32 chi + return NULL; + } + +- reqsz = sizeof(*fwreq) + n_fwnames * sizeof(struct brcmf_fw_item); +- fwreq = kzalloc(reqsz, GFP_KERNEL); ++ fwreq = kzalloc(struct_size(fwreq, items, n_fwnames), GFP_KERNEL); + if (!fwreq) + return NULL; + diff --git a/package/kernel/mac80211/patches/brcm/367-v5.2-brcmfmac-Loading-the-correct-firmware-for-brcm43456.patch b/package/kernel/mac80211/patches/brcm/367-v5.2-brcmfmac-Loading-the-correct-firmware-for-brcm43456.patch new file mode 100644 index 0000000000..d19284e672 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/367-v5.2-brcmfmac-Loading-the-correct-firmware-for-brcm43456.patch @@ -0,0 +1,35 @@ +From e3062e05e1cfe378bb9b3fa0bef46711372bcf13 Mon Sep 17 00:00:00 2001 +From: Ondrej Jirman +Date: Sat, 6 Apr 2019 01:45:13 +0200 +Subject: [PATCH] brcmfmac: Loading the correct firmware for brcm43456 + +SDIO based brcm43456 is currently misdetected as brcm43455 and the wrong +firmware name is used. Correct the detection and load the correct +firmware file. Chiprev for brcm43456 is "9". + +Signed-off-by: Ondrej Jirman +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c +@@ -622,6 +622,7 @@ BRCMF_FW_DEF(43430A0, "brcmfmac43430a0-s + /* Note the names are not postfixed with a1 for backward compatibility */ + BRCMF_FW_DEF(43430A1, "brcmfmac43430-sdio"); + BRCMF_FW_DEF(43455, "brcmfmac43455-sdio"); ++BRCMF_FW_DEF(43456, "brcmfmac43456-sdio"); + BRCMF_FW_DEF(4354, "brcmfmac4354-sdio"); + BRCMF_FW_DEF(4356, "brcmfmac4356-sdio"); + BRCMF_FW_DEF(4373, "brcmfmac4373-sdio"); +@@ -642,7 +643,8 @@ static const struct brcmf_firmware_mappi + BRCMF_FW_ENTRY(BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, 4339), + BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0x00000001, 43430A0), + BRCMF_FW_ENTRY(BRCM_CC_43430_CHIP_ID, 0xFFFFFFFE, 43430A1), +- BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, 43455), ++ BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0x00000200, 43456), ++ BRCMF_FW_ENTRY(BRCM_CC_4345_CHIP_ID, 0xFFFFFDC0, 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), diff --git a/package/kernel/mac80211/patches/brcm/368-v5.2-brcmfmac-fix-leak-of-mypkt-on-error-return-path.patch b/package/kernel/mac80211/patches/brcm/368-v5.2-brcmfmac-fix-leak-of-mypkt-on-error-return-path.patch new file mode 100644 index 0000000000..a9a9d74c10 --- /dev/null +++ b/package/kernel/mac80211/patches/brcm/368-v5.2-brcmfmac-fix-leak-of-mypkt-on-error-return-path.patch @@ -0,0 +1,41 @@ +From a927e8d8ab57e696800e20cf09a72b7dfe3bbebb Mon Sep 17 00:00:00 2001 +From: Colin Ian King +Date: Tue, 9 Apr 2019 12:43:33 +0100 +Subject: [PATCH] brcmfmac: fix leak of mypkt on error return path + +Currently if the call to brcmf_sdiod_set_backplane_window fails then +error return path leaks mypkt. Fix this by returning by a new +error path labelled 'out' that calls brcmu_pkt_buf_free_skb to free +mypkt. Also remove redundant check on err before calling +brcmf_sdiod_skbuff_write. + +Addresses-Coverity: ("Resource Leak") +Fixes: a7c3aa1509e2 ("brcmfmac: Remove brcmf_sdiod_addrprep()") +Signed-off-by: Colin Ian King +Reviewed-by: Mukesh Ojha +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +--- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c ++++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/bcmsdh.c +@@ -617,15 +617,13 @@ int brcmf_sdiod_send_buf(struct brcmf_sd + + err = brcmf_sdiod_set_backplane_window(sdiodev, addr); + if (err) +- return err; ++ goto out; + + addr &= SBSDIO_SB_OFT_ADDR_MASK; + addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; + +- if (!err) +- err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, addr, +- mypkt); +- ++ err = brcmf_sdiod_skbuff_write(sdiodev, sdiodev->func2, addr, mypkt); ++out: + brcmu_pkt_buf_free_skb(mypkt); + + return err; diff --git a/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch b/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch index b3f30943ab..6861667b2b 100644 --- a/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch +++ b/package/kernel/mac80211/patches/brcm/810-b43-gpio-mask-module-option.patch @@ -10,7 +10,7 @@ struct b43_phy phy; --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c -@@ -72,6 +72,11 @@ MODULE_FIRMWARE("b43/ucode40.fw"); +@@ -85,6 +85,11 @@ MODULE_FIRMWARE("b43/ucode40.fw"); MODULE_FIRMWARE("b43/ucode42.fw"); MODULE_FIRMWARE("b43/ucode9.fw"); @@ -22,7 +22,7 @@ static int modparam_bad_frames_preempt; module_param_named(bad_frames_preempt, modparam_bad_frames_preempt, int, 0444); MODULE_PARM_DESC(bad_frames_preempt, -@@ -2867,10 +2872,10 @@ static int b43_gpio_init(struct b43_wlde +@@ -2892,10 +2897,10 @@ static int b43_gpio_init(struct b43_wlde u32 mask, set; b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); diff --git a/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch b/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch index a8dbefb5d9..5eb1dc550a 100644 --- a/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch +++ b/package/kernel/mac80211/patches/brcm/811-b43_no_pio.patch @@ -11,7 +11,7 @@ b43-$(CPTCFG_B43_LEDS) += leds.o --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c -@@ -2000,10 +2000,12 @@ static void b43_do_interrupt_thread(stru +@@ -2018,10 +2018,12 @@ static void b43_do_interrupt_thread(stru dma_reason[0], dma_reason[1], dma_reason[2], dma_reason[3], dma_reason[4], dma_reason[5]); @@ -75,7 +75,7 @@ #endif /* B43_PIO_H_ */ --- a/drivers/net/wireless/broadcom/b43/Kconfig +++ b/drivers/net/wireless/broadcom/b43/Kconfig -@@ -100,7 +100,7 @@ config B43_BCMA_PIO +@@ -98,7 +98,7 @@ config B43_BCMA_PIO default y config B43_PIO diff --git a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch index cd7b7583c9..d643d2f82c 100644 --- a/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch +++ b/package/kernel/mac80211/patches/brcm/812-b43-add-antenna-control.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c -@@ -1642,7 +1642,7 @@ static void b43_write_beacon_template(st +@@ -1658,7 +1658,7 @@ static void b43_write_beacon_template(st len, ram_offset, shm_size_offset, rate); /* Write the PHY TX control parameters. */ @@ -9,7 +9,7 @@ antenna = b43_antenna_to_phyctl(antenna); ctl = b43_shm_read16(dev, B43_SHM_SHARED, B43_SHM_SH_BEACPHYCTL); /* We can't send beacons with short preamble. Would get PHY errors. */ -@@ -3282,8 +3282,8 @@ static int b43_chip_init(struct b43_wlde +@@ -3307,8 +3307,8 @@ static int b43_chip_init(struct b43_wlde /* Select the antennae */ if (phy->ops->set_rx_antenna) @@ -20,7 +20,7 @@ if (phy->type == B43_PHYTYPE_B) { value16 = b43_read16(dev, 0x005E); -@@ -3983,7 +3983,6 @@ static int b43_op_config(struct ieee8021 +@@ -4008,7 +4008,6 @@ static int b43_op_config(struct ieee8021 struct b43_wldev *dev = wl->current_dev; struct b43_phy *phy = &dev->phy; struct ieee80211_conf *conf = &hw->conf; @@ -28,7 +28,7 @@ int err = 0; mutex_lock(&wl->mutex); -@@ -4026,11 +4025,9 @@ static int b43_op_config(struct ieee8021 +@@ -4051,11 +4050,9 @@ static int b43_op_config(struct ieee8021 } /* Antennas for RX and management frame TX. */ @@ -42,7 +42,7 @@ if (wl->radio_enabled != phy->radio_on) { if (wl->radio_enabled) { -@@ -5174,6 +5171,47 @@ static int b43_op_get_survey(struct ieee +@@ -5199,6 +5196,47 @@ static int b43_op_get_survey(struct ieee return 0; } @@ -90,7 +90,7 @@ static const struct ieee80211_ops b43_hw_ops = { .tx = b43_op_tx, .conf_tx = b43_op_conf_tx, -@@ -5195,6 +5233,8 @@ static const struct ieee80211_ops b43_hw +@@ -5220,6 +5258,8 @@ static const struct ieee80211_ops b43_hw .sw_scan_complete = b43_op_sw_scan_complete_notifier, .get_survey = b43_op_get_survey, .rfkill_poll = b43_rfkill_poll, @@ -99,7 +99,7 @@ }; /* Hard-reset the chip. Do not call this directly. -@@ -5496,6 +5536,8 @@ static int b43_one_core_attach(struct b4 +@@ -5523,6 +5563,8 @@ static int b43_one_core_attach(struct b4 if (!wldev) goto out; @@ -108,14 +108,14 @@ wldev->use_pio = b43_modparam_pio; wldev->dev = dev; wldev->wl = wl; -@@ -5590,6 +5632,9 @@ static struct b43_wl *b43_wireless_init( +@@ -5617,6 +5659,9 @@ static struct b43_wl *b43_wireless_init( wiphy_ext_feature_set(hw->wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST); + hw->wiphy->available_antennas_rx = 0x3; + hw->wiphy->available_antennas_tx = 0x3; + - wl->hw_registered = false; + wl->hw_registred = false; hw->max_rates = 2; SET_IEEE80211_DEV(hw, dev->dev); --- a/drivers/net/wireless/broadcom/b43/b43.h diff --git a/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch b/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch index 2aa7612878..03f4524c88 100644 --- a/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch +++ b/package/kernel/mac80211/patches/brcm/814-b43-only-use-gpio-0-1-for-led.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c -@@ -2884,6 +2884,14 @@ static int b43_gpio_init(struct b43_wlde +@@ -2909,6 +2909,14 @@ static int b43_gpio_init(struct b43_wlde } else if (dev->dev->chip_id == 0x5354) { /* Don't allow overtaking buttons GPIOs */ set &= 0x2; /* 0x2 is LED GPIO on BCM5354 */ diff --git a/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch b/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch index a8eae19413..f07151aa4e 100644 --- a/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch +++ b/package/kernel/mac80211/patches/brcm/815-b43-always-take-overlapping-devs.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c -@@ -114,7 +114,7 @@ static int b43_modparam_pio = 0; +@@ -127,7 +127,7 @@ static int b43_modparam_pio = 0; module_param_named(pio, b43_modparam_pio, int, 0644); MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); diff --git a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch index 000333c928..d431d7e700 100644 --- a/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch +++ b/package/kernel/mac80211/patches/brcm/860-brcmfmac-register-wiphy-s-during-module_init.patch @@ -13,7 +13,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/core.c -@@ -1472,6 +1472,7 @@ int __init brcmf_core_init(void) +@@ -1436,6 +1436,7 @@ int __init brcmf_core_init(void) { if (!schedule_work(&brcmf_driver_work)) return -EBUSY; @@ -23,7 +23,7 @@ Signed-off-by: Rafał Miłecki } --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/firmware.c -@@ -431,6 +431,7 @@ struct brcmf_fw { +@@ -442,6 +442,7 @@ struct brcmf_fw { struct brcmf_fw_request *req; u32 curpos; void (*done)(struct device *dev, int err, struct brcmf_fw_request *req); @@ -31,7 +31,7 @@ Signed-off-by: Rafał Miłecki }; static void brcmf_fw_request_done(const struct firmware *fw, void *ctx); -@@ -638,6 +639,8 @@ static void brcmf_fw_request_done(const +@@ -649,6 +650,8 @@ static void brcmf_fw_request_done(const fwctx->req = NULL; } fwctx->done(fwctx->dev, ret, fwctx->req); @@ -40,7 +40,7 @@ Signed-off-by: Rafał Miłecki kfree(fwctx); } -@@ -662,6 +665,8 @@ int brcmf_fw_get_firmwares(struct device +@@ -673,6 +676,8 @@ int brcmf_fw_get_firmwares(struct device { struct brcmf_fw_item *first = &req->items[0]; struct brcmf_fw *fwctx; @@ -49,7 +49,7 @@ Signed-off-by: Rafał Miłecki int ret; brcmf_dbg(TRACE, "enter: dev=%s\n", dev_name(dev)); -@@ -678,6 +683,9 @@ int brcmf_fw_get_firmwares(struct device +@@ -689,6 +694,9 @@ int brcmf_fw_get_firmwares(struct device fwctx->dev = dev; fwctx->req = req; fwctx->done = fw_cb; @@ -59,7 +59,7 @@ Signed-off-by: Rafał Miłecki ret = request_firmware_nowait(THIS_MODULE, true, first->path, fwctx->dev, GFP_KERNEL, fwctx, -@@ -685,6 +693,12 @@ int brcmf_fw_get_firmwares(struct device +@@ -696,6 +704,12 @@ int brcmf_fw_get_firmwares(struct device if (ret < 0) brcmf_fw_request_done(NULL, fwctx); diff --git a/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch b/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch index 5f0fa7faab..45cfb1ddbf 100644 --- a/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch +++ b/package/kernel/mac80211/patches/brcm/861-brcmfmac-workaround-bug-with-some-inconsistent-BSSes.patch @@ -10,7 +10,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -628,8 +628,36 @@ static struct wireless_dev *brcmf_cfg802 +@@ -620,8 +620,36 @@ static struct wireless_dev *brcmf_cfg802 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy); struct brcmf_pub *drvr = cfg->pub; struct wireless_dev *wdev; diff --git a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch index 6412653a3a..5cbc48f76a 100644 --- a/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch +++ b/package/kernel/mac80211/patches/brcm/862-brcmfmac-Disable-power-management.patch @@ -14,7 +14,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c -@@ -2795,6 +2795,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip +@@ -2774,6 +2774,10 @@ brcmf_cfg80211_set_power_mgmt(struct wip * preference in cfg struct to apply this to * FW later while initializing the dongle */ diff --git a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch index 2613171a86..5bb7015810 100644 --- a/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch +++ b/package/kernel/mac80211/patches/brcm/863-brcmfmac-add-in-driver-tables-with-country-codes.patch @@ -12,7 +12,7 @@ Signed-off-by: Rafał Miłecki --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/of.c -@@ -12,6 +12,36 @@ +@@ -23,6 +23,36 @@ #include "common.h" #include "of.h" @@ -49,7 +49,7 @@ Signed-off-by: Rafał Miłecki void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type, struct brcmf_mp_device *settings) { -@@ -30,6 +60,8 @@ void brcmf_of_probe(struct device *dev, +@@ -41,6 +71,8 @@ void brcmf_of_probe(struct device *dev, of_node_put(root); } diff --git a/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch b/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch index fe79c40c11..249c3036be 100644 --- a/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch +++ b/package/kernel/mac80211/patches/brcm/864-brcmfmac-do-not-use-internal-roaming-engine-by-default.patch @@ -9,7 +9,7 @@ Signed-off-by: Phil Elwell --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/common.c -@@ -59,7 +59,11 @@ static int brcmf_fcmode; +@@ -70,7 +70,11 @@ static int brcmf_fcmode; module_param_named(fcmode, brcmf_fcmode, int, 0); MODULE_PARM_DESC(fcmode, "Mode of firmware signalled flow control"); diff --git a/package/kernel/mac80211/patches/brcm/109-v5.4-brcmfmac-get-chip-s-default-RAM-info-during-PCIe-set.patch b/package/kernel/mac80211/patches/brcm/865-brcmfmac-get-RAM-info-right-before-downloading-PCIe-.patch similarity index 59% rename from package/kernel/mac80211/patches/brcm/109-v5.4-brcmfmac-get-chip-s-default-RAM-info-during-PCIe-set.patch rename to package/kernel/mac80211/patches/brcm/865-brcmfmac-get-RAM-info-right-before-downloading-PCIe-.patch index b04e78c70e..88b9807311 100644 --- a/package/kernel/mac80211/patches/brcm/109-v5.4-brcmfmac-get-chip-s-default-RAM-info-during-PCIe-set.patch +++ b/package/kernel/mac80211/patches/brcm/865-brcmfmac-get-RAM-info-right-before-downloading-PCIe-.patch @@ -1,29 +1,19 @@ -From 82f93cf46d6007ffa003b2d4a2834563b6b84d21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= -Date: Thu, 29 Aug 2019 10:27:01 +0200 -Subject: [PATCH] brcmfmac: get chip's default RAM info during PCIe setup +Subject: [PATCH] brcmfmac: get RAM info right before downloading PCIe firmware MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -Getting RAM info just once per driver's lifetime (during chip -recognition) is not enough as it may get adjusted later (depending on -the used firmware). Subsequent inits may load different firmwares so a -full RAM recognition is required on every PCIe setup. This is especially -important since implementing hardware reset on a firmware crash. +It's important as brcmf_chip_get_raminfo() also makes sure that memory +is properly setup. Without it the firmware could report invalid RAM +address like 0x04000001. -Moreover calling brcmf_chip_get_raminfo() makes sure that RAM core is -up. It's important as having BCMA_CORE_SYS_MEM down on BCM4366 was -resulting in firmware failing to initialize and following error: -[ 65.657546] brcmfmac 0000:01:00.0: brcmf_pcie_download_fw_nvram: Invalid shared RAM address 0x04000001 +During a normal brcmfmac lifetime brcmf_chip_get_raminfo() is called on +probe by the brcmf_chip_recognition(). This change allows implementing +further improvements like handling errors by resetting a device with +the brcmf_pcie_reset_device() and redownloading a firmware afterwards. -This change makes brcmf_chip_get_raminfo() call during chip recognition -redundant for PCIe devices but SDIO and USB still need it and it's a -very small overhead anyway. - -Fixes: 4684997d9eea ("brcmfmac: reset PCIe bus on a firmware crash") Signed-off-by: Rafał Miłecki -Signed-off-by: Kalle Valo --- drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c | 6 ++++-- drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h | 1 + @@ -32,7 +22,7 @@ Signed-off-by: Kalle Valo --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.c -@@ -696,8 +696,10 @@ static u32 brcmf_chip_tcm_rambase(struct +@@ -707,8 +707,10 @@ static u32 brcmf_chip_tcm_rambase(struct return 0; } @@ -44,7 +34,7 @@ Signed-off-by: Kalle Valo struct brcmf_core_priv *mem_core; struct brcmf_core *mem; -@@ -979,7 +981,7 @@ static int brcmf_chip_recognition(struct +@@ -990,7 +992,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_set_passive(&ci->pub); } @@ -55,7 +45,7 @@ Signed-off-by: Kalle Valo static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id) --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/chip.h -@@ -69,6 +69,7 @@ struct brcmf_buscore_ops { +@@ -80,6 +80,7 @@ struct brcmf_buscore_ops { void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec); }; @@ -65,7 +55,7 @@ Signed-off-by: Kalle Valo void brcmf_chip_detach(struct brcmf_chip *chip); --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/pcie.c -@@ -1770,6 +1770,12 @@ static void brcmf_pcie_setup(struct devi +@@ -1762,6 +1762,12 @@ static void brcmf_pcie_setup(struct devi nvram_len = fwreq->items[BRCMF_PCIE_FW_NVRAM].nv_data.len; kfree(fwreq); diff --git a/package/kernel/mac80211/patches/build/002-change_allconfig.patch b/package/kernel/mac80211/patches/build/002-change_allconfig.patch index 368725d0c3..a071ae6370 100644 --- a/package/kernel/mac80211/patches/build/002-change_allconfig.patch +++ b/package/kernel/mac80211/patches/build/002-change_allconfig.patch @@ -1,6 +1,6 @@ --- a/kconf/conf.c +++ b/kconf/conf.c -@@ -598,40 +598,12 @@ int main(int ac, char **av) +@@ -594,40 +594,12 @@ int main(int ac, char **av) case oldconfig: case listnewconfig: case olddefconfig: diff --git a/package/kernel/mac80211/patches/build/015-ipw200-mtu.patch b/package/kernel/mac80211/patches/build/015-ipw200-mtu.patch index 68dd821331..d57d821fea 100644 --- a/package/kernel/mac80211/patches/build/015-ipw200-mtu.patch +++ b/package/kernel/mac80211/patches/build/015-ipw200-mtu.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c -@@ -11481,6 +11481,15 @@ static const struct attribute_group ipw_ +@@ -11498,6 +11498,15 @@ static const struct attribute_group ipw_ .attrs = ipw_sysfs_entries, }; @@ -16,7 +16,7 @@ #ifdef CPTCFG_IPW2200_PROMISCUOUS static int ipw_prom_open(struct net_device *dev) { -@@ -11529,15 +11538,6 @@ static netdev_tx_t ipw_prom_hard_start_x +@@ -11546,15 +11555,6 @@ static netdev_tx_t ipw_prom_hard_start_x return NETDEV_TX_OK; } diff --git a/package/kernel/mac80211/patches/build/050-lib80211_option.patch b/package/kernel/mac80211/patches/build/050-lib80211_option.patch index 721e59661d..6282cdab5f 100644 --- a/package/kernel/mac80211/patches/build/050-lib80211_option.patch +++ b/package/kernel/mac80211/patches/build/050-lib80211_option.patch @@ -1,6 +1,6 @@ --- a/net/wireless/Kconfig +++ b/net/wireless/Kconfig -@@ -186,7 +186,7 @@ config CFG80211_WEXT_EXPORT +@@ -185,7 +185,7 @@ config CFG80211_WEXT_EXPORT endif # CFG80211 config LIB80211 @@ -9,14 +9,13 @@ depends on m default n help -@@ -196,16 +196,16 @@ config LIB80211 +@@ -195,15 +195,15 @@ config LIB80211 Drivers should select this themselves if needed. config LIB80211_CRYPT_WEP - tristate + tristate "lib80211 WEP support" depends on m - select BPAUTO_CRYPTO_LIB_ARC4 config LIB80211_CRYPT_CCMP - tristate @@ -27,5 +26,5 @@ - tristate + tristate "lib80211 TKIP support" depends on m - select BPAUTO_CRYPTO_LIB_ARC4 + config LIB80211_DEBUG diff --git a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch index dce99bbbdb..06636060f7 100644 --- a/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch +++ b/package/kernel/mac80211/patches/build/060-no_local_ssb_bcma.patch @@ -1,9 +1,9 @@ --- a/local-symbols +++ b/local-symbols -@@ -412,43 +412,6 @@ USB_SIERRA_NET= +@@ -396,43 +396,6 @@ USB_IPHETH= + USB_SIERRA_NET= USB_VL600= USB_NET_CH9200= - USB_NET_AQC111= -SSB_POSSIBLE= -SSB= -SSB_SPROM= @@ -46,7 +46,7 @@ USB_WDM= --- a/drivers/net/wireless/broadcom/b43/Kconfig +++ b/drivers/net/wireless/broadcom/b43/Kconfig -@@ -63,21 +63,21 @@ endchoice +@@ -61,21 +61,21 @@ endchoice config B43_PCI_AUTOSELECT bool depends on B43 && SSB_PCIHOST_POSSIBLE @@ -72,7 +72,7 @@ ---help--- Broadcom 43xx device support for Soft-MAC SDIO devices. -@@ -96,13 +96,13 @@ config B43_SDIO +@@ -94,13 +94,13 @@ config B43_SDIO config B43_BCMA_PIO bool depends on B43 && B43_BCMA @@ -90,7 +90,7 @@ config B43_PHY_G --- a/drivers/net/wireless/broadcom/b43/main.c +++ b/drivers/net/wireless/broadcom/b43/main.c -@@ -2851,7 +2851,7 @@ static struct ssb_device *b43_ssb_gpio_d +@@ -2876,7 +2876,7 @@ static struct ssb_device *b43_ssb_gpio_d { struct ssb_bus *bus = dev->dev->sdev->bus; @@ -99,7 +99,7 @@ return (bus->chipco.dev ? bus->chipco.dev : bus->pcicore.dev); #else return bus->chipco.dev; -@@ -4868,7 +4868,7 @@ static int b43_wireless_core_init(struct +@@ -4893,7 +4893,7 @@ static int b43_wireless_core_init(struct } if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ @@ -110,7 +110,7 @@ dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) --- a/drivers/net/wireless/broadcom/b43legacy/Kconfig +++ b/drivers/net/wireless/broadcom/b43legacy/Kconfig -@@ -3,7 +3,7 @@ config B43LEGACY +@@ -2,7 +2,7 @@ config B43LEGACY tristate "Broadcom 43xx-legacy wireless support (mac80211 stack)" depends on m depends on SSB_POSSIBLE && MAC80211 && HAS_DMA @@ -119,7 +119,7 @@ depends on FW_LOADER ---help--- b43legacy is a driver for 802.11b devices from Broadcom (BCM4301 and -@@ -25,15 +25,15 @@ config B43LEGACY +@@ -24,15 +24,15 @@ config B43LEGACY config B43LEGACY_PCI_AUTOSELECT bool depends on B43LEGACY && SSB_PCIHOST_POSSIBLE @@ -140,7 +140,7 @@ # LED support --- a/drivers/net/wireless/broadcom/b43legacy/main.c +++ b/drivers/net/wireless/broadcom/b43legacy/main.c -@@ -1905,7 +1905,7 @@ static int b43legacy_gpio_init(struct b4 +@@ -1937,7 +1937,7 @@ static int b43legacy_gpio_init(struct b4 if (dev->dev->id.revision >= 2) mask |= 0x0010; /* FIXME: This is redundant. */ @@ -149,7 +149,7 @@ pcidev = bus->pcicore.dev; #endif gpiodev = bus->chipco.dev ? : pcidev; -@@ -1924,7 +1924,7 @@ static void b43legacy_gpio_cleanup(struc +@@ -1956,7 +1956,7 @@ static void b43legacy_gpio_cleanup(struc struct ssb_bus *bus = dev->dev->bus; struct ssb_device *gpiodev, *pcidev = NULL; @@ -181,7 +181,7 @@ obj-$(CPTCFG_BRCMSMAC) += brcmsmac.o --- a/drivers/net/wireless/broadcom/brcm80211/Kconfig +++ b/drivers/net/wireless/broadcom/brcm80211/Kconfig -@@ -8,7 +8,7 @@ config BRCMSMAC +@@ -7,7 +7,7 @@ config BRCMSMAC depends on m depends on MAC80211 depends on BCMA_POSSIBLE @@ -192,10 +192,10 @@ select BRCMUTIL --- a/Kconfig.local +++ b/Kconfig.local -@@ -1240,117 +1240,6 @@ config BACKPORTED_USB_NET_CH9200 - config BACKPORTED_USB_NET_AQC111 +@@ -1192,117 +1192,6 @@ config BACKPORTED_USB_VL600 + config BACKPORTED_USB_NET_CH9200 tristate - default USB_NET_AQC111 + default USB_NET_CH9200 -config BACKPORTED_SSB_POSSIBLE - tristate - default SSB_POSSIBLE diff --git a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch index cfa40e1bd2..f3e311a2e9 100644 --- a/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch +++ b/package/kernel/mac80211/patches/mwl/700-mwl8k-missing-pci-id-for-WNR854T.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -5694,6 +5694,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") +@@ -5686,6 +5686,7 @@ MODULE_FIRMWARE("mwl8k/fmimage_8366.fw") MODULE_FIRMWARE(MWL8K_8366_AP_FW(MWL8K_8366_AP_FW_API)); static const struct pci_device_id mwl8k_pci_id_table[] = { diff --git a/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch b/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch index 90adb66bb1..c3e6db8f05 100644 --- a/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch +++ b/package/kernel/mac80211/patches/mwl/801-libertas-configure-sysfs-links.patch @@ -11,7 +11,7 @@ err_wiphy_new: --- a/drivers/net/wireless/marvell/libertas/main.c +++ b/drivers/net/wireless/marvell/libertas/main.c -@@ -935,6 +935,7 @@ struct lbs_private *lbs_add_card(void *c +@@ -930,6 +930,7 @@ struct lbs_private *lbs_add_card(void *c goto err_adapter; } diff --git a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch index f3130f7ae7..61a6c4c70f 100644 --- a/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch +++ b/package/kernel/mac80211/patches/mwl/940-mwl8k_init_devices_synchronously.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/marvell/mwl8k.c +++ b/drivers/net/wireless/marvell/mwl8k.c -@@ -6279,6 +6279,8 @@ static int mwl8k_probe(struct pci_dev *p +@@ -6271,6 +6271,8 @@ static int mwl8k_probe(struct pci_dev *p priv->running_bsses = 0; @@ -9,7 +9,7 @@ return rc; err_stop_firmware: -@@ -6312,8 +6314,6 @@ static void mwl8k_remove(struct pci_dev +@@ -6304,8 +6306,6 @@ static void mwl8k_remove(struct pci_dev return; priv = hw->priv; diff --git a/package/kernel/mac80211/patches/mwl/941-mwl8k-Fix-rate_idx-underflow.patch b/package/kernel/mac80211/patches/mwl/941-mwl8k-Fix-rate_idx-underflow.patch new file mode 100644 index 0000000000..4f4812be80 --- /dev/null +++ b/package/kernel/mac80211/patches/mwl/941-mwl8k-Fix-rate_idx-underflow.patch @@ -0,0 +1,80 @@ +From b897577af85bb5e5638efa780bc3716fae5212d3 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Petr=20=C5=A0tetiar?= +Date: Mon, 8 Apr 2019 09:45:56 +0200 +Subject: [PATCH] mwl8k: Fix rate_idx underflow +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It was reported on OpenWrt bug tracking system[1], that several users +are affected by the endless reboot of their routers if they configure +5GHz interface with channel 44 or 48. + +The reboot loop is caused by the following excessive number of WARN_ON +messages: + + WARNING: CPU: 0 PID: 0 at backports-4.19.23-1/net/mac80211/rx.c:4516 + ieee80211_rx_napi+0x1fc/0xa54 [mac80211] + +as the messages are being correctly emitted by the following guard: + + case RX_ENC_LEGACY: + if (WARN_ON(status->rate_idx >= sband->n_bitrates)) + +as the rate_idx is in this case erroneously set to 251 (0xfb). This fix +simply converts previously used magic number to proper constant and +guards against substraction which is leading to the currently observed +underflow. + +1. https://bugs.openwrt.org/index.php?do=details&task_id=2218 + +Fixes: 854783444bab ("mwl8k: properly set receive status rate index on 5 GHz receive") +Cc: +Tested-by: Eubert Bao +Reported-by: Eubert Bao +Signed-off-by: Petr Štetiar +--- + drivers/net/wireless/marvell/mwl8k.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/drivers/net/wireless/marvell/mwl8k.c b/drivers/net/wireless/marvell/mwl8k.c +index 8e4e9b6..ffc565a 100644 +--- a/drivers/net/wireless/marvell/mwl8k.c ++++ b/drivers/net/wireless/marvell/mwl8k.c +@@ -441,6 +441,9 @@ struct mwl8k_sta { + #define MWL8K_CMD_UPDATE_STADB 0x1123 + #define MWL8K_CMD_BASTREAM 0x1125 + ++#define MWL8K_LEGACY_5G_RATE_OFFSET \ ++ (ARRAY_SIZE(mwl8k_rates_24) - ARRAY_SIZE(mwl8k_rates_50)) ++ + static const char *mwl8k_cmd_name(__le16 cmd, char *buf, int bufsize) + { + u16 command = le16_to_cpu(cmd); +@@ -1016,8 +1019,9 @@ static void mwl8k_rxd_ap_refill(void *_rxd, dma_addr_t addr, int len) + + if (rxd->channel > 14) { + status->band = NL80211_BAND_5GHZ; +- if (!(status->encoding == RX_ENC_HT)) +- status->rate_idx -= 5; ++ if (!(status->encoding == RX_ENC_HT) && ++ status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET) ++ status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET; + } else { + status->band = NL80211_BAND_2GHZ; + } +@@ -1124,8 +1128,9 @@ static void mwl8k_rxd_sta_refill(void *_rxd, dma_addr_t addr, int len) + + if (rxd->channel > 14) { + status->band = NL80211_BAND_5GHZ; +- if (!(status->encoding == RX_ENC_HT)) +- status->rate_idx -= 5; ++ if (!(status->encoding == RX_ENC_HT) && ++ status->rate_idx >= MWL8K_LEGACY_5G_RATE_OFFSET) ++ status->rate_idx -= MWL8K_LEGACY_5G_RATE_OFFSET; + } else { + status->band = NL80211_BAND_2GHZ; + } +-- +1.9.1 + diff --git a/package/kernel/mac80211/patches/rt2x00/001-rt2x00-use-simple_read_from_buffer.patch b/package/kernel/mac80211/patches/rt2x00/001-rt2x00-use-simple_read_from_buffer.patch new file mode 100644 index 0000000000..1319cc244c --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/001-rt2x00-use-simple_read_from_buffer.patch @@ -0,0 +1,59 @@ +From f483039cf51acf30494cd754194562c22cf98764 Mon Sep 17 00:00:00 2001 +From: Dan Carpenter +Date: Wed, 22 Aug 2018 13:41:26 +0300 +Subject: [PATCH 01/28] rt2x00: use simple_read_from_buffer() + +The problem with this copy_to_user() calls is that they don't ensure +that "size" is less than the "length" which the user provided. + +Obviously, this is debugfs and "size" is normally going to be very small +so it probably doesn't matter, but this is the correct thing to do. + +Signed-off-by: Dan Carpenter +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + .../net/wireless/ralink/rt2x00/rt2x00debug.c | 18 +++--------------- + 1 file changed, 3 insertions(+), 15 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +@@ -464,11 +464,7 @@ static ssize_t rt2x00debug_read_##__name + \ + size = sprintf(line, __format, value); \ + \ +- if (copy_to_user(buf, line, size)) \ +- return -EFAULT; \ +- \ +- *offset += size; \ +- return size; \ ++ return simple_read_from_buffer(buf, length, offset, line, size); \ + } + + #define RT2X00DEBUGFS_OPS_WRITE(__name, __type) \ +@@ -545,11 +541,7 @@ static ssize_t rt2x00debug_read_dev_flag + + size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->flags); + +- if (copy_to_user(buf, line, size)) +- return -EFAULT; +- +- *offset += size; +- return size; ++ return simple_read_from_buffer(buf, length, offset, line, size); + } + + static const struct file_operations rt2x00debug_fop_dev_flags = { +@@ -574,11 +566,7 @@ static ssize_t rt2x00debug_read_cap_flag + + size = sprintf(line, "0x%.8x\n", (unsigned int)intf->rt2x00dev->cap_flags); + +- if (copy_to_user(buf, line, size)) +- return -EFAULT; +- +- *offset += size; +- return size; ++ return simple_read_from_buffer(buf, length, offset, line, size); + } + + static const struct file_operations rt2x00debug_fop_cap_flags = { diff --git a/package/kernel/mac80211/patches/rt2x00/002-rt2800-move-usb-specific-txdone-txstatus-routines-to.patch b/package/kernel/mac80211/patches/rt2x00/002-rt2800-move-usb-specific-txdone-txstatus-routines-to.patch new file mode 100644 index 0000000000..a883258a4c --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/002-rt2800-move-usb-specific-txdone-txstatus-routines-to.patch @@ -0,0 +1,357 @@ +From 5c656c71b1bf5611ce8262bab338104e04d10b8d Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 26 Sep 2018 12:24:53 +0200 +Subject: [PATCH 02/28] rt2800: move usb specific txdone/txstatus routines to + rt2800lib + +In order to reuse usb txdone/txstatus routines for mmio, move them +to common rt2800lib.c file. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 138 +++++++++++++++++ + .../net/wireless/ralink/rt2x00/rt2800lib.h | 3 + + .../net/wireless/ralink/rt2x00/rt2800usb.c | 143 +----------------- + 3 files changed, 145 insertions(+), 139 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -957,6 +957,47 @@ static void rt2800_rate_from_status(stru + skbdesc->tx_rate_flags = flags; + } + ++static bool rt2800_txdone_entry_check(struct queue_entry *entry, u32 reg) ++{ ++ __le32 *txwi; ++ u32 word; ++ int wcid, ack, pid; ++ int tx_wcid, tx_ack, tx_pid, is_agg; ++ ++ /* ++ * This frames has returned with an IO error, ++ * so the status report is not intended for this ++ * frame. ++ */ ++ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) ++ return false; ++ ++ wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); ++ ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); ++ pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); ++ is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); ++ ++ /* ++ * Validate if this TX status report is intended for ++ * this entry by comparing the WCID/ACK/PID fields. ++ */ ++ txwi = rt2800_drv_get_txwi(entry); ++ ++ word = rt2x00_desc_read(txwi, 1); ++ tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); ++ tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); ++ tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); ++ ++ if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { ++ rt2x00_dbg(entry->queue->rt2x00dev, ++ "TX status report missed for queue %d entry %d\n", ++ entry->queue->qid, entry->entry_idx); ++ return false; ++ } ++ ++ return true; ++} ++ + void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, + bool match) + { +@@ -1059,6 +1100,103 @@ void rt2800_txdone_entry(struct queue_en + } + EXPORT_SYMBOL_GPL(rt2800_txdone_entry); + ++void rt2800_txdone(struct rt2x00_dev *rt2x00dev) ++{ ++ struct data_queue *queue; ++ struct queue_entry *entry; ++ u32 reg; ++ u8 qid; ++ bool match; ++ ++ while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { ++ /* ++ * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is ++ * guaranteed to be one of the TX QIDs . ++ */ ++ qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); ++ queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); ++ ++ if (unlikely(rt2x00queue_empty(queue))) { ++ rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", ++ qid); ++ break; ++ } ++ ++ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); ++ ++ if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || ++ !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { ++ rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n", ++ entry->entry_idx, qid); ++ break; ++ } ++ ++ match = rt2800_txdone_entry_check(entry, reg); ++ rt2800_txdone_entry(entry, reg, rt2800_drv_get_txwi(entry), match); ++ } ++} ++EXPORT_SYMBOL_GPL(rt2800_txdone); ++ ++static inline bool rt2800_entry_txstatus_timeout(struct queue_entry *entry) ++{ ++ bool tout; ++ ++ if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) ++ return false; ++ ++ tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500)); ++ if (unlikely(tout)) ++ rt2x00_dbg(entry->queue->rt2x00dev, ++ "TX status timeout for entry %d in queue %d\n", ++ entry->entry_idx, entry->queue->qid); ++ return tout; ++ ++} ++ ++bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev) ++{ ++ struct data_queue *queue; ++ struct queue_entry *entry; ++ ++ tx_queue_for_each(rt2x00dev, queue) { ++ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); ++ if (rt2800_entry_txstatus_timeout(entry)) ++ return true; ++ } ++ return false; ++} ++EXPORT_SYMBOL_GPL(rt2800_txstatus_timeout); ++ ++void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev) ++{ ++ struct data_queue *queue; ++ struct queue_entry *entry; ++ ++ /* ++ * Process any trailing TX status reports for IO failures, ++ * we loop until we find the first non-IO error entry. This ++ * can either be a frame which is free, is being uploaded, ++ * or has completed the upload but didn't have an entry ++ * in the TX_STAT_FIFO register yet. ++ */ ++ tx_queue_for_each(rt2x00dev, queue) { ++ while (!rt2x00queue_empty(queue)) { ++ entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); ++ ++ if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || ++ !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) ++ break; ++ ++ if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) || ++ rt2800_entry_txstatus_timeout(entry)) ++ rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); ++ else ++ break; ++ } ++ } ++} ++EXPORT_SYMBOL_GPL(rt2800_txdone_nostatus); ++ + static unsigned int rt2800_hw_beacon_base(struct rt2x00_dev *rt2x00dev, + unsigned int index) + { +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +@@ -195,6 +195,9 @@ void rt2800_process_rxwi(struct queue_en + + void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, + bool match); ++void rt2800_txdone(struct rt2x00_dev *rt2x00dev); ++void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev); ++bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev); + + void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); + void rt2800_clear_beacon(struct queue_entry *entry); +--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +@@ -116,35 +116,6 @@ static bool rt2800usb_txstatus_pending(s + return false; + } + +-static inline bool rt2800usb_entry_txstatus_timeout(struct queue_entry *entry) +-{ +- bool tout; +- +- if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) +- return false; +- +- tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500)); +- if (unlikely(tout)) +- rt2x00_dbg(entry->queue->rt2x00dev, +- "TX status timeout for entry %d in queue %d\n", +- entry->entry_idx, entry->queue->qid); +- return tout; +- +-} +- +-static bool rt2800usb_txstatus_timeout(struct rt2x00_dev *rt2x00dev) +-{ +- struct data_queue *queue; +- struct queue_entry *entry; +- +- tx_queue_for_each(rt2x00dev, queue) { +- entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); +- if (rt2800usb_entry_txstatus_timeout(entry)) +- return true; +- } +- return false; +-} +- + #define TXSTATUS_READ_INTERVAL 1000000 + + static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, +@@ -171,7 +142,7 @@ static bool rt2800usb_tx_sta_fifo_read_c + } + + /* Check if there is any entry that timedout waiting on TX status */ +- if (rt2800usb_txstatus_timeout(rt2x00dev)) ++ if (rt2800_txstatus_timeout(rt2x00dev)) + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + + if (rt2800usb_txstatus_pending(rt2x00dev)) { +@@ -501,123 +472,17 @@ static int rt2800usb_get_tx_data_len(str + /* + * TX control handlers + */ +-static bool rt2800usb_txdone_entry_check(struct queue_entry *entry, u32 reg) +-{ +- __le32 *txwi; +- u32 word; +- int wcid, ack, pid; +- int tx_wcid, tx_ack, tx_pid, is_agg; +- +- /* +- * This frames has returned with an IO error, +- * so the status report is not intended for this +- * frame. +- */ +- if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags)) +- return false; +- +- wcid = rt2x00_get_field32(reg, TX_STA_FIFO_WCID); +- ack = rt2x00_get_field32(reg, TX_STA_FIFO_TX_ACK_REQUIRED); +- pid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_TYPE); +- is_agg = rt2x00_get_field32(reg, TX_STA_FIFO_TX_AGGRE); +- +- /* +- * Validate if this TX status report is intended for +- * this entry by comparing the WCID/ACK/PID fields. +- */ +- txwi = rt2800usb_get_txwi(entry); +- +- word = rt2x00_desc_read(txwi, 1); +- tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); +- tx_ack = rt2x00_get_field32(word, TXWI_W1_ACK); +- tx_pid = rt2x00_get_field32(word, TXWI_W1_PACKETID); +- +- if (wcid != tx_wcid || ack != tx_ack || (!is_agg && pid != tx_pid)) { +- rt2x00_dbg(entry->queue->rt2x00dev, +- "TX status report missed for queue %d entry %d\n", +- entry->queue->qid, entry->entry_idx); +- return false; +- } +- +- return true; +-} +- +-static void rt2800usb_txdone(struct rt2x00_dev *rt2x00dev) +-{ +- struct data_queue *queue; +- struct queue_entry *entry; +- u32 reg; +- u8 qid; +- bool match; +- +- while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { +- /* +- * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is +- * guaranteed to be one of the TX QIDs . +- */ +- qid = rt2x00_get_field32(reg, TX_STA_FIFO_PID_QUEUE); +- queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); +- +- if (unlikely(rt2x00queue_empty(queue))) { +- rt2x00_dbg(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", +- qid); +- break; +- } +- +- entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); +- +- if (unlikely(test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || +- !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags))) { +- rt2x00_warn(rt2x00dev, "Data pending for entry %u in queue %u\n", +- entry->entry_idx, qid); +- break; +- } +- +- match = rt2800usb_txdone_entry_check(entry, reg); +- rt2800_txdone_entry(entry, reg, rt2800usb_get_txwi(entry), match); +- } +-} +- +-static void rt2800usb_txdone_nostatus(struct rt2x00_dev *rt2x00dev) +-{ +- struct data_queue *queue; +- struct queue_entry *entry; +- +- /* +- * Process any trailing TX status reports for IO failures, +- * we loop until we find the first non-IO error entry. This +- * can either be a frame which is free, is being uploaded, +- * or has completed the upload but didn't have an entry +- * in the TX_STAT_FIFO register yet. +- */ +- tx_queue_for_each(rt2x00dev, queue) { +- while (!rt2x00queue_empty(queue)) { +- entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); +- +- if (test_bit(ENTRY_OWNER_DEVICE_DATA, &entry->flags) || +- !test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) +- break; +- +- if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) || +- rt2800usb_entry_txstatus_timeout(entry)) +- rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); +- else +- break; +- } +- } +-} +- + static void rt2800usb_work_txdone(struct work_struct *work) + { + struct rt2x00_dev *rt2x00dev = + container_of(work, struct rt2x00_dev, txdone_work); + + while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || +- rt2800usb_txstatus_timeout(rt2x00dev)) { ++ rt2800_txstatus_timeout(rt2x00dev)) { + +- rt2800usb_txdone(rt2x00dev); ++ rt2800_txdone(rt2x00dev); + +- rt2800usb_txdone_nostatus(rt2x00dev); ++ rt2800_txdone_nostatus(rt2x00dev); + + /* + * The hw may delay sending the packet after DMA complete diff --git a/package/kernel/mac80211/patches/rt2x00/003-rt2800mmio-use-txdone-txstatus-routines-from-lib.patch b/package/kernel/mac80211/patches/rt2x00/003-rt2800mmio-use-txdone-txstatus-routines-from-lib.patch new file mode 100644 index 0000000000..48f0c27011 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/003-rt2800mmio-use-txdone-txstatus-routines-from-lib.patch @@ -0,0 +1,244 @@ +From 0b0d556e0ebb6c966bc993e21a22a156812d8fdf Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 26 Sep 2018 12:24:54 +0200 +Subject: [PATCH 03/28] rt2800mmio: use txdone/txstatus routines from lib + +Use usb txdone/txstatus routines (now in rt2800libc) for mmio devices. + +Note this also change how we handle INT_SOURCE_CSR_TX_FIFO_STATUS +interrupt. Now it is disabled since IRQ routine till end of the txstatus +tasklet (the same behaviour like others interrupts). Reason to do not +disable this interrupt was not to miss any tx status from 16 entries +FIFO register. Now, since we check for tx status timeout, we can +allow to miss some tx statuses. However this will be improved in further +patch where I also implement read status FIFO register in the tasklet. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + .../net/wireless/ralink/rt2x00/rt2800mmio.c | 180 +----------------- + .../net/wireless/ralink/rt2x00/rt2x00queue.c | 1 + + 2 files changed, 9 insertions(+), 172 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -175,161 +175,6 @@ static void rt2800mmio_wakeup(struct rt2 + rt2800_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); + } + +-static bool rt2800mmio_txdone_entry_check(struct queue_entry *entry, u32 status) +-{ +- __le32 *txwi; +- u32 word; +- int wcid, tx_wcid; +- +- wcid = rt2x00_get_field32(status, TX_STA_FIFO_WCID); +- +- txwi = rt2800_drv_get_txwi(entry); +- word = rt2x00_desc_read(txwi, 1); +- tx_wcid = rt2x00_get_field32(word, TXWI_W1_WIRELESS_CLI_ID); +- +- return (tx_wcid == wcid); +-} +- +-static bool rt2800mmio_txdone_find_entry(struct queue_entry *entry, void *data) +-{ +- u32 status = *(u32 *)data; +- +- /* +- * rt2800pci hardware might reorder frames when exchanging traffic +- * with multiple BA enabled STAs. +- * +- * For example, a tx queue +- * [ STA1 | STA2 | STA1 | STA2 ] +- * can result in tx status reports +- * [ STA1 | STA1 | STA2 | STA2 ] +- * when the hw decides to aggregate the frames for STA1 into one AMPDU. +- * +- * To mitigate this effect, associate the tx status to the first frame +- * in the tx queue with a matching wcid. +- */ +- if (rt2800mmio_txdone_entry_check(entry, status) && +- !test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { +- /* +- * Got a matching frame, associate the tx status with +- * the frame +- */ +- entry->status = status; +- set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); +- return true; +- } +- +- /* Check the next frame */ +- return false; +-} +- +-static bool rt2800mmio_txdone_match_first(struct queue_entry *entry, void *data) +-{ +- u32 status = *(u32 *)data; +- +- /* +- * Find the first frame without tx status and assign this status to it +- * regardless if it matches or not. +- */ +- if (!test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { +- /* +- * Got a matching frame, associate the tx status with +- * the frame +- */ +- entry->status = status; +- set_bit(ENTRY_DATA_STATUS_SET, &entry->flags); +- return true; +- } +- +- /* Check the next frame */ +- return false; +-} +-static bool rt2800mmio_txdone_release_entries(struct queue_entry *entry, +- void *data) +-{ +- if (test_bit(ENTRY_DATA_STATUS_SET, &entry->flags)) { +- rt2800_txdone_entry(entry, entry->status, +- rt2800mmio_get_txwi(entry), true); +- return false; +- } +- +- /* No more frames to release */ +- return true; +-} +- +-static bool rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev) +-{ +- struct data_queue *queue; +- u32 status; +- u8 qid; +- int max_tx_done = 16; +- +- while (kfifo_get(&rt2x00dev->txstatus_fifo, &status)) { +- qid = rt2x00_get_field32(status, TX_STA_FIFO_PID_QUEUE); +- if (unlikely(qid >= QID_RX)) { +- /* +- * Unknown queue, this shouldn't happen. Just drop +- * this tx status. +- */ +- rt2x00_warn(rt2x00dev, "Got TX status report with unexpected pid %u, dropping\n", +- qid); +- break; +- } +- +- queue = rt2x00queue_get_tx_queue(rt2x00dev, qid); +- if (unlikely(queue == NULL)) { +- /* +- * The queue is NULL, this shouldn't happen. Stop +- * processing here and drop the tx status +- */ +- rt2x00_warn(rt2x00dev, "Got TX status for an unavailable queue %u, dropping\n", +- qid); +- break; +- } +- +- if (unlikely(rt2x00queue_empty(queue))) { +- /* +- * The queue is empty. Stop processing here +- * and drop the tx status. +- */ +- rt2x00_warn(rt2x00dev, "Got TX status for an empty queue %u, dropping\n", +- qid); +- break; +- } +- +- /* +- * Let's associate this tx status with the first +- * matching frame. +- */ +- if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, +- Q_INDEX, &status, +- rt2800mmio_txdone_find_entry)) { +- /* +- * We cannot match the tx status to any frame, so just +- * use the first one. +- */ +- if (!rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, +- Q_INDEX, &status, +- rt2800mmio_txdone_match_first)) { +- rt2x00_warn(rt2x00dev, "No frame found for TX status on queue %u, dropping\n", +- qid); +- break; +- } +- } +- +- /* +- * Release all frames with a valid tx status. +- */ +- rt2x00queue_for_each_entry(queue, Q_INDEX_DONE, +- Q_INDEX, NULL, +- rt2800mmio_txdone_release_entries); +- +- if (--max_tx_done == 0) +- break; +- } +- +- return !max_tx_done; +-} +- + static inline void rt2800mmio_enable_interrupt(struct rt2x00_dev *rt2x00dev, + struct rt2x00_field32 irq_field) + { +@@ -349,14 +194,14 @@ static inline void rt2800mmio_enable_int + void rt2800mmio_txstatus_tasklet(unsigned long data) + { + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; +- if (rt2800mmio_txdone(rt2x00dev)) +- tasklet_schedule(&rt2x00dev->txstatus_tasklet); + +- /* +- * No need to enable the tx status interrupt here as we always +- * leave it enabled to minimize the possibility of a tx status +- * register overflow. See comment in interrupt handler. +- */ ++ rt2800_txdone(rt2x00dev); ++ ++ rt2800_txdone_nostatus(rt2x00dev); ++ ++ if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) ++ rt2800mmio_enable_interrupt(rt2x00dev, ++ INT_SOURCE_CSR_TX_FIFO_STATUS); + } + EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet); + +@@ -440,10 +285,6 @@ static void rt2800mmio_txstatus_interrup + * because we can schedule the tasklet multiple times (when the + * interrupt fires again during tx status processing). + * +- * Furthermore we don't disable the TX_FIFO_STATUS +- * interrupt here but leave it enabled so that the TX_STA_FIFO +- * can also be read while the tx status tasklet gets executed. +- * + * Since we have only one producer and one consumer we don't + * need to lock the kfifo. + */ +@@ -485,13 +326,8 @@ irqreturn_t rt2800mmio_interrupt(int irq + */ + mask = ~reg; + +- if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { ++ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) + rt2800mmio_txstatus_interrupt(rt2x00dev); +- /* +- * Never disable the TX_FIFO_STATUS interrupt. +- */ +- rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1); +- } + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) + tasklet_hi_schedule(&rt2x00dev->pretbtt_tasklet); +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +@@ -113,6 +113,7 @@ int rt2x00queue_map_txskb(struct queue_e + return -ENOMEM; + + skbdesc->flags |= SKBDESC_DMA_MAPPED_TX; ++ rt2x00lib_dmadone(entry); + return 0; + } + EXPORT_SYMBOL_GPL(rt2x00queue_map_txskb); diff --git a/package/kernel/mac80211/patches/rt2x00/004-rt2x00-do-not-check-for-txstatus-timeout-every-time-.patch b/package/kernel/mac80211/patches/rt2x00/004-rt2x00-do-not-check-for-txstatus-timeout-every-time-.patch new file mode 100644 index 0000000000..832768d042 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/004-rt2x00-do-not-check-for-txstatus-timeout-every-time-.patch @@ -0,0 +1,72 @@ +From 5022efb50f625d11fdf18b1fee0f64ebb1863664 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 26 Sep 2018 12:24:55 +0200 +Subject: [PATCH 04/28] rt2x00: do not check for txstatus timeout every time on + tasklet + +Do not check for tx status timeout everytime we perform txstatus tasklet. +Perform check once per half a second. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 7 +++++++ + drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 3 ++- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 ++ + drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 1 + + 4 files changed, 12 insertions(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1158,11 +1158,18 @@ bool rt2800_txstatus_timeout(struct rt2x + struct data_queue *queue; + struct queue_entry *entry; + ++ if (time_before(jiffies, ++ rt2x00dev->last_nostatus_check + msecs_to_jiffies(500))) ++ return false; ++ ++ rt2x00dev->last_nostatus_check = jiffies; ++ + tx_queue_for_each(rt2x00dev, queue) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + if (rt2800_entry_txstatus_timeout(entry)) + return true; + } ++ + return false; + } + EXPORT_SYMBOL_GPL(rt2800_txstatus_timeout); +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -197,7 +197,8 @@ void rt2800mmio_txstatus_tasklet(unsigne + + rt2800_txdone(rt2x00dev); + +- rt2800_txdone_nostatus(rt2x00dev); ++ if (rt2800_txstatus_timeout(rt2x00dev)) ++ rt2800_txdone_nostatus(rt2x00dev); + + if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) + rt2800mmio_enable_interrupt(rt2x00dev, +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -980,6 +980,8 @@ struct rt2x00_dev { + */ + DECLARE_KFIFO_PTR(txstatus_fifo, u32); + ++ unsigned long last_nostatus_check; ++ + /* + * Timer to ensure tx status reports are read (rt2800usb). + */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +@@ -1039,6 +1039,7 @@ void rt2x00queue_start_queues(struct rt2 + */ + tx_queue_for_each(rt2x00dev, queue) + rt2x00queue_start_queue(queue); ++ rt2x00dev->last_nostatus_check = jiffies; + + rt2x00queue_start_queue(rt2x00dev->rx); + } diff --git a/package/kernel/mac80211/patches/rt2x00/005-rt2x00-use-different-txstatus-timeouts-when-flushing.patch b/package/kernel/mac80211/patches/rt2x00/005-rt2x00-use-different-txstatus-timeouts-when-flushing.patch new file mode 100644 index 0000000000..0f29026373 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/005-rt2x00-use-different-txstatus-timeouts-when-flushing.patch @@ -0,0 +1,112 @@ +From adf26a356f132e35093585521ea3e36cd185af83 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 26 Sep 2018 12:24:56 +0200 +Subject: [PATCH 05/28] rt2x00: use different txstatus timeouts when flushing + +Use different tx status timeouts for normal operation and when flushing. +This increase timeout to 2s for normal operation as when there are bad +radio conditions and frames are reposted many times device can not provide +the status for quite long. With new timeout we can still get valid status +on such bad conditions. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 31 +++++++++++++------ + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 + + .../net/wireless/ralink/rt2x00/rt2x00mac.c | 4 +++ + 3 files changed, 26 insertions(+), 10 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1137,36 +1137,47 @@ void rt2800_txdone(struct rt2x00_dev *rt + } + EXPORT_SYMBOL_GPL(rt2800_txdone); + +-static inline bool rt2800_entry_txstatus_timeout(struct queue_entry *entry) ++static inline bool rt2800_entry_txstatus_timeout(struct rt2x00_dev *rt2x00dev, ++ struct queue_entry *entry) + { +- bool tout; ++ bool ret; ++ unsigned long tout; + + if (!test_bit(ENTRY_DATA_STATUS_PENDING, &entry->flags)) + return false; + +- tout = time_after(jiffies, entry->last_action + msecs_to_jiffies(500)); +- if (unlikely(tout)) ++ if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) ++ tout = msecs_to_jiffies(100); ++ else ++ tout = msecs_to_jiffies(2000); ++ ++ ret = time_after(jiffies, entry->last_action + tout); ++ if (unlikely(ret)) + rt2x00_dbg(entry->queue->rt2x00dev, + "TX status timeout for entry %d in queue %d\n", + entry->entry_idx, entry->queue->qid); +- return tout; +- ++ return ret; + } + + bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev) + { + struct data_queue *queue; + struct queue_entry *entry; ++ unsigned long tout; ++ ++ if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) ++ tout = msecs_to_jiffies(50); ++ else ++ tout = msecs_to_jiffies(1000); + +- if (time_before(jiffies, +- rt2x00dev->last_nostatus_check + msecs_to_jiffies(500))) ++ if (time_before(jiffies, rt2x00dev->last_nostatus_check + tout)) + return false; + + rt2x00dev->last_nostatus_check = jiffies; + + tx_queue_for_each(rt2x00dev, queue) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); +- if (rt2800_entry_txstatus_timeout(entry)) ++ if (rt2800_entry_txstatus_timeout(rt2x00dev, entry)) + return true; + } + +@@ -1195,7 +1206,7 @@ void rt2800_txdone_nostatus(struct rt2x0 + break; + + if (test_bit(ENTRY_DATA_IO_FAILED, &entry->flags) || +- rt2800_entry_txstatus_timeout(entry)) ++ rt2800_entry_txstatus_timeout(rt2x00dev, entry)) + rt2x00lib_txdone_noinfo(entry, TXDONE_FAILURE); + else + break; +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -665,6 +665,7 @@ enum rt2x00_state_flags { + DEVICE_STATE_STARTED, + DEVICE_STATE_ENABLED_RADIO, + DEVICE_STATE_SCANNING, ++ DEVICE_STATE_FLUSHING, + + /* + * Driver configuration +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +@@ -720,8 +720,12 @@ void rt2x00mac_flush(struct ieee80211_hw + if (!test_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags)) + return; + ++ set_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags); ++ + tx_queue_for_each(rt2x00dev, queue) + rt2x00queue_flush_queue(queue, drop); ++ ++ clear_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags); + } + EXPORT_SYMBOL_GPL(rt2x00mac_flush); + diff --git a/package/kernel/mac80211/patches/rt2x00/006-rt2800-flush-and-txstatus-rework-for-rt2800mmio.patch b/package/kernel/mac80211/patches/rt2x00/006-rt2800-flush-and-txstatus-rework-for-rt2800mmio.patch new file mode 100644 index 0000000000..784fbb16f1 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/006-rt2800-flush-and-txstatus-rework-for-rt2800mmio.patch @@ -0,0 +1,238 @@ +From 0240564430c0697d8fde3743d70346a922466b36 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 26 Sep 2018 12:24:57 +0200 +Subject: [PATCH 06/28] rt2800: flush and txstatus rework for rt2800mmio + +Implement custom rt2800mmio flush routine and change txstatus +routine to read TX_STA_FIFO also in the tasklet. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 14 +-- + .../net/wireless/ralink/rt2x00/rt2800mmio.c | 118 +++++++++++++----- + .../net/wireless/ralink/rt2x00/rt2800mmio.h | 1 + + .../net/wireless/ralink/rt2x00/rt2800pci.c | 2 +- + 4 files changed, 97 insertions(+), 38 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1147,7 +1147,7 @@ static inline bool rt2800_entry_txstatus + return false; + + if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) +- tout = msecs_to_jiffies(100); ++ tout = msecs_to_jiffies(50); + else + tout = msecs_to_jiffies(2000); + +@@ -1163,15 +1163,13 @@ bool rt2800_txstatus_timeout(struct rt2x + { + struct data_queue *queue; + struct queue_entry *entry; +- unsigned long tout; + +- if (test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) +- tout = msecs_to_jiffies(50); +- else +- tout = msecs_to_jiffies(1000); ++ if (!test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) { ++ unsigned long tout = msecs_to_jiffies(1000); + +- if (time_before(jiffies, rt2x00dev->last_nostatus_check + tout)) +- return false; ++ if (time_before(jiffies, rt2x00dev->last_nostatus_check + tout)) ++ return false; ++ } + + rt2x00dev->last_nostatus_check = jiffies; + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -191,21 +191,6 @@ static inline void rt2800mmio_enable_int + spin_unlock_irq(&rt2x00dev->irqmask_lock); + } + +-void rt2800mmio_txstatus_tasklet(unsigned long data) +-{ +- struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; +- +- rt2800_txdone(rt2x00dev); +- +- if (rt2800_txstatus_timeout(rt2x00dev)) +- rt2800_txdone_nostatus(rt2x00dev); +- +- if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) +- rt2800mmio_enable_interrupt(rt2x00dev, +- INT_SOURCE_CSR_TX_FIFO_STATUS); +-} +-EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet); +- + void rt2800mmio_pretbtt_tasklet(unsigned long data) + { + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; +@@ -270,12 +255,26 @@ void rt2800mmio_autowake_tasklet(unsigne + } + EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet); + +-static void rt2800mmio_txstatus_interrupt(struct rt2x00_dev *rt2x00dev) ++static void rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev) ++{ ++ bool timeout = false; ++ ++ while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || ++ (timeout = rt2800_txstatus_timeout(rt2x00dev))) { ++ ++ rt2800_txdone(rt2x00dev); ++ ++ if (timeout) ++ rt2800_txdone_nostatus(rt2x00dev); ++ } ++} ++ ++static bool rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev) + { + u32 status; +- int i; ++ bool more = false; + +- /* ++ /* FIXEME: rewrite this comment + * The TX_FIFO_STATUS interrupt needs special care. We should + * read TX_STA_FIFO but we should do it immediately as otherwise + * the register can overflow and we would lose status reports. +@@ -286,25 +285,37 @@ static void rt2800mmio_txstatus_interrup + * because we can schedule the tasklet multiple times (when the + * interrupt fires again during tx status processing). + * +- * Since we have only one producer and one consumer we don't ++ * txstatus tasklet is called with INT_SOURCE_CSR_TX_FIFO_STATUS ++ * disabled so have only one producer and one consumer - we don't + * need to lock the kfifo. + */ +- for (i = 0; i < rt2x00dev->tx->limit; i++) { ++ while (!kfifo_is_full(&rt2x00dev->txstatus_fifo)) { + status = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO); +- + if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) + break; + +- if (!kfifo_put(&rt2x00dev->txstatus_fifo, status)) { +- rt2x00_warn(rt2x00dev, "TX status FIFO overrun, drop tx status report\n"); +- break; +- } ++ kfifo_put(&rt2x00dev->txstatus_fifo, status); ++ more = true; + } + +- /* Schedule the tasklet for processing the tx status. */ +- tasklet_schedule(&rt2x00dev->txstatus_tasklet); ++ return more; + } + ++void rt2800mmio_txstatus_tasklet(unsigned long data) ++{ ++ struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; ++ ++ do { ++ rt2800mmio_txdone(rt2x00dev); ++ ++ } while (rt2800mmio_fetch_txstatus(rt2x00dev)); ++ ++ if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) ++ rt2800mmio_enable_interrupt(rt2x00dev, ++ INT_SOURCE_CSR_TX_FIFO_STATUS); ++} ++EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet); ++ + irqreturn_t rt2800mmio_interrupt(int irq, void *dev_instance) + { + struct rt2x00_dev *rt2x00dev = dev_instance; +@@ -327,8 +338,10 @@ irqreturn_t rt2800mmio_interrupt(int irq + */ + mask = ~reg; + +- if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) +- rt2800mmio_txstatus_interrupt(rt2x00dev); ++ if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { ++ rt2800mmio_fetch_txstatus(rt2x00dev); ++ tasklet_schedule(&rt2x00dev->txstatus_tasklet); ++ } + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) + tasklet_hi_schedule(&rt2x00dev->pretbtt_tasklet); +@@ -453,6 +466,53 @@ void rt2800mmio_kick_queue(struct data_q + } + EXPORT_SYMBOL_GPL(rt2800mmio_kick_queue); + ++void rt2800mmio_flush_queue(struct data_queue *queue, bool drop) ++{ ++ struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; ++ bool tx_queue = false; ++ unsigned int i; ++ ++ switch (queue->qid) { ++ case QID_AC_VO: ++ case QID_AC_VI: ++ case QID_AC_BE: ++ case QID_AC_BK: ++ tx_queue = true; ++ break; ++ case QID_RX: ++ break; ++ default: ++ return; ++ } ++ ++ for (i = 0; i < 5; i++) { ++ /* ++ * Check if the driver is already done, otherwise we ++ * have to sleep a little while to give the driver/hw ++ * the oppurtunity to complete interrupt process itself. ++ */ ++ if (rt2x00queue_empty(queue)) ++ break; ++ ++ /* ++ * For TX queues schedule completion tasklet to catch ++ * tx status timeouts, othewise just wait. ++ */ ++ if (tx_queue) { ++ tasklet_disable(&rt2x00dev->txstatus_tasklet); ++ rt2800mmio_txdone(rt2x00dev); ++ tasklet_enable(&rt2x00dev->txstatus_tasklet); ++ } ++ ++ /* ++ * Wait for a little while to give the driver ++ * the oppurtunity to recover itself. ++ */ ++ msleep(50); ++ } ++} ++EXPORT_SYMBOL_GPL(rt2800mmio_flush_queue); ++ + void rt2800mmio_stop_queue(struct data_queue *queue) + { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h +@@ -148,6 +148,7 @@ void rt2800mmio_toggle_irq(struct rt2x00 + /* Queue handlers */ + void rt2800mmio_start_queue(struct data_queue *queue); + void rt2800mmio_kick_queue(struct data_queue *queue); ++void rt2800mmio_flush_queue(struct data_queue *queue, bool drop); + void rt2800mmio_stop_queue(struct data_queue *queue); + void rt2800mmio_queue_init(struct data_queue *queue); + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c +@@ -364,7 +364,7 @@ static const struct rt2x00lib_ops rt2800 + .start_queue = rt2800mmio_start_queue, + .kick_queue = rt2800mmio_kick_queue, + .stop_queue = rt2800mmio_stop_queue, +- .flush_queue = rt2x00mmio_flush_queue, ++ .flush_queue = rt2800mmio_flush_queue, + .write_tx_desc = rt2800mmio_write_tx_desc, + .write_tx_data = rt2800_write_tx_data, + .write_beacon = rt2800_write_beacon, diff --git a/package/kernel/mac80211/patches/rt2x00/007-rt2x00-rt2400pci-mark-expected-switch-fall-through.patch b/package/kernel/mac80211/patches/rt2x00/007-rt2x00-rt2400pci-mark-expected-switch-fall-through.patch new file mode 100644 index 0000000000..2161ad9ef3 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/007-rt2x00-rt2400pci-mark-expected-switch-fall-through.patch @@ -0,0 +1,25 @@ +From 6eba8fd2235237784dfd01da55c3210d493aebdb Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Mon, 22 Oct 2018 22:44:34 +0200 +Subject: [PATCH 07/28] rt2x00: rt2400pci: mark expected switch fall-through + +In preparation to enabling -Wimplicit-fallthrough, mark switch cases +where we are expecting to fall through. + +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2400pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2400pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2400pci.c +@@ -1302,7 +1302,7 @@ static void rt2400pci_txdone(struct rt2x + break; + case 2: /* Failure, excessive retries */ + __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); +- /* Don't break, this is a failed frame! */ ++ /* Fall through - this is a failed frame! */ + default: /* Failure */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + } diff --git a/package/kernel/mac80211/patches/rt2x00/008-rt2x00-rt2500pci-mark-expected-switch-fall-through.patch b/package/kernel/mac80211/patches/rt2x00/008-rt2x00-rt2500pci-mark-expected-switch-fall-through.patch new file mode 100644 index 0000000000..d10de6b0e5 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/008-rt2x00-rt2500pci-mark-expected-switch-fall-through.patch @@ -0,0 +1,25 @@ +From 10bb92217747c3384a01ebec005faa2f5e72bbd8 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Mon, 22 Oct 2018 22:45:19 +0200 +Subject: [PATCH 08/28] rt2x00: rt2500pci: mark expected switch fall-through + +In preparation to enabling -Wimplicit-fallthrough, mark switch cases +where we are expecting to fall through. + +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2500pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2500pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2500pci.c +@@ -1430,7 +1430,7 @@ static void rt2500pci_txdone(struct rt2x + break; + case 2: /* Failure, excessive retries */ + __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); +- /* Don't break, this is a failed frame! */ ++ /* Fall through - this is a failed frame! */ + default: /* Failure */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + } diff --git a/package/kernel/mac80211/patches/rt2x00/009-rt2x00-rt2800lib-mark-expected-switch-fall-throughs.patch b/package/kernel/mac80211/patches/rt2x00/009-rt2x00-rt2800lib-mark-expected-switch-fall-throughs.patch new file mode 100644 index 0000000000..99f971b95f --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/009-rt2x00-rt2800lib-mark-expected-switch-fall-throughs.patch @@ -0,0 +1,44 @@ +From 916e6bbcfcff6cc5d7d33bba8557a30f3af50326 Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Mon, 22 Oct 2018 22:46:03 +0200 +Subject: [PATCH 09/28] rt2x00: rt2800lib: mark expected switch fall-throughs + +In preparation to enabling -Wimplicit-fallthrough, mark switch cases +where we are expecting to fall through. + +Addresses-Coverity-ID: 145198 ("Missing break in switch") +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 4 ++++ + 1 file changed, 4 insertions(+) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -2482,6 +2482,7 @@ static void rt2800_config_channel_rf3052 + switch (rt2x00dev->default_ant.tx_chain_num) { + case 1: + rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); ++ /* fall through */ + case 2: + rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); + break; +@@ -2490,6 +2491,7 @@ static void rt2800_config_channel_rf3052 + switch (rt2x00dev->default_ant.rx_chain_num) { + case 1: + rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); ++ /* fall through */ + case 2: + rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); + break; +@@ -9457,8 +9459,10 @@ static int rt2800_probe_hw_mode(struct r + switch (rx_chains) { + case 3: + spec->ht.mcs.rx_mask[2] = 0xff; ++ /* fall through */ + case 2: + spec->ht.mcs.rx_mask[1] = 0xff; ++ /* fall through */ + case 1: + spec->ht.mcs.rx_mask[0] = 0xff; + spec->ht.mcs.rx_mask[4] = 0x1; /* MCS32 */ diff --git a/package/kernel/mac80211/patches/rt2x00/010-rt2x00-clear-IV-s-on-start-to-fix-AP-mode-regression.patch b/package/kernel/mac80211/patches/rt2x00/010-rt2x00-clear-IV-s-on-start-to-fix-AP-mode-regression.patch deleted file mode 100644 index 8859c0dd9e..0000000000 --- a/package/kernel/mac80211/patches/rt2x00/010-rt2x00-clear-IV-s-on-start-to-fix-AP-mode-regression.patch +++ /dev/null @@ -1,113 +0,0 @@ -From patchwork Mon Aug 19 11:20:07 2019 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Stanislaw Gruszka -X-Patchwork-Id: 11100685 -X-Patchwork-Delegate: kvalo@adurom.com -Return-Path: -From: Stanislaw Gruszka -To: linux-wireless@vger.kernel.org -Subject: [PATCH 5.3] rt2x00: clear IV's on start to fix AP mode regression -Date: Mon, 19 Aug 2019 13:20:07 +0200 -Message-Id: <1566213607-6723-1-git-send-email-sgruszka@redhat.com> -Sender: linux-wireless-owner@vger.kernel.org -List-ID: -X-Mailing-List: linux-wireless@vger.kernel.org - -To do not brake HW restart we should keep initialization vectors data. -I assumed that on start the data is already initialized to zeros, but -that not true on some scenarios and we should clear it. So add -additional flag to check if we are under HW restart and clear IV's -data if we are not. - -Patch fixes AP mode regression. - -Reported-and-tested-by: Emil Karlson -Fixes: 710e6cc1595e ("rt2800: do not nullify initialization vector data") -Signed-off-by: Stanislaw Gruszka ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 +++++++++ - drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 + - drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 13 ++++++++----- - 3 files changed, 18 insertions(+), 5 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -6095,6 +6095,15 @@ static int rt2800_init_registers(struct - } - - /* -+ * Clear encryption initialization vectors on start, but keep them -+ * for watchdog reset. Otherwise we will have wrong IVs and not be -+ * able to keep connections after reset. -+ */ -+ if (!test_bit(DEVICE_STATE_RESET, &rt2x00dev->flags)) -+ for (i = 0; i < 256; i++) -+ rt2800_register_write(rt2x00dev, MAC_IVEIV_ENTRY(i), 0); -+ -+ /* - * Clear all beacons - */ - for (i = 0; i < 8; i++) ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -658,6 +658,7 @@ enum rt2x00_state_flags { - DEVICE_STATE_ENABLED_RADIO, - DEVICE_STATE_SCANNING, - DEVICE_STATE_FLUSHING, -+ DEVICE_STATE_RESET, - - /* - * Driver configuration ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1256,13 +1256,14 @@ static int rt2x00lib_initialize(struct r - - int rt2x00lib_start(struct rt2x00_dev *rt2x00dev) - { -- int retval; -+ int retval = 0; - - if (test_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags)) { - /* - * This is special case for ieee80211_restart_hw(), otherwise - * mac80211 never call start() two times in row without stop(); - */ -+ set_bit(DEVICE_STATE_RESET, &rt2x00dev->flags); - rt2x00dev->ops->lib->pre_reset_hw(rt2x00dev); - rt2x00lib_stop(rt2x00dev); - } -@@ -1273,14 +1274,14 @@ int rt2x00lib_start(struct rt2x00_dev *r - */ - retval = rt2x00lib_load_firmware(rt2x00dev); - if (retval) -- return retval; -+ goto out; - - /* - * Initialize the device. - */ - retval = rt2x00lib_initialize(rt2x00dev); - if (retval) -- return retval; -+ goto out; - - rt2x00dev->intf_ap_count = 0; - rt2x00dev->intf_sta_count = 0; -@@ -1289,11 +1290,13 @@ int rt2x00lib_start(struct rt2x00_dev *r - /* Enable the radio */ - retval = rt2x00lib_enable_radio(rt2x00dev); - if (retval) -- return retval; -+ goto out; - - set_bit(DEVICE_STATE_STARTED, &rt2x00dev->flags); - -- return 0; -+out: -+ clear_bit(DEVICE_STATE_RESET, &rt2x00dev->flags); -+ return retval; - } - - void rt2x00lib_stop(struct rt2x00_dev *rt2x00dev) diff --git a/package/kernel/mac80211/patches/rt2x00/010-rt2x00-rt61pci-mark-expected-switch-fall-through.patch b/package/kernel/mac80211/patches/rt2x00/010-rt2x00-rt61pci-mark-expected-switch-fall-through.patch new file mode 100644 index 0000000000..5b0f96d293 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/010-rt2x00-rt61pci-mark-expected-switch-fall-through.patch @@ -0,0 +1,25 @@ +From 641dd8068ecb078e7d12efe465df202bc16ca5eb Mon Sep 17 00:00:00 2001 +From: "Gustavo A. R. Silva" +Date: Mon, 22 Oct 2018 22:46:47 +0200 +Subject: [PATCH 10/28] rt2x00: rt61pci: mark expected switch fall-through + +In preparation to enabling -Wimplicit-fallthrough, mark switch cases +where we are expecting to fall through. + +Signed-off-by: Gustavo A. R. Silva +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt61pci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c +@@ -2226,7 +2226,7 @@ static void rt61pci_txdone(struct rt2x00 + break; + case 6: /* Failure, excessive retries */ + __set_bit(TXDONE_EXCESSIVE_RETRY, &txdesc.flags); +- /* Don't break, this is a failed frame! */ ++ /* Fall through - this is a failed frame! */ + default: /* Failure */ + __set_bit(TXDONE_FAILURE, &txdesc.flags); + } diff --git a/package/kernel/mac80211/patches/rt2x00/011-cross-tree-phase-out-dma_zalloc_coherent.patch b/package/kernel/mac80211/patches/rt2x00/011-cross-tree-phase-out-dma_zalloc_coherent.patch new file mode 100644 index 0000000000..8100eb063b --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/011-cross-tree-phase-out-dma_zalloc_coherent.patch @@ -0,0 +1,40 @@ +From 750afb08ca71310fcf0c4e2cb1565c63b8235b60 Mon Sep 17 00:00:00 2001 +From: Luis Chamberlain +Date: Fri, 4 Jan 2019 09:23:09 +0100 +Subject: [PATCH 11/28] cross-tree: phase out dma_zalloc_coherent() + +We already need to zero out memory for dma_alloc_coherent(), as such +using dma_zalloc_coherent() is superflous. Phase it out. + +This change was generated with the following Coccinelle SmPL patch: + +@ replace_dma_zalloc_coherent @ +expression dev, size, data, handle, flags; +@@ + +-dma_zalloc_coherent(dev, size, handle, flags) ++dma_alloc_coherent(dev, size, handle, flags) + +Suggested-by: Christoph Hellwig +Signed-off-by: Luis Chamberlain +[hch: re-ran the script on the latest tree] +Signed-off-by: Christoph Hellwig +--- + drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.c +@@ -119,9 +119,9 @@ static int rt2x00mmio_alloc_queue_dma(st + /* + * Allocate DMA memory for descriptor and buffer. + */ +- addr = dma_zalloc_coherent(rt2x00dev->dev, +- queue->limit * queue->desc_size, &dma, +- GFP_KERNEL); ++ addr = dma_alloc_coherent(rt2x00dev->dev, ++ queue->limit * queue->desc_size, &dma, ++ GFP_KERNEL); + if (!addr) + return -ENOMEM; + diff --git a/package/kernel/mac80211/patches/rt2x00/011-rt2x00-clear-up-IV-s-on-key-removal.patch b/package/kernel/mac80211/patches/rt2x00/011-rt2x00-clear-up-IV-s-on-key-removal.patch deleted file mode 100644 index 7f3f139e9f..0000000000 --- a/package/kernel/mac80211/patches/rt2x00/011-rt2x00-clear-up-IV-s-on-key-removal.patch +++ /dev/null @@ -1,55 +0,0 @@ -From patchwork Fri Aug 23 12:48:03 2019 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Stanislaw Gruszka -X-Patchwork-Id: 11111605 -X-Patchwork-Delegate: kvalo@adurom.com -From: Stanislaw Gruszka -To: linux-wireless@vger.kernel.org -Subject: [PATCH 5.3] rt2x00: clear up IV's on key removal -Date: Fri, 23 Aug 2019 14:48:03 +0200 -Message-Id: <1566564483-31088-1-git-send-email-sgruszka@redhat.com> -Sender: linux-wireless-owner@vger.kernel.org -List-ID: -X-Mailing-List: linux-wireless@vger.kernel.org - -After looking at code I realized that my previous fix -95844124385e ("rt2x00: clear IV's on start to fix AP mode regression") -was incomplete. We can still have wrong IV's after re-keyring. -To fix that, clear up IV's also on key removal. - -Fixes: 710e6cc1595e ("rt2800: do not nullify initialization vector data") -Signed-off-by: Stanislaw Gruszka ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 19 ++++++++++++------- - 1 file changed, 12 insertions(+), 7 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -1654,13 +1654,18 @@ static void rt2800_config_wcid_attr_ciph - - offset = MAC_IVEIV_ENTRY(key->hw_key_idx); - -- rt2800_register_multiread(rt2x00dev, offset, -- &iveiv_entry, sizeof(iveiv_entry)); -- if ((crypto->cipher == CIPHER_TKIP) || -- (crypto->cipher == CIPHER_TKIP_NO_MIC) || -- (crypto->cipher == CIPHER_AES)) -- iveiv_entry.iv[3] |= 0x20; -- iveiv_entry.iv[3] |= key->keyidx << 6; -+ if (crypto->cmd == SET_KEY) { -+ rt2800_register_multiread(rt2x00dev, offset, -+ &iveiv_entry, sizeof(iveiv_entry)); -+ if ((crypto->cipher == CIPHER_TKIP) || -+ (crypto->cipher == CIPHER_TKIP_NO_MIC) || -+ (crypto->cipher == CIPHER_AES)) -+ iveiv_entry.iv[3] |= 0x20; -+ iveiv_entry.iv[3] |= key->keyidx << 6; -+ } else { -+ memset(&iveiv_entry, 0, sizeof(iveiv_entry)); -+ } -+ - rt2800_register_multiwrite(rt2x00dev, offset, - &iveiv_entry, sizeof(iveiv_entry)); - } diff --git a/package/kernel/mac80211/patches/rt2x00/012-rt2x00-reduce-tx-power-to-nominal-level-on-RT6352.patch b/package/kernel/mac80211/patches/rt2x00/012-rt2x00-reduce-tx-power-to-nominal-level-on-RT6352.patch new file mode 100644 index 0000000000..a07832e97c --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/012-rt2x00-reduce-tx-power-to-nominal-level-on-RT6352.patch @@ -0,0 +1,32 @@ +From c2e28ef7711ffcb083474ee5f154264c6ec1ec07 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= +Date: Thu, 27 Dec 2018 15:05:25 +0100 +Subject: [PATCH 12/28] rt2x00: reduce tx power to nominal level on RT6352 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Current implementation of RT6352 support provides too high tx power +at least on iPA/eLNA devices. Reduce amplification of variable gain +amplifier by 6dB to match board target power of 17dBm. +Transmited signal strength with this patch is similar to that of +stock firmware or pandorabox firmware. Throughput measured with iperf +improves. Device tested: Xiaomi Miwifi Mini. + +Signed-off-by: Tomislav Požega +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -5477,7 +5477,7 @@ static int rt2800_init_registers(struct + rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00000000); + rt2800_register_write(rt2x00dev, MIMO_PS_CFG, 0x00000002); + rt2800_register_write(rt2x00dev, TX_PIN_CFG, 0x00150F0F); +- rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x06060606); ++ rt2800_register_write(rt2x00dev, TX_ALC_VGA3, 0x00000000); + rt2800_register_write(rt2x00dev, TX0_BB_GAIN_ATTEN, 0x0); + rt2800_register_write(rt2x00dev, TX1_BB_GAIN_ATTEN, 0x0); + rt2800_register_write(rt2x00dev, TX0_RF_GAIN_ATTEN, 0x6C6C666C); diff --git a/package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch b/package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch new file mode 100644 index 0000000000..dc884c17d2 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/013-rt2x00-Work-around-a-firmware-bug-with-shared-keys.patch @@ -0,0 +1,143 @@ +From a4296994eb8061ee3455721a296c387c639bf635 Mon Sep 17 00:00:00 2001 +From: Bernd Edlinger +Date: Tue, 15 Jan 2019 14:01:29 +0000 +Subject: [PATCH 13/28] rt2x00: Work around a firmware bug with shared keys + +Apparently the rt2x61 firmware fails temporarily to decode +broadcast packets if the shared keys are not assigned +in the "correct" sequence. At the same time unicast +packets work fine, since they are encrypted with the +pairwise key. + +At least with WPA2 CCMP mode the shared keys are +set in the following sequence: keyidx=1, 2, 1, 2. +After a while only keyidx 2 gets decrypted, and +keyidx 1 is ignored, probably because there is never +a keyidx 3. + +Symptoms are arping -b works for 10 minutes, since +keyidx=2 is used for broadcast, and then it stops +working for 10 minutes, because keyidx=1 is used. +That failure mode repeats forever. + +Note, the firmware does not even know which keyidx +corresponds to which hw_key_idx so the firmware is +trying to be smarter than the driver, which is bound +to fail. + +As workaround the function rt61pci_config_shared_key +requests software decryption of the shared keys, +by returning EOPNOTSUPP. However, pairwise keys are +still handled by hardware which works just fine. + +Signed-off-by: Bernd Edlinger +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt61pci.c | 93 +------------------- + 1 file changed, 4 insertions(+), 89 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt61pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt61pci.c +@@ -321,97 +321,12 @@ static int rt61pci_config_shared_key(str + struct rt2x00lib_crypto *crypto, + struct ieee80211_key_conf *key) + { +- struct hw_key_entry key_entry; +- struct rt2x00_field32 field; +- u32 mask; +- u32 reg; +- +- if (crypto->cmd == SET_KEY) { +- /* +- * rt2x00lib can't determine the correct free +- * key_idx for shared keys. We have 1 register +- * with key valid bits. The goal is simple, read +- * the register, if that is full we have no slots +- * left. +- * Note that each BSS is allowed to have up to 4 +- * shared keys, so put a mask over the allowed +- * entries. +- */ +- mask = (0xf << crypto->bssidx); +- +- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0); +- reg &= mask; +- +- if (reg && reg == mask) +- return -ENOSPC; +- +- key->hw_key_idx += reg ? ffz(reg) : 0; +- +- /* +- * Upload key to hardware +- */ +- memcpy(key_entry.key, crypto->key, +- sizeof(key_entry.key)); +- memcpy(key_entry.tx_mic, crypto->tx_mic, +- sizeof(key_entry.tx_mic)); +- memcpy(key_entry.rx_mic, crypto->rx_mic, +- sizeof(key_entry.rx_mic)); +- +- reg = SHARED_KEY_ENTRY(key->hw_key_idx); +- rt2x00mmio_register_multiwrite(rt2x00dev, reg, +- &key_entry, sizeof(key_entry)); +- +- /* +- * The cipher types are stored over 2 registers. +- * bssidx 0 and 1 keys are stored in SEC_CSR1 and +- * bssidx 1 and 2 keys are stored in SEC_CSR5. +- * Using the correct defines correctly will cause overhead, +- * so just calculate the correct offset. +- */ +- if (key->hw_key_idx < 8) { +- field.bit_offset = (3 * key->hw_key_idx); +- field.bit_mask = 0x7 << field.bit_offset; +- +- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR1); +- rt2x00_set_field32(®, field, crypto->cipher); +- rt2x00mmio_register_write(rt2x00dev, SEC_CSR1, reg); +- } else { +- field.bit_offset = (3 * (key->hw_key_idx - 8)); +- field.bit_mask = 0x7 << field.bit_offset; +- +- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR5); +- rt2x00_set_field32(®, field, crypto->cipher); +- rt2x00mmio_register_write(rt2x00dev, SEC_CSR5, reg); +- } +- +- /* +- * The driver does not support the IV/EIV generation +- * in hardware. However it doesn't support the IV/EIV +- * inside the ieee80211 frame either, but requires it +- * to be provided separately for the descriptor. +- * rt2x00lib will cut the IV/EIV data out of all frames +- * given to us by mac80211, but we must tell mac80211 +- * to generate the IV/EIV data. +- */ +- key->flags |= IEEE80211_KEY_FLAG_GENERATE_IV; +- } +- + /* +- * SEC_CSR0 contains only single-bit fields to indicate +- * a particular key is valid. Because using the FIELD32() +- * defines directly will cause a lot of overhead, we use +- * a calculation to determine the correct bit directly. ++ * Let the software handle the shared keys, ++ * since the hardware decryption does not work reliably, ++ * because the firmware does not know the key's keyidx. + */ +- mask = 1 << key->hw_key_idx; +- +- reg = rt2x00mmio_register_read(rt2x00dev, SEC_CSR0); +- if (crypto->cmd == SET_KEY) +- reg |= mask; +- else if (crypto->cmd == DISABLE_KEY) +- reg &= ~mask; +- rt2x00mmio_register_write(rt2x00dev, SEC_CSR0, reg); +- +- return 0; ++ return -EOPNOTSUPP; + } + + static int rt61pci_config_pairwise_key(struct rt2x00_dev *rt2x00dev, diff --git a/package/kernel/mac80211/patches/rt2x00/014-rt2x00-no-need-to-check-return-value-of-debugfs_crea.patch b/package/kernel/mac80211/patches/rt2x00/014-rt2x00-no-need-to-check-return-value-of-debugfs_crea.patch new file mode 100644 index 0000000000..26f2df10e0 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/014-rt2x00-no-need-to-check-return-value-of-debugfs_crea.patch @@ -0,0 +1,107 @@ +From 2587791d57588562c21e5ef7e678f02ab2f3eb82 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Tue, 22 Jan 2019 16:21:34 +0100 +Subject: [PATCH 14/28] rt2x00: no need to check return value of debugfs_create + functions + +When calling debugfs functions, there is no need to ever check the +return value. The function can work or not, but the code logic should +never do something different based on this. + +Cc: Stanislaw Gruszka +Cc: Helmut Schaa +Cc: Kalle Valo +Cc: linux-wireless@vger.kernel.org +Signed-off-by: Greg Kroah-Hartman +Acked-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + .../net/wireless/ralink/rt2x00/rt2x00debug.c | 27 ------------------- + 1 file changed, 27 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c +@@ -656,36 +656,24 @@ void rt2x00debug_register(struct rt2x00_ + intf->driver_folder = + debugfs_create_dir(intf->rt2x00dev->ops->name, + rt2x00dev->hw->wiphy->debugfsdir); +- if (IS_ERR(intf->driver_folder) || !intf->driver_folder) +- goto exit; + + intf->driver_entry = + rt2x00debug_create_file_driver("driver", intf, &intf->driver_blob); +- if (IS_ERR(intf->driver_entry) || !intf->driver_entry) +- goto exit; + + intf->chipset_entry = + rt2x00debug_create_file_chipset("chipset", + intf, &intf->chipset_blob); +- if (IS_ERR(intf->chipset_entry) || !intf->chipset_entry) +- goto exit; + + intf->dev_flags = debugfs_create_file("dev_flags", 0400, + intf->driver_folder, intf, + &rt2x00debug_fop_dev_flags); +- if (IS_ERR(intf->dev_flags) || !intf->dev_flags) +- goto exit; + + intf->cap_flags = debugfs_create_file("cap_flags", 0400, + intf->driver_folder, intf, + &rt2x00debug_fop_cap_flags); +- if (IS_ERR(intf->cap_flags) || !intf->cap_flags) +- goto exit; + + intf->register_folder = + debugfs_create_dir("register", intf->driver_folder); +- if (IS_ERR(intf->register_folder) || !intf->register_folder) +- goto exit; + + #define RT2X00DEBUGFS_CREATE_REGISTER_ENTRY(__intf, __name) \ + ({ \ +@@ -695,9 +683,6 @@ void rt2x00debug_register(struct rt2x00_ + 0600, \ + (__intf)->register_folder, \ + &(__intf)->offset_##__name); \ +- if (IS_ERR((__intf)->__name##_off_entry) || \ +- !(__intf)->__name##_off_entry) \ +- goto exit; \ + \ + (__intf)->__name##_val_entry = \ + debugfs_create_file(__stringify(__name) "_value", \ +@@ -705,9 +690,6 @@ void rt2x00debug_register(struct rt2x00_ + (__intf)->register_folder, \ + (__intf), \ + &rt2x00debug_fop_##__name); \ +- if (IS_ERR((__intf)->__name##_val_entry) || \ +- !(__intf)->__name##_val_entry) \ +- goto exit; \ + } \ + }) + +@@ -721,15 +703,10 @@ void rt2x00debug_register(struct rt2x00_ + + intf->queue_folder = + debugfs_create_dir("queue", intf->driver_folder); +- if (IS_ERR(intf->queue_folder) || !intf->queue_folder) +- goto exit; + + intf->queue_frame_dump_entry = + debugfs_create_file("dump", 0400, intf->queue_folder, + intf, &rt2x00debug_fop_queue_dump); +- if (IS_ERR(intf->queue_frame_dump_entry) +- || !intf->queue_frame_dump_entry) +- goto exit; + + skb_queue_head_init(&intf->frame_dump_skbqueue); + init_waitqueue_head(&intf->frame_dump_waitqueue); +@@ -747,10 +724,6 @@ void rt2x00debug_register(struct rt2x00_ + #endif + + return; +- +-exit: +- rt2x00debug_deregister(rt2x00dev); +- rt2x00_err(rt2x00dev, "Failed to register debug handler\n"); + } + + void rt2x00debug_deregister(struct rt2x00_dev *rt2x00dev) diff --git a/package/kernel/mac80211/patches/rt2x00/015-rt2x00-do-not-set-IEEE80211_TX_STAT_AMPDU_NO_BACK-on-tx-status.patch b/package/kernel/mac80211/patches/rt2x00/015-rt2x00-do-not-set-IEEE80211_TX_STAT_AMPDU_NO_BACK-on-tx-status.patch deleted file mode 100644 index a4497df475..0000000000 --- a/package/kernel/mac80211/patches/rt2x00/015-rt2x00-do-not-set-IEEE80211_TX_STAT_AMPDU_NO_BACK-on-tx-status.patch +++ /dev/null @@ -1,50 +0,0 @@ -From patchwork Fri Aug 23 07:09:56 2019 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Stanislaw Gruszka -X-Patchwork-Id: 11110703 -X-Patchwork-Delegate: kvalo@adurom.com -From: Stanislaw Gruszka -To: linux-wireless@vger.kernel.org -Subject: [PATCH] rt2x00: do not set IEEE80211_TX_STAT_AMPDU_NO_BACK on tx - status -Date: Fri, 23 Aug 2019 09:09:56 +0200 -Message-Id: <1566544196-20371-1-git-send-email-sgruszka@redhat.com> -Sender: linux-wireless-owner@vger.kernel.org -List-ID: -X-Mailing-List: linux-wireless@vger.kernel.org - -According to documentation IEEE80211_TX_STAT_AMPDU_NO_BACK is suppose -to be used when we do not recive BA (BlockAck). However on rt2x00 we -use it when remote station fail to decode one or more subframes within -AMPDU (some bits are not set in BlockAck bitmap). Setting the flag result -in sent of BAR (BlockAck Request) frame and this might result of abuse -of BA session, since remote station can sent BA with incorrect -sequence numbers after receiving BAR. This problem is visible especially -when connecting two rt2800 devices. - -Previously I observed some performance benefits when using the flag -when connecting with iwlwifi devices. But currently possibly due -to reacent changes in rt2x00 removing the flag has no effect on -those test cases. - -So remove the IEEE80211_TX_STAT_AMPDU_NO_BACK. - -Signed-off-by: Stanislaw Gruszka ---- - drivers/net/wireless/ralink/rt2x00/rt2x00dev.c | 3 --- - 1 file changed, 3 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -371,9 +371,6 @@ static void rt2x00lib_fill_tx_status(str - IEEE80211_TX_CTL_AMPDU; - tx_info->status.ampdu_len = 1; - tx_info->status.ampdu_ack_len = success ? 1 : 0; -- -- if (!success) -- tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - } - - if (rate_flags & IEEE80211_TX_RC_USE_RTS_CTS) { diff --git a/package/kernel/mac80211/patches/rt2x00/015-rt2x00-remove-unneeded-check.patch b/package/kernel/mac80211/patches/rt2x00/015-rt2x00-remove-unneeded-check.patch new file mode 100644 index 0000000000..50e7de0855 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/015-rt2x00-remove-unneeded-check.patch @@ -0,0 +1,137 @@ +From 17ae2acd1a6f5148edd80d84194e5d7c80be360e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= +Date: Wed, 13 Feb 2019 11:09:12 +0100 +Subject: [PATCH 15/28] rt2x00: remove unneeded check +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Remove band check from rf53xx channel config routine since all chips +using it are single band. + +Signed-off-by: Tomislav Požega +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 103 +++++++++--------- + 1 file changed, 50 insertions(+), 53 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -2966,6 +2966,7 @@ static void rt2800_config_channel_rf53xx + struct channel_info *info) + { + u8 rfcsr; ++ int idx = rf->channel-1; + + rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); + rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); +@@ -3003,60 +3004,56 @@ static void rt2800_config_channel_rf53xx + + rt2800_freq_cal_mode1(rt2x00dev); + +- if (rf->channel <= 14) { +- int idx = rf->channel-1; ++ if (rt2x00_has_cap_bt_coexist(rt2x00dev)) { ++ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { ++ /* r55/r59 value array of channel 1~14 */ ++ static const char r55_bt_rev[] = {0x83, 0x83, ++ 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, ++ 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; ++ static const char r59_bt_rev[] = {0x0e, 0x0e, ++ 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, ++ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; ++ ++ rt2800_rfcsr_write(rt2x00dev, 55, ++ r55_bt_rev[idx]); ++ rt2800_rfcsr_write(rt2x00dev, 59, ++ r59_bt_rev[idx]); ++ } else { ++ static const char r59_bt[] = {0x8b, 0x8b, 0x8b, ++ 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, ++ 0x88, 0x88, 0x86, 0x85, 0x84}; + +- if (rt2x00_has_cap_bt_coexist(rt2x00dev)) { +- if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { +- /* r55/r59 value array of channel 1~14 */ +- static const char r55_bt_rev[] = {0x83, 0x83, +- 0x83, 0x73, 0x73, 0x63, 0x53, 0x53, +- 0x53, 0x43, 0x43, 0x43, 0x43, 0x43}; +- static const char r59_bt_rev[] = {0x0e, 0x0e, +- 0x0e, 0x0e, 0x0e, 0x0b, 0x0a, 0x09, +- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07}; +- +- rt2800_rfcsr_write(rt2x00dev, 55, +- r55_bt_rev[idx]); +- rt2800_rfcsr_write(rt2x00dev, 59, +- r59_bt_rev[idx]); +- } else { +- static const char r59_bt[] = {0x8b, 0x8b, 0x8b, +- 0x8b, 0x8b, 0x8b, 0x8b, 0x8a, 0x89, +- 0x88, 0x88, 0x86, 0x85, 0x84}; ++ rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); ++ } ++ } else { ++ if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { ++ static const char r55_nonbt_rev[] = {0x23, 0x23, ++ 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, ++ 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; ++ static const char r59_nonbt_rev[] = {0x07, 0x07, ++ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, ++ 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; ++ ++ rt2800_rfcsr_write(rt2x00dev, 55, ++ r55_nonbt_rev[idx]); ++ rt2800_rfcsr_write(rt2x00dev, 59, ++ r59_nonbt_rev[idx]); ++ } else if (rt2x00_rt(rt2x00dev, RT5390) || ++ rt2x00_rt(rt2x00dev, RT5392) || ++ rt2x00_rt(rt2x00dev, RT6352)) { ++ static const char r59_non_bt[] = {0x8f, 0x8f, ++ 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, ++ 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; ++ ++ rt2800_rfcsr_write(rt2x00dev, 59, ++ r59_non_bt[idx]); ++ } else if (rt2x00_rt(rt2x00dev, RT5350)) { ++ static const char r59_non_bt[] = {0x0b, 0x0b, ++ 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, ++ 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06}; + +- rt2800_rfcsr_write(rt2x00dev, 59, r59_bt[idx]); +- } +- } else { +- if (rt2x00_rt_rev_gte(rt2x00dev, RT5390, REV_RT5390F)) { +- static const char r55_nonbt_rev[] = {0x23, 0x23, +- 0x23, 0x23, 0x13, 0x13, 0x03, 0x03, +- 0x03, 0x03, 0x03, 0x03, 0x03, 0x03}; +- static const char r59_nonbt_rev[] = {0x07, 0x07, +- 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, +- 0x07, 0x07, 0x06, 0x05, 0x04, 0x04}; +- +- rt2800_rfcsr_write(rt2x00dev, 55, +- r55_nonbt_rev[idx]); +- rt2800_rfcsr_write(rt2x00dev, 59, +- r59_nonbt_rev[idx]); +- } else if (rt2x00_rt(rt2x00dev, RT5390) || +- rt2x00_rt(rt2x00dev, RT5392) || +- rt2x00_rt(rt2x00dev, RT6352)) { +- static const char r59_non_bt[] = {0x8f, 0x8f, +- 0x8f, 0x8f, 0x8f, 0x8f, 0x8f, 0x8d, +- 0x8a, 0x88, 0x88, 0x87, 0x87, 0x86}; +- +- rt2800_rfcsr_write(rt2x00dev, 59, +- r59_non_bt[idx]); +- } else if (rt2x00_rt(rt2x00dev, RT5350)) { +- static const char r59_non_bt[] = {0x0b, 0x0b, +- 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a, +- 0x0a, 0x09, 0x08, 0x07, 0x07, 0x06}; +- +- rt2800_rfcsr_write(rt2x00dev, 59, +- r59_non_bt[idx]); +- } ++ rt2800_rfcsr_write(rt2x00dev, 59, ++ r59_non_bt[idx]); + } + } + } diff --git a/package/kernel/mac80211/patches/rt2x00/016-rt2x00-remove-confusing-AGC-register.patch b/package/kernel/mac80211/patches/rt2x00/016-rt2x00-remove-confusing-AGC-register.patch new file mode 100644 index 0000000000..8f3791d2ce --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/016-rt2x00-remove-confusing-AGC-register.patch @@ -0,0 +1,34 @@ +From 5991a2ecd070ce5ef646b4e8e0bc8d99110604ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Tomislav=20Po=C5=BEega?= +Date: Wed, 13 Feb 2019 11:09:13 +0100 +Subject: [PATCH 16/28] rt2x00: remove confusing AGC register +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Register 66 was causing issues on RT6352 if set to the same value as +in MTK driver. With 1c reg value device was working fine in both HT20 +and HT40 modes. + +Signed-off-by: Tomislav Požega +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 6 +----- + 1 file changed, 1 insertion(+), 5 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3983,11 +3983,7 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 196, reg); + + /* AGC init */ +- if (rt2x00_rt(rt2x00dev, RT6352)) +- reg = 0x04; +- else +- reg = rf->channel <= 14 ? 0x1c : 0x24; +- ++ reg = rf->channel <= 14 ? 0x1c : 0x24; + reg += 2 * rt2x00dev->lna_gain; + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); + diff --git a/package/kernel/mac80211/patches/rt2x00/016-rt2x00-revert-rt2800-enable-TX_PIN_CFG_LNA_PE_-bits-per-band.patch b/package/kernel/mac80211/patches/rt2x00/016-rt2x00-revert-rt2800-enable-TX_PIN_CFG_LNA_PE_-bits-per-band.patch deleted file mode 100644 index 3fcf231870..0000000000 --- a/package/kernel/mac80211/patches/rt2x00/016-rt2x00-revert-rt2800-enable-TX_PIN_CFG_LNA_PE_-bits-per-band.patch +++ /dev/null @@ -1,70 +0,0 @@ -From patchwork Thu Aug 29 11:29:59 2019 -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Stanislaw Gruszka -X-Patchwork-Id: 11121089 -X-Patchwork-Delegate: kvalo@adurom.com -From: Stanislaw Gruszka -To: linux-wireless@vger.kernel.org -Subject: [PATCH 5.3] Revert "rt2800: enable TX_PIN_CFG_LNA_PE_ bits per band" -Date: Thu, 29 Aug 2019 13:29:59 +0200 -Message-Id: <1567078199-3645-1-git-send-email-sgruszka@redhat.com> -Sender: linux-wireless-owner@vger.kernel.org -List-ID: -X-Mailing-List: linux-wireless@vger.kernel.org - -This reverts commit 9ad3b55654455258a9463384edb40077439d879f. - -As reported by Sergey: - -"I got some problem after upgrade kernel to 5.2 version (debian testing -linux-image-5.2.0-2-amd64). 5Ghz client stopped to see AP. -Some tests with 1metre distance between client-AP: 2.4Ghz -22dBm, for -5Ghz - 53dBm !, for longer distance (8m + walls) 2.4 - 61dBm, 5Ghz not -visible." - -It was identified that rx signal level degradation was caused by -9ad3b5565445 ("rt2800: enable TX_PIN_CFG_LNA_PE_ bits per band"). -So revert this commit. - -Cc: # v5.1+ -Reported-and-tested-by: Sergey Maranchuk -Signed-off-by: Stanislaw Gruszka ---- - drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 18 ++++++------------ - 1 file changed, 6 insertions(+), 12 deletions(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4242,24 +4242,18 @@ static void rt2800_config_channel(struct - switch (rt2x00dev->default_ant.rx_chain_num) { - case 3: - /* Turn on tertiary LNAs */ -- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, -- rf->channel > 14); -- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, -- rf->channel <= 14); -+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1); -+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1); - /* fall-through */ - case 2: - /* Turn on secondary LNAs */ -- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, -- rf->channel > 14); -- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, -- rf->channel <= 14); -+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); -+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); - /* fall-through */ - case 1: - /* Turn on primary LNAs */ -- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, -- rf->channel > 14); -- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, -- rf->channel <= 14); -+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1); -+ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1); - break; - } - diff --git a/package/kernel/mac80211/patches/rt2x00/017-rt2800-enable-TX_PIN_CFG_LNA_PE_-bits-per-band.patch b/package/kernel/mac80211/patches/rt2x00/017-rt2800-enable-TX_PIN_CFG_LNA_PE_-bits-per-band.patch new file mode 100644 index 0000000000..eb82d6275b --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/017-rt2800-enable-TX_PIN_CFG_LNA_PE_-bits-per-band.patch @@ -0,0 +1,47 @@ +From 9ad3b55654455258a9463384edb40077439d879f Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 13 Feb 2019 11:09:14 +0100 +Subject: [PATCH 17/28] rt2800: enable TX_PIN_CFG_LNA_PE_ bits per band + +Do not enable TX_PIN_CFG_LNA_PE_A* bits for 2.4GHz band and +vice versa TX_PIN_CFG_LNA_PE_G* bits for 5GHz. + +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3893,18 +3893,24 @@ static void rt2800_config_channel(struct + switch (rt2x00dev->default_ant.rx_chain_num) { + case 3: + /* Turn on tertiary LNAs */ +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1); +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, ++ rf->channel > 14); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, ++ rf->channel <= 14); + /* fall-through */ + case 2: + /* Turn on secondary LNAs */ +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, ++ rf->channel > 14); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, ++ rf->channel <= 14); + /* fall-through */ + case 1: + /* Turn on primary LNAs */ +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1); +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, ++ rf->channel > 14); ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, ++ rf->channel <= 14); + break; + } + diff --git a/package/kernel/mac80211/patches/rt2x00/017-rt2x00-initialize-last_reset.patch b/package/kernel/mac80211/patches/rt2x00/017-rt2x00-initialize-last_reset.patch deleted file mode 100644 index 034bfdf757..0000000000 --- a/package/kernel/mac80211/patches/rt2x00/017-rt2x00-initialize-last_reset.patch +++ /dev/null @@ -1,35 +0,0 @@ -Content-Type: text/plain; charset="utf-8" -MIME-Version: 1.0 -Content-Transfer-Encoding: 7bit -X-Patchwork-Submitter: Stanislaw Gruszka -X-Patchwork-Id: 11161981 -From: Stanislaw Gruszka -To: linux-wireless@vger.kernel.org -Subject: [PATCH] rt2x00: initialize last_reset -Date: Thu, 26 Sep 2019 10:54:33 +0200 -Message-Id: <20190926085433.1300-1-sgruszka@redhat.com> -Sender: linux-wireless-owner@vger.kernel.org -List-ID: -X-Mailing-List: linux-wireless@vger.kernel.org - -Initialize last_reset variable to INITIAL_JIFFIES, otherwise it is not -possible to test H/W reset for first 5 minutes of system run. - -Fixes: e403fa31ed71 ("rt2x00: add restart hw") -Reported-and-tested-by: Jonathan Liu -Signed-off-by: Stanislaw Gruszka ---- - drivers/net/wireless/ralink/rt2x00/rt2x00debug.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - ---- a/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c -+++ b/drivers/net/wireless/ralink/rt2x00/rt2x00debug.c -@@ -575,7 +575,7 @@ static ssize_t rt2x00debug_write_restart - { - struct rt2x00debug_intf *intf = file->private_data; - struct rt2x00_dev *rt2x00dev = intf->rt2x00dev; -- static unsigned long last_reset; -+ static unsigned long last_reset = INITIAL_JIFFIES; - - if (!rt2x00_has_cap_restart_hw(rt2x00dev)) - return -EOPNOTSUPP; diff --git a/package/kernel/mac80211/patches/rt2x00/018-rt2800-enable-TX_PIN_CFG_RFRX_EN-only-for-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/018-rt2800-enable-TX_PIN_CFG_RFRX_EN-only-for-MT7620.patch new file mode 100644 index 0000000000..3a4c2cd8e5 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/018-rt2800-enable-TX_PIN_CFG_RFRX_EN-only-for-MT7620.patch @@ -0,0 +1,41 @@ +From 7aca14885edeab536a8cbe1e7cfeadd4c3310b9b Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 13 Feb 2019 11:09:15 +0100 +Subject: [PATCH 18/28] rt2800: enable TX_PIN_CFG_RFRX_EN only for MT7620 + +The TX_PIN_CFG_RFRX_EN bit was not set on other devices than MT7620, +restore old behavaviour since setting this bit maight not be +correct for older devices. + +Fixes: 41977e86c984 ("rt2x00: add support for MT7620") +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3858,10 +3858,12 @@ static void rt2800_config_channel(struct + if (rt2x00_rt(rt2x00dev, RT3572)) + rt2800_rfcsr_write(rt2x00dev, 8, 0); + +- if (rt2x00_rt(rt2x00dev, RT6352)) ++ if (rt2x00_rt(rt2x00dev, RT6352)) { + tx_pin = rt2800_register_read(rt2x00dev, TX_PIN_CFG); +- else ++ rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); ++ } else { + tx_pin = 0; ++ } + + switch (rt2x00dev->default_ant.tx_chain_num) { + case 3: +@@ -3916,7 +3918,6 @@ static void rt2800_config_channel(struct + + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); + rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); +- rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFRX_EN, 1); /* mt7620 */ + + rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); + diff --git a/package/kernel/mac80211/patches/rt2x00/019-rt2800-comment-and-simplify-AGC-init-for-RT6352.patch b/package/kernel/mac80211/patches/rt2x00/019-rt2800-comment-and-simplify-AGC-init-for-RT6352.patch new file mode 100644 index 0000000000..4d0beb263d --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/019-rt2800-comment-and-simplify-AGC-init-for-RT6352.patch @@ -0,0 +1,33 @@ +From c7ff1bfeaf1ca69e3e401be211b55d1738d0c5fc Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Wed, 13 Feb 2019 11:09:16 +0100 +Subject: [PATCH 19/28] rt2800: comment and simplify AGC init for RT6352 + +We do not need separate lines for calculating register values. +Also add comment that value is different than in vendor driver. + +Suggested-by: Daniel Golle +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -3989,9 +3989,12 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 195, 141); + rt2800_bbp_write(rt2x00dev, 196, reg); + +- /* AGC init */ +- reg = rf->channel <= 14 ? 0x1c : 0x24; +- reg += 2 * rt2x00dev->lna_gain; ++ /* AGC init. ++ * Despite the vendor driver using different values here for ++ * RT6352 chip, we use 0x1c for now. This may have to be changed ++ * once TSSI got implemented. ++ */ ++ reg = (rf->channel <= 14 ? 0x1c : 0x24) + 2*rt2x00dev->lna_gain; + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); + + rt2800_iq_calibrate(rt2x00dev, rf->channel); diff --git a/package/kernel/mac80211/patches/rt2x00/020-cfg80211-add-ratelimited-variants-of-err-and-warn.patch b/package/kernel/mac80211/patches/rt2x00/020-cfg80211-add-ratelimited-variants-of-err-and-warn.patch new file mode 100644 index 0000000000..bea1884489 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/020-cfg80211-add-ratelimited-variants-of-err-and-warn.patch @@ -0,0 +1,39 @@ +From patchwork Tue Mar 12 09:51:40 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10848957 +X-Patchwork-Delegate: johannes@sipsolutions.net +From: Stanislaw Gruszka +To: linux-wireless@vger.kernel.org +Cc: =?utf-8?q?Tomislav_Po=C5=BEega?= , + Daniel Golle , Felix Fietkau , + Mathias Kresin +Subject: [PATCH v3 1/4] cfg80211: add ratelimited variants of err and warn +Date: Tue, 12 Mar 2019 10:51:40 +0100 +Message-Id: <1552384303-29529-2-git-send-email-sgruszka@redhat.com> +In-Reply-To: <1552384303-29529-1-git-send-email-sgruszka@redhat.com> +References: <1552384303-29529-1-git-send-email-sgruszka@redhat.com> + +wiphy_{err,warn}_ratelimited will be used by rt2x00 + +Signed-off-by: Stanislaw Gruszka +--- + include/net/cfg80211.h | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -6597,6 +6597,11 @@ int cfg80211_external_auth_request(struc + #define wiphy_info(wiphy, format, args...) \ + dev_info(&(wiphy)->dev, format, ##args) + ++#define wiphy_err_ratelimited(wiphy, format, args...) \ ++ dev_err_ratelimited(&(wiphy)->dev, format, ##args) ++#define wiphy_warn_ratelimited(wiphy, format, args...) \ ++ dev_warn_ratelimited(&(wiphy)->dev, format, ##args) ++ + #define wiphy_debug(wiphy, format, args...) \ + wiphy_printk(KERN_DEBUG, wiphy, format, ##args) + diff --git a/package/kernel/mac80211/patches/rt2x00/021-rt2x00-use-ratelimited-variants-dev_warn-dev_err.patch b/package/kernel/mac80211/patches/rt2x00/021-rt2x00-use-ratelimited-variants-dev_warn-dev_err.patch new file mode 100644 index 0000000000..2d74a71e1f --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/021-rt2x00-use-ratelimited-variants-dev_warn-dev_err.patch @@ -0,0 +1,42 @@ +From patchwork Tue Mar 12 09:51:41 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10848959 +X-Patchwork-Delegate: kvalo@adurom.com +From: Stanislaw Gruszka +To: linux-wireless@vger.kernel.org +Cc: =?utf-8?q?Tomislav_Po=C5=BEega?= , + Daniel Golle , Felix Fietkau , + Mathias Kresin +Subject: [PATCH v3 2/4] rt2x00: use ratelimited variants dev_warn/dev_err +Date: Tue, 12 Mar 2019 10:51:41 +0100 +Message-Id: <1552384303-29529-3-git-send-email-sgruszka@redhat.com> +In-Reply-To: <1552384303-29529-1-git-send-email-sgruszka@redhat.com> +References: <1552384303-29529-1-git-send-email-sgruszka@redhat.com> + +As reported by Randy we can overwhelm logs on some USB error conditions. +To avoid that use dev_warn_ratelimited() and dev_err_ratelimitd(). + +Reported-and-tested-by: Randy Oostdyk +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -69,10 +69,10 @@ + printk(KERN_ERR KBUILD_MODNAME ": %s: Error - " fmt, \ + __func__, ##__VA_ARGS__) + #define rt2x00_err(dev, fmt, ...) \ +- wiphy_err((dev)->hw->wiphy, "%s: Error - " fmt, \ ++ wiphy_err_ratelimited((dev)->hw->wiphy, "%s: Error - " fmt, \ + __func__, ##__VA_ARGS__) + #define rt2x00_warn(dev, fmt, ...) \ +- wiphy_warn((dev)->hw->wiphy, "%s: Warning - " fmt, \ ++ wiphy_warn_ratelimited((dev)->hw->wiphy, "%s: Warning - " fmt, \ + __func__, ##__VA_ARGS__) + #define rt2x00_info(dev, fmt, ...) \ + wiphy_info((dev)->hw->wiphy, "%s: Info - " fmt, \ diff --git a/package/kernel/mac80211/patches/rt2x00/022-rt2x00-check-number-of-EPROTO-errors.patch b/package/kernel/mac80211/patches/rt2x00/022-rt2x00-check-number-of-EPROTO-errors.patch new file mode 100644 index 0000000000..251ac287bf --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/022-rt2x00-check-number-of-EPROTO-errors.patch @@ -0,0 +1,96 @@ +From patchwork Tue Mar 12 09:51:42 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10848961 +X-Patchwork-Delegate: kvalo@adurom.com +From: Stanislaw Gruszka +To: linux-wireless@vger.kernel.org +Cc: =?utf-8?q?Tomislav_Po=C5=BEega?= , + Daniel Golle , Felix Fietkau , + Mathias Kresin +Subject: [PATCH v3 3/4] rt2x00: check number of EPROTO errors +Date: Tue, 12 Mar 2019 10:51:42 +0100 +Message-Id: <1552384303-29529-4-git-send-email-sgruszka@redhat.com> +In-Reply-To: <1552384303-29529-1-git-send-email-sgruszka@redhat.com> +References: <1552384303-29529-1-git-send-email-sgruszka@redhat.com> + +Some USB host devices/drivers on some conditions can always return +EPROTO error on submitted URBs. That can cause infinity loop in the +rt2x00 driver. + +Since we can have single EPROTO errors we can not mark as device as +removed to avoid infinity loop. However we can count consecutive +EPROTO errors and mark device as removed if get lot of it. +I choose number 10 as threshold. + +Reported-and-tested-by: Randy Oostdyk +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 + + drivers/net/wireless/ralink/rt2x00/rt2x00usb.c | 22 +++++++++++++++++++--- + 2 files changed, 20 insertions(+), 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -1017,6 +1017,7 @@ struct rt2x00_dev { + unsigned int extra_tx_headroom; + + struct usb_anchor *anchor; ++ unsigned int num_proto_errs; + + /* Clock for System On Chip devices. */ + struct clk *clk; +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00usb.c +@@ -31,6 +31,22 @@ + #include "rt2x00.h" + #include "rt2x00usb.h" + ++static bool rt2x00usb_check_usb_error(struct rt2x00_dev *rt2x00dev, int status) ++{ ++ if (status == -ENODEV || status == -ENOENT) ++ return true; ++ ++ if (status == -EPROTO || status == -ETIMEDOUT) ++ rt2x00dev->num_proto_errs++; ++ else ++ rt2x00dev->num_proto_errs = 0; ++ ++ if (rt2x00dev->num_proto_errs > 3) ++ return true; ++ ++ return false; ++} ++ + /* + * Interfacing with the HW. + */ +@@ -57,7 +73,7 @@ int rt2x00usb_vendor_request(struct rt2x + if (status >= 0) + return 0; + +- if (status == -ENODEV || status == -ENOENT) { ++ if (rt2x00usb_check_usb_error(rt2x00dev, status)) { + /* Device has disappeared. */ + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + break; +@@ -321,7 +337,7 @@ static bool rt2x00usb_kick_tx_entry(stru + + status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (status) { +- if (status == -ENODEV || status == -ENOENT) ++ if (rt2x00usb_check_usb_error(rt2x00dev, status)) + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + rt2x00lib_dmadone(entry); +@@ -410,7 +426,7 @@ static bool rt2x00usb_kick_rx_entry(stru + + status = usb_submit_urb(entry_priv->urb, GFP_ATOMIC); + if (status) { +- if (status == -ENODEV || status == -ENOENT) ++ if (rt2x00usb_check_usb_error(rt2x00dev, status)) + clear_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + set_bit(ENTRY_DATA_IO_FAILED, &entry->flags); + rt2x00lib_dmadone(entry); diff --git a/package/kernel/mac80211/patches/rt2x00/023-rt2x00-do-not-print-error-when-queue-is-full.patch b/package/kernel/mac80211/patches/rt2x00/023-rt2x00-do-not-print-error-when-queue-is-full.patch new file mode 100644 index 0000000000..7e2f2193be --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/023-rt2x00-do-not-print-error-when-queue-is-full.patch @@ -0,0 +1,43 @@ +From patchwork Tue Mar 12 09:51:43 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10848963 +X-Patchwork-Delegate: kvalo@adurom.com +From: Stanislaw Gruszka +To: linux-wireless@vger.kernel.org +Cc: =?utf-8?q?Tomislav_Po=C5=BEega?= , + Daniel Golle , Felix Fietkau , + Mathias Kresin +Subject: [PATCH v3 4/4] rt2x00: do not print error when queue is full +Date: Tue, 12 Mar 2019 10:51:43 +0100 +Message-Id: <1552384303-29529-5-git-send-email-sgruszka@redhat.com> +In-Reply-To: <1552384303-29529-1-git-send-email-sgruszka@redhat.com> +References: <1552384303-29529-1-git-send-email-sgruszka@redhat.com> + +For unknown reasons printk() on some context can cause CPU hung on +embedded MT7620 AP/router MIPS platforms. What can result on wifi +disconnects. + +This patch move queue full messages to debug level what is consistent +with other mac80211 drivers which drop packet silently if tx queue is +full. This make MT7620 OpenWRT routers more stable, what was reported +by various users. + +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +@@ -671,7 +671,7 @@ int rt2x00queue_write_tx_frame(struct da + spin_lock(&queue->tx_lock); + + if (unlikely(rt2x00queue_full(queue))) { +- rt2x00_err(queue->rt2x00dev, "Dropping frame due to full tx queue %d\n", ++ rt2x00_dbg(queue->rt2x00dev, "Dropping frame due to full tx queue %d\n", + queue->qid); + ret = -ENOBUFS; + goto out; diff --git a/package/kernel/mac80211/patches/rt2x00/024-rt2800-partially-restore-old-mmio-txstatus-behaviour.patch b/package/kernel/mac80211/patches/rt2x00/024-rt2800-partially-restore-old-mmio-txstatus-behaviour.patch new file mode 100644 index 0000000000..52314a79ae --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/024-rt2800-partially-restore-old-mmio-txstatus-behaviour.patch @@ -0,0 +1,128 @@ +From 91a5340db0526b7263bc8da14b120ea3129b5f28 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Sat, 9 Feb 2019 12:08:31 +0100 +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10804437 +X-Patchwork-Delegate: kvalo@adurom.com +Subject: [PATCH 21/28] rt2800: partially restore old mmio txstatus behaviour + +Do not disable txstatus interrupt and add quota of processed tx statuses in +one tasklet. Quota is needed to allow to fed device with new frames during +processing of tx statuses. + +Patch fixes about 15% performance degradation on some scenarios coused by +0b0d556e0ebb ("rt2800mmio: use txdone/txstatus routines from lib"). + +Signed-off-by: Stanislaw Gruszka +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 4 +-- + .../net/wireless/ralink/rt2x00/rt2800lib.h | 2 +- + .../net/wireless/ralink/rt2x00/rt2800mmio.c | 30 +++++-------------- + .../net/wireless/ralink/rt2x00/rt2800usb.c | 2 +- + 4 files changed, 12 insertions(+), 26 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1100,7 +1100,7 @@ void rt2800_txdone_entry(struct queue_en + } + EXPORT_SYMBOL_GPL(rt2800_txdone_entry); + +-void rt2800_txdone(struct rt2x00_dev *rt2x00dev) ++void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota) + { + struct data_queue *queue; + struct queue_entry *entry; +@@ -1108,7 +1108,7 @@ void rt2800_txdone(struct rt2x00_dev *rt + u8 qid; + bool match; + +- while (kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { ++ while (quota-- > 0 && kfifo_get(&rt2x00dev->txstatus_fifo, ®)) { + /* + * TX_STA_FIFO_PID_QUEUE is a 2-bit field, thus qid is + * guaranteed to be one of the TX QIDs . +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +@@ -195,7 +195,7 @@ void rt2800_process_rxwi(struct queue_en + + void rt2800_txdone_entry(struct queue_entry *entry, u32 status, __le32 *txwi, + bool match); +-void rt2800_txdone(struct rt2x00_dev *rt2x00dev); ++void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota); + void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev); + bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev); + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -255,20 +255,6 @@ void rt2800mmio_autowake_tasklet(unsigne + } + EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet); + +-static void rt2800mmio_txdone(struct rt2x00_dev *rt2x00dev) +-{ +- bool timeout = false; +- +- while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || +- (timeout = rt2800_txstatus_timeout(rt2x00dev))) { +- +- rt2800_txdone(rt2x00dev); +- +- if (timeout) +- rt2800_txdone_nostatus(rt2x00dev); +- } +-} +- + static bool rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev) + { + u32 status; +@@ -305,14 +291,11 @@ void rt2800mmio_txstatus_tasklet(unsigne + { + struct rt2x00_dev *rt2x00dev = (struct rt2x00_dev *)data; + +- do { +- rt2800mmio_txdone(rt2x00dev); ++ rt2800_txdone(rt2x00dev, 16); + +- } while (rt2800mmio_fetch_txstatus(rt2x00dev)); ++ if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) ++ tasklet_schedule(&rt2x00dev->txstatus_tasklet); + +- if (test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) +- rt2800mmio_enable_interrupt(rt2x00dev, +- INT_SOURCE_CSR_TX_FIFO_STATUS); + } + EXPORT_SYMBOL_GPL(rt2800mmio_txstatus_tasklet); + +@@ -339,8 +322,10 @@ irqreturn_t rt2800mmio_interrupt(int irq + mask = ~reg; + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_TX_FIFO_STATUS)) { ++ rt2x00_set_field32(&mask, INT_MASK_CSR_TX_FIFO_STATUS, 1); + rt2800mmio_fetch_txstatus(rt2x00dev); +- tasklet_schedule(&rt2x00dev->txstatus_tasklet); ++ if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) ++ tasklet_schedule(&rt2x00dev->txstatus_tasklet); + } + + if (rt2x00_get_field32(reg, INT_SOURCE_CSR_PRE_TBTT)) +@@ -500,7 +485,8 @@ void rt2800mmio_flush_queue(struct data_ + */ + if (tx_queue) { + tasklet_disable(&rt2x00dev->txstatus_tasklet); +- rt2800mmio_txdone(rt2x00dev); ++ rt2800_txdone(rt2x00dev, UINT_MAX); ++ rt2800_txdone_nostatus(rt2x00dev); + tasklet_enable(&rt2x00dev->txstatus_tasklet); + } + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +@@ -480,7 +480,7 @@ static void rt2800usb_work_txdone(struct + while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || + rt2800_txstatus_timeout(rt2x00dev)) { + +- rt2800_txdone(rt2x00dev); ++ rt2800_txdone(rt2x00dev, UINT_MAX); + + rt2800_txdone_nostatus(rt2x00dev); + diff --git a/package/kernel/mac80211/patches/rt2x00/025-rt2800-new-flush-implementation-for-SoC-devices.patch b/package/kernel/mac80211/patches/rt2x00/025-rt2800-new-flush-implementation-for-SoC-devices.patch new file mode 100644 index 0000000000..e3a914a0fa --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/025-rt2800-new-flush-implementation-for-SoC-devices.patch @@ -0,0 +1,27 @@ +From 11f8ad1656035176bad9d89de7ea0e7fe6d82c32 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Sat, 9 Feb 2019 12:08:32 +0100 +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10804439 +X-Patchwork-Delegate: kvalo@adurom.com +Subject: [PATCH 22/28] rt2800: new flush implementation for SoC devices + +Use new flush_queue() calback for SoC devices, what was already done for +PCIe devices. + +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2800soc.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -203,7 +203,7 @@ static const struct rt2x00lib_ops rt2800 + .start_queue = rt2800mmio_start_queue, + .kick_queue = rt2800mmio_kick_queue, + .stop_queue = rt2800mmio_stop_queue, +- .flush_queue = rt2x00mmio_flush_queue, ++ .flush_queue = rt2800mmio_flush_queue, + .write_tx_desc = rt2800mmio_write_tx_desc, + .write_tx_data = rt2800_write_tx_data, + .write_beacon = rt2800_write_beacon, diff --git a/package/kernel/mac80211/patches/rt2x00/026-rt2800-move-txstatus-pending-routine.patch b/package/kernel/mac80211/patches/rt2x00/026-rt2800-move-txstatus-pending-routine.patch new file mode 100644 index 0000000000..e5bfbecd1e --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/026-rt2800-move-txstatus-pending-routine.patch @@ -0,0 +1,106 @@ +From 2bbea7645c3d095014a080db170941818650e141 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Sat, 9 Feb 2019 12:08:33 +0100 +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10804441 +X-Patchwork-Delegate: kvalo@adurom.com +Subject: [PATCH 23/28] rt2800: move txstatus pending routine + +Move rt2800usb_txstatus_pending routine to rt2800lib. It will be reused +by rt2800mmio code. + +Signed-off-by: Stanislaw Gruszka +--- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 17 ++++++++++++++ + .../net/wireless/ralink/rt2x00/rt2800lib.h | 1 + + .../net/wireless/ralink/rt2x00/rt2800usb.c | 22 +++---------------- + 3 files changed, 21 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1183,6 +1183,23 @@ bool rt2800_txstatus_timeout(struct rt2x + } + EXPORT_SYMBOL_GPL(rt2800_txstatus_timeout); + ++/* ++ * test if there is an entry in any TX queue for which DMA is done ++ * but the TX status has not been returned yet ++ */ ++bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev) ++{ ++ struct data_queue *queue; ++ ++ tx_queue_for_each(rt2x00dev, queue) { ++ if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) != ++ rt2x00queue_get_entry(queue, Q_INDEX_DONE)) ++ return true; ++ } ++ return false; ++} ++EXPORT_SYMBOL_GPL(rt2800_txstatus_pending); ++ + void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev) + { + struct data_queue *queue; +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +@@ -198,6 +198,7 @@ void rt2800_txdone_entry(struct queue_en + void rt2800_txdone(struct rt2x00_dev *rt2x00dev, unsigned int quota); + void rt2800_txdone_nostatus(struct rt2x00_dev *rt2x00dev); + bool rt2800_txstatus_timeout(struct rt2x00_dev *rt2x00dev); ++bool rt2800_txstatus_pending(struct rt2x00_dev *rt2x00dev); + + void rt2800_write_beacon(struct queue_entry *entry, struct txentry_desc *txdesc); + void rt2800_clear_beacon(struct queue_entry *entry); +--- a/drivers/net/wireless/ralink/rt2x00/rt2800usb.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800usb.c +@@ -100,22 +100,6 @@ static void rt2800usb_stop_queue(struct + } + } + +-/* +- * test if there is an entry in any TX queue for which DMA is done +- * but the TX status has not been returned yet +- */ +-static bool rt2800usb_txstatus_pending(struct rt2x00_dev *rt2x00dev) +-{ +- struct data_queue *queue; +- +- tx_queue_for_each(rt2x00dev, queue) { +- if (rt2x00queue_get_entry(queue, Q_INDEX_DMA_DONE) != +- rt2x00queue_get_entry(queue, Q_INDEX_DONE)) +- return true; +- } +- return false; +-} +- + #define TXSTATUS_READ_INTERVAL 1000000 + + static bool rt2800usb_tx_sta_fifo_read_completed(struct rt2x00_dev *rt2x00dev, +@@ -145,7 +129,7 @@ static bool rt2800usb_tx_sta_fifo_read_c + if (rt2800_txstatus_timeout(rt2x00dev)) + queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + +- if (rt2800usb_txstatus_pending(rt2x00dev)) { ++ if (rt2800_txstatus_pending(rt2x00dev)) { + /* Read register after 1 ms */ + hrtimer_start(&rt2x00dev->txstatus_timer, + TXSTATUS_READ_INTERVAL, +@@ -160,7 +144,7 @@ stop_reading: + * clear_bit someone could do rt2x00usb_interrupt_txdone, so recheck + * here again if status reading is needed. + */ +- if (rt2800usb_txstatus_pending(rt2x00dev) && ++ if (rt2800_txstatus_pending(rt2x00dev) && + !test_and_set_bit(TX_STATUS_READING, &rt2x00dev->flags)) + return true; + else +@@ -489,7 +473,7 @@ static void rt2800usb_work_txdone(struct + * if the medium is busy, thus the TX_STA_FIFO entry is + * also delayed -> use a timer to retrieve it. + */ +- if (rt2800usb_txstatus_pending(rt2x00dev)) ++ if (rt2800_txstatus_pending(rt2x00dev)) + rt2800usb_async_read_tx_status(rt2x00dev); + } + } diff --git a/package/kernel/mac80211/patches/rt2x00/027-rt2800mmio-fetch-tx-status-changes.patch b/package/kernel/mac80211/patches/rt2x00/027-rt2800mmio-fetch-tx-status-changes.patch new file mode 100644 index 0000000000..4bb62c2288 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/027-rt2800mmio-fetch-tx-status-changes.patch @@ -0,0 +1,61 @@ +From f6a9618198e190a2ba09ce3f0aa8e9ee1763bd38 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Sat, 9 Feb 2019 12:08:34 +0100 +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10804443 +X-Patchwork-Delegate: kvalo@adurom.com +Subject: [PATCH 24/28] rt2800mmio: fetch tx status changes + +Prepare to use rt2800mmio_fetch_txstatus() in concurrent manner and drop +return value since is not longer needed. + +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2800mmio.c | 17 +++++++++-------- + 1 file changed, 9 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -255,12 +255,12 @@ void rt2800mmio_autowake_tasklet(unsigne + } + EXPORT_SYMBOL_GPL(rt2800mmio_autowake_tasklet); + +-static bool rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev) ++static void rt2800mmio_fetch_txstatus(struct rt2x00_dev *rt2x00dev) + { + u32 status; +- bool more = false; ++ unsigned long flags; + +- /* FIXEME: rewrite this comment ++ /* + * The TX_FIFO_STATUS interrupt needs special care. We should + * read TX_STA_FIFO but we should do it immediately as otherwise + * the register can overflow and we would lose status reports. +@@ -271,20 +271,21 @@ static bool rt2800mmio_fetch_txstatus(st + * because we can schedule the tasklet multiple times (when the + * interrupt fires again during tx status processing). + * +- * txstatus tasklet is called with INT_SOURCE_CSR_TX_FIFO_STATUS +- * disabled so have only one producer and one consumer - we don't +- * need to lock the kfifo. ++ * We also read statuses from tx status timeout timer, use ++ * lock to prevent concurent writes to fifo. + */ ++ ++ spin_lock_irqsave(&rt2x00dev->irqmask_lock, flags); ++ + while (!kfifo_is_full(&rt2x00dev->txstatus_fifo)) { + status = rt2x00mmio_register_read(rt2x00dev, TX_STA_FIFO); + if (!rt2x00_get_field32(status, TX_STA_FIFO_VALID)) + break; + + kfifo_put(&rt2x00dev->txstatus_fifo, status); +- more = true; + } + +- return more; ++ spin_unlock_irqrestore(&rt2x00dev->irqmask_lock, flags); + } + + void rt2800mmio_txstatus_tasklet(unsigned long data) diff --git a/package/kernel/mac80211/patches/rt2x00/028-rt2800mmio-use-timer-and-work-for-handling-tx-status.patch b/package/kernel/mac80211/patches/rt2x00/028-rt2800mmio-use-timer-and-work-for-handling-tx-status.patch new file mode 100644 index 0000000000..bf038a5991 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/028-rt2800mmio-use-timer-and-work-for-handling-tx-status.patch @@ -0,0 +1,194 @@ +From 175c2548332b45b144af673e70fdbb1a947d7aba Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Sat, 9 Feb 2019 12:08:35 +0100 +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10804445 +X-Patchwork-Delegate: kvalo@adurom.com +Subject: [PATCH 25/28] rt2800mmio: use timer and work for handling tx statuses + timeouts + +Sometimes we can get into situation when there are pending statuses, +but we do not get INT_SOURCE_CSR_TX_FIFO_STATUS. Handle this situation +by arming timeout timer and read statuses (it will fix case when +we just do not have irq) and queue work to handle case we missed +statues from hardware FIFO. + +Signed-off-by: Stanislaw Gruszka +--- + .../net/wireless/ralink/rt2x00/rt2800mmio.c | 81 +++++++++++++++++-- + .../net/wireless/ralink/rt2x00/rt2800mmio.h | 1 + + .../net/wireless/ralink/rt2x00/rt2800pci.c | 2 +- + .../net/wireless/ralink/rt2x00/rt2800soc.c | 2 +- + .../net/wireless/ralink/rt2x00/rt2x00dev.c | 4 + + 5 files changed, 82 insertions(+), 8 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.c +@@ -426,6 +426,9 @@ void rt2800mmio_start_queue(struct data_ + } + EXPORT_SYMBOL_GPL(rt2800mmio_start_queue); + ++/* 200 ms */ ++#define TXSTATUS_TIMEOUT 200000000 ++ + void rt2800mmio_kick_queue(struct data_queue *queue) + { + struct rt2x00_dev *rt2x00dev = queue->rt2x00dev; +@@ -440,6 +443,8 @@ void rt2800mmio_kick_queue(struct data_q + entry = rt2x00queue_get_entry(queue, Q_INDEX); + rt2x00mmio_register_write(rt2x00dev, TX_CTX_IDX(queue->qid), + entry->entry_idx); ++ hrtimer_start(&rt2x00dev->txstatus_timer, ++ TXSTATUS_TIMEOUT, HRTIMER_MODE_REL); + break; + case QID_MGMT: + entry = rt2x00queue_get_entry(queue, Q_INDEX); +@@ -484,12 +489,8 @@ void rt2800mmio_flush_queue(struct data_ + * For TX queues schedule completion tasklet to catch + * tx status timeouts, othewise just wait. + */ +- if (tx_queue) { +- tasklet_disable(&rt2x00dev->txstatus_tasklet); +- rt2800_txdone(rt2x00dev, UINT_MAX); +- rt2800_txdone_nostatus(rt2x00dev); +- tasklet_enable(&rt2x00dev->txstatus_tasklet); +- } ++ if (tx_queue) ++ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); + + /* + * Wait for a little while to give the driver +@@ -627,6 +628,10 @@ void rt2800mmio_clear_entry(struct queue + word = rt2x00_desc_read(entry_priv->desc, 1); + rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 1); + rt2x00_desc_write(entry_priv->desc, 1, word); ++ ++ /* If last entry stop txstatus timer */ ++ if (entry->queue->length == 1) ++ hrtimer_cancel(&rt2x00dev->txstatus_timer); + } + } + EXPORT_SYMBOL_GPL(rt2800mmio_clear_entry); +@@ -759,6 +764,70 @@ int rt2800mmio_enable_radio(struct rt2x0 + } + EXPORT_SYMBOL_GPL(rt2800mmio_enable_radio); + ++static void rt2800mmio_work_txdone(struct work_struct *work) ++{ ++ struct rt2x00_dev *rt2x00dev = ++ container_of(work, struct rt2x00_dev, txdone_work); ++ ++ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) ++ return; ++ ++ while (!kfifo_is_empty(&rt2x00dev->txstatus_fifo) || ++ rt2800_txstatus_timeout(rt2x00dev)) { ++ ++ tasklet_disable(&rt2x00dev->txstatus_tasklet); ++ rt2800_txdone(rt2x00dev, UINT_MAX); ++ rt2800_txdone_nostatus(rt2x00dev); ++ tasklet_enable(&rt2x00dev->txstatus_tasklet); ++ } ++ ++ if (rt2800_txstatus_pending(rt2x00dev)) ++ hrtimer_start(&rt2x00dev->txstatus_timer, ++ TXSTATUS_TIMEOUT, HRTIMER_MODE_REL); ++} ++ ++static enum hrtimer_restart rt2800mmio_tx_sta_fifo_timeout(struct hrtimer *timer) ++{ ++ struct rt2x00_dev *rt2x00dev = ++ container_of(timer, struct rt2x00_dev, txstatus_timer); ++ ++ if (!test_bit(DEVICE_STATE_ENABLED_RADIO, &rt2x00dev->flags)) ++ goto out; ++ ++ if (!rt2800_txstatus_pending(rt2x00dev)) ++ goto out; ++ ++ rt2800mmio_fetch_txstatus(rt2x00dev); ++ if (!kfifo_is_empty(&rt2x00dev->txstatus_fifo)) ++ tasklet_schedule(&rt2x00dev->txstatus_tasklet); ++ else ++ queue_work(rt2x00dev->workqueue, &rt2x00dev->txdone_work); ++out: ++ return HRTIMER_NORESTART; ++} ++ ++int rt2800mmio_probe_hw(struct rt2x00_dev *rt2x00dev) ++{ ++ int retval; ++ ++ retval = rt2800_probe_hw(rt2x00dev); ++ if (retval) ++ return retval; ++ ++ /* ++ * Set txstatus timer function. ++ */ ++ rt2x00dev->txstatus_timer.function = rt2800mmio_tx_sta_fifo_timeout; ++ ++ /* ++ * Overwrite TX done handler ++ */ ++ INIT_WORK(&rt2x00dev->txdone_work, rt2800mmio_work_txdone); ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(rt2800mmio_probe_hw); ++ + MODULE_AUTHOR(DRV_PROJECT); + MODULE_VERSION(DRV_VERSION); + MODULE_DESCRIPTION("rt2800 MMIO library"); +--- a/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800mmio.h +@@ -153,6 +153,7 @@ void rt2800mmio_stop_queue(struct data_q + void rt2800mmio_queue_init(struct data_queue *queue); + + /* Initialization functions */ ++int rt2800mmio_probe_hw(struct rt2x00_dev *rt2x00dev); + bool rt2800mmio_get_entry_state(struct queue_entry *entry); + void rt2800mmio_clear_entry(struct queue_entry *entry); + int rt2800mmio_init_queues(struct rt2x00_dev *rt2x00dev); +--- a/drivers/net/wireless/ralink/rt2x00/rt2800pci.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800pci.c +@@ -346,7 +346,7 @@ static const struct rt2x00lib_ops rt2800 + .tbtt_tasklet = rt2800mmio_tbtt_tasklet, + .rxdone_tasklet = rt2800mmio_rxdone_tasklet, + .autowake_tasklet = rt2800mmio_autowake_tasklet, +- .probe_hw = rt2800_probe_hw, ++ .probe_hw = rt2800mmio_probe_hw, + .get_firmware_name = rt2800pci_get_firmware_name, + .check_firmware = rt2800_check_firmware, + .load_firmware = rt2800_load_firmware, +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -185,7 +185,7 @@ static const struct rt2x00lib_ops rt2800 + .tbtt_tasklet = rt2800mmio_tbtt_tasklet, + .rxdone_tasklet = rt2800mmio_rxdone_tasklet, + .autowake_tasklet = rt2800mmio_autowake_tasklet, +- .probe_hw = rt2800_probe_hw, ++ .probe_hw = rt2800mmio_probe_hw, + .get_firmware_name = rt2800soc_get_firmware_name, + .check_firmware = rt2800soc_check_firmware, + .load_firmware = rt2800soc_load_firmware, +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +@@ -1391,6 +1391,8 @@ int rt2x00lib_probe_dev(struct rt2x00_de + mutex_init(&rt2x00dev->conf_mutex); + INIT_LIST_HEAD(&rt2x00dev->bar_list); + spin_lock_init(&rt2x00dev->bar_list_lock); ++ hrtimer_init(&rt2x00dev->txstatus_timer, CLOCK_MONOTONIC, ++ HRTIMER_MODE_REL); + + set_bit(DEVICE_STATE_PRESENT, &rt2x00dev->flags); + +@@ -1515,6 +1517,8 @@ void rt2x00lib_remove_dev(struct rt2x00_ + cancel_delayed_work_sync(&rt2x00dev->autowakeup_work); + cancel_work_sync(&rt2x00dev->sleep_work); + ++ hrtimer_cancel(&rt2x00dev->txstatus_timer); ++ + /* + * Kill the tx status tasklet. + */ diff --git a/package/kernel/mac80211/patches/rt2x00/029-rt2x00-remove-last_nostatus_check.patch b/package/kernel/mac80211/patches/rt2x00/029-rt2x00-remove-last_nostatus_check.patch new file mode 100644 index 0000000000..0daaef5e8b --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/029-rt2x00-remove-last_nostatus_check.patch @@ -0,0 +1,57 @@ +From 6013a91f15c9dabd668d5736652b9bcfb0ef0378 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Sat, 9 Feb 2019 12:08:36 +0100 +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10804447 +X-Patchwork-Delegate: kvalo@adurom.com +Subject: [PATCH 26/28] rt2x00: remove last_nostatus_check + +We do not any longer check txstatus timeout from tasklet, so do not need +this optimization. + +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2800lib.c | 9 --------- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 2 -- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 1 - + 3 files changed, 12 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -1164,15 +1164,6 @@ bool rt2800_txstatus_timeout(struct rt2x + struct data_queue *queue; + struct queue_entry *entry; + +- if (!test_bit(DEVICE_STATE_FLUSHING, &rt2x00dev->flags)) { +- unsigned long tout = msecs_to_jiffies(1000); +- +- if (time_before(jiffies, rt2x00dev->last_nostatus_check + tout)) +- return false; +- } +- +- rt2x00dev->last_nostatus_check = jiffies; +- + tx_queue_for_each(rt2x00dev, queue) { + entry = rt2x00queue_get_entry(queue, Q_INDEX_DONE); + if (rt2800_entry_txstatus_timeout(rt2x00dev, entry)) +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -981,8 +981,6 @@ struct rt2x00_dev { + */ + DECLARE_KFIFO_PTR(txstatus_fifo, u32); + +- unsigned long last_nostatus_check; +- + /* + * Timer to ensure tx status reports are read (rt2800usb). + */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +@@ -1039,7 +1039,6 @@ void rt2x00queue_start_queues(struct rt2 + */ + tx_queue_for_each(rt2x00dev, queue) + rt2x00queue_start_queue(queue); +- rt2x00dev->last_nostatus_check = jiffies; + + rt2x00queue_start_queue(rt2x00dev->rx); + } diff --git a/package/kernel/mac80211/patches/rt2x00/030-rt2x00-remove-not-used-entry-field.patch b/package/kernel/mac80211/patches/rt2x00/030-rt2x00-remove-not-used-entry-field.patch new file mode 100644 index 0000000000..53134a5bc3 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/030-rt2x00-remove-not-used-entry-field.patch @@ -0,0 +1,34 @@ +From 2758f09b22bc08e89e0391486b2d707ad2479599 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Sat, 9 Feb 2019 12:08:37 +0100 +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10804449 +X-Patchwork-Delegate: kvalo@adurom.com +Subject: [PATCH 27/28] rt2x00: remove not used entry field + +Remove not used any longer queue_entry field and flag. + +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.h | 3 --- + 1 file changed, 3 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.h +@@ -361,7 +361,6 @@ enum queue_entry_flags { + ENTRY_DATA_PENDING, + ENTRY_DATA_IO_FAILED, + ENTRY_DATA_STATUS_PENDING, +- ENTRY_DATA_STATUS_SET, + }; + + /** +@@ -387,8 +386,6 @@ struct queue_entry { + + unsigned int entry_idx; + +- u32 status; +- + void *priv_data; + }; + diff --git a/package/kernel/mac80211/patches/rt2x00/031-rt2x00mmio-remove-legacy-comment.patch b/package/kernel/mac80211/patches/rt2x00/031-rt2x00mmio-remove-legacy-comment.patch new file mode 100644 index 0000000000..199a6e3255 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/031-rt2x00mmio-remove-legacy-comment.patch @@ -0,0 +1,26 @@ +From f44e145869bb517460648e4ed71b7e9001964d06 Mon Sep 17 00:00:00 2001 +From: Stanislaw Gruszka +Date: Sat, 9 Feb 2019 12:08:38 +0100 +X-Patchwork-Submitter: Stanislaw Gruszka +X-Patchwork-Id: 10804451 +X-Patchwork-Delegate: kvalo@adurom.com +Subject: [PATCH 28/28] rt2x00mmio: remove legacy comment + +Remove comment about fields that ware removed. + +Signed-off-by: Stanislaw Gruszka +--- + drivers/net/wireless/ralink/rt2x00/rt2x00mmio.h | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mmio.h +@@ -80,8 +80,6 @@ int rt2x00mmio_regbusy_read(struct rt2x0 + * + * @desc: Pointer to device descriptor + * @desc_dma: DMA pointer to &desc. +- * @data: Pointer to device's entry memory. +- * @data_dma: DMA pointer to &data. + */ + struct queue_entry_priv_mmio { + __le32 *desc; diff --git a/package/kernel/mac80211/patches/rt2x00/032-rt2x00-do-not-increment-sequence-number-while-re-tra.patch b/package/kernel/mac80211/patches/rt2x00/032-rt2x00-do-not-increment-sequence-number-while-re-tra.patch new file mode 100644 index 0000000000..c1f3815998 --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/032-rt2x00-do-not-increment-sequence-number-while-re-tra.patch @@ -0,0 +1,94 @@ +From 746ba11f170603bf1eaade817553a6c2e9135bbe Mon Sep 17 00:00:00 2001 +From: Vijayakumar Durai +Date: Wed, 27 Mar 2019 11:03:17 +0100 +Subject: [PATCH] rt2x00: do not increment sequence number while + re-transmitting + +Currently rt2x00 devices retransmit the management frames with +incremented sequence number if hardware is assigning the sequence. + +This is HW bug fixed already for non-QOS data frames, but it should +be fixed for management frames except beacon. + +Without fix retransmitted frames have wrong SN: + + AlphaNet_e8:fb:36 Vivotek_52:31:51 Authentication, SN=1648, FN=0, Flags=........C Frame is not being retransmitted 1648 1 + AlphaNet_e8:fb:36 Vivotek_52:31:51 Authentication, SN=1649, FN=0, Flags=....R...C Frame is being retransmitted 1649 1 + AlphaNet_e8:fb:36 Vivotek_52:31:51 Authentication, SN=1650, FN=0, Flags=....R...C Frame is being retransmitted 1650 1 + +With the fix SN stays correctly the same: + + 88:6a:e3:e8:f9:a2 8c:f5:a3:88:76:87 Authentication, SN=1450, FN=0, Flags=........C + 88:6a:e3:e8:f9:a2 8c:f5:a3:88:76:87 Authentication, SN=1450, FN=0, Flags=....R...C + 88:6a:e3:e8:f9:a2 8c:f5:a3:88:76:87 Authentication, SN=1450, FN=0, Flags=....R...C + +Cc: stable@vger.kernel.org +Signed-off-by: Vijayakumar Durai +[sgruszka: simplify code, change comments and changelog] +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2x00.h | 1 - + drivers/net/wireless/ralink/rt2x00/rt2x00mac.c | 10 ---------- + drivers/net/wireless/ralink/rt2x00/rt2x00queue.c | 15 +++++++++------ + 3 files changed, 9 insertions(+), 17 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h +@@ -673,7 +673,6 @@ enum rt2x00_state_flags { + CONFIG_CHANNEL_HT40, + CONFIG_POWERSAVING, + CONFIG_HT_DISABLED, +- CONFIG_QOS_DISABLED, + CONFIG_MONITORING, + + /* +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00mac.c +@@ -642,19 +642,9 @@ void rt2x00mac_bss_info_changed(struct i + rt2x00dev->intf_associated--; + + rt2x00leds_led_assoc(rt2x00dev, !!rt2x00dev->intf_associated); +- +- clear_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags); + } + + /* +- * Check for access point which do not support 802.11e . We have to +- * generate data frames sequence number in S/W for such AP, because +- * of H/W bug. +- */ +- if (changes & BSS_CHANGED_QOS && !bss_conf->qos) +- set_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags); +- +- /* + * When the erp information has changed, we should perform + * additional configuration steps. For all other changes we are done. + */ +--- a/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2x00queue.c +@@ -201,15 +201,18 @@ static void rt2x00queue_create_tx_descri + if (!rt2x00_has_cap_flag(rt2x00dev, REQUIRE_SW_SEQNO)) { + /* + * rt2800 has a H/W (or F/W) bug, device incorrectly increase +- * seqno on retransmited data (non-QOS) frames. To workaround +- * the problem let's generate seqno in software if QOS is +- * disabled. ++ * seqno on retransmitted data (non-QOS) and management frames. ++ * To workaround the problem let's generate seqno in software. ++ * Except for beacons which are transmitted periodically by H/W ++ * hence hardware has to assign seqno for them. + */ +- if (test_bit(CONFIG_QOS_DISABLED, &rt2x00dev->flags)) +- __clear_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); +- else ++ if (ieee80211_is_beacon(hdr->frame_control)) { ++ __set_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); + /* H/W will generate sequence number */ + return; ++ } ++ ++ __clear_bit(ENTRY_TXD_GENERATE_SEQ, &txdesc->flags); + } + + /* diff --git a/package/kernel/mac80211/patches/rt2x00/050-rt2x00-add-RT3883-support.patch b/package/kernel/mac80211/patches/rt2x00/050-rt2x00-add-RT3883-support.patch new file mode 100644 index 0000000000..162a20155d --- /dev/null +++ b/package/kernel/mac80211/patches/rt2x00/050-rt2x00-add-RT3883-support.patch @@ -0,0 +1,959 @@ +From d0e61a0f7cca51ce340a5a73595189972122ff25 Mon Sep 17 00:00:00 2001 +From: Gabor Juhos +Date: Wed, 24 Apr 2019 09:49:24 +0200 +Subject: [PATCH] rt2x00: add RT3883 support + +Patch add support for RT3883 chip. Code was taken direclty +from openwrt project and merge into one patch. + +Signed-off-by: Gabor Juhos +Signed-off-by: Stanislaw Gruszka +Signed-off-by: Kalle Valo +--- + drivers/net/wireless/ralink/rt2x00/rt2800.h | 19 +- + .../net/wireless/ralink/rt2x00/rt2800lib.c | 598 +++++++++++++++++- + .../net/wireless/ralink/rt2x00/rt2800soc.c | 9 +- + 3 files changed, 607 insertions(+), 19 deletions(-) + +--- a/drivers/net/wireless/ralink/rt2x00/rt2800.h ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h +@@ -48,7 +48,8 @@ + * RF2853 2.4G/5G 3T3R + * RF3320 2.4G 1T1R(RT3350/RT3370/RT3390) + * RF3322 2.4G 2T2R(RT3352/RT3371/RT3372/RT3391/RT3392) +- * RF3053 2.4G/5G 3T3R(RT3883/RT3563/RT3573/RT3593/RT3662) ++ * RF3053 2.4G/5G 3T3R(RT3563/RT3573/RT3593) ++ * RF3853 2.4G/5G 3T3R(RT3883/RT3662) + * RF5592 2.4G/5G 2T2R + * RF3070 2.4G 1T1R + * RF5360 2.4G 1T1R +@@ -72,6 +73,7 @@ + #define RF5592 0x000f + #define RF3070 0x3070 + #define RF3290 0x3290 ++#define RF3853 0x3853 + #define RF5350 0x5350 + #define RF5360 0x5360 + #define RF5362 0x5362 +@@ -1726,6 +1728,20 @@ + #define TX_PWR_CFG_9B_STBC_MCS7 FIELD32(0x000000ff) + + /* ++ * TX_TXBF_CFG: ++ */ ++#define TX_TXBF_CFG_0 0x138c ++#define TX_TXBF_CFG_1 0x13a4 ++#define TX_TXBF_CFG_2 0x13a8 ++#define TX_TXBF_CFG_3 0x13ac ++ ++/* ++ * TX_FBK_CFG_3S: ++ */ ++#define TX_FBK_CFG_3S_0 0x13c4 ++#define TX_FBK_CFG_3S_1 0x13c8 ++ ++/* + * RX_FILTER_CFG: RX configuration register. + */ + #define RX_FILTER_CFG 0x1400 +@@ -2296,6 +2312,7 @@ struct mac_iveiv_entry { + /* + * RFCSR 2: + */ ++#define RFCSR2_RESCAL_BP FIELD8(0x40) + #define RFCSR2_RESCAL_EN FIELD8(0x80) + #define RFCSR2_RX2_EN_MT7620 FIELD8(0x02) + #define RFCSR2_TX2_EN_MT7620 FIELD8(0x20) +--- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +@@ -381,7 +381,8 @@ static unsigned int rt2800_eeprom_word_i + wiphy_name(rt2x00dev->hw->wiphy), word)) + return 0; + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + map = rt2800_eeprom_map_ext; + else + map = rt2800_eeprom_map; +@@ -590,6 +591,7 @@ void rt2800_get_txwi_rxwi_size(struct rt + { + switch (rt2x00dev->chip.rt) { + case RT3593: ++ case RT3883: + *txwi_size = TXWI_DESC_SIZE_4WORDS; + *rxwi_size = RXWI_DESC_SIZE_5WORDS; + break; +@@ -2180,7 +2182,8 @@ void rt2800_config_ant(struct rt2x00_dev + rt2800_bbp_write(rt2x00dev, 3, r3); + rt2800_bbp_write(rt2x00dev, 1, r1); + +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + if (ant->rx_chain_num == 1) + rt2800_bbp_write(rt2x00dev, 86, 0x00); + else +@@ -2202,7 +2205,8 @@ static void rt2800_config_lna_gain(struc + eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_LNA); + lna_gain = rt2x00_get_field16(eeprom, EEPROM_LNA_A0); + } else if (libconf->rf.channel <= 128) { +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2); + lna_gain = rt2x00_get_field16(eeprom, + EEPROM_EXT_LNA2_A1); +@@ -2212,7 +2216,8 @@ static void rt2800_config_lna_gain(struc + EEPROM_RSSI_BG2_LNA_A1); + } + } else { +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2); + lna_gain = rt2x00_get_field16(eeprom, + EEPROM_EXT_LNA2_A2); +@@ -2880,6 +2885,211 @@ static void rt2800_config_channel_rf3053 + } + } + ++static void rt2800_config_channel_rf3853(struct rt2x00_dev *rt2x00dev, ++ struct ieee80211_conf *conf, ++ struct rf_channel *rf, ++ struct channel_info *info) ++{ ++ u8 rfcsr; ++ u8 bbp; ++ u8 pwr1, pwr2, pwr3; ++ ++ const bool txbf_enabled = false; /* TODO */ ++ ++ /* TODO: add band selection */ ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); ++ else if (rf->channel < 132) ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x80); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); ++ ++ rt2800_rfcsr_write(rt2x00dev, 8, rf->rf1); ++ rt2800_rfcsr_write(rt2x00dev, 9, rf->rf3); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x46); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x52); ++ ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR1_PLL_PD, 1); ++ ++ switch (rt2x00dev->default_ant.tx_chain_num) { ++ case 3: ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX2_PD, 1); ++ /* fallthrough */ ++ case 2: ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX1_PD, 1); ++ /* fallthrough */ ++ case 1: ++ rt2x00_set_field8(&rfcsr, RFCSR1_TX0_PD, 1); ++ break; ++ } ++ ++ switch (rt2x00dev->default_ant.rx_chain_num) { ++ case 3: ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX2_PD, 1); ++ /* fallthrough */ ++ case 2: ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX1_PD, 1); ++ /* fallthrough */ ++ case 1: ++ rt2x00_set_field8(&rfcsr, RFCSR1_RX0_PD, 1); ++ break; ++ } ++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); ++ ++ rt2800_freq_cal_mode1(rt2x00dev); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 30); ++ if (!conf_is_ht40(conf)) ++ rfcsr &= ~(0x06); ++ else ++ rfcsr |= 0x06; ++ rt2800_rfcsr_write(rt2x00dev, 30, rfcsr); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 31, 0xa0); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); ++ ++ if (conf_is_ht40(conf)) ++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x3c); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x20); ++ ++ /* loopback RF_BS */ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 36); ++ if (rf->channel <= 14) ++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 1); ++ else ++ rt2x00_set_field8(&rfcsr, RFCSR36_RF_BS, 0); ++ rt2800_rfcsr_write(rt2x00dev, 36, rfcsr); ++ ++ if (rf->channel <= 14) ++ rfcsr = 0x23; ++ else if (rf->channel < 100) ++ rfcsr = 0x36; ++ else if (rf->channel < 132) ++ rfcsr = 0x32; ++ else ++ rfcsr = 0x30; ++ ++ if (txbf_enabled) ++ rfcsr |= 0x40; ++ ++ rt2800_rfcsr_write(rt2x00dev, 39, rfcsr); ++ ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x9b); ++ ++ if (rf->channel <= 14) ++ rfcsr = 0xbb; ++ else if (rf->channel < 100) ++ rfcsr = 0xeb; ++ else if (rf->channel < 132) ++ rfcsr = 0xb3; ++ else ++ rfcsr = 0x9b; ++ rt2800_rfcsr_write(rt2x00dev, 45, rfcsr); ++ ++ if (rf->channel <= 14) ++ rfcsr = 0x8e; ++ else ++ rfcsr = 0x8a; ++ ++ if (txbf_enabled) ++ rfcsr |= 0x20; ++ ++ rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); ++ ++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 51); ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x75); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 52); ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x45); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); ++ ++ if (rf->channel <= 14) { ++ pwr1 = info->default_power1 & 0x1f; ++ pwr2 = info->default_power2 & 0x1f; ++ pwr3 = info->default_power3 & 0x1f; ++ } else { ++ pwr1 = 0x48 | ((info->default_power1 & 0x18) << 1) | ++ (info->default_power1 & 0x7); ++ pwr2 = 0x48 | ((info->default_power2 & 0x18) << 1) | ++ (info->default_power2 & 0x7); ++ pwr3 = 0x48 | ((info->default_power3 & 0x18) << 1) | ++ (info->default_power3 & 0x7); ++ } ++ ++ rt2800_rfcsr_write(rt2x00dev, 53, pwr1); ++ rt2800_rfcsr_write(rt2x00dev, 54, pwr2); ++ rt2800_rfcsr_write(rt2x00dev, 55, pwr3); ++ ++ rt2x00_dbg(rt2x00dev, "Channel:%d, pwr1:%02x, pwr2:%02x, pwr3:%02x\n", ++ rf->channel, pwr1, pwr2, pwr3); ++ ++ bbp = (info->default_power1 >> 5) | ++ ((info->default_power2 & 0xe0) >> 1); ++ rt2800_bbp_write(rt2x00dev, 109, bbp); ++ ++ bbp = rt2800_bbp_read(rt2x00dev, 110); ++ bbp &= 0x0f; ++ bbp |= (info->default_power3 & 0xe0) >> 1; ++ rt2800_bbp_write(rt2x00dev, 110, bbp); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 57); ++ if (rf->channel <= 14) ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x6e); ++ else ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); ++ ++ /* Enable RF tuning */ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 3); ++ rt2x00_set_field8(&rfcsr, RFCSR3_VCOCAL_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 3, rfcsr); ++ ++ udelay(2000); ++ ++ bbp = rt2800_bbp_read(rt2x00dev, 49); ++ /* clear update flag */ ++ rt2800_bbp_write(rt2x00dev, 49, bbp & 0xfe); ++ rt2800_bbp_write(rt2x00dev, 49, bbp); ++ ++ /* TODO: add calibration for TxBF */ ++} ++ + #define POWER_BOUND 0x27 + #define POWER_BOUND_5G 0x2b + +@@ -3683,19 +3893,51 @@ static char rt2800_txpower_to_dev(struct + unsigned int channel, + char txpower) + { +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + txpower = rt2x00_get_field8(txpower, EEPROM_TXPOWER_ALC); + + if (channel <= 14) + return clamp_t(char, txpower, MIN_G_TXPOWER, MAX_G_TXPOWER); + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + return clamp_t(char, txpower, MIN_A_TXPOWER_3593, + MAX_A_TXPOWER_3593); + else + return clamp_t(char, txpower, MIN_A_TXPOWER, MAX_A_TXPOWER); + } + ++static void rt3883_bbp_adjust(struct rt2x00_dev *rt2x00dev, ++ struct rf_channel *rf) ++{ ++ u8 bbp; ++ ++ bbp = (rf->channel > 14) ? 0x48 : 0x38; ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, bbp); ++ ++ rt2800_bbp_write(rt2x00dev, 69, 0x12); ++ ++ if (rf->channel <= 14) { ++ rt2800_bbp_write(rt2x00dev, 70, 0x0a); ++ } else { ++ /* Disable CCK packet detection */ ++ rt2800_bbp_write(rt2x00dev, 70, 0x00); ++ } ++ ++ rt2800_bbp_write(rt2x00dev, 73, 0x10); ++ ++ if (rf->channel > 14) { ++ rt2800_bbp_write(rt2x00dev, 62, 0x1d); ++ rt2800_bbp_write(rt2x00dev, 63, 0x1d); ++ rt2800_bbp_write(rt2x00dev, 64, 0x1d); ++ } else { ++ rt2800_bbp_write(rt2x00dev, 62, 0x2d); ++ rt2800_bbp_write(rt2x00dev, 63, 0x2d); ++ rt2800_bbp_write(rt2x00dev, 64, 0x2d); ++ } ++} ++ + static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev, + struct ieee80211_conf *conf, + struct rf_channel *rf, +@@ -3714,6 +3956,12 @@ static void rt2800_config_channel(struct + rt2800_txpower_to_dev(rt2x00dev, rf->channel, + info->default_power3); + ++ switch (rt2x00dev->chip.rt) { ++ case RT3883: ++ rt3883_bbp_adjust(rt2x00dev, rf); ++ break; ++ } ++ + switch (rt2x00dev->chip.rf) { + case RF2020: + case RF3020: +@@ -3734,6 +3982,9 @@ static void rt2800_config_channel(struct + case RF3322: + rt2800_config_channel_rf3322(rt2x00dev, conf, rf, info); + break; ++ case RF3853: ++ rt2800_config_channel_rf3853(rt2x00dev, conf, rf, info); ++ break; + case RF3070: + case RF5350: + case RF5360: +@@ -3815,6 +4066,15 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 77, 0x98); ++ } else if (rt2x00_rt(rt2x00dev, RT3883)) { ++ rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); ++ rt2800_bbp_write(rt2x00dev, 64, 0x37 - rt2x00dev->lna_gain); ++ ++ if (rt2x00dev->default_ant.rx_chain_num > 1) ++ rt2800_bbp_write(rt2x00dev, 86, 0x46); ++ else ++ rt2800_bbp_write(rt2x00dev, 86, 0); + } else { + rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); + rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); +@@ -3828,6 +4088,7 @@ static void rt2800_config_channel(struct + !rt2x00_rt(rt2x00dev, RT6352)) { + if (rt2x00_has_cap_external_lna_bg(rt2x00dev)) { + rt2800_bbp_write(rt2x00dev, 82, 0x62); ++ rt2800_bbp_write(rt2x00dev, 82, 0x62); + rt2800_bbp_write(rt2x00dev, 75, 0x46); + } else { + if (rt2x00_rt(rt2x00dev, RT3593)) +@@ -3836,19 +4097,22 @@ static void rt2800_config_channel(struct + rt2800_bbp_write(rt2x00dev, 82, 0x84); + rt2800_bbp_write(rt2x00dev, 75, 0x50); + } +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 83, 0x8a); + } + + } else { + if (rt2x00_rt(rt2x00dev, RT3572)) + rt2800_bbp_write(rt2x00dev, 82, 0x94); +- else if (rt2x00_rt(rt2x00dev, RT3593)) ++ else if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 82, 0x82); + else if (!rt2x00_rt(rt2x00dev, RT6352)) + rt2800_bbp_write(rt2x00dev, 82, 0xf2); + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_bbp_write(rt2x00dev, 83, 0x9a); + + if (rt2x00_has_cap_external_lna_a(rt2x00dev)) +@@ -3984,6 +4248,23 @@ static void rt2800_config_channel(struct + usleep_range(1000, 1500); + } + ++ if (rt2x00_rt(rt2x00dev, RT3883)) { ++ if (!conf_is_ht40(conf)) ++ rt2800_bbp_write(rt2x00dev, 105, 0x34); ++ else ++ rt2800_bbp_write(rt2x00dev, 105, 0x04); ++ ++ /* AGC init */ ++ if (rf->channel <= 14) ++ reg = 0x2e + rt2x00dev->lna_gain; ++ else ++ reg = 0x20 + ((rt2x00dev->lna_gain * 5) / 3); ++ ++ rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, reg); ++ ++ usleep_range(1000, 1500); ++ } ++ + if (rt2x00_rt(rt2x00dev, RT5592) || rt2x00_rt(rt2x00dev, RT6352)) { + reg = 0x10; + if (!conf_is_ht40(conf)) { +@@ -4243,6 +4524,9 @@ static u8 rt2800_compensate_txpower(stru + if (rt2x00_rt(rt2x00dev, RT3593)) + return min_t(u8, txpower, 0xc); + ++ if (rt2x00_rt(rt2x00dev, RT3883)) ++ return min_t(u8, txpower, 0xf); ++ + if (rt2x00_has_cap_power_limit(rt2x00dev)) { + /* + * Check if eirp txpower exceed txpower_limit. +@@ -5004,7 +5288,8 @@ static void rt2800_config_txpower(struct + struct ieee80211_channel *chan, + int power_level) + { +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + rt2800_config_txpower_rt3593(rt2x00dev, chan, power_level); + else if (rt2x00_rt(rt2x00dev, RT6352)) + rt2800_config_txpower_rt6352(rt2x00dev, chan, power_level); +@@ -5051,6 +5336,7 @@ void rt2800_vco_calibration(struct rt2x0 + case RF3053: + case RF3070: + case RF3290: ++ case RF3853: + case RF5350: + case RF5360: + case RF5362: +@@ -5251,7 +5537,8 @@ static u8 rt2800_get_default_vgc(struct + else + vgc = 0x2e + rt2x00dev->lna_gain; + } else { /* 5GHZ band */ +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + vgc = 0x20 + (rt2x00dev->lna_gain * 5) / 3; + else if (rt2x00_rt(rt2x00dev, RT5592)) + vgc = 0x24 + (2 * rt2x00dev->lna_gain); +@@ -5271,7 +5558,8 @@ static inline void rt2800_set_vgc(struct + { + if (qual->vgc_level != vgc_level) { + if (rt2x00_rt(rt2x00dev, RT3572) || +- rt2x00_rt(rt2x00dev, RT3593)) { ++ rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + rt2800_bbp_write_with_rx_chain(rt2x00dev, 66, + vgc_level); + } else if (rt2x00_rt(rt2x00dev, RT5592)) { +@@ -5318,6 +5606,11 @@ void rt2800_link_tuner(struct rt2x00_dev + } + break; + ++ case RT3883: ++ if (qual->rssi > -65) ++ vgc += 0x10; ++ break; ++ + case RT5592: + if (qual->rssi > -65) + vgc += 0x20; +@@ -5470,6 +5763,12 @@ static int rt2800_init_registers(struct + rt2800_register_write(rt2x00dev, TX_SW_CFG2, + 0x00000000); + } ++ } else if (rt2x00_rt(rt2x00dev, RT3883)) { ++ rt2800_register_write(rt2x00dev, TX_SW_CFG0, 0x00000402); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG1, 0x00000000); ++ rt2800_register_write(rt2x00dev, TX_SW_CFG2, 0x00040000); ++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_0, 0x8000fc21); ++ rt2800_register_write(rt2x00dev, TX_TXBF_CFG_3, 0x00009c40); + } else if (rt2x00_rt(rt2x00dev, RT5390) || + rt2x00_rt(rt2x00dev, RT5392) || + rt2x00_rt(rt2x00dev, RT6352)) { +@@ -5683,6 +5982,11 @@ static int rt2800_init_registers(struct + reg = rt2x00_rt(rt2x00dev, RT5592) ? 0x00000082 : 0x00000002; + rt2800_register_write(rt2x00dev, TXOP_HLDR_ET, reg); + ++ if (rt2x00_rt(rt2x00dev, RT3883)) { ++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_0, 0x12111008); ++ rt2800_register_write(rt2x00dev, TX_FBK_CFG_3S_1, 0x16151413); ++ } ++ + reg = rt2800_register_read(rt2x00dev, TX_RTS_CFG); + rt2x00_set_field32(®, TX_RTS_CFG_AUTO_RTS_RETRY_LIMIT, 7); + rt2x00_set_field32(®, TX_RTS_CFG_RTS_THRES, +@@ -6299,6 +6603,47 @@ static void rt2800_init_bbp_3593(struct + rt2800_bbp_write(rt2x00dev, 103, 0xc0); + } + ++static void rt2800_init_bbp_3883(struct rt2x00_dev *rt2x00dev) ++{ ++ rt2800_init_bbp_early(rt2x00dev); ++ ++ rt2800_bbp_write(rt2x00dev, 4, 0x50); ++ rt2800_bbp_write(rt2x00dev, 47, 0x48); ++ ++ rt2800_bbp_write(rt2x00dev, 86, 0x46); ++ rt2800_bbp_write(rt2x00dev, 88, 0x90); ++ ++ rt2800_bbp_write(rt2x00dev, 92, 0x02); ++ ++ rt2800_bbp_write(rt2x00dev, 103, 0xc0); ++ rt2800_bbp_write(rt2x00dev, 104, 0x92); ++ rt2800_bbp_write(rt2x00dev, 105, 0x34); ++ rt2800_bbp_write(rt2x00dev, 106, 0x12); ++ rt2800_bbp_write(rt2x00dev, 120, 0x50); ++ rt2800_bbp_write(rt2x00dev, 137, 0x0f); ++ rt2800_bbp_write(rt2x00dev, 163, 0x9d); ++ ++ /* Set ITxBF timeout to 0x9C40=1000msec */ ++ rt2800_bbp_write(rt2x00dev, 179, 0x02); ++ rt2800_bbp_write(rt2x00dev, 180, 0x00); ++ rt2800_bbp_write(rt2x00dev, 182, 0x40); ++ rt2800_bbp_write(rt2x00dev, 180, 0x01); ++ rt2800_bbp_write(rt2x00dev, 182, 0x9c); ++ ++ rt2800_bbp_write(rt2x00dev, 179, 0x00); ++ ++ /* Reprogram the inband interface to put right values in RXWI */ ++ rt2800_bbp_write(rt2x00dev, 142, 0x04); ++ rt2800_bbp_write(rt2x00dev, 143, 0x3b); ++ rt2800_bbp_write(rt2x00dev, 142, 0x06); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa0); ++ rt2800_bbp_write(rt2x00dev, 142, 0x07); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa1); ++ rt2800_bbp_write(rt2x00dev, 142, 0x08); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa2); ++ rt2800_bbp_write(rt2x00dev, 148, 0xc8); ++} ++ + static void rt2800_init_bbp_53xx(struct rt2x00_dev *rt2x00dev) + { + int ant, div_mode; +@@ -6743,6 +7088,9 @@ static void rt2800_init_bbp(struct rt2x0 + case RT3593: + rt2800_init_bbp_3593(rt2x00dev); + return; ++ case RT3883: ++ rt2800_init_bbp_3883(rt2x00dev); ++ return; + case RT5390: + case RT5392: + rt2800_init_bbp_53xx(rt2x00dev); +@@ -7614,6 +7962,144 @@ static void rt2800_init_rfcsr_5350(struc + rt2800_rfcsr_write(rt2x00dev, 63, 0x00); + } + ++static void rt2800_init_rfcsr_3883(struct rt2x00_dev *rt2x00dev) ++{ ++ u8 rfcsr; ++ ++ /* TODO: get the actual ECO value from the SoC */ ++ const unsigned int eco = 5; ++ ++ rt2800_rf_init_calibration(rt2x00dev, 2); ++ ++ rt2800_rfcsr_write(rt2x00dev, 0, 0xe0); ++ rt2800_rfcsr_write(rt2x00dev, 1, 0x03); ++ rt2800_rfcsr_write(rt2x00dev, 2, 0x50); ++ rt2800_rfcsr_write(rt2x00dev, 3, 0x20); ++ rt2800_rfcsr_write(rt2x00dev, 4, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 5, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 6, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 7, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 8, 0x5b); ++ rt2800_rfcsr_write(rt2x00dev, 9, 0x08); ++ rt2800_rfcsr_write(rt2x00dev, 10, 0xd3); ++ rt2800_rfcsr_write(rt2x00dev, 11, 0x48); ++ rt2800_rfcsr_write(rt2x00dev, 12, 0x1a); ++ rt2800_rfcsr_write(rt2x00dev, 13, 0x12); ++ rt2800_rfcsr_write(rt2x00dev, 14, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 15, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 16, 0x00); ++ ++ /* RFCSR 17 will be initialized later based on the ++ * frequency offset stored in the EEPROM ++ */ ++ ++ rt2800_rfcsr_write(rt2x00dev, 18, 0x40); ++ rt2800_rfcsr_write(rt2x00dev, 19, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 20, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 21, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 22, 0x20); ++ rt2800_rfcsr_write(rt2x00dev, 23, 0xc0); ++ rt2800_rfcsr_write(rt2x00dev, 24, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 25, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 26, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 27, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 28, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 29, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 30, 0x10); ++ rt2800_rfcsr_write(rt2x00dev, 31, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 32, 0x80); ++ rt2800_rfcsr_write(rt2x00dev, 33, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 34, 0x20); ++ rt2800_rfcsr_write(rt2x00dev, 35, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 36, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 37, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 38, 0x86); ++ rt2800_rfcsr_write(rt2x00dev, 39, 0x23); ++ rt2800_rfcsr_write(rt2x00dev, 40, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 41, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 42, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 43, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 44, 0x93); ++ rt2800_rfcsr_write(rt2x00dev, 45, 0xbb); ++ rt2800_rfcsr_write(rt2x00dev, 46, 0x60); ++ rt2800_rfcsr_write(rt2x00dev, 47, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 48, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 49, 0x8e); ++ rt2800_rfcsr_write(rt2x00dev, 50, 0x86); ++ rt2800_rfcsr_write(rt2x00dev, 51, 0x51); ++ rt2800_rfcsr_write(rt2x00dev, 52, 0x05); ++ rt2800_rfcsr_write(rt2x00dev, 53, 0x76); ++ rt2800_rfcsr_write(rt2x00dev, 54, 0x76); ++ rt2800_rfcsr_write(rt2x00dev, 55, 0x76); ++ rt2800_rfcsr_write(rt2x00dev, 56, 0xdb); ++ rt2800_rfcsr_write(rt2x00dev, 57, 0x3e); ++ rt2800_rfcsr_write(rt2x00dev, 58, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 59, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 60, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 61, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 62, 0x00); ++ rt2800_rfcsr_write(rt2x00dev, 63, 0x00); ++ ++ /* TODO: rx filter calibration? */ ++ ++ rt2800_bbp_write(rt2x00dev, 137, 0x0f); ++ ++ rt2800_bbp_write(rt2x00dev, 163, 0x9d); ++ ++ rt2800_bbp_write(rt2x00dev, 105, 0x05); ++ ++ rt2800_bbp_write(rt2x00dev, 179, 0x02); ++ rt2800_bbp_write(rt2x00dev, 180, 0x00); ++ rt2800_bbp_write(rt2x00dev, 182, 0x40); ++ rt2800_bbp_write(rt2x00dev, 180, 0x01); ++ rt2800_bbp_write(rt2x00dev, 182, 0x9c); ++ ++ rt2800_bbp_write(rt2x00dev, 179, 0x00); ++ ++ rt2800_bbp_write(rt2x00dev, 142, 0x04); ++ rt2800_bbp_write(rt2x00dev, 143, 0x3b); ++ rt2800_bbp_write(rt2x00dev, 142, 0x06); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa0); ++ rt2800_bbp_write(rt2x00dev, 142, 0x07); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa1); ++ rt2800_bbp_write(rt2x00dev, 142, 0x08); ++ rt2800_bbp_write(rt2x00dev, 143, 0xa2); ++ rt2800_bbp_write(rt2x00dev, 148, 0xc8); ++ ++ if (eco == 5) { ++ rt2800_rfcsr_write(rt2x00dev, 32, 0xd8); ++ rt2800_rfcsr_write(rt2x00dev, 33, 0x32); ++ } ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 2); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_BP, 0); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); ++ msleep(1); ++ rt2x00_set_field8(&rfcsr, RFCSR2_RESCAL_EN, 0); ++ rt2800_rfcsr_write(rt2x00dev, 2, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 1); ++ rt2x00_set_field8(&rfcsr, RFCSR1_RF_BLOCK_EN, 1); ++ rt2800_rfcsr_write(rt2x00dev, 1, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 6); ++ rfcsr |= 0xc0; ++ rt2800_rfcsr_write(rt2x00dev, 6, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 22); ++ rfcsr |= 0x20; ++ rt2800_rfcsr_write(rt2x00dev, 22, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 46); ++ rfcsr |= 0x20; ++ rt2800_rfcsr_write(rt2x00dev, 46, rfcsr); ++ ++ rfcsr = rt2800_rfcsr_read(rt2x00dev, 20); ++ rfcsr &= ~0xee; ++ rt2800_rfcsr_write(rt2x00dev, 20, rfcsr); ++} ++ + static void rt2800_init_rfcsr_5390(struct rt2x00_dev *rt2x00dev) + { + rt2800_rf_init_calibration(rt2x00dev, 2); +@@ -8456,6 +8942,9 @@ static void rt2800_init_rfcsr(struct rt2 + case RT3390: + rt2800_init_rfcsr_3390(rt2x00dev); + break; ++ case RT3883: ++ rt2800_init_rfcsr_3883(rt2x00dev); ++ break; + case RT3572: + rt2800_init_rfcsr_3572(rt2x00dev); + break; +@@ -8661,7 +9150,8 @@ static u8 rt2800_get_txmixer_gain_24g(st + { + u16 word; + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + return 0; + + word = rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_BG); +@@ -8675,7 +9165,8 @@ static u8 rt2800_get_txmixer_gain_5g(str + { + u16 word; + +- if (rt2x00_rt(rt2x00dev, RT3593)) ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) + return 0; + + word = rt2800_eeprom_read(rt2x00dev, EEPROM_TXMIXER_GAIN_A); +@@ -8781,7 +9272,8 @@ static int rt2800_validate_eeprom(struct + word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_BG2); + if (abs(rt2x00_get_field16(word, EEPROM_RSSI_BG2_OFFSET2)) > 10) + rt2x00_set_field16(&word, EEPROM_RSSI_BG2_OFFSET2, 0); +- if (!rt2x00_rt(rt2x00dev, RT3593)) { ++ if (!rt2x00_rt(rt2x00dev, RT3593) && ++ !rt2x00_rt(rt2x00dev, RT3883)) { + if (rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0x00 || + rt2x00_get_field16(word, EEPROM_RSSI_BG2_LNA_A1) == 0xff) + rt2x00_set_field16(&word, EEPROM_RSSI_BG2_LNA_A1, +@@ -8801,7 +9293,8 @@ static int rt2800_validate_eeprom(struct + word = rt2800_eeprom_read(rt2x00dev, EEPROM_RSSI_A2); + if (abs(rt2x00_get_field16(word, EEPROM_RSSI_A2_OFFSET2)) > 10) + rt2x00_set_field16(&word, EEPROM_RSSI_A2_OFFSET2, 0); +- if (!rt2x00_rt(rt2x00dev, RT3593)) { ++ if (!rt2x00_rt(rt2x00dev, RT3593) && ++ !rt2x00_rt(rt2x00dev, RT3883)) { + if (rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0x00 || + rt2x00_get_field16(word, EEPROM_RSSI_A2_LNA_A2) == 0xff) + rt2x00_set_field16(&word, EEPROM_RSSI_A2_LNA_A2, +@@ -8809,7 +9302,8 @@ static int rt2800_validate_eeprom(struct + } + rt2800_eeprom_write(rt2x00dev, EEPROM_RSSI_A2, word); + +- if (rt2x00_rt(rt2x00dev, RT3593)) { ++ if (rt2x00_rt(rt2x00dev, RT3593) || ++ rt2x00_rt(rt2x00dev, RT3883)) { + word = rt2800_eeprom_read(rt2x00dev, EEPROM_EXT_LNA2); + if (rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0x00 || + rt2x00_get_field16(word, EEPROM_EXT_LNA2_A1) == 0xff) +@@ -8848,6 +9342,8 @@ static int rt2800_init_eeprom(struct rt2 + rf = rt2800_eeprom_read(rt2x00dev, EEPROM_CHIP_ID); + else if (rt2x00_rt(rt2x00dev, RT3352)) + rf = RF3322; ++ else if (rt2x00_rt(rt2x00dev, RT3883)) ++ rf = RF3853; + else if (rt2x00_rt(rt2x00dev, RT5350)) + rf = RF5350; + else +@@ -8868,6 +9364,7 @@ static int rt2800_init_eeprom(struct rt2 + case RF3290: + case RF3320: + case RF3322: ++ case RF3853: + case RF5350: + case RF5360: + case RF5362: +@@ -9154,6 +9651,66 @@ static const struct rf_channel rf_vals_3 + {14, 0xF0, 2, 0x18}, + }; + ++static const struct rf_channel rf_vals_3853[] = { ++ {1, 241, 6, 2}, ++ {2, 241, 6, 7}, ++ {3, 242, 6, 2}, ++ {4, 242, 6, 7}, ++ {5, 243, 6, 2}, ++ {6, 243, 6, 7}, ++ {7, 244, 6, 2}, ++ {8, 244, 6, 7}, ++ {9, 245, 6, 2}, ++ {10, 245, 6, 7}, ++ {11, 246, 6, 2}, ++ {12, 246, 6, 7}, ++ {13, 247, 6, 2}, ++ {14, 248, 6, 4}, ++ ++ {36, 0x56, 8, 4}, ++ {38, 0x56, 8, 6}, ++ {40, 0x56, 8, 8}, ++ {44, 0x57, 8, 0}, ++ {46, 0x57, 8, 2}, ++ {48, 0x57, 8, 4}, ++ {52, 0x57, 8, 8}, ++ {54, 0x57, 8, 10}, ++ {56, 0x58, 8, 0}, ++ {60, 0x58, 8, 4}, ++ {62, 0x58, 8, 6}, ++ {64, 0x58, 8, 8}, ++ ++ {100, 0x5b, 8, 8}, ++ {102, 0x5b, 8, 10}, ++ {104, 0x5c, 8, 0}, ++ {108, 0x5c, 8, 4}, ++ {110, 0x5c, 8, 6}, ++ {112, 0x5c, 8, 8}, ++ {114, 0x5c, 8, 10}, ++ {116, 0x5d, 8, 0}, ++ {118, 0x5d, 8, 2}, ++ {120, 0x5d, 8, 4}, ++ {124, 0x5d, 8, 8}, ++ {126, 0x5d, 8, 10}, ++ {128, 0x5e, 8, 0}, ++ {132, 0x5e, 8, 4}, ++ {134, 0x5e, 8, 6}, ++ {136, 0x5e, 8, 8}, ++ {140, 0x5f, 8, 0}, ++ ++ {149, 0x5f, 8, 9}, ++ {151, 0x5f, 8, 11}, ++ {153, 0x60, 8, 1}, ++ {157, 0x60, 8, 5}, ++ {159, 0x60, 8, 7}, ++ {161, 0x60, 8, 9}, ++ {165, 0x61, 8, 1}, ++ {167, 0x61, 8, 3}, ++ {169, 0x61, 8, 5}, ++ {171, 0x61, 8, 7}, ++ {173, 0x61, 8, 9}, ++}; ++ + static const struct rf_channel rf_vals_5592_xtal20[] = { + /* Channel, N, K, mod, R */ + {1, 482, 4, 10, 3}, +@@ -9417,6 +9974,11 @@ static int rt2800_probe_hw_mode(struct r + spec->channels = rf_vals_3x; + break; + ++ case RF3853: ++ spec->num_channels = ARRAY_SIZE(rf_vals_3853); ++ spec->channels = rf_vals_3853; ++ break; ++ + case RF5592: + reg = rt2800_register_read(rt2x00dev, MAC_DEBUG_INDEX); + if (rt2x00_get_field32(reg, MAC_DEBUG_INDEX_XTAL)) { +@@ -9536,6 +10098,7 @@ static int rt2800_probe_hw_mode(struct r + case RF3053: + case RF3070: + case RF3290: ++ case RF3853: + case RF5350: + case RF5360: + case RF5362: +@@ -9578,6 +10141,7 @@ static int rt2800_probe_rt(struct rt2x00 + case RT3390: + case RT3572: + case RT3593: ++ case RT3883: + case RT5350: + case RT5390: + case RT5392: +--- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c ++++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +@@ -51,9 +51,16 @@ static bool rt2800soc_hwcrypt_disabled(s + + static void rt2800soc_disable_radio(struct rt2x00_dev *rt2x00dev) + { ++ u32 reg; ++ + rt2800_disable_radio(rt2x00dev); + rt2x00mmio_register_write(rt2x00dev, PWR_PIN_CFG, 0); +- rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, 0); ++ ++ reg = 0; ++ if (rt2x00_rt(rt2x00dev, RT3883)) ++ rt2x00_set_field32(®, TX_PIN_CFG_RFTR_EN, 1); ++ ++ rt2x00mmio_register_write(rt2x00dev, TX_PIN_CFG, reg); + } + + static int rt2800soc_set_device_state(struct rt2x00_dev *rt2x00dev, diff --git a/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch b/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch index 295904c64e..9dd348151c 100644 --- a/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch +++ b/package/kernel/mac80211/patches/rt2x00/100-rt2x00_options.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/Kconfig +++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -@@ -226,36 +226,37 @@ config RT2800SOC +@@ -225,36 +225,37 @@ config RT2800SOC config RT2800_LIB diff --git a/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch b/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch index b4106b0197..699989baa0 100644 --- a/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch +++ b/package/kernel/mac80211/patches/rt2x00/501-rt2x00-allow-to-build-rt2800soc-module-for-RT3883.patch @@ -10,7 +10,7 @@ Signed-off-by: Gabor Juhos --- a/drivers/net/wireless/ralink/rt2x00/Kconfig +++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -@@ -211,7 +211,7 @@ endif +@@ -210,7 +210,7 @@ endif config RT2800SOC tristate "Ralink WiSoC support" depends on m @@ -19,7 +19,7 @@ Signed-off-by: Gabor Juhos select RT2X00_LIB_SOC select RT2X00_LIB_MMIO select RT2X00_LIB_CRYPTO -@@ -246,7 +246,7 @@ config RT2X00_LIB_PCI +@@ -245,7 +245,7 @@ config RT2X00_LIB_PCI config RT2X00_LIB_SOC tristate "RT2x00 SoC support" diff --git a/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch b/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch index f9d48b2b31..9d47076ff6 100644 --- a/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch +++ b/package/kernel/mac80211/patches/rt2x00/601-rt2x00-introduce-rt2x00_platform_h.patch @@ -22,7 +22,7 @@ +#endif /* _RT2X00_PLATFORM_H */ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -29,6 +29,7 @@ +@@ -40,6 +40,7 @@ #include #include #include diff --git a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch index b388fb9e5d..697d8188f0 100644 --- a/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch +++ b/package/kernel/mac80211/patches/rt2x00/602-rt2x00-introduce-rt2x00eeprom.patch @@ -1,6 +1,6 @@ --- a/local-symbols +++ b/local-symbols -@@ -313,6 +313,7 @@ RT2X00_LIB_FIRMWARE= +@@ -305,6 +305,7 @@ RT2X00_LIB_FIRMWARE= RT2X00_LIB_CRYPTO= RT2X00_LIB_LEDS= RT2X00_LIB_DEBUGFS= @@ -10,7 +10,7 @@ RTL8180= --- a/drivers/net/wireless/ralink/rt2x00/Kconfig +++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -@@ -70,6 +70,7 @@ config RT2800PCI +@@ -69,6 +69,7 @@ config RT2800PCI select RT2X00_LIB_MMIO select RT2X00_LIB_PCI select RT2X00_LIB_FIRMWARE @@ -18,7 +18,7 @@ select RT2X00_LIB_CRYPTO depends on CRC_CCITT depends on EEPROM_93CX6 -@@ -216,6 +217,7 @@ config RT2800SOC +@@ -215,6 +216,7 @@ config RT2800SOC select RT2X00_LIB_MMIO select RT2X00_LIB_CRYPTO select RT2X00_LIB_FIRMWARE @@ -26,12 +26,12 @@ select RT2800_LIB select RT2800_LIB_MMIO ---help--- -@@ -266,6 +268,9 @@ config RT2X00_LIB_FIRMWARE +@@ -265,6 +267,9 @@ config RT2X00_LIB_FIRMWARE config RT2X00_LIB_CRYPTO bool +config RT2X00_LIB_EEPROM -+ bool ++ boolean + config RT2X00_LIB_LEDS bool @@ -48,7 +48,7 @@ obj-$(CPTCFG_RT2X00_LIB_MMIO) += rt2x00mmio.o --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -37,6 +37,8 @@ struct rt2800_drv_data { +@@ -48,6 +48,8 @@ struct rt2800_drv_data { struct ieee80211_sta *wcid_to_sta[STA_IDS_SIZE]; }; @@ -57,7 +57,7 @@ struct rt2800_ops { u32 (*register_read)(struct rt2x00_dev *rt2x00dev, const unsigned int offset); -@@ -135,6 +137,15 @@ static inline int rt2800_read_eeprom(str +@@ -145,6 +147,15 @@ static inline int rt2800_read_eeprom(str { const struct rt2800_ops *rt2800ops = rt2x00dev->ops->drv; @@ -75,7 +75,7 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -@@ -90,19 +90,6 @@ static int rt2800soc_set_device_state(st +@@ -102,19 +102,6 @@ static int rt2800soc_set_device_state(st return retval; } @@ -95,7 +95,7 @@ /* Firmware functions */ static char *rt2800soc_get_firmware_name(struct rt2x00_dev *rt2x00dev) { -@@ -166,7 +153,6 @@ static const struct rt2800_ops rt2800soc +@@ -178,7 +165,6 @@ static const struct rt2800_ops rt2800soc .register_multiread = rt2x00mmio_register_multiread, .register_multiwrite = rt2x00mmio_register_multiwrite, .regbusy_read = rt2x00mmio_regbusy_read, @@ -105,7 +105,7 @@ .drv_init_registers = rt2800mmio_init_registers, --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -695,6 +695,7 @@ enum rt2x00_capability_flags { +@@ -702,6 +702,7 @@ enum rt2x00_capability_flags { REQUIRE_HT_TX_DESC, REQUIRE_PS_AUTOWAKE, REQUIRE_DELAYED_RFKILL, @@ -113,7 +113,7 @@ /* * Capabilities -@@ -971,6 +972,11 @@ struct rt2x00_dev { +@@ -977,6 +978,11 @@ struct rt2x00_dev { const struct firmware *fw; /* @@ -127,7 +127,7 @@ DECLARE_KFIFO_PTR(txstatus_fifo, u32); --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1418,6 +1418,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de +@@ -1423,6 +1423,10 @@ int rt2x00lib_probe_dev(struct rt2x00_de INIT_DELAYED_WORK(&rt2x00dev->autowakeup_work, rt2x00lib_autowakeup); INIT_WORK(&rt2x00dev->sleep_work, rt2x00lib_sleep); @@ -138,7 +138,7 @@ /* * Let the driver probe the device to detect the capabilities. */ -@@ -1561,6 +1565,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ +@@ -1566,6 +1570,11 @@ void rt2x00lib_remove_dev(struct rt2x00_ * Free the driver data. */ kfree(rt2x00dev->drv_data); @@ -261,7 +261,7 @@ +} --- a/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00lib.h -@@ -286,6 +286,22 @@ static inline void rt2x00lib_free_firmwa +@@ -297,6 +297,22 @@ static inline void rt2x00lib_free_firmwa #endif /* CPTCFG_RT2X00_LIB_FIRMWARE */ /* @@ -286,7 +286,7 @@ #ifdef CPTCFG_RT2X00_LIB_DEBUGFS --- a/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00soc.c -@@ -86,6 +86,7 @@ int rt2x00soc_probe(struct platform_devi +@@ -97,6 +97,7 @@ int rt2x00soc_probe(struct platform_devi if (IS_ERR(rt2x00dev->clk)) rt2x00dev->clk = NULL; diff --git a/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch b/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch index 08ca7c96fd..b3e1220b60 100644 --- a/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch +++ b/package/kernel/mac80211/patches/rt2x00/604-rt2x00-load-eeprom-on-SoC-from-a-mtd-device-defines-.patch @@ -12,7 +12,7 @@ Signed-off-by: John Crispin --- a/drivers/net/wireless/ralink/rt2x00/Kconfig +++ b/drivers/net/wireless/ralink/rt2x00/Kconfig -@@ -220,6 +220,7 @@ config RT2800SOC +@@ -219,6 +219,7 @@ config RT2800SOC select RT2X00_LIB_EEPROM select RT2800_LIB select RT2800_LIB_MMIO diff --git a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch index 8a885fad86..202dfc0b89 100644 --- a/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch +++ b/package/kernel/mac80211/patches/rt2x00/606-rt2x00-allow_disabling_bands_through_platform_data.patch @@ -12,7 +12,7 @@ #endif /* _RT2X00_PLATFORM_H */ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1012,6 +1012,22 @@ static int rt2x00lib_probe_hw_modes(stru +@@ -1026,6 +1026,22 @@ static int rt2x00lib_probe_hw_modes(stru unsigned int num_rates; unsigned int i; @@ -37,7 +37,7 @@ num_rates += 4; --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -400,6 +400,7 @@ struct hw_mode_spec { +@@ -409,6 +409,7 @@ struct hw_mode_spec { unsigned int supported_bands; #define SUPPORT_BAND_2GHZ 0x00000001 #define SUPPORT_BAND_5GHZ 0x00000002 diff --git a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch index b5b2c61037..b8b0188040 100644 --- a/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch +++ b/package/kernel/mac80211/patches/rt2x00/607-rt2x00-add_platform_data_mac_addr.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -990,8 +990,13 @@ static void rt2x00lib_rate(struct ieee80 +@@ -1004,8 +1004,13 @@ static void rt2x00lib_rate(struct ieee80 void rt2x00lib_set_mac_address(struct rt2x00_dev *rt2x00dev, u8 *eeprom_mac_addr) { @@ -12,7 +12,7 @@ + ether_addr_copy(eeprom_mac_addr, pdata->mac_address); + mac_addr = of_get_mac_address(rt2x00dev->dev->of_node); - if (!IS_ERR(mac_addr)) + if (mac_addr) ether_addr_copy(eeprom_mac_addr, mac_addr); --- a/include/linux/rt2x00_platform.h +++ b/include/linux/rt2x00_platform.h diff --git a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch index ff8b2c947b..ca66aa8e3b 100644 --- a/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch +++ b/package/kernel/mac80211/patches/rt2x00/608-rt2x00-allow_disabling_bands_through_dts.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1016,6 +1016,16 @@ static int rt2x00lib_probe_hw_modes(stru +@@ -1030,6 +1030,16 @@ static int rt2x00lib_probe_hw_modes(stru struct ieee80211_rate *rates; unsigned int num_rates; unsigned int i; diff --git a/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch b/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch index 35714c04d2..ed219c801e 100644 --- a/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch +++ b/package/kernel/mac80211/patches/rt2x00/609-rt2x00-make-wmac-loadable-via-OF-on-rt288x-305x-SoC.patch @@ -13,7 +13,7 @@ Signed-off-by: John Crispin --- a/drivers/net/wireless/ralink/rt2x00/rt2800soc.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800soc.c -@@ -223,10 +223,17 @@ static int rt2800soc_probe(struct platfo +@@ -232,10 +232,17 @@ static int rt2800soc_probe(struct platfo return rt2x00soc_probe(pdev, &rt2800soc_ops); } diff --git a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch index 0efd3a157d..f0c079b62b 100644 --- a/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch +++ b/package/kernel/mac80211/patches/rt2x00/610-rt2x00-change-led-polarity-from-OF.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -25,6 +25,7 @@ +@@ -36,6 +36,7 @@ #include #include #include @@ -8,7 +8,7 @@ #include "rt2x00.h" #include "rt2800lib.h" -@@ -9534,6 +9535,17 @@ static int rt2800_init_eeprom(struct rt2 +@@ -9458,6 +9459,17 @@ static int rt2800_init_eeprom(struct rt2 rt2800_init_led(rt2x00dev, &rt2x00dev->led_assoc, LED_TYPE_ASSOC); rt2800_init_led(rt2x00dev, &rt2x00dev->led_qual, LED_TYPE_QUALITY); @@ -28,7 +28,7 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00leds.c -@@ -98,6 +98,9 @@ static int rt2x00leds_register_led(struc +@@ -109,6 +109,9 @@ static int rt2x00leds_register_led(struc led->led_dev.name = name; led->led_dev.brightness = LED_OFF; diff --git a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch index d909a2e6c6..062b18a63b 100644 --- a/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch +++ b/package/kernel/mac80211/patches/rt2x00/611-rt2x00-add-AP+STA-support.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00dev.c -@@ -1356,7 +1356,7 @@ static inline void rt2x00lib_set_if_comb +@@ -1361,7 +1361,7 @@ static inline void rt2x00lib_set_if_comb */ if_limit = &rt2x00dev->if_limits_ap; if_limit->max = rt2x00dev->ops->max_ap_intf; diff --git a/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch b/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch index 9bbf2ad07e..2b6aa43c2d 100644 --- a/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch +++ b/package/kernel/mac80211/patches/rt2x00/650-rt2x00-add-support-for-external-PA-on-MT7620.patch @@ -20,7 +20,7 @@ Signed-off-by: Tomislav Po=C5=BEega --- a/drivers/net/wireless/ralink/rt2x00/rt2800.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800.h -@@ -2739,6 +2739,7 @@ enum rt2800_eeprom_word { +@@ -2750,6 +2750,7 @@ enum rt2800_eeprom_word { #define EEPROM_NIC_CONF2_RX_STREAM FIELD16(0x000f) #define EEPROM_NIC_CONF2_TX_STREAM FIELD16(0x00f0) #define EEPROM_NIC_CONF2_CRYSTAL FIELD16(0x0600) @@ -30,7 +30,7 @@ Signed-off-by: Tomislav Po=C5=BEega * EEPROM LNA --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -4359,6 +4359,45 @@ static void rt2800_config_channel(struct +@@ -4290,6 +4290,45 @@ static void rt2800_config_channel(struct rt2800_iq_calibrate(rt2x00dev, rf->channel); } @@ -76,7 +76,7 @@ Signed-off-by: Tomislav Po=C5=BEega bbp = rt2800_bbp_read(rt2x00dev, 4); rt2x00_set_field8(&bbp, BBP4_BANDWIDTH, 2 * conf_is_ht40(conf)); rt2800_bbp_write(rt2x00dev, 4, bbp); -@@ -9563,7 +9602,8 @@ static int rt2800_init_eeprom(struct rt2 +@@ -9487,7 +9526,8 @@ static int rt2800_init_eeprom(struct rt2 */ eeprom = rt2800_eeprom_read(rt2x00dev, EEPROM_NIC_CONF1); @@ -86,7 +86,7 @@ Signed-off-by: Tomislav Po=C5=BEega if (rt2x00_get_field16(eeprom, EEPROM_NIC_CONF1_EXTERNAL_TX0_PA_3352)) __set_bit(CAPABILITY_EXTERNAL_PA_TX0, -@@ -9574,6 +9614,18 @@ static int rt2800_init_eeprom(struct rt2 +@@ -9498,6 +9538,18 @@ static int rt2800_init_eeprom(struct rt2 &rt2x00dev->cap_flags); } diff --git a/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch b/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch index 38558885ac..454f55b1cf 100644 --- a/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch +++ b/package/kernel/mac80211/patches/rt2x00/982-rt2x00-add-rf-self-txdc-calibration.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -8425,6 +8425,58 @@ static void rt2800_init_rfcsr_5592(struc +@@ -8349,6 +8349,58 @@ static void rt2800_init_rfcsr_5592(struc rt2800_led_open_drain_enable(rt2x00dev); } @@ -59,7 +59,7 @@ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, bool set_bw, bool is_ht40) { -@@ -9032,6 +9084,7 @@ static void rt2800_init_rfcsr_6352(struc +@@ -8956,6 +9008,7 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); @@ -69,7 +69,7 @@ } --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -242,6 +242,7 @@ void rt2800_link_tuner(struct rt2x00_dev +@@ -243,6 +243,7 @@ void rt2800_link_tuner(struct rt2x00_dev const u32 count); void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev); @@ -79,7 +79,7 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -563,6 +563,7 @@ struct rt2x00lib_ops { +@@ -572,6 +572,7 @@ struct rt2x00lib_ops { struct link_qual *qual, const u32 count); void (*gain_calibration) (struct rt2x00_dev *rt2x00dev); void (*vco_calibration) (struct rt2x00_dev *rt2x00dev); diff --git a/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch b/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch index e56044f882..6f0d5b577f 100644 --- a/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch +++ b/package/kernel/mac80211/patches/rt2x00/983-rt2x00-add-r-calibration.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -8477,6 +8477,160 @@ void rt2800_rf_self_txdc_cal(struct rt2x +@@ -8401,6 +8401,160 @@ void rt2800_rf_self_txdc_cal(struct rt2x } EXPORT_SYMBOL_GPL(rt2800_rf_self_txdc_cal); @@ -161,7 +161,7 @@ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, bool set_bw, bool is_ht40) { -@@ -9084,6 +9238,7 @@ static void rt2800_init_rfcsr_6352(struc +@@ -9008,6 +9162,7 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rfcsr_write_dccal(rt2x00dev, 5, 0x00); rt2800_rfcsr_write_dccal(rt2x00dev, 17, 0x7C); @@ -171,7 +171,7 @@ rt2800_bw_filter_calibration(rt2x00dev, false); --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -243,6 +243,8 @@ void rt2800_link_tuner(struct rt2x00_dev +@@ -244,6 +244,8 @@ void rt2800_link_tuner(struct rt2x00_dev void rt2800_gain_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_vco_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev); @@ -182,7 +182,7 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -564,6 +564,8 @@ struct rt2x00lib_ops { +@@ -573,6 +573,8 @@ struct rt2x00lib_ops { void (*gain_calibration) (struct rt2x00_dev *rt2x00dev); void (*vco_calibration) (struct rt2x00_dev *rt2x00dev); void (*rf_self_txdc_cal) (struct rt2x00_dev *rt2x00dev); diff --git a/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch b/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch index 79cc7807b2..fbeace27da 100644 --- a/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch +++ b/package/kernel/mac80211/patches/rt2x00/984-rt2x00-add-rxdcoc-calibration.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -8631,6 +8631,71 @@ void rt2800_r_calibration(struct rt2x00_ +@@ -8555,6 +8555,71 @@ void rt2800_r_calibration(struct rt2x00_ } EXPORT_SYMBOL_GPL(rt2800_r_calibration); @@ -72,7 +72,7 @@ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, bool set_bw, bool is_ht40) { -@@ -9240,6 +9305,7 @@ static void rt2800_init_rfcsr_6352(struc +@@ -9164,6 +9229,7 @@ static void rt2800_init_rfcsr_6352(struc rt2800_r_calibration(rt2x00dev); rt2800_rf_self_txdc_cal(rt2x00dev); @@ -82,7 +82,7 @@ } --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -245,6 +245,7 @@ void rt2800_vco_calibration(struct rt2x0 +@@ -246,6 +246,7 @@ void rt2800_vco_calibration(struct rt2x0 void rt2800_rf_self_txdc_cal(struct rt2x00_dev *rt2x00dev); int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2); void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev); @@ -92,7 +92,7 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -566,6 +566,7 @@ struct rt2x00lib_ops { +@@ -575,6 +575,7 @@ struct rt2x00lib_ops { void (*rf_self_txdc_cal) (struct rt2x00_dev *rt2x00dev); int (*calcrcalibrationcode) (struct rt2x00_dev *rt2x00dev, int d1, int d2); void (*r_calibration) (struct rt2x00_dev *rt2x00dev); diff --git a/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch b/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch index 01bed89a63..f469c4ebc7 100644 --- a/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch +++ b/package/kernel/mac80211/patches/rt2x00/985-rt2x00-add-rxiq-calibration.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -8696,6 +8696,386 @@ void rt2800_rxdcoc_calibration(struct rt +@@ -8620,6 +8620,386 @@ void rt2800_rxdcoc_calibration(struct rt } EXPORT_SYMBOL_GPL(rt2800_rxdcoc_calibration); @@ -387,7 +387,7 @@ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, bool set_bw, bool is_ht40) { -@@ -9308,6 +9688,7 @@ static void rt2800_init_rfcsr_6352(struc +@@ -9232,6 +9612,7 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rxdcoc_calibration(rt2x00dev); rt2800_bw_filter_calibration(rt2x00dev, true); rt2800_bw_filter_calibration(rt2x00dev, false); @@ -397,7 +397,7 @@ static void rt2800_init_rfcsr(struct rt2x00_dev *rt2x00dev) --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -246,6 +246,7 @@ void rt2800_rf_self_txdc_cal(struct rt2x +@@ -247,6 +247,7 @@ void rt2800_rf_self_txdc_cal(struct rt2x int rt2800_calcrcalibrationcode(struct rt2x00_dev *rt2x00dev, int d1, int d2); void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev); @@ -407,7 +407,7 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -567,6 +567,7 @@ struct rt2x00lib_ops { +@@ -576,6 +576,7 @@ struct rt2x00lib_ops { int (*calcrcalibrationcode) (struct rt2x00_dev *rt2x00dev, int d1, int d2); void (*r_calibration) (struct rt2x00_dev *rt2x00dev); void (*rxdcoc_calibration) (struct rt2x00_dev *rt2x00dev); diff --git a/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch b/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch index eca6573457..31a860c1a7 100644 --- a/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch +++ b/package/kernel/mac80211/patches/rt2x00/986-rt2x00-add-TX-LOFT-calibration.patch @@ -1,6 +1,6 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.c +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.c -@@ -9076,6 +9076,954 @@ restore_value: +@@ -9000,6 +9000,954 @@ restore_value: } EXPORT_SYMBOL_GPL(rt2800_rxiq_calibration); @@ -955,7 +955,7 @@ static void rt2800_bbp_core_soft_reset(struct rt2x00_dev *rt2x00dev, bool set_bw, bool is_ht40) { -@@ -9688,6 +10636,7 @@ static void rt2800_init_rfcsr_6352(struc +@@ -9612,6 +10560,7 @@ static void rt2800_init_rfcsr_6352(struc rt2800_rxdcoc_calibration(rt2x00dev); rt2800_bw_filter_calibration(rt2x00dev, true); rt2800_bw_filter_calibration(rt2x00dev, false); @@ -965,7 +965,7 @@ --- a/drivers/net/wireless/ralink/rt2x00/rt2800lib.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2800lib.h -@@ -17,6 +17,16 @@ +@@ -28,6 +28,16 @@ #define WCID_START 33 #define WCID_END 222 #define STA_IDS_SIZE (WCID_END - WCID_START + 2) @@ -982,7 +982,7 @@ /* RT2800 driver data structure */ struct rt2800_drv_data { -@@ -247,6 +257,7 @@ int rt2800_calcrcalibrationcode(struct r +@@ -248,6 +258,7 @@ int rt2800_calcrcalibrationcode(struct r void rt2800_r_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_rxdcoc_calibration(struct rt2x00_dev *rt2x00dev); void rt2800_rxiq_calibration(struct rt2x00_dev *rt2x00dev); @@ -992,7 +992,7 @@ void rt2800_disable_radio(struct rt2x00_dev *rt2x00dev); --- a/drivers/net/wireless/ralink/rt2x00/rt2x00.h +++ b/drivers/net/wireless/ralink/rt2x00/rt2x00.h -@@ -568,6 +568,7 @@ struct rt2x00lib_ops { +@@ -577,6 +577,7 @@ struct rt2x00lib_ops { void (*r_calibration) (struct rt2x00_dev *rt2x00dev); void (*rxdcoc_calibration) (struct rt2x00_dev *rt2x00dev); void (*rxiq_calibration) (struct rt2x00_dev *rt2x00dev); diff --git a/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch b/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch deleted file mode 100644 index 7bba7176cb..0000000000 --- a/package/kernel/mac80211/patches/subsys/030-mac80211_fix-scan-when-operating-on-DFS-channels-in-ETSI-domains.patch +++ /dev/null @@ -1,118 +0,0 @@ -From dc0c18ed229cdcca283dd78fefa38273ec37a42c Mon Sep 17 00:00:00 2001 -From: Aaron Komisar -Date: Wed, 2 Oct 2019 13:59:07 +0000 -Subject: mac80211: fix scan when operating on DFS channels in ETSI domains - -In non-ETSI regulatory domains scan is blocked when operating channel -is a DFS channel. For ETSI, however, once DFS channel is marked as -available after the CAC, this channel will remain available (for some -time) even after leaving this channel. - -Therefore a scan can be done without any impact on the availability -of the DFS channel as no new CAC is required after the scan. - -Enable scan in mac80211 in these cases. - -Signed-off-by: Aaron Komisar -Link: https://lore.kernel.org/r/1570024728-17284-1-git-send-email-aaron.komisar@tandemg.com -Signed-off-by: Johannes Berg ---- - include/net/cfg80211.h | 8 ++++++++ - net/mac80211/scan.c | 30 ++++++++++++++++++++++++++++-- - net/wireless/reg.c | 1 + - net/wireless/reg.h | 8 -------- - 4 files changed, 37 insertions(+), 10 deletions(-) - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -5451,6 +5451,14 @@ const struct ieee80211_reg_rule *freq_re - const char *reg_initiator_name(enum nl80211_reg_initiator initiator); - - /** -+ * regulatory_pre_cac_allowed - check if pre-CAC allowed in the current regdom -+ * @wiphy: wiphy for which pre-CAC capability is checked. -+ * -+ * Pre-CAC is allowed only in some regdomains (notable ETSI). -+ */ -+bool regulatory_pre_cac_allowed(struct wiphy *wiphy); -+ -+/** - * DOC: Internal regulatory db functions - * - */ ---- a/net/mac80211/scan.c -+++ b/net/mac80211/scan.c -@@ -520,10 +520,33 @@ static int ieee80211_start_sw_scan(struc - return 0; - } - -+static bool __ieee80211_can_leave_ch(struct ieee80211_sub_if_data *sdata) -+{ -+ struct ieee80211_local *local = sdata->local; -+ struct ieee80211_sub_if_data *sdata_iter; -+ -+ if (!ieee80211_is_radar_required(local)) -+ return true; -+ -+ if (!regulatory_pre_cac_allowed(local->hw.wiphy)) -+ return false; -+ -+ mutex_lock(&local->iflist_mtx); -+ list_for_each_entry(sdata_iter, &local->interfaces, list) { -+ if (sdata_iter->wdev.cac_started) { -+ mutex_unlock(&local->iflist_mtx); -+ return false; -+ } -+ } -+ mutex_unlock(&local->iflist_mtx); -+ -+ return true; -+} -+ - static bool ieee80211_can_scan(struct ieee80211_local *local, - struct ieee80211_sub_if_data *sdata) - { -- if (ieee80211_is_radar_required(local)) -+ if (!__ieee80211_can_leave_ch(sdata)) - return false; - - if (!list_empty(&local->roc_list)) -@@ -630,7 +653,10 @@ static int __ieee80211_start_scan(struct - - lockdep_assert_held(&local->mtx); - -- if (local->scan_req || ieee80211_is_radar_required(local)) -+ if (local->scan_req) -+ return -EBUSY; -+ -+ if (!__ieee80211_can_leave_ch(sdata)) - return -EBUSY; - - if (!ieee80211_can_scan(local, sdata)) { ---- a/net/wireless/reg.c -+++ b/net/wireless/reg.c -@@ -3866,6 +3866,7 @@ bool regulatory_pre_cac_allowed(struct w - - return pre_cac_allowed; - } -+EXPORT_SYMBOL(regulatory_pre_cac_allowed); - - void regulatory_propagate_dfs_state(struct wiphy *wiphy, - struct cfg80211_chan_def *chandef, ---- a/net/wireless/reg.h -+++ b/net/wireless/reg.h -@@ -156,14 +156,6 @@ bool regulatory_indoor_allowed(void); - #define REG_PRE_CAC_EXPIRY_GRACE_MS 2000 - - /** -- * regulatory_pre_cac_allowed - if pre-CAC allowed in the current dfs domain -- * @wiphy: wiphy for which pre-CAC capability is checked. -- -- * Pre-CAC is allowed only in ETSI domain. -- */ --bool regulatory_pre_cac_allowed(struct wiphy *wiphy); -- --/** - * regulatory_propagate_dfs_state - Propagate DFS channel state to other wiphys - * @wiphy - wiphy on which radar is detected and the event will be propagated - * to other available wiphys having the same DFS domain diff --git a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch index f5ec895f0b..0fe6ee196c 100644 --- a/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch +++ b/package/kernel/mac80211/patches/subsys/100-remove-cryptoapi-dependencies.patch @@ -20,14 +20,17 @@ ethtool.o \ --- a/net/mac80211/aead_api.c +++ /dev/null -@@ -1,112 +0,0 @@ --// SPDX-License-Identifier: GPL-2.0-only +@@ -1,115 +0,0 @@ -/* - * Copyright 2003-2004, Instant802 Networks, Inc. - * Copyright 2005-2006, Devicescape Software, Inc. - * Copyright 2014-2015, Qualcomm Atheros, Inc. - * - * Rewrite: Copyright (C) 2013 Linaro Ltd +- * +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License version 2 as +- * published by the Free Software Foundation. - */ - -#include @@ -135,8 +138,12 @@ -} --- a/net/mac80211/aead_api.h +++ /dev/null -@@ -1,23 +0,0 @@ --/* SPDX-License-Identifier: GPL-2.0-only */ +@@ -1,27 +0,0 @@ +-/* +- * This program is free software; you can redistribute it and/or modify +- * it under the terms of the GNU General Public License version 2 as +- * published by the Free Software Foundation. +- */ - -#ifndef _AEAD_API_H -#define _AEAD_API_H @@ -161,7 +168,7 @@ -#endif /* _AEAD_API_H */ --- a/net/mac80211/aes_ccm.h +++ b/net/mac80211/aes_ccm.h -@@ -7,39 +7,17 @@ +@@ -10,39 +10,17 @@ #ifndef AES_CCM_H #define AES_CCM_H @@ -326,7 +333,7 @@ +} --- a/net/mac80211/aes_gcm.h +++ b/net/mac80211/aes_gcm.h -@@ -6,38 +6,30 @@ +@@ -9,38 +9,30 @@ #ifndef AES_GCM_H #define AES_GCM_H @@ -378,7 +385,7 @@ #endif /* AES_GCM_H */ --- a/net/mac80211/wpa.c +++ b/net/mac80211/wpa.c -@@ -311,7 +311,8 @@ ieee80211_crypto_tkip_decrypt(struct iee +@@ -314,7 +314,8 @@ ieee80211_crypto_tkip_decrypt(struct iee } @@ -388,7 +395,7 @@ { __le16 mask_fc; int a4_included, mgmt; -@@ -341,14 +342,8 @@ static void ccmp_special_blocks(struct s +@@ -344,14 +345,8 @@ static void ccmp_special_blocks(struct s else qos_tid = 0; @@ -405,7 +412,7 @@ /* Nonce: Nonce Flags | A2 | PN * Nonce Flags: Priority (b0..b3) | Management (b4) | Reserved (b5..b7) -@@ -356,6 +351,8 @@ static void ccmp_special_blocks(struct s +@@ -359,6 +354,8 @@ static void ccmp_special_blocks(struct s b_0[1] = qos_tid | (mgmt << 4); memcpy(&b_0[2], hdr->addr2, ETH_ALEN); memcpy(&b_0[8], pn, IEEE80211_CCMP_PN_LEN); @@ -414,7 +421,7 @@ /* AAD (extra authenticate-only data) / masked 802.11 header * FC | A1 | A2 | A3 | SC | [A4] | [QC] */ -@@ -412,7 +409,7 @@ static int ccmp_encrypt_skb(struct ieee8 +@@ -415,7 +412,7 @@ static int ccmp_encrypt_skb(struct ieee8 u8 *pos; u8 pn[6]; u64 pn64; @@ -423,7 +430,7 @@ u8 b_0[AES_BLOCK_SIZE]; if (info->control.hw_key && -@@ -467,9 +464,11 @@ static int ccmp_encrypt_skb(struct ieee8 +@@ -470,9 +467,11 @@ static int ccmp_encrypt_skb(struct ieee8 return 0; pos += IEEE80211_CCMP_HDR_LEN; @@ -438,7 +445,7 @@ } -@@ -542,13 +541,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee +@@ -545,13 +544,13 @@ ieee80211_crypto_ccmp_decrypt(struct iee u8 aad[2 * AES_BLOCK_SIZE]; u8 b_0[AES_BLOCK_SIZE]; /* hardware didn't decrypt/verify MIC */ @@ -454,7 +461,7 @@ return RX_DROP_UNUSABLE; } -@@ -643,7 +642,7 @@ static int gcmp_encrypt_skb(struct ieee8 +@@ -646,7 +645,7 @@ static int gcmp_encrypt_skb(struct ieee8 u8 *pos; u8 pn[6]; u64 pn64; @@ -463,7 +470,7 @@ u8 j_0[AES_BLOCK_SIZE]; if (info->control.hw_key && -@@ -700,8 +699,10 @@ static int gcmp_encrypt_skb(struct ieee8 +@@ -703,8 +702,10 @@ static int gcmp_encrypt_skb(struct ieee8 pos += IEEE80211_GCMP_HDR_LEN; gcmp_special_blocks(skb, pn, j_0, aad); @@ -476,7 +483,7 @@ } ieee80211_tx_result -@@ -1124,9 +1125,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct +@@ -1127,9 +1128,9 @@ ieee80211_crypto_aes_gmac_encrypt(struct struct ieee80211_key *key = tx->key; struct ieee80211_mmie_16 *mmie; struct ieee80211_hdr *hdr; @@ -488,12 +495,12 @@ if (WARN_ON(skb_queue_len(&tx->skbs) != 1)) return TX_DROP; -@@ -1172,7 +1173,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct +@@ -1175,7 +1176,7 @@ ieee80211_crypto_aes_gmac_decrypt(struct struct ieee80211_rx_status *status = IEEE80211_SKB_RXCB(skb); struct ieee80211_key *key = rx->key; struct ieee80211_mmie_16 *mmie; -- u8 aad[GMAC_AAD_LEN], *mic, ipn[6], nonce[GMAC_NONCE_LEN]; -+ u8 aad[20], *mic, ipn[6], nonce[12]; +- u8 aad[GMAC_AAD_LEN], mic[GMAC_MIC_LEN], ipn[6], nonce[GMAC_NONCE_LEN]; ++ u8 aad[20], mic[16], ipn[6], nonce[12]; struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; if (!ieee80211_is_mgmt(hdr->frame_control)) @@ -646,9 +653,9 @@ +} --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig -@@ -6,8 +6,6 @@ config MAC80211 +@@ -5,8 +5,6 @@ config MAC80211 depends on CRYPTO - select BPAUTO_CRYPTO_LIB_ARC4 + depends on CRYPTO_ARC4 depends on CRYPTO_AES - depends on CRYPTO_CCM - depends on CRYPTO_GCM @@ -657,7 +664,7 @@ ---help--- --- a/net/mac80211/aes_gmac.h +++ b/net/mac80211/aes_gmac.h -@@ -12,10 +12,22 @@ +@@ -15,10 +15,22 @@ #define GMAC_MIC_LEN 16 #define GMAC_NONCE_LEN 12 @@ -687,7 +694,7 @@ #endif /* AES_GMAC_H */ --- a/net/mac80211/key.h +++ b/net/mac80211/key.h -@@ -87,7 +87,7 @@ struct ieee80211_key { +@@ -88,7 +88,7 @@ struct ieee80211_key { * Management frames. */ u8 rx_pn[IEEE80211_NUM_TIDS + 1][IEEE80211_CCMP_PN_LEN]; diff --git a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch index dcc0ac4dfb..6775884a34 100644 --- a/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch +++ b/package/kernel/mac80211/patches/subsys/110-mac80211_keep_keys_on_stop_ap.patch @@ -2,8 +2,8 @@ Used for AP+STA support in OpenWrt - preserve AP mode keys across STA reconnects --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -1169,7 +1169,6 @@ static int ieee80211_stop_ap(struct wiph - sdata->vif.bss_conf.ftmr_params = NULL; +@@ -1067,7 +1067,6 @@ static int ieee80211_stop_ap(struct wiph + sdata->u.ap.driver_smps_mode = IEEE80211_SMPS_OFF; __sta_info_flush(sdata, true); - ieee80211_free_keys(sdata, true); diff --git a/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch b/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch index 172e5b04fd..ffd8807ccc 100644 --- a/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch +++ b/package/kernel/mac80211/patches/subsys/120-cfg80211_allow_perm_addr_change.patch @@ -1,6 +1,6 @@ --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c -@@ -23,18 +23,35 @@ static inline struct cfg80211_registered +@@ -24,18 +24,35 @@ static inline struct cfg80211_registered return container_of(dev, struct cfg80211_registered_device, wiphy.dev); } diff --git a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch b/package/kernel/mac80211/patches/subsys/130-disable-fils.patch index f370dd52ee..f1163764a0 100644 --- a/package/kernel/mac80211/patches/subsys/130-disable-fils.patch +++ b/package/kernel/mac80211/patches/subsys/130-disable-fils.patch @@ -2,7 +2,7 @@ Disable FILS support, since it pulls in crypto hash support --- a/net/mac80211/fils_aead.h +++ b/net/mac80211/fils_aead.h -@@ -7,7 +7,7 @@ +@@ -10,7 +10,7 @@ #ifndef FILS_AEAD_H #define FILS_AEAD_H @@ -16,12 +16,12 @@ Disable FILS support, since it pulls in crypto hash support @@ -1,4 +1,4 @@ -#if LINUX_VERSION_IS_GEQ(4,3,0) +#if 0 /* LINUX_VERSION_IS_GEQ(4,3,0) */ - // SPDX-License-Identifier: GPL-2.0-only /* * FILS AEAD for (Re)Association Request/Response frames + * Copyright 2016, Qualcomm Atheros, Inc. --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -571,7 +571,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +@@ -570,7 +570,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ NL80211_FEATURE_MAC_ON_CREATE | NL80211_FEATURE_USERSPACE_MPM | NL80211_FEATURE_FULL_AP_CLIENT_STATE; diff --git a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch b/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch index 9830602ab0..d138b2c5ac 100644 --- a/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch +++ b/package/kernel/mac80211/patches/subsys/131-Revert-mac80211-aes-cmac-switch-to-shash-CMAC-driver.patch @@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/aes_cmac.c +++ b/net/mac80211/aes_cmac.c -@@ -19,50 +19,126 @@ +@@ -22,50 +22,126 @@ #define CMAC_TLEN_256 16 /* CMAC TLen = 128 bits (16 octets) */ #define AAD_LEN 20 @@ -166,7 +166,7 @@ Signed-off-by: Felix Fietkau } --- a/net/mac80211/aes_cmac.h +++ b/net/mac80211/aes_cmac.h -@@ -7,14 +7,13 @@ +@@ -10,14 +10,13 @@ #define AES_CMAC_H #include @@ -188,7 +188,7 @@ Signed-off-by: Felix Fietkau #endif /* AES_CMAC_H */ --- a/net/mac80211/key.h +++ b/net/mac80211/key.h -@@ -92,7 +92,7 @@ struct ieee80211_key { +@@ -93,7 +93,7 @@ struct ieee80211_key { } ccmp; struct { u8 rx_pn[IEEE80211_CMAC_PN_LEN]; diff --git a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch b/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch index 2a9c09b4ad..9d185e61e7 100644 --- a/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch +++ b/package/kernel/mac80211/patches/subsys/132-mac80211-remove-cmac-dependency.patch @@ -1,8 +1,8 @@ --- a/net/mac80211/Kconfig +++ b/net/mac80211/Kconfig -@@ -6,7 +6,6 @@ config MAC80211 +@@ -5,7 +5,6 @@ config MAC80211 depends on CRYPTO - select BPAUTO_CRYPTO_LIB_ARC4 + depends on CRYPTO_ARC4 depends on CRYPTO_AES - depends on CRYPTO_CMAC depends on CRC32 diff --git a/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch b/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch index 449179a962..42a6382209 100644 --- a/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch +++ b/package/kernel/mac80211/patches/subsys/140-tweak-TSQ-setting.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -4012,6 +4012,12 @@ out: +@@ -3797,6 +3797,12 @@ out: netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb, struct net_device *dev) { diff --git a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch index 14ef714f68..1581b3400b 100644 --- a/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch +++ b/package/kernel/mac80211/patches/subsys/150-disable_addr_notifier.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -314,7 +314,7 @@ void ieee80211_restart_hw(struct ieee802 +@@ -315,7 +315,7 @@ void ieee80211_restart_hw(struct ieee802 } EXPORT_SYMBOL(ieee80211_restart_hw); @@ -9,7 +9,7 @@ static int ieee80211_ifa_changed(struct notifier_block *nb, unsigned long data, void *arg) { -@@ -373,7 +373,7 @@ static int ieee80211_ifa_changed(struct +@@ -374,7 +374,7 @@ static int ieee80211_ifa_changed(struct } #endif @@ -18,7 +18,7 @@ static int ieee80211_ifa6_changed(struct notifier_block *nb, unsigned long data, void *arg) { -@@ -1269,14 +1269,14 @@ int ieee80211_register_hw(struct ieee802 +@@ -1168,14 +1168,14 @@ int ieee80211_register_hw(struct ieee802 rtnl_unlock(); @@ -35,7 +35,7 @@ local->ifa6_notifier.notifier_call = ieee80211_ifa6_changed; result = register_inet6addr_notifier(&local->ifa6_notifier); if (result) -@@ -1285,13 +1285,13 @@ int ieee80211_register_hw(struct ieee802 +@@ -1184,13 +1184,13 @@ int ieee80211_register_hw(struct ieee802 return 0; @@ -52,7 +52,7 @@ fail_ifa: #endif rtnl_lock(); -@@ -1319,10 +1319,10 @@ void ieee80211_unregister_hw(struct ieee +@@ -1219,10 +1219,10 @@ void ieee80211_unregister_hw(struct ieee tasklet_kill(&local->tx_pending_tasklet); tasklet_kill(&local->tasklet); diff --git a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch index 634c531b00..fcc173da69 100644 --- a/package/kernel/mac80211/patches/subsys/210-ap_scan.patch +++ b/package/kernel/mac80211/patches/subsys/210-ap_scan.patch @@ -1,6 +1,6 @@ --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2319,7 +2319,7 @@ static int ieee80211_scan(struct wiphy * +@@ -2237,7 +2237,7 @@ static int ieee80211_scan(struct wiphy * * the frames sent while scanning on other channel will be * lost) */ diff --git a/package/kernel/mac80211/patches/subsys/300-mac80211-add-stop-start-logic-for-software-TXQs.patch b/package/kernel/mac80211/patches/subsys/300-mac80211-add-stop-start-logic-for-software-TXQs.patch new file mode 100644 index 0000000000..422e9c2977 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/300-mac80211-add-stop-start-logic-for-software-TXQs.patch @@ -0,0 +1,272 @@ +From: Manikanta Pubbisetty +Date: Wed, 11 Jul 2018 00:12:53 +0530 +Subject: [PATCH] mac80211: add stop/start logic for software TXQs + +Sometimes, it is required to stop the transmissions momentarily and +resume it later; stopping the txqs becomes very critical in scenarios where +the packet transmission has to be ceased completely. For example, during +the hardware restart, during off channel operations, +when initiating CSA(upon detecting a radar on the DFS channel), etc. + +The TX queue stop/start logic in mac80211 works well in stopping the TX +when drivers make use of netdev queues, i.e, when Qdiscs in network layer +take care of traffic scheduling. Since the devices implementing +wake_tx_queue can run without Qdiscs, packets will be handed to mac80211 +directly without queueing them in the netdev queues. + +Also, mac80211 does not invoke any of the +netif_stop_*/netif_wake_* APIs if wake_tx_queue is implemented. +Since the queues are not stopped in this case, transmissions can continue +and this will impact negatively on the operation of the wireless device. + +For example, +During hardware restart, we stop the netdev queues so that packets are +not sent to the driver. Since ath10k implements wake_tx_queue, +TX queues will not be stopped and packets might reach the hardware while +it is restarting; this can make hardware unresponsive and the only +possible option for recovery is to reboot the entire system. + +There is another problem to this, it is observed that the packets +were sent on the DFS channel for a prolonged duration after radar +detection impacting the channel closing time. + +We can still invoke netif stop/wake APIs when wake_tx_queue is implemented +but this could lead to packet drops in network layer; adding stop/start +logic for software TXQs in mac80211 instead makes more sense; the change +proposed adds the same in mac80211. + +Signed-off-by: Manikanta Pubbisetty +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -1504,6 +1504,8 @@ enum ieee80211_vif_flags { + * @drv_priv: data area for driver use, will always be aligned to + * sizeof(void \*). + * @txq: the multicast data TX queue (if driver uses the TXQ abstraction) ++ * @txqs_stopped: per AC flag to indicate that intermediate TXQs are stopped, ++ * protected by fq->lock. + */ + struct ieee80211_vif { + enum nl80211_iftype type; +@@ -1528,6 +1530,8 @@ struct ieee80211_vif { + + unsigned int probe_req_reg; + ++ bool txqs_stopped[IEEE80211_NUM_ACS]; ++ + /* must be last */ + u8 drv_priv[0] __aligned(sizeof(void *)); + }; +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -818,6 +818,7 @@ enum txq_info_flags { + IEEE80211_TXQ_STOP, + IEEE80211_TXQ_AMPDU, + IEEE80211_TXQ_NO_AMSDU, ++ IEEE80211_TXQ_STOP_NETIF_TX, + }; + + /** +@@ -1226,6 +1227,7 @@ struct ieee80211_local { + + struct sk_buff_head pending[IEEE80211_MAX_QUEUES]; + struct tasklet_struct tx_pending_tasklet; ++ struct tasklet_struct wake_txqs_tasklet; + + atomic_t agg_queue_stop[IEEE80211_MAX_QUEUES]; + +@@ -2039,6 +2041,7 @@ void ieee80211_txq_remove_vlan(struct ie + struct ieee80211_sub_if_data *sdata); + void ieee80211_fill_txq_stats(struct cfg80211_txq_stats *txqstats, + struct txq_info *txqi); ++void ieee80211_wake_txqs(unsigned long data); + void ieee80211_send_auth(struct ieee80211_sub_if_data *sdata, + u16 transaction, u16 auth_alg, u16 status, + const u8 *extra, size_t extra_len, const u8 *bssid, +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -686,6 +686,10 @@ struct ieee80211_hw *ieee80211_alloc_hw_ + tasklet_init(&local->tx_pending_tasklet, ieee80211_tx_pending, + (unsigned long)local); + ++ if (ops->wake_tx_queue) ++ tasklet_init(&local->wake_txqs_tasklet, ieee80211_wake_txqs, ++ (unsigned long)local); ++ + tasklet_init(&local->tasklet, + ieee80211_tasklet_handler, + (unsigned long) local); +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3482,13 +3482,19 @@ struct sk_buff *ieee80211_tx_dequeue(str + struct ieee80211_tx_info *info; + struct ieee80211_tx_data tx; + ieee80211_tx_result r; +- struct ieee80211_vif *vif; ++ struct ieee80211_vif *vif = txq->vif; + + spin_lock_bh(&fq->lock); + +- if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags)) ++ if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) || ++ test_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags)) + goto out; + ++ if (vif->txqs_stopped[ieee80211_ac_from_tid(txq->tid)]) { ++ set_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags); ++ goto out; ++ } ++ + /* Make sure fragments stay together. */ + skb = __skb_dequeue(&txqi->frags); + if (skb) +@@ -3583,6 +3589,7 @@ begin: + } + + IEEE80211_SKB_CB(skb)->control.vif = vif; ++ + out: + spin_unlock_bh(&fq->lock); + +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -240,6 +240,99 @@ __le16 ieee80211_ctstoself_duration(stru + } + EXPORT_SYMBOL(ieee80211_ctstoself_duration); + ++static void __ieee80211_wake_txqs(struct ieee80211_sub_if_data *sdata, int ac) ++{ ++ struct ieee80211_local *local = sdata->local; ++ struct ieee80211_vif *vif = &sdata->vif; ++ struct fq *fq = &local->fq; ++ struct ps_data *ps = NULL; ++ struct txq_info *txqi; ++ struct sta_info *sta; ++ int i; ++ ++ spin_lock_bh(&fq->lock); ++ ++ if (sdata->vif.type == NL80211_IFTYPE_AP) ++ ps = &sdata->bss->ps; ++ ++ sdata->vif.txqs_stopped[ac] = false; ++ ++ list_for_each_entry_rcu(sta, &local->sta_list, list) { ++ if (sdata != sta->sdata) ++ continue; ++ ++ for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { ++ struct ieee80211_txq *txq = sta->sta.txq[i]; ++ ++ txqi = to_txq_info(txq); ++ ++ if (ac != txq->ac) ++ continue; ++ ++ if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, ++ &txqi->flags)) ++ continue; ++ ++ spin_unlock_bh(&fq->lock); ++ drv_wake_tx_queue(local, txqi); ++ spin_lock_bh(&fq->lock); ++ } ++ } ++ ++ if (!vif->txq) ++ goto out; ++ ++ txqi = to_txq_info(vif->txq); ++ ++ if (!test_and_clear_bit(IEEE80211_TXQ_STOP_NETIF_TX, &txqi->flags) || ++ (ps && atomic_read(&ps->num_sta_ps)) || ac != vif->txq->ac) ++ goto out; ++ ++ spin_unlock_bh(&fq->lock); ++ ++ drv_wake_tx_queue(local, txqi); ++ return; ++out: ++ spin_unlock_bh(&fq->lock); ++} ++ ++void ieee80211_wake_txqs(unsigned long data) ++{ ++ struct ieee80211_local *local = (struct ieee80211_local *)data; ++ struct ieee80211_sub_if_data *sdata; ++ int n_acs = IEEE80211_NUM_ACS; ++ unsigned long flags; ++ int i; ++ ++ rcu_read_lock(); ++ spin_lock_irqsave(&local->queue_stop_reason_lock, flags); ++ ++ if (local->hw.queues < IEEE80211_NUM_ACS) ++ n_acs = 1; ++ ++ for (i = 0; i < local->hw.queues; i++) { ++ if (local->queue_stop_reasons[i]) ++ continue; ++ ++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); ++ list_for_each_entry_rcu(sdata, &local->interfaces, list) { ++ int ac; ++ ++ for (ac = 0; ac < n_acs; ac++) { ++ int ac_queue = sdata->vif.hw_queue[ac]; ++ ++ if (ac_queue == i || ++ sdata->vif.cab_queue == i) ++ __ieee80211_wake_txqs(sdata, ac); ++ } ++ } ++ spin_lock_irqsave(&local->queue_stop_reason_lock, flags); ++ } ++ ++ spin_unlock_irqrestore(&local->queue_stop_reason_lock, flags); ++ rcu_read_unlock(); ++} ++ + void ieee80211_propagate_queue_wake(struct ieee80211_local *local, int queue) + { + struct ieee80211_sub_if_data *sdata; +@@ -308,6 +401,9 @@ static void __ieee80211_wake_queue(struc + rcu_read_unlock(); + } else + tasklet_schedule(&local->tx_pending_tasklet); ++ ++ if (local->ops->wake_tx_queue) ++ tasklet_schedule(&local->wake_txqs_tasklet); + } + + void ieee80211_wake_queue_by_reason(struct ieee80211_hw *hw, int queue, +@@ -351,9 +447,6 @@ static void __ieee80211_stop_queue(struc + if (__test_and_set_bit(reason, &local->queue_stop_reasons[queue])) + return; + +- if (local->ops->wake_tx_queue) +- return; +- + if (local->hw.queues < IEEE80211_NUM_ACS) + n_acs = 1; + +@@ -366,8 +459,15 @@ static void __ieee80211_stop_queue(struc + + for (ac = 0; ac < n_acs; ac++) { + if (sdata->vif.hw_queue[ac] == queue || +- sdata->vif.cab_queue == queue) +- netif_stop_subqueue(sdata->dev, ac); ++ sdata->vif.cab_queue == queue) { ++ if (!local->ops->wake_tx_queue) { ++ netif_stop_subqueue(sdata->dev, ac); ++ continue; ++ } ++ spin_lock(&local->fq.lock); ++ sdata->vif.txqs_stopped[ac] = true; ++ spin_unlock(&local->fq.lock); ++ } + } + } + rcu_read_unlock(); diff --git a/package/kernel/mac80211/patches/subsys/301-mac80211-do-not-call-driver-wake_tx_queue-op-during-.patch b/package/kernel/mac80211/patches/subsys/301-mac80211-do-not-call-driver-wake_tx_queue-op-during-.patch new file mode 100644 index 0000000000..5bbf4db23b --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/301-mac80211-do-not-call-driver-wake_tx_queue-op-during-.patch @@ -0,0 +1,33 @@ +From: Felix Fietkau +Date: Fri, 1 Mar 2019 14:42:56 +0100 +Subject: [PATCH] mac80211: do not call driver wake_tx_queue op during reconfig + +There are several scenarios in which mac80211 can call drv_wake_tx_queue +after ieee80211_restart_hw has been called and has not yet completed. +Driver private structs are considered uninitialized until mac80211 has +uploaded the vifs, stations and keys again, so using private tx queue +data during that time is not safe. + +The driver can also not rely on drv_reconfig_complete to figure out when +it is safe to accept drv_wake_tx_queue calls again, because it is only +called after all tx queues are woken again. + +To fix this, bail out early in drv_wake_tx_queue if local->in_reconfig +is set. + +Cc: stable@vger.kernel.org +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -1166,6 +1166,9 @@ static inline void drv_wake_tx_queue(str + { + struct ieee80211_sub_if_data *sdata = vif_to_sdata(txq->txq.vif); + ++ if (local->in_reconfig) ++ return; ++ + if (!check_sdata_in_driver(sdata)) + return; + diff --git a/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch new file mode 100644 index 0000000000..661fb46ea4 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/303-mac80211-minstrel-Enable-STBC-and-LDPC-for-VHT-Rates.patch @@ -0,0 +1,82 @@ +From: Chaitanya T K +Date: Mon, 27 Jun 2016 15:23:26 +0530 +Subject: [PATCH] mac80211: minstrel: Enable STBC and LDPC for VHT Rates + +If peer support reception of STBC and LDPC, enable them for better +performance. + +Signed-off-by: Chaitanya TK +--- + +--- a/include/linux/ieee80211.h ++++ b/include/linux/ieee80211.h +@@ -1659,6 +1659,7 @@ struct ieee80211_mu_edca_param_set { + #define IEEE80211_VHT_CAP_RXSTBC_3 0x00000300 + #define IEEE80211_VHT_CAP_RXSTBC_4 0x00000400 + #define IEEE80211_VHT_CAP_RXSTBC_MASK 0x00000700 ++#define IEEE80211_VHT_CAP_RXSTBC_SHIFT 8 + #define IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE 0x00000800 + #define IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE 0x00001000 + #define IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT 13 +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1130,7 +1130,7 @@ minstrel_ht_update_caps(void *priv, stru + struct minstrel_ht_sta_priv *msp = priv_sta; + struct minstrel_ht_sta *mi = &msp->ht; + struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; +- u16 sta_cap = sta->ht_cap.cap; ++ u16 ht_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; + struct sta_info *sinfo = container_of(sta, struct sta_info, sta); + int use_vht; +@@ -1138,6 +1138,7 @@ minstrel_ht_update_caps(void *priv, stru + int ack_dur; + int stbc; + int i; ++ bool ldpc = false; + + /* fall back to the old minstrel for legacy stations */ + if (!sta->ht_cap.ht_supported) +@@ -1175,16 +1176,24 @@ minstrel_ht_update_caps(void *priv, stru + } + mi->sample_tries = 4; + +- /* TODO tx_flags for vht - ATM the RC API is not fine-grained enough */ + if (!use_vht) { +- stbc = (sta_cap & IEEE80211_HT_CAP_RX_STBC) >> ++ stbc = (ht_cap & IEEE80211_HT_CAP_RX_STBC) >> + IEEE80211_HT_CAP_RX_STBC_SHIFT; +- mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; + +- if (sta_cap & IEEE80211_HT_CAP_LDPC_CODING) +- mi->tx_flags |= IEEE80211_TX_CTL_LDPC; ++ if (ht_cap & IEEE80211_HT_CAP_LDPC_CODING) ++ ldpc = true; ++ } else { ++ stbc = (vht_cap->cap & IEEE80211_VHT_CAP_RXSTBC_MASK) >> ++ IEEE80211_VHT_CAP_RXSTBC_SHIFT; ++ ++ if (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC) ++ ldpc = true; + } + ++ mi->tx_flags |= stbc << IEEE80211_TX_CTL_STBC_SHIFT; ++ if (ldpc) ++ mi->tx_flags |= IEEE80211_TX_CTL_LDPC; ++ + for (i = 0; i < ARRAY_SIZE(mi->groups); i++) { + u32 gflags = minstrel_mcs_groups[i].flags; + int bw, nss; +@@ -1197,10 +1206,10 @@ minstrel_ht_update_caps(void *priv, stru + + if (gflags & IEEE80211_TX_RC_SHORT_GI) { + if (gflags & IEEE80211_TX_RC_40_MHZ_WIDTH) { +- if (!(sta_cap & IEEE80211_HT_CAP_SGI_40)) ++ if (!(ht_cap & IEEE80211_HT_CAP_SGI_40)) + continue; + } else { +- if (!(sta_cap & IEEE80211_HT_CAP_SGI_20)) ++ if (!(ht_cap & IEEE80211_HT_CAP_SGI_20)) + continue; + } + } diff --git a/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch new file mode 100644 index 0000000000..95d4f294aa --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/304-mac80211-minstrel-remove-unnecessary-debugfs-cleanup.patch @@ -0,0 +1,150 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 12:41:51 +0100 +Subject: [PATCH] mac80211: minstrel: remove unnecessary debugfs cleanup + code + +debugfs entries are cleaned up by debugfs_remove_recursive already. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel.c ++++ b/net/mac80211/rc80211_minstrel.c +@@ -689,8 +689,8 @@ minstrel_alloc(struct ieee80211_hw *hw, + + #ifdef CPTCFG_MAC80211_DEBUGFS + mp->fixed_rate_idx = (u32) -1; +- mp->dbg_fixed_rate = debugfs_create_u32("fixed_rate_idx", +- 0666, debugfsdir, &mp->fixed_rate_idx); ++ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, ++ &mp->fixed_rate_idx); + #endif + + minstrel_init_cck_rates(mp); +@@ -701,9 +701,6 @@ minstrel_alloc(struct ieee80211_hw *hw, + static void + minstrel_free(void *priv) + { +-#ifdef CPTCFG_MAC80211_DEBUGFS +- debugfs_remove(((struct minstrel_priv *)priv)->dbg_fixed_rate); +-#endif + kfree(priv); + } + +@@ -735,7 +732,6 @@ const struct rate_control_ops mac80211_m + .free_sta = minstrel_free_sta, + #ifdef CPTCFG_MAC80211_DEBUGFS + .add_sta_debugfs = minstrel_add_sta_debugfs, +- .remove_sta_debugfs = minstrel_remove_sta_debugfs, + #endif + .get_expected_throughput = minstrel_get_expected_throughput, + }; +--- a/net/mac80211/rc80211_minstrel.h ++++ b/net/mac80211/rc80211_minstrel.h +@@ -109,11 +109,6 @@ struct minstrel_sta_info { + + /* sampling table */ + u8 *sample_table; +- +-#ifdef CPTCFG_MAC80211_DEBUGFS +- struct dentry *dbg_stats; +- struct dentry *dbg_stats_csv; +-#endif + }; + + struct minstrel_priv { +@@ -137,7 +132,6 @@ struct minstrel_priv { + * - setting will be applied on next update + */ + u32 fixed_rate_idx; +- struct dentry *dbg_fixed_rate; + #endif + }; + +@@ -156,7 +150,6 @@ minstrel_get_ewmsd10(struct minstrel_rat + + extern const struct rate_control_ops mac80211_minstrel; + void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +-void minstrel_remove_sta_debugfs(void *priv, void *priv_sta); + + /* Recalculate success probabilities and counters for a given rate using EWMA */ + void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs); +--- a/net/mac80211/rc80211_minstrel_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_debugfs.c +@@ -214,19 +214,7 @@ minstrel_add_sta_debugfs(void *priv, voi + { + struct minstrel_sta_info *mi = priv_sta; + +- mi->dbg_stats = debugfs_create_file("rc_stats", 0444, dir, mi, +- &minstrel_stat_fops); +- +- mi->dbg_stats_csv = debugfs_create_file("rc_stats_csv", 0444, dir, mi, +- &minstrel_stat_csv_fops); +-} +- +-void +-minstrel_remove_sta_debugfs(void *priv, void *priv_sta) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- +- debugfs_remove(mi->dbg_stats); +- +- debugfs_remove(mi->dbg_stats_csv); ++ debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops); ++ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi, ++ &minstrel_stat_csv_fops); + } +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1393,7 +1393,6 @@ static const struct rate_control_ops mac + .free = minstrel_ht_free, + #ifdef CPTCFG_MAC80211_DEBUGFS + .add_sta_debugfs = minstrel_ht_add_sta_debugfs, +- .remove_sta_debugfs = minstrel_ht_remove_sta_debugfs, + #endif + .get_expected_throughput = minstrel_ht_get_expected_throughput, + }; +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -110,17 +110,12 @@ struct minstrel_ht_sta_priv { + struct minstrel_ht_sta ht; + struct minstrel_sta_info legacy; + }; +-#ifdef CPTCFG_MAC80211_DEBUGFS +- struct dentry *dbg_stats; +- struct dentry *dbg_stats_csv; +-#endif + void *ratelist; + void *sample_table; + bool is_ht; + }; + + void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); +-void minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta); + int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, + int prob_ewma); + +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -303,17 +303,8 @@ minstrel_ht_add_sta_debugfs(void *priv, + { + struct minstrel_ht_sta_priv *msp = priv_sta; + +- msp->dbg_stats = debugfs_create_file("rc_stats", 0444, dir, msp, +- &minstrel_ht_stat_fops); +- msp->dbg_stats_csv = debugfs_create_file("rc_stats_csv", 0444, dir, msp, +- &minstrel_ht_stat_csv_fops); +-} +- +-void +-minstrel_ht_remove_sta_debugfs(void *priv, void *priv_sta) +-{ +- struct minstrel_ht_sta_priv *msp = priv_sta; +- +- debugfs_remove(msp->dbg_stats); +- debugfs_remove(msp->dbg_stats_csv); ++ debugfs_create_file("rc_stats", S_IRUGO, dir, msp, ++ &minstrel_ht_stat_fops); ++ debugfs_create_file("rc_stats_csv", S_IRUGO, dir, msp, ++ &minstrel_ht_stat_csv_fops); + } diff --git a/package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch b/package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch new file mode 100644 index 0000000000..9a233753ad --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/305-mac80211-minstrel-merge-with-minstrel_ht-always-enab.patch @@ -0,0 +1,575 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 12:43:30 +0100 +Subject: [PATCH] mac80211: minstrel: merge with minstrel_ht, always enable + VHT support + +Legacy-only devices are not very common and the overhead of the extra +code for HT and VHT rates is not big enough to justify all those extra +lines of code to make it optional. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/Kconfig ++++ b/net/mac80211/Kconfig +@@ -25,20 +25,6 @@ config MAC80211_RC_MINSTREL + ---help--- + This option enables the 'minstrel' TX rate control algorithm + +-config MAC80211_RC_MINSTREL_HT +- bool "Minstrel 802.11n support" if EXPERT +- depends on MAC80211_RC_MINSTREL +- default y +- ---help--- +- This option enables the 'minstrel_ht' TX rate control algorithm +- +-config MAC80211_RC_MINSTREL_VHT +- bool "Minstrel 802.11ac support" if EXPERT +- depends on MAC80211_RC_MINSTREL_HT +- default n +- ---help--- +- This option enables VHT in the 'minstrel_ht' TX rate control algorithm +- + choice + prompt "Default rate control algorithm" + depends on MAC80211_HAS_RC +@@ -60,8 +46,7 @@ endchoice + + config MAC80211_RC_DEFAULT + string +- default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL && MAC80211_RC_MINSTREL_HT +- default "minstrel" if MAC80211_RC_DEFAULT_MINSTREL ++ default "minstrel_ht" if MAC80211_RC_DEFAULT_MINSTREL + default "" + + endif +--- a/net/mac80211/Makefile ++++ b/net/mac80211/Makefile +@@ -52,13 +52,14 @@ mac80211-$(CONFIG_PM) += pm.o + + CFLAGS_trace.o := -I$(src) + +-rc80211_minstrel-y := rc80211_minstrel.o +-rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_debugfs.o ++rc80211_minstrel-y := \ ++ rc80211_minstrel.o \ ++ rc80211_minstrel_ht.o + +-rc80211_minstrel_ht-y := rc80211_minstrel_ht.o +-rc80211_minstrel_ht-$(CPTCFG_MAC80211_DEBUGFS) += rc80211_minstrel_ht_debugfs.o ++rc80211_minstrel-$(CPTCFG_MAC80211_DEBUGFS) += \ ++ rc80211_minstrel_debugfs.o \ ++ rc80211_minstrel_ht_debugfs.o + + mac80211-$(CPTCFG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y) +-mac80211-$(CPTCFG_MAC80211_RC_MINSTREL_HT) += $(rc80211_minstrel_ht-y) + + ccflags-y += -DDEBUG +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -1308,18 +1308,12 @@ static int __init ieee80211_init(void) + if (ret) + return ret; + +- ret = rc80211_minstrel_ht_init(); +- if (ret) +- goto err_minstrel; +- + ret = ieee80211_iface_init(); + if (ret) + goto err_netdev; + + return 0; + err_netdev: +- rc80211_minstrel_ht_exit(); +- err_minstrel: + rc80211_minstrel_exit(); + + return ret; +@@ -1327,7 +1321,6 @@ static int __init ieee80211_init(void) + + static void __exit ieee80211_exit(void) + { +- rc80211_minstrel_ht_exit(); + rc80211_minstrel_exit(); + + ieee80211s_stop(); +--- a/net/mac80211/rate.h ++++ b/net/mac80211/rate.h +@@ -95,18 +95,5 @@ static inline void rc80211_minstrel_exit + } + #endif + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_HT +-int rc80211_minstrel_ht_init(void); +-void rc80211_minstrel_ht_exit(void); +-#else +-static inline int rc80211_minstrel_ht_init(void) +-{ +- return 0; +-} +-static inline void rc80211_minstrel_ht_exit(void) +-{ +-} +-#endif +- + + #endif /* IEEE80211_RATE_H */ +--- a/net/mac80211/rc80211_minstrel.c ++++ b/net/mac80211/rc80211_minstrel.c +@@ -572,138 +572,6 @@ minstrel_rate_init(void *priv, struct ie + minstrel_update_rates(mp, mi); + } + +-static void * +-minstrel_alloc_sta(void *priv, struct ieee80211_sta *sta, gfp_t gfp) +-{ +- struct ieee80211_supported_band *sband; +- struct minstrel_sta_info *mi; +- struct minstrel_priv *mp = priv; +- struct ieee80211_hw *hw = mp->hw; +- int max_rates = 0; +- int i; +- +- mi = kzalloc(sizeof(struct minstrel_sta_info), gfp); +- if (!mi) +- return NULL; +- +- for (i = 0; i < NUM_NL80211_BANDS; i++) { +- sband = hw->wiphy->bands[i]; +- if (sband && sband->n_bitrates > max_rates) +- max_rates = sband->n_bitrates; +- } +- +- mi->r = kcalloc(max_rates, sizeof(struct minstrel_rate), gfp); +- if (!mi->r) +- goto error; +- +- mi->sample_table = kmalloc_array(max_rates, SAMPLE_COLUMNS, gfp); +- if (!mi->sample_table) +- goto error1; +- +- mi->last_stats_update = jiffies; +- return mi; +- +-error1: +- kfree(mi->r); +-error: +- kfree(mi); +- return NULL; +-} +- +-static void +-minstrel_free_sta(void *priv, struct ieee80211_sta *sta, void *priv_sta) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- +- kfree(mi->sample_table); +- kfree(mi->r); +- kfree(mi); +-} +- +-static void +-minstrel_init_cck_rates(struct minstrel_priv *mp) +-{ +- static const int bitrates[4] = { 10, 20, 55, 110 }; +- struct ieee80211_supported_band *sband; +- u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); +- int i, j; +- +- sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; +- if (!sband) +- return; +- +- for (i = 0, j = 0; i < sband->n_bitrates; i++) { +- struct ieee80211_rate *rate = &sband->bitrates[i]; +- +- if (rate->flags & IEEE80211_RATE_ERP_G) +- continue; +- +- if ((rate_flags & sband->bitrates[i].flags) != rate_flags) +- continue; +- +- for (j = 0; j < ARRAY_SIZE(bitrates); j++) { +- if (rate->bitrate != bitrates[j]) +- continue; +- +- mp->cck_rates[j] = i; +- break; +- } +- } +-} +- +-static void * +-minstrel_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) +-{ +- struct minstrel_priv *mp; +- +- mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); +- if (!mp) +- return NULL; +- +- /* contention window settings +- * Just an approximation. Using the per-queue values would complicate +- * the calculations and is probably unnecessary */ +- mp->cw_min = 15; +- mp->cw_max = 1023; +- +- /* number of packets (in %) to use for sampling other rates +- * sample less often for non-mrr packets, because the overhead +- * is much higher than with mrr */ +- mp->lookaround_rate = 5; +- mp->lookaround_rate_mrr = 10; +- +- /* maximum time that the hw is allowed to stay in one MRR segment */ +- mp->segment_size = 6000; +- +- if (hw->max_rate_tries > 0) +- mp->max_retry = hw->max_rate_tries; +- else +- /* safe default, does not necessarily have to match hw properties */ +- mp->max_retry = 7; +- +- if (hw->max_rates >= 4) +- mp->has_mrr = true; +- +- mp->hw = hw; +- mp->update_interval = 100; +- +-#ifdef CPTCFG_MAC80211_DEBUGFS +- mp->fixed_rate_idx = (u32) -1; +- debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, +- &mp->fixed_rate_idx); +-#endif +- +- minstrel_init_cck_rates(mp); +- +- return mp; +-} +- +-static void +-minstrel_free(void *priv) +-{ +- kfree(priv); +-} +- + static u32 minstrel_get_expected_throughput(void *priv_sta) + { + struct minstrel_sta_info *mi = priv_sta; +@@ -722,28 +590,8 @@ static u32 minstrel_get_expected_through + } + + const struct rate_control_ops mac80211_minstrel = { +- .name = "minstrel", + .tx_status_ext = minstrel_tx_status, + .get_rate = minstrel_get_rate, + .rate_init = minstrel_rate_init, +- .alloc = minstrel_alloc, +- .free = minstrel_free, +- .alloc_sta = minstrel_alloc_sta, +- .free_sta = minstrel_free_sta, +-#ifdef CPTCFG_MAC80211_DEBUGFS +- .add_sta_debugfs = minstrel_add_sta_debugfs, +-#endif + .get_expected_throughput = minstrel_get_expected_throughput, + }; +- +-int __init +-rc80211_minstrel_init(void) +-{ +- return ieee80211_rate_control_register(&mac80211_minstrel); +-} +- +-void +-rc80211_minstrel_exit(void) +-{ +- ieee80211_rate_control_unregister(&mac80211_minstrel); +-} +--- a/net/mac80211/rc80211_minstrel.h ++++ b/net/mac80211/rc80211_minstrel.h +@@ -158,7 +158,5 @@ int minstrel_get_tp_avg(struct minstrel_ + /* debugfs */ + int minstrel_stats_open(struct inode *inode, struct file *file); + int minstrel_stats_csv_open(struct inode *inode, struct file *file); +-ssize_t minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos); +-int minstrel_stats_release(struct inode *inode, struct file *file); + + #endif +--- a/net/mac80211/rc80211_minstrel_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_debugfs.c +@@ -54,22 +54,6 @@ + #include + #include "rc80211_minstrel.h" + +-ssize_t +-minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) +-{ +- struct minstrel_debugfs_info *ms; +- +- ms = file->private_data; +- return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len); +-} +- +-int +-minstrel_stats_release(struct inode *inode, struct file *file) +-{ +- kfree(file->private_data); +- return 0; +-} +- + int + minstrel_stats_open(struct inode *inode, struct file *file) + { +@@ -135,14 +119,6 @@ minstrel_stats_open(struct inode *inode, + return 0; + } + +-static const struct file_operations minstrel_stat_fops = { +- .owner = THIS_MODULE, +- .open = minstrel_stats_open, +- .read = minstrel_stats_read, +- .release = minstrel_stats_release, +- .llseek = default_llseek, +-}; +- + int + minstrel_stats_csv_open(struct inode *inode, struct file *file) + { +@@ -200,21 +176,3 @@ minstrel_stats_csv_open(struct inode *in + + return 0; + } +- +-static const struct file_operations minstrel_stat_csv_fops = { +- .owner = THIS_MODULE, +- .open = minstrel_stats_csv_open, +- .read = minstrel_stats_read, +- .release = minstrel_stats_release, +- .llseek = default_llseek, +-}; +- +-void +-minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir) +-{ +- struct minstrel_sta_info *mi = priv_sta; +- +- debugfs_create_file("rc_stats", S_IRUGO, dir, mi, &minstrel_stat_fops); +- debugfs_create_file("rc_stats_csv", S_IRUGO, dir, mi, +- &minstrel_stat_csv_fops); +-} +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -137,12 +137,10 @@ + } \ + } + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + static bool minstrel_vht_only = true; + module_param(minstrel_vht_only, bool, 0644); + MODULE_PARM_DESC(minstrel_vht_only, + "Use only VHT rates when VHT is supported by sta."); +-#endif + + /* + * To enable sufficiently targeted rate sampling, MCS rates are divided into +@@ -171,7 +169,6 @@ const struct mcs_group minstrel_mcs_grou + + CCK_GROUP, + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + VHT_GROUP(1, 0, BW_20), + VHT_GROUP(2, 0, BW_20), + VHT_GROUP(3, 0, BW_20), +@@ -195,7 +192,6 @@ const struct mcs_group minstrel_mcs_grou + VHT_GROUP(1, 1, BW_80), + VHT_GROUP(2, 1, BW_80), + VHT_GROUP(3, 1, BW_80), +-#endif + }; + + static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; +@@ -1146,12 +1142,10 @@ minstrel_ht_update_caps(void *priv, stru + + BUILD_BUG_ON(ARRAY_SIZE(minstrel_mcs_groups) != MINSTREL_GROUPS_NB); + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + if (vht_cap->vht_supported) + use_vht = vht_cap->vht_mcs.tx_mcs_map != cpu_to_le16(~0); + else +-#endif +- use_vht = 0; ++ use_vht = 0; + + msp->is_ht = true; + memset(mi, 0, sizeof(*mi)); +@@ -1226,10 +1220,9 @@ minstrel_ht_update_caps(void *priv, stru + + /* HT rate */ + if (gflags & IEEE80211_TX_RC_MCS) { +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + if (use_vht && minstrel_vht_only) + continue; +-#endif ++ + mi->supported[i] = mcs->rx_mask[nss - 1]; + if (mi->supported[i]) + n_supported++; +@@ -1349,16 +1342,88 @@ minstrel_ht_free_sta(void *priv, struct + kfree(msp); + } + ++static void ++minstrel_ht_init_cck_rates(struct minstrel_priv *mp) ++{ ++ static const int bitrates[4] = { 10, 20, 55, 110 }; ++ struct ieee80211_supported_band *sband; ++ u32 rate_flags = ieee80211_chandef_rate_flags(&mp->hw->conf.chandef); ++ int i, j; ++ ++ sband = mp->hw->wiphy->bands[NL80211_BAND_2GHZ]; ++ if (!sband) ++ return; ++ ++ for (i = 0, j = 0; i < sband->n_bitrates; i++) { ++ struct ieee80211_rate *rate = &sband->bitrates[i]; ++ ++ if (rate->flags & IEEE80211_RATE_ERP_G) ++ continue; ++ ++ if ((rate_flags & sband->bitrates[i].flags) != rate_flags) ++ continue; ++ ++ for (j = 0; j < ARRAY_SIZE(bitrates); j++) { ++ if (rate->bitrate != bitrates[j]) ++ continue; ++ ++ mp->cck_rates[j] = i; ++ break; ++ } ++ } ++} ++ + static void * + minstrel_ht_alloc(struct ieee80211_hw *hw, struct dentry *debugfsdir) + { +- return mac80211_minstrel.alloc(hw, debugfsdir); ++ struct minstrel_priv *mp; ++ ++ mp = kzalloc(sizeof(struct minstrel_priv), GFP_ATOMIC); ++ if (!mp) ++ return NULL; ++ ++ /* contention window settings ++ * Just an approximation. Using the per-queue values would complicate ++ * the calculations and is probably unnecessary */ ++ mp->cw_min = 15; ++ mp->cw_max = 1023; ++ ++ /* number of packets (in %) to use for sampling other rates ++ * sample less often for non-mrr packets, because the overhead ++ * is much higher than with mrr */ ++ mp->lookaround_rate = 5; ++ mp->lookaround_rate_mrr = 10; ++ ++ /* maximum time that the hw is allowed to stay in one MRR segment */ ++ mp->segment_size = 6000; ++ ++ if (hw->max_rate_tries > 0) ++ mp->max_retry = hw->max_rate_tries; ++ else ++ /* safe default, does not necessarily have to match hw properties */ ++ mp->max_retry = 7; ++ ++ if (hw->max_rates >= 4) ++ mp->has_mrr = true; ++ ++ mp->hw = hw; ++ mp->update_interval = 100; ++ ++#ifdef CPTCFG_MAC80211_DEBUGFS ++ mp->fixed_rate_idx = (u32) -1; ++ debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, ++ &mp->fixed_rate_idx); ++#endif ++ ++ minstrel_ht_init_cck_rates(mp); ++ ++ return mp; + } + + static void + minstrel_ht_free(void *priv) + { +- mac80211_minstrel.free(priv); ++ kfree(priv); + } + + static u32 minstrel_ht_get_expected_throughput(void *priv_sta) +@@ -1417,14 +1482,14 @@ static void __init init_sample_table(voi + } + + int __init +-rc80211_minstrel_ht_init(void) ++rc80211_minstrel_init(void) + { + init_sample_table(); + return ieee80211_rate_control_register(&mac80211_minstrel_ht); + } + + void +-rc80211_minstrel_ht_exit(void) ++rc80211_minstrel_exit(void) + { + ieee80211_rate_control_unregister(&mac80211_minstrel_ht); + } +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -15,11 +15,7 @@ + */ + #define MINSTREL_MAX_STREAMS 3 + #define MINSTREL_HT_STREAM_GROUPS 4 /* BW(=2) * SGI(=2) */ +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + #define MINSTREL_VHT_STREAM_GROUPS 6 /* BW(=3) * SGI(=2) */ +-#else +-#define MINSTREL_VHT_STREAM_GROUPS 0 +-#endif + + #define MINSTREL_HT_GROUPS_NB (MINSTREL_MAX_STREAMS * \ + MINSTREL_HT_STREAM_GROUPS) +@@ -34,11 +30,7 @@ + #define MINSTREL_CCK_GROUP (MINSTREL_HT_GROUP_0 + MINSTREL_HT_GROUPS_NB) + #define MINSTREL_VHT_GROUP_0 (MINSTREL_CCK_GROUP + 1) + +-#ifdef CPTCFG_MAC80211_RC_MINSTREL_VHT + #define MCS_GROUP_RATES 10 +-#else +-#define MCS_GROUP_RATES 8 +-#endif + + struct mcs_group { + u32 flags; +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -15,6 +15,22 @@ + #include "rc80211_minstrel.h" + #include "rc80211_minstrel_ht.h" + ++static ssize_t ++minstrel_stats_read(struct file *file, char __user *buf, size_t len, loff_t *ppos) ++{ ++ struct minstrel_debugfs_info *ms; ++ ++ ms = file->private_data; ++ return simple_read_from_buffer(buf, len, ppos, ms->buf, ms->len); ++} ++ ++static int ++minstrel_stats_release(struct inode *inode, struct file *file) ++{ ++ kfree(file->private_data); ++ return 0; ++} ++ + static char * + minstrel_ht_stats_dump(struct minstrel_ht_sta *mi, int i, char *p) + { diff --git a/package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch b/package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch new file mode 100644 index 0000000000..02a0ca0a52 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/306-mac80211-minstrel-reduce-minstrel_mcs_groups-size.patch @@ -0,0 +1,368 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 12:45:47 +0100 +Subject: [PATCH] mac80211: minstrel: reduce minstrel_mcs_groups size + +By storing a shift value for all duration values of a group, we can +reduce precision by a neglegible amount to make it fit into a u16 value. +This improves cache footprint and reduces size: + +Before: + text data bss dec hex filename + 10024 116 0 10140 279c rc80211_minstrel_ht.o + +After: + text data bss dec hex filename + 9368 116 0 9484 250c rc80211_minstrel_ht.o + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -52,22 +52,23 @@ + _streams - 1 + + /* MCS rate information for an MCS group */ +-#define MCS_GROUP(_streams, _sgi, _ht40) \ ++#define MCS_GROUP(_streams, _sgi, _ht40, _s) \ + [GROUP_IDX(_streams, _sgi, _ht40)] = { \ + .streams = _streams, \ ++ .shift = _s, \ + .flags = \ + IEEE80211_TX_RC_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ + (_ht40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ + .duration = { \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234), \ +- MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 54 : 26) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 108 : 52) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 162 : 78) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 216 : 104) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 324 : 156) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 432 : 208) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 486 : 234) >> _s, \ ++ MCS_DURATION(_streams, _sgi, _ht40 ? 540 : 260) >> _s \ + } \ + } + +@@ -80,9 +81,10 @@ + #define BW2VBPS(_bw, r3, r2, r1) \ + (_bw == BW_80 ? r3 : _bw == BW_40 ? r2 : r1) + +-#define VHT_GROUP(_streams, _sgi, _bw) \ ++#define VHT_GROUP(_streams, _sgi, _bw, _s) \ + [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ + .streams = _streams, \ ++ .shift = _s, \ + .flags = \ + IEEE80211_TX_RC_VHT_MCS | \ + (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ +@@ -90,25 +92,25 @@ + _bw == BW_40 ? IEEE80211_TX_RC_40_MHZ_WIDTH : 0), \ + .duration = { \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 117, 54, 26)), \ ++ BW2VBPS(_bw, 117, 54, 26)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 234, 108, 52)), \ ++ BW2VBPS(_bw, 234, 108, 52)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 351, 162, 78)), \ ++ BW2VBPS(_bw, 351, 162, 78)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 468, 216, 104)), \ ++ BW2VBPS(_bw, 468, 216, 104)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 702, 324, 156)), \ ++ BW2VBPS(_bw, 702, 324, 156)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 936, 432, 208)), \ ++ BW2VBPS(_bw, 936, 432, 208)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1053, 486, 234)), \ ++ BW2VBPS(_bw, 1053, 486, 234)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1170, 540, 260)), \ ++ BW2VBPS(_bw, 1170, 540, 260)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1404, 648, 312)), \ ++ BW2VBPS(_bw, 1404, 648, 312)) >> _s, \ + MCS_DURATION(_streams, _sgi, \ +- BW2VBPS(_bw, 1560, 720, 346)) \ ++ BW2VBPS(_bw, 1560, 720, 346)) >> _s \ + } \ + } + +@@ -121,19 +123,20 @@ + (CCK_DURATION((_bitrate > 10 ? 20 : 10), false, 60) + \ + CCK_DURATION(_bitrate, _short, AVG_PKT_SIZE)) + +-#define CCK_DURATION_LIST(_short) \ +- CCK_ACK_DURATION(10, _short), \ +- CCK_ACK_DURATION(20, _short), \ +- CCK_ACK_DURATION(55, _short), \ +- CCK_ACK_DURATION(110, _short) ++#define CCK_DURATION_LIST(_short, _s) \ ++ CCK_ACK_DURATION(10, _short) >> _s, \ ++ CCK_ACK_DURATION(20, _short) >> _s, \ ++ CCK_ACK_DURATION(55, _short) >> _s, \ ++ CCK_ACK_DURATION(110, _short) >> _s + +-#define CCK_GROUP \ ++#define CCK_GROUP(_s) \ + [MINSTREL_CCK_GROUP] = { \ + .streams = 0, \ + .flags = 0, \ ++ .shift = _s, \ + .duration = { \ +- CCK_DURATION_LIST(false), \ +- CCK_DURATION_LIST(true) \ ++ CCK_DURATION_LIST(false, _s), \ ++ CCK_DURATION_LIST(true, _s) \ + } \ + } + +@@ -151,47 +154,47 @@ MODULE_PARM_DESC(minstrel_vht_only, + * BW -> SGI -> #streams + */ + const struct mcs_group minstrel_mcs_groups[] = { +- MCS_GROUP(1, 0, BW_20), +- MCS_GROUP(2, 0, BW_20), +- MCS_GROUP(3, 0, BW_20), +- +- MCS_GROUP(1, 1, BW_20), +- MCS_GROUP(2, 1, BW_20), +- MCS_GROUP(3, 1, BW_20), +- +- MCS_GROUP(1, 0, BW_40), +- MCS_GROUP(2, 0, BW_40), +- MCS_GROUP(3, 0, BW_40), +- +- MCS_GROUP(1, 1, BW_40), +- MCS_GROUP(2, 1, BW_40), +- MCS_GROUP(3, 1, BW_40), +- +- CCK_GROUP, +- +- VHT_GROUP(1, 0, BW_20), +- VHT_GROUP(2, 0, BW_20), +- VHT_GROUP(3, 0, BW_20), +- +- VHT_GROUP(1, 1, BW_20), +- VHT_GROUP(2, 1, BW_20), +- VHT_GROUP(3, 1, BW_20), +- +- VHT_GROUP(1, 0, BW_40), +- VHT_GROUP(2, 0, BW_40), +- VHT_GROUP(3, 0, BW_40), +- +- VHT_GROUP(1, 1, BW_40), +- VHT_GROUP(2, 1, BW_40), +- VHT_GROUP(3, 1, BW_40), +- +- VHT_GROUP(1, 0, BW_80), +- VHT_GROUP(2, 0, BW_80), +- VHT_GROUP(3, 0, BW_80), +- +- VHT_GROUP(1, 1, BW_80), +- VHT_GROUP(2, 1, BW_80), +- VHT_GROUP(3, 1, BW_80), ++ MCS_GROUP(1, 0, BW_20, 5), ++ MCS_GROUP(2, 0, BW_20, 4), ++ MCS_GROUP(3, 0, BW_20, 4), ++ ++ MCS_GROUP(1, 1, BW_20, 5), ++ MCS_GROUP(2, 1, BW_20, 4), ++ MCS_GROUP(3, 1, BW_20, 4), ++ ++ MCS_GROUP(1, 0, BW_40, 4), ++ MCS_GROUP(2, 0, BW_40, 4), ++ MCS_GROUP(3, 0, BW_40, 4), ++ ++ MCS_GROUP(1, 1, BW_40, 4), ++ MCS_GROUP(2, 1, BW_40, 4), ++ MCS_GROUP(3, 1, BW_40, 4), ++ ++ CCK_GROUP(8), ++ ++ VHT_GROUP(1, 0, BW_20, 5), ++ VHT_GROUP(2, 0, BW_20, 4), ++ VHT_GROUP(3, 0, BW_20, 4), ++ ++ VHT_GROUP(1, 1, BW_20, 5), ++ VHT_GROUP(2, 1, BW_20, 4), ++ VHT_GROUP(3, 1, BW_20, 4), ++ ++ VHT_GROUP(1, 0, BW_40, 4), ++ VHT_GROUP(2, 0, BW_40, 4), ++ VHT_GROUP(3, 0, BW_40, 4), ++ ++ VHT_GROUP(1, 1, BW_40, 4), ++ VHT_GROUP(2, 1, BW_40, 4), ++ VHT_GROUP(3, 1, BW_40, 4), ++ ++ VHT_GROUP(1, 0, BW_80, 4), ++ VHT_GROUP(2, 0, BW_80, 4), ++ VHT_GROUP(3, 0, BW_80, 4), ++ ++ VHT_GROUP(1, 1, BW_80, 4), ++ VHT_GROUP(2, 1, BW_80, 4), ++ VHT_GROUP(3, 1, BW_80, 4), + }; + + static u8 sample_table[SAMPLE_COLUMNS][MCS_GROUP_RATES] __read_mostly; +@@ -307,7 +310,8 @@ minstrel_ht_get_tp_avg(struct minstrel_h + if (group != MINSTREL_CCK_GROUP) + nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); + +- nsecs += minstrel_mcs_groups[group].duration[rate]; ++ nsecs += minstrel_mcs_groups[group].duration[rate] << ++ minstrel_mcs_groups[group].shift; + + /* + * For the throughput calculation, limit the probability value to 90% to +@@ -755,12 +759,19 @@ minstrel_ht_tx_status(void *priv, struct + minstrel_ht_update_rates(mp, mi); + } + ++static inline int ++minstrel_get_duration(int index) ++{ ++ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; ++ unsigned int duration = group->duration[index % MCS_GROUP_RATES]; ++ return duration << group->shift; ++} ++ + static void + minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, + int index) + { + struct minstrel_rate_stats *mrs; +- const struct mcs_group *group; + unsigned int tx_time, tx_time_rtscts, tx_time_data; + unsigned int cw = mp->cw_min; + unsigned int ctime = 0; +@@ -779,8 +790,7 @@ minstrel_calc_retransmit(struct minstrel + mrs->retry_count_rtscts = 2; + mrs->retry_updated = true; + +- group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- tx_time_data = group->duration[index % MCS_GROUP_RATES] * ampdu_len / 1000; ++ tx_time_data = minstrel_get_duration(index) * ampdu_len / 1000; + + /* Contention time for first 2 tries */ + ctime = (t_slot * cw) >> 1; +@@ -874,20 +884,24 @@ minstrel_ht_get_max_amsdu_len(struct min + int group = mi->max_prob_rate / MCS_GROUP_RATES; + const struct mcs_group *g = &minstrel_mcs_groups[group]; + int rate = mi->max_prob_rate % MCS_GROUP_RATES; ++ unsigned int duration; + + /* Disable A-MSDU if max_prob_rate is bad */ + if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100)) + return 1; + ++ duration = g->duration[rate]; ++ duration <<= g->shift; ++ + /* If the rate is slower than single-stream MCS1, make A-MSDU limit small */ +- if (g->duration[rate] > MCS_DURATION(1, 0, 52)) ++ if (duration > MCS_DURATION(1, 0, 52)) + return 500; + + /* + * If the rate is slower than single-stream MCS4, limit A-MSDU to usual + * data packet size + */ +- if (g->duration[rate] > MCS_DURATION(1, 0, 104)) ++ if (duration > MCS_DURATION(1, 0, 104)) + return 1600; + + /* +@@ -895,7 +909,7 @@ minstrel_ht_get_max_amsdu_len(struct min + * rate success probability is less than 75%, limit A-MSDU to twice the usual + * data packet size + */ +- if (g->duration[rate] > MCS_DURATION(1, 0, 260) || ++ if (duration > MCS_DURATION(1, 0, 260) || + (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) < + MINSTREL_FRAC(75, 100))) + return 3200; +@@ -942,13 +956,6 @@ minstrel_ht_update_rates(struct minstrel + rate_control_set_rates(mp->hw, mi->sta, rates); + } + +-static inline int +-minstrel_get_duration(int index) +-{ +- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; +- return group->duration[index % MCS_GROUP_RATES]; +-} +- + static int + minstrel_get_sample_rate(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) + { +--- a/net/mac80211/rc80211_minstrel_ht.h ++++ b/net/mac80211/rc80211_minstrel_ht.h +@@ -33,9 +33,10 @@ + #define MCS_GROUP_RATES 10 + + struct mcs_group { +- u32 flags; +- unsigned int streams; +- unsigned int duration[MCS_GROUP_RATES]; ++ u16 flags; ++ u8 streams; ++ u8 shift; ++ u16 duration[MCS_GROUP_RATES]; + }; + + extern const struct mcs_group minstrel_mcs_groups[]; +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -58,6 +58,7 @@ minstrel_ht_stats_dump(struct minstrel_h + static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int prob_ewmsd; ++ unsigned int duration; + + if (!(mi->supported[i] & BIT(j))) + continue; +@@ -95,7 +96,9 @@ minstrel_ht_stats_dump(struct minstrel_h + p += sprintf(p, " %3u ", idx); + + /* tx_time[rate(i)] in usec */ +- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); ++ duration = mg->duration[j]; ++ duration <<= mg->shift; ++ tx_time = DIV_ROUND_CLOSEST(duration, 1000); + p += sprintf(p, "%6u ", tx_time); + + tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); +@@ -204,6 +207,7 @@ minstrel_ht_stats_csv_dump(struct minstr + static const int bitrates[4] = { 10, 20, 55, 110 }; + int idx = i * MCS_GROUP_RATES + j; + unsigned int prob_ewmsd; ++ unsigned int duration; + + if (!(mi->supported[i] & BIT(j))) + continue; +@@ -238,7 +242,10 @@ minstrel_ht_stats_csv_dump(struct minstr + } + + p += sprintf(p, "%u,", idx); +- tx_time = DIV_ROUND_CLOSEST(mg->duration[j], 1000); ++ ++ duration = mg->duration[j]; ++ duration <<= mg->shift; ++ tx_time = DIV_ROUND_CLOSEST(duration, 1000); + p += sprintf(p, "%u,", tx_time); + + tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); diff --git a/package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch b/package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch new file mode 100644 index 0000000000..502d8c7768 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/307-mac80211-minstrel-fix-using-short-preamble-CCK-rates.patch @@ -0,0 +1,31 @@ +From: Felix Fietkau +Date: Sat, 10 Feb 2018 13:43:07 +0100 +Subject: [PATCH] mac80211: minstrel: fix using short preamble CCK rates on + HT clients + +mi->supported[MINSTREL_CCK_GROUP] needs to be updated + +Fixes: 782dda00ab8e ("mac80211: minstrel_ht: move short preamble check out of get_rate") +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1135,7 +1135,6 @@ minstrel_ht_update_caps(void *priv, stru + struct ieee80211_mcs_info *mcs = &sta->ht_cap.mcs; + u16 ht_cap = sta->ht_cap.cap; + struct ieee80211_sta_vht_cap *vht_cap = &sta->vht_cap; +- struct sta_info *sinfo = container_of(sta, struct sta_info, sta); + int use_vht; + int n_supported = 0; + int ack_dur; +@@ -1267,8 +1266,7 @@ minstrel_ht_update_caps(void *priv, stru + if (!n_supported) + goto use_legacy; + +- if (test_sta_flag(sinfo, WLAN_STA_SHORT_PREAMBLE)) +- mi->cck_supported_short |= mi->cck_supported_short << 4; ++ mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4; + + /* create an initial rate table with the lowest supported rates */ + minstrel_ht_update_stats(mp, mi); diff --git a/package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch b/package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch new file mode 100644 index 0000000000..f0ffcd9655 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/308-mac80211-minstrel-fix-CCK-rate-group-streams-value.patch @@ -0,0 +1,20 @@ +From: Felix Fietkau +Date: Thu, 1 Mar 2018 13:27:54 +0100 +Subject: [PATCH] mac80211: minstrel: fix CCK rate group streams value + +Fixes a harmless underflow issue when CCK rates are actively being used + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -131,7 +131,7 @@ + + #define CCK_GROUP(_s) \ + [MINSTREL_CCK_GROUP] = { \ +- .streams = 0, \ ++ .streams = 1, \ + .flags = 0, \ + .shift = _s, \ + .duration = { \ diff --git a/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch b/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch new file mode 100644 index 0000000000..e0049c36eb --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/309-mac80211-minstrel-fix-sampling-reporting-of-CCK-rate.patch @@ -0,0 +1,58 @@ +From: Felix Fietkau +Date: Thu, 1 Mar 2018 13:28:48 +0100 +Subject: [PATCH] mac80211: minstrel: fix sampling/reporting of CCK rates + in HT mode + +Long/short preamble selection cannot be sampled separately, since it +depends on the BSS state. Because of that, sampling attempts to +currently not used preamble modes are not counted in the statistics, +which leads to CCK rates being sampled too often. + +Fix statistics accounting for long/short preamble by increasing the +index where necessary. +Fix excessive CCK rate sampling by dropping unsupported sample attempts. + +This improves throughput on 2.4 GHz channels + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -281,7 +281,8 @@ minstrel_ht_get_stats(struct minstrel_pr + break; + + /* short preamble */ +- if (!(mi->supported[group] & BIT(idx))) ++ if ((mi->supported[group] & BIT(idx + 4)) && ++ (rate->flags & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)) + idx += 4; + } + return &mi->groups[group].rates[idx]; +@@ -1080,18 +1081,23 @@ minstrel_ht_get_rate(void *priv, struct + return; + + sample_group = &minstrel_mcs_groups[sample_idx / MCS_GROUP_RATES]; ++ sample_idx %= MCS_GROUP_RATES; ++ ++ if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP] && ++ (sample_idx >= 4) != txrc->short_preamble) ++ return; ++ + info->flags |= IEEE80211_TX_CTL_RATE_CTRL_PROBE; + rate->count = 1; + +- if (sample_idx / MCS_GROUP_RATES == MINSTREL_CCK_GROUP) { ++ if (sample_group == &minstrel_mcs_groups[MINSTREL_CCK_GROUP]) { + int idx = sample_idx % ARRAY_SIZE(mp->cck_rates); + rate->idx = mp->cck_rates[idx]; + } else if (sample_group->flags & IEEE80211_TX_RC_VHT_MCS) { + ieee80211_rate_set_vht(rate, sample_idx % MCS_GROUP_RATES, + sample_group->streams); + } else { +- rate->idx = sample_idx % MCS_GROUP_RATES + +- (sample_group->streams - 1) * 8; ++ rate->idx = sample_idx + (sample_group->streams - 1) * 8; + } + + rate->flags = sample_group->flags; diff --git a/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch new file mode 100644 index 0000000000..414cb137de --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel-do-not-sample-rates-3-times-slower.patch @@ -0,0 +1,40 @@ +From: Felix Fietkau +Date: Sat, 3 Mar 2018 18:48:58 +0100 +Subject: [PATCH] mac80211: minstrel: do not sample rates 3 times slower than + max_prob_rate + +These rates are highly unlikely to be used quickly, even if the link +deteriorates rapidly. This improves throughput in cases where CCK rates +are not reliable enough to be skipped entirely during sampling. +Sampling these rates regularly can cost a lot of airtime. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -1004,10 +1004,13 @@ minstrel_get_sample_rate(struct minstrel + return -1; + + /* +- * Do not sample if the probability is already higher than 95% +- * to avoid wasting airtime. ++ * Do not sample if the probability is already higher than 95%, ++ * or if the rate is 3 times slower than the current max probability ++ * rate, to avoid wasting airtime. + */ +- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100)) ++ sample_dur = minstrel_get_duration(sample_idx); ++ if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) || ++ minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur) + return -1; + + /* +@@ -1017,7 +1020,6 @@ minstrel_get_sample_rate(struct minstrel + + cur_max_tp_streams = minstrel_mcs_groups[tp_rate1 / + MCS_GROUP_RATES].streams; +- sample_dur = minstrel_get_duration(sample_idx); + if (sample_dur >= minstrel_get_duration(tp_rate2) && + (cur_max_tp_streams - 1 < + minstrel_mcs_groups[sample_group].streams || diff --git a/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-fix-per-group-max-throughput-ra.patch b/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-fix-per-group-max-throughput-ra.patch deleted file mode 100644 index d971d84178..0000000000 --- a/package/kernel/mac80211/patches/subsys/310-mac80211-minstrel_ht-fix-per-group-max-throughput-ra.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Felix Fietkau -Date: Fri, 14 Jun 2019 21:12:04 +0200 -Subject: [PATCH] mac80211: minstrel_ht: fix per-group max throughput rate - initialization - -The group number needs to be multiplied by the number of rates per group -to get the full rate index - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -575,7 +575,7 @@ minstrel_ht_update_stats(struct minstrel - - /* (re)Initialize group rate indexes */ - for(j = 0; j < MAX_THR_RATES; j++) -- tmp_group_tp_rate[j] = group; -+ tmp_group_tp_rate[j] = MCS_GROUP_RATES * group; - - for (i = 0; i < MCS_GROUP_RATES; i++) { - if (!(mi->supported[group] & BIT(i))) diff --git a/package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch b/package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch new file mode 100644 index 0000000000..1fd2b25271 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/311-mac80211-fix-memory-accounting-with-A-MSDU-aggregati.patch @@ -0,0 +1,58 @@ +From: Felix Fietkau +Date: Thu, 8 Mar 2018 21:00:56 +0100 +Subject: [PATCH] mac80211: fix memory accounting with A-MSDU aggregation + +fq uses skb->truesize for memory usage tracking. Increments/decrements +are done on enqueue/dequeue. +When A-MSDU aggregation is performed on tx side, the packet is +aggregated with the last packet in the queue belonging to the same flow. +There are multiple bugs here: +- The truesize field of the aggregated packet isn't updated, so memory +usage is underestimated +- fq->memory_usage isn't adjusted. + +Because of the combination of both bugs, this only causes tx issues in +rare cases, mainly when the A-MSDU head needs to be reallocated. + +Fix this by adjusting both truesize of the A-MSDU head and adding the +truesize delta to fq->memory_usage. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3185,6 +3185,7 @@ static bool ieee80211_amsdu_aggregate(st + u8 max_subframes = sta->sta.max_amsdu_subframes; + int max_frags = local->hw.max_tx_fragments; + int max_amsdu_len = sta->sta.max_amsdu_len; ++ int orig_truesize; + __be16 len; + void *data; + bool ret = false; +@@ -3216,12 +3217,13 @@ static bool ieee80211_amsdu_aggregate(st + flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func); + head = skb_peek_tail(&flow->queue); + if (!head) +- goto out; ++ goto unlock; + ++ orig_truesize = head->truesize; + orig_len = head->len; + + if (skb->len + head->len > max_amsdu_len) +- goto out; ++ goto unlock; + + nfrags = 1 + skb_shinfo(skb)->nr_frags; + nfrags += 1 + skb_shinfo(head)->nr_frags; +@@ -3279,6 +3281,9 @@ out_recalc: + fq_recalc_backlog(fq, tin, flow); + } + out: ++ fq->memory_usage += head->truesize - orig_truesize; ++ ++unlock: + spin_unlock_bh(&fq->lock); + + return ret; diff --git a/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-reduce-unnecessary-rate-probing.patch b/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-reduce-unnecessary-rate-probing.patch deleted file mode 100644 index 11f6ead13d..0000000000 --- a/package/kernel/mac80211/patches/subsys/311-mac80211-minstrel_ht-reduce-unnecessary-rate-probing.patch +++ /dev/null @@ -1,42 +0,0 @@ -From: Felix Fietkau -Date: Wed, 5 Jun 2019 20:42:49 +0200 -Subject: [PATCH] mac80211: minstrel_ht: reduce unnecessary rate probing - attempts - -On hardware with static fallback tables (e.g. mt76x2), rate probing attempts -can be very expensive. -On such devices, avoid sampling rates slower than the per-group max throughput -rate, based on the assumption that the fallback table will take care of probing -lower rates within that group if the higher rates fail. -To make this work, this also fixes a wrong initialization in the previously -unused per-group sorted rate array. -To further reduce unnecessary probing attempts, skip duplicate attempts on -rates slower than the max throughput rate. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -1059,6 +1059,21 @@ minstrel_get_sample_rate(struct minstrel - minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur) - return -1; - -+ -+ /* -+ * For devices with no configurable multi-rate retry, skip sampling -+ * below the per-group max throughput rate, and only use one sampling -+ * attempt per rate -+ */ -+ if (mp->hw->max_rates == 1 && -+ (minstrel_get_duration(mg->max_group_tp_rate[0]) < sample_dur || -+ mrs->attempts)) -+ return -1; -+ -+ /* Skip already sampled slow rates */ -+ if (sample_dur >= minstrel_get_duration(tp_rate1) && mrs->attempts) -+ return -1; -+ - /* - * Make sure that lower rates get sampled only occasionally, - * if the link is working perfectly. diff --git a/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch b/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch new file mode 100644 index 0000000000..f221d36bf8 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-add-flag-to-indicate-missing-in.patch @@ -0,0 +1,122 @@ +From: Felix Fietkau +Date: Wed, 16 Jan 2019 22:32:12 +0100 +Subject: [PATCH] mac80211: minstrel_ht: add flag to indicate + missing/inaccurate tx A-MPDU length + +Some hardware (e.g. MediaTek MT7603) cannot report A-MPDU length in tx status +information. Add support for a flag to indicate that, to allow minstrel_ht +to use a fixed value in its internal calculation (which gives better results +than just defaulting to 1). + +Signed-off-by: Felix Fietkau +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2131,6 +2131,9 @@ struct ieee80211_txq { + * @IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP: The driver (or firmware) doesn't + * support QoS NDP for AP probing - that's most likely a driver bug. + * ++ * @IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN: Driver does not report accurate A-MPDU ++ * length in tx status information ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2176,6 +2179,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_SUPPORTS_TDLS_BUFFER_STA, + IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, + IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP, ++ IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -214,6 +214,7 @@ static const char *hw_flag_names[] = { + FLAG(SUPPORTS_TDLS_BUFFER_STA), + FLAG(DEAUTH_NEED_MGD_TX_PREP), + FLAG(DOESNT_SUPPORT_QOS_NDP), ++ FLAG(TX_STATUS_NO_AMPDU_LEN), + #undef FLAG + }; + +--- a/net/mac80211/rc80211_minstrel_ht.c ++++ b/net/mac80211/rc80211_minstrel_ht.c +@@ -294,6 +294,15 @@ minstrel_get_ratestats(struct minstrel_h + return &mi->groups[index / MCS_GROUP_RATES].rates[index % MCS_GROUP_RATES]; + } + ++static unsigned int ++minstrel_ht_avg_ampdu_len(struct minstrel_ht_sta *mi) ++{ ++ if (!mi->avg_ampdu_len) ++ return AVG_AMPDU_SIZE; ++ ++ return MINSTREL_TRUNC(mi->avg_ampdu_len); ++} ++ + /* + * Return current throughput based on the average A-MPDU length, taking into + * account the expected number of retransmissions and their expected length +@@ -309,7 +318,7 @@ minstrel_ht_get_tp_avg(struct minstrel_h + return 0; + + if (group != MINSTREL_CCK_GROUP) +- nsecs = 1000 * mi->overhead / MINSTREL_TRUNC(mi->avg_ampdu_len); ++ nsecs = 1000 * mi->overhead / minstrel_ht_avg_ampdu_len(mi); + + nsecs += minstrel_mcs_groups[group].duration[rate] << + minstrel_mcs_groups[group].shift; +@@ -503,8 +512,12 @@ minstrel_ht_update_stats(struct minstrel + u16 tmp_cck_tp_rate[MAX_THR_RATES], index; + + if (mi->ampdu_packets > 0) { +- mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, +- MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), EWMA_LEVEL); ++ if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN)) ++ mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, ++ MINSTREL_FRAC(mi->ampdu_len, mi->ampdu_packets), ++ EWMA_LEVEL); ++ else ++ mi->avg_ampdu_len = 0; + mi->ampdu_len = 0; + mi->ampdu_packets = 0; + } +@@ -709,7 +722,9 @@ minstrel_ht_tx_status(void *priv, struct + mi->ampdu_len += info->status.ampdu_len; + + if (!mi->sample_wait && !mi->sample_tries && mi->sample_count > 0) { +- mi->sample_wait = 16 + 2 * MINSTREL_TRUNC(mi->avg_ampdu_len); ++ int avg_ampdu_len = minstrel_ht_avg_ampdu_len(mi); ++ ++ mi->sample_wait = 16 + 2 * avg_ampdu_len; + mi->sample_tries = 1; + mi->sample_count--; + } +@@ -777,7 +792,7 @@ minstrel_calc_retransmit(struct minstrel + unsigned int cw = mp->cw_min; + unsigned int ctime = 0; + unsigned int t_slot = 9; /* FIXME */ +- unsigned int ampdu_len = MINSTREL_TRUNC(mi->avg_ampdu_len); ++ unsigned int ampdu_len = minstrel_ht_avg_ampdu_len(mi); + unsigned int overhead = 0, overhead_rtscts = 0; + + mrs = minstrel_get_ratestats(mi, index); +--- a/net/mac80211/rc80211_minstrel_ht_debugfs.c ++++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c +@@ -163,9 +163,10 @@ minstrel_ht_stats_open(struct inode *ino + "lookaround %d\n", + max(0, (int) mi->total_packets - (int) mi->sample_packets), + mi->sample_packets); +- p += sprintf(p, "Average # of aggregated frames per A-MPDU: %d.%d\n", +- MINSTREL_TRUNC(mi->avg_ampdu_len), +- MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); ++ if (mi->avg_ampdu_len) ++ p += sprintf(p, "Average # of aggregated frames per A-MPDU: %d.%d\n", ++ MINSTREL_TRUNC(mi->avg_ampdu_len), ++ MINSTREL_TRUNC(mi->avg_ampdu_len * 10) % 10); + ms->len = p - ms->buf; + WARN_ON(ms->len + sizeof(*ms) > 32768); + diff --git a/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-fix-default-max-throughput-rate.patch b/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-fix-default-max-throughput-rate.patch deleted file mode 100644 index 9855c35a5d..0000000000 --- a/package/kernel/mac80211/patches/subsys/312-mac80211-minstrel_ht-fix-default-max-throughput-rate.patch +++ /dev/null @@ -1,46 +0,0 @@ -From: Felix Fietkau -Date: Fri, 14 Jun 2019 21:14:22 +0200 -Subject: [PATCH] mac80211: minstrel_ht: fix default max throughput rate - indexes - -Use the first supported rate instead of 0 (which can be invalid) - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -486,7 +486,7 @@ minstrel_ht_assign_best_tp_rates(struct - tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma; - tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); - -- if (tmp_cck_tp > tmp_mcs_tp) { -+ if (tmp_cck_tp_rate && tmp_cck_tp > tmp_mcs_tp) { - for(i = 0; i < MAX_THR_RATES; i++) { - minstrel_ht_sort_best_tp_rates(mi, tmp_cck_tp_rate[i], - tmp_mcs_tp_rate); -@@ -558,11 +558,19 @@ minstrel_ht_update_stats(struct minstrel - mi->sample_slow = 0; - mi->sample_count = 0; - -- /* Initialize global rate indexes */ -- for(j = 0; j < MAX_THR_RATES; j++){ -- tmp_mcs_tp_rate[j] = 0; -- tmp_cck_tp_rate[j] = 0; -- } -+ memset(tmp_mcs_tp_rate, 0, sizeof(tmp_mcs_tp_rate)); -+ memset(tmp_cck_tp_rate, 0, sizeof(tmp_cck_tp_rate)); -+ if (mi->supported[MINSTREL_CCK_GROUP]) -+ for (j = 0; j < ARRAY_SIZE(tmp_cck_tp_rate); j++) -+ tmp_cck_tp_rate[j] = MINSTREL_CCK_GROUP * MCS_GROUP_RATES; -+ -+ if (mi->supported[MINSTREL_VHT_GROUP_0]) -+ index = MINSTREL_VHT_GROUP_0 * MCS_GROUP_RATES; -+ else -+ index = MINSTREL_HT_GROUP_0 * MCS_GROUP_RATES; -+ -+ for (j = 0; j < ARRAY_SIZE(tmp_mcs_tp_rate); j++) -+ tmp_mcs_tp_rate[j] = index; - - /* Find best rate sets within all MCS groups*/ - for (group = 0; group < ARRAY_SIZE(minstrel_mcs_groups); group++) { diff --git a/package/kernel/mac80211/patches/subsys/313-mac80211-fix-unaligned-access-in-mesh-table-hash-fun.patch b/package/kernel/mac80211/patches/subsys/313-mac80211-fix-unaligned-access-in-mesh-table-hash-fun.patch new file mode 100644 index 0000000000..2ce23586ca --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/313-mac80211-fix-unaligned-access-in-mesh-table-hash-fun.patch @@ -0,0 +1,21 @@ +From: Felix Fietkau +Date: Wed, 13 Mar 2019 18:52:56 +0100 +Subject: [PATCH] mac80211: fix unaligned access in mesh table hash function + +The pointer to the last four bytes of the address is not guaranteed to be +aligned, so we need to use __get_unaligned_cpu32 here + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -23,7 +23,7 @@ static void mesh_path_free_rcu(struct me + static u32 mesh_table_hash(const void *addr, u32 len, u32 seed) + { + /* Use last four bytes of hw addr as hash index */ +- return jhash_1word(*(u32 *)(addr+2), seed); ++ return jhash_1word(__get_unaligned_cpu32(addr+2), seed); + } + + static const struct rhashtable_params mesh_rht_params = { diff --git a/package/kernel/mac80211/patches/subsys/313-mac80211-minstrel_ht-improve-rate-probing-for-device.patch b/package/kernel/mac80211/patches/subsys/313-mac80211-minstrel_ht-improve-rate-probing-for-device.patch deleted file mode 100644 index 5b8e608b0a..0000000000 --- a/package/kernel/mac80211/patches/subsys/313-mac80211-minstrel_ht-improve-rate-probing-for-device.patch +++ /dev/null @@ -1,481 +0,0 @@ -From: Felix Fietkau -Date: Fri, 14 Jun 2019 21:15:47 +0200 -Subject: [PATCH] mac80211: minstrel_ht: improve rate probing for devices - with static fallback - -On some devices that only support static rate fallback tables sending rate -control probing packets can be really expensive. -Probing lower rates can already hurt throughput quite a bit. What hurts even -more is the fact that on mt76x0/mt76x2, single probing packets can only be -forced by directing packets at a different internal hardware queue, which -causes some heavy reordering and extra latency. -The reordering issue is mainly problematic while pushing lots of packets to -a particular station. If there is little activity, the overhead of probing is -neglegible. - -The static fallback behavior is designed to pretty much only handle rate -control algorithms that use only a very limited set of rates on which the -algorithm switches up/down based on packet error rate. - -In order to better support that kind of hardware, this patch implements a -different approach to rate probing where it switches to a slightly higher rate, -waits for tx status feedback, then updates the stats and switches back to -the new max throughput rate. This only triggers above a packet rate of 100 -per stats interval (~50ms). -For that kind of probing, the code has to reduce the set of probing rates -a lot more compared to single packet probing, so it uses only one packet -per MCS group which is either slightly faster, or as close as possible to -the max throughput rate. -This allows switching between similar rates with different numbers of -streams. The algorithm assumes that the hardware will work its way lower -within an MCS group in case of retransmissions, so that lower rates don't -have to be probed by the high packets per second rate probing code. - -To further reduce the search space, it also does not probe rates with lower -channel bandwidth than the max throughput rate. - -At the moment, these changes will only affect mt76x0/mt76x2. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -95,6 +95,7 @@ struct minstrel_sta_info { - struct minstrel_priv { - struct ieee80211_hw *hw; - bool has_mrr; -+ u32 sample_switch; - unsigned int cw_min; - unsigned int cw_max; - unsigned int max_retry; ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -18,6 +18,8 @@ - #define AVG_AMPDU_SIZE 16 - #define AVG_PKT_SIZE 1200 - -+#define SAMPLE_SWITCH_THR 100 -+ - /* Number of bits for an average sized packet */ - #define MCS_NBITS ((AVG_PKT_SIZE * AVG_AMPDU_SIZE) << 3) - -@@ -58,6 +60,7 @@ - [GROUP_IDX(_streams, _sgi, _ht40)] = { \ - .streams = _streams, \ - .shift = _s, \ -+ .bw = _ht40, \ - .flags = \ - IEEE80211_TX_RC_MCS | \ - (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ -@@ -94,6 +97,7 @@ - [VHT_GROUP_IDX(_streams, _sgi, _bw)] = { \ - .streams = _streams, \ - .shift = _s, \ -+ .bw = _bw, \ - .flags = \ - IEEE80211_TX_RC_VHT_MCS | \ - (_sgi ? IEEE80211_TX_RC_SHORT_GI : 0) | \ -@@ -526,6 +530,133 @@ minstrel_ht_prob_rate_reduce_streams(str - } - } - -+static inline int -+minstrel_get_duration(int index) -+{ -+ const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; -+ unsigned int duration = group->duration[index % MCS_GROUP_RATES]; -+ return duration << group->shift; -+} -+ -+static bool -+minstrel_ht_probe_group(struct minstrel_ht_sta *mi, const struct mcs_group *tp_group, -+ int tp_idx, const struct mcs_group *group) -+{ -+ if (group->bw < tp_group->bw) -+ return false; -+ -+ if (group->streams == tp_group->streams) -+ return true; -+ -+ if (tp_idx < 4 && group->streams == tp_group->streams - 1) -+ return true; -+ -+ return group->streams == tp_group->streams + 1; -+} -+ -+static void -+minstrel_ht_find_probe_rates(struct minstrel_ht_sta *mi, u16 *rates, int *n_rates, -+ bool faster_rate) -+{ -+ const struct mcs_group *group, *tp_group; -+ int i, g, max_dur; -+ int tp_idx; -+ -+ tp_group = &minstrel_mcs_groups[mi->max_tp_rate[0] / MCS_GROUP_RATES]; -+ tp_idx = mi->max_tp_rate[0] % MCS_GROUP_RATES; -+ -+ max_dur = minstrel_get_duration(mi->max_tp_rate[0]); -+ if (faster_rate) -+ max_dur -= max_dur / 16; -+ -+ for (g = 0; g < MINSTREL_GROUPS_NB; g++) { -+ u16 supported = mi->supported[g]; -+ -+ if (!supported) -+ continue; -+ -+ group = &minstrel_mcs_groups[g]; -+ if (!minstrel_ht_probe_group(mi, tp_group, tp_idx, group)) -+ continue; -+ -+ for (i = 0; supported; supported >>= 1, i++) { -+ int idx; -+ -+ if (!(supported & 1)) -+ continue; -+ -+ if ((group->duration[i] << group->shift) > max_dur) -+ continue; -+ -+ idx = g * MCS_GROUP_RATES + i; -+ if (idx == mi->max_tp_rate[0]) -+ continue; -+ -+ rates[(*n_rates)++] = idx; -+ break; -+ } -+ } -+} -+ -+static void -+minstrel_ht_rate_sample_switch(struct minstrel_priv *mp, -+ struct minstrel_ht_sta *mi) -+{ -+ struct minstrel_rate_stats *mrs; -+ u16 rates[MINSTREL_GROUPS_NB]; -+ int n_rates = 0; -+ int probe_rate = 0; -+ bool faster_rate; -+ int i; -+ u8 random; -+ -+ /* -+ * Use rate switching instead of probing packets for devices with -+ * little control over retry fallback behavior -+ */ -+ if (mp->hw->max_rates > 1) -+ return; -+ -+ /* -+ * If the current EWMA prob is >75%, look for a rate that's 6.25% -+ * faster than the max tp rate. -+ * If that fails, look again for a rate that is at least as fast -+ */ -+ mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); -+ faster_rate = mrs->prob_ewma > MINSTREL_FRAC(75, 100); -+ minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate); -+ if (!n_rates && faster_rate) -+ minstrel_ht_find_probe_rates(mi, rates, &n_rates, false); -+ -+ /* If no suitable rate was found, try to pick the next one in the group */ -+ if (!n_rates) { -+ int g_idx = mi->max_tp_rate[0] / MCS_GROUP_RATES; -+ u16 supported = mi->supported[g_idx]; -+ -+ supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES; -+ for (i = 0; supported; i++) { -+ if (!(supported & 1)) -+ continue; -+ -+ probe_rate = mi->max_tp_rate[0] + i; -+ goto out; -+ } -+ -+ return; -+ } -+ -+ i = 0; -+ if (n_rates > 1) { -+ random = prandom_u32(); -+ i = random % n_rates; -+ } -+ probe_rate = rates[i]; -+ -+out: -+ mi->sample_rate = probe_rate; -+ mi->sample_mode = MINSTREL_SAMPLE_ACTIVE; -+} -+ - /* - * Update rate statistics and select new primary rates - * -@@ -536,7 +667,8 @@ minstrel_ht_prob_rate_reduce_streams(str - * higher throughput rates, even if the probablity is a bit lower - */ - static void --minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) -+minstrel_ht_update_stats(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, -+ bool sample) - { - struct minstrel_mcs_group_data *mg; - struct minstrel_rate_stats *mrs; -@@ -544,6 +676,18 @@ minstrel_ht_update_stats(struct minstrel - u16 tmp_mcs_tp_rate[MAX_THR_RATES], tmp_group_tp_rate[MAX_THR_RATES]; - u16 tmp_cck_tp_rate[MAX_THR_RATES], index; - -+ mi->sample_mode = MINSTREL_SAMPLE_IDLE; -+ -+ if (sample) { -+ mi->total_packets_cur = mi->total_packets - -+ mi->total_packets_last; -+ mi->total_packets_last = mi->total_packets; -+ } -+ if (!mp->sample_switch) -+ sample = false; -+ if (mi->total_packets_cur < SAMPLE_SWITCH_THR && mp->sample_switch != 1) -+ sample = false; -+ - if (mi->ampdu_packets > 0) { - if (!ieee80211_hw_check(mp->hw, TX_STATUS_NO_AMPDU_LEN)) - mi->avg_ampdu_len = minstrel_ewma(mi->avg_ampdu_len, -@@ -630,12 +774,16 @@ minstrel_ht_update_stats(struct minstrel - /* try to sample all available rates during each interval */ - mi->sample_count *= 8; - -+ if (sample) -+ minstrel_ht_rate_sample_switch(mp, mi); -+ - #ifdef CPTCFG_MAC80211_DEBUGFS - /* use fixed index if set */ - if (mp->fixed_rate_idx != -1) { - for (i = 0; i < 4; i++) - mi->max_tp_rate[i] = mp->fixed_rate_idx; - mi->max_prob_rate = mp->fixed_rate_idx; -+ mi->sample_mode = MINSTREL_SAMPLE_IDLE; - } - #endif - -@@ -739,15 +887,17 @@ minstrel_ht_tx_status(void *priv, struct - struct minstrel_ht_sta_priv *msp = priv_sta; - struct minstrel_ht_sta *mi = &msp->ht; - struct ieee80211_tx_rate *ar = info->status.rates; -- struct minstrel_rate_stats *rate, *rate2; -+ struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL; - struct minstrel_priv *mp = priv; - bool last, update = false; -+ bool sample_status = false; - int i; - - if (!msp->is_ht) - return mac80211_minstrel.tx_status_ext(priv, sband, - &msp->legacy, st); - -+ - /* This packet was aggregated but doesn't carry status info */ - if ((info->flags & IEEE80211_TX_CTL_AMPDU) && - !(info->flags & IEEE80211_TX_STAT_AMPDU)) -@@ -773,12 +923,17 @@ minstrel_ht_tx_status(void *priv, struct - if (info->flags & IEEE80211_TX_CTL_RATE_CTRL_PROBE) - mi->sample_packets += info->status.ampdu_len; - -+ if (mi->sample_mode != MINSTREL_SAMPLE_IDLE) -+ rate_sample = minstrel_get_ratestats(mi, mi->sample_rate); -+ - last = !minstrel_ht_txstat_valid(mp, &ar[0]); - for (i = 0; !last; i++) { - last = (i == IEEE80211_TX_MAX_RATES - 1) || - !minstrel_ht_txstat_valid(mp, &ar[i + 1]); - - rate = minstrel_ht_get_stats(mp, mi, &ar[i]); -+ if (rate == rate_sample) -+ sample_status = true; - - if (last) - rate->success += info->status.ampdu_ack_len; -@@ -786,44 +941,60 @@ minstrel_ht_tx_status(void *priv, struct - rate->attempts += ar[i].count * info->status.ampdu_len; - } - -- /* -- * check for sudden death of spatial multiplexing, -- * downgrade to a lower number of streams if necessary. -- */ -- rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); -- if (rate->attempts > 30 && -- MINSTREL_FRAC(rate->success, rate->attempts) < -- MINSTREL_FRAC(20, 100)) { -- minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); -+ switch (mi->sample_mode) { -+ case MINSTREL_SAMPLE_IDLE: -+ break; -+ -+ case MINSTREL_SAMPLE_ACTIVE: -+ if (!sample_status) -+ break; -+ -+ mi->sample_mode = MINSTREL_SAMPLE_PENDING; - update = true; -- } -+ break; -+ -+ case MINSTREL_SAMPLE_PENDING: -+ if (sample_status) -+ break; - -- rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); -- if (rate2->attempts > 30 && -- MINSTREL_FRAC(rate2->success, rate2->attempts) < -- MINSTREL_FRAC(20, 100)) { -- minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); - update = true; -+ minstrel_ht_update_stats(mp, mi, false); -+ break; -+ } -+ -+ -+ if (mp->hw->max_rates > 1) { -+ /* -+ * check for sudden death of spatial multiplexing, -+ * downgrade to a lower number of streams if necessary. -+ */ -+ rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); -+ if (rate->attempts > 30 && -+ MINSTREL_FRAC(rate->success, rate->attempts) < -+ MINSTREL_FRAC(20, 100)) { -+ minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); -+ update = true; -+ } -+ -+ rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); -+ if (rate2->attempts > 30 && -+ MINSTREL_FRAC(rate2->success, rate2->attempts) < -+ MINSTREL_FRAC(20, 100)) { -+ minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); -+ update = true; -+ } - } - - if (time_after(jiffies, mi->last_stats_update + - (mp->update_interval / 2 * HZ) / 1000)) { - update = true; -- minstrel_ht_update_stats(mp, mi); -+ minstrel_ht_update_stats(mp, mi, true); - } - - if (update) - minstrel_ht_update_rates(mp, mi); - } - --static inline int --minstrel_get_duration(int index) --{ -- const struct mcs_group *group = &minstrel_mcs_groups[index / MCS_GROUP_RATES]; -- unsigned int duration = group->duration[index % MCS_GROUP_RATES]; -- return duration << group->shift; --} -- - static void - minstrel_calc_retransmit(struct minstrel_priv *mp, struct minstrel_ht_sta *mi, - int index) -@@ -988,14 +1159,18 @@ static void - minstrel_ht_update_rates(struct minstrel_priv *mp, struct minstrel_ht_sta *mi) - { - struct ieee80211_sta_rates *rates; -+ u16 first_rate = mi->max_tp_rate[0]; - int i = 0; - -+ if (mi->sample_mode == MINSTREL_SAMPLE_ACTIVE) -+ first_rate = mi->sample_rate; -+ - rates = kzalloc(sizeof(*rates), GFP_ATOMIC); - if (!rates) - return; - - /* Start with max_tp_rate[0] */ -- minstrel_ht_set_rate(mp, mi, rates, i++, mi->max_tp_rate[0]); -+ minstrel_ht_set_rate(mp, mi, rates, i++, first_rate); - - if (mp->hw->max_rates >= 3) { - /* At least 3 tx rates supported, use max_tp_rate[1] next */ -@@ -1020,6 +1195,11 @@ minstrel_get_sample_rate(struct minstrel - int tp_rate1, tp_rate2; - int sample_idx = 0; - -+ if (mp->hw->max_rates == 1 && mp->sample_switch && -+ (mi->total_packets_cur >= SAMPLE_SWITCH_THR || -+ mp->sample_switch == 1)) -+ return -1; -+ - if (mi->sample_wait > 0) { - mi->sample_wait--; - return -1; -@@ -1341,7 +1521,7 @@ minstrel_ht_update_caps(void *priv, stru - mi->supported[MINSTREL_CCK_GROUP] |= mi->cck_supported_short << 4; - - /* create an initial rate table with the lowest supported rates */ -- minstrel_ht_update_stats(mp, mi); -+ minstrel_ht_update_stats(mp, mi, true); - minstrel_ht_update_rates(mp, mi); - - return; -@@ -1459,6 +1639,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h - if (!mp) - return NULL; - -+ mp->sample_switch = -1; -+ - /* contention window settings - * Just an approximation. Using the per-queue values would complicate - * the calculations and is probably unnecessary */ -@@ -1490,6 +1672,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h - mp->fixed_rate_idx = (u32) -1; - debugfs_create_u32("fixed_rate_idx", S_IRUGO | S_IWUGO, debugfsdir, - &mp->fixed_rate_idx); -+ debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir, -+ &mp->sample_switch); - #endif - - minstrel_ht_init_cck_rates(mp); ---- a/net/mac80211/rc80211_minstrel_ht.h -+++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -33,6 +33,7 @@ struct mcs_group { - u16 flags; - u8 streams; - u8 shift; -+ u8 bw; - u16 duration[MCS_GROUP_RATES]; - }; - -@@ -50,6 +51,12 @@ struct minstrel_mcs_group_data { - struct minstrel_rate_stats rates[MCS_GROUP_RATES]; - }; - -+enum minstrel_sample_mode { -+ MINSTREL_SAMPLE_IDLE, -+ MINSTREL_SAMPLE_ACTIVE, -+ MINSTREL_SAMPLE_PENDING, -+}; -+ - struct minstrel_ht_sta { - struct ieee80211_sta *sta; - -@@ -71,6 +78,8 @@ struct minstrel_ht_sta { - unsigned int overhead; - unsigned int overhead_rtscts; - -+ unsigned int total_packets_last; -+ unsigned int total_packets_cur; - unsigned int total_packets; - unsigned int sample_packets; - -@@ -82,6 +91,9 @@ struct minstrel_ht_sta { - u8 sample_count; - u8 sample_slow; - -+ enum minstrel_sample_mode sample_mode; -+ u16 sample_rate; -+ - /* current MCS group to be sampled */ - u8 sample_group; - diff --git a/package/kernel/mac80211/patches/subsys/314-mac80211-add-IEEE80211_KEY_FLAG_GENERATE_MMIE-to-iee.patch b/package/kernel/mac80211/patches/subsys/314-mac80211-add-IEEE80211_KEY_FLAG_GENERATE_MMIE-to-iee.patch deleted file mode 100644 index f732345842..0000000000 --- a/package/kernel/mac80211/patches/subsys/314-mac80211-add-IEEE80211_KEY_FLAG_GENERATE_MMIE-to-iee.patch +++ /dev/null @@ -1,58 +0,0 @@ -From: Lorenzo Bianconi -Date: Tue, 16 Jul 2019 00:09:19 +0200 -Subject: [PATCH] mac80211: add IEEE80211_KEY_FLAG_GENERATE_MMIE to - ieee80211_key_flags - -Add IEEE80211_KEY_FLAG_GENERATE_MMIE flag to ieee80211_key_flags in order -to allow the driver to notify mac80211 to generate MMIE and that it -requires sequence number generation only. -This is a preliminary patch to add BIP_CMAC_128 hw support to mt7615 -driver - -Signed-off-by: Lorenzo Bianconi -Link: https://lore.kernel.org/r/dfe275f9aa0f1cc6b33085f9efd5d8447f68ad13.1563228405.git.lorenzo@kernel.org -Signed-off-by: Johannes Berg ---- - ---- a/include/net/mac80211.h -+++ b/include/net/mac80211.h -@@ -1702,6 +1702,9 @@ struct wireless_dev *ieee80211_vif_to_wd - * a TKIP key if it only requires MIC space. Do not set together with - * @IEEE80211_KEY_FLAG_GENERATE_MMIC on the same key. - * @IEEE80211_KEY_FLAG_NO_AUTO_TX: Key needs explicit Tx activation. -+ * @IEEE80211_KEY_FLAG_GENERATE_MMIE: This flag should be set by the driver -+ * for a AES_CMAC key to indicate that it requires sequence number -+ * generation only - */ - enum ieee80211_key_flags { - IEEE80211_KEY_FLAG_GENERATE_IV_MGMT = BIT(0), -@@ -1714,6 +1717,7 @@ enum ieee80211_key_flags { - IEEE80211_KEY_FLAG_RESERVE_TAILROOM = BIT(7), - IEEE80211_KEY_FLAG_PUT_MIC_SPACE = BIT(8), - IEEE80211_KEY_FLAG_NO_AUTO_TX = BIT(9), -+ IEEE80211_KEY_FLAG_GENERATE_MMIE = BIT(10), - }; - - /** ---- a/net/mac80211/wpa.c -+++ b/net/mac80211/wpa.c -@@ -947,7 +947,8 @@ ieee80211_crypto_aes_cmac_encrypt(struct - - info = IEEE80211_SKB_CB(skb); - -- if (info->control.hw_key) -+ if (info->control.hw_key && -+ !(key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_MMIE)) - return TX_CONTINUE; - - if (WARN_ON(skb_tailroom(skb) < sizeof(*mmie))) -@@ -963,6 +964,9 @@ ieee80211_crypto_aes_cmac_encrypt(struct - - bip_ipn_set64(mmie->sequence_number, pn64); - -+ if (info->control.hw_key) -+ return TX_CONTINUE; -+ - bip_aad(skb, aad); - - /* diff --git a/package/kernel/mac80211/patches/subsys/315-mac80211-minstrel_ht-fix-infinite-loop-because-suppo.patch b/package/kernel/mac80211/patches/subsys/315-mac80211-minstrel_ht-fix-infinite-loop-because-suppo.patch deleted file mode 100644 index eb70d4d5d2..0000000000 --- a/package/kernel/mac80211/patches/subsys/315-mac80211-minstrel_ht-fix-infinite-loop-because-suppo.patch +++ /dev/null @@ -1,25 +0,0 @@ -From: Colin Ian King -Date: Thu, 22 Aug 2019 13:20:34 +0100 -Subject: [PATCH] mac80211: minstrel_ht: fix infinite loop because supported is - not being shifted - -Currently the for-loop will spin forever if variable supported is -non-zero because supported is never changed. Fix this by adding in -the missing right shift of supported. - -Addresses-Coverity: ("Infinite loop") -Fixes: 48cb39522a9d ("mac80211: minstrel_ht: improve rate probing for devices with static fallback") -Signed-off-by: Colin Ian King ---- - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -634,7 +634,7 @@ minstrel_ht_rate_sample_switch(struct mi - u16 supported = mi->supported[g_idx]; - - supported >>= mi->max_tp_rate[0] % MCS_GROUP_RATES; -- for (i = 0; supported; i++) { -+ for (i = 0; supported; supported >>= 1, i++) { - if (!(supported & 1)) - continue; - diff --git a/package/kernel/mac80211/patches/subsys/320-mac80211-Add-TXQ-scheduling-API.patch b/package/kernel/mac80211/patches/subsys/320-mac80211-Add-TXQ-scheduling-API.patch new file mode 100644 index 0000000000..0f7d9e1506 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/320-mac80211-Add-TXQ-scheduling-API.patch @@ -0,0 +1,292 @@ +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Tue, 18 Dec 2018 17:02:06 -0800 +Subject: [PATCH] mac80211: Add TXQ scheduling API +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This adds an API to mac80211 to handle scheduling of TXQs. The interface +between driver and mac80211 for TXQ handling is changed by adding two new +functions: ieee80211_next_txq(), which will return the next TXQ to schedule +in the current round-robin rotation, and ieee80211_return_txq(), which the +driver uses to indicate that it has finished scheduling a TXQ (which will +then be put back in the scheduling rotation if it isn't empty). + +The driver must call ieee80211_txq_schedule_start() at the start of each +scheduling session, and ieee80211_txq_schedule_end() at the end. The API +then guarantees that the same TXQ is not returned twice in the same +session (so a driver can loop on ieee80211_next_txq() without worrying +about breaking the loop. + +Usage of the new API is optional, so drivers can be ported one at a time. +In this patch, the actual scheduling performed by mac80211 is simple +round-robin, but a subsequent commit adds airtime fairness awareness to the +scheduler. + +Signed-off-by: Toke Høiland-Jørgensen +[minor kernel-doc fix, propagate sparse locking checks out] +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -107,9 +107,15 @@ + * The driver is expected to initialize its private per-queue data for stations + * and interfaces in the .add_interface and .sta_add ops. + * +- * The driver can't access the queue directly. To dequeue a frame, it calls +- * ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a queue, it +- * calls the .wake_tx_queue driver op. ++ * The driver can't access the queue directly. To dequeue a frame from a ++ * txq, it calls ieee80211_tx_dequeue(). Whenever mac80211 adds a new frame to a ++ * queue, it calls the .wake_tx_queue driver op. ++ * ++ * Drivers can optionally delegate responsibility for scheduling queues to ++ * mac80211, to take advantage of airtime fairness accounting. In this case, to ++ * obtain the next queue to pull frames from, the driver calls ++ * ieee80211_next_txq(). The driver is then expected to return the txq using ++ * ieee80211_return_txq(). + * + * For AP powersave TIM handling, the driver only needs to indicate if it has + * buffered packets in the driver specific data structures by calling +@@ -5979,7 +5985,8 @@ void ieee80211_unreserve_tid(struct ieee + * ieee80211_tx_dequeue - dequeue a packet from a software tx queue + * + * @hw: pointer as obtained from ieee80211_alloc_hw() +- * @txq: pointer obtained from station or virtual interface ++ * @txq: pointer obtained from station or virtual interface, or from ++ * ieee80211_next_txq() + * + * Returns the skb if successful, %NULL if no frame was available. + */ +@@ -5987,6 +5994,54 @@ struct sk_buff *ieee80211_tx_dequeue(str + struct ieee80211_txq *txq); + + /** ++ * ieee80211_next_txq - get next tx queue to pull packets from ++ * ++ * @hw: pointer as obtained from ieee80211_alloc_hw() ++ * @ac: AC number to return packets from. ++ * ++ * Should only be called between calls to ieee80211_txq_schedule_start() ++ * and ieee80211_txq_schedule_end(). ++ * Returns the next txq if successful, %NULL if no queue is eligible. If a txq ++ * is returned, it should be returned with ieee80211_return_txq() after the ++ * driver has finished scheduling it. ++ */ ++struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac); ++ ++/** ++ * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq() ++ * ++ * @hw: pointer as obtained from ieee80211_alloc_hw() ++ * @txq: pointer obtained from station or virtual interface ++ * ++ * Should only be called between calls to ieee80211_txq_schedule_start() ++ * and ieee80211_txq_schedule_end(). ++ */ ++void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); ++ ++/** ++ * ieee80211_txq_schedule_start - acquire locks for safe scheduling of an AC ++ * ++ * @hw: pointer as obtained from ieee80211_alloc_hw() ++ * @ac: AC number to acquire locks for ++ * ++ * Acquire locks needed to schedule TXQs from the given AC. Should be called ++ * before ieee80211_next_txq() or ieee80211_return_txq(). ++ */ ++void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) ++ __acquires(txq_lock); ++ ++/** ++ * ieee80211_txq_schedule_end - release locks for safe scheduling of an AC ++ * ++ * @hw: pointer as obtained from ieee80211_alloc_hw() ++ * @ac: AC number to acquire locks for ++ * ++ * Release locks previously acquired by ieee80211_txq_schedule_end(). ++ */ ++void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac) ++ __releases(txq_lock); ++ ++/** + * ieee80211_txq_get_depth - get pending frame/byte count of given txq + * + * The values are not guaranteed to be coherent with regard to each other, i.e. +--- a/net/mac80211/agg-tx.c ++++ b/net/mac80211/agg-tx.c +@@ -229,7 +229,7 @@ ieee80211_agg_start_txq(struct sta_info + clear_bit(IEEE80211_TXQ_STOP, &txqi->flags); + local_bh_disable(); + rcu_read_lock(); +- drv_wake_tx_queue(sta->sdata->local, txqi); ++ schedule_and_wake_txq(sta->sdata->local, txqi); + rcu_read_unlock(); + local_bh_enable(); + } +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -1176,6 +1176,15 @@ static inline void drv_wake_tx_queue(str + local->ops->wake_tx_queue(&local->hw, &txq->txq); + } + ++static inline void schedule_and_wake_txq(struct ieee80211_local *local, ++ struct txq_info *txqi) ++{ ++ spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]); ++ ieee80211_return_txq(&local->hw, &txqi->txq); ++ spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); ++ drv_wake_tx_queue(local, txqi); ++} ++ + static inline int drv_start_nan(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct cfg80211_nan_conf *conf) +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -829,6 +829,8 @@ enum txq_info_flags { + * a fq_flow which is already owned by a different tin + * @def_cvars: codel vars for @def_flow + * @frags: used to keep fragments created after dequeue ++ * @schedule_order: used with ieee80211_local->active_txqs ++ * @schedule_round: counter to prevent infinite loops on TXQ scheduling + */ + struct txq_info { + struct fq_tin tin; +@@ -836,6 +838,8 @@ struct txq_info { + struct codel_vars def_cvars; + struct codel_stats cstats; + struct sk_buff_head frags; ++ struct list_head schedule_order; ++ u16 schedule_round; + unsigned long flags; + + /* keep last! */ +@@ -1127,6 +1131,11 @@ struct ieee80211_local { + struct codel_vars *cvars; + struct codel_params cparams; + ++ /* protects active_txqs and txqi->schedule_order */ ++ spinlock_t active_txq_lock[IEEE80211_NUM_ACS]; ++ struct list_head active_txqs[IEEE80211_NUM_ACS]; ++ u16 schedule_round[IEEE80211_NUM_ACS]; ++ + const struct ieee80211_ops *ops; + + /* +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -652,6 +652,11 @@ struct ieee80211_hw *ieee80211_alloc_hw_ + spin_lock_init(&local->rx_path_lock); + spin_lock_init(&local->queue_stop_reason_lock); + ++ for (i = 0; i < IEEE80211_NUM_ACS; i++) { ++ INIT_LIST_HEAD(&local->active_txqs[i]); ++ spin_lock_init(&local->active_txq_lock[i]); ++ } ++ + INIT_LIST_HEAD(&local->chanctx_list); + mutex_init(&local->chanctx_mtx); + +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -1244,7 +1244,7 @@ void ieee80211_sta_ps_deliver_wakeup(str + if (!txq_has_queue(sta->sta.txq[i])) + continue; + +- drv_wake_tx_queue(local, to_txq_info(sta->sta.txq[i])); ++ schedule_and_wake_txq(local, to_txq_info(sta->sta.txq[i])); + } + } + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1441,6 +1441,7 @@ void ieee80211_txq_init(struct ieee80211 + codel_vars_init(&txqi->def_cvars); + codel_stats_init(&txqi->cstats); + __skb_queue_head_init(&txqi->frags); ++ INIT_LIST_HEAD(&txqi->schedule_order); + + txqi->txq.vif = &sdata->vif; + +@@ -1464,6 +1465,9 @@ void ieee80211_txq_purge(struct ieee8021 + + fq_tin_reset(fq, tin, fq_skb_free_func); + ieee80211_purge_tx_queue(&local->hw, &txqi->frags); ++ spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]); ++ list_del_init(&txqi->schedule_order); ++ spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); + } + + void ieee80211_txq_set_params(struct ieee80211_local *local) +@@ -1580,7 +1584,7 @@ static bool ieee80211_queue_skb(struct i + ieee80211_txq_enqueue(local, txqi, skb); + spin_unlock_bh(&fq->lock); + +- drv_wake_tx_queue(local, txqi); ++ schedule_and_wake_txq(local, txqi); + + return true; + } +@@ -3602,6 +3606,60 @@ out: + } + EXPORT_SYMBOL(ieee80211_tx_dequeue); + ++struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct txq_info *txqi = NULL; ++ ++ lockdep_assert_held(&local->active_txq_lock[ac]); ++ ++ txqi = list_first_entry_or_null(&local->active_txqs[ac], ++ struct txq_info, ++ schedule_order); ++ ++ if (!txqi || txqi->schedule_round == local->schedule_round[ac]) ++ return NULL; ++ ++ list_del_init(&txqi->schedule_order); ++ txqi->schedule_round = local->schedule_round[ac]; ++ return &txqi->txq; ++} ++EXPORT_SYMBOL(ieee80211_next_txq); ++ ++void ieee80211_return_txq(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct txq_info *txqi = to_txq_info(txq); ++ ++ lockdep_assert_held(&local->active_txq_lock[txq->ac]); ++ ++ if (list_empty(&txqi->schedule_order) && ++ (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) ++ list_add_tail(&txqi->schedule_order, ++ &local->active_txqs[txq->ac]); ++} ++EXPORT_SYMBOL(ieee80211_return_txq); ++ ++void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) ++ __acquires(txq_lock) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ ++ spin_lock_bh(&local->active_txq_lock[ac]); ++ local->schedule_round[ac]++; ++} ++EXPORT_SYMBOL(ieee80211_txq_schedule_start); ++ ++void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac) ++ __releases(txq_lock) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ ++ spin_unlock_bh(&local->active_txq_lock[ac]); ++} ++EXPORT_SYMBOL(ieee80211_txq_schedule_end); ++ + void __ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev, + u32 info_flags) diff --git a/package/kernel/mac80211/patches/subsys/321-cfg80211-Add-airtime-statistics-and-settings.patch b/package/kernel/mac80211/patches/subsys/321-cfg80211-Add-airtime-statistics-and-settings.patch new file mode 100644 index 0000000000..7eb64c4251 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/321-cfg80211-Add-airtime-statistics-and-settings.patch @@ -0,0 +1,202 @@ +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Tue, 18 Dec 2018 17:02:07 -0800 +Subject: [PATCH] cfg80211: Add airtime statistics and settings +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This adds TX airtime statistics to the cfg80211 station dump (to go along +with the RX info already present), and adds a new parameter to set the +airtime weight of each station. The latter allows userspace to implement +policies for different stations by varying their weights. + +Signed-off-by: Toke Høiland-Jørgensen +[rmanohar@codeaurora.org: fixed checkpatch warnings] +Signed-off-by: Rajkumar Manoharan +[move airtime weight != 0 check into policy] +Signed-off-by: Johannes Berg +--- + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -988,6 +988,7 @@ enum station_parameters_apply_mask { + * @support_p2p_ps: information if station supports P2P PS mechanism + * @he_capa: HE capabilities of station + * @he_capa_len: the length of the HE capabilities ++ * @airtime_weight: airtime scheduler weight for this station + */ + struct station_parameters { + const u8 *supported_rates; +@@ -1017,6 +1018,7 @@ struct station_parameters { + int support_p2p_ps; + const struct ieee80211_he_cap_elem *he_capa; + u8 he_capa_len; ++ u16 airtime_weight; + }; + + /** +@@ -1284,6 +1286,8 @@ struct cfg80211_tid_stats { + * @rx_beacon_signal_avg: signal strength average (in dBm) for beacons received + * from this peer + * @rx_duration: aggregate PPDU duration(usecs) for all the frames from a peer ++ * @tx_duration: aggregate PPDU duration(usecs) for all the frames to a peer ++ * @airtime_weight: current airtime scheduling weight + * @pertid: per-TID statistics, see &struct cfg80211_tid_stats, using the last + * (IEEE80211_NUM_TIDS) index for MSDUs not encapsulated in QoS-MPDUs. + * Note that this doesn't use the @filled bit, but is used if non-NULL. +@@ -1330,12 +1334,15 @@ struct station_info { + + u32 expected_throughput; + +- u64 rx_beacon; ++ u64 tx_duration; + u64 rx_duration; ++ u64 rx_beacon; + u8 rx_beacon_signal_avg; + struct cfg80211_tid_stats *pertid; + s8 ack_signal; + s8 avg_ack_signal; ++ ++ u16 airtime_weight; + }; + + #if IS_ENABLED(CPTCFG_CFG80211) +@@ -2361,6 +2368,8 @@ enum wiphy_params_flags { + WIPHY_PARAM_TXQ_QUANTUM = 1 << 8, + }; + ++#define IEEE80211_DEFAULT_AIRTIME_WEIGHT 256 ++ + /** + * struct cfg80211_pmksa - PMK Security Association + * +--- a/include/uapi/linux/nl80211.h ++++ b/include/uapi/linux/nl80211.h +@@ -2241,6 +2241,9 @@ enum nl80211_commands { + * association request when used with NL80211_CMD_NEW_STATION). Can be set + * only if %NL80211_STA_FLAG_WME is set. + * ++ * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime ++ * scheduler. ++ * + * @NUM_NL80211_ATTR: total number of nl80211_attrs available + * @NL80211_ATTR_MAX: highest attribute number currently defined + * @__NL80211_ATTR_AFTER_LAST: internal use +@@ -2682,6 +2685,14 @@ enum nl80211_attrs { + + NL80211_ATTR_HE_CAPABILITY, + ++ /* not backported yet */ ++ NL80211_ATTR_FTM_RESPONDER, ++ NL80211_ATTR_FTM_RESPONDER_STATS, ++ NL80211_ATTR_TIMEOUT, ++ NL80211_ATTR_PEER_MEASUREMENTS, ++ ++ NL80211_ATTR_AIRTIME_WEIGHT, ++ + /* add attributes here, update the policy in nl80211.c */ + + __NL80211_ATTR_AFTER_LAST, +@@ -3052,6 +3063,9 @@ enum nl80211_sta_bss_param { + * @NL80211_STA_INFO_ACK_SIGNAL: signal strength of the last ACK frame(u8, dBm) + * @NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG: avg signal strength of (data) + * ACK frame (s8, dBm) ++ * @NL80211_STA_INFO_TX_DURATION: aggregate PPDU duration for all frames ++ * sent to the station (u64, usec) ++ * @NL80211_STA_INFO_AIRTIME_WEIGHT: current airtime weight for station (u16) + * @__NL80211_STA_INFO_AFTER_LAST: internal + * @NL80211_STA_INFO_MAX: highest possible station info attribute + */ +@@ -3093,6 +3107,14 @@ enum nl80211_sta_info { + NL80211_STA_INFO_ACK_SIGNAL, + NL80211_STA_INFO_DATA_ACK_SIGNAL_AVG, + ++ /* not backported yet */ ++ NL80211_STA_INFO_RX_MPDUS, ++ NL80211_STA_INFO_FCS_ERROR_COUNT, ++ NL80211_STA_INFO_CONNECTED_TO_GATE, ++ ++ NL80211_STA_INFO_TX_DURATION, ++ NL80211_STA_INFO_AIRTIME_WEIGHT, ++ + /* keep last */ + __NL80211_STA_INFO_AFTER_LAST, + NL80211_STA_INFO_MAX = __NL80211_STA_INFO_AFTER_LAST - 1 +@@ -5224,6 +5246,10 @@ enum nl80211_feature_flags { + * except for supported rates from the probe request content if requested + * by the %NL80211_SCAN_FLAG_MIN_PREQ_CONTENT flag. + * ++ * @NL80211_EXT_FEATURE_AIRTIME_FAIRNESS: Driver supports getting airtime ++ * fairness for transmitted packets and has enabled airtime fairness ++ * scheduling. ++ * + * @NUM_NL80211_EXT_FEATURES: number of extended features. + * @MAX_NL80211_EXT_FEATURES: highest extended feature index. + */ +@@ -5260,6 +5286,12 @@ enum nl80211_ext_feature_index { + NL80211_EXT_FEATURE_SCAN_RANDOM_SN, + NL80211_EXT_FEATURE_SCAN_MIN_PREQ_CONTENT, + ++ /* --- not backported yet --- */ ++ NL80211_EXT_FEATURE_CAN_REPLACE_PTK0, ++ NL80211_EXT_FEATURE_ENABLE_FTM_RESPONDER, ++ ++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS, ++ + /* add new features before the definition below */ + NUM_NL80211_EXT_FEATURES, + MAX_NL80211_EXT_FEATURES = NUM_NL80211_EXT_FEATURES - 1 +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -430,6 +430,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_TXQ_QUANTUM] = { .type = NLA_U32 }, + [NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY, + .len = NL80211_HE_MAX_CAPABILITY_LEN }, ++ [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1), + }; + + /* policy for the key attributes */ +@@ -4658,6 +4659,11 @@ static int nl80211_send_station(struct s + PUT_SINFO(PLID, plid, u16); + PUT_SINFO(PLINK_STATE, plink_state, u8); + PUT_SINFO_U64(RX_DURATION, rx_duration); ++ PUT_SINFO_U64(TX_DURATION, tx_duration); ++ ++ if (wiphy_ext_feature_isset(&rdev->wiphy, ++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) ++ PUT_SINFO(AIRTIME_WEIGHT, airtime_weight, u16); + + switch (rdev->wiphy.signal_type) { + case CFG80211_SIGNAL_TYPE_MBM: +@@ -5294,6 +5300,15 @@ static int nl80211_set_station(struct sk + nla_get_u8(info->attrs[NL80211_ATTR_OPMODE_NOTIF]); + } + ++ if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]) ++ params.airtime_weight = ++ nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]); ++ ++ if (params.airtime_weight && ++ !wiphy_ext_feature_isset(&rdev->wiphy, ++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) ++ return -EOPNOTSUPP; ++ + /* Include parameters for TDLS peer (will check later) */ + err = nl80211_set_station_tdls(info, ¶ms); + if (err) +@@ -5432,6 +5447,15 @@ static int nl80211_new_station(struct sk + return -EINVAL; + } + ++ if (info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]) ++ params.airtime_weight = ++ nla_get_u16(info->attrs[NL80211_ATTR_AIRTIME_WEIGHT]); ++ ++ if (params.airtime_weight && ++ !wiphy_ext_feature_isset(&rdev->wiphy, ++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) ++ return -EOPNOTSUPP; ++ + err = nl80211_parse_sta_channel_info(info, ¶ms); + if (err) + return err; diff --git a/package/kernel/mac80211/patches/subsys/322-mac80211-Add-airtime-accounting-and-scheduling-to-TX.patch b/package/kernel/mac80211/patches/subsys/322-mac80211-Add-airtime-accounting-and-scheduling-to-TX.patch new file mode 100644 index 0000000000..d4176eb491 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/322-mac80211-Add-airtime-accounting-and-scheduling-to-TX.patch @@ -0,0 +1,522 @@ +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Tue, 18 Dec 2018 17:02:08 -0800 +Subject: [PATCH] mac80211: Add airtime accounting and scheduling to TXQs +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This adds airtime accounting and scheduling to the mac80211 TXQ +scheduler. A new callback, ieee80211_sta_register_airtime(), is added +that drivers can call to report airtime usage for stations. + +When airtime information is present, mac80211 will schedule TXQs +(through ieee80211_next_txq()) in a way that enforces airtime fairness +between active stations. This scheduling works the same way as the ath9k +in-driver airtime fairness scheduling. If no airtime usage is reported +by the driver, the scheduler will default to round-robin scheduling. + +For drivers that don't control TXQ scheduling in software, a new API +function, ieee80211_txq_may_transmit(), is added which the driver can use +to check if the TXQ is eligible for transmission, or should be throttled to +enforce fairness. Calls to this function must also be enclosed in +ieee80211_txq_schedule_{start,end}() calls to ensure proper locking. + +The API ieee80211_txq_may_transmit() also ensures that TXQ list will be +aligned aginst driver's own round-robin scheduler list. i.e it rotates +the TXQ list till it makes the requested node becomes the first entry +in TXQ list. Thus both the TXQ list and driver's list are in sync. + +Co-developed-by: Rajkumar Manoharan +Signed-off-by: Louie Lu +[added debugfs write op to reset airtime counter] +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: Rajkumar Manoharan +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2304,6 +2304,9 @@ enum ieee80211_hw_flags { + * supported by HW. + * @max_nan_de_entries: maximum number of NAN DE functions supported by the + * device. ++ * ++ * @weight_multipler: Driver specific airtime weight multiplier used while ++ * refilling deficit of each TXQ. + */ + struct ieee80211_hw { + struct ieee80211_conf conf; +@@ -2339,6 +2342,7 @@ struct ieee80211_hw { + u8 n_cipher_schemes; + const struct ieee80211_cipher_scheme *cipher_schemes; + u8 max_nan_de_entries; ++ u8 weight_multiplier; + }; + + static inline bool _ieee80211_hw_check(struct ieee80211_hw *hw, +@@ -5299,6 +5303,34 @@ void ieee80211_sta_eosp(struct ieee80211 + void ieee80211_send_eosp_nullfunc(struct ieee80211_sta *pubsta, int tid); + + /** ++ * ieee80211_sta_register_airtime - register airtime usage for a sta/tid ++ * ++ * Register airtime usage for a given sta on a given tid. The driver can call ++ * this function to notify mac80211 that a station used a certain amount of ++ * airtime. This information will be used by the TXQ scheduler to schedule ++ * stations in a way that ensures airtime fairness. ++ * ++ * The reported airtime should as a minimum include all time that is spent ++ * transmitting to the remote station, including overhead and padding, but not ++ * including time spent waiting for a TXOP. If the time is not reported by the ++ * hardware it can in some cases be calculated from the rate and known frame ++ * composition. When possible, the time should include any failed transmission ++ * attempts. ++ * ++ * The driver can either call this function synchronously for every packet or ++ * aggregate, or asynchronously as airtime usage information becomes available. ++ * TX and RX airtime can be reported together, or separately by setting one of ++ * them to 0. ++ * ++ * @pubsta: the station ++ * @tid: the TID to register airtime for ++ * @tx_airtime: airtime used during TX (in usec) ++ * @rx_airtime: airtime used during RX (in usec) ++ */ ++void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, ++ u32 tx_airtime, u32 rx_airtime); ++ ++/** + * ieee80211_iter_keys - iterate keys programmed into the device + * @hw: pointer obtained from ieee80211_alloc_hw() + * @vif: virtual interface to iterate, may be %NULL for all +@@ -6042,6 +6074,33 @@ void ieee80211_txq_schedule_end(struct i + __releases(txq_lock); + + /** ++ * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit ++ * ++ * This function is used to check whether given txq is allowed to transmit by ++ * the airtime scheduler, and can be used by drivers to access the airtime ++ * fairness accounting without going using the scheduling order enfored by ++ * next_txq(). ++ * ++ * Returns %true if the airtime scheduler thinks the TXQ should be allowed to ++ * transmit, and %false if it should be throttled. This function can also have ++ * the side effect of rotating the TXQ in the scheduler rotation, which will ++ * eventually bring the deficit to positive and allow the station to transmit ++ * again. ++ * ++ * The API ieee80211_txq_may_transmit() also ensures that TXQ list will be ++ * aligned aginst driver's own round-robin scheduler list. i.e it rotates ++ * the TXQ list till it makes the requested node becomes the first entry ++ * in TXQ list. Thus both the TXQ list and driver's list are in sync. If this ++ * function returns %true, the driver is expected to schedule packets ++ * for transmission, and then return the TXQ through ieee80211_return_txq(). ++ * ++ * @hw: pointer as obtained from ieee80211_alloc_hw() ++ * @txq: pointer obtained from station or virtual interface ++ */ ++bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq); ++ ++/** + * ieee80211_txq_get_depth - get pending frame/byte count of given txq + * + * The values are not guaranteed to be coherent with regard to each other, i.e. +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1434,6 +1434,9 @@ static int sta_apply_parameters(struct i + if (ieee80211_vif_is_mesh(&sdata->vif)) + sta_apply_mesh_params(local, sta, params); + ++ if (params->airtime_weight) ++ sta->airtime_weight = params->airtime_weight; ++ + /* set the STA state after all sta info from usermode has been set */ + if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) || + set & BIT(NL80211_STA_FLAG_ASSOCIATED)) { +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -380,6 +380,9 @@ void debugfs_hw_add(struct ieee80211_loc + if (local->ops->wake_tx_queue) + DEBUGFS_ADD_MODE(aqm, 0600); + ++ debugfs_create_u16("airtime_flags", 0600, ++ phyd, &local->airtime_flags); ++ + statsd = debugfs_create_dir("statistics", phyd); + + /* if the dir failed, don't put all the other things into the root! */ +--- a/net/mac80211/debugfs_sta.c ++++ b/net/mac80211/debugfs_sta.c +@@ -178,9 +178,9 @@ static ssize_t sta_aqm_read(struct file + txqi->tin.tx_bytes, + txqi->tin.tx_packets, + txqi->flags, +- txqi->flags & (1<flags & (1<flags & (1<flags) ? "STOP" : "RUN", ++ test_bit(IEEE80211_TXQ_AMPDU, &txqi->flags) ? " AMPDU" : "", ++ test_bit(IEEE80211_TXQ_NO_AMSDU, &txqi->flags) ? " NO-AMSDU" : ""); + } + + rcu_read_unlock(); +@@ -192,6 +192,64 @@ static ssize_t sta_aqm_read(struct file + } + STA_OPS(aqm); + ++static ssize_t sta_airtime_read(struct file *file, char __user *userbuf, ++ size_t count, loff_t *ppos) ++{ ++ struct sta_info *sta = file->private_data; ++ struct ieee80211_local *local = sta->sdata->local; ++ size_t bufsz = 200; ++ char *buf = kzalloc(bufsz, GFP_KERNEL), *p = buf; ++ u64 rx_airtime = 0, tx_airtime = 0; ++ s64 deficit[IEEE80211_NUM_ACS]; ++ ssize_t rv; ++ int ac; ++ ++ if (!buf) ++ return -ENOMEM; ++ ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { ++ spin_lock_bh(&local->active_txq_lock[ac]); ++ rx_airtime += sta->airtime[ac].rx_airtime; ++ tx_airtime += sta->airtime[ac].tx_airtime; ++ deficit[ac] = sta->airtime[ac].deficit; ++ spin_unlock_bh(&local->active_txq_lock[ac]); ++ } ++ ++ p += scnprintf(p, bufsz + buf - p, ++ "RX: %llu us\nTX: %llu us\nWeight: %u\n" ++ "Deficit: VO: %lld us VI: %lld us BE: %lld us BK: %lld us\n", ++ rx_airtime, ++ tx_airtime, ++ sta->airtime_weight, ++ deficit[0], ++ deficit[1], ++ deficit[2], ++ deficit[3]); ++ ++ rv = simple_read_from_buffer(userbuf, count, ppos, buf, p - buf); ++ kfree(buf); ++ return rv; ++} ++ ++static ssize_t sta_airtime_write(struct file *file, const char __user *userbuf, ++ size_t count, loff_t *ppos) ++{ ++ struct sta_info *sta = file->private_data; ++ struct ieee80211_local *local = sta->sdata->local; ++ int ac; ++ ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) { ++ spin_lock_bh(&local->active_txq_lock[ac]); ++ sta->airtime[ac].rx_airtime = 0; ++ sta->airtime[ac].tx_airtime = 0; ++ sta->airtime[ac].deficit = sta->airtime_weight; ++ spin_unlock_bh(&local->active_txq_lock[ac]); ++ } ++ ++ return count; ++} ++STA_OPS_RW(airtime); ++ + static ssize_t sta_agg_status_read(struct file *file, char __user *userbuf, + size_t count, loff_t *ppos) + { +@@ -546,6 +604,10 @@ void ieee80211_sta_debugfs_add(struct st + if (local->ops->wake_tx_queue) + DEBUGFS_ADD(aqm); + ++ if (wiphy_ext_feature_isset(local->hw.wiphy, ++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) ++ DEBUGFS_ADD(airtime); ++ + if (sizeof(sta->driver_buffered_tids) == sizeof(u32)) + debugfs_create_x32("driver_buffered_tids", 0400, + sta->debugfs_dir, +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -1136,6 +1136,8 @@ struct ieee80211_local { + struct list_head active_txqs[IEEE80211_NUM_ACS]; + u16 schedule_round[IEEE80211_NUM_ACS]; + ++ u16 airtime_flags; ++ + const struct ieee80211_ops *ops; + + /* +--- a/net/mac80211/main.c ++++ b/net/mac80211/main.c +@@ -656,6 +656,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ + INIT_LIST_HEAD(&local->active_txqs[i]); + spin_lock_init(&local->active_txq_lock[i]); + } ++ local->airtime_flags = AIRTIME_USE_TX | AIRTIME_USE_RX; + + INIT_LIST_HEAD(&local->chanctx_list); + mutex_init(&local->chanctx_mtx); +@@ -1142,6 +1143,9 @@ int ieee80211_register_hw(struct ieee802 + if (!local->hw.max_nan_de_entries) + local->hw.max_nan_de_entries = IEEE80211_MAX_NAN_INSTANCE_ID; + ++ if (!local->hw.weight_multiplier) ++ local->hw.weight_multiplier = 1; ++ + result = ieee80211_wep_init(local); + if (result < 0) + wiphy_debug(local->hw.wiphy, "Failed to initialize wep: %d\n", +--- a/net/mac80211/sta_info.c ++++ b/net/mac80211/sta_info.c +@@ -90,7 +90,6 @@ static void __cleanup_single_sta(struct + struct tid_ampdu_tx *tid_tx; + struct ieee80211_sub_if_data *sdata = sta->sdata; + struct ieee80211_local *local = sdata->local; +- struct fq *fq = &local->fq; + struct ps_data *ps; + + if (test_sta_flag(sta, WLAN_STA_PS_STA) || +@@ -115,9 +114,7 @@ static void __cleanup_single_sta(struct + for (i = 0; i < ARRAY_SIZE(sta->sta.txq); i++) { + struct txq_info *txqi = to_txq_info(sta->sta.txq[i]); + +- spin_lock_bh(&fq->lock); + ieee80211_txq_purge(local, txqi); +- spin_unlock_bh(&fq->lock); + } + } + +@@ -381,9 +378,12 @@ struct sta_info *sta_info_alloc(struct i + if (sta_prepare_rate_control(local, sta, gfp)) + goto free_txq; + ++ sta->airtime_weight = IEEE80211_DEFAULT_AIRTIME_WEIGHT; ++ + for (i = 0; i < IEEE80211_NUM_ACS; i++) { + skb_queue_head_init(&sta->ps_tx_buf[i]); + skb_queue_head_init(&sta->tx_filtered[i]); ++ sta->airtime[i].deficit = sta->airtime_weight; + } + + for (i = 0; i < IEEE80211_NUM_TIDS; i++) +@@ -1821,6 +1821,27 @@ void ieee80211_sta_set_buffered(struct i + } + EXPORT_SYMBOL(ieee80211_sta_set_buffered); + ++void ieee80211_sta_register_airtime(struct ieee80211_sta *pubsta, u8 tid, ++ u32 tx_airtime, u32 rx_airtime) ++{ ++ struct sta_info *sta = container_of(pubsta, struct sta_info, sta); ++ struct ieee80211_local *local = sta->sdata->local; ++ u8 ac = ieee80211_ac_from_tid(tid); ++ u32 airtime = 0; ++ ++ if (sta->local->airtime_flags & AIRTIME_USE_TX) ++ airtime += tx_airtime; ++ if (sta->local->airtime_flags & AIRTIME_USE_RX) ++ airtime += rx_airtime; ++ ++ spin_lock_bh(&local->active_txq_lock[ac]); ++ sta->airtime[ac].tx_airtime += tx_airtime; ++ sta->airtime[ac].rx_airtime += rx_airtime; ++ sta->airtime[ac].deficit -= airtime; ++ spin_unlock_bh(&local->active_txq_lock[ac]); ++} ++EXPORT_SYMBOL(ieee80211_sta_register_airtime); ++ + int sta_info_move_state(struct sta_info *sta, + enum ieee80211_sta_state new_state) + { +@@ -2183,6 +2204,23 @@ void sta_set_sinfo(struct sta_info *sta, + sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED); + } + ++ if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_RX_DURATION))) { ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) ++ sinfo->rx_duration += sta->airtime[ac].rx_airtime; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_DURATION); ++ } ++ ++ if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_TX_DURATION))) { ++ for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) ++ sinfo->tx_duration += sta->airtime[ac].tx_airtime; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_DURATION); ++ } ++ ++ if (!(sinfo->filled & BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT))) { ++ sinfo->airtime_weight = sta->airtime_weight; ++ sinfo->filled |= BIT_ULL(NL80211_STA_INFO_AIRTIME_WEIGHT); ++ } ++ + sinfo->rx_dropped_misc = sta->rx_stats.dropped; + if (sta->pcpu_rx_stats) { + for_each_possible_cpu(cpu) { +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -127,6 +127,16 @@ enum ieee80211_agg_stop_reason { + AGG_STOP_DESTROY_STA, + }; + ++/* Debugfs flags to enable/disable use of RX/TX airtime in scheduler */ ++#define AIRTIME_USE_TX BIT(0) ++#define AIRTIME_USE_RX BIT(1) ++ ++struct airtime_info { ++ u64 rx_airtime; ++ u64 tx_airtime; ++ s64 deficit; ++}; ++ + struct sta_info; + + /** +@@ -563,6 +573,9 @@ struct sta_info { + } tx_stats; + u16 tid_seq[IEEE80211_QOS_CTL_TID_MASK + 1]; + ++ struct airtime_info airtime[IEEE80211_NUM_ACS]; ++ u16 airtime_weight; ++ + /* + * Aggregation information, locked with lock. + */ +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -825,6 +825,12 @@ static void __ieee80211_tx_status(struct + ieee80211_sta_tx_notify(sta->sdata, (void *) skb->data, + acked, info->status.tx_time); + ++ if (info->status.tx_time && ++ wiphy_ext_feature_isset(local->hw.wiphy, ++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) ++ ieee80211_sta_register_airtime(&sta->sta, tid, ++ info->status.tx_time, 0); ++ + if (ieee80211_hw_check(&local->hw, REPORTS_TX_ACK_STATUS)) { + if (info->flags & IEEE80211_TX_STAT_ACK) { + if (sta->status_stats.lost_packets) +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1463,8 +1463,11 @@ void ieee80211_txq_purge(struct ieee8021 + struct fq *fq = &local->fq; + struct fq_tin *tin = &txqi->tin; + ++ spin_lock_bh(&fq->lock); + fq_tin_reset(fq, tin, fq_skb_free_func); + ieee80211_purge_tx_queue(&local->hw, &txqi->frags); ++ spin_unlock_bh(&fq->lock); ++ + spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]); + list_del_init(&txqi->schedule_order); + spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); +@@ -3613,11 +3616,28 @@ struct ieee80211_txq *ieee80211_next_txq + + lockdep_assert_held(&local->active_txq_lock[ac]); + ++ begin: + txqi = list_first_entry_or_null(&local->active_txqs[ac], + struct txq_info, + schedule_order); ++ if (!txqi) ++ return NULL; ++ ++ if (txqi->txq.sta) { ++ struct sta_info *sta = container_of(txqi->txq.sta, ++ struct sta_info, sta); ++ ++ if (sta->airtime[txqi->txq.ac].deficit < 0) { ++ sta->airtime[txqi->txq.ac].deficit += ++ sta->airtime_weight; ++ list_move_tail(&txqi->schedule_order, ++ &local->active_txqs[txqi->txq.ac]); ++ goto begin; ++ } ++ } ++ + +- if (!txqi || txqi->schedule_round == local->schedule_round[ac]) ++ if (txqi->schedule_round == local->schedule_round[ac]) + return NULL; + + list_del_init(&txqi->schedule_order); +@@ -3635,12 +3655,74 @@ void ieee80211_return_txq(struct ieee802 + lockdep_assert_held(&local->active_txq_lock[txq->ac]); + + if (list_empty(&txqi->schedule_order) && +- (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) +- list_add_tail(&txqi->schedule_order, +- &local->active_txqs[txq->ac]); ++ (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) { ++ /* If airtime accounting is active, always enqueue STAs at the ++ * head of the list to ensure that they only get moved to the ++ * back by the airtime DRR scheduler once they have a negative ++ * deficit. A station that already has a negative deficit will ++ * get immediately moved to the back of the list on the next ++ * call to ieee80211_next_txq(). ++ */ ++ if (txqi->txq.sta && ++ wiphy_ext_feature_isset(local->hw.wiphy, ++ NL80211_EXT_FEATURE_AIRTIME_FAIRNESS)) ++ list_add(&txqi->schedule_order, ++ &local->active_txqs[txq->ac]); ++ else ++ list_add_tail(&txqi->schedule_order, ++ &local->active_txqs[txq->ac]); ++ } + } + EXPORT_SYMBOL(ieee80211_return_txq); + ++bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct txq_info *iter, *tmp, *txqi = to_txq_info(txq); ++ struct sta_info *sta; ++ u8 ac = txq->ac; ++ ++ lockdep_assert_held(&local->active_txq_lock[ac]); ++ ++ if (!txqi->txq.sta) ++ goto out; ++ ++ if (list_empty(&txqi->schedule_order)) ++ goto out; ++ ++ list_for_each_entry_safe(iter, tmp, &local->active_txqs[ac], ++ schedule_order) { ++ if (iter == txqi) ++ break; ++ ++ if (!iter->txq.sta) { ++ list_move_tail(&iter->schedule_order, ++ &local->active_txqs[ac]); ++ continue; ++ } ++ sta = container_of(iter->txq.sta, struct sta_info, sta); ++ if (sta->airtime[ac].deficit < 0) ++ sta->airtime[ac].deficit += sta->airtime_weight; ++ list_move_tail(&iter->schedule_order, &local->active_txqs[ac]); ++ } ++ ++ sta = container_of(txqi->txq.sta, struct sta_info, sta); ++ if (sta->airtime[ac].deficit >= 0) ++ goto out; ++ ++ sta->airtime[ac].deficit += sta->airtime_weight; ++ list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); ++ ++ return false; ++out: ++ if (!list_empty(&txqi->schedule_order)) ++ list_del_init(&txqi->schedule_order); ++ ++ return true; ++} ++EXPORT_SYMBOL(ieee80211_txq_may_transmit); ++ + void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) + __acquires(txq_lock) + { diff --git a/package/kernel/mac80211/patches/subsys/323-mac80211-Expose-ieee80211_schedule_txq-function.patch b/package/kernel/mac80211/patches/subsys/323-mac80211-Expose-ieee80211_schedule_txq-function.patch new file mode 100644 index 0000000000..573f9bd135 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/323-mac80211-Expose-ieee80211_schedule_txq-function.patch @@ -0,0 +1,73 @@ +From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= +Date: Tue, 22 Jan 2019 15:20:16 +0100 +Subject: [PATCH] mac80211: Expose ieee80211_schedule_txq() function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Since we reworked ieee80211_return_txq() so it assumes that the caller +takes care of logging, we need another function that can be called without +holding any locks. Introduce ieee80211_schedule_txq() which serves this +purpose. + +Signed-off-by: Toke Høiland-Jørgensen +Signed-off-by: Johannes Berg +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -6074,6 +6074,19 @@ void ieee80211_txq_schedule_end(struct i + __releases(txq_lock); + + /** ++ * ieee80211_schedule_txq - schedule a TXQ for transmission ++ * ++ * @hw: pointer as obtained from ieee80211_alloc_hw() ++ * @txq: pointer obtained from station or virtual interface ++ * ++ * Schedules a TXQ for transmission if it is not already scheduled. Takes a ++ * lock, which means it must *not* be called between ++ * ieee80211_txq_schedule_start() and ieee80211_txq_schedule_end() ++ */ ++void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) ++ __acquires(txq_lock) __releases(txq_lock); ++ ++/** + * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit + * + * This function is used to check whether given txq is allowed to transmit by +--- a/net/mac80211/driver-ops.h ++++ b/net/mac80211/driver-ops.h +@@ -1179,9 +1179,7 @@ static inline void drv_wake_tx_queue(str + static inline void schedule_and_wake_txq(struct ieee80211_local *local, + struct txq_info *txqi) + { +- spin_lock_bh(&local->active_txq_lock[txqi->txq.ac]); +- ieee80211_return_txq(&local->hw, &txqi->txq); +- spin_unlock_bh(&local->active_txq_lock[txqi->txq.ac]); ++ ieee80211_schedule_txq(&local->hw, &txqi->txq); + drv_wake_tx_queue(local, txqi); + } + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3675,6 +3675,19 @@ void ieee80211_return_txq(struct ieee802 + } + EXPORT_SYMBOL(ieee80211_return_txq); + ++void ieee80211_schedule_txq(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq) ++ __acquires(txq_lock) __releases(txq_lock) ++{ ++ struct ieee80211_local *local = hw_to_local(hw); ++ struct txq_info *txqi = to_txq_info(txq); ++ ++ spin_lock_bh(&local->active_txq_lock[txq->ac]); ++ ieee80211_return_txq(hw, txq); ++ spin_unlock_bh(&local->active_txq_lock[txq->ac]); ++} ++EXPORT_SYMBOL(ieee80211_schedule_txq); ++ + bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) + { diff --git a/package/kernel/mac80211/patches/subsys/350-cfg80211-add-local-BSS-receive-time-to-survey-inform.patch b/package/kernel/mac80211/patches/subsys/350-cfg80211-add-local-BSS-receive-time-to-survey-inform.patch deleted file mode 100644 index af70b46fdc..0000000000 --- a/package/kernel/mac80211/patches/subsys/350-cfg80211-add-local-BSS-receive-time-to-survey-inform.patch +++ /dev/null @@ -1,77 +0,0 @@ -From: Felix Fietkau -Date: Wed, 28 Aug 2019 12:13:55 +0200 -Subject: [PATCH] cfg80211: add local BSS receive time to survey information - -This is useful for checking how much airtime is being used up by other -transmissions on the channel, e.g. by calculating (time_rx - time_bss_rx) -or (time_busy - time_bss_rx - time_tx) - -Signed-off-by: Felix Fietkau ---- - ---- a/include/net/cfg80211.h -+++ b/include/net/cfg80211.h -@@ -682,6 +682,7 @@ ieee80211_chandef_max_power(struct cfg80 - * @SURVEY_INFO_TIME_RX: receive time was filled in - * @SURVEY_INFO_TIME_TX: transmit time was filled in - * @SURVEY_INFO_TIME_SCAN: scan time was filled in -+ * @SURVEY_INFO_TIME_BSS_RX: local BSS receive time was filled in - * - * Used by the driver to indicate which info in &struct survey_info - * it has filled in during the get_survey(). -@@ -695,6 +696,7 @@ enum survey_info_flags { - SURVEY_INFO_TIME_RX = BIT(5), - SURVEY_INFO_TIME_TX = BIT(6), - SURVEY_INFO_TIME_SCAN = BIT(7), -+ SURVEY_INFO_TIME_BSS_RX = BIT(8), - }; - - /** -@@ -711,6 +713,7 @@ enum survey_info_flags { - * @time_rx: amount of time the radio spent receiving data - * @time_tx: amount of time the radio spent transmitting data - * @time_scan: amount of time the radio spent for scanning -+ * @time_bss_rx: amount of time the radio spent receiving data on a local BSS - * - * Used by dump_survey() to report back per-channel survey information. - * -@@ -725,6 +728,7 @@ struct survey_info { - u64 time_rx; - u64 time_tx; - u64 time_scan; -+ u64 time_bss_rx; - u32 filled; - s8 noise; - }; ---- a/include/uapi/linux/nl80211.h -+++ b/include/uapi/linux/nl80211.h -@@ -3836,6 +3836,8 @@ enum nl80211_user_reg_hint_type { - * @NL80211_SURVEY_INFO_TIME_SCAN: time the radio spent for scan - * (on this channel or globally) - * @NL80211_SURVEY_INFO_PAD: attribute used for padding for 64-bit alignment -+ * @NL80211_SURVEY_INFO_TIME_BSS_RX: amount of time the radio spent -+ * receiving local BSS data - * @NL80211_SURVEY_INFO_MAX: highest survey info attribute number - * currently defined - * @__NL80211_SURVEY_INFO_AFTER_LAST: internal use -@@ -3852,6 +3854,7 @@ enum nl80211_survey_info { - NL80211_SURVEY_INFO_TIME_TX, - NL80211_SURVEY_INFO_TIME_SCAN, - NL80211_SURVEY_INFO_PAD, -+ NL80211_SURVEY_INFO_TIME_BSS_RX, - - /* keep last */ - __NL80211_SURVEY_INFO_AFTER_LAST, ---- a/net/wireless/nl80211.c -+++ b/net/wireless/nl80211.c -@@ -8694,6 +8694,10 @@ static int nl80211_send_survey(struct sk - nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_SCAN, - survey->time_scan, NL80211_SURVEY_INFO_PAD)) - goto nla_put_failure; -+ if ((survey->filled & SURVEY_INFO_TIME_BSS_RX) && -+ nla_put_u64_64bit(msg, NL80211_SURVEY_INFO_TIME_BSS_RX, -+ survey->time_bss_rx, NL80211_SURVEY_INFO_PAD)) -+ goto nla_put_failure; - - nla_nest_end(msg, infoattr); - diff --git a/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch b/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch new file mode 100644 index 0000000000..2759895c98 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/350-mac80211-add-hdrlen-to-ieee80211_tx_data.patch @@ -0,0 +1,228 @@ +From: Janusz Dziedzic +Date: Fri, 19 Feb 2016 11:01:49 +0100 +Subject: [PATCH] mac80211: add hdrlen to ieee80211_tx_data + +This is preparation for adding support for inserting padding between the +802.11 header and LLC data + +Signed-off-by: Janusz Dziedzic +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/ieee80211_i.h ++++ b/net/mac80211/ieee80211_i.h +@@ -179,6 +179,7 @@ struct ieee80211_tx_data { + struct ieee80211_tx_rate rate; + + unsigned int flags; ++ unsigned int hdrlen; + }; + + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -925,7 +925,7 @@ ieee80211_tx_h_fragment(struct ieee80211 + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; + int frag_threshold = tx->local->hw.wiphy->frag_threshold; +- int hdrlen; ++ int hdrlen = tx->hdrlen; + int fragnum; + + /* no matter what happens, tx->skb moves to tx->skbs */ +@@ -946,8 +946,6 @@ ieee80211_tx_h_fragment(struct ieee80211 + if (WARN_ON(info->flags & IEEE80211_TX_CTL_AMPDU)) + return TX_DROP; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); +- + /* internal error, why isn't DONTFRAG set? */ + if (WARN_ON(skb->len + FCS_LEN <= frag_threshold)) + return TX_DROP; +@@ -1178,6 +1176,8 @@ ieee80211_tx_prepare(struct ieee80211_su + + hdr = (struct ieee80211_hdr *) skb->data; + ++ tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ + if (likely(sta)) { + if (!IS_ERR(sta)) + tx->sta = sta; +@@ -3525,6 +3525,7 @@ begin: + tx.local = local; + tx.skb = skb; + tx.sdata = vif_to_sdata(info->control.vif); ++ tx.hdrlen = ieee80211_hdrlen(hdr->frame_control); + + if (txq->sta) + tx.sta = container_of(txq->sta, struct sta_info, sta); +@@ -3551,7 +3552,7 @@ begin: + + if (tx.key && + (tx.key->conf.flags & IEEE80211_KEY_FLAG_GENERATE_IV)) +- pn_offs = ieee80211_hdrlen(hdr->frame_control); ++ pn_offs = tx.hdrlen; + + ieee80211_xmit_fast_finish(sta->sdata, sta, pn_offs, + tx.key, skb); +@@ -4008,6 +4009,7 @@ ieee80211_build_data_template(struct iee + hdr = (void *)skb->data; + tx.sta = sta_info_get(sdata, hdr->addr1); + tx.skb = skb; ++ tx.hdrlen = ieee80211_hdrlen(hdr->frame_control); + + if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) { + rcu_read_unlock(); +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -1390,6 +1390,7 @@ void ieee80211_send_auth(struct ieee8021 + struct ieee80211_local *local = sdata->local; + struct sk_buff *skb; + struct ieee80211_mgmt *mgmt; ++ unsigned int hdrlen; + int err; + + /* 24 + 6 = header + auth_algo + auth_transaction + status_code */ +@@ -1413,8 +1414,10 @@ void ieee80211_send_auth(struct ieee8021 + skb_put_data(skb, extra, extra_len); + + if (auth_alg == WLAN_AUTH_SHARED_KEY && transaction == 3) { ++ hdrlen = ieee80211_hdrlen(mgmt->frame_control); + mgmt->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); +- err = ieee80211_wep_encrypt(local, skb, key, key_len, key_idx); ++ err = ieee80211_wep_encrypt(local, skb, hdrlen, key, ++ key_len, key_idx); + WARN_ON(err); + } + +--- a/net/mac80211/wep.c ++++ b/net/mac80211/wep.c +@@ -89,11 +89,11 @@ static void ieee80211_wep_get_iv(struct + + static u8 *ieee80211_wep_add_iv(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + int keylen, int keyidx) + { + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); +- unsigned int hdrlen; + u8 *newhdr; + + hdr->frame_control |= cpu_to_le16(IEEE80211_FCTL_PROTECTED); +@@ -101,7 +101,6 @@ static u8 *ieee80211_wep_add_iv(struct i + if (WARN_ON(skb_headroom(skb) < IEEE80211_WEP_IV_LEN)) + return NULL; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); + newhdr = skb_push(skb, IEEE80211_WEP_IV_LEN); + memmove(newhdr, newhdr + IEEE80211_WEP_IV_LEN, hdrlen); + +@@ -160,6 +159,7 @@ int ieee80211_wep_encrypt_data(struct cr + */ + int ieee80211_wep_encrypt(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + const u8 *key, int keylen, int keyidx) + { + u8 *iv; +@@ -169,7 +169,7 @@ int ieee80211_wep_encrypt(struct ieee802 + if (WARN_ON(skb_tailroom(skb) < IEEE80211_WEP_ICV_LEN)) + return -1; + +- iv = ieee80211_wep_add_iv(local, skb, keylen, keyidx); ++ iv = ieee80211_wep_add_iv(local, skb, hdrlen, keylen, keyidx); + if (!iv) + return -1; + +@@ -307,13 +307,14 @@ static int wep_encrypt_skb(struct ieee80 + struct ieee80211_key_conf *hw_key = info->control.hw_key; + + if (!hw_key) { +- if (ieee80211_wep_encrypt(tx->local, skb, tx->key->conf.key, ++ if (ieee80211_wep_encrypt(tx->local, skb, tx->hdrlen, ++ tx->key->conf.key, + tx->key->conf.keylen, + tx->key->conf.keyidx)) + return -1; + } else if ((hw_key->flags & IEEE80211_KEY_FLAG_GENERATE_IV) || + (hw_key->flags & IEEE80211_KEY_FLAG_PUT_IV_SPACE)) { +- if (!ieee80211_wep_add_iv(tx->local, skb, ++ if (!ieee80211_wep_add_iv(tx->local, skb, tx->hdrlen, + tx->key->conf.keylen, + tx->key->conf.keyidx)) + return -1; +--- a/net/mac80211/wep.h ++++ b/net/mac80211/wep.h +@@ -22,6 +22,7 @@ int ieee80211_wep_encrypt_data(struct cr + size_t klen, u8 *data, size_t data_len); + int ieee80211_wep_encrypt(struct ieee80211_local *local, + struct sk_buff *skb, ++ unsigned int hdrlen, + const u8 *key, int keylen, int keyidx); + int ieee80211_wep_decrypt_data(struct crypto_cipher *tfm, u8 *rc4key, + size_t klen, u8 *data, size_t data_len); +--- a/net/mac80211/wpa.c ++++ b/net/mac80211/wpa.c +@@ -44,7 +44,7 @@ ieee80211_tx_h_michael_mic_add(struct ie + skb->len < 24 || !ieee80211_is_data_present(hdr->frame_control)) + return TX_CONTINUE; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + if (skb->len < hdrlen) + return TX_DROP; + +@@ -195,7 +195,6 @@ mic_fail_no_key: + + static int tkip_encrypt_skb(struct ieee80211_tx_data *tx, struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + struct ieee80211_key *key = tx->key; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + unsigned int hdrlen; +@@ -210,7 +209,7 @@ static int tkip_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -428,7 +427,7 @@ static int ccmp_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -660,7 +659,7 @@ static int gcmp_encrypt_skb(struct ieee8 + return 0; + } + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = tx->hdrlen; + len = skb->len - hdrlen; + + if (info->control.hw_key) +@@ -800,7 +799,6 @@ static ieee80211_tx_result + ieee80211_crypto_cs_encrypt(struct ieee80211_tx_data *tx, + struct sk_buff *skb) + { +- struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; + struct ieee80211_key *key = tx->key; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + int hdrlen; +@@ -816,8 +814,7 @@ ieee80211_crypto_cs_encrypt(struct ieee8 + pskb_expand_head(skb, iv_len, 0, GFP_ATOMIC))) + return TX_DROP; + +- hdrlen = ieee80211_hdrlen(hdr->frame_control); +- ++ hdrlen = tx->hdrlen; + pos = skb_push(skb, iv_len); + memmove(pos, pos + iv_len, hdrlen); + diff --git a/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch b/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch new file mode 100644 index 0000000000..d8dbecca1b --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/351-mac80211-add-TX_NEEDS_ALIGNED4_SKBS-hw-flag.patch @@ -0,0 +1,304 @@ +From: Janusz Dziedzic +Date: Sun, 10 Mar 2019 17:22:08 +0100 +Subject: [PATCH] mac80211: add TX_NEEDS_ALIGNED4_SKBS hw flag + +The driver should set this flag if the hardware requires tx skb data +(starting with the LLC header) to be aligned to 4 bytes. + +Padding is added after ieee80211_hdr, before IV/LLC. + +Before this patch, we have to do memmove(hdrlen) twice in the driver: +Once before we pass this to HW and once again in tx completion +(to fix up the skb for monitor mode). + +With this patch we can skip this memmove() and thus reduce CPU cycles in +the data path. + +Signed-off-by: Janusz Dziedzic +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -2140,6 +2140,9 @@ struct ieee80211_txq { + * @IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN: Driver does not report accurate A-MPDU + * length in tx status information + * ++ * @IEEE80211_HW_TX_NEEDS_ALIGNED4_SKBS: Driver need aligned skbs to four-byte. ++ * Padding will be added after ieee80211_hdr, before IV/LLC. ++ * + * @NUM_IEEE80211_HW_FLAGS: number of hardware flags, used for sizing arrays + */ + enum ieee80211_hw_flags { +@@ -2186,6 +2189,7 @@ enum ieee80211_hw_flags { + IEEE80211_HW_DEAUTH_NEED_MGD_TX_PREP, + IEEE80211_HW_DOESNT_SUPPORT_QOS_NDP, + IEEE80211_HW_TX_STATUS_NO_AMPDU_LEN, ++ IEEE80211_HW_TX_NEEDS_ALIGNED4_SKBS, + + /* keep last, obviously */ + NUM_IEEE80211_HW_FLAGS +@@ -2472,6 +2476,40 @@ ieee80211_get_alt_retry_rate(const struc + void ieee80211_free_txskb(struct ieee80211_hw *hw, struct sk_buff *skb); + + /** ++ * ieee80211_hdr_padsize - get size of padding between 802.11 header and LLC ++ * @hw: the hardware ++ * @hdrlen: 802.11 header length ++ */ ++static inline unsigned int ++ieee80211_hdr_padsize(struct ieee80211_hw *hw, unsigned int hdrlen) ++{ ++ /* ++ * While hdrlen is already aligned to two-byte boundaries, ++ * simple check with & 2 will return correct padsize. ++ */ ++ if (ieee80211_hw_check(hw, TX_NEEDS_ALIGNED4_SKBS)) ++ return hdrlen & 2; ++ return 0; ++} ++ ++/** ++ * ieee80211_padded_hdrlen - get padded 802.11 header size ++ * @hw: the hardware ++ * @fc: frame control field in little-endian format ++ */ ++static inline unsigned int ++ieee80211_padded_hdrlen(struct ieee80211_hw *hw, __le16 fc) ++{ ++ unsigned int hdrlen; ++ ++ hdrlen = ieee80211_hdrlen(fc); ++ hdrlen += ieee80211_hdr_padsize(hw, hdrlen); ++ ++ return hdrlen; ++} ++ ++ ++/** + * DOC: Hardware crypto acceleration + * + * mac80211 is capable of taking advantage of many hardware +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -1871,6 +1871,10 @@ int ieee80211_if_add(struct ieee80211_lo + + 8 /* rfc1042/bridge tunnel */ + - ETH_HLEN /* ethernet hard_header_len */ + + IEEE80211_ENCRYPT_HEADROOM; ++ ++ if (ieee80211_hw_check(&local->hw, TX_NEEDS_ALIGNED4_SKBS)) ++ ndev->needed_headroom += 2; /* padding */ ++ + ndev->needed_tailroom = IEEE80211_ENCRYPT_TAILROOM; + + ret = dev_alloc_name(ndev, ndev->name); +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -105,13 +105,15 @@ void mesh_path_assign_nexthop(struct mes + static void prepare_for_gate(struct sk_buff *skb, char *dst_addr, + struct mesh_path *gate_mpath) + { ++ struct ieee80211_sub_if_data *sdata = gate_mpath->sdata; ++ struct ieee80211_hw *hw = &sdata->local->hw; + struct ieee80211_hdr *hdr; + struct ieee80211s_hdr *mshdr; + int mesh_hdrlen, hdrlen; + char *next_hop; + + hdr = (struct ieee80211_hdr *) skb->data; +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control); + mshdr = (struct ieee80211s_hdr *) (skb->data + hdrlen); + + if (!(mshdr->flags & MESH_FLAGS_AE)) { +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -2597,7 +2597,7 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + struct ieee80211_local *local = rx->local; + struct ieee80211_sub_if_data *sdata = rx->sdata; + struct ieee80211_if_mesh *ifmsh = &sdata->u.mesh; +- u16 ac, q, hdrlen; ++ u16 ac, q, hdrlen, padsize; + int tailroom = 0; + + hdr = (struct ieee80211_hdr *) skb->data; +@@ -2690,7 +2690,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + if (sdata->crypto_tx_tailroom_needed_cnt) + tailroom = IEEE80211_ENCRYPT_TAILROOM; + +- fwd_skb = skb_copy_expand(skb, local->tx_headroom + ++ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); ++ ++ fwd_skb = skb_copy_expand(skb, local->tx_headroom + padsize + + sdata->encrypt_headroom, + tailroom, GFP_ATOMIC); + if (!fwd_skb) +@@ -2722,6 +2724,12 @@ ieee80211_rx_h_mesh_fwding(struct ieee80 + return RX_DROP_MONITOR; + } + ++ if (padsize) { ++ skb_push(fwd_skb, padsize); ++ memmove(fwd_skb->data, skb->data + padsize, hdrlen); ++ memset(fwd_skb->data + hdrlen, 0, padsize); ++ } ++ + IEEE80211_IFSTA_MESH_CTR_INC(ifmsh, fwded_frames); + ieee80211_add_pending_skb(local, fwd_skb); + out: +--- a/net/mac80211/sta_info.h ++++ b/net/mac80211/sta_info.h +@@ -311,7 +311,7 @@ struct ieee80211_fast_tx { + u8 hdr_len; + u8 sa_offs, da_offs, pn_offs; + u8 band; +- u8 hdr[30 + 2 + IEEE80211_FAST_XMIT_MAX_IV + ++ u8 hdr[30 + 2 + 2 + IEEE80211_FAST_XMIT_MAX_IV + + sizeof(rfc1042_header)] __aligned(2); + + struct rcu_head rcu_head; +--- a/net/mac80211/status.c ++++ b/net/mac80211/status.c +@@ -515,6 +515,7 @@ static void ieee80211_report_used_skb(st + { + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_hdr *hdr = (void *)skb->data; ++ struct ieee80211_hw *hw = &local->hw; + bool acked = info->flags & IEEE80211_TX_STAT_ACK; + + if (dropped) +@@ -531,7 +532,7 @@ static void ieee80211_report_used_skb(st + skb->dev = NULL; + } else { + unsigned int hdr_size = +- ieee80211_hdrlen(hdr->frame_control); ++ ieee80211_padded_hdrlen(hw, hdr->frame_control); + + /* Check to see if packet is a TDLS teardown packet */ + if (ieee80211_is_data(hdr->frame_control) && +@@ -655,9 +656,22 @@ void ieee80211_tx_monitor(struct ieee802 + struct sk_buff *skb2; + struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); + struct ieee80211_sub_if_data *sdata; ++ struct ieee80211_hdr *hdr = (void *)skb->data; + struct net_device *prev_dev = NULL; ++ unsigned int hdrlen, padsize; + int rtap_len; + ++ /* Remove padding if was added */ ++ if (ieee80211_hw_check(&local->hw, TX_NEEDS_ALIGNED4_SKBS)) { ++ hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); ++ ++ if (padsize && skb->len > hdrlen + padsize) { ++ memmove(skb->data + padsize, skb->data, hdrlen); ++ skb_pull(skb, padsize); ++ } ++ } ++ + /* send frame to monitor interfaces now */ + rtap_len = ieee80211_tx_radiotap_len(info); + if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { +--- a/net/mac80211/tkip.c ++++ b/net/mac80211/tkip.c +@@ -201,10 +201,12 @@ void ieee80211_get_tkip_p2k(struct ieee8 + { + struct ieee80211_key *key = (struct ieee80211_key *) + container_of(keyconf, struct ieee80211_key, conf); ++ struct ieee80211_hw *hw = &key->local->hw; + const u8 *tk = &key->conf.key[NL80211_TKIP_DATA_OFFSET_ENCR_KEY]; + struct tkip_ctx *ctx = &key->u.tkip.tx; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data; +- const u8 *data = (u8 *)hdr + ieee80211_hdrlen(hdr->frame_control); ++ const u8 *data = (u8 *)hdr + ieee80211_padded_hdrlen(hw, ++ hdr->frame_control); + u32 iv32 = get_unaligned_le32(&data[4]); + u16 iv16 = data[2] | (data[0] << 8); + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1175,8 +1175,7 @@ ieee80211_tx_prepare(struct ieee80211_su + info->flags &= ~IEEE80211_TX_INTFL_NEED_TXPROCESSING; + + hdr = (struct ieee80211_hdr *) skb->data; +- +- tx->hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ tx->hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); + + if (likely(sta)) { + if (!IS_ERR(sta)) +@@ -2222,7 +2221,7 @@ netdev_tx_t ieee80211_monitor_start_xmit + goto fail; + + hdr = (struct ieee80211_hdr *)(skb->data + len_rthdr); +- hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ hdrlen = ieee80211_padded_hdrlen(&local->hw, hdr->frame_control); + + if (skb->len < len_rthdr + hdrlen) + goto fail; +@@ -2440,7 +2439,7 @@ static struct sk_buff *ieee80211_build_h + struct ieee80211_chanctx_conf *chanctx_conf; + struct ieee80211_sub_if_data *ap_sdata; + enum nl80211_band band; +- int ret; ++ int padsize, ret; + + if (IS_ERR(sta)) + sta = NULL; +@@ -2739,7 +2738,9 @@ static struct sk_buff *ieee80211_build_h + } + + skb_pull(skb, skip_header_bytes); ++ padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); + head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); ++ head_need += padsize; + + /* + * So we need to modify the skb header and hence need a copy of +@@ -2772,6 +2773,9 @@ static struct sk_buff *ieee80211_build_h + memcpy(skb_push(skb, meshhdrlen), &mesh_hdr, meshhdrlen); + #endif + ++ if (padsize) ++ memset(skb_push(skb, padsize), 0, padsize); ++ + if (ieee80211_is_data_qos(fc)) { + __le16 *qos_control; + +@@ -2947,6 +2951,8 @@ void ieee80211_check_fast_xmit(struct st + fc |= cpu_to_le16(IEEE80211_STYPE_QOS_DATA); + } + ++ build.hdr_len += ieee80211_hdr_padsize(&local->hw, build.hdr_len); ++ + /* We store the key here so there's no point in using rcu_dereference() + * but that's fine because the code that changes the pointers will call + * this function after doing so. For a single CPU that would be enough, +@@ -3525,7 +3531,7 @@ begin: + tx.local = local; + tx.skb = skb; + tx.sdata = vif_to_sdata(info->control.vif); +- tx.hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ tx.hdrlen = ieee80211_padded_hdrlen(hw, hdr->frame_control); + + if (txq->sta) + tx.sta = container_of(txq->sta, struct sta_info, sta); +@@ -4009,7 +4015,7 @@ ieee80211_build_data_template(struct iee + hdr = (void *)skb->data; + tx.sta = sta_info_get(sdata, hdr->addr1); + tx.skb = skb; +- tx.hdrlen = ieee80211_hdrlen(hdr->frame_control); ++ tx.hdrlen = ieee80211_padded_hdrlen(&tx.local->hw, hdr->frame_control); + + if (ieee80211_tx_h_select_key(&tx) != TX_CONTINUE) { + rcu_read_unlock(); +--- a/net/mac80211/debugfs.c ++++ b/net/mac80211/debugfs.c +@@ -215,6 +215,7 @@ static const char *hw_flag_names[] = { + FLAG(DEAUTH_NEED_MGD_TX_PREP), + FLAG(DOESNT_SUPPORT_QOS_NDP), + FLAG(TX_STATUS_NO_AMPDU_LEN), ++ FLAG(TX_NEEDS_ALIGNED4_SKBS), + #undef FLAG + }; + diff --git a/package/kernel/mac80211/patches/subsys/352-mac80211-rework-locking-for-txq-scheduling-airtime-f.patch b/package/kernel/mac80211/patches/subsys/352-mac80211-rework-locking-for-txq-scheduling-airtime-f.patch new file mode 100644 index 0000000000..ef67dd1977 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/352-mac80211-rework-locking-for-txq-scheduling-airtime-f.patch @@ -0,0 +1,214 @@ +From: Felix Fietkau +Date: Wed, 13 Mar 2019 19:09:22 +0100 +Subject: [PATCH] mac80211: rework locking for txq scheduling / airtime + fairness + +Holding the lock around the entire duration of tx scheduling can create +some nasty lock contention, especially when processing airtime information +from the tx status or the rx path. +Improve locking by only holding the active_txq_lock for lookups / scheduling +list modifications. + +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -6069,8 +6069,6 @@ struct sk_buff *ieee80211_tx_dequeue(str + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @ac: AC number to return packets from. + * +- * Should only be called between calls to ieee80211_txq_schedule_start() +- * and ieee80211_txq_schedule_end(). + * Returns the next txq if successful, %NULL if no queue is eligible. If a txq + * is returned, it should be returned with ieee80211_return_txq() after the + * driver has finished scheduling it. +@@ -6078,51 +6076,41 @@ struct sk_buff *ieee80211_tx_dequeue(str + struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac); + + /** +- * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq() +- * +- * @hw: pointer as obtained from ieee80211_alloc_hw() +- * @txq: pointer obtained from station or virtual interface +- * +- * Should only be called between calls to ieee80211_txq_schedule_start() +- * and ieee80211_txq_schedule_end(). +- */ +-void ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); +- +-/** +- * ieee80211_txq_schedule_start - acquire locks for safe scheduling of an AC ++ * ieee80211_txq_schedule_start - start new scheduling round for TXQs + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @ac: AC number to acquire locks for + * +- * Acquire locks needed to schedule TXQs from the given AC. Should be called +- * before ieee80211_next_txq() or ieee80211_return_txq(). ++ * Should be called before ieee80211_next_txq() or ieee80211_return_txq(). + */ +-void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) +- __acquires(txq_lock); ++void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac); ++ ++/* (deprecated) */ ++static inline void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac) ++{ ++} + + /** +- * ieee80211_txq_schedule_end - release locks for safe scheduling of an AC ++ * ieee80211_schedule_txq - schedule a TXQ for transmission + * + * @hw: pointer as obtained from ieee80211_alloc_hw() +- * @ac: AC number to acquire locks for ++ * @txq: pointer obtained from station or virtual interface + * +- * Release locks previously acquired by ieee80211_txq_schedule_end(). ++ * Schedules a TXQ for transmission if it is not already scheduled. + */ +-void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac) +- __releases(txq_lock); ++void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); + + /** +- * ieee80211_schedule_txq - schedule a TXQ for transmission ++ * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq() + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @txq: pointer obtained from station or virtual interface +- * +- * Schedules a TXQ for transmission if it is not already scheduled. Takes a +- * lock, which means it must *not* be called between +- * ieee80211_txq_schedule_start() and ieee80211_txq_schedule_end() + */ +-void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) +- __acquires(txq_lock) __releases(txq_lock); ++static inline void ++ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) ++{ ++ ieee80211_schedule_txq(hw, txq); ++} + + /** + * ieee80211_txq_may_transmit - check whether TXQ is allowed to transmit +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3619,16 +3619,17 @@ EXPORT_SYMBOL(ieee80211_tx_dequeue); + struct ieee80211_txq *ieee80211_next_txq(struct ieee80211_hw *hw, u8 ac) + { + struct ieee80211_local *local = hw_to_local(hw); ++ struct ieee80211_txq *ret = NULL; + struct txq_info *txqi = NULL; + +- lockdep_assert_held(&local->active_txq_lock[ac]); ++ spin_lock_bh(&local->active_txq_lock[ac]); + + begin: + txqi = list_first_entry_or_null(&local->active_txqs[ac], + struct txq_info, + schedule_order); + if (!txqi) +- return NULL; ++ goto out; + + if (txqi->txq.sta) { + struct sta_info *sta = container_of(txqi->txq.sta, +@@ -3645,21 +3646,25 @@ struct ieee80211_txq *ieee80211_next_txq + + + if (txqi->schedule_round == local->schedule_round[ac]) +- return NULL; ++ goto out; + + list_del_init(&txqi->schedule_order); + txqi->schedule_round = local->schedule_round[ac]; +- return &txqi->txq; ++ ret = &txqi->txq; ++ ++out: ++ spin_unlock_bh(&local->active_txq_lock[ac]); ++ return ret; + } + EXPORT_SYMBOL(ieee80211_next_txq); + +-void ieee80211_return_txq(struct ieee80211_hw *hw, +- struct ieee80211_txq *txq) ++void ieee80211_schedule_txq(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq) + { + struct ieee80211_local *local = hw_to_local(hw); + struct txq_info *txqi = to_txq_info(txq); + +- lockdep_assert_held(&local->active_txq_lock[txq->ac]); ++ spin_lock_bh(&local->active_txq_lock[txq->ac]); + + if (list_empty(&txqi->schedule_order) && + (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) { +@@ -3679,18 +3684,7 @@ void ieee80211_return_txq(struct ieee802 + list_add_tail(&txqi->schedule_order, + &local->active_txqs[txq->ac]); + } +-} +-EXPORT_SYMBOL(ieee80211_return_txq); + +-void ieee80211_schedule_txq(struct ieee80211_hw *hw, +- struct ieee80211_txq *txq) +- __acquires(txq_lock) __releases(txq_lock) +-{ +- struct ieee80211_local *local = hw_to_local(hw); +- struct txq_info *txqi = to_txq_info(txq); +- +- spin_lock_bh(&local->active_txq_lock[txq->ac]); +- ieee80211_return_txq(hw, txq); + spin_unlock_bh(&local->active_txq_lock[txq->ac]); + } + EXPORT_SYMBOL(ieee80211_schedule_txq); +@@ -3703,7 +3697,7 @@ bool ieee80211_txq_may_transmit(struct i + struct sta_info *sta; + u8 ac = txq->ac; + +- lockdep_assert_held(&local->active_txq_lock[ac]); ++ spin_lock_bh(&local->active_txq_lock[ac]); + + if (!txqi->txq.sta) + goto out; +@@ -3733,34 +3727,27 @@ bool ieee80211_txq_may_transmit(struct i + + sta->airtime[ac].deficit += sta->airtime_weight; + list_move_tail(&txqi->schedule_order, &local->active_txqs[ac]); ++ spin_unlock_bh(&local->active_txq_lock[ac]); + + return false; + out: + if (!list_empty(&txqi->schedule_order)) + list_del_init(&txqi->schedule_order); ++ spin_unlock_bh(&local->active_txq_lock[ac]); + + return true; + } + EXPORT_SYMBOL(ieee80211_txq_may_transmit); + + void ieee80211_txq_schedule_start(struct ieee80211_hw *hw, u8 ac) +- __acquires(txq_lock) + { + struct ieee80211_local *local = hw_to_local(hw); + + spin_lock_bh(&local->active_txq_lock[ac]); + local->schedule_round[ac]++; +-} +-EXPORT_SYMBOL(ieee80211_txq_schedule_start); +- +-void ieee80211_txq_schedule_end(struct ieee80211_hw *hw, u8 ac) +- __releases(txq_lock) +-{ +- struct ieee80211_local *local = hw_to_local(hw); +- + spin_unlock_bh(&local->active_txq_lock[ac]); + } +-EXPORT_SYMBOL(ieee80211_txq_schedule_end); ++EXPORT_SYMBOL(ieee80211_txq_schedule_start); + + void __ieee80211_subif_start_xmit(struct sk_buff *skb, + struct net_device *dev, diff --git a/package/kernel/mac80211/patches/subsys/353-mac80211-mesh-drop-redundant-rcu_read_lock-unlock-ca.patch b/package/kernel/mac80211/patches/subsys/353-mac80211-mesh-drop-redundant-rcu_read_lock-unlock-ca.patch new file mode 100644 index 0000000000..86300be4ed --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/353-mac80211-mesh-drop-redundant-rcu_read_lock-unlock-ca.patch @@ -0,0 +1,96 @@ +From: Felix Fietkau +Date: Sat, 16 Mar 2019 17:43:58 +0100 +Subject: [PATCH] mac80211: mesh: drop redundant rcu_read_lock/unlock calls + +The callers of these functions are all within RCU locked sections + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/mesh_hwmp.c ++++ b/net/mac80211/mesh_hwmp.c +@@ -1112,16 +1112,13 @@ int mesh_nexthop_resolve(struct ieee8021 + struct mesh_path *mpath; + struct sk_buff *skb_to_free = NULL; + u8 *target_addr = hdr->addr3; +- int err = 0; + + /* Nulls are only sent to peers for PS and should be pre-addressed */ + if (ieee80211_is_qos_nullfunc(hdr->frame_control)) + return 0; + +- rcu_read_lock(); +- err = mesh_nexthop_lookup(sdata, skb); +- if (!err) +- goto endlookup; ++ if (!mesh_nexthop_lookup(sdata, skb)) ++ return 0; + + /* no nexthop found, start resolving */ + mpath = mesh_path_lookup(sdata, target_addr); +@@ -1129,8 +1126,7 @@ int mesh_nexthop_resolve(struct ieee8021 + mpath = mesh_path_add(sdata, target_addr); + if (IS_ERR(mpath)) { + mesh_path_discard_frame(sdata, skb); +- err = PTR_ERR(mpath); +- goto endlookup; ++ return PTR_ERR(mpath); + } + } + +@@ -1143,13 +1139,10 @@ int mesh_nexthop_resolve(struct ieee8021 + info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING; + ieee80211_set_qos_hdr(sdata, skb); + skb_queue_tail(&mpath->frame_queue, skb); +- err = -ENOENT; + if (skb_to_free) + mesh_path_discard_frame(sdata, skb_to_free); + +-endlookup: +- rcu_read_unlock(); +- return err; ++ return -ENOENT; + } + + /** +@@ -1169,13 +1162,10 @@ int mesh_nexthop_lookup(struct ieee80211 + struct sta_info *next_hop; + struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data; + u8 *target_addr = hdr->addr3; +- int err = -ENOENT; + +- rcu_read_lock(); + mpath = mesh_path_lookup(sdata, target_addr); +- + if (!mpath || !(mpath->flags & MESH_PATH_ACTIVE)) +- goto endlookup; ++ return -ENOENT; + + if (time_after(jiffies, + mpath->exp_time - +@@ -1190,12 +1180,10 @@ int mesh_nexthop_lookup(struct ieee80211 + memcpy(hdr->addr1, next_hop->sta.addr, ETH_ALEN); + memcpy(hdr->addr2, sdata->vif.addr, ETH_ALEN); + ieee80211_mps_set_frame_flags(sdata, next_hop, hdr); +- err = 0; ++ return 0; + } + +-endlookup: +- rcu_read_unlock(); +- return err; ++ return -ENOENT; + } + + void mesh_path_timer(struct timer_list *t) +--- a/net/mac80211/mesh_pathtbl.c ++++ b/net/mac80211/mesh_pathtbl.c +@@ -219,7 +219,7 @@ static struct mesh_path *mpath_lookup(st + { + struct mesh_path *mpath; + +- mpath = rhashtable_lookup_fast(&tbl->rhead, dst, mesh_rht_params); ++ mpath = rhashtable_lookup(&tbl->rhead, dst, mesh_rht_params); + + if (mpath && mpath_expired(mpath)) { + spin_lock_bh(&mpath->state_lock); diff --git a/package/kernel/mac80211/patches/subsys/354-mac80211-calculate-hash-for-fq-without-holding-fq-lo.patch b/package/kernel/mac80211/patches/subsys/354-mac80211-calculate-hash-for-fq-without-holding-fq-lo.patch new file mode 100644 index 0000000000..2b6d8ab525 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/354-mac80211-calculate-hash-for-fq-without-holding-fq-lo.patch @@ -0,0 +1,124 @@ +From: Felix Fietkau +Date: Sat, 16 Mar 2019 17:57:38 +0100 +Subject: [PATCH] mac80211: calculate hash for fq without holding fq->lock + in itxq enqueue + +Reduces lock contention on enqueue/dequeue of iTXQ packets + +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/fq_impl.h ++++ b/include/net/fq_impl.h +@@ -107,21 +107,23 @@ begin: + return skb; + } + ++static u32 fq_flow_idx(struct fq *fq, struct sk_buff *skb) ++{ ++ u32 hash = skb_get_hash_perturb(skb, fq->perturbation); ++ ++ return reciprocal_scale(hash, fq->flows_cnt); ++} ++ + static struct fq_flow *fq_flow_classify(struct fq *fq, +- struct fq_tin *tin, ++ struct fq_tin *tin, u32 idx, + struct sk_buff *skb, + fq_flow_get_default_t get_default_func) + { + struct fq_flow *flow; +- u32 hash; +- u32 idx; + + lockdep_assert_held(&fq->lock); + +- hash = skb_get_hash_perturb(skb, fq->perturbation); +- idx = reciprocal_scale(hash, fq->flows_cnt); + flow = &fq->flows[idx]; +- + if (flow->tin && flow->tin != tin) { + flow = get_default_func(fq, tin, idx, skb); + tin->collisions++; +@@ -153,7 +155,7 @@ static void fq_recalc_backlog(struct fq + } + + static void fq_tin_enqueue(struct fq *fq, +- struct fq_tin *tin, ++ struct fq_tin *tin, u32 idx, + struct sk_buff *skb, + fq_skb_free_t free_func, + fq_flow_get_default_t get_default_func) +@@ -163,7 +165,7 @@ static void fq_tin_enqueue(struct fq *fq + + lockdep_assert_held(&fq->lock); + +- flow = fq_flow_classify(fq, tin, skb, get_default_func); ++ flow = fq_flow_classify(fq, tin, idx, skb, get_default_func); + + flow->tin = tin; + flow->backlog += skb->len; +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -1390,11 +1390,15 @@ static void ieee80211_txq_enqueue(struct + { + struct fq *fq = &local->fq; + struct fq_tin *tin = &txqi->tin; ++ u32 flow_idx = fq_flow_idx(fq, skb); + + ieee80211_set_skb_enqueue_time(skb); +- fq_tin_enqueue(fq, tin, skb, ++ ++ spin_lock_bh(&fq->lock); ++ fq_tin_enqueue(fq, tin, flow_idx, skb, + fq_skb_free_func, + fq_flow_get_default_func); ++ spin_unlock_bh(&fq->lock); + } + + static bool fq_vlan_filter_func(struct fq *fq, struct fq_tin *tin, +@@ -1564,7 +1568,6 @@ static bool ieee80211_queue_skb(struct i + struct sta_info *sta, + struct sk_buff *skb) + { +- struct fq *fq = &local->fq; + struct ieee80211_vif *vif; + struct txq_info *txqi; + +@@ -1582,9 +1585,7 @@ static bool ieee80211_queue_skb(struct i + if (!txqi) + return false; + +- spin_lock_bh(&fq->lock); + ieee80211_txq_enqueue(local, txqi, skb); +- spin_unlock_bh(&fq->lock); + + schedule_and_wake_txq(local, txqi); + +@@ -3198,6 +3199,7 @@ static bool ieee80211_amsdu_aggregate(st + u8 max_subframes = sta->sta.max_amsdu_subframes; + int max_frags = local->hw.max_tx_fragments; + int max_amsdu_len = sta->sta.max_amsdu_len; ++ u32 flow_idx; + int orig_truesize; + __be16 len; + void *data; +@@ -3220,6 +3222,8 @@ static bool ieee80211_amsdu_aggregate(st + max_amsdu_len = min_t(int, max_amsdu_len, + sta->sta.max_rc_amsdu_len); + ++ flow_idx = fq_flow_idx(fq, skb); ++ + spin_lock_bh(&fq->lock); + + /* TODO: Ideally aggregation should be done on dequeue to remain +@@ -3227,7 +3231,8 @@ static bool ieee80211_amsdu_aggregate(st + */ + + tin = &txqi->tin; +- flow = fq_flow_classify(fq, tin, skb, fq_flow_get_default_func); ++ flow = fq_flow_classify(fq, tin, flow_idx, skb, ++ fq_flow_get_default_func); + head = skb_peek_tail(&flow->queue); + if (!head) + goto unlock; diff --git a/package/kernel/mac80211/patches/subsys/355-mac80211-run-late-dequeue-late-tx-handlers-without-h.patch b/package/kernel/mac80211/patches/subsys/355-mac80211-run-late-dequeue-late-tx-handlers-without-h.patch new file mode 100644 index 0000000000..3127c86822 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/355-mac80211-run-late-dequeue-late-tx-handlers-without-h.patch @@ -0,0 +1,55 @@ +From: Felix Fietkau +Date: Sat, 16 Mar 2019 18:00:12 +0100 +Subject: [PATCH] mac80211: run late dequeue late tx handlers without + holding fq->lock + +Reduces lock contention on enqueue/dequeue of iTXQ packets + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3507,6 +3507,7 @@ struct sk_buff *ieee80211_tx_dequeue(str + ieee80211_tx_result r; + struct ieee80211_vif *vif = txq->vif; + ++begin: + spin_lock_bh(&fq->lock); + + if (test_bit(IEEE80211_TXQ_STOP, &txqi->flags) || +@@ -3523,11 +3524,12 @@ struct sk_buff *ieee80211_tx_dequeue(str + if (skb) + goto out; + +-begin: + skb = fq_tin_dequeue(fq, tin, fq_tin_dequeue_func); + if (!skb) + goto out; + ++ spin_unlock_bh(&fq->lock); ++ + hdr = (struct ieee80211_hdr *)skb->data; + info = IEEE80211_SKB_CB(skb); + +@@ -3573,8 +3575,11 @@ begin: + + skb = __skb_dequeue(&tx.skbs); + +- if (!skb_queue_empty(&tx.skbs)) ++ if (!skb_queue_empty(&tx.skbs)) { ++ spin_lock_bh(&fq->lock); + skb_queue_splice_tail(&tx.skbs, &txqi->frags); ++ spin_unlock_bh(&fq->lock); ++ } + } + + if (skb && skb_has_frag_list(skb) && +@@ -3613,6 +3618,7 @@ begin: + } + + IEEE80211_SKB_CB(skb)->control.vif = vif; ++ return skb; + + out: + spin_unlock_bh(&fq->lock); diff --git a/package/kernel/mac80211/patches/subsys/356-mac80211-set-NETIF_F_LLTX-when-using-intermediate-tx.patch b/package/kernel/mac80211/patches/subsys/356-mac80211-set-NETIF_F_LLTX-when-using-intermediate-tx.patch new file mode 100644 index 0000000000..95ab3ab9fb --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/356-mac80211-set-NETIF_F_LLTX-when-using-intermediate-tx.patch @@ -0,0 +1,22 @@ +From: Felix Fietkau +Date: Sat, 16 Mar 2019 18:01:53 +0100 +Subject: [PATCH] mac80211: set NETIF_F_LLTX when using intermediate tx + queues + +When using iTXQ, tx sequence number allocation and statistics are run at +dequeue time. Because of that, it is safe to enable NETIF_F_LLTX, which +allows tx handlers to run on multiple CPUs in parallel. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/iface.c ++++ b/net/mac80211/iface.c +@@ -1301,6 +1301,7 @@ static void ieee80211_if_setup(struct ne + static void ieee80211_if_setup_no_queue(struct net_device *dev) + { + ieee80211_if_setup(dev); ++ dev->features |= NETIF_F_LLTX; + #if LINUX_VERSION_IS_GEQ(4,3,0) + dev->priv_flags |= IFF_NO_QUEUE; + #else diff --git a/package/kernel/mac80211/patches/subsys/300-mac80211-optimize-skb-resizing.patch b/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch similarity index 91% rename from package/kernel/mac80211/patches/subsys/300-mac80211-optimize-skb-resizing.patch rename to package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch index b0c527a68c..919aa36a48 100644 --- a/package/kernel/mac80211/patches/subsys/300-mac80211-optimize-skb-resizing.patch +++ b/package/kernel/mac80211/patches/subsys/357-mac80211-optimize-skb-resizing.patch @@ -24,10 +24,10 @@ Signed-off-by: Felix Fietkau --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1779,6 +1779,9 @@ int ieee80211_tx_control_port(struct wip +@@ -1761,6 +1761,9 @@ void ieee80211_clear_fast_xmit(struct st + int ieee80211_tx_control_port(struct wiphy *wiphy, struct net_device *dev, + const u8 *buf, size_t len, const u8 *dest, __be16 proto, bool unencrypted); - int ieee80211_probe_mesh_link(struct wiphy *wiphy, struct net_device *dev, - const u8 *buf, size_t len); +int ieee80211_skb_resize(struct ieee80211_local *local, + struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, int hdrlen, int hdr_add); @@ -36,9 +36,9 @@ Signed-off-by: Felix Fietkau void ieee80211_apply_htcap_overrides(struct ieee80211_sub_if_data *sdata, --- a/net/mac80211/status.c +++ b/net/mac80211/status.c -@@ -655,6 +655,11 @@ void ieee80211_tx_monitor(struct ieee802 - struct net_device *prev_dev = NULL; - int rtap_len; +@@ -672,6 +672,11 @@ void ieee80211_tx_monitor(struct ieee802 + } + } + if (ieee80211_skb_resize(local, NULL, skb, 0, 0)) { + dev_kfree_skb(skb); @@ -50,7 +50,7 @@ Signed-off-by: Felix Fietkau if (WARN_ON_ONCE(skb_headroom(skb) < rtap_len)) { --- a/net/mac80211/tx.c +++ b/net/mac80211/tx.c -@@ -1936,37 +1936,53 @@ static bool ieee80211_tx(struct ieee8021 +@@ -1914,37 +1914,53 @@ static bool ieee80211_tx(struct ieee8021 } /* device xmit handlers */ @@ -67,20 +67,14 @@ Signed-off-by: Felix Fietkau struct ieee80211_hdr *hdr; - bool enc_tailroom; - int tail_need = 0; -- ++ int head_need, head_max; ++ int tail_need, tail_max; ++ bool enc_tailroom = false; + - hdr = (struct ieee80211_hdr *) skb->data; - enc_tailroom = may_encrypt && - (sdata->crypto_tx_tailroom_needed_cnt || - ieee80211_is_mgmt(hdr->frame_control)); -- -- if (enc_tailroom) { -- tail_need = IEEE80211_ENCRYPT_TAILROOM; -- tail_need -= skb_tailroom(skb); -- tail_need = max_t(int, tail_need, 0); -+ int head_need, head_max; -+ int tail_need, tail_max; -+ bool enc_tailroom = false; -+ + if (sdata && !hdr_len && + !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT)) { + hdr = (struct ieee80211_hdr *) skb->data; @@ -88,7 +82,11 @@ Signed-off-by: Felix Fietkau + ieee80211_is_mgmt(hdr->frame_control)); + hdr_len += sdata->encrypt_headroom; + } -+ + +- if (enc_tailroom) { +- tail_need = IEEE80211_ENCRYPT_TAILROOM; +- tail_need -= skb_tailroom(skb); +- tail_need = max_t(int, tail_need, 0); + head_need = head_max = hdr_len; + tail_need = tail_max = 0; + if (!sdata) { @@ -123,7 +121,7 @@ Signed-off-by: Felix Fietkau wiphy_debug(local->hw.wiphy, "failed to reallocate TX buffer\n"); return -ENOMEM; -@@ -1982,18 +1998,8 @@ void ieee80211_xmit(struct ieee80211_sub +@@ -1960,18 +1976,8 @@ void ieee80211_xmit(struct ieee80211_sub struct ieee80211_local *local = sdata->local; struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); struct ieee80211_hdr *hdr; @@ -131,24 +129,25 @@ Signed-off-by: Felix Fietkau - bool may_encrypt; - - may_encrypt = !(info->flags & IEEE80211_TX_INTFL_DONT_ENCRYPT); - +- - headroom = local->tx_headroom; - if (may_encrypt) - headroom += sdata->encrypt_headroom; - headroom -= skb_headroom(skb); - headroom = max_t(int, 0, headroom); -- + - if (ieee80211_skb_resize(sdata, skb, headroom, may_encrypt)) { + if (ieee80211_skb_resize(local, sdata, skb, 0, 0)) { ieee80211_free_txskb(&local->hw, skb); return; } -@@ -2774,29 +2780,13 @@ static struct sk_buff *ieee80211_build_h - } +@@ -2740,30 +2746,14 @@ static struct sk_buff *ieee80211_build_h skb_pull(skb, skip_header_bytes); + padsize = ieee80211_hdr_padsize(&local->hw, hdrlen); - head_need = hdrlen + encaps_len + meshhdrlen - skb_headroom(skb); + head_need = hdrlen + encaps_len + meshhdrlen; + head_need += padsize; - /* - * So we need to modify the skb header and hence need a copy of @@ -179,7 +178,7 @@ Signed-off-by: Felix Fietkau } if (encaps_data) -@@ -3411,7 +3401,6 @@ static bool ieee80211_xmit_fast(struct i +@@ -3377,7 +3367,6 @@ static bool ieee80211_xmit_fast(struct i struct ieee80211_local *local = sdata->local; u16 ethertype = (skb->data[12] << 8) | skb->data[13]; int extra_head = fast_tx->hdr_len - (ETH_HLEN - 2); @@ -187,7 +186,7 @@ Signed-off-by: Felix Fietkau struct ethhdr eth; struct ieee80211_tx_info *info; struct ieee80211_hdr *hdr = (void *)fast_tx->hdr; -@@ -3463,10 +3452,7 @@ static bool ieee80211_xmit_fast(struct i +@@ -3429,10 +3418,7 @@ static bool ieee80211_xmit_fast(struct i * as the may-encrypt argument for the resize to not account for * more room than we already have in 'extra_head' */ diff --git a/package/kernel/mac80211/patches/subsys/358-mac80211-make-ieee80211_schedule_txq-schedule-empty-.patch b/package/kernel/mac80211/patches/subsys/358-mac80211-make-ieee80211_schedule_txq-schedule-empty-.patch new file mode 100644 index 0000000000..a0a65f35a8 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/358-mac80211-make-ieee80211_schedule_txq-schedule-empty-.patch @@ -0,0 +1,105 @@ +From: Felix Fietkau +Date: Sun, 17 Mar 2019 14:26:59 +0100 +Subject: [PATCH] mac80211: make ieee80211_schedule_txq schedule empty TXQs + +Currently there is no way for the driver to signal to mac80211 that it should +schedule a TXQ even if there are no packets on the mac80211 part of that queue. +This is problematic if the driver has an internal retry queue to deal with +software A-MPDU retry. + +This patch changes the behavior of ieee80211_schedule_txq to always schedule +the queue, as its only user (ath9k) seems to expect such behavior already: +it calls this function on tx status and on powersave wakeup whenever its +internal retry queue is not empty. + +Also add an extra argument to ieee80211_return_txq to get the same behavior. + +This fixes an issue on ath9k where tx queues with packets to retry (and no +new packets in mac80211) would not get serviced. + +Fixes: 89cea7493a346 ("ath9k: Switch to mac80211 TXQ scheduling and airtime APIs") +Signed-off-by: Felix Fietkau +--- + +--- a/include/net/mac80211.h ++++ b/include/net/mac80211.h +@@ -6090,26 +6090,42 @@ static inline void ieee80211_txq_schedul + { + } + ++void __ieee80211_schedule_txq(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq, bool force); ++ + /** + * ieee80211_schedule_txq - schedule a TXQ for transmission + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @txq: pointer obtained from station or virtual interface + * +- * Schedules a TXQ for transmission if it is not already scheduled. ++ * Schedules a TXQ for transmission if it is not already scheduled, ++ * even if mac80211 does not have any packets buffered. ++ * ++ * The driver may call this function if it has buffered packets for ++ * this TXQ internally. + */ +-void ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq); ++static inline void ++ieee80211_schedule_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) ++{ ++ __ieee80211_schedule_txq(hw, txq, true); ++} + + /** + * ieee80211_return_txq - return a TXQ previously acquired by ieee80211_next_txq() + * + * @hw: pointer as obtained from ieee80211_alloc_hw() + * @txq: pointer obtained from station or virtual interface ++ * @force: schedule txq even if mac80211 does not have any buffered packets. ++ * ++ * The driver may set force=true if it has buffered packets for this TXQ ++ * internally. + */ + static inline void +-ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq) ++ieee80211_return_txq(struct ieee80211_hw *hw, struct ieee80211_txq *txq, ++ bool force) + { +- ieee80211_schedule_txq(hw, txq); ++ __ieee80211_schedule_txq(hw, txq, force); + } + + /** +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3655,8 +3655,9 @@ out: + } + EXPORT_SYMBOL(ieee80211_next_txq); + +-void ieee80211_schedule_txq(struct ieee80211_hw *hw, +- struct ieee80211_txq *txq) ++void __ieee80211_schedule_txq(struct ieee80211_hw *hw, ++ struct ieee80211_txq *txq, ++ bool force) + { + struct ieee80211_local *local = hw_to_local(hw); + struct txq_info *txqi = to_txq_info(txq); +@@ -3664,7 +3665,8 @@ void ieee80211_schedule_txq(struct ieee8 + spin_lock_bh(&local->active_txq_lock[txq->ac]); + + if (list_empty(&txqi->schedule_order) && +- (!skb_queue_empty(&txqi->frags) || txqi->tin.backlog_packets)) { ++ (force || !skb_queue_empty(&txqi->frags) || ++ txqi->tin.backlog_packets)) { + /* If airtime accounting is active, always enqueue STAs at the + * head of the list to ensure that they only get moved to the + * back by the airtime DRR scheduler once they have a negative +@@ -3684,7 +3686,7 @@ void ieee80211_schedule_txq(struct ieee8 + + spin_unlock_bh(&local->active_txq_lock[txq->ac]); + } +-EXPORT_SYMBOL(ieee80211_schedule_txq); ++EXPORT_SYMBOL(__ieee80211_schedule_txq); + + bool ieee80211_txq_may_transmit(struct ieee80211_hw *hw, + struct ieee80211_txq *txq) diff --git a/package/kernel/mac80211/patches/subsys/359-mac80211-un-schedule-TXQs-on-powersave-start.patch b/package/kernel/mac80211/patches/subsys/359-mac80211-un-schedule-TXQs-on-powersave-start.patch new file mode 100644 index 0000000000..1abb2db7c2 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/359-mac80211-un-schedule-TXQs-on-powersave-start.patch @@ -0,0 +1,31 @@ +From: Felix Fietkau +Date: Tue, 19 Mar 2019 11:36:12 +0100 +Subject: [PATCH] mac80211: un-schedule TXQs on powersave start + +Once a station enters powersave, its queues should not be returned by +ieee80211_next_txq() anymore. They will be re-scheduled again after the +station has woken up again + +Fixes: 1866760096bf4 ("mac80211: Add TXQ scheduling API") +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/rx.c ++++ b/net/mac80211/rx.c +@@ -1508,7 +1508,15 @@ static void sta_ps_start(struct sta_info + return; + + for (tid = 0; tid < ARRAY_SIZE(sta->sta.txq); tid++) { +- if (txq_has_queue(sta->sta.txq[tid])) ++ struct ieee80211_txq *txq = sta->sta.txq[tid]; ++ struct txq_info *txqi = to_txq_info(txq); ++ ++ spin_lock(&local->active_txq_lock[txq->ac]); ++ if (!list_empty(&txqi->schedule_order)) ++ list_del_init(&txqi->schedule_order); ++ spin_unlock(&local->active_txq_lock[txq->ac]); ++ ++ if (txq_has_queue(txq)) + set_bit(tid, &sta->txq_buffered_tids); + else + clear_bit(tid, &sta->txq_buffered_tids); diff --git a/package/kernel/mac80211/patches/subsys/360-mac80211-minstrel-remove-divisions-in-tx-status-path.patch b/package/kernel/mac80211/patches/subsys/360-mac80211-minstrel-remove-divisions-in-tx-status-path.patch deleted file mode 100644 index 0bdeded529..0000000000 --- a/package/kernel/mac80211/patches/subsys/360-mac80211-minstrel-remove-divisions-in-tx-status-path.patch +++ /dev/null @@ -1,61 +0,0 @@ -From: Felix Fietkau -Date: Sat, 28 Sep 2019 15:44:06 +0200 -Subject: [PATCH] mac80211: minstrel: remove divisions in tx status path - -Use a slightly different threshold for downgrading spatial streams to -make it easier to calculate without divisions. -Slightly reduces CPU overhead. - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.c -+++ b/net/mac80211/rc80211_minstrel.c -@@ -289,8 +289,7 @@ minstrel_tx_status(void *priv, struct ie - if (mi->sample_deferred > 0) - mi->sample_deferred--; - -- if (time_after(jiffies, mi->last_stats_update + -- (mp->update_interval * HZ) / 1000)) -+ if (time_after(jiffies, mi->last_stats_update + mp->update_interval)) - minstrel_update_stats(mp, mi); - } - ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -970,23 +970,21 @@ minstrel_ht_tx_status(void *priv, struct - */ - rate = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); - if (rate->attempts > 30 && -- MINSTREL_FRAC(rate->success, rate->attempts) < -- MINSTREL_FRAC(20, 100)) { -+ rate->success < rate->attempts / 4) { - minstrel_downgrade_rate(mi, &mi->max_tp_rate[0], true); - update = true; - } - - rate2 = minstrel_get_ratestats(mi, mi->max_tp_rate[1]); - if (rate2->attempts > 30 && -- MINSTREL_FRAC(rate2->success, rate2->attempts) < -- MINSTREL_FRAC(20, 100)) { -+ rate2->success < rate2->attempts / 4) { - minstrel_downgrade_rate(mi, &mi->max_tp_rate[1], false); - update = true; - } - } - - if (time_after(jiffies, mi->last_stats_update + -- (mp->update_interval / 2 * HZ) / 1000)) { -+ mp->update_interval / 2)) { - update = true; - minstrel_ht_update_stats(mp, mi, true); - } -@@ -1666,7 +1664,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h - mp->has_mrr = true; - - mp->hw = hw; -- mp->update_interval = 100; -+ mp->update_interval = HZ / 10; - - #ifdef CPTCFG_MAC80211_DEBUGFS - mp->fixed_rate_idx = (u32) -1; diff --git a/package/kernel/mac80211/patches/subsys/360-mac80211-when-using-iTXQ-select-the-queue-in-ieee802.patch b/package/kernel/mac80211/patches/subsys/360-mac80211-when-using-iTXQ-select-the-queue-in-ieee802.patch new file mode 100644 index 0000000000..bb3af7317a --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/360-mac80211-when-using-iTXQ-select-the-queue-in-ieee802.patch @@ -0,0 +1,183 @@ +From: Felix Fietkau +Date: Fri, 22 Mar 2019 18:06:03 +0100 +Subject: [PATCH] mac80211: when using iTXQ, select the queue in + ieee80211_subif_start_xmit + +When using iTXQ, the network stack does not need the real queue number, since +mac80211 is using its internal queues anyway. In that case we can defer +selecting the queue and remove a redundant station lookup in the tx path to save +some CPU cycles. + +Signed-off-by: Felix Fietkau +--- + +--- a/net/mac80211/tx.c ++++ b/net/mac80211/tx.c +@@ -3753,6 +3753,7 @@ void __ieee80211_subif_start_xmit(struct + u32 info_flags) + { + struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); ++ struct ieee80211_local *local = sdata->local; + struct sta_info *sta; + struct sk_buff *next; + +@@ -3766,7 +3767,15 @@ void __ieee80211_subif_start_xmit(struct + if (ieee80211_lookup_ra_sta(sdata, skb, &sta)) + goto out_free; + +- if (!IS_ERR_OR_NULL(sta)) { ++ if (IS_ERR(sta)) ++ sta = NULL; ++ ++ if (local->ops->wake_tx_queue) { ++ u16 queue = __ieee80211_select_queue(sdata, sta, skb); ++ skb_set_queue_mapping(skb, queue); ++ } ++ ++ if (sta) { + struct ieee80211_fast_tx *fast_tx; + + /* We need a bit of data queued to build aggregates properly, so +--- a/net/mac80211/wme.c ++++ b/net/mac80211/wme.c +@@ -141,6 +141,42 @@ u16 ieee80211_select_queue_80211(struct + return ieee80211_downgrade_queue(sdata, NULL, skb); + } + ++u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, ++ struct sta_info *sta, struct sk_buff *skb) ++{ ++ struct mac80211_qos_map *qos_map; ++ bool qos; ++ ++ /* all mesh/ocb stations are required to support WME */ ++ if (sdata->vif.type == NL80211_IFTYPE_MESH_POINT || ++ sdata->vif.type == NL80211_IFTYPE_OCB) ++ qos = true; ++ else if (sta) ++ qos = sta->sta.wme; ++ else ++ qos = false; ++ ++ if (!qos) { ++ skb->priority = 0; /* required for correct WPA/11i MIC */ ++ return IEEE80211_AC_BE; ++ } ++ ++ if (skb->protocol == sdata->control_port_protocol) { ++ skb->priority = 7; ++ goto downgrade; ++ } ++ ++ /* use the data classifier to determine what 802.1d tag the ++ * data frame has */ ++ qos_map = rcu_dereference(sdata->qos_map); ++ skb->priority = cfg80211_classify8021d(skb, qos_map ? ++ &qos_map->qos_map : NULL); ++ ++ downgrade: ++ return ieee80211_downgrade_queue(sdata, sta, skb); ++} ++ ++ + /* Indicate which queue to use. */ + u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb) +@@ -148,10 +184,12 @@ u16 ieee80211_select_queue(struct ieee80 + struct ieee80211_local *local = sdata->local; + struct sta_info *sta = NULL; + const u8 *ra = NULL; +- bool qos = false; +- struct mac80211_qos_map *qos_map; + u16 ret; + ++ /* when using iTXQ, we can do this later */ ++ if (local->ops->wake_tx_queue) ++ return 0; ++ + if (local->hw.queues < IEEE80211_NUM_ACS || skb->len < 6) { + skb->priority = 0; /* required for correct WPA/11i MIC */ + return 0; +@@ -161,10 +199,8 @@ u16 ieee80211_select_queue(struct ieee80 + switch (sdata->vif.type) { + case NL80211_IFTYPE_AP_VLAN: + sta = rcu_dereference(sdata->u.vlan.sta); +- if (sta) { +- qos = sta->sta.wme; ++ if (sta) + break; +- } + /* fall through */ + case NL80211_IFTYPE_AP: + ra = skb->data; +@@ -172,56 +208,26 @@ u16 ieee80211_select_queue(struct ieee80 + case NL80211_IFTYPE_WDS: + ra = sdata->u.wds.remote_addr; + break; +-#ifdef CPTCFG_MAC80211_MESH +- case NL80211_IFTYPE_MESH_POINT: +- qos = true; +- break; +-#endif + case NL80211_IFTYPE_STATION: + /* might be a TDLS station */ + sta = sta_info_get(sdata, skb->data); + if (sta) +- qos = sta->sta.wme; ++ break; + + ra = sdata->u.mgd.bssid; + break; + case NL80211_IFTYPE_ADHOC: + ra = skb->data; + break; +- case NL80211_IFTYPE_OCB: +- /* all stations are required to support WME */ +- qos = true; +- break; + default: + break; + } + +- if (!sta && ra && !is_multicast_ether_addr(ra)) { ++ if (!sta && ra && !is_multicast_ether_addr(ra)) + sta = sta_info_get(sdata, ra); +- if (sta) +- qos = sta->sta.wme; +- } + +- if (!qos) { +- skb->priority = 0; /* required for correct WPA/11i MIC */ +- ret = IEEE80211_AC_BE; +- goto out; +- } ++ ret = __ieee80211_select_queue(sdata, sta, skb); + +- if (skb->protocol == sdata->control_port_protocol) { +- skb->priority = 7; +- goto downgrade; +- } +- +- /* use the data classifier to determine what 802.1d tag the +- * data frame has */ +- qos_map = rcu_dereference(sdata->qos_map); +- skb->priority = cfg80211_classify8021d(skb, qos_map ? +- &qos_map->qos_map : NULL); +- +- downgrade: +- ret = ieee80211_downgrade_queue(sdata, sta, skb); +- out: + rcu_read_unlock(); + return ret; + } +--- a/net/mac80211/wme.h ++++ b/net/mac80211/wme.h +@@ -16,6 +16,8 @@ + u16 ieee80211_select_queue_80211(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb, + struct ieee80211_hdr *hdr); ++u16 __ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, ++ struct sta_info *sta, struct sk_buff *skb); + u16 ieee80211_select_queue(struct ieee80211_sub_if_data *sdata, + struct sk_buff *skb); + void ieee80211_set_qos_hdr(struct ieee80211_sub_if_data *sdata, diff --git a/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch b/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch deleted file mode 100644 index bce9e75378..0000000000 --- a/package/kernel/mac80211/patches/subsys/361-mac80211-minstrel_ht-replace-rate-stats-ewma-with-a-.patch +++ /dev/null @@ -1,235 +0,0 @@ -From: Felix Fietkau -Date: Sat, 28 Sep 2019 15:46:06 +0200 -Subject: [PATCH] mac80211: minstrel_ht: replace rate stats ewma with a - better moving average - -Rate success probability usually fluctuates a lot under normal conditions. -With a simple EWMA, noise and fluctuation can be reduced by increasing the -window length, but that comes at the cost of introducing lag on sudden -changes. - -This change replaces the EWMA implementation with a moving average that's -designed to significantly reduce lag while keeping a bigger window size -by being better at filtering out noise. - -It is only slightly more expensive than the simple EWMA and still avoids -divisions in its calculation. - -The algorithm is adapted from an implementation intended for a completely -different field (stock market trading), where the tradeoff of lag vs -noise filtering is equally important. - -The algorithm works in the same way as the "smoothing filter" from -http://www.stockspotter.com/files/PredictiveIndicators.pdf adapted for -fixed-point math with some constants, using only addition, bit shifts -and multiplication - -To better make use of the filtering and bigger window size, the update -interval is cut in half. - -For testing, the algorithm can be reverted to the older one via debugfs - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.c -+++ b/net/mac80211/rc80211_minstrel.c -@@ -157,14 +157,18 @@ minstrel_update_rates(struct minstrel_pr - * Recalculate statistics and counters of a given rate - */ - void --minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs) -+minstrel_calc_rate_stats(struct minstrel_priv *mp, -+ struct minstrel_rate_stats *mrs) - { - unsigned int cur_prob; - - if (unlikely(mrs->attempts > 0)) { - mrs->sample_skipped = 0; - cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); -- if (unlikely(!mrs->att_hist)) { -+ if (mp->new_avg) { -+ mrs->prob_ewma = minstrel_filter_avg_add(&mrs->avg, -+ cur_prob); -+ } else if (unlikely(!mrs->att_hist)) { - mrs->prob_ewma = cur_prob; - } else { - /*update exponential weighted moving avarage */ -@@ -200,7 +204,7 @@ minstrel_update_stats(struct minstrel_pr - struct minstrel_rate_stats *tmp_mrs = &mi->r[tmp_prob_rate].stats; - - /* Update statistics of success probability per rate */ -- minstrel_calc_rate_stats(mrs); -+ minstrel_calc_rate_stats(mp, mrs); - - /* Sample less often below the 10% chance of success. - * Sample less often above the 95% chance of success. */ -@@ -289,7 +293,8 @@ minstrel_tx_status(void *priv, struct ie - if (mi->sample_deferred > 0) - mi->sample_deferred--; - -- if (time_after(jiffies, mi->last_stats_update + mp->update_interval)) -+ if (time_after(jiffies, mi->last_stats_update + -+ mp->update_interval / (mp->new_avg ? 2 : 1))) - minstrel_update_stats(mp, mi); - } - ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -19,6 +19,21 @@ - #define MAX_THR_RATES 4 - - /* -+ * Coefficients for moving average with noise filter (period=16), -+ * scaled by 10 bits -+ * -+ * a1 = exp(-pi * sqrt(2) / period) -+ * coeff2 = 2 * a1 * cos(sqrt(2) * 2 * pi / period) -+ * coeff3 = -sqr(a1) -+ * coeff1 = 1 - coeff2 - coeff3 -+ */ -+#define MINSTREL_AVG_COEFF1 (MINSTREL_FRAC(1, 1) - \ -+ MINSTREL_AVG_COEFF2 - \ -+ MINSTREL_AVG_COEFF3) -+#define MINSTREL_AVG_COEFF2 0x00001499 -+#define MINSTREL_AVG_COEFF3 -0x0000092e -+ -+/* - * Perform EWMA (Exponentially Weighted Moving Average) calculation - */ - static inline int -@@ -32,6 +47,41 @@ minstrel_ewma(int old, int new, int weig - return old + incr; - } - -+struct minstrel_avg_ctx { -+ s32 prev[2]; -+}; -+ -+static inline int minstrel_filter_avg_add(struct minstrel_avg_ctx *ctx, s32 in) -+{ -+ s32 out_1 = ctx->prev[0]; -+ s32 out_2 = ctx->prev[1]; -+ s32 val; -+ -+ if (!in) -+ in += 1; -+ -+ if (!out_1) { -+ val = out_1 = in; -+ goto out; -+ } -+ -+ val = MINSTREL_AVG_COEFF1 * in; -+ val += MINSTREL_AVG_COEFF2 * out_1; -+ val += MINSTREL_AVG_COEFF3 * out_2; -+ val >>= MINSTREL_SCALE; -+ -+ if (val > 1 << MINSTREL_SCALE) -+ val = 1 << MINSTREL_SCALE; -+ if (val < 0) -+ val = 1; -+ -+out: -+ ctx->prev[1] = out_1; -+ ctx->prev[0] = val; -+ -+ return val; -+} -+ - struct minstrel_rate_stats { - /* current / last sampling period attempts/success counters */ - u16 attempts, last_attempts; -@@ -40,6 +90,8 @@ struct minstrel_rate_stats { - /* total attempts/success counters */ - u32 att_hist, succ_hist; - -+ struct minstrel_avg_ctx avg; -+ - /* prob_ewma - exponential weighted moving average of prob */ - u16 prob_ewma; - -@@ -95,6 +147,7 @@ struct minstrel_sta_info { - struct minstrel_priv { - struct ieee80211_hw *hw; - bool has_mrr; -+ bool new_avg; - u32 sample_switch; - unsigned int cw_min; - unsigned int cw_max; -@@ -126,7 +179,8 @@ extern const struct rate_control_ops mac - void minstrel_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); - - /* Recalculate success probabilities and counters for a given rate using EWMA */ --void minstrel_calc_rate_stats(struct minstrel_rate_stats *mrs); -+void minstrel_calc_rate_stats(struct minstrel_priv *mp, -+ struct minstrel_rate_stats *mrs); - int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma); - - /* debugfs */ ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -737,7 +737,7 @@ minstrel_ht_update_stats(struct minstrel - - mrs = &mg->rates[i]; - mrs->retry_updated = false; -- minstrel_calc_rate_stats(mrs); -+ minstrel_calc_rate_stats(mp, mrs); - cur_prob = mrs->prob_ewma; - - if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0) -@@ -773,6 +773,8 @@ minstrel_ht_update_stats(struct minstrel - - /* try to sample all available rates during each interval */ - mi->sample_count *= 8; -+ if (mp->new_avg) -+ mi->sample_count /= 2; - - if (sample) - minstrel_ht_rate_sample_switch(mp, mi); -@@ -889,6 +891,7 @@ minstrel_ht_tx_status(void *priv, struct - struct ieee80211_tx_rate *ar = info->status.rates; - struct minstrel_rate_stats *rate, *rate2, *rate_sample = NULL; - struct minstrel_priv *mp = priv; -+ u32 update_interval = mp->update_interval / 2; - bool last, update = false; - bool sample_status = false; - int i; -@@ -943,6 +946,10 @@ minstrel_ht_tx_status(void *priv, struct - - switch (mi->sample_mode) { - case MINSTREL_SAMPLE_IDLE: -+ if (mp->new_avg && -+ (mp->hw->max_rates > 1 || -+ mi->total_packets_cur < SAMPLE_SWITCH_THR)) -+ update_interval /= 2; - break; - - case MINSTREL_SAMPLE_ACTIVE: -@@ -983,8 +990,7 @@ minstrel_ht_tx_status(void *priv, struct - } - } - -- if (time_after(jiffies, mi->last_stats_update + -- mp->update_interval / 2)) { -+ if (time_after(jiffies, mi->last_stats_update + update_interval)) { - update = true; - minstrel_ht_update_stats(mp, mi, true); - } -@@ -1665,6 +1671,7 @@ minstrel_ht_alloc(struct ieee80211_hw *h - - mp->hw = hw; - mp->update_interval = HZ / 10; -+ mp->new_avg = true; - - #ifdef CPTCFG_MAC80211_DEBUGFS - mp->fixed_rate_idx = (u32) -1; -@@ -1672,6 +1679,8 @@ minstrel_ht_alloc(struct ieee80211_hw *h - &mp->fixed_rate_idx); - debugfs_create_u32("sample_switch", S_IRUGO | S_IWUSR, debugfsdir, - &mp->sample_switch); -+ debugfs_create_bool("new_avg", S_IRUGO | S_IWUSR, debugfsdir, -+ &mp->new_avg); - #endif - - minstrel_ht_init_cck_rates(mp); diff --git a/package/kernel/mac80211/patches/subsys/362-mac80211-minstrel_ht-rename-prob_ewma-to-prob_avg-us.patch b/package/kernel/mac80211/patches/subsys/362-mac80211-minstrel_ht-rename-prob_ewma-to-prob_avg-us.patch deleted file mode 100644 index 23419afb12..0000000000 --- a/package/kernel/mac80211/patches/subsys/362-mac80211-minstrel_ht-rename-prob_ewma-to-prob_avg-us.patch +++ /dev/null @@ -1,424 +0,0 @@ -From: Felix Fietkau -Date: Tue, 8 Oct 2019 18:54:46 +0200 -Subject: [PATCH] mac80211: minstrel_ht: rename prob_ewma to prob_avg, use it - for the new average - -Reduces per-rate data structure size - -Signed-off-by: Felix Fietkau ---- - ---- a/net/mac80211/rc80211_minstrel.c -+++ b/net/mac80211/rc80211_minstrel.c -@@ -70,7 +70,7 @@ rix_to_ndx(struct minstrel_sta_info *mi, - } - - /* return current EMWA throughput */ --int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma) -+int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg) - { - int usecs; - -@@ -79,13 +79,13 @@ int minstrel_get_tp_avg(struct minstrel_ - usecs = 1000000; - - /* reset thr. below 10% success */ -- if (mr->stats.prob_ewma < MINSTREL_FRAC(10, 100)) -+ if (mr->stats.prob_avg < MINSTREL_FRAC(10, 100)) - return 0; - -- if (prob_ewma > MINSTREL_FRAC(90, 100)) -+ if (prob_avg > MINSTREL_FRAC(90, 100)) - return MINSTREL_TRUNC(100000 * (MINSTREL_FRAC(90, 100) / usecs)); - else -- return MINSTREL_TRUNC(100000 * (prob_ewma / usecs)); -+ return MINSTREL_TRUNC(100000 * (prob_avg / usecs)); - } - - /* find & sort topmost throughput rates */ -@@ -98,8 +98,8 @@ minstrel_sort_best_tp_rates(struct minst - - for (j = MAX_THR_RATES; j > 0; --j) { - tmp_mrs = &mi->r[tp_list[j - 1]].stats; -- if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_ewma) <= -- minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_ewma)) -+ if (minstrel_get_tp_avg(&mi->r[i], cur_mrs->prob_avg) <= -+ minstrel_get_tp_avg(&mi->r[tp_list[j - 1]], tmp_mrs->prob_avg)) - break; - } - -@@ -166,15 +166,15 @@ minstrel_calc_rate_stats(struct minstrel - mrs->sample_skipped = 0; - cur_prob = MINSTREL_FRAC(mrs->success, mrs->attempts); - if (mp->new_avg) { -- mrs->prob_ewma = minstrel_filter_avg_add(&mrs->avg, -- cur_prob); -+ minstrel_filter_avg_add(&mrs->prob_avg, -+ &mrs->prob_avg_1, cur_prob); - } else if (unlikely(!mrs->att_hist)) { -- mrs->prob_ewma = cur_prob; -+ mrs->prob_avg = cur_prob; - } else { - /*update exponential weighted moving avarage */ -- mrs->prob_ewma = minstrel_ewma(mrs->prob_ewma, -- cur_prob, -- EWMA_LEVEL); -+ mrs->prob_avg = minstrel_ewma(mrs->prob_avg, -+ cur_prob, -+ EWMA_LEVEL); - } - mrs->att_hist += mrs->attempts; - mrs->succ_hist += mrs->success; -@@ -208,8 +208,8 @@ minstrel_update_stats(struct minstrel_pr - - /* Sample less often below the 10% chance of success. - * Sample less often above the 95% chance of success. */ -- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) || -- mrs->prob_ewma < MINSTREL_FRAC(10, 100)) { -+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100) || -+ mrs->prob_avg < MINSTREL_FRAC(10, 100)) { - mr->adjusted_retry_count = mrs->retry_count >> 1; - if (mr->adjusted_retry_count > 2) - mr->adjusted_retry_count = 2; -@@ -229,14 +229,14 @@ minstrel_update_stats(struct minstrel_pr - * choose the maximum throughput rate as max_prob_rate - * (2) if all success probabilities < 95%, the rate with - * highest success probability is chosen as max_prob_rate */ -- if (mrs->prob_ewma >= MINSTREL_FRAC(95, 100)) { -- tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_ewma); -+ if (mrs->prob_avg >= MINSTREL_FRAC(95, 100)) { -+ tmp_cur_tp = minstrel_get_tp_avg(mr, mrs->prob_avg); - tmp_prob_tp = minstrel_get_tp_avg(&mi->r[tmp_prob_rate], -- tmp_mrs->prob_ewma); -+ tmp_mrs->prob_avg); - if (tmp_cur_tp >= tmp_prob_tp) - tmp_prob_rate = i; - } else { -- if (mrs->prob_ewma >= tmp_mrs->prob_ewma) -+ if (mrs->prob_avg >= tmp_mrs->prob_avg) - tmp_prob_rate = i; - } - } -@@ -426,7 +426,7 @@ minstrel_get_rate(void *priv, struct iee - * has a probability of >95%, we shouldn't be attempting - * to use it, as this only wastes precious airtime */ - if (!mrr_capable && -- (mi->r[ndx].stats.prob_ewma > MINSTREL_FRAC(95, 100))) -+ (mi->r[ndx].stats.prob_avg > MINSTREL_FRAC(95, 100))) - return; - - mi->prev_sample = true; -@@ -577,7 +577,7 @@ static u32 minstrel_get_expected_through - * computing cur_tp - */ - tmp_mrs = &mi->r[idx].stats; -- tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_ewma) * 10; -+ tmp_cur_tp = minstrel_get_tp_avg(&mi->r[idx], tmp_mrs->prob_avg) * 10; - tmp_cur_tp = tmp_cur_tp * 1200 * 8 / 1024; - - return tmp_cur_tp; ---- a/net/mac80211/rc80211_minstrel.h -+++ b/net/mac80211/rc80211_minstrel.h -@@ -47,14 +47,10 @@ minstrel_ewma(int old, int new, int weig - return old + incr; - } - --struct minstrel_avg_ctx { -- s32 prev[2]; --}; -- --static inline int minstrel_filter_avg_add(struct minstrel_avg_ctx *ctx, s32 in) -+static inline int minstrel_filter_avg_add(u16 *prev_1, u16 *prev_2, s32 in) - { -- s32 out_1 = ctx->prev[0]; -- s32 out_2 = ctx->prev[1]; -+ s32 out_1 = *prev_1; -+ s32 out_2 = *prev_2; - s32 val; - - if (!in) -@@ -76,8 +72,8 @@ static inline int minstrel_filter_avg_ad - val = 1; - - out: -- ctx->prev[1] = out_1; -- ctx->prev[0] = val; -+ *prev_2 = out_1; -+ *prev_1 = val; - - return val; - } -@@ -90,10 +86,9 @@ struct minstrel_rate_stats { - /* total attempts/success counters */ - u32 att_hist, succ_hist; - -- struct minstrel_avg_ctx avg; -- -- /* prob_ewma - exponential weighted moving average of prob */ -- u16 prob_ewma; -+ /* prob_avg - moving average of prob */ -+ u16 prob_avg; -+ u16 prob_avg_1; - - /* maximum retry counts */ - u8 retry_count; -@@ -181,7 +176,7 @@ void minstrel_add_sta_debugfs(void *priv - /* Recalculate success probabilities and counters for a given rate using EWMA */ - void minstrel_calc_rate_stats(struct minstrel_priv *mp, - struct minstrel_rate_stats *mrs); --int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_ewma); -+int minstrel_get_tp_avg(struct minstrel_rate *mr, int prob_avg); - - /* debugfs */ - int minstrel_stats_open(struct inode *inode, struct file *file); ---- a/net/mac80211/rc80211_minstrel_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_debugfs.c -@@ -90,8 +90,8 @@ minstrel_stats_open(struct inode *inode, - p += sprintf(p, "%6u ", mr->perfect_tx_time); - - tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); -- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); -- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); -+ tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg); -+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); - - p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u" - " %3u %3u %-3u " -@@ -147,8 +147,8 @@ minstrel_stats_csv_open(struct inode *in - p += sprintf(p, "%u,",mr->perfect_tx_time); - - tp_max = minstrel_get_tp_avg(mr, MINSTREL_FRAC(100,100)); -- tp_avg = minstrel_get_tp_avg(mr, mrs->prob_ewma); -- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); -+ tp_avg = minstrel_get_tp_avg(mr, mrs->prob_avg); -+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); - - p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u,%u," - "%llu,%llu,%d,%d\n", ---- a/net/mac80211/rc80211_minstrel_ht.c -+++ b/net/mac80211/rc80211_minstrel_ht.c -@@ -346,12 +346,12 @@ minstrel_ht_avg_ampdu_len(struct minstre - */ - int - minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, -- int prob_ewma) -+ int prob_avg) - { - unsigned int nsecs = 0; - - /* do not account throughput if sucess prob is below 10% */ -- if (prob_ewma < MINSTREL_FRAC(10, 100)) -+ if (prob_avg < MINSTREL_FRAC(10, 100)) - return 0; - - if (group != MINSTREL_CCK_GROUP) -@@ -365,11 +365,11 @@ minstrel_ht_get_tp_avg(struct minstrel_h - * account for collision related packet error rate fluctuation - * (prob is scaled - see MINSTREL_FRAC above) - */ -- if (prob_ewma > MINSTREL_FRAC(90, 100)) -+ if (prob_avg > MINSTREL_FRAC(90, 100)) - return MINSTREL_TRUNC(100000 * ((MINSTREL_FRAC(90, 100) * 1000) - / nsecs)); - else -- return MINSTREL_TRUNC(100000 * ((prob_ewma * 1000) / nsecs)); -+ return MINSTREL_TRUNC(100000 * ((prob_avg * 1000) / nsecs)); - } - - /* -@@ -389,13 +389,13 @@ minstrel_ht_sort_best_tp_rates(struct mi - - cur_group = index / MCS_GROUP_RATES; - cur_idx = index % MCS_GROUP_RATES; -- cur_prob = mi->groups[cur_group].rates[cur_idx].prob_ewma; -+ cur_prob = mi->groups[cur_group].rates[cur_idx].prob_avg; - cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, cur_prob); - - do { - tmp_group = tp_list[j - 1] / MCS_GROUP_RATES; - tmp_idx = tp_list[j - 1] % MCS_GROUP_RATES; -- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma; -+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; - tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, - tmp_prob); - if (cur_tp_avg < tmp_tp_avg || -@@ -432,7 +432,7 @@ minstrel_ht_set_best_prob_rate(struct mi - - tmp_group = mi->max_prob_rate / MCS_GROUP_RATES; - tmp_idx = mi->max_prob_rate % MCS_GROUP_RATES; -- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma; -+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; - tmp_tp_avg = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); - - /* if max_tp_rate[0] is from MCS_GROUP max_prob_rate get selected from -@@ -444,11 +444,11 @@ minstrel_ht_set_best_prob_rate(struct mi - - max_gpr_group = mg->max_group_prob_rate / MCS_GROUP_RATES; - max_gpr_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; -- max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_ewma; -+ max_gpr_prob = mi->groups[max_gpr_group].rates[max_gpr_idx].prob_avg; - -- if (mrs->prob_ewma > MINSTREL_FRAC(75, 100)) { -+ if (mrs->prob_avg > MINSTREL_FRAC(75, 100)) { - cur_tp_avg = minstrel_ht_get_tp_avg(mi, cur_group, cur_idx, -- mrs->prob_ewma); -+ mrs->prob_avg); - if (cur_tp_avg > tmp_tp_avg) - mi->max_prob_rate = index; - -@@ -458,9 +458,9 @@ minstrel_ht_set_best_prob_rate(struct mi - if (cur_tp_avg > max_gpr_tp_avg) - mg->max_group_prob_rate = index; - } else { -- if (mrs->prob_ewma > tmp_prob) -+ if (mrs->prob_avg > tmp_prob) - mi->max_prob_rate = index; -- if (mrs->prob_ewma > max_gpr_prob) -+ if (mrs->prob_avg > max_gpr_prob) - mg->max_group_prob_rate = index; - } - } -@@ -482,12 +482,12 @@ minstrel_ht_assign_best_tp_rates(struct - - tmp_group = tmp_cck_tp_rate[0] / MCS_GROUP_RATES; - tmp_idx = tmp_cck_tp_rate[0] % MCS_GROUP_RATES; -- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma; -+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; - tmp_cck_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); - - tmp_group = tmp_mcs_tp_rate[0] / MCS_GROUP_RATES; - tmp_idx = tmp_mcs_tp_rate[0] % MCS_GROUP_RATES; -- tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_ewma; -+ tmp_prob = mi->groups[tmp_group].rates[tmp_idx].prob_avg; - tmp_mcs_tp = minstrel_ht_get_tp_avg(mi, tmp_group, tmp_idx, tmp_prob); - - if (tmp_cck_tp_rate && tmp_cck_tp > tmp_mcs_tp) { -@@ -518,7 +518,7 @@ minstrel_ht_prob_rate_reduce_streams(str - continue; - - tmp_idx = mg->max_group_prob_rate % MCS_GROUP_RATES; -- tmp_prob = mi->groups[group].rates[tmp_idx].prob_ewma; -+ tmp_prob = mi->groups[group].rates[tmp_idx].prob_avg; - - if (tmp_tp < minstrel_ht_get_tp_avg(mi, group, tmp_idx, tmp_prob) && - (minstrel_mcs_groups[group].streams < tmp_max_streams)) { -@@ -623,7 +623,7 @@ minstrel_ht_rate_sample_switch(struct mi - * If that fails, look again for a rate that is at least as fast - */ - mrs = minstrel_get_ratestats(mi, mi->max_tp_rate[0]); -- faster_rate = mrs->prob_ewma > MINSTREL_FRAC(75, 100); -+ faster_rate = mrs->prob_avg > MINSTREL_FRAC(75, 100); - minstrel_ht_find_probe_rates(mi, rates, &n_rates, faster_rate); - if (!n_rates && faster_rate) - minstrel_ht_find_probe_rates(mi, rates, &n_rates, false); -@@ -738,7 +738,7 @@ minstrel_ht_update_stats(struct minstrel - mrs = &mg->rates[i]; - mrs->retry_updated = false; - minstrel_calc_rate_stats(mp, mrs); -- cur_prob = mrs->prob_ewma; -+ cur_prob = mrs->prob_avg; - - if (minstrel_ht_get_tp_avg(mi, group, i, cur_prob) == 0) - continue; -@@ -1012,7 +1012,7 @@ minstrel_calc_retransmit(struct minstrel - unsigned int overhead = 0, overhead_rtscts = 0; - - mrs = minstrel_get_ratestats(mi, index); -- if (mrs->prob_ewma < MINSTREL_FRAC(1, 10)) { -+ if (mrs->prob_avg < MINSTREL_FRAC(1, 10)) { - mrs->retry_count = 1; - mrs->retry_count_rtscts = 1; - return; -@@ -1069,7 +1069,7 @@ minstrel_ht_set_rate(struct minstrel_pri - if (!mrs->retry_updated) - minstrel_calc_retransmit(mp, mi, index); - -- if (mrs->prob_ewma < MINSTREL_FRAC(20, 100) || !mrs->retry_count) { -+ if (mrs->prob_avg < MINSTREL_FRAC(20, 100) || !mrs->retry_count) { - ratetbl->rate[offset].count = 2; - ratetbl->rate[offset].count_rts = 2; - ratetbl->rate[offset].count_cts = 2; -@@ -1103,11 +1103,11 @@ minstrel_ht_set_rate(struct minstrel_pri - } - - static inline int --minstrel_ht_get_prob_ewma(struct minstrel_ht_sta *mi, int rate) -+minstrel_ht_get_prob_avg(struct minstrel_ht_sta *mi, int rate) - { - int group = rate / MCS_GROUP_RATES; - rate %= MCS_GROUP_RATES; -- return mi->groups[group].rates[rate].prob_ewma; -+ return mi->groups[group].rates[rate].prob_avg; - } - - static int -@@ -1119,7 +1119,7 @@ minstrel_ht_get_max_amsdu_len(struct min - unsigned int duration; - - /* Disable A-MSDU if max_prob_rate is bad */ -- if (mi->groups[group].rates[rate].prob_ewma < MINSTREL_FRAC(50, 100)) -+ if (mi->groups[group].rates[rate].prob_avg < MINSTREL_FRAC(50, 100)) - return 1; - - duration = g->duration[rate]; -@@ -1142,7 +1142,7 @@ minstrel_ht_get_max_amsdu_len(struct min - * data packet size - */ - if (duration > MCS_DURATION(1, 0, 260) || -- (minstrel_ht_get_prob_ewma(mi, mi->max_tp_rate[0]) < -+ (minstrel_ht_get_prob_avg(mi, mi->max_tp_rate[0]) < - MINSTREL_FRAC(75, 100))) - return 3200; - -@@ -1247,7 +1247,7 @@ minstrel_get_sample_rate(struct minstrel - * rate, to avoid wasting airtime. - */ - sample_dur = minstrel_get_duration(sample_idx); -- if (mrs->prob_ewma > MINSTREL_FRAC(95, 100) || -+ if (mrs->prob_avg > MINSTREL_FRAC(95, 100) || - minstrel_get_duration(mi->max_prob_rate) * 3 < sample_dur) - return -1; - -@@ -1705,7 +1705,7 @@ static u32 minstrel_ht_get_expected_thro - - i = mi->max_tp_rate[0] / MCS_GROUP_RATES; - j = mi->max_tp_rate[0] % MCS_GROUP_RATES; -- prob = mi->groups[i].rates[j].prob_ewma; -+ prob = mi->groups[i].rates[j].prob_avg; - - /* convert tp_avg from pkt per second in kbps */ - tp_avg = minstrel_ht_get_tp_avg(mi, i, j, prob) * 10; ---- a/net/mac80211/rc80211_minstrel_ht.h -+++ b/net/mac80211/rc80211_minstrel_ht.h -@@ -119,6 +119,6 @@ struct minstrel_ht_sta_priv { - - void minstrel_ht_add_sta_debugfs(void *priv, void *priv_sta, struct dentry *dir); - int minstrel_ht_get_tp_avg(struct minstrel_ht_sta *mi, int group, int rate, -- int prob_ewma); -+ int prob_avg); - - #endif ---- a/net/mac80211/rc80211_minstrel_ht_debugfs.c -+++ b/net/mac80211/rc80211_minstrel_ht_debugfs.c -@@ -98,8 +98,8 @@ minstrel_ht_stats_dump(struct minstrel_h - p += sprintf(p, "%6u ", tx_time); - - tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); -- tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); -- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); -+ tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg); -+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); - - p += sprintf(p, "%4u.%1u %4u.%1u %3u.%1u" - " %3u %3u %-3u " -@@ -243,8 +243,8 @@ minstrel_ht_stats_csv_dump(struct minstr - p += sprintf(p, "%u,", tx_time); - - tp_max = minstrel_ht_get_tp_avg(mi, i, j, MINSTREL_FRAC(100, 100)); -- tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_ewma); -- eprob = MINSTREL_TRUNC(mrs->prob_ewma * 1000); -+ tp_avg = minstrel_ht_get_tp_avg(mi, i, j, mrs->prob_avg); -+ eprob = MINSTREL_TRUNC(mrs->prob_avg * 1000); - - p += sprintf(p, "%u.%u,%u.%u,%u.%u,%u,%u," - "%u,%llu,%llu,", diff --git a/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch b/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch new file mode 100644 index 0000000000..2940615354 --- /dev/null +++ b/package/kernel/mac80211/patches/subsys/390-nl-mac-80211-allow-4addr-AP-operation-on-crypto-cont.patch @@ -0,0 +1,107 @@ +From 3ad31f4efe9674a8bda057c79995a9468281e77f Mon Sep 17 00:00:00 2001 +From: Manikanta Pubbisetty +Date: Wed, 21 Nov 2018 16:33:48 +0530 +Subject: [PATCH] {nl,mac}80211: allow 4addr AP operation on crypto controlled + devices + +As per the current design, for sw crypto controlled devices, it is +the device which has to advertise the support for AP/VLAN iftype +based on it's capability to tranmsit packets encrypted in software +(In VLAN functionality, group traffic generated for a specific +VLAN group is always encrypted in software). Commit db3bdcb9c3ff +("mac80211: allow AP_VLAN operation on crypto controlled devices") +has introduced this change. + +Since 4addr AP operation also uses AP/VLAN iftype, this conditional +way of advertising AP/VLAN support has broken 4addr AP mode operation on +crypto controlled devices which do not support VLAN functionality. + +For example: +In the case of ath10k driver, not all firmwares have support for VLAN +functionality but all can support 4addr AP operation. Because AP/VLAN +support is not advertised for these devices, 4addr AP operations are +also blocked. + +Fix this by allowing 4addr opertion on devices which do not advertise +AP/VLAN iftype but which can support 4addr operation (the desicion is +taken based on the wiphy flag WIPHY_FLAG_4ADDR_AP). + +Fixes: Commit db3bdcb9c3ff ("mac80211: allow AP_VLAN operation on +crypto controlled devices") +Signed-off-by: Manikanta Pubbisetty +--- + include/net/cfg80211.h | 3 ++- + net/mac80211/util.c | 4 +++- + net/wireless/core.c | 9 +++++++-- + net/wireless/nl80211.c | 10 ++++++++-- + 4 files changed, 20 insertions(+), 6 deletions(-) + +--- a/include/net/cfg80211.h ++++ b/include/net/cfg80211.h +@@ -3457,7 +3457,8 @@ struct cfg80211_ops { + * on wiphy_new(), but can be changed by the driver if it has a good + * reason to override the default + * @WIPHY_FLAG_4ADDR_AP: supports 4addr mode even on AP (with a single station +- * on a VLAN interface) ++ * on a VLAN interface). This flag also serves an extra purpose of ++ * supporting 4ADDR AP mode on devices which do not support AP/VLAN iftype. + * @WIPHY_FLAG_4ADDR_STATION: supports 4addr mode even as a station + * @WIPHY_FLAG_CONTROL_PORT_PROTOCOL: This device supports setting the + * control port protocol ethertype. The device also honours the +--- a/net/mac80211/util.c ++++ b/net/mac80211/util.c +@@ -3626,7 +3626,9 @@ int ieee80211_check_combinations(struct + } + + /* Always allow software iftypes */ +- if (local->hw.wiphy->software_iftypes & BIT(iftype)) { ++ if (local->hw.wiphy->software_iftypes & BIT(iftype) || ++ (iftype == NL80211_IFTYPE_AP_VLAN && ++ local->hw.wiphy->flags & WIPHY_FLAG_4ADDR_AP)) { + if (radar_detect) + return -EINVAL; + return 0; +--- a/net/wireless/core.c ++++ b/net/wireless/core.c +@@ -1351,8 +1351,13 @@ static int cfg80211_netdev_notifier_call + } + break; + case NETDEV_PRE_UP: +- if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) +- return notifier_from_errno(-EOPNOTSUPP); ++ if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) { ++ if (!(wdev->iftype == NL80211_IFTYPE_AP_VLAN && ++ rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP && ++ wdev->use_4addr)) ++ return notifier_from_errno(-EOPNOTSUPP); ++ } ++ + if (rfkill_blocked(rdev->rfkill)) + return notifier_from_errno(-ERFKILL); + break; +--- a/net/wireless/nl80211.c ++++ b/net/wireless/nl80211.c +@@ -3194,8 +3194,7 @@ static int nl80211_new_interface(struct + return -EINVAL; + } + +- if (!rdev->ops->add_virtual_intf || +- !(rdev->wiphy.interface_modes & (1 << type))) ++ if (!rdev->ops->add_virtual_intf) + return -EOPNOTSUPP; + + if ((type == NL80211_IFTYPE_P2P_DEVICE || type == NL80211_IFTYPE_NAN || +@@ -3214,6 +3213,13 @@ static int nl80211_new_interface(struct + return err; + } + ++ if (!(rdev->wiphy.interface_modes & (1 << type))) { ++ if (!(type == NL80211_IFTYPE_AP_VLAN && ++ rdev->wiphy.flags & WIPHY_FLAG_4ADDR_AP && ++ params.use_4addr)) ++ return -EOPNOTSUPP; ++ } ++ + err = nl80211_parse_mon_options(rdev, type, info, ¶ms); + if (err < 0) + return err; diff --git a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch b/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch similarity index 79% rename from package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch rename to package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch index a76953933f..4dcd7b5fcc 100644 --- a/package/kernel/mac80211/patches/subsys/500-mac80211_configure_antenna_gain.patch +++ b/package/kernel/mac80211/patches/subsys/522-mac80211_configure_antenna_gain.patch @@ -1,6 +1,6 @@ --- a/include/net/cfg80211.h +++ b/include/net/cfg80211.h -@@ -3348,6 +3348,7 @@ struct cfg80211_update_owe_info { +@@ -2968,6 +2968,7 @@ struct cfg80211_external_auth_params { * (as advertised by the nl80211 feature flag.) * @get_tx_power: store the current TX power into the dbm variable; * return 0 if successful @@ -8,7 +8,7 @@ * * @set_wds_peer: set the WDS peer for a WDS interface * -@@ -3660,6 +3661,7 @@ struct cfg80211_ops { +@@ -3268,6 +3269,7 @@ struct cfg80211_ops { enum nl80211_tx_power_setting type, int mbm); int (*get_tx_power)(struct wiphy *wiphy, struct wireless_dev *wdev, int *dbm); @@ -18,7 +18,7 @@ const u8 *addr); --- a/include/net/mac80211.h +++ b/include/net/mac80211.h -@@ -1476,6 +1476,7 @@ enum ieee80211_smps_mode { +@@ -1395,6 +1395,7 @@ enum ieee80211_smps_mode { * * @power_level: requested transmit power (in dBm), backward compatibility * value only that is set to the minimum of all interfaces @@ -26,7 +26,7 @@ * * @chandef: the channel definition to tune to * @radar_enabled: whether radar detection is enabled -@@ -1496,6 +1497,7 @@ enum ieee80211_smps_mode { +@@ -1415,6 +1416,7 @@ enum ieee80211_smps_mode { struct ieee80211_conf { u32 flags; int power_level, dynamic_ps_timeout; @@ -36,9 +36,9 @@ u8 ps_dtim_period; --- a/include/uapi/linux/nl80211.h +++ b/include/uapi/linux/nl80211.h -@@ -2356,6 +2356,9 @@ enum nl80211_commands { - * - * @NL80211_ATTR_TWT_RESPONDER: Enable target wait time responder support. +@@ -2244,6 +2244,9 @@ enum nl80211_commands { + * @NL80211_ATTR_AIRTIME_WEIGHT: Station's weight when scheduled by the airtime + * scheduler. * + * @NL80211_ATTR_WIPHY_ANTENNA_GAIN: Configured antenna gain. Used to reduce + * transmit power to stay within regulatory limits. u32, dBi. @@ -46,9 +46,9 @@ * @NUM_NL80211_ATTR: total number of nl80211_attrs available * @NL80211_ATTR_MAX: highest attribute number currently defined * @__NL80211_ATTR_AFTER_LAST: internal use -@@ -2813,6 +2816,8 @@ enum nl80211_attrs { +@@ -2693,6 +2696,8 @@ enum nl80211_attrs { - NL80211_ATTR_TWT_RESPONDER, + NL80211_ATTR_AIRTIME_WEIGHT, + NL80211_ATTR_WIPHY_ANTENNA_GAIN, + @@ -57,7 +57,7 @@ __NL80211_ATTR_AFTER_LAST, --- a/net/mac80211/cfg.c +++ b/net/mac80211/cfg.c -@@ -2584,6 +2584,19 @@ static int ieee80211_get_tx_power(struct +@@ -2505,6 +2505,19 @@ static int ieee80211_get_tx_power(struct return 0; } @@ -77,7 +77,7 @@ static int ieee80211_set_wds_peer(struct wiphy *wiphy, struct net_device *dev, const u8 *addr) { -@@ -3997,6 +4010,7 @@ const struct cfg80211_ops mac80211_confi +@@ -3872,6 +3885,7 @@ const struct cfg80211_ops mac80211_confi .set_wiphy_params = ieee80211_set_wiphy_params, .set_tx_power = ieee80211_set_tx_power, .get_tx_power = ieee80211_get_tx_power, @@ -87,7 +87,7 @@ CFG80211_TESTMODE_CMD(ieee80211_testmode_cmd) --- a/net/mac80211/ieee80211_i.h +++ b/net/mac80211/ieee80211_i.h -@@ -1372,6 +1372,7 @@ struct ieee80211_local { +@@ -1365,6 +1365,7 @@ struct ieee80211_local { int dynamic_ps_forced_timeout; int user_power_level; /* in dBm, for all interfaces */ @@ -97,7 +97,7 @@ --- a/net/mac80211/main.c +++ b/net/mac80211/main.c -@@ -93,7 +93,7 @@ static u32 ieee80211_hw_conf_chan(struct +@@ -94,7 +94,7 @@ static u32 ieee80211_hw_conf_chan(struct struct ieee80211_sub_if_data *sdata; struct cfg80211_chan_def chandef = {}; u32 changed = 0; @@ -106,7 +106,7 @@ u32 offchannel_flag; offchannel_flag = local->hw.conf.flags & IEEE80211_CONF_OFFCHANNEL; -@@ -150,6 +150,12 @@ static u32 ieee80211_hw_conf_chan(struct +@@ -151,6 +151,12 @@ static u32 ieee80211_hw_conf_chan(struct } rcu_read_unlock(); @@ -119,7 +119,7 @@ if (local->hw.conf.power_level != power) { changed |= IEEE80211_CONF_CHANGE_POWER; local->hw.conf.power_level = power; -@@ -639,6 +645,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ +@@ -626,6 +632,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_ IEEE80211_RADIOTAP_MCS_HAVE_BW; local->hw.radiotap_vht_details = IEEE80211_RADIOTAP_VHT_KNOWN_GI | IEEE80211_RADIOTAP_VHT_KNOWN_BANDWIDTH; @@ -129,15 +129,15 @@ local->user_power_level = IEEE80211_UNSET_POWER_LEVEL; --- a/net/wireless/nl80211.c +++ b/net/wireless/nl80211.c -@@ -574,6 +574,7 @@ const struct nla_policy nl80211_policy[N - [NL80211_ATTR_SAE_PASSWORD] = { .type = NLA_BINARY, - .len = SAE_PASSWORD_MAX_LEN }, - [NL80211_ATTR_TWT_RESPONDER] = { .type = NLA_FLAG }, +@@ -431,6 +431,7 @@ static const struct nla_policy nl80211_p + [NL80211_ATTR_HE_CAPABILITY] = { .type = NLA_BINARY, + .len = NL80211_HE_MAX_CAPABILITY_LEN }, + [NL80211_ATTR_AIRTIME_WEIGHT] = NLA_POLICY_MIN(NLA_U16, 1), + [NL80211_ATTR_WIPHY_ANTENNA_GAIN] = { .type = NLA_U32 }, }; /* policy for the key attributes */ -@@ -2869,6 +2870,20 @@ static int nl80211_set_wiphy(struct sk_b +@@ -2588,6 +2589,20 @@ static int nl80211_set_wiphy(struct sk_b if (result) return result; } diff --git a/package/lean/luci-app-mwan3helper/Makefile b/package/lean/luci-app-mwan3helper/Makefile index cd14c00376..38dedff054 100644 --- a/package/lean/luci-app-mwan3helper/Makefile +++ b/package/lean/luci-app-mwan3helper/Makefile @@ -9,7 +9,7 @@ LUCI_TITLE:=LuCI support for MWAN3 Helper LUCI_DEPENDS:=+luci-app-mwan3 +pdnsd-alt +dnsmasq-full +ipset LUCI_PKGARCH:=all PKG_VERSION:=1 -PKG_RELEASE:=2 +PKG_RELEASE:=3 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/package/lean/luci-app-mwan3helper/root/etc/mwan3helper/gfw.txt b/package/lean/luci-app-mwan3helper/root/etc/mwan3helper/gfw.txt index 64b256dc75..073d0aa7a3 100644 --- a/package/lean/luci-app-mwan3helper/root/etc/mwan3helper/gfw.txt +++ b/package/lean/luci-app-mwan3helper/root/etc/mwan3helper/gfw.txt @@ -1863,7 +1863,6 @@ gotdns.ch gotgeeks.com gotrusted.com gotw.ca -gov.cn gov.taipei gov.tw gr8domain.biz diff --git a/package/lean/luci-app-netdata/Makefile b/package/lean/luci-app-netdata/Makefile new file mode 100644 index 0000000000..8794d5a4da --- /dev/null +++ b/package/lean/luci-app-netdata/Makefile @@ -0,0 +1,16 @@ +# Copyright (C) 2016 Openwrt.org +# +# This is free software, licensed under the Apache License, Version 2.0 . +# + +include $(TOPDIR)/rules.mk + +LUCI_TITLE:=LuCI support for Netdata +LUCI_DEPENDS:=+netdata +LUCI_PKGARCH:=all +PKG_VERSION:=1.0 +PKG_RELEASE:=3 + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/package/lean/luci-app-netdata/luasrc/controller/netdata.lua b/package/lean/luci-app-netdata/luasrc/controller/netdata.lua new file mode 100644 index 0000000000..b9c8a44480 --- /dev/null +++ b/package/lean/luci-app-netdata/luasrc/controller/netdata.lua @@ -0,0 +1,6 @@ +module("luci.controller.netdata", package.seeall) + +function index() + + entry({"admin","status","netdata"},template("netdata"),_("NetData"),10).leaf=true +end \ No newline at end of file diff --git a/package/lean/luci-app-netdata/luasrc/view/netdata.htm b/package/lean/luci-app-netdata/luasrc/view/netdata.htm new file mode 100644 index 0000000000..a6620e64d7 --- /dev/null +++ b/package/lean/luci-app-netdata/luasrc/view/netdata.htm @@ -0,0 +1,9 @@ +<%+header%> +
+

<%=translate("NetData")%>

+ +
+ +<%+footer%> diff --git a/package/lean/luci-app-netdata/po/zh-cn/netdata.po b/package/lean/luci-app-netdata/po/zh-cn/netdata.po new file mode 100644 index 0000000000..e8966b815d --- /dev/null +++ b/package/lean/luci-app-netdata/po/zh-cn/netdata.po @@ -0,0 +1,5 @@ +msgid "" +msgstr "Content-Type: text/plain; charset=UTF-8" + +msgid "NetData" +msgstr "实时监控" diff --git a/package/lean/luci-app-ssr-plus/Makefile b/package/lean/luci-app-ssr-plus/Makefile index 801c07b8f1..c4861adc25 100644 --- a/package/lean/luci-app-ssr-plus/Makefile +++ b/package/lean/luci-app-ssr-plus/Makefile @@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-ssr-plus PKG_VERSION:=1 -PKG_RELEASE:=118 +PKG_RELEASE:=120 PKG_CONFIG_DEPENDS:= CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \ diff --git a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua index 9157079f6b..5b7dc7fe32 100644 --- a/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua +++ b/package/lean/luci-app-ssr-plus/luasrc/model/cbi/shadowsocksr/client-config.lua @@ -210,17 +210,17 @@ o:depends("type", "v2ray") -- TCP伪装 o = s:option(ListValue, "tcp_guise", translate("Camouflage Type")) o:depends("transport", "tcp") -o:value("none", translate("None")) o:value("http", "HTTP") +o:value("none", translate("None")) o.rmempty = true -- HTTP域名 -o = s:option(DynamicList, "http_host", translate("HTTP Host")) +o = s:option(Value, "http_host", translate("HTTP Host")) o:depends("tcp_guise", "http") o.rmempty = true -- HTTP路径 -o = s:option(DynamicList, "http_path", translate("HTTP Path")) +o = s:option(Value, "http_path", translate("HTTP Path")) o:depends("tcp_guise", "http") o.rmempty = true @@ -239,7 +239,7 @@ o.rmempty = true -- [[ H2部分 ]]-- -- H2域名 -o = s:option(DynamicList, "h2_host", translate("HTTP/2 Host")) +o = s:option(Value, "h2_host", translate("HTTP/2 Host")) o:depends("transport", "h2") o.rmempty = true diff --git a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm index 9e3ad39fc9..639ef70271 100644 --- a/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm +++ b/package/lean/luci-app-ssr-plus/luasrc/view/shadowsocksr/ssrurl.htm @@ -135,7 +135,7 @@ document.getElementById('cbid.shadowsocksr.' + sid + '.password').value = b64decsafe(ssm[6]); document.getElementById('cbid.shadowsocksr.' + sid + '.obfs_param').value = dictvalue(pdict, 'obfsparam'); document.getElementById('cbid.shadowsocksr.' + sid + '.protocol_param').value = dictvalue(pdict, 'protoparam'); - + var rem = pdict['remarks']; if (typeof (rem) != 'undefined' && rem != '' && rem.length > 0) document.getElementById('cbid.shadowsocksr.' + sid + '.alias').value = b64decutf8safe(rem); @@ -188,6 +188,8 @@ document.getElementById('cbid.shadowsocksr.' + sid + '.vmess_id').value = ssm.id; document.getElementById('cbid.shadowsocksr.' + sid + '.security').value = ssm.type; document.getElementById('cbid.shadowsocksr.' + sid + '.transport').value = ssm.net; + document.getElementById('cbid.shadowsocksr.' + sid + '.http_host').value = ssm.host; + document.getElementById('cbid.shadowsocksr.' + sid + '.http_path').value = ssm.path; s.innerHTML = "导入V2ray配置信息成功"; return false; diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.sh b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.sh index 56bc6735cc..c4fe9f3280 100755 --- a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.sh +++ b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.sh @@ -47,8 +47,10 @@ Server_Update() { ${uci_set}tcp_guise="$ssr_tcp_guise" ${uci_set}ws_host="$ssr_ws_host" ${uci_set}ws_path="$ssr_ws_path" + ${uci_set}h2_host="$ssr_h2_host" + ${uci_set}h2_path="$ssr_h2_path" ${uci_set}tls="$ssr_tls" - ${uci_set}security="auto" + ${uci_set}security=$ssr_security ${uci_set}alias="$ssr_remarks" fi @@ -186,12 +188,17 @@ do json_get_var ssr_port port json_get_var ssr_alter_id aid json_get_var ssr_vmess_id id - json_get_var ssr_security type + json_get_var ssr_security security + if [ "$ssr_security" == "" ]; then + ssr_security="auto" + fi json_get_var ssr_transport net json_get_var ssr_remarks ps ssr_tcp_guise="none" json_get_var ssr_ws_host host json_get_var ssr_ws_path path + json_get_var ssr_h2_host host + json_get_var ssr_h2_path path json_get_var ssr_tls tls if [ "$ssr_tls" == "tls" -o "$ssr_tls" == "1" ]; then ssr_tls="1" diff --git a/package/lean/luci-app-ttyd/Makefile b/package/lean/luci-app-ttyd/Makefile index 3667783ca3..cd54f30d29 100644 --- a/package/lean/luci-app-ttyd/Makefile +++ b/package/lean/luci-app-ttyd/Makefile @@ -9,7 +9,7 @@ LUCI_TITLE:=LuCI support for ttyd LUCI_DEPENDS:=+ttyd LUCI_PKGARCH:=all PKG_VERSION:=1.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 include $(TOPDIR)/feeds/luci/luci.mk diff --git a/package/lean/luci-app-ttyd/luasrc/view/terminal.htm b/package/lean/luci-app-ttyd/luasrc/view/terminal.htm index 00653f7e4c..784f86f4ff 100644 --- a/package/lean/luci-app-ttyd/luasrc/view/terminal.htm +++ b/package/lean/luci-app-ttyd/luasrc/view/terminal.htm @@ -4,6 +4,6 @@

<%=translate("TTYD Terminal")%>

<%+footer%> \ No newline at end of file diff --git a/package/libs/mbedtls/Makefile b/package/libs/mbedtls/Makefile index f03ae71d0c..9126c16a1d 100644 --- a/package/libs/mbedtls/Makefile +++ b/package/libs/mbedtls/Makefile @@ -48,9 +48,9 @@ define Package/libmbedtls/config config LIBMBEDTLS_HAVE_SSE2 depends on PACKAGE_libmbedtls bool - default y if x86_64 + default y if !TARGET_x86_legacy && !TARGET_x86_geode prompt "Enable use of x86 SSE2 instructions" - depends on x86_64 + depends on x86_64 || i386 help Use of SSE2 instructions greatly increase performance (up to 3x faster) with a minimum (~0.2%, or 23KB) increase in package diff --git a/scripts/json_add_image_info.py b/scripts/json_add_image_info.py new file mode 100644 index 0000000000..fe498b773f --- /dev/null +++ b/scripts/json_add_image_info.py @@ -0,0 +1,1156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + openwrt/json_add_image_info.py at master · openwrt/openwrt · GitHub + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content + + + + + + + + + + + +
+ +
+ + +
+ +
+ + + +
+
+
+ + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + Permalink + + + + + +
+ + +
+ + Branch: + master + + + + + + + +
+ +
+ + Find file + + + Copy path + +
+
+ + +
+ + Find file + + + Copy path + +
+
+ + + + +
+
+ + @aparcar + aparcar + + build: create JSON files containing image info + + + + 881ed09 + Sep 29, 2019 + +
+ +
+
+ + 1 contributor + + +
+ +

+ Users who have contributed to this file +

+
+ +
+
+
+
+ + + + + +
+ +
+
+ + executable file + + 56 lines (40 sloc) + + 1.53 KB +
+ +
+ +
+ Raw + Blame + History +
+ + +
+ + + +
+
+
+ + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
#!/usr/bin/env python3
+
import json
import os
import hashlib
+
+
def e(variable, default=None):
return os.environ.get(variable, default)
+
+
json_path = "{}{}{}.json".format(e("BIN_DIR"), os.sep, e("IMAGE_PREFIX"))
+
with open(os.path.join(e("BIN_DIR"), e("IMAGE_NAME")), "rb") as image_file:
image_hash = hashlib.sha256(image_file.read()).hexdigest()
+
+
def get_titles():
titles = []
for prefix in ["", "ALT0_", "ALT1_", "ALT2_"]:
title = {}
for var in ["vendor", "model", "variant"]:
if e("DEVICE_{}{}".format(prefix, var.upper())):
title[var] = e("DEVICE_{}{}".format(prefix, var.upper()))
+
if title:
titles.append(title)
+
if not titles:
titles.append({"title": e("DEVICE_TITLE")})
+
return titles
+
+
if not os.path.exists(json_path):
device_info = {
"id": e("DEVICE_ID"),
"image_prefix": e("IMAGE_PREFIX"),
"images": [],
"metadata_version": 1,
"supported_devices": e("SUPPORTED_DEVICES").split(),
"target": "{}/{}".format(e("TARGET"), e("SUBTARGET", "generic")),
"titles": get_titles(),
"version_commit": e("VERSION_CODE"),
"version_number": e("VERSION_NUMBER"),
}
else:
with open(json_path, "r") as json_file:
device_info = json.load(json_file)
+
image_info = {"type": e("IMAGE_TYPE"), "name": e("IMAGE_NAME"), "sha256": image_hash}
device_info["images"].append(image_info)
+
with open(json_path, "w") as json_file:
json.dump(device_info, json_file, sort_keys=True, indent=" ")
+ + + +
+ +
+ + + +
+ + +
+ + +
+
+ + + +
+
+ +
+
+ + +
+ + + + + + +
+ + + You can’t perform that action at this time. +
+ + + + + + + + + + + + + + +
+ + + + diff --git a/scripts/metadata.pm b/scripts/metadata.pm index 4a5464edc0..8ca963e757 100644 --- a/scripts/metadata.pm +++ b/scripts/metadata.pm @@ -140,7 +140,8 @@ sub parse_target_metadata($) { id => $1, name => $1, priority => 999, - packages => [] + packages => [], + default => "y if TARGET_ALL_PROFILES" }; $1 =~ /^DEVICE_/ and $target->{has_devices} = 1; push @{$target->{profiles}}, $profile; @@ -152,6 +153,7 @@ sub parse_target_metadata($) { }; /^Target-Profile-Packages:\s*(.*)\s*$/ and $profile->{packages} = [ split(/\s+/, $1) ]; /^Target-Profile-Description:\s*(.*)\s*/ and $profile->{desc} = get_multiline(*FILE); + /^Target-Profile-Default:\s*(.+)\s*$/ and $profile->{default} = $1; } close FILE; foreach my $target (@target) { diff --git a/scripts/target-metadata.pl b/scripts/target-metadata.pl index 47f489567c..b4613a75d0 100755 --- a/scripts/target-metadata.pl +++ b/scripts/target-metadata.pl @@ -292,7 +292,7 @@ () menuconfig TARGET_DEVICE_$target->{conf}_$profile->{id} bool "$profile->{name}" depends on TARGET_$target->{conf} - default y if TARGET_ALL_PROFILES + default $profile->{default} EOF my @pkglist = merge_package_lists($target->{packages}, $profile->{packages}); foreach my $pkg (@pkglist) { diff --git a/target/linux/brcm2708/image/Makefile b/target/linux/brcm2708/image/Makefile index db2b3b5562..7f9619100c 100644 --- a/target/linux/brcm2708/image/Makefile +++ b/target/linux/brcm2708/image/Makefile @@ -27,7 +27,7 @@ define Build/boot-common mcopy -i $@.boot $(KDIR)/COPYING.linux :: mcopy -i $@.boot $(KDIR)/LICENCE.broadcom :: mcopy -i $@.boot cmdline.txt :: - mcopy -i $@.boot config.txt :: + mcopy -i $@.boot $(BOOT_CONFIG) ::config.txt mcopy -i $@.boot distroconfig.txt :: mcopy -i $@.boot $(IMAGE_KERNEL) ::$(KERNEL_IMG) $(foreach dts,$(shell echo $(DEVICE_DTS)),mcopy -i $@.boot $(DTS_DIR)/$(dts).dtb ::;) @@ -68,6 +68,7 @@ define Device/Default IMAGES := factory.img.gz sysupgrade.img.gz IMAGE/sysupgrade.img.gz := boot-common | boot-2708 | sdcard-img | gzip | append-metadata IMAGE/factory.img.gz := boot-common | boot-2708 | sdcard-img | gzip + BOOT_CONFIG := config.txt endef define Device/rpi @@ -151,6 +152,7 @@ define Device/rpi-4 kmod-brcmfmac wpad-basic IMAGE/sysupgrade.img.gz := boot-common | boot-2711 | sdcard-img | gzip | append-metadata IMAGE/factory.img.gz := boot-common | boot-2711 | sdcard-img | gzip + BOOT_CONFIG := config-bcm2711-arm64.txt endef ifeq ($(SUBTARGET),bcm2711) TARGET_DEVICES += rpi-4 diff --git a/target/linux/brcm2708/image/config-bcm2711-arm64.txt b/target/linux/brcm2708/image/config-bcm2711-arm64.txt new file mode 100644 index 0000000000..984aab585e --- /dev/null +++ b/target/linux/brcm2708/image/config-bcm2711-arm64.txt @@ -0,0 +1,17 @@ +################################################################################ +# Bootloader configuration - config.txt +################################################################################ + +################################################################################ +# For overclocking and various other settings, see: +# https://www.raspberrypi.org/documentation/configuration/config-txt/README.md +################################################################################ + +# Force aarch64 +arm_64bit=1 + +# OpenWrt config +include distroconfig.txt + +[all] +# Place your custom settings here. diff --git a/target/linux/generic/backport-4.9/041-mm-rename-__alloc_page_frag-to-page_frag_alloc-and-_.patch b/target/linux/generic/backport-4.9/041-mm-rename-__alloc_page_frag-to-page_frag_alloc-and-_.patch new file mode 100644 index 0000000000..facc43004e --- /dev/null +++ b/target/linux/generic/backport-4.9/041-mm-rename-__alloc_page_frag-to-page_frag_alloc-and-_.patch @@ -0,0 +1,137 @@ +From: Alexander Duyck +Date: Tue, 10 Jan 2017 16:58:06 -0800 +Subject: [PATCH] mm: rename __alloc_page_frag to page_frag_alloc and + __free_page_frag to page_frag_free + +Patch series "Page fragment updates", v4. + +This patch series takes care of a few cleanups for the page fragments +API. + +First we do some renames so that things are much more consistent. First +we move the page_frag_ portion of the name to the front of the functions +names. Secondly we split out the cache specific functions from the +other page fragment functions by adding the word "cache" to the name. + +Finally I added a bit of documentation that will hopefully help to +explain some of this. I plan to revisit this later as we get things +more ironed out in the near future with the changes planned for the DMA +setup to support eXpress Data Path. + +This patch (of 3): + +This patch renames the page frag functions to be more consistent with +other APIs. Specifically we place the name page_frag first in the name +and then have either an alloc or free call name that we append as the +suffix. This makes it a bit clearer in terms of naming. + +In addition we drop the leading double underscores since we are +technically no longer a backing interface and instead the front end that +is called from the networking APIs. + +Link: http://lkml.kernel.org/r/20170104023854.13451.67390.stgit@localhost.localdomain +Signed-off-by: Alexander Duyck +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +--- + +--- a/include/linux/gfp.h ++++ b/include/linux/gfp.h +@@ -508,9 +508,9 @@ extern void free_hot_cold_page_list(stru + struct page_frag_cache; + extern void __page_frag_drain(struct page *page, unsigned int order, + unsigned int count); +-extern void *__alloc_page_frag(struct page_frag_cache *nc, +- unsigned int fragsz, gfp_t gfp_mask); +-extern void __free_page_frag(void *addr); ++extern void *page_frag_alloc(struct page_frag_cache *nc, ++ unsigned int fragsz, gfp_t gfp_mask); ++extern void page_frag_free(void *addr); + + #define __free_page(page) __free_pages((page), 0) + #define free_page(addr) free_pages((addr), 0) +--- a/include/linux/skbuff.h ++++ b/include/linux/skbuff.h +@@ -2476,7 +2476,7 @@ static inline struct sk_buff *netdev_all + + static inline void skb_free_frag(void *addr) + { +- __free_page_frag(addr); ++ page_frag_free(addr); + } + + void *napi_alloc_frag(unsigned int fragsz); +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -3949,8 +3949,8 @@ void __page_frag_drain(struct page *page + } + EXPORT_SYMBOL(__page_frag_drain); + +-void *__alloc_page_frag(struct page_frag_cache *nc, +- unsigned int fragsz, gfp_t gfp_mask) ++void *page_frag_alloc(struct page_frag_cache *nc, ++ unsigned int fragsz, gfp_t gfp_mask) + { + unsigned int size = PAGE_SIZE; + struct page *page; +@@ -4001,19 +4001,19 @@ refill: + + return nc->va + offset; + } +-EXPORT_SYMBOL(__alloc_page_frag); ++EXPORT_SYMBOL(page_frag_alloc); + + /* + * Frees a page fragment allocated out of either a compound or order 0 page. + */ +-void __free_page_frag(void *addr) ++void page_frag_free(void *addr) + { + struct page *page = virt_to_head_page(addr); + + if (unlikely(put_page_testzero(page))) + __free_pages_ok(page, compound_order(page)); + } +-EXPORT_SYMBOL(__free_page_frag); ++EXPORT_SYMBOL(page_frag_free); + + static void *make_alloc_exact(unsigned long addr, unsigned int order, + size_t size) +--- a/net/core/skbuff.c ++++ b/net/core/skbuff.c +@@ -369,7 +369,7 @@ static void *__netdev_alloc_frag(unsigne + + local_irq_save(flags); + nc = this_cpu_ptr(&netdev_alloc_cache); +- data = __alloc_page_frag(nc, fragsz, gfp_mask); ++ data = page_frag_alloc(nc, fragsz, gfp_mask); + local_irq_restore(flags); + return data; + } +@@ -393,7 +393,7 @@ static void *__napi_alloc_frag(unsigned + { + struct napi_alloc_cache *nc = this_cpu_ptr(&napi_alloc_cache); + +- return __alloc_page_frag(&nc->page, fragsz, gfp_mask); ++ return page_frag_alloc(&nc->page, fragsz, gfp_mask); + } + + void *napi_alloc_frag(unsigned int fragsz) +@@ -445,7 +445,7 @@ struct sk_buff *__netdev_alloc_skb(struc + local_irq_save(flags); + + nc = this_cpu_ptr(&netdev_alloc_cache); +- data = __alloc_page_frag(nc, len, gfp_mask); ++ data = page_frag_alloc(nc, len, gfp_mask); + pfmemalloc = nc->pfmemalloc; + + local_irq_restore(flags); +@@ -509,7 +509,7 @@ struct sk_buff *__napi_alloc_skb(struct + if (sk_memalloc_socks()) + gfp_mask |= __GFP_MEMALLOC; + +- data = __alloc_page_frag(&nc->page, len, gfp_mask); ++ data = page_frag_alloc(&nc->page, len, gfp_mask); + if (unlikely(!data)) + return NULL; + diff --git a/target/linux/generic/backport-4.9/042-mm-rename-__page_frag-functions-to-__page_frag_cache.patch b/target/linux/generic/backport-4.9/042-mm-rename-__page_frag-functions-to-__page_frag_cache.patch new file mode 100644 index 0000000000..31b57167b4 --- /dev/null +++ b/target/linux/generic/backport-4.9/042-mm-rename-__page_frag-functions-to-__page_frag_cache.patch @@ -0,0 +1,79 @@ +From: Alexander Duyck +Date: Tue, 10 Jan 2017 16:58:09 -0800 +Subject: [PATCH] mm: rename __page_frag functions to __page_frag_cache, drop + order from drain + +This patch does two things. + +First it goes through and renames the __page_frag prefixed functions to +__page_frag_cache so that we can be clear that we are draining or +refilling the cache, not the frags themselves. + +Second we drop the order parameter from __page_frag_cache_drain since we +don't actually need to pass it since all fragments are either order 0 or +must be a compound page. + +Link: http://lkml.kernel.org/r/20170104023954.13451.5678.stgit@localhost.localdomain +Signed-off-by: Alexander Duyck +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +--- + +--- a/include/linux/gfp.h ++++ b/include/linux/gfp.h +@@ -506,8 +506,7 @@ extern void free_hot_cold_page(struct pa + extern void free_hot_cold_page_list(struct list_head *list, bool cold); + + struct page_frag_cache; +-extern void __page_frag_drain(struct page *page, unsigned int order, +- unsigned int count); ++extern void __page_frag_cache_drain(struct page *page, unsigned int count); + extern void *page_frag_alloc(struct page_frag_cache *nc, + unsigned int fragsz, gfp_t gfp_mask); + extern void page_frag_free(void *addr); +--- a/mm/page_alloc.c ++++ b/mm/page_alloc.c +@@ -3914,8 +3914,8 @@ EXPORT_SYMBOL(free_pages); + * drivers to provide a backing region of memory for use as either an + * sk_buff->head, or to be used in the "frags" portion of skb_shared_info. + */ +-static struct page *__page_frag_refill(struct page_frag_cache *nc, +- gfp_t gfp_mask) ++static struct page *__page_frag_cache_refill(struct page_frag_cache *nc, ++ gfp_t gfp_mask) + { + struct page *page = NULL; + gfp_t gfp = gfp_mask; +@@ -3935,19 +3935,20 @@ static struct page *__page_frag_refill(s + return page; + } + +-void __page_frag_drain(struct page *page, unsigned int order, +- unsigned int count) ++void __page_frag_cache_drain(struct page *page, unsigned int count) + { + VM_BUG_ON_PAGE(page_ref_count(page) == 0, page); + + if (page_ref_sub_and_test(page, count)) { ++ unsigned int order = compound_order(page); ++ + if (order == 0) + free_hot_cold_page(page, false); + else + __free_pages_ok(page, order); + } + } +-EXPORT_SYMBOL(__page_frag_drain); ++EXPORT_SYMBOL(__page_frag_cache_drain); + + void *page_frag_alloc(struct page_frag_cache *nc, + unsigned int fragsz, gfp_t gfp_mask) +@@ -3958,7 +3959,7 @@ void *page_frag_alloc(struct page_frag_c + + if (unlikely(!nc->va)) { + refill: +- page = __page_frag_refill(nc, gfp_mask); ++ page = __page_frag_cache_refill(nc, gfp_mask); + if (!page) + return NULL; + diff --git a/target/linux/generic/config-4.19 b/target/linux/generic/config-4.19 index 46728cec01..e732c402d3 100644 --- a/target/linux/generic/config-4.19 +++ b/target/linux/generic/config-4.19 @@ -285,6 +285,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARC_EMAC is not set # CONFIG_ARC_IRQ_NO_AUTOSAVE is not set # CONFIG_ARM64_ERRATUM_1024718 is not set +# CONFIG_ARM64_ERRATUM_1463225 is not set # CONFIG_ARM64_ERRATUM_819472 is not set # CONFIG_ARM64_ERRATUM_824069 is not set # CONFIG_ARM64_ERRATUM_826319 is not set @@ -296,6 +297,7 @@ CONFIG_ARCH_MMAP_RND_COMPAT_BITS_MIN=8 # CONFIG_ARM64_ERRATUM_858921 is not set # CONFIG_ARM64_RAS_EXTN is not set # CONFIG_ARM64_RELOC_TEST is not set +CONFIG_ARM64_SW_TTBR0_PAN=y # CONFIG_ARM_APPENDED_DTB is not set # CONFIG_ARM_ARCH_TIMER is not set # CONFIG_ARM_BIG_LITTLE_CPUFREQ is not set @@ -447,6 +449,7 @@ CONFIG_ATM_CLIP_NO_ICMP=y # CONFIG_BACKLIGHT_LV5207LP is not set # CONFIG_BACKLIGHT_PANDORA is not set # CONFIG_BACKLIGHT_PM8941_WLED is not set +# CONFIG_BACKLIGHT_PWM is not set # CONFIG_BACKLIGHT_RPI is not set # CONFIG_BACKLIGHT_SAHARA is not set # CONFIG_BACKTRACE_SELF_TEST is not set @@ -608,6 +611,7 @@ CONFIG_BLOCK=y # CONFIG_BNA is not set # CONFIG_BNX2 is not set # CONFIG_BNX2X is not set +# CONFIG_BNX2X_SRIOV is not set # CONFIG_BNXT is not set # CONFIG_BONDING is not set # CONFIG_BOOKE_WDT is not set @@ -616,7 +620,7 @@ CONFIG_BOOKE_WDT_DEFAULT_TIMEOUT=3 CONFIG_BOOT_RAW=y CONFIG_BPF=y # CONFIG_BPFILTER is not set -# CONFIG_BPF_JIT is not set +CONFIG_BPF_JIT=y # CONFIG_BPF_JIT_ALWAYS_ON is not set # CONFIG_BPF_STREAM_PARSER is not set CONFIG_BPF_SYSCALL=y @@ -695,6 +699,7 @@ CONFIG_BT_HCIUART_H4=y # CONFIG_BT_LE is not set # CONFIG_BT_LEDS is not set # CONFIG_BT_MRVL is not set +# CONFIG_BT_MTKUART is not set # CONFIG_BT_RFCOMM is not set CONFIG_BT_RFCOMM_TTY=y # CONFIG_BT_SELFTEST is not set @@ -778,6 +783,8 @@ CONFIG_CC_OPTIMIZE_FOR_PERFORMANCE=y # CONFIG_CHARGER_SBS is not set # CONFIG_CHARGER_SMB347 is not set # CONFIG_CHARGER_TWL4030 is not set +# CONFIG_CHASH_SELFTEST is not set +# CONFIG_CHASH_STATS is not set # CONFIG_CHECKPOINT_RESTORE is not set # CONFIG_CHELSIO_T1 is not set # CONFIG_CHELSIO_T3 is not set @@ -847,6 +854,7 @@ CONFIG_CMDLINE="" # CONFIG_COMMON_CLK_XLNX_CLKWZRD is not set CONFIG_COMPACTION=y # CONFIG_COMPAL_LAPTOP is not set +# CONFIG_COMPAT is not set # CONFIG_COMPAT_BRK is not set # CONFIG_COMPILE_TEST is not set # CONFIG_CONFIGFS_FS is not set @@ -918,7 +926,7 @@ CONFIG_CRYPTO_ALGAPI=y CONFIG_CRYPTO_ALGAPI2=y # CONFIG_CRYPTO_ANSI_CPRNG is not set # CONFIG_CRYPTO_ANUBIS is not set -CONFIG_CRYPTO_ARC4=y +# CONFIG_CRYPTO_ARC4 is not set # CONFIG_CRYPTO_AUTHENC is not set CONFIG_CRYPTO_BLKCIPHER=y CONFIG_CRYPTO_BLKCIPHER2=y @@ -942,6 +950,8 @@ CONFIG_CRYPTO_BLKCIPHER2=y # CONFIG_CRYPTO_DEFLATE is not set # CONFIG_CRYPTO_DES is not set # CONFIG_CRYPTO_DEV_ATMEL_AES is not set +# CONFIG_CRYPTO_DEV_ATMEL_AUTHENC is not set +# CONFIG_CRYPTO_DEV_ATMEL_ECC is not set # CONFIG_CRYPTO_DEV_ATMEL_SHA is not set # CONFIG_CRYPTO_DEV_ATMEL_TDES is not set # CONFIG_CRYPTO_DEV_CAVIUM_ZIP is not set @@ -1102,14 +1112,12 @@ CONFIG_DEBUG_KERNEL=y # CONFIG_DEBUG_PINCTRL is not set # CONFIG_DEBUG_PI_LIST is not set # CONFIG_DEBUG_PREEMPT is not set -# CONFIG_DEBUG_RODATA is not set # CONFIG_DEBUG_RODATA_TEST is not set # CONFIG_DEBUG_RSEQ is not set # CONFIG_DEBUG_RT_MUTEXES is not set # CONFIG_DEBUG_RWSEMS is not set # CONFIG_DEBUG_SECTION_MISMATCH is not set # CONFIG_DEBUG_SEMIHOSTING is not set -# CONFIG_DEBUG_SET_MODULE_RONX is not set # CONFIG_DEBUG_SG is not set # CONFIG_DEBUG_SHIRQ is not set # CONFIG_DEBUG_SLAB is not set @@ -1213,14 +1221,20 @@ CONFIG_DQL=y # CONFIG_DRAGONRISE_FF is not set # CONFIG_DRM is not set # CONFIG_DRM_AMDGPU is not set +# CONFIG_DRM_AMDGPU_CIK is not set +# CONFIG_DRM_AMDGPU_GART_DEBUGFS is not set +# CONFIG_DRM_AMDGPU_SI is not set +# CONFIG_DRM_AMDGPU_USERPTR is not set +# CONFIG_DRM_AMD_ACP is not set # CONFIG_DRM_ANALOGIX_ANX78XX is not set # CONFIG_DRM_ARCPGU is not set # CONFIG_DRM_ARMADA is not set # CONFIG_DRM_AST is not set # CONFIG_DRM_BOCHS is not set +# CONFIG_DRM_CDNS_DSI is not set # CONFIG_DRM_CIRRUS_QEMU is not set # CONFIG_DRM_DEBUG_MM is not set -# CONFIG_DRM_DEBUG_MM_SELFTEST is not set +# CONFIG_DRM_DEBUG_SELFTEST is not set # CONFIG_DRM_DP_AUX_CHARDEV is not set # CONFIG_DRM_DP_CEC is not set # CONFIG_DRM_DUMB_VGA_DAC is not set @@ -1228,14 +1242,18 @@ CONFIG_DQL=y # CONFIG_DRM_ETNAVIV is not set # CONFIG_DRM_EXYNOS is not set # CONFIG_DRM_FBDEV_EMULATION is not set +# CONFIG_DRM_FBDEV_LEAK_PHYS_SMEM is not set # CONFIG_DRM_FSL_DCU is not set +# CONFIG_DRM_GMA500 is not set # CONFIG_DRM_HDLCD is not set # CONFIG_DRM_HISI_HIBMC is not set # CONFIG_DRM_HISI_KIRIN is not set # CONFIG_DRM_I2C_ADV7511 is not set # CONFIG_DRM_I2C_CH7006 is not set +# CONFIG_DRM_I2C_NXP_TDA9950 is not set # CONFIG_DRM_I2C_NXP_TDA998X is not set # CONFIG_DRM_I2C_SIL164 is not set +# CONFIG_DRM_I915 is not set # CONFIG_DRM_LEGACY is not set # CONFIG_DRM_LIB_RANDOM is not set # CONFIG_DRM_LOAD_EDID_FIRMWARE is not set @@ -1247,13 +1265,22 @@ CONFIG_DQL=y # CONFIG_DRM_NOUVEAU is not set # CONFIG_DRM_NXP_PTN3460 is not set # CONFIG_DRM_OMAP is not set +# CONFIG_DRM_PANEL_ARM_VERSATILE is not set +# CONFIG_DRM_PANEL_ILITEK_IL9322 is not set +# CONFIG_DRM_PANEL_ILITEK_ILI9881C is not set +# CONFIG_DRM_PANEL_INNOLUX_P079ZCA is not set # CONFIG_DRM_PANEL_JDI_LT070ME05000 is not set # CONFIG_DRM_PANEL_LG_LG4573 is not set # CONFIG_DRM_PANEL_LVDS is not set +# CONFIG_DRM_PANEL_ORISETECH_OTM8009A is not set # CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00 is not set # CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN is not set +# CONFIG_DRM_PANEL_RAYDIUM_RM68200 is not set # CONFIG_DRM_PANEL_SAMSUNG_LD9040 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2 is not set +# CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03 is not set # CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0 is not set +# CONFIG_DRM_PANEL_SEIKO_43WVF1G is not set # CONFIG_DRM_PANEL_SHARP_LQ101R1SX01 is not set # CONFIG_DRM_PANEL_SHARP_LS043T1LE01 is not set # CONFIG_DRM_PANEL_SITRONIX_ST7789V is not set @@ -1261,11 +1288,16 @@ CONFIG_DQL=y # CONFIG_DRM_PL111 is not set # CONFIG_DRM_QXL is not set # CONFIG_DRM_RADEON is not set +# CONFIG_DRM_RADEON_USERPTR is not set # CONFIG_DRM_RCAR_DW_HDMI is not set +# CONFIG_DRM_RCAR_LVDS is not set # CONFIG_DRM_SII902X is not set +# CONFIG_DRM_SII9234 is not set # CONFIG_DRM_SIL_SII8620 is not set # CONFIG_DRM_STI is not set # CONFIG_DRM_STM is not set +# CONFIG_DRM_SUN4I is not set +# CONFIG_DRM_THINE_THC63LVD1024 is not set # CONFIG_DRM_TILCDC is not set # CONFIG_DRM_TINYDRM is not set # CONFIG_DRM_TI_TFP410 is not set @@ -1273,6 +1305,9 @@ CONFIG_DQL=y # CONFIG_DRM_UDL is not set # CONFIG_DRM_VBOXVIDEO is not set # CONFIG_DRM_VGEM is not set +# CONFIG_DRM_VIRTIO_GPU is not set +# CONFIG_DRM_VKMS is not set +# CONFIG_DRM_VMWGFX is not set # CONFIG_DRM_XEN is not set # CONFIG_DS1682 is not set # CONFIG_DS1803 is not set @@ -1359,6 +1394,7 @@ CONFIG_EXPORTFS=y CONFIG_EXT4_USE_FOR_EXT2=y # CONFIG_EXTCON is not set # CONFIG_EXTCON_ADC_JACK is not set +# CONFIG_EXTCON_ARIZONA is not set # CONFIG_EXTCON_AXP288 is not set # CONFIG_EXTCON_GPIO is not set # CONFIG_EXTCON_INTEL_INT3496 is not set @@ -1409,6 +1445,7 @@ CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" # CONFIG_FB_CYBER2000 is not set # CONFIG_FB_DA8XX is not set # CONFIG_FB_DDC is not set +# CONFIG_FB_FLEX is not set # CONFIG_FB_FOREIGN_ENDIAN is not set # CONFIG_FB_GEODE is not set # CONFIG_FB_GOLDFISH is not set @@ -1454,6 +1491,39 @@ CONFIG_FB_NOTIFY=y # CONFIG_FB_SYS_FOPS is not set # CONFIG_FB_SYS_IMAGEBLIT is not set # CONFIG_FB_TFT is not set +# CONFIG_FB_TFT_AGM1264K_FL is not set +# CONFIG_FB_TFT_BD663474 is not set +# CONFIG_FB_TFT_FBTFT_DEVICE is not set +# CONFIG_FB_TFT_HX8340BN is not set +# CONFIG_FB_TFT_HX8347D is not set +# CONFIG_FB_TFT_HX8353D is not set +# CONFIG_FB_TFT_HX8357D is not set +# CONFIG_FB_TFT_ILI9163 is not set +# CONFIG_FB_TFT_ILI9320 is not set +# CONFIG_FB_TFT_ILI9325 is not set +# CONFIG_FB_TFT_ILI9340 is not set +# CONFIG_FB_TFT_ILI9341 is not set +# CONFIG_FB_TFT_ILI9481 is not set +# CONFIG_FB_TFT_ILI9486 is not set +# CONFIG_FB_TFT_PCD8544 is not set +# CONFIG_FB_TFT_RA8875 is not set +# CONFIG_FB_TFT_S6D02A1 is not set +# CONFIG_FB_TFT_S6D1121 is not set +# CONFIG_FB_TFT_SH1106 is not set +# CONFIG_FB_TFT_SSD1289 is not set +# CONFIG_FB_TFT_SSD1305 is not set +# CONFIG_FB_TFT_SSD1306 is not set +# CONFIG_FB_TFT_SSD1325 is not set +# CONFIG_FB_TFT_SSD1331 is not set +# CONFIG_FB_TFT_SSD1351 is not set +# CONFIG_FB_TFT_ST7735R is not set +# CONFIG_FB_TFT_ST7789V is not set +# CONFIG_FB_TFT_TINYLCD is not set +# CONFIG_FB_TFT_TLS8204 is not set +# CONFIG_FB_TFT_UC1611 is not set +# CONFIG_FB_TFT_UC1701 is not set +# CONFIG_FB_TFT_UPD161704 is not set +# CONFIG_FB_TFT_WATTEROTT is not set # CONFIG_FB_TILEBLITTING is not set # CONFIG_FB_TMIO is not set # CONFIG_FB_TRIDENT is not set @@ -1534,7 +1604,7 @@ CONFIG_GACT_PROB=y # CONFIG_GAMEPORT is not set # CONFIG_GATEWORKS_GW16083 is not set # CONFIG_GCC_PLUGINS is not set -CONFIG_GCC_VERSION=70400 +CONFIG_GCC_VERSION=80300 # CONFIG_GCOV is not set # CONFIG_GCOV_KERNEL is not set # CONFIG_GDB_SCRIPTS is not set @@ -1631,7 +1701,9 @@ CONFIG_GPIOLIB_FASTPATH_LIMIT=512 # CONFIG_HAMACHI is not set # CONFIG_HAMRADIO is not set # CONFIG_HAPPYMEAL is not set -# CONFIG_HARDENED_USERCOPY is not set +CONFIG_HARDENED_USERCOPY=y +# CONFIG_HARDENED_USERCOPY_FALLBACK is not set +# CONFIG_HARDENED_USERCOPY_PAGESPAN is not set CONFIG_HARDEN_EL2_VECTORS=y # CONFIG_HARDLOCKUP_DETECTOR is not set # CONFIG_HAVE_AOUT is not set @@ -1687,6 +1759,7 @@ CONFIG_HAVE_STACKPROTECTOR=y # CONFIG_HID_BATTERY_STRENGTH is not set # CONFIG_HID_BELKIN is not set # CONFIG_HID_BETOP_FF is not set +# CONFIG_HID_BIGBEN_FF is not set # CONFIG_HID_CHERRY is not set # CONFIG_HID_CHICONY is not set # CONFIG_HID_CMEDIA is not set @@ -1814,6 +1887,7 @@ CONFIG_HW_PERF_EVENTS=y # CONFIG_HW_RANDOM_GEODE is not set # CONFIG_HW_RANDOM_INTEL is not set # CONFIG_HW_RANDOM_IPROC_RNG200 is not set +# CONFIG_HW_RANDOM_OMAP is not set # CONFIG_HW_RANDOM_OMAP3_ROM is not set # CONFIG_HW_RANDOM_PPC4XX is not set # CONFIG_HW_RANDOM_TIMERIOMEM is not set @@ -2089,6 +2163,7 @@ CONFIG_INPUT_MISC=y # CONFIG_INPUT_WISTRON_BTNS is not set # CONFIG_INPUT_YEALINK is not set # CONFIG_INT340X_THERMAL is not set +# CONFIG_INTEL_ATOMISP2_PM is not set # CONFIG_INTEL_CHT_INT33FE is not set # CONFIG_INTEL_HID_EVENT is not set # CONFIG_INTEL_IDLE is not set @@ -2342,6 +2417,7 @@ CONFIG_KERNFS=y # CONFIG_KEYBOARD_SUNKBD is not set # CONFIG_KEYBOARD_TCA6416 is not set # CONFIG_KEYBOARD_TCA8418 is not set +# CONFIG_KEYBOARD_TEGRA is not set # CONFIG_KEYBOARD_TM2_TOUCHKEY is not set # CONFIG_KEYBOARD_TWL4030 is not set # CONFIG_KEYBOARD_XTKBD is not set @@ -2830,6 +2906,7 @@ CONFIG_MODULE_UNLOAD=y # CONFIG_MQ_IOSCHED_KYBER is not set # CONFIG_MS5611 is not set # CONFIG_MS5637 is not set +# CONFIG_MSCC_OCELOT_SWITCH is not set # CONFIG_MSDOS_FS is not set CONFIG_MSDOS_PARTITION=y # CONFIG_MSI_BITMAP_SELFTEST is not set @@ -3132,6 +3209,7 @@ CONFIG_NET_CORE=y # CONFIG_NET_DROP_MONITOR is not set # CONFIG_NET_DSA is not set # CONFIG_NET_DSA_BCM_SF2 is not set +# CONFIG_NET_DSA_LEGACY is not set # CONFIG_NET_DSA_LOOP is not set # CONFIG_NET_DSA_MT7530 is not set # CONFIG_NET_DSA_MV88E6060 is not set @@ -3142,10 +3220,12 @@ CONFIG_NET_CORE=y # CONFIG_NET_DSA_MV88E6XXX is not set # CONFIG_NET_DSA_MV88E6XXX_NEED_PPU is not set # CONFIG_NET_DSA_QCA8K is not set +# CONFIG_NET_DSA_REALTEK_SMI is not set # CONFIG_NET_DSA_SMSC_LAN9303_I2C is not set # CONFIG_NET_DSA_SMSC_LAN9303_MDIO is not set # CONFIG_NET_DSA_TAG_DSA is not set # CONFIG_NET_DSA_TAG_EDSA is not set +# CONFIG_NET_DSA_VITESSE_VSC73XX is not set # CONFIG_NET_EMATCH is not set # CONFIG_NET_EMATCH_CANID is not set # CONFIG_NET_EMATCH_CMP is not set @@ -3488,7 +3568,7 @@ CONFIG_NMI_LOG_BUF_SHIFT=13 # CONFIG_OPROFILE is not set # CONFIG_OPROFILE_EVENT_MULTIPLEX is not set # CONFIG_OPT3001 is not set -# CONFIG_OPTIMIZE_INLINING is not set +CONFIG_OPTIMIZE_INLINING=y # CONFIG_ORANGEFS_FS is not set # CONFIG_ORION_WATCHDOG is not set # CONFIG_OSF_PARTITION is not set @@ -3618,13 +3698,13 @@ CONFIG_PARTITION_ADVANCED=y # CONFIG_PCI_LAYERSCAPE is not set # CONFIG_PCI_MSI is not set # CONFIG_PCI_PASID is not set +# CONFIG_PCI_PF_STUB is not set # CONFIG_PCI_PRI is not set CONFIG_PCI_QUIRKS=y # CONFIG_PCI_REALLOC_ENABLE_AUTO is not set # CONFIG_PCI_STUB is not set # CONFIG_PCI_SW_SWITCHTEC is not set CONFIG_PCI_SYSCALL=y -# CONFIG_PCI_V3_SEMI is not set # CONFIG_PCI_XGENE is not set # CONFIG_PCMCIA is not set # CONFIG_PCMCIA_3C574 is not set @@ -3754,6 +3834,8 @@ CONFIG_PPP_MULTILINK=y CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_TRACER is not set # CONFIG_PREEMPT_VOLUNTARY is not set +# CONFIG_PREEMPTIRQ_EVENTS is not set +# CONFIG_PREEMPTIRQ_DELAY_TEST is not set CONFIG_PREVENT_FIRMWARE_BUILD=y CONFIG_PRINTK=y CONFIG_PRINTK_NMI=y @@ -4224,6 +4306,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_ADM1026 is not set # CONFIG_SENSORS_ADM1029 is not set # CONFIG_SENSORS_ADM1031 is not set +# CONFIG_SENSORS_ADM1275 is not set # CONFIG_SENSORS_ADM9240 is not set # CONFIG_SENSORS_ADS1015 is not set # CONFIG_SENSORS_ADS7828 is not set @@ -4272,10 +4355,12 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_HTU21 is not set # CONFIG_SENSORS_I5500 is not set # CONFIG_SENSORS_I5K_AMB is not set +# CONFIG_SENSORS_IBM_CFFPS is not set # CONFIG_SENSORS_IIO_HWMON is not set # CONFIG_SENSORS_INA209 is not set # CONFIG_SENSORS_INA2XX is not set # CONFIG_SENSORS_INA3221 is not set +# CONFIG_SENSORS_IR35221 is not set # CONFIG_SENSORS_ISL29018 is not set # CONFIG_SENSORS_ISL29028 is not set # CONFIG_SENSORS_IT87 is not set @@ -4286,6 +4371,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_LIS3LV02D is not set # CONFIG_SENSORS_LIS3_I2C is not set # CONFIG_SENSORS_LIS3_SPI is not set +# CONFIG_SENSORS_LM25066 is not set # CONFIG_SENSORS_LM63 is not set # CONFIG_SENSORS_LM70 is not set # CONFIG_SENSORS_LM73 is not set @@ -4303,7 +4389,9 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_LM95241 is not set # CONFIG_SENSORS_LM95245 is not set # CONFIG_SENSORS_LTC2945 is not set +# CONFIG_SENSORS_LTC2978 is not set # CONFIG_SENSORS_LTC2990 is not set +# CONFIG_SENSORS_LTC3815 is not set # CONFIG_SENSORS_LTC4151 is not set # CONFIG_SENSORS_LTC4215 is not set # CONFIG_SENSORS_LTC4222 is not set @@ -4311,17 +4399,22 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_LTC4260 is not set # CONFIG_SENSORS_LTC4261 is not set # CONFIG_SENSORS_MAX1111 is not set +# CONFIG_SENSORS_MAX16064 is not set # CONFIG_SENSORS_MAX16065 is not set # CONFIG_SENSORS_MAX1619 is not set # CONFIG_SENSORS_MAX1668 is not set # CONFIG_SENSORS_MAX197 is not set +# CONFIG_SENSORS_MAX20751 is not set # CONFIG_SENSORS_MAX31722 is not set +# CONFIG_SENSORS_MAX31785 is not set # CONFIG_SENSORS_MAX31790 is not set +# CONFIG_SENSORS_MAX34440 is not set # CONFIG_SENSORS_MAX6621 is not set # CONFIG_SENSORS_MAX6639 is not set # CONFIG_SENSORS_MAX6642 is not set # CONFIG_SENSORS_MAX6650 is not set # CONFIG_SENSORS_MAX6697 is not set +# CONFIG_SENSORS_MAX8688 is not set # CONFIG_SENSORS_MCP3021 is not set # CONFIG_SENSORS_NCT6683 is not set # CONFIG_SENSORS_NCT6775 is not set @@ -4333,6 +4426,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_PC87360 is not set # CONFIG_SENSORS_PC87427 is not set # CONFIG_SENSORS_PCF8591 is not set +# CONFIG_SENSORS_PMBUS is not set # CONFIG_SENSORS_POWR1220 is not set # CONFIG_SENSORS_PWM_FAN is not set # CONFIG_SENSORS_SCH5627 is not set @@ -4356,8 +4450,12 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_TMP108 is not set # CONFIG_SENSORS_TMP401 is not set # CONFIG_SENSORS_TMP421 is not set +# CONFIG_SENSORS_TPS40422 is not set +# CONFIG_SENSORS_TPS53679 is not set # CONFIG_SENSORS_TSL2550 is not set # CONFIG_SENSORS_TSL2563 is not set +# CONFIG_SENSORS_UCD9000 is not set +# CONFIG_SENSORS_UCD9200 is not set # CONFIG_SENSORS_VEXPRESS is not set # CONFIG_SENSORS_VIA686A is not set # CONFIG_SENSORS_VIA_CPUTEMP is not set @@ -4374,6 +4472,7 @@ CONFIG_SELECT_MEMORY_MODEL=y # CONFIG_SENSORS_W83L785TS is not set # CONFIG_SENSORS_W83L786NG is not set # CONFIG_SENSORS_XGENE is not set +# CONFIG_SENSORS_ZL6100 is not set CONFIG_SERIAL_8250=y # CONFIG_SERIAL_8250_ACCENT is not set # CONFIG_SERIAL_8250_ASPEED_VUART is not set @@ -5162,6 +5261,7 @@ CONFIG_TMPFS_XATTR=y # CONFIG_TOPSTAR_LAPTOP is not set # CONFIG_TORTURE_TEST is not set # CONFIG_TOSHIBA_HAPS is not set +# CONFIG_TOUCHSCREEN_88PM860X is not set # CONFIG_TOUCHSCREEN_AD7877 is not set # CONFIG_TOUCHSCREEN_AD7879 is not set # CONFIG_TOUCHSCREEN_AD7879_I2C is not set @@ -5170,13 +5270,22 @@ CONFIG_TMPFS_XATTR=y # CONFIG_TOUCHSCREEN_ADS7846 is not set # CONFIG_TOUCHSCREEN_AR1021_I2C is not set # CONFIG_TOUCHSCREEN_ATMEL_MXT is not set +# CONFIG_TOUCHSCREEN_ATMEL_MXT_T37 is not set # CONFIG_TOUCHSCREEN_AUO_PIXCIR is not set # CONFIG_TOUCHSCREEN_BU21013 is not set # CONFIG_TOUCHSCREEN_BU21029 is not set # CONFIG_TOUCHSCREEN_CHIPONE_ICN8318 is not set +# CONFIG_TOUCHSCREEN_CHIPONE_ICN8505 is not set +# CONFIG_TOUCHSCREEN_COLIBRI_VF50 is not set # CONFIG_TOUCHSCREEN_CY8CTMG110 is not set # CONFIG_TOUCHSCREEN_CYTTSP4_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_I2C is not set +# CONFIG_TOUCHSCREEN_CYTTSP4_SPI is not set # CONFIG_TOUCHSCREEN_CYTTSP_CORE is not set +# CONFIG_TOUCHSCREEN_CYTTSP_I2C is not set +# CONFIG_TOUCHSCREEN_CYTTSP_SPI is not set +# CONFIG_TOUCHSCREEN_DA9034 is not set +# CONFIG_TOUCHSCREEN_DA9052 is not set # CONFIG_TOUCHSCREEN_DYNAPRO is not set # CONFIG_TOUCHSCREEN_EDT_FT5X06 is not set # CONFIG_TOUCHSCREEN_EETI is not set @@ -5186,49 +5295,91 @@ CONFIG_TMPFS_XATTR=y # CONFIG_TOUCHSCREEN_ELAN is not set # CONFIG_TOUCHSCREEN_ELO is not set # CONFIG_TOUCHSCREEN_EXC3000 is not set -# CONFIG_TOUCHSCREEN_FT6236 is not set # CONFIG_TOUCHSCREEN_FUJITSU is not set # CONFIG_TOUCHSCREEN_GOODIX is not set # CONFIG_TOUCHSCREEN_GUNZE is not set # CONFIG_TOUCHSCREEN_HAMPSHIRE is not set # CONFIG_TOUCHSCREEN_HIDEEP is not set +# CONFIG_TOUCHSCREEN_HP600 is not set +# CONFIG_TOUCHSCREEN_HP7XX is not set +# CONFIG_TOUCHSCREEN_HTCPEN is not set # CONFIG_TOUCHSCREEN_ILI210X is not set # CONFIG_TOUCHSCREEN_IMX6UL_TSC is not set # CONFIG_TOUCHSCREEN_INEXIO is not set +# CONFIG_TOUCHSCREEN_IPAQ_MICRO is not set +# CONFIG_TOUCHSCREEN_IPROC is not set +# CONFIG_TOUCHSCREEN_LPC32XX is not set # CONFIG_TOUCHSCREEN_MAX11801 is not set +# CONFIG_TOUCHSCREEN_MC13783 is not set # CONFIG_TOUCHSCREEN_MCS5000 is not set # CONFIG_TOUCHSCREEN_MELFAS_MIP4 is not set +# CONFIG_TOUCHSCREEN_MIGOR is not set # CONFIG_TOUCHSCREEN_MK712 is not set # CONFIG_TOUCHSCREEN_MMS114 is not set # CONFIG_TOUCHSCREEN_MTOUCH is not set +# CONFIG_TOUCHSCREEN_MX25 is not set +# CONFIG_TOUCHSCREEN_MXS_LRADC is not set +# CONFIG_TOUCHSCREEN_PCAP is not set # CONFIG_TOUCHSCREEN_PENMOUNT is not set # CONFIG_TOUCHSCREEN_PIXCIR is not set +# CONFIG_TOUCHSCREEN_PROPERTIES is not set # CONFIG_TOUCHSCREEN_RM_TS is not set # CONFIG_TOUCHSCREEN_ROHM_BU21023 is not set +# CONFIG_TOUCHSCREEN_RPI_FT5406 is not set # CONFIG_TOUCHSCREEN_S3C2410 is not set # CONFIG_TOUCHSCREEN_S6SY761 is not set # CONFIG_TOUCHSCREEN_SILEAD is not set # CONFIG_TOUCHSCREEN_SIS_I2C is not set # CONFIG_TOUCHSCREEN_ST1232 is not set # CONFIG_TOUCHSCREEN_STMFTS is not set +# CONFIG_TOUCHSCREEN_STMPE is not set +# CONFIG_TOUCHSCREEN_SUN4I is not set # CONFIG_TOUCHSCREEN_SUR40 is not set # CONFIG_TOUCHSCREEN_SURFACE3_SPI is not set # CONFIG_TOUCHSCREEN_SX8654 is not set -# CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4 is not set +# CONFIG_TOUCHSCREEN_TI_AM335X_TSC is not set # CONFIG_TOUCHSCREEN_TOUCHIT213 is not set # CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set # CONFIG_TOUCHSCREEN_TOUCHWIN is not set # CONFIG_TOUCHSCREEN_TPS6507X is not set +# CONFIG_TOUCHSCREEN_TS4800 is not set # CONFIG_TOUCHSCREEN_TSC2004 is not set # CONFIG_TOUCHSCREEN_TSC2005 is not set # CONFIG_TOUCHSCREEN_TSC2007 is not set +# CONFIG_TOUCHSCREEN_TSC2007_IIO is not set +# CONFIG_TOUCHSCREEN_TSC200X_CORE is not set # CONFIG_TOUCHSCREEN_TSC_SERIO is not set +# CONFIG_TOUCHSCREEN_UCB1400 is not set +# CONFIG_TOUCHSCREEN_USB_3M is not set # CONFIG_TOUCHSCREEN_USB_COMPOSITE is not set +# CONFIG_TOUCHSCREEN_USB_DMC_TSC10 is not set +# CONFIG_TOUCHSCREEN_USB_E2I is not set +# CONFIG_TOUCHSCREEN_USB_EASYTOUCH is not set +# CONFIG_TOUCHSCREEN_USB_EGALAX is not set +# CONFIG_TOUCHSCREEN_USB_ELO is not set +# CONFIG_TOUCHSCREEN_USB_ETT_TC45USB is not set +# CONFIG_TOUCHSCREEN_USB_ETURBO is not set +# CONFIG_TOUCHSCREEN_USB_GENERAL_TOUCH is not set +# CONFIG_TOUCHSCREEN_USB_GOTOP is not set +# CONFIG_TOUCHSCREEN_USB_GUNZE is not set +# CONFIG_TOUCHSCREEN_USB_IDEALTEK is not set +# CONFIG_TOUCHSCREEN_USB_IRTOUCH is not set +# CONFIG_TOUCHSCREEN_USB_ITM is not set +# CONFIG_TOUCHSCREEN_USB_JASTEC is not set +# CONFIG_TOUCHSCREEN_USB_NEXIO is not set +# CONFIG_TOUCHSCREEN_USB_PANJIT is not set +# CONFIG_TOUCHSCREEN_USB_ZYTRONIC is not set # CONFIG_TOUCHSCREEN_W90X900 is not set # CONFIG_TOUCHSCREEN_WACOM_I2C is not set # CONFIG_TOUCHSCREEN_WACOM_W8001 is not set # CONFIG_TOUCHSCREEN_WDT87XX_I2C is not set +# CONFIG_TOUCHSCREEN_WM831X is not set +# CONFIG_TOUCHSCREEN_WM9705 is not set +# CONFIG_TOUCHSCREEN_WM9712 is not set +# CONFIG_TOUCHSCREEN_WM9713 is not set # CONFIG_TOUCHSCREEN_WM97XX is not set +# CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE is not set +# CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE is not set # CONFIG_TOUCHSCREEN_ZET6223 is not set # CONFIG_TOUCHSCREEN_ZFORCE is not set # CONFIG_TPL0102 is not set @@ -5279,7 +5430,6 @@ CONFIG_UBIFS_FS_FORMAT4=y # CONFIG_UCB1400_CORE is not set # CONFIG_UCSI is not set # CONFIG_UDF_FS is not set -CONFIG_UDF_NLS=y CONFIG_UEVENT_HELPER=y CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_UFS_FS is not set @@ -5296,7 +5446,7 @@ CONFIG_UNIX98_PTYS=y # CONFIG_UNIX_DIAG is not set # CONFIG_UNUSED_SYMBOLS is not set # CONFIG_UPROBES is not set -# CONFIG_UPROBE_EVENT is not set +# CONFIG_UPROBE_EVENTS is not set # CONFIG_US5182D is not set # CONFIG_USB is not set # CONFIG_USBIP_CORE is not set @@ -5439,6 +5589,7 @@ CONFIG_USB_GADGET_VBUS_DRAW=2 # CONFIG_USB_HUB_USB251XB is not set # CONFIG_USB_HWA_HCD is not set # CONFIG_USB_IDMOUSE is not set +# CONFIG_USB_IMX21_HCD is not set # CONFIG_USB_IOWARRIOR is not set # CONFIG_USB_IPHETH is not set # CONFIG_USB_ISIGHTFW is not set @@ -5638,6 +5789,7 @@ CONFIG_USB_VIDEO_CLASS_INPUT_EVDEV=y # CONFIG_USB_WUSB_CBAF is not set # CONFIG_USB_XHCI_DBGCAP is not set # CONFIG_USB_XHCI_HCD is not set +# CONFIG_USB_XHCI_MVEBU is not set # CONFIG_USB_XUSBATM is not set # CONFIG_USB_YUREX is not set # CONFIG_USB_ZD1201 is not set @@ -5943,3 +6095,5 @@ CONFIG_ZONE_DMA=y # CONFIG_ZSMALLOC is not set # CONFIG_ZX_TDM is not set # CONFIG_NET_ACT_CTINFO is not set +# CONFIG_RPI_AXIPERF is not set + diff --git a/target/linux/rb532/image/Makefile b/target/linux/rb532/image/Makefile index 12265fe2c6..195bb78a81 100644 --- a/target/linux/rb532/image/Makefile +++ b/target/linux/rb532/image/Makefile @@ -39,6 +39,7 @@ define Device/nand CMDLINE := ubi.mtd=1 ubi.block=0,rootfs root=/dev/ubiblock0_1 BOARD_NAME := rb532 SUPPORTED_DEVICES := rb532 + DEVICE_TITLE := rb532 NAND KERNEL_INITRAMFS := append-kernel | patch-cmdline | lzma | lzma-loader-elf KERNEL := $$(KERNEL_INITRAMFS) | kernel2minor -s 2048 -i 0 -c IMAGES := sysupgrade.bin